Skip to content

Commit 7ca00a9

Browse files
SC llvm teamSC llvm team
SC llvm team
authored and
SC llvm team
committed
Merged main:210e8984fe15 into amd-gfx:b56415c184f2
Local branch amd-gfx b56415c Merged main:4effda09d897 into amd-gfx:3d7ab622862d Remote branch main 210e898 [lld/mac] Resolve defined symbols before undefined symbols in bitcode (llvm#67445)
2 parents b56415c + 210e898 commit 7ca00a9

File tree

89 files changed

+1864
-864
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

89 files changed

+1864
-864
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -171,11 +171,6 @@ Attribute Changes in Clang
171171
automatic diagnostic to use parameters of types that the format style
172172
supports but that are never the result of default argument promotion, such as
173173
``float``. (`#59824: <https://github.com/llvm/llvm-project/issues/59824>`_)
174-
- The ``constructor`` and ``destructor`` attributes now diagnose when:
175-
- the priority is not between 101 and 65535, inclusive,
176-
- the function it is applied to accepts arguments or has a non-void return
177-
type, or
178-
- the function it is applied to is a non-static member function (C++).
179174

180175
Improvements to Clang's diagnostics
181176
-----------------------------------

clang/include/clang/Basic/AttrDocs.td

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7251,10 +7251,8 @@ after returning from ``main()`` or when the ``exit()`` function has been
72517251
called. Note, ``quick_exit()``, ``_Exit()``, and ``abort()`` prevent a function
72527252
marked ``destructor`` from being called.
72537253

7254-
The constructor or destructor function cannot accept any arguments and its
7255-
return type should be ``void``, ``int``, or ``unsigned int``. The latter two
7256-
types are supported for historical reasons. In C++ language modes, the function
7257-
cannot be marked ``consteval``, nor can it be a non-static member function.
7254+
The constructor or destructor function should not accept any arguments and its
7255+
return type should be ``void``.
72587256

72597257
The attributes accept an optional argument used to specify the priority order
72607258
in which to execute constructor and destructor functions. The priority is

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2864,8 +2864,6 @@ def warn_cxx11_compat_constexpr_body_multiple_return : Warning<
28642864
InGroup<CXXPre14Compat>, DefaultIgnore;
28652865
def note_constexpr_body_previous_return : Note<
28662866
"previous return statement is here">;
2867-
def err_ctordtor_attr_consteval : Error<
2868-
"%0 attribute cannot be applied to a 'consteval' function">;
28692867

28702868
// C++20 function try blocks in constexpr
28712869
def ext_constexpr_function_try_block_cxx20 : ExtWarn<
@@ -3178,11 +3176,6 @@ def err_alignas_underaligned : Error<
31783176
"requested alignment is less than minimum alignment of %1 for type %0">;
31793177
def warn_aligned_attr_underaligned : Warning<err_alignas_underaligned.Summary>,
31803178
InGroup<IgnoredAttributes>;
3181-
def err_ctor_dtor_attr_on_non_void_func : Error<
3182-
"%0 attribute can only be applied to a function which accepts no arguments "
3183-
"and has a 'void' or 'int' return type">;
3184-
def err_ctor_dtor_member_func : Error<
3185-
"%0 attribute cannot be applied to a member function">;
31863179
def err_attribute_sizeless_type : Error<
31873180
"%0 attribute cannot be applied to sizeless type %1">;
31883181
def err_attribute_argument_n_type : Error<

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 23 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -2352,78 +2352,26 @@ static void handleUnusedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
23522352
D->addAttr(::new (S.Context) UnusedAttr(S.Context, AL));
23532353
}
23542354

