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
This commit is contained in:
Bernd Edlinger 2019-01-07 17:08:51 +00:00 committed by Bernd Edlinger
parent 18fd43b952
commit 08c35030c7
16 changed files with 211 additions and 71 deletions

View File

@ -1,3 +1,19 @@
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

View File

@ -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))

View File

@ -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)
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,
{ {
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,
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)
/* 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)
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,
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,
(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,
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,
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,
} }
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,
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,
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,
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,
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,
/* 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,
} }
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,
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,
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,
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;

View File

@ -1,3 +1,22 @@
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

View File

@ -0,0 +1,47 @@
/* PR c/5597 */
/* { dg-do compile } */
/* { dg-options "" } */
/* Verify that GCC forbids non-static initialization of
flexible array members. */
struct str { int len; char s[]; };
struct str a = { 2, "a" };
void foo()
{
static struct str b = { 2, "b" };
struct str c = { 2, "c" }; /* { 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 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) {};
}

View File

@ -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 {
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 {
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;

View File

@ -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);
} }

View File

@ -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" }
} }

View File

@ -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;
} }

View File

@ -0,0 +1,19 @@
/* { 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() {}
};

View File

@ -0,0 +1,23 @@
/* { 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;

View File

@ -0,0 +1,7 @@
/* { 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)" } */

View File

@ -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)
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" }

View File

@ -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)
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" }

View File

@ -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 ()
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 ()
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" }

View File

@ -1,18 +0,0 @@
/* PR c/5597 */
/* { dg-do compile } */
/* { dg-options "" } */
/* Verify that GCC forbids non-static initialization of
flexible array members. */
struct str { int len; char s[]; };
struct str a = { 2, "a" };
void foo()
{
static struct str b = { 2, "b" };
struct str c = { 2, "c" }; /* { 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)" } */
}