re PR c++/58706 (ICE with lambda in OpenMP for-loop)
authorJakub Jelinek <jakub@gcc.gnu.org>
Mon, 8 Aug 2016 19:50:29 +0000 (21:50 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 8 Aug 2016 19:50:29 +0000 (21:50 +0200)
PR c++/58706
* parser.c: Include tree-iterator.h.
(cp_parser_omp_for_loop_init): Move lambda DECL_EXPRs from init
to FOR_BLOCK.
(cp_parser_omp_for_loop): Handle non-STATEMENT_LIST FOR_BLOCK
entries.

* testsuite/libgomp.c++/pr58706.C: New test.

From-SVN: r239251

gcc/cp/ChangeLog
gcc/cp/parser.c
libgomp/ChangeLog
libgomp/testsuite/libgomp.c++/pr58706.C [new file with mode: 0644]

index 4efbc7b..bd036a8 100644 (file)
@@ -1,9 +1,18 @@
+2016-08-08  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/58706
+       * parser.c: Include tree-iterator.h.
+       (cp_parser_omp_for_loop_init): Move lambda DECL_EXPRs from init
+       to FOR_BLOCK.
+       (cp_parser_omp_for_loop): Handle non-STATEMENT_LIST FOR_BLOCK
+       entries.
+
 2016-08-06  Jonathan Wakely  <jwakely@redhat.com>
 
        * call.c (convert_like_real): Harmonize diagnostics for invalid
        reference binding.
 
-2016-08-05 Martin Sebor  <msebor@redhat.com>
+2016-08-05  Martin Sebor  <msebor@redhat.com>
 
        * constexpr.c (cxx_eval_store_expression): Remove hyphen from
        the spelling of "constant-expression" in diagnostic messages
index 72a494d..cff735b 100644 (file)
@@ -41,6 +41,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "context.h"
 #include "cp-cilkplus.h"
 #include "gcc-rich-location.h"
+#include "tree-iterator.h"
 
 \f
 /* The lexer.  */
@@ -33495,7 +33496,33 @@ cp_parser_omp_for_loop_init (cp_parser *parser,
                  init = NULL_TREE;
                }
              else
-               init = pop_stmt_list (this_pre_body);
+               {
+                 init = pop_stmt_list (this_pre_body);
+                 if (init && TREE_CODE (init) == STATEMENT_LIST)
+                   {
+                     tree_stmt_iterator i = tsi_start (init);
+                     /* Move lambda DECL_EXPRs to FOR_BLOCK.  */
+                     while (!tsi_end_p (i))
+                       {
+                         tree t = tsi_stmt (i);
+                         if (TREE_CODE (t) == DECL_EXPR
+                             && TREE_CODE (DECL_EXPR_DECL (t)) == TYPE_DECL)
+                           {
+                             tsi_delink (&i);
+                             vec_safe_push (for_block, t);
+                             continue;
+                           }
+                         break;
+                       }
+                     if (tsi_one_before_end_p (i))
+                       {
+                         tree t = tsi_stmt (i);
+                         tsi_delink (&i);
+                         free_stmt_list (init);
+                         init = t;
+                       }
+                   }
+               }
              this_pre_body = NULL_TREE;
            }
          else
@@ -33899,7 +33926,13 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
     }
 
   while (!for_block->is_empty ())
-    add_stmt (pop_stmt_list (for_block->pop ()));
+    {
+      tree t = for_block->pop ();
+      if (TREE_CODE (t) == STATEMENT_LIST)
+       add_stmt (pop_stmt_list (t));
+      else
+       add_stmt (t);
+    }
   release_tree_vector (for_block);
 
   return ret;
index 70e765e..ae5f28f 100644 (file)
@@ -1,3 +1,8 @@
+2016-08-08  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/58706
+       * testsuite/libgomp.c++/pr58706.C: New test.
+
 2016-08-04  Thomas Schwinge  <thomas@codesourcery.com>
 
        * testsuite/libgomp.oacc-c++/routine-1-auto.C: New file.
diff --git a/libgomp/testsuite/libgomp.c++/pr58706.C b/libgomp/testsuite/libgomp.c++/pr58706.C
new file mode 100644 (file)
index 0000000..3d8ea89
--- /dev/null
@@ -0,0 +1,47 @@
+// PR c++/58706
+// { dg-do run }
+// { dg-options "-std=c++11" }
+
+template <typename T>
+T
+foo ()
+{
+  T n = T ();
+#pragma omp parallel for reduction (+: n)
+  for (T i = [](){ return 3; }(); i < 10; ++i)
+    n++;
+  return n;
+}
+
+template <typename T>
+T
+bar ()
+{
+  T n = T ();
+#pragma omp parallel for reduction (+: n)
+  for (T i = [](){ return 1; }() + [](){ return 4; }(); i < 10; ++i)
+    n++;
+  return n;
+}
+
+template <typename T>
+T
+baz ()
+{
+  T n = T ();
+#pragma omp parallel for reduction (+: n)
+  for (T i = T (); i < [](){ return 7; }() + [](){ return 11; }(); i += [](){ return 3; }() - [](){ return 1; }())
+    n++;
+  return n;
+}
+
+int
+main ()
+{
+  if (foo <int> () != 7 || foo <long long> () != 7)
+    __builtin_abort ();
+  if (bar <int> () != 5 || bar <char> () != 5)
+    __builtin_abort ();
+  if (baz <int> () != 9 || baz <long long> () != 9)
+    __builtin_abort ();
+}