2015-09-15 17:50:24 +08:00
|
|
|
// RUN: %clang_cc1 -fsanitize=alignment,null,object-size,shift-base,shift-exponent,return,signed-integer-overflow,vla-bound,float-cast-overflow,integer-divide-by-zero,bool,returns-nonnull-attribute,nonnull-attribute -fsanitize-recover=alignment,null,object-size,shift-base,shift-exponent,signed-integer-overflow,vla-bound,float-cast-overflow,integer-divide-by-zero,bool,returns-nonnull-attribute,nonnull-attribute -emit-llvm %s -o - -triple x86_64-linux-gnu | opt -instnamer -S | FileCheck %s --check-prefix=CHECK-COMMON --check-prefix=CHECK-UBSAN
|
|
|
|
// RUN: %clang_cc1 -fsanitize-trap=alignment,null,object-size,shift-base,shift-exponent,return,signed-integer-overflow,vla-bound,float-cast-overflow,integer-divide-by-zero,bool,returns-nonnull-attribute,nonnull-attribute -fsanitize-recover=alignment,null,object-size,shift-base,shift-exponent,signed-integer-overflow,vla-bound,float-cast-overflow,integer-divide-by-zero,bool,returns-nonnull-attribute,nonnull-attribute -fsanitize=alignment,null,object-size,shift-base,shift-exponent,return,signed-integer-overflow,vla-bound,float-cast-overflow,integer-divide-by-zero,bool,returns-nonnull-attribute,nonnull-attribute -fsanitize-recover=alignment,null,object-size,shift-base,shift-exponent,signed-integer-overflow,vla-bound,float-cast-overflow,integer-divide-by-zero,bool,returns-nonnull-attribute,nonnull-attribute -emit-llvm %s -o - -triple x86_64-linux-gnu | opt -instnamer -S | FileCheck %s --check-prefix=CHECK-COMMON --check-prefix=CHECK-TRAP
|
2012-11-06 10:30:30 +08:00
|
|
|
// RUN: %clang_cc1 -fsanitize=signed-integer-overflow -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK-OVERFLOW
|
2010-04-11 02:34:14 +08:00
|
|
|
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-UBSAN: @[[INT:.*]] = private unnamed_addr constant { i16, i16, [6 x i8] } { i16 0, i16 11, [6 x i8] c"'int'\00" }
|
2012-10-10 03:52:38 +08:00
|
|
|
|
|
|
|
// FIXME: When we only emit each type once, use [[INT]] more below.
|
2017-01-06 22:40:12 +08:00
|
|
|
// CHECK-UBSAN: @[[LINE_100:.*]] = private unnamed_addr global {{.*}}, i32 100, i32 5 {{.*}} @[[INT]], i8 2, i8 1
|
|
|
|
// CHECK-UBSAN: @[[LINE_200:.*]] = {{.*}}, i32 200, i32 10 {{.*}}, i8 2, i8 0
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-UBSAN: @[[LINE_300:.*]] = {{.*}}, i32 300, i32 12 {{.*}} @{{.*}}, {{.*}} @{{.*}}
|
|
|
|
// CHECK-UBSAN: @[[LINE_400:.*]] = {{.*}}, i32 400, i32 12 {{.*}} @{{.*}}, {{.*}} @{{.*}}
|
2017-01-06 22:40:12 +08:00
|
|
|
// CHECK-UBSAN: @[[LINE_500:.*]] = {{.*}}, i32 500, i32 10 {{.*}} @{{.*}}, i8 2, i8 0 }
|
|
|
|
// CHECK-UBSAN: @[[LINE_600:.*]] = {{.*}}, i32 600, i32 3 {{.*}} @{{.*}}, i8 2, i8 1 }
|
2012-10-10 03:52:38 +08:00
|
|
|
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-UBSAN: @[[STRUCT_S:.*]] = private unnamed_addr constant { i16, i16, [11 x i8] } { i16 -1, i16 0, [11 x i8] c"'struct S'\00" }
|
2012-10-10 03:52:38 +08:00
|
|
|
|
2017-01-06 22:40:12 +08:00
|
|
|
// CHECK-UBSAN: @[[LINE_700:.*]] = {{.*}}, i32 700, i32 14 {{.*}} @[[STRUCT_S]], i8 2, i8 3 }
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-UBSAN: @[[LINE_800:.*]] = {{.*}}, i32 800, i32 12 {{.*}} @{{.*}} }
|
|
|
|
// CHECK-UBSAN: @[[LINE_900:.*]] = {{.*}}, i32 900, i32 11 {{.*}} @{{.*}} }
|
2015-08-11 12:19:28 +08:00
|
|
|
// CHECK-UBSAN: @[[FP16:.*]] = private unnamed_addr constant { i16, i16, [9 x i8] } { i16 1, i16 16, [9 x i8] c"'__fp16'\00" }
|
|
|
|
// CHECK-UBSAN: @[[LINE_1200:.*]] = {{.*}}, i32 1200, i32 10 {{.*}} @{{.*}} }
|
|
|
|
// CHECK-UBSAN: @[[LINE_1300:.*]] = {{.*}}, i32 1300, i32 10 {{.*}} @{{.*}} }
|
|
|
|
// CHECK-UBSAN: @[[LINE_1400:.*]] = {{.*}}, i32 1400, i32 10 {{.*}} @{{.*}} }
|
|
|
|
// Make sure we check the fp16 type_mismatch data so we can easily match the signed char float_cast_overflow
|
|
|
|
// CHECK-UBSAN: @[[LINE_1500:.*]] = {{.*}}, i32 1500, i32 10 {{.*}} @[[FP16]], {{.*}} }
|
|
|
|
// CHECK-UBSAN: @[[SCHAR:.*]] = private unnamed_addr constant { i16, i16, [14 x i8] } { i16 0, i16 7, [14 x i8] c"'signed char'\00" }
|
|
|
|
// CHECK-UBSAN: @[[LINE_1500:.*]] = {{.*}}, i32 1500, i32 10 {{.*}} @[[FP16]], {{.*}} }
|
2012-10-10 03:52:38 +08:00
|
|
|
|
2010-04-11 02:34:14 +08:00
|
|
|
// PR6805
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-COMMON-LABEL: @foo
|
2010-04-11 02:34:14 +08:00
|
|
|
void foo() {
|
|
|
|
union { int i; } u;
|
2012-11-01 15:22:08 +08:00
|
|
|
|
Retry^2: [ubsan] Reduce null checking of C++ object pointers (PR27581)
This patch teaches ubsan to insert exactly one null check for the 'this'
pointer per method/lambda.
Previously, given a load of a member variable from an instance method
('this->x'), ubsan would insert a null check for 'this', and another
null check for '&this->x', before allowing the load to occur.
Similarly, given a call to a method from another method bound to the
same instance ('this->foo()'), ubsan would a redundant null check for
'this'. There is also a redundant null check in the case where the
object pointer is a reference ('Ref.foo()').
This patch teaches ubsan to remove the redundant null checks identified
above.
Testing: check-clang, check-ubsan, and a stage2 ubsan build.
I also compiled X86FastISel.cpp with -fsanitize=null using
patched/unpatched clangs based on r293572. Here are the number of null
checks emitted:
-------------------------------------
| Setup | # of null checks |
-------------------------------------
| unpatched, -O0 | 21767 |
| patched, -O0 | 10758 |
-------------------------------------
Changes since the initial commit:
- Don't introduce any unintentional object-size or alignment checks.
- Don't rely on IRGen of C labels in the test.
Differential Revision: https://reviews.llvm.org/D29530
llvm-svn: 295515
2017-02-18 07:22:59 +08:00
|
|
|
// CHECK-COMMON: %[[I8PTR:.*]] = bitcast i32* %[[PTR:.*]] to i8*
|
2019-01-31 04:34:35 +08:00
|
|
|
// CHECK-COMMON-NEXT: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64.p0i8(i8* %[[I8PTR]], i1 false, i1 false, i1 false)
|
2017-04-26 10:17:21 +08:00
|
|
|
// CHECK-COMMON-NEXT: %[[OK:.*]] = icmp uge i64 %[[SIZE]], 4
|
2014-11-12 06:03:54 +08:00
|
|
|
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-UBSAN: br i1 %[[OK]], {{.*}} !prof ![[WEIGHT_MD:.*]], !nosanitize
|
|
|
|
// CHECK-TRAP: br i1 %[[OK]], {{.*}}
|
2012-10-10 03:52:38 +08:00
|
|
|
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-UBSAN: %[[ARG:.*]] = ptrtoint {{.*}} %[[PTR]] to i64
|
2017-01-06 22:40:12 +08:00
|
|
|
// CHECK-UBSAN-NEXT: call void @__ubsan_handle_type_mismatch_v1(i8* bitcast ({{.*}} @[[LINE_100]] to i8*), i64 %[[ARG]])
|
2012-11-06 06:21:05 +08:00
|
|
|
|
2013-02-22 17:10:20 +08:00
|
|
|
// CHECK-TRAP: call void @llvm.trap() [[NR_NUW:#[0-9]+]]
|
2013-01-30 07:31:22 +08:00
|
|
|
// CHECK-TRAP-NEXT: unreachable
|
2012-10-10 03:52:38 +08:00
|
|
|
#line 100
|
2010-04-11 02:34:14 +08:00
|
|
|
u.i=1;
|
|
|
|
}
|
2012-05-08 04:23:03 +08:00
|
|
|
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-COMMON-LABEL: @bar
|
2012-05-08 04:23:03 +08:00
|
|
|
int bar(int *a) {
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-COMMON: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64
|
|
|
|
// CHECK-COMMON-NEXT: icmp uge i64 %[[SIZE]], 4
|
2012-08-24 08:54:33 +08:00
|
|
|
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-COMMON: %[[PTRINT:.*]] = ptrtoint
|
|
|
|
// CHECK-COMMON-NEXT: %[[MISALIGN:.*]] = and i64 %[[PTRINT]], 3
|
|
|
|
// CHECK-COMMON-NEXT: icmp eq i64 %[[MISALIGN]], 0
|
2013-01-30 07:31:22 +08:00
|
|
|
|
2017-10-03 09:27:24 +08:00
|
|
|
// CHECK-UBSAN: call void @__ubsan_handle_type_mismatch_v1(i8* bitcast ({{.*}} @[[LINE_200]] to i8*), i64 %[[PTRINT]])
|
2013-01-30 07:31:22 +08:00
|
|
|
|
2013-02-22 17:10:20 +08:00
|
|
|
// CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
|
2013-01-30 07:31:22 +08:00
|
|
|
// CHECK-TRAP-NEXT: unreachable
|
|
|
|
|
2012-10-10 03:52:38 +08:00
|
|
|
#line 200
|
2012-05-08 04:23:03 +08:00
|
|
|
return *a;
|
|
|
|
}
|
2012-08-25 08:32:28 +08:00
|
|
|
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-UBSAN-LABEL: @addr_space
|
2012-11-01 15:22:08 +08:00
|
|
|
int addr_space(int __attribute__((address_space(256))) *a) {
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-UBSAN-NOT: __ubsan
|
2012-11-01 15:22:08 +08:00
|
|
|
return *a;
|
|
|
|
}
|
|
|
|
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-COMMON-LABEL: @lsh_overflow
|
2012-08-25 08:32:28 +08:00
|
|
|
int lsh_overflow(int a, int b) {
|
2015-03-10 05:50:19 +08:00
|
|
|
// CHECK-COMMON: %[[RHS_INBOUNDS:.*]] = icmp ule i32 %[[RHS:.*]], 31
|
|
|
|
// CHECK-COMMON-NEXT: br i1 %[[RHS_INBOUNDS]], label %[[CHECK_BB:.*]], label %[[CONT_BB:.*]],
|
2015-03-06 05:57:35 +08:00
|
|
|
|
2015-03-10 05:50:19 +08:00
|
|
|
// CHECK-COMMON: [[CHECK_BB]]:
|
|
|
|
// CHECK-COMMON-NEXT: %[[SHIFTED_OUT_WIDTH:.*]] = sub nuw nsw i32 31, %[[RHS]]
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-COMMON-NEXT: %[[SHIFTED_OUT:.*]] = lshr i32 %[[LHS:.*]], %[[SHIFTED_OUT_WIDTH]]
|
|
|
|
// CHECK-COMMON-NEXT: %[[NO_OVERFLOW:.*]] = icmp eq i32 %[[SHIFTED_OUT]], 0
|
2015-03-10 05:50:19 +08:00
|
|
|
// CHECK-COMMON-NEXT: br label %[[CONT_BB]]
|
|
|
|
|
|
|
|
// CHECK-COMMON: [[CONT_BB]]:
|
|
|
|
// CHECK-COMMON-NEXT: %[[VALID_BASE:.*]] = phi i1 [ true, {{.*}} ], [ %[[NO_OVERFLOW]], %[[CHECK_BB]] ]
|
|
|
|
// CHECK-COMMON-NEXT: %[[VALID:.*]] = and i1 %[[RHS_INBOUNDS]], %[[VALID_BASE]]
|
2012-08-25 08:32:28 +08:00
|
|
|
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-UBSAN: br i1 %[[VALID]], {{.*}} !prof ![[WEIGHT_MD]]
|
|
|
|
// CHECK-TRAP: br i1 %[[VALID]]
|
2013-02-26 06:37:49 +08:00
|
|
|
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-UBSAN: %[[ARG1:.*]] = zext
|
|
|
|
// CHECK-UBSAN-NEXT: %[[ARG2:.*]] = zext
|
|
|
|
// CHECK-UBSAN-NEXT: call void @__ubsan_handle_shift_out_of_bounds(i8* bitcast ({{.*}} @[[LINE_300]] to i8*), i64 %[[ARG1]], i64 %[[ARG2]])
|
|
|
|
// CHECK-UBSAN-NOT: call void @__ubsan_handle_shift_out_of_bounds
|
2012-10-10 03:52:38 +08:00
|
|
|
|
2013-02-22 17:10:20 +08:00
|
|
|
// CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
|
2013-02-26 06:37:49 +08:00
|
|
|
// CHECK-TRAP: unreachable
|
|
|
|
// CHECK-TRAP-NOT: call void @llvm.trap()
|
2013-01-30 07:31:22 +08:00
|
|
|
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-COMMON: %[[RET:.*]] = shl i32 %[[LHS]], %[[RHS]]
|
|
|
|
// CHECK-COMMON-NEXT: ret i32 %[[RET]]
|
2012-10-10 03:52:38 +08:00
|
|
|
#line 300
|
2012-08-25 08:32:28 +08:00
|
|
|
return a << b;
|
|
|
|
}
|
|
|
|
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-COMMON-LABEL: @rsh_inbounds
|
2012-08-25 08:32:28 +08:00
|
|
|
int rsh_inbounds(int a, int b) {
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-COMMON: %[[INBOUNDS:.*]] = icmp ule i32 %[[RHS:.*]], 31
|
|
|
|
// CHECK-COMMON: br i1 %[[INBOUNDS]]
|
2013-01-30 07:31:22 +08:00
|
|
|
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-UBSAN: %[[ARG1:.*]] = zext
|
|
|
|
// CHECK-UBSAN-NEXT: %[[ARG2:.*]] = zext
|
|
|
|
// CHECK-UBSAN-NEXT: call void @__ubsan_handle_shift_out_of_bounds(i8* bitcast ({{.*}} @[[LINE_400]] to i8*), i64 %[[ARG1]], i64 %[[ARG2]])
|
2012-10-10 03:52:38 +08:00
|
|
|
|
2013-02-22 17:10:20 +08:00
|
|
|
// CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
|
2013-01-30 07:31:22 +08:00
|
|
|
// CHECK-TRAP-NEXT: unreachable
|
|
|
|
|
2015-03-10 05:50:19 +08:00
|
|
|
// CHECK-COMMON: %[[RET:.*]] = ashr i32 {{.*}}, %[[RHS]]
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-COMMON-NEXT: ret i32 %[[RET]]
|
2012-10-10 03:52:38 +08:00
|
|
|
#line 400
|
2012-08-25 08:32:28 +08:00
|
|
|
return a >> b;
|
|
|
|
}
|
2012-10-05 07:52:29 +08:00
|
|
|
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-COMMON-LABEL: @load
|
2012-10-10 03:52:38 +08:00
|
|
|
int load(int *p) {
|
2017-01-06 22:40:12 +08:00
|
|
|
// CHECK-UBSAN: call void @__ubsan_handle_type_mismatch_v1(i8* bitcast ({{.*}} @[[LINE_500]] to i8*), i64 %{{.*}})
|
2013-01-30 07:31:22 +08:00
|
|
|
|
2013-02-22 17:10:20 +08:00
|
|
|
// CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
|
2013-01-30 07:31:22 +08:00
|
|
|
// CHECK-TRAP-NEXT: unreachable
|
2012-10-10 03:52:38 +08:00
|
|
|
#line 500
|
|
|
|
return *p;
|
|
|
|
}
|
|
|
|
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-COMMON-LABEL: @store
|
2012-10-10 03:52:38 +08:00
|
|
|
void store(int *p, int q) {
|
2017-01-06 22:40:12 +08:00
|
|
|
// CHECK-UBSAN: call void @__ubsan_handle_type_mismatch_v1(i8* bitcast ({{.*}} @[[LINE_600]] to i8*), i64 %{{.*}})
|
2013-01-30 07:31:22 +08:00
|
|
|
|
2013-02-22 17:10:20 +08:00
|
|
|
// CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
|
2013-01-30 07:31:22 +08:00
|
|
|
// CHECK-TRAP-NEXT: unreachable
|
2012-10-10 03:52:38 +08:00
|
|
|
#line 600
|
|
|
|
*p = q;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct S { int k; };
|
|
|
|
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-COMMON-LABEL: @member_access
|
2012-10-10 03:52:38 +08:00
|
|
|
int *member_access(struct S *p) {
|
2017-01-06 22:40:12 +08:00
|
|
|
// CHECK-UBSAN: call void @__ubsan_handle_type_mismatch_v1(i8* bitcast ({{.*}} @[[LINE_700]] to i8*), i64 %{{.*}})
|
2013-01-30 07:31:22 +08:00
|
|
|
|
2013-02-22 17:10:20 +08:00
|
|
|
// CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
|
2013-01-30 07:31:22 +08:00
|
|
|
// CHECK-TRAP-NEXT: unreachable
|
2012-10-10 03:52:38 +08:00
|
|
|
#line 700
|
|
|
|
return &p->k;
|
|
|
|
}
|
|
|
|
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-COMMON-LABEL: @signed_overflow
|
2012-10-10 03:52:38 +08:00
|
|
|
int signed_overflow(int a, int b) {
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-UBSAN: %[[ARG1:.*]] = zext
|
|
|
|
// CHECK-UBSAN-NEXT: %[[ARG2:.*]] = zext
|
|
|
|
// CHECK-UBSAN-NEXT: call void @__ubsan_handle_add_overflow(i8* bitcast ({{.*}} @[[LINE_800]] to i8*), i64 %[[ARG1]], i64 %[[ARG2]])
|
2013-01-30 07:31:22 +08:00
|
|
|
|
2013-02-22 17:10:20 +08:00
|
|
|
// CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
|
2013-01-30 07:31:22 +08:00
|
|
|
// CHECK-TRAP-NEXT: unreachable
|
2012-10-10 03:52:38 +08:00
|
|
|
#line 800
|
|
|
|
return a + b;
|
|
|
|
}
|
|
|
|
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-COMMON-LABEL: @no_return
|
2012-10-05 07:52:29 +08:00
|
|
|
int no_return() {
|
|
|
|
// Reaching the end of a noreturn function is fine in C.
|
2012-11-06 06:21:05 +08:00
|
|
|
// FIXME: If the user explicitly requests -fsanitize=return, we should catch
|
|
|
|
// that here even though it's not undefined behavior.
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-COMMON-NOT: call
|
|
|
|
// CHECK-COMMON-NOT: unreachable
|
|
|
|
// CHECK-COMMON: ret i32
|
2012-10-05 07:52:29 +08:00
|
|
|
}
|
2012-10-10 09:11:12 +08:00
|
|
|
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-UBSAN-LABEL: @vla_bound
|
2012-10-10 09:11:12 +08:00
|
|
|
void vla_bound(int n) {
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-UBSAN: icmp sgt i32 %[[PARAM:.*]], 0
|
2012-10-10 09:11:12 +08:00
|
|
|
//
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-UBSAN: %[[ARG:.*]] = zext i32 %[[PARAM]] to i64
|
|
|
|
// CHECK-UBSAN-NEXT: call void @__ubsan_handle_vla_bound_not_positive(i8* bitcast ({{.*}} @[[LINE_900]] to i8*), i64 %[[ARG]])
|
2012-10-10 09:11:12 +08:00
|
|
|
#line 900
|
|
|
|
int arr[n * 3];
|
|
|
|
}
|
2012-10-13 06:57:06 +08:00
|
|
|
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-UBSAN-LABEL: @int_float_no_overflow
|
2012-10-13 06:57:06 +08:00
|
|
|
float int_float_no_overflow(__int128 n) {
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-UBSAN-NOT: call void @__ubsan_handle
|
2012-10-13 06:57:06 +08:00
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-COMMON-LABEL: @int_float_overflow
|
2012-10-13 06:57:06 +08:00
|
|
|
float int_float_overflow(unsigned __int128 n) {
|
Treat the range of representable values of floating-point types as [-inf, +inf] not as [-max, +max].
Summary:
Prior to r329065, we used [-max, max] as the range of representable
values because LLVM's `fptrunc` did not guarantee defined behavior when
truncating from a larger floating-point type to a smaller one. Now that
has been fixed, we can make clang follow normal IEEE 754 semantics in this
regard and take the larger range [-inf, +inf] as the range of representable
values.
In practice, this affects two parts of the frontend:
* the constant evaluator no longer treats floating-point evaluations
that result in +-inf as being undefined (because they no longer leave
the range of representable values of the type)
* UBSan no longer treats conversions to floating-point type that are
outside the [-max, +max] range as being undefined
In passing, also remove the float-divide-by-zero sanitizer from
-fsanitize=undefined, on the basis that while it's undefined per C++
rules (and we disallow it in constant expressions for that reason), it
is defined by Clang / LLVM / IEEE 754.
Reviewers: rnk, BillyONeal
Subscribers: cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D63793
llvm-svn: 365272
2019-07-07 05:05:52 +08:00
|
|
|
// CHECK-UBSAN-NOT: call {{.*}} @__ubsan_handle_float_cast_overflow(
|
|
|
|
// CHECK-TRAP-NOT: call {{.*}} @llvm.trap(
|
|
|
|
// CHECK-COMMON: }
|
2012-10-13 06:57:06 +08:00
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-COMMON-LABEL: @int_fp16_overflow
|
2012-10-13 06:57:06 +08:00
|
|
|
void int_fp16_overflow(int n, __fp16 *p) {
|
Treat the range of representable values of floating-point types as [-inf, +inf] not as [-max, +max].
Summary:
Prior to r329065, we used [-max, max] as the range of representable
values because LLVM's `fptrunc` did not guarantee defined behavior when
truncating from a larger floating-point type to a smaller one. Now that
has been fixed, we can make clang follow normal IEEE 754 semantics in this
regard and take the larger range [-inf, +inf] as the range of representable
values.
In practice, this affects two parts of the frontend:
* the constant evaluator no longer treats floating-point evaluations
that result in +-inf as being undefined (because they no longer leave
the range of representable values of the type)
* UBSan no longer treats conversions to floating-point type that are
outside the [-max, +max] range as being undefined
In passing, also remove the float-divide-by-zero sanitizer from
-fsanitize=undefined, on the basis that while it's undefined per C++
rules (and we disallow it in constant expressions for that reason), it
is defined by Clang / LLVM / IEEE 754.
Reviewers: rnk, BillyONeal
Subscribers: cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D63793
llvm-svn: 365272
2019-07-07 05:05:52 +08:00
|
|
|
// CHECK-UBSAN-NOT: call {{.*}} @__ubsan_handle_float_cast_overflow(
|
|
|
|
// CHECK-COMMON: }
|
2012-10-13 06:57:06 +08:00
|
|
|
*p = n;
|
|
|
|
}
|
|
|
|
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-COMMON-LABEL: @float_int_overflow
|
2012-10-13 06:57:06 +08:00
|
|
|
int float_int_overflow(float f) {
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-COMMON: %[[GE:.*]] = fcmp ogt float %[[F:.*]], 0xC1E0000020000000
|
|
|
|
// CHECK-COMMON: %[[LE:.*]] = fcmp olt float %[[F]], 0x41E0000000000000
|
|
|
|
// CHECK-COMMON: %[[INBOUNDS:.*]] = and i1 %[[GE]], %[[LE]]
|
|
|
|
// CHECK-COMMON-NEXT: br i1 %[[INBOUNDS]]
|
2013-01-30 07:31:22 +08:00
|
|
|
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-UBSAN: %[[CAST:.*]] = bitcast float %[[F]] to i32
|
|
|
|
// CHECK-UBSAN: %[[ARG:.*]] = zext i32 %[[CAST]] to i64
|
2015-08-11 12:19:28 +08:00
|
|
|
// CHECK-UBSAN: call void @__ubsan_handle_float_cast_overflow(i8* bitcast ({{.*}} @[[LINE_1200]] to i8*), i64 %[[ARG]]
|
2013-01-30 07:31:22 +08:00
|
|
|
|
2013-02-22 17:10:20 +08:00
|
|
|
// CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
|
2013-01-30 07:31:22 +08:00
|
|
|
// CHECK-TRAP-NEXT: unreachable
|
2015-08-11 12:19:28 +08:00
|
|
|
#line 1200
|
2012-10-13 06:57:06 +08:00
|
|
|
return f;
|
|
|
|
}
|
|
|
|
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-COMMON-LABEL: @long_double_int_overflow
|
2013-03-22 08:47:07 +08:00
|
|
|
int long_double_int_overflow(long double ld) {
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-UBSAN: alloca x86_fp80
|
2013-03-22 08:47:07 +08:00
|
|
|
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-COMMON: %[[GE:.*]] = fcmp ogt x86_fp80 %[[F:.*]], 0xKC01E800000010000000
|
|
|
|
// CHECK-COMMON: %[[LE:.*]] = fcmp olt x86_fp80 %[[F]], 0xK401E800000000000000
|
|
|
|
// CHECK-COMMON: %[[INBOUNDS:.*]] = and i1 %[[GE]], %[[LE]]
|
|
|
|
// CHECK-COMMON-NEXT: br i1 %[[INBOUNDS]]
|
2013-03-22 08:47:07 +08:00
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
// CHECK-UBSAN: store x86_fp80 %[[F]], x86_fp80* %[[ALLOCA:.*]], align 16, !nosanitize
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-UBSAN: %[[ARG:.*]] = ptrtoint x86_fp80* %[[ALLOCA]] to i64
|
2015-08-11 12:19:28 +08:00
|
|
|
// CHECK-UBSAN: call void @__ubsan_handle_float_cast_overflow(i8* bitcast ({{.*}} @[[LINE_1300]] to i8*), i64 %[[ARG]]
|
2013-03-22 08:47:07 +08:00
|
|
|
|
|
|
|
// CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
|
|
|
|
// CHECK-TRAP-NEXT: unreachable
|
2015-08-11 12:19:28 +08:00
|
|
|
#line 1300
|
2013-03-22 08:47:07 +08:00
|
|
|
return ld;
|
|
|
|
}
|
|
|
|
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-COMMON-LABEL: @float_uint_overflow
|
2012-10-13 06:57:06 +08:00
|
|
|
unsigned float_uint_overflow(float f) {
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-COMMON: %[[GE:.*]] = fcmp ogt float %[[F:.*]], -1.{{0*}}e+00
|
|
|
|
// CHECK-COMMON: %[[LE:.*]] = fcmp olt float %[[F]], 0x41F0000000000000
|
|
|
|
// CHECK-COMMON: %[[INBOUNDS:.*]] = and i1 %[[GE]], %[[LE]]
|
|
|
|
// CHECK-COMMON-NEXT: br i1 %[[INBOUNDS]]
|
2013-01-30 07:31:22 +08:00
|
|
|
|
2015-08-11 12:19:28 +08:00
|
|
|
// CHECK-UBSAN: call void @__ubsan_handle_float_cast_overflow(i8* bitcast ({{.*}} @[[LINE_1400]] to i8*),
|
2013-01-30 07:31:22 +08:00
|
|
|
|
2013-02-22 17:10:20 +08:00
|
|
|
// CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
|
2013-01-30 07:31:22 +08:00
|
|
|
// CHECK-TRAP-NEXT: unreachable
|
2015-08-11 12:19:28 +08:00
|
|
|
#line 1400
|
2012-10-13 06:57:06 +08:00
|
|
|
return f;
|
|
|
|
}
|
|
|
|
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-COMMON-LABEL: @fp16_char_overflow
|
2012-10-13 06:57:06 +08:00
|
|
|
signed char fp16_char_overflow(__fp16 *p) {
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-COMMON: %[[GE:.*]] = fcmp ogt float %[[F:.*]], -1.29{{0*}}e+02
|
|
|
|
// CHECK-COMMON: %[[LE:.*]] = fcmp olt float %[[F]], 1.28{{0*}}e+02
|
|
|
|
// CHECK-COMMON: %[[INBOUNDS:.*]] = and i1 %[[GE]], %[[LE]]
|
|
|
|
// CHECK-COMMON-NEXT: br i1 %[[INBOUNDS]]
|
2013-01-30 07:31:22 +08:00
|
|
|
|
2015-08-11 12:19:28 +08:00
|
|
|
// CHECK-UBSAN: call void @__ubsan_handle_float_cast_overflow(i8* bitcast ({{.*}} @[[LINE_1500]] to i8*),
|
2013-01-30 07:31:22 +08:00
|
|
|
|
2013-02-22 17:10:20 +08:00
|
|
|
// CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
|
2013-01-30 07:31:22 +08:00
|
|
|
// CHECK-TRAP-NEXT: unreachable
|
2015-08-11 12:19:28 +08:00
|
|
|
#line 1500
|
2012-10-13 06:57:06 +08:00
|
|
|
return *p;
|
|
|
|
}
|
|
|
|
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-COMMON-LABEL: @float_float_overflow
|
2012-10-13 06:57:06 +08:00
|
|
|
float float_float_overflow(double f) {
|
Treat the range of representable values of floating-point types as [-inf, +inf] not as [-max, +max].
Summary:
Prior to r329065, we used [-max, max] as the range of representable
values because LLVM's `fptrunc` did not guarantee defined behavior when
truncating from a larger floating-point type to a smaller one. Now that
has been fixed, we can make clang follow normal IEEE 754 semantics in this
regard and take the larger range [-inf, +inf] as the range of representable
values.
In practice, this affects two parts of the frontend:
* the constant evaluator no longer treats floating-point evaluations
that result in +-inf as being undefined (because they no longer leave
the range of representable values of the type)
* UBSan no longer treats conversions to floating-point type that are
outside the [-max, +max] range as being undefined
In passing, also remove the float-divide-by-zero sanitizer from
-fsanitize=undefined, on the basis that while it's undefined per C++
rules (and we disallow it in constant expressions for that reason), it
is defined by Clang / LLVM / IEEE 754.
Reviewers: rnk, BillyONeal
Subscribers: cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D63793
llvm-svn: 365272
2019-07-07 05:05:52 +08:00
|
|
|
// CHECK-UBSAN-NOT: call {{.*}} @__ubsan_handle_float_cast_overflow(i8* bitcast ({{.*}} @[[LINE_1600]] to i8*),
|
|
|
|
// CHECK-TRAP-NOT: call {{.*}} @llvm.trap() [[NR_NUW]]
|
|
|
|
// CHECK-COMMON: }
|
2012-10-13 06:57:06 +08:00
|
|
|
return f;
|
|
|
|
}
|
2012-11-06 10:30:30 +08:00
|
|
|
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-COMMON-LABEL: @int_divide_overflow
|
2014-07-18 07:53:44 +08:00
|
|
|
// CHECK-OVERFLOW-LABEL: @int_divide_overflow
|
2012-11-06 10:30:30 +08:00
|
|
|
int int_divide_overflow(int a, int b) {
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-COMMON: %[[ZERO:.*]] = icmp ne i32 %[[B:.*]], 0
|
2012-11-06 10:30:30 +08:00
|
|
|
// CHECK-OVERFLOW-NOT: icmp ne i32 %{{.*}}, 0
|
|
|
|
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-COMMON: %[[AOK:.*]] = icmp ne i32 %[[A:.*]], -2147483648
|
|
|
|
// CHECK-COMMON-NEXT: %[[BOK:.*]] = icmp ne i32 %[[B]], -1
|
|
|
|
// CHECK-COMMON-NEXT: %[[OVER:.*]] = or i1 %[[AOK]], %[[BOK]]
|
|
|
|
// CHECK-COMMON: %[[OK:.*]] = and i1 %[[ZERO]], %[[OVER]]
|
|
|
|
// CHECK-COMMON: br i1 %[[OK]]
|
2012-11-06 10:30:30 +08:00
|
|
|
|
|
|
|
// CHECK-OVERFLOW: %[[AOK:.*]] = icmp ne i32 %[[A:.*]], -2147483648
|
|
|
|
// CHECK-OVERFLOW-NEXT: %[[BOK:.*]] = icmp ne i32 %[[B:.*]], -1
|
|
|
|
// CHECK-OVERFLOW-NEXT: %[[OK:.*]] = or i1 %[[AOK]], %[[BOK]]
|
|
|
|
// CHECK-OVERFLOW: br i1 %[[OK]]
|
2013-01-30 07:31:22 +08:00
|
|
|
|
2013-02-22 17:10:20 +08:00
|
|
|
// CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
|
2013-01-30 07:31:22 +08:00
|
|
|
// CHECK-TRAP: unreachable
|
2012-11-06 10:30:30 +08:00
|
|
|
return a / b;
|
|
|
|
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-COMMON: }
|
2012-11-06 10:30:30 +08:00
|
|
|
// CHECK-OVERFLOW: }
|
|
|
|
}
|
2012-12-13 15:11:50 +08:00
|
|
|
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-COMMON-LABEL: @sour_bool
|
2012-12-13 15:11:50 +08:00
|
|
|
_Bool sour_bool(_Bool *p) {
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-COMMON: %[[OK:.*]] = icmp ule i8 {{.*}}, 1
|
|
|
|
// CHECK-COMMON: br i1 %[[OK]]
|
2013-01-30 07:31:22 +08:00
|
|
|
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-UBSAN: call void @__ubsan_handle_load_invalid_value(i8* bitcast ({{.*}}), i64 {{.*}})
|
2013-01-30 07:31:22 +08:00
|
|
|
|
2013-02-22 17:10:20 +08:00
|
|
|
// CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
|
2013-01-30 07:31:22 +08:00
|
|
|
// CHECK-TRAP: unreachable
|
2012-12-13 15:11:50 +08:00
|
|
|
return *p;
|
|
|
|
}
|
2012-12-15 09:39:14 +08:00
|
|
|
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-COMMON-LABEL: @ret_nonnull
|
2014-08-13 08:26:40 +08:00
|
|
|
__attribute__((returns_nonnull))
|
|
|
|
int *ret_nonnull(int *a) {
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-COMMON: [[OK:%.*]] = icmp ne i32* {{.*}}, null
|
|
|
|
// CHECK-COMMON: br i1 [[OK]]
|
|
|
|
|
|
|
|
// CHECK-UBSAN: call void @__ubsan_handle_nonnull_return
|
2014-08-13 08:26:40 +08:00
|
|
|
|
|
|
|
// CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
|
|
|
|
// CHECK-TRAP: unreachable
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-COMMON-LABEL: @call_decl_nonnull
|
2014-09-09 01:22:45 +08:00
|
|
|
__attribute__((nonnull)) void decl_nonnull(int *a);
|
|
|
|
void call_decl_nonnull(int *a) {
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-COMMON: [[OK:%.*]] = icmp ne i32* {{.*}}, null
|
|
|
|
// CHECK-COMMON: br i1 [[OK]]
|
|
|
|
|
|
|
|
// CHECK-UBSAN: call void @__ubsan_handle_nonnull_arg
|
2014-09-09 01:22:45 +08:00
|
|
|
|
|
|
|
// CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
|
|
|
|
// CHECK-TRAP: unreachable
|
|
|
|
decl_nonnull(a);
|
|
|
|
}
|
|
|
|
|
2015-05-31 00:11:40 +08:00
|
|
|
extern void *memcpy (void *, const void *, unsigned) __attribute__((nonnull(1, 2)));
|
|
|
|
|
|
|
|
// CHECK-COMMON-LABEL: @call_memcpy_nonnull
|
|
|
|
void call_memcpy_nonnull(void *p, void *q, int sz) {
|
|
|
|
// CHECK-COMMON: icmp ne i8* {{.*}}, null
|
|
|
|
// CHECK-UBSAN: call void @__ubsan_handle_nonnull_arg
|
|
|
|
// CHECK-TRAP: call void @llvm.trap()
|
|
|
|
|
|
|
|
// CHECK-COMMON: icmp ne i8* {{.*}}, null
|
|
|
|
// CHECK-UBSAN: call void @__ubsan_handle_nonnull_arg
|
|
|
|
// CHECK-TRAP: call void @llvm.trap()
|
|
|
|
memcpy(p, q, sz);
|
|
|
|
}
|
|
|
|
|
|
|
|
extern void *memmove (void *, const void *, unsigned) __attribute__((nonnull(1, 2)));
|
|
|
|
|
|
|
|
// CHECK-COMMON-LABEL: @call_memmove_nonnull
|
|
|
|
void call_memmove_nonnull(void *p, void *q, int sz) {
|
|
|
|
// CHECK-COMMON: icmp ne i8* {{.*}}, null
|
|
|
|
// CHECK-UBSAN: call void @__ubsan_handle_nonnull_arg
|
|
|
|
// CHECK-TRAP: call void @llvm.trap()
|
|
|
|
|
|
|
|
// CHECK-COMMON: icmp ne i8* {{.*}}, null
|
|
|
|
// CHECK-UBSAN: call void @__ubsan_handle_nonnull_arg
|
|
|
|
// CHECK-TRAP: call void @llvm.trap()
|
|
|
|
memmove(p, q, sz);
|
|
|
|
}
|
|
|
|
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-COMMON-LABEL: @call_nonnull_variadic
|
2014-09-09 01:22:45 +08:00
|
|
|
__attribute__((nonnull)) void nonnull_variadic(int a, ...);
|
|
|
|
void call_nonnull_variadic(int a, int *b) {
|
2014-11-12 05:50:44 +08:00
|
|
|
// CHECK-COMMON: [[OK:%.*]] = icmp ne i32* {{.*}}, null
|
|
|
|
// CHECK-COMMON: br i1 [[OK]]
|
|
|
|
|
|
|
|
// CHECK-UBSAN: call void @__ubsan_handle_nonnull_arg
|
|
|
|
// CHECK-UBSAN-NOT: __ubsan_handle_nonnull_arg
|
|
|
|
|
2015-04-17 07:25:00 +08:00
|
|
|
// CHECK-COMMON: call void (i32, ...) @nonnull_variadic
|
2014-09-09 01:22:45 +08:00
|
|
|
nonnull_variadic(a, b);
|
|
|
|
}
|
|
|
|
|
2014-12-16 03:10:08 +08:00
|
|
|
// CHECK-UBSAN: ![[WEIGHT_MD]] = !{!"branch_weights", i32 1048575, i32 1}
|
2013-02-22 17:10:20 +08:00
|
|
|
|
|
|
|
// CHECK-TRAP: attributes [[NR_NUW]] = { noreturn nounwind }
|