aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2008-09-03 22:33:21 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2008-09-03 22:33:21 +0200
commit3368cdd3f5f242e4ffe9147802591f5d9b5c40ec (patch)
tree2662e64fc943bf103ce1cf286233d3c13eb6a6c8
parent8660d962235b733aacb2c63c6cc11785317d847e (diff)
downloadgcc-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/ChangeLog12
-rw-r--r--gcc/cp/cp-tree.h3
-rw-r--r--gcc/cp/decl.c19
-rw-r--r--gcc/cp/decl2.c9
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/g++.dg/gomp/pr37189.C27
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);
+}