Hi Jordan,

Thank you for your comments. I have changed the check to use 
RecursiveASTVisitor. However i'm not sure what i should write as category in 
bugreport. You mentioned adding a new category in CommonBugCategories for 
SIzeofOnExpression, should i do that or is what i have enough for now? 

I have provided a new diff.

//Anders

From: Jordan Rose [mailto:[email protected]]
Sent: den 25 september 2013 04:01
To: Anders Rönnholm
Cc: [email protected]
Subject: Re: [PATCH] [StaticAnalyzer] New checker StringPlusChar

I was sort of right: we have a warning -Wstring-plus-int for adding an integer 
(or character literal) to a string literal...but nothing for variables.

Nevertheless, this is a syntactic check rather than a path-sensitive one, so 
I'd recommend writing it using checkASTCodeBody instead. You can take a look at 
CheckSizeofPointer.cpp to see how this works, though I'd recommend using the 
slightly-more-powerful RecursiveASTVisitor (overriding VisitBinaryOperator) 
rather than building your own recursion with StmtVisitor.

Jordan


On Sep 19, 2013, at 9:23 , Jordan Rose 
<[email protected]<mailto:[email protected]>> wrote:

> I could have sworn we had a check or warning for this already, but I don't 
> see it. Hopefully I'll get a chance to review this soon; thanks, Anders!
>
> Jordan
>
>
> On Sep 19, 2013, at 7:46 , Anders Rönnholm 
> <[email protected]<mailto:[email protected]>> wrote:
>
>> 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]<mailto:[email protected]>
>>
>> www.evidente.se<http://www.evidente.se>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> [email protected]<mailto:[email protected]>
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
Index: lib/StaticAnalyzer/Checkers/StringPlusCharChecker.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/StringPlusCharChecker.cpp	(revision 0)
+++ lib/StaticAnalyzer/Checkers/StringPlusCharChecker.cpp	(working copy)
@@ -0,0 +1,89 @@
+//== StringPlusCharChecker.cpp - string plus char checker ------------------==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief This defines StringPlusCharChecker, a check that
+/// checks additions of chars to string pointers.
+///
+//===----------------------------------------------------------------------===//
+
+#include "ClangSACheckers.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+
+using namespace clang;
+using namespace ento;
+
+namespace {
+class StringPlusCharVisitor
+    : public RecursiveASTVisitor<StringPlusCharVisitor> {
+public:
+  explicit StringPlusCharVisitor(BugReporter &br, AnalysisDeclContext *ac)
+      : BR(br), AC(ac) {}
+
+  bool VisitBinaryOperator(BinaryOperator *B) {
+    // Only check add operators.
+    if (B->getOpcode() != BO_Add)
+      return false;
+
+    const DeclRefExpr *StringRefExpr =
+        dyn_cast<DeclRefExpr>(B->getLHS()->IgnoreImpCasts());
+    const CharacterLiteral *CharExpr =
+        dyn_cast<CharacterLiteral>(B->getRHS()->IgnoreImpCasts());
+    if (!CharExpr || !StringRefExpr)
+      return false;
+
+    // Return if not a PointerType.
+    if (!StringRefExpr->getType()->isAnyPointerType())
+      return false;
+
+    // Only report if it is a string or string ptr.
+    const ASTContext &Context = BR.getContext();
+    if (!(StringRefExpr->getType() ==
+              Context.getPointerType(Context.getConstType(Context.CharTy)) ||
+          StringRefExpr->getType() == Context.getPointerType(Context.CharTy)))
+      return false;
+
+    PathDiagnosticLocation ELoc =
+        PathDiagnosticLocation::createBegin(B, BR.getSourceManager(), AC);
+    BR.EmitBasicReport(AC->getDecl(), "Unusual pointer arithmetic",
+                       "String plus char",
+                       "Unusual pointer arithmetic. A character literal is "
+                       "added to a value of type char*",
+                       ELoc);
+    return false;
+  }
+
+private:
+  BugReporter &BR;
+  AnalysisDeclContext *AC;
+};
+}
+
+namespace {
+class StringPlusCharChecker : public Checker<check::ASTCodeBody> {
+public:
+  void checkASTCodeBody(const Decl *D, AnalysisManager &mgr,
+                        BugReporter &BR) const;
+};
+} // end anonymous namespace
+
+void StringPlusCharChecker::checkASTCodeBody(const Decl *D,
+                                             AnalysisManager &mgr,
+                                             BugReporter &BR) const {
+
+  StringPlusCharVisitor Visitor(BR, mgr.getAnalysisDeclContext(D));
+  Visitor.TraverseDecl(const_cast<Decl *>(D));
+}
+
+void ento::registerStringPlusCharChecker(CheckerManager &mgr) {
+  mgr.registerChecker<StringPlusCharChecker>();
+}
Index: lib/StaticAnalyzer/Checkers/CMakeLists.txt
===================================================================
--- lib/StaticAnalyzer/Checkers/CMakeLists.txt	(revision 191652)
+++ 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: lib/StaticAnalyzer/Checkers/Checkers.td
===================================================================
--- lib/StaticAnalyzer/Checkers/Checkers.td	(revision 191652)
+++ 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<"Warn about string plus char">,
+  DescFile<"StringPlusCharChecker.cpp">;
+
 } // end "alpha.core"
 
 //===----------------------------------------------------------------------===//
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,19 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.core.StringPlusChar -verify %s
+class A {
+public:
+  A(): str() { }
+  A(const char *p) { }
+  A(char *p) : str(p + 'a') { } // expected-warning {{Unusual pointer arithmetic. A character literal is added to a value of type char*}}
+  A& operator+(const char *p) { return *this; }
+  A& operator+(char ch) { return *this; }
+  char * str;
+};
+
+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