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

Reply via email to