diff options
author | Jason Merrill <jason@redhat.com> | 2017-05-09 09:48:58 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2017-05-09 09:48:58 -0400 |
commit | 6064858051d6e07bb89f3384c0d828f07c576c7a (patch) | |
tree | 815f68ce3b1ebd2059c5d426b0319427a127795a /gcc | |
parent | 6c38fbc648dc7bfa73ef703d1584196f64dcc151 (diff) | |
download | gcc-6064858051d6e07bb89f3384c0d828f07c576c7a.zip gcc-6064858051d6e07bb89f3384c0d828f07c576c7a.tar.gz gcc-6064858051d6e07bb89f3384c0d828f07c576c7a.tar.bz2 |
PR c++/70167 - array prvalue treated as lvalue
* cp-tree.h (CONSTRUCTOR_C99_COMPOUND_LITERAL): New.
(enum fcl_t): New.
* semantics.c (finish_compound_literal): Add fcl_context parameter.
Only make a static variable for C99 syntax.
* parser.c (cp_parser_postfix_expression): Pass it.
* pt.c (tsubst_copy_and_build): Likewise.
* call.c (extend_ref_init_temps): Set
DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P.
From-SVN: r247793
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/cp/call.c | 3 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 11 | ||||
-rw-r--r-- | gcc/cp/parser.c | 4 | ||||
-rw-r--r-- | gcc/cp/pt.c | 7 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 21 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/initlist-array6.C | 11 |
7 files changed, 60 insertions, 9 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c4b850f..a5990e2 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,15 @@ +2017-05-09 Jason Merrill <jason@redhat.com> + + PR c++/70167 - array prvalue treated as lvalue + * cp-tree.h (CONSTRUCTOR_C99_COMPOUND_LITERAL): New. + (enum fcl_t): New. + * semantics.c (finish_compound_literal): Add fcl_context parameter. + Only make a static variable for C99 syntax. + * parser.c (cp_parser_postfix_expression): Pass it. + * pt.c (tsubst_copy_and_build): Likewise. + * call.c (extend_ref_init_temps): Set + DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P. + 2017-05-09 Nathan Sidwell <nathan@acm.org> * cp-lang.c (get_global_decls, cxx_pushdecl): New. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index d9accd1..dee236e 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -10516,6 +10516,9 @@ extend_ref_init_temps (tree decl, tree init, vec<tree, va_gc> **cleanups) FOR_EACH_VEC_SAFE_ELT (elts, i, p) p->value = extend_ref_init_temps (decl, p->value, cleanups); } + recompute_constructor_flags (ctor); + if (decl_maybe_constant_var_p (decl) && TREE_CONSTANT (ctor)) + DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = true; } } diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index b64fa6d..100f85c 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -369,6 +369,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX]; DECL_NON_TRIVIALLY_INITIALIZED_P (in VAR_DECL) CALL_EXPR_ORDERED_ARGS (in CALL_EXPR, AGGR_INIT_EXPR) DECLTYPE_FOR_REF_CAPTURE (in DECLTYPE_TYPE) + CONSTUCTOR_C99_COMPOUND_LITERAL (in CONSTRUCTOR) 4: TREE_HAS_CONSTRUCTOR (in INDIRECT_REF, SAVE_EXPR, CONSTRUCTOR, CALL_EXPR, or FIELD_DECL). IDENTIFIER_TYPENAME_P (in IDENTIFIER_NODE) @@ -3898,6 +3899,11 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter) #define CONSTRUCTOR_MUTABLE_POISON(NODE) \ (TREE_LANG_FLAG_2 (CONSTRUCTOR_CHECK (NODE))) +/* True if this typed CONSTRUCTOR represents C99 compound-literal syntax rather + than C++11 functional cast syntax. */ +#define CONSTRUCTOR_C99_COMPOUND_LITERAL(NODE) \ + (TREE_LANG_FLAG_3 (CONSTRUCTOR_CHECK (NODE))) + #define DIRECT_LIST_INIT_P(NODE) \ (BRACE_ENCLOSED_INITIALIZER_P (NODE) && CONSTRUCTOR_IS_DIRECT_INIT (NODE)) @@ -6483,7 +6489,10 @@ extern tree finish_this_expr (void); extern tree finish_pseudo_destructor_expr (tree, tree, tree, location_t); extern cp_expr finish_unary_op_expr (location_t, enum tree_code, cp_expr, tsubst_flags_t); -extern tree finish_compound_literal (tree, tree, tsubst_flags_t); +/* Whether this call to finish_compound_literal represents a C++11 functional + cast or a C99 compound literal. */ +enum fcl_t { fcl_functional, fcl_c99 }; +extern tree finish_compound_literal (tree, tree, tsubst_flags_t, fcl_t = fcl_functional); extern tree finish_fname (tree); extern void finish_translation_unit (void); extern tree finish_template_type_parm (tree, tree); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index ab56f12..1951452 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -6770,7 +6770,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, /* Form the representation of the compound-literal. */ postfix_expression = finish_compound_literal (type, initializer, - tf_warning_or_error); + tf_warning_or_error, fcl_c99); postfix_expression.set_location (initializer.get_location ()); break; } @@ -26834,7 +26834,7 @@ cp_parser_functional_cast (cp_parser* parser, tree type) type = TREE_TYPE (type); cast = finish_compound_literal (type, expression_list, - tf_warning_or_error); + tf_warning_or_error, fcl_functional); /* Create a location of the form: type_name{i, f} ^~~~~~~~~~~~~~~ diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index b42b1fc..a4a0d83 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -17709,7 +17709,12 @@ tsubst_copy_and_build (tree t, CONSTRUCTOR_IS_DIRECT_INIT (r) = CONSTRUCTOR_IS_DIRECT_INIT (t); if (TREE_HAS_CONSTRUCTOR (t)) - RETURN (finish_compound_literal (type, r, complain)); + { + fcl_t cl = fcl_functional; + if (CONSTRUCTOR_C99_COMPOUND_LITERAL (t)) + cl = fcl_c99; + RETURN (finish_compound_literal (type, r, complain, cl)); + } TREE_TYPE (r) = type; RETURN (r); diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index b15763d..238dfff 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -2647,12 +2647,14 @@ finish_unary_op_expr (location_t op_loc, enum tree_code code, cp_expr expr, return result; } -/* Finish a compound-literal expression. TYPE is the type to which - the CONSTRUCTOR in COMPOUND_LITERAL is being cast. */ +/* Finish a compound-literal expression or C++11 functional cast with aggregate + initializer. TYPE is the type to which the CONSTRUCTOR in COMPOUND_LITERAL + is being cast. */ tree finish_compound_literal (tree type, tree compound_literal, - tsubst_flags_t complain) + tsubst_flags_t complain, + fcl_t fcl_context) { if (type == error_mark_node) return error_mark_node; @@ -2661,7 +2663,7 @@ finish_compound_literal (tree type, tree compound_literal, { compound_literal = finish_compound_literal (TREE_TYPE (type), compound_literal, - complain); + complain, fcl_context); return cp_build_c_cast (type, compound_literal, complain); } @@ -2682,6 +2684,8 @@ finish_compound_literal (tree type, tree compound_literal, TREE_TYPE (compound_literal) = type; /* Mark the expression as a compound literal. */ TREE_HAS_CONSTRUCTOR (compound_literal) = 1; + if (fcl_context == fcl_c99) + CONSTRUCTOR_C99_COMPOUND_LITERAL (compound_literal) = 1; return compound_literal; } @@ -2717,10 +2721,17 @@ finish_compound_literal (tree type, tree compound_literal, compound_literal = digest_init_flags (type, compound_literal, LOOKUP_NORMAL, complain); if (TREE_CODE (compound_literal) == CONSTRUCTOR) - TREE_HAS_CONSTRUCTOR (compound_literal) = true; + { + TREE_HAS_CONSTRUCTOR (compound_literal) = true; + if (fcl_context == fcl_c99) + CONSTRUCTOR_C99_COMPOUND_LITERAL (compound_literal) = 1; + } /* Put static/constant array temporaries in static variables. */ + /* FIXME all C99 compound literals should be variables rather than C++ + temporaries, unless they are used as an aggregate initializer. */ if ((!at_function_scope_p () || CP_TYPE_CONST_P (type)) + && fcl_context == fcl_c99 && TREE_CODE (type) == ARRAY_TYPE && !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type) && initializer_constant_valid_p (compound_literal, type)) diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-array6.C b/gcc/testsuite/g++.dg/cpp0x/initlist-array6.C new file mode 100644 index 0000000..fdfde0a --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist-array6.C @@ -0,0 +1,11 @@ +// PR c++/70167 +// { dg-do compile { target c++11 } } + +template<class T, unsigned S> void f(T(&&)[S]) { } + +using arr = const int[2]; + +int main() +{ + f(arr{1, 2}); +} |