SVals.cpp revision 8cc13ea74fea1c04042a2f4087665bc5182e8408
1a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//= RValues.cpp - Abstract RValues for Path-Sens. Value Tracking -*- C++ -*-==// 2a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// 3a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// The LLVM Compiler Infrastructure 4a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// 5a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// This file is distributed under the University of Illinois Open Source 6a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// License. See LICENSE.TXT for details. 7a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// 8a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//===----------------------------------------------------------------------===// 9a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// 10aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek// This files defines RVal, LVal, and NonLVal, classes that represent 11a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// abstract r-values for use with path-sensitive value tracking. 12a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// 13a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//===----------------------------------------------------------------------===// 14a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 15cc409b764e12ff81d422bc4317e0b7552cf10011Ted Kremenek#include "clang/Analysis/PathSensitive/RValues.h" 16d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek#include "llvm/Support/Streams.h" 17a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 18a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekusing namespace clang; 19a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekusing llvm::dyn_cast; 20a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekusing llvm::cast; 21a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekusing llvm::APSInt; 22a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 23a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//===----------------------------------------------------------------------===// 2490e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenek// Symbol Iteration. 2590e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenek//===----------------------------------------------------------------------===// 2690e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenek 27aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted KremenekRVal::symbol_iterator RVal::symbol_begin() const { 28aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek if (isa<lval::SymbolVal>(this)) 29aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return (symbol_iterator) (&Data); 30aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek else if (isa<nonlval::SymbolVal>(this)) 31aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return (symbol_iterator) (&Data); 32aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek else if (isa<nonlval::SymIntConstraintVal>(this)) { 33aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek const SymIntConstraint& C = 34aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek cast<nonlval::SymIntConstraintVal>(this)->getConstraint(); 35aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 36aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return (symbol_iterator) &C.getSymbol(); 3790e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenek } 3890e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenek 3990e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenek return NULL; 4090e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenek} 41a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 42aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted KremenekRVal::symbol_iterator RVal::symbol_end() const { 4390e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenek symbol_iterator X = symbol_begin(); 4490e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenek return X ? X+1 : NULL; 4590e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenek} 46cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek 47cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek//===----------------------------------------------------------------------===// 48aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek// Transfer function dispatch for Non-LVals. 49cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek//===----------------------------------------------------------------------===// 50cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek 518cc13ea74fea1c04042a2f4087665bc5182e8408Ted KremenekRVal 52aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremeneknonlval::ConcreteInt::EvalBinOp(ValueManager& ValMgr, BinaryOperator::Opcode Op, 53aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek const nonlval::ConcreteInt& R) const { 54aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 558cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek const llvm::APSInt* X = ValMgr.EvaluateAPSInt(Op, getValue(), R.getValue()); 568cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek 578cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek if (X) 588cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek return nonlval::ConcreteInt(*X); 598cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek else 608cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek return UndefinedVal(); 61cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek} 62cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek 63cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek 64cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek // Bitwise-Complement. 65cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek 66cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremeneknonlval::ConcreteInt 67cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremeneknonlval::ConcreteInt::EvalComplement(ValueManager& ValMgr) const { 68cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek return ValMgr.getValue(~getValue()); 69cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek} 70cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek 71cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek // Unary Minus. 72a6e4d21dc4fe87fe1b0bcd9c3c3ec43b391aa44bTed Kremenek 73cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremeneknonlval::ConcreteInt 74cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremeneknonlval::ConcreteInt::EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const { 75cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek assert (U->getType() == U->getSubExpr()->getType()); 76cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek assert (U->getType()->isIntegerType()); 77cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek return ValMgr.getValue(-getValue()); 78c5d3b4ca4707b1fe69629bfefd73087dc4893dd8Ted Kremenek} 79c5d3b4ca4707b1fe69629bfefd73087dc4893dd8Ted Kremenek 80cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek//===----------------------------------------------------------------------===// 81aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek// Transfer function dispatch for LVals. 82cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek//===----------------------------------------------------------------------===// 83c5d3b4ca4707b1fe69629bfefd73087dc4893dd8Ted Kremenek 848cc13ea74fea1c04042a2f4087665bc5182e8408Ted KremenekRVal 85aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremeneklval::ConcreteInt::EvalBinOp(ValueManager& ValMgr, BinaryOperator::Opcode Op, 86aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek const lval::ConcreteInt& R) const { 87cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek 88cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek assert (Op == BinaryOperator::Add || Op == BinaryOperator::Sub || 89cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek (Op >= BinaryOperator::LT && Op <= BinaryOperator::NE)); 90cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek 918cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek const llvm::APSInt* X = ValMgr.EvaluateAPSInt(Op, getValue(), R.getValue()); 928cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek 938cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek if (X) 948cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek return lval::ConcreteInt(*X); 958cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek else 968cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek return UndefinedVal(); 97a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek} 98a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 99aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted KremenekNonLVal LVal::EQ(ValueManager& ValMgr, const LVal& R) const { 100aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 101a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek switch (getSubKind()) { 102a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek default: 103aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek assert(false && "EQ not implemented for this LVal."); 104aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek break; 105cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek 1060806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek case lval::ConcreteIntKind: 107aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek if (isa<lval::ConcreteInt>(R)) { 1080806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek bool b = cast<lval::ConcreteInt>(this)->getValue() == 109aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek cast<lval::ConcreteInt>(R).getValue(); 110cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek 111aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return NonLVal::MakeIntTruthVal(ValMgr, b); 1120806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek } 113aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek else if (isa<lval::SymbolVal>(R)) { 114cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek 1150806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek const SymIntConstraint& C = 116aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek ValMgr.getConstraint(cast<lval::SymbolVal>(R).getSymbol(), 117aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek BinaryOperator::EQ, 118aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek cast<lval::ConcreteInt>(this)->getValue()); 1190806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek 1200806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek return nonlval::SymIntConstraintVal(C); 1210806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek } 1220806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek 1230806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek break; 1240806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek 125cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek case lval::SymbolValKind: { 126aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek if (isa<lval::ConcreteInt>(R)) { 127cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek 128cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek const SymIntConstraint& C = 129aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek ValMgr.getConstraint(cast<lval::SymbolVal>(this)->getSymbol(), 130aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek BinaryOperator::EQ, 131aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek cast<lval::ConcreteInt>(R).getValue()); 132cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek 133cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek return nonlval::SymIntConstraintVal(C); 134cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek } 135cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek 136aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek assert (!isa<lval::SymbolVal>(R) && "FIXME: Implement unification."); 1370806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek 138cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek break; 1390806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek } 140a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 141cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek case lval::DeclValKind: 142aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek if (isa<lval::DeclVal>(R)) { 143aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek bool b = cast<lval::DeclVal>(*this) == cast<lval::DeclVal>(R); 144aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return NonLVal::MakeIntTruthVal(ValMgr, b); 1450806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek } 1460806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek 1470806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek break; 148a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek } 1490806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek 150aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return NonLVal::MakeIntTruthVal(ValMgr, false); 151a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek} 152a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 153aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted KremenekNonLVal LVal::NE(ValueManager& ValMgr, const LVal& R) const { 154a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek switch (getSubKind()) { 155a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek default: 156aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek assert(false && "NE not implemented for this LVal."); 157aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek break; 158a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 1590806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek case lval::ConcreteIntKind: 160aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek if (isa<lval::ConcreteInt>(R)) { 1610806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek bool b = cast<lval::ConcreteInt>(this)->getValue() != 162aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek cast<lval::ConcreteInt>(R).getValue(); 1630806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek 164aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return NonLVal::MakeIntTruthVal(ValMgr, b); 1650806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek } 166aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek else if (isa<lval::SymbolVal>(R)) { 1670806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek 1680806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek const SymIntConstraint& C = 169aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek ValMgr.getConstraint(cast<lval::SymbolVal>(R).getSymbol(), 1700806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek BinaryOperator::NE, 1710806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek cast<lval::ConcreteInt>(this)->getValue()); 1720806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek 1730806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek return nonlval::SymIntConstraintVal(C); 1740806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek } 175a6e4d21dc4fe87fe1b0bcd9c3c3ec43b391aa44bTed Kremenek 1760806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek break; 177a6e4d21dc4fe87fe1b0bcd9c3c3ec43b391aa44bTed Kremenek 1780806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek case lval::SymbolValKind: { 179aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek if (isa<lval::ConcreteInt>(R)) { 1800806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek 1810806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek const SymIntConstraint& C = 1820806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek ValMgr.getConstraint(cast<lval::SymbolVal>(this)->getSymbol(), 1830806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek BinaryOperator::NE, 184aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek cast<lval::ConcreteInt>(R).getValue()); 1850806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek 1860806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek return nonlval::SymIntConstraintVal(C); 1870806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek } 1880806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek 189aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek assert (!isa<lval::SymbolVal>(R) && "FIXME: Implement sym !=."); 1900806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek 1910806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek break; 1920806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek } 1930806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek 1940806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek case lval::DeclValKind: 195aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek if (isa<lval::DeclVal>(R)) { 196aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek bool b = cast<lval::DeclVal>(*this) == cast<lval::DeclVal>(R); 197aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return NonLVal::MakeIntTruthVal(ValMgr, b); 198aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 1990806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek 200aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek break; 201a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek } 2020806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek 203aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return NonLVal::MakeIntTruthVal(ValMgr, true); 204a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek} 205a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 206a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//===----------------------------------------------------------------------===// 207aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek// Utility methods for constructing Non-LVals. 208a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//===----------------------------------------------------------------------===// 209a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 210aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted KremenekNonLVal NonLVal::MakeVal(ValueManager& ValMgr, uint64_t X, QualType T, 211aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek SourceLocation Loc) { 212aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 213329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek return nonlval::ConcreteInt(ValMgr.getValue(X, T, Loc)); 214a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek} 215a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 216aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted KremenekNonLVal NonLVal::MakeVal(ValueManager& ValMgr, IntegerLiteral* I) { 217aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 218329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek return nonlval::ConcreteInt(ValMgr.getValue(APSInt(I->getValue(), 219aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek I->getType()->isUnsignedIntegerType()))); 220a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek} 221a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 222aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted KremenekNonLVal NonLVal::MakeIntTruthVal(ValueManager& ValMgr, bool b) { 223aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 224cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek return nonlval::ConcreteInt(ValMgr.getTruthValue(b)); 225cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek} 226cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek 227d763eb91aab5bdecd11825fadb35d6d8cc905f63Ted KremenekRVal RVal::GetSymbolValue(SymbolManager& SymMgr, VarDecl* D) { 228aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 229a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek QualType T = D->getType(); 230a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 231a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek if (T->isPointerType() || T->isReferenceType()) 232329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek return lval::SymbolVal(SymMgr.getSymbol(D)); 233a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek else 234329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek return nonlval::SymbolVal(SymMgr.getSymbol(D)); 235a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek} 236a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 2372a502578a785d5e7ed9e08e2895dbdcfa5333c11Ted Kremenek//===----------------------------------------------------------------------===// 238aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek// Utility methods for constructing LVals. 2392a502578a785d5e7ed9e08e2895dbdcfa5333c11Ted Kremenek//===----------------------------------------------------------------------===// 2402a502578a785d5e7ed9e08e2895dbdcfa5333c11Ted Kremenek 241aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted KremenekLVal LVal::MakeVal(AddrLabelExpr* E) { return lval::GotoLabel(E->getLabel()); } 242cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek 243a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//===----------------------------------------------------------------------===// 244a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// Pretty-Printing. 245a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//===----------------------------------------------------------------------===// 246a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 247aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekvoid RVal::printStdErr() const { print(*llvm::cerr.stream()); } 248aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 249aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekvoid RVal::print(std::ostream& Out) const { 2502a502578a785d5e7ed9e08e2895dbdcfa5333c11Ted Kremenek 251a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek switch (getBaseKind()) { 252aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 25353c641a735da0c3fe077aab63a6fef16c8798937Ted Kremenek case UnknownKind: 254aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek Out << "Invalid"; break; 255a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 256aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek case NonLValKind: 257aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek cast<NonLVal>(this)->print(Out); break; 258a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 259aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek case LValKind: 260aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek cast<LVal>(this)->print(Out); break; 261a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 2624a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek case UndefinedKind: 2634a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek Out << "Undefined"; break; 264a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 265a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek default: 266aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek assert (false && "Invalid RVal."); 267a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek } 268a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek} 269a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 2700806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenekstatic void printOpcode(std::ostream& Out, BinaryOperator::Opcode Op) { 271aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 272aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek switch (Op) { 273aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek case BinaryOperator::Mul: Out << '*' ; break; 274aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek case BinaryOperator::Div: Out << '/' ; break; 275aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek case BinaryOperator::Rem: Out << '%' ; break; 276aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek case BinaryOperator::Add: Out << '+' ; break; 277aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek case BinaryOperator::Sub: Out << '-' ; break; 27850d0ac299c641bee9024f3fbae2ea0640898a040Ted Kremenek case BinaryOperator::Shl: Out << "<<" ; break; 27950d0ac299c641bee9024f3fbae2ea0640898a040Ted Kremenek case BinaryOperator::Shr: Out << ">>" ; break; 280aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek case BinaryOperator::LT: Out << "<" ; break; 281aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek case BinaryOperator::GT: Out << '>' ; break; 282aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek case BinaryOperator::LE: Out << "<=" ; break; 283aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek case BinaryOperator::GE: Out << ">=" ; break; 284aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek case BinaryOperator::EQ: Out << "==" ; break; 285aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek case BinaryOperator::NE: Out << "!=" ; break; 286aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek case BinaryOperator::And: Out << '&' ; break; 287aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek case BinaryOperator::Xor: Out << '^' ; break; 288aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek case BinaryOperator::Or: Out << '|' ; break; 289aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 2900806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek default: assert(false && "Not yet implemented."); 2910806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek } 2920806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek} 2930806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek 294aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekvoid NonLVal::print(std::ostream& Out) const { 295aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 296a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek switch (getSubKind()) { 297aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 298329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek case nonlval::ConcreteIntKind: 299329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek Out << cast<nonlval::ConcreteInt>(this)->getValue().toString(); 300cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek 301cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek if (cast<nonlval::ConcreteInt>(this)->getValue().isUnsigned()) 302cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek Out << 'U'; 303cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek 304a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek break; 305a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 306329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek case nonlval::SymbolValKind: 3070806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek Out << '$' << cast<nonlval::SymbolVal>(this)->getSymbol(); 308a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek break; 3090806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek 3100806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek case nonlval::SymIntConstraintValKind: { 3110806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek const nonlval::SymIntConstraintVal& C = 3120806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek *cast<nonlval::SymIntConstraintVal>(this); 3130806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek 3140806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek Out << '$' << C.getConstraint().getSymbol() << ' '; 3150806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek printOpcode(Out, C.getConstraint().getOpcode()); 3160806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek Out << ' ' << C.getConstraint().getInt().toString(); 317cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek 318cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek if (C.getConstraint().getInt().isUnsigned()) 319cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek Out << 'U'; 320cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek 3210806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek break; 3220806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek } 323a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 324a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek default: 325aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek assert (false && "Pretty-printed not implemented for this NonLVal."); 326a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek break; 327a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek } 328a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek} 329a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 330aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekvoid LVal::print(std::ostream& Out) const { 331aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 332a6e4d21dc4fe87fe1b0bcd9c3c3ec43b391aa44bTed Kremenek switch (getSubKind()) { 333aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 334329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek case lval::ConcreteIntKind: 335329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek Out << cast<lval::ConcreteInt>(this)->getValue().toString() 336aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek << " (LVal)"; 337a6e4d21dc4fe87fe1b0bcd9c3c3ec43b391aa44bTed Kremenek break; 338a6e4d21dc4fe87fe1b0bcd9c3c3ec43b391aa44bTed Kremenek 339329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek case lval::SymbolValKind: 3400806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek Out << '$' << cast<lval::SymbolVal>(this)->getSymbol(); 341a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek break; 3422a502578a785d5e7ed9e08e2895dbdcfa5333c11Ted Kremenek 3432a502578a785d5e7ed9e08e2895dbdcfa5333c11Ted Kremenek case lval::GotoLabelKind: 3442a502578a785d5e7ed9e08e2895dbdcfa5333c11Ted Kremenek Out << "&&" 3452a502578a785d5e7ed9e08e2895dbdcfa5333c11Ted Kremenek << cast<lval::GotoLabel>(this)->getLabel()->getID()->getName(); 3462a502578a785d5e7ed9e08e2895dbdcfa5333c11Ted Kremenek break; 34708b66255e2605adfa8777dbff293db1c69bc1092Ted Kremenek 348329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek case lval::DeclValKind: 349a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek Out << '&' 350de43424560f1a744de6214dab6bbee28ad8437f5Ted Kremenek << cast<lval::DeclVal>(this)->getDecl()->getIdentifier()->getName(); 351de43424560f1a744de6214dab6bbee28ad8437f5Ted Kremenek break; 352de43424560f1a744de6214dab6bbee28ad8437f5Ted Kremenek 353de43424560f1a744de6214dab6bbee28ad8437f5Ted Kremenek case lval::FuncValKind: 354de43424560f1a744de6214dab6bbee28ad8437f5Ted Kremenek Out << "function " 355de43424560f1a744de6214dab6bbee28ad8437f5Ted Kremenek << cast<lval::FuncVal>(this)->getDecl()->getIdentifier()->getName(); 356a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek break; 357a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 358a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek default: 359aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek assert (false && "Pretty-printing not implemented for this LVal."); 360a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek break; 361a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek } 362a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek} 363