r228202 - Catch more cases when diagnosing integer-constant-expression overflows.

Josh Magee joshua_magee at playstation.sony.com
Wed Feb 4 13:50:20 PST 2015


Author: jmagee
Date: Wed Feb  4 15:50:20 2015
New Revision: 228202

URL: http://llvm.org/viewvc/llvm-project?rev=228202&view=rev
Log:
Catch more cases when diagnosing integer-constant-expression overflows.

When visiting AssignmentOps, keep evaluating after a failure (when possible) in
order to identify overflow in subexpressions.

Differential Revision: http://reviews.llvm.org/D1238

Added:
    cfe/trunk/test/Sema/integer-overflow.c
    cfe/trunk/test/SemaCXX/integer-overflow.cpp
Modified:
    cfe/trunk/lib/AST/ExprConstant.cpp
    cfe/trunk/test/Sema/complex-int.c

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=228202&r1=228201&r2=228202&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Wed Feb  4 15:50:20 2015
@@ -6834,7 +6834,7 @@ void DataRecursiveIntBinOpEvaluator::pro
 }
 
 bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
-  if (E->isAssignmentOp())
+  if (!Info.keepEvaluatingAfterFailure() && E->isAssignmentOp())
     return Error(E);
 
   if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(E))
@@ -6846,7 +6846,11 @@ bool IntExprEvaluator::VisitBinaryOperat
   if (LHSTy->isAnyComplexType() || RHSTy->isAnyComplexType()) {
     ComplexValue LHS, RHS;
     bool LHSOK;
-    if (E->getLHS()->getType()->isRealFloatingType()) {
+    if (E->isAssignmentOp()) {
+      LValue LV;
+      EvaluateLValue(E->getLHS(), LV, Info);
+      LHSOK = false;
+    } else if (LHSTy->isRealFloatingType()) {
       LHSOK = EvaluateFloat(E->getLHS(), LHS.FloatReal, Info);
       if (LHSOK) {
         LHS.makeComplexFloat();

Modified: cfe/trunk/test/Sema/complex-int.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/complex-int.c?rev=228202&r1=228201&r2=228202&view=diff
==============================================================================
--- cfe/trunk/test/Sema/complex-int.c (original)
+++ cfe/trunk/test/Sema/complex-int.c Wed Feb  4 15:50:20 2015
@@ -8,6 +8,8 @@ __complex__ signed yy;
 __complex__ int result;
 int ii;
 int aa = 1 + 1.0iF;
+int bb = 0;
+bb += 1i;
 
 result = arr*ii;
 result = ii*brr;

Added: cfe/trunk/test/Sema/integer-overflow.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/integer-overflow.c?rev=228202&view=auto
==============================================================================
--- cfe/trunk/test/Sema/integer-overflow.c (added)
+++ cfe/trunk/test/Sema/integer-overflow.c Wed Feb  4 15:50:20 2015
@@ -0,0 +1,147 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+typedef unsigned long long uint64_t;
+typedef unsigned long long uint32_t;
+
+uint64_t f0(uint64_t);
+uint64_t f1(uint64_t, uint32_t);
+uint64_t f2(uint64_t, ...);
+
+static const uint64_t overflow = 1 * 4608 * 1024 * 1024; // expected-warning {{overflow in expression; result is 536870912 with type 'int'}}
+
+uint64_t check_integer_overflows(int i) {
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  uint64_t overflow = 4608 * 1024 * 1024,
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+           overflow2 = (uint64_t)(4608 * 1024 * 1024),
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+           overflow3 = (uint64_t)(4608 * 1024 * 1024 * i),
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+           overflow4 =  (1ULL * ((4608) * ((1024) * (1024))) + 2ULL),
+// expected-warning at +1 2{{overflow in expression; result is 536870912 with type 'int'}}
+           multi_overflow = (uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024));
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  overflow += overflow2 = overflow3 = (uint64_t)(4608 * 1024 * 1024);
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  overflow += overflow2 = overflow3 = 4608 * 1024 * 1024;
+
+  uint64_t not_overflow = 4608 * 1024 * 1024ULL;
+  uint64_t not_overflow2 = (1ULL * ((uint64_t)(4608) * (1024 * 1024)) + 2ULL);
+
+// expected-warning at +1 2{{overflow in expression; result is 536870912 with type 'int'}}
+  overflow = 4608 * 1024 * 1024 ?  4608 * 1024 * 1024 : 0;
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  overflow =  0 ? 0 : 4608 * 1024 * 1024;
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  if (4608 * 1024 * 1024)
+    return 0;
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  if ((uint64_t)(4608 * 1024 * 1024))
+    return 1;
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  if ((uint64_t)(4608 * 1024 * 1024))
+    return 2;
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  if ((uint64_t)(4608 * 1024 * 1024 * i))
+    return 3;
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  if ((1ULL * ((4608) * ((1024) * (1024))) + 2ULL))
+    return 4;
+
+// expected-warning at +1 2{{overflow in expression; result is 536870912 with type 'int'}}
+  if ((uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024)))
+    return 5;
+
+  switch (i) {
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  case 4608 * 1024 * 1024:
+    return 6;
+// expected-warning at +1 {{overflow in expression; result is 537919488 with type 'int'}}
+  case (uint64_t)(4609 * 1024 * 1024):
+    return 7;
+// expected-error at +1 {{expression is not an integer constant expression}}
+  case ((uint64_t)(4608 * 1024 * 1024 * i)):
+    return 8;
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  case ((1ULL * ((4608) * ((1024) * (1024))) + 2ULL)):
+    return 9;
+// expected-warning at +2 2{{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow converting case value to switch condition type (288230376151711744 to 0)}}
+  case ((uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024))):
+    return 10;
+  }
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  while (4608 * 1024 * 1024);
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  while ((uint64_t)(4608 * 1024 * 1024));
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  while ((uint64_t)(4608 * 1024 * 1024));
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  while ((uint64_t)(4608 * 1024 * 1024 * i));
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  while ((1ULL * ((4608) * ((1024) * (1024))) + 2ULL));
+
+// expected-warning at +1 2{{overflow in expression; result is 536870912 with type 'int'}}
+  while ((uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024)));
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  do { } while (4608 * 1024 * 1024);
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  do { } while ((uint64_t)(4608 * 1024 * 1024));
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  do { } while ((uint64_t)(4608 * 1024 * 1024));
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  do { } while ((uint64_t)(4608 * 1024 * 1024 * i));
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  do { } while ((1ULL * ((4608) * ((1024) * (1024))) + 2ULL));
+
+// expected-warning at +1 2{{overflow in expression; result is 536870912 with type 'int'}}
+  do { } while ((uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024)));
+
+// expected-warning at +3 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +3 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +3 {{overflow in expression; result is 536870912 with type 'int'}}
+  for (uint64_t i = 4608 * 1024 * 1024;
+       (uint64_t)(4608 * 1024 * 1024);
+       i += (uint64_t)(4608 * 1024 * 1024 * i));
+
+// expected-warning at +3 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +3 2{{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +3 2{{overflow in expression; result is 536870912 with type 'int'}}
+  for (uint64_t i = (1ULL * ((4608) * ((1024) * (1024))) + 2ULL);
+       ((uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024)));
+       i = ((4608 * 1024 * 1024) + ((uint64_t)(4608 * 1024 * 1024))));
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  _Complex long long x = 4608 * 1024 * 1024;
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  (__real__ x) = 4608 * 1024 * 1024;
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  (__imag__ x) = 4608 * 1024 * 1024;
+
+// expected-warning at +4 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +3 {{array index 536870912 is past the end of the array (which contains 10 elements)}}
+// expected-note at +1 {{array 'a' declared here}}
+  uint64_t a[10];
+  a[4608 * 1024 * 1024] = 1i;
+
+// expected-warning at +1 2{{overflow in expression; result is 536870912 with type 'int'}}
+  return ((4608 * 1024 * 1024) + ((uint64_t)(4608 * 1024 * 1024)));
+}

