public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/114479] New: std::is_array_v<int[0]> changed from false to true in GCC 14
@ 2024-03-26 11:16 nikolasklauser at berlin dot de
  2024-03-26 11:42 ` [Bug c++/114479] [14 Regression] " pinskia at gcc dot gnu.org
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: nikolasklauser at berlin dot de @ 2024-03-26 11:16 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 114479
           Summary: std::is_array_v<int[0]> changed from false to true in
                    GCC 14
           Product: gcc
           Version: 14.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: nikolasklauser at berlin dot de
  Target Milestone: ---

```
#include <type_traits>

static_assert(!std::is_array_v<int[0]>);
```
works with GCC 13, but GCC 14 fails to compile. This is most likely caused by
the use of the new `__is_array` builtin. It probably has the same bug as Clang
(https://github.com/llvm/llvm-project/issues/54705).

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

* [Bug c++/114479] [14 Regression] std::is_array_v<int[0]> changed from false to true in GCC 14
  2024-03-26 11:16 [Bug c++/114479] New: std::is_array_v<int[0]> changed from false to true in GCC 14 nikolasklauser at berlin dot de
@ 2024-03-26 11:42 ` pinskia at gcc dot gnu.org
  2024-03-26 11:42 ` redi at gcc dot gnu.org
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: pinskia at gcc dot gnu.org @ 2024-03-26 11:42 UTC (permalink / raw)
  To: gcc-bugs

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

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |wrong-code
            Summary|std::is_array_v<int[0]>     |[14 Regression]
                   |changed from false to true  |std::is_array_v<int[0]>
                   |in GCC 14                   |changed from false to true
                   |                            |in GCC 14
   Target Milestone|---                         |14.0

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

* [Bug c++/114479] [14 Regression] std::is_array_v<int[0]> changed from false to true in GCC 14
  2024-03-26 11:16 [Bug c++/114479] New: std::is_array_v<int[0]> changed from false to true in GCC 14 nikolasklauser at berlin dot de
  2024-03-26 11:42 ` [Bug c++/114479] [14 Regression] " pinskia at gcc dot gnu.org
@ 2024-03-26 11:42 ` redi at gcc dot gnu.org
  2024-03-27  7:57 ` rguenth at gcc dot gnu.org
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: redi at gcc dot gnu.org @ 2024-03-26 11:42 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |kmatsui at gcc dot gnu.org
     Ever confirmed|0                           |1
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2024-03-26

--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Ha, this again. I first observed this in Feb 2022, before GCC's new behaviour.
The MSVC behaviour was because their compiler intercepts the std::is_array
trait and replaces it with a call to their __is_array intrinsic, which does
exactly what clang and gcc's __is_array does.

GCC should fix it too.

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

* [Bug c++/114479] [14 Regression] std::is_array_v<int[0]> changed from false to true in GCC 14
  2024-03-26 11:16 [Bug c++/114479] New: std::is_array_v<int[0]> changed from false to true in GCC 14 nikolasklauser at berlin dot de
  2024-03-26 11:42 ` [Bug c++/114479] [14 Regression] " pinskia at gcc dot gnu.org
  2024-03-26 11:42 ` redi at gcc dot gnu.org
@ 2024-03-27  7:57 ` rguenth at gcc dot gnu.org
  2024-03-29 15:56 ` mpolacek at gcc dot gnu.org
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: rguenth at gcc dot gnu.org @ 2024-03-27  7:57 UTC (permalink / raw)
  To: gcc-bugs

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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P3                          |P1

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

* [Bug c++/114479] [14 Regression] std::is_array_v<int[0]> changed from false to true in GCC 14
  2024-03-26 11:16 [Bug c++/114479] New: std::is_array_v<int[0]> changed from false to true in GCC 14 nikolasklauser at berlin dot de
                   ` (2 preceding siblings ...)
  2024-03-27  7:57 ` rguenth at gcc dot gnu.org
@ 2024-03-29 15:56 ` mpolacek at gcc dot gnu.org
  2024-03-31 10:05 ` redi at gcc dot gnu.org
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: mpolacek at gcc dot gnu.org @ 2024-03-29 15:56 UTC (permalink / raw)
  To: gcc-bugs

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

Marek Polacek <mpolacek at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |mpolacek at gcc dot gnu.org

--- Comment #2 from Marek Polacek <mpolacek at gcc dot gnu.org> ---
I think the patch is simply

--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12439,7 +12439,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree
type2)
       return CP_AGGREGATE_TYPE_P (type1);

     case CPTK_IS_ARRAY:
-      return type_code1 == ARRAY_TYPE;
+      return (type_code1 == ARRAY_TYPE
+         /* ??? We don't want to report T[0] as being an array type.  */
+         && !(TYPE_SIZE (type1) && integer_zerop (TYPE_SIZE (type1))));

     case CPTK_IS_ASSIGNABLE:
       return is_xible (MODIFY_EXPR, type1, type2);

