Mercurial > projects > ldc
comparison gen/llvmhelpers.cpp @ 442:76078c8ab5b9
Move DtoArrayBoundsCheck from llvmhelpers to arrays.
author | Christian Kamm <kamm incasoftware de> |
---|---|
date | Thu, 31 Jul 2008 19:14:49 +0200 |
parents | ca80e42d11e0 |
children | cc40db549aea |
comparison
equal
deleted
inserted
replaced
441:ca80e42d11e0 | 442:76078c8ab5b9 |
---|---|
151 | 151 |
152 // after assert is always unreachable | 152 // after assert is always unreachable |
153 gIR->ir->CreateUnreachable(); | 153 gIR->ir->CreateUnreachable(); |
154 } | 154 } |
155 | 155 |
156 /****************************************************************************************/ | |
157 /*//////////////////////////////////////////////////////////////////////////////////////// | |
158 // ARRAY BOUNDS HELPER | |
159 ////////////////////////////////////////////////////////////////////////////////////////*/ | |
160 | |
161 void DtoArrayBoundsCheck(Loc& loc, DValue* arr, DValue* index, bool isslice) | |
162 { | |
163 Type* arrty = arr->getType()->toBasetype(); | |
164 assert((arrty->ty == Tsarray || arrty->ty == Tarray) && "Can only array bounds check for static or dynamic arrays"); | |
165 | |
166 // static arrays can get static checks for static indices | |
167 | |
168 if(arr->getType()->ty == Tsarray) | |
169 { | |
170 TypeSArray* tsa = (TypeSArray*)arrty; | |
171 size_t tdim = tsa->dim->toInteger(); | |
172 | |
173 if(llvm::ConstantInt* cindex = llvm::dyn_cast<llvm::ConstantInt>(index->getRVal())) | |
174 if(cindex->uge(tdim + (isslice ? 1 : 0))) { | |
175 size_t cindexval = cindex->getValue().getZExtValue(); | |
176 if(!isslice) | |
177 error(loc, "index %u is larger or equal array size %u", cindexval, tdim); | |
178 else | |
179 error(loc, "slice upper bound %u is larger than array size %u", cindexval, tdim); | |
180 return; | |
181 } | |
182 } | |
183 | |
184 // runtime check | |
185 | |
186 llvm::BasicBlock* oldend = gIR->scopeend(); | |
187 llvm::BasicBlock* failbb = llvm::BasicBlock::Create("arrayboundscheckfail", gIR->topfunc(), oldend); | |
188 llvm::BasicBlock* okbb = llvm::BasicBlock::Create("arrayboundsok", gIR->topfunc(), oldend); | |
189 | |
190 llvm::ICmpInst::Predicate cmpop = isslice ? llvm::ICmpInst::ICMP_ULE : llvm::ICmpInst::ICMP_ULT; | |
191 LLValue* cond = gIR->ir->CreateICmp(cmpop, index->getRVal(), DtoArrayLen(arr), "boundscheck"); | |
192 gIR->ir->CreateCondBr(cond, okbb, failbb); | |
193 | |
194 // set up failbb to call the array bounds error runtime function | |
195 | |
196 gIR->scope() = IRScope(failbb, okbb); | |
197 | |
198 std::vector<LLValue*> args; | |
199 llvm::PAListPtr palist; | |
200 | |
201 // file param | |
202 // FIXME: every array bounds check creates a global for the filename !!! | |
203 LLConstant* c = DtoConstString(loc.filename); | |
204 | |
205 llvm::AllocaInst* alloc = gIR->func()->srcfileArg; | |
206 if (!alloc) | |
207 { | |
208 alloc = new llvm::AllocaInst(c->getType(), ".srcfile", gIR->topallocapoint()); | |
209 gIR->func()->srcfileArg = alloc; | |
210 } | |
211 LLValue* ptr = DtoGEPi(alloc, 0,0, "tmp"); | |
212 DtoStore(c->getOperand(0), ptr); | |
213 ptr = DtoGEPi(alloc, 0,1, "tmp"); | |
214 DtoStore(c->getOperand(1), ptr); | |
215 | |
216 args.push_back(alloc); | |
217 palist = palist.addAttr(1, llvm::ParamAttr::ByVal); | |
218 | |
219 // line param | |
220 c = DtoConstUint(loc.linnum); | |
221 args.push_back(c); | |
222 | |
223 // call | |
224 llvm::Function* errorfn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_array_bounds"); | |
225 CallOrInvoke* call = gIR->CreateCallOrInvoke(errorfn, args.begin(), args.end()); | |
226 call->setParamAttrs(palist); | |
227 | |
228 // the function does not return | |
229 gIR->ir->CreateUnreachable(); | |
230 | |
231 | |
232 // if ok, proceed in okbb | |
233 gIR->scope() = IRScope(okbb, oldend); | |
234 } | |
235 | 156 |
236 /****************************************************************************************/ | 157 /****************************************************************************************/ |
237 /*//////////////////////////////////////////////////////////////////////////////////////// | 158 /*//////////////////////////////////////////////////////////////////////////////////////// |
238 // LABEL HELPER | 159 // LABEL HELPER |
239 ////////////////////////////////////////////////////////////////////////////////////////*/ | 160 ////////////////////////////////////////////////////////////////////////////////////////*/ |