Added: cfe/trunk/test/SemaCXX/integer-overflow.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/integer-overflow.cpp?rev=228202&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/integer-overflow.cpp (added)
+++ cfe/trunk/test/SemaCXX/integer-overflow.cpp Wed Feb  4 15:50:20 2015
@@ -0,0 +1,166 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only -std=gnu++98
+typedef unsigned long long uint64_t;
+typedef unsigned long long uint32_t;
+
+uint64_t f0(uint64_t);
+uint64_t f1(uint64_t, uint32_t);
+uint64_t f2(uint64_t, ...);
+
+static const uint64_t overflow = 1 * 4608 * 1024 * 1024; // expected-warning {{overflow in expression; result is 536870912 with type 'int'}}
+
+uint64_t check_integer_overflows(int i) { //expected-note {{declared here}}
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  uint64_t overflow = 4608 * 1024 * 1024,
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+           overflow2 = (uint64_t)(4608 * 1024 * 1024),
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+           overflow3 = (uint64_t)(4608 * 1024 * 1024 * i),
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+           overflow4 =  (1ULL * ((4608) * ((1024) * (1024))) + 2ULL),
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+           overflow5 = static_cast<uint64_t>(4608 * 1024 * 1024),
+// expected-warning at +1 2{{overflow in expression; result is 536870912 with type 'int'}}
+           multi_overflow = (uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024));
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  overflow += overflow2 = overflow3 = (uint64_t)(4608 * 1024 * 1024);
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  overflow += overflow2 = overflow3 = 4608 * 1024 * 1024;
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  overflow += overflow2 = overflow3 = static_cast<uint64_t>(4608 * 1024 * 1024);
+
+  uint64_t not_overflow = 4608 * 1024 * 1024ULL;
+  uint64_t not_overflow2 = (1ULL * ((uint64_t)(4608) * (1024 * 1024)) + 2ULL);
+
+// expected-warning at +1 2{{overflow in expression; result is 536870912 with type 'int'}}
+  overflow = 4608 * 1024 * 1024 ?  4608 * 1024 * 1024 : 0;
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  overflow =  0 ? 0 : 4608 * 1024 * 1024;
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  if (4608 * 1024 * 1024)
+    return 0;
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  if ((uint64_t)(4608 * 1024 * 1024))
+    return 1;
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  if (static_cast<uint64_t>(4608 * 1024 * 1024))
+    return 1;
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  if ((uint64_t)(4608 * 1024 * 1024))
+    return 2;
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  if ((uint64_t)(4608 * 1024 * 1024 * i))
+    return 3;
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  if ((1ULL * ((4608) * ((1024) * (1024))) + 2ULL))
+    return 4;
+
+// expected-warning at +1 2{{overflow in expression; result is 536870912 with type 'int'}}
+  if ((uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024)))
+    return 5;
+
+  switch (i) {
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  case 4608 * 1024 * 1024:
+    return 6;
+// expected-warning at +1 {{overflow in expression; result is 537919488 with type 'int'}}
+  case (uint64_t)(4609 * 1024 * 1024):
+    return 7;
+// expected-warning at +1 {{overflow in expression; result is 537919488 with type 'int'}}
+  case 1 + static_cast<uint64_t>(4609 * 1024 * 1024):
+    return 7;
+// expected-error at +2 {{expression is not an integral constant expression}}
+// expected-note at +1 {{read of non-const variable 'i' is not allowed in a constant expression}}
+  case ((uint64_t)(4608 * 1024 * 1024 * i)):
+    return 8;
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  case ((1ULL * ((4608) * ((1024) * (1024))) + 2ULL)):
+    return 9;
+// expected-warning at +2 2{{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow converting case value to switch condition type (288230376151711744 to 0)}}
+  case ((uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024))):
+    return 10;
+  }
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  while (4608 * 1024 * 1024);
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  while ((uint64_t)(4608 * 1024 * 1024));
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  while (static_cast<uint64_t>(4608 * 1024 * 1024));
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  while ((uint64_t)(4608 * 1024 * 1024));
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  while ((uint64_t)(4608 * 1024 * 1024 * i));
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  while ((1ULL * ((4608) * ((1024) * (1024))) + 2ULL));
+
+// expected-warning at +1 2{{overflow in expression; result is 536870912 with type 'int'}}
+  while ((uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024)));
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  do { } while (4608 * 1024 * 1024);
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  do { } while ((uint64_t)(4608 * 1024 * 1024));
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  do { } while (static_cast<uint64_t>(4608 * 1024 * 1024));
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  do { } while ((uint64_t)(4608 * 1024 * 1024));
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  do { } while ((uint64_t)(4608 * 1024 * 1024 * i));
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  do { } while ((1ULL * ((4608) * ((1024) * (1024))) + 2ULL));
+
+// expected-warning at +1 2{{overflow in expression; result is 536870912 with type 'int'}}
+  do { } while ((uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024)));
+
+// expected-warning at +3 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +3 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +3 {{overflow in expression; result is 536870912 with type 'int'}}
+  for (uint64_t i = 4608 * 1024 * 1024;
+       (uint64_t)(4608 * 1024 * 1024);
+       i += (uint64_t)(4608 * 1024 * 1024 * i));
+
+// expected-warning at +3 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +3 2{{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +3 2{{overflow in expression; result is 536870912 with type 'int'}}
+  for (uint64_t i = (1ULL * ((4608) * ((1024) * (1024))) + 2ULL);
+       ((uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024)));
+       i = ((4608 * 1024 * 1024) + ((uint64_t)(4608 * 1024 * 1024))));
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  _Complex long long x = 4608 * 1024 * 1024;
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  (__real__ x) = 4608 * 1024 * 1024;
+
+// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+  (__imag__ x) = 4608 * 1024 * 1024;
+
+// expected-warning at +4 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +3 {{array index 536870912 is past the end of the array (which contains 10 elements)}}
+// expected-note at +1 {{array 'a' declared here}}
+  uint64_t a[10];
+  a[4608 * 1024 * 1024] = 1i;
+
+// expected-warning at +1 2{{overflow in expression; result is 536870912 with type 'int'}}
+  return ((4608 * 1024 * 1024) + ((uint64_t)(4608 * 1024 * 1024)));
+}





More information about the cfe-commits mailing list