diff options
author | Jakub Jelinek <jakub@redhat.com> | 2008-09-03 22:33:21 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2008-09-03 22:33:21 +0200 |
commit | 3368cdd3f5f242e4ffe9147802591f5d9b5c40ec (patch) | |
tree | 2662e64fc943bf103ce1cf286233d3c13eb6a6c8 | |
parent | 8660d962235b733aacb2c63c6cc11785317d847e (diff) | |
download | gcc-3368cdd3f5f242e4ffe9147802591f5d9b5c40ec.zip gcc-3368cdd3f5f242e4ffe9147802591f5d9b5c40ec.tar.gz gcc-3368cdd3f5f242e4ffe9147802591f5d9b5c40ec.tar.bz2 |
re PR c++/37189 (OpenMP task construct with implicit firstprivate variables ICEs)
PR c++/37189
* cp-tree.h (defer_mark_used_calls, deferred_mark_used_calls): New
extern decls.
* decl2.c (mark_used): If defer_mark_used_calls, push decl into
deferred_mark_used_calls vector and exit early.
* decl.c (defer_mark_used_calls, deferred_mark_used_calls): New
variables.
(finish_function): Set defer_mark_used_calls for the duration of the
function. Call mark_used on any queued decls.
* g++.dg/gomp/pr37189.C: New test.
From-SVN: r139955
-rw-r--r-- | gcc/cp/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 3 | ||||
-rw-r--r-- | gcc/cp/decl.c | 19 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 9 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/gomp/pr37189.C | 27 |
6 files changed, 73 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 88b3946..442dd8e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,15 @@ +2008-09-03 Jakub Jelinek <jakub@redhat.com> + + PR c++/37189 + * cp-tree.h (defer_mark_used_calls, deferred_mark_used_calls): New + extern decls. + * decl2.c (mark_used): If defer_mark_used_calls, push decl into + deferred_mark_used_calls vector and exit early. + * decl.c (defer_mark_used_calls, deferred_mark_used_calls): New + variables. + (finish_function): Set defer_mark_used_calls for the duration of the + function. Call mark_used on any queued decls. + 2008-09-02 Jason Merrill <jason@redhat.com> PR c++/37208 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index a668aa0..ca069b7 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4381,6 +4381,9 @@ extern void initialize_artificial_var (tree, tree); extern tree check_var_type (tree, tree); extern tree reshape_init (tree, tree); +extern bool defer_mark_used_calls; +extern GTY(()) VEC(tree, gc) *deferred_mark_used_calls; + /* in decl2.c */ extern bool check_java_method (tree); extern tree build_memfn_type (tree, tree, cp_cv_quals); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 0f7b5d7..fbd16e5 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -227,6 +227,11 @@ struct named_label_entry GTY(()) function, two inside the body of a function in a local class, etc.) */ int function_depth; +/* To avoid unwanted recursion, finish_function defers all mark_used calls + encountered during its execution until it finishes. */ +bool defer_mark_used_calls; +VEC(tree, gc) *deferred_mark_used_calls; + /* States indicating how grokdeclarator() should handle declspecs marked with __attribute__((deprecated)). An object declared as __attribute__((deprecated)) suppresses warnings of uses of other @@ -12033,6 +12038,9 @@ finish_function (int flags) if (fndecl == NULL_TREE) return error_mark_node; + gcc_assert (!defer_mark_used_calls); + defer_mark_used_calls = true; + if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fndecl) && DECL_VIRTUAL_P (fndecl) && !processing_template_decl) @@ -12232,6 +12240,17 @@ finish_function (int flags) cxx_pop_function_context and then reset via pop_function_context. */ current_function_decl = NULL_TREE; + defer_mark_used_calls = false; + if (deferred_mark_used_calls) + { + unsigned int i; + tree decl; + + for (i = 0; VEC_iterate (tree, deferred_mark_used_calls, i, decl); i++) + mark_used (decl); + VEC_free (tree, gc, deferred_mark_used_calls); + } + return fndecl; } diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 4f19766..a128fb7 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -3776,6 +3776,15 @@ mark_used (tree decl) /* If we don't need a value, then we don't need to synthesize DECL. */ if (skip_evaluation) return; + + /* If within finish_function, defer the rest until that function + finishes, otherwise it might recurse. */ + if (defer_mark_used_calls) + { + VEC_safe_push (tree, gc, deferred_mark_used_calls, decl); + return; + } + /* Normally, we can wait until instantiation-time to synthesize DECL. However, if DECL is a static data member initialized with a constant, we need the value right now because a reference to diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7fe9ef6..bfadce1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2008-09-03 Jakub Jelinek <jakub@redhat.com> + PR c++/37189 + * g++.dg/gomp/pr37189.C: New test. + PR debug/37322 * gfortran.dg/debug/pr35154-dwarf2.f: Fix up scan-assembler regexps. diff --git a/gcc/testsuite/g++.dg/gomp/pr37189.C b/gcc/testsuite/g++.dg/gomp/pr37189.C new file mode 100644 index 0000000..31d95f2 --- /dev/null +++ b/gcc/testsuite/g++.dg/gomp/pr37189.C @@ -0,0 +1,27 @@ +// PR c++/37189 +// { dg-do compile } +// { dg-options "-fopenmp" } + +struct S +{ + S () {} + S (S const &) {} +}; + +struct T +{ + S s; +}; + +void +bar (T &) +{ +} + +int +foo () +{ + T t; + #pragma omp task + bar (t); +} |