public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r13-5379] openmp, c++: Workaround fold_for_warn ICE on invalid OpenMP collapsed loops [PR108503]
@ 2023-01-26  9:48 Jakub Jelinek
  0 siblings, 0 replies; only message in thread
From: Jakub Jelinek @ 2023-01-26  9:48 UTC (permalink / raw)
  To: gcc-cvs

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

commit r13-5379-gd427407a199a0c276cb02d6bbb64e6ecc02e590d
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Thu Jan 26 10:41:10 2023 +0100

    openmp, c++: Workaround fold_for_warn ICE on invalid OpenMP collapsed loops [PR108503]
    
    My recent change to deduce structured binding vars earlier caused the following
    invalid testcase to ICE.  The problem is that because at cp_convert_omp_range_for
    when !processing_template_decl we aren't yet ready to finalize the structured bindings
    (e.g. can't emit there associated code) but need to deduce types of the vars so that
    we don't get errors if we parse invalid uses of those vars in inner loops of the
    collapsed construct.  This is done by temporarily bumping processing_template_decl
    around the call to cp_finish_decomp.  Unfortunately, as we can't finalize it yet,
    the types of the vars will be deduced, but their DECL_VALUE_EXPR is not finalized
    yet and if say fold_for_warn tries to constant expression evaluate them, it
    recurses on DECL_VALUE_EXPR and ICEs because it sees e.g. ARRAY_REF (with NULL type)
    on a VAR_DECL with class type.
    
    The following patch works around that by temporarily hiding the DECL_VALUE_EXPRs
    by clearing DECL_HAS_VALUE_EXPR_P in that case during cp_convert_omp_range_for
    and arranging for cp_finish_omp_range_for to set it back before doing the
    final cp_finish_decomp.
    
    2023-01-25  Jakub Jelinek  <jakub@redhat.com>
    
            PR c++/108503
            * parser.cc (cp_convert_omp_range_for): If cp_finish_decomp has been
            called in !processing_template_decl with processing_template_decl
            temporarily set, clear DECL_HAS_VALUE_EXPR_P on the vars temporarily.
            (cp_finish_omp_range_for): And set it back again here.
    
            * g++.dg/gomp/pr108503.C: New test.

Diff:
---
 gcc/cp/parser.cc                     | 27 +++++++++++++++++++++++++++
 gcc/testsuite/g++.dg/gomp/pr108503.C | 27 +++++++++++++++++++++++++++
 2 files changed, 54 insertions(+)

diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 07ec0e14491..e0c46d2d748 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -43039,6 +43039,7 @@ cp_convert_omp_range_for (tree &this_pre_body, vec<tree, va_gc> *for_block,
 {
   tree begin, end, range_temp_decl = NULL_TREE;
   tree iter_type, begin_expr, end_expr;
+  bool clear_has_value_expr = false;
 
   if (processing_template_decl)
     {
@@ -43185,6 +43186,8 @@ cp_convert_omp_range_for (tree &this_pre_body, vec<tree, va_gc> *for_block,
 	      ++processing_template_decl;
 	      cp_finish_decomp (orig_decl, decomp_first_name, decomp_cnt);
 	      --processing_template_decl;
+	      if (!processing_template_decl)
+		clear_has_value_expr = true;
 	    }
 	}
     }
@@ -43193,8 +43196,20 @@ cp_convert_omp_range_for (tree &this_pre_body, vec<tree, va_gc> *for_block,
   TREE_VEC_ELT (v, 0) = range_temp_decl;
   TREE_VEC_ELT (v, 1) = end;
   TREE_VEC_ELT (v, 2) = orig_decl;
+  if (clear_has_value_expr)
+    TREE_PUBLIC (v) = 1;
   for (unsigned i = 0; i < decomp_cnt; i++)
     {
+      if (clear_has_value_expr)
+	{
+	  /* If cp_finish_decomp was called with processing_template_decl
+	     temporarily set to 1, then decomp names will have deduced
+	     name but the DECL_VALUE_EXPR will be dependent.  Hide those
+	     from folding of other loop initializers e.g. for warning
+	     purposes until cp_finish_omp_range_for.  */
+	  gcc_checking_assert (DECL_HAS_VALUE_EXPR_P (decomp_first_name));
+	  DECL_HAS_VALUE_EXPR_P (decomp_first_name) = 0;
+	}
       TREE_VEC_ELT (v, i + 3) = decomp_first_name;
       decomp_first_name = DECL_CHAIN (decomp_first_name);
     }
@@ -43217,6 +43232,18 @@ cp_finish_omp_range_for (tree orig, tree begin)
     {
       decomp_first_name = TREE_VEC_ELT (TREE_CHAIN (orig), 3);
       decomp_cnt = TREE_VEC_LENGTH (TREE_CHAIN (orig)) - 3;
+      if (TREE_PUBLIC (TREE_CHAIN (orig)))
+	{
+	  /* Undo temporary clearing of DECL_HAS_VALUE_EXPR_P done
+	     by cp_convert_omp_range_for above.  */
+	  TREE_PUBLIC (TREE_CHAIN (orig)) = 0;
+	  tree d = decomp_first_name;
+	  for (unsigned i = 0; i < decomp_cnt; i++)
+	    {
+	      DECL_HAS_VALUE_EXPR_P (d) = 1;
+	      d = DECL_CHAIN (d);
+	    }
+	}
       cp_maybe_mangle_decomp (decl, decomp_first_name, decomp_cnt);
     }
 
diff --git a/gcc/testsuite/g++.dg/gomp/pr108503.C b/gcc/testsuite/g++.dg/gomp/pr108503.C
new file mode 100644
index 00000000000..906d41b9a8f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/gomp/pr108503.C
@@ -0,0 +1,27 @@
+// PR c++/108503
+// { dg-do compile { target c++17 } }
+// { dg-additional-options "-Wall" }
+
+namespace std {
+  template <typename T> struct tuple_size;
+  template <int, typename> struct tuple_element;
+}
+struct A {
+  template <int I> int get () { return 1; }
+};
+template <> struct std::tuple_size <A> { static const int value = 3; };
+template <int I> struct std::tuple_element <I, A> { using type = int; };
+
+struct B {
+  A *begin ();
+  A *end ();
+};
+
+void
+foo (B a)
+{
+  #pragma omp for collapse(2)
+  for (auto [i, j, k] : a)
+    for (int l = i; l < j; l += k)	// { dg-error "initializer expression refers to iteration variable 'i'" }
+      ;					// { dg-error "condition expression refers to iteration variable 'j'" "" { target *-*-* } .-1 }
+}					// { dg-error "increment expression refers to iteration variable 'k'" "" { target *-*-* } .-2 }

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-01-26  9:48 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-26  9:48 [gcc r13-5379] openmp, c++: Workaround fold_for_warn ICE on invalid OpenMP collapsed loops [PR108503] Jakub Jelinek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).