From 4da97565d3c23bcced3f1f1512c4496c8ec68e2b Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 15 Apr 2013 11:24:03 -0400 Subject: 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 --- gcc/cp/ChangeLog | 6 ++++ gcc/cp/pt.c | 43 ++++++++++++++++----------- gcc/testsuite/g++.dg/cpp0x/decltype-call3.C | 46 +++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 17 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index eefd11e..209c9cb 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,11 @@ 2013-04-15 Jason Merrill + 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 * semantics.c (insert_capture_proxy): Just use index 1 in the stmt_list_stack. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index dc1385e..36520a4 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -11782,8 +11782,17 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) else if (DECLTYPE_FOR_LAMBDA_PROXY (t)) type = lambda_proxy_type (type); 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, cp_type_quals (t) | cp_type_quals (type), @@ -13431,9 +13440,8 @@ tsubst_copy_and_build (tree 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; + tsubst_flags_t decltype_flag = (complain & tf_decltype); + complain &= ~tf_decltype; switch (TREE_CODE (t)) { @@ -13521,7 +13529,8 @@ tsubst_copy_and_build (tree t, r = convert_from_reference (r); } 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); } @@ -13598,7 +13607,8 @@ tsubst_copy_and_build (tree t, case POSTINCREMENT_EXPR: op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0), 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 PREINCREMENT_EXPR: @@ -13610,7 +13620,8 @@ tsubst_copy_and_build (tree t, case REALPART_EXPR: case IMAGPART_EXPR: 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: RETURN (cp_build_unary_op (FIX_TRUNC_EXPR, RECUR (TREE_OPERAND (t, 0)), @@ -13627,7 +13638,8 @@ tsubst_copy_and_build (tree t, else op1 = tsubst_non_call_postfix_expression (op1, args, complain, 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 MINUS_EXPR: @@ -13676,7 +13688,7 @@ tsubst_copy_and_build (tree t, ? ERROR_MARK : TREE_CODE (TREE_OPERAND (t, 1))), /*overload=*/NULL, - complain); + complain|decltype_flag); if (EXPR_P (r) && TREE_NO_WARNING (t)) TREE_NO_WARNING (r) = TREE_NO_WARNING (t); @@ -13692,7 +13704,8 @@ tsubst_copy_and_build (tree t, op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0), args, complain, in_decl); 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: if (PACK_EXPANSION_P (TREE_OPERAND (t, 0))) @@ -13785,7 +13798,7 @@ tsubst_copy_and_build (tree t, RECUR (TREE_OPERAND (t, 0)), TREE_CODE (TREE_OPERAND (t, 1)), RECUR (TREE_OPERAND (t, 2)), - complain); + complain|decltype_flag); /* TREE_NO_WARNING must be set if either the expression was parenthesized or it uses an operator such as >>= rather than plain assignment. In the former case, it was already @@ -13874,7 +13887,7 @@ tsubst_copy_and_build (tree t, RETURN (build_x_compound_expr (EXPR_LOCATION (t), op0, RECUR (TREE_OPERAND (t, 1)), - complain)); + complain|decltype_flag)); } case CALL_EXPR: @@ -13886,10 +13899,6 @@ 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. */ diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype-call3.C b/gcc/testsuite/g++.dg/cpp0x/decltype-call3.C index 1d12b01..27797a2 100644 --- a/gcc/testsuite/g++.dg/cpp0x/decltype-call3.C +++ b/gcc/testsuite/g++.dg/cpp0x/decltype-call3.C @@ -43,6 +43,50 @@ A operator==(B,B); A operator->*(B,B); #define TRY(E) static_cast(0) + +template +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); +} + int main() { B b; @@ -83,4 +127,6 @@ int main() TRY(b>>b); TRY(b==b); TRY(b->*b); + + f(); } -- cgit v1.1