https://gcc.gnu.org/g:8e3291f507757e40336600e09ead9d1123eefe1e

commit r16-5438-g8e3291f507757e40336600e09ead9d1123eefe1e
Author: Jakub Jelinek <[email protected]>
Date:   Thu Nov 20 07:59:13 2025 +0100

    c++: Fix error recovery for enums with bad underlying type [PR122540]
    
    The r16-4698 patch to use fold_convert in finish_enum_value_list instead
    of copy_node + set TREE_TYPE caused UB in the compiler as detected e.g.
    by valgrind on the g++.dg/parse/pr96442.C g++.dg/cpp0x/auto9.C testcases.
    If underlying type is valid, start_enum does:
          else if (CP_INTEGRAL_TYPE_P (underlying_type))
            {
              copy_type_enum (enumtype, underlying_type);
              ENUM_UNDERLYING_TYPE (enumtype) = underlying_type;
            }
    and the copy_type_enum ensures the ENUMERAL_TYPE has the same
    TYPE_PRECISION, TYPE_SIZE etc.  But if the underlying type is erroneous,
    it errors and for error recovery sets
    ENUM_UNDERLYING_TYPE (enumtype) = integer_type_node;
    This means TYPE_PRECISION on the ENUMERAL_TYPE remains 0, TYPE_SIZE NULL
    etc. and then later on when we try to fold_convert the enumerator values
    to that type, we invoke UB in the wide_int code because it really doesn't
    like casts to 0 precision integral types.
    
    The following patch fixes it by calling also copy_type_enum from
    integer_type_node when we set such underlying type.
    
    2025-11-20  Jakub Jelinek  <[email protected]>
    
            PR c++/122540
            * decl.cc (start_enum): When setting ENUM_UNDERLYING_TYPE
            to integer_type_node during error recovery, also call 
copy_type_enum.

Diff:
---
 gcc/cp/decl.cc | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 29165e447b38..c62f0777f5b2 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -18723,6 +18723,7 @@ start_enum (tree name, tree enumtype, tree 
underlying_type,
        {
          error ("underlying type %qT of %qT must be an integral type",
                 underlying_type, enumtype);
+         copy_type_enum (enumtype, integer_type_node);
          ENUM_UNDERLYING_TYPE (enumtype) = integer_type_node;
        }
     }

Reply via email to