diff options
| -rw-r--r-- | clang/include/clang/Analysis/PathSensitive/ValueState.h | 17 | ||||
| -rw-r--r-- | clang/lib/Analysis/ValueState.cpp | 120 | 
2 files changed, 108 insertions, 29 deletions
diff --git a/clang/include/clang/Analysis/PathSensitive/ValueState.h b/clang/include/clang/Analysis/PathSensitive/ValueState.h index 554e6f5f869..46f62e12ebc 100644 --- a/clang/include/clang/Analysis/PathSensitive/ValueState.h +++ b/clang/include/clang/Analysis/PathSensitive/ValueState.h @@ -365,7 +365,6 @@ public:    const ValueState* AddNE(const ValueState* St, SymbolID sym,                            const llvm::APSInt& V); -      bool isEqual(const ValueState* state, Expr* Ex, const llvm::APSInt& V);    bool isEqual(const ValueState* state, Expr* Ex, uint64_t); @@ -397,6 +396,9 @@ private:    const ValueState* AssumeAux(const ValueState* St, NonLVal Cond,                                bool Assumption, bool& isFeasible); +     +  const ValueState* AssumeSymInt(const ValueState* St, bool Assumption,                                  +                                 const SymIntConstraint& C, bool& isFeasible);    const ValueState* AssumeSymNE(const ValueState* St, SymbolID sym,                                  const llvm::APSInt& V, bool& isFeasible); @@ -404,8 +406,17 @@ private:    const ValueState* AssumeSymEQ(const ValueState* St, SymbolID sym,                                  const llvm::APSInt& V, bool& isFeasible); -  const ValueState* AssumeSymInt(const ValueState* St, bool Assumption, -                                 const SymIntConstraint& C, bool& isFeasible); +  const ValueState* AssumeSymLT(const ValueState* St, SymbolID sym, +                                const llvm::APSInt& V, bool& isFeasible); +   +  const ValueState* AssumeSymLE(const ValueState* St, SymbolID sym, +                                const llvm::APSInt& V, bool& isFeasible); +   +  const ValueState* AssumeSymGT(const ValueState* St, SymbolID sym, +                                const llvm::APSInt& V, bool& isFeasible); +   +  const ValueState* AssumeSymGE(const ValueState* St, SymbolID sym, +                                const llvm::APSInt& V, bool& isFeasible);  };  } // end clang namespace diff --git a/clang/lib/Analysis/ValueState.cpp b/clang/lib/Analysis/ValueState.cpp index 1cf695438bb..ffc4c28f2cd 100644 --- a/clang/lib/Analysis/ValueState.cpp +++ b/clang/lib/Analysis/ValueState.cpp @@ -435,9 +435,52 @@ const ValueState* ValueStateManager::AssumeAux(const ValueState* St, NonLVal Con    }  } -const ValueState* ValueStateManager::AssumeSymNE(const ValueState* St, -                                            SymbolID sym, const llvm::APSInt& V, -                                            bool& isFeasible) { + + +const ValueState* ValueStateManager::AssumeSymInt(const ValueState* St, +                                             bool Assumption, +                                             const SymIntConstraint& C, +                                             bool& isFeasible) { +   +  switch (C.getOpcode()) { +    default: +      // No logic yet for other operators. +      isFeasible = true; +      return St; +       +    case BinaryOperator::EQ: +      if (Assumption) +        return AssumeSymEQ(St, C.getSymbol(), C.getInt(), isFeasible); +      else +        return AssumeSymNE(St, C.getSymbol(), C.getInt(), isFeasible); +       +    case BinaryOperator::NE: +      if (Assumption) +        return AssumeSymNE(St, C.getSymbol(), C.getInt(), isFeasible); +      else +        return AssumeSymEQ(St, C.getSymbol(), C.getInt(), isFeasible); +       +    case BinaryOperator::GE: +      if (Assumption) +        return AssumeSymGE(St, C.getSymbol(), C.getInt(), isFeasible); +      else +        return AssumeSymLT(St, C.getSymbol(), C.getInt(), isFeasible); +       +    case BinaryOperator::LE: +      if (Assumption) +        return AssumeSymLE(St, C.getSymbol(), C.getInt(), isFeasible); +      else +        return AssumeSymGT(St, C.getSymbol(), C.getInt(), isFeasible);     +  } +} + +//===----------------------------------------------------------------------===// +// FIXME: This should go into a plug-in constraint engine. +//===----------------------------------------------------------------------===// + +const ValueState* +ValueStateManager::AssumeSymNE(const ValueState* St, SymbolID sym, +                               const llvm::APSInt& V, bool& isFeasible) {    // First, determine if sym == X, where X != V.    if (const llvm::APSInt* X = St->getSymVal(sym)) { @@ -458,8 +501,9 @@ const ValueState* ValueStateManager::AssumeSymNE(const ValueState* St,    return AddNE(St, sym, V);  } -const ValueState* ValueStateManager::AssumeSymEQ(const ValueState* St, SymbolID sym, -                                            const llvm::APSInt& V, bool& isFeasible) { +const ValueState* +ValueStateManager::AssumeSymEQ(const ValueState* St, SymbolID sym, +                               const llvm::APSInt& V, bool& isFeasible) {    // First, determine if sym == X, where X != V.    if (const llvm::APSInt* X = St->getSymVal(sym)) { @@ -480,27 +524,51 @@ const ValueState* ValueStateManager::AssumeSymEQ(const ValueState* St, SymbolID    return AddEQ(St, sym, V);  } -const ValueState* ValueStateManager::AssumeSymInt(const ValueState* St, -                                             bool Assumption, -                                             const SymIntConstraint& C, -                                             bool& isFeasible) { +const ValueState* +ValueStateManager::AssumeSymLT(const ValueState* St, SymbolID sym, +                               const llvm::APSInt& V, bool& isFeasible) { -  switch (C.getOpcode()) { -    default: -      // No logic yet for other operators. -      isFeasible = true; -      return St; -       -    case BinaryOperator::EQ: -      if (Assumption) -        return AssumeSymEQ(St, C.getSymbol(), C.getInt(), isFeasible); -      else -        return AssumeSymNE(St, C.getSymbol(), C.getInt(), isFeasible); -       -    case BinaryOperator::NE: -      if (Assumption) -        return AssumeSymNE(St, C.getSymbol(), C.getInt(), isFeasible); -      else -        return AssumeSymEQ(St, C.getSymbol(), C.getInt(), isFeasible); +  // FIXME: For now have assuming x < y be the same as assuming sym != V; +  return AssumeSymNE(St, sym, V, isFeasible); +} + +const ValueState* +ValueStateManager::AssumeSymGT(const ValueState* St, SymbolID sym, +                               const llvm::APSInt& V, bool& isFeasible) { +   +  // FIXME: For now have assuming x > y be the same as assuming sym != V; +  return AssumeSymNE(St, sym, V, isFeasible); +} + +const ValueState* +ValueStateManager::AssumeSymGE(const ValueState* St, SymbolID sym, +                               const llvm::APSInt& V, bool& isFeasible) { +   +  // FIXME: Primitive logic for now.  Only reject a path if the value of +  //  sym is a constant X and !(X >= V). +   +  if (const llvm::APSInt* X = St->getSymVal(sym)) { +    isFeasible = *X >= V; +    return St;    } +   +  isFeasible = true; +  return St;  } + +const ValueState* +ValueStateManager::AssumeSymLE(const ValueState* St, SymbolID sym, +                               const llvm::APSInt& V, bool& isFeasible) { +   +  // FIXME: Primitive logic for now.  Only reject a path if the value of +  //  sym is a constant X and !(X <= V). +     +  if (const llvm::APSInt* X = St->getSymVal(sym)) { +    isFeasible = *X <= V; +    return St; +  } +   +  isFeasible = true; +  return St; +} +  | 