2355-
static bool diagnoseInvalidPriority(Sema &S, uint32_t Priority,
2356-
const ParsedAttr &A,
2357-
SourceLocation PriorityLoc) {
2358-
constexpr uint32_t ReservedPriorityLower = 101, ReservedPriorityUpper = 65535;
2359-
2360-
// Only perform the priority check if the attribute is outside of a system
2361-
// header. Values <= 100 are reserved for the implementation, and libc++
2362-
// benefits from being able to specify values in that range. Values > 65535
2363-
// are reserved for historical reasons.
2364-
if ((Priority < ReservedPriorityLower || Priority > ReservedPriorityUpper) &&
2365-
!S.getSourceManager().isInSystemHeader(A.getLoc())) {
2366-
S.Diag(A.getLoc(), diag::err_attribute_argument_out_of_range)
2367-
<< PriorityLoc << A << ReservedPriorityLower << ReservedPriorityUpper;
2368-
A.setInvalid();
2369-
return true;
2370-
}
2371-
return false;
2372-
}
2373-
2374-
template <typename CtorDtorAttr>
2375-
static void handleCtorDtorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2376-
uint32_t Priority = CtorDtorAttr::DefaultPriority;
2355+
static void handleConstructorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2356+
uint32_t priority = ConstructorAttr::DefaultPriority;
23772357
if (S.getLangOpts().HLSL && AL.getNumArgs()) {
23782358
S.Diag(AL.getLoc(), diag::err_hlsl_init_priority_unsupported);
23792359
return;
23802360
}
2361+
if (AL.getNumArgs() &&
2362+
!checkUInt32Argument(S, AL, AL.getArgAsExpr(0), priority))
2363+
return;
23812364

2382-
// If we're given an argument for the priority, check that it's valid.
2383-
if (AL.getNumArgs()) {
2384-
if (!checkUInt32Argument(S, AL, AL.getArgAsExpr(0), Priority))
2385-
return;
2386-
2387-
// Ensure the priority is in a reasonable range.
2388-
if (diagnoseInvalidPriority(S, Priority, AL,
2389-
AL.getArgAsExpr(0)->getExprLoc()))
2390-
return;
2391-
}
2365+
D->addAttr(::new (S.Context) ConstructorAttr(S.Context, AL, priority));
2366+
}
23922367

2393-
// Ensure the function we're attaching to is something that is sensible to
2394-
// automatically call before or after main(); it should accept no arguments.
2395-
// In theory, a void return type is the only truly safe return type (consider
2396-
// that calling conventions may place returned values in a hidden pointer
2397-
// argument passed to the function that will not be present when called
2398-
// automatically). However, there is a significant amount of existing code
2399-
// which uses an int return type. So we will accept void, int, and
2400-
// unsigned int return types. Any other return type, or a non-void parameter
2401-
// list is treated as an error because it's a form of type system
2402-
// incompatibility. The function also cannot be a member function. We allow
2403-
// K&R C functions because that's a difficult edge case where it depends on
2404-
// how the function is defined as to whether it does or does not expect
2405-
// arguments.
2406-
const auto *FD = cast<FunctionDecl>(D);
2407-
QualType RetTy = FD->getReturnType();
2408-
if (!(RetTy->isVoidType() ||
2409-
RetTy->isSpecificBuiltinType(BuiltinType::UInt) ||
2410-
RetTy->isSpecificBuiltinType(BuiltinType::Int)) ||
2411-
(FD->hasPrototype() && FD->getNumParams() != 0)) {
2412-
S.Diag(AL.getLoc(), diag::err_ctor_dtor_attr_on_non_void_func)
2413-
<< AL << FD->getSourceRange();
2368+
static void handleDestructorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2369+
uint32_t priority = DestructorAttr::DefaultPriority;
2370+
if (AL.getNumArgs() &&
2371+
!checkUInt32Argument(S, AL, AL.getArgAsExpr(0), priority))
24142372
return;
2415-
} else if (const auto *MD = dyn_cast<CXXMethodDecl>(FD);
2416-
MD && MD->isInstance()) {
2417-
S.Diag(AL.getLoc(), diag::err_ctor_dtor_member_func)
2418-
<< AL << FD->getSourceRange();
2419-
return;
2420-
} else if (FD->isConsteval()) {
2421-
S.Diag(AL.getLoc(), diag::err_ctordtor_attr_consteval)
2422-
<< AL << FD->getSourceRange();
2423-
return;
2424-
}
24252373

