delcypher wrote:

Ok. Now I see what's happening.

These lines here are basically giving ownership of `LateParsedAttribute` to the 
`LateParsedAttrList`

```
      // Handle attributes with arguments that require late parsing.
      LateParsedAttribute *LA =
          new LateParsedAttribute(this, *AttrName, AttrNameLoc);
      LateAttrs->push_back(LA);
```

However `LateParsedAttrList` is basically just a 

```
class LateParsedAttrList: public SmallVector<LateParsedAttribute *, 2> {
...
}
```

so it won't free the pointers when the list is destroyed. If we look at the C++ 
code that handles this we can see a bunch of manual memory management.

```
/// Parse all attributes in LAs, and attach them to Decl D.
void Parser::ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D,
                                     bool EnterScope, bool OnDefinition) {
  assert(LAs.parseSoon() &&
         "Attribute list should be marked for immediate parsing.");
  for (unsigned i = 0, ni = LAs.size(); i < ni; ++i) {
    if (D)
      LAs[i]->addDecl(D);
    ParseLexedAttribute(*LAs[i], EnterScope, OnDefinition);
    delete LAs[i];
  }
  LAs.clear();
}
```

This is a silly footgun. `LateParsedAttrList` should properly take ownership of 
its pointers by deleting them when the list is destroyed.

For now we should just replicate what is done for C++ but once we're confident 
we've fixed things we should make `LateParsedAttrList` properly own its 
pointers.

https://github.com/llvm/llvm-project/pull/90786
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to