Files
TheRock/compiler/amd-llvm/clang/unittests/Analysis/FlowSensitive/UncheckedStatusOrAccessModelTestFixture.h
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

160 lines
6.4 KiB
C++

//===- UncheckedStatusOrAccessModelTestFixture.h --------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_ANALYSIS_FLOW_SENSITIVE_UNCHECKEDSTATUSORACCESSMODELTESTFIXTURE_H_
#define LLVM_CLANG_ANALYSIS_FLOW_SENSITIVE_UNCHECKEDSTATUSORACCESSMODELTESTFIXTURE_H_
#include <algorithm>
#include <iterator>
#include <string>
#include <utility>
#include <vector>
#include "TestingSupport.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/Analysis/CFG.h"
#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
#include "clang/Analysis/FlowSensitive/MatchSwitch.h"
#include "clang/Analysis/FlowSensitive/Models/UncheckedStatusOrAccessModel.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Error.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
namespace clang::dataflow::statusor_model {
enum class UncheckedStatusOrAccessModelTestAliasKind {
kUnaliased = 0, // no alias
kPartiallyAliased = 1, // template<typename T> using Alias = absl::StatusOr;
kFullyAliased = 2, // using Alias = absl::StatusOr<int>;
};
// Base class for the test executors. This is needed to abstract away the
// template parameter from the UncheckedStatusOrAccessModelTestExecutor. This
// allows us to use UncheckedStatusOrAccessModelTestExecutorBase* in the
// UncheckedStatusOrAccessModelTest.
class UncheckedStatusOrAccessModelTestExecutorBase {
public:
virtual void
ExpectDiagnosticsFor(std::string SourceCode,
UncheckedStatusOrAccessModelTestAliasKind) const = 0;
virtual void ExpectDiagnosticsForLambda(
std::string SourceCode,
UncheckedStatusOrAccessModelTestAliasKind) const = 0;
virtual ~UncheckedStatusOrAccessModelTestExecutorBase() = default;
};
// Returns these macros according to the alias kind:
// - STATUS
// - STATUSOR_INT
// - STATUSOR_BOOL
// - STATUSOR_VOIDPTR
// Tests should use these macros instead of e.g. absl::StatusOr<int> to ensure
// the model is insensitive to whether the StatusOr<> is aliased or not.
std::string GetAliasMacros(UncheckedStatusOrAccessModelTestAliasKind AliasKind);
std::vector<std::pair<std::string, std::string>>
GetHeaders(UncheckedStatusOrAccessModelTestAliasKind AliasKind);
// This allows us to run the same test suite for multiple models. This allows
// vendors to model internal APIs in an extension of the base model, and make
// sure that these tests still pass.
template <typename Model>
class UncheckedStatusOrAccessModelTestExecutor
: public UncheckedStatusOrAccessModelTestExecutorBase {
public:
void ExpectDiagnosticsFor(
std::string SourceCode,
UncheckedStatusOrAccessModelTestAliasKind AliasKind) const override {
using namespace ::clang::ast_matchers; // NOLINT: Too many names
ExpectDiagnosticsFor(SourceCode, hasName("target"), AliasKind);
}
void ExpectDiagnosticsForLambda(
std::string SourceCode,
UncheckedStatusOrAccessModelTestAliasKind AliasKind) const override {
using namespace ::clang::ast_matchers; // NOLINT: Too many names
ExpectDiagnosticsFor(SourceCode,
allOf(hasOverloadedOperatorName("()"),
hasDeclContext(cxxRecordDecl(isLambda()))),
AliasKind);
}
template <typename FuncDeclMatcher>
void ExpectDiagnosticsFor(
std::string SourceCode, FuncDeclMatcher FuncMatcher,
UncheckedStatusOrAccessModelTestAliasKind AliasKind) const {
std::vector<std::pair<std::string, std::string>> Headers =
GetHeaders(AliasKind);
UncheckedStatusOrAccessModelOptions Options{};
std::vector<SourceLocation> Diagnostics;
llvm::Error Error = test::checkDataflow<Model>(
test::AnalysisInputs<Model>(
SourceCode, std::move(FuncMatcher),
[](ASTContext &Ctx, Environment &Env) { return Model(Ctx, Env); })
.withPostVisitCFG(
[&Diagnostics,
Diagnoser = UncheckedStatusOrAccessDiagnoser(Options)](
ASTContext &Ctx, const CFGElement &Elt,
const TransferStateForDiagnostics<
UncheckedStatusOrAccessModel::Lattice> &State) mutable {
auto EltDiagnostics = Diagnoser(Elt, Ctx, State);
llvm::move(EltDiagnostics, std::back_inserter(Diagnostics));
})
.withASTBuildArgs(
{"-fsyntax-only", "-std=c++20", "-Wno-undefined-inline"})
.withASTBuildVirtualMappedFiles(
tooling::FileContentMappings(Headers.begin(), Headers.end())),
/*VerifyResults=*/[&Diagnostics, SourceCode](
const llvm::DenseMap<unsigned, std::string>
&Annotations,
const test::AnalysisOutputs &AO) {
llvm::DenseSet<unsigned> AnnotationLines;
for (const auto &[Line, _] : Annotations)
AnnotationLines.insert(Line);
auto &SrcMgr = AO.ASTCtx.getSourceManager();
llvm::DenseSet<unsigned> DiagnosticLines;
for (SourceLocation &Loc : Diagnostics)
DiagnosticLines.insert(SrcMgr.getPresumedLineNumber(Loc));
EXPECT_THAT(DiagnosticLines, testing::ContainerEq(AnnotationLines))
<< "\nFailing code:\n"
<< SourceCode;
});
if (Error)
FAIL() << llvm::toString(std::move(Error));
}
~UncheckedStatusOrAccessModelTestExecutor() override = default;
};
class UncheckedStatusOrAccessModelTest
: public ::testing::TestWithParam<
std::pair<UncheckedStatusOrAccessModelTestExecutorBase *,
UncheckedStatusOrAccessModelTestAliasKind>> {
protected:
void ExpectDiagnosticsFor(std::string SourceCode) {
GetParam().first->ExpectDiagnosticsFor(SourceCode, GetParam().second);
}
void ExpectDiagnosticsForLambda(std::string SourceCode) {
GetParam().first->ExpectDiagnosticsForLambda(SourceCode, GetParam().second);
}
};
} // namespace clang::dataflow::statusor_model
#endif // LLVM_CLANG_ANALYSIS_FLOW_SENSITIVE_UNCHECKEDSTATUSORACCESSMODELTESTFIXTURE_H_