[clang] [clang] All {con, de}structor attributes to use template args (PR #67376)

via cfe-commits cfe-commits at lists.llvm.org
Mon Sep 25 14:41:53 PDT 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-codegen

<details>
<summary>Changes</summary>

Fixes #<!-- -->67154

---
Full diff: https://github.com/llvm/llvm-project/pull/67376.diff


6 Files Affected:

- (modified) clang/include/clang/Basic/Attr.td (+6-2) 
- (modified) clang/lib/CodeGen/CodeGenModule.cpp (+14-3) 
- (modified) clang/lib/Sema/SemaDeclAttr.cpp (+22-11) 
- (modified) clang/test/CodeGenCXX/constructor-attr.cpp (+14) 
- (added) clang/test/CodeGenCXX/destructor-attr.cpp (+20) 
- (added) clang/test/Sema/ctor-dtor-attr.cpp (+13) 


``````````diff
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index dd4d45171db4899..8c4e63bebf110cf 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1156,9 +1156,11 @@ def ConstInit : InheritableAttr {
 
 def Constructor : InheritableAttr {
   let Spellings = [GCC<"constructor">];
-  let Args = [DefaultIntArgument<"Priority", 65535>];
+  let Args = [ExprArgument<"Priority", 1>];
   let Subjects = SubjectList<[Function]>;
   let Documentation = [CtorDtorDocs];
+  let TemplateDependent = 1;
+  let AdditionalMembers = [{ static const int DefaultPriority = 65535; }];
 }
 
 def CPUSpecific : InheritableAttr {
@@ -1422,9 +1424,11 @@ def Deprecated : InheritableAttr {
 
 def Destructor : InheritableAttr {
   let Spellings = [GCC<"destructor">];
-  let Args = [DefaultIntArgument<"Priority", 65535>];
+  let Args = [ExprArgument<"Priority", 1>];
   let Subjects = SubjectList<[Function]>;
   let Documentation = [CtorDtorDocs];
+  let TemplateDependent = 1;
+  let AdditionalMembers = [{ static const int DefaultPriority = 65535; }];
 }
 
 def EmptyBases : InheritableAttr, TargetSpecificAttr<TargetMicrosoftCXXABI> {
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 130cedcd4f2bf68..e93c36bbce95ec6 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -32,6 +32,7 @@
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
+#include "clang/AST/Expr.h"
 #include "clang/AST/Mangle.h"
 #include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/StmtVisitor.h"
@@ -5661,10 +5662,20 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD,
   setNonAliasAttributes(GD, Fn);
   SetLLVMFunctionAttributesForDefinition(D, Fn);
 
-  if (const ConstructorAttr *CA = D->getAttr<ConstructorAttr>())
-    AddGlobalCtor(Fn, CA->getPriority());
+  auto getPrio = [this](auto *Attr) -> int {
+    Expr *E = Attr->getPriority();
+    if (!E)
+      return Attr->DefaultPriority;
+    if (auto CE = E->getIntegerConstantExpr(getContext()))
+      return CE->getExtValue();
+    return Attr->DefaultPriority;
+  };
+
+  if (const ConstructorAttr *CA = D->getAttr<ConstructorAttr>()) {
+    AddGlobalCtor(Fn, getPrio(CA));
+  }
   if (const DestructorAttr *DA = D->getAttr<DestructorAttr>())
-    AddGlobalDtor(Fn, DA->getPriority(), true);
+    AddGlobalDtor(Fn, getPrio(DA), true);
   if (D->hasAttr<AnnotateAttr>())
     AddGlobalAnnotations(D, Fn);
   if (getLangOpts().OpenMP && D->hasAttr<OMPDeclareTargetDeclAttr>())
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 090a54eedaa07d0..d857f5e78ae97a3 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -2352,26 +2352,37 @@ static void handleUnusedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
   D->addAttr(::new (S.Context) UnusedAttr(S.Context, AL));
 }
 
+template <typename Attr>
+static void handleCtorDtorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
+  uint32_t priority = Attr::DefaultPriority;
+  Expr *E = nullptr;
+  if (AL.getNumArgs()) {
+    E = AL.getArgAsExpr(0);
+    if (E->isValueDependent()) {
+      if (!E->isTypeDependent() && !E->getType()->isIntegerType()) {
+        S.Diag(getAttrLoc(AL), diag::err_attribute_argument_type)
+            << &AL << AANT_ArgumentIntegerConstant << E->getSourceRange();
+        return;
+      }
+    } else if (!checkUInt32Argument(S, AL, AL.getArgAsExpr(0), priority)) {
+      return;
+    }
+  }
+
+  D->addAttr(::new (S.Context) Attr(S.Context, AL, E));
+}
+
 static void handleConstructorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
-  uint32_t priority = ConstructorAttr::DefaultPriority;
   if (S.getLangOpts().HLSL && AL.getNumArgs()) {
     S.Diag(AL.getLoc(), diag::err_hlsl_init_priority_unsupported);
     return;
   }
-  if (AL.getNumArgs() &&
-      !checkUInt32Argument(S, AL, AL.getArgAsExpr(0), priority))
-    return;
 
-  D->addAttr(::new (S.Context) ConstructorAttr(S.Context, AL, priority));
+  handleCtorDtorAttr<ConstructorAttr>(S, D, AL);
 }
 
 static void handleDestructorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
-  uint32_t priority = DestructorAttr::DefaultPriority;
-  if (AL.getNumArgs() &&
-      !checkUInt32Argument(S, AL, AL.getArgAsExpr(0), priority))
-    return;
-
-  D->addAttr(::new (S.Context) DestructorAttr(S.Context, AL, priority));
+  return handleCtorDtorAttr<DestructorAttr>(S, D, AL);
 }
 
 template <typename AttrTy>
diff --git a/clang/test/CodeGenCXX/constructor-attr.cpp b/clang/test/CodeGenCXX/constructor-attr.cpp
index ec27ed210ce760f..af0e147d3e51057 100644
--- a/clang/test/CodeGenCXX/constructor-attr.cpp
+++ b/clang/test/CodeGenCXX/constructor-attr.cpp
@@ -1,6 +1,9 @@
 // RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
 
 // CHECK: @llvm.global_ctors
+// CHECK-SAME: i32 101, ptr @_Z18template_dependentILi101EEvv
+// CHECK-SAME: i32 108, ptr @_Z18template_dependentILi108EEvv
+// CHECK-SAME: i32 111, ptr @_Z19template_dependent2ILi111EEvv
 
 // PR6521
 void bar();
@@ -10,3 +13,14 @@ struct Foo {
     bar();
   }
 };
