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
This commit is contained in:
parent
b43e6340c8
commit
1f6857ba56
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
24
gcc/testsuite/g++.dg/cpp0x/range-for37.C
Normal file
24
gcc/testsuite/g++.dg/cpp0x/range-for37.C
Normal file
@ -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}) {}
|
||||
}
|
||||
};
|
Loading…
Reference in New Issue
Block a user