but are we *sure* that we don't want to treat int[0] as an array type?  It's
not clear to me that https://github.com/llvm/llvm-project/pull/86652 reached a
consensus.

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

* [Bug c++/114479] [14 Regression] std::is_array_v<int[0]> changed from false to true in GCC 14
  2024-03-26 11:16 [Bug c++/114479] New: std::is_array_v<int[0]> changed from false to true in GCC 14 nikolasklauser at berlin dot de
                   ` (3 preceding siblings ...)
  2024-03-29 15:56 ` mpolacek at gcc dot gnu.org
@ 2024-03-31 10:05 ` redi at gcc dot gnu.org
  2024-04-01 14:28 ` mpolacek at gcc dot gnu.org
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: redi at gcc dot gnu.org @ 2024-03-31 10:05 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> ---
[dcl.array] says that for T[N] the value "N specifies the array bound, i.e.,
the
number of elements in the array; N shall be greater than zero."

So T[0] is not a valid array type. And std::is_array<T[0]> has never been true
for any traditional implementation based on partial specialization of class
templates, only when switching to an intrinsic __is_array that fails to
accurately give the same behaviour as the std::is_array trait.

Since the purpose of the __is_array intrinsic is to optimize the std::is_array
trait, it should have the same behaviour. For the optimization to change the
behaviour of the trait seems like the tail wagging the dog.

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

* [Bug c++/114479] [14 Regression] std::is_array_v<int[0]> changed from false to true in GCC 14
  2024-03-26 11:16 [Bug c++/114479] New: std::is_array_v<int[0]> changed from false to true in GCC 14 nikolasklauser at berlin dot de
                   ` (4 preceding siblings ...)
  2024-03-31 10:05 ` redi at gcc dot gnu.org
@ 2024-04-01 14:28 ` mpolacek at gcc dot gnu.org
  2024-04-01 15:25 ` arthur.j.odwyer at gmail dot com
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: mpolacek at gcc dot gnu.org @ 2024-04-01 14:28 UTC (permalink / raw)
  To: gcc-bugs

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

Marek Polacek <mpolacek at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Assignee|unassigned at gcc dot gnu.org      |mpolacek at gcc dot gnu.org
             Status|NEW                         |ASSIGNED

--- Comment #4 from Marek Polacek <mpolacek at gcc dot gnu.org> ---
Thanks.  I'll go ahead and submit my patch.

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

* [Bug c++/114479] [14 Regression] std::is_array_v<int[0]> changed from false to true in GCC 14
  2024-03-26 11:16 [Bug c++/114479] New: std::is_array_v<int[0]> changed from false to true in GCC 14 nikolasklauser at berlin dot de
                   ` (5 preceding siblings ...)
  2024-04-01 14:28 ` mpolacek at gcc dot gnu.org
