The -Wstrict-aliasing warning was gated on flag_strict_aliasing, so
passing -fno-strict-aliasing silenced the warning even when explicitly
requested with -Wstrict-aliasing.  The warning analysis is purely
type-based and does not depend on the optimization being active, so
temporarily enable flag_strict_aliasing around the alias set query
calls to get meaningful results for the warning.

gcc/c-family/ChangeLog:

        * c-warn.cc (strict_aliasing_warning):

gcc/ChangeLog:

        * doc/invoke.texi:

gcc/testsuite/ChangeLog:

        * c-c++-common/Wstrict-aliasing2-with-fno.c: New test.
        * c-c++-common/Wstrict-aliasing3-with-fno.c: New test.

Signed-off-by: Sammy Al Hashemi <[email protected]>
---
 gcc/c-family/c-warn.cc                        | 21 ++++++++++++-------
 gcc/doc/invoke.texi                           | 16 ++++++++------
 .../c-c++-common/Wstrict-aliasing2-with-fno.c | 12 +++++++++++
 .../c-c++-common/Wstrict-aliasing3-with-fno.c | 12 +++++++++++
 4 files changed, 48 insertions(+), 13 deletions(-)
 create mode 100644 gcc/testsuite/c-c++-common/Wstrict-aliasing2-with-fno.c
 create mode 100644 gcc/testsuite/c-c++-common/Wstrict-aliasing3-with-fno.c

diff --git a/gcc/c-family/c-warn.cc b/gcc/c-family/c-warn.cc
index 1767d2dc090..a3e07e188a7 100644
--- a/gcc/c-family/c-warn.cc
+++ b/gcc/c-family/c-warn.cc
@@ -701,8 +701,7 @@ strict_aliasing_warning (location_t loc, tree type, tree 
expr)
   STRIP_NOPS (expr);
   tree otype = TREE_TYPE (expr);
 
-  if (!(flag_strict_aliasing
-       && POINTER_TYPE_P (type)
+  if (!(POINTER_TYPE_P (type)
        && POINTER_TYPE_P (otype)
        && !VOID_TYPE_P (TREE_TYPE (type)))
       /* If the type we are casting to is a ref-all pointer
@@ -710,6 +709,13 @@ strict_aliasing_warning (location_t loc, tree type, tree 
expr)
       || TYPE_REF_CAN_ALIAS_ALL (type))
     return false;
 
+  /* Temporarily enable strict aliasing so that the alias set query
+     functions return meaningful results for the warning.  */
+  int save_flag_strict_aliasing = flag_strict_aliasing;
+  flag_strict_aliasing = 1;
+
+  bool result = false;
+
   if ((warn_strict_aliasing > 1) && TREE_CODE (expr) == ADDR_EXPR
       && (DECL_P (TREE_OPERAND (expr, 0))
          || handled_component_p (TREE_OPERAND (expr, 0))))
@@ -721,7 +727,7 @@ strict_aliasing_warning (location_t loc, tree type, tree 
expr)
          warning_at (loc, OPT_Wstrict_aliasing,
                      "type-punning to incomplete type "
                      "might break strict-aliasing rules");
-         return true;
+         result = true;
        }
       else
        {
@@ -739,7 +745,7 @@ strict_aliasing_warning (location_t loc, tree type, tree 
expr)
              warning_at (loc, OPT_Wstrict_aliasing,
                          "dereferencing type-punned "
                          "pointer will break strict-aliasing rules");
-             return true;
+             result = true;
            }
          else if (warn_strict_aliasing == 2
                   && !alias_sets_must_conflict_p (set1, set2))
@@ -747,7 +753,7 @@ strict_aliasing_warning (location_t loc, tree type, tree 
expr)
              warning_at (loc, OPT_Wstrict_aliasing,
                          "dereferencing type-punned "
                          "pointer might break strict-aliasing rules");
-             return true;
+             result = true;
            }
        }
     }
@@ -765,11 +771,12 @@ strict_aliasing_warning (location_t loc, tree type, tree 
expr)
          warning_at (loc, OPT_Wstrict_aliasing,
                      "dereferencing type-punned "
                      "pointer might break strict-aliasing rules");
-         return true;
+         result = true;
        }
     }
 
-  return false;
+  flag_strict_aliasing = save_flag_strict_aliasing;
+  return result;
 }
 
 /* Warn about memset (&a, 0, sizeof (&a)); and similar mistakes with
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 339d1d2c97a..b361290cee4 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -8674,17 +8674,21 @@ the implementation.
 @opindex Wstrict-aliasing
 @opindex Wno-strict-aliasing
 @item -Wstrict-aliasing
-This option is only active when @option{-fstrict-aliasing} is active.
-It warns about code that might break the strict aliasing rules that the
-compiler is using for optimization.  The warning does not catch all
+This option warns about code that might break the strict aliasing rules
+that the compiler uses for optimization when @option{-fstrict-aliasing}
+is active.  This option is independent of @option{-fstrict-aliasing};
+it diagnoses code that would violate strict aliasing rules regardless of
+whether the optimization is enabled.  The warning does not catch all
 cases, but does attempt to catch the more common pitfalls.  It is
 included in @option{-Wall}.
 It is equivalent to @option{-Wstrict-aliasing=3}.
 
 @item -Wstrict-aliasing=@var{n}
-This option is only active when @option{-fstrict-aliasing} is active.
-It warns about code that might break the strict aliasing rules that the
-compiler is using for optimization.
+This option warns about code that might break the strict aliasing rules
+that the compiler uses for optimization when @option{-fstrict-aliasing}
+is active.  This option is independent of @option{-fstrict-aliasing};
+it diagnoses code that would violate strict aliasing rules regardless of
+whether the optimization is enabled.
 Higher levels correspond to higher accuracy (fewer false positives).
 Higher levels also correspond to more effort, similar to the way @option{-O}
 works.
diff --git a/gcc/testsuite/c-c++-common/Wstrict-aliasing2-with-fno.c 
b/gcc/testsuite/c-c++-common/Wstrict-aliasing2-with-fno.c
new file mode 100644
index 00000000000..c7b223ed91b
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wstrict-aliasing2-with-fno.c
@@ -0,0 +1,12 @@
+/* Test the usage of option -Wstrict-aliasing.  */
+/* Make sure it's enabled even when -fno-strict-aliasing.  */
+/* Set -Wstrict-aliasing=2 so it warns on casts */
+/* { dg-do compile } */
+/* { dg-options "-Wstrict-aliasing=2 -fno-strict-aliasing" } */
+
+int main(int argc, char *argv[])
+{
+    int x;
+    float *q = (float*) &x; /* { dg-warning "strict-aliasing" } */
+    return x;
+}
diff --git a/gcc/testsuite/c-c++-common/Wstrict-aliasing3-with-fno.c 
b/gcc/testsuite/c-c++-common/Wstrict-aliasing3-with-fno.c
new file mode 100644
index 00000000000..e999b13aec4
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wstrict-aliasing3-with-fno.c
@@ -0,0 +1,12 @@
+/* Test the usage of option -Wstrict-aliasing.  */
+/* Make sure it's enabled even when -fno-strict-aliasing.  */
+/* Set -Wstrict-aliasing=3 so that it only warns on dereference */
+/* { dg-do compile } */
+/* { dg-options "-Wstrict-aliasing=3 -fno-strict-aliasing" } */
+
+int main(int argc, char *argv[])
+{
+    int x;
+    *(float*) &x = 42; /* { dg-warning "strict-aliasing" } */
+    return x;
+}
-- 
2.54.0

Reply via email to