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; + } + else + { + cond = instantiate_non_dependent_expr (cond); + cond = cxx_constant_value (cond, NULL_TREE); + } } finish_cond (&IF_COND (if_stmt), cond); add_stmt (if_stmt); 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) { }; // { dg-error "overloaded function" } +} Marek