clang API Documentation

ReturnUndefChecker.cpp
Go to the documentation of this file.
00001 //== ReturnUndefChecker.cpp -------------------------------------*- C++ -*--==//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file defines ReturnUndefChecker, which is a path-sensitive
00011 // check which looks for undefined or garbage values being returned to the
00012 // caller.
00013 //
00014 //===----------------------------------------------------------------------===//
00015 
00016 #include "ClangSACheckers.h"
00017 #include "clang/StaticAnalyzer/Core/Checker.h"
00018 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
00019 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
00020 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
00021 
00022 using namespace clang;
00023 using namespace ento;
00024 
00025 namespace {
00026 class ReturnUndefChecker : 
00027     public Checker< check::PreStmt<ReturnStmt> > {
00028   mutable OwningPtr<BuiltinBug> BT;
00029 public:
00030   void checkPreStmt(const ReturnStmt *RS, CheckerContext &C) const;
00031 };
00032 }
00033 
00034 void ReturnUndefChecker::checkPreStmt(const ReturnStmt *RS,
00035                                       CheckerContext &C) const {
00036  
00037   const Expr *RetE = RS->getRetValue();
00038   if (!RetE)
00039     return;
00040   
00041   if (!C.getState()->getSVal(RetE, C.getLocationContext()).isUndef())
00042     return;
00043   
00044   ExplodedNode *N = C.generateSink();
00045 
00046   if (!N)
00047     return;
00048   
00049   if (!BT)
00050     BT.reset(new BuiltinBug("Garbage return value",
00051                             "Undefined or garbage value returned to caller"));
00052     
00053   BugReport *report = 
00054     new BugReport(*BT, BT->getDescription(), N);
00055 
00056   report->addRange(RetE->getSourceRange());
00057   report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, RetE,
00058                                                                   report));
00059 
00060   C.EmitReport(report);
00061 }
00062 
00063 void ento::registerReturnUndefChecker(CheckerManager &mgr) {
00064   mgr.registerChecker<ReturnUndefChecker>();
00065 }