Re: [PATCH v6] c-family: honor explicit -Wstrict-aliasing under -fno-strict-aliasing
Andrea Pinski <[email protected]>
| Newsgroups | gmane.comp.gcc.patches |
|---|---|
| Message-ID | <CALvbMcC22basU_O9phDy5Ef9m2e6Lh95Baw3YzrkOYXgyNGXYQ@mail.gmail.com> |
On Mon, Aug 10, 2026 at 1:20 PM Sammy Al Hashemi <[email protected]> wrote: > > The front-end strict aliasing warning was gated on flag_strict_aliasing, > so -fno-strict-aliasing silenced it even when -Wstrict-aliasing was > requested explicitly. The front-end check is type-based and does not > need the optimization to be active, so honor an explicit -Wstrict-aliasing > regardless of -fstrict-aliasing. > > strict_aliasing_warning temporarily forces flag_strict_aliasing around > the alias set queries so they return meaningful results, but only when > OPTION_SET_P (warn_strict_aliasing) is true. When the warning is only > implied (for example by -Wall), the previous behavior of staying quiet > under -fno-strict-aliasing is preserved. > > This affects only the front-end, type-based diagnostic. The additional > back-end checking, which uses flow-sensitive points-to information for > multiple-statement cases, still runs only when optimization is enabled. > > temp_override and make_temp_override are moved from cp/cp-tree.h to > c-family/c-common.h so the front-end warning code can use them; > in_consteval_if_p_temp_override stays in cp-tree.h as it depends on the > C++-only saved_scope. > > gcc/c-family/ChangeLog: > > * c-common.h (class temp_override): Move from cp-tree.h. > (type_identity_t): Likewise. > (make_temp_override): Likewise. > * c-warn.cc (strict_aliasing_warning): Do not gate on > flag_strict_aliasing. Temporarily enable it around the alias > set queries when -Wstrict-aliasing was requested explicitly. > > gcc/cp/ChangeLog: > > * cp-tree.h (class temp_override): Move to c-common.h. > (type_identity_t): Likewise. > (make_temp_override): Likewise. > > gcc/ChangeLog: > > * doc/invoke.texi (-Wstrict-aliasing): Document that the > front-end type-based checking runs without -fstrict-aliasing > when the warning is requested explicitly. > (-Wstrict-aliasing=n): Likewise. > > 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]> > --- > v6: > - Only bypass the -fstrict-aliasing gate when -Wstrict-aliasing was > requested explicitly (OPTION_SET_P (warn_strict_aliasing)); an > implicit -Wall no longer triggers it under -fno-strict-aliasing. > - Fix the temp_override to span the whole function (v5 scoped it to > an if-block, so it had no effect on the alias-set queries). > - Soften the -Wstrict-aliasing documentation: scope the claim to the > front-end type-based check and restore the note about the back-end > flow-sensitive pass that runs under optimization. > - Also move make_temp_override to c-common.h alongside temp_override; > drop the now-redundant per-file c-family/c-common.h includes. > - ChangeLog: use present tense and trailing periods. > > gcc/c-family/c-common.h | 51 +++++++++++++++++++ > gcc/c-family/c-warn.cc | 11 +++- > gcc/cp/cp-tree.h | 51 ------------------- > gcc/doc/invoke.texi | 24 ++++++--- > .../c-c++-common/Wstrict-aliasing2-with-fno.c | 12 +++++ > .../c-c++-common/Wstrict-aliasing3-with-fno.c | 12 +++++ > 6 files changed, 100 insertions(+), 61 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..82d61dbc575 100644 > --- a/gcc/c-family/c-common.h > +++ b/gcc/c-family/c-common.h > @@ -1750,4 +1750,55 @@ 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; } > +}; > + > +/* Wrapping a template parameter in type_identity_t hides it from template > + argument deduction. */ > +#if __cpp_lib_type_identity > +using std::type_identity_t; > +#else > +template <typename T> > +struct type_identity { typedef T type; }; > +template <typename T> > +using type_identity_t = typename type_identity<T>::type; > +#endif > + > +/* Object generator function for temp_override, so you don't need to write the > + type of the object as a template argument. > + > + Use as auto x = make_temp_override (flag); */ > + > +template <typename T> > +inline temp_override<T> > +make_temp_override (T& var) > +{ > + return { var }; > +} > + > +/* Likewise, but use as auto x = make_temp_override (flag, value); */ > + > +template <typename T> > +inline temp_override<T> > +make_temp_override (T& var, type_identity_t<T> overrider) > +{ > + return { var, overrider }; > +} > + > #endif /* ! GCC_C_COMMON_H */ > diff --git a/gcc/c-family/c-warn.cc b/gcc/c-family/c-warn.cc > index 1767d2dc090..4374e7e4752 100644 > --- a/gcc/c-family/c-warn.cc > +++ b/gcc/c-family/c-warn.cc > @@ -41,6 +41,7 @@ along with GCC; see the file COPYING3. If not see > #include "tree-pretty-print.h" > #include "langhooks.h" > #include "gcc-urlifier.h" > +#include "../lto-opts.cc" I just noticed this include, this seems wrong. I think you just need opts.h here. The rest looks good. I will give others some time (a week or so) to review this but I think once the include is fixed I will push the patch. Thanks, Andrea > > /* Print a warning if a constant expression had overflow in folding. > Invoke this function on every expression that the language > @@ -701,8 +702,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 +710,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. > + Only do this if the user explicitly asked for `-Wstrict-aliasing` */ > + temp_override<int> save (flag_strict_aliasing, > + OPTION_SET_P (warn_strict_aliasing) ? > + 1 : flag_strict_aliasing); > + > 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/cp-tree.h b/gcc/cp/cp-tree.h > index bf477a67a34..9ad4c327e99 100644 > --- a/gcc/cp/cp-tree.h > +++ b/gcc/cp/cp-tree.h > @@ -2255,57 +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 > -using std::type_identity_t; > -#else > -template <typename T> > -struct type_identity { typedef T type; }; > -template <typename T> > -using type_identity_t = typename type_identity<T>::type; > -#endif > - > -/* Object generator function for temp_override, so you don't need to write the > - type of the object as a template argument. > - > - Use as auto x = make_temp_override (flag); */ > - > -template <typename T> > -inline temp_override<T> > -make_temp_override (T& var) > -{ > - return { var }; > -} > - > -/* Likewise, but use as auto x = make_temp_override (flag, value); */ > - > -template <typename T> > -inline temp_override<T> > -make_temp_override (T& var, type_identity_t<T> overrider) > -{ > - return { var, overrider }; > -} > - > /* temp_override for in_consteval_if_p, which can't use make_temp_override > because it is a bitfield. */ > > diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi > index 339d1d2c97a..fe18ba24fe6 100644 > --- a/gcc/doc/invoke.texi > +++ b/gcc/doc/invoke.texi > @@ -8674,17 +8674,25 @@ 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 > -cases, but does attempt to catch the more common pitfalls. It is > -included in @option{-Wall}. > +This option warns about code that might break the strict aliasing rules > +that the compiler uses for optimization. The type-based checking done > +in the front end is performed even when @option{-fstrict-aliasing} is > +not active, provided @option{-Wstrict-aliasing} is requested explicitly; > +it is not performed for @option{-fno-strict-aliasing -Wall} alone. When > +optimization is enabled, the warning also runs in the back end, where it > +handles multiple-statement cases using flow-sensitive points-to > +information. 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. The type-based checking done > +in the front end is performed even when @option{-fstrict-aliasing} is > +not active, provided @option{-Wstrict-aliasing} is requested explicitly. > +When optimization is enabled, the warning also runs in the back end, > +where it handles multiple-statement cases using flow-sensitive points-to > +information. > 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.55.0 >