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 
DiagnosticsTestHelper(DiagnosticsEngine & diag)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.
TEST(DiagnosticTest,suppressAndTrap)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
TEST(DiagnosticTest,fatalsAsError)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
TEST(DiagnosticTest,softReset)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 
TEST(DiagnosticTest,diagnosticError)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