https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89446
Bug ID: 89446 Summary: [7/8 Regression] __builtin_constant_p expression crashes in char_traits::compare Product: gcc Version: 8.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: redi at gcc dot gnu.org Target Milestone: --- #include <string_view> int main() { std::string_view s1, s2; return s1 == s2; } This crashes when compiled with -std=c++17 -O1 -fnon-call-exceptions Program received signal SIGSEGV, Segmentation fault. main () at /usr/include/c++/8/bits/char_traits.h:303 303 if (__builtin_constant_p(__n) #0 main () at /usr/include/c++/8/bits/char_traits.h:303 I think the fix is: --- a/libstdc++-v3/include/bits/char_traits.h +++ b/libstdc++-v3/include/bits/char_traits.h @@ -248,7 +248,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __constant_char_array_p(const _CharT* __a, size_t __n) { size_t __i = 0; - while (__builtin_constant_p(__a[__i]) && __i < __n) + while (__i < __n && __builtin_constant_p(__a[__i]) && __i < __n) __i++; return __i == __n; } But we can also avoid those checks entirely for empty strings: @@ -301,14 +301,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static _GLIBCXX17_CONSTEXPR int compare(const char_type* __s1, const char_type* __s2, size_t __n) { + if (__n == 0) + return 0; #if __cplusplus > 201402 if (__builtin_constant_p(__n) && __constant_char_array_p(__s1, __n) && __constant_char_array_p(__s2, __n)) return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n); #endif - if (__n == 0) - return 0; return __builtin_memcmp(__s1, __s2, __n); } (and similarly in char_traits<char>::find and char_traits<wchar_t>). It doesn't currently fail on trunk, because we use __builtin_is_constant_evaluated now instead of the __builtin_constant_p checks, but the bug is still present.