[clang] 085dcc8 - [clang][Frontend] Fix a crash in DiagnosticRenderer.

Balázs Kéri via cfe-commits cfe-commits at lists.llvm.org
Tue Feb 16 23:53:44 PST 2021


Author: Balázs Kéri
Date: 2021-02-17T09:02:49+01:00
New Revision: 085dcc82178f94b99783c5730e70a953e4105c00

URL: https://github.com/llvm/llvm-project/commit/085dcc82178f94b99783c5730e70a953e4105c00
DIFF: https://github.com/llvm/llvm-project/commit/085dcc82178f94b99783c5730e70a953e4105c00.diff

LOG: [clang][Frontend] Fix a crash in DiagnosticRenderer.

Displaying the problem range could crash if the begin and end of a
range is in different files or macros. After the change such range
is displayed only as the beginning location.

There is a bug for this problem:
https://bugs.llvm.org/show_bug.cgi?id=46540

Reviewed By: steakhal

Differential Revision: https://reviews.llvm.org/D95860

Added: 
    clang/test/Analysis/copypaste/Inputs/clone-begin-end-different-file-begin-1.inc
    clang/test/Analysis/copypaste/Inputs/clone-begin-end-different-file-begin-2.inc
    clang/test/Analysis/copypaste/Inputs/clone-begin-end-different-file-begin-macro-1.inc
    clang/test/Analysis/copypaste/Inputs/clone-begin-end-different-file-begin-macro-2.inc
    clang/test/Analysis/copypaste/Inputs/clone-begin-end-different-file-end-macro.inc
    clang/test/Analysis/copypaste/Inputs/clone-begin-end-different-file-end.inc
    clang/test/Analysis/copypaste/clone-begin-end-different-file.cpp
    clang/test/Frontend/crash-diagnostic-renderer.cpp

Modified: 
    clang/lib/Frontend/DiagnosticRenderer.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Frontend/DiagnosticRenderer.cpp b/clang/lib/Frontend/DiagnosticRenderer.cpp
index 22b957988f46..0afc8f3b1dab 100644
--- a/clang/lib/Frontend/DiagnosticRenderer.cpp
+++ b/clang/lib/Frontend/DiagnosticRenderer.cpp
@@ -394,6 +394,13 @@ mapDiagnosticRanges(FullSourceLoc CaretLoc, ArrayRef<CharSourceRange> Ranges,
       }
     }
 
+    // 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<FileID, 4> CommonArgExpansions;
     computeCommonMacroArgExpansionFileIDs(Begin, End, SM, CommonArgExpansions);

diff  --git a/clang/test/Analysis/copypaste/Inputs/clone-begin-end-
diff erent-file-begin-1.inc b/clang/test/Analysis/copypaste/Inputs/clone-begin-end-
diff erent-file-begin-1.inc
new file mode 100644
index 000000000000..a6b44fd87073
--- /dev/null
+++ b/clang/test/Analysis/copypaste/Inputs/clone-begin-end-
diff erent-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-
diff erent-file-begin-2.inc b/clang/test/Analysis/copypaste/Inputs/clone-begin-end-
diff erent-file-begin-2.inc
new file mode 100644
index 000000000000..7aa4a3dcdc86
--- /dev/null
+++ b/clang/test/Analysis/copypaste/Inputs/clone-begin-end-
diff erent-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-
diff erent-file-begin-macro-1.inc b/clang/test/Analysis/copypaste/Inputs/clone-begin-end-
diff erent-file-begin-macro-1.inc
new file mode 100644
index 000000000000..76637bbd8733
--- /dev/null
+++ b/clang/test/Analysis/copypaste/Inputs/clone-begin-end-
diff erent-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-
diff erent-file-begin-macro-2.inc b/clang/test/Analysis/copypaste/Inputs/clone-begin-end-
diff erent-file-begin-macro-2.inc
new file mode 100644
index 000000000000..9f03aeac4e83
--- /dev/null
+++ b/clang/test/Analysis/copypaste/Inputs/clone-begin-end-
diff erent-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-
diff erent-file-end-macro.inc b/clang/test/Analysis/copypaste/Inputs/clone-begin-end-
diff erent-file-end-macro.inc
new file mode 100644
index 000000000000..62d8fe9f6db6
--- /dev/null
+++ b/clang/test/Analysis/copypaste/Inputs/clone-begin-end-
diff erent-file-end-macro.inc
@@ -0,0 +1 @@
+X

diff  --git a/clang/test/Analysis/copypaste/Inputs/clone-begin-end-
diff erent-file-end.inc b/clang/test/Analysis/copypaste/Inputs/clone-begin-end-
diff erent-file-end.inc
new file mode 100644
index 000000000000..1fa180e56531
--- /dev/null
+++ b/clang/test/Analysis/copypaste/Inputs/clone-begin-end-
diff erent-file-end.inc
@@ -0,0 +1 @@
+while (true) {}

diff  --git a/clang/test/Analysis/copypaste/clone-begin-end-
diff erent-file.cpp b/clang/test/Analysis/copypaste/clone-begin-end-
diff erent-file.cpp
new file mode 100644
index 000000000000..a5f1b668feff
--- /dev/null
+++ b/clang/test/Analysis/copypaste/clone-begin-end-
diff erent-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 
diff erent file.
+
+void f_end(int i) {
+  if (i == 10) // expected-warning{{Duplicate code detected}}
+#include "Inputs/clone-begin-end-
diff erent-file-end.inc"
+  if (i == 10) // expected-note{{Similar code here}}
+#include "Inputs/clone-begin-end-
diff erent-file-end.inc"
+}
+
+void f_begin(int i) {
+#include "Inputs/clone-begin-end-
diff erent-file-begin-1.inc"
+    if (true) {}
+#include "Inputs/clone-begin-end-
diff erent-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-
diff erent-file-end-macro.inc"
+  if (i == 10) // expected-note{{Similar code here}}
+#include "Inputs/clone-begin-end-
diff erent-file-end-macro.inc"
+}
+
+#undef X
+#define X if (i == 10)
+
+void f2m(int i) {
+#include "Inputs/clone-begin-end-
diff erent-file-begin-macro-1.inc"
+    while (true) { i = 1; }
+#include "Inputs/clone-begin-end-
diff erent-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
index 000000000000..8bf17a3170db
--- /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 at 13{{'b' does not refer to a type name in pseudo-destructor expression; expected the name of type 'volatile long'}}
+// expected-error at 13{{expected ')'}}
+// expected-note at 13{{to match this '('}}
+// expected-error at 13{{reference to pseudo-destructor must be called; did you mean to call it with no arguments?}}
+// expected-error at 13{{cannot initialize a variable of type 'volatile long' with an rvalue of type 'void'}}
+// expected-error at 13{{expected ';' after top level declarator}}
+volatile long a ( a .~b


        


More information about the cfe-commits mailing list