Hi,

I have been looking into this issue, which should be rather easy to solve: the problem seems that in a template we are mishandling ~ as a bitwise complement operator (vs destructor introducer). We end up here in cp_parser_unqualified_id:

        type_decl
          = cp_parser_class_name (parser,
                      /*typename_keyword_p=*/false,
                      /*template_keyword_p=*/false,
                      typename_type,
                      /*check_dependency=*/false,
                      /*class_head_p=*/false,
                      declarator_p);
        if (processing_template_decl
        && ! cp_parser_parse_definitely (parser))
          {
        /* We couldn't find a type with this name, so just accept
           it and check for a match at instantiation time.  */
        type_decl = cp_parser_identifier (parser);
        if (type_decl != error_mark_node)
          type_decl = build_nt (BIT_NOT_EXPR, type_decl);
        return type_decl;
          }

and apparently the cp_parser_id_expression call at the beginning of cp_parser_decltype_expr succeeds with a BIT_NOT_EXPR with an identifier as argument. But that means that we are looking into the ~ class-name production, which obviously doesn't make sense as decltype expression. If we keep on working in cp_parser_decltype_expr we end up calling cp_parser_expression (the same we do for things like !x or ++x) and everything goes well. Anyway, draft tested on x86_64-linux.

Thanks!
Paolo.

//////////////////////////////


Index: cp/parser.c
===================================================================
--- cp/parser.c (revision 224331)
+++ cp/parser.c (working copy)
@@ -12252,6 +12252,12 @@ cp_parser_decltype_expr (cp_parser *parser,
                                   /*declarator_p=*/false,
                                   /*optional_p=*/false);
 
+  /* The production ~ class-name is not ok here, keep looking, it's probably
+     a complement expression (c++/65091).  */
+  if (TREE_CODE (expr) == BIT_NOT_EXPR
+      && identifier_p (TREE_OPERAND (expr, 0)))
+    expr = error_mark_node;
+
   if (!cp_parser_error_occurred (parser) && expr != error_mark_node)
     {
       bool non_integral_constant_expression_p = false;
Index: testsuite/g++.dg/cpp0x/decltype63.C
===================================================================
--- testsuite/g++.dg/cpp0x/decltype63.C (revision 0)
+++ testsuite/g++.dg/cpp0x/decltype63.C (working copy)
@@ -0,0 +1,9 @@
+// PR c++/65091
+// { dg-do compile { target c++11 } }
+
+template<typename T>
+auto foo(T x) -> decltype(~x)
+{ return ~x; }
+
+int bar()
+{ return foo(10); }

Reply via email to