Skip to content

Commit a9845d6

Browse files
authored
[clang] Add some CodeGen tests for CWG 1xx issues (#80338)
Covers CWG issues [124](https://cplusplus.github.io/CWG/issues/124.html) [185](https://cplusplus.github.io/CWG/issues/185.html), [193](https://cplusplus.github.io/CWG/issues/193.html), [199](https://cplusplus.github.io/CWG/issues/199.html). I also looked at [190](https://cplusplus.github.io/CWG/issues/190.html), but concluded that we should try to test it via C++20 `std::is_layout_compatible` first. I tried to group tests under `dr1xx-codegen.cpp`, but found out that CodeGen can arbitrarily reorder function definitions in LLVM module. In particular, interleaving between regular function definitions and destructor definitions present in the source might not be preserved, which messes up FileCheck directives. `CHECK-DAG` can help with that, but its interaction with `CHECK-LABEL` (lack of thereof) would require me to relax tests too much.
1 parent b04dd5d commit a9845d6

File tree

6 files changed

+169
-8
lines changed

6 files changed

+169
-8
lines changed

clang/test/CXX/drs/dr124.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// RUN: %clang_cc1 -std=c++98 %s -triple x86_64-linux-gnu -emit-llvm -disable-llvm-passes -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK
2+
// RUN: %clang_cc1 -std=c++11 %s -triple x86_64-linux-gnu -emit-llvm -disable-llvm-passes -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK
3+
// RUN: %clang_cc1 -std=c++14 %s -triple x86_64-linux-gnu -emit-llvm -disable-llvm-passes -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK
4+
// RUN: %clang_cc1 -std=c++17 %s -triple x86_64-linux-gnu -emit-llvm -disable-llvm-passes -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK
5+
// RUN: %clang_cc1 -std=c++20 %s -triple x86_64-linux-gnu -emit-llvm -disable-llvm-passes -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK
6+
// RUN: %clang_cc1 -std=c++23 %s -triple x86_64-linux-gnu -emit-llvm -disable-llvm-passes -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK
7+
// RUN: %clang_cc1 -std=c++2c %s -triple x86_64-linux-gnu -emit-llvm -disable-llvm-passes -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK
8+
9+
#if __cplusplus == 199711L
10+
#define NOTHROW throw()
11+
#else
12+
#define NOTHROW noexcept(true)
13+
#endif
14+
15+
namespace dr124 { // dr124: 2.7
16+
17+
extern void full_expr_fence() NOTHROW;
18+
19+
struct A {
20+
A() NOTHROW {}
21+
~A() NOTHROW {}
22+
};
23+
24+
struct B {
25+
B(A = A()) NOTHROW {}
26+
~B() NOTHROW {}
27+
};
28+
29+
void f() {
30+
full_expr_fence();
31+
B b[2];
32+
full_expr_fence();
33+
}
34+
35+
// CHECK-LABEL: define {{.*}} void @dr124::f()()
36+
// CHECK: call void @dr124::full_expr_fence()
37+
// CHECK: br label %arrayctor.loop
38+
// CHECK-LABEL: arrayctor.loop:
39+
// CHECK: call void @dr124::A::A()
40+
// CHECK: call void @dr124::B::B(dr124::A)
41+
// CHECK: call void @dr124::A::~A()
42+
// CHECK: br {{.*}}, label %arrayctor.cont, label %arrayctor.loop
43+
// CHECK-LABEL: arrayctor.cont:
44+
// CHECK: call void @dr124::full_expr_fence()
45+
// CHECK: br label %arraydestroy.body
46+
// CHECK-LABEL: arraydestroy.body:
47+
// CHECK: call void @dr124::B::~B()
48+
// CHECK-LABEL: }
49+
50+
51+
} // namespace dr124

clang/test/CXX/drs/dr185.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// RUN: %clang_cc1 -std=c++98 %s -triple x86_64-linux-gnu -emit-llvm -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK
2+
// RUN: %clang_cc1 -std=c++11 %s -triple x86_64-linux-gnu -emit-llvm -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK
3+
// RUN: %clang_cc1 -std=c++14 %s -triple x86_64-linux-gnu -emit-llvm -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK
4+
// RUN: %clang_cc1 -std=c++17 %s -triple x86_64-linux-gnu -emit-llvm -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK
5+
// RUN: %clang_cc1 -std=c++20 %s -triple x86_64-linux-gnu -emit-llvm -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK
6+
// RUN: %clang_cc1 -std=c++23 %s -triple x86_64-linux-gnu -emit-llvm -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK
7+
// RUN: %clang_cc1 -std=c++2c %s -triple x86_64-linux-gnu -emit-llvm -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK
8+
9+
namespace dr185 { // dr185: 2.7
10+
struct A {
11+
mutable int value;
12+
explicit A(int i) : value(i) {}
13+
void mutate(int i) const { value = i; }
14+
};
15+
16+
int foo() {
17+
A const& t = A(1);
18+
A n(t);
19+
t.mutate(2);
20+
return n.value;
21+
}
22+
23+
// CHECK-LABEL: define {{.*}} i32 @dr185::foo()
24+
// CHECK: call void @dr185::A::A(int)(ptr {{[^,]*}} %ref.tmp, {{.*}})
25+
// CHECK: store ptr %ref.tmp, ptr %t
26+
// CHECK-NOT: %t =
27+
// CHECK: [[DR185_T:%.+]] = load ptr, ptr %t
28+
// CHECK: call void @llvm.memcpy.p0.p0.i64(ptr {{[^,]*}} %n, ptr {{[^,]*}} [[DR185_T]], {{.*}})
29+
// CHECK-LABEL: }
30+
} // namespace dr185

clang/test/CXX/drs/dr193.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// RUN: %clang_cc1 -std=c++98 %s -triple x86_64-linux-gnu -emit-llvm -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK
2+
// RUN: %clang_cc1 -std=c++11 %s -triple x86_64-linux-gnu -emit-llvm -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK
3+
// RUN: %clang_cc1 -std=c++14 %s -triple x86_64-linux-gnu -emit-llvm -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK
4+
// RUN: %clang_cc1 -std=c++17 %s -triple x86_64-linux-gnu -emit-llvm -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK
5+
// RUN: %clang_cc1 -std=c++20 %s -triple x86_64-linux-gnu -emit-llvm -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK
6+
// RUN: %clang_cc1 -std=c++23 %s -triple x86_64-linux-gnu -emit-llvm -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK
7+
// RUN: %clang_cc1 -std=c++2c %s -triple x86_64-linux-gnu -emit-llvm -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK
8+
9+
#if __cplusplus == 199711L
10+
#define NOTHROW throw()
11+
#else
12+
#define NOTHROW noexcept(true)
13+
#endif
14+
15+
namespace dr193 { // dr193: 2.7
16+
struct A {
17+
~A() NOTHROW {}
18+
};
19+
20+
struct B {
21+
~B() NOTHROW {}
22+
};
23+
24+
struct C {
25+
~C() NOTHROW {}
26+
};
27+
28+
struct D : A {
29+
B b;
30+
~D() NOTHROW { C c; }
31+
};
32+
33+
void foo() {
34+
D d;
35+
}
36+
37+
// skipping over D1 (complete object destructor)
38+
// CHECK-LABEL: define {{.*}} void @dr193::D::~D(){{.*}}
39+
// CHECK-LABEL: define {{.*}} void @dr193::D::~D(){{.*}}
40+
// CHECK-NOT: call void @dr193::A::~A()
41+
// CHECK-NOT: call void @dr193::B::~B()
42+
// CHECK: call void @dr193::C::~C()
43+
// CHECK: call void @dr193::B::~B()
44+
// CHECK: call void @dr193::A::~A()
45+
// CHECK-LABEL: }
46+
} // namespace dr193

clang/test/CXX/drs/dr199.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// RUN: %clang_cc1 -std=c++98 %s -triple x86_64-linux-gnu -emit-llvm -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK
2+
// RUN: %clang_cc1 -std=c++11 %s -triple x86_64-linux-gnu -emit-llvm -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK
3+
// RUN: %clang_cc1 -std=c++14 %s -triple x86_64-linux-gnu -emit-llvm -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK
4+
// RUN: %clang_cc1 -std=c++17 %s -triple x86_64-linux-gnu -emit-llvm -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK
5+
// RUN: %clang_cc1 -std=c++20 %s -triple x86_64-linux-gnu -emit-llvm -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK
6+
// RUN: %clang_cc1 -std=c++23 %s -triple x86_64-linux-gnu -emit-llvm -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK
7+
// RUN: %clang_cc1 -std=c++2c %s -triple x86_64-linux-gnu -emit-llvm -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK
8+
9+
#if __cplusplus == 199711L
10+
#define NOTHROW throw()
11+
#else
12+
#define NOTHROW noexcept(true)
13+
#endif
14+
15+
namespace dr199 { // dr199: 2.8
16+
struct A {
17+
~A() NOTHROW {}
18+
};
19+
20+
struct B {
21+
~B() NOTHROW {}
22+
};
23+
24+
void foo() {
25+
A(), B();
26+
}
27+
28+
// CHECK-LABEL: define {{.*}} void @dr199::foo()
29+
// CHECK-NOT: call void @dr199::A::~A()
30+
// CHECK: call void @dr199::B::~B()
31+
// CHECK: call void @dr199::A::~A()
32+
// CHECK-LABEL: }
33+
} // namespace dr199

clang/test/CXX/drs/dr1xx.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ namespace dr122 { // dr122: yes
306306
}
307307

308308
// dr123: na
309-
// dr124: dup 201
309+
// dr124 is in dr124.cpp
310310

311311
// dr125: yes
312312
struct dr125_A { struct dr125_B {}; }; // #dr125_B
@@ -1169,7 +1169,7 @@ namespace dr184 { // dr184: yes
11691169
void h() { A<B>().g(); }
11701170
}
11711171

1172-
// dr185 FIXME: add codegen test
1172+
// dr185 is in dr185.cpp
11731173

11741174
namespace dr187 { // dr187: sup 481
11751175
const int Z = 1;
@@ -1184,6 +1184,7 @@ namespace dr188 { // dr188: yes
11841184
}
11851185

11861186
// dr190 FIXME: add codegen test for tbaa
1187+
// or implement C++20 std::is_layout_compatible and test it this way
11871188

11881189
int dr191_j;
11891190
namespace dr191 { // dr191: yes
@@ -1215,7 +1216,7 @@ namespace dr191 { // dr191: yes
12151216
}
12161217
}
12171218

1218-
// dr193 FIXME: add codegen test
1219+
// dr193 is in dr193.cpp
12191220

12201221
namespace dr194 { // dr194: yes
12211222
struct A {
@@ -1290,4 +1291,4 @@ namespace dr198 { // dr198: yes
12901291
};
12911292
}
12921293

1293-
// dr199 FIXME: add codegen test
1294+
// dr199 is in dr199.cpp

clang/www/cxx_dr_status.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -782,7 +782,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
782782
<td><a href="https://cplusplus.github.io/CWG/issues/124.html">124</a></td>
783783
<td>CD1</td>
784784
<td>Lifetime of temporaries in default initialization of class arrays</td>
785-
<td class="unknown" align="center">Duplicate of <a href="#201">201</a></td>
785+
<td class="full" align="center">Clang 2.7</td>
786786
</tr>
787787
<tr id="125">
788788
<td><a href="https://cplusplus.github.io/CWG/issues/125.html">125</a></td>
@@ -1148,7 +1148,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
11481148
<td><a href="https://cplusplus.github.io/CWG/issues/185.html">185</a></td>
11491149
<td>TC1</td>
11501150
<td>"Named" temporaries and copy elision</td>
1151-
<td class="unknown" align="center">Unknown</td>
1151+
<td class="full" align="center">Clang 2.7</td>
11521152
</tr>
11531153
<tr class="open" id="186">
11541154
<td><a href="https://cplusplus.github.io/CWG/issues/186.html">186</a></td>
@@ -1196,7 +1196,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
11961196
<td><a href="https://cplusplus.github.io/CWG/issues/193.html">193</a></td>
11971197
<td>TC1</td>
11981198
<td>Order of destruction of local automatics of destructor</td>
1199-
<td class="unknown" align="center">Unknown</td>
1199+
<td class="full" align="center">Clang 2.7</td>
12001200
</tr>
12011201
<tr id="194">
12021202
<td><a href="https://cplusplus.github.io/CWG/issues/194.html">194</a></td>
@@ -1232,7 +1232,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
12321232
<td><a href="https://cplusplus.github.io/CWG/issues/199.html">199</a></td>
12331233
<td>CD1</td>
12341234
<td>Order of destruction of temporaries</td>
1235-
<td class="unknown" align="center">Unknown</td>
1235+
<td class="full" align="center">Clang 2.8</td>
12361236
</tr>
12371237
<tr id="200">
12381238
<td><a href="https://cplusplus.github.io/CWG/issues/200.html">200</a></td>

0 commit comments

Comments
 (0)