+
+template <int P>
+[[gnu::constructor(P)]] void template_dependent() {}
+
+template void template_dependent<101>();
+template void template_dependent<100 + 8>();
+
+template <int P>
+__attribute__((constructor(P))) void template_dependent2() {}
+
+template void template_dependent2<111>();
diff --git a/clang/test/CodeGenCXX/destructor-attr.cpp b/clang/test/CodeGenCXX/destructor-attr.cpp
new file mode 100644
index 000000000000000..0f05385187165cf
--- /dev/null
+++ b/clang/test/CodeGenCXX/destructor-attr.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: @llvm.global_dtors
+// CHECK-SAME: i32 101, ptr @_Z18template_dependentILi101EEvv
+// CHECK-SAME: i32 108, ptr @_Z18template_dependentILi108EEvv
+
+// PR6521
+void bar();
+struct Foo {
+  // CHECK-LABEL: define linkonce_odr {{.*}}void @_ZN3Foo3fooEv
+  static void foo() __attribute__((constructor)) {
+    bar();
+  }
+};
+
+template <int P>
+[[gnu::destructor(P)]] void template_dependent() {}
+
+template void template_dependent<101>();
+template void template_dependent<100 + 8>();
diff --git a/clang/test/Sema/ctor-dtor-attr.cpp b/clang/test/Sema/ctor-dtor-attr.cpp
new file mode 100644
index 000000000000000..a6340805b43c2d3
--- /dev/null
+++ b/clang/test/Sema/ctor-dtor-attr.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-strict-prototypes %s
+
+template <int I> [[gnu::constructor(I)]] void ok_ctor();
+template <int I> __attribute__((constructor(I))) void ok2_ctor();
+
+template <int *I> [[gnu::constructor(I)]] void bad_ctor(); // expected-error {{'constructor' attribute requires an integer constant}}
+template <int *I> __attribute__((constructor(I))) void bad2_ctor(); // expected-error {{'constructor' attribute requires an integer constant}}
+
+template <int I> [[gnu::destructor(I)]] void ok_ctor();
+template <int I> __attribute__((destructor(I))) void ok2_dtor();
+
+template <int *I> [[gnu::destructor(I)]] void bad_dtor(); // expected-error {{'destructor' attribute requires an integer constant}}
+template <int *I> __attribute__((destructor(I))) void bad2_dtor(); // expected-error {{'destructor' attribute requires an integer constant}}

``````````

</details>


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


More information about the cfe-commits mailing list