llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-temporal-safety @llvm/pr-subscribers-clang Author: Utkarsh Saxena (usx95) <details> <summary>Changes</summary> Fixes an off-by-one crash in the lifetime_capture_by attribute handling. The CapturingArgIdx is already an index into the full Args array, but the code was incorrectly creating a CallArgs array (dropping the first argument for instance methods) and then indexing into it with CapturingArgIdx, causing incorrect argument access and potential out-of-bounds crashes. --- Full diff: https://github.com/llvm/llvm-project/pull/227231.diff 2 Files Affected: - (modified) clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp (+6-5) - (modified) clang/test/Sema/LifetimeSafety/safety.cpp (+23) ``````````diff diff --git a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp index 292e3279233bb..a6726c46f5347 100644 --- a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp +++ b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp @@ -1044,11 +1044,12 @@ void FactsGenerator::handleLifetimeCaptureBy(const FunctionDecl *FD, CapturingArgIdx == LifetimeCaptureByAttr::Unknown || CapturingArgIdx == LifetimeCaptureByAttr::Invalid) continue; - ArrayRef<const Expr *> CallArgs = IsInstance ? Args.drop_front() : Args; - const Expr *CapturedByArg = - (CapturingArgIdx == LifetimeCaptureByAttr::This) - ? Args[0] - : CallArgs[CapturingArgIdx]; + // FIXME: Diagnose bad CapturingArgIdx. + if (CapturingArgIdx != LifetimeCaptureByAttr::This && + (CapturingArgIdx < 0 || + static_cast<size_t>(CapturingArgIdx) >= Args.size())) + continue; + const Expr *CapturedByArg = Args[CapturingArgIdx]; assert(CapturedByArg && "Capturer expression must be valid"); OriginList *Dest = readValue(CapturedByArg); diff --git a/clang/test/Sema/LifetimeSafety/safety.cpp b/clang/test/Sema/LifetimeSafety/safety.cpp index bf49e86577678..fb91fb30713db 100644 --- a/clang/test/Sema/LifetimeSafety/safety.cpp +++ b/clang/test/Sema/LifetimeSafety/safety.cpp @@ -4076,6 +4076,29 @@ void capturing_multiple_locals() { use(v); // expected-note 2 {{later used here}} } +namespace off_by_one_crash { +struct Item { + const int* ptr; +}; + +struct Container { + const Item* saved; +}; + +struct Helper { + void AddItem(const Item& item [[clang::lifetime_capture_by(c)]], + Container& c) const; + void Populate() const { + Container c{}; + { + Item item; + AddItem(item, c); // expected-warning {{local variable 'item' does not live long enough}} + } // expected-note {{local variable 'item' is destroyed here}} + use(c); // expected-note {{later used here}} + } +}; +} // namespace off_by_one_crash + struct [[gsl::Pointer()]] PtrWithInt { int x; }; PtrWithInt f() { return PtrWithInt{10}; `````````` </details> https://github.com/llvm/llvm-project/pull/227231 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
