================ @@ -5987,4 +6018,204 @@ TEST(TransferTest, EvaluateBlockWithUnreachablePreds) { ASTContext &ASTCtx) {}); } +TEST(TransferTest, LambdaCaptureByCopy) { + std::string Code = R"( + void target(int Foo, int Bar) { + [Foo]() { + (void)0; + // [[p]] + }(); + } + )"; + runDataflowOnLambda( + Code, + [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results, + ASTContext &ASTCtx) { + ASSERT_THAT(Results.keys(), UnorderedElementsAre("p")); + const Environment &Env = getEnvironmentAtAnnotation(Results, "p"); + + const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo"); + ASSERT_THAT(FooDecl, NotNull()); + + const StorageLocation *FooLoc = Env.getStorageLocation(*FooDecl); + ASSERT_TRUE(isa_and_nonnull<ScalarStorageLocation>(FooLoc)); + + const Value *FooVal = Env.getValue(*FooLoc); + EXPECT_TRUE(isa_and_nonnull<IntegerValue>(FooVal)); + + const ValueDecl *BarDecl = findValueDecl(ASTCtx, "Bar"); + ASSERT_THAT(BarDecl, NotNull()); + + const StorageLocation *BarLoc = Env.getStorageLocation(*BarDecl); + EXPECT_THAT(BarLoc, IsNull()); + }); +} + +TEST(TransferTest, LambdaCaptureByReference) { + std::string Code = R"( + void target(int Foo, int Bar) { + [&Foo]() { + (void)0; + // [[p]] + }(); + } + )"; + runDataflowOnLambda( + Code, + [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results, + ASTContext &ASTCtx) { + ASSERT_THAT(Results.keys(), UnorderedElementsAre("p")); + const Environment &Env = getEnvironmentAtAnnotation(Results, "p"); + + const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo"); + ASSERT_THAT(FooDecl, NotNull()); + + const StorageLocation *FooLoc = Env.getStorageLocation(*FooDecl); + ASSERT_TRUE(isa_and_nonnull<ScalarStorageLocation>(FooLoc)); + + const Value *FooVal = Env.getValue(*FooLoc); + EXPECT_TRUE(isa_and_nonnull<IntegerValue>(FooVal)); + + const ValueDecl *BarDecl = findValueDecl(ASTCtx, "Bar"); + ASSERT_THAT(BarDecl, NotNull()); + + const StorageLocation *BarLoc = Env.getStorageLocation(*BarDecl); + EXPECT_THAT(BarLoc, IsNull()); + }); +} + +TEST(TransferTest, LambdaCaptureWithInitializer) { + std::string Code = R"( + void target(int Bar) { + [Foo=Bar]() { + (void)0; + // [[p]] + }(); + } + )"; + runDataflowOnLambda( + Code, + [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results, + ASTContext &ASTCtx) { + ASSERT_THAT(Results.keys(), UnorderedElementsAre("p")); + const Environment &Env = getEnvironmentAtAnnotation(Results, "p"); + + const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo"); + ASSERT_THAT(FooDecl, NotNull()); + + const StorageLocation *FooLoc = Env.getStorageLocation(*FooDecl); + ASSERT_TRUE(isa_and_nonnull<ScalarStorageLocation>(FooLoc)); + + const Value *FooVal = Env.getValue(*FooLoc); + EXPECT_TRUE(isa_and_nonnull<IntegerValue>(FooVal)); + + const ValueDecl *BarDecl = findValueDecl(ASTCtx, "Bar"); + ASSERT_THAT(BarDecl, NotNull()); + + const StorageLocation *BarLoc = Env.getStorageLocation(*BarDecl); + EXPECT_THAT(BarLoc, IsNull()); + }); +} + +TEST(TransferTest, LambdaCaptureByCopyImplicit) { + std::string Code = R"( + void target(int Foo, int Bar) { + [=]() { + Foo; + // [[p]] + }(); + } + )"; + runDataflowOnLambda( + Code, + [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results, + ASTContext &ASTCtx) { + ASSERT_THAT(Results.keys(), UnorderedElementsAre("p")); + const Environment &Env = getEnvironmentAtAnnotation(Results, "p"); + + const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo"); + ASSERT_THAT(FooDecl, NotNull()); + + const StorageLocation *FooLoc = Env.getStorageLocation(*FooDecl); + ASSERT_TRUE(isa_and_nonnull<ScalarStorageLocation>(FooLoc)); + + const Value *FooVal = Env.getValue(*FooLoc); + EXPECT_TRUE(isa_and_nonnull<IntegerValue>(FooVal)); + + const ValueDecl *BarDecl = findValueDecl(ASTCtx, "Bar"); + ASSERT_THAT(BarDecl, NotNull()); + + const StorageLocation *BarLoc = Env.getStorageLocation(*BarDecl); + EXPECT_THAT(BarLoc, IsNull()); + }); +} + +TEST(TransferTest, LambdaCaptureByReferenceImplicit) { + std::string Code = R"( + void target(int Foo, int Bar) { + [&]() { + Foo; + // [[p]] + }(); + } + )"; + runDataflowOnLambda( + Code, + [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results, + ASTContext &ASTCtx) { + ASSERT_THAT(Results.keys(), UnorderedElementsAre("p")); + const Environment &Env = getEnvironmentAtAnnotation(Results, "p"); + + const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo"); + ASSERT_THAT(FooDecl, NotNull()); + + const StorageLocation *FooLoc = Env.getStorageLocation(*FooDecl); + ASSERT_TRUE(isa_and_nonnull<ScalarStorageLocation>(FooLoc)); + + const Value *FooVal = Env.getValue(*FooLoc); + EXPECT_TRUE(isa_and_nonnull<IntegerValue>(FooVal)); + + const ValueDecl *BarDecl = findValueDecl(ASTCtx, "Bar"); + ASSERT_THAT(BarDecl, NotNull()); + + const StorageLocation *BarLoc = Env.getStorageLocation(*BarDecl); + EXPECT_THAT(BarLoc, IsNull()); ---------------- ymand wrote:
Why is `BarLoc` null here, given the capture-by-ref? https://github.com/llvm/llvm-project/pull/68558 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits