GetPersistentExpressionStateForLanguage() can return a nullptr if it cannot construct a typesystem. This patch adds missing nullptr checks at all uses.
Inspired by rdar://problem/58317195
Paths
| Differential D72413
Add missing nullptr checks. ClosedPublic Authored by aprantl on Jan 8 2020, 1:43 PM.
Details Summary GetPersistentExpressionStateForLanguage() can return a nullptr if it cannot construct a typesystem. This patch adds missing nullptr checks at all uses. Inspired by rdar://problem/58317195
Diff Detail
Event TimelineComment Actions If we can't make a persistent expression state, are we going to be able to do anything useful with expressions? I don't see anything wrong here, but it seems like we should really be putting up a crunchy frog warning and erroring out of "expr"directly if we really can't make a type system. Comment Actions
I looked at that for a bit, but there is no obvious place where to early exit without refactoring much more of ClangExpressionDeclMap. Comment Actions I am curious what prompted this set of changes, they look sensible but I don't see how we can do anything useful if we end up in this state. Do we currently have a way to end up in this state? Comment Actions
Not in llvm.org. This was prompted by a swift-lldb-crash where we can end up with no Swift context after a catastrophic error. I believe that in practice the clang runtimes are always available, but the API returns a nullable pointer so the call sites should take this into account: PersistentExpressionState * Target::GetPersistentExpressionStateForLanguage(lldb::LanguageType language) { auto type_system_or_err = GetScratchTypeSystemForLanguage(language, true); if (auto err = type_system_or_err.takeError()) { LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET), std::move(err), "Unable to get persistent expression state for language {}", Language::GetNameForLanguageType(language)); return nullptr; } return type_system_or_err->GetPersistentExpressionState(); } Comment Actions
We should merge it like this, IMHO. Comment Actions The C++ expression parser will probably behave incredibly incorrectly without a persistent state but before this patch it just crashed, so I think this is good to go. Comment Actions
FWIW, you could also just add the check to ClangUserExpression::ClangUserExpressionHelper::ResetDeclMap and return a nullptr there. The API is designed to return a nullptr for utility expressions on that don't use the DeclMap. That's the only place in upstream LLDB where we construct a DeclMap with a target, so if there is a check there then the DeclMap doesn't need any further changes and we can just assume there is a persistent state in the rest of the code. But it doesn't really make the code much better, just this patch smaller. This revision is now accepted and ready to land.Jan 10 2020, 12:02 AM Closed by commit rGe9331a56fead: Add missing nullptr checks. (authored by aprantl). · Explain WhyJan 10 2020, 8:53 AM This revision was automatically updated to reflect the committed changes. Comment Actions
Should we consider a refactor to ClangExpressionDeclMap that makes this more obvious? [and maybe allows us to not sprinkling these checks everywhere] -- as a followup?
Revision Contents
Diff 237348 lldb/source/Expression/REPL.cpp
lldb/source/Expression/UserExpression.cpp
lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp
lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
lldb/source/Target/ABI.cpp
|