Commit 81becb8c authored by Jakob Kummerow's avatar Jakob Kummerow Committed by Commit Bot

[ubsan] Fix errors related to AsmType

The AsmType class uses a design similar to the old Object* model, where
arbitrary values (including 0) are reinterpret_cast to pointers. This
yields the following UBSan error, among others:

    src/asmjs/asm-parser.cc:2000:51: runtime error: member call on null
    pointer of type 'v8::internal::wasm::AsmType'

This patch does the smallest possible fix by turning the affected methods
into static functions. Longer-term, we should consider switching the
overall class design to a "struct wrapping an Address" model like the new
Object definition, which is a bit non-trivial because some AsmType types
are ZoneObject subclasses.

Bug: v8:3770
Change-Id: Ie2a7cdc9eab32c4c469d699212c84b0419480b4f
Reviewed-on: https://chromium-review.googlesource.com/c/1397663Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58586}
parent 5a5606be
......@@ -1997,7 +1997,8 @@ AsmType* AsmJsParser::BitwiseORExpression() {
// Remember whether the first operand to this OR-expression has requested
// deferred validation of the |0 annotation.
// NOTE: This has to happen here to work recursively.
bool requires_zero = call_coercion_deferred_->IsExactly(AsmType::Signed());
bool requires_zero =
AsmType::IsExactly(call_coercion_deferred_, AsmType::Signed());
call_coercion_deferred_ = nullptr;
// TODO(bradnelson): Make it prettier.
bool zero = false;
......
......@@ -38,11 +38,12 @@ std::string AsmType::Name() {
return this->AsCallableType()->Name();
}
bool AsmType::IsExactly(AsmType* that) {
// TODO(jpp): maybe this can become this == that.
AsmValueType* avt = this->AsValueType();
bool AsmType::IsExactly(AsmType* x, AsmType* y) {
// TODO(jpp): maybe this can become x == y.
if (x == nullptr) return y == nullptr;
AsmValueType* avt = x->AsValueType();
if (avt != nullptr) {
AsmValueType* tavt = that->AsValueType();
AsmValueType* tavt = y->AsValueType();
if (tavt == nullptr) {
return false;
}
......@@ -51,7 +52,7 @@ bool AsmType::IsExactly(AsmType* that) {
// TODO(jpp): is it useful to allow non-value types to be tested with
// IsExactly?
return that == this;
return x == y;
}
bool AsmType::IsA(AsmType* that) {
......@@ -200,7 +201,7 @@ class AsmMinMaxType final : public AsmCallableType {
bool CanBeInvokedWith(AsmType* return_type,
const ZoneVector<AsmType*>& args) override {
if (!return_type_->IsExactly(return_type)) {
if (!AsmType::IsExactly(return_type_, return_type)) {
return false;
}
......@@ -239,7 +240,7 @@ bool AsmFunctionType::IsA(AsmType* other) {
if (that == nullptr) {
return false;
}
if (!return_type_->IsExactly(that->return_type_)) {
if (!AsmType::IsExactly(return_type_, that->return_type_)) {
return false;
}
......@@ -248,7 +249,7 @@ bool AsmFunctionType::IsA(AsmType* other) {
}
for (size_t ii = 0; ii < args_.size(); ++ii) {
if (!args_[ii]->IsExactly(that->args_[ii])) {
if (!AsmType::IsExactly(args_[ii], that->args_[ii])) {
return false;
}
}
......@@ -258,7 +259,7 @@ bool AsmFunctionType::IsA(AsmType* other) {
bool AsmFunctionType::CanBeInvokedWith(AsmType* return_type,
const ZoneVector<AsmType*>& args) {
if (!return_type_->IsExactly(return_type)) {
if (!AsmType::IsExactly(return_type_, return_type)) {
return false;
}
......
......@@ -214,9 +214,9 @@ class V8_EXPORT_PRIVATE AsmType {
static AsmType* MinMaxType(Zone* zone, AsmType* dest, AsmType* src);
std::string Name();
// IsExactly returns true if this is the exact same type as that. For
// non-value types (e.g., callables), this returns this == that.
bool IsExactly(AsmType* that);
// IsExactly returns true if x is the exact same type as y. For
// non-value types (e.g., callables), this returns x == y.
static bool IsExactly(AsmType* x, AsmType* y);
// IsA is used to query whether this is an instance of that (i.e., if this is
// a type derived from that.) For non-value types (e.g., callables), this
// returns this == that.
......
......@@ -250,7 +250,7 @@ TEST_F(AsmTypeTest, IsExactly) {
for (size_t ii = 0; ii < arraysize(test_types); ++ii) {
for (size_t jj = 0; jj < arraysize(test_types); ++jj) {
EXPECT_EQ(ii == jj, test_types[ii]->IsExactly(test_types[jj]))
EXPECT_EQ(ii == jj, AsmType::IsExactly(test_types[ii], test_types[jj]))
<< test_types[ii]->Name()
<< ((ii == jj) ? " is not exactly " : " is exactly ")
<< test_types[jj]->Name();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment