https://github.com/jhuber6 created 
https://github.com/llvm/llvm-project/pull/129917

Summary:
The `-Wglobal-constructors` option is useful for restricting the usage
of global constructors / destructors. However, it currently ignores the
attributes that introduce global constructors, meaning that the module
can still have ctors if `-Werror` is set. If this is intentional by the
user, I believe it would be more correct to push the diagnostic.


>From 58e9c848c648b919c7ea3500f6928b7474f7e582 Mon Sep 17 00:00:00 2001
From: Joseph Huber <hube...@outlook.com>
Date: Wed, 5 Mar 2025 13:27:19 -0600
Subject: [PATCH] [Clang] Make '-Wglobal-constructors` work on the GNU
 attributes

Summary:
The `-Wglobal-constructors` option is useful for restricting the usage
of global constructors / destructors. However, it currently ignores the
attributes that introduce global constructors, meaning that the module
can still have ctors if `-Werror` is set. If this is intentional by the
user, I believe it would be more correct to push the diagnostic.
---
 clang/lib/Sema/SemaDeclAttr.cpp                      | 12 ++++++++++++
 .../SemaCXX/attr-require-constant-initialization.cpp |  5 +++++
 2 files changed, 17 insertions(+)

diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index fdf3b9c636127..9daa47c533ad2 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -7596,6 +7596,18 @@ void Sema::ProcessDeclAttributeList(
     D->setInvalidDecl();
   }
 
+  // Warn on global constructors and destructors created by attributes.
+  if (D->hasAttr<ConstructorAttr>() &&
+      !getDiagnostics().isIgnored(diag::warn_global_constructor,
+                                  D->getLocation()))
+    Diag(D->getLocation(), diag::warn_global_constructor)
+        << D->getSourceRange();
+  if (D->hasAttr<DestructorAttr>() &&
+      !getDiagnostics().isIgnored(diag::warn_global_destructor,
+                                  D->getLocation()))
+    Diag(D->getLocation(), diag::warn_global_destructor)
+        << D->getSourceRange();
+
   // Do this check after processing D's attributes because the attribute
   // objc_method_family can change whether the given method is in the init
   // family, and it can be applied after objc_designated_initializer. This is a
diff --git a/clang/test/SemaCXX/attr-require-constant-initialization.cpp 
b/clang/test/SemaCXX/attr-require-constant-initialization.cpp
index 4c0a834551715..b1736ea7a3ebe 100644
--- a/clang/test/SemaCXX/attr-require-constant-initialization.cpp
+++ b/clang/test/SemaCXX/attr-require-constant-initialization.cpp
@@ -337,6 +337,11 @@ constexpr TestCtor<NotC> inval_constexpr(42); // 
expected-error {{must be initia
 ATTR constexpr TestCtor<NotC> inval_constexpr2(42); // expected-error {{must 
be initialized by a constant expression}}
 // expected-note@-1 {{in call to 'TestCtor(42)'}}
 
+[[gnu::constructor]] void ctor() {}
+// expected-warning@-1 {{declaration requires a global constructor}}
+[[gnu::destructor]] void dtor() {}
+// expected-warning@-1 {{declaration requires a global destructor}}
+
 #elif defined(TEST_THREE)
 #if defined(__cplusplus)
 #error This test requires C

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to