diff mbox

[C++,Patch/RFC] PR 65091

Message ID 55796697.2050407@oracle.com
State New
Headers show

Commit Message

Paolo Carlini June 11, 2015, 10:44 a.m. UTC
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.

//////////////////////////////
diff mbox

Patch

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); }