xref: /llvm-project/clang/test/SemaCXX/compound-literal.cpp (revision 7c1d9b15eee3a34678addab2bab66f3020ac0753)
1 // RUN: %clang_cc1 -std=c++03 -verify -ast-dump %s > %t-03
2 // RUN: FileCheck --input-file=%t-03 %s
3 // RUN: %clang_cc1 -std=c++11 -verify -ast-dump %s > %t-11
4 // RUN: FileCheck --input-file=%t-11 %s
5 // RUN: FileCheck --input-file=%t-11 %s --check-prefix=CHECK-CXX11
6 // RUN: %clang_cc1 -verify -std=c++17 %s
7 
8 // http://llvm.org/PR7905
9 namespace PR7905 {
10 struct S; // expected-note {{forward declaration}}
foo1()11 void foo1() {
12   (void)(S[]) {{3}}; // expected-error {{array has incomplete element type}}
13 }
14 
15 template <typename T> struct M { T m; };
foo2()16 void foo2() {
17   (void)(M<short> []) {{3}};
18 }
19 }
20 
21 // Check compound literals mixed with C++11 list-initialization.
22 namespace brace_initializers {
23   struct POD {
24     int x, y;
25   };
26   struct HasCtor {
27     HasCtor(int x, int y);
28   };
29   struct HasDtor {
30     int x, y;
31     ~HasDtor();
32   };
33   struct HasCtorDtor {
34     HasCtorDtor(int x, int y);
35     ~HasCtorDtor();
36   };
37 
38   POD p = (POD){1, 2};
39   // CHECK-NOT: CXXBindTemporaryExpr {{.*}} 'brace_initializers::POD'
40   // CHECK: CompoundLiteralExpr {{.*}} 'POD':'brace_initializers::POD'
41   // CHECK-NEXT: InitListExpr {{.*}} 'POD':'brace_initializers::POD'
42   // CHECK-NEXT: ConstantExpr {{.*}}
43   // CHECK-NEXT: IntegerLiteral {{.*}} 1{{$}}
44   // CHECK-NEXT: ConstantExpr {{.*}}
45   // CHECK-NEXT: IntegerLiteral {{.*}} 2{{$}}
46 
test()47   void test() {
48     (void)(POD){1, 2};
49     // CHECK-NOT: CXXBindTemporaryExpr {{.*}} 'POD':'brace_initializers::POD'
50     // CHECK-NOT: ConstantExpr {{.*}} 'POD':'brace_initializers::POD'
51     // CHECK: CompoundLiteralExpr {{.*}} 'POD':'brace_initializers::POD'
52     // CHECK-NEXT: InitListExpr {{.*}} 'POD':'brace_initializers::POD'
53     // CHECK-NEXT: IntegerLiteral {{.*}} 1{{$}}
54     // CHECK-NEXT: IntegerLiteral {{.*}} 2{{$}}
55 
56     (void)(HasDtor){1, 2};
57     // CHECK: CXXBindTemporaryExpr {{.*}} 'HasDtor':'brace_initializers::HasDtor'
58     // CHECK-NEXT: CompoundLiteralExpr {{.*}} 'HasDtor':'brace_initializers::HasDtor'
59     // CHECK-NEXT: InitListExpr {{.*}} 'HasDtor':'brace_initializers::HasDtor'
60     // CHECK-NEXT: IntegerLiteral {{.*}} 1{{$}}
61     // CHECK-NEXT: IntegerLiteral {{.*}} 2{{$}}
62 
63 #if __cplusplus >= 201103L
64     (void)(HasCtor){1, 2};
65     // CHECK-CXX11-NOT: CXXBindTemporaryExpr {{.*}} 'HasCtor':'brace_initializers::HasCtor'
66     // CHECK-CXX11-NOT: ConstantExpr {{.*}} 'HasCtor':'brace_initializers::HasCtor'
67     // CHECK-CXX11: CompoundLiteralExpr {{.*}} 'HasCtor':'brace_initializers::HasCtor'
68     // CHECK-CXX11-NEXT: CXXTemporaryObjectExpr {{.*}} 'HasCtor':'brace_initializers::HasCtor'
69     // CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 1{{$}}
70     // CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 2{{$}}
71 
72     (void)(HasCtorDtor){1, 2};
73     // CHECK-CXX11: CXXBindTemporaryExpr {{.*}} 'HasCtorDtor':'brace_initializers::HasCtorDtor'
74     // CHECK-CXX11-NOT: ConstantExpr {{.*}} 'HasCtorDtor':'brace_initializers::HasCtorDtor'
75     // CHECK-CXX11: CompoundLiteralExpr {{.*}} 'HasCtorDtor':'brace_initializers::HasCtorDtor'
76     // CHECK-CXX11-NEXT: CXXTemporaryObjectExpr {{.*}} 'HasCtorDtor':'brace_initializers::HasCtorDtor'
77     // CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 1{{$}}
78     // CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 2{{$}}
79 #endif
80   }
81 
82   struct PrivateDtor {
83     int x, y;
84   private:
85     ~PrivateDtor(); // expected-note {{declared private here}}
86   };
87 
testPrivateDtor()88   void testPrivateDtor() {
89     (void)(PrivateDtor){1, 2}; // expected-error {{temporary of type 'PrivateDtor' has private destructor}}
90   }
91 }
92 
93 // This doesn't necessarily need to be an error, but CodeGen can't handle it
94 // at the moment.
95 int PR17415 = (int){PR17415}; // expected-error {{initializer element is not a compile-time constant}}
96 
97 // Make sure we accept this.  (Not sure if we actually should... but we do
98 // at the moment.)
99 template<unsigned> struct Value { };
100 template<typename T>
101 int &check_narrowed(Value<sizeof((T){1.1})>);
102 
103 #if __cplusplus >= 201103L
104 // Compound literals in global lambdas have automatic storage duration
105 // and are not subject to the constant-initialization rules.
__anon79c23e7d0102null106 int computed_with_lambda = [] {
107   int x = 5;
108   int result = ((int[]) { x, x + 2, x + 4, x + 6 })[0];
109   return result;
110 }();
111 #endif
112 
113 namespace DynamicFileScopeLiteral {
114 // This covers the case where we have a file-scope compound literal with a
115 // non-constant initializer in C++. Previously, we had a bug where Clang forgot
116 // to consider initializer list elements for bases.
117 struct Empty {};
118 struct Foo : Empty { // expected-note 0+ {{candidate constructor}}
119   int x;
120   int y;
121 };
122 int f();
123 #if __cplusplus < 201103L
124 // expected-error@+6 {{non-aggregate type 'Foo' cannot be initialized with an initializer list}}
125 #elif __cplusplus < 201703L
126 // expected-error@+4 {{no matching constructor}}
127 #else
128 // expected-error@+2 {{initializer element is not a compile-time constant}}
129 #endif
130 Foo o = (Foo){ {}, 1, f() };
131 }
132