re PR c++/52363 (Presence/absence of -pedantic compilation affects run-time behavior)

/cp
2012-04-24  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/52363
	* call.c (tourney, perform_overload_resolution,
	build_operator_new_call, build_user_type_conversion_1,
	build_user_type_conversion, perform_overload_resolution,
	add_template_candidate, add_template_candidate_real,
	add_template_conv_candidate, add_builtin_candidates,
	add_builtin_candidate, build_builtin_candidate,
	add_conv_candidate, add_function_candidate, implicit_conversion,
	reference_binding, build_list_conv, conditional_conversion,
	add_candidates, can_convert_array, build_aggr_conv,
	build_array_conv, build_complex_conv, conditional_conversion):
	Add tsubst_flags_t parameter.
	(joust): Likewise, use it to handle SFINAE as if pedantic.
	(add_list_candidates, build_integral_nontype_arg_conv,
	perform_overload_resolution, build_new_function_call,
	build_operator_new_call, build_op_call_1,
	build_conditional_expr_1, build_new_op_1, convert_like_real,
	convert_arg_to_ellipsis, convert_default_arg,
	convert_for_arg_passing, build_over_call,
	build_new_method_call_1, can_convert_arg, can_convert_arg_bad,
	perform_implicit_conversion_flags,
	perform_direct_initialization_if_possible,
	initialize_reference): Adjust.
	* typeck.c (casts_away_constness, casts_away_constness_r):
	Add tsubst_flags_t parameter.
	(convert_arguments, check_for_casting_away_constness,
	build_static_cast_1, build_ptrmemfunc, convert_for_assignment):
	Adjust.
	* decl.c (reshape_init_r, check_default_argument): Likewise.
	* cp-gimplify.c (cxx_omp_clause_apply_fn): Likewise.
	* pt.c (convert_nontype_argument, check_non_deducible_conversion):
	Likewise.
	* init.c (build_new_1): Likewise.
	* cvt.c (convert_to_reference, ocp_convert, build_type_conversion,
	build_expr_type_conversion, ): Likewise.
	* search.c (check_final_overrider): Likewise.
	* cp-tree.h (build_user_type_conversion,
	build_operator_new_call, can_convert, can_convert_arg,
	can_convert_arg_bad, convert_default_arg,
	convert_arg_to_ellipsis, convert_for_arg_passing):
	Adjust declaration.

/testsuite
2012-04-24  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/52363
	* g++.dg/cpp0x/sfinae35.C: New.
	* g++.dg/cpp0x/sfinae36.C: Likewise.

From-SVN: r186774
This commit is contained in:
Paolo Carlini 2012-04-24 16:25:15 +00:00 committed by Paolo Carlini
parent 5ada012290
commit b40e334f1f
13 changed files with 360 additions and 205 deletions

View File

@ -1,3 +1,47 @@
2012-04-24 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/52363
* call.c (tourney, perform_overload_resolution,
build_operator_new_call, build_user_type_conversion_1,
build_user_type_conversion, perform_overload_resolution,
add_template_candidate, add_template_candidate_real,
add_template_conv_candidate, add_builtin_candidates,
add_builtin_candidate, build_builtin_candidate,
add_conv_candidate, add_function_candidate, implicit_conversion,
reference_binding, build_list_conv, conditional_conversion,
add_candidates, can_convert_array, build_aggr_conv,
build_array_conv, build_complex_conv, conditional_conversion):
Add tsubst_flags_t parameter.
(joust): Likewise, use it to handle SFINAE as if pedantic.
(add_list_candidates, build_integral_nontype_arg_conv,
perform_overload_resolution, build_new_function_call,
build_operator_new_call, build_op_call_1,
build_conditional_expr_1, build_new_op_1, convert_like_real,
convert_arg_to_ellipsis, convert_default_arg,
convert_for_arg_passing, build_over_call,
build_new_method_call_1, can_convert_arg, can_convert_arg_bad,
perform_implicit_conversion_flags,
perform_direct_initialization_if_possible,
initialize_reference): Adjust.
* typeck.c (casts_away_constness, casts_away_constness_r):
Add tsubst_flags_t parameter.
(convert_arguments, check_for_casting_away_constness,
build_static_cast_1, build_ptrmemfunc, convert_for_assignment):
Adjust.
* decl.c (reshape_init_r, check_default_argument): Likewise.
* cp-gimplify.c (cxx_omp_clause_apply_fn): Likewise.
* pt.c (convert_nontype_argument, check_non_deducible_conversion):
Likewise.
* init.c (build_new_1): Likewise.
* cvt.c (convert_to_reference, ocp_convert, build_type_conversion,
build_expr_type_conversion, ): Likewise.
* search.c (check_final_overrider): Likewise.
* cp-tree.h (build_user_type_conversion,
build_operator_new_call, can_convert, can_convert_arg,
can_convert_arg_bad, convert_default_arg,
convert_arg_to_ellipsis, convert_for_arg_passing):
Adjust declaration.
2012-04-22 Jan Hubicka <jh@suse.cz>
* decl2.c (maybe_make_one_only): Mark keyed COMDATs as USED so they

