PING: Wconversion: fixes for C++ front-end

Manuel López-Ibáñez lopezibanez@gmail.com
Sat Mar 17 05:06:00 GMT 2007


Committed as revision 123005.

On 16 Mar 2007 05:59:34 -0500, Gabriel Dos Reis <gdr@cs.tamu.edu> wrote:
> "Richard Guenther" <richard.guenther@gmail.com> writes:
>
> | On 3/16/07, Manuel López-Ibáñez <lopezibanez@gmail.com> wrote:
> | > On 16/03/07, gdr@cs.tamu.edu <gdr@cs.tamu.edu> wrote:
> | > > Quoting Manuel López-Ibáñez <lopezibanez@gmail.com>:
> | > >
> | > > > Updated to resolve conflicts, re-bootstrapped and re-regression re-tested.
> | > > >
> | > > > OK for mainline?
> | > >
> | > > Yes.
> | > >
> | >
> | > I am sorry Gabriel to pester you but Dirk changes broke my patch and I
> | > have to resolve some conflicts, do you want me to send them again or I
> | > can just commit them after bootstrapping+testing?
> |
> | You should always re-post the patch you committed if there are significant
> | changes.  The approval should still hold though.
>
> Agreed.
>
> Thanks,
>
> -- Gaby
>
-------------- next part --------------
Index: gcc/doc/invoke.texi
===================================================================
--- gcc/doc/invoke.texi	(revision 123004)
+++ gcc/doc/invoke.texi	(revision 123005)
@@ -3396,6 +3396,12 @@
 ((int) x)} and @code{ui = (unsigned) -1}, or if the value is not
 changed by the conversion like in @code{abs (2.0)}.
 
+For C++, also warn for conversions between @code{NULL} and non-pointer
+types; confusing overload resolution for user-defined conversions; and
+conversions that will never use a type conversion operator:
+conversions to @code{void}, the same type, a base class or a reference
+to them.
+
 @item -Wempty-body
 @opindex Wempty-body
 An empty body occurs in an @samp{if}, @samp{else} or @samp{do while}
Index: gcc/ChangeLog
===================================================================
--- gcc/ChangeLog	(revision 123004)
+++ gcc/ChangeLog	(revision 123005)
@@ -1,3 +1,10 @@
+2007-03-16  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
+
+	* doc/invoke.texi (-Wconversion): Document warnings specific to C++.
+	* c-common.c (convert_and_check): Move warning logic to...
+	(warnings_for_convert_and_check): ...here. Define.
+	* c-common.h (warnings_for_convert_and_check): Declare.
+	
 2007-03-16  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
 
 	* pa.c (attr_length_call): Partially revert change of 2007-03-09.
Index: gcc/testsuite/ChangeLog
===================================================================
--- gcc/testsuite/ChangeLog	(revision 123004)
+++ gcc/testsuite/ChangeLog	(revision 123005)
@@ -1,3 +1,10 @@
+2007-03-16  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
+
+	* g++.dg/warn/Wconversion-integer.C: New
+	* g++.dg/warn/Wconversion-real.C: New.
+	* g++.dg/warn/Wconversion-real-integer.C: New.
+	* g++.dg/warn/conv2.C: Updated.
+	
 2007-03-16  Richard Sandiford  <richard@codesourcery.com>
 
 	* gcc.dg/intmax_t-1.c: Restrict XFAIL to VxWorks kernels;
