Skip to content

Commit 3339a00

Browse files
authored
[clang] Respect [[gnu::error]] on functions passed to [[gnu::cleanup]] (#152082)
Forward SourceLocation to `EmitCall` so that clang triggers an error when a function inside `[[gnu::cleanup(func)]]` is annotated with `[[gnu::error("some message")]]`. resolves #146520
1 parent e797c71 commit 3339a00

File tree

3 files changed

+22
-5
lines changed

3 files changed

+22
-5
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@ Bug Fixes to Attribute Support
172172

173173
- ``[[nodiscard]]`` is now respected on Objective-C and Objective-C++ methods.
174174
(#GH141504)
175+
- Using ``[[gnu::cleanup(some_func)]]`` where some_func is annotated with
176+
``[[gnu::error("some error")]]`` now correctly triggers an error. (#GH146520)
175177

176178
Bug Fixes to C++ Support
177179
^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/CodeGen/CGDecl.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -599,10 +599,11 @@ namespace {
599599
llvm::Constant *CleanupFn;
600600
const CGFunctionInfo &FnInfo;
601601
const VarDecl &Var;
602+
const CleanupAttr *Attribute;
602603

603604
CallCleanupFunction(llvm::Constant *CleanupFn, const CGFunctionInfo *Info,
604-
const VarDecl *Var)
605-
: CleanupFn(CleanupFn), FnInfo(*Info), Var(*Var) {}
605+
const VarDecl *Var, const CleanupAttr *Attr)
606+
: CleanupFn(CleanupFn), FnInfo(*Info), Var(*Var), Attribute(Attr) {}
606607

607608
void Emit(CodeGenFunction &CGF, Flags flags) override {
608609
DeclRefExpr DRE(CGF.getContext(), const_cast<VarDecl *>(&Var), false,
@@ -624,8 +625,11 @@ namespace {
624625
CallArgList Args;
625626
Args.add(RValue::get(Arg),
626627
CGF.getContext().getPointerType(Var.getType()));
627-
auto Callee = CGCallee::forDirect(CleanupFn);
628-
CGF.EmitCall(FnInfo, Callee, ReturnValueSlot(), Args);
628+
GlobalDecl GD = GlobalDecl(Attribute->getFunctionDecl());
629+
auto Callee = CGCallee::forDirect(CleanupFn, CGCalleeInfo(GD));
630+
CGF.EmitCall(FnInfo, Callee, ReturnValueSlot(), Args,
631+
/*callOrInvoke*/ nullptr, /*IsMustTail*/ false,
632+
Attribute->getLoc());
629633
}
630634
};
631635
} // end anonymous namespace
@@ -2231,7 +2235,8 @@ void CodeGenFunction::EmitAutoVarCleanups(const AutoVarEmission &emission) {
22312235
assert(F && "Could not find function!");
22322236

22332237
const CGFunctionInfo &Info = CGM.getTypes().arrangeFunctionDeclaration(FD);
2234-
EHStack.pushCleanup<CallCleanupFunction>(NormalAndEHCleanup, F, &Info, &D);
2238+
EHStack.pushCleanup<CallCleanupFunction>(NormalAndEHCleanup, F, &Info, &D,
2239+
CA);
22352240
}
22362241

22372242
// If this is a block variable, call _Block_object_destroy

clang/test/Frontend/backend-attribute-error-warning-optimize.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,13 @@ void indirect(void) {
2020
quux = foo;
2121
quux();
2222
}
23+
24+
// https://github.com/llvm/llvm-project/issues/146520
25+
26+
[[gnu::error("error please")]]
27+
void cleaner_function(char*);
28+
29+
void asdf(void){
30+
[[gnu::cleanup(cleaner_function)]] // expected-error {{call to 'cleaner_function' declared with 'error' attribute: error please}}
31+
char x;
32+
}

0 commit comments

Comments
 (0)