PR c++/52748
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 15 Apr 2013 15:24:03 +0000 (15:24 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 15 Apr 2013 15:24:03 +0000 (15:24 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@197982 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/g++.dg/cpp0x/decltype-call3.C

index eefd11e..209c9cb 100644 (file)
@@ -1,5 +1,11 @@
 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
        * semantics.c (insert_capture_proxy): Just use index 1 in the
        stmt_list_stack.
index dc1385e..36520a4 100644 (file)
@@ -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.  */
index 1d12b01..27797a2 100644 (file)
@@ -43,6 +43,50 @@ A operator==(B,B);
 A operator->*(B,B);
 
 #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()
 {
   B b;
@@ -83,4 +127,6 @@ int main()
   TRY(b>>b);
   TRY(b==b);
   TRY(b->*b);
+
+  f<B>();
 }