mirror of git://gcc.gnu.org/git/gcc.git
re PR c++/51611 ([c++0x] ICE with non-static data member initializer and virtual base class)
PR c++/51611 * cp-tree.h (CONVERT_EXPR_VBASE_PATH): New. * class.c (build_base_path): Defer vbase conversion in an NSDMI. * tree.c (bot_replace): Expand it here. * cp-gimplify.c (cp_genericize_r): Make sure deferred conversion doesn't leak into GENERIC. From-SVN: r182602
This commit is contained in:
parent
e2c4d88e42
commit
c65b06073c
|
@ -1,3 +1,12 @@
|
|||
2011-12-21 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/51611
|
||||
* cp-tree.h (CONVERT_EXPR_VBASE_PATH): New.
|
||||
* class.c (build_base_path): Defer vbase conversion in an NSDMI.
|
||||
* tree.c (bot_replace): Expand it here.
|
||||
* cp-gimplify.c (cp_genericize_r): Make sure deferred conversion
|
||||
doesn't leak into GENERIC.
|
||||
|
||||
2011-12-21 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR c++/51305
|
||||
|
|
|
@ -318,6 +318,19 @@ build_base_path (enum tree_code code,
|
|||
return expr;
|
||||
}
|
||||
|
||||
/* If we're in an NSDMI, we don't have the full constructor context yet
|
||||
that we need for converting to a virtual base, so just build a stub
|
||||
CONVERT_EXPR and expand it later in bot_replace. */
|
||||
if (virtual_access && fixed_type_p < 0
|
||||
&& current_scope () != current_function_decl)
|
||||
{
|
||||
expr = build1 (CONVERT_EXPR, ptr_target_type, expr);
|
||||
CONVERT_EXPR_VBASE_PATH (expr) = true;
|
||||
if (!want_pointer)
|
||||
expr = build_indirect_ref (EXPR_LOCATION (expr), expr, RO_NULL);
|
||||
return expr;
|
||||
}
|
||||
|
||||
/* Do we need to check for a null pointer? */
|
||||
if (want_pointer && !nonnull)
|
||||
{
|
||||
|
|
|
@ -1100,6 +1100,8 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
|
|||
wtd->omp_ctx = omp_ctx.outer;
|
||||
splay_tree_delete (omp_ctx.variables);
|
||||
}
|
||||
else if (TREE_CODE (stmt) == CONVERT_EXPR)
|
||||
gcc_assert (!CONVERT_EXPR_VBASE_PATH (stmt));
|
||||
|
||||
pointer_set_insert (p_set, *stmt_p);
|
||||
|
||||
|
|
|
@ -74,6 +74,7 @@ c-common.h, not after.
|
|||
DECL_OVERRIDE_P (in FUNCTION_DECL)
|
||||
IMPLICIT_CONV_EXPR_DIRECT_INIT (in IMPLICIT_CONV_EXPR)
|
||||
TRANSACTION_EXPR_IS_STMT (in TRANSACTION_EXPR)
|
||||
CONVERT_EXPR_VBASE_PATH (in CONVERT_EXPR)
|
||||
1: IDENTIFIER_VIRTUAL_P (in IDENTIFIER_NODE)
|
||||
TI_PENDING_TEMPLATE_FLAG.
|
||||
TEMPLATE_PARMS_FOR_INLINE.
|
||||
|
@ -4011,6 +4012,11 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
|
|||
(TREE_CODE (EXPR) == TARGET_EXPR && TREE_LANG_FLAG_2 (EXPR) \
|
||||
&& same_type_ignoring_top_level_qualifiers_p (TYPE, TREE_TYPE (EXPR)))
|
||||
|
||||
/* True if this CONVERT_EXPR is for a conversion to virtual base in
|
||||
an NSDMI, and should be re-evaluated when used in a constructor. */
|
||||
#define CONVERT_EXPR_VBASE_PATH(NODE) \
|
||||
TREE_LANG_FLAG_0 (CONVERT_EXPR_CHECK (NODE))
|
||||
|
||||
/* An enumeration of the kind of tags that C++ accepts. */
|
||||
enum tag_types {
|
||||
none_type = 0, /* Not a tag type. */
|
||||
|
|
|
@ -1944,6 +1944,20 @@ bot_replace (tree* t,
|
|||
parsing with the real one for this function. */
|
||||
*t = current_class_ptr;
|
||||
}
|
||||
else if (TREE_CODE (*t) == CONVERT_EXPR
|
||||
&& CONVERT_EXPR_VBASE_PATH (*t))
|
||||
{
|
||||
/* In an NSDMI build_base_path defers building conversions to virtual
|
||||
bases, and we handle it here. */
|
||||
tree basetype = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (*t)));
|
||||
VEC(tree,gc) *vbases = CLASSTYPE_VBASECLASSES (current_class_type);
|
||||
int i; tree binfo;
|
||||
FOR_EACH_VEC_ELT (tree, vbases, i, binfo)
|
||||
if (BINFO_TYPE (binfo) == basetype)
|
||||
break;
|
||||
*t = build_base_path (PLUS_EXPR, TREE_OPERAND (*t, 0), binfo, true,
|
||||
tf_warning_or_error);
|
||||
}
|
||||
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2011-12-21 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/51611
|
||||
* g++.dg/cpp0x/nsdmi-virtual1.C: New.
|
||||
|
||||
2011-12-21 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR c++/51305
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
// PR c++/51611
|
||||
// { dg-options -std=c++0x }
|
||||
// { dg-do run }
|
||||
|
||||
struct A
|
||||
{
|
||||
A(): i(42) { }
|
||||
int i;
|
||||
int f() { return i; }
|
||||
};
|
||||
|
||||
struct B : virtual A
|
||||
{
|
||||
int j = i + f();
|
||||
int k = A::i + A::f();
|
||||
};
|
||||
|
||||
struct C: B { int pad; };
|
||||
|
||||
int main()
|
||||
{
|
||||
C c;
|
||||
if (c.j != 84 || c.k != 84)
|
||||
__builtin_abort();
|
||||
}
|
||||
|
Loading…
Reference in New Issue