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
|
|
|
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 -triple=i686-pc-linux-gnu
|
|
|
|
|
|
|
|
void ugly_news(int *ip) {
|
|
|
|
// These are ill-formed according to one reading of C++98, and at the least
|
2014-06-03 15:28:54 +08:00
|
|
|
// have undefined behavior.
|
|
|
|
// FIXME: They're ill-formed in C++11.
|
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)new int[-1]; // expected-warning {{array size is negative}}
|
|
|
|
(void)new int[2000000000]; // expected-warning {{array is too large}}
|
|
|
|
}
|
2012-02-16 20:59:47 +08:00
|
|
|
|
|
|
|
|
|
|
|
struct S {
|
|
|
|
S(int);
|
|
|
|
S();
|
|
|
|
~S();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct T { // expected-note 2 {{not viable}}
|
|
|
|
T(int); // expected-note {{not viable}}
|
|
|
|
};
|
|
|
|
|
|
|
|
void fn() {
|
|
|
|
(void) new int[2] {1, 2};
|
|
|
|
(void) new S[2] {1, 2};
|
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.
|
|
|
|
(void) new T[2] {1, 2}; // expected-error {{no matching constructor}} expected-note {{in implicit initialization of array element 2}}
|
2012-02-16 20:59:47 +08:00
|
|
|
}
|