Commit 08c35030 by Bernd Edlinger Committed by Bernd Edlinger

re PR c++/88261 (ICE: verify_gimple failed (error: non-trivial conversion at assignment))

        PR c++/88261
        PR c++/69338
        PR c++/69696
        PR c++/69697
        * cp-tree.h (LOOKUP_ALLOW_FLEXARRAY_INIT): New flag value.
        * typeck2.c (digest_init_r): Raise an error for non-static
        initialization of a flexible array member.
        (process_init_constructor, massage_init_elt,
        process_init_constructor_array, process_init_constructor_record,
        process_init_constructor_union, process_init_constructor): Add the
        flags parameter and pass it thru.
        (store_init_value): Pass LOOKUP_ALLOW_FLEXARRAY_INIT parameter to
        digest_init_flags for static decls.

gcc/testsuite:
2019-01-07  Bernd Edlinger  <bernd.edlinger@hotmail.de>

        PR c++/88261
        PR c++/69338
        PR c++/69696
        PR c++/69697
        * gcc.dg/array-6.c: Move from here ...
        * c-c++-common/array-6.c: ... to here and add some more test coverage.
        * g++.dg/pr69338.C: New test.
        * g++.dg/pr69697.C: Likewise.
        * g++.dg/ext/flexary32.C: Likewise.
        * g++.dg/ext/flexary3.C: Adjust test.
        * g++.dg/ext/flexary12.C: Likewise.
        * g++.dg/ext/flexary13.C: Likewise.
        * g++.dg/ext/flexary15.C: Likewise.
        * g++.dg/warn/Wplacement-new-size-1.C: Likewise.
        * g++.dg/warn/Wplacement-new-size-2.C: Likewise.
        * g++.dg/warn/Wplacement-new-size-6.C: Likewise.

