diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6c501a8d0e2..21374244ba5 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2014-06-04 Paolo Carlini + + PR c++/43453 + * typeck.c (cp_build_modify_expr): Handle array of characters + initialized by a string literal. + * decl.c (check_initializer): Handle parenthesized string literal + as initializer. + * typeck2.c (store_init_value): Remove redundant check. + 2014-06-04 Jason Merrill PR c++/51253 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 8dc5f1fa9f4..3d4058c2d91 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -5758,6 +5758,13 @@ check_initializer (tree decl, tree init, int flags, vec **cleanups) check_narrowing (type, init); } } + else if (TREE_CODE (type) == ARRAY_TYPE + && TREE_CODE (init) == TREE_LIST + && char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type))) + && list_length (init) == 1 + && TREE_CODE (TREE_VALUE (init)) == STRING_CST) + /* We get here with code like `char s[] ("abc");' */ + init = TREE_VALUE (init); /* If DECL has an array type without a specific bound, deduce the array size from the initializer. */ diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index aa96fb49318..4a876f94888 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -7511,6 +7511,18 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs, return error_mark_node; } + /* C++11 8.5/17: "If the destination type is an array of characters, + an array of char16_t, an array of char32_t, or an array of wchar_t, + and the initializer is a string literal...". */ + else if (TREE_CODE (newrhs) == STRING_CST + && char_type_p (TREE_TYPE (TYPE_MAIN_VARIANT (lhstype))) + && modifycode == INIT_EXPR) + { + newrhs = digest_init (lhstype, newrhs, complain); + if (newrhs == error_mark_node) + return error_mark_node; + } + else if (!same_or_base_type_p (TYPE_MAIN_VARIANT (lhstype), TYPE_MAIN_VARIANT (TREE_TYPE (newrhs)))) { diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index 18bc25f766d..3ed5c1dd06b 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -785,16 +785,9 @@ store_init_value (tree decl, tree init, vec** cleanups, int flags) { gcc_assert (TREE_CODE (decl) != RESULT_DECL); - if (TREE_CODE (init) == TREE_LIST - && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE) - { - error ("cannot initialize arrays using this syntax"); - return NULL_TREE; - } - else - /* We get here with code like `int a (2);' */ - init = build_x_compound_expr_from_list (init, ELK_INIT, - tf_warning_or_error); + /* We get here with code like `int a (2);' */ + init = build_x_compound_expr_from_list (init, ELK_INIT, + tf_warning_or_error); } /* End of special C++ code. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e53501c7e78..c19c8d065ce 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-06-04 Paolo Carlini + + PR c++/43453 + * g++.dg/init/pr43453.C: New. + 2014-06-04 Marc Glisse PR tree-optimization/61385 diff --git a/gcc/testsuite/g++.dg/init/pr43453.C b/gcc/testsuite/g++.dg/init/pr43453.C new file mode 100644 index 00000000000..4c91282d425 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/pr43453.C @@ -0,0 +1,33 @@ +// PR c++/43453 + +struct A { + char x[4]; + A() : x("bug") { }; +}; + +char x [4] ("bug"); + +struct CA { + const char cx[4]; + CA() : cx("bug") { }; +}; + +const char cx [4] ("bug"); + +struct B { + char y[4]; + B() : y("bu") { }; +}; + +char y [4] ("bu"); + +struct C { + char z[4]; + C() : z("bugs") { }; // { dg-error "too long" } +}; + +char z [4] ("bugs"); // { dg-error "too long" } + +char k [] ("bug"); + +const char ck [] ("bug");