@ 2024-04-01 15:25 ` arthur.j.odwyer at gmail dot com
  2024-04-02 18:34 ` cvs-commit at gcc dot gnu.org
  2024-04-02 18:35 ` mpolacek at gcc dot gnu.org
  8 siblings, 0 replies; 10+ messages in thread
From: arthur.j.odwyer at gmail dot com @ 2024-04-01 15:25 UTC (permalink / raw)
  To: gcc-bugs

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

Arthur O'Dwyer <arthur.j.odwyer at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |arthur.j.odwyer at gmail dot com

--- Comment #5 from Arthur O'Dwyer <arthur.j.odwyer at gmail dot com> ---
IIUC, the logic here goes as follows:

(1) Everyone's compiler extension currently makes this assertion fail, not
succeed:

  #include <type_traits>
  template<class T> struct is_array : std::false_type {};
  template<class T> struct is_array<T[]> : std::true_type {};
  template<class T, std::size_t N> struct is_array<T[N]> : std::true_type {};
  static_assert(is_array<int[0]>::value, "this assert fails");

(2) Everyone's library is expected to implement `std::is_array` as the moral
equivalent of the partial specializations in (1). No reasonable library would
ever do anything else.

(3) Therefore, everyone's library will claim that int[0] is not an array type:
  static_assert(std::is_array<int[0]>::value, "this assert fails");

(4) The __is_array builtin is provided specifically to speed up std::is_array
(and for no other reason). Therefore, it should give the same answer as (3).
Therefore, __is_array(int[0]) should also report false:
  static_assert(__is_array(int[0]), "this assert fails");

This logic doesn't depend on any abstract reasoning about whether int[0] is
really "an array type" (I think it certainly *is* an array type, FWIW); it
simply depends on observing the extension's behavior in (1) -- and then *not*
claiming that that's a bug we need to fix. If the extension's behavior is
"correct" (i.e. we're not going to change it), then the behavior of
__is_array(T[0]) falls naturally out of that.

Personally, if I were designing the extension today, I would certainly make
T[0] match the partial specialization for T[N] (with N=0). This seems like it
would match users' expectations, and it doesn't seem to break any code that
wasn't already trying to use the extension, except for pathological party
tricks like being able to obfuscate the condition (N >= 1) as
(std::is_array_v<int[N]>). However, *if* the extension's behavior (1) is set in
stone, *then* conclusion (4) follows inexorably.

And since both (1) and (4) are core-language compiler issues, libstdc++ isn't
involved here: it's simply a bug for GCC to provide
partial-specialization-matching behavior as in (1) without also providing
__is_array behavior as in (4).

HOWEVER, here's a big question which I believe Aaron Ballman also raised on
llvm-project#54705: If it's not an array type, then where do we get off calling
it a compound type ( https://eel.is/c++draft/basic#compound-1 ), a literal type
( https://eel.is/c++draft/basic#types.general-10 ), an aggregate (
https://eel.is/c++draft/dcl.init.aggr#1 ), etc?

It certainly would be *simpler* -- if a big upheaval -- for GCC to provide
neither (1) nor (4), i.e. change the specialization-matching behavior to match
__is_array rather than the other way around. Then all the traits would give
consistent answers: int[0] would be a compound type, a literal type, and an
aggregate *because* it was an array type.

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

* [Bug c++/114479] [14 Regression] std::is_array_v<int[0]> changed from false to true in GCC 14
  2024-03-26 11:16 [Bug c++/114479] New: std::is_array_v<int[0]> changed from false to true in GCC 14 nikolasklauser at berlin dot de
                   ` (6 preceding siblings ...)
  2024-04-01 15:25 ` arthur.j.odwyer at gmail dot com
@ 2024-04-02 18:34 ` cvs-commit at gcc dot gnu.org
  2024-04-02 18:35 ` mpolacek at gcc dot gnu.org
  8 siblings, 0 replies; 10+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2024-04-02 18:34 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #6 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The trunk branch has been updated by Marek Polacek <mpolacek@gcc.gnu.org>:

https://gcc.gnu.org/g:2f2924078ce51c2a0da3ad8f958f2d1de533969a

commit r14-9759-g2f2924078ce51c2a0da3ad8f958f2d1de533969a
Author: Marek Polacek <polacek@redhat.com>
Date:   Mon Apr 1 12:55:46 2024 -0400

    c++: make __is_array return false for T[0] [PR114479]

    When we switched to using the __is_array built-in trait to implement
    std::is_array in r14-6623-g7fd9c349e45534, we started saying that
    T[0] is an array.  There are various opinions as to whether that is
    the best answer, but it seems prudent to keep the GCC 13 result.

            PR c++/114479

    gcc/cp/ChangeLog:

            * semantics.cc (trait_expr_value) <case CPTK_IS_ARRAY>: Return
false
            for zero-sized arrays.

    gcc/testsuite/ChangeLog:

            * g++.dg/ext/is_array.C: Extend.

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

* [Bug c++/114479] [14 Regression] std::is_array_v<int[0]> changed from false to true in GCC 14
  2024-03-26 11:16 [Bug c++/114479] New: std::is_array_v<int[0]> changed from false to true in GCC 14 nikolasklauser at berlin dot de
                   ` (7 preceding siblings ...)
  2024-04-02 18:34 ` cvs-commit at gcc dot gnu.org
@ 2024-04-02 18:35 ` mpolacek at gcc dot gnu.org
  8 siblings, 0 replies; 10+ messages in thread
From: mpolacek at gcc dot gnu.org @ 2024-04-02 18:35 UTC (permalink / raw)
  To: gcc-bugs

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

Marek Polacek <mpolacek at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|ASSIGNED                    |RESOLVED
         Resolution|---                         |FIXED

--- Comment #7 from Marek Polacek <mpolacek at gcc dot gnu.org> ---
Fixed.

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

end of thread, other threads:[~2024-04-02 18:35 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-03-26 11:16 [Bug c++/114479] New: std::is_array_v<int[0]> changed from false to true in GCC 14 nikolasklauser at berlin dot de
2024-03-26 11:42 ` [Bug c++/114479] [14 Regression] " pinskia at gcc dot gnu.org
2024-03-26 11:42 ` redi at gcc dot gnu.org
2024-03-27  7:57 ` rguenth at gcc dot gnu.org
2024-03-29 15:56 ` mpolacek at gcc dot gnu.org
2024-03-31 10:05 ` redi at gcc dot gnu.org
2024-04-01 14:28 ` mpolacek at gcc dot gnu.org
2024-04-01 15:25 ` arthur.j.odwyer at gmail dot com
2024-04-02 18:34 ` cvs-commit at gcc dot gnu.org
2024-04-02 18:35 ` mpolacek 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).