[gcc/devel/omp/gcc-16] OpenMP/C++: Don't do NRVO on vars used in an 'omp allocate' directive

Sandra Loosemore via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
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; }
 };
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.