This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH for c++/60146 (ICE with #pragma omp for)


My earlier patch to simplify DECL_EXPR handling simplified things too far, since the omp_for code really wants to keep control of initializing non-class iterators. So I needed to re-complexify the code a bit.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit 4929fd87044013cb0987ba95a00c01e29bdfa3a7
Author: Jason Merrill <jason@redhat.com>
Date:   Mon Feb 24 15:51:35 2014 -0500

    	PR c++/60146
    	* pt.c (tsubst_omp_for_iterator): Don't let substitution of the
    	DECL_EXPR initialize a non-class iterator.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 2dc5f32..d6198c0 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -13063,31 +13063,40 @@ tsubst_omp_for_iterator (tree t, int i, tree declv, tree initv,
   tsubst_expr ((NODE), args, complain, in_decl,	\
 	       integral_constant_expression_p)
   tree decl, init, cond, incr;
-  bool init_decl;
 
   init = TREE_VEC_ELT (OMP_FOR_INIT (t), i);
   gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
   decl = TREE_OPERAND (init, 0);
   init = TREE_OPERAND (init, 1);
-  /* Do this before substituting into decl to handle 'auto'.  */
-  init_decl = (init && TREE_CODE (init) == DECL_EXPR);
+  tree decl_expr = NULL_TREE;
+  if (init && TREE_CODE (init) == DECL_EXPR)
+    {
+      decl_expr = init;
+      init = DECL_INITIAL (DECL_EXPR_DECL (init));
+      decl = tsubst_decl (decl, args, complain);
+    }
+  else
+    decl = RECUR (decl);
   init = RECUR (init);
-  decl = RECUR (decl);
 
-  if (decl == error_mark_node || init == error_mark_node)
-    return;
-
-  if (init_decl)
-    {
-      gcc_assert (!processing_template_decl);
-      init = DECL_INITIAL (decl);
-      DECL_INITIAL (decl) = NULL_TREE;
-    }
+  tree auto_node = type_uses_auto (TREE_TYPE (decl));
+  if (auto_node && init)
+    TREE_TYPE (decl)
+      = do_auto_deduction (TREE_TYPE (decl), init, auto_node);
 
   gcc_assert (!type_dependent_expression_p (decl));
 
   if (!CLASS_TYPE_P (TREE_TYPE (decl)))
     {
+      if (decl_expr)
+	{
+	  /* Declare the variable, but don't let that initialize it.  */
+	  tree init_sav = DECL_INITIAL (DECL_EXPR_DECL (decl_expr));
+	  DECL_INITIAL (DECL_EXPR_DECL (decl_expr)) = NULL_TREE;
+	  RECUR (decl_expr);
+	  DECL_INITIAL (DECL_EXPR_DECL (decl_expr)) = init_sav;
+	}
+
       cond = RECUR (TREE_VEC_ELT (OMP_FOR_COND (t), i));
       incr = TREE_VEC_ELT (OMP_FOR_INCR (t), i);
       if (TREE_CODE (incr) == MODIFY_EXPR)
@@ -13104,7 +13113,13 @@ tsubst_omp_for_iterator (tree t, int i, tree declv, tree initv,
       return;
     }
 
-  if (init && !init_decl)
+  if (decl_expr)
+    {
+      /* Declare and initialize the variable.  */
+      RECUR (decl_expr);
+      init = NULL_TREE;
+    }
+  else if (init)
     {
       tree c;
       for (c = *clauses; c ; c = OMP_CLAUSE_CHAIN (c))
diff --git a/gcc/testsuite/g++.dg/gomp/for-20.C b/gcc/testsuite/g++.dg/gomp/for-20.C
new file mode 100644
index 0000000..7b57b16
--- /dev/null
+++ b/gcc/testsuite/g++.dg/gomp/for-20.C
@@ -0,0 +1,16 @@
+// PR c++/60146
+// { dg-do compile }
+// { dg-options -fopenmp }
+
+int foo() { return 0; }
+
+template<typename T> void bar()
+{
+#pragma omp parallel for
+  for (T i = foo(); i < 8; ++i) {}
+}
+
+void baz()
+{
+  bar<int>();
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]