===================================================================
@@ -6439,7 +6439,7 @@ convert_default_arg (tree type, tree arg, tree fn,
push_defarg_context (fn);
if (fn && DECL_TEMPLATE_INFO (fn))
- arg = tsubst_default_argument (fn, type, arg);
+ arg = tsubst_default_argument (fn, type, arg, complain);
/* Due to:
===================================================================
@@ -5222,7 +5222,7 @@ extern tree static_fn_type (tree);
extern void revert_static_member_fn (tree);
extern void fixup_anonymous_aggr (tree);
extern tree compute_array_index_type (tree, tree, tsubst_flags_t);
-extern tree check_default_argument (tree, tree);
+extern tree check_default_argument (tree, tree, tsubst_flags_t);
typedef int (*walk_namespaces_fn) (tree, void *);
extern int walk_namespaces (walk_namespaces_fn,
void *);
@@ -5504,7 +5504,8 @@ extern tree maybe_process_partial_specialization (
extern tree most_specialized_instantiation (tree);
extern void print_candidates (tree);
extern void instantiate_pending_templates (int);
-extern tree tsubst_default_argument (tree, tree, tree);
+extern tree tsubst_default_argument (tree, tree, tree,
+ tsubst_flags_t);
extern tree tsubst (tree, tree, tsubst_flags_t, tree);
extern tree tsubst_copy_and_build (tree, tree, tsubst_flags_t,
tree, bool, bool);
===================================================================
@@ -10883,7 +10883,7 @@ local_variable_p_walkfn (tree *tp, int *walk_subtr
DECL, if there is no DECL available. */
tree
-check_default_argument (tree decl, tree arg)
+check_default_argument (tree decl, tree arg, tsubst_flags_t complain)
{
tree var;
tree decl_type;
@@ -10915,13 +10915,14 @@ tree
A default argument expression is implicitly converted to the
parameter type. */
++cp_unevaluated_operand;
- perform_implicit_conversion_flags (decl_type, arg, tf_warning_or_error,
+ perform_implicit_conversion_flags (decl_type, arg, complain,
LOOKUP_IMPLICIT);
--cp_unevaluated_operand;
if (warn_zero_as_null_pointer_constant
&& TYPE_PTR_OR_PTRMEM_P (decl_type)
&& null_ptr_cst_p (arg)
+ && (complain & tf_warning)
&& maybe_warn_zero_as_null_pointer_constant (arg, input_location))
return nullptr_node;
@@ -10935,10 +10936,14 @@ tree
var = cp_walk_tree_without_duplicates (&arg, local_variable_p_walkfn, NULL);
if (var)
{
- if (DECL_NAME (var) == this_identifier)
- permerror (input_location, "default argument %qE uses %qD", arg, var);
- else
- error ("default argument %qE uses local variable %qD", arg, var);
+ if (complain & tf_warning_or_error)
+ {
+ if (DECL_NAME (var) == this_identifier)
+ permerror (input_location, "default argument %qE uses %qD",
+ arg, var);
+ else
+ error ("default argument %qE uses local variable %qD", arg, var);
+ }
return error_mark_node;
}
@@ -11089,7 +11094,7 @@ grokparms (tree parmlist, tree *parms)
if (any_error)
init = NULL_TREE;
else if (init && !processing_template_decl)
- init = check_default_argument (decl, init);
+ init = check_default_argument (decl, init, tf_warning_or_error);
}
DECL_CHAIN (decl) = decls;
===================================================================
@@ -22996,7 +22999,8 @@ cp_parser_late_parse_one_default_arg (cp_parser *p
/* In a non-template class, check conversions now. In a template,
we'll wait and instantiate these as needed. */
if (TREE_CODE (decl) == PARM_DECL)
- parsed_arg = check_default_argument (parmtype, parsed_arg);
+ parsed_arg = check_default_argument (parmtype, parsed_arg,
+ tf_warning_or_error);
else
{
int flags = LOOKUP_IMPLICIT;
===================================================================
@@ -184,7 +184,7 @@ static int coerce_template_template_parms (tree, t
tree, tree);
static bool template_template_parm_bindings_ok_p (tree, tree);
static int template_args_equal (tree, tree);
-static void tsubst_default_arguments (tree);
+static void tsubst_default_arguments (tree, tsubst_flags_t);
static tree for_each_template_parm_r (tree *, int *, void *);
static tree copy_default_args_to_explicit_spec_1 (tree, tree);
static void copy_default_args_to_explicit_spec (tree);
@@ -9875,7 +9875,7 @@ tsubst_aggr_type (tree t,
FN), which has the indicated TYPE. */
tree
-tsubst_default_argument (tree fn, tree type, tree arg)
+tsubst_default_argument (tree fn, tree type, tree arg, tsubst_flags_t complain)
{
tree saved_class_ptr = NULL_TREE;
tree saved_class_ref = NULL_TREE;
@@ -9915,7 +9915,7 @@ tree
stack. */
++function_depth;
arg = tsubst_expr (arg, DECL_TI_ARGS (fn),
- tf_warning_or_error, NULL_TREE,
+ complain, NULL_TREE,
/*integral_constant_expression_p=*/false);
--function_depth;
pop_deferring_access_checks();
@@ -9927,12 +9927,13 @@ tree
cp_function_chain->x_current_class_ref = saved_class_ref;
}
- if (errorcount+sorrycount > errs)
+ if (errorcount+sorrycount > errs
+ && (complain & tf_warning_or_error))
inform (input_location,
" when instantiating default argument for call to %D", fn);
/* Make sure the default argument is reasonable. */
- arg = check_default_argument (type, arg);
+ arg = check_default_argument (type, arg, complain);
pop_access_scope (fn);
@@ -9942,7 +9943,7 @@ tree
/* Substitute into all the default arguments for FN. */
static void
-tsubst_default_arguments (tree fn)
+tsubst_default_arguments (tree fn, tsubst_flags_t complain)
{
tree arg;
tree tmpl_args;
@@ -9963,7 +9964,8 @@ static void
if (TREE_PURPOSE (arg))
TREE_PURPOSE (arg) = tsubst_default_argument (fn,
TREE_VALUE (arg),
- TREE_PURPOSE (arg));
+ TREE_PURPOSE (arg),
+ complain);
}
/* Substitute the ARGS into the T, which is a _DECL. Return the
@@ -10323,7 +10325,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t com
if (!member
&& !PRIMARY_TEMPLATE_P (gen_tmpl)
&& !uses_template_parms (argvec))
- tsubst_default_arguments (r);
+ tsubst_default_arguments (r, complain);
}
else
DECL_TEMPLATE_INFO (r) = NULL_TREE;
===================================================================
@@ -0,0 +1,17 @@
+// { dg-options "-std=c++11 -Wall -Wextra" }
+
+template<class T>
+void f(T t, void* = 0) // { dg-warning "unused parameter" }
+{
+}
+
+template<class T>
+auto g(T t) -> decltype(f(t))
+{
+ f(t);
+}
+
+int main()
+{
+ g(0);
+}