re PR c++/41468 (SFINAE for expressions doesn't consider ambiguous conversion sequences)

PR c++/41468
	* class.c (convert_to_base): Add complain parameter.  Pass
	ba_quiet to lookup_base if we don't want errors.
	(build_vfield_ref): Pass complain to convert_to_base.
	* call.c (convert_like_real): Likewise.
	(initialize_reference): Likewise.
	(perform_direct_initialization_if_possible): Pass complain to
	convert_like_real.
	* cp-tree.h: Adjust.

From-SVN: r158798
This commit is contained in:
Jason Merrill 2010-04-27 15:04:09 -04:00 committed by Jason Merrill
parent 6ad86a5b26
commit 798ec80703
6 changed files with 59 additions and 8 deletions

View File

@ -1,3 +1,15 @@
2010-04-27 Jason Merrill <jason@redhat.com>
PR c++/41468
* class.c (convert_to_base): Add complain parameter. Pass
ba_quiet to lookup_base if we don't want errors.
(build_vfield_ref): Pass complain to convert_to_base.
* call.c (convert_like_real): Likewise.
(initialize_reference): Likewise.
(perform_direct_initialization_if_possible): Pass complain to
convert_like_real.
* cp-tree.h: Adjust.
2010-04-27 Fabien Chêne <fabien.chene@gmail.com>
Jason Merrill <jason@redhat.com>

View File

@ -5019,7 +5019,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
/* Build an expression for `*((base*) &expr)'. */
expr = cp_build_unary_op (ADDR_EXPR, expr, 0, complain);
expr = convert_to_base (expr, build_pointer_type (totype),
!c_cast_p, /*nonnull=*/true);
!c_cast_p, /*nonnull=*/true, complain);
expr = cp_build_indirect_ref (expr, RO_IMPLICIT_CONVERSION, complain);
return expr;
}
@ -5142,7 +5142,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
case ck_ptr:
if (convs->base_p)
expr = convert_to_base (expr, totype, !c_cast_p,
/*nonnull=*/false);
/*nonnull=*/false, complain);
return build_nop (totype, expr);
case ck_pmem:
@ -7584,7 +7584,7 @@ perform_direct_initialization_if_possible (tree type,
expr = convert_like_real (conv, expr, NULL_TREE, 0, 0,
/*issue_conversion_warnings=*/false,
c_cast_p,
tf_warning_or_error);
complain);
/* Free all the conversions we allocated. */
obstack_free (&conversion_obstack, p);
@ -7810,7 +7810,7 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup,
expr = convert_to_base (expr,
build_pointer_type (base_conv_type),
/*check_access=*/true,
/*nonnull=*/true);
/*nonnull=*/true, complain);
expr = build2 (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
}
else

View File

@ -506,10 +506,12 @@ build_simple_base_path (tree expr, tree binfo)
assumed to be non-NULL. */
tree
convert_to_base (tree object, tree type, bool check_access, bool nonnull)
convert_to_base (tree object, tree type, bool check_access, bool nonnull,
tsubst_flags_t complain)
{
tree binfo;
tree object_type;
base_access access;
if (TYPE_PTR_P (TREE_TYPE (object)))
{
@ -519,8 +521,11 @@ convert_to_base (tree object, tree type, bool check_access, bool nonnull)
else
object_type = TREE_TYPE (object);
access = check_access ? ba_check : ba_unique;
if (!(complain & tf_error))
access |= ba_quiet;
binfo = lookup_base (object_type, type,
check_access ? ba_check : ba_unique,
access,
NULL);
if (!binfo || binfo == error_mark_node)
return error_mark_node;
@ -575,7 +580,7 @@ build_vfield_ref (tree datum, tree type)
/* First, convert to the requested type. */
if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (datum), type))
datum = convert_to_base (datum, type, /*check_access=*/false,
/*nonnull=*/true);
/*nonnull=*/true, tf_warning_or_error);
/* Second, the requested type may not be the owner of its own vptr.
If not, convert to the base class that owns it. We cannot use

View File

@ -4569,7 +4569,8 @@ extern void validate_conversion_obstack (void);
extern tree build_vfield_ref (tree, tree);
extern tree build_base_path (enum tree_code, tree,
tree, int);
extern tree convert_to_base (tree, tree, bool, bool);
extern tree convert_to_base (tree, tree, bool, bool,
tsubst_flags_t);
extern tree convert_to_base_statically (tree, tree);
extern tree build_vtbl_ref (tree, tree);
extern tree build_vfn_ref (tree, tree);

View File

@ -1,3 +1,8 @@
2010-04-27 Jason Merrill <jason@redhat.com>
PR c++/41468
* g++.dg/template/sfinae17.C: New.
2010-04-27 Fabien Chêne <fabien.chene@gmail.com>
* g++.dg/init/pr42844.C: New.

View File

@ -0,0 +1,28 @@
// The conversion from D* to B* is ambiguous, but that should not produce
// an error, it should remove the first f overload by SFINAE.
#define static_assert(TEST,STR) \
do { int ar[(TEST)?1:-1]; } while (0);
struct B {};
struct B1 : B {};
struct B2 : B {};
struct D : B1, B2 {};
template <class T> T create();
typedef char one[1];
typedef char two[2];
template <class T>
one &f(char (*)[sizeof static_cast<T>(create<D *>())]);
template <class T>
two &f(...);
int main()
{
static_assert(sizeof f<int>(0) == sizeof(two), "");
static_assert(sizeof f<B *>(0) == sizeof(two), "");
}