Description
Silverscript accepts a call to an undefined function when the result is assigned
to an unused local variable. The declaration is later eliminated, so the
undefined call never reaches bytecode compilation.
This is harmless at runtime because no code is emitted for the declaration.
Reproduction
Create unknown-call.sil:
pragma silverscript ^0.1.0;
contract UnknownCallInUnusedLocal() {
entrypoint function spend() {
byte[32] unused = missingFunction(bytes("test"));
require(true);
}
}
Compile it:
cargo run --quiet -p silverscript-lang --bin silverc -- unknown-call.sil
The contract compiles successfully.
If unused is subsequently referenced, compilation correctly fails because
missingFunction does not exist:
require(unused.length == 32);
Expected behavior
Compilation should fail in both cases with an unknown-function diagnostic
pointing to missingFunction.
Dead or unused code should still be name- and type-checked before it is removed.
Likely cause
Expression-call validation currently permits calls that match neither a known
builtin nor a declared function. Later, lower_local_aliases removes an
unassigned local with no uses, including its initializer. Consequently,
bytecode compilation never sees the unknown call.
Description
Silverscript accepts a call to an undefined function when the result is assigned
to an unused local variable. The declaration is later eliminated, so the
undefined call never reaches bytecode compilation.
This is harmless at runtime because no code is emitted for the declaration.
Reproduction
Create
unknown-call.sil:Compile it:
The contract compiles successfully.
If
unusedis subsequently referenced, compilation correctly fails becausemissingFunctiondoes not exist:Expected behavior
Compilation should fail in both cases with an unknown-function diagnostic
pointing to
missingFunction.Dead or unused code should still be name- and type-checked before it is removed.
Likely cause
Expression-call validation currently permits calls that match neither a known
builtin nor a declared function. Later,
lower_local_aliasesremoves anunassigned local with no uses, including its initializer. Consequently,
bytecode compilation never sees the unknown call.