1 //===- unittests/Basic/DiagnosticTest.cpp -- Diagnostic engine tests ------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "clang/Basic/Diagnostic.h" 10 #include "clang/Basic/DiagnosticError.h" 11 #include "clang/Basic/DiagnosticIDs.h" 12 #include "gtest/gtest.h" 13 14 using namespace llvm; 15 using namespace clang; 16 17 void clang::DiagnosticsTestHelper(DiagnosticsEngine &diag) { 18 unsigned delayedDiagID = 0U; 19 20 EXPECT_EQ(diag.DelayedDiagID, delayedDiagID); 21 EXPECT_FALSE(diag.DiagStates.empty()); 22 EXPECT_TRUE(diag.DiagStatesByLoc.empty()); 23 EXPECT_TRUE(diag.DiagStateOnPushStack.empty()); 24 } 25 26 namespace { 27 28 // Check that DiagnosticErrorTrap works with SuppressAllDiagnostics. 29 TEST(DiagnosticTest, suppressAndTrap) { 30 DiagnosticsEngine Diags(new DiagnosticIDs(), 31 new DiagnosticOptions, 32 new IgnoringDiagConsumer()); 33 Diags.setSuppressAllDiagnostics(true); 34 35 { 36 DiagnosticErrorTrap trap(Diags); 37 38 // Diag that would set UncompilableErrorOccurred and ErrorOccurred. 39 Diags.Report(diag::err_target_unknown_triple) << "unknown"; 40 41 // Diag that would set UnrecoverableErrorOccurred and ErrorOccurred. 42 Diags.Report(diag::err_cannot_open_file) << "file" << "error"; 43 44 // Diag that would set FatalErrorOccurred 45 // (via non-note following a fatal error). 46 Diags.Report(diag::warn_mt_message) << "warning"; 47 48 EXPECT_TRUE(trap.hasErrorOccurred()); 49 EXPECT_TRUE(trap.hasUnrecoverableErrorOccurred()); 50 } 51 52 EXPECT_FALSE(Diags.hasErrorOccurred()); 53 EXPECT_FALSE(Diags.hasFatalErrorOccurred()); 54 EXPECT_FALSE(Diags.hasUncompilableErrorOccurred()); 55 EXPECT_FALSE(Diags.hasUnrecoverableErrorOccurred()); 56 } 57 58 // Check that FatalsAsError works as intended 59 TEST(DiagnosticTest, fatalsAsError) { 60 for (unsigned FatalsAsError = 0; FatalsAsError != 2; ++FatalsAsError) { 61 DiagnosticsEngine Diags(new DiagnosticIDs(), 62 new DiagnosticOptions, 63 new IgnoringDiagConsumer()); 64 Diags.setFatalsAsError(FatalsAsError); 65 66 // Diag that would set UnrecoverableErrorOccurred and ErrorOccurred. 67 Diags.Report(diag::err_cannot_open_file) << "file" << "error"; 68 69 // Diag that would set FatalErrorOccurred 70 // (via non-note following a fatal error). 71 Diags.Report(diag::warn_mt_message) << "warning"; 72 73 EXPECT_TRUE(Diags.hasErrorOccurred()); 74 EXPECT_EQ(Diags.hasFatalErrorOccurred(), FatalsAsError ? 0u : 1u); 75 EXPECT_TRUE(Diags.hasUncompilableErrorOccurred()); 76 EXPECT_TRUE(Diags.hasUnrecoverableErrorOccurred()); 77 78 // The warning should be emitted and counted only if we're not suppressing 79 // after fatal errors. 80 EXPECT_EQ(Diags.getNumWarnings(), FatalsAsError); 81 } 82 } 83 84 // Check that soft RESET works as intended 85 TEST(DiagnosticTest, softReset) { 86 DiagnosticsEngine Diags(new DiagnosticIDs(), new DiagnosticOptions, 87 new IgnoringDiagConsumer()); 88 89 unsigned numWarnings = 0U, numErrors = 0U; 90 91 Diags.Reset(true); 92 // Check For ErrorOccurred and TrapNumErrorsOccurred 93 EXPECT_FALSE(Diags.hasErrorOccurred()); 94 EXPECT_FALSE(Diags.hasFatalErrorOccurred()); 95 EXPECT_FALSE(Diags.hasUncompilableErrorOccurred()); 96 // Check for UnrecoverableErrorOccurred and TrapNumUnrecoverableErrorsOccurred 97 EXPECT_FALSE(Diags.hasUnrecoverableErrorOccurred()); 98 99 EXPECT_EQ(Diags.getNumWarnings(), numWarnings); 100 EXPECT_EQ(Diags.getNumErrors(), numErrors); 101 102 // Check for private variables of DiagnosticsEngine differentiating soft reset 103 DiagnosticsTestHelper(Diags); 104 105 EXPECT_FALSE(Diags.isDiagnosticInFlight()); 106 EXPECT_TRUE(Diags.isLastDiagnosticIgnored()); 107 } 108 109 TEST(DiagnosticTest, diagnosticError) { 110 DiagnosticsEngine Diags(new DiagnosticIDs(), new DiagnosticOptions, 111 new IgnoringDiagConsumer()); 112 PartialDiagnostic::DiagStorageAllocator Alloc; 113 llvm::Expected<std::pair<int, int>> Value = DiagnosticError::create( 114 SourceLocation(), PartialDiagnostic(diag::err_cannot_open_file, Alloc) 115 << "file" 116 << "error"); 117 ASSERT_TRUE(!Value); 118 llvm::Error Err = Value.takeError(); 119 Optional<PartialDiagnosticAt> ErrDiag = DiagnosticError::take(Err); 120 llvm::cantFail(std::move(Err)); 121 ASSERT_FALSE(!ErrDiag); 122 EXPECT_EQ(ErrDiag->first, SourceLocation()); 123 EXPECT_EQ(ErrDiag->second.getDiagID(), diag::err_cannot_open_file); 124 125 Value = std::make_pair(20, 1); 126 ASSERT_FALSE(!Value); 127 EXPECT_EQ(*Value, std::make_pair(20, 1)); 128 EXPECT_EQ(Value->first, 20); 129 } 130 } 131