aboutsummaryrefslogtreecommitdiff
path: root/clang/test/AST/ByteCode
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test/AST/ByteCode')
-rw-r--r--clang/test/AST/ByteCode/builtin-constant-p.cpp6
-rw-r--r--clang/test/AST/ByteCode/builtin-functions.cpp28
-rw-r--r--clang/test/AST/ByteCode/cxx2a.cpp60
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());
+}