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

Reply via email to