Hi!

As the testcase shows, for implicit conversions between signed integer
and signed integer with some attribute that makes it a distinct type from
that such as may_alias attribute, we warn that the pointer targets differ
in signedness, even when they have the same size.  For similar unsigned
integer vs. unsigned integer with attribute we warn about initialization
from incompatible pointer type.  This patch ensures we treat the former
as the latter.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2012-12-07  Jakub Jelinek  <ja...@redhat.com>

        PR c/39464
        * c-typeck.c (convert_for_assignment): For -Wpointer-sign
        warning require that both c_common_unsigned_type as well as
        c_common_signed_type is the same for both mvl and mvr types.

        * gcc.dg/pr39464.c: New test.

--- gcc/c/c-typeck.c.jj 2012-12-07 17:08:05.391996135 +0100
+++ gcc/c/c-typeck.c    2012-12-07 17:31:11.831147409 +0100
@@ -5543,8 +5543,10 @@ convert_for_assignment (location_t locat
       if (VOID_TYPE_P (ttl) || VOID_TYPE_P (ttr)
          || (target_cmp = comp_target_types (location, type, rhstype))
          || is_opaque_pointer
-         || (c_common_unsigned_type (mvl)
-             == c_common_unsigned_type (mvr)))
+         || ((c_common_unsigned_type (mvl)
+              == c_common_unsigned_type (mvr))
+             && c_common_signed_type (mvl)
+                == c_common_signed_type (mvr)))
        {
          if (pedantic
              && ((VOID_TYPE_P (ttl) && TREE_CODE (ttr) == FUNCTION_TYPE)
--- gcc/testsuite/gcc.dg/pr39464.c.jj   2012-12-07 17:19:33.885125923 +0100
+++ gcc/testsuite/gcc.dg/pr39464.c      2012-12-07 17:33:14.000000000 +0100
@@ -0,0 +1,19 @@
+/* PR c/39464 */
+/* { dg-do compile } */
+/* { dg-options "-Wall" } */
+
+typedef int T __attribute__((may_alias));
+typedef unsigned int U __attribute__((may_alias));
+
+void
+foo (void *p)
+{
+  T *a = (int *) p;            /* { dg-warning "initialization from 
incompatible pointer type" } */
+  int *b = (T *) p;            /* { dg-warning "initialization from 
incompatible pointer type" } */
+  U *c = (unsigned int *) p;   /* { dg-warning "initialization from 
incompatible pointer type" } */
+  unsigned int *d = (U *) p;   /* { dg-warning "initialization from 
incompatible pointer type" } */
+  (void) a;
+  (void) b;
+  (void) c;
+  (void) d;
+}

        Jakub

Reply via email to