Title: [233391] trunk
Revision
233391
Author
[email protected]
Date
2018-06-29 23:42:04 -0700 (Fri, 29 Jun 2018)

Log Message

WTF's internal std::optional implementation should abort() on bad optional access
https://bugs.webkit.org/show_bug.cgi?id=186536

Patch by Frederic Wang <[email protected]> on 2018-06-29
Reviewed by Michael Catanzaro.

Source/WTF:

Currently, some ports built with recent compilers will cause the program to abort when one
tries to access the value of an unset std:optional (i.e. std::nullopt) as specified by C++17.
However, most ports still use WTF's internal std::optional implementation, which does not
verify illegal access. Hence it's not possible for developers working on these ports to
detect issues like bugs #186189, #186535, #186752, #186753, #187139 or #187145. WTF's version
of std::optional was introduced in bug #164199 but it was not possible to verify the
availability of the value inside constexpr member functions because the assert might involve
asm declarations. This commit introduces a new RELEASE_ASSERT_UNDER_CONSTEXPR_CONTEXT macro
(a simplified version of RELEASE_ASSERT that can be used in constexpr context) and uses it in
WTF's implementation of std::optional.

* wtf/Assertions.h: Define RELEASE_ASSERT_UNDER_CONSTEXPR_CONTEXT as a version of
RELEASE_ASSERT that can be used in constexpr context (in particular avoids asm declarations).
* wtf/Optional.h:
(std::optional::operator ->): Add an assert to ensure the optional value is available.
(std::optional::operator *): Ditto.
(std::optional::value const): Ditto.
(std::optional::value): Ditto.
(std::optional<T::value const): Ditto.

LayoutTests:

* TestExpectations: Mark one WebAnimations test as crashing (bug #187145).

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (233390 => 233391)


--- trunk/LayoutTests/ChangeLog	2018-06-30 05:40:44 UTC (rev 233390)
+++ trunk/LayoutTests/ChangeLog	2018-06-30 06:42:04 UTC (rev 233391)
@@ -1,3 +1,12 @@
+2018-06-29  Frederic Wang  <[email protected]>
+
+        WTF's internal std::optional implementation should abort() on bad optional access
+        https://bugs.webkit.org/show_bug.cgi?id=186536
+
+        Reviewed by Michael Catanzaro.
+
+        * TestExpectations: Mark one WebAnimations test as crashing (bug #187145).
+
 2018-06-29  Nan Wang  <[email protected]>
 
         Crash under WebCore::AXObjectCache::handleMenuItemSelected

Modified: trunk/LayoutTests/TestExpectations (233390 => 233391)


--- trunk/LayoutTests/TestExpectations	2018-06-30 05:40:44 UTC (rev 233390)
+++ trunk/LayoutTests/TestExpectations	2018-06-30 06:42:04 UTC (rev 233391)
@@ -386,6 +386,8 @@
 # End platform-specific tests.
 #//////////////////////////////////////////////////////////////////////////////////////////
 
+webkit.org/b/187145 imported/w3c/web-platform-tests/web-animations/interfaces/Animatable/animate-no-browsing-context.html [ Crash ]
+
 # media/video-seek-after-end.html is flaky
 webkit.org/b/116293 media/video-seek-after-end.html [ Pass Failure ]
 

Modified: trunk/Source/WTF/ChangeLog (233390 => 233391)


--- trunk/Source/WTF/ChangeLog	2018-06-30 05:40:44 UTC (rev 233390)
+++ trunk/Source/WTF/ChangeLog	2018-06-30 06:42:04 UTC (rev 233391)
@@ -1,3 +1,30 @@
+2018-06-29  Frederic Wang  <[email protected]>
+
+        WTF's internal std::optional implementation should abort() on bad optional access
+        https://bugs.webkit.org/show_bug.cgi?id=186536
+
+        Reviewed by Michael Catanzaro.
+
+        Currently, some ports built with recent compilers will cause the program to abort when one
+        tries to access the value of an unset std:optional (i.e. std::nullopt) as specified by C++17.
+        However, most ports still use WTF's internal std::optional implementation, which does not
+        verify illegal access. Hence it's not possible for developers working on these ports to
+        detect issues like bugs #186189, #186535, #186752, #186753, #187139 or #187145. WTF's version
+        of std::optional was introduced in bug #164199 but it was not possible to verify the
+        availability of the value inside constexpr member functions because the assert might involve
+        asm declarations. This commit introduces a new RELEASE_ASSERT_UNDER_CONSTEXPR_CONTEXT macro
+        (a simplified version of RELEASE_ASSERT that can be used in constexpr context) and uses it in
+        WTF's implementation of std::optional.
+
+        * wtf/Assertions.h: Define RELEASE_ASSERT_UNDER_CONSTEXPR_CONTEXT as a version of
+        RELEASE_ASSERT that can be used in constexpr context (in particular avoids asm declarations).
+        * wtf/Optional.h:
+        (std::optional::operator ->): Add an assert to ensure the optional value is available.
+        (std::optional::operator *): Ditto.
+        (std::optional::value const): Ditto. 
+        (std::optional::value): Ditto.
+        (std::optional<T::value const): Ditto.
+
 2018-06-29  Darin Adler  <[email protected]>
 
         [Cocoa] reduce unnecessary use of .mm source files in WTF, spruce up some implementation details

Modified: trunk/Source/WTF/wtf/Assertions.h (233390 => 233391)


--- trunk/Source/WTF/wtf/Assertions.h	2018-06-30 05:40:44 UTC (rev 233390)
+++ trunk/Source/WTF/wtf/Assertions.h	2018-06-30 06:42:04 UTC (rev 233391)
@@ -220,6 +220,12 @@
 #define WTFBreakpointTrap() WTFCrash() // Not implemented.
 #endif
 
+#if COMPILER(MSVC)
+#define WTFBreakpointTrapUnderConstexprContext() __debugbreak()
+#else
+#define WTFBreakpointTrapUnderConstexprContext() __builtin_trap()
+#endif
+
 #ifndef CRASH
 
 #if defined(NDEBUG) && OS(DARWIN)
@@ -505,6 +511,27 @@
 #define RELEASE_ASSERT_NOT_REACHED() ASSERT_NOT_REACHED()
 #endif
 
+/* RELEASE_ASSERT_UNDER_CONSTEXPR_CONTEXT
+
+   This is a special version of RELEASE_ASSERT(assertion) that can be used in constexpr contexts.
+*/
+#if ASSERT_DISABLED
+#define RELEASE_ASSERT_UNDER_CONSTEXPR_CONTEXT(assertion) do { \
+    if (UNLIKELY(!(assertion))) { \
+        WTFBreakpointTrapUnderConstexprContext(); \
+        __builtin_unreachable(); \
+    } \
+} while (0)
+#else
+#define RELEASE_ASSERT_UNDER_CONSTEXPR_CONTEXT(assertion) do { \
+    if (!(assertion)) { \
+        WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion); \
+        WTFBreakpointTrapUnderConstexprContext(); \
+        __builtin_unreachable(); \
+    } \
+} while (0)
+#endif
+
 /* UNREACHABLE_FOR_PLATFORM */
 
 #if COMPILER(CLANG)

