================
@@ -1275,9 +1227,62 @@ class TrivialFunctionAnalysisVisitor
return Visit(VMT->getSubExpr());
}
+ // Returns true if E is known to evaluate to a smart pointer which holds
+ // nullptr, e.g. RefPtr<T>(), RefPtr<T>(nullptr),
Ref<T>(HashTableEmptyValue),
+ // or a call to a function which simply returns one such as
+ // HashTraits<Ref<T>>::emptyValue(). Destructing such a smart pointer can't
+ // delete anything.
+ bool isNullSmartPtr(const Expr *E, unsigned Depth = 0) {
+ if (!E || Depth > 4)
+ return false;
+ while (true) {
+ E = E->IgnoreParenCasts();
+ if (auto *EWC = dyn_cast<ExprWithCleanups>(E))
+ E = EWC->getSubExpr();
+ else if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
+ E = MTE->getSubExpr();
+ else if (auto *BTE = dyn_cast<CXXBindTemporaryExpr>(E))
+ E = BTE->getSubExpr();
+ else
+ break;
+ }
+ if (auto *CE = dyn_cast<CXXConstructExpr>(E)) {
+ auto *Ctor = CE->getConstructor();
+ if (!Ctor || !isOwnerPtr(safeGetName(Ctor->getParent())))
+ return false;
+ if (!CE->getNumArgs())
+ return Ctor->isDefaultConstructor();
+ if (CE->getNumArgs() != 1)
+ return false;
+ auto *Arg = CE->getArg(0)->IgnoreParenImpCasts();
+ auto ArgType = Arg->getType();
+ if (ArgType->isNullPtrType())
+ return true;
+ if (auto *TD = ArgType->getAsTagDecl();
+ TD && safeGetName(TD) == "HashTableEmptyValueType")
+ return true;
+ if (Ctor->isCopyOrMoveConstructor())
+ return isNullSmartPtr(Arg, Depth + 1);
+ return false;
+ }
+ if (auto *CE = dyn_cast<CallExpr>(E)) {
+ auto *Callee = CE->getDirectCallee();
+ if (!Callee || (isa<CXXMethodDecl>(Callee) &&
+ cast<CXXMethodDecl>(Callee)->isVirtual()))
+ return false;
----------------
steakhal wrote:
I think this simplifies to this:
```suggestion
auto *Callee = dyn_cast_or_null<CXXMethodDecl>(CE->getDirectCallee());
if (!Callee || Callee->isVirtual())
return false;
```
https://github.com/llvm/llvm-project/pull/230809
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits