1 //==- CheckSizeofPointer.cpp - Check for sizeof on pointers ------*- C++ -*-==// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines a check for unintended use of sizeof() on pointer 11 // expressions. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "clang/StaticAnalyzer/BugReporter/BugReporter.h" 16 #include "clang/AST/StmtVisitor.h" 17 #include "clang/StaticAnalyzer/Checkers/LocalCheckers.h" 18 19 using namespace clang; 20 using namespace ento; 21 22 namespace { 23 class WalkAST : public StmtVisitor<WalkAST> { 24 BugReporter &BR; 25 26 public: 27 WalkAST(BugReporter &br) : BR(br) {} 28 void VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E); 29 void VisitStmt(Stmt *S) { VisitChildren(S); } 30 void VisitChildren(Stmt *S); 31 }; 32 } 33 34 void WalkAST::VisitChildren(Stmt *S) { 35 for (Stmt::child_iterator I = S->child_begin(), E = S->child_end(); I!=E; ++I) 36 if (Stmt *child = *I) 37 Visit(child); 38 } 39 40 // CWE-467: Use of sizeof() on a Pointer Type 41 void WalkAST::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) { 42 if (!E->isSizeOf()) 43 return; 44 45 // If an explicit type is used in the code, usually the coder knows what he is 46 // doing. 47 if (E->isArgumentType()) 48 return; 49 50 QualType T = E->getTypeOfArgument(); 51 if (T->isPointerType()) { 52 53 // Many false positives have the form 'sizeof *p'. This is reasonable 54 // because people know what they are doing when they intentionally 55 // dereference the pointer. 56 Expr *ArgEx = E->getArgumentExpr(); 57 if (!isa<DeclRefExpr>(ArgEx->IgnoreParens())) 58 return; 59 60 SourceRange R = ArgEx->getSourceRange(); 61 BR.EmitBasicReport("Potential unintended use of sizeof() on pointer type", 62 "Logic", 63 "The code calls sizeof() on a pointer type. " 64 "This can produce an unexpected result.", 65 E->getLocStart(), &R, 1); 66 } 67 } 68 69 void ento::CheckSizeofPointer(const Decl *D, BugReporter &BR) { 70 WalkAST walker(BR); 71 walker.Visit(D->getBody()); 72 } 73