================
@@ -4987,15 +5130,23 @@ void Parser::ParseStructUnionBody(SourceLocation 
RecordLoc,
 
   ParsedAttributes attrs(AttrFactory);
   // If attributes exist after struct contents, parse them.
-  MaybeParseGNUAttributes(attrs, &LateFieldAttrs);
+  MaybeParseGNUAttributes(attrs);
 
   // Late parse field attributes if necessary.
   ParseLexedCAttributeList(LateFieldAttrs, /*EnterScope=*/false);
-
   SmallVector<Decl *, 32> FieldDecls(TagDecl->fields());
 
   Actions.ActOnFields(getCurScope(), RecordLoc, TagDecl, FieldDecls,
                       T.getOpenLocation(), T.getCloseLocation(), attrs);
+  Scope *ParentScope = getCurScope()->getParent();
+  assert(ParentScope);
+  // Process late-parsed type attributes for the outermost record. Nested
+  // non-anonymous records are handled immediately after their declaration is
+  // parsed, which is when it is known whether the record is anonymous.
+  if (getLangOpts().ExperimentalLateParseAttributes &&
+      !ParentScope->getEntity()->isRecord())
----------------
ahatanak wrote:

Looks like it's crashing compiling this piece of code:

```
#define PRODUCT(A ,B) struct prod { A a; B b; } 
#define SUM(A, B) struct sum { _Bool flag; union { A a; B b; }; }
void func1(PRODUCT(int, SUM(float, double)) x);
```

`-fexperimental-late-parse-attributes` is needed for structs like this in the 
test:

```
struct GuardedBy6 {
  // c17-error@-1 {{redefinition of 'GuardedBy6'}}
  int b __attribute__((guarded_by(lock)));
  struct Lock lock;
};
```

`guarded_by(lock)` references `lock`, which is declared after `b` in the struct.

https://github.com/llvm/llvm-project/pull/179612
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to