1 //===---- CheckerHelpers.cpp - Helper functions for checkers ----*- 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 several static functions for use in checkers. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h" 15 #include "clang/AST/Decl.h" 16 #include "clang/AST/Expr.h" 17 18 // Recursively find any substatements containing macros containsMacro(const Stmt * S)19bool clang::ento::containsMacro(const Stmt *S) { 20 if (S->getLocStart().isMacroID()) 21 return true; 22 23 if (S->getLocEnd().isMacroID()) 24 return true; 25 26 for (const Stmt *Child : S->children()) 27 if (Child && containsMacro(Child)) 28 return true; 29 30 return false; 31 } 32 33 // Recursively find any substatements containing enum constants containsEnum(const Stmt * S)34bool clang::ento::containsEnum(const Stmt *S) { 35 const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(S); 36 37 if (DR && isa<EnumConstantDecl>(DR->getDecl())) 38 return true; 39 40 for (const Stmt *Child : S->children()) 41 if (Child && containsEnum(Child)) 42 return true; 43 44 return false; 45 } 46 47 // Recursively find any substatements containing static vars containsStaticLocal(const Stmt * S)48bool clang::ento::containsStaticLocal(const Stmt *S) { 49 const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(S); 50 51 if (DR) 52 if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) 53 if (VD->isStaticLocal()) 54 return true; 55 56 for (const Stmt *Child : S->children()) 57 if (Child && containsStaticLocal(Child)) 58 return true; 59 60 return false; 61 } 62 63 // Recursively find any substatements containing __builtin_offsetof containsBuiltinOffsetOf(const Stmt * S)64bool clang::ento::containsBuiltinOffsetOf(const Stmt *S) { 65 if (isa<OffsetOfExpr>(S)) 66 return true; 67 68 for (const Stmt *Child : S->children()) 69 if (Child && containsBuiltinOffsetOf(Child)) 70 return true; 71 72 return false; 73 } 74 75 // Extract lhs and rhs from assignment statement 76 std::pair<const clang::VarDecl *, const clang::Expr *> parseAssignment(const Stmt * S)77clang::ento::parseAssignment(const Stmt *S) { 78 const VarDecl *VD = nullptr; 79 const Expr *RHS = nullptr; 80 81 if (auto Assign = dyn_cast_or_null<BinaryOperator>(S)) { 82 if (Assign->isAssignmentOp()) { 83 // Ordinary assignment 84 RHS = Assign->getRHS(); 85 if (auto DE = dyn_cast_or_null<DeclRefExpr>(Assign->getLHS())) 86 VD = dyn_cast_or_null<VarDecl>(DE->getDecl()); 87 } 88 } else if (auto PD = dyn_cast_or_null<DeclStmt>(S)) { 89 // Initialization 90 assert(PD->isSingleDecl() && "We process decls one by one"); 91 VD = dyn_cast_or_null<VarDecl>(PD->getSingleDecl()); 92 RHS = VD->getAnyInitializer(); 93 } 94 95 return std::make_pair(VD, RHS); 96 } 97