diff --git a/go/downgrades/23f2f56b5d3a846b4f73e3fa62510e36f934fb46/exprs.ql b/go/downgrades/23f2f56b5d3a846b4f73e3fa62510e36f934fb46/exprs.ql new file mode 100644 index 00000000000..80911bb7a6b --- /dev/null +++ b/go/downgrades/23f2f56b5d3a846b4f73e3fa62510e36f934fb46/exprs.ql @@ -0,0 +1,31 @@ +class Expr_ extends @expr { + string toString() { result = "Expr" } +} + +class ExprParent_ extends @exprparent { + string toString() { result = "ExprParent" } +} + +// The schema for exprs is: +// +// exprs(unique int id: @expr, +// int kind: int ref, +// int parent: @exprparent ref, +// int idx: int ref); +// +// `@rangeelementexpr` (kind 55) is a synthesized node that groups the loop +// variables (the key and value) of a `range` statement. To downgrade we remove +// those nodes and reparent their children (the key and value expressions) +// directly onto the `range` statement, at the same indices. +from Expr_ id, int kind, ExprParent_ newparent, int idx +where + exists(ExprParent_ parent | exprs(id, kind, parent, idx) and kind != 55 | + // A key or value grouped by a range element node: reparent it onto the + // range statement (the range element node's own parent). + exists(Expr_ pe | pe = parent and exprs(pe, 55, newparent, _)) + or + // Any other expression keeps its parent unchanged. + not exists(Expr_ pe | pe = parent and exprs(pe, 55, _, _)) and + newparent = parent + ) +select id, kind, newparent, idx diff --git a/go/downgrades/23f2f56b5d3a846b4f73e3fa62510e36f934fb46/go.dbscheme b/go/downgrades/23f2f56b5d3a846b4f73e3fa62510e36f934fb46/go.dbscheme new file mode 100644 index 00000000000..b1341734d68 --- /dev/null +++ b/go/downgrades/23f2f56b5d3a846b4f73e3fa62510e36f934fb46/go.dbscheme @@ -0,0 +1,563 @@ +/** Auto-generated dbscheme; do not edit. Run `make gen` in directory `go/` to regenerate. */ + + +/** Duplicate code **/ + +duplicateCode( + unique int id : @duplication, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +similarCode( + unique int id : @similarity, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +@duplication_or_similarity = @duplication | @similarity; + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref); + +/** External data **/ + +externalData( + int id : @externalDataElement, + varchar(900) path : string ref, + int column: int ref, + varchar(900) value : string ref +); + +snapshotDate(unique date snapshotDate : date ref); + +sourceLocationPrefix(varchar(900) prefix : string ref); + +/** Overlay support **/ + +databaseMetadata( + string metadataKey: string ref, + string value: string ref +); + +overlayChangedFiles( + string path: string ref +); + + +/* + * XML Files + */ + +xmlEncoding( + unique int id: @file ref, + string encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +compilations(unique int id: @compilation, string cwd: string ref); + +#keyset[id, num] +compilation_args(int id: @compilation ref, int num: int ref, string arg: string ref); + +#keyset[id, num, kind] +compilation_time(int id: @compilation ref, int num: int ref, int kind: int ref, float secs: float ref); + +diagnostic_for(unique int diagnostic: @diagnostic ref, int compilation: @compilation ref, int file_number: int ref, int file_number_diagnostic_number: int ref); + +compilation_finished(unique int id: @compilation ref, float cpu_seconds: float ref, float elapsed_seconds: float ref); + +#keyset[id, num] +compilation_compiling_files(int id: @compilation ref, int num: int ref, int file: @file ref); + +diagnostics(unique int id: @diagnostic, int severity: int ref, string error_tag: string ref, string error_message: string ref, + string full_error_message: string ref, int location: @location ref); + +locations_default(unique int id: @location_default, int file: @file ref, int beginLine: int ref, int beginColumn: int ref, + int endLine: int ref, int endColumn: int ref); + +numlines(int element_id: @sourceline ref, int num_lines: int ref, int num_code: int ref, int num_comment: int ref); + +files(unique int id: @file, string name: string ref); + +folders(unique int id: @folder, string name: string ref); + +containerparent(int parent: @container ref, unique int child: @container ref); + +has_location(unique int locatable: @locatable ref, int location: @location ref); + +#keyset[parent, idx] +comment_groups(unique int id: @comment_group, int parent: @file ref, int idx: int ref); + +comments(unique int id: @comment, int kind: int ref, int parent: @comment_group ref, int idx: int ref, string text: string ref); + +doc_comments(unique int node: @documentable ref, int comment: @comment_group ref); + +#keyset[parent, idx] +exprs(unique int id: @expr, int kind: int ref, int parent: @exprparent ref, int idx: int ref); + +literals(unique int expr: @expr ref, string value: string ref, string raw: string ref); + +constvalues(unique int expr: @expr ref, string value: string ref, string exact: string ref); + +fields(unique int id: @field, int parent: @fieldparent ref, int idx: int ref); + +typeparamdecls(unique int id: @typeparamdecl, int parent: @typeparamdeclparent ref, int idx: int ref); + +#keyset[parent, idx] +stmts(unique int id: @stmt, int kind: int ref, int parent: @stmtparent ref, int idx: int ref); + +#keyset[parent, idx] +decls(unique int id: @decl, int kind: int ref, int parent: @declparent ref, int idx: int ref); + +#keyset[parent, idx] +specs(unique int id: @spec, int kind: int ref, int parent: @gendecl ref, int idx: int ref); + +scopes(unique int id: @scope, int kind: int ref); + +scopenesting(unique int inner: @scope ref, int outer: @scope ref); + +scopenodes(unique int node: @scopenode ref, int scope: @localscope ref); + +objects(unique int id: @object, int kind: int ref, string name: string ref); + +objectscopes(unique int object: @object ref, int scope: @scope ref); + +objecttypes(unique int object: @object ref, int tp: @type ref); + +methodreceivers(unique int method: @object ref, int receiver: @object ref); + +fieldstructs(unique int field: @object ref, int struct: @structtype ref); + +methodhosts(int method: @object ref, int host: @definedtype ref); + +defs(int ident: @ident ref, int object: @object ref); + +uses(int ident: @ident ref, int object: @object ref); + +types(unique int id: @type, int kind: int ref); + +type_of(unique int expr: @expr ref, int tp: @type ref); + +typename(unique int tp: @type ref, string name: string ref); + +key_type(unique int map: @maptype ref, int tp: @type ref); + +element_type(unique int container: @containertype ref, int tp: @type ref); + +base_type(unique int ptr: @pointertype ref, int tp: @type ref); + +underlying_type(unique int defined: @definedtype ref, int tp: @type ref); + +#keyset[parent, index] +component_types(int parent: @compositetype ref, int index: int ref, string name: string ref, int tp: @type ref); + +#keyset[parent, index] +struct_tags(int parent: @structtype ref, int index: int ref, string tag: string ref); + +#keyset[interface, index] +interface_private_method_ids(int interface: @interfacetype ref, int index: int ref, string id: string ref); + +array_length(unique int tp: @arraytype ref, string len: string ref); + +type_objects(unique int tp: @type ref, int object: @object ref); + +packages(unique int id: @package, string name: string ref, string path: string ref, int scope: @packagescope ref); + +#keyset[parent, idx] +modexprs(unique int id: @modexpr, int kind: int ref, int parent: @modexprparent ref, int idx: int ref); + +#keyset[parent, idx] +modtokens(string token: string ref, int parent: @modexpr ref, int idx: int ref); + +#keyset[package, idx] +errors(unique int id: @error, int kind: int ref, string msg: string ref, string rawpos: string ref, + string file: string ref, int line: int ref, int col: int ref, int package: @package ref, int idx: int ref); + +has_ellipsis(int id: @callorconversionexpr ref); + +variadic(int id: @signaturetype ref); + +#keyset[parent, idx] +typeparam(unique int tp: @typeparamtype ref, string name: string ref, int bound: @compositetype ref, + int parent: @typeparamparentobject ref, int idx: int ref); + +@container = @file | @folder; + +@locatable = @xmllocatable | @node | @localscope; + +@node = @documentable | @exprparent | @modexprparent | @fieldparent | @stmtparent | @declparent | @typeparamdeclparent + | @scopenode | @comment_group | @comment; + +@documentable = @file | @field | @typeparamdecl | @spec | @gendecl | @funcdecl | @modexpr; + +@exprparent = @funcdef | @file | @expr | @field | @stmt | @decl | @typeparamdecl | @spec; + +@modexprparent = @file | @modexpr; + +@fieldparent = @decl | @structtypeexpr | @functypeexpr | @interfacetypeexpr; + +@stmtparent = @funcdef | @stmt | @decl; + +@declparent = @file | @declstmt; + +@typeparamdeclparent = @funcdecl | @typespec; + +@funcdef = @funclit | @funcdecl; + +@scopenode = @file | @functypeexpr | @blockstmt | @ifstmt | @caseclause | @switchstmt | @commclause | @loopstmt; + +@location = @location_default; + +@sourceline = @locatable; + +case @comment.kind of + 0 = @slashslashcomment +| 1 = @slashstarcomment; + +case @expr.kind of + 0 = @badexpr +| 1 = @ident +| 2 = @ellipsis +| 3 = @intlit +| 4 = @floatlit +| 5 = @imaglit +| 6 = @charlit +| 7 = @stringlit +| 8 = @funclit +| 9 = @compositelit +| 10 = @parenexpr +| 11 = @selectorexpr +| 12 = @indexexpr +| 13 = @genericfunctioninstantiationexpr +| 14 = @generictypeinstantiationexpr +| 15 = @sliceexpr +| 16 = @typeassertexpr +| 17 = @callorconversionexpr +| 18 = @starexpr +| 19 = @keyvalueexpr +| 20 = @arraytypeexpr +| 21 = @structtypeexpr +| 22 = @functypeexpr +| 23 = @interfacetypeexpr +| 24 = @maptypeexpr +| 25 = @typesetliteralexpr +| 26 = @plusexpr +| 27 = @minusexpr +| 28 = @notexpr +| 29 = @complementexpr +| 30 = @derefexpr +| 31 = @addressexpr +| 32 = @arrowexpr +| 33 = @lorexpr +| 34 = @landexpr +| 35 = @eqlexpr +| 36 = @neqexpr +| 37 = @lssexpr +| 38 = @leqexpr +| 39 = @gtrexpr +| 40 = @geqexpr +| 41 = @addexpr +| 42 = @subexpr +| 43 = @orexpr +| 44 = @xorexpr +| 45 = @mulexpr +| 46 = @quoexpr +| 47 = @remexpr +| 48 = @shlexpr +| 49 = @shrexpr +| 50 = @andexpr +| 51 = @andnotexpr +| 52 = @sendchantypeexpr +| 53 = @recvchantypeexpr +| 54 = @sendrcvchantypeexpr; + +@basiclit = @intlit | @floatlit | @imaglit | @charlit | @stringlit; + +@operatorexpr = @logicalexpr | @arithmeticexpr | @bitwiseexpr | @unaryexpr | @binaryexpr; + +@logicalexpr = @logicalunaryexpr | @logicalbinaryexpr; + +@arithmeticexpr = @arithmeticunaryexpr | @arithmeticbinaryexpr; + +@bitwiseexpr = @bitwiseunaryexpr | @bitwisebinaryexpr; + +@unaryexpr = @logicalunaryexpr | @bitwiseunaryexpr | @arithmeticunaryexpr | @derefexpr | @addressexpr | @arrowexpr; + +@logicalunaryexpr = @notexpr; + +@bitwiseunaryexpr = @complementexpr; + +@arithmeticunaryexpr = @plusexpr | @minusexpr; + +@binaryexpr = @logicalbinaryexpr | @bitwisebinaryexpr | @arithmeticbinaryexpr | @comparison; + +@logicalbinaryexpr = @lorexpr | @landexpr; + +@bitwisebinaryexpr = @shiftexpr | @orexpr | @xorexpr | @andexpr | @andnotexpr; + +@arithmeticbinaryexpr = @addexpr | @subexpr | @mulexpr | @quoexpr | @remexpr; + +@shiftexpr = @shlexpr | @shrexpr; + +@comparison = @equalitytest | @relationalcomparison; + +@equalitytest = @eqlexpr | @neqexpr; + +@relationalcomparison = @lssexpr | @leqexpr | @gtrexpr | @geqexpr; + +@chantypeexpr = @sendchantypeexpr | @recvchantypeexpr | @sendrcvchantypeexpr; + +case @stmt.kind of + 0 = @badstmt +| 1 = @declstmt +| 2 = @emptystmt +| 3 = @labeledstmt +| 4 = @exprstmt +| 5 = @sendstmt +| 6 = @incstmt +| 7 = @decstmt +| 8 = @gostmt +| 9 = @deferstmt +| 10 = @returnstmt +| 11 = @breakstmt +| 12 = @continuestmt +| 13 = @gotostmt +| 14 = @fallthroughstmt +| 15 = @blockstmt +| 16 = @ifstmt +| 17 = @caseclause +| 18 = @exprswitchstmt +| 19 = @typeswitchstmt +| 20 = @commclause +| 21 = @selectstmt +| 22 = @forstmt +| 23 = @rangestmt +| 24 = @assignstmt +| 25 = @definestmt +| 26 = @addassignstmt +| 27 = @subassignstmt +| 28 = @mulassignstmt +| 29 = @quoassignstmt +| 30 = @remassignstmt +| 31 = @andassignstmt +| 32 = @orassignstmt +| 33 = @xorassignstmt +| 34 = @shlassignstmt +| 35 = @shrassignstmt +| 36 = @andnotassignstmt; + +@incdecstmt = @incstmt | @decstmt; + +@assignment = @simpleassignstmt | @compoundassignstmt; + +@simpleassignstmt = @assignstmt | @definestmt; + +@compoundassignstmt = @addassignstmt | @subassignstmt | @mulassignstmt | @quoassignstmt | @remassignstmt + | @andassignstmt | @orassignstmt | @xorassignstmt | @shlassignstmt | @shrassignstmt | @andnotassignstmt; + +@branchstmt = @breakstmt | @continuestmt | @gotostmt | @fallthroughstmt; + +@switchstmt = @exprswitchstmt | @typeswitchstmt; + +@loopstmt = @forstmt | @rangestmt; + +case @decl.kind of + 0 = @baddecl +| 1 = @importdecl +| 2 = @constdecl +| 3 = @typedecl +| 4 = @vardecl +| 5 = @funcdecl; + +@gendecl = @importdecl | @constdecl | @typedecl | @vardecl; + +case @spec.kind of + 0 = @importspec +| 1 = @valuespec +| 2 = @typedefspec +| 3 = @aliasspec; + +@typespec = @typedefspec | @aliasspec; + +case @object.kind of + 0 = @pkgobject +| 1 = @decltypeobject +| 2 = @builtintypeobject +| 3 = @declconstobject +| 4 = @builtinconstobject +| 5 = @declvarobject +| 6 = @declfunctionobject +| 7 = @builtinfunctionobject +| 8 = @labelobject; + +@typeparamparentobject = @decltypeobject | @declfunctionobject; + +@declobject = @decltypeobject | @declconstobject | @declvarobject | @declfunctionobject; + +@builtinobject = @builtintypeobject | @builtinconstobject | @builtinfunctionobject; + +@typeobject = @decltypeobject | @builtintypeobject; + +@valueobject = @constobject | @varobject | @functionobject; + +@constobject = @declconstobject | @builtinconstobject; + +@varobject = @declvarobject; + +@functionobject = @declfunctionobject | @builtinfunctionobject; + +case @scope.kind of + 0 = @universescope +| 1 = @packagescope +| 2 = @localscope; + +case @type.kind of + 0 = @invalidtype +| 1 = @boolexprtype +| 2 = @inttype +| 3 = @int8type +| 4 = @int16type +| 5 = @int32type +| 6 = @int64type +| 7 = @uinttype +| 8 = @uint8type +| 9 = @uint16type +| 10 = @uint32type +| 11 = @uint64type +| 12 = @uintptrtype +| 13 = @float32type +| 14 = @float64type +| 15 = @complex64type +| 16 = @complex128type +| 17 = @stringexprtype +| 18 = @unsafepointertype +| 19 = @boolliteraltype +| 20 = @intliteraltype +| 21 = @runeliteraltype +| 22 = @floatliteraltype +| 23 = @complexliteraltype +| 24 = @stringliteraltype +| 25 = @nilliteraltype +| 26 = @typeparamtype +| 27 = @arraytype +| 28 = @slicetype +| 29 = @structtype +| 30 = @pointertype +| 31 = @interfacetype +| 32 = @tupletype +| 33 = @signaturetype +| 34 = @maptype +| 35 = @sendchantype +| 36 = @recvchantype +| 37 = @sendrcvchantype +| 38 = @definedtype +| 39 = @typesetliteraltype; + +@basictype = @booltype | @numerictype | @stringtype | @literaltype | @invalidtype | @unsafepointertype; + +@booltype = @boolexprtype | @boolliteraltype; + +@numerictype = @integertype | @floattype | @complextype; + +@integertype = @signedintegertype | @unsignedintegertype; + +@signedintegertype = @inttype | @int8type | @int16type | @int32type | @int64type | @intliteraltype | @runeliteraltype; + +@unsignedintegertype = @uinttype | @uint8type | @uint16type | @uint32type | @uint64type | @uintptrtype; + +@floattype = @float32type | @float64type | @floatliteraltype; + +@complextype = @complex64type | @complex128type | @complexliteraltype; + +@stringtype = @stringexprtype | @stringliteraltype; + +@literaltype = @boolliteraltype | @intliteraltype | @runeliteraltype | @floatliteraltype | @complexliteraltype + | @stringliteraltype | @nilliteraltype; + +@compositetype = @typeparamtype | @containertype | @structtype | @pointertype | @interfacetype | @tupletype + | @signaturetype | @definedtype | @typesetliteraltype; + +@containertype = @arraytype | @slicetype | @maptype | @chantype; + +@chantype = @sendchantype | @recvchantype | @sendrcvchantype; + +case @modexpr.kind of + 0 = @modcommentblock +| 1 = @modline +| 2 = @modlineblock +| 3 = @modlparen +| 4 = @modrparen; + +case @error.kind of + 0 = @unknownerror +| 1 = @listerror +| 2 = @parseerror +| 3 = @typeerror; + diff --git a/go/downgrades/23f2f56b5d3a846b4f73e3fa62510e36f934fb46/has_location.ql b/go/downgrades/23f2f56b5d3a846b4f73e3fa62510e36f934fb46/has_location.ql new file mode 100644 index 00000000000..34dda880ebd --- /dev/null +++ b/go/downgrades/23f2f56b5d3a846b4f73e3fa62510e36f934fb46/has_location.ql @@ -0,0 +1,23 @@ +class Locatable_ extends @locatable { + string toString() { result = "Locatable" } +} + +class Location_ extends @location { + string toString() { result = "Location" } +} + +class Expr_ extends @expr { + string toString() { result = "Expr" } +} + +// The schema for has_location is: +// +// has_location(unique int locatable: @locatable ref, int location: @location ref); +// +// The synthesized `@rangeelementexpr` nodes (kind 55) are removed by the +// accompanying `exprs` downgrade, so their locations must be removed too. +from Locatable_ locatable, Location_ location +where + has_location(locatable, location) and + not exists(Expr_ e | e = locatable and exprs(e, 55, _, _)) +select locatable, location diff --git a/go/downgrades/23f2f56b5d3a846b4f73e3fa62510e36f934fb46/old.dbscheme b/go/downgrades/23f2f56b5d3a846b4f73e3fa62510e36f934fb46/old.dbscheme new file mode 100644 index 00000000000..23f2f56b5d3 --- /dev/null +++ b/go/downgrades/23f2f56b5d3a846b4f73e3fa62510e36f934fb46/old.dbscheme @@ -0,0 +1,564 @@ +/** Auto-generated dbscheme; do not edit. Run `make gen` in directory `go/` to regenerate. */ + + +/** Duplicate code **/ + +duplicateCode( + unique int id : @duplication, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +similarCode( + unique int id : @similarity, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +@duplication_or_similarity = @duplication | @similarity; + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref); + +/** External data **/ + +externalData( + int id : @externalDataElement, + varchar(900) path : string ref, + int column: int ref, + varchar(900) value : string ref +); + +snapshotDate(unique date snapshotDate : date ref); + +sourceLocationPrefix(varchar(900) prefix : string ref); + +/** Overlay support **/ + +databaseMetadata( + string metadataKey: string ref, + string value: string ref +); + +overlayChangedFiles( + string path: string ref +); + + +/* + * XML Files + */ + +xmlEncoding( + unique int id: @file ref, + string encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +compilations(unique int id: @compilation, string cwd: string ref); + +#keyset[id, num] +compilation_args(int id: @compilation ref, int num: int ref, string arg: string ref); + +#keyset[id, num, kind] +compilation_time(int id: @compilation ref, int num: int ref, int kind: int ref, float secs: float ref); + +diagnostic_for(unique int diagnostic: @diagnostic ref, int compilation: @compilation ref, int file_number: int ref, int file_number_diagnostic_number: int ref); + +compilation_finished(unique int id: @compilation ref, float cpu_seconds: float ref, float elapsed_seconds: float ref); + +#keyset[id, num] +compilation_compiling_files(int id: @compilation ref, int num: int ref, int file: @file ref); + +diagnostics(unique int id: @diagnostic, int severity: int ref, string error_tag: string ref, string error_message: string ref, + string full_error_message: string ref, int location: @location ref); + +locations_default(unique int id: @location_default, int file: @file ref, int beginLine: int ref, int beginColumn: int ref, + int endLine: int ref, int endColumn: int ref); + +numlines(int element_id: @sourceline ref, int num_lines: int ref, int num_code: int ref, int num_comment: int ref); + +files(unique int id: @file, string name: string ref); + +folders(unique int id: @folder, string name: string ref); + +containerparent(int parent: @container ref, unique int child: @container ref); + +has_location(unique int locatable: @locatable ref, int location: @location ref); + +#keyset[parent, idx] +comment_groups(unique int id: @comment_group, int parent: @file ref, int idx: int ref); + +comments(unique int id: @comment, int kind: int ref, int parent: @comment_group ref, int idx: int ref, string text: string ref); + +doc_comments(unique int node: @documentable ref, int comment: @comment_group ref); + +#keyset[parent, idx] +exprs(unique int id: @expr, int kind: int ref, int parent: @exprparent ref, int idx: int ref); + +literals(unique int expr: @expr ref, string value: string ref, string raw: string ref); + +constvalues(unique int expr: @expr ref, string value: string ref, string exact: string ref); + +fields(unique int id: @field, int parent: @fieldparent ref, int idx: int ref); + +typeparamdecls(unique int id: @typeparamdecl, int parent: @typeparamdeclparent ref, int idx: int ref); + +#keyset[parent, idx] +stmts(unique int id: @stmt, int kind: int ref, int parent: @stmtparent ref, int idx: int ref); + +#keyset[parent, idx] +decls(unique int id: @decl, int kind: int ref, int parent: @declparent ref, int idx: int ref); + +#keyset[parent, idx] +specs(unique int id: @spec, int kind: int ref, int parent: @gendecl ref, int idx: int ref); + +scopes(unique int id: @scope, int kind: int ref); + +scopenesting(unique int inner: @scope ref, int outer: @scope ref); + +scopenodes(unique int node: @scopenode ref, int scope: @localscope ref); + +objects(unique int id: @object, int kind: int ref, string name: string ref); + +objectscopes(unique int object: @object ref, int scope: @scope ref); + +objecttypes(unique int object: @object ref, int tp: @type ref); + +methodreceivers(unique int method: @object ref, int receiver: @object ref); + +fieldstructs(unique int field: @object ref, int struct: @structtype ref); + +methodhosts(int method: @object ref, int host: @definedtype ref); + +defs(int ident: @ident ref, int object: @object ref); + +uses(int ident: @ident ref, int object: @object ref); + +types(unique int id: @type, int kind: int ref); + +type_of(unique int expr: @expr ref, int tp: @type ref); + +typename(unique int tp: @type ref, string name: string ref); + +key_type(unique int map: @maptype ref, int tp: @type ref); + +element_type(unique int container: @containertype ref, int tp: @type ref); + +base_type(unique int ptr: @pointertype ref, int tp: @type ref); + +underlying_type(unique int defined: @definedtype ref, int tp: @type ref); + +#keyset[parent, index] +component_types(int parent: @compositetype ref, int index: int ref, string name: string ref, int tp: @type ref); + +#keyset[parent, index] +struct_tags(int parent: @structtype ref, int index: int ref, string tag: string ref); + +#keyset[interface, index] +interface_private_method_ids(int interface: @interfacetype ref, int index: int ref, string id: string ref); + +array_length(unique int tp: @arraytype ref, string len: string ref); + +type_objects(unique int tp: @type ref, int object: @object ref); + +packages(unique int id: @package, string name: string ref, string path: string ref, int scope: @packagescope ref); + +#keyset[parent, idx] +modexprs(unique int id: @modexpr, int kind: int ref, int parent: @modexprparent ref, int idx: int ref); + +#keyset[parent, idx] +modtokens(string token: string ref, int parent: @modexpr ref, int idx: int ref); + +#keyset[package, idx] +errors(unique int id: @error, int kind: int ref, string msg: string ref, string rawpos: string ref, + string file: string ref, int line: int ref, int col: int ref, int package: @package ref, int idx: int ref); + +has_ellipsis(int id: @callorconversionexpr ref); + +variadic(int id: @signaturetype ref); + +#keyset[parent, idx] +typeparam(unique int tp: @typeparamtype ref, string name: string ref, int bound: @compositetype ref, + int parent: @typeparamparentobject ref, int idx: int ref); + +@container = @file | @folder; + +@locatable = @xmllocatable | @node | @localscope; + +@node = @documentable | @exprparent | @modexprparent | @fieldparent | @stmtparent | @declparent | @typeparamdeclparent + | @scopenode | @comment_group | @comment; + +@documentable = @file | @field | @typeparamdecl | @spec | @gendecl | @funcdecl | @modexpr; + +@exprparent = @funcdef | @file | @expr | @field | @stmt | @decl | @typeparamdecl | @spec; + +@modexprparent = @file | @modexpr; + +@fieldparent = @decl | @structtypeexpr | @functypeexpr | @interfacetypeexpr; + +@stmtparent = @funcdef | @stmt | @decl; + +@declparent = @file | @declstmt; + +@typeparamdeclparent = @funcdecl | @typespec; + +@funcdef = @funclit | @funcdecl; + +@scopenode = @file | @functypeexpr | @blockstmt | @ifstmt | @caseclause | @switchstmt | @commclause | @loopstmt; + +@location = @location_default; + +@sourceline = @locatable; + +case @comment.kind of + 0 = @slashslashcomment +| 1 = @slashstarcomment; + +case @expr.kind of + 0 = @badexpr +| 1 = @ident +| 2 = @ellipsis +| 3 = @intlit +| 4 = @floatlit +| 5 = @imaglit +| 6 = @charlit +| 7 = @stringlit +| 8 = @funclit +| 9 = @compositelit +| 10 = @parenexpr +| 11 = @selectorexpr +| 12 = @indexexpr +| 13 = @genericfunctioninstantiationexpr +| 14 = @generictypeinstantiationexpr +| 15 = @sliceexpr +| 16 = @typeassertexpr +| 17 = @callorconversionexpr +| 18 = @starexpr +| 19 = @keyvalueexpr +| 20 = @arraytypeexpr +| 21 = @structtypeexpr +| 22 = @functypeexpr +| 23 = @interfacetypeexpr +| 24 = @maptypeexpr +| 25 = @typesetliteralexpr +| 26 = @plusexpr +| 27 = @minusexpr +| 28 = @notexpr +| 29 = @complementexpr +| 30 = @derefexpr +| 31 = @addressexpr +| 32 = @arrowexpr +| 33 = @lorexpr +| 34 = @landexpr +| 35 = @eqlexpr +| 36 = @neqexpr +| 37 = @lssexpr +| 38 = @leqexpr +| 39 = @gtrexpr +| 40 = @geqexpr +| 41 = @addexpr +| 42 = @subexpr +| 43 = @orexpr +| 44 = @xorexpr +| 45 = @mulexpr +| 46 = @quoexpr +| 47 = @remexpr +| 48 = @shlexpr +| 49 = @shrexpr +| 50 = @andexpr +| 51 = @andnotexpr +| 52 = @sendchantypeexpr +| 53 = @recvchantypeexpr +| 54 = @sendrcvchantypeexpr +| 55 = @rangeelementexpr; + +@basiclit = @intlit | @floatlit | @imaglit | @charlit | @stringlit; + +@operatorexpr = @logicalexpr | @arithmeticexpr | @bitwiseexpr | @unaryexpr | @binaryexpr; + +@logicalexpr = @logicalunaryexpr | @logicalbinaryexpr; + +@arithmeticexpr = @arithmeticunaryexpr | @arithmeticbinaryexpr; + +@bitwiseexpr = @bitwiseunaryexpr | @bitwisebinaryexpr; + +@unaryexpr = @logicalunaryexpr | @bitwiseunaryexpr | @arithmeticunaryexpr | @derefexpr | @addressexpr | @arrowexpr; + +@logicalunaryexpr = @notexpr; + +@bitwiseunaryexpr = @complementexpr; + +@arithmeticunaryexpr = @plusexpr | @minusexpr; + +@binaryexpr = @logicalbinaryexpr | @bitwisebinaryexpr | @arithmeticbinaryexpr | @comparison; + +@logicalbinaryexpr = @lorexpr | @landexpr; + +@bitwisebinaryexpr = @shiftexpr | @orexpr | @xorexpr | @andexpr | @andnotexpr; + +@arithmeticbinaryexpr = @addexpr | @subexpr | @mulexpr | @quoexpr | @remexpr; + +@shiftexpr = @shlexpr | @shrexpr; + +@comparison = @equalitytest | @relationalcomparison; + +@equalitytest = @eqlexpr | @neqexpr; + +@relationalcomparison = @lssexpr | @leqexpr | @gtrexpr | @geqexpr; + +@chantypeexpr = @sendchantypeexpr | @recvchantypeexpr | @sendrcvchantypeexpr; + +case @stmt.kind of + 0 = @badstmt +| 1 = @declstmt +| 2 = @emptystmt +| 3 = @labeledstmt +| 4 = @exprstmt +| 5 = @sendstmt +| 6 = @incstmt +| 7 = @decstmt +| 8 = @gostmt +| 9 = @deferstmt +| 10 = @returnstmt +| 11 = @breakstmt +| 12 = @continuestmt +| 13 = @gotostmt +| 14 = @fallthroughstmt +| 15 = @blockstmt +| 16 = @ifstmt +| 17 = @caseclause +| 18 = @exprswitchstmt +| 19 = @typeswitchstmt +| 20 = @commclause +| 21 = @selectstmt +| 22 = @forstmt +| 23 = @rangestmt +| 24 = @assignstmt +| 25 = @definestmt +| 26 = @addassignstmt +| 27 = @subassignstmt +| 28 = @mulassignstmt +| 29 = @quoassignstmt +| 30 = @remassignstmt +| 31 = @andassignstmt +| 32 = @orassignstmt +| 33 = @xorassignstmt +| 34 = @shlassignstmt +| 35 = @shrassignstmt +| 36 = @andnotassignstmt; + +@incdecstmt = @incstmt | @decstmt; + +@assignment = @simpleassignstmt | @compoundassignstmt; + +@simpleassignstmt = @assignstmt | @definestmt; + +@compoundassignstmt = @addassignstmt | @subassignstmt | @mulassignstmt | @quoassignstmt | @remassignstmt + | @andassignstmt | @orassignstmt | @xorassignstmt | @shlassignstmt | @shrassignstmt | @andnotassignstmt; + +@branchstmt = @breakstmt | @continuestmt | @gotostmt | @fallthroughstmt; + +@switchstmt = @exprswitchstmt | @typeswitchstmt; + +@loopstmt = @forstmt | @rangestmt; + +case @decl.kind of + 0 = @baddecl +| 1 = @importdecl +| 2 = @constdecl +| 3 = @typedecl +| 4 = @vardecl +| 5 = @funcdecl; + +@gendecl = @importdecl | @constdecl | @typedecl | @vardecl; + +case @spec.kind of + 0 = @importspec +| 1 = @valuespec +| 2 = @typedefspec +| 3 = @aliasspec; + +@typespec = @typedefspec | @aliasspec; + +case @object.kind of + 0 = @pkgobject +| 1 = @decltypeobject +| 2 = @builtintypeobject +| 3 = @declconstobject +| 4 = @builtinconstobject +| 5 = @declvarobject +| 6 = @declfunctionobject +| 7 = @builtinfunctionobject +| 8 = @labelobject; + +@typeparamparentobject = @decltypeobject | @declfunctionobject; + +@declobject = @decltypeobject | @declconstobject | @declvarobject | @declfunctionobject; + +@builtinobject = @builtintypeobject | @builtinconstobject | @builtinfunctionobject; + +@typeobject = @decltypeobject | @builtintypeobject; + +@valueobject = @constobject | @varobject | @functionobject; + +@constobject = @declconstobject | @builtinconstobject; + +@varobject = @declvarobject; + +@functionobject = @declfunctionobject | @builtinfunctionobject; + +case @scope.kind of + 0 = @universescope +| 1 = @packagescope +| 2 = @localscope; + +case @type.kind of + 0 = @invalidtype +| 1 = @boolexprtype +| 2 = @inttype +| 3 = @int8type +| 4 = @int16type +| 5 = @int32type +| 6 = @int64type +| 7 = @uinttype +| 8 = @uint8type +| 9 = @uint16type +| 10 = @uint32type +| 11 = @uint64type +| 12 = @uintptrtype +| 13 = @float32type +| 14 = @float64type +| 15 = @complex64type +| 16 = @complex128type +| 17 = @stringexprtype +| 18 = @unsafepointertype +| 19 = @boolliteraltype +| 20 = @intliteraltype +| 21 = @runeliteraltype +| 22 = @floatliteraltype +| 23 = @complexliteraltype +| 24 = @stringliteraltype +| 25 = @nilliteraltype +| 26 = @typeparamtype +| 27 = @arraytype +| 28 = @slicetype +| 29 = @structtype +| 30 = @pointertype +| 31 = @interfacetype +| 32 = @tupletype +| 33 = @signaturetype +| 34 = @maptype +| 35 = @sendchantype +| 36 = @recvchantype +| 37 = @sendrcvchantype +| 38 = @definedtype +| 39 = @typesetliteraltype; + +@basictype = @booltype | @numerictype | @stringtype | @literaltype | @invalidtype | @unsafepointertype; + +@booltype = @boolexprtype | @boolliteraltype; + +@numerictype = @integertype | @floattype | @complextype; + +@integertype = @signedintegertype | @unsignedintegertype; + +@signedintegertype = @inttype | @int8type | @int16type | @int32type | @int64type | @intliteraltype | @runeliteraltype; + +@unsignedintegertype = @uinttype | @uint8type | @uint16type | @uint32type | @uint64type | @uintptrtype; + +@floattype = @float32type | @float64type | @floatliteraltype; + +@complextype = @complex64type | @complex128type | @complexliteraltype; + +@stringtype = @stringexprtype | @stringliteraltype; + +@literaltype = @boolliteraltype | @intliteraltype | @runeliteraltype | @floatliteraltype | @complexliteraltype + | @stringliteraltype | @nilliteraltype; + +@compositetype = @typeparamtype | @containertype | @structtype | @pointertype | @interfacetype | @tupletype + | @signaturetype | @definedtype | @typesetliteraltype; + +@containertype = @arraytype | @slicetype | @maptype | @chantype; + +@chantype = @sendchantype | @recvchantype | @sendrcvchantype; + +case @modexpr.kind of + 0 = @modcommentblock +| 1 = @modline +| 2 = @modlineblock +| 3 = @modlparen +| 4 = @modrparen; + +case @error.kind of + 0 = @unknownerror +| 1 = @listerror +| 2 = @parseerror +| 3 = @typeerror; + diff --git a/go/downgrades/23f2f56b5d3a846b4f73e3fa62510e36f934fb46/upgrade.properties b/go/downgrades/23f2f56b5d3a846b4f73e3fa62510e36f934fb46/upgrade.properties new file mode 100644 index 00000000000..abaabbd305d --- /dev/null +++ b/go/downgrades/23f2f56b5d3a846b4f73e3fa62510e36f934fb46/upgrade.properties @@ -0,0 +1,4 @@ +description: Remove @rangeelementexpr, reparenting range loop variables onto the range statement +compatibility: full +exprs.rel: run exprs.qlo +has_location.rel: run has_location.qlo diff --git a/go/extractor/dbscheme/tables.go b/go/extractor/dbscheme/tables.go index 9c537fbaf89..5554750a5db 100644 --- a/go/extractor/dbscheme/tables.go +++ b/go/extractor/dbscheme/tables.go @@ -532,6 +532,12 @@ var ChanTypeExprs = map[ast.ChanDir]*BranchType{ ast.SEND | ast.RECV: ExprKind.NewBranch("@sendrcvchantypeexpr", ChanTypeExpr), } +// RangeElementExpr is the type of the synthesized node representing the loop +// variables (key and value) bound by a `range` statement. It groups the key and +// value expressions into a single "tuple pattern" target, mirroring how other +// languages present a single variable node for a `foreach` loop. +var RangeElementExpr = ExprKind.NewBranch("@rangeelementexpr") + // StmtKind is a case type for distinguishing different kinds of statement AST nodes var StmtKind = NewCaseType(StmtType, "kind") diff --git a/go/extractor/extractor.go b/go/extractor/extractor.go index 158f0029704..8248015d79a 100644 --- a/go/extractor/extractor.go +++ b/go/extractor/extractor.go @@ -1416,8 +1416,18 @@ func extractStmt(tw *trap.Writer, stmt ast.Stmt, parent trap.Label, idx int) { emitScopeNodeInfo(tw, stmt, lbl) case *ast.RangeStmt: kind = dbscheme.RangeStmtType.Index() - extractExpr(tw, stmt.Key, lbl, 0, false) - extractExpr(tw, stmt.Value, lbl, 1, false) + // Synthesize a "range element" node that groups the loop variables (the + // key and value) into a single target. This mirrors how other languages + // present a single loop-variable node for a `foreach` loop and lets the + // shared control-flow library drive the destructuring through this node. + patternLbl := tw.Labeler.FreshID() + dbscheme.ExprsTable.Emit(tw, patternLbl, dbscheme.RangeElementExpr.Index(), lbl, 0) + // The range element node uses the location of the whole range statement, + // so that the destructuring control-flow and data-flow nodes derived from + // it keep the same location they had before this node was introduced. + extractNodeLocation(tw, stmt, patternLbl) + extractExpr(tw, stmt.Key, patternLbl, 0, false) + extractExpr(tw, stmt.Value, patternLbl, 1, false) extractExpr(tw, stmt.X, lbl, 2, false) extractStmt(tw, stmt.Body, lbl, 3) emitScopeNodeInfo(tw, stmt, lbl) diff --git a/go/ql/lib/go.dbscheme b/go/ql/lib/go.dbscheme index b1341734d68..23f2f56b5d3 100644 --- a/go/ql/lib/go.dbscheme +++ b/go/ql/lib/go.dbscheme @@ -336,7 +336,8 @@ case @expr.kind of | 51 = @andnotexpr | 52 = @sendchantypeexpr | 53 = @recvchantypeexpr -| 54 = @sendrcvchantypeexpr; +| 54 = @sendrcvchantypeexpr +| 55 = @rangeelementexpr; @basiclit = @intlit | @floatlit | @imaglit | @charlit | @stringlit; diff --git a/go/ql/lib/semmle/go/Stmt.qll b/go/ql/lib/semmle/go/Stmt.qll index 8deadd55512..8b04e6c197f 100644 --- a/go/ql/lib/semmle/go/Stmt.qll +++ b/go/ql/lib/semmle/go/Stmt.qll @@ -1148,11 +1148,14 @@ class ForStmt extends @forstmt, LoopStmt { * ``` */ class RangeStmt extends @rangestmt, LoopStmt { + /** Gets the synthesized node grouping the loop variables of this `range` statement. */ + RangeElementExpr getPattern() { result = this.getChildExpr(0) } + /** Gets the expression denoting the key of this `range` statement. */ - Expr getKey() { result = this.getChildExpr(0) } + Expr getKey() { result = this.getPattern().getKey() } /** Get the expression denoting the value of this `range` statement. */ - Expr getValue() { result = this.getChildExpr(1) } + Expr getValue() { result = this.getPattern().getValue() } /** Gets the domain of this `range` statement. */ Expr getDomain() { result = this.getChildExpr(2) } @@ -1165,3 +1168,31 @@ class RangeStmt extends @rangestmt, LoopStmt { override string getAPrimaryQlClass() { result = "RangeStmt" } } + +/** + * A synthesized node grouping the loop variables (key and value) bound by a + * `range` statement. + * + * This node acts as the single target of the destructuring performed on each + * iteration of the loop, so that a `range` statement can be modelled with a + * single loop-variable node in the same way as a `foreach` loop in other + * languages. It is present for every `range` statement, even when no loop + * variables are bound (as in `for range x`). + */ +class RangeElementExpr extends @rangeelementexpr, Expr { + /** Gets the `range` statement that this node belongs to. */ + RangeStmt getRangeStmt() { result = this.getParent() } + + /** Gets the expression denoting the key of the `range` statement. */ + Expr getKey() { result = this.getChildExpr(0) } + + /** Gets the expression denoting the value of the `range` statement. */ + Expr getValue() { result = this.getChildExpr(1) } + + /** Gets the domain of the `range` statement. */ + Expr getDomain() { result = this.getRangeStmt().getDomain() } + + override string toString() { result = "range element" } + + override string getAPrimaryQlClass() { result = "RangeElementExpr" } +} diff --git a/go/ql/lib/semmle/go/controlflow/ControlFlowGraphShared.qll b/go/ql/lib/semmle/go/controlflow/ControlFlowGraphShared.qll index d4c41ed9b14..71ea3b8b815 100644 --- a/go/ql/lib/semmle/go/controlflow/ControlFlowGraphShared.qll +++ b/go/ql/lib/semmle/go/controlflow/ControlFlowGraphShared.qll @@ -212,11 +212,17 @@ module GoCfg { } class ForeachStmt extends LoopStmt { - ForeachStmt() { none() } + ForeachStmt() { this instanceof Go::RangeStmt } - Expr getVariable() { none() } + // Go's `range` statement binds its key and value by destructuring the + // current element. The extractor synthesizes a single "range element" + // node grouping the key and value (see `Go::RangeElementExpr`), which we + // present here as the loop variable. The shared library routes control + // flow into and out of this node, and Go wires the destructuring through + // it (see `rangeStmtStep`). + Expr getVariable() { result = this.(Go::RangeStmt).getPattern() } - Expr getCollection() { none() } + Expr getCollection() { result = this.(Go::RangeStmt).getDomain() } } class BreakStmt = Go::BreakStmt; @@ -504,13 +510,16 @@ module GoCfg { or notBlankIdent(n.(Go::ValueSpec).getNameExpr(i)) or - notBlankIdent(n.(Go::RangeStmt).getKey()) and i = 0 + notBlankIdent(n.(Go::RangeElementExpr).getKey()) and i = 0 or - notBlankIdent(n.(Go::RangeStmt).getValue()) and i = 1 + notBlankIdent(n.(Go::RangeElementExpr).getValue()) and i = 1 ) and tag = "assign:" + i.toString() ) or + // Get the next key-value pair produced by a `range` statement. + n instanceof Go::RangeElementExpr and tag = "next" + or // Compound assignment implicit RHS n instanceof Go::CompoundAssignStmt and tag = "compound-rhs" or @@ -574,9 +583,6 @@ module GoCfg { tag = "result-zero-init:" + i.toString() ) or - // Next node for range statements - n instanceof Go::RangeStmt and tag = "next" - or // Implicit deref implicitDerefCondition(n) and tag = "implicit-deref" or @@ -632,10 +638,10 @@ module GoCfg { exists(spec.getNameExpr(i)) ) or - exists(Go::RangeStmt rs | s = rs | - exists(rs.getKey()) and i = 0 + exists(Go::RangeElementExpr p | s = p | + exists(p.getKey()) and i = 0 or - exists(rs.getValue()) and i = 1 + exists(p.getValue()) and i = 1 ) or exists(Go::ReturnStmt ret, Go::SignatureType rettp | @@ -1010,7 +1016,7 @@ module GoCfg { predicate overridesCallableBodyExit(Ast::Callable c) { funcHasDefer(c.(Go::FuncDef)) } predicate step(PreControlFlowNode n1, PreControlFlowNode n2) { - rangeLoop(n1, n2) or + rangeStmtStep(n1, n2) or selectStmt(n1, n2) or deferStmt(n1, n2) or goStmtStep(n1, n2) or @@ -1139,9 +1145,9 @@ module GoCfg { or notBlankIdent(assgn.(Go::ValueSpec).getNameExpr(j)) or - notBlankIdent(assgn.(Go::RangeStmt).getKey()) and j = 0 + notBlankIdent(assgn.(Go::RangeElementExpr).getKey()) and j = 0 or - notBlankIdent(assgn.(Go::RangeStmt).getValue()) and j = 1 + notBlankIdent(assgn.(Go::RangeElementExpr).getValue()) and j = 1 ) and result = "assign:" + j.toString() and ord = 2 * j + 1 @@ -1511,34 +1517,31 @@ module GoCfg { ) } - private predicate rangeLoop(PreControlFlowNode n1, PreControlFlowNode n2) { - exists(Go::RangeStmt s | - // Use the shared library's auto-created `[LoopHeader]` additional node - // (created for every `LoopStmt`) as the join/branch point of the range loop. - n1.isBefore(s) and n2.isBefore(s.getDomain()) + private predicate rangeStmtStep(PreControlFlowNode n1, PreControlFlowNode n2) { + exists(Go::RangeElementExpr p | + // The shared `ForeachStmt` model owns the loop skeleton (testing the + // domain for emptiness, the `[LoopHeader]` join/branch point, and the + // loop exit) and routes control flow into `Before(p)` and out of + // `After(p)`, where `p` is the synthesized "range element" loop + // variable. Here we get the next key-value pair and destructure it into + // the key/value variables using the shared extract/assign epilogue + // machinery. + n1.isBefore(p) and n2.isAdditional(p, "next") or - n1.isAfter(s.getDomain()) and n2.isAdditional(s, "[LoopHeader]") - or - n1.isAdditional(s, "[LoopHeader]") and n2.isAdditional(s, "next") - or - n1.isAdditional(s, "next") and + n1.isAdditional(p, "next") and ( - exists(getFirstEpilogueTag(s)) and n2.isAdditional(s, getFirstEpilogueTag(s)) + exists(getFirstEpilogueTag(p)) and n2.isAdditional(p, getFirstEpilogueTag(p)) or - not exists(getFirstEpilogueTag(s)) and n2.isBefore(s.getBody()) + not exists(getFirstEpilogueTag(p)) and n2.isAfter(p) ) or exists(string tag1, string tag2 | - epilogueSucc(s, tag1, tag2) and - n1.isAdditional(s, tag1) and - n2.isAdditional(s, tag2) + epilogueSucc(p, tag1, tag2) and + n1.isAdditional(p, tag1) and + n2.isAdditional(p, tag2) ) or - n1.isAdditional(s, getLastEpilogueTag(s)) and n2.isBefore(s.getBody()) - or - n1.isAfter(s.getBody()) and n2.isAdditional(s, "[LoopHeader]") - or - n1.isAdditional(s, "[LoopHeader]") and n2.isAfter(s) + n1.isAdditional(p, getLastEpilogueTag(p)) and n2.isAfter(p) ) } diff --git a/go/ql/lib/semmle/go/controlflow/IR.qll b/go/ql/lib/semmle/go/controlflow/IR.qll index f554e66810a..a2eb3d89bd8 100644 --- a/go/ql/lib/semmle/go/controlflow/IR.qll +++ b/go/ql/lib/semmle/go/controlflow/IR.qll @@ -709,7 +709,7 @@ module IR { or exists(assgn.(ValueSpec).getNameExpr(i)) or - assgn instanceof RangeStmt and i in [0, 1] + assgn instanceof RangeElementExpr and i in [0, 1] ) } @@ -763,7 +763,7 @@ module IR { or exists(s.(ValueSpec).getNameExpr(i)) or - s instanceof RangeStmt and i in [0, 1] + s instanceof RangeElementExpr and i in [0, 1] or exists(s.(ReturnStmt).getEnclosingFunction().getType().(SignatureType).getResultType(i)) or @@ -803,7 +803,9 @@ module IR { result = e.getType().(TupleType).getComponentType(pragma[only_bind_into](i)) ) or - exists(Type rangeType | rangeType = s.(RangeStmt).getDomain().getType().getUnderlyingType() | + exists(Type rangeType | + rangeType = s.(RangeElementExpr).getDomain().getType().getUnderlyingType() + | exists(Type baseType | baseType = rangeType.(ArrayType).getElementType() or baseType = @@ -1105,16 +1107,16 @@ module IR { /** An instruction that gets the next key-value pair in a range loop. */ class GetNextEntryInstruction extends Instruction { - RangeStmt rs; + RangeElementExpr p; - GetNextEntryInstruction() { this.isAdditional(rs, "next") } + GetNextEntryInstruction() { this.isAdditional(p, "next") } /** * Gets the instruction computing the value whose key-value pairs this instruction reads. */ - Instruction getDomain() { result = evalExprInstruction(rs.getDomain()) } + Instruction getDomain() { result = evalExprInstruction(p.getDomain()) } - override ControlFlow::Root getRoot() { result.isRootOf(rs) } + override ControlFlow::Root getRoot() { result.isRootOf(p.getRangeStmt()) } } /** @@ -1240,10 +1242,10 @@ module IR { or lhs = assgn.(ValueSpec).getNameExpr(i) or - exists(RangeStmt rs | rs = assgn | - i = 0 and lhs = rs.getKey().stripParens() + exists(RangeElementExpr p | p = assgn | + i = 0 and lhs = p.getKey().stripParens() or - i = 1 and lhs = rs.getValue().stripParens() + i = 1 and lhs = p.getValue().stripParens() ) ) or @@ -1496,13 +1498,17 @@ module IR { * Gets the instruction corresponding to the assignment of the key variable * of range statement `rs`. */ - AssignInstruction assignKeyInstruction(RangeStmt rs) { result.isAdditional(rs, "assign:0") } + AssignInstruction assignKeyInstruction(RangeStmt rs) { + result.isAdditional(rs.getPattern(), "assign:0") + } /** * Gets the instruction corresponding to the assignment of the value variable * of range statement `rs`. */ - AssignInstruction assignValueInstruction(RangeStmt rs) { result.isAdditional(rs, "assign:1") } + AssignInstruction assignValueInstruction(RangeStmt rs) { + result.isAdditional(rs.getPattern(), "assign:1") + } /** * Gets the instruction corresponding to the implicit initialization of `v` diff --git a/go/ql/lib/upgrades/b1341734d6870b105e5c9d168ce7dec25d7f72d0/go.dbscheme b/go/ql/lib/upgrades/b1341734d6870b105e5c9d168ce7dec25d7f72d0/go.dbscheme new file mode 100644 index 00000000000..23f2f56b5d3 --- /dev/null +++ b/go/ql/lib/upgrades/b1341734d6870b105e5c9d168ce7dec25d7f72d0/go.dbscheme @@ -0,0 +1,564 @@ +/** Auto-generated dbscheme; do not edit. Run `make gen` in directory `go/` to regenerate. */ + + +/** Duplicate code **/ + +duplicateCode( + unique int id : @duplication, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +similarCode( + unique int id : @similarity, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +@duplication_or_similarity = @duplication | @similarity; + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref); + +/** External data **/ + +externalData( + int id : @externalDataElement, + varchar(900) path : string ref, + int column: int ref, + varchar(900) value : string ref +); + +snapshotDate(unique date snapshotDate : date ref); + +sourceLocationPrefix(varchar(900) prefix : string ref); + +/** Overlay support **/ + +databaseMetadata( + string metadataKey: string ref, + string value: string ref +); + +overlayChangedFiles( + string path: string ref +); + + +/* + * XML Files + */ + +xmlEncoding( + unique int id: @file ref, + string encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +compilations(unique int id: @compilation, string cwd: string ref); + +#keyset[id, num] +compilation_args(int id: @compilation ref, int num: int ref, string arg: string ref); + +#keyset[id, num, kind] +compilation_time(int id: @compilation ref, int num: int ref, int kind: int ref, float secs: float ref); + +diagnostic_for(unique int diagnostic: @diagnostic ref, int compilation: @compilation ref, int file_number: int ref, int file_number_diagnostic_number: int ref); + +compilation_finished(unique int id: @compilation ref, float cpu_seconds: float ref, float elapsed_seconds: float ref); + +#keyset[id, num] +compilation_compiling_files(int id: @compilation ref, int num: int ref, int file: @file ref); + +diagnostics(unique int id: @diagnostic, int severity: int ref, string error_tag: string ref, string error_message: string ref, + string full_error_message: string ref, int location: @location ref); + +locations_default(unique int id: @location_default, int file: @file ref, int beginLine: int ref, int beginColumn: int ref, + int endLine: int ref, int endColumn: int ref); + +numlines(int element_id: @sourceline ref, int num_lines: int ref, int num_code: int ref, int num_comment: int ref); + +files(unique int id: @file, string name: string ref); + +folders(unique int id: @folder, string name: string ref); + +containerparent(int parent: @container ref, unique int child: @container ref); + +has_location(unique int locatable: @locatable ref, int location: @location ref); + +#keyset[parent, idx] +comment_groups(unique int id: @comment_group, int parent: @file ref, int idx: int ref); + +comments(unique int id: @comment, int kind: int ref, int parent: @comment_group ref, int idx: int ref, string text: string ref); + +doc_comments(unique int node: @documentable ref, int comment: @comment_group ref); + +#keyset[parent, idx] +exprs(unique int id: @expr, int kind: int ref, int parent: @exprparent ref, int idx: int ref); + +literals(unique int expr: @expr ref, string value: string ref, string raw: string ref); + +constvalues(unique int expr: @expr ref, string value: string ref, string exact: string ref); + +fields(unique int id: @field, int parent: @fieldparent ref, int idx: int ref); + +typeparamdecls(unique int id: @typeparamdecl, int parent: @typeparamdeclparent ref, int idx: int ref); + +#keyset[parent, idx] +stmts(unique int id: @stmt, int kind: int ref, int parent: @stmtparent ref, int idx: int ref); + +#keyset[parent, idx] +decls(unique int id: @decl, int kind: int ref, int parent: @declparent ref, int idx: int ref); + +#keyset[parent, idx] +specs(unique int id: @spec, int kind: int ref, int parent: @gendecl ref, int idx: int ref); + +scopes(unique int id: @scope, int kind: int ref); + +scopenesting(unique int inner: @scope ref, int outer: @scope ref); + +scopenodes(unique int node: @scopenode ref, int scope: @localscope ref); + +objects(unique int id: @object, int kind: int ref, string name: string ref); + +objectscopes(unique int object: @object ref, int scope: @scope ref); + +objecttypes(unique int object: @object ref, int tp: @type ref); + +methodreceivers(unique int method: @object ref, int receiver: @object ref); + +fieldstructs(unique int field: @object ref, int struct: @structtype ref); + +methodhosts(int method: @object ref, int host: @definedtype ref); + +defs(int ident: @ident ref, int object: @object ref); + +uses(int ident: @ident ref, int object: @object ref); + +types(unique int id: @type, int kind: int ref); + +type_of(unique int expr: @expr ref, int tp: @type ref); + +typename(unique int tp: @type ref, string name: string ref); + +key_type(unique int map: @maptype ref, int tp: @type ref); + +element_type(unique int container: @containertype ref, int tp: @type ref); + +base_type(unique int ptr: @pointertype ref, int tp: @type ref); + +underlying_type(unique int defined: @definedtype ref, int tp: @type ref); + +#keyset[parent, index] +component_types(int parent: @compositetype ref, int index: int ref, string name: string ref, int tp: @type ref); + +#keyset[parent, index] +struct_tags(int parent: @structtype ref, int index: int ref, string tag: string ref); + +#keyset[interface, index] +interface_private_method_ids(int interface: @interfacetype ref, int index: int ref, string id: string ref); + +array_length(unique int tp: @arraytype ref, string len: string ref); + +type_objects(unique int tp: @type ref, int object: @object ref); + +packages(unique int id: @package, string name: string ref, string path: string ref, int scope: @packagescope ref); + +#keyset[parent, idx] +modexprs(unique int id: @modexpr, int kind: int ref, int parent: @modexprparent ref, int idx: int ref); + +#keyset[parent, idx] +modtokens(string token: string ref, int parent: @modexpr ref, int idx: int ref); + +#keyset[package, idx] +errors(unique int id: @error, int kind: int ref, string msg: string ref, string rawpos: string ref, + string file: string ref, int line: int ref, int col: int ref, int package: @package ref, int idx: int ref); + +has_ellipsis(int id: @callorconversionexpr ref); + +variadic(int id: @signaturetype ref); + +#keyset[parent, idx] +typeparam(unique int tp: @typeparamtype ref, string name: string ref, int bound: @compositetype ref, + int parent: @typeparamparentobject ref, int idx: int ref); + +@container = @file | @folder; + +@locatable = @xmllocatable | @node | @localscope; + +@node = @documentable | @exprparent | @modexprparent | @fieldparent | @stmtparent | @declparent | @typeparamdeclparent + | @scopenode | @comment_group | @comment; + +@documentable = @file | @field | @typeparamdecl | @spec | @gendecl | @funcdecl | @modexpr; + +@exprparent = @funcdef | @file | @expr | @field | @stmt | @decl | @typeparamdecl | @spec; + +@modexprparent = @file | @modexpr; + +@fieldparent = @decl | @structtypeexpr | @functypeexpr | @interfacetypeexpr; + +@stmtparent = @funcdef | @stmt | @decl; + +@declparent = @file | @declstmt; + +@typeparamdeclparent = @funcdecl | @typespec; + +@funcdef = @funclit | @funcdecl; + +@scopenode = @file | @functypeexpr | @blockstmt | @ifstmt | @caseclause | @switchstmt | @commclause | @loopstmt; + +@location = @location_default; + +@sourceline = @locatable; + +case @comment.kind of + 0 = @slashslashcomment +| 1 = @slashstarcomment; + +case @expr.kind of + 0 = @badexpr +| 1 = @ident +| 2 = @ellipsis +| 3 = @intlit +| 4 = @floatlit +| 5 = @imaglit +| 6 = @charlit +| 7 = @stringlit +| 8 = @funclit +| 9 = @compositelit +| 10 = @parenexpr +| 11 = @selectorexpr +| 12 = @indexexpr +| 13 = @genericfunctioninstantiationexpr +| 14 = @generictypeinstantiationexpr +| 15 = @sliceexpr +| 16 = @typeassertexpr +| 17 = @callorconversionexpr +| 18 = @starexpr +| 19 = @keyvalueexpr +| 20 = @arraytypeexpr +| 21 = @structtypeexpr +| 22 = @functypeexpr +| 23 = @interfacetypeexpr +| 24 = @maptypeexpr +| 25 = @typesetliteralexpr +| 26 = @plusexpr +| 27 = @minusexpr +| 28 = @notexpr +| 29 = @complementexpr +| 30 = @derefexpr +| 31 = @addressexpr +| 32 = @arrowexpr +| 33 = @lorexpr +| 34 = @landexpr +| 35 = @eqlexpr +| 36 = @neqexpr +| 37 = @lssexpr +| 38 = @leqexpr +| 39 = @gtrexpr +| 40 = @geqexpr +| 41 = @addexpr +| 42 = @subexpr +| 43 = @orexpr +| 44 = @xorexpr +| 45 = @mulexpr +| 46 = @quoexpr +| 47 = @remexpr +| 48 = @shlexpr +| 49 = @shrexpr +| 50 = @andexpr +| 51 = @andnotexpr +| 52 = @sendchantypeexpr +| 53 = @recvchantypeexpr +| 54 = @sendrcvchantypeexpr +| 55 = @rangeelementexpr; + +@basiclit = @intlit | @floatlit | @imaglit | @charlit | @stringlit; + +@operatorexpr = @logicalexpr | @arithmeticexpr | @bitwiseexpr | @unaryexpr | @binaryexpr; + +@logicalexpr = @logicalunaryexpr | @logicalbinaryexpr; + +@arithmeticexpr = @arithmeticunaryexpr | @arithmeticbinaryexpr; + +@bitwiseexpr = @bitwiseunaryexpr | @bitwisebinaryexpr; + +@unaryexpr = @logicalunaryexpr | @bitwiseunaryexpr | @arithmeticunaryexpr | @derefexpr | @addressexpr | @arrowexpr; + +@logicalunaryexpr = @notexpr; + +@bitwiseunaryexpr = @complementexpr; + +@arithmeticunaryexpr = @plusexpr | @minusexpr; + +@binaryexpr = @logicalbinaryexpr | @bitwisebinaryexpr | @arithmeticbinaryexpr | @comparison; + +@logicalbinaryexpr = @lorexpr | @landexpr; + +@bitwisebinaryexpr = @shiftexpr | @orexpr | @xorexpr | @andexpr | @andnotexpr; + +@arithmeticbinaryexpr = @addexpr | @subexpr | @mulexpr | @quoexpr | @remexpr; + +@shiftexpr = @shlexpr | @shrexpr; + +@comparison = @equalitytest | @relationalcomparison; + +@equalitytest = @eqlexpr | @neqexpr; + +@relationalcomparison = @lssexpr | @leqexpr | @gtrexpr | @geqexpr; + +@chantypeexpr = @sendchantypeexpr | @recvchantypeexpr | @sendrcvchantypeexpr; + +case @stmt.kind of + 0 = @badstmt +| 1 = @declstmt +| 2 = @emptystmt +| 3 = @labeledstmt +| 4 = @exprstmt +| 5 = @sendstmt +| 6 = @incstmt +| 7 = @decstmt +| 8 = @gostmt +| 9 = @deferstmt +| 10 = @returnstmt +| 11 = @breakstmt +| 12 = @continuestmt +| 13 = @gotostmt +| 14 = @fallthroughstmt +| 15 = @blockstmt +| 16 = @ifstmt +| 17 = @caseclause +| 18 = @exprswitchstmt +| 19 = @typeswitchstmt +| 20 = @commclause +| 21 = @selectstmt +| 22 = @forstmt +| 23 = @rangestmt +| 24 = @assignstmt +| 25 = @definestmt +| 26 = @addassignstmt +| 27 = @subassignstmt +| 28 = @mulassignstmt +| 29 = @quoassignstmt +| 30 = @remassignstmt +| 31 = @andassignstmt +| 32 = @orassignstmt +| 33 = @xorassignstmt +| 34 = @shlassignstmt +| 35 = @shrassignstmt +| 36 = @andnotassignstmt; + +@incdecstmt = @incstmt | @decstmt; + +@assignment = @simpleassignstmt | @compoundassignstmt; + +@simpleassignstmt = @assignstmt | @definestmt; + +@compoundassignstmt = @addassignstmt | @subassignstmt | @mulassignstmt | @quoassignstmt | @remassignstmt + | @andassignstmt | @orassignstmt | @xorassignstmt | @shlassignstmt | @shrassignstmt | @andnotassignstmt; + +@branchstmt = @breakstmt | @continuestmt | @gotostmt | @fallthroughstmt; + +@switchstmt = @exprswitchstmt | @typeswitchstmt; + +@loopstmt = @forstmt | @rangestmt; + +case @decl.kind of + 0 = @baddecl +| 1 = @importdecl +| 2 = @constdecl +| 3 = @typedecl +| 4 = @vardecl +| 5 = @funcdecl; + +@gendecl = @importdecl | @constdecl | @typedecl | @vardecl; + +case @spec.kind of + 0 = @importspec +| 1 = @valuespec +| 2 = @typedefspec +| 3 = @aliasspec; + +@typespec = @typedefspec | @aliasspec; + +case @object.kind of + 0 = @pkgobject +| 1 = @decltypeobject +| 2 = @builtintypeobject +| 3 = @declconstobject +| 4 = @builtinconstobject +| 5 = @declvarobject +| 6 = @declfunctionobject +| 7 = @builtinfunctionobject +| 8 = @labelobject; + +@typeparamparentobject = @decltypeobject | @declfunctionobject; + +@declobject = @decltypeobject | @declconstobject | @declvarobject | @declfunctionobject; + +@builtinobject = @builtintypeobject | @builtinconstobject | @builtinfunctionobject; + +@typeobject = @decltypeobject | @builtintypeobject; + +@valueobject = @constobject | @varobject | @functionobject; + +@constobject = @declconstobject | @builtinconstobject; + +@varobject = @declvarobject; + +@functionobject = @declfunctionobject | @builtinfunctionobject; + +case @scope.kind of + 0 = @universescope +| 1 = @packagescope +| 2 = @localscope; + +case @type.kind of + 0 = @invalidtype +| 1 = @boolexprtype +| 2 = @inttype +| 3 = @int8type +| 4 = @int16type +| 5 = @int32type +| 6 = @int64type +| 7 = @uinttype +| 8 = @uint8type +| 9 = @uint16type +| 10 = @uint32type +| 11 = @uint64type +| 12 = @uintptrtype +| 13 = @float32type +| 14 = @float64type +| 15 = @complex64type +| 16 = @complex128type +| 17 = @stringexprtype +| 18 = @unsafepointertype +| 19 = @boolliteraltype +| 20 = @intliteraltype +| 21 = @runeliteraltype +| 22 = @floatliteraltype +| 23 = @complexliteraltype +| 24 = @stringliteraltype +| 25 = @nilliteraltype +| 26 = @typeparamtype +| 27 = @arraytype +| 28 = @slicetype +| 29 = @structtype +| 30 = @pointertype +| 31 = @interfacetype +| 32 = @tupletype +| 33 = @signaturetype +| 34 = @maptype +| 35 = @sendchantype +| 36 = @recvchantype +| 37 = @sendrcvchantype +| 38 = @definedtype +| 39 = @typesetliteraltype; + +@basictype = @booltype | @numerictype | @stringtype | @literaltype | @invalidtype | @unsafepointertype; + +@booltype = @boolexprtype | @boolliteraltype; + +@numerictype = @integertype | @floattype | @complextype; + +@integertype = @signedintegertype | @unsignedintegertype; + +@signedintegertype = @inttype | @int8type | @int16type | @int32type | @int64type | @intliteraltype | @runeliteraltype; + +@unsignedintegertype = @uinttype | @uint8type | @uint16type | @uint32type | @uint64type | @uintptrtype; + +@floattype = @float32type | @float64type | @floatliteraltype; + +@complextype = @complex64type | @complex128type | @complexliteraltype; + +@stringtype = @stringexprtype | @stringliteraltype; + +@literaltype = @boolliteraltype | @intliteraltype | @runeliteraltype | @floatliteraltype | @complexliteraltype + | @stringliteraltype | @nilliteraltype; + +@compositetype = @typeparamtype | @containertype | @structtype | @pointertype | @interfacetype | @tupletype + | @signaturetype | @definedtype | @typesetliteraltype; + +@containertype = @arraytype | @slicetype | @maptype | @chantype; + +@chantype = @sendchantype | @recvchantype | @sendrcvchantype; + +case @modexpr.kind of + 0 = @modcommentblock +| 1 = @modline +| 2 = @modlineblock +| 3 = @modlparen +| 4 = @modrparen; + +case @error.kind of + 0 = @unknownerror +| 1 = @listerror +| 2 = @parseerror +| 3 = @typeerror; + diff --git a/go/ql/lib/upgrades/b1341734d6870b105e5c9d168ce7dec25d7f72d0/old.dbscheme b/go/ql/lib/upgrades/b1341734d6870b105e5c9d168ce7dec25d7f72d0/old.dbscheme new file mode 100644 index 00000000000..b1341734d68 --- /dev/null +++ b/go/ql/lib/upgrades/b1341734d6870b105e5c9d168ce7dec25d7f72d0/old.dbscheme @@ -0,0 +1,563 @@ +/** Auto-generated dbscheme; do not edit. Run `make gen` in directory `go/` to regenerate. */ + + +/** Duplicate code **/ + +duplicateCode( + unique int id : @duplication, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +similarCode( + unique int id : @similarity, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +@duplication_or_similarity = @duplication | @similarity; + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref); + +/** External data **/ + +externalData( + int id : @externalDataElement, + varchar(900) path : string ref, + int column: int ref, + varchar(900) value : string ref +); + +snapshotDate(unique date snapshotDate : date ref); + +sourceLocationPrefix(varchar(900) prefix : string ref); + +/** Overlay support **/ + +databaseMetadata( + string metadataKey: string ref, + string value: string ref +); + +overlayChangedFiles( + string path: string ref +); + + +/* + * XML Files + */ + +xmlEncoding( + unique int id: @file ref, + string encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +compilations(unique int id: @compilation, string cwd: string ref); + +#keyset[id, num] +compilation_args(int id: @compilation ref, int num: int ref, string arg: string ref); + +#keyset[id, num, kind] +compilation_time(int id: @compilation ref, int num: int ref, int kind: int ref, float secs: float ref); + +diagnostic_for(unique int diagnostic: @diagnostic ref, int compilation: @compilation ref, int file_number: int ref, int file_number_diagnostic_number: int ref); + +compilation_finished(unique int id: @compilation ref, float cpu_seconds: float ref, float elapsed_seconds: float ref); + +#keyset[id, num] +compilation_compiling_files(int id: @compilation ref, int num: int ref, int file: @file ref); + +diagnostics(unique int id: @diagnostic, int severity: int ref, string error_tag: string ref, string error_message: string ref, + string full_error_message: string ref, int location: @location ref); + +locations_default(unique int id: @location_default, int file: @file ref, int beginLine: int ref, int beginColumn: int ref, + int endLine: int ref, int endColumn: int ref); + +numlines(int element_id: @sourceline ref, int num_lines: int ref, int num_code: int ref, int num_comment: int ref); + +files(unique int id: @file, string name: string ref); + +folders(unique int id: @folder, string name: string ref); + +containerparent(int parent: @container ref, unique int child: @container ref); + +has_location(unique int locatable: @locatable ref, int location: @location ref); + +#keyset[parent, idx] +comment_groups(unique int id: @comment_group, int parent: @file ref, int idx: int ref); + +comments(unique int id: @comment, int kind: int ref, int parent: @comment_group ref, int idx: int ref, string text: string ref); + +doc_comments(unique int node: @documentable ref, int comment: @comment_group ref); + +#keyset[parent, idx] +exprs(unique int id: @expr, int kind: int ref, int parent: @exprparent ref, int idx: int ref); + +literals(unique int expr: @expr ref, string value: string ref, string raw: string ref); + +constvalues(unique int expr: @expr ref, string value: string ref, string exact: string ref); + +fields(unique int id: @field, int parent: @fieldparent ref, int idx: int ref); + +typeparamdecls(unique int id: @typeparamdecl, int parent: @typeparamdeclparent ref, int idx: int ref); + +#keyset[parent, idx] +stmts(unique int id: @stmt, int kind: int ref, int parent: @stmtparent ref, int idx: int ref); + +#keyset[parent, idx] +decls(unique int id: @decl, int kind: int ref, int parent: @declparent ref, int idx: int ref); + +#keyset[parent, idx] +specs(unique int id: @spec, int kind: int ref, int parent: @gendecl ref, int idx: int ref); + +scopes(unique int id: @scope, int kind: int ref); + +scopenesting(unique int inner: @scope ref, int outer: @scope ref); + +scopenodes(unique int node: @scopenode ref, int scope: @localscope ref); + +objects(unique int id: @object, int kind: int ref, string name: string ref); + +objectscopes(unique int object: @object ref, int scope: @scope ref); + +objecttypes(unique int object: @object ref, int tp: @type ref); + +methodreceivers(unique int method: @object ref, int receiver: @object ref); + +fieldstructs(unique int field: @object ref, int struct: @structtype ref); + +methodhosts(int method: @object ref, int host: @definedtype ref); + +defs(int ident: @ident ref, int object: @object ref); + +uses(int ident: @ident ref, int object: @object ref); + +types(unique int id: @type, int kind: int ref); + +type_of(unique int expr: @expr ref, int tp: @type ref); + +typename(unique int tp: @type ref, string name: string ref); + +key_type(unique int map: @maptype ref, int tp: @type ref); + +element_type(unique int container: @containertype ref, int tp: @type ref); + +base_type(unique int ptr: @pointertype ref, int tp: @type ref); + +underlying_type(unique int defined: @definedtype ref, int tp: @type ref); + +#keyset[parent, index] +component_types(int parent: @compositetype ref, int index: int ref, string name: string ref, int tp: @type ref); + +#keyset[parent, index] +struct_tags(int parent: @structtype ref, int index: int ref, string tag: string ref); + +#keyset[interface, index] +interface_private_method_ids(int interface: @interfacetype ref, int index: int ref, string id: string ref); + +array_length(unique int tp: @arraytype ref, string len: string ref); + +type_objects(unique int tp: @type ref, int object: @object ref); + +packages(unique int id: @package, string name: string ref, string path: string ref, int scope: @packagescope ref); + +#keyset[parent, idx] +modexprs(unique int id: @modexpr, int kind: int ref, int parent: @modexprparent ref, int idx: int ref); + +#keyset[parent, idx] +modtokens(string token: string ref, int parent: @modexpr ref, int idx: int ref); + +#keyset[package, idx] +errors(unique int id: @error, int kind: int ref, string msg: string ref, string rawpos: string ref, + string file: string ref, int line: int ref, int col: int ref, int package: @package ref, int idx: int ref); + +has_ellipsis(int id: @callorconversionexpr ref); + +variadic(int id: @signaturetype ref); + +#keyset[parent, idx] +typeparam(unique int tp: @typeparamtype ref, string name: string ref, int bound: @compositetype ref, + int parent: @typeparamparentobject ref, int idx: int ref); + +@container = @file | @folder; + +@locatable = @xmllocatable | @node | @localscope; + +@node = @documentable | @exprparent | @modexprparent | @fieldparent | @stmtparent | @declparent | @typeparamdeclparent + | @scopenode | @comment_group | @comment; + +@documentable = @file | @field | @typeparamdecl | @spec | @gendecl | @funcdecl | @modexpr; + +@exprparent = @funcdef | @file | @expr | @field | @stmt | @decl | @typeparamdecl | @spec; + +@modexprparent = @file | @modexpr; + +@fieldparent = @decl | @structtypeexpr | @functypeexpr | @interfacetypeexpr; + +@stmtparent = @funcdef | @stmt | @decl; + +@declparent = @file | @declstmt; + +@typeparamdeclparent = @funcdecl | @typespec; + +@funcdef = @funclit | @funcdecl; + +@scopenode = @file | @functypeexpr | @blockstmt | @ifstmt | @caseclause | @switchstmt | @commclause | @loopstmt; + +@location = @location_default; + +@sourceline = @locatable; + +case @comment.kind of + 0 = @slashslashcomment +| 1 = @slashstarcomment; + +case @expr.kind of + 0 = @badexpr +| 1 = @ident +| 2 = @ellipsis +| 3 = @intlit +| 4 = @floatlit +| 5 = @imaglit +| 6 = @charlit +| 7 = @stringlit +| 8 = @funclit +| 9 = @compositelit +| 10 = @parenexpr +| 11 = @selectorexpr +| 12 = @indexexpr +| 13 = @genericfunctioninstantiationexpr +| 14 = @generictypeinstantiationexpr +| 15 = @sliceexpr +| 16 = @typeassertexpr +| 17 = @callorconversionexpr +| 18 = @starexpr +| 19 = @keyvalueexpr +| 20 = @arraytypeexpr +| 21 = @structtypeexpr +| 22 = @functypeexpr +| 23 = @interfacetypeexpr +| 24 = @maptypeexpr +| 25 = @typesetliteralexpr +| 26 = @plusexpr +| 27 = @minusexpr +| 28 = @notexpr +| 29 = @complementexpr +| 30 = @derefexpr +| 31 = @addressexpr +| 32 = @arrowexpr +| 33 = @lorexpr +| 34 = @landexpr +| 35 = @eqlexpr +| 36 = @neqexpr +| 37 = @lssexpr +| 38 = @leqexpr +| 39 = @gtrexpr +| 40 = @geqexpr +| 41 = @addexpr +| 42 = @subexpr +| 43 = @orexpr +| 44 = @xorexpr +| 45 = @mulexpr +| 46 = @quoexpr +| 47 = @remexpr +| 48 = @shlexpr +| 49 = @shrexpr +| 50 = @andexpr +| 51 = @andnotexpr +| 52 = @sendchantypeexpr +| 53 = @recvchantypeexpr +| 54 = @sendrcvchantypeexpr; + +@basiclit = @intlit | @floatlit | @imaglit | @charlit | @stringlit; + +@operatorexpr = @logicalexpr | @arithmeticexpr | @bitwiseexpr | @unaryexpr | @binaryexpr; + +@logicalexpr = @logicalunaryexpr | @logicalbinaryexpr; + +@arithmeticexpr = @arithmeticunaryexpr | @arithmeticbinaryexpr; + +@bitwiseexpr = @bitwiseunaryexpr | @bitwisebinaryexpr; + +@unaryexpr = @logicalunaryexpr | @bitwiseunaryexpr | @arithmeticunaryexpr | @derefexpr | @addressexpr | @arrowexpr; + +@logicalunaryexpr = @notexpr; + +@bitwiseunaryexpr = @complementexpr; + +@arithmeticunaryexpr = @plusexpr | @minusexpr; + +@binaryexpr = @logicalbinaryexpr | @bitwisebinaryexpr | @arithmeticbinaryexpr | @comparison; + +@logicalbinaryexpr = @lorexpr | @landexpr; + +@bitwisebinaryexpr = @shiftexpr | @orexpr | @xorexpr | @andexpr | @andnotexpr; + +@arithmeticbinaryexpr = @addexpr | @subexpr | @mulexpr | @quoexpr | @remexpr; + +@shiftexpr = @shlexpr | @shrexpr; + +@comparison = @equalitytest | @relationalcomparison; + +@equalitytest = @eqlexpr | @neqexpr; + +@relationalcomparison = @lssexpr | @leqexpr | @gtrexpr | @geqexpr; + +@chantypeexpr = @sendchantypeexpr | @recvchantypeexpr | @sendrcvchantypeexpr; + +case @stmt.kind of + 0 = @badstmt +| 1 = @declstmt +| 2 = @emptystmt +| 3 = @labeledstmt +| 4 = @exprstmt +| 5 = @sendstmt +| 6 = @incstmt +| 7 = @decstmt +| 8 = @gostmt +| 9 = @deferstmt +| 10 = @returnstmt +| 11 = @breakstmt +| 12 = @continuestmt +| 13 = @gotostmt +| 14 = @fallthroughstmt +| 15 = @blockstmt +| 16 = @ifstmt +| 17 = @caseclause +| 18 = @exprswitchstmt +| 19 = @typeswitchstmt +| 20 = @commclause +| 21 = @selectstmt +| 22 = @forstmt +| 23 = @rangestmt +| 24 = @assignstmt +| 25 = @definestmt +| 26 = @addassignstmt +| 27 = @subassignstmt +| 28 = @mulassignstmt +| 29 = @quoassignstmt +| 30 = @remassignstmt +| 31 = @andassignstmt +| 32 = @orassignstmt +| 33 = @xorassignstmt +| 34 = @shlassignstmt +| 35 = @shrassignstmt +| 36 = @andnotassignstmt; + +@incdecstmt = @incstmt | @decstmt; + +@assignment = @simpleassignstmt | @compoundassignstmt; + +@simpleassignstmt = @assignstmt | @definestmt; + +@compoundassignstmt = @addassignstmt | @subassignstmt | @mulassignstmt | @quoassignstmt | @remassignstmt + | @andassignstmt | @orassignstmt | @xorassignstmt | @shlassignstmt | @shrassignstmt | @andnotassignstmt; + +@branchstmt = @breakstmt | @continuestmt | @gotostmt | @fallthroughstmt; + +@switchstmt = @exprswitchstmt | @typeswitchstmt; + +@loopstmt = @forstmt | @rangestmt; + +case @decl.kind of + 0 = @baddecl +| 1 = @importdecl +| 2 = @constdecl +| 3 = @typedecl +| 4 = @vardecl +| 5 = @funcdecl; + +@gendecl = @importdecl | @constdecl | @typedecl | @vardecl; + +case @spec.kind of + 0 = @importspec +| 1 = @valuespec +| 2 = @typedefspec +| 3 = @aliasspec; + +@typespec = @typedefspec | @aliasspec; + +case @object.kind of + 0 = @pkgobject +| 1 = @decltypeobject +| 2 = @builtintypeobject +| 3 = @declconstobject +| 4 = @builtinconstobject +| 5 = @declvarobject +| 6 = @declfunctionobject +| 7 = @builtinfunctionobject +| 8 = @labelobject; + +@typeparamparentobject = @decltypeobject | @declfunctionobject; + +@declobject = @decltypeobject | @declconstobject | @declvarobject | @declfunctionobject; + +@builtinobject = @builtintypeobject | @builtinconstobject | @builtinfunctionobject; + +@typeobject = @decltypeobject | @builtintypeobject; + +@valueobject = @constobject | @varobject | @functionobject; + +@constobject = @declconstobject | @builtinconstobject; + +@varobject = @declvarobject; + +@functionobject = @declfunctionobject | @builtinfunctionobject; + +case @scope.kind of + 0 = @universescope +| 1 = @packagescope +| 2 = @localscope; + +case @type.kind of + 0 = @invalidtype +| 1 = @boolexprtype +| 2 = @inttype +| 3 = @int8type +| 4 = @int16type +| 5 = @int32type +| 6 = @int64type +| 7 = @uinttype +| 8 = @uint8type +| 9 = @uint16type +| 10 = @uint32type +| 11 = @uint64type +| 12 = @uintptrtype +| 13 = @float32type +| 14 = @float64type +| 15 = @complex64type +| 16 = @complex128type +| 17 = @stringexprtype +| 18 = @unsafepointertype +| 19 = @boolliteraltype +| 20 = @intliteraltype +| 21 = @runeliteraltype +| 22 = @floatliteraltype +| 23 = @complexliteraltype +| 24 = @stringliteraltype +| 25 = @nilliteraltype +| 26 = @typeparamtype +| 27 = @arraytype +| 28 = @slicetype +| 29 = @structtype +| 30 = @pointertype +| 31 = @interfacetype +| 32 = @tupletype +| 33 = @signaturetype +| 34 = @maptype +| 35 = @sendchantype +| 36 = @recvchantype +| 37 = @sendrcvchantype +| 38 = @definedtype +| 39 = @typesetliteraltype; + +@basictype = @booltype | @numerictype | @stringtype | @literaltype | @invalidtype | @unsafepointertype; + +@booltype = @boolexprtype | @boolliteraltype; + +@numerictype = @integertype | @floattype | @complextype; + +@integertype = @signedintegertype | @unsignedintegertype; + +@signedintegertype = @inttype | @int8type | @int16type | @int32type | @int64type | @intliteraltype | @runeliteraltype; + +@unsignedintegertype = @uinttype | @uint8type | @uint16type | @uint32type | @uint64type | @uintptrtype; + +@floattype = @float32type | @float64type | @floatliteraltype; + +@complextype = @complex64type | @complex128type | @complexliteraltype; + +@stringtype = @stringexprtype | @stringliteraltype; + +@literaltype = @boolliteraltype | @intliteraltype | @runeliteraltype | @floatliteraltype | @complexliteraltype + | @stringliteraltype | @nilliteraltype; + +@compositetype = @typeparamtype | @containertype | @structtype | @pointertype | @interfacetype | @tupletype + | @signaturetype | @definedtype | @typesetliteraltype; + +@containertype = @arraytype | @slicetype | @maptype | @chantype; + +@chantype = @sendchantype | @recvchantype | @sendrcvchantype; + +case @modexpr.kind of + 0 = @modcommentblock +| 1 = @modline +| 2 = @modlineblock +| 3 = @modlparen +| 4 = @modrparen; + +case @error.kind of + 0 = @unknownerror +| 1 = @listerror +| 2 = @parseerror +| 3 = @typeerror; + diff --git a/go/ql/lib/upgrades/b1341734d6870b105e5c9d168ce7dec25d7f72d0/upgrade.properties b/go/ql/lib/upgrades/b1341734d6870b105e5c9d168ce7dec25d7f72d0/upgrade.properties new file mode 100644 index 00000000000..768d62bb215 --- /dev/null +++ b/go/ql/lib/upgrades/b1341734d6870b105e5c9d168ce7dec25d7f72d0/upgrade.properties @@ -0,0 +1,2 @@ +description: Add @rangeelementexpr, grouping the loop variables of a range statement +compatibility: partial diff --git a/go/ql/test/library-tests/semmle/go/PrintAst/PrintAst.expected b/go/ql/test/library-tests/semmle/go/PrintAst/PrintAst.expected index 66aa2643063..ddd01261135 100644 --- a/go/ql/test/library-tests/semmle/go/PrintAst/PrintAst.expected +++ b/go/ql/test/library-tests/semmle/go/PrintAst/PrintAst.expected @@ -547,8 +547,9 @@ input.go: # 133| Type = []int # 133| 2: [BlockStmt] block statement # 134| 0: [RangeStmt] range statement -# 134| 0: [Ident, VariableName] x -# 134| Type = int +# 134| 0: [RangeElementExpr] range element +# 134| 0: [Ident, VariableName] x +# 134| Type = int # 134| 1: [Ident, VariableName] xs # 134| Type = []int # 134| 2: [BlockStmt] block statement @@ -573,13 +574,14 @@ input.go: # 138| 1: [Ident, VariableName] x # 138| Type = int # 141| 1: [RangeStmt] range statement -# 141| 0: [Ident, VariableName] i -# 141| Type = int -# 141| 1: [Ident, VariableName] v -# 141| Type = int -# 141| 2: [Ident, VariableName] xs +# 141| 0: [RangeElementExpr] range element +# 141| 0: [Ident, VariableName] i +# 141| Type = int +# 141| 1: [Ident, VariableName] v +# 141| Type = int +# 141| 1: [Ident, VariableName] xs # 141| Type = []int -# 141| 3: [BlockStmt] block statement +# 141| 2: [BlockStmt] block statement # 142| 0: [ExprStmt] expression statement # 142| 0: [CallExpr] call to Print # 142| Type = (int, error) @@ -593,9 +595,10 @@ input.go: # 142| 2: [Ident, VariableName] v # 142| Type = int # 145| 2: [RangeStmt] range statement -# 145| 0: [Ident, VariableName] xs +# 145| 0: [RangeElementExpr] range element +# 145| 1: [Ident, VariableName] xs # 145| Type = []int -# 145| 1: [BlockStmt] block statement +# 145| 2: [BlockStmt] block statement other.go: # 0| [GoFile] other.go # 1| package: [Ident] main diff --git a/go/ql/test/library-tests/semmle/go/PrintAst/PrintAstExcludeComments.expected b/go/ql/test/library-tests/semmle/go/PrintAst/PrintAstExcludeComments.expected index 099aa4e6144..c25ff250f78 100644 --- a/go/ql/test/library-tests/semmle/go/PrintAst/PrintAstExcludeComments.expected +++ b/go/ql/test/library-tests/semmle/go/PrintAst/PrintAstExcludeComments.expected @@ -527,8 +527,9 @@ input.go: # 133| Type = []int # 133| 2: [BlockStmt] block statement # 134| 0: [RangeStmt] range statement -# 134| 0: [Ident, VariableName] x -# 134| Type = int +# 134| 0: [RangeElementExpr] range element +# 134| 0: [Ident, VariableName] x +# 134| Type = int # 134| 1: [Ident, VariableName] xs # 134| Type = []int # 134| 2: [BlockStmt] block statement @@ -553,13 +554,14 @@ input.go: # 138| 1: [Ident, VariableName] x # 138| Type = int # 141| 1: [RangeStmt] range statement -# 141| 0: [Ident, VariableName] i -# 141| Type = int -# 141| 1: [Ident, VariableName] v -# 141| Type = int -# 141| 2: [Ident, VariableName] xs +# 141| 0: [RangeElementExpr] range element +# 141| 0: [Ident, VariableName] i +# 141| Type = int +# 141| 1: [Ident, VariableName] v +# 141| Type = int +# 141| 1: [Ident, VariableName] xs # 141| Type = []int -# 141| 3: [BlockStmt] block statement +# 141| 2: [BlockStmt] block statement # 142| 0: [ExprStmt] expression statement # 142| 0: [CallExpr] call to Print # 142| Type = (int, error) @@ -573,9 +575,10 @@ input.go: # 142| 2: [Ident, VariableName] v # 142| Type = int # 145| 2: [RangeStmt] range statement -# 145| 0: [Ident, VariableName] xs +# 145| 0: [RangeElementExpr] range element +# 145| 1: [Ident, VariableName] xs # 145| Type = []int -# 145| 1: [BlockStmt] block statement +# 145| 2: [BlockStmt] block statement other.go: # 0| [GoFile] other.go # 1| package: [Ident] main diff --git a/go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph/ControlFlowNode_getASuccessor.expected b/go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph/ControlFlowNode_getASuccessor.expected index a2437d2ad28..3426a60d04e 100644 --- a/go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph/ControlFlowNode_getASuccessor.expected +++ b/go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph/ControlFlowNode_getASuccessor.expected @@ -3981,16 +3981,20 @@ | stmts.go:145:23:159:1 | arg:0 block statement | stmts.go:145:23:159:1 | param-init:0 block statement | | stmts.go:145:23:159:1 | block statement | stmts.go:145:23:159:1 | arg:0 block statement | | stmts.go:145:23:159:1 | param-init:0 block statement | stmts.go:146:2:151:2 | range statement | +| stmts.go:146:2:151:2 | After range element | stmts.go:146:20:151:2 | block statement | | stmts.go:146:2:151:2 | After range statement | stmts.go:153:2:155:2 | range statement | | stmts.go:146:2:151:2 | [LoopHeader] range statement | stmts.go:146:2:151:2 | After range statement | -| stmts.go:146:2:151:2 | [LoopHeader] range statement | stmts.go:146:2:151:2 | next range statement | -| stmts.go:146:2:151:2 | assign:0 range statement | stmts.go:146:20:151:2 | block statement | -| stmts.go:146:2:151:2 | extract:0 range statement | stmts.go:146:2:151:2 | assign:0 range statement | -| stmts.go:146:2:151:2 | next range statement | stmts.go:146:2:151:2 | extract:0 range statement | +| stmts.go:146:2:151:2 | [LoopHeader] range statement | stmts.go:146:2:151:2 | range element | +| stmts.go:146:2:151:2 | assign:0 range element | stmts.go:146:2:151:2 | After range element | +| stmts.go:146:2:151:2 | extract:0 range element | stmts.go:146:2:151:2 | assign:0 range element | +| stmts.go:146:2:151:2 | next range element | stmts.go:146:2:151:2 | extract:0 range element | +| stmts.go:146:2:151:2 | range element | stmts.go:146:2:151:2 | next range element | | stmts.go:146:2:151:2 | range statement | stmts.go:146:17:146:18 | Before xs | -| stmts.go:146:17:146:18 | After xs | stmts.go:146:2:151:2 | [LoopHeader] range statement | +| stmts.go:146:17:146:18 | After xs [empty] | stmts.go:146:2:151:2 | After range statement | +| stmts.go:146:17:146:18 | After xs [non-empty] | stmts.go:146:2:151:2 | range element | | stmts.go:146:17:146:18 | Before xs | stmts.go:146:17:146:18 | xs | -| stmts.go:146:17:146:18 | xs | stmts.go:146:17:146:18 | After xs | +| stmts.go:146:17:146:18 | xs | stmts.go:146:17:146:18 | After xs [empty] | +| stmts.go:146:17:146:18 | xs | stmts.go:146:17:146:18 | After xs [non-empty] | | stmts.go:146:20:151:2 | After block statement | stmts.go:146:2:151:2 | [LoopHeader] range statement | | stmts.go:146:20:151:2 | block statement | stmts.go:147:3:149:3 | if statement | | stmts.go:147:3:149:3 | After if statement | stmts.go:150:3:150:14 | expression statement | @@ -4021,18 +4025,22 @@ | stmts.go:150:13:150:13 | After x | stmts.go:150:3:150:14 | call to Print | | stmts.go:150:13:150:13 | Before x | stmts.go:150:13:150:13 | x | | stmts.go:150:13:150:13 | x | stmts.go:150:13:150:13 | After x | +| stmts.go:153:2:155:2 | After range element | stmts.go:153:23:155:2 | block statement | | stmts.go:153:2:155:2 | After range statement | stmts.go:157:2:158:2 | range statement | | stmts.go:153:2:155:2 | [LoopHeader] range statement | stmts.go:153:2:155:2 | After range statement | -| stmts.go:153:2:155:2 | [LoopHeader] range statement | stmts.go:153:2:155:2 | next range statement | -| stmts.go:153:2:155:2 | assign:0 range statement | stmts.go:153:2:155:2 | extract:1 range statement | -| stmts.go:153:2:155:2 | assign:1 range statement | stmts.go:153:23:155:2 | block statement | -| stmts.go:153:2:155:2 | extract:0 range statement | stmts.go:153:2:155:2 | assign:0 range statement | -| stmts.go:153:2:155:2 | extract:1 range statement | stmts.go:153:2:155:2 | assign:1 range statement | -| stmts.go:153:2:155:2 | next range statement | stmts.go:153:2:155:2 | extract:0 range statement | +| stmts.go:153:2:155:2 | [LoopHeader] range statement | stmts.go:153:2:155:2 | range element | +| stmts.go:153:2:155:2 | assign:0 range element | stmts.go:153:2:155:2 | extract:1 range element | +| stmts.go:153:2:155:2 | assign:1 range element | stmts.go:153:2:155:2 | After range element | +| stmts.go:153:2:155:2 | extract:0 range element | stmts.go:153:2:155:2 | assign:0 range element | +| stmts.go:153:2:155:2 | extract:1 range element | stmts.go:153:2:155:2 | assign:1 range element | +| stmts.go:153:2:155:2 | next range element | stmts.go:153:2:155:2 | extract:0 range element | +| stmts.go:153:2:155:2 | range element | stmts.go:153:2:155:2 | next range element | | stmts.go:153:2:155:2 | range statement | stmts.go:153:20:153:21 | Before xs | -| stmts.go:153:20:153:21 | After xs | stmts.go:153:2:155:2 | [LoopHeader] range statement | +| stmts.go:153:20:153:21 | After xs [empty] | stmts.go:153:2:155:2 | After range statement | +| stmts.go:153:20:153:21 | After xs [non-empty] | stmts.go:153:2:155:2 | range element | | stmts.go:153:20:153:21 | Before xs | stmts.go:153:20:153:21 | xs | -| stmts.go:153:20:153:21 | xs | stmts.go:153:20:153:21 | After xs | +| stmts.go:153:20:153:21 | xs | stmts.go:153:20:153:21 | After xs [empty] | +| stmts.go:153:20:153:21 | xs | stmts.go:153:20:153:21 | After xs [non-empty] | | stmts.go:153:23:155:2 | After block statement | stmts.go:153:2:155:2 | [LoopHeader] range statement | | stmts.go:153:23:155:2 | block statement | stmts.go:154:3:154:17 | expression statement | | stmts.go:154:3:154:11 | After selection of Print | stmts.go:154:13:154:13 | Before i | @@ -4050,14 +4058,18 @@ | stmts.go:154:16:154:16 | After v | stmts.go:154:3:154:17 | call to Print | | stmts.go:154:16:154:16 | Before v | stmts.go:154:16:154:16 | v | | stmts.go:154:16:154:16 | v | stmts.go:154:16:154:16 | After v | +| stmts.go:157:2:158:2 | After range element | stmts.go:157:15:158:2 | block statement | | stmts.go:157:2:158:2 | After range statement | stmts.go:145:23:159:1 | After block statement | | stmts.go:157:2:158:2 | [LoopHeader] range statement | stmts.go:157:2:158:2 | After range statement | -| stmts.go:157:2:158:2 | [LoopHeader] range statement | stmts.go:157:2:158:2 | next range statement | -| stmts.go:157:2:158:2 | next range statement | stmts.go:157:15:158:2 | block statement | +| stmts.go:157:2:158:2 | [LoopHeader] range statement | stmts.go:157:2:158:2 | range element | +| stmts.go:157:2:158:2 | next range element | stmts.go:157:2:158:2 | After range element | +| stmts.go:157:2:158:2 | range element | stmts.go:157:2:158:2 | next range element | | stmts.go:157:2:158:2 | range statement | stmts.go:157:12:157:13 | Before xs | -| stmts.go:157:12:157:13 | After xs | stmts.go:157:2:158:2 | [LoopHeader] range statement | +| stmts.go:157:12:157:13 | After xs [empty] | stmts.go:157:2:158:2 | After range statement | +| stmts.go:157:12:157:13 | After xs [non-empty] | stmts.go:157:2:158:2 | range element | | stmts.go:157:12:157:13 | Before xs | stmts.go:157:12:157:13 | xs | -| stmts.go:157:12:157:13 | xs | stmts.go:157:12:157:13 | After xs | +| stmts.go:157:12:157:13 | xs | stmts.go:157:12:157:13 | After xs [empty] | +| stmts.go:157:12:157:13 | xs | stmts.go:157:12:157:13 | After xs [non-empty] | | stmts.go:157:15:158:2 | block statement | stmts.go:157:2:158:2 | [LoopHeader] range statement | | tst.go:0:0:0:0 | After tst.go | tst.go:0:0:0:0 | Normal Exit | | tst.go:0:0:0:0 | Entry | tst.go:0:0:0:0 | tst.go | diff --git a/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalFlowStep.expected b/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalFlowStep.expected index 0f34d658917..b6501541cc5 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalFlowStep.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalFlowStep.expected @@ -1,169 +1,169 @@ -| main.go:3:12:3:12 | SSA def(x) | main.go:5:5:5:5 | x | -| main.go:3:12:3:12 | argument corresponding to x | main.go:3:12:3:12 | SSA def(x) | -| main.go:3:19:3:20 | SSA def(fn) | main.go:10:24:10:25 | fn | -| main.go:3:19:3:20 | argument corresponding to fn | main.go:3:19:3:20 | SSA def(fn) | +| main.go:3:39:12:1 | SSA def(fn) | main.go:10:24:10:25 | fn | +| main.go:3:39:12:1 | SSA def(x) | main.go:5:5:5:5 | x | +| main.go:3:39:12:1 | arg:0 block statement | main.go:3:39:12:1 | SSA def(x) | +| main.go:3:39:12:1 | arg:1 block statement | main.go:3:39:12:1 | SSA def(fn) | | main.go:5:5:5:5 | x | main.go:6:7:6:7 | x | | main.go:5:5:5:5 | x | main.go:8:8:8:8 | x | -| main.go:6:3:6:3 | SSA def(y) | main.go:10:12:10:12 | y | -| main.go:6:7:6:7 | x | main.go:6:3:6:3 | SSA def(y) | +| main.go:6:3:6:7 | SSA def(y) | main.go:10:12:10:12 | y | +| main.go:6:7:6:7 | x | main.go:6:3:6:7 | SSA def(y) | | main.go:6:7:6:7 | x | main.go:10:7:10:7 | x | -| main.go:8:3:8:3 | SSA def(y) | main.go:10:12:10:12 | y | -| main.go:8:7:8:8 | -... | main.go:8:3:8:3 | SSA def(y) | +| main.go:8:3:8:8 | SSA def(y) | main.go:10:12:10:12 | y | +| main.go:8:7:8:8 | -... | main.go:8:3:8:8 | SSA def(y) | | main.go:8:8:8:8 | x | main.go:10:7:10:7 | x | -| main.go:10:2:10:2 | SSA def(z) | main.go:11:14:11:14 | z | +| main.go:10:2:10:27 | SSA def(z) | main.go:11:14:11:14 | z | | main.go:10:7:10:7 | x | main.go:10:22:10:22 | x | -| main.go:10:7:10:12 | ...<=... | main.go:10:7:10:27 | ...&&... | -| main.go:10:7:10:27 | ...&&... | main.go:10:2:10:2 | SSA def(z) | +| main.go:10:7:10:12 | ...<=... | main.go:10:7:10:27 | After ...&&... | +| main.go:10:7:10:27 | After ...&&... | main.go:10:2:10:27 | SSA def(z) | | main.go:10:12:10:12 | y | main.go:10:17:10:17 | y | -| main.go:10:17:10:27 | ...>=... | main.go:10:7:10:27 | ...&&... | +| main.go:10:17:10:27 | ...>=... | main.go:10:7:10:27 | After ...&&... | | main.go:11:14:11:14 | z | main.go:11:9:11:15 | type conversion | -| main.go:15:9:15:9 | 0 | main.go:15:2:15:4 | SSA def(acc) | +| main.go:15:9:15:9 | 0 | main.go:15:2:15:9 | SSA def(acc) | | main.go:16:9:19:2 | SSA def(acc) | main.go:17:3:17:5 | acc | | main.go:17:3:17:7 | SSA def(acc) | main.go:18:10:18:12 | acc | -| main.go:17:3:17:7 | rhs of increment statement | main.go:17:3:17:7 | SSA def(acc) | -| main.go:22:12:22:12 | SSA def(b) | main.go:23:5:23:5 | b | -| main.go:22:12:22:12 | argument corresponding to b | main.go:22:12:22:12 | SSA def(b) | -| main.go:22:20:22:20 | SSA def(x) | main.go:24:10:24:10 | x | -| main.go:22:20:22:20 | SSA def(x) | main.go:26:11:26:11 | x | -| main.go:22:20:22:20 | argument corresponding to x | main.go:22:20:22:20 | SSA def(x) | +| main.go:17:3:17:7 | incdec-rhs increment statement | main.go:17:3:17:7 | SSA def(acc) | +| main.go:22:42:31:1 | SSA def(b) | main.go:23:5:23:5 | b | +| main.go:22:42:31:1 | SSA def(x) | main.go:24:10:24:10 | x | +| main.go:22:42:31:1 | SSA def(x) | main.go:26:11:26:11 | x | +| main.go:22:42:31:1 | arg:0 block statement | main.go:22:42:31:1 | SSA def(b) | +| main.go:22:42:31:1 | arg:1 block statement | main.go:22:42:31:1 | SSA def(x) | | main.go:24:10:24:10 | x | main.go:24:10:24:19 | type assertion | -| main.go:26:2:26:2 | SSA def(n) | main.go:27:11:27:11 | n | -| main.go:26:2:26:17 | ... := ...[0] | main.go:26:2:26:2 | SSA def(n) | -| main.go:26:2:26:17 | ... := ...[1] | main.go:26:5:26:6 | SSA def(ok) | -| main.go:26:5:26:6 | SSA def(ok) | main.go:27:5:27:6 | ok | -| main.go:26:11:26:11 | x | main.go:26:2:26:17 | ... := ...[0] | -| main.go:38:2:38:2 | SSA def(s) | main.go:39:15:39:15 | s | -| main.go:38:7:38:20 | slice literal | main.go:38:2:38:2 | SSA def(s) | -| main.go:38:7:38:20 | slice literal [postupdate] | main.go:38:2:38:2 | SSA def(s) | -| main.go:39:2:39:3 | SSA def(s1) | main.go:40:18:40:19 | s1 | -| main.go:39:8:39:25 | call to append | main.go:39:2:39:3 | SSA def(s1) | +| main.go:26:2:26:17 | SSA def(n) | main.go:27:11:27:11 | n | +| main.go:26:2:26:17 | SSA def(ok) | main.go:27:5:27:6 | ok | +| main.go:26:2:26:17 | extract:0 ... := ... | main.go:26:2:26:17 | SSA def(n) | +| main.go:26:2:26:17 | extract:1 ... := ... | main.go:26:2:26:17 | SSA def(ok) | +| main.go:26:11:26:11 | x | main.go:26:2:26:17 | extract:0 ... := ... | +| main.go:38:2:38:20 | SSA def(s) | main.go:39:15:39:15 | s | +| main.go:38:7:38:20 | slice literal | main.go:38:2:38:20 | SSA def(s) | +| main.go:38:7:38:20 | slice literal [postupdate] | main.go:38:2:38:20 | SSA def(s) | +| main.go:39:2:39:25 | SSA def(s1) | main.go:40:18:40:19 | s1 | +| main.go:39:8:39:25 | call to append | main.go:39:2:39:25 | SSA def(s1) | | main.go:39:15:39:15 | s | main.go:40:15:40:15 | s | | main.go:39:15:39:15 | s [postupdate] | main.go:40:15:40:15 | s | -| main.go:40:2:40:3 | SSA def(s2) | main.go:43:9:43:10 | s2 | -| main.go:40:8:40:23 | call to append | main.go:40:2:40:3 | SSA def(s2) | +| main.go:40:2:40:23 | SSA def(s2) | main.go:43:9:43:10 | s2 | +| main.go:40:8:40:23 | call to append | main.go:40:2:40:23 | SSA def(s2) | | main.go:40:15:40:15 | s | main.go:42:7:42:7 | s | | main.go:40:15:40:15 | s [postupdate] | main.go:42:7:42:7 | s | -| main.go:41:2:41:3 | SSA def(s4) | main.go:42:10:42:11 | s4 | -| main.go:41:8:41:21 | call to make | main.go:41:2:41:3 | SSA def(s4) | -| main.go:46:13:46:14 | SSA def(xs) | main.go:47:20:47:21 | xs | -| main.go:46:13:46:14 | argument corresponding to xs | main.go:46:13:46:14 | SSA def(xs) | -| main.go:46:24:46:27 | SSA def(keys) | main.go:46:24:46:27 | implicit read of keys | -| main.go:46:24:46:27 | SSA def(keys) | main.go:49:3:49:6 | keys | -| main.go:46:24:46:27 | zero value for keys | main.go:46:24:46:27 | SSA def(keys) | -| main.go:46:34:46:37 | SSA def(vals) | main.go:46:34:46:37 | implicit read of vals | -| main.go:46:34:46:37 | SSA def(vals) | main.go:48:3:48:6 | vals | -| main.go:46:34:46:37 | zero value for vals | main.go:46:34:46:37 | SSA def(vals) | -| main.go:47:2:50:2 | range statement[0] | main.go:47:6:47:6 | SSA def(k) | -| main.go:47:2:50:2 | range statement[1] | main.go:47:9:47:9 | SSA def(v) | -| main.go:47:6:47:6 | SSA def(k) | main.go:49:11:49:11 | k | -| main.go:47:9:47:9 | SSA def(v) | main.go:48:11:48:11 | v | -| main.go:48:3:48:6 | SSA def(vals) | main.go:46:34:46:37 | implicit read of vals | -| main.go:48:3:48:6 | SSA def(vals) | main.go:48:3:48:6 | vals | -| main.go:48:3:48:11 | ... += ... | main.go:48:3:48:6 | SSA def(vals) | -| main.go:49:3:49:6 | SSA def(keys) | main.go:46:24:46:27 | implicit read of keys | -| main.go:49:3:49:6 | SSA def(keys) | main.go:49:3:49:6 | keys | -| main.go:49:3:49:11 | ... += ... | main.go:49:3:49:6 | SSA def(keys) | -| main.go:55:6:55:7 | SSA def(ch) | main.go:56:2:56:3 | ch | -| main.go:55:6:55:7 | zero value for ch | main.go:55:6:55:7 | SSA def(ch) | +| main.go:41:2:41:21 | SSA def(s4) | main.go:42:10:42:11 | s4 | +| main.go:41:8:41:21 | call to make | main.go:41:2:41:21 | SSA def(s4) | +| main.go:46:44:52:1 | SSA def(keys) | main.go:46:44:52:1 | result-read:0 block statement | +| main.go:46:44:52:1 | SSA def(keys) | main.go:49:3:49:6 | keys | +| main.go:46:44:52:1 | SSA def(vals) | main.go:46:44:52:1 | result-read:1 block statement | +| main.go:46:44:52:1 | SSA def(vals) | main.go:48:3:48:6 | vals | +| main.go:46:44:52:1 | SSA def(xs) | main.go:47:20:47:21 | xs | +| main.go:46:44:52:1 | arg:0 block statement | main.go:46:44:52:1 | SSA def(xs) | +| main.go:46:44:52:1 | result-zero-init:0 block statement | main.go:46:44:52:1 | SSA def(keys) | +| main.go:46:44:52:1 | result-zero-init:1 block statement | main.go:46:44:52:1 | SSA def(vals) | +| main.go:47:2:50:2 | SSA def(k) | main.go:49:11:49:11 | k | +| main.go:47:2:50:2 | SSA def(v) | main.go:48:11:48:11 | v | +| main.go:47:2:50:2 | extract:0 range element | main.go:47:2:50:2 | SSA def(k) | +| main.go:47:2:50:2 | extract:1 range element | main.go:47:2:50:2 | SSA def(v) | +| main.go:48:3:48:11 | SSA def(vals) | main.go:46:44:52:1 | result-read:1 block statement | +| main.go:48:3:48:11 | SSA def(vals) | main.go:48:3:48:6 | vals | +| main.go:48:3:48:11 | compound-rhs ... += ... | main.go:48:3:48:11 | SSA def(vals) | +| main.go:49:3:49:11 | SSA def(keys) | main.go:46:44:52:1 | result-read:0 block statement | +| main.go:49:3:49:11 | SSA def(keys) | main.go:49:3:49:6 | keys | +| main.go:49:3:49:11 | compound-rhs ... += ... | main.go:49:3:49:11 | SSA def(keys) | +| main.go:55:6:55:17 | SSA def(ch) | main.go:56:2:56:3 | ch | +| main.go:55:6:55:17 | zero-init:0 value declaration specifier | main.go:55:6:55:17 | SSA def(ch) | | main.go:56:2:56:3 | ch | main.go:57:4:57:5 | ch | | main.go:56:2:56:3 | ch [postupdate] | main.go:57:4:57:5 | ch | -| main.go:61:2:61:2 | SSA def(x) | main.go:64:11:64:11 | x | -| main.go:61:7:61:7 | 1 | main.go:61:2:61:2 | SSA def(x) | -| main.go:62:2:62:2 | SSA def(y) | main.go:64:14:64:14 | y | -| main.go:62:7:62:7 | 2 | main.go:62:2:62:2 | SSA def(y) | -| main.go:63:2:63:2 | SSA def(z) | main.go:64:17:64:17 | z | -| main.go:63:7:63:7 | 3 | main.go:63:2:63:2 | SSA def(z) | -| main.go:64:2:64:2 | SSA def(a) | main.go:66:9:66:9 | a | -| main.go:64:7:64:18 | call to min | main.go:64:2:64:2 | SSA def(a) | +| main.go:61:2:61:7 | SSA def(x) | main.go:64:11:64:11 | x | +| main.go:61:7:61:7 | 1 | main.go:61:2:61:7 | SSA def(x) | +| main.go:62:2:62:7 | SSA def(y) | main.go:64:14:64:14 | y | +| main.go:62:7:62:7 | 2 | main.go:62:2:62:7 | SSA def(y) | +| main.go:63:2:63:7 | SSA def(z) | main.go:64:17:64:17 | z | +| main.go:63:7:63:7 | 3 | main.go:63:2:63:7 | SSA def(z) | +| main.go:64:2:64:18 | SSA def(a) | main.go:66:9:66:9 | a | +| main.go:64:7:64:18 | call to min | main.go:64:2:64:18 | SSA def(a) | | main.go:64:11:64:11 | x | main.go:64:7:64:18 | call to min | | main.go:64:11:64:11 | x | main.go:65:11:65:11 | x | | main.go:64:14:64:14 | y | main.go:64:7:64:18 | call to min | | main.go:64:14:64:14 | y | main.go:65:14:65:14 | y | | main.go:64:17:64:17 | z | main.go:64:7:64:18 | call to min | | main.go:64:17:64:17 | z | main.go:65:17:65:17 | z | -| main.go:65:2:65:2 | SSA def(b) | main.go:66:12:66:12 | b | -| main.go:65:7:65:18 | call to max | main.go:65:2:65:2 | SSA def(b) | +| main.go:65:2:65:18 | SSA def(b) | main.go:66:12:66:12 | b | +| main.go:65:7:65:18 | call to max | main.go:65:2:65:18 | SSA def(b) | | main.go:65:11:65:11 | x | main.go:65:7:65:18 | call to max | | main.go:65:14:65:14 | y | main.go:65:7:65:18 | call to max | | main.go:65:17:65:17 | z | main.go:65:7:65:18 | call to max | -| strings.go:8:12:8:12 | SSA def(s) | strings.go:9:24:9:24 | s | -| strings.go:8:12:8:12 | argument corresponding to s | strings.go:8:12:8:12 | SSA def(s) | -| strings.go:9:2:9:3 | SSA def(s2) | strings.go:11:20:11:21 | s2 | -| strings.go:9:8:9:38 | call to Replace | strings.go:9:2:9:3 | SSA def(s2) | +| strings.go:8:29:12:1 | SSA def(s) | strings.go:9:24:9:24 | s | +| strings.go:8:29:12:1 | arg:0 block statement | strings.go:8:29:12:1 | SSA def(s) | +| strings.go:9:2:9:38 | SSA def(s2) | strings.go:11:20:11:21 | s2 | +| strings.go:9:8:9:38 | call to Replace | strings.go:9:2:9:38 | SSA def(s2) | | strings.go:9:24:9:24 | s | strings.go:10:27:10:27 | s | -| strings.go:10:2:10:3 | SSA def(s3) | strings.go:11:24:11:25 | s3 | -| strings.go:10:8:10:42 | call to ReplaceAll | strings.go:10:2:10:3 | SSA def(s3) | +| strings.go:10:2:10:42 | SSA def(s3) | strings.go:11:24:11:25 | s3 | +| strings.go:10:8:10:42 | call to ReplaceAll | strings.go:10:2:10:42 | SSA def(s3) | | strings.go:11:20:11:21 | s2 | strings.go:11:48:11:49 | s2 | | strings.go:11:24:11:25 | s3 | strings.go:11:67:11:68 | s3 | -| url.go:8:12:8:12 | SSA def(b) | url.go:11:5:11:5 | b | -| url.go:8:12:8:12 | argument corresponding to b | url.go:8:12:8:12 | SSA def(b) | -| url.go:8:20:8:20 | SSA def(s) | url.go:12:46:12:46 | s | -| url.go:8:20:8:20 | SSA def(s) | url.go:14:48:14:48 | s | -| url.go:8:20:8:20 | argument corresponding to s | url.go:8:20:8:20 | SSA def(s) | -| url.go:12:3:12:5 | SSA def(res) | url.go:19:9:19:11 | res | -| url.go:12:3:12:48 | ... = ...[0] | url.go:12:3:12:5 | SSA def(res) | -| url.go:12:3:12:48 | ... = ...[1] | url.go:12:8:12:10 | SSA def(err) | -| url.go:12:8:12:10 | SSA def(err) | url.go:16:5:16:7 | err | -| url.go:14:3:14:5 | SSA def(res) | url.go:19:9:19:11 | res | -| url.go:14:3:14:50 | ... = ...[0] | url.go:14:3:14:5 | SSA def(res) | -| url.go:14:3:14:50 | ... = ...[1] | url.go:14:8:14:10 | SSA def(err) | -| url.go:14:8:14:10 | SSA def(err) | url.go:16:5:16:7 | err | -| url.go:22:12:22:12 | SSA def(i) | url.go:24:5:24:5 | i | -| url.go:22:12:22:12 | argument corresponding to i | url.go:22:12:22:12 | SSA def(i) | -| url.go:22:19:22:19 | SSA def(s) | url.go:23:20:23:20 | s | -| url.go:22:19:22:19 | argument corresponding to s | url.go:22:19:22:19 | SSA def(s) | -| url.go:23:2:23:2 | SSA def(u) | url.go:25:10:25:10 | u | -| url.go:23:2:23:21 | ... := ...[0] | url.go:23:2:23:2 | SSA def(u) | +| url.go:8:37:20:1 | SSA def(b) | url.go:11:5:11:5 | b | +| url.go:8:37:20:1 | SSA def(s) | url.go:12:46:12:46 | s | +| url.go:8:37:20:1 | SSA def(s) | url.go:14:48:14:48 | s | +| url.go:8:37:20:1 | arg:0 block statement | url.go:8:37:20:1 | SSA def(b) | +| url.go:8:37:20:1 | arg:1 block statement | url.go:8:37:20:1 | SSA def(s) | +| url.go:12:3:12:48 | SSA def(err) | url.go:16:5:16:7 | err | +| url.go:12:3:12:48 | SSA def(res) | url.go:19:9:19:11 | res | +| url.go:12:3:12:48 | extract:0 ... = ... | url.go:12:3:12:48 | SSA def(res) | +| url.go:12:3:12:48 | extract:1 ... = ... | url.go:12:3:12:48 | SSA def(err) | +| url.go:14:3:14:50 | SSA def(err) | url.go:16:5:16:7 | err | +| url.go:14:3:14:50 | SSA def(res) | url.go:19:9:19:11 | res | +| url.go:14:3:14:50 | extract:0 ... = ... | url.go:14:3:14:50 | SSA def(res) | +| url.go:14:3:14:50 | extract:1 ... = ... | url.go:14:3:14:50 | SSA def(err) | +| url.go:22:38:38:1 | SSA def(i) | url.go:24:5:24:5 | i | +| url.go:22:38:38:1 | SSA def(s) | url.go:23:20:23:20 | s | +| url.go:22:38:38:1 | arg:0 block statement | url.go:22:38:38:1 | SSA def(i) | +| url.go:22:38:38:1 | arg:1 block statement | url.go:22:38:38:1 | SSA def(s) | +| url.go:23:2:23:21 | SSA def(u) | url.go:25:10:25:10 | u | +| url.go:23:2:23:21 | extract:0 ... := ... | url.go:23:2:23:21 | SSA def(u) | | url.go:23:20:23:20 | s | url.go:27:29:27:29 | s | -| url.go:27:2:27:2 | SSA def(u) | url.go:28:14:28:14 | u | -| url.go:27:2:27:30 | ... = ...[0] | url.go:27:2:27:2 | SSA def(u) | +| url.go:27:2:27:30 | SSA def(u) | url.go:28:14:28:14 | u | +| url.go:27:2:27:30 | extract:0 ... = ... | url.go:27:2:27:30 | SSA def(u) | | url.go:28:14:28:14 | u | url.go:29:14:29:14 | u | | url.go:28:14:28:14 | u [postupdate] | url.go:29:14:29:14 | u | | url.go:29:14:29:14 | u | url.go:30:11:30:11 | u | | url.go:29:14:29:14 | u [postupdate] | url.go:30:11:30:11 | u | -| url.go:30:2:30:3 | SSA def(bs) | url.go:31:14:31:15 | bs | -| url.go:30:2:30:27 | ... := ...[0] | url.go:30:2:30:3 | SSA def(bs) | +| url.go:30:2:30:27 | SSA def(bs) | url.go:31:14:31:15 | bs | +| url.go:30:2:30:27 | extract:0 ... := ... | url.go:30:2:30:27 | SSA def(bs) | | url.go:30:11:30:11 | u | url.go:32:9:32:9 | u | | url.go:30:11:30:11 | u [postupdate] | url.go:32:9:32:9 | u | -| url.go:32:2:32:2 | SSA def(u) | url.go:33:14:33:14 | u | -| url.go:32:2:32:23 | ... = ...[0] | url.go:32:2:32:2 | SSA def(u) | +| url.go:32:2:32:23 | SSA def(u) | url.go:33:14:33:14 | u | +| url.go:32:2:32:23 | extract:0 ... = ... | url.go:32:2:32:23 | SSA def(u) | | url.go:33:14:33:14 | u | url.go:34:14:34:14 | u | | url.go:33:14:33:14 | u [postupdate] | url.go:34:14:34:14 | u | | url.go:34:14:34:14 | u | url.go:35:14:35:14 | u | | url.go:34:14:34:14 | u [postupdate] | url.go:35:14:35:14 | u | | url.go:35:14:35:14 | u | url.go:36:6:36:6 | u | | url.go:35:14:35:14 | u [postupdate] | url.go:36:6:36:6 | u | -| url.go:36:2:36:2 | SSA def(u) | url.go:37:9:37:9 | u | +| url.go:36:2:36:26 | SSA def(u) | url.go:37:9:37:9 | u | | url.go:36:6:36:6 | u | url.go:36:25:36:25 | u | | url.go:36:6:36:6 | u [postupdate] | url.go:36:25:36:25 | u | -| url.go:36:6:36:26 | call to ResolveReference | url.go:36:2:36:2 | SSA def(u) | -| url.go:42:2:42:3 | SSA def(ui) | url.go:43:11:43:12 | ui | -| url.go:42:7:42:38 | call to UserPassword | url.go:42:2:42:3 | SSA def(ui) | -| url.go:43:2:43:3 | SSA def(pw) | url.go:44:14:44:15 | pw | -| url.go:43:2:43:23 | ... := ...[0] | url.go:43:2:43:3 | SSA def(pw) | +| url.go:36:6:36:26 | call to ResolveReference | url.go:36:2:36:26 | SSA def(u) | +| url.go:42:2:42:38 | SSA def(ui) | url.go:43:11:43:12 | ui | +| url.go:42:7:42:38 | call to UserPassword | url.go:42:2:42:38 | SSA def(ui) | +| url.go:43:2:43:23 | SSA def(pw) | url.go:44:14:44:15 | pw | +| url.go:43:2:43:23 | extract:0 ... := ... | url.go:43:2:43:23 | SSA def(pw) | | url.go:43:11:43:12 | ui | url.go:45:14:45:15 | ui | | url.go:43:11:43:12 | ui [postupdate] | url.go:45:14:45:15 | ui | | url.go:45:14:45:15 | ui | url.go:46:9:46:10 | ui | | url.go:45:14:45:15 | ui [postupdate] | url.go:46:9:46:10 | ui | -| url.go:49:12:49:12 | SSA def(q) | url.go:50:25:50:25 | q | -| url.go:49:12:49:12 | argument corresponding to q | url.go:49:12:49:12 | SSA def(q) | -| url.go:50:2:50:2 | SSA def(v) | url.go:51:14:51:14 | v | -| url.go:50:2:50:26 | ... := ...[0] | url.go:50:2:50:2 | SSA def(v) | +| url.go:49:33:54:1 | SSA def(q) | url.go:50:25:50:25 | q | +| url.go:49:33:54:1 | arg:0 block statement | url.go:49:33:54:1 | SSA def(q) | +| url.go:50:2:50:26 | SSA def(v) | url.go:51:14:51:14 | v | +| url.go:50:2:50:26 | extract:0 ... := ... | url.go:50:2:50:26 | SSA def(v) | | url.go:51:14:51:14 | v | url.go:52:14:52:14 | v | | url.go:51:14:51:14 | v [postupdate] | url.go:52:14:52:14 | v | | url.go:52:14:52:14 | v | url.go:53:9:53:9 | v | | url.go:52:14:52:14 | v [postupdate] | url.go:53:9:53:9 | v | -| url.go:56:12:56:12 | SSA def(q) | url.go:57:29:57:29 | q | -| url.go:56:12:56:12 | argument corresponding to q | url.go:56:12:56:12 | SSA def(q) | -| url.go:57:2:57:8 | SSA def(joined1) | url.go:58:38:58:44 | joined1 | -| url.go:57:2:57:39 | ... := ...[0] | url.go:57:2:57:8 | SSA def(joined1) | -| url.go:58:2:58:8 | SSA def(joined2) | url.go:59:24:59:30 | joined2 | -| url.go:58:2:58:45 | ... := ...[0] | url.go:58:2:58:8 | SSA def(joined2) | -| url.go:59:2:59:6 | SSA def(asUrl) | url.go:60:15:60:19 | asUrl | -| url.go:59:2:59:31 | ... := ...[0] | url.go:59:2:59:6 | SSA def(asUrl) | -| url.go:60:2:60:10 | SSA def(joinedUrl) | url.go:61:9:61:17 | joinedUrl | -| url.go:60:15:60:37 | call to JoinPath | url.go:60:2:60:10 | SSA def(joinedUrl) | -| url.go:64:13:64:13 | SSA def(q) | url.go:66:27:66:27 | q | -| url.go:64:13:64:13 | argument corresponding to q | url.go:64:13:64:13 | SSA def(q) | -| url.go:65:2:65:9 | SSA def(cleanUrl) | url.go:66:9:66:16 | cleanUrl | -| url.go:65:2:65:48 | ... := ...[0] | url.go:65:2:65:9 | SSA def(cleanUrl) | +| url.go:56:31:62:1 | SSA def(q) | url.go:57:29:57:29 | q | +| url.go:56:31:62:1 | arg:0 block statement | url.go:56:31:62:1 | SSA def(q) | +| url.go:57:2:57:39 | SSA def(joined1) | url.go:58:38:58:44 | joined1 | +| url.go:57:2:57:39 | extract:0 ... := ... | url.go:57:2:57:39 | SSA def(joined1) | +| url.go:58:2:58:45 | SSA def(joined2) | url.go:59:24:59:30 | joined2 | +| url.go:58:2:58:45 | extract:0 ... := ... | url.go:58:2:58:45 | SSA def(joined2) | +| url.go:59:2:59:31 | SSA def(asUrl) | url.go:60:15:60:19 | asUrl | +| url.go:59:2:59:31 | extract:0 ... := ... | url.go:59:2:59:31 | SSA def(asUrl) | +| url.go:60:2:60:37 | SSA def(joinedUrl) | url.go:61:9:61:17 | joinedUrl | +| url.go:60:15:60:37 | call to JoinPath | url.go:60:2:60:37 | SSA def(joinedUrl) | +| url.go:64:32:67:1 | SSA def(q) | url.go:66:27:66:27 | q | +| url.go:64:32:67:1 | arg:0 block statement | url.go:64:32:67:1 | SSA def(q) | +| url.go:65:2:65:48 | SSA def(cleanUrl) | url.go:66:9:66:16 | cleanUrl | +| url.go:65:2:65:48 | extract:0 ... := ... | url.go:65:2:65:48 | SSA def(cleanUrl) | diff --git a/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalTaintStep.expected b/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalTaintStep.expected index 66784562496..4ace99a0ab2 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalTaintStep.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalTaintStep.expected @@ -1,5 +1,5 @@ -| main.go:26:11:26:17 | type assertion | main.go:26:2:26:17 | ... := ...[0] | -| main.go:26:11:26:17 | type assertion | main.go:26:2:26:17 | ... := ...[1] | +| main.go:26:11:26:17 | type assertion | main.go:26:2:26:17 | extract:0 ... := ... | +| main.go:26:11:26:17 | type assertion | main.go:26:2:26:17 | extract:1 ... := ... | | main.go:38:13:38:13 | 1 | main.go:38:7:38:20 | slice literal | | main.go:38:16:38:16 | 2 | main.go:38:7:38:20 | slice literal | | main.go:38:19:38:19 | 3 | main.go:38:7:38:20 | slice literal | @@ -8,9 +8,9 @@ | main.go:40:15:40:15 | s | main.go:40:8:40:23 | call to append | | main.go:40:18:40:19 | s1 | main.go:40:8:40:23 | call to append | | main.go:42:10:42:11 | s4 | main.go:42:7:42:7 | s [postupdate] | -| main.go:47:20:47:21 | next key-value pair in range | main.go:47:2:50:2 | range statement[0] | -| main.go:47:20:47:21 | next key-value pair in range | main.go:47:2:50:2 | range statement[1] | -| main.go:47:20:47:21 | xs | main.go:47:2:50:2 | range statement[1] | +| main.go:47:2:50:2 | next range element | main.go:47:2:50:2 | extract:0 range element | +| main.go:47:2:50:2 | next range element | main.go:47:2:50:2 | extract:1 range element | +| main.go:47:20:47:21 | xs | main.go:47:2:50:2 | extract:1 range element | | strings.go:9:24:9:24 | s | strings.go:9:8:9:38 | call to Replace | | strings.go:9:32:9:34 | "_" | strings.go:9:8:9:38 | call to Replace | | strings.go:10:27:10:27 | s | strings.go:10:8:10:42 | call to ReplaceAll | @@ -24,29 +24,29 @@ | strings.go:11:48:11:49 | s2 | strings.go:11:30:11:50 | call to Sprintf | | strings.go:11:54:11:69 | call to Sprintln | strings.go:11:9:11:69 | ...+... | | strings.go:11:67:11:68 | s3 | strings.go:11:54:11:69 | call to Sprintln | -| url.go:12:14:12:48 | call to PathUnescape | url.go:12:3:12:48 | ... = ...[0] | -| url.go:12:14:12:48 | call to PathUnescape | url.go:12:3:12:48 | ... = ...[1] | -| url.go:12:31:12:47 | call to PathEscape | url.go:12:3:12:48 | ... = ...[0] | +| url.go:12:14:12:48 | call to PathUnescape | url.go:12:3:12:48 | extract:0 ... = ... | +| url.go:12:14:12:48 | call to PathUnescape | url.go:12:3:12:48 | extract:1 ... = ... | +| url.go:12:31:12:47 | call to PathEscape | url.go:12:3:12:48 | extract:0 ... = ... | | url.go:12:46:12:46 | s | url.go:12:31:12:47 | call to PathEscape | -| url.go:14:14:14:50 | call to QueryUnescape | url.go:14:3:14:50 | ... = ...[0] | -| url.go:14:14:14:50 | call to QueryUnescape | url.go:14:3:14:50 | ... = ...[1] | -| url.go:14:32:14:49 | call to QueryEscape | url.go:14:3:14:50 | ... = ...[0] | +| url.go:14:14:14:50 | call to QueryUnescape | url.go:14:3:14:50 | extract:0 ... = ... | +| url.go:14:14:14:50 | call to QueryUnescape | url.go:14:3:14:50 | extract:1 ... = ... | +| url.go:14:32:14:49 | call to QueryEscape | url.go:14:3:14:50 | extract:0 ... = ... | | url.go:14:48:14:48 | s | url.go:14:32:14:49 | call to QueryEscape | -| url.go:23:10:23:21 | call to Parse | url.go:23:2:23:21 | ... := ...[0] | -| url.go:23:10:23:21 | call to Parse | url.go:23:2:23:21 | ... := ...[1] | -| url.go:23:20:23:20 | s | url.go:23:2:23:21 | ... := ...[0] | -| url.go:27:9:27:30 | call to ParseRequestURI | url.go:27:2:27:30 | ... = ...[0] | -| url.go:27:9:27:30 | call to ParseRequestURI | url.go:27:2:27:30 | ... = ...[1] | -| url.go:27:29:27:29 | s | url.go:27:2:27:30 | ... = ...[0] | +| url.go:23:10:23:21 | call to Parse | url.go:23:2:23:21 | extract:0 ... := ... | +| url.go:23:10:23:21 | call to Parse | url.go:23:2:23:21 | extract:1 ... := ... | +| url.go:23:20:23:20 | s | url.go:23:2:23:21 | extract:0 ... := ... | +| url.go:27:9:27:30 | call to ParseRequestURI | url.go:27:2:27:30 | extract:0 ... = ... | +| url.go:27:9:27:30 | call to ParseRequestURI | url.go:27:2:27:30 | extract:1 ... = ... | +| url.go:27:29:27:29 | s | url.go:27:2:27:30 | extract:0 ... = ... | | url.go:28:14:28:14 | u | url.go:28:14:28:28 | call to EscapedPath | | url.go:29:14:29:14 | u | url.go:29:14:29:25 | call to Hostname | -| url.go:30:11:30:11 | u | url.go:30:2:30:27 | ... := ...[0] | -| url.go:30:11:30:27 | call to MarshalBinary | url.go:30:2:30:27 | ... := ...[0] | -| url.go:30:11:30:27 | call to MarshalBinary | url.go:30:2:30:27 | ... := ...[1] | -| url.go:32:9:32:9 | u | url.go:32:2:32:23 | ... = ...[0] | -| url.go:32:9:32:23 | call to Parse | url.go:32:2:32:23 | ... = ...[0] | -| url.go:32:9:32:23 | call to Parse | url.go:32:2:32:23 | ... = ...[1] | -| url.go:32:17:32:22 | "/foo" | url.go:32:2:32:23 | ... = ...[0] | +| url.go:30:11:30:11 | u | url.go:30:2:30:27 | extract:0 ... := ... | +| url.go:30:11:30:27 | call to MarshalBinary | url.go:30:2:30:27 | extract:0 ... := ... | +| url.go:30:11:30:27 | call to MarshalBinary | url.go:30:2:30:27 | extract:1 ... := ... | +| url.go:32:9:32:9 | u | url.go:32:2:32:23 | extract:0 ... = ... | +| url.go:32:9:32:23 | call to Parse | url.go:32:2:32:23 | extract:0 ... = ... | +| url.go:32:9:32:23 | call to Parse | url.go:32:2:32:23 | extract:1 ... = ... | +| url.go:32:17:32:22 | "/foo" | url.go:32:2:32:23 | extract:0 ... = ... | | url.go:33:14:33:14 | u | url.go:33:14:33:21 | call to Port | | url.go:34:14:34:14 | u | url.go:34:14:34:22 | call to Query | | url.go:35:14:35:14 | u | url.go:35:14:35:27 | call to RequestURI | @@ -55,30 +55,30 @@ | url.go:41:17:41:20 | "me" | url.go:41:8:41:21 | call to User | | url.go:42:24:42:27 | "me" | url.go:42:7:42:38 | call to UserPassword | | url.go:42:30:42:37 | "secret" | url.go:42:7:42:38 | call to UserPassword | -| url.go:43:11:43:12 | ui | url.go:43:2:43:23 | ... := ...[0] | -| url.go:43:11:43:23 | call to Password | url.go:43:2:43:23 | ... := ...[0] | -| url.go:43:11:43:23 | call to Password | url.go:43:2:43:23 | ... := ...[1] | +| url.go:43:11:43:12 | ui | url.go:43:2:43:23 | extract:0 ... := ... | +| url.go:43:11:43:23 | call to Password | url.go:43:2:43:23 | extract:0 ... := ... | +| url.go:43:11:43:23 | call to Password | url.go:43:2:43:23 | extract:1 ... := ... | | url.go:45:14:45:15 | ui | url.go:45:14:45:26 | call to Username | -| url.go:50:10:50:26 | call to ParseQuery | url.go:50:2:50:26 | ... := ...[0] | -| url.go:50:10:50:26 | call to ParseQuery | url.go:50:2:50:26 | ... := ...[1] | -| url.go:50:25:50:25 | q | url.go:50:2:50:26 | ... := ...[0] | +| url.go:50:10:50:26 | call to ParseQuery | url.go:50:2:50:26 | extract:0 ... := ... | +| url.go:50:10:50:26 | call to ParseQuery | url.go:50:2:50:26 | extract:1 ... := ... | +| url.go:50:25:50:25 | q | url.go:50:2:50:26 | extract:0 ... := ... | | url.go:51:14:51:14 | v | url.go:51:14:51:23 | call to Encode | | url.go:52:14:52:14 | v | url.go:52:14:52:26 | call to Get | -| url.go:57:16:57:39 | call to JoinPath | url.go:57:2:57:39 | ... := ...[0] | -| url.go:57:16:57:39 | call to JoinPath | url.go:57:2:57:39 | ... := ...[1] | -| url.go:57:29:57:29 | q | url.go:57:2:57:39 | ... := ...[0] | -| url.go:57:32:57:38 | "clean" | url.go:57:2:57:39 | ... := ...[0] | -| url.go:58:16:58:45 | call to JoinPath | url.go:58:2:58:45 | ... := ...[0] | -| url.go:58:16:58:45 | call to JoinPath | url.go:58:2:58:45 | ... := ...[1] | -| url.go:58:29:58:35 | "clean" | url.go:58:2:58:45 | ... := ...[0] | -| url.go:58:38:58:44 | joined1 | url.go:58:2:58:45 | ... := ...[0] | -| url.go:59:14:59:31 | call to Parse | url.go:59:2:59:31 | ... := ...[0] | -| url.go:59:14:59:31 | call to Parse | url.go:59:2:59:31 | ... := ...[1] | -| url.go:59:24:59:30 | joined2 | url.go:59:2:59:31 | ... := ...[0] | +| url.go:57:16:57:39 | call to JoinPath | url.go:57:2:57:39 | extract:0 ... := ... | +| url.go:57:16:57:39 | call to JoinPath | url.go:57:2:57:39 | extract:1 ... := ... | +| url.go:57:29:57:29 | q | url.go:57:2:57:39 | extract:0 ... := ... | +| url.go:57:32:57:38 | "clean" | url.go:57:2:57:39 | extract:0 ... := ... | +| url.go:58:16:58:45 | call to JoinPath | url.go:58:2:58:45 | extract:0 ... := ... | +| url.go:58:16:58:45 | call to JoinPath | url.go:58:2:58:45 | extract:1 ... := ... | +| url.go:58:29:58:35 | "clean" | url.go:58:2:58:45 | extract:0 ... := ... | +| url.go:58:38:58:44 | joined1 | url.go:58:2:58:45 | extract:0 ... := ... | +| url.go:59:14:59:31 | call to Parse | url.go:59:2:59:31 | extract:0 ... := ... | +| url.go:59:14:59:31 | call to Parse | url.go:59:2:59:31 | extract:1 ... := ... | +| url.go:59:24:59:30 | joined2 | url.go:59:2:59:31 | extract:0 ... := ... | | url.go:60:15:60:19 | asUrl | url.go:60:15:60:37 | call to JoinPath | | url.go:60:30:60:36 | "clean" | url.go:60:15:60:37 | call to JoinPath | -| url.go:65:17:65:48 | call to Parse | url.go:65:2:65:48 | ... := ...[0] | -| url.go:65:17:65:48 | call to Parse | url.go:65:2:65:48 | ... := ...[1] | -| url.go:65:27:65:47 | "http://harmless.org" | url.go:65:2:65:48 | ... := ...[0] | +| url.go:65:17:65:48 | call to Parse | url.go:65:2:65:48 | extract:0 ... := ... | +| url.go:65:17:65:48 | call to Parse | url.go:65:2:65:48 | extract:1 ... := ... | +| url.go:65:27:65:47 | "http://harmless.org" | url.go:65:2:65:48 | extract:0 ... := ... | | url.go:66:9:66:16 | cleanUrl | url.go:66:9:66:28 | call to JoinPath | | url.go:66:27:66:27 | q | url.go:66:9:66:28 | call to JoinPath | diff --git a/go/ql/test/query-tests/Security/CWE-022/ZipSlip.expected b/go/ql/test/query-tests/Security/CWE-022/ZipSlip.expected index f1b77213bbc..e7facda57ed 100644 --- a/go/ql/test/query-tests/Security/CWE-022/ZipSlip.expected +++ b/go/ql/test/query-tests/Security/CWE-022/ZipSlip.expected @@ -1,8 +1,8 @@ #select | UnsafeUnzipSymlinkGood.go:72:3:72:25 | extract:0 ... := ... | UnsafeUnzipSymlinkGood.go:72:3:72:25 | extract:0 ... := ... | UnsafeUnzipSymlinkGood.go:61:31:61:62 | call to Join | Unsanitized archive entry, which may contain '..', is used in a $@. | UnsafeUnzipSymlinkGood.go:61:31:61:62 | call to Join | file system operation | -| ZipSlip.go:11:2:15:2 | extract:1 range statement | ZipSlip.go:11:2:15:2 | extract:1 range statement | ZipSlip.go:14:20:14:20 | p | Unsanitized archive entry, which may contain '..', is used in a $@. | ZipSlip.go:14:20:14:20 | p | file system operation | +| ZipSlip.go:11:2:15:2 | extract:1 range element | ZipSlip.go:11:2:15:2 | extract:1 range element | ZipSlip.go:14:20:14:20 | p | Unsanitized archive entry, which may contain '..', is used in a $@. | ZipSlip.go:14:20:14:20 | p | file system operation | | tarslip.go:15:2:15:30 | extract:0 ... := ... | tarslip.go:15:2:15:30 | extract:0 ... := ... | tarslip.go:16:14:16:34 | call to Dir | Unsanitized archive entry, which may contain '..', is used in a $@. | tarslip.go:16:14:16:34 | call to Dir | file system operation | -| tst.go:23:2:43:2 | extract:1 range statement | tst.go:23:2:43:2 | extract:1 range statement | tst.go:29:20:29:23 | path | Unsanitized archive entry, which may contain '..', is used in a $@. | tst.go:29:20:29:23 | path | file system operation | +| tst.go:23:2:43:2 | extract:1 range element | tst.go:23:2:43:2 | extract:1 range element | tst.go:29:20:29:23 | path | Unsanitized archive entry, which may contain '..', is used in a $@. | tst.go:29:20:29:23 | path | file system operation | edges | UnsafeUnzipSymlinkGood.go:52:55:67:1 | SSA def(candidate) | UnsafeUnzipSymlinkGood.go:61:53:61:61 | candidate | provenance | | | UnsafeUnzipSymlinkGood.go:61:53:61:61 | candidate | UnsafeUnzipSymlinkGood.go:61:31:61:62 | call to Join | provenance | FunctionModel Sink:MaD:3 | @@ -10,12 +10,12 @@ edges | UnsafeUnzipSymlinkGood.go:72:3:72:25 | extract:0 ... := ... | UnsafeUnzipSymlinkGood.go:76:70:76:80 | selection of Name | provenance | | | UnsafeUnzipSymlinkGood.go:76:24:76:38 | selection of Linkname | UnsafeUnzipSymlinkGood.go:52:55:67:1 | SSA def(candidate) | provenance | | | UnsafeUnzipSymlinkGood.go:76:70:76:80 | selection of Name | UnsafeUnzipSymlinkGood.go:52:55:67:1 | SSA def(candidate) | provenance | | -| ZipSlip.go:11:2:15:2 | extract:1 range statement | ZipSlip.go:12:24:12:29 | selection of Name | provenance | | +| ZipSlip.go:11:2:15:2 | extract:1 range element | ZipSlip.go:12:24:12:29 | selection of Name | provenance | | | ZipSlip.go:12:3:12:30 | extract:0 ... := ... | ZipSlip.go:14:20:14:20 | p | provenance | Sink:MaD:1 | | ZipSlip.go:12:24:12:29 | selection of Name | ZipSlip.go:12:3:12:30 | extract:0 ... := ... | provenance | MaD:4 | | tarslip.go:15:2:15:30 | extract:0 ... := ... | tarslip.go:16:23:16:33 | selection of Name | provenance | | | tarslip.go:16:23:16:33 | selection of Name | tarslip.go:16:14:16:34 | call to Dir | provenance | MaD:5 Sink:MaD:2 | -| tst.go:23:2:43:2 | extract:1 range statement | tst.go:29:20:29:23 | path | provenance | Sink:MaD:1 | +| tst.go:23:2:43:2 | extract:1 range element | tst.go:29:20:29:23 | path | provenance | Sink:MaD:1 | models | 1 | Sink: io/ioutil; ; false; WriteFile; ; ; Argument[0]; path-injection; manual | | 2 | Sink: os; ; false; MkdirAll; ; ; Argument[0]; path-injection; manual | @@ -29,13 +29,13 @@ nodes | UnsafeUnzipSymlinkGood.go:72:3:72:25 | extract:0 ... := ... | semmle.label | extract:0 ... := ... | | UnsafeUnzipSymlinkGood.go:76:24:76:38 | selection of Linkname | semmle.label | selection of Linkname | | UnsafeUnzipSymlinkGood.go:76:70:76:80 | selection of Name | semmle.label | selection of Name | -| ZipSlip.go:11:2:15:2 | extract:1 range statement | semmle.label | extract:1 range statement | +| ZipSlip.go:11:2:15:2 | extract:1 range element | semmle.label | extract:1 range element | | ZipSlip.go:12:3:12:30 | extract:0 ... := ... | semmle.label | extract:0 ... := ... | | ZipSlip.go:12:24:12:29 | selection of Name | semmle.label | selection of Name | | ZipSlip.go:14:20:14:20 | p | semmle.label | p | | tarslip.go:15:2:15:30 | extract:0 ... := ... | semmle.label | extract:0 ... := ... | | tarslip.go:16:14:16:34 | call to Dir | semmle.label | call to Dir | | tarslip.go:16:23:16:33 | selection of Name | semmle.label | selection of Name | -| tst.go:23:2:43:2 | extract:1 range statement | semmle.label | extract:1 range statement | +| tst.go:23:2:43:2 | extract:1 range element | semmle.label | extract:1 range element | | tst.go:29:20:29:23 | path | semmle.label | path | subpaths diff --git a/go/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected b/go/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected index 904218f731f..365555fe455 100644 --- a/go/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected +++ b/go/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected @@ -60,10 +60,10 @@ | protobuf.go:14:14:14:35 | call to GetDescription | protobuf.go:9:2:9:23 | SSA def(password) | protobuf.go:14:14:14:35 | call to GetDescription | $@ flows to a logging call. | protobuf.go:9:2:9:23 | SSA def(password) | Sensitive data returned by an access to password | | server1.go:19:15:19:19 | user3 | server1.go:17:4:17:63 | key-value pair | server1.go:19:15:19:19 | user3 | $@ flows to a logging call. | server1.go:17:4:17:63 | key-value pair | Sensitive data returned by an access to password | edges -| klog.go:21:3:26:3 | extract:1 range statement | klog.go:22:27:22:33 | headers | provenance | | -| klog.go:21:30:21:37 | selection of Header | klog.go:21:3:26:3 | extract:1 range statement | provenance | Src:MaD:11 Config | -| klog.go:22:4:25:4 | extract:1 range statement | klog.go:23:15:23:20 | header | provenance | | -| klog.go:22:27:22:33 | headers | klog.go:22:4:25:4 | extract:1 range statement | provenance | Config | +| klog.go:21:3:26:3 | extract:1 range element | klog.go:22:27:22:33 | headers | provenance | | +| klog.go:21:30:21:37 | selection of Header | klog.go:21:3:26:3 | extract:1 range element | provenance | Src:MaD:11 Config | +| klog.go:22:4:25:4 | extract:1 range element | klog.go:23:15:23:20 | header | provenance | | +| klog.go:22:27:22:33 | headers | klog.go:22:4:25:4 | extract:1 range element | provenance | Config | | klog.go:29:13:29:20 | selection of Header | klog.go:29:13:29:41 | call to Get | provenance | Src:MaD:11 Config | | main.go:17:2:17:23 | SSA def(password) | main.go:19:12:19:19 | password | provenance | | | main.go:17:2:17:23 | SSA def(password) | main.go:20:19:20:26 | password | provenance | | @@ -175,9 +175,9 @@ models | 10 | Sink: log; Logger; true; Printf; ; ; Argument[0..1]; log-injection; manual | | 11 | Source: net/http; Request; true; Header; ; ; ; remote; manual | nodes -| klog.go:21:3:26:3 | extract:1 range statement | semmle.label | extract:1 range statement | +| klog.go:21:3:26:3 | extract:1 range element | semmle.label | extract:1 range element | | klog.go:21:30:21:37 | selection of Header | semmle.label | selection of Header | -| klog.go:22:4:25:4 | extract:1 range statement | semmle.label | extract:1 range statement | +| klog.go:22:4:25:4 | extract:1 range element | semmle.label | extract:1 range element | | klog.go:22:27:22:33 | headers | semmle.label | headers | | klog.go:23:15:23:20 | header | semmle.label | header | | klog.go:29:13:29:20 | selection of Header | semmle.label | selection of Header |