zcov: / lib/Checker/Environment.cpp


Files: 1 Branches Taken: 77.8% 28 / 36
Generated: 2010-02-10 01:31 Branches Executed: 94.4% 34 / 36
Line Coverage: 93.8% 45 / 48


Programs: 1 Runs 2897


       1                 : //== Environment.cpp - Map from Stmt* to Locations/Values -------*- 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 defined the Environment and EnvironmentManager classes.
      11                 : //
      12                 : //===----------------------------------------------------------------------===//
      13                 : #include "clang/Checker/PathSensitive/GRState.h"
      14                 : #include "clang/Analysis/Analyses/LiveVariables.h"
      15                 : #include "llvm/ADT/ImmutableMap.h"
      16                 : 
      17                 : using namespace clang;
      18                 : 
      19            62723: SVal Environment::GetSVal(const Stmt *E, ValueManager& ValMgr) const {
      20                 : 
      21             1028:   for (;;) {
      22                 : 
                        0: branch 1 not taken
                     1028: branch 2 taken
                       58: branch 3 taken
                     5114: branch 4 taken
                    22634: branch 5 taken
                    33889: branch 6 taken
      23            62723:     switch (E->getStmtClass()) {
      24                 : 
      25                 :       case Stmt::AddrLabelExprClass:
      26                0:         return ValMgr.makeLoc(cast<AddrLabelExpr>(E));
      27                 : 
      28                 :         // ParenExprs are no-ops.
      29                 : 
      30                 :       case Stmt::ParenExprClass:
      31             1028:         E = cast<ParenExpr>(E)->getSubExpr();
      32                 :         continue;
      33                 : 
      34                 :       case Stmt::CharacterLiteralClass: {
      35               58:         const CharacterLiteral* C = cast<CharacterLiteral>(E);
      36               58:         return ValMgr.makeIntVal(C->getValue(), C->getType());
      37                 :       }
      38                 : 
      39                 :       case Stmt::IntegerLiteralClass: {
      40                 :         // In C++, this expression may have been bound to a temporary object.
      41             5114:         SVal const *X = ExprBindings.lookup(E);
                        1: branch 0 taken
                     5113: branch 1 taken
      42             5114:         if (X)
      43                1:           return *X;
      44                 :         else
      45             5113:           return ValMgr.makeIntVal(cast<IntegerLiteral>(E));
      46                 :       }
      47                 : 
      48                 :       // Casts where the source and target type are the same
      49                 :       // are no-ops.  We blast through these to get the descendant
      50                 :       // subexpression that has a value.
      51                 : 
      52                 :       case Stmt::ImplicitCastExprClass:
      53                 :       case Stmt::CStyleCastExprClass: {
      54            22634:         const CastExpr* C = cast<CastExpr>(E);
      55            22634:         QualType CT = C->getType();
      56                 : 
                       18: branch 2 taken
                    22616: branch 3 taken
      57            22634:         if (CT->isVoidType())
      58               18:           return UnknownVal();
      59                 : 
      60                 :         break;
      61                 :       }
      62                 : 
      63                 :         // Handle all other Stmt* using a lookup.
      64                 : 
      65                 :       default:
      66                 :         break;
      67                 :     };
      68                 : 
      69                 :     break;
      70                 :   }
      71                 : 
      72            56505:   return LookupExpr(E);
      73                 : }
      74                 : 
      75                 : Environment EnvironmentManager::BindExpr(Environment Env, const Stmt *S,
      76            28058:                                          SVal V, bool Invalidate) {
                        0: branch 0 not taken
                    28058: branch 1 taken
      77            28058:   assert(S);
      78                 : 
                     1110: branch 1 taken
                    26948: branch 2 taken
      79            28058:   if (V.isUnknown()) {
                     1110: branch 0 taken
                        0: branch 1 not taken
      80             1110:     if (Invalidate)
      81             1110:       return Environment(F.Remove(Env.ExprBindings, S), Env.ACtx);
      82                 :     else
      83                0:       return Env;
      84                 :   }
      85                 : 
      86            26948:   return Environment(F.Add(Env.ExprBindings, S, V), Env.ACtx);
      87                 : }
      88                 : 
      89                 : namespace {
                        0: branch 1 not taken
                        0: branch 2 not taken
                        0: branch 5 not taken
                     2437: branch 6 taken
      90             2437: class MarkLiveCallback : public SymbolVisitor {
      91                 :   SymbolReaper &SymReaper;
      92                 : public:
      93             2437:   MarkLiveCallback(SymbolReaper &symreaper) : SymReaper(symreaper) {}
      94             1202:   bool VisitSymbol(SymbolRef sym) { SymReaper.markLive(sym); return true; }
      95                 : };
      96                 : } // end anonymous namespace
      97                 : 
      98                 : // RemoveDeadBindings:
      99                 : //  - Remove subexpression bindings.
     100                 : //  - Remove dead block expression bindings.
     101                 : //  - Keep live block expression bindings:
     102                 : //   - Mark their reachable symbols live in SymbolReaper,
     103                 : //     see ScanReachableSymbols.
     104                 : //   - Mark the region in DRoots if the binding is a loc::MemRegionVal.
     105                 : 
     106                 : Environment
     107                 : EnvironmentManager::RemoveDeadBindings(Environment Env, const Stmt *S,
     108                 :                                        SymbolReaper &SymReaper,
     109                 :                                        const GRState *ST,
     110            11706:                               llvm::SmallVectorImpl<const MemRegion*> &DRoots) {
     111                 : 
     112            11706:   CFG &C = *Env.getAnalysisContext().getCFG();
     113                 : 
     114                 :   // We construct a new Environment object entirely, as this is cheaper than
     115                 :   // individually removing all the subexpression bindings (which will greatly
     116                 :   // outnumber block-level expression bindings).
     117            11706:   Environment NewEnv = getInitialEnvironment(&Env.getAnalysisContext());
     118                 : 
     119                 :   // Iterate over the block-expr bindings.
                    24486: branch 4 taken
                    11706: branch 5 taken
     120            36192:   for (Environment::iterator I = Env.begin(), E = Env.end();
     121                 :        I != E; ++I) {
     122                 : 
     123            24486:     const Stmt *BlkExpr = I.getKey();
     124                 : 
     125                 :     // Not a block-level expression?
                    16506: branch 1 taken
                     7980: branch 2 taken
     126            24486:     if (!C.isBlkExpr(BlkExpr))
     127            16506:       continue;
     128                 : 
     129             7980:     const SVal &X = I.getData();
     130                 : 
                     2437: branch 1 taken
                     5543: branch 2 taken
     131             7980:     if (SymReaper.isLive(S, BlkExpr)) {
     132                 :       // Copy the binding to the new map.
     133             2437:       NewEnv.ExprBindings = F.Add(NewEnv.ExprBindings, BlkExpr, X);
     134                 : 
     135                 :       // If the block expr's value is a memory region, then mark that region.
                      966: branch 1 taken
                     1471: branch 2 taken
     136             2437:       if (isa<loc::MemRegionVal>(X)) {
     137              966:         const MemRegion* R = cast<loc::MemRegionVal>(X).getRegion();
     138              966:         DRoots.push_back(R);
     139                 :         // Mark the super region of the RX as live.
     140                 :         // e.g.: int x; char *y = (char*) &x; if (*y) ...
     141                 :         // 'y' => element region. 'x' is its super region.
     142                 :         // We only add one level super region for now.
     143                 : 
     144                 :         // FIXME: maybe multiple level of super regions should be added.
                      966: branch 1 taken
                        0: branch 2 not taken
     145              966:         if (const SubRegion *SR = dyn_cast<SubRegion>(R))
     146              966:           DRoots.push_back(SR->getSuperRegion());
     147                 :       }
     148                 : 
     149                 :       // Mark all symbols in the block expr's value live.
     150             2437:       MarkLiveCallback cb(SymReaper);
     151             2437:       ST->scanReachableSymbols(X, cb);
     152             2437:       continue;
     153                 :     }
     154                 : 
     155                 :     // Otherwise the expression is dead with a couple exceptions.
     156                 :     // Do not misclean LogicalExpr or ConditionalOperator.  It is dead at the
     157                 :     // beginning of itself, but we need its UndefinedVal to determine its
     158                 :     // SVal.
                      699: branch 1 taken
                     4844: branch 2 taken
                      699: branch 5 taken
                        0: branch 6 not taken
                      699: branch 7 taken
                     4844: branch 8 taken
     159             5543:     if (X.isUndef() && cast<UndefinedVal>(X).getData())
     160              699:       NewEnv.ExprBindings = F.Add(NewEnv.ExprBindings, BlkExpr, X);
     161            11706:   }
     162                 : 
     163                 :   return NewEnv;
     164                0: }

Generated: 2010-02-10 01:31 by zcov