File diff suppressed because it is too large Load Diff

View File

@ -1273,7 +1273,8 @@ cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2)
for (parm = defparm; parm && parm != void_list_node;
parm = TREE_CHAIN (parm), i++)
argarray[i] = convert_default_arg (TREE_VALUE (parm),
TREE_PURPOSE (parm), fn, i);
TREE_PURPOSE (parm), fn, i,
tf_warning_or_error);
t = build_call_a (fn, i, argarray);
t = fold_convert (void_type_node, t);
t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
@ -1306,7 +1307,7 @@ cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2)
parm = TREE_CHAIN (parm), i++)
argarray[i] = convert_default_arg (TREE_VALUE (parm),
TREE_PURPOSE (parm),
fn, i);
fn, i, tf_warning_or_error);
t = build_call_a (fn, i, argarray);
t = fold_convert (void_type_node, t);
return fold_build_cleanup_point_expr (TREE_TYPE (t), t);

View File

@ -4862,11 +4862,13 @@ extern bool null_ptr_cst_p (tree);
extern bool null_member_pointer_value_p (tree);
extern bool sufficient_parms_p (const_tree);
extern tree type_decays_to (tree);
extern tree build_user_type_conversion (tree, tree, int);
extern tree build_user_type_conversion (tree, tree, int,
tsubst_flags_t);
extern tree build_new_function_call (tree, VEC(tree,gc) **, bool,
tsubst_flags_t);
extern tree build_operator_new_call (tree, VEC(tree,gc) **, tree *,
tree *, tree *);
tree *, tree *,
tsubst_flags_t);
extern tree build_new_method_call (tree, tree, VEC(tree,gc) **,
tree, int, tree *,
tsubst_flags_t);
@ -4878,18 +4880,21 @@ extern tree build_new_op (enum tree_code, int, tree,
extern tree build_op_call (tree, VEC(tree,gc) **,
tsubst_flags_t);
extern tree build_op_delete_call (enum tree_code, tree, tree, bool, tree, tree);
extern bool can_convert (tree, tree);
extern bool can_convert_arg (tree, tree, tree, int);
extern bool can_convert_arg_bad (tree, tree, tree, int);
extern bool can_convert (tree, tree, tsubst_flags_t);
extern bool can_convert_arg (tree, tree, tree, int,
tsubst_flags_t);
extern bool can_convert_arg_bad (tree, tree, tree, int,
tsubst_flags_t);
extern bool enforce_access (tree, tree, tree);
extern void push_defarg_context (tree);
extern void pop_defarg_context (void);
extern tree convert_default_arg (tree, tree, tree, int);
extern tree convert_arg_to_ellipsis (tree);
extern tree convert_default_arg (tree, tree, tree, int,
tsubst_flags_t);
extern tree convert_arg_to_ellipsis (tree, tsubst_flags_t);
extern tree build_x_va_arg (tree, tree);
extern tree cxx_type_promotes_to (tree);
extern tree type_passed_as (tree);
extern tree convert_for_arg_passing (tree, tree);
extern tree convert_for_arg_passing (tree, tree, tsubst_flags_t);
extern bool is_properly_derived_from (tree, tree);
extern tree initialize_reference (tree, tree, int,
tsubst_flags_t);

View File

@ -408,12 +408,12 @@ convert_to_reference (tree reftype, tree expr, int convtype,
tree rval = NULL_TREE;
tree rval_as_conversion = NULL_TREE;
bool can_convert_intype_to_type;
tsubst_flags_t complain = ((flags & LOOKUP_COMPLAIN)
? tf_warning_or_error : tf_none);
if (TREE_CODE (type) == FUNCTION_TYPE
&& TREE_TYPE (expr) == unknown_type_node)
expr = instantiate_type (type, expr,
(flags & LOOKUP_COMPLAIN)
? tf_warning_or_error : tf_none);
expr = instantiate_type (type, expr, complain);
if (expr == error_mark_node)
return error_mark_node;
@ -425,7 +425,8 @@ convert_to_reference (tree reftype, tree expr, int convtype,
intype = TYPE_MAIN_VARIANT (intype);
can_convert_intype_to_type = can_convert (type, intype);
can_convert_intype_to_type = can_convert (type, intype, complain);
if (!can_convert_intype_to_type
&& (convtype & CONV_IMPLICIT) && MAYBE_CLASS_TYPE_P (intype)
&& ! (flags & LOOKUP_NO_CONVERSION))
@ -445,7 +446,7 @@ convert_to_reference (tree reftype, tree expr, int convtype,
}
}
if (((convtype & CONV_STATIC) && can_convert (intype, type))
if (((convtype & CONV_STATIC) && can_convert (intype, type, complain))
|| ((convtype & CONV_IMPLICIT) && can_convert_intype_to_type))
{
if (flags & LOOKUP_COMPLAIN)
@ -821,7 +822,8 @@ ocp_convert (tree type, tree expr, int convtype, int flags)
/* For copy-initialization, first we create a temp of the proper type
with a user-defined conversion sequence, then we direct-initialize
the target with the temp (see [dcl.init]). */
ctor = build_user_type_conversion (type, ctor, flags);
ctor = build_user_type_conversion (type, ctor, flags,
tf_warning_or_error);
else
{
VEC(tree,gc) *ctor_vec = make_tree_vector_single (ctor);
@ -1451,7 +1453,8 @@ build_type_conversion (tree xtype, tree expr)
{
/* C++: check to see if we can convert this aggregate type
into the required type. */
return build_user_type_conversion (xtype, expr, LOOKUP_NORMAL);
return build_user_type_conversion (xtype, expr, LOOKUP_NORMAL,
tf_warning_or_error);
}
/* Convert the given EXPR to one of a group of types suitable for use in an
@ -1609,7 +1612,8 @@ build_expr_type_conversion (int desires, tree expr, bool complain)
if (winner)
{
tree type = non_reference (TREE_TYPE (TREE_TYPE (winner)));
return build_user_type_conversion (type, expr, LOOKUP_NORMAL);
return build_user_type_conversion (type, expr, LOOKUP_NORMAL,
tf_warning_or_error);
}
return NULL_TREE;

View File

@ -5266,7 +5266,8 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p,
valid aggregate initialization. */
&& !first_initializer_p
&& (same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (init))
|| can_convert_arg (type, TREE_TYPE (init), init, LOOKUP_NORMAL)))
|| can_convert_arg (type, TREE_TYPE (init), init, LOOKUP_NORMAL,
complain)))
{
d->cur++;
return init;
@ -10602,7 +10603,8 @@ check_default_argument (tree decl, tree arg)
A default argument expression is implicitly converted to the
parameter type. */
if (!TREE_TYPE (arg)
|| !can_convert_arg (decl_type, TREE_TYPE (arg), arg, LOOKUP_NORMAL))
|| !can_convert_arg (decl_type, TREE_TYPE (arg), arg, LOOKUP_NORMAL,
tf_warning_or_error))
{
if (decl)
error ("default argument for %q#D has type %qT",

View File

@ -2381,7 +2381,7 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts,
alloc_call = build_operator_new_call (fnname, placement,
&size, &cookie_size,
&alloc_fn);
&alloc_fn, complain);
}
}

