diff --git a/src/frontc/cabs2cil.ml b/src/frontc/cabs2cil.ml index fd6e239ce..2f4dea79b 100644 --- a/src/frontc/cabs2cil.ml +++ b/src/frontc/cabs2cil.ml @@ -4459,7 +4459,7 @@ and doExp (asconst: bool) (* This expression is used as a constant *) the castTo do this work. This was necessary for test/small1/union5, in which a transparent union is passed as an argument *) - let (sa, a', att) = force_right_to_left_evaluation (doExp false a (AExp None)) in + let (sa, a', att) = force_right_to_left_evaluation (doExp asconst a (AExp None)) in let (_, a'') = castTo ~kind:Implicit att at a' in (* C11 6.5.2.2.7 *) (sa :: ss, a'' :: args') | ([], args) -> (* No more types *) @@ -4469,7 +4469,7 @@ and doExp (asconst: bool) (* This expression is used as a constant *) | [] -> ([], []) | a :: args -> let (ss, args') = loop args in - let (sa, a', at) = force_right_to_left_evaluation (doExp false a (AExp None)) in + let (sa, a', at) = force_right_to_left_evaluation (doExp asconst a (AExp None)) in if isBuiltinChooseExprOrTgmath then (* This built-in function is analogous to the `? :' operator in C, except that the expression returned diff --git a/test/small1/builtin_choose_expr2.c b/test/small1/builtin_choose_expr2.c new file mode 100644 index 000000000..61606f8cc --- /dev/null +++ b/test/small1/builtin_choose_expr2.c @@ -0,0 +1,5 @@ +// Both bitfield widths shall be evaluated constantly +struct S1 { + int x : __builtin_choose_expr(sizeof(long) > sizeof(int) || sizeof(int) > sizeof(short), 1, 2), + y : __builtin_choose_expr(sizeof(char) > sizeof(short) && sizeof(char) == sizeof(char), 3, 4); +} s1; diff --git a/test/testcil.pl b/test/testcil.pl index 07ac32d9d..c1056b055 100644 --- a/test/testcil.pl +++ b/test/testcil.pl @@ -551,6 +551,7 @@ sub addToGroup { addTest("test/builtin2 "); addTest("testrun/builtin3 "); addTest("testrun/builtin_choose_expr"); +addTest("test/builtin_choose_expr2"); addTest("testrungcc/builtin_object_size _GNUCC=1 OPTIMIZE=1"); addTest("testrun/builtin4 "); addTest("test/builtin5 ");