google / google/xls

Prematurely erased type parameters lead to crashes in interpretation.

Open
#2,354 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
1.9k
Forks
283
Avg merge
2d 10h
Merged PRs (30d)
135

Description

**Describe the bug**
Calling a function with a parametrized struct where the parameter is not directly used in the type-construction of the struct, but used in some function value later crashes during evaluation.

**To Reproduce**

Let's consider `reproduce.x`:

```rust
import std;

// Note: we have a parameter on this type, which is apparently forgottn later
pub struct Foo {
x: u12, // if we used uN[PARAM], it works. <--
}

fn Foo_ParamDependent(f: Foo, y: u32) -> u32 {
f.x as u32 + y + PARAM
}

#[test]
fn foo_test() {
let f: Foo = Foo{ x: u12:19, }; // Clearly available PARAM=u12
let result = Foo_ParamDependent(f, u32:17); // this crashes
//let result = Foo_ParamDependent(f, u32:17); // this works <--
let expected = u32:17 + u32:19 + u32:12;
assert_eq(result, expected);
}
```

Run:
```
interpreter_main reproduce.x
```

Experience crash

Stack trace

```
[symbolize_elf.inc : 393] RAW: Unable to get high fd: rc=0, limit=1024
E0608 20:31:17.118381 2347820 command_line_utils.cc:50] Could not extract a textual position from error message: INTERNAL: BytecodeEmitter could not find slot or binding for name: PARAM @ reproduce.x:8:23-8:28 stack: 0x564dd6440d6b: std::__1::__variant_detail::__visitation::__base::__dispatcher<>::__dispatch[abi:ne180100]<>()
0x564dd6433eb0: xls::dslx::BytecodeEmitter::HandleNameRef()
0x564dd783ea2b: xls::dslx::NameRef::AcceptExpr()
0x564dd6421977: xls::dslx::BytecodeEmitter::HandleBinop()
0x564dd7841cc8: xls::dslx::Binop::AcceptExpr()
0x564dd643ce3f: std::__1::__variant_detail::__visitation::__base::__dispatcher<>::__dispatch[abi:ne180100]<>()
0x564dd64227a8: xls::dslx::BytecodeEmitter::HandleStatementBlock()
0x564dd7841e08: xls::dslx::StatementBlock::AcceptExpr()
0x564dd641e16d: xls::dslx::BytecodeEmitter::EmitInternal()
0x564dd641e032: xls::dslx::BytecodeEmitter::Emit()
0x564dd6311563: xls::dslx::BytecodeCache::GetOrCreateBytecodeFunction()
0x564dd6457a9a: xls::dslx::BytecodeInterpreter::GetBytecodeFn()
0x564dd6447841: xls::dslx::BytecodeInterpreter::EvalCall()
0x564dd6446321: xls::dslx::BytecodeInterpreter::EvalNextInstruction()
0x564dd64440d1: xls::dslx::BytecodeInterpreter::Run()
0x564dd64435db: xls::dslx::BytecodeInterpreter::Interpret()
0x564dd640c3db: xls::dslx::ConstexprEvaluator::InterpretExpr()
0x564dd64118e2: xls::dslx::ConstexprEvaluator::HandleInvocation()
0x564dd7841328: xls::dslx::Invocation::AcceptExpr()
0x564dd640b5bd: xls::dslx::ConstexprEvaluator::Evaluate()
0x564dd6330408: xls::dslx::(anonymous namespace)::DeduceVisitor::HandleLet()
0x564dd78426db: xls::dslx::Let::Accept()
0x564dd631dcf1: xls::dslx::Deduce()
0x564dd631aa45: std::__1::__function::__func<>::operator()()
0x564dd64a7c6c: xls::dslx::DeduceCtx::Deduce()
0x564dd63261e4: xls::dslx::(anonymous namespace)::DeduceVisitor::HandleStatement()
0x564dd784253b: xls::dslx::Statement::Accept()
0x564dd631dcf1: xls::dslx::Deduce()
0x564dd631aa45: std::__1::__function::__func<>::operator()()
0x564dd64a7c6c: xls::dslx::DeduceCtx::Deduce()
0x564dd632c6c6: xls::dslx::(anonymous namespace)::DeduceVisitor::HandleStatementBlock()
0x564dd7841dcb: xls::dslx::StatementBlock::Accept()
0x564dd631dcf1: xls::dslx::Deduce()
0x564dd631aa45: std::__1::__function::__func<>::operator()()
0x564dd64a7c6c: xls::dslx::DeduceCtx::Deduce()
0x564dd64a8aac: xls::dslx::DeduceCtx::DeduceAndResolve()
0x564dd631b542: xls::dslx::TypecheckFunction()
0x564dd63173a7: std::__1::__variant_detail::__visitation::__base::__dispatcher<>::__dispatch[abi:ne180100]<>()
0x564dd63151ec: xls::dslx::typecheck_internal::TypecheckModuleMember()
0x564dd6315e0f: xls::dslx::TypecheckModule()
0x564dd6314786: xls::dslx::TypecheckModule()
0x564dd6313d6d: xls::dslx::ParseAndTypecheck()
0x564dd627df7c: xls::dslx::AbstractTestRunner::ParseAndTest()
0x564dd620bd98: main
0x7f117962a47e: __libc_start_call_main
; while evaluating: Foo_ParamDependent(f, u32:17): INVALID_ARGUMENT: Provided status is not in recognized error form: INTERNAL: BytecodeEmitter could not find slot or binding for name: PARAM @ reproduce.x:8:23-8:28 stack: 0x564dd6440d6b: std::__1::__variant_detail::__visitation::__base::__dispatcher<>::__dispatch[abi:ne180100]<>()
0x564dd6433eb0: xls::dslx::BytecodeEmitter::HandleNameRef()
0x564dd783ea2b: xls::dslx::NameRef::AcceptExpr()
0x564dd6421977: xls::dslx::BytecodeEmitter::HandleBinop()
0x564dd7841cc8: xls::dslx::Binop::AcceptExpr()
0x564dd643ce3f: std::__1::__variant_detail::__visitation::__base::__dispatcher<>::__dispatch[abi:ne180100]<>()
0x564dd64227a8: xls::dslx::BytecodeEmitter::HandleStatementBlock()
0x564dd7841e08: xls::dslx::StatementBlock::AcceptExpr()
0x564dd641e16d: xls::dslx::BytecodeEmitter::EmitInternal()
0x564dd641e032: xls::dslx::BytecodeEmitter::Emit()
0x564dd6311563: xls::dslx::BytecodeCache::GetOrCreateBytecodeFunction()
0x564dd6457a9a: xls::dslx::BytecodeInterpreter::GetBytecodeFn()
0x564dd6447841: xls::dslx::BytecodeInterpreter::EvalCall()
0x564dd6446321: xls::dslx::BytecodeInterpreter::EvalNextInstruction()
0x564dd64440d1: xls::dslx::BytecodeInterpreter::Run()
0x564dd64435db: xls::dslx::BytecodeInterpreter::Interpret()
0x564dd640c3db: xls::dslx::ConstexprEvaluator::InterpretExpr()
0x564dd64118e2: xls::dslx::ConstexprEvaluator::HandleInvocation()
0x564dd7841328: xls::dslx::Invocation::AcceptExpr()
0x564dd640b5bd: xls::dslx::ConstexprEvaluator::Evaluate()
0x564dd6330408: xls::dslx::(anonymous namespace)::DeduceVisitor::HandleLet()
0x564dd78426db: xls::dslx::Let::Accept()
0x564dd631dcf1: xls::dslx::Deduce()
0x564dd631aa45: std::__1::__function::__func<>::operator()()
0x564dd64a7c6c: xls::dslx::DeduceCtx::Deduce()
0x564dd63261e4: xls::dslx::(anonymous namespace)::DeduceVisitor::HandleStatement()
0x564dd784253b: xls::dslx::Statement::Accept()
0x564dd631dcf1: xls::dslx::Deduce()
0x564dd631aa45: std::__1::__function::__func<>::operator()()
0x564dd64a7c6c: xls::dslx::DeduceCtx::Deduce()
0x564dd632c6c6: xls::dslx::(anonymous namespace)::DeduceVisitor::HandleStatementBlock()
0x564dd7841dcb: xls::dslx::StatementBlock::Accept()
0x564dd631dcf1: xls::dslx::Deduce()
0x564dd631aa45: std::__1::__function::__func<>::operator()()
0x564dd64a7c6c: xls::dslx::DeduceCtx::Deduce()
0x564dd64a8aac: xls::dslx::DeduceCtx::DeduceAndResolve()
0x564dd631b542: xls::dslx::TypecheckFunction()
0x564dd63173a7: std::__1::__variant_detail::__visitation::__base::__dispatcher<>::__dispatch[abi:ne180100]<>()
0x564dd63151ec: xls::dslx::typecheck_internal::TypecheckModuleMember()
0x564dd6315e0f: xls::dslx::TypecheckModule()
0x564dd6314786: xls::dslx::TypecheckModule()
0x564dd6313d6d: xls::dslx::ParseAndTypecheck()
0x564dd627df7c: xls::dslx::AbstractTestRunner::ParseAndTest()
0x564dd620bd98: main
0x7f117962a47e: __libc_start_call_main
; while evaluating: Foo_ParamDependent(f, u32:17)
Error: INTERNAL: BytecodeEmitter could not find slot or binding for name: PARAM @ reproduce.x:8:23-8:28 stack: 0x564dd6440d6b: std::__1::__variant_detail::__visitation::__base::__dispatcher<>::__dispatch[abi:ne180100]<>()
0x564dd6433eb0: xls::dslx::BytecodeEmitter::HandleNameRef()
0x564dd783ea2b: xls::dslx::NameRef::AcceptExpr()
0x564dd6421977: xls::dslx::BytecodeEmitter::HandleBinop()
0x564dd7841cc8: xls::dslx::Binop::AcceptExpr()
0x564dd643ce3f: std::__1::__variant_detail::__visitation::__base::__dispatcher<>::__dispatch[abi:ne180100]<>()
0x564dd64227a8: xls::dslx::BytecodeEmitter::HandleStatementBlock()
0x564dd7841e08: xls::dslx::StatementBlock::AcceptExpr()
0x564dd641e16d: xls::dslx::BytecodeEmitter::EmitInternal()
0x564dd641e032: xls::dslx::BytecodeEmitter::Emit()
0x564dd6311563: xls::dslx::BytecodeCache::GetOrCreateBytecodeFunction()
0x564dd6457a9a: xls::dslx::BytecodeInterpreter::GetBytecodeFn()
0x564dd6447841: xls::dslx::BytecodeInterpreter::EvalCall()
0x564dd6446321: xls::dslx::BytecodeInterpreter::EvalNextInstruction()
0x564dd64440d1: xls::dslx::BytecodeInterpreter::Run()
0x564dd64435db: xls::dslx::BytecodeInterpreter::Interpret()
0x564dd640c3db: xls::dslx::ConstexprEvaluator::InterpretExpr()
0x564dd64118e2: xls::dslx::ConstexprEvaluator::HandleInvocation()
0x564dd7841328: xls::dslx::Invocation::AcceptExpr()
0x564dd640b5bd: xls::dslx::ConstexprEvaluator::Evaluate()
0x564dd6330408: xls::dslx::(anonymous namespace)::DeduceVisitor::HandleLet()
0x564dd78426db: xls::dslx::Let::Accept()
0x564dd631dcf1: xls::dslx::Deduce()
0x564dd631aa45: std::__1::__function::__func<>::operator()()
0x564dd64a7c6c: xls::dslx::DeduceCtx::Deduce()
0x564dd63261e4: xls::dslx::(anonymous namespace)::DeduceVisitor::HandleStatement()
0x564dd784253b: xls::dslx::Statement::Accept()
0x564dd631dcf1: xls::dslx::Deduce()
0x564dd631aa45: std::__1::__function::__func<>::operator()()
0x564dd64a7c6c: xls::dslx::DeduceCtx::Deduce()
0x564dd632c6c6: xls::dslx::(anonymous namespace)::DeduceVisitor::HandleStatementBlock()
0x564dd7841dcb: xls::dslx::StatementBlock::Accept()
0x564dd631dcf1: xls::dslx::Deduce()
0x564dd631aa45: std::__1::__function::__func<>::operator()()
0x564dd64a7c6c: xls::dslx::DeduceCtx::Deduce()
0x564dd64a8aac: xls::dslx::DeduceCtx::DeduceAndResolve()
0x564dd631b542: xls::dslx::TypecheckFunction()
0x564dd63173a7: std::__1::__variant_detail::__visitation::__base::__dispatcher<>::__dispatch[abi:ne180100]<>()
0x564dd63151ec: xls::dslx::typecheck_internal::TypecheckModuleMember()
0x564dd6315e0f: xls::dslx::TypecheckModule()
0x564dd6314786: xls::dslx::TypecheckModule()
0x564dd6313d6d: xls::dslx::ParseAndTypecheck()
0x564dd627df7c: xls::dslx::AbstractTestRunner::ParseAndTest()
0x564dd620bd98: main
0x7f117962a47e: __libc_start_call_main
; while evaluating: Foo_ParamDependent(f, u32:17)make: *** [Makefile:19: reproduce.test] Error 1
```

**Expected behavior**

No crash.
No premature erasure of parameters - they are part of the type and will be needed later. it should not be necessary to manually parametrize function calls that should find their parameters from the type.
From the behavior it looks like that this only happens as if the type-parameter is deemed unnecessary in the type itself, thus is discarded.

**Environment (this can be helpful for troubleshooting):**
`v0.0.0-7829-gc605fae2d`

**Additional context**

Note, if the parameter is used in the type, this works (see comment in `struct Foo`)
Also, if we explicitly parametrize the call to `Foo_ParamDependent()`, it also works (see second comment)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.