Mercurial > projects > ldc
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); |