Re: [PATCH v2] C, ObjC: Add -Wunterminated-string-initialization

2023-09-30 Thread Alejandro Colomar
Hi David,

Sorry for the half-year delay!  I have some update.  :)

On Fri, Mar 24, 2023 at 10:53:22AM -0400, David Malcolm wrote:
> On Fri, 2023-03-24 at 14:39 +0100, Alejandro Colomar via Gcc-patches
> wrote:
> > Warn about the following:
> > 
> >     char  s[3] = "foo";
> > 
> > Initializing a char array with a string literal of the same length as
> > the size of the array is usually a mistake.  Rarely is the case where
> > one wants to create a non-terminated character sequence from a string
> > literal.
> > 
> > In some cases, for writing faster code, one may want to use arrays
> > instead of pointers, since that removes the need for storing an array
> > of
> > pointers apart from the strings themselves.
> > 
> >     char  *log_levels[]   = { "info", "warning", "err" };
> > vs.
> >     char  log_levels[][7] = { "info", "warning", "err" };
> > 
> > This forces the programmer to specify a size, which might change if a
> > new entry is later added.  Having no way to enforce null termination
> > is
> > very dangerous, however, so it is useful to have a warning for this,
> > so
> > that the compiler can make sure that the programmer didn't make any
> > mistakes.  This warning catches the bug above, so that the programmer
> > will be able to fix it and write:
> > 
> >     char  log_levels[][8] = { "info", "warning", "err" };
> > 
> > This warning already existed as part of -Wc++-compat, but this patch
> > allows enabling it separately.  It is also included in -Wextra, since
> > it may not always be desired (when unterminated character sequences
> > are
> > wanted), but it's likely to be desired in most cases.
> > 
> > Link:
> > <https://lists.gnu.org/archive/html/groff/2022-11/msg00059.html>
> > Link:
> > <https://lists.gnu.org/archive/html/groff/2022-11/msg00063.html>
> > Link:
> > <https://inbox.sourceware.org/gcc/36da94eb-1cac-5ae8-7fea-ec66160cf41
> > 3...@gmail.com/T/>
> > Acked-by: Doug McIlroy 
> > Cc: "G. Branden Robinson" 
> > Cc: Ralph Corderoy 
> > Cc: Dave Kemper 
> > Cc: Larry McVoy 
> > Cc: Andrew Pinski 
> > Cc: Jonathan Wakely 
> > Cc: Andrew Clayton 
> > Cc: Martin Uecker 
> > Signed-off-by: Alejandro Colomar 
> > ---
> > 
> > Hi,
> 
> Hi Alex, thanks for the patch.
> 
> > 
> > I sent v1 to the wrong list.  This time I've made sure to write to
> > gcc-patches@.
> 
> Note that right now we're deep in bug-fixing/stabilization for GCC 13
> (and trunk is still tracking that effort), so your patch might be more
> suitable for GCC 14.
> 
> > 
> > v2 adds some draft of a test, as suggested by Martin.  However, I
> > don't
> > know yet how to write those, so the test is just a draft.  But I did
> > test the feature, by compiling GCC and compiling some small program
> > with
> > it.
> 
> Unfortunately the answer to the question "how do I run just one
> testcase in GCC's testsuite" is rather non-trivial; FWIW I've written
> up some notes on working with the GCC testsuite here:
> https://gcc-newbies-guide.readthedocs.io/en/latest/working-with-the-testsuite.html
> 
> Hope this is helpful
> Dave
> 
> 
> [...snip...]
> 

I ran the tests, and get some unexpected failure.  I used dg-warning,
but maybe I used it wrong?  Here's the output:

```
output is:
/home/alx/src/gnu/gcc/wustr/gcc/testsuite/gcc.dg/Wunterminated-string-initialization.c:5:14:
 warning: initializer-string for array of 'char' is too long 
[-Wunterminated-string-initi
alization]

FAIL: gcc.dg/Wunterminated-string-initialization.c  (test for warnings, line 5)
```

And here's the test:

```
/* { dg-do compile } */
/* { dg-options "-Wunterminated-string-initialization" } */

char a1[] = "a";
char a2[1] = "a";   /* { dg-warning "unterminated char sequence" } */
char a3[2] = "a";
```

Why isn't it expecting the warning?

Thanks,
Alex


signature.asc
Description: PGP signature


Re: [PATCH v2] C, ObjC: Add -Wunterminated-string-initialization

2023-10-01 Thread Alejandro Colomar
On Sun, Oct 01, 2023 at 09:37:59AM +0200, Martin Uecker wrote:
> 
> (I shortened the recipient list)
> 
> Am Sonntag, dem 01.10.2023 um 02:55 +0200 schrieb Alejandro Colomar:
> 
> > > 
> ...
> > I ran the tests, and get some unexpected failure.  I used dg-warning,
> > but maybe I used it wrong?  Here's the output:
> > 
> > ```
> > output is:
> > /home/alx/src/gnu/gcc/wustr/gcc/testsuite/gcc.dg/Wunterminated-string-initialization.c:5:14:
> >  warning: initializer-string for array of 'char' is too long 
> > [-Wunterminated-string-initi
> > alization]
> > 
> > FAIL: gcc.dg/Wunterminated-string-initialization.c  (test for warnings, 
> > line 5)
> > ```
> > 
> > And here's the test:
> > 
> > ```
> > /* { dg-do compile } */
> > /* { dg-options "-Wunterminated-string-initialization" } */
> > 
> > char a1[] = "a";
> > char a2[1] = "a";   /* { dg-warning "unterminated char sequence" } */
> > char a3[2] = "a";
> > ```
> > 
> > Why isn't it expecting the warning?
> 
> Because the text does not match the actual output above?

Makes sense.

Here's the output after a fix (which I'll send soon as a new revision):

```
output is:
/home/alx/src/gnu/gcc/wustr/gcc/testsuite/gcc.dg/Wunterminated-string-initialization.c:5:14:
 warning: initializer-string for array of 'char' is too long 
[-Wunterminated-string-initialization]

```
and

```
=== gcc Summary ===

# of expected passes2
```

The only thing that concerns me a little bit is that I don't see any
PASS (or XFAIL).

> You should see an additional FAIL for an excess warning.

Yep, I did.

Cheers,
Alex

> 
> Martin
> 
> 
> 
> 


signature.asc
Description: PGP signature


[PATCH v3] C, ObjC: Add -Wunterminated-string-initialization

2023-10-01 Thread Alejandro Colomar
From: Alejandro Colomar 

Warn about the following:

char  s[3] = "foo";

Initializing a char array with a string literal of the same length as
the size of the array is usually a mistake.  Rarely is the case where
one wants to create a non-terminated character sequence from a string
literal.

In some cases, for writing faster code, one may want to use arrays
instead of pointers, since that removes the need for storing an array of
pointers apart from the strings themselves.

char  *log_levels[]   = { "info", "warning", "err" };
vs.
char  log_levels[][7] = { "info", "warning", "err" };

This forces the programmer to specify a size, which might change if a
new entry is later added.  Having no way to enforce null termination is
very dangerous, however, so it is useful to have a warning for this, so
that the compiler can make sure that the programmer didn't make any
mistakes.  This warning catches the bug above, so that the programmer
will be able to fix it and write:

char  log_levels[][8] = { "info", "warning", "err" };

This warning already existed as part of -Wc++-compat, but this patch
allows enabling it separately.  It is also included in -Wextra, since
it may not always be desired (when unterminated character sequences are
wanted), but it's likely to be desired in most cases.

Link: <https://lists.gnu.org/archive/html/groff/2022-11/msg00059.html>
Link: <https://lists.gnu.org/archive/html/groff/2022-11/msg00063.html>
Link: 
<https://inbox.sourceware.org/gcc/36da94eb-1cac-5ae8-7fea-ec66160cf...@gmail.com/T/>
Acked-by: Doug McIlroy 
Cc: "G. Branden Robinson" 
Cc: Ralph Corderoy 
Cc: Dave Kemper 
Cc: Larry McVoy 
Cc: Andrew Pinski 
Cc: Jonathan Wakely 
Cc: Andrew Clayton 
Cc: Martin Uecker 
Cc: David Malcolm 
Signed-off-by: Alejandro Colomar 
---

v3:

-  Fix dg-warning message in the testsuite.

 gcc/c-family/c.opt | 4 
 gcc/c/c-typeck.cc  | 6 +++---
 gcc/testsuite/gcc.dg/Wunterminated-string-initialization.c | 6 ++
 3 files changed, 13 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/Wunterminated-string-initialization.c

diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 44b9c862c14..e8f6b836836 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -1407,6 +1407,10 @@ Wunsuffixed-float-constants
 C ObjC Var(warn_unsuffixed_float_constants) Warning
 Warn about unsuffixed float constants.
 
+Wunterminated-string-initialization
+C ObjC Var(warn_unterminated_string_initialization) Warning LangEnabledBy(C 
ObjC,Wextra || Wc++-compat)
+Warn about character arrays initialized as unterminated character sequences by 
a string literal.
+
 Wunused
 C ObjC C++ ObjC++ LangEnabledBy(C ObjC C++ ObjC++,Wall)
 ; documented in common.opt
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index e55e887da14..7df9de819ed 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -8399,11 +8399,11 @@ digest_init (location_t init_loc, tree type, tree init, 
tree origtype,
pedwarn_init (init_loc, 0,
  ("initializer-string for array of %qT "
   "is too long"), typ1);
- else if (warn_cxx_compat
+ else if (warn_unterminated_string_initialization
   && compare_tree_int (TYPE_SIZE_UNIT (type), len) < 0)
-   warning_at (init_loc, OPT_Wc___compat,
+   warning_at (init_loc, OPT_Wunterminated_string_initialization,
("initializer-string for array of %qT "
-"is too long for C++"), typ1);
+"is too long"), typ1);
  if (compare_tree_int (TYPE_SIZE_UNIT (type), len) < 0)
{
  unsigned HOST_WIDE_INT size
diff --git a/gcc/testsuite/gcc.dg/Wunterminated-string-initialization.c 
b/gcc/testsuite/gcc.dg/Wunterminated-string-initialization.c
new file mode 100644
index 000..13d5dbc6640
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wunterminated-string-initialization.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-Wunterminated-string-initialization" } */
+
+char a1[] = "a";
+char a2[1] = "a";  /* { dg-warning "initializer-string for array of 'char' 
is too long" } */
+char a3[2] = "a";
-- 
2.40.1



[PATCH v4] C, ObjC: Add -Wunterminated-string-initialization

2023-10-01 Thread Alejandro Colomar
Warn about the following:

char  s[3] = "foo";

Initializing a char array with a string literal of the same length as
the size of the array is usually a mistake.  Rarely is the case where
one wants to create a non-terminated character sequence from a string
literal.

In some cases, for writing faster code, one may want to use arrays
instead of pointers, since that removes the need for storing an array of
pointers apart from the strings themselves.

char  *log_levels[]   = { "info", "warning", "err" };
vs.
char  log_levels[][7] = { "info", "warning", "err" };

This forces the programmer to specify a size, which might change if a
new entry is later added.  Having no way to enforce null termination is
very dangerous, however, so it is useful to have a warning for this, so
that the compiler can make sure that the programmer didn't make any
mistakes.  This warning catches the bug above, so that the programmer
will be able to fix it and write:

char  log_levels[][8] = { "info", "warning", "err" };

This warning already existed as part of -Wc++-compat, but this patch
allows enabling it separately.  It is also included in -Wextra, since
it may not always be desired (when unterminated character sequences are
wanted), but it's likely to be desired in most cases.

Link: <https://lists.gnu.org/archive/html/groff/2022-11/msg00059.html>
Link: <https://lists.gnu.org/archive/html/groff/2022-11/msg00063.html>
Link: 
<https://inbox.sourceware.org/gcc/36da94eb-1cac-5ae8-7fea-ec66160cf...@gmail.com/T/>
Acked-by: Doug McIlroy 
Cc: "G. Branden Robinson" 
Cc: Ralph Corderoy 
Cc: Dave Kemper 
Cc: Larry McVoy 
Cc: Andrew Pinski 
Cc: Jonathan Wakely 
Cc: Andrew Clayton 
Cc: Martin Uecker 
Cc: David Malcolm 
Signed-off-by: Alejandro Colomar 
---

v4:

-  Fix From: address

 gcc/c-family/c.opt | 4 
 gcc/c/c-typeck.cc  | 6 +++---
 gcc/testsuite/gcc.dg/Wunterminated-string-initialization.c | 6 ++
 3 files changed, 13 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/Wunterminated-string-initialization.c

diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 44b9c862c14..e8f6b836836 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -1407,6 +1407,10 @@ Wunsuffixed-float-constants
 C ObjC Var(warn_unsuffixed_float_constants) Warning
 Warn about unsuffixed float constants.
 
+Wunterminated-string-initialization
+C ObjC Var(warn_unterminated_string_initialization) Warning LangEnabledBy(C 
ObjC,Wextra || Wc++-compat)
+Warn about character arrays initialized as unterminated character sequences by 
a string literal.
+
 Wunused
 C ObjC C++ ObjC++ LangEnabledBy(C ObjC C++ ObjC++,Wall)
 ; documented in common.opt
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index e55e887da14..7df9de819ed 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -8399,11 +8399,11 @@ digest_init (location_t init_loc, tree type, tree init, 
tree origtype,
pedwarn_init (init_loc, 0,
  ("initializer-string for array of %qT "
   "is too long"), typ1);
- else if (warn_cxx_compat
+ else if (warn_unterminated_string_initialization
   && compare_tree_int (TYPE_SIZE_UNIT (type), len) < 0)
-   warning_at (init_loc, OPT_Wc___compat,
+   warning_at (init_loc, OPT_Wunterminated_string_initialization,
("initializer-string for array of %qT "
-"is too long for C++"), typ1);
+"is too long"), typ1);
  if (compare_tree_int (TYPE_SIZE_UNIT (type), len) < 0)
{
  unsigned HOST_WIDE_INT size
diff --git a/gcc/testsuite/gcc.dg/Wunterminated-string-initialization.c 
b/gcc/testsuite/gcc.dg/Wunterminated-string-initialization.c
new file mode 100644
index 000..13d5dbc6640
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wunterminated-string-initialization.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-Wunterminated-string-initialization" } */
+
+char a1[] = "a";
+char a2[1] = "a";  /* { dg-warning "initializer-string for array of 'char' 
is too long" } */
+char a3[2] = "a";
-- 
2.40.1



[PATCH v5] C, ObjC: Add -Wunterminated-string-initialization

2023-10-01 Thread Alejandro Colomar
Warn about the following:

char  s[3] = "foo";

Initializing a char array with a string literal of the same length as
the size of the array is usually a mistake.  Rarely is the case where
one wants to create a non-terminated character sequence from a string
literal.

In some cases, for writing faster code, one may want to use arrays
instead of pointers, since that removes the need for storing an array of
pointers apart from the strings themselves.

char  *log_levels[]   = { "info", "warning", "err" };
vs.
char  log_levels[][7] = { "info", "warning", "err" };

This forces the programmer to specify a size, which might change if a
new entry is later added.  Having no way to enforce null termination is
very dangerous, however, so it is useful to have a warning for this, so
that the compiler can make sure that the programmer didn't make any
mistakes.  This warning catches the bug above, so that the programmer
will be able to fix it and write:

char  log_levels[][8] = { "info", "warning", "err" };

This warning already existed as part of -Wc++-compat, but this patch
allows enabling it separately.  It is also included in -Wextra, since
it may not always be desired (when unterminated character sequences are
wanted), but it's likely to be desired in most cases.

Since Wc++-compat now includes this warning, the test has to be modified
to expect the text of the new warning too, in .

Link: <https://lists.gnu.org/archive/html/groff/2022-11/msg00059.html>
Link: <https://lists.gnu.org/archive/html/groff/2022-11/msg00063.html>
Link: 
<https://inbox.sourceware.org/gcc/36da94eb-1cac-5ae8-7fea-ec66160cf...@gmail.com/T/>
Acked-by: Doug McIlroy 
Cc: "G. Branden Robinson" 
Cc: Ralph Corderoy 
Cc: Dave Kemper 
Cc: Larry McVoy 
Cc: Andrew Pinski 
Cc: Jonathan Wakely 
Cc: Andrew Clayton 
Cc: Martin Uecker 
Cc: David Malcolm 
Signed-off-by: Alejandro Colomar 
---

v5:

-  Fix existing C++-compat tests.  [reported by ]


 gcc/c-family/c.opt | 4 
 gcc/c/c-typeck.cc  | 6 +++---
 gcc/testsuite/gcc.dg/Wcxx-compat-14.c  | 2 +-
 gcc/testsuite/gcc.dg/Wunterminated-string-initialization.c | 6 ++
 4 files changed, 14 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/Wunterminated-string-initialization.c

diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 44b9c862c14..e8f6b836836 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -1407,6 +1407,10 @@ Wunsuffixed-float-constants
 C ObjC Var(warn_unsuffixed_float_constants) Warning
 Warn about unsuffixed float constants.
 
+Wunterminated-string-initialization
+C ObjC Var(warn_unterminated_string_initialization) Warning LangEnabledBy(C 
ObjC,Wextra || Wc++-compat)
+Warn about character arrays initialized as unterminated character sequences by 
a string literal.
+
 Wunused
 C ObjC C++ ObjC++ LangEnabledBy(C ObjC C++ ObjC++,Wall)
 ; documented in common.opt
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index e55e887da14..7df9de819ed 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -8399,11 +8399,11 @@ digest_init (location_t init_loc, tree type, tree init, 
tree origtype,
pedwarn_init (init_loc, 0,
  ("initializer-string for array of %qT "
   "is too long"), typ1);
- else if (warn_cxx_compat
+ else if (warn_unterminated_string_initialization
   && compare_tree_int (TYPE_SIZE_UNIT (type), len) < 0)
-   warning_at (init_loc, OPT_Wc___compat,
+   warning_at (init_loc, OPT_Wunterminated_string_initialization,
("initializer-string for array of %qT "
-"is too long for C++"), typ1);
+"is too long"), typ1);
  if (compare_tree_int (TYPE_SIZE_UNIT (type), len) < 0)
{
  unsigned HOST_WIDE_INT size
diff --git a/gcc/testsuite/gcc.dg/Wcxx-compat-14.c 
b/gcc/testsuite/gcc.dg/Wcxx-compat-14.c
index 23783711be6..6df0ee197cc 100644
--- a/gcc/testsuite/gcc.dg/Wcxx-compat-14.c
+++ b/gcc/testsuite/gcc.dg/Wcxx-compat-14.c
@@ -2,5 +2,5 @@
 /* { dg-options "-Wc++-compat" } */
 
 char a1[] = "a";
-char a2[1] = "a";  /* { dg-warning "C\[+\]\[+\]" } */
+char a2[1] = "a";  /* { dg-warning "initializer-string for array of 'char' 
is too long" } */
 char a3[2] = "a";
diff --git a/gcc/testsuite/gcc.dg/Wunterminated-string-initialization.c 
b/gcc/testsuite/gcc.dg/Wunterminated-string-initialization.c
new file mode 100644
index 000..13d5dbc6640
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wunterminated-string-initialization.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-Wunterminated-string-initialization" } */
+
+char a1[] = "a";
+char a2[1] = "a";  /* { dg-warning "initializer-string for array of 'char' 
is too long" } */
+char a3[2] = "a";
-- 
2.40.1



Ping: [PATCH v5] C, ObjC: Add -Wunterminated-string-initialization

2023-10-08 Thread Alejandro Colomar
Hi,

Gentle ping here.

Thanks,
Alex

On Sun, Oct 01, 2023 at 06:24:00PM +0200, Alejandro Colomar wrote:
> Warn about the following:
> 
> char  s[3] = "foo";
> 
> Initializing a char array with a string literal of the same length as
> the size of the array is usually a mistake.  Rarely is the case where
> one wants to create a non-terminated character sequence from a string
> literal.
> 
> In some cases, for writing faster code, one may want to use arrays
> instead of pointers, since that removes the need for storing an array of
> pointers apart from the strings themselves.
> 
> char  *log_levels[]   = { "info", "warning", "err" };
> vs.
> char  log_levels[][7] = { "info", "warning", "err" };
> 
> This forces the programmer to specify a size, which might change if a
> new entry is later added.  Having no way to enforce null termination is
> very dangerous, however, so it is useful to have a warning for this, so
> that the compiler can make sure that the programmer didn't make any
> mistakes.  This warning catches the bug above, so that the programmer
> will be able to fix it and write:
> 
> char  log_levels[][8] = { "info", "warning", "err" };
> 
> This warning already existed as part of -Wc++-compat, but this patch
> allows enabling it separately.  It is also included in -Wextra, since
> it may not always be desired (when unterminated character sequences are
> wanted), but it's likely to be desired in most cases.
> 
> Since Wc++-compat now includes this warning, the test has to be modified
> to expect the text of the new warning too, in .
> 
> Link: <https://lists.gnu.org/archive/html/groff/2022-11/msg00059.html>
> Link: <https://lists.gnu.org/archive/html/groff/2022-11/msg00063.html>
> Link: 
> <https://inbox.sourceware.org/gcc/36da94eb-1cac-5ae8-7fea-ec66160cf...@gmail.com/T/>
> Acked-by: Doug McIlroy 
> Cc: "G. Branden Robinson" 
> Cc: Ralph Corderoy 
> Cc: Dave Kemper 
> Cc: Larry McVoy 
> Cc: Andrew Pinski 
> Cc: Jonathan Wakely 
> Cc: Andrew Clayton 
> Cc: Martin Uecker 
> Cc: David Malcolm 
> Signed-off-by: Alejandro Colomar 
> ---
> 
> v5:
> 
> -  Fix existing C++-compat tests.  [reported by ]
> 
> 
>  gcc/c-family/c.opt | 4 
>  gcc/c/c-typeck.cc  | 6 +++---
>  gcc/testsuite/gcc.dg/Wcxx-compat-14.c  | 2 +-
>  gcc/testsuite/gcc.dg/Wunterminated-string-initialization.c | 6 ++
>  4 files changed, 14 insertions(+), 4 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/Wunterminated-string-initialization.c
> 
> diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
> index 44b9c862c14..e8f6b836836 100644
> --- a/gcc/c-family/c.opt
> +++ b/gcc/c-family/c.opt
> @@ -1407,6 +1407,10 @@ Wunsuffixed-float-constants
>  C ObjC Var(warn_unsuffixed_float_constants) Warning
>  Warn about unsuffixed float constants.
>  
> +Wunterminated-string-initialization
> +C ObjC Var(warn_unterminated_string_initialization) Warning LangEnabledBy(C 
> ObjC,Wextra || Wc++-compat)
> +Warn about character arrays initialized as unterminated character sequences 
> by a string literal.
> +
>  Wunused
>  C ObjC C++ ObjC++ LangEnabledBy(C ObjC C++ ObjC++,Wall)
>  ; documented in common.opt
> diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
> index e55e887da14..7df9de819ed 100644
> --- a/gcc/c/c-typeck.cc
> +++ b/gcc/c/c-typeck.cc
> @@ -8399,11 +8399,11 @@ digest_init (location_t init_loc, tree type, tree 
> init, tree origtype,
>   pedwarn_init (init_loc, 0,
> ("initializer-string for array of %qT "
>  "is too long"), typ1);
> -   else if (warn_cxx_compat
> +   else if (warn_unterminated_string_initialization
>  && compare_tree_int (TYPE_SIZE_UNIT (type), len) < 0)
> - warning_at (init_loc, OPT_Wc___compat,
> + warning_at (init_loc, OPT_Wunterminated_string_initialization,
>   ("initializer-string for array of %qT "
> -  "is too long for C++"), typ1);
> +  "is too long"), typ1);
> if (compare_tree_int (TYPE_SIZE_UNIT (type), len) < 0)
>   {
> unsigned HOST_WIDE_INT size
> diff --git a/gcc/testsuite/gcc.dg/Wcxx-compat-14.c 
> b/gcc/testsuite/gcc.dg/Wcxx-compat-14.c
> index 23783711be6..6df0ee197cc 100644
> --- a/gcc/testsuite/gcc.dg/Wcxx-compat-14.c
> +++ b/gcc/

[PATCH v6] C, ObjC: Add -Wunterminated-string-initialization

2024-03-05 Thread Alejandro Colomar
Warn about the following:

char  s[3] = "foo";

Initializing a char array with a string literal of the same length as
the size of the array is usually a mistake.  Rarely is the case where
one wants to create a non-terminated character sequence from a string
literal.

In some cases, for writing faster code, one may want to use arrays
instead of pointers, since that removes the need for storing an array of
pointers apart from the strings themselves.

char  *log_levels[]   = { "info", "warning", "err" };
vs.
char  log_levels[][7] = { "info", "warning", "err" };

This forces the programmer to specify a size, which might change if a
new entry is later added.  Having no way to enforce null termination is
very dangerous, however, so it is useful to have a warning for this, so
that the compiler can make sure that the programmer didn't make any
mistakes.  This warning catches the bug above, so that the programmer
will be able to fix it and write:

char  log_levels[][8] = { "info", "warning", "err" };

This warning already existed as part of -Wc++-compat, but this patch
allows enabling it separately.  It is also included in -Wextra, since
it may not always be desired (when unterminated character sequences are
wanted), but it's likely to be desired in most cases.

Since Wc++-compat now includes this warning, the test has to be modified
to expect the text of the new warning too, in .

Link: <https://lists.gnu.org/archive/html/groff/2022-11/msg00059.html>
Link: <https://lists.gnu.org/archive/html/groff/2022-11/msg00063.html>
Link: 
<https://inbox.sourceware.org/gcc/36da94eb-1cac-5ae8-7fea-ec66160cf...@gmail.com/T/>
Acked-by: Doug McIlroy 
Cc: "G. Branden Robinson" 
Cc: Ralph Corderoy 
Cc: Dave Kemper 
Cc: Larry McVoy 
Cc: Andrew Pinski 
Cc: Jonathan Wakely 
Cc: Andrew Clayton 
Cc: Martin Uecker 
Cc: David Malcolm 
Cc: Mike Stump 
Cc: Joseph Myers 
Cc: Sandra Loosemore 
Signed-off-by: Alejandro Colomar 
---

Hi!

v6:
-  Small wording fix in c.opt
-  Document the option in invoke.texi

I tried again, but didn't find much alphabetic order  in there, so put
it where Mike suggested, after -Warray-bounds=n.

Have a lovely night!
Alex


Range-diff against v5:
1:  d98d1fec176 ! 1:  e8fd975bde7 C, ObjC: Add 
-Wunterminated-string-initialization
@@ gcc/c-family/c.opt: Wunsuffixed-float-constants
  
 +Wunterminated-string-initialization
 +C ObjC Var(warn_unterminated_string_initialization) Warning 
LangEnabledBy(C ObjC,Wextra || Wc++-compat)
-+Warn about character arrays initialized as unterminated character 
sequences by a string literal.
++Warn about character arrays initialized as unterminated character 
sequences with a string literal.
 +
  Wunused
  C ObjC C++ ObjC++ LangEnabledBy(C ObjC C++ ObjC++,Wall)
@@ gcc/c/c-typeck.cc: digest_init (location_t init_loc, tree type, tree 
init, tree
{
  unsigned HOST_WIDE_INT size
 
+ ## gcc/doc/invoke.texi ##
+@@ gcc/doc/invoke.texi: Objective-C and Objective-C++ Dialects}.
+ -Wsystem-headers  -Wtautological-compare  -Wtrampolines  -Wtrigraphs
+ -Wtrivial-auto-var-init -Wtsan -Wtype-limits  -Wundef
+ -Wuninitialized  -Wunknown-pragmas
+--Wunsuffixed-float-constants  -Wunused
++-Wunsuffixed-float-constants
++-Wunterminated-string-initialization
++-Wunused
+ -Wunused-but-set-parameter  -Wunused-but-set-variable
+ -Wunused-const-variable  -Wunused-const-variable=@var{n}
+ -Wunused-function  -Wunused-label  -Wunused-local-typedefs
+@@ gcc/doc/invoke.texi: name is still supported, but the newer name is 
more descriptive.)
+ -Wredundant-move @r{(only for C++)}
+ -Wtype-limits
+ -Wuninitialized
++-Wunterminated-string-initialization
+ -Wshift-negative-value @r{(in C++11 to C++17 and in C99 and newer)}
+ -Wunused-parameter @r{(only with} @option{-Wunused} @r{or} 
@option{-Wall}@r{)}
+ -Wunused-but-set-parameter @r{(only with} @option{-Wunused} @r{or} 
@option{-Wall}@r{)}}
+@@ gcc/doc/invoke.texi: arithmetic that may yield out of bounds values. 
This warning level may
+ give a larger number of false positives and is deactivated by default.
+ @end table
+ 
++@opindex Wunterminated-string-initialization
++@opindex Wno-unterminated-string-initialization
++@item -Wunterminated-string-initialization
++Warn about character arrays
++initialized as unterminated character sequences
++with a string literal.
++For example:
++
++@smallexample
++char arr[3] = "foo";
++@end smallexample
++
++@option{-Wunterminated-string-initialization} is enabled by 
@option{-Wextra}.
++
+ @opindex Warray-compare
+ @opindex Wno-array-compare
+ @item -Warray-compare
+
  ## gcc/testsuite/

Re: [PATCH v6] C, ObjC: Add -Wunterminated-string-initialization

2024-03-05 Thread Alejandro Colomar
On Tue, Mar 05, 2024 at 09:20:42PM +0100, Alejandro Colomar wrote:
> Hi!
> 
> v6:
> -  Small wording fix in c.opt
> -  Document the option in invoke.texi
> 
> I tried again, but didn't find much alphabetic order  in there, so put
> it where Mike suggested, after -Warray-bounds=n.
> 
> Have a lovely night!
> Alex
> 
[...]
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index 146b40414b0..f81df4de934 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -410,7 +410,9 @@ Objective-C and Objective-C++ Dialects}.
>  -Wsystem-headers  -Wtautological-compare  -Wtrampolines  -Wtrigraphs
>  -Wtrivial-auto-var-init -Wtsan -Wtype-limits  -Wundef
>  -Wuninitialized  -Wunknown-pragmas
> --Wunsuffixed-float-constants  -Wunused
> +-Wunsuffixed-float-constants
> +-Wunterminated-string-initialization
> +-Wunused
>  -Wunused-but-set-parameter  -Wunused-but-set-variable
>  -Wunused-const-variable  -Wunused-const-variable=@var{n}
>  -Wunused-function  -Wunused-label  -Wunused-local-typedefs
> @@ -6264,6 +6266,7 @@ name is still supported, but the newer name is more 
> descriptive.)
>  -Wredundant-move @r{(only for C++)}
>  -Wtype-limits
>  -Wuninitialized
> +-Wunterminated-string-initialization
>  -Wshift-negative-value @r{(in C++11 to C++17 and in C99 and newer)}
>  -Wunused-parameter @r{(only with} @option{-Wunused} @r{or} 
> @option{-Wall}@r{)}
>  -Wunused-but-set-parameter @r{(only with} @option{-Wunused} @r{or} 
> @option{-Wall}@r{)}}
> @@ -8281,6 +8284,20 @@ arithmetic that may yield out of bounds values. This 
> warning level may
>  give a larger number of false positives and is deactivated by default.
>  @end table
>  
> +@opindex Wunterminated-string-initialization
> +@opindex Wno-unterminated-string-initialization
> +@item -Wunterminated-string-initialization
> +Warn about character arrays
> +initialized as unterminated character sequences
> +with a string literal.
> +For example:
> +
> +@smallexample
> +char arr[3] = "foo";
> +@end smallexample
> +
> +@option{-Wunterminated-string-initialization} is enabled by @option{-Wextra}.

Oops, I should also mention -Wc++-compat here.


-- 
<https://www.alejandro-colomar.es/>
Looking for a remote C programming job at the moment.


signature.asc
Description: PGP signature


[PATCH v7] C, ObjC: Add -Wunterminated-string-initialization

2024-03-05 Thread Alejandro Colomar
Warn about the following:

char  s[3] = "foo";

Initializing a char array with a string literal of the same length as
the size of the array is usually a mistake.  Rarely is the case where
one wants to create a non-terminated character sequence from a string
literal.

In some cases, for writing faster code, one may want to use arrays
instead of pointers, since that removes the need for storing an array of
pointers apart from the strings themselves.

char  *log_levels[]   = { "info", "warning", "err" };
vs.
char  log_levels[][7] = { "info", "warning", "err" };

This forces the programmer to specify a size, which might change if a
new entry is later added.  Having no way to enforce null termination is
very dangerous, however, so it is useful to have a warning for this, so
that the compiler can make sure that the programmer didn't make any
mistakes.  This warning catches the bug above, so that the programmer
will be able to fix it and write:

char  log_levels[][8] = { "info", "warning", "err" };

This warning already existed as part of -Wc++-compat, but this patch
allows enabling it separately.  It is also included in -Wextra, since
it may not always be desired (when unterminated character sequences are
wanted), but it's likely to be desired in most cases.

Since Wc++-compat now includes this warning, the test has to be modified
to expect the text of the new warning too, in .

Link: <https://lists.gnu.org/archive/html/groff/2022-11/msg00059.html>
Link: <https://lists.gnu.org/archive/html/groff/2022-11/msg00063.html>
Link: 
<https://inbox.sourceware.org/gcc/36da94eb-1cac-5ae8-7fea-ec66160cf...@gmail.com/T/>
Acked-by: Doug McIlroy 
Cc: "G. Branden Robinson" 
Cc: Ralph Corderoy 
Cc: Dave Kemper 
Cc: Larry McVoy 
Cc: Andrew Pinski 
Cc: Jonathan Wakely 
Cc: Andrew Clayton 
Cc: Martin Uecker 
Cc: David Malcolm 
Cc: Mike Stump 
Cc: Joseph Myers 
Cc: Sandra Loosemore 
Signed-off-by: Alejandro Colomar 
---
Range-diff against v6:
1:  e8fd975bde7 ! 1:  c0f3ffcca7a C, ObjC: Add 
-Wunterminated-string-initialization
@@ gcc/doc/invoke.texi: arithmetic that may yield out of bounds values. 
This warnin
  
 +@opindex Wunterminated-string-initialization
 +@opindex Wno-unterminated-string-initialization
-+@item -Wunterminated-string-initialization
++@item -Wunterminated-string-initialization @r{(C and Objective-C only)}
 +Warn about character arrays
 +initialized as unterminated character sequences
 +with a string literal.
@@ gcc/doc/invoke.texi: arithmetic that may yield out of bounds values. 
This warnin
 +char arr[3] = "foo";
 +@end smallexample
 +
-+@option{-Wunterminated-string-initialization} is enabled by 
@option{-Wextra}.
++This warning is enabled by @option{-Wextra} and @option{-Wc++-compat}.
++In C++, such initializations are an error.
 +
  @opindex Warray-compare
  @opindex Wno-array-compare

 gcc/c-family/c.opt|  4 
 gcc/c/c-typeck.cc |  6 +++---
 gcc/doc/invoke.texi   | 20 ++-
 gcc/testsuite/gcc.dg/Wcxx-compat-14.c |  2 +-
 .../Wunterminated-string-initialization.c |  6 ++
 5 files changed, 33 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/Wunterminated-string-initialization.c

diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 44b9c862c14..3837021747b 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -1407,6 +1407,10 @@ Wunsuffixed-float-constants
 C ObjC Var(warn_unsuffixed_float_constants) Warning
 Warn about unsuffixed float constants.
 
+Wunterminated-string-initialization
+C ObjC Var(warn_unterminated_string_initialization) Warning LangEnabledBy(C 
ObjC,Wextra || Wc++-compat)
+Warn about character arrays initialized as unterminated character sequences 
with a string literal.
+
 Wunused
 C ObjC C++ ObjC++ LangEnabledBy(C ObjC C++ ObjC++,Wall)
 ; documented in common.opt
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index e55e887da14..7df9de819ed 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -8399,11 +8399,11 @@ digest_init (location_t init_loc, tree type, tree init, 
tree origtype,
pedwarn_init (init_loc, 0,
  ("initializer-string for array of %qT "
   "is too long"), typ1);
- else if (warn_cxx_compat
+ else if (warn_unterminated_string_initialization
   && compare_tree_int (TYPE_SIZE_UNIT (type), len) < 0)
-   warning_at (init_loc, OPT_Wc___compat,
+   warning_at (init_loc, OPT_Wunterminated_string_initialization,
("initializer-string for array of %qT "
-"i

[PATCH v8] C, ObjC: Add -Wunterminated-string-initialization

2024-03-06 Thread Alejandro Colomar
Warn about the following:

char  s[3] = "foo";

Initializing a char array with a string literal of the same length as
the size of the array is usually a mistake.  Rarely is the case where
one wants to create a non-terminated character sequence from a string
literal.

In some cases, for writing faster code, one may want to use arrays
instead of pointers, since that removes the need for storing an array of
pointers apart from the strings themselves.

char  *log_levels[]   = { "info", "warning", "err" };
vs.
char  log_levels[][7] = { "info", "warning", "err" };

This forces the programmer to specify a size, which might change if a
new entry is later added.  Having no way to enforce null termination is
very dangerous, however, so it is useful to have a warning for this, so
that the compiler can make sure that the programmer didn't make any
mistakes.  This warning catches the bug above, so that the programmer
will be able to fix it and write:

char  log_levels[][8] = { "info", "warning", "err" };

This warning already existed as part of -Wc++-compat, but this patch
allows enabling it separately.  It is also included in -Wextra, since
it may not always be desired (when unterminated character sequences are
wanted), but it's likely to be desired in most cases.

Since Wc++-compat now includes this warning, the test has to be modified
to expect the text of the new warning too, in .

gcc/c-family/ChangeLog:

* c.opt: Add -Wunterminated-string-initialization.

gcc/c/ChangeLog:

* c-typeck.cc (digest_init): Separate warnings about character
  arrays being initialized as unterminated character sequences
  with string literals, from -Wc++-compat, into a new warning,
  -Wunterminated-string-initialization.

gcc/ChangeLog:

* doc/invoke.texi: Document the new
  -Wunterminated-string-initialization.

gcc/testsuite/ChangeLog:

* gcc.dg/Wcxx-compat-14.c: Adapt the test to match the new text
  of the warning, which doesn't say anything about C++ anymore.
* gcc.dg/Wunterminated-string-initialization.c: New test.

Link: <https://lists.gnu.org/archive/html/groff/2022-11/msg00059.html>
Link: <https://lists.gnu.org/archive/html/groff/2022-11/msg00063.html>
Link: 
<https://inbox.sourceware.org/gcc/36da94eb-1cac-5ae8-7fea-ec66160cf...@gmail.com/T/>
Acked-by: Doug McIlroy 
[Sandra: The documentation parts of the patch are OK.]
Reviewed-by: Sandra Loosemore 
Cc: "G. Branden Robinson" 
Cc: Ralph Corderoy 
Cc: Dave Kemper 
Cc: Larry McVoy 
Cc: Andrew Pinski 
Cc: Jonathan Wakely 
Cc: Andrew Clayton 
Cc: Martin Uecker 
Cc: David Malcolm 
Cc: Mike Stump 
Cc: Joseph Myers 
Signed-off-by: Alejandro Colomar 
---

Hi!

I've added a changelog to the commit message, as requested by Sandra,
and noted her review.

Have a lovely day!
Alex


Range-diff against v7:
1:  c0f3ffcca7a ! 1:  06236d0aa05 C, ObjC: Add 
-Wunterminated-string-initialization
@@ Commit message
 Since Wc++-compat now includes this warning, the test has to be 
modified
 to expect the text of the new warning too, in 
.
 
+gcc/c-family/ChangeLog:
+
+* c.opt: Add -Wunterminated-string-initialization.
+
+gcc/c/ChangeLog:
+
+* c-typeck.cc (digest_init): Separate warnings about character
+  arrays being initialized as unterminated character sequences
+  with string literals, from -Wc++-compat, into a new warning,
+  -Wunterminated-string-initialization.
+
+gcc/ChangeLog:
+
+* doc/invoke.texi: Document the new
+  -Wunterminated-string-initialization.
+
+gcc/testsuite/ChangeLog:
+
+* gcc.dg/Wcxx-compat-14.c: Adapt the test to match the new text
+  of the warning, which doesn't say anything about C++ anymore.
+* gcc.dg/Wunterminated-string-initialization.c: New test.
+
 Link: <https://lists.gnu.org/archive/html/groff/2022-11/msg00059.html>
 Link: <https://lists.gnu.org/archive/html/groff/2022-11/msg00063.html>
 Link: 
<https://inbox.sourceware.org/gcc/36da94eb-1cac-5ae8-7fea-ec66160cf...@gmail.com/T/>
 Acked-by: Doug McIlroy 
+[Sandra: The documentation parts of the patch are OK.]
+Reviewed-by: Sandra Loosemore 
 Cc: "G. Branden Robinson" 
 Cc: Ralph Corderoy 
     Cc: Dave Kemper 
@@ Commit message
 Cc: David Malcolm 
 Cc: Mike Stump 
 Cc: Joseph Myers 
-Cc: Sandra Loosemore 
 Signed-off-by: Alejandro Colomar 
 
  ## gcc/c-family/c.opt ##

 gcc/c-family/c.opt|  4 
 gcc/c/c-typeck.cc |  6 +++-

[PATCH v5 RESEND] C, ObjC: Add -Wunterminated-string-initialization

2024-02-06 Thread Alejandro Colomar
Warn about the following:

char  s[3] = "foo";

Initializing a char array with a string literal of the same length as
the size of the array is usually a mistake.  Rarely is the case where
one wants to create a non-terminated character sequence from a string
literal.

In some cases, for writing faster code, one may want to use arrays
instead of pointers, since that removes the need for storing an array of
pointers apart from the strings themselves.

char  *log_levels[]   = { "info", "warning", "err" };
vs.
char  log_levels[][7] = { "info", "warning", "err" };

This forces the programmer to specify a size, which might change if a
new entry is later added.  Having no way to enforce null termination is
very dangerous, however, so it is useful to have a warning for this, so
that the compiler can make sure that the programmer didn't make any
mistakes.  This warning catches the bug above, so that the programmer
will be able to fix it and write:

char  log_levels[][8] = { "info", "warning", "err" };

This warning already existed as part of -Wc++-compat, but this patch
allows enabling it separately.  It is also included in -Wextra, since
it may not always be desired (when unterminated character sequences are
wanted), but it's likely to be desired in most cases.

Since Wc++-compat now includes this warning, the test has to be modified
to expect the text of the new warning too, in .

Link: <https://lists.gnu.org/archive/html/groff/2022-11/msg00059.html>
Link: <https://lists.gnu.org/archive/html/groff/2022-11/msg00063.html>
Link: 
<https://inbox.sourceware.org/gcc/36da94eb-1cac-5ae8-7fea-ec66160cf...@gmail.com/T/>
Acked-by: Doug McIlroy 
Cc: "G. Branden Robinson" 
Cc: Ralph Corderoy 
Cc: Dave Kemper 
Cc: Larry McVoy 
Cc: Andrew Pinski 
Cc: Jonathan Wakely 
Cc: Andrew Clayton 
Cc: Martin Uecker 
Cc: David Malcolm 
Signed-off-by: Alejandro Colomar 
---

v5:

-  Fix existing C++-compat tests.  [reported by ]


 gcc/c-family/c.opt | 4 
 gcc/c/c-typeck.cc  | 6 +++---
 gcc/testsuite/gcc.dg/Wcxx-compat-14.c  | 2 +-
 gcc/testsuite/gcc.dg/Wunterminated-string-initialization.c | 6 ++
 4 files changed, 14 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/Wunterminated-string-initialization.c

diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 44b9c862c14..e8f6b836836 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -1407,6 +1407,10 @@ Wunsuffixed-float-constants
 C ObjC Var(warn_unsuffixed_float_constants) Warning
 Warn about unsuffixed float constants.
 
+Wunterminated-string-initialization
+C ObjC Var(warn_unterminated_string_initialization) Warning LangEnabledBy(C 
ObjC,Wextra || Wc++-compat)
+Warn about character arrays initialized as unterminated character sequences by 
a string literal.
+
 Wunused
 C ObjC C++ ObjC++ LangEnabledBy(C ObjC C++ ObjC++,Wall)
 ; documented in common.opt
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index e55e887da14..7df9de819ed 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -8399,11 +8399,11 @@ digest_init (location_t init_loc, tree type, tree init, 
tree origtype,
pedwarn_init (init_loc, 0,
  ("initializer-string for array of %qT "
   "is too long"), typ1);
- else if (warn_cxx_compat
+ else if (warn_unterminated_string_initialization
   && compare_tree_int (TYPE_SIZE_UNIT (type), len) < 0)
-   warning_at (init_loc, OPT_Wc___compat,
+   warning_at (init_loc, OPT_Wunterminated_string_initialization,
("initializer-string for array of %qT "
-"is too long for C++"), typ1);
+"is too long"), typ1);
  if (compare_tree_int (TYPE_SIZE_UNIT (type), len) < 0)
{
  unsigned HOST_WIDE_INT size
diff --git a/gcc/testsuite/gcc.dg/Wcxx-compat-14.c 
b/gcc/testsuite/gcc.dg/Wcxx-compat-14.c
index 23783711be6..6df0ee197cc 100644
--- a/gcc/testsuite/gcc.dg/Wcxx-compat-14.c
+++ b/gcc/testsuite/gcc.dg/Wcxx-compat-14.c
@@ -2,5 +2,5 @@
 /* { dg-options "-Wc++-compat" } */
 
 char a1[] = "a";
-char a2[1] = "a";  /* { dg-warning "C\[+\]\[+\]" } */
+char a2[1] = "a";  /* { dg-warning "initializer-string for array of 'char' 
is too long" } */
 char a3[2] = "a";
diff --git a/gcc/testsuite/gcc.dg/Wunterminated-string-initialization.c 
b/gcc/testsuite/gcc.dg/Wunterminated-string-initialization.c
new file mode 100644
index 000..13d5dbc6640
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wunter

Re: [PATCH v5 RESEND] C, ObjC: Add -Wunterminated-string-initialization

2024-02-25 Thread Alejandro Colomar
Hi Mike, Joseph,

On Sun, Feb 25, 2024 at 10:10:09AM -0800, Mike Stump wrote:
> On Feb 6, 2024, at 2:45 AM, Alejandro Colomar  wrote:
> > 
> > Warn about the following:
> > 
> >char  s[3] = "foo";
> 
> No ObjC specific impact here, so no need for ObjC review.
> 
> As a member of the peanut gallery, I like the patch.
> 
> Joseph, this is been submitted 5 times over the past year.  Any thoughts?

Thanks!  BTW, I'd like to know if I did anything wrong so that it wasn't
reviewed in all this time, or if it's just that everyone was busy doing
other stuff.  Do you prefer if I ping more often?  Or something else?

Have a lovely day!
Alex

-- 
<https://www.alejandro-colomar.es/>
Looking for a remote C programming job at the moment.


signature.asc
Description: PGP signature


Re: [PATCH v5 RESEND] C, ObjC: Add -Wunterminated-string-initialization

2024-02-26 Thread Alejandro Colomar
Hi Joseph,

On Mon, Feb 26, 2024 at 03:24:32PM +, Joseph Myers wrote:
> On Sun, 25 Feb 2024, Mike Stump wrote:
> 
> > On Feb 6, 2024, at 2:45 AM, Alejandro Colomar  wrote:
> > > 
> > > Warn about the following:
> > > 
> > >char  s[3] = "foo";
> > 
> > No ObjC specific impact here, so no need for ObjC review.
> > 
> > As a member of the peanut gallery, I like the patch.
> > 
> > Joseph, this is been submitted 5 times over the past year.  Any thoughts?
> 
> The idea seems reasonable, but the patch needs documentation for the new 
> option in invoke.texi.

Thanks!  Will do.

I don't see an obvious order in that file.  Where would you put the
option?  Do you want me to sort(1) it first, and then insert the new
option in alphabetic order?

$ man gcc 2>/dev/null | grep -e '^ \{0,3\}[^ ]' -e '^ \{4,7\}-' | sed -n '/^ 
\{1,3\}Options to Request or Suppress Warnings/,/^ \{1,3\}[^ ]/p'
   Options to Request or Suppress Warnings
 -fsyntax-only
 -fmax-errors=n
 -w  Inhibit all warning messages.
 -Werror
 -Werror=
 -Wfatal-errors
 -Wno- options with old compilers, but if something goes wrong, the 
compiler warns that an unrecognized option is present.
 -Wpedantic
 -pedantic
 -pedantic-errors
 -Wall
 -Wextra
 -Wabi (C, Objective‐C, C++ and Objective-C++ only)
 -Wno-changes-meaning (C++ and Objective-C++ only)
 -Wchar-subscripts
 -Wno-coverage-mismatch
 -Wno-coverage-invalid-line-number
 -Wno-cpp (C, Objective‐C, C++, Objective-C++ and Fortran only)
 -Wdouble-promotion (C, C++, Objective‐C and Objective-C++ only)
 -Wduplicate-decl-specifier (C and Objective‐C only)
 -Wformat
 -Wformat=n
 -Wno-format-contains-nul
 -Wno-format-extra-args
 -Wformat-overflow
 -Wformat-overflow=level
 -Wno-format-zero-length
 -Wformat-nonliteral
 -Wformat-security
 -Wformat-signedness
 -Wformat-truncation
 -Wformat-truncation=level
 -Wformat-y2k
 -Wnonnull
 -Wnonnull-compare
 -Wnull-dereference
 -Winfinite-recursion
 -Winit-self (C, C++, Objective‐C and Objective-C++ only)
 -Wno-implicit-int (C and Objective‐C only)
 -Wno-implicit-function-declaration (C and Objective‐C only)
 -Wimplicit (C and Objective‐C only)
 -Wimplicit-fallthrough
 -Wimplicit-fallthrough=n
 -Wno-if-not-aligned (C, C++, Objective‐C and Objective-C++ only)
 -Wignored-qualifiers (C and C++ only)
 -Wno-ignored-attributes (C and C++ only)
 -Wmain
 -Wmisleading-indentation (C and C++ only)
 -Wmissing-attributes
 -Wmissing-braces
 -Wmissing-include-dirs (C, C++, Objective‐C, Objective-C++ and Fortran 
only)
 -Wno-missing-profile
 -Wmismatched-dealloc
 -Wmultistatement-macros
 -Wparentheses
 -Wno-self-move (C++ and Objective-C++ only)
 -Wsequence-point
 -Wno-return-local-addr
 -Wreturn-type
 -Wno-shift-count-negative
 -Wno-shift-count-overflow
 -Wshift-negative-value
 -Wno-shift-overflow
 -Wshift-overflow=n
 -Wswitch
 -Wswitch-default
 -Wswitch-enum
 -Wno-switch-bool
 -Wno-switch-outside-range
 -Wno-switch-unreachable
 -Wsync-nand (C and C++ only)
 -Wtrivial-auto-var-init
 -Wunused-but-set-parameter
 -Wunused-but-set-variable
 -Wunused-function
 -Wunused-label
 -Wunused-local-typedefs (C, Objective‐C, C++ and Objective-C++ only)
 -Wunused-parameter
 -Wno-unused-result
 -Wunused-variable
 -Wunused-const-variable
 -Wunused-const-variable=n
 -Wunused-value
 -Wunused
 -Wuninitialized
 -Wno-invalid-memory-model
 -Wmaybe-uninitialized
 -Wunknown-pragmas
 -Wno-pragmas
 -Wno-prio-ctor-dtor
 -Wstrict-aliasing
 -Wstrict-aliasing=n
 -Wstrict-overflow
 -Wstrict-overflow=n
 -Wstring-compare
 -Wno-stringop-overflow
 -Wstringop-overflow
 -Wstringop-overflow=type
 -Wno-stringop-overread
 -Wno-stringop-truncation
 -Wstrict-flex-arrays
 -Wsuggest-attribute=[pure|const|noreturn|format|cold|malloc]
 -Walloc-zero
 -Walloc-size-larger-than=byte‐size
 -Wno-alloc-size-larger-than
 -Walloca
 -Walloca-larger-than=byte‐size
 -Wno-alloca-larger-than
 -Warith-conversion
 -Warray-bounds
 -Warray-bounds=n
 -Warray-compare
 -Warray-parameter
 -Warray-parameter=n
 -Wattribute-alias=n
 -Wno-attribute-alias
 -Wbidi-chars=[none|unpaired|any|ucn]
 -Wbool-compare
 -Wbool-operation
 -Wduplicated-branches
 -Wduplicated-cond
 -Wframe-address
 -Wno-discarded-qualifiers (C and Objective‐C only)
 -Wno-discarded-array-qualifiers (C and Objective‐C only)
 -Wno-incompatible-pointer-types (C and Objective‐C only)
 -Wno-int-conversion (C and Objective‐C only)
 -Wzero-length-b

Re: [PATCH v5] C, ObjC: Add -Wunterminated-string-initialization

2023-11-13 Thread Alejandro Colomar
Hi,

Gentle ping, just again a little before v14 stage 3.

Do I need to do anything else with this patch?  The CI seemed to say
it's ok.

Cheers,
Alex

On Sun, Oct 01, 2023 at 06:24:00PM +0200, Alejandro Colomar wrote:
> Warn about the following:
> 
> char  s[3] = "foo";
> 
> Initializing a char array with a string literal of the same length as
> the size of the array is usually a mistake.  Rarely is the case where
> one wants to create a non-terminated character sequence from a string
> literal.
> 
> In some cases, for writing faster code, one may want to use arrays
> instead of pointers, since that removes the need for storing an array of
> pointers apart from the strings themselves.
> 
> char  *log_levels[]   = { "info", "warning", "err" };
> vs.
> char  log_levels[][7] = { "info", "warning", "err" };
> 
> This forces the programmer to specify a size, which might change if a
> new entry is later added.  Having no way to enforce null termination is
> very dangerous, however, so it is useful to have a warning for this, so
> that the compiler can make sure that the programmer didn't make any
> mistakes.  This warning catches the bug above, so that the programmer
> will be able to fix it and write:
> 
> char  log_levels[][8] = { "info", "warning", "err" };
> 
> This warning already existed as part of -Wc++-compat, but this patch
> allows enabling it separately.  It is also included in -Wextra, since
> it may not always be desired (when unterminated character sequences are
> wanted), but it's likely to be desired in most cases.
> 
> Since Wc++-compat now includes this warning, the test has to be modified
> to expect the text of the new warning too, in .
> 
> Link: <https://lists.gnu.org/archive/html/groff/2022-11/msg00059.html>
> Link: <https://lists.gnu.org/archive/html/groff/2022-11/msg00063.html>
> Link: 
> <https://inbox.sourceware.org/gcc/36da94eb-1cac-5ae8-7fea-ec66160cf...@gmail.com/T/>
> Acked-by: Doug McIlroy 
> Cc: "G. Branden Robinson" 
> Cc: Ralph Corderoy 
> Cc: Dave Kemper 
> Cc: Larry McVoy 
> Cc: Andrew Pinski 
> Cc: Jonathan Wakely 
> Cc: Andrew Clayton 
> Cc: Martin Uecker 
> Cc: David Malcolm 
> Signed-off-by: Alejandro Colomar 
> ---
> 
> v5:
> 
> -  Fix existing C++-compat tests.  [reported by ]
> 
> 
>  gcc/c-family/c.opt | 4 
>  gcc/c/c-typeck.cc  | 6 +++---
>  gcc/testsuite/gcc.dg/Wcxx-compat-14.c  | 2 +-
>  gcc/testsuite/gcc.dg/Wunterminated-string-initialization.c | 6 ++
>  4 files changed, 14 insertions(+), 4 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/Wunterminated-string-initialization.c
> 
> diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
> index 44b9c862c14..e8f6b836836 100644
> --- a/gcc/c-family/c.opt
> +++ b/gcc/c-family/c.opt
> @@ -1407,6 +1407,10 @@ Wunsuffixed-float-constants
>  C ObjC Var(warn_unsuffixed_float_constants) Warning
>  Warn about unsuffixed float constants.
>  
> +Wunterminated-string-initialization
> +C ObjC Var(warn_unterminated_string_initialization) Warning LangEnabledBy(C 
> ObjC,Wextra || Wc++-compat)
> +Warn about character arrays initialized as unterminated character sequences 
> by a string literal.
> +
>  Wunused
>  C ObjC C++ ObjC++ LangEnabledBy(C ObjC C++ ObjC++,Wall)
>  ; documented in common.opt
> diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
> index e55e887da14..7df9de819ed 100644
> --- a/gcc/c/c-typeck.cc
> +++ b/gcc/c/c-typeck.cc
> @@ -8399,11 +8399,11 @@ digest_init (location_t init_loc, tree type, tree 
> init, tree origtype,
>   pedwarn_init (init_loc, 0,
> ("initializer-string for array of %qT "
>  "is too long"), typ1);
> -   else if (warn_cxx_compat
> +   else if (warn_unterminated_string_initialization
>  && compare_tree_int (TYPE_SIZE_UNIT (type), len) < 0)
> - warning_at (init_loc, OPT_Wc___compat,
> + warning_at (init_loc, OPT_Wunterminated_string_initialization,
>   ("initializer-string for array of %qT "
> -  "is too long for C++"), typ1);
> +  "is too long"), typ1);
> if (compare_tree_int (TYPE_SIZE_UNIT (type), len) < 0)
>   {
> unsigned HOST_WIDE_INT size
> diff --git a/gcc/testsuite/gcc.dg/Wcxx-compat-14.c 
> b/gcc/testsuite/gcc.

[PATCH v9] C, ObjC: Add -Wunterminated-string-initialization

2024-06-29 Thread Alejandro Colomar
Warn about the following:

char  s[3] = "foo";

Initializing a char array with a string literal of the same length as
the size of the array is usually a mistake.  Rarely is the case where
one wants to create a non-terminated character sequence from a string
literal.

In some cases, for writing faster code, one may want to use arrays
instead of pointers, since that removes the need for storing an array of
pointers apart from the strings themselves.

char  *log_levels[]   = { "info", "warning", "err" };
vs.
char  log_levels[][7] = { "info", "warning", "err" };

This forces the programmer to specify a size, which might change if a
new entry is later added.  Having no way to enforce null termination is
very dangerous, however, so it is useful to have a warning for this, so
that the compiler can make sure that the programmer didn't make any
mistakes.  This warning catches the bug above, so that the programmer
will be able to fix it and write:

char  log_levels[][8] = { "info", "warning", "err" };

This warning already existed as part of -Wc++-compat, but this patch
allows enabling it separately.  It is also included in -Wextra, since
it may not always be desired (when unterminated character sequences are
wanted), but it's likely to be desired in most cases.

Since Wc++-compat now includes this warning, the test has to be modified
to expect the text of the new warning too, in .

gcc/c-family/ChangeLog:

* c.opt: Add -Wunterminated-string-initialization.

gcc/c/ChangeLog:

* c-typeck.cc (digest_init): Separate warnings about character
  arrays being initialized as unterminated character sequences
  with string literals, from -Wc++-compat, into a new warning,
  -Wunterminated-string-initialization.

gcc/ChangeLog:

* doc/invoke.texi: Document the new
  -Wunterminated-string-initialization.

gcc/testsuite/ChangeLog:

* gcc.dg/Wcxx-compat-14.c: Adapt the test to match the new text
  of the warning, which doesn't say anything about C++ anymore.
* gcc.dg/Wunterminated-string-initialization.c: New test.

Link: <https://lists.gnu.org/archive/html/groff/2022-11/msg00059.html>
Link: <https://lists.gnu.org/archive/html/groff/2022-11/msg00063.html>
Link: 
<https://inbox.sourceware.org/gcc/36da94eb-1cac-5ae8-7fea-ec66160cf...@gmail.com/T/>
Closes: <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115185>
Acked-by: Doug McIlroy 
[Sandra: The documentation parts of the patch are OK.]
Reviewed-by: Sandra Loosemore 
Reviewed-by: Martin Uecker 
Cc: "G. Branden Robinson" 
Cc: Ralph Corderoy 
Cc: Dave Kemper 
Cc: Larry McVoy 
Cc: Andrew Pinski 
Cc: Jonathan Wakely 
Cc: Andrew Clayton 
Cc: David Malcolm 
Cc: Mike Stump 
Cc: Joseph Myers 
Cc: Konstantin Kharlamov 
Signed-off-by: Alejandro Colomar 
---

Hi!

Here's another round of this patch.

v9 changes:

-  Reviewed by Martin.
-  Add link to related bugzilla bug (and CC its reporter).
-  Rebase on top of git master.

See full range-diff below.

Have a lovely day,
Alex

P.S.: I'm looking for a job; if anyone is interested, please contact me.

Range-diff against v8:
1:  06236d0aa05 ! 1:  1010e7d7ec2 C, ObjC: Add 
-Wunterminated-string-initialization
@@ Commit message
 Link: <https://lists.gnu.org/archive/html/groff/2022-11/msg00059.html>
 Link: <https://lists.gnu.org/archive/html/groff/2022-11/msg00063.html>
 Link: 
<https://inbox.sourceware.org/gcc/36da94eb-1cac-5ae8-7fea-ec66160cf...@gmail.com/T/>
+Closes: <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115185>
 Acked-by: Doug McIlroy 
 [Sandra: The documentation parts of the patch are OK.]
 Reviewed-by: Sandra Loosemore 
+Reviewed-by: Martin Uecker 
 Cc: "G. Branden Robinson" 
 Cc: Ralph Corderoy 
 Cc: Dave Kemper 
@@ Commit message
 Cc: Andrew Pinski 
 Cc: Jonathan Wakely 
     Cc: Andrew Clayton 
-Cc: Martin Uecker 
 Cc: David Malcolm 
 Cc: Mike Stump 
 Cc: Joseph Myers 
+Cc: Konstantin Kharlamov 
 Signed-off-by: Alejandro Colomar 
 
  ## gcc/c-family/c.opt ##
@@ gcc/c/c-typeck.cc: digest_init (location_t init_loc, tree type, tree 
init, tree
  ## gcc/doc/invoke.texi ##
 @@ gcc/doc/invoke.texi: Objective-C and Objective-C++ Dialects}.
  -Wsystem-headers  -Wtautological-compare  -Wtrampolines  -Wtrigraphs
- -Wtrivial-auto-var-init -Wtsan -Wtype-limits  -Wundef
+ -Wtrivial-auto-var-init  -Wno-tsan  -Wtype-limits  -Wundef
  -Wuninitialized  -Wunknown-pragmas
 --Wunsuffixed-float-constants  -Wunused
 +-Wunsuffixed-float-constants
@@ gcc/doc/invoke.texi: Objective-C and Objective-C++ Dialects}.
  -Wunused-const-variable  -Wunused-const-variabl

Re: [PATCH v9] C, ObjC: Add -Wunterminated-string-initialization

2024-06-29 Thread Alejandro Colomar
On Sat, Jun 29, 2024 at 02:52:40PM GMT, Alejandro Colomar wrote:
> Warn about the following:
> 
> char  s[3] = "foo";
> 
> Initializing a char array with a string literal of the same length as
> the size of the array is usually a mistake.  Rarely is the case where
> one wants to create a non-terminated character sequence from a string
> literal.
> 
> In some cases, for writing faster code, one may want to use arrays
> instead of pointers, since that removes the need for storing an array of
> pointers apart from the strings themselves.
> 
> char  *log_levels[]   = { "info", "warning", "err" };
> vs.
> char  log_levels[][7] = { "info", "warning", "err" };
> 
> This forces the programmer to specify a size, which might change if a
> new entry is later added.  Having no way to enforce null termination is
> very dangerous, however, so it is useful to have a warning for this, so
> that the compiler can make sure that the programmer didn't make any
> mistakes.  This warning catches the bug above, so that the programmer
> will be able to fix it and write:
> 
> char  log_levels[][8] = { "info", "warning", "err" };
> 
> This warning already existed as part of -Wc++-compat, but this patch
> allows enabling it separately.  It is also included in -Wextra, since
> it may not always be desired (when unterminated character sequences are
> wanted), but it's likely to be desired in most cases.
> 
> Since Wc++-compat now includes this warning, the test has to be modified
> to expect the text of the new warning too, in .
> 
> gcc/c-family/ChangeLog:
> 
>   * c.opt: Add -Wunterminated-string-initialization.
> 
> gcc/c/ChangeLog:
> 
>   * c-typeck.cc (digest_init): Separate warnings about character
> arrays being initialized as unterminated character sequences
> with string literals, from -Wc++-compat, into a new warning,
> -Wunterminated-string-initialization.
> 
> gcc/ChangeLog:
> 
>   * doc/invoke.texi: Document the new
> -Wunterminated-string-initialization.
> 
> gcc/testsuite/ChangeLog:
> 
>   * gcc.dg/Wcxx-compat-14.c: Adapt the test to match the new text
> of the warning, which doesn't say anything about C++ anymore.
>   * gcc.dg/Wunterminated-string-initialization.c: New test.
> 
> Link: <https://lists.gnu.org/archive/html/groff/2022-11/msg00059.html>
> Link: <https://lists.gnu.org/archive/html/groff/2022-11/msg00063.html>
> Link: 
> <https://inbox.sourceware.org/gcc/36da94eb-1cac-5ae8-7fea-ec66160cf...@gmail.com/T/>
> Closes: <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115185>
> Acked-by: Doug McIlroy 
> [Sandra: The documentation parts of the patch are OK.]
> Reviewed-by: Sandra Loosemore 
> Reviewed-by: Martin Uecker 
> Cc: "G. Branden Robinson" 
> Cc: Ralph Corderoy 
> Cc: Dave Kemper 
> Cc: Larry McVoy 
> Cc: Andrew Pinski 
> Cc: Jonathan Wakely 
> Cc: Andrew Clayton 
> Cc: David Malcolm 
> Cc: Mike Stump 
> Cc: Joseph Myers 
> Cc: Konstantin Kharlamov 
> Signed-off-by: Alejandro Colomar 
> ---
> 
> Hi!
> 
> Here's another round of this patch.
> 
> v9 changes:
> 
> -  Reviewed by Martin.
> -  Add link to related bugzilla bug (and CC its reporter).
> -  Rebase on top of git master.
> 
> See full range-diff below.
> 
> Have a lovely day,
> Alex
> 
> P.S.: I'm looking for a job; if anyone is interested, please contact me.
> 
> Range-diff against v8:
> 1:  06236d0aa05 ! 1:  1010e7d7ec2 C, ObjC: Add 
> -Wunterminated-string-initialization
> @@ Commit message
>  Link: 
> <https://lists.gnu.org/archive/html/groff/2022-11/msg00059.html>
>  Link: 
> <https://lists.gnu.org/archive/html/groff/2022-11/msg00063.html>
>  Link: 
> <https://inbox.sourceware.org/gcc/36da94eb-1cac-5ae8-7fea-ec66160cf...@gmail.com/T/>
> +Closes: <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115185>
>  Acked-by: Doug McIlroy 
>  [Sandra: The documentation parts of the patch are OK.]
>  Reviewed-by: Sandra Loosemore 
> +Reviewed-by: Martin Uecker 
>  Cc: "G. Branden Robinson" 
>  Cc: Ralph Corderoy 
>  Cc: Dave Kemper 
> @@ Commit message
>  Cc: Andrew Pinski 
>  Cc: Jonathan Wakely 
>  Cc: Andrew Clayton 
> -Cc: Martin Uecker 
>  Cc: David Malcolm 
>  Cc: Mike Stump 
>  Cc: Joseph Myers 
> +Cc: Konstantin Kharlamov 
>  Signed-off-by: Alejandro Colom

Re: [PATCH v9] C, ObjC: Add -Wunterminated-string-initialization

2024-06-29 Thread Alejandro Colomar
On Sat, Jun 29, 2024 at 02:58:48PM GMT, Alejandro Colomar wrote:
> On Sat, Jun 29, 2024 at 02:52:40PM GMT, Alejandro Colomar wrote:
> > @@ -6450,6 +6452,8 @@ name is still supported, but the newer name is more 
> > descriptive.)
> >  -Wstring-compare
> >  -Wtype-limits
> >  -Wuninitialized
> > +-Wshift-negative-value @r{(in C++11 to C++17 and in C99 and newer)}
> > +-Wunterminated-string-initialization
> 
> Whoops; while in the rebase resolution of conflicts this seemed to
> be an addition from elsewhere.  I didn't intend to add it here.  I'll
> fix that, and send a v10.  I'll investigate how this line appeared.

Ahhh; it seems that line had been removed, not added, somewhere between
my v8 and v9.  I misunderstood the git conflict.

> 
> >  -Wunused-parameter @r{(only with} @option{-Wunused} @r{or} 
> > @option{-Wall}@r{)}
> >  -Wunused-but-set-parameter @r{(only with} @option{-Wunused} @r{or} 
> > @option{-Wall}@r{)}}


-- 
<https://www.alejandro-colomar.es/>


signature.asc
Description: PGP signature


[PATCH v10] C, ObjC: Add -Wunterminated-string-initialization

2024-06-29 Thread Alejandro Colomar
Warn about the following:

char  s[3] = "foo";

Initializing a char array with a string literal of the same length as
the size of the array is usually a mistake.  Rarely is the case where
one wants to create a non-terminated character sequence from a string
literal.

In some cases, for writing faster code, one may want to use arrays
instead of pointers, since that removes the need for storing an array of
pointers apart from the strings themselves.

char  *log_levels[]   = { "info", "warning", "err" };
vs.
char  log_levels[][7] = { "info", "warning", "err" };

This forces the programmer to specify a size, which might change if a
new entry is later added.  Having no way to enforce null termination is
very dangerous, however, so it is useful to have a warning for this, so
that the compiler can make sure that the programmer didn't make any
mistakes.  This warning catches the bug above, so that the programmer
will be able to fix it and write:

char  log_levels[][8] = { "info", "warning", "err" };

This warning already existed as part of -Wc++-compat, but this patch
allows enabling it separately.  It is also included in -Wextra, since
it may not always be desired (when unterminated character sequences are
wanted), but it's likely to be desired in most cases.

Since Wc++-compat now includes this warning, the test has to be modified
to expect the text of the new warning too, in .

gcc/c-family/ChangeLog:

* c.opt: Add -Wunterminated-string-initialization.

gcc/c/ChangeLog:

* c-typeck.cc (digest_init): Separate warnings about character
  arrays being initialized as unterminated character sequences
  with string literals, from -Wc++-compat, into a new warning,
  -Wunterminated-string-initialization.

gcc/ChangeLog:

* doc/invoke.texi: Document the new
  -Wunterminated-string-initialization.

gcc/testsuite/ChangeLog:

* gcc.dg/Wcxx-compat-14.c: Adapt the test to match the new text
  of the warning, which doesn't say anything about C++ anymore.
* gcc.dg/Wunterminated-string-initialization.c: New test.

Link: <https://lists.gnu.org/archive/html/groff/2022-11/msg00059.html>
Link: <https://lists.gnu.org/archive/html/groff/2022-11/msg00063.html>
Link: 
<https://inbox.sourceware.org/gcc/36da94eb-1cac-5ae8-7fea-ec66160cf...@gmail.com/T/>
Closes: <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115185>
Acked-by: Doug McIlroy 
Acked-by: Mike Stump 
[Sandra: The documentation parts of the patch are OK.]
Reviewed-by: Sandra Loosemore 
Reviewed-by: Martin Uecker 
Cc: "G. Branden Robinson" 
Cc: Ralph Corderoy 
Cc: Dave Kemper 
Cc: Larry McVoy 
Cc: Andrew Pinski 
Cc: Jonathan Wakely 
Cc: Andrew Clayton 
Cc: David Malcolm 
Cc: Joseph Myers 
Cc: Konstantin Kharlamov 
Signed-off-by: Alejandro Colomar 
---

Hi!

v10 changes:

-  Fix accident introduced while fixing rebase conflict in v9.
-  Upgrade an informal "As a member of the peanut gallery, I like the
   patch." into an Acked-by: Mike Stump .

See full range-diff below.

Have a lovely day!
Alex


Range-diff against v9:
1:  1010e7d7ec2 ! 1:  5a567664d7c C, ObjC: Add 
-Wunterminated-string-initialization
@@ Commit message
 Link: 
<https://inbox.sourceware.org/gcc/36da94eb-1cac-5ae8-7fea-ec66160cf...@gmail.com/T/>
 Closes: <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115185>
 Acked-by: Doug McIlroy 
+Acked-by: Mike Stump 
 [Sandra: The documentation parts of the patch are OK.]
 Reviewed-by: Sandra Loosemore 
 Reviewed-by: Martin Uecker 
@@ Commit message
 Cc: Jonathan Wakely 
     Cc: Andrew Clayton 
 Cc: David Malcolm 
-Cc: Mike Stump 
 Cc: Joseph Myers 
 Cc: Konstantin Kharlamov 
 Signed-off-by: Alejandro Colomar 
@@ gcc/doc/invoke.texi: name is still supported, but the newer name is more 
descrip
  -Wstring-compare
  -Wtype-limits
  -Wuninitialized
-+-Wshift-negative-value @r{(in C++11 to C++17 and in C99 and newer)}
 +-Wunterminated-string-initialization
  -Wunused-parameter @r{(only with} @option{-Wunused} @r{or} 
@option{-Wall}@r{)}
  -Wunused-but-set-parameter @r{(only with} @option{-Wunused} @r{or} 
@option{-Wall}@r{)}}

 gcc/c-family/c.opt|  4 
 gcc/c/c-typeck.cc |  6 +++---
 gcc/doc/invoke.texi   | 20 ++-
 gcc/testsuite/gcc.dg/Wcxx-compat-14.c |  2 +-
 .../Wunterminated-string-initialization.c |  6 ++
 5 files changed, 33 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/Wunterminated-string-initialization.c

diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 864ef4e3b3d..c2e43fe13de 100644
--- a/gcc/c-family/c.

[PATCH] doc: Document -fasm as the opposite of -fno-asm

2024-07-01 Thread Alejandro Colomar
gcc/ChangeLog:

* doc/invoke.texi: Document -fasm.

Signed-off-by: Alejandro Colomar 
---
 gcc/doc/invoke.texi | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 30c4b002d1f..2d55f2715b3 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -198,7 +198,7 @@ in the following sections.
 @item C Language Options
 @xref{C Dialect Options,,Options Controlling C Dialect}.
 @gccoptlist{-ansi  -std=@var{standard}  -aux-info @var{filename}
--fno-asm
+-f@r{[}no-@r{]}asm
 -fno-builtin  -fno-builtin-@var{function}  -fcond-mismatch
 -ffreestanding  -fgimple  -fgnu-tm  -fgnu89-inline  -fhosted
 -flax-vector-conversions  -fms-extensions
@@ -2600,8 +2600,8 @@ comments, after the declaration.
 
 @opindex fno-asm
 @opindex fasm
-@item -fno-asm
-Do not recognize @code{asm}, @code{inline} or @code{typeof} as a
+@item -f@r{[}no-@r{]}asm
+Do (or do not) recognize @code{asm}, @code{inline} or @code{typeof} as a
 keyword, so that code can use these words as identifiers.  You can use
 the keywords @code{__asm__}, @code{__inline__} and @code{__typeof__}
 instead.  In C, @option{-ansi} implies @option{-fno-asm}.
-- 
2.45.2



signature.asc
Description: PGP signature


Re: [PATCH] doc: Document -fasm as the opposite of -fno-asm

2024-07-01 Thread Alejandro Colomar
On Mon, Jul 01, 2024 at 12:40:45PM GMT, Jakub Jelinek wrote:
> On Mon, Jul 01, 2024 at 11:37:40AM +0200, Alejandro Colomar wrote:
> > gcc/ChangeLog:
> > 
> > * doc/invoke.texi: Document -fasm.
> 
> Why?  We have almost 1300 options which accept the negative forms
> and we don't document any of them this way, the manual explicitly states
> that:
> 
> Many options have long names starting with @samp{-f} or with
> @samp{-W}---for example,
> @option{-fmove-loop-invariants}, @option{-Wformat} and so on.  Most of
> these have both positive and negative forms; the negative form of
> @option{-ffoo} is @option{-fno-foo}.  This manual documents
> only one of these two forms, whichever one is not the default.

Ahh; hadn't seen that.  Thanks!

> 
> > Signed-off-by: Alejandro Colomar 
> > ---
> >  gcc/doc/invoke.texi | 6 +++---
> >  1 file changed, 3 insertions(+), 3 deletions(-)
> > 
> > diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> > index 30c4b002d1f..2d55f2715b3 100644
> > --- a/gcc/doc/invoke.texi
> > +++ b/gcc/doc/invoke.texi
> > @@ -198,7 +198,7 @@ in the following sections.
> >  @item C Language Options
> >  @xref{C Dialect Options,,Options Controlling C Dialect}.
> >  @gccoptlist{-ansi  -std=@var{standard}  -aux-info @var{filename}
> > --fno-asm
> > +-f@r{[}no-@r{]}asm
> >  -fno-builtin  -fno-builtin-@var{function}  -fcond-mismatch
> >  -ffreestanding  -fgimple  -fgnu-tm  -fgnu89-inline  -fhosted
> >  -flax-vector-conversions  -fms-extensions
> > @@ -2600,8 +2600,8 @@ comments, after the declaration.
> >  
> >  @opindex fno-asm
> >  @opindex fasm
> > -@item -fno-asm
> > -Do not recognize @code{asm}, @code{inline} or @code{typeof} as a
> > +@item -f@r{[}no-@r{]}asm
> > +Do (or do not) recognize @code{asm}, @code{inline} or @code{typeof} as a
> >  keyword, so that code can use these words as identifiers.  You can use
> >  the keywords @code{__asm__}, @code{__inline__} and @code{__typeof__}
> >  instead.  In C, @option{-ansi} implies @option{-fno-asm}.
> > -- 
> > 2.45.2
> > 
> 
> 
> 
>   Jakub
> 

-- 
<https://www.alejandro-colomar.es/>


signature.asc
Description: PGP signature


Re: [COMMITTED] Regenerate c.opt.urls

2024-07-17 Thread Alejandro Colomar
Hi Mark,

On Wed, Jul 17, 2024 at 06:07:20PM GMT, Mark Wielaard wrote:
> > diff --git a/gcc/c-family/c.opt.urls b/gcc/c-family/c.opt.urls
> > index 1b60ae4847b..df5f58a1eee 100644
> > --- a/gcc/c-family/c.opt.urls
> > +++ b/gcc/c-family/c.opt.urls
> > @@ -870,6 +870,9 @@ 
> > UrlSuffix(gcc/Warning-Options.html#index-Wno-unknown-pragmas) 
> > LangUrlSuffix_D(gd
> >  Wunsuffixed-float-constants
> >  UrlSuffix(gcc/Warning-Options.html#index-Wno-unsuffixed-float-constants)
> >  
> > +Wunterminated-string-initialization
> > +UrlSuffix(gcc/Warning-Options.html#index-Wno-unterminated-string-initialization)
> > +
> >  Wunused
> >  UrlSuffix(gcc/Warning-Options.html#index-Wno-unused)
> 
> I made sure that was also generated locally and pushed the attached to
> make the autoregen buildbot happy.

Thanks!

Have a lovely day!
Alex


-- 



signature.asc
Description: PGP signature


Re: [PATCH v8] C, ObjC: Add -Wunterminated-string-initialization

2024-05-14 Thread Alejandro Colomar
Ping.

I see that GCC-14 has been released recently.  This is a gentle ping to
see if this is a better time for this patch.

Have a lovely day!
Alex


signature.asc
Description: PGP signature


Re: [PATCH v5 3/3] c: Add __lengthof__ operator

2024-08-08 Thread Alejandro Colomar
Hello Jens,

On Thu, Aug 08, 2024 at 07:35:12AM GMT, Jₑₙₛ Gustedt wrote:
> Hello Alejandro,
> 
> On Thu, 8 Aug 2024 00:44:02 +0200, Alejandro Colomar wrote:
> 
> > +Its syntax is similar to @code{sizeof}.
> 
> For my curiosity, do you also make the same distinction that with
> expressions you may omit the parenthesis?

I thought of it.  TBH, I haven't tested that thoroughly.

In principle, I have implemented it in the same way as sizeof, yes.

Personally, I would have never allowed sizeof without parentheses, but I
understand there are people who think the parentheses hurt readability,
so I kept it in the same way.

I'm not sure why the parentheses are necessary with type names in
sizeof, but to maintain expectations, I think it would be better to do
the same here.

> 
> I wouldn't be sure that we should continue that distinction from
> `sizeof`.

But then, what do we do?  Allow lengthof with type names without parens?
Or require parens?  I'm not comfortable with that choice.

> Also that prefix variant would be difficult to wrap in a
> `lengthof` macro (without underscores) as we would probably like to
> have it in the end.

Do you mean that I should add _Lengthof?  We're adding __lengthof__ to
be a GNU extension with relative freedom from ISO.  If I sent a patch
adding _Lengthof, we'd have to send a proposal to ISO at the same time,
and we'd be waiting for ISO to discuss it before I can merge it.  And we
couldn't bring prior art to ISO.

With this approach instead, the plan is:

-  Merge __lengthof__ in GCC before ISO hears of it (well, there are
   already several WG14 members in this discussion, so you have actually
   heard of it, but we're free to do more or less what we want).

-  Propose _Lengthof to ISO C, with prior art in GCC as __lengthof__,
   proposing the same semantics.  Also propose a lengthof macro defined
   in 

-  When ISO C accepts _Lengthof and lengthof, map _Lengthof in GCC to
   the same internals as __lengthof__, so they are the same thing.

Still, I'm interested in having some feedback from WG14, to prevent
implementing something that will have modifications when merged to
ISO C, so please CC anyone interested from WG14, if you know of any.

Have a lovely day!
Alex

-- 
<https://www.alejandro-colomar.es/>


signature.asc
Description: PGP signature


Re: [PATCH v5 3/3] c: Add __lengthof__ operator

2024-08-08 Thread Alejandro Colomar
Hi Martin,

On Thu, Aug 08, 2024 at 09:39:59AM GMT, Martin Uecker wrote:
> > $ /opt/local/gnu/gcc/lengthof/bin/gcc zero.c
> > zero.c:18:12: error: variably modified ‘Z’ at file scope
> >18 | static int Z[__lengthof__(Y)];
> >   |^
> > 
> > 
> > See that D, which is identical to Z, does not cause an error.
> > There's one case of [0] resulting in a constant expression, and another
> > in a VLA.  Can you please help investigate why it's happening?
> 
> This seems to be another bug where we incorrectly set
> C_TYPE_VARIABLE_SIZE and this also affects sizeof:
> 
> https://godbolt.org/z/a8Ej6c5jr
> 
> Strangely it seems related to the function declaration
> with the unspecified size before.  I will look into this,
> I am just working on some checking functions that make sure
> that those bits are consistent all the time because I also
> missed some cases where I need to set C_TYPE_VARIABLY_MODIFIED
> 
> I filed a new bug:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116284

Huh, that's obscure!  Thanks!  :-)

> 
> ...
> 
> >   |^
> > 
> > If I make [0] always result in a constant expression (and thus break
> > some [*] cases), by doing
> > 
> > -  var = var || (zero && C_TYPE_VARIABLE_SIZE (type));
> > 
> > Then the problem disappears.  But I'm worried that it might be hiding
> > the problem instead of removing it, since I don't really understand why
> > it's happening.  Do you know why?
> > 
> > Anyway, I'll remove that line to support [0].  But it would be
> > interesting to learn why this problem triggers.
> 
> You need the line to support variable size arrays.

Not really.  'zero' is only true for [0] and for [*], but nor for
[zero], right?  

All vla tests seem to pass if I remove that line.  The only issue will
be that

void f(char (*a)[*], int (*x)[__lengthof__(*a)]);

will result in 'int (*x)[0]' until you change the implementation of [*],
but I think we can live with that small detail.

> Please just  uncomment
> your test with a reference to the bug for now and I will try fix this ASAP.

I'll send v6 in a moment; feel free to insist in this if you disagree
after seeing it, but I think it works well without the line.

> 
> Martin

Cheers,
Alex

-- 



signature.asc
Description: PGP signature


Re: [PATCH v5 3/3] c: Add __lengthof__ operator

2024-08-08 Thread Alejandro Colomar
Hi Jens,

On Thu, Aug 08, 2024 at 11:13:02AM GMT, Jens Gustedt wrote:
> > but to maintain expectations, I think it would be better to do
> > the same here.
> 
> Just to compare, the recent additions in C23 typeof etc. only have the
> parenthesized versions. So there would be precedent. And it really
> eases transition

Hmmm, interesting.

The good part of reusing sizeof syntax is that I can reuse internal code
for sizeof.  But I'll check if I can change it easily to only support
parens.

> > > I wouldn't be sure that we should continue that distinction from
> > > `sizeof`.
> > 
> > But then, what do we do?  Allow lengthof with type names without parens?
> > Or require parens?  I'm not comfortable with that choice.
> > 
> > > Also that prefix variant would be difficult to wrap in a
> > > `lengthof` macro (without underscores) as we would probably like to
> > > have it in the end.
> > 
> > Do you mean that I should add _Lengthof?  We're adding __lengthof__ to
> > be a GNU extension with relative freedom from ISO.  If I sent a patch
> > adding _Lengthof, we'd have to send a proposal to ISO at the same time,
> > and we'd be waiting for ISO to discuss it before I can merge it.  And we
> > couldn't bring prior art to ISO.
> > 
> > With this approach instead, the plan is:
> > 
> > -  Merge __lengthof__ in GCC before ISO hears of it (well, there are
> >already several WG14 members in this discussion, so you have actually
> >heard of it, but we're free to do more or less what we want).
> > 
> > -  Propose _Lengthof to ISO C, with prior art in GCC as __lengthof__,
> >proposing the same semantics.  Also propose a lengthof macro defined
> >in 
> 
> I don't really see why we should take a detour via _Lengthof, I would
> hope we could directly propose lengthof as the standardization

Hmmm, maybe programs already use lengthof for some other purpose.
Hopefully not, but I don't know.  In any case, I'm fine with both
approaches.

> > -  When ISO C accepts _Lengthof and lengthof, map _Lengthof in GCC to
> >the same internals as __lengthof__, so they are the same thing.
> > 
> > Still, I'm interested in having some feedback from WG14, to prevent
> > implementing something that will have modifications when merged to
> > ISO C, so please CC anyone interested from WG14, if you know of any.
> 
> I think that more important would be to have clang on board with this.

Does anyone have any Clang maintainer in mind that would be interested
in being CCed?  If so, please let me know (and/or add it yourselves).

> 
> In any case, thanks for doing this!

:-)

Cheers,
Alex

-- 



signature.asc
Description: PGP signature


Re: [PATCH v5 3/3] c: Add __lengthof__ operator

2024-08-08 Thread Alejandro Colomar
On Thu, Aug 08, 2024 at 11:23:51AM GMT, Martin Uecker wrote:
> > Not really.  'zero' is only true for [0] and for [*], but nor for
> > [zero], right?  
> > 
> > All vla tests seem to pass if I remove that line.  The only issue will
> > be that
> > 
> > void f(char (*a)[*], int (*x)[__lengthof__(*a)]);
> > 
> > will result in 'int (*x)[0]' until you change the implementation of [*],
> > but I think we can live with that small detail.
> 
> 
> I plan to change the representation of [0], so it would be nice if the
> [*] cases are correct as much as possible so that they not get forgotten
> later.

Ahhh, thanks!  Will do, then.

> 
> Martin

Cheers,
Alex

-- 



signature.asc
Description: PGP signature


Re: [PATCH v5 3/3] c: Add __lengthof__ operator

2024-08-08 Thread Alejandro Colomar
Hi Martin, Jens, Joseph,

On Thu, Aug 08, 2024 at 06:30:42PM GMT, Martin Uecker wrote:
> Am Donnerstag, dem 08.08.2024 um 18:23 +0200 schrieb Jens Gustedt:
> > As said, even if we don't consider this problematic because we are used to 
> > the mildly complex case distinction that you just exposed over several 
> > paragraphs, it doesn't mean that we should
> > do it, nor does it mean that it would be beneficial for our users or for 
> > other implementations that would like to follow. 
> > 
> > And also as said, all other features in the standard, being types, typeof, 
> > or expressions, e.g offsetof, unreachable or other gnu extensions,  don't 
> > have nor need this kind of syntax.
> > 
> > We should be designing features for the future, not the past
> 
> 
> While not problematic for parsing, I see now how the grammar becomes
> better if we eliminated this quirk. Thanks!
> 
> But we should then deprecate this for sizeof too.

How about having __lengthof__ behave like sizeof, but deprecate it in
sizeof too?

ISO C could accept only lengthof() with parens, and we could have it
without them as a deprecated-on-arrival GNU extension.

And then remove it from both at some point in the future.

We could start by adding a -Wall warning for sizeof without parens, and
promote it to an error a few versions later.

Have a lovely day!
Alex

P.S.:  I'm doing a whole-tree update to use __lengthof__ instead of
open-coded sizeof divisons or macros based on it, and I've found several
bugs already.  I'll use this change to test the new operator in the
entire code base, which should result in no regressions at all.  That
would be an interesting test suite.  :)

However, I advance that it will be painful to review that patch.

-- 



signature.asc
Description: PGP signature


Re: [PATCH v5 3/3] c: Add __lengthof__ operator

2024-08-08 Thread Alejandro Colomar
Hi Joseph,

On Thu, Aug 08, 2024 at 05:31:05PM GMT, Joseph Myers wrote:
> On Thu, 8 Aug 2024, Alejandro Colomar wrote:
> 
> > How about having __lengthof__ behave like sizeof, but deprecate it in
> > sizeof too?
> 
> Deprecation would be a matter for WG14.

Yep; I wouldn't add it to -Wall unless WG14 decides to deprecate it
first.  But if it does, that could be the path.  For lengthof, I think
keeping it like sizeof would be the simplest, as an implementer.  And
users will probably not care too much.  And if WG14 decides to deprecate
it from sizeof, they can also deprecate it from lengthof at the same
time.

> I think the code base (code on the host is generally in C++) should be 
> readable to people who know C++ (C++11 is the documented requirement for 
> building GCC - we're very conservative about adopting new language 
> versions, to facilitate bootstrapping on a wide range of systems) as it 
> is, not a playground for trying out new language features.  We have enough 
> GCC-specific versions of standard features as it is (e.g. the GCC-specific 
> vectors designed to interoperate with GCC's garbage collection), using a 
> new feature that doesn't add expressivity and isn't in any standard C++ 
> version doesn't seem like a good idea to me.
> 
> Actual bugs should of course be fixed.  But certainly standard features 
> are preferable to something specific to GCC, and existing macros in GCC 
> such as ARRAY_SIZE that people are at least familiar with are preferable 
> to introducing a new language feature.

ARRAY_SIZE() is very rarely used.  From what I've seen, most of the
existing code uses the raw sizeof division, and there's a non-negligible
amount of typos in those.

I suggest that someone at least converts most or all calls to
ARRAY_SIZE(), so that it can later easily be changed to lengthof().

I can provide my patch as a draft, so that it's just adding some include
and s/__lengthof__/ARRAY_SIZE/, plus some whitespace and parens fixes.

> 
> *If* the feature were adopted into C++26, we could then consider if 
> existing macros should be renamed to look more like the future language 
> feature.
> 
> Target code is at least always compiled with the same version of GCC, but 
> it still shouldn't be a playground for new language features; that doesn't 
> help readability, backporting patches to versions without the features, 
> etc.

It will serve me as a huge test suite anyway; so it's worth it even if
just for myself.  And it will uncover bugs.  :)

Thanks!

Have a lovely day!
Alex

-- 
<https://www.alejandro-colomar.es/>


signature.asc
Description: PGP signature


Re: [PATCH v5 3/3] c: Add __lengthof__ operator

2024-08-08 Thread Alejandro Colomar
Hi Martin,

On Thu, Aug 08, 2024 at 08:16:50PM GMT, Martin Uecker wrote:
> > It will serve me as a huge test suite anyway; so it's worth it even if
> > just for myself.  And it will uncover bugs.  :)
> 
> Did you implement a C++ version? Or are you talking about the C parts
> of the code.

I'll start with C, but was considering trying to implement a C++
version.  But I think it's not worth it for me.  I don't like the
language at all, anyway.  :)

> It is a bit sad that we do not get the testing of the
> C FE anymore which a self-hosting would have.

Yup.  I wish GCC had not moved to C++.  Maybe improving the C language
helps that goal (move back to C) in the very long term.  :)

> Martin

Cheers,
Alex

-- 



signature.asc
Description: PGP signature


Re: [PATCH v5 3/3] c: Add __lengthof__ operator

2024-08-08 Thread Alejandro Colomar
Hi Joseph,

On Thu, Aug 08, 2024 at 05:31:05PM GMT, Joseph Myers wrote:
> Actual bugs should of course be fixed.

Here are the suspects:

./gcc/testsuite/gcc.target/powerpc/sse3-addsubps.c:80:
  for (i = 0; i < sizeof (vals) / sizeof (vals); i += 8)

./gcc/c-family/c-pragma.cc:1811:
= sizeof (omp_pragmas_simd) / sizeof (*omp_pragmas);

The second sizeof expression seems to have a bogus operand, and the
correct one is probably the common one in sizeof divisions.

There are some others which are weird, but the result is correct.  For
example:

./libstdc++-v3/testsuite/21_strings/basic_string/cons/char/constexpr.cc:62:
  const auto len = (sizeof(cs) - 1)/sizeof(C);
./libstdc++-v3/testsuite/21_strings/basic_string/cons/wchar_t/constexpr.cc:62:
  const auto len = (sizeof(cs) - 1)/sizeof(C);

Which would read better as sizeof/sizeof - 1.

There are others which also could be improved in readability terms, but
I don't think it's worth bikeshedding that at the moment.  If you do a
global switch to ARRAY_SIZE(), I can help with those.  I'll keep the
commit in the backyard in case we need it for something.

It's:
 662 files changed, 1426 insertions(+), 1545 deletions(-)

Have a lovely night!
Alex


-- 



signature.asc
Description: PGP signature


Re: [PATCH v5 3/3] c: Add __lengthof__ operator

2024-08-08 Thread Alejandro Colomar
On Thu, Aug 08, 2024 at 08:36:36PM GMT, Joseph Myers wrote:
> On Thu, 8 Aug 2024, Alejandro Colomar wrote:
> 
> > Here are the suspects:
> > 
> > ./gcc/testsuite/gcc.target/powerpc/sse3-addsubps.c:80:
> >   for (i = 0; i < sizeof (vals) / sizeof (vals); i += 8)
> 
> The key question for testcases is *does the test actually test what was 
> intended*?  We never want to change testcases simply for cleanness or 
> consistency; being inconsistent is actively good in the testsuite, which 
> should cover as wide a variety of weird code as possible.

I suspect it doesn't test what was intended.  sizeof(vals)/sizeof(vals)
is 1, which doesn't look like intended at all.  Also, there were related
tests that had the proper division.

> 
> -- 
> Joseph S. Myers
> josmy...@redhat.com
> 

-- 
<https://www.alejandro-colomar.es/>


signature.asc
Description: PGP signature


Internal Compiler Error (was: [PATCH v5 0/3] c: Add __lengthof__ operator)

2024-08-08 Thread Alejandro Colomar
Hi!

While running `make check -j24`, I've seen an internal compiler error.
I've tried to reproduce it, but it only triggered once that time.

This is the only log I've been able to collect.  I hope it helps.

lto1: internal compiler error: in lto_read_decls, at 
lto/lto-common.cc:1970
0x23234de internal_error(char const*, ...)
../.././gcc/diagnostic-global-context.cc:491
0x923807 fancy_abort(char const*, int, char const*)
../.././gcc/diagnostic.cc:1772
0x71d494 lto_read_decls
../.././gcc/lto/lto-common.cc:1970
0x97b959 lto_file_finalize
../.././gcc/lto/lto-common.cc:2299
0x97b959 lto_create_files_from_ids
../.././gcc/lto/lto-common.cc:2309
0x97b959 lto_file_read
../.././gcc/lto/lto-common.cc:2364
0x97b959 read_cgraph_and_symbols(unsigned int, char const**)
../.././gcc/lto/lto-common.cc:2812
0x95c012 lto_main()
../.././gcc/lto/lto.cc:658
Please submit a full bug report, with preprocessed source (by using 
-freport-bug).
Please include the complete backtrace with any bug report.
See  for instructions.
lto-wrapper: fatal error: 
/home/alx/src/gnu/gcc/len/host-x86_64-pc-linux-gnu/gcc/xgcc returned 1 exit 
status
compilation terminated.
/usr/bin/ld: error: lto-wrapper failed
collect2: error: ld returned 1 exit status

To clarify, this was run after running a slightly-modified version of
this patch set, and nothing else.  In theory, I think, I haven't touched
anything that should cause an lto ICE.  I've rebased on top of git HEAD
earlier today, and have applied the changes shown below.

I assume I'm causing it somehow, with my patches, but maybe it's not.
Is git HEAD known to be in a bad state at the moment regarding lto?


The range-diff below is what will be v6, which I was planning to send
today, but haven't because of this ICE.

Cheers,
Alex


$ git range-diff 73010cb4af6^..af05d01e68d gnu/master..HEAD
1:  73010cb4af6 = 1:  8b68e250503 gcc/: Rename array_type_nelts() => 
array_type_nelts_minus_one()
2:  9b835478721 = 2:  21433097103 Merge definitions of array_type_nelts_top()
3:  af05d01e68d ! 3:  e8867c0fef4 c: Add __lengthof__ operator
@@ Commit message
 
 FUTURE DIRECTIONS:
 
-  We could make it work with array parameters to functions, and
-  somehow magically return the length designator of the array,
-  regardless of it being really a pointer.
+-  We should make it work with array parameters to functions,
+   and somehow magically return the length designator of the array,
+   regardless of it being really a pointer.
+
+-  Fix support for [0].
 
 Cc: Joseph Myers 
 Cc: Gabriel Ravier 
@@ Commit message
 gcc/testsuite/ChangeLog:
 
 * gcc.dg/lengthof-compile.c:
+* gcc.dg/lengthof-vla.c:
 * gcc.dg/lengthof.c: Add tests for __lengthof__ operator.
 
 Link: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2529.pdf
@@ gcc/c/c-typeck.cc: c_expr_sizeof_type (location_t loc, struct 
c_type_name *t)
 +static bool
 +is_top_array_vla (tree type)
 +{
-+  bool zero, var;
++  bool zero, star, var;
 +  tree d;
 +
 +  if (TREE_CODE (type) != ARRAY_TYPE)
@@ gcc/c/c-typeck.cc: c_expr_sizeof_type (location_t loc, struct 
c_type_name *t)
 +
 +  d = TYPE_DOMAIN (type);
 +  zero = !TYPE_MAX_VALUE (d);
-+  var = (!zero
-+   && (TREE_CODE (TYPE_MIN_VALUE (d)) != INTEGER_CST
-+   || TREE_CODE (TYPE_MAX_VALUE (d)) != INTEGER_CST));
-+  var = var || (zero && C_TYPE_VARIABLE_SIZE (type));
++  star = (zero && C_TYPE_VARIABLE_SIZE (type));
++  if (star)
++return true;
++  if (zero)
++return false;
++
++  var = (TREE_CODE (TYPE_MIN_VALUE (d)) != INTEGER_CST
++   || TREE_CODE (TYPE_MAX_VALUE (d)) != INTEGER_CST);
 +  return var;
 +}
 +
@@ gcc/doc/extend.texi: If the operand of the @code{__alignof__} expression 
is a fu
 +
 +The keyword @code{__lengthof__} determines the length of an array operand,
 +that is, the number of elements in the array.
-+Its syntax is just like @code{sizeof}.
-+The operand must be a complete array type.
++Its syntax is similar to @code{sizeof}.
++The operand must be a complete array type or an expression of that type.
++For example:
++
++@smallexample
++int a[n];
++__lengthof__ (a);  // returns n
++__lengthof__ (int [7][3]);  // returns 7
++@end smallexample
++
 +The operand is not evaluated
 +if the top-level length designator is an integer constant expression
-+(in this case, the operator results in a constant expression);
++(in this case, the operator resu

[PATCH v6 0/3] c: Add __lengthof__ operator

2024-08-09 Thread Alejandro Colomar
Hi!

v6:

-  Note that support for 0-length arrays is slightly broken.
-  Improve readability of is_top_array_vla(), without changing behavior.
-  Doc: Clarify that both types and expressions are accepted, and
   provide an example.  [Joseph]
-  Doc: Wording improvements.  [Joseph, Jens]
-  Tests:  [Joseph, Martin]
   -  Remove unnecessary assignments where we're just interested in
  the __lengthof__ expression.
   -  Add tests for arrays whose length is implicit: [] = {...}
   -  Add tests for 0-length arrays.
   -  Add tests for non-arrays.
   -  Add tests for undefined symbols.
   -  Add tests for the version without parentheses.
   -  Test whether some expressions are constant or variable.
   -  Use static_assert(3) instead of assert(3) where possible.
-  CC: Add an LLVM developer: Timm.

Below is a range-diff against v5.

I've tested for regressions, and it seems there aren't (x86_64).
I've also replaced sizeof divisions in the C testsuite by __lengthof__,
to get broader testing, and it also worked well (those changes are not
included in this patch).

I've seen some internal compiler errors while running `make -j24 check`
that I haven't been able to reproduce consistently.  However, they are
in parts of the repository that are unrelated to my changes, so I
suspect those are problems that existed before my patches.  (I've
reported the ICE in an earlier subthread of this thread.)


Have a lovely day!
Alex


Alejandro Colomar (3):
  gcc/: Rename array_type_nelts() => array_type_nelts_minus_one()
  Merge definitions of array_type_nelts_top()
  c: Add __lengthof__ operator

 gcc/c-family/c-common.cc|  26 
 gcc/c-family/c-common.def   |   3 +
 gcc/c-family/c-common.h |   2 +
 gcc/c/c-decl.cc |  30 +++--
 gcc/c/c-fold.cc |   7 +-
 gcc/c/c-parser.cc   |  61 +++---
 gcc/c/c-tree.h  |   4 +
 gcc/c/c-typeck.cc   | 118 ++-
 gcc/config/aarch64/aarch64.cc   |   2 +-
 gcc/config/i386/i386.cc |   2 +-
 gcc/cp/cp-tree.h|   1 -
 gcc/cp/decl.cc  |   2 +-
 gcc/cp/init.cc  |   8 +-
 gcc/cp/lambda.cc|   3 +-
 gcc/cp/operators.def|   1 +
 gcc/cp/tree.cc  |  13 --
 gcc/doc/extend.texi |  31 +
 gcc/expr.cc |   8 +-
 gcc/fortran/trans-array.cc  |   2 +-
 gcc/fortran/trans-openmp.cc |   4 +-
 gcc/rust/backend/rust-tree.cc   |  13 --
 gcc/rust/backend/rust-tree.h|   2 -
 gcc/target.h|   3 +
 gcc/testsuite/gcc.dg/lengthof-compile.c | 115 ++
 gcc/testsuite/gcc.dg/lengthof-vla.c |  46 
 gcc/testsuite/gcc.dg/lengthof.c | 150 
 gcc/tree.cc |  17 ++-
 gcc/tree.h  |   3 +-
 28 files changed, 598 insertions(+), 79 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/lengthof-compile.c
 create mode 100644 gcc/testsuite/gcc.dg/lengthof-vla.c
 create mode 100644 gcc/testsuite/gcc.dg/lengthof.c

Range-diff against v5:
1:  73010cb4af6 = 1:  8b68e250503 gcc/: Rename array_type_nelts() => 
array_type_nelts_minus_one()
2:  9b835478721 = 2:  21433097103 Merge definitions of array_type_nelts_top()
3:  af05d01e68d ! 3:  71fd2013967 c: Add __lengthof__ operator
@@ Commit message
 
 FUTURE DIRECTIONS:
 
-  We could make it work with array parameters to functions, and
-  somehow magically return the length designator of the array,
-  regardless of it being really a pointer.
+-  We should make it work with array parameters to functions,
+   and somehow magically return the length designator of the array,
+   regardless of it being really a pointer.
+
+-  Fix support for [0].
 
 Cc: Joseph Myers 
 Cc: Gabriel Ravier 
@@ Commit message
 Cc: David Brown 
 Cc: Florian Weimer 
 Cc: Andreas Schwab 
+Cc: Timm Baeder 
 
 gcc/ChangeLog:
 
@@ Commit message
 gcc/testsuite/ChangeLog:
 
 * gcc.dg/lengthof-compile.c:
+* gcc.dg/lengthof-vla.c:
 * gcc.dg/lengthof.c: Add tests for __lengthof__ operator.
 
 Link: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2529.pdf
@@ gcc/c/c-typeck.cc: c_expr_sizeof_type (location_t loc, struct 
c_type_name *t)
 +static bool
 +is_top_array_vla (tree type)
 +{
-+  bool zero, var;
++  bool zero, star, var;
 +  tree d;
 +
 +  if (TREE_CODE (type) != ARRAY_TYPE)
@@ gcc/c/c-typeck.cc: c_expr_sizeof_type (location_t loc, struct 
c_type_name

[PATCH v6 1/3] gcc/: Rename array_type_nelts() => array_type_nelts_minus_one()

2024-08-09 Thread Alejandro Colomar
The old name was misleading.

While at it, also rename some temporary variables that are used with
this function, for consistency.

Link: 
https://inbox.sourceware.org/gcc-patches/9fffd80-dca-2c7e-14b-6c9b509a7...@redhat.com/T/#m2f661c67c8f7b2c405c8c7fc3152dd85dc729120
Cc: Gabriel Ravier 
Cc: Martin Uecker 
Cc: Joseph Myers 
Cc: Xavier Del Campo Romero 
Cc: Jakub Jelinek 

gcc/ChangeLog:

* tree.cc (array_type_nelts): Rename function ...
(array_type_nelts_minus_one): ... to this name.  The old name
was misleading.
* tree.h (array_type_nelts): Rename function ...
(array_type_nelts_minus_one): ... to this name.  The old name
was misleading.
* expr.cc (count_type_elements):
Rename array_type_nelts() => array_type_nelts_minus_one()
* config/aarch64/aarch64.cc
(pure_scalable_type_info::analyze_array): Likewise.
* config/i386/i386.cc (ix86_canonical_va_list_type): Likewise.

gcc/c/ChangeLog:

* c-decl.cc (one_element_array_type_p, get_parm_array_spec):
Rename array_type_nelts() => array_type_nelts_minus_one()
* c-fold.cc (c_fold_array_ref): Likewise.

gcc/cp/ChangeLog:

* decl.cc (reshape_init_array):
Rename array_type_nelts() => array_type_nelts_minus_one()
* init.cc (build_zero_init_1): Likewise.
(build_value_init_noctor): Likewise.
(build_vec_init): Likewise.
(build_delete): Likewise.
* lambda.cc (add_capture): Likewise.
* tree.cc (array_type_nelts_top): Likewise.

gcc/fortran/ChangeLog:

* trans-array.cc (structure_alloc_comps):
Rename array_type_nelts() => array_type_nelts_minus_one()
* trans-openmp.cc (gfc_walk_alloc_comps): Likewise.
(gfc_omp_clause_linear_ctor): Likewise.

gcc/rust/ChangeLog:

* backend/rust-tree.cc (array_type_nelts_top):
Rename array_type_nelts() => array_type_nelts_minus_one()

Suggested-by: Richard Biener 
Signed-off-by: Alejandro Colomar 
---
 gcc/c/c-decl.cc   | 10 +-
 gcc/c/c-fold.cc   |  7 ---
 gcc/config/aarch64/aarch64.cc |  2 +-
 gcc/config/i386/i386.cc   |  2 +-
 gcc/cp/decl.cc|  2 +-
 gcc/cp/init.cc|  8 
 gcc/cp/lambda.cc  |  3 ++-
 gcc/cp/tree.cc|  2 +-
 gcc/expr.cc   |  8 
 gcc/fortran/trans-array.cc|  2 +-
 gcc/fortran/trans-openmp.cc   |  4 ++--
 gcc/rust/backend/rust-tree.cc |  2 +-
 gcc/tree.cc   |  4 ++--
 gcc/tree.h|  2 +-
 14 files changed, 30 insertions(+), 28 deletions(-)

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 8cef8f2c289..e7c2783e724 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -5309,7 +5309,7 @@ one_element_array_type_p (const_tree type)
 {
   if (TREE_CODE (type) != ARRAY_TYPE)
 return false;
-  return integer_zerop (array_type_nelts (type));
+  return integer_zerop (array_type_nelts_minus_one (type));
 }
 
 /* Determine whether TYPE is a zero-length array type "[0]".  */
@@ -6257,15 +6257,15 @@ get_parm_array_spec (const struct c_parm *parm, tree 
attrs)
  for (tree type = parm->specs->type; TREE_CODE (type) == ARRAY_TYPE;
   type = TREE_TYPE (type))
{
- tree nelts = array_type_nelts (type);
- if (error_operand_p (nelts))
+ tree nelts_minus_one = array_type_nelts_minus_one (type);
+ if (error_operand_p (nelts_minus_one))
return attrs;
- if (TREE_CODE (nelts) != INTEGER_CST)
+ if (TREE_CODE (nelts_minus_one) != INTEGER_CST)
{
  /* Each variable VLA bound is represented by the dollar
 sign.  */
  spec += "$";
- tpbnds = tree_cons (NULL_TREE, nelts, tpbnds);
+ tpbnds = tree_cons (NULL_TREE, nelts_minus_one, tpbnds);
}
}
  tpbnds = nreverse (tpbnds);
diff --git a/gcc/c/c-fold.cc b/gcc/c/c-fold.cc
index 57b67c74bd8..9ea174f79c4 100644
--- a/gcc/c/c-fold.cc
+++ b/gcc/c/c-fold.cc
@@ -73,11 +73,12 @@ c_fold_array_ref (tree type, tree ary, tree index)
   unsigned elem_nchars = (TYPE_PRECISION (elem_type)
  / TYPE_PRECISION (char_type_node));
   unsigned len = (unsigned) TREE_STRING_LENGTH (ary) / elem_nchars;
-  tree nelts = array_type_nelts (TREE_TYPE (ary));
+  tree nelts_minus_one = array_type_nelts_minus_one (TREE_TYPE (ary));
   bool dummy1 = true, dummy2 = true;
-  nelts = c_fully_fold_internal (nelts, true, &dummy1, &dummy2, false, false);
+  nelts_minus_one = c_fully_fold_internal (nelts_minus_one, true, &dummy1,
+  &dummy2, false, false);
   unsigned HOST_WIDE_INT i = tree_to_uhwi (index);
-  if (!tree_int_cst_le (index, nelts)
+  if (!tree_int_cst_le (index, nelts_minu

[PATCH v6 3/3] c: Add __lengthof__ operator

2024-08-09 Thread Alejandro Colomar
This operator is similar to sizeof but can only be applied to an array,
and returns its length (number of elements).

FUTURE DIRECTIONS:

-  We should make it work with array parameters to functions,
   and somehow magically return the length designator of the array,
   regardless of it being really a pointer.

-  Fix support for [0].

Cc: Joseph Myers 
Cc: Gabriel Ravier 
Cc: Jakub Jelinek 
Cc: Kees Cook 
Cc: Qing Zhao 
Cc: Jens Gustedt 
Cc: David Brown 
Cc: Florian Weimer 
Cc: Andreas Schwab 
Cc: Timm Baeder 

gcc/ChangeLog:

* doc/extend.texi: Document __lengthof__ operator.
* target.h (enum type_context_kind): Add __lengthof__ operator.

gcc/c-family/ChangeLog:

* c-common.h:
* c-common.def:
* c-common.cc (c_lengthof_type): Add __lengthof__ operator.

gcc/c/ChangeLog:

* c-tree.h
(c_expr_lengthof_expr, c_expr_lengthof_type):
* c-decl.cc
(start_struct, finish_struct):
(start_enum, finish_enum):
* c-parser.cc
(c_parser_sizeof_expression):
(c_parser_lengthof_expression):
(c_parser_sizeof_or_lengthof_expression):
(c_parser_unary_expression):
* c-typeck.cc
(build_external_ref):
(record_maybe_used_decl, pop_maybe_used):
(is_top_array_vla):
(c_expr_lengthof_expr, c_expr_lengthof_type):
Add __lengthof__operator.

gcc/cp/ChangeLog:

* operators.def: Add __lengthof__ operator.

gcc/testsuite/ChangeLog:

* gcc.dg/lengthof-compile.c:
* gcc.dg/lengthof-vla.c:
* gcc.dg/lengthof.c: Add tests for __lengthof__ operator.

Link: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2529.pdf
Link: https://inbox.sourceware.org/gcc/m8s4oqy--...@tutanota.com/T/
Suggested-by: Xavier Del Campo Romero 
Co-developed-by: Martin Uecker 
Signed-off-by: Alejandro Colomar 
---
 gcc/c-family/c-common.cc|  26 
 gcc/c-family/c-common.def   |   3 +
 gcc/c-family/c-common.h |   2 +
 gcc/c/c-decl.cc |  20 +++-
 gcc/c/c-parser.cc   |  61 +++---
 gcc/c/c-tree.h  |   4 +
 gcc/c/c-typeck.cc   | 118 ++-
 gcc/cp/operators.def|   1 +
 gcc/doc/extend.texi |  31 +
 gcc/target.h|   3 +
 gcc/testsuite/gcc.dg/lengthof-compile.c | 115 ++
 gcc/testsuite/gcc.dg/lengthof-vla.c |  46 
 gcc/testsuite/gcc.dg/lengthof.c | 150 
 13 files changed, 556 insertions(+), 24 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/lengthof-compile.c
 create mode 100644 gcc/testsuite/gcc.dg/lengthof-vla.c
 create mode 100644 gcc/testsuite/gcc.dg/lengthof.c

diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index e7e371fd26f..9f5feb83345 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -465,6 +465,7 @@ const struct c_common_resword c_common_reswords[] =
   { "__inline",RID_INLINE, 0 },
   { "__inline__",  RID_INLINE, 0 },
   { "__label__",   RID_LABEL,  0 },
+  { "__lengthof__",RID_LENGTHOF, 0 },
   { "__null",  RID_NULL,   0 },
   { "__real",  RID_REALPART,   0 },
   { "__real__",RID_REALPART,   0 },
@@ -4070,6 +4071,31 @@ c_alignof_expr (location_t loc, tree expr)
 
   return fold_convert_loc (loc, size_type_node, t);
 }
+
+/* Implement the lengthof keyword: Return the length of an array,
+   that is, the number of elements in the array.  */
+
+tree
+c_lengthof_type (location_t loc, tree type)
+{
+  enum tree_code type_code;
+
+  type_code = TREE_CODE (type);
+  if (type_code != ARRAY_TYPE)
+{
+  error_at (loc, "invalid application of % to type %qT", type);
+  return error_mark_node;
+}
+  if (!COMPLETE_TYPE_P (type))
+{
+  error_at (loc,
+   "invalid application of % to incomplete type %qT",
+   type);
+  return error_mark_node;
+}
+
+  return array_type_nelts_top (type);
+}
 
 /* Handle C and C++ default attributes.  */
 
diff --git a/gcc/c-family/c-common.def b/gcc/c-family/c-common.def
index 5de96e5d4a8..6d162f67104 100644
--- a/gcc/c-family/c-common.def
+++ b/gcc/c-family/c-common.def
@@ -50,6 +50,9 @@ DEFTREECODE (EXCESS_PRECISION_EXPR, "excess_precision_expr", 
tcc_expression, 1)
number.  */
 DEFTREECODE (USERDEF_LITERAL, "userdef_literal", tcc_exceptional, 3)
 
+/* Represents a 'lengthof' expression.  */
+DEFTREECODE (LENGTHOF_EXPR, "lengthof_expr", tcc_expression, 1)
+
 /* Represents a 'sizeof' expression during C++ template expansion,
or for the purpose of -Wsizeof-pointer-memaccess warning.  */
 DEFTREECODE (SIZEOF_EXPR, "sizeof_expr", tcc_expression, 1)
d

[PATCH v6 2/3] Merge definitions of array_type_nelts_top()

2024-08-09 Thread Alejandro Colomar
There were two identical definitions, and none of them are available
where they are needed for implementing __lengthof__.  Merge them, and
provide the single definition in gcc/tree.{h,cc}, where it's available
for __lengthof__, which will be added in the following commit.

gcc/ChangeLog:

* tree.h (array_type_nelts_top):
* tree.cc (array_type_nelts_top): Define function (moved from
gcc/cp/).

gcc/cp/ChangeLog:

* cp-tree.h (array_type_nelts_top):
* tree.cc (array_type_nelts_top): Remove function (move
to gcc/).

gcc/rust/ChangeLog:

* backend/rust-tree.h (array_type_nelts_top):
* backend/rust-tree.cc (array_type_nelts_top): Remove function.

Signed-off-by: Alejandro Colomar 
---
 gcc/cp/cp-tree.h  |  1 -
 gcc/cp/tree.cc| 13 -
 gcc/rust/backend/rust-tree.cc | 13 -
 gcc/rust/backend/rust-tree.h  |  2 --
 gcc/tree.cc   | 13 +
 gcc/tree.h|  1 +
 6 files changed, 14 insertions(+), 29 deletions(-)

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index b1693051231..76d7bc34577 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -8100,7 +8100,6 @@ extern tree build_exception_variant   (tree, 
tree);
 extern void fixup_deferred_exception_variants   (tree, tree);
 extern tree bind_template_template_parm(tree, tree);
 extern tree array_type_nelts_total (tree);
-extern tree array_type_nelts_top   (tree);
 extern bool array_of_unknown_bound_p   (const_tree);
 extern tree break_out_target_exprs (tree, bool = false);
 extern tree build_ctor_subob_ref   (tree, tree, tree);
diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
index 040136c70ab..7d179491476 100644
--- a/gcc/cp/tree.cc
+++ b/gcc/cp/tree.cc
@@ -3079,19 +3079,6 @@ cxx_print_statistics (void)
 depth_reached);
 }
 
-/* Return, as an INTEGER_CST node, the number of elements for TYPE
-   (which is an ARRAY_TYPE).  This counts only elements of the top
-   array.  */
-
-tree
-array_type_nelts_top (tree type)
-{
-  return fold_build2_loc (input_location,
- PLUS_EXPR, sizetype,
- array_type_nelts_minus_one (type),
- size_one_node);
-}
-
 /* Return, as an INTEGER_CST node, the number of elements for TYPE
(which is an ARRAY_TYPE).  This one is a recursive count of all
ARRAY_TYPEs that are clumped together.  */
diff --git a/gcc/rust/backend/rust-tree.cc b/gcc/rust/backend/rust-tree.cc
index 8d32e5203ae..3dc6b076711 100644
--- a/gcc/rust/backend/rust-tree.cc
+++ b/gcc/rust/backend/rust-tree.cc
@@ -859,19 +859,6 @@ is_empty_class (tree type)
   return CLASSTYPE_EMPTY_P (type);
 }
 
-// forked from gcc/cp/tree.cc array_type_nelts_top
-
-/* Return, as an INTEGER_CST node, the number of elements for TYPE
-   (which is an ARRAY_TYPE).  This counts only elements of the top
-   array.  */
-
-tree
-array_type_nelts_top (tree type)
-{
-  return fold_build2_loc (input_location, PLUS_EXPR, sizetype,
- array_type_nelts_minus_one (type), size_one_node);
-}
-
 // forked from gcc/cp/tree.cc builtin_valid_in_constant_expr_p
 
 /* Test whether DECL is a builtin that may appear in a
diff --git a/gcc/rust/backend/rust-tree.h b/gcc/rust/backend/rust-tree.h
index 26c8b653ac6..e597c3ab81d 100644
--- a/gcc/rust/backend/rust-tree.h
+++ b/gcc/rust/backend/rust-tree.h
@@ -2993,8 +2993,6 @@ extern location_t rs_expr_location (const_tree);
 extern int
 is_empty_class (tree type);
 
-extern tree array_type_nelts_top (tree);
-
 extern bool
 is_really_empty_class (tree, bool);
 
diff --git a/gcc/tree.cc b/gcc/tree.cc
index ed0a766016a..cedf95cc222 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -3729,6 +3729,19 @@ array_type_nelts_minus_one (const_tree type)
  ? max
  : fold_build2 (MINUS_EXPR, TREE_TYPE (max), max, min));
 }
+
+/* Return, as an INTEGER_CST node, the number of elements for TYPE
+   (which is an ARRAY_TYPE).  This counts only elements of the top
+   array.  */
+
+tree
+array_type_nelts_top (tree type)
+{
+  return fold_build2_loc (input_location,
+ PLUS_EXPR, sizetype,
+ array_type_nelts_minus_one (type),
+ size_one_node);
+}
 
 /* If arg is static -- a reference to an object in static storage -- then
return the object.  This is not the same as the C meaning of `static'.
diff --git a/gcc/tree.h b/gcc/tree.h
index 69d40bb4f04..9061dafd027 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -4922,6 +4922,7 @@ extern tree build_method_type (tree, tree);
 extern tree build_offset_type (tree, tree);
 extern tree build_complex_type (tree, bool named = false);
 extern tree array_type_nelts_minus_one (const_tree);
+extern tree array_type_nelts_top (tree);
 
 extern tree value_member (tree, tree);
 extern tree purpose_member (const_tree, tree);
-- 
2.45.2



sig

Re: [PATCH v6 3/3] c: Add __lengthof__ operator

2024-08-09 Thread Alejandro Colomar
On Fri, Aug 09, 2024 at 03:59:19PM GMT, Alejandro Colomar wrote:
> This operator is similar to sizeof but can only be applied to an array,
> and returns its length (number of elements).
> 
> FUTURE DIRECTIONS:
> 
> -  We should make it work with array parameters to functions,
>and somehow magically return the length designator of the array,
>regardless of it being really a pointer.
> 
> -  Fix support for [0].
> 
> Cc: Joseph Myers 
> Cc: Gabriel Ravier 
> Cc: Jakub Jelinek 
> Cc: Kees Cook 
> Cc: Qing Zhao 
> Cc: Jens Gustedt 
> Cc: David Brown 
> Cc: Florian Weimer 
> Cc: Andreas Schwab 
> Cc: Timm Baeder 
> 
> gcc/ChangeLog:
> 
>   * doc/extend.texi: Document __lengthof__ operator.
>   * target.h (enum type_context_kind): Add __lengthof__ operator.
> 
> gcc/c-family/ChangeLog:
> 
>   * c-common.h:
>   * c-common.def:
>   * c-common.cc (c_lengthof_type): Add __lengthof__ operator.
> 
> gcc/c/ChangeLog:
> 
>   * c-tree.h
>   (c_expr_lengthof_expr, c_expr_lengthof_type):
>   * c-decl.cc
>   (start_struct, finish_struct):
>   (start_enum, finish_enum):
>   * c-parser.cc
>   (c_parser_sizeof_expression):
>   (c_parser_lengthof_expression):
>   (c_parser_sizeof_or_lengthof_expression):
>   (c_parser_unary_expression):
>   * c-typeck.cc
>   (build_external_ref):
>   (record_maybe_used_decl, pop_maybe_used):
>   (is_top_array_vla):
>   (c_expr_lengthof_expr, c_expr_lengthof_type):
>   Add __lengthof__operator.
> 
> gcc/cp/ChangeLog:
> 
>   * operators.def: Add __lengthof__ operator.
> 
> gcc/testsuite/ChangeLog:
> 
>   * gcc.dg/lengthof-compile.c:
>   * gcc.dg/lengthof-vla.c:
>   * gcc.dg/lengthof.c: Add tests for __lengthof__ operator.
> 
> Link: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2529.pdf
> Link: https://inbox.sourceware.org/gcc/m8s4oqy--...@tutanota.com/T/
> Suggested-by: Xavier Del Campo Romero 
> Co-developed-by: Martin Uecker 
> Signed-off-by: Alejandro Colomar 
> ---
>  gcc/c-family/c-common.cc|  26 
>  gcc/c-family/c-common.def   |   3 +
>  gcc/c-family/c-common.h |   2 +
>  gcc/c/c-decl.cc |  20 +++-
>  gcc/c/c-parser.cc   |  61 +++---
>  gcc/c/c-tree.h  |   4 +
>  gcc/c/c-typeck.cc   | 118 ++-
>  gcc/cp/operators.def|   1 +
>  gcc/doc/extend.texi |  31 +
>  gcc/target.h|   3 +
>  gcc/testsuite/gcc.dg/lengthof-compile.c | 115 ++
>  gcc/testsuite/gcc.dg/lengthof-vla.c |  46 
>  gcc/testsuite/gcc.dg/lengthof.c | 150 
>  13 files changed, 556 insertions(+), 24 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/lengthof-compile.c
>  create mode 100644 gcc/testsuite/gcc.dg/lengthof-vla.c
>  create mode 100644 gcc/testsuite/gcc.dg/lengthof.c
> 
> diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
> index e7e371fd26f..9f5feb83345 100644
> --- a/gcc/c-family/c-common.cc
> +++ b/gcc/c-family/c-common.cc
> @@ -465,6 +465,7 @@ const struct c_common_resword c_common_reswords[] =
>{ "__inline",  RID_INLINE, 0 },
>{ "__inline__",RID_INLINE, 0 },
>{ "__label__", RID_LABEL,  0 },
> +  { "__lengthof__",  RID_LENGTHOF, 0 },
>{ "__null",RID_NULL,   0 },
>{ "__real",RID_REALPART,   0 },
>{ "__real__",  RID_REALPART,   0 },
> @@ -4070,6 +4071,31 @@ c_alignof_expr (location_t loc, tree expr)
>  
>return fold_convert_loc (loc, size_type_node, t);
>  }
> +
> +/* Implement the lengthof keyword: Return the length of an array,
> +   that is, the number of elements in the array.  */
> +
> +tree
> +c_lengthof_type (location_t loc, tree type)
> +{
> +  enum tree_code type_code;
> +
> +  type_code = TREE_CODE (type);
> +  if (type_code != ARRAY_TYPE)
> +{
> +  error_at (loc, "invalid application of % to type %qT", 
> type);
> +  return error_mark_node;
> +}
> +  if (!COMPLETE_TYPE_P (type))
> +{
> +  error_at (loc,
> + "invalid application of % to incomplete type %qT",
> + type);
> +  return error_mark_node;
> +}
> +
> +  return array_type_nelts_top (type);
> +}
>  
>  /* Handle C and C++ default attributes.  */
>  
> diff --git a/gcc/c-family/c-common.def b/gcc/c-fam

[PATCH v7 0/3] c: Add __lengthof__ operator

2024-08-10 Thread Alejandro Colomar
Hi!

v7:

-  Tests:
   -  Fix 2 tests (whitespace fix).
   -  Fix typo in comment.


Alejandro Colomar (3):
  gcc/: Rename array_type_nelts() => array_type_nelts_minus_one()
  Merge definitions of array_type_nelts_top()
  c: Add __lengthof__ operator

 gcc/c-family/c-common.cc|  26 
 gcc/c-family/c-common.def   |   3 +
 gcc/c-family/c-common.h |   2 +
 gcc/c/c-decl.cc |  30 +++--
 gcc/c/c-fold.cc |   7 +-
 gcc/c/c-parser.cc   |  61 +++---
 gcc/c/c-tree.h  |   4 +
 gcc/c/c-typeck.cc   | 118 ++-
 gcc/config/aarch64/aarch64.cc   |   2 +-
 gcc/config/i386/i386.cc |   2 +-
 gcc/cp/cp-tree.h|   1 -
 gcc/cp/decl.cc  |   2 +-
 gcc/cp/init.cc  |   8 +-
 gcc/cp/lambda.cc|   3 +-
 gcc/cp/operators.def|   1 +
 gcc/cp/tree.cc  |  13 --
 gcc/doc/extend.texi |  31 +
 gcc/expr.cc |   8 +-
 gcc/fortran/trans-array.cc  |   2 +-
 gcc/fortran/trans-openmp.cc |   4 +-
 gcc/rust/backend/rust-tree.cc   |  13 --
 gcc/rust/backend/rust-tree.h|   2 -
 gcc/target.h|   3 +
 gcc/testsuite/gcc.dg/lengthof-compile.c | 115 ++
 gcc/testsuite/gcc.dg/lengthof-vla.c |  46 
 gcc/testsuite/gcc.dg/lengthof.c | 150 
 gcc/tree.cc |  17 ++-
 gcc/tree.h  |   3 +-
 28 files changed, 598 insertions(+), 79 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/lengthof-compile.c
 create mode 100644 gcc/testsuite/gcc.dg/lengthof-vla.c
 create mode 100644 gcc/testsuite/gcc.dg/lengthof.c

Range-diff against v6:
1:  8b68e250503 = 1:  8b68e250503 gcc/: Rename array_type_nelts() => 
array_type_nelts_minus_one()
2:  21433097103 = 2:  21433097103 Merge definitions of array_type_nelts_top()
3:  71fd2013967 ! 3:  4bd3837d09c c: Add __lengthof__ operator
@@ gcc/testsuite/gcc.dg/lengthof-compile.c (new)
 +  int n = 7;
 +
 +  _Static_assert (__lengthof__ (int [3][n]) == 3);
-+  _Static_assert (__lengthof__ (int [n][3]) == 7); /* { dg-error "not 
constant"} */
++  _Static_assert (__lengthof__ (int [n][3]) == 7); /* { dg-error "not 
constant" } */
 +  _Static_assert (__lengthof__ (int [0][3]) == 0);
 +  _Static_assert (__lengthof__ (int [0]) == 0);
 +
-+  /* FIXME: lengthog(int [0][n]) should result in a constant expression.  
*/
-+  _Static_assert (__lengthof__ (int [0][n]) == 0); /* { dg-error "not 
constant"} */
++  /* FIXME: lengthof(int [0][n]) should result in a constant expression.  
*/
++  _Static_assert (__lengthof__ (int [0][n]) == 0); /* { dg-error "not 
constant" } */
 +}
 
  ## gcc/testsuite/gcc.dg/lengthof-vla.c (new) ##
-- 
2.45.2



signature.asc
Description: PGP signature


[PATCH v7 1/3] gcc/: Rename array_type_nelts() => array_type_nelts_minus_one()

2024-08-10 Thread Alejandro Colomar
The old name was misleading.

While at it, also rename some temporary variables that are used with
this function, for consistency.

Link: 
https://inbox.sourceware.org/gcc-patches/9fffd80-dca-2c7e-14b-6c9b509a7...@redhat.com/T/#m2f661c67c8f7b2c405c8c7fc3152dd85dc729120
Cc: Gabriel Ravier 
Cc: Martin Uecker 
Cc: Joseph Myers 
Cc: Xavier Del Campo Romero 
Cc: Jakub Jelinek 

gcc/ChangeLog:

* tree.cc (array_type_nelts): Rename function ...
(array_type_nelts_minus_one): ... to this name.  The old name
was misleading.
* tree.h (array_type_nelts): Rename function ...
(array_type_nelts_minus_one): ... to this name.  The old name
was misleading.
* expr.cc (count_type_elements):
Rename array_type_nelts() => array_type_nelts_minus_one()
* config/aarch64/aarch64.cc
(pure_scalable_type_info::analyze_array): Likewise.
* config/i386/i386.cc (ix86_canonical_va_list_type): Likewise.

gcc/c/ChangeLog:

* c-decl.cc (one_element_array_type_p, get_parm_array_spec):
Rename array_type_nelts() => array_type_nelts_minus_one()
* c-fold.cc (c_fold_array_ref): Likewise.

gcc/cp/ChangeLog:

* decl.cc (reshape_init_array):
Rename array_type_nelts() => array_type_nelts_minus_one()
* init.cc (build_zero_init_1): Likewise.
(build_value_init_noctor): Likewise.
(build_vec_init): Likewise.
(build_delete): Likewise.
* lambda.cc (add_capture): Likewise.
* tree.cc (array_type_nelts_top): Likewise.

gcc/fortran/ChangeLog:

* trans-array.cc (structure_alloc_comps):
Rename array_type_nelts() => array_type_nelts_minus_one()
* trans-openmp.cc (gfc_walk_alloc_comps): Likewise.
(gfc_omp_clause_linear_ctor): Likewise.

gcc/rust/ChangeLog:

* backend/rust-tree.cc (array_type_nelts_top):
Rename array_type_nelts() => array_type_nelts_minus_one()

Suggested-by: Richard Biener 
Signed-off-by: Alejandro Colomar 
---
 gcc/c/c-decl.cc   | 10 +-
 gcc/c/c-fold.cc   |  7 ---
 gcc/config/aarch64/aarch64.cc |  2 +-
 gcc/config/i386/i386.cc   |  2 +-
 gcc/cp/decl.cc|  2 +-
 gcc/cp/init.cc|  8 
 gcc/cp/lambda.cc  |  3 ++-
 gcc/cp/tree.cc|  2 +-
 gcc/expr.cc   |  8 
 gcc/fortran/trans-array.cc|  2 +-
 gcc/fortran/trans-openmp.cc   |  4 ++--
 gcc/rust/backend/rust-tree.cc |  2 +-
 gcc/tree.cc   |  4 ++--
 gcc/tree.h|  2 +-
 14 files changed, 30 insertions(+), 28 deletions(-)

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 8cef8f2c289..e7c2783e724 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -5309,7 +5309,7 @@ one_element_array_type_p (const_tree type)
 {
   if (TREE_CODE (type) != ARRAY_TYPE)
 return false;
-  return integer_zerop (array_type_nelts (type));
+  return integer_zerop (array_type_nelts_minus_one (type));
 }
 
 /* Determine whether TYPE is a zero-length array type "[0]".  */
@@ -6257,15 +6257,15 @@ get_parm_array_spec (const struct c_parm *parm, tree 
attrs)
  for (tree type = parm->specs->type; TREE_CODE (type) == ARRAY_TYPE;
   type = TREE_TYPE (type))
{
- tree nelts = array_type_nelts (type);
- if (error_operand_p (nelts))
+ tree nelts_minus_one = array_type_nelts_minus_one (type);
+ if (error_operand_p (nelts_minus_one))
return attrs;
- if (TREE_CODE (nelts) != INTEGER_CST)
+ if (TREE_CODE (nelts_minus_one) != INTEGER_CST)
{
  /* Each variable VLA bound is represented by the dollar
 sign.  */
  spec += "$";
- tpbnds = tree_cons (NULL_TREE, nelts, tpbnds);
+ tpbnds = tree_cons (NULL_TREE, nelts_minus_one, tpbnds);
}
}
  tpbnds = nreverse (tpbnds);
diff --git a/gcc/c/c-fold.cc b/gcc/c/c-fold.cc
index 57b67c74bd8..9ea174f79c4 100644
--- a/gcc/c/c-fold.cc
+++ b/gcc/c/c-fold.cc
@@ -73,11 +73,12 @@ c_fold_array_ref (tree type, tree ary, tree index)
   unsigned elem_nchars = (TYPE_PRECISION (elem_type)
  / TYPE_PRECISION (char_type_node));
   unsigned len = (unsigned) TREE_STRING_LENGTH (ary) / elem_nchars;
-  tree nelts = array_type_nelts (TREE_TYPE (ary));
+  tree nelts_minus_one = array_type_nelts_minus_one (TREE_TYPE (ary));
   bool dummy1 = true, dummy2 = true;
-  nelts = c_fully_fold_internal (nelts, true, &dummy1, &dummy2, false, false);
+  nelts_minus_one = c_fully_fold_internal (nelts_minus_one, true, &dummy1,
+  &dummy2, false, false);
   unsigned HOST_WIDE_INT i = tree_to_uhwi (index);
-  if (!tree_int_cst_le (index, nelts)
+  if (!tree_int_cst_le (index, nelts_minu

[PATCH v7 3/3] c: Add __lengthof__ operator

2024-08-10 Thread Alejandro Colomar
This operator is similar to sizeof but can only be applied to an array,
and returns its length (number of elements).

FUTURE DIRECTIONS:

-  We should make it work with array parameters to functions,
   and somehow magically return the length designator of the array,
   regardless of it being really a pointer.

-  Fix support for [0].

Cc: Joseph Myers 
Cc: Gabriel Ravier 
Cc: Jakub Jelinek 
Cc: Kees Cook 
Cc: Qing Zhao 
Cc: Jens Gustedt 
Cc: David Brown 
Cc: Florian Weimer 
Cc: Andreas Schwab 
Cc: Timm Baeder 

gcc/ChangeLog:

* doc/extend.texi: Document __lengthof__ operator.
* target.h (enum type_context_kind): Add __lengthof__ operator.

gcc/c-family/ChangeLog:

* c-common.h:
* c-common.def:
* c-common.cc (c_lengthof_type): Add __lengthof__ operator.

gcc/c/ChangeLog:

* c-tree.h
(c_expr_lengthof_expr, c_expr_lengthof_type):
* c-decl.cc
(start_struct, finish_struct):
(start_enum, finish_enum):
* c-parser.cc
(c_parser_sizeof_expression):
(c_parser_lengthof_expression):
(c_parser_sizeof_or_lengthof_expression):
(c_parser_unary_expression):
* c-typeck.cc
(build_external_ref):
(record_maybe_used_decl, pop_maybe_used):
(is_top_array_vla):
(c_expr_lengthof_expr, c_expr_lengthof_type):
Add __lengthof__operator.

gcc/cp/ChangeLog:

* operators.def: Add __lengthof__ operator.

gcc/testsuite/ChangeLog:

* gcc.dg/lengthof-compile.c:
* gcc.dg/lengthof-vla.c:
* gcc.dg/lengthof.c: Add tests for __lengthof__ operator.

Link: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2529.pdf
Link: https://inbox.sourceware.org/gcc/m8s4oqy--...@tutanota.com/T/
Suggested-by: Xavier Del Campo Romero 
Co-developed-by: Martin Uecker 
Signed-off-by: Alejandro Colomar 
---
 gcc/c-family/c-common.cc|  26 
 gcc/c-family/c-common.def   |   3 +
 gcc/c-family/c-common.h |   2 +
 gcc/c/c-decl.cc |  20 +++-
 gcc/c/c-parser.cc   |  61 +++---
 gcc/c/c-tree.h  |   4 +
 gcc/c/c-typeck.cc   | 118 ++-
 gcc/cp/operators.def|   1 +
 gcc/doc/extend.texi |  31 +
 gcc/target.h|   3 +
 gcc/testsuite/gcc.dg/lengthof-compile.c | 115 ++
 gcc/testsuite/gcc.dg/lengthof-vla.c |  46 
 gcc/testsuite/gcc.dg/lengthof.c | 150 
 13 files changed, 556 insertions(+), 24 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/lengthof-compile.c
 create mode 100644 gcc/testsuite/gcc.dg/lengthof-vla.c
 create mode 100644 gcc/testsuite/gcc.dg/lengthof.c

diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index e7e371fd26f..9f5feb83345 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -465,6 +465,7 @@ const struct c_common_resword c_common_reswords[] =
   { "__inline",RID_INLINE, 0 },
   { "__inline__",  RID_INLINE, 0 },
   { "__label__",   RID_LABEL,  0 },
+  { "__lengthof__",RID_LENGTHOF, 0 },
   { "__null",  RID_NULL,   0 },
   { "__real",  RID_REALPART,   0 },
   { "__real__",RID_REALPART,   0 },
@@ -4070,6 +4071,31 @@ c_alignof_expr (location_t loc, tree expr)
 
   return fold_convert_loc (loc, size_type_node, t);
 }
+
+/* Implement the lengthof keyword: Return the length of an array,
+   that is, the number of elements in the array.  */
+
+tree
+c_lengthof_type (location_t loc, tree type)
+{
+  enum tree_code type_code;
+
+  type_code = TREE_CODE (type);
+  if (type_code != ARRAY_TYPE)
+{
+  error_at (loc, "invalid application of % to type %qT", type);
+  return error_mark_node;
+}
+  if (!COMPLETE_TYPE_P (type))
+{
+  error_at (loc,
+   "invalid application of % to incomplete type %qT",
+   type);
+  return error_mark_node;
+}
+
+  return array_type_nelts_top (type);
+}
 
 /* Handle C and C++ default attributes.  */
 
diff --git a/gcc/c-family/c-common.def b/gcc/c-family/c-common.def
index 5de96e5d4a8..6d162f67104 100644
--- a/gcc/c-family/c-common.def
+++ b/gcc/c-family/c-common.def
@@ -50,6 +50,9 @@ DEFTREECODE (EXCESS_PRECISION_EXPR, "excess_precision_expr", 
tcc_expression, 1)
number.  */
 DEFTREECODE (USERDEF_LITERAL, "userdef_literal", tcc_exceptional, 3)
 
+/* Represents a 'lengthof' expression.  */
+DEFTREECODE (LENGTHOF_EXPR, "lengthof_expr", tcc_expression, 1)
+
 /* Represents a 'sizeof' expression during C++ template expansion,
or for the purpose of -Wsizeof-pointer-memaccess warning.  */
 DEFTREECODE (SIZEOF_EXPR, "sizeof_expr", tcc_expression, 1)
d

[PATCH v7 2/3] Merge definitions of array_type_nelts_top()

2024-08-10 Thread Alejandro Colomar
There were two identical definitions, and none of them are available
where they are needed for implementing __lengthof__.  Merge them, and
provide the single definition in gcc/tree.{h,cc}, where it's available
for __lengthof__, which will be added in the following commit.

gcc/ChangeLog:

* tree.h (array_type_nelts_top):
* tree.cc (array_type_nelts_top): Define function (moved from
gcc/cp/).

gcc/cp/ChangeLog:

* cp-tree.h (array_type_nelts_top):
* tree.cc (array_type_nelts_top): Remove function (move
to gcc/).

gcc/rust/ChangeLog:

* backend/rust-tree.h (array_type_nelts_top):
* backend/rust-tree.cc (array_type_nelts_top): Remove function.

Signed-off-by: Alejandro Colomar 
---
 gcc/cp/cp-tree.h  |  1 -
 gcc/cp/tree.cc| 13 -
 gcc/rust/backend/rust-tree.cc | 13 -
 gcc/rust/backend/rust-tree.h  |  2 --
 gcc/tree.cc   | 13 +
 gcc/tree.h|  1 +
 6 files changed, 14 insertions(+), 29 deletions(-)

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index b1693051231..76d7bc34577 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -8100,7 +8100,6 @@ extern tree build_exception_variant   (tree, 
tree);
 extern void fixup_deferred_exception_variants   (tree, tree);
 extern tree bind_template_template_parm(tree, tree);
 extern tree array_type_nelts_total (tree);
-extern tree array_type_nelts_top   (tree);
 extern bool array_of_unknown_bound_p   (const_tree);
 extern tree break_out_target_exprs (tree, bool = false);
 extern tree build_ctor_subob_ref   (tree, tree, tree);
diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
index 040136c70ab..7d179491476 100644
--- a/gcc/cp/tree.cc
+++ b/gcc/cp/tree.cc
@@ -3079,19 +3079,6 @@ cxx_print_statistics (void)
 depth_reached);
 }
 
-/* Return, as an INTEGER_CST node, the number of elements for TYPE
-   (which is an ARRAY_TYPE).  This counts only elements of the top
-   array.  */
-
-tree
-array_type_nelts_top (tree type)
-{
-  return fold_build2_loc (input_location,
- PLUS_EXPR, sizetype,
- array_type_nelts_minus_one (type),
- size_one_node);
-}
-
 /* Return, as an INTEGER_CST node, the number of elements for TYPE
(which is an ARRAY_TYPE).  This one is a recursive count of all
ARRAY_TYPEs that are clumped together.  */
diff --git a/gcc/rust/backend/rust-tree.cc b/gcc/rust/backend/rust-tree.cc
index 8d32e5203ae..3dc6b076711 100644
--- a/gcc/rust/backend/rust-tree.cc
+++ b/gcc/rust/backend/rust-tree.cc
@@ -859,19 +859,6 @@ is_empty_class (tree type)
   return CLASSTYPE_EMPTY_P (type);
 }
 
-// forked from gcc/cp/tree.cc array_type_nelts_top
-
-/* Return, as an INTEGER_CST node, the number of elements for TYPE
-   (which is an ARRAY_TYPE).  This counts only elements of the top
-   array.  */
-
-tree
-array_type_nelts_top (tree type)
-{
-  return fold_build2_loc (input_location, PLUS_EXPR, sizetype,
- array_type_nelts_minus_one (type), size_one_node);
-}
-
 // forked from gcc/cp/tree.cc builtin_valid_in_constant_expr_p
 
 /* Test whether DECL is a builtin that may appear in a
diff --git a/gcc/rust/backend/rust-tree.h b/gcc/rust/backend/rust-tree.h
index 26c8b653ac6..e597c3ab81d 100644
--- a/gcc/rust/backend/rust-tree.h
+++ b/gcc/rust/backend/rust-tree.h
@@ -2993,8 +2993,6 @@ extern location_t rs_expr_location (const_tree);
 extern int
 is_empty_class (tree type);
 
-extern tree array_type_nelts_top (tree);
-
 extern bool
 is_really_empty_class (tree, bool);
 
diff --git a/gcc/tree.cc b/gcc/tree.cc
index ed0a766016a..cedf95cc222 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -3729,6 +3729,19 @@ array_type_nelts_minus_one (const_tree type)
  ? max
  : fold_build2 (MINUS_EXPR, TREE_TYPE (max), max, min));
 }
+
+/* Return, as an INTEGER_CST node, the number of elements for TYPE
+   (which is an ARRAY_TYPE).  This counts only elements of the top
+   array.  */
+
+tree
+array_type_nelts_top (tree type)
+{
+  return fold_build2_loc (input_location,
+ PLUS_EXPR, sizetype,
+ array_type_nelts_minus_one (type),
+ size_one_node);
+}
 
 /* If arg is static -- a reference to an object in static storage -- then
return the object.  This is not the same as the C meaning of `static'.
diff --git a/gcc/tree.h b/gcc/tree.h
index 69d40bb4f04..9061dafd027 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -4922,6 +4922,7 @@ extern tree build_method_type (tree, tree);
 extern tree build_offset_type (tree, tree);
 extern tree build_complex_type (tree, bool named = false);
 extern tree array_type_nelts_minus_one (const_tree);
+extern tree array_type_nelts_top (tree);
 
 extern tree value_member (tree, tree);
 extern tree purpose_member (const_tree, tree);
-- 
2.45.2



sig

[PATCH v8 0/3] c: Add __lengthof__ operator

2024-08-11 Thread Alejandro Colomar
Hi!

v8:

-  Reformat (simplify) change-log entries.
-  Improve wording of documentation.
-  Add link to LLVM issue in commit message.

I've added a GitHub issue in the LLVM project reporting about the
existence of this patch set:
<https://github.com/llvm/llvm-project/issues/102836>

Have a lovely night!
Alex

Alejandro Colomar (3):
  gcc/: Rename array_type_nelts() => array_type_nelts_minus_one()
  Merge definitions of array_type_nelts_top()
  c: Add __lengthof__ operator

 gcc/c-family/c-common.cc|  26 
 gcc/c-family/c-common.def   |   3 +
 gcc/c-family/c-common.h |   2 +
 gcc/c/c-decl.cc |  30 +++--
 gcc/c/c-fold.cc |   7 +-
 gcc/c/c-parser.cc   |  61 +++---
 gcc/c/c-tree.h  |   4 +
 gcc/c/c-typeck.cc   | 118 ++-
 gcc/config/aarch64/aarch64.cc   |   2 +-
 gcc/config/i386/i386.cc |   2 +-
 gcc/cp/cp-tree.h|   1 -
 gcc/cp/decl.cc  |   2 +-
 gcc/cp/init.cc  |   8 +-
 gcc/cp/lambda.cc|   3 +-
 gcc/cp/operators.def|   1 +
 gcc/cp/tree.cc  |  13 --
 gcc/doc/extend.texi |  31 +
 gcc/expr.cc |   8 +-
 gcc/fortran/trans-array.cc  |   2 +-
 gcc/fortran/trans-openmp.cc |   4 +-
 gcc/rust/backend/rust-tree.cc   |  13 --
 gcc/rust/backend/rust-tree.h|   2 -
 gcc/target.h|   3 +
 gcc/testsuite/gcc.dg/lengthof-compile.c | 115 ++
 gcc/testsuite/gcc.dg/lengthof-vla.c |  46 
 gcc/testsuite/gcc.dg/lengthof.c | 150 
 gcc/tree.cc |  17 ++-
 gcc/tree.h  |   3 +-
 28 files changed, 598 insertions(+), 79 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/lengthof-compile.c
 create mode 100644 gcc/testsuite/gcc.dg/lengthof-vla.c
 create mode 100644 gcc/testsuite/gcc.dg/lengthof.c

Range-diff against v7:
1:  8b68e250503 ! 1:  a6aa38c9013 gcc/: Rename array_type_nelts() => 
array_type_nelts_minus_one()
@@ Commit message
 
 gcc/ChangeLog:
 
-* tree.cc (array_type_nelts): Rename function ...
-(array_type_nelts_minus_one): ... to this name.  The old name
-was misleading.
-* tree.h (array_type_nelts): Rename function ...
-(array_type_nelts_minus_one): ... to this name.  The old name
-was misleading.
+* tree.cc (array_type_nelts, array_type_nelts_minus_one):
+* tree.h (array_type_nelts, array_type_nelts_minus_one):
 * expr.cc (count_type_elements):
-Rename array_type_nelts() => array_type_nelts_minus_one()
 * config/aarch64/aarch64.cc
-(pure_scalable_type_info::analyze_array): Likewise.
-* config/i386/i386.cc (ix86_canonical_va_list_type): Likewise.
+(pure_scalable_type_info::analyze_array):
+* config/i386/i386.cc (ix86_canonical_va_list_type):
+Rename array_type_nelts() => array_type_nelts_minus_one()
+The old name was misleading.
 
 gcc/c/ChangeLog:
 
 * c-decl.cc (one_element_array_type_p, get_parm_array_spec):
+* c-fold.cc (c_fold_array_ref):
 Rename array_type_nelts() => array_type_nelts_minus_one()
-* c-fold.cc (c_fold_array_ref): Likewise.
 
 gcc/cp/ChangeLog:
 
 * decl.cc (reshape_init_array):
+* init.cc
+(build_zero_init_1):
+(build_value_init_noctor):
+(build_vec_init):
+(build_delete):
+* lambda.cc (add_capture):
+* tree.cc (array_type_nelts_top):
 Rename array_type_nelts() => array_type_nelts_minus_one()
-* init.cc (build_zero_init_1): Likewise.
-(build_value_init_noctor): Likewise.
-(build_vec_init): Likewise.
-(build_delete): Likewise.
-* lambda.cc (add_capture): Likewise.
-* tree.cc (array_type_nelts_top): Likewise.
 
 gcc/fortran/ChangeLog:
 
 * trans-array.cc (structure_alloc_comps):
+* trans-openmp.cc
+(gfc_walk_alloc_comps):
+(gfc_omp_clause_linear_ctor):
 Rename array_type_nelts() => array_type_nelts_minus_one()
-* trans-openmp.cc (gfc_walk_alloc_comps): Likewise.
-(gfc_omp_clause_linear_ctor): Likewise.
 
 gcc/rust/ChangeLog:
 
2:  21433097103 ! 2

[PATCH v8 2/3] Merge definitions of array_type_nelts_top()

2024-08-11 Thread Alejandro Colomar
There were two identical definitions, and none of them are available
where they are needed for implementing __lengthof__.  Merge them, and
provide the single definition in gcc/tree.{h,cc}, where it's available
for __lengthof__, which will be added in the following commit.

gcc/ChangeLog:

* tree.h (array_type_nelts_top):
* tree.cc (array_type_nelts_top):
Define function (moved from gcc/cp/).

gcc/cp/ChangeLog:

* cp-tree.h (array_type_nelts_top):
* tree.cc (array_type_nelts_top):
Remove function (move to gcc/).

gcc/rust/ChangeLog:

* backend/rust-tree.h (array_type_nelts_top):
* backend/rust-tree.cc (array_type_nelts_top):
Remove function.

Signed-off-by: Alejandro Colomar 
---
 gcc/cp/cp-tree.h  |  1 -
 gcc/cp/tree.cc| 13 -
 gcc/rust/backend/rust-tree.cc | 13 -
 gcc/rust/backend/rust-tree.h  |  2 --
 gcc/tree.cc   | 13 +
 gcc/tree.h|  1 +
 6 files changed, 14 insertions(+), 29 deletions(-)

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index b1693051231..76d7bc34577 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -8100,7 +8100,6 @@ extern tree build_exception_variant   (tree, 
tree);
 extern void fixup_deferred_exception_variants   (tree, tree);
 extern tree bind_template_template_parm(tree, tree);
 extern tree array_type_nelts_total (tree);
-extern tree array_type_nelts_top   (tree);
 extern bool array_of_unknown_bound_p   (const_tree);
 extern tree break_out_target_exprs (tree, bool = false);
 extern tree build_ctor_subob_ref   (tree, tree, tree);
diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
index 040136c70ab..7d179491476 100644
--- a/gcc/cp/tree.cc
+++ b/gcc/cp/tree.cc
@@ -3079,19 +3079,6 @@ cxx_print_statistics (void)
 depth_reached);
 }
 
-/* Return, as an INTEGER_CST node, the number of elements for TYPE
-   (which is an ARRAY_TYPE).  This counts only elements of the top
-   array.  */
-
-tree
-array_type_nelts_top (tree type)
-{
-  return fold_build2_loc (input_location,
- PLUS_EXPR, sizetype,
- array_type_nelts_minus_one (type),
- size_one_node);
-}
-
 /* Return, as an INTEGER_CST node, the number of elements for TYPE
(which is an ARRAY_TYPE).  This one is a recursive count of all
ARRAY_TYPEs that are clumped together.  */
diff --git a/gcc/rust/backend/rust-tree.cc b/gcc/rust/backend/rust-tree.cc
index 8d32e5203ae..3dc6b076711 100644
--- a/gcc/rust/backend/rust-tree.cc
+++ b/gcc/rust/backend/rust-tree.cc
@@ -859,19 +859,6 @@ is_empty_class (tree type)
   return CLASSTYPE_EMPTY_P (type);
 }
 
-// forked from gcc/cp/tree.cc array_type_nelts_top
-
-/* Return, as an INTEGER_CST node, the number of elements for TYPE
-   (which is an ARRAY_TYPE).  This counts only elements of the top
-   array.  */
-
-tree
-array_type_nelts_top (tree type)
-{
-  return fold_build2_loc (input_location, PLUS_EXPR, sizetype,
- array_type_nelts_minus_one (type), size_one_node);
-}
-
 // forked from gcc/cp/tree.cc builtin_valid_in_constant_expr_p
 
 /* Test whether DECL is a builtin that may appear in a
diff --git a/gcc/rust/backend/rust-tree.h b/gcc/rust/backend/rust-tree.h
index 26c8b653ac6..e597c3ab81d 100644
--- a/gcc/rust/backend/rust-tree.h
+++ b/gcc/rust/backend/rust-tree.h
@@ -2993,8 +2993,6 @@ extern location_t rs_expr_location (const_tree);
 extern int
 is_empty_class (tree type);
 
-extern tree array_type_nelts_top (tree);
-
 extern bool
 is_really_empty_class (tree, bool);
 
diff --git a/gcc/tree.cc b/gcc/tree.cc
index ed0a766016a..cedf95cc222 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -3729,6 +3729,19 @@ array_type_nelts_minus_one (const_tree type)
  ? max
  : fold_build2 (MINUS_EXPR, TREE_TYPE (max), max, min));
 }
+
+/* Return, as an INTEGER_CST node, the number of elements for TYPE
+   (which is an ARRAY_TYPE).  This counts only elements of the top
+   array.  */
+
+tree
+array_type_nelts_top (tree type)
+{
+  return fold_build2_loc (input_location,
+ PLUS_EXPR, sizetype,
+ array_type_nelts_minus_one (type),
+ size_one_node);
+}
 
 /* If arg is static -- a reference to an object in static storage -- then
return the object.  This is not the same as the C meaning of `static'.
diff --git a/gcc/tree.h b/gcc/tree.h
index 69d40bb4f04..9061dafd027 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -4922,6 +4922,7 @@ extern tree build_method_type (tree, tree);
 extern tree build_offset_type (tree, tree);
 extern tree build_complex_type (tree, bool named = false);
 extern tree array_type_nelts_minus_one (const_tree);
+extern tree array_type_nelts_top (tree);
 
 extern tree value_member (tree, tree);
 extern tree purpose_member (const_tree, tree);
-- 
2.45.2



sig

[PATCH v8 1/3] gcc/: Rename array_type_nelts() => array_type_nelts_minus_one()

2024-08-11 Thread Alejandro Colomar
The old name was misleading.

While at it, also rename some temporary variables that are used with
this function, for consistency.

Link: 
https://inbox.sourceware.org/gcc-patches/9fffd80-dca-2c7e-14b-6c9b509a7...@redhat.com/T/#m2f661c67c8f7b2c405c8c7fc3152dd85dc729120
Cc: Gabriel Ravier 
Cc: Martin Uecker 
Cc: Joseph Myers 
Cc: Xavier Del Campo Romero 
Cc: Jakub Jelinek 

gcc/ChangeLog:

* tree.cc (array_type_nelts, array_type_nelts_minus_one):
* tree.h (array_type_nelts, array_type_nelts_minus_one):
* expr.cc (count_type_elements):
* config/aarch64/aarch64.cc
(pure_scalable_type_info::analyze_array):
* config/i386/i386.cc (ix86_canonical_va_list_type):
Rename array_type_nelts() => array_type_nelts_minus_one()
The old name was misleading.

gcc/c/ChangeLog:

* c-decl.cc (one_element_array_type_p, get_parm_array_spec):
* c-fold.cc (c_fold_array_ref):
Rename array_type_nelts() => array_type_nelts_minus_one()

gcc/cp/ChangeLog:

* decl.cc (reshape_init_array):
* init.cc
(build_zero_init_1):
(build_value_init_noctor):
(build_vec_init):
(build_delete):
* lambda.cc (add_capture):
* tree.cc (array_type_nelts_top):
Rename array_type_nelts() => array_type_nelts_minus_one()

gcc/fortran/ChangeLog:

* trans-array.cc (structure_alloc_comps):
* trans-openmp.cc
(gfc_walk_alloc_comps):
(gfc_omp_clause_linear_ctor):
Rename array_type_nelts() => array_type_nelts_minus_one()

gcc/rust/ChangeLog:

* backend/rust-tree.cc (array_type_nelts_top):
Rename array_type_nelts() => array_type_nelts_minus_one()

Suggested-by: Richard Biener 
Signed-off-by: Alejandro Colomar 
---
 gcc/c/c-decl.cc   | 10 +-
 gcc/c/c-fold.cc   |  7 ---
 gcc/config/aarch64/aarch64.cc |  2 +-
 gcc/config/i386/i386.cc   |  2 +-
 gcc/cp/decl.cc|  2 +-
 gcc/cp/init.cc|  8 
 gcc/cp/lambda.cc  |  3 ++-
 gcc/cp/tree.cc|  2 +-
 gcc/expr.cc   |  8 
 gcc/fortran/trans-array.cc|  2 +-
 gcc/fortran/trans-openmp.cc   |  4 ++--
 gcc/rust/backend/rust-tree.cc |  2 +-
 gcc/tree.cc   |  4 ++--
 gcc/tree.h|  2 +-
 14 files changed, 30 insertions(+), 28 deletions(-)

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 8cef8f2c289..e7c2783e724 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -5309,7 +5309,7 @@ one_element_array_type_p (const_tree type)
 {
   if (TREE_CODE (type) != ARRAY_TYPE)
 return false;
-  return integer_zerop (array_type_nelts (type));
+  return integer_zerop (array_type_nelts_minus_one (type));
 }
 
 /* Determine whether TYPE is a zero-length array type "[0]".  */
@@ -6257,15 +6257,15 @@ get_parm_array_spec (const struct c_parm *parm, tree 
attrs)
  for (tree type = parm->specs->type; TREE_CODE (type) == ARRAY_TYPE;
   type = TREE_TYPE (type))
{
- tree nelts = array_type_nelts (type);
- if (error_operand_p (nelts))
+ tree nelts_minus_one = array_type_nelts_minus_one (type);
+ if (error_operand_p (nelts_minus_one))
return attrs;
- if (TREE_CODE (nelts) != INTEGER_CST)
+ if (TREE_CODE (nelts_minus_one) != INTEGER_CST)
{
  /* Each variable VLA bound is represented by the dollar
 sign.  */
  spec += "$";
- tpbnds = tree_cons (NULL_TREE, nelts, tpbnds);
+ tpbnds = tree_cons (NULL_TREE, nelts_minus_one, tpbnds);
}
}
  tpbnds = nreverse (tpbnds);
diff --git a/gcc/c/c-fold.cc b/gcc/c/c-fold.cc
index 57b67c74bd8..9ea174f79c4 100644
--- a/gcc/c/c-fold.cc
+++ b/gcc/c/c-fold.cc
@@ -73,11 +73,12 @@ c_fold_array_ref (tree type, tree ary, tree index)
   unsigned elem_nchars = (TYPE_PRECISION (elem_type)
  / TYPE_PRECISION (char_type_node));
   unsigned len = (unsigned) TREE_STRING_LENGTH (ary) / elem_nchars;
-  tree nelts = array_type_nelts (TREE_TYPE (ary));
+  tree nelts_minus_one = array_type_nelts_minus_one (TREE_TYPE (ary));
   bool dummy1 = true, dummy2 = true;
-  nelts = c_fully_fold_internal (nelts, true, &dummy1, &dummy2, false, false);
+  nelts_minus_one = c_fully_fold_internal (nelts_minus_one, true, &dummy1,
+  &dummy2, false, false);
   unsigned HOST_WIDE_INT i = tree_to_uhwi (index);
-  if (!tree_int_cst_le (index, nelts)
+  if (!tree_int_cst_le (index, nelts_minus_one)
   || i >= len
   || i + elem_nchars > len)
 return NULL_TREE;
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 2ac5a22c848..a757796afcf 100644
--- a/gcc/config/aarch64/aa

[PATCH v8 3/3] c: Add __lengthof__ operator

2024-08-11 Thread Alejandro Colomar
This operator is similar to sizeof but can only be applied to an array,
and returns its length (number of elements).

FUTURE DIRECTIONS:

-  We should make it work with array parameters to functions,
   and somehow magically return the length designator of the array,
   regardless of it being really a pointer.

-  Fix support for [0].

Cc: Joseph Myers 
Cc: Gabriel Ravier 
Cc: Jakub Jelinek 
Cc: Kees Cook 
Cc: Qing Zhao 
Cc: Jens Gustedt 
Cc: David Brown 
Cc: Florian Weimer 
Cc: Andreas Schwab 
Cc: Timm Baeder 

gcc/ChangeLog:

* doc/extend.texi: Document __lengthof__ operator.
* target.h (enum type_context_kind): Add __lengthof__ operator.

gcc/c-family/ChangeLog:

* c-common.h:
* c-common.def:
* c-common.cc (c_lengthof_type): Add __lengthof__ operator.

gcc/c/ChangeLog:

* c-tree.h
(c_expr_lengthof_expr, c_expr_lengthof_type):
* c-decl.cc
(start_struct, finish_struct):
(start_enum, finish_enum):
* c-parser.cc
(c_parser_sizeof_expression):
(c_parser_lengthof_expression):
(c_parser_sizeof_or_lengthof_expression):
(c_parser_unary_expression):
* c-typeck.cc
(build_external_ref):
(record_maybe_used_decl, pop_maybe_used):
(is_top_array_vla):
(c_expr_lengthof_expr, c_expr_lengthof_type):
Add __lengthof__operator.

gcc/cp/ChangeLog:

* operators.def: Add __lengthof__ operator.

gcc/testsuite/ChangeLog:

* gcc.dg/lengthof-compile.c:
* gcc.dg/lengthof-vla.c:
* gcc.dg/lengthof.c: Add tests for __lengthof__ operator.

Link: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2529.pdf
Link: https://inbox.sourceware.org/gcc/m8s4oqy--...@tutanota.com/T/
Link: https://github.com/llvm/llvm-project/issues/102836
Suggested-by: Xavier Del Campo Romero 
Co-developed-by: Martin Uecker 
Signed-off-by: Alejandro Colomar 
---
 gcc/c-family/c-common.cc|  26 
 gcc/c-family/c-common.def   |   3 +
 gcc/c-family/c-common.h |   2 +
 gcc/c/c-decl.cc |  20 +++-
 gcc/c/c-parser.cc   |  61 +++---
 gcc/c/c-tree.h  |   4 +
 gcc/c/c-typeck.cc   | 118 ++-
 gcc/cp/operators.def|   1 +
 gcc/doc/extend.texi |  31 +
 gcc/target.h|   3 +
 gcc/testsuite/gcc.dg/lengthof-compile.c | 115 ++
 gcc/testsuite/gcc.dg/lengthof-vla.c |  46 
 gcc/testsuite/gcc.dg/lengthof.c | 150 
 13 files changed, 556 insertions(+), 24 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/lengthof-compile.c
 create mode 100644 gcc/testsuite/gcc.dg/lengthof-vla.c
 create mode 100644 gcc/testsuite/gcc.dg/lengthof.c

diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index e7e371fd26f..9f5feb83345 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -465,6 +465,7 @@ const struct c_common_resword c_common_reswords[] =
   { "__inline",RID_INLINE, 0 },
   { "__inline__",  RID_INLINE, 0 },
   { "__label__",   RID_LABEL,  0 },
+  { "__lengthof__",RID_LENGTHOF, 0 },
   { "__null",  RID_NULL,   0 },
   { "__real",  RID_REALPART,   0 },
   { "__real__",RID_REALPART,   0 },
@@ -4070,6 +4071,31 @@ c_alignof_expr (location_t loc, tree expr)
 
   return fold_convert_loc (loc, size_type_node, t);
 }
+
+/* Implement the lengthof keyword: Return the length of an array,
+   that is, the number of elements in the array.  */
+
+tree
+c_lengthof_type (location_t loc, tree type)
+{
+  enum tree_code type_code;
+
+  type_code = TREE_CODE (type);
+  if (type_code != ARRAY_TYPE)
+{
+  error_at (loc, "invalid application of % to type %qT", type);
+  return error_mark_node;
+}
+  if (!COMPLETE_TYPE_P (type))
+{
+  error_at (loc,
+   "invalid application of % to incomplete type %qT",
+   type);
+  return error_mark_node;
+}
+
+  return array_type_nelts_top (type);
+}
 
 /* Handle C and C++ default attributes.  */
 
diff --git a/gcc/c-family/c-common.def b/gcc/c-family/c-common.def
index 5de96e5d4a8..6d162f67104 100644
--- a/gcc/c-family/c-common.def
+++ b/gcc/c-family/c-common.def
@@ -50,6 +50,9 @@ DEFTREECODE (EXCESS_PRECISION_EXPR, "excess_precision_expr", 
tcc_expression, 1)
number.  */
 DEFTREECODE (USERDEF_LITERAL, "userdef_literal", tcc_exceptional, 3)
 
+/* Represents a 'lengthof' expression.  */
+DEFTREECODE (LENGTHOF_EXPR, "lengthof_expr", tcc_expression, 1)
+
 /* Represents a 'sizeof' expression during C++ template expansion,
or for the purpose of -Wsizeof-pointer-memaccess warning.  */
 DEFTREECODE (

[WG14] Request for document number; _Lengthof

2024-08-12 Thread Alejandro Colomar
Hi David,

I want to send an updated version of n2529.  The original author didn't
respond to my mail, so I'll take over.  I've been preparing a GCC patch
set for adding the feature to GCC, and have informed Clang developers
about it too.

The title would be

_Lengthof - New pointer-proof keyword to determine array length (v2)

Can you please assign me a number for it?  Thanks.

Cheers,
Alex


-- 



signature.asc
Description: PGP signature


Re: [committed] testsuite: Fix up sse3-addsubps.c

2024-08-12 Thread Alejandro Colomar
Hi Jakub,

On Sat, Aug 10, 2024 at 10:57:25AM GMT, Jakub Jelinek wrote:
> This is an obvious typo as can be seen in what the test does, what similar
> tests committed in the same commit do (all the others use sizeof (vals) /
> sizeof (vals[0])) and what the test originates from (i386/sse3-addsubps.c
> uses there constant 80, which is that sizeof (vals) / sizeof (vals[0])).
> 
> Tested on powerpc64-linux (where the test is UNSUPPORTED) and
> powerpc64le-linux, where the test passes before (in that case it tests just
> one vector rather than all 10) and after the change.
> 
> Committed to trunk as obvious.
> 
> 2024-08-10  Jakub Jelinek  
> 
>   * gcc.target/powerpc/sse3-addsubps.c (TEST): Divide by
>   sizeof (vals[0]) rather than sizeof (vals).
> 
> --- gcc/testsuite/gcc.target/powerpc/sse3-addsubps.c.jj3  2024-03-18 
> 11:02:16.152884555 +
> +++ gcc/testsuite/gcc.target/powerpc/sse3-addsubps.c  2024-08-10 
> 08:46:57.259430503 +
> @@ -77,7 +77,7 @@ TEST (void)
>int i;
>int fail = 0;
>  
> -  for (i = 0; i < sizeof (vals) / sizeof (vals); i += 8)
> +  for (i = 0; i < sizeof (vals) / sizeof (vals[0]); i += 8)
>  {
>p1[0] = vals[i+0];
>p1[1] = vals[i+1];

Thanks for this, and also for

commit 723e0f724e0c884a31ddf4a688604e7163ed31f2
Author: Jakub Jelinek 
Date:   Fri Aug 9 09:34:50 2024 +0200

c-family: Add some more ARRAY_SIZE uses

These two spots were just non-standard, because they divided
sizeof (omp_pragmas_simd) by sizeof (*omp_pragmas) and not
the expected sizeof (*omp_pragmas_simd) and so weren't converted
into ARRAY_SIZE.  Both of the latter sizes are the same though,
as both arrays have the same type, so this patch doesn't change
anything but readability.

2024-08-09  Jakub Jelinek  

* c-pragma.cc (c_pp_lookup_pragma): Use ARRAY_SIZE in
n_omp_pragmas_simd initializer.
(init_pragmas): Likewise.


(It would be nice if the commit messages would have included something
 like Reported-by or an equivalent.)  :)

Have a lovely night!
Alex


-- 



signature.asc
Description: PGP signature


Re: [WG14] Request for document number; _Lengthof

2024-08-13 Thread Alejandro Colomar
On Tue, Aug 13, 2024 at 01:34:58AM GMT, Alejandro Colomar wrote:
> Hi David,

I obviously meant Daniel.  :-)

> 
> I want to send an updated version of n2529.  The original author didn't
> respond to my mail, so I'll take over.  I've been preparing a GCC patch
> set for adding the feature to GCC, and have informed Clang developers
> about it too.
> 
> The title would be
> 
> _Lengthof - New pointer-proof keyword to determine array length (v2)
> 
> Can you please assign me a number for it?  Thanks.
> 
> Cheers,
> Alex
> 
> 
> -- 
> <https://www.alejandro-colomar.es/>



-- 
<https://www.alejandro-colomar.es/>


signature.asc
Description: PGP signature


v2.1 Draft for a lengthof paper

2024-08-13 Thread Alejandro Colomar
Hi,

On Tue, Aug 13, 2024 at 01:34:58AM GMT, Alejandro Colomar wrote:
> I want to send an updated version of n2529.  The original author didn't
> respond to my mail, so I'll take over.  I've been preparing a GCC patch
> set for adding the feature to GCC, and have informed Clang developers
> about it too.
> 
> The title would be
> 
> _Lengthof - New pointer-proof keyword to determine array length (v2)
> 
> Can you please assign me a number for it?  Thanks.

Attached is a draft for a paper (both the man(7) source and the
generated PDF).

I have only added lengthof for now, not _Lengthof, as suggested by Jens.
Depending on feedback, I'll propose the uglified version.

Cheers,
Alex

-- 
<https://www.alejandro-colomar.es/>


lengthof.man
Description: Unix manual page


lengthof.pdf
Description: Adobe PDF document


signature.asc
Description: PGP signature


Re: v2.1 Draft for a lengthof paper

2024-08-13 Thread Alejandro Colomar
Hi Xavier,

On Wed, Aug 14, 2024 at 12:38:53AM GMT, Xavier Del Campo Romero wrote:
> I have been overseeing these last emails -

Ahhh, good to know; thanks!  :)

> thank you very much for your
> efforts, Alex!

:-)

> I did not reply until now because I do not have prior
> experience with gcc internals, so my feedback would probably have not
> been that useful.

Ok.

> Those emails from 2020 were in fact discussing two completely different
> proposals at once:
> 
> 1. Add _Lengthof + #include 
> 2. Allow static qualifier on compound literals

Yup.

> Whereas proposal #2 made it into C23 (kudos to Jens Gustedt!), and as
> you already know by now, proposal #1 received some negative feedback,
> suggesting _Typeof/typeof + some macro magic as a pragmatic workaround
> instead.

The original author of that negative feedback talked to me in private
a week ago, and said he likes my proposal.  We have no negative feedback
anymore.  :)

> Since the proposal did not get much traction and I would had been
> unable to contribute to gcc myself, I just gave up on it. IIRC the
> deadline for new proposals closed soon after, anyway.

Ok.

> But I am glad that someone with proper experience took the initiative.

Fun fact: this is my second non-trivial patch to GCC.  I wouldn't say I
had the proper experience with GCC internals when I started this patch
set.  But I'm unemployed at the moment, which gives me all the time I
need for learning those.  :)

> I still think the proposal is relevant and has interesting use cases.
> 
> > I have only added lengthof for now, not _Lengthof, as suggested by Jens.
> > Depending on feedback, I'll propose the uglified version.
> 
> Probably, all of us know why the uglified version is the usual approach
> preferred by the C standard: we do not know how many applications would
> break otherwise.

Yup.

> However, we see that this trend is now changing with C23, so probably
> it makes sense to define lengthof directly.

Yeah, since Jens is in WG14 and he suggested to follow this trend, maybe
we can.  If not, it's trivial to change the proposal to use the uglified
name plus a macro.

Checking , I see that while several
projects have a lengthof() macro, all of them use it with semantics
compatible with this keyword, so it shouldn't break too much.  Maybe
those projects will start receiving diagnostics that they're redefining
a standard keyword, but that's not too bad.

> As for the parentheses, I personally think lengthof should follow
> similar rules compared to sizeof.

I think most people agree with this.

> 
> Best regards,

Have a lovely night!
Alex

-- 



signature.asc
Description: PGP signature


Re: v2.1 Draft for a lengthof paper

2024-08-14 Thread Alejandro Colomar
Hi Jens, Martin,

On Wed, Aug 14, 2024 at 08:11:20AM GMT, Jens Gustedt wrote:
> > Checking , I see that while several
> > projects have a lengthof() macro, all of them use it with semantics
> > compatible with this keyword, so it shouldn't break too much.  Maybe
> > those projects will start receiving diagnostics that they're redefining
> > a standard keyword, but that's not too bad.
> 
> For a WG14 paper you should add these findings to support that choice.
> Another option would be for WG14 to standardize the then existing 
> implementation with the double underscores.

Makes sense; I'll add that into new "Prior art" and "Backwards
compatibility" sections within the paper.

> > > As for the parentheses, I personally think lengthof should follow
> > > similar rules compared to sizeof.
> > 
> > I think most people agree with this.
> 
> I still don't, in particular not for standardisation.
> 
> We have to remember that there are many small C compilers out there. 
> I would not want unnecessary burden on them. So my preferred choice would be
> a standardisation as a macro, similar to offsetof.
> gcc (and clang) could then just map that to their builtin, other compilers 
> could use
> whatever they have at the moment, even just the macros that you have in the 
> paper as a starting point. 
> 
> The rest would be "quality of implementation"

Hmmm, sounds reasonable.

Some doubts:

If we allow a compiler to implement it as a predefined macro that
expands to the usual sizeof division, it might produce double evaluation
in some VLA cases.  That would be surprising to some programs, which may
expect either 0 or 1 evaluations, but not 2.  Maybe we can leave it as
unspecified behavior, and an implementation may document that double
evaluation may happen if the input is a VLA?

> What time horizon do you see to add the feature for array parameters?

Martin, what do you think?  I think the only blocking thing for me is
what you mentioned about turning function parameters into arrays that
decay almost everywhere.  Once that's set up, my code will probably work
with them without modification, or maybe with just a little tweak.  Do
you have an idea of how much time that can take you?

I expect it to be well before C2y.  Maybe a year or two?

Have a lovely day!
Alex

> Thanks
> Jens

-- 



signature.asc
Description: PGP signature


Re: v2.1 Draft for a lengthof paper

2024-08-14 Thread Alejandro Colomar
Hi Aaron, Jens,

On Wed, Aug 14, 2024 at 02:17:52PM GMT, Jens Gustedt wrote:
> Am 14. August 2024 13:31:19 MESZ schrieb "Ballman, Aaron" 
> :
> > Sorry for top-posting, my work account is stuck on Outlook. :-/
> > 
> > > For a WG14 paper you should add these findings to support that choice.
> > > Another option would be for WG14 to standardize the then existing 
> > > implementation with the double underscores.
> > 
> > +1, it's always good to explain prior art and existing uses as part
> > of the paper. However, please also point out that C++ has a prior
> > art as well which is slightly different and very much worth
> > considering: they have one API for getting the array's rank,
> > and another for getting a specific rank's extent. This is a general
> > solution that doesn't require the programmer to have deep knowledge
> > of C's declarator syntax and how it relates to multidimensional
> > arrays.

I have added that to my draft.  I'll publish it soon as a reply to the
GCC mailing list.  See below for details of what I have added for now.

> > 
> > That said, I suspect WG14 would not be keen on standardizing
> > `lengthof` without an ugly keyword given that there are plenty of other 
> > uses of it that would break: 
> > 
> > https://sourcegraph.com/github.com/illumos/illumos-gate/-/blob/usr/src/cmd/mailx/names.c?L53-55
> > https://sourcegraph.com/github.com/Rockbox/rockbox/-/blob/tools/ipod_fw.c?L292-294
> > https://sourcegraph.com/github.com/OpenSmalltalk/opensmalltalk-vm/-/blob/src/spur64.stack/validImage.c?L7014-7018
> > (and many, many others)

What regex did you use for searching?

I was thinking of renaming the proposal to elementsof(), to avoid
confusion between length of an array and length of a string.  Would you
mind checking if elementsof() is ok?

> > >> > As for the parentheses, I personally think lengthof should follow 
> > >> > similar rules compared to sizeof.
> > >> 
> > >> I think most people agree with this.
> > >
> > > I still don't, in particular not for standardisation.
> > > 
> > > We have to remember that there are many small C compilers out there.
> > 
> > Those compilers already have to handle parsing this for sizeof, so
> > that's not particularly compelling

Agree.  I suspect it will be simpler for existing compilers to follow
sizeof than to have new syntax.  However, it's easy to keep it as a QoI
detail, so I've temporarily changed the wording to require parentheses,
and let implementations lift that restriction.

> > (even if we wanted to design C
> > for the lowest common denominator of implementation effort, which
> > I'm not convinced is a good approach these days).

Off-topic, but I wish that had been the approach when a few
implementations (I suspect proprietary vendors; this was never
disclosed) rejected redefining NULL as the right thing: (void *) 0.

I fixed one of the last free-software implementations of NULL that
expanded to 0, and nullptr would probably never have been added if WG14
had not accepted the pressure from such horrible implementations.



> > That said, if we went with a rank/extent design, I think we'd *have*
> > to use parens because the extent interface would take two operands
> > (the array and the rank you're interested in getting the extent of)
> > and it would be inconsistent for the rank interface to then not
> > require parens.

   Prior art
 C
It is common in C programs to get the number of elements of
an array via the usual sizeof division and  wrap  it  in  a
macro.  Common names include:

•  ARRAY_SIZE()
•  NELEM()
•  NELEMS()
•  NITEMS()
•  NELTS()
•  elementsof()
•  lengthof()

 C++
In  C++,  there  are several standard features to determine
the number of elements of an array:

std::size()   (since C++17)
std::ssize()  (since C++20)
   The syntax of these is  identical  to  the  usual  C
   macros named above.

   It’s  a  bit different, since it’s a general purpose
   sizing template, which works on non‐array types too,
   with different semantics.

   But when applied to an array, it has the same seman‐
   tics as the macros above.

std::extent  (since C++23)
   The syntax of this is quite different.   It  uses  a
   numeric index as a second parameter to determine the
   dimension  in which the number of elements should be
   counted.

   C arrays are much simpler than C++’s many array‐like
   types, and I don’t see a reason why  we  would  need
   something  as  complex  as  std::extent  in C.  Cer‐
   tainly, existing projects have not developed such  a
   

Re: v2.1 Draft for a lengthof paper

2024-08-14 Thread Alejandro Colomar
Hi Aaron,

On Wed, Aug 14, 2024 at 12:40:41PM GMT, Ballman, Aaron wrote:
> > We should not impose an implementation in the language where doing
> > it in a header can be completely sufficient.
> 
> But can doing this in a header be completely sufficient in practice?
> e.g., the user who passes a pointer rather than an array is in for
> quite a surprise, or passing a struct, or passing a FAM, etc. If we
> want to put constraints on the interface, that may be more challenging
> to do from a header file than from the compiler.

I've provided a C23-portable and safe implementation of lengthof() as a
macro:

   Portability
 Prior  to C23 it was impossible to do this portably, but since C23
 it is possible to portably write a macro that determines the  num‐
 ber  of  elements  of an array, that is, the number of elements in
 the array.

#define must_be(e)  \
(   \
0 * (int) sizeof(   \
struct {\
static_assert(e);   \
int ISO_C_forbids_a_struct_with_no_members; \
}   \
)   \
)
#define is_array(a) \
(   \
_Generic(&(a),  \
typeof((a)[0]) **:  0,  \
default:1   \
)   \
)
#define sizeof_array(a)  (sizeof(a) + must_be(is_array(a)))
#define nitems(a)(sizeof_array(a) / sizeof((a)[0]))

 While diagnostics could be better, with good  helper‐macro  names,
 they are decent.

The issues with this implementation are also listed in the paper.
Here's a TL;DR:

-  It doesn't accept type names.

-  In results unnecessarily in run-time values where a keyword could
   result in an integer constant expression:

int  a[7][n];
int  (*p)[7][n];

p = &a;
nitems(*p++);

-  Double evaluation: not only the macro evaluates in more cases than a
   keyword, it evaluates twice (due to the two sizeof calls).

-  Less diagnostics.  Since there are less constant expressions, there
   are less opportunities to catch UB.

So far, we've lived with all of those issues (plus the lack of
portability, since this could only be implemented via compiler
extensions until C23).

But ideally, I'd like to avoid the wording juggling that would be
required to allow such an implementation.  Here's an example of the
difference in wording that would be required:

 The elementsof operator yields the number of elements
 of its operand.
 The number of elements is determined from the type of the operand.
 The result is an integer.
 If the number of elements of the array type is variable,
 the operand is evaluated;
+otherwise,
+if the operand is a variable-length array,
+it is unspecified whether the operand is evaluated;
 otherwise,
 the operand is not evaluated and the result is an integer constant.
+If the operand is evaluated,
+it is unspecified the number of times it is evaluated.

Which sounds very suspicious.

> I'm still thinking on how important rank + extent is vs overall array
> length. If C had constexpr functions, then I'd almost certainly want
> array rank and extent to be the building blocks and then lengthof can
> be a constexpr function looping over rank and summing extents. But we
> don't have that yet, and "bird hand" vs "bird in bush"... :-D

Or you can build it the other way around: define extent() as a macro
that wraps lengthof().

About rank, I suspect you could also develop something with _Generic(3),
but I didn't try.

Cheers,
Alex

-- 



signature.asc
Description: PGP signature


Re: v2.1 Draft for a lengthof paper

2024-08-14 Thread Alejandro Colomar
Hi Aaron,

On Wed, Aug 14, 2024 at 01:21:18PM GMT, Ballman, Aaron wrote:
> > What regex did you use for searching?
> 
> I went cheap and easy rather than trying to narrow down:
> https://sourcegraph.com/search?q=context:global+lang:C+lengthof&patternType=regexp&sm=0

Ahh, context:global seems to be what I wanted.  Where is that
documented?

> > I was thinking of renaming the proposal to elementsof(), to avoid confusion 
> > between length of an array and length of a string.  Would you mind checking 
> > if elementsof() is ok?
> 
> From what I was seeing, it looks to be used more uniformly as a
> function-like macro accepting a single argument.

Thanks!  I'll rename it to elementsof().

Cheers,
Alex

> ~Aaron

-- 



signature.asc
Description: PGP signature


Re: v2.1 Draft for a lengthof paper

2024-08-14 Thread Alejandro Colomar
Hi Martin,

On Wed, Aug 14, 2024 at 03:50:00PM GMT, Martin Uecker wrote:
> An operator that returns an array with all dimensions of a multi-dimensional
> array would make a a lot of sense to me. 
> 
> 
> double array[4][3][2];
> 
> // array_dims(array) = (constexpr size_t[3]){ 4, 3, 2 }

And what if array[4][n][2]?  No constexpr anymore, which is bad.

> 
> int dim1 = (array_dims(array))[0]
> int dim2 = (array_dims(array))[1]
> int dim3 = (array_dims(array))[2]
>  
> You can then implement lengthof in terms of this operator:
> 
> #define lengthof(x) (array_dims(array)[0])

Not really.  This implementation would result in less constant
expressions that my proposal.  That's detrimental for diagnostics and
usability.

And the fundamental operator would be very complex, to allow users
implementing simpler wrappers.  I think the fundamental operators should
be as simple as possible, in the spirit of C, and let users build on top
of those basic tools.

This reminds me of the 'static' specifier for array parameters, which is
conflated with two meanings: nonnull and length.  I'd rather have a way
to specify nullness, and another one to specify length, and let users
compose them.

At first glance I oppose this array_dims operator.

> and you can obtain the rank by applying lengthof to the array:
> 
> #define rank(x) lengthof(array_dims(x))

I'm curious to see what kind of code would be enabled by a rank()
operator in C that we can't write at the moment.

> If the array is constexpr for regular arrays and array
> indexing returns a constant again for constexpr arrays, this
> would all work out.
> 
> Martin

Have a lovely day!
Alex

-- 



signature.asc
Description: PGP signature


Re: v2.1 Draft for a lengthof paper

2024-08-14 Thread Alejandro Colomar
Hi Aaron,

On Wed, Aug 14, 2024 at 01:59:58PM GMT, Ballman, Aaron wrote:
> > Why would you be looping? lengthof only addresses the outer dimension 
> > sizeof would need a loop, no ?
> 
> Due to poor reading comprehension, I missed in the paper that lengthof
> works on the outer dimension. 😉 I think having a way to get the
> flattened size of a multidimensional array is a useful feature.

As long as you know the type of the inner-most element, you can do it.
This excludes auto, but I think you usually know this.

double x[4][5][6][7];
size_t n = sizeof(x) / sizeof(double);

This hard-codes 'double', but should be good enough usually.

Cheers,
Alex

-- 



signature.asc
Description: PGP signature


Re: v2.1 Draft for a lengthof paper

2024-08-14 Thread Alejandro Colomar
On Wed, Aug 14, 2024 at 03:50:21PM GMT, Jens Gustedt wrote:
> > > > 
> > > > That said, I suspect WG14 would not be keen on standardizing
> > > > `lengthof` without an ugly keyword given that there are plenty of other 
> > > > uses of it that would break: 
> > > > 
> > > > https://sourcegraph.com/github.com/illumos/illumos-gate/-/blob/usr/src/cmd/mailx/names.c?L53-55
> > > > https://sourcegraph.com/github.com/Rockbox/rockbox/-/blob/tools/ipod_fw.c?L292-294
> > > > https://sourcegraph.com/github.com/OpenSmalltalk/opensmalltalk-vm/-/blob/src/spur64.stack/validImage.c?L7014-7018
> > > > (and many, many others)
> > 
> > What regex did you use for searching?
> > 
> > I was thinking of renaming the proposal to elementsof(), to avoid
> > confusion between length of an array and length of a string.  Would you
> > mind checking if elementsof() is ok?
> 
> No, not for me. I really want as to go consistently to talk about
> array length for this. Consistent terminology is important.

I understand your desire for consistency.  I think your paper is a net
improvement over the status quo (which is a mix of length, size, and
number of elements).  After your proposal, there will be only length and
number of elements.  That's great.

However, strlen(3) came first, and we must respect it.

Since you haven't proposed eliminating "number of elements" from the
standard, and it would still be used alongside length, I think
elementsof() would be consistent with your view (consistent with "number
of elements").

Alternatively, you could use a new term, for example extent, for
referring to the number of elements of an array.  That would be more
respectful to strlen(3), keeping a strong distinction between string
length and array **.

Or how about always referring to it as "number of elements"?  It's
longer to type, but would be the most consistent approach.

Also, elementsof() is free to use, while lengthof() has a several
existing incompatible cases (as Aaron has shown), so we can't use that
name so freely.

> > I have concerns about a libc (or a predefined macro) implementation:
> > the sizeof division causes double evaluation with any VLAs, while my
> > implementation for GCC has less cases of evaluation, and when it needs
> > to evaluate, it only does it once.  It would be hard to find a good
> > wording that would allow an implementation to implement this as a macro.
> 
> No, we should not allow double evaluation.
> 
> putting this in a `({})`

I would love to see a proposal for adding this GNU extension to ISO C.
Did nobody do it yet?  I could try to, if I find some time.  (But I'll
take a longish time for that; if anyone else does it, it would be
great.)

> and doing a `typedef typeof(X) _my_type;` with the macro parameter `X` at the 
> beginning completely avoids double evaluation. So quality implantations are
> possible, but perhaps differently and with other builtins than we are
> imagining. Don't impose the view of one particular implementation onto others.

Ahhh, good.  I haven't thought of that possibility.  Sure, that makes
sense now.  It gives more strength to your proposal of allowing libc
implementations, and thus require parens in the standard.

> Somewhere was brought in an argument with `offsetof`. 
> This is exactly what we need. Implementations being able to start
> with a simple solution (as everybody did in the beginning of
> `offsetof`), and improve that implementation at their pace when they
> are ready for it. 

Agree.

> > > this was basically what we did for `unreachable` and I think it worked
> > > out fine.
> 
> I still think that the different options that we had there can be used
> to ask the right questions for WG14. 

I'm looking at it.  I've already taken some parts of it.  :)

Cheers,
Alex

-- 



signature.asc
Description: PGP signature


Re: v2.1 Draft for a lengthof paper

2024-08-14 Thread Alejandro Colomar
Hi Aaron,

On Wed, Aug 14, 2024 at 02:07:16PM GMT, Ballman, Aaron wrote:
> > Ahh, context:global seems to be what I wanted.  Where is that documented?
> 
> For me it is the default when I go to https://sourcegraph.com/search but 
> there's documentation at 
> https://sourcegraph.com/docs/code-search/working/search_contexts

Ahh, no, it was a red herring.  I though that was restricting the search
to global definitions.  There's no way to restrict to definitions,
right?  I'd like a way to discard uses, since that doesn't give much
info.

But for lengthof() it seems to quickly find incomatible cases, so we
were lucky that we don't need to restrict it.

> 
> > Thanks!  I'll rename it to elementsof().
> 
> Rather than renaming it, I'd say that the name chosen in the proposed
> text is a placeholder, and have a section in the prose that describes
> different naming choices, pros and cons, suggests a name from you as
> the author, but asks WG14 to pick the final name.
> I know Jens mentioned he doesn’t like the name `elementsof` and I
> suspect if we ask five more people we'll get about seven more opinions
> on what the name could/should be. 😝

Yup, but I want to have a placeholder that would be a name that I would
like, and a defendible one.  :-)

I'll add questions at the bottom, proposing alternatives.

Cheers,
Alex

-- 



signature.asc
Description: PGP signature


[PATCH v9 0/3] c: Add __elementsof__ operator

2024-08-14 Thread Alejandro Colomar
Hi!

v9:

-  Rename s/lengthof/elementsof/

   There are existing lengthof() functions in the wild, which are
   incompatible with (completely unrelated to) this operator.

   In the case of elementsof(), we only found macros that expand to the
   usual sizeof division (plus safety checks in some cases), so this one
   would be compatible.  [Aaron]

   ISO C uses "number of elements" and "length" indistinctly for
   referring to the number of elements of an array, so this name should
   also be obvious.

   Also, lengthof() might induce to ambiguity in contexts where string
   lengths are used, due to the overload of the term length.
   elementsof() is free of that ambiguity.

   I guess elementsof() has slightly more chances of being later
   accepted into ISO C than lengthof(), due to backwards compatibility
   with those existing functions named lengthof().

-  Cc: += Daniel, A., Eugene, Aaron, Paul

I'll send as a reply the updated draft for a WG14 C2y proposal
incorporating these changes.

As usual, below is a range diff against v8.

Have a lovely day!
Alex


Alejandro Colomar (3):
  gcc/: Rename array_type_nelts() => array_type_nelts_minus_one()
  Merge definitions of array_type_nelts_top()
  c: Add __elementsof__ operator

 gcc/c-family/c-common.cc  |  26 
 gcc/c-family/c-common.def |   3 +
 gcc/c-family/c-common.h   |   2 +
 gcc/c/c-decl.cc   |  31 +++--
 gcc/c/c-fold.cc   |   7 +-
 gcc/c/c-parser.cc |  62 +++--
 gcc/c/c-tree.h|   4 +
 gcc/c/c-typeck.cc | 118 -
 gcc/config/aarch64/aarch64.cc |   2 +-
 gcc/config/i386/i386.cc   |   2 +-
 gcc/cp/cp-tree.h  |   1 -
 gcc/cp/decl.cc|   2 +-
 gcc/cp/init.cc|   8 +-
 gcc/cp/lambda.cc  |   3 +-
 gcc/cp/operators.def  |   1 +
 gcc/cp/tree.cc|  13 --
 gcc/doc/extend.texi   |  30 +
 gcc/expr.cc   |   8 +-
 gcc/fortran/trans-array.cc|   2 +-
 gcc/fortran/trans-openmp.cc   |   4 +-
 gcc/rust/backend/rust-tree.cc |  13 --
 gcc/rust/backend/rust-tree.h  |   2 -
 gcc/target.h  |   3 +
 gcc/testsuite/gcc.dg/elementsof-compile.c | 115 +
 gcc/testsuite/gcc.dg/elementsof-vla.c |  46 +++
 gcc/testsuite/gcc.dg/elementsof.c | 150 ++
 gcc/tree.cc   |  17 ++-
 gcc/tree.h|   3 +-
 28 files changed, 599 insertions(+), 79 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/elementsof-compile.c
 create mode 100644 gcc/testsuite/gcc.dg/elementsof-vla.c
 create mode 100644 gcc/testsuite/gcc.dg/elementsof.c

Range-diff against v8:
1:  a6aa38c9013 = 1:  a6aa38c9013 gcc/: Rename array_type_nelts() => 
array_type_nelts_minus_one()
2:  43300a17e4a ! 2:  4ce16ee4dfe Merge definitions of array_type_nelts_top()
@@ Commit message
 Merge definitions of array_type_nelts_top()
 
 There were two identical definitions, and none of them are available
-where they are needed for implementing __lengthof__.  Merge them, and
+where they are needed for implementing __elementsof__.  Merge them, and
 provide the single definition in gcc/tree.{h,cc}, where it's available
-for __lengthof__, which will be added in the following commit.
+for __elementsof__, which will be added in the following commit.
 
 gcc/ChangeLog:
 
3:  e6af87d54af ! 3:  caae5dbecb3 c: Add __lengthof__ operator
    @@ Metadata
 Author: Alejandro Colomar 
 
  ## Commit message ##
-c: Add __lengthof__ operator
+c: Add __elementsof__ operator
 
 This operator is similar to sizeof but can only be applied to an array,
-and returns its length (number of elements).
+and returns its number of elements.
 
 FUTURE DIRECTIONS:
 
 -  We should make it work with array parameters to functions,
-   and somehow magically return the length designator of the array,
+   and somehow magically return the number of elements of the array,
regardless of it being really a pointer.
 
 -  Fix support for [0].
@@ Commit message
 Cc: Florian Weimer 
 Cc: Andreas Schwab 
 Cc: Timm Baeder 
+Cc: Daniel Plakosh 
+Cc: "A. Jiang" 
+Cc: Eugene Zelenko 
+Cc: Aaron Ballman 
+Cc: Paul Koning 
 
 gcc/ChangeLog:
 
-* doc/extend.texi: Document __lengthof__ operator.
-* target.h (enum type_context_kind): Add

[PATCH v9 1/3] gcc/: Rename array_type_nelts() => array_type_nelts_minus_one()

2024-08-14 Thread Alejandro Colomar
The old name was misleading.

While at it, also rename some temporary variables that are used with
this function, for consistency.

Link: 
https://inbox.sourceware.org/gcc-patches/9fffd80-dca-2c7e-14b-6c9b509a7...@redhat.com/T/#m2f661c67c8f7b2c405c8c7fc3152dd85dc729120
Cc: Gabriel Ravier 
Cc: Martin Uecker 
Cc: Joseph Myers 
Cc: Xavier Del Campo Romero 
Cc: Jakub Jelinek 

gcc/ChangeLog:

* tree.cc (array_type_nelts, array_type_nelts_minus_one):
* tree.h (array_type_nelts, array_type_nelts_minus_one):
* expr.cc (count_type_elements):
* config/aarch64/aarch64.cc
(pure_scalable_type_info::analyze_array):
* config/i386/i386.cc (ix86_canonical_va_list_type):
Rename array_type_nelts() => array_type_nelts_minus_one()
The old name was misleading.

gcc/c/ChangeLog:

* c-decl.cc (one_element_array_type_p, get_parm_array_spec):
* c-fold.cc (c_fold_array_ref):
Rename array_type_nelts() => array_type_nelts_minus_one()

gcc/cp/ChangeLog:

* decl.cc (reshape_init_array):
* init.cc
(build_zero_init_1):
(build_value_init_noctor):
(build_vec_init):
(build_delete):
* lambda.cc (add_capture):
* tree.cc (array_type_nelts_top):
Rename array_type_nelts() => array_type_nelts_minus_one()

gcc/fortran/ChangeLog:

* trans-array.cc (structure_alloc_comps):
* trans-openmp.cc
(gfc_walk_alloc_comps):
(gfc_omp_clause_linear_ctor):
Rename array_type_nelts() => array_type_nelts_minus_one()

gcc/rust/ChangeLog:

* backend/rust-tree.cc (array_type_nelts_top):
Rename array_type_nelts() => array_type_nelts_minus_one()

Suggested-by: Richard Biener 
Signed-off-by: Alejandro Colomar 
---
 gcc/c/c-decl.cc   | 10 +-
 gcc/c/c-fold.cc   |  7 ---
 gcc/config/aarch64/aarch64.cc |  2 +-
 gcc/config/i386/i386.cc   |  2 +-
 gcc/cp/decl.cc|  2 +-
 gcc/cp/init.cc|  8 
 gcc/cp/lambda.cc  |  3 ++-
 gcc/cp/tree.cc|  2 +-
 gcc/expr.cc   |  8 
 gcc/fortran/trans-array.cc|  2 +-
 gcc/fortran/trans-openmp.cc   |  4 ++--
 gcc/rust/backend/rust-tree.cc |  2 +-
 gcc/tree.cc   |  4 ++--
 gcc/tree.h|  2 +-
 14 files changed, 30 insertions(+), 28 deletions(-)

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 8cef8f2c289..e7c2783e724 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -5309,7 +5309,7 @@ one_element_array_type_p (const_tree type)
 {
   if (TREE_CODE (type) != ARRAY_TYPE)
 return false;
-  return integer_zerop (array_type_nelts (type));
+  return integer_zerop (array_type_nelts_minus_one (type));
 }
 
 /* Determine whether TYPE is a zero-length array type "[0]".  */
@@ -6257,15 +6257,15 @@ get_parm_array_spec (const struct c_parm *parm, tree 
attrs)
  for (tree type = parm->specs->type; TREE_CODE (type) == ARRAY_TYPE;
   type = TREE_TYPE (type))
{
- tree nelts = array_type_nelts (type);
- if (error_operand_p (nelts))
+ tree nelts_minus_one = array_type_nelts_minus_one (type);
+ if (error_operand_p (nelts_minus_one))
return attrs;
- if (TREE_CODE (nelts) != INTEGER_CST)
+ if (TREE_CODE (nelts_minus_one) != INTEGER_CST)
{
  /* Each variable VLA bound is represented by the dollar
 sign.  */
  spec += "$";
- tpbnds = tree_cons (NULL_TREE, nelts, tpbnds);
+ tpbnds = tree_cons (NULL_TREE, nelts_minus_one, tpbnds);
}
}
  tpbnds = nreverse (tpbnds);
diff --git a/gcc/c/c-fold.cc b/gcc/c/c-fold.cc
index 57b67c74bd8..9ea174f79c4 100644
--- a/gcc/c/c-fold.cc
+++ b/gcc/c/c-fold.cc
@@ -73,11 +73,12 @@ c_fold_array_ref (tree type, tree ary, tree index)
   unsigned elem_nchars = (TYPE_PRECISION (elem_type)
  / TYPE_PRECISION (char_type_node));
   unsigned len = (unsigned) TREE_STRING_LENGTH (ary) / elem_nchars;
-  tree nelts = array_type_nelts (TREE_TYPE (ary));
+  tree nelts_minus_one = array_type_nelts_minus_one (TREE_TYPE (ary));
   bool dummy1 = true, dummy2 = true;
-  nelts = c_fully_fold_internal (nelts, true, &dummy1, &dummy2, false, false);
+  nelts_minus_one = c_fully_fold_internal (nelts_minus_one, true, &dummy1,
+  &dummy2, false, false);
   unsigned HOST_WIDE_INT i = tree_to_uhwi (index);
-  if (!tree_int_cst_le (index, nelts)
+  if (!tree_int_cst_le (index, nelts_minus_one)
   || i >= len
   || i + elem_nchars > len)
 return NULL_TREE;
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 2ac5a22c848..a757796afcf 100644
--- a/gcc/config/aarch64/aa

[PATCH v9 2/3] Merge definitions of array_type_nelts_top()

2024-08-14 Thread Alejandro Colomar
There were two identical definitions, and none of them are available
where they are needed for implementing __elementsof__.  Merge them, and
provide the single definition in gcc/tree.{h,cc}, where it's available
for __elementsof__, which will be added in the following commit.

gcc/ChangeLog:

* tree.h (array_type_nelts_top):
* tree.cc (array_type_nelts_top):
Define function (moved from gcc/cp/).

gcc/cp/ChangeLog:

* cp-tree.h (array_type_nelts_top):
* tree.cc (array_type_nelts_top):
Remove function (move to gcc/).

gcc/rust/ChangeLog:

* backend/rust-tree.h (array_type_nelts_top):
* backend/rust-tree.cc (array_type_nelts_top):
Remove function.

Signed-off-by: Alejandro Colomar 
---
 gcc/cp/cp-tree.h  |  1 -
 gcc/cp/tree.cc| 13 -
 gcc/rust/backend/rust-tree.cc | 13 -
 gcc/rust/backend/rust-tree.h  |  2 --
 gcc/tree.cc   | 13 +
 gcc/tree.h|  1 +
 6 files changed, 14 insertions(+), 29 deletions(-)

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index b1693051231..76d7bc34577 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -8100,7 +8100,6 @@ extern tree build_exception_variant   (tree, 
tree);
 extern void fixup_deferred_exception_variants   (tree, tree);
 extern tree bind_template_template_parm(tree, tree);
 extern tree array_type_nelts_total (tree);
-extern tree array_type_nelts_top   (tree);
 extern bool array_of_unknown_bound_p   (const_tree);
 extern tree break_out_target_exprs (tree, bool = false);
 extern tree build_ctor_subob_ref   (tree, tree, tree);
diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
index 040136c70ab..7d179491476 100644
--- a/gcc/cp/tree.cc
+++ b/gcc/cp/tree.cc
@@ -3079,19 +3079,6 @@ cxx_print_statistics (void)
 depth_reached);
 }
 
-/* Return, as an INTEGER_CST node, the number of elements for TYPE
-   (which is an ARRAY_TYPE).  This counts only elements of the top
-   array.  */
-
-tree
-array_type_nelts_top (tree type)
-{
-  return fold_build2_loc (input_location,
- PLUS_EXPR, sizetype,
- array_type_nelts_minus_one (type),
- size_one_node);
-}
-
 /* Return, as an INTEGER_CST node, the number of elements for TYPE
(which is an ARRAY_TYPE).  This one is a recursive count of all
ARRAY_TYPEs that are clumped together.  */
diff --git a/gcc/rust/backend/rust-tree.cc b/gcc/rust/backend/rust-tree.cc
index 8d32e5203ae..3dc6b076711 100644
--- a/gcc/rust/backend/rust-tree.cc
+++ b/gcc/rust/backend/rust-tree.cc
@@ -859,19 +859,6 @@ is_empty_class (tree type)
   return CLASSTYPE_EMPTY_P (type);
 }
 
-// forked from gcc/cp/tree.cc array_type_nelts_top
-
-/* Return, as an INTEGER_CST node, the number of elements for TYPE
-   (which is an ARRAY_TYPE).  This counts only elements of the top
-   array.  */
-
-tree
-array_type_nelts_top (tree type)
-{
-  return fold_build2_loc (input_location, PLUS_EXPR, sizetype,
- array_type_nelts_minus_one (type), size_one_node);
-}
-
 // forked from gcc/cp/tree.cc builtin_valid_in_constant_expr_p
 
 /* Test whether DECL is a builtin that may appear in a
diff --git a/gcc/rust/backend/rust-tree.h b/gcc/rust/backend/rust-tree.h
index 26c8b653ac6..e597c3ab81d 100644
--- a/gcc/rust/backend/rust-tree.h
+++ b/gcc/rust/backend/rust-tree.h
@@ -2993,8 +2993,6 @@ extern location_t rs_expr_location (const_tree);
 extern int
 is_empty_class (tree type);
 
-extern tree array_type_nelts_top (tree);
-
 extern bool
 is_really_empty_class (tree, bool);
 
diff --git a/gcc/tree.cc b/gcc/tree.cc
index ed0a766016a..cedf95cc222 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -3729,6 +3729,19 @@ array_type_nelts_minus_one (const_tree type)
  ? max
  : fold_build2 (MINUS_EXPR, TREE_TYPE (max), max, min));
 }
+
+/* Return, as an INTEGER_CST node, the number of elements for TYPE
+   (which is an ARRAY_TYPE).  This counts only elements of the top
+   array.  */
+
+tree
+array_type_nelts_top (tree type)
+{
+  return fold_build2_loc (input_location,
+ PLUS_EXPR, sizetype,
+ array_type_nelts_minus_one (type),
+ size_one_node);
+}
 
 /* If arg is static -- a reference to an object in static storage -- then
return the object.  This is not the same as the C meaning of `static'.
diff --git a/gcc/tree.h b/gcc/tree.h
index 69d40bb4f04..9061dafd027 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -4922,6 +4922,7 @@ extern tree build_method_type (tree, tree);
 extern tree build_offset_type (tree, tree);
 extern tree build_complex_type (tree, bool named = false);
 extern tree array_type_nelts_minus_one (const_tree);
+extern tree array_type_nelts_top (tree);
 
 extern tree value_member (tree, tree);
 extern tree purpose_member (const_tree, tree);

[PATCH v9 3/3] c: Add __elementsof__ operator

2024-08-14 Thread Alejandro Colomar
This operator is similar to sizeof but can only be applied to an array,
and returns its number of elements.

FUTURE DIRECTIONS:

-  We should make it work with array parameters to functions,
   and somehow magically return the number of elements of the array,
   regardless of it being really a pointer.

-  Fix support for [0].

Cc: Joseph Myers 
Cc: Gabriel Ravier 
Cc: Jakub Jelinek 
Cc: Kees Cook 
Cc: Qing Zhao 
Cc: Jens Gustedt 
Cc: David Brown 
Cc: Florian Weimer 
Cc: Andreas Schwab 
Cc: Timm Baeder 
Cc: Daniel Plakosh 
Cc: "A. Jiang" 
Cc: Eugene Zelenko 
Cc: Aaron Ballman 
Cc: Paul Koning 

gcc/ChangeLog:

* doc/extend.texi: Document __elementsof__ operator.
* target.h (enum type_context_kind): Add __elementsof__ operator.

gcc/c-family/ChangeLog:

* c-common.h:
* c-common.def:
* c-common.cc (c_elementsof_type): Add __elementsof__ operator.

gcc/c/ChangeLog:

* c-tree.h
(c_expr_elementsof_expr, c_expr_elementsof_type):
* c-decl.cc
(start_struct, finish_struct):
(start_enum, finish_enum):
* c-parser.cc
(c_parser_sizeof_expression):
(c_parser_elementsof_expression):
(c_parser_sizeof_or_elementsof_expression):
(c_parser_unary_expression):
* c-typeck.cc
(build_external_ref):
(record_maybe_used_decl, pop_maybe_used):
(is_top_array_vla):
(c_expr_elementsof_expr, c_expr_elementsof_type):
Add __elementsof__operator.

gcc/cp/ChangeLog:

* operators.def: Add __elementsof__ operator.

gcc/testsuite/ChangeLog:

* gcc.dg/elementsof-compile.c:
* gcc.dg/elementsof-vla.c:
* gcc.dg/elementsof.c: Add tests for __elementsof__ operator.

Link: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2529.pdf
Link: https://inbox.sourceware.org/gcc/m8s4oqy--...@tutanota.com/T/
Link: https://github.com/llvm/llvm-project/issues/102836
Suggested-by: Xavier Del Campo Romero 
Co-developed-by: Martin Uecker 
Signed-off-by: Alejandro Colomar 
---
 gcc/c-family/c-common.cc  |  26 
 gcc/c-family/c-common.def |   3 +
 gcc/c-family/c-common.h   |   2 +
 gcc/c/c-decl.cc   |  21 ++-
 gcc/c/c-parser.cc |  62 +++--
 gcc/c/c-tree.h|   4 +
 gcc/c/c-typeck.cc | 118 -
 gcc/cp/operators.def  |   1 +
 gcc/doc/extend.texi   |  30 +
 gcc/target.h  |   3 +
 gcc/testsuite/gcc.dg/elementsof-compile.c | 115 +
 gcc/testsuite/gcc.dg/elementsof-vla.c |  46 +++
 gcc/testsuite/gcc.dg/elementsof.c | 150 ++
 13 files changed, 557 insertions(+), 24 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/elementsof-compile.c
 create mode 100644 gcc/testsuite/gcc.dg/elementsof-vla.c
 create mode 100644 gcc/testsuite/gcc.dg/elementsof.c

diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index e7e371fd26f..7e6ef179413 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -465,6 +465,7 @@ const struct c_common_resword c_common_reswords[] =
   { "__inline",RID_INLINE, 0 },
   { "__inline__",  RID_INLINE, 0 },
   { "__label__",   RID_LABEL,  0 },
+  { "__elementsof__",  RID_ELEMENTSOF, 0 },
   { "__null",  RID_NULL,   0 },
   { "__real",  RID_REALPART,   0 },
   { "__real__",RID_REALPART,   0 },
@@ -4070,6 +4071,31 @@ c_alignof_expr (location_t loc, tree expr)
 
   return fold_convert_loc (loc, size_type_node, t);
 }
+
+/* Implement the lementsof keyword:
+   Return the number of elements of an array.  */
+
+tree
+c_elementsof_type (location_t loc, tree type)
+{
+  enum tree_code type_code;
+
+  type_code = TREE_CODE (type);
+  if (type_code != ARRAY_TYPE)
+{
+  error_at (loc, "invalid application of % to type %qT", 
type);
+  return error_mark_node;
+}
+  if (!COMPLETE_TYPE_P (type))
+{
+  error_at (loc,
+   "invalid application of % to incomplete type %qT",
+   type);
+  return error_mark_node;
+}
+
+  return array_type_nelts_top (type);
+}
 
 /* Handle C and C++ default attributes.  */
 
diff --git a/gcc/c-family/c-common.def b/gcc/c-family/c-common.def
index 5de96e5d4a8..c43a1e4ab08 100644
--- a/gcc/c-family/c-common.def
+++ b/gcc/c-family/c-common.def
@@ -50,6 +50,9 @@ DEFTREECODE (EXCESS_PRECISION_EXPR, "excess_precision_expr", 
tcc_expression, 1)
number.  */
 DEFTREECODE (USERDEF_LITERAL, "userdef_literal", tcc_exceptional, 3)
 
+/* Represents a 'elementsof' expression.  */
+DEFTREECODE (ELEMENTSOF_EXPR, "elementsof_expr", tcc_expression, 1)
+
 /* Represents a 'sizeof

[PATCH v10 0/3] c: Add __nelementsof__ operator

2024-08-19 Thread Alejandro Colomar
Hi!

This is v10 of this patch set; hopefully, we're close to an end.

I've already submitted a proposal for C2y to WG14, as n3313:
<https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3313.pdf>

For those who haven't been following since the start, the entire thread
of patch set revisions and their discussions can be found here:
<https://inbox.sourceware.org/gcc-patches/20240728141547.302478-1-...@kernel.org/T/#t>
It also contains drafts of the n3313 proposal.

Changes since v9:

-  Rename s/__elementsof__/__nelementsof__/

   elementsof() doesn't mean in English something compatible with its
   programming semantics.  While there's existing uses of it in
   programming, that's an abuse of English, which could cause confusion,
   or maybe preclude a more appropriate use of that name in the future.

   nelementsof() is just one more byte, and is much more appropriate, by
   being a contraction of "_n_umber (of) elements of".

   Also, there's only one use of nelementsof() in the wild, which makes
   backwards compatibility much less of a concern.  That use is
   semantically compatible with this proposed operator.  And we could
   just notify that project the existence of a new standard operator
   with that name, if we finally settle on this name.

-  Rebase on top of git HEAD.

-  CC +=
Daniel Lundin, Nikolaos, JeanHeyd, Fernando, Jonathan, Chris,
Ville, Alex Celeste, Jakub Łukasiewicz

I have a draft for an updated proposal to WG14 (more recent than n3313).
It has some changes to the documentation of prior art, some typo fixes,
etc., and renames elementsof()=>nelementsof(), but the meat of the
proposal is the same.  I've also rebased it on top of the latest draft
for C2y, which is n3301.  I'll send it as a reply to this subthread.

This cover letter is sent to both gcc-patches@ and gcc@.  The patches
are only sent to gcc-patches@, and the draft for WG14 is only sent to
gcc@.

If anyone wants to add an `Acked-by:` (or `Reviewed-by:`), please do it
explicitly.  There've been some informal ones, but I prefer to pick them
from explicit ones.


Have a lovely day!

Alex


Alejandro Colomar (3):
  gcc/: Rename array_type_nelts() => array_type_nelts_minus_one()
  Merge definitions of array_type_nelts_top()
  c: Add __nelementsof__ operator

 gcc/c-family/c-common.cc   |  26 
 gcc/c-family/c-common.def  |   3 +
 gcc/c-family/c-common.h|   2 +
 gcc/c/c-decl.cc|  32 +++--
 gcc/c/c-fold.cc|   7 +-
 gcc/c/c-parser.cc  |  62 +++--
 gcc/c/c-tree.h |   4 +
 gcc/c/c-typeck.cc  | 118 +++-
 gcc/config/aarch64/aarch64.cc  |   2 +-
 gcc/config/i386/i386.cc|   2 +-
 gcc/cp/cp-tree.h   |   1 -
 gcc/cp/decl.cc |   2 +-
 gcc/cp/init.cc |   8 +-
 gcc/cp/lambda.cc   |   3 +-
 gcc/cp/operators.def   |   1 +
 gcc/cp/tree.cc |  13 --
 gcc/doc/extend.texi|  30 +
 gcc/expr.cc|   8 +-
 gcc/fortran/trans-array.cc |   2 +-
 gcc/fortran/trans-openmp.cc|   4 +-
 gcc/rust/backend/rust-tree.cc  |  13 --
 gcc/rust/backend/rust-tree.h   |   2 -
 gcc/target.h   |   3 +
 gcc/testsuite/gcc.dg/nelementsof-compile.c | 115 
 gcc/testsuite/gcc.dg/nelementsof-vla.c |  46 +++
 gcc/testsuite/gcc.dg/nelementsof.c | 150 +
 gcc/tree.cc|  17 ++-
 gcc/tree.h |   3 +-
 28 files changed, 600 insertions(+), 79 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/nelementsof-compile.c
 create mode 100644 gcc/testsuite/gcc.dg/nelementsof-vla.c
 create mode 100644 gcc/testsuite/gcc.dg/nelementsof.c

Range-diff against v9:
1:  a6aa38c9013 = 1:  ab72c4cee8f gcc/: Rename array_type_nelts() => 
array_type_nelts_minus_one()
2:  4ce16ee4dfe ! 2:  27852be4ac0 Merge definitions of array_type_nelts_top()
@@ Commit message
 Merge definitions of array_type_nelts_top()
 
 There were two identical definitions, and none of them are available
-where they are needed for implementing __elementsof__.  Merge them, and
+where they are needed for implementing __nelementsof__.  Merge them, 
and
 provide the single definition in gcc/tree.{h,cc}, where it's available
-for __elementsof__, which will be added in the following commit.
+for __nelementsof__, which will be added in the following commit.
 
 gcc/ChangeLog:
 
3:  caae5dbecb3 ! 3:  9c78ce1f66d c: Add __elementsof__ 

[PATCH v10 1/3] gcc/: Rename array_type_nelts() => array_type_nelts_minus_one()

2024-08-19 Thread Alejandro Colomar
The old name was misleading.

While at it, also rename some temporary variables that are used with
this function, for consistency.

Link: 
https://inbox.sourceware.org/gcc-patches/9fffd80-dca-2c7e-14b-6c9b509a7...@redhat.com/T/#m2f661c67c8f7b2c405c8c7fc3152dd85dc729120
Cc: Gabriel Ravier 
Cc: Martin Uecker 
Cc: Joseph Myers 
Cc: Xavier Del Campo Romero 
Cc: Jakub Jelinek 

gcc/ChangeLog:

* tree.cc (array_type_nelts, array_type_nelts_minus_one):
* tree.h (array_type_nelts, array_type_nelts_minus_one):
* expr.cc (count_type_elements):
* config/aarch64/aarch64.cc
(pure_scalable_type_info::analyze_array):
* config/i386/i386.cc (ix86_canonical_va_list_type):
Rename array_type_nelts() => array_type_nelts_minus_one()
The old name was misleading.

gcc/c/ChangeLog:

* c-decl.cc (one_element_array_type_p, get_parm_array_spec):
* c-fold.cc (c_fold_array_ref):
Rename array_type_nelts() => array_type_nelts_minus_one()

gcc/cp/ChangeLog:

* decl.cc (reshape_init_array):
* init.cc
(build_zero_init_1):
(build_value_init_noctor):
(build_vec_init):
(build_delete):
* lambda.cc (add_capture):
* tree.cc (array_type_nelts_top):
Rename array_type_nelts() => array_type_nelts_minus_one()

gcc/fortran/ChangeLog:

* trans-array.cc (structure_alloc_comps):
* trans-openmp.cc
(gfc_walk_alloc_comps):
(gfc_omp_clause_linear_ctor):
Rename array_type_nelts() => array_type_nelts_minus_one()

gcc/rust/ChangeLog:

* backend/rust-tree.cc (array_type_nelts_top):
Rename array_type_nelts() => array_type_nelts_minus_one()

Suggested-by: Richard Biener 
Signed-off-by: Alejandro Colomar 
---
 gcc/c/c-decl.cc   | 10 +-
 gcc/c/c-fold.cc   |  7 ---
 gcc/config/aarch64/aarch64.cc |  2 +-
 gcc/config/i386/i386.cc   |  2 +-
 gcc/cp/decl.cc|  2 +-
 gcc/cp/init.cc|  8 
 gcc/cp/lambda.cc  |  3 ++-
 gcc/cp/tree.cc|  2 +-
 gcc/expr.cc   |  8 
 gcc/fortran/trans-array.cc|  2 +-
 gcc/fortran/trans-openmp.cc   |  4 ++--
 gcc/rust/backend/rust-tree.cc |  2 +-
 gcc/tree.cc   |  4 ++--
 gcc/tree.h|  2 +-
 14 files changed, 30 insertions(+), 28 deletions(-)

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 8cef8f2c289..e7c2783e724 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -5309,7 +5309,7 @@ one_element_array_type_p (const_tree type)
 {
   if (TREE_CODE (type) != ARRAY_TYPE)
 return false;
-  return integer_zerop (array_type_nelts (type));
+  return integer_zerop (array_type_nelts_minus_one (type));
 }
 
 /* Determine whether TYPE is a zero-length array type "[0]".  */
@@ -6257,15 +6257,15 @@ get_parm_array_spec (const struct c_parm *parm, tree 
attrs)
  for (tree type = parm->specs->type; TREE_CODE (type) == ARRAY_TYPE;
   type = TREE_TYPE (type))
{
- tree nelts = array_type_nelts (type);
- if (error_operand_p (nelts))
+ tree nelts_minus_one = array_type_nelts_minus_one (type);
+ if (error_operand_p (nelts_minus_one))
return attrs;
- if (TREE_CODE (nelts) != INTEGER_CST)
+ if (TREE_CODE (nelts_minus_one) != INTEGER_CST)
{
  /* Each variable VLA bound is represented by the dollar
 sign.  */
  spec += "$";
- tpbnds = tree_cons (NULL_TREE, nelts, tpbnds);
+ tpbnds = tree_cons (NULL_TREE, nelts_minus_one, tpbnds);
}
}
  tpbnds = nreverse (tpbnds);
diff --git a/gcc/c/c-fold.cc b/gcc/c/c-fold.cc
index 57b67c74bd8..9ea174f79c4 100644
--- a/gcc/c/c-fold.cc
+++ b/gcc/c/c-fold.cc
@@ -73,11 +73,12 @@ c_fold_array_ref (tree type, tree ary, tree index)
   unsigned elem_nchars = (TYPE_PRECISION (elem_type)
  / TYPE_PRECISION (char_type_node));
   unsigned len = (unsigned) TREE_STRING_LENGTH (ary) / elem_nchars;
-  tree nelts = array_type_nelts (TREE_TYPE (ary));
+  tree nelts_minus_one = array_type_nelts_minus_one (TREE_TYPE (ary));
   bool dummy1 = true, dummy2 = true;
-  nelts = c_fully_fold_internal (nelts, true, &dummy1, &dummy2, false, false);
+  nelts_minus_one = c_fully_fold_internal (nelts_minus_one, true, &dummy1,
+  &dummy2, false, false);
   unsigned HOST_WIDE_INT i = tree_to_uhwi (index);
-  if (!tree_int_cst_le (index, nelts)
+  if (!tree_int_cst_le (index, nelts_minus_one)
   || i >= len
   || i + elem_nchars > len)
 return NULL_TREE;
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index bfd7bcdef7c..f787347b56e 100644
--- a/gcc/config/aarch64/aa

[PATCH v10 3/3] c: Add __nelementsof__ operator

2024-08-19 Thread Alejandro Colomar
This operator is similar to sizeof but can only be applied to an array,
and returns its number of elements.

FUTURE DIRECTIONS:

-  We should make it work with array parameters to functions,
   and somehow magically return the number of elements of the array,
   regardless of it being really a pointer.

-  Fix support for [0].

Cc: Joseph Myers 
Cc: Gabriel Ravier 
Cc: Jakub Jelinek 
Cc: Kees Cook 
Cc: Qing Zhao 
Cc: Jens Gustedt 
Cc: David Brown 
Cc: Florian Weimer 
Cc: Andreas Schwab 
Cc: Timm Baeder 
Cc: Daniel Plakosh 
Cc: "A. Jiang" 
Cc: Eugene Zelenko 
Cc: Aaron Ballman 
Cc: Paul Koning 
Cc: Daniel Lundin 
Cc: Nikolaos Strimpas 
Cc: JeanHeyd Meneide 
Cc: Fernando Borretti 
Cc: Jonathan Protzenko 
Cc: Chris Bazley 
Cc: Ville Voutilainen 
Cc: Alex Celeste 
Cc: Jakub Łukasiewicz 

gcc/ChangeLog:

* doc/extend.texi: Document __nelementsof__ operator.
* target.h (enum type_context_kind): Add __nelementsof__ operator.

gcc/c-family/ChangeLog:

* c-common.h:
* c-common.def:
* c-common.cc (c_nelementsof_type): Add __nelementsof__ operator.

gcc/c/ChangeLog:

* c-tree.h
(c_expr_nelementsof_expr, c_expr_nelementsof_type):
* c-decl.cc
(start_struct, finish_struct):
(start_enum, finish_enum):
* c-parser.cc
(c_parser_sizeof_expression):
(c_parser_nelementsof_expression):
(c_parser_sizeof_or_nelementsof_expression):
(c_parser_unary_expression):
* c-typeck.cc
(build_external_ref):
(record_maybe_used_decl, pop_maybe_used):
(is_top_array_vla):
(c_expr_nelementsof_expr, c_expr_nelementsof_type):
Add __nelementsof__operator.

gcc/cp/ChangeLog:

* operators.def: Add __nelementsof__ operator.

gcc/testsuite/ChangeLog:

* gcc.dg/nelementsof-compile.c:
* gcc.dg/nelementsof-vla.c:
* gcc.dg/nelementsof.c: Add tests for __nelementsof__ operator.

Link: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3313.pdf
Link: https://inbox.sourceware.org/gcc/m8s4oqy--...@tutanota.com/T/
Link: https://github.com/llvm/llvm-project/issues/102836
Suggested-by: Xavier Del Campo Romero 
Co-developed-by: Martin Uecker 
Signed-off-by: Alejandro Colomar 
---
 gcc/c-family/c-common.cc   |  26 
 gcc/c-family/c-common.def  |   3 +
 gcc/c-family/c-common.h|   2 +
 gcc/c/c-decl.cc|  22 ++-
 gcc/c/c-parser.cc  |  62 +++--
 gcc/c/c-tree.h |   4 +
 gcc/c/c-typeck.cc  | 118 +++-
 gcc/cp/operators.def   |   1 +
 gcc/doc/extend.texi|  30 +
 gcc/target.h   |   3 +
 gcc/testsuite/gcc.dg/nelementsof-compile.c | 115 
 gcc/testsuite/gcc.dg/nelementsof-vla.c |  46 +++
 gcc/testsuite/gcc.dg/nelementsof.c | 150 +
 13 files changed, 558 insertions(+), 24 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/nelementsof-compile.c
 create mode 100644 gcc/testsuite/gcc.dg/nelementsof-vla.c
 create mode 100644 gcc/testsuite/gcc.dg/nelementsof.c

diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index e7e371fd26f..188bb9b65ef 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -465,6 +465,7 @@ const struct c_common_resword c_common_reswords[] =
   { "__inline",RID_INLINE, 0 },
   { "__inline__",  RID_INLINE, 0 },
   { "__label__",   RID_LABEL,  0 },
+  { "__nelementsof__", RID_NELEMENTSOF, 0 },
   { "__null",  RID_NULL,   0 },
   { "__real",  RID_REALPART,   0 },
   { "__real__",RID_REALPART,   0 },
@@ -4070,6 +4071,31 @@ c_alignof_expr (location_t loc, tree expr)
 
   return fold_convert_loc (loc, size_type_node, t);
 }
+
+/* Implement the lementsof keyword:
+   Return the number of elements of an array.  */
+
+tree
+c_nelementsof_type (location_t loc, tree type)
+{
+  enum tree_code type_code;
+
+  type_code = TREE_CODE (type);
+  if (type_code != ARRAY_TYPE)
+{
+  error_at (loc, "invalid application of % to type %qT", 
type);
+  return error_mark_node;
+}
+  if (!COMPLETE_TYPE_P (type))
+{
+  error_at (loc,
+   "invalid application of % to incomplete type %qT",
+   type);
+  return error_mark_node;
+}
+
+  return array_type_nelts_top (type);
+}
 
 /* Handle C and C++ default attributes.  */
 
diff --git a/gcc/c-family/c-common.def b/gcc/c-family/c-common.def
index 5de96e5d4a8..12ee0d2adb3 100644
--- a/gcc/c-family/c-common.def
+++ b/gcc/c-family/c-common.def
@@ -50,6 +50,9 @@ DEFTREECODE (EXCESS_PRECISION_EXPR, "excess_precision_expr", 
tcc_expression, 1)
number.  */
 DEFTREECODE (USERDEF

[PATCH v10 2/3] Merge definitions of array_type_nelts_top()

2024-08-19 Thread Alejandro Colomar
There were two identical definitions, and none of them are available
where they are needed for implementing __nelementsof__.  Merge them, and
provide the single definition in gcc/tree.{h,cc}, where it's available
for __nelementsof__, which will be added in the following commit.

gcc/ChangeLog:

* tree.h (array_type_nelts_top):
* tree.cc (array_type_nelts_top):
Define function (moved from gcc/cp/).

gcc/cp/ChangeLog:

* cp-tree.h (array_type_nelts_top):
* tree.cc (array_type_nelts_top):
Remove function (move to gcc/).

gcc/rust/ChangeLog:

* backend/rust-tree.h (array_type_nelts_top):
* backend/rust-tree.cc (array_type_nelts_top):
Remove function.

Signed-off-by: Alejandro Colomar 
---
 gcc/cp/cp-tree.h  |  1 -
 gcc/cp/tree.cc| 13 -
 gcc/rust/backend/rust-tree.cc | 13 -
 gcc/rust/backend/rust-tree.h  |  2 --
 gcc/tree.cc   | 13 +
 gcc/tree.h|  1 +
 6 files changed, 14 insertions(+), 29 deletions(-)

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index a53fbcb43ec..39f23b04a78 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -8103,7 +8103,6 @@ extern tree build_exception_variant   (tree, 
tree);
 extern void fixup_deferred_exception_variants   (tree, tree);
 extern tree bind_template_template_parm(tree, tree);
 extern tree array_type_nelts_total (tree);
-extern tree array_type_nelts_top   (tree);
 extern bool array_of_unknown_bound_p   (const_tree);
 extern tree break_out_target_exprs (tree, bool = false);
 extern tree build_ctor_subob_ref   (tree, tree, tree);
diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
index 040136c70ab..7d179491476 100644
--- a/gcc/cp/tree.cc
+++ b/gcc/cp/tree.cc
@@ -3079,19 +3079,6 @@ cxx_print_statistics (void)
 depth_reached);
 }
 
-/* Return, as an INTEGER_CST node, the number of elements for TYPE
-   (which is an ARRAY_TYPE).  This counts only elements of the top
-   array.  */
-
-tree
-array_type_nelts_top (tree type)
-{
-  return fold_build2_loc (input_location,
- PLUS_EXPR, sizetype,
- array_type_nelts_minus_one (type),
- size_one_node);
-}
-
 /* Return, as an INTEGER_CST node, the number of elements for TYPE
(which is an ARRAY_TYPE).  This one is a recursive count of all
ARRAY_TYPEs that are clumped together.  */
diff --git a/gcc/rust/backend/rust-tree.cc b/gcc/rust/backend/rust-tree.cc
index 8d32e5203ae..3dc6b076711 100644
--- a/gcc/rust/backend/rust-tree.cc
+++ b/gcc/rust/backend/rust-tree.cc
@@ -859,19 +859,6 @@ is_empty_class (tree type)
   return CLASSTYPE_EMPTY_P (type);
 }
 
-// forked from gcc/cp/tree.cc array_type_nelts_top
-
-/* Return, as an INTEGER_CST node, the number of elements for TYPE
-   (which is an ARRAY_TYPE).  This counts only elements of the top
-   array.  */
-
-tree
-array_type_nelts_top (tree type)
-{
-  return fold_build2_loc (input_location, PLUS_EXPR, sizetype,
- array_type_nelts_minus_one (type), size_one_node);
-}
-
 // forked from gcc/cp/tree.cc builtin_valid_in_constant_expr_p
 
 /* Test whether DECL is a builtin that may appear in a
diff --git a/gcc/rust/backend/rust-tree.h b/gcc/rust/backend/rust-tree.h
index 26c8b653ac6..e597c3ab81d 100644
--- a/gcc/rust/backend/rust-tree.h
+++ b/gcc/rust/backend/rust-tree.h
@@ -2993,8 +2993,6 @@ extern location_t rs_expr_location (const_tree);
 extern int
 is_empty_class (tree type);
 
-extern tree array_type_nelts_top (tree);
-
 extern bool
 is_really_empty_class (tree, bool);
 
diff --git a/gcc/tree.cc b/gcc/tree.cc
index ed0a766016a..cedf95cc222 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -3729,6 +3729,19 @@ array_type_nelts_minus_one (const_tree type)
  ? max
  : fold_build2 (MINUS_EXPR, TREE_TYPE (max), max, min));
 }
+
+/* Return, as an INTEGER_CST node, the number of elements for TYPE
+   (which is an ARRAY_TYPE).  This counts only elements of the top
+   array.  */
+
+tree
+array_type_nelts_top (tree type)
+{
+  return fold_build2_loc (input_location,
+ PLUS_EXPR, sizetype,
+ array_type_nelts_minus_one (type),
+ size_one_node);
+}
 
 /* If arg is static -- a reference to an object in static storage -- then
return the object.  This is not the same as the C meaning of `static'.
diff --git a/gcc/tree.h b/gcc/tree.h
index 69d40bb4f04..9061dafd027 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -4922,6 +4922,7 @@ extern tree build_method_type (tree, tree);
 extern tree build_offset_type (tree, tree);
 extern tree build_complex_type (tree, bool named = false);
 extern tree array_type_nelts_minus_one (const_tree);
+extern tree array_type_nelts_top (tree);
 
 extern tree value_member (tree, tree);
 extern tree purpose_member (const_tree, tree);

Re: [PATCH v10 1/3] gcc/: Rename array_type_nelts() => array_type_nelts_minus_one()

2024-08-20 Thread Alejandro Colomar
Hi Jason,

On Mon, Aug 19, 2024 at 12:46:13PM GMT, Jason Merrill wrote:
> On 8/19/24 6:58 AM, Alejandro Colomar wrote:
> > 
> > Link: 
> > https://inbox.sourceware.org/gcc-patches/9fffd80-dca-2c7e-14b-6c9b509a7...@redhat.com/T/#m2f661c67c8f7b2c405c8c7fc3152dd85dc729120
> > Cc: Gabriel Ravier 
> > Cc: Martin Uecker 
> > Cc: Joseph Myers 
> > Cc: Xavier Del Campo Romero 
> > Cc: Jakub Jelinek 
> > 
> > gcc/ChangeLog:
> > 
> > * tree.cc (array_type_nelts, array_type_nelts_minus_one):
> > * tree.h (array_type_nelts, array_type_nelts_minus_one):
> > * expr.cc (count_type_elements):
> > * config/aarch64/aarch64.cc
> > (pure_scalable_type_info::analyze_array):
> > [etc]
> 
> FYI the commit message checker, which you can run yourself as git
> gcc-verify, will reject this for missing descriptions, e.g.

Hmm, thanks!  I've added some changes to that verifier so that I can
use Cc: and Link: tags.

> 
> > ERR: missing description of a change: " * expr.cc 
> > (count_type_elements):"
> > ERR: missing description of a change: " 
> > (pure_scalable_type_info::analyze_array):"
> 
> To avoid this, you can remove the end-of-line colons for changes described
> farther below.

Thanks!

> 
> Jason
> 

Have a lovely day!
Alex

-- 
<https://www.alejandro-colomar.es/>


signature.asc
Description: PGP signature


[PATCH v11 0/4] c: Add __nelementsof__ operator

2024-08-20 Thread Alejandro Colomar
Hi!

v11 changes:

-  Add patch for the commit checker, to allow Cc: and Link: tags.

-  CC += Doug, Jason

-  Fix changelog entries to pass the checker, following advice from
   Jason to remove some colons.

-  Move Cc: and Link: tags to below the changelog, since thanks to the
   new patch 1/4 they are not warned anymore.  (Except for links longer
   than 100 characters, which still raised a warning, and so I kept
   above the changelog entries, where they don't trigger warnings.)

-  Change s/Co-developed-by/Co-authored-by/, which seems to be what the
   checker expects.

Below is a range-diff against v10.

Have a lovely day!
Alex


Alejandro Colomar (4):
  contrib/: Add support for Cc: and Link: tags
  gcc/: Rename array_type_nelts() => array_type_nelts_minus_one()
  Merge definitions of array_type_nelts_top()
  c: Add __nelementsof__ operator

 contrib/gcc-changelog/git_commit.py|   5 +-
 gcc/c-family/c-common.cc   |  26 
 gcc/c-family/c-common.def  |   3 +
 gcc/c-family/c-common.h|   2 +
 gcc/c/c-decl.cc|  32 +++--
 gcc/c/c-fold.cc|   7 +-
 gcc/c/c-parser.cc  |  62 +++--
 gcc/c/c-tree.h |   4 +
 gcc/c/c-typeck.cc  | 118 +++-
 gcc/config/aarch64/aarch64.cc  |   2 +-
 gcc/config/i386/i386.cc|   2 +-
 gcc/cp/cp-tree.h   |   1 -
 gcc/cp/decl.cc |   2 +-
 gcc/cp/init.cc |   8 +-
 gcc/cp/lambda.cc   |   3 +-
 gcc/cp/operators.def   |   1 +
 gcc/cp/tree.cc |  13 --
 gcc/doc/extend.texi|  30 +
 gcc/expr.cc|   8 +-
 gcc/fortran/trans-array.cc |   2 +-
 gcc/fortran/trans-openmp.cc|   4 +-
 gcc/rust/backend/rust-tree.cc  |  13 --
 gcc/rust/backend/rust-tree.h   |   2 -
 gcc/target.h   |   3 +
 gcc/testsuite/gcc.dg/nelementsof-compile.c | 115 
 gcc/testsuite/gcc.dg/nelementsof-vla.c |  46 +++
 gcc/testsuite/gcc.dg/nelementsof.c | 150 +
 gcc/tree.cc|  17 ++-
 gcc/tree.h |   3 +-
 29 files changed, 604 insertions(+), 80 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/nelementsof-compile.c
 create mode 100644 gcc/testsuite/gcc.dg/nelementsof-vla.c
 create mode 100644 gcc/testsuite/gcc.dg/nelementsof.c

Range-diff against v10:
-:  --- > 1:  2e851b8f8d2 contrib/: Add support for Cc: and Link: tags
1:  ab72c4cee8f ! 2:  d582d12adb8 gcc/: Rename array_type_nelts() => 
array_type_nelts_minus_one()
@@ Commit message
 While at it, also rename some temporary variables that are used with
 this function, for consistency.
 
-Link: 
https://inbox.sourceware.org/gcc-patches/9fffd80-dca-2c7e-14b-6c9b509a7...@redhat.com/T/#m2f661c67c8f7b2c405c8c7fc3152dd85dc729120
-Cc: Gabriel Ravier 
-Cc: Martin Uecker 
-Cc: Joseph Myers 
-Cc: Xavier Del Campo Romero 
-Cc: Jakub Jelinek 
+Link: 
<https://inbox.sourceware.org/gcc-patches/9fffd80-dca-2c7e-14b-6c9b509a7...@redhat.com/T/#m2f661c67c8f7b2c405c8c7fc3152dd85dc729120>
 
 gcc/ChangeLog:
 
-* tree.cc (array_type_nelts, array_type_nelts_minus_one):
-* tree.h (array_type_nelts, array_type_nelts_minus_one):
-* expr.cc (count_type_elements):
+* tree.cc (array_type_nelts, array_type_nelts_minus_one)
+* tree.h (array_type_nelts, array_type_nelts_minus_one)
+* expr.cc (count_type_elements)
 * config/aarch64/aarch64.cc
-(pure_scalable_type_info::analyze_array):
+(pure_scalable_type_info::analyze_array)
 * config/i386/i386.cc (ix86_canonical_va_list_type):
 Rename array_type_nelts() => array_type_nelts_minus_one()
 The old name was misleading.
 
 gcc/c/ChangeLog:
 
-* c-decl.cc (one_element_array_type_p, get_parm_array_spec):
+* c-decl.cc (one_element_array_type_p, get_parm_array_spec)
 * c-fold.cc (c_fold_array_ref):
 Rename array_type_nelts() => array_type_nelts_minus_one()
 
 gcc/cp/ChangeLog:
 
-* decl.cc (reshape_init_array):
+* decl.cc (reshape_init_array)
 * init.cc
-(build_zero_init_1):
-(build_value_init_noctor):
-(build_vec_init):
-(build_delete):
-* lambda.cc (add_capture):
+

[PATCH v11 1/4] contrib/: Add support for Cc: and Link: tags

2024-08-20 Thread Alejandro Colomar
contrib/ChangeLog:

* gcc-changelog/git_commit.py: (GitCommit):
Add support for 'Cc: ' and 'Link: ' tags.

Cc: Jason Merrill 
Signed-off-by: Alejandro Colomar 
---
 contrib/gcc-changelog/git_commit.py | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/contrib/gcc-changelog/git_commit.py 
b/contrib/gcc-changelog/git_commit.py
index 87ecb9e1a17..64fb986b74c 100755
--- a/contrib/gcc-changelog/git_commit.py
+++ b/contrib/gcc-changelog/git_commit.py
@@ -182,7 +182,8 @@ CO_AUTHORED_BY_PREFIX = 'co-authored-by: '
 
 REVIEW_PREFIXES = ('reviewed-by: ', 'reviewed-on: ', 'signed-off-by: ',
'acked-by: ', 'tested-by: ', 'reported-by: ',
-   'suggested-by: ')
+   'suggested-by: ', 'cc: ')
+LINK_PREFIXES = ('link: ')
 DATE_FORMAT = '%Y-%m-%d'
 
 
@@ -524,6 +525,8 @@ class GitCommit:
 continue
 elif lowered_line.startswith(REVIEW_PREFIXES):
 continue
+elif lowered_line.startswith(LINK_PREFIXES):
+continue
 else:
 m = cherry_pick_regex.search(line)
 if m:
-- 
2.45.2



signature.asc
Description: PGP signature


[PATCH v11 2/4] gcc/: Rename array_type_nelts() => array_type_nelts_minus_one()

2024-08-20 Thread Alejandro Colomar
The old name was misleading.

While at it, also rename some temporary variables that are used with
this function, for consistency.

Link: 
<https://inbox.sourceware.org/gcc-patches/9fffd80-dca-2c7e-14b-6c9b509a7...@redhat.com/T/#m2f661c67c8f7b2c405c8c7fc3152dd85dc729120>

gcc/ChangeLog:

* tree.cc (array_type_nelts, array_type_nelts_minus_one)
* tree.h (array_type_nelts, array_type_nelts_minus_one)
* expr.cc (count_type_elements)
* config/aarch64/aarch64.cc
(pure_scalable_type_info::analyze_array)
* config/i386/i386.cc (ix86_canonical_va_list_type):
Rename array_type_nelts() => array_type_nelts_minus_one()
The old name was misleading.

gcc/c/ChangeLog:

* c-decl.cc (one_element_array_type_p, get_parm_array_spec)
* c-fold.cc (c_fold_array_ref):
Rename array_type_nelts() => array_type_nelts_minus_one()

gcc/cp/ChangeLog:

* decl.cc (reshape_init_array)
* init.cc
(build_zero_init_1)
(build_value_init_noctor)
(build_vec_init)
(build_delete)
* lambda.cc (add_capture)
* tree.cc (array_type_nelts_top):
Rename array_type_nelts() => array_type_nelts_minus_one()

gcc/fortran/ChangeLog:

* trans-array.cc (structure_alloc_comps)
* trans-openmp.cc
(gfc_walk_alloc_comps)
(gfc_omp_clause_linear_ctor):
Rename array_type_nelts() => array_type_nelts_minus_one()

gcc/rust/ChangeLog:

* backend/rust-tree.cc (array_type_nelts_top):
Rename array_type_nelts() => array_type_nelts_minus_one()

Cc: Gabriel Ravier 
Cc: Martin Uecker 
Cc: Joseph Myers 
Cc: Xavier Del Campo Romero 
Cc: Jakub Jelinek 
Suggested-by: Richard Biener 
Signed-off-by: Alejandro Colomar 
---
 gcc/c/c-decl.cc   | 10 +-
 gcc/c/c-fold.cc   |  7 ---
 gcc/config/aarch64/aarch64.cc |  2 +-
 gcc/config/i386/i386.cc   |  2 +-
 gcc/cp/decl.cc|  2 +-
 gcc/cp/init.cc|  8 
 gcc/cp/lambda.cc  |  3 ++-
 gcc/cp/tree.cc|  2 +-
 gcc/expr.cc   |  8 
 gcc/fortran/trans-array.cc|  2 +-
 gcc/fortran/trans-openmp.cc   |  4 ++--
 gcc/rust/backend/rust-tree.cc |  2 +-
 gcc/tree.cc   |  4 ++--
 gcc/tree.h|  2 +-
 14 files changed, 30 insertions(+), 28 deletions(-)

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 8cef8f2c289..e7c2783e724 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -5309,7 +5309,7 @@ one_element_array_type_p (const_tree type)
 {
   if (TREE_CODE (type) != ARRAY_TYPE)
 return false;
-  return integer_zerop (array_type_nelts (type));
+  return integer_zerop (array_type_nelts_minus_one (type));
 }
 
 /* Determine whether TYPE is a zero-length array type "[0]".  */
@@ -6257,15 +6257,15 @@ get_parm_array_spec (const struct c_parm *parm, tree 
attrs)
  for (tree type = parm->specs->type; TREE_CODE (type) == ARRAY_TYPE;
   type = TREE_TYPE (type))
{
- tree nelts = array_type_nelts (type);
- if (error_operand_p (nelts))
+ tree nelts_minus_one = array_type_nelts_minus_one (type);
+ if (error_operand_p (nelts_minus_one))
return attrs;
- if (TREE_CODE (nelts) != INTEGER_CST)
+ if (TREE_CODE (nelts_minus_one) != INTEGER_CST)
{
  /* Each variable VLA bound is represented by the dollar
 sign.  */
  spec += "$";
- tpbnds = tree_cons (NULL_TREE, nelts, tpbnds);
+ tpbnds = tree_cons (NULL_TREE, nelts_minus_one, tpbnds);
}
}
  tpbnds = nreverse (tpbnds);
diff --git a/gcc/c/c-fold.cc b/gcc/c/c-fold.cc
index 57b67c74bd8..9ea174f79c4 100644
--- a/gcc/c/c-fold.cc
+++ b/gcc/c/c-fold.cc
@@ -73,11 +73,12 @@ c_fold_array_ref (tree type, tree ary, tree index)
   unsigned elem_nchars = (TYPE_PRECISION (elem_type)
  / TYPE_PRECISION (char_type_node));
   unsigned len = (unsigned) TREE_STRING_LENGTH (ary) / elem_nchars;
-  tree nelts = array_type_nelts (TREE_TYPE (ary));
+  tree nelts_minus_one = array_type_nelts_minus_one (TREE_TYPE (ary));
   bool dummy1 = true, dummy2 = true;
-  nelts = c_fully_fold_internal (nelts, true, &dummy1, &dummy2, false, false);
+  nelts_minus_one = c_fully_fold_internal (nelts_minus_one, true, &dummy1,
+  &dummy2, false, false);
   unsigned HOST_WIDE_INT i = tree_to_uhwi (index);
-  if (!tree_int_cst_le (index, nelts)
+  if (!tree_int_cst_le (index, nelts_minus_one)
   || i >= len
   || i + elem_nchars > len)
 return NULL_TREE;
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index bfd7bcdef7c..f787347b56e 100644
--- a/gcc/config/aarc

[PATCH v11 4/4] c: Add __nelementsof__ operator

2024-08-20 Thread Alejandro Colomar
This operator is similar to sizeof but can only be applied to an array,
and returns its number of elements.

FUTURE DIRECTIONS:

-  We should make it work with array parameters to functions,
   and somehow magically return the number of elements of the array,
   regardless of it being really a pointer.

-  Fix support for [0].

gcc/ChangeLog:

* doc/extend.texi: Document __nelementsof__ operator.
* target.h (enum type_context_kind): Add __nelementsof__ operator.

gcc/c-family/ChangeLog:

* c-common.h
* c-common.def:
* c-common.cc (c_nelementsof_type): Add __nelementsof__ operator.

gcc/c/ChangeLog:

* c-tree.h
(c_expr_nelementsof_expr, c_expr_nelementsof_type)
* c-decl.cc
(start_struct, finish_struct)
(start_enum, finish_enum)
* c-parser.cc
(c_parser_sizeof_expression)
(c_parser_nelementsof_expression)
(c_parser_sizeof_or_nelementsof_expression)
(c_parser_unary_expression)
* c-typeck.cc
(build_external_ref)
(record_maybe_used_decl, pop_maybe_used)
(is_top_array_vla)
(c_expr_nelementsof_expr, c_expr_nelementsof_type):
Add __nelementsof__operator.

gcc/cp/ChangeLog:

* operators.def: Add __nelementsof__ operator.

gcc/testsuite/ChangeLog:

* gcc.dg/nelementsof-compile.c
* gcc.dg/nelementsof-vla.c
* gcc.dg/nelementsof.c: Add tests for __nelementsof__ operator.

Link: <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3313.pdf>
Link: <https://inbox.sourceware.org/gcc/m8s4oqy--...@tutanota.com/T/>
Link: <https://github.com/llvm/llvm-project/issues/102836>
Cc: Joseph Myers 
Cc: Gabriel Ravier 
Cc: Jakub Jelinek 
Cc: Kees Cook 
Cc: Qing Zhao 
Cc: Jens Gustedt 
Cc: David Brown 
Cc: Florian Weimer 
Cc: Andreas Schwab 
Cc: Timm Baeder 
Cc: Daniel Plakosh 
Cc: "A. Jiang" 
Cc: Eugene Zelenko 
Cc: Aaron Ballman 
Cc: Paul Koning 
Cc: Daniel Lundin 
Cc: Nikolaos Strimpas 
Cc: JeanHeyd Meneide 
Cc: Fernando Borretti 
Cc: Jonathan Protzenko 
Cc: Chris Bazley 
Cc: Ville Voutilainen 
Cc: Alex Celeste 
Cc: Jakub Łukasiewicz 
Cc: Douglas McIlroy 
Cc: Jason Merrill 
Suggested-by: Xavier Del Campo Romero 
Co-authored-by: Martin Uecker 
Signed-off-by: Alejandro Colomar 
---
 gcc/c-family/c-common.cc   |  26 
 gcc/c-family/c-common.def  |   3 +
 gcc/c-family/c-common.h|   2 +
 gcc/c/c-decl.cc|  22 ++-
 gcc/c/c-parser.cc  |  62 +++--
 gcc/c/c-tree.h |   4 +
 gcc/c/c-typeck.cc  | 118 +++-
 gcc/cp/operators.def   |   1 +
 gcc/doc/extend.texi|  30 +
 gcc/target.h   |   3 +
 gcc/testsuite/gcc.dg/nelementsof-compile.c | 115 
 gcc/testsuite/gcc.dg/nelementsof-vla.c |  46 +++
 gcc/testsuite/gcc.dg/nelementsof.c | 150 +
 13 files changed, 558 insertions(+), 24 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/nelementsof-compile.c
 create mode 100644 gcc/testsuite/gcc.dg/nelementsof-vla.c
 create mode 100644 gcc/testsuite/gcc.dg/nelementsof.c

diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index e7e371fd26f..188bb9b65ef 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -465,6 +465,7 @@ const struct c_common_resword c_common_reswords[] =
   { "__inline",RID_INLINE, 0 },
   { "__inline__",  RID_INLINE, 0 },
   { "__label__",   RID_LABEL,  0 },
+  { "__nelementsof__", RID_NELEMENTSOF, 0 },
   { "__null",  RID_NULL,   0 },
   { "__real",  RID_REALPART,   0 },
   { "__real__",RID_REALPART,   0 },
@@ -4070,6 +4071,31 @@ c_alignof_expr (location_t loc, tree expr)
 
   return fold_convert_loc (loc, size_type_node, t);
 }
+
+/* Implement the lementsof keyword:
+   Return the number of elements of an array.  */
+
+tree
+c_nelementsof_type (location_t loc, tree type)
+{
+  enum tree_code type_code;
+
+  type_code = TREE_CODE (type);
+  if (type_code != ARRAY_TYPE)
+{
+  error_at (loc, "invalid application of % to type %qT", 
type);
+  return error_mark_node;
+}
+  if (!COMPLETE_TYPE_P (type))
+{
+  error_at (loc,
+   "invalid application of % to incomplete type %qT",
+   type);
+  return error_mark_node;
+}
+
+  return array_type_nelts_top (type);
+}
 
 /* Handle C and C++ default attributes.  */
 
diff --git a/gcc/c-family/c-common.def b/gcc/c-family/c-common.def
index 5de96e5d4a8..12ee0d2adb3 100644
--- a/gcc/c-family/c-common.def
+++ b/gcc/c-family/c-common.def
@@ -50,6 +50,9 @@ DEFTREECODE (EXCESS_PRECISION_EXPR, "excess_precision_expr", 
tcc_expr

[PATCH v11 3/4] Merge definitions of array_type_nelts_top()

2024-08-20 Thread Alejandro Colomar
There were two identical definitions, and none of them are available
where they are needed for implementing __nelementsof__.  Merge them, and
provide the single definition in gcc/tree.{h,cc}, where it's available
for __nelementsof__, which will be added in the following commit.

gcc/ChangeLog:

* tree.h (array_type_nelts_top)
* tree.cc (array_type_nelts_top):
Define function (moved from gcc/cp/).

gcc/cp/ChangeLog:

* cp-tree.h (array_type_nelts_top)
* tree.cc (array_type_nelts_top):
Remove function (move to gcc/).

gcc/rust/ChangeLog:

* backend/rust-tree.h (array_type_nelts_top)
* backend/rust-tree.cc (array_type_nelts_top):
Remove function.

Signed-off-by: Alejandro Colomar 
---
 gcc/cp/cp-tree.h  |  1 -
 gcc/cp/tree.cc| 13 -
 gcc/rust/backend/rust-tree.cc | 13 -
 gcc/rust/backend/rust-tree.h  |  2 --
 gcc/tree.cc   | 13 +
 gcc/tree.h|  1 +
 6 files changed, 14 insertions(+), 29 deletions(-)

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index a53fbcb43ec..39f23b04a78 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -8103,7 +8103,6 @@ extern tree build_exception_variant   (tree, 
tree);
 extern void fixup_deferred_exception_variants   (tree, tree);
 extern tree bind_template_template_parm(tree, tree);
 extern tree array_type_nelts_total (tree);
-extern tree array_type_nelts_top   (tree);
 extern bool array_of_unknown_bound_p   (const_tree);
 extern tree break_out_target_exprs (tree, bool = false);
 extern tree build_ctor_subob_ref   (tree, tree, tree);
diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
index 040136c70ab..7d179491476 100644
--- a/gcc/cp/tree.cc
+++ b/gcc/cp/tree.cc
@@ -3079,19 +3079,6 @@ cxx_print_statistics (void)
 depth_reached);
 }
 
-/* Return, as an INTEGER_CST node, the number of elements for TYPE
-   (which is an ARRAY_TYPE).  This counts only elements of the top
-   array.  */
-
-tree
-array_type_nelts_top (tree type)
-{
-  return fold_build2_loc (input_location,
- PLUS_EXPR, sizetype,
- array_type_nelts_minus_one (type),
- size_one_node);
-}
-
 /* Return, as an INTEGER_CST node, the number of elements for TYPE
(which is an ARRAY_TYPE).  This one is a recursive count of all
ARRAY_TYPEs that are clumped together.  */
diff --git a/gcc/rust/backend/rust-tree.cc b/gcc/rust/backend/rust-tree.cc
index 8d32e5203ae..3dc6b076711 100644
--- a/gcc/rust/backend/rust-tree.cc
+++ b/gcc/rust/backend/rust-tree.cc
@@ -859,19 +859,6 @@ is_empty_class (tree type)
   return CLASSTYPE_EMPTY_P (type);
 }
 
-// forked from gcc/cp/tree.cc array_type_nelts_top
-
-/* Return, as an INTEGER_CST node, the number of elements for TYPE
-   (which is an ARRAY_TYPE).  This counts only elements of the top
-   array.  */
-
-tree
-array_type_nelts_top (tree type)
-{
-  return fold_build2_loc (input_location, PLUS_EXPR, sizetype,
- array_type_nelts_minus_one (type), size_one_node);
-}
-
 // forked from gcc/cp/tree.cc builtin_valid_in_constant_expr_p
 
 /* Test whether DECL is a builtin that may appear in a
diff --git a/gcc/rust/backend/rust-tree.h b/gcc/rust/backend/rust-tree.h
index 26c8b653ac6..e597c3ab81d 100644
--- a/gcc/rust/backend/rust-tree.h
+++ b/gcc/rust/backend/rust-tree.h
@@ -2993,8 +2993,6 @@ extern location_t rs_expr_location (const_tree);
 extern int
 is_empty_class (tree type);
 
-extern tree array_type_nelts_top (tree);
-
 extern bool
 is_really_empty_class (tree, bool);
 
diff --git a/gcc/tree.cc b/gcc/tree.cc
index ed0a766016a..cedf95cc222 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -3729,6 +3729,19 @@ array_type_nelts_minus_one (const_tree type)
  ? max
  : fold_build2 (MINUS_EXPR, TREE_TYPE (max), max, min));
 }
+
+/* Return, as an INTEGER_CST node, the number of elements for TYPE
+   (which is an ARRAY_TYPE).  This counts only elements of the top
+   array.  */
+
+tree
+array_type_nelts_top (tree type)
+{
+  return fold_build2_loc (input_location,
+ PLUS_EXPR, sizetype,
+ array_type_nelts_minus_one (type),
+ size_one_node);
+}
 
 /* If arg is static -- a reference to an object in static storage -- then
return the object.  This is not the same as the C meaning of `static'.
diff --git a/gcc/tree.h b/gcc/tree.h
index 69d40bb4f04..9061dafd027 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -4922,6 +4922,7 @@ extern tree build_method_type (tree, tree);
 extern tree build_offset_type (tree, tree);
 extern tree build_complex_type (tree, bool named = false);
 extern tree array_type_nelts_minus_one (const_tree);
+extern tree array_type_nelts_top (tree);
 
 extern tree value_member (tree, tree);
 extern tree purpose_member (const_tree, tree);
-- 
2.45.2



sig

Re: [PATCH v11 1/4] contrib/: Add support for Cc: and Link: tags

2024-08-20 Thread Alejandro Colomar
Hi,

On Tue, Aug 20, 2024 at 08:41:28PM GMT, Alejandro Colomar wrote:
> contrib/ChangeLog:
> 
>   * gcc-changelog/git_commit.py: (GitCommit):

There's a spurious ':' in the line above (before the '(').  I've removed
it for an eventual v12.

>   Add support for 'Cc: ' and 'Link: ' tags.
> 
> Cc: Jason Merrill 
> Signed-off-by: Alejandro Colomar 

Is it ok to send this patch together with this patch set, or should I
send it separately?

Cheers,
Alex

> ---
>  contrib/gcc-changelog/git_commit.py | 5 -
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/contrib/gcc-changelog/git_commit.py 
> b/contrib/gcc-changelog/git_commit.py
> index 87ecb9e1a17..64fb986b74c 100755
> --- a/contrib/gcc-changelog/git_commit.py
> +++ b/contrib/gcc-changelog/git_commit.py
> @@ -182,7 +182,8 @@ CO_AUTHORED_BY_PREFIX = 'co-authored-by: '
>  
>  REVIEW_PREFIXES = ('reviewed-by: ', 'reviewed-on: ', 'signed-off-by: ',
> 'acked-by: ', 'tested-by: ', 'reported-by: ',
> -   'suggested-by: ')
> +   'suggested-by: ', 'cc: ')
> +LINK_PREFIXES = ('link: ')
>  DATE_FORMAT = '%Y-%m-%d'
>  
>  
> @@ -524,6 +525,8 @@ class GitCommit:
>  continue
>  elif lowered_line.startswith(REVIEW_PREFIXES):
>  continue
> +elif lowered_line.startswith(LINK_PREFIXES):
> +continue
>  else:
>  m = cherry_pick_regex.search(line)
>  if m:
> -- 
> 2.45.2
> 



-- 
<https://www.alejandro-colomar.es/>


signature.asc
Description: PGP signature


[RFC v1 0/2] c: Add _Lengthof operator

2024-07-28 Thread Alejandro Colomar
Hi!

I've got something working:

$ cat len.c 
#include 

int
main(int argc, char *argv[argc + 1])
{
int a[42];
size_t  n;

(void) argv;

//n = _Lengthof(argv);
//printf("_Lengthof(argv) == %zu\n", n);

n = _Lengthof(a);
printf("%zu\n", n);

n = _Lengthof(long [99]);
printf("%zu\n", n);

n = _Lengthof(short [n - 10]);
printf("%zu\n", n);

int  b[n / 2];
n = _Lengthof(b);
printf("%zu\n", n);
}
$ /opt/local/gnu/gcc/lengthof/bin/gcc -Wall -Wextra len.c 
$ ./a.out 
42
99
89
44

I'd like to be able to uncomment those two lines in the future, but we
probably want to do that in a separate commit.

Does anyone know if we have the information available for getting that
value from the 'tree' object?  Or do we need some refactor first in
order to keep that information?

Also, I've reused much of sizeof's code, and maybe I should change some
of that.  It's my first contribution to gcc of this size, and I don't
yet know what some of those internals mean.  While my implementation
seems to be working (for the test above), I guess it's not ideal in
terms of readability, and may also not work well with C++ or some corner
cases.  Can somebody with more experience have a look at the code?

I suspect this is not yet ready, and thus doesn't have a ChangeLog.

Have a lovely day!
Alex


Alejandro Colomar (2):
  Merge definitions of array_type_nelts_top()
  c: Add _Lengthof() operator

 gcc/Makefile.in   |  1 +
 gcc/c-family/c-common.cc  | 20 +
 gcc/c-family/c-common.def |  4 ++
 gcc/c-family/c-common.h   |  2 +
 gcc/c/c-parser.cc | 35 +++
 gcc/c/c-tree.h|  4 ++
 gcc/c/c-typeck.cc | 84 +++
 gcc/cp/cp-tree.h  |  1 -
 gcc/cp/operators.def  |  1 +
 gcc/cp/tree.cc| 13 --
 gcc/ginclude/stdlength.h  | 35 +++
 gcc/rust/backend/rust-tree.cc | 13 --
 gcc/rust/backend/rust-tree.h  |  2 -
 gcc/target.h  |  3 ++
 gcc/tree.cc   | 13 ++
 gcc/tree.h|  1 +
 16 files changed, 195 insertions(+), 37 deletions(-)
 create mode 100644 gcc/ginclude/stdlength.h

Range-diff against v0:
-:  --- > 1:  507f5a51e17 Merge definitions of array_type_nelts_top()
-:  --- > 2:  e5835b982af c: Add _Lengthof() operator
-- 
2.45.2



signature.asc
Description: PGP signature


[RFC v1 1/2] Merge definitions of array_type_nelts_top()

2024-07-28 Thread Alejandro Colomar
There were two identical definitions, and none of them are available
where they are needed for implementing _Lengthof().  Merge them, and
provide the single definition in gcc/tree.{h,cc}, where it's available
for _Lengthof().

Signed-off-by: Alejandro Colomar 
---
 gcc/cp/cp-tree.h  |  1 -
 gcc/cp/tree.cc| 13 -
 gcc/rust/backend/rust-tree.cc | 13 -
 gcc/rust/backend/rust-tree.h  |  2 --
 gcc/tree.cc   | 13 +
 gcc/tree.h|  1 +
 6 files changed, 14 insertions(+), 29 deletions(-)

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index c1a371bc721..e6c1c63f872 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -8099,7 +8099,6 @@ extern tree build_exception_variant   (tree, 
tree);
 extern void fixup_deferred_exception_variants   (tree, tree);
 extern tree bind_template_template_parm(tree, tree);
 extern tree array_type_nelts_total (tree);
-extern tree array_type_nelts_top   (tree);
 extern bool array_of_unknown_bound_p   (const_tree);
 extern tree break_out_target_exprs (tree, bool = false);
 extern tree build_ctor_subob_ref   (tree, tree, tree);
diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
index dfd4a3a948b..1f3ecff1a21 100644
--- a/gcc/cp/tree.cc
+++ b/gcc/cp/tree.cc
@@ -3071,19 +3071,6 @@ cxx_print_statistics (void)
 depth_reached);
 }
 
-/* Return, as an INTEGER_CST node, the number of elements for TYPE
-   (which is an ARRAY_TYPE).  This counts only elements of the top
-   array.  */
-
-tree
-array_type_nelts_top (tree type)
-{
-  return fold_build2_loc (input_location,
- PLUS_EXPR, sizetype,
- array_type_nelts (type),
- size_one_node);
-}
-
 /* Return, as an INTEGER_CST node, the number of elements for TYPE
(which is an ARRAY_TYPE).  This one is a recursive count of all
ARRAY_TYPEs that are clumped together.  */
diff --git a/gcc/rust/backend/rust-tree.cc b/gcc/rust/backend/rust-tree.cc
index 2a5ffcbf895..dd8eda84f9b 100644
--- a/gcc/rust/backend/rust-tree.cc
+++ b/gcc/rust/backend/rust-tree.cc
@@ -859,19 +859,6 @@ is_empty_class (tree type)
   return CLASSTYPE_EMPTY_P (type);
 }
 
-// forked from gcc/cp/tree.cc array_type_nelts_top
-
-/* Return, as an INTEGER_CST node, the number of elements for TYPE
-   (which is an ARRAY_TYPE).  This counts only elements of the top
-   array.  */
-
-tree
-array_type_nelts_top (tree type)
-{
-  return fold_build2_loc (input_location, PLUS_EXPR, sizetype,
- array_type_nelts (type), size_one_node);
-}
-
 // forked from gcc/cp/tree.cc builtin_valid_in_constant_expr_p
 
 /* Test whether DECL is a builtin that may appear in a
diff --git a/gcc/rust/backend/rust-tree.h b/gcc/rust/backend/rust-tree.h
index 26c8b653ac6..e597c3ab81d 100644
--- a/gcc/rust/backend/rust-tree.h
+++ b/gcc/rust/backend/rust-tree.h
@@ -2993,8 +2993,6 @@ extern location_t rs_expr_location (const_tree);
 extern int
 is_empty_class (tree type);
 
-extern tree array_type_nelts_top (tree);
-
 extern bool
 is_really_empty_class (tree, bool);
 
diff --git a/gcc/tree.cc b/gcc/tree.cc
index 2d2d5b6db6e..3b0adb4cd9f 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -3729,6 +3729,19 @@ array_type_nelts (const_tree type)
  ? max
  : fold_build2 (MINUS_EXPR, TREE_TYPE (max), max, min));
 }
+
+/* Return, as an INTEGER_CST node, the number of elements for TYPE
+   (which is an ARRAY_TYPE).  This counts only elements of the top
+   array.  */
+
+tree
+array_type_nelts_top (tree type)
+{
+  return fold_build2_loc (input_location,
+ PLUS_EXPR, sizetype,
+ array_type_nelts (type),
+ size_one_node);
+}
 
 /* If arg is static -- a reference to an object in static storage -- then
return the object.  This is not the same as the C meaning of `static'.
diff --git a/gcc/tree.h b/gcc/tree.h
index 28e8e71b036..c620e55b68d 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -4922,6 +4922,7 @@ extern tree build_method_type (tree, tree);
 extern tree build_offset_type (tree, tree);
 extern tree build_complex_type (tree, bool named = false);
 extern tree array_type_nelts (const_tree);
+extern tree array_type_nelts_top (tree);
 
 extern tree value_member (tree, tree);
 extern tree purpose_member (const_tree, tree);
-- 
2.45.2



signature.asc
Description: PGP signature


[RFC v1 2/2] c: Add _Lengthof() operator

2024-07-28 Thread Alejandro Colomar
This operator is similar to sizeof() but can only be applied to an
array, and returns its length (number of elements).

FUTURE DIRECTIONS:

We could make it work with array parameters to functions, and
somehow magically return the length designator of the array,
regardless of it being really a pointer.

Link: <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2529.pdf>
Cc: Gabriel Ravier 
Cc: Martin Uecker 
Cc: Joseph Myers 
Signed-off-by: Alejandro Colomar 
---
 gcc/Makefile.in   |  1 +
 gcc/c-family/c-common.cc  | 20 ++
 gcc/c-family/c-common.def |  4 ++
 gcc/c-family/c-common.h   |  2 +
 gcc/c/c-parser.cc | 35 
 gcc/c/c-tree.h|  4 ++
 gcc/c/c-typeck.cc | 84 +++
 gcc/cp/operators.def  |  1 +
 gcc/ginclude/stdlength.h  | 35 
 gcc/target.h  |  3 ++
 10 files changed, 181 insertions(+), 8 deletions(-)
 create mode 100644 gcc/ginclude/stdlength.h

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index f4bb4a88cf3..88496edbdc8 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -477,6 +477,7 @@ USER_H = $(srcdir)/ginclude/float.h \
 $(srcdir)/ginclude/stdalign.h \
 $(srcdir)/ginclude/stdatomic.h \
 $(srcdir)/ginclude/stdckdint.h \
+$(srcdir)/ginclude/stdlength.h \
 $(EXTRA_HEADERS)
 
 USER_H_INC_NEXT_PRE = @user_headers_inc_next_pre@
diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index e7e371fd26f..c9020a7faef 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -407,6 +407,7 @@ const struct c_common_resword c_common_reswords[] =
   { "_Decimal64",   RID_DFLOAT64,  D_CONLY },
   { "_Decimal128",  RID_DFLOAT128, D_CONLY },
   { "_Fract",   RID_FRACT, D_CONLY | D_EXT },
+  { "_Lengthof",RID_LENGTHOF,  D_CONLY | D_EXT },
   { "_Accum",   RID_ACCUM, D_CONLY | D_EXT },
   { "_Sat", RID_SAT,   D_CONLY | D_EXT },
   { "_Static_assert",   RID_STATIC_ASSERT, D_CONLY },
@@ -523,6 +524,7 @@ const struct c_common_resword c_common_reswords[] =
   { "if",  RID_IF, 0 },
   { "inline",  RID_INLINE, D_EXT89 },
   { "int", RID_INT,0 },
+  { "lengthof",RID_LENGTHOF,   D_EXT },
   { "long",RID_LONG,   0 },
   { "mutable", RID_MUTABLE,D_CXXONLY | D_CXXWARN },
   { "namespace",   RID_NAMESPACE,  D_CXXONLY | D_CXXWARN },
@@ -4070,6 +4072,24 @@ c_alignof_expr (location_t loc, tree expr)
 
   return fold_convert_loc (loc, size_type_node, t);
 }
+
+/* Implement the _Lengthof keyword: Return the length of an array,
+   that is, the number of elements in the array.  */
+
+tree
+c_lengthof_type (location_t loc, tree type)
+{
+  enum tree_code type_code;
+
+  type_code = TREE_CODE (type);
+  if (type_code != ARRAY_TYPE)
+{
+  error_at (loc, "invalid application of %<_Lengthof%> to type %qT", type);
+  return error_mark_node;
+}
+
+  return array_type_nelts_top (type);
+}
 
 /* Handle C and C++ default attributes.  */
 
diff --git a/gcc/c-family/c-common.def b/gcc/c-family/c-common.def
index 5de96e5d4a8..46e128072b5 100644
--- a/gcc/c-family/c-common.def
+++ b/gcc/c-family/c-common.def
@@ -50,6 +50,10 @@ DEFTREECODE (EXCESS_PRECISION_EXPR, "excess_precision_expr", 
tcc_expression, 1)
number.  */
 DEFTREECODE (USERDEF_LITERAL, "userdef_literal", tcc_exceptional, 3)
 
+/* Represents a 'sizeof' expression during C++ template expansion,
+   or for the purpose of -Wsizeof-pointer-memaccess warning.  */
+DEFTREECODE (LENGTHOF_EXPR, "lengthof_expr", tcc_expression, 1)
+
 /* Represents a 'sizeof' expression during C++ template expansion,
or for the purpose of -Wsizeof-pointer-memaccess warning.  */
 DEFTREECODE (SIZEOF_EXPR, "sizeof_expr", tcc_expression, 1)
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index ccaea27c2b9..f815a4cf3bc 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -105,6 +105,7 @@ enum rid
 
   /* C extensions */
   RID_ASM,   RID_TYPEOF,   RID_TYPEOF_UNQUAL, RID_ALIGNOF,  RID_ATTRIBUTE,
+  RID_LENGTHOF,
   RID_VA_ARG,
   RID_EXTENSION, RID_IMAGPART, RID_REALPART, RID_LABEL,RID_CHOOSE_EXPR,
   RID_TYPES_COMPATIBLE_P,  RID_BUILTIN_COMPLEX,   RID_BUILTIN_SHUFFLE,
@@ -885,6 +886,7 @@ extern tree c_common_truthvalue_conversion (location_t, 
tree);
 extern void c_apply_type_quals_to_decl (int, tree);
 extern tree c_sizeof_or_alignof_type (location_t, tree, bool, bool, int);
 extern tree c_alignof_expr (location_t, tree);
+extern tree c_lengthof_type (location_t, tree);
 /* Print an error message for invalid operands to arith operation CODE.
NOP_EXPR is used

Re: [RFC v1 0/2] c: Add _Lengthof operator

2024-07-28 Thread Alejandro Colomar
Hi Martin,

On Sun, Jul 28, 2024 at 04:42:26PM GMT, Martin Uecker wrote:
> Am Sonntag, dem 28.07.2024 um 16:15 +0200 schrieb Alejandro Colomar:
> 
> ...
> > 
> > Does anyone know if we have the information available for getting that
> > value from the 'tree' object?  Or do we need some refactor first in
> > order to keep that information?
> 
> What I wanted to try is to not immediately adjust the type to a
> pointer and keep it represented as an array, so that the size is
> preserved.  We currently already have a flag that tells us that
> the type came from a parameter declared as an array, so we would
> do it the other way round and have a flag that tells us that it
> is really a pointer.  

Thanks!  Thanks makes sense.  I suspected you had something in mind.  :)

Do you remember that flag's name?  I can have a look at inverting that.

> In most cases the array would then decay and nothing needs to be
> changed, but in some cases we would special case it to get the 
> correct result (addressof / sizeof / typeof and maybe others).  
> Those are also cases which should have a warning anyway. So this
> *should* be simple, but I haven't tried.
> 
> I will look at you code later, but I would recommend to avoid
> refactoring that touches different parts of the compiler at this
> point.

I had to do patch 1/2 for having the function that gives me the nelts
value; other than that, I've tried to keep it minimal.

> I also wonder whether it would make sense to propose a GNU
> extension first instead of implementing a full prototype for
> the standard feature? I do not think we could merge the
> former without having an accepted proposal.

Do you mean a __lengthof__ operator first, without using the _L name
or ?

If so, I agree.

> Martin

Cheers,
Alex

> > Alejandro Colomar (2):
> >   Merge definitions of array_type_nelts_top()
> >   c: Add _Lengthof() operator
> > 
> >  gcc/Makefile.in   |  1 +
> >  gcc/c-family/c-common.cc  | 20 +
> >  gcc/c-family/c-common.def |  4 ++
> >  gcc/c-family/c-common.h   |  2 +
> >  gcc/c/c-parser.cc | 35 +++
> >  gcc/c/c-tree.h|  4 ++
> >  gcc/c/c-typeck.cc | 84 +++
> >  gcc/cp/cp-tree.h  |  1 -
> >  gcc/cp/operators.def  |  1 +
> >  gcc/cp/tree.cc| 13 --
> >  gcc/ginclude/stdlength.h  | 35 +++
> >  gcc/rust/backend/rust-tree.cc | 13 --
> >  gcc/rust/backend/rust-tree.h  |  2 -
> >  gcc/target.h  |  3 ++
> >  gcc/tree.cc   | 13 ++
> >  gcc/tree.h|  1 +
> >  16 files changed, 195 insertions(+), 37 deletions(-)
> >  create mode 100644 gcc/ginclude/stdlength.h
> > 
> > Range-diff against v0:
> > -:  --- > 1:  507f5a51e17 Merge definitions of 
> > array_type_nelts_top()
> > -:  --- > 2:  e5835b982af c: Add _Lengthof() operator
> 

-- 
<https://www.alejandro-colomar.es/>


signature.asc
Description: PGP signature


[RFC v2 0/2] c: Add __lengthof__ operator

2024-07-28 Thread Alejandro Colomar
v2:

-  Add a GNU extension first; not using ISO C-reserved names.  That is,
   add __lengthof__ instead of _Lengthof/lengthof.
-  Use 'in_lengthof' instead of 'in_sizeof'.

Alejandro Colomar (2):
  Merge definitions of array_type_nelts_top()
  c: Add __lengthof__() operator

 gcc/c-family/c-common.cc  | 19 +++
 gcc/c-family/c-common.def |  3 ++
 gcc/c-family/c-common.h   |  2 +
 gcc/c/c-decl.cc   | 20 +---
 gcc/c/c-parser.cc | 61 --
 gcc/c/c-tree.h|  4 ++
 gcc/c/c-typeck.cc | 95 +--
 gcc/cp/cp-tree.h  |  1 -
 gcc/cp/operators.def  |  1 +
 gcc/cp/tree.cc| 13 -
 gcc/rust/backend/rust-tree.cc | 13 -
 gcc/rust/backend/rust-tree.h  |  2 -
 gcc/target.h  |  3 ++
 gcc/tree.cc   | 13 +
 gcc/tree.h|  1 +
 15 files changed, 198 insertions(+), 53 deletions(-)

Range-diff against v1:
1:  507f5a51e17 = 1:  507f5a51e17 Merge definitions of array_type_nelts_top()
2:  e5835b982af ! 2:  6b48d48ecdd c: Add _Lengthof() operator
@@ Metadata
     Author: Alejandro Colomar 
 
  ## Commit message ##
-c: Add _Lengthof() operator
+c: Add __lengthof__() operator
 
 This operator is similar to sizeof() but can only be applied to an
 array, and returns its length (number of elements).
@@ Commit message
 Cc: Joseph Myers 
 Signed-off-by: Alejandro Colomar 
 
- ## gcc/Makefile.in ##
-@@ gcc/Makefile.in: USER_H = $(srcdir)/ginclude/float.h \
-$(srcdir)/ginclude/stdalign.h \
-$(srcdir)/ginclude/stdatomic.h \
-$(srcdir)/ginclude/stdckdint.h \
-+   $(srcdir)/ginclude/stdlength.h \
-$(EXTRA_HEADERS)
- 
- USER_H_INC_NEXT_PRE = @user_headers_inc_next_pre@
-
  ## gcc/c-family/c-common.cc ##
 @@ gcc/c-family/c-common.cc: const struct c_common_resword 
c_common_reswords[] =
-   { "_Decimal64",   RID_DFLOAT64,  D_CONLY },
-   { "_Decimal128",  RID_DFLOAT128, D_CONLY },
-   { "_Fract",   RID_FRACT, D_CONLY | D_EXT },
-+  { "_Lengthof",RID_LENGTHOF,  D_CONLY | D_EXT },
-   { "_Accum",   RID_ACCUM, D_CONLY | D_EXT },
-   { "_Sat", RID_SAT,   D_CONLY | D_EXT },
-   { "_Static_assert",   RID_STATIC_ASSERT, D_CONLY },
-@@ gcc/c-family/c-common.cc: const struct c_common_resword 
c_common_reswords[] =
-   { "if", RID_IF, 0 },
-   { "inline", RID_INLINE, D_EXT89 },
-   { "int",RID_INT,0 },
-+  { "lengthof",   RID_LENGTHOF,   D_EXT },
-   { "long",   RID_LONG,   0 },
-   { "mutable",RID_MUTABLE,D_CXXONLY | D_CXXWARN },
-   { "namespace",  RID_NAMESPACE,  D_CXXONLY | D_CXXWARN },
+   { "__inline",   RID_INLINE, 0 },
+   { "__inline__", RID_INLINE, 0 },
+   { "__label__",  RID_LABEL,  0 },
++  { "__lengthof__",   RID_LENGTHOF, 0 },
+   { "__null", RID_NULL,   0 },
+   { "__real", RID_REALPART,   0 },
+   { "__real__",   RID_REALPART,   0 },
 @@ gcc/c-family/c-common.cc: c_alignof_expr (location_t loc, tree expr)
  
return fold_convert_loc (loc, size_type_node, t);
  }
 +
-+/* Implement the _Lengthof keyword: Return the length of an array,
++/* Implement the lengthof keyword: Return the length of an array,
 +   that is, the number of elements in the array.  */
 +
 +tree
@@ gcc/c-family/c-common.cc: c_alignof_expr (location_t loc, tree expr)
 +  type_code = TREE_CODE (type);
 +  if (type_code != ARRAY_TYPE)
 +{
-+  error_at (loc, "invalid application of %<_Lengthof%> to type %qT", 
type);
++  error_at (loc, "invalid application of % to type %qT", 
type);
 +  return error_mark_node;
 +}
 +
@@ gcc/c-family/c-common.def: DEFTREECODE (EXCESS_PRECISION_EXPR, 
"excess_precision
 number.  */
  DEFTREECODE (USERDEF_LITERAL, "userdef_literal", tcc_exceptional, 3)
  
-+/* Represents a 'sizeof' expression during C++ template expansion,
-+   or for the purpose of -Wsizeof-pointer-memaccess warning.  */
++/* Represents a 'lengthof' expression.  */
 +DEFTREECODE (LENGTHOF_EXPR, "lengthof_expr", tcc_expression, 1)
 +
  /* Represents a 'sizeof' expression during C++ template expansion,
@@ gcc/c-family/c-common.h: extern tree c_common_truthvalue_conversion 
(location_t,
   

[RFC v2 1/2] Merge definitions of array_type_nelts_top()

2024-07-28 Thread Alejandro Colomar
There were two identical definitions, and none of them are available
where they are needed for implementing _Lengthof().  Merge them, and
provide the single definition in gcc/tree.{h,cc}, where it's available
for _Lengthof().

Signed-off-by: Alejandro Colomar 
---
 gcc/cp/cp-tree.h  |  1 -
 gcc/cp/tree.cc| 13 -
 gcc/rust/backend/rust-tree.cc | 13 -
 gcc/rust/backend/rust-tree.h  |  2 --
 gcc/tree.cc   | 13 +
 gcc/tree.h|  1 +
 6 files changed, 14 insertions(+), 29 deletions(-)

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index c1a371bc721..e6c1c63f872 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -8099,7 +8099,6 @@ extern tree build_exception_variant   (tree, 
tree);
 extern void fixup_deferred_exception_variants   (tree, tree);
 extern tree bind_template_template_parm(tree, tree);
 extern tree array_type_nelts_total (tree);
-extern tree array_type_nelts_top   (tree);
 extern bool array_of_unknown_bound_p   (const_tree);
 extern tree break_out_target_exprs (tree, bool = false);
 extern tree build_ctor_subob_ref   (tree, tree, tree);
diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
index dfd4a3a948b..1f3ecff1a21 100644
--- a/gcc/cp/tree.cc
+++ b/gcc/cp/tree.cc
@@ -3071,19 +3071,6 @@ cxx_print_statistics (void)
 depth_reached);
 }
 
-/* Return, as an INTEGER_CST node, the number of elements for TYPE
-   (which is an ARRAY_TYPE).  This counts only elements of the top
-   array.  */
-
-tree
-array_type_nelts_top (tree type)
-{
-  return fold_build2_loc (input_location,
- PLUS_EXPR, sizetype,
- array_type_nelts (type),
- size_one_node);
-}
-
 /* Return, as an INTEGER_CST node, the number of elements for TYPE
(which is an ARRAY_TYPE).  This one is a recursive count of all
ARRAY_TYPEs that are clumped together.  */
diff --git a/gcc/rust/backend/rust-tree.cc b/gcc/rust/backend/rust-tree.cc
index 2a5ffcbf895..dd8eda84f9b 100644
--- a/gcc/rust/backend/rust-tree.cc
+++ b/gcc/rust/backend/rust-tree.cc
@@ -859,19 +859,6 @@ is_empty_class (tree type)
   return CLASSTYPE_EMPTY_P (type);
 }
 
-// forked from gcc/cp/tree.cc array_type_nelts_top
-
-/* Return, as an INTEGER_CST node, the number of elements for TYPE
-   (which is an ARRAY_TYPE).  This counts only elements of the top
-   array.  */
-
-tree
-array_type_nelts_top (tree type)
-{
-  return fold_build2_loc (input_location, PLUS_EXPR, sizetype,
- array_type_nelts (type), size_one_node);
-}
-
 // forked from gcc/cp/tree.cc builtin_valid_in_constant_expr_p
 
 /* Test whether DECL is a builtin that may appear in a
diff --git a/gcc/rust/backend/rust-tree.h b/gcc/rust/backend/rust-tree.h
index 26c8b653ac6..e597c3ab81d 100644
--- a/gcc/rust/backend/rust-tree.h
+++ b/gcc/rust/backend/rust-tree.h
@@ -2993,8 +2993,6 @@ extern location_t rs_expr_location (const_tree);
 extern int
 is_empty_class (tree type);
 
-extern tree array_type_nelts_top (tree);
-
 extern bool
 is_really_empty_class (tree, bool);
 
diff --git a/gcc/tree.cc b/gcc/tree.cc
index 2d2d5b6db6e..3b0adb4cd9f 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -3729,6 +3729,19 @@ array_type_nelts (const_tree type)
  ? max
  : fold_build2 (MINUS_EXPR, TREE_TYPE (max), max, min));
 }
+
+/* Return, as an INTEGER_CST node, the number of elements for TYPE
+   (which is an ARRAY_TYPE).  This counts only elements of the top
+   array.  */
+
+tree
+array_type_nelts_top (tree type)
+{
+  return fold_build2_loc (input_location,
+ PLUS_EXPR, sizetype,
+ array_type_nelts (type),
+ size_one_node);
+}
 
 /* If arg is static -- a reference to an object in static storage -- then
return the object.  This is not the same as the C meaning of `static'.
diff --git a/gcc/tree.h b/gcc/tree.h
index 28e8e71b036..c620e55b68d 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -4922,6 +4922,7 @@ extern tree build_method_type (tree, tree);
 extern tree build_offset_type (tree, tree);
 extern tree build_complex_type (tree, bool named = false);
 extern tree array_type_nelts (const_tree);
+extern tree array_type_nelts_top (tree);
 
 extern tree value_member (tree, tree);
 extern tree purpose_member (const_tree, tree);
-- 
2.45.2



signature.asc
Description: PGP signature


[RFC v2 2/2] c: Add __lengthof__() operator

2024-07-28 Thread Alejandro Colomar
This operator is similar to sizeof() but can only be applied to an
array, and returns its length (number of elements).

FUTURE DIRECTIONS:

We could make it work with array parameters to functions, and
somehow magically return the length designator of the array,
regardless of it being really a pointer.

Link: <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2529.pdf>
Cc: Gabriel Ravier 
Cc: Martin Uecker 
Cc: Joseph Myers 
Signed-off-by: Alejandro Colomar 
---
 gcc/c-family/c-common.cc  | 19 
 gcc/c-family/c-common.def |  3 ++
 gcc/c-family/c-common.h   |  2 +
 gcc/c/c-decl.cc   | 20 ++---
 gcc/c/c-parser.cc | 61 +++--
 gcc/c/c-tree.h|  4 ++
 gcc/c/c-typeck.cc | 95 +--
 gcc/cp/operators.def  |  1 +
 gcc/target.h  |  3 ++
 9 files changed, 184 insertions(+), 24 deletions(-)

diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index e7e371fd26f..c0d6239c1f8 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -465,6 +465,7 @@ const struct c_common_resword c_common_reswords[] =
   { "__inline",RID_INLINE, 0 },
   { "__inline__",  RID_INLINE, 0 },
   { "__label__",   RID_LABEL,  0 },
+  { "__lengthof__",RID_LENGTHOF, 0 },
   { "__null",  RID_NULL,   0 },
   { "__real",  RID_REALPART,   0 },
   { "__real__",RID_REALPART,   0 },
@@ -4070,6 +4071,24 @@ c_alignof_expr (location_t loc, tree expr)
 
   return fold_convert_loc (loc, size_type_node, t);
 }
+
+/* Implement the lengthof keyword: Return the length of an array,
+   that is, the number of elements in the array.  */
+
+tree
+c_lengthof_type (location_t loc, tree type)
+{
+  enum tree_code type_code;
+
+  type_code = TREE_CODE (type);
+  if (type_code != ARRAY_TYPE)
+{
+  error_at (loc, "invalid application of % to type %qT", type);
+  return error_mark_node;
+}
+
+  return array_type_nelts_top (type);
+}
 
 /* Handle C and C++ default attributes.  */
 
diff --git a/gcc/c-family/c-common.def b/gcc/c-family/c-common.def
index 5de96e5d4a8..6d162f67104 100644
--- a/gcc/c-family/c-common.def
+++ b/gcc/c-family/c-common.def
@@ -50,6 +50,9 @@ DEFTREECODE (EXCESS_PRECISION_EXPR, "excess_precision_expr", 
tcc_expression, 1)
number.  */
 DEFTREECODE (USERDEF_LITERAL, "userdef_literal", tcc_exceptional, 3)
 
+/* Represents a 'lengthof' expression.  */
+DEFTREECODE (LENGTHOF_EXPR, "lengthof_expr", tcc_expression, 1)
+
 /* Represents a 'sizeof' expression during C++ template expansion,
or for the purpose of -Wsizeof-pointer-memaccess warning.  */
 DEFTREECODE (SIZEOF_EXPR, "sizeof_expr", tcc_expression, 1)
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index ccaea27c2b9..f815a4cf3bc 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -105,6 +105,7 @@ enum rid
 
   /* C extensions */
   RID_ASM,   RID_TYPEOF,   RID_TYPEOF_UNQUAL, RID_ALIGNOF,  RID_ATTRIBUTE,
+  RID_LENGTHOF,
   RID_VA_ARG,
   RID_EXTENSION, RID_IMAGPART, RID_REALPART, RID_LABEL,RID_CHOOSE_EXPR,
   RID_TYPES_COMPATIBLE_P,  RID_BUILTIN_COMPLEX,   RID_BUILTIN_SHUFFLE,
@@ -885,6 +886,7 @@ extern tree c_common_truthvalue_conversion (location_t, 
tree);
 extern void c_apply_type_quals_to_decl (int, tree);
 extern tree c_sizeof_or_alignof_type (location_t, tree, bool, bool, int);
 extern tree c_alignof_expr (location_t, tree);
+extern tree c_lengthof_type (location_t, tree);
 /* Print an error message for invalid operands to arith operation CODE.
NOP_EXPR is used as a special case (see truthvalue_conversion).  */
 extern void binary_op_error (rich_location *, enum tree_code, tree, tree);
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 97f1d346835..1836151fc41 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -8937,12 +8937,16 @@ start_struct (location_t loc, enum tree_code code, tree 
name,
  within a statement expr used within sizeof, et. al.  This is not
  terribly serious as C++ doesn't permit statement exprs within
  sizeof anyhow.  */
-  if (warn_cxx_compat && (in_sizeof || in_typeof || in_alignof))
+  if (warn_cxx_compat && (in_sizeof || in_typeof || in_alignof || in_lengthof))
 warning_at (loc, OPT_Wc___compat,
"defining type in %qs expression is invalid in C++",
(in_sizeof
 ? "sizeof"
-: (in_typeof ? "typeof" : "alignof")));
+: (in_typeof
+   ? "typeof"
+   : (in_alignof
+  ? "alignof"
+  : "lengthof";
 
   if (in_underspecified_init)
 error_at (loc, "%q

Re: [RFC v1 1/2] Merge definitions of array_type_nelts_top()

2024-07-29 Thread Alejandro Colomar
Hi Richard,

On Mon, Jul 29, 2024 at 10:27:35AM GMT, Richard Biener wrote:
> On Sun, Jul 28, 2024 at 4:16 PM Alejandro Colomar  wrote:
> >
> > There were two identical definitions, and none of them are available
> > where they are needed for implementing _Lengthof().  Merge them, and
> > provide the single definition in gcc/tree.{h,cc}, where it's available
> > for _Lengthof().
> >
> > Signed-off-by: Alejandro Colomar 
> > ---
> >  gcc/cp/cp-tree.h  |  1 -
> >  gcc/cp/tree.cc| 13 -
> >  gcc/rust/backend/rust-tree.cc | 13 -
> >  gcc/rust/backend/rust-tree.h  |  2 --
> >  gcc/tree.cc   | 13 +
> >  gcc/tree.h|  1 +
> >  6 files changed, 14 insertions(+), 29 deletions(-)
> >

[...]

> > diff --git a/gcc/tree.cc b/gcc/tree.cc
> > index 2d2d5b6db6e..3b0adb4cd9f 100644
> > --- a/gcc/tree.cc
> > +++ b/gcc/tree.cc
> > @@ -3729,6 +3729,19 @@ array_type_nelts (const_tree type)
> >   ? max
> >   : fold_build2 (MINUS_EXPR, TREE_TYPE (max), max, min));
> >  }
> > +
> > +/* Return, as an INTEGER_CST node, the number of elements for TYPE
> > +   (which is an ARRAY_TYPE).  This counts only elements of the top
> > +   array.  */
> > +
> > +tree
> > +array_type_nelts_top (tree type)
> > +{
> > +  return fold_build2_loc (input_location,
> > + PLUS_EXPR, sizetype,
> > + array_type_nelts (type),
> > + size_one_node);
> > +}
> 
> But this is now extremely confusing API with array_type_nelts above this
> saying
> 
> /* Return, as a tree node, the number of elements for TYPE (which is an
>ARRAY_TYPE) minus one.  This counts only elements of the top array.  */
> 
> so both are "_top".  And there's build_array_type_nelts that's taking
> the number of elements.
> 
> Can you please rename the existing array_type_nelts to
> array_type_nelts_minus_one?  Then _top could be dropped as well from
> the alternate API  you add.

I wanted to do that, but then I found other functions that are named
similarly, such as build_array_type_nelts(), and thought that I wasn't
sure if all of them should be renamed to _minus_one, or just some.  So
I decided to start without renaming.

But yeah, I think I should rename.  I'll prepare a patch for renaming it
independently of this patch set, and send it to be merged before this
patch set.

> I'll also note since array_type_nelts_top calls the other function and that 
> has
> 
>   /* If they did it with unspecified bounds, then we should have already
>  given an error about it before we got here.  */
>   if (! TYPE_DOMAIN (type))
> return error_mark_node;
> 
> the function should handle error_mark_node (and pass that down).

H, now I understand that (! TYPE_DOMAIN (type))

$ grep -rn return.array_type_nelts gcc
gcc/cp/call.cc:12111:return array_type_nelts_top (c->type);
gcc/c-family/c-common.cc:4090:  return array_type_nelts_top (type);

$ sed -n 12102,12119p gcc/cp/call.cc
/* Return a tree representing the number of elements initialized by the
   list-initialization C.  The caller must check that C converts to an
   array type.  */

static tree
nelts_initialized_by_list_init (conversion *c)
{
  /* If the array we're converting to has a dimension, we'll use that.  
*/
  if (TYPE_DOMAIN (c->type))
return array_type_nelts_top (c->type);
  else
{
  /* Otherwise, we look at how many elements the constructor we're
 initializing from has.  */
  tree ctor = conv_get_original_expr (c);
  return size_int (CONSTRUCTOR_NELTS (ctor));
}
}

It seems that would fail when measuring for example

#define memberof(T, member)  ((T){}.member)

struct s {
int x;
int a[];
};

__lengthof__(memberof(struct s, a));

I guess?

$ cat len.c 
#include 

#define memberof(T, member)  ((T){}.member)

struct s {
int x;
int y[];
};

int
main(int argc, char *argv[argc + 1])
{
int a[42];
size_t  n;

(void) argv;

//n = __lengthof__(argv);
//printf("__lengthof__(argv) == %zu\n", n);

n = __lengthof__(a);
printf("lengthof(a):\t %zu\n", n);

n = __lengthof__(long [99]);
printf("l

[PATCH v1] gcc/: Rename array_type_nelts() => array_type_nelts_minus_one()

2024-07-29 Thread Alejandro Colomar
The old name was misleading.

While at it, also rename some temporary variables that are used with
this function, for consistency.

Link: 
https://inbox.sourceware.org/gcc-patches/9fffd80-dca-2c7e-14b-6c9b509a7...@redhat.com/T/#m2f661c67c8f7b2c405c8c7fc3152dd85dc729120
Cc: Gabriel Ravier 
Cc: Martin Uecker 
Cc: Joseph Myers 
Cc: Xavier Del Campo Romero 

gcc/ChangeLog:

* tree.cc (array_type_nelts): Rename function ...
(array_type_nelts_minus_one): ... to this name.  The old name
was misleading.
* tree.h: Likewise.
* c/c-decl.cc: Likewise.
* c/c-fold.cc: Likewise.
* config/aarch64/aarch64.cc: Likewise.
* config/i386/i386.cc: Likewise.
* cp/decl.cc: Likewise.
* cp/init.cc: Likewise.
* cp/lambda.cc: Likewise.
* cp/tree.cc: Likewise.
* expr.cc: Likewise.
* fortran/trans-array.cc: Likewise.
* fortran/trans-openmp.cc: Likewise.
* rust/backend/rust-tree.cc: Likewise.

Suggested-by: Richard Biener 
Signed-off-by: Alejandro Colomar 
---
Range-diff against v0:
-:  --- > 1:  82efbc3c540 gcc/: Rename array_type_nelts() => 
array_type_nelts_minus_one()

 gcc/c/c-decl.cc   | 10 +-
 gcc/c/c-fold.cc   |  7 ---
 gcc/config/aarch64/aarch64.cc |  2 +-
 gcc/config/i386/i386.cc   |  2 +-
 gcc/cp/decl.cc|  2 +-
 gcc/cp/init.cc|  8 
 gcc/cp/lambda.cc  |  3 ++-
 gcc/cp/tree.cc|  2 +-
 gcc/expr.cc   |  8 
 gcc/fortran/trans-array.cc|  2 +-
 gcc/fortran/trans-openmp.cc   |  4 ++--
 gcc/rust/backend/rust-tree.cc |  2 +-
 gcc/tree.cc   |  4 ++--
 gcc/tree.h|  2 +-
 14 files changed, 30 insertions(+), 28 deletions(-)

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 97f1d346835..4dced430d1f 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -5309,7 +5309,7 @@ one_element_array_type_p (const_tree type)
 {
   if (TREE_CODE (type) != ARRAY_TYPE)
 return false;
-  return integer_zerop (array_type_nelts (type));
+  return integer_zerop (array_type_nelts_minus_one (type));
 }
 
 /* Determine whether TYPE is a zero-length array type "[0]".  */
@@ -6257,15 +6257,15 @@ get_parm_array_spec (const struct c_parm *parm, tree 
attrs)
  for (tree type = parm->specs->type; TREE_CODE (type) == ARRAY_TYPE;
   type = TREE_TYPE (type))
{
- tree nelts = array_type_nelts (type);
- if (error_operand_p (nelts))
+ tree nelts_minus_one = array_type_nelts_minus_one (type);
+ if (error_operand_p (nelts_minus_one))
return attrs;
- if (TREE_CODE (nelts) != INTEGER_CST)
+ if (TREE_CODE (nelts_minus_one) != INTEGER_CST)
{
  /* Each variable VLA bound is represented by the dollar
 sign.  */
  spec += "$";
- tpbnds = tree_cons (NULL_TREE, nelts, tpbnds);
+ tpbnds = tree_cons (NULL_TREE, nelts_minus_one, tpbnds);
}
}
  tpbnds = nreverse (tpbnds);
diff --git a/gcc/c/c-fold.cc b/gcc/c/c-fold.cc
index 57b67c74bd8..9ea174f79c4 100644
--- a/gcc/c/c-fold.cc
+++ b/gcc/c/c-fold.cc
@@ -73,11 +73,12 @@ c_fold_array_ref (tree type, tree ary, tree index)
   unsigned elem_nchars = (TYPE_PRECISION (elem_type)
  / TYPE_PRECISION (char_type_node));
   unsigned len = (unsigned) TREE_STRING_LENGTH (ary) / elem_nchars;
-  tree nelts = array_type_nelts (TREE_TYPE (ary));
+  tree nelts_minus_one = array_type_nelts_minus_one (TREE_TYPE (ary));
   bool dummy1 = true, dummy2 = true;
-  nelts = c_fully_fold_internal (nelts, true, &dummy1, &dummy2, false, false);
+  nelts_minus_one = c_fully_fold_internal (nelts_minus_one, true, &dummy1,
+  &dummy2, false, false);
   unsigned HOST_WIDE_INT i = tree_to_uhwi (index);
-  if (!tree_int_cst_le (index, nelts)
+  if (!tree_int_cst_le (index, nelts_minus_one)
   || i >= len
   || i + elem_nchars > len)
 return NULL_TREE;
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 0d41a193ec1..eaef2a0e985 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -1082,7 +1082,7 @@ pure_scalable_type_info::analyze_array (const_tree type)
 
   /* An array of unknown, flexible or variable length will be passed and
  returned by reference whatever we do.  */
-  tree nelts_minus_one = array_type_nelts (type);
+  tree nelts_minus_one = array_type_nelts_minus_one (type);
   if (!tree_fits_uhwi_p (nelts_minus_one))
 return DOESNT_MATTER;
 
diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index 9c2ebe74fc9..298d8c9131a 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -2451

[PATCH v2 0/1] gcc/: Rename array_type_nelts() => array_type_nelts_minus_one()

2024-07-30 Thread Alejandro Colomar
Hi Richard, Jakub,

I've adjusted the ChangeLog; hopefully it'll be good now.

On Tue, Jul 30, 2024 at 12:22:01PM +0200, Richard Biener wrote:
> The changes look good to me, please leave the frontend maintainers
> time to chime in.

Sure; as much as they need.  My latest patch
(-Wunterminated-string-initialization) took 2 years to get in; I expect
__lengthof__, which is a larger feature, to take no less than that.  :)

Below is a range-diff comparing v1 and v2.

BTW, I put the Cc and Link lines before the changelog, because Martin
had issues with them while merging and pushing my latest patch.  Please
let me know if that will work (workaround the scripts).

> Also Jakub had reservations with the renaming because of branch
> maintainance.  I think if that proves an issue we could backport the
> renaming as well, or make sure that array_type_nelts is not
> re-introduced with the same name but different semantics.

I don't expect __lengthof__ to be merged before 2025, and then, I
thought we could keep the name array_type_nelts_top() for some time, to
prevent issues like that.

Anyway, I think backporting this change could be good.  So, how does
this timeline sound to you?

-  Rename array_type_nelts() => array_type_nelts_minus_one() now.
-  Backport that change to stable branches.

[... a year or so passes ...]

-  Make array_type_nelts_top() a global API.
-  Add __lengthof__.

[... a year or so passes ...]

-  Rename array_type_nelts_top() => array_type_nelts()

This would reduce chances of mistakes.

Have a lovely day!
Alex


Alejandro Colomar (1):
  gcc/: Rename array_type_nelts() => array_type_nelts_minus_one()

 gcc/c/c-decl.cc   | 10 +-
 gcc/c/c-fold.cc   |  7 ---
 gcc/config/aarch64/aarch64.cc |  2 +-
 gcc/config/i386/i386.cc   |  2 +-
 gcc/cp/decl.cc|  2 +-
 gcc/cp/init.cc|  8 
 gcc/cp/lambda.cc  |  3 ++-
 gcc/cp/tree.cc|  2 +-
 gcc/expr.cc   |  8 
 gcc/fortran/trans-array.cc|  2 +-
 gcc/fortran/trans-openmp.cc   |  4 ++--
 gcc/rust/backend/rust-tree.cc |  2 +-
 gcc/tree.cc   |  4 ++--
 gcc/tree.h|  2 +-
 14 files changed, 30 insertions(+), 28 deletions(-)

Range-diff against v1:
1:  82efbc3c540 ! 1:  73010cb4af6 gcc/: Rename array_type_nelts() => 
array_type_nelts_minus_one()
@@ Commit message
 Cc: Martin Uecker 
 Cc: Joseph Myers 
 Cc: Xavier Del Campo Romero 
+Cc: Jakub Jelinek 
 
 gcc/ChangeLog:
 
 * tree.cc (array_type_nelts): Rename function ...
 (array_type_nelts_minus_one): ... to this name.  The old name
 was misleading.
-* tree.h: Likewise.
-* c/c-decl.cc: Likewise.
-* c/c-fold.cc: Likewise.
-* config/aarch64/aarch64.cc: Likewise.
-* config/i386/i386.cc: Likewise.
-* cp/decl.cc: Likewise.
-* cp/init.cc: Likewise.
-* cp/lambda.cc: Likewise.
-* cp/tree.cc: Likewise.
-* expr.cc: Likewise.
-* fortran/trans-array.cc: Likewise.
-* fortran/trans-openmp.cc: Likewise.
-* rust/backend/rust-tree.cc: Likewise.
+* tree.h (array_type_nelts): Rename function ...
+(array_type_nelts_minus_one): ... to this name.  The old name
+was misleading.
+* expr.cc (count_type_elements):
+Rename array_type_nelts() => array_type_nelts_minus_one()
+* config/aarch64/aarch64.cc
+(pure_scalable_type_info::analyze_array): Likewise.
+* config/i386/i386.cc (ix86_canonical_va_list_type): Likewise.
+
+gcc/c/ChangeLog:
+
+* c-decl.cc (one_element_array_type_p, get_parm_array_spec):
+Rename array_type_nelts() => array_type_nelts_minus_one()
+* c-fold.cc (c_fold_array_ref): Likewise.
+
+gcc/cp/ChangeLog:
+
+* decl.cc (reshape_init_array):
+Rename array_type_nelts() => array_type_nelts_minus_one()
+* init.cc (build_zero_init_1): Likewise.
+(build_value_init_noctor): Likewise.
+(build_vec_init): Likewise.
+(build_delete): Likewise.
+* lambda.cc (add_capture): Likewise.
+* tree.cc (array_type_nelts_top): Likewise.
+
+gcc/fortran/ChangeLog:
+
+* trans-array.cc (structure_alloc_comps):
+Rename array_type_nelts() => array_type_nelts_minus_one()
+* trans-openmp.cc (gfc_walk_alloc_comps): Likewise.
+(gfc_omp_clause_linear_ctor): Likewise.
+

[PATCH v2 1/1] gcc/: Rename array_type_nelts() => array_type_nelts_minus_one()

2024-07-30 Thread Alejandro Colomar
The old name was misleading.

While at it, also rename some temporary variables that are used with
this function, for consistency.

Link: 
https://inbox.sourceware.org/gcc-patches/9fffd80-dca-2c7e-14b-6c9b509a7...@redhat.com/T/#m2f661c67c8f7b2c405c8c7fc3152dd85dc729120
Cc: Gabriel Ravier 
Cc: Martin Uecker 
Cc: Joseph Myers 
Cc: Xavier Del Campo Romero 
Cc: Jakub Jelinek 

gcc/ChangeLog:

* tree.cc (array_type_nelts): Rename function ...
(array_type_nelts_minus_one): ... to this name.  The old name
was misleading.
* tree.h (array_type_nelts): Rename function ...
(array_type_nelts_minus_one): ... to this name.  The old name
was misleading.
* expr.cc (count_type_elements):
Rename array_type_nelts() => array_type_nelts_minus_one()
* config/aarch64/aarch64.cc
(pure_scalable_type_info::analyze_array): Likewise.
* config/i386/i386.cc (ix86_canonical_va_list_type): Likewise.

gcc/c/ChangeLog:

* c-decl.cc (one_element_array_type_p, get_parm_array_spec):
Rename array_type_nelts() => array_type_nelts_minus_one()
* c-fold.cc (c_fold_array_ref): Likewise.

gcc/cp/ChangeLog:

* decl.cc (reshape_init_array):
Rename array_type_nelts() => array_type_nelts_minus_one()
* init.cc (build_zero_init_1): Likewise.
(build_value_init_noctor): Likewise.
(build_vec_init): Likewise.
(build_delete): Likewise.
* lambda.cc (add_capture): Likewise.
* tree.cc (array_type_nelts_top): Likewise.

gcc/fortran/ChangeLog:

* trans-array.cc (structure_alloc_comps):
Rename array_type_nelts() => array_type_nelts_minus_one()
* trans-openmp.cc (gfc_walk_alloc_comps): Likewise.
(gfc_omp_clause_linear_ctor): Likewise.

gcc/rust/ChangeLog:

* backend/rust-tree.cc (array_type_nelts_top):
Rename array_type_nelts() => array_type_nelts_minus_one()

Suggested-by: Richard Biener 
Signed-off-by: Alejandro Colomar 
---
 gcc/c/c-decl.cc   | 10 +-
 gcc/c/c-fold.cc   |  7 ---
 gcc/config/aarch64/aarch64.cc |  2 +-
 gcc/config/i386/i386.cc   |  2 +-
 gcc/cp/decl.cc|  2 +-
 gcc/cp/init.cc|  8 
 gcc/cp/lambda.cc  |  3 ++-
 gcc/cp/tree.cc|  2 +-
 gcc/expr.cc   |  8 
 gcc/fortran/trans-array.cc|  2 +-
 gcc/fortran/trans-openmp.cc   |  4 ++--
 gcc/rust/backend/rust-tree.cc |  2 +-
 gcc/tree.cc   |  4 ++--
 gcc/tree.h|  2 +-
 14 files changed, 30 insertions(+), 28 deletions(-)

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 97f1d346835..4dced430d1f 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -5309,7 +5309,7 @@ one_element_array_type_p (const_tree type)
 {
   if (TREE_CODE (type) != ARRAY_TYPE)
 return false;
-  return integer_zerop (array_type_nelts (type));
+  return integer_zerop (array_type_nelts_minus_one (type));
 }
 
 /* Determine whether TYPE is a zero-length array type "[0]".  */
@@ -6257,15 +6257,15 @@ get_parm_array_spec (const struct c_parm *parm, tree 
attrs)
  for (tree type = parm->specs->type; TREE_CODE (type) == ARRAY_TYPE;
   type = TREE_TYPE (type))
{
- tree nelts = array_type_nelts (type);
- if (error_operand_p (nelts))
+ tree nelts_minus_one = array_type_nelts_minus_one (type);
+ if (error_operand_p (nelts_minus_one))
return attrs;
- if (TREE_CODE (nelts) != INTEGER_CST)
+ if (TREE_CODE (nelts_minus_one) != INTEGER_CST)
{
  /* Each variable VLA bound is represented by the dollar
 sign.  */
  spec += "$";
- tpbnds = tree_cons (NULL_TREE, nelts, tpbnds);
+ tpbnds = tree_cons (NULL_TREE, nelts_minus_one, tpbnds);
}
}
  tpbnds = nreverse (tpbnds);
diff --git a/gcc/c/c-fold.cc b/gcc/c/c-fold.cc
index 57b67c74bd8..9ea174f79c4 100644
--- a/gcc/c/c-fold.cc
+++ b/gcc/c/c-fold.cc
@@ -73,11 +73,12 @@ c_fold_array_ref (tree type, tree ary, tree index)
   unsigned elem_nchars = (TYPE_PRECISION (elem_type)
  / TYPE_PRECISION (char_type_node));
   unsigned len = (unsigned) TREE_STRING_LENGTH (ary) / elem_nchars;
-  tree nelts = array_type_nelts (TREE_TYPE (ary));
+  tree nelts_minus_one = array_type_nelts_minus_one (TREE_TYPE (ary));
   bool dummy1 = true, dummy2 = true;
-  nelts = c_fully_fold_internal (nelts, true, &dummy1, &dummy2, false, false);
+  nelts_minus_one = c_fully_fold_internal (nelts_minus_one, true, &dummy1,
+  &dummy2, false, false);
   unsigned HOST_WIDE_INT i = tree_to_uhwi (index);
-  if (!tree_int_cst_le (index, nelts)
+  if (!tree_int_cst_le (index, nelts_minu

Re: [RFC v1 0/2] c: Add _Lengthof operator

2024-08-03 Thread Alejandro Colomar
Hi Joseph,

On Mon, Jul 29, 2024 at 11:13:08AM GMT, Joseph Myers wrote:
> On Sun, 28 Jul 2024, Alejandro Colomar wrote:
> 
> >  gcc/Makefile.in   |  1 +
> >  gcc/c-family/c-common.cc  | 20 +
> >  gcc/c-family/c-common.def |  4 ++
> >  gcc/c-family/c-common.h   |  2 +
> >  gcc/c/c-parser.cc | 35 +++
> >  gcc/c/c-tree.h|  4 ++
> >  gcc/c/c-typeck.cc | 84 +++
> >  gcc/cp/cp-tree.h  |  1 -
> >  gcc/cp/operators.def  |  1 +
> >  gcc/cp/tree.cc| 13 --
> >  gcc/ginclude/stdlength.h  | 35 +++
> >  gcc/rust/backend/rust-tree.cc | 13 --
> >  gcc/rust/backend/rust-tree.h  |  2 -
> >  gcc/target.h  |  3 ++
> >  gcc/tree.cc   | 13 ++
> >  gcc/tree.h|  1 +
> 
> Please start with documentation and testcases, neither of which are 
> included here

While I haven't started yet with test cases within the test suite, I
have tests.  There's a test program in the cover letter of the patch set
is the draft of a test suite for the feature.

Running the test suite is much more uncomfortable (to me) than compiling
a program manually, for iterating on the feature.  I need to get used to
this test suite.  :)

> - making sure that both documentation and testcases cover 
> all the error cases and questions of e.g. evaluation of VLA operands.  
> Documentation and testcases are the most important pieces for reviewing a 
> proposed addition of a new language feature, before the actual 
> implementation.

I was just having a look at what can be done.  Now that it's working for
the cases I wanted it to work, I've started documenting it.  I'll also
have a look at adding the tests to the test suite, although that will
take a few more iterations probably.

> A relevant semantic question to answer here: sizeof evaluates all VLA 
> operands, should this operator do likewise, or should it only evaluate 
> when the toplevel array is of variable length (but not for a 
> constant-length array of variable-size elements)?

I see benefits of both approaches.  The former is trivial to implement.
I'm not sure how much work would be needed for the latter, but probably
a bit more than that.  As a programmer, I think I would ask for the
latter; I guess that's what we'd want, ideally.  Thanks for the
feedback!  :)

Have a lovely night!
Alex

> -- 
> Joseph S. Myers
> josmy...@redhat.com
> 

-- 
<https://www.alejandro-colomar.es/>


signature.asc
Description: PGP signature


[RFC v3 1/3] gcc/: Rename array_type_nelts() => array_type_nelts_minus_one()

2024-08-03 Thread Alejandro Colomar
The old name was misleading.

While at it, also rename some temporary variables that are used with
this function, for consistency.

Link: 
https://inbox.sourceware.org/gcc-patches/9fffd80-dca-2c7e-14b-6c9b509a7...@redhat.com/T/#m2f661c67c8f7b2c405c8c7fc3152dd85dc729120
Cc: Gabriel Ravier 
Cc: Martin Uecker 
Cc: Joseph Myers 
Cc: Xavier Del Campo Romero 
Cc: Jakub Jelinek 

gcc/ChangeLog:

* tree.cc (array_type_nelts): Rename function ...
(array_type_nelts_minus_one): ... to this name.  The old name
was misleading.
* tree.h (array_type_nelts): Rename function ...
(array_type_nelts_minus_one): ... to this name.  The old name
was misleading.
* expr.cc (count_type_elements):
Rename array_type_nelts() => array_type_nelts_minus_one()
* config/aarch64/aarch64.cc
(pure_scalable_type_info::analyze_array): Likewise.
* config/i386/i386.cc (ix86_canonical_va_list_type): Likewise.

gcc/c/ChangeLog:

* c-decl.cc (one_element_array_type_p, get_parm_array_spec):
Rename array_type_nelts() => array_type_nelts_minus_one()
* c-fold.cc (c_fold_array_ref): Likewise.

gcc/cp/ChangeLog:

* decl.cc (reshape_init_array):
Rename array_type_nelts() => array_type_nelts_minus_one()
* init.cc (build_zero_init_1): Likewise.
(build_value_init_noctor): Likewise.
(build_vec_init): Likewise.
(build_delete): Likewise.
* lambda.cc (add_capture): Likewise.
* tree.cc (array_type_nelts_top): Likewise.

gcc/fortran/ChangeLog:

* trans-array.cc (structure_alloc_comps):
Rename array_type_nelts() => array_type_nelts_minus_one()
* trans-openmp.cc (gfc_walk_alloc_comps): Likewise.
(gfc_omp_clause_linear_ctor): Likewise.

gcc/rust/ChangeLog:

* backend/rust-tree.cc (array_type_nelts_top):
Rename array_type_nelts() => array_type_nelts_minus_one()

Suggested-by: Richard Biener 
Signed-off-by: Alejandro Colomar 
---
 gcc/c/c-decl.cc   | 10 +-
 gcc/c/c-fold.cc   |  7 ---
 gcc/config/aarch64/aarch64.cc |  2 +-
 gcc/config/i386/i386.cc   |  2 +-
 gcc/cp/decl.cc|  2 +-
 gcc/cp/init.cc|  8 
 gcc/cp/lambda.cc  |  3 ++-
 gcc/cp/tree.cc|  2 +-
 gcc/expr.cc   |  8 
 gcc/fortran/trans-array.cc|  2 +-
 gcc/fortran/trans-openmp.cc   |  4 ++--
 gcc/rust/backend/rust-tree.cc |  2 +-
 gcc/tree.cc   |  4 ++--
 gcc/tree.h|  2 +-
 14 files changed, 30 insertions(+), 28 deletions(-)

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 97f1d346835..4dced430d1f 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -5309,7 +5309,7 @@ one_element_array_type_p (const_tree type)
 {
   if (TREE_CODE (type) != ARRAY_TYPE)
 return false;
-  return integer_zerop (array_type_nelts (type));
+  return integer_zerop (array_type_nelts_minus_one (type));
 }
 
 /* Determine whether TYPE is a zero-length array type "[0]".  */
@@ -6257,15 +6257,15 @@ get_parm_array_spec (const struct c_parm *parm, tree 
attrs)
  for (tree type = parm->specs->type; TREE_CODE (type) == ARRAY_TYPE;
   type = TREE_TYPE (type))
{
- tree nelts = array_type_nelts (type);
- if (error_operand_p (nelts))
+ tree nelts_minus_one = array_type_nelts_minus_one (type);
+ if (error_operand_p (nelts_minus_one))
return attrs;
- if (TREE_CODE (nelts) != INTEGER_CST)
+ if (TREE_CODE (nelts_minus_one) != INTEGER_CST)
{
  /* Each variable VLA bound is represented by the dollar
 sign.  */
  spec += "$";
- tpbnds = tree_cons (NULL_TREE, nelts, tpbnds);
+ tpbnds = tree_cons (NULL_TREE, nelts_minus_one, tpbnds);
}
}
  tpbnds = nreverse (tpbnds);
diff --git a/gcc/c/c-fold.cc b/gcc/c/c-fold.cc
index 57b67c74bd8..9ea174f79c4 100644
--- a/gcc/c/c-fold.cc
+++ b/gcc/c/c-fold.cc
@@ -73,11 +73,12 @@ c_fold_array_ref (tree type, tree ary, tree index)
   unsigned elem_nchars = (TYPE_PRECISION (elem_type)
  / TYPE_PRECISION (char_type_node));
   unsigned len = (unsigned) TREE_STRING_LENGTH (ary) / elem_nchars;
-  tree nelts = array_type_nelts (TREE_TYPE (ary));
+  tree nelts_minus_one = array_type_nelts_minus_one (TREE_TYPE (ary));
   bool dummy1 = true, dummy2 = true;
-  nelts = c_fully_fold_internal (nelts, true, &dummy1, &dummy2, false, false);
+  nelts_minus_one = c_fully_fold_internal (nelts_minus_one, true, &dummy1,
+  &dummy2, false, false);
   unsigned HOST_WIDE_INT i = tree_to_uhwi (index);
-  if (!tree_int_cst_le (index, nelts)
+  if (!tree_int_cst_le (index, nelts_minu

[RFC v3 0/3] c: Add __lengthof__ operator

2024-08-03 Thread Alejandro Colomar
, 
i);

puts("");
// X(*p++)
short  (*p)[42];
p = &a;
n = __lengthof__(*p++);
printf("lengthof(*p++):\t %zu; p: %p\n", n, p);

p = &a;
n = sizeof(*p++);
printf("lengthof(*p++):\t %zu; p: %p\n", n, p);

p = &a;
n = alignof(*p++);
printf("alignof(*p++):\t %zu;  p: %p\n", n, p);

p = &a;
typeof(*p++)  z4;
printf("typeof(*p++);\t p: %p\n", p);

puts("");
// X(*q++)
short  (*q)[__lengthof__(b)];
q = &a;
n = __lengthof__(*q++);
printf("lengthof(*q++):\t %zu; p: %p\n", n, q);

q = &a;
n = sizeof(*q++);
printf("lengthof(*q++):\t %zu; p: %p\n", n, q);

q = &a;
n = alignof(*q++);
printf("alignof(*q++):\t %zu;  p: %p\n", n, q);

q = &a;
typeof(*q++)  z5;
printf("typeof(*q++);\t p: %p\n", q);
}

$ /opt/local/gnu/gcc/lengthof/bin/gcc len.c 
$ ./a.out 
lengthof(a): 42
lengthof(long [0]):  0
lengthof(long [99]): 99
lengthof(short [n - 10]):89
lengthof(b): 44

lengthof(memberof(struct s, y)): 8
sizeof(memberof(struct s, y)):   32
alignof(memberof(struct s, y)):  4

alignof(memberof(struct s, z)):  4

lengthof(struct {int x;}[i++]):  4;  i: 5
sizeof(struct {int x;}[i++]):16; i: 5
alignof(struct {int x;}[i++]):   4;  i: 4
typeof(struct {int x;}[i++]);i: 5

lengthof(struct {int x[i++];}[3]):   3;  i: 5
sizeof(struct {int x[i++];}[3]): 48; i: 5
alignof(struct {int x[i++];}[3]):4;  i: 4
typeof(struct {int x[i++];}[3]); i: 5

lengthof(struct {int x[(i++, 2)];}[3]):  3;  i: 5
sizeof(struct {int x[(i++, 2)];}[3]):24; i: 5
alignof(struct {int x[(i++, 2)];}[3]):   4;  i: 4
typeof(struct {int x[(i++, 2)];}[3]);i: 5

lengthof(*p++):  42; p: 0x7fffe52379f0
lengthof(*p++):  84; p: 0x7fffe52379f0
alignof(*p++):   2;  p: 0x7fffe52379f0
typeof(*p++);p: 0x7fffe52379f0

lengthof(*q++):  44; p: 0x7fffe5237a48
lengthof(*q++):  88; p: 0x7fffe5237a48
alignof(*q++):   2;  p: 0x7fffe52379f0
typeof(*q++);p: 0x7fffe5237a48

There are some things to consider:

-  Error handling could be incomplete; there are a few things I still
   don't understand.
-  I'd like to implement it so that only top-level VLAs trigger
   evaluation, but I still don't understand that well.

Other than that, it starts looking good.


Have a lovely night!
Alex


Alejandro Colomar (3):
  gcc/: Rename array_type_nelts() => array_type_nelts_minus_one()
  Merge definitions of array_type_nelts_top()
  c: Add __lengthof__() operator

 gcc/c-family/c-common.cc  | 26 ++
 gcc/c-family/c-common.def |  3 ++
 gcc/c-family/c-common.h   |  2 +
 gcc/c/c-decl.cc   | 30 +++
 gcc/c/c-fold.cc   |  7 +--
 gcc/c/c-parser.cc | 61 --
 gcc/c/c-tree.h|  4 ++
 gcc/c/c-typeck.cc | 95 +--
 gcc/config/aarch64/aarch64.cc |  2 +-
 gcc/config/i386/i386.cc   |  2 +-
 gcc/cp/cp-tree.h  |  1 -
 gcc/cp/decl.cc|  2 +-
 gcc/cp/init.cc|  8 +--
 gcc/cp/lambda.cc  |  3 +-
 gcc/cp/operators.def  |  1 +
 gcc/cp/tree.cc| 13 -
 gcc/doc/extend.texi   | 12 +
 gcc/expr.cc   |  8 +--
 gcc/fortran/trans-array.cc|  2 +-
 gcc/fortran/trans-openmp.cc   |  4 +-
 gcc/rust/backend/rust-tree.cc | 13 -
 gcc/rust/backend/rust-tree.h  |  2 -
 gcc/target.h  |  3 ++
 gcc/tree.cc   | 17 ++-
 gcc/tree.h|  3 +-
 25 files changed, 245 insertions(+), 79 deletions(-)

Range-diff against v2:
-:  --- > 1:  73010cb4af6 gcc/: Rename array_type_nelts() => 
array_type_nelts_minus_one()
1:  507f5a51e17 ! 2:  2bb966a0a89 Merge definitions of array_type_nelts_top()
@@ Commit message
     Merge definitions of array_type_nelts_top()
 
 There were two identical definitions, and none of them are available
-where they are needed for implementing _Lengthof().  Merge them, and
+where they are needed for implementing __lengthof__().  Merge them, and
 provide the single definition in gcc/tree.{h,cc}, where it's available

[RFC v3 2/3] Merge definitions of array_type_nelts_top()

2024-08-03 Thread Alejandro Colomar
There were two identical definitions, and none of them are available
where they are needed for implementing __lengthof__().  Merge them, and
provide the single definition in gcc/tree.{h,cc}, where it's available
for __lengthof__().

Signed-off-by: Alejandro Colomar 
---
 gcc/cp/cp-tree.h  |  1 -
 gcc/cp/tree.cc| 13 -
 gcc/rust/backend/rust-tree.cc | 13 -
 gcc/rust/backend/rust-tree.h  |  2 --
 gcc/tree.cc   | 13 +
 gcc/tree.h|  1 +
 6 files changed, 14 insertions(+), 29 deletions(-)

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index c1a371bc721..e6c1c63f872 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -8099,7 +8099,6 @@ extern tree build_exception_variant   (tree, 
tree);
 extern void fixup_deferred_exception_variants   (tree, tree);
 extern tree bind_template_template_parm(tree, tree);
 extern tree array_type_nelts_total (tree);
-extern tree array_type_nelts_top   (tree);
 extern bool array_of_unknown_bound_p   (const_tree);
 extern tree break_out_target_exprs (tree, bool = false);
 extern tree build_ctor_subob_ref   (tree, tree, tree);
diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
index 3baeb8fa252..1f3ecff1a21 100644
--- a/gcc/cp/tree.cc
+++ b/gcc/cp/tree.cc
@@ -3071,19 +3071,6 @@ cxx_print_statistics (void)
 depth_reached);
 }
 
-/* Return, as an INTEGER_CST node, the number of elements for TYPE
-   (which is an ARRAY_TYPE).  This counts only elements of the top
-   array.  */
-
-tree
-array_type_nelts_top (tree type)
-{
-  return fold_build2_loc (input_location,
- PLUS_EXPR, sizetype,
- array_type_nelts_minus_one (type),
- size_one_node);
-}
-
 /* Return, as an INTEGER_CST node, the number of elements for TYPE
(which is an ARRAY_TYPE).  This one is a recursive count of all
ARRAY_TYPEs that are clumped together.  */
diff --git a/gcc/rust/backend/rust-tree.cc b/gcc/rust/backend/rust-tree.cc
index a2c12204667..dd8eda84f9b 100644
--- a/gcc/rust/backend/rust-tree.cc
+++ b/gcc/rust/backend/rust-tree.cc
@@ -859,19 +859,6 @@ is_empty_class (tree type)
   return CLASSTYPE_EMPTY_P (type);
 }
 
-// forked from gcc/cp/tree.cc array_type_nelts_top
-
-/* Return, as an INTEGER_CST node, the number of elements for TYPE
-   (which is an ARRAY_TYPE).  This counts only elements of the top
-   array.  */
-
-tree
-array_type_nelts_top (tree type)
-{
-  return fold_build2_loc (input_location, PLUS_EXPR, sizetype,
- array_type_nelts_minus_one (type), size_one_node);
-}
-
 // forked from gcc/cp/tree.cc builtin_valid_in_constant_expr_p
 
 /* Test whether DECL is a builtin that may appear in a
diff --git a/gcc/rust/backend/rust-tree.h b/gcc/rust/backend/rust-tree.h
index 26c8b653ac6..e597c3ab81d 100644
--- a/gcc/rust/backend/rust-tree.h
+++ b/gcc/rust/backend/rust-tree.h
@@ -2993,8 +2993,6 @@ extern location_t rs_expr_location (const_tree);
 extern int
 is_empty_class (tree type);
 
-extern tree array_type_nelts_top (tree);
-
 extern bool
 is_really_empty_class (tree, bool);
 
diff --git a/gcc/tree.cc b/gcc/tree.cc
index dcaccc4c362..cbbc7627ad6 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -3729,6 +3729,19 @@ array_type_nelts_minus_one (const_tree type)
  ? max
  : fold_build2 (MINUS_EXPR, TREE_TYPE (max), max, min));
 }
+
+/* Return, as an INTEGER_CST node, the number of elements for TYPE
+   (which is an ARRAY_TYPE).  This counts only elements of the top
+   array.  */
+
+tree
+array_type_nelts_top (tree type)
+{
+  return fold_build2_loc (input_location,
+ PLUS_EXPR, sizetype,
+ array_type_nelts_minus_one (type),
+ size_one_node);
+}
 
 /* If arg is static -- a reference to an object in static storage -- then
return the object.  This is not the same as the C meaning of `static'.
diff --git a/gcc/tree.h b/gcc/tree.h
index fdddbcf408e..a6c46440b1a 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -4922,6 +4922,7 @@ extern tree build_method_type (tree, tree);
 extern tree build_offset_type (tree, tree);
 extern tree build_complex_type (tree, bool named = false);
 extern tree array_type_nelts_minus_one (const_tree);
+extern tree array_type_nelts_top (tree);
 
 extern tree value_member (tree, tree);
 extern tree purpose_member (const_tree, tree);
-- 
2.45.2



signature.asc
Description: PGP signature


[RFC v3 3/3] c: Add __lengthof__() operator

2024-08-03 Thread Alejandro Colomar
This operator is similar to sizeof() but can only be applied to an
array, and returns its length (number of elements).

TO BE DECIDED BEFORE MERGING:

It would be better to not evaluate the operand if the top-level
array is not a VLA.

FUTURE DIRECTIONS:

We could make it work with array parameters to functions, and
somehow magically return the length designator of the array,
regardless of it being really a pointer.

Link: <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2529.pdf>
Cc: Xavier Del Campo Romero 
Cc: Gabriel Ravier 
Cc: Martin Uecker 
Cc: Joseph Myers 
Cc: Jakub Jelinek 
Signed-off-by: Alejandro Colomar 
---
 gcc/c-family/c-common.cc  | 26 +++
 gcc/c-family/c-common.def |  3 ++
 gcc/c-family/c-common.h   |  2 +
 gcc/c/c-decl.cc   | 20 ++---
 gcc/c/c-parser.cc | 61 +++--
 gcc/c/c-tree.h|  4 ++
 gcc/c/c-typeck.cc | 95 +--
 gcc/cp/operators.def  |  1 +
 gcc/doc/extend.texi   | 12 +
 gcc/target.h  |  3 ++
 10 files changed, 203 insertions(+), 24 deletions(-)

diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index e7e371fd26f..91793dfbffc 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -465,6 +465,7 @@ const struct c_common_resword c_common_reswords[] =
   { "__inline",RID_INLINE, 0 },
   { "__inline__",  RID_INLINE, 0 },
   { "__label__",   RID_LABEL,  0 },
+  { "__lengthof__",RID_LENGTHOF, 0 },
   { "__null",  RID_NULL,   0 },
   { "__real",  RID_REALPART,   0 },
   { "__real__",RID_REALPART,   0 },
@@ -4070,6 +4071,31 @@ c_alignof_expr (location_t loc, tree expr)
 
   return fold_convert_loc (loc, size_type_node, t);
 }
+
+/* Implement the lengthof keyword: Return the length of an array,
+   that is, the number of elements in the array.  */
+
+tree
+c_lengthof_type (location_t loc, tree type)
+{
+  enum tree_code type_code;
+
+  type_code = TREE_CODE (type);
+  if (!COMPLETE_TYPE_P (type))
+{
+  error_at (loc,
+   "invalid application of % to incomplete type %qT",
+   type);
+  return error_mark_node;
+}
+  if (type_code != ARRAY_TYPE)
+{
+  error_at (loc, "invalid application of % to type %qT", type);
+  return error_mark_node;
+}
+
+  return array_type_nelts_top (type);
+}
 
 /* Handle C and C++ default attributes.  */
 
diff --git a/gcc/c-family/c-common.def b/gcc/c-family/c-common.def
index 5de96e5d4a8..6d162f67104 100644
--- a/gcc/c-family/c-common.def
+++ b/gcc/c-family/c-common.def
@@ -50,6 +50,9 @@ DEFTREECODE (EXCESS_PRECISION_EXPR, "excess_precision_expr", 
tcc_expression, 1)
number.  */
 DEFTREECODE (USERDEF_LITERAL, "userdef_literal", tcc_exceptional, 3)
 
+/* Represents a 'lengthof' expression.  */
+DEFTREECODE (LENGTHOF_EXPR, "lengthof_expr", tcc_expression, 1)
+
 /* Represents a 'sizeof' expression during C++ template expansion,
or for the purpose of -Wsizeof-pointer-memaccess warning.  */
 DEFTREECODE (SIZEOF_EXPR, "sizeof_expr", tcc_expression, 1)
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index ccaea27c2b9..f815a4cf3bc 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -105,6 +105,7 @@ enum rid
 
   /* C extensions */
   RID_ASM,   RID_TYPEOF,   RID_TYPEOF_UNQUAL, RID_ALIGNOF,  RID_ATTRIBUTE,
+  RID_LENGTHOF,
   RID_VA_ARG,
   RID_EXTENSION, RID_IMAGPART, RID_REALPART, RID_LABEL,RID_CHOOSE_EXPR,
   RID_TYPES_COMPATIBLE_P,  RID_BUILTIN_COMPLEX,   RID_BUILTIN_SHUFFLE,
@@ -885,6 +886,7 @@ extern tree c_common_truthvalue_conversion (location_t, 
tree);
 extern void c_apply_type_quals_to_decl (int, tree);
 extern tree c_sizeof_or_alignof_type (location_t, tree, bool, bool, int);
 extern tree c_alignof_expr (location_t, tree);
+extern tree c_lengthof_type (location_t, tree);
 /* Print an error message for invalid operands to arith operation CODE.
NOP_EXPR is used as a special case (see truthvalue_conversion).  */
 extern void binary_op_error (rich_location *, enum tree_code, tree, tree);
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 4dced430d1f..790c58b2558 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -8937,12 +8937,16 @@ start_struct (location_t loc, enum tree_code code, tree 
name,
  within a statement expr used within sizeof, et. al.  This is not
  terribly serious as C++ doesn't permit statement exprs within
  sizeof anyhow.  */
-  if (warn_cxx_compat && (in_sizeof || in_typeof || in_alignof))
+  if (warn_cxx_compat && (in_sizeof || in_typeof || in_alignof || in_lengthof))
 warning_at (loc, OPT_Wc___compat,
"defining type in %qs expression is invali

Re: [RFC v3 3/3] c: Add __lengthof__() operator

2024-08-04 Thread Alejandro Colomar
Hi Martin,

On Sun, Aug 04, 2024 at 07:38:49AM GMT, Martin Uecker wrote:
> Am Sonntag, dem 04.08.2024 um 01:17 +0200 schrieb Alejandro Colomar:
> > 
> > FUTURE DIRECTIONS:
> > 
> > We could make it work with array parameters to functions, and
> > somehow magically return the length designator of the array,
> > regardless of it being really a pointer.
> 
> And maybe flexible array members with "counted_by" attribute.

Hmmm; I didn't know that one.  Indeed.  I'll have a look at implementing
that in this patch set.

> > +
> > +/* Implement the lengthof keyword: Return the length of an array,
> > +   that is, the number of elements in the array.  */
> > +
> > +tree
> > +c_lengthof_type (location_t loc, tree type)
> > +{
> > +  enum tree_code type_code;
> > +
> > +  type_code = TREE_CODE (type);
> > +  if (!COMPLETE_TYPE_P (type))
> > +{
> > +  error_at (loc,
> > +   "invalid application of % to incomplete type %qT",
> > +   type);
> > +  return error_mark_node;
> > +}
> > +  if (type_code != ARRAY_TYPE)
> > +{
> > +  error_at (loc, "invalid application of % to type %qT", 
> > type);
> > +  return error_mark_node;
> > +}
> 
> I would swap these two errors, because the first is more specific and
> less helpful if you pass an incomplete struct, where it would be better
> to get the second error.

Agree.

BTW, I still don't understand what `if (! TYPE_DOMAIN (type))` means,
within array_type_nelts_minus_one().  What code triggers that condition?
Am I missing error handling for that?  Thanks!

Have a lovely day!
Alex

> 
> Martin
> 
> > +
> > +  return array_type_nelts_top (type);
> > +}
> 

-- 
<https://www.alejandro-colomar.es/>


signature.asc
Description: PGP signature


Re: [RFC v3 3/3] c: Add __lengthof__() operator

2024-08-04 Thread Alejandro Colomar
Hi Martin,

On Sun, Aug 04, 2024 at 11:39:26AM GMT, Martin Uecker wrote:
> Am Sonntag, dem 04.08.2024 um 10:25 +0200 schrieb Alejandro Colomar:
> > Hi Martin,
> > 
> > On Sun, Aug 04, 2024 at 07:38:49AM GMT, Martin Uecker wrote:
> > > Am Sonntag, dem 04.08.2024 um 01:17 +0200 schrieb Alejandro Colomar:
> > > > 
> > > > FUTURE DIRECTIONS:
> > > > 
> > > > We could make it work with array parameters to functions, and
> > > > somehow magically return the length designator of the array,
> > > > regardless of it being really a pointer.
> > > 
> > > And maybe flexible array members with "counted_by" attribute.
> > 
> > Hmmm; I didn't know that one.  Indeed.  I'll have a look at implementing
> > that in this patch set.
> 
> But maybe wait for this:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116016

Maybe; if I don't find a way to implement it now, their patches may give
me some tool to do it.  I'll still try to do it now, just to try.

I've drafted something by making build_counted_by_ref() an extern
function, and then I wrote

diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index 9f5feb83345..875d471a1f4 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -4078,6 +4078,7 @@ c_alignof_expr (location_t loc, tree expr)
 tree
 c_lengthof_type (location_t loc, tree type)
 {
+  tree counted_by;
   enum tree_code type_code;
 
   type_code = TREE_CODE (type);
@@ -4086,6 +4087,12 @@ c_lengthof_type (location_t loc, tree type)
   error_at (loc, "invalid application of % to type 
%qT", type);
   return error_mark_node;
 }
+
+  counted_by = lookup_attribute ("counted_by", DECL_ATTRIBUTES (type));
+  if (counted_by)
+// XXX: How to build the counted_by ref without the parent struct 
type?
+return build_counted_by_ref (NULL, type, counted_by);
+
   if (!COMPLETE_TYPE_P (type))
 {
   error_at (loc,

But since I don't have the struct to which the FAM belongs, I don't know
how to get that working.  Do you have any idea?  Or maybe it's better to
just wait for those patches to be merged, and reuse their
infrastructure?


> > > > +
> > > > +/* Implement the lengthof keyword: Return the length of an array,
> > > > +   that is, the number of elements in the array.  */
> > > > +
> > > > +tree
> > > > +c_lengthof_type (location_t loc, tree type)
> > > > +{
> > > > +  enum tree_code type_code;
> > > > +
> > > > +  type_code = TREE_CODE (type);
> > > > +  if (!COMPLETE_TYPE_P (type))
> > > > +{
> > > > +  error_at (loc,
> > > > +   "invalid application of % to incomplete type 
> > > > %qT",
> > > > +   type);
> > > > +  return error_mark_node;
> > > > +}
> > > > +  if (type_code != ARRAY_TYPE)
> > > > +{
> > > > +  error_at (loc, "invalid application of % to type 
> > > > %qT", type);
> > > > +  return error_mark_node;
> > > > +}
> > > 
> > > I would swap these two errors, because the first is more specific and
> > > less helpful if you pass an incomplete struct, where it would be better
> > > to get the second error.
> > 
> > Agree.
> > 
> > BTW, I still don't understand what `if (! TYPE_DOMAIN (type))` means,
> > within array_type_nelts_minus_one().  What code triggers that condition?
> > Am I missing error handling for that?  Thanks!
> 
> For incomplete arrays, basically we have the following different
> variants for arrays:

Thanks!  This list is very useful.

> T[ ] incomplete: !TYPE_DOMAIN 
> T[1] constant size: TYPE_MAX_VALUE == INTEGER_CST

I guess that old flexible-array members using [1] are understood as
normal arrays [42], right?

> T[n] variable size: TYPE_MAX_VALUE != INTEGER_CST
> T[0] flexible array member: !TYPE_MAX_VALUE && !C_TYPE_VARIABLE_SIZE
>   (ISO version T[0] has TYPE_SIZE == NULL_TREE)

ISO version is T[], right?  Did ISO add support for zero-sized arrays?

> T[*] unspecified variable size: !TYPE_MAX_VALUE && C_TYPE_VARIABLE_SIZE

This is not allowed aoutside of function-prototype scope.  And there it
decays to pointer way before reaching __lengthof__.  So we can't handle
that at the moment.  However, we'll have to keep 

Re: [RFC v3 3/3] c: Add __lengthof__() operator

2024-08-04 Thread Alejandro Colomar
On Sun, Aug 04, 2024 at 06:40:14PM GMT, Alejandro Colomar wrote:
> > The last 
> > case should return a non-constant.
> 
> The last case [*] is only allowed in prototypes.  How should we get the
> non-constant value?  It's just another way to say [], isn't it?
> 
> > If you reuse the sizeof code, it should be mostly correct, but
> > maybe the last case needs to be revisted. In the following
> > examples
> > 
> > void foo(char (*a)[3][*], int (*x)[__lengthof__(*a)]);
> > void bar(char (*a)[*][3], int (*x)[__lengthof__(*a)]);
> > 
> > the array '*x' should be a regular fixed size array in foo
> > but a VLA in 'bar'.
> 
> In the function prototype, it seems to be completely ignoring
> __lengthof__, just as it ignores any expression, so I don't know if it's
> working (I could try to print some debugging values to stderr from the
> compiler, if we care about it).

Huh, no, my bad.  It must be using the lengthof value.  It needs to
match pointers to arrays of a given size.  I'll test this.

> 
>   $ cat muecker.h 
>   void foo(char (*a)[3][*], int (*x)[__lengthof__(*a)]);
>   void bar(char (*a)[*][3], int (*x)[__lengthof__(*a)]);
>   void f(char (*a)[3][*], int (*x)[sizeof(*a)]);
>   void b(char (*a)[*][3], int (*x)[sizeof(*a)]);
>   $ /opt/local/gnu/gcc/lengthof/bin/gcc muecker.h -S
>   $
> 
> I assume the code above is not reaching my code.

-- 
<https://www.alejandro-colomar.es/>


signature.asc
Description: PGP signature


Re: [RFC v3 3/3] c: Add __lengthof__() operator

2024-08-04 Thread Alejandro Colomar
Hi Martin,

On Sun, Aug 04, 2024 at 06:43:46PM GMT, Alejandro Colomar wrote:
> On Sun, Aug 04, 2024 at 06:40:14PM GMT, Alejandro Colomar wrote:
> > > The last 
> > > case should return a non-constant.
> > 
> > The last case [*] is only allowed in prototypes.  How should we get the
> > non-constant value?  It's just another way to say [], isn't it?
> > 
> > > If you reuse the sizeof code, it should be mostly correct, but
> > > maybe the last case needs to be revisted. In the following
> > > examples
> > > 
> > > void foo(char (*a)[3][*], int (*x)[__lengthof__(*a)]);
> > > void bar(char (*a)[*][3], int (*x)[__lengthof__(*a)]);
> > > 
> > > the array '*x' should be a regular fixed size array in foo
> > > but a VLA in 'bar'.
> > 
> > In the function prototype, it seems to be completely ignoring
> > __lengthof__, just as it ignores any expression, so I don't know if it's
> > working (I could try to print some debugging values to stderr from the
> > compiler, if we care about it).
> 
> Huh, no, my bad.  It must be using the lengthof value.  It needs to
> match pointers to arrays of a given size.  I'll test this.

Is this missing diagnostics?

$ cat star.c 
void foo(char (*a)[3][*], int (*x)[__lengthof__(*a)]);
void bar(char (*a)[*][3], int (*x)[__lengthof__(*a)]);
void foos(char (*a)[3][*], int (*x)[sizeof(*a)]);
void bars(char (*a)[*][3], int (*x)[sizeof(*a)]);

int
main(void)
{
int  i3[3];
int  i5[5];
char c35[3][5];
char c53[5][3];

foo(&c35, &i3);
foo(&c35, &i5);  // I'd expect this to fail
bar(&c53, &i3);  // I'd expect this to fail
bar(&c53, &i5);

foos(&c35, &i3);
foos(&c35, &i5);  // I'd expect this to fail
bars(&c53, &i3);  // I'd expect this to fail
bars(&c53, &i5);
}
$ /opt/local/gnu/gcc/lengthof/bin/gcc -Wall -Wextra star.c -S
$

Cheers,
Alex

> 
> > 
> > $ cat muecker.h 
> > void foo(char (*a)[3][*], int (*x)[__lengthof__(*a)]);
> > void bar(char (*a)[*][3], int (*x)[__lengthof__(*a)]);
> > void f(char (*a)[3][*], int (*x)[sizeof(*a)]);
> > void b(char (*a)[*][3], int (*x)[sizeof(*a)]);
> > $ /opt/local/gnu/gcc/lengthof/bin/gcc muecker.h -S
> > $
> > 
> > I assume the code above is not reaching my code.
> 
> -- 
> <https://www.alejandro-colomar.es/>



-- 
<https://www.alejandro-colomar.es/>


signature.asc
Description: PGP signature


Re: [RFC v3 3/3] c: Add __lengthof__() operator

2024-08-04 Thread Alejandro Colomar
On Sun, Aug 04, 2024 at 08:02:25PM GMT, Martin Uecker wrote:
> Hi Alex,

Hi Martin,

> > Is this missing diagnostics?
> > 
> > $ cat star.c 
> > void foo(char (*a)[3][*], int (*x)[__lengthof__(*a)]);
> > void bar(char (*a)[*][3], int (*x)[__lengthof__(*a)]);
> > void foos(char (*a)[3][*], int (*x)[sizeof(*a)]);
> > void bars(char (*a)[*][3], int (*x)[sizeof(*a)]);
> > 
> > int
> > main(void)
> > {
> > int  i3[3];
> > int  i5[5];
> > char c35[3][5];
> > char c53[5][3];
> > 
> > foo(&c35, &i3);
> > foo(&c35, &i5);  // I'd expect this to fail
> 
> Yes, this should fail. The int (*)[5] is not
> compatible with int(*)[3].
> 
> > bar(&c53, &i3);  // I'd expect this to fail
> 
> This is no contraint violation, because int (*)[5] is
> compatible with int (*i)[*], so this needs to be accepted.

No constraint, but I'd expect a diagnostic from -Wextra (array-bounds?).

> It is then UB at run-time and the patches I posted recently

Can you please send a link to those patches?

> would catch this.  When possible, a compile time warning 
> would be nice and I am also looking into this.
> 
> It would also be good if we could allow a compiler to
> reject this at compile time... also something I am
> thinking about.

Thanks!

> 
> > bar(&c53, &i5);
> > 
> > foos(&c35, &i3);
> > foos(&c35, &i5);  // I'd expect this to fail
> > bars(&c53, &i3);  // I'd expect this to fail
> 
> These are both okay, because the sizeof is not an integer
> constant expressions (both int[*][3] and int[3][*] have
> variable size), so the last argument has to be compatible
> with int[*] which they both are.  Both would trigger
> run-time UB then because the size is then 15.

D'oh!  I screwed it.  I wanted to have written this:

$ cat star.c 
void foo(char (*a)[3][*], int (*x)[__lengthof__(*a)]);
void bar(char (*a)[*][3], int (*x)[__lengthof__(*a)]);
void foo2(char (*a)[3][*], int (*x)[sizeof(**a)]);
void bar2(char (*a)[*][3], int (*x)[sizeof(**a)]);

int
main(void)
{
int  i3[3];
int  i5[5];
char c35[3][5];
char c53[5][3];

foo(&c35, &i3);
foo(&c35, &i5);  // I'd expect this to err
bar(&c53, &i3);  // I'd expect this to warn
bar(&c53, &i5);

foo2(&c35, &i3);  // I'd expect this to warn
foo2(&c35, &i5);
bar2(&c53, &i3);
//bar2(&c53, &i5);  // error: -Wincompatible-pointer-types
}
$ /opt/local/gnu/gcc/lengthof/bin/gcc -Wall -Wextra star.c -S
$ 


> 
> Martin

Cheers,
Alex

-- 



signature.asc
Description: PGP signature


Re: [RFC v3 3/3] c: Add __lengthof__() operator

2024-08-05 Thread Alejandro Colomar
[CC += Kees, Qing]

Hi Joseph,

On Sun, Aug 04, 2024 at 08:34:24PM GMT, Alejandro Colomar wrote:
> On Sun, Aug 04, 2024 at 08:02:25PM GMT, Martin Uecker wrote:
> D'oh!  I screwed it.  I wanted to have written this:
> 
>   $ cat star.c 
>   void foo(char (*a)[3][*], int (*x)[__lengthof__(*a)]);

I think this answers your question of if we want __lengthof__ to
evaluate its operand if the top-level array is non-VLA but an inner
array is VLA.

We clearly want it to not evaluate, because we want this __lengthof__
to be a constant expression, ...

>   void bar(char (*a)[*][3], int (*x)[__lengthof__(*a)]);
>   void foo2(char (*a)[3][*], int (*x)[sizeof(**a)]);
>   void bar2(char (*a)[*][3], int (*x)[sizeof(**a)]);
> 
>   int
>   main(void)
>   {
>   int  i3[3];
>   int  i5[5];
>   char c35[3][5];
>   char c53[5][3];
> 
>   foo(&c35, &i3);
>   foo(&c35, &i5);  // I'd expect this to err

... and thus cause a compile-time error here
(-Wincompatible-pointer-types).

I suspect we need to modify array_type_nelts_minus_one() for that; I'm
going to investigate.

Have a lovely day!
Alex

>   bar(&c53, &i3);  // I'd expect this to warn
>   bar(&c53, &i5);
> 
>   foo2(&c35, &i3);  // I'd expect this to warn
>   foo2(&c35, &i5);
>   bar2(&c53, &i3);
>   //bar2(&c53, &i5);  // error: -Wincompatible-pointer-types
>   }
>   $ /opt/local/gnu/gcc/lengthof/bin/gcc -Wall -Wextra star.c -S
>   $ 

-- 
<https://www.alejandro-colomar.es/>


signature.asc
Description: PGP signature


Re: [RFC v3 3/3] c: Add __lengthof__() operator

2024-08-05 Thread Alejandro Colomar
Hi Martin,

On Sun, Aug 04, 2024 at 11:39:26AM GMT, Martin Uecker wrote:
> > BTW, I still don't understand what `if (! TYPE_DOMAIN (type))` means,
> > within array_type_nelts_minus_one().  What code triggers that condition?
> > Am I missing error handling for that?  Thanks!
> 
> For incomplete arrays, basically we have the following different
> variants for arrays:
> 
> T[ ] incomplete: !TYPE_DOMAIN 
> T[1] constant size: TYPE_MAX_VALUE == INTEGER_CST
> T[n] variable size: TYPE_MAX_VALUE != INTEGER_CST
> T[0] flexible array member: !TYPE_MAX_VALUE && !C_TYPE_VARIABLE_SIZE
>   (ISO version T[0] has TYPE_SIZE == NULL_TREE)
> T[*] unspecified variable size: !TYPE_MAX_VALUE && C_TYPE_VARIABLE_SIZE

Could you describe the following types?  I've repeated the ones you
already described, deduplicated some that have a different meaning in
different contexts, and added some multi-dimensional arrays.

T[ ] (incomplete type; function parameter)
T[ ] (flexible array member)
T[0] (zero-size array)
T[0] (GNU flexible array member)
T[1] (old flexible array member)
T[7] (constant size)
T[7][n]  (constant size with inner variable size)
T[7][*]  (constant size with inner unspecified size)
T[n] (variable size)
T[*] (unspecified size)

That would help with the [*] issues I'm investigating.  I think
array_type_nelts_minus_one(T[7][*]) is not giving a constant expression,
and I'd like to fix that.

Have a lovely day!
Alex

-- 



signature.asc
Description: PGP signature


Re: [RFC v3 3/3] c: Add __lengthof__() operator

2024-08-05 Thread Alejandro Colomar
On Mon, Aug 05, 2024 at 01:55:50PM GMT, Alejandro Colomar wrote:
> Hi Martin,
> 
> On Sun, Aug 04, 2024 at 11:39:26AM GMT, Martin Uecker wrote:
> > > BTW, I still don't understand what `if (! TYPE_DOMAIN (type))` means,
> > > within array_type_nelts_minus_one().  What code triggers that condition?
> > > Am I missing error handling for that?  Thanks!
> > 
> > For incomplete arrays, basically we have the following different
> > variants for arrays:
> > 
> > T[ ] incomplete: !TYPE_DOMAIN 
> > T[1] constant size: TYPE_MAX_VALUE == INTEGER_CST
> > T[n] variable size: TYPE_MAX_VALUE != INTEGER_CST
> > T[0] flexible array member: !TYPE_MAX_VALUE && !C_TYPE_VARIABLE_SIZE
> >   (ISO version T[0] has TYPE_SIZE == NULL_TREE)
> > T[*] unspecified variable size: !TYPE_MAX_VALUE && C_TYPE_VARIABLE_SIZE
> 
> Could you describe the following types?  I've repeated the ones you
> already described, deduplicated some that have a different meaning in
> different contexts, and added some multi-dimensional arrays.
> 
> T[ ] (incomplete type; function parameter)
> T[ ] (flexible array member)
> T[0] (zero-size array)
> T[0] (GNU flexible array member)
> T[1] (old flexible array member)
> T[7] (constant size)
> T[7][n]  (constant size with inner variable size)
> T[7][*]  (constant size with inner unspecified size)

And please also describe T[7][4], although I expect that to be just the
same as T[7].

> T[n] (variable size)
> T[*] (unspecified size)
> 
> That would help with the [*] issues I'm investigating.  I think
> array_type_nelts_minus_one(T[7][*]) is not giving a constant expression,
> and I'd like to fix that.
> 
> Have a lovely day!
> Alex
> 
> -- 
> <https://www.alejandro-colomar.es/>



-- 
<https://www.alejandro-colomar.es/>


signature.asc
Description: PGP signature


Re: [RFC v3 3/3] c: Add __lengthof__() operator

2024-08-05 Thread Alejandro Colomar
On Mon, Aug 05, 2024 at 01:57:35PM GMT, Alejandro Colomar wrote:
> On Mon, Aug 05, 2024 at 01:55:50PM GMT, Alejandro Colomar wrote:
> > Hi Martin,
> > 
> > On Sun, Aug 04, 2024 at 11:39:26AM GMT, Martin Uecker wrote:
> > > > BTW, I still don't understand what `if (! TYPE_DOMAIN (type))` means,
> > > > within array_type_nelts_minus_one().  What code triggers that condition?
> > > > Am I missing error handling for that?  Thanks!
> > > 
> > > For incomplete arrays, basically we have the following different
> > > variants for arrays:
> > > 
> > > T[ ] incomplete: !TYPE_DOMAIN 
> > > T[1] constant size: TYPE_MAX_VALUE == INTEGER_CST
> > > T[n] variable size: TYPE_MAX_VALUE != INTEGER_CST
> > > T[0] flexible array member: !TYPE_MAX_VALUE && !C_TYPE_VARIABLE_SIZE
> > >   (ISO version T[0] has TYPE_SIZE == NULL_TREE)
> > > T[*] unspecified variable size: !TYPE_MAX_VALUE && C_TYPE_VARIABLE_SIZE
> > 
> > Could you describe the following types?  I've repeated the ones you
> > already described, deduplicated some that have a different meaning in
> > different contexts, and added some multi-dimensional arrays.
> > 
> > T[ ] (incomplete type; function parameter)
> > T[ ] (flexible array member)
> > T[0] (zero-size array)
> > T[0] (GNU flexible array member)
> > T[1] (old flexible array member)
> > T[7] (constant size)
> > T[7][n]  (constant size with inner variable size)
> > T[7][*]  (constant size with inner unspecified size)
> 
> And please also describe T[7][4], although I expect that to be just the
> same as T[7].

And it would also be interesting to describe T[7][ ].

> 
> > T[n] (variable size)
> > T[*] (unspecified size)
> > 
> > That would help with the [*] issues I'm investigating.  I think
> > array_type_nelts_minus_one(T[7][*]) is not giving a constant expression,
> > and I'd like to fix that.
> > 
> > Have a lovely day!
> > Alex
> > 
> > -- 
> > <https://www.alejandro-colomar.es/>
> 
> 
> 
> -- 
> <https://www.alejandro-colomar.es/>



-- 
<https://www.alejandro-colomar.es/>


signature.asc
Description: PGP signature


Re: [RFC v3 3/3] c: Add __lengthof__() operator

2024-08-05 Thread Alejandro Colomar
On Mon, Aug 05, 2024 at 01:58:18PM GMT, Alejandro Colomar wrote:
> On Mon, Aug 05, 2024 at 01:57:35PM GMT, Alejandro Colomar wrote:
> > On Mon, Aug 05, 2024 at 01:55:50PM GMT, Alejandro Colomar wrote:
> > > Hi Martin,
> > > 
> > > On Sun, Aug 04, 2024 at 11:39:26AM GMT, Martin Uecker wrote:
> > > > > BTW, I still don't understand what `if (! TYPE_DOMAIN (type))` means,
> > > > > within array_type_nelts_minus_one().  What code triggers that 
> > > > > condition?
> > > > > Am I missing error handling for that?  Thanks!
> > > > 
> > > > For incomplete arrays, basically we have the following different
> > > > variants for arrays:
> > > > 
> > > > T[ ] incomplete: !TYPE_DOMAIN 
> > > > T[1] constant size: TYPE_MAX_VALUE == INTEGER_CST
> > > > T[n] variable size: TYPE_MAX_VALUE != INTEGER_CST
> > > > T[0] flexible array member: !TYPE_MAX_VALUE && !C_TYPE_VARIABLE_SIZE
> > > >   (ISO version T[0] has TYPE_SIZE == NULL_TREE)
> > > > T[*] unspecified variable size: !TYPE_MAX_VALUE && C_TYPE_VARIABLE_SIZE
> > > 
> > > Could you describe the following types?  I've repeated the ones you
> > > already described, deduplicated some that have a different meaning in
> > > different contexts, and added some multi-dimensional arrays.
> > > 
> > > T[ ] (incomplete type; function parameter)
> > > T[ ] (flexible array member)
> > > T[0] (zero-size array)
> > > T[0] (GNU flexible array member)
> > > T[1] (old flexible array member)
> > > T[7] (constant size)
> > > T[7][n]  (constant size with inner variable size)
> > > T[7][*]  (constant size with inner unspecified size)
> > 
> > And please also describe T[7][4], although I expect that to be just the
> > same as T[7].
> 
> And it would also be interesting to describe T[7][ ].

And maybe also:

T[n][m]
T[n][*]
T[n][ ]
T[n][7]

> 
> > 
> > > T[n] (variable size)
> > > T[*] (unspecified size)
> > > 
> > > That would help with the [*] issues I'm investigating.  I think
> > > array_type_nelts_minus_one(T[7][*]) is not giving a constant expression,
> > > and I'd like to fix that.
> > > 
> > > Have a lovely day!
> > > Alex
> > > 
> > > -- 
> > > <https://www.alejandro-colomar.es/>
> > 
> > 
> > 
> > -- 
> > <https://www.alejandro-colomar.es/>
> 
> 
> 
> -- 
> <https://www.alejandro-colomar.es/>



-- 
<https://www.alejandro-colomar.es/>


signature.asc
Description: PGP signature


Re: [RFC v3 3/3] c: Add __lengthof__() operator

2024-08-05 Thread Alejandro Colomar
Hi Martin,

On Mon, Aug 05, 2024 at 03:35:06PM GMT, Martin Uecker wrote:
> > > > > > For incomplete arrays, basically we have the following different
> > > > > > variants for arrays:
> > > > > > 
> > > > > > T[ ] incomplete: !TYPE_DOMAIN 
> > > > > > T[1] constant size: TYPE_MAX_VALUE == INTEGER_CST
> > > > > > T[n] variable size: TYPE_MAX_VALUE != INTEGER_CST
> > > > > > T[0] flexible array member: !TYPE_MAX_VALUE && !C_TYPE_VARIABLE_SIZE
> > > > > >   (ISO version T[0] has TYPE_SIZE == NULL_TREE)
> > > > > > T[*] unspecified variable size: !TYPE_MAX_VALUE && 
> > > > > > C_TYPE_VARIABLE_SIZE
> > > > > 
> > > > > Could you describe the following types?  I've repeated the ones you
> > > > > already described, deduplicated some that have a different meaning in
> > > > > different contexts, and added some multi-dimensional arrays.
> > > > > 
> > > > > T[ ] (incomplete type; function parameter)
> > > > > T[ ] (flexible array member)
> > > > > T[0] (zero-size array)
> > > > > T[0] (GNU flexible array member)
> > > > > T[1] (old flexible array member)
> > > > > T[7] (constant size)
> > > > > T[7][n]  (constant size with inner variable size)
> > > > > T[7][*]  (constant size with inner unspecified size)
> > > > 
> > > > And please also describe T[7][4], although I expect that to be just the
> > > > same as T[7].
> > > 
> > > And it would also be interesting to describe T[7][ ].
> > 
> > And maybe also:
> > 
> > T[n][m]
> > T[n][*]
> > T[n][ ]
> > T[n][7]
> 
> I do not understand your question. What do you mean by
> "describe the type"?

I had in mind what you already did above, (e.g.,
T[1] constant size: TYPE_MAX_VALUE == INTEGER_CST), but with a more
comprehensive list.  comptypes_internal() seems what I wanted.

> But I think you might make it unnecessarily complicated.  It
> should be sufficient to look at the outermost size.  You
> can completely ignore thatever happens There
> should be three cases if I am not mistaken:
> 
> - incomplete (includes ISO FAM) -> error
> - constant (includes GNU FAM) -> return fixed size
> - variable (includes unspecified) -> evaluate the
> argument and return the size, while making sure it is 
> visibly non-constant.
> 
> To check that the array has a variable length, you can use
> the same logic as in comptypes_internal (cf. d1_variable).

Hmmm, comptypes_internal() has taught me what I was asking here.
However, it seems to not be enough for what I actually need.

Here's my problem:

The array is correctly considered a fixed-length array.  I know it
because the following debugging code:

+fprintf(stderr, "ALX: %s() %d\n", __func__, __LINE__);
+tree dom = TYPE_DOMAIN (type);
+int zero = !TYPE_MAX_VALUE (dom);
+fprintf(stderr, "ALX: zero: %d\n", zero);
+int var0 = !zero
+&& (TREE_CODE (TYPE_MIN_VALUE (dom)) != INTEGER_CST
+   || TREE_CODE (TYPE_MAX_VALUE (dom)) != INTEGER_CST);
+fprintf(stderr, "ALX: var: %d\n", var0);
+int var = var0 || (zero && TYPE_LANG_FLAG_1(type));
+fprintf(stderr, "ALX: var: %d\n", var);
+  ret = array_type_nelts_top (type);
+fprintf(stderr, "ALX: %s() %d\n", __func__, __LINE__);

prints:

ALX: c_lengthof_type() 4098
ALX: zero: 0
ALX: var: 0
ALX: var: 0
ALX: c_lengthof_type() 4109

for
void foo(char (*a)[3][*], int (*x)[__lengthof__(*a)]);

That differs from

ALX: c_lengthof_type() 4098
ALX: zero: 1
ALX: var: 0
ALX: var: 1
ALX: c_lengthof_type() 4109

for
void bar(char (*a)[*][3], int (*x)[__lengthof__(*a)]);

However, if I turn on -Wvla, both get a warning:

len.c: At top level:
len.c:288:1: warning: ISO C90 forbids variable length array ‘x’ [-Wvla]
  288 | void foo(char (*a)[3][*], int (*x)[__lengthof__(*a)]);
  | ^~~~
len.c:289:1: warning: ISO C90 forbids variable length array ‘x’ [-Wvla]
  289 | void bar(char (*a)[*][3], int (*x)[__lengthof__(*a)]);
  | ^~~~

I suspect that the problem is in:

$ grepc -tfd array_type_nelts_minus_one gcc
gcc/tree.cc:tree
array_type_nelts_minus_one (const_tree type)
{
  tree index_type, min, max;

  /* If they did it with unspecified bounds, then we should have already
 given an error about it before we got here.  */
  if (! TYPE_DOMAIN (type))
return error_mark_node;

  index_type = TYPE_DOMAIN (type);
  min = TYPE_MIN_VALUE (index_type);
  max = TYPE_MAX_VALUE (index_type);

  /* TYPE_MAX_VALUE may not be set if the array has unknown length.  */
  if (!max)
{
  /* zero sized arrays are represented from C FE as complete types 
with
 NULL TYPE_MAX_VALUE and zero TYPE_SIZE, while C++ FE represents
 them as min 0, max -1.  */
  if (COMPLETE_T

  1   2   3   >