OSDN Git Service

2005-11-24 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 24 Nov 2005 10:48:15 +0000 (10:48 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 24 Nov 2005 10:48:15 +0000 (10:48 +0000)
Dirk Mueller <dmueller@suse.de>

PR c++/14024
* c-common.h (strict_aliasing_warning): Declare.
* c-common.c (strict_aliasing_warning): New function,
split out from ...
* c-typeck.c (build_c_cast): ... here.

* typeck.c (build_reinterpret_cast_1): Use it.

* g++.dg/warn/Wstrict-aliasing-1.C: New testcase.
* g++.dg/warn/Wstrict-aliasing-2.C: Likewise.
* g++.dg/warn/Wstrict-aliasing-3.C: Likewise.
* g++.dg/warn/Wstrict-aliasing-4.C: Likewise.
* g++.dg/warn/Wstrict-aliasing-5.C: Likewise.
* g++.dg/warn/Wstrict-aliasing-6.C: Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@107459 138bc75d-0d04-0410-961f-82ee72b054a4

13 files changed:
gcc/ChangeLog
gcc/c-common.c
gcc/c-common.h
gcc/c-typeck.c
gcc/cp/ChangeLog
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/warn/Wstrict-aliasing-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/warn/Wstrict-aliasing-2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/warn/Wstrict-aliasing-3.C [new file with mode: 0644]
gcc/testsuite/g++.dg/warn/Wstrict-aliasing-4.C [new file with mode: 0644]
gcc/testsuite/g++.dg/warn/Wstrict-aliasing-5.C [new file with mode: 0644]
gcc/testsuite/g++.dg/warn/Wstrict-aliasing-6.C [new file with mode: 0644]

index c983bce..2efba8c 100644 (file)
@@ -1,3 +1,12 @@
+2005-11-24  Richard Guenther  <rguenther@suse.de>
+       Dirk Mueller <dmueller@suse.de>
+
+       PR c++/14024
+       * c-common.h (strict_aliasing_warning): Declare.
+       * c-common.c (strict_aliasing_warning): New function,
+       split out from ...
+       * c-typeck.c (build_c_cast): ... here.
+
 2005-11-24  Paolo Bonzini  <bonzini@gnu.org>
 
        * optabs.c (expand_binop): Use swap_commutative_operands_with_target
 2005-11-24  Paolo Bonzini  <bonzini@gnu.org>
 
        * optabs.c (expand_binop): Use swap_commutative_operands_with_target
index b843df2..82fe613 100644 (file)
@@ -954,6 +954,42 @@ unsigned_conversion_warning (tree result, tree operand)
     }
 }
 
     }
 }
 
+/* Print a warning about casts that might indicate violation
+   of strict aliasing rules if -Wstrict-aliasing is used and
+   strict aliasing mode is in effect. otype is the original
+   TREE_TYPE of expr, and type the type we're casting to. */
+
+void
+strict_aliasing_warning(tree otype, tree type, tree expr)
+{
+  if (flag_strict_aliasing && warn_strict_aliasing
+      && POINTER_TYPE_P (type) && POINTER_TYPE_P (otype)
+      && TREE_CODE (expr) == ADDR_EXPR
+      && (DECL_P (TREE_OPERAND (expr, 0))
+          || TREE_CODE (TREE_OPERAND (expr, 0)) == COMPONENT_REF)
+      && !VOID_TYPE_P (TREE_TYPE (type)))
+    {
+      /* Casting the address of an object to non void pointer. Warn
+         if the cast breaks type based aliasing.  */
+      if (!COMPLETE_TYPE_P (TREE_TYPE (type)))
+        warning (OPT_Wstrict_aliasing, "type-punning to incomplete type "
+                 "might break strict-aliasing rules");
+      else
+        {
+          HOST_WIDE_INT set1 = get_alias_set (TREE_TYPE (TREE_OPERAND (expr, 0)));
+          HOST_WIDE_INT set2 = get_alias_set (TREE_TYPE (type));
+
+          if (!alias_sets_conflict_p (set1, set2))
+            warning (OPT_Wstrict_aliasing, "dereferencing type-punned "
+                     "pointer will break strict-aliasing rules");
+          else if (warn_strict_aliasing > 1
+                  && !alias_sets_might_conflict_p (set1, set2))
+            warning (OPT_Wstrict_aliasing, "dereferencing type-punned "
+                     "pointer might break strict-aliasing rules");
+        }
+    }
+}
+
 /* Nonzero if constant C has a value that is permissible
    for type TYPE (an INTEGER_TYPE).  */
 
 /* Nonzero if constant C has a value that is permissible
    for type TYPE (an INTEGER_TYPE).  */
 
