diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp
index 5e0159e..37b0948 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -18,6 +18,7 @@
 #include "clang/AST/RecordLayout.h"
 #include "clang/AST/StmtVisitor.h"
 #include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/SourceManager.h"
 #include "llvm/Constants.h"
 #include "llvm/Function.h"
 #include "llvm/GlobalVariable.h"
@@ -272,13 +273,14 @@ public:
   // Binary Operators.
   Value *EmitMul(const BinOpInfo &Ops) {
     if (CGF.getContext().getLangOptions().OverflowChecking
-        && Ops.Ty->isSignedIntegerType())
+        && Ops.Ty->isIntegerType())
       return EmitOverflowCheckedBinOp(Ops);
     return Builder.CreateMul(Ops.LHS, Ops.RHS, "mul");
   }
   /// Create a binary op that checks for overflow.
   /// Currently only supports +, - and *.
   Value *EmitOverflowCheckedBinOp(const BinOpInfo &Ops);
+  Value *EmitOverflowInst(unsigned IID, std::string &err, PresumedLoc loc, const BinOpInfo &Info);
   Value *EmitDiv(const BinOpInfo &Ops);
   Value *EmitRem(const BinOpInfo &Ops);
   Value *EmitAdd(const BinOpInfo &Ops);
@@ -679,7 +681,20 @@ Value *ScalarExprEmitter::VisitPrePostIncDec(const UnaryOperator *E,
                 &ignored);
       NextVal = llvm::ConstantFP::get(F);
     }
-    NextVal = Builder.CreateAdd(InVal, NextVal, isInc ? "inc" : "dec");
+
+    if (CGF.getContext().getLangOptions().OverflowChecking && ValTy->isIntegerType()) {
+      std::string e = isInc ? "Integer increment overflow" : "Integer decrement overflow";
+      unsigned IID = ValTy->isSignedIntegerType() ?
+        llvm::Intrinsic::sadd_with_overflow : llvm::Intrinsic::uadd_with_overflow;
+      PresumedLoc loc = CGF.getContext().getSourceManager().getPresumedLoc(E->getOperatorLoc());
+      BinOpInfo Ops;
+      Ops.Ty = ValTy;
+      Ops.LHS = InVal;
+      Ops.RHS = NextVal;
+      NextVal = EmitOverflowInst(IID, e, loc, Ops);
+    } else {
+      NextVal = Builder.CreateAdd(InVal, NextVal, isInc ? "inc" : "dec");
+    }
   }
   
   // Store the updated result through the lvalue.
