Compare commits

..

1 Commits

Author SHA1 Message Date
Taus
a87a1a1efa Python: Fix broken queries 2026-01-20 13:25:41 +00:00
16 changed files with 1104 additions and 11251 deletions

View File

@@ -1,13 +0,0 @@
class PreprocessorDirective extends @preprocdirect {
string toString() { none() }
}
class Location extends @location_default {
string toString() { none() }
}
from PreprocessorDirective ppd, int kind, int kind_new, Location l
where
preprocdirects(ppd, kind, l) and
if kind = 17 then kind_new = /* ppd_warning */ 18 else kind_new = kind
select ppd, kind_new, l

View File

@@ -1,4 +0,0 @@
description: Support embed preprocessor directive
compatibility: partial
embeds.rel: delete
preprocdirects.rel: run preprocdirects.qlo

View File

@@ -1,4 +0,0 @@
---
category: feature
---
* Added a subclass `Embed` of `PreprocessorDirective` for C23 and C++26 `#embed` preprocessor directives.

View File

@@ -328,27 +328,3 @@ class PreprocessorPragma extends PreprocessorDirective, @ppd_pragma {
class PreprocessorLine extends PreprocessorDirective, @ppd_line {
override string toString() { result = "#line " + this.getHead() }
}
/**
* A C23 or C++26 `#embed` preprocessor directive. For example, the following code
* contains one `Embed` directive:
* ```cpp
* char arr[] = {
* #embed "bin"
* };
* ```
*/
class Embed extends PreprocessorDirective, @ppd_embed {
override string toString() { result = "#embed " + this.getIncludeText() }
/**
* Gets the token which occurs after `#embed`, for example `"filename"`
* or `<filename>`.
*/
string getIncludeText() { result = this.getHead() }
/**
* Gets the file directly embedded by this `#embed`.
*/
File getEmbeddedFile() { embeds(underlyingElement(this), unresolveElement(result)) }
}

View File

@@ -21,7 +21,7 @@ private string getLocationFilePath(@location_default loc) {
* Gets the file path for an element with a single location.
*/
overlay[local]
string getSingleLocationFilePath(@element e) {
private string getSingleLocationFilePath(@element e) {
exists(@location_default loc |
var_decls(e, _, _, _, loc)
or
@@ -34,38 +34,6 @@ string getSingleLocationFilePath(@element e) {
macroinvocations(e, _, loc, _)
or
preprocdirects(e, _, loc)
or
diagnostics(e, _, _, _, _, loc)
or
usings(e, _, loc, _)
or
static_asserts(e, _, _, loc, _)
or
derivations(e, _, _, _, loc)
or
frienddecls(e, _, _, loc)
or
comments(e, _, loc)
or
exprs(e, _, loc)
or
stmts(e, _, loc)
or
initialisers(e, _, _, loc)
or
attributes(e, _, _, _, loc)
or
attribute_args(e, _, _, _, loc)
or
namequalifiers(e, _, _, loc)
or
enumconstants(e, _, _, _, _, loc)
or
type_mentions(e, _, loc, _)
or
lambda_capture(e, _, _, _, _, _, loc)
or
concept_templates(e, _, loc)
|
result = getLocationFilePath(loc)
)
@@ -75,7 +43,7 @@ string getSingleLocationFilePath(@element e) {
* Gets the file path for an element with potentially multiple locations.
*/
overlay[local]
string getMultiLocationFilePath(@element e) {
private string getMultiLocationFilePath(@element e) {
exists(@location_default loc |
exists(@var_decl vd | var_decls(vd, e, _, _, loc))
or

View File

@@ -1,64 +0,0 @@
/**
* Provides consistency queries for checking that every database entity
* that can be discarded (i.e. everything but `@compilation` and some external
* entities) in an overlay database is indeed discarded.
*
* This validates that Overlay.qll's `getSingleLocationFilePath` and
* `getMultiLocationFilePath` predicates cover all entity types.
*/
import cpp
private import Overlay
/**
* Holds if `element` is not covered by the discard predicates in Overlay.qll.
*
* This query is intended to flag cases where new entity types are added
* to the dbscheme but the corresponding discard predicate is not updated.
*
* An element is considered covered if it has a path via either
* `getSingleLocationFilePath` or `getMultiLocationFilePath`.
*/
query predicate consistencyTest(Element element, string message) {
(
// Check that every @element has a path via the discard predicates
not exists(getSingleLocationFilePath(element)) and
not exists(getMultiLocationFilePath(element)) and
// Exclude global/synthetic entities that don't need to be discarded
not element instanceof @specifier and
not element instanceof @builtintype and
not element instanceof @derivedtype and
not element instanceof @routinetype and
not element instanceof @ptrtomember and
not element instanceof @decltype and
not element instanceof @type_operator and
not element instanceof @specialnamequalifyingelement and
// Exclude files/folders (handled separately by overlay infrastructure)
not element instanceof @file and
not element instanceof @folder and
// Exclude XML entities (not C++ code)
not element instanceof @xmllocatable and
// Exclude compiler diagnostics (metadata, not source entities)
not element instanceof @diagnostic and
// Exclude usertypes without declarations (compiler built-ins like 'auto', '__va_list')
not (element instanceof @usertype and not exists(@type_decl td | type_decls(td, element, _))) and
// Exclude namespaces without declarations (global namespace)
not (
element instanceof @namespace and
not exists(@namespace_decl nd | namespace_decls(nd, element, _, _))
) and
// Exclude functions without declarations (compiler-generated like implicit operator=)
not (
element instanceof @function and not exists(@fun_decl fd | fun_decls(fd, element, _, _, _))
) and
// Exclude variables without declarations (parameters of compiler-generated functions)
not (
element instanceof @variable and not exists(@var_decl vd | var_decls(vd, element, _, _, _))
) and
exists(Location loc | loc = element.getLocation() |
message =
element.getPrimaryQlClasses() + " at " + loc.getFile().getRelativePath() + ":" +
loc.getStartLine().toString() + " not covered by discard predicates"
)
)
}

View File

@@ -2353,7 +2353,6 @@ case @preprocdirect.kind of
| 14 = @ppd_ms_import
| 15 = @ppd_elifdef
| 16 = @ppd_elifndef
| 17 = @ppd_embed
| 18 = @ppd_warning
;
@@ -2380,11 +2379,6 @@ includes(
int included: @file ref
);
embeds(
unique int id: @ppd_embed ref,
int included: @file ref
);
link_targets(
int id: @link_target,
int binary: @file ref

File diff suppressed because it is too large Load Diff

View File

@@ -1,2 +0,0 @@
description: Support embed preprocessor directive
compatibility: partial

View File

@@ -471,11 +471,10 @@ Definition getUniqueDefinition(Expr use) {
not result = TLocalDefinition(use)
}
/** A helper class to get suitable locations for attributes */
class NiceLocationExpr extends Expr {
/** Gets a textual representation of this element. */
override string toString() { result = this.(Expr).toString() }
final class FinalExpr = Expr;
/** A helper class to get suitable locations for attributes */
class NiceLocationExpr extends FinalExpr {
/**
* Holds if this element is at the specified location.
* The location spans column `bc` of line `bl` to

View File

@@ -3,8 +3,10 @@
import python
import semmle.python.dataflow.new.DataFlow
final class FinalAstNode = AstNode;
/** A looping construct. */
abstract class Loop extends AstNode {
abstract class Loop extends FinalAstNode {
/**
* Gets a loop variable of this loop.
* For example, `x` and `y` in `for x,y in pairs: print(x+y)`
@@ -13,9 +15,9 @@ abstract class Loop extends AstNode {
}
/** A `for` loop. */
private class ForLoop extends Loop, For {
private class ForLoop extends Loop instanceof For {
override Variable getALoopVariable() {
this.getTarget() = result.getAnAccess().getParentNode*() and
this.(For).getTarget() = result.getAnAccess().getParentNode*() and
result.getScope() = this.getScope()
}
}

View File

@@ -59,7 +59,9 @@ predicate ok_to_fail(ImportExpr ie) {
os_specific_import(ie) != get_os()
}
class VersionTest extends ControlFlowNode {
final class FinalControlFlowNode = ControlFlowNode;
class VersionTest extends FinalControlFlowNode {
VersionTest() {
exists(string name |
name.matches("%version%") and
@@ -70,7 +72,7 @@ class VersionTest extends ControlFlowNode {
)
}
override string toString() { result = "VersionTest" }
string toString() { result = "VersionTest" }
}
/** A guard on the version of the Python interpreter */