//===- unittests/Basic/DiagnosticTest.cpp -- Diagnostic engine tests ------===//
//
// 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/DiagnosticError.h"
#include "clang/Basic/DiagnosticIDs.h"
#include "clang/Basic/DiagnosticLex.h"
#include "clang/Basic/DiagnosticSema.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <memory>
#include <optional>
#include <vector>

using namespace llvm;
using namespace clang;

// Declare DiagnosticsTestHelper to avoid GCC warning
namespace clang {
void DiagnosticsTestHelper(DiagnosticsEngine &diag);
}

void clang::DiagnosticsTestHelper(DiagnosticsEngine &diag) {
  EXPECT_FALSE(diag.DiagStates.empty());
  EXPECT_TRUE(diag.DiagStatesByLoc.empty());
  EXPECT_TRUE(diag.DiagStateOnPushStack.empty());
}

namespace {
using testing::AllOf;
using testing::ElementsAre;
using testing::IsEmpty;

// Check that DiagnosticErrorTrap works with SuppressAllDiagnostics.
TEST(DiagnosticTest, suppressAndTrap) {
  DiagnosticOptions DiagOpts;
  DiagnosticsEngine Diags(new DiagnosticIDs(), DiagOpts,
                          new IgnoringDiagConsumer());
  Diags.setSuppressAllDiagnostics(true);

  {
    DiagnosticErrorTrap trap(Diags);

    // Diag that would set UncompilableErrorOccurred and ErrorOccurred.
    Diags.Report(diag::err_target_unknown_triple) << "unknown";

    // Diag that would set UnrecoverableErrorOccurred and ErrorOccurred.
    Diags.Report(diag::err_cannot_open_file) << "file" << "error";

    // Diag that would set FatalErrorOccurred
    // (via non-note following a fatal error).
    Diags.Report(diag::warn_apinotes_message) << "warning";

    EXPECT_TRUE(trap.hasErrorOccurred());
    EXPECT_TRUE(trap.hasUnrecoverableErrorOccurred());
  }

  EXPECT_FALSE(Diags.hasErrorOccurred());
  EXPECT_FALSE(Diags.hasFatalErrorOccurred());
  EXPECT_FALSE(Diags.hasUncompilableErrorOccurred());
  EXPECT_FALSE(Diags.hasUnrecoverableErrorOccurred());
}

// Check that FatalsAsError works as intended
TEST(DiagnosticTest, fatalsAsError) {
  for (unsigned FatalsAsError = 0; FatalsAsError != 2; ++FatalsAsError) {
    DiagnosticOptions DiagOpts;
    DiagnosticsEngine Diags(new DiagnosticIDs(), DiagOpts,
                            new IgnoringDiagConsumer());
    Diags.setFatalsAsError(FatalsAsError);

    // Diag that would set UnrecoverableErrorOccurred and ErrorOccurred.
    Diags.Report(diag::err_cannot_open_file) << "file" << "error";

    // Diag that would set FatalErrorOccurred
    // (via non-note following a fatal error).
    Diags.Report(diag::warn_apinotes_message) << "warning";

    EXPECT_TRUE(Diags.hasErrorOccurred());
    EXPECT_EQ(Diags.hasFatalErrorOccurred(), FatalsAsError ? 0u : 1u);
    EXPECT_TRUE(Diags.hasUncompilableErrorOccurred());
    EXPECT_TRUE(Diags.hasUnrecoverableErrorOccurred());

    // The warning should be emitted and counted only if we're not suppressing
    // after fatal errors.
    EXPECT_EQ(Diags.getNumWarnings(), FatalsAsError);
  }
}

TEST(DiagnosticTest, tooManyErrorsIsAlwaysFatal) {
  DiagnosticOptions DiagOpts;
  DiagnosticsEngine Diags(new DiagnosticIDs(), DiagOpts,
                          new IgnoringDiagConsumer());
  Diags.setFatalsAsError(true);

  // Report a fatal_too_many_errors diagnostic to ensure that still
  // acts as a fatal error despite downgrading fatal errors to errors.
  Diags.Report(diag::fatal_too_many_errors);
  EXPECT_TRUE(Diags.hasFatalErrorOccurred());

  // Ensure that the severity of that diagnostic is really "fatal".
  EXPECT_EQ(Diags.getDiagnosticLevel(diag::fatal_too_many_errors, {}),
            DiagnosticsEngine::Level::Fatal);
}

// Check that soft RESET works as intended
TEST(DiagnosticTest, softReset) {
  DiagnosticOptions DiagOpts;
  DiagnosticsEngine Diags(new DiagnosticIDs(), DiagOpts,
                          new IgnoringDiagConsumer());

  unsigned numWarnings = 0U, numErrors = 0U;

  Diags.Reset(true);
  // Check For ErrorOccurred and TrapNumErrorsOccurred
  EXPECT_FALSE(Diags.hasErrorOccurred());
  EXPECT_FALSE(Diags.hasFatalErrorOccurred());
  EXPECT_FALSE(Diags.hasUncompilableErrorOccurred());
  // Check for UnrecoverableErrorOccurred and TrapNumUnrecoverableErrorsOccurred
  EXPECT_FALSE(Diags.hasUnrecoverableErrorOccurred());

  EXPECT_EQ(Diags.getNumWarnings(), numWarnings);
  EXPECT_EQ(Diags.getNumErrors(), numErrors);

  // Check for private variables of DiagnosticsEngine differentiating soft reset
  DiagnosticsTestHelper(Diags);

  EXPECT_TRUE(Diags.isLastDiagnosticIgnored());
}

TEST(DiagnosticTest, diagnosticError) {
  DiagnosticOptions DiagOpts;
  DiagnosticsEngine Diags(new DiagnosticIDs(), DiagOpts,
                          new IgnoringDiagConsumer());
  PartialDiagnostic::DiagStorageAllocator Alloc;
  llvm::Expected<std::pair<int, int>> Value = DiagnosticError::create(
      SourceLocation(), PartialDiagnostic(diag::err_cannot_open_file, Alloc)
                            << "file"
                            << "error");
  ASSERT_TRUE(!Value);
  llvm::Error Err = Value.takeError();
  std::optional<PartialDiagnosticAt> ErrDiag = DiagnosticError::take(Err);
  llvm::cantFail(std::move(Err));
  ASSERT_FALSE(!ErrDiag);
  EXPECT_EQ(ErrDiag->first, SourceLocation());
  EXPECT_EQ(ErrDiag->second.getDiagID(), diag::err_cannot_open_file);

  Value = std::make_pair(20, 1);
  ASSERT_FALSE(!Value);
  EXPECT_EQ(*Value, std::make_pair(20, 1));
  EXPECT_EQ(Value->first, 20);
}

TEST(DiagnosticTest, storedDiagEmptyWarning) {
  DiagnosticOptions DiagOpts;
  DiagnosticsEngine Diags(new DiagnosticIDs(), DiagOpts);

  class CaptureDiagnosticConsumer : public DiagnosticConsumer {
  public:
    SmallVector<StoredDiagnostic> StoredDiags;

    void HandleDiagnostic(DiagnosticsEngine::Level level,
                          const Diagnostic &Info) override {
      StoredDiags.push_back(StoredDiagnostic(level, Info));
    }
  };

  CaptureDiagnosticConsumer CaptureConsumer;
  Diags.setClient(&CaptureConsumer, /*ShouldOwnClient=*/false);
  Diags.Report(diag::pp_hash_warning) << "";
  ASSERT_TRUE(CaptureConsumer.StoredDiags.size() == 1);

  // Make sure an empty warning can round-trip with \c StoredDiagnostic.
  Diags.Report(CaptureConsumer.StoredDiags.front());
}

class SuppressionMappingTest : public testing::Test {
public:
  SuppressionMappingTest() {
    Diags.setClient(&CaptureConsumer, /*ShouldOwnClient=*/false);
  }

protected:
  llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> FS =
      llvm::makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>();
  DiagnosticOptions DiagOpts;
  DiagnosticsEngine Diags{new DiagnosticIDs(), DiagOpts};

