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 @@ -394,6 +394,13 @@ } } + // There is a chance that begin or end is invalid here, for example if + // specific compile error is reported. + // It is possible that the FileID's do not match, if one comes from an + // included file. In this case we can not produce a meaningful source range. + if (Begin.isInvalid() || End.isInvalid() || BeginFileID != EndFileID) + continue; + // Do the backtracking. SmallVector CommonArgExpansions; computeCommonMacroArgExpansionFileIDs(Begin, End, SM, CommonArgExpansions); diff --git a/clang/test/Analysis/copypaste/Inputs/clone-begin-end-different-file-begin-1.inc b/clang/test/Analysis/copypaste/Inputs/clone-begin-end-different-file-begin-1.inc new file mode 100644 --- /dev/null +++ b/clang/test/Analysis/copypaste/Inputs/clone-begin-end-different-file-begin-1.inc @@ -0,0 +1 @@ +while (i == 10) // expected-warning{{Duplicate code detected}} diff --git a/clang/test/Analysis/copypaste/Inputs/clone-begin-end-different-file-begin-2.inc b/clang/test/Analysis/copypaste/Inputs/clone-begin-end-different-file-begin-2.inc new file mode 100644 --- /dev/null +++ b/clang/test/Analysis/copypaste/Inputs/clone-begin-end-different-file-begin-2.inc @@ -0,0 +1 @@ +while (i == 10) // expected-note{{Similar code here}} diff --git a/clang/test/Analysis/copypaste/Inputs/clone-begin-end-different-file-begin-macro-1.inc b/clang/test/Analysis/copypaste/Inputs/clone-begin-end-different-file-begin-macro-1.inc new file mode 100644 --- /dev/null +++ b/clang/test/Analysis/copypaste/Inputs/clone-begin-end-different-file-begin-macro-1.inc @@ -0,0 +1 @@ +X // expected-warning{{Duplicate code detected}} diff --git a/clang/test/Analysis/copypaste/Inputs/clone-begin-end-different-file-begin-macro-2.inc b/clang/test/Analysis/copypaste/Inputs/clone-begin-end-different-file-begin-macro-2.inc new file mode 100644 --- /dev/null +++ b/clang/test/Analysis/copypaste/Inputs/clone-begin-end-different-file-begin-macro-2.inc @@ -0,0 +1 @@ +X // expected-note{{Similar code here}} diff --git a/clang/test/Analysis/copypaste/Inputs/clone-begin-end-different-file-end-macro.inc b/clang/test/Analysis/copypaste/Inputs/clone-begin-end-different-file-end-macro.inc new file mode 100644 --- /dev/null +++ b/clang/test/Analysis/copypaste/Inputs/clone-begin-end-different-file-end-macro.inc @@ -0,0 +1 @@ +X diff --git a/clang/test/Analysis/copypaste/Inputs/clone-begin-end-different-file-end.inc b/clang/test/Analysis/copypaste/Inputs/clone-begin-end-different-file-end.inc new file mode 100644 --- /dev/null +++ b/clang/test/Analysis/copypaste/Inputs/clone-begin-end-different-file-end.inc @@ -0,0 +1 @@ +while (true) {} diff --git a/clang/test/Analysis/copypaste/clone-begin-end-different-file.cpp b/clang/test/Analysis/copypaste/clone-begin-end-different-file.cpp new file mode 100644 --- /dev/null +++ b/clang/test/Analysis/copypaste/clone-begin-end-different-file.cpp @@ -0,0 +1,37 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=5 -verify %s + +// This test should verify that there is no crash if the detected clone range +// starts in a file and ends in a different file. + +void f_end(int i) { + if (i == 10) // expected-warning{{Duplicate code detected}} +#include "Inputs/clone-begin-end-different-file-end.inc" + if (i == 10) // expected-note{{Similar code here}} +#include "Inputs/clone-begin-end-different-file-end.inc" +} + +void f_begin(int i) { +#include "Inputs/clone-begin-end-different-file-begin-1.inc" + if (true) {} +#include "Inputs/clone-begin-end-different-file-begin-2.inc" + if (true) {} +} + +#define X while (true) {} + +void f1m(int i) { + if (i == 10) // expected-warning{{Duplicate code detected}} +#include "Inputs/clone-begin-end-different-file-end-macro.inc" + if (i == 10) // expected-note{{Similar code here}} +#include "Inputs/clone-begin-end-different-file-end-macro.inc" +} + +#undef X +#define X if (i == 10) + +void f2m(int i) { +#include "Inputs/clone-begin-end-different-file-begin-macro-1.inc" + while (true) { i = 1; } +#include "Inputs/clone-begin-end-different-file-begin-macro-2.inc" + while (true) { i = 1; } +} diff --git a/clang/test/Frontend/crash-diagnostic-renderer.cpp b/clang/test/Frontend/crash-diagnostic-renderer.cpp new file mode 100644 --- /dev/null +++ b/clang/test/Frontend/crash-diagnostic-renderer.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -verify %s + +// This case reproduces a problem that is shown here: +// https://bugs.llvm.org/show_bug.cgi?id=46540 +// No assertion should happen during printing of diagnostic messages. + +// expected-error@13{{'b' does not refer to a type name in pseudo-destructor expression; expected the name of type 'volatile long'}} +// expected-error@13{{expected ')'}} +// expected-note@13{{to match this '('}} +// expected-error@13{{reference to pseudo-destructor must be called; did you mean to call it with no arguments?}} +// expected-error@13{{cannot initialize a variable of type 'volatile long' with an rvalue of type 'void'}} +// expected-error@13{{expected ';' after top level declarator}} +volatile long a ( a .~b