[gcc r15-6452] gimple-fold: Fix up fold_array_ctor_reference RAW_DATA_CST handling [PR118207]

2024-12-28 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:65c8fd7b017482c6d6bd0c7a7c6e296f016e38d0

commit r15-6452-g65c8fd7b017482c6d6bd0c7a7c6e296f016e38d0
Author: Jakub Jelinek 
Date:   Sat Dec 28 15:42:56 2024 +0100

gimple-fold: Fix up fold_array_ctor_reference RAW_DATA_CST handling 
[PR118207]

The following testcases ICE because fold_array_ctor_reference in the
RAW_DATA_CST handling just return build_int_cst without actually checking
that if type is non-NULL, TREE_TYPE (val) is uselessly convertible to it.

By falling through the code after it without *suboff += we get everything
we need, the two if conditionals will never be true (we've already
checked that size == BITS_PER_UNIT and so can't be 0, and val will be
INTEGER_CST), but it will do the important fold_ctor_reference call
which will deal with type incompatibilities.

2024-12-28  Jakub Jelinek  

PR tree-optimization/118207
* gimple-fold.cc (fold_array_ctor_reference): For RAW_DATA_CST,
just set val to build_int_cst and fall through to the normal
element handling code instead of returning build_int_cst right away.

* gcc.dg/pr118207.c: New test.

Diff:
---
 gcc/gimple-fold.cc|  3 +--
 gcc/testsuite/c-c++-common/cpp/embed-29.c | 17 +
 gcc/testsuite/gcc.dg/pr118207.c   | 25 +
 3 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc
