xref: /llvm-project/clang/test/SemaCXX/decltype.cpp (revision 55ea36002bd364518c20b3ce282640c920697bf7)
1 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -Wno-c99-designator %s
2 
3 // PR5290
4 int const f0();
5 void f0_test() {
6   decltype(0, f0()) i = 0;
7   i = 0;
8 }
9 
10 struct A { int a[1]; A() { } };
11 typedef A const AC;
12 int &f1(int*);
13 float &f2(int const*);
14 
15 void test_f2() {
16   float &fr = f2(AC().a);
17 }
18 
19 template <class T>
20 struct Future {
21   explicit Future(T v);
22 
23   template <class F>
24   auto call(F&& fn) -> decltype(fn(T())) {
25     return fn(T());
26   }
27 
28   template <class B, class F>
29   auto then(F&& fn) -> decltype(call(fn))
30   {
31     return fn(T());
32   }
33 };
34 
35 void rdar16527205() {
36   Future<int> f1(42);
37   f1.call([](int){ return Future<float>(0); });
38 }
39 
40 namespace pr10154 {
41   class A{
42       A(decltype(nullptr) param);
43   };
44 }
45 
46 template<typename T> struct S {};
47 template<typename T> auto f(T t) -> decltype(S<int>(t)) {
48   using U = decltype(S<int>(t));
49   using U = S<int>;
50   return S<int>(t);
51 }
52 
53 struct B {
54   B(decltype(undeclared)); // expected-error {{undeclared identifier}}
55 };
56 struct C {
57   C(decltype(undeclared; // expected-error {{undeclared identifier}} \
58                          // expected-error {{expected ')'}} expected-note {{to match this '('}}
59 };
60 
61 namespace PR16529 {
62   struct U {};
63   template <typename T> struct S {
64     static decltype(T{}, U{}) &f();
65   };
66   U &r = S<int>::f();
67 }
68 
69 namespace PR18876 {
70   struct A { ~A() = delete; }; // expected-note +{{here}}
71   A f();
72   decltype(f()) *a; // ok, function call
73   decltype(A()) *b; // expected-error {{attempt to use a deleted function}}
74   decltype(0, f()) *c; // ok, function call on RHS of comma
75   decltype(0, A()) *d; // expected-error {{attempt to use a deleted function}}
76   decltype(f(), 0) *e; // expected-error {{attempt to use a deleted function}}
77 }
78 
79 namespace D5789 {
80   struct P1 { char x[6]; } g1 = { "foo" };
81   struct LP1 { struct P1 p1; };
82 
83   // expected-warning@+3 {{initializer partially overrides}}
84   // expected-note@+2 {{previous initialization}}
85   // expected-note@+1 {{previous definition}}
86   template<class T> void foo(decltype(T(LP1{ .p1 = g1, .p1.x[1] = 'x' }))) {}
87 
88   // expected-warning@+3 {{initializer partially overrides}}
89   // expected-note@+2 {{previous initialization}}
90   template<class T>
91   void foo(decltype(T(LP1{ .p1 = g1, .p1.x[1] = 'r' }))) {} // okay
92 
93   // expected-warning@+3 {{initializer partially overrides}}
94   // expected-note@+2 {{previous initialization}}
95   template<class T>
96   void foo(decltype(T(LP1{ .p1 = { "foo" }, .p1.x[1] = 'x'}))) {} // okay
97 
98   // expected-warning@+3 {{initializer partially overrides}}
99   // expected-note@+2 {{previous initialization}}
100   // expected-error@+1 {{redefinition of 'foo'}}
101   template<class T> void foo(decltype(T(LP1{ .p1 = g1, .p1.x[1] = 'x' }))) {}
102 }
103 
104 namespace GH58674 {
105   struct Foo {
106     float value_;
107     struct nested {
108       float value_;
109     };
110   };
111 
112   template <typename T>
113   struct TemplateFoo {
114     float value_;
115   };
116 
117   float bar;
118 
119   template <typename T>
120   struct Animal{};
121 
122   template <typename T>
123   class Cat : Animal<T> {
124     using okay = decltype(Foo::value_);
125     using also_okay = decltype(bar);
126     using okay2 = decltype(Foo::nested::value_);
127     using okay3 = decltype(TemplateFoo<T>::value_);
128   public:
129     void meow() {
130       using okay = decltype(Foo::value_);
131       using also_okay = decltype(bar);
132       using okay2 = decltype(Foo::nested::value_);
133       using okay3 = decltype(TemplateFoo<T>::value_);
134     }
135   };
136 
137   void baz() {
138       Cat<void>{}.meow();
139   }
140 }
141 
142 namespace GH97646 {
143   template<bool B>
144   void f() {
145     decltype(B) x = false;
146     !x;
147   }
148 }
149 
150 namespace GH99873 {
151 struct B {
152   int x;
153 };
154 
155 template<typename T>
156 struct A {
157   template<typename U>
158   constexpr int f() const {
159     return 1;
160   }
161 
162   template<>
163   constexpr int f<int>() const {
164     return decltype(B::x)();
165   }
166 };
167 
168 // This shouldn't crash.
169 static_assert(A<int>().f<int>() == 0, "");
170 // The result should not be dependent.
171 static_assert(A<int>().f<int>() != 0, ""); // expected-error {{static assertion failed due to requirement 'GH99873::A<int>().f<int>() != 0'}}
172                                            // expected-note@-1 {{expression evaluates to '0 != 0'}}
173 }
174 
175 template<typename>
176 class conditional {
177 };
178 
179 // FIXME: The diagnostics here are produced twice.
180 void foo(conditional<decltype((1),int>) {  // expected-note 2 {{to match this '('}} expected-error {{expected ')'}} expected-note 2{{to match this '<'}}
181 } // expected-error {{expected function body after function declarator}} expected-error 2 {{expected '>'}} expected-error {{expected ')'}}
182