Index: gcc/testsuite/g++.dg/warn/Wconversion-real-integer.C
===================================================================
--- gcc/testsuite/g++.dg/warn/Wconversion-real-integer.C	(revision 0)
+++ gcc/testsuite/g++.dg/warn/Wconversion-real-integer.C	(revision 123005)
@@ -0,0 +1,73 @@
+/* Test for diagnostics for Wconversion between floating-point and
+   integers. C++ equivalent of
+   gcc/testsuite/gcc.dg/Wconversion-real-integer.c */
+
+/* { dg-do compile }
+/* { dg-options "-Wconversion" } */
+
+#include <limits.h>
+
+void fsi (signed int x);
+void fui (unsigned int x);
+void ffloat (float x);
+void fdouble (double x);
+
+float  vfloat;
+double vdouble;
+
+void h (void)
+{
+  unsigned int ui = 3;
+  int   si = 3;
+  unsigned char uc = 3;
+  signed char sc = 3;
+  float  f = 3;
+  double d = 3;
+
+  fsi (3.1f); /* { dg-warning "conversion" } */
+  si = 3.1f; /* { dg-warning "conversion" } */
+  fsi (3.1);  /* { dg-warning "conversion" } */
+  si = 3.1;  /* { dg-warning "conversion" } */
+  fsi (d);    /* { dg-warning "conversion" } */
+  si = d;    /* { dg-warning "conversion" } */
+  fui (-1.0); /* { dg-warning "overflow" } */
+  ui = -1.0;   /* { dg-warning "overflow" } */
+  ffloat (INT_MAX);  /* { dg-warning "conversion" } */
+  vfloat = INT_MAX;  /* { dg-warning "conversion" } */
+  ffloat (16777217); /* { dg-warning "conversion" } */
+  vfloat = 16777217; /* { dg-warning "conversion" } */
+  ffloat (si); /* { dg-warning "conversion" } */
+  vfloat = si; /* { dg-warning "conversion" } */
+  ffloat (ui); /* { dg-warning "conversion" } */
+  vfloat = ui; /* { dg-warning "conversion" } */
+
+  fsi (3);
+  si = 3;
+  fsi (3.0f);
+  si = 3.0f;
+  fsi (3.0);
+  si = 3.0;
+  fsi (16777217.0f);
+  si = 16777217.0f;
+  fsi ((int) 3.1);
+  si = (int) 3.1;
+  ffloat (3U);
+  vfloat = 3U;
+  ffloat (3);
+  vfloat = 3;
+  ffloat (INT_MIN);
+  vfloat = INT_MIN;
+  ffloat (uc);
+  vfloat = uc;
+  ffloat (sc);
+  vfloat = sc;
+
+  fdouble (UINT_MAX);
+  vdouble = UINT_MAX;
+  fdouble (ui);
+  vdouble = ui;
+  fdouble (si);
+  vdouble = si;
+}
+
+
Index: gcc/testsuite/g++.dg/warn/Wconversion-real.C
===================================================================
--- gcc/testsuite/g++.dg/warn/Wconversion-real.C	(revision 0)
+++ gcc/testsuite/g++.dg/warn/Wconversion-real.C	(revision 123005)
@@ -0,0 +1,85 @@
+/* Test for diagnostics for Wconversion for floating-point.  
+   C++ equivalent of gcc/testsuite/gcc.dg/Wconversion-real.c */
+
+/* { dg-do compile }
+/* { dg-options "-Wconversion" } */
+
+float  vfloat;
+double vdouble;
+long double vlongdouble;
+
+void ffloat (float f);
+void fdouble (double d);
+void flongdouble (long double ld);
+
+void h (void)
+{
+  float f = 0;
+  double d = 0;
+  long double ld = 0;
+
+  ffloat (3.1); /* { dg-warning "conversion" } */
+  vfloat = 3.1; /* { dg-warning "conversion" } */
+  ffloat (3.1L); /* { dg-warning "conversion" } */
+  vfloat = 3.1L;  /* { dg-warning "conversion" } */
+  fdouble (3.1L); /* { dg-warning "conversion" "" { target large_long_double } } */
+  vdouble = 3.1L; /* { dg-warning "conversion" "" { target large_long_double } } */
+  ffloat (vdouble); /* { dg-warning "conversion" } */
+  vfloat = vdouble; /* { dg-warning "conversion" } */
+  ffloat (vlongdouble); /* { dg-warning "conversion" } */
+  vfloat = vlongdouble; /* { dg-warning "conversion" } */
+  fdouble (vlongdouble); /* { dg-warning "conversion" "" { target large_long_double } } */
+  vdouble = vlongdouble; /* { dg-warning "conversion" "" { target large_long_double } } */
+
+
+  ffloat ((float) 3.1); 
+  vfloat = (float) 3.1;
+  ffloat ((float) 3.1L);
+  vfloat = (float) 3.1L; 
+  fdouble ((double) 3.1L); 
+  vdouble = (double) 3.1L; 
+  ffloat ((float) vdouble); 
+  vfloat = (float) vdouble; 
+  ffloat ((float) vlongdouble); 
+  vfloat = (float) vlongdouble;
+  fdouble ((double) vlongdouble);
+  vdouble = (double) vlongdouble;
+
+
+  ffloat (3.0);
+  vfloat = 3.0;
+  ffloat (3.1f);
+  vfloat = 3.1f;
+  ffloat (0.25L);
+  vfloat = 0.25L;
+
+
+  fdouble (3.0);
+  vdouble = 3.0;
+  fdouble (3.1f);
+  vdouble = 3.1f;
+  fdouble (0.25L);
+  vdouble = 0.25L;
+
+  flongdouble (3.0);
+  vlongdouble = 3.0;
+  flongdouble (3.1f);
+  vlongdouble = 3.1f;
+  flongdouble (0.25L);
+  vlongdouble = 0.25L;
+
+  ffloat (f);
+  vfloat = f;
+  fdouble (f);
+  vdouble = f;
+  fdouble (d);
+  vdouble = d;
+  flongdouble (f);
+  vlongdouble = f;
+  flongdouble (d);
+  vlongdouble = d;
+  flongdouble (ld);
+  vlongdouble = ld;
+}
+
+
Index: gcc/testsuite/g++.dg/warn/Wconversion-integer.C
===================================================================
--- gcc/testsuite/g++.dg/warn/Wconversion-integer.C	(revision 0)
+++ gcc/testsuite/g++.dg/warn/Wconversion-integer.C	(revision 123005)
@@ -0,0 +1,95 @@
+/* Test for diagnostics for implicit conversions between integer types
+   C++ equivalent of gcc/testsuite/gcc.dg/Wconversion-integer.c  */
+
+// { dg-do compile } 
+// { dg-options "-fsigned-char -Wconversion" } 
+
+#include <limits.h>
+
+void fsc (signed char sc);
+void fuc (unsigned char uc);
+unsigned fui (unsigned int  ui);
+void fsi (signed int ui);
+
+void h (int x)
+{
+  unsigned int ui = 3;
+  int   si = 3;
+  unsigned char uc = 3;
+  signed char   sc = 3;
+
+  fuc (-1); /* { dg-warning "negative integer implicitly converted to unsigned type" } */
+  uc = -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
+  fuc ('\xa0'); /* { dg-warning "negative integer implicitly converted to unsigned type" } */
+  uc = '\xa0'; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
+  uc = x ? 1U : -1; /* { dg-warning "conversion" } */
+  /* { dg-warning "negative integer implicitly converted to unsigned type" "" { target *-*-* } 25 } */
+  uc = x ? SCHAR_MIN : 1U; /* { dg-warning "conversion" } */
+  /* { dg-warning "negative integer implicitly converted to unsigned type" "" { target *-*-* } 27 } */
+
+  uc = x ? 1 : -1; /* { dg-warning "conversion" } */
+
+  uc = x ? SCHAR_MIN : 1; /* { dg-warning "conversion" } */
+
+  fuc ('A');
+  uc = 'A';
+  uc = (unsigned char) -1;
+
+  fui (-1); /* { dg-warning "negative integer implicitly converted to unsigned type" } */
+  ui = -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
+  ui = x ? 1U : -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
+  ui = x ? INT_MIN : 1U; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
+  ui = ui ? SCHAR_MIN : 1U; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
+  ui = 1U * -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
+  ui = ui + INT_MIN; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
+  ui = x ? 1 : -1; /* { dg-warning "conversion" } */
+  ui = ui ? SCHAR_MIN : 1; /* { dg-warning "conversion" } */
+
+  ui = -1 * (1 * -1);
+  ui = (unsigned) -1;
+
+  fsc (uc); /* { dg-warning "conversion" } */
+  sc = uc;  /* { dg-warning "conversion" } */
+  fuc (sc); /* { dg-warning "conversion" } */
+  uc = sc;  /* { dg-warning "conversion" } */
+  fsi (ui); /* { dg-warning "conversion" } */
+  si = ui;  /* { dg-warning "conversion" } */
+  fui (si); /* { dg-warning "conversion" } */ 
+  ui = si;  /* { dg-warning "conversion" } */ 
+  fui (sc); /* { dg-warning "conversion" } */
+  ui = sc;  /* { dg-warning "conversion" } */
+
+  fui ('\xa0');/* { dg-warning "negative integer implicitly converted to unsigned type" } */
+  ui = '\xa0'; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
+
+  fsi (si);
+  fui (ui);
+  fsi (uc);
+  si = uc;
+  fui (uc);
+  ui = uc;
+  fui ('A');
+  ui = 'A';
+  fsi ('A');
+  si = 'A';
+  
+
+  fsi (UINT_MAX - 1);  /* { dg-warning "conversion" } */
+  si = UINT_MAX - 1;   /* { dg-warning "conversion" } */
+  fsi (UINT_MAX - 1U); /* { dg-warning "conversion" } */
+  si = UINT_MAX - 1U;  /* { dg-warning "conversion" } */
+  fsi (UINT_MAX/3U);
+  si = UINT_MAX/3U;
+  fsi (UINT_MAX/3);
+  si = UINT_MAX/3;
+  fui (UINT_MAX - 1);
+  ui = UINT_MAX - 1;
+
+  fsi (0x80000000); /* { dg-warning "conversion" } */
+  si = 0x80000000;  /* { dg-warning "conversion" } */
+}
+
+
+unsigned fui (unsigned a) { return a + -1; } /* { dg-warning "negative integer implicitly converted to unsigned type" } */
+
+
Index: gcc/testsuite/g++.dg/warn/conv2.C
===================================================================
--- gcc/testsuite/g++.dg/warn/conv2.C	(revision 123004)
+++ gcc/testsuite/g++.dg/warn/conv2.C	(revision 123005)
@@ -1,4 +1,5 @@
 // PR c++/13932
 // { dg-options "-Wconversion" }
 
