From c1b0e23bf098151bea013252c19f8794343a5b05 Mon Sep 17 00:00:00 2001
From: Will Dietz <w@wdtz.org>
Date: Tue, 13 Mar 2012 11:19:51 -0500
Subject: [PATCH] Ported IOC to mainline.

---
 include/clang/Basic/LangOptions.def |   10 +
 include/clang/Driver/CC1Options.td  |   20 +
 include/clang/Driver/OptTable.h     |    2 +
 include/clang/Driver/Options.td     |   20 +
 lib/CodeGen/CGBlocks.cpp            |   12 +
 lib/CodeGen/CGBuiltin.cpp           |    2 +-
 lib/CodeGen/CGExpr.cpp              |  299 ++++++++++-
 lib/CodeGen/CGExprCXX.cpp           |   20 +-
 lib/CodeGen/CGExprScalar.cpp        |  948 +++++++++++++++++++++++++++++++++--
 lib/CodeGen/CodeGenFunction.cpp     |   23 +-
 lib/CodeGen/CodeGenFunction.h       |  162 ++++++
 lib/CodeGen/CodeGenModule.cpp       |    1 +
 lib/CodeGen/CodeGenModule.h         |    5 +
 lib/Driver/Driver.cpp               |   43 ++
 lib/Driver/OptTable.cpp             |   35 ++
 lib/Driver/Tools.cpp                |   10 +
 lib/Frontend/CompilerInvocation.cpp |   30 ++
 17 files changed, 1599 insertions(+), 43 deletions(-)

diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def
index d2ce7c0..d97c1a4 100644
--- a/include/clang/Basic/LangOptions.def
+++ b/include/clang/Basic/LangOptions.def
@@ -117,6 +117,16 @@ LANGOPT(CUDA              , 1, 0, "CUDA")
 LANGOPT(AssumeSaneOperatorNew , 1, 1, "implicit __attribute__((malloc)) for C++'s new operators")
 BENIGN_LANGOPT(ElideConstructors , 1, 1, "C++ copy constructor elision")
 BENIGN_LANGOPT(CatchUndefined    , 1, 0, "catching undefined behavior at run time")
+BENIGN_LANGOPT(CatchUndefinedAnsiC    , 1, 0, "Generate code to check for undefined ops in AnsiC.")
+BENIGN_LANGOPT(CatchUndefinedC99    , 1, 0, "Generate code to check for undefined ops in C99.")
+BENIGN_LANGOPT(CatchUndefinedCXX0X    , 1, 0, "Generate code to check for undefined ops in CXX0X.")
+BENIGN_LANGOPT(CatchUndefinedCXX98    , 1, 0, "Generate code to check for undefined ops in CXX98.")
+BENIGN_LANGOPT(CatchNonArithUndefined    , 1, 0, "Generate code to check for non-arithmetic undefined ops.")
+BENIGN_LANGOPT(UseIntrinsic    , 1, 0, "Use GCC's intrinsic overflow checks to examine arithmetic operation overflow.")
+BENIGN_LANGOPT(UseRandomValue    , 1, 0, "Use the values returned by trap handler as arithmetic operations' results.")
+BENIGN_LANGOPT(HandlerNull    , 1, 0, "__ub_trap_handler refers to NULL. ")
+BENIGN_LANGOPT(ChecksNum    , 1, 0, "Output the number of instrumented checks. ")
+BENIGN_LANGOPT(CatchNonUBCType    , 1, 0, "Generate code to check for integer-related but non-undefined ops. ")
 BENIGN_LANGOPT(DumpRecordLayouts , 1, 0, "dumping the layout of IRgen'd records")
 BENIGN_LANGOPT(DumpRecordLayoutsSimple , 1, 0, "dumping the layout of IRgen'd records in a simple form")
 BENIGN_LANGOPT(DumpVTableLayouts , 1, 0, "dumping the layouts of emitted vtables")
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index 83c988a..30f130a 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -158,6 +158,26 @@ def fno_dwarf_directory_asm : Flag<"-fno-dwarf-directory-asm">,
   HelpText<"Don't separate directory and filename in .file directives">;
 def fcatch_undefined_behavior : Flag<"-fcatch-undefined-behavior">,
   HelpText<"Generate runtime checks for undefined behavior.">;
+def fcatch_undefined_ansic_behavior : Flag<"-fcatch-undefined-ansic-behavior">,
+  HelpText<"Generate runtime checks for undefined behavior in arithmetic operation upon ansi c standard.">;
+def fcatch_undefined_c99_behavior : Flag<"-fcatch-undefined-c99-behavior">,
+  HelpText<"Generate runtime checks for undefined behavior in arithmetic operation upon c99 standard.">;
+def fcatch_undefined_cxx0x_behavior : Flag<"-fcatch-undefined-cxx0x-behavior">,
+  HelpText<"Generate runtime checks for undefined behavior in arithmetic operation upon c++0x standard.">;
+def fcatch_undefined_cxx98_behavior : Flag<"-fcatch-undefined-cxx98-behavior">,
+  HelpText<"Generate runtime checks for undefined behavior in arithmetic operation upon c++98 standard.">;
+def fcatch_undefined_nonarith_behavior : Flag<"-fcatch-undefined-nonarith-behavior">,
+  HelpText<"Generate runtime checks for undefined behavior in non-arithmetic operations.">;
+def fuse_intrinsic : Flag<"-fuse-intrinsic">,
+  HelpText<"Check the arithmetic operation upon GCC's intrinsic functions.">;
+def fuse_random_value : Flag<"-fuse-random-value">,
+  HelpText<"Use the values returned by trap handler as arithmetic operations' results.">;
+def fhandler_null : Flag<"-fhandler-null">,
+  HelpText<"__ub_trap_handler refers to NULL.">;
+def fchecks_num : Flag<"-fchecks-num">,
+  HelpText<"Output the number of instrumented number.">;
+def fcatch_non_ubc_type : Flag<"-fcatch-non-ubc-type">,
+  HelpText<"Generate runtime checks for integer-related but non-undefined ops.">;
 def flimit_debug_info : Flag<"-flimit-debug-info">,
   HelpText<"Limit debug information produced to reduce size of debug binary">;
 def fno_common : Flag<"-fno-common">,
diff --git a/include/clang/Driver/OptTable.h b/include/clang/Driver/OptTable.h
index 3af6f8f..50d1e7b 100644
--- a/include/clang/Driver/OptTable.h
+++ b/include/clang/Driver/OptTable.h
@@ -138,6 +138,8 @@
       return getInfo(id).MetaVar;
     }
 
+    Arg *ParseOneArgTrap(const ArgList &Args, unsigned &Index, const char *Str) const;
+
     /// ParseOneArg - Parse a single argument; returning the new argument and
     /// updating Index.
     ///
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index b796771..79783a3 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -295,6 +295,26 @@ def fbuiltin : Flag<"-fbuiltin">, Group<f_Group>;
 def fcaret_diagnostics : Flag<"-fcaret-diagnostics">, Group<f_Group>;
 def fcatch_undefined_behavior : Flag<"-fcatch-undefined-behavior">,
     Group<f_Group>, HelpText<"Generate runtime checks for undefined behavior.">;
+def fcatch_undefined_ansic_behavior : Flag<"-fcatch-undefined-ansic-behavior">,
+    Group<f_Group>, HelpText<"Generate runtime checks for undefined behavior in arithmetic operation upon ansi c standard.">;
+def fcatch_undefined_c99_behavior : Flag<"-fcatch-undefined-c99-behavior">,
+    Group<f_Group>, HelpText<"Generate runtime checks for undefined behavior in arithmetic operation upon c99 standard.">;
+def fcatch_undefined_cxx0x_behavior : Flag<"-fcatch-undefined-cxx0x-behavior">,
+    Group<f_Group>, HelpText<"Generate runtime checks for undefined behavior in arithmetic operation upon c++0x standard.">;
+def fcatch_undefined_cxx98_behavior : Flag<"-fcatch-undefined-cxx98-behavior">,
+    Group<f_Group>, HelpText<"Generate runtime checks for undefined behavior in arithmetic operation upon c++98 standard.">;
+def fcatch_undefined_nonarith_behavior : Flag<"-fcatch-undefined-nonarith-behavior">,
+    Group<f_Group>, HelpText<"Generate runtime checks for undefined behavior in non-arithmetic operations.">;
+def fuse_intrinsic : Flag<"-fuse-intrinsic">,
+    Group<f_Group>, HelpText<"Check the arithmetic operation upon GCC's intrinsic functions.">;
+def fuse_random_value : Flag<"-fuse-random-value">,
+    Group<f_Group>, HelpText<"Use the values returned by trap handler as arithmetic operations' results.">;
+def fhandler_null : Flag<"-fhandler-null">,
+    Group<f_Group>, HelpText<"__ub_trap_handler refers to NULL.">;
+def fchecks_num : Flag<"-fchecks-num">,
+    Group<f_Group>, HelpText<"Output the number of instrumented number.">;
+def fcatch_non_ubc_type : Flag<"-fcatch-non-ubc-type">,
+    Group<f_Group>, HelpText<"Generate runtime checks for integer-related but non-undefined ops.">;
 def fclasspath_EQ : Joined<"-fclasspath=">, Group<f_Group>;
 def fcolor_diagnostics : Flag<"-fcolor-diagnostics">, Group<f_Group>;
 def fcommon : Flag<"-fcommon">, Group<f_Group>;
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp
index f8c7bcd..0bffefb 100644
--- a/lib/CodeGen/CGBlocks.cpp
+++ b/lib/CodeGen/CGBlocks.cpp
@@ -988,6 +988,18 @@ static llvm::Constant *buildGlobalBlock(CodeGenModule &CGM,
   return llvm::ConstantExpr::getBitCast(literal, requiredType);
 }
 
+void CodeGenFunction::CXXThisIsNull() {
+  llvm::BasicBlock *Cont = createBasicBlock("this.cont");
+  CreateTrapBB();
+  std::string tmpRule = "'this' refers to NULL!";
+  ATEI.setAll(0, 0, 0, Cont, tmpRule, 0);
+  llvm::Value *thisNull = llvm::Constant::getNullValue(CXXThisValue->getType());
+  Builder.CreateCondBr(Builder.CreateICmpEQ(CXXThisValue, thisNull),
+                       getSoleTrapBB(), Cont);
+  EmitTrapBB();
+  EmitBlock(Cont);
+}
+
 llvm::Function *
 CodeGenFunction::GenerateBlockFunction(GlobalDecl GD,
                                        const CGBlockInfo &blockInfo,
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index e30b513..7b353f7 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -368,7 +368,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
     return RValue::get(Builder.CreateCall(F));
   }
   case Builtin::BI__builtin_unreachable: {
-    if (CatchUndefined)
+    if ((catchArithUndefined()||catchNonArithUndefined()) && HaveInsertPoint())
       EmitBranch(getTrapBB());
     else
       Builder.CreateUnreachable();
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index 5f2b1f0..f30b147 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -26,6 +26,7 @@
 #include "llvm/LLVMContext.h"
 #include "llvm/Support/MDBuilder.h"
 #include "llvm/Target/TargetData.h"
+#include "clang/Basic/SourceManager.h"
 using namespace clang;
 using namespace CodeGen;
 
@@ -517,7 +518,7 @@ unsigned CodeGenFunction::getAccessedFieldNo(unsigned Idx,
 }
 
 void CodeGenFunction::EmitCheck(llvm::Value *Address, unsigned Size) {
-  if (!CatchUndefined)
+  if (!catchNonArithUndefined())
     return;
 
   // This needs to be to the standard address space.
@@ -528,15 +529,21 @@ void CodeGenFunction::EmitCheck(llvm::Value *Address, unsigned Size) {
   // In time, people may want to control this and use a 1 here.
   llvm::Value *Arg = Builder.getFalse();
   llvm::Value *C = Builder.CreateCall2(F, Address, Arg);
-  llvm::BasicBlock *Cont = createBasicBlock();
-  llvm::BasicBlock *Check = createBasicBlock();
+  llvm::BasicBlock *Cont = createBasicBlock("obj.cont");
+  llvm::BasicBlock *Check = createBasicBlock("obj.check");
   llvm::Value *NegativeOne = llvm::ConstantInt::get(IntPtrTy, -1ULL);
   Builder.CreateCondBr(Builder.CreateICmpEQ(C, NegativeOne), Cont, Check);
     
   EmitBlock(Check);
+  CreateTrapBB();
+  std::string tmpRule;
+  tmpRule = "An object has its stored value accessed by an lvalue ";
+  tmpRule += "of an allowable type!";
+  ATEI.setAll(0, 0, 0, Cont, tmpRule, 0);
   Builder.CreateCondBr(Builder.CreateICmpUGE(C,
                                         llvm::ConstantInt::get(IntPtrTy, Size)),
-                       Cont, getTrapBB());
+                       Cont, getSoleTrapBB());
+  EmitTrapBB();
   EmitBlock(Cont);
 }
 
@@ -616,9 +623,11 @@ LValue CodeGenFunction::EmitUnsupportedLValue(const Expr *E,
 
 LValue CodeGenFunction::EmitCheckedLValue(const Expr *E) {
   LValue LV = EmitLValue(E);
-  if (!isa<DeclRefExpr>(E) && !LV.isBitField() && LV.isSimple())
+  if (!isa<DeclRefExpr>(E) && !LV.isBitField() && LV.isSimple()) {
+    NonArithSL = E->getExprLoc();
     EmitCheck(LV.getAddress(), 
               getContext().getTypeSizeInChars(E->getType()).getQuantity());
+  }
   return LV;
 }
 
@@ -1729,6 +1738,272 @@ LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) {
   }
 }
 
