Conversation
Problem: An initializer whose type cannot be assigned to the declared variable type, such as `x : STRING := 3`, passes `--check` and aborts later in code generation. Only body assignments ran the assignment type check; declarations did not. Solution: Run the same assignment validation on every variable initializer. `REFERENCE TO` and alias declarations bind a reference and keep their own check, and the lowered copies of initializers are skipped so each mismatch is reported once at its declaration. Inline pointer types no longer include their initializer in the location used for type names in diagnostics. Refs: PRG-4728 (cherry picked from commit c64eead) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Build Artifacts🐧 Linux
From workflow run 🪟 Windows
From workflow run |
volsa
previously approved these changes
Sep 17, 2026
Problem: A BOOL or REAL literal inside an array initializer, such as `ARRAY[0..1] OF REAL := [TRUE, FALSE]`, passes `--check` and then either panics in code generation or produces an ill-typed constant that breaks the link step. Scalar initializers already convert such literals. Solution: Cast every numeric element of an array literal to the array's element type before the constant array is built, in declarations and in body assignments alike. Refs: PRG-4728 (cherry picked from commit 671a247) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…0.x) Problem: Running the assignment validation on pointer-typed declarations turns previously accepted initializers such as `POINTER TO INT := 'foo'` into errors, and `REF_TO STRING := REF(a)` with a different target type reports an E037 error where the body form only warns. Solution: Skip the new initializer check for pointer-typed declarations and validate address initializers with the same check the body uses, so a `REF_TO` target type mismatch reports the E090 warning and nothing else. The two pointer initializer tests keep documenting the gap. Refs: PRG-4728 (cherry picked from commit c0535b6) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
….0.x) Problem: A string or real value stored into a pointer declaration, such as `p : POINTER TO INT := 'foo'`, is accepted, while the same assignment in a body is an error. The value is never a valid address. Solution: Pointer declarations only skip the assignment check for integer initializers; every other non-pointer value is reported like in a body. Address initializers keep going through the address branch. Refs: PRG-4728 (cherry picked from commit 5d3b04d) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
….0.x) Problem: `a : DINT := TRUE` is accepted although BOOL is not a numeric value, `b : BOOL := 5` is accepted although only 0 and 1 are BOOL literals, and the elements of an array literal are never checked against the element type, so `ARRAY[0..1] OF DINT := ['a', 'b']` passes `--check` and fails in code generation. Solution: A BOOL value assigned to another numeric type is an invalid assignment, as is an integer literal other than 0 or 1, or a real literal, assigned to a BOOL. Every element of an array literal is validated like an assignment to the element type, including nested literals; spliced array references and flat initializers of nested arrays are left to the existing length checks. The standard library's BOOL_TO_<integer> functions use the explicit IF form already used for the bit types. Refs: PRG-4728 (cherry picked from commit ea94468) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Problem: `DINT#TRUE` and `REAL#TRUE` pass validation although a BOOL literal is no numeric value, while `x : BOOL := BOOL#TRUE` fails with an unresolved constant because the constant evaluator expects an integer literal behind every integer type prefix. Solution: A BOOL literal behind a non-BOOL type prefix is an incompatible literal cast (E054), like `DINT#1.5` already is. The constant evaluator keeps a BOOL literal behind a BOOL prefix as it is. The equal-operation test no longer stores a BOOL comparison into a DINT variable. Refs: PRG-4728 (cherry picked from commit 7584dbc) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Backport of #1924 to release/1.0.x.
Problem: An initializer whose type cannot be assigned to the declared variable type, such as
x : STRING := 3ora : DINT := TRUE, passes--checkand aborts later in code generation or silently stores a converted value. Only body assignments ran the assignment type check;VAR,VAR_GLOBAL, function block members and struct members were never validated, whileVAR_TEMPwas caught by accident through its lowered copy and reported without a source location. BOOL was treated as a numeric value everywhere, soDINT := TRUEandDINT#TRUEwere accepted in bodies too, and array literal elements were never checked against the element type, soARRAY[0..1] OF REAL := [TRUE, FALSE]panicked in code generation.Solution: Run the same assignment validation on every variable initializer and on every element of an array literal, so declarations and body assignments report identical diagnostics (E037 mismatches, E067 downcasts). A BOOL value assigned to another numeric type is now an invalid assignment, as is an integer literal other than 0 or 1, or a real literal, assigned to a BOOL;
BOOL := 1stays valid. A BOOL literal behind a numeric type prefix (DINT#TRUE) is an incompatible literal cast likeDINT#1.5, andBOOL#TRUEnow evaluates as a constant initializer. The standard library'sBOOL_TO_<integer>functions use the explicit IF form already used for the bit conversions, and the CFC storage test on a numeric sink now asserts the rejection. The lowered copies of initializers are skipped so each mismatch is reported once, at its declaration. Pointer-typed declarations accept pointer and integer initializers for now; any other value, such as a string or a real, is rejected like in a body, and aREF_TOinitializer whose target type differs reports the same E090 warning as the body form instead of an error. Inline pointer types no longer include their initializer in the location used for type names. Numeric array literal elements are cast to the array's element type in code generation, so accepted conversions such asARRAY OF INT := [1.5, 2]no longer panic.Refs: PRG-4728
🤖 Generated with Claude Code