@@ -2381,32 +2381,6 @@ namespace {
2381
2381
hasMemberwiseInitializer = false ;
2382
2382
}
2383
2383
2384
- if (hasZeroInitializableStorage &&
2385
- !(cxxRecordDecl && cxxRecordDecl->hasDefaultConstructor ())) {
2386
- // Add default constructor for the struct if compiling in C mode.
2387
- // If we're compiling for C++:
2388
- // 1. If a default constructor is declared, don't synthesize one.
2389
- // 2. If a default constructor is deleted, don't try to synthesize one.
2390
- // 3. If there is no default constructor, synthesize a C-like default
2391
- // constructor that zero-initializes the backing memory of the
2392
- // struct. This is important to maintain source compatibility when a
2393
- // client enables C++ interop in an existing project that uses C
2394
- // interop and might rely on the fact that C structs have a default
2395
- // constructor available in Swift.
2396
- ConstructorDecl *defaultCtor =
2397
- synthesizer.createDefaultConstructor (result);
2398
- ctors.push_back (defaultCtor);
2399
- if (cxxRecordDecl) {
2400
- auto attr = AvailableAttr::createPlatformAgnostic (
2401
- defaultCtor->getASTContext (),
2402
- " This zero-initializes the backing memory of the struct, which "
2403
- " is unsafe for some C++ structs. Consider adding an explicit "
2404
- " default initializer for this C++ struct." ,
2405
- " " , PlatformAgnosticAvailabilityKind::Deprecated);
2406
- defaultCtor->getAttrs ().add (attr);
2407
- }
2408
- }
2409
-
2410
2384
bool forceMemberwiseInitializer = false ;
2411
2385
if (cxxRecordDecl && cxxRecordDecl->isInStdNamespace () &&
2412
2386
cxxRecordDecl->getIdentifier () &&
@@ -2437,6 +2411,42 @@ namespace {
2437
2411
ctors.push_back (valueCtor);
2438
2412
}
2439
2413
2414
+ // Add default constructor for the struct if compiling in C mode.
2415
+ // If we're compiling for C++:
2416
+ // 1. If a default constructor is declared, don't synthesize one.
2417
+ // 2. If a default constructor is deleted, don't try to synthesize one.
2418
+ // 3. If there is no default constructor, synthesize a C-like default
2419
+ // constructor that zero-initializes the backing memory of the
2420
+ // struct. This is important to maintain source compatibility when a
2421
+ // client enables C++ interop in an existing project that uses C
2422
+ // interop and might rely on the fact that C structs have a default
2423
+ // constructor available in Swift.
2424
+ bool needsEmptyInitializer = true ;
2425
+ if (cxxRecordDecl) {
2426
+ if (auto structResult = dyn_cast<StructDecl>(result)) {
2427
+ for (auto constructorDecl : ctors) {
2428
+ if (constructorDecl->getParameters ()->size () == 0 ) {
2429
+ needsEmptyInitializer = false ;
2430
+ break ;
2431
+ }
2432
+ }
2433
+ }
2434
+ }
2435
+ if (hasZeroInitializableStorage && needsEmptyInitializer) {
2436
+ ConstructorDecl *defaultCtor =
2437
+ synthesizer.createDefaultConstructor (result);
2438
+ ctors.push_back (defaultCtor);
2439
+ if (cxxRecordDecl) {
2440
+ auto attr = AvailableAttr::createPlatformAgnostic (
2441
+ defaultCtor->getASTContext (),
2442
+ " This zero-initializes the backing memory of the struct, which "
2443
+ " is unsafe for some C++ structs. Consider adding an explicit "
2444
+ " default initializer for this C++ struct." ,
2445
+ " " , PlatformAgnosticAvailabilityKind::Deprecated);
2446
+ defaultCtor->getAttrs ().add (attr);
2447
+ }
2448
+ }
2449
+
2440
2450
// Do not allow Swift to construct foreign reference types (at least, not
2441
2451
// yet).
2442
2452
if (isa<StructDecl>(result)) {
0 commit comments