aboutsummaryrefslogtreecommitdiff
path: root/test/CXX/expr/expr.const/p2-0x.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2012-02-01 08:10:20 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2012-02-01 08:10:20 +0000
commit15efc4d597a47e6ba5794d4fd8d561bf6947233c (patch)
treef2e85b5cbf295eb13d69dc66f47805230c83ec76 /test/CXX/expr/expr.const/p2-0x.cpp
parentab14ae2ab16088b6a7f69eac6e152c3e9f9ea01b (diff)
constexpr: check for overflow in pointer subtraction.
This is a mess. According to the C++11 standard, pointer subtraction only has undefined behavior if the difference of the array indices does not fit into a ptrdiff_t. However, common implementations effectively perform a char* subtraction first, and then divide the result by the element size, which can cause overflows in some cases. Those cases are not considered to be undefined behavior by this change; perhaps they should be. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@149490 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CXX/expr/expr.const/p2-0x.cpp')
-rw-r--r--test/CXX/expr/expr.const/p2-0x.cpp10
1 files changed, 9 insertions, 1 deletions
diff --git a/test/CXX/expr/expr.const/p2-0x.cpp b/test/CXX/expr/expr.const/p2-0x.cpp
index 857f02960f..8e68b9a0fb 100644
--- a/test/CXX/expr/expr.const/p2-0x.cpp
+++ b/test/CXX/expr/expr.const/p2-0x.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -std=c++11 -pedantic -verify -fcxx-exceptions %s -fconstexpr-depth 128
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -pedantic -verify -fcxx-exceptions %s -fconstexpr-depth 128 -triple i686-pc-linux-gnu
// A conditional-expression is a core constant expression unless it involves one
// of the following as a potentially evaluated subexpression [...]:
@@ -222,6 +222,14 @@ namespace UndefinedBehavior {
constexpr long long ll4 = ll3 - 1; // expected-error {{constant}} expected-note {{ -9223372036854775809 }}
constexpr long long ll5 = ll3 * ll3; // expected-error {{constant}} expected-note {{ 85070591730234615865843651857942052864 }}
+ // Yikes.
+ char melchizedek[2200000000];
+ typedef decltype(melchizedek[1] - melchizedek[0]) ptrdiff_t;
+ constexpr ptrdiff_t d1 = &melchizedek[0x7fffffff] - &melchizedek[0]; // ok
+ constexpr ptrdiff_t d2 = &melchizedek[0x80000000u] - &melchizedek[0]; // expected-error {{constant expression}} expected-note {{ 2147483648 }}
+ constexpr ptrdiff_t d3 = &melchizedek[0] - &melchizedek[0x80000000u]; // ok
+ constexpr ptrdiff_t d4 = &melchizedek[0] - &melchizedek[0x80000001u]; // expected-error {{constant expression}} expected-note {{ -2147483649 }}
+
// Unsigned int overflow.
static_assert(65536u * 65536u == 0u, ""); // ok
static_assert(4294967295u + 1u == 0u, ""); // ok