r259622 - Fix miscompile and rejects-valids when disambiguating after an ambiguous

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Tue Feb 2 18:58:20 PST 2016


Author: rsmith
Date: Tue Feb  2 20:58:20 2016
New Revision: 259622

URL: http://llvm.org/viewvc/llvm-project?rev=259622&view=rev
Log:
Fix miscompile and rejects-valids when disambiguating after an ambiguous
C-style-cast to function/array type or parenthesized function-style cast/array
indexing.

Modified:
    cfe/trunk/lib/Parse/ParseExpr.cpp
    cfe/trunk/test/Parser/cxx-ambig-paren-expr.cpp

Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=259622&r1=259621&r2=259622&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExpr.cpp Tue Feb  2 20:58:20 2016
@@ -1010,15 +1010,24 @@ ExprResult Parser::ParseCastExpression(b
     //   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

Modified: cfe/trunk/test/Parser/cxx-ambig-paren-expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx-ambig-paren-expr.cpp?rev=259622&r1=259621&r2=259622&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx-ambig-paren-expr.cpp (original)
+++ cfe/trunk/test/Parser/cxx-ambig-paren-expr.cpp Tue Feb  2 20:58:20 2016
@@ -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.




More information about the cfe-commits mailing list