On Thu, Oct 11, 2018 at 11:35:23AM -0400, Jason Merrill wrote: > > + /* [dcl.fct.spec] > > + "the constant-expression, if supplied, shall be a contextually > > + converted constant expression of type bool." */ > > + expr = build_explicit_specifier (expr, tf_warning_or_error); > > + /* We could evaluate it -- mark the decl as appropriate. */ > > + if (expr == boolean_true_node) > > + set_and_check_decl_spec_loc (decl_specs, ds_explicit, token); > > + else if (explicit_specifier) > > + /* The expression was value-dependent. Remember it so that we can > > + substitute it later. */ > > + *explicit_specifier = expr; > > What if expr == boolean_false_node?
Then we proceed like no explicit was present and the decl isn't marked as explicit/nonconverting. Perhaps I could have made this clearer with else if (expr == boolean_true_node) /* Don't mark the decl as explicit. */; or somesuch. > > + /* Handle explicit(dependent-expr). */ > > + if (DECL_HAS_DEPENDENT_EXPLICIT_SPEC_P (t)) > > + { > > + tree spec = lookup_explicit_specifier (t); > > + spec = tsubst_copy_and_build (spec, args, complain, in_decl, > > + /*function_p=*/false, > > + /*i_c_e_p=*/true); > > + spec = build_explicit_specifier (spec, complain); > > + DECL_NONCONVERTING_P (t) = (spec == boolean_true_node); > > + } > > What if spec is still dependent, e.g. after partial substitution of a > member template? Something like this? template<typename> struct A { template<typename T, int N = 0> explicit(N) operator T(); }; void bar () { A<int> a; int i = a; } This also seemed to work: if spec is still dependent, the decl isn't marked as DECL_NONCONVERTING_P, and we'll try again after deduction (fn_type_unification in add_template_candidate). Marek