diff options
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 17 | ||||
-rw-r--r-- | test/SemaCXX/decltype.cpp | 9 |
2 files changed, 23 insertions, 3 deletions
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index e656a6bd76..492250da1d 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -696,9 +696,22 @@ SourceLocation Parser::ParseDecltypeSpecifier(DeclSpec &DS) { 0, /*IsDecltype=*/true); Result = ParseExpression(); if (Result.isInvalid()) { - SkipUntil(tok::r_paren); DS.SetTypeSpecError(); - return StartLoc; + if (SkipUntil(tok::r_paren, /*StopAtSemi=*/true, /*DontConsume=*/true)) { + EndLoc = ConsumeParen(); + } else { + assert(Tok.is(tok::semi)); + if (PP.isBacktrackEnabled()) { + // Backtrack to get the location of the last token before the semi. + PP.RevertCachedTokens(2); + ConsumeToken(); // the semi. + EndLoc = ConsumeAnyToken(); + assert(Tok.is(tok::semi)); + } else { + EndLoc = Tok.getLocation(); + } + } + return EndLoc; } // Match the ')' diff --git a/test/SemaCXX/decltype.cpp b/test/SemaCXX/decltype.cpp index ef3103ded7..f9bdececc4 100644 --- a/test/SemaCXX/decltype.cpp +++ b/test/SemaCXX/decltype.cpp @@ -1,5 +1,4 @@ // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s -// expected-no-diagnostics // PR5290 int const f0(); @@ -29,3 +28,11 @@ template<typename T> auto f(T t) -> decltype(S<int>(t)) { using U = S<int>; return S<int>(t); } + +struct B { + B(decltype(undeclared)); // expected-error {{undeclared identifier}} +}; +struct C { + C(decltype(undeclared; // expected-error {{undeclared identifier}} \ + // expected-error {{expected ')'}} expected-note {{to match this '('}} +}; |