|
17 | 17 | #include "swift/AST/DiagnosticsSIL.h" |
18 | 18 | #include "swift/AST/DistributedDecl.h" |
19 | 19 | #include "swift/AST/Expr.h" |
| 20 | +#include "swift/AST/ParameterList.h" |
| 21 | +#include "swift/AST/SemanticAttrs.h" |
20 | 22 | #include "swift/AST/Stmt.h" |
21 | | -#include "swift/Basic/Assertions.h" |
22 | 23 | #include "swift/ClangImporter/ClangModule.h" |
23 | 24 | #include "swift/SIL/BasicBlockBits.h" |
24 | | -#include "swift/AST/SemanticAttrs.h" |
25 | 25 | #include "swift/SIL/BasicBlockData.h" |
26 | 26 | #include "swift/SIL/InstructionUtils.h" |
27 | 27 | #include "swift/SIL/MemAccessUtils.h" |
|
30 | 30 | #include "swift/SIL/SILValue.h" |
31 | 31 | #include "swift/SILOptimizer/PassManager/Passes.h" |
32 | 32 | #include "swift/SILOptimizer/PassManager/Transforms.h" |
33 | | -#include "swift/SILOptimizer/Utils/CFGOptUtils.h" |
34 | 33 | #include "swift/SILOptimizer/Utils/DistributedActor.h" |
35 | 34 | #include "swift/SILOptimizer/Utils/InstOptUtils.h" |
36 | 35 | #include "llvm/ADT/STLExtras.h" |
@@ -2298,8 +2297,61 @@ bool LifetimeChecker::diagnoseReturnWithoutInitializingStoredProperties( |
2298 | 2297 | theStruct->getParentModule()->getName(), |
2299 | 2298 | theStruct->hasClangNode()); |
2300 | 2299 | } else { |
| 2300 | + // to generate the missing variables |
| 2301 | + std::string missingVariablesMessage; |
| 2302 | + std::string suggestedInitializerString; |
| 2303 | + AvailabilitySet Liveness = |
| 2304 | + getLivenessAtInst(Use.Inst, Use.FirstElement, Use.NumElements); |
| 2305 | + for (unsigned i = Use.FirstElement, e = Use.FirstElement + Use.NumElements; |
| 2306 | + i != e; ++i) { |
| 2307 | + // Ignore a failed super.init requirement. |
| 2308 | + if (i == TheMemory.getNumElements() - 1 && TheMemory.isDerivedClassSelf()) |
| 2309 | + continue; |
| 2310 | + |
| 2311 | + std::string Name; |
| 2312 | + auto *Decl = TheMemory.getPathStringToElement(i, Name); |
| 2313 | + |
| 2314 | + auto propertyInitIsolation = ActorIsolation::forUnspecified(); |
| 2315 | + |
| 2316 | + std::string inferredDeclType; |
| 2317 | + if (Decl) { |
| 2318 | + if (auto *var = dyn_cast<VarDecl>(Decl)) { |
| 2319 | + inferredDeclType = var->getValueInterfaceType().getString(); |
| 2320 | + propertyInitIsolation = var->getInitializerIsolation(); |
| 2321 | + } |
| 2322 | + |
| 2323 | + // If it's marked @_compilerInitialized, delay emission of the note. |
| 2324 | + if (Decl->getAttrs().hasAttribute<CompilerInitializedAttr>()) { |
| 2325 | + continue; |
| 2326 | + } |
| 2327 | + } |
| 2328 | + |
| 2329 | + if (propertyInitIsolation.isGlobalActor()) { |
| 2330 | + continue; |
| 2331 | + } |
| 2332 | + |
| 2333 | + auto declNameWithoutSelf = StringRef(Name).split(".").second; |
| 2334 | + suggestedInitializerString += |
| 2335 | + std::string(declNameWithoutSelf) + ":" + inferredDeclType + ","; |
| 2336 | + missingVariablesMessage += |
| 2337 | + Name + "=" + std::string(declNameWithoutSelf) + "\n"; |
| 2338 | + } |
| 2339 | + |
| 2340 | + suggestedInitializerString.pop_back(); |
| 2341 | + |
2301 | 2342 | diagnose(Module, loc, |
2302 | | - diag::return_from_init_without_initing_stored_properties); |
| 2343 | + diag::return_from_init_without_initing_stored_properties) |
| 2344 | + .fixItInsert(loc.getEndSourceLoc(), missingVariablesMessage); |
| 2345 | + |
| 2346 | + Decl *decl = Inst->getFunction()->getDeclContext()->getAsDecl(); |
| 2347 | + |
| 2348 | + if (auto *functionDecl = dyn_cast<AbstractFunctionDecl>(decl)) { |
| 2349 | + auto RParenLoc = functionDecl->getParameters()->getRParenLoc(); |
| 2350 | + auto initFunctionLocation = SILLocation(functionDecl); |
| 2351 | + |
| 2352 | + diagnose(Module, initFunctionLocation, diag::return_from_init_without_initing_stored_properties) |
| 2353 | + .fixItInsert(RParenLoc, suggestedInitializerString); |
| 2354 | + } |
2303 | 2355 | noteUninitializedMembers(Use); |
2304 | 2356 | } |
2305 | 2357 |
|
|
0 commit comments