[clang] [Clang] Fix crash involving `__attribute__((cleanup))` attributes and improve handling of multiple `cleanup` attributes (PR #207785)

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Tue Jul 7 08:08:06 PDT 2026


================
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -std=c11 -triple x86_64-unknown-linux -verify -fsyntax-only %s
+
+// Check that a cleanup attribute on an invalid declaration doesn't crash,
+// and that we diagnose duplicate cleanup attributes.
+
+#define C(x) __attribute__((cleanup(x)))
+void foo(double *x U) {} // expected-error {{expected ')'}} expected-note {{to match this '('}}
+void bar() {
+  C(foo) C(foo) baz8; // expected-error {{type specifier missing, defaults to 'int'}} \
+                         expected-warning 2 {{passing 4-byte aligned argument to 8-byte aligned parameter}} \
+                         expected-warning {{declaration has multiple 'cleanup' attributes; all but the last one will be ignored}} \
+                         expected-error {{'cleanup' function 'foo' parameter has type 'double *' which is incompatible with type 'int *'}}
+}
+
+void f1(double *x);
+void f2(double *x);
+void f3(double *x);
+void bar2() {
+  C(f1) // expected-warning {{declaration has multiple 'cleanup' attributes; all but the last one will be ignored}}
----------------
AaronBallman wrote:

Also worth testing:
```
[[gnu::cleanup(f1), gnu::cleanup(f2)]] double d;
```
I cannot find a way to inherit the attribute through a previous declaration because `cleanup` doesn't apply to external variables and you can't do things like declare templates at block scope. But if we can think of a way to hit that case, it'd be the only other test scenario I can think of.

https://github.com/llvm/llvm-project/pull/207785


More information about the cfe-commits mailing list