mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-04 22:02:52 +01:00
Disallow compile time bindings where they aren't clearly supported. (#4338)
This is resolving a fuzz-discovered crash related to function suspends and compile time bind indices. Although the crash originally came from clearly invalid syntax (missing the `=` inside a `class` decl), the syntax with a value should also be valid but has the same crash. This approach disallows compile-time bindings in contexts that can create ambiguous results, particularly class declarations. These are an issue because a suspended function can have let declarations after it. I'm allowing them in function bodies and interface scopes. --------- Co-authored-by: Richard Smith <richard@metafoo.co.uk>
This commit is contained in:
co-authored by
Richard Smith
parent
49a8efbe1b
commit
87678cc374
@@ -13,6 +13,18 @@ auto ScopeStack::VerifyOnFinish() -> void {
|
||||
CARBON_CHECK(scope_stack_.empty(), "{0}", scope_stack_.size());
|
||||
}
|
||||
|
||||
auto ScopeStack::VerifyNextCompileTimeBindIndex(llvm::StringLiteral label,
|
||||
const ScopeStackEntry& scope)
|
||||
-> void {
|
||||
CARBON_CHECK(
|
||||
static_cast<int32_t>(compile_time_binding_stack_.all_values_size()) ==
|
||||
scope.next_compile_time_bind_index.index,
|
||||
"Wrong number of entries in compile-time binding stack after {0}: have "
|
||||
"{1}, expected {2}",
|
||||
label, compile_time_binding_stack_.all_values_size(),
|
||||
scope.next_compile_time_bind_index.index);
|
||||
}
|
||||
|
||||
auto ScopeStack::Push(SemIR::InstId scope_inst_id, SemIR::NameScopeId scope_id,
|
||||
SemIR::SpecificId specific_id,
|
||||
bool lexical_lookup_has_load_error) -> void {
|
||||
@@ -49,6 +61,8 @@ auto ScopeStack::Push(SemIR::InstId scope_inst_id, SemIR::NameScopeId scope_id,
|
||||
CARBON_CHECK(next_scope_index_.index != std::numeric_limits<int32_t>::max(),
|
||||
"Ran out of scopes");
|
||||
++next_scope_index_.index;
|
||||
|
||||
VerifyNextCompileTimeBindIndex("Push", scope_stack_.back());
|
||||
}
|
||||
|
||||
auto ScopeStack::Pop() -> void {
|
||||
@@ -72,13 +86,7 @@ auto ScopeStack::Pop() -> void {
|
||||
return_scope_stack_.back().returned_var = SemIR::InstId::Invalid;
|
||||
}
|
||||
|
||||
CARBON_CHECK(
|
||||
scope.next_compile_time_bind_index.index ==
|
||||
static_cast<int32_t>(compile_time_binding_stack_.all_values_size()),
|
||||
"Wrong number of entries in compile-time binding stack, have {0}, "
|
||||
"expected {1}",
|
||||
compile_time_binding_stack_.all_values_size(),
|
||||
scope.next_compile_time_bind_index.index);
|
||||
VerifyNextCompileTimeBindIndex("Pop", scope);
|
||||
compile_time_binding_stack_.PopArray();
|
||||
}
|
||||
|
||||
@@ -216,13 +224,7 @@ auto ScopeStack::Restore(SuspendedScope scope) -> void {
|
||||
}
|
||||
}
|
||||
|
||||
CARBON_CHECK(
|
||||
scope.entry.next_compile_time_bind_index.index ==
|
||||
static_cast<int32_t>(compile_time_binding_stack_.all_values_size()),
|
||||
"Wrong number of entries in compile-time binding stack when restoring, "
|
||||
"have {0}, expected {1}",
|
||||
compile_time_binding_stack_.all_values_size(),
|
||||
scope.entry.next_compile_time_bind_index.index);
|
||||
VerifyNextCompileTimeBindIndex("Restore", scope.entry);
|
||||
|
||||
if (scope.entry.scope_id.is_valid()) {
|
||||
non_lexical_scope_stack_.push_back(
|
||||
|
||||
Reference in New Issue
Block a user