//===- unittests/Driver/SanitizerArgsTest.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/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticIDs.h"
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Driver/Compilation.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/Job.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TargetParser/Host.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <cstdlib>
#include <memory>
#include <optional>
#include <string>
using namespace clang;
using namespace clang::driver;

using ::testing::Contains;
using ::testing::StrEq;

namespace {

static constexpr const char *ClangBinary = "clang";
static constexpr const char *InputFile = "/sources/foo.c";

std::string concatPaths(llvm::ArrayRef<StringRef> Components) {
  llvm::SmallString<128> P;
  for (StringRef C : Components)
    llvm::sys::path::append(P, C);
  return std::string(P);
}

class SanitizerArgsTest : public ::testing::Test {
protected:
  const Command &emulateSingleCompilation(std::vector<std::string> ExtraArgs,
                                          std::vector<std::string> ExtraFiles) {
    assert(!DriverInstance && "Running twice is not allowed");

    DiagnosticOptions DiagOpts;
    DiagnosticsEngine Diags(DiagnosticIDs::create(), DiagOpts,
                            new TextDiagnosticPrinter(llvm::errs(), DiagOpts));
    DriverInstance.emplace(ClangBinary, "x86_64-unknown-linux-gnu", Diags,
                           "clang LLVM compiler", prepareFS(ExtraFiles));

    std::vector<const char *> Args = {ClangBinary};
    for (const auto &A : ExtraArgs)
      Args.push_back(A.c_str());
    Args.push_back("-c");
    Args.push_back(InputFile);

    CompilationJob.reset(DriverInstance->BuildCompilation(Args));

    if (Diags.hasErrorOccurred())
      ADD_FAILURE() << "Error occurred while parsing compilation arguments. "
                       "See stderr for details.";

    const auto &Commands = CompilationJob->getJobs().getJobs();
    assert(Commands.size() == 1);
    return *Commands.front();
  }

private:
  llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem>
  prepareFS(llvm::ArrayRef<std::string> ExtraFiles) {
    auto FS = llvm::makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>();
    FS->addFile(ClangBinary, time_t(), llvm::MemoryBuffer::getMemBuffer(""));
    FS->addFile(InputFile, time_t(), llvm::MemoryBuffer::getMemBuffer(""));
    for (llvm::StringRef F : ExtraFiles)
      FS->addFile(F, time_t(), llvm::MemoryBuffer::getMemBuffer(""));
    return FS;
  }

  std::optional<Driver> DriverInstance;
  std::unique_ptr<driver::Compilation> CompilationJob;
};

TEST_F(SanitizerArgsTest, Ignorelists) {
  const std::string ResourceDir = "/opt/llvm/lib/resources";
  const std::string UserIgnorelist = "/source/my_ignorelist.txt";
  const std::string ASanIgnorelist =
      concatPaths({ResourceDir, "share", "asan_ignorelist.txt"});

  auto &Command = emulateSingleCompilation(
      /*ExtraArgs=*/{"-fsanitize=address", "-resource-dir", ResourceDir,
                     std::string("-fsanitize-ignorelist=") + UserIgnorelist},
      /*ExtraFiles=*/{ASanIgnorelist, UserIgnorelist});

  // System ignorelists are added based on resource-dir.
  EXPECT_THAT(Command.getArguments(),
              Contains(StrEq(std::string("-fsanitize-system-ignorelist=") +
                             ASanIgnorelist)));
  // User ignorelists should also be added.
  EXPECT_THAT(
      Command.getArguments(),
      Contains(StrEq(std::string("-fsanitize-ignorelist=") + UserIgnorelist)));
}

TEST_F(SanitizerArgsTest, XRayLists) {
  const std::string XRayAllowlist = "/source/xray_allowlist.txt";
  const std::string XRayIgnorelist = "/source/xray_ignorelist.txt";
  const std::string XRayAttrList = "/source/xray_attr_list.txt";

  auto &Command = emulateSingleCompilation(
      /*ExtraArgs=*/
      {
          "-fxray-instrument",
          "-fxray-always-instrument=" + XRayAllowlist,
          "-fxray-never-instrument=" + XRayIgnorelist,
          "-fxray-attr-list=" + XRayAttrList,
      },
      /*ExtraFiles=*/{XRayAllowlist, XRayIgnorelist, XRayAttrList});

  // Ignorelists exist in the filesystem, so they should be added to the
  // compilation command, produced by the driver.
  EXPECT_THAT(Command.getArguments(),
              Contains(StrEq("-fxray-always-instrument=" + XRayAllowlist)));
  EXPECT_THAT(Command.getArguments(),
              Contains(StrEq("-fxray-never-instrument=" + XRayIgnorelist)));
  EXPECT_THAT(Command.getArguments(),
              Contains(StrEq("-fxray-attr-list=" + XRayAttrList)));
}

} // namespace
