From a2d4cdc96a585c0b863226b2f142445538674127 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek <jakub@redhat.com> Date: Mon, 1 Dec 2008 16:27:12 +0100 Subject: [PATCH] re PR c++/38257 (ICE with auto and #pragma omp parallel) 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. From-SVN: r142320 --- gcc/cp/ChangeLog | 6 ++ gcc/cp/parser.c | 20 ++++- gcc/cp/pt.c | 15 +++- libgomp/ChangeLog | 3 + libgomp/testsuite/libgomp.c++/for-7.C | 110 ++++++++++++++++++++++++++ 5 files changed, 150 insertions(+), 4 deletions(-) create mode 100644 libgomp/testsuite/libgomp.c++/for-7.C 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 (); +}