Coverage Report

Created: 2020-03-31 06:27

/Users/buildslave/jenkins/workspace/coverage/llvm-project/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
13.2k
SimpleConstraintManager::~SimpleConstraintManager() {}
24
25
ProgramStateRef SimpleConstraintManager::assume(ProgramStateRef State,
26
                                                DefinedSVal Cond,
27
928k
                                                bool Assumption) {
28
928k
  // If we have a Loc value, cast it to a bool NonLoc first.
29
928k
  if (Optional<Loc> LV = Cond.getAs<Loc>()) {
30
788k
    SValBuilder &SVB = State->getStateManager().getSValBuilder();
31
788k
    QualType T;
32
788k
    const MemRegion *MR = LV->getAsRegion();
33
788k
    if (const TypedRegion *TR = dyn_cast_or_null<TypedRegion>(MR))
34
761k
      T = TR->getLocationType();
35
27.5k
    else
36
27.5k
      T = SVB.getContext().VoidPtrTy;
37
788k
38
788k
    Cond = SVB.evalCast(*LV, SVB.getContext().BoolTy, T).castAs<DefinedSVal>();
39
788k
  }
40
928k
41
928k
  return assume(State, Cond.castAs<NonLoc>(), Assumption);
42
928k
}
43
44
ProgramStateRef SimpleConstraintManager::assume(ProgramStateRef State,
45
928k
                                                NonLoc Cond, bool Assumption) {
46
928k
  State = assumeAux(State, Cond, Assumption);
47
928k
  if (NotifyAssumeClients && SU)
48
928k
    return SU->processAssume(State, Cond, Assumption);
49
0
  return State;
50
0
}
51
52
ProgramStateRef SimpleConstraintManager::assumeAux(ProgramStateRef State,
53
                                                   NonLoc Cond,
54
928k
                                                   bool Assumption) {
55
928k
56
928k
  // We cannot reason about SymSymExprs, and can only reason about some
57
928k
  // SymIntExprs.
58
928k
  if (!canReasonAbout(Cond)) {
59
3.77k
    // Just add the constraint to the expression without trying to simplify.
60
3.77k
    SymbolRef Sym = Cond.getAsSymExpr();
61
3.77k
    assert(Sym);
62
3.77k
    return assumeSymUnsupported(State, Sym, Assumption);
63
3.77k
  }
64
924k
65
924k
  switch (Cond.getSubKind()) {
66
0
  default:
67
0
    llvm_unreachable("'Assume' not implemented for this NonLoc");
68
0
69
189k
  case nonloc::SymbolValKind: {
70
189k
    nonloc::SymbolVal SV = Cond.castAs<nonloc::SymbolVal>();
71
189k
    SymbolRef Sym = SV.getSymbol();
72
189k
    assert(Sym);
73
189k
    return assumeSym(State, Sym, Assumption);
74
0
  }
75
0
76
734k
  case nonloc::ConcreteIntKind: {
77
734k
    bool b = Cond.castAs<nonloc::ConcreteInt>().getValue() != 0;
78
734k
    bool isFeasible = b ? 
Assumption717k
:
!Assumption17.1k
;
79
734k
    return isFeasible ? 
State359k
:
nullptr374k
;
80
0
  }
81
0
82
36
  case nonloc::PointerToMemberKind: {
83
36
    bool IsNull = !Cond.castAs<nonloc::PointerToMember>().isNullMemberPointer();
84
36
    bool IsFeasible = IsNull ? Assumption : 
!Assumption0
;
85
36
    return IsFeasible ? 
State18
:
nullptr18
;
86
0
  }
87
0
88
38
  case nonloc::LocAsIntegerKind:
89
38
    return assume(State, Cond.castAs<nonloc::LocAsInteger>().getLoc(),
90
38
                  Assumption);
91
924k
  } // end switch
92
924k
}
93
94
ProgramStateRef SimpleConstraintManager::assumeInclusiveRange(
95
    ProgramStateRef State, NonLoc Value, const llvm::APSInt &From,
96
2.53k
    const llvm::APSInt &To, bool InRange) {
97
2.53k
98
2.53k
  assert(From.isUnsigned() == To.isUnsigned() &&
99
2.53k
         From.getBitWidth() == To.getBitWidth() &&
100
2.53k
         "Values should have same types!");
101
2.53k
102
2.53k
  if (!canReasonAbout(Value)) {
103
24
    // Just add the constraint to the expression without trying to simplify.
104
24
    SymbolRef Sym = Value.getAsSymExpr();
105
24
    assert(Sym);
106
24
    return assumeSymInclusiveRange(State, Sym, From, To, InRange);
107
24
  }
108
2.50k
109
2.50k
  switch (Value.getSubKind()) {
110
0
  default:
111
0
    llvm_unreachable("'assumeInclusiveRange' is not implemented"
112
0
                     "for this NonLoc");
113
0
114
1.82k
  case nonloc::LocAsIntegerKind:
115
1.82k
  case nonloc::SymbolValKind: {
116
1.82k
    if (SymbolRef Sym = Value.getAsSymbol())
117
1.82k
      return assumeSymInclusiveRange(State, Sym, From, To, InRange);
118
2
    return State;
119
2
  } // end switch
120
2
121
679
  case nonloc::ConcreteIntKind: {
122
679
    const llvm::APSInt &IntVal = Value.castAs<nonloc::ConcreteInt>().getValue();
123
679
    bool IsInRange = IntVal >= From && 
IntVal <= To491
;
124
679
    bool isFeasible = (IsInRange == InRange);
125
679
    return isFeasible ? 
State431
:
nullptr248
;
126
2
  }
127
2.50k
  } // end switch
128
2.50k
}
129
130
} // end of namespace ento
131
132
} // end of namespace clang