Panic during codegen when dereferencing paren-expression
Describe the bug
This came up during the implementation of SUPER but an equivalent example is also reproducible on master.
When trying to dereference the parenthesized result of a REF call, we hit a panic in inkwell.
To Reproduce
FUNCTION_BLOCK fb1
VAR
x : INT := 10;
ref_x : REF_TO INT;
END_VAR
ref_x := REF(x);
x := (REF(x))^; // this expression should be valid, but panics
END_FUNCTION_BLOCK
panics with:
thread '<unnamed>' panicked at /home/michael/.cargo/registry/src/index.crates.io-6f17d22bba15001f/inkwell-0.2.0/src/values/enums.rs:302:13:
Found IntValue(IntValue { int_value: Value { name: "deref", address: 0x74e03c008d60, is_const: false, is_null: false, is_undef: false, llvm_value: " %deref = load i16, i16* %x, align 2", llvm_type: "i16" } }) but expected PointerValue variant
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Additional context
This does not happen when dereferencing a parenthesized pointer, so it might be due to the inlining of our builtins.
Edit: this might also be an RValue problem, since dereferencing a pointer should require an LValue.
Additional examples
FUNCTION_BLOCK foo
VAR
i : LINT;
ref_i : REF_TO LINT;
END_VAR
i := (REF(i) + 1)^ + 5; // panics
i := (ref_i + 1)^ + 5; // panics
END_FUNCTION_BLOCK
panic:
thread '<unnamed>' panicked at /home/michael/.cargo/registry/src/index.crates.io-6f17d22bba15001f/inkwell-0.2.0/src/values/enums.rs:302:13:
Found IntValue(IntValue { int_value: Value { name: "deref", address: 0x747a6400be80, is_const: false, is_null: false, is_undef: false, llvm_value: " %deref = load i64, i64* %access___foo_ref_i, align 4", llvm_type: "i64" } }) but expected PointerValue variant
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
If one of the operands happens to be a struct-type, we don't hit a panic but abort codegen with a diagnostic instead.
FUNCTION_BLOCK bar
VAR
x : LINT := 10;
y : LINT := 20;
END_VAR
END_FUNCTION_BLOCK
FUNCTION_BLOCK foo
VAR
i : LINT;
b : bar;
ref_b : REF_TO bar;
END_VAR
i := (REF(b) + 1)^ + 5;
i := (ref_b + 1)^ + 5;
END_FUNCTION_BLOCK
Resulting codegen error:
Invalid types, cannot generate binary expression for "bar" and "DINT" at: target/demo.st:126:17:{126:17-126:29}: .
Hint: You can use `plc explain <ErrorCode>` for more information
Expected behavior For each of those cases, we should either be able to deref the resulting RValue and attempt to continue (this might be undefined behaviour and a security concern) or catch these cases during validation and abort gracefully.