-int i = 1.; // { dg-warning "converting" }
+int i = 1.;
+int j = 1.1; // { dg-warning "conversion" }
Index: gcc/cp/typeck.c
===================================================================
--- gcc/cp/typeck.c	(revision 123004)
+++ gcc/cp/typeck.c	(revision 123005)
@@ -3837,9 +3837,9 @@
   if (! converted)
     {
       if (TREE_TYPE (op0) != result_type)
-	op0 = cp_convert (result_type, op0);
+	op0 = cp_convert_and_check (result_type, op0);
       if (TREE_TYPE (op1) != result_type)
-	op1 = cp_convert (result_type, op1);
+	op1 = cp_convert_and_check (result_type, op1);
 
       if (op0 == error_mark_node || op1 == error_mark_node)
 	return error_mark_node;
Index: gcc/cp/call.c
===================================================================
--- gcc/cp/call.c	(revision 123004)
+++ gcc/cp/call.c	(revision 123005)
@@ -4245,11 +4245,12 @@
   return expr;
 }
 
-/* Perform warnings about conversion of EXPR to type TOTYPE.
+/* Perform warnings about peculiar, but valid, conversions from/to NULL.
+   EXPR is implicitly converted to type TOTYPE.
    FN and ARGNUM are used for diagnostics.  */
 
 static void
