aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/pt.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/pt.c')
-rw-r--r--gcc/cp/pt.c120
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));