-
Notifications
You must be signed in to change notification settings - Fork 68
Description
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.