Hi Andrea,

I really appreciate the help and guidance along the way. This was my first 
contribution and I really appreciate your help. I will definitely stay involved 
in the project :)

Best,
Sammy

On Wed, Aug 26, 2026, at 9:25 PM, Andrea Pinski wrote:
> On Wed, Aug 26, 2026 at 2:50 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: Include opts.h.
> >         (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]>
> 
> Now pushed as r17-3685-g39ba948f9b86e1.  Thanks for the patch and
> revisions while we did the review and this last rebase.
> Hope you continue to contribute to GCC too.
> 
> Thanks,
> Andrea
> 
> 
> > ---
> > v8:
> >   - Rebase onto current master.  Upstream commit 3a578f6fcb8 changed
> >     temp_override to take type_identity_t<T> as its second constructor
> >     argument and moved the type_identity_t definition above the class;
> >     carry that version over to c-common.h, which is what made v7 fail
> >     to apply.
> >   - Include "opts.h" directly rather than by relative path.
> >
> > v7:
> >   - Replace bad include of "lto-opts.cc" to "opts.h".
> >
> > 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 b89a8477e7c..197db508c16 100644
> > --- a/gcc/c-family/c-common.h
> > +++ b/gcc/c-family/c-common.h
> > @@ -1752,4 +1752,55 @@ namespace selftest {
> >  } // namespace selftest
> >  #endif /* #if CHECKING_P */
> >
> > +/* 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
> > +
> > +/* 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, type_identity_t<T> overrider)
> > +    : overridden_variable (var), saved_value (var)
> > +  {
> > +    overridden_variable = overrider;
> > +  }
> > +  ~temp_override() { overridden_variable = saved_value; }
> > +};
> > +
> > +/* 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..a27dda88e12 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 "opts.h"
> >
> >  /* 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 ab7729c0613..0f989eb1648 100644
> > --- a/gcc/cp/cp-tree.h
> > +++ b/gcc/cp/cp-tree.h
> > @@ -2266,57 +2266,6 @@ public:
> >    }
> >  };
> >
> > -/* 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
> > -
> > -/* 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, type_identity_t<T> overrider)
> > -    : overridden_variable (var), saved_value (var)
> > -  {
> > -    overridden_variable = overrider;
> > -  }
> > -  ~temp_override() { overridden_variable = saved_value; }
> > -};
> > -
> > -/* 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 d30ff18a1f2..e119e149fb1 100644
> > --- a/gcc/doc/invoke.texi
> > +++ b/gcc/doc/invoke.texi
> > @@ -8751,17 +8751,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
> >
> 

Reply via email to