Commit c65b0607 by Jason Merrill Committed by Jason Merrill

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
parent e2c4d88e
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;
}
......
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
......
// 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();
}
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