Coverage Report

Created: 2023-09-21 18:56

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