Fix an invalid static cast in ClangExpressionParser.cpp

This was found by the green dragon sanitizer bot.

rdar://problem/48536644

Differential Revision: https://reviews.llvm.org/D59314

llvm-svn: 356090
This commit is contained in:
Adrian Prantl 2019-03-13 19:46:30 +00:00
parent 74a04e80c8
commit 7e34d78da1
16 changed files with 82 additions and 20 deletions

View File

@ -34,11 +34,22 @@ class RecordingMemoryManager;
//---------------------------------------------------------------------- //----------------------------------------------------------------------
class Expression { class Expression {
public: public:
/// Discriminator for LLVM-style RTTI (dyn_cast<> et al.)
enum ExpressionKind {
eKindFunctionCaller,
eKindClangFunctionCaller,
eKindUserExpression,
eKindLLVMUserExpression,
eKindClangUserExpression,
eKindUtilityFunction,
eKindClangUtilityFunction,
};
enum ResultType { eResultTypeAny, eResultTypeId }; enum ResultType { eResultTypeAny, eResultTypeId };
Expression(Target &target); Expression(Target &target, ExpressionKind kind);
Expression(ExecutionContextScope &exe_scope); Expression(ExecutionContextScope &exe_scope, ExpressionKind kind);
//------------------------------------------------------------------ //------------------------------------------------------------------
/// Destructor /// Destructor
@ -103,6 +114,12 @@ public:
virtual ExpressionTypeSystemHelper *GetTypeSystemHelper() { return nullptr; } virtual ExpressionTypeSystemHelper *GetTypeSystemHelper() { return nullptr; }
/// LLVM-style RTTI support.
ExpressionKind getKind() const { return m_kind; }
private:
/// LLVM-style RTTI support.
const ExpressionKind m_kind;
protected: protected:
lldb::TargetWP m_target_wp; /// Expression's always have to have a target... lldb::TargetWP m_target_wp; /// Expression's always have to have a target...
lldb::ProcessWP m_jit_process_wp; /// An expression might have a process, but lldb::ProcessWP m_jit_process_wp; /// An expression might have a process, but

View File

@ -57,6 +57,11 @@ namespace lldb_private {
//---------------------------------------------------------------------- //----------------------------------------------------------------------
class FunctionCaller : public Expression { class FunctionCaller : public Expression {
public: public:
/// LLVM-style RTTI support.
static bool classof(const Expression *E) {
return E->getKind() == eKindFunctionCaller;
}
//------------------------------------------------------------------ //------------------------------------------------------------------
/// Constructor /// Constructor
/// ///

View File

@ -33,6 +33,11 @@ namespace lldb_private {
//---------------------------------------------------------------------- //----------------------------------------------------------------------
class LLVMUserExpression : public UserExpression { class LLVMUserExpression : public UserExpression {
public: public:
/// LLVM-style RTTI support.
static bool classof(const Expression *E) {
return E->getKind() == eKindLLVMUserExpression;
}
// The IRPasses struct is filled in by a runtime after an expression is // The IRPasses struct is filled in by a runtime after an expression is
// compiled and can be used to to run fixups/analysis passes as required. // compiled and can be used to to run fixups/analysis passes as required.
// EarlyPasses are run on the generated module before lldb runs its own IR // EarlyPasses are run on the generated module before lldb runs its own IR
@ -48,7 +53,8 @@ public:
LLVMUserExpression(ExecutionContextScope &exe_scope, llvm::StringRef expr, LLVMUserExpression(ExecutionContextScope &exe_scope, llvm::StringRef expr,
llvm::StringRef prefix, lldb::LanguageType language, llvm::StringRef prefix, lldb::LanguageType language,
ResultType desired_type, ResultType desired_type,
const EvaluateExpressionOptions &options); const EvaluateExpressionOptions &options,
ExpressionKind kind);
~LLVMUserExpression() override; ~LLVMUserExpression() override;
bool FinalizeJITExecution( bool FinalizeJITExecution(

View File

@ -36,6 +36,11 @@ namespace lldb_private {
//---------------------------------------------------------------------- //----------------------------------------------------------------------
class UserExpression : public Expression { class UserExpression : public Expression {
public: public:
/// LLVM-style RTTI support.
static bool classof(const Expression *E) {
return E->getKind() == eKindUserExpression;
}
enum { kDefaultTimeout = 500000u }; enum { kDefaultTimeout = 500000u };
//------------------------------------------------------------------ //------------------------------------------------------------------
@ -60,7 +65,8 @@ public:
UserExpression(ExecutionContextScope &exe_scope, llvm::StringRef expr, UserExpression(ExecutionContextScope &exe_scope, llvm::StringRef expr,
llvm::StringRef prefix, lldb::LanguageType language, llvm::StringRef prefix, lldb::LanguageType language,
ResultType desired_type, ResultType desired_type,
const EvaluateExpressionOptions &options); const EvaluateExpressionOptions &options,
ExpressionKind kind);
//------------------------------------------------------------------ //------------------------------------------------------------------
/// Destructor /// Destructor

View File

@ -31,6 +31,11 @@ namespace lldb_private {
//---------------------------------------------------------------------- //----------------------------------------------------------------------
class UtilityFunction : public Expression { class UtilityFunction : public Expression {
public: public:
/// LLVM-style RTTI support.
static bool classof(const Expression *E) {
return E->getKind() == eKindUtilityFunction;
}
//------------------------------------------------------------------ //------------------------------------------------------------------
/// Constructor /// Constructor
/// ///
@ -41,7 +46,7 @@ public:
/// The name of the function, as used in the text. /// The name of the function, as used in the text.
//------------------------------------------------------------------ //------------------------------------------------------------------
UtilityFunction(ExecutionContextScope &exe_scope, const char *text, UtilityFunction(ExecutionContextScope &exe_scope, const char *text,
const char *name); const char *name, ExpressionKind kind);
~UtilityFunction() override; ~UtilityFunction() override;

View File

@ -12,16 +12,18 @@
using namespace lldb_private; using namespace lldb_private;
Expression::Expression(Target &target) Expression::Expression(Target &target, ExpressionKind kind)
: m_target_wp(target.shared_from_this()), : m_kind(kind),
m_target_wp(target.shared_from_this()),
m_jit_start_addr(LLDB_INVALID_ADDRESS), m_jit_start_addr(LLDB_INVALID_ADDRESS),
m_jit_end_addr(LLDB_INVALID_ADDRESS) { m_jit_end_addr(LLDB_INVALID_ADDRESS) {
// Can't make any kind of expression without a target. // Can't make any kind of expression without a target.
assert(m_target_wp.lock()); assert(m_target_wp.lock());
} }
Expression::Expression(ExecutionContextScope &exe_scope) Expression::Expression(ExecutionContextScope &exe_scope, ExpressionKind kind)
: m_target_wp(exe_scope.CalculateTarget()), : m_kind(kind),
m_target_wp(exe_scope.CalculateTarget()),
m_jit_start_addr(LLDB_INVALID_ADDRESS), m_jit_start_addr(LLDB_INVALID_ADDRESS),
m_jit_end_addr(LLDB_INVALID_ADDRESS) { m_jit_end_addr(LLDB_INVALID_ADDRESS) {
assert(m_target_wp.lock()); assert(m_target_wp.lock());

View File

@ -37,7 +37,8 @@ FunctionCaller::FunctionCaller(ExecutionContextScope &exe_scope,
const Address &functionAddress, const Address &functionAddress,
const ValueList &arg_value_list, const ValueList &arg_value_list,
const char *name) const char *name)
: Expression(exe_scope), m_execution_unit_sp(), m_parser(), : Expression(exe_scope, eKindFunctionCaller),
m_execution_unit_sp(), m_parser(),
m_jit_module_wp(), m_name(name ? name : "<unknown>"), m_jit_module_wp(), m_name(name ? name : "<unknown>"),
m_function_ptr(NULL), m_function_addr(functionAddress), m_function_ptr(NULL), m_function_addr(functionAddress),
m_function_return_type(return_type), m_function_return_type(return_type),

View File

@ -41,8 +41,10 @@ LLVMUserExpression::LLVMUserExpression(ExecutionContextScope &exe_scope,
llvm::StringRef prefix, llvm::StringRef prefix,
lldb::LanguageType language, lldb::LanguageType language,
ResultType desired_type, ResultType desired_type,
const EvaluateExpressionOptions &options) const EvaluateExpressionOptions &options,
: UserExpression(exe_scope, expr, prefix, language, desired_type, options), ExpressionKind kind)
: UserExpression(exe_scope, expr, prefix, language, desired_type, options,
kind),
m_stack_frame_bottom(LLDB_INVALID_ADDRESS), m_stack_frame_bottom(LLDB_INVALID_ADDRESS),
m_stack_frame_top(LLDB_INVALID_ADDRESS), m_allow_cxx(false), m_stack_frame_top(LLDB_INVALID_ADDRESS), m_allow_cxx(false),
m_allow_objc(false), m_transformed_text(), m_execution_unit_sp(), m_allow_objc(false), m_transformed_text(), m_execution_unit_sp(),

View File

@ -48,8 +48,9 @@ UserExpression::UserExpression(ExecutionContextScope &exe_scope,
llvm::StringRef expr, llvm::StringRef prefix, llvm::StringRef expr, llvm::StringRef prefix,
lldb::LanguageType language, lldb::LanguageType language,
ResultType desired_type, ResultType desired_type,
const EvaluateExpressionOptions &options) const EvaluateExpressionOptions &options,
: Expression(exe_scope), m_expr_text(expr), m_expr_prefix(prefix), ExpressionKind kind)
: Expression(exe_scope, kind), m_expr_text(expr), m_expr_prefix(prefix),
m_language(language), m_desired_type(desired_type), m_options(options) {} m_language(language), m_desired_type(desired_type), m_options(options) {}
UserExpression::~UserExpression() {} UserExpression::~UserExpression() {}

View File

@ -39,8 +39,10 @@ using namespace lldb;
/// The name of the function, as used in the text. /// The name of the function, as used in the text.
//------------------------------------------------------------------ //------------------------------------------------------------------
UtilityFunction::UtilityFunction(ExecutionContextScope &exe_scope, UtilityFunction::UtilityFunction(ExecutionContextScope &exe_scope,
const char *text, const char *name) const char *text, const char *name,
: Expression(exe_scope), m_execution_unit_sp(), m_jit_module_wp(), ExpressionKind kind)
: Expression(exe_scope, kind),
m_execution_unit_sp(), m_jit_module_wp(),
m_function_text(), m_function_text(),
m_function_name(name) {} m_function_name(name) {}

View File

@ -492,8 +492,8 @@ ClangExpressionParser::ClangExpressionParser(
// long time parsing and importing debug information. // long time parsing and importing debug information.
lang_opts.SpellChecking = false; lang_opts.SpellChecking = false;
auto &clang_expr = *static_cast<ClangUserExpression *>(&m_expr); auto *clang_expr = dyn_cast<ClangUserExpression>(&m_expr);
if (clang_expr.DidImportCxxModules()) { if (clang_expr && clang_expr->DidImportCxxModules()) {
LLDB_LOG(log, "Adding lang options for importing C++ modules"); LLDB_LOG(log, "Adding lang options for importing C++ modules");
lang_opts.Modules = true; lang_opts.Modules = true;

View File

@ -61,6 +61,11 @@ class ClangExpressionParser;
class ClangFunctionCaller : public FunctionCaller { class ClangFunctionCaller : public FunctionCaller {
friend class ASTStructExtractor; friend class ASTStructExtractor;
/// LLVM-style RTTI support.
static bool classof(const Expression *E) {
return E->getKind() == eKindClangFunctionCaller;
}
class ClangFunctionCallerHelper : public ClangExpressionHelper { class ClangFunctionCallerHelper : public ClangExpressionHelper {
public: public:
ClangFunctionCallerHelper(ClangFunctionCaller &owner) : m_owner(owner) {} ClangFunctionCallerHelper(ClangFunctionCaller &owner) : m_owner(owner) {}

View File

@ -64,7 +64,7 @@ ClangUserExpression::ClangUserExpression(
ResultType desired_type, const EvaluateExpressionOptions &options, ResultType desired_type, const EvaluateExpressionOptions &options,
ValueObject *ctx_obj) ValueObject *ctx_obj)
: LLVMUserExpression(exe_scope, expr, prefix, language, desired_type, : LLVMUserExpression(exe_scope, expr, prefix, language, desired_type,
options), options, eKindClangUserExpression),
m_type_system_helper(*m_target_wp.lock(), options.GetExecutionPolicy() == m_type_system_helper(*m_target_wp.lock(), options.GetExecutionPolicy() ==
eExecutionPolicyTopLevel), eExecutionPolicyTopLevel),
m_result_delegate(exe_scope.CalculateTarget()), m_ctx_obj(ctx_obj) { m_result_delegate(exe_scope.CalculateTarget()), m_ctx_obj(ctx_obj) {

View File

@ -40,6 +40,11 @@ namespace lldb_private {
//---------------------------------------------------------------------- //----------------------------------------------------------------------
class ClangUserExpression : public LLVMUserExpression { class ClangUserExpression : public LLVMUserExpression {
public: public:
/// LLVM-style RTTI support.
static bool classof(const Expression *E) {
return E->getKind() == eKindClangUserExpression;
}
enum { kDefaultTimeout = 500000u }; enum { kDefaultTimeout = 500000u };
class ClangUserExpressionHelper : public ClangExpressionHelper { class ClangUserExpressionHelper : public ClangExpressionHelper {

View File

@ -40,7 +40,7 @@ using namespace lldb_private;
//------------------------------------------------------------------ //------------------------------------------------------------------
ClangUtilityFunction::ClangUtilityFunction(ExecutionContextScope &exe_scope, ClangUtilityFunction::ClangUtilityFunction(ExecutionContextScope &exe_scope,
const char *text, const char *name) const char *text, const char *name)
: UtilityFunction(exe_scope, text, name) { : UtilityFunction(exe_scope, text, name, eKindClangUtilityFunction) {
m_function_text.assign(ClangExpressionSourceCode::g_expression_prefix); m_function_text.assign(ClangExpressionSourceCode::g_expression_prefix);
if (text && text[0]) if (text && text[0])
m_function_text.append(text); m_function_text.append(text);

View File

@ -36,6 +36,11 @@ namespace lldb_private {
//---------------------------------------------------------------------- //----------------------------------------------------------------------
class ClangUtilityFunction : public UtilityFunction { class ClangUtilityFunction : public UtilityFunction {
public: public:
/// LLVM-style RTTI support.
static bool classof(const Expression *E) {
return E->getKind() == eKindClangUtilityFunction;
}
class ClangUtilityFunctionHelper : public ClangExpressionHelper { class ClangUtilityFunctionHelper : public ClangExpressionHelper {
public: public:
ClangUtilityFunctionHelper() {} ClangUtilityFunctionHelper() {}