struct S { S(int); }; int id(int v); double id(double v); template<class> auto f(double v) -> decltype(S{id(v)}); GCC 11 correctly issues a narrowing conversion warning for this testcase ever since r11-434: <stdin>:6:50: warning: narrowing conversion of ‘id(v)’ from ‘double’ to ‘int’ [-Wnarrowing] But in GCC 12 the warning is gone.
Confirmed.
r12-6075 is exposing a latent bug with non-dependent decltype folding, namely we instantiate the expression only if it's potentially constant. In this case, id(v) is not potentially constant because id is not a constexpr function, so we discard the expression without actually instantiating it and therefore never issue the narrowing warning.
(In reply to Patrick Palka from comment #2) > r12-6075 Patrick, can you please start using latest git gcc-descr version: gcc-descr = "!f() { \"`git rev-parse --show-toplevel`/contrib/git-descr.sh\" $@; } ; f" gcc-undescr = "!f() { \"`git rev-parse --show-toplevel`/contrib/git-undescr.sh\" $@; } ; f" So that hashes are appended to revisions: $ git gcc-descr r12-7534-g7cce7b1c3d8291 Thanks
The master branch has been updated by Patrick Palka <ppalka@gcc.gnu.org>: https://gcc.gnu.org/g:ec0f53a3a542e762f8fc8c22b9d345f922be5867 commit r12-7564-gec0f53a3a542e762f8fc8c22b9d345f922be5867 Author: Patrick Palka <ppalka@redhat.com> Date: Wed Mar 9 08:42:37 2022 -0500 c++: non-constant non-dependent decltype folding [PR104823] When processing a non-dependent decltype operand we want to instantiate it even if it's non-constant, since non-dependent decltype is always resolved ahead of time. But currently finish_decltype_type uses instantiate_non_dependent_expr, which instantiates only potentially constant expressions, and this causes us to miss diagnosing the narrowing conversion in S{id(v)} in the below testcase because we never instantiate this non-constant non-dependent decltype operand. In light of > On Mon, 7 Mar 2022, Jason Merrill wrote: >> On 3/7/22 14:41, Patrick Palka wrote: >>> instantiate_non_dependent_expr instantiates only potentially constant >>> expressions >> >> Hmm, that now strikes me as a problematic interface, as we don't know whether >> what we get back is template or non-template trees. this patch drops the potentially-constant check in i_n_d_e and turns its dependence check into a checking_assert, since most callers already check that the argument is non-dependent; thus i_n_d_e now instantiates even non-constant expressions and always returns non-templated trees. This patch also relaxes the dependence check in i_n_d_e to use the _uneval version (since that's what finish_decltype_type uses) and strengthens the dependence checks used by other callers accordingly. In cp_parser_parenthesized_expression_list_elt we were calling instantiate_non_dependent_expr (when parsing an attribute list) without first checking for non-dependence. We could fix this by guarding the call appropriately, but I noticed we also fold non-dependent attributes later from cp_check_const_attribute, so this earlier folding is at best redundant. And it currently causes us to reject constexpr-attribute4.C below due to the second folding seeing non-templated trees. Thus the right solution here seems to be to remove this unguarded call to i_n_d_e so that we end up instantiating non-dependent attributes only once. Finally, after calling i_n_d_e in finish_decltype_type we need to keep processing_template_decl cleared for sake of the later call to lvalue_kind, which handles templated and non-templated COND_EXPR differently. Otherwise we'd incorrectly reject the declaration of g in cpp0x/cond2.C with: error: 'g' declared as function returning a function PR c++/104823 gcc/cp/ChangeLog: * except.cc (build_noexcept_spec): Strengthen dependence check to instantiation_dependent_expression_p. * parser.cc (cp_parser_parenthesized_expression_list_elt): Remove fold_expr_p parameter, and don't call instantiate_non_dependent_expr. (cp_parser_parenthesized_expression_list): Adjust accordingly. * pt.cc (expand_integer_pack): Strengthen dependence check to instantiation_dependent_expression_p. (instantiate_non_dependent_expr_internal): Adjust comment. (instantiate_non_dependent_expr_sfinae): Likewise. Drop the potentially-constant check, and relax and turn the dependence check into a checking assert. (instantiate_non_dependent_or_null): Adjust comment. * semantics.cc (finish_decltype_type): Keep processing_template_decl cleared after calling instantiate_non_dependent_expr_sfinae. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/Wnarrowing19.C: New test.
Fixed.