@@ -70,7 +70,7 @@ struct LifetimeCheckPass : public LifetimeCheckBase<LifetimeCheckPass> {
7070 CallParam,
7171 IndirectCallParam,
7272 };
73- void checkPointerDeref (mlir::Value addr, mlir::Location loc,
73+ bool checkPointerDeref (mlir::Value addr, mlir::Location loc,
7474 DerefStyle derefStyle = DerefStyle::Direct);
7575 void checkCoroTaskStore (StoreOp storeOp);
7676 void checkLambdaCaptureStore (StoreOp storeOp);
@@ -1515,8 +1515,12 @@ void LifetimeCheckPass::emitInvalidHistory(mlir::InFlightDiagnostic &D,
15151515 }
15161516}
15171517
1518- void LifetimeCheckPass::checkPointerDeref (mlir::Value addr, mlir::Location loc,
1518+ bool LifetimeCheckPass::checkPointerDeref (mlir::Value addr, mlir::Location loc,
15191519 DerefStyle derefStyle) {
1520+ // Skip temporaries early - they're about to be destroyed anyway
1521+ if (isSkippableTemporary (addr))
1522+ return false ; // Not an error, just a temporary
1523+
15201524 bool hasInvalid = getPmap ()[addr].count (State::getInvalid ());
15211525 bool hasNullptr = getPmap ()[addr].count (State::getNullPtr ());
15221526
@@ -1527,10 +1531,6 @@ void LifetimeCheckPass::checkPointerDeref(mlir::Value addr, mlir::Location loc,
15271531 emitRemark (loc) << " pset => " << Out.str ();
15281532 };
15291533
1530- // Do not emit the same warning twice or more.
1531- if (emittedDiagnostics.count (loc))
1532- return ;
1533-
15341534 bool psetRemarkEmitted = false ;
15351535 if (opts.emitRemarkPsetAlways ()) {
15361536 emitPsetRemark ();
@@ -1539,15 +1539,20 @@ void LifetimeCheckPass::checkPointerDeref(mlir::Value addr, mlir::Location loc,
15391539
15401540 // 2.4.2 - On every dereference of a Pointer p, enforce that p is valid.
15411541 if (!hasInvalid && !hasNullptr)
1542- return ;
1542+ return false ; // No error
15431543
15441544 // TODO: create verbosity/accuracy levels, for now use deref styles directly
15451545 // to decide when not to emit a warning.
15461546
15471547 // For indirect calls, do not relly on blunt nullptr passing, require some
15481548 // invalidation to have happened in a path.
15491549 if (derefStyle == DerefStyle::IndirectCallParam && !hasInvalid)
1550- return ;
1550+ return false ; // No error
1551+
1552+ // Do not emit the same warning twice or more (check AFTER we know there's an
1553+ // error)
1554+ if (emittedDiagnostics.count (loc))
1555+ return true ; // Already reported
15511556
15521557 // Ok, filtered out questionable warnings, take the bad path leading to this
15531558 // deference point and diagnose it.
@@ -1588,6 +1593,8 @@ void LifetimeCheckPass::checkPointerDeref(mlir::Value addr, mlir::Location loc,
15881593
15891594 if (!psetRemarkEmitted && opts.emitRemarkPsetInvalid ())
15901595 emitPsetRemark ();
1596+
1597+ return true ; // Error was reported
15911598}
15921599
15931600static FuncOp getCalleeFromSymbol (ModuleOp mod, llvm::StringRef name) {
@@ -1727,35 +1734,28 @@ void LifetimeCheckPass::checkArgForRValueRef(
17271734
17281735 // Owner types
17291736 if (owners.count (addr)) {
1730- if (getPmap ()[addr].count (State::getInvalid ()) ||
1731- getPmap ()[addr].count (State::getNullPtr ())) {
1732- checkPointerDeref (addr, callOp.getLoc ());
1733- return ;
1734- }
1735- if (!isSkippableTemporary (addr))
1736- markOwnerAsMovedFrom (addr, callOp.getLoc ());
1737+ if (checkPointerDeref (addr, callOp.getLoc ()))
1738+ return ; // Already reported error
1739+ markOwnerAsMovedFrom (addr, callOp.getLoc ());
17371740 return ;
17381741 }
17391742
1740- // Pointer types
1743+ // Pointer types - only check Invalid (not NullPtr)
17411744 if (ptrs.count (addr)) {
17421745 if (getPmap ()[addr].count (State::getInvalid ())) {
17431746 checkPointerDeref (addr, callOp.getLoc ());
17441747 return ;
17451748 }
1746- if (!isSkippableTemporary (addr))
1747- markPointerOrValueTypeAsMovedFrom (addr, callOp.getLoc ());
1749+ markPointerOrValueTypeAsMovedFrom (addr, callOp.getLoc ());
17481750 return ;
17491751 }
17501752
1751- // Value types (primitives )
1753+ // Value types - only check Invalid (not NullPtr )
17521754 if (getPmap ()[addr].count (State::getInvalid ())) {
17531755 checkPointerDeref (addr, callOp.getLoc ());
17541756 return ;
17551757 }
1756-
1757- if (!isSkippableTemporary (addr))
1758- markPointerOrValueTypeAsMovedFrom (addr, callOp.getLoc ());
1758+ markPointerOrValueTypeAsMovedFrom (addr, callOp.getLoc ());
17591759}
17601760
17611761void LifetimeCheckPass::checkCopyAssignment (CallOp callOp,
@@ -1916,6 +1916,10 @@ void LifetimeCheckPass::checkNonConstUseOfOwner(mlir::Value ownerAddr,
19161916
19171917void LifetimeCheckPass::markOwnerAsMovedFrom (mlir::Value addr,
19181918 mlir::Location loc) {
1919+ // Don't mark temporaries as moved-from - they're about to be destroyed
1920+ if (isSkippableTemporary (addr))
1921+ return ;
1922+
19191923 // All owner types are marked invalid after move. Safe operations on specific
19201924 // owner types (e.g., smart pointer get/reset) are handled separately in
19211925 // isSmartPointerSafeMethod.
@@ -1936,6 +1940,10 @@ bool LifetimeCheckPass::isValueTypeMovedFrom(mlir::Value addr) {
19361940
19371941void LifetimeCheckPass::markPointerOrValueTypeAsMovedFrom (mlir::Value addr,
19381942 mlir::Location loc) {
1943+ // Don't mark temporaries as moved-from
1944+ if (isSkippableTemporary (addr))
1945+ return ;
1946+
19391947 markPsetInvalid (addr, InvalidStyle::MovedFrom, loc);
19401948}
19411949
@@ -1984,18 +1992,14 @@ void LifetimeCheckPass::checkMoveCtor(CallOp callOp, cir::CXXCtorAttr ctor) {
19841992 // Check if this is an Owner type move constructor
19851993 auto addr = getThisParamOwnerCategory (callOp);
19861994 if (addr && owners.count (src)) {
1987- // Don't mark temporaries as moved-from - they're about to be destroyed
1988- if (!isSkippableTemporary (src))
1989- markOwnerAsMovedFrom (src, callOp.getLoc ());
1995+ markOwnerAsMovedFrom (src, callOp.getLoc ());
19901996 return ;
19911997 }
19921998
19931999 // Check if this is a Pointer type move constructor
19942000 addr = getThisParamPointerCategory (callOp);
19952001 if (addr && ptrs.count (src)) {
1996- // Don't mark temporaries as moved-from
1997- if (!isSkippableTemporary (src))
1998- markPointerOrValueTypeAsMovedFrom (src, callOp.getLoc ());
2002+ markPointerOrValueTypeAsMovedFrom (src, callOp.getLoc ());
19992003 return ;
20002004 }
20012005}
@@ -2183,7 +2187,7 @@ void LifetimeCheckPass::checkCall(CallOp callOp) {
21832187 // invalid access to Ptr if any of its methods are used.
21842188 auto addr = getThisParamPointerCategory (callOp);
21852189 if (addr)
2186- return checkPointerDeref (addr, callOp.getLoc ());
2190+ checkPointerDeref (addr, callOp.getLoc ());
21872191}
21882192
21892193void LifetimeCheckPass::checkOperation (Operation *op) {
0 commit comments