Hi,
This is a new check i want to get reviewed. It checks for char literal
additions on strings.
Example:
char* str;
str = str + 'c';
This is a suspicious pointer arithmetic, probably string addition was intended.
Thanks,
Anders
.......................................................................................................................
Anders Rönnholm Senior Engineer
Evidente ES East AB Warfvinges väg 34 SE-112 51 Stockholm Sweden
Mobile: +46 (0)70 912 42 54
E-mail: [email protected]
www.evidente.se
Index: lib/StaticAnalyzer/Checkers/StringPlusCharChecker.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/StringPlusCharChecker.cpp (revision 0)
+++ lib/StaticAnalyzer/Checkers/StringPlusCharChecker.cpp (working copy)
@@ -0,0 +1,76 @@
+//== StringPlusCharChecker.cpp - string plus char checker --------------*- C++ -*--==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This defines StringPlusCharChecker, a check that
+// checks additions of chars to string pointers.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ClangSACheckers.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/CheckerContext.h"
+
+using namespace clang;
+using namespace ento;
+
+namespace {
+class StringPlusCharChecker : public Checker< check::PreStmt<BinaryOperator> > {
+ mutable OwningPtr<BuiltinBug> BT;
+ void reportBug(const char *Msg,
+ ProgramStateRef State,
+ CheckerContext &C) const ;
+public:
+ void checkPreStmt(const BinaryOperator *B, CheckerContext &C) const;
+};
+} // end anonymous namespace
+
+void StringPlusCharChecker::reportBug(const char *Msg,
+ ProgramStateRef State,
+ CheckerContext &C) const {
+ if (ExplodedNode *N = C.generateSink(State)) {
+ if (!BT)
+ BT.reset(new BuiltinBug(Msg));
+
+ BugReport *R = new BugReport(*BT, Msg, N);
+ bugreporter::trackNullOrUndefValue(N, bugreporter::GetDenomExpr(N), *R);
+ C.emitReport(R);
+ }
+}
+
+void StringPlusCharChecker::checkPreStmt(const BinaryOperator *B,
+ CheckerContext &C) const {
+ //Only check add operators
+ if (B->getOpcode() != BO_Add)
+ return;
+
+ CharacterLiteral* CharExpr =
+ dyn_cast<CharacterLiteral>(B->getRHS()->IgnoreImpCasts());
+ DeclRefExpr* StringRefExpr = dyn_cast<DeclRefExpr>(B->getLHS()->IgnoreImpCasts());
+ if (!CharExpr || !StringRefExpr)
+ return;
+
+ //Return if not a PointerType
+ if (!StringRefExpr->getType()->isAnyPointerType())
+ return;
+
+ const ASTContext &Context = C.getASTContext();
+ //Only report if it is a string or string ptr
+ if (!(StringRefExpr->getType() ==
+ Context.getPointerType(Context.getConstType(Context.CharTy)) ||
+ StringRefExpr->getType() == Context.getPointerType(Context.CharTy)))
+ return;
+
+ reportBug("Unusual pointer arithmetic. A character literal is added to a value of type char*", C.getState(), C);
+}
+
+void ento::registerStringPlusCharChecker(CheckerManager &mgr) {
+ mgr.registerChecker<StringPlusCharChecker>();
+}
Index: lib/StaticAnalyzer/Checkers/Checkers.td
===================================================================
--- lib/StaticAnalyzer/Checkers/Checkers.td (revision 191003)
+++ lib/StaticAnalyzer/Checkers/Checkers.td (working copy)
@@ -116,6 +116,10 @@
HelpText<"Warn about unintended use of sizeof() on pointer expressions">,
DescFile<"CheckSizeofPointer.cpp">;
+def StringPlusCharChecker : Checker<"StringPlusChar">,
+ HelpText<"Check for string plus char">,
+ DescFile<"StringPlusCharChecker.cpp">;
+
} // end "alpha.core"
//===----------------------------------------------------------------------===//
Index: lib/StaticAnalyzer/Checkers/CMakeLists.txt
===================================================================
--- lib/StaticAnalyzer/Checkers/CMakeLists.txt (revision 190991)
+++ lib/StaticAnalyzer/Checkers/CMakeLists.txt (working copy)
@@ -60,6 +61,7 @@
SimpleStreamChecker.cpp
StackAddrEscapeChecker.cpp
StreamChecker.cpp
+ StringPlusCharChecker.cpp
TaintTesterChecker.cpp
TraversalChecker.cpp
UndefBranchChecker.cpp
Index: test/Analysis/string-plus-char-checks.c
===================================================================
--- test/Analysis/string-plus-char-checks.c (revision 0)
+++ test/Analysis/string-plus-char-checks.c (working copy)
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.core.StringPlusChar -verify %s
+
+void checkStringPointerPlusChar() {
+ char* str;
+ char *str2 = str + 'c'; // expected-warning {{Unusual pointer arithmetic. A character literal is added to a value of type char*}}
+}
+
+void checkConstStringPointerPlusChar() {
+ const char* str;
+ const char *str2 = str + 'c'; // expected-warning {{Unusual pointer arithmetic. A character literal is added to a value of type char*}}
+}
+
+void checkCharPlusStringPointer() {
+ char* str = "";
+ str = 'c' + str;
+} // no-warning
+
+void checkIntPointerPlusChar() {
+ int* i = 0;
+ i = i + 'c';
+} // no-warning
Index: test/Analysis/string-plus-char-checks.cpp
===================================================================
--- test/Analysis/string-plus-char-checks.cpp (revision 0)
+++ test/Analysis/string-plus-char-checks.cpp (working copy)
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.core.StringPlusChar -verify %s
+class A {
+public:
+ A() { }
+ A(const char *p) { }
+ A& operator+(const char *p) { return *this; }
+ A& operator+(char ch) { return *this; }
+};
+
+void checkStringPointerPlusChar(const char *str) {
+ A a = str + 'a'; // expected-warning {{Unusual pointer arithmetic. A character literal is added to a value of type char*}}
+}
+
+void checkClassOperatorPlusChar(const char *str) {
+ A a;
+ a = a + str + 'b';
+} // no-warning
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits