From 9e96b8d0709ef64d2c13cdb7cadcc306ddc06953 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Thu, 13 Sep 2012 17:25:15 -0700 Subject: Warn pointer to signed integer cast for ilp32 --- gcc/c-family/c.opt | 4 ++++ gcc/c/c-typeck.c | 23 +++++++++++++--------- gcc/cp/typeck.c | 5 +++++ .../g++.dg/warn/Wpointer-to-signed-int-cast-1.C | 23 ++++++++++++++++++++++ .../gcc.dg/Wpointer-to-signed-int-cast-1.c | 17 ++++++++++++++++ 5 files changed, 63 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/g++.dg/warn/Wpointer-to-signed-int-cast-1.C create mode 100644 gcc/testsuite/gcc.dg/Wpointer-to-signed-int-cast-1.c 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; +} -- cgit v1.2.1