The issue here is that we try to determine the EH specification of
B::C::C() from within SFINAE context, and we can't determine it yet
because the NSDMI for B::C::i hasn't been parsed yet. This patch
allows that determination to fail quietly in SFINAE context; we'll try
again the next time it is needed.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit 616193fb149d17e8a671a46c03dca98aecbcc752
Author: Jason Merrill
Date: Tue Aug 8 12:49:42 2017 -0400
PR c++/81359 - Unparsed NSDMI error from SFINAE context.
* init.c (get_nsdmi): Add complain parm.
* typeck2.c (digest_nsdmi_init): Add complain parm.
(process_init_constructor_record): Pass complain to get_nsdmi.
* pt.c (maybe_instantiate_noexcept): Add complain parm, return bool.
* method.c (get_defaulted_eh_spec): Add complain parm. Pass it into
synthesized_method_walk.
(synthesized_method_walk): Adjust.
(walk_field_subobs): Pass complain to get_nsdmi.
(defaulted_late_check): Skip other checks if deleted.
* decl2.c (mark_used): Pass complain to maybe_instantiate_noexcept.
* call.c (build_aggr_conv): Pass complain to get_nsdmi.
* parser.c (defarg_location): New.
* error.c (location_of): Use it.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index fdd3731..4903119 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -916,7 +916,7 @@ build_aggr_conv (tree type, tree ctor, int flags,
tsubst_flags_t complain)
if (i < CONSTRUCTOR_NELTS (ctor))
val = CONSTRUCTOR_ELT (ctor, i)->value;
else if (DECL_INITIAL (field))
- val = get_nsdmi (field, /*ctor*/false);
+ val = get_nsdmi (field, /*ctor*/false, complain);
else if (TREE_CODE (ftype) == REFERENCE_TYPE)
/* Value-initialization of reference is ill-formed. */
return NULL;
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 508570b..94738bd 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -8093,8 +8093,9 @@ resolve_address_of_overloaded_function (tree target_type,
continue;
/* In C++17 we need the noexcept-qualifier to compare types. */
- if (flag_noexcept_type)
- maybe_instantiate_noexcept (fn);
+ if (flag_noexcept_type
+ && !maybe_instantiate_noexcept (fn, complain))
+ continue;
/* See if there's a match. */
tree fntype = static_fn_type (fn);
@@ -8176,7 +8177,7 @@ resolve_address_of_overloaded_function (tree target_type,
/* In C++17 we need the noexcept-qualifier to compare types. */
if (flag_noexcept_type)
- maybe_instantiate_noexcept (instantiation);
+ maybe_instantiate_noexcept (instantiation, complain);
/* See if there's a match. */
tree fntype = static_fn_type (instantiation);
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 115cdaf..3a0bd16 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -6297,7 +6297,7 @@ extern tree get_type_value(tree);
extern tree build_zero_init(tree, tree, bool);
extern tree build_value_init (tree, tsubst_flags_t);
extern tree build_value_init_noctor(tree, tsubst_flags_t);
-extern tree get_nsdmi (tree, bool);
+extern tree get_nsdmi (tree, bool, tsubst_flags_t);
extern tree build_offset_ref (tree, tree, bool,
tsubst_flags_t);
extern tree throw_bad_array_new_length (void);
@@ -6355,7 +6355,7 @@ extern bool trivial_fn_p (tree);
extern tree forward_parm (tree);
extern bool is_trivially_xible (enum tree_code, tree, tree);
extern bool is_xible (enum tree_code, tree, tree);
-extern tree get_defaulted_eh_spec (tree);
+extern tree get_defaulted_eh_spec (tree, tsubst_flags_t =
tf_warning_or_error);
extern void after_nsdmi_defaulted_late_checks (tree);
extern bool maybe_explain_implicit_delete (tree);
extern void explain_implicit_non_constexpr (tree);
@@ -6385,6 +6385,7 @@ extern tree cp_convert_range_for (tree, tree, tree, tree,
unsigned int, bool);
extern bool parsing_nsdmi (void);
extern bool parsing_default_capturing_generic_lambda_in_template (void);
extern void inject_this_parameter (tree, cp_cv_quals);
+extern location_t defarg_location (tree);
/* in pt.c */
extern bool check_template_shadow (tree);
@@ -6448,7 +6449,7 @@ extern int more_specialized_fn(tree,
tree, int);
extern void do_decl_instantiation (tree, tree);
extern void do_type_instantiation (tree, tree, tsubst_flags_t);
extern bool always_instantiate_p (tree);
-extern void maybe_instantiate_noexcept (tree);
+extern bool maybe_instan