diff --git a/clang/lib/Frontend/DiagnosticRenderer.cpp b/clang/lib/Frontend/DiagnosticRenderer.cpp --- a/clang/lib/Frontend/DiagnosticRenderer.cpp +++ b/clang/lib/Frontend/DiagnosticRenderer.cpp @@ -167,6 +167,10 @@ PLoc.isInvalid() ? FullSourceLoc() : FullSourceLoc(PLoc.getIncludeLoc(), Loc.getManager()); + // Reset `LastIncludeLoc` on a new error so that the include stacks are + // not skipped. + if (Level == DiagnosticsEngine::Error) + LastIncludeLoc = SourceLocation(); // Skip redundant include stacks altogether. if (LastIncludeLoc == IncludeLoc) return; diff --git a/clang/test/Misc/Inputs/include-stack-on-error-1.h b/clang/test/Misc/Inputs/include-stack-on-error-1.h new file mode 100644 --- /dev/null +++ b/clang/test/Misc/Inputs/include-stack-on-error-1.h @@ -0,0 +1,2 @@ +void b1(); +template void b2(T x, T y) { x + y; } diff --git a/clang/test/Misc/Inputs/include-stack-on-error-2.h b/clang/test/Misc/Inputs/include-stack-on-error-2.h new file mode 100644 --- /dev/null +++ b/clang/test/Misc/Inputs/include-stack-on-error-2.h @@ -0,0 +1,4 @@ +void c() { + b1(0); + b2("0", "0"); +} diff --git a/clang/test/Misc/Inputs/include-stack-on-error-3.h b/clang/test/Misc/Inputs/include-stack-on-error-3.h new file mode 100644 --- /dev/null +++ b/clang/test/Misc/Inputs/include-stack-on-error-3.h @@ -0,0 +1,5 @@ +void b1(); +void c() { + b1(0); + b2("0", "0"); +} diff --git a/clang/test/Misc/include-stack-on-error-1.cpp b/clang/test/Misc/include-stack-on-error-1.cpp new file mode 100644 --- /dev/null +++ b/clang/test/Misc/include-stack-on-error-1.cpp @@ -0,0 +1,24 @@ +// Test duplicate include stacks on a new error are not skipped. +// RUN: not %clang_cc1 -fsyntax-only -I %S/Inputs %s 2>&1 | FileCheck %s -check-prefix=STACK +// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-show-note-include-stack -I %S/Inputs %s 2>&1 | FileCheck %s -check-prefix=NOTESTACK + +#include "include-stack-on-error-1.h" +#include "include-stack-on-error-2.h" + +// STACK: In file included from +// STACK: error: no matching function for call to 'b1' +// STACK-NOT: In file included from +// STACK: note: candidate function not viable +// STACK: In file included from +// STACK: error: invalid operands to binary expression +// STACK-NOT: In file included from +// STACK: note: in instantiation of function template specialization + +// NOTESTACK: In file included from +// NOTESTACK: error: no matching function for call to 'b1' +// NOTESTACK: In file included from +// NOTESTACK: note: candidate function not viable +// NOTESTACK: In file included from +// NOTESTACK: error: invalid operands to binary expression +// NOTESTACK: In file included from +// NOTESTACK: note: in instantiation of function template specialization diff --git a/clang/test/Misc/include-stack-on-error-2.cpp b/clang/test/Misc/include-stack-on-error-2.cpp new file mode 100644 --- /dev/null +++ b/clang/test/Misc/include-stack-on-error-2.cpp @@ -0,0 +1,15 @@ +// Test duplicate include stacks that are not on a new error are skipped. +// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-show-note-include-stack -I %S/Inputs %s 2>&1 | FileCheck %s -check-prefix=NOTESTACK + +#include "include-stack-on-error-1.h" +#include "include-stack-on-error-3.h" + +// NOTESTACK: In file included from +// NOTESTACK: error: no matching function for call to 'b1' +// This include should be skipped due to duplicate include location. +// NOTESTACK-NOT: In file included from +// NOTESTACK: note: candidate function not viable +// NOTESTACK: In file included from +// NOTESTACK: error: invalid operands to binary expression +// NOTESTACK: In file included from +// NOTESTACK: note: in instantiation of function template specialization