summaryrefslogtreecommitdiff
path: root/clang/test/CXX/expr/expr.prim/expr.prim.general
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test/CXX/expr/expr.prim/expr.prim.general')
-rw-r--r--clang/test/CXX/expr/expr.prim/expr.prim.general/p12-0x.cpp38
-rw-r--r--clang/test/CXX/expr/expr.prim/expr.prim.general/p3-0x.cpp101
-rw-r--r--clang/test/CXX/expr/expr.prim/expr.prim.general/p4-0x.cpp20
-rw-r--r--clang/test/CXX/expr/expr.prim/expr.prim.general/p8-0x.cpp78
4 files changed, 237 insertions, 0 deletions
diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.general/p12-0x.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.general/p12-0x.cpp
new file mode 100644
index 0000000..249c976
--- /dev/null
+++ b/clang/test/CXX/expr/expr.prim/expr.prim.general/p12-0x.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+struct S {
+ int *j = &nonexistent; // expected-error {{use of undeclared identifier 'nonexistent'}}
+ int *m = &n; // ok
+
+ int n = f(); // ok
+ int f();
+};
+
+int i = sizeof(S::m); // ok
+int j = sizeof(S::m + 42); // ok
+
+
+struct T {
+ int n;
+ static void f() {
+ int a[n]; // expected-error {{invalid use of member 'n' in static member function}}
+ int b[sizeof n]; // ok
+ }
+};
+
+// Make sure the rule for unevaluated operands works correctly with typeid.
+namespace std {
+ class type_info;
+}
+class Poly { virtual ~Poly(); };
+const std::type_info& k = typeid(S::m);
+const std::type_info& m = typeid(*(Poly*)S::m); // expected-error {{invalid use of non-static data member}}
+const std::type_info& n = typeid(*(Poly*)(0*sizeof S::m));
+
+namespace PR11956 {
+ struct X { char a; };
+ struct Y { int f() { return sizeof(X::a); } }; // ok
+
+ struct A { enum E {} E; };
+ struct B { int f() { return sizeof(A::E); } }; // ok
+}
diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.general/p3-0x.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.general/p3-0x.cpp
new file mode 100644
index 0000000..030c90c
--- /dev/null
+++ b/clang/test/CXX/expr/expr.prim/expr.prim.general/p3-0x.cpp
@@ -0,0 +1,101 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify
+
+struct A {
+ int &f(int*);
+ float &f(int*) const noexcept;
+
+ int *ptr;
+ auto g1() noexcept(noexcept(f(ptr))) -> decltype(f(this->ptr));
+ auto g2() const noexcept(noexcept(f((*this).ptr))) -> decltype(f(ptr));
+};
+
+void testA(A &a) {
+ int &ir = a.g1();
+ float &fr = a.g2();
+ static_assert(!noexcept(a.g1()), "exception-specification failure");
+ static_assert(noexcept(a.g2()), "exception-specification failure");
+}
+
+struct B {
+ char g();
+ template<class T> auto f(T t) -> decltype(t + g())
+ { return t + g(); }
+};
+
+template auto B::f(int t) -> decltype(t + g());
+
+template<typename T>
+struct C {
+ int &f(T*);
+ float &f(T*) const noexcept;
+
+ T* ptr;
+ auto g1() noexcept(noexcept(f(ptr))) -> decltype(f((*this).ptr));
+ auto g2() const noexcept(noexcept(f(((this))->ptr))) -> decltype(f(ptr));
+};
+
+void test_C(C<int> ci) {
+ int *p = 0;
+ int &ir = ci.g1();
+ float &fr = ci.g2();
+ static_assert(!noexcept(ci.g1()), "exception-specification failure");
+ static_assert(noexcept(ci.g2()), "exception-specification failure");
+}
+
+namespace PR10036 {
+ template <class I>
+ void
+ iter_swap(I x, I y) noexcept;
+
+ template <class T>
+ class A
+ {
+ T t_;
+ public:
+ void swap(A& a) noexcept(noexcept(iter_swap(&t_, &a.t_)));
+ };
+
+ void test() {
+ A<int> i, j;
+ i.swap(j);
+ }
+}
+
+namespace Static {
+ struct X1 {
+ int m;
+ static auto f() -> decltype(m); // expected-error{{'this' cannot be implicitly used in a static member function declaration}}
+ static auto g() -> decltype(this->m); // expected-error{{'this' cannot be used in a static member function declaration}}
+
+ static int h();
+
+ static int i() noexcept(noexcept(m + 2)); // expected-error{{'this' cannot be implicitly used in a static member function declaration}}
+ };
+
+ auto X1::h() -> decltype(m) { return 0; } // expected-error{{'this' cannot be implicitly used in a static member function declaration}}
+
+ template<typename T>
+ struct X2 {
+ int m;
+
+ T f(T*);
+ static T f(int);
+
+ auto g(T x) -> decltype(f(x)) { return 0; }
+ };
+
+ void test_X2() {
+ X2<int>().g(0);
+ }
+}
+
+namespace PR12564 {
+ struct Base {
+ void bar(Base&) {} // unexpected-note {{here}}
+ };
+
+ struct Derived : Base {
+ // FIXME: This should be accepted.
+ void foo(Derived& d) noexcept(noexcept(d.bar(d))) {} // unexpected-error {{cannot bind to a value of unrelated type}}
+ };
+}
diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.general/p4-0x.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.general/p4-0x.cpp
new file mode 100644
index 0000000..4e57b74
--- /dev/null
+++ b/clang/test/CXX/expr/expr.prim/expr.prim.general/p4-0x.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+struct S {
+ S *p = this; // ok
+ decltype(this) q; // expected-error {{invalid use of 'this' outside of a non-static member function}}
+
+ int arr[sizeof(this)]; // expected-error {{invalid use of 'this' outside of a non-static member function}}
+ int sz = sizeof(this); // ok
+};
+
+namespace CaptureThis {
+ struct X {
+ int n = 10;
+ int m = [&]{return n + 1; }();
+ int o = [&]{return this->m + 1; }();
+ int p = [&]{return [&](int x) { return this->m + x;}(o); }();
+ };
+
+ X x;
+}
diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.general/p8-0x.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.general/p8-0x.cpp
new file mode 100644
index 0000000..5b3a004
--- /dev/null
+++ b/clang/test/CXX/expr/expr.prim/expr.prim.general/p8-0x.cpp
@@ -0,0 +1,78 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+struct global {
+};
+
+namespace PR10127 {
+ struct outer {
+ struct middle {
+ struct inner {
+ int func();
+ int i;
+ };
+ struct inner2 {
+ };
+ struct inner3 {
+ };
+ int mfunc();
+ };
+ typedef int td_int;
+ };
+
+ struct str {
+ operator decltype(outer::middle::inner()) ();
+ operator decltype(outer::middle())::inner2 ();
+ operator decltype(outer())::middle::inner3 ();
+ str(int (decltype(outer::middle::inner())::*n)(),
+ int (decltype(outer::middle())::inner::*o)(),
+ int (decltype(outer())::middle::inner::*p)());
+ };
+
+ decltype(outer::middle::inner()) a;
+ void scope() {
+ a.decltype(outer::middle())::mfunc(); // expected-error{{'PR10127::outer::middle::mfunc' is not a member of class 'decltype(outer::middle::inner())'}}
+ a.decltype(outer::middle::inner())::func();
+ a.decltype(outer::middle())::inner::func();
+ a.decltype(outer())::middle::inner::func();
+
+ a.decltype(outer())::middle::inner::~inner();
+
+ decltype(outer())::middle::inner().func();
+ }
+ decltype(outer::middle())::inner b;
+ decltype(outer())::middle::inner c;
+ decltype(outer())::fail d; // expected-error{{no type named 'fail' in 'PR10127::outer'}}
+ decltype(outer())::fail::inner e; // expected-error{{no member named 'fail' in 'PR10127::outer'}}
+ decltype()::fail f; // expected-error{{expected expression}}
+ decltype()::middle::fail g; // expected-error{{expected expression}}
+
+ decltype(int()) h;
+ decltype(int())::PR10127::outer i; // expected-error{{'decltype(int())' (aka 'int') is not a class, namespace, or scoped enumeration}}
+ decltype(int())::global j; // expected-error{{'decltype(int())' (aka 'int') is not a class, namespace, or scoped enumeration}}
+
+ outer::middle k = decltype(outer())::middle();
+ outer::middle::inner l = decltype(outer())::middle::inner();
+
+ template<typename T>
+ struct templ {
+ typename decltype(T())::middle::inner x; // expected-error{{type 'decltype(int())' (aka 'int') cannot be used prior to '::' because it has no members}}
+ };
+
+ template class templ<int>; // expected-note{{in instantiation of template class 'PR10127::templ<int>' requested here}}
+ template class templ<outer>;
+
+ enum class foo {
+ bar,
+ baz
+ };
+
+ foo m = decltype(foo::bar)::baz;
+
+ enum E {
+ };
+ struct bar {
+ enum E : decltype(outer())::td_int(4);
+ enum F : decltype(outer())::td_int;
+ enum G : decltype; // expected-error{{expected '(' after 'decltype'}}
+ };
+}