+// 0(000): unsigned 8-bit integer ; 1(001): unsigned 16-bit integer
+// 2(010): unsigned 32-bit integer ; 3(011): unsigned 64-bit integer
+// 4(100): signed 8-bit integer ; 5(101): signed 16-bit integer
+// 6(110): signed 32-bit integer ; 7(111): signed 64-bit integer
+// 8: float ; 9: double ; 10: Unrecognized type
+static unsigned checkValueType(QualType opType, const llvm::Value *value) {
+  unsigned valueTy = 15;
+  if (value) {
+    if (opType->isIntegerType()) {
+      if (opType->isSignedIntegerType()) {
+        if (value->getType()->isIntegerTy(8))
+          valueTy = 5;
+        if (value->getType()->isIntegerTy(16))
+          valueTy = 6;
+        if (value->getType()->isIntegerTy(32))
+          valueTy = 7;
+        if (value->getType()->isIntegerTy(64))
+          valueTy = 8;
+        if (value->getType()->getScalarSizeInBits() > 64)
+          valueTy = 9;
+      }
+      else {
+        if (value->getType()->isIntegerTy(8))
+          valueTy = 0;
+        if (value->getType()->isIntegerTy(16))
+          valueTy = 1;
+        if (value->getType()->isIntegerTy(32))
+          valueTy = 2;
+        if (value->getType()->isIntegerTy(64))
+          valueTy = 3;
+        if (value->getType()->getScalarSizeInBits() > 64)
+          valueTy = 4;
+      }
+    }
+    else {
+      // Except the integer type, only float type left...
+      if (value->getType()->isFloatTy())
+        valueTy = 10;
+      if (value->getType()->isDoubleTy())
+        valueTy = 11;
+      if (value->getType()->getScalarSizeInBits() > 64)
+        valueTy = 12;
+    }
+  }
+  return valueTy;
+}
+
+bool CodeGenFunction::catchArithUndefined() const{
+   return ((CatchUndefined == true)      ||
+           (CatchUndefinedAnsiC == true) ||
+           (CatchUndefinedC99 == true)   ||
+           (CatchUndefinedCXX0X == true) ||
+           (CatchUndefinedCXX98 == true));
+}
+
+bool CodeGenFunction::catchNonArithUndefined() const {
+   return ((CatchUndefined == true) ||
+           (CatchNonArithUndefined == true));
+}
+
+bool CodeGenFunction::catchNonUBCType() const {
+   return CatchNonUBCType;
+}
+
+// get the trap handler function, and return a value dumped by
+// __ub_trap_handler...
+void CodeGenFunction::invokeTrapHandlerFunction() {
+  const char *fileName = 0;
+  unsigned int line = 0;
+  unsigned int column = 0;
+  const BinaryOperator *BOP = 0;
+  const UnaryOperator *UOP = 0;
+  const char *opcodeStr = 0;
+  clang::SourceLocation SL;
+
+  if (ATEI.getOp()) {
+    if ((BOP = dyn_cast<BinaryOperator>(ATEI.getOp()))) {
+      opcodeStr = clang::BinaryOperator::getOpcodeStr(BOP->getOpcode());
+      SL = BOP->getOperatorLoc();
+    } else if ((UOP = dyn_cast<UnaryOperator>(ATEI.getOp()))) {
+      opcodeStr = clang::UnaryOperator::getOpcodeStr(UOP->getOpcode());
+      SL = UOP->getOperatorLoc();
+    }
+  } else {
+    if (ATEI.getAssignOp()) {
+      opcodeStr = "=";
+      SL = NonArithSL;
+    } else {
+      // For non-arithmetic operation, opcodeStr is unnecessary,
+      // use "no opstr" instead...
+      opcodeStr = "no operator or =";
+      SL = NonArithSL;
+    }
+  }
+
+  if (!SL.isValid()) {
+    fileName = "unknown file name";
+    line = 0;
+    column = 0;
+  } else {
+    SourceManager &SM = getContext().getSourceManager();
+    PresumedLoc PLoc = SM.getPresumedLoc(SL);
+
+    if (PLoc.isValid()) {
+      fileName = PLoc.getFilename();
+      line = PLoc.getLine();
+      column = PLoc.getColumn();
+    } else {
+      fileName = "unknown file name";
+      line = 0;
+      column = 0;
+    }
+  }
+  // File name argument
+  llvm::Value *fileNameArg = Builder.CreateGlobalStringPtr(fileName);
+  // Operator code argument
+  llvm::Value *opStrArg = Builder.CreateGlobalStringPtr(opcodeStr);
+  // Rule argument
+  llvm::Value *ruleStrArg = Builder.CreateGlobalStringPtr(ATEI.getRule().data());
+
+  llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(getLLVMContext());
+  llvm::Type* handlerArgTypes[] = {
+    Int32Ty, Int32Ty, Int8PtrTy, Int8PtrTy,
+    Int8PtrTy, Int8Ty, Int8Ty, Int8Ty, Int8Ty,
+    Int64Ty, Int64Ty
+  };
+
+  // The function type of trap handler...
+  llvm::FunctionType *handlerTy =
+        llvm::FunctionType::get(Int64Ty, makeArrayRef(handlerArgTypes), true);
+  llvm::Value *handlerFunction =
+        CGM.CreateRuntimeFunction(handlerTy, "undefined_behavior_trap_handler");
+
+  std::vector<llvm::Value*> handlerArgValues;
+  handlerArgValues.push_back(llvm::ConstantInt::get(Int32Ty, line));
+  handlerArgValues.push_back(llvm::ConstantInt::get(Int32Ty, column));
+  handlerArgValues.push_back(fileNameArg);
+  handlerArgValues.push_back(opStrArg);
+  handlerArgValues.push_back(ruleStrArg);
+  handlerArgValues.push_back(llvm::ConstantInt::get(Int8Ty, ATEI.getMark()));
+  // exprMark determines how many operands are involved in.
+  // 3: Non-arithmetic operation;
+  // 2: Binary arithmetic operation;
+  // 1: Unary arithmetic operation
+  unsigned exprMark; // determine the number of arguments
+  unsigned lvalue_mark, rvalue_mark;
+  if (BOP) {
+    exprMark = 2;
+    lvalue_mark = checkValueType(BOP->getType(), ATEI.getLValue());
+    rvalue_mark = checkValueType(BOP->getType(), ATEI.getRValue());
+  }
+  else if (UOP) {
+    exprMark = 1;
+    lvalue_mark = checkValueType(UOP->getType(), ATEI.getLValue());
+    rvalue_mark = checkValueType(UOP->getType(), ATEI.getRValue());
+  }
+  else {
+    if (ATEI.getMark() == 1) {
+      exprMark = 2;
+      lvalue_mark = checkValueType(NONUBC.getSrcType(), ATEI.getLValue());
+      rvalue_mark = checkValueType(NONUBC.getDstType(), ATEI.getRValue());
+    }
+    else {
+      exprMark = 3;
+      lvalue_mark = 6;
+      rvalue_mark = 6;
+    }
+  }
+  handlerArgValues.push_back(llvm::ConstantInt::get(Int8Ty, exprMark));
+  handlerArgValues.push_back(llvm::ConstantInt::get(Int8Ty, lvalue_mark));
+  handlerArgValues.push_back(llvm::ConstantInt::get(Int8Ty, rvalue_mark));
+
+  for (unsigned LRSwitch = 0; LRSwitch < 2; LRSwitch++) {
+    if ((LRSwitch == 0)? ATEI.getLValue() : ATEI.getRValue()) {
+      switch ((LRSwitch == 0)? lvalue_mark : rvalue_mark) {
+      case 0:
+      case 1:
+      case 2:
+      case 3:
+        handlerArgValues.push_back(Builder.CreateZExt(
+                         (LRSwitch == 0)? ATEI.getLValue() : ATEI.getRValue(),
+                         Int64Ty));
+        break;
+      case 5:
+      case 6:
+      case 7:
+      case 8:
+        handlerArgValues.push_back(Builder.CreateSExt(
+                         (LRSwitch == 0)? ATEI.getLValue() : ATEI.getRValue(),
+                         Int64Ty));
+        break;
+      case 4:
+      case 9:
+        handlerArgValues.push_back(Builder.CreateTrunc(
+                         (LRSwitch == 0)? ATEI.getLValue() : ATEI.getRValue(),
+                         Int64Ty));
+        break;
+      case 10:
+      case 11:
+      case 12:
+        handlerArgValues.push_back(Builder.CreateFPToUI(
+                         (LRSwitch == 0)? ATEI.getLValue() : ATEI.getRValue(),
+                         Int64Ty));
+        break;
+      default:
+        // Except for the integer, float, double types, seems
+        // there exist no other types for simple scalar arithmetic
+        // operations. If there are, just use the zero to represent them.
+        handlerArgValues.push_back(llvm::ConstantInt::get(Int64Ty, 0, true));
+        break;
+      }
+    }
+    else {
+      handlerArgValues.push_back(llvm::ConstantInt::get(Int64Ty, 0, true));
+    }
+  }
+
+  // Execute the concrete trap handler...
+  trapHandlerResult = Builder.CreateCall(handlerFunction,
+                                         makeArrayRef(handlerArgValues));
+  if (rvOpTy && UseRandomValue) {
+    if (rvOpTy->isIntegerTy()) {
+      // interger type...
+      if (rvOpTy->getScalarSizeInBits() <= 64)
+        trapHandlerResult = Builder.CreateTrunc(trapHandlerResult, rvOpTy);
+      else {
+        // is that possible??
+        trapHandlerResult = Builder.CreateZExt(trapHandlerResult, rvOpTy);
+      }
+    }
+    else {
+      trapHandlerResult = Builder.CreateUIToFP(trapHandlerResult, rvOpTy);
+    }
+  }
+}
+
+void CodeGenFunction::CreateTrapBB() {
+  TrapBB = createBasicBlock("trap");
+}
+
+llvm::BasicBlock *CodeGenFunction::getSoleTrapBB() {
+  assert(TrapBB && "TrapBB in getSoleTrapBB is NULL!");
+  return TrapBB;
+}
+
+void CodeGenFunction::EmitTrapBB() {
+  assert(TrapBB && "TrapBB in EmitTrapBB is NULL!");
+  EmitBlock(TrapBB);
+
+  if(ChecksNum) {
+     llvm::outs() << "The total number of instrumented checks:" << CGM.getChecksNum() << "\n";
+  }
+
+  // Invoke the trap handler function...
+  // Unnecessary to get the returned value
+  invokeTrapHandlerFunction();
+
+  if (ATEI.getTrapNextBB()) {
+     EmitBranch(ATEI.getTrapNextBB());
+     ATEI.clearAll();
+  }
+  else {
+     Builder.CreateUnreachable();
+  }
+}
+
 llvm::BasicBlock *CodeGenFunction::getTrapBB() {
   const CodeGenOptions &GCO = CGM.getCodeGenOpts();
 
@@ -1796,17 +2071,25 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E) {
     Idx = Builder.CreateIntCast(Idx, IntPtrTy, IdxSigned, "idxprom");
   
   // FIXME: As llvm implements the object size checking, this can come out.
-  if (CatchUndefined) {
+  if (catchNonArithUndefined()) {
     if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E->getBase())){
       if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ICE->getSubExpr())) {
         if (ICE->getCastKind() == CK_ArrayToPointerDecay) {
           if (const ConstantArrayType *CAT
               = getContext().getAsConstantArrayType(DRE->getType())) {
             llvm::APInt Size = CAT->getSize();
-            llvm::BasicBlock *Cont = createBasicBlock("cont");
+            CreateTrapBB();
+            llvm::BasicBlock *Cont = createBasicBlock("array.cont");
+            std::string str;
+            llvm::raw_string_ostream os(str);
+            os << "The current index is greater than array size: "
+                                                      << Size.getZExtValue();
+            NonArithSL = E->getExprLoc();
+            ATEI.setAll(0, 0, 0, Cont, os.str(), 0);
             Builder.CreateCondBr(Builder.CreateICmpULE(Idx,
                                   llvm::ConstantInt::get(Idx->getType(), Size)),
-                                 Cont, getTrapBB());
+                                 Cont, getSoleTrapBB());
+            EmitTrapBB();
             EmitBlock(Cont);
           }
         }
diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp
index c69c883..1d4f6b4 100644
--- a/lib/CodeGen/CGExprCXX.cpp
+++ b/lib/CodeGen/CGExprCXX.cpp
@@ -50,7 +50,24 @@ RValue CodeGenFunction::EmitCXXMemberCall(const CXXMethodDecl *MD,
   // And the rest of the call args.
   EmitCallArgs(Args, FPT, ArgBeg, ArgEnd);
 
-  return EmitCall(CGM.getTypes().arrangeFunctionCall(FPT->getResultType(), Args,
+  QualType ResultType = FPT->getResultType();
+
+  if (catchNonArithUndefined()) {
+    llvm::BasicBlock *Cont = createBasicBlock("this.cont");
+    CreateTrapBB();
+    std::string str;
+    llvm::raw_string_ostream os(str);
+    os << "The object calling member function: " << MD->getNameAsString()
+       << " is NULL!";
+    ATEI.setAll(0, 0, 0, Cont, os.str(), 0);
+    llvm::Value *thisNull = llvm::Constant::getNullValue(This->getType());
+    Builder.CreateCondBr(Builder.CreateICmpEQ(This, thisNull),
+                         getSoleTrapBB(), Cont);
+    EmitTrapBB();
+    EmitBlock(Cont);
+  }
+
+  return EmitCall(CGM.getTypes().arrangeFunctionCall(ResultType, Args,
                                                      FPT->getExtInfo(),
                                                      required),
                   Callee, ReturnValue, Args, MD);
@@ -175,6 +192,7 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE,
   if (isa<BinaryOperator>(callee))
     return EmitCXXMemberPointerCallExpr(CE, ReturnValue);
 
+  NonArithSL = CE->getExprLoc();
   const MemberExpr *ME = cast<MemberExpr>(callee);
   const CXXMethodDecl *MD = cast<CXXMethodDecl>(ME->getMemberDecl());
 
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp
index 18891f7..a8d34c4 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -30,6 +30,7 @@
 #include "llvm/Support/CFG.h"
 #include "llvm/Target/TargetData.h"
 #include <cstdarg>
+#include "clang/Basic/SourceManager.h"
 
 using namespace clang;
 using namespace CodeGen;
@@ -97,6 +98,9 @@ class ScalarExprEmitter
   /// boolean (i1) truth value.  This is equivalent to "Val != 0".
   Value *EmitConversionToBool(Value *Src, QualType DstTy);
 
+  void EmitNonUBCSameType (Value *Src, Value *Dst, llvm::Type *SrcTy,
+                           llvm::Type *DstTy, bool InputSigned, bool dstSigned);
+
   /// EmitScalarConversion - Emit a conversion from the specified type to the
   /// specified destination type, both of which are LLVM scalar types.
   Value *EmitScalarConversion(Value *Src, QualType SrcTy, QualType DstTy);
@@ -393,6 +397,12 @@ class ScalarExprEmitter
     if (Ops.Ty->isSignedIntegerOrEnumerationType()) {
       switch (CGF.getContext().getLangOpts().getSignedOverflowBehavior()) {
       case LangOptions::SOB_Undefined:
+        if (CGF.catchArithUndefined()) {
+          if (CGF.UseIntrinsic)
+            return UndefinedBehaviorOverflowCheck(Ops);
+          else
+            return UndefinedBehaviorMulCheck(Ops);
+        }
         return Builder.CreateNSWMul(Ops.LHS, Ops.RHS, "mul");
       case LangOptions::SOB_Defined:
         return Builder.CreateMul(Ops.LHS, Ops.RHS, "mul");
@@ -403,6 +413,11 @@ class ScalarExprEmitter
     
     if (Ops.LHS->getType()->isFPOrFPVectorTy())
       return Builder.CreateFMul(Ops.LHS, Ops.RHS, "mul");
+
+    // Here, we must consider the unsigned overflowing operation...
+    if (Ops.Ty->hasUnsignedIntegerRepresentation() && CGF.catchNonUBCType())
+      UnsignedOverflowMulCheck(Ops);
+
     return Builder.CreateMul(Ops.LHS, Ops.RHS, "mul");
   }
   bool isTrapvOverflowBehavior() {
@@ -412,6 +427,18 @@ class ScalarExprEmitter
   /// Create a binary op that checks for overflow.
   /// Currently only supports +, - and *.
   Value *EmitOverflowCheckedBinOp(const BinOpInfo &Ops);
+  Value *getNormalAdditionValue(const BinOpInfo &Ops, unsigned addMark);
+  Value *UndefinedBehaviorAddCheck(const BinOpInfo &Ops, unsigned addMark);
+  void UnsignedOverflowAddCheck(const BinOpInfo &Ops);
+  Value *UndefinedBehaviorSubCheck(const BinOpInfo &Ops);
+  void UnsignedOverflowSubCheck(const BinOpInfo &Ops);
+  Value *UndefinedBehaviorMulCheck(const BinOpInfo &Ops);
+  void UnsignedOverflowMulCheck(const BinOpInfo &Ops);
+  Value *UndefinedBehaviorOverflowCheck(const BinOpInfo &Ops);
+  void UndefinedBehaviorDivAndRemCheck(const BinOpInfo &Ops,
+                                       llvm::BasicBlock* normalBlock,
+                                       llvm::BasicBlock* finalBlock,
+                                       llvm::Value *Zero, bool isDiv);
   // Emit the overflow BB when -ftrapv option is activated. 
   void EmitOverflowBB(llvm::BasicBlock *overflowBB) {
     Builder.SetInsertPoint(overflowBB);
@@ -422,6 +449,36 @@ class ScalarExprEmitter
   // Check for undefined division and modulus behaviors.
   void EmitUndefinedBehaviorIntegerDivAndRemCheck(const BinOpInfo &Ops, 
                                                   llvm::Value *Zero,bool isDiv);
+
+  static void printDetailedInfo(CodeGenFunction &CGF, clang::SourceLocation SL) {
+    const char *fileName;
+    unsigned int line = 0;
+    unsigned int column = 0;
+
+    if (!SL.isValid()) {
+      fileName = "unknown file name";
+      line = 0;
+      column = 0;
+    }
+    else {
+      SourceManager &SM = CGF.getContext().getSourceManager();
+      PresumedLoc PLoc = SM.getPresumedLoc(SL);
+
+      if (PLoc.isValid()) {
+        fileName = PLoc.getFilename();
+        line = PLoc.getLine();
+        column = PLoc.getColumn();
+      }
+      else {
+        fileName = "unknown file name";
+        line = 0;
+        column = 0;
+      }
+    }
+
+    llvm::outs() << "filename: " << fileName << " line: " << line << " column: " << column << "\n";
+  }
+
   Value *EmitDiv(const BinOpInfo &Ops);
   Value *EmitRem(const BinOpInfo &Ops);
   Value *EmitAdd(const BinOpInfo &Ops);
@@ -537,6 +594,70 @@ Value *ScalarExprEmitter::EmitConversionToBool(Value *Src, QualType SrcType) {
   return EmitPointerToBoolConversion(Src);
 }
 
+void ScalarExprEmitter::EmitNonUBCSameType (Value *Src, Value *Dst,
+                                            llvm::Type *SrcTy,
+                                            llvm::Type *DstTy, bool InputSigned,
+                                            bool dstSigned) {
+  if (isa<llvm::IntegerType>(Src->getType())) {
+    if (llvm::IntegerType *DTy = dyn_cast<llvm::IntegerType>(DstTy)) {
+      std::string tmpRule;
+      if (dstSigned) {
+        if (SrcTy->getScalarSizeInBits() >= DstTy->getScalarSizeInBits()) {
+          // (signed) dst = (unsigned) src;
+          llvm::Value *UUpperB = llvm::ConstantInt::get(VMContext,
+                        llvm::APInt::getMaxValue(DTy->getBitWidth()-1));
+
+          llvm::BasicBlock *TruncCont = CGF.createBasicBlock("trunc.cont");
+          CGF.CreateTrapBB();
+
+          tmpRule = "Warning: (signed) dst = (unsigned) src";
+          tmpRule += ", Src goes beyond the range [0, SINT_MAX]";
+          tmpRule += ", then the unsigned src is misinterpreted";
+
+          CGF.ATEI.setAll(Src, Dst, 0, TruncCont, tmpRule, 1);
+          CGF.Builder.CreateCondBr(Builder.CreateICmpULE(Src,
+                                   Builder.CreateZExt(UUpperB, SrcTy)),
+                                   TruncCont, CGF.getSoleTrapBB());
+          CGF.EmitTrapBB();
+          CGF.EmitBlock(TruncCont);
+        }
+      }
+      else {
+        // (unsigned) dst = (signed) src;
+        llvm::Value *Zero = llvm::Constant::getNullValue(SrcTy);
+        llvm::BasicBlock *TruncCont = CGF.createBasicBlock("trunc.cont");
+        llvm::BasicBlock *TruncFinal = CGF.createBasicBlock("trunc.final");
+        CGF.CreateTrapBB();
+
+        tmpRule = "Warning: (unsigned) dst = (signed) src";
+        tmpRule += ". Src is smaller than 0, signedness transformation error";
+
+        CGF.ATEI.setAll(Src, Dst, 0, TruncFinal, tmpRule, 1);
+        CGF.Builder.CreateCondBr(Builder.CreateICmpSLT(Src, Zero),
+                                 CGF.getSoleTrapBB(), TruncCont);
+        CGF.EmitTrapBB();
+        CGF.EmitBlock(TruncCont);
+
+        if (SrcTy->getScalarSizeInBits() > DstTy->getScalarSizeInBits()) {
+          llvm::Value *UIntMax = llvm::ConstantInt::get(VMContext,
+                         llvm::APInt::getMaxValue(DTy->getBitWidth()));
+          CGF.CreateTrapBB();
+          tmpRule = "Warning: (unsigned) dst = (signed) src";
+          tmpRule += ". Src is greater than 0, unsigned dst can not";
+          tmpRule += " take the signed src value";
+
+          CGF.ATEI.setAll(Src, Dst, 0, TruncFinal, tmpRule, 1);
+          CGF.Builder.CreateCondBr(
+                   Builder.CreateICmpSGT(Src, Builder.CreateZExt(UIntMax, SrcTy)),
+                   CGF.getSoleTrapBB(), TruncFinal);
+          CGF.EmitTrapBB();
+        }
+        CGF.EmitBlock(TruncFinal);
+      }
+    }
+  }
+}
+
 /// EmitScalarConversion - Emit a conversion from the specified type to the
 /// specified destination type, both of which are LLVM scalar types.
 Value *ScalarExprEmitter::EmitScalarConversion(Value *Src, QualType SrcType,
@@ -564,8 +685,15 @@ Value *ScalarExprEmitter::EmitScalarConversion(Value *Src, QualType SrcType,
   llvm::Type *DstTy = ConvertType(DstType);
 
   // Ignore conversions like int -> uint.
-  if (SrcTy == DstTy)
+  if (SrcTy == DstTy) {
+    if (CGF.catchNonUBCType()) {
+      bool InputSigned = SrcType->isSignedIntegerType();
+      bool dstSigned = DstType->isSignedIntegerType();
+      CGF.NONUBC.setAll(SrcType, DstType);
+      EmitNonUBCSameType(Src, Src, SrcTy, DstTy, InputSigned, dstSigned);
+    }
     return Src;
+  }
 
   // Handle pointer conversions next: pointers can only be converted to/from
   // other pointers and integers. Check for pointer types in terms of LLVM, as
@@ -626,8 +754,70 @@ Value *ScalarExprEmitter::EmitScalarConversion(Value *Src, QualType SrcType,
 
   if (isa<llvm::IntegerType>(SrcTy)) {
     bool InputSigned = SrcType->isSignedIntegerOrEnumerationType();
-    if (isa<llvm::IntegerType>(DstTy))
+    if (isa<llvm::IntegerType>(DstTy)) {
+      if (CGF.catchNonUBCType()) {
+        bool dstSigned = DstType->isSignedIntegerType();
+        std::string tmpRule;
+        if (InputSigned == dstSigned) {
+          // (signed) dst = (signed) src || (unsigned) dst = (unsigned) src;
+          const llvm::IntegerType *Ty = cast<llvm::IntegerType>(DstTy);
+          llvm::Value *IntMax = NULL;
+          llvm::Value *IntMin = NULL;
+          if (dstSigned) {
+            IntMax = llvm::ConstantInt::get(VMContext,
+                             llvm::APInt::getSignedMaxValue(Ty->getBitWidth()));
+            IntMin = llvm::ConstantInt::get(VMContext,
+                             llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
+          }
+          else {
+            IntMax = llvm::ConstantInt::get(VMContext,
+                             llvm::APInt::getMaxValue(Ty->getBitWidth()));
+            IntMin = llvm::ConstantInt::get(VMContext,
+                             llvm::APInt::getMinValue(Ty->getBitWidth()));
+          }
+
+          if (SrcTy->getScalarSizeInBits() > DstTy->getScalarSizeInBits()) {
+            // truncation, potentially there is data loss..
+            llvm::BasicBlock *TruncCont = CGF.createBasicBlock("trunc.cont");
+            CGF.CreateTrapBB();
+
+            if (dstSigned) {
+              tmpRule = "Warning: (signed) dst = (signed) src; ";
+              tmpRule += "Src goes beyond the range [SINT_MIN, SINT_MAX]";
+              tmpRule += " determined by dstType, potential data loss!";
+              CGF.ATEI.setAll(Src, Builder.CreateIntCast(Src, DstTy, InputSigned, "conv"),
+                              0, TruncCont, tmpRule, 1);
+              CGF.NONUBC.setAll(SrcType, DstType);
+              CGF.Builder.CreateCondBr(Builder.CreateAnd(
+                  Builder.CreateICmpSGE(Src, Builder.CreateSExt(IntMin, SrcTy)),
+                  Builder.CreateICmpSLE(Src, Builder.CreateSExt(IntMax, SrcTy)), "and"),
+                  TruncCont, CGF.getSoleTrapBB());
+            }
+            else {
+              tmpRule = "Warning: (unsigned) dst = (unsigned) src; ";
+              tmpRule += "Src goes beyond the range [UINT_MIN, UINT_MAX]";
+              tmpRule += " determined by dstType, potential data loss!";
+              CGF.ATEI.setAll(Src, Builder.CreateIntCast(Src, DstTy, InputSigned, "conv"),
+                              0, TruncCont, tmpRule, 1);
+              CGF.NONUBC.setAll(SrcType, DstType);
+              CGF.Builder.CreateCondBr(Builder.CreateAnd(
+                  Builder.CreateICmpUGE(Src, Builder.CreateZExt(IntMin, SrcTy)),
+                  Builder.CreateICmpULE(Src, Builder.CreateZExt(IntMax, SrcTy)), "and"),
+                  TruncCont, CGF.getSoleTrapBB());
+            }
+
+            CGF.EmitTrapBB();
+            CGF.EmitBlock(TruncCont);
+          }
+        }
+        else {
+          CGF.NONUBC.setAll(SrcType, DstType);
+          EmitNonUBCSameType(Src, Builder.CreateIntCast(Src, DstTy, InputSigned, "conv"),
+                             SrcTy, DstTy, InputSigned, dstSigned);
+        }
+      }
       Res = Builder.CreateIntCast(Src, DstTy, InputSigned, "conv");
+    }
     else if (InputSigned)
       Res = Builder.CreateSIToFP(Src, DstTy, "conv");
     else
@@ -1022,6 +1212,7 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
   Expr *E = CE->getSubExpr();
   QualType DestTy = CE->getType();
   CastKind Kind = CE->getCastKind();
+  CGF.NonArithSL = E->getExprLoc();
   
   if (!DestTy->isVoidType())
     TestAndClearIgnoreResultAssign();
@@ -1249,7 +1440,22 @@ Value *ScalarExprEmitter::VisitStmtExpr(const StmtExpr *E) {
                                 llvm::Value *NextVal, bool IsInc) {
   switch (CGF.getContext().getLangOpts().getSignedOverflowBehavior()) {
   case LangOptions::SOB_Undefined:
-    return Builder.CreateNSWAdd(InVal, NextVal, IsInc ? "inc" : "dec");
+    if (CGF.catchArithUndefined()) {
+      BinOpInfo BinOp;
+      BinOp.LHS = InVal;
+      BinOp.RHS = NextVal;
+      BinOp.Ty = E->getType();
+      BinOp.Opcode = BO_Add;
+      BinOp.E = E;
+      if (CGF.UseIntrinsic)
+        return UndefinedBehaviorOverflowCheck(BinOp);
+      else
+        return UndefinedBehaviorAddCheck(BinOp, IsInc ? 1 : 2);
+    }
+    else {
+      return Builder.CreateNSWAdd(InVal, NextVal, IsInc ? "inc" : "dec");
+    }
+    break;
   case LangOptions::SOB_Defined:
     return Builder.CreateAdd(InVal, NextVal, IsInc ? "inc" : "dec");
   case LangOptions::SOB_Trapping:
@@ -1307,8 +1513,29 @@ Value *ScalarExprEmitter::VisitStmtExpr(const StmtExpr *E) {
         value->getType()->getPrimitiveSizeInBits() >=
             CGF.IntTy->getBitWidth())
       value = EmitAddConsiderOverflowBehavior(E, value, amt, isInc);
-    else
+    else {
+      // Here, we must consider the unsigned overflowing operation...
+      if (type->isUnsignedIntegerType() && CGF.catchNonUBCType()) {
+        int tmpamount = 1;
+        llvm::Value *tmpamt = llvm::ConstantInt::get(value->getType(), tmpamount);
+        BinOpInfo BinOp;
+        BinOp.LHS = value;
+        BinOp.RHS = tmpamt;
+        BinOp.Ty = E->getType();
+        BinOp.E = E;
+
+        if (isInc) {
+          BinOp.Opcode = BO_Add;
+          UnsignedOverflowAddCheck(BinOp);
+        }
+        else {
+          BinOp.Opcode = BO_Sub;
+          UnsignedOverflowSubCheck(BinOp);
+        }
+      }
+
       value = Builder.CreateAdd(value, amt, isInc ? "inc" : "dec");
+    }
   
   // Next most common: pointer increment.
   } else if (const PointerType *ptr = type->getAs<PointerType>()) {
@@ -1781,22 +2008,114 @@ void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
   Builder.SetInsertPoint(contBB);
 }
 
-Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) {
-  if (isTrapvOverflowBehavior()) { 
-    llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
+void ScalarExprEmitter::UndefinedBehaviorDivAndRemCheck(
+                                         const BinOpInfo &Ops,
+                                         llvm::BasicBlock* normalBlock,
+                                         llvm::BasicBlock* finalBlock,
+                                         llvm::Value *Zero, bool isDiv) {
+  std::string tmpRule;
+  CGF.CreateTrapBB();
+  if (Ops.Ty->hasSignedIntegerRepresentation()) {
+    llvm::IntegerType *Ty = cast<llvm::IntegerType>(Zero->getType());
+    llvm::Value *IntMin =
+      llvm::ConstantInt::get(VMContext,
+                             llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
+    llvm::Value *NegOne = llvm::ConstantInt::get(Ty, -1ULL);
+
+    if (isDiv) {
+      tmpRule = "Signed Division: Divisor is 0 ";
+      tmpRule += "|| divident is INT_MIN, divisor is -1";
+    }
+    else {
+      tmpRule = "Signed Modulus: The second operand is 0 ";
+      tmpRule += "|| The first operand: INT_MIN, the second operand: -1";
+    }
+    CGF.ATEI.setAll(Ops.LHS, Ops.RHS, Ops.E, finalBlock, tmpRule, 0);
+    llvm::Value *Cond1 = Builder.CreateICmpEQ(Ops.RHS, Zero);
+    llvm::Value *LHSCmp = Builder.CreateICmpEQ(Ops.LHS, IntMin);
+    llvm::Value *RHSCmp = Builder.CreateICmpEQ(Ops.RHS, NegOne);
+    llvm::Value *Cond2 = Builder.CreateAnd(LHSCmp, RHSCmp, "and");
+    CGF.Builder.CreateCondBr(Builder.CreateOr(Cond1, Cond2, "or"),
+        CGF.getSoleTrapBB(),
+        CGF.UseRandomValue? normalBlock : finalBlock);
+  }
+  else {
+    if (isDiv)
+      tmpRule = "Unsigned Division: Divisor is 0";
+    else
+      tmpRule = "Unsigned Modulus: The second operand is 0";
+    CGF.ATEI.setAll(Ops.LHS, Ops.RHS, Ops.E, finalBlock, tmpRule, 0);
+    CGF.Builder.CreateCondBr(Builder.CreateICmpEQ(Ops.RHS, Zero),
+                             CGF.getSoleTrapBB(),
+                             CGF.UseRandomValue? normalBlock : finalBlock);
+  }
+  CGF.EmitTrapBB();
+}
 
-    if (Ops.Ty->isIntegerType())
-      EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero, true);
+Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) {
+  if (CGF.catchArithUndefined() || isTrapvOverflowBehavior()) {
+    std::string tmpRule;
+    bool AddedCheck = false;
+    CGF.rvOpTy = ConvertType(Ops.Ty);
+    llvm::Value *Zero = llvm::Constant::getNullValue(CGF.rvOpTy);
+    llvm::BasicBlock *DivNormalEnd = CGF.createBasicBlock("div.norm");
+    llvm::BasicBlock *DivFinalEnd = CGF.createBasicBlock("div.final");
+
+    if (Ops.Ty->isIntegerType()) {
+      if (isTrapvOverflowBehavior())
+        EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero, true);
+      else if (CGF.catchArithUndefined()) {
+        UndefinedBehaviorDivAndRemCheck(Ops, DivNormalEnd,
+                                        DivFinalEnd, Zero, true);
+        AddedCheck = true;
+      }
+    }
     else if (Ops.Ty->isRealFloatingType()) {
-      llvm::Function::iterator insertPt = Builder.GetInsertBlock();
-      llvm::BasicBlock *DivCont = CGF.createBasicBlock("div.cont", CGF.CurFn,
-                                                       llvm::next(insertPt));
-      llvm::BasicBlock *overflowBB = CGF.createBasicBlock("overflow",
-                                                          CGF.CurFn);
-      CGF.Builder.CreateCondBr(Builder.CreateFCmpOEQ(Ops.RHS, Zero), 
-                               overflowBB, DivCont);
-      EmitOverflowBB(overflowBB);
-      Builder.SetInsertPoint(DivCont);
+      if (isTrapvOverflowBehavior()) {
+        llvm::Function::iterator insertPt = Builder.GetInsertBlock();
+        llvm::BasicBlock *DivCont = CGF.createBasicBlock("div.cont", CGF.CurFn,
+                                                         llvm::next(insertPt));
+        llvm::BasicBlock *overflowBB = CGF.createBasicBlock("overflow",
+                                                            CGF.CurFn);
+        CGF.Builder.CreateCondBr(Builder.CreateFCmpOEQ(Ops.RHS, Zero),
+                                 overflowBB, DivCont);
+        EmitOverflowBB(overflowBB);
+        Builder.SetInsertPoint(DivCont);
+      }
+      else if (CGF.catchArithUndefined()) {
+        CGF.CreateTrapBB();
+        tmpRule = "Floating Division: Divisor is 0";
+        CGF.ATEI.setAll(Ops.LHS, Ops.RHS, Ops.E, DivFinalEnd, tmpRule, 0);
+        CGF.Builder.CreateCondBr(Builder.CreateFCmpOEQ(Ops.RHS, Zero),
+                                 CGF.getSoleTrapBB(),
+                                 CGF.UseRandomValue? DivNormalEnd : DivFinalEnd);
+        CGF.EmitTrapBB();
+        AddedCheck = true;
+      }
+    }
+
+    if (CGF.catchArithUndefined() && AddedCheck) {
+      llvm::Value *result = 0;
+
+      if (CGF.UseRandomValue) {
+        CGF.EmitBlock(DivNormalEnd);
+        if (Ops.LHS->getType()->isFPOrFPVectorTy())
+          result = Builder.CreateFDiv(Ops.LHS, Ops.RHS, "div");
+        else if (Ops.Ty->hasUnsignedIntegerRepresentation())
+          result = Builder.CreateUDiv(Ops.LHS, Ops.RHS, "div");
+        else
+          result = Builder.CreateSDiv(Ops.LHS, Ops.RHS, "div");
+        CGF.EmitBranch(DivFinalEnd);
+      }
+
+      CGF.EmitBlock(DivFinalEnd);
+
+      if (CGF.UseRandomValue) {
+        llvm::PHINode *phi = Builder.CreatePHI(CGF.rvOpTy, 2);
+        phi->addIncoming(CGF.trapHandlerResult, CGF.getSoleTrapBB());
+        phi->addIncoming(result, DivNormalEnd);
+        return phi;
+      }
     }
   }
   if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
@@ -1819,11 +2138,43 @@ Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) {
 
 Value *ScalarExprEmitter::EmitRem(const BinOpInfo &Ops) {
   // Rem in C can't be a floating point type: C99 6.5.5p2.
-  if (isTrapvOverflowBehavior()) {
-    llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
+  if (CGF.catchArithUndefined() || isTrapvOverflowBehavior()) {
+    bool AddedCheck = false;
+    CGF.rvOpTy = ConvertType(Ops.Ty);
+    llvm::Value *Zero = llvm::Constant::getNullValue(CGF.rvOpTy);
+    llvm::BasicBlock *RemNormalEnd = CGF.createBasicBlock("rem.norm.end");
+    llvm::BasicBlock *RemFinalEnd = CGF.createBasicBlock("rem.final.end");
+
+    if (Ops.Ty->isIntegerType()){
+      if (isTrapvOverflowBehavior())
+        EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero, false);
+      else if (CGF.catchArithUndefined()) {
+        UndefinedBehaviorDivAndRemCheck(Ops, RemNormalEnd,
+                                        RemFinalEnd, Zero, true);
+        AddedCheck = true;
+      }
+    }
+
+    if (CGF.catchArithUndefined() && AddedCheck) {
+      llvm::Value *result = 0;
+      if (CGF.UseRandomValue) {
+        CGF.EmitBlock(RemNormalEnd);
+        if (Ops.Ty->isUnsignedIntegerType())
+          result = Builder.CreateURem(Ops.LHS, Ops.RHS, "rem");
+        else
+          result = Builder.CreateSRem(Ops.LHS, Ops.RHS, "rem");
+        CGF.EmitBranch(RemFinalEnd);
+      }
+
+      CGF.EmitBlock(RemFinalEnd);
 
-    if (Ops.Ty->isIntegerType()) 
-      EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero, false);
+      if (CGF.UseRandomValue) {
+        llvm::PHINode *phi = Builder.CreatePHI(CGF.rvOpTy, 2);
+        phi->addIncoming(CGF.trapHandlerResult, CGF.getSoleTrapBB());
+        phi->addIncoming(result, RemNormalEnd);
+        return phi;
+      }
+    }
   }
 
   if (Ops.Ty->hasUnsignedIntegerRepresentation())
@@ -1918,6 +2269,399 @@ Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(const BinOpInfo &Ops) {
   return phi;
 }
 
+Value *ScalarExprEmitter::UndefinedBehaviorOverflowCheck(const BinOpInfo &Ops) {
+  unsigned IID;
+  unsigned OpID = 0;
+  std::string tmpRule;
+
+  switch (Ops.Opcode) {
+  case BO_Add:
+  case BO_AddAssign:
+    OpID = 1;
+    tmpRule = "Signed Addition Overflow";
+    IID = llvm::Intrinsic::sadd_with_overflow;
+    break;
+  case BO_Sub:
+  case BO_SubAssign:
+    OpID = 2;
+    tmpRule = "Signed Subtraction Overflow";
+    IID = llvm::Intrinsic::ssub_with_overflow;
+    break;
+  case BO_Mul:
+  case BO_MulAssign:
+    OpID = 3;
+    tmpRule = "Signed Multiplication Overflow";
+    IID = llvm::Intrinsic::smul_with_overflow;
+    break;
+  default:
+    assert(false && "Unsupported operation for overflow detection");
+    IID = 0;
+  }
+  OpID <<= 1;
+  OpID |= 1;
+
+  llvm::Type *opTy = CGF.CGM.getTypes().ConvertType(Ops.Ty);
+  CGF.rvOpTy = opTy;
+  llvm::Function *intrinsic = CGF.CGM.getIntrinsic(IID, opTy);
+
+  llvm::Value *resultAndOverflow = Builder.CreateCall2(intrinsic, Ops.LHS, Ops.RHS);
+  llvm::Value *result = 0;
+  llvm::Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
+  llvm::BasicBlock *contNormalBB = CGF.createBasicBlock("overflow.norm.cont");
+  llvm::BasicBlock *contFinalBB = CGF.createBasicBlock("overflow.final.cont");
+
+  CGF.CreateTrapBB();
+  CGF.ATEI.setAll(Ops.LHS, Ops.RHS, Ops.E, contFinalBB, tmpRule, 0);
+  CGF.Builder.CreateCondBr(overflow, CGF.getSoleTrapBB(), CGF.UseRandomValue? contNormalBB : contFinalBB);
+  CGF.EmitTrapBB();
+
+  if (CGF.UseRandomValue) {
+    CGF.EmitBlock(contNormalBB);
+    result = Builder.CreateExtractValue(resultAndOverflow, 0);
+    CGF.EmitBranch(contFinalBB);
+  }
+
+  CGF.EmitBlock(contFinalBB);
+
+  if (CGF.UseRandomValue) {
+    llvm::PHINode *phi = Builder.CreatePHI(opTy, 2);
+    phi->addIncoming(CGF.trapHandlerResult, CGF.getSoleTrapBB());
+    phi->addIncoming(result, contNormalBB);
+    return phi;
+  }
+  return Builder.CreateExtractValue(resultAndOverflow, 0);
+}
+
+Value *ScalarExprEmitter::getNormalAdditionValue(const BinOpInfo &Ops,
+                                                 unsigned addMark) {
+  llvm::Value *value = 0;
+  switch(addMark) {
+    case 0:
+      value = Builder.CreateNSWAdd(Ops.LHS, Ops.RHS, "add");
+      break;
+    case 1:
+      value = Builder.CreateNSWAdd(Ops.LHS, Ops.RHS, "inc");
+      break;
+    case 2:
+      value = Builder.CreateNSWAdd(Ops.LHS, Ops.RHS, "dec");
+      break;
+  }
+  return value;
+}
+
+// (((si1>0) && (si2>0) && (si1 > (INT_MAX-si2)))
+// || ((si1<0) && (si2<0) && (si1 < (INT_MIN-si2))))
+Value *ScalarExprEmitter::UndefinedBehaviorAddCheck(const BinOpInfo &Ops,
+                                                    unsigned addMark) {
+  CGF.rvOpTy = ConvertType(Ops.Ty);
+  if (CGF.rvOpTy->isVectorTy()) {
+    return getNormalAdditionValue(Ops, addMark);
+  }
+
+  const llvm::IntegerType *Ty = cast<llvm::IntegerType>(CGF.rvOpTy);
+  llvm::Value *IntMax = llvm::ConstantInt::get(
+                                    VMContext,
+                                    llvm::APInt::getSignedMaxValue(Ty->getBitWidth()));
+  llvm::Value *IntMin = llvm::ConstantInt::get(
+                                    VMContext,
+                                    llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
+
+  std::string tmpRule;
+  llvm::Value *Zero = llvm::Constant::getNullValue(CGF.rvOpTy);
+
+  llvm::BasicBlock *TrueBB1 = CGF.createBasicBlock("add.true");
+  llvm::BasicBlock *FalseBB1 = CGF.createBasicBlock("add.false");
+  llvm::BasicBlock *AddNormalEnd = CGF.createBasicBlock("add.norm.end");
+  llvm::BasicBlock *AddFinalEnd = CGF.createBasicBlock("add.final.end");
+
+  CGF.Builder.CreateCondBr(Builder.CreateAnd(
+                             Builder.CreateICmpSGT(Ops.LHS, Zero),
+                               Builder.CreateICmpSGT(Ops.RHS, Zero), "and"),
+                           TrueBB1, FalseBB1);
+  CGF.EmitBlock(TrueBB1);
+
+  CGF.CreateTrapBB();
+  tmpRule = "Signed Addition Overflow";
+  CGF.ATEI.setAll(Ops.LHS, Ops.RHS, Ops.E, AddFinalEnd, tmpRule, 0);
+  CGF.Builder.CreateCondBr(Builder.CreateICmpSGT(Ops.LHS,
+                             Builder.CreateNSWSub(IntMax, Ops.RHS, "sub")),
+                           CGF.getSoleTrapBB(),
+                           CGF.UseRandomValue? AddNormalEnd : AddFinalEnd);
+  CGF.EmitTrapBB();
+
+  CGF.EmitBlock(FalseBB1);
+  llvm::BasicBlock *TrueBB2 = CGF.createBasicBlock("add.true");
+  CGF.Builder.CreateCondBr(Builder.CreateAnd(
+                             Builder.CreateICmpSLT(Ops.LHS, Zero),
+                               Builder.CreateICmpSLT(Ops.RHS, Zero), "and"),
+                           TrueBB2,
+                           CGF.UseRandomValue? AddNormalEnd : AddFinalEnd);
+
+  CGF.EmitBlock(TrueBB2);
+  CGF.Builder.CreateCondBr(Builder.CreateICmpSLT(Ops.LHS,
+                             Builder.CreateNSWSub(IntMin, Ops.RHS, "sub")),
+                           CGF.getSoleTrapBB(),
+                           CGF.UseRandomValue? AddNormalEnd : AddFinalEnd);
+
+  llvm::Value * result = 0;
+  if (CGF.UseRandomValue) {
+    CGF.EmitBlock(AddNormalEnd);
+    result = getNormalAdditionValue(Ops, addMark);
+    CGF.EmitBranch(AddFinalEnd);
+  }
+
+  CGF.EmitBlock(AddFinalEnd);
+
+  if (CGF.UseRandomValue) {
+    llvm::PHINode *phi = Builder.CreatePHI(CGF.rvOpTy, 2);
+    phi->addIncoming(CGF.trapHandlerResult, CGF.getSoleTrapBB());
+    phi->addIncoming(result, AddNormalEnd);
+    return phi;
+  }
+  return getNormalAdditionValue(Ops, addMark);
+}
+
+void ScalarExprEmitter::UnsignedOverflowAddCheck(const BinOpInfo &Ops) {
+  CGF.rvOpTy = ConvertType(Ops.Ty);
+  if (CGF.rvOpTy->isVectorTy()) {
+    return;
+  }
+
+  const llvm::IntegerType *Ty = cast<llvm::IntegerType>(CGF.rvOpTy);
+  llvm::Value *UIntMax = llvm::ConstantInt::get(
+                                    VMContext,
+                                    llvm::APInt::getMaxValue(Ty->getBitWidth()));
+  std::string tmpRule;
+  llvm::BasicBlock *UAddCont = CGF.createBasicBlock("uadd.cont");
+
+  CGF.CreateTrapBB();
+  tmpRule = "Unsigned Addition Overflow";
+  CGF.ATEI.setAll(Ops.LHS, Ops.RHS, Ops.E, UAddCont, tmpRule, 2);
+  CGF.Builder.CreateCondBr(Builder.CreateICmpUGT(Ops.LHS,
+                             Builder.CreateNUWSub(UIntMax, Ops.RHS, "uadd")),
+                           CGF.getSoleTrapBB(), UAddCont);
+
+  CGF.EmitTrapBB();
+  CGF.EmitBlock(UAddCont);
+}
+
+// si2 < 0 ? si1 > INT_MAX + si2 : si1 < INT_MIN + si2
+Value *ScalarExprEmitter::UndefinedBehaviorSubCheck(const BinOpInfo &Ops) {
+  CGF.rvOpTy = ConvertType(Ops.Ty);
+  if (CGF.rvOpTy->isVectorTy()) {
+    return Builder.CreateNSWSub(Ops.LHS, Ops.RHS, "sub");
+  }
+  const llvm::IntegerType *Ty = cast<llvm::IntegerType>(CGF.rvOpTy);
+  llvm::Value *IntMax = llvm::ConstantInt::get(
+                                    VMContext,
+                                    llvm::APInt::getSignedMaxValue(Ty->getBitWidth()));
+  llvm::Value *IntMin = llvm::ConstantInt::get(
+                                    VMContext,
+                                    llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
+
+  std::string tmpRule;
+  llvm::Value *Zero = llvm::Constant::getNullValue(CGF.rvOpTy);
+
+  llvm::BasicBlock *TrueBB1 = CGF.createBasicBlock("sub.true");
+  llvm::BasicBlock *FalseBB1 = CGF.createBasicBlock("sub.false");
+  llvm::BasicBlock *SubNormalEnd = CGF.createBasicBlock("sub.norm.end");
+  llvm::BasicBlock *SubFinalEnd = CGF.createBasicBlock("sub.final.end");
+
+  CGF.Builder.CreateCondBr(Builder.CreateICmpSLT(Ops.RHS, Zero),
+                           TrueBB1, FalseBB1);
+  CGF.EmitBlock(TrueBB1);
+
+  CGF.CreateTrapBB();
+  tmpRule = "Signed Subtraction Overflow";
+  CGF.ATEI.setAll(Ops.LHS, Ops.RHS, Ops.E, SubFinalEnd, tmpRule, 0);
+  CGF.Builder.CreateCondBr(Builder.CreateICmpSGT(Ops.LHS,
+                             Builder.CreateNSWAdd(IntMax, Ops.RHS, "add")),
+                           CGF.getSoleTrapBB(),
+                           CGF.UseRandomValue? SubNormalEnd : SubFinalEnd);
+  CGF.EmitTrapBB();
+
+  CGF.EmitBlock(FalseBB1);
+  llvm::BasicBlock *TrueBB2 = CGF.createBasicBlock("sub.true");
+  CGF.Builder.CreateCondBr(Builder.CreateICmpSGT(Ops.RHS, Zero),
+                           TrueBB2,
+                           CGF.UseRandomValue? SubNormalEnd : SubFinalEnd);
+
+  CGF.EmitBlock(TrueBB2);
+  CGF.Builder.CreateCondBr(Builder.CreateICmpSLT(Ops.LHS,
+                             Builder.CreateNSWAdd(IntMin, Ops.RHS, "add")),
+                           CGF.getSoleTrapBB(),
+                           CGF.UseRandomValue? SubNormalEnd : SubFinalEnd);
+
+  llvm::Value *result = 0;
+  if (CGF.UseRandomValue) {
+    CGF.EmitBlock(SubNormalEnd);
+    result = Builder.CreateNSWSub(Ops.LHS, Ops.RHS, "sub");
+    CGF.EmitBranch(SubFinalEnd);
+  }
+
+  CGF.EmitBlock(SubFinalEnd);
+
+  if (CGF.UseRandomValue) {
+    llvm::PHINode *phi = Builder.CreatePHI(CGF.rvOpTy, 2);
+    phi->addIncoming(CGF.trapHandlerResult, CGF.getSoleTrapBB());
+    phi->addIncoming(result, SubNormalEnd);
+    return phi;
+  }
+  return Builder.CreateNSWSub(Ops.LHS, Ops.RHS, "sub");
+}
+
+
+void ScalarExprEmitter::UnsignedOverflowSubCheck(const BinOpInfo &Ops) {
+  CGF.rvOpTy = ConvertType(Ops.Ty);
+  if (CGF.rvOpTy->isVectorTy()) {
+    return;
+  }
+  std::string tmpRule;
+  llvm::BasicBlock *USubCont = CGF.createBasicBlock("usub.cont");
+
+  CGF.CreateTrapBB();
+  tmpRule = "Unsigned Subtraction Overflow";
+  CGF.ATEI.setAll(Ops.LHS, Ops.RHS, Ops.E, USubCont, tmpRule, 2);
+  CGF.Builder.CreateCondBr(Builder.CreateICmpULT(Ops.LHS, Ops.RHS),
+                           CGF.getSoleTrapBB(), USubCont);
+  CGF.EmitTrapBB();
+  CGF.EmitBlock(USubCont);
+}
+
+// (((si1 > 0) && (si2 > 0) && (si1 > (INT_MAX / si2)))
+// || ((si1 > 0) && (si2 < 0) && (si2 < (INT_MIN / si1)))
+// || ((si1 < 0) && (si2 > 0) && (si1 < (INT_MIN / si2)))
+// || ((si1 < 0) && (si2 < 0) && (si1 != 0) && (si2 < (INT_MAX / si1))))
+Value *ScalarExprEmitter::UndefinedBehaviorMulCheck(const BinOpInfo &Ops) {
+  CGF.rvOpTy = ConvertType(Ops.Ty);
+  if (CGF.rvOpTy->isVectorTy()) {
+    return Builder.CreateNSWMul(Ops.LHS, Ops.RHS, "mul");
+  }
+  const llvm::IntegerType *Ty = cast<llvm::IntegerType>(CGF.rvOpTy);
+  llvm::Value *IntMax = llvm::ConstantInt::get(
+                                    VMContext,
+                                    llvm::APInt::getSignedMaxValue(Ty->getBitWidth()));
+  llvm::Value *IntMin = llvm::ConstantInt::get(
+                                    VMContext,
+                                    llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
+
+  std::string tmpRule;
+  llvm::Value *Zero = llvm::Constant::getNullValue(CGF.rvOpTy);
+
+  // Cond1: (si1 > 0) && (si2 > 0) && (si1 > (INT_MAX / si2))
+  llvm::BasicBlock *TrueBB1 = CGF.createBasicBlock("mul.true");
+  llvm::BasicBlock *FalseBB1 = CGF.createBasicBlock("mul.false");
+  llvm::BasicBlock *MulNormalEnd = CGF.createBasicBlock("mul.norm.end");
+  llvm::BasicBlock *MulFinalEnd = CGF.createBasicBlock("mul.final.end");
+
+  CGF.Builder.CreateCondBr(Builder.CreateAnd(
+                             Builder.CreateICmpSGT(Ops.LHS, Zero),
+                               Builder.CreateICmpSGT(Ops.RHS, Zero), "and"),
+                           TrueBB1, FalseBB1);
+  CGF.EmitBlock(TrueBB1);
+  CGF.CreateTrapBB();
+  tmpRule = "Signed Multiplication Overflow";
+  CGF.ATEI.setAll(Ops.LHS, Ops.RHS, Ops.E, MulFinalEnd, tmpRule, 0);
+  CGF.Builder.CreateCondBr(Builder.CreateICmpSGT(Ops.LHS,
+                             Builder.CreateSDiv(IntMax, Ops.RHS, "div")),
+                           CGF.getSoleTrapBB(),
+                           CGF.UseRandomValue? MulNormalEnd : MulFinalEnd);
+  CGF.EmitTrapBB();
+
+  CGF.EmitBlock(FalseBB1);
+  // Cond2: (si1 > 0) && (si2 < 0) && (si2 < (INT_MIN / si1))
+  llvm::BasicBlock *TrueBB2 = CGF.createBasicBlock("mul.true");
+  llvm::BasicBlock *FalseBB2 = CGF.createBasicBlock("mul.false");
+
+  CGF.Builder.CreateCondBr(Builder.CreateAnd(
+                             Builder.CreateICmpSGT(Ops.LHS, Zero),
+                               Builder.CreateICmpSLT(Ops.RHS, Zero), "and"),
+                           TrueBB2, FalseBB2);
+
+  CGF.EmitBlock(TrueBB2);
+  CGF.Builder.CreateCondBr(Builder.CreateICmpSLT(Ops.RHS,
+                             Builder.CreateSDiv(IntMin, Ops.LHS, "div")),
+                           CGF.getSoleTrapBB(),
+                           CGF.UseRandomValue? MulNormalEnd : MulFinalEnd);
+
+  CGF.EmitBlock(FalseBB2);
+  // Cond3: (si1 < 0) && (si2 > 0) && (si1 < (INT_MIN / si2))
+  llvm::BasicBlock *TrueBB3 = CGF.createBasicBlock("mul.true");
+  llvm::BasicBlock *FalseBB3 = CGF.createBasicBlock("mul.false");
+
+  CGF.Builder.CreateCondBr(Builder.CreateAnd(
+                             Builder.CreateICmpSLT(Ops.LHS, Zero),
+                               Builder.CreateICmpSGT(Ops.RHS, Zero), "and"),
+			   TrueBB3, FalseBB3);
+
+  CGF.EmitBlock(TrueBB3);
+  CGF.Builder.CreateCondBr(Builder.CreateICmpSLT(Ops.LHS,
+                             Builder.CreateSDiv(IntMin, Ops.RHS, "div")),
+			     CGF.getSoleTrapBB(),
+			     CGF.UseRandomValue? MulNormalEnd : MulFinalEnd);
+
+  CGF.EmitBlock(FalseBB3);
+  // Cond4: (si1 < 0) && (si2 < 0) && (si2 < (INT_MAX / si1))
+  llvm::BasicBlock *TrueBB4 = CGF.createBasicBlock("mul.true");
+
+  CGF.Builder.CreateCondBr(Builder.CreateAnd(
+                             Builder.CreateICmpSLT(Ops.LHS, Zero),
+                               Builder.CreateICmpSLT(Ops.RHS, Zero), "and"),
+                           TrueBB4,
+                           CGF.UseRandomValue? MulNormalEnd : MulFinalEnd);
+
+  CGF.EmitBlock(TrueBB4);
+  CGF.Builder.CreateCondBr(Builder.CreateICmpSLT(Ops.RHS,
+                             Builder.CreateSDiv(IntMax, Ops.LHS, "div")),
+                           CGF.getSoleTrapBB(),
+                           CGF.UseRandomValue? MulNormalEnd : MulFinalEnd);
+
+  llvm::Value *result = 0;
+  if (CGF.UseRandomValue) {
+    CGF.EmitBlock(MulNormalEnd);
+    result = Builder.CreateNSWMul(Ops.LHS, Ops.RHS, "mul");
+    CGF.EmitBranch(MulFinalEnd);
+  }
+  CGF.EmitBlock(MulFinalEnd);
+
+  if (CGF.UseRandomValue) {
+    llvm::PHINode *phi = Builder.CreatePHI(CGF.rvOpTy, 2);
+    phi->addIncoming(CGF.trapHandlerResult, CGF.getSoleTrapBB());
+    phi->addIncoming(result, MulNormalEnd);
+    return phi;
+  }
+  return Builder.CreateNSWMul(Ops.LHS, Ops.RHS, "mul");
+}
+
+void ScalarExprEmitter::UnsignedOverflowMulCheck(const BinOpInfo &Ops) {
+  CGF.rvOpTy = ConvertType(Ops.Ty);
+  if (CGF.rvOpTy->isVectorTy()) {
+    return;
+  }
+  const llvm::IntegerType *Ty = cast<llvm::IntegerType>(CGF.rvOpTy);
+  llvm::Value *Zero = llvm::Constant::getNullValue(CGF.rvOpTy);
+  llvm::Value *UIntMax = llvm::ConstantInt::get(
+                                    VMContext,
+                                    llvm::APInt::getMaxValue(Ty->getBitWidth()));
+
+  std::string tmpRule;
+  llvm::BasicBlock *UMulCont = CGF.createBasicBlock("umul.cont");
+  llvm::BasicBlock *ZeroTrueBB = CGF.createBasicBlock("umul.zero.true");
+
+  CGF.Builder.CreateCondBr(Builder.CreateICmpUGT(Ops.RHS, Zero),
+                            ZeroTrueBB, UMulCont);
+
+  CGF.EmitBlock(ZeroTrueBB);
+  CGF.CreateTrapBB();
+  tmpRule = "Unsigned Multiplication Overflow";
+  CGF.ATEI.setAll(Ops.LHS, Ops.RHS, Ops.E, UMulCont, tmpRule, 2);
+  CGF.Builder.CreateCondBr(Builder.CreateICmpUGT(Ops.LHS,
+                             Builder.CreateUDiv(UIntMax, Ops.RHS, "udiv")),
+                           CGF.getSoleTrapBB(), UMulCont);
+  CGF.EmitTrapBB();
+  CGF.EmitBlock(UMulCont);
+}
+
 /// Emit pointer + index arithmetic.
 static Value *emitPointerArithmetic(CodeGenFunction &CGF,
                                     const BinOpInfo &op,
@@ -2009,6 +2753,12 @@ Value *ScalarExprEmitter::EmitAdd(const BinOpInfo &op) {
   if (op.Ty->isSignedIntegerOrEnumerationType()) {
     switch (CGF.getContext().getLangOpts().getSignedOverflowBehavior()) {
     case LangOptions::SOB_Undefined:
+      if (CGF.catchArithUndefined()) {
+        if (CGF.UseIntrinsic)
+          return UndefinedBehaviorOverflowCheck(op);
+        else
+          return UndefinedBehaviorAddCheck(op, 0);
+      }
       return Builder.CreateNSWAdd(op.LHS, op.RHS, "add");
     case LangOptions::SOB_Defined:
       return Builder.CreateAdd(op.LHS, op.RHS, "add");
@@ -2020,6 +2770,10 @@ Value *ScalarExprEmitter::EmitAdd(const BinOpInfo &op) {
   if (op.LHS->getType()->isFPOrFPVectorTy())
     return Builder.CreateFAdd(op.LHS, op.RHS, "add");
 
+  // Here, we must consider the unsigned overflowing operation...
+  if (op.Ty->hasUnsignedIntegerRepresentation() && CGF.catchNonUBCType())
+    UnsignedOverflowAddCheck(op);
+
   return Builder.CreateAdd(op.LHS, op.RHS, "add");
 }
 
@@ -2029,6 +2783,12 @@ Value *ScalarExprEmitter::EmitSub(const BinOpInfo &op) {
     if (op.Ty->isSignedIntegerOrEnumerationType()) {
       switch (CGF.getContext().getLangOpts().getSignedOverflowBehavior()) {
       case LangOptions::SOB_Undefined:
+        if (CGF.catchArithUndefined()) {
+          if (CGF.UseIntrinsic)
+            return UndefinedBehaviorOverflowCheck(op);
+          else
+            return UndefinedBehaviorSubCheck(op);
+        }
         return Builder.CreateNSWSub(op.LHS, op.RHS, "sub");
       case LangOptions::SOB_Defined:
         return Builder.CreateSub(op.LHS, op.RHS, "sub");
@@ -2040,6 +2800,10 @@ Value *ScalarExprEmitter::EmitSub(const BinOpInfo &op) {
     if (op.LHS->getType()->isFPOrFPVectorTy())
       return Builder.CreateFSub(op.LHS, op.RHS, "sub");
 
+    // Here, we must consider the unsigned overflowing operation...
+    if (op.Ty->hasUnsignedIntegerRepresentation() && CGF.catchNonUBCType())
+      UnsignedOverflowSubCheck(op);
+
     return Builder.CreateSub(op.LHS, op.RHS, "sub");
   }
 
@@ -2108,14 +2872,94 @@ Value *ScalarExprEmitter::EmitShl(const BinOpInfo &Ops) {
   if (Ops.LHS->getType() != RHS->getType())
     RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(), false, "sh_prom");
 
-  if (CGF.CatchUndefined 
-      && isa<llvm::IntegerType>(Ops.LHS->getType())) {
+  if (CGF.catchArithUndefined()
+       && isa<llvm::IntegerType>(Ops.LHS->getType())) {
+    std::string tmpRule;
     unsigned Width = cast<llvm::IntegerType>(Ops.LHS->getType())->getBitWidth();
-    llvm::BasicBlock *Cont = CGF.createBasicBlock("cont");
+    bool Continue = Ops.Ty->isSignedIntegerType()
+                      && (CGF.CatchUndefinedC99 || CGF.CatchUndefinedCXX0X
+                         || CGF.CatchUndefined);
+    llvm::Value *tmpTrapResult = 0;
+    llvm::BasicBlock *tmpTrapBB = 0;
+    llvm::BasicBlock *ShlCont1 = CGF.createBasicBlock("shl.cont");
+    llvm::BasicBlock *ShlNonNormalEnd =
+                                CGF.createBasicBlock("shl.non.norm.end");
+    llvm::BasicBlock *ShlNormalEnd = CGF.createBasicBlock("shl.norm.end");
+    llvm::BasicBlock *ShlFinalEnd = CGF.createBasicBlock("shl.final.end");
+    CGF.rvOpTy = ConvertType(Ops.Ty);
+
+    CGF.CreateTrapBB();
+    // The type of left shift result is that of the promoted left operand...
+    if (Ops.Ty->isSignedIntegerType()) {
+      tmpRule = "Signed Left Shift: Right operand is negative or is greater";
+      tmpRule += " than or equal to the width of the promoted left operand";
+    }
+    else {
+      tmpRule = "Unsigned Left Shift: Right operand is negative or is greater";
+      tmpRule += " than or equal to the width of the promoted left operand";
+    }
+    if (CGF.UseRandomValue)
+      CGF.ATEI.setAll(Ops.LHS, RHS, Ops.E,
+                      Continue? ShlNonNormalEnd : ShlFinalEnd, tmpRule, 0);
+    else
+      CGF.ATEI.setAll(Ops.LHS, RHS, Ops.E, ShlCont1, tmpRule, 0);
     CGF.Builder.CreateCondBr(Builder.CreateICmpULT(RHS,
                                  llvm::ConstantInt::get(RHS->getType(), Width)),
-                             Cont, CGF.getTrapBB());
-    CGF.EmitBlock(Cont);
+                             ShlCont1, CGF.getSoleTrapBB());
+    CGF.EmitTrapBB();
+    tmpTrapResult = CGF.trapHandlerResult;
+    tmpTrapBB = CGF.getSoleTrapBB();
+    CGF.EmitBlock(ShlCont1);
+
+    if (Continue) {
+      const llvm::IntegerType *Ty = cast<llvm::IntegerType>(CGF.rvOpTy);
+      llvm::Value *IntMax = llvm::ConstantInt::get(
+                                       VMContext,
+                                       llvm::APInt::getSignedMaxValue(Ty->getBitWidth()));
+
+      // Here, we can directly execute the instruction "Int_Max >> right"
+      // without checking whether right operand is greater than the
+      // width of left operand type due to previous checks.
+      llvm::Value *ResValue = Builder.CreateAShr(IntMax, RHS, "shr");
+      llvm::BasicBlock *ShlCont2 = CGF.createBasicBlock("shl.cont");
+      CGF.CreateTrapBB();
+      tmpRule = "Signed Left Shift: left operand is negative || ";
+      tmpRule += "left operand is nonnegative, ";
+      tmpRule += "but the result can not be represented in the result ";
+      tmpRule += "signed type";
+      CGF.ATEI.setAll(Ops.LHS, RHS, Ops.E,
+                      CGF.UseRandomValue? ShlNonNormalEnd : ShlCont2, tmpRule, 0);
+      CGF.Builder.CreateCondBr(Builder.CreateICmpUGT(Ops.LHS, ResValue),
+                               CGF.getSoleTrapBB(), ShlCont2);
+      CGF.EmitTrapBB();
+      CGF.EmitBlock(ShlCont2);
+    }
+
+    if (CGF.UseRandomValue) {
+      CGF.EmitBlock(ShlNormalEnd);
+      llvm::Value *result = Builder.CreateShl(Ops.LHS, RHS, "shl");
+      llvm::PHINode *tmpphi = 0;
+      llvm::PHINode *finalPHI = 0;
+      CGF.EmitBranch(ShlFinalEnd);
+
+      if (Continue) {
+        CGF.EmitBlock(ShlNonNormalEnd);
+        tmpphi = Builder.CreatePHI(CGF.rvOpTy, 2);
+        tmpphi->addIncoming(tmpTrapResult, tmpTrapBB);
+        tmpphi->addIncoming(CGF.trapHandlerResult, CGF.getSoleTrapBB());
+        CGF.EmitBranch(ShlFinalEnd);
+      }
+
+      CGF.EmitBlock(ShlFinalEnd);
+
+      finalPHI = Builder.CreatePHI(CGF.rvOpTy, 2);
+      if (Continue)
+        finalPHI->addIncoming(tmpphi, ShlNonNormalEnd);
+      else
+        finalPHI->addIncoming(CGF.trapHandlerResult, CGF.getSoleTrapBB());
+      finalPHI->addIncoming(result, ShlNormalEnd);
+      return finalPHI;
+    }
   }
 
   return Builder.CreateShl(Ops.LHS, RHS, "shl");
@@ -2128,14 +2972,49 @@ Value *ScalarExprEmitter::EmitShr(const BinOpInfo &Ops) {
   if (Ops.LHS->getType() != RHS->getType())
     RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(), false, "sh_prom");
 
-  if (CGF.CatchUndefined 
+  if (CGF.catchArithUndefined()
       && isa<llvm::IntegerType>(Ops.LHS->getType())) {
+    std::string tmpRule;
     unsigned Width = cast<llvm::IntegerType>(Ops.LHS->getType())->getBitWidth();
-    llvm::BasicBlock *Cont = CGF.createBasicBlock("cont");
+    CGF.rvOpTy = ConvertType(Ops.Ty);
+    llvm::BasicBlock *ShrNormalEnd = CGF.createBasicBlock("shr.norm.cont");
+    llvm::BasicBlock *ShrFinalEnd = CGF.createBasicBlock("shr.final.cont");
+
+    CGF.CreateTrapBB();
+    // Since the type of the result is that of the promoted left operand...
+    if (Ops.Ty->isSignedIntegerType()) {
+      tmpRule = "Signed Right Shift: Right operand is negative or is greater";
+      tmpRule += " than or equal to the width of the promoted left operand";
+    }
+    else {
+      tmpRule = "Unsigned Right Shift: Right operand is negative or is greater";
+      tmpRule += " than or equal to the width of the promoted left operand";
+    }
+    CGF.ATEI.setAll(Ops.LHS, RHS, Ops.E, ShrFinalEnd, tmpRule, 0);
     CGF.Builder.CreateCondBr(Builder.CreateICmpULT(RHS,
-                                 llvm::ConstantInt::get(RHS->getType(), Width)),
-                             Cont, CGF.getTrapBB());
-    CGF.EmitBlock(Cont);
+                               llvm::ConstantInt::get(RHS->getType(), Width)),
+                             CGF.UseRandomValue? ShrNormalEnd : ShrFinalEnd,
+                             CGF.getSoleTrapBB());
+    CGF.EmitTrapBB();
+
+    llvm::Value *result = 0;
+    if (CGF.UseRandomValue) {
+      CGF.EmitBlock(ShrNormalEnd);
+      if (Ops.Ty->hasUnsignedIntegerRepresentation())
+        result = Builder.CreateLShr(Ops.LHS, RHS, "shr");
+      else
+        result = Builder.CreateAShr(Ops.LHS, RHS, "shr");
+      CGF.EmitBranch(ShrFinalEnd);
+    }
+
+    CGF.EmitBlock(ShrFinalEnd);
+
+    if (CGF.UseRandomValue) {
+      llvm::PHINode *phi = Builder.CreatePHI(CGF.rvOpTy, 2);
+      phi->addIncoming(CGF.trapHandlerResult, CGF.getSoleTrapBB());
+      phi->addIncoming(result, ShrNormalEnd);
+      return phi;
+    }
   }
 
   if (Ops.Ty->hasUnsignedIntegerRepresentation())
@@ -2311,6 +3190,8 @@ Value *ScalarExprEmitter::EmitCompare(const BinaryOperator *E,unsigned UICmpOpc,
 
 Value *ScalarExprEmitter::VisitBinAssign(const BinaryOperator *E) {
   bool Ignore = TestAndClearIgnoreResultAssign();
+  CGF.ATEI.setAssignOp(E);
+  CGF.NonArithSL = E->getOperatorLoc();
 
   Value *RHS;
   LValue LHS;
@@ -2348,6 +3229,8 @@ Value *ScalarExprEmitter::VisitBinAssign(const BinaryOperator *E) {
       CGF.EmitStoreThroughLValue(RValue::get(RHS), LHS);
   }
 
+  CGF.ATEI.clearAssignOp();
+
   // If the result is clearly ignored, return now.
   if (Ignore)
     return 0;
@@ -2742,6 +3625,7 @@ Value *CodeGenFunction::EmitScalarExpr(const Expr *E, bool IgnoreResultAssign) {
   assert(E && !hasAggregateLLVMType(E->getType()) &&
          "Invalid scalar expression to emit");
 
+  NonArithSL = E->getExprLoc();
   if (isa<CXXDefaultArgExpr>(E))
     disableDebugInfo();
   Value *V = ScalarExprEmitter(*this, IgnoreResultAssign)
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index 2939062..8c00eeb 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -39,9 +39,29 @@
     IndirectBranch(0), SwitchInsn(0), CaseRangeBlock(0), UnreachableBlock(0),
     CXXABIThisDecl(0), CXXABIThisValue(0), CXXThisValue(0), CXXVTTDecl(0),
     CXXVTTValue(0), OutermostConditional(0), TerminateLandingPad(0),
-    TerminateHandler(0), TrapBB(0) {
+    TerminateHandler(0), TrapBB(0),
+    ATEI(), NONUBC(), NonArithSL() {
+  // Get some frequently used types.
+  LLVMPointerWidth = Target.getPointerWidth(0);
+  llvm::LLVMContext &LLVMContext = CGM.getLLVMContext();
+  rvOpTy = 0;
+  trapHandlerResult = 0;
+  IntPtrTy = llvm::IntegerType::get(LLVMContext, LLVMPointerWidth);
+  Int8Ty  = llvm::Type::getInt8Ty(LLVMContext);
+  Int32Ty  = llvm::Type::getInt32Ty(LLVMContext);
+  Int64Ty  = llvm::Type::getInt64Ty(LLVMContext);
 
   CatchUndefined = getContext().getLangOpts().CatchUndefined;
+  CatchUndefinedAnsiC = getContext().getLangOpts().CatchUndefinedAnsiC;
+  CatchUndefinedC99 = getContext().getLangOpts().CatchUndefinedC99;
+  CatchUndefinedCXX0X = getContext().getLangOpts().CatchUndefinedCXX0X;
+  CatchUndefinedCXX98 = getContext().getLangOpts().CatchUndefinedCXX98;
+  CatchNonArithUndefined = getContext().getLangOpts().CatchNonArithUndefined;
+  UseIntrinsic = getContext().getLangOpts().UseIntrinsic;
+  UseRandomValue = getContext().getLangOpts().UseRandomValue;
+  ChecksNum = getContext().getLangOpts().ChecksNum;
+  CatchNonUBCType = getContext().getLangOpts().CatchNonUBCType;
+
   CGM.getCXXABI().getMangleContext().startNewFunction();
 }
 
@@ -353,6 +373,7 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
   PrologueCleanupDepth = EHStack.stable_begin();
   EmitFunctionProlog(*CurFnInfo, CurFn, Args);
 
+  NonArithSL = StartLoc;
   if (D && isa<CXXMethodDecl>(D) && cast<CXXMethodDecl>(D)->isInstance()) {
     CGM.getCXXABI().EmitInstanceFunctionProlog(*this);
     const CXXMethodDecl *MD = cast<CXXMethodDecl>(D);
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index 83f1e2d..673e4b2 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -78,6 +78,119 @@
   class BlockFlags;
   class BlockFieldFlags;
 
+class NonUBCType {
+private:
+  QualType srcType;
+  QualType dstType;
+public:
+  NonUBCType() {}
+
+  ~NonUBCType() {}
+
+  void setAll(QualType src, QualType dst) {
+    // copy construction
+    srcType = src;
+    dstType = dst;
+  }
+
+  QualType getSrcType() {
+    return srcType;
+  }
+
+  QualType getDstType() {
+    return dstType;
+  }
+};
+
+// The information contained in this class will be used by trap handler
+// in trap block.
+class ArithmeticTrapErrorInfo {
+private:
+  llvm::Value *LValue; // The left operand
+  llvm::Value *RValue; // The right operand
+  const Expr *Operator; // The binary or unary operator
+  const BinaryOperator *AssignOp; // The assign operator
+  llvm::BasicBlock *trapNextBB; // The basic block that trap block jumps to
+  std::string rule; // The rule violated
+  unsigned mark; // The mark type for undefined checking or non-undefined one
+
+public:
+
+  ArithmeticTrapErrorInfo() {
+    LValue = 0;
+    RValue  = 0;
+    Operator = 0;
+    AssignOp = 0;
+    trapNextBB = 0;
+    mark = 0;
+  }
+
+  ~ArithmeticTrapErrorInfo() {
+    LValue  = 0;
+    RValue  = 0;
+    Operator = 0;
+    AssignOp = 0;
+    trapNextBB = 0;
+    rule.clear();
+    mark = 0;
+  }
+
+  void setAll(llvm::Value *lvalue, llvm::Value *rvalue, const Expr *Op,
+              llvm::BasicBlock *nextBB, std::string tmpRule, unsigned m) {
+    LValue = lvalue;
+    RValue = rvalue;
+    Operator = Op;
+    trapNextBB = nextBB;
+    rule = tmpRule;
+    mark = m;
+  }
+
+  void clearAll() {
+    LValue = 0;
+    RValue = 0;
+    Operator = 0;
+    trapNextBB = 0;
+    rule.clear();
+    mark = 0;
+  }
+
+  llvm::Value *getLValue() const {
+    return LValue;
+  }
+
+  llvm::Value *getRValue() const {
+    return RValue;
+  }
+
+  const Expr *getOp() const {
+    return Operator;
+  }
+
+  void setAssignOp(const BinaryOperator *op) {
+    AssignOp = op;
+  }
+
+  const BinaryOperator *getAssignOp() const {
+    return AssignOp;
+  }
+
+  void clearAssignOp() {
+    AssignOp = 0;
+  }
+
+  llvm::BasicBlock *getTrapNextBB() const {
+    return trapNextBB;
+  }
+
+  std::string getRule() const {
+    return rule;
+  }
+
+  unsigned getMark() const {
+    return mark;
+  }
+};
+
 /// A branch fixup.  These are required when emitting a goto to a
 /// label which hasn't been emitted yet.  The goto is optimistically
 /// emitted as a branch to the basic block for the label, and (if it
@@ -591,7 +704,30 @@ class CodeGenFunction : public CodeGenTypeCache {
   /// we prefer to insert allocas.
   llvm::AssertingVH<llvm::Instruction> AllocaInsertPt;
 
+  // The type used in trap block
+  llvm::Type* rvOpTy;
+  llvm::Value* trapHandlerResult;
+
+  // intptr_t, i8, i32, i64
+  //llvm::IntegerType *IntPtrTy, *Int8Ty, *Int32Ty, *Int64Ty;
+  uint32_t LLVMPointerWidth;
+
+  bool Exceptions;
   bool CatchUndefined;
+  bool CatchUndefinedAnsiC;
+  bool CatchUndefinedC99;
+  bool CatchUndefinedCXX0X;
+  bool CatchUndefinedCXX98;
+  bool CatchNonArithUndefined;
+  bool CatchNonUBCType;
+
+  // Whether to apply LLVM intrinsic backends for +, - and *
+  bool UseIntrinsic;
+  // Whether to use the random result returned by trap handler
+  // instead of operation's own result.
+  bool UseRandomValue;
+  // Whether to output the number of instrumented checks
+  bool ChecksNum;
 
   /// In ARC, whether we should autorelease the return value.
   bool AutoreleaseResult;
@@ -1193,6 +1329,10 @@ class CodeGenFunction : public CodeGenTypeCache {
   llvm::BasicBlock *TrapBB;
 
 public:
+  ArithmeticTrapErrorInfo ATEI; // The arithmetic trap info object
+  NonUBCType NONUBC; // The non-integer-undefined-checking object
+  // The detailed source code location of non-arithmetic operation
+  clang::SourceLocation NonArithSL;
   CodeGenFunction(CodeGenModule &cgm);
   ~CodeGenFunction();
 
@@ -1365,6 +1505,7 @@ class CodeGenFunction : public CodeGenTypeCache {
 
   void GenerateCode(GlobalDecl GD, llvm::Function *Fn,
                     const CGFunctionInfo &FnInfo);
+  void CXXThisIsNull();
   void StartFunction(GlobalDecl GD, QualType RetTy,
                      llvm::Function *Fn,
                      const CGFunctionInfo &FnInfo,
@@ -2505,10 +2646,31 @@ class CodeGenFunction : public CodeGenTypeCache {
   void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock,
                             llvm::BasicBlock *FalseBlock);
 
+  /// Whether to catch arithmetic operations..
+  bool catchArithUndefined() const;
+
+  /// Whether to catch non-arithmetic operations..
+  bool catchNonArithUndefined() const;
+
+  /// Whether to catch non-undefined operations..
+  bool catchNonUBCType() const;
+
+  /// Invoke the concrete trap handler...
+  void invokeTrapHandlerFunction();
+
   /// getTrapBB - Create a basic block that will call the trap intrinsic.  We'll
   /// generate a branch around the created basic block as necessary.
   llvm::BasicBlock *getTrapBB();
 
+  /// CreateTrapBB - create the trap BB
+  void CreateTrapBB();
+
+  /// getSoleTrapBB - Just return the trap BB
+  llvm::BasicBlock *getSoleTrapBB();
+
+  /// EmitTrapBB - Just emit the relevant trap BB
+  void EmitTrapBB();
+
   /// EmitCallArg - Emit a single call argument.
   void EmitCallArg(CallArgList &args, const Expr *E, QualType ArgType);
 
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 9a55c08..f070a79 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -109,6 +109,7 @@
 
   // If debug info or coverage generation is enabled, create the CGDebugInfo
   // object.
+  checksNum = 0;
   if (CodeGenOpts.DebugInfo || CodeGenOpts.EmitGcovArcs ||
       CodeGenOpts.EmitGcovNotes)
     DebugInfo = new CGDebugInfo(*this);
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index 38f5008..d9bc030 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -344,6 +344,7 @@ class CodeGenModule : public CodeGenTypeCache {
   llvm::Constant *BlockObjectAssign;
   llvm::Constant *BlockObjectDispose;
 
+  uint32_t checksNum;
   llvm::Type *BlockDescriptorType;
   llvm::Type *GenericBlockLiteralType;
 
@@ -359,6 +360,10 @@ class CodeGenModule : public CodeGenTypeCache {
 
   ~CodeGenModule();
 
+  uint32_t getChecksNum() {
+    return ++checksNum;
+  }
+
   /// Release - Finalize LLVM code generation.
   void Release();
 
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index 3ddac69..745e3c7 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -100,6 +100,49 @@ InputArgList *Driver::ParseArgStrings(ArrayRef<const char *> ArgList) {
   InputArgList *Args = getOpts().ParseArgs(ArgList.begin(), ArgList.end(),
                                            MissingArgIndex, MissingArgCount);
 
+  Arg *FinalPhaseArg = 0;
+  if (getFinalPhase(*Args, &FinalPhaseArg) == phases::Link
+      && (Args->hasArg(options::OPT_fcatch_undefined_behavior)
+        || Args->hasArg(options::OPT_fcatch_undefined_ansic_behavior)
+        || Args->hasArg(options::OPT_fcatch_undefined_c99_behavior)
+        || Args->hasArg(options::OPT_fcatch_undefined_cxx0x_behavior)
+        || Args->hasArg(options::OPT_fcatch_undefined_cxx98_behavior)
+        || Args->hasArg(options::OPT_fcatch_undefined_nonarith_behavior)
+        || Args->hasArg(options::OPT_fcatch_non_ubc_type))) {
+     // Manifest that the linkage is the final stage of whole compilation chain.
+     unsigned Index = 0, End = ArgList.end() - ArgList.begin();
+     bool lmFound = false;
+
+     while (Index < End) {
+       if (strcmp(*(ArgList.begin() + Index), "-lm") == 0) {
+         lmFound = true;
+         break;
+       }
+       Index++;
+     }
+
+     const char *newTrapLib;
+     Index = Args->size();
+     Arg *trapArg = 0;
+
+     if (Args->hasArg(options::OPT_fhandler_null)) {
+       // Activate the -fhandler-null flag...
+       newTrapLib = "-ltrapubnull";
+     }
+     else {
+       // Default case...
+       newTrapLib = "-ltrapub";
+     }
+     trapArg = getOpts().ParseOneArgTrap(*Args, Index, newTrapLib);
+     Args->append(trapArg);
+
+     if (!lmFound) {
+       const char *newLmLib = "-lm";
+       trapArg = getOpts().ParseOneArgTrap(*Args, Index, newLmLib);
+       Args->append(trapArg);
+     }
+  }
+
   // Check for missing argument error.
   if (MissingArgCount)
     Diag(clang::diag::err_drv_missing_argument)
diff --git a/lib/Driver/OptTable.cpp b/lib/Driver/OptTable.cpp
index 4f5390b..877e77d 100644
--- a/lib/Driver/OptTable.cpp
+++ b/lib/Driver/OptTable.cpp
@@ -185,6 +185,41 @@ Option *OptTable::CreateOption(unsigned id) const {
   return Opt;
 }
 
+// Index is just a padding argument, no real meaning...
+Arg *OptTable::ParseOneArgTrap(const ArgList &Args, unsigned &Index,
+                               const char *Str) const {
+  unsigned Prev = Index;
+  // Anything that doesn't start with '-' is an input, as is '-' itself.
+  if (Str[0] != '-' || Str[1] == '\0')
+    return new Arg(TheInputOption, Index++, Str);
+
+  const Info *Start = OptionInfos + FirstSearchableIndex;
+  const Info *End = OptionInfos + getNumOptions();
+
+  // Search for the first next option which could be a prefix.
+  Start = std::lower_bound(Start, End, Str);
+
+  for (; Start != End; ++Start) {
+    // Scan for first option which is a proper prefix.
+    for (; Start != End; ++Start) {
+      if (memcmp(Str, Start->Name, strlen(Start->Name)) == 0)
+        break;
+    }
+    if (Start == End)
+      break;
+
+    // -lxxx, just tease out 'xxx' part...
+    const char *strPart = Str + 2;
+    return new Arg(getOption(Start - OptionInfos + 1), Index++, strPart);
+
+    // Otherwise, see if this argument was missing values.
+    if (Prev != Index)
+      return 0;
+  }
+
+  return new Arg(TheUnknownOption, Index++, Str);
+}
+
 Arg *OptTable::ParseOneArg(const ArgList &Args, unsigned &Index) const {
   unsigned Prev = Index;
   const char *Str = Args.getArgString(Index);
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index 47b5294..c73d3bc 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -2073,6 +2073,16 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
 
   // Forward -f (flag) options which we can pass directly.
   Args.AddLastArg(CmdArgs, options::OPT_fcatch_undefined_behavior);
+  Args.AddLastArg(CmdArgs, options::OPT_fcatch_undefined_ansic_behavior);
+  Args.AddLastArg(CmdArgs, options::OPT_fcatch_undefined_c99_behavior);
+  Args.AddLastArg(CmdArgs, options::OPT_fcatch_undefined_cxx0x_behavior);
+  Args.AddLastArg(CmdArgs, options::OPT_fcatch_undefined_cxx98_behavior);
+  Args.AddLastArg(CmdArgs, options::OPT_fcatch_undefined_nonarith_behavior);
+  Args.AddLastArg(CmdArgs, options::OPT_fuse_intrinsic);
+  Args.AddLastArg(CmdArgs, options::OPT_fuse_random_value);
+  Args.AddLastArg(CmdArgs, options::OPT_fhandler_null);
+  Args.AddLastArg(CmdArgs, options::OPT_fchecks_num);
+  Args.AddLastArg(CmdArgs, options::OPT_fcatch_non_ubc_type);
   Args.AddLastArg(CmdArgs, options::OPT_femit_all_decls);
   Args.AddLastArg(CmdArgs, options::OPT_fheinous_gnu_extensions);
   Args.AddLastArg(CmdArgs, options::OPT_flimit_debug_info);
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 4c5b063..c766556 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -666,6 +666,26 @@ static void LangOptsToArgs(const LangOptions &Opts, ToArgsList &Res) {
     Res.push_back("-fcatch-undefined-behavior");
   if (Opts.AddressSanitizer)
     Res.push_back("-faddress-sanitizer");
+  if (Opts.CatchUndefinedAnsiC)
+    Res.push_back("-fcatch-undefined-ansic-behavior");
+  if (Opts.CatchUndefinedC99)
+    Res.push_back("-fcatch-undefined-c99-behavior");
+  if (Opts.CatchUndefinedCXX0X)
+    Res.push_back("-fcatch-undefined-cxx0x-behavior");
+  if (Opts.CatchUndefinedCXX98)
+    Res.push_back("-fcatch-undefined-cxx98-behavior");
+  if (Opts.CatchNonArithUndefined)
+    Res.push_back("-fcatch-undefined-nonarith-behavior");
+  if (Opts.UseIntrinsic)
+    Res.push_back("-fuse-intrinsic");
+  if (Opts.UseRandomValue)
+    Res.push_back("-fuse-random-value");
+  if (Opts.HandlerNull)
+    Res.push_back("-fhandler-null");
+  if (Opts.ChecksNum)
+    Res.push_back("-fchecks-num");
+  if (Opts.CatchNonUBCType)
+    Res.push_back("-fcatch-non-ubc-type");
   if (Opts.ThreadSanitizer)
     Res.push_back("-fthread-sanitizer");
   if (Opts.WritableStrings)
@@ -1893,6 +1913,16 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
   Opts.ObjCDefaultSynthProperties =
     Args.hasArg(OPT_fobjc_default_synthesize_properties);
   Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior);
+  Opts.CatchUndefinedAnsiC = Args.hasArg(OPT_fcatch_undefined_ansic_behavior);
+  Opts.CatchUndefinedC99 = Args.hasArg(OPT_fcatch_undefined_c99_behavior);
+  Opts.CatchUndefinedCXX0X = Args.hasArg(OPT_fcatch_undefined_cxx0x_behavior);
+  Opts.CatchUndefinedCXX98 = Args.hasArg(OPT_fcatch_undefined_cxx98_behavior);
+  Opts.CatchNonArithUndefined = Args.hasArg(OPT_fcatch_undefined_nonarith_behavior);
+  Opts.UseIntrinsic = Args.hasArg(OPT_fuse_intrinsic);
+  Opts.UseRandomValue = Args.hasArg(OPT_fuse_random_value);
+  Opts.HandlerNull = Args.hasArg(OPT_fhandler_null);
+  Opts.ChecksNum = Args.hasArg(OPT_fchecks_num);
+  Opts.CatchNonUBCType = Args.hasArg(OPT_fcatch_non_ubc_type);
   Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
   Opts.PackStruct = Args.getLastArgIntValue(OPT_fpack_struct, 0, Diags);
   Opts.PICLevel = Args.getLastArgIntValue(OPT_pic_level, 0, Diags);
-- 
1.7.10

