[clang] [clang] All {con, de}structor attributes to use template args (PR #67376)
Alex Brachet via cfe-commits
cfe-commits at lists.llvm.org
Mon Sep 25 14:40:53 PDT 2023
https://github.com/abrachet created https://github.com/llvm/llvm-project/pull/67376
Fixes #67154
>From 5317e66d8997c0406994809901429d5a88c0e0c6 Mon Sep 17 00:00:00 2001
From: Alex Brachet <abrachet at google.com>
Date: Mon, 25 Sep 2023 17:35:13 -0400
Subject: [PATCH] [clang] All {con,de}structor attributes to use template args
Fixes #67154
---
clang/include/clang/Basic/Attr.td | 8 ++++--
clang/lib/CodeGen/CodeGenModule.cpp | 17 +++++++++--
clang/lib/Sema/SemaDeclAttr.cpp | 33 ++++++++++++++--------
clang/test/CodeGenCXX/constructor-attr.cpp | 14 +++++++++
clang/test/CodeGenCXX/destructor-attr.cpp | 20 +++++++++++++
clang/test/Sema/ctor-dtor-attr.cpp | 13 +++++++++
6 files changed, 89 insertions(+), 16 deletions(-)
create mode 100644 clang/test/CodeGenCXX/destructor-attr.cpp
create mode 100644 clang/test/Sema/ctor-dtor-attr.cpp
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}}
More information about the cfe-commits
mailing list