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