]> granicus.if.org Git - llvm/commitdiff
[MC] Prevent out of order HashDirective lexing in AsmLexer.
authorNirav Dave <niravd@google.com>
Sat, 1 Oct 2016 00:42:32 +0000 (00:42 +0000)
committerNirav Dave <niravd@google.com>
Sat, 1 Oct 2016 00:42:32 +0000 (00:42 +0000)
To lex hash directives we peek ahead to find component tokens, create a
unified token, and unlex the peeked tokens so the parser does not need
to parse the tokens then. Make sure we do not to lex another hash
directive during peek operation.

This fixes PR28921.

Reviewers: rnk, loladiro

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D24839

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@282992 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/MC/MCParser/AsmLexer.h
lib/MC/MCParser/AsmLexer.cpp
test/MC/AsmParser/pr28921.s [new file with mode: 0644]

index 06937e25f59ef61dd92be3683025560f9bd6d3f1..029598c013d3570c0ed226017006d67dc5eabbbb 100644 (file)
@@ -32,7 +32,7 @@ class AsmLexer : public MCAsmLexer {
   bool IsAtStartOfLine;
   bool IsAtStartOfStatement;
   bool IsParsingMSInlineAsm;
-
+  bool IsPeeking;
   void operator=(const AsmLexer&) = delete;
   AsmLexer(const AsmLexer&) = delete;
 
index c1f71bcc36810b9ac1eba22665eef9f2e8252e99..d0c8bce0382660f274ede3c89af5d986020b7041 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
+#include "llvm/MC/MCParser/AsmLexer.h"
 #include "llvm/ADT/APInt.h"
 #include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringSwitch.h"
 #include "llvm/ADT/StringRef.h"
-#include "llvm/MC/MCParser/AsmLexer.h"
-#include "llvm/MC/MCParser/MCAsmLexer.h"
+#include "llvm/ADT/StringSwitch.h"
 #include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCParser/MCAsmLexer.h"
 #include "llvm/Support/SMLoc.h"
+#include "llvm/Support/SaveAndRestore.h"
 #include <cassert>
 #include <cctype>
 #include <cstdio>
 #include <cstring>
-#include <tuple>
 #include <string>
+#include <tuple>
 #include <utility>
 
 using namespace llvm;
 
-AsmLexer::AsmLexer(const MCAsmInfo &MAI) : MAI(MAI) {
-  CurPtr = nullptr;
-  IsAtStartOfLine = true;
-  IsAtStartOfStatement = true;
-  IsParsingMSInlineAsm = false;
+AsmLexer::AsmLexer(const MCAsmInfo &MAI)
+    : MAI(MAI), CurPtr(nullptr), IsAtStartOfLine(true),
+      IsAtStartOfStatement(true), IsParsingMSInlineAsm(false),
+      IsPeeking(false) {
   AllowAtInIdentifier = !StringRef(MAI.getCommentString()).startswith("@");
 }
 
@@ -487,17 +487,15 @@ StringRef AsmLexer::LexUntilEndOfLine() {
 
 size_t AsmLexer::peekTokens(MutableArrayRef<AsmToken> Buf,
                             bool ShouldSkipSpace) {
-  const char *SavedTokStart = TokStart;
-  const char *SavedCurPtr = CurPtr;
-  bool SavedAtStartOfLine = IsAtStartOfLine;
-  bool SavedAtStartOfStatement = IsAtStartOfStatement;
-  bool SavedSkipSpace = SkipSpace;
-
+  SaveAndRestore<const char *> SavedTokenStart(TokStart);
+  SaveAndRestore<const char *> SavedCurPtr(CurPtr);
+  SaveAndRestore<bool> SavedAtStartOfLine(IsAtStartOfLine);
+  SaveAndRestore<bool> SavedAtStartOfStatement(IsAtStartOfStatement);
+  SaveAndRestore<bool> SavedSkipSpace(SkipSpace, ShouldSkipSpace);
+  SaveAndRestore<bool> SavedIsPeeking(IsPeeking, true);
   std::string SavedErr = getErr();
   SMLoc SavedErrLoc = getErrLoc();
 
-  SkipSpace = ShouldSkipSpace;
-
   size_t ReadCount;
   for (ReadCount = 0; ReadCount < Buf.size(); ++ReadCount) {
     AsmToken Token = LexToken();
@@ -509,13 +507,6 @@ size_t AsmLexer::peekTokens(MutableArrayRef<AsmToken> Buf,
   }
 
   SetError(SavedErrLoc, SavedErr);
-
-  SkipSpace = SavedSkipSpace;
-  IsAtStartOfLine = SavedAtStartOfLine;
-  IsAtStartOfStatement = SavedAtStartOfStatement;
-  CurPtr = SavedCurPtr;
-  TokStart = SavedTokStart;
-
   return ReadCount;
 }
 
@@ -525,7 +516,7 @@ bool AsmLexer::isAtStartOfComment(const char *Ptr) {
   if (CommentString[1] == '\0')
     return CommentString[0] == Ptr[0];
 
-  // FIXME: special case for the bogus "##" comment string in X86MCAsmInfoDarwin
+  // Allow # preprocessor commments also be counted as comments for "##" cases
   if (CommentString[1] == '#')
     return CommentString[0] == Ptr[0];
 
@@ -542,7 +533,7 @@ AsmToken AsmLexer::LexToken() {
   // This always consumes at least one character.
   int CurChar = getNextChar();
 
-  if (CurChar == '#' && IsAtStartOfStatement) {
+  if (!IsPeeking && CurChar == '#' && IsAtStartOfStatement) {
     // If this starts with a '#', this may be a cpp
     // hash directive and otherwise a line comment.
     AsmToken TokenBuf[2];
diff --git a/test/MC/AsmParser/pr28921.s b/test/MC/AsmParser/pr28921.s
new file mode 100644 (file)
index 0000000..2fbb555
--- /dev/null
@@ -0,0 +1,8 @@
+// RUN: llvm-mc -triple i386-unknown-unknown %s
+
+# 1 "kernel.S"
+# 1 "<built-in>" 1
+# 1 "kernel.S" 2
+##
+# 10 "kernel.S"
+##