li.zhe.hua updated this revision to Diff 432124.
li.zhe.hua added a comment.
Address reviewer comment.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D126413/new/
https://reviews.llvm.org/D126413
Files:
clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
Index: clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
===================================================================
--- clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -1476,6 +1476,112 @@
});
}
+TEST_F(TransferTest, StructThisInLambda) {
+ std::string ThisCaptureCode = R"(
+ struct A {
+ void frob() {
+ [this]() {
+ int Foo = Bar;
+ // [[p1]]
+ }();
+ }
+
+ int Bar;
+ };
+ )";
+ runDataflow(
+ ThisCaptureCode,
+ [](llvm::ArrayRef<
+ std::pair<std::string, DataflowAnalysisState<NoopLattice>>>
+ Results,
+ ASTContext &ASTCtx) {
+ ASSERT_THAT(Results, ElementsAre(Pair("p1", _)));
+ const Environment &Env = Results[0].second.Env;
+
+ const auto *ThisLoc = dyn_cast<AggregateStorageLocation>(
+ Env.getThisPointeeStorageLocation());
+ ASSERT_THAT(ThisLoc, NotNull());
+
+ const ValueDecl *BarDecl = findValueDecl(ASTCtx, "Bar");
+ ASSERT_THAT(BarDecl, NotNull());
+
+ const auto *BarLoc =
+ cast<ScalarStorageLocation>(&ThisLoc->getChild(*BarDecl));
+ ASSERT_TRUE(isa_and_nonnull<ScalarStorageLocation>(BarLoc));
+
+ const Value *BarVal = Env.getValue(*BarLoc);
+ ASSERT_TRUE(isa_and_nonnull<IntegerValue>(BarVal));
+
+ const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
+ ASSERT_THAT(FooDecl, NotNull());
+ EXPECT_EQ(Env.getValue(*FooDecl, SkipPast::None), BarVal);
+ },
+ LangStandard::lang_cxx17, /*ApplyBuiltinTransfer=*/true, "operator()");
+
+ std::string RefCaptureDefaultCode = R"(
+ struct A {
+ void frob() {
+ [&]() {
+ int Foo = Bar;
+ // [[p2]]
+ }();
+ }
+
+ int Bar;
+ };
+ )";
+ runDataflow(
+ RefCaptureDefaultCode,
+ [](llvm::ArrayRef<
+ std::pair<std::string, DataflowAnalysisState<NoopLattice>>>
+ Results,
+ ASTContext &ASTCtx) {
+ ASSERT_THAT(Results, ElementsAre(Pair("p2", _)));
+ const Environment &Env = Results[0].second.Env;
+
+ const auto *ThisLoc = dyn_cast<AggregateStorageLocation>(
+ Env.getThisPointeeStorageLocation());
+ ASSERT_THAT(ThisLoc, NotNull());
+
+ const ValueDecl *BarDecl = findValueDecl(ASTCtx, "Bar");
+ ASSERT_THAT(BarDecl, NotNull());
+
+ const auto *BarLoc =
+ cast<ScalarStorageLocation>(&ThisLoc->getChild(*BarDecl));
+ ASSERT_TRUE(isa_and_nonnull<ScalarStorageLocation>(BarLoc));
+
+ const Value *BarVal = Env.getValue(*BarLoc);
+ ASSERT_TRUE(isa_and_nonnull<IntegerValue>(BarVal));
+
+ const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
+ ASSERT_THAT(FooDecl, NotNull());
+ EXPECT_EQ(Env.getValue(*FooDecl, SkipPast::None), BarVal);
+ },
+ LangStandard::lang_cxx17, /*ApplyBuiltinTransfer=*/true, "operator()");
+
+ std::string FreeFunctionLambdaCode = R"(
+ void foo() {
+ int Bar;
+ [&]() {
+ int Foo = Bar;
+ // [[p3]]
+ }();
+ }
+ )";
+ runDataflow(
+ FreeFunctionLambdaCode,
+ [](llvm::ArrayRef<
+ std::pair<std::string, DataflowAnalysisState<NoopLattice>>>
+ Results,
+ ASTContext &ASTCtx) {
+ ASSERT_THAT(Results, ElementsAre(Pair("p3", _)));
+ const Environment &Env = Results[0].second.Env;
+
+ EXPECT_THAT(Env.getThisPointeeStorageLocation(), IsNull());
+ },
+ LangStandard::lang_cxx17, /*ApplyBuiltinTransfer=*/true, "operator()");
+}
+
TEST_F(TransferTest, ConstructorInitializer) {
std::string Code = R"(
struct target {
Index: clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
===================================================================
--- clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -216,7 +216,12 @@
}
if (const auto *MethodDecl = dyn_cast<CXXMethodDecl>(&DeclCtx)) {
- if (!MethodDecl->isStatic()) {
+ auto *Parent = MethodDecl->getParent();
+ assert(Parent != nullptr);
+ if (Parent->isLambda())
+ MethodDecl = dyn_cast<CXXMethodDecl>(Parent->getDeclContext());
+
+ if (MethodDecl && !MethodDecl->isStatic()) {
QualType ThisPointeeType = MethodDecl->getThisObjectType();
// FIXME: Add support for union types.
if (!ThisPointeeType->isUnionType()) {
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits