https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122185

--- Comment #27 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jakub Jelinek <[email protected]>:

https://gcc.gnu.org/g:fb22d7f3b665555cfb55673ca2b954f860d28b50

commit r16-5506-gfb22d7f3b665555cfb55673ca2b954f860d28b50
Author: Jakub Jelinek <[email protected]>
Date:   Sat Nov 22 12:24:35 2025 +0100

    c++: Readd type checks for cp_fold -ffold-simple-inlines foldings
[PR122185]

    In GCC15, cp_fold -ffold-simple-inlines code contained
      if (INDIRECT_TYPE_P (TREE_TYPE (x))
          && INDIRECT_TYPE_P (TREE_TYPE (r)))
    check around the optimization, but as std::to_underlying has been
    added to the set, it got removed.
    Now, the check isn't needed when using correct libstdc++-v3 headers,
    because the function template types ensure the converted types are sane
    (so for most of them both are some kind of REFERENCE_TYPEs, for addressof
    one REFERENCE_TYPE and one POINTER_TYPE, for to_underlying one
ENUMERAL_TYPE
    and one INTEGRAL_TYPE_P).
    But when some fuzzer or user attempts to implement one or more of those
    std:: functions and does it wrong (sure, such code is invalid), we can ICE
    because build_nop certainly doesn't handle all possible type conversions.

    So, the following patch readds the INDIRECT_REF_P && INDIRECT_REF_P check
    for everything but to_underlying, for which it checks ENUMERAL_TYPE to
    INTEGRAL_TYPE_P.  That way we don't ICE on bogus code.

    Though, I wonder about 2 things, whether the CALL_EXPR_ARG in there
    shouldn't be also guarded just in case somebody tries to compile
    namespace std { int to_underlying (); }; int a = std::to_underlying ();
    and also whether this to_underlying folding doesn't behave differently
    from the libstdc++-v3 implementation if the enum is
    enum A : bool { B, C };
    I think -fno-fold-simple-inlines will compile it as != 0, while
    the -ffold-simple-inlines code just as a cast.  Sure, enum with underlying
    bool can't contain enumerators with values other than 0 and 1, but it is
    still 8-bit at least and so what happens with other values?

    2025-11-22  Jakub Jelinek  <[email protected]>

            PR c++/122185
            * cp-gimplify.cc (cp_fold) <case CALL_EXPR>: For
-ffold-simple-inlines
            restore check that both types are INDIRECT_TYPE_P, except for
            "to_underlying" check that r has ENUMERAL_TYPE and x has
            INTEGRAL_TYPE_P.

            * g++.dg/cpp1z/pr122185.C: New test.

Reply via email to