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 ////////////////////////////////////////////////////////////////////////////////////////*/