aboutsummaryrefslogtreecommitdiff
path: root/test/CodeGenCXX/catch-undef-behavior.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2013-12-22 00:07:40 +0000
committerDimitry Andric <dim@FreeBSD.org>2013-12-22 00:07:40 +0000
commitbfef399519ca9b8a4b4c6b563253bad7e0eeffe0 (patch)
treedf8df0b0067b381eab470a3b8f28d14a552a6340 /test/CodeGenCXX/catch-undef-behavior.cpp
parent6a0372513edbc473b538d2f724efac50405d6fef (diff)
downloadsrc-bfef399519ca9b8a4b4c6b563253bad7e0eeffe0.tar.gz
src-bfef399519ca9b8a4b4c6b563253bad7e0eeffe0.zip
Vendor import of clang release_34 branch r197841 (effectively, 3.4 RC3):vendor/clang/clang-release_34-r197841
Notes
Notes: svn path=/vendor/clang/dist/; revision=259701 svn path=/vendor/clang/clang-release_34-r197841/; revision=259703; tag=vendor/clang/clang-release_34-r197841
Diffstat (limited to 'test/CodeGenCXX/catch-undef-behavior.cpp')
-rw-r--r--test/CodeGenCXX/catch-undef-behavior.cpp158
1 files changed, 155 insertions, 3 deletions
diff --git a/test/CodeGenCXX/catch-undef-behavior.cpp b/test/CodeGenCXX/catch-undef-behavior.cpp
index d6d0edfa1edb..338da57f0c7b 100644
--- a/test/CodeGenCXX/catch-undef-behavior.cpp
+++ b/test/CodeGenCXX/catch-undef-behavior.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsanitize=signed-integer-overflow,integer-divide-by-zero,float-divide-by-zero,shift,unreachable,return,vla-bound,alignment,null,vptr,object-size,float-cast-overflow,bool,enum,bounds -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -fsanitize=signed-integer-overflow,integer-divide-by-zero,float-divide-by-zero,shift,unreachable,return,vla-bound,alignment,null,vptr,object-size,float-cast-overflow,bool,enum,array-bounds,function -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s
struct S {
double d;
@@ -186,7 +186,7 @@ void bad_downcast_pointer(S *p) {
// CHECK: %[[NONNULL:.*]] = icmp ne {{.*}}, null
// CHECK: br i1 %[[NONNULL]],
- // CHECK: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64(
+ // CHECK: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64.p0i8(
// CHECK: %[[E1:.*]] = icmp uge i64 %[[SIZE]], 24
// CHECK: %[[MISALIGN:.*]] = and i64 %{{.*}}, 7
// CHECK: %[[E2:.*]] = icmp eq i64 %[[MISALIGN]], 0
@@ -207,7 +207,7 @@ void bad_downcast_pointer(S *p) {
void bad_downcast_reference(S &p) {
// CHECK: %[[E1:.*]] = icmp ne {{.*}}, null
// CHECK-NOT: br i1
- // CHECK: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64(
+ // CHECK: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64.p0i8(
// CHECK: %[[E2:.*]] = icmp uge i64 %[[SIZE]], 24
// CHECK: %[[E12:.*]] = and i1 %[[E1]], %[[E2]]
// CHECK: %[[MISALIGN:.*]] = and i64 %{{.*}}, 7
@@ -321,4 +321,156 @@ char string_index(int n) {
return "Hello"[n];
}
+class A // align=4
+{
+ int a1, a2, a3;
+};
+
+class B // align=8
+{
+ long b1, b2;
+};
+
+class C : public A, public B // align=16
+{
+ alignas(16) int c1;
+};
+
+// Make sure we check the alignment of the pointer after subtracting any
+// offset. The pointer before subtraction doesn't need to be aligned for
+// the destination type.
+
+// CHECK-LABEL: define void @_Z16downcast_pointerP1B(%class.B* %b)
+void downcast_pointer(B *b) {
+ (void) static_cast<C*>(b);
+ // Alignment check from EmitTypeCheck(TCK_DowncastPointer, ...)
+ // CHECK: [[SUB:%[.a-z0-9]*]] = getelementptr i8* {{.*}}, i64 -16
+ // CHECK-NEXT: [[C:%[0-9]*]] = bitcast i8* [[SUB]] to %class.C*
+ // null check goes here
+ // CHECK: [[FROM_PHI:%[0-9]*]] = phi %class.C* [ [[C]], {{.*}} ], {{.*}}
+ // Objectsize check goes here
+ // CHECK: [[C_INT:%[0-9]*]] = ptrtoint %class.C* [[FROM_PHI]] to i64
+ // CHECK-NEXT: [[MASKED:%[0-9]*]] = and i64 [[C_INT]], 15
+ // CHECK-NEXT: [[TEST:%[0-9]*]] = icmp eq i64 [[MASKED]], 0
+ // AND the alignment test with the objectsize test.
+ // CHECK-NEXT: [[AND:%[0-9]*]] = and i1 {{.*}}, [[TEST]]
+ // CHECK-NEXT: br i1 [[AND]]
+}
+
+// CHECK-LABEL: define void @_Z18downcast_referenceR1B(%class.B* %b)
+void downcast_reference(B &b) {
+ (void) static_cast<C&>(b);
+ // Alignment check from EmitTypeCheck(TCK_DowncastReference, ...)
+ // CHECK: [[SUB:%[.a-z0-9]*]] = getelementptr i8* {{.*}}, i64 -16
+ // CHECK-NEXT: [[C:%[0-9]*]] = bitcast i8* [[SUB]] to %class.C*
+ // Objectsize check goes here
+ // CHECK: [[C_INT:%[0-9]*]] = ptrtoint %class.C* [[C]] to i64
+ // CHECK-NEXT: [[MASKED:%[0-9]*]] = and i64 [[C_INT]], 15
+ // CHECK-NEXT: [[TEST:%[0-9]*]] = icmp eq i64 [[MASKED]], 0
+ // AND the alignment test with the objectsize test.
+ // CHECK-NEXT: [[AND:%[0-9]*]] = and i1 {{.*}}, [[TEST]]
+ // CHECK-NEXT: br i1 [[AND]]
+}
+
+// CHECK-LABEL: @_Z22indirect_function_callPFviE({{.*}} prefix <{ i32, i8* }> <{ i32 1413876459, i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*) }>
+void indirect_function_call(void (*p)(int)) {
+ // CHECK: [[PTR:%[0-9]*]] = bitcast void (i32)* {{.*}} to <{ i32, i8* }>*
+
+ // Signature check
+ // CHECK-NEXT: [[SIGPTR:%[0-9]*]] = getelementptr <{ i32, i8* }>* [[PTR]], i32 0, i32 0
+ // CHECK-NEXT: [[SIG:%[0-9]*]] = load i32* [[SIGPTR]]
+ // CHECK-NEXT: [[SIGCMP:%[0-9]*]] = icmp eq i32 [[SIG]], 1413876459
+ // CHECK-NEXT: br i1 [[SIGCMP]]
+
+ // RTTI pointer check
+ // CHECK: [[RTTIPTR:%[0-9]*]] = getelementptr <{ i32, i8* }>* [[PTR]], i32 0, i32 1
+ // CHECK-NEXT: [[RTTI:%[0-9]*]] = load i8** [[RTTIPTR]]
+ // CHECK-NEXT: [[RTTICMP:%[0-9]*]] = icmp eq i8* [[RTTI]], bitcast ({ i8*, i8* }* @_ZTIFviE to i8*)
+ // CHECK-NEXT: br i1 [[RTTICMP]]
+ p(42);
+}
+
+namespace CopyValueRepresentation {
+ // CHECK-LABEL: define {{.*}} @_ZN23CopyValueRepresentation2S3aSERKS0_
+ // CHECK-NOT: call {{.*}} @__ubsan_handle_load_invalid_value
+ // CHECK-LABEL: define {{.*}} @_ZN23CopyValueRepresentation2S4aSEOS0_
+ // CHECK-NOT: call {{.*}} @__ubsan_handle_load_invalid_value
+ // CHECK-LABEL: define {{.*}} @_ZN23CopyValueRepresentation2S5C2ERKS0_
+ // CHECK-NOT: call {{.*}} __ubsan_handle_load_invalid_value
+ // CHECK-LABEL: define {{.*}} @_ZN23CopyValueRepresentation2S2C2ERKS0_
+ // CHECK: __ubsan_handle_load_invalid_value
+ // CHECK-LABEL: define {{.*}} @_ZN23CopyValueRepresentation2S1C2ERKS0_
+ // CHECK-NOT: call {{.*}} __ubsan_handle_load_invalid_value
+
+ struct CustomCopy { CustomCopy(); CustomCopy(const CustomCopy&); };
+ struct S1 {
+ CustomCopy CC;
+ bool b;
+ };
+ void callee1(S1);
+ void test1() {
+ S1 s11;
+ callee1(s11);
+ S1 s12;
+ s12 = s11;
+ }
+
+ static bool some_global_bool;
+ struct ExprCopy {
+ ExprCopy();
+ ExprCopy(const ExprCopy&, bool b = some_global_bool);
+ };
+ struct S2 {
+ ExprCopy EC;
+ bool b;
+ };
+ void callee2(S2);
+ void test2(void) {
+ S2 s21;
+ callee2(s21);
+ S2 s22;
+ s22 = s21;
+ }
+
+ struct CustomAssign { CustomAssign &operator=(const CustomAssign&); };
+ struct S3 {
+ CustomAssign CA;
+ bool b;
+ };
+ void test3() {
+ S3 x, y;
+ x = y;
+ }
+
+ struct CustomMove {
+ CustomMove();
+ CustomMove(const CustomMove&&);
+ CustomMove &operator=(const CustomMove&&);
+ };
+ struct S4 {
+ CustomMove CM;
+ bool b;
+ };
+ void test4() {
+ S4 x, y;
+ x = static_cast<S4&&>(y);
+ }
+
+ struct EnumCustomCopy {
+ EnumCustomCopy();
+ EnumCustomCopy(const EnumCustomCopy&);
+ };
+ struct S5 {
+ EnumCustomCopy ECC;
+ bool b;
+ };
+ void callee5(S5);
+ void test5() {
+ S5 s51;
+ callee5(s51);
+ S5 s52;
+ s52 = s51;
+ }
+}
+
// CHECK: attributes [[NR_NUW]] = { noreturn nounwind }