summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp
diff options
context:
space:
mode:
authorDevin Coughlin <dcoughlin@apple.com>2016-04-28 19:44:40 +0000
committerDevin Coughlin <dcoughlin@apple.com>2016-04-28 19:44:40 +0000
commit97dc0c8c29f857fcffffc2b1ebaad459e91dc150 (patch)
tree8d57cf4dc491102ca8bab1b1ff42c0869ebdd459 /clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp
parente8c6840c71db30f07e7eaa6796d6d2c189330e58 (diff)
downloadbcm5719-llvm-97dc0c8c29f857fcffffc2b1ebaad459e91dc150.tar.gz
bcm5719-llvm-97dc0c8c29f857fcffffc2b1ebaad459e91dc150.zip
[analyzer] Add path note for localizability checker.
Add a path note indicating the location of the non-localized string literal in NonLocalizedStringChecker. rdar://problem/25981525 llvm-svn: 267924
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp64
1 files changed, 64 insertions, 0 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp
index a25f3e01c91..7be2f574f0e 100644
--- a/clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp
@@ -111,6 +111,30 @@ NonLocalizedStringChecker::NonLocalizedStringChecker() {
"Localizability Issue (Apple)"));
}
+namespace {
+class NonLocalizedStringBRVisitor final
+ : public BugReporterVisitorImpl<NonLocalizedStringBRVisitor> {
+
+ const MemRegion *NonLocalizedString;
+ bool Satisfied;
+
+public:
+ NonLocalizedStringBRVisitor(const MemRegion *NonLocalizedString)
+ : NonLocalizedString(NonLocalizedString), Satisfied(false) {
+ assert(NonLocalizedString);
+ }
+
+ PathDiagnosticPiece *VisitNode(const ExplodedNode *Succ,
+ const ExplodedNode *Pred,
+ BugReporterContext &BRC,
+ BugReport &BR) override;
+
+ void Profile(llvm::FoldingSetNodeID &ID) const override {
+ ID.Add(NonLocalizedString);
+ }
+};
+} // End anonymous namespace.
+
#define NEW_RECEIVER(receiver) \
llvm::DenseMap<Selector, uint8_t> &receiver##M = \
UIMethods.insert({&Ctx.Idents.get(#receiver), \
@@ -676,6 +700,11 @@ void NonLocalizedStringChecker::reportLocalizationError(
R->addRange(M.getSourceRange());
}
R->markInteresting(S);
+
+ const MemRegion *StringRegion = S.getAsRegion();
+ if (StringRegion)
+ R->addVisitor(llvm::make_unique<NonLocalizedStringBRVisitor>(StringRegion));
+
C.emitReport(std::move(R));
}
@@ -866,6 +895,41 @@ void NonLocalizedStringChecker::checkPostStmt(const ObjCStringLiteral *SL,
setNonLocalizedState(sv, C);
}
+PathDiagnosticPiece *
+NonLocalizedStringBRVisitor::VisitNode(const ExplodedNode *Succ,
+ const ExplodedNode *Pred,
+ BugReporterContext &BRC, BugReport &BR) {
+ if (Satisfied)
+ return nullptr;
+
+ Optional<StmtPoint> Point = Succ->getLocation().getAs<StmtPoint>();
+ if (!Point.hasValue())
+ return nullptr;
+
+ auto *LiteralExpr = dyn_cast<ObjCStringLiteral>(Point->getStmt());
+ if (!LiteralExpr)
+ return nullptr;
+
+ ProgramStateRef State = Succ->getState();
+ SVal LiteralSVal = State->getSVal(LiteralExpr, Succ->getLocationContext());
+ if (LiteralSVal.getAsRegion() != NonLocalizedString)
+ return nullptr;
+
+ Satisfied = true;
+
+ PathDiagnosticLocation L =
+ PathDiagnosticLocation::create(*Point, BRC.getSourceManager());
+
+ if (!L.isValid() || !L.asLocation().isValid())
+ return nullptr;
+
+ auto *Piece = new PathDiagnosticEventPiece(L,
+ "Non-localized string literal here");
+ Piece->addRange(LiteralExpr->getSourceRange());
+
+ return Piece;
+}
+
namespace {
class EmptyLocalizationContextChecker
: public Checker<check::ASTDecl<ObjCImplementationDecl>> {
OpenPOWER on IntegriCloud