This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Warn when casting a pointer (constant) to an integer of different size.
- From: Carlos O'Donell <carlos at codesourcery dot com>
- To: joseph at codesourcery dot com, gcc-patches at gcc dot gnu dot org
- Date: Wed, 28 Dec 2005 17:08:40 -0500
- Subject: [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" } */
+}