Modified: trunk/Source/WTF/wtf/Optional.h (233390 => 233391)


--- trunk/Source/WTF/wtf/Optional.h	2018-06-30 05:40:44 UTC (rev 233390)
+++ trunk/Source/WTF/wtf/Optional.h	2018-06-30 06:42:04 UTC (rev 233391)
@@ -530,8 +530,7 @@
   }
 
   OPTIONAL_MUTABLE_CONSTEXPR T* operator ->() {
-    // FIXME: We need to offer special assert function that can be used under the contexpr context.
-    // CONSTEXPR_ASSERT(initialized());
+    RELEASE_ASSERT_UNDER_CONSTEXPR_CONTEXT(initialized());
     return dataptr();
   }
 
@@ -540,32 +539,27 @@
   }
 
   OPTIONAL_MUTABLE_CONSTEXPR T& operator *() & {
-    // FIXME: We need to offer special assert function that can be used under the contexpr context.
-    // CONSTEXPR_ASSERT(initialized());
+    RELEASE_ASSERT_UNDER_CONSTEXPR_CONTEXT(initialized());
     return contained_val();
   }
 
   OPTIONAL_MUTABLE_CONSTEXPR T&& operator *() && {
-    // FIXME: We need to offer special assert function that can be used under the contexpr context.
-    // CONSTEXPR_ASSERT(initialized());
+    RELEASE_ASSERT_UNDER_CONSTEXPR_CONTEXT(initialized());
     return detail_::constexpr_move(contained_val());
   }
 
   constexpr T const& value() const& {
-    // FIXME: We need to offer special assert function that can be used under the contexpr context.
-    // return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val());
+    RELEASE_ASSERT_UNDER_CONSTEXPR_CONTEXT(initialized());
     return contained_val();
   }
 
   OPTIONAL_MUTABLE_CONSTEXPR T& value() & {
-    // FIXME: We need to offer special assert function that can be used under the contexpr context.
-    // return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val());
+    RELEASE_ASSERT_UNDER_CONSTEXPR_CONTEXT(initialized());
     return contained_val();
   }
 
   OPTIONAL_MUTABLE_CONSTEXPR T&& value() && {
-    // FIXME: We need to offer special assert function that can be used under the contexpr context.
-    // if (!initialized()) __THROW_EXCEPTION(bad_optional_access("bad optional access"));
+    RELEASE_ASSERT_UNDER_CONSTEXPR_CONTEXT(initialized());
     return std::move(contained_val());
   }
 
@@ -683,8 +677,7 @@
   }
 
   constexpr T& value() const {
-    // FIXME: We need to offer special assert function that can be used under the contexpr context.
-    // return ref ? *ref : (throw bad_optional_access("bad optional access"), *ref);
+    RELEASE_ASSERT_UNDER_CONSTEXPR_CONTEXT(ref());
     return *ref;
   }
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to