  llvm::ArrayRef<StoredDiagnostic> diags() {
    return CaptureConsumer.StoredDiags;
  }

  SourceLocation locForFile(llvm::StringRef FileName) {
    auto Buf = MemoryBuffer::getMemBuffer("", FileName);
    SourceManager &SM = Diags.getSourceManager();
    FileID FooID = SM.createFileID(std::move(Buf));
    return SM.getLocForStartOfFile(FooID);
  }

private:
  FileManager FM{{}, FS};
  SourceManager SM{Diags, FM};

  class CaptureDiagnosticConsumer : public DiagnosticConsumer {
  public:
    std::vector<StoredDiagnostic> StoredDiags;

    void HandleDiagnostic(DiagnosticsEngine::Level level,
                          const Diagnostic &Info) override {
      StoredDiags.push_back(StoredDiagnostic(level, Info));
    }
  };
  CaptureDiagnosticConsumer CaptureConsumer;
};

MATCHER_P(WithMessage, Msg, "has diagnostic message") {
  return arg.getMessage() == Msg;
}
MATCHER(IsError, "has error severity") {
  return arg.getLevel() == DiagnosticsEngine::Level::Error;
}

TEST_F(SuppressionMappingTest, MissingMappingFile) {
  Diags.getDiagnosticOptions().DiagnosticSuppressionMappingsFile = "foo.txt";
  clang::ProcessWarningOptions(Diags, Diags.getDiagnosticOptions(), *FS);
  EXPECT_THAT(diags(), ElementsAre(AllOf(
                           WithMessage("no such file or directory: 'foo.txt'"),
                           IsError())));
}

TEST_F(SuppressionMappingTest, MalformedFile) {
  Diags.getDiagnosticOptions().DiagnosticSuppressionMappingsFile = "foo.txt";
  FS->addFile("foo.txt", /*ModificationTime=*/{},
              llvm::MemoryBuffer::getMemBuffer("asdf", "foo.txt"));
  clang::ProcessWarningOptions(Diags, Diags.getDiagnosticOptions(), *FS);
  EXPECT_THAT(diags(),
              ElementsAre(AllOf(
                  WithMessage("failed to process suppression mapping file "
                              "'foo.txt': malformed line 1: 'asdf'"),
                  IsError())));
}

TEST_F(SuppressionMappingTest, UnknownDiagName) {
  Diags.getDiagnosticOptions().DiagnosticSuppressionMappingsFile = "foo.txt";
  FS->addFile("foo.txt", /*ModificationTime=*/{},
              llvm::MemoryBuffer::getMemBuffer("[non-existing-warning]"));
  clang::ProcessWarningOptions(Diags, Diags.getDiagnosticOptions(), *FS);
  EXPECT_THAT(diags(), ElementsAre(WithMessage(
                           "unknown warning option 'non-existing-warning'")));
}

TEST_F(SuppressionMappingTest, SuppressesGroup) {
  llvm::StringLiteral SuppressionMappingFile = R"(
  [unused]
  src:*)";
  Diags.getDiagnosticOptions().DiagnosticSuppressionMappingsFile = "foo.txt";
  FS->addFile("foo.txt", /*ModificationTime=*/{},
              llvm::MemoryBuffer::getMemBuffer(SuppressionMappingFile));
  clang::ProcessWarningOptions(Diags, Diags.getDiagnosticOptions(), *FS);
  EXPECT_THAT(diags(), IsEmpty());