-convert_conversion_warnings (tree totype, tree expr, tree fn, int argnum)
+conversion_null_warnings (tree totype, tree expr, tree fn, int argnum)
 {
   tree t = non_reference (totype);
 
@@ -4263,19 +4264,8 @@
 	warning (OPT_Wconversion, "converting to non-pointer type %qT from NULL", t);
     }
 
-  /* Warn about assigning a floating-point type to an integer type.  */
-  if (TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE
-      && TREE_CODE (t) == INTEGER_TYPE)
-    {
-      if (fn)
-	warning (OPT_Wconversion, "passing %qT for argument %P to %qD",
-		 TREE_TYPE (expr), argnum, fn);
-      else
-	warning (OPT_Wconversion, "converting to %qT from %qT", t, TREE_TYPE (expr));
-    }
-
   /* Issue warnings if "false" is converted to a NULL pointer */
-  if (expr == boolean_false_node && fn && POINTER_TYPE_P (t))
+  else if (expr == boolean_false_node && fn && POINTER_TYPE_P (t))
     warning (OPT_Wconversion,
 	     "converting %<false%> to pointer type for argument %P of %qD",
 	     argnum, fn);
@@ -4328,7 +4318,7 @@
     }
 
   if (issue_conversion_warnings)
-    convert_conversion_warnings (totype, expr, fn, argnum);
+    conversion_null_warnings (totype, expr, fn, argnum);
 
   switch (convs->kind)
     {
@@ -4415,7 +4405,7 @@
 
   expr = convert_like_real (convs->u.next, expr, fn, argnum,
 			    convs->kind == ck_ref_bind ? -1 : 1,
-			    /*issue_conversion_warnings=*/false,
+			    convs->kind == ck_ref_bind ? issue_conversion_warnings : false, 
 			    c_cast_p);
   if (expr == error_mark_node)
     return error_mark_node;
Index: gcc/cp/cvt.c
===================================================================
--- gcc/cp/cvt.c	(revision 123004)
+++ gcc/cp/cvt.c	(revision 123005)
@@ -593,6 +593,29 @@
   return ocp_convert (type, expr, CONV_OLD_CONVERT, LOOKUP_NORMAL);
 }
 
+/* C++ equivalent of convert_and_check but using cp_convert as the
+   conversion function.
+
+   Convert EXPR to TYPE, warning about conversion problems with constants.
+   Invoke this function on every expression that is converted implicitly,
+   i.e. because of language rules and not because of an explicit cast.  */
+
+tree
+cp_convert_and_check (tree type, tree expr)
+{
+  tree result;
+
+  if (TREE_TYPE (expr) == type)
+    return expr;
+  
+  result = cp_convert (type, expr);
+
+  if (!skip_evaluation && !TREE_OVERFLOW_P (expr))
+    warnings_for_convert_and_check (type, expr, result);
+
+  return result;
+}
+
 /* Conversion...
 
    FLAGS indicates how we should behave.  */
