summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/Parse/ParseExpr.cpp15
-rw-r--r--clang/test/Parser/cxx-ambig-paren-expr.cpp9
2 files changed, 19 insertions, 5 deletions
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index ad23804d1da..13b77223acc 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -1010,15 +1010,24 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
// unary-expression:
// ++ cast-expression
// -- cast-expression
- SourceLocation SavedLoc = ConsumeToken();
+ Token SavedTok = Tok;
+ ConsumeToken();
// One special case is implicitly handled here: if the preceding tokens are
// an ambiguous cast expression, such as "(T())++", then we recurse to
// determine whether the '++' is prefix or postfix.
Res = ParseCastExpression(!getLangOpts().CPlusPlus,
/*isAddressOfOperand*/false, NotCastExpr,
- NotTypeCast);
+ isTypeCast);
+ if (NotCastExpr) {
+ // If we return with NotCastExpr = true, we must not consume any tokens,
+ // so put the token back where we found it.
+ assert(Res.isInvalid());
+ UnconsumeToken(SavedTok);
+ return ExprError();
+ }
if (!Res.isInvalid())
- Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Res.get());
+ Res = Actions.ActOnUnaryOp(getCurScope(), SavedTok.getLocation(),
+ SavedKind, Res.get());
return Res;
}
case tok::amp: { // unary-expression: '&' cast-expression
diff --git a/clang/test/Parser/cxx-ambig-paren-expr.cpp b/clang/test/Parser/cxx-ambig-paren-expr.cpp
index 39882056723..1535b009725 100644
--- a/clang/test/Parser/cxx-ambig-paren-expr.cpp
+++ b/clang/test/Parser/cxx-ambig-paren-expr.cpp
@@ -21,8 +21,13 @@ void f() {
struct S{int operator()();};
(S())();
- // FIXME: Special case: "++" is postfix here, not prefix
- // (S())++;
+ // Special case: "++" is postfix here, not prefix
+ (S())++; // expected-error {{cannot increment value of type 'S'}}
+
+ struct X { int &operator++(int); X operator[](int); int &operator++(); };
+ int &postfix_incr = (X()[3])++;
+ (X())++ ++; // ok, not a C-style cast
+ (X())++ ++X(); // expected-error {{C-style cast from 'int' to 'X ()'}}
}
// Make sure we do tentative parsing correctly in conditions.
OpenPOWER on IntegriCloud