r244394 - Revert "[analyzer] Add checkers for OS X / iOS localizability issues"

Anna Zaks via cfe-commits cfe-commits at lists.llvm.org
Fri Aug 7 21:53:04 PDT 2015


Author: zaks
Date: Fri Aug  7 23:53:04 2015
New Revision: 244394

URL: http://llvm.org/viewvc/llvm-project?rev=244394&view=rev
Log:
Revert "[analyzer] Add checkers for OS X / iOS localizability issues"

This reverts commit fc885033a30b6e30ccf82398ae7c30e646727b10.

Revert all localization checker commits until the proper fix is implemented.

Removed:
    cfe/trunk/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp
    cfe/trunk/test/Analysis/localization-aggressive.m
    cfe/trunk/test/Analysis/localization.m
Modified:
    cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt
    cfe/trunk/lib/StaticAnalyzer/Checkers/Checkers.td

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt?rev=244394&r1=244393&r2=244394&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt Fri Aug  7 23:53:04 2015
@@ -39,7 +39,6 @@ add_clang_library(clangStaticAnalyzerChe
   IdenticalExprChecker.cpp
   IvarInvalidationChecker.cpp
   LLVMConventionsChecker.cpp
-  LocalizationChecker.cpp
   MacOSKeychainAPIChecker.cpp
   MacOSXAPIChecker.cpp
   MallocChecker.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/Checkers.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/Checkers.td?rev=244394&r1=244393&r2=244394&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/Checkers.td (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/Checkers.td Fri Aug  7 23:53:04 2015
@@ -452,14 +452,6 @@ def DirectIvarAssignmentForAnnotatedFunc
   HelpText<"Check for direct assignments to instance variables in the methods annotated with objc_no_direct_instance_variable_assignment">,
   DescFile<"DirectIvarAssignment.cpp">;
 
-def NonLocalizedStringChecker : Checker<"NonLocalizedStringChecker">,
-  HelpText<"Warns about uses of non-localized NSStrings passed to UI methods expecting localized NSStrings">,
-  DescFile<"LocalizationChecker.cpp">;
-
-def EmptyLocalizationContextChecker : Checker<"EmptyLocalizationContextChecker">,
-  HelpText<"Check that NSLocalizedString macros include a comment for context">,
-  DescFile<"LocalizationChecker.cpp">;
-
 } // end "alpha.osx.cocoa"
 
 let ParentPackage = CoreFoundation in {

Removed: cfe/trunk/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp?rev=244393&view=auto
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp (removed)
@@ -1,559 +0,0 @@
-//=- LocalizationChecker.cpp -------------------------------------*- C++ -*-==//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-//  This file defines a set of checks for localizability including:
-//  1) A checker that warns about uses of non-localized NSStrings passed to
-//     UI methods expecting localized strings
-//  2) A syntactic checker that warns against the bad practice of
-//     not including a comment in NSLocalizedString macros.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ClangSACheckers.h"
-#include "SelectorExtras.h"
-#include "clang/AST/Attr.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
-#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
-#include "clang/StaticAnalyzer/Core/Checker.h"
-#include "clang/StaticAnalyzer/Core/CheckerManager.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
-#include "clang/Lex/Lexer.h"
-#include "clang/AST/RecursiveASTVisitor.h"
-#include "clang/AST/StmtVisitor.h"
-#include "llvm/Support/Unicode.h"
-
-using namespace clang;
-using namespace ento;
-
-namespace {
-struct LocalizedState {
-private:
-  enum Kind { NonLocalized, Localized } K;
-  LocalizedState(Kind InK) : K(InK) {}
-
-public:
-  bool isLocalized() const { return K == Localized; }
-  bool isNonLocalized() const { return K == NonLocalized; }
-
-  static LocalizedState getLocalized() { return LocalizedState(Localized); }
-  static LocalizedState getNonLocalized() {
-    return LocalizedState(NonLocalized);
-  }
-
-  // Overload the == operator
-  bool operator==(const LocalizedState &X) const { return K == X.K; }
-
-  // LLVMs equivalent of a hash function
-  void Profile(llvm::FoldingSetNodeID &ID) const { ID.AddInteger(K); }
-};
-
-class NonLocalizedStringChecker
-    : public Checker<check::PostCall, check::PreObjCMessage,
-                     check::PostObjCMessage,
-                     check::PostStmt<ObjCStringLiteral>> {
-
-  mutable std::unique_ptr<BugType> BT;
-
-  // Methods that require a localized string
-  mutable std::map<StringRef, std::map<StringRef, uint8_t>> UIMethods;
-  // Methods that return a localized string
-  mutable llvm::SmallSet<std::pair<StringRef, StringRef>, 10> LSM;
-  // C Functions that return a localized string
-  mutable llvm::StringMap<char> LSF;
-
-  void initUIMethods(ASTContext &Ctx) const;
-  void initLocStringsMethods(ASTContext &Ctx) const;
-
-  bool hasNonLocalizedState(SVal S, CheckerContext &C) const;
-  bool hasLocalizedState(SVal S, CheckerContext &C) const;
-  void setNonLocalizedState(SVal S, CheckerContext &C) const;
-  void setLocalizedState(SVal S, CheckerContext &C) const;
-
-  bool isAnnotatedAsLocalized(const Decl *D) const;
-  void reportLocalizationError(SVal S, const ObjCMethodCall &M,
-                               CheckerContext &C, int argumentNumber = 0) const;
-
-public:
-  NonLocalizedStringChecker();
-
-  // When this parameter is set to true, the checker assumes all
-  // methods that return NSStrings are unlocalized. Thus, more false
-  // positives will be reported.
-  DefaultBool IsAggressive;
-
-  void checkPreObjCMessage(const ObjCMethodCall &msg, CheckerContext &C) const;
-  void checkPostObjCMessage(const ObjCMethodCall &msg, CheckerContext &C) const;
-  void checkPostStmt(const ObjCStringLiteral *SL, CheckerContext &C) const;
-  void checkPostCall(const CallEvent &Call, CheckerContext &C) const;
-};
-
-} // end anonymous namespace
-
-REGISTER_MAP_WITH_PROGRAMSTATE(LocalizedMemMap, const MemRegion *,
-                               LocalizedState)
-
-NonLocalizedStringChecker::NonLocalizedStringChecker() {
-  BT.reset(new BugType(this, "Unlocalized string", "Localizability Error"));
-}
-
-/// Initializes a list of methods that require a localized string
-/// Format: {"ClassName", {{"selectorName:", LocStringArg#}, ...}, ...}
-void NonLocalizedStringChecker::initUIMethods(ASTContext &Ctx) const {
-  if (!UIMethods.empty())
-    return;
-
-  // TODO: This should eventually be a comprehensive list of UIKit methods
-
-  UIMethods = {{"UILabel", {{"setText:", 0}}},
-               {"UIButton", {{"setText:", 0}}},
-               {"NSButton", {{"setTitle:", 0}}},
-               {"NSButtonCell", {{"setTitle:", 0}}},
-               {"NSMenuItem", {{"setTitle:", 0}}},
-               {"UIAlertAction", {{"actionWithTitle:style:handler:", 0}}},
-               {"UIAlertController",
-                {{"alertControllerWithTitle:message:preferredStyle:", 1}}},
-               {"NSAttributedString",
-                {{"initWithString:", 0}, {"initWithString:attributes:", 0}}}};
-}
-
-/// Initializes a list of methods and C functions that return a localized string
-void NonLocalizedStringChecker::initLocStringsMethods(ASTContext &Ctx) const {
-  if (!LSM.empty())
-    return;
-
-  LSM.insert({"NSBundle", "localizedStringForKey:value:table:"});
-  LSM.insert({"NSDateFormatter", "stringFromDate:"});
-  LSM.insert(
-      {"NSDateFormatter", "localizedStringFromDate:dateStyle:timeStyle:"});
-  LSM.insert({"NSNumberFormatter", "stringFromNumber:"});
-  LSM.insert({"UITextField", "text"});
-  LSM.insert({"UITextView", "text"});
-  LSM.insert({"UILabel", "text"});
-
-  LSF.insert({"CFDateFormatterCreateStringWithDate", '\0'});
-  LSF.insert({"CFDateFormatterCreateStringWithAbsoluteTime", '\0'});
-  LSF.insert({"CFNumberFormatterCreateStringWithNumber", '\0'});
-}
-
-/// Checks to see if the method / function declaration includes
-/// __attribute__((annotate("returns_localized_nsstring")))
-bool NonLocalizedStringChecker::isAnnotatedAsLocalized(const Decl *D) const {
-  return std::any_of(
-      D->specific_attr_begin<AnnotateAttr>(),
-      D->specific_attr_end<AnnotateAttr>(), [](const AnnotateAttr *Ann) {
-        return Ann->getAnnotation() == "returns_localized_nsstring";
-      });
-}
-
-/// Returns true if the given SVal is marked as Localized in the program state
-bool NonLocalizedStringChecker::hasLocalizedState(SVal S,
-                                                  CheckerContext &C) const {
-  const MemRegion *mt = S.getAsRegion();
-  if (mt) {
-    const LocalizedState *LS = C.getState()->get<LocalizedMemMap>(mt);
-    if (LS && LS->isLocalized())
-      return true;
-  }
-  return false;
-}
-
-/// Returns true if the given SVal is marked as NonLocalized in the program
-/// state
-bool NonLocalizedStringChecker::hasNonLocalizedState(SVal S,
-                                                     CheckerContext &C) const {
-  const MemRegion *mt = S.getAsRegion();
-  if (mt) {
-    const LocalizedState *LS = C.getState()->get<LocalizedMemMap>(mt);
-    if (LS && LS->isNonLocalized())
-      return true;
-  }
-  return false;
-}
-
-/// Marks the given SVal as Localized in the program state
-void NonLocalizedStringChecker::setLocalizedState(const SVal S,
-                                                  CheckerContext &C) const {
-  const MemRegion *mt = S.getAsRegion();
-  if (mt) {
-    ProgramStateRef State =
-        C.getState()->set<LocalizedMemMap>(mt, LocalizedState::getLocalized());
-    C.addTransition(State);
-  }
-}
-
-/// Marks the given SVal as NonLocalized in the program state
-void NonLocalizedStringChecker::setNonLocalizedState(const SVal S,
-                                                     CheckerContext &C) const {
-  const MemRegion *mt = S.getAsRegion();
-  if (mt) {
-    ProgramStateRef State = C.getState()->set<LocalizedMemMap>(
-        mt, LocalizedState::getNonLocalized());
-    C.addTransition(State);
-  }
-}
-
-/// Reports a localization error for the passed in method call and SVal
-void NonLocalizedStringChecker::reportLocalizationError(
-    SVal S, const ObjCMethodCall &M, CheckerContext &C,
-    int argumentNumber) const {
-
-  ExplodedNode *ErrNode = C.getPredecessor();
-  static CheckerProgramPointTag Tag("NonLocalizedStringChecker",
-                                    "UnlocalizedString");
-  ErrNode = C.addTransition(C.getState(), C.getPredecessor(), &Tag);
-
-  if (!ErrNode)
-    return;
-
-  // Generate the bug report.
-  std::unique_ptr<BugReport> R(
-      new BugReport(*BT, "String should be localized", ErrNode));
-  if (argumentNumber) {
-    R->addRange(M.getArgExpr(argumentNumber - 1)->getSourceRange());
-  } else {
-    R->addRange(M.getSourceRange());
-  }
-  R->markInteresting(S);
-  C.emitReport(std::move(R));
-}
-
-/// Check if the string being passed in has NonLocalized state
-void NonLocalizedStringChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
-                                                    CheckerContext &C) const {
-  initUIMethods(C.getASTContext());
-
-  const ObjCInterfaceDecl *OD = msg.getReceiverInterface();
-  if (!OD)
-    return;
-  const IdentifierInfo *odInfo = OD->getIdentifier();
-
-  Selector S = msg.getSelector();
-
-  StringRef Name(S.getAsString());
-  assert(!Name.empty());
-
-  auto method = UIMethods.find(odInfo->getName());
-  if (odInfo->isStr("NSString")) {
-    // Handle the case where the receiver is an NSString
-    // These special NSString methods draw to the screen
-
-    if (!(Name.startswith("drawAtPoint") || Name.startswith("drawInRect") ||
-          Name.startswith("drawWithRect")))
-      return;
-
-    SVal svTitle = msg.getReceiverSVal();
-
-    bool isNonLocalized = hasNonLocalizedState(svTitle, C);
-
-    if (isNonLocalized) {
-      reportLocalizationError(svTitle, msg, C);
-    }
-  } else if (method != UIMethods.end()) {
-
-    std::map<StringRef, uint8_t> m = method->second;
-
-    auto argumentIterator = m.find(Name);
-
-    if (argumentIterator == m.end())
-      return;
-
-    int argumentNumber = argumentIterator->second;
-
-    SVal svTitle = msg.getArgSVal(argumentNumber);
-
-    if (const ObjCStringRegion *SR =
-            dyn_cast_or_null<ObjCStringRegion>(svTitle.getAsRegion())) {
-      StringRef stringValue =
-          SR->getObjCStringLiteral()->getString()->getString();
-      if ((stringValue.trim().size() == 0 && stringValue.size() > 0) ||
-          stringValue.empty())
-        return;
-      if (!IsAggressive && llvm::sys::unicode::columnWidthUTF8(stringValue) < 2)
-        return;
-    }
-
-    bool isNonLocalized = hasNonLocalizedState(svTitle, C);
-
-    if (isNonLocalized) {
-      reportLocalizationError(svTitle, msg, C, argumentNumber + 1);
-    }
-  }
-}
-
-static inline bool isNSStringType(QualType T, ASTContext &Ctx) {
-
-  const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
-  if (!PT)
-    return false;
-
-  ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface();
-  if (!Cls)
-    return false;
-
-  IdentifierInfo *ClsName = Cls->getIdentifier();
-
-  // FIXME: Should we walk the chain of classes?
-  return ClsName == &Ctx.Idents.get("NSString") ||
-         ClsName == &Ctx.Idents.get("NSMutableString");
-}
-
-/// Marks a string being returned by any call as localized
-/// if it is in LocStringFunctions (LSF) or the function is annotated.
-/// Otherwise, we mark it as NonLocalized (Aggressive) or
-/// NonLocalized only if it is not backed by a SymRegion (Non-Aggressive),
-/// basically leaving only string literals as NonLocalized.
-void NonLocalizedStringChecker::checkPostCall(const CallEvent &Call,
-                                              CheckerContext &C) const {
-  initLocStringsMethods(C.getASTContext());
-
-  if (!Call.getOriginExpr())
-    return;
-
-  // Anything that takes in a localized NSString as an argument
-  // and returns an NSString will be assumed to be returning a
-  // localized NSString. (Counter: Incorrectly combining two LocalizedStrings)
-  const QualType RT = Call.getResultType();
-  if (isNSStringType(RT, C.getASTContext())) {
-    for (unsigned i = 0; i < Call.getNumArgs(); ++i) {
-      SVal argValue = Call.getArgSVal(i);
-      if (hasLocalizedState(argValue, C)) {
-        SVal sv = Call.getReturnValue();
-        setLocalizedState(sv, C);
-        return;
-      }
-    }
-  }
-
-  const Decl *D = Call.getDecl();
-  if (!D)
-    return;
-
-  StringRef IdentifierName = C.getCalleeName(D->getAsFunction());
-
-  SVal sv = Call.getReturnValue();
-  if (isAnnotatedAsLocalized(D) || LSF.find(IdentifierName) != LSF.end()) {
-    setLocalizedState(sv, C);
-  } else if (isNSStringType(RT, C.getASTContext()) &&
-             !hasLocalizedState(sv, C)) {
-    if (IsAggressive) {
-      setNonLocalizedState(sv, C);
-    } else {
-      const SymbolicRegion *SymReg =
-          dyn_cast_or_null<SymbolicRegion>(sv.getAsRegion());
-      if (!SymReg)
-        setNonLocalizedState(sv, C);
-    }
-  }
-}
-
-/// Marks a string being returned by an ObjC method as localized
-/// if it is in LocStringMethods or the method is annotated
-void NonLocalizedStringChecker::checkPostObjCMessage(const ObjCMethodCall &msg,
-                                                     CheckerContext &C) const {
-  initLocStringsMethods(C.getASTContext());
-
-  if (!msg.isInstanceMessage())
-    return;
-
-  const ObjCInterfaceDecl *OD = msg.getReceiverInterface();
-  if (!OD)
-    return;
-  const IdentifierInfo *odInfo = OD->getIdentifier();
-
-  StringRef IdentifierName = odInfo->getName();
-
-  Selector S = msg.getSelector();
-  StringRef SelectorName = S.getAsString();
-  assert(!SelectorName.empty());
-
-  std::pair<StringRef, StringRef> MethodDescription = {IdentifierName,
-                                                       SelectorName};
-
-  if (LSM.count(MethodDescription) || isAnnotatedAsLocalized(msg.getDecl())) {
-    SVal sv = msg.getReturnValue();
-    setLocalizedState(sv, C);
-  }
-}
-
-/// Marks all empty string literals as localized
-void NonLocalizedStringChecker::checkPostStmt(const ObjCStringLiteral *SL,
-                                              CheckerContext &C) const {
-  SVal sv = C.getSVal(SL);
-  setNonLocalizedState(sv, C);
-}
-
-namespace {
-class EmptyLocalizationContextChecker
-    : public Checker<check::ASTDecl<ObjCImplementationDecl>> {
-
-  // A helper class, which walks the AST
-  class MethodCrawler : public ConstStmtVisitor<MethodCrawler> {
-    const ObjCMethodDecl *MD;
-    BugReporter &BR;
-    AnalysisManager &Mgr;
-    const CheckerBase *Checker;
-    LocationOrAnalysisDeclContext DCtx;
-
-  public:
-    MethodCrawler(const ObjCMethodDecl *InMD, BugReporter &InBR,
-                  const CheckerBase *Checker, AnalysisManager &InMgr,
-                  AnalysisDeclContext *InDCtx)
-        : MD(InMD), BR(InBR), Mgr(InMgr), Checker(Checker), DCtx(InDCtx) {}
-
-    void VisitStmt(const Stmt *S) { VisitChildren(S); }
-
-    void VisitObjCMessageExpr(const ObjCMessageExpr *ME);
-
-    void reportEmptyContextError(const ObjCMessageExpr *M) const;
-
-    void VisitChildren(const Stmt *S) {
-      for (const Stmt *Child : S->children()) {
-        if (Child)
-          this->Visit(Child);
-      }
-    }
-  };
-
-public:
-  void checkASTDecl(const ObjCImplementationDecl *D, AnalysisManager &Mgr,
-                    BugReporter &BR) const;
-};
-} // end anonymous namespace
-
-void EmptyLocalizationContextChecker::checkASTDecl(
-    const ObjCImplementationDecl *D, AnalysisManager &Mgr,
-    BugReporter &BR) const {
-
-  for (const ObjCMethodDecl *M : D->methods()) {
-    AnalysisDeclContext *DCtx = Mgr.getAnalysisDeclContext(M);
-
-    const Stmt *Body = M->getBody();
-    assert(Body);
-
-    MethodCrawler MC(M->getCanonicalDecl(), BR, this, Mgr, DCtx);
-    MC.VisitStmt(Body);
-  }
-}
-
-/// This check attempts to match these macros, assuming they are defined as
-/// follows:
-///
-/// #define NSLocalizedString(key, comment) \
-/// [[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:nil]
-/// #define NSLocalizedStringFromTable(key, tbl, comment) \
-/// [[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:(tbl)]
-/// #define NSLocalizedStringFromTableInBundle(key, tbl, bundle, comment) \
-/// [bundle localizedStringForKey:(key) value:@"" table:(tbl)]
-/// #define NSLocalizedStringWithDefaultValue(key, tbl, bundle, val, comment)
-///
-/// We cannot use the path sensitive check because the macro argument we are
-/// checking for (comment) is not used and thus not present in the AST,
-/// so we use Lexer on the original macro call and retrieve the value of
-/// the comment. If it's empty or nil, we raise a warning.
-void EmptyLocalizationContextChecker::MethodCrawler::VisitObjCMessageExpr(
-    const ObjCMessageExpr *ME) {
-
-  const ObjCInterfaceDecl *OD = ME->getReceiverInterface();
-  if (!OD)
-    return;
-
-  const IdentifierInfo *odInfo = OD->getIdentifier();
-
-  if (!(odInfo->isStr("NSBundle") ||
-        StringRef(ME->getSelector().getAsString())
-            .equals("localizedStringForKey:value:table:"))) {
-    return;
-  }
-
-  SourceRange R = ME->getSourceRange();
-  if (!R.getBegin().isMacroID())
-    return;
-
-  // getImmediateMacroCallerLoc gets the location of the immediate macro
-  // caller, one level up the stack toward the initial macro typed into the
-  // source, so SL should point to the NSLocalizedString macro.
-  SourceLocation SL =
-      Mgr.getSourceManager().getImmediateMacroCallerLoc(R.getBegin());
-  std::pair<FileID, unsigned> SLInfo =
-      Mgr.getSourceManager().getDecomposedLoc(SL);
-
-  SrcMgr::SLocEntry SE = Mgr.getSourceManager().getSLocEntry(SLInfo.first);
-
-  // If NSLocalizedString macro is wrapped in another macro, we need to
-  // unwrap the expansion until we get to the NSLocalizedStringMacro.
-  while (SE.isExpansion()) {
-    SL = SE.getExpansion().getSpellingLoc();
-    SLInfo = Mgr.getSourceManager().getDecomposedLoc(SL);
-    SE = Mgr.getSourceManager().getSLocEntry(SLInfo.first);
-  }
-
-  llvm::MemoryBuffer *BF = SE.getFile().getContentCache()->getRawBuffer();
-  Lexer TheLexer(SL, LangOptions(), BF->getBufferStart(),
-                 BF->getBufferStart() + SLInfo.second, BF->getBufferEnd());
-
-  Token I;
-  Token Result;    // This will hold the token just before the last ')'
-  int p_count = 0; // This is for parenthesis matching
-  while (!TheLexer.LexFromRawLexer(I)) {
-    if (I.getKind() == tok::l_paren)
-      ++p_count;
-    if (I.getKind() == tok::r_paren) {
-      if (p_count == 1)
-        break;
-      --p_count;
-    }
-    Result = I;
-  }
-
-  if (isAnyIdentifier(Result.getKind())) {
-    if (Result.getRawIdentifier().equals("nil")) {
-      reportEmptyContextError(ME);
-      return;
-    }
-  }
-
-  if (!isStringLiteral(Result.getKind()))
-    return;
-
-  StringRef Comment =
-      StringRef(Result.getLiteralData(), Result.getLength()).trim("\"");
-
-  if ((Comment.trim().size() == 0 && Comment.size() > 0) || // Is Whitespace
-      Comment.empty()) {
-    reportEmptyContextError(ME);
-  }
-}
-
-void EmptyLocalizationContextChecker::MethodCrawler::reportEmptyContextError(
-    const ObjCMessageExpr *ME) const {
-  // Generate the bug report.
-  BR.EmitBasicReport(MD, Checker, "Context Missing", "Localizability Error",
-                     "Localized string macro should include a non-empty "
-                     "comment for translators",
-                     PathDiagnosticLocation(ME, BR.getSourceManager(), DCtx));
-}
-
-//===----------------------------------------------------------------------===//
-// Checker registration.
-//===----------------------------------------------------------------------===//
-
-void ento::registerNonLocalizedStringChecker(CheckerManager &mgr) {
-  NonLocalizedStringChecker *checker =
-      mgr.registerChecker<NonLocalizedStringChecker>();
-  checker->IsAggressive =
-      mgr.getAnalyzerOptions().getBooleanOption("AggressiveReport", false);
-}
-
-void ento::registerEmptyLocalizationContextChecker(CheckerManager &mgr) {
-  mgr.registerChecker<EmptyLocalizationContextChecker>();
-}
\ No newline at end of file

Removed: cfe/trunk/test/Analysis/localization-aggressive.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/localization-aggressive.m?rev=244393&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/localization-aggressive.m (original)
+++ cfe/trunk/test/Analysis/localization-aggressive.m (removed)
@@ -1,243 +0,0 @@
-// RUN: %clang_cc1 -analyze -fblocks -analyzer-store=region  -analyzer-checker=alpha.osx.cocoa.NonLocalizedStringChecker -analyzer-checker=alpha.osx.cocoa.EmptyLocalizationContextChecker -verify  -analyzer-config AggressiveReport=true %s
-
-// These declarations were reduced using Delta-Debugging from Foundation.h
-// on Mac OS X.
-
-#define nil ((id)0)
-#define NSLocalizedString(key, comment)                                        \
-  [[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:nil]
-#define NSLocalizedStringFromTable(key, tbl, comment)                          \
-  [[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:(tbl)]
-#define NSLocalizedStringFromTableInBundle(key, tbl, bundle, comment)          \
-  [bundle localizedStringForKey:(key) value:@"" table:(tbl)]
-#define NSLocalizedStringWithDefaultValue(key, tbl, bundle, val, comment)      \
-  [bundle localizedStringForKey:(key) value:(val) table:(tbl)]
-#define CGFLOAT_TYPE double
-typedef CGFLOAT_TYPE CGFloat;
-struct CGPoint {
-  CGFloat x;
-  CGFloat y;
-};
-typedef struct CGPoint CGPoint;
- at interface NSObject
-+ (id)alloc;
-- (id)init;
- at end
- at class NSDictionary;
- at interface NSString : NSObject
-- (void)drawAtPoint:(CGPoint)point withAttributes:(NSDictionary *)attrs;
-+ (instancetype)localizedStringWithFormat:(NSString *)format, ...;
- at end
- at interface NSBundle : NSObject
-+ (NSBundle *)mainBundle;
-- (NSString *)localizedStringForKey:(NSString *)key
-                              value:(NSString *)value
-                              table:(NSString *)tableName;
- at end
- at interface UILabel : NSObject
- at property(nullable, nonatomic, copy) NSString *text;
-- (void)accessibilitySetIdentification:(NSString *)ident;
- at end
- at interface TestObject : NSObject
- at property(strong) NSString *text;
- at end
-
- at interface LocalizationTestSuite : NSObject
-NSString *ForceLocalized(NSString *str)
-    __attribute__((annotate("returns_localized_nsstring")));
-CGPoint CGPointMake(CGFloat x, CGFloat y);
-int random();
-// This next one is a made up API
-NSString *CFNumberFormatterCreateStringWithNumber(float x);
-+ (NSString *)forceLocalized:(NSString *)str
-    __attribute__((annotate("returns_localized_nsstring")));
- at end
-
-// Test cases begin here
- at implementation LocalizationTestSuite
-
-// A C-Funtion that returns a localized string because it has the
-// "returns_localized_nsstring" annotation
-NSString *ForceLocalized(NSString *str) { return str; }
-// An ObjC method that returns a localized string because it has the
-// "returns_localized_nsstring" annotation
-+ (NSString *)forceLocalized:(NSString *)str {
-  return str;
-}
-
-// An ObjC method that returns a localized string
-+ (NSString *)unLocalizedStringMethod {
-  return @"UnlocalizedString";
-}
-
-- (void)testLocalizationErrorDetectedOnPathway {
-  UILabel *testLabel = [[UILabel alloc] init];
-  NSString *bar = NSLocalizedString(@"Hello", @"Comment");
-
-  if (random()) {
-    bar = @"Unlocalized string";
-  }
-
-  [testLabel setText:bar]; // expected-warning {{String should be localized}}
-}
-
-- (void)testLocalizationErrorDetectedOnNSString {
-  NSString *bar = NSLocalizedString(@"Hello", @"Comment");
-
-  if (random()) {
-    bar = @"Unlocalized string";
-  }
-
-  [bar drawAtPoint:CGPointMake(0, 0) withAttributes:nil]; // expected-warning {{String should be localized}}
-}
-
-- (void)testNoLocalizationErrorDetectedFromCFunction {
-  UILabel *testLabel = [[UILabel alloc] init];
-  NSString *bar = CFNumberFormatterCreateStringWithNumber(1);
-
-  [testLabel setText:bar]; // no-warning
-}
-
-- (void)testAnnotationAddsLocalizedStateForCFunction {
-  UILabel *testLabel = [[UILabel alloc] init];
-  NSString *bar = NSLocalizedString(@"Hello", @"Comment");
-
-  if (random()) {
-    bar = @"Unlocalized string";
-  }
-
-  [testLabel setText:ForceLocalized(bar)]; // no-warning
-}
-
-- (void)testAnnotationAddsLocalizedStateForObjCMethod {
-  UILabel *testLabel = [[UILabel alloc] init];
-  NSString *bar = NSLocalizedString(@"Hello", @"Comment");
-
-  if (random()) {
-    bar = @"Unlocalized string";
-  }
-
-  [testLabel setText:[LocalizationTestSuite forceLocalized:bar]]; // no-warning
-}
-
-// An empty string literal @"" should not raise an error
-- (void)testEmptyStringLiteralHasLocalizedState {
-  UILabel *testLabel = [[UILabel alloc] init];
-  NSString *bar = @"";
-
-  [testLabel setText:bar]; // no-warning
-}
-
-// An empty string literal @"" inline should not raise an error
-- (void)testInlineEmptyStringLiteralHasLocalizedState {
-  UILabel *testLabel = [[UILabel alloc] init];
-  [testLabel setText:@""]; // no-warning
-}
-
-// An string literal @"Hello" inline should raise an error
-- (void)testInlineStringLiteralHasLocalizedState {
-  UILabel *testLabel = [[UILabel alloc] init];
-  [testLabel setText:@"Hello"]; // expected-warning {{String should be localized}}
-}
-
-// A nil string should not raise an error
-- (void)testNilStringIsNotMarkedAsUnlocalized {
-  UILabel *testLabel = [[UILabel alloc] init];
-  [testLabel setText:nil]; // no-warning
-}
-
-// A method that takes in a localized string and returns a string
-// most likely that string is localized.
-- (void)testLocalizedStringArgument {
-  UILabel *testLabel = [[UILabel alloc] init];
-  NSString *localizedString = NSLocalizedString(@"Hello", @"Comment");
-
-  NSString *combinedString =
-      [NSString localizedStringWithFormat:@"%@", localizedString];
-
-  [testLabel setText:combinedString]; // no-warning
-}
-
-// A String passed in as a an parameter should not be considered
-// unlocalized
-- (void)testLocalizedStringAsArgument:(NSString *)argumentString {
-  UILabel *testLabel = [[UILabel alloc] init];
-
-  [testLabel setText:argumentString]; // no-warning
-}
-
-// A String passed into another method that calls a method that
-// requires a localized string should give an error
-- (void)localizedStringAsArgument:(NSString *)argumentString {
-  UILabel *testLabel = [[UILabel alloc] init];
-
-  [testLabel setText:argumentString]; // expected-warning {{String should be localized}}
-}
-
-// The warning is expected to be seen in localizedStringAsArgument: body
-- (void)testLocalizedStringAsArgumentOtherMethod:(NSString *)argumentString {
-  [self localizedStringAsArgument:@"UnlocalizedString"];
-}
-
-// [LocalizationTestSuite unLocalizedStringMethod] returns an unlocalized string
-// so we expect an error. Unfrtunately, it probably doesn't make a difference
-// what [LocalizationTestSuite unLocalizedStringMethod] returns since all
-// string values returned are marked as Unlocalized in aggressive reporting.
-- (void)testUnLocalizedStringMethod {
-  UILabel *testLabel = [[UILabel alloc] init];
-  NSString *bar = NSLocalizedString(@"Hello", @"Comment");
-
-  [testLabel setText:[LocalizationTestSuite unLocalizedStringMethod]]; // expected-warning {{String should be localized}}
-}
-
-// This is the reverse situation: accessibilitySetIdentification: doesn't care
-// about localization so we don't expect a warning
-- (void)testMethodNotInRequiresLocalizedStringMethods {
-  UILabel *testLabel = [[UILabel alloc] init];
-
-  [testLabel accessibilitySetIdentification:@"UnlocalizedString"]; // no-warning
-}
-
-// EmptyLocalizationContextChecker tests
-#define HOM(s) YOLOC(s)
-#define YOLOC(x) NSLocalizedString(x, nil)
-
-- (void)testNilLocalizationContext {
-  NSString *string = NSLocalizedString(@"LocalizedString", nil); // expected-warning {{Localized string macro should include a non-empty comment for translators}}
-  NSString *string2 = NSLocalizedString(@"LocalizedString", nil); // expected-warning {{Localized string macro should include a non-empty comment for translators}}
-  NSString *string3 = NSLocalizedString(@"LocalizedString", nil); // expected-warning {{Localized string macro should include a non-empty comment for translators}}
-}
-
-- (void)testEmptyLocalizationContext {
-  NSString *string = NSLocalizedString(@"LocalizedString", @""); // expected-warning {{Localized string macro should include a non-empty comment for translators}}
-  NSString *string2 = NSLocalizedString(@"LocalizedString", @" "); // expected-warning {{Localized string macro should include a non-empty comment for translators}}
-  NSString *string3 = NSLocalizedString(@"LocalizedString", @"	 "); // expected-warning {{Localized string macro should include a non-empty comment for translators}}
-}
-
-- (void)testNSLocalizedStringVariants {
-  NSString *string = NSLocalizedStringFromTable(@"LocalizedString", nil, @""); // expected-warning {{Localized string macro should include a non-empty comment for translators}}
-  NSString *string2 = NSLocalizedStringFromTableInBundle(@"LocalizedString", nil, [[NSBundle alloc] init],@""); // expected-warning {{Localized string macro should include a non-empty comment for translators}}
-  NSString *string3 = NSLocalizedStringWithDefaultValue(@"LocalizedString", nil, [[NSBundle alloc] init], nil,@""); // expected-warning {{Localized string macro should include a non-empty comment for translators}}
-}
-
-- (void)testMacroExpansionNilString {
-  NSString *string = YOLOC(@"Hello"); // expected-warning {{Localized string macro should include a non-empty comment for translators}}
-  NSString *string2 = HOM(@"Hello");  // expected-warning {{Localized string macro should include a non-empty comment for translators}}
-  NSString *string3 = NSLocalizedString((0 ? @"Critical" : @"Current"),nil); // 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")
-
-- (void)testNoWarningForNilCommentPassedIntoOtherMacro {
-  NSString *string = KCLocalizedString(@"Hello",@""); // no-warning
-  NSString *string2 = KCLocalizedString(@"Hello",nil); // no-warning
-  NSString *string3 = KCLocalizedString(@"Hello",@"Comment"); // no-warning
-}
-
-- (void)testPossibleFalsePositiveSituationAbove {
-  NSString *string = POSSIBLE_FALSE_POSITIVE(@"Hello", nil); // no-warning
-  NSString *string2 = POSSIBLE_FALSE_POSITIVE(@"Hello", @"Hello"); // no-warning
-}
-
- at end

Removed: cfe/trunk/test/Analysis/localization.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/localization.m?rev=244393&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/localization.m (original)
+++ cfe/trunk/test/Analysis/localization.m (removed)
@@ -1,86 +0,0 @@
-// RUN: %clang_cc1 -analyze -fblocks -analyzer-store=region -analyzer-checker=alpha.osx.cocoa.NonLocalizedStringChecker -analyzer-checker=alpha.osx.cocoa.EmptyLocalizationContextChecker -verify  %s
-
-// The larger set of tests in located in localization.m. These are tests
-// specific for non-aggressive reporting.
-
-// These declarations were reduced using Delta-Debugging from Foundation.h
-// on Mac OS X.
-
-#define nil ((id)0)
-#define NSLocalizedString(key, comment)                                        \
-  [[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:nil]
-#define NSLocalizedStringFromTable(key, tbl, comment)                          \
-  [[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:(tbl)]
-#define NSLocalizedStringFromTableInBundle(key, tbl, bundle, comment)          \
-  [bundle localizedStringForKey:(key) value:@"" table:(tbl)]
-#define NSLocalizedStringWithDefaultValue(key, tbl, bundle, val, comment)      \
-  [bundle localizedStringForKey:(key) value:(val) table:(tbl)]
- at interface NSObject
-+ (id)alloc;
-- (id)init;
- at end
- at interface NSString : NSObject
- at end
- at interface NSBundle : NSObject
-+ (NSBundle *)mainBundle;
-- (NSString *)localizedStringForKey:(NSString *)key
-                              value:(NSString *)value
-                              table:(NSString *)tableName;
- at end
- at interface UILabel : NSObject
- at property(nullable, nonatomic, copy) NSString *text;
- at end
- at interface TestObject : NSObject
- at property(strong) NSString *text;
- at end
-
- at interface LocalizationTestSuite : NSObject
-int random();
- at end
-
-// Test cases begin here
- at implementation LocalizationTestSuite
-
-// An object passed in as an parameter's string member
-// should not be considered unlocalized
-- (void)testObjectAsArgument:(TestObject *)argumentObject {
-  UILabel *testLabel = [[UILabel alloc] init];
-
-  [testLabel setText:[argumentObject text]]; // no-warning
-  [testLabel setText:argumentObject.text];   // no-warning
-}
-
-- (void)testLocalizationErrorDetectedOnPathway {
-  UILabel *testLabel = [[UILabel alloc] init];
-  NSString *bar = NSLocalizedString(@"Hello", @"Comment");
-
-  if (random()) {
-    bar = @"Unlocalized string";
-  }
-
-  [testLabel setText:bar]; // expected-warning {{String should be localized}}
-}
-
-- (void)testOneCharacterStringsDoNotGiveAWarning {
-  UILabel *testLabel = [[UILabel alloc] init];
-  NSString *bar = NSLocalizedString(@"Hello", @"Comment");
-
-  if (random()) {
-    bar = @"-";
-  }
-
-  [testLabel setText:bar]; // no-warning
-}
-
-- (void)testOneCharacterUTFStringsDoNotGiveAWarning {
-  UILabel *testLabel = [[UILabel alloc] init];
-  NSString *bar = NSLocalizedString(@"Hello", @"Comment");
-
-  if (random()) {
-    bar = @"—";
-  }
-
-  [testLabel setText:bar]; // no-warning
-}
-
- at end




More information about the cfe-commits mailing list