Skip to content

CASE over a REAL/LREAL selector is rejected even when the value is an integer conversion #208

Description

@dreamclass

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

  1. When the selector is real-typed, coerce it to the integer type of the case
    labels (truncate) before the equality/range comparison.
  2. 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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions