diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-05-05 23:31:59 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-05-05 23:31:59 +0000 |
commit | 5528ac9f40ec6cb54e7096908bf2beeed511bce4 (patch) | |
tree | fcdc39987b01a3338d6012a828133ceabffae09d /test | |
parent | b476a14e9b35ef2448b42b033e1f0cceaa3f2778 (diff) |
C++1y: support for increment and decrement in constant expression evaluation.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@181173 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test')
-rw-r--r-- | test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp | 2 | ||||
-rw-r--r-- | test/SemaCXX/constant-expression-cxx1y.cpp | 80 |
2 files changed, 74 insertions, 8 deletions
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp index e12011d19c..3bc639dd57 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp @@ -277,7 +277,7 @@ namespace std_example { constexpr int prev(int x) { return --x; } -#if 1 // FIXME: !defined CXX1Y +#ifndef CXX1Y // expected-error@-4 {{never produces a constant expression}} // expected-note@-4 {{subexpression}} #endif diff --git a/test/SemaCXX/constant-expression-cxx1y.cpp b/test/SemaCXX/constant-expression-cxx1y.cpp index 62739ee8c1..2dfded4cc3 100644 --- a/test/SemaCXX/constant-expression-cxx1y.cpp +++ b/test/SemaCXX/constant-expression-cxx1y.cpp @@ -161,11 +161,9 @@ namespace string_assign { swap(*begin++, *end); #else if (begin != end) { - end = end - 1; - if (begin == end) + if (begin == --end) return; - swap(*begin, *end); - begin = begin + 1; + swap(*begin++, *end); reverse(begin, end); } #endif @@ -180,10 +178,8 @@ namespace string_assign { } #else if (a != ae && b != be) { - if (*a != *b) + if (*a++ != *b++) return false; - a = a + 1; - b = b + 1; return equal(a, ae, b, be); } #endif @@ -286,3 +282,73 @@ namespace null { } static_assert(test(0), ""); // expected-error {{constant expression}} expected-note {{in call}} } + +namespace incdec { + template<typename T> constexpr T &ref(T &&r) { return r; } + template<typename T> constexpr T postinc(T &&r) { return (r++, r); } + template<typename T> constexpr T postdec(T &&r) { return (r--, r); } + + static_assert(++ref(0) == 1, ""); + static_assert(ref(0)++ == 0, ""); + static_assert(postinc(0) == 1, ""); + static_assert(--ref(0) == -1, ""); + static_assert(ref(0)-- == 0, ""); + static_assert(postdec(0) == -1, ""); + + constexpr int overflow_int_inc_1 = ref(0x7fffffff)++; // expected-error {{constant}} expected-note {{2147483648}} + constexpr int overflow_int_inc_1_ok = ref(0x7ffffffe)++; + constexpr int overflow_int_inc_2 = ++ref(0x7fffffff); // expected-error {{constant}} expected-note {{2147483648}} + constexpr int overflow_int_inc_2_ok = ++ref(0x7ffffffe); + + // inc/dec on short can't overflow because we promote to int first + static_assert(++ref<short>(0x7fff) == (int)0xffff8000u, ""); + static_assert(--ref<short>(0x8000) == 0x7fff, ""); + + // inc on bool sets to true + static_assert(++ref(false), ""); // expected-warning {{deprecated}} + static_assert(++ref(true), ""); // expected-warning {{deprecated}} + + int arr[10]; + static_assert(++ref(&arr[0]) == &arr[1], ""); + static_assert(++ref(&arr[9]) == &arr[10], ""); + static_assert(++ref(&arr[10]) == &arr[11], ""); // expected-error {{constant}} expected-note {{cannot refer to element 11}} + static_assert(ref(&arr[0])++ == &arr[0], ""); + static_assert(ref(&arr[10])++ == &arr[10], ""); // expected-error {{constant}} expected-note {{cannot refer to element 11}} + static_assert(postinc(&arr[0]) == &arr[1], ""); + static_assert(--ref(&arr[10]) == &arr[9], ""); + static_assert(--ref(&arr[1]) == &arr[0], ""); + static_assert(--ref(&arr[0]) != &arr[0], ""); // expected-error {{constant}} expected-note {{cannot refer to element -1}} + static_assert(ref(&arr[1])-- == &arr[1], ""); + static_assert(ref(&arr[0])-- == &arr[0], ""); // expected-error {{constant}} expected-note {{cannot refer to element -1}} + static_assert(postdec(&arr[1]) == &arr[0], ""); + + int x; + static_assert(++ref(&x) == &x + 1, ""); + + static_assert(++ref(0.0) == 1.0, ""); + static_assert(ref(0.0)++ == 0.0, ""); + static_assert(postinc(0.0) == 1.0, ""); + static_assert(--ref(0.0) == -1.0, ""); + static_assert(ref(0.0)-- == 0.0, ""); + static_assert(postdec(0.0) == -1.0, ""); + + static_assert(++ref(1e100) == 1e100, ""); + static_assert(--ref(1e100) == 1e100, ""); + + union U { + int a, b; + }; + constexpr int f(U u) { + return ++u.b; // expected-note {{increment of member 'b' of union with active member 'a'}} + } + constexpr int wrong_member = f({0}); // expected-error {{constant}} expected-note {{in call to 'f({.a = 0})'}} + constexpr int vol = --ref<volatile int>(0); // expected-error {{constant}} expected-note {{decrement of volatile-qualified}} + + constexpr int incr(int k) { + int x = k; + if (x++ == 100) + return x; + return incr(x); + } + static_assert(incr(0) == 101, ""); +} |