diff --git a/clang/lib/Analysis/FlowSensitive/Transfer.cpp b/clang/lib/Analysis/FlowSensitive/Transfer.cpp --- a/clang/lib/Analysis/FlowSensitive/Transfer.cpp +++ b/clang/lib/Analysis/FlowSensitive/Transfer.cpp @@ -598,7 +598,7 @@ const Expr *Arg = S->getArg(0); assert(Arg != nullptr); - auto *ArgLoc = cast( + auto *ArgLoc = cast_or_null( Env.getStorageLocation(*Arg, SkipPast::Reference)); if (ArgLoc == nullptr) return; diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp --- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp @@ -2237,6 +2237,21 @@ }); } +TEST(TransferTest, CopyConstructorArgIsRefReturnedByFunction) { + // This is a crash repro. + std::string Code = R"( + struct S {}; + const S &returnsSRef(); + void target() { + S s(returnsSRef()); + } + )"; + runDataflow( + Code, + [](const llvm::StringMap> &Results, + ASTContext &ASTCtx) {}); +} + TEST(TransferTest, MoveConstructor) { std::string Code = R"( namespace std {