From: Jakub Jelinek Date: Fri, 16 Jan 2026 10:03:18 +0000 (+0100) Subject: c, c++: Fix vector enum division handling [PR123437] X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3556beac9c893a136a449be2df3618a833b743e0;p=thirdparty%2Fgcc.git c, c++: Fix vector enum division handling [PR123437] To my surprise we accept generic vectors with enumeral element types (unlike e.g. _Complex) and we don't actually try to perform "integral" promotions for those either (which for scalars promotes ENUMERAL_TYPE operands to their underlying type or promoted underlying type). I'm afraid it is inappropriate to change the promotions at this point in stage4, that would be a significant user visible change (though sure for a feature that hopefully nobody actually uses). Anyway, in GCC 16 development some assertions that RDIV_EXPR is only used for floating (scalar/vector/complex) operands were added and those now trigger on trying to divide vectors where both operands are enum vectors. THis is due to the FEs using RDIV_EXPR instead of TRUNC_DIV_EXPR when the operands (after promotions) don't have INTEGER_TYPE (or for C BITINT_TYPE) operands. This patch just adds vector enum to that. 2026-01-16 Jakub Jelinek Peter Damianov PR c/123437 * c-typeck.cc (build_binary_op): Don't use RDIV_EXPR resultcode if both types are integral, _BitInt or newly VECTOR_TYPE of ENUMERAL_TYPE. * typeck.cc (cp_build_binary_op): Don't use RDIV_EXPR resultcode if both types are integral, _BitInt or newly VECTOR_TYPE of ENUMERAL_TYPE. * c-c++-common/pr123437.c: New test. --- diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc index 04b33111f62..60ed44c2f67 100644 --- a/gcc/c/c-typeck.cc +++ b/gcc/c/c-typeck.cc @@ -14469,8 +14469,10 @@ build_binary_op (location_t location, enum tree_code code, if (code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE) tcode1 = TREE_CODE (TREE_TYPE (TREE_TYPE (op1))); - if (!(((tcode0 == INTEGER_TYPE || tcode0 == BITINT_TYPE) - && (tcode1 == INTEGER_TYPE || tcode1 == BITINT_TYPE)) + if (!(((tcode0 == INTEGER_TYPE || tcode0 == BITINT_TYPE + || (tcode0 == ENUMERAL_TYPE && code0 == VECTOR_TYPE)) + && (tcode1 == INTEGER_TYPE || tcode1 == BITINT_TYPE + || (tcode1 == ENUMERAL_TYPE && code1 == VECTOR_TYPE))) || (tcode0 == FIXED_POINT_TYPE && tcode1 == FIXED_POINT_TYPE))) resultcode = RDIV_EXPR; else diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc index 290359c938e..980f2d115a6 100644 --- a/gcc/cp/typeck.cc +++ b/gcc/cp/typeck.cc @@ -5858,7 +5858,10 @@ cp_build_binary_op (const op_location_t &location, if (tcode1 == COMPLEX_TYPE || tcode1 == VECTOR_TYPE) tcode1 = TREE_CODE (TREE_TYPE (TREE_TYPE (op1))); - if (!(tcode0 == INTEGER_TYPE && tcode1 == INTEGER_TYPE)) + if (!((tcode0 == INTEGER_TYPE + || (tcode0 == ENUMERAL_TYPE && code0 == VECTOR_TYPE)) + && (tcode1 == INTEGER_TYPE + || (tcode1 == ENUMERAL_TYPE && code1 == VECTOR_TYPE)))) resultcode = RDIV_EXPR; else { diff --git a/gcc/testsuite/c-c++-common/pr123437.c b/gcc/testsuite/c-c++-common/pr123437.c new file mode 100644 index 00000000000..41ddf05f4cf --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr123437.c @@ -0,0 +1,12 @@ +/* PR c/123437 */ +/* { dg-do compile } */ + +enum E { F }; +typedef enum E V __attribute__ ((vector_size (16))); +V x, y, z; + +void +foo () +{ + z = x / y; +}