diff options
Diffstat (limited to 'gcc/cp/pt.c')
-rw-r--r-- | gcc/cp/pt.c | 120 |
1 files changed, 83 insertions, 37 deletions
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index eb9fc7f94c7..427447913ec 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -4306,6 +4306,13 @@ check_default_tmpl_args (tree decl, tree parms, bool is_primary, local scope. */ return true; + if (TREE_CODE (decl) == TYPE_DECL + && TREE_TYPE (decl) + && LAMBDA_TYPE_P (TREE_TYPE (decl))) + /* A lambda doesn't have an explicit declaration; don't complain + about the parms of the enclosing class. */ + return true; + if (current_class_type && !TYPE_BEING_DEFINED (current_class_type) && DECL_LANG_SPECIFIC (decl) @@ -4674,6 +4681,8 @@ push_template_decl_real (tree decl, bool is_friend) if (!ctx || TREE_CODE (ctx) == FUNCTION_DECL || (CLASS_TYPE_P (ctx) && TYPE_BEING_DEFINED (ctx)) + || (TREE_CODE (decl) == TYPE_DECL + && LAMBDA_TYPE_P (TREE_TYPE (decl))) || (is_friend && !DECL_TEMPLATE_INFO (decl))) { if (DECL_LANG_SPECIFIC (decl) @@ -5044,9 +5053,8 @@ fold_non_dependent_expr_sfinae (tree expr, tsubst_flags_t complain) as two declarations of the same function, for example. */ if (processing_template_decl - && !type_dependent_expression_p (expr) - && potential_constant_expression (expr) - && !value_dependent_expression_p (expr)) + && !instantiation_dependent_expression_p (expr) + && potential_constant_expression (expr)) { HOST_WIDE_INT saved_processing_template_decl; @@ -5554,15 +5562,19 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) qualification conversion. Let's strip everything. */ else if (TREE_CODE (expr) == NOP_EXPR && TYPE_PTROBV_P (type)) { - STRIP_NOPS (expr); - gcc_assert (TREE_CODE (expr) == ADDR_EXPR); - gcc_assert (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE); - /* Skip the ADDR_EXPR only if it is part of the decay for - an array. Otherwise, it is part of the original argument - in the source code. */ - if (TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == ARRAY_TYPE) - expr = TREE_OPERAND (expr, 0); - expr_type = TREE_TYPE (expr); + tree probe = expr; + STRIP_NOPS (probe); + if (TREE_CODE (probe) == ADDR_EXPR + && TREE_CODE (TREE_TYPE (probe)) == POINTER_TYPE) + { + /* Skip the ADDR_EXPR only if it is part of the decay for + an array. Otherwise, it is part of the original argument + in the source code. */ + if (TREE_CODE (TREE_TYPE (TREE_OPERAND (probe, 0))) == ARRAY_TYPE) + probe = TREE_OPERAND (probe, 0); + expr = probe; + expr_type = TREE_TYPE (expr); + } } /* [temp.arg.nontype]/5, bullet 1 @@ -5641,6 +5653,13 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) expr, expr); return NULL_TREE; } + if (POINTER_TYPE_P (expr_type)) + { + error ("%qE is not a valid template argument for %qT" + "because it is not the address of a variable", + expr, type); + return NULL_TREE; + } /* Other values, like integer constants, might be valid non-type arguments of some other type. */ return error_mark_node; @@ -5788,7 +5807,7 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) return NULL_TREE; } - expr = convert_nontype_argument_function (TREE_TYPE (type), expr); + expr = convert_nontype_argument_function (type, expr); if (!expr || expr == error_mark_node) return expr; @@ -8992,12 +9011,26 @@ instantiate_class_template_1 (tree type) } } - if (CLASSTYPE_LAMBDA_EXPR (type)) + if (tree expr = CLASSTYPE_LAMBDA_EXPR (type)) { tree decl = lambda_function (type); if (decl) { instantiate_decl (decl, false, false); + + /* We need to instantiate the capture list from the template + after we've instantiated the closure members, but before we + consider adding the conversion op. Also keep any captures + that may have been added during instantiation of the op(). */ + tree tmpl_expr = CLASSTYPE_LAMBDA_EXPR (pattern); + tree tmpl_cap + = tsubst_copy_and_build (LAMBDA_EXPR_CAPTURE_LIST (tmpl_expr), + args, tf_warning_or_error, NULL_TREE, + false, false); + + LAMBDA_EXPR_CAPTURE_LIST (expr) + = chainon (tmpl_cap, nreverse (LAMBDA_EXPR_CAPTURE_LIST (expr))); + maybe_add_lambda_conv_op (type); } else @@ -10826,6 +10859,9 @@ tsubst_arg_types (tree arg_types, } return error_mark_node; } + /* DR 657. */ + if (abstract_virtuals_error_sfinae (ACU_PARM, type, complain)) + return error_mark_node; /* Do array-to-pointer, function-to-pointer conversion, and ignore top-level qualifiers as required. */ @@ -10888,10 +10924,8 @@ tsubst_function_type (tree t, return_type = tsubst (TREE_TYPE (t), args, complain, in_decl); if (return_type == error_mark_node) return error_mark_node; - /* The standard does not presently indicate that creation of a - function type with an invalid return type is a deduction failure. - However, that is clearly analogous to creating an array of "void" - or a reference to a reference. This is core issue #486. */ + /* DR 486 clarifies that creation of a function type with an + invalid return type is a deduction failure. */ if (TREE_CODE (return_type) == ARRAY_TYPE || TREE_CODE (return_type) == FUNCTION_TYPE) { @@ -10904,6 +10938,9 @@ tsubst_function_type (tree t, } return error_mark_node; } + /* And DR 657. */ + if (abstract_virtuals_error_sfinae (ACU_RETURN, return_type, complain)) + return error_mark_node; /* Substitute the argument types. */ arg_types = tsubst_arg_types (TYPE_ARG_TYPES (t), args, NULL_TREE, @@ -11625,13 +11662,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) error ("creating array of %qT", type); return error_mark_node; } - if (ABSTRACT_CLASS_TYPE_P (type)) - { - if (complain & tf_error) - error ("creating array of %qT, which is an abstract class type", - type); - return error_mark_node; - } + + if (abstract_virtuals_error_sfinae (ACU_ARRAY, type, complain)) + return error_mark_node; r = build_cplus_array_type (type, domain); @@ -11757,7 +11790,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) ++c_inhibit_evaluation_warnings; type = tsubst_expr (DECLTYPE_TYPE_EXPR (t), args, - complain, in_decl, + complain|tf_decltype, in_decl, /*integral_constant_expression_p=*/false); --cp_unevaluated_operand; @@ -12010,7 +12043,7 @@ tsubst_qualified_id (tree qualified_id, tree args, else if (TYPE_P (scope)) { expr = (adjust_result_of_qualified_name_lookup - (expr, scope, current_class_type)); + (expr, scope, current_nonlambda_class_type ())); expr = (finish_qualified_id_expr (scope, expr, done, address_p && PTRMEM_OK_P (qualified_id), QUALIFIED_NAME_IS_TEMPLATE (qualified_id), @@ -13393,6 +13426,12 @@ tsubst_copy_and_build (tree t, if (EXPR_HAS_LOCATION (t)) input_location = EXPR_LOCATION (t); + /* N3276 decltype magic only applies to calls at the top level or on the + right side of a comma. */ + if (TREE_CODE (t) != CALL_EXPR + && TREE_CODE (t) != COMPOUND_EXPR) + complain &= ~tf_decltype; + switch (TREE_CODE (t)) { case USING_DECL: @@ -13824,10 +13863,16 @@ tsubst_copy_and_build (tree t, complain)); case COMPOUND_EXPR: - RETURN (build_x_compound_expr (EXPR_LOCATION (t), - RECUR (TREE_OPERAND (t, 0)), - RECUR (TREE_OPERAND (t, 1)), - complain)); + { + tree op0 = tsubst_copy_and_build (TREE_OPERAND (t, 0), args, + complain & ~tf_decltype, in_decl, + /*function_p=*/false, + integral_constant_expression_p); + RETURN (build_x_compound_expr (EXPR_LOCATION (t), + op0, + RECUR (TREE_OPERAND (t, 1)), + complain)); + } case CALL_EXPR: { @@ -13838,6 +13883,10 @@ tsubst_copy_and_build (tree t, bool koenig_p; tree ret; + /* Don't pass tf_decltype down to subexpressions. */ + tsubst_flags_t decltype_flag = (complain & tf_decltype); + complain &= ~tf_decltype; + function = CALL_EXPR_FN (t); /* When we parsed the expression, we determined whether or not Koenig lookup should be performed. */ @@ -14004,6 +14053,9 @@ tsubst_copy_and_build (tree t, if (DECL_P (function)) mark_used (function); + /* Put back tf_decltype for the actual call. */ + complain |= decltype_flag; + if (TREE_CODE (function) == OFFSET_REF) ret = build_offset_ref_call_from_tree (function, &call_args, complain); @@ -14471,12 +14523,6 @@ tsubst_copy_and_build (tree t, declaration of the op() for later calls to lambda_function. */ complete_type (type); - /* The capture list refers to closure members, so this needs to - wait until after we finish instantiating the type. Also keep - any captures that may have been added during instantiation. */ - LAMBDA_EXPR_CAPTURE_LIST (r) - = chainon (RECUR (LAMBDA_EXPR_CAPTURE_LIST (t)), - LAMBDA_EXPR_CAPTURE_LIST (r)); LAMBDA_EXPR_THIS_CAPTURE (r) = NULL_TREE; RETURN (build_lambda_object (r)); |