@@ -847,41 +862,48 @@ Value *ScalarExprEmitter::EmitRem(const BinOpInfo &Ops) {
 
 Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(const BinOpInfo &Ops) {
   unsigned IID;
-  unsigned OpID = 0;
+  std::string e;
 
   switch (Ops.E->getOpcode()) {
   case BinaryOperator::Add:
   case BinaryOperator::AddAssign:
-    OpID = 1;
-    IID = llvm::Intrinsic::sadd_with_overflow;
+    e = "Integer addition overflow";
+    IID = Ops.Ty->isSignedIntegerType() ? llvm::Intrinsic::sadd_with_overflow
+    	: llvm::Intrinsic::uadd_with_overflow;
     break;
   case BinaryOperator::Sub:
   case BinaryOperator::SubAssign:
-    OpID = 2;
-    IID = llvm::Intrinsic::ssub_with_overflow;
+    e = "Integer subtraction overflow";
+    IID = Ops.Ty->isSignedIntegerType() ? llvm::Intrinsic::ssub_with_overflow
+    	: llvm::Intrinsic::usub_with_overflow;
     break;
   case BinaryOperator::Mul:
   case BinaryOperator::MulAssign:
-    OpID = 3;
-    IID = llvm::Intrinsic::smul_with_overflow;
+    e = "Integer multiplication overflow";
+    IID = Ops.Ty->isSignedIntegerType() ? llvm::Intrinsic::smul_with_overflow
+    	: llvm::Intrinsic::umul_with_overflow;
     break;
   default:
     assert(false && "Unsupported operation for overflow detection");
     IID = 0;
   }
-  OpID <<= 1;
-  OpID |= 1;
 
-  const llvm::Type *opTy = CGF.CGM.getTypes().ConvertType(Ops.Ty);
+  PresumedLoc loc = CGF.getContext().getSourceManager().getPresumedLoc(Ops.E->getOperatorLoc());
+
+  return EmitOverflowInst(IID, e, loc, Ops);
+}
+
+// Info.E is not used
+Value *ScalarExprEmitter::EmitOverflowInst(unsigned IID, std::string &err, PresumedLoc loc, const BinOpInfo &Info) {
+  const llvm::Type *opTy = CGF.CGM.getTypes().ConvertType(Info.Ty);
 
   llvm::Function *intrinsic = CGF.CGM.getIntrinsic(IID, &opTy, 1);
 
-  Value *resultAndOverflow = Builder.CreateCall2(intrinsic, Ops.LHS, Ops.RHS);
+  Value *resultAndOverflow = Builder.CreateCall2(intrinsic, Info.LHS, Info.RHS);
   Value *result = Builder.CreateExtractValue(resultAndOverflow, 0);
   Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
 
   // Branch in case of overflow.
-  llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
   llvm::BasicBlock *overflowBB =
     CGF.createBasicBlock("overflow", CGF.CurFn);
   llvm::BasicBlock *continueBB =
@@ -893,47 +915,36 @@ Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(const BinOpInfo &Ops) {
 
   Builder.SetInsertPoint(overflowBB);
 
+  QualType cCharPtr = CGF.getContext().getPointerType(CGF.getContext().CharTy);
+  cCharPtr.setCVRQualifiers(QualType::Const);
+  QualType integer = CGF.getContext().IntTy;
+
+  llvm::Value *error = Builder.CreateStructGEP(CGF.CGM.GetAddrOfConstantCString(err), 0, "arraydecay");
+  llvm::Value *func = Builder.CreateStructGEP(CGF.CGM.GetAddrOfConstantCString(CGF.CurFn->getName()), 0, "arraydecay");
+  llvm::Value *file = Builder.CreateStructGEP(CGF.CGM.GetAddrOfConstantCString(std::string(loc.getFilename())), 0, "arraydecay");
+
   // Handler is:
-  // long long *__overflow_handler)(long long a, long long b, char op, 
-  // char width)
-  std::vector<const llvm::Type*> handerArgTypes;
-  handerArgTypes.push_back(llvm::Type::Int64Ty);
-  handerArgTypes.push_back(llvm::Type::Int64Ty);
-  handerArgTypes.push_back(llvm::Type::Int8Ty);
-  handerArgTypes.push_back(llvm::Type::Int8Ty);
-  llvm::FunctionType *handlerTy = llvm::FunctionType::get(llvm::Type::Int64Ty,
-      handerArgTypes, false);
-  llvm::Value *handlerFunction =
-    CGF.CGM.getModule().getOrInsertGlobal("__overflow_handler",
-        llvm::PointerType::getUnqual(handlerTy));
-  handlerFunction = Builder.CreateLoad(handlerFunction);
-
-  llvm::Value *handlerResult = Builder.CreateCall4(handlerFunction,
-      Builder.CreateSExt(Ops.LHS, llvm::Type::Int64Ty),
-      Builder.CreateSExt(Ops.RHS, llvm::Type::Int64Ty),
-      llvm::ConstantInt::get(llvm::Type::Int8Ty, OpID),
-      llvm::ConstantInt::get(llvm::Type::Int8Ty, 
-        cast<llvm::IntegerType>(opTy)->getBitWidth()));
-
-  handlerResult = Builder.CreateTrunc(handlerResult, opTy);
-
-  Builder.CreateBr(continueBB);
+  // void __acc_runtime_failure_line(const char *error, const char *func,
+  // const char *file, int line)
+  llvm::Function *handlerFunction = llvm::dyn_cast<llvm::Function>(
+    CGF.CGM.getModule().getOrInsertFunction(std::string("__acc_runtime_failure_line"), llvm::Type::VoidTy, error->getType(), func->getType(), file->getType(), ConvertType(integer), NULL));
+  assert(handlerFunction && "getOrInsertFunction didn't produce llvm::Function");
+  handlerFunction->addFnAttr(llvm::Attribute::NoReturn | llvm::Attribute::NoUnwind);
+
+  Builder.CreateCall4(handlerFunction, error, func, file,
+      llvm::ConstantInt::get(ConvertType(integer), loc.getLine()));
+  Builder.CreateUnreachable();
+
   
   // Set up the continuation
   Builder.SetInsertPoint(continueBB);
-  // Get the correct result
-  llvm::PHINode *phi = Builder.CreatePHI(opTy);
-  phi->reserveOperandSpace(2);
-  phi->addIncoming(result, initialBB);
-  phi->addIncoming(handlerResult, overflowBB);
-
-  return phi;
+  return result;
 }
 
 Value *ScalarExprEmitter::EmitAdd(const BinOpInfo &Ops) {
   if (!Ops.Ty->isPointerType()) {
     if (CGF.getContext().getLangOptions().OverflowChecking
-        && Ops.Ty->isSignedIntegerType())
+        && Ops.Ty->isIntegerType())
       return EmitOverflowCheckedBinOp(Ops);
     return Builder.CreateAdd(Ops.LHS, Ops.RHS, "add");
   }
@@ -998,7 +1009,7 @@ Value *ScalarExprEmitter::EmitAdd(const BinOpInfo &Ops) {
 Value *ScalarExprEmitter::EmitSub(const BinOpInfo &Ops) {
   if (!isa<llvm::PointerType>(Ops.LHS->getType())) {
     if (CGF.getContext().getLangOptions().OverflowChecking
-        && Ops.Ty->isSignedIntegerType())
+        && Ops.Ty->isIntegerType())
       return EmitOverflowCheckedBinOp(Ops);
     return Builder.CreateSub(Ops.LHS, Ops.RHS, "sub");
   }
