aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 '('}}
+};