diff options
author | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-11-17 20:17:56 +0000 |
---|---|---|
committer | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-11-17 20:17:56 +0000 |
commit | ba5b9ab335a795fb359588471344e205f89449ef (patch) | |
tree | 6ba13b465e2a25a0a17dad66c10d9b9043cdfe4f | |
parent | d85d1efc03a614320861cfbffbf7dade2cb0e32f (diff) | |
download | gcc-ba5b9ab335a795fb359588471344e205f89449ef.tar.gz |
PR c++/50473
* decl.c (cp_finish_decl): Don't try to process a non-dependent
constant initializer for a reference.
* pt.c (value_dependent_expression_p): A reference is always
dependent.
* call.c (extend_ref_init_temps_1): Also clear TREE_SIDE_EFFECTS
on any NOP_EXPRs.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@217672 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/call.c | 4 | ||||
-rw-r--r-- | gcc/cp/decl.c | 1 | ||||
-rw-r--r-- | gcc/cp/pt.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/constexpr-ice12.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/constexpr-ref5.C | 13 |
6 files changed, 28 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 18e06d82cd1..05ca4931910 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,13 @@ 2014-11-17 Jason Merrill <jason@redhat.com> + PR c++/50473 + * decl.c (cp_finish_decl): Don't try to process a non-dependent + constant initializer for a reference. + * pt.c (value_dependent_expression_p): A reference is always + dependent. + * call.c (extend_ref_init_temps_1): Also clear TREE_SIDE_EFFECTS + on any NOP_EXPRs. + Handle C++14 constexpr flow control. * constexpr.c (cxx_eval_loop_expr, cxx_eval_switch_expr): New. (cxx_eval_statement_list): New. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 4f0b1725da2..06162aa6286 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -9712,9 +9712,11 @@ extend_ref_init_temps_1 (tree decl, tree init, vec<tree, va_gc> **cleanups) { tree subinit = NULL_TREE; *p = set_up_extended_ref_temp (decl, *p, cleanups, &subinit); + recompute_tree_invariant_for_addr_expr (sub); + if (init != sub) + init = fold_convert (TREE_TYPE (init), sub); if (subinit) init = build2 (COMPOUND_EXPR, TREE_TYPE (init), subinit, init); - recompute_tree_invariant_for_addr_expr (sub); } return init; } diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 47da0ca4ecc..e69b5217490 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -6419,6 +6419,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, else if (init && init_const_expr_p && !type_dependent_p + && TREE_CODE (type) != REFERENCE_TYPE && decl_maybe_constant_var_p (decl) && !type_dependent_init_p (init) && !value_dependent_init_p (init)) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 1ee3dc11906..c0f3b8c5f9f 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -20959,6 +20959,8 @@ value_dependent_expression_p (tree expression) if (DECL_INITIAL (expression) && decl_constant_var_p (expression) && (TREE_CODE (DECL_INITIAL (expression)) == TREE_LIST + /* cp_finish_decl doesn't fold reference initializers. */ + || TREE_CODE (TREE_TYPE (expression)) == REFERENCE_TYPE || value_dependent_expression_p (DECL_INITIAL (expression)))) return true; return false; diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-ice12.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-ice12.C index 98f53b14c10..c5483376c37 100644 --- a/gcc/testsuite/g++.dg/cpp0x/constexpr-ice12.C +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-ice12.C @@ -3,7 +3,7 @@ struct A { - static constexpr int&& i = 0; // { dg-error "initialization" } + static constexpr int&& i = 0; }; int j = A::i; diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-ref5.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-ref5.C new file mode 100644 index 00000000000..230510c4c29 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-ref5.C @@ -0,0 +1,13 @@ +// PR c++/50473 +// { dg-do compile { target c++11 } } + +constexpr int f() { return 1; } + +template<class T> +struct test +{ + static constexpr const auto& value = f(); + int a[value]; +}; + +test<int> t; |