From f6776a4249d4867c258cc180589264c8ea10fa51 Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Fri, 25 Oct 2024 18:06:38 +0100 Subject: [PATCH 01/14] C++: Initial telemetry queries and tests --- cpp/ql/src/Telemetry/CompilerErrors.ql | 12 + cpp/ql/src/Telemetry/DatabaseQuality.ql | 12 + cpp/ql/src/Telemetry/Diagnostics.qll | 32 +++ cpp/ql/src/Telemetry/ExtractionMetrics.ql | 12 + cpp/ql/src/Telemetry/Metrics.qll | 260 ++++++++++++++++++ cpp/ql/src/Telemetry/MissingIncludes.ql | 12 + cpp/ql/src/Telemetry/SucceededIncludes.ql | 12 + .../extraction_errors/CompilerErrors.expected | 10 + .../extraction_errors/CompilerErrors.qlref | 1 + .../DatabaseQuality.expected | 9 + .../extraction_errors/DatabaseQuality.qlref | 1 + .../ExtractionMetrics.expected | 20 ++ .../extraction_errors/ExtractionMetrics.qlref | 1 + .../MissingIncludes.expected | 0 .../extraction_errors/MissingIncludes.qlref | 1 + .../extraction_errors/PrintAst.expected | 79 ++++++ .../extraction_errors/PrintAst.qlref | 1 + .../SucceededIncludes.expected | 1 + .../extraction_errors/SucceededIncludes.qlref | 1 + .../extraction_errors/diags.expected | 10 + .../library-tests/extraction_errors/diags.ql | 4 + .../error_fn_returns.expected | 1 + .../extraction_errors/error_fn_returns.ql | 5 + .../extraction_errors/error_types.expected | 1 + .../extraction_errors/error_types.ql | 6 + .../error_variables.expected | 1 + .../extraction_errors/error_variables.ql | 5 + .../extraction_errors/functions.expected | 6 + .../extraction_errors/functions.ql | 5 + .../library-tests/extraction_errors/test.c | 5 + .../library-tests/extraction_errors/test.cpp | 17 ++ .../library-tests/extraction_errors/test.h | 4 + 32 files changed, 547 insertions(+) create mode 100644 cpp/ql/src/Telemetry/CompilerErrors.ql create mode 100644 cpp/ql/src/Telemetry/DatabaseQuality.ql create mode 100644 cpp/ql/src/Telemetry/Diagnostics.qll create mode 100644 cpp/ql/src/Telemetry/ExtractionMetrics.ql create mode 100644 cpp/ql/src/Telemetry/Metrics.qll create mode 100644 cpp/ql/src/Telemetry/MissingIncludes.ql create mode 100644 cpp/ql/src/Telemetry/SucceededIncludes.ql create mode 100644 cpp/ql/test/library-tests/extraction_errors/CompilerErrors.expected create mode 100644 cpp/ql/test/library-tests/extraction_errors/CompilerErrors.qlref create mode 100644 cpp/ql/test/library-tests/extraction_errors/DatabaseQuality.expected create mode 100644 cpp/ql/test/library-tests/extraction_errors/DatabaseQuality.qlref create mode 100644 cpp/ql/test/library-tests/extraction_errors/ExtractionMetrics.expected create mode 100644 cpp/ql/test/library-tests/extraction_errors/ExtractionMetrics.qlref create mode 100644 cpp/ql/test/library-tests/extraction_errors/MissingIncludes.expected create mode 100644 cpp/ql/test/library-tests/extraction_errors/MissingIncludes.qlref create mode 100644 cpp/ql/test/library-tests/extraction_errors/PrintAst.expected create mode 100644 cpp/ql/test/library-tests/extraction_errors/PrintAst.qlref create mode 100644 cpp/ql/test/library-tests/extraction_errors/SucceededIncludes.expected create mode 100644 cpp/ql/test/library-tests/extraction_errors/SucceededIncludes.qlref create mode 100644 cpp/ql/test/library-tests/extraction_errors/diags.expected create mode 100644 cpp/ql/test/library-tests/extraction_errors/diags.ql create mode 100644 cpp/ql/test/library-tests/extraction_errors/error_fn_returns.expected create mode 100644 cpp/ql/test/library-tests/extraction_errors/error_fn_returns.ql create mode 100644 cpp/ql/test/library-tests/extraction_errors/error_types.expected create mode 100644 cpp/ql/test/library-tests/extraction_errors/error_types.ql create mode 100644 cpp/ql/test/library-tests/extraction_errors/error_variables.expected create mode 100644 cpp/ql/test/library-tests/extraction_errors/error_variables.ql create mode 100644 cpp/ql/test/library-tests/extraction_errors/functions.expected create mode 100644 cpp/ql/test/library-tests/extraction_errors/functions.ql create mode 100644 cpp/ql/test/library-tests/extraction_errors/test.c create mode 100644 cpp/ql/test/library-tests/extraction_errors/test.cpp create mode 100644 cpp/ql/test/library-tests/extraction_errors/test.h diff --git a/cpp/ql/src/Telemetry/CompilerErrors.ql b/cpp/ql/src/Telemetry/CompilerErrors.ql new file mode 100644 index 00000000000..eef845db415 --- /dev/null +++ b/cpp/ql/src/Telemetry/CompilerErrors.ql @@ -0,0 +1,12 @@ +/** + * @name Compiler errors + * @description A count of all compiler errors, grouped by error text. + * @kind metric + * @tags summary telemetry + * @id cpp/telemetry/compiler-errors + */ + +import Metrics + +from CppMetrics::ErrorCount m +select m, m.getValue() as c order by c desc diff --git a/cpp/ql/src/Telemetry/DatabaseQuality.ql b/cpp/ql/src/Telemetry/DatabaseQuality.ql new file mode 100644 index 00000000000..787eb0a8812 --- /dev/null +++ b/cpp/ql/src/Telemetry/DatabaseQuality.ql @@ -0,0 +1,12 @@ +/** + * @name Database quality + * @description Metrics that indicate the quality of the database. + * @kind metric + * @tags summary telemetry + * @id cpp/telemetry/database-quality + */ + +import Metrics + +from QualityMetric m +select m, m.getValue() order by m diff --git a/cpp/ql/src/Telemetry/Diagnostics.qll b/cpp/ql/src/Telemetry/Diagnostics.qll new file mode 100644 index 00000000000..13dc5c75658 --- /dev/null +++ b/cpp/ql/src/Telemetry/Diagnostics.qll @@ -0,0 +1,32 @@ +import cpp + +/** + * A syntax error. + */ +class SyntaxError extends CompilerError { + SyntaxError() { this.getTag().matches("exp_%") } +} + +/** + * A cannot open file error. + * Typically this is due to a missing include. + */ +class CannotOpenFile extends CompilerError { + CannotOpenFile() { this.hasTag("cannot_open_file") } + + string getIncludedFile() { + result = this.getMessage().regexpCapture("cannot open source file '([^']+)'", 1) + } +} + +/** + * An undefined identifier error. + * Currently unused. + */ +class UndefinedIdentifier extends CompilerError { + UndefinedIdentifier() { this.hasTag("undefined_identifier") } + + string getIdentifier() { + result = this.getMessage().regexpCapture("identifier '([^']+)' is undefined", 1) + } +} diff --git a/cpp/ql/src/Telemetry/ExtractionMetrics.ql b/cpp/ql/src/Telemetry/ExtractionMetrics.ql new file mode 100644 index 00000000000..c19000ad89b --- /dev/null +++ b/cpp/ql/src/Telemetry/ExtractionMetrics.ql @@ -0,0 +1,12 @@ +/** + * @name Extraction metrics + * @description Raw metrics relating to extraction. + * @kind metric + * @tags summary telemetry + * @id cpp/telemetry/extraction-metrics + */ + +import Metrics + +from ExtractionMetric m +select m, m.getValue() order by m diff --git a/cpp/ql/src/Telemetry/Metrics.qll b/cpp/ql/src/Telemetry/Metrics.qll new file mode 100644 index 00000000000..5f30dc86c89 --- /dev/null +++ b/cpp/ql/src/Telemetry/Metrics.qll @@ -0,0 +1,260 @@ +import cpp +import Diagnostics + +/** + * A metric is a string with a value. + */ +abstract class Metric extends string { + bindingset[this] + Metric() { any() } + + /** Gets the value of this metric. */ + abstract float getValue(); +} + +/** + * A metric that we want to report in cpp/telemetry/extraction-metrics + */ +abstract class ExtractionMetric extends Metric { + bindingset[this] + ExtractionMetric() { any() } +} + +/** + * A metric that provides a baseline for a SuccessMetric. + */ +abstract class BaseMetric extends ExtractionMetric { + bindingset[this] + BaseMetric() { any() } +} + +/** + * A metric that is relative to another metric, + * so can be used to calculate percentages. + * + * For clarity, metrics should express success, + * so higher values means better. + */ +abstract class SuccessMetric extends ExtractionMetric { + bindingset[this] + SuccessMetric() { any() } + + /** Gets the metric this is relative to. */ + abstract BaseMetric getBaseline(); +} + +/** + * A metric used to report database quality. + */ +class QualityMetric extends Metric { + BaseMetric base_metric; + SuccessMetric relative_metric; + + QualityMetric() { + base_metric = relative_metric.getBaseline() and this = "Percentage of " + relative_metric + } + + override float getValue() { result = 100 * relative_metric.getValue() / base_metric.getValue() } +} + +/** Various metrics we want to report. */ +module CppMetrics { + class CompilationUnits extends BaseMetric { + CompilationUnits() { this = "compilation units" } + + override float getValue() { result = count(Compilation c) } + } + + class SourceFiles extends BaseMetric { + SourceFiles() { this = "source files" } + + override float getValue() { result = count(File f | f.fromSource()) } + } + + class SourceFilesWithoutErrors extends SuccessMetric { + SourceFilesWithoutErrors() { this = "source files without errors" } + + override float getValue() { + result = count(File f | f.fromSource() and not exists(CompilerError e | f = e.getFile())) + } + + override SourceFiles getBaseline() { any() } + } + + class CompilationUnitsWithoutErrors extends SuccessMetric { + CompilationUnitsWithoutErrors() { this = "compilation units without errors" } + + override float getValue() { + result = count(Compilation c | not exists(Diagnostic d | d.getFile() = c.getAFileCompiled())) + } + + override CompilationUnits getBaseline() { any() } + } + + class Expressions extends BaseMetric { + Expressions() { this = "expressions" } + + override float getValue() { result = count(Expr e) } + } + + class SucceededExpressions extends SuccessMetric { + SucceededExpressions() { this = "non-error expressions" } + + override float getValue() { result = count(Expr e) - count(ErrorExpr e) } + + override Expressions getBaseline() { any() } + } + + class TypedExpressions extends SuccessMetric { + TypedExpressions() { this = "expressions with a known type" } + + override float getValue() { result = count(Expr e | not e.getType() instanceof ErroneousType) } + + override Expressions getBaseline() { any() } + } + + class Calls extends BaseMetric { + Calls() { this = "calls" } + + override float getValue() { result = count(Call c) } + } + + class SucceededCalls extends SuccessMetric { + SucceededCalls() { this = "calls with a target" } + + override float getValue() { + result = count(Call c | not c.getTarget().getADeclarationEntry().isImplicit()) + } + + override Calls getBaseline() { any() } + } + + class Variables extends BaseMetric { + Variables() { this = "variables" } + + override float getValue() { result = count(Variable v) } + } + + class VariablesKnownType extends SuccessMetric { + VariablesKnownType() { this = "variables with a known type" } + + override float getValue() { + result = count(Variable v | not v.getType() instanceof ErroneousType) + } + + override Variables getBaseline() { any() } + } + + class LinesOfText extends BaseMetric { + LinesOfText() { this = "lines of text" } + + override float getValue() { result = sum(File f | | f.getMetrics().getNumberOfLines()) } + } + + class LinesOfCode extends BaseMetric { + LinesOfCode() { this = "lines of code" } + + override float getValue() { result = sum(File f | | f.getMetrics().getNumberOfLinesOfCode()) } + } + + private predicate errorLine(File file, int line) { + exists(Locatable l, Location loc | + loc = l.getLocation() and + loc.getFile() = file and + line in [loc.getStartLine() .. loc.getEndLine()] + | + l instanceof Diagnostic + or + l instanceof ErrorExpr + ) + } + + class SucceededLines extends SuccessMetric { + SucceededLines() { this = "lines of code without errors" } + + override float getValue() { + result = + sum(File f | | f.getMetrics().getNumberOfLinesOfCode()) - + count(File file, int line | errorLine(file, line)) + } + + override LinesOfCode getBaseline() { any() } + } + + class Functions extends BaseMetric { + Functions() { this = "functions" } + + override float getValue() { result = count(Function f) } + } + + class SucceededFunctions extends SuccessMetric { + SucceededFunctions() { this = "functions without errors" } + + override float getValue() { result = count(Function f | not f.hasErrors()) } + + override Functions getBaseline() { any() } + } + + class Includes extends BaseMetric { + Includes() { this = "#include directives" } + + override float getValue() { result = count(Include i) + count(CannotOpenFile e) } + } + + class SucceededIncludes extends SuccessMetric { + SucceededIncludes() { this = "successfully resolved #include directives" } + + override float getValue() { result = count(Include i) } + + override Includes getBaseline() { any() } + } + + class SucceededIncludeCount extends Metric { + string include_text; + + SucceededIncludeCount() { + exists(Include i | + i.getIncludeText() = include_text and + exists(i.getFile().getRelativePath()) // Only report includes from the repo + ) and + this = "Successfully included " + include_text + } + + override float getValue() { result = count(Include i | i.getIncludeText() = include_text) } + + string getIncludeText() { result = include_text } + } + + class MissingIncludeCount extends Metric { + string include_text; + + MissingIncludeCount() { + exists(CannotOpenFile e | e.getIncludedFile() = include_text) and + this = "Failed to include '" + include_text + "'" + } + + override float getValue() { + result = count(CannotOpenFile e | e.getIncludedFile() = include_text) + } + + string getIncludeText() { result = include_text } + } + + class CompilerErrors extends ExtractionMetric { + CompilerErrors() { this = "compiler errors" } + + override float getValue() { result = count(CompilerError e) } + } + + class ErrorCount extends Metric { + ErrorCount() { exists(CompilerError e | e.getMessage() = this) } + + override float getValue() { result = count(CompilerError e | e.getMessage() = this) } + } + + class SyntaxErrorCount extends ExtractionMetric { + SyntaxErrorCount() { this = "syntax errors" } + + override float getValue() { result = count(SyntaxError e) } + } +} diff --git a/cpp/ql/src/Telemetry/MissingIncludes.ql b/cpp/ql/src/Telemetry/MissingIncludes.ql new file mode 100644 index 00000000000..e58fbf3fcf5 --- /dev/null +++ b/cpp/ql/src/Telemetry/MissingIncludes.ql @@ -0,0 +1,12 @@ +/** + * @name Failed to include header file + * @description A count of all failed includes, grouped by filename. + * @kind metric + * @tags summary telemetry + * @id cpp/telemetry/failed-includes + */ + +import Metrics + +from CppMetrics::MissingIncludeCount e +select e.getIncludeText(), e.getValue() as c order by c desc diff --git a/cpp/ql/src/Telemetry/SucceededIncludes.ql b/cpp/ql/src/Telemetry/SucceededIncludes.ql new file mode 100644 index 00000000000..e303add9a49 --- /dev/null +++ b/cpp/ql/src/Telemetry/SucceededIncludes.ql @@ -0,0 +1,12 @@ +/** + * @name Successfully included header files + * @description A count of all succeeded includes, grouped by filename. + * @kind metric + * @tags summary telemetry + * @id cpp/telemetry/succeeded-includes + */ + +import Metrics + +from CppMetrics::SucceededIncludeCount m +select m.getIncludeText(), m.getValue() diff --git a/cpp/ql/test/library-tests/extraction_errors/CompilerErrors.expected b/cpp/ql/test/library-tests/extraction_errors/CompilerErrors.expected new file mode 100644 index 00000000000..27c1b8c641e --- /dev/null +++ b/cpp/ql/test/library-tests/extraction_errors/CompilerErrors.expected @@ -0,0 +1,10 @@ +| 'this' may only be used inside a nonstatic member function | 1.0 | +| There was an error during this compilation | 1.0 | +| expected a ')' | 1.0 | +| expected a ';' | 1.0 | +| expected an expression | 1.0 | +| identifier 'no_such_function' is undefined | 1.0 | +| identifier 'nsf2' is undefined | 1.0 | +| identifier 'so_is_this' is undefined | 1.0 | +| identifier 'uint32_t' is undefined | 1.0 | +| too few arguments in function call | 1.0 | diff --git a/cpp/ql/test/library-tests/extraction_errors/CompilerErrors.qlref b/cpp/ql/test/library-tests/extraction_errors/CompilerErrors.qlref new file mode 100644 index 00000000000..fd0c287c00d --- /dev/null +++ b/cpp/ql/test/library-tests/extraction_errors/CompilerErrors.qlref @@ -0,0 +1 @@ +Telemetry/CompilerErrors.ql diff --git a/cpp/ql/test/library-tests/extraction_errors/DatabaseQuality.expected b/cpp/ql/test/library-tests/extraction_errors/DatabaseQuality.expected new file mode 100644 index 00000000000..73e5a585a43 --- /dev/null +++ b/cpp/ql/test/library-tests/extraction_errors/DatabaseQuality.expected @@ -0,0 +1,9 @@ +| Percentage of calls with a target | 50.0 | +| Percentage of compilation units without errors | 50.0 | +| Percentage of expressions with a known type | 30.0 | +| Percentage of functions without errors | 75.0 | +| Percentage of lines of code without errors | 63.1578947368421 | +| Percentage of non-error expressions | 30.0 | +| Percentage of source files without errors | 66.66666666666667 | +| Percentage of successfully resolved #include directives | 100.0 | +| Percentage of variables with a known type | 90.0 | diff --git a/cpp/ql/test/library-tests/extraction_errors/DatabaseQuality.qlref b/cpp/ql/test/library-tests/extraction_errors/DatabaseQuality.qlref new file mode 100644 index 00000000000..b2c536f00d7 --- /dev/null +++ b/cpp/ql/test/library-tests/extraction_errors/DatabaseQuality.qlref @@ -0,0 +1 @@ +Telemetry/DatabaseQuality.ql diff --git a/cpp/ql/test/library-tests/extraction_errors/ExtractionMetrics.expected b/cpp/ql/test/library-tests/extraction_errors/ExtractionMetrics.expected new file mode 100644 index 00000000000..dcba2f00087 --- /dev/null +++ b/cpp/ql/test/library-tests/extraction_errors/ExtractionMetrics.expected @@ -0,0 +1,20 @@ +| #include directives | 2.0 | +| calls | 2.0 | +| calls with a target | 1.0 | +| compilation units | 2.0 | +| compilation units without errors | 1.0 | +| compiler errors | 10.0 | +| expressions | 10.0 | +| expressions with a known type | 3.0 | +| functions | 8.0 | +| functions without errors | 6.0 | +| lines of code | 19.0 | +| lines of code without errors | 12.0 | +| lines of text | 26.0 | +| non-error expressions | 3.0 | +| source files | 3.0 | +| source files without errors | 2.0 | +| successfully resolved #include directives | 2.0 | +| syntax errors | 3.0 | +| variables | 10.0 | +| variables with a known type | 9.0 | diff --git a/cpp/ql/test/library-tests/extraction_errors/ExtractionMetrics.qlref b/cpp/ql/test/library-tests/extraction_errors/ExtractionMetrics.qlref new file mode 100644 index 00000000000..80547fdfd98 --- /dev/null +++ b/cpp/ql/test/library-tests/extraction_errors/ExtractionMetrics.qlref @@ -0,0 +1 @@ +Telemetry/ExtractionMetrics.ql \ No newline at end of file diff --git a/cpp/ql/test/library-tests/extraction_errors/MissingIncludes.expected b/cpp/ql/test/library-tests/extraction_errors/MissingIncludes.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/cpp/ql/test/library-tests/extraction_errors/MissingIncludes.qlref b/cpp/ql/test/library-tests/extraction_errors/MissingIncludes.qlref new file mode 100644 index 00000000000..8481a932a57 --- /dev/null +++ b/cpp/ql/test/library-tests/extraction_errors/MissingIncludes.qlref @@ -0,0 +1 @@ +Telemetry/MissingIncludes.ql \ No newline at end of file diff --git a/cpp/ql/test/library-tests/extraction_errors/PrintAst.expected b/cpp/ql/test/library-tests/extraction_errors/PrintAst.expected new file mode 100644 index 00000000000..7ff9a540565 --- /dev/null +++ b/cpp/ql/test/library-tests/extraction_errors/PrintAst.expected @@ -0,0 +1,79 @@ +#-----| [CopyAssignmentOperator] __va_list_tag& __va_list_tag::operator=(__va_list_tag const&) +#-----| : +#-----| getParameter(0): [Parameter] (unnamed parameter 0) +#-----| Type = [LValueReferenceType] const __va_list_tag & +#-----| [MoveAssignmentOperator] __va_list_tag& __va_list_tag::operator=(__va_list_tag&&) +#-----| : +#-----| getParameter(0): [Parameter] (unnamed parameter 0) +#-----| Type = [RValueReferenceType] __va_list_tag && +test.c: +# 3| [TopLevelFunction] void g() +# 3| : +# 3| getEntryPoint(): [BlockStmt] { ... } +# 4| getStmt(0): [DeclStmt] declaration +# 4| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x +# 4| Type = [IntType] int +# 4| getVariable().getInitializer(): [Initializer] initializer for x +# 4| getExpr(): [FunctionCall] call to no_such_function +# 4| Type = [IntType] int +# 4| ValueCategory = prvalue +# 5| getStmt(1): [ReturnStmt] return ... +# 4| [TopLevelFunction] int no_such_function() +# 4| : +test.cpp: +# 5| [TopLevelFunction] void function_with_errors() +# 5| : +# 5| getEntryPoint(): [BlockStmt] { ... } +# 6| getStmt(0): [DeclStmt] declaration +# 6| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x +# 6| Type = [ErroneousType] error +# 6| getVariable().getInitializer(): [Initializer] initializer for x +# 6| getExpr(): [ErrorExpr] +# 6| Type = [ErroneousType] error +# 6| ValueCategory = prvalue +# 7| getStmt(1): [ExprStmt] ExprStmt +#-----| getExpr(): [ErrorExpr] +#-----| Type = [ErroneousType] error +#-----| ValueCategory = prvalue +# 8| getStmt(2): [ExprStmt] ExprStmt +#-----| getExpr(): [ErrorExpr] +#-----| Type = [ErroneousType] error +#-----| ValueCategory = prvalue +# 9| getStmt(3): [ExprStmt] ExprStmt +#-----| getExpr(): [ErrorExpr] +#-----| Type = [ErroneousType] error +#-----| ValueCategory = prvalue +# 10| getStmt(4): [ExprStmt] ExprStmt +# 10| getExpr(): [FunctionCall] call to f +# 10| Type = [IntType] int +# 10| ValueCategory = prvalue +# 10| getArgument(0): [Literal] 1 +# 10| Type = [IntType] int +# 10| Value = [Literal] 1 +# 10| ValueCategory = prvalue +# 11| getStmt(5): [ExprStmt] ExprStmt +#-----| getExpr(): [ErrorExpr] +#-----| Type = [ErroneousType] error +#-----| ValueCategory = prvalue +# 12| getStmt(6): [ReturnStmt] return ... +# 14| [TopLevelFunction] error fn2() +# 14| : +# 14| getEntryPoint(): [BlockStmt] { ... } +# 15| getStmt(0): [ExprStmt] ExprStmt +#-----| getExpr(): [ErrorExpr] +#-----| Type = [ErroneousType] error +#-----| ValueCategory = prvalue +# 16| getStmt(1): [ExprStmt] ExprStmt +#-----| getExpr(): [ErrorExpr] +#-----| Type = [ErroneousType] error +#-----| ValueCategory = prvalue +# 17| getStmt(2): [ReturnStmt] return ... +test.h: +# 4| [TopLevelFunction] int f(int) +# 4| : +# 4| getParameter(0): [Parameter] (unnamed parameter 0) +# 4| Type = [IntType] int +# 4| [TopLevelFunction] int f(int) +# 4| : +# 4| getParameter(0): [Parameter] (unnamed parameter 0) +# 4| Type = [IntType] int diff --git a/cpp/ql/test/library-tests/extraction_errors/PrintAst.qlref b/cpp/ql/test/library-tests/extraction_errors/PrintAst.qlref new file mode 100644 index 00000000000..6fcb30ac7a6 --- /dev/null +++ b/cpp/ql/test/library-tests/extraction_errors/PrintAst.qlref @@ -0,0 +1 @@ +semmle/code/cpp/PrintAST.ql \ No newline at end of file diff --git a/cpp/ql/test/library-tests/extraction_errors/SucceededIncludes.expected b/cpp/ql/test/library-tests/extraction_errors/SucceededIncludes.expected new file mode 100644 index 00000000000..deebd4f51ea --- /dev/null +++ b/cpp/ql/test/library-tests/extraction_errors/SucceededIncludes.expected @@ -0,0 +1 @@ +| "test.h" | 2.0 | diff --git a/cpp/ql/test/library-tests/extraction_errors/SucceededIncludes.qlref b/cpp/ql/test/library-tests/extraction_errors/SucceededIncludes.qlref new file mode 100644 index 00000000000..055b6af49a7 --- /dev/null +++ b/cpp/ql/test/library-tests/extraction_errors/SucceededIncludes.qlref @@ -0,0 +1 @@ +Telemetry/SucceededIncludes.ql diff --git a/cpp/ql/test/library-tests/extraction_errors/diags.expected b/cpp/ql/test/library-tests/extraction_errors/diags.expected new file mode 100644 index 00000000000..68e5c9c154c --- /dev/null +++ b/cpp/ql/test/library-tests/extraction_errors/diags.expected @@ -0,0 +1,10 @@ +| file://:0:0:0:0 | There was an error during this compilation | +| test.cpp:6:14:6:14 | identifier 'no_such_function' is undefined | +| test.cpp:9:14:9:14 | identifier 'nsf2' is undefined | +| test.cpp:11:7:11:7 | too few arguments in function call | +| test.cpp:14:1:14:1 | identifier 'uint32_t' is undefined | +| test.cpp:15:5:15:5 | 'this' may only be used inside a nonstatic member function | +| test.cpp:15:10:15:10 | expected a ';' | +| test.cpp:16:5:16:5 | identifier 'so_is_this' is undefined | +| test.cpp:16:16:16:16 | expected a ')' | +| test.cpp:16:16:16:16 | expected an expression | diff --git a/cpp/ql/test/library-tests/extraction_errors/diags.ql b/cpp/ql/test/library-tests/extraction_errors/diags.ql new file mode 100644 index 00000000000..9e7db729265 --- /dev/null +++ b/cpp/ql/test/library-tests/extraction_errors/diags.ql @@ -0,0 +1,4 @@ +import cpp + +from Diagnostic d +select d \ No newline at end of file diff --git a/cpp/ql/test/library-tests/extraction_errors/error_fn_returns.expected b/cpp/ql/test/library-tests/extraction_errors/error_fn_returns.expected new file mode 100644 index 00000000000..a06ba8bf672 --- /dev/null +++ b/cpp/ql/test/library-tests/extraction_errors/error_fn_returns.expected @@ -0,0 +1 @@ +| test.cpp:14:10:14:12 | fn2 | diff --git a/cpp/ql/test/library-tests/extraction_errors/error_fn_returns.ql b/cpp/ql/test/library-tests/extraction_errors/error_fn_returns.ql new file mode 100644 index 00000000000..28fe33cb2a6 --- /dev/null +++ b/cpp/ql/test/library-tests/extraction_errors/error_fn_returns.ql @@ -0,0 +1,5 @@ +import cpp + +from Function fn +where fn.getType() instanceof ErroneousType or not exists(fn.getType()) +select fn diff --git a/cpp/ql/test/library-tests/extraction_errors/error_types.expected b/cpp/ql/test/library-tests/extraction_errors/error_types.expected new file mode 100644 index 00000000000..d15915d4f7a --- /dev/null +++ b/cpp/ql/test/library-tests/extraction_errors/error_types.expected @@ -0,0 +1 @@ +| test.cpp:6:13:6:31 | | diff --git a/cpp/ql/test/library-tests/extraction_errors/error_types.ql b/cpp/ql/test/library-tests/extraction_errors/error_types.ql new file mode 100644 index 00000000000..3b754dffa65 --- /dev/null +++ b/cpp/ql/test/library-tests/extraction_errors/error_types.ql @@ -0,0 +1,6 @@ +import cpp + +from Expr e +where e.getType() instanceof ErroneousType +and e.fromSource() +select e diff --git a/cpp/ql/test/library-tests/extraction_errors/error_variables.expected b/cpp/ql/test/library-tests/extraction_errors/error_variables.expected new file mode 100644 index 00000000000..d5b216dba71 --- /dev/null +++ b/cpp/ql/test/library-tests/extraction_errors/error_variables.expected @@ -0,0 +1 @@ +| test.cpp:6:10:6:10 | x | This variable does not have a type. | diff --git a/cpp/ql/test/library-tests/extraction_errors/error_variables.ql b/cpp/ql/test/library-tests/extraction_errors/error_variables.ql new file mode 100644 index 00000000000..e3867462b56 --- /dev/null +++ b/cpp/ql/test/library-tests/extraction_errors/error_variables.ql @@ -0,0 +1,5 @@ +import cpp + +from Variable v +where v.getType() instanceof ErroneousType or not exists(v.getType()) +select v, "This variable does not have a type." diff --git a/cpp/ql/test/library-tests/extraction_errors/functions.expected b/cpp/ql/test/library-tests/extraction_errors/functions.expected new file mode 100644 index 00000000000..e1c62fd7e49 --- /dev/null +++ b/cpp/ql/test/library-tests/extraction_errors/functions.expected @@ -0,0 +1,6 @@ +| test.c:3:6:3:6 | g | +| test.c:4:13:4:13 | no_such_function | +| test.cpp:5:6:5:25 | function_with_errors | +| test.cpp:14:10:14:12 | fn2 | +| test.h:4:5:4:5 | f | +| test.h:4:5:4:5 | f | diff --git a/cpp/ql/test/library-tests/extraction_errors/functions.ql b/cpp/ql/test/library-tests/extraction_errors/functions.ql new file mode 100644 index 00000000000..1c0ddd3fd45 --- /dev/null +++ b/cpp/ql/test/library-tests/extraction_errors/functions.ql @@ -0,0 +1,5 @@ +import cpp + +from Function fn +where fn.fromSource() +select fn \ No newline at end of file diff --git a/cpp/ql/test/library-tests/extraction_errors/test.c b/cpp/ql/test/library-tests/extraction_errors/test.c new file mode 100644 index 00000000000..e247964f71c --- /dev/null +++ b/cpp/ql/test/library-tests/extraction_errors/test.c @@ -0,0 +1,5 @@ +#include "test.h" + +void g() { + int x = no_such_function(); +} diff --git a/cpp/ql/test/library-tests/extraction_errors/test.cpp b/cpp/ql/test/library-tests/extraction_errors/test.cpp new file mode 100644 index 00000000000..b2ca86bcbaa --- /dev/null +++ b/cpp/ql/test/library-tests/extraction_errors/test.cpp @@ -0,0 +1,17 @@ +// semmle-extractor-options: --expect_errors + +#include "test.h" + +void function_with_errors() { + auto x = no_such_function(); + x+2; + no_such_function(); + ADD(x+1, nsf2()); + f(1); + f(); +} + +uint32_t fn2() { + this is a syntax error; + so_is_this(; +} diff --git a/cpp/ql/test/library-tests/extraction_errors/test.h b/cpp/ql/test/library-tests/extraction_errors/test.h new file mode 100644 index 00000000000..6957e49d8c9 --- /dev/null +++ b/cpp/ql/test/library-tests/extraction_errors/test.h @@ -0,0 +1,4 @@ + +#define ADD(A,B) ((A)+(B)) + +int f(int); From a53e1dec206e9733b241f4552e95634cbc2d52db Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Fri, 1 Nov 2024 16:55:48 +0000 Subject: [PATCH 02/14] C++: Minor edits --- cpp/ql/src/Telemetry/Metrics.qll | 2 +- .../extraction_errors/ExtractionMetrics.expected | 2 +- .../extraction_errors/PrintAst.expected | 16 ++++++++-------- .../library-tests/extraction_errors/diags.ql | 2 +- .../extraction_errors/error_fn_returns.expected | 1 - .../extraction_errors/error_fn_returns.ql | 5 ----- .../extraction_errors/error_types.expected | 1 - .../extraction_errors/error_types.ql | 6 ------ .../extraction_errors/functions.expected | 4 ++-- .../library-tests/extraction_errors/functions.ql | 2 +- .../test/library-tests/extraction_errors/test.h | 2 -- 11 files changed, 14 insertions(+), 29 deletions(-) delete mode 100644 cpp/ql/test/library-tests/extraction_errors/error_fn_returns.expected delete mode 100644 cpp/ql/test/library-tests/extraction_errors/error_fn_returns.ql delete mode 100644 cpp/ql/test/library-tests/extraction_errors/error_types.expected delete mode 100644 cpp/ql/test/library-tests/extraction_errors/error_types.ql diff --git a/cpp/ql/src/Telemetry/Metrics.qll b/cpp/ql/src/Telemetry/Metrics.qll index 5f30dc86c89..59936330e28 100644 --- a/cpp/ql/src/Telemetry/Metrics.qll +++ b/cpp/ql/src/Telemetry/Metrics.qll @@ -215,7 +215,7 @@ module CppMetrics { SucceededIncludeCount() { exists(Include i | i.getIncludeText() = include_text and - exists(i.getFile().getRelativePath()) // Only report includes from the repo + exists(i.getFile().getRelativePath()) // Only report includes from the repo ) and this = "Successfully included " + include_text } diff --git a/cpp/ql/test/library-tests/extraction_errors/ExtractionMetrics.expected b/cpp/ql/test/library-tests/extraction_errors/ExtractionMetrics.expected index dcba2f00087..7fb84fc291e 100644 --- a/cpp/ql/test/library-tests/extraction_errors/ExtractionMetrics.expected +++ b/cpp/ql/test/library-tests/extraction_errors/ExtractionMetrics.expected @@ -10,7 +10,7 @@ | functions without errors | 6.0 | | lines of code | 19.0 | | lines of code without errors | 12.0 | -| lines of text | 26.0 | +| lines of text | 24.0 | | non-error expressions | 3.0 | | source files | 3.0 | | source files without errors | 2.0 | diff --git a/cpp/ql/test/library-tests/extraction_errors/PrintAst.expected b/cpp/ql/test/library-tests/extraction_errors/PrintAst.expected index 7ff9a540565..ce2b59b6a08 100644 --- a/cpp/ql/test/library-tests/extraction_errors/PrintAst.expected +++ b/cpp/ql/test/library-tests/extraction_errors/PrintAst.expected @@ -69,11 +69,11 @@ test.cpp: #-----| ValueCategory = prvalue # 17| getStmt(2): [ReturnStmt] return ... test.h: -# 4| [TopLevelFunction] int f(int) -# 4| : -# 4| getParameter(0): [Parameter] (unnamed parameter 0) -# 4| Type = [IntType] int -# 4| [TopLevelFunction] int f(int) -# 4| : -# 4| getParameter(0): [Parameter] (unnamed parameter 0) -# 4| Type = [IntType] int +# 2| [TopLevelFunction] int f(int) +# 2| : +# 2| getParameter(0): [Parameter] (unnamed parameter 0) +# 2| Type = [IntType] int +# 2| [TopLevelFunction] int f(int) +# 2| : +# 2| getParameter(0): [Parameter] (unnamed parameter 0) +# 2| Type = [IntType] int diff --git a/cpp/ql/test/library-tests/extraction_errors/diags.ql b/cpp/ql/test/library-tests/extraction_errors/diags.ql index 9e7db729265..3fa864748e1 100644 --- a/cpp/ql/test/library-tests/extraction_errors/diags.ql +++ b/cpp/ql/test/library-tests/extraction_errors/diags.ql @@ -1,4 +1,4 @@ import cpp from Diagnostic d -select d \ No newline at end of file +select d diff --git a/cpp/ql/test/library-tests/extraction_errors/error_fn_returns.expected b/cpp/ql/test/library-tests/extraction_errors/error_fn_returns.expected deleted file mode 100644 index a06ba8bf672..00000000000 --- a/cpp/ql/test/library-tests/extraction_errors/error_fn_returns.expected +++ /dev/null @@ -1 +0,0 @@ -| test.cpp:14:10:14:12 | fn2 | diff --git a/cpp/ql/test/library-tests/extraction_errors/error_fn_returns.ql b/cpp/ql/test/library-tests/extraction_errors/error_fn_returns.ql deleted file mode 100644 index 28fe33cb2a6..00000000000 --- a/cpp/ql/test/library-tests/extraction_errors/error_fn_returns.ql +++ /dev/null @@ -1,5 +0,0 @@ -import cpp - -from Function fn -where fn.getType() instanceof ErroneousType or not exists(fn.getType()) -select fn diff --git a/cpp/ql/test/library-tests/extraction_errors/error_types.expected b/cpp/ql/test/library-tests/extraction_errors/error_types.expected deleted file mode 100644 index d15915d4f7a..00000000000 --- a/cpp/ql/test/library-tests/extraction_errors/error_types.expected +++ /dev/null @@ -1 +0,0 @@ -| test.cpp:6:13:6:31 | | diff --git a/cpp/ql/test/library-tests/extraction_errors/error_types.ql b/cpp/ql/test/library-tests/extraction_errors/error_types.ql deleted file mode 100644 index 3b754dffa65..00000000000 --- a/cpp/ql/test/library-tests/extraction_errors/error_types.ql +++ /dev/null @@ -1,6 +0,0 @@ -import cpp - -from Expr e -where e.getType() instanceof ErroneousType -and e.fromSource() -select e diff --git a/cpp/ql/test/library-tests/extraction_errors/functions.expected b/cpp/ql/test/library-tests/extraction_errors/functions.expected index e1c62fd7e49..db80ede0655 100644 --- a/cpp/ql/test/library-tests/extraction_errors/functions.expected +++ b/cpp/ql/test/library-tests/extraction_errors/functions.expected @@ -2,5 +2,5 @@ | test.c:4:13:4:13 | no_such_function | | test.cpp:5:6:5:25 | function_with_errors | | test.cpp:14:10:14:12 | fn2 | -| test.h:4:5:4:5 | f | -| test.h:4:5:4:5 | f | +| test.h:2:5:2:5 | f | +| test.h:2:5:2:5 | f | diff --git a/cpp/ql/test/library-tests/extraction_errors/functions.ql b/cpp/ql/test/library-tests/extraction_errors/functions.ql index 1c0ddd3fd45..ac52eec7309 100644 --- a/cpp/ql/test/library-tests/extraction_errors/functions.ql +++ b/cpp/ql/test/library-tests/extraction_errors/functions.ql @@ -2,4 +2,4 @@ import cpp from Function fn where fn.fromSource() -select fn \ No newline at end of file +select fn diff --git a/cpp/ql/test/library-tests/extraction_errors/test.h b/cpp/ql/test/library-tests/extraction_errors/test.h index 6957e49d8c9..a3941657c0e 100644 --- a/cpp/ql/test/library-tests/extraction_errors/test.h +++ b/cpp/ql/test/library-tests/extraction_errors/test.h @@ -1,4 +1,2 @@ - #define ADD(A,B) ((A)+(B)) - int f(int); From 6c402adbccf2e1fb73553b554c67b6704724c46d Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Fri, 1 Nov 2024 17:15:19 +0000 Subject: [PATCH 03/14] C++: Minor edits --- cpp/ql/src/Telemetry/CompilerErrors.ql | 2 +- cpp/ql/src/Telemetry/DatabaseQuality.ql | 2 +- cpp/ql/src/Telemetry/ExtractionMetrics.ql | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cpp/ql/src/Telemetry/CompilerErrors.ql b/cpp/ql/src/Telemetry/CompilerErrors.ql index eef845db415..a6e113d5f04 100644 --- a/cpp/ql/src/Telemetry/CompilerErrors.ql +++ b/cpp/ql/src/Telemetry/CompilerErrors.ql @@ -9,4 +9,4 @@ import Metrics from CppMetrics::ErrorCount m -select m, m.getValue() as c order by c desc +select m.toString(), m.getValue() diff --git a/cpp/ql/src/Telemetry/DatabaseQuality.ql b/cpp/ql/src/Telemetry/DatabaseQuality.ql index 787eb0a8812..af8e340507b 100644 --- a/cpp/ql/src/Telemetry/DatabaseQuality.ql +++ b/cpp/ql/src/Telemetry/DatabaseQuality.ql @@ -9,4 +9,4 @@ import Metrics from QualityMetric m -select m, m.getValue() order by m +select m.toString(), m.getValue() diff --git a/cpp/ql/src/Telemetry/ExtractionMetrics.ql b/cpp/ql/src/Telemetry/ExtractionMetrics.ql index c19000ad89b..968bf456ecb 100644 --- a/cpp/ql/src/Telemetry/ExtractionMetrics.ql +++ b/cpp/ql/src/Telemetry/ExtractionMetrics.ql @@ -9,4 +9,4 @@ import Metrics from ExtractionMetric m -select m, m.getValue() order by m +select m.toString(), m.getValue() From 8d2cef632eca5fe750a743cc31afe0332ca7b808 Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Fri, 1 Nov 2024 17:33:48 +0000 Subject: [PATCH 04/14] C++: Minor edits --- cpp/ql/src/Telemetry/Metrics.qll | 5 ++++- cpp/ql/src/Telemetry/MissingIncludes.ql | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/cpp/ql/src/Telemetry/Metrics.qll b/cpp/ql/src/Telemetry/Metrics.qll index 59936330e28..178f5956f4b 100644 --- a/cpp/ql/src/Telemetry/Metrics.qll +++ b/cpp/ql/src/Telemetry/Metrics.qll @@ -54,7 +54,10 @@ class QualityMetric extends Metric { base_metric = relative_metric.getBaseline() and this = "Percentage of " + relative_metric } - override float getValue() { result = 100 * relative_metric.getValue() / base_metric.getValue() } + override float getValue() { + base_metric.getValue() > 0 and + result = 100 * relative_metric.getValue() / base_metric.getValue() + } } /** Various metrics we want to report. */ diff --git a/cpp/ql/src/Telemetry/MissingIncludes.ql b/cpp/ql/src/Telemetry/MissingIncludes.ql index e58fbf3fcf5..8a88176e39c 100644 --- a/cpp/ql/src/Telemetry/MissingIncludes.ql +++ b/cpp/ql/src/Telemetry/MissingIncludes.ql @@ -9,4 +9,4 @@ import Metrics from CppMetrics::MissingIncludeCount e -select e.getIncludeText(), e.getValue() as c order by c desc +select e.getIncludeText(), e.getValue() From 9a81ce8bb4f6152fc11e444bd5f111281494fc2b Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Mon, 4 Nov 2024 12:39:46 +0000 Subject: [PATCH 05/14] C++: Separate int and float metrics --- cpp/ql/src/Telemetry/Metrics.qll | 58 +++++++++---------- .../extraction_errors/CompilerErrors.expected | 20 +++---- .../ExtractionMetrics.expected | 40 ++++++------- .../SucceededIncludes.expected | 2 +- 4 files changed, 59 insertions(+), 61 deletions(-) diff --git a/cpp/ql/src/Telemetry/Metrics.qll b/cpp/ql/src/Telemetry/Metrics.qll index 178f5956f4b..9eb637c3046 100644 --- a/cpp/ql/src/Telemetry/Metrics.qll +++ b/cpp/ql/src/Telemetry/Metrics.qll @@ -7,9 +7,6 @@ import Diagnostics abstract class Metric extends string { bindingset[this] Metric() { any() } - - /** Gets the value of this metric. */ - abstract float getValue(); } /** @@ -18,6 +15,9 @@ abstract class Metric extends string { abstract class ExtractionMetric extends Metric { bindingset[this] ExtractionMetric() { any() } + + /** Gets the value of this metric. */ + abstract int getValue(); } /** @@ -54,9 +54,9 @@ class QualityMetric extends Metric { base_metric = relative_metric.getBaseline() and this = "Percentage of " + relative_metric } - override float getValue() { + float getValue() { base_metric.getValue() > 0 and - result = 100 * relative_metric.getValue() / base_metric.getValue() + result = 100.0 * relative_metric.getValue() / base_metric.getValue() } } @@ -65,19 +65,19 @@ module CppMetrics { class CompilationUnits extends BaseMetric { CompilationUnits() { this = "compilation units" } - override float getValue() { result = count(Compilation c) } + override int getValue() { result = count(Compilation c) } } class SourceFiles extends BaseMetric { SourceFiles() { this = "source files" } - override float getValue() { result = count(File f | f.fromSource()) } + override int getValue() { result = count(File f | f.fromSource()) } } class SourceFilesWithoutErrors extends SuccessMetric { SourceFilesWithoutErrors() { this = "source files without errors" } - override float getValue() { + override int getValue() { result = count(File f | f.fromSource() and not exists(CompilerError e | f = e.getFile())) } @@ -87,7 +87,7 @@ module CppMetrics { class CompilationUnitsWithoutErrors extends SuccessMetric { CompilationUnitsWithoutErrors() { this = "compilation units without errors" } - override float getValue() { + override int getValue() { result = count(Compilation c | not exists(Diagnostic d | d.getFile() = c.getAFileCompiled())) } @@ -97,13 +97,13 @@ module CppMetrics { class Expressions extends BaseMetric { Expressions() { this = "expressions" } - override float getValue() { result = count(Expr e) } + override int getValue() { result = count(Expr e) } } class SucceededExpressions extends SuccessMetric { SucceededExpressions() { this = "non-error expressions" } - override float getValue() { result = count(Expr e) - count(ErrorExpr e) } + override int getValue() { result = count(Expr e) - count(ErrorExpr e) } override Expressions getBaseline() { any() } } @@ -111,7 +111,7 @@ module CppMetrics { class TypedExpressions extends SuccessMetric { TypedExpressions() { this = "expressions with a known type" } - override float getValue() { result = count(Expr e | not e.getType() instanceof ErroneousType) } + override int getValue() { result = count(Expr e | not e.getType() instanceof ErroneousType) } override Expressions getBaseline() { any() } } @@ -119,13 +119,13 @@ module CppMetrics { class Calls extends BaseMetric { Calls() { this = "calls" } - override float getValue() { result = count(Call c) } + override int getValue() { result = count(Call c) } } class SucceededCalls extends SuccessMetric { SucceededCalls() { this = "calls with a target" } - override float getValue() { + override int getValue() { result = count(Call c | not c.getTarget().getADeclarationEntry().isImplicit()) } @@ -135,13 +135,13 @@ module CppMetrics { class Variables extends BaseMetric { Variables() { this = "variables" } - override float getValue() { result = count(Variable v) } + override int getValue() { result = count(Variable v) } } class VariablesKnownType extends SuccessMetric { VariablesKnownType() { this = "variables with a known type" } - override float getValue() { + override int getValue() { result = count(Variable v | not v.getType() instanceof ErroneousType) } @@ -151,13 +151,13 @@ module CppMetrics { class LinesOfText extends BaseMetric { LinesOfText() { this = "lines of text" } - override float getValue() { result = sum(File f | | f.getMetrics().getNumberOfLines()) } + override int getValue() { result = sum(File f | | f.getMetrics().getNumberOfLines()) } } class LinesOfCode extends BaseMetric { LinesOfCode() { this = "lines of code" } - override float getValue() { result = sum(File f | | f.getMetrics().getNumberOfLinesOfCode()) } + override int getValue() { result = sum(File f | | f.getMetrics().getNumberOfLinesOfCode()) } } private predicate errorLine(File file, int line) { @@ -175,7 +175,7 @@ module CppMetrics { class SucceededLines extends SuccessMetric { SucceededLines() { this = "lines of code without errors" } - override float getValue() { + override int getValue() { result = sum(File f | | f.getMetrics().getNumberOfLinesOfCode()) - count(File file, int line | errorLine(file, line)) @@ -187,13 +187,13 @@ module CppMetrics { class Functions extends BaseMetric { Functions() { this = "functions" } - override float getValue() { result = count(Function f) } + override int getValue() { result = count(Function f) } } class SucceededFunctions extends SuccessMetric { SucceededFunctions() { this = "functions without errors" } - override float getValue() { result = count(Function f | not f.hasErrors()) } + override int getValue() { result = count(Function f | not f.hasErrors()) } override Functions getBaseline() { any() } } @@ -201,13 +201,13 @@ module CppMetrics { class Includes extends BaseMetric { Includes() { this = "#include directives" } - override float getValue() { result = count(Include i) + count(CannotOpenFile e) } + override int getValue() { result = count(Include i) + count(CannotOpenFile e) } } class SucceededIncludes extends SuccessMetric { SucceededIncludes() { this = "successfully resolved #include directives" } - override float getValue() { result = count(Include i) } + override int getValue() { result = count(Include i) } override Includes getBaseline() { any() } } @@ -223,7 +223,7 @@ module CppMetrics { this = "Successfully included " + include_text } - override float getValue() { result = count(Include i | i.getIncludeText() = include_text) } + int getValue() { result = count(Include i | i.getIncludeText() = include_text) } string getIncludeText() { result = include_text } } @@ -236,9 +236,7 @@ module CppMetrics { this = "Failed to include '" + include_text + "'" } - override float getValue() { - result = count(CannotOpenFile e | e.getIncludedFile() = include_text) - } + int getValue() { result = count(CannotOpenFile e | e.getIncludedFile() = include_text) } string getIncludeText() { result = include_text } } @@ -246,18 +244,18 @@ module CppMetrics { class CompilerErrors extends ExtractionMetric { CompilerErrors() { this = "compiler errors" } - override float getValue() { result = count(CompilerError e) } + override int getValue() { result = count(CompilerError e) } } class ErrorCount extends Metric { ErrorCount() { exists(CompilerError e | e.getMessage() = this) } - override float getValue() { result = count(CompilerError e | e.getMessage() = this) } + int getValue() { result = count(CompilerError e | e.getMessage() = this) } } class SyntaxErrorCount extends ExtractionMetric { SyntaxErrorCount() { this = "syntax errors" } - override float getValue() { result = count(SyntaxError e) } + override int getValue() { result = count(SyntaxError e) } } } diff --git a/cpp/ql/test/library-tests/extraction_errors/CompilerErrors.expected b/cpp/ql/test/library-tests/extraction_errors/CompilerErrors.expected index 27c1b8c641e..1e4e4c8e3c6 100644 --- a/cpp/ql/test/library-tests/extraction_errors/CompilerErrors.expected +++ b/cpp/ql/test/library-tests/extraction_errors/CompilerErrors.expected @@ -1,10 +1,10 @@ -| 'this' may only be used inside a nonstatic member function | 1.0 | -| There was an error during this compilation | 1.0 | -| expected a ')' | 1.0 | -| expected a ';' | 1.0 | -| expected an expression | 1.0 | -| identifier 'no_such_function' is undefined | 1.0 | -| identifier 'nsf2' is undefined | 1.0 | -| identifier 'so_is_this' is undefined | 1.0 | -| identifier 'uint32_t' is undefined | 1.0 | -| too few arguments in function call | 1.0 | +| 'this' may only be used inside a nonstatic member function | 1 | +| There was an error during this compilation | 1 | +| expected a ')' | 1 | +| expected a ';' | 1 | +| expected an expression | 1 | +| identifier 'no_such_function' is undefined | 1 | +| identifier 'nsf2' is undefined | 1 | +| identifier 'so_is_this' is undefined | 1 | +| identifier 'uint32_t' is undefined | 1 | +| too few arguments in function call | 1 | diff --git a/cpp/ql/test/library-tests/extraction_errors/ExtractionMetrics.expected b/cpp/ql/test/library-tests/extraction_errors/ExtractionMetrics.expected index 7fb84fc291e..5530005b709 100644 --- a/cpp/ql/test/library-tests/extraction_errors/ExtractionMetrics.expected +++ b/cpp/ql/test/library-tests/extraction_errors/ExtractionMetrics.expected @@ -1,20 +1,20 @@ -| #include directives | 2.0 | -| calls | 2.0 | -| calls with a target | 1.0 | -| compilation units | 2.0 | -| compilation units without errors | 1.0 | -| compiler errors | 10.0 | -| expressions | 10.0 | -| expressions with a known type | 3.0 | -| functions | 8.0 | -| functions without errors | 6.0 | -| lines of code | 19.0 | -| lines of code without errors | 12.0 | -| lines of text | 24.0 | -| non-error expressions | 3.0 | -| source files | 3.0 | -| source files without errors | 2.0 | -| successfully resolved #include directives | 2.0 | -| syntax errors | 3.0 | -| variables | 10.0 | -| variables with a known type | 9.0 | +| #include directives | 2 | +| calls | 2 | +| calls with a target | 1 | +| compilation units | 2 | +| compilation units without errors | 1 | +| compiler errors | 10 | +| expressions | 10 | +| expressions with a known type | 3 | +| functions | 8 | +| functions without errors | 6 | +| lines of code | 19 | +| lines of code without errors | 12 | +| lines of text | 24 | +| non-error expressions | 3 | +| source files | 3 | +| source files without errors | 2 | +| successfully resolved #include directives | 2 | +| syntax errors | 3 | +| variables | 10 | +| variables with a known type | 9 | diff --git a/cpp/ql/test/library-tests/extraction_errors/SucceededIncludes.expected b/cpp/ql/test/library-tests/extraction_errors/SucceededIncludes.expected index deebd4f51ea..13536ce172c 100644 --- a/cpp/ql/test/library-tests/extraction_errors/SucceededIncludes.expected +++ b/cpp/ql/test/library-tests/extraction_errors/SucceededIncludes.expected @@ -1 +1 @@ -| "test.h" | 2.0 | +| "test.h" | 2 | From 067ecdeea0ac3cf1b49c530138108c44feca9ba4 Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Mon, 4 Nov 2024 13:06:53 +0000 Subject: [PATCH 06/14] C++: Match more tags --- cpp/ql/src/Telemetry/Diagnostics.qll | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/cpp/ql/src/Telemetry/Diagnostics.qll b/cpp/ql/src/Telemetry/Diagnostics.qll index 13dc5c75658..19cb818ab17 100644 --- a/cpp/ql/src/Telemetry/Diagnostics.qll +++ b/cpp/ql/src/Telemetry/Diagnostics.qll @@ -4,7 +4,16 @@ import cpp * A syntax error. */ class SyntaxError extends CompilerError { - SyntaxError() { this.getTag().matches("exp_%") } + SyntaxError() { + this.getTag().matches("exp_%") or + this.getTag() = + [ + "bad_data_member_initialization", "bad_pure_specifier", "bad_return", "bad_uuid_string", + "literal_without_initializer", "missing_class_definition", "missing_exception_declaration", + "nonstd_const_member_decl_not_allowed", "operator_name_not_allowed", + "wide_string_invalid_in_asm" + ] + } } /** @@ -12,7 +21,7 @@ class SyntaxError extends CompilerError { * Typically this is due to a missing include. */ class CannotOpenFile extends CompilerError { - CannotOpenFile() { this.hasTag("cannot_open_file") } + CannotOpenFile() { this.hasTag(["cannot_open_file", "cannot_open_file_reason"]) } string getIncludedFile() { result = this.getMessage().regexpCapture("cannot open source file '([^']+)'", 1) From faeff396eb54fca5311e4b4cfc3f7f045f3db42d Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Fri, 8 Nov 2024 14:37:59 +0000 Subject: [PATCH 07/14] C++: Limit metrics to top 500 --- cpp/ql/src/Telemetry/CompilerErrors.ql | 1 + cpp/ql/src/Telemetry/Metrics.qll | 8 ++++++++ cpp/ql/src/Telemetry/MissingIncludes.ql | 1 + cpp/ql/src/Telemetry/SucceededIncludes.ql | 1 + 4 files changed, 11 insertions(+) diff --git a/cpp/ql/src/Telemetry/CompilerErrors.ql b/cpp/ql/src/Telemetry/CompilerErrors.ql index a6e113d5f04..a4e5cd5f8fc 100644 --- a/cpp/ql/src/Telemetry/CompilerErrors.ql +++ b/cpp/ql/src/Telemetry/CompilerErrors.ql @@ -9,4 +9,5 @@ import Metrics from CppMetrics::ErrorCount m +where RankMetric::getRank(m) <= 500 select m.toString(), m.getValue() diff --git a/cpp/ql/src/Telemetry/Metrics.qll b/cpp/ql/src/Telemetry/Metrics.qll index 9eb637c3046..168b6a13c97 100644 --- a/cpp/ql/src/Telemetry/Metrics.qll +++ b/cpp/ql/src/Telemetry/Metrics.qll @@ -60,6 +60,14 @@ class QualityMetric extends Metric { } } +signature class RankedMetric extends Metric { + int getValue(); +} + +module RankMetric { + int getRank(M s) { s = rank[result](M m | | m order by m.getValue() desc) } +} + /** Various metrics we want to report. */ module CppMetrics { class CompilationUnits extends BaseMetric { diff --git a/cpp/ql/src/Telemetry/MissingIncludes.ql b/cpp/ql/src/Telemetry/MissingIncludes.ql index 8a88176e39c..a3a65de7577 100644 --- a/cpp/ql/src/Telemetry/MissingIncludes.ql +++ b/cpp/ql/src/Telemetry/MissingIncludes.ql @@ -9,4 +9,5 @@ import Metrics from CppMetrics::MissingIncludeCount e +where RankMetric::getRank(e) <= 500 select e.getIncludeText(), e.getValue() diff --git a/cpp/ql/src/Telemetry/SucceededIncludes.ql b/cpp/ql/src/Telemetry/SucceededIncludes.ql index e303add9a49..dda4fa414d9 100644 --- a/cpp/ql/src/Telemetry/SucceededIncludes.ql +++ b/cpp/ql/src/Telemetry/SucceededIncludes.ql @@ -9,4 +9,5 @@ import Metrics from CppMetrics::SucceededIncludeCount m +where RankMetric::getRank(m) <= 500 select m.getIncludeText(), m.getValue() From e6f351205633ce2949a5d6389bda70f29240d338 Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Fri, 8 Nov 2024 16:12:43 +0000 Subject: [PATCH 08/14] C++: Remove unused class UndefinedIdentifier --- cpp/ql/src/Telemetry/Diagnostics.qll | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/cpp/ql/src/Telemetry/Diagnostics.qll b/cpp/ql/src/Telemetry/Diagnostics.qll index 19cb818ab17..b5019425c8e 100644 --- a/cpp/ql/src/Telemetry/Diagnostics.qll +++ b/cpp/ql/src/Telemetry/Diagnostics.qll @@ -27,15 +27,3 @@ class CannotOpenFile extends CompilerError { result = this.getMessage().regexpCapture("cannot open source file '([^']+)'", 1) } } - -/** - * An undefined identifier error. - * Currently unused. - */ -class UndefinedIdentifier extends CompilerError { - UndefinedIdentifier() { this.hasTag("undefined_identifier") } - - string getIdentifier() { - result = this.getMessage().regexpCapture("identifier '([^']+)' is undefined", 1) - } -} From 34ee947d2f50444ce7e30029ac385acce883376c Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Mon, 11 Nov 2024 15:11:05 +0000 Subject: [PATCH 09/14] C++: Limit number of errors/includes to 50 --- cpp/ql/src/Telemetry/CompilerErrors.ql | 2 +- cpp/ql/src/Telemetry/MissingIncludes.ql | 2 +- cpp/ql/src/Telemetry/SucceededIncludes.ql | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cpp/ql/src/Telemetry/CompilerErrors.ql b/cpp/ql/src/Telemetry/CompilerErrors.ql index a4e5cd5f8fc..0f5166f9e9f 100644 --- a/cpp/ql/src/Telemetry/CompilerErrors.ql +++ b/cpp/ql/src/Telemetry/CompilerErrors.ql @@ -9,5 +9,5 @@ import Metrics from CppMetrics::ErrorCount m -where RankMetric::getRank(m) <= 500 +where RankMetric::getRank(m) <= 50 select m.toString(), m.getValue() diff --git a/cpp/ql/src/Telemetry/MissingIncludes.ql b/cpp/ql/src/Telemetry/MissingIncludes.ql index a3a65de7577..6ff58729dd2 100644 --- a/cpp/ql/src/Telemetry/MissingIncludes.ql +++ b/cpp/ql/src/Telemetry/MissingIncludes.ql @@ -9,5 +9,5 @@ import Metrics from CppMetrics::MissingIncludeCount e -where RankMetric::getRank(e) <= 500 +where RankMetric::getRank(e) <= 50 select e.getIncludeText(), e.getValue() diff --git a/cpp/ql/src/Telemetry/SucceededIncludes.ql b/cpp/ql/src/Telemetry/SucceededIncludes.ql index dda4fa414d9..aa08acd9fdb 100644 --- a/cpp/ql/src/Telemetry/SucceededIncludes.ql +++ b/cpp/ql/src/Telemetry/SucceededIncludes.ql @@ -9,5 +9,5 @@ import Metrics from CppMetrics::SucceededIncludeCount m -where RankMetric::getRank(m) <= 500 +where RankMetric::getRank(m) <= 50 select m.getIncludeText(), m.getValue() From fb82d435b5e1d3e6704327ac7efde09a25b94f2e Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Mon, 11 Nov 2024 15:27:58 +0000 Subject: [PATCH 10/14] C++: Various renamings --- cpp/ql/src/Telemetry/Diagnostics.qll | 4 +-- cpp/ql/src/Telemetry/Metrics.qll | 28 +++++++++---------- .../DatabaseQuality.expected | 2 +- .../ExtractionMetrics.expected | 4 +-- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/cpp/ql/src/Telemetry/Diagnostics.qll b/cpp/ql/src/Telemetry/Diagnostics.qll index b5019425c8e..cc7dcb3a36d 100644 --- a/cpp/ql/src/Telemetry/Diagnostics.qll +++ b/cpp/ql/src/Telemetry/Diagnostics.qll @@ -20,8 +20,8 @@ class SyntaxError extends CompilerError { * A cannot open file error. * Typically this is due to a missing include. */ -class CannotOpenFile extends CompilerError { - CannotOpenFile() { this.hasTag(["cannot_open_file", "cannot_open_file_reason"]) } +class CannotOpenFileError extends CompilerError { + CannotOpenFileError() { this.hasTag(["cannot_open_file", "cannot_open_file_reason"]) } string getIncludedFile() { result = this.getMessage().regexpCapture("cannot open source file '([^']+)'", 1) diff --git a/cpp/ql/src/Telemetry/Metrics.qll b/cpp/ql/src/Telemetry/Metrics.qll index 168b6a13c97..74d90426825 100644 --- a/cpp/ql/src/Telemetry/Metrics.qll +++ b/cpp/ql/src/Telemetry/Metrics.qll @@ -47,16 +47,16 @@ abstract class SuccessMetric extends ExtractionMetric { * A metric used to report database quality. */ class QualityMetric extends Metric { - BaseMetric base_metric; - SuccessMetric relative_metric; + BaseMetric baseMetric; + SuccessMetric relativeMetric; QualityMetric() { - base_metric = relative_metric.getBaseline() and this = "Percentage of " + relative_metric + baseMetric = relativeMetric.getBaseline() and this = "Percentage of " + relativeMetric } float getValue() { - base_metric.getValue() > 0 and - result = 100.0 * relative_metric.getValue() / base_metric.getValue() + baseMetric.getValue() > 0 and + result = 100.0 * relativeMetric.getValue() / baseMetric.getValue() } } @@ -70,8 +70,8 @@ module RankMetric { /** Various metrics we want to report. */ module CppMetrics { - class CompilationUnits extends BaseMetric { - CompilationUnits() { this = "compilation units" } + class Compilations extends BaseMetric { + Compilations() { this = "compilations" } override int getValue() { result = count(Compilation c) } } @@ -92,14 +92,14 @@ module CppMetrics { override SourceFiles getBaseline() { any() } } - class CompilationUnitsWithoutErrors extends SuccessMetric { - CompilationUnitsWithoutErrors() { this = "compilation units without errors" } + class CompilationsWithoutErrors extends SuccessMetric { + CompilationsWithoutErrors() { this = "compilations without errors" } override int getValue() { result = count(Compilation c | not exists(Diagnostic d | d.getFile() = c.getAFileCompiled())) } - override CompilationUnits getBaseline() { any() } + override Compilations getBaseline() { any() } } class Expressions extends BaseMetric { @@ -186,7 +186,7 @@ module CppMetrics { override int getValue() { result = sum(File f | | f.getMetrics().getNumberOfLinesOfCode()) - - count(File file, int line | errorLine(file, line)) + count(File f, int line | errorLine(f, line)) } override LinesOfCode getBaseline() { any() } @@ -209,7 +209,7 @@ module CppMetrics { class Includes extends BaseMetric { Includes() { this = "#include directives" } - override int getValue() { result = count(Include i) + count(CannotOpenFile e) } + override int getValue() { result = count(Include i) + count(CannotOpenFileError e) } } class SucceededIncludes extends SuccessMetric { @@ -240,11 +240,11 @@ module CppMetrics { string include_text; MissingIncludeCount() { - exists(CannotOpenFile e | e.getIncludedFile() = include_text) and + exists(CannotOpenFileError e | e.getIncludedFile() = include_text) and this = "Failed to include '" + include_text + "'" } - int getValue() { result = count(CannotOpenFile e | e.getIncludedFile() = include_text) } + int getValue() { result = count(CannotOpenFileError e | e.getIncludedFile() = include_text) } string getIncludeText() { result = include_text } } diff --git a/cpp/ql/test/library-tests/extraction_errors/DatabaseQuality.expected b/cpp/ql/test/library-tests/extraction_errors/DatabaseQuality.expected index 73e5a585a43..22ad915bfb9 100644 --- a/cpp/ql/test/library-tests/extraction_errors/DatabaseQuality.expected +++ b/cpp/ql/test/library-tests/extraction_errors/DatabaseQuality.expected @@ -1,5 +1,5 @@ | Percentage of calls with a target | 50.0 | -| Percentage of compilation units without errors | 50.0 | +| Percentage of compilations without errors | 50.0 | | Percentage of expressions with a known type | 30.0 | | Percentage of functions without errors | 75.0 | | Percentage of lines of code without errors | 63.1578947368421 | diff --git a/cpp/ql/test/library-tests/extraction_errors/ExtractionMetrics.expected b/cpp/ql/test/library-tests/extraction_errors/ExtractionMetrics.expected index 5530005b709..c6e455eaf29 100644 --- a/cpp/ql/test/library-tests/extraction_errors/ExtractionMetrics.expected +++ b/cpp/ql/test/library-tests/extraction_errors/ExtractionMetrics.expected @@ -1,8 +1,8 @@ | #include directives | 2 | | calls | 2 | | calls with a target | 1 | -| compilation units | 2 | -| compilation units without errors | 1 | +| compilations | 2 | +| compilations without errors | 1 | | compiler errors | 10 | | expressions | 10 | | expressions with a known type | 3 | From 593dcb646b596938138e2134b1656db3e65af758 Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Mon, 11 Nov 2024 15:48:57 +0000 Subject: [PATCH 11/14] C++: Remove missing includes test --- .../library-tests/extraction_errors/MissingIncludes.expected | 0 .../test/library-tests/extraction_errors/MissingIncludes.qlref | 1 - 2 files changed, 1 deletion(-) delete mode 100644 cpp/ql/test/library-tests/extraction_errors/MissingIncludes.expected delete mode 100644 cpp/ql/test/library-tests/extraction_errors/MissingIncludes.qlref diff --git a/cpp/ql/test/library-tests/extraction_errors/MissingIncludes.expected b/cpp/ql/test/library-tests/extraction_errors/MissingIncludes.expected deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/cpp/ql/test/library-tests/extraction_errors/MissingIncludes.qlref b/cpp/ql/test/library-tests/extraction_errors/MissingIncludes.qlref deleted file mode 100644 index 8481a932a57..00000000000 --- a/cpp/ql/test/library-tests/extraction_errors/MissingIncludes.qlref +++ /dev/null @@ -1 +0,0 @@ -Telemetry/MissingIncludes.ql \ No newline at end of file From 2351328aa185abb3519483f29e55ee9ffc2839f7 Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Mon, 11 Nov 2024 16:17:19 +0000 Subject: [PATCH 12/14] C++: Rename SourceFiles metric --- cpp/ql/src/Telemetry/Metrics.qll | 10 +++++----- .../extraction_errors/DatabaseQuality.expected | 2 +- .../extraction_errors/ExtractionMetrics.expected | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/cpp/ql/src/Telemetry/Metrics.qll b/cpp/ql/src/Telemetry/Metrics.qll index 74d90426825..41d817e4411 100644 --- a/cpp/ql/src/Telemetry/Metrics.qll +++ b/cpp/ql/src/Telemetry/Metrics.qll @@ -76,20 +76,20 @@ module CppMetrics { override int getValue() { result = count(Compilation c) } } - class SourceFiles extends BaseMetric { - SourceFiles() { this = "source files" } + class SourceAndHeaderFiles extends BaseMetric { + SourceAndHeaderFiles() { this = "source/header files" } override int getValue() { result = count(File f | f.fromSource()) } } - class SourceFilesWithoutErrors extends SuccessMetric { - SourceFilesWithoutErrors() { this = "source files without errors" } + class SourceAndHeaderFilesWithoutErrors extends SuccessMetric { + SourceAndHeaderFilesWithoutErrors() { this = "source/header files without errors" } override int getValue() { result = count(File f | f.fromSource() and not exists(CompilerError e | f = e.getFile())) } - override SourceFiles getBaseline() { any() } + override SourceAndHeaderFiles getBaseline() { any() } } class CompilationsWithoutErrors extends SuccessMetric { diff --git a/cpp/ql/test/library-tests/extraction_errors/DatabaseQuality.expected b/cpp/ql/test/library-tests/extraction_errors/DatabaseQuality.expected index 22ad915bfb9..cd55ff43477 100644 --- a/cpp/ql/test/library-tests/extraction_errors/DatabaseQuality.expected +++ b/cpp/ql/test/library-tests/extraction_errors/DatabaseQuality.expected @@ -4,6 +4,6 @@ | Percentage of functions without errors | 75.0 | | Percentage of lines of code without errors | 63.1578947368421 | | Percentage of non-error expressions | 30.0 | -| Percentage of source files without errors | 66.66666666666667 | +| Percentage of source/header files without errors | 66.66666666666667 | | Percentage of successfully resolved #include directives | 100.0 | | Percentage of variables with a known type | 90.0 | diff --git a/cpp/ql/test/library-tests/extraction_errors/ExtractionMetrics.expected b/cpp/ql/test/library-tests/extraction_errors/ExtractionMetrics.expected index c6e455eaf29..c0e97d037db 100644 --- a/cpp/ql/test/library-tests/extraction_errors/ExtractionMetrics.expected +++ b/cpp/ql/test/library-tests/extraction_errors/ExtractionMetrics.expected @@ -12,8 +12,8 @@ | lines of code without errors | 12 | | lines of text | 24 | | non-error expressions | 3 | -| source files | 3 | -| source files without errors | 2 | +| source/header files | 3 | +| source/header files without errors | 2 | | successfully resolved #include directives | 2 | | syntax errors | 3 | | variables | 10 | From 317f43d32528ba0337e4400f26eabc5c23ffac2d Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Mon, 11 Nov 2024 16:31:36 +0000 Subject: [PATCH 13/14] C++: Don't use PrintAST in a test --- .../extraction_errors/ErrorExprs.expected | 7 ++ .../extraction_errors/ErrorExprs.ql | 4 + .../extraction_errors/PrintAst.expected | 79 ------------------- .../extraction_errors/PrintAst.qlref | 1 - 4 files changed, 11 insertions(+), 80 deletions(-) create mode 100644 cpp/ql/test/library-tests/extraction_errors/ErrorExprs.expected create mode 100644 cpp/ql/test/library-tests/extraction_errors/ErrorExprs.ql delete mode 100644 cpp/ql/test/library-tests/extraction_errors/PrintAst.expected delete mode 100644 cpp/ql/test/library-tests/extraction_errors/PrintAst.qlref diff --git a/cpp/ql/test/library-tests/extraction_errors/ErrorExprs.expected b/cpp/ql/test/library-tests/extraction_errors/ErrorExprs.expected new file mode 100644 index 00000000000..3f437a7fd26 --- /dev/null +++ b/cpp/ql/test/library-tests/extraction_errors/ErrorExprs.expected @@ -0,0 +1,7 @@ +| test.cpp:6:13:6:31 | initializer for x | test.cpp:6:13:6:31 | | +| test.cpp:7:5:7:8 | ExprStmt | file://:0:0:0:0 | | +| test.cpp:8:5:8:23 | ExprStmt | file://:0:0:0:0 | | +| test.cpp:9:5:9:21 | ExprStmt | file://:0:0:0:0 | | +| test.cpp:11:5:11:8 | ExprStmt | file://:0:0:0:0 | | +| test.cpp:15:5:15:8 | ExprStmt | file://:0:0:0:0 | | +| test.cpp:16:5:16:16 | ExprStmt | file://:0:0:0:0 | | diff --git a/cpp/ql/test/library-tests/extraction_errors/ErrorExprs.ql b/cpp/ql/test/library-tests/extraction_errors/ErrorExprs.ql new file mode 100644 index 00000000000..25c2118e010 --- /dev/null +++ b/cpp/ql/test/library-tests/extraction_errors/ErrorExprs.ql @@ -0,0 +1,4 @@ +import cpp + +from ErrorExpr e +select e.getParent(), e diff --git a/cpp/ql/test/library-tests/extraction_errors/PrintAst.expected b/cpp/ql/test/library-tests/extraction_errors/PrintAst.expected deleted file mode 100644 index ce2b59b6a08..00000000000 --- a/cpp/ql/test/library-tests/extraction_errors/PrintAst.expected +++ /dev/null @@ -1,79 +0,0 @@ -#-----| [CopyAssignmentOperator] __va_list_tag& __va_list_tag::operator=(__va_list_tag const&) -#-----| : -#-----| getParameter(0): [Parameter] (unnamed parameter 0) -#-----| Type = [LValueReferenceType] const __va_list_tag & -#-----| [MoveAssignmentOperator] __va_list_tag& __va_list_tag::operator=(__va_list_tag&&) -#-----| : -#-----| getParameter(0): [Parameter] (unnamed parameter 0) -#-----| Type = [RValueReferenceType] __va_list_tag && -test.c: -# 3| [TopLevelFunction] void g() -# 3| : -# 3| getEntryPoint(): [BlockStmt] { ... } -# 4| getStmt(0): [DeclStmt] declaration -# 4| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x -# 4| Type = [IntType] int -# 4| getVariable().getInitializer(): [Initializer] initializer for x -# 4| getExpr(): [FunctionCall] call to no_such_function -# 4| Type = [IntType] int -# 4| ValueCategory = prvalue -# 5| getStmt(1): [ReturnStmt] return ... -# 4| [TopLevelFunction] int no_such_function() -# 4| : -test.cpp: -# 5| [TopLevelFunction] void function_with_errors() -# 5| : -# 5| getEntryPoint(): [BlockStmt] { ... } -# 6| getStmt(0): [DeclStmt] declaration -# 6| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x -# 6| Type = [ErroneousType] error -# 6| getVariable().getInitializer(): [Initializer] initializer for x -# 6| getExpr(): [ErrorExpr] -# 6| Type = [ErroneousType] error -# 6| ValueCategory = prvalue -# 7| getStmt(1): [ExprStmt] ExprStmt -#-----| getExpr(): [ErrorExpr] -#-----| Type = [ErroneousType] error -#-----| ValueCategory = prvalue -# 8| getStmt(2): [ExprStmt] ExprStmt -#-----| getExpr(): [ErrorExpr] -#-----| Type = [ErroneousType] error -#-----| ValueCategory = prvalue -# 9| getStmt(3): [ExprStmt] ExprStmt -#-----| getExpr(): [ErrorExpr] -#-----| Type = [ErroneousType] error -#-----| ValueCategory = prvalue -# 10| getStmt(4): [ExprStmt] ExprStmt -# 10| getExpr(): [FunctionCall] call to f -# 10| Type = [IntType] int -# 10| ValueCategory = prvalue -# 10| getArgument(0): [Literal] 1 -# 10| Type = [IntType] int -# 10| Value = [Literal] 1 -# 10| ValueCategory = prvalue -# 11| getStmt(5): [ExprStmt] ExprStmt -#-----| getExpr(): [ErrorExpr] -#-----| Type = [ErroneousType] error -#-----| ValueCategory = prvalue -# 12| getStmt(6): [ReturnStmt] return ... -# 14| [TopLevelFunction] error fn2() -# 14| : -# 14| getEntryPoint(): [BlockStmt] { ... } -# 15| getStmt(0): [ExprStmt] ExprStmt -#-----| getExpr(): [ErrorExpr] -#-----| Type = [ErroneousType] error -#-----| ValueCategory = prvalue -# 16| getStmt(1): [ExprStmt] ExprStmt -#-----| getExpr(): [ErrorExpr] -#-----| Type = [ErroneousType] error -#-----| ValueCategory = prvalue -# 17| getStmt(2): [ReturnStmt] return ... -test.h: -# 2| [TopLevelFunction] int f(int) -# 2| : -# 2| getParameter(0): [Parameter] (unnamed parameter 0) -# 2| Type = [IntType] int -# 2| [TopLevelFunction] int f(int) -# 2| : -# 2| getParameter(0): [Parameter] (unnamed parameter 0) -# 2| Type = [IntType] int diff --git a/cpp/ql/test/library-tests/extraction_errors/PrintAst.qlref b/cpp/ql/test/library-tests/extraction_errors/PrintAst.qlref deleted file mode 100644 index 6fcb30ac7a6..00000000000 --- a/cpp/ql/test/library-tests/extraction_errors/PrintAst.qlref +++ /dev/null @@ -1 +0,0 @@ -semmle/code/cpp/PrintAST.ql \ No newline at end of file From 91b1cb8a7676258a4c2632b54df8387657460334 Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Tue, 12 Nov 2024 09:46:50 +0000 Subject: [PATCH 14/14] C++: Some renaming --- cpp/ql/src/Telemetry/Metrics.qll | 24 +++++++++---------- .../DatabaseQuality.expected | 2 +- .../ExtractionMetrics.expected | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/cpp/ql/src/Telemetry/Metrics.qll b/cpp/ql/src/Telemetry/Metrics.qll index 41d817e4411..b3c90af8450 100644 --- a/cpp/ql/src/Telemetry/Metrics.qll +++ b/cpp/ql/src/Telemetry/Metrics.qll @@ -130,8 +130,8 @@ module CppMetrics { override int getValue() { result = count(Call c) } } - class SucceededCalls extends SuccessMetric { - SucceededCalls() { this = "calls with a target" } + class CallsWithExplicitTarget extends SuccessMetric { + CallsWithExplicitTarget() { this = "calls with an explicit target" } override int getValue() { result = count(Call c | not c.getTarget().getADeclarationEntry().isImplicit()) @@ -221,32 +221,32 @@ module CppMetrics { } class SucceededIncludeCount extends Metric { - string include_text; + string includeText; SucceededIncludeCount() { exists(Include i | - i.getIncludeText() = include_text and + i.getIncludeText() = includeText and exists(i.getFile().getRelativePath()) // Only report includes from the repo ) and - this = "Successfully included " + include_text + this = "Successfully included " + includeText } - int getValue() { result = count(Include i | i.getIncludeText() = include_text) } + int getValue() { result = count(Include i | i.getIncludeText() = includeText) } - string getIncludeText() { result = include_text } + string getIncludeText() { result = includeText } } class MissingIncludeCount extends Metric { - string include_text; + string includeText; MissingIncludeCount() { - exists(CannotOpenFileError e | e.getIncludedFile() = include_text) and - this = "Failed to include '" + include_text + "'" + exists(CannotOpenFileError e | e.getIncludedFile() = includeText) and + this = "Failed to include '" + includeText + "'" } - int getValue() { result = count(CannotOpenFileError e | e.getIncludedFile() = include_text) } + int getValue() { result = count(CannotOpenFileError e | e.getIncludedFile() = includeText) } - string getIncludeText() { result = include_text } + string getIncludeText() { result = includeText } } class CompilerErrors extends ExtractionMetric { diff --git a/cpp/ql/test/library-tests/extraction_errors/DatabaseQuality.expected b/cpp/ql/test/library-tests/extraction_errors/DatabaseQuality.expected index cd55ff43477..6d9cea2d734 100644 --- a/cpp/ql/test/library-tests/extraction_errors/DatabaseQuality.expected +++ b/cpp/ql/test/library-tests/extraction_errors/DatabaseQuality.expected @@ -1,4 +1,4 @@ -| Percentage of calls with a target | 50.0 | +| Percentage of calls with an explicit target | 50.0 | | Percentage of compilations without errors | 50.0 | | Percentage of expressions with a known type | 30.0 | | Percentage of functions without errors | 75.0 | diff --git a/cpp/ql/test/library-tests/extraction_errors/ExtractionMetrics.expected b/cpp/ql/test/library-tests/extraction_errors/ExtractionMetrics.expected index c0e97d037db..ee2cc0f9963 100644 --- a/cpp/ql/test/library-tests/extraction_errors/ExtractionMetrics.expected +++ b/cpp/ql/test/library-tests/extraction_errors/ExtractionMetrics.expected @@ -1,6 +1,6 @@ | #include directives | 2 | | calls | 2 | -| calls with a target | 1 | +| calls with an explicit target | 1 | | compilations | 2 | | compilations without errors | 1 | | compiler errors | 10 |