[clang] [Clang] Fix __is_array returning true for zero-sized arrays (PR #86652)

2024-05-20 Thread Nikolas Klauser via cfe-commits

https://github.com/philnik777 closed 
https://github.com/llvm/llvm-project/pull/86652
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Fix __is_array returning true for zero-sized arrays (PR #86652)

2024-05-18 Thread Nikolas Klauser via cfe-commits

https://github.com/philnik777 updated 
https://github.com/llvm/llvm-project/pull/86652

>From 90f88bdac3dc40635c58f3f67e29354e6a32896e Mon Sep 17 00:00:00 2001
From: Nikolas Klauser 
Date: Tue, 26 Mar 2024 12:23:24 +0100
Subject: [PATCH] [Clang] Fix __is_array returning true for zero-sized arrays

---
 clang/docs/ReleaseNotes.rst| 2 ++
 clang/lib/Sema/SemaExprCXX.cpp | 4 
 clang/test/SemaCXX/type-traits.cpp | 4 +++-
 3 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 7fbe2fec6ca06..e668202853710 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -345,6 +345,8 @@ Bug Fixes in This Version
 - Fixes an assertion failure on invalid code when trying to define member
   functions in lambdas.
 
+- ``__is_array`` no longer returns ``true`` for zero-sized arrays. Fixes 
(#GH54705).
+
 Bug Fixes to Compiler Builtins
 ^^
 
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index c34a40fa7c81a..93d2b4b259fbc 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -5143,6 +5143,10 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait 
UTT,
   case UTT_IsFloatingPoint:
 return T->isFloatingType();
   case UTT_IsArray:
+// zero-sized arrays aren't considered arrays in partial specializations,
+// so __is_array shouldn't consider them arrays either.
+if (const auto* CAT = C.getAsConstantArrayType(T))
+  return CAT->getSize() != 0;
 return T->isArrayType();
   case UTT_IsBoundedArray:
 if (!T->isVariableArrayType()) {
diff --git a/clang/test/SemaCXX/type-traits.cpp 
b/clang/test/SemaCXX/type-traits.cpp
index 14ec17989ec7c..49df4b668513c 100644
--- a/clang/test/SemaCXX/type-traits.cpp
+++ b/clang/test/SemaCXX/type-traits.cpp
@@ -25,6 +25,7 @@ typedef Empty EmptyArMB[1][2];
 typedef int Int;
 typedef Int IntAr[10];
 typedef Int IntArNB[];
+typedef Int IntArZero[0];
 class Statics { static int priv; static NonPOD np; };
 union EmptyUnion {};
 union IncompleteUnion; // expected-note {{forward declaration of 
'IncompleteUnion'}}
@@ -685,6 +686,7 @@ void is_array()
 {
   static_assert(__is_array(IntAr));
   static_assert(__is_array(IntArNB));
+  static_assert(!__is_array(IntArZero));
   static_assert(__is_array(UnionAr));
 
   static_assert(!__is_array(void));
@@ -1804,7 +1806,7 @@ void is_layout_compatible(int n)
   static_assert(!__is_layout_compatible(EnumForward, int));
   static_assert(!__is_layout_compatible(EnumClassForward, int));
   // FIXME: the following should be rejected (array of unknown bound and void 
are the only allowed incomplete types)
-  static_assert(__is_layout_compatible(CStructIncomplete, CStructIncomplete)); 
+  static_assert(__is_layout_compatible(CStructIncomplete, CStructIncomplete));
   static_assert(!__is_layout_compatible(CStruct, CStructIncomplete));
   static_assert(__is_layout_compatible(CStructIncomplete[2], 
CStructIncomplete[2]));
 }

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Fix __is_array returning true for zero-sized arrays (PR #86652)

2024-05-18 Thread Nikolas Klauser via cfe-commits

https://github.com/philnik777 updated 
https://github.com/llvm/llvm-project/pull/86652

>From 90f88bdac3dc40635c58f3f67e29354e6a32896e Mon Sep 17 00:00:00 2001
From: Nikolas Klauser 
Date: Tue, 26 Mar 2024 12:23:24 +0100
Subject: [PATCH] [Clang] Fix __is_array returning true for zero-sized arrays

---
 clang/docs/ReleaseNotes.rst| 2 ++
 clang/lib/Sema/SemaExprCXX.cpp | 4 
 clang/test/SemaCXX/type-traits.cpp | 4 +++-
 3 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 7fbe2fec6ca06..e668202853710 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -345,6 +345,8 @@ Bug Fixes in This Version
 - Fixes an assertion failure on invalid code when trying to define member
   functions in lambdas.
 
+- ``__is_array`` no longer returns ``true`` for zero-sized arrays. Fixes 
(#GH54705).
+
 Bug Fixes to Compiler Builtins
 ^^
 
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index c34a40fa7c81a..93d2b4b259fbc 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -5143,6 +5143,10 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait 
UTT,
   case UTT_IsFloatingPoint:
 return T->isFloatingType();
   case UTT_IsArray:
+// zero-sized arrays aren't considered arrays in partial specializations,
+// so __is_array shouldn't consider them arrays either.
+if (const auto* CAT = C.getAsConstantArrayType(T))
+  return CAT->getSize() != 0;
 return T->isArrayType();
   case UTT_IsBoundedArray:
 if (!T->isVariableArrayType()) {
diff --git a/clang/test/SemaCXX/type-traits.cpp 
b/clang/test/SemaCXX/type-traits.cpp
index 14ec17989ec7c..49df4b668513c 100644
--- a/clang/test/SemaCXX/type-traits.cpp
+++ b/clang/test/SemaCXX/type-traits.cpp
@@ -25,6 +25,7 @@ typedef Empty EmptyArMB[1][2];
 typedef int Int;
 typedef Int IntAr[10];
 typedef Int IntArNB[];
+typedef Int IntArZero[0];
 class Statics { static int priv; static NonPOD np; };
 union EmptyUnion {};
 union IncompleteUnion; // expected-note {{forward declaration of 
'IncompleteUnion'}}
@@ -685,6 +686,7 @@ void is_array()
 {
   static_assert(__is_array(IntAr));
   static_assert(__is_array(IntArNB));
+  static_assert(!__is_array(IntArZero));
   static_assert(__is_array(UnionAr));
 
   static_assert(!__is_array(void));
@@ -1804,7 +1806,7 @@ void is_layout_compatible(int n)
   static_assert(!__is_layout_compatible(EnumForward, int));
   static_assert(!__is_layout_compatible(EnumClassForward, int));
   // FIXME: the following should be rejected (array of unknown bound and void 
are the only allowed incomplete types)
-  static_assert(__is_layout_compatible(CStructIncomplete, CStructIncomplete)); 
+  static_assert(__is_layout_compatible(CStructIncomplete, CStructIncomplete));
   static_assert(!__is_layout_compatible(CStruct, CStructIncomplete));
   static_assert(__is_layout_compatible(CStructIncomplete[2], 
CStructIncomplete[2]));
 }

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Fix __is_array returning true for zero-sized arrays (PR #86652)

2024-05-18 Thread Nikolas Klauser via cfe-commits

https://github.com/philnik777 updated 
https://github.com/llvm/llvm-project/pull/86652

>From 90f88bdac3dc40635c58f3f67e29354e6a32896e Mon Sep 17 00:00:00 2001
From: Nikolas Klauser 
Date: Tue, 26 Mar 2024 12:23:24 +0100
Subject: [PATCH] [Clang] Fix __is_array returning true for zero-sized arrays

---
 clang/docs/ReleaseNotes.rst| 2 ++
 clang/lib/Sema/SemaExprCXX.cpp | 4 
 clang/test/SemaCXX/type-traits.cpp | 4 +++-
 3 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 7fbe2fec6ca06..e668202853710 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -345,6 +345,8 @@ Bug Fixes in This Version
 - Fixes an assertion failure on invalid code when trying to define member
   functions in lambdas.
 
+- ``__is_array`` no longer returns ``true`` for zero-sized arrays. Fixes 
(#GH54705).
+
 Bug Fixes to Compiler Builtins
 ^^
 
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index c34a40fa7c81a..93d2b4b259fbc 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -5143,6 +5143,10 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait 
UTT,
   case UTT_IsFloatingPoint:
 return T->isFloatingType();
   case UTT_IsArray:
+// zero-sized arrays aren't considered arrays in partial specializations,
+// so __is_array shouldn't consider them arrays either.
+if (const auto* CAT = C.getAsConstantArrayType(T))
+  return CAT->getSize() != 0;
 return T->isArrayType();
   case UTT_IsBoundedArray:
 if (!T->isVariableArrayType()) {
diff --git a/clang/test/SemaCXX/type-traits.cpp 
b/clang/test/SemaCXX/type-traits.cpp
index 14ec17989ec7c..49df4b668513c 100644
--- a/clang/test/SemaCXX/type-traits.cpp
+++ b/clang/test/SemaCXX/type-traits.cpp
@@ -25,6 +25,7 @@ typedef Empty EmptyArMB[1][2];
 typedef int Int;
 typedef Int IntAr[10];
 typedef Int IntArNB[];
+typedef Int IntArZero[0];
 class Statics { static int priv; static NonPOD np; };
 union EmptyUnion {};
 union IncompleteUnion; // expected-note {{forward declaration of 
'IncompleteUnion'}}
@@ -685,6 +686,7 @@ void is_array()
 {
   static_assert(__is_array(IntAr));
   static_assert(__is_array(IntArNB));
+  static_assert(!__is_array(IntArZero));
   static_assert(__is_array(UnionAr));
 
   static_assert(!__is_array(void));
@@ -1804,7 +1806,7 @@ void is_layout_compatible(int n)
   static_assert(!__is_layout_compatible(EnumForward, int));
   static_assert(!__is_layout_compatible(EnumClassForward, int));
   // FIXME: the following should be rejected (array of unknown bound and void 
are the only allowed incomplete types)
-  static_assert(__is_layout_compatible(CStructIncomplete, CStructIncomplete)); 
+  static_assert(__is_layout_compatible(CStructIncomplete, CStructIncomplete));
   static_assert(!__is_layout_compatible(CStruct, CStructIncomplete));
   static_assert(__is_layout_compatible(CStructIncomplete[2], 
CStructIncomplete[2]));
 }

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Fix __is_array returning true for zero-sized arrays (PR #86652)

2024-05-15 Thread Aaron Ballman via cfe-commits


@@ -5143,6 +5143,10 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait 
UTT,
   case UTT_IsFloatingPoint:
 return T->isFloatingType();
   case UTT_IsArray:
+// zero-sized arrays aren't considered arrays in partial specializations,

AaronBallman wrote:

```suggestion
// Zero-sized arrays aren't considered arrays in partial specializations,
```

https://github.com/llvm/llvm-project/pull/86652
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Fix __is_array returning true for zero-sized arrays (PR #86652)

2024-05-15 Thread Aaron Ballman via cfe-commits


@@ -5143,6 +5143,10 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait 
UTT,
   case UTT_IsFloatingPoint:
 return T->isFloatingType();
   case UTT_IsArray:
+// zero-sized arrays aren't considered arrays in partial specializations,
+// so __is_array shouldn't consider them arrays either.
+if (const auto* CAT = C.getAsConstantArrayType(T))

AaronBallman wrote:

```suggestion
if (const auto *CAT = C.getAsConstantArrayType(T))
```

https://github.com/llvm/llvm-project/pull/86652
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Fix __is_array returning true for zero-sized arrays (PR #86652)

2024-05-15 Thread Aaron Ballman via cfe-commits

https://github.com/AaronBallman edited 
https://github.com/llvm/llvm-project/pull/86652
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Fix __is_array returning true for zero-sized arrays (PR #86652)

2024-05-15 Thread Aaron Ballman via cfe-commits

https://github.com/AaronBallman approved this pull request.

Realistically, I don't think we can deprecate the extension in general:
https://sourcegraph.com/search?q=context:global+%5BA-Za-z0-9_%5D%2B%5Cs%5BA-Za-z0-9_%5D%2B%5C%5B0%5C%5D%3B+-file:.*test.*+-file:.*clang.*+count:10&patternType=regexp&sm=0

I don't think we can even deprecate it for just C++:
https://sourcegraph.com/search?q=context:global+%5BA-Za-z0-9_%5D%2B%5Cs%5BA-Za-z0-9_%5D%2B%5C%5B0%5C%5D%3B+-file:.*test.*+-file:.*clang.*+count:10+lang:C%2B%2B+&patternType=regexp&sm=0

but we might be able to deprecate it for uses where the zero-sized array is not 
the last member of a structure declaration:
https://sourcegraph.com/search?q=context:global+%5BA-Za-z0-9_%5D%2B%5Cs%5BA-Za-z0-9_%5D%2B%5C%5B0%5C%5D%3B%5Cs*%5BA-Za-z_%5D+-file:.*test.*+-file:.*clang.*+lang:C+count:10&patternType=regexp&sm=0
 (has a lot of false positives like `sizeof foo[0];` and `return foo[0];`)

I think we should consider deprecation orthogonal to this patch though.

There does not seem to be evidence that this is being used for anything other 
than implementing traits: 
https://sourcegraph.com/search?q=context:global+__is_array%5Cb+lang:C%2B%2B+-file:.*test.*+-file:.*clang.*+-file:.*libcxx.*+-file:.*libc%5C%2B%5C%2B.*+-file:.*trait.*+-repo:.*clang.*&patternType=regexp&sm=0

so I think the patch is "correct" insofar as this terrible extension is 
concerned. Some small nits with the changes, but otherwise LGTM.

https://github.com/llvm/llvm-project/pull/86652
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Fix __is_array returning true for zero-sized arrays (PR #86652)

2024-05-13 Thread via cfe-commits

cor3ntin wrote:

My 0 cents:

- I think deprecating the extension make sense
- In the meantime I think the builtin exists to support the library so the 
patch make sense as is (otherwise we have to prove it is used for something 
else). 

My understanding is that "0-length arrays" are mostly an unfortunate attempt at 
a flexible-member-arrays with sharper edges, so their support in the context of 
c++ type trait doesn't really make sense.

https://github.com/llvm/llvm-project/pull/86652
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Fix __is_array returning true for zero-sized arrays (PR #86652)

2024-05-11 Thread Nikolas Klauser via cfe-commits

philnik777 wrote:

@AaronBallman Any thoughts on how we should proceed here?


https://github.com/llvm/llvm-project/pull/86652
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Fix __is_array returning true for zero-sized arrays (PR #86652)

2024-04-01 Thread Nikolas Klauser via cfe-commits

philnik777 wrote:

I'd personally be fine with deprecating it. As I said above, we use it in 
libc++ for padding inside `string` like
```c++
struct short_string {
  ;
  char padding[sizeof(value_type) - 1];
  ;
};
```
That could be refactored relatively easily as
```c++
template 
struct padding_t {
  char data[Size];
};

template <>
struct padding_t<0> {};

struct short_string {
  ;
  [[no_unique_address]] padding_t padding;
  ;
};

```
so I don't think that's a use-case worth keeping the extension for.

https://github.com/llvm/llvm-project/pull/86652
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Fix __is_array returning true for zero-sized arrays (PR #86652)

2024-04-01 Thread Aaron Ballman via cfe-commits

AaronBallman wrote:

> Last time I checked, neither GCC nor Clang allowed T[0] to match a partial 
> specialization for `is_array` so the extension isn't very well extended 
> :)

Oh, I agree, I am learning to loathe this extension the more I look into this. 
Did you see this lovely bit:

> Oh wow, and it gets even more surprising... adding a zero-length array to a 
> structure reduces the size of the structure (in C++): 
> https://godbolt.org/z/5E4YsT1Ye

But that's why I'm asking questions about what we *should* be doing with the 
feature overall. As it currently stands, this extension seems like it is broken 
in C++ in multiple ways. Fixing a tiny corner of it is fine, but I'd like to 
know what the overall big picture is so we can know whether the tiny corner 
changes fit or not. We could fix this by changing partial specializations to 
care about zero-sized arrays, too. (Personally, I would love to "fix" this by 
deprecating the extension as the only justification for it I've been able to 
dig up is as a hack for flexible arrays -- deprecating this extension outside 
of GNU89 mode has some appeal, barring other information about its value.)

https://github.com/llvm/llvm-project/pull/86652
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Fix __is_array returning true for zero-sized arrays (PR #86652)

2024-04-01 Thread Jonathan Wakely via cfe-commits

jwakely wrote:

Last time I checked, neither GCC nor Clang allowed T[0] to match a partial 
specialization for `is_array` so the extension isn't very well extended :)

https://github.com/llvm/llvm-project/pull/86652
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Fix __is_array returning true for zero-sized arrays (PR #86652)

2024-04-01 Thread Aaron Ballman via cfe-commits

AaronBallman wrote:

> As I've just commented at https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114479 
> the `__is_array` intrinsic exists to optimize `std::is_array` and so should 
> match its existing behaviour. If you want to change the behaviour of 
> `std::is_array` then please do so via an LWG issue, e.g. requesting 
> clarification of the behaviour for `T[0]`.
> 
> An optimization to speed up compilation of `std::is_array` should not dictate 
> its behaviour.

Errr, I think there's some circular logic here perhaps:

> [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.

Except `T[0]` is a valid array type because it's supported as a language 
extension in Clang and GCC; that's the whole reason you can spell `T[0]` at all.

This boils down to a fundamental question: what makes something an array type 
in the first place? Is it the declaration syntax or is it the semantics? If 
it's declaration syntax, then `T[0]` is clearly an array type. If it's 
semantics, then `T[0]` is not an array type but `std::vector` is. 
Personally, I think the declaration syntax is what makes something an array 
type per https://eel.is/c++draft/dcl.array#1 saying "a declaration of the 
form". Yes, it says the size shall not be zero, but that's the bit we've 
extended, so it's circular to say "the standard says zero isn't allowed and 
therefore the library behavior is to return false from std::is_array".

So I think I'm arguing for an LWG issue.

https://github.com/llvm/llvm-project/pull/86652
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Fix __is_array returning true for zero-sized arrays (PR #86652)

2024-03-31 Thread Jonathan Wakely via cfe-commits

jwakely wrote:

As I've just commented at https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114479 
the `__is_array` intrinsic exists to optimize `std::is_array` and so should 
match its existing behaviour. If you want to change the behaviour of 
`std::is_array` then please do so via an LWG issue, e.g. requesting 
clarification of the behaviour for `T[0]`.

An optimization to speed up compilation of `std::is_array` should not dictate 
its behaviour.


https://github.com/llvm/llvm-project/pull/86652
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Fix __is_array returning true for zero-sized arrays (PR #86652)

2024-03-31 Thread Jonathan Wakely via cfe-commits

jwakely wrote:

> We don't use the trait currently in libc++ because of this bug and GCC only 
> added it in trunk (and have the same bug), so probably not.

N.B. MSVC used to have the same bug as well, and it affected their 
`std::is_array` because MSVC auto-replaces `std::is_array::value` with the 
intrinsic (and never instantiates the class template). I noted this behaviour 
in Feb 2022 and they fixed the intrinsic.

https://github.com/llvm/llvm-project/pull/86652
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Fix __is_array returning true for zero-sized arrays (PR #86652)

2024-03-29 Thread Aaron Ballman via cfe-commits

AaronBallman wrote:

> Another option would be to to not acknowledge zero-sized arrays in the type 
> traits at all, just like vector types: https://godbolt.org/z/aP685vz8q. That 
> may be the most consistent stance on this. Basically "It's non-standard and 
> doesn't fit neatly in any of the standard categories, so it's in no category 
> at all."

That's a possibility, though I wonder if it's actually user-friendly to issue a 
diagnostic if trying to use a non-standard type that can't fit the C++ type 
traits model. It's annoying for folks writing generic code, but so long as the 
diagnostic is SFINAE-able, maybe it's okay? My concern is that either returning 
`true` or `false` from any of those traits may give really surprising results 
to users, whereas a diagnostic makes it clear "you've wandered off the beaten 
path here and you need to think more carefully about what this all means". It's 
not quite as far as the idea of making them invalid types and perhaps is a bad 
idea, but I'm also somewhat okay with the idea of making it harder to use these 
non-standard extensions in highly generic code.

https://github.com/llvm/llvm-project/pull/86652
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Fix __is_array returning true for zero-sized arrays (PR #86652)

2024-03-28 Thread Kees Cook via cfe-commits

kees wrote:

I guess I don't have a strong opinion here, since these helpers are specific to 
C++, and I've been generally trying to remove fixed-size 0-sized arrays in C 
projects (i.e. the Linux kernel). I do care about C flexible arrays (and their 
associated extensions), though. I suspect there is some existing weirdness for 
C++ when using static initializers, though. See https://godbolt.org/z/PnYMcxhfM

```
struct S { int a; int b[]; };
static struct S s = { .a = 42, .b = { 10, 20, 30, 40 }, };
static struct S z = { .a = 13, };
```

Specifically `z.b` is a 0-sized flexible array, but `s.b` isn't. Should they 
have different results?

https://github.com/llvm/llvm-project/pull/86652
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Fix __is_array returning true for zero-sized arrays (PR #86652)

2024-03-28 Thread Nikolas Klauser via cfe-commits

philnik777 wrote:

Another option would be to to not acknowledge zero-sized arrays in the type 
traits at all, just like vector types: https://godbolt.org/z/aP685vz8q. That 
may be the most consistent stance on this. Basically "It's non-standard and 
doesn't fit neatly in any of the standard categories, so it's in no category at 
all."

https://github.com/llvm/llvm-project/pull/86652
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Fix __is_array returning true for zero-sized arrays (PR #86652)

2024-03-28 Thread Nikolas Klauser via cfe-commits

philnik777 wrote:

> I wonder if we should be considering making zero-length arrays into a 
> non-conforming extension behind a flag? e.g., `-fzero-sized-arrays` and then 
> it does report true for `__is_array`, `__is_bounded_array`, and handles 
> template specializations, etc as though it were really an array. That solves 
> two problems: 1) we can make the feature regular as opposed to having so many 
> sharp edges, 2) it pushes a surprising and questionable extension behind an 
> opt-in feature flag, and it creates at least one problem: 1) potentially 
> would change behavior of existing code in C++. So maybe this isn't a tenable 
> idea, but do we think it's worth exploring?

I think it may be worth exploring, but I'm not sure it's feasible. We've been 
using them accidentally a lot in the test suite in libc++ simply because it's 
really easy to miss that it's an extension, and we're also using it in our 
`string` implementation for padding.

> > My natural inclination is that it is array-like, but... that just makes me 
> > want `__is_array` to return `true` for it all the more.
> 
> Yes. An array is an array, regardless of its size. The size is just a storage 
> characteristic. It'd almost be like arguing that `NaN` isn't a float.

I don't think the float analogy really works here. The fact is that zero-sized 
arrays aren't acknowledged as being valid by the standard, so they don't behave 
like other arrays. It's _not_ just a storage characteristic. Having 
`-ffast-math` and then passing `NAN` somewhere seems like a better analogy to 
me. Things are mostly treated as if `NAN` didn't exist, and `NAN` also doesn't 
work like other floats.

> > I wonder if we should be considering making zero-length arrays into a 
> > non-conforming extension behind a flag?
> 
> It was never as simple as zero-length arrays. It was also _trailing arrays of 
> any size_ in structures. Those extensions create huge problems with being 
> able to reason about the characteristics of arrays, and we do have a flag for 
> this: `-fstrict-flex-arrays=3`. It is designed to disable all of the "treat 
> it like a flexible array" logic for the old "fake flexible array" objects. 
> But a flexible array is _still an array_. And also note that its size can 
> _change at runtime_ (see the `counted_by` attribute), which even more clearly 
> argues that you can't claim a flexible array isn't an array.

I'm not sure how the array being able to change its size at runtime makes it 
harder to claim it isn't one? non-zero-sized arrays don't do that. It's 
actually another thing that is different from the rest of the arrays.
I'm also not sure that it makes a ton of sense to talk about flexible arrays, 
since they aren't part of the type system, but `T[0]` happen to become flexible 
arrays if it is at the end of a struct (IIUC).

Another option (that I haven't thought deeply about): Make `T[0]` not be a type 
at all, i.e. make it illegal to `decltype`, `sizeof` etc. uses of it. I don't 
know how breaking that would be, and it's probably just as confusing as the 
current state of things, or even more so. Just wanted to throw it out.


https://github.com/llvm/llvm-project/pull/86652
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Fix __is_array returning true for zero-sized arrays (PR #86652)

2024-03-28 Thread Kees Cook via cfe-commits

kees wrote:

> My natural inclination is that it is array-like, but... that just makes me 
> want `__is_array` to return `true` for it all the more.

Yes. An array is an array, regardless of its size. The size is just a storage 
characteristic. It'd almost be like arguing that `NaN` isn't a float.

> I wonder if we should be considering making zero-length arrays into a 
> non-conforming extension behind a flag?

It was never as simple as zero-length arrays. It was also _trailing arrays of 
any size_ in structures. Those extensions create huge problems with being able 
to reason about the characteristics of arrays, and we do have a flag for this: 
`-fstrict-flex-arrays=3`. It is designed to disable all of the "treat it like a 
flexible array" logic for the old "fake flexible array" objects. But a flexible 
array is _still an array_. And also note that its size can _change at runtime_ 
(see the `counted_by` attribute), which even more clearly argues that you can't 
claim a flexible array isn't an array.

https://github.com/llvm/llvm-project/pull/86652
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Fix __is_array returning true for zero-sized arrays (PR #86652)

2024-03-27 Thread Aaron Ballman via cfe-commits

AaronBallman wrote:

> > I think we need to consider the following things:
> > ```
> > * Should `Ty[0]` and `Ty[]` be handled the same way? (Remember, we support 
> > `[0]` in structures as a sort of flexible array member and we support 
> > flexible array members in C++ as an extension.)
> > ```
> 
> I'm not sure what you're referring to. AFAICT `T[]` at the end of a struct 
> denotes a flexible array member, but `T[0]` doesn't. Or does it?

It doesn't per spec but it does as a common compiler extension: 
https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html

So my question is more that, if `T[0]` isn't considered an array because it has 
no size, should `T[]` be considered the same way?

> > ```
> > * We should probably change the value of `__is_bounded_array` at the same 
> > time as `__is_array`.
> > ```
> 
> Yes. I'll update the PR accordingly.
> 
> > ```
> > * What should the behavior of `__is_aggregate` be?
> > ```
> 
> I guess it should be true? I can't think of any case where a zero-sized array 
> would be different from a non-zero-sized one at least. I don't have a strong 
> opinion either way though.

I'm not entirely certain of how this particular type trait is used in practice. 
 Based on 
https://sourcegraph.com/search?q=context:global+lang:C%2B%2B+std::is_aggregate+-file:.*libcxx.*+-file:.*test.*+-file:.*clang.*+-file:.*gcc.*&patternType=keyword&sm=0
 it seems that most uses for this trait are to decide whether you can use 
aggregate initialization or not, and `Ty[0]` can be "used" in empty aggregate 
initialization (e.g., `int x[0] = {};`) so perhaps returning `true` makes 
sense? But then again, an aggregate is a class or array type, so the fact that 
`Ty[0]` will be reported as `false` for both of those doesn't seem ideal. CC 
@ldionne @mordante @cor3ntin for more opinions

> > ```
> > * What about other type traits (`__is_compound`, `__is_abstract`, etc)? 
> > Basically, what's the principle we're using for this type?
> > ```
> 
> Maybe we could think of it as array-like? i.e. it has the same traits as an 
> array except that it's not one. I think the semantics only really break down 
> for array-specific features. Just to get a sense, I've gone through a few 
> traits:
> 
> * `is_compound`: it seems pretty clear to me that it is a compound type, 
> since `T[0]` is a distinct type from `T`, but contains a type `T` in its 
> definition.
> 
> * `is_class`: It seems pretty clear to me that it's not a class. I don't 
> think anybody would disagree here.
> 
> * `is_abstract`: You can define a variable of it, so it's not. It's also 
> not a class type.
> 
> * `is_object`: I think it is, but this could be argued either way. The 
> best thing I could come up with is that it's closer to an array than it is to 
> a function or reference type.
> 
> 
> `is_empty` seems like an interesting case. It's the smallest type there is, 
> with `sizeof(int[0]) == 0`, but it's not considered empty by any 
> implementation. MSVC rejects the `sizeof` call though. I think it shouldn't 
> be considered empty though, since `is_empty` kind-of implies that the type is 
> a class type.

My natural inclination is that it is array-like, but... that just makes me want 
`__is_array` to return `true` for it all the more. That's... what it is. I 
wonder if we should be considering making zero-length arrays into a 
non-conforming extension behind a flag? e.g., `-fzero-sized-arrays` and then it 
does report true for `__is_array`, `__is_bounded_array`, and handles template 
specializations, etc as though it were really an array. That solves two 
problems: 1) we can make the feature regular as opposed to having so many sharp 
edges, 2) it pushes a surprising and questionable extension behind an opt-in 
feature flag, and it creates at least one problem: 1) potentially would change 
behavior of existing code in C++. So maybe this isn't a tenable idea, but do we 
think it's worth exploring?

Oh wow, and it gets even more surprising... adding a zero-length array to a 
structure *reduces the size of the structure* (in C++): 
https://godbolt.org/z/5E4YsT1Ye

CC @nickdesaulniers @kees @bwendling for more opinions from people who live 
with this kind of extension...

https://github.com/llvm/llvm-project/pull/86652
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Fix __is_array returning true for zero-sized arrays (PR #86652)

2024-03-26 Thread Nikolas Klauser via cfe-commits

philnik777 wrote:

> This doesn't leave us with good options, does it? :-(

Not really. Zero-sized arrays should probably have been supported by C++ all 
along, but it's too late to change it now.

> I think we need to consider the following things:
> 
> * Should `Ty[0]` and `Ty[]` be handled the same way? (Remember, we 
> support `[0]` in structures as a sort of flexible array member and we support 
> flexible array members in C++ as an extension.)

I'm not sure what you're referring to. AFAICT `T[]` at the end of a struct 
denotes a flexible array member, but `T[0]` doesn't. Or does it?

> * We should probably change the value of `__is_bounded_array` at the same 
> time as `__is_array`.

Yes. I'll update the PR accordingly.

> * What should the behavior of `__is_aggregate` be?

I guess it should be true? I can't think of any case where a zero-sized array 
would be different from a non-zero-sized one at least. I don't have a strong 
opinion either way though.

> * What about other type traits (`__is_compound`, `__is_abstract`, etc)? 
> Basically, what's the principle we're using for this type?

Maybe we could think of it as array-like? i.e. it has the same traits as an 
array except that it's not one. I think the semantics only really break down 
for array-specific features. Just to get a sense, I've gone through a few 
traits:
- `is_compound`: it seems pretty clear to me that it is a compound type, since 
`T[0]` is a distinct type from `T`, but contains a type `T` in its definition.
- `is_class`: It seems pretty clear to me that it's not a class. I don't think 
anybody would disagree here.
- `is_abstract`: You can define a variable of it, so it's not. It's also not a 
class type.
- `is_object`: I think it is, but this could be argued either way. The best 
thing I could come up with is that it's closer to an array than it is to a 
function or reference type.

`is_empty` seems like an interesting case. It's the smallest type there is, 
with `sizeof(int[0]) == 0`, but it's not considered empty by any 
implementation. MSVC rejects the `sizeof` call though. I think it shouldn't be 
considered empty though, since `is_empty` kind-of implies that the type is a 
class type.

> 
> > > > We don't use the trait currently in libc++ because of this bug and GCC 
> > > > only added it in trunk (and have the same bug), so probably not.
> > > 
> > > 
> > > For example, it seems to be used in Unreal Engine: 
> > > https://github.com/windystrife/UnrealEngine_NVIDIAGameWorks/blob/b50e6338a7c5b26374d66306ebc7807541ff815e/Engine/Source/Runtime/Core/Public/Templates/UnrealTemplate.h#L128
> > 
> > 
> > If you think it's a significant enough change that we should add an ABI tag 
> > I can do that.
> 
> I don't have a good feeling one way or the other yet, so let's hold off for 
> the moment and see what the final scope of the changes are before making a 
> decision.

Sounds good.

https://github.com/llvm/llvm-project/pull/86652
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Fix __is_array returning true for zero-sized arrays (PR #86652)

2024-03-26 Thread Aaron Ballman via cfe-commits

AaronBallman wrote:

> > > According to the spec it's ill-formed, so I'm not sure it falls under any 
> > > sensible category.
> > 
> > 
> > It's an extension we support so it's up to us to decide what sensible is.
> 
> Sure. If we end up putting it in the array category we should probably 
> coordinate with GCC.
> 
> > > For T[0] this returns false.
> > 
> > 
> > Understood, but why is this not the bug to be fixed? (It would also fix the 
> > `takes_an_array` case as well.)
> 
> Because I don't think we can. AFAICT this is valid C++:
> 
> ```c++
> template 
> int func() {
>   return 1;
> }
> 
> template 
> int func() {
>   return 0;
> }
> ```
> 
> If clang accepted `int[0]` in this context the observable behaviour would 
> change.

Hmm, I think you're right: https://godbolt.org/z/PjGoc3Yob, the 
`static_assert(func<0>() == 0);` case would start to fail to compile, similar 
to the code using `func<1>()`.

This doesn't leave us with good options, does it? :-(

I think we need to consider the following things:

* Should `Ty[0]` and `Ty[]` be handled the same way? (Remember, we support 
`[0]` in structures as a sort of flexible array member and we support flexible 
array members in C++ as an extension.)
* We should probably change the value of `__is_bounded_array` at the same time 
as `__is_array`.
* What should the behavior of `__is_aggregate` be?
* What about other type traits (`__is_compound`, `__is_abstract`, etc)? 
Basically, what's the principle we're using for this type?

> > > We don't use the trait currently in libc++ because of this bug and GCC 
> > > only added it in trunk (and have the same bug), so probably not.
> > 
> > 
> > For example, it seems to be used in Unreal Engine: 
> > https://github.com/windystrife/UnrealEngine_NVIDIAGameWorks/blob/b50e6338a7c5b26374d66306ebc7807541ff815e/Engine/Source/Runtime/Core/Public/Templates/UnrealTemplate.h#L128
> 
> If you think it's a significant enough change that we should add an ABI tag I 
> can do that.

I don't have a good feeling one way or the other yet, so let's hold off for the 
moment and see what the final scope of the changes are before making a decision.

https://github.com/llvm/llvm-project/pull/86652
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Fix __is_array returning true for zero-sized arrays (PR #86652)

2024-03-26 Thread Nikolas Klauser via cfe-commits

philnik777 wrote:

> > According to the spec it's ill-formed, so I'm not sure it falls under any 
> > sensible category.
> 
> It's an extension we support so it's up to us to decide what sensible is.

Sure. If we end up putting it in the array category we should probably 
coordinate with GCC.

> > For T[0] this returns false.
> 
> Understood, but why is this not the bug to be fixed? (It would also fix the 
> `takes_an_array` case as well.)

Because I don't think we can. AFAICT this is valid C++:
```c++
template 
int func() {
  return 1;
}

template 
int func() {
  return 0;
}
```
If clang accepted `int[0]` in this context the observable behaviour would 
change.

> > We don't use the trait currently in libc++ because of this bug and GCC only 
> > added it in trunk (and have the same bug), so probably not.
> 
> For example, it seems to be used in Unreal Engine: 
> https://github.com/windystrife/UnrealEngine_NVIDIAGameWorks/blob/b50e6338a7c5b26374d66306ebc7807541ff815e/Engine/Source/Runtime/Core/Public/Templates/UnrealTemplate.h#L128

If you think it's a significant enough change that we should add an ABI tag I 
can do that.


https://github.com/llvm/llvm-project/pull/86652
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Fix __is_array returning true for zero-sized arrays (PR #86652)

2024-03-26 Thread Aaron Ballman via cfe-commits

AaronBallman wrote:

> According to the spec it's ill-formed, so I'm not sure it falls under any 
> sensible category.

It's an extension we support so it's up to us to decide what sensible is.

> For T[0] this returns false.

Understood, but why is this not the bug to be fixed? (It would also fix the 
`takes_an_array` case as well.)

> We don't use the trait currently in libc++ because of this bug and GCC only 
> added it in trunk (and have the same bug), so probably not.

For example, it seems to be used in Unreal Engine: 
https://github.com/windystrife/UnrealEngine_NVIDIAGameWorks/blob/b50e6338a7c5b26374d66306ebc7807541ff815e/Engine/Source/Runtime/Core/Public/Templates/UnrealTemplate.h#L128

https://github.com/llvm/llvm-project/pull/86652
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Fix __is_array returning true for zero-sized arrays (PR #86652)

2024-03-26 Thread Nikolas Klauser via cfe-commits

philnik777 wrote:

> My primary question is: then what is it?
> 
> We return true for `__is_aggregrate` (https://godbolt.org/z/67zjeo7Mj), and 
> an aggregate is an array or class type 
> (https://eel.is/c++draft/dcl.init.aggr#1). This isn't a class type... but it 
> is an aggregate... so it must be an array? (We also don't claim it's a 
> pointer or a reference currently... so this thing will be basically invisible 
> to type traits.)

According to the spec it's ill-formed, so I'm not sure it falls under any 
sensible category.

> I would think it is an array given that it uses array syntax for declarations 
> and array semantics for accesses, but it's also not an array that's usable so 
> I can see why others say it's not an array. Personally, I think Clang's 
> behavior here makes the most sense -- we claim it's an array, we also claim 
> it's a bounded array, and we claim its extent is zero 
> (https://godbolt.org/z/4GdYTh4GG), and that matches the declaration for the 
> type. So with this change, I'm worried about how type traits can possibly 
> reason about this type -- I'd like to understand better why other 
> implementations decided this isn't an array and what it's classified as with 
> their type traits. Assuming that logic is compelling, there's more work 
> needed here to handle things like claiming it's a bounded array but not an 
> array.

For MSVC it's probably because they don't support `T[0]`. The main reason I 
don't think it should be considered an array for the type traits is that it 
doesn't behave like other arrays. e.g. the implementation that's used without 
the builtin is
```c++
template 
inline constexpr bool is_array_v = false;

template 
inline constexpr bool is_array_v = true;

template 
inline constexpr bool is_array_v = true;
```

For `T[0]` this returns false. 

Another example

> Also, do we need an ABI tag for folks to get the old behavior given that this 
> change almost certainly will impact ABI through type traits?

We don't use the trait currently in libc++ because of this bug and GCC only 
added it in trunk (and have the same bug), so probably not.


https://github.com/llvm/llvm-project/pull/86652
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Fix __is_array returning true for zero-sized arrays (PR #86652)

2024-03-26 Thread Aaron Ballman via cfe-commits

https://github.com/AaronBallman requested changes to this pull request.

My primary question is: then what is it?

We return true for `__is_aggregrate` (https://godbolt.org/z/67zjeo7Mj), and an 
aggregate is an array or class type (https://eel.is/c++draft/dcl.init.aggr#1). 
This isn't a class type... but it is an aggregate... so it must be an array? 
(We also don't claim it's a pointer or a reference currently... so this thing 
will be basically invisible to type traits.)

I would think it is an array given that it uses array syntax for declarations 
and array semantics for accesses, but it's also not an array that's usable so I 
can see why others say it's not an array. Personally, I think Clang's behavior 
here makes the most sense -- we claim it's an array, we also claim it's a 
bounded array, and we claim its extent is zero 
(https://godbolt.org/z/4GdYTh4GG), and that matches the declaration for the 
type. So with this change, I'm worried about how type traits can possibly 
reason about this type -- I'd like to understand better why other 
implementations decided this isn't an array and what it's classified as with 
their type traits. Assuming that logic is compelling, there's more work needed 
here to handle things like claiming it's a bounded array but not an array.

Also, do we need an ABI tag for folks to get the old behavior given that this 
change almost certainly will impact ABI through type traits?

https://github.com/llvm/llvm-project/pull/86652
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Fix __is_array returning true for zero-sized arrays (PR #86652)

2024-03-26 Thread Aaron Ballman via cfe-commits


@@ -1804,7 +1806,7 @@ void is_layout_compatible(int n)
   static_assert(!__is_layout_compatible(EnumForward, int));
   static_assert(!__is_layout_compatible(EnumClassForward, int));
   // FIXME: the following should be rejected (array of unknown bound and void 
are the only allowed incomplete types)
-  static_assert(__is_layout_compatible(CStructIncomplete, CStructIncomplete)); 
+  static_assert(__is_layout_compatible(CStructIncomplete, CStructIncomplete));

AaronBallman wrote:

Spurious whitespace change.

https://github.com/llvm/llvm-project/pull/86652
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Fix __is_array returning true for zero-sized arrays (PR #86652)

2024-03-26 Thread Aaron Ballman via cfe-commits

https://github.com/AaronBallman edited 
https://github.com/llvm/llvm-project/pull/86652
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Fix __is_array returning true for zero-sized arrays (PR #86652)

2024-03-26 Thread via cfe-commits

github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff 5b544b511c7133fcb26a5c563b746a4baefb38d6 
90f88bdac3dc40635c58f3f67e29354e6a32896e -- clang/lib/Sema/SemaExprCXX.cpp 
clang/test/SemaCXX/type-traits.cpp
``





View the diff from clang-format here.


``diff
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 93d2b4b259..46dd14a871 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -5145,7 +5145,7 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait 
UTT,
   case UTT_IsArray:
 // zero-sized arrays aren't considered arrays in partial specializations,
 // so __is_array shouldn't consider them arrays either.
-if (const auto* CAT = C.getAsConstantArrayType(T))
+if (const auto *CAT = C.getAsConstantArrayType(T))
   return CAT->getSize() != 0;
 return T->isArrayType();
   case UTT_IsBoundedArray:

``




https://github.com/llvm/llvm-project/pull/86652
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Fix __is_array returning true for zero-sized arrays (PR #86652)

2024-03-26 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Nikolas Klauser (philnik777)


Changes

Fixes #54705


---
Full diff: https://github.com/llvm/llvm-project/pull/86652.diff


3 Files Affected:

- (modified) clang/docs/ReleaseNotes.rst (+2) 
- (modified) clang/lib/Sema/SemaExprCXX.cpp (+4) 
- (modified) clang/test/SemaCXX/type-traits.cpp (+3-1) 


``diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 7fbe2fec6ca065..e6682028537101 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -345,6 +345,8 @@ Bug Fixes in This Version
 - Fixes an assertion failure on invalid code when trying to define member
   functions in lambdas.
 
+- ``__is_array`` no longer returns ``true`` for zero-sized arrays. Fixes 
(#GH54705).
+
 Bug Fixes to Compiler Builtins
 ^^
 
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index c34a40fa7c81ac..93d2b4b259fbc3 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -5143,6 +5143,10 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait 
UTT,
   case UTT_IsFloatingPoint:
 return T->isFloatingType();
   case UTT_IsArray:
+// zero-sized arrays aren't considered arrays in partial specializations,
+// so __is_array shouldn't consider them arrays either.
+if (const auto* CAT = C.getAsConstantArrayType(T))
+  return CAT->getSize() != 0;
 return T->isArrayType();
   case UTT_IsBoundedArray:
 if (!T->isVariableArrayType()) {
diff --git a/clang/test/SemaCXX/type-traits.cpp 
b/clang/test/SemaCXX/type-traits.cpp
index 14ec17989ec7c7..49df4b668513c0 100644
--- a/clang/test/SemaCXX/type-traits.cpp
+++ b/clang/test/SemaCXX/type-traits.cpp
@@ -25,6 +25,7 @@ typedef Empty EmptyArMB[1][2];
 typedef int Int;
 typedef Int IntAr[10];
 typedef Int IntArNB[];
+typedef Int IntArZero[0];
 class Statics { static int priv; static NonPOD np; };
 union EmptyUnion {};
 union IncompleteUnion; // expected-note {{forward declaration of 
'IncompleteUnion'}}
@@ -685,6 +686,7 @@ void is_array()
 {
   static_assert(__is_array(IntAr));
   static_assert(__is_array(IntArNB));
+  static_assert(!__is_array(IntArZero));
   static_assert(__is_array(UnionAr));
 
   static_assert(!__is_array(void));
@@ -1804,7 +1806,7 @@ void is_layout_compatible(int n)
   static_assert(!__is_layout_compatible(EnumForward, int));
   static_assert(!__is_layout_compatible(EnumClassForward, int));
   // FIXME: the following should be rejected (array of unknown bound and void 
are the only allowed incomplete types)
-  static_assert(__is_layout_compatible(CStructIncomplete, CStructIncomplete)); 
+  static_assert(__is_layout_compatible(CStructIncomplete, CStructIncomplete));
   static_assert(!__is_layout_compatible(CStruct, CStructIncomplete));
   static_assert(__is_layout_compatible(CStructIncomplete[2], 
CStructIncomplete[2]));
 }

``




https://github.com/llvm/llvm-project/pull/86652
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Fix __is_array returning true for zero-sized arrays (PR #86652)

2024-03-26 Thread Nikolas Klauser via cfe-commits

https://github.com/philnik777 created 
https://github.com/llvm/llvm-project/pull/86652

Fixes #54705


>From 90f88bdac3dc40635c58f3f67e29354e6a32896e Mon Sep 17 00:00:00 2001
From: Nikolas Klauser 
Date: Tue, 26 Mar 2024 12:23:24 +0100
Subject: [PATCH] [Clang] Fix __is_array returning true for zero-sized arrays

---
 clang/docs/ReleaseNotes.rst| 2 ++
 clang/lib/Sema/SemaExprCXX.cpp | 4 
 clang/test/SemaCXX/type-traits.cpp | 4 +++-
 3 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 7fbe2fec6ca065..e6682028537101 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -345,6 +345,8 @@ Bug Fixes in This Version
 - Fixes an assertion failure on invalid code when trying to define member
   functions in lambdas.
 
+- ``__is_array`` no longer returns ``true`` for zero-sized arrays. Fixes 
(#GH54705).
+
 Bug Fixes to Compiler Builtins
 ^^
 
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index c34a40fa7c81ac..93d2b4b259fbc3 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -5143,6 +5143,10 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait 
UTT,
   case UTT_IsFloatingPoint:
 return T->isFloatingType();
   case UTT_IsArray:
+// zero-sized arrays aren't considered arrays in partial specializations,
+// so __is_array shouldn't consider them arrays either.
+if (const auto* CAT = C.getAsConstantArrayType(T))
+  return CAT->getSize() != 0;
 return T->isArrayType();
   case UTT_IsBoundedArray:
 if (!T->isVariableArrayType()) {
diff --git a/clang/test/SemaCXX/type-traits.cpp 
b/clang/test/SemaCXX/type-traits.cpp
index 14ec17989ec7c7..49df4b668513c0 100644
--- a/clang/test/SemaCXX/type-traits.cpp
+++ b/clang/test/SemaCXX/type-traits.cpp
@@ -25,6 +25,7 @@ typedef Empty EmptyArMB[1][2];
 typedef int Int;
 typedef Int IntAr[10];
 typedef Int IntArNB[];
+typedef Int IntArZero[0];
 class Statics { static int priv; static NonPOD np; };
 union EmptyUnion {};
 union IncompleteUnion; // expected-note {{forward declaration of 
'IncompleteUnion'}}
@@ -685,6 +686,7 @@ void is_array()
 {
   static_assert(__is_array(IntAr));
   static_assert(__is_array(IntArNB));
+  static_assert(!__is_array(IntArZero));
   static_assert(__is_array(UnionAr));
 
   static_assert(!__is_array(void));
@@ -1804,7 +1806,7 @@ void is_layout_compatible(int n)
   static_assert(!__is_layout_compatible(EnumForward, int));
   static_assert(!__is_layout_compatible(EnumClassForward, int));
   // FIXME: the following should be rejected (array of unknown bound and void 
are the only allowed incomplete types)
-  static_assert(__is_layout_compatible(CStructIncomplete, CStructIncomplete)); 
+  static_assert(__is_layout_compatible(CStructIncomplete, CStructIncomplete));
   static_assert(!__is_layout_compatible(CStruct, CStructIncomplete));
   static_assert(__is_layout_compatible(CStructIncomplete[2], 
CStructIncomplete[2]));
 }

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits