Commit 4da97565 by Jason Merrill Committed by Jason Merrill

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

	PR c++/52748
	* pt.c (tsubst) [DECLTYPE_TYPE]: If ~id is an expression
	rather than a destructor name, it isn't an unqualified-name.
	(tsubst_copy_and_build): Pass down decltype_flag to operator
	handling code, too.

From-SVN: r197982
parent a68329c2
2013-04-15 Jason Merrill <jason@redhat.com> 2013-04-15 Jason Merrill <jason@redhat.com>
PR c++/52748
* pt.c (tsubst) [DECLTYPE_TYPE]: If ~id is an expression
rather than a destructor name, it isn't an unqualified-name.
(tsubst_copy_and_build): Pass down decltype_flag to operator
handling code, too.
PR c++/56388 PR c++/56388
* semantics.c (insert_capture_proxy): Just use index 1 in the * semantics.c (insert_capture_proxy): Just use index 1 in the
stmt_list_stack. stmt_list_stack.
......
...@@ -11782,8 +11782,17 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) ...@@ -11782,8 +11782,17 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
else if (DECLTYPE_FOR_LAMBDA_PROXY (t)) else if (DECLTYPE_FOR_LAMBDA_PROXY (t))
type = lambda_proxy_type (type); type = lambda_proxy_type (type);
else else
type = finish_decltype_type {
(type, DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t), complain); bool id = DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t);
if (id && TREE_CODE (DECLTYPE_TYPE_EXPR (t)) == BIT_NOT_EXPR
&& EXPR_P (type))
/* In a template ~id could be either a complement expression
or an unqualified-id naming a destructor; if instantiating
it produces an expression, it's not an id-expression or
member access. */
id = false;
type = finish_decltype_type (type, id, complain);
}
return cp_build_qualified_type_real (type, return cp_build_qualified_type_real (type,
cp_type_quals (t) cp_type_quals (t)
| cp_type_quals (type), | cp_type_quals (type),
...@@ -13431,8 +13440,7 @@ tsubst_copy_and_build (tree t, ...@@ -13431,8 +13440,7 @@ tsubst_copy_and_build (tree t,
/* N3276 decltype magic only applies to calls at the top level or on the /* N3276 decltype magic only applies to calls at the top level or on the
right side of a comma. */ right side of a comma. */
if (TREE_CODE (t) != CALL_EXPR tsubst_flags_t decltype_flag = (complain & tf_decltype);
&& TREE_CODE (t) != COMPOUND_EXPR)
complain &= ~tf_decltype; complain &= ~tf_decltype;
switch (TREE_CODE (t)) switch (TREE_CODE (t))
...@@ -13521,7 +13529,8 @@ tsubst_copy_and_build (tree t, ...@@ -13521,7 +13529,8 @@ tsubst_copy_and_build (tree t,
r = convert_from_reference (r); r = convert_from_reference (r);
} }
else else
r = build_x_indirect_ref (input_location, r, RO_UNARY_STAR, complain); r = build_x_indirect_ref (input_location, r, RO_UNARY_STAR,
complain|decltype_flag);
RETURN (r); RETURN (r);
} }
...@@ -13598,7 +13607,8 @@ tsubst_copy_and_build (tree t, ...@@ -13598,7 +13607,8 @@ tsubst_copy_and_build (tree t,
case POSTINCREMENT_EXPR: case POSTINCREMENT_EXPR:
op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0), op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0),
args, complain, in_decl); args, complain, in_decl);
RETURN (build_x_unary_op (input_location, TREE_CODE (t), op1, complain)); RETURN (build_x_unary_op (input_location, TREE_CODE (t), op1,
complain|decltype_flag));
case PREDECREMENT_EXPR: case PREDECREMENT_EXPR:
case PREINCREMENT_EXPR: case PREINCREMENT_EXPR:
...@@ -13610,7 +13620,8 @@ tsubst_copy_and_build (tree t, ...@@ -13610,7 +13620,8 @@ tsubst_copy_and_build (tree t,
case REALPART_EXPR: case REALPART_EXPR:
case IMAGPART_EXPR: case IMAGPART_EXPR:
RETURN (build_x_unary_op (input_location, TREE_CODE (t), RETURN (build_x_unary_op (input_location, TREE_CODE (t),
RECUR (TREE_OPERAND (t, 0)), complain)); RECUR (TREE_OPERAND (t, 0)),
complain|decltype_flag));
case FIX_TRUNC_EXPR: case FIX_TRUNC_EXPR:
RETURN (cp_build_unary_op (FIX_TRUNC_EXPR, RECUR (TREE_OPERAND (t, 0)), RETURN (cp_build_unary_op (FIX_TRUNC_EXPR, RECUR (TREE_OPERAND (t, 0)),
...@@ -13627,7 +13638,8 @@ tsubst_copy_and_build (tree t, ...@@ -13627,7 +13638,8 @@ tsubst_copy_and_build (tree t,
else else
op1 = tsubst_non_call_postfix_expression (op1, args, complain, op1 = tsubst_non_call_postfix_expression (op1, args, complain,
in_decl); in_decl);
RETURN (build_x_unary_op (input_location, ADDR_EXPR, op1, complain)); RETURN (build_x_unary_op (input_location, ADDR_EXPR, op1,
complain|decltype_flag));
case PLUS_EXPR: case PLUS_EXPR:
case MINUS_EXPR: case MINUS_EXPR:
...@@ -13676,7 +13688,7 @@ tsubst_copy_and_build (tree t, ...@@ -13676,7 +13688,7 @@ tsubst_copy_and_build (tree t,
? ERROR_MARK ? ERROR_MARK
: TREE_CODE (TREE_OPERAND (t, 1))), : TREE_CODE (TREE_OPERAND (t, 1))),
/*overload=*/NULL, /*overload=*/NULL,
complain); complain|decltype_flag);
if (EXPR_P (r) && TREE_NO_WARNING (t)) if (EXPR_P (r) && TREE_NO_WARNING (t))
TREE_NO_WARNING (r) = TREE_NO_WARNING (t); TREE_NO_WARNING (r) = TREE_NO_WARNING (t);
...@@ -13692,7 +13704,8 @@ tsubst_copy_and_build (tree t, ...@@ -13692,7 +13704,8 @@ tsubst_copy_and_build (tree t,
op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0), op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0),
args, complain, in_decl); args, complain, in_decl);
RETURN (build_x_array_ref (EXPR_LOCATION (t), op1, RETURN (build_x_array_ref (EXPR_LOCATION (t), op1,
RECUR (TREE_OPERAND (t, 1)), complain)); RECUR (TREE_OPERAND (t, 1)),
complain|decltype_flag));
case SIZEOF_EXPR: case SIZEOF_EXPR:
if (PACK_EXPANSION_P (TREE_OPERAND (t, 0))) if (PACK_EXPANSION_P (TREE_OPERAND (t, 0)))
...@@ -13785,7 +13798,7 @@ tsubst_copy_and_build (tree t, ...@@ -13785,7 +13798,7 @@ tsubst_copy_and_build (tree t,
RECUR (TREE_OPERAND (t, 0)), RECUR (TREE_OPERAND (t, 0)),
TREE_CODE (TREE_OPERAND (t, 1)), TREE_CODE (TREE_OPERAND (t, 1)),
RECUR (TREE_OPERAND (t, 2)), RECUR (TREE_OPERAND (t, 2)),
complain); complain|decltype_flag);
/* TREE_NO_WARNING must be set if either the expression was /* TREE_NO_WARNING must be set if either the expression was
parenthesized or it uses an operator such as >>= rather parenthesized or it uses an operator such as >>= rather
than plain assignment. In the former case, it was already than plain assignment. In the former case, it was already
...@@ -13874,7 +13887,7 @@ tsubst_copy_and_build (tree t, ...@@ -13874,7 +13887,7 @@ tsubst_copy_and_build (tree t,
RETURN (build_x_compound_expr (EXPR_LOCATION (t), RETURN (build_x_compound_expr (EXPR_LOCATION (t),
op0, op0,
RECUR (TREE_OPERAND (t, 1)), RECUR (TREE_OPERAND (t, 1)),
complain)); complain|decltype_flag));
} }
case CALL_EXPR: case CALL_EXPR:
...@@ -13886,10 +13899,6 @@ tsubst_copy_and_build (tree t, ...@@ -13886,10 +13899,6 @@ tsubst_copy_and_build (tree t,
bool koenig_p; bool koenig_p;
tree ret; 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); function = CALL_EXPR_FN (t);
/* When we parsed the expression, we determined whether or /* When we parsed the expression, we determined whether or
not Koenig lookup should be performed. */ not Koenig lookup should be performed. */
......
...@@ -43,6 +43,50 @@ A operator==(B,B); ...@@ -43,6 +43,50 @@ A operator==(B,B);
A operator->*(B,B); A operator->*(B,B);
#define TRY(E) static_cast<decltype(E)*>(0) #define TRY(E) static_cast<decltype(E)*>(0)
template <class B>
void f()
{
B b;
TRY(b(0));
TRY(b[0]);
TRY(b=0);
TRY(b+=0);
TRY(b-=0);
TRY(b*=0);
TRY(b/=0);
TRY(b^=0);
TRY(b&=0);
TRY(b|=0);
TRY(b<<=0);
TRY(b>>=0);
TRY(-b);
TRY(+b);
TRY(*b);
TRY(&b);
TRY(!b);
TRY(~b);
TRY(++b);
TRY(--b);
TRY(b+b);
TRY(b-b);
TRY(b*b);
TRY(b/b);
TRY(b%b);
TRY(b^b);
TRY(b&b);
TRY(b|b);
TRY(b>b);
TRY(b<b);
TRY((b,b));
TRY(b<<b);
TRY(b>>b);
TRY(b==b);
TRY(b->*b);
}
int main() int main()
{ {
B b; B b;
...@@ -83,4 +127,6 @@ int main() ...@@ -83,4 +127,6 @@ int main()
TRY(b>>b); TRY(b>>b);
TRY(b==b); TRY(b==b);
TRY(b->*b); TRY(b->*b);
f<B>();
} }
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