Skip to content

THIS.<field> (without ^ deref) panics in codegen with "GEP pointee is not a struct" #1728

@ghaith

Description

@ghaith

🤖 This issue body was drafted by Claude on Ghaith's behalf.

Symptom

Compiling a program where a method body references THIS.<field> (a member access on THIS without dereferencing first via ^) crashes the compiler with:

Builder error: GEP pointee is not a struct (pointee: "ptr", index: 1).

No diagnostic is emitted by plc check — the error appears only during codegen.

Minimal reproducer

plc.json:

{ "name": "min", "files": ["src/**/*.st"], "compile_type": "Shared", "output": "min.so" }

src/m.st:

INTERFACE IAnimal
    METHOD legs : DINT
    END_METHOD
END_INTERFACE

FUNCTION_BLOCK fb
VAR
    a : IAnimal;
END_VAR
METHOD m : DINT
    THIS.a.legs();
END_METHOD
END_FUNCTION_BLOCK

plc build plc.json → panic above.
Replacing THIS.a.legs() with THIS^.a.legs() compiles cleanly.

Expected behaviour

A validation error at the THIS.a site stating that THIS is POINTER TO fb and member access requires an explicit dereference (THIS^.a). This is consistent with how rusty already rejects member access on other typed pointers (E068).

Likely root cause (preliminary)

THIS is modelled as POINTER TO <enclosing FB> and the parser/AST distinguishes is_this() vs is_this_deref() (compiler/plc_ast/src/ast.rs:1401). The validator's pointer-deref-required rule must be missing the THIS-as-base case: undeclared_var.field.method() correctly produces E048, and somePointerVar.field correctly produces E068, but THIS.field slips through both checks and reaches the codegen path with an unindirected pointer operand, which then fails LLVM's BuildGEP precondition.

Found while compiling a real-world project.

Environment

  • plc 0.5.0 (Wed May 6 13:36:43 2026 +0200, 59e1e9d1e5) (current master tip)
  • x86_64-linux-gnu

Metadata

Metadata

Assignees

No one assigned

    Labels

    1.0This PR/Issue is required before we reach feature completionbugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions