Index: clang/lib/Analysis/FlowSensitive/Transfer.cpp =================================================================== --- clang/lib/Analysis/FlowSensitive/Transfer.cpp +++ clang/lib/Analysis/FlowSensitive/Transfer.cpp @@ -732,7 +732,15 @@ Env.setValue(Loc, *Val); if (Type->isStructureOrClassType()) { - for (auto It : llvm::zip(Type->getAsRecordDecl()->fields(), S->inits())) { + // Unnamed bitfields are only used for padding and are not appearing in + // `InitListExpr`'s inits. However, those fields do appear in RecordDecl's + // field list, and we thus need to remove them before mapping inits to + // fields to avoid mapping inits to the wrongs fields. + std::vector Fields; + llvm::copy_if( + Type->getAsRecordDecl()->fields(), std::back_inserter(Fields), + [](const FieldDecl *Field) { return !Field->isUnnamedBitfield(); }); + for (auto It : llvm::zip(Fields, S->inits())) { const FieldDecl *Field = std::get<0>(It); assert(Field != nullptr); Index: clang/unittests/Analysis/FlowSensitive/TransferTest.cpp =================================================================== --- clang/unittests/Analysis/FlowSensitive/TransferTest.cpp +++ clang/unittests/Analysis/FlowSensitive/TransferTest.cpp @@ -5080,4 +5080,28 @@ {BuiltinOptions{ContextSensitiveOptions{}}}); } +TEST(TransferTest, UnnamedBitfieldInitializer) { + std::string Code = R"( + struct B {}; + struct A { + unsigned a; + unsigned : 4; + unsigned c; + B b; + }; + void target() { + A a = {}; + A test = a; + (void)test.c; + } + )"; + runDataflow( + Code, + [](const llvm::StringMap> &Results, + ASTContext &ASTCtx) { + // This doesn't need a body because this test was crashing the framework + // before handling correctly Unnamed bitfields in `InitListExpr`. + }); +} + } // namespace