summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2012-09-13 17:25:15 -0700
committerH.J. Lu <hjl.tools@gmail.com>2012-09-13 17:25:15 -0700
commit9e96b8d0709ef64d2c13cdb7cadcc306ddc06953 (patch)
tree7848e3ef5e0eb4531ba9be85d50d3ca8dc59cb69
parent628277461faf5027a8ffb2859d9617d6579dac45 (diff)
downloadgcc-hjl/pr54037.tar.gz
Warn pointer to signed integer cast for ilp32hjl/pr54037
-rw-r--r--gcc/c-family/c.opt4
-rw-r--r--gcc/c/c-typeck.c23
-rw-r--r--gcc/cp/typeck.c5
-rw-r--r--gcc/testsuite/g++.dg/warn/Wpointer-to-signed-int-cast-1.C23
-rw-r--r--gcc/testsuite/gcc.dg/Wpointer-to-signed-int-cast-1.c17
5 files changed, 63 insertions, 9 deletions
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 914d110597d..0f5d941b921 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -581,6 +581,10 @@ Wpointer-to-int-cast
C ObjC Var(warn_pointer_to_int_cast) Init(1) Warning
Warn when a pointer is cast to an integer of a different size
+Wpointer-to-signed-int-cast
+C ObjC C++ ObjC++ Var(warn_pointer_to_signed_int_cast) Warning
+Warn when a pointer is cast to a signed integer of the same size
+
Wpragmas
C ObjC C++ ObjC++ Var(warn_pragmas) Init(1) Warning
Warn about misuses of pragmas
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 99920ef288b..b401edc6507 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -4657,15 +4657,20 @@ build_c_cast (location_t loc, tree type, tree expr)
"cast increases required alignment of target type");
if (TREE_CODE (type) == INTEGER_TYPE
- && TREE_CODE (otype) == POINTER_TYPE
- && 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 appropriate. */
- warning_at (loc, OPT_Wpointer_to_int_cast,
- "cast from pointer to integer of different size");
+ && TREE_CODE (otype) == POINTER_TYPE)
+ {
+ if (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 appropriate. */
+ warning_at (loc, OPT_Wpointer_to_int_cast,
+ "cast from pointer to integer of different size");
+ else if (!TYPE_UNSIGNED (type) && ptr_mode != word_mode)
+ warning_at (loc, OPT_Wpointer_to_signed_int_cast,
+ "cast from pointer to signed integer");
+ }
if (TREE_CODE (value) == CALL_EXPR
&& TREE_CODE (type) != TREE_CODE (otype))
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 25f37e896fa..3ce10812180 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -6374,6 +6374,11 @@ build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p,
else
return error_mark_node;
}
+ else if (TYPE_PRECISION (type) == TYPE_PRECISION (intype)
+ && !TYPE_UNSIGNED (type)
+ && ptr_mode != word_mode)
+ warning_at (input_location, OPT_Wpointer_to_signed_int_cast,
+ "cast from %qT to %qT", intype, type);
if (NULLPTR_TYPE_P (intype))
return build_int_cst (type, 0);
}
diff --git a/gcc/testsuite/g++.dg/warn/Wpointer-to-signed-int-cast-1.C b/gcc/testsuite/g++.dg/warn/Wpointer-to-signed-int-cast-1.C
new file mode 100644
index 00000000000..f951056bc7d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wpointer-to-signed-int-cast-1.C
@@ -0,0 +1,23 @@
+// Test -Wpointer-to-signed-int-cast - off by default.
+// { dg-do compile { target { int128 && ilp32 } } }
+// { dg-options "-Wpointer-to-signed-int-cast" }
+
+void *p;
+
+long
+foo (void)
+{
+ return (long) p; // { dg-warning "cast from 'void\\*' to 'long int'" }
+}
+
+unsigned long
+bar (void)
+{
+ return (unsigned long) p;
+}
+
+long long
+xxx (void)
+{
+ return (long long) p;
+}
diff --git a/gcc/testsuite/gcc.dg/Wpointer-to-signed-int-cast-1.c b/gcc/testsuite/gcc.dg/Wpointer-to-signed-int-cast-1.c
new file mode 100644
index 00000000000..5d265d8a28a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wpointer-to-signed-int-cast-1.c
@@ -0,0 +1,17 @@
+/* Test -Wpointer-to-signed-int-cast - off by default. */
+/* { dg-do compile { target { int128 && ilp32 } } } */
+/* { dg-options "-Wpointer-to-signed-int-cast" } */
+
+void *p;
+
+long
+foo (void)
+{
+ return (long) p; /* { dg-warning "cast from pointer to signed integer" } */
+}
+
+unsigned long
+bar (void)
+{
+ return (unsigned long) p;
+}