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