(struct find_parameter_pack_data*)data;
bool parameter_pack_p = false;
+ /* Handle type aliases/typedefs. */
+ if (TYPE_P (t)
+ && TYPE_NAME (t)
+ && TREE_CODE (TYPE_NAME (t)) == TYPE_DECL
+ && TYPE_DECL_ALIAS_P (TYPE_NAME (t)))
+ {
+ if (TYPE_TEMPLATE_INFO (t))
+ cp_walk_tree (&TYPE_TI_ARGS (t),
+ &find_parameter_packs_r,
+ ppd, ppd->visited);
+ *walk_subtrees = 0;
+ return NULL_TREE;
+ }
+
/* Identify whether this is a parameter pack or not. */
switch (TREE_CODE (t))
{
if (check_for_bare_parameter_packs (TYPE_RAISES_EXCEPTIONS (type)))
TYPE_RAISES_EXCEPTIONS (type) = NULL_TREE;
}
- else if (check_for_bare_parameter_packs (TREE_TYPE (decl)))
+ else if (check_for_bare_parameter_packs ((TREE_CODE (decl) == TYPE_DECL
+ && TYPE_DECL_ALIAS_P (decl))
+ ? DECL_ORIGINAL_TYPE (decl)
+ : TREE_TYPE (decl)))
{
TREE_TYPE (decl) = error_mark_node;
return error_mark_node;
unify_inconsistency (bool explain_p, tree parm, tree first, tree second)
{
if (explain_p)
- inform (input_location,
- " conflicting deductions for parameter %qE (%qE and %qE)",
- parm, first, second);
+ {
+ if (TYPE_P (parm))
+ inform (input_location,
+ " deduced conflicting types for parameter %qT (%qT and %qT)",
+ parm, first, second);
+ else
+ inform (input_location,
+ " deduced conflicting values for non-type parameter "
+ "%qE (%qE and %qE)", parm, first, second);
+ }
return 1;
}
to a null value, but otherwise still need to be of a specific form. */
if (cxx_dialect >= cxx0x)
{
- if (INTEGRAL_OR_ENUMERATION_TYPE_P (type))
+ if (TREE_CODE (expr) == PTRMEM_CST)
+ /* A PTRMEM_CST is already constant, and a valid template
+ argument for a parameter of pointer to member type, we just want
+ to leave it in that form rather than lower it to a
+ CONSTRUCTOR. */;
+ else if (INTEGRAL_OR_ENUMERATION_TYPE_P (type))
expr = maybe_constant_value (expr);
else if (TYPE_PTR_P (type)
- || (TYPE_PTR_TO_MEMBER_P (type)
- && TREE_CODE (expr) != PTRMEM_CST))
+ || TYPE_PTR_TO_MEMBER_P (type))
{
tree folded = maybe_constant_value (expr);
if (TYPE_PTR_P (type) ? integer_zerop (folded)
if (requires_type && ! is_type && TREE_CODE (arg) == SCOPE_REF
&& TREE_CODE (TREE_OPERAND (arg, 0)) == TEMPLATE_TYPE_PARM)
{
- permerror (input_location, "to refer to a type member of a template parameter, "
- "use %<typename %E%>", orig_arg);
+ if (TREE_CODE (TREE_OPERAND (arg, 1)) == BIT_NOT_EXPR)
+ {
+ if (complain & tf_error)
+ error ("invalid use of destructor %qE as a type", orig_arg);
+ return error_mark_node;
+ }
+
+ permerror (input_location,
+ "to refer to a type member of a template parameter, "
+ "use %<typename %E%>", orig_arg);
orig_arg = make_typename_type (TREE_OPERAND (arg, 0),
TREE_OPERAND (arg, 1),
if (CLASSTYPE_LAMBDA_EXPR (type))
{
- tree lambda = CLASSTYPE_LAMBDA_EXPR (type);
- if (LAMBDA_EXPR_DEDUCE_RETURN_TYPE_P (lambda))
+ tree decl = lambda_function (type);
+ if (decl)
{
- apply_lambda_return_type (lambda, void_type_node);
- LAMBDA_EXPR_RETURN_TYPE (lambda) = NULL_TREE;
+ 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 (decl, false, false);
+ maybe_add_lambda_conv_op (type);
}
- instantiate_decl (lambda_function (type), false, false);
- maybe_add_lambda_conv_op (type);
+ else
+ gcc_assert (errorcount);
}
/* Set the file and line number information to whatever is given for
len = my_len;
else if (len != my_len)
{
- if (TREE_CODE (t) == TYPE_PACK_EXPANSION)
+ if (!(complain & tf_error))
+ /* Fail quietly. */;
+ else if (TREE_CODE (t) == TYPE_PACK_EXPANSION)
error ("mismatched argument pack lengths while expanding "
"%<%T%>",
pattern);
type = DECL_ORIGINAL_TYPE (t);
else
type = TREE_TYPE (t);
- if (TREE_CODE (t) == VAR_DECL && VAR_HAD_UNKNOWN_BOUND (t))
+ if (TREE_CODE (t) == VAR_DECL
+ && VAR_HAD_UNKNOWN_BOUND (t)
+ && type != error_mark_node)
type = strip_array_domain (type);
type = tsubst (type, args, complain, in_decl);
}
&& ANON_AGGR_TYPE_P (TREE_TYPE (decl)))
/* Anonymous aggregates are a special case. */
finish_anon_union (decl);
+ else if (is_capture_proxy (DECL_EXPR_DECL (t)))
+ {
+ DECL_CONTEXT (decl) = current_function_decl;
+ insert_capture_proxy (decl);
+ }
else
{
int const_init = false;
if (TRANSACTION_EXPR_IS_STMT (t))
{
+ tree body = TRANSACTION_EXPR_BODY (t);
+ tree noex = NULL_TREE;
+ if (TREE_CODE (body) == MUST_NOT_THROW_EXPR)
+ {
+ noex = MUST_NOT_THROW_COND (body);
+ if (noex == NULL_TREE)
+ noex = boolean_true_node;
+ body = TREE_OPERAND (body, 0);
+ }
stmt = begin_transaction_stmt (input_location, NULL, flags);
- RECUR (TRANSACTION_EXPR_BODY (t));
- finish_transaction_stmt (stmt, NULL, flags);
+ RECUR (body);
+ finish_transaction_stmt (stmt, NULL, flags, RECUR (noex));
}
else
{
stmt = build_transaction_expr (EXPR_LOCATION (t),
RECUR (TRANSACTION_EXPR_BODY (t)),
- flags);
+ flags, NULL_TREE);
return stmt;
}
}
break;
+ case MUST_NOT_THROW_EXPR:
+ return build_must_not_throw_expr (RECUR (TREE_OPERAND (t, 0)),
+ RECUR (MUST_NOT_THROW_COND (t)));
+
case EXPR_PACK_EXPANSION:
error ("invalid use of pack expansion expression");
return error_mark_node;
return r;
}
+ case TRANSACTION_EXPR:
+ return tsubst_expr(t, args, complain, in_decl,
+ integral_constant_expression_p);
+
default:
/* Handle Objective-C++ constructs, if appropriate. */
{
case BOOLEAN_TYPE:
case ENUMERAL_TYPE:
case VOID_TYPE:
+ case NULLPTR_TYPE:
if (TREE_CODE (arg) != TREE_CODE (parm))
return unify_type_mismatch (explain_p, parm, arg);