  SourceLocation FooLoc = locForFile("foo.cpp");
  EXPECT_TRUE(Diags.isSuppressedViaMapping(diag::warn_unused_function, FooLoc));
  EXPECT_FALSE(Diags.isSuppressedViaMapping(diag::warn_deprecated, FooLoc));
}

TEST_F(SuppressionMappingTest, EmitCategoryIsExcluded) {
  llvm::StringLiteral SuppressionMappingFile = R"(
  [unused]
  src:*
  src:*foo.cpp=emit)";
  Diags.getDiagnosticOptions().DiagnosticSuppressionMappingsFile = "foo.txt";
  FS->addFile("foo.txt", /*ModificationTime=*/{},
              llvm::MemoryBuffer::getMemBuffer(SuppressionMappingFile));
  clang::ProcessWarningOptions(Diags, Diags.getDiagnosticOptions(), *FS);
  EXPECT_THAT(diags(), IsEmpty());

  EXPECT_TRUE(Diags.isSuppressedViaMapping(diag::warn_unused_function,
                                           locForFile("bar.cpp")));
  EXPECT_FALSE(Diags.isSuppressedViaMapping(diag::warn_unused_function,
                                            locForFile("foo.cpp")));
}

TEST_F(SuppressionMappingTest, LongestMatchWins) {
  llvm::StringLiteral SuppressionMappingFile = R"(
  [unused]
  src:*clang/*
  src:*clang/lib/Sema/*=emit
  src:*clang/lib/Sema/foo*)";
  Diags.getDiagnosticOptions().DiagnosticSuppressionMappingsFile = "foo.txt";
  FS->addFile("foo.txt", /*ModificationTime=*/{},
              llvm::MemoryBuffer::getMemBuffer(SuppressionMappingFile));
  clang::ProcessWarningOptions(Diags, Diags.getDiagnosticOptions(), *FS);
  EXPECT_THAT(diags(), IsEmpty());

  EXPECT_TRUE(Diags.isSuppressedViaMapping(
      diag::warn_unused_function, locForFile("clang/lib/Basic/foo.h")));
  EXPECT_FALSE(Diags.isSuppressedViaMapping(
      diag::warn_unused_function, locForFile("clang/lib/Sema/bar.h")));
  EXPECT_TRUE(Diags.isSuppressedViaMapping(diag::warn_unused_function,
                                           locForFile("clang/lib/Sema/foo.h")));
}

