https://gcc.gnu.org/g:b02c061bb84c0a2dbf3987e9ff77243d089cbd7a

commit r15-7155-gb02c061bb84c0a2dbf3987e9ff77243d089cbd7a
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Thu Jan 23 11:17:47 2025 +0100

    c++: Fix build_omp_array_section for type dependent array_expr [PR118590]
    
    As can be seen on the testcase, when array_expr is type dependent, assuming
    it has non-NULL TREE_TYPE is just wrong, it can often have NULL type, and 
even
    if not, blindly assuming it is a pointer or array type is also wrong.
    
    So, like in many other spots in the C++ FE, for type dependent expressions
    we want to create something which will survive until instantiation and can 
be
    redone at that point.
    
    Unfortunately, build_omp_array_section is called before we actually do any
    kind of checking what array_expr really is, and on invalid code it can be 
e.g.
    a TYPE_DECL on which type_dependent_expression_p ICEs (as can be seen on the
    pr67522.C testcase).  So, I've hacked this by checking it is not TYPE_DECL,
    I hope a TYPE_P can't make it through there when we just lookup an 
identifier.
    
    Anyway, this patch is not enough, we can ICE e.g. on 
__uint128_t[0:something]
    during instantiation, so I think something needs to be done for this in 
pt.cc
    as well.
    
    2025-01-23  Jakub Jelinek  <ja...@redhat.com>
    
            PR c++/118590
            * typeck.cc (build_omp_array_section): If array_expr is type 
dependent
            or a TYPE_DECL, build OMP_ARRAY_SECTION with NULL type.
    
            * g++.dg/goacc/pr118590.C: New test.

Diff:
---
 gcc/cp/typeck.cc                      |  5 +++++
 gcc/testsuite/g++.dg/goacc/pr118590.C | 29 +++++++++++++++++++++++++++++
 2 files changed, 34 insertions(+)

diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index 6b549809243a..a9c32ff930d5 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -4867,6 +4867,11 @@ tree
 build_omp_array_section (location_t loc, tree array_expr, tree index,
                         tree length)
 {
+  if (TREE_CODE (array_expr) == TYPE_DECL
+      || type_dependent_expression_p (array_expr))
+    return build3_loc (loc, OMP_ARRAY_SECTION, NULL_TREE, array_expr, index,
+                      length);
+
   tree type = TREE_TYPE (array_expr);
   gcc_assert (type);
   type = non_reference (type);
diff --git a/gcc/testsuite/g++.dg/goacc/pr118590.C 
b/gcc/testsuite/g++.dg/goacc/pr118590.C
new file mode 100644
index 000000000000..846fe6702f46
--- /dev/null
+++ b/gcc/testsuite/g++.dg/goacc/pr118590.C
@@ -0,0 +1,29 @@
+// PR c++/118590
+// { dg-do compile }
+
+template <typename T>
+struct A
+{
+  int z;
+};
+
+template <typename T, typename U>
+struct B
+{
+  char *w;
+  A<T> y;
+};
+
+template <typename T, typename U>
+void
+foo  (B<T, U> &x)
+{
+  A<T> c = x.y;
+  #pragma acc enter data copyin(x.w[0 : c.z])
+}
+
+void
+bar (B<int, int> &x)
+{
+  foo (x);
+}

Reply via email to