summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorJames Molloy <james.molloy@arm.com>2016-08-16 09:45:36 +0000
committerJames Molloy <james.molloy@arm.com>2016-08-16 09:45:36 +0000
commit59802321785b4b9fc31b10456c62ba3a06d3a631 (patch)
tree9972dd07f70520851b4bed007d4ee1a8f074ab42 /clang
parent5a123c4e37d9969a7c1a0d2b470db9330267817b (diff)
downloadbcm5719-llvm-59802321785b4b9fc31b10456c62ba3a06d3a631.tar.gz
bcm5719-llvm-59802321785b4b9fc31b10456c62ba3a06d3a631.zip
Left shifts of negative values are defined if -fwrapv is set
This means we shouldn't emit ubsan detection code or warn. Fixes PR25552. llvm-svn: 278786
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/CodeGen/CGExprScalar.cpp3
-rw-r--r--clang/lib/Sema/SemaExpr.cpp2
-rw-r--r--clang/test/CodeGen/wrapv-lshr-sanitize.c12
-rw-r--r--clang/test/Sema/negative-shift-wrapv.c9
4 files changed, 24 insertions, 2 deletions
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index f3936873359..700b5374ad9 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -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)
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 78fa995e256..41c8a4c52a1 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -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/clang/test/CodeGen/wrapv-lshr-sanitize.c b/clang/test/CodeGen/wrapv-lshr-sanitize.c
new file mode 100644
index 00000000000..c09dab7cf7b
--- /dev/null
+++ b/clang/test/CodeGen/wrapv-lshr-sanitize.c
@@ -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/clang/test/Sema/negative-shift-wrapv.c b/clang/test/Sema/negative-shift-wrapv.c
new file mode 100644
index 00000000000..b8748201ffc
--- /dev/null
+++ b/clang/test/Sema/negative-shift-wrapv.c
@@ -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
OpenPOWER on IntegriCloud