Commit 46cb9332 by Martin Sebor Committed by Martin Sebor

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
parent be2083ea
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> 2016-02-06 Richard Henderson <rth@redhat.com>
PR c/69643 PR c/69643
......
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> 2016-02-01 Jakub Jelinek <jakub@redhat.com>
PR preprocessor/69543 PR preprocessor/69543
......
...@@ -777,7 +777,11 @@ ObjC ObjC++ Var(warn_protocol) Init(1) Warning ...@@ -777,7 +777,11 @@ ObjC ObjC++ Var(warn_protocol) Init(1) Warning
Warn if inherited methods are unimplemented. Warn if inherited methods are unimplemented.
Wplacement-new 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. Warn for placement new expressions with undefined behavior.
Wredundant-decls Wredundant-decls
......
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> 2016-02-05 Jason Merrill <jason@redhat.com>
PR c++/68948 PR c++/68948
......
...@@ -2285,6 +2285,33 @@ throw_bad_array_new_length (void) ...@@ -2285,6 +2285,33 @@ throw_bad_array_new_length (void)
return build_cxx_call (fn, 0, NULL, tf_warning_or_error); 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 /* 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 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 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) ...@@ -2375,10 +2402,25 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
oper = TREE_OPERAND (oper, 0); 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 /* Descend into a struct or union to find the member whose address
is being used as the agument. */ is being used as the agument. */
while (TREE_CODE (oper) == COMPONENT_REF) 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))) if ((addr_expr || !POINTER_TYPE_P (TREE_TYPE (oper)))
&& (TREE_CODE (oper) == VAR_DECL && (TREE_CODE (oper) == VAR_DECL
...@@ -2387,7 +2429,7 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper) ...@@ -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 /* A possibly optimistic estimate of the number of bytes available
in the destination buffer. */ 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 /* True when the estimate above is in fact the exact size
of the destination buffer rather than an estimate. */ of the destination buffer rather than an estimate. */
bool exact_size = true; bool exact_size = true;
...@@ -2410,20 +2452,45 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper) ...@@ -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. */ as the optimistic estimate of the available space in it. */
bytes_avail = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (oper))); 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 else
{ {
/* Bail if neither the size of the object nor its type is known. */ /* Bail if neither the size of the object nor its type is known. */
return; return;
} }
/* Avoid diagnosing flexible array members (accepted as an extension tree_code oper_code = TREE_CODE (TREE_TYPE (oper));
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;
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. */ /* The size of the buffer can only be adjusted down but not up. */
gcc_checking_assert (0 <= adjust); gcc_checking_assert (0 <= adjust);
...@@ -2452,7 +2519,7 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper) ...@@ -2452,7 +2519,7 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
{ {
if (nelts) if (nelts)
if (CONSTANT_CLASS_P (nelts)) if (CONSTANT_CLASS_P (nelts))
warning_at (loc, OPT_Wplacement_new, warning_at (loc, OPT_Wplacement_new_,
exact_size ? exact_size ?
"placement new constructing an object of type " "placement new constructing an object of type "
"%<%T [%wu]%> and size %qwu in a region of type %qT " "%<%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) ...@@ -2464,7 +2531,7 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
TREE_TYPE (oper), TREE_TYPE (oper),
bytes_avail); bytes_avail);
else else
warning_at (loc, OPT_Wplacement_new, warning_at (loc, OPT_Wplacement_new_,
exact_size ? exact_size ?
"placement new constructing an array of objects " "placement new constructing an array of objects "
"of type %qT and size %qwu in a region of type %qT " "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) ...@@ -2475,7 +2542,7 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
type, bytes_need, TREE_TYPE (oper), type, bytes_need, TREE_TYPE (oper),
bytes_avail); bytes_avail);
else else
warning_at (loc, OPT_Wplacement_new, warning_at (loc, OPT_Wplacement_new_,
exact_size ? exact_size ?
"placement new constructing an object of type %qT " "placement new constructing an object of type %qT "
"and size %qwu in a region of type %qT and size %qwi" "and size %qwu in a region of type %qT and size %qwi"
......
...@@ -281,7 +281,8 @@ Objective-C and Objective-C++ Dialects}. ...@@ -281,7 +281,8 @@ Objective-C and Objective-C++ Dialects}.
-Woverride-init-side-effects -Woverlength-strings @gol -Woverride-init-side-effects -Woverlength-strings @gol
-Wpacked -Wpacked-bitfield-compat -Wpadded @gol -Wpacked -Wpacked-bitfield-compat -Wpadded @gol
-Wparentheses -Wno-pedantic-ms-format @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 -Wno-pragmas -Wredundant-decls -Wno-return-local-addr @gol
-Wreturn-type -Wsequence-point -Wshadow -Wno-shadow-ivar @gol -Wreturn-type -Wsequence-point -Wshadow -Wno-shadow-ivar @gol
-Wshift-overflow -Wshift-overflow=@var{n} @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, ...@@ -4894,6 +4895,7 @@ width specifiers @code{I32}, @code{I64}, and @code{I} used on Windows targets,
which depend on the MS runtime. which depend on the MS runtime.
@item -Wplacement-new @item -Wplacement-new
@itemx -Wplacement-new=@var{n}
@opindex Wplacement-new @opindex Wplacement-new
@opindex Wno-placement-new @opindex Wno-placement-new
Warn about placement new expressions with undefined behavior, such as Warn about placement new expressions with undefined behavior, such as
...@@ -4906,7 +4908,36 @@ char buf [64]; ...@@ -4906,7 +4908,36 @@ char buf [64];
new (buf) int[64]; new (buf) int[64];
@end smallexample @end smallexample
This warning is enabled by default. 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 @item -Wpointer-arith
@opindex Wpointer-arith @opindex Wpointer-arith
@opindex Wno-pointer-arith @opindex Wno-pointer-arith
......
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> 2016-02-06 Richard HEnderson <rth@redhat.com>
PR c/69643 PR c/69643
......
// 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" }
}
// 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" }
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment