2012-02-23 01:37:52 +08:00
|
|
|
// RUN: %clang_cc1 -std=c++11 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s
|
2017-02-14 07:49:55 +08:00
|
|
|
// RUN: %clang_cc1 -std=c++11 -triple i386-unknown-unknown %s -emit-llvm -fsanitize=signed-integer-overflow -o - | FileCheck --check-prefix=SIO %s
|
2012-02-23 01:37:52 +08:00
|
|
|
|
PR22924, PR22845, some of CWG1464: When checking the initializer for an array
new expression, distinguish between the case of a constant and non-constant
initializer. In the former case, if the bound is erroneous (too many
initializer elements, bound is negative, or allocated size overflows), reject,
and take the bound into account when determining whether we need to
default-construct any elements. In the remanining cases, move the logic to
check for default-constructibility of trailing elements into the initialization
code rather than inventing a bogus array bound, to cope with cases where the
number of initialized elements is not the same as the number of initializer
list elements (this can happen due to string literal initialization or brace
elision).
This also fixes rejects-valid and crash-on-valid errors when initializing a
new'd array of character type from a braced string literal.
llvm-svn: 283406
2016-10-06 06:41:02 +08:00
|
|
|
// CHECK: @[[ABC4:.*]] = {{.*}} constant [4 x i8] c"abc\00"
|
|
|
|
// CHECK: @[[ABC15:.*]] = {{.*}} constant [15 x i8] c"abc\00\00\00\00
|
|
|
|
|
2013-08-15 14:47:53 +08:00
|
|
|
// CHECK-LABEL: define void @_Z2fni
|
2012-02-23 01:37:52 +08:00
|
|
|
void fn(int n) {
|
|
|
|
// CHECK: icmp ult i{{32|64}} %{{[^ ]+}}, 3
|
|
|
|
// CHECK: store i32 1
|
|
|
|
// CHECK: store i32 2
|
|
|
|
// CHECK: store i32 3
|
2014-06-03 14:58:52 +08:00
|
|
|
// CHECK: sub {{.*}}, 12
|
|
|
|
// CHECK: call void @llvm.memset
|
2012-02-23 01:37:52 +08:00
|
|
|
new int[n] { 1, 2, 3 };
|
|
|
|
}
|
|
|
|
|
2013-08-15 14:47:53 +08:00
|
|
|
// CHECK-LABEL: define void @_Z11const_exactv
|
2012-02-23 01:37:52 +08:00
|
|
|
void const_exact() {
|
|
|
|
// CHECK-NOT: icmp ult i{{32|64}} %{{[^ ]+}}, 3
|
|
|
|
// CHECK-NOT: icmp eq i32*
|
|
|
|
new int[3] { 1, 2, 3 };
|
|
|
|
}
|
|
|
|
|
2013-08-15 14:47:53 +08:00
|
|
|
// CHECK-LABEL: define void @_Z16const_sufficientv
|
2012-02-23 01:37:52 +08:00
|
|
|
void const_sufficient() {
|
|
|
|
// CHECK-NOT: icmp ult i{{32|64}} %{{[^ ]+}}, 3
|
|
|
|
new int[4] { 1, 2, 3 };
|
|
|
|
// CHECK: ret void
|
|
|
|
}
|
2014-06-03 14:58:52 +08:00
|
|
|
|
|
|
|
// CHECK-LABEL: define void @_Z22check_array_value_initv
|
|
|
|
void check_array_value_init() {
|
|
|
|
struct S;
|
|
|
|
new (int S::*[3][4][5]) ();
|
|
|
|
|
2016-04-08 05:46:12 +08:00
|
|
|
// CHECK: call i8* @_Zna{{.}}(i{{32 240|64 480}})
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK: getelementptr inbounds i{{32|64}}, i{{32|64}}* {{.*}}, i{{32|64}} 60
|
2014-06-03 14:58:52 +08:00
|
|
|
|
|
|
|
// CHECK: phi
|
|
|
|
// CHECK: store i{{32|64}} -1,
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK: getelementptr inbounds i{{32|64}}, i{{32|64}}* {{.*}}, i{{32|64}} 1
|
2014-06-03 14:58:52 +08:00
|
|
|
// CHECK: icmp eq
|
|
|
|
// CHECK: br i1
|
|
|
|
}
|
PR22924, PR22845, some of CWG1464: When checking the initializer for an array
new expression, distinguish between the case of a constant and non-constant
initializer. In the former case, if the bound is erroneous (too many
initializer elements, bound is negative, or allocated size overflows), reject,
and take the bound into account when determining whether we need to
default-construct any elements. In the remanining cases, move the logic to
check for default-constructibility of trailing elements into the initialization
code rather than inventing a bogus array bound, to cope with cases where the
number of initialized elements is not the same as the number of initializer
list elements (this can happen due to string literal initialization or brace
elision).
This also fixes rejects-valid and crash-on-valid errors when initializing a
new'd array of character type from a braced string literal.
llvm-svn: 283406
2016-10-06 06:41:02 +08:00
|
|
|
|
|
|
|
// CHECK-LABEL: define void @_Z15string_nonconsti
|
|
|
|
void string_nonconst(int n) {
|
|
|
|
// CHECK: icmp slt i{{32|64}} %{{[^ ]+}}, 4
|
|
|
|
// FIXME: Conditionally throw an exception rather than passing -1 to alloc function
|
|
|
|
// CHECK: select
|
|
|
|
// CHECK: %[[PTR:.*]] = call i8* @_Zna{{.}}(i{{32|64}}
|
|
|
|
// CHECK: call void @llvm.memcpy{{.*}}(i8* %[[PTR]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[ABC4]], i32 0, i32 0), i32 4,
|
|
|
|
// CHECK: %[[REST:.*]] = getelementptr inbounds i8, i8* %[[PTR]], i32 4
|
|
|
|
// CHECK: %[[RESTSIZE:.*]] = sub {{.*}}, 4
|
|
|
|
// CHECK: call void @llvm.memset{{.*}}(i8* %[[REST]], i8 0, i{{32|64}} %[[RESTSIZE]],
|
|
|
|
new char[n] { "abc" };
|
|
|
|
}
|
|
|
|
|
|
|
|
// CHECK-LABEL: define void @_Z12string_exactv
|
|
|
|
void string_exact() {
|
|
|
|
// CHECK-NOT: icmp
|
|
|
|
// CHECK: %[[PTR:.*]] = call i8* @_Zna{{.}}(i{{32|64}} 4)
|
|
|
|
// CHECK: call void @llvm.memcpy{{.*}}(i8* %[[PTR]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[ABC4]], i32 0, i32 0), i32 4,
|
|
|
|
// CHECK-NOT: memset
|
|
|
|
new char[4] { "abc" };
|
|
|
|
}
|
|
|
|
|
|
|
|
// CHECK-LABEL: define void @_Z17string_sufficientv
|
|
|
|
void string_sufficient() {
|
|
|
|
// CHECK-NOT: icmp
|
|
|
|
// CHECK: %[[PTR:.*]] = call i8* @_Zna{{.}}(i{{32|64}} 15)
|
|
|
|
// FIXME: For very large arrays, it would be preferable to emit a small copy and a memset.
|
|
|
|
// CHECK: call void @llvm.memcpy{{.*}}(i8* %[[PTR]], i8* getelementptr inbounds ([15 x i8], [15 x i8]* @[[ABC15]], i32 0, i32 0), i32 15,
|
|
|
|
// CHECK-NOT: memset
|
|
|
|
new char[15] { "abc" };
|
|
|
|
}
|
|
|
|
|
|
|
|
// CHECK-LABEL: define void @_Z10aggr_exactv
|
|
|
|
void aggr_exact() {
|
|
|
|
// CHECK-NOT: icmp
|
|
|
|
// CHECK: %[[MEM:.*]] = call i8* @_Zna{{.}}(i{{32|64}} 16)
|
|
|
|
// CHECK: %[[PTR0:.*]] = bitcast i8* %[[MEM]] to %[[AGGR:.*]]*
|
|
|
|
// CHECK: %[[FIELD:.*]] = getelementptr inbounds %[[AGGR]], %[[AGGR]]* %[[PTR0]], i32 0, i32 0{{$}}
|
|
|
|
// CHECK: store i32 1, i32* %[[FIELD]]
|
|
|
|
// CHECK: %[[FIELD:.*]] = getelementptr inbounds %[[AGGR]], %[[AGGR]]* %[[PTR0]], i32 0, i32 1{{$}}
|
|
|
|
// CHECK: store i32 2, i32* %[[FIELD]]
|
|
|
|
// CHECK: %[[PTR1:.*]] = getelementptr inbounds %[[AGGR]], %[[AGGR]]* %[[PTR0]], i32 1{{$}}
|
|
|
|
// CHECK: %[[FIELD:.*]] = getelementptr inbounds %[[AGGR]], %[[AGGR]]* %[[PTR1]], i32 0, i32 0{{$}}
|
|
|
|
// CHECK: store i32 3, i32* %[[FIELD]]
|
|
|
|
// CHECK: %[[FIELD:.*]] = getelementptr inbounds %[[AGGR]], %[[AGGR]]* %[[PTR1]], i32 0, i32 1{{$}}
|
|
|
|
// CHECK: store i32 0, i32* %[[FIELD]]
|
|
|
|
// CHECK-NOT: store
|
|
|
|
// CHECK-NOT: memset
|
|
|
|
struct Aggr { int a, b; };
|
|
|
|
new Aggr[2] { 1, 2, 3 };
|
|
|
|
}
|
|
|
|
|
|
|
|
// CHECK-LABEL: define void @_Z15aggr_sufficienti
|
|
|
|
void aggr_sufficient(int n) {
|
|
|
|
// CHECK: icmp ult i32 %{{.*}}, 2
|
|
|
|
// CHECK: %[[MEM:.*]] = call i8* @_Zna{{.}}(
|
|
|
|
// CHECK: %[[PTR0:.*]] = bitcast i8* %[[MEM]] to %[[AGGR:.*]]*
|
|
|
|
// CHECK: %[[FIELD:.*]] = getelementptr inbounds %[[AGGR]], %[[AGGR]]* %[[PTR0]], i32 0, i32 0{{$}}
|
|
|
|
// CHECK: store i32 1, i32* %[[FIELD]]
|
|
|
|
// CHECK: %[[FIELD:.*]] = getelementptr inbounds %[[AGGR]], %[[AGGR]]* %[[PTR0]], i32 0, i32 1{{$}}
|
|
|
|
// CHECK: store i32 2, i32* %[[FIELD]]
|
|
|
|
// CHECK: %[[PTR1:.*]] = getelementptr inbounds %[[AGGR]], %[[AGGR]]* %[[PTR0]], i32 1{{$}}
|
|
|
|
// CHECK: %[[FIELD:.*]] = getelementptr inbounds %[[AGGR]], %[[AGGR]]* %[[PTR1]], i32 0, i32 0{{$}}
|
|
|
|
// CHECK: store i32 3, i32* %[[FIELD]]
|
|
|
|
// CHECK: %[[FIELD:.*]] = getelementptr inbounds %[[AGGR]], %[[AGGR]]* %[[PTR1]], i32 0, i32 1{{$}}
|
|
|
|
// CHECK: store i32 0, i32* %[[FIELD]]
|
|
|
|
// CHECK: %[[PTR2:.*]] = getelementptr inbounds %[[AGGR]], %[[AGGR]]* %[[PTR1]], i32 1{{$}}
|
|
|
|
// CHECK: %[[REMAIN:.*]] = sub i32 {{.*}}, 16
|
|
|
|
// CHECK: %[[MEM:.*]] = bitcast %[[AGGR]]* %[[PTR2]] to i8*
|
|
|
|
// CHECK: call void @llvm.memset{{.*}}(i8* %[[MEM]], i8 0, i32 %[[REMAIN]],
|
|
|
|
struct Aggr { int a, b; };
|
|
|
|
new Aggr[n] { 1, 2, 3 };
|
|
|
|
}
|
2017-02-14 07:49:55 +08:00
|
|
|
|
|
|
|
// SIO-LABEL: define void @_Z14constexpr_testv
|
|
|
|
void constexpr_test() {
|
|
|
|
// SIO: call i8* @_Zna{{.}}(i32 4)
|
|
|
|
new int[0+1]{0};
|
|
|
|
}
|