[cfe-commits] r50665 - in /cfe/trunk: lib/Lex/PPExpressions.cpp test/Preprocessor/expr_invalid_tok.c test/Preprocessor/expr_liveness.c

Chris Lattner sabre at nondot.org
Mon May 5 13:07:41 PDT 2008


Author: lattner
Date: Mon May  5 15:07:41 2008
New Revision: 50665

URL: http://llvm.org/viewvc/llvm-project?rev=50665&view=rev
Log:
Fix a few more bugs in preprocessor expressions w.r.t. ?:.  Now I 
think it is really right. :)  This fixes PR2284.

Modified:
    cfe/trunk/lib/Lex/PPExpressions.cpp
    cfe/trunk/test/Preprocessor/expr_invalid_tok.c
    cfe/trunk/test/Preprocessor/expr_liveness.c

Modified: cfe/trunk/lib/Lex/PPExpressions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPExpressions.cpp?rev=50665&r1=50664&r2=50665&view=diff

==============================================================================
--- cfe/trunk/lib/Lex/PPExpressions.cpp (original)
+++ cfe/trunk/lib/Lex/PPExpressions.cpp Mon May  5 15:07:41 2008
@@ -362,8 +362,8 @@
   case tok::pipe:                 return 7;
   case tok::ampamp:               return 6;
   case tok::pipepipe:             return 5;
-  case tok::comma:                return 4;
-  case tok::question:             return 3;
+  case tok::question:             return 4;
+  case tok::comma:                return 3;
   case tok::colon:                return 2;
   case tok::r_paren:              return 0;   // Lowest priority, end of expr.
   case tok::eom:                  return 0;   // Lowest priority, end of macro.
@@ -432,14 +432,25 @@
       return true;
     }
     
-    bool isRightAssoc = Operator == tok::question;
+    // Decide whether to include the next binop in this subexpression.  For
+    // example, when parsing x+y*z and looking at '*', we want to recursively
+    // handling y*z as a single subexpression.  We do this because the
+    // precedence of * is higher than that of +.  The only strange case we have
+    // to handle here is for the ?: operator, where the precedence is actually
+    // lower than the LHS of the '?'.  The grammar rule is:
+    //
+    // conditional-expression ::=
+    //    logical-OR-expression ? expression : conditional-expression
+    // where 'expression' is actually comma-expression.
+    unsigned RHSPrec;
+    if (Operator == tok::question)
+      // The RHS of "?" should be maximally consumed as an expression.
+      RHSPrec = getPrecedence(tok::comma);
+    else  // All others should munch while higher precedence.
+      RHSPrec = ThisPrec+1;
     
-    // Get the precedence of the operator to the right of the RHS.  If it binds
-    // more tightly with RHS than we do, evaluate it completely first.
-    if (ThisPrec < PeekPrec ||
-        (ThisPrec == PeekPrec && isRightAssoc)) {
-      if (EvaluateDirectiveSubExpr(RHS, ThisPrec+!isRightAssoc, 
-                                   PeekTok, RHSIsLive, PP))
+    if (PeekPrec >= RHSPrec) {
+      if (EvaluateDirectiveSubExpr(RHS, RHSPrec, PeekTok, RHSIsLive, PP))
         return true;
       PeekPrec = getPrecedence(PeekTok.getKind());
     }
@@ -609,8 +620,8 @@
       if (EvaluateValue(AfterColonVal, PeekTok, DT, AfterColonLive, PP))
         return true;
 
-      // Parse anything after the : RHS that has a higher precedence than ?.
-      if (EvaluateDirectiveSubExpr(AfterColonVal, ThisPrec+1,
+      // Parse anything after the : with the same precedence as ?.
+      if (EvaluateDirectiveSubExpr(AfterColonVal, ThisPrec,
                                    PeekTok, AfterColonLive, PP))
         return true;
       
@@ -681,7 +692,8 @@
   
   // Otherwise, we must have a binary operator (e.g. "#if 1 < 2"), so parse the
   // operator and the stuff after it.
-  if (EvaluateDirectiveSubExpr(ResVal, 1, Tok, true, *this)) {
+  if (EvaluateDirectiveSubExpr(ResVal, getPrecedence(tok::question),
+                               Tok, true, *this)) {
     // Parse error, skip the rest of the macro line.
     if (Tok.isNot(tok::eom))
       DiscardUntilEndOfDirective();

Modified: cfe/trunk/test/Preprocessor/expr_invalid_tok.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/expr_invalid_tok.c?rev=50665&r1=50664&r2=50665&view=diff

==============================================================================
--- cfe/trunk/test/Preprocessor/expr_invalid_tok.c (original)
+++ cfe/trunk/test/Preprocessor/expr_invalid_tok.c Mon May  5 15:07:41 2008
@@ -1,5 +1,6 @@
 // RUN: not clang -E %s 2>&1 | grep 'invalid token at start of a preprocessor expression'
 // RUN: not clang -E %s 2>&1 | grep 'token is not a valid binary operator in a preprocessor subexpression'
+// RUN: not clang -E %s 2>&1 | grep ':14: error: expected end of line in preprocessor expression'
 // PR2220
 
 #if 1 * * 2
@@ -8,3 +9,7 @@
 #if 4 [ 2
 #endif
 
+
+// PR2284 - The constant-expr production does not including comma.
+#if 1 ? 2 : 0, 1
+#endif

Modified: cfe/trunk/test/Preprocessor/expr_liveness.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/expr_liveness.c?rev=50665&r1=50664&r2=50665&view=diff

==============================================================================
--- cfe/trunk/test/Preprocessor/expr_liveness.c (original)
+++ cfe/trunk/test/Preprocessor/expr_liveness.c Mon May  5 15:07:41 2008
@@ -30,6 +30,10 @@
 #if 1 ? 2 ? 3 : 4 : 5
 #endif
 
+// PR2284
+#if 1 ? 0: 1 ? 1/0: 1/0
+#endif
+
 #else
 
 





More information about the cfe-commits mailing list