Problem
Summary
STruC++ raises a semantic error — CASE selector must be an integer, bit, or
enum type, got LREAL — for a CASE statement whose selector is REAL/LREAL,
even when the selector is an integer-producing conversion such as TRUNC(...).
Environment
- STruC++ version: 0.6.2
- The error is emitted by
strucpp semantic analysis (before codegen).
Impact
No response
Reproduction
case_real.st:
PROGRAM PLC_PRG
VAR
In1 : LREAL;
y : INT;
END_VAR
CASE TRUNC(In1) OF
0: y := 10;
1: y := 20;
ELSE
y := 0;
END_CASE;
END_PROGRAM
strucpp case_real.st -o case_real.cpp --no-default-libs
Actual result
Compilation failed:
case_real.st:6:10: error: CASE selector must be an integer, bit, or enum type, got LREAL
6 | CASE TRUNC(In1) OF
| ^
The selector is TRUNC(In1), which yields an integral value, but its declared
return type is still real, so the type check fails.
Code Locations
No response
Fix
Root cause
The CASE type check requires the selector's static type to be
integer/bit/enum and does not:
- recognize that
TRUNC / REAL_TO_* conversions produce an integer value, nor
- insert an implicit real→integer coercion of the selector for comparison.
Suggested fixes
- When the selector is real-typed, coerce it to the integer type of the case
labels (truncate) before the equality/range comparison.
- At minimum, treat a selector whose top-level operator is an explicit
integer-producing conversion (TRUNC, REAL_TO_DINT, …) as integer-typed.
Note
This is distinct from the other reported CASE defect
(CASE over VAR_GLOBAL CONSTANT emits non-constexpr switch labels), which is a
codegen problem on the case labels. This one is a semantic rejection on the
selector type.
Acceptance
A CASE whose selector reduces to an integer value should be accepted. Each
case label is an integer constant; the selector value is compared after
truncation to an integer.
Problem
Summary
STruC++ raises a semantic error — CASE selector must be an integer, bit, or
enum type, got LREAL — for a
CASEstatement whose selector isREAL/LREAL,even when the selector is an integer-producing conversion such as
TRUNC(...).Environment
strucppsemantic analysis (before codegen).Impact
No response
Reproduction
case_real.st:Actual result
The selector is
TRUNC(In1), which yields an integral value, but its declaredreturn type is still real, so the type check fails.
Code Locations
No response
Fix
Root cause
The
CASEtype check requires the selector's static type to beinteger/bit/enum and does not:
TRUNC/REAL_TO_*conversions produce an integer value, norSuggested fixes
labels (truncate) before the equality/range comparison.
integer-producing conversion (
TRUNC,REAL_TO_DINT, …) as integer-typed.Note
This is distinct from the other reported
CASEdefect(
CASE over VAR_GLOBAL CONSTANT emits non-constexpr switch labels), which is acodegen problem on the case labels. This one is a semantic rejection on the
selector type.
Acceptance
A
CASEwhose selector reduces to an integer value should be accepted. Eachcase label is an integer constant; the selector value is compared after
truncation to an integer.