Skip to content

Commit

Permalink
[clang][dataflow] Don't crash when constructing an array of records.
Browse files Browse the repository at this point in the history
When I wrote https://reviews.llvm.org/D155446, I assumed that a `CXXConstructExpr` would always have record type, but this isn't true: It can have array type when constructing an array of records. The code would crash in this situation because `createValue()` would return null.

This patch includes a test that reproduces the crash without the other changes in the patch.

Reviewed By: sammccall

Differential Revision: https://reviews.llvm.org/D156402
  • Loading branch information
martinboehme committed Jul 27, 2023
1 parent d3d9377 commit e6e83cb
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 3 deletions.
11 changes: 8 additions & 3 deletions clang/lib/Analysis/FlowSensitive/Transfer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -500,9 +500,14 @@ class TransferVisitor : public ConstStmtVisitor<TransferVisitor> {
return;
}

auto &InitialVal = *cast<StructValue>(Env.createValue(S->getType()));
copyRecord(InitialVal.getAggregateLoc(), Env.getResultObjectLocation(*S),
Env);
// `CXXConstructExpr` can have array type if default-initializing an array
// of records, and we currently can't create values for arrays. So check if
// we've got a record type.
if (S->getType()->isRecordType()) {
auto &InitialVal = *cast<StructValue>(Env.createValue(S->getType()));
copyRecord(InitialVal.getAggregateLoc(), Env.getResultObjectLocation(*S),
Env);
}

transferInlineCall(S, ConstructorDecl);
}
Expand Down
22 changes: 22 additions & 0 deletions clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,28 @@ TEST(TransferTest, StructVarDeclWithInit) {
});
}

TEST(TransferTest, StructArrayVarDecl) {
std::string Code = R"(
struct A {};
void target() {
A Array[2];
// [[p]]
}
)";
runDataflow(
Code,
[](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
ASTContext &ASTCtx) {
const Environment &Env = getEnvironmentAtAnnotation(Results, "p");

const ValueDecl *ArrayDecl = findValueDecl(ASTCtx, "Array");

// We currently don't create values for arrays.
ASSERT_THAT(Env.getValue(*ArrayDecl), IsNull());
});
}

TEST(TransferTest, ClassVarDecl) {
std::string Code = R"(
class A {
Expand Down

0 comments on commit e6e83cb

Please sign in to comment.