[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