+2011-09-24 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/44267
+ * class.c (build_base_path): Add a tsubst_flags_t parameter.
+ (convert_to_base): Adjust call.
+ * typeck.c (build_class_member_access_expr,
+ get_member_function_from_ptrfunc, build_static_cast_1): Likewise.
+ * init.c (dfs_initialize_vtbl_ptrs, emit_mem_initializers): Likewise.
+ * method.c (do_build_copy_constructor, do_build_copy_assign): Likewise.
+ * rtti.c (build_dynamic_cast_1): Likewise.
+ * typeck2.c (build_scoped_ref, build_m_component_ref): Likewise.
+ * call.c (build_over_call, build_special_member_call): Likewise.
+ * cvt.c (cp_convert_to_pointer, convert_to_pointer_force,
+ build_up_reference): Likewise.
+ * cp-tree.h (build_base_path): Adjust declaration.
+
2011-09-23 Jason Merrill <jason@redhat.com>
Core 253 - allow const objects with no initializer or
converted_arg = build_base_path (PLUS_EXPR,
arg,
cand->conversion_path,
- 1);
+ 1, complain);
/* Check that the base class is accessible. */
if (!accessible_base_p (TREE_TYPE (argtype),
BINFO_TYPE (cand->conversion_path), true))
base_binfo = lookup_base (TREE_TYPE (TREE_TYPE (converted_arg)),
TREE_TYPE (parmtype), ba_unique, NULL);
converted_arg = build_base_path (PLUS_EXPR, converted_arg,
- base_binfo, 1);
+ base_binfo, 1, complain);
argarray[j++] = converted_arg;
parm = TREE_CHAIN (parm);
if (TREE_DEPRECATED (fn))
warn_deprecated_use (fn, NULL_TREE);
- argarray[0] = build_base_path (PLUS_EXPR, argarray[0], binfo, 1);
+ argarray[0] = build_base_path (PLUS_EXPR, argarray[0], binfo, 1,
+ complain);
if (TREE_SIDE_EFFECTS (argarray[0]))
argarray[0] = save_expr (argarray[0]);
t = build_pointer_type (TREE_TYPE (fn));
/* However, for assignment operators, we must convert
dynamically if the base is virtual. */
instance = build_base_path (PLUS_EXPR, instance,
- binfo, /*nonnull=*/1);
+ binfo, /*nonnull=*/1, complain);
}
}
build_base_path (enum tree_code code,
tree expr,
tree binfo,
- int nonnull)
+ int nonnull,
+ tsubst_flags_t complain)
{
tree v_binfo = NULL_TREE;
tree d_binfo = NULL_TREE;
if (code == MINUS_EXPR && v_binfo)
{
- error ("cannot convert from base %qT to derived type %qT via virtual base %qT",
- BINFO_TYPE (binfo), BINFO_TYPE (d_binfo), BINFO_TYPE (v_binfo));
+ if (complain & tf_error)
+ error ("cannot convert from base %qT to derived type %qT via "
+ "virtual base %qT", BINFO_TYPE (binfo), BINFO_TYPE (d_binfo),
+ BINFO_TYPE (v_binfo));
return error_mark_node;
}
if (!want_pointer)
/* This must happen before the call to save_expr. */
- expr = cp_build_addr_expr (expr, tf_warning_or_error);
+ expr = cp_build_addr_expr (expr, complain);
else
expr = mark_rvalue_use (expr);
interesting to the optimizers anyway. */
&& !has_empty)
{
- expr = cp_build_indirect_ref (expr, RO_NULL, tf_warning_or_error);
+ expr = cp_build_indirect_ref (expr, RO_NULL, complain);
expr = build_simple_base_path (expr, binfo);
if (want_pointer)
expr = build_address (expr);
t = TREE_TYPE (TYPE_VFIELD (current_class_type));
t = build_pointer_type (t);
v_offset = convert (t, current_vtt_parm);
- v_offset = cp_build_indirect_ref (v_offset, RO_NULL,
- tf_warning_or_error);
+ v_offset = cp_build_indirect_ref (v_offset, RO_NULL, complain);
}
else
v_offset = build_vfield_ref (cp_build_indirect_ref (expr, RO_NULL,
- tf_warning_or_error),
+ complain),
TREE_TYPE (TREE_TYPE (expr)));
v_offset = fold_build_pointer_plus (v_offset, BINFO_VPTR_FIELD (v_binfo));
v_offset = build1 (NOP_EXPR,
build_pointer_type (ptrdiff_type_node),
v_offset);
- v_offset = cp_build_indirect_ref (v_offset, RO_NULL, tf_warning_or_error);
+ v_offset = cp_build_indirect_ref (v_offset, RO_NULL, complain);
TREE_CONSTANT (v_offset) = 1;
offset = convert_to_integer (ptrdiff_type_node,
null_test = NULL;
if (!want_pointer)
- expr = cp_build_indirect_ref (expr, RO_NULL, tf_warning_or_error);
+ expr = cp_build_indirect_ref (expr, RO_NULL, complain);
out:
if (null_test)
if (!binfo || binfo == error_mark_node)
return error_mark_node;
- return build_base_path (PLUS_EXPR, object, binfo, nonnull);
+ return build_base_path (PLUS_EXPR, object, binfo, nonnull, complain);
}
/* EXPR is an expression with unqualified class type. BASE is a base
/* in class.c */
extern tree build_vfield_ref (tree, tree);
extern tree build_base_path (enum tree_code, tree,
- tree, int);
+ tree, int, tsubst_flags_t);
extern tree convert_to_base (tree, tree, bool, bool,
tsubst_flags_t);
extern tree convert_to_base_statically (tree, tree);
/* Language-level data type conversion for GNU C++.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
- Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+ 2011 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
This file is part of GCC.
if (binfo || same_p)
{
if (binfo)
- expr = build_base_path (code, expr, binfo, 0);
+ expr = build_base_path (code, expr, binfo, 0,
+ tf_warning_or_error);
/* Add any qualifier conversions. */
return build_nop (type, expr);
}
return error_mark_node;
if (binfo)
{
- expr = build_base_path (code, expr, binfo, 0);
+ expr = build_base_path (code, expr, binfo, 0,
+ tf_warning_or_error);
if (expr == error_mark_node)
return error_mark_node;
/* Add any qualifier conversions. */
return error_mark_node;
if (binfo == NULL_TREE)
return error_not_base_type (target_type, argtype);
- rval = build_base_path (PLUS_EXPR, rval, binfo, 1);
+ rval = build_base_path (PLUS_EXPR, rval, binfo, 1,
+ tf_warning_or_error);
}
else
rval
{
tree base_ptr = TREE_VALUE ((tree) data);
- base_ptr = build_base_path (PLUS_EXPR, base_ptr, binfo, /*nonnull=*/1);
+ base_ptr = build_base_path (PLUS_EXPR, base_ptr, binfo, /*nonnull=*/1,
+ tf_warning_or_error);
expand_virtual_init (binfo, base_ptr);
}
tree base_addr;
base_addr = build_base_path (PLUS_EXPR, current_class_ptr,
- subobject, 1);
+ subobject, 1, tf_warning_or_error);
expand_aggr_init_1 (subobject, NULL_TREE,
cp_build_indirect_ref (base_addr, RO_NULL,
tf_warning_or_error),
for (vbases = CLASSTYPE_VBASECLASSES (current_class_type), i = 0;
VEC_iterate (tree, vbases, i, binfo); i++)
{
- init = build_base_path (PLUS_EXPR, parm, binfo, 1);
+ init = build_base_path (PLUS_EXPR, parm, binfo, 1,
+ tf_warning_or_error);
if (move_p)
init = move (init);
member_init_list
if (BINFO_VIRTUAL_P (base_binfo))
continue;
- init = build_base_path (PLUS_EXPR, parm, base_binfo, 1);
+ init = build_base_path (PLUS_EXPR, parm, base_binfo, 1,
+ tf_warning_or_error);
if (move_p)
init = move (init);
member_init_list
/* We must convert PARM directly to the base class
explicitly since the base class may be ambiguous. */
- converted_parm = build_base_path (PLUS_EXPR, parm, base_binfo, 1);
+ converted_parm = build_base_path (PLUS_EXPR, parm, base_binfo, 1,
+ tf_warning_or_error);
if (move_p)
converted_parm = move (converted_parm);
/* Call the base class assignment operator. */
/* RunTime Type Identification
Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- 2005, 2006, 2007, 2008, 2009, 2010
+ 2005, 2006, 2007, 2008, 2009, 2010, 2011
Free Software Foundation, Inc.
Mostly written by Jason Merrill (jason@cygnus.com).
if (binfo)
{
expr = build_base_path (PLUS_EXPR, convert_from_reference (expr),
- binfo, 0);
+ binfo, 0, complain);
if (TREE_CODE (exprtype) == POINTER_TYPE)
expr = rvalue (expr);
return expr;
/* Convert to the base. */
object = build_base_path (PLUS_EXPR, object, binfo,
- /*nonnull=*/1);
+ /*nonnull=*/1, complain);
/* If we found the base successfully then we should be able
to convert to it successfully. */
gcc_assert (object != error_mark_node);
basetype = lookup_base (TREE_TYPE (TREE_TYPE (instance_ptr)),
basetype, ba_check, NULL);
instance_ptr = build_base_path (PLUS_EXPR, instance_ptr, basetype,
- 1);
+ 1, tf_warning_or_error);
if (instance_ptr == error_mark_node)
return error_mark_node;
}
/* Convert from "B*" to "D*". This function will check that "B"
is not a virtual base of "D". */
expr = build_base_path (MINUS_EXPR, build_address (expr),
- base, /*nonnull=*/false);
+ base, /*nonnull=*/false, complain);
/* Convert the pointer to a reference -- but then remember that
there are no expressions with reference type in C++.
base = lookup_base (TREE_TYPE (type), TREE_TYPE (intype),
c_cast_p ? ba_unique : ba_check,
NULL);
- expr = build_base_path (MINUS_EXPR, expr, base, /*nonnull=*/false);
+ expr = build_base_path (MINUS_EXPR, expr, base, /*nonnull=*/false,
+ complain);
return cp_fold_convert(type, expr);
}
}
*binfo_p = binfo;
- return build_base_path (PLUS_EXPR, datum, binfo, 1);
+ return build_base_path (PLUS_EXPR, datum, binfo, 1,
+ tf_warning_or_error);
}
/* Build a reference to an object specified by the C++ `->' operator.
/* Convert object to the correct base. */
if (binfo)
- datum = build_base_path (PLUS_EXPR, datum, binfo, 1);
+ datum = build_base_path (PLUS_EXPR, datum, binfo, 1,
+ tf_warning_or_error);
/* Build an expression for "object + offset" where offset is the
value stored in the pointer-to-data-member. */
+2011-09-24 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/44267
+ * g++.dg/template/sfinae28.C: New.
+
2011-09-23 Ian Lance Taylor <iant@google.com>
* go.test/go-test.exp (errchk): Handle more cases of getting
--- /dev/null
+// Origin: PR c++/44267
+
+struct B {};
+struct D : B {};
+struct VD : virtual B {};
+
+template <class T> T create();
+
+typedef char one[1];
+typedef char two[2];
+
+template <class D, class B>
+one& f(char (*)[sizeof(static_cast<D>(create<B>()))]);
+
+template <class D, class B>
+two& f(...);
+
+int main()
+{
+ f<D*, int>(0);
+ f<D*, B*>(0);
+ f<VD*, B*>(0);
+ return 0;
+}