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