diff options
author | martinboehme <mboehme@google.com> | 2024-06-11 08:40:02 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-11 08:40:02 +0200 |
commit | 275196d866c86d95fc46b3324876ccbea09da79b (patch) | |
tree | 7b2eef1b5f31b72e1a5df91785c4498dcbc2599d /clang/unittests | |
parent | 05e87a583ce2680fc7309491c8bc23fd0e3bd049 (diff) | |
download | llvm-275196d866c86d95fc46b3324876ccbea09da79b.zip llvm-275196d866c86d95fc46b3324876ccbea09da79b.tar.gz llvm-275196d866c86d95fc46b3324876ccbea09da79b.tar.bz2 |
[clang][nullability] Don't return null fields from `getReferencedDecls()`. (#94983)
The patch includes a repro for a case where we were returning a null
`FieldDecl`
when calling `getReferencedDecls()` on the `InitListExpr` for a union.
Also, I noticed while working on this that `RecordInitListHelper` has a
bug
where it doesn't work correctly for empty unions. This patch also
includes a
repro and fix for this bug.
Diffstat (limited to 'clang/unittests')
-rw-r--r-- | clang/unittests/Analysis/FlowSensitive/ASTOpsTest.cpp | 88 | ||||
-rw-r--r-- | clang/unittests/Analysis/FlowSensitive/CMakeLists.txt | 1 |
2 files changed, 89 insertions, 0 deletions
diff --git a/clang/unittests/Analysis/FlowSensitive/ASTOpsTest.cpp b/clang/unittests/Analysis/FlowSensitive/ASTOpsTest.cpp new file mode 100644 index 0000000..cd1c076 --- /dev/null +++ b/clang/unittests/Analysis/FlowSensitive/ASTOpsTest.cpp @@ -0,0 +1,88 @@ +//===- unittests/Analysis/FlowSensitive/ASTOpsTest.cpp --------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "clang/Analysis/FlowSensitive/ASTOps.h" +#include "TestingSupport.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include <memory> + +namespace { + +using namespace clang; +using namespace dataflow; + +using ast_matchers::cxxRecordDecl; +using ast_matchers::hasName; +using ast_matchers::hasType; +using ast_matchers::initListExpr; +using ast_matchers::match; +using ast_matchers::selectFirst; +using test::findValueDecl; +using testing::IsEmpty; +using testing::UnorderedElementsAre; + +TEST(ASTOpsTest, RecordInitListHelperOnEmptyUnionInitList) { + // This is a regression test: The `RecordInitListHelper` used to assert-fail + // when called for the `InitListExpr` of an empty union. + std::string Code = R"cc( + struct S { + S() : UField{} {}; + + union U {} UField; + }; + )cc"; + std::unique_ptr<ASTUnit> Unit = + tooling::buildASTFromCodeWithArgs(Code, {"-fsyntax-only", "-std=c++17"}); + auto &ASTCtx = Unit->getASTContext(); + + ASSERT_EQ(ASTCtx.getDiagnostics().getClient()->getNumErrors(), 0U); + + auto *InitList = selectFirst<InitListExpr>( + "init", + match(initListExpr(hasType(cxxRecordDecl(hasName("U")))).bind("init"), + ASTCtx)); + ASSERT_NE(InitList, nullptr); + + RecordInitListHelper Helper(InitList); + EXPECT_THAT(Helper.base_inits(), IsEmpty()); + EXPECT_THAT(Helper.field_inits(), IsEmpty()); +} + +TEST(ASTOpsTest, ReferencedDeclsOnUnionInitList) { + // This is a regression test: `getReferencedDecls()` used to return a null + // `FieldDecl` in this case (in addition to the correct non-null `FieldDecl`) + // because `getInitializedFieldInUnion()` returns null for the syntactic form + // of the `InitListExpr`. + std::string Code = R"cc( + struct S { + S() : UField{0} {}; + + union U { + int I; + } UField; + }; + )cc"; + std::unique_ptr<ASTUnit> Unit = + tooling::buildASTFromCodeWithArgs(Code, {"-fsyntax-only", "-std=c++17"}); + auto &ASTCtx = Unit->getASTContext(); + + ASSERT_EQ(ASTCtx.getDiagnostics().getClient()->getNumErrors(), 0U); + + auto *InitList = selectFirst<InitListExpr>( + "init", + match(initListExpr(hasType(cxxRecordDecl(hasName("U")))).bind("init"), + ASTCtx)); + ASSERT_NE(InitList, nullptr); + auto *IDecl = cast<FieldDecl>(findValueDecl(ASTCtx, "I")); + + EXPECT_THAT(getReferencedDecls(*InitList).Fields, + UnorderedElementsAre(IDecl)); +} + +} // namespace diff --git a/clang/unittests/Analysis/FlowSensitive/CMakeLists.txt b/clang/unittests/Analysis/FlowSensitive/CMakeLists.txt index cfabb80..12fee5d 100644 --- a/clang/unittests/Analysis/FlowSensitive/CMakeLists.txt +++ b/clang/unittests/Analysis/FlowSensitive/CMakeLists.txt @@ -5,6 +5,7 @@ set(LLVM_LINK_COMPONENTS add_clang_unittest(ClangAnalysisFlowSensitiveTests ArenaTest.cpp + ASTOpsTest.cpp CFGMatchSwitchTest.cpp ChromiumCheckModelTest.cpp DataflowAnalysisContextTest.cpp |