mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 22:02:23 +01:00
Per #257, we should be treating unformedness as all-or-nothing, rather than being a per-field or per-array-element property. Previously we initialized an array with no explicit initializer as containing a sequence of uninitialized values, but that led to crashes when attempting to access those values, as the checks for reading an uninitialized value only expected values to be uninitialized at the top level. Also, we had existing tests that attempt to store to an element of an uninitialized array. We now detect that and treat it as UB during evaluation, rather than crashing due to trying to perform field access into an uninitialized value. Finally, many of these problems can be detected statically, but the resolve_unformed pass wasn't catching them because it missed a few expression and declaration forms. Support for those cases has been added too. This causes the pass to recurse more often, and in particular our existing recursion test started hitting a stack overflow after this, so resolve_unformed now uses `RunWithExtraStack`. In passing, remove the need to explicitly tell `RunWithExtraStack` the return type, and infer it as the return type of the callable instead.
49 lines
1.4 KiB
C++
49 lines
1.4 KiB
C++
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
|
// Exceptions. See /LICENSE for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|
|
#ifndef CARBON_EXPLORER_INTERPRETER_STACK_SPACE_H_
|
|
#define CARBON_EXPLORER_INTERPRETER_STACK_SPACE_H_
|
|
|
|
#include <optional>
|
|
|
|
#include "llvm/ADT/STLFunctionalExtras.h"
|
|
|
|
namespace Carbon {
|
|
|
|
namespace Internal {
|
|
|
|
// Returns true if a new thread should be started for more stack space.
|
|
auto IsStackSpaceNearlyExhausted() -> bool;
|
|
|
|
// Starts a thread to run the function.
|
|
auto RunWithExtraStackHelper(llvm::function_ref<void()> fn) -> void;
|
|
|
|
} // namespace Internal
|
|
|
|
// Runs `fn` after ensuring there is a reasonable amount of space left on the
|
|
// stack for it to run in. This will run `fn` in a separate thread if there is
|
|
// not enough space left on the current stack, or if RunWithExtraStack didn't
|
|
// create the current thread.
|
|
//
|
|
// Usage:
|
|
// return RunWithExtraStack([&]() -> ReturnType {
|
|
// <function body>
|
|
// });
|
|
template <typename Fn>
|
|
auto RunWithExtraStack(Fn fn) -> decltype(fn()) {
|
|
using ReturnType = decltype(fn());
|
|
static_assert(!std::is_reference_v<ReturnType>);
|
|
if (Internal::IsStackSpaceNearlyExhausted()) {
|
|
std::optional<ReturnType> result;
|
|
Internal::RunWithExtraStackHelper([&] { result = fn(); });
|
|
return std::move(*result);
|
|
} else {
|
|
return fn();
|
|
}
|
|
}
|
|
|
|
} // namespace Carbon
|
|
|
|
#endif // CARBON_EXPLORER_INTERPRETER_STACK_SPACE_H_
|