[gcc r15-6452] gimple-fold: Fix up fold_array_ctor_reference RAW_DATA_CST handling [PR118207]
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
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]
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]
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; }