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
>

Reply via email to