index 2d6e2074416f..b0353de78158 100644
--- a/gcc/gimple-fold.cc
+++ b/gcc/gimple-fold.cc
@@ -9707,9 +9707,8 @@ fold_array_ctor_reference (tree type, tree ctor,
  constructor_elt *elt = CONSTRUCTOR_ELT (ctor, ctor_idx);
  if (elt->index == NULL_TREE || TREE_CODE (elt->index) != INTEGER_CST)
return NULL_TREE;
- *suboff += access_index.to_uhwi () * BITS_PER_UNIT;
  unsigned o = (access_index - wi::to_offset (elt->index)).to_uhwi ();
- return build_int_cst (TREE_TYPE (val), RAW_DATA_UCHAR_ELT (val, o));
+ val = build_int_cst (TREE_TYPE (val), RAW_DATA_UCHAR_ELT (val, o));
}
   if (!size && TREE_CODE (val) != CONSTRUCTOR)
{
diff --git a/gcc/testsuite/c-c++-common/cpp/embed-29.c 
b/gcc/testsuite/c-c++-common/cpp/embed-29.c
new file mode 100644
index ..0c524ef7abc4
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cpp/embed-29.c
@@ -0,0 +1,17 @@
+/* PR tree-optimization/118207 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+struct A { unsigned char a; };
+struct B { struct A b; };
+static const unsigned char c[] = {
+#embed __FILE__
+};
+struct B d;
+
+void
+foo ()
+{
+  const struct B *t = (const struct B *) &c;
+  d.b = t->b;
+}
diff --git a/gcc/testsuite/gcc.dg/pr118207.c b/gcc/testsuite/gcc.dg/pr118207.c
new file mode 100644
index ..6366721ae257
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr118207.c
@@ -0,0 +1,25 @@
+/* PR tree-optimization/118207 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+struct A { unsigned char a; };
+struct B { struct A b; };
+static const unsigned char c[160] = {
+  1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+  1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+  1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+  1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+  1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+  1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+  1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+  1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+  1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+  1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
+struct B d;
+
+void
+foo ()
+{
+  const struct B *t = (const struct B *) &c;
+  d.b = t->b;
+}


[gcc r15-6456] libstdc++-v3/testsuite/.../year_month_day/3.cc, 4.cc: Cut down for simulators

2024-12-28 Thread Hans-Peter Nilsson via Gcc-cvs
https://gcc.gnu.org/g:4da027d87eabd9a6cb0f5c1ed7ee10540501c7a3

commit r15-6456-g4da027d87eabd9a6cb0f5c1ed7ee10540501c7a3
Author: Hans-Peter Nilsson 
Date:   Sun Dec 29 03:32:04 2024 +0100

libstdc++-v3/testsuite/.../year_month_day/3.cc, 4.cc: Cut down for 
simulators

These two long-running tests happened to fail for me when
run in parallel (nprocs - 1) compared to a serial run, for
target mmix on my laptop.  The runtime is 3m40s for 3.cc
before this change, and 0.9s afterwards.

* testsuite/std/time/year_month_day/3.cc (test01): Add ifdeffery to
limit the tested dates.  For simulators, pass start and end dates
limiting the tested range to 10 days, centered on days (0).
* testsuite/std/time/year_month_day/4.cc: Ditto.

Diff:
---
 libstdc++-v3/testsuite/std/time/year_month_day/3.cc | 11 ++-
 libstdc++-v3/testsuite/std/time/year_month_day/4.cc | 10 +-
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/testsuite/std/time/year_month_day/3.cc 
b/libstdc++-v3/testsuite/std/time/year_month_day/3.cc
index 05dc750c0a09..f4829a686f79 100644
--- a/libstdc++-v3/testsuite/std/time/year_month_day/3.cc
+++ b/libstdc++-v3/testsuite/std/time/year_month_day/3.cc
@@ -1,4 +1,5 @@
 // { dg-do run { target c++20 } }
+// { dg-additional-options "-DSTART_DAY=-5 -DEND_DAY=5 
-DSTART_YMD=1833y/February/8d" { target simulator } }
 
 // Copyright (C) 2021-2024 Free Software Foundation, Inc.
 //
@@ -50,11 +51,19 @@ void test01()
 {
   using namespace std::chrono;
 
+#ifdef START_DAY
+  auto n   = days{START_DAY};
+  auto ymd = START_YMD;
+  auto end_day = days{END_DAY};
+#else
   // [-12687428, 11248737] maps to [-32767y/January/1d, 32767y/December/31d]
 
   auto n   = days{-12687428};
   auto ymd = -32767y/January/1d;
-  while (n < days{11248737}) {
+  auto end_day = days{11248737};
+#endif
+
+  while (n < end_day) {
 VERIFY( year_month_day{sys_days{n}} == ymd );
 ++n;
 advance(ymd);
diff --git a/libstdc++-v3/testsuite/std/time/year_month_day/4.cc 
b/libstdc++-v3/testsuite/std/time/year_month_day/4.cc
index 6b6714e3a85e..09a7551dcfc0 100644
--- a/libstdc++-v3/testsuite/std/time/year_month_day/4.cc
+++ b/libstdc++-v3/testsuite/std/time/year_month_day/4.cc
@@ -1,4 +1,5 @@
 // { dg-do run { target c++20 } }
+// { dg-additional-options "-DSTART_DAY=-5 -DSTART_YMD=1833y/February/8d 
-DEND_YMD=2106y/November/24d" { target simulator } }
 
 // Copyright (C) 2021-2024 Free Software Foundation, Inc.
 //
@@ -50,11 +51,18 @@ void test01()
 {
   using namespace std::chrono;
 
+#ifdef START_DAY
+  auto n   = days{START_DAY};
+  auto ymd = START_YMD;
+#else
   // [-32767y/January/1d, 32767y/December/31d] maps to [-12687428, 11248737]
 
   auto n   = days{-12687428};
   auto ymd = -32767y/January/1d;
-  while (ymd < 32767y/December/31d) {
+#define END_YMD 32767y/December/31d
+#endif
+
+  while (ymd < END_YMD) {
 VERIFY( static_cast(ymd) == sys_days{n} );
 ++n;
 advance(ymd);


[gcc r15-6453] c++: Don't treat lambda typedef as lambda declaration [PR106221]

2024-12-28 Thread Nathaniel Shead via Gcc-cvs
https://gcc.gnu.org/g:ce81cd2eac686dc0f1c91adac779add550b0

commit r15-6453-gce81cd2eac686dc0f1c91adac779add550b0
Author: Nathaniel Shead 
Date:   Sun Dec 22 01:18:16 2024 +1100

c++: Don't treat lambda typedef as lambda declaration [PR106221]

I noticed that in a couple of places we sometimes treat any TYPE_DECL of
lambda type as defining a lambda, which isn't always true since C++20:
in `using T = decltype([]{})`, T is not a lambda-declaration.

PR c++/106221
PR c++/110680

gcc/cp/ChangeLog:

* pt.cc (check_default_tmpl_args): Check this is actually a
lambda declaration and not just a typedef.
(push_template_decl): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/cpp2a/lambda-uneval19.C: New test.

Signed-off-by: Nathaniel Shead 

Diff:
---
 gcc/cp/pt.cc |  8 
 gcc/testsuite/g++.dg/cpp2a/lambda-uneval19.C | 20 
 2 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 7fa286698ef2..0ffa0b53e26a 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -5637,8 +5637,7 @@ check_default_tmpl_args (tree decl, tree parms, bool 
is_primary,
local scope.  */
 return true;
 
-  if ((TREE_CODE (decl) == TYPE_DECL
-   && TREE_TYPE (decl)
+  if ((DECL_IMPLICIT_TYPEDEF_P (decl)
&& LAMBDA_TYPE_P (TREE_TYPE (decl)))
   || (TREE_CODE (decl) == FUNCTION_DECL
  && LAMBDA_FUNCTION_P (decl)))
@@ -5924,7 +5923,7 @@ push_template_decl (tree decl, bool is_friend)
  template  friend void A::f();
is not primary.  */
 ;
-  else if (TREE_CODE (decl) == TYPE_DECL && LAMBDA_TYPE_P (TREE_TYPE (decl)))
+  else if (DECL_IMPLICIT_TYPEDEF_P (decl) && LAMBDA_TYPE_P (TREE_TYPE (decl)))
 /* Lambdas are not primary.  */
 ;
   else
@@ -6077,7 +6076,8 @@ push_template_decl (tree decl, bool is_friend)
   else if (!ctx
   || TREE_CODE (ctx) == FUNCTION_DECL
   || (CLASS_TYPE_P (ctx) && TYPE_BEING_DEFINED (ctx))
-  || (TREE_CODE (decl) == TYPE_DECL && LAMBDA_TYPE_P (TREE_TYPE 
(decl)))
+  || (DECL_IMPLICIT_TYPEDEF_P (decl)
+  && LAMBDA_TYPE_P (TREE_TYPE (decl)))
   || (is_friend && !(DECL_LANG_SPECIFIC (decl)
  && DECL_TEMPLATE_INFO (decl
 {
diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-uneval19.C 
b/gcc/testsuite/g++.dg/cpp2a/lambda-uneval19.C
new file mode 100644
index ..a9682cce6e67
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/lambda-uneval19.C
@@ -0,0 +1,20 @@
+// { dg-do compile { target c++20 } }
+
+// PR c++/106221
+using T = decltype([](){});
+
+template
+using foo = T;
+
+using bar = foo;
+
+// PR c++/110680
+template 
+struct S {
+  auto f() { return X; }
+};
+
+template 
+using C = decltype(S().f());
+
+using D = C;


[gcc r15-6454] c++/modules: Fallback to ftruncate if posix_fallocate fails [PR115008]

2024-12-28 Thread Nathaniel Shead via Gcc-cvs
https://gcc.gnu.org/g:84aa7065deec49bab9fb0b085cd0a0dcc42cc479

commit r15-6454-g84aa7065deec49bab9fb0b085cd0a0dcc42cc479
Author: Nathaniel Shead 
Date:   Sat Dec 21 23:42:28 2024 +1100

c++/modules: Fallback to ftruncate if posix_fallocate fails [PR115008]

Depending on the libc and filesystem, in cases where posix_fallocate
cannot do an efficient preallocation it may return EINVAL.  In such a
case we should fall back to ftruncate instead.

Apparently, depending on the system the use of posix_fallocate can have
a noticeable speedup over ftruncate in general (depending on the system)
so it probably isn't worth it to use ftruncate in all cases.

PR c++/100358
PR c++/115008

gcc/cp/ChangeLog:

* module.cc (elf_out::create_mapping): Fallback to ftruncate if
posix_fallocate fails.

Signed-off-by: Nathaniel Shead 

Diff:
---
 gcc/cp/module.cc | 19 ++-
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index b9cf16433b5d..9ad587ebd6ac 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -1905,13 +1905,23 @@ elf_in::begin (location_t loc)
 void
 elf_out::create_mapping (unsigned ext, bool extending)
 {
-#ifndef HAVE_POSIX_FALLOCATE
-#define posix_fallocate(fd,off,len) ftruncate (fd, off + len)
+  /* A wrapper around posix_fallocate, falling back to ftruncate
+ if the underlying filesystem does not support the operation.  */
+  auto allocate = [](int fd, off_t offset, off_t length)
+{
+#ifdef HAVE_POSIX_FALLOCATE
+  int result = posix_fallocate (fd, offset, length);
+  if (result != EINVAL)
+   return result == 0;
+  /* Not supported by the underlying filesystem, fallback to ftruncate.  */
 #endif
+  return ftruncate (fd, offset + length) == 0;
+};
+
   void *mapping = MAP_FAILED;
   if (extending && ext < 1024 * 1024)
 {
-  if (!posix_fallocate (fd, offset, ext * 2))
+  if (allocate (fd, offset, ext * 2))
mapping = mmap (NULL, ext * 2, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, offset);
   if (mapping != MAP_FAILED)
@@ -1919,7 +1929,7 @@ elf_out::create_mapping (unsigned ext, bool extending)
 }
   if (mapping == MAP_FAILED)
 {
-  if (!extending || !posix_fallocate (fd, offset, ext))
+  if (!extending || allocate (fd, offset, ext))
mapping = mmap (NULL, ext, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, offset);
   if (mapping == MAP_FAILED)
@@ -1929,7 +1939,6 @@ elf_out::create_mapping (unsigned ext, bool extending)
  ext = 0;
}
 }
-#undef posix_fallocate
   hdr.buffer = (char *)mapping;
   extent = ext;
 }