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