From 14151428978dc4e82a66807397a295aa58e3f80d Mon Sep 17 00:00:00 2001
From: Andre Maroneze <andre.maroneze@cea.fr>
Date: Mon, 2 Sep 2024 13:41:40 +0200
Subject: [PATCH] [Kernel] Cabs2cil: fix several operators with _Generic

---
 src/kernel_internals/typing/cabs2cil.ml   | 11 ++++++-----
 tests/syntax/generic.c                    | 10 ++++++++++
 tests/syntax/oracle/generic.10.res.oracle |  9 +++++++++
 3 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/src/kernel_internals/typing/cabs2cil.ml b/src/kernel_internals/typing/cabs2cil.ml
index 1753414b85b..63d023836e1 100644
--- a/src/kernel_internals/typing/cabs2cil.ml
+++ b/src/kernel_internals/typing/cabs2cil.ml
@@ -5975,7 +5975,7 @@ and doExp local_env
         | Cabs.VARIABLE _ | Cabs.UNARY (Cabs.MEMOF, _) (* Regular lvalues *)
         | Cabs.CONSTANT (Cabs.CONST_STRING _) | Cabs.CONSTANT (Cabs.CONST_WSTRING _)
         | Cabs.INDEX _ | Cabs.MEMBEROF _ | Cabs.MEMBEROFPTR _
-        | Cabs.CAST (_, Cabs.COMPOUND_INIT _) ->
+        | Cabs.GENERIC _ | Cabs.CAST (_, Cabs.COMPOUND_INIT _) ->
           begin
             let (r, se, e', t) =
               doExp local_env CNoConst e (AExp None)
@@ -6021,7 +6021,7 @@ and doExp local_env
           Kernel.fatal ~current:true "normalization of unop failed"
         | (Cabs.VARIABLE _ | Cabs.UNARY (Cabs.MEMOF, _) | (* Regular lvalues *)
            Cabs.INDEX _ | Cabs.MEMBEROF _ | Cabs.MEMBEROFPTR _ |
-           Cabs.CAST _ (* A GCC extension *)) -> begin
+           Cabs.GENERIC _ | Cabs.CAST _ (* A GCC extension *)) -> begin
             let uop' = if uop = Cabs.PREINCR then PlusA else MinusA in
             if asconst = CConst then
               Kernel.warning ~current:true "PREINCR or PREDECR in constant";
@@ -6054,7 +6054,7 @@ and doExp local_env
           Kernel.fatal ~current:true "normalization of unop failed"
         | Cabs.VARIABLE _ | Cabs.UNARY (Cabs.MEMOF, _) (* Regular lvalues *)
         | Cabs.INDEX _ | Cabs.MEMBEROF _ | Cabs.MEMBEROFPTR _
-        | Cabs.CAST _ (* A GCC extension *) -> begin
+        | Cabs.GENERIC _ | Cabs.CAST _ (* A GCC extension *) -> begin
             if asconst = CConst then
               Kernel.warning ~current:true "POSTINCR or POSTDECR in constant";
             (* If we do not drop the result then we must save the value *)
@@ -6110,7 +6110,8 @@ and doExp local_env
           Kernel.fatal
             ~current:true "normalization of lval in assignment failed"
         | (Cabs.VARIABLE _ | Cabs.UNARY (Cabs.MEMOF, _) | (* Regular lvalues *)
-           Cabs.INDEX _ | Cabs.MEMBEROF _ | Cabs.MEMBEROFPTR _ ) -> begin
+           Cabs.INDEX _ | Cabs.MEMBEROF _ | Cabs.MEMBEROFPTR _ |
+           Cabs.GENERIC _ ) -> begin
             if asconst = CConst then
               Kernel.warning ~current:true "ASSIGN in constant";
             let se0 = unspecified_chunk empty in
@@ -6211,7 +6212,7 @@ and doExp local_env
           Kernel.fatal ~current:true "normalization of lval in compound assignment failed"
         | Cabs.VARIABLE _ | Cabs.UNARY (Cabs.MEMOF, _) | (* Regular lvalues *)
           Cabs.INDEX _ | Cabs.MEMBEROF _ | Cabs.MEMBEROFPTR _ |
-          Cabs.CAST _ (* GCC extension *) -> begin
+          Cabs.GENERIC _ | Cabs.CAST _ (* GCC extension *) -> begin
             if asconst = CConst then
               Kernel.warning ~current:true "op_ASSIGN in constant";
             let bop' = match bop with
diff --git a/tests/syntax/generic.c b/tests/syntax/generic.c
index 15a9d6aa05f..4864c662eb4 100644
--- a/tests/syntax/generic.c
+++ b/tests/syntax/generic.c
@@ -77,5 +77,15 @@ int main() {
   int ok4 = _Generic(p, void(*)(int): 0, void(*)(long): 1);
   double c = cbrt(0.0f);
   int ok5 = _Generic(foo, fptr: 0, int: 4, vfptr: 5);
+
+  char vtc[2] = {4, -3};
+  double vtd[2] = {4.0, -3.0};
+  double *vt = &_Generic(vt, char*: vtc[0], double*: vtd[0]);
+  int x = 3;
+  short y = 4;
+  _Generic(42, short: y, int: x)++;
+  --_Generic(42, short: y, int: x);
+  _Generic(42, short: y, int: x) += 10;
+  _Generic(42, short: y, int: x) = 10;
   return 0;
 }
diff --git a/tests/syntax/oracle/generic.10.res.oracle b/tests/syntax/oracle/generic.10.res.oracle
index 70bdefa20fd..0260f779bf2 100644
--- a/tests/syntax/oracle/generic.10.res.oracle
+++ b/tests/syntax/oracle/generic.10.res.oracle
@@ -25,6 +25,15 @@ int main(void)
   tmp = cbrtf(0.0f);
   double c = (double)tmp;
   int ok5 = 0;
+  char vtc[2] = {(char)4, (char)(-3)};
+  double vtd[2] = {4.0, - 3.0};
+  double *vt = vtd;
+  int x = 3;
+  short y = (short)4;
+  x ++;
+  x --;
+  x += 10;
+  x = 10;
   __retres = 0;
   return __retres;
 }
-- 
GitLab