diff options
Diffstat (limited to 'clang/test/AST/ByteCode')
-rw-r--r-- | clang/test/AST/ByteCode/builtin-constant-p.cpp | 6 | ||||
-rw-r--r-- | clang/test/AST/ByteCode/builtin-functions.cpp | 28 | ||||
-rw-r--r-- | clang/test/AST/ByteCode/cxx2a.cpp | 60 |
3 files changed, 94 insertions, 0 deletions
diff --git a/clang/test/AST/ByteCode/builtin-constant-p.cpp b/clang/test/AST/ByteCode/builtin-constant-p.cpp index 0d222d1..62899b6 100644 --- a/clang/test/AST/ByteCode/builtin-constant-p.cpp +++ b/clang/test/AST/ByteCode/builtin-constant-p.cpp @@ -12,3 +12,9 @@ static_assert(__builtin_constant_p(I + 10.0), ""); static_assert(__builtin_constant_p(nullptr), ""); static_assert(__builtin_constant_p(&I), ""); // both-error {{failed due to requirement}} static_assert(__builtin_constant_p((void)I), ""); // both-error {{failed due to requirement}} + +extern int z; +constexpr int foo(int &a) { + return __builtin_constant_p(a); +} +static_assert(!foo(z)); diff --git a/clang/test/AST/ByteCode/builtin-functions.cpp b/clang/test/AST/ByteCode/builtin-functions.cpp index c1fd1bc..7237640 100644 --- a/clang/test/AST/ByteCode/builtin-functions.cpp +++ b/clang/test/AST/ByteCode/builtin-functions.cpp @@ -1244,6 +1244,34 @@ namespace BuiltinMemcpy { } static_assert(cpyptr()); +#ifndef __AVR__ + constexpr int test_memmove(int a, int b, int n) { + int arr[4] = {1, 2, 3, 4}; + __builtin_memmove(arr + a, arr + b, n); // both-note {{destination is not a contiguous array of at least 3 elements of type 'int'}} + return result(arr); + } + static_assert(test_memmove(2, 0, 12) == 4234); // both-error {{constant}} \ + // both-note {{in call}} +#endif + + struct Trivial { char k; short s; constexpr bool ok() { return k == 3 && s == 4; } }; + constexpr bool test_trivial() { + Trivial arr[3] = {{1, 2}, {3, 4}, {5, 6}}; + __builtin_memcpy(arr, arr+1, sizeof(Trivial)); + __builtin_memmove(arr+1, arr, 2 * sizeof(Trivial)); + + return arr[0].ok() && arr[1].ok() && arr[2].ok(); + } + static_assert(test_trivial()); + + // Check that an incomplete array is rejected. + constexpr int test_incomplete_array_type() { // both-error {{never produces a constant}} + extern int arr[]; + __builtin_memmove(arr, arr, 4 * sizeof(arr[0])); + // both-note@-1 2{{'memmove' not supported: source is not a contiguous array of at least 4 elements of type 'int'}} + return arr[0] * 1000 + arr[1] * 100 + arr[2] * 10 + arr[3]; + } + static_assert(test_incomplete_array_type() == 1234); // both-error {{constant}} both-note {{in call}} } namespace Memcmp { diff --git a/clang/test/AST/ByteCode/cxx2a.cpp b/clang/test/AST/ByteCode/cxx2a.cpp index eaae978..f600688 100644 --- a/clang/test/AST/ByteCode/cxx2a.cpp +++ b/clang/test/AST/ByteCode/cxx2a.cpp @@ -110,3 +110,63 @@ namespace DtorOrder { } static_assert(check_abnormal_termination()); } + +namespace std { + struct type_info; +} + +namespace TypeId { + struct A { + const std::type_info &ti = typeid(*this); + }; + struct A2 : A {}; + static_assert(&A().ti == &typeid(A)); + static_assert(&typeid((A2())) == &typeid(A2)); + extern A2 extern_a2; + static_assert(&typeid(extern_a2) == &typeid(A2)); + + constexpr A2 a2; + constexpr const A &a1 = a2; + static_assert(&typeid(a1) == &typeid(A)); + + struct B { + virtual void f(); + const std::type_info &ti1 = typeid(*this); + }; + struct B2 : B { + const std::type_info &ti2 = typeid(*this); + }; + static_assert(&B2().ti1 == &typeid(B)); + static_assert(&B2().ti2 == &typeid(B2)); + extern B2 extern_b2; + static_assert(&typeid(extern_b2) == &typeid(B2)); // both-error {{constant expression}} \ + // both-note{{typeid applied to object 'extern_b2' whose dynamic type is not constant}} + + + constexpr B2 b2; + constexpr const B &b1 = b2; + static_assert(&typeid(b1) == &typeid(B2)); + + constexpr bool side_effects() { + // Not polymorphic nor a glvalue. + bool OK = true; + (void)typeid(OK = false, A2()); // both-warning {{has no effect}} + if (!OK) return false; + + // Not polymorphic. + A2 a2; + (void)typeid(OK = false, a2); // both-warning {{has no effect}} + if (!OK) return false; + + // Not a glvalue. + (void)typeid(OK = false, B2()); // both-warning {{has no effect}} + if (!OK) return false; + + // Polymorphic glvalue: operand evaluated. + OK = false; + B2 b2; + (void)typeid(OK = true, b2); // both-warning {{will be evaluated}} + return OK; + } + static_assert(side_effects()); +} |