[clang-include-cleaner] Make cleanup attr report expr location (#140233)

Instead of reporting the location of the attribute, let's report the
location of the function reference that's passed to the cleanup
attribute as the first argument. This is required as the attribute might
be coming from a macro which means clang-include-cleaner skips the use
as it gets attributed to the header file declaringt the macro and not to
the main file.

To make this work, we have to add a fake argument to the CleanupAttr
constructor so we can pass in the original Expr alongside the function
declaration.

Fixes #140212
This commit is contained in:
Daan De Meyer
2025-05-21 16:40:30 +02:00
committed by GitHub
parent 95bd9eef42
commit 32946ddd2e
4 changed files with 17 additions and 4 deletions

View File

@@ -322,7 +322,7 @@ public:
}
bool VisitCleanupAttr(CleanupAttr *attr) {
report(attr->getLocation(), attr->getFunctionDecl());
report(attr->getArgLoc(), attr->getFunctionDecl());
return true;
}

View File

@@ -573,7 +573,7 @@ TEST(WalkAST, OperatorNewDelete) {
TEST(WalkAST, CleanupAttr) {
testWalk("void* $explicit^freep(void *p);",
"void foo() { __attribute__((^__cleanup__(freep))) char* x = 0; }");
"void foo() { __attribute__((__cleanup__(^freep))) char* x = 0; }");
}
} // namespace

View File

@@ -1354,6 +1354,17 @@ def Cleanup : InheritableAttr {
let Args = [DeclArgument<Function, "FunctionDecl">];
let Subjects = SubjectList<[LocalVar]>;
let Documentation = [CleanupDocs];
// FIXME: DeclArgument should be reworked to also store the
// Expr instead of adding attr specific hacks like the following.
// See the discussion in https://github.com/llvm/llvm-project/pull/14023.
let AdditionalMembers = [{
private:
SourceLocation ArgLoc;
public:
void setArgLoc(const SourceLocation &Loc) { ArgLoc = Loc; }
auto getArgLoc() const { return ArgLoc; }
}];
}
def CmseNSEntry : InheritableAttr, TargetSpecificAttr<TargetARM> {

View File

@@ -3620,7 +3620,9 @@ static void handleCleanupAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
return;
}
D->addAttr(::new (S.Context) CleanupAttr(S.Context, AL, FD));
auto *attr = ::new (S.Context) CleanupAttr(S.Context, AL, FD);
attr->setArgLoc(E->getExprLoc());
D->addAttr(attr);
}
static void handleEnumExtensibilityAttr(Sema &S, Decl *D,