comparison gen/llvmhelpers.cpp @ 440:d8dc221d3db7

Insert array bound checks for slices.
author Christian Kamm <kamm incasoftware de>
date Wed, 30 Jul 2008 19:02:13 +0200
parents 47b64d06eb9f
children ca80e42d11e0
comparison
equal deleted inserted replaced
439:47b64d06eb9f 440:d8dc221d3db7
156 /****************************************************************************************/ 156 /****************************************************************************************/
157 /*//////////////////////////////////////////////////////////////////////////////////////// 157 /*////////////////////////////////////////////////////////////////////////////////////////
158 // ARRAY BOUNDS HELPER 158 // ARRAY BOUNDS HELPER
159 ////////////////////////////////////////////////////////////////////////////////////////*/ 159 ////////////////////////////////////////////////////////////////////////////////////////*/
160 160
161 void DtoArrayBoundsCheck(Loc& loc, DValue* arr, DValue* index) 161 void DtoArrayBoundsCheck(Loc& loc, DValue* arr, DValue* index, bool isslice)
162 { 162 {
163 Type* arrty = arr->getType(); 163 Type* arrty = arr->getType();
164 assert((arrty->ty == Tsarray || arrty->ty == Tarray) && "Can only array bounds check for static or dynamic arrays"); 164 assert((arrty->ty == Tsarray || arrty->ty == Tarray) && "Can only array bounds check for static or dynamic arrays");
165 165
166 // static arrays can get static checks for static indices 166 // static arrays can get static checks for static indices
169 { 169 {
170 TypeSArray* tsa = (TypeSArray*)arrty; 170 TypeSArray* tsa = (TypeSArray*)arrty;
171 size_t tdim = tsa->dim->toInteger(); 171 size_t tdim = tsa->dim->toInteger();
172 172
173 if(llvm::ConstantInt* cindex = llvm::dyn_cast<llvm::ConstantInt>(index->getRVal())) 173 if(llvm::ConstantInt* cindex = llvm::dyn_cast<llvm::ConstantInt>(index->getRVal()))
174 if(cindex->uge(tdim)) { 174 if(cindex->uge(tdim + (isslice ? 1 : 0))) {
175 error(loc, "index %d is larger than array size %d", index, tdim); 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);
176 return; 180 return;
177 } 181 }
178 } 182 }
179 183
180 // runtime check 184 // runtime check
181 185
182 llvm::BasicBlock* oldend = gIR->scopeend(); 186 llvm::BasicBlock* oldend = gIR->scopeend();
183 llvm::BasicBlock* failbb = llvm::BasicBlock::Create("arrayboundscheckfail", gIR->topfunc(), oldend); 187 llvm::BasicBlock* failbb = llvm::BasicBlock::Create("arrayboundscheckfail", gIR->topfunc(), oldend);
184 llvm::BasicBlock* okbb = llvm::BasicBlock::Create("arrayboundsok", gIR->topfunc(), oldend); 188 llvm::BasicBlock* okbb = llvm::BasicBlock::Create("arrayboundsok", gIR->topfunc(), oldend);
185 189
186 LLValue* cond = gIR->ir->CreateICmp(llvm::ICmpInst::ICMP_ULT, index->getRVal(), DtoArrayLen(arr), "boundscheck"); 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");
187 gIR->ir->CreateCondBr(cond, okbb, failbb); 192 gIR->ir->CreateCondBr(cond, okbb, failbb);
188 193
189 // set up failbb to call the array bounds error runtime function 194 // set up failbb to call the array bounds error runtime function
190 195
191 gIR->scope() = IRScope(failbb, okbb); 196 gIR->scope() = IRScope(failbb, okbb);