================
@@ -195,6 +195,25 @@ bool Parser::ParseSingleGNUAttribute(ParsedAttributes 
&Attrs,
   // Handle attributes with arguments that require late parsing.
   LateParsedAttribute *LA =
       new LateParsedAttribute(this, *AttrName, AttrNameLoc);
+
+  // Keep the innermost prototype's parameters available in case they are 
needed
+  // by late-parsing attributes. A function keeps its own parameters in scope,
+  // so skip it; a parameter of function type is adjusted to a pointer, so keep
+  // it.
+  if (D && (!D->isFunctionDeclarator() || D->isPrototypeContext())) {
----------------
melver wrote:

Attributes like guarded_by and pt_guarded_by have ParseArgsInFunctionScope = 0 
because they guard the function pointer variable/field itself, not a call 
through it.

If a function pointer field has a parameter whose name collides with the 
struct's mutex field:
```
    struct S {
      void (*cb)(int mu) GUARDED_BY(mu);
      struct Mutex mu;
    };
```
populating LA->ProtoParams for guarded_by brings int mu into scope during late 
parsing and shadows S::mu (or triggers the ambiguity error in C++), whereas 
eager parsing in C resolves S::mu.

Should this be:
```
    +  if (D && IsAttributeArgsParsedInFunctionScope(*AttrName) &&
    +      (!D->isFunctionDeclarator() || D->isPrototypeContext())) {
```

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

Reply via email to