aboutsummaryrefslogtreecommitdiff
path: root/clang/unittests
diff options
context:
space:
mode:
authormartinboehme <mboehme@google.com>2024-06-11 08:40:02 +0200
committerGitHub <noreply@github.com>2024-06-11 08:40:02 +0200
commit275196d866c86d95fc46b3324876ccbea09da79b (patch)
tree7b2eef1b5f31b72e1a5df91785c4498dcbc2599d /clang/unittests
parent05e87a583ce2680fc7309491c8bc23fd0e3bd049 (diff)
downloadllvm-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.cpp88
-rw-r--r--clang/unittests/Analysis/FlowSensitive/CMakeLists.txt1
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