From 5b2aa385f9aa5e23140afdee701a390bf3500e30 Mon Sep 17 00:00:00 2001
From: Basile Desloges <basile.desloges@cea.fr>
Date: Wed, 18 Sep 2024 10:38:37 +0200
Subject: [PATCH] [kernel] Const-fold enum value in ternary ops

When using an enum in a ternary operator, the value is const-folded
before checking if it evaluates to `true` or `false` so that const-expr
used as enum values are supported.
---
 src/kernel_internals/typing/cabs2cil.ml | 2 +-
 tests/syntax/enum1.c                    | 6 ++++++
 tests/syntax/oracle/enum1.res.oracle    | 7 +++++++
 3 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/src/kernel_internals/typing/cabs2cil.ml b/src/kernel_internals/typing/cabs2cil.ml
index 4bc7199b1be..abb0e06bdcd 100644
--- a/src/kernel_internals/typing/cabs2cil.ml
+++ b/src/kernel_internals/typing/cabs2cil.ml
@@ -1425,7 +1425,7 @@ let rec isConstTrueFalse c: [ `CTrue | `CFalse ] =
   | CReal(f, _, _) ->
     if f = 0.0 then `CFalse else `CTrue
   | CEnum {eival = e} ->
-    match isExpTrueFalse e with
+    match isExpTrueFalse (Cil.constFold true e) with
     | `CTrue | `CFalse as r -> r
     | `CUnknown -> Kernel.fatal ~current:true "Non-constant enum"
 (* Evaluate expressions to `CTrue, `CFalse or `CUnknown *)
diff --git a/tests/syntax/enum1.c b/tests/syntax/enum1.c
index 74487342a08..86966132878 100644
--- a/tests/syntax/enum1.c
+++ b/tests/syntax/enum1.c
@@ -28,3 +28,9 @@ enum Foo { EN1, EN2, EN3 };
 int f() { return !EN1; }
 
 int g() { return EN1; }
+
+enum Bar { CONST_ENUM = 1 == 2 };
+
+int h() {
+  return CONST_ENUM ? 0 : 1;
+}
diff --git a/tests/syntax/oracle/enum1.res.oracle b/tests/syntax/oracle/enum1.res.oracle
index 73766d556e6..b0fc1e66898 100644
--- a/tests/syntax/oracle/enum1.res.oracle
+++ b/tests/syntax/oracle/enum1.res.oracle
@@ -67,6 +67,13 @@ int g(void)
   return __retres;
 }
 
+int h(void)
+{
+  int __retres;
+  __retres = 1;
+  return __retres;
+}
+
 int e2(void)
 {
   int __retres;
-- 
GitLab