Commit 1f6857ba by Marek Polacek Committed by Marek Polacek

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
parent b43e6340
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> 2019-02-13 Marek Polacek <polacek@redhat.com>
PR c++/89297 - ICE with OVERLOAD in template. PR c++/89297 - ICE with OVERLOAD in template.
......
...@@ -1318,7 +1318,7 @@ find_constructor (tree *tp, int *walk_subtrees, void *) ...@@ -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 /* 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. */ subexpression, return an unshared copy of T. Otherwise return T. */
static tree tree
unshare_constructor (tree t) unshare_constructor (tree t)
{ {
tree ctor = walk_tree (&t, find_constructor, NULL, NULL); tree ctor = walk_tree (&t, find_constructor, NULL, NULL);
......
...@@ -7710,6 +7710,7 @@ extern void explain_invalid_constexpr_fn (tree); ...@@ -7710,6 +7710,7 @@ extern void explain_invalid_constexpr_fn (tree);
extern vec<tree> cx_error_context (void); extern vec<tree> cx_error_context (void);
extern tree fold_sizeof_expr (tree); extern tree fold_sizeof_expr (tree);
extern void clear_cv_and_fold_caches (void); extern void clear_cv_and_fold_caches (void);
extern tree unshare_constructor (tree);
/* In cp-ubsan.c */ /* In cp-ubsan.c */
extern void cp_ubsan_maybe_instrument_member_call (tree); extern void cp_ubsan_maybe_instrument_member_call (tree);
......
...@@ -2796,17 +2796,31 @@ finish_compound_literal (tree type, tree compound_literal, ...@@ -2796,17 +2796,31 @@ finish_compound_literal (tree type, tree compound_literal,
return error_mark_node; return error_mark_node;
} }
if (instantiation_dependent_expression_p (compound_literal) /* Used to hold a copy of the compound literal in a template. */
|| dependent_type_p (type)) 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. */ /* Mark the expression as a compound literal. */
TREE_HAS_CONSTRUCTOR (compound_literal) = 1; TREE_HAS_CONSTRUCTOR (orig_cl) = 1;
/* And as instantiation-dependent. */ /* And as instantiation-dependent. */
CONSTRUCTOR_IS_DEPENDENT (compound_literal) = true; CONSTRUCTOR_IS_DEPENDENT (orig_cl) = dependent_p;
if (fcl_context == fcl_c99) if (fcl_context == fcl_c99)
CONSTRUCTOR_C99_COMPOUND_LITERAL (compound_literal) = 1; CONSTRUCTOR_C99_COMPOUND_LITERAL (orig_cl) = 1;
return compound_literal; /* 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); type = complete_type (type);
...@@ -2842,8 +2856,18 @@ finish_compound_literal (tree type, tree compound_literal, ...@@ -2842,8 +2856,18 @@ finish_compound_literal (tree type, tree compound_literal,
if (type == error_mark_node) if (type == error_mark_node)
return 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); 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) if (TREE_CODE (compound_literal) == CONSTRUCTOR)
{ {
TREE_HAS_CONSTRUCTOR (compound_literal) = true; TREE_HAS_CONSTRUCTOR (compound_literal) = true;
......
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> 2019-02-16 David Malcolm <dmalcolm@redhat.com>
PR c++/88680 PR c++/88680
......
// 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}) {}
}
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment