Coverage Report

Created: 2020-11-24 06:42

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