index 96905af..c78f462 100644 (file)
@@ -649,6 +649,7 @@ extern void binary_op_error (enum tree_code);
 extern tree fix_string_type (tree);
 struct varray_head_tag;
 extern void constant_expression_warning (tree);
 extern tree fix_string_type (tree);
 struct varray_head_tag;
 extern void constant_expression_warning (tree);
+extern void strict_aliasing_warning(tree, tree, tree);
 extern tree convert_and_check (tree, tree);
 extern void overflow_warning (tree);
 extern void unsigned_conversion_warning (tree, tree);
 extern tree convert_and_check (tree, tree);
 extern void overflow_warning (tree);
 extern void unsigned_conversion_warning (tree, tree);
index 2150238..735d9e7 100644 (file)
@@ -3441,33 +3441,7 @@ build_c_cast (tree type, tree expr)
        warning (OPT_Wint_to_pointer_cast, "cast to pointer from integer "
                 "of different size");
 
        warning (OPT_Wint_to_pointer_cast, "cast to pointer from integer "
                 "of different size");
 
-      if (flag_strict_aliasing && warn_strict_aliasing
-         && TREE_CODE (type) == POINTER_TYPE
-         && TREE_CODE (otype) == POINTER_TYPE
-         && TREE_CODE (expr) == ADDR_EXPR
-         && (DECL_P (TREE_OPERAND (expr, 0))
-             || TREE_CODE (TREE_OPERAND (expr, 0)) == COMPONENT_REF)
-         && !VOID_TYPE_P (TREE_TYPE (type)))
-       {
-         /* Casting the address of an object to non void pointer. Warn
-            if the cast breaks type based aliasing.  */
-         if (!COMPLETE_TYPE_P (TREE_TYPE (type)))
-           warning (OPT_Wstrict_aliasing, "type-punning to incomplete type "
-                    "might break strict-aliasing rules");
-         else
-           {
-             HOST_WIDE_INT set1 = get_alias_set (TREE_TYPE (TREE_OPERAND (expr, 0)));
-             HOST_WIDE_INT set2 = get_alias_set (TREE_TYPE (type));
-
-             if (!alias_sets_conflict_p (set1, set2))
-               warning (OPT_Wstrict_aliasing, "dereferencing type-punned "
-                        "pointer will break strict-aliasing rules");
-             else if (warn_strict_aliasing > 1
-                      && !alias_sets_might_conflict_p (set1, set2))
-               warning (OPT_Wstrict_aliasing, "dereferencing type-punned "
-                        "pointer might break strict-aliasing rules");
-           }
-       }
+      strict_aliasing_warning (otype, type, expr);
 
       /* If pedantic, warn for conversions between function and object
         pointer types, except for converting a null pointer constant
 
       /* If pedantic, warn for conversions between function and object
         pointer types, except for converting a null pointer constant
index 046d049..dbf3330 100644 (file)
@@ -1,3 +1,10 @@
+2005-11-24  Richard Guenther  <rguenther@suse.de>
+       Dirk Mueller <dmueller@suse.de>
+
+       PR c++/14024
+       * typeck.c (build_reinterpret_cast_1): Use
+       strict_aliasing_warning.
+
 2005-11-23  Gabriel Dos Reis  <gdr@integrable-solutions.net>
 
        PR c++/24235
 2005-11-23  Gabriel Dos Reis  <gdr@integrable-solutions.net>
 
        PR c++/24235
index b3c155a..60ef195 100644 (file)
@@ -5011,6 +5011,8 @@ build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p,
   else if ((TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype))
           || (TYPE_PTROBV_P (type) && TYPE_PTROBV_P (intype)))
     {
   else if ((TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype))
           || (TYPE_PTROBV_P (type) && TYPE_PTROBV_P (intype)))
     {
+      tree sexpr = expr;
+
       if (!c_cast_p)
        check_for_casting_away_constness (intype, type, error,
                                          "reinterpret_cast");
       if (!c_cast_p)
        check_for_casting_away_constness (intype, type, error,
                                          "reinterpret_cast");
@@ -5025,6 +5027,11 @@ build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p,
                 "target type",
                 intype, type);
 
                 "target type",
                 intype, type);
 
+      /* We need to strip nops here, because the frontend likes to
+        create (int *)&a for array-to-pointer decay, instead of &a[0].  */
+      STRIP_NOPS (sexpr);
+      strict_aliasing_warning (intype, type, sexpr);
+
       return fold_if_not_in_template (build_nop (type, expr));
     }
   else if ((TYPE_PTRFN_P (type) && TYPE_PTROBV_P (intype))
       return fold_if_not_in_template (build_nop (type, expr));
     }
   else if ((TYPE_PTRFN_P (type) && TYPE_PTROBV_P (intype))
index 9ed97b8..d2bc993 100644 (file)
@@ -1,3 +1,14 @@
+2005-11-24  Richard Guenther  <rguenther@suse.de>
+       Dirk Mueller <dmueller@suse.de>
+
+       PR c++/14024
+       * g++.dg/warn/Wstrict-aliasing-1.C: New testcase.
+       * g++.dg/warn/Wstrict-aliasing-2.C: Likewise.
+       * g++.dg/warn/Wstrict-aliasing-3.C: Likewise.
+       * g++.dg/warn/Wstrict-aliasing-4.C: Likewise.
+       * g++.dg/warn/Wstrict-aliasing-5.C: Likewise.
+       * g++.dg/warn/Wstrict-aliasing-6.C: Likewise.
+
 2005-11-23  Uros Bizjak  <uros@kss-loka.si>
 
        * g++.dg/other/i386-1.C: Pass if CPU has no SSE2 support.
 2005-11-23  Uros Bizjak  <uros@kss-loka.si>
 
        * g++.dg/other/i386-1.C: Pass if CPU has no SSE2 support.
diff --git a/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-1.C b/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-1.C
new file mode 100644 (file)
index 0000000..3e9db36
--- /dev/null
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-Wstrict-aliasing=2 -O2" } */
+
+double x;
+int *foo(void)
+{
+  return (int *)&x; /* { dg-warning "strict-aliasing" } */
+}
+
diff --git a/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-2.C b/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-2.C
new file mode 100644 (file)
index 0000000..713b354
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-Wstrict-aliasing=2 -O2" } */
+
+double x;
+
+template <typename T>
+T *foo(void)
+{
+  return (T *)&x; /* { dg-bogus "strict-aliasing" } */
+}
+
+template double *foo<double>(void);
+
diff --git a/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-3.C b/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-3.C
new file mode 100644 (file)
index 0000000..9fc3538
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-Wstrict-aliasing=2 -O2" } */
+
+double x;
+
+template <typename T>
+T *foo(void)
+{
+  return (T *)&x; /* { dg-warning "strict-aliasing" } */
+}
+
+template int *foo<int>(void); /* { dg-warning "instantiated from here" } */
+template char *foo<char>(void); /* { dg-bogus "instantiated from here" } */
+
diff --git a/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-4.C b/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-4.C
new file mode 100644 (file)
index 0000000..e877c70
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-Wstrict-aliasing=2 -O2" } */
+
+double x;
+
+template <typename T>
+T *foo(void)
+{
+  int a[2];
+  float *y = (float *)a; /* { dg-bogus "strict-aliasing" } */
+  return (T *)&x; /* { dg-bogus "strict-aliasing" } */
+}
+
diff --git a/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-5.C b/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-5.C
new file mode 100644 (file)
index 0000000..a049251
--- /dev/null
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-Wstrict-aliasing=2 -O2" } */
+
+float foo ()
+{
+  unsigned int MASK = 0x80000000;
+  return (float &) MASK; /* { dg-warning "strict-aliasing" } */
+}
+
diff --git a/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-6.C b/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-6.C
new file mode 100644 (file)
index 0000000..6f935c8
--- /dev/null
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-Wstrict-aliasing=2 -O2" } */
+
+int foo ()
+{
+  char buf[8];
+  return *((int *)buf); /* { dg-warning "strict-aliasing" } */
+}
+