From 038849b39b8a27687b192bbfca220b01c3945591 Mon Sep 17 00:00:00 2001 From: jakub Date: Wed, 3 Sep 2008 20:33:21 +0000 Subject: [PATCH] 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@139955 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 12 ++++++++++++ gcc/cp/cp-tree.h | 3 +++ gcc/cp/decl.c | 19 +++++++++++++++++++ gcc/cp/decl2.c | 9 +++++++++ gcc/testsuite/ChangeLog | 3 +++ gcc/testsuite/g++.dg/gomp/pr37189.C | 27 +++++++++++++++++++++++++++ 6 files changed, 73 insertions(+) create mode 100644 gcc/testsuite/g++.dg/gomp/pr37189.C 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 + + 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 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 + 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); +} -- 2.7.4