PR c++/38257
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 1 Dec 2008 15:27:12 +0000 (15:27 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 1 Dec 2008 15:27:12 +0000 (15:27 +0000)
* parser.c (cp_parser_omp_for_loop): Handle auto.
* pt.c (tsubst_omp_for_iterator): Likewise.

* testsuite/libgomp.c++/for-7.C: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@142320 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/cp/pt.c
libgomp/ChangeLog
libgomp/testsuite/libgomp.c++/for-7.C [new file with mode: 0644]

index 1c53d89..438b3e0 100644 (file)
@@ -1,3 +1,9 @@
+2008-12-01  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/38257
+       * parser.c (cp_parser_omp_for_loop): Handle auto.
+       * pt.c (tsubst_omp_for_iterator): Likewise.
+
 2008-11-28  Jason Merrill  <jason@redhat.com>
 
        PR c++/38233
index 6870037..275a7f3 100644 (file)
@@ -21118,13 +21118,14 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
 
              else 
                {
-                 tree pushed_scope;
+                 tree pushed_scope, auto_node;
 
                  decl = start_decl (declarator, &type_specifiers,
-                                    /*initialized_p=*/false, attributes,
+                                    SD_INITIALIZED, attributes,
                                     /*prefix_attributes=*/NULL_TREE,
                                     &pushed_scope);
 
+                 auto_node = type_uses_auto (TREE_TYPE (decl));
                  if (cp_lexer_next_token_is_not (parser->lexer, CPP_EQ))
                    {
                      if (cp_lexer_next_token_is (parser->lexer, 
@@ -21139,7 +21140,8 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
                      cp_parser_skip_to_end_of_statement (parser);
                    }
                  else if (CLASS_TYPE_P (TREE_TYPE (decl))
-                          || type_dependent_expression_p (decl))
+                          || type_dependent_expression_p (decl)
+                          || auto_node)
                    {
                      bool is_direct_init, is_non_constant_init;
 
@@ -21147,6 +21149,17 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
                                                    &is_direct_init,
                                                    &is_non_constant_init);
 
+                     if (auto_node && !type_dependent_expression_p (init))
+                       {
+                         TREE_TYPE (decl)
+                           = do_auto_deduction (TREE_TYPE (decl), init,
+                                                auto_node);
+
+                         if (!CLASS_TYPE_P (TREE_TYPE (decl))
+                             && !type_dependent_expression_p (decl))
+                           goto non_class;
+                       }
+                     
                      cp_finish_decl (decl, init, !is_non_constant_init,
                                      asm_specification,
                                      LOOKUP_ONLYCONVERTING);
@@ -21166,6 +21179,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
                      cp_lexer_consume_token (parser->lexer);
                      init = cp_parser_assignment_expression (parser, false);
 
+                   non_class:
                      if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
                        init = error_mark_node;
                      else
index 241cea6..8de27a6 100644 (file)
@@ -10324,12 +10324,25 @@ tsubst_omp_for_iterator (tree t, int i, tree declv, tree initv,
 #define RECUR(NODE)                            \
   tsubst_expr ((NODE), args, complain, in_decl,        \
               integral_constant_expression_p)
-  tree decl, init, cond, incr;
+  tree decl, init, cond, incr, auto_node;
 
   init = TREE_VEC_ELT (OMP_FOR_INIT (t), i);
   gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
   decl = RECUR (TREE_OPERAND (init, 0));
   init = TREE_OPERAND (init, 1);
+  auto_node = type_uses_auto (TREE_TYPE (decl));
+  if (auto_node && init)
+    {
+      tree init_expr = init;
+      tree orig_type;
+      if (TREE_CODE (init_expr) == DECL_EXPR)
+       init_expr = DECL_INITIAL (DECL_EXPR_DECL (init_expr));
+      orig_type = TREE_TYPE (init_expr);
+      TREE_TYPE (init_expr) = RECUR (TREE_TYPE (init_expr));
+      TREE_TYPE (decl)
+       = do_auto_deduction (TREE_TYPE (decl), init_expr, auto_node);
+      TREE_TYPE (init_expr) = orig_type;
+    }
   gcc_assert (!type_dependent_expression_p (decl));
 
   if (!CLASS_TYPE_P (TREE_TYPE (decl)))
index 5576af2..89c8a42 100644 (file)
@@ -1,5 +1,8 @@
 2008-12-01  Jakub Jelinek  <jakub@redhat.com>
 
+       PR c++/38257
+       * testsuite/libgomp.c++/for-7.C: New test.
+
        PR c++/38348
        * testsuite/libgomp.c++/for-6.C: New test.
 
diff --git a/libgomp/testsuite/libgomp.c++/for-7.C b/libgomp/testsuite/libgomp.c++/for-7.C
new file mode 100644 (file)
index 0000000..9d626c0
--- /dev/null
@@ -0,0 +1,110 @@
+// PR c++/
+// { dg-do run }
+// { dg-options "-std=c++0x -fopenmp" }
+
+extern "C" void abort ();
+int cnt;
+
+template <typename T>
+void
+f0 (T, int)
+{
+  abort ();
+}
+
+template <>
+void
+f0<int> (int, int type)
+{
+  if (type != 0)
+    abort ();
+#pragma omp atomic
+  cnt++;
+}
+
+template <>
+void
+f0<const char *> (const char *, int type)
+{
+  if (type != 1)
+    abort ();
+#pragma omp atomic
+  cnt++;
+}
+
+template <typename T>
+void
+f1 ()
+{
+#pragma omp parallel for
+  for (auto i = 0; i < 10; i++)
+    f0 (i, 0);
+}
+
+template <typename T>
+void
+f2 ()
+{
+#pragma omp parallel for
+  for (auto i = T (0); i < T (10); i += T (1))
+    f0 (i, 0);
+}
+
+void
+f3 ()
+{
+#pragma omp parallel for
+  for (auto i = 0; i < 10; i++)
+    f0 (i, 0);
+}
+
+const char *p = "abcdefghij";
+
+template <typename T>
+void
+f4 ()
+{
+#pragma omp parallel for
+  for (auto i = p; i < p + 10; i++)
+    f0 (i, 1);
+}
+
+template <typename T>
+void
+f5 ()
+{
+#pragma omp parallel for
+  for (auto i = T (p); i < T (p + 10); i++)
+    f0 (i, 1);
+}
+
+void
+f6 ()
+{
+#pragma omp parallel for
+  for (auto i = p; i < p + 10; i++)
+    f0 (i, 1);
+}
+
+int
+main ()
+{
+  f1<int> ();
+  if (cnt != 10)
+    abort ();
+  f2<int> ();
+  if (cnt != 20)
+    abort ();
+  f3 ();
+  if (cnt != 30)
+    abort ();
+  f4<int> ();
+  if (cnt != 40)
+    abort ();
+  f5<const char *> ();
+  if (cnt != 50)
+    abort ();
+  f6 ();
+  if (cnt != 60)
+    abort ();
+}