llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-temporal-safety Author: Zeyi Xu (zeyi2) <details> <summary>Changes</summary> Avoid assuming that a placement allocation function has a second `ParmVarDecl` before checking whether that parameter is `void*`. Variadic `operator new(size_t, ...)` can have a placement argument matched by the ellipsis instead. Closes https://github.com/llvm/llvm-project/issues/199584 --- Full diff: https://github.com/llvm/llvm-project/pull/199588.diff 2 Files Affected: - (modified) clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp (+23-22) - (modified) clang/test/Sema/warn-lifetime-safety.cpp (+11) ``````````diff diff --git a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp index 8a7a4b79a1584..fa5a1aa4a7903 100644 --- a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp +++ b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp @@ -640,28 +640,29 @@ void FactsGenerator::VisitCXXNewExpr(const CXXNewExpr *NE) { // And that the placement parameter num is 1, // that is to mostly limit to standard library placement new. if (NE->getNumPlacementArgs() == 1) { - if (const auto *Arg = NE->getOperatorNew() - ->getParamDecl(1) - ->getType() - ->getAs<PointerType>(); - Arg && Arg->isVoidPointerType()) { - // Use the placement argument before the implicit conversion to void*, so - // inner origins are still available. - const Expr *PlacementArg = NE->getPlacementArg(0); - if (const auto *ICE = dyn_cast<ImplicitCastExpr>(PlacementArg); - ICE && ICE->getCastKind() == CK_BitCast && - PlacementArg->getType()->isVoidPointerType()) - PlacementArg = ICE->getSubExpr(); - OriginList *PlacementList = getOriginsList(*PlacementArg); - // FIXME: General placement arguments need separate handling to overwrite - // the right origins. - - // The pointer returned by placement new comes from the placement - // argument. - if (PlacementList) - CurrentBlockFacts.push_back(FactMgr.createFact<OriginFlowFact>( - NewList->getOuterOriginID(), PlacementList->getOuterOriginID(), - true)); + const FunctionDecl *OperatorNew = NE->getOperatorNew(); + if (OperatorNew->getNumParams() > 1) { + if (const auto *Arg = + OperatorNew->getParamDecl(1)->getType()->getAs<PointerType>(); + Arg && Arg->isVoidPointerType()) { + // Use the placement argument before the implicit conversion to void*, + // so inner origins are still available. + const Expr *PlacementArg = NE->getPlacementArg(0); + if (const auto *ICE = dyn_cast<ImplicitCastExpr>(PlacementArg); + ICE && ICE->getCastKind() == CK_BitCast && + PlacementArg->getType()->isVoidPointerType()) + PlacementArg = ICE->getSubExpr(); + OriginList *PlacementList = getOriginsList(*PlacementArg); + // FIXME: General placement arguments need separate handling to + // overwrite the right origins. + + // The pointer returned by placement new comes from the placement + // argument. + if (PlacementList) + CurrentBlockFacts.push_back(FactMgr.createFact<OriginFlowFact>( + NewList->getOuterOriginID(), PlacementList->getOuterOriginID(), + true)); + } } } else { const Loan *L = createLoan(FactMgr, NE); diff --git a/clang/test/Sema/warn-lifetime-safety.cpp b/clang/test/Sema/warn-lifetime-safety.cpp index 70ec968dfd5c1..4bb7eb1e49437 100644 --- a/clang/test/Sema/warn-lifetime-safety.cpp +++ b/clang/test/Sema/warn-lifetime-safety.cpp @@ -2982,6 +2982,17 @@ void placement_new_heap_then_delete_use_after_free() { (void)*p; // expected-note {{later used here}} } +struct PlacementArg {}; + +struct VariadicPlacementNew { + void *operator new(decltype(sizeof(0)), ...); +}; + +void variadic_placement_new() { + PlacementArg arg; + (void)new (arg) VariadicPlacementNew; +} + int* foo(int* x [[clang::lifetimebound]], int* y [[clang::lifetimebound]]); void placement_new_delete_result_of_lifetimebound_call() { `````````` </details> https://github.com/llvm/llvm-project/pull/199588 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
