fix PR3809, codegen for inc/dec of function pointers.

llvm-svn: 67165
This commit is contained in:
Chris Lattner 2009-03-18 04:25:13 +00:00
parent 63d06ab65a
commit c2a0b97950
2 changed files with 23 additions and 3 deletions

View File

@ -627,10 +627,18 @@ Value *ScalarExprEmitter::VisitPrePostIncDec(const UnaryOperator *E,
int AmountVal = isInc ? 1 : -1;
Value *NextVal;
if (isa<llvm::PointerType>(InVal->getType())) {
if (const llvm::PointerType *PT =
dyn_cast<llvm::PointerType>(InVal->getType())) {
// FIXME: This isn't right for VLAs.
NextVal = llvm::ConstantInt::get(llvm::Type::Int32Ty, AmountVal);
NextVal = Builder.CreateGEP(InVal, NextVal, "ptrincdec");
llvm::Constant *Inc =llvm::ConstantInt::get(llvm::Type::Int32Ty, AmountVal);
if (!isa<llvm::FunctionType>(PT->getElementType())) {
NextVal = Builder.CreateGEP(InVal, Inc, "ptrincdec");
} else {
const llvm::Type *i8Ty = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
NextVal = Builder.CreateBitCast(InVal, i8Ty, "tmp");
NextVal = Builder.CreateGEP(NextVal, Inc, "ptrincdec");
NextVal = Builder.CreateBitCast(NextVal, InVal->getType());
}
} else if (InVal->getType() == llvm::Type::Int1Ty && isInc) {
// Bool++ is an interesting case, due to promotion rules, we get:
// Bool++ -> Bool = Bool+1 -> Bool = (int)Bool+1 ->

View File

@ -67,3 +67,15 @@ int bar() {
return ((struct X)foo()).Y + 1;
}
// PR3809: INC/DEC of function pointers.
void f2(void);
unsigned f1(void) {
void (*fp)(void) = f2;
++fp;
fp++;
--fp;
fp--;
return (unsigned) fp;
}