Skip to content

[clang] Add some CodeGen tests for CWG 2xx issues #80823

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

Merged
merged 7 commits into from
Feb 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions clang/test/CXX/drs/dr201.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// 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
// 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
// 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
// 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
// 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
// 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
// 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

#if __cplusplus == 199711L
#define NOTHROW throw()
#else
#define NOTHROW noexcept(true)
#endif

namespace dr201 { // dr201: 2.8
Copy link
Contributor

Choose a reason for hiding this comment

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

What is tested here?
My understanding is that this issue deal with the sequence of destructions in

auto foo[2] = {A(temp()), B(temp())};

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll update the test to make it more clear, but I test whether a temporary is destroyed at the end of full expression. Which I believe is what 201 is about, contrary to its title.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I'll update the test to make it more clear, but I test whether a temporary is destroyed at the end of full expression. Which I believe is what 201 is about, contrary to its title.

TBH, I think this is one of those "textual pendentry" type DRs where two sentences were inconsistent. It is complaining that in the expression: B b = A(); whether the call to B::B is 'part' of the full expression (so the deletion of the temporary isn't really meaningful).

It was never contentous based on my reading whether the temporary was deleted 'end of statement' (in fact, it was, in 1 sentence deleted AFTER init, which was AFTER end of statement, but that wasn't the case in the other sentence).

Because of this, I think your test is reasonably fine, except I'd add a check for the call to B::B before A::~A.

Also, it might be valuable to get the 'default argument to a default constructor called in array' is deleted BEFORE the initialization of the array.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added check for B::B().
I also added a test for related CWG124 to #80338


extern void full_expr_fence() NOTHROW;

struct A {
~A() NOTHROW {}
};

struct B {
B(A) NOTHROW {}
~B() NOTHROW {}
};

void foo() {
full_expr_fence();
B b = A();
full_expr_fence();
}

// CHECK-LABEL: define {{.*}} void @dr201::foo()
// CHECK: call void @dr201::full_expr_fence()
// CHECK: call void @dr201::B::B(dr201::A)
// CHECK: call void @dr201::A::~A()
// CHECK: call void @dr201::full_expr_fence()
// CHECK: call void @dr201::B::~B()
// CHECK-LABEL: }

} // namespace dr201
41 changes: 41 additions & 0 deletions clang/test/CXX/drs/dr210.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// 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
// 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
// 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
// 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
// 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
// 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
// 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

#if __cplusplus == 199711L
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wvariadic-macros"
#define static_assert(...) __extension__ _Static_assert(__VA_ARGS__)
#pragma clang diagnostic pop
#endif
Copy link
Collaborator

Choose a reason for hiding this comment

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

Wowzers, lot of work to make this happen, but thank you for doing it!


namespace dr210 { // dr210: 2.7
struct B {
long i;
B();
virtual ~B();
};

static_assert(sizeof(B) == 16, "");

struct D : B {
long j;
D();
};

static_assert(sizeof(D) == 24, "");

void toss(const B* b) {
throw *b;
}

// CHECK-LABEL: define {{.*}} void @dr210::toss(dr210::B const*)
// CHECK: %[[EXCEPTION:.*]] = call ptr @__cxa_allocate_exception(i64 16)
// CHECK: call void @__cxa_throw(ptr %[[EXCEPTION]], ptr @typeinfo for dr210::B, ptr @dr210::B::~B())
// CHECK-LABEL: }

} // namespace dr210
30 changes: 30 additions & 0 deletions clang/test/CXX/drs/dr292.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// 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
// 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
// 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
// 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
// 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
// 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
// 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

namespace dr292 { // dr292: 2.9
Copy link
Contributor

Choose a reason for hiding this comment

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

I think an additional test
new A(no_except()) checking the absence of delete might also be good

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I updated PR description to mention that resolution to 292 has been superseded by P0145R3. The latter is the wording I'm testing: we're making sure that we pass to deallocation function what was returned by allocation function, and making sure that potentially-throwing expression is evaluated in-between.

In new A(no_except()) initializer can't throw, and there's no need figure out what to pass to deallocation function, so I consider it out of scope of the CWG issue.


extern int g();

struct A {
A(int) throw() {}
};

void f() {
new A(g());
}

// CHECK-LABEL: define {{.*}} void @dr292::f()()
// CHECK: %[[CALL:.+]] = call {{.*}} @operator new(unsigned long)({{.*}})
// CHECK: invoke {{.*}} i32 @dr292::g()()
// CHECK-NEXT: to {{.*}} unwind label %lpad
// CHECK-LABEL: lpad:
// CHECK: call void @operator delete(void*)(ptr {{.*}} %[[CALL]])
// CHECK-LABEL: eh.resume:
// CHECK-LABEL: }

} // namespace dr292
6 changes: 3 additions & 3 deletions clang/test/CXX/drs/dr2xx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ namespace dr200 { // dr200: dup 214
}
}

// dr201 FIXME: write codegen test
// dr201 is in dr201.cpp

namespace dr202 { // dr202: 3.1
template<typename T> T f();
Expand Down Expand Up @@ -76,7 +76,7 @@ namespace dr209 { // dr209: 3.2
};
}

// dr210 FIXME: write codegen test
// dr210 is in dr210.cpp

namespace dr211 { // dr211: yes
struct A {
Expand Down Expand Up @@ -1188,7 +1188,7 @@ namespace dr289 { // dr289: yes

// dr290: na
// dr291: dup 391
// dr292 FIXME: write a codegen test
// dr292 is in dr292.cpp

namespace dr294 { // dr294: no
void f() throw(int);
Expand Down
6 changes: 3 additions & 3 deletions clang/www/cxx_dr_status.html
Original file line number Diff line number Diff line change
Expand Up @@ -1244,7 +1244,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://cplusplus.github.io/CWG/issues/201.html">201</a></td>
<td>CD1</td>
<td>Order of destruction of temporaries in initializers</td>
<td class="unknown" align="center">Unknown</td>
<td class="full" align="center">Clang 2.8</td>
</tr>
<tr id="202">
<td><a href="https://cplusplus.github.io/CWG/issues/202.html">202</a></td>
Expand Down Expand Up @@ -1299,7 +1299,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://cplusplus.github.io/CWG/issues/210.html">210</a></td>
<td>TC1</td>
<td>What is the type matched by an exception handler?</td>
<td class="unknown" align="center">Unknown</td>
<td class="full" align="center">Clang 2.7</td>
</tr>
<tr id="211">
<td><a href="https://cplusplus.github.io/CWG/issues/211.html">211</a></td>
Expand Down Expand Up @@ -1792,7 +1792,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://cplusplus.github.io/CWG/issues/292.html">292</a></td>
<td>CD3</td>
<td>Deallocation on exception in <TT>new</TT> before arguments evaluated</td>
<td class="unknown" align="center">Unknown</td>
<td class="full" align="center">Clang 2.9</td>
</tr>
<tr class="open" id="293">
<td><a href="https://cplusplus.github.io/CWG/issues/293.html">293</a></td>
Expand Down