diff options
-rw-r--r-- | lib/CodeGen/CGExprConstant.cpp | 16 | ||||
-rw-r--r-- | test/CodeGen/struct-init.c | 13 |
2 files changed, 26 insertions, 3 deletions
diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp index be9eaad9ac..58b1884817 100644 --- a/lib/CodeGen/CGExprConstant.cpp +++ b/lib/CodeGen/CGExprConstant.cpp @@ -447,9 +447,19 @@ public: // int - int return llvm::ConstantExpr::getSub(LHS, RHS); } - - assert(0 && "Unhandled bin sub case!"); - return 0; + + assert(isa<llvm::PointerType>(LHS->getType())); + + const llvm::Type *ResultType = ConvertType(E->getType()); + const QualType Type = E->getLHS()->getType(); + const QualType ElementType = Type->getAsPointerType()->getPointeeType(); + + LHS = llvm::ConstantExpr::getPtrToInt(LHS, ResultType); + RHS = llvm::ConstantExpr::getPtrToInt(RHS, ResultType); + + llvm::Constant *sub = llvm::ConstantExpr::getSub(LHS, RHS); + llvm::Constant *size = EmitSizeAlignOf(ElementType, E->getType(), true); + return llvm::ConstantExpr::getSDiv(sub, size); } llvm::Constant *VisitBinShl(const BinaryOperator *E) { diff --git a/test/CodeGen/struct-init.c b/test/CodeGen/struct-init.c new file mode 100644 index 0000000000..5b815de399 --- /dev/null +++ b/test/CodeGen/struct-init.c @@ -0,0 +1,13 @@ +// RUN: clang %s -emit-llvm + +typedef struct _zend_ini_entry zend_ini_entry; +struct _zend_ini_entry { + void *mh_arg1; +}; + +char a; + +const zend_ini_entry ini_entries[] = { + { ((char*)&((zend_ini_entry*)0)->mh_arg1 - (char*)(void*)0)}, + { ((long long*)&a - (long long*)(void*)2)}, +}; |