Hi,

I forgot that there is i line limit of 80, i have corrected that.

//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

________________________________________
Från: Anders Rönnholm
Skickat: den 20 september 2013 10:23
Till: [email protected]
Ämne: [PATCH] [StaticAnalyzer] New checker Sizeof on expression

Hi,

I have another checker i would like to get reviewed. It checks for usage of 
sizeof on an expression. For now it only checks binary operators. Sizeof on 
defines does not generate a warning.

Example:
sizeof(2 + 1);

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/CMakeLists.txt
===================================================================
--- lib/StaticAnalyzer/Checkers/CMakeLists.txt	(revision 191075)
+++ lib/StaticAnalyzer/Checkers/CMakeLists.txt	(working copy)
@@ -19,6 +19,7 @@
   CheckObjCDealloc.cpp
   CheckObjCInstMethSignature.cpp
   CheckSecuritySyntaxOnly.cpp
+  CheckSizeofOnExpression.cpp
   CheckSizeofPointer.cpp
   CheckerDocumentation.cpp
   ChrootChecker.cpp
Index: lib/StaticAnalyzer/Checkers/Checkers.td
===================================================================
--- lib/StaticAnalyzer/Checkers/Checkers.td	(revision 191075)
+++ lib/StaticAnalyzer/Checkers/Checkers.td	(working copy)
@@ -112,6 +112,10 @@
   HelpText<"Check for pointer subtractions on two pointers pointing to different memory chunks">,
   DescFile<"PointerSubChecker">;
 
+def SizeofOnExpressionChecker : Checker<"SizeofOnExpression">,
+  HelpText<"Check for expression in sizeof()">,
+  DescFile<"CheckSizeofOnExpression.cpp">;
+
 def SizeofPointerChecker : Checker<"SizeofPtr">,
   HelpText<"Warn about unintended use of sizeof() on pointer expressions">,
   DescFile<"CheckSizeofPointer.cpp">;
Index: lib/StaticAnalyzer/Checkers/CheckSizeofOnExpression.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/CheckSizeofOnExpression.cpp	(revision 0)
+++ lib/StaticAnalyzer/Checkers/CheckSizeofOnExpression.cpp	(working copy)
@@ -0,0 +1,93 @@
+//==- CheckSizeofOnExpression.cpp - Check expressions in sizeof() *- 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 check for expressions made in sizeof()
+//
+//===----------------------------------------------------------------------===//
+
+#include "ClangSACheckers.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
+
+using namespace clang;
+using namespace ento;
+
+namespace {
+class WalkAST : public StmtVisitor<WalkAST> {
+  BugReporter &BR;
+  AnalysisDeclContext* AC;
+
+public:
+  WalkAST(BugReporter &br, AnalysisDeclContext* ac) : BR(br), AC(ac) {}
+  void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E);
+  void VisitStmt(Stmt *S) { VisitChildren(S); }
+  void VisitChildren(Stmt *S);
+};
+}
+
+void WalkAST::VisitChildren(Stmt *S) {
+  for (Stmt::child_iterator I = S->child_begin(), E = S->child_end(); I!=E; ++I)
+    if (Stmt *child = *I)
+      Visit(child);
+}
+
+
+void WalkAST::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) {
+  if (E->getKind() != UETT_SizeOf)
+    return;
+
+  if (E->isArgumentType())
+    return;
+
+  Expr *Expr = E->getArgumentExpr();
+  if (!Expr)
+    return;
+
+  BinaryOperator *Binop = dyn_cast<BinaryOperator>(Expr->IgnoreParens());
+
+  //Only check binary operators
+  if (!Binop)
+    return;
+
+  // is expression based on macro => don't warn
+  if ((Binop->getLHS()->getExprLoc().isMacroID()) ||
+      (Binop->getRHS()->getExprLoc().isMacroID()))
+    return;
+
+  SourceRange R = Expr->getSourceRange();
+  PathDiagnosticLocation ELoc =
+    PathDiagnosticLocation::createBegin(E, BR.getSourceManager(), AC);
+  BR.EmitBasicReport(AC->getDecl(),
+                     "Expression with an operation in sizeof()",
+                     "Logic",
+                     "Sizeof() on an expression with an operator "
+                     "may yield unexpected results.",
+                     ELoc, &R, 1);
+}
+
+//===----------------------------------------------------------------------===//
+// SizeofOnExpressionChecker
+//===----------------------------------------------------------------------===//
+
+namespace {
+class SizeofOnExpressionChecker : public Checker<check::ASTCodeBody> {
+public:
+  void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
+                        BugReporter &BR) const {
+    WalkAST walker(BR, mgr.getAnalysisDeclContext(D));
+    walker.Visit(D->getBody());
+  }
+};
+}
+
+void ento::registerSizeofOnExpressionChecker(CheckerManager &mgr) {
+  mgr.registerChecker<SizeofOnExpressionChecker>();
+}
Index: test/Analysis/sizeofonexpression.c
===================================================================
--- test/Analysis/sizeofonexpression.c	(revision 0)
+++ test/Analysis/sizeofonexpression.c	(working copy)
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.core.SizeofOnExpression -verify %s
+
+#define DEF (1+2)
+
+struct s {
+  int xx;
+  int yy;
+};
+
+int SizeofStructExpression(struct s p) {
+  return sizeof(sizeof(p) + 1);  // expected-warning{{Sizeof() on an expression with an operator may yield unexpected results}}
+}
+
+int SizeofStructMemberExpression(struct s p) {
+  return sizeof(p.xx * p.yy); // expected-warning{{Sizeof() on an expression with an operator may yield unexpected results}}
+}
+
+int SizeofLiteralExpression() {
+  return sizeof(2 + 1);  // expected-warning{{Sizeof() on an expression with an operator may yield unexpected results}}
+}
+
+int SizeofRefExpression() {
+  int x = 1, y = 2;
+  return sizeof(x / y);  // expected-warning{{Sizeof() on an expression with an operator may yield unexpected results}}
+}
+
+int SizeofDefineExpression() {
+  return sizeof(DEF + 2);
+} // no-warning
+
+int SizeofDefineExpression2() {
+  return sizeof(2 - DEF);
+} // no-warning
+
+int SizeofFunctionCallExpression() {
+  return sizeof(SizeofDefine() - 1); // expected-warning{{Sizeof() on an expression with an operator may yield unexpected results}}
+}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to