From-SVN: r267653
parent 18fd43b9
2019-01-07 Bernd Edlinger <bernd.edlinger@hotmail.de>
PR c++/88261
PR c++/69338
PR c++/69696
PR c++/69697
* cp-tree.h (LOOKUP_ALLOW_FLEXARRAY_INIT): New flag value.
* typeck2.c (digest_init_r): Raise an error for non-static
initialization of a flexible array member.
(process_init_constructor, massage_init_elt,
process_init_constructor_array, process_init_constructor_record,
process_init_constructor_union, process_init_constructor): Add the
flags parameter and pass it thru.
(store_init_value): Pass LOOKUP_ALLOW_FLEXARRAY_INIT parameter to
digest_init_flags for static decls.
2019-01-07 Jakub Jelinek <jakub@redhat.com> 2019-01-07 Jakub Jelinek <jakub@redhat.com>
PR c++/85052 PR c++/85052
......
...@@ -5454,6 +5454,8 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, TYPENAME_FLAG }; ...@@ -5454,6 +5454,8 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, TYPENAME_FLAG };
#define LOOKUP_NO_NON_INTEGRAL (LOOKUP_NO_RVAL_BIND << 1) #define LOOKUP_NO_NON_INTEGRAL (LOOKUP_NO_RVAL_BIND << 1)
/* Used for delegating constructors in order to diagnose self-delegation. */ /* Used for delegating constructors in order to diagnose self-delegation. */
#define LOOKUP_DELEGATING_CONS (LOOKUP_NO_NON_INTEGRAL << 1) #define LOOKUP_DELEGATING_CONS (LOOKUP_NO_NON_INTEGRAL << 1)
/* Allow initialization of a flexible array members. */
#define LOOKUP_ALLOW_FLEXARRAY_INIT (LOOKUP_DELEGATING_CONS << 1)
#define LOOKUP_NAMESPACES_ONLY(F) \ #define LOOKUP_NAMESPACES_ONLY(F) \
(((F) & LOOKUP_PREFER_NAMESPACES) && !((F) & LOOKUP_PREFER_TYPES)) (((F) & LOOKUP_PREFER_NAMESPACES) && !((F) & LOOKUP_PREFER_TYPES))
......
...@@ -35,7 +35,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -35,7 +35,7 @@ along with GCC; see the file COPYING3. If not see
#include "gcc-rich-location.h" #include "gcc-rich-location.h"
static tree static tree
process_init_constructor (tree type, tree init, int nested, process_init_constructor (tree type, tree init, int nested, int flags,
tsubst_flags_t complain); tsubst_flags_t complain);
...@@ -817,8 +817,12 @@ store_init_value (tree decl, tree init, vec<tree, va_gc>** cleanups, int flags) ...@@ -817,8 +817,12 @@ store_init_value (tree decl, tree init, vec<tree, va_gc>** cleanups, int flags)
if (flags & LOOKUP_ALREADY_DIGESTED) if (flags & LOOKUP_ALREADY_DIGESTED)
value = init; value = init;
else else
/* Digest the specified initializer into an expression. */ {
value = digest_init_flags (type, init, flags, tf_warning_or_error); if (TREE_STATIC (decl))
flags |= LOOKUP_ALLOW_FLEXARRAY_INIT;
/* Digest the specified initializer into an expression. */
value = digest_init_flags (type, init, flags, tf_warning_or_error);
}
if (TREE_CODE (type) == ARRAY_TYPE if (TREE_CODE (type) == ARRAY_TYPE
&& TYPE_STRING_FLAG (TREE_TYPE (type)) && TYPE_STRING_FLAG (TREE_TYPE (type))
...@@ -1068,8 +1072,18 @@ digest_init_r (tree type, tree init, int nested, int flags, ...@@ -1068,8 +1072,18 @@ digest_init_r (tree type, tree init, int nested, int flags,
{ {
if (nested && !TYPE_DOMAIN (type)) if (nested && !TYPE_DOMAIN (type))
/* C++ flexible array members have a null domain. */ /* C++ flexible array members have a null domain. */
pedwarn (loc, OPT_Wpedantic, {
"initialization of a flexible array member"); if (flags & LOOKUP_ALLOW_FLEXARRAY_INIT)
pedwarn (loc, OPT_Wpedantic,
"initialization of a flexible array member");
else
{
if (complain & tf_error)
error_at (loc, "non-static initialization of"
" a flexible array member");
return error_mark_node;
}
}
tree typ1 = TYPE_MAIN_VARIANT (TREE_TYPE (type)); tree typ1 = TYPE_MAIN_VARIANT (TREE_TYPE (type));
if (char_type_p (typ1) if (char_type_p (typ1)
...@@ -1193,7 +1207,8 @@ digest_init_r (tree type, tree init, int nested, int flags, ...@@ -1193,7 +1207,8 @@ digest_init_r (tree type, tree init, int nested, int flags,
if (BRACE_ENCLOSED_INITIALIZER_P (stripped_init) if (BRACE_ENCLOSED_INITIALIZER_P (stripped_init)
&& !TYPE_NON_AGGREGATE_CLASS (type)) && !TYPE_NON_AGGREGATE_CLASS (type))
return process_init_constructor (type, stripped_init, nested, complain); return process_init_constructor (type, stripped_init, nested, flags,
complain);
else else
{ {
if (COMPOUND_LITERAL_P (stripped_init) && code == ARRAY_TYPE) if (COMPOUND_LITERAL_P (stripped_init) && code == ARRAY_TYPE)
...@@ -1291,9 +1306,12 @@ picflag_from_initializer (tree init) ...@@ -1291,9 +1306,12 @@ picflag_from_initializer (tree init)
/* Adjust INIT for going into a CONSTRUCTOR. */ /* Adjust INIT for going into a CONSTRUCTOR. */
static tree static tree
massage_init_elt (tree type, tree init, int nested, tsubst_flags_t complain) massage_init_elt (tree type, tree init, int nested, int flags,
tsubst_flags_t complain)
{ {
init = digest_init_r (type, init, nested ? 2 : 1, LOOKUP_IMPLICIT, complain); flags &= LOOKUP_ALLOW_FLEXARRAY_INIT;
flags |= LOOKUP_IMPLICIT;
init = digest_init_r (type, init, nested ? 2 : 1, flags, complain);
/* Strip a simple TARGET_EXPR when we know this is an initializer. */ /* Strip a simple TARGET_EXPR when we know this is an initializer. */
if (SIMPLE_TARGET_EXPR_P (init)) if (SIMPLE_TARGET_EXPR_P (init))
init = TARGET_EXPR_INITIAL (init); init = TARGET_EXPR_INITIAL (init);
...@@ -1311,11 +1329,11 @@ massage_init_elt (tree type, tree init, int nested, tsubst_flags_t complain) ...@@ -1311,11 +1329,11 @@ massage_init_elt (tree type, tree init, int nested, tsubst_flags_t complain)
which describe the initializers. */ which describe the initializers. */
static int static int
process_init_constructor_array (tree type, tree init, int nested, process_init_constructor_array (tree type, tree init, int nested, int flags,
tsubst_flags_t complain) tsubst_flags_t complain)
{ {
unsigned HOST_WIDE_INT i, len = 0; unsigned HOST_WIDE_INT i, len = 0;
int flags = 0; int picflags = 0;
bool unbounded = false; bool unbounded = false;
constructor_elt *ce; constructor_elt *ce;
vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (init); vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (init);
...@@ -1365,7 +1383,8 @@ process_init_constructor_array (tree type, tree init, int nested, ...@@ -1365,7 +1383,8 @@ process_init_constructor_array (tree type, tree init, int nested,
ce->index = error_mark_node; ce->index = error_mark_node;
gcc_assert (ce->value); gcc_assert (ce->value);
ce->value ce->value
= massage_init_elt (TREE_TYPE (type), ce->value, nested, complain); = massage_init_elt (TREE_TYPE (type), ce->value, nested, flags,
complain);
gcc_checking_assert gcc_checking_assert
(ce->value == error_mark_node (ce->value == error_mark_node
...@@ -1373,7 +1392,7 @@ process_init_constructor_array (tree type, tree init, int nested, ...@@ -1373,7 +1392,7 @@ process_init_constructor_array (tree type, tree init, int nested,
(strip_array_types (TREE_TYPE (type)), (strip_array_types (TREE_TYPE (type)),
strip_array_types (TREE_TYPE (ce->value))))); strip_array_types (TREE_TYPE (ce->value)))));
flags |= picflag_from_initializer (ce->value); picflags |= picflag_from_initializer (ce->value);
} }
/* No more initializers. If the array is unbounded, we are done. Otherwise, /* No more initializers. If the array is unbounded, we are done. Otherwise,
...@@ -1389,7 +1408,8 @@ process_init_constructor_array (tree type, tree init, int nested, ...@@ -1389,7 +1408,8 @@ process_init_constructor_array (tree type, tree init, int nested,
we can't rely on the back end to do it for us, so make the we can't rely on the back end to do it for us, so make the
initialization explicit by list-initializing from T{}. */ initialization explicit by list-initializing from T{}. */
next = build_constructor (init_list_type_node, NULL); next = build_constructor (init_list_type_node, NULL);
next = massage_init_elt (TREE_TYPE (type), next, nested, complain); next = massage_init_elt (TREE_TYPE (type), next, nested, flags,
complain);
if (initializer_zerop (next)) if (initializer_zerop (next))
/* The default zero-initialization is fine for us; don't /* The default zero-initialization is fine for us; don't
add anything to the CONSTRUCTOR. */ add anything to the CONSTRUCTOR. */
...@@ -1406,7 +1426,7 @@ process_init_constructor_array (tree type, tree init, int nested, ...@@ -1406,7 +1426,7 @@ process_init_constructor_array (tree type, tree init, int nested,
if (next) if (next)
{ {
flags |= picflag_from_initializer (next); picflags |= picflag_from_initializer (next);
if (len > i+1 if (len > i+1
&& (initializer_constant_valid_p (next, TREE_TYPE (next)) && (initializer_constant_valid_p (next, TREE_TYPE (next))
== null_pointer_node)) == null_pointer_node))
...@@ -1426,7 +1446,7 @@ process_init_constructor_array (tree type, tree init, int nested, ...@@ -1426,7 +1446,7 @@ process_init_constructor_array (tree type, tree init, int nested,
} }
CONSTRUCTOR_ELTS (init) = v; CONSTRUCTOR_ELTS (init) = v;
return flags; return picflags;
} }
/* Subroutine of process_init_constructor, which will process an initializer /* Subroutine of process_init_constructor, which will process an initializer
...@@ -1434,7 +1454,7 @@ process_init_constructor_array (tree type, tree init, int nested, ...@@ -1434,7 +1454,7 @@ process_init_constructor_array (tree type, tree init, int nested,
the initializers. */ the initializers. */
static int static int
process_init_constructor_record (tree type, tree init, int nested, process_init_constructor_record (tree type, tree init, int nested, int flags,
tsubst_flags_t complain) tsubst_flags_t complain)
{ {
vec<constructor_elt, va_gc> *v = NULL; vec<constructor_elt, va_gc> *v = NULL;
...@@ -1449,7 +1469,7 @@ process_init_constructor_record (tree type, tree init, int nested, ...@@ -1449,7 +1469,7 @@ process_init_constructor_record (tree type, tree init, int nested,
gcc_assert (!TYPE_POLYMORPHIC_P (type)); gcc_assert (!TYPE_POLYMORPHIC_P (type));
restart: restart:
int flags = 0; int picflags = 0;
unsigned HOST_WIDE_INT idx = 0; unsigned HOST_WIDE_INT idx = 0;
int designator_skip = -1; int designator_skip = -1;
/* Generally, we will always have an index for each initializer (which is /* Generally, we will always have an index for each initializer (which is
...@@ -1517,7 +1537,7 @@ process_init_constructor_record (tree type, tree init, int nested, ...@@ -1517,7 +1537,7 @@ process_init_constructor_record (tree type, tree init, int nested,
if (ce) if (ce)
{ {
gcc_assert (ce->value); gcc_assert (ce->value);
next = massage_init_elt (type, next, nested, complain); next = massage_init_elt (type, next, nested, flags, complain);
++idx; ++idx;
} }
} }
...@@ -1546,7 +1566,8 @@ process_init_constructor_record (tree type, tree init, int nested, ...@@ -1546,7 +1566,8 @@ process_init_constructor_record (tree type, tree init, int nested,
for us, so build up TARGET_EXPRs. If the type in question is for us, so build up TARGET_EXPRs. If the type in question is
a class, just build one up; if it's an array, recurse. */ a class, just build one up; if it's an array, recurse. */
next = build_constructor (init_list_type_node, NULL); next = build_constructor (init_list_type_node, NULL);
next = massage_init_elt (TREE_TYPE (field), next, nested, complain); next = massage_init_elt (TREE_TYPE (field), next, nested, flags,
complain);
/* Warn when some struct elements are implicitly initialized. */ /* Warn when some struct elements are implicitly initialized. */
if ((complain & tf_warning) if ((complain & tf_warning)
...@@ -1597,7 +1618,7 @@ process_init_constructor_record (tree type, tree init, int nested, ...@@ -1597,7 +1618,7 @@ process_init_constructor_record (tree type, tree init, int nested,
/* If this is a bitfield, now convert to the lowered type. */ /* If this is a bitfield, now convert to the lowered type. */
if (type != TREE_TYPE (field)) if (type != TREE_TYPE (field))
next = cp_convert_and_check (TREE_TYPE (field), next, complain); next = cp_convert_and_check (TREE_TYPE (field), next, complain);
flags |= picflag_from_initializer (next); picflags |= picflag_from_initializer (next);
CONSTRUCTOR_APPEND_ELT (v, field, next); CONSTRUCTOR_APPEND_ELT (v, field, next);
} }
...@@ -1653,7 +1674,7 @@ process_init_constructor_record (tree type, tree init, int nested, ...@@ -1653,7 +1674,7 @@ process_init_constructor_record (tree type, tree init, int nested,
} }
CONSTRUCTOR_ELTS (init) = v; CONSTRUCTOR_ELTS (init) = v;
return flags; return picflags;
} }
/* Subroutine of process_init_constructor, which will process a single /* Subroutine of process_init_constructor, which will process a single
...@@ -1661,7 +1682,7 @@ process_init_constructor_record (tree type, tree init, int nested, ...@@ -1661,7 +1682,7 @@ process_init_constructor_record (tree type, tree init, int nested,
which describe the initializer. */ which describe the initializer. */
static int static int
process_init_constructor_union (tree type, tree init, int nested, process_init_constructor_union (tree type, tree init, int nested, int flags,
tsubst_flags_t complain) tsubst_flags_t complain)
{ {
constructor_elt *ce; constructor_elt *ce;
...@@ -1749,7 +1770,7 @@ process_init_constructor_union (tree type, tree init, int nested, ...@@ -1749,7 +1770,7 @@ process_init_constructor_union (tree type, tree init, int nested,
if (ce->value && ce->value != error_mark_node) if (ce->value && ce->value != error_mark_node)
ce->value = massage_init_elt (TREE_TYPE (ce->index), ce->value, nested, ce->value = massage_init_elt (TREE_TYPE (ce->index), ce->value, nested,
complain); flags, complain);
return picflag_from_initializer (ce->value); return picflag_from_initializer (ce->value);
} }
...@@ -1769,40 +1790,43 @@ process_init_constructor_union (tree type, tree init, int nested, ...@@ -1769,40 +1790,43 @@ process_init_constructor_union (tree type, tree init, int nested,
of error. */ of error. */
static tree static tree
process_init_constructor (tree type, tree init, int nested, process_init_constructor (tree type, tree init, int nested, int flags,
tsubst_flags_t complain) tsubst_flags_t complain)
{ {
int flags; int picflags;
gcc_assert (BRACE_ENCLOSED_INITIALIZER_P (init)); gcc_assert (BRACE_ENCLOSED_INITIALIZER_P (init));
if (TREE_CODE (type) == ARRAY_TYPE || VECTOR_TYPE_P (type)) if (TREE_CODE (type) == ARRAY_TYPE || VECTOR_TYPE_P (type))
flags = process_init_constructor_array (type, init, nested, complain); picflags = process_init_constructor_array (type, init, nested, flags,
complain);
else if (TREE_CODE (type) == RECORD_TYPE) else if (TREE_CODE (type) == RECORD_TYPE)
flags = process_init_constructor_record (type, init, nested, complain); picflags = process_init_constructor_record (type, init, nested, flags,
complain);
else if (TREE_CODE (type) == UNION_TYPE) else if (TREE_CODE (type) == UNION_TYPE)
flags = process_init_constructor_union (type, init, nested, complain); picflags = process_init_constructor_union (type, init, nested, flags,
complain);
else else
gcc_unreachable (); gcc_unreachable ();
if (flags & PICFLAG_ERRONEOUS) if (picflags & PICFLAG_ERRONEOUS)
return error_mark_node; return error_mark_node;
TREE_TYPE (init) = type; TREE_TYPE (init) = type;
if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type) == NULL_TREE) if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type) == NULL_TREE)
cp_complete_array_type (&TREE_TYPE (init), init, /*do_default=*/0); cp_complete_array_type (&TREE_TYPE (init), init, /*do_default=*/0);
if (flags & PICFLAG_SIDE_EFFECTS) if (picflags & PICFLAG_SIDE_EFFECTS)
{ {
TREE_CONSTANT (init) = false; TREE_CONSTANT (init) = false;
TREE_SIDE_EFFECTS (init) = true; TREE_SIDE_EFFECTS (init) = true;
} }
else if (flags & PICFLAG_NOT_ALL_CONSTANT) else if (picflags & PICFLAG_NOT_ALL_CONSTANT)
/* Make sure TREE_CONSTANT isn't set from build_constructor. */ /* Make sure TREE_CONSTANT isn't set from build_constructor. */
TREE_CONSTANT (init) = false; TREE_CONSTANT (init) = false;
else else
{ {
TREE_CONSTANT (init) = 1; TREE_CONSTANT (init) = 1;
if (!(flags & PICFLAG_NOT_ALL_SIMPLE)) if (!(picflags & PICFLAG_NOT_ALL_SIMPLE))
TREE_STATIC (init) = 1; TREE_STATIC (init) = 1;
} }
return init; return init;
......
2019-01-07 Bernd Edlinger <bernd.edlinger@hotmail.de>
PR c++/88261
PR c++/69338
PR c++/69696
PR c++/69697
* gcc.dg/array-6.c: Move from here ...
* c-c++-common/array-6.c: ... to here and add some more test coverage.
* g++.dg/pr69338.C: New test.
* g++.dg/pr69697.C: Likewise.
* g++.dg/ext/flexary32.C: Likewise.
* g++.dg/ext/flexary3.C: Adjust test.
* g++.dg/ext/flexary12.C: Likewise.
* g++.dg/ext/flexary13.C: Likewise.
* g++.dg/ext/flexary15.C: Likewise.
* g++.dg/warn/Wplacement-new-size-1.C: Likewise.
* g++.dg/warn/Wplacement-new-size-2.C: Likewise.
* g++.dg/warn/Wplacement-new-size-6.C: Likewise.
2019-01-07 Richard Earnshaw <rearnsha@arm.com> 2019-01-07 Richard Earnshaw <rearnsha@arm.com>
* gcc.target/aarch64/subs_compare_2.c: Make '#' immediate prefix * gcc.target/aarch64/subs_compare_2.c: Make '#' immediate prefix
......
...@@ -16,3 +16,32 @@ void foo() ...@@ -16,3 +16,32 @@ void foo()
struct str d = (struct str) { 2, "d" }; /* { dg-error "(non-static)|(near initialization)" } */ struct str d = (struct str) { 2, "d" }; /* { dg-error "(non-static)|(near initialization)" } */
struct str e = (struct str) { d.len, "e" }; /* { dg-error "(non-static)|(initialization)" } */ struct str e = (struct str) { d.len, "e" }; /* { dg-error "(non-static)|(initialization)" } */
} }
struct str f = { 0, {} };
void bar()
{
static struct str g = { 0, {} };
struct str h = { 0, {} }; /* { dg-error "(non-static)|(near initialization)" } */
struct str i = (struct str) { 0, {} }; /* { dg-error "(non-static)|(near initialization)" } */
struct str j = (struct str) { i.len, {} }; /* { dg-error "(non-static)|(initialization)" } */
}
struct str k = { 0 };
void baz()
{
static struct str l = { 0 };
struct str m = { 0 };
struct str n = (struct str) { 0 };
struct str o = (struct str) { n.len };
}
struct str p = {};
void qux()
{
static struct str q = {};
struct str r = {};
struct str s = (struct str) {};
}
...@@ -12,7 +12,7 @@ struct A { ...@@ -12,7 +12,7 @@ struct A {
void f1 () void f1 ()
{ {
// This is the meat of the test from c++/69290: // This is the meat of the test from c++/69290:
struct A a static struct A a
= { "c" }; // { dg-error "invalid conversion from .const char\\*. to .int." } = { "c" }; // { dg-error "invalid conversion from .const char\\*. to .int." }
(void)&a; (void)&a;
...@@ -27,13 +27,13 @@ struct B { ...@@ -27,13 +27,13 @@ struct B {
void f2 () void f2 ()
{ {
struct B b1 static struct B b1
= { 0, "c" }; // { dg-error "invalid conversion from .const char\\*. to .int." } = { 0, "c" }; // { dg-error "invalid conversion from .const char\\*. to .int." }
(void)&b1; (void)&b1;
const char s[] = "c"; const char s[] = "c";
struct B b2 static struct B b2
= { 0, s }; // { dg-error "invalid conversion from .const char\\*. to .int." } = { 0, s }; // { dg-error "invalid conversion from .const char\\*. to .int." }
(void)&b2; (void)&b2;
...@@ -57,7 +57,7 @@ struct C { ...@@ -57,7 +57,7 @@ struct C {
void f3 () void f3 ()
{ {
struct C<double> cd static struct C<double> cd
= { "c" }; // { dg-error "cannot convert .const char\\*. to .double." } = { "c" }; // { dg-error "cannot convert .const char\\*. to .double." }
(void)&cd; (void)&cd;
......
...@@ -19,33 +19,33 @@ int main () ...@@ -19,33 +19,33 @@ int main ()
ASSERT (s.n == 0); ASSERT (s.n == 0);
} }
{ {
Ax s = static Ax s =
{ 0, { } }; // dg-warning "initialization of a flexible array member" } { 0, { } }; // dg-warning "initialization of a flexible array member" }
ASSERT (s.n == 0); ASSERT (s.n == 0);
} }
{ {
Ax s = static Ax s =
{ 1, { 2 } }; // dg-warning "initialization of a flexible array member" } { 1, { 2 } }; // dg-warning "initialization of a flexible array member" }
ASSERT (s.n == 1 && s.a [0] == 2); ASSERT (s.n == 1 && s.a [0] == 2);
} }
{ {
Ax s = static Ax s =
{ 2, { 3, 4 } }; // dg-warning "initialization of a flexible array member" } { 2, { 3, 4 } }; // dg-warning "initialization of a flexible array member" }
ASSERT (s.n = 2 && s.a [0] == 3 && s.a [1] == 4); ASSERT (s.n = 2 && s.a [0] == 3 && s.a [1] == 4);
} }
{ {
Ax s = static Ax s =
{ 123, i }; // dg-warning "initialization of a flexible array member" } { 123, i }; // dg-warning "initialization of a flexible array member" }
ASSERT (s.n == 123 && s.a [0] == i); ASSERT (s.n == 123 && s.a [0] == i);
} }
{ {
Ax s = static Ax s =
{ 456, { i } }; // dg-warning "initialization of a flexible array member" } { 456, { i } }; // dg-warning "initialization of a flexible array member" }
ASSERT (s.n == 456 && s.a [0] == i); ASSERT (s.n == 456 && s.a [0] == i);
} }
{ {
int j = i + 1, k = j + 1; int j = i + 1, k = j + 1;
Ax s = static Ax s =
{ 3, { i, j, k } }; // dg-warning "initialization of a flexible array member" } { 3, { i, j, k } }; // dg-warning "initialization of a flexible array member" }
ASSERT (s.n == 3 && s.a [0] == i && s.a [1] == j && s.a [2] == k); ASSERT (s.n == 3 && s.a [0] == i && s.a [1] == j && s.a [2] == k);
} }
......
...@@ -10,5 +10,5 @@ struct S { ...@@ -10,5 +10,5 @@ struct S {
void foo (const char *a) void foo (const char *a)
{ {
const S s = { 1, { a, "b" } }; // { dg-warning "invalid conversion" } static const S s = { 1, { a, "b" } }; // { dg-warning "invalid conversion" }
} }
...@@ -17,5 +17,6 @@ struct s { ...@@ -17,5 +17,6 @@ struct s {
int main() int main()
{ {
struct s s = { .c = 0 }; // { dg-error "initializer" } struct s s = { .c = 0 }; // { dg-error "initializer" }
// { dg-error "non-static initialization of a flexible array member" "" { target *-*-* } .-1 }
return 0; return 0;
} }
/* { dg-do compile { target c++11 } } */
/* { dg-options -Wno-pedantic } */
struct str { int len; char s[]; };
struct foo {
str x = {3, {1,2,3}}; /* { dg-error "(non-static)|(initialization)" } */
foo() {}
};
struct bar {
static constexpr str x = {3, {1,2,3}};
bar() {}
};
struct baz {
str x = {3};
baz() {}
};
/* { dg-do compile { target c++11 } } */
/* { dg-additional-options "-Wno-pedantic" } */
struct A { char i, a[]; };
void foo()
{
struct A a0 = { 3, "AB" }; /* { dg-error "(non-static)|(initialization)" } */
}
struct A a1 = { 3, "AB" }; /* { dg-bogus "(non-static)|(initialization)" } */
struct A a2 = (struct A){ 3, "AB" }; /* { dg-error "(non-static)|(initialization)" } */
struct B1 {
A a3;
B1 (): a3 { 3, "AB" } { } /* { dg-error "(non-static)|(initialization)" } */
} b1;
struct B2 {
A a4;
B2 (): a4 ((struct A){ 3, "AB" }) { } /* { dg-error "(non-static)|(initialization)" } */
} b2;
/* { dg-do compile { target c++11 } } */
/* { dg-additional-options "-Wno-pedantic" } */
int i;
struct A { int n, a[]; }
a = i ? A({ 1, { 2 } }) /* { dg-error "(non-static)|(initialization)" } */
: A({ 2, { 3, 4 } }); /* { dg-error "(non-static)|(initialization)" } */
...@@ -28,7 +28,7 @@ void fAx (Ax *px, Ax &rx) ...@@ -28,7 +28,7 @@ void fAx (Ax *px, Ax &rx)
void fAx2 () void fAx2 ()
{ {
Ax ax2 = { 1, { 2, 3 } }; static Ax ax2 = { 1, { 2, 3 } };
new (ax2.a) Int16; new (ax2.a) Int16;
new (ax2.a) Int32; // { dg-warning "placement" } new (ax2.a) Int32; // { dg-warning "placement" }
...@@ -82,7 +82,7 @@ void fBx (BAx *pbx, BAx &rbx) ...@@ -82,7 +82,7 @@ void fBx (BAx *pbx, BAx &rbx)
void fBx1 () void fBx1 ()
{ {
BAx bax1 = { 1, /* Ax = */ { 2, /* a[] = */ {} } }; static BAx bax1 = { 1, /* Ax = */ { 2, /* a[] = */ {} } };
new (bax1.ax.a) char; // { dg-warning "placement" } new (bax1.ax.a) char; // { dg-warning "placement" }
new (bax1.ax.a) char[2]; // { dg-warning "placement" } new (bax1.ax.a) char[2]; // { dg-warning "placement" }
......
...@@ -33,13 +33,13 @@ void fAx (Ax *px, Ax &rx) ...@@ -33,13 +33,13 @@ void fAx (Ax *px, Ax &rx)
void fAx2 () void fAx2 ()
{ {
// Initialization of non-static objects with flexible array members // Initialization of non-static objects with flexible array members
// isn't allowed in C and should perhaps be disallowed in C++ as // isn't allowed in C and had to be be disallowed in C++ as
// well to avoid c++/69696 - incorrect initialization of block-scope // well to avoid c++/69696 - incorrect initialization of block-scope
// flexible array members. // flexible array members.
Ax ax2 = { 1, { 2, 3 } }; Ax ax2 = { 1, { 2, 3 } }; // { dg-error "non-static initialization of a flexible array member" }
new (ax2.a) Int16; new (ax2.a) Int16; // { dg-warning "placement" }
new (ax2.a) Int16[1]; new (ax2.a) Int16[1]; // { dg-warning "placement" }
new (ax2.a) Int16[2]; // { dg-warning "placement" } new (ax2.a) Int16[2]; // { dg-warning "placement" }
new (ax2.a) Int32; // { dg-warning "placement" } new (ax2.a) Int32; // { dg-warning "placement" }
new (ax2.a) Int32[2]; // { dg-warning "placement" } new (ax2.a) Int32[2]; // { dg-warning "placement" }
...@@ -140,7 +140,7 @@ void fBx (BAx *pbx, BAx &rbx) ...@@ -140,7 +140,7 @@ void fBx (BAx *pbx, BAx &rbx)
void fBx1 () void fBx1 ()
{ {
BAx bax1 = { 1, /* Ax = */ { 2, /* a[] = */ {} } }; static BAx bax1 = { 1, /* Ax = */ { 2, /* a[] = */ {} } };
new (bax1.ax.a) char; // { dg-warning "placement" } new (bax1.ax.a) char; // { dg-warning "placement" }
new (bax1.ax.a) char[2]; // { dg-warning "placement" } new (bax1.ax.a) char[2]; // { dg-warning "placement" }
......
...@@ -15,7 +15,7 @@ struct BAx { int i; Ax ax; }; ...@@ -15,7 +15,7 @@ struct BAx { int i; Ax ax; };
void fBx1 () void fBx1 ()
{ {
BAx bax1 = { 1, /* Ax = */ { 2, /* a[] = */ { 3 } } }; // { dg-error "initialization of flexible array member in a nested context" } static BAx bax1 = { 1, /* Ax = */ { 2, /* a[] = */ { 3 } } }; // { dg-error "initialization of flexible array member in a nested context" }
new (bax1.ax.a) char; // { dg-warning "placement" } new (bax1.ax.a) char; // { dg-warning "placement" }
new (bax1.ax.a) char[2]; // { dg-warning "placement" } new (bax1.ax.a) char[2]; // { dg-warning "placement" }
...@@ -25,7 +25,7 @@ void fBx1 () ...@@ -25,7 +25,7 @@ void fBx1 ()
void fBx2 () void fBx2 ()
{ {
BAx bax2 = { 1, /* Ax = */ { 2, /* a[] = */ { 3, 4 } } }; // { dg-error "initialization of flexible array member in a nested context" } static BAx bax2 = { 1, /* Ax = */ { 2, /* a[] = */ { 3, 4 } } }; // { dg-error "initialization of flexible array member in a nested context" }
new (bax2.ax.a) char; // { dg-warning "placement" } new (bax2.ax.a) char; // { dg-warning "placement" }
new (bax2.ax.a) char[2]; // { dg-warning "placement" } new (bax2.ax.a) char[2]; // { dg-warning "placement" }
...@@ -37,7 +37,7 @@ void fBx2 () ...@@ -37,7 +37,7 @@ void fBx2 ()
void fBx3 () void fBx3 ()
{ {
BAx bax2 = { 1, /* Ax = */ { 3, /* a[] = */ { 4, 5, 6 } } }; // { dg-error "initialization of flexible array member in a nested context" } static BAx bax2 = { 1, /* Ax = */ { 3, /* a[] = */ { 4, 5, 6 } } }; // { dg-error "initialization of flexible array member in a nested context" }
new (bax2.ax.a) char; // { dg-warning "placement" } new (bax2.ax.a) char; // { dg-warning "placement" }
new (bax2.ax.a) char[2]; // { dg-warning "placement" } new (bax2.ax.a) char[2]; // { 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