2426-
D->addAttr(CtorDtorAttr::Create(S.Context, Priority, AL));
2374+
D->addAttr(::new (S.Context) DestructorAttr(S.Context, AL, priority));
24272375
}
24282376

24292377
template <typename AttrTy>
@@ -3940,9 +3888,16 @@ static void handleInitPriorityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
39403888
return;
39413889
}
39423890

3943-
if (diagnoseInvalidPriority(S, prioritynum, AL, E->getExprLoc()))
3891+
// Only perform the priority check if the attribute is outside of a system
3892+
// header. Values <= 100 are reserved for the implementation, and libc++
3893+
// benefits from being able to specify values in that range.
3894+
if ((prioritynum < 101 || prioritynum > 65535) &&
3895+
!S.getSourceManager().isInSystemHeader(AL.getLoc())) {
3896+
S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_range)
3897+
<< E->getSourceRange() << AL << 101 << 65535;
3898+
AL.setInvalid();
39443899
return;
3945-
3900+
}
39463901
D->addAttr(::new (S.Context) InitPriorityAttr(S.Context, AL, prioritynum));
39473902
}
39483903

@@ -8975,13 +8930,13 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
89758930
handlePassObjectSizeAttr(S, D, AL);
89768931
break;
89778932
case ParsedAttr::AT_Constructor:
8978-
handleCtorDtorAttr<ConstructorAttr>(S, D, AL);
8933+
handleConstructorAttr(S, D, AL);
89798934
break;
89808935
case ParsedAttr::AT_Deprecated:
89818936
handleDeprecatedAttr(S, D, AL);
89828937
break;
89838938
case ParsedAttr::AT_Destructor:
8984-
handleCtorDtorAttr<DestructorAttr>(S, D, AL);
8939+
handleDestructorAttr(S, D, AL);
89858940
break;
89868941
case ParsedAttr::AT_EnableIf:
89878942
handleEnableIfAttr(S, D, AL);

clang/test/CodeGen/PowerPC/aix-destructor-attribute.c

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@
1212
// RUN: -fno-use-cxa-atexit -fregister-global-dtors-with-atexit < %s | \
1313
// RUN: FileCheck --check-prefix=REGISTER %s
1414

15-
int bar(void) __attribute__((destructor(101)));
15+
int bar(void) __attribute__((destructor(100)));
1616
int bar2(void) __attribute__((destructor(65535)));
17+
int bar3(int) __attribute__((destructor(65535)));
1718

