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; }
 };

Reply via email to