https://gcc.gnu.org/g:f0b74d62dcbf53715b9c288e9f86286d040730b3
commit f0b74d62dcbf53715b9c288e9f86286d040730b3 Author: Waffl3x <[email protected]> Date: Tue May 5 09:02:00 2026 -0600 OpenMP/C++: Don't do NRVO on vars used in an 'omp allocate' directive NRVO is incompatible with the transformations made by an allocate directive, this patch disables it for those variables. Also adjusts a few tests that were modified to work around this bug. gcc/cp/ChangeLog: * typeck.cc (can_do_nrvo_p): Return false for vars in an allocate directive. gcc/testsuite/ChangeLog: * g++.dg/gomp/allocate-5.C: Remove workarounds, enable ilp32. * g++.dg/gomp/allocate-6.C: Likewise. * g++.dg/gomp/allocate-7.C: Likewise. * g++.dg/gomp/allocate-22.C: New test. Signed-off-by: Waffl3x <[email protected]> Diff: --- gcc/cp/typeck.cc | 5 ++++- gcc/testsuite/g++.dg/gomp/allocate-22.C | 31 +++++++++++++++++++++++++++++++ gcc/testsuite/g++.dg/gomp/allocate-5.C | 3 +-- gcc/testsuite/g++.dg/gomp/allocate-6.C | 3 +-- gcc/testsuite/g++.dg/gomp/allocate-7.C | 8 +++++--- 5 files changed, 42 insertions(+), 8 deletions(-) diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc index 7e2d4efa4c77..688637261c1b 100644 --- a/gcc/cp/typeck.cc +++ b/gcc/cp/typeck.cc @@ -11171,7 +11171,10 @@ can_do_nrvo_p (tree retval, tree functype) && same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (retval)), TYPE_MAIN_VARIANT (functype)) /* And the returned value must be non-volatile. */ - && !TYPE_VOLATILE (TREE_TYPE (retval))); + && !TYPE_VOLATILE (TREE_TYPE (retval)) + /* And the variable must not be used in an allocate directive. */ + && (!flag_openmp || !lookup_attribute ("omp allocate", + DECL_ATTRIBUTES (retval)))); } /* True if we would like to perform NRVO, i.e. can_do_nrvo_p is true and we diff --git a/gcc/testsuite/g++.dg/gomp/allocate-22.C b/gcc/testsuite/g++.dg/gomp/allocate-22.C new file mode 100644 index 000000000000..821d9b2c6108 --- /dev/null +++ b/gcc/testsuite/g++.dg/gomp/allocate-22.C @@ -0,0 +1,31 @@ +/* { dg-do compile { target c++14 } } */ + +/* This used to ICE due to NRVO being attempted on 's', NRVO can not be + done on a variable used in an allocate directive. */ + +/* NRVO probably kicks in when sizeof(T) is greater than 16. */ +struct S +{ + char _v[17]; +}; + +S f0() +{ + S s; + #pragma omp allocate(s) + return s; +} + +/* Also test with a VERY LARGE type just in case the above isn't big enough + to trigger NRVO in all cases. */ +struct Big +{ + char _v[4096]; +}; + +Big f1() +{ + Big b; + #pragma omp allocate(b) + return b; +} diff --git a/gcc/testsuite/g++.dg/gomp/allocate-5.C b/gcc/testsuite/g++.dg/gomp/allocate-5.C index 724dd9801380..f1085521fc59 100644 --- a/gcc/testsuite/g++.dg/gomp/allocate-5.C +++ b/gcc/testsuite/g++.dg/gomp/allocate-5.C @@ -1,5 +1,4 @@ /* { dg-additional-options "-fdump-tree-gimple" } */ -/* { dg-skip-if "" { ilp32 } } */ #include "allocate-allocator-handle.h" @@ -55,7 +54,7 @@ struct S0 { }; struct S1 { - int _v[2]; + int _v[32]; S1(int v) : _v() { int *end = _v + sizeof(_v) / sizeof(*_v); for (int *it = _v; it != end; ++it) diff --git a/gcc/testsuite/g++.dg/gomp/allocate-6.C b/gcc/testsuite/g++.dg/gomp/allocate-6.C index eb0c78a24db9..d33b7d530971 100644 --- a/gcc/testsuite/g++.dg/gomp/allocate-6.C +++ b/gcc/testsuite/g++.dg/gomp/allocate-6.C @@ -1,5 +1,4 @@ /* { dg-do compile { target c++11 } } */ -/* { dg-skip-if "" { ilp32 } } */ /* { dg-additional-options "-fdump-tree-gimple" } */ #include "allocate-allocator-handle.h" @@ -23,7 +22,7 @@ struct S0 { }; struct S1 { - int _v[2]; + int _v[32]; S1(int v) : _v() { int *end = _v + sizeof(_v) / sizeof(*_v); for (int *it = _v; it != end; ++it) diff --git a/gcc/testsuite/g++.dg/gomp/allocate-7.C b/gcc/testsuite/g++.dg/gomp/allocate-7.C index 01fc5b84014d..16cc5843d1b6 100644 --- a/gcc/testsuite/g++.dg/gomp/allocate-7.C +++ b/gcc/testsuite/g++.dg/gomp/allocate-7.C @@ -1,5 +1,4 @@ /* { dg-do compile { target c++20 } } */ -/* { dg-skip-if "" { ilp32 } } */ /* { dg-additional-options "-fdump-tree-gimple" } */ #include "allocate-allocator-handle.h" @@ -37,8 +36,11 @@ struct S0 { }; struct S1 { - int _v[2]; - S1(int v) : _v{v, v} {} + int _v[32]; + S1(int v) : _v{v, v, v, v, v, v, v, v, + v, v, v, v, v, v, v, v, + v, v, v, v, v, v, v, v, + v, v, v, v, v, v, v, v} {} operator int() const { return 42; } };
