-
Notifications
You must be signed in to change notification settings - Fork 10.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[clang] Add some CodeGen tests for CWG 4xx issues #83715
Conversation
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.
@llvm/pr-subscribers-clang Author: Vlad Serebrennikov (Endilll) ChangesThis patch covers the following defect reports: CWG475 "When is Full diff: https://github.com/llvm/llvm-project/pull/83715.diff 7 Files Affected:
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@-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>
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
// CHECK-DAG: @dr441::dynamic_init = global %"struct.dr441::A" zeroinitializer | ||
// CHECK-DAG: @dr441::i = global i32 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Kind of like above, we're not able to test that the initialization occurs in the correct order without an end-to-end test, so this is about the best I think we can do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Late review but LGTM
This patch covers the following defect reports:
CWG438 "Possible flaw in wording for multiple accesses to object between sequence points",
CWG439 "Guarantees on casting pointer back to cv-qualified version of original type",
CWG441 "Ordering of static reference initialization",
CWG462 "Lifetime of temporaries bound to comma expressions",
CWG492 "
typeid
constness inconsistent with example".CWG475 "When is
std::uncaught_exception()
true? (take 2)" requires a libc++abi test.As for CWG454 "When is a definition of a static data member required?", I don't feel confident in my understanding of it, so skipping over it.