https://github.com/Mr-Anyone updated https://github.com/llvm/llvm-project/pull/152082
>From c0fda068d6a17845593702ea6198ad458bec217d Mon Sep 17 00:00:00 2001 From: Vincent <[email protected]> Date: Tue, 5 Aug 2025 13:39:02 +0800 Subject: [PATCH 1/3] [clang] Emit Error for Cleanup Attribute Functions Marked with Error Attribute Forward SourceLocation to `EmitCall` so that clang triggers an error when a function inside [[gnu::cleanup(func)]] is annotated with [[gnu::error("...")]]. resolves #146520 --- clang/docs/ReleaseNotes.rst | 2 ++ clang/lib/CodeGen/CGDecl.cpp | 11 +++++++++-- .../backend-attribute-error-warning-optimize.c | 10 ++++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 9231f2cae9bfa..4fc354e254e38 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -152,6 +152,8 @@ Bug Fixes to Attribute Support - ``[[nodiscard]]`` is now respected on Objective-C and Objective-C++ methods. (#GH141504) +- Using ``[[gnu::cleanup(some_func)]]`` where some_func is annotated with + ``[[gnu::error("some error")]]`` now correctly triggers an error. (#GH146520) Bug Fixes to C++ Support ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index 04f13c7d7a6a3..8f1d1fac3f083 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -624,8 +624,15 @@ namespace { CallArgList Args; Args.add(RValue::get(Arg), CGF.getContext().getPointerType(Var.getType())); - auto Callee = CGCallee::forDirect(CleanupFn); - CGF.EmitCall(FnInfo, Callee, ReturnValueSlot(), Args); + bool HasCleanupAttr = Var.hasAttr<CleanupAttr>(); + GlobalDecl GD = HasCleanupAttr + ? (Var.getAttr<CleanupAttr>()->getFunctionDecl()) + : GlobalDecl(); + SourceLocation Loc = HasCleanupAttr ? Var.getAttr<CleanupAttr>()->getLoc() + : SourceLocation(); + auto Callee = CGCallee::forDirect(CleanupFn, CGCalleeInfo(GD)); + CGF.EmitCall(FnInfo, Callee, ReturnValueSlot(), Args, + /*callOrInvoke*/ nullptr, /*IsMustTail*/ false, Loc); } }; } // end anonymous namespace diff --git a/clang/test/Frontend/backend-attribute-error-warning-optimize.c b/clang/test/Frontend/backend-attribute-error-warning-optimize.c index d3951e3b6b1f5..d5a8d57e36c96 100644 --- a/clang/test/Frontend/backend-attribute-error-warning-optimize.c +++ b/clang/test/Frontend/backend-attribute-error-warning-optimize.c @@ -20,3 +20,13 @@ void indirect(void) { quux = foo; quux(); } + +// https://github.com/llvm/llvm-project/issues/146520 + +[[gnu::error("error please")]] +void cleaner_function(char*); + +void asdf(void){ + [[gnu::cleanup(cleaner_function)]] // expected-error {{call to 'cleaner_function' declared with 'error' attribute: error please}} + char x; +} >From c36e978c05a50619f9e92a3c3176d2a0c70fe0cc Mon Sep 17 00:00:00 2001 From: Vincent <[email protected]> Date: Wed, 6 Aug 2025 11:15:20 +0800 Subject: [PATCH 2/3] Saved SourceLocation In CallCleanupFunction --- clang/lib/CodeGen/CGDecl.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index 8f1d1fac3f083..1dc765d389b5f 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -599,10 +599,11 @@ namespace { llvm::Constant *CleanupFn; const CGFunctionInfo &FnInfo; const VarDecl &Var; + SourceLocation Loc; CallCleanupFunction(llvm::Constant *CleanupFn, const CGFunctionInfo *Info, - const VarDecl *Var) - : CleanupFn(CleanupFn), FnInfo(*Info), Var(*Var) {} + const VarDecl *Var, SourceLocation Location) + : CleanupFn(CleanupFn), FnInfo(*Info), Var(*Var), Loc(Location) {} void Emit(CodeGenFunction &CGF, Flags flags) override { DeclRefExpr DRE(CGF.getContext(), const_cast<VarDecl *>(&Var), false, @@ -628,8 +629,6 @@ namespace { GlobalDecl GD = HasCleanupAttr ? (Var.getAttr<CleanupAttr>()->getFunctionDecl()) : GlobalDecl(); - SourceLocation Loc = HasCleanupAttr ? Var.getAttr<CleanupAttr>()->getLoc() - : SourceLocation(); auto Callee = CGCallee::forDirect(CleanupFn, CGCalleeInfo(GD)); CGF.EmitCall(FnInfo, Callee, ReturnValueSlot(), Args, /*callOrInvoke*/ nullptr, /*IsMustTail*/ false, Loc); @@ -2238,7 +2237,8 @@ void CodeGenFunction::EmitAutoVarCleanups(const AutoVarEmission &emission) { assert(F && "Could not find function!"); const CGFunctionInfo &Info = CGM.getTypes().arrangeFunctionDeclaration(FD); - EHStack.pushCleanup<CallCleanupFunction>(NormalAndEHCleanup, F, &Info, &D); + EHStack.pushCleanup<CallCleanupFunction>(NormalAndEHCleanup, F, &Info, &D, + CA->getLoc()); } // If this is a block variable, call _Block_object_destroy >From 1c22a113c30b89437a2cfa1fe3ee9527b765b370 Mon Sep 17 00:00:00 2001 From: Vincent <[email protected]> Date: Wed, 6 Aug 2025 11:36:50 +0800 Subject: [PATCH 3/3] Store Pointer to CleanupAttr Instead --- clang/lib/CodeGen/CGDecl.cpp | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index 1dc765d389b5f..ff2dadad0d4ef 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -599,11 +599,11 @@ namespace { llvm::Constant *CleanupFn; const CGFunctionInfo &FnInfo; const VarDecl &Var; - SourceLocation Loc; + const CleanupAttr *Attribute; CallCleanupFunction(llvm::Constant *CleanupFn, const CGFunctionInfo *Info, - const VarDecl *Var, SourceLocation Location) - : CleanupFn(CleanupFn), FnInfo(*Info), Var(*Var), Loc(Location) {} + const VarDecl *Var, const CleanupAttr *Attr) + : CleanupFn(CleanupFn), FnInfo(*Info), Var(*Var), Attribute(Attr) {} void Emit(CodeGenFunction &CGF, Flags flags) override { DeclRefExpr DRE(CGF.getContext(), const_cast<VarDecl *>(&Var), false, @@ -625,13 +625,11 @@ namespace { CallArgList Args; Args.add(RValue::get(Arg), CGF.getContext().getPointerType(Var.getType())); - bool HasCleanupAttr = Var.hasAttr<CleanupAttr>(); - GlobalDecl GD = HasCleanupAttr - ? (Var.getAttr<CleanupAttr>()->getFunctionDecl()) - : GlobalDecl(); + GlobalDecl GD = GlobalDecl(Attribute->getFunctionDecl()); auto Callee = CGCallee::forDirect(CleanupFn, CGCalleeInfo(GD)); CGF.EmitCall(FnInfo, Callee, ReturnValueSlot(), Args, - /*callOrInvoke*/ nullptr, /*IsMustTail*/ false, Loc); + /*callOrInvoke*/ nullptr, /*IsMustTail*/ false, + Attribute->getLoc()); } }; } // end anonymous namespace @@ -2238,7 +2236,7 @@ void CodeGenFunction::EmitAutoVarCleanups(const AutoVarEmission &emission) { const CGFunctionInfo &Info = CGM.getTypes().arrangeFunctionDeclaration(FD); EHStack.pushCleanup<CallCleanupFunction>(NormalAndEHCleanup, F, &Info, &D, - CA->getLoc()); + CA); } // If this is a block variable, call _Block_object_destroy _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
