[gcc r16-6817] c, c++: Fix vector enum division handling [PR123437]

Jakub Jelinek jakub@gcc.gnu.org
Fri Jan 16 10:04:20 GMT 2026


https://gcc.gnu.org/g:3556beac9c893a136a449be2df3618a833b743e0

commit r16-6817-g3556beac9c893a136a449be2df3618a833b743e0
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Fri Jan 16 11:03:18 2026 +0100

    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  <jakub@redhat.com>
                Peter Damianov  <peter0x44@disroot.org>
    
            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:
---
 gcc/c/c-typeck.cc                     |  6 ++++--
 gcc/cp/typeck.cc                      |  5 ++++-
 gcc/testsuite/c-c++-common/pr123437.c | 12 ++++++++++++
 3 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 04b33111f629..60ed44c2f672 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 290359c938e8..980f2d115a66 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 000000000000..41ddf05f4cf4
--- /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;
+}


More information about the Gcc-cvs mailing list