diff options
author | Jason Merrill <jason@redhat.com> | 2011-08-23 12:03:15 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2011-08-23 12:03:15 -0400 |
commit | 9b8662c2b04820f6024648ff863b83dbbf07844f (patch) | |
tree | 095408f307618afaaf5d92253bb0546486159200 /gcc/cp | |
parent | 2787914706395bf7864bdc76491ada1b0a552cae (diff) | |
download | gcc-9b8662c2b04820f6024648ff863b83dbbf07844f.zip gcc-9b8662c2b04820f6024648ff863b83dbbf07844f.tar.gz gcc-9b8662c2b04820f6024648ff863b83dbbf07844f.tar.bz2 |
Core 975
Core 975
* decl.c (cxx_init_decl_processing): Initialize
dependent_lambda_return_type_node.
* cp-tree.h (cp_tree_index): Add CPTI_DEPENDENT_LAMBDA_RETURN_TYPE.
(dependent_lambda_return_type_node): Define.
(DECLTYPE_FOR_LAMBDA_RETURN): Remove.
* semantics.c (lambda_return_type): Handle overloaded function.
Use dependent_lambda_return_type_node instead of
DECLTYPE_FOR_LAMBDA_RETURN.
(apply_lambda_return_type): Don't check dependent_type_p.
* pt.c (tsubst_copy_and_build): Handle lambda return type deduction.
(instantiate_class_template_1): Likewise.
(tsubst): Don't use DECLTYPE_FOR_LAMBDA_RETURN.
* mangle.c (write_type): Likewise.
* typeck.c (structural_comptypes): Likewise.
(check_return_expr): Handle dependent_lambda_return_type_node.
From-SVN: r177995
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 19 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 9 | ||||
-rw-r--r-- | gcc/cp/decl.c | 4 | ||||
-rw-r--r-- | gcc/cp/mangle.c | 2 | ||||
-rw-r--r-- | gcc/cp/pt.c | 31 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 19 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 21 |
7 files changed, 68 insertions, 37 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 0f60bcb..0f325a8 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,24 @@ 2011-08-23 Jason Merrill <jason@redhat.com> + Core 975 + * decl.c (cxx_init_decl_processing): Initialize + dependent_lambda_return_type_node. + * cp-tree.h (cp_tree_index): Add CPTI_DEPENDENT_LAMBDA_RETURN_TYPE. + (dependent_lambda_return_type_node): Define. + (DECLTYPE_FOR_LAMBDA_RETURN): Remove. + * semantics.c (lambda_return_type): Handle overloaded function. + Use dependent_lambda_return_type_node instead of + DECLTYPE_FOR_LAMBDA_RETURN. + (apply_lambda_return_type): Don't check dependent_type_p. + * pt.c (tsubst_copy_and_build): Handle lambda return type deduction. + (instantiate_class_template_1): Likewise. + (tsubst): Don't use DECLTYPE_FOR_LAMBDA_RETURN. + * mangle.c (write_type): Likewise. + * typeck.c (structural_comptypes): Likewise. + (check_return_expr): Handle dependent_lambda_return_type_node. + +2011-08-23 Jason Merrill <jason@redhat.com> + PR c++/50024 * semantics.c (maybe_constant_value): Don't try to fold { }. * pt.c (build_non_dependent_expr): Don't wrap { }. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index ff5509e..8595943 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -83,7 +83,6 @@ c-common.h, not after. STMT_IS_FULL_EXPR_P (in _STMT) TARGET_EXPR_LIST_INIT_P (in TARGET_EXPR) LAMBDA_EXPR_MUTABLE_P (in LAMBDA_EXPR) - DECLTYPE_FOR_LAMBDA_RETURN (in DECLTYPE_TYPE) DECL_FINAL_P (in FUNCTION_DECL) QUALIFIED_NAME_IS_TEMPLATE (in SCOPE_REF) 2: IDENTIFIER_OPNAME_P (in IDENTIFIER_NODE) @@ -775,6 +774,7 @@ enum cp_tree_index CPTI_CLASS_TYPE, CPTI_UNKNOWN_TYPE, CPTI_INIT_LIST_TYPE, + CPTI_DEPENDENT_LAMBDA_RETURN_TYPE, CPTI_VTBL_TYPE, CPTI_VTBL_PTR_TYPE, CPTI_STD, @@ -846,6 +846,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX]; #define class_type_node cp_global_trees[CPTI_CLASS_TYPE] #define unknown_type_node cp_global_trees[CPTI_UNKNOWN_TYPE] #define init_list_type_node cp_global_trees[CPTI_INIT_LIST_TYPE] +#define dependent_lambda_return_type_node cp_global_trees[CPTI_DEPENDENT_LAMBDA_RETURN_TYPE] #define vtbl_type_node cp_global_trees[CPTI_VTBL_TYPE] #define vtbl_ptr_type_node cp_global_trees[CPTI_VTBL_PTR_TYPE] #define std_node cp_global_trees[CPTI_STD] @@ -3425,12 +3426,10 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter) (DECLTYPE_TYPE_CHECK (NODE))->type_common.string_flag /* These flags indicate that we want different semantics from normal - decltype: lambda capture just drops references, lambda return also does - type decay, lambda proxies look through implicit dereference. */ + decltype: lambda capture just drops references, lambda proxies look + through implicit dereference. */ #define DECLTYPE_FOR_LAMBDA_CAPTURE(NODE) \ TREE_LANG_FLAG_0 (DECLTYPE_TYPE_CHECK (NODE)) -#define DECLTYPE_FOR_LAMBDA_RETURN(NODE) \ - TREE_LANG_FLAG_1 (DECLTYPE_TYPE_CHECK (NODE)) #define DECLTYPE_FOR_LAMBDA_PROXY(NODE) \ TREE_LANG_FLAG_2 (DECLTYPE_TYPE_CHECK (NODE)) diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index c125f05..c375cf7 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -3597,6 +3597,10 @@ cxx_init_decl_processing (void) init_list_type_node = make_node (LANG_TYPE); record_unknown_type (init_list_type_node, "init list"); + dependent_lambda_return_type_node = make_node (LANG_TYPE); + record_unknown_type (dependent_lambda_return_type_node, + "undeduced lambda return type"); + { /* Make sure we get a unique function type, so we can give its pointer type a name. (This wins for gdb.) */ diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index 53d4bc6..4c7cc79 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -1953,7 +1953,7 @@ write_type (tree type) case DECLTYPE_TYPE: /* These shouldn't make it into mangling. */ gcc_assert (!DECLTYPE_FOR_LAMBDA_CAPTURE (type) - && !DECLTYPE_FOR_LAMBDA_RETURN (type)); + && !DECLTYPE_FOR_LAMBDA_PROXY (type)); /* In ABI <5, we stripped decltype of a plain decl. */ if (!abi_version_at_least (5) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 3f9a4c0..6b970f9 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -8887,7 +8887,16 @@ instantiate_class_template_1 (tree type) } if (CLASSTYPE_LAMBDA_EXPR (type)) - maybe_add_lambda_conv_op (type); + { + tree lambda = CLASSTYPE_LAMBDA_EXPR (type); + if (LAMBDA_EXPR_DEDUCE_RETURN_TYPE_P (lambda)) + { + apply_lambda_return_type (lambda, void_type_node); + LAMBDA_EXPR_RETURN_TYPE (lambda) = NULL_TREE; + } + instantiate_decl (lambda_function (type), false, false); + maybe_add_lambda_conv_op (type); + } /* Set the file and line number information to whatever is given for the class itself. This puts error messages involving generated @@ -11420,8 +11429,6 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) if (DECLTYPE_FOR_LAMBDA_CAPTURE (t)) type = lambda_capture_field_type (type); - else if (DECLTYPE_FOR_LAMBDA_RETURN (t)) - type = lambda_return_type (type); else if (DECLTYPE_FOR_LAMBDA_PROXY (t)) type = lambda_proxy_type (type); else @@ -13882,10 +13889,17 @@ tsubst_copy_and_build (tree t, LAMBDA_EXPR_MUTABLE_P (r) = LAMBDA_EXPR_MUTABLE_P (t); LAMBDA_EXPR_DISCRIMINATOR (r) = (LAMBDA_EXPR_DISCRIMINATOR (t)); - LAMBDA_EXPR_CAPTURE_LIST (r) - = RECUR (LAMBDA_EXPR_CAPTURE_LIST (t)); LAMBDA_EXPR_EXTRA_SCOPE (r) = RECUR (LAMBDA_EXPR_EXTRA_SCOPE (t)); + if (LAMBDA_EXPR_RETURN_TYPE (t) == dependent_lambda_return_type_node) + { + LAMBDA_EXPR_RETURN_TYPE (r) = dependent_lambda_return_type_node; + LAMBDA_EXPR_DEDUCE_RETURN_TYPE_P (r) = true; + } + else + LAMBDA_EXPR_RETURN_TYPE (r) + = tsubst (LAMBDA_EXPR_RETURN_TYPE (t), args, complain, in_decl); + gcc_assert (LAMBDA_EXPR_THIS_CAPTURE (t) == NULL_TREE && LAMBDA_EXPR_PENDING_PROXIES (t) == NULL); @@ -13895,9 +13909,10 @@ tsubst_copy_and_build (tree t, declaration of the op() for later calls to lambda_function. */ complete_type (type); - type = tsubst (LAMBDA_EXPR_RETURN_TYPE (t), args, complain, in_decl); - if (type) - apply_lambda_return_type (r, type); + /* The capture list refers to closure members, so this needs to + wait until after we finish instantiating the type. */ + LAMBDA_EXPR_CAPTURE_LIST (r) + = RECUR (LAMBDA_EXPR_CAPTURE_LIST (t)); return build_lambda_object (r); } diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 2f62e35..5deb2eb 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -8323,18 +8323,14 @@ tree lambda_return_type (tree expr) { tree type; - if (BRACE_ENCLOSED_INITIALIZER_P (expr)) + if (type_unknown_p (expr) + || BRACE_ENCLOSED_INITIALIZER_P (expr)) { - warning (0, "cannot deduce lambda return type from a braced-init-list"); + cxx_incomplete_type_error (expr, TREE_TYPE (expr)); return void_type_node; } if (type_dependent_expression_p (expr)) - { - type = cxx_make_type (DECLTYPE_TYPE); - DECLTYPE_TYPE_EXPR (type) = expr; - DECLTYPE_FOR_LAMBDA_RETURN (type) = true; - SET_TYPE_STRUCTURAL_EQUALITY (type); - } + type = dependent_lambda_return_type_node; else type = cv_unqualified (type_decays_to (unlowered_expr_type (expr))); return type; @@ -8394,12 +8390,10 @@ apply_lambda_return_type (tree lambda, tree return_type) LAMBDA_EXPR_RETURN_TYPE (lambda) = return_type; - /* If we got a DECLTYPE_TYPE, don't stick it in the function yet, - it would interfere with instantiating the closure type. */ - if (dependent_type_p (return_type)) - return; if (return_type == error_mark_node) return; + if (TREE_TYPE (TREE_TYPE (fco)) == return_type) + return; /* TREE_TYPE (FUNCTION_DECL) == METHOD_TYPE TREE_TYPE (METHOD_TYPE) == return-type */ @@ -8412,6 +8406,7 @@ apply_lambda_return_type (tree lambda, tree return_type) /* We already have a DECL_RESULT from start_preparsed_function. Now we need to redo the work it and allocate_struct_function did to reflect the new type. */ + gcc_assert (current_function_decl == fco); result = build_decl (input_location, RESULT_DECL, NULL_TREE, TYPE_MAIN_VARIANT (return_type)); DECL_ARTIFICIAL (result) = 1; diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 4c130ee..9db0ce3 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -1331,8 +1331,8 @@ structural_comptypes (tree t1, tree t2, int strict) != DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t2) || (DECLTYPE_FOR_LAMBDA_CAPTURE (t1) != DECLTYPE_FOR_LAMBDA_CAPTURE (t2)) - || (DECLTYPE_FOR_LAMBDA_RETURN (t1) - != DECLTYPE_FOR_LAMBDA_RETURN (t2)) + || (DECLTYPE_FOR_LAMBDA_PROXY (t1) + != DECLTYPE_FOR_LAMBDA_PROXY (t2)) || !cp_tree_equal (DECLTYPE_TYPE_EXPR (t1), DECLTYPE_TYPE_EXPR (t2))) return false; @@ -7657,15 +7657,14 @@ check_return_expr (tree retval, bool *no_warning) tree type = lambda_return_type (retval); tree oldtype = LAMBDA_EXPR_RETURN_TYPE (lambda); - if (VOID_TYPE_P (type)) - { /* Nothing. */ } - else if (oldtype == NULL_TREE) - { - pedwarn (input_location, OPT_pedantic, "lambda return type " - "can only be deduced when the return statement is " - "the only statement in the function body"); - apply_lambda_return_type (lambda, type); - } + if (oldtype == NULL_TREE) + apply_lambda_return_type (lambda, type); + /* If one of the answers is type-dependent, we can't do any + better until instantiation time. */ + else if (oldtype == dependent_lambda_return_type_node) + /* Leave it. */; + else if (type == dependent_lambda_return_type_node) + apply_lambda_return_type (lambda, type); else if (!same_type_p (type, oldtype)) error ("inconsistent types %qT and %qT deduced for " "lambda return type", type, oldtype); |