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/decl.c | |
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/decl.c')
-rw-r--r-- | gcc/cp/decl.c | 19 |
1 files changed, 19 insertions, 0 deletions
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; } |