Skip to content
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

Merged
merged 3 commits into from
Mar 6, 2024

Conversation

Endilll
Copy link
Contributor

@Endilll Endilll commented Mar 3, 2024

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.

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.
@llvmbot llvmbot added the clang Clang issues not falling into any other category label Mar 3, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented Mar 3, 2024

@llvm/pr-subscribers-clang

Author: Vlad Serebrennikov (Endilll)

Changes

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.


Full diff: https://github.com/llvm/llvm-project/pull/83715.diff

7 Files Affected:

  • (added) clang/test/CXX/drs/dr438.cpp (+24)
  • (added) clang/test/CXX/drs/dr439.cpp (+27)
  • (added) clang/test/CXX/drs/dr441.cpp (+38)
  • (added) clang/test/CXX/drs/dr462.cpp (+33)
  • (added) clang/test/CXX/drs/dr492.cpp (+37)
  • (modified) clang/test/CXX/drs/dr4xx.cpp (+6-6)
  • (modified) clang/www/cxx_dr_status.html (+5-5)
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>

Copy link
Collaborator

@AaronBallman AaronBallman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

clang/test/CXX/drs/dr439.cpp Show resolved Hide resolved
Comment on lines +22 to +23
// CHECK-DAG: @dr441::dynamic_init = global %"struct.dr441::A" zeroinitializer
// CHECK-DAG: @dr441::i = global i32 0
Copy link
Collaborator

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.

@Endilll Endilll merged commit 7a0accc into llvm:main Mar 6, 2024
4 checks passed
@Endilll Endilll deleted the dr4xx-codegen branch March 6, 2024 08:21
Copy link
Collaborator

@shafik shafik left a 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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++ clang Clang issues not falling into any other category test-suite
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants