public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug libstdc++/96710] New: __int128 vs <type_traits>
@ 2020-08-19 15:08 redi at gcc dot gnu.org
  2020-12-10 15:30 ` [Bug libstdc++/96710] " redi at gcc dot gnu.org
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: redi at gcc dot gnu.org @ 2020-08-19 15:08 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96710

            Bug ID: 96710
           Summary: __int128 vs <type_traits>
           Product: gcc
           Version: 11.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: redi at gcc dot gnu.org
  Target Milestone: ---

In strict modes (e.g. -std=c++17) the __int128 type does not belong to any of
the standard type categories, because is_integer<__int128> is false, which
means is_arithmetic<__int128> is false.

Our definitions of is_scalar depends on is_arithmetic, so is_scalar<__int128>
is false, and therefore is_object<__int128> is false. This is clearly nonsense.

We should fix this, so that even when is_integer<__int128> is false, we can
still give sensible answers for __int128 that do not (unsucessfully) try to
deny its existence.

Of course the ideal would be for WG14 to accept
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2425.pdf and then we can just
say is_integer<__int128> is true even in strict modes and everybody rejoices.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Bug libstdc++/96710] __int128 vs <type_traits>
  2020-08-19 15:08 [Bug libstdc++/96710] New: __int128 vs <type_traits> redi at gcc dot gnu.org
@ 2020-12-10 15:30 ` redi at gcc dot gnu.org
  2022-05-18 12:42 ` redi at gcc dot gnu.org
  2024-02-06 11:12 ` redi at gcc dot gnu.org
  2 siblings, 0 replies; 4+ messages in thread
From: redi at gcc dot gnu.org @ 2020-12-10 15:30 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96710

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2020-12-10
     Ever confirmed|0                           |1

--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> ---
I would like is_scalar to be true for all scalar types such as __int20 and
__float128, irrespective of whether is_integer or is_floating_point is true.
They're certainly not class types, nor pointers, so they have to fit somewhere
in the type system.

A related issue is that on msp430 std::incrementable<__int20> is false for
strict mode. Ideally all the INT_N extension types would satisfy that, maybe
via something like:

--- a/libstdc++-v3/include/bits/iterator_concepts.h
+++ b/libstdc++-v3/include/bits/iterator_concepts.h
@@ -173,15 +173,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        = make_signed_t<decltype(std::declval<_Tp>() - std::declval<_Tp>())>;
     };

-#if defined __STRICT_ANSI__ && defined __SIZEOF_INT128__
-  // __int128 is incrementable even if !integral<__int128>
-  template<>
-    struct incrementable_traits<__int128>
-    { using difference_type = __int128; };
-
-  template<>
-    struct incrementable_traits<unsigned __int128>
-    { using difference_type = __int128; };
+#ifdef __STRICT_ANSI__
+  // Types like __int128 are incrementable even if integral<__int128> is
false.
+  // In non-strict modes they match the partial specialization above,
+  // but in strict modes we need this one so they satisfy std::incrementable.
+  template<typename _Tp>
+    requires (__gnu_cxx::__is_integer_nonstrict<_Tp>::__value
+             != std::__is_integer<_Tp>::__value)
+    struct incrementable_traits<_Tp>
+    { using difference_type = make_signed_t<Tp>; };
 #endif

   namespace __detail
@@ -556,40 +556,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     class __max_diff_type;
     class __max_size_type;

-    template<typename _Tp>
-      concept __is_signed_int128
-#if __SIZEOF_INT128__
-       = same_as<_Tp, __int128>;
-#else
-       = false;
-#endif
-
-    template<typename _Tp>
-      concept __is_unsigned_int128
-#if __SIZEOF_INT128__
-       = same_as<_Tp, unsigned __int128>;
-#else
-       = false;
-#endif
-
     template<typename _Tp>
       concept __cv_bool = same_as<const volatile _Tp, const volatile bool>;

     template<typename _Tp>
-      concept __integral_nonbool = integral<_Tp> && !__cv_bool<_Tp>;
-
-    template<typename _Tp>
-      concept __is_int128 = __is_signed_int128<_Tp> ||
__is_unsigned_int128<_Tp>;
+      concept __integral_nonbool
+       = __gnu_cxx::__is_integer_nonstrict_v<_Tp> && !__cv_bool<_Tp>;

     template<typename _Tp>
       concept __is_integer_like = __integral_nonbool<_Tp>
-       || __is_int128<_Tp>
        || same_as<_Tp, __max_diff_type> || same_as<_Tp, __max_size_type>;

     template<typename _Tp>
-      concept __is_signed_integer_like = signed_integral<_Tp>
-       || __is_signed_int128<_Tp>
-       || same_as<_Tp, __max_diff_type>;
+      concept __is_signed_integer_like
+       = (__gnu_cxx::__is_integer_nonstrict_v<_Tp>
+           && bool(__gnu_cxx::__int_traits<_Tp>::__is_signed))
+         || same_as<_Tp, __max_diff_type>;

   } // namespace ranges::__detail

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Bug libstdc++/96710] __int128 vs <type_traits>
  2020-08-19 15:08 [Bug libstdc++/96710] New: __int128 vs <type_traits> redi at gcc dot gnu.org
  2020-12-10 15:30 ` [Bug libstdc++/96710] " redi at gcc dot gnu.org
@ 2022-05-18 12:42 ` redi at gcc dot gnu.org
  2024-02-06 11:12 ` redi at gcc dot gnu.org
  2 siblings, 0 replies; 4+ messages in thread
From: redi at gcc dot gnu.org @ 2022-05-18 12:42 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96710

--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Jonathan Wakely from comment #0)
> Our definitions of is_scalar depends on is_arithmetic, so
> is_scalar<__int128> is false, and therefore is_object<__int128> is false.
> This is clearly nonsense.

Hmm, what I wrote is nonsense. Our is_object does not depend on is_scalar:

  /// is_object
  template<typename _Tp>
    struct is_object
    : public __not_<__or_<is_function<_Tp>, is_reference<_Tp>,
                          is_void<_Tp>>>::type
    { };

So is_object<__int128> is always true.

But is_scalar<__int128> still depends on __STRICT_ANSI__ which seems wrong.
It's not a compound type, so it's scalar.


Currently we define is_scalar as:

  template<typename _Tp>
    struct is_scalar
    : public __or_<is_arithmetic<_Tp>, is_enum<_Tp>, is_pointer<_Tp>,
                   is_member_pointer<_Tp>, is_null_pointer<_Tp>>::type
    { };

I think a better definition would be:

  template<typename _Tp>
    struct is_scalar
    : public __and_<is_object<_Tp>, __not_<is_array<_Tp>>,
                                    __not_<is_class<_Tp>>,
                                    __not_<is_union<_Tp>>>
    { };

Which could be optimized using partial specializations for the array cases:

  template<typename _Tp>
    struct is_scalar
    : public __and_<is_object<_Tp>, __not_<is_class<_Tp>>,
                                    __not_<is_union<_Tp>>>
    { };

  template<typename _Tp>
    struct is_scalar<_Tp[]>
    : public false_type
    { };

  template<typename _Tp, size_t _Num>
    struct is_scalar<_Tp[_Num]>
    : public false_type
    { };

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Bug libstdc++/96710] __int128 vs <type_traits>
  2020-08-19 15:08 [Bug libstdc++/96710] New: __int128 vs <type_traits> redi at gcc dot gnu.org
  2020-12-10 15:30 ` [Bug libstdc++/96710] " redi at gcc dot gnu.org
  2022-05-18 12:42 ` redi at gcc dot gnu.org
@ 2024-02-06 11:12 ` redi at gcc dot gnu.org
  2 siblings, 0 replies; 4+ messages in thread
From: redi at gcc dot gnu.org @ 2024-02-06 11:12 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96710

--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Jonathan Wakely from comment #0)
> Of course the ideal would be for WG14 to accept
> http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2425.pdf and then we can
> just say is_integer<__int128> is true even in strict modes and everybody
> rejoices.

We can do that now.

We need to audit all the places that need changes to support __int128 as an
extended integer type.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2024-02-06 11:12 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-19 15:08 [Bug libstdc++/96710] New: __int128 vs <type_traits> redi at gcc dot gnu.org
2020-12-10 15:30 ` [Bug libstdc++/96710] " redi at gcc dot gnu.org
2022-05-18 12:42 ` redi at gcc dot gnu.org
2024-02-06 11:12 ` redi at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).