Skip to content

Commit

Permalink
[clang][dataflow] Add a test that we can access fields of anonymous r…
Browse files Browse the repository at this point in the history
…ecords.

Reviewed By: sammccall, ymandel, gribozavr2, xazax.hun

Differential Revision: https://reviews.llvm.org/D153409
  • Loading branch information
martinboehme committed Jun 28, 2023
1 parent bd89f9e commit d04b198
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 1 deletion.
12 changes: 11 additions & 1 deletion clang/unittests/Analysis/FlowSensitive/TestingSupport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,9 +154,19 @@ test::buildStatementToAnnotationMapping(const FunctionDecl *Func,
}

const ValueDecl *test::findValueDecl(ASTContext &ASTCtx, llvm::StringRef Name) {
auto TargetNodes = match(valueDecl(hasName(Name)).bind("v"), ASTCtx);
auto TargetNodes = match(
valueDecl(unless(indirectFieldDecl()), hasName(Name)).bind("v"), ASTCtx);
assert(TargetNodes.size() == 1 && "Name must be unique");
auto *const Result = selectFirst<ValueDecl>("v", TargetNodes);
assert(Result != nullptr);
return Result;
}

const IndirectFieldDecl *test::findIndirectFieldDecl(ASTContext &ASTCtx,
llvm::StringRef Name) {
auto TargetNodes = match(indirectFieldDecl(hasName(Name)).bind("i"), ASTCtx);
assert(TargetNodes.size() == 1 && "Name must be unique");
const auto *Result = selectFirst<IndirectFieldDecl>("i", TargetNodes);
assert(Result != nullptr);
return Result;
}
8 changes: 8 additions & 0 deletions clang/unittests/Analysis/FlowSensitive/TestingSupport.h
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,14 @@ runDataflowReturnError(llvm::StringRef Code, VerifyResultsT VerifyResults,
/// `Name` must be unique in `ASTCtx`.
const ValueDecl *findValueDecl(ASTContext &ASTCtx, llvm::StringRef Name);

/// Returns the `IndirectFieldDecl` for the given identifier.
///
/// Requirements:
///
/// `Name` must be unique in `ASTCtx`.
const IndirectFieldDecl *findIndirectFieldDecl(ASTContext &ASTCtx,
llvm::StringRef Name);

/// Returns the storage location (of type `LocT`) for the given identifier.
/// `LocT` must be a subclass of `StorageLocation` and must be of the
/// appropriate type.
Expand Down
34 changes: 34 additions & 0 deletions clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5434,4 +5434,38 @@ TEST(TransferTest, BuiltinFunctionModeled) {
});
}

// Check that fields of anonymous records are modeled.
TEST(TransferTest, AnonymousStruct) {
std::string Code = R"(
struct S {
struct {
bool b;
};
};
void target() {
S s;
s.b = true;
// [[p]]
}
)";
runDataflow(
Code,
[](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
ASTContext &ASTCtx) {
const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
const ValueDecl *SDecl = findValueDecl(ASTCtx, "s");
const ValueDecl *BDecl = findValueDecl(ASTCtx, "b");
const IndirectFieldDecl *IndirectField =
findIndirectFieldDecl(ASTCtx, "b");

auto *S =
cast<AggregateStorageLocation>(Env.getStorageLocation(*SDecl));
auto &AnonStruct = cast<AggregateStorageLocation>(
S->getChild(*cast<ValueDecl>(IndirectField->chain().front())));

auto *B = cast<BoolValue>(Env.getValue(AnonStruct.getChild(*BDecl)));
ASSERT_TRUE(Env.flowConditionImplies(*B));
});
}

} // namespace

0 comments on commit d04b198

Please sign in to comment.