brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.5 KiB · dd5e374 Raw
133 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8//9//  This file defines SimpleConstraintManager, a class that provides a10//  simplified constraint manager interface, compared to ConstraintManager.11//12//===----------------------------------------------------------------------===//13 14#include "clang/StaticAnalyzer/Core/PathSensitive/SimpleConstraintManager.h"15#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"16#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"17#include <optional>18 19namespace clang {20 21namespace ento {22 23SimpleConstraintManager::~SimpleConstraintManager() {}24 25ProgramStateRef SimpleConstraintManager::assumeInternal(ProgramStateRef State,26                                                        DefinedSVal Cond,27                                                        bool Assumption) {28  // If we have a Loc value, cast it to a bool NonLoc first.29  if (std::optional<Loc> LV = Cond.getAs<Loc>()) {30    SValBuilder &SVB = State->getStateManager().getSValBuilder();31    QualType T;32    const MemRegion *MR = LV->getAsRegion();33    if (const TypedRegion *TR = dyn_cast_or_null<TypedRegion>(MR))34      T = TR->getLocationType();35    else36      T = SVB.getContext().VoidPtrTy;37 38    Cond = SVB.evalCast(*LV, SVB.getContext().BoolTy, T).castAs<DefinedSVal>();39  }40 41  return assume(State, Cond.castAs<NonLoc>(), Assumption);42}43 44ProgramStateRef SimpleConstraintManager::assume(ProgramStateRef State,45                                                NonLoc Cond, bool Assumption) {46  State = assumeAux(State, Cond, Assumption);47  if (EE)48    return EE->processAssume(State, Cond, Assumption);49  return State;50}51 52ProgramStateRef SimpleConstraintManager::assumeAux(ProgramStateRef State,53                                                   NonLoc Cond,54                                                   bool Assumption) {55 56  // We cannot reason about SymSymExprs, and can only reason about some57  // SymIntExprs.58  if (!canReasonAbout(Cond)) {59    // Just add the constraint to the expression without trying to simplify.60    SymbolRef Sym = Cond.getAsSymbol();61    assert(Sym);62    return assumeSymUnsupported(State, Sym, Assumption);63  }64 65  switch (Cond.getKind()) {66  default:67    llvm_unreachable("'Assume' not implemented for this NonLoc");68 69  case nonloc::SymbolValKind: {70    nonloc::SymbolVal SV = Cond.castAs<nonloc::SymbolVal>();71    SymbolRef Sym = SV.getSymbol();72    assert(Sym);73    return assumeSym(State, Sym, Assumption);74  }75 76  case nonloc::ConcreteIntKind: {77    bool b = *Cond.castAs<nonloc::ConcreteInt>().getValue() != 0;78    bool isFeasible = b ? Assumption : !Assumption;79    return isFeasible ? State : nullptr;80  }81 82  case nonloc::PointerToMemberKind: {83    bool IsNull = !Cond.castAs<nonloc::PointerToMember>().isNullMemberPointer();84    bool IsFeasible = IsNull ? Assumption : !Assumption;85    return IsFeasible ? State : nullptr;86  }87 88  case nonloc::LocAsIntegerKind:89    return assumeInternal(State, Cond.castAs<nonloc::LocAsInteger>().getLoc(),90                          Assumption);91  } // end switch92}93 94ProgramStateRef SimpleConstraintManager::assumeInclusiveRangeInternal(95    ProgramStateRef State, NonLoc Value, const llvm::APSInt &From,96    const llvm::APSInt &To, bool InRange) {97 98  assert(From.isUnsigned() == To.isUnsigned() &&99         From.getBitWidth() == To.getBitWidth() &&100         "Values should have same types!");101 102  if (!canReasonAbout(Value)) {103    // Just add the constraint to the expression without trying to simplify.104    SymbolRef Sym = Value.getAsSymbol();105    assert(Sym);106    return assumeSymInclusiveRange(State, Sym, From, To, InRange);107  }108 109  switch (Value.getKind()) {110  default:111    llvm_unreachable("'assumeInclusiveRange' is not implemented"112                     "for this NonLoc");113 114  case nonloc::LocAsIntegerKind:115  case nonloc::SymbolValKind: {116    if (SymbolRef Sym = Value.getAsSymbol())117      return assumeSymInclusiveRange(State, Sym, From, To, InRange);118    return State;119  } // end switch120 121  case nonloc::ConcreteIntKind: {122    const llvm::APSInt &IntVal = Value.castAs<nonloc::ConcreteInt>().getValue();123    bool IsInRange = IntVal >= From && IntVal <= To;124    bool isFeasible = (IsInRange == InRange);125    return isFeasible ? State : nullptr;126  }127  } // end switch128}129 130} // end of namespace ento131 132} // end of namespace clang133