This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Warn when casting a pointer (constant) to an integer of different size.


Just checking to make sure the final result is okay.
Tested on x86-pc-linux-gnu with no regressions.

I added cast-4.c as a new test which fails previously 
but passes after the patch is applied.

Ok?

Cheers,
Carlos.
-- 
Carlos O'Donell                                                                              
CodeSourcery, LLC                                                                                   
carlos@codesourcery.com 

The case "constant -> pointer -> integer" should have a warning when the
size of integer and pointer are not the same.

If the size of integer is greater than the pointer size it could produce
unwanted sign extension. This can help track down incorrect casts and
replace them with casts to uintptr_t.

And example could be:

	((unsigned long long)((void *)(0xdeadbeef)))

Should emit a warning, since the result could become 0xffffffffdeadbeef
instead of 0xdeadbeef. 

It should emit a warning in the more generic case when the precisions
are not equal, and that is what the patch does.  I've included fixes for
the regressions caused by the patch.

gcc/testsuite/

2005-12-28  Carlos O'Donell <carlos@codesourcery.com>

	* gcc.dg/cast-1.c: Add new warning.
	* gcc.dg/cast-2.c: Add new warning.
	* gcc.dg/cast-3.c: Add new warning.
	* gcc.dg/format/cast-1.c: Add new warning.
	* gcc.dg/cast-4.c: New test.

gcc/

2005-12-28  Carlos O'Donell <carlos@codesourcery.com>

	* c-typeck.c (build_c_cast): Always warn when casting 
	from a pointer to an integer of different size, even if 
	the node was constant.

Index: gcc/testsuite/gcc.dg/cast-2.c
===================================================================
--- gcc/testsuite/gcc.dg/cast-2.c	(revision 109081)
+++ gcc/testsuite/gcc.dg/cast-2.c	(working copy)
@@ -37,5 +37,5 @@
   (void *) c; /* { dg-warning "warning: cast to pointer from integer of different size" } */
   (void *) (char) 1;
   (char) p; /* { dg-warning "warning: cast from pointer to integer of different size" } */
-  (char) (void *) 1;
+  (char) (void *) 1; /* { dg-warning "warning: cast from pointer to integer of different size" } */
 }
Index: gcc/testsuite/gcc.dg/cast-1.c
===================================================================
--- gcc/testsuite/gcc.dg/cast-1.c	(revision 109081)
+++ gcc/testsuite/gcc.dg/cast-1.c	(working copy)
@@ -37,5 +37,5 @@
   (void *) c; /* { dg-warning "warning: cast to pointer from integer of different size" } */
   (void *) (char) 1;
   (char) p; /* { dg-warning "warning: cast from pointer to integer of different size" } */
-  (char) (void *) 1;
+  (char) (void *) 1; /* { dg-warning "warning: cast from pointer to integer of different size" } */
 }
Index: gcc/testsuite/gcc.dg/cast-3.c
===================================================================
--- gcc/testsuite/gcc.dg/cast-3.c	(revision 109081)
+++ gcc/testsuite/gcc.dg/cast-3.c	(working copy)
@@ -37,5 +37,5 @@
   (void *) c; /* { dg-warning "warning: cast to pointer from integer of different size" } */
   (void *) (char) 1;
   (char) p; /* { dg-warning "warning: cast from pointer to integer of different size" } */
-  (char) (void *) 1;
+  (char) (void *) 1; /* { dg-warning "warning: cast from pointer to integer of different size" } */
 }
Index: gcc/testsuite/gcc.dg/format/cast-1.c
===================================================================
--- gcc/testsuite/gcc.dg/format/cast-1.c	(revision 109081)
+++ gcc/testsuite/gcc.dg/format/cast-1.c	(working copy)
@@ -12,5 +12,5 @@
 {
   printf("%s", x); /* { dg-warning "format" } */
   printf((char *)(size_t)"%s", x); /* { dg-warning "format" } */
-  printf((char *)(char)"%s", x);
+  printf((char *)(char)"%s", x); /* { dg-warning "warning: cast from pointer to integer of different size" } */
 }
Index: gcc/c-typeck.c
===================================================================
--- gcc/c-typeck.c	(revision 109081)
+++ gcc/c-typeck.c	(working copy)
@@ -3508,8 +3508,12 @@
 
       if (TREE_CODE (type) == INTEGER_TYPE
 	  && TREE_CODE (otype) == POINTER_TYPE
-	  && TYPE_PRECISION (type) != TYPE_PRECISION (otype)
-	  && !TREE_CONSTANT (value))
+	  && TYPE_PRECISION (type) != TYPE_PRECISION (otype))
+      /* Unlike conversion of integers to pointers, where the 
+         warning is disabled for converting constants because 
+         of cases such as SIG_*, warn about converting constant 
+         pointers to integers.  In some cases it may cause unwanted 
+         sign extension, and a warning is apprpriate. */
 	warning (OPT_Wpointer_to_int_cast,
 		 "cast from pointer to integer of different size");
 
--- /dev/null	2004-06-24 11:05:26.000000000 -0700
+++ gcc/testsuite/gcc.dg/cast-4.c	2005-12-27 15:20:43.000000000 -0800
@@ -0,0 +1,13 @@
+/* Test warnings when casting from a constant integer to pointer.  
+   Test with -pedantic-errors.  */
+/* Origin: Carlos O'Donell <carlos@codesourcery.com> */
+/* { dg-do compile } */
+/* { dg-options "-std=gnu99 -pedantic-errors" } */
+
+extern int i;
+char c;
+void
+f (void)
+{
+  c = (char)&i; /* { dg-warning "warning: cast from pointer to integer of different size" } */
+}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]