aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2012-06-12 14:32:04 -0400
committerJason Merrill <jason@gcc.gnu.org>2012-06-12 14:32:04 -0400
commitfdaf2f48c02dcb5dcf9bbca130b2de56fc947f75 (patch)
tree80e3be6314fbf654191d8c01e090f396c9f34812 /gcc
parent0089c3bb1eb0c8bb8d0f8d0d91dd29f1ed760893 (diff)
downloadgcc-fdaf2f48c02dcb5dcf9bbca130b2de56fc947f75.zip
gcc-fdaf2f48c02dcb5dcf9bbca130b2de56fc947f75.tar.gz
gcc-fdaf2f48c02dcb5dcf9bbca130b2de56fc947f75.tar.bz2
re PR c++/53599 (gcc-4.7.1_rc20120606 segfaults compiling boost.karma)
PR c++/53599 * name-lookup.c (pushtag_1): Add a DECL_EXPR for a local class. * semantics.c (finish_cond): Build a COMPOUND_EXPR. * pt.c (tsubst_expr) [COMPOUND_EXPR]: Handle. [DECL_EXPR]: Don't call cp_finish_decl for an implicit typedef. Don't return the decl. From-SVN: r188473
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/name-lookup.c11
-rw-r--r--gcc/cp/pt.c15
-rw-r--r--gcc/cp/semantics.c11
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/template/local7.C15
6 files changed, 58 insertions, 8 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 29c721f..203955e 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,12 @@
+2012-06-09 Jason Merrill <jason@redhat.com>
+
+ PR c++/53599
+ * name-lookup.c (pushtag_1): Add a DECL_EXPR for a local class.
+ * semantics.c (finish_cond): Build a COMPOUND_EXPR.
+ * pt.c (tsubst_expr) [COMPOUND_EXPR]: Handle.
+ [DECL_EXPR]: Don't call cp_finish_decl for an implicit typedef.
+ Don't return the decl.
+
2012-06-11 Richard Guenther <rguenther@suse.de>
PR c++/53605
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 9cc6d39..0f28820 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -5796,7 +5796,16 @@ pushtag_1 (tree name, tree type, tag_scope scope)
class.) */
if (TYPE_CONTEXT (type)
&& TREE_CODE (TYPE_CONTEXT (type)) == FUNCTION_DECL)
- VEC_safe_push (tree, gc, local_classes, type);
+ {
+ if (processing_template_decl)
+ {
+ /* Push a DECL_EXPR so we call pushtag at the right time in
+ template instantiation rather than in some nested context. */
+ add_decl_expr (decl);
+ }
+ else
+ VEC_safe_push (tree, gc, local_classes, type);
+ }
}
if (b->kind == sk_class
&& !COMPLETE_TYPE_P (current_class_type))
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index df80159..04f7be8 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -12887,6 +12887,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
DECL_CONTEXT (decl) = current_function_decl;
insert_capture_proxy (decl);
}
+ else if (DECL_IMPLICIT_TYPEDEF_P (t))
+ /* We already did a pushtag. */;
else
{
int const_init = false;
@@ -12930,9 +12932,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
}
}
- /* A DECL_EXPR can also be used as an expression, in the condition
- clause of an if/for/while construct. */
- return decl;
+ break;
}
case FOR_STMT:
@@ -13341,6 +13341,15 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
error ("use %<...%> to expand argument pack");
return error_mark_node;
+ case COMPOUND_EXPR:
+ tmp = RECUR (TREE_OPERAND (t, 0));
+ if (tmp == NULL_TREE)
+ /* If the first operand was a statement, we're done with it. */
+ return RECUR (TREE_OPERAND (t, 1));
+ return build_x_compound_expr (EXPR_LOCATION (t), tmp,
+ RECUR (TREE_OPERAND (t, 1)),
+ complain);
+
default:
gcc_assert (!STATEMENT_CODE_P (TREE_CODE (t)));
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 7769bba..f8ad2a5 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -509,11 +509,14 @@ finish_cond (tree *cond_p, tree expr)
if (processing_template_decl)
{
tree cond = pop_stmt_list (*cond_p);
- if (TREE_CODE (cond) == DECL_EXPR)
- expr = cond;
- if (check_for_bare_parameter_packs (expr))
- *cond_p = error_mark_node;
+ if (expr == NULL_TREE)
+ /* Empty condition in 'for'. */
+ gcc_assert (empty_expr_stmt_p (cond));
+ else if (check_for_bare_parameter_packs (expr))
+ expr = error_mark_node;
+ else if (!empty_expr_stmt_p (cond))
+ expr = build2 (COMPOUND_EXPR, TREE_TYPE (expr), cond, expr);
}
*cond_p = expr;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 953ccb9..908e25b 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2012-06-07 Jason Merrill <jason@redhat.com>
+
+ PR c++/53599
+ * g++.dg/template/local7.C: New.
+
2012-06-12 Oleg Endo <olegendo@gcc.gnu.org>
PR target/53511
diff --git a/gcc/testsuite/g++.dg/template/local7.C b/gcc/testsuite/g++.dg/template/local7.C
new file mode 100644
index 0000000..3045534
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/local7.C
@@ -0,0 +1,15 @@
+// PR c++/53599
+
+template <typename T>
+int foo ()
+{
+ struct F;
+ struct G
+ {
+ static int F::* bar();
+ };
+
+ return sizeof(G);
+}
+
+int z = foo <int> ();