TEST_F(SuppressionMappingTest, IsIgnored) {
  llvm::StringLiteral SuppressionMappingFile = R"(
  [unused]
  src:*clang/*)";
  Diags.getDiagnosticOptions().DiagnosticSuppressionMappingsFile = "foo.txt";
  Diags.getDiagnosticOptions().Warnings = {"unused"};
  FS->addFile("foo.txt", /*ModificationTime=*/{},
              llvm::MemoryBuffer::getMemBuffer(SuppressionMappingFile));
  clang::ProcessWarningOptions(Diags, Diags.getDiagnosticOptions(), *FS);
  ASSERT_THAT(diags(), IsEmpty());

  SourceManager &SM = Diags.getSourceManager();
  auto ClangID =
      SM.createFileID(llvm::MemoryBuffer::getMemBuffer("", "clang/foo.h"));
  auto NonClangID =
      SM.createFileID(llvm::MemoryBuffer::getMemBuffer("", "llvm/foo.h"));
  auto PresumedClangID =
      SM.createFileID(llvm::MemoryBuffer::getMemBuffer("", "llvm/foo2.h"));
  // Add a line directive to point into clang/foo.h
  SM.AddLineNote(SM.getLocForStartOfFile(PresumedClangID), 42,
                 SM.getLineTableFilenameID("clang/foo.h"), false, false,
                 clang::SrcMgr::C_User);

  EXPECT_TRUE(Diags.isIgnored(diag::warn_unused_function,
                              SM.getLocForStartOfFile(ClangID)));
  EXPECT_FALSE(Diags.isIgnored(diag::warn_unused_function,
                               SM.getLocForStartOfFile(NonClangID)));
  EXPECT_TRUE(Diags.isIgnored(diag::warn_unused_function,
                              SM.getLocForStartOfFile(PresumedClangID)));

  // Pretend we have a clang-diagnostic pragma to enforce the warning. Make sure
  // suppressing mapping doesn't take over.
  Diags.setSeverity(diag::warn_unused_function, diag::Severity::Error,
                    SM.getLocForStartOfFile(ClangID));
  EXPECT_FALSE(Diags.isIgnored(diag::warn_unused_function,
                               SM.getLocForStartOfFile(ClangID)));
}

TEST_F(SuppressionMappingTest, ParsingRespectsOtherWarningOpts) {
  Diags.getDiagnosticOptions().DiagnosticSuppressionMappingsFile = "foo.txt";
  FS->addFile("foo.txt", /*ModificationTime=*/{},
              llvm::MemoryBuffer::getMemBuffer("[non-existing-warning]"));
  Diags.getDiagnosticOptions().Warnings.push_back("no-unknown-warning-option");
  clang::ProcessWarningOptions(Diags, Diags.getDiagnosticOptions(), *FS);
  EXPECT_THAT(diags(), IsEmpty());
}
} // namespace
