On Thu, Feb 21, 2019 at 03:47:44PM -1000, Jason Merrill wrote: > On 2/21/19 1:35 PM, Marek Polacek wrote: > > We were ICEing because we called build_converted_constant_expr on an > > expression > > that wasn't value-dependent, but it still contained template codes, and that > > didn't work too well because check_narrowing calls maybe_constant_value. > > Hmm, I'm concerned about convert_like_real from > build_converted_constant_expr adding more template codes; you probably want > a processing_template_decl_sentinel after the > instantiate_non_dependent_expr.
OK, that's a good trick. > Also, value_dependent_expression_p should probably be > instantiation_dependent_expression_p. I think I used value_* because that's what build_noexcept_spec had. Also value_dependent_expression_p calls type_dependent_expression_p. But I've changed it anyway. Thanks, Bootstrapped/regtested on x86_64-linux, ok for trunk? 2019-02-22 Marek Polacek <pola...@redhat.com> PR c++/89420 - ICE with CAST_EXPR in explicit-specifier. * decl.c (build_explicit_specifier): Don't check processing_template_decl. Call instantiation_dependent_expression_p instead of value_dependent_expression_p. Call instantiate_non_dependent_expr_sfinae before build_converted_constant_expr instead of calling instantiate_non_dependent_expr after it. Add processing_template_decl_sentinel. * g++.dg/cpp2a/explicit14.C: New test. diff --git gcc/cp/decl.c gcc/cp/decl.c index 612afbacd27..c5b5bd3ce08 100644 --- gcc/cp/decl.c +++ gcc/cp/decl.c @@ -16687,12 +16687,14 @@ require_deduced_type (tree decl, tsubst_flags_t complain) tree build_explicit_specifier (tree expr, tsubst_flags_t complain) { - if (processing_template_decl && value_dependent_expression_p (expr)) + if (instantiation_dependent_expression_p (expr)) /* Wait for instantiation, tsubst_function_decl will handle it. */ return expr; + expr = instantiate_non_dependent_expr_sfinae (expr, complain); + /* Don't let convert_like_real create more template codes. */ + processing_template_decl_sentinel s; expr = build_converted_constant_expr (boolean_type_node, expr, complain); - expr = instantiate_non_dependent_expr (expr); expr = cxx_constant_value (expr); return expr; } diff --git gcc/testsuite/g++.dg/cpp2a/explicit14.C gcc/testsuite/g++.dg/cpp2a/explicit14.C new file mode 100644 index 00000000000..9c3acc32ac4 --- /dev/null +++ gcc/testsuite/g++.dg/cpp2a/explicit14.C @@ -0,0 +1,11 @@ +// PR c++/89420 +// { dg-do compile { target c++2a } } + +template<typename> +struct S { + explicit(int(1)) S(int); + explicit(int{1}) S(int, int); +}; + +S<int> s(1); +S<int> s2(1, 2);