]> granicus.if.org Git - clang/commitdiff
Fix PR2477 - clang misparses "//*" in C89 mode
authorChris Lattner <sabre@nondot.org>
Fri, 16 Jan 2009 22:39:25 +0000 (22:39 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 16 Jan 2009 22:39:25 +0000 (22:39 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62368 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Lex/Lexer.cpp
test/Lexer/c90.c

index 0eb439a27b68d03837ee361f6fd0973b8e601f06..fa29d0a38e09dc712f22aa06acd12464de1262ff 100644 (file)
@@ -1300,7 +1300,8 @@ LexNextToken:
     
     // If the next token is obviously a // or /* */ comment, skip it efficiently
     // too (without going through the big switch stmt).
-    if (CurPtr[0] == '/' && CurPtr[1] == '/' && !inKeepCommentMode()) {
+    if (CurPtr[0] == '/' && CurPtr[1] == '/' && !inKeepCommentMode() &&
+        Features.BCPLComment) {
       SkipBCPLComment(Result, CurPtr+2);
       goto SkipIgnoredUnits;
     } else if (CurPtr[0] == '/' && CurPtr[1] == '*' && !inKeepCommentMode()) {
@@ -1480,18 +1481,32 @@ LexNextToken:
     // 6.4.9: Comments
     Char = getCharAndSize(CurPtr, SizeTmp);
     if (Char == '/') {         // BCPL comment.
-      if (SkipBCPLComment(Result, ConsumeChar(CurPtr, SizeTmp, Result)))
-        return; // KeepCommentMode
+      // Even if BCPL comments are disabled (e.g. in C89 mode), we generally
+      // want to lex this as a comment.  There is one problem with this though,
+      // that in one particular corner case, this can change the behavior of the
+      // resultant program.  For example, In  "foo //**/ bar", C89 would lex
+      // this as "foo / bar" and langauges with BCPL comments would lex it as
+      // "foo".  Check to see if the character after the second slash is a '*'.
+      // If so, we will lex that as a "/" instead of the start of a comment.
+      if (Features.BCPLComment ||
+          getCharAndSize(CurPtr+SizeTmp, SizeTmp2) != '*') {
+        if (SkipBCPLComment(Result, ConsumeChar(CurPtr, SizeTmp, Result)))
+          return; // KeepCommentMode
       
-      // It is common for the tokens immediately after a // comment to be
-      // whitespace (indentation for the next line).  Instead of going through
-      // the big switch, handle it efficiently now.
-      goto SkipIgnoredUnits;
-    } else if (Char == '*') {  // /**/ comment.
+        // It is common for the tokens immediately after a // comment to be
+        // whitespace (indentation for the next line).  Instead of going through
+        // the big switch, handle it efficiently now.
+        goto SkipIgnoredUnits;
+      }
+    }
+      
+    if (Char == '*') {  // /**/ comment.
       if (SkipBlockComment(Result, ConsumeChar(CurPtr, SizeTmp, Result)))
         return; // KeepCommentMode
       goto LexNextToken;   // GCC isn't tail call eliminating.
-    } else if (Char == '=') {
+    }
+      
+    if (Char == '=') {
       CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
       Kind = tok::slashequal;
     } else {
index 4bbddaf38b4d43d1a7d9d418f65b18dc9d6ed8e9..d76c73ddc3d33c46bd08c61743caab480b914c38 100644 (file)
@@ -4,3 +4,10 @@
 enum { cast_hex = (long) (
       0x0p-1   /* expected-error {{hexadecimal floating constants are a C99 feature}} */
      ) };
+
+/* PR2477 */
+int test1(int a,int b) {return a//* This is a divide followed by block comment in c89 mode */
+b;}
+
+// comment accepted as extension    /* expected-error {{// comments are not allowed in this language}}
+