summaryrefslogtreecommitdiffstats
path: root/test/SemaCXX/constant-expression-cxx11.cpp
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2012-12-02 13:20:44 +0000
committerdim <dim@FreeBSD.org>2012-12-02 13:20:44 +0000
commit056abd2059c65a3e908193aeae16fad98017437c (patch)
tree2732d02d7d51218d6eed98ac7fcfc5b8794896b5 /test/SemaCXX/constant-expression-cxx11.cpp
parentcc73504950eb7b5dff2dded9bedd67bc36d64641 (diff)
downloadFreeBSD-src-056abd2059c65a3e908193aeae16fad98017437c.zip
FreeBSD-src-056abd2059c65a3e908193aeae16fad98017437c.tar.gz
Vendor import of clang release_32 branch r168974 (effectively, 3.2 RC2):
http://llvm.org/svn/llvm-project/cfe/branches/release_32@168974
Diffstat (limited to 'test/SemaCXX/constant-expression-cxx11.cpp')
-rw-r--r--test/SemaCXX/constant-expression-cxx11.cpp83
1 files changed, 82 insertions, 1 deletions
diff --git a/test/SemaCXX/constant-expression-cxx11.cpp b/test/SemaCXX/constant-expression-cxx11.cpp
index a3ead79..f504eb6 100644
--- a/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/test/SemaCXX/constant-expression-cxx11.cpp
@@ -521,12 +521,18 @@ namespace DependentValues {
struct I { int n; typedef I V[10]; };
I::V x, y;
-template<bool B> struct S {
+int g();
+template<bool B, typename T> struct S : T {
int k;
void f() {
I::V &cells = B ? x : y;
I &i = cells[k];
switch (i.n) {}
+
+ // FIXME: We should be able to diagnose this.
+ constexpr int n = g();
+
+ constexpr int m = this->g(); // ok, could be constexpr
}
};
@@ -741,6 +747,15 @@ constexpr bool check(T a, T b) { return a == b.k; }
static_assert(S(5) == 11, "");
static_assert(check(S(5), 11), "");
+namespace PR14171 {
+
+struct X {
+ constexpr (operator int)() { return 0; }
+};
+static_assert(X() == 0, "");
+
+}
+
}
}
@@ -1374,3 +1389,69 @@ namespace ConditionalLValToRVal {
constexpr A a(4);
static_assert(f(a).v == 4, "");
}
+
+namespace TLS {
+ __thread int n;
+ int m;
+
+ constexpr bool b = &n == &n;
+
+ constexpr int *p = &n; // expected-error{{constexpr variable 'p' must be initialized by a constant expression}}
+
+ constexpr int *f() { return &n; }
+ constexpr int *q = f(); // expected-error{{constexpr variable 'q' must be initialized by a constant expression}}
+ constexpr bool c = f() == f();
+
+ constexpr int *g() { return &m; }
+ constexpr int *r = g();
+}
+
+namespace Void {
+ constexpr void f() { return; } // expected-error{{constexpr function's return type 'void' is not a literal type}}
+
+ void assert_failed(const char *msg, const char *file, int line); // expected-note {{declared here}}
+#define ASSERT(expr) ((expr) ? static_cast<void>(0) : assert_failed(#expr, __FILE__, __LINE__))
+ template<typename T, size_t S>
+ constexpr T get(T (&a)[S], size_t k) {
+ return ASSERT(k > 0 && k < S), a[k]; // expected-note{{non-constexpr function 'assert_failed'}}
+ }
+#undef ASSERT
+ template int get(int (&a)[4], size_t);
+ constexpr int arr[] = { 4, 1, 2, 3, 4 };
+ static_assert(get(arr, 1) == 1, "");
+ static_assert(get(arr, 4) == 4, "");
+ static_assert(get(arr, 0) == 4, ""); // expected-error{{not an integral constant expression}} \
+ // expected-note{{in call to 'get(arr, 0)'}}
+}
+
+namespace std { struct type_info; }
+
+namespace TypeId {
+ struct A { virtual ~A(); };
+ A f();
+ A &g();
+ constexpr auto &x = typeid(f());
+ constexpr auto &y = typeid(g()); // expected-error{{constant expression}} \
+ // expected-note{{typeid applied to expression of polymorphic type 'TypeId::A' is not allowed in a constant expression}}
+}
+
+namespace PR14203 {
+ struct duration {
+ constexpr duration() {}
+ constexpr operator int() const { return 0; }
+ };
+ template<typename T> void f() {
+ // If we want to evaluate this at the point of the template definition, we
+ // need to trigger the implicit definition of the move constructor at that
+ // point.
+ // FIXME: C++ does not permit us to implicitly define it at the appropriate
+ // times, since it is only allowed to be implicitly defined when it is
+ // odr-used.
+ constexpr duration d = duration();
+ }
+ // FIXME: It's unclear whether this is valid. On the one hand, we're not
+ // allowed to generate a move constructor. On the other hand, if we did,
+ // this would be a constant expression. For now, we generate a move
+ // constructor here.
+ int n = sizeof(short{duration(duration())});
+}
OpenPOWER on IntegriCloud