diff options
author | martinboehme <mboehme@google.com> | 2024-02-21 10:10:25 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-21 10:10:25 +0100 |
commit | 4725993f1a812c86b9ad79d229a015d0216ff550 (patch) | |
tree | b05ac9ed380d8b1666ac90194301e315d306206a /clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp | |
parent | f8c1af1d096b97a42e4ab178c93accfc4e5fa288 (diff) | |
download | llvm-4725993f1a812c86b9ad79d229a015d0216ff550.zip llvm-4725993f1a812c86b9ad79d229a015d0216ff550.tar.gz llvm-4725993f1a812c86b9ad79d229a015d0216ff550.tar.bz2 |
[clang][dataflow] Correctly handle `InitListExpr` of union type. (#82348)
Diffstat (limited to 'clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp')
-rw-r--r-- | clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp index d487944..0cfc26e 100644 --- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp +++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp @@ -361,8 +361,8 @@ getFieldsGlobalsAndFuncs(const Stmt &S, FieldSet &Fields, if (const auto *FD = dyn_cast<FieldDecl>(VD)) Fields.insert(FD); } else if (auto *InitList = dyn_cast<InitListExpr>(&S)) { - if (RecordDecl *RD = InitList->getType()->getAsRecordDecl()) - for (const auto *FD : getFieldsForInitListExpr(RD)) + if (InitList->getType()->isRecordType()) + for (const auto *FD : getFieldsForInitListExpr(InitList)) Fields.insert(FD); } } @@ -1104,12 +1104,22 @@ RecordStorageLocation *getBaseObjectLocation(const MemberExpr &ME, return Env.get<RecordStorageLocation>(*Base); } -std::vector<FieldDecl *> getFieldsForInitListExpr(const RecordDecl *RD) { +std::vector<const FieldDecl *> +getFieldsForInitListExpr(const InitListExpr *InitList) { + const RecordDecl *RD = InitList->getType()->getAsRecordDecl(); + assert(RD != nullptr); + + std::vector<const FieldDecl *> Fields; + + if (InitList->getType()->isUnionType()) { + Fields.push_back(InitList->getInitializedFieldInUnion()); + return Fields; + } + // Unnamed bitfields are only used for padding and do not appear 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<FieldDecl *> Fields; llvm::copy_if( RD->fields(), std::back_inserter(Fields), [](const FieldDecl *Field) { return !Field->isUnnamedBitfield(); }); |