1d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu//===--- UndefinedArraySubscriptChecker.h ----------------------*- C++ -*--===// 2d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu// 3d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu// The LLVM Compiler Infrastructure 4d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu// 5d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu// This file is distributed under the University of Illinois Open Source 6d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu// License. See LICENSE.TXT for details. 7d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu// 8d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu//===----------------------------------------------------------------------===// 9d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu// 10d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis// This defines UndefinedArraySubscriptChecker, a builtin check in ExprEngine 11d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu// that performs checks for undefined array subscripts. 12d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu// 13d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu//===----------------------------------------------------------------------===// 14d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu 15eb290caacc49587e4d3c992ba742d1916cab5350Argyrios Kyrtzidis#include "ClangSACheckers.h" 16cff15128c6c089bd6fae841b80680e6f5afbf0bfReid Kleckner#include "clang/AST/DeclCXX.h" 1755fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" 18ec8605f1d7ec846dbf51047bfd5c56d32d1ff91cArgyrios Kyrtzidis#include "clang/StaticAnalyzer/Core/Checker.h" 19eb290caacc49587e4d3c992ba742d1916cab5350Argyrios Kyrtzidis#include "clang/StaticAnalyzer/Core/CheckerManager.h" 20eb290caacc49587e4d3c992ba742d1916cab5350Argyrios Kyrtzidis#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" 21d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu 22d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xuusing namespace clang; 239ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenekusing namespace ento; 24d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu 25d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xunamespace { 26ba5fb5a955c896815c439289fc51c03cf0635129Kovarththanan Rajaratnamclass UndefinedArraySubscriptChecker 27ec8605f1d7ec846dbf51047bfd5c56d32d1ff91cArgyrios Kyrtzidis : public Checker< check::PreStmt<ArraySubscriptExpr> > { 28651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines mutable std::unique_ptr<BugType> BT; 29eb290caacc49587e4d3c992ba742d1916cab5350Argyrios Kyrtzidis 30d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xupublic: 31eb290caacc49587e4d3c992ba742d1916cab5350Argyrios Kyrtzidis void checkPreStmt(const ArraySubscriptExpr *A, CheckerContext &C) const; 32d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu}; 33d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu} // end anonymous namespace 34d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu 35a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainarvoid 36eb290caacc49587e4d3c992ba742d1916cab5350Argyrios KyrtzidisUndefinedArraySubscriptChecker::checkPreStmt(const ArraySubscriptExpr *A, 37eb290caacc49587e4d3c992ba742d1916cab5350Argyrios Kyrtzidis CheckerContext &C) const { 38ecee1651c100342366a9417c85c6e50399039930Jordan Rose const Expr *Index = A->getIdx(); 39ecee1651c100342366a9417c85c6e50399039930Jordan Rose if (!C.getSVal(Index).isUndef()) 40ecee1651c100342366a9417c85c6e50399039930Jordan Rose return; 41ecee1651c100342366a9417c85c6e50399039930Jordan Rose 42ecee1651c100342366a9417c85c6e50399039930Jordan Rose // Sema generates anonymous array variables for copying array struct fields. 43ecee1651c100342366a9417c85c6e50399039930Jordan Rose // Don't warn if we're in an implicitly-generated constructor. 44ecee1651c100342366a9417c85c6e50399039930Jordan Rose const Decl *D = C.getLocationContext()->getDecl(); 45ecee1651c100342366a9417c85c6e50399039930Jordan Rose if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) 46a7b879723d3989d85b9492fd8218e7d745367fe3Jordan Rose if (Ctor->isDefaulted()) 47ecee1651c100342366a9417c85c6e50399039930Jordan Rose return; 48ecee1651c100342366a9417c85c6e50399039930Jordan Rose 49a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ExplodedNode *N = C.generateErrorNode(); 50ecee1651c100342366a9417c85c6e50399039930Jordan Rose if (!N) 51ecee1651c100342366a9417c85c6e50399039930Jordan Rose return; 52ecee1651c100342366a9417c85c6e50399039930Jordan Rose if (!BT) 53651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BT.reset(new BuiltinBug(this, "Array subscript is undefined")); 54ecee1651c100342366a9417c85c6e50399039930Jordan Rose 55ecee1651c100342366a9417c85c6e50399039930Jordan Rose // Generate a report for this bug. 56a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar auto R = llvm::make_unique<BugReport>(*BT, BT->getName(), N); 57ecee1651c100342366a9417c85c6e50399039930Jordan Rose R->addRange(A->getIdx()->getSourceRange()); 58ecee1651c100342366a9417c85c6e50399039930Jordan Rose bugreporter::trackNullOrUndefValue(N, A->getIdx(), *R); 59a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar C.emitReport(std::move(R)); 60d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu} 61eb290caacc49587e4d3c992ba742d1916cab5350Argyrios Kyrtzidis 62eb290caacc49587e4d3c992ba742d1916cab5350Argyrios Kyrtzidisvoid ento::registerUndefinedArraySubscriptChecker(CheckerManager &mgr) { 63eb290caacc49587e4d3c992ba742d1916cab5350Argyrios Kyrtzidis mgr.registerChecker<UndefinedArraySubscriptChecker>(); 64eb290caacc49587e4d3c992ba742d1916cab5350Argyrios Kyrtzidis} 65