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

Reply via email to