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