diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index 32821ea2200..f1ac8c2d4bd 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn @@ -271,15 +271,12 @@ config("compiler") { cflags += [ "-fcolor-diagnostics" ] } - # C++11 compiler flags setup. + # C++ standard compiler flags setup. # --------------------------- if (is_win) { - # Up-to-date toolchain MSVC doesn't support c++11 flag any longer. - cc_std = [ "/std:c++14" ] - } else if (is_fuchsia) { - cc_std = [ "-std=c++17" ] + cc_std = [ "/std:c++17" ] } else { - cc_std = [ "-std=c++11" ] + cc_std = [ "-std=c++17" ] } cflags_cc += cc_std cflags_objcc += cc_std diff --git a/runtime/platform/globals.h b/runtime/platform/globals.h index 407304ef549..52201dcc817 100644 --- a/runtime/platform/globals.h +++ b/runtime/platform/globals.h @@ -20,7 +20,13 @@ // from the way the Dart project expects it: DEBUG indicating a debug build. #if !defined(NDEBUG) && !defined(DEBUG) #define DEBUG -#endif // !NDEBUG && !DEBUG +#endif // !NDEBUG && !DEBUG \ +#else +// Since uses NDEBUG to signify that assert() macros should be turned +// off, we'll define it when DEBUG is _not_ set. +#if !defined(DEBUG) +#define NDEBUG +#endif #endif // GOOGLE3 // __STDC_FORMAT_MACROS has to be defined before including to @@ -85,6 +91,8 @@ #include #include +#include // For assert() in constant expressions. + #if defined(_WIN32) #include "platform/floating_point_win.h" #endif // defined(_WIN32) @@ -136,12 +144,6 @@ #define DEBUG_ONLY(code) #endif // defined(DEBUG) -#if defined(DEBUG) -#define UNLESS_DEBUG(code) -#else // defined(DEBUG) -#define UNLESS_DEBUG(code) code -#endif // defined(DEBUG) - namespace dart { struct simd128_value_t { diff --git a/runtime/platform/utils.h b/runtime/platform/utils.h index eecab24cba4..788dd2a8912 100644 --- a/runtime/platform/utils.h +++ b/runtime/platform/utils.h @@ -57,7 +57,7 @@ class Utils { } template - static inline bool IsPowerOfTwo(T x) { + static constexpr bool IsPowerOfTwo(T x) { return ((x & (x - 1)) == 0) && (x != 0); } @@ -73,13 +73,13 @@ class Utils { } template - static inline bool IsAligned(T x, intptr_t n) { - ASSERT(IsPowerOfTwo(n)); + static constexpr bool IsAligned(T x, intptr_t n) { + assert(IsPowerOfTwo(n)); return (x & (n - 1)) == 0; } template - static inline bool IsAligned(T* x, intptr_t n) { + static constexpr bool IsAligned(T* x, intptr_t n) { return IsAligned(reinterpret_cast(x), n); } diff --git a/runtime/vm/bitfield.h b/runtime/vm/bitfield.h index 4a4f45fb753..b982d834470 100644 --- a/runtime/vm/bitfield.h +++ b/runtime/vm/bitfield.h @@ -7,7 +7,6 @@ #include -#include "platform/assert.h" #include "platform/globals.h" namespace dart { @@ -52,8 +51,8 @@ class BitField { static constexpr int bitsize() { return size; } // Returns an S with the bit field value encoded. - static UNLESS_DEBUG(constexpr) S encode(T value) { - DEBUG_ASSERT(is_valid(value)); + static constexpr S encode(T value) { + assert(is_valid(value)); return encode_unchecked(value); } @@ -62,29 +61,28 @@ class BitField { // Ensure we slide down the sign bit if the value in the bit field is signed // and negative. We use 64-bit ints inside the expression since we can have // both cases: sizeof(S) > sizeof(T) or sizeof(S) < sizeof(T). - return static_cast( - (sign_extend - ? (static_cast(static_cast(value) - << (64 - (size + position))) >> - (64 - size)) - : ((static_cast::type>(value) >> - position) & - mask()))); + if constexpr (sign_extend) { + auto const u = static_cast(value); + return static_cast((static_cast(u << (64 - kNextBit))) >> + (64 - size)); + } else { + auto const u = static_cast::type>(value); + return static_cast((u >> position) & mask()); + } } // Returns an S with the bit field value encoded based on the // original value. Only the bits corresponding to this bit field // will be changed. - static UNLESS_DEBUG(constexpr) S update(T value, S original) { - DEBUG_ASSERT(is_valid(value)); - return encode_unchecked(value) | (~mask_in_place() & original); + static constexpr S update(T value, S original) { + return encode(value) | (~mask_in_place() & original); } private: // Returns an S with the bit field value encoded. static constexpr S encode_unchecked(T value) { - return (static_cast::type>(value) & mask()) - << position; + auto const u = static_cast::type>(value); + return (u & mask()) << position; } }; diff --git a/runtime/vm/bitfield_test.cc b/runtime/vm/bitfield_test.cc index e90a2571b35..e2d40f000e1 100644 --- a/runtime/vm/bitfield_test.cc +++ b/runtime/vm/bitfield_test.cc @@ -70,4 +70,16 @@ VM_UNIT_TEST_CASE(BitFields_SignedField) { TestSignExtendedBitField(); } +#if defined(DEBUG) +#define DEBUG_CRASH "Crash" +#else +#define DEBUG_CRASH "Pass" +#endif + +VM_UNIT_TEST_CASE_WITH_EXPECTATION(BitFields_Assert, DEBUG_CRASH) { + class F : public BitField {}; + const uint32_t value = F::encode(kMaxUint32); + EXPECT_EQ(kMaxUint8, value); +} + } // namespace dart diff --git a/runtime/vm/image_snapshot.cc b/runtime/vm/image_snapshot.cc index 614740466b7..25ace1d7580 100644 --- a/runtime/vm/image_snapshot.cc +++ b/runtime/vm/image_snapshot.cc @@ -557,7 +557,7 @@ void ImageWriter::WriteROData(NonStreamingWriteStream* stream, bool vm) { } } -static UNLESS_DEBUG(constexpr) const uword kReadOnlyGCBits = +static constexpr uword kReadOnlyGCBits = UntaggedObject::OldBit::encode(true) | UntaggedObject::OldAndNotMarkedBit::encode(false) | UntaggedObject::OldAndNotRememberedBit::encode(true) | diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h index 79fa9df94df..a4f0b8aa191 100644 --- a/runtime/vm/raw_object.h +++ b/runtime/vm/raw_object.h @@ -153,7 +153,7 @@ class UntaggedObject { static constexpr intptr_t kMaxSizeTag = kMaxSizeTagInUnitsOfAlignment * kObjectAlignment; - static UNLESS_DEBUG(constexpr) uword encode(intptr_t size) { + static constexpr uword encode(intptr_t size) { return SizeBits::encode(SizeToTagValue(size)); } @@ -161,11 +161,11 @@ class UntaggedObject { return TagValueToSize(SizeBits::decode(tag)); } - static UNLESS_DEBUG(constexpr) uword update(intptr_t size, uword tag) { + static constexpr uword update(intptr_t size, uword tag) { return SizeBits::update(SizeToTagValue(size), tag); } - static UNLESS_DEBUG(constexpr) bool SizeFits(intptr_t size) { + static constexpr bool SizeFits(intptr_t size) { DEBUG_ASSERT(Utils::IsAligned(size, kObjectAlignment)); return (size <= kMaxSizeTag); } @@ -175,8 +175,8 @@ class UntaggedObject { class SizeBits : public BitField {}; - static UNLESS_DEBUG(constexpr) intptr_t SizeToTagValue(intptr_t size) { - DEBUG_ASSERT(Utils::IsAligned(size, kObjectAlignment)); + static constexpr intptr_t SizeToTagValue(intptr_t size) { + assert(Utils::IsAligned(size, kObjectAlignment)); return !SizeFits(size) ? 0 : (size >> kObjectAlignmentLog2); } static constexpr intptr_t TagValueToSize(intptr_t value) {