Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
Line
Count
Source (jump to first uncovered line)
1
//== SimpleConstraintManager.cpp --------------------------------*- C++ -*--==//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
//  This file defines SimpleConstraintManager, a class that provides a
10
//  simplified constraint manager interface, compared to ConstraintManager.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "clang/StaticAnalyzer/Core/PathSensitive/SimpleConstraintManager.h"
15
#include "clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h"
16
#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
17
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
18
19
namespace clang {
20
21
namespace ento {
22
23
10.8k
SimpleConstraintManager::~SimpleConstraintManager() {}
24
25
ProgramStateRef SimpleConstraintManager::assume(ProgramStateRef State,
26
                                                DefinedSVal Cond,
27
665k
                                                bool Assumption) {
28
665k
  // If we have a Loc value, cast it to a bool NonLoc first.
29
665k
  if (Optional<Loc> LV = Cond.getAs<Loc>()) {
30
548k
    SValBuilder &SVB = State->getStateManager().getSValBuilder();
31
548k
    QualType T;
32
548k
    const MemRegion *MR = LV->getAsRegion();
33
548k
    if (const TypedRegion *TR = dyn_cast_or_null<TypedRegion>(MR))
34
530k
      T = TR->getLocationType();
35
17.7k
    else
36
17.7k
      T = SVB.getContext().VoidPtrTy;
37
548k
38
548k
    Cond = SVB.evalCast(*LV, SVB.getContext().BoolTy, T).castAs<DefinedSVal>();
39
548k
  }
40
665k
41
665k
  return assume(State, Cond.castAs<NonLoc>(), Assumption);
42
665k
}
43
44
ProgramStateRef SimpleConstraintManager::assume(ProgramStateRef State,
45
665k
                                                NonLoc Cond, bool Assumption) {
46
665k
  State = assumeAux(State, Cond, Assumption);
47
665k
  if (NotifyAssumeClients && SU)
48
665k
    return SU->processAssume(State, Cond, Assumption);
49
0
  return State;
50
0
}
51
52
ProgramStateRef SimpleConstraintManager::assumeAux(ProgramStateRef State,
53
                                                   NonLoc Cond,
54
665k
                                                   bool Assumption) {
55
665k
56
665k
  // We cannot reason about SymSymExprs, and can only reason about some
57
665k
  // SymIntExprs.
58
665k
  if (!canReasonAbout(Cond)) {
59
3.74k
    // Just add the constraint to the expression without trying to simplify.
60
3.74k
    SymbolRef Sym = Cond.getAsSymExpr();
61
3.74k
    assert(Sym);
62
3.74k
    return assumeSymUnsupported(State, Sym, Assumption);
63
3.74k
  }
64
661k
65
661k
  switch (Cond.getSubKind()) {
66
661k
  default:
67
0
    llvm_unreachable("'Assume' not implemented for this NonLoc");
68
661k
69
661k
  case nonloc::SymbolValKind: {
70
160k
    nonloc::SymbolVal SV = Cond.castAs<nonloc::SymbolVal>();
71
160k
    SymbolRef Sym = SV.getSymbol();
72
160k
    assert(Sym);
73
160k
    return assumeSym(State, Sym, Assumption);
74
661k
  }
75
661k
76
661k
  case nonloc::ConcreteIntKind: {
77
500k
    bool b = Cond.castAs<nonloc::ConcreteInt>().getValue() != 0;
78
500k
    bool isFeasible = b ? 
Assumption486k
:
!Assumption14.8k
;
79
500k
    return isFeasible ? 
State243k
:
nullptr257k
;
80
661k
  }
81
661k
82
661k
  case nonloc::PointerToMemberKind: {
83
16
    bool IsNull = !Cond.castAs<nonloc::PointerToMember>().isNullMemberPointer();
84
16
    bool IsFeasible = IsNull ? Assumption : 
!Assumption0
;
85
16
    return IsFeasible ? 
State8
:
nullptr8
;
86
661k
  }
87
661k
88
661k
  case nonloc::LocAsIntegerKind:
89
34
    return assume(State, Cond.castAs<nonloc::LocAsInteger>().getLoc(),
90
34
                  Assumption);
91
661k
  } // end switch
92
661k
}
93
94
ProgramStateRef SimpleConstraintManager::assumeInclusiveRange(
95
    ProgramStateRef State, NonLoc Value, const llvm::APSInt &From,
96
2.49k
    const llvm::APSInt &To, bool InRange) {
97
2.49k
98
2.49k
  assert(From.isUnsigned() == To.isUnsigned() &&
99
2.49k
         From.getBitWidth() == To.getBitWidth() &&
100
2.49k
         "Values should have same types!");
101
2.49k
102
2.49k
  if (!canReasonAbout(Value)) {
103
12
    // Just add the constraint to the expression without trying to simplify.
104
12
    SymbolRef Sym = Value.getAsSymExpr();
105
12
    assert(Sym);
106
12
    return assumeSymInclusiveRange(State, Sym, From, To, InRange);
107
12
  }
108
2.47k
109
2.47k
  switch (Value.getSubKind()) {
110
2.47k
  default:
111
0
    llvm_unreachable("'assumeInclusiveRange' is not implemented"
112
2.47k
                     "for this NonLoc");
113
2.47k
114
2.47k
  case nonloc::LocAsIntegerKind:
115
1.76k
  case nonloc::SymbolValKind: {
116
1.76k
    if (SymbolRef Sym = Value.getAsSymbol())
117
1.76k
      return assumeSymInclusiveRange(State, Sym, From, To, InRange);
118
2
    return State;
119
2
  } // end switch
120
2
121
714
  case nonloc::ConcreteIntKind: {
122
714
    const llvm::APSInt &IntVal = Value.castAs<nonloc::ConcreteInt>().getValue();
123
714
    bool IsInRange = IntVal >= From && 
IntVal <= To490
;
124
714
    bool isFeasible = (IsInRange == InRange);
125
714
    return isFeasible ? 
State464
:
nullptr250
;
126
2
  }
127
2.47k
  } // end switch
128
2.47k
}
129
130
} // end of namespace ento
131
132
} // end of namespace clang