@@ -55,13 +55,14 @@ class LifetimeChecker {
5555 const LiveOriginsAnalysis &LiveOrigins;
5656 const FactManager &FactMgr;
5757 LifetimeSafetyReporter *Reporter;
58+ AnalysisDeclContext ∾
5859
5960public:
6061 LifetimeChecker (const LoanPropagationAnalysis &LoanPropagation,
6162 const LiveOriginsAnalysis &LiveOrigins, const FactManager &FM,
6263 AnalysisDeclContext &ADC, LifetimeSafetyReporter *Reporter)
6364 : LoanPropagation(LoanPropagation), LiveOrigins(LiveOrigins), FactMgr(FM),
64- Reporter (Reporter) {
65+ Reporter (Reporter), AC(ADC) {
6566 for (const CFGBlock *B : *ADC.getAnalysis <PostOrderCFGView>())
6667 for (const Fact *F : FactMgr.getFacts (B))
6768 if (const auto *EF = F->getAs <ExpireFact>())
@@ -70,6 +71,7 @@ class LifetimeChecker {
7071 checkAnnotations (OEF);
7172 issuePendingWarnings ();
7273 suggestAnnotations ();
74+ inferAnnotations ();
7375 }
7476
7577 // / Checks if an escaping origin holds a placeholder loan, indicating a
@@ -157,41 +159,18 @@ class LifetimeChecker {
157159 void suggestAnnotations () {
158160 if (!Reporter)
159161 return ;
162+ for (const auto &[PVD, EscapeExpr] : AnnotationWarningsMap)
163+ Reporter->suggestAnnotation (PVD, EscapeExpr);
164+ }
165+
166+ void inferAnnotations () {
160167 for (const auto &[ConstPVD, EscapeExpr] : AnnotationWarningsMap) {
161168 ParmVarDecl *PVD = const_cast <ParmVarDecl *>(ConstPVD);
162-
169+ if (PVD->hasAttr <LifetimeBoundAttr>())
170+ continue ;
163171 ASTContext &Ctx = AC.getASTContext ();
164-
165- // 1. Get the IdentifierInfo for the attribute's name ("lifetimebound").
166- IdentifierInfo *Ident = &Ctx.Idents .get (" lifetimebound" );
167-
168- // 2. Construct the AttributeCommonInfo for an implicit attribute.
169- // We use the constructor that takes a name, range, and form.
170- // Form::Implicit() tells Clang this attribute is not from source code.
171- AttributeCommonInfo AttrInfo (Ident, SourceRange (),
172- AttributeCommonInfo::Form::Implicit ());
173-
174- // 3. Create the final LifetimeBoundAttr.
175- auto *Attr = new (Ctx) LifetimeBoundAttr (Ctx, AttrInfo);
176-
177- // 4. Add the attribute to the parameter declaration.
172+ auto *Attr = LifetimeBoundAttr::CreateImplicit (Ctx, SourceLocation ());
178173 PVD->addAttr (Attr);
179-
180- if (const FunctionDecl *FD =
181- dyn_cast<FunctionDecl>(PVD->getDeclContext ())) {
182- for (const FunctionDecl *Redecl : FD->redecls ()) {
183- if (Redecl != FD) {
184- const ParmVarDecl *RedeclPVD =
185- Redecl->getParamDecl (PVD->getFunctionScopeIndex ());
186- if (RedeclPVD) {
187- auto *NewAttr = new (Ctx) LifetimeBoundAttr (Ctx, AttrInfo);
188- const_cast <ParmVarDecl *>(RedeclPVD)->addAttr (NewAttr);
189- }
190- }
191- }
192- }
193-
194- Reporter->suggestAnnotation (ConstPVD, EscapeExpr);
195174 }
196175 }
197176};
0 commit comments