View File

@ -6063,7 +6063,7 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
"because it is of type %qT", expr, type,
TREE_TYPE (expr));
/* If we are just one standard conversion off, explain. */
if (can_convert (type, TREE_TYPE (expr)))
if (can_convert (type, TREE_TYPE (expr), complain))
inform (input_location,
"standard conversions are not allowed in this context");
return NULL_TREE;
@ -15128,14 +15128,15 @@ check_non_deducible_conversion (tree parm, tree arg, int strict,
if (strict == DEDUCE_CONV)
{
if (can_convert_arg (type, parm, NULL_TREE, flags))
if (can_convert_arg (type, parm, NULL_TREE, flags,
explain_p ? tf_warning_or_error : tf_none))
return unify_success (explain_p);
}
else if (strict != DEDUCE_EXACT)
{
if (can_convert_arg (parm, type,
TYPE_P (arg) ? NULL_TREE : arg,
flags))
flags, explain_p ? tf_warning_or_error : tf_none))
return unify_success (explain_p);
}

View File

@ -1,7 +1,8 @@
/* Breadth-first and depth-first routines for
searching multiple-inheritance lattice for GNU C++.
Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
1999, 2000, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011,
2012
Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com)
@ -1891,7 +1892,8 @@ check_final_overrider (tree overrider, tree basefn)
}
}
else if (!pedantic
&& can_convert (TREE_TYPE (base_type), TREE_TYPE (over_type)))
&& can_convert (TREE_TYPE (base_type), TREE_TYPE (over_type),
tf_warning_or_error))
/* GNU extension, allow trivial pointer conversions such as
converting to void *, or qualification conversion. */
{

View File

@ -55,8 +55,8 @@ static bool comp_except_types (tree, tree, bool);
static bool comp_array_types (const_tree, const_tree, bool);
static tree pointer_diff (tree, tree, tree);
static tree get_delta_difference (tree, tree, bool, bool, tsubst_flags_t);
static void casts_away_constness_r (tree *, tree *);
static bool casts_away_constness (tree, tree);
static void casts_away_constness_r (tree *, tree *, tsubst_flags_t);
static bool casts_away_constness (tree, tree, tsubst_flags_t);
static void maybe_warn_about_returning_address_of_local (tree);
static tree lookup_destructor (tree, tree, tree);
static void warn_args_num (location_t, tree, bool);
@ -3500,7 +3500,7 @@ convert_arguments (tree typelist, VEC(tree,gc) **values, tree fndecl,
parmval = convert_for_initialization
(NULL_TREE, type, val, flags,
ICR_ARGPASS, fndecl, i, complain);
parmval = convert_for_arg_passing (type, parmval);
parmval = convert_for_arg_passing (type, parmval, complain);
}
if (parmval == error_mark_node)
@ -3517,7 +3517,7 @@ convert_arguments (tree typelist, VEC(tree,gc) **values, tree fndecl,
types. */
val = require_complete_type_sfinae (val, complain);
else
val = convert_arg_to_ellipsis (val);
val = convert_arg_to_ellipsis (val, complain);
VEC_replace (tree, *values, i, val);
}
@ -3543,7 +3543,7 @@ convert_arguments (tree typelist, VEC(tree,gc) **values, tree fndecl,
tree parmval
= convert_default_arg (TREE_VALUE (typetail),
TREE_PURPOSE (typetail),
fndecl, i);
fndecl, i, complain);
if (parmval == error_mark_node)
return -1;
@ -5782,7 +5782,7 @@ check_for_casting_away_constness (tree src_type, tree dest_type,
if (cast == CAST_EXPR && !warn_cast_qual)
return false;
if (!casts_away_constness (src_type, dest_type))
if (!casts_away_constness (src_type, dest_type, complain))
return false;
switch (cast)
@ -5932,7 +5932,8 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p,
&& DERIVED_FROM_P (intype, TREE_TYPE (type))
&& can_convert (build_pointer_type (TYPE_MAIN_VARIANT (intype)),
build_pointer_type (TYPE_MAIN_VARIANT
(TREE_TYPE (type))))
(TREE_TYPE (type))),
complain)
&& (c_cast_p
|| at_least_as_qualified_p (TREE_TYPE (type), intype)))
{
@ -6059,7 +6060,8 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p,
&& can_convert (build_pointer_type (TYPE_MAIN_VARIANT
(TREE_TYPE (intype))),
build_pointer_type (TYPE_MAIN_VARIANT
(TREE_TYPE (type)))))
(TREE_TYPE (type))),
complain))
{
tree base;
@ -6100,7 +6102,7 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p,
t1 = intype;
t2 = type;
}
if (can_convert (t1, t2) || can_convert (t2, t1))
if (can_convert (t1, t2, complain) || can_convert (t2, t1, complain))
{
if (!c_cast_p
&& check_for_casting_away_constness (intype, type,
@ -7301,7 +7303,8 @@ build_ptrmemfunc (tree type, tree pfn, int force, bool c_cast_p,
tree n;
if (!force
&& !can_convert_arg (to_type, TREE_TYPE (pfn), pfn, LOOKUP_NORMAL))
&& !can_convert_arg (to_type, TREE_TYPE (pfn), pfn,
LOOKUP_NORMAL, complain))
error ("invalid conversion to type %qT from type %qT",
to_type, pfn_type);
@ -7566,7 +7569,7 @@ convert_for_assignment (tree type, tree rhs,
We allow bad conversions here because by the time we get to this point
we are committed to doing the conversion. If we end up doing a bad
conversion, convert_like will complain. */
if (!can_convert_arg_bad (type, rhstype, rhs, flags))
if (!can_convert_arg_bad (type, rhstype, rhs, flags, complain))
{
/* When -Wno-pmf-conversions is use, we just silently allow
conversions from pointers-to-members to plain pointers. If
@ -8419,7 +8422,7 @@ cp_apply_type_quals_to_decl (int type_quals, tree decl)
if and only if there is no implicit conversion from T1 to T2. */
static void
casts_away_constness_r (tree *t1, tree *t2)
casts_away_constness_r (tree *t1, tree *t2, tsubst_flags_t complain)
{
int quals1;
int quals2;
@ -8469,7 +8472,7 @@ casts_away_constness_r (tree *t1, tree *t2)
else
*t2 = TREE_TYPE (*t2);
casts_away_constness_r (t1, t2);
casts_away_constness_r (t1, t2, complain);
*t1 = build_pointer_type (*t1);
*t2 = build_pointer_type (*t2);
*t1 = cp_build_qualified_type (*t1, quals1);
@ -8485,7 +8488,7 @@ casts_away_constness_r (tree *t1, tree *t2)
*/
static bool
casts_away_constness (tree t1, tree t2)
casts_away_constness (tree t1, tree t2, tsubst_flags_t complain)
{
if (TREE_CODE (t2) == REFERENCE_TYPE)
{
@ -8497,7 +8500,8 @@ casts_away_constness (tree t1, tree t2)
casts away constness. */
t1 = (TREE_CODE (t1) == REFERENCE_TYPE ? TREE_TYPE (t1) : t1);
return casts_away_constness (build_pointer_type (t1),
build_pointer_type (TREE_TYPE (t2)));
build_pointer_type (TREE_TYPE (t2)),
complain);
}
if (TYPE_PTRMEM_P (t1) && TYPE_PTRMEM_P (t2))
@ -8510,7 +8514,8 @@ casts_away_constness (tree t1, tree t2)
constness. */
return casts_away_constness
(build_pointer_type (TYPE_PTRMEM_POINTED_TO_TYPE (t1)),
build_pointer_type (TYPE_PTRMEM_POINTED_TO_TYPE (t2)));
build_pointer_type (TYPE_PTRMEM_POINTED_TO_TYPE (t2)),
complain);
/* Casting away constness is only something that makes sense for
pointer or reference types. */
@ -8521,8 +8526,8 @@ casts_away_constness (tree t1, tree t2)
/* Top-level qualifiers don't matter. */
t1 = TYPE_MAIN_VARIANT (t1);
t2 = TYPE_MAIN_VARIANT (t2);
casts_away_constness_r (&t1, &t2);
if (!can_convert (t2, t1))
casts_away_constness_r (&t1, &t2, complain);
if (!can_convert (t2, t1, complain))
return true;
return false;

View File

@ -1,8 +1,14 @@
2012-04-24 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/52363
* g++.dg/cpp0x/sfinae35.C: New.
* g++.dg/cpp0x/sfinae36.C: Likewise.
2012-04-24 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
PR target/47197
* gcc.target/powerpc/pr47197.c: New test.
2012-04-24 Richard Guenther <rguenther@suse.de>
PR tree-optimization/53085

View File

@ -0,0 +1,13 @@
// PR c++/52363
// { dg-options -std=c++11 }
#include <type_traits>
struct proxy
{
void operator=(int const&);
void operator=(int&&) const;
};
static_assert( !std::is_assignable<proxy, int>::value, "" );
static_assert( std::is_assignable<const proxy, int>::value, "" );

View File

@ -0,0 +1,13 @@
// PR c++/52363
// { dg-options "-std=c++11 -pedantic" }
#include <type_traits>
struct proxy
{
void operator=(int const&);
void operator=(int&&) const;
};
static_assert( !std::is_assignable<proxy, int>::value, "" );
static_assert( std::is_assignable<const proxy, int>::value, "" );