diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 588825b01ca4fbcecdaf449374d43121a78188df..b9e632a1846e42f57c4015b781db287eaefeac25 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -788,6 +788,14 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression, } case tok::annot_cxxscope: { // [C++] id-expression: qualified-id + // If TryAnnotateTypeOrScopeToken annotates the token, tail recurse. + // (We can end up in this situation after tentative parsing.) + if (TryAnnotateTypeOrScopeToken()) + return ExprError(); + if (!Tok.is(tok::annot_cxxscope)) + return ParseCastExpression(isUnaryExpression, isAddressOfOperand, + NotCastExpr, TypeOfCast); + Token Next = NextToken(); if (Next.is(tok::annot_template_id)) { TemplateIdAnnotation *TemplateId diff --git a/clang/test/SemaCXX/qualified-id-lookup.cpp b/clang/test/SemaCXX/qualified-id-lookup.cpp index abde62efceae3bcbae557d5e1cfddde300c8bb5f..dfb059aa36ad00cac24ec295c390fb64da82782f 100644 --- a/clang/test/SemaCXX/qualified-id-lookup.cpp +++ b/clang/test/SemaCXX/qualified-id-lookup.cpp @@ -124,3 +124,25 @@ namespace test1 { template class ClassChecker; } + +namespace PR6830 { + namespace foo { + + class X { + public: + X() {} + }; + + } // namespace foo + + class Z { + public: + explicit Z(const foo::X& x) {} + + void Work() {} + }; + + void Test() { + Z(foo::X()).Work(); + } +}