diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 628f4d1ecf96..3c2858423d33 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,18 @@ 2016-02-10 Jason Merrill + PR c++/68926 + * pt.c (resolve_nondeduced_context): Add complain parm. + (do_auto_deduction): Pass it. + * cvt.c (convert_to_void): Likewise. + * decl.c (cp_finish_decl): Likewise. + * init.c (build_new): Likewise. + * rtti.c (get_tinfo_decl_dynamic): Likewise. + * semantics.c (finish_decltype_type): Likewise. + * typeck.c (decay_conversion): Likewise. + * cp-tree.h: Adjust declaration. + * call.c (standard_conversion): Add complain parm, pass it along. + (implicit_conversion): Pass it. + PR c++/69657 * name-lookup.c (ambiguous_decl): Call remove_hidden_names. (lookup_name_real_1): Likewise. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index ce87be72c14f..cb71176c6ca1 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -190,7 +190,6 @@ static struct z_candidate *add_function_candidate tree, int, tsubst_flags_t); static conversion *implicit_conversion (tree, tree, tree, bool, int, tsubst_flags_t); -static conversion *standard_conversion (tree, tree, tree, bool, int); static conversion *reference_binding (tree, tree, tree, bool, int, tsubst_flags_t); static conversion *build_conv (conversion_kind, tree, conversion *); @@ -1080,7 +1079,7 @@ strip_top_quals (tree t) static conversion * standard_conversion (tree to, tree from, tree expr, bool c_cast_p, - int flags) + int flags, tsubst_flags_t complain) { enum tree_code fcode, tcode; conversion *conv; @@ -1110,7 +1109,7 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p, else if (TREE_CODE (to) == BOOLEAN_TYPE) { /* Necessary for eg, TEMPLATE_ID_EXPRs (c++/50961). */ - expr = resolve_nondeduced_context (expr); + expr = resolve_nondeduced_context (expr, complain); from = TREE_TYPE (expr); } } @@ -1149,7 +1148,8 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p, the standard conversion sequence to perform componentwise conversion. */ conversion *part_conv = standard_conversion - (TREE_TYPE (to), TREE_TYPE (from), NULL_TREE, c_cast_p, flags); + (TREE_TYPE (to), TREE_TYPE (from), NULL_TREE, c_cast_p, flags, + complain); if (part_conv) { @@ -1799,7 +1799,7 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p, if (TREE_CODE (to) == REFERENCE_TYPE) conv = reference_binding (to, from, expr, c_cast_p, flags, complain); else - conv = standard_conversion (to, from, expr, c_cast_p, flags); + conv = standard_conversion (to, from, expr, c_cast_p, flags, complain); if (conv) return conv; diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index ead017edab2a..3b91089f50d0 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6180,7 +6180,7 @@ extern tree get_template_parms_at_level (tree, int); extern tree get_template_innermost_arguments (const_tree); extern tree get_template_argument_pack_elems (const_tree); extern tree get_function_template_decl (const_tree); -extern tree resolve_nondeduced_context (tree); +extern tree resolve_nondeduced_context (tree, tsubst_flags_t); extern hashval_t iterative_hash_template_arg (tree arg, hashval_t val); extern tree coerce_template_parms (tree, tree, tree); extern tree coerce_template_parms (tree, tree, tree, tsubst_flags_t); diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index 60362fd73c49..0d1048cd7fe4 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -1253,7 +1253,7 @@ convert_to_void (tree expr, impl_conv_void implicit, tsubst_flags_t complain) default:; } - expr = resolve_nondeduced_context (expr); + expr = resolve_nondeduced_context (expr, complain); { tree probe = expr; diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 11f7ce615a49..09bd512313b6 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -6575,7 +6575,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, if (TREE_CODE (d_init) == TREE_LIST) d_init = build_x_compound_expr_from_list (d_init, ELK_INIT, tf_warning_or_error); - d_init = resolve_nondeduced_context (d_init); + d_init = resolve_nondeduced_context (d_init, tf_warning_or_error); type = TREE_TYPE (decl) = do_auto_deduction (type, d_init, auto_node, tf_warning_or_error, diff --git a/gcc/cp/init.c b/gcc/cp/init.c index cb2e852fdfc5..338f85e2c7de 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -3364,7 +3364,7 @@ build_new (vec **placement, tree type, tree nelts, if (auto_node) { tree d_init = (**init)[0]; - d_init = resolve_nondeduced_context (d_init); + d_init = resolve_nondeduced_context (d_init, complain); type = do_auto_deduction (type, d_init, auto_node); } } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 76a6019a29e9..a215aa78b4c1 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -18575,7 +18575,7 @@ resolve_overloaded_unification (tree tparms, lvalue for the function template specialization. */ tree -resolve_nondeduced_context (tree orig_expr) +resolve_nondeduced_context (tree orig_expr, tsubst_flags_t complain) { tree expr, offset, baselink; bool addr; @@ -18658,16 +18658,16 @@ resolve_nondeduced_context (tree orig_expr) { tree base = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (offset, 0))); - expr = build_offset_ref (base, expr, addr, tf_warning_or_error); + expr = build_offset_ref (base, expr, addr, complain); } if (addr) - expr = cp_build_addr_expr (expr, tf_warning_or_error); + expr = cp_build_addr_expr (expr, complain); return expr; } - else if (good == 0 && badargs) + else if (good == 0 && badargs && (complain & tf_error)) /* There were no good options and at least one bad one, so let the user know what the problem is. */ - instantiate_template (badfn, badargs, tf_warning_or_error); + instantiate_template (badfn, badargs, complain); } return orig_expr; } @@ -23880,7 +23880,7 @@ do_auto_deduction (tree type, tree init, tree auto_node, if (type == error_mark_node) return error_mark_node; - init = resolve_nondeduced_context (init); + init = resolve_nondeduced_context (init, complain); if (AUTO_IS_DECLTYPE (auto_node)) { diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index a43ff85b8caf..69c39055d8b6 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -242,7 +242,7 @@ get_tinfo_decl_dynamic (tree exp, tsubst_flags_t complain) if (error_operand_p (exp)) return error_mark_node; - exp = resolve_nondeduced_context (exp); + exp = resolve_nondeduced_context (exp, complain); /* peel back references, so they match. */ type = non_reference (TREE_TYPE (exp)); diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index c9f9db4d4108..0cf5f930b1e9 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -8699,7 +8699,7 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p, /* The type denoted by decltype(e) is defined as follows: */ - expr = resolve_nondeduced_context (expr); + expr = resolve_nondeduced_context (expr, complain); if (invalid_nonstatic_memfn_p (input_location, expr, complain)) return error_mark_node; diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index d2c23f42df2f..c9fa11290088 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -1932,7 +1932,7 @@ decay_conversion (tree exp, if (type == error_mark_node) return error_mark_node; - exp = resolve_nondeduced_context (exp); + exp = resolve_nondeduced_context (exp, complain); if (type_unknown_p (exp)) { if (complain & tf_error) diff --git a/gcc/testsuite/g++.dg/cpp0x/sfinae56.C b/gcc/testsuite/g++.dg/cpp0x/sfinae56.C new file mode 100644 index 000000000000..0f954328eb47 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/sfinae56.C @@ -0,0 +1,26 @@ +// PR c++/68926 +// { dg-do compile { target c++11 } } + +struct true_type { static constexpr bool value = true; }; +struct false_type { static constexpr bool value = false; }; + +template struct enable_if { using type = void; }; +template<> struct enable_if { }; + +template struct is_same : false_type { }; +template struct is_same : true_type { }; + +template +typename enable_if::value>::type +func(); + +template)> +true_type test(T); + +false_type test(...); + +int main() +{ + decltype(test(0))::value; // ok + decltype(test(0.f))::value; // error +}