diff options
author | David Majnemer <david.majnemer@gmail.com> | 2014-07-19 00:17:06 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2014-07-19 00:17:06 +0000 |
commit | efe057553273ac61818513c03ee45bf1a7573e67 (patch) | |
tree | 38ee9579942f82eef21dea144fed08f3e26c35b4 /test/CodeGenCXX/typeid-should-throw.cpp | |
parent | 41b1c7360d86805e720ece80593c455465e3afae (diff) |
CodeGen: Properly null-check typeid expressions
Thoroughly check for a pointer dereference which yields a glvalue. Look
through casts, comma operators, conditional operators, paren
expressions, etc.
This was originally D4416.
Differential Revision: http://reviews.llvm.org/D4592
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@213434 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGenCXX/typeid-should-throw.cpp')
-rw-r--r-- | test/CodeGenCXX/typeid-should-throw.cpp | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/test/CodeGenCXX/typeid-should-throw.cpp b/test/CodeGenCXX/typeid-should-throw.cpp new file mode 100644 index 0000000000..1d8fc85896 --- /dev/null +++ b/test/CodeGenCXX/typeid-should-throw.cpp @@ -0,0 +1,82 @@ +// RUN: %clang_cc1 %s -triple %itanium_abi_triple -Wno-unused-value -emit-llvm -o - -std=c++11 | FileCheck %s +namespace std { +struct type_info; +} + +struct A { + virtual ~A(); + operator bool(); +}; +struct B : A {}; + +void f1(A *x) { typeid(false, *x); } +// CHECK-LABEL: define void @_Z2f1P1A +// CHECK: icmp eq {{.*}}, null +// CHECK-NEXT: br i1 + +void f2(bool b, A *x, A *y) { typeid(b ? *x : *y); } +// CHECK-LABEL: define void @_Z2f2bP1AS0_ +// CHECK: icmp eq {{.*}}, null +// CHECK-NEXT: br i1 + +void f3(bool b, A *x, A &y) { typeid(b ? *x : y); } +// CHECK-LABEL: define void @_Z2f3bP1ARS_ +// CHECK: icmp eq {{.*}}, null +// CHECK-NEXT: br i1 + +void f4(bool b, A &x, A *y) { typeid(b ? x : *y); } +// CHECK-LABEL: define void @_Z2f4bR1APS_ +// CHECK: icmp eq {{.*}}, null +// CHECK-NEXT: br i1 + +void f5(volatile A *x) { typeid(*x); } +// CHECK-LABEL: define void @_Z2f5PV1A +// CHECK: icmp eq {{.*}}, null +// CHECK-NEXT: br i1 + +void f6(A *x) { typeid((B &)*(B *)x); } +// CHECK-LABEL: define void @_Z2f6P1A +// CHECK: icmp eq {{.*}}, null +// CHECK-NEXT: br i1 + +void f7(A *x) { typeid((*x)); } +// CHECK-LABEL: define void @_Z2f7P1A +// CHECK: icmp eq {{.*}}, null +// CHECK-NEXT: br i1 + +void f8(A *x) { typeid(x[0]); } +// CHECK-LABEL: define void @_Z2f8P1A +// CHECK: icmp eq {{.*}}, null +// CHECK-NEXT: br i1 + +void f9(A *x) { typeid(0[x]); } +// CHECK-LABEL: define void @_Z2f9P1A +// CHECK: icmp eq {{.*}}, null +// CHECK-NEXT: br i1 + +void f10(A *x, A *y) { typeid(*y ?: *x); } +// CHECK-LABEL: define void @_Z3f10P1AS0_ +// CHECK: icmp eq {{.*}}, null +// CHECK-NEXT: br i1 + +void f11(A *x, A &y) { typeid(*x ?: y); } +// CHECK-LABEL: define void @_Z3f11P1ARS_ +// CHECK: icmp eq {{.*}}, null +// CHECK-NEXT: br i1 + +void f12(A &x, A *y) { typeid(x ?: *y); } +// CHECK-LABEL: define void @_Z3f12R1APS_ +// CHECK: icmp eq {{.*}}, null +// CHECK-NEXT: br i1 + +void f13(A &x, A &y) { typeid(x ?: y); } +// CHECK-LABEL: define void @_Z3f13R1AS0_ +// CHECK-NOT: icmp eq {{.*}}, null + +void f14(A *x) { typeid((const A &)(A)*x); } +// CHECK-LABEL: define void @_Z3f14P1A +// CHECK-NOT: icmp eq {{.*}}, null + +void f15(A *x) { typeid((A &&)*(A *)nullptr); } +// CHECK-LABEL: define void @_Z3f15P1A +// CHECK-NOT: icmp eq {{.*}}, null |