On 3/8/21 7:34 PM, Marek Polacek wrote:
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?
OK. I tried Martin's testcase, and get the expected
wa.C:2:35: error: narrowing conversion of ‘256’ from ‘long unsigned int’
to ‘char’ [-Wnarrowing]
Don't you?
Jason
-- >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