summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-03-18 04:25:13 +0000
committerChris Lattner <sabre@nondot.org>2009-03-18 04:25:13 +0000
commitc2a0b9795030d6434116e6a8587681bdd1d2acd6 (patch)
tree75bdb483da0415268842840292955db4434fc329
parent63d06ab65a9b6f3f2dced57345848adf289bdeb7 (diff)
downloadbcm5719-llvm-c2a0b9795030d6434116e6a8587681bdd1d2acd6.tar.gz
bcm5719-llvm-c2a0b9795030d6434116e6a8587681bdd1d2acd6.zip
fix PR3809, codegen for inc/dec of function pointers.
llvm-svn: 67165
-rw-r--r--clang/lib/CodeGen/CGExprScalar.cpp14
-rw-r--r--clang/test/CodeGen/exprs.c12
2 files changed, 23 insertions, 3 deletions
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 1a64e3c905a..80aa755e189 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -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 ->
diff --git a/clang/test/CodeGen/exprs.c b/clang/test/CodeGen/exprs.c
index db60b5a3301..c22a4ecc71d 100644
--- a/clang/test/CodeGen/exprs.c
+++ b/clang/test/CodeGen/exprs.c
@@ -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;
+}
+
OpenPOWER on IntegriCloud