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