Skip to content

Commit

Permalink
Merge pull request #527 from wasmx/parser_no_default_case
Browse files Browse the repository at this point in the history
Introduce UNREACHABLE macro
  • Loading branch information
chfast authored Oct 20, 2020
2 parents 5db71c8 + cbec087 commit c179d1b
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 6 deletions.
6 changes: 6 additions & 0 deletions lib/fizzy/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ target_include_directories(fizzy PUBLIC ${FIZZY_INCLUDE_DIR})
target_sources(
fizzy PRIVATE
${FIZZY_INCLUDE_DIR}/fizzy/fizzy.h
asserts.cpp
asserts.hpp
cxx20/bit.hpp
cxx20/span.hpp
bytes.hpp
Expand Down Expand Up @@ -37,6 +39,10 @@ target_sources(
value.hpp
)

if(CMAKE_BUILD_TYPE STREQUAL Coverage AND CMAKE_CXX_COMPILER_ID MATCHES GNU)
set_source_files_properties(asserts.cpp PROPERTIES COMPILE_DEFINITIONS GCOV)
endif()

# The fizzy::fizzy-internal links fizzy::fizzy library with access to internal headers.
add_library(fizzy-internal INTERFACE)
add_library(fizzy::fizzy-internal ALIAS fizzy-internal)
Expand Down
20 changes: 20 additions & 0 deletions lib/fizzy/asserts.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Fizzy: A fast WebAssembly interpreter
// Copyright 2020 The Fizzy Authors.
// SPDX-License-Identifier: Apache-2.0

#include "asserts.hpp"

#ifdef GCOV
extern "C" void __gcov_flush();
#endif

namespace fizzy
{
bool unreachable() noexcept
{
#ifdef GCOV
__gcov_flush();
#endif
return false; // LCOV_EXCL_LINE
}
} // namespace fizzy
28 changes: 28 additions & 0 deletions lib/fizzy/asserts.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Fizzy: A fast WebAssembly interpreter
// Copyright 2020 The Fizzy Authors.
// SPDX-License-Identifier: Apache-2.0

#include <cassert>

#ifndef __has_builtin
#define __has_builtin(name) 0
#endif

#ifndef __has_feature
#define __has_feature(name) 0
#endif


namespace fizzy
{
/// A helper for assert(unreachable()). Always returns false. Also flushes coverage data.
bool unreachable() noexcept;
} // namespace fizzy

#ifndef NDEBUG
#define FIZZY_UNREACHABLE() assert(fizzy::unreachable())
#elif __has_builtin(__builtin_unreachable)
#define FIZZY_UNREACHABLE() __builtin_unreachable()
#else
#define FIZZY_UNREACHABLE() (void)0
#endif
4 changes: 2 additions & 2 deletions lib/fizzy/execute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// SPDX-License-Identifier: Apache-2.0

#include "execute.hpp"
#include "asserts.hpp"
#include "cxx20/bit.hpp"
#include "stack.hpp"
#include "trunc_boundaries.hpp"
Expand Down Expand Up @@ -1554,8 +1555,7 @@ ExecutionResult execute(Instance& instance, FuncIdx func_idx, const Value* args,
}

default:
assert(false);
break;
FIZZY_UNREACHABLE();
}
}

Expand Down
9 changes: 5 additions & 4 deletions lib/fizzy/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// SPDX-License-Identifier: Apache-2.0

#include "parser.hpp"
#include "asserts.hpp"
#include "leb128.hpp"
#include "limits.hpp"
#include "types.hpp"
Expand Down Expand Up @@ -532,8 +533,8 @@ std::unique_ptr<const Module> parse(bytes_view input)
case ExternalKind::Global:
module->imported_global_types.emplace_back(import.desc.global);
break;
default:
assert(false);
default: // LCOV_EXCL_LINE
FIZZY_UNREACHABLE(); // LCOV_EXCL_LINE
}
}

Expand Down Expand Up @@ -635,8 +636,8 @@ std::unique_ptr<const Module> parse(bytes_view input)
if (export_.index >= total_global_count)
throw validation_error{"invalid index of an exported global"};
break;
default:
assert(false);
default: // LCOV_EXCL_LINE
FIZZY_UNREACHABLE(); // LCOV_EXCL_LINE
}
if (!export_names.emplace(export_.name).second)
throw validation_error{"duplicate export name " + export_.name};
Expand Down
2 changes: 2 additions & 0 deletions test/unittests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ target_link_libraries(fizzy-unittests PRIVATE fizzy::fizzy-internal fizzy::test-
target_sources(
fizzy-unittests PRIVATE
api_test.cpp
asserts_test.cpp
capi_test.cpp
constexpr_vector_test.cpp
cxx20_bit_test.cpp
cxx20_span_test.cpp
end_to_end_test.cpp
execute_call_test.cpp
execute_control_test.cpp
execute_death_test.cpp
execute_floating_point_test.cpp
execute_numeric_test.cpp
execute_test.cpp
Expand Down
14 changes: 14 additions & 0 deletions test/unittests/asserts_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Fizzy: A fast WebAssembly interpreter
// Copyright 2020 The Fizzy Authors.
// SPDX-License-Identifier: Apache-2.0

#include "asserts.hpp"
#include <gtest/gtest.h>

#if !defined(NDEBUG) || __has_feature(undefined_behavior_sanitizer)
TEST(asserts_death, unreachable)
{
static constexpr auto unreachable = []() noexcept { FIZZY_UNREACHABLE(); };
EXPECT_DEATH(unreachable(), "unreachable");
}
#endif
28 changes: 28 additions & 0 deletions test/unittests/execute_death_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Fizzy: A fast WebAssembly interpreter
// Copyright 2020 The Fizzy Authors.
// SPDX-License-Identifier: Apache-2.0

#include "asserts.hpp"
#include "execute.hpp"
#include <gtest/gtest.h>

using namespace fizzy;

#if !defined(NDEBUG) || __has_feature(undefined_behavior_sanitizer)
TEST(execute_death, malformed_instruction_opcode)
{
constexpr auto malformed_opcode = static_cast<Instr>(6);

Code code;
code.instructions.emplace_back(malformed_opcode);
code.instructions.emplace_back(Instr::end);

auto module = std::make_unique<Module>();
module->typesec.emplace_back(FuncType{});
module->funcsec.emplace_back(TypeIdx{0});
module->codesec.emplace_back(std::move(code));

auto instance = instantiate(std::move(module));
EXPECT_DEATH(execute(*instance, 0, nullptr), "unreachable");
}
#endif

0 comments on commit c179d1b

Please sign in to comment.