[clang] 7176158 - [clang][bytecode] Improve diagnostics on typeid field access (#209101)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Jul 13 03:19:31 PDT 2026
Author: Timm Baeder
Date: 2026-07-13T12:19:26+02:00
New Revision: 717615829bba4035897a4ebdbdef919f31529762
URL: https://github.com/llvm/llvm-project/commit/717615829bba4035897a4ebdbdef919f31529762
DIFF: https://github.com/llvm/llvm-project/commit/717615829bba4035897a4ebdbdef919f31529762.diff
LOG: [clang][bytecode] Improve diagnostics on typeid field access (#209101)
Do some extra work to extract the requested field name.
Added:
Modified:
clang/lib/AST/ByteCode/Interp.cpp
clang/test/AST/ByteCode/typeid.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp
index 20235b07fcc47..58bbf4aaf5f89 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -1564,6 +1564,34 @@ bool CheckLiteralType(InterpState &S, CodePtr OpPC, const Type *T) {
return false;
}
+static bool diagnoseTypeIdField(InterpState &S, CodePtr OpPC,
+ const Pointer &Ptr, unsigned Offset) {
+ assert(Ptr.isTypeidPointer());
+ const Record *R = S.getContext().getRecord(
+ Ptr.asTypeidPointer().TypeInfoType->getAsRecordDecl());
+ if (!R)
+ return false;
+ const Record::Field *Field =
+ llvm::find_if(R->fields(), [=](const Record::Field &F) -> bool {
+ return F.Offset == Offset;
+ });
+ if (!Field)
+ return false;
+
+ std::string TypeIdStr;
+ llvm::raw_string_ostream SS(TypeIdStr);
+ SS << "typeid(";
+ QualType(Ptr.asTypeidPointer().TypePtr, 0)
+ .print(SS, S.getASTContext().getPrintingPolicy());
+ SS << ").";
+ SS << Field->Decl->getNameAsString();
+
+ S.FFDiag(S.Current->getSource(OpPC),
+ diag::note_constexpr_access_unreadable_object)
+ << AK_Read << TypeIdStr;
+ return false;
+}
+
static bool getField(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
uint32_t Off) {
if (S.getLangOpts().CPlusPlus && S.inConstantContext() &&
@@ -1587,12 +1615,10 @@ static bool getField(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
}
if (!Ptr.isBlockPointer()) {
- // FIXME: The only time we (seem to) get here is when trying to access a
- // field of a typeid pointer. In that case, we're supposed to diagnose e.g.
- // `typeid(int).name`, but we currently diagnose `&typeid(int)`.
- S.FFDiag(S.Current->getSource(OpPC),
- diag::note_constexpr_access_unreadable_object)
- << AK_Read << Ptr.toDiagnosticString(S.getASTContext());
+ // If we're trying to get the field of a TypeId pointer, try to produce a
+ // proper diagnostic.
+ if (Ptr.isTypeidPointer())
+ return diagnoseTypeIdField(S, OpPC, Ptr, Off);
return false;
}
diff --git a/clang/test/AST/ByteCode/typeid.cpp b/clang/test/AST/ByteCode/typeid.cpp
index 4e7664f505c23..4b9c024632354 100644
--- a/clang/test/AST/ByteCode/typeid.cpp
+++ b/clang/test/AST/ByteCode/typeid.cpp
@@ -22,6 +22,8 @@ class type_info : public __pointer_type_info {
protected:
typedef __type_info_implementations::__impl __impl;
__impl::__type_name_t __type_name;
+public:
+ const char *name;
};
}; // namespace std
@@ -32,6 +34,9 @@ static_assert(&typeid(int) < &typeid(long)); // both-error {{not an integral con
static_assert(&typeid(int) > &typeid(long)); // both-error {{not an integral constant expression}} \
// both-note {{comparison between pointers to unrelated objects '&typeid(int)' and '&typeid(long)' has unspecified value}}
+constexpr auto name = typeid(int).name; // both-error {{constant expression}} \
+ // both-note {{read of object 'typeid(int).name' whose value is not known}}
+
struct Base {
virtual void func() ;
};
More information about the cfe-commits
mailing list