]> granicus.if.org Git - clang/commitdiff
Left shifts of negative values are defined if -fwrapv is set
authorJames Molloy <james.molloy@arm.com>
Tue, 16 Aug 2016 09:45:36 +0000 (09:45 +0000)
committerJames Molloy <james.molloy@arm.com>
Tue, 16 Aug 2016 09:45:36 +0000 (09:45 +0000)
This means we shouldn't emit ubsan detection code or warn.
Fixes PR25552.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@278786 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGExprScalar.cpp
lib/Sema/SemaExpr.cpp
test/CodeGen/wrapv-lshr-sanitize.c [new file with mode: 0644]
test/Sema/negative-shift-wrapv.c [new file with mode: 0644]

index f3936873359258f8dc21b61a194e4c3a21403da2..700b5374ad9da344ccd6f986869e5481c88a6c70 100644 (file)
@@ -2714,7 +2714,8 @@ Value *ScalarExprEmitter::EmitShl(const BinOpInfo &Ops) {
     RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(), false, "sh_prom");
 
   bool SanitizeBase = CGF.SanOpts.has(SanitizerKind::ShiftBase) &&
-                      Ops.Ty->hasSignedIntegerRepresentation();
+                      Ops.Ty->hasSignedIntegerRepresentation() &&
+                      !CGF.getLangOpts().isSignedOverflowDefined();
   bool SanitizeExponent = CGF.SanOpts.has(SanitizerKind::ShiftExponent);
   // OpenCL 6.3j: shift values are effectively % word size of LHS.
   if (CGF.getLangOpts().OpenCL)
index 78fa995e256e72020ab92f83ff626d0652daf606..41c8a4c52a1b8fe0063b291e709dccaec8ab5c83 100644 (file)
@@ -8670,7 +8670,7 @@ static void DiagnoseBadShiftValues(Sema& S, ExprResult &LHS, ExprResult &RHS,
 
   // If LHS does not have a signed type and non-negative value
   // then, the behavior is undefined. Warn about it.
-  if (Left.isNegative()) {
+  if (Left.isNegative() && !S.getLangOpts().isSignedOverflowDefined()) {
     S.DiagRuntimeBehavior(Loc, LHS.get(),
                           S.PDiag(diag::warn_shift_lhs_negative)
                             << LHS.get()->getSourceRange());
diff --git a/test/CodeGen/wrapv-lshr-sanitize.c b/test/CodeGen/wrapv-lshr-sanitize.c
new file mode 100644 (file)
index 0000000..c09dab7
--- /dev/null
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsanitize=shift-base -emit-llvm %s -o - -triple x86_64-linux-gnu -fwrapv | FileCheck %s
+
+// CHECK-LABEL: @lsh_overflow
+int lsh_overflow(int a, int b) {
+  // CHECK-NOT: br
+  // CHECK-NOT: call void @__ubsan_
+  // CHECK-NOT: call void @llvm.trap
+  
+  // CHECK:      %[[RET:.*]] = shl i32
+  // CHECK-NEXT: ret i32 %[[RET]]
+  return a << b;
+}
diff --git a/test/Sema/negative-shift-wrapv.c b/test/Sema/negative-shift-wrapv.c
new file mode 100644 (file)
index 0000000..b874820
--- /dev/null
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -Wall -ffreestanding -fsyntax-only -fwrapv -verify %s
+
+int test() {
+  int i;
+  i = -1 << 1; // no-warning
+  return i;
+}
+
+// expected-no-diagnostics