On 3/25/21 3:02 PM, Marek Polacek wrote:
On Tue, Mar 23, 2021 at 04:59:53PM -0400, Jason Merrill via Gcc-patches wrote:
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.
Thanks, pushed.
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?
Huh, I really don't:
$ ./cc1plus -quiet q.C -Wall -W -pedantic -Wnarrowing
# nothing
How can that be?
Ah, it was because I still had in my tree my experimental change to use
IMPLICIT_CONV more broadly:
It looks like we warned for this testcase in 4.6 and 4.7.
Jason
>From d5f8f390392f8f78902061d191a77a486ce70751 Mon Sep 17 00:00:00 2001
From: Jason Merrill <ja...@redhat.com>
Date: Fri, 19 Mar 2021 05:45:01 -0400
Subject: [PATCH] more-implicit-conv
To: gcc-patches@gcc.gnu.org
---
gcc/cp/call.c | 28 ++--------------------------
1 file changed, 2 insertions(+), 26 deletions(-)
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 390b8aa4325..4e22d9a4c3f 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -8048,27 +8048,6 @@ convert_like_internal (conversion *convs, tree expr, tree fn, int argnum,
return expr;
}
-/* Return true if converting FROM to TO is unsafe in a template. */
-
-static bool
-conv_unsafe_in_template_p (tree to, tree from)
-{
- /* Converting classes involves TARGET_EXPR. */
- if (CLASS_TYPE_P (to) || CLASS_TYPE_P (from))
- return true;
-
- /* Converting real to integer produces FIX_TRUNC_EXPR which tsubst
- doesn't handle. */
- if (SCALAR_FLOAT_TYPE_P (from) && INTEGRAL_OR_ENUMERATION_TYPE_P (to))
- return true;
-
- /* Converting integer to real isn't a trivial conversion, either. */
- if (INTEGRAL_OR_ENUMERATION_TYPE_P (from) && SCALAR_FLOAT_TYPE_P (to))
- return true;
-
- return false;
-}
-
/* Wrapper for convert_like_internal that handles creating
IMPLICIT_CONV_EXPR. */
@@ -8084,14 +8063,11 @@ convert_like (conversion *convs, tree expr, tree fn, int argnum,
function. */
tree conv_expr = NULL_TREE;
if (processing_template_decl
- && convs->kind != ck_identity
- && conv_unsafe_in_template_p (convs->type, TREE_TYPE (expr)))
+ && CONVERSION_RANK (convs) > cr_identity)
{
conv_expr = build1 (IMPLICIT_CONV_EXPR, convs->type, expr);
if (convs->kind != ck_ref_bind)
conv_expr = convert_from_reference (conv_expr);
- if (!convs->bad_p)
- return conv_expr;
/* Do the normal processing to give the bad_p errors. But we still
need to return the IMPLICIT_CONV_EXPR, unless we're returning
error_mark_node. */
@@ -8100,7 +8076,7 @@ convert_like (conversion *convs, tree expr, tree fn, int argnum,
issue_conversion_warnings, c_cast_p, complain);
if (expr == error_mark_node)
return error_mark_node;
- return conv_expr ? conv_expr : expr;
+ return (conv_expr && !TREE_CONSTANT (expr)) ? conv_expr : expr;
}
/* Convenience wrapper for convert_like. */
--
2.27.0