2017-01-25 07:18:28 +08:00
|
|
|
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 -triple=i686-pc-linux-gnu -pedantic
|
Fix a rejects-valid in C++11: array new of a negative size, or overflowing array
new, is well-formed with defined semantics of throwing (a type which can be
caught by a handler for) std::bad_array_new_length, unlike in C++98 where it is
somewhere nebulous between undefined behavior and ill-formed.
If the array size is an integral constant expression and satisfies one of these
criteria, we would previous the array new expression, but now in C++11 mode, we
merely issue a warning (the code is still rejected in C++98 mode, naturally).
We don't yet implement new C++11 semantics correctly (see PR11644), but we do
implement the overflow checking, and (for the default operator new) convert such
expressions to an exception, so accepting such code now does not seem especially
unsafe.
llvm-svn: 149767
2012-02-04 13:35:53 +08:00
|
|
|
|
|
|
|
void ugly_news(int *ip) {
|
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
|
|
|
(void)new int[-1]; // expected-error {{array size is negative}}
|
|
|
|
(void)new int[2000000000]; // expected-error {{array is too large}}
|
Fix a rejects-valid in C++11: array new of a negative size, or overflowing array
new, is well-formed with defined semantics of throwing (a type which can be
caught by a handler for) std::bad_array_new_length, unlike in C++98 where it is
somewhere nebulous between undefined behavior and ill-formed.
If the array size is an integral constant expression and satisfies one of these
criteria, we would previous the array new expression, but now in C++11 mode, we
merely issue a warning (the code is still rejected in C++98 mode, naturally).
We don't yet implement new C++11 semantics correctly (see PR11644), but we do
implement the overflow checking, and (for the default operator new) convert such
expressions to an exception, so accepting such code now does not seem especially
unsafe.
llvm-svn: 149767
2012-02-04 13:35:53 +08:00
|
|
|
}
|
2012-02-16 20:59:47 +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
|
|
|
void pr22845a() {
|
|
|
|
constexpr int i = -1;
|
|
|
|
int *p = new int[i]; // expected-error {{array size is negative}}
|
|
|
|
}
|
|
|
|
|
|
|
|
void pr22845b() {
|
|
|
|
constexpr int i = 1;
|
|
|
|
int *p = new int[i]{1, 2}; // expected-error {{excess elements in array initializer}}
|
|
|
|
}
|
2012-02-16 20:59:47 +08:00
|
|
|
|
|
|
|
struct S {
|
|
|
|
S(int);
|
|
|
|
S();
|
|
|
|
~S();
|
|
|
|
};
|
|
|
|
|
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
|
|
|
struct T { // expected-note 1+{{not viable}}
|
|
|
|
T(int); // expected-note 1+{{not viable}}
|
2012-02-16 20:59:47 +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
|
|
|
void fn(int n) {
|
2012-02-16 20:59:47 +08:00
|
|
|
(void) new int[2] {1, 2};
|
|
|
|
(void) new S[2] {1, 2};
|
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
|
|
|
(void) new S[3] {1, 2};
|
2017-01-25 07:18:28 +08:00
|
|
|
(void) new S[n] {};
|
2014-06-03 15:28:54 +08:00
|
|
|
// C++11 [expr.new]p19:
|
|
|
|
// If the new-expression creates an object or an array of objects of class
|
|
|
|
// type, access and ambiguity control are done for the allocation function,
|
|
|
|
// the deallocation function (12.5), and the constructor (12.1).
|
|
|
|
//
|
|
|
|
// Note that this happens even if the array bound is constant and the
|
|
|
|
// initializer initializes every array element.
|
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
|
|
|
//
|
|
|
|
// It's not clear that this is the intended interpretation, however -- we
|
|
|
|
// obviously don't want to check for a default constructor for 'new S(0)'.
|
|
|
|
// Instead, we only check for a default constructor in the case of an array
|
|
|
|
// new with a non-constant bound or insufficient initializers.
|
|
|
|
(void) new T[2] {1, 2}; // ok
|
|
|
|
(void) new T[3] {1, 2}; // expected-error {{no matching constructor}} expected-note {{in implicit initialization of array element 2}}
|
|
|
|
(void) new T[n] {1, 2}; // expected-error {{no matching constructor}} expected-note {{in implicit initialization of trailing array elements in runtime-sized array new}}
|
2017-01-25 07:18:28 +08:00
|
|
|
(void) new T[n] {}; // expected-error {{no matching constructor}} expected-note {{in implicit initialization of trailing array elements in runtime-sized array new}}
|
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
|
|
|
}
|
|
|
|
|
|
|
|
struct U {
|
|
|
|
T t; // expected-note 3{{in implicit initialization of field 't'}}
|
|
|
|
S s;
|
|
|
|
};
|
|
|
|
void g(int n) {
|
|
|
|
// Aggregate initialization, brace-elision, and array new combine to create
|
|
|
|
// this monstrosity.
|
|
|
|
(void) new U[2] {1, 2}; // expected-error {{no matching constructor}} expected-note {{in implicit initialization of array element 1}}
|
|
|
|
(void) new U[2] {1, 2, 3}; // ok
|
|
|
|
(void) new U[2] {1, 2, 3, 4}; // ok
|
|
|
|
(void) new U[2] {1, 2, 3, 4, 5}; // expected-error {{excess elements in array initializer}}
|
|
|
|
|
|
|
|
(void) new U[n] {1, 2}; // expected-error {{no matching constructor}} expected-note {{in implicit initialization of trailing array elements}}
|
|
|
|
(void) new U[n] {1, 2, 3}; // expected-error {{no matching constructor}} expected-note {{in implicit initialization of trailing array elements}}
|
2012-02-16 20:59:47 +08:00
|
|
|
}
|