]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/14024 (g++ isn't reporting aliasing warnings)
authorRichard Guenther <rguenther@suse.de>
Thu, 24 Nov 2005 10:48:15 +0000 (10:48 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 24 Nov 2005 10:48:15 +0000 (10:48 +0000)
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.

* 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.

Co-Authored-By: Dirk Mueller <dmueller@suse.de>
From-SVN: r107459

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 c983bce514cd398b2b30d9e55f3f60f83f9d1dac..2efba8ce0b655b73f3c7a7d66ef5853e5d82de38 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
index b843df2593537c3c2d56ce605e8fd339039dde35..82fe6131c1de462caf9c5ff90e57cd404f1fa266 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).  */
 
index 96905af107f8f32e430e99d80fa2fef9dcc8a907..c78f4625327cc8fe162341ed5aa8d5d77d088a99 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 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);
index 2150238ec6e1abc5c445b5c28d520eb15a2fafa4..735d9e741ed0c592ff2de6acc083a62f80a84fd1 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");
 
-      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
index 046d049bd08f645274042f66d361e7a1ec445cda..dbf3330abb8b4d0d8f47f96f4331035350b9892d 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
index b3c155a13c0e23b82be6f1fb331f528128c7d6bf..60ef195a90cc3f6f6fe5d491f3a992fe50288c84 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)))
     {
+      tree sexpr = expr;
+
       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);
 
+      /* 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))
index 9ed97b85fa6d06e2c58403c8d675013f62df6703..d2bc993463755543c7a41a3ef57366841d2a9582 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.
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" } */
+}
+