xref: /aosp_15_r20/external/clang/test/SemaTemplate/instantiate-sizeof.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -triple x86_64-linux-gnu -fsyntax-only -verify -std=c++11 %s
2*67e74705SXin Li 
3*67e74705SXin Li // Make sure we handle contexts correctly with sizeof
f(T n)4*67e74705SXin Li template<typename T> void f(T n) {
5*67e74705SXin Li   int buffer[n];
6*67e74705SXin Li   [] { int x = sizeof(sizeof(buffer)); }();
7*67e74705SXin Li }
main()8*67e74705SXin Li int main() {
9*67e74705SXin Li   f<int>(1);
10*67e74705SXin Li }
11*67e74705SXin Li 
12*67e74705SXin Li // Make sure we handle references to non-static data members in unevaluated
13*67e74705SXin Li // contexts in class template methods correctly. Previously we assumed these
14*67e74705SXin Li // would be valid MemberRefExprs, but they have no 'this' so we need to form a
15*67e74705SXin Li // DeclRefExpr to the FieldDecl instead.
16*67e74705SXin Li // PR26893
17*67e74705SXin Li template <class T>
18*67e74705SXin Li struct M {
MM19*67e74705SXin Li   M() {}; // expected-note {{in instantiation of default member initializer 'M<S>::m' requested here}}
20*67e74705SXin Li   int m = *T::x; // expected-error {{invalid use of non-static data member 'x'}}
fM21*67e74705SXin Li   void f() {
22*67e74705SXin Li     // These are valid.
23*67e74705SXin Li     static_assert(sizeof(T::x) == 8, "ptr");
24*67e74705SXin Li     static_assert(sizeof(*T::x) == 4, "int");
25*67e74705SXin Li   }
26*67e74705SXin Li };
27*67e74705SXin Li struct S { int *x; };
28*67e74705SXin Li template struct M<S>; // expected-note {{in instantiation of member function 'M<S>::M' requested here}}
29*67e74705SXin Li 
30*67e74705SXin Li // Similar test case for PR26893.
31*67e74705SXin Li template <typename T=void>
32*67e74705SXin Li struct bar {
33*67e74705SXin Li   struct foo { int array[10]; };
bazbar34*67e74705SXin Li   int baz() { return sizeof(foo::array); }
35*67e74705SXin Li };
36*67e74705SXin Li template struct bar<>;
37