diff options
author | Marek Polacek <polacek@redhat.com> | 2019-02-17 16:52:40 +0000 |
---|---|---|
committer | Marek Polacek <mpolacek@gcc.gnu.org> | 2019-02-17 16:52:40 +0000 |
commit | 1f6857ba5608f715621cfe8d3c3be31b3040e9e6 (patch) | |
tree | 9dee916ca3c34d2ac5f7cf385af30f3daf880f59 /gcc | |
parent | b43e6340c80f3ae0ddf70950a8f979f4791c3252 (diff) | |
download | gcc-1f6857ba5608f715621cfe8d3c3be31b3040e9e6.zip gcc-1f6857ba5608f715621cfe8d3c3be31b3040e9e6.tar.gz gcc-1f6857ba5608f715621cfe8d3c3be31b3040e9e6.tar.bz2 |
PR c++/89217 - ICE with list-initialization in range-based for loop.
* constexpr.c (unshare_constructor): No longer static.
* cp-tree.h (unshare_constructor): Declare.
* semantics.c (finish_compound_literal): When dealing with a
non-dependent expression in a template, return the original
expression. Pass LOOKUP_NO_NARROWING to digest_init_flags.
* g++.dg/cpp0x/range-for37.C: New test.
From-SVN: r268969
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/constexpr.c | 2 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 1 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 40 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/range-for37.C | 24 |
6 files changed, 72 insertions, 9 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d6d1f59..d4e0625 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2019-02-17 Marek Polacek <polacek@redhat.com> + + PR c++/89217 - ICE with list-initialization in range-based for loop. + * constexpr.c (unshare_constructor): No longer static. + * cp-tree.h (unshare_constructor): Declare. + * semantics.c (finish_compound_literal): When dealing with a + non-dependent expression in a template, return the original + expression. Pass LOOKUP_NO_NARROWING to digest_init_flags. + 2019-02-13 Marek Polacek <polacek@redhat.com> PR c++/89297 - ICE with OVERLOAD in template. diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 923763f..d946a79 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -1318,7 +1318,7 @@ find_constructor (tree *tp, int *walk_subtrees, void *) /* If T is a CONSTRUCTOR or an expression that has a CONSTRUCTOR node as a subexpression, return an unshared copy of T. Otherwise return T. */ -static tree +tree unshare_constructor (tree t) { tree ctor = walk_tree (&t, find_constructor, NULL, NULL); diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 44a3620..60ca136 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -7710,6 +7710,7 @@ extern void explain_invalid_constexpr_fn (tree); extern vec<tree> cx_error_context (void); extern tree fold_sizeof_expr (tree); extern void clear_cv_and_fold_caches (void); +extern tree unshare_constructor (tree); /* In cp-ubsan.c */ extern void cp_ubsan_maybe_instrument_member_call (tree); diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index aa5a163..3ecd192 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -2796,17 +2796,31 @@ finish_compound_literal (tree type, tree compound_literal, return error_mark_node; } - if (instantiation_dependent_expression_p (compound_literal) - || dependent_type_p (type)) + /* Used to hold a copy of the compound literal in a template. */ + tree orig_cl = NULL_TREE; + + if (processing_template_decl) { - TREE_TYPE (compound_literal) = type; + const bool dependent_p + = (instantiation_dependent_expression_p (compound_literal) + || dependent_type_p (type)); + if (dependent_p) + /* We're about to return, no need to copy. */ + orig_cl = compound_literal; + else + /* We're going to need a copy. */ + orig_cl = unshare_constructor (compound_literal); + TREE_TYPE (orig_cl) = type; /* Mark the expression as a compound literal. */ - TREE_HAS_CONSTRUCTOR (compound_literal) = 1; + TREE_HAS_CONSTRUCTOR (orig_cl) = 1; /* And as instantiation-dependent. */ - CONSTRUCTOR_IS_DEPENDENT (compound_literal) = true; + CONSTRUCTOR_IS_DEPENDENT (orig_cl) = dependent_p; if (fcl_context == fcl_c99) - CONSTRUCTOR_C99_COMPOUND_LITERAL (compound_literal) = 1; - return compound_literal; + CONSTRUCTOR_C99_COMPOUND_LITERAL (orig_cl) = 1; + /* If the compound literal is dependent, we're done for now. */ + if (dependent_p) + return orig_cl; + /* Otherwise, do go on to e.g. check narrowing. */ } type = complete_type (type); @@ -2842,8 +2856,18 @@ finish_compound_literal (tree type, tree compound_literal, if (type == error_mark_node) return error_mark_node; } - compound_literal = digest_init_flags (type, compound_literal, LOOKUP_NORMAL, + compound_literal = digest_init_flags (type, compound_literal, + LOOKUP_NORMAL | LOOKUP_NO_NARROWING, complain); + /* If we're in a template, return the original compound literal. */ + if (orig_cl) + { + if (!VECTOR_TYPE_P (type)) + return get_target_expr_sfinae (orig_cl, complain); + else + return orig_cl; + } + if (TREE_CODE (compound_literal) == CONSTRUCTOR) { TREE_HAS_CONSTRUCTOR (compound_literal) = true; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 45fbe7c..38959b3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-02-17 Marek Polacek <polacek@redhat.com> + + PR c++/89217 - ICE with list-initialization in range-based for loop. + * g++.dg/cpp0x/range-for37.C: New test. + 2019-02-16 David Malcolm <dmalcolm@redhat.com> PR c++/88680 diff --git a/gcc/testsuite/g++.dg/cpp0x/range-for37.C b/gcc/testsuite/g++.dg/cpp0x/range-for37.C new file mode 100644 index 0000000..d5c7c09 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/range-for37.C @@ -0,0 +1,24 @@ +// PR c++/89217 +// { dg-do compile { target c++11 } } + +struct R {}; + +struct C +{ + R* begin() const { return &r; } + R* end() const { return &r; } + + R& r; +}; + +struct S +{ + void f1() { f2<true>(); } + R& r; + + template<bool> + void f2() + { + for (auto i : C{r}) {} + } +}; |