]> granicus.if.org Git - clang/commitdiff
fix inc/dec to honor -fwrapv and -ftrapv, implementing PR7426.
authorChris Lattner <sabre@nondot.org>
Sat, 26 Jun 2010 22:18:28 +0000 (22:18 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 26 Jun 2010 22:18:28 +0000 (22:18 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@106962 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGExprScalar.cpp
test/CodeGen/integer-overflow.c

index 63d14f0e53be61ba96bd4617a192191745a96a8a..208e1a6c8965fb75a13e6d1b6e2337fde7c7abf9 100644 (file)
@@ -1179,11 +1179,27 @@ EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
   } else if (isa<llvm::IntegerType>(InVal->getType())) {
     NextVal = llvm::ConstantInt::get(InVal->getType(), AmountVal);
     
-    // Signed integer overflow is undefined behavior.
-    if (ValTy->isSignedIntegerType())
-      NextVal = Builder.CreateNSWAdd(InVal, NextVal, isInc ? "inc" : "dec");
-    else
+    if (!ValTy->isSignedIntegerType())
+      // Unsigned integer inc is always two's complement.
       NextVal = Builder.CreateAdd(InVal, NextVal, isInc ? "inc" : "dec");
+    else {
+      switch (CGF.getContext().getLangOptions().getSignedOverflowBehavior()) {
+      case LangOptions::SOB_Undefined:
+        NextVal = Builder.CreateNSWAdd(InVal, NextVal, isInc ? "inc" : "dec");
+        break;
+      case LangOptions::SOB_Defined:
+        NextVal = Builder.CreateAdd(InVal, NextVal, isInc ? "inc" : "dec");
+        break;
+      case LangOptions::SOB_Trapping:
+        BinOpInfo BinOp;
+        BinOp.LHS = InVal;
+        BinOp.RHS = NextVal;
+        BinOp.Ty = E->getType();
+        BinOp.Opcode = BinaryOperator::Add;
+        BinOp.E = E;
+        return EmitOverflowCheckedBinOp(BinOp);
+      }
+    }
   } else {
     // Add the inc/dec to the real part.
     if (InVal->getType()->isFloatTy())
index dea3d0a1a3e4cb3708542e9b0a554ca0e9c0978c..9bed741b3236a59f53110b1ffedc63d690230624 100644 (file)
@@ -21,13 +21,25 @@ void test1() {
   // TRAPV: llvm.ssub.with.overflow.i32
   f11G = a - b;
   
-  // DEFAULT: sub nsw i32 0, 
-  // WRAPV: sub i32 0, 
-  // TRAPV: llvm.ssub.with.overflow.i32
-  f11G = -a;
-  
   // DEFAULT: mul nsw i32
   // WRAPV: mul i32
   // TRAPV: llvm.smul.with.overflow.i32
   f11G = a * b;
+
+  // DEFAULT: sub nsw i32 0, 
+  // WRAPV: sub i32 0, 
+  // TRAPV: llvm.ssub.with.overflow.i32(i32 0
+  f11G = -a;
+  
+  // PR7426 - Overflow checking for increments.
+  
+  // DEFAULT: add nsw i32 {{.*}}, 1
+  // WRAPV: add i32 {{.*}}, 1
+  // TRAPV: llvm.sadd.with.overflow.i32({{.*}}, i32 1)
+  ++a;
+  
+  // DEFAULT: add nsw i32 {{.*}}, -1
+  // WRAPV: add i32 {{.*}}, -1
+  // TRAPV: llvm.sadd.with.overflow.i32({{.*}}, i32 -1)
+  --a;
 }