diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-09-03 20:33:21 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-09-03 20:33:21 +0000 |
commit | 038849b39b8a27687b192bbfca220b01c3945591 (patch) | |
tree | 2662e64fc943bf103ce1cf286233d3c13eb6a6c8 /gcc/cp | |
parent | 4cf52be57abd745a846e6d724e0763f9617f816d (diff) |
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
Diffstat (limited to 'gcc/cp')
-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 |
4 files changed, 43 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 88b394673ab..442dd8e60e9 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 a668aa092fb..ca069b765cf 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 0f7b5d7fa70..fbd16e5b19c 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 4f19766462d..a128fb7c5e2 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 |