Skip to content

Commit e6e83cb

Browse files
committed
[clang][dataflow] Don't crash when constructing an array of records.
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
1 parent d3d9377 commit e6e83cb

File tree

2 files changed

+30
-3
lines changed

2 files changed

+30
-3
lines changed

clang/lib/Analysis/FlowSensitive/Transfer.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -500,9 +500,14 @@ class TransferVisitor : public ConstStmtVisitor<TransferVisitor> {
500500
return;
501501
}
502502

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

507512
transferInlineCall(S, ConstructorDecl);
508513
}

clang/unittests/Analysis/FlowSensitive/TransferTest.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,28 @@ TEST(TransferTest, StructVarDeclWithInit) {
310310
});
311311
}
312312

313+
TEST(TransferTest, StructArrayVarDecl) {
314+
std::string Code = R"(
315+
struct A {};
316+
317+
void target() {
318+
A Array[2];
319+
// [[p]]
320+
}
321+
)";
322+
runDataflow(
323+
Code,
324+
[](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
325+
ASTContext &ASTCtx) {
326+
const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
327+
328+
const ValueDecl *ArrayDecl = findValueDecl(ASTCtx, "Array");
329+
330+
// We currently don't create values for arrays.
331+
ASSERT_THAT(Env.getValue(*ArrayDecl), IsNull());
332+
});
333+
}
334+
313335
TEST(TransferTest, ClassVarDecl) {
314336
std::string Code = R"(
315337
class A {

0 commit comments

Comments
 (0)