catch-undef-behavior.cpp revision 0848333c398d1ddd9f4e3b60cccef6a1b2698f78
12c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith// RUN: %clang_cc1 -fcatch-undefined-behavior -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s
22c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith
32c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith// CHECK: @_Z17reference_binding
42c9f87ca5cccbfdaad82762368af5b2323320653Richard Smithvoid reference_binding(int *p) {
52c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith  // C++ core issue 453: If an lvalue to which a reference is directly bound
62c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith  // designates neither an existing object or function of an appropriate type,
72c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith  // nor a region of storage of suitable size and alignment to contain an object
82c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith  // of the reference's type, the behavior is undefined.
92c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith
102c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith  // CHECK: icmp ne {{.*}}, null
112c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith
122c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith  // CHECK: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64
132c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith  // CHECK-NEXT: icmp uge i64 %[[SIZE]], 4
142c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith
152c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith  // CHECK: %[[PTRINT:.*]] = ptrtoint
162c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith  // CHECK-NEXT: %[[MISALIGN:.*]] = and i64 %[[PTRINT]], 3
172c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith  // CHECK-NEXT: icmp eq i64 %[[MISALIGN]], 0
182c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith  int &r = *p;
192c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith}
202c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith
212c9f87ca5cccbfdaad82762368af5b2323320653Richard Smithstruct S {
222c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith  double d;
232c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith  int a, b;
242c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith  virtual int f();
252c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith};
262c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith
272c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith// CHECK: @_Z13member_access
282c9f87ca5cccbfdaad82762368af5b2323320653Richard Smithvoid member_access(S *p) {
290848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith  // (1a) Check 'p' is appropriately sized and aligned for member access.
302c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith
312c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith  // CHECK: icmp ne {{.*}}, null
322c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith
332c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith  // CHECK: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64
342c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith  // CHECK-NEXT: icmp uge i64 %[[SIZE]], 24
352c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith
362c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith  // CHECK: %[[PTRINT:.*]] = ptrtoint
372c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith  // CHECK-NEXT: %[[MISALIGN:.*]] = and i64 %[[PTRINT]], 7
382c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith  // CHECK-NEXT: icmp eq i64 %[[MISALIGN]], 0
392c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith
400848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith  // (1b) Check that 'p' actually points to an 'S'.
410848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith
420848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith  // CHECK: %[[VPTRADDR:.*]] = bitcast {{.*}} to i64*
430848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith  // CHECK-NEXT: %[[VPTR:.*]] = load i64* %[[VPTRADDR]]
440848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith  //
450848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith  // hash_16_bytes:
460848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith  //
470848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith  // If this number changes, it indicates that either the mangled name of ::S
480848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith  // has changed, or that LLVM's hashing function has changed. The latter case
490848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith  // is OK if the hashing function is still stable.
500848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith  // CHECK-NEXT: xor i64 -4030275160588942838, %[[VPTR]]
510848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith  // CHECK-NEXT: mul i64 {{.*}}, -7070675565921424023
520848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith  // CHECK-NEXT: lshr i64 {{.*}}, 47
530848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith  // CHECK-NEXT: xor i64
540848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith  // CHECK-NEXT: xor i64 %[[VPTR]]
550848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith  // CHECK-NEXT: mul i64 {{.*}}, -7070675565921424023
560848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith  // CHECK-NEXT: lshr i64 {{.*}}, 47
570848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith  // CHECK-NEXT: xor i64
580848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith  // CHECK-NEXT: %[[HASH:.*]] = mul i64 {{.*}}, -7070675565921424023
590848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith  //
600848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith  // Check the hash against the table:
610848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith  //
620848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith  // CHECK-NEXT: %[[IDX:.*]] = and i64 %{{.*}}, 127
630848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith  // CHECK-NEXT: getelementptr inbounds [128 x i64]* @__ubsan_vptr_type_cache, i32 0, i64 %[[IDX]]
640848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith  // CHECK-NEXT: %[[CACHEVAL:.*]] = load i64*
650848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith  // CHECK-NEXT: icmp eq i64 %[[CACHEVAL]], %[[HASH]]
660848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith  // CHECK-NEXT: br i1
670848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith
680848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith  // CHECK: call void @__ubsan_handle_dynamic_type_cache_miss({{.*}}, i64 %{{.*}}, i64 %[[HASH]])
690848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith
702c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith  // (2) Check 'p->b' is appropriately sized and aligned for a load.
712c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith
722c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith  // FIXME: Suppress this in the trivial case of a member access, because we
732c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith  // know we've just checked the member access expression itself.
742c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith
752c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith  // CHECK: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64
762c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith  // CHECK-NEXT: icmp uge i64 %[[SIZE]], 4
772c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith
782c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith  // CHECK: %[[PTRINT:.*]] = ptrtoint
792c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith  // CHECK-NEXT: %[[MISALIGN:.*]] = and i64 %[[PTRINT]], 3
802c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith  // CHECK-NEXT: icmp eq i64 %[[MISALIGN]], 0
812c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith  int k = p->b;
822c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith
830848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith  // (3a) Check 'p' is appropriately sized and aligned for member function call.
842c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith
852c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith  // CHECK: icmp ne {{.*}}, null
862c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith
872c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith  // CHECK: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64
882c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith  // CHECK-NEXT: icmp uge i64 %[[SIZE]], 24
892c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith
902c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith  // CHECK: %[[PTRINT:.*]] = ptrtoint
912c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith  // CHECK-NEXT: %[[MISALIGN:.*]] = and i64 %[[PTRINT]], 7
922c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith  // CHECK-NEXT: icmp eq i64 %[[MISALIGN]], 0
930848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith
940848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith  // (3b) Check that 'p' actually points to an 'S'
950848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith
960848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith  // CHECK: load i64*
970848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith  // CHECK-NEXT: xor i64 -4030275160588942838,
980848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith  // [...]
990848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith  // CHECK: getelementptr inbounds [128 x i64]* @__ubsan_vptr_type_cache, i32 0, i64 %
1000848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith  // CHECK: br i1
1010848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith  // CHECK: call void @__ubsan_handle_dynamic_type_cache_miss({{.*}}, i64 %{{.*}}, i64 %{{.*}})
1020848333c398d1ddd9f4e3b60cccef6a1b2698f78Richard Smith
1032c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith  k = p->f();
1042c9f87ca5cccbfdaad82762368af5b2323320653Richard Smith}
1059d3e226acad5e23e562cde0a69362bb266f2a333Richard Smith
1069d3e226acad5e23e562cde0a69362bb266f2a333Richard Smith// CHECK: @_Z12lsh_overflow
1079d3e226acad5e23e562cde0a69362bb266f2a333Richard Smithint lsh_overflow(int a, int b) {
1089d3e226acad5e23e562cde0a69362bb266f2a333Richard Smith  // CHECK: %[[INBOUNDS:.*]] = icmp ule i32 %[[RHS:.*]], 31
1099d3e226acad5e23e562cde0a69362bb266f2a333Richard Smith  // CHECK-NEXT: br i1 %[[INBOUNDS]]
1109d3e226acad5e23e562cde0a69362bb266f2a333Richard Smith
1119d3e226acad5e23e562cde0a69362bb266f2a333Richard Smith  // CHECK: %[[SHIFTED_OUT_WIDTH:.*]] = sub nuw nsw i32 31, %[[RHS]]
1129d3e226acad5e23e562cde0a69362bb266f2a333Richard Smith  // CHECK-NEXT: %[[SHIFTED_OUT:.*]] = lshr i32 %[[LHS:.*]], %[[SHIFTED_OUT_WIDTH]]
1139d3e226acad5e23e562cde0a69362bb266f2a333Richard Smith
1149d3e226acad5e23e562cde0a69362bb266f2a333Richard Smith  // This is present for C++11 but not for C: C++ core issue 1457 allows a '1'
1159d3e226acad5e23e562cde0a69362bb266f2a333Richard Smith  // to be shifted into the sign bit, but not out of it.
1169d3e226acad5e23e562cde0a69362bb266f2a333Richard Smith  // CHECK-NEXT: %[[SHIFTED_OUT_NOT_SIGN:.*]] = lshr i32 %[[SHIFTED_OUT]], 1
1179d3e226acad5e23e562cde0a69362bb266f2a333Richard Smith
1189d3e226acad5e23e562cde0a69362bb266f2a333Richard Smith  // CHECK-NEXT: %[[NO_OVERFLOW:.*]] = icmp eq i32 %[[SHIFTED_OUT_NOT_SIGN]], 0
1199d3e226acad5e23e562cde0a69362bb266f2a333Richard Smith  // CHECK-NEXT: br i1 %[[NO_OVERFLOW]]
1209d3e226acad5e23e562cde0a69362bb266f2a333Richard Smith
1219d3e226acad5e23e562cde0a69362bb266f2a333Richard Smith  // CHECK: %[[RET:.*]] = shl i32 %[[LHS]], %[[RHS]]
1229d3e226acad5e23e562cde0a69362bb266f2a333Richard Smith  // CHECK-NEXT: ret i32 %[[RET]]
1239d3e226acad5e23e562cde0a69362bb266f2a333Richard Smith  return a << b;
1249d3e226acad5e23e562cde0a69362bb266f2a333Richard Smith}
12536ef0d54cfddf31cd48816e78ab4db73b31a6c1dRichard Smith
12636ef0d54cfddf31cd48816e78ab4db73b31a6c1dRichard Smith// CHECK: @_Z9no_return
12736ef0d54cfddf31cd48816e78ab4db73b31a6c1dRichard Smithint no_return() {
1284def70d3040e73707c738f7c366737a986135edfRichard Smith  // CHECK:      call void @__ubsan_handle_missing_return(i8* bitcast ({{.*}}* @{{.*}} to i8*)) noreturn nounwind
1294def70d3040e73707c738f7c366737a986135edfRichard Smith  // CHECK-NEXT: unreachable
13036ef0d54cfddf31cd48816e78ab4db73b31a6c1dRichard Smith}
131