[clang] [C23] Implement WG14 N3037 (PR #132939)

Cyndy Ishida via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 1 12:17:21 PDT 2025


================
@@ -450,6 +453,41 @@ class StmtComparer {
 };
 } // namespace
 
+static bool
+CheckStructurallyEquivalentAttributes(StructuralEquivalenceContext &Context,
+                                      const Decl *D1, const Decl *D2,
+                                      const Decl *PrimaryDecl = nullptr) {
+  // If either declaration has an attribute on it, we treat the declarations
+  // as not being structurally equivalent.
+  // FIXME: this should be handled on a case-by-case basis via tablegen in
+  // Attr.td. There are multiple cases to consider: one declation with the
+  // attribute, another without it; different attribute syntax|spellings for
+  // the same semantic attribute, differences in attribute arguments, order
+  // in which attributes are applied, how to merge attributes if the types are
+  // structurally equivalent, etc.
+  const Attr *D1Attr = nullptr, *D2Attr = nullptr;
+  if (D1->hasAttrs())
+    D1Attr = *D1->getAttrs().begin();
+  if (D2->hasAttrs())
+    D2Attr = *D2->getAttrs().begin();
+  if (D1Attr || D2Attr) {
+    const auto *DiagnoseDecl = cast<TypeDecl>(PrimaryDecl ? PrimaryDecl : D2);
----------------
cyndyishida wrote:

For some more context, we've been qualifying the 21.x branch and discovered that the series of patches related to implementing WG14 N3037, has broken several Objective-C projects with `gnu23` set. Building with clang modules is a common configuration that seems to have been broken here by these structural equivalence checks. 

These are the relevant commits we found that represent the regression. It is basically the set of commits I needed to be able to revert cleanly. 
```
460ff1eb0ef10a599b96a5a7fa1f4bd3973de4c7 - [C23] AST equivalence of attributes (#151196)
3d6fb12dfcef05407439580491430c376489d6a5 - [C23] More improved type compatibility for enumerations (#150946)
3b53c84e338bfb870f49e6a520725d86ff40c375 - C23] Handle type compatibility for enumerations better (#150282)
6769a836e97d5a09b239f78a8fd63cf4dac1fe13 -  [C23] Handle type compatibility of unnamed records (#141783)
ee3610efb511ec0a8d5ebd2016ce23b4b4344cd1  -  Remove unused function; NFC
a4ceac7e3e04c32cb3e334eb89b54d8e99a298f8  - [C23] Implement WG14 N3037 (#132939)
```

Akira has a patch to simply account for `Context.Complain` when diagnosing violations, but that further exposes an issue with modular builds. I've attached a reproducer that contains a set of files & a modulemap to demonstrate the issue. `run.sh` just invokes clang; you can change the path to point to what is correct on your system and assumes you are in the `repro` directory. 

[repro.zip](https://github.com/user-attachments/files/22646854/repro.zip)

The reproduced case basically is that when we are compiling a TU (client.m) that itself is a part of the same project that vends a module. The compiler accepts an option `-fmodule-name=Foo` to let the compiler know this. When this happens, headers from that module are treated textually, but if those same headers are resolved transitively through a different module, that would be respected as a modular header & thus `Foo.pcm` is created and also contains the same declarations. This typically would result in a redeclaration issue, but [the compiler explicitly supports this case through type merging.](https://github.com/llvm/llvm-project/blob/e84dcba9246d696715fe1daa4ddb218182580a70/clang/lib/Serialization/ASTReaderDecl.cpp#L1362) It seems like for the unnamed struct that is in ivar, the structural equivalence check now fails, but previously didn't, due to https://github.com/llvm/llvm-project/blob/e84dcba9246d696715fe1daa4ddb218182580a70/clang/lib/AST/ASTStructuralEquivalence.cpp#L1774 checking `!D1->getIdentifier()` which is the case for unnamed structs. 

We do heavily rely on type merging support & this configuration is working. @AaronBallman could you please take a look? Apologies in advance for the delay in reporting the observed breakages.

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


More information about the cfe-commits mailing list