On Wed, Mar 14, 2018 at 02:06:36PM -0400, Jason Merrill wrote: > On Wed, Mar 14, 2018 at 11:59 AM, Marek Polacek <pola...@redhat.com> wrote: > > cxx_constant_value doesn't understand template codes, and neither it > > understands OVERLOADs, so if we pass an OVERLOAD to it, we crash. Here > > instantiate_non_dependent_expr got an OVERLOAD, but since it calls > > is_nondependent_constant_expression which checks type_unknown_p, it left the > > expression as it was. We can't use is_nondependent_constant_expression in > > finish_if_stmt_cond because i_n_c_e checks is_constant_expression and that > > is > > not suitable here; we'd miss diagnostics. So I did the following; I think > > we > > should reject the testcase with an error. > > > > Bootstrapped/regtested on x86_64-linux, ok for trunk? > > > > 2018-03-14 Marek Polacek <pola...@redhat.com> > > > > PR c++/84854 > > * semantics.c (finish_if_stmt_cond): Give error if the condition > > is an overloaded function with no contextual type information. > > > > * g++.dg/cpp1z/constexpr-if15.C: New test. > > > > diff --git gcc/cp/semantics.c gcc/cp/semantics.c > > index fdf37bea770..a056e9445e9 100644 > > --- gcc/cp/semantics.c > > +++ gcc/cp/semantics.c > > @@ -735,8 +735,16 @@ finish_if_stmt_cond (tree cond, tree if_stmt) > > && require_constant_expression (cond) > > && !value_dependent_expression_p (cond)) > > { > > - cond = instantiate_non_dependent_expr (cond); > > - cond = cxx_constant_value (cond, NULL_TREE); > > + if (type_unknown_p (cond)) > > + { > > + cxx_incomplete_type_error (cond, TREE_TYPE (cond)); > > + cond = error_mark_node; > > I think I'd prefer to skip this block when type_unknown_p, and leave > error handling up to the code shared with regular if.
Like this? It was my first version, but I thought we wanted the error; the following rejects the testcase only when instantiating the template function. Which is fine by me, too. Bootstrapped/regtested on x86_64-linux, ok for trunk? 2018-03-15 Marek Polacek <pola...@redhat.com> PR c++/84854 * semantics.c (finish_if_stmt_cond): Check type_unknown_p. * g++.dg/cpp1z/constexpr-if15.C: New test. diff --git gcc/cp/semantics.c gcc/cp/semantics.c index fdf37bea770..753a5f4d4f8 100644 --- gcc/cp/semantics.c +++ gcc/cp/semantics.c @@ -733,7 +733,8 @@ finish_if_stmt_cond (tree cond, tree if_stmt) if (IF_STMT_CONSTEXPR_P (if_stmt) && !type_dependent_expression_p (cond) && require_constant_expression (cond) - && !value_dependent_expression_p (cond)) + && !value_dependent_expression_p (cond) + && !type_unknown_p (cond)) { cond = instantiate_non_dependent_expr (cond); cond = cxx_constant_value (cond, NULL_TREE); diff --git gcc/testsuite/g++.dg/cpp1z/constexpr-if15.C gcc/testsuite/g++.dg/cpp1z/constexpr-if15.C index e69de29bb2d..c819b3e3a07 100644 --- gcc/testsuite/g++.dg/cpp1z/constexpr-if15.C +++ gcc/testsuite/g++.dg/cpp1z/constexpr-if15.C @@ -0,0 +1,11 @@ +// PR c++/84854 +// { dg-options -std=c++17 } + +constexpr int foo () { return 1; } +constexpr int foo (int) { return 2; } + +template <typename> +void a() +{ + if constexpr(foo) { }; +} Marek