r357823 - [Lexer] NFC: Fix an off-by-one bug in getAsCharRange().

Artem Dergachev via cfe-commits cfe-commits at lists.llvm.org
Fri Apr 5 14:48:52 PDT 2019


Author: dergachev
Date: Fri Apr  5 14:48:52 2019
New Revision: 357823

URL: http://llvm.org/viewvc/llvm-project?rev=357823&view=rev
Log:
[Lexer] NFC: Fix an off-by-one bug in getAsCharRange().

As the unit test demonstrates, subtracting 1 from the offset was unnecessary.

The only user of this function was the plist file emitter (in Static Analyzer
and ARCMigrator). It means that a lot of Static Analyzer's plist arrows
are in fact off by one character. The patch carefully preserves this
completely incorrect behavior and causes no functional change,
i.e. no plist format breakage.

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

Modified:
    cfe/trunk/include/clang/Basic/PlistSupport.h
    cfe/trunk/include/clang/Lex/Lexer.h
    cfe/trunk/unittests/Lex/LexerTest.cpp

Modified: cfe/trunk/include/clang/Basic/PlistSupport.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/PlistSupport.h?rev=357823&r1=357822&r2=357823&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/PlistSupport.h (original)
+++ cfe/trunk/include/clang/Basic/PlistSupport.h Fri Apr  5 14:48:52 2019
@@ -127,7 +127,11 @@ inline void EmitRange(raw_ostream &o, co
   assert(R.isCharRange() && "cannot handle a token range");
   Indent(o, indent) << "<array>\n";
   EmitLocation(o, SM, R.getBegin(), FM, indent + 1);
-  EmitLocation(o, SM, R.getEnd(), FM, indent + 1);
+
+  // The ".getLocWithOffset(-1)" emulates the behavior of an off-by-one bug
+  // in Lexer that is already fixed. It is here for backwards compatibility
+  // even though it is incorrect.
+  EmitLocation(o, SM, R.getEnd().getLocWithOffset(-1), FM, indent + 1);
   Indent(o, indent) << "</array>\n";
 }
 

Modified: cfe/trunk/include/clang/Lex/Lexer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Lexer.h?rev=357823&r1=357822&r2=357823&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/Lexer.h (original)
+++ cfe/trunk/include/clang/Lex/Lexer.h Fri Apr  5 14:48:52 2019
@@ -382,7 +382,7 @@ public:
     SourceLocation End = getLocForEndOfToken(Range.getEnd(), 0, SM, LangOpts);
     return End.isInvalid() ? CharSourceRange()
                            : CharSourceRange::getCharRange(
-                                 Range.getBegin(), End.getLocWithOffset(-1));
+                                 Range.getBegin(), End);
   }
   static CharSourceRange getAsCharRange(CharSourceRange Range,
                                         const SourceManager &SM,

Modified: cfe/trunk/unittests/Lex/LexerTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Lex/LexerTest.cpp?rev=357823&r1=357822&r2=357823&view=diff
==============================================================================
--- cfe/trunk/unittests/Lex/LexerTest.cpp (original)
+++ cfe/trunk/unittests/Lex/LexerTest.cpp Fri Apr  5 14:48:52 2019
@@ -513,4 +513,23 @@ TEST_F(LexerTest, StringizingRasString)
   EXPECT_EQ(String6, R"(a\\\n\n\n    \\\\b)");
 }
 
+TEST_F(LexerTest, CharRangeOffByOne) {
+  std::vector<Token> toks = Lex(R"(#define MOO 1
+    void foo() { MOO; })");
+  const Token &moo = toks[5];
+
+  EXPECT_EQ(getSourceText(moo, moo), "MOO");
+
+  SourceRange R{moo.getLocation(), moo.getLocation()};
+
+  EXPECT_TRUE(
+      Lexer::isAtStartOfMacroExpansion(R.getBegin(), SourceMgr, LangOpts));
+  EXPECT_TRUE(
+      Lexer::isAtEndOfMacroExpansion(R.getEnd(), SourceMgr, LangOpts));
+
+  CharSourceRange CR = Lexer::getAsCharRange(R, SourceMgr, LangOpts);
+
+  EXPECT_EQ(Lexer::getSourceText(CR, SourceMgr, LangOpts), "MOO"); // Was "MO".
+}
+
 } // anonymous namespace




More information about the cfe-commits mailing list