aboutsummaryrefslogtreecommitdiff
path: root/clang/test/CodeGenCXX/dynamic-cast-exact.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test/CodeGenCXX/dynamic-cast-exact.cpp')
-rw-r--r--clang/test/CodeGenCXX/dynamic-cast-exact.cpp42
1 files changed, 41 insertions, 1 deletions
diff --git a/clang/test/CodeGenCXX/dynamic-cast-exact.cpp b/clang/test/CodeGenCXX/dynamic-cast-exact.cpp
index 86e1965..588d808 100644
--- a/clang/test/CodeGenCXX/dynamic-cast-exact.cpp
+++ b/clang/test/CodeGenCXX/dynamic-cast-exact.cpp
@@ -9,6 +9,7 @@ struct E : A { int e; };
struct F : virtual A { int f; };
struct G : virtual A { int g; };
struct H final : C, D, E, F, G { int h; };
+struct H1 final: C, private D { int h1; };
// CHECK-LABEL: @_Z7inexactP1A
C *inexact(A *a) {
@@ -77,10 +78,49 @@ H *exact_multi(A *a) {
return dynamic_cast<H*>(a);
}
+// CHECK-LABEL: @_Z19exact_invalid_multiP1D
+H1 *exact_invalid_multi(D* d) {
+ // CHECK: entry:
+ // CHECK-NEXT: %d.addr = alloca ptr
+ // CHECK-NEXT: store ptr %d, ptr %d.addr
+ // CHECK-NEXT: load ptr, ptr %d.addr
+ // CHECK-NEXT: ret ptr null
+ return dynamic_cast<H1*>(d);
+}
+
+// CHECK-LABEL: @_Z19exact_invalid_multiR1D
+H1 &exact_invalid_multi(D& d) {
+ // CHECK: entry:
+ // CHECK-NEXT: %d.addr = alloca ptr
+ // CHECK-NEXT: store ptr %d, ptr %d.addr
+ // CHECK-NEXT: load ptr, ptr %d.addr
+ // CHECK-NEXT: call void @__cxa_bad_cast()
+ // CHECK-NEXT: unreachable
+ // CHECK: dynamic_cast.unreachable:
+ // CHECK-NEXT: ret ptr poison
+ return dynamic_cast<H1&>(d);
+}
+
+namespace GH137518 {
+ class base { virtual void fn() = 0; };
+ class test final : base { virtual void fn() { } };
+ test* new_test() { return new test(); }
+
+ // CHECK-LABEL: @_ZN8GH1375184castEPNS_4baseE(
+ test* cast(base* b) {
+ // CHECK: entry:
+ // CHECK-NEXT: %b.addr = alloca ptr
+ // CHECK-NEXT: store ptr %b, ptr %b.addr
+ // CHECK-NEXT: load ptr, ptr %b.addr
+ // CHECK-NEXT: ret ptr null
+ return dynamic_cast<test*>(b);
+ }
+}
+
namespace GH64088 {
// Ensure we mark the B vtable as used here, because we're going to emit a
// reference to it.
- // CHECK: define {{.*}} @_ZN7GH640881BD0
+ // CHECK: define {{.*}} void @_ZN7GH640881BD0Ev(
struct A { virtual ~A(); };
struct B final : A { virtual ~B() = default; };
B *cast(A *p) { return dynamic_cast<B*>(p); }