[clang] [clang] Add some CodeGen tests for CWG 4xx issues (PR #83715)
Vlad Serebrennikov via cfe-commits
cfe-commits at lists.llvm.org
Tue Mar 5 12:22:25 PST 2024
https://github.com/Endilll updated https://github.com/llvm/llvm-project/pull/83715
>From 59a558a653098c1b96b47cffc62b1f3bf1cb92d8 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sun, 3 Mar 2024 12:21:17 +0300
Subject: [PATCH 1/3] [clang] Add some CodeGen tests for CWG 4xx issues
This patch covers the following defect reports:
[CWG438](https://cplusplus.github.io/CWG/issues/438.html) "Possible flaw in wording for multiple accesses to object between sequence points",
[CWG439](https://cplusplus.github.io/CWG/issues/439.html) "Guarantees on casting pointer back to cv-qualified version of original type",
[CWG441](https://cplusplus.github.io/CWG/issues/441.html) "Ordering of static reference initialization",
[CWG462](https://cplusplus.github.io/CWG/issues/462.html) "Lifetime of temporaries bound to comma expressions",
[CWG492](https://cplusplus.github.io/CWG/issues/492.html) "`typeid` constness inconsistent with example".
[CWG475](https://cplusplus.github.io/CWG/issues/475.html) "When is `std::uncaught_exception()` true? (take 2)" requires a libc++abi test. As for [CWG454](https://cplusplus.github.io/CWG/issues/454.html) "When is a definition of a static data member required?", I don't feel confident in my understanding of it, so skipping over it.
---
clang/test/CXX/drs/dr438.cpp | 24 +++++++++++++++++++++++
clang/test/CXX/drs/dr439.cpp | 27 +++++++++++++++++++++++++
clang/test/CXX/drs/dr441.cpp | 38 ++++++++++++++++++++++++++++++++++++
clang/test/CXX/drs/dr462.cpp | 33 +++++++++++++++++++++++++++++++
clang/test/CXX/drs/dr492.cpp | 37 +++++++++++++++++++++++++++++++++++
clang/test/CXX/drs/dr4xx.cpp | 12 ++++++------
clang/www/cxx_dr_status.html | 10 +++++-----
7 files changed, 170 insertions(+), 11 deletions(-)
create mode 100644 clang/test/CXX/drs/dr438.cpp
create mode 100644 clang/test/CXX/drs/dr439.cpp
create mode 100644 clang/test/CXX/drs/dr441.cpp
create mode 100644 clang/test/CXX/drs/dr462.cpp
create mode 100644 clang/test/CXX/drs/dr492.cpp
diff --git a/clang/test/CXX/drs/dr438.cpp b/clang/test/CXX/drs/dr438.cpp
new file mode 100644
index 00000000000000..1213edf9911518
--- /dev/null
+++ b/clang/test/CXX/drs/dr438.cpp
@@ -0,0 +1,24 @@
+// 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
+// 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
+// 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
+// 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
+// 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
+// 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
+// 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
+
+namespace dr438 { // dr438: 2.7
+
+void f() {
+ long A[2];
+ A[0] = 0;
+ A[A[0]] = 1;
+}
+
+} // namespace dr438
+
+// CHECK-LABEL: define {{.*}} void @dr438::f()()
+// CHECK: [[A:%.+]] = alloca [2 x i64]
+// CHECK: [[ARRAYIDX1:%.+]] = getelementptr inbounds [2 x i64], ptr [[A]], i64 0, i64 0
+// CHECK: [[TEMPIDX:%.+]] = load i64, ptr [[ARRAYIDX1]]
+// CHECK: [[ARRAYIDX2:%.+]] = getelementptr inbounds [2 x i64], ptr [[A]], i64 0, i64 [[TEMPIDX]]
+// CHECK-LABEL: }
diff --git a/clang/test/CXX/drs/dr439.cpp b/clang/test/CXX/drs/dr439.cpp
new file mode 100644
index 00000000000000..874cd75cf2eb9f
--- /dev/null
+++ b/clang/test/CXX/drs/dr439.cpp
@@ -0,0 +1,27 @@
+// 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
+// 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
+// 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
+// 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
+// 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
+// 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
+// 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
+
+namespace dr439 { // dr439: 2.7
+
+void f() {
+ int* p1 = new int;
+ const int* p2 = static_cast<const int*>(static_cast<void *>(p1));
+ bool b = p1 == p2; // b will have the value true.
+}
+
+} // namespace dr439
+
+// CHECK-LABEL: define {{.*}} void @dr439::f()()
+// CHECK: [[P1:%.+]] = alloca ptr, align 8
+// CHECK-NEXT: [[P2:%.+]] = alloca ptr, align 8
+// CHECK: [[TEMP0:%.+]] = load ptr, ptr [[P1]]
+// CHECK-NEXT: store ptr [[TEMP0:%.+]], ptr [[P2]]
+// CHECK-NEXT: [[TEMP1:%.+]] = load ptr, ptr [[P1]]
+// CHECK-NEXT: [[TEMP2:%.+]] = load ptr, ptr [[P2]]
+// CHECK-NEXT: {{.*}} = icmp eq ptr [[TEMP1]], [[TEMP2]]
+// CHECK-LABEL: }
diff --git a/clang/test/CXX/drs/dr441.cpp b/clang/test/CXX/drs/dr441.cpp
new file mode 100644
index 00000000000000..6504bba689d225
--- /dev/null
+++ b/clang/test/CXX/drs/dr441.cpp
@@ -0,0 +1,38 @@
+// 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
+// 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
+// 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
+// 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
+// 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
+// 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
+// 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
+
+namespace dr441 { // dr441: 2.7
+
+struct A {
+ A() {}
+};
+
+A dynamic_init;
+int i;
+int& ir = i;
+int* ip = &i;
+
+} // namespace dr441
+
+// CHECK-DAG: @dr441::dynamic_init = global %"struct.dr441::A" zeroinitializer
+// CHECK-DAG: @dr441::i = global i32 0
+// CHECK-DAG: @dr441::ir = constant ptr @dr441::i
+// CHECK-DAG: @dr441::ip = global ptr @dr441::i
+// CHECK-DAG: @llvm.global_ctors = appending global [{{.+}}] [{ {{.+}} } { {{.+}}, ptr @_GLOBAL__sub_I_dr441.cpp, {{.+}} }]
+
+// CHECK-LABEL: define {{.*}} void @__cxx_global_var_init()
+// CHECK-NEXT: entry:
+// CHECK-NEXT: call void @dr441::A::A()({{.*}} @dr441::dynamic_init)
+// CHECK-NEXT: ret void
+// CHECK-NEXT: }
+
+// CHECK-LABEL: define {{.*}} void @_GLOBAL__sub_I_dr441.cpp()
+// CHECK-NEXT: entry:
+// CHECK-NEXT: call void @__cxx_global_var_init()
+// CHECK-NEXT: ret void
+// CHECK-NEXT: }
diff --git a/clang/test/CXX/drs/dr462.cpp b/clang/test/CXX/drs/dr462.cpp
new file mode 100644
index 00000000000000..2b268778ea10da
--- /dev/null
+++ b/clang/test/CXX/drs/dr462.cpp
@@ -0,0 +1,33 @@
+// 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
+// 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
+// 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
+// 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
+// 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
+// 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
+// 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
+
+#if __cplusplus == 199711L
+#define NOTHROW throw()
+#else
+#define NOTHROW noexcept(true)
+#endif
+
+namespace dr462 { // dr462: 2.7
+
+struct A {
+ ~A() NOTHROW {}
+};
+
+extern void full_expr_fence() NOTHROW;
+
+void f() {
+ const A& r = (3, A());
+ full_expr_fence();
+}
+
+} // namespace dr462
+
+// CHECK-LABEL: define {{.*}} void @dr462::f()()
+// CHECK: call void @dr462::full_expr_fence()()
+// CHECK: call void @dr462::A::~A()
+// CHECK-LABEL: }
diff --git a/clang/test/CXX/drs/dr492.cpp b/clang/test/CXX/drs/dr492.cpp
new file mode 100644
index 00000000000000..f53f1cb5412404
--- /dev/null
+++ b/clang/test/CXX/drs/dr492.cpp
@@ -0,0 +1,37 @@
+// 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
+// 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
+// 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
+// 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
+// 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
+// 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
+// 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
+
+#if __cplusplus == 199711L
+#define NOTHROW throw()
+#else
+#define NOTHROW noexcept(true)
+#endif
+
+namespace std {
+struct type_info {
+ const char* name() const NOTHROW;
+};
+}
+
+namespace dr492 { // dr492: 2.7
+
+void f() {
+ typeid(int).name();
+ typeid(const int).name();
+ typeid(volatile int).name();
+ typeid(const volatile int).name();
+}
+
+} // namespace dr492
+
+// CHECK-LABEL: define {{.*}} void @dr492::f()()
+// CHECK: {{.*}} = call {{.*}} @std::type_info::name() const({{.*}} @typeinfo for int)
+// CHECK-NEXT: {{.*}} = call {{.*}} @std::type_info::name() const({{.*}} @typeinfo for int)
+// CHECK-NEXT: {{.*}} = call {{.*}} @std::type_info::name() const({{.*}} @typeinfo for int)
+// CHECK-NEXT: {{.*}} = call {{.*}} @std::type_info::name() const({{.*}} @typeinfo for int)
+// CHECK-LABEL: }
diff --git a/clang/test/CXX/drs/dr4xx.cpp b/clang/test/CXX/drs/dr4xx.cpp
index 612a152aec4c4d..343c4ee6f3344e 100644
--- a/clang/test/CXX/drs/dr4xx.cpp
+++ b/clang/test/CXX/drs/dr4xx.cpp
@@ -698,9 +698,9 @@ namespace dr437 { // dr437: sup 1308
};
}
-// dr438 FIXME write a codegen test
-// dr439 FIXME write a codegen test
-// dr441 FIXME write a codegen test
+// dr438 is in dr438.cpp
+// dr439 is in dr439.cpp
+// dr441 is in dr441.cpp
// dr442: sup 348
// dr443: na
@@ -943,7 +943,7 @@ namespace dr460 { // dr460: yes
}
// dr461: na
-// dr462 FIXME write a codegen test
+// dr462 is in dr462.cpp
// dr463: na
// dr464: na
// dr465: na
@@ -1089,7 +1089,7 @@ namespace dr474 { // dr474: 3.4
}
}
-// dr475 FIXME write a codegen test
+// dr475 FIXME write a libc++abi test
namespace dr477 { // dr477: 3.5
struct A {
@@ -1437,7 +1437,7 @@ namespace dr491 { // dr491: dup 413
// expected-error at -1 {{excess elements in array initializer}}
}
-// dr492 FIXME write a codegen test
+// dr492 is in dr492.cpp
namespace dr493 { // dr493: dup 976
struct X {
diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html
index 8b638e06f4aab6..b13401625a6fb5 100755
--- a/clang/www/cxx_dr_status.html
+++ b/clang/www/cxx_dr_status.html
@@ -2668,13 +2668,13 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://cplusplus.github.io/CWG/issues/438.html">438</a></td>
<td>CD2</td>
<td>Possible flaw in wording for multiple accesses to object between sequence points</td>
- <td class="unknown" align="center">Unknown</td>
+ <td class="full" align="center">Clang 2.7</td>
</tr>
<tr id="439">
<td><a href="https://cplusplus.github.io/CWG/issues/439.html">439</a></td>
<td>CD1</td>
<td>Guarantees on casting pointer back to cv-qualified version of original type</td>
- <td class="unknown" align="center">Unknown</td>
+ <td class="full" align="center">Clang 2.7</td>
</tr>
<tr id="440">
<td><a href="https://cplusplus.github.io/CWG/issues/440.html">440</a></td>
@@ -2686,7 +2686,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://cplusplus.github.io/CWG/issues/441.html">441</a></td>
<td>CD1</td>
<td>Ordering of static reference initialization</td>
- <td class="unknown" align="center">Unknown</td>
+ <td class="full" align="center">Clang 2.7</td>
</tr>
<tr id="442">
<td><a href="https://cplusplus.github.io/CWG/issues/442.html">442</a></td>
@@ -2812,7 +2812,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://cplusplus.github.io/CWG/issues/462.html">462</a></td>
<td>CD3</td>
<td>Lifetime of temporaries bound to comma expressions</td>
- <td class="unknown" align="center">Unknown</td>
+ <td class="full" align="center">Clang 2.7</td>
</tr>
<tr id="463">
<td><a href="https://cplusplus.github.io/CWG/issues/463.html">463</a></td>
@@ -2992,7 +2992,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://cplusplus.github.io/CWG/issues/492.html">492</a></td>
<td>CD1</td>
<td><TT>typeid</TT> constness inconsistent with example</td>
- <td class="unknown" align="center">Unknown</td>
+ <td class="full" align="center">Clang 2.7</td>
</tr>
<tr id="493">
<td><a href="https://cplusplus.github.io/CWG/issues/493.html">493</a></td>
>From d395b9642e809c318880add6523c1b0c3b2b1b4e Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Tue, 5 Mar 2024 23:20:06 +0300
Subject: [PATCH 2/3] Make CWG438 test stricter
---
clang/test/CXX/drs/dr438.cpp | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/clang/test/CXX/drs/dr438.cpp b/clang/test/CXX/drs/dr438.cpp
index 1213edf9911518..a6ed39b88c2420 100644
--- a/clang/test/CXX/drs/dr438.cpp
+++ b/clang/test/CXX/drs/dr438.cpp
@@ -18,7 +18,8 @@ void f() {
// CHECK-LABEL: define {{.*}} void @dr438::f()()
// CHECK: [[A:%.+]] = alloca [2 x i64]
+// CHECK: {{.+}} = getelementptr inbounds [2 x i64], ptr [[A]], i64 0, i64 0
// CHECK: [[ARRAYIDX1:%.+]] = getelementptr inbounds [2 x i64], ptr [[A]], i64 0, i64 0
-// CHECK: [[TEMPIDX:%.+]] = load i64, ptr [[ARRAYIDX1]]
-// CHECK: [[ARRAYIDX2:%.+]] = getelementptr inbounds [2 x i64], ptr [[A]], i64 0, i64 [[TEMPIDX]]
+// CHECK-NEXT: [[TEMPIDX:%.+]] = load i64, ptr [[ARRAYIDX1]]
+// CHECK-NEXT: [[ARRAYIDX2:%.+]] = getelementptr inbounds [2 x i64], ptr [[A]], i64 0, i64 [[TEMPIDX]]
// CHECK-LABEL: }
>From de5eb9bfff859e257bc15dbce39363be8cb8d606 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Tue, 5 Mar 2024 23:22:04 +0300
Subject: [PATCH 3/3] Add a comment to CWG439 test
---
clang/test/CXX/drs/dr439.cpp | 3 +++
1 file changed, 3 insertions(+)
diff --git a/clang/test/CXX/drs/dr439.cpp b/clang/test/CXX/drs/dr439.cpp
index 874cd75cf2eb9f..46960af93bb9aa 100644
--- a/clang/test/CXX/drs/dr439.cpp
+++ b/clang/test/CXX/drs/dr439.cpp
@@ -16,6 +16,9 @@ void f() {
} // namespace dr439
+// We're checking that p2 was copied from p1, and then was carried over
+// to the comparison without change.
+
// CHECK-LABEL: define {{.*}} void @dr439::f()()
// CHECK: [[P1:%.+]] = alloca ptr, align 8
// CHECK-NEXT: [[P2:%.+]] = alloca ptr, align 8
More information about the cfe-commits
mailing list