summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2008-12-01 15:27:12 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2008-12-01 15:27:12 +0000
commit304ac2258615e9b7335848ebef1f6a21fd92c474 (patch)
treeecc36046a609da5f002a051ee7dfcc4183fc8c30
parent65785067a216279cc248b8fd5cc6082b830c2039 (diff)
downloadppe42-gcc-304ac2258615e9b7335848ebef1f6a21fd92c474.tar.gz
ppe42-gcc-304ac2258615e9b7335848ebef1f6a21fd92c474.zip
PR c++/38257
* 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
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/parser.c20
-rw-r--r--gcc/cp/pt.c15
-rw-r--r--libgomp/ChangeLog3
-rw-r--r--libgomp/testsuite/libgomp.c++/for-7.C110
5 files changed, 150 insertions, 4 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 1c53d89ffc8..438b3e0d309 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 6870037e151..275a7f3b4d3 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -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
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 241cea6423a..8de27a6a913 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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)))
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index 5576af2049c..89c8a42dd41 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -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
index 00000000000..9d626c028df
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/for-7.C
@@ -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 ();
+}
OpenPOWER on IntegriCloud