11053d246f451c399468248625d1146e3d845e21eTed Kremenek//== ReturnUndefChecker.cpp -------------------------------------*- C++ -*--==// 21053d246f451c399468248625d1146e3d845e21eTed Kremenek// 31053d246f451c399468248625d1146e3d845e21eTed Kremenek// The LLVM Compiler Infrastructure 41053d246f451c399468248625d1146e3d845e21eTed Kremenek// 51053d246f451c399468248625d1146e3d845e21eTed Kremenek// This file is distributed under the University of Illinois Open Source 61053d246f451c399468248625d1146e3d845e21eTed Kremenek// License. See LICENSE.TXT for details. 71053d246f451c399468248625d1146e3d845e21eTed Kremenek// 81053d246f451c399468248625d1146e3d845e21eTed Kremenek//===----------------------------------------------------------------------===// 91053d246f451c399468248625d1146e3d845e21eTed Kremenek// 101053d246f451c399468248625d1146e3d845e21eTed Kremenek// This file defines ReturnUndefChecker, which is a path-sensitive 111053d246f451c399468248625d1146e3d845e21eTed Kremenek// check which looks for undefined or garbage values being returned to the 121053d246f451c399468248625d1146e3d845e21eTed Kremenek// caller. 131053d246f451c399468248625d1146e3d845e21eTed Kremenek// 141053d246f451c399468248625d1146e3d845e21eTed Kremenek//===----------------------------------------------------------------------===// 151053d246f451c399468248625d1146e3d845e21eTed Kremenek 167f649d749f18b3499456d7ae6a69f3bbd7cf7cdcArgyrios Kyrtzidis#include "ClangSACheckers.h" 17ec8605f1d7ec846dbf51047bfd5c56d32d1ff91cArgyrios Kyrtzidis#include "clang/StaticAnalyzer/Core/Checker.h" 187f649d749f18b3499456d7ae6a69f3bbd7cf7cdcArgyrios Kyrtzidis#include "clang/StaticAnalyzer/Core/CheckerManager.h" 197f649d749f18b3499456d7ae6a69f3bbd7cf7cdcArgyrios Kyrtzidis#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" 209b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" 211053d246f451c399468248625d1146e3d845e21eTed Kremenek 221053d246f451c399468248625d1146e3d845e21eTed Kremenekusing namespace clang; 239ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenekusing namespace ento; 241053d246f451c399468248625d1146e3d845e21eTed Kremenek 251053d246f451c399468248625d1146e3d845e21eTed Kremeneknamespace { 26ba5fb5a955c896815c439289fc51c03cf0635129Kovarththanan Rajaratnamclass ReturnUndefChecker : 27ec8605f1d7ec846dbf51047bfd5c56d32d1ff91cArgyrios Kyrtzidis public Checker< check::PreStmt<ReturnStmt> > { 286f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith mutable OwningPtr<BuiltinBug> BT; 291053d246f451c399468248625d1146e3d845e21eTed Kremenekpublic: 307f649d749f18b3499456d7ae6a69f3bbd7cf7cdcArgyrios Kyrtzidis void checkPreStmt(const ReturnStmt *RS, CheckerContext &C) const; 311053d246f451c399468248625d1146e3d845e21eTed Kremenek}; 321053d246f451c399468248625d1146e3d845e21eTed Kremenek} 331053d246f451c399468248625d1146e3d845e21eTed Kremenek 347f649d749f18b3499456d7ae6a69f3bbd7cf7cdcArgyrios Kyrtzidisvoid ReturnUndefChecker::checkPreStmt(const ReturnStmt *RS, 357f649d749f18b3499456d7ae6a69f3bbd7cf7cdcArgyrios Kyrtzidis CheckerContext &C) const { 361053d246f451c399468248625d1146e3d845e21eTed Kremenek 371053d246f451c399468248625d1146e3d845e21eTed Kremenek const Expr *RetE = RS->getRetValue(); 381053d246f451c399468248625d1146e3d845e21eTed Kremenek if (!RetE) 391053d246f451c399468248625d1146e3d845e21eTed Kremenek return; 401053d246f451c399468248625d1146e3d845e21eTed Kremenek 415eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek if (!C.getState()->getSVal(RetE, C.getLocationContext()).isUndef()) 421053d246f451c399468248625d1146e3d845e21eTed Kremenek return; 431053d246f451c399468248625d1146e3d845e21eTed Kremenek 44d048c6ef5b6cfaa0cecb8cc1d4bdace32ed21d07Ted Kremenek ExplodedNode *N = C.generateSink(); 451053d246f451c399468248625d1146e3d845e21eTed Kremenek 461053d246f451c399468248625d1146e3d845e21eTed Kremenek if (!N) 471053d246f451c399468248625d1146e3d845e21eTed Kremenek return; 481053d246f451c399468248625d1146e3d845e21eTed Kremenek 491053d246f451c399468248625d1146e3d845e21eTed Kremenek if (!BT) 507f649d749f18b3499456d7ae6a69f3bbd7cf7cdcArgyrios Kyrtzidis BT.reset(new BuiltinBug("Garbage return value", 517f649d749f18b3499456d7ae6a69f3bbd7cf7cdcArgyrios Kyrtzidis "Undefined or garbage value returned to caller")); 521053d246f451c399468248625d1146e3d845e21eTed Kremenek 53e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks BugReport *report = 54e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks new BugReport(*BT, BT->getDescription(), N); 551053d246f451c399468248625d1146e3d845e21eTed Kremenek 56017ca15cb3d7032e3779e6abb7b51bfe73ab4ddaTed Kremenek report->addRange(RetE->getSourceRange()); 57a1f81bb0e55749a1414b1b5124bb83b9052ff2acJordan Rose bugreporter::trackNullOrUndefValue(N, RetE, *report); 581053d246f451c399468248625d1146e3d845e21eTed Kremenek 591053d246f451c399468248625d1146e3d845e21eTed Kremenek C.EmitReport(report); 601053d246f451c399468248625d1146e3d845e21eTed Kremenek} 617f649d749f18b3499456d7ae6a69f3bbd7cf7cdcArgyrios Kyrtzidis 627f649d749f18b3499456d7ae6a69f3bbd7cf7cdcArgyrios Kyrtzidisvoid ento::registerReturnUndefChecker(CheckerManager &mgr) { 637f649d749f18b3499456d7ae6a69f3bbd7cf7cdcArgyrios Kyrtzidis mgr.registerChecker<ReturnUndefChecker>(); 647f649d749f18b3499456d7ae6a69f3bbd7cf7cdcArgyrios Kyrtzidis} 65