@@ -142,13 +142,6 @@ struct SubclassUnsafeMembers : public UnsafeMembers {
142142 {}
143143};
144144
145- // Without an explicit constructor, there is no CXXDefaultInitExpr to anchor on
146- // in matchers.
147- struct AggregateUnsafeMembers {
148- UnsafeMembers f1;
149- UnsafeMembers f2{3 }; // expected-warning{{function introduces unsafe buffer manipulation}}
150- };
151-
152145// https://github.com/llvm/llvm-project/issues/80482
153146void testClassMembers () {
154147 UnsafeMembers (3 ); // expected-warning{{function introduces unsafe buffer manipulation}}
@@ -166,22 +159,10 @@ void testClassMembers() {
166159
167160 SubclassUnsafeMembers ();
168161 SubclassUnsafeMembers (3 ); // expected-warning{{function introduces unsafe buffer manipulation}}
169-
170- (void )AggregateUnsafeMembers{
171- .f1 = UnsafeMembers (3 ), // expected-warning{{function introduces unsafe buffer manipulation}}
172- };
173-
174- (void )AggregateUnsafeMembers (3 ); // expected-warning{{function introduces unsafe buffer manipulation}}
175-
176- // FIXME: This should generate a warning but InitListExpr construction is
177- // treated as calling an implicit constructor, while ParentListInitExpr (the
178- // one above) is not. So `MatchDescendantVisitor::shouldVisitImplicitCode()`
179- // must return true for this to generate a warning. However that moves the
180- // SourceLocation of warnings from field initializers that construct through
181- // InitListExpr, preventing us from matching warnings against them.
182- (void )AggregateUnsafeMembers{3 };
183162}
184163
164+ // Not an aggregate, so its constructor is not implicit code and will be
165+ // visited/checked for warnings.
185166struct NotCalledHoldsUnsafeMembers {
186167 NotCalledHoldsUnsafeMembers ()
187168 : FromCtor(3 ), // expected-warning{{function introduces unsafe buffer manipulation}}
@@ -192,3 +173,75 @@ struct NotCalledHoldsUnsafeMembers {
192173 UnsafeMembers FromCtor2;
193174 UnsafeMembers FromField{3 }; // expected-warning{{function introduces unsafe buffer manipulation}}
194175};
176+
177+ // An aggregate, so its constructor is implicit code. Since it's not called, it
178+ // is never generated.
179+ struct AggregateUnused {
180+ UnsafeMembers f1;
181+ // While this field would trigger the warning during initialization, since
182+ // it's unused, there's no code generated that does the initialization, so
183+ // no warning.
184+ UnsafeMembers f2{3 };
185+ };
186+
187+ struct AggregateExplicitlyInitializedSafe {
188+ UnsafeMembers f1;
189+ // The warning is not fired as the field is always explicltly initialized
190+ // elsewhere. This initializer is never used.
191+ UnsafeMembers f2{3 };
192+ };
193+
194+ void testAggregateExplicitlyInitializedSafe () {
195+ AggregateExplicitlyInitializedSafe A{
196+ .f2 = UnsafeMembers (), // A safe constructor.
197+ };
198+ }
199+
200+ struct AggregateExplicitlyInitializedUnsafe {
201+ UnsafeMembers f1;
202+ // The warning is not fired as the field is always explicltly initialized
203+ // elsewhere. This initializer is never used.
204+ UnsafeMembers f2{3 };
205+ };
206+
207+ void testAggregateExplicitlyInitializedUnsafe () {
208+ AggregateExplicitlyInitializedUnsafe A{
209+ .f2 = UnsafeMembers (3 ), // expected-warning{{function introduces unsafe buffer manipulation}}
210+ };
211+ }
212+
213+ struct AggregateViaAggregateInit {
214+ UnsafeMembers f1;
215+ // FIXME: A construction of this class does initialize the field through
216+ // this initializer, so it should warn. Ideally it should also point to
217+ // where the site of the construction is in testAggregateViaAggregateInit().
218+ UnsafeMembers f2{3 };
219+ };
220+
221+ void testAggregateViaAggregateInit () {
222+ AggregateViaAggregateInit A{};
223+ };
224+
225+ struct AggregateViaValueInit {
226+ UnsafeMembers f1;
227+ // FIXME: A construction of this class does initialize the field through
228+ // this initializer, so it should warn. Ideally it should also point to
229+ // where the site of the construction is in testAggregateViaValueInit().
230+ UnsafeMembers f2{3 };
231+ };
232+
233+ void testAggregateViaValueInit () {
234+ auto A = AggregateViaValueInit ();
235+ };
236+
237+ struct AggregateViaDefaultInit {
238+ UnsafeMembers f1;
239+ // FIXME: A construction of this class does initialize the field through
240+ // this initializer, so it should warn. Ideally it should also point to
241+ // where the site of the construction is in testAggregateViaValueInit().
242+ UnsafeMembers f2{3 };
243+ };
244+
245+ void testAggregateViaDefaultInit () {
246+ AggregateViaDefaultInit A;
247+ };
0 commit comments