Mercurial > projects > ldc
comparison gen/llvmhelpers.cpp @ 439:47b64d06eb9f
Enable array bounds check and emit them in IndexExp.
author | Christian Kamm <kamm incasoftware de> |
---|---|
date | Wed, 30 Jul 2008 18:38:56 +0200 |
parents | 74101be2a553 |
children | d8dc221d3db7 |
comparison
equal
deleted
inserted
replaced
438:3c133dd1eda3 | 439:47b64d06eb9f |
---|---|
149 CallOrInvoke* call = gIR->CreateCallOrInvoke(fn, args.begin(), args.end()); | 149 CallOrInvoke* call = gIR->CreateCallOrInvoke(fn, args.begin(), args.end()); |
150 call->setParamAttrs(palist); | 150 call->setParamAttrs(palist); |
151 | 151 |
152 // after assert is always unreachable | 152 // after assert is always unreachable |
153 gIR->ir->CreateUnreachable(); | 153 gIR->ir->CreateUnreachable(); |
154 } | |
155 | |
156 /****************************************************************************************/ | |
157 /*//////////////////////////////////////////////////////////////////////////////////////// | |
158 // ARRAY BOUNDS HELPER | |
159 ////////////////////////////////////////////////////////////////////////////////////////*/ | |
160 | |
161 void DtoArrayBoundsCheck(Loc& loc, DValue* arr, DValue* index) | |
162 { | |
163 Type* arrty = arr->getType(); | |
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)) { | |
175 error(loc, "index %d is larger than array size %d", index, tdim); | |
176 return; | |
177 } | |
178 } | |
179 | |
180 // runtime check | |
181 | |
182 llvm::BasicBlock* oldend = gIR->scopeend(); | |
183 llvm::BasicBlock* failbb = llvm::BasicBlock::Create("arrayboundscheckfail", gIR->topfunc(), oldend); | |
184 llvm::BasicBlock* okbb = llvm::BasicBlock::Create("arrayboundsok", gIR->topfunc(), oldend); | |
185 | |
186 LLValue* cond = gIR->ir->CreateICmp(llvm::ICmpInst::ICMP_ULT, index->getRVal(), DtoArrayLen(arr), "boundscheck"); | |
187 gIR->ir->CreateCondBr(cond, okbb, failbb); | |
188 | |
189 // set up failbb to call the array bounds error runtime function | |
190 | |
191 gIR->scope() = IRScope(failbb, okbb); | |
192 | |
193 std::vector<LLValue*> args; | |
194 llvm::PAListPtr palist; | |
195 | |
196 // file param | |
197 // FIXME: every array bounds check creates a global for the filename !!! | |
198 LLConstant* c = DtoConstString(loc.filename); | |
199 | |
200 llvm::AllocaInst* alloc = gIR->func()->srcfileArg; | |
201 if (!alloc) | |
202 { | |
203 alloc = new llvm::AllocaInst(c->getType(), ".srcfile", gIR->topallocapoint()); | |
204 gIR->func()->srcfileArg = alloc; | |
205 } | |
206 LLValue* ptr = DtoGEPi(alloc, 0,0, "tmp"); | |
207 DtoStore(c->getOperand(0), ptr); | |
208 ptr = DtoGEPi(alloc, 0,1, "tmp"); | |
209 DtoStore(c->getOperand(1), ptr); | |
210 | |
211 args.push_back(alloc); | |
212 palist = palist.addAttr(1, llvm::ParamAttr::ByVal); | |
213 | |
214 // line param | |
215 c = DtoConstUint(loc.linnum); | |
216 args.push_back(c); | |
217 | |
218 // call | |
219 llvm::Function* errorfn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_array_bounds"); | |
220 CallOrInvoke* call = gIR->CreateCallOrInvoke(errorfn, args.begin(), args.end()); | |
221 call->setParamAttrs(palist); | |
222 | |
223 // the function does not return | |
224 gIR->ir->CreateUnreachable(); | |
225 | |
226 | |
227 // if ok, proceed in okbb | |
228 gIR->scope() = IRScope(okbb, oldend); | |
154 } | 229 } |
155 | 230 |
156 /****************************************************************************************/ | 231 /****************************************************************************************/ |
157 /*//////////////////////////////////////////////////////////////////////////////////////// | 232 /*//////////////////////////////////////////////////////////////////////////////////////// |
158 // LABEL HELPER | 233 // LABEL HELPER |