From: Mike Stump Date: Mon, 16 Nov 2009 23:36:30 +0000 (+0000) Subject: Testcase for dynamic_cast. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=39f36e37f53bfec22a4bc2a594f2dd314395c86c;p=clang Testcase for dynamic_cast. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@88996 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/test/CodeGenCXX/dyncast.cpp b/test/CodeGenCXX/dyncast.cpp new file mode 100644 index 0000000000..0c46d0e61f --- /dev/null +++ b/test/CodeGenCXX/dyncast.cpp @@ -0,0 +1,413 @@ +// RUN: clang-cc -I%S -triple x86_64-apple-darwin -std=c++0x -emit-llvm %s -o %t.ll +// RUN: FileCheck -check-prefix LL --input-file=%t.ll %s + +#include + +class test1_A { virtual void f() { } }; +class test1_B { virtual void g() { } }; +class test1_D : public virtual test1_A, private test1_B {}; +class test1_E : public test1_D, public test1_B {}; +class test1_F : public test1_E, public test1_D {}; + +extern test1_D test1_d; +extern test1_F test1_f; + +extern "C" int printf(const char *str...); + +#define S(V, N) if (V) printf("PASS: %d\n", N); else printf("FAIL: %d\n", N) + +void test1() { + test1_B* bp = (test1_B*)&test1_d; + test1_A* ap = &test1_d; + // This throws + // test1_D& dr = dynamic_cast(*bp); + test1_D* dp = dynamic_cast(bp); + S(dp == 0, 1); + ap = dynamic_cast(bp); + S(ap == 0, 2); + bp = dynamic_cast(ap); + S(bp == 0, 3); + ap = dynamic_cast(&test1_d); + S(ap != 0, 4); + // FIXME: Doesn't work yet, gcc fails this at comepile time + // bp = dynamic_cast(&test1_d); + // S(bp == 0, 5); + { + test1_A* ap = &test1_f; + S(ap != 0, 6); + test1_D* dp = dynamic_cast(ap); + S(dp == 0, 7); + // cast from virtual base + test1_E* ep1 = dynamic_cast(ap); + S(ep1 != 0, 8); + } + dp = dynamic_cast(&test1_d); + S(dp == &test1_d, 9); + const test1_D *cdp = dynamic_cast(&test1_d); + S(cdp == &test1_d, 10); + dp = dynamic_cast((test1_A*)0); + S(dp == 0, 11); + ap = dynamic_cast(&test1_d); + S(ap == (test1_A*)&test1_d, 12); + test1_E* ep = dynamic_cast(&test1_f); + S(ep == (test1_E*)&test1_f, 13); + void *vp = dynamic_cast(ap); + S(vp == &test1_d, 14); + const void *cvp = dynamic_cast(ap); + S(cvp == &test1_d, 15); +} + +// CHECK-LL: define void @_Z5test1v() nounwind { +// CHECK-LL-NEXT:entry: +// CHECK-LL-NEXT: %bp = alloca %class.test1_A*, align 8 +// CHECK-LL-NEXT: %ap = alloca %class.test1_A*, align 8 +// CHECK-LL-NEXT: %dp = alloca %class.test1_D*, align 8 +// CHECK-LL-NEXT: %ap37 = alloca %class.test1_A*, align 8 +// CHECK-LL-NEXT: %dp53 = alloca %class.test1_D*, align 8 +// CHECK-LL-NEXT: %ep1 = alloca %class.test1_E*, align 8 +// CHECK-LL-NEXT: %cdp = alloca %class.test1_D*, align 8 +// CHECK-LL-NEXT: %ep = alloca %class.test1_E*, align 8 +// CHECK-LL-NEXT: %vp = alloca i8*, align 8 +// CHECK-LL-NEXT: %cvp = alloca i8*, align 8 +// CHECK-LL-NEXT: br i1 false, label %cast.null, label %cast.notnull +// CHECK-LL: cast.notnull: +// CHECK-LL-NEXT: br label %cast.end +// CHECK-LL: cast.null: +// CHECK-LL-NEXT: br label %cast.end +// CHECK-LL: cast.end: +// CHECK-LL-NEXT: %0 = phi %class.test1_A* [ bitcast (%class.test1_D* @test1_d to %class.test1_A*), %cast.notnull ], [ null, %cast.null ] +// CHECK-LL-NEXT: store %class.test1_A* %0, %class.test1_A** %bp +// CHECK-LL-NEXT: br i1 false, label %cast.null2, label %cast.notnull1 +// CHECK-LL: cast.notnull1: +// CHECK-LL-NEXT: %vtable = load i8** bitcast (%class.test1_D* @test1_d to i8**) +// CHECK-LL-NEXT: %vbase.offset.ptr = getelementptr i8* %vtable, i64 -24 +// CHECK-LL-NEXT: %1 = bitcast i8* %vbase.offset.ptr to i64* +// CHECK-LL-NEXT: %vbase.offset = load i64* %1 +// CHECK-LL-NEXT: %add.ptr = getelementptr i8* getelementptr inbounds (%class.test1_D* @test1_d, i32 0, i32 0, i32 0), i64 %vbase.offset +// CHECK-LL-NEXT: %2 = bitcast i8* %add.ptr to %class.test1_A* +// CHECK-LL-NEXT: br label %cast.end3 +// CHECK-LL: cast.null2: +// CHECK-LL-NEXT: br label %cast.end3 +// CHECK-LL: cast.end3: +// CHECK-LL-NEXT: %3 = phi %class.test1_A* [ %2, %cast.notnull1 ], [ null, %cast.null2 ] +// CHECK-LL-NEXT: store %class.test1_A* %3, %class.test1_A** %ap +// CHECK-LL-NEXT: %tmp = load %class.test1_A** %bp +// CHECK-LL-NEXT: %4 = icmp ne %class.test1_A* %tmp, null +// CHECK-LL-NEXT: br i1 %4, label %5, label %9 +// CHECK-LL: ;