1819
int bar(void) {
1920
return 1;
@@ -23,12 +24,16 @@ int bar2(void) {
2324
return 2;
2425
}
2526

26-
// NO-REGISTER: @llvm.global_dtors = appending global [2 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 101, ptr @bar, ptr null }, { i32, ptr, ptr } { i32 65535, ptr @bar2, ptr null }]
27+
int bar3(int a) {
28+
return a;
29+
}
30+
31+
// NO-REGISTER: @llvm.global_dtors = appending global [3 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 100, ptr @bar, ptr null }, { i32, ptr, ptr } { i32 65535, ptr @bar2, ptr null }, { i32, ptr, ptr } { i32 65535, ptr @bar3, ptr null }]
2732

28-
// REGISTER: @llvm.global_ctors = appending global [2 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 101, ptr @__GLOBAL_init_101, ptr null }, { i32, ptr, ptr } { i32 65535, ptr @__GLOBAL_init_65535, ptr null }]
29-
// REGISTER: @llvm.global_dtors = appending global [2 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 101, ptr @__GLOBAL_cleanup_101, ptr null }, { i32, ptr, ptr } { i32 65535, ptr @__GLOBAL_cleanup_65535, ptr null }]
33+
// REGISTER: @llvm.global_ctors = appending global [2 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 100, ptr @__GLOBAL_init_100, ptr null }, { i32, ptr, ptr } { i32 65535, ptr @__GLOBAL_init_65535, ptr null }]
34+
// REGISTER: @llvm.global_dtors = appending global [2 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 100, ptr @__GLOBAL_cleanup_100, ptr null }, { i32, ptr, ptr } { i32 65535, ptr @__GLOBAL_cleanup_65535, ptr null }]
3035

31-
// REGISTER: define internal void @__GLOBAL_init_101() [[ATTR:#[0-9]+]] {
36+
// REGISTER: define internal void @__GLOBAL_init_100() [[ATTR:#[0-9]+]] {
3237
// REGISTER: entry:
3338
// REGISTER: %0 = call i32 @atexit(ptr @bar)
3439
// REGISTER: ret void
@@ -37,10 +42,11 @@ int bar2(void) {
3742
// REGISTER: define internal void @__GLOBAL_init_65535() [[ATTR:#[0-9]+]] {
3843
// REGISTER: entry:
3944
// REGISTER: %0 = call i32 @atexit(ptr @bar2)
45+
// REGISTER: %1 = call i32 @atexit(ptr @bar3)
4046
// REGISTER: ret void
4147
// REGISTER: }
4248

43-
// REGISTER: define internal void @__GLOBAL_cleanup_101() [[ATTR:#[0-9]+]] {
49+
// REGISTER: define internal void @__GLOBAL_cleanup_100() [[ATTR:#[0-9]+]] {
4450
// REGISTER: entry:
4551
// REGISTER: %0 = call i32 @unatexit(ptr @bar)
4652
// REGISTER: %needs_destruct = icmp eq i32 %0, 0
@@ -56,11 +62,20 @@ int bar2(void) {
5662

5763
// REGISTER: define internal void @__GLOBAL_cleanup_65535() [[ATTR:#[0-9]+]] {
5864
// REGISTER: entry:
59-
// REGISTER: %0 = call i32 @unatexit(ptr @bar2)
65+
// REGISTER: %0 = call i32 @unatexit(ptr @bar3)
6066
// REGISTER: %needs_destruct = icmp eq i32 %0, 0
61-
// REGISTER: br i1 %needs_destruct, label %destruct.call, label %destruct.end
67+
// REGISTER: br i1 %needs_destruct, label %destruct.call, label %unatexit.call
6268

6369
// REGISTER: destruct.call:
70+
// REGISTER: call void @bar3()
71+
// REGISTER: br label %unatexit.call
72+
73+
// REGISTER: unatexit.call:
74+
// REGISTER: %1 = call i32 @unatexit(ptr @bar2)
75+
// REGISTER: %needs_destruct1 = icmp eq i32 %1, 0
76+
// REGISTER: br i1 %needs_destruct1, label %destruct.call2, label %destruct.end
77+
78+
// REGISTER: destruct.call2:
6479
// REGISTER: call void @bar2()
6580
// REGISTER: br label %destruct.end
6681

clang/test/CodeGen/debug-info-codeview-unnamed.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,23 @@ int main(int argc, char* argv[], char* arge[]) {
88
//
99
struct { int bar; } one = {42};
1010
//
11-
// LINUX: !{{[0-9]+}} = !DILocalVariable(name: "one"
12-
// LINUX-SAME: type: [[TYPE_OF_ONE:![0-9]+]]
13-
// LINUX-SAME: )
14-
// LINUX: [[TYPE_OF_ONE]] = distinct !DICompositeType(
11+
// LINUX: [[TYPE_OF_ONE:![0-9]+]] = distinct !DICompositeType(
1512
// LINUX-SAME: tag: DW_TAG_structure_type
1613
// LINUX-NOT: name:
1714
// LINUX-NOT: identifier:
1815
// LINUX-SAME: )
16+
// LINUX: !{{[0-9]+}} = !DILocalVariable(name: "one"
17+
// LINUX-SAME: type: [[TYPE_OF_ONE]]
18+
// LINUX-SAME: )
1919
//
20-
// MSVC: !{{[0-9]+}} = !DILocalVariable(name: "one"
21-
// MSVC-SAME: type: [[TYPE_OF_ONE:![0-9]+]]
22-
// MSVC-SAME: )
23-
// MSVC: [[TYPE_OF_ONE]] = distinct !DICompositeType
20+
// MSVC: [[TYPE_OF_ONE:![0-9]+]] = distinct !DICompositeType
2421
// MSVC-SAME: tag: DW_TAG_structure_type
2522
// MSVC-NOT: name:
2623
// MSVC-NOT: identifier:
2724
// MSVC-SAME: )
25+
// MSVC: !{{[0-9]+}} = !DILocalVariable(name: "one"
26+
// MSVC-SAME: type: [[TYPE_OF_ONE]]
27+
// MSVC-SAME: )
2828

2929
return 0;
3030
}

clang/test/CodeGen/debug-info-unused-types.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@ void quux(void) {
1818
// CHECK: !DICompileUnit{{.+}}retainedTypes: [[RETTYPES:![0-9]+]]
1919
// CHECK: [[TYPE0:![0-9]+]] = !DICompositeType(tag: DW_TAG_enumeration_type, name: "bar"
2020
// CHECK: [[TYPE1:![0-9]+]] = !DIEnumerator(name: "BAR"
21-
// CHECK: [[TYPE2:![0-9]+]] = !DICompositeType(tag: DW_TAG_enumeration_type, name: "z"
22-
// CHECK: [[TYPE3:![0-9]+]] = !DIEnumerator(name: "Z"
23-
// CHECK: [[RETTYPES]] = !{[[TYPE4:![0-9]+]], [[TYPE5:![0-9]+]], [[TYPE0]], [[TYPE6:![0-9]+]], {{![0-9]+}}, [[TYPE7:![0-9]+]], [[TYPE2]], [[TYPE8:![0-9]+]]}
24-
// CHECK: [[TYPE4]] = !DIDerivedType(tag: DW_TAG_typedef, name: "my_int"
25-
// CHECK: [[TYPE5]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "foo"
26-
// CHECK: [[TYPE6]] = distinct !DICompositeType(tag: DW_TAG_union_type, name: "baz"
27-
// CHECK: [[TYPE7]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "y"
21+
// CHECK: [[RETTYPES]] = !{[[TYPE2:![0-9]+]], [[TYPE3:![0-9]+]], [[TYPE0]], [[TYPE4:![0-9]+]], {{![0-9]+}}}
22+
// CHECK: [[TYPE2]] = !DIDerivedType(tag: DW_TAG_typedef, name: "my_int"
23+
// CHECK: [[TYPE3]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "foo"
24+
// CHECK: [[TYPE4]] = distinct !DICompositeType(tag: DW_TAG_union_type, name: "baz"
25+
// CHECK: [[SP:![0-9]+]] = distinct !DISubprogram(name: "quux", {{.*}}, retainedNodes: [[SPRETNODES:![0-9]+]]
26+
// CHECK: [[SPRETNODES]] = !{[[TYPE5:![0-9]+]], [[TYPE6:![0-9]+]], [[TYPE8:![0-9]+]]}
27+
// CHECK: [[TYPE5]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "y"
28+
// CHECK: [[TYPE6]] = !DICompositeType(tag: DW_TAG_enumeration_type, name: "z"
29+
// CHECK: [[TYPE7:![0-9]+]] = !DIEnumerator(name: "Z"
2830
// CHECK: [[TYPE8]] = distinct !DICompositeType(tag: DW_TAG_union_type, name: "w"
2931

3032
// Check that debug info is not emitted for the typedef, struct, enum, and

clang/test/CodeGen/debug-info-unused-types.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@ void quux() {
1313
// CHECK: !DICompileUnit{{.+}}retainedTypes: [[RETTYPES:![0-9]+]]
1414
// CHECK: [[TYPE0:![0-9]+]] = !DICompositeType(tag: DW_TAG_enumeration_type, name: "baz"
1515
// CHECK: [[TYPE1:![0-9]+]] = !DIEnumerator(name: "BAZ"
16-
// CHECK: [[TYPE2:![0-9]+]] = !DICompositeType(tag: DW_TAG_enumeration_type, name: "z"
17-
// CHECK: [[TYPE3:![0-9]+]] = !DIEnumerator(name: "Z"
18-
// CHECK: [[RETTYPES]] = !{[[TYPE4:![0-9]+]], [[TYPE5:![0-9]+]], [[TYPE0]], {{![0-9]+}}, [[TYPE6:![0-9]+]], [[TYPE2]]}
19-
// CHECK: [[TYPE4]] = !DIDerivedType(tag: DW_TAG_typedef, name: "foo"
20-
// CHECK: [[TYPE5]] = distinct !DICompositeType(tag: DW_TAG_class_type, name: "bar"
21-
// CHECK: [[TYPE6]] = distinct !DICompositeType(tag: DW_TAG_class_type, name: "y"
16+
// CHECK: [[RETTYPES]] = !{[[TYPE2:![0-9]+]], [[TYPE3:![0-9]+]], [[TYPE0]], {{![0-9]+}}}
17+
// CHECK: [[TYPE2]] = !DIDerivedType(tag: DW_TAG_typedef, name: "foo"
18+
// CHECK: [[TYPE3]] = distinct !DICompositeType(tag: DW_TAG_class_type, name: "bar"
19+
// CHECK: [[SP:![0-9]+]] = distinct !DISubprogram(name: "quux", {{.*}}, retainedNodes: [[SPRETNODES:![0-9]+]]
20+
// CHECK: [[SPRETNODES]] = !{[[TYPE4:![0-9]+]], [[TYPE5:![0-9]+]]}
21+
// CHECK: [[TYPE4]] = distinct !DICompositeType(tag: DW_TAG_class_type, name: "y", scope: [[SP]]
22+
// CHECK: [[TYPE5]] = !DICompositeType(tag: DW_TAG_enumeration_type, name: "z", scope: [[SP]]
23+
// CHECK: [[TYPE6:![0-9]+]] = !DIEnumerator(name: "Z"
2224

2325
// NODBG-NOT: !DI{{CompositeType|Enumerator|DerivedType}}
2426

clang/test/CodeGenCXX/aix-destructor-attribute.cpp

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@ struct test {
1717
~test();
1818
} t;
1919

20-
int bar() __attribute__((destructor(101)));
20+
int bar() __attribute__((destructor(100)));
2121
int bar2() __attribute__((destructor(65535)));
22+
int bar3(int) __attribute__((destructor(65535)));
2223

2324
int bar() {
2425
return 1;
@@ -28,13 +29,17 @@ int bar2() {
2829
return 2;
2930
}
3031

32+
int bar3(int a) {
33+
return a;
34+
}
35+
3136
// NO-REGISTER: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr @_GLOBAL__sub_I__, ptr null }]
32-
// NO-REGISTER: @llvm.global_dtors = appending global [3 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 101, ptr @_Z3barv, ptr null }, { i32, ptr, ptr } { i32 65535, ptr @_Z4bar2v, ptr null }, { i32, ptr, ptr } { i32 65535, ptr @_GLOBAL__D_a, ptr null }]
37+
// NO-REGISTER: @llvm.global_dtors = appending global [4 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 100, ptr @_Z3barv, ptr null }, { i32, ptr, ptr } { i32 65535, ptr @_Z4bar2v, ptr null }, { i32, ptr, ptr } { i32 65535, ptr @_Z4bar3i, ptr null }, { i32, ptr, ptr } { i32 65535, ptr @_GLOBAL__D_a, ptr null }]
3338

34-
// REGISTER: @llvm.global_ctors = appending global [3 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr @_GLOBAL__sub_I__, ptr null }, { i32, ptr, ptr } { i32 101, ptr @__GLOBAL_init_101, ptr null }, { i32, ptr, ptr } { i32 65535, ptr @__GLOBAL_init_65535, ptr null }]
35-
// REGISTER: @llvm.global_dtors = appending global [3 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr @_GLOBAL__D_a, ptr null }, { i32, ptr, ptr } { i32 101, ptr @__GLOBAL_cleanup_101, ptr null }, { i32, ptr, ptr } { i32 65535, ptr @__GLOBAL_cleanup_65535, ptr null }]
39+
// REGISTER: @llvm.global_ctors = appending global [3 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr @_GLOBAL__sub_I__, ptr null }, { i32, ptr, ptr } { i32 100, ptr @__GLOBAL_init_100, ptr null }, { i32, ptr, ptr } { i32 65535, ptr @__GLOBAL_init_65535, ptr null }]
40+
// REGISTER: @llvm.global_dtors = appending global [3 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr @_GLOBAL__D_a, ptr null }, { i32, ptr, ptr } { i32 100, ptr @__GLOBAL_cleanup_100, ptr null }, { i32, ptr, ptr } { i32 65535, ptr @__GLOBAL_cleanup_65535, ptr null }]
3641

37-
// REGISTER: define internal void @__GLOBAL_init_101() [[ATTR:#[0-9]+]] {
42+
// REGISTER: define internal void @__GLOBAL_init_100() [[ATTR:#[0-9]+]] {
3843
// REGISTER: entry:
3944
// REGISTER: %0 = call i32 @atexit(ptr @_Z3barv)
4045
// REGISTER: ret void
@@ -43,10 +48,11 @@ int bar2() {
4348
// REGISTER: define internal void @__GLOBAL_init_65535() [[ATTR:#[0-9]+]] {
4449
// REGISTER: entry:
4550
// REGISTER: %0 = call i32 @atexit(ptr @_Z4bar2v)
51+
// REGISTER: %1 = call i32 @atexit(ptr @_Z4bar3i)
4652
// REGISTER: ret void
4753
// REGISTER: }
4854

49-
// REGISTER: define internal void @__GLOBAL_cleanup_101() [[ATTR:#[0-9]+]] {
55+
// REGISTER: define internal void @__GLOBAL_cleanup_100() [[ATTR:#[0-9]+]] {
5056
// REGISTER: entry:
5157
// REGISTER: %0 = call i32 @unatexit(ptr @_Z3barv)
5258
// REGISTER: %needs_destruct = icmp eq i32 %0, 0
@@ -62,11 +68,20 @@ int bar2() {
6268

6369
// REGISTER: define internal void @__GLOBAL_cleanup_65535() [[ATTR:#[0-9]+]] {
6470
// REGISTER: entry:
65-
// REGISTER: %0 = call i32 @unatexit(ptr @_Z4bar2v)
71+
// REGISTER: %0 = call i32 @unatexit(ptr @_Z4bar3i)
6672
// REGISTER: %needs_destruct = icmp eq i32 %0, 0
67-
// REGISTER: br i1 %needs_destruct, label %destruct.call, label %destruct.end
73+
// REGISTER: br i1 %needs_destruct, label %destruct.call, label %unatexit.call
6874

6975
// REGISTER: destruct.call:
76+
// REGISTER: call void @_Z4bar3i()
77+
// REGISTER: br label %unatexit.call
78+
79+
// REGISTER: unatexit.call:
80+
// REGISTER: %1 = call i32 @unatexit(ptr @_Z4bar2v)
81+
// REGISTER: %needs_destruct1 = icmp eq i32 %1, 0
82+
// REGISTER: br i1 %needs_destruct1, label %destruct.call2, label %destruct.end
83+
84+
// REGISTER: destruct.call2:
7085
// REGISTER: call void @_Z4bar2v()
7186
// REGISTER: br label %destruct.end
7287

0 commit comments

Comments
 (0)