diff options
author | Jason Merrill <jason@redhat.com> | 2012-06-12 14:32:04 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2012-06-12 14:32:04 -0400 |
commit | fdaf2f48c02dcb5dcf9bbca130b2de56fc947f75 (patch) | |
tree | 80e3be6314fbf654191d8c01e090f396c9f34812 /gcc | |
parent | 0089c3bb1eb0c8bb8d0f8d0d91dd29f1ed760893 (diff) | |
download | gcc-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/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/name-lookup.c | 11 | ||||
-rw-r--r-- | gcc/cp/pt.c | 15 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 11 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/local7.C | 15 |
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> (); |