From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mailrelay.tugraz.at (mailrelay.tugraz.at [129.27.2.202]) by sourceware.org (Postfix) with ESMTPS id 4463C3858288 for ; Sun, 19 May 2024 10:24:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 4463C3858288 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=tugraz.at Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=tugraz.at ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 4463C3858288 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=129.27.2.202 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1716114280; cv=none; b=KV5n6ayg90a6G7cTFjr8GBRlTTD2nR4SaN/o4fjCIvepFoFNCmmCv+CkAB0pEkgkTikaTb4wmI/h0jXYlnVSFV2vXFnyr7kpmmDVoiXCjFzJa4QQy/3OZSfihwkdYGtZqdEc9EqWT4nJej8aw5eaaKN2pzSsH7mJLkH64t/V5Hs= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1716114280; c=relaxed/simple; bh=BhSz5ABTjMIw/bFZXK5sDewSckTsVIYoTr8X5HBrUn8=; h=DKIM-Signature:Message-ID:Subject:From:To:Date:MIME-Version; b=imhiTJllBdPdznVVz3OqO+YVQOAcEUMgNmJGfbYFDJhSqy8GOdPzKkTpLgRARhd2gi0GCwmOvYFJNwDmVtnVR266LweGvLUTWskiWGwdmivrvomr24djGcuU0FI65SsDpdQwpj/QA8HanuFKcVbamfCCRFacj4VjLdoGKo8h+RA= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from vra-169-182.tugraz.at (vra-169-182.tugraz.at [129.27.169.182]) by mailrelay.tugraz.at (Postfix) with ESMTPSA id 4VhxdQ4bxvz3wZs; Sun, 19 May 2024 12:24:26 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tugraz.at; s=mailrelay; t=1716114266; bh=8mDAzW9YC6HFLN6AlgXAJa5Pry/YnKAYhkbC/3qe8Vo=; h=Subject:From:To:Cc:Date:In-Reply-To:References; b=L//E/cM7LnxzXcnwbX8VJtRtt5T2Q+IqYI15jNKcMFMU3y9+Kkr8cdEYSfbatFNYp 4LBv+eIRH1KR1gEX5CxCKsM5iLnZQeTokjHLYX9+cz/uzQm72h70vFE78AJvGUhq4O UdB58GO0PMnCz0NSHWte9P0TjSEKkZ2jlnR7UEbM= Message-ID: <194e5cd68595c5c923b869be2d875ed0991b98f0.camel@tugraz.at> Subject: [C PATCH, v2] Fix for redeclared enumerator initialized with different type [PR115109] From: Martin Uecker To: gcc-patches@gcc.gnu.org Cc: Joseph Myers Date: Sun, 19 May 2024 12:24:26 +0200 In-Reply-To: <45067a3258e0ec1677ed95f62ac21c1353d66355.camel@tugraz.at> References: <02a9b94e4d653b6f1b9f89a1b62187f46e871738.camel@tugraz.at> <45067a3258e0ec1677ed95f62ac21c1353d66355.camel@tugraz.at> Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable User-Agent: Evolution 3.46.4-2 MIME-Version: 1.0 X-TUG-Backscatter-control: G/VXY7/6zeyuAY/PU2/0qw X-Spam-Scanner: SpamAssassin 3.003001 X-Spam-Score-relay: -1.9 X-Scanned-By: MIMEDefang 2.74 on 129.27.10.116 X-Spam-Status: No, score=-11.5 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: First version was flawed, as it used the wrong type. Here is another iteration. Bootstrapped and regression tested on x86_64. c23: Fix for redeclared enumerator initialized with different type [PR1= 15109] =20 c23 specifies that the type of a redeclared enumerator is the one of th= e previous declaration. Convert initializers with different type accordi= ngly and add -Woverflow warning. =20 2024-05-18 Martin Uecker =20 PR c/115109 =20 gcc/c/ * c-decl.cc (build_enumerator): When redeclaring an enumerator convert value to previous type. For redeclared enumerators use underlying type for computing the next value. =20 gcc/testsuite/ * gcc.dg/pr115109.c: New test. * gcc.dg/c23-tag-enum-6.c: New test. * gcc.dg/c23-tag-enum-7.c: New test. diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index b691b91b3db..540927a8df6 100644 --- a/gcc/c/c-decl.cc +++ b/gcc/c/c-decl.cc @@ -10209,6 +10209,7 @@ build_enumerator (location_t decl_loc, location_t l= oc, struct c_enum_contents *the_enum, tree name, tree value) { tree decl; + tree old_decl; =20 /* Validate and default VALUE. */ =20 @@ -10268,6 +10269,24 @@ build_enumerator (location_t decl_loc, location_t = loc, definition. */ value =3D convert (the_enum->enum_type, value); } + else if (flag_isoc23 + && (old_decl =3D lookup_name_in_scope (name, current_scope)) + && old_decl !=3D error_mark_node + && TREE_TYPE (old_decl) + && TREE_TYPE (TREE_TYPE (old_decl)) + && TREE_CODE (old_decl) =3D=3D CONST_DECL) + { + /* Enumeration constants in a redeclaration have the previous type. = */ + tree previous_type =3D TREE_TYPE (DECL_INITIAL (old_decl)); + if (!int_fits_type_p (value, previous_type)) + { + warning_at (loc, OPT_Woverflow, + "value of redeclared enumerator outside the range of " + "the previous type %qT", previous_type); + locate_old_decl (old_decl); + } + value =3D convert (previous_type, value); + } else { /* Even though the underlying type of an enum is unspecified, the @@ -10334,9 +10353,14 @@ build_enumerator (location_t decl_loc, location_t = loc, false); } else - the_enum->enum_next_value - =3D build_binary_op (EXPR_LOC_OR_LOC (value, input_location), - PLUS_EXPR, value, integer_one_node, false); + { + /* In a redeclaration the type can already be the enumeral type. */ + if (TREE_CODE (TREE_TYPE (value)) =3D=3D ENUMERAL_TYPE) + value =3D convert (ENUM_UNDERLYING_TYPE (TREE_TYPE (value)), value); + the_enum->enum_next_value + =3D build_binary_op (EXPR_LOC_OR_LOC (value, input_location), + PLUS_EXPR, value, integer_one_node, false); + } the_enum->enum_overflow =3D tree_int_cst_lt (the_enum->enum_next_value, = value); if (the_enum->enum_overflow && !ENUM_FIXED_UNDERLYING_TYPE_P (the_enum->enum_type)) diff --git a/gcc/testsuite/gcc.dg/c23-tag-enum-6.c b/gcc/testsuite/gcc.dg/c= 23-tag-enum-6.c new file mode 100644 index 00000000000..ff9ec89775e --- /dev/null +++ b/gcc/testsuite/gcc.dg/c23-tag-enum-6.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-std=3Dc23" } */ + +#include + +enum E : int { a =3D 1, b =3D 2 }; +enum E : int { b =3D _Generic(a, enum E: 2), a =3D 1 }; + +enum H { x =3D 1 }; +enum H { x =3D 2UL + UINT_MAX }; /* { dg-warning "outside the range" } */ + +enum K : int { z =3D 1 }; +enum K : int { z =3D 2UL + UINT_MAX }; /* { dg-error "outside the range" }= */ + diff --git a/gcc/testsuite/gcc.dg/c23-tag-enum-7.c b/gcc/testsuite/gcc.dg/c= 23-tag-enum-7.c new file mode 100644 index 00000000000..4a5b4bc63f6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c23-tag-enum-7.c @@ -0,0 +1,41 @@ +/* { dg-do compile } + * { dg-options "-std=3Dc23" } */ + +#include + +// enumerators are all representable in int +enum E { a =3D 1UL, b =3D _Generic(a, int: 2) }; +static_assert(_Generic(a, int: 1)); +static_assert(_Generic(b, int: 1)); +enum E { a =3D 1UL, b =3D _Generic(a, int: 2) }; +static_assert(_Generic(a, int: 1)); +static_assert(_Generic(b, int: 1)); + +// enumerators are not representable in int +enum H { c =3D 1UL << (UINT_WIDTH + 1), d =3D 2 }; +static_assert(_Generic(c, enum H: 1)); +static_assert(_Generic(d, enum H: 1)); +enum H { c =3D 1UL << (UINT_WIDTH + 1), d =3D _Generic(c, enum H: 2) }; +static_assert(_Generic(c, enum H: 1)); +static_assert(_Generic(d, enum H: 1)); + +// there is an overflow in the first redeclaration +enum K { e =3D UINT_MAX, f, g =3D _Generic(e, unsigned int: 0) + _Generic(= f, unsigned long: 1) }; +static_assert(_Generic(e, enum K: 1)); +static_assert(_Generic(f, enum K: 1)); +static_assert(_Generic(g, enum K: 1)); +enum K { e =3D UINT_MAX, f, g =3D _Generic(e, enum K: 0) + _Generic(f, enu= m K: 1) }; +static_assert(_Generic(e, enum K: 1)); +static_assert(_Generic(f, enum K: 1)); +static_assert(_Generic(g, enum K: 1)); + +// there is an overflow in the first redeclaration +enum U { k =3D INT_MAX, l, m =3D _Generic(k, int: 0) + _Generic(l, long: 1= ) }; +static_assert(_Generic(k, enum U: 1)); +static_assert(_Generic(l, enum U: 1)); +static_assert(_Generic(m, enum U: 1)); +enum U { k =3D INT_MAX, l, m =3D _Generic(k, enum U: 0) + _Generic(l, enum= U: 1) }; +static_assert(_Generic(k, enum U: 1)); +static_assert(_Generic(l, enum U: 1)); +static_assert(_Generic(m, enum U: 1)); + diff --git a/gcc/testsuite/gcc.dg/pr115109.c b/gcc/testsuite/gcc.dg/pr11510= 9.c new file mode 100644 index 00000000000..961197d0c71 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr115109.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-options "-std=3Dc23" } */ + +#include + +enum E { a =3D 1UL << (ULONG_WIDTH - 5), b =3D 2 }; +enum E { a =3D 1ULL << (ULONG_WIDTH - 5), b =3D _Generic(a, enum E: 2) }; +