Index: gcc/cp/cp-tree.h
===================================================================
--- gcc/cp/cp-tree.h	(revision 123004)
+++ gcc/cp/cp-tree.h	(revision 123005)
@@ -4049,6 +4049,7 @@
 extern tree force_rvalue			(tree);
 extern tree ocp_convert				(tree, tree, int, int);
 extern tree cp_convert				(tree, tree);
+extern tree cp_convert_and_check                (tree, tree);
 extern tree convert_to_void	(tree, const char */*implicit context*/);
 extern tree convert_force			(tree, tree, int);
 extern tree build_expr_type_conversion		(int, tree, bool);
Index: gcc/cp/ChangeLog
===================================================================
--- gcc/cp/ChangeLog	(revision 123004)
+++ gcc/cp/ChangeLog	(revision 123005)
@@ -1,3 +1,15 @@
+2007-03-16  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
+
+	* cvt.c (cp_convert_and_check) : Define.
+	* cp-tree.h (cp_convert_and_check): Declare.
+	* call.c (convert_conversion_warnings): Rename to
+	conversion_null_warnings.  The warning for floating-point to
+	integer is handled by convert_and_check in convert_like_real.
+	(convert_like_real): convert_conversion_warnings was renamed as
+	conversion_null_warnings.
+	* typeck.c (build_binary_op): Use cp_convert_and_check to warn for
+	overflow and changes of value during conversion.
+
 2007-03-15  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
 
 	PR c++/30891
Index: gcc/c-common.c
===================================================================
--- gcc/c-common.c	(revision 123004)
+++ gcc/c-common.c	(revision 123005)
@@ -1168,7 +1168,7 @@
 }
 
 /* Warns if the conversion of EXPR to TYPE may alter a value.
-   This function is called from convert_and_check.  */
+   This is a helper function for warnings_for_convert_and_check.  */
 
 static void
 conversion_warning (tree type, tree expr)
@@ -1276,23 +1276,13 @@
     }
 }
 
-/* Convert EXPR to TYPE, warning about conversion problems with constants.
-   Invoke this function on every expression that is converted implicitly,
-   i.e. because of language rules and not because of an explicit cast.  */
+/* Produce warnings after a conversion. RESULT is the result of
+   converting EXPR to TYPE.  This is a helper function for
+   convert_and_check and cp_convert_and_check.  */
 
-tree
-convert_and_check (tree type, tree expr)
+void
+warnings_for_convert_and_check (tree type, tree expr, tree result)
 {
-  tree result;
-
-  if (TREE_TYPE (expr) == type)
-    return expr;
-  
-  result = convert (type, expr);
-
-  if (skip_evaluation || TREE_OVERFLOW_P (expr))
-    return result;
-
   if (TREE_CODE (expr) == INTEGER_CST
       && (TREE_CODE (type) == INTEGER_TYPE
           || TREE_CODE (type) == ENUMERAL_TYPE)
@@ -1332,7 +1322,26 @@
              "overflow in implicit constant conversion");
   else if (warn_conversion)
     conversion_warning (type, expr);
+}
+
+
+/* Convert EXPR to TYPE, warning about conversion problems with constants.
+   Invoke this function on every expression that is converted implicitly,
+   i.e. because of language rules and not because of an explicit cast.  */
+
+tree
+convert_and_check (tree type, tree expr)
+{
+  tree result;
+
+  if (TREE_TYPE (expr) == type)
+    return expr;
   
+  result = convert (type, expr);
+
+  if (!skip_evaluation && !TREE_OVERFLOW_P (expr))
+    warnings_for_convert_and_check (type, expr, result);
+
   return result;
 }
 

Index: gcc/c-common.h
===================================================================
--- gcc/c-common.h	(revision 123004)
+++ gcc/c-common.h	(revision 123005)
@@ -671,6 +671,7 @@
 extern void constant_expression_warning (tree);
 extern void strict_aliasing_warning (tree, tree, tree);
 extern void empty_if_body_warning (tree, tree);
+extern void warnings_for_convert_and_check (tree, tree, tree);
 extern tree convert_and_check (tree, tree);
 extern void overflow_warning (tree);
 extern void warn_logical_operator (enum tree_code, tree, tree);


More information about the Gcc-patches mailing list