PR c++/83058 - ICE on C++ code with negative array index: in warn_placement_new_too_small
gcc/cp/ChangeLog: PR c++/83058 * init.c (warn_placement_new_too_small): Use offset_int instead of HOST_WIDE_INT. gcc/testsuite/ChangeLog: PR c++/83058 * g++.dg/warn/Wplacement-new-size-5.C: New test. From-SVN: r255182
This commit is contained in:
parent
de3d4fd0f5
commit
9ca1eaacd3
@ -1,3 +1,9 @@
|
||||
2017-11-27 Martin Sebor <msebor@redhat.com>
|
||||
|
||||
PR c++/83058
|
||||
* init.c (warn_placement_new_too_small): Use offset_int instead of
|
||||
HOST_WIDE_INT.
|
||||
|
||||
2017-11-27 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/81888
|
||||
|
125
gcc/cp/init.c
125
gcc/cp/init.c
@ -2498,9 +2498,9 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
|
||||
|
||||
/* The number of bytes to add to or subtract from the size of the provided
|
||||
buffer based on an offset into an array or an array element reference.
|
||||
Although intermediate results may be negative (as in a[3] - 2) the final
|
||||
result cannot be. */
|
||||
HOST_WIDE_INT adjust = 0;
|
||||
Although intermediate results may be negative (as in a[3] - 2) a valid
|
||||
final result cannot be. */
|
||||
offset_int adjust = 0;
|
||||
/* True when the size of the entire destination object should be used
|
||||
to compute the possibly optimistic estimate of the available space. */
|
||||
bool use_obj_size = false;
|
||||
@ -2524,7 +2524,7 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
|
||||
is a constant. */
|
||||
if (TREE_CODE (oper) == POINTER_PLUS_EXPR)
|
||||
{
|
||||
/* If the offset is comple-time constant, use it to compute a more
|
||||
/* If the offset is compile-time constant, use it to compute a more
|
||||
accurate estimate of the size of the buffer. Since the operand
|
||||
of POINTER_PLUS_EXPR is represented as an unsigned type, convert
|
||||
it to signed first.
|
||||
@ -2532,7 +2532,7 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
|
||||
estimate (this may lead to false negatives). */
|
||||
tree adj = TREE_OPERAND (oper, 1);
|
||||
if (CONSTANT_CLASS_P (adj))
|
||||
adjust += tree_to_shwi (convert (ssizetype, adj));
|
||||
adjust += wi::to_offset (convert (ssizetype, adj));
|
||||
else
|
||||
use_obj_size = true;
|
||||
|
||||
@ -2559,9 +2559,9 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
|
||||
not a compile-time constant, use the index to determine the
|
||||
size of the buffer. Otherwise, use the entire array as
|
||||
an optimistic estimate of the size. */
|
||||
const_tree adj = TREE_OPERAND (oper, 1);
|
||||
const_tree adj = fold_non_dependent_expr (TREE_OPERAND (oper, 1));
|
||||
if (!use_obj_size && CONSTANT_CLASS_P (adj))
|
||||
adjust += tree_to_shwi (adj);
|
||||
adjust += wi::to_offset (adj);
|
||||
else
|
||||
{
|
||||
use_obj_size = true;
|
||||
@ -2580,10 +2580,18 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
|
||||
members from arrays of unspecified size. */
|
||||
bool compref = TREE_CODE (oper) == COMPONENT_REF;
|
||||
|
||||
/* For COMPONENT_REF (i.e., a struct member) the size of the entire
|
||||
enclosing struct. Used to validate the adjustment (offset) into
|
||||
an array at the end of a struct. */
|
||||
offset_int compsize = 0;
|
||||
|
||||
/* Descend into a struct or union to find the member whose address
|
||||
is being used as the argument. */
|
||||
if (TREE_CODE (oper) == COMPONENT_REF)
|
||||
{
|
||||
tree comptype = TREE_TYPE (TREE_OPERAND (oper, 0));
|
||||
compsize = wi::to_offset (TYPE_SIZE_UNIT (comptype));
|
||||
|
||||
tree op0 = oper;
|
||||
while (TREE_CODE (op0 = TREE_OPERAND (op0, 0)) == COMPONENT_REF);
|
||||
if (VAR_P (op0))
|
||||
@ -2591,14 +2599,15 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
|
||||
oper = TREE_OPERAND (oper, 1);
|
||||
}
|
||||
|
||||
if ((addr_expr || !POINTER_TYPE_P (TREE_TYPE (oper)))
|
||||
tree opertype = TREE_TYPE (oper);
|
||||
if ((addr_expr || !POINTER_TYPE_P (opertype))
|
||||
&& (VAR_P (oper)
|
||||
|| TREE_CODE (oper) == FIELD_DECL
|
||||
|| TREE_CODE (oper) == PARM_DECL))
|
||||
{
|
||||
/* A possibly optimistic estimate of the number of bytes available
|
||||
in the destination buffer. */
|
||||
unsigned HOST_WIDE_INT bytes_avail = 0;
|
||||
offset_int bytes_avail = 0;
|
||||
/* True when the estimate above is in fact the exact size
|
||||
of the destination buffer rather than an estimate. */
|
||||
bool exact_size = true;
|
||||
@ -2613,47 +2622,42 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
|
||||
/* Use the size of the entire array object when the expression
|
||||
refers to a variable or its size depends on an expression
|
||||
that's not a compile-time constant. */
|
||||
bytes_avail = tree_to_uhwi (DECL_SIZE_UNIT (oper));
|
||||
bytes_avail = wi::to_offset (DECL_SIZE_UNIT (oper));
|
||||
exact_size = !use_obj_size;
|
||||
}
|
||||
else if (TYPE_SIZE_UNIT (TREE_TYPE (oper))
|
||||
&& tree_fits_uhwi_p (TYPE_SIZE_UNIT (TREE_TYPE (oper))))
|
||||
else if (tree opersize = TYPE_SIZE_UNIT (opertype))
|
||||
{
|
||||
/* Use the size of the type of the destination buffer object
|
||||
as the optimistic estimate of the available space in it. */
|
||||
bytes_avail = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (oper)));
|
||||
}
|
||||
else if (var_decl)
|
||||
{
|
||||
/* Constructing into a buffer provided by the flexible array
|
||||
member of a declared object (which is permitted as a G++
|
||||
extension). If the array member has been initialized,
|
||||
determine its size from the initializer. Otherwise,
|
||||
the array size is zero. */
|
||||
bytes_avail = 0;
|
||||
|
||||
if (tree init = find_field_init (oper, DECL_INITIAL (var_decl)))
|
||||
bytes_avail = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (init)));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Bail if neither the size of the object nor its type is known. */
|
||||
return;
|
||||
as the optimistic estimate of the available space in it.
|
||||
Use the maximum possible size for zero-size arrays and
|
||||
flexible array members (except of initialized objects
|
||||
thereof). */
|
||||
if (TREE_CODE (opersize) == INTEGER_CST)
|
||||
bytes_avail = wi::to_offset (opersize);
|
||||
}
|
||||
|
||||
tree_code oper_code = TREE_CODE (TREE_TYPE (oper));
|
||||
if (bytes_avail == 0)
|
||||
{
|
||||
if (var_decl)
|
||||
{
|
||||
/* Constructing into a buffer provided by the flexible array
|
||||
member of a declared object (which is permitted as a G++
|
||||
extension). If the array member has been initialized,
|
||||
determine its size from the initializer. Otherwise,
|
||||
the array size is zero. */
|
||||
if (tree init = find_field_init (oper, DECL_INITIAL (var_decl)))
|
||||
bytes_avail = wi::to_offset (TYPE_SIZE_UNIT (TREE_TYPE (init)));
|
||||
}
|
||||
else
|
||||
bytes_avail = (wi::to_offset (TYPE_MAX_VALUE (ptrdiff_type_node))
|
||||
- compsize);
|
||||
}
|
||||
|
||||
tree_code oper_code = TREE_CODE (opertype);
|
||||
|
||||
if (compref && oper_code == ARRAY_TYPE)
|
||||
{
|
||||
/* Avoid diagnosing flexible array members (which are accepted
|
||||
as an extension and diagnosed with -Wpedantic) and zero-length
|
||||
arrays (also an extension).
|
||||
Overflowing construction in one-element arrays is diagnosed
|
||||
only at level 2. */
|
||||
if (bytes_avail == 0 && !var_decl)
|
||||
return;
|
||||
|
||||
tree nelts = array_type_nelts_top (TREE_TYPE (oper));
|
||||
tree nelts = array_type_nelts_top (opertype);
|
||||
tree nelts_cst = maybe_constant_value (nelts);
|
||||
if (TREE_CODE (nelts_cst) == INTEGER_CST
|
||||
&& integer_onep (nelts_cst)
|
||||
@ -2662,29 +2666,35 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
|
||||
return;
|
||||
}
|
||||
|
||||
/* The size of the buffer can only be adjusted down but not up. */
|
||||
gcc_checking_assert (0 <= adjust);
|
||||
|
||||
/* Reduce the size of the buffer by the adjustment computed above
|
||||
from the offset and/or the index into the array. */
|
||||
if (bytes_avail < static_cast<unsigned HOST_WIDE_INT>(adjust))
|
||||
if (bytes_avail < adjust || adjust < 0)
|
||||
bytes_avail = 0;
|
||||
else
|
||||
bytes_avail -= adjust;
|
||||
{
|
||||
tree elttype = (TREE_CODE (opertype) == ARRAY_TYPE
|
||||
? TREE_TYPE (opertype) : opertype);
|
||||
if (tree eltsize = TYPE_SIZE_UNIT (elttype))
|
||||
{
|
||||
bytes_avail -= adjust * wi::to_offset (eltsize);
|
||||
if (bytes_avail < 0)
|
||||
bytes_avail = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* The minimum amount of space needed for the allocation. This
|
||||
is an optimistic estimate that makes it possible to detect
|
||||
placement new invocation for some undersize buffers but not
|
||||
others. */
|
||||
unsigned HOST_WIDE_INT bytes_need;
|
||||
offset_int bytes_need;
|
||||
|
||||
if (CONSTANT_CLASS_P (size))
|
||||
bytes_need = tree_to_uhwi (size);
|
||||
bytes_need = wi::to_offset (size);
|
||||
else if (nelts && CONSTANT_CLASS_P (nelts))
|
||||
bytes_need = tree_to_uhwi (nelts)
|
||||
* tree_to_uhwi (TYPE_SIZE_UNIT (type));
|
||||
bytes_need = (wi::to_offset (nelts)
|
||||
* wi::to_offset (TYPE_SIZE_UNIT (type)));
|
||||
else if (tree_fits_uhwi_p (TYPE_SIZE_UNIT (type)))
|
||||
bytes_need = tree_to_uhwi (TYPE_SIZE_UNIT (type));
|
||||
bytes_need = wi::to_offset (TYPE_SIZE_UNIT (type));
|
||||
else
|
||||
{
|
||||
/* The type is a VLA. */
|
||||
@ -2703,9 +2713,8 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
|
||||
: "placement new constructing an object of type "
|
||||
"%<%T [%wu]%> and size %qwu in a region of type %qT "
|
||||
"and size at most %qwu",
|
||||
type, tree_to_uhwi (nelts), bytes_need,
|
||||
TREE_TYPE (oper),
|
||||
bytes_avail);
|
||||
type, tree_to_uhwi (nelts), bytes_need.to_uhwi (),
|
||||
opertype, bytes_avail.to_uhwi ());
|
||||
else
|
||||
warning_at (loc, OPT_Wplacement_new_,
|
||||
exact_size ?
|
||||
@ -2715,8 +2724,8 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
|
||||
: "placement new constructing an array of objects "
|
||||
"of type %qT and size %qwu in a region of type %qT "
|
||||
"and size at most %qwu",
|
||||
type, bytes_need, TREE_TYPE (oper),
|
||||
bytes_avail);
|
||||
type, bytes_need.to_uhwi (), opertype,
|
||||
bytes_avail.to_uhwi ());
|
||||
else
|
||||
warning_at (loc, OPT_Wplacement_new_,
|
||||
exact_size ?
|
||||
@ -2725,8 +2734,8 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
|
||||
: "placement new constructing an object of type %qT "
|
||||
"and size %qwu in a region of type %qT and size "
|
||||
"at most %qwu",
|
||||
type, bytes_need, TREE_TYPE (oper),
|
||||
bytes_avail);
|
||||
type, bytes_need.to_uhwi (), opertype,
|
||||
bytes_avail.to_uhwi ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,8 @@
|
||||
2017-11-27 Martin Sebor <msebor@redhat.com>
|
||||
|
||||
PR c++/83058
|
||||
* g++.dg/warn/Wplacement-new-size-5.C: New test.
|
||||
|
||||
2017-11-27 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/81888
|
||||
|
241
gcc/testsuite/g++.dg/warn/Wplacement-new-size-5.C
Normal file
241
gcc/testsuite/g++.dg/warn/Wplacement-new-size-5.C
Normal file
@ -0,0 +1,241 @@
|
||||
// PR c++/83058 - ICE on C++ code with negative array index: in
|
||||
// warn_placement_new_too_small
|
||||
// { dg-do compile }
|
||||
// { dg-additional-options "-Wplacement-new -Wno-pedantic" }
|
||||
|
||||
#define SIZE_MAX __SIZE_MAX__
|
||||
#define DIFF_MAX __PTRDIFF_MAX__
|
||||
#define DIFF_MIN (-DIFF_MAX - 1)
|
||||
|
||||
void* operator new (__SIZE_TYPE__ n, void *p) { return p; }
|
||||
void* operator new[] (__SIZE_TYPE__ n, void *p) { return p; }
|
||||
|
||||
struct A { };
|
||||
|
||||
char carr[2];
|
||||
int iarr[2];
|
||||
|
||||
struct C0 { char i, carr[0]; };
|
||||
struct I0 { int i, iarr[0]; };
|
||||
struct CX { char i, carr[]; };
|
||||
struct IX { int i, iarr[]; };
|
||||
|
||||
void test_single (C0 *pc, CX *qc, I0 *pi, IX *qi, int n)
|
||||
{
|
||||
new (&carr[DIFF_MIN]) A (); // { dg-warning "placement new constructing an object of type .A. and size .1. in a region of type .char \\\[2]. and size .0." }
|
||||
new (&carr[-1]) A; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (carr -1 ) A; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&carr[0]) A;
|
||||
new (carr) A;
|
||||
new (&carr[1]) A;
|
||||
new (carr + 1) A;
|
||||
new (&carr[n]) A;
|
||||
new (carr + n) A;
|
||||
new (&carr[DIFF_MAX]) A; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (carr + DIFF_MAX) A; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&carr[SIZE_MAX]) A; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (carr + SIZE_MAX) A; // { dg-warning "\\\[-Wplacement-new" }
|
||||
|
||||
new (&pc->carr[DIFF_MIN]) A; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&pc->carr[-1]) A; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&pc->carr[0]) A;
|
||||
new (&pc->carr[9]) A;
|
||||
new (&pc->carr[n]) A;
|
||||
new (&pc->carr[DIFF_MAX]) A; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&pc->carr[SIZE_MAX]) A; // { dg-warning "\\\[-Wplacement-new" }
|
||||
|
||||
{
|
||||
/* The highest index at which a single A can be constructed. */
|
||||
enum { MAX = DIFF_MAX - sizeof *pc - sizeof (A) };
|
||||
new (&pc->carr[MAX]) A;
|
||||
new (&pc->carr[MAX + 1]) A; // { dg-warning "\\\[-Wplacement-new" }
|
||||
}
|
||||
|
||||
new (&qc->carr[DIFF_MIN]) A; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&qc->carr[-1]) A; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&qc->carr[0]) A;
|
||||
new (&qc->carr[9]) A;
|
||||
new (&qc->carr[n]) A;
|
||||
new (&qc->carr[DIFF_MAX]) A; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&qc->carr[SIZE_MAX]) A; // { dg-warning "\\\[-Wplacement-new" }
|
||||
|
||||
{
|
||||
/* The highest index at which a single A can be constructed. */
|
||||
enum { MAX = DIFF_MAX - sizeof *qc - sizeof (A) };
|
||||
new (&qc->carr[MAX]) A;
|
||||
new (&qc->carr[MAX + 1]) A; // { dg-warning "\\\[-Wplacement-new" }
|
||||
}
|
||||
|
||||
new (&pi->iarr[DIFF_MIN]) A; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&pi->iarr[-1]) A; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&pi->iarr[0]) A;
|
||||
new (&pi->iarr[9]) A;
|
||||
new (&pi->iarr[n]) A;
|
||||
new (&pi->iarr[DIFF_MAX]) A; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&pi->iarr[SIZE_MAX]) A; // { dg-warning "\\\[-Wplacement-new" }
|
||||
|
||||
{
|
||||
enum { MAX = (DIFF_MAX - sizeof *pi) / sizeof *pi->iarr };
|
||||
new (&pi->iarr[MAX]) A;
|
||||
new (&pi->iarr[MAX + 1]) A; // { dg-warning "\\\[-Wplacement-new" }
|
||||
}
|
||||
|
||||
new (&qi->iarr[DIFF_MIN]) A; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&qi->iarr[-1]) A; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&qi->iarr[0]) A;
|
||||
new (&qi->iarr[9]) A;
|
||||
new (&qi->iarr[n]) A;
|
||||
new (&qi->iarr[DIFF_MAX]) A; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&qi->iarr[SIZE_MAX]) A; // { dg-warning "\\\[-Wplacement-new" }
|
||||
|
||||
{
|
||||
enum { MAX = (DIFF_MAX - sizeof *qi) / sizeof *qi->iarr };
|
||||
new (&qi->iarr[MAX]) A;
|
||||
new (&qi->iarr[MAX + 1]) A; // { dg-warning "\\\[-Wplacement-new" }
|
||||
}
|
||||
|
||||
new (&iarr[DIFF_MIN]) A; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&iarr[-1]) A; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&iarr[1]) A;
|
||||
new (&iarr[n]) A;
|
||||
new (&iarr[DIFF_MAX]) A; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&iarr[SIZE_MAX]) A; // { dg-warning "\\\[-Wplacement-new" }
|
||||
}
|
||||
|
||||
void test_array_1 (C0 *pc, CX *qc, I0 *pi, IX *qi)
|
||||
{
|
||||
enum { N = 1 };
|
||||
|
||||
new (&carr[DIFF_MIN]) A[N]; // { dg-warning "placement new constructing an object of type .A \\\[\[0-9\]+]. and size .\[0-9\]+. in a region of type .char \\\[2]. and size .0." }
|
||||
new (&carr[-1]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&carr[DIFF_MAX]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&carr[SIZE_MAX]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
|
||||
new (&pc->carr[DIFF_MIN]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&pc->carr[-1]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&pc->carr[DIFF_MAX]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&pc->carr[SIZE_MAX]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
|
||||
{
|
||||
enum { MAX = DIFF_MAX - sizeof *pc - sizeof (A[N]) };
|
||||
new (&pc->carr[MAX]) A[N];
|
||||
new (&pc->carr[MAX + 1]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
}
|
||||
|
||||
new (&qc->carr[DIFF_MIN]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&qc->carr[-1]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&qc->carr[DIFF_MAX]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&qc->carr[SIZE_MAX]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
|
||||
{
|
||||
enum { MAX = DIFF_MAX - sizeof *qc - sizeof (A[N]) };
|
||||
new (&qc->carr[MAX]) A[N];
|
||||
new (&qc->carr[MAX + 1]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
}
|
||||
|
||||
new (&pi->iarr[DIFF_MIN]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&pi->iarr[-1]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&pi->iarr[DIFF_MAX]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&pi->iarr[SIZE_MAX]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
|
||||
{
|
||||
enum { MAX = (DIFF_MAX - sizeof *pi) / sizeof *pi->iarr };
|
||||
new (&pi->iarr[MAX]) A[N];
|
||||
new (&pi->iarr[MAX + 1]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
}
|
||||
|
||||
new (&qi->iarr[DIFF_MIN]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&qi->iarr[-1]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&qi->iarr[DIFF_MAX]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&qi->iarr[SIZE_MAX]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
|
||||
{
|
||||
enum { MAX = (DIFF_MAX - sizeof *qi) / sizeof *qi->iarr };
|
||||
new (&qi->iarr[MAX]) A[N];
|
||||
new (&qi->iarr[MAX + 1]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
}
|
||||
|
||||
new (&iarr[DIFF_MIN]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&iarr[-1]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&iarr[DIFF_MAX]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&iarr[SIZE_MAX]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
}
|
||||
|
||||
|
||||
void test_array_3 (C0 *pc, CX *qc, I0 *pi, IX *qi)
|
||||
{
|
||||
enum { N = 3 };
|
||||
|
||||
new (&carr[DIFF_MIN]) A[N]; // { dg-warning "placement new constructing an object of type .A \\\[\[0-9\]+]. and size .\[0-9\]+. in a region of type .char \\\[2]. and size .0." }
|
||||
new (&carr[-1]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&carr[DIFF_MAX]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&carr[SIZE_MAX]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
|
||||
new (&pc->carr[DIFF_MIN]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&pc->carr[-1]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&pc->carr[DIFF_MAX]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&pc->carr[SIZE_MAX]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
|
||||
{
|
||||
enum { MAX = DIFF_MAX - sizeof *pc - sizeof (A[N]) };
|
||||
new (&pc->carr[MAX]) A[N];
|
||||
new (&pc->carr[MAX + 1]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
}
|
||||
|
||||
new (&qc->carr[DIFF_MIN]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&qc->carr[-1]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&qc->carr[DIFF_MAX]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&qc->carr[SIZE_MAX]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
|
||||
{
|
||||
enum { MAX = DIFF_MAX - sizeof *qc - sizeof (A[N]) };
|
||||
new (&qc->carr[MAX]) A[N];
|
||||
new (&qc->carr[MAX + 1]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
}
|
||||
|
||||
new (&pi->iarr[DIFF_MIN]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&pi->iarr[-1]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&pi->iarr[DIFF_MAX]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&pi->iarr[SIZE_MAX]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
|
||||
{
|
||||
enum { MAX = (DIFF_MAX - sizeof *pi) / sizeof *pi->iarr };
|
||||
new (&pi->iarr[MAX]) A[N];
|
||||
new (&pi->iarr[MAX + 1]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
}
|
||||
|
||||
new (&qi->iarr[DIFF_MIN]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&qi->iarr[-1]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&qi->iarr[DIFF_MAX]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&qi->iarr[SIZE_MAX]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
|
||||
{
|
||||
enum { MAX = (DIFF_MAX - sizeof *qi) / sizeof *qi->iarr };
|
||||
new (&qi->iarr[MAX]) A[N];
|
||||
new (&qi->iarr[MAX + 1]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
}
|
||||
|
||||
new (&iarr[DIFF_MIN]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&iarr[-1]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&iarr[DIFF_MAX]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&iarr[SIZE_MAX]) A[N]; // { dg-warning "\\\[-Wplacement-new" }
|
||||
}
|
||||
|
||||
|
||||
void test_vla (unsigned n)
|
||||
{
|
||||
char cvla[n];
|
||||
|
||||
new (&cvla[DIFF_MIN]) A; // { dg-warning "placement new constructing an object of type .A. and size .1. in a region of type .char \\\[n]. and size .0." }
|
||||
new (&cvla[-1]) A; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (cvla -1) A; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&cvla[0]) A;
|
||||
new (&cvla[9]) A;
|
||||
new (&cvla[n - 1]) A;
|
||||
new (cvla + n - 1) A;
|
||||
new (&cvla[DIFF_MAX - 1]) A;
|
||||
new (&cvla[DIFF_MAX]) A; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (cvla + DIFF_MAX) A; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (&cvla[SIZE_MAX]) A; // { dg-warning "\\\[-Wplacement-new" }
|
||||
new (cvla + SIZE_MAX) A; // { dg-warning "\\\[-Wplacement-new" }
|
||||
}
|
Loading…
Reference in New Issue
Block a user