Skip to content

Commit 81595e9

Browse files
authored
[Clang][Sema] Add a test for move ctor calling for a base class. NFC (#97164)
When clang compiles the following expression: ```c++ return A{B{"Move Ctor"}}; ``` (where `B` is a base class for `A`), it adds a call to the move constructor of `B`. When the code is changed to... ```c++ return A{{"No Move Ctor"}}; ``` ... a move constructor is invoked neither for `A` nor for `B`. The lit test demonstrates the difference in the generated AST.
1 parent f7914aa commit 81595e9

File tree

1 file changed

+171
-0
lines changed

1 file changed

+171
-0
lines changed
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
// RUN: %clang_cc1 -ast-dump=json %s | FileCheck -strict-whitespace %s
2+
3+
struct ExplicitBase {
4+
explicit ExplicitBase(const char *) { }
5+
ExplicitBase(const ExplicitBase &) {}
6+
ExplicitBase(ExplicitBase &&) {}
7+
ExplicitBase &operator=(const ExplicitBase &) { return *this; }
8+
ExplicitBase &operator=(ExplicitBase &&) { return *this; }
9+
~ExplicitBase() { }
10+
};
11+
12+
struct Derived1 : ExplicitBase {};
13+
14+
Derived1 makeDerived1() {
15+
// CHECK: "kind": "FunctionDecl",
16+
// CHECK: "name": "makeDerived1",
17+
18+
// CHECK: "kind": "CompoundStmt",
19+
20+
// CHECK: "kind": "ReturnStmt",
21+
// CHECK: "kind": "ExprWithCleanups",
22+
// CHECK: "type": {
23+
// CHECK-NEXT: "qualType": "Derived1"
24+
// CHECK-NEXT: },
25+
26+
// CHECK: "kind": "CXXFunctionalCastExpr",
27+
// CHECK: "type": {
28+
// CHECK-NEXT: "qualType": "Derived1"
29+
// CHECK-NEXT: },
30+
// CHECK-NEXT: "valueCategory": "prvalue",
31+
// CHECK-NEXT: "castKind": "NoOp",
32+
33+
// CHECK: "kind": "CXXBindTemporaryExpr",
34+
// CHECK: "type": {
35+
// CHECK-NEXT: "qualType": "Derived1"
36+
// CHECK-NEXT: },
37+
// CHECK-NEXT: "valueCategory": "prvalue",
38+
39+
// CHECK: "kind": "InitListExpr",
40+
// CHECK: "type": {
41+
// CHECK-NEXT: "qualType": "Derived1"
42+
// CHECK-NEXT: },
43+
// CHECK-NEXT: "valueCategory": "prvalue",
44+
45+
// CHECK: "kind": "CXXConstructExpr",
46+
// CHECK: "type": {
47+
// CHECK-NEXT: "qualType": "ExplicitBase"
48+
// CHECK-NEXT: },
49+
// CHECK-NEXT: "valueCategory": "prvalue",
50+
// CHECK-NEXT: "ctorType": {
51+
// CHECK-NEXT: "qualType": "void (ExplicitBase &&)"
52+
// CHECK-NEXT: },
53+
// CHECK-NEXT: "hadMultipleCandidates": true,
54+
// CHECK-NEXT: "constructionKind": "non-virtual base",
55+
56+
// CHECK: "kind": "MaterializeTemporaryExpr",
57+
// CHECK: "type": {
58+
// CHECK-NEXT: "qualType": "ExplicitBase"
59+
// CHECK-NEXT: },
60+
// CHECK-NEXT: "valueCategory": "xvalue",
61+
// CHECK-NEXT: "storageDuration": "full expression",
62+
63+
// CHECK: "kind": "CXXBindTemporaryExpr",
64+
// CHECK: "type": {
65+
// CHECK-NEXT: "qualType": "ExplicitBase"
66+
// CHECK-NEXT: },
67+
// CHECK-NEXT: "valueCategory": "prvalue",
68+
69+
// CHECK: "kind": "CXXTemporaryObjectExpr",
70+
// CHECK: "type": {
71+
// CHECK-NEXT: "qualType": "ExplicitBase"
72+
// CHECK-NEXT: },
73+
// CHECK-NEXT: "valueCategory": "prvalue",
74+
// CHECK-NEXT: "ctorType": {
75+
// CHECK-NEXT: "qualType": "void (const char *)"
76+
// CHECK-NEXT: },
77+
// CHECK-NEXT: "list": true,
78+
// CHECK-NEXT: "hadMultipleCandidates": true,
79+
// CHECK-NEXT: "constructionKind": "complete",
80+
81+
// CHECK: "kind": "ImplicitCastExpr",
82+
// CHECK: "type": {
83+
// CHECK-NEXT: "qualType": "const char *"
84+
// CHECK-NEXT: },
85+
// CHECK-NEXT: "valueCategory": "prvalue",
86+
// CHECK-NEXT: "castKind": "ArrayToPointerDecay",
87+
88+
// CHECK: "kind": "StringLiteral",
89+
// CHECK: "type": {
90+
// CHECK-NEXT: "qualType": "const char[10]"
91+
// CHECK-NEXT: },
92+
// CHECK-NEXT: "valueCategory": "lvalue",
93+
// CHECK-NEXT: "value": "\"Move Ctor\""
94+
return Derived1{ExplicitBase{"Move Ctor"}};
95+
}
96+
97+
struct ImplicitBase {
98+
ImplicitBase(const char *) { }
99+
ImplicitBase(const ImplicitBase &) {}
100+
ImplicitBase(ImplicitBase &&) {}
101+
ImplicitBase &operator=(const ImplicitBase &) { return *this; }
102+
ImplicitBase &operator=(ImplicitBase &&) { return *this; }
103+
~ImplicitBase() { }
104+
};
105+
106+
struct Derived2 : ImplicitBase {};
107+
108+
Derived2 makeDerived2() {
109+
// CHECK: "kind": "FunctionDecl",
110+
// CHECK: "name": "makeDerived2",
111+
112+
// CHECK: "kind": "CompoundStmt",
113+
114+
// CHECK: "kind": "ReturnStmt",
115+
116+
// CHECK: "kind": "ExprWithCleanups",
117+
// CHECK: "type": {
118+
// CHECK-NEXT: "qualType": "Derived2"
119+
// CHECK-NEXT: },
120+
// CHECK-NEXT: "valueCategory": "prvalue",
121+
// CHECK-NEXT: "cleanupsHaveSideEffects": true,
122+
123+
// CHECK: "kind": "CXXFunctionalCastExpr",
124+
// CHECK: "type": {
125+
// CHECK-NEXT: "qualType": "Derived2"
126+
// CHECK-NEXT: },
127+
// CHECK-NEXT: "valueCategory": "prvalue",
128+
// CHECK-NEXT: "castKind": "NoOp",
129+
130+
// CHECK: "kind": "CXXBindTemporaryExpr",
131+
// CHECK: "type": {
132+
// CHECK-NEXT: "qualType": "Derived2"
133+
// CHECK-NEXT: },
134+
// CHECK-NEXT: "valueCategory": "prvalue",
135+
136+
// CHECK: "kind": "InitListExpr",
137+
// CHECK: "type": {
138+
// CHECK-NEXT: "qualType": "Derived2"
139+
// CHECK-NEXT: },
140+
// CHECK-NEXT: "valueCategory": "prvalue",
141+
142+
// CHECK: "kind": "CXXConstructExpr",
143+
// CHECK: "type": {
144+
// CHECK-NEXT: "qualType": "ImplicitBase"
145+
// CHECK-NEXT: },
146+
// CHECK-NEXT: "valueCategory": "prvalue",
147+
// CHECK-NEXT: "ctorType": {
148+
// CHECK-NEXT: "qualType": "void (const char *)"
149+
// CHECK-NEXT: },
150+
// CHECK-NEXT: "list": true,
151+
// CHECK-NEXT: "hadMultipleCandidates": true,
152+
// CHECK-NEXT: "constructionKind": "non-virtual base",
153+
154+
// CHECK: "kind": "ImplicitCastExpr",
155+
// CHECK: "type": {
156+
// CHECK-NEXT: "qualType": "const char *"
157+
// CHECK-NEXT: },
158+
// CHECK-NEXT: "valueCategory": "prvalue",
159+
// CHECK-NEXT: "castKind": "ArrayToPointerDecay",
160+
161+
// CHECK: "kind": "StringLiteral",
162+
// CHECK: "type": {
163+
// CHECK-NEXT: "qualType": "const char[8]"
164+
// CHECK-NEXT: },
165+
// CHECK-NEXT: "valueCategory": "lvalue",
166+
// CHECK-NEXT: "value": "\"No Ctor\""
167+
return Derived2{{"No Ctor"}};
168+
}
169+
170+
// NOTE: CHECK lines have been autogenerated by gen_ast_dump_json_test.py
171+
// using --filters=FunctionDecl,CompoundStmt,ReturnStmt,MaterializeTemporaryExpr,CXXBindTemporaryExpr,CXXTemporaryObjectExpr,ImplicitCastExpr,StringLiteralStringLiteral

0 commit comments

Comments
 (0)