By making __glibcxx_assert constexpr compatible we can get rid of a
FIXME in basic_string_view and so fix following XPASS in _GLIBCXX_DEBUG
modes.
XPASS: 21_strings/basic_string_view/element_access/char/2.cc execution test
XPASS: 21_strings/basic_string_view/element_access/wchar_t/2.cc
execution test
Should I also rename those in 2_neg.cc ?
I had to move the assert block in c++config to benefit from
_GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED definition. The generation
of the compilation error is not very nice but it is still better than no
error and we can see the assertion:
/home/fdt/dev/gcc/git/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/wchar_t/constexpr_neg.cc:31:22:
erreur: condition non constante pour l'assertion statique
31 | static_assert(test() == 0); // { dg-error "non-constant
condition" }
| ~~~~~~~^~~~
Dans le fichier inclus depuis
/home/fdt/dev/gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/limits:42,
depuis
/home/fdt/dev/gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/string_view:40,
depuis
/home/fdt/dev/gcc/git/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/wchar_t/constexpr_neg.cc:21:
/home/fdt/dev/gcc/git/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/wchar_t/constexpr_neg.cc:31:19:
dans l'expansion « constexpr » de « test() »
/home/fdt/dev/gcc/git/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/wchar_t/constexpr_neg.cc:28:13:
dans l'expansion « constexpr » de
« s.std::basic_string_view<wchar_t>::operator[](4) »
/home/fdt/dev/gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/string_view:206:2:
erreur: inline assembly is not a constant expression
206 | __glibcxx_assert(__pos < this->_M_len);
| ^~~~~~~~~~~~~~~~
/home/fdt/dev/gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/string_view:206:2:
note: only unevaluated inline assembly is allowed in a « constexpr »
function in C++2a
* include/bits/c++config
[_GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED](__glibcxx_assert_impl):
New.
* include/std/string_view
(basic_string_view<>:operator[](size_type)):
Restore __glibcxx_assert.
(basic_string_view<>::front()): Likewise.
(basic_string_view<>::back()): Likewise.
*
testsuite/21_strings/basic_string_view/element_access/char/back_constexpr_neg.cc:
New.
*
testsuite/21_strings/basic_string_view/element_access/char/constexpr.cc:
New.
*
testsuite/21_strings/basic_string_view/element_access/char/constexpr_neg.cc:
New.
*
testsuite/21_strings/basic_string_view/element_access/char/front_back_constexpr.cc:
New.
*
testsuite/21_strings/basic_string_view/element_access/char/front_constexpr_neg.cc:
New.
*
testsuite/21_strings/basic_string_view/element_access/wchar_t/constexpr.cc:
New.
*
testsuite/21_strings/basic_string_view/element_access/wchar_t/constexpr_neg.cc:
New.
Tested under Linux x86_64 normal and debug modes.
Ok to commit ?
François
diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config
index b1fad59d4b3..4d821627447 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -441,37 +441,6 @@ namespace std
# define _GLIBCXX_EXTERN_TEMPLATE -1
#endif
-// Assert.
-#if defined(_GLIBCXX_ASSERTIONS) \
- || defined(_GLIBCXX_PARALLEL) || defined(_GLIBCXX_PARALLEL_ASSERTIONS)
-namespace std
-{
- // Avoid the use of assert, because we're trying to keep the <cassert>
- // include out of the mix.
- extern "C++" inline void
- __replacement_assert(const char* __file, int __line,
- const char* __function, const char* __condition)
- {
- __builtin_printf("%s:%d: %s: Assertion '%s' failed.\n", __file, __line,
- __function, __condition);
- __builtin_abort();
- }
-}
-#define __glibcxx_assert_impl(_Condition) \
- do \
- { \
- if (! (_Condition)) \
- std::__replacement_assert(__FILE__, __LINE__, __PRETTY_FUNCTION__, \
- #_Condition); \
- } while (false)
-#endif
-
-#if defined(_GLIBCXX_ASSERTIONS)
-# define __glibcxx_assert(_Condition) __glibcxx_assert_impl(_Condition)
-#else
-# define __glibcxx_assert(_Condition)
-#endif
-
// Macros for race detectors.
// _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(A) and
// _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(A) should be used to explain
@@ -663,6 +632,53 @@ namespace std
# endif
#endif // GCC
+// Assert.
+#if defined(_GLIBCXX_ASSERTIONS) \
+ || defined(_GLIBCXX_PARALLEL) || defined(_GLIBCXX_PARALLEL_ASSERTIONS)
+namespace std
+{
+ // Avoid the use of assert, because we're trying to keep the <cassert>
+ // include out of the mix.
+ extern "C++" inline void
+ __replacement_assert(const char* __file, int __line,
+ const char* __function, const char* __condition)
+ {
+ __builtin_printf("%s:%d: %s: Assertion '%s' failed.\n", __file, __line,
+ __function, __condition);
+ __builtin_abort();
+ }
+}
+# ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
+# define __glibcxx_assert_impl(_Condition) \
+ do \
+ { \
+ if (__builtin_is_constant_evaluated()) \
+ { \
+ if (!(_Condition)) \
+ /* FIXME Generate compilation error here. */ \
+ asm("assertion failure"); \
+ } \
+ else if (! (_Condition)) \
+ std::__replacement_assert(__FILE__, __LINE__, __PRETTY_FUNCTION__, \
+ #_Condition); \
+ } while (false)
+# else
+# define __glibcxx_assert_impl(_Condition) \
+ do \
+ { \
+ if (! (_Condition)) \
+ std::__replacement_assert(__FILE__, __LINE__, __PRETTY_FUNCTION__, \
+ #_Condition); \
+ } while (false)
+# endif
+#endif
+
+#if defined(_GLIBCXX_ASSERTIONS)
+# define __glibcxx_assert(_Condition) __glibcxx_assert_impl(_Condition)
+#else
+# define __glibcxx_assert(_Condition)
+#endif
+
// PSTL configuration
#if __cplusplus >= 201703L
diff --git a/libstdc++-v3/include/std/string_view b/libstdc++-v3/include/std/string_view
index 798cb89a621..84ecb56b5d2 100644
--- a/libstdc++-v3/include/std/string_view
+++ b/libstdc++-v3/include/std/string_view
@@ -203,8 +203,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
constexpr const_reference
operator[](size_type __pos) const noexcept
{
- // TODO: Assert to restore in a way compatible with the constexpr.
- // __glibcxx_assert(__pos < this->_M_len);
+ __glibcxx_assert(__pos < this->_M_len);
return *(this->_M_str + __pos);
}
@@ -221,16 +220,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
constexpr const_reference
front() const noexcept
{
- // TODO: Assert to restore in a way compatible with the constexpr.
- // __glibcxx_assert(this->_M_len > 0);
+ __glibcxx_assert(this->_M_len > 0);
return *this->_M_str;
}
constexpr const_reference
back() const noexcept
{
- // TODO: Assert to restore in a way compatible with the constexpr.
- // __glibcxx_assert(this->_M_len > 0);
+ __glibcxx_assert(this->_M_len > 0);
return *(this->_M_str + this->_M_len - 1);
}
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/back_constexpr_neg.cc b/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/back_constexpr_neg.cc
new file mode 100644
index 00000000000..1bf7f758c57
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/back_constexpr_neg.cc
@@ -0,0 +1,35 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17 -D_GLIBCXX_ASSERTIONS" }
+// { dg-do compile { target c++17 xfail *-*-* } }
+
+#include <string_view>
+
+typedef std::string_view string_view_type;
+
+constexpr char
+back()
+{
+ string_view_type s("");
+ return s.back();
+}
+
+static_assert(back() != 'a'); // { dg-error "non-constant condition" }
+
+// { dg-prune-output "in 'constexpr' expansion" }
+// { dg-prune-output "not a constant expression" }
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/constexpr.cc b/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/constexpr.cc
new file mode 100644
index 00000000000..aa2a08ebe83
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/constexpr.cc
@@ -0,0 +1,31 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do compile { target c++17 } }
+
+#include <string_view>
+
+constexpr char
+test()
+{
+ typedef std::string_view string_view_type;
+ string_view_type s("abcd");
+ return s[0];
+}
+
+static_assert(test() == 'a');
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/constexpr_neg.cc b/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/constexpr_neg.cc
new file mode 100644
index 00000000000..77ad7ba0aeb
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/constexpr_neg.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17 -D_GLIBCXX_ASSERTIONS" }
+// { dg-do compile { target c++17 xfail *-*-* } }
+
+#include <string_view>
+
+constexpr char
+test()
+{
+ typedef std::string_view string_view_type;
+ string_view_type s("abcd");
+ return s[s.length()];
+}
+
+static_assert(test() == 0); // { dg-error "non-constant condition" }
+
+// { dg-prune-output "in 'constexpr' expansion" }
+// { dg-prune-output "not a constant expression" }
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/front_back_constexpr.cc b/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/front_back_constexpr.cc
new file mode 100644
index 00000000000..7ead45ddcf6
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/front_back_constexpr.cc
@@ -0,0 +1,41 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do compile { target c++17 } }
+
+#include <string_view>
+
+typedef std::string_view string_view_type;
+
+constexpr char
+front()
+{
+ string_view_type s("abcd");
+ return s.front();
+}
+
+static_assert(front() == 'a');
+
+constexpr char
+back()
+{
+ string_view_type s("abcd");
+ return s.back();
+}
+
+static_assert(back() == 'd');
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/front_constexpr_neg.cc b/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/front_constexpr_neg.cc
new file mode 100644
index 00000000000..19800739814
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/front_constexpr_neg.cc
@@ -0,0 +1,35 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17 -D_GLIBCXX_ASSERTIONS" }
+// { dg-do compile { target c++17 xfail *-*-* } }
+
+#include <string_view>
+
+typedef std::string_view string_view_type;
+
+constexpr char
+front()
+{
+ string_view_type s("");
+ return s.front();
+}
+
+static_assert(front() != 'a'); // { dg-error "non-constant condition" }
+
+// { dg-prune-output "in 'constexpr' expansion" }
+// { dg-prune-output "not a constant expression" }
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/wchar_t/constexpr.cc b/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/wchar_t/constexpr.cc
new file mode 100644
index 00000000000..f4171628e9f
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/wchar_t/constexpr.cc
@@ -0,0 +1,31 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do compile { target c++17 } }
+
+#include <string_view>
+
+constexpr wchar_t
+test()
+{
+ typedef std::wstring_view string_view_type;
+ string_view_type s(L"abcd");
+ return s[0];
+}
+
+static_assert(test() == L'a');
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/wchar_t/constexpr_neg.cc b/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/wchar_t/constexpr_neg.cc
new file mode 100644
index 00000000000..2b1bc68d11c
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/wchar_t/constexpr_neg.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17 -D_GLIBCXX_ASSERTIONS" }
+// { dg-do compile { target c++17 xfail *-*-* } }
+
+#include <string_view>
+
+constexpr wchar_t
+test()
+{
+ typedef std::wstring_view string_view_type;
+ string_view_type s(L"abcd");
+ return s[4];
+}
+
+static_assert(test() == 0); // { dg-error "non-constant condition" }
+
+// { dg-prune-output "in 'constexpr' expansion" }
+// { dg-prune-output "not a constant expression" }