Skip to content

Commit 01929d4

Browse files
authored
Merge pull request github#8526 from MathiasVP/internal-diagmetric-queries-ql
C++: Add internal `ExtractionError` query
2 parents efc0d95 + 5cbd865 commit 01929d4

File tree

3 files changed

+159
-0
lines changed

3 files changed

+159
-0
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* @name Extraction errors
3+
* @description List all extraction errors for files in the source code directory.
4+
* @kind diagnostic
5+
* @id cpp/diagnostics/extraction-errors
6+
*/
7+
8+
import cpp
9+
import ExtractionErrors
10+
11+
// NOTE:
12+
// This file looks like the other `diagnostics/extraction-errors` queries in other CodeQL supported
13+
// languages. However, since this diagnostic query is located in the `Internal` subdirectory it will not
14+
// appear in the Code Scanning suite. The related query `cpp/diagnostics/extraction-warnings` is,
15+
// however, included as a public diagnostics query.
16+
from ExtractionError error
17+
where
18+
error instanceof ExtractionUnknownError or
19+
exists(error.getFile().getRelativePath())
20+
select error, "Extraction failed in " + error.getFile() + " with error " + error.getErrorMessage(),
21+
error.getSeverity()
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
/**
2+
* Provides a common hierarchy of all types of errors that can occur during extraction.
3+
*/
4+
5+
import cpp
6+
7+
/*
8+
* A note about how the C/C++ extractor emits diagnostics:
9+
* When the extractor frontend encounters an error, it emits a diagnostic message,
10+
* that includes a message, location and severity.
11+
* However, that process is best-effort and may fail (e.g. due to lack of memory).
12+
* Thus, if the extractor emitted at least one diagnostic of severity discretionary
13+
* error (or higher), it *also* emits a simple "There was an error during this compilation"
14+
* error diagnostic, without location information.
15+
* In the common case, this means that a compilation during which one or more errors happened also gets
16+
* the catch-all diagnostic.
17+
* This diagnostic has the empty string as file path.
18+
* We filter out these useless diagnostics if there is at least one error-level diagnostic
19+
* for the affected compilation in the database.
20+
* Otherwise, we show it to indicate that something went wrong and that we
21+
* don't know what exactly happened.
22+
*/
23+
24+
/**
25+
* An error that, if present, leads to a file being marked as non-successfully extracted.
26+
*/
27+
class ReportableError extends Diagnostic {
28+
ReportableError() {
29+
(
30+
this instanceof CompilerDiscretionaryError or
31+
this instanceof CompilerError or
32+
this instanceof CompilerCatastrophe
33+
) and
34+
// Filter for the catch-all diagnostic, see note above.
35+
not this.getFile().getAbsolutePath() = ""
36+
}
37+
}
38+
39+
private newtype TExtractionError =
40+
TReportableError(ReportableError err) or
41+
TCompilationFailed(Compilation c, File f) {
42+
f = c.getAFileCompiled() and not c.normalTermination()
43+
} or
44+
// Show the catch-all diagnostic (see note above) only if we haven't seen any other error-level diagnostic
45+
// for that compilation
46+
TUnknownError(CompilerError err) {
47+
not exists(ReportableError e | e.getCompilation() = err.getCompilation())
48+
}
49+
50+
/**
51+
* Superclass for the extraction error hierarchy.
52+
*/
53+
class ExtractionError extends TExtractionError {
54+
/** Gets the string representation of the error. */
55+
string toString() { none() }
56+
57+
/** Gets the error message for this error. */
58+
string getErrorMessage() { none() }
59+
60+
/** Gets the file this error occured in. */
61+
File getFile() { none() }
62+
63+
/** Gets the location this error occured in. */
64+
Location getLocation() { none() }
65+
66+
/** Gets the SARIF severity of this error. */
67+
int getSeverity() {
68+
// Unfortunately, we can't distinguish between errors and fatal errors in SARIF,
69+
// so all errors have severity 2.
70+
result = 2
71+
}
72+
}
73+
74+
/**
75+
* An unrecoverable extraction error, where extraction was unable to finish.
76+
* This can be caused by a multitude of reasons, for example:
77+
* - hitting a frontend assertion
78+
* - crashing due to dereferencing an invalid pointer
79+
* - stack overflow
80+
* - out of memory
81+
*/
82+
class ExtractionUnrecoverableError extends ExtractionError, TCompilationFailed {
83+
Compilation c;
84+
File f;
85+
86+
ExtractionUnrecoverableError() { this = TCompilationFailed(c, f) }
87+
88+
override string toString() {
89+
result = "Unrecoverable extraction error while compiling " + f.toString()
90+
}
91+
92+
override string getErrorMessage() { result = "unrecoverable compilation failure." }
93+
94+
override File getFile() { result = f }
95+
96+
override Location getLocation() { result = f.getLocation() }
97+
}
98+
99+
/**
100+
* A recoverable extraction error.
101+
* These are compiler errors from the frontend.
102+
* Upon encountering one of these, we still continue extraction, but the
103+
* database will be incomplete for that file.
104+
*/
105+
class ExtractionRecoverableError extends ExtractionError, TReportableError {
106+
ReportableError err;
107+
108+
ExtractionRecoverableError() { this = TReportableError(err) }
109+
110+
override string toString() { result = "Recoverable extraction error: " + err }
111+
112+
override string getErrorMessage() { result = err.getFullMessage() }
113+
114+
override File getFile() { result = err.getFile() }
115+
116+
override Location getLocation() { result = err.getLocation() }
117+
}
118+
119+
/**
120+
* An unknown error happened during extraction.
121+
* These are only displayed if we know that we encountered an error during extraction,
122+
* but, for some reason, failed to emit a proper diagnostic with location information
123+
* and error message.
124+
*/
125+
class ExtractionUnknownError extends ExtractionError, TUnknownError {
126+
CompilerError err;
127+
128+
ExtractionUnknownError() { this = TUnknownError(err) }
129+
130+
override string toString() { result = "Unknown extraction error: " + err }
131+
132+
override string getErrorMessage() { result = err.getFullMessage() }
133+
134+
override File getFile() { result = err.getFile() }
135+
136+
override Location getLocation() { result = err.getLocation() }
137+
}

misc/suite-helpers/code-scanning-selectors.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,4 @@
2727
query path:
2828
- /^experimental\/.*/
2929
- Metrics/Summaries/FrameworkCoverage.ql
30+
- /Diagnostics/Internal/.*/

0 commit comments

Comments
 (0)