]> granicus.if.org Git - clang/commitdiff
[analyzer] Use lazily created buffer in EmptyLocalizationContextChecker
authorDevin Coughlin <dcoughlin@apple.com>
Tue, 30 Aug 2016 23:07:14 +0000 (23:07 +0000)
committerDevin Coughlin <dcoughlin@apple.com>
Tue, 30 Aug 2016 23:07:14 +0000 (23:07 +0000)
Fix a crash when relexing the underlying memory buffer to find incorrect
arguments to NSLocalizedString(). With precompiled headers, the raw
buffer may be NULL. Instead, use the source manager to get the buffer,
which will lazily create the buffer for precompiled headers.

rdar://problem/27429091

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

lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp
test/Analysis/Inputs/localization-pch.h [new file with mode: 0644]
test/Analysis/localization-aggressive.m

index 1386f97cda5eccc3f5454f9ae07e6d8de0b210ba..d1dab6d27d45f6a47315f7381a72da9855d682d8 100644 (file)
@@ -1016,6 +1016,8 @@ void EmptyLocalizationContextChecker::checkASTDecl(
 void EmptyLocalizationContextChecker::MethodCrawler::VisitObjCMessageExpr(
     const ObjCMessageExpr *ME) {
 
+  // FIXME: We may be able to use PPCallbacks to check for empy context
+  // comments as part of preprocessing and avoid this re-lexing hack.
   const ObjCInterfaceDecl *OD = ME->getReceiverInterface();
   if (!OD)
     return;
@@ -1050,7 +1052,12 @@ void EmptyLocalizationContextChecker::MethodCrawler::VisitObjCMessageExpr(
     SE = Mgr.getSourceManager().getSLocEntry(SLInfo.first);
   }
 
-  llvm::MemoryBuffer *BF = SE.getFile().getContentCache()->getRawBuffer();
+  bool Invalid = false;
+  llvm::MemoryBuffer *BF =
+      Mgr.getSourceManager().getBuffer(SLInfo.first, SL, &Invalid);
+  if (Invalid)
+    return;
+
   Lexer TheLexer(SL, LangOptions(), BF->getBufferStart(),
                  BF->getBufferStart() + SLInfo.second, BF->getBufferEnd());
 
diff --git a/test/Analysis/Inputs/localization-pch.h b/test/Analysis/Inputs/localization-pch.h
new file mode 100644 (file)
index 0000000..973270e
--- /dev/null
@@ -0,0 +1,5 @@
+// Used to test missing checker for missing localization context comments
+// in precompiled headers.
+
+#define MyLocalizedStringInPCH(key) NSLocalizedString((key), @"")
+
index 79c9c13312121f2ea1596589f55cc2cb566ed2a5..89950d4eed747012445c74b6c98a872e275b2755 100644 (file)
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 -analyze -fblocks -analyzer-store=region  -analyzer-checker=optin.osx.cocoa.localizability.NonLocalizedStringChecker -analyzer-checker=optin.osx.cocoa.localizability.EmptyLocalizationContextChecker -verify  -analyzer-config AggressiveReport=true %s
+// RUN: %clang_cc1 -fblocks -x objective-c-header -emit-pch -o %t.pch %S/Inputs/localization-pch.h
+
+// RUN: %clang_cc1 -analyze -fblocks -analyzer-store=region  -analyzer-checker=optin.osx.cocoa.localizability.NonLocalizedStringChecker -analyzer-checker=optin.osx.cocoa.localizability.EmptyLocalizationContextChecker -include-pch %t.pch -verify  -analyzer-config AggressiveReport=true %s
 
 // These declarations were reduced using Delta-Debugging from Foundation.h
 // on Mac OS X.
@@ -249,6 +251,10 @@ NSString *ForceLocalized(NSString *str) { return str; }
   NSString *string3 = NSLocalizedString((0 ? @"Critical" : @"Current"),nil); // expected-warning {{Localized string macro should include a non-empty comment for translators}}
 }
 
+- (void)testMacroExpansionDefinedInPCH {
+  NSString *string = MyLocalizedStringInPCH(@"Hello"); // expected-warning {{Localized string macro should include a non-empty comment for translators}}
+}
+
 #define KCLocalizedString(x,comment) NSLocalizedString(x, comment)
 #define POSSIBLE_FALSE_POSITIVE(s,other) KCLocalizedString(s,@"Comment")