diff options
author | Jason Merrill <jason@redhat.com> | 2011-10-13 17:23:36 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2011-10-13 17:23:36 -0400 |
commit | 0e81aa85294d479dea3fb9b5a71e6f7242770af6 (patch) | |
tree | 0b3894e6a191ea60c4236c20d9491127731db082 | |
parent | f1c141a7da0daee15591401fa0a24cf71cc4734c (diff) | |
download | gcc-0e81aa85294d479dea3fb9b5a71e6f7242770af6.zip gcc-0e81aa85294d479dea3fb9b5a71e6f7242770af6.tar.gz gcc-0e81aa85294d479dea3fb9b5a71e6f7242770af6.tar.bz2 |
re PR c++/50437 ([C++0x] [4.7 regression] ICE for trivial use of lambda in template function)
PR c++/50437
* cp-tree.h (struct tree_lambda_expr): Add closure field.
(LAMBDA_EXPR_CLOSURE): New.
* pt.c (tsubst_copy_and_build) [LAMBDA_EXPR]: Likewise.
* semantics.c (build_lambda_object): Use it instead of TREE_TYPE.
(begin_lambda_type, lambda_function, add_capture): Likewise.
(add_default_capture, lambda_expr_this_capture): Likewise.
From-SVN: r179944
-rw-r--r-- | gcc/cp/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 7 | ||||
-rw-r--r-- | gcc/cp/pt.c | 4 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 20 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/lambda/lambda-auto1.C | 14 |
6 files changed, 47 insertions, 11 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 039b155..0322103 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2011-10-13 Jason Merrill <jason@redhat.com> + + PR c++/50437 + * cp-tree.h (struct tree_lambda_expr): Add closure field. + (LAMBDA_EXPR_CLOSURE): New. + * pt.c (tsubst_copy_and_build) [LAMBDA_EXPR]: Likewise. + * semantics.c (build_lambda_object): Use it instead of TREE_TYPE. + (begin_lambda_type, lambda_function, add_capture): Likewise. + (add_default_capture, lambda_expr_this_capture): Likewise. + 2011-10-13 Diego Novillo <dnovillo@google.com> * cp-tree.h (struct language_function): Rename in_function_try_handler diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 1b896b8..bae6071 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -671,6 +671,12 @@ enum cp_lambda_default_capture_mode_type { #define LAMBDA_EXPR_PENDING_PROXIES(NODE) \ (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->pending_proxies) +/* The closure type of the lambda. Note that the TREE_TYPE of a + LAMBDA_EXPR is always NULL_TREE, because we need to instantiate the + LAMBDA_EXPR in order to instantiate the type. */ +#define LAMBDA_EXPR_CLOSURE(NODE) \ + (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->closure) + struct GTY (()) tree_lambda_expr { struct tree_typed typed; @@ -678,6 +684,7 @@ struct GTY (()) tree_lambda_expr tree this_capture; tree return_type; tree extra_scope; + tree closure; VEC(tree,gc)* pending_proxies; location_t locus; enum cp_lambda_default_capture_mode_type default_capture_mode; diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index bfbd244..880f3d1 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -13937,8 +13937,8 @@ tsubst_copy_and_build (tree t, { tree r = build_lambda_expr (); - tree type = tsubst (TREE_TYPE (t), args, complain, NULL_TREE); - TREE_TYPE (r) = type; + tree type = tsubst (LAMBDA_EXPR_CLOSURE (t), args, complain, NULL_TREE); + LAMBDA_EXPR_CLOSURE (r) = type; CLASSTYPE_LAMBDA_EXPR (type) = r; LAMBDA_EXPR_LOCATION (r) diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index eed38e6..7d37fa3 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -8324,7 +8324,7 @@ build_lambda_object (tree lambda_expr) /* N2927: "[The closure] class type is not an aggregate." But we briefly treat it as an aggregate to make this simpler. */ - type = TREE_TYPE (lambda_expr); + type = LAMBDA_EXPR_CLOSURE (lambda_expr); CLASSTYPE_NON_AGGREGATE (type) = 0; expr = finish_compound_literal (type, expr, tf_warning_or_error); CLASSTYPE_NON_AGGREGATE (type) = 1; @@ -8365,7 +8365,7 @@ begin_lambda_type (tree lambda) type = begin_class_definition (type, /*attributes=*/NULL_TREE); /* Cross-reference the expression and the type. */ - TREE_TYPE (lambda) = type; + LAMBDA_EXPR_CLOSURE (lambda) = type; CLASSTYPE_LAMBDA_EXPR (type) = lambda; return type; @@ -8399,7 +8399,7 @@ lambda_function (tree lambda) { tree type; if (TREE_CODE (lambda) == LAMBDA_EXPR) - type = TREE_TYPE (lambda); + type = LAMBDA_EXPR_CLOSURE (lambda); else type = lambda; gcc_assert (LAMBDA_TYPE_P (type)); @@ -8714,7 +8714,7 @@ add_capture (tree lambda, tree id, tree initializer, bool by_reference_p, /* If TREE_TYPE isn't set, we're still in the introducer, so check for duplicates. */ - if (!TREE_TYPE (lambda)) + if (!LAMBDA_EXPR_CLOSURE (lambda)) { if (IDENTIFIER_MARKED (name)) { @@ -8740,13 +8740,14 @@ add_capture (tree lambda, tree id, tree initializer, bool by_reference_p, LAMBDA_EXPR_THIS_CAPTURE (lambda) = member; /* Add it to the appropriate closure class if we've started it. */ - if (current_class_type && current_class_type == TREE_TYPE (lambda)) + if (current_class_type + && current_class_type == LAMBDA_EXPR_CLOSURE (lambda)) finish_member_declaration (member); LAMBDA_EXPR_CAPTURE_LIST (lambda) = tree_cons (member, initializer, LAMBDA_EXPR_CAPTURE_LIST (lambda)); - if (TREE_TYPE (lambda)) + if (LAMBDA_EXPR_CLOSURE (lambda)) return build_capture_proxy (member); /* For explicit captures we haven't started the function yet, so we wait and build the proxy from cp_parser_lambda_body. */ @@ -8789,7 +8790,7 @@ add_default_capture (tree lambda_stack, tree id, tree initializer) { tree lambda = TREE_VALUE (node); - current_class_type = TREE_TYPE (lambda); + current_class_type = LAMBDA_EXPR_CLOSURE (lambda); var = add_capture (lambda, id, initializer, @@ -8820,7 +8821,7 @@ lambda_expr_this_capture (tree lambda) if (!this_capture && LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda) != CPLD_NONE) { - tree containing_function = TYPE_CONTEXT (TREE_TYPE (lambda)); + tree containing_function = TYPE_CONTEXT (LAMBDA_EXPR_CLOSURE (lambda)); tree lambda_stack = tree_cons (NULL_TREE, lambda, NULL_TREE); tree init = NULL_TREE; @@ -8870,7 +8871,8 @@ lambda_expr_this_capture (tree lambda) else { /* To make sure that current_class_ref is for the lambda. */ - gcc_assert (TYPE_MAIN_VARIANT (TREE_TYPE (current_class_ref)) == TREE_TYPE (lambda)); + gcc_assert (TYPE_MAIN_VARIANT (TREE_TYPE (current_class_ref)) + == LAMBDA_EXPR_CLOSURE (lambda)); result = this_capture; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 283b699..3c15036 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2011-10-13 Jason Merrill <jason@redhat.com> + PR c++/50437 + * g++.dg/cpp0x/lambda/lambda-auto1.C: New. + PR c++/50618 * g++.dg/init/vbase1.C: New. diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-auto1.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-auto1.C new file mode 100644 index 0000000..b5ba066 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-auto1.C @@ -0,0 +1,14 @@ +// PR c++/50437 +// { dg-options -std=c++0x } + +template <typename T> +void f() +{ + auto g = [](T t){ return t == 0; }; + g(T()); +} + +int main() +{ + f<int>(); +} |