From: Jonathan Wakely
Date: Fri, 30 Sep 2016 16:07:43 +0000 (+0100)
Subject: Implement LWG 2192 and LWG 2294 for std::abs
X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=37b204de605563e7932e26099d28ea8c86cb1935;p=gcc.git
Implement LWG 2192 and LWG 2294 for std::abs
* doc/xml/manual/intro.xml: Document LWG 2192 changes.
* doc/html/*: Regenerate.
* include/Makefile.am: Add bits/std_abs.h.
* include/Makefile.in: Regenerate.
* include/bits/std_abs.h: New header defining all required overloads
of std::abs in one place (LWG 2294).
* include/c_global/cmath (abs(double), abs(float), abs(long double)):
Move to bits/std_abs.h.
(abs<_Tp>(_Tp)): Remove.
* include/c_global/cstdlib (abs(long), abs(long long), abs(__int)):
Move to bits/std_abs.h.
* testsuite/26_numerics/headers/cmath/dr2192.cc: New test.
* testsuite/26_numerics/headers/cmath/dr2192_neg.cc: New test.
* testsuite/26_numerics/headers/cstdlib/dr2192.cc: New test.
* testsuite/26_numerics/headers/cstdlib/dr2192_neg.cc: New test.
From-SVN: r240660
---
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 0bd62c549b8..f73e62e4789 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,21 @@
2016-09-30 Jonathan Wakely
+ * doc/xml/manual/intro.xml: Document LWG 2192 changes.
+ * doc/html/*: Regenerate.
+ * include/Makefile.am: Add bits/std_abs.h.
+ * include/Makefile.in: Regenerate.
+ * include/bits/std_abs.h: New header defining all required overloads
+ of std::abs in one place (LWG 2294).
+ * include/c_global/cmath (abs(double), abs(float), abs(long double)):
+ Move to bits/std_abs.h.
+ (abs<_Tp>(_Tp)): Remove.
+ * include/c_global/cstdlib (abs(long), abs(long long), abs(__int)):
+ Move to bits/std_abs.h.
+ * testsuite/26_numerics/headers/cmath/dr2192.cc: New test.
+ * testsuite/26_numerics/headers/cmath/dr2192_neg.cc: New test.
+ * testsuite/26_numerics/headers/cstdlib/dr2192.cc: New test.
+ * testsuite/26_numerics/headers/cstdlib/dr2192_neg.cc: New test.
+
PR libstdc++/77801
* include/experimental/numeric: Include .
(__abs): Define.
diff --git a/libstdc++-v3/doc/html/manual/bugs.html b/libstdc++-v3/doc/html/manual/bugs.html
index de2ad5f1182..8469c6efa4a 100644
--- a/libstdc++-v3/doc/html/manual/bugs.html
+++ b/libstdc++-v3/doc/html/manual/bugs.html
@@ -411,6 +411,10 @@
2187:
vector<bool> is missing emplace and emplace_back member functions
Add emplace and emplace_back member functions.
+
2192:
+ Validity and return type of std::abs(0u) is unclear
+
Move all declarations to a common header and remove the
+ generic abs which accepted unsigned arguments.
2196:
Specification of is_*[copy/move]_[constructible/assignable] unclear for non-referencable types
Use the referenceable type concept.
diff --git a/libstdc++-v3/doc/xml/manual/intro.xml b/libstdc++-v3/doc/xml/manual/intro.xml
index 238ab241080..47478513666 100644
--- a/libstdc++-v3/doc/xml/manual/intro.xml
+++ b/libstdc++-v3/doc/xml/manual/intro.xml
@@ -940,6 +940,13 @@ requirements of the license of GCC.
Add emplace and emplace_back member functions.
+ 2192:
+ Validity and return type of std::abs(0u) is unclear
+
+ Move all declarations to a common header and remove the
+ generic abs which accepted unsigned arguments.
+
+
2196:
Specification of is_*[copy/move]_[constructible/assignable] unclear for non-referencable types
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 778225899c3..4e63fbb438b 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -159,6 +159,7 @@ bits_headers = \
${bits_srcdir}/shared_ptr_base.h \
${bits_srcdir}/slice_array.h \
${bits_srcdir}/sstream.tcc \
+ ${bits_srcdir}/std_abs.h \
${bits_srcdir}/std_mutex.h \
${bits_srcdir}/stl_algo.h \
${bits_srcdir}/stl_algobase.h \
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index 4e2b9e4f676..8b788b551c4 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -450,6 +450,7 @@ bits_headers = \
${bits_srcdir}/shared_ptr_base.h \
${bits_srcdir}/slice_array.h \
${bits_srcdir}/sstream.tcc \
+ ${bits_srcdir}/std_abs.h \
${bits_srcdir}/std_mutex.h \
${bits_srcdir}/stl_algo.h \
${bits_srcdir}/stl_algobase.h \
diff --git a/libstdc++-v3/include/bits/std_abs.h b/libstdc++-v3/include/bits/std_abs.h
new file mode 100644
index 00000000000..ab0f980a3a6
--- /dev/null
+++ b/libstdc++-v3/include/bits/std_abs.h
@@ -0,0 +1,107 @@
+// -*- C++ -*- C library enhancements header.
+
+// Copyright (C) 2016 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.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// .
+
+/** @file include/bits/std_abs.h
+ * This is an internal header file, included by other library headers.
+ * Do not attempt to use it directly. @headername{cmath, cstdlib}
+ */
+
+#ifndef _GLIBCXX_BITS_STD_ABS_H
+#define _GLIBCXX_BITS_STD_ABS_H
+
+#pragma GCC system_header
+
+#include
+
+#define _GLIBCXX_INCLUDE_NEXT_C_HEADERS
+#include_next
+#ifdef __CORRECT_ISO_CPP_MATH_H_PROTO
+# include_next
+#endif
+#undef _GLIBCXX_INCLUDE_NEXT_C_HEADERS
+
+#undef abs
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+ using ::abs;
+
+#ifndef __CORRECT_ISO_CPP_STDLIB_H_PROTO
+ inline long
+ abs(long __i) { return __builtin_labs(__i); }
+#endif
+
+#ifdef _GLIBCXX_USE_LONG_LONG
+ inline long long
+ abs(long long __x) { return __builtin_llabs (__x); }
+#endif
+
+// _GLIBCXX_RESOLVE_LIB_DEFECTS
+// 2192. Validity and return type of std::abs(0u) is unclear
+// 2294. should declare abs(double)
+
+#ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
+ inline _GLIBCXX_CONSTEXPR double
+ abs(double __x)
+ { return __builtin_fabs(__x); }
+
+ inline _GLIBCXX_CONSTEXPR float
+ abs(float __x)
+ { return __builtin_fabsf(__x); }
+
+ inline _GLIBCXX_CONSTEXPR long double
+ abs(long double __x)
+ { return __builtin_fabsl(__x); }
+#endif
+
+#if defined(__GLIBCXX_TYPE_INT_N_0)
+ inline _GLIBCXX_CONSTEXPR __GLIBCXX_TYPE_INT_N_0
+ abs(__GLIBCXX_TYPE_INT_N_0 __x) { return __x >= 0 ? __x : -__x; }
+#endif
+#if defined(__GLIBCXX_TYPE_INT_N_1)
+ inline _GLIBCXX_CONSTEXPR __GLIBCXX_TYPE_INT_N_1
+ abs(__GLIBCXX_TYPE_INT_N_1 __x) { return __x >= 0 ? __x : -__x; }
+#endif
+#if defined(__GLIBCXX_TYPE_INT_N_2)
+ inline _GLIBCXX_CONSTEXPR __GLIBCXX_TYPE_INT_N_2
+ abs(__GLIBCXX_TYPE_INT_N_2 __x) { return __x >= 0 ? __x : -__x; }
+#endif
+#if defined(__GLIBCXX_TYPE_INT_N_3)
+ inline _GLIBCXX_CONSTEXPR __GLIBCXX_TYPE_INT_N_3
+ abs(__GLIBCXX_TYPE_INT_N_3 __x) { return __x >= 0 ? __x : -__x; }
+#endif
+
+#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_FLOAT128)
+ inline _GLIBCXX_CONSTEXPR
+ __float128
+ abs(__float128 __x)
+ { return __x < 0 ? -__x : __x; }
+#endif
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
+
+#endif // _GLIBCXX_BITS_STD_ABS_H
diff --git a/libstdc++-v3/include/c_global/cmath b/libstdc++-v3/include/c_global/cmath
index 0e7c4ada699..24ce811adf2 100644
--- a/libstdc++-v3/include/c_global/cmath
+++ b/libstdc++-v3/include/c_global/cmath
@@ -44,12 +44,12 @@
#define _GLIBCXX_INCLUDE_NEXT_C_HEADERS
#include_next
#undef _GLIBCXX_INCLUDE_NEXT_C_HEADERS
+#include
#ifndef _GLIBCXX_CMATH
#define _GLIBCXX_CMATH 1
// Get rid of those macros defined in in lieu of real functions.
-#undef abs
#undef div
#undef acos
#undef asin
@@ -80,29 +80,6 @@ namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
-#ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
- inline _GLIBCXX_CONSTEXPR double
- abs(double __x)
- { return __builtin_fabs(__x); }
-#endif
-
-#ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
- inline _GLIBCXX_CONSTEXPR float
- abs(float __x)
- { return __builtin_fabsf(__x); }
-
- inline _GLIBCXX_CONSTEXPR long double
- abs(long double __x)
- { return __builtin_fabsl(__x); }
-#endif
-
- template
- inline _GLIBCXX_CONSTEXPR
- typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value,
- double>::__type
- abs(_Tp __x)
- { return __builtin_fabs(__x); }
-
using ::acos;
#ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
diff --git a/libstdc++-v3/include/c_global/cstdlib b/libstdc++-v3/include/c_global/cstdlib
index 1ba5fb7f03a..15733dfb75b 100644
--- a/libstdc++-v3/include/c_global/cstdlib
+++ b/libstdc++-v3/include/c_global/cstdlib
@@ -74,10 +74,10 @@ namespace std
#define _GLIBCXX_INCLUDE_NEXT_C_HEADERS
#include_next
#undef _GLIBCXX_INCLUDE_NEXT_C_HEADERS
+#include
// Get rid of those macros defined in in lieu of real functions.
#undef abort
-#undef abs
#undef atexit
#if __cplusplus >= 201103L
# ifdef _GLIBCXX_HAVE_AT_QUICK_EXIT
@@ -125,7 +125,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
using ::ldiv_t;
using ::abort;
- using ::abs;
using ::atexit;
#if __cplusplus >= 201103L
# ifdef _GLIBCXX_HAVE_AT_QUICK_EXIT
@@ -168,35 +167,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#endif // _GLIBCXX_USE_WCHAR_T
#ifndef __CORRECT_ISO_CPP_STDLIB_H_PROTO
- inline long
- abs(long __i) { return __builtin_labs(__i); }
-
inline ldiv_t
div(long __i, long __j) { return ldiv(__i, __j); }
#endif
-#ifdef _GLIBCXX_USE_LONG_LONG
- inline long long
- abs(long long __x) { return __builtin_llabs (__x); }
-#endif
-
-#if defined(__GLIBCXX_TYPE_INT_N_0)
- inline __GLIBCXX_TYPE_INT_N_0
- abs(__GLIBCXX_TYPE_INT_N_0 __x) { return __x >= 0 ? __x : -__x; }
-#endif
-#if defined(__GLIBCXX_TYPE_INT_N_1)
- inline __GLIBCXX_TYPE_INT_N_1
- abs(__GLIBCXX_TYPE_INT_N_1 __x) { return __x >= 0 ? __x : -__x; }
-#endif
-#if defined(__GLIBCXX_TYPE_INT_N_2)
- inline __GLIBCXX_TYPE_INT_N_2
- abs(__GLIBCXX_TYPE_INT_N_2 __x) { return __x >= 0 ? __x : -__x; }
-#endif
-#if defined(__GLIBCXX_TYPE_INT_N_3)
- inline __GLIBCXX_TYPE_INT_N_3
- abs(__GLIBCXX_TYPE_INT_N_3 __x) { return __x >= 0 ? __x : -__x; }
-#endif
-
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
diff --git a/libstdc++-v3/testsuite/26_numerics/headers/cmath/dr2192.cc b/libstdc++-v3/testsuite/26_numerics/headers/cmath/dr2192.cc
new file mode 100644
index 00000000000..b8d13cdfd70
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/headers/cmath/dr2192.cc
@@ -0,0 +1,39 @@
+// Copyright (C) 2016 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
+// .
+
+// { dg-do compile { target c++11 } }
+
+// NB: Don't include any other headers in this file.
+// LWG 2192 requires to declare overloads for integral types.
+#include
+
+template struct is_same { enum { value = 0 }; };
+template struct is_same { enum { value = 1 }; };
+
+template
+ constexpr bool check(T val) {
+ return is_same::value;
+ }
+
+// Unsigned arguments that promote to int are valid:
+static_assert( check(1), "abs((short)1) returns int" );
+static_assert( check(1),
+ "abs((unsigned short)1) returns int" );
+
+static_assert( check(1), "abs(1) returns int" );
+static_assert( check(1l), "abs(1l) returns long" );
+static_assert( check(1ll), "abs(1ll) returns long long" );
diff --git a/libstdc++-v3/testsuite/26_numerics/headers/cmath/dr2192_neg.cc b/libstdc++-v3/testsuite/26_numerics/headers/cmath/dr2192_neg.cc
new file mode 100644
index 00000000000..bda980a0eda
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/headers/cmath/dr2192_neg.cc
@@ -0,0 +1,29 @@
+// Copyright (C) 2016 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
+// .
+
+// { dg-do compile { target c++11 } }
+
+// NB: Don't include any other headers in this file.
+// LWG 2192 requires abs to be ill-formed for unsigned arguments.
+#include
+
+void test()
+{
+ std::abs(0u); // { dg-error "ambiguous" }
+ std::abs(0lu); // { dg-error "ambiguous" }
+ std::abs(0llu); // { dg-error "ambiguous" }
+}
diff --git a/libstdc++-v3/testsuite/26_numerics/headers/cstdlib/dr2192.cc b/libstdc++-v3/testsuite/26_numerics/headers/cstdlib/dr2192.cc
new file mode 100644
index 00000000000..312e907728c
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/headers/cstdlib/dr2192.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2016 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
+// .
+
+// { dg-do compile { target c++11 } }
+
+// NB: Don't include any other headers in this file.
+// LWG 2192 requires to declare overloads for floating point types.
+#include
+
+template struct is_same { enum { value = 0 }; };
+template struct is_same { enum { value = 1 }; };
+
+template
+ constexpr bool check(T val) {
+ return is_same::value;
+ }
+
+static_assert( check(1.f), "abs(1.f) returns float" );
+static_assert( check(1.), "abs(1.) returns double" );
+static_assert( check(1.l), "abs(1.l) returns long double" );
diff --git a/libstdc++-v3/testsuite/26_numerics/headers/cstdlib/dr2192_neg.cc b/libstdc++-v3/testsuite/26_numerics/headers/cstdlib/dr2192_neg.cc
new file mode 100644
index 00000000000..9f0046f93ca
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/headers/cstdlib/dr2192_neg.cc
@@ -0,0 +1,29 @@
+// Copyright (C) 2016 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
+// .
+
+// { dg-do compile { target c++11 } }
+
+// NB: Don't include any other headers in this file.
+// LWG 2192 requires abs to be ill-formed for unsigned arguments.
+#include
+
+void test()
+{
+ std::abs(0u); // { dg-error "ambiguous" }
+ std::abs(0lu); // { dg-error "ambiguous" }
+ std::abs(0llu); // { dg-error "ambiguous" }
+}