[clang] [C23] Handle type compatibility of unnamed records (PR #141783)

Erich Keane via cfe-commits cfe-commits at lists.llvm.org
Wed May 28 08:06:58 PDT 2025


================
@@ -1751,9 +1751,20 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
   // fulfill the preceding requirements. ... Otherwise, the structure, union,
   // or enumerated types are incompatible.
 
-  if (!NameIsStructurallyEquivalent(*D1, *D2)) {
+  // Note: "the same tag" refers to the identifier for the structure; two
+  // structures without names are not compatible within a TU. In C23, if either
+  // declaration has no name, they're not equivalent. However, the paragraph
+  // after the bulleted list goes on to talk about compatibility of anonymous
+  // structure and union members, so this prohibition only applies to top-level
+  // declarations, not members.
+  if (Context.LangOpts.C23 && (!D1->getIdentifier() || !D2->getIdentifier()) &&
+      (D1->getDeclContext()->isTranslationUnit() ||
----------------
erichkeane wrote:

Does lexical decl context come into play here at all?  

Also, and this might be my C++-brain firing here, but is this sufficient?  I know in C++ we typically check `isFileContextDecl` but IIRC that is just namespaces...

Also-also-- what about structs who are defined 'inline' (or whatever y'all call it)... are those never equal too?  Something like defined in a param list, or in an enum-initializer, or function scope?

So I wonder if we want to invert this and check if decl-context is a RecordDecl?

https://github.com/llvm/llvm-project/pull/141783


More information about the cfe-commits mailing list