aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2012-10-26 22:53:44 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2012-10-26 22:53:44 +0000
commit1e584697aa795f915cd46afefd4e1141ee356b8c (patch)
treeb2505241fa6d595796a0fa0a2e2966e9d37a937e
parentaa014664a6083de28e255cfd304cae4605cf5e4f (diff)
In Parser::ParseDecltypeSpecifier, make sure the end location it returns
is at the end of parsed tokens when an error occurs, otherwise we'll hit an assertion when trying to annotate the decltype tokens. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@166826 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Parse/ParseDeclCXX.cpp17
-rw-r--r--test/SemaCXX/decltype.cpp9
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 '('}}
+};