PR c++/69662 - -Wplacement-new on allocated one element array members
gcc/testsuite/ChangeLog: PR c++/69662 * g++.dg/warn/Wplacement-new-size-1.C: New test. * g++.dg/warn/Wplacement-new-size-2.C: New test. gcc/cp/ChangeLog: PR c++/69662 * init.c (find_field_init): New function. (warn_placement_new_too_small): Call it. Handle one-element arrays at ends of structures special. gcc/c-family/ChangeLog: PR c++/69662 * c.opt (Warning options): Update -Wplacement-new to take an optional argument. gcc/ChangeLog: PR c++/69662 * doc/invoke.texi: Update -Wplacement-new to take an optional argument. From-SVN: r233190
This commit is contained in:
parent
be2083eab7
commit
46cb933227
@ -1,3 +1,9 @@
|
||||
2016-02-05 Martin Sebor <msebor@redhat.com>
|
||||
|
||||
PR c++/69662
|
||||
* doc/invoke.texi: Update -Wplacement-new to take an optional
|
||||
argument.
|
||||
|
||||
2016-02-06 Richard Henderson <rth@redhat.com>
|
||||
|
||||
PR c/69643
|
||||
|
@ -1,3 +1,9 @@
|
||||
2016-02-05 Martin Sebor <msebor@redhat.com>
|
||||
|
||||
PR c++/69662
|
||||
* c.opt (Warning options): Update -Wplacement-new to take
|
||||
an optional argument.
|
||||
|
||||
2016-02-01 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR preprocessor/69543
|
||||
|
@ -777,7 +777,11 @@ ObjC ObjC++ Var(warn_protocol) Init(1) Warning
|
||||
Warn if inherited methods are unimplemented.
|
||||
|
||||
Wplacement-new
|
||||
C++ Var(warn_placement_new) Init(1) Warning
|
||||
C++ Warning Alias(Wplacement-new=, 1, 0)
|
||||
Warn for placement new expressions with undefined behavior.
|
||||
|
||||
Wplacement-new=
|
||||
C++ Joined RejectNegative UInteger Var(warn_placement_new) Init(-1) Warning
|
||||
Warn for placement new expressions with undefined behavior.
|
||||
|
||||
Wredundant-decls
|
||||
|
@ -1,3 +1,10 @@
|
||||
2016-02-05 Martin Sebor <msebor@redhat.com>
|
||||
|
||||
PR c++/69662
|
||||
* init.c (find_field_init): New function.
|
||||
(warn_placement_new_too_small): Call it. Handle one-element arrays
|
||||
at ends of structures special.
|
||||
|
||||
2016-02-05 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/68948
|
||||
|
@ -2285,6 +2285,33 @@ throw_bad_array_new_length (void)
|
||||
return build_cxx_call (fn, 0, NULL, tf_warning_or_error);
|
||||
}
|
||||
|
||||
/* Attempt to find the initializer for field T in the initializer INIT,
|
||||
when non-null. Returns the initializer when successful and NULL
|
||||
otherwise. */
|
||||
static tree
|
||||
find_field_init (tree t, tree init)
|
||||
{
|
||||
if (!init)
|
||||
return NULL_TREE;
|
||||
|
||||
unsigned HOST_WIDE_INT idx;
|
||||
tree field, elt;
|
||||
|
||||
/* Iterate over all top-level initializer elements. */
|
||||
FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (init), idx, field, elt)
|
||||
{
|
||||
/* If the member T is found, return it. */
|
||||
if (field == t)
|
||||
return elt;
|
||||
|
||||
/* Otherwise continue and/or recurse into nested initializers. */
|
||||
if (TREE_CODE (elt) == CONSTRUCTOR
|
||||
&& (init = find_field_init (t, elt)))
|
||||
return init;
|
||||
}
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Attempt to verify that the argument, OPER, of a placement new expression
|
||||
refers to an object sufficiently large for an object of TYPE or an array
|
||||
of NELTS of such objects when NELTS is non-null, and issue a warning when
|
||||
@ -2375,10 +2402,25 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
|
||||
oper = TREE_OPERAND (oper, 0);
|
||||
}
|
||||
|
||||
/* Refers to the declared object that constains the subobject referenced
|
||||
by OPER. When the object is initialized, makes it possible to determine
|
||||
the actual size of a flexible array member used as the buffer passed
|
||||
as OPER to placement new. */
|
||||
tree var_decl = NULL_TREE;
|
||||
/* True when operand is a COMPONENT_REF, to distinguish flexible array
|
||||
members from arrays of unspecified size. */
|
||||
bool compref = TREE_CODE (oper) == COMPONENT_REF;
|
||||
|
||||
/* Descend into a struct or union to find the member whose address
|
||||
is being used as the agument. */
|
||||
while (TREE_CODE (oper) == COMPONENT_REF)
|
||||
oper = TREE_OPERAND (oper, 1);
|
||||
{
|
||||
tree op0 = oper;
|
||||
while (TREE_CODE (op0 = TREE_OPERAND (op0, 0)) == COMPONENT_REF);
|
||||
if (TREE_CODE (op0) == VAR_DECL)
|
||||
var_decl = op0;
|
||||
oper = TREE_OPERAND (oper, 1);
|
||||
}
|
||||
|
||||
if ((addr_expr || !POINTER_TYPE_P (TREE_TYPE (oper)))
|
||||
&& (TREE_CODE (oper) == VAR_DECL
|
||||
@ -2387,7 +2429,7 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
|
||||
{
|
||||
/* A possibly optimistic estimate of the number of bytes available
|
||||
in the destination buffer. */
|
||||
unsigned HOST_WIDE_INT bytes_avail;
|
||||
unsigned HOST_WIDE_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;
|
||||
@ -2410,20 +2452,45 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
|
||||
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;
|
||||
}
|
||||
|
||||
/* Avoid diagnosing flexible array members (accepted as an extension
|
||||
and diagnosed with -Wpedantic).
|
||||
Constructing objects that appear to overflow the C99 equivalent of
|
||||
flexible array members (i.e., array members of size zero or one)
|
||||
are diagnosed in C++ since their declaration cannot be diagnosed. */
|
||||
if (bytes_avail == 0 && TREE_CODE (TREE_TYPE (oper)) == ARRAY_TYPE)
|
||||
return;
|
||||
tree_code oper_code = TREE_CODE (TREE_TYPE (oper));
|
||||
|
||||
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_cst = maybe_constant_value (nelts);
|
||||
if (TREE_CODE (nelts_cst) == INTEGER_CST
|
||||
&& integer_onep (nelts_cst)
|
||||
&& !var_decl
|
||||
&& warn_placement_new < 2)
|
||||
return;
|
||||
}
|
||||
|
||||
/* The size of the buffer can only be adjusted down but not up. */
|
||||
gcc_checking_assert (0 <= adjust);
|
||||
|
||||
@ -2452,7 +2519,7 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
|
||||
{
|
||||
if (nelts)
|
||||
if (CONSTANT_CLASS_P (nelts))
|
||||
warning_at (loc, OPT_Wplacement_new,
|
||||
warning_at (loc, OPT_Wplacement_new_,
|
||||
exact_size ?
|
||||
"placement new constructing an object of type "
|
||||
"%<%T [%wu]%> and size %qwu in a region of type %qT "
|
||||
@ -2464,7 +2531,7 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
|
||||
TREE_TYPE (oper),
|
||||
bytes_avail);
|
||||
else
|
||||
warning_at (loc, OPT_Wplacement_new,
|
||||
warning_at (loc, OPT_Wplacement_new_,
|
||||
exact_size ?
|
||||
"placement new constructing an array of objects "
|
||||
"of type %qT and size %qwu in a region of type %qT "
|
||||
@ -2475,7 +2542,7 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
|
||||
type, bytes_need, TREE_TYPE (oper),
|
||||
bytes_avail);
|
||||
else
|
||||
warning_at (loc, OPT_Wplacement_new,
|
||||
warning_at (loc, OPT_Wplacement_new_,
|
||||
exact_size ?
|
||||
"placement new constructing an object of type %qT "
|
||||
"and size %qwu in a region of type %qT and size %qwi"
|
||||
|
@ -281,7 +281,8 @@ Objective-C and Objective-C++ Dialects}.
|
||||
-Woverride-init-side-effects -Woverlength-strings @gol
|
||||
-Wpacked -Wpacked-bitfield-compat -Wpadded @gol
|
||||
-Wparentheses -Wno-pedantic-ms-format @gol
|
||||
-Wplacement-new -Wpointer-arith -Wno-pointer-to-int-cast @gol
|
||||
-Wplacement-new -Wplacement-new=@var{n} @gol
|
||||
-Wpointer-arith -Wno-pointer-to-int-cast @gol
|
||||
-Wno-pragmas -Wredundant-decls -Wno-return-local-addr @gol
|
||||
-Wreturn-type -Wsequence-point -Wshadow -Wno-shadow-ivar @gol
|
||||
-Wshift-overflow -Wshift-overflow=@var{n} @gol
|
||||
@ -4894,6 +4895,7 @@ width specifiers @code{I32}, @code{I64}, and @code{I} used on Windows targets,
|
||||
which depend on the MS runtime.
|
||||
|
||||
@item -Wplacement-new
|
||||
@itemx -Wplacement-new=@var{n}
|
||||
@opindex Wplacement-new
|
||||
@opindex Wno-placement-new
|
||||
Warn about placement new expressions with undefined behavior, such as
|
||||
@ -4906,7 +4908,36 @@ char buf [64];
|
||||
new (buf) int[64];
|
||||
@end smallexample
|
||||
This warning is enabled by default.
|
||||
|
||||
|
||||
@table @gcctabopt
|
||||
@item -Wplacement-new=1
|
||||
This is the default warning level of @option{-Wplacement-new}. At this
|
||||
level the warning is not issued for some strictly undefined constructs that
|
||||
GCC allows as extensions for compatibility with legacy code. For example,
|
||||
the following @code{new} expression is not diagnosed at this level even
|
||||
though it has undefined behavior according to the C++ standard because
|
||||
it writes past the end of the one-element array.
|
||||
@smallexample
|
||||
struct S @{ int n, a[1]; @};
|
||||
S *s = (S *)malloc (sizeof *s + 31 * sizeof s->a[0]);
|
||||
new (s->a)int [32]();
|
||||
@end smallexample
|
||||
|
||||
@item -Wplacement-new=2
|
||||
At this level, in addition to diagnosing all the same constructs as at level
|
||||
1, a diagnostic is also issued for placement new expressions that construct
|
||||
an object in the last member of structure whose type is an array of a single
|
||||
element and whose size is less than the size of the object being constructed.
|
||||
While the previous example would be diagnosed, the following construct makes
|
||||
use of the flexible member array extension to avoid the warning at level 2.
|
||||
@smallexample
|
||||
struct S @{ int n, a[]; @};
|
||||
S *s = (S *)malloc (sizeof *s + 32 * sizeof s->a[0]);
|
||||
new (s->a)int [32]();
|
||||
@end smallexample
|
||||
|
||||
@end table
|
||||
|
||||
@item -Wpointer-arith
|
||||
@opindex Wpointer-arith
|
||||
@opindex Wno-pointer-arith
|
||||
|
@ -1,3 +1,9 @@
|
||||
2016-02-05 Martin Sebor <msebor@redhat.com>
|
||||
|
||||
PR c++/69662
|
||||
* g++.dg/warn/Wplacement-new-size-1.C: New test.
|
||||
* g++.dg/warn/Wplacement-new-size-2.C: New test.
|
||||
|
||||
2016-02-06 Richard HEnderson <rth@redhat.com>
|
||||
|
||||
PR c/69643
|
||||
|
139
gcc/testsuite/g++.dg/warn/Wplacement-new-size-1.C
Normal file
139
gcc/testsuite/g++.dg/warn/Wplacement-new-size-1.C
Normal file
@ -0,0 +1,139 @@
|
||||
// PR c++/69662 - -Wplacement-new on allocated one element array members
|
||||
// Exercising the more permissive -Wplacement-new=1. The difference
|
||||
// between -Wplacement-new=1 is denoted by "no warning at level 1" in
|
||||
// the comments below.
|
||||
// { dg-do compile }
|
||||
// { dg-options "-Wno-pedantic -Wplacement-new=1" }
|
||||
|
||||
typedef __typeof__ (sizeof 0) size_t;
|
||||
|
||||
void* operator new (size_t, void *p) { return p; }
|
||||
void* operator new[] (size_t, void *p) { return p; }
|
||||
|
||||
struct Ax { char n, a []; };
|
||||
struct A0 { char n, a [0]; };
|
||||
struct A1 { char n, a [1]; };
|
||||
struct A2 { char n, a [2]; };
|
||||
|
||||
typedef __INT16_TYPE__ Int16;
|
||||
typedef __INT32_TYPE__ Int32;
|
||||
|
||||
void fAx (Ax *px, Ax &rx)
|
||||
{
|
||||
Ax ax;
|
||||
new (ax.a) Int32; // { dg-warning "placement" }
|
||||
new (px->a) Int32;
|
||||
new (rx.a) Int32;
|
||||
}
|
||||
|
||||
void fAx2 ()
|
||||
{
|
||||
Ax ax2 = { 1, { 2, 3 } };
|
||||
|
||||
new (ax2.a) Int16;
|
||||
new (ax2.a) Int32; // { dg-warning "placement" }
|
||||
}
|
||||
|
||||
void fA0 (A0 *p0, A0 &r0)
|
||||
{
|
||||
A0 a0;
|
||||
new (a0.a) Int32; // { dg-warning "placement" }
|
||||
new (p0->a) Int32;
|
||||
new (r0.a) Int32;
|
||||
}
|
||||
|
||||
void fA1 (A1 *p1, A1 &r1)
|
||||
{
|
||||
A1 a1;
|
||||
new (a1.a) Int32; // { dg-warning "placement" }
|
||||
new (p1->a) Int32; // no warning at level 1
|
||||
new (r1.a) Int32; // no warning at level 1
|
||||
}
|
||||
|
||||
void fA2 (A2 *p2, A2 &r2)
|
||||
{
|
||||
A2 a2;
|
||||
new (a2.a) Int32; // { dg-warning "placement" }
|
||||
new (p2->a) Int32; // { dg-warning "placement" }
|
||||
new (r2.a) Int32; // { dg-warning "placement" }
|
||||
}
|
||||
|
||||
struct BAx { int i; Ax ax; };
|
||||
struct BA0 { int i; A0 a0; };
|
||||
struct BA1 { int i; A1 a1; };
|
||||
struct BA2 { int i; A2 a2; };
|
||||
|
||||
void fBx (BAx *pbx, BAx &rbx)
|
||||
{
|
||||
BAx bax;
|
||||
new (bax.ax.a) char; // { dg-warning "placement" }
|
||||
new (bax.ax.a) Int16; // { dg-warning "placement" }
|
||||
new (bax.ax.a) Int32; // { dg-warning "placement" }
|
||||
|
||||
new (pbx->ax.a) char;
|
||||
new (rbx.ax.a) char;
|
||||
new (pbx->ax.a) Int16;
|
||||
new (rbx.ax.a) Int16;
|
||||
new (pbx->ax.a) Int32;
|
||||
new (rbx.ax.a) Int32;
|
||||
new (pbx->ax.a) int[1234];
|
||||
new (rbx.ax.a) int[5678];
|
||||
}
|
||||
|
||||
void fBx1 ()
|
||||
{
|
||||
BAx bax1 = { 1, /* Ax = */ { 2, /* a[] = */ { 3 } } };
|
||||
|
||||
new (bax1.ax.a) char;
|
||||
new (bax1.ax.a) char[2]; // { dg-warning "placement" }
|
||||
new (bax1.ax.a) Int16; // { dg-warning "placement" }
|
||||
new (bax1.ax.a) Int32; // { dg-warning "placement" }
|
||||
}
|
||||
|
||||
void fBx2 ()
|
||||
{
|
||||
BAx bax2 = { 1, /* Ax = */ { 2, /* a[] = */ { 3, 4 } } };
|
||||
|
||||
new (bax2.ax.a) char;
|
||||
new (bax2.ax.a) char[2];
|
||||
new (bax2.ax.a) char[3]; // { dg-warning "placement" }
|
||||
new (bax2.ax.a) Int16;
|
||||
new (bax2.ax.a) char[4]; // { dg-warning "placement" }
|
||||
new (bax2.ax.a) Int32; // { dg-warning "placement" }
|
||||
}
|
||||
|
||||
void fBx3 ()
|
||||
{
|
||||
BAx bax2 = { 1, /* Ax = */ { 3, /* a[] = */ { 4, 5, 6 } } };
|
||||
|
||||
new (bax2.ax.a) char;
|
||||
new (bax2.ax.a) char[2];
|
||||
new (bax2.ax.a) Int16;
|
||||
new (bax2.ax.a) char[3];
|
||||
new (bax2.ax.a) char[4]; // { dg-warning "placement" }
|
||||
new (bax2.ax.a) Int32; // { dg-warning "placement" }
|
||||
}
|
||||
|
||||
void fB0 (BA0 *pb0, BA0 &rb0)
|
||||
{
|
||||
BA0 ba0;
|
||||
new (ba0.a0.a) Int32; // { dg-warning "placement" }
|
||||
new (pb0->a0.a) Int32;
|
||||
new (rb0.a0.a) Int32;
|
||||
}
|
||||
|
||||
void fB1 (BA1 *pb1, BA1 &rb1)
|
||||
{
|
||||
BA1 ba1;
|
||||
new (ba1.a1.a) Int32; // { dg-warning "placement" }
|
||||
new (pb1->a1.a) Int32; // no warning at level 1
|
||||
new (rb1.a1.a) Int32; // no warning at level 1
|
||||
}
|
||||
|
||||
void fB2 (BA2 *pb2, BA2 &rb2)
|
||||
{
|
||||
BA2 ba2;
|
||||
new (ba2.a2.a) Int32; // { dg-warning "placement" }
|
||||
new (pb2->a2.a) Int32; // { dg-warning "placement" }
|
||||
new (rb2.a2.a) Int32; // { dg-warning "placement" }
|
||||
}
|
197
gcc/testsuite/g++.dg/warn/Wplacement-new-size-2.C
Normal file
197
gcc/testsuite/g++.dg/warn/Wplacement-new-size-2.C
Normal file
@ -0,0 +1,197 @@
|
||||
// PR c++/69662 - -Wplacement-new on allocated one element array members
|
||||
// Exercising -Wplacement-new=2.
|
||||
// { dg-do compile }
|
||||
// { dg-options "-Wno-pedantic -Wplacement-new=2" }
|
||||
|
||||
typedef __typeof__ (sizeof 0) size_t;
|
||||
|
||||
void* operator new (size_t, void *p) { return p; }
|
||||
void* operator new[] (size_t, void *p) { return p; }
|
||||
|
||||
struct Ax { char n, a []; };
|
||||
struct A0 { char n, a [0]; };
|
||||
struct A1 { char n, a [1]; };
|
||||
struct A2 { char n, a [2]; };
|
||||
|
||||
typedef __INT16_TYPE__ Int16;
|
||||
typedef __INT32_TYPE__ Int32;
|
||||
|
||||
void fAx (Ax *px, Ax &rx)
|
||||
{
|
||||
Ax ax;
|
||||
|
||||
new (ax.a) Int32; // { dg-warning "placement" }
|
||||
new (ax.a) Int32[1]; // { dg-warning "placement" }
|
||||
|
||||
new (px->a) Int32;
|
||||
new (px->a) Int32[1];
|
||||
|
||||
new (rx.a) Int32;
|
||||
new (rx.a) Int32[2];
|
||||
}
|
||||
|
||||
void fAx2 ()
|
||||
{
|
||||
// Initialization of non-static objects with flexible array members
|
||||
// isn't allowed in C and should perhaps be disallowed in C++ as
|
||||
// well to avoid c++/69696 - incorrect initialization of block-scope
|
||||
// flexible array members.
|
||||
Ax ax2 = { 1, { 2, 3 } };
|
||||
|
||||
new (ax2.a) Int16;
|
||||
new (ax2.a) Int16[1];
|
||||
new (ax2.a) Int16[2]; // { dg-warning "placement" }
|
||||
new (ax2.a) Int32; // { dg-warning "placement" }
|
||||
new (ax2.a) Int32[2]; // { dg-warning "placement" }
|
||||
}
|
||||
|
||||
void fAx3 ()
|
||||
{
|
||||
static Ax ax3 = { 1, { 2, 3, 4 } };
|
||||
|
||||
new (ax3.a) Int16;
|
||||
new (ax3.a) Int16[1];
|
||||
new (ax3.a) Int16[2]; // { dg-warning "placement" }
|
||||
new (ax3.a) Int32; // { dg-warning "placement" }
|
||||
new (ax3.a) Int32[1]; // { dg-warning "placement" }
|
||||
}
|
||||
|
||||
static Ax ax4 = { 1, { 2, 3, 4, 5 } };
|
||||
|
||||
void fAx4 ()
|
||||
{
|
||||
new (ax4.a) Int16;
|
||||
new (ax4.a) Int16[1];
|
||||
new (ax4.a) Int16[2];
|
||||
new (ax4.a) Int32;
|
||||
new (ax4.a) Int32[1];
|
||||
new (ax4.a) Int32[2]; // { dg-warning "placement" }
|
||||
}
|
||||
|
||||
void fA0 (A0 *p0, A0 &r0)
|
||||
{
|
||||
A0 a0;
|
||||
|
||||
new (a0.a) Int32; // { dg-warning "placement" }
|
||||
new (a0.a) Int32[1]; // { dg-warning "placement" }
|
||||
|
||||
new (p0->a) Int32;
|
||||
new (p0->a) Int32[1];
|
||||
new (p0->a) Int32[2];
|
||||
|
||||
new (r0.a) Int32;
|
||||
new (r0.a) Int32[1];
|
||||
new (r0.a) Int32[2];
|
||||
}
|
||||
|
||||
void fA1 (A1 *p1, A1 &r1)
|
||||
{
|
||||
A1 a1;
|
||||
|
||||
new (a1.a) Int32; // { dg-warning "placement" }
|
||||
new (a1.a) Int32[1]; // { dg-warning "placement" }
|
||||
|
||||
new (p1->a) Int32; // { dg-warning "placement" }
|
||||
new (p1->a) Int32[1]; // { dg-warning "placement" }
|
||||
new (p1->a) Int32[2]; // { dg-warning "placement" }
|
||||
|
||||
new (r1.a) Int32; // { dg-warning "placement" }
|
||||
new (r1.a) Int32[1]; // { dg-warning "placement" }
|
||||
new (r1.a) Int32[2]; // { dg-warning "placement" }
|
||||
}
|
||||
|
||||
void fA2 (A2 *p2, A2 &r2)
|
||||
{
|
||||
A2 a2;
|
||||
new (a2.a) Int32; // { dg-warning "placement" }
|
||||
new (a2.a) Int32[1]; // { dg-warning "placement" }
|
||||
new (a2.a) Int32[2]; // { dg-warning "placement" }
|
||||
|
||||
new (p2->a) Int32; // { dg-warning "placement" }
|
||||
new (p2->a) Int32[1]; // { dg-warning "placement" }
|
||||
new (p2->a) Int32[2]; // { dg-warning "placement" }
|
||||
|
||||
new (r2.a) Int32; // { dg-warning "placement" }
|
||||
new (r2.a) Int32[1]; // { dg-warning "placement" }
|
||||
new (r2.a) Int32[2]; // { dg-warning "placement" }
|
||||
}
|
||||
|
||||
struct BAx { int i; Ax ax; };
|
||||
struct BA0 { int i; A0 a0; };
|
||||
struct BA1 { int i; A1 a1; };
|
||||
struct BA2 { int i; A2 a2; };
|
||||
|
||||
void fBx (BAx *pbx, BAx &rbx)
|
||||
{
|
||||
BAx bax;
|
||||
new (bax.ax.a) char; // { dg-warning "placement" }
|
||||
new (bax.ax.a) Int16; // { dg-warning "placement" }
|
||||
new (bax.ax.a) Int32; // { dg-warning "placement" }
|
||||
|
||||
new (pbx->ax.a) char;
|
||||
new (rbx.ax.a) char;
|
||||
new (pbx->ax.a) Int16;
|
||||
new (rbx.ax.a) Int16;
|
||||
new (pbx->ax.a) Int32;
|
||||
new (rbx.ax.a) Int32;
|
||||
new (pbx->ax.a) int[1234];
|
||||
new (rbx.ax.a) int[5678];
|
||||
}
|
||||
|
||||
void fBx1 ()
|
||||
{
|
||||
BAx bax1 = { 1, /* Ax = */ { 2, /* a[] = */ { 3 } } };
|
||||
|
||||
new (bax1.ax.a) char;
|
||||
new (bax1.ax.a) char[2]; // { dg-warning "placement" }
|
||||
new (bax1.ax.a) Int16; // { dg-warning "placement" }
|
||||
new (bax1.ax.a) Int32; // { dg-warning "placement" }
|
||||
}
|
||||
|
||||
void fBx2 ()
|
||||
{
|
||||
BAx bax2 = { 1, /* Ax = */ { 2, /* a[] = */ { 3, 4 } } };
|
||||
|
||||
new (bax2.ax.a) char;
|
||||
new (bax2.ax.a) char[2];
|
||||
new (bax2.ax.a) char[3]; // { dg-warning "placement" }
|
||||
new (bax2.ax.a) Int16;
|
||||
new (bax2.ax.a) char[4]; // { dg-warning "placement" }
|
||||
new (bax2.ax.a) Int32; // { dg-warning "placement" }
|
||||
}
|
||||
|
||||
void fBx3 ()
|
||||
{
|
||||
BAx bax2 = { 1, /* Ax = */ { 3, /* a[] = */ { 4, 5, 6 } } };
|
||||
|
||||
new (bax2.ax.a) char;
|
||||
new (bax2.ax.a) char[2];
|
||||
new (bax2.ax.a) Int16;
|
||||
new (bax2.ax.a) char[3];
|
||||
new (bax2.ax.a) char[4]; // { dg-warning "placement" }
|
||||
new (bax2.ax.a) Int32; // { dg-warning "placement" }
|
||||
}
|
||||
|
||||
void fB0 (BA0 *pb0, BA0 &rb0)
|
||||
{
|
||||
BA0 ba0;
|
||||
new (ba0.a0.a) Int32; // { dg-warning "placement" }
|
||||
new (pb0->a0.a) Int32;
|
||||
new (rb0.a0.a) Int32;
|
||||
}
|
||||
|
||||
void fB1 (BA1 *pb1, BA1 &rb1)
|
||||
{
|
||||
BA1 ba1;
|
||||
new (ba1.a1.a) Int32; // { dg-warning "placement" }
|
||||
new (pb1->a1.a) Int32; // { dg-warning "placement" }
|
||||
new (rb1.a1.a) Int32; // { dg-warning "placement" }
|
||||
}
|
||||
|
||||
void fB2 (BA2 *pb2, BA2 &rb2)
|
||||
{
|
||||
BA2 ba2;
|
||||
new (ba2.a2.a) Int32; // { dg-warning "placement" }
|
||||
new (pb2->a2.a) Int32; // { dg-warning "placement" }
|
||||
new (rb2.a2.a) Int32; // { dg-warning "placement" }
|
||||
}
|
Loading…
Reference in New Issue
Block a user