llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Timm Baeder (tbaederr) <details> <summary>Changes</summary> Do some extra work to extract the requested field name. --- Full diff: https://github.com/llvm/llvm-project/pull/209101.diff 2 Files Affected: - (modified) clang/lib/AST/ByteCode/Interp.cpp (+32-6) - (modified) clang/test/AST/ByteCode/typeid.cpp (+5) ``````````diff diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp index 0adcdfe6e78c9..f5ffca0d0fa8b 100644 --- a/clang/lib/AST/ByteCode/Interp.cpp +++ b/clang/lib/AST/ByteCode/Interp.cpp @@ -1554,6 +1554,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() && @@ -1577,12 +1605,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() ; }; `````````` </details> https://github.com/llvm/llvm-project/pull/209101 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
