Commit 57fcd4f4 by Jason Merrill Committed by Jason Merrill

re PR c++/52748 ([C++11] N3276 changes to decltype)

	N3276
	PR c++/52748
	* cp-tree.h (tsubst_flags): Add tf_decltype.
	* call.c (build_cxx_call): Don't build a temporary if it's set.
	(build_over_call): Make sure it's only passed to build_cxx_call.
	* parser.c (cp_parser_primary_expression): Add decltype_p parm.
	(cp_parser_unary_expression): Likewise.
	(cp_parser_cast_expression): Likewise.
	(cp_parser_binary_expression): Likewise.
	(cp_parser_assignment_expression): Likewise.
	(cp_parser_postfix_expression): Likewise.  Pass tf_decltype.
	(cp_parser_explicit_instantiation): Add decltype_p.  Force a
	temporary for a call on the LHS of a comma.
	(cp_parser_decltype): Pass true to decltype_p parms.
	* pt.c (tsubst) [DECLTYPE_TYPE]: Pass tf_decltype.
	(tsubst_copy_and_build): Pass tf_decltype down only for
	CALL_EXPR and the RHS of COMPOUND_EXPR.
	* tree.c (build_cplus_new): Call complete_type_or_maybe_complain.

From-SVN: r196736
parent 2df663cc
2013-03-16 Jason Merrill <jason@redhat.com>
N3276
PR c++/52748
* cp-tree.h (tsubst_flags): Add tf_decltype.
* call.c (build_cxx_call): Don't build a temporary if it's set.
(build_over_call): Make sure it's only passed to build_cxx_call.
* parser.c (cp_parser_primary_expression): Add decltype_p parm.
(cp_parser_unary_expression): Likewise.
(cp_parser_cast_expression): Likewise.
(cp_parser_binary_expression): Likewise.
(cp_parser_assignment_expression): Likewise.
(cp_parser_postfix_expression): Likewise. Pass tf_decltype.
(cp_parser_explicit_instantiation): Add decltype_p. Force a
temporary for a call on the LHS of a comma.
(cp_parser_decltype): Pass true to decltype_p parms.
* pt.c (tsubst) [DECLTYPE_TYPE]: Pass tf_decltype.
(tsubst_copy_and_build): Pass tf_decltype down only for
CALL_EXPR and the RHS of COMPOUND_EXPR.
* tree.c (build_cplus_new): Call complete_type_or_maybe_complain.
* cp-tree.h (abstract_class_use): New enum.
* typeck2.c (pending_abstract_type): Add use field.
(abstract_virtuals_error_sfinae): Add overloads taking
......
......@@ -6693,6 +6693,10 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
/* else continue to get conversion error. */
}
/* N3276 magic doesn't apply to nested calls. */
int decltype_flag = (complain & tf_decltype);
complain &= ~tf_decltype;
/* Find maximum size of vector to hold converted arguments. */
parmlen = list_length (parm);
nargs = vec_safe_length (args) + (first_arg != NULL_TREE ? 1 : 0);
......@@ -7064,7 +7068,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
return error_mark_node;
}
return build_cxx_call (fn, nargs, argarray, complain);
return build_cxx_call (fn, nargs, argarray, complain|decltype_flag);
}
/* Build and return a call to FN, using NARGS arguments in ARGARRAY.
......@@ -7106,12 +7110,20 @@ build_cxx_call (tree fn, int nargs, tree *argarray,
if (VOID_TYPE_P (TREE_TYPE (fn)))
return fn;
fn = require_complete_type_sfinae (fn, complain);
if (fn == error_mark_node)
return error_mark_node;
/* 5.2.2/11: If a function call is a prvalue of object type: if the
function call is either the operand of a decltype-specifier or the
right operand of a comma operator that is the operand of a
decltype-specifier, a temporary object is not introduced for the
prvalue. The type of the prvalue may be incomplete. */
if (!(complain & tf_decltype))
{
fn = require_complete_type_sfinae (fn, complain);
if (fn == error_mark_node)
return error_mark_node;
if (MAYBE_CLASS_TYPE_P (TREE_TYPE (fn)))
fn = build_cplus_new (TREE_TYPE (fn), fn, complain);
if (MAYBE_CLASS_TYPE_P (TREE_TYPE (fn)))
fn = build_cplus_new (TREE_TYPE (fn), fn, complain);
}
return convert_from_reference (fn);
}
......
......@@ -4203,6 +4203,9 @@ enum tsubst_flags {
conversion might be permissible,
not actually performing the
conversion. */
tf_decltype = 1 << 7, /* We are the operand of decltype.
Used to implement the special rules
for calls in decltype (5.2.2/11). */
tf_partial = 1 << 8, /* Doing initial explicit argument
substitution in fn_type_unification. */
/* Convenient substitution flags combinations. */
......
......@@ -11781,7 +11781,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;
......@@ -13417,6 +13417,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:
......@@ -13848,10 +13854,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:
{
......@@ -13862,6 +13874,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. */
......@@ -14028,6 +14044,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);
......
......@@ -469,6 +469,9 @@ build_cplus_new (tree type, tree init, tsubst_flags_t complain)
tree rval = build_aggr_init_expr (type, init);
tree slot;
if (!complete_type_or_maybe_complain (type, init, complain))
return error_mark_node;
/* Make sure that we're not trying to create an instance of an
abstract class. */
if (abstract_virtuals_error_sfinae (NULL_TREE, type, complain))
......
// PR c++/52748
// N3276
// { dg-do compile { target c++11 } }
struct A; // { dg-error "forward declaration" }
A f();
decltype(f()) g1(); // OK
decltype(((f()))) g2b(); // OK
decltype(42,f()) g3(); // OK
decltype(42,45,f()) g3b(); // OK
decltype(42,45,(f())) g3c(); // OK
decltype(42,((45,(f())))) g3c(); // OK
decltype(f(),42) g4(); // { dg-error "" }
decltype(45,f(),42) g4b(); // { dg-error "" }
class B
{
~B(); // { dg-error "private" }
public:
int i;
void operator[](int);
};
B h();
void i(const B&);
decltype(h()) g5a(); // OK
decltype(h().i) g5(); // { dg-error "" }
decltype(h()[0]) g6(); // { dg-error "" }
decltype(i(h())) g7(); // { dg-error "" }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment