blob: 88b360d1d0ebadac503c4dfb371df0f77254d1aa [file] [log] [blame]
Ted Kremenek240f1f02008-03-07 20:13:31 +00001//=== BasicValueFactory.cpp - Basic values for Path Sens analysis --*- C++ -*-//
Ted Kremenekd70d0b02008-02-16 01:12:31 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
Ted Kremenek240f1f02008-03-07 20:13:31 +000010// This file defines BasicValueFactory, a class that manages the lifetime
11// of APSInt objects and symbolic constraints used by GRExprEngine
12// and related classes.
Ted Kremenekd70d0b02008-02-16 01:12:31 +000013//
14//===----------------------------------------------------------------------===//
15
Ted Kremenek240f1f02008-03-07 20:13:31 +000016#include "clang/Analysis/PathSensitive/BasicValueFactory.h"
Ted Kremenekd70d0b02008-02-16 01:12:31 +000017
18using namespace clang;
19
Ted Kremenek240f1f02008-03-07 20:13:31 +000020BasicValueFactory::~BasicValueFactory() {
Ted Kremenekd70d0b02008-02-16 01:12:31 +000021 // Note that the dstor for the contents of APSIntSet will never be called,
22 // so we iterate over the set and invoke the dstor for each APSInt. This
23 // frees an aux. memory allocated to represent very large constants.
24 for (APSIntSetTy::iterator I=APSIntSet.begin(), E=APSIntSet.end(); I!=E; ++I)
25 I->getValue().~APSInt();
26}
27
Ted Kremenek240f1f02008-03-07 20:13:31 +000028const llvm::APSInt& BasicValueFactory::getValue(const llvm::APSInt& X) {
Ted Kremenekd70d0b02008-02-16 01:12:31 +000029 llvm::FoldingSetNodeID ID;
30 void* InsertPos;
31 typedef llvm::FoldingSetNodeWrapper<llvm::APSInt> FoldNodeTy;
32
33 X.Profile(ID);
34 FoldNodeTy* P = APSIntSet.FindNodeOrInsertPos(ID, InsertPos);
35
36 if (!P) {
37 P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
38 new (P) FoldNodeTy(X);
39 APSIntSet.InsertNode(P, InsertPos);
40 }
41
42 return *P;
43}
44
Ted Kremenek240f1f02008-03-07 20:13:31 +000045const llvm::APSInt& BasicValueFactory::getValue(uint64_t X, unsigned BitWidth,
Ted Kremenekd70d0b02008-02-16 01:12:31 +000046 bool isUnsigned) {
47 llvm::APSInt V(BitWidth, isUnsigned);
48 V = X;
49 return getValue(V);
50}
51
Ted Kremenek240f1f02008-03-07 20:13:31 +000052const llvm::APSInt& BasicValueFactory::getValue(uint64_t X, QualType T) {
Ted Kremenekd70d0b02008-02-16 01:12:31 +000053
Chris Lattner98be4942008-03-05 18:54:05 +000054 unsigned bits = Ctx.getTypeSize(T);
Ted Kremenekd70d0b02008-02-16 01:12:31 +000055 llvm::APSInt V(bits, T->isUnsignedIntegerType());
56 V = X;
57 return getValue(V);
58}
59
60const SymIntConstraint&
Ted Kremenek240f1f02008-03-07 20:13:31 +000061BasicValueFactory::getConstraint(SymbolID sym, BinaryOperator::Opcode Op,
Ted Kremenekd70d0b02008-02-16 01:12:31 +000062 const llvm::APSInt& V) {
63
64 llvm::FoldingSetNodeID ID;
65 SymIntConstraint::Profile(ID, sym, Op, V);
66 void* InsertPos;
67
68 SymIntConstraint* C = SymIntCSet.FindNodeOrInsertPos(ID, InsertPos);
69
70 if (!C) {
71 C = (SymIntConstraint*) BPAlloc.Allocate<SymIntConstraint>();
72 new (C) SymIntConstraint(sym, Op, V);
73 SymIntCSet.InsertNode(C, InsertPos);
74 }
75
76 return *C;
77}
78
Ted Kremenek8cc13ea2008-02-28 20:32:03 +000079const llvm::APSInt*
Ted Kremenek240f1f02008-03-07 20:13:31 +000080BasicValueFactory::EvaluateAPSInt(BinaryOperator::Opcode Op,
Ted Kremenekd70d0b02008-02-16 01:12:31 +000081 const llvm::APSInt& V1, const llvm::APSInt& V2) {
82
83 switch (Op) {
84 default:
85 assert (false && "Invalid Opcode.");
86
87 case BinaryOperator::Mul:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +000088 return &getValue( V1 * V2 );
Ted Kremenekd70d0b02008-02-16 01:12:31 +000089
90 case BinaryOperator::Div:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +000091 return &getValue( V1 / V2 );
Ted Kremenekd70d0b02008-02-16 01:12:31 +000092
93 case BinaryOperator::Rem:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +000094 return &getValue( V1 % V2 );
Ted Kremenekd70d0b02008-02-16 01:12:31 +000095
96 case BinaryOperator::Add:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +000097 return &getValue( V1 + V2 );
Ted Kremenekd70d0b02008-02-16 01:12:31 +000098
99 case BinaryOperator::Sub:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000100 return &getValue( V1 - V2 );
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000101
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000102 case BinaryOperator::Shl: {
103
104 // FIXME: This logic should probably go higher up, where we can
105 // test these conditions symbolically.
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000106
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000107 // FIXME: Expand these checks to include all undefined behavior.
108
109 if (V2.isSigned() && V2.isNegative())
110 return NULL;
111
112 uint64_t Amt = V2.getZExtValue();
113
114 if (Amt > V1.getBitWidth())
115 return NULL;
116
117 return &getValue( V1.operator<<( (unsigned) Amt ));
118 }
119
120 case BinaryOperator::Shr: {
121
122 // FIXME: This logic should probably go higher up, where we can
123 // test these conditions symbolically.
124
125 // FIXME: Expand these checks to include all undefined behavior.
126
127 if (V2.isSigned() && V2.isNegative())
128 return NULL;
129
130 uint64_t Amt = V2.getZExtValue();
131
132 if (Amt > V1.getBitWidth())
133 return NULL;
134
135 return &getValue( V1.operator>>( (unsigned) Amt ));
136 }
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000137
138 case BinaryOperator::LT:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000139 return &getTruthValue( V1 < V2 );
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000140
141 case BinaryOperator::GT:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000142 return &getTruthValue( V1 > V2 );
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000143
144 case BinaryOperator::LE:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000145 return &getTruthValue( V1 <= V2 );
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000146
147 case BinaryOperator::GE:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000148 return &getTruthValue( V1 >= V2 );
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000149
150 case BinaryOperator::EQ:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000151 return &getTruthValue( V1 == V2 );
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000152
153 case BinaryOperator::NE:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000154 return &getTruthValue( V1 != V2 );
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000155
156 // Note: LAnd, LOr, Comma are handled specially by higher-level logic.
157
158 case BinaryOperator::And:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000159 return &getValue( V1 & V2 );
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000160
161 case BinaryOperator::Or:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000162 return &getValue( V1 | V2 );
Ted Kremenek1caf26a2008-02-19 20:53:37 +0000163
164 case BinaryOperator::Xor:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000165 return &getValue( V1 ^ V2 );
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000166 }
167}