118 lines
3.3 KiB
Diff
118 lines
3.3 KiB
Diff
|
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.
|
|||
|
|
|||
|
PR c++/37189
|
|||
|
* g++.dg/gomp/pr37189.C: New test.
|
|||
|
|
|||
|
--- gcc/cp/decl2.c (revision 139954)
|
|||
|
+++ gcc/cp/decl2.c (revision 139955)
|
|||
|
@@ -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
|
|||
|
--- gcc/cp/decl.c (revision 139954)
|
|||
|
+++ gcc/cp/decl.c (revision 139955)
|
|||
|
@@ -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;
|
|||
|
}
|
|||
|
|
|||
|
--- gcc/cp/cp-tree.h (revision 139954)
|
|||
|
+++ gcc/cp/cp-tree.h (revision 139955)
|
|||
|
@@ -4381,6 +4381,9 @@ extern void initialize_artificial_var (
|
|||
|
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);
|
|||
|
--- gcc/testsuite/g++.dg/gomp/pr37189.C (revision 0)
|
|||
|
+++ gcc/testsuite/g++.dg/gomp/pr37189.C (revision 139955)
|
|||
|
@@ -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);
|
|||
|
+}
|