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-common.h (class temp_override): Moved temp_override from
cp-tree.h
* c-warn.cc (strict_aliasing_warning): Remove guard on
flag_strict_aliasing. Temporarily enable it via RAII around
alias set queries so the warning fires independently.
gcc/ChangeLog:
* doc/invoke.texi (-Wstrict-aliasing): Document that the
warning now works independently of -fstrict-aliasing.
gcc/testsuite/ChangeLog:
* c-c++-common/Wstrict-aliasing2-with-fno.c: New test.
* c-c++-common/Wstrict-aliasing3-with-fno.c: New test.
gcc/cp/ChangeLog:
* constexpr.cc: included c-common.h
* cp-gimplify.cc: included c-common.h
* cp-tree.h (class temp_override): Moved temp_override to
c-common.h
* init.cc: included c-common.h
* pt.cc: included c-common.h
* reflect.cc: included c-common.h
Signed-off-by: Sammy Al Hashemi <[email protected]>
---
gcc/c-family/c-common.h | 20 +++++++++++++++++++
gcc/c-family/c-warn.cc | 7 +++++--
gcc/cp/constexpr.cc | 1 +
gcc/cp/cp-gimplify.cc | 1 +
gcc/cp/cp-tree.h | 19 ------------------
gcc/cp/init.cc | 1 +
gcc/cp/pt.cc | 1 +
gcc/cp/reflect.cc | 1 +
gcc/doc/invoke.texi | 16 +++++++++------
.../c-c++-common/Wstrict-aliasing2-with-fno.c | 12 +++++++++++
.../c-c++-common/Wstrict-aliasing3-with-fno.c | 12 +++++++++++
11 files changed, 64 insertions(+), 27 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-common.h b/gcc/c-family/c-common.h
index d9ed2b070f5..50db268e6f2 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -1750,4 +1750,24 @@ namespace selftest {
} // namespace selftest
#endif /* #if CHECKING_P */
+/* RAII sentinel that saves the value of a variable, optionally
+ overrides it right away, and restores its value when the sentinel
+ id destructed. */
+
+template <typename T>
+class temp_override
+{
+ T& overridden_variable;
+ T saved_value;
+public:
+ temp_override(T& var) : overridden_variable (var), saved_value (var) {}
+ temp_override(T& var, T overrider)
+ : overridden_variable (var), saved_value (var)
+ {
+ overridden_variable = overrider;
+ }
+ ~temp_override() { overridden_variable = saved_value; }
+};
+
+
#endif /* ! GCC_C_COMMON_H */
diff --git a/gcc/c-family/c-warn.cc b/gcc/c-family/c-warn.cc
index 1767d2dc090..620a5eeb01f 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,10 @@ 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. */
+ temp_override<int> save (flag_strict_aliasing, 1);
+
if ((warn_strict_aliasing > 1) && TREE_CODE (expr) == ADDR_EXPR
&& (DECL_P (TREE_OPERAND (expr, 0))
|| handled_component_p (TREE_OPERAND (expr, 0))))
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index 97dde5a310d..94207dce9f1 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h"
#include "cp-tree.h"
#include "varasm.h"
+#include "c-family/c-common.h"
#include "c-family/c-objc.h"
#include "tree-iterator.h"
#include "gimplify.h"
diff --git a/gcc/cp/cp-gimplify.cc b/gcc/cp/cp-gimplify.cc
index 6845134c01d..b65810a1689 100644
--- a/gcc/cp/cp-gimplify.cc
+++ b/gcc/cp/cp-gimplify.cc
@@ -30,6 +30,7 @@ along with GCC; see the file COPYING3. If not see
#include "stor-layout.h"
#include "tree-iterator.h"
#include "gimplify.h"
+#include "c-family/c-common.h"
#include "c-family/c-ubsan.h"
#include "stringpool.h"
#include "attribs.h"
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index bf477a67a34..5f22f911864 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -2255,25 +2255,6 @@ public:
}
};
-/* RAII sentinel that saves the value of a variable, optionally
- overrides it right away, and restores its value when the sentinel
- id destructed. */
-
-template <typename T>
-class temp_override
-{
- T& overridden_variable;
- T saved_value;
-public:
- temp_override(T& var) : overridden_variable (var), saved_value (var) {}
- temp_override(T& var, T overrider)
- : overridden_variable (var), saved_value (var)
- {
- overridden_variable = overrider;
- }
- ~temp_override() { overridden_variable = saved_value; }
-};
-
/* Wrapping a template parameter in type_identity_t hides it from template
argument deduction. */
#if __cpp_lib_type_identity
diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc
index 8d0018a31cc..f7133577bfb 100644
--- a/gcc/cp/init.cc
+++ b/gcc/cp/init.cc
@@ -28,6 +28,7 @@ along with GCC; see the file COPYING3. If not see
#include "stringpool.h"
#include "varasm.h"
#include "gimplify.h"
+#include "c-family/c-common.h"
#include "c-family/c-ubsan.h"
#include "intl.h"
#include "stringpool.h"
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 4683b57f34b..83366cdc083 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see
#include "attribs.h"
#include "stor-layout.h"
#include "intl.h"
+#include "c-family/c-common.h"
#include "c-family/c-objc.h"
#include "cp-objcp-common.h"
#include "toplev.h"
diff --git a/gcc/cp/reflect.cc b/gcc/cp/reflect.cc
index 673b79d0bde..f12de2bf19c 100644
--- a/gcc/cp/reflect.cc
+++ b/gcc/cp/reflect.cc
@@ -28,6 +28,7 @@ along with GCC; see the file COPYING3. If not see
#include "stringpool.h" // for get_identifier
#include "intl.h"
#include "attribs.h"
+#include "c-family/c-common.h"
#include "c-family/c-pragma.h" // for parse_in
#include "gimplify.h" // for unshare_expr
#include "metafns.h"
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