On Fri, Mar 05, 2021 at 05:03:45PM -0500, Jason Merrill wrote: > On 3/4/21 9:37 PM, Marek Polacek wrote: > > This PR complains that we issue a -Wconversion warning in > > > > template <int N> struct X {}; > > template <class T> X<sizeof(T)> foo(); > > > > saying "conversion from 'long unsigned int' to 'int' may change value". > > While it's not technically wrong, I suspect -Wconversion warnings aren't > > all that useful for value-dependent expressions. So this patch disables > > them, though I'm open to other ideas. > > How about suppressing -Wconversion in > build_converted_constant_expr_internal? If the size_t value ended up being > too large for the int parameter, we would give an error about overflow in a > constant expression, not just a warning.
That works for me too. As you say, if we convert to a type that cannot represent all the values of the original type, we give a pedantic-error warning in check_narrowing. I've slightly enhanced the test, too. Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/10? -- >8 -- This PR complains that we issue a -Wconversion warning in template <int N> struct X {}; template <class T> X<sizeof(T)> foo(); saying "conversion from 'long unsigned int' to 'int' may change value". While it's not technically wrong, I suspect -Wconversion warnings aren't all that useful for value-dependent expressions. So this patch disables them. This is a regression that started with r241425: @@ -7278,7 +7306,7 @@ convert_template_argument (tree parm, val = error_mark_node; } } - else if (!dependent_template_arg_p (orig_arg) + else if (!type_dependent_expression_p (orig_arg) && !uses_template_parms (t)) /* We used to call digest_init here. However, digest_init will report errors, which we don't want when complain Here orig_arg is SIZEOF_EXPR<T>; dependent_template_arg_p (orig_arg) was true, but type_dependent_expression_p (orig_arg) is false so we warn in convert_nontype_argument. gcc/cp/ChangeLog: PR c++/99331 * call.c (build_converted_constant_expr_internal): Don't emit -Wconversion warnings. gcc/testsuite/ChangeLog: PR c++/99331 * g++.dg/warn/Wconversion5.C: New test. --- gcc/cp/call.c | 3 +++ gcc/testsuite/g++.dg/warn/Wconversion5.C | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 gcc/testsuite/g++.dg/warn/Wconversion5.C diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 7d12fea60f2..55d7e71c0c9 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -4484,6 +4484,9 @@ build_converted_constant_expr_internal (tree type, tree expr, && processing_template_decl) conv = next_conversion (conv); + /* Issuing conversion warnings for value-dependent expressions is + likely too noisy. */ + warning_sentinel w (warn_conversion); conv->check_narrowing = true; conv->check_narrowing_const_only = true; expr = convert_like (conv, expr, complain); diff --git a/gcc/testsuite/g++.dg/warn/Wconversion5.C b/gcc/testsuite/g++.dg/warn/Wconversion5.C new file mode 100644 index 00000000000..f5ae6312bc5 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wconversion5.C @@ -0,0 +1,19 @@ +// PR c++/99331 +// { dg-do compile { target c++11 } } +// { dg-options "-Wconversion" } +// Don't issue -Wconversion warnings for value-dependent expressions. + +template <int> struct X {}; +template <signed char> struct Y {}; +template <typename T> X<sizeof(T)> foo(); +template <typename T> X<alignof(T)> foo2(); +template<int I> Y<I> foo3(); +template<int> Y<1024> foo4(); // { dg-error "narrowing conversion" } +template<int> Y<1u> foo5(); +template<int> X<__INT_MAX__ + 1U> foo6(); // { dg-error "narrowing conversion" } + +template <typename T> +struct S { + using t = X<sizeof(T)>; + using u = X<alignof(T)>; +}; base-commit: bd85b4dd2dd7b00b6342ed1e33fb48035a3dcb61 -- 2.29.2