diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e612a423462..bb25a64ebfb 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -19,7 +19,7 @@ repos: rev: v1.6.0 hooks: - id: autopep8 - files: ^swift/.*\.py + files: ^misc/codegen/.*\.py - repo: local hooks: diff --git a/cpp/downgrades/19887dbd33327fb07d54251786e0cb2578539775/old.dbscheme b/cpp/downgrades/19887dbd33327fb07d54251786e0cb2578539775/old.dbscheme new file mode 100644 index 00000000000..19887dbd333 --- /dev/null +++ b/cpp/downgrades/19887dbd33327fb07d54251786e0cb2578539775/old.dbscheme @@ -0,0 +1,2212 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * gcc -c f1.c f2.c f3.c + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/** + * Information about packages that provide code used during compilation. + * The `id` is just a unique identifier. + * The `namespace` is typically the name of the package manager that + * provided the package (e.g. "dpkg" or "yum"). + * The `package_name` is the name of the package, and `version` is its + * version (as a string). + */ +external_packages( + unique int id: @external_package, + string namespace : string ref, + string package_name : string ref, + string version : string ref +); + +/** + * Holds if File `fileid` was provided by package `package`. + */ +header_to_external_package( + int fileid : @file ref, + int package : @external_package ref +); + +/* + * Version history + */ + +svnentries( + unique int id : @svnentry, + string revision : string ref, + string author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + string action : string ref +) + +svnentrymsg( + unique int id : @svnentry ref, + string message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/* + * C++ dbscheme + */ + +@location = @location_stmt | @location_expr | @location_default ; + +/** + * The location of an element that is not an expression or a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + /** The location of an element that is not an expression or a statement. */ + unique int id: @location_default, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_stmt( + /** The location of a statement. */ + unique int id: @location_stmt, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of an expression. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_expr( + /** The location of an expression. */ + unique int id: @location_expr, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int 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_default ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +case @macroinvocation.kind of + 1 = @macro_expansion +| 2 = @other_macro_reference +; + +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +/* +case @function.kind of + 1 = @normal_function +| 2 = @constructor +| 3 = @destructor +| 4 = @conversion_function +| 5 = @operator +| 6 = @builtin_function // GCC built-in functions, e.g. __builtin___memcpy_chk +; +*/ + +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +function_entry_point( + int id: @function ref, + unique int entry_point: @stmt ref +); + +function_return_type( + int id: @function ref, + int return_type: @type ref +); + +/** + * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits` + * instance associated with it, and the variables representing the `handle` and `promise` + * for it. + */ +coroutine( + unique int function: @function ref, + int traits: @type ref, + int handle: @variable ref, + int promise: @variable ref +); + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +member_function_this_type( + unique int id: @function ref, + int this_type: @type ref +); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) +is_structured_binding(unique int id: @variable ref); + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @functionorblock ref, + int index: int ref, + int type_id: @type ref +); + +overrides( + int new: @function ref, + int old: @function ref +); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +orphaned_variables( + int var: @localvariable ref, + int function: @function ref +) + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/** + * Built-in types are the fundamental types, e.g., integral, floating, and void. + */ +case @builtintype.kind of + 1 = @errortype +| 2 = @unknowntype +| 3 = @void +| 4 = @boolean +| 5 = @char +| 6 = @unsigned_char +| 7 = @signed_char +| 8 = @short +| 9 = @unsigned_short +| 10 = @signed_short +| 11 = @int +| 12 = @unsigned_int +| 13 = @signed_int +| 14 = @long +| 15 = @unsigned_long +| 16 = @signed_long +| 17 = @long_long +| 18 = @unsigned_long_long +| 19 = @signed_long_long +// ... 20 Microsoft-specific __int8 +// ... 21 Microsoft-specific __int16 +// ... 22 Microsoft-specific __int32 +// ... 23 Microsoft-specific __int64 +| 24 = @float +| 25 = @double +| 26 = @long_double +| 27 = @complex_float // C99-specific _Complex float +| 28 = @complex_double // C99-specific _Complex double +| 29 = @complex_long_double // C99-specific _Complex long double +| 30 = @imaginary_float // C99-specific _Imaginary float +| 31 = @imaginary_double // C99-specific _Imaginary double +| 32 = @imaginary_long_double // C99-specific _Imaginary long double +| 33 = @wchar_t // Microsoft-specific +| 34 = @decltype_nullptr // C++11 +| 35 = @int128 // __int128 +| 36 = @unsigned_int128 // unsigned __int128 +| 37 = @signed_int128 // signed __int128 +| 38 = @float128 // __float128 +| 39 = @complex_float128 // _Complex __float128 +| 40 = @decimal32 // _Decimal32 +| 41 = @decimal64 // _Decimal64 +| 42 = @decimal128 // _Decimal128 +| 43 = @char16_t +| 44 = @char32_t +| 45 = @std_float32 // _Float32 +| 46 = @float32x // _Float32x +| 47 = @std_float64 // _Float64 +| 48 = @float64x // _Float64x +| 49 = @std_float128 // _Float128 +| 50 = @float128x // _Float128x +| 51 = @char8_t +| 52 = @float16 // _Float16 +| 53 = @complex_float16 // _Complex _Float16 +; + +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/** + * Derived types are types that are directly derived from existing types and + * point to, refer to, transform type data to return a new type. + */ +case @derivedtype.kind of + 1 = @pointer +| 2 = @reference +| 3 = @type_with_specifiers +| 4 = @array +| 5 = @gnu_vector +| 6 = @routineptr +| 7 = @routinereference +| 8 = @rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated +| 10 = @block +; + +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +/** + * An instance of the C++11 `decltype` operator. For example: + * ``` + * int a; + * decltype(1+a) b; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * would change the semantics of this decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ +#keyset[id, expr] +decltypes( + int id: @decltype, + int expr: @expr ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +/* +case @usertype.kind of + 1 = @struct +| 2 = @class +| 3 = @union +| 4 = @enum +| 5 = @typedef // classic C: typedef typedef type name +| 6 = @template +| 7 = @template_parameter +| 8 = @template_template_parameter +| 9 = @proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated +| 13 = @scoped_enum +| 14 = @using_alias // a using name = type style typedef +; +*/ + +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + string uuid: string ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +is_proxy_class_for( + unique int id: @usertype ref, + unique int templ_param_id: @usertype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location ref, + // a_symbol_reference_kind from the frontend. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); + +/* + Fixed point types + precision(1) = short, precision(2) = default, precision(3) = long + is_unsigned(1) = unsigned is_unsigned(2) = signed + is_fract_type(1) = declared with _Fract + saturating(1) = declared with _Sat +*/ +/* TODO +fixedpointtypes( + unique int id: @fixedpointtype, + int precision: int ref, + int is_unsigned: int ref, + int is_fract_type: int ref, + int saturating: int ref); +*/ + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +| 4 = @attribute_arg_constant_expr +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_constant( + unique int arg: @attribute_arg ref, + int constant: @expr ref +) +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + /* TODO | @fixedpointtype */ + | @routinetype + | @ptrtomember + | @decltype; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall( + unique int caller: @funbindexpr ref, + int kind: int ref +); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr + +@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr + +/* + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 3 = size_and_alignment + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_expr ref +); + +braced_initialisers( + int init: @initialiser ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_expr ref +); + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +| 330 = @isassignable +| 331 = @isaggregate +| 332 = @hasuniqueobjectrepresentations +| 333 = @builtinbitcast +| 334 = @builtinshuffle +| 335 = @blockassignexpr +| 336 = @issame +| 337 = @isfunction +| 338 = @islayoutcompatible +| 339 = @ispointerinterconvertiblebaseof +| 340 = @isarray +| 341 = @arrayrank +| 342 = @arrayextent +| 343 = @isarithmetic +| 344 = @iscompletetype +| 345 = @iscompound +| 346 = @isconst +| 347 = @isfloatingpoint +| 348 = @isfundamental +| 349 = @isintegral +| 350 = @islvaluereference +| 351 = @ismemberfunctionpointer +| 352 = @ismemberobjectpointer +| 353 = @ismemberpointer +| 354 = @isobject +| 355 = @ispointer +| 356 = @isreference +| 357 = @isrvaluereference +| 358 = @isscalar +| 359 = @issigned +| 360 = @isunsigned +| 361 = @isvoid +| 362 = @isvolatile +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + | @isassignable + | @isaggregate + | @hasuniqueobjectrepresentations + | @builtinbitcast + | @builtinshuffle + | @issame + | @isfunction + | @islayoutcompatible + | @ispointerinterconvertiblebaseof + | @isarray + | @arrayrank + | @arrayextent + | @isarithmetic + | @iscompletetype + | @iscompound + | @isconst + | @isfloatingpoint + | @isfundamental + | @isintegral + | @islvaluereference + | @ismemberfunctionpointer + | @ismemberobjectpointer + | @ismemberpointer + | @isobject + | @ispointer + | @isreference + | @isrvaluereference + | @isscalar + | @issigned + | @isunsigned + | @isvoid + | @isvolatile + ; + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref, + int position: int ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref, + int position: int ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof; + +sizeof_bind( + unique int expr: @runtime_sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_stmt ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +if_initialization( + unique int if_stmt: @stmt_if ref, + int init_id: @stmt ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_initialization( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int init_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +switch_initialization( + unique int switch_stmt: @stmt_switch ref, + int init_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +for_initialization( + unique int for_stmt: @stmt_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@functionorblock = @function | @stmt_block; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @functionorblock ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +link_targets( + unique int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target 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; diff --git a/cpp/downgrades/19887dbd33327fb07d54251786e0cb2578539775/semmlecode.cpp.dbscheme b/cpp/downgrades/19887dbd33327fb07d54251786e0cb2578539775/semmlecode.cpp.dbscheme new file mode 100644 index 00000000000..a5bb28ed29f --- /dev/null +++ b/cpp/downgrades/19887dbd33327fb07d54251786e0cb2578539775/semmlecode.cpp.dbscheme @@ -0,0 +1,2210 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * gcc -c f1.c f2.c f3.c + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/** + * Information about packages that provide code used during compilation. + * The `id` is just a unique identifier. + * The `namespace` is typically the name of the package manager that + * provided the package (e.g. "dpkg" or "yum"). + * The `package_name` is the name of the package, and `version` is its + * version (as a string). + */ +external_packages( + unique int id: @external_package, + string namespace : string ref, + string package_name : string ref, + string version : string ref +); + +/** + * Holds if File `fileid` was provided by package `package`. + */ +header_to_external_package( + int fileid : @file ref, + int package : @external_package ref +); + +/* + * Version history + */ + +svnentries( + unique int id : @svnentry, + string revision : string ref, + string author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + string action : string ref +) + +svnentrymsg( + unique int id : @svnentry ref, + string message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/* + * C++ dbscheme + */ + +@location = @location_stmt | @location_expr | @location_default ; + +/** + * The location of an element that is not an expression or a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + /** The location of an element that is not an expression or a statement. */ + unique int id: @location_default, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_stmt( + /** The location of a statement. */ + unique int id: @location_stmt, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of an expression. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_expr( + /** The location of an expression. */ + unique int id: @location_expr, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int 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_default ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +case @macroinvocation.kind of + 1 = @macro_expansion +| 2 = @other_macro_reference +; + +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +/* +case @function.kind of + 1 = @normal_function +| 2 = @constructor +| 3 = @destructor +| 4 = @conversion_function +| 5 = @operator +| 6 = @builtin_function // GCC built-in functions, e.g. __builtin___memcpy_chk +; +*/ + +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +function_entry_point( + int id: @function ref, + unique int entry_point: @stmt ref +); + +function_return_type( + int id: @function ref, + int return_type: @type ref +); + +/** + * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits` + * instance associated with it, and the variables representing the `handle` and `promise` + * for it. + */ +coroutine( + unique int function: @function ref, + int traits: @type ref, + int handle: @variable ref, + int promise: @variable ref +); + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +member_function_this_type( + unique int id: @function ref, + int this_type: @type ref +); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) +is_structured_binding(unique int id: @variable ref); + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @functionorblock ref, + int index: int ref, + int type_id: @type ref +); + +overrides( + int new: @function ref, + int old: @function ref +); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +orphaned_variables( + int var: @localvariable ref, + int function: @function ref +) + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/** + * Built-in types are the fundamental types, e.g., integral, floating, and void. + */ +case @builtintype.kind of + 1 = @errortype +| 2 = @unknowntype +| 3 = @void +| 4 = @boolean +| 5 = @char +| 6 = @unsigned_char +| 7 = @signed_char +| 8 = @short +| 9 = @unsigned_short +| 10 = @signed_short +| 11 = @int +| 12 = @unsigned_int +| 13 = @signed_int +| 14 = @long +| 15 = @unsigned_long +| 16 = @signed_long +| 17 = @long_long +| 18 = @unsigned_long_long +| 19 = @signed_long_long +// ... 20 Microsoft-specific __int8 +// ... 21 Microsoft-specific __int16 +// ... 22 Microsoft-specific __int32 +// ... 23 Microsoft-specific __int64 +| 24 = @float +| 25 = @double +| 26 = @long_double +| 27 = @complex_float // C99-specific _Complex float +| 28 = @complex_double // C99-specific _Complex double +| 29 = @complex_long_double // C99-specific _Complex long double +| 30 = @imaginary_float // C99-specific _Imaginary float +| 31 = @imaginary_double // C99-specific _Imaginary double +| 32 = @imaginary_long_double // C99-specific _Imaginary long double +| 33 = @wchar_t // Microsoft-specific +| 34 = @decltype_nullptr // C++11 +| 35 = @int128 // __int128 +| 36 = @unsigned_int128 // unsigned __int128 +| 37 = @signed_int128 // signed __int128 +| 38 = @float128 // __float128 +| 39 = @complex_float128 // _Complex __float128 +| 40 = @decimal32 // _Decimal32 +| 41 = @decimal64 // _Decimal64 +| 42 = @decimal128 // _Decimal128 +| 43 = @char16_t +| 44 = @char32_t +| 45 = @std_float32 // _Float32 +| 46 = @float32x // _Float32x +| 47 = @std_float64 // _Float64 +| 48 = @float64x // _Float64x +| 49 = @std_float128 // _Float128 +| 50 = @float128x // _Float128x +| 51 = @char8_t +| 52 = @float16 // _Float16 +| 53 = @complex_float16 // _Complex _Float16 +; + +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/** + * Derived types are types that are directly derived from existing types and + * point to, refer to, transform type data to return a new type. + */ +case @derivedtype.kind of + 1 = @pointer +| 2 = @reference +| 3 = @type_with_specifiers +| 4 = @array +| 5 = @gnu_vector +| 6 = @routineptr +| 7 = @routinereference +| 8 = @rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated +| 10 = @block +; + +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +/** + * An instance of the C++11 `decltype` operator. For example: + * ``` + * int a; + * decltype(1+a) b; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * would change the semantics of this decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ +#keyset[id, expr] +decltypes( + int id: @decltype, + int expr: @expr ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +/* +case @usertype.kind of + 1 = @struct +| 2 = @class +| 3 = @union +| 4 = @enum +| 5 = @typedef // classic C: typedef typedef type name +| 6 = @template +| 7 = @template_parameter +| 8 = @template_template_parameter +| 9 = @proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated +| 13 = @scoped_enum +| 14 = @using_alias // a using name = type style typedef +; +*/ + +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + string uuid: string ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +is_proxy_class_for( + unique int id: @usertype ref, + unique int templ_param_id: @usertype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location ref, + // a_symbol_reference_kind from the frontend. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); + +/* + Fixed point types + precision(1) = short, precision(2) = default, precision(3) = long + is_unsigned(1) = unsigned is_unsigned(2) = signed + is_fract_type(1) = declared with _Fract + saturating(1) = declared with _Sat +*/ +/* TODO +fixedpointtypes( + unique int id: @fixedpointtype, + int precision: int ref, + int is_unsigned: int ref, + int is_fract_type: int ref, + int saturating: int ref); +*/ + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +| 4 = @attribute_arg_constant_expr +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_constant( + unique int arg: @attribute_arg ref, + int constant: @expr ref +) +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + /* TODO | @fixedpointtype */ + | @routinetype + | @ptrtomember + | @decltype; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall( + unique int caller: @funbindexpr ref, + int kind: int ref +); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr + +@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr + +/* + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 3 = size_and_alignment + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_expr ref +); + +braced_initialisers( + int init: @initialiser ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_expr ref +); + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +| 330 = @isassignable +| 331 = @isaggregate +| 332 = @hasuniqueobjectrepresentations +| 333 = @builtinbitcast +| 334 = @builtinshuffle +| 335 = @blockassignexpr +| 336 = @issame +| 337 = @isfunction +| 338 = @islayoutcompatible +| 339 = @ispointerinterconvertiblebaseof +| 340 = @isarray +| 341 = @arrayrank +| 342 = @arrayextent +| 343 = @isarithmetic +| 344 = @iscompletetype +| 345 = @iscompound +| 346 = @isconst +| 347 = @isfloatingpoint +| 348 = @isfundamental +| 349 = @isintegral +| 350 = @islvaluereference +| 351 = @ismemberfunctionpointer +| 352 = @ismemberobjectpointer +| 353 = @ismemberpointer +| 354 = @isobject +| 355 = @ispointer +| 356 = @isreference +| 357 = @isrvaluereference +| 358 = @isscalar +| 359 = @issigned +| 360 = @isunsigned +| 361 = @isvoid +| 362 = @isvolatile +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + | @isassignable + | @isaggregate + | @hasuniqueobjectrepresentations + | @builtinbitcast + | @builtinshuffle + | @issame + | @isfunction + | @islayoutcompatible + | @ispointerinterconvertiblebaseof + | @isarray + | @arrayrank + | @arrayextent + | @isarithmetic + | @iscompletetype + | @iscompound + | @isconst + | @isfloatingpoint + | @isfundamental + | @isintegral + | @islvaluereference + | @ismemberfunctionpointer + | @ismemberobjectpointer + | @ismemberpointer + | @isobject + | @ispointer + | @isreference + | @isrvaluereference + | @isscalar + | @issigned + | @isunsigned + | @isvoid + | @isvolatile + ; + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. + */ +#keyset[aggregate, field] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. + */ +#keyset[aggregate, element_index] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof; + +sizeof_bind( + unique int expr: @runtime_sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_stmt ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +if_initialization( + unique int if_stmt: @stmt_if ref, + int init_id: @stmt ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_initialization( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int init_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +switch_initialization( + unique int switch_stmt: @stmt_switch ref, + int init_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +for_initialization( + unique int for_stmt: @stmt_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@functionorblock = @function | @stmt_block; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @functionorblock ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +link_targets( + unique int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target 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; diff --git a/cpp/downgrades/19887dbd33327fb07d54251786e0cb2578539775/upgrade.properties b/cpp/downgrades/19887dbd33327fb07d54251786e0cb2578539775/upgrade.properties new file mode 100644 index 00000000000..eab51f4d94d --- /dev/null +++ b/cpp/downgrades/19887dbd33327fb07d54251786e0cb2578539775/upgrade.properties @@ -0,0 +1,4 @@ +description: Revert support for repeated initializers, which are allowed in C with designated initializers. +compatibility: full +aggregate_field_init.rel: reorder aggregate_field_init.rel (int aggregate, int initializer, int field, int position) aggregate initializer field +aggregate_array_init.rel: reorder aggregate_array_init.rel (int aggregate, int initializer, int element_index, int position) aggregate initializer element_index diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/rangeanalysis/Bound.qll b/cpp/ql/lib/experimental/semmle/code/cpp/rangeanalysis/Bound.qll index abff447ca87..cca5f635ad6 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/rangeanalysis/Bound.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/rangeanalysis/Bound.qll @@ -1,86 +1 @@ -import cpp -private import semmle.code.cpp.ir.IR -private import semmle.code.cpp.ir.ValueNumbering - -private newtype TBound = - TBoundZero() or - TBoundValueNumber(ValueNumber vn) { - exists(Instruction i | - vn.getAnInstruction() = i and - ( - i.getResultIRType() instanceof IRIntegerType or - i.getResultIRType() instanceof IRAddressType - ) and - not vn.getAnInstruction() instanceof ConstantInstruction - | - i instanceof PhiInstruction - or - i instanceof InitializeParameterInstruction - or - i instanceof CallInstruction - or - i instanceof VariableAddressInstruction - or - i instanceof FieldAddressInstruction - or - i.(LoadInstruction).getSourceAddress() instanceof VariableAddressInstruction - or - i.(LoadInstruction).getSourceAddress() instanceof FieldAddressInstruction - or - i.getAUse() instanceof ArgumentOperand - or - i instanceof PointerArithmeticInstruction - or - i.getAUse() instanceof AddressOperand - ) - } - -/** - * A bound that may be inferred for an expression plus/minus an integer delta. - */ -abstract class Bound extends TBound { - abstract string toString(); - - /** Gets an expression that equals this bound plus `delta`. */ - abstract Instruction getInstruction(int delta); - - /** Gets an expression that equals this bound. */ - Instruction getInstruction() { result = getInstruction(0) } - - abstract Location getLocation(); -} - -/** - * The bound that corresponds to the integer 0. This is used to represent all - * integer bounds as bounds are always accompanied by an added integer delta. - */ -class ZeroBound extends Bound, TBoundZero { - override string toString() { result = "0" } - - override Instruction getInstruction(int delta) { - result.(ConstantValueInstruction).getValue().toInt() = delta - } - - override Location getLocation() { result instanceof UnknownDefaultLocation } -} - -/** - * A bound corresponding to the value of an `Instruction`. - */ -class ValueNumberBound extends Bound, TBoundValueNumber { - ValueNumber vn; - - ValueNumberBound() { this = TBoundValueNumber(vn) } - - /** Gets an `Instruction` that equals this bound. */ - override Instruction getInstruction(int delta) { - this = TBoundValueNumber(valueNumber(result)) and delta = 0 - } - - override string toString() { result = "ValueNumberBound" } - - override Location getLocation() { result = vn.getLocation() } - - /** Gets the value number that equals this bound. */ - ValueNumber getValueNumber() { result = vn } -} +import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.Bound diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/rangeanalysis/extensions/RangeNode.qll b/cpp/ql/lib/experimental/semmle/code/cpp/rangeanalysis/extensions/RangeNode.qll new file mode 100644 index 00000000000..d24d754a4ac --- /dev/null +++ b/cpp/ql/lib/experimental/semmle/code/cpp/rangeanalysis/extensions/RangeNode.qll @@ -0,0 +1,115 @@ +/** + * This module implements subclasses for various DataFlow nodes that extends + * their `toString()` predicates with range information, if applicable. By + * including this module in a `path-problem` query, this range information + * will be displayed at each step in the query results. + * + * This is currently implemented for `DataFlow::ExprNode` and `DataFlow::DefinitionByReferenceNode`, + * but it is not yet implemented for `DataFlow::ParameterNode`. + */ + +private import cpp +private import semmle.code.cpp.dataflow.DataFlow +private import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis + +string getExprBoundAsString(Expr e) { + if exists(lowerBound(e)) and exists(upperBound(e)) + then result = "[" + lowerBound(e) + ", " + upperBound(e) + "]" + else result = "[unknown range]" +} + +/** + * Holds for any integer type after resolving typedefs and stripping `const` + * specifiers, such as for `const size_t` + */ +predicate isIntegralType(Type t) { + // We use `getUnspecifiedType` here because without it things like + // `const size_t` aren't considered to be integral + t.getUnspecifiedType() instanceof IntegralType +} + +/** + * Holds for any reference to an integer type after resolving typedefs and + * stripping `const` specifiers, such as for `const size_t&` + */ +predicate isIntegralReferenceType(Type t) { isIntegralType(t.(ReferenceType).stripType()) } + +/** + * Holds for any pointer to an integer type after resolving typedefs and + * stripping `const` specifiers, such as for `const size_t*`. This predicate + * holds for any pointer depth, such as for `const size_t**`. + */ +predicate isIntegralPointerType(Type t) { isIntegralType(t.(PointerType).stripType()) } + +predicate hasIntegralOrReferenceIntegralType(Locatable e) { + exists(Type t | + ( + t = e.(Expr).getUnspecifiedType() + or + // This will cover variables, parameters, type declarations, etc. + t = e.(DeclarationEntry).getUnspecifiedType() + ) and + (isIntegralType(t) or isIntegralReferenceType(t)) + ) +} + +Expr getLOp(Operation o) { + result = o.(BinaryOperation).getLeftOperand() or + result = o.(Assignment).getLValue() +} + +Expr getROp(Operation o) { + result = o.(BinaryOperation).getRightOperand() or + result = o.(Assignment).getRValue() +} + +/** + * Display the ranges of expressions in the path view + */ +private class ExprRangeNode extends DataFlow::ExprNode { + pragma[inline] + private string getIntegralBounds(Expr arg) { + if hasIntegralOrReferenceIntegralType(arg) + then result = getExprBoundAsString(arg) + else result = "" + } + + private string getOperationBounds(Operation e) { + result = + getExprBoundAsString(e) + " = " + getExprBoundAsString(getLOp(e)) + e.getOperator() + + getExprBoundAsString(getROp(e)) + } + + private string getCallBounds(Call e) { + result = + getExprBoundAsString(e) + "(" + + concat(Expr arg, int i | arg = e.getArgument(i) | getIntegralBounds(arg) order by i, ",") + + ")" + } + + override string toString() { + exists(Expr e | e = getExpr() | + if hasIntegralOrReferenceIntegralType(e) + then + result = super.toString() + ": " + getOperationBounds(e) + or + result = super.toString() + ": " + getCallBounds(e) + or + not exists(getOperationBounds(e)) and + not exists(getCallBounds(e)) and + result = super.toString() + ": " + getExprBoundAsString(e) + else result = super.toString() + ) + } +} + +/** + * Display the ranges of expressions in the path view + */ +private class ReferenceArgumentRangeNode extends DataFlow::DefinitionByReferenceNode { + override string toString() { + if hasIntegralOrReferenceIntegralType(asDefiningArgument()) + then result = super.toString() + ": " + getExprBoundAsString(getArgument()) + else result = super.toString() + } +} diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysis.qll b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysis.qll deleted file mode 100644 index 0413aefd5ad..00000000000 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysis.qll +++ /dev/null @@ -1,3 +0,0 @@ -import experimental.semmle.code.cpp.semantic.SemanticBound -private import RangeAnalysisImpl as Impl -import Impl::Public \ No newline at end of file diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/Literal.qll b/cpp/ql/lib/semmle/code/cpp/exprs/Literal.qll index 93609763ec3..566e4675a9f 100644 --- a/cpp/ql/lib/semmle/code/cpp/exprs/Literal.qll +++ b/cpp/ql/lib/semmle/code/cpp/exprs/Literal.qll @@ -192,7 +192,8 @@ class ClassAggregateLiteral extends AggregateLiteral { */ Expr getFieldExpr(Field field) { field = classType.getAField() and - aggregate_field_init(underlyingElement(this), unresolveElement(result), unresolveElement(field)) + aggregate_field_init(underlyingElement(this), unresolveElement(result), unresolveElement(field), + _) } /** @@ -264,7 +265,7 @@ class ArrayOrVectorAggregateLiteral extends AggregateLiteral { * element `elementIndex`, if present. */ Expr getElementExpr(int elementIndex) { - aggregate_array_init(underlyingElement(this), unresolveElement(result), elementIndex) + aggregate_array_init(underlyingElement(this), unresolveElement(result), elementIndex, _) } /** diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/internal/ValueNumberingInternal.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/internal/ValueNumberingInternal.qll index 2dc735f49df..85a28fbc677 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/internal/ValueNumberingInternal.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/internal/ValueNumberingInternal.qll @@ -159,26 +159,56 @@ private predicate fieldAddressValueNumber( tvalueNumber(instr.getObjectAddress()) = objectAddress } +pragma[nomagic] +private predicate binaryValueNumber0( + BinaryInstruction instr, IRFunction irFunc, Opcode opcode, boolean isLeft, + TValueNumber valueNumber +) { + not instr instanceof PointerArithmeticInstruction and + instr.getEnclosingIRFunction() = irFunc and + instr.getOpcode() = opcode and + ( + isLeft = true and + tvalueNumber(instr.getLeft()) = valueNumber + or + isLeft = false and + tvalueNumber(instr.getRight()) = valueNumber + ) +} + +pragma[assume_small_delta] private predicate binaryValueNumber( BinaryInstruction instr, IRFunction irFunc, Opcode opcode, TValueNumber leftOperand, TValueNumber rightOperand ) { - instr.getEnclosingIRFunction() = irFunc and - not instr instanceof PointerArithmeticInstruction and - instr.getOpcode() = opcode and - tvalueNumber(instr.getLeft()) = leftOperand and - tvalueNumber(instr.getRight()) = rightOperand + binaryValueNumber0(instr, irFunc, opcode, true, leftOperand) and + binaryValueNumber0(instr, irFunc, opcode, false, rightOperand) } -private predicate pointerArithmeticValueNumber( +pragma[nomagic] +private predicate pointerArithmeticValueNumber0( PointerArithmeticInstruction instr, IRFunction irFunc, Opcode opcode, int elementSize, - TValueNumber leftOperand, TValueNumber rightOperand + boolean isLeft, TValueNumber valueNumber ) { instr.getEnclosingIRFunction() = irFunc and instr.getOpcode() = opcode and instr.getElementSize() = elementSize and - tvalueNumber(instr.getLeft()) = leftOperand and - tvalueNumber(instr.getRight()) = rightOperand + ( + isLeft = true and + tvalueNumber(instr.getLeft()) = valueNumber + or + isLeft = false and + tvalueNumber(instr.getRight()) = valueNumber + ) +} + +pragma[assume_small_delta] +private predicate pointerArithmeticValueNumber( + PointerArithmeticInstruction instr, IRFunction irFunc, Opcode opcode, int elementSize, + TValueNumber leftOperand, TValueNumber rightOperand +) { + pointerArithmeticValueNumber0(instr, irFunc, opcode, elementSize, true, leftOperand) and + pointerArithmeticValueNumber0(instr, irFunc, opcode, elementSize, false, rightOperand) } private predicate unaryValueNumber( @@ -203,14 +233,29 @@ private predicate inheritanceConversionValueNumber( unique( | | instr.getDerivedClass()) = derivedClass } +pragma[nomagic] +private predicate loadTotalOverlapValueNumber0( + LoadTotalOverlapInstruction instr, IRFunction irFunc, IRType type, TValueNumber valueNumber, + boolean isAddress +) { + instr.getEnclosingIRFunction() = irFunc and + instr.getResultIRType() = type and + ( + isAddress = true and + tvalueNumberOfOperand(instr.getSourceAddressOperand()) = valueNumber + or + isAddress = false and + tvalueNumber(instr.getSourceValueOperand().getAnyDef()) = valueNumber + ) +} + +pragma[assume_small_delta] private predicate loadTotalOverlapValueNumber( LoadTotalOverlapInstruction instr, IRFunction irFunc, IRType type, TValueNumber memOperand, TValueNumber operand ) { - instr.getEnclosingIRFunction() = irFunc and - tvalueNumber(instr.getAnOperand().(MemoryOperand).getAnyDef()) = memOperand and - tvalueNumberOfOperand(instr.getAnOperand().(AddressOperand)) = operand and - instr.getResultIRType() = type + loadTotalOverlapValueNumber0(instr, irFunc, type, operand, true) and + loadTotalOverlapValueNumber0(instr, irFunc, type, memOperand, false) } /** diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/gvn/internal/ValueNumberingInternal.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/gvn/internal/ValueNumberingInternal.qll index 2dc735f49df..85a28fbc677 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/gvn/internal/ValueNumberingInternal.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/gvn/internal/ValueNumberingInternal.qll @@ -159,26 +159,56 @@ private predicate fieldAddressValueNumber( tvalueNumber(instr.getObjectAddress()) = objectAddress } +pragma[nomagic] +private predicate binaryValueNumber0( + BinaryInstruction instr, IRFunction irFunc, Opcode opcode, boolean isLeft, + TValueNumber valueNumber +) { + not instr instanceof PointerArithmeticInstruction and + instr.getEnclosingIRFunction() = irFunc and + instr.getOpcode() = opcode and + ( + isLeft = true and + tvalueNumber(instr.getLeft()) = valueNumber + or + isLeft = false and + tvalueNumber(instr.getRight()) = valueNumber + ) +} + +pragma[assume_small_delta] private predicate binaryValueNumber( BinaryInstruction instr, IRFunction irFunc, Opcode opcode, TValueNumber leftOperand, TValueNumber rightOperand ) { - instr.getEnclosingIRFunction() = irFunc and - not instr instanceof PointerArithmeticInstruction and - instr.getOpcode() = opcode and - tvalueNumber(instr.getLeft()) = leftOperand and - tvalueNumber(instr.getRight()) = rightOperand + binaryValueNumber0(instr, irFunc, opcode, true, leftOperand) and + binaryValueNumber0(instr, irFunc, opcode, false, rightOperand) } -private predicate pointerArithmeticValueNumber( +pragma[nomagic] +private predicate pointerArithmeticValueNumber0( PointerArithmeticInstruction instr, IRFunction irFunc, Opcode opcode, int elementSize, - TValueNumber leftOperand, TValueNumber rightOperand + boolean isLeft, TValueNumber valueNumber ) { instr.getEnclosingIRFunction() = irFunc and instr.getOpcode() = opcode and instr.getElementSize() = elementSize and - tvalueNumber(instr.getLeft()) = leftOperand and - tvalueNumber(instr.getRight()) = rightOperand + ( + isLeft = true and + tvalueNumber(instr.getLeft()) = valueNumber + or + isLeft = false and + tvalueNumber(instr.getRight()) = valueNumber + ) +} + +pragma[assume_small_delta] +private predicate pointerArithmeticValueNumber( + PointerArithmeticInstruction instr, IRFunction irFunc, Opcode opcode, int elementSize, + TValueNumber leftOperand, TValueNumber rightOperand +) { + pointerArithmeticValueNumber0(instr, irFunc, opcode, elementSize, true, leftOperand) and + pointerArithmeticValueNumber0(instr, irFunc, opcode, elementSize, false, rightOperand) } private predicate unaryValueNumber( @@ -203,14 +233,29 @@ private predicate inheritanceConversionValueNumber( unique( | | instr.getDerivedClass()) = derivedClass } +pragma[nomagic] +private predicate loadTotalOverlapValueNumber0( + LoadTotalOverlapInstruction instr, IRFunction irFunc, IRType type, TValueNumber valueNumber, + boolean isAddress +) { + instr.getEnclosingIRFunction() = irFunc and + instr.getResultIRType() = type and + ( + isAddress = true and + tvalueNumberOfOperand(instr.getSourceAddressOperand()) = valueNumber + or + isAddress = false and + tvalueNumber(instr.getSourceValueOperand().getAnyDef()) = valueNumber + ) +} + +pragma[assume_small_delta] private predicate loadTotalOverlapValueNumber( LoadTotalOverlapInstruction instr, IRFunction irFunc, IRType type, TValueNumber memOperand, TValueNumber operand ) { - instr.getEnclosingIRFunction() = irFunc and - tvalueNumber(instr.getAnOperand().(MemoryOperand).getAnyDef()) = memOperand and - tvalueNumberOfOperand(instr.getAnOperand().(AddressOperand)) = operand and - instr.getResultIRType() = type + loadTotalOverlapValueNumber0(instr, irFunc, type, operand, true) and + loadTotalOverlapValueNumber0(instr, irFunc, type, memOperand, false) } /** diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/gvn/internal/ValueNumberingInternal.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/gvn/internal/ValueNumberingInternal.qll index 2dc735f49df..85a28fbc677 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/gvn/internal/ValueNumberingInternal.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/gvn/internal/ValueNumberingInternal.qll @@ -159,26 +159,56 @@ private predicate fieldAddressValueNumber( tvalueNumber(instr.getObjectAddress()) = objectAddress } +pragma[nomagic] +private predicate binaryValueNumber0( + BinaryInstruction instr, IRFunction irFunc, Opcode opcode, boolean isLeft, + TValueNumber valueNumber +) { + not instr instanceof PointerArithmeticInstruction and + instr.getEnclosingIRFunction() = irFunc and + instr.getOpcode() = opcode and + ( + isLeft = true and + tvalueNumber(instr.getLeft()) = valueNumber + or + isLeft = false and + tvalueNumber(instr.getRight()) = valueNumber + ) +} + +pragma[assume_small_delta] private predicate binaryValueNumber( BinaryInstruction instr, IRFunction irFunc, Opcode opcode, TValueNumber leftOperand, TValueNumber rightOperand ) { - instr.getEnclosingIRFunction() = irFunc and - not instr instanceof PointerArithmeticInstruction and - instr.getOpcode() = opcode and - tvalueNumber(instr.getLeft()) = leftOperand and - tvalueNumber(instr.getRight()) = rightOperand + binaryValueNumber0(instr, irFunc, opcode, true, leftOperand) and + binaryValueNumber0(instr, irFunc, opcode, false, rightOperand) } -private predicate pointerArithmeticValueNumber( +pragma[nomagic] +private predicate pointerArithmeticValueNumber0( PointerArithmeticInstruction instr, IRFunction irFunc, Opcode opcode, int elementSize, - TValueNumber leftOperand, TValueNumber rightOperand + boolean isLeft, TValueNumber valueNumber ) { instr.getEnclosingIRFunction() = irFunc and instr.getOpcode() = opcode and instr.getElementSize() = elementSize and - tvalueNumber(instr.getLeft()) = leftOperand and - tvalueNumber(instr.getRight()) = rightOperand + ( + isLeft = true and + tvalueNumber(instr.getLeft()) = valueNumber + or + isLeft = false and + tvalueNumber(instr.getRight()) = valueNumber + ) +} + +pragma[assume_small_delta] +private predicate pointerArithmeticValueNumber( + PointerArithmeticInstruction instr, IRFunction irFunc, Opcode opcode, int elementSize, + TValueNumber leftOperand, TValueNumber rightOperand +) { + pointerArithmeticValueNumber0(instr, irFunc, opcode, elementSize, true, leftOperand) and + pointerArithmeticValueNumber0(instr, irFunc, opcode, elementSize, false, rightOperand) } private predicate unaryValueNumber( @@ -203,14 +233,29 @@ private predicate inheritanceConversionValueNumber( unique( | | instr.getDerivedClass()) = derivedClass } +pragma[nomagic] +private predicate loadTotalOverlapValueNumber0( + LoadTotalOverlapInstruction instr, IRFunction irFunc, IRType type, TValueNumber valueNumber, + boolean isAddress +) { + instr.getEnclosingIRFunction() = irFunc and + instr.getResultIRType() = type and + ( + isAddress = true and + tvalueNumberOfOperand(instr.getSourceAddressOperand()) = valueNumber + or + isAddress = false and + tvalueNumber(instr.getSourceValueOperand().getAnyDef()) = valueNumber + ) +} + +pragma[assume_small_delta] private predicate loadTotalOverlapValueNumber( LoadTotalOverlapInstruction instr, IRFunction irFunc, IRType type, TValueNumber memOperand, TValueNumber operand ) { - instr.getEnclosingIRFunction() = irFunc and - tvalueNumber(instr.getAnOperand().(MemoryOperand).getAnyDef()) = memOperand and - tvalueNumberOfOperand(instr.getAnOperand().(AddressOperand)) = operand and - instr.getResultIRType() = type + loadTotalOverlapValueNumber0(instr, irFunc, type, operand, true) and + loadTotalOverlapValueNumber0(instr, irFunc, type, memOperand, false) } /** diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/SimpleRangeAnalysis.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/SimpleRangeAnalysis.qll similarity index 93% rename from cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/SimpleRangeAnalysis.qll rename to cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/SimpleRangeAnalysis.qll index f5e5b27e080..c881de4c340 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/SimpleRangeAnalysis.qll +++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/SimpleRangeAnalysis.qll @@ -5,11 +5,11 @@ private import cpp private import semmle.code.cpp.ir.IR -private import experimental.semmle.code.cpp.semantic.SemanticBound -private import experimental.semmle.code.cpp.semantic.SemanticExprSpecific -private import RangeAnalysisImpl +private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticBound +private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticExprSpecific +private import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeAnalysis +private import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeAnalysisImpl private import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils - /** * Gets the lower bound of the expression. * diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/Semantic.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/Semantic.qll similarity index 100% rename from cpp/ql/lib/experimental/semmle/code/cpp/semantic/Semantic.qll rename to cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/Semantic.qll diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticBound.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/SemanticBound.qll similarity index 100% rename from cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticBound.qll rename to cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/SemanticBound.qll diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticCFG.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/SemanticCFG.qll similarity index 100% rename from cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticCFG.qll rename to cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/SemanticCFG.qll diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExpr.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/SemanticExpr.qll similarity index 100% rename from cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExpr.qll rename to cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/SemanticExpr.qll diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/SemanticExprSpecific.qll similarity index 99% rename from cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll rename to cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/SemanticExprSpecific.qll index 0b3249a3013..6ac6081c558 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll +++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/SemanticExprSpecific.qll @@ -5,7 +5,7 @@ private import cpp as Cpp private import semmle.code.cpp.ir.IR as IR private import Semantic -private import experimental.semmle.code.cpp.rangeanalysis.Bound as IRBound +private import analysis.Bound as IRBound private import semmle.code.cpp.controlflow.IRGuards as IRGuards private import semmle.code.cpp.ir.ValueNumbering diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticGuard.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/SemanticGuard.qll similarity index 100% rename from cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticGuard.qll rename to cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/SemanticGuard.qll diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticLocation.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/SemanticLocation.qll similarity index 100% rename from cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticLocation.qll rename to cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/SemanticLocation.qll diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticOpcode.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/SemanticOpcode.qll similarity index 100% rename from cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticOpcode.qll rename to cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/SemanticOpcode.qll diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticSSA.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/SemanticSSA.qll similarity index 100% rename from cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticSSA.qll rename to cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/SemanticSSA.qll diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticType.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/SemanticType.qll similarity index 100% rename from cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticType.qll rename to cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/SemanticType.qll diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticTypeSpecific.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/SemanticTypeSpecific.qll similarity index 100% rename from cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticTypeSpecific.qll rename to cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/SemanticTypeSpecific.qll diff --git a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/Bound.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/Bound.qll new file mode 100644 index 00000000000..abff447ca87 --- /dev/null +++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/Bound.qll @@ -0,0 +1,86 @@ +import cpp +private import semmle.code.cpp.ir.IR +private import semmle.code.cpp.ir.ValueNumbering + +private newtype TBound = + TBoundZero() or + TBoundValueNumber(ValueNumber vn) { + exists(Instruction i | + vn.getAnInstruction() = i and + ( + i.getResultIRType() instanceof IRIntegerType or + i.getResultIRType() instanceof IRAddressType + ) and + not vn.getAnInstruction() instanceof ConstantInstruction + | + i instanceof PhiInstruction + or + i instanceof InitializeParameterInstruction + or + i instanceof CallInstruction + or + i instanceof VariableAddressInstruction + or + i instanceof FieldAddressInstruction + or + i.(LoadInstruction).getSourceAddress() instanceof VariableAddressInstruction + or + i.(LoadInstruction).getSourceAddress() instanceof FieldAddressInstruction + or + i.getAUse() instanceof ArgumentOperand + or + i instanceof PointerArithmeticInstruction + or + i.getAUse() instanceof AddressOperand + ) + } + +/** + * A bound that may be inferred for an expression plus/minus an integer delta. + */ +abstract class Bound extends TBound { + abstract string toString(); + + /** Gets an expression that equals this bound plus `delta`. */ + abstract Instruction getInstruction(int delta); + + /** Gets an expression that equals this bound. */ + Instruction getInstruction() { result = getInstruction(0) } + + abstract Location getLocation(); +} + +/** + * The bound that corresponds to the integer 0. This is used to represent all + * integer bounds as bounds are always accompanied by an added integer delta. + */ +class ZeroBound extends Bound, TBoundZero { + override string toString() { result = "0" } + + override Instruction getInstruction(int delta) { + result.(ConstantValueInstruction).getValue().toInt() = delta + } + + override Location getLocation() { result instanceof UnknownDefaultLocation } +} + +/** + * A bound corresponding to the value of an `Instruction`. + */ +class ValueNumberBound extends Bound, TBoundValueNumber { + ValueNumber vn; + + ValueNumberBound() { this = TBoundValueNumber(vn) } + + /** Gets an `Instruction` that equals this bound. */ + override Instruction getInstruction(int delta) { + this = TBoundValueNumber(valueNumber(result)) and delta = 0 + } + + override string toString() { result = "ValueNumberBound" } + + override Location getLocation() { result = vn.getLocation() } + + /** Gets the value number that equals this bound. */ + ValueNumber getValueNumber() { result = vn } +} diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/ConstantAnalysis.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/ConstantAnalysis.qll similarity index 91% rename from cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/ConstantAnalysis.qll rename to cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/ConstantAnalysis.qll index 2cfa99ae30a..c01b64e73d6 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/ConstantAnalysis.qll +++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/ConstantAnalysis.qll @@ -2,7 +2,7 @@ * Simple constant analysis using the Semantic interface. */ -private import experimental.semmle.code.cpp.semantic.Semantic +private import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic private import ConstantAnalysisSpecific as Specific /** An expression that always has the same integer value. */ diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/ConstantAnalysisSpecific.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/ConstantAnalysisSpecific.qll similarity index 71% rename from cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/ConstantAnalysisSpecific.qll rename to cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/ConstantAnalysisSpecific.qll index cd7f96d6557..4713a10ebfc 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/ConstantAnalysisSpecific.qll +++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/ConstantAnalysisSpecific.qll @@ -2,7 +2,7 @@ * C++-specific implementation of constant analysis. */ -private import experimental.semmle.code.cpp.semantic.Semantic +private import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic /** * Gets the constant integer value of the specified expression, if any. diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/FloatDelta.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/FloatDelta.qll similarity index 100% rename from cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/FloatDelta.qll rename to cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/FloatDelta.qll diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/IntDelta.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/IntDelta.qll similarity index 100% rename from cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/IntDelta.qll rename to cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/IntDelta.qll diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/ModulusAnalysis.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/ModulusAnalysis.qll similarity index 99% rename from cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/ModulusAnalysis.qll rename to cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/ModulusAnalysis.qll index acb5436e9c9..a05e948a2b0 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/ModulusAnalysis.qll +++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/ModulusAnalysis.qll @@ -11,7 +11,7 @@ */ private import ModulusAnalysisSpecific::Private -private import experimental.semmle.code.cpp.semantic.Semantic +private import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic private import ConstantAnalysis private import RangeUtils private import RangeAnalysisStage diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/ModulusAnalysisSpecific.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/ModulusAnalysisSpecific.qll similarity index 62% rename from cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/ModulusAnalysisSpecific.qll rename to cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/ModulusAnalysisSpecific.qll index a2fb5598e0e..c0e7287e23b 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/ModulusAnalysisSpecific.qll +++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/ModulusAnalysisSpecific.qll @@ -2,7 +2,7 @@ * C++-specific implementation of modulus analysis. */ module Private { - private import experimental.semmle.code.cpp.semantic.Semantic + private import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic predicate ignoreExprModulus(SemExpr e) { none() } } diff --git a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysis.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysis.qll new file mode 100644 index 00000000000..013068393da --- /dev/null +++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysis.qll @@ -0,0 +1,3 @@ +import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticBound +private import RangeAnalysisImpl as Impl +import Impl::Public \ No newline at end of file diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisImpl.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisImpl.qll similarity index 91% rename from cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisImpl.qll rename to cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisImpl.qll index 272cc875cc1..2026a21c652 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisImpl.qll @@ -1,10 +1,10 @@ private import RangeAnalysisStage private import RangeAnalysisSpecific -private import experimental.semmle.code.cpp.semantic.analysis.FloatDelta +private import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.FloatDelta private import RangeUtils -private import experimental.semmle.code.cpp.semantic.SemanticBound as SemanticBound -private import experimental.semmle.code.cpp.semantic.SemanticLocation -private import experimental.semmle.code.cpp.semantic.SemanticSSA +private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticBound as SemanticBound +private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticLocation +private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticSSA module ConstantBounds implements BoundSig { class SemBound instanceof SemanticBound::SemBound { diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisSpecific.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisSpecific.qll similarity index 95% rename from cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisSpecific.qll rename to cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisSpecific.qll index 34d5bca116b..2ddc20c8a33 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisSpecific.qll +++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisSpecific.qll @@ -2,9 +2,9 @@ * C++-specific implementation of range analysis. */ -private import experimental.semmle.code.cpp.semantic.Semantic +private import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic private import RangeAnalysisStage -private import experimental.semmle.code.cpp.semantic.analysis.FloatDelta +private import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.FloatDelta module CppLangImpl implements LangSig { /** diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisSpecific2.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisSpecific2.qll similarity index 95% rename from cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisSpecific2.qll rename to cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisSpecific2.qll index 1ea72e355b9..e4955e0ee8b 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisSpecific2.qll +++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisSpecific2.qll @@ -2,10 +2,10 @@ * C++-specific implementation of range analysis. */ -private import experimental.semmle.code.cpp.semantic.Semantic +private import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic private import RangeAnalysisStage -private import experimental.semmle.code.cpp.semantic.analysis.FloatDelta -private import experimental.semmle.code.cpp.semantic.analysis.IntDelta +private import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.FloatDelta +private import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.IntDelta private import RangeAnalysisImpl private import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisStage.qll similarity index 97% rename from cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll rename to cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisStage.qll index 65ac5a3b62a..2554f999c8b 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll +++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisStage.qll @@ -65,32 +65,29 @@ private import RangeUtils as Utils private import SignAnalysisCommon -private import experimental.semmle.code.cpp.semantic.analysis.ModulusAnalysis -import experimental.semmle.code.cpp.semantic.SemanticExpr -import experimental.semmle.code.cpp.semantic.SemanticSSA -import experimental.semmle.code.cpp.semantic.SemanticGuard -import experimental.semmle.code.cpp.semantic.SemanticCFG -import experimental.semmle.code.cpp.semantic.SemanticType -import experimental.semmle.code.cpp.semantic.SemanticOpcode +private import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.ModulusAnalysis +import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticExpr +import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticSSA +import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticGuard +import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticCFG +import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticType +import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticOpcode private import ConstantAnalysis private import Sign -import experimental.semmle.code.cpp.semantic.SemanticLocation +import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticLocation /** * Holds if `typ` is a small integral type with the given lower and upper bounds. */ -private predicate typeBound(SemIntegerType typ, int lowerbound, int upperbound) { +private predicate typeBound(SemIntegerType typ, float lowerbound, float upperbound) { exists(int bitSize | bitSize = typ.getByteSize() * 8 | - bitSize < 32 and - ( - if typ.isSigned() - then ( - upperbound = 1.bitShiftLeft(bitSize - 1) - 1 and - lowerbound = -upperbound - 1 - ) else ( - lowerbound = 0 and - upperbound = 1.bitShiftLeft(bitSize) - 1 - ) + if typ.isSigned() + then ( + upperbound = 2.pow(bitSize - 1) - 1 and + lowerbound = -upperbound - 1 + ) else ( + lowerbound = 0 and + upperbound = 2.pow(bitSize) - 1 ) ) } @@ -295,10 +292,10 @@ module RangeStage< } /** Gets the lower bound of the resulting type. */ - int getLowerBound() { typeBound(getTrackedType(this), result, _) } + float getLowerBound() { typeBound(getTrackedType(this), result, _) } /** Gets the upper bound of the resulting type. */ - int getUpperBound() { typeBound(getTrackedType(this), _, result) } + float getUpperBound() { typeBound(getTrackedType(this), _, result) } } private module SignAnalysisInstantiated = SignAnalysis; // TODO: will this cause reevaluation if it's instantiated with the same DeltaSig and UtilParam multiple times? diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeUtils.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeUtils.qll similarity index 98% rename from cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeUtils.qll rename to cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeUtils.qll index d9cc2cc9a71..7eeed5d7975 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeUtils.qll +++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeUtils.qll @@ -2,7 +2,7 @@ * Provides utility predicates for range analysis. */ -private import experimental.semmle.code.cpp.semantic.Semantic +private import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic private import RangeAnalysisSpecific private import RangeAnalysisStage as Range private import ConstantAnalysis diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/Sign.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/Sign.qll similarity index 98% rename from cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/Sign.qll rename to cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/Sign.qll index 692a812911c..814691d9bcd 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/Sign.qll +++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/Sign.qll @@ -1,4 +1,4 @@ -private import experimental.semmle.code.cpp.semantic.Semantic +private import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic newtype TSign = TNeg() or diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/SignAnalysisCommon.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/SignAnalysisCommon.qll similarity index 99% rename from cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/SignAnalysisCommon.qll rename to cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/SignAnalysisCommon.qll index ec3427558d4..9abcdc842ab 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/SignAnalysisCommon.qll +++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/SignAnalysisCommon.qll @@ -8,7 +8,7 @@ private import RangeAnalysisStage private import SignAnalysisSpecific as Specific -private import experimental.semmle.code.cpp.semantic.Semantic +private import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic private import ConstantAnalysis private import RangeUtils private import Sign diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/SignAnalysisSpecific.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/SignAnalysisSpecific.qll similarity index 88% rename from cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/SignAnalysisSpecific.qll rename to cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/SignAnalysisSpecific.qll index 0f482790d4d..8bdb9dbc6b9 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/SignAnalysisSpecific.qll +++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/SignAnalysisSpecific.qll @@ -2,7 +2,7 @@ * Provides C++-specific definitions for use in sign analysis. */ -private import experimental.semmle.code.cpp.semantic.Semantic +private import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic /** * Workaround to allow certain expressions to have a negative sign, even if the type of the diff --git a/cpp/ql/lib/semmlecode.cpp.dbscheme b/cpp/ql/lib/semmlecode.cpp.dbscheme index a5bb28ed29f..19887dbd333 100644 --- a/cpp/ql/lib/semmlecode.cpp.dbscheme +++ b/cpp/ql/lib/semmlecode.cpp.dbscheme @@ -1820,24 +1820,26 @@ new_array_allocated_type( /** * The field being initialized by an initializer expression within an aggregate - * initializer for a class/struct/union. + * initializer for a class/struct/union. Position is used to sort repeated initializers. */ -#keyset[aggregate, field] +#keyset[aggregate, position] aggregate_field_init( int aggregate: @aggregateliteral ref, int initializer: @expr ref, - int field: @membervariable ref + int field: @membervariable ref, + int position: int ref ); /** * The index of the element being initialized by an initializer expression - * within an aggregate initializer for an array. + * within an aggregate initializer for an array. Position is used to sort repeated initializers. */ -#keyset[aggregate, element_index] +#keyset[aggregate, position] aggregate_array_init( int aggregate: @aggregateliteral ref, int initializer: @expr ref, - int element_index: int ref + int element_index: int ref, + int position: int ref ); @ctorinit = @ctordirectinit diff --git a/cpp/ql/lib/semmlecode.cpp.dbscheme.stats b/cpp/ql/lib/semmlecode.cpp.dbscheme.stats index 93bbbcd82d3..24253b0aeb5 100644 --- a/cpp/ql/lib/semmlecode.cpp.dbscheme.stats +++ b/cpp/ql/lib/semmlecode.cpp.dbscheme.stats @@ -2,7 +2,7 @@ @compilation - 9947 + 9948 @externalDataElement @@ -18,303 +18,303 @@ @location_stmt - 3813507 + 3813678 @location_default - 29670824 + 29769315 @location_expr - 13165934 + 13166528 @diagnostic - 72033 + 72036 @file - 122193 + 123102 @folder - 15274 + 15387 @macro_expansion - 33908240 + 33954616 @other_macro_reference - 839618 + 857985 @function - 4634561 + 4638253 @fun_decl - 4995588 + 5001965 @var_decl - 8393866 + 8416189 @type_decl - 3242758 + 3241228 @namespace_decl - 308849 + 308863 @using - 369357 + 369307 @static_assert - 130539 + 130544 @parameter - 6539671 + 6569654 @membervariable - 1052936 + 1052983 @globalvariable - 301270 + 301276 @localvariable - 581183 + 581207 @enumconstant - 241267 + 241278 @errortype - 462 + 466 @unknowntype - 462 + 466 @void - 462 + 466 @boolean - 462 + 466 @char - 462 + 466 @unsigned_char - 462 + 466 @signed_char - 462 + 466 @short - 462 + 466 @unsigned_short - 462 + 466 @signed_short - 462 + 466 @int - 462 + 466 @unsigned_int - 462 + 466 @signed_int - 462 + 466 @long - 462 + 466 @unsigned_long - 462 + 466 @signed_long - 462 + 466 @long_long - 462 + 466 @unsigned_long_long - 462 + 466 @signed_long_long - 462 + 466 @float - 462 + 466 @double - 462 + 466 @long_double - 462 + 466 @complex_float - 462 + 466 @complex_double - 462 + 466 @complex_long_double - 462 + 466 @imaginary_float - 462 + 466 @imaginary_double - 462 + 466 @imaginary_long_double - 462 + 466 @wchar_t - 462 + 466 @decltype_nullptr - 462 + 466 @int128 - 462 + 466 @unsigned_int128 - 462 + 466 @signed_int128 - 462 + 466 @float128 - 462 + 466 @complex_float128 - 462 + 466 @decimal32 - 462 + 466 @decimal64 - 462 + 466 @decimal128 - 462 + 466 @char16_t - 462 + 466 @char32_t - 462 + 466 @std_float32 - 462 + 466 @float32x - 462 + 466 @std_float64 - 462 + 466 @float64x - 462 + 466 @std_float128 - 462 + 466 @float128x - 462 + 466 @char8_t - 462 + 466 @float16 - 462 + 466 @complex_float16 - 462 + 466 @pointer - 565145 + 567483 @reference - 1747594 + 1747669 @type_with_specifiers - 1007634 + 1009066 @array - 109233 + 110046 @routineptr - 635444 + 635462 @rvalue_reference - 613466 + 613493 @gnu_vector @@ -330,47 +330,47 @@ @decltype - 28696 + 27045 @usertype - 5233032 + 5225787 @mangledname - 4996504 + 4988979 @type_mention - 4022409 + 4022590 @routinetype - 547131 + 547147 @ptrtomember - 37491 + 37770 @specifier - 24531 + 24713 @gnuattribute - 680858 + 685456 @stdattribute - 493040 + 492036 @alignas - 9719 + 9792 @declspec - 243696 + 243716 @msattribute @@ -378,15 +378,15 @@ @attribute_arg_token - 38879 + 39168 @attribute_arg_type - 462 + 466 @attribute_arg_constant_expr - 367506 + 370239 @attribute_arg_empty @@ -398,63 +398,63 @@ @derivation - 368247 + 368257 @frienddecl - 716101 + 716121 @comment - 8773481 + 8774227 @namespace - 12497 + 12123 @specialnamequalifyingelement - 462 + 466 @namequalifier - 1533160 + 1533233 @value - 10758747 + 10759232 @initialiser - 1699633 + 1699706 @lambdacapture - 27771 + 27977 @errorexpr - 46890 + 46892 @address_of - 438806 + 438815 @reference_to - 1592422 + 1592467 @indirect - 292157 + 292170 @ref_indirect - 1938618 + 1938672 @array_to_pointer - 1428562 + 1428626 @vacuous_destructor_call @@ -462,55 +462,55 @@ @parexpr - 3581772 + 3581934 @arithnegexpr - 650874 + 650875 @complementexpr - 27791 + 27792 @notexpr - 275965 + 275977 @postincrexpr - 61942 + 61944 @postdecrexpr - 41968 + 41970 @preincrexpr - 70456 + 70459 @predecrexpr - 26164 + 26165 @conditionalexpr - 656192 + 656221 @addexpr - 397731 + 397749 @subexpr - 340216 + 340231 @mulexpr - 305846 + 305860 @divexpr - 132945 + 132951 @remexpr @@ -518,75 +518,75 @@ @paddexpr - 86517 + 86521 @psubexpr - 49816 + 49819 @pdiffexpr - 35456 + 35459 @lshiftexpr - 565360 + 565385 @rshiftexpr - 140605 + 140612 @andexpr - 488242 + 488264 @orexpr - 145223 + 145229 @xorexpr - 54084 + 54087 @eqexpr - 469864 + 469885 @neexpr - 301187 + 301200 @gtexpr - 99050 + 99787 @ltexpr - 104605 + 101652 @geexpr - 59150 + 59152 @leexpr - 212171 + 212181 @assignexpr - 935392 + 935434 @assignaddexpr - 68222 + 68229 @assignsubexpr - 11180 + 11181 @assignmulexpr - 7146 + 7147 @assigndivexpr @@ -610,11 +610,11 @@ @assignorexpr - 23830 + 23831 @assignxorexpr - 21807 + 21808 @assignpaddexpr @@ -622,23 +622,23 @@ @andlogicalexpr - 249535 + 249546 @orlogicalexpr - 864670 + 864709 @commaexpr - 124044 + 124055 @subscriptexpr - 367589 + 367604 @callexpr - 303632 + 302160 @vastartexpr @@ -646,7 +646,7 @@ @vaendexpr - 2777 + 2797 @vacopyexpr @@ -654,15 +654,15 @@ @varaccess - 6019061 + 6019333 @thisaccess - 1126986 + 1127035 @new_expr - 47667 + 47668 @delete_expr @@ -670,11 +670,11 @@ @throw_expr - 21694 + 21695 @condition_decl - 42425 + 42427 @braced_init_list @@ -682,27 +682,27 @@ @type_id - 36482 + 36483 @runtime_sizeof - 295343 + 295357 @runtime_alignof - 49890 + 49891 @sizeof_pack - 5554 + 5595 @routineexpr - 2917109 + 2917246 @type_operand - 1126879 + 1126930 @isemptyexpr @@ -710,15 +710,15 @@ @ispodexpr - 633 + 634 @hastrivialdestructor - 462 + 466 @literal - 4406609 + 4406808 @aggregateliteral @@ -734,15 +734,15 @@ @ctordirectinit - 112975 + 112978 @ctorvirtualinit - 6512 + 6513 @ctorfieldinit - 201112 + 201118 @ctordelegatinginit @@ -750,7 +750,7 @@ @dtordirectdestruct - 41774 + 41776 @dtorvirtualdestruct @@ -758,19 +758,19 @@ @dtorfielddestruct - 41704 + 41705 @static_cast - 210924 + 210934 @reinterpret_cast - 30749 + 30752 @const_cast - 35247 + 35250 @dynamic_cast @@ -778,27 +778,27 @@ @c_style_cast - 4209396 + 4209495 @lambdaexpr - 21291 + 21449 @param_ref - 245644 + 245656 @istrivialexpr - 925 + 932 @istriviallycopyableexpr - 3702 + 3730 @isconstructibleexpr - 462 + 466 @isfinalexpr @@ -806,15 +806,15 @@ @noexceptexpr - 25736 + 25737 @builtinaddressof - 13301 + 13302 @temp_init - 826635 + 826674 @assume @@ -870,7 +870,7 @@ @assignpsubexpr - 1150 + 1151 @virtfunptrexpr @@ -882,11 +882,11 @@ @expr_stmt - 94230 + 94234 @offsetofexpr - 19959 + 19960 @hasassignexpr @@ -958,7 +958,7 @@ @typescompexpr - 562840 + 562865 @intaddrexpr @@ -966,7 +966,7 @@ @uuidof - 20119 + 20120 @foldexpr @@ -1022,7 +1022,7 @@ @isnothrowconstructibleexpr - 14433 + 14434 @hasfinalizerexpr @@ -1222,83 +1222,83 @@ @stmt_expr - 1483544 + 1483611 @stmt_if - 724702 + 724735 @stmt_while - 30109 + 30110 @stmt_label - 53053 + 53056 @stmt_return - 1285346 + 1284647 @stmt_block - 1423277 + 1423603 @stmt_end_test_while - 148625 + 148632 @stmt_for - 61453 + 61456 @stmt_switch_case - 209633 + 209643 @stmt_switch - 20752 + 20753 @stmt_try_block - 46919 + 46921 @stmt_decl - 606527 + 606553 @stmt_empty - 193316 + 193324 @stmt_continue - 22524 + 22525 @stmt_break - 102326 + 102331 @stmt_range_based_for - 8331 + 8393 @stmt_handler - 65311 + 65314 @stmt_constexpr_if - 52504 + 52508 @stmt_goto - 110506 + 110511 @stmt_asm - 109799 + 109804 @stmt_microsoft_try @@ -1314,7 +1314,7 @@ @stmt_assigned_goto - 9060 + 9061 @stmt_co_return @@ -1322,51 +1322,51 @@ @ppd_if - 661419 + 666338 @ppd_ifdef - 261049 + 262991 @ppd_ifndef - 264289 + 266255 @ppd_elif - 24994 + 25180 @ppd_else - 207358 + 208900 @ppd_endif - 1186758 + 1195584 @ppd_plain_include - 308723 + 311019 @ppd_define - 2433092 + 2433298 @ppd_undef - 257809 + 258328 @ppd_pragma - 311993 + 312020 @ppd_include_next - 1851 + 1865 @ppd_line - 27756 + 27757 @ppd_error @@ -1412,11 +1412,11 @@ compilations - 9947 + 9948 id - 9947 + 9948 cwd @@ -1434,7 +1434,7 @@ 1 2 - 9947 + 9948 @@ -1460,7 +1460,7 @@ compilation_args - 651465 + 651494 id @@ -1472,7 +1472,7 @@ arg - 34403 + 34405 @@ -1496,7 +1496,7 @@ 126 127 - 3861 + 3862 127 @@ -1710,7 +1710,7 @@ 1 2 - 32343 + 32344 2 @@ -1731,7 +1731,7 @@ 1 2 - 33199 + 33200 2 @@ -1746,7 +1746,7 @@ compilation_compiling_files - 11526 + 11527 id @@ -1874,7 +1874,7 @@ 1 2 - 1754 + 1755 2 @@ -1910,7 +1910,7 @@ 1 2 - 1754 + 1755 2 @@ -1972,7 +1972,7 @@ 1 2 - 9173 + 9174 2 @@ -1992,7 +1992,7 @@ compilation_time - 46107 + 46109 id @@ -2008,7 +2008,7 @@ seconds - 10290 + 10051 @@ -2089,43 +2089,53 @@ 3 4 - 598 + 678 4 5 - 398 + 319 - 5 + 6 8 - 159 + 119 8 - 9 - 79 + 10 + 119 10 11 - 279 + 79 - 12 - 17 + 11 + 12 159 + + 13 + 17 + 119 + 17 - 22 + 21 159 - 27 - 89 + 21 + 44 159 + + 55 + 89 + 79 + @@ -2140,7 +2150,7 @@ 1 2 - 1754 + 1755 2 @@ -2192,42 +2202,37 @@ 3 4 - 1156 + 1236 4 5 - 598 + 518 5 6 - 239 + 159 6 7 - 438 + 558 7 - 8 - 79 - - - 8 9 279 9 - 25 + 24 279 - 25 - 95 - 239 + 24 + 91 + 279 @@ -2283,13 +2288,13 @@ 39 - 125 - 126 + 120 + 121 39 - 133 - 134 + 129 + 130 39 @@ -2306,27 +2311,27 @@ 1 2 - 6102 + 5823 2 3 - 1874 + 2074 3 4 - 1276 + 917 4 6 - 797 + 917 6 40 - 239 + 319 @@ -2342,32 +2347,32 @@ 1 2 - 5344 + 5065 2 3 - 2113 + 1794 3 4 - 1116 + 1236 4 5 - 598 + 757 5 - 9 + 7 877 - 9 - 59 - 239 + 7 + 67 + 319 @@ -2383,12 +2388,12 @@ 1 2 - 10051 + 9892 2 - 4 - 239 + 3 + 159 @@ -2398,11 +2403,11 @@ diagnostic_for - 841590 + 841626 diagnostic - 72033 + 72036 compilation @@ -2433,7 +2438,7 @@ 2 3 - 59653 + 59655 254 @@ -2454,7 +2459,7 @@ 1 2 - 72033 + 72036 @@ -2470,7 +2475,7 @@ 1 2 - 72033 + 72036 @@ -2749,15 +2754,15 @@ compilation_finished - 9947 + 9948 id - 9947 + 9948 cpu_seconds - 8149 + 7838 elapsed_seconds @@ -2775,7 +2780,7 @@ 1 2 - 9947 + 9948 @@ -2791,7 +2796,7 @@ 1 2 - 9947 + 9948 @@ -2807,17 +2812,17 @@ 1 2 - 6881 + 6605 2 3 - 1037 + 853 3 - 16 - 230 + 12 + 380 @@ -2833,12 +2838,12 @@ 1 2 - 7873 + 7354 2 3 - 276 + 484 @@ -2859,11 +2864,6 @@ 2 3 - 11 - - - 3 - 4 23 @@ -2872,43 +2872,43 @@ 11 - 10 - 11 + 7 + 8 + 23 + + + 11 + 12 11 - 12 - 13 + 25 + 26 11 - 30 - 31 + 52 + 53 11 - 61 - 62 + 114 + 115 11 - 111 - 112 + 145 + 146 11 - 157 - 158 + 244 + 245 11 - 230 - 231 - 11 - - - 238 - 239 + 248 + 249 11 @@ -2930,11 +2930,6 @@ 2 3 - 11 - - - 3 - 4 23 @@ -2943,43 +2938,43 @@ 11 - 10 - 11 + 7 + 8 + 23 + + + 11 + 12 11 - 12 - 13 + 25 + 26 11 - 30 - 31 + 51 + 52 11 - 61 - 62 + 102 + 103 11 - 103 - 104 + 107 + 108 11 - 111 - 112 + 172 + 173 11 - 182 - 183 - 11 - - - 208 - 209 + 230 + 231 11 @@ -3206,11 +3201,11 @@ sourceLocationPrefix - 462 + 466 prefix - 462 + 466 @@ -4704,31 +4699,31 @@ locations_default - 29670824 + 29769315 id - 29670824 + 29769315 container - 137467 + 138490 startLine - 2080993 + 2092739 startColumn - 36565 + 36837 endLine - 2083770 + 2096936 endColumn - 47674 + 48028 @@ -4742,7 +4737,7 @@ 1 2 - 29670824 + 29769315 @@ -4758,7 +4753,7 @@ 1 2 - 29670824 + 29769315 @@ -4774,7 +4769,7 @@ 1 2 - 29670824 + 29769315 @@ -4790,7 +4785,7 @@ 1 2 - 29670824 + 29769315 @@ -4806,7 +4801,7 @@ 1 2 - 29670824 + 29769315 @@ -4822,67 +4817,67 @@ 1 2 - 15737 + 15854 2 12 - 10645 + 10724 13 20 - 11571 + 11657 21 36 - 11108 + 11191 36 55 - 11108 + 11191 55 77 - 10645 + 10724 77 102 - 10645 + 10724 102 149 - 10645 + 10724 149 227 - 11108 + 11191 228 350 - 10645 + 10724 - 351 + 352 604 - 10645 + 10724 630 1494 - 10645 + 10724 - 1925 + 1829 2380 - 2314 + 2331 @@ -4898,67 +4893,67 @@ 1 2 - 15737 + 15854 2 9 - 10645 + 10724 9 16 - 11571 + 11657 16 25 - 11108 + 11191 25 40 - 10645 + 10724 40 57 - 10645 + 10724 58 - 73 - 10645 + 72 + 10724 73 103 - 11108 + 11191 106 141 - 11571 + 11657 148 - 226 - 11108 + 225 + 10724 - 226 - 373 - 10645 + 225 + 360 + 10724 - 381 - 1456 - 10645 + 372 + 1255 + 10724 - 1464 - 1614 - 1388 + 1455 + 1569 + 1865 @@ -4974,214 +4969,214 @@ 1 2 - 15737 + 15854 2 4 - 8794 + 8393 4 5 - 7405 + 7927 5 6 - 7405 + 7460 6 8 - 11571 + 11191 8 13 - 12034 + 12123 13 - 18 - 11571 + 17 + 11191 - 18 - 26 - 12034 - - - 26 - 32 - 11108 - - - 32 - 40 - 10645 - - - 40 - 54 - 10645 - - - 54 - 67 - 10645 - - - 67 - 77 - 7868 - - - - - - - container - endLine - - - 12 - - - 1 - 2 - 15737 - - - 2 - 9 - 10645 - - - 9 - 16 - 11571 - - - 16 + 17 25 - 11108 + 11191 25 - 40 - 10645 - - - 40 - 57 - 10645 - - - 58 - 72 - 10645 - - - 72 - 98 - 10645 - - - 101 - 140 - 11571 - - - 140 - 224 - 10645 - - - 224 - 360 - 10645 - - - 364 - 1185 - 10645 - - - 1254 - 1611 - 2314 - - - - - - - container - endColumn - - - 12 - - - 1 - 2 - 15737 - - - 2 - 10 - 11108 - - - 10 - 14 - 10645 - - - 14 - 21 - 11108 - - - 22 31 - 11108 + 12123 31 39 - 12497 + 11191 + + + 39 + 54 + 11191 + + + 54 + 67 + 10724 + + + 67 + 77 + 7927 + + + + + + + container + endLine + + + 12 + + + 1 + 2 + 15854 + + + 2 + 9 + 10724 + + + 9 + 16 + 11657 + + + 16 + 25 + 11191 + + + 25 + 40 + 10724 + + + 40 + 57 + 10724 + + + 58 + 71 + 10724 + + + 72 + 98 + 10724 + + + 101 + 140 + 11657 + + + 140 + 222 + 10724 + + + 223 + 360 + 11191 + + + 372 + 1255 + 10724 + + + 1452 + 1566 + 1865 + + + + + + + container + endColumn + + + 12 + + + 1 + 2 + 15854 + + + 2 + 10 + 11191 + + + 10 + 14 + 10724 + + + 14 + 21 + 11191 + + + 22 + 31 + 11191 + + + 31 + 39 + 12590 39 48 - 11571 + 12123 48 - 55 - 10645 + 56 + 11657 - 55 - 63 - 11108 + 56 + 64 + 12123 - 63 - 70 - 11571 + 64 + 73 + 12123 - 70 - 77 - 12034 + 73 + 78 + 10724 - 77 + 78 90 - 8331 + 6994 @@ -5197,52 +5192,52 @@ 1 2 - 572088 + 583803 2 3 - 312426 + 314750 3 4 - 196250 + 192580 4 6 - 159221 + 161804 6 10 - 186993 + 183720 10 16 - 163387 + 162271 16 25 - 166164 + 167400 25 - 46 - 160610 + 45 + 157141 - 46 - 169 - 156907 + 45 + 160 + 157608 - 170 + 160 298 - 6942 + 11657 @@ -5258,42 +5253,42 @@ 1 2 - 855355 + 870109 2 3 - 275861 + 273716 3 5 - 189307 + 193046 5 8 - 178198 + 173462 8 - 12 - 159684 + 13 + 187917 - 12 - 18 - 163850 + 13 + 20 + 160872 - 18 - 39 - 157370 + 20 + 51 + 159473 - 39 + 51 298 - 101365 + 74141 @@ -5309,47 +5304,47 @@ 1 2 - 601710 + 614112 2 3 - 308261 + 310087 3 4 - 199953 + 198642 4 6 - 181901 + 182322 6 9 - 177736 + 173462 9 13 - 163850 + 162737 13 19 - 171256 + 173928 19 29 - 164313 + 165069 29 52 - 112010 + 112377 @@ -5365,22 +5360,22 @@ 1 2 - 1520939 + 1529919 2 3 - 345752 + 348323 3 5 - 161999 + 161804 5 16 - 52302 + 52691 @@ -5396,52 +5391,52 @@ 1 2 - 576716 + 588466 2 3 - 313352 + 316149 3 4 - 198564 + 195378 4 6 - 165701 + 167866 6 9 - 157833 + 158074 9 14 - 175421 + 170198 14 21 - 173570 + 174394 21 32 - 159684 + 163670 32 - 60 - 156444 + 63 + 157608 - 60 + 64 66 - 3702 + 932 @@ -5457,72 +5452,72 @@ 1 31 - 2777 + 2797 42 85 - 2777 + 2797 86 128 - 2777 + 2797 129 229 - 2777 + 2797 248 292 - 2777 + 2797 293 360 - 2777 + 2797 - 376 - 459 - 2777 + 373 + 456 + 2797 475 - 560 - 2777 + 565 + 2797 565 - 623 - 2777 + 619 + 2797 - 626 - 699 - 2777 + 622 + 689 + 2797 - 699 - 796 - 2777 + 695 + 793 + 2797 820 - 1568 - 2777 + 1563 + 2797 - 1705 - 5647 - 2777 + 1638 + 5626 + 2797 - 15306 - 15307 - 462 + 15295 + 15296 + 466 @@ -5538,67 +5533,67 @@ 1 18 - 2777 + 2797 23 35 - 3239 + 3264 38 43 - 2777 + 2797 44 61 - 2777 + 2797 65 73 - 2777 + 2797 73 84 - 3239 + 3264 84 - 97 - 3239 + 96 + 2797 - 98 + 96 101 - 2314 + 3264 101 105 - 3239 + 3264 - 106 - 111 - 2777 + 107 + 112 + 2797 - 111 - 123 - 2777 + 112 + 126 + 2797 - 127 - 154 - 2777 + 137 + 170 + 2797 - 169 + 195 298 - 1851 + 1398 @@ -5614,72 +5609,72 @@ 1 19 - 2777 + 2797 30 72 - 2777 + 2797 83 122 - 2777 + 2797 122 205 - 2777 + 2797 214 261 - 2777 + 2797 - 264 + 265 322 - 2777 + 2797 - 325 - 380 - 2777 + 322 + 379 + 2797 404 - 436 - 2777 + 430 + 2797 - 454 + 452 474 - 2777 + 2797 - 479 - 514 - 2777 + 478 + 505 + 2797 - 517 - 586 - 2777 + 511 + 583 + 2797 - 587 - 838 - 2777 + 584 + 836 + 2797 - 1116 - 2197 - 2777 + 1104 + 2196 + 2797 - 2387 - 2388 - 462 + 2381 + 2382 + 466 @@ -5695,72 +5690,72 @@ 1 19 - 2777 + 2797 30 72 - 2777 + 2797 83 122 - 2777 + 2797 122 205 - 2777 + 2797 214 261 - 2777 + 2797 - 264 + 265 322 - 2777 + 2797 - 325 + 322 380 - 2777 + 2797 404 - 436 - 2777 + 430 + 2797 - 454 + 452 474 - 2777 + 2797 - 478 - 513 - 2777 + 477 + 504 + 2797 - 520 - 585 - 2777 + 514 + 582 + 2797 - 587 - 837 - 2777 + 584 + 835 + 2797 - 1121 - 2205 - 2777 + 1109 + 2203 + 2797 - 2383 - 2384 - 462 + 2376 + 2377 + 466 @@ -5776,67 +5771,67 @@ 1 7 - 2777 + 2797 7 11 - 3239 + 3264 11 16 - 3239 + 3264 16 22 - 2777 + 2797 22 24 - 2314 + 3264 24 - 27 - 3239 + 28 + 2797 - 28 - 33 - 2777 + 29 + 34 + 3264 - 33 - 40 - 3239 + 34 + 41 + 3264 - 40 - 43 - 2777 + 41 + 46 + 2797 - 43 + 46 49 - 2777 + 1865 49 54 - 2777 + 2797 54 74 - 2777 + 2797 75 86 - 1851 + 1865 @@ -5852,52 +5847,52 @@ 1 2 - 579956 + 594062 2 3 - 306872 + 306823 3 4 - 196250 + 195844 4 6 - 159221 + 159007 6 10 - 186067 + 183254 10 16 - 161536 + 160872 16 25 - 168016 + 169732 25 45 - 157370 + 158074 45 160 - 157370 + 158074 160 298 - 11108 + 11191 @@ -5913,47 +5908,47 @@ 1 2 - 866926 + 885497 2 3 - 265215 + 260193 3 4 - 122193 + 124501 4 6 - 139782 + 140821 6 10 - 192547 + 184653 10 15 - 165239 + 168333 15 26 - 163387 + 163203 26 120 - 156907 + 158074 121 298 - 11571 + 11657 @@ -5969,22 +5964,22 @@ 1 2 - 1513997 + 1527588 2 3 - 343438 + 341329 3 5 - 169404 + 170664 5 10 - 56931 + 57354 @@ -6000,47 +5995,47 @@ 1 2 - 610967 + 625303 2 3 - 299466 + 300295 3 4 - 201804 + 201906 4 6 - 184216 + 183254 6 9 - 174496 + 170198 9 13 - 166627 + 166001 13 19 - 172181 + 174861 19 29 - 160147 + 160872 29 52 - 113862 + 114242 @@ -6056,52 +6051,52 @@ 1 2 - 586436 + 600590 2 3 - 305946 + 306823 3 4 - 196250 + 193979 4 6 - 169404 + 168799 6 9 - 154593 + 155743 9 14 - 171256 + 167866 14 21 - 177273 + 178125 21 32 - 161536 + 163203 32 60 - 157370 + 158074 60 65 - 3702 + 3730 @@ -6117,67 +6112,67 @@ 1 2 - 5091 + 5129 2 8 - 3702 + 3730 9 186 - 3702 + 3730 - 196 + 193 295 - 3702 + 3730 297 - 498 - 3702 + 495 + 3730 503 - 554 - 3702 + 555 + 3730 - 563 + 561 634 - 3702 + 3730 640 - 762 - 3702 + 758 + 4196 - 765 - 871 - 3702 + 768 + 877 + 3730 - 879 - 1081 - 3702 + 877 + 1076 + 3730 - 1083 - 1287 - 3702 + 1193 + 1290 + 3730 - 1311 - 1591 - 3702 + 1295 + 1686 + 3730 - 1689 - 2419 - 1851 + 1875 + 2418 + 1398 @@ -6193,67 +6188,67 @@ 1 2 - 5554 + 5595 2 - 6 - 3702 + 5 + 3730 - 6 + 5 65 - 3702 + 3730 70 100 - 3702 + 3730 100 111 - 3702 + 3730 112 122 - 3702 + 3730 122 134 - 3702 + 3730 139 152 - 3702 + 3730 152 160 - 3702 + 3730 160 171 - 3702 + 3730 171 175 - 3702 + 3730 176 192 - 3702 + 3730 207 298 - 1388 + 1398 @@ -6269,67 +6264,67 @@ 1 2 - 5554 + 5595 2 8 - 3702 + 3730 9 - 106 - 3702 + 105 + 3730 155 241 - 3702 + 3730 253 - 335 - 3702 + 336 + 3730 - 340 + 339 426 - 3702 + 3730 - 437 + 435 488 - 3702 + 3730 489 - 574 - 3702 + 572 + 3730 - 576 - 627 - 3702 + 573 + 623 + 3730 - 630 - 698 - 3702 + 628 + 696 + 4196 - 698 - 815 - 3702 + 701 + 816 + 3730 - 816 - 993 - 3702 + 836 + 1095 + 3730 - 1106 + 1163 1174 - 1388 + 932 @@ -6345,67 +6340,67 @@ 1 2 - 6017 + 6061 2 4 - 3702 + 3730 4 8 - 4165 + 4196 8 15 - 3702 + 3730 15 23 - 3702 + 3730 23 29 - 3702 + 3730 29 35 - 4165 + 4196 35 39 - 3239 + 3264 39 42 - 3702 + 3730 42 44 - 2777 + 2797 44 46 - 3702 + 3730 46 49 - 3702 + 3730 49 53 - 1388 + 1398 @@ -6421,67 +6416,67 @@ 1 2 - 5554 + 5595 2 8 - 3702 + 3730 9 156 - 3702 + 3730 159 240 - 3702 + 3730 251 - 334 - 3702 + 335 + 3730 - 342 + 341 430 - 3702 + 3730 - 435 + 433 490 - 3702 + 3730 490 - 575 - 3702 + 573 + 3730 - 575 - 626 - 3702 + 573 + 622 + 3730 - 630 - 701 - 3702 + 628 + 698 + 3730 - 701 - 811 - 3702 + 700 + 810 + 3730 - 813 - 992 - 3702 + 811 + 987 + 3730 - 1108 - 1181 - 1388 + 1096 + 1180 + 1398 @@ -6491,19 +6486,19 @@ locations_stmt - 3813507 + 3813678 id - 3813507 + 3813678 container - 3082 + 3083 startLine - 199837 + 199846 startColumn @@ -6511,7 +6506,7 @@ endLine - 194103 + 194112 endColumn @@ -6529,7 +6524,7 @@ 1 2 - 3813507 + 3813678 @@ -6545,7 +6540,7 @@ 1 2 - 3813507 + 3813678 @@ -6561,7 +6556,7 @@ 1 2 - 3813507 + 3813678 @@ -6577,7 +6572,7 @@ 1 2 - 3813507 + 3813678 @@ -6593,7 +6588,7 @@ 1 2 - 3813507 + 3813678 @@ -6994,37 +6989,37 @@ 1 2 - 21539 + 21540 2 3 - 15291 + 15292 3 4 - 12475 + 12476 4 6 - 14448 + 14449 6 8 - 12516 + 12517 8 11 - 16709 + 16710 11 16 - 17264 + 17265 16 @@ -7034,22 +7029,22 @@ 22 29 - 16976 + 16977 29 37 - 17367 + 17368 37 45 - 15085 + 15086 45 56 - 16175 + 16176 56 @@ -7070,7 +7065,7 @@ 1 2 - 22300 + 22301 2 @@ -7095,27 +7090,27 @@ 8 11 - 17572 + 17573 11 16 - 16360 + 16361 16 22 - 16216 + 16217 22 29 - 16956 + 16957 29 36 - 15990 + 15991 36 @@ -7125,7 +7120,7 @@ 44 54 - 15640 + 15641 54 @@ -7146,22 +7141,22 @@ 1 2 - 26821 + 26823 2 3 - 20840 + 20841 3 4 - 16812 + 16813 4 5 - 16072 + 16073 5 @@ -7171,22 +7166,22 @@ 6 7 - 19854 + 19855 7 8 - 22752 + 22753 8 9 - 20388 + 20389 9 10 - 15003 + 15004 10 @@ -7212,12 +7207,12 @@ 1 2 - 34590 + 34592 2 3 - 25794 + 25795 3 @@ -7227,7 +7222,7 @@ 4 5 - 16216 + 16217 5 @@ -7237,12 +7232,12 @@ 6 7 - 12023 + 12024 7 8 - 10173 + 10174 8 @@ -7252,7 +7247,7 @@ 9 10 - 10728 + 10729 10 @@ -7262,12 +7257,12 @@ 11 12 - 10173 + 10174 12 14 - 15784 + 15785 14 @@ -7288,27 +7283,27 @@ 1 2 - 22135 + 22136 2 3 - 16195 + 16196 3 4 - 12948 + 12949 4 6 - 16072 + 16073 6 8 - 14695 + 14696 8 @@ -7318,32 +7313,32 @@ 10 14 - 18292 + 18293 14 18 - 17017 + 17018 18 22 - 17572 + 17573 22 26 - 18497 + 18498 26 30 - 16380 + 16381 30 36 - 15229 + 15230 36 @@ -7734,12 +7729,12 @@ 1 2 - 17408 + 17409 2 3 - 14407 + 14408 3 @@ -7749,7 +7744,7 @@ 4 6 - 15599 + 15600 6 @@ -7759,12 +7754,12 @@ 8 11 - 15455 + 15456 11 15 - 14633 + 14634 15 @@ -7774,7 +7769,7 @@ 21 27 - 15414 + 15415 27 @@ -7784,17 +7779,17 @@ 34 42 - 15743 + 15744 42 52 - 16010 + 16011 52 130 - 14407 + 14408 @@ -7810,7 +7805,7 @@ 1 2 - 24951 + 24952 2 @@ -7820,47 +7815,47 @@ 3 4 - 12763 + 12764 4 6 - 15661 + 15662 6 8 - 15003 + 15004 8 11 - 15887 + 15888 11 16 - 17449 + 17450 16 20 - 14592 + 14593 20 26 - 17161 + 17162 26 32 - 16257 + 16258 32 39 - 14859 + 14860 39 @@ -7881,22 +7876,22 @@ 1 2 - 32473 + 32475 2 3 - 23759 + 23760 3 4 - 18456 + 18457 4 5 - 15147 + 15148 5 @@ -7911,32 +7906,32 @@ 7 8 - 11735 + 11736 8 9 - 10913 + 10914 9 10 - 10173 + 10174 10 12 - 17963 + 17964 12 15 - 17716 + 17717 15 100 - 10214 + 10215 @@ -7952,12 +7947,12 @@ 1 2 - 24951 + 24952 2 3 - 20388 + 20389 3 @@ -7967,7 +7962,7 @@ 4 5 - 17798 + 17799 5 @@ -7977,27 +7972,27 @@ 6 7 - 20429 + 20430 7 8 - 22423 + 22424 8 9 - 18744 + 18745 9 10 - 12927 + 12928 10 12 - 15024 + 15025 12 @@ -8018,12 +8013,12 @@ 1 2 - 24704 + 24705 2 3 - 16627 + 16628 3 @@ -8033,12 +8028,12 @@ 4 6 - 17819 + 17820 6 8 - 15332 + 15333 8 @@ -8048,32 +8043,32 @@ 10 13 - 14407 + 14408 13 16 - 15024 + 15025 16 19 - 14654 + 14655 19 22 - 14037 + 14038 22 26 - 17120 + 17121 26 31 - 15332 + 15333 31 @@ -8473,11 +8468,11 @@ locations_expr - 13165934 + 13166528 id - 13165934 + 13166528 container @@ -8485,7 +8480,7 @@ startLine - 191904 + 191913 startColumn @@ -8493,7 +8488,7 @@ endLine - 191883 + 191892 endColumn @@ -8511,7 +8506,7 @@ 1 2 - 13165934 + 13166528 @@ -8527,7 +8522,7 @@ 1 2 - 13165934 + 13166528 @@ -8543,7 +8538,7 @@ 1 2 - 13165934 + 13166528 @@ -8559,7 +8554,7 @@ 1 2 - 13165934 + 13166528 @@ -8575,7 +8570,7 @@ 1 2 - 13165934 + 13166528 @@ -8991,32 +8986,32 @@ 1 5 - 16113 + 16114 5 9 - 16483 + 16484 9 15 - 16031 + 16032 15 23 - 15106 + 15107 23 32 - 15147 + 15148 32 44 - 15003 + 15004 44 @@ -9026,17 +9021,17 @@ 60 80 - 14818 + 14819 80 103 - 14633 + 14634 103 130 - 14777 + 14778 130 @@ -9067,12 +9062,12 @@ 1 2 - 23512 + 23513 2 3 - 15620 + 15621 3 @@ -9082,27 +9077,27 @@ 4 6 - 16360 + 16361 6 8 - 13626 + 13627 8 11 - 16442 + 16443 11 16 - 17346 + 17347 16 21 - 16442 + 16443 21 @@ -9112,12 +9107,12 @@ 28 35 - 15805 + 15806 35 43 - 15846 + 15847 43 @@ -9138,12 +9133,12 @@ 1 4 - 15969 + 15970 4 7 - 17531 + 17532 7 @@ -9153,47 +9148,47 @@ 11 16 - 17408 + 17409 16 21 - 17511 + 17512 21 26 - 15065 + 15066 26 31 - 16175 + 16176 31 36 - 17716 + 17717 36 40 - 15702 + 15703 40 44 - 16298 + 16299 44 49 - 16894 + 16895 49 63 - 8940 + 8941 @@ -9209,17 +9204,17 @@ 1 2 - 101943 + 101948 2 3 - 44620 + 44622 3 4 - 27643 + 27645 4 @@ -9245,7 +9240,7 @@ 1 4 - 16956 + 16957 4 @@ -9255,32 +9250,32 @@ 7 11 - 16421 + 16422 11 16 - 16216 + 16217 16 21 - 16442 + 16443 21 27 - 16771 + 16772 27 33 - 16442 + 16443 33 38 - 14469 + 14470 38 @@ -9290,17 +9285,17 @@ 43 47 - 14695 + 14696 47 52 - 16771 + 16772 52 65 - 14448 + 14449 65 @@ -9711,37 +9706,37 @@ 5 9 - 16483 + 16484 9 15 - 15805 + 15806 15 23 - 15085 + 15086 23 32 - 15640 + 15641 32 44 - 14736 + 14737 44 60 - 14489 + 14490 60 80 - 15250 + 15251 80 @@ -9756,17 +9751,17 @@ 130 160 - 14880 + 14881 160 195 - 14551 + 14552 195 299 - 9536 + 9537 @@ -9782,12 +9777,12 @@ 1 2 - 23512 + 23513 2 3 - 15558 + 15559 3 @@ -9797,12 +9792,12 @@ 4 6 - 16051 + 16052 6 8 - 13482 + 13483 8 @@ -9817,7 +9812,7 @@ 15 20 - 16771 + 16772 20 @@ -9827,17 +9822,17 @@ 26 33 - 16051 + 16052 33 40 - 14633 + 14634 40 49 - 14592 + 14593 49 @@ -9858,22 +9853,22 @@ 1 2 - 95469 + 95473 2 3 - 50005 + 50007 3 4 - 29370 + 29371 4 6 - 15599 + 15600 6 @@ -9894,57 +9889,57 @@ 1 4 - 15825 + 15826 4 7 - 17449 + 17450 7 11 - 16483 + 16484 11 16 - 17346 + 17347 16 21 - 17305 + 17306 21 26 - 15147 + 15148 26 31 - 16298 + 16299 31 36 - 17675 + 17676 36 40 - 15291 + 15292 40 44 - 16442 + 16443 44 49 - 16976 + 16977 49 @@ -9965,17 +9960,17 @@ 1 4 - 17182 + 17183 4 7 - 16791 + 16792 7 11 - 16421 + 16422 11 @@ -9985,22 +9980,22 @@ 16 21 - 16010 + 16011 21 26 - 14510 + 14511 26 32 - 16154 + 16155 32 38 - 17490 + 17491 38 @@ -10010,12 +10005,12 @@ 43 47 - 14469 + 14470 47 52 - 16565 + 16566 52 @@ -10405,23 +10400,23 @@ numlines - 1383934 + 1382103 element_id - 1376992 + 1375109 num_lines - 100902 + 101652 num_code - 84239 + 84866 num_comment - 59245 + 59685 @@ -10435,12 +10430,12 @@ 1 2 - 1370049 + 1368114 2 3 - 6942 + 6994 @@ -10456,12 +10451,12 @@ 1 2 - 1370974 + 1369047 2 3 - 6017 + 6061 @@ -10477,7 +10472,7 @@ 1 2 - 1376992 + 1375109 @@ -10493,27 +10488,27 @@ 1 2 - 67576 + 68079 2 3 - 12034 + 12123 3 4 - 7405 + 7460 4 21 - 7868 + 7927 29 - 926 - 6017 + 921 + 6061 @@ -10529,27 +10524,27 @@ 1 2 - 69891 + 70410 2 3 - 12034 + 12123 3 4 - 8331 + 8393 4 6 - 9257 + 9325 6 7 - 1388 + 1398 @@ -10565,22 +10560,22 @@ 1 2 - 68965 + 69478 2 3 - 14811 + 14921 3 4 - 10645 + 10724 4 7 - 6479 + 6528 @@ -10596,27 +10591,27 @@ 1 2 - 52302 + 52691 2 3 - 14348 + 14455 3 5 - 6479 + 6528 5 42 - 6479 + 6528 44 - 927 - 4628 + 922 + 4662 @@ -10632,27 +10627,27 @@ 1 2 - 52302 + 52691 2 3 - 16662 + 16786 3 5 - 6017 + 6061 5 8 - 6479 + 6528 8 12 - 2777 + 2797 @@ -10668,27 +10663,27 @@ 1 2 - 52765 + 53157 2 3 - 15737 + 15854 3 5 - 7405 + 7460 5 7 - 5091 + 5129 7 10 - 3239 + 3264 @@ -10704,32 +10699,32 @@ 1 2 - 34251 + 34505 2 3 - 9257 + 9325 3 4 - 4165 + 4196 4 6 - 4628 + 4662 6 11 - 5091 + 5129 17 - 2622 - 1851 + 2596 + 1865 @@ -10745,32 +10740,32 @@ 1 2 - 34251 + 34505 2 3 - 9257 + 9325 3 4 - 4165 + 4196 4 6 - 4628 + 4662 6 8 - 4628 + 4662 10 38 - 2314 + 2331 @@ -10786,32 +10781,32 @@ 1 2 - 34251 + 34505 2 3 - 9257 + 9325 3 4 - 4165 + 4196 4 6 - 4628 + 4662 6 10 - 4628 + 4662 10 37 - 2314 + 2331 @@ -10821,11 +10816,11 @@ diagnostics - 72033 + 72036 id - 72033 + 72036 severity @@ -10841,7 +10836,7 @@ full_error_message - 62489 + 62491 location @@ -10859,7 +10854,7 @@ 1 2 - 72033 + 72036 @@ -10875,7 +10870,7 @@ 1 2 - 72033 + 72036 @@ -10891,7 +10886,7 @@ 1 2 - 72033 + 72036 @@ -10907,7 +10902,7 @@ 1 2 - 72033 + 72036 @@ -10923,7 +10918,7 @@ 1 2 - 72033 + 72036 @@ -11319,7 +11314,7 @@ 1 2 - 62477 + 62480 829 @@ -11340,7 +11335,7 @@ 1 2 - 62489 + 62491 @@ -11356,7 +11351,7 @@ 1 2 - 62489 + 62491 @@ -11372,7 +11367,7 @@ 1 2 - 62489 + 62491 @@ -11388,7 +11383,7 @@ 1 2 - 62489 + 62491 @@ -11498,15 +11493,15 @@ files - 122193 + 123102 id - 122193 + 123102 name - 122193 + 123102 @@ -11520,7 +11515,7 @@ 1 2 - 122193 + 123102 @@ -11536,7 +11531,7 @@ 1 2 - 122193 + 123102 @@ -11546,15 +11541,15 @@ folders - 15274 + 15387 id - 15274 + 15387 name - 15274 + 15387 @@ -11568,7 +11563,7 @@ 1 2 - 15274 + 15387 @@ -11584,7 +11579,7 @@ 1 2 - 15274 + 15387 @@ -11594,15 +11589,15 @@ containerparent - 136542 + 137557 parent - 15274 + 15387 child - 136542 + 137557 @@ -11616,32 +11611,32 @@ 1 2 - 6479 + 6528 2 3 - 3239 + 3264 3 5 - 1388 + 1398 5 12 - 1388 + 1398 23 28 - 1388 + 1398 40 67 - 1388 + 1398 @@ -11657,7 +11652,7 @@ 1 2 - 136542 + 137557 @@ -11667,11 +11662,11 @@ fileannotations - 5237780 + 5238006 id - 5002 + 5003 kind @@ -11679,11 +11674,11 @@ name - 55930 + 55932 value - 47019 + 47021 @@ -11702,7 +11697,7 @@ 2 3 - 4829 + 4830 @@ -11918,7 +11913,7 @@ 1 2 - 9048 + 9049 2 @@ -11989,7 +11984,7 @@ 1 2 - 55930 + 55932 @@ -12020,12 +12015,12 @@ 4 6 - 4610 + 4611 6 9 - 4218 + 4219 9 @@ -12035,7 +12030,7 @@ 14 17 - 4218 + 4219 17 @@ -12055,7 +12050,7 @@ 82 157 - 4195 + 4196 158 @@ -12126,7 +12121,7 @@ 266 321 - 3757 + 3758 322 @@ -12152,7 +12147,7 @@ 1 2 - 47007 + 47010 2 @@ -12183,7 +12178,7 @@ 5 8 - 3584 + 3585 8 @@ -12203,7 +12198,7 @@ 19 29 - 3584 + 3585 29 @@ -12243,15 +12238,15 @@ inmacroexpansion - 109604513 + 109609474 id - 17998714 + 17999527 inv - 2695879 + 2696000 @@ -12265,37 +12260,37 @@ 1 3 - 1579476 + 1579546 3 5 - 1076083 + 1076132 5 6 - 1182998 + 1183051 6 7 - 4812255 + 4812473 7 8 - 6375799 + 6376088 8 9 - 2601108 + 2601226 9 21 - 370992 + 371008 @@ -12311,57 +12306,57 @@ 1 2 - 377826 + 377842 2 3 - 543242 + 543265 3 4 - 350956 + 350972 4 7 - 200341 + 200350 7 8 - 206822 + 206832 8 9 - 241503 + 241514 9 10 - 2206 + 2207 10 11 - 324968 + 324983 11 337 - 224489 + 224500 339 423 - 206025 + 206034 423 7616 - 17496 + 17497 @@ -12371,15 +12366,15 @@ affectedbymacroexpansion - 35632303 + 35633915 id - 5148541 + 5148773 inv - 2780346 + 2780470 @@ -12393,37 +12388,37 @@ 1 2 - 2811453 + 2811579 2 3 - 559241 + 559267 3 4 - 264485 + 264497 4 5 - 564894 + 564919 5 12 - 391280 + 391297 12 50 - 406753 + 406771 50 9900 - 150433 + 150439 @@ -12439,67 +12434,67 @@ 1 4 - 228755 + 228764 4 7 - 231419 + 231430 7 9 - 220127 + 220137 9 12 - 250688 + 250699 12 13 - 333446 + 333461 13 14 - 165325 + 165332 14 15 - 298368 + 298382 15 16 - 121649 + 121654 16 17 - 276168 + 276181 17 18 - 146706 + 146713 18 20 - 251734 + 251745 20 25 - 208646 + 208656 25 109 - 47308 + 47310 @@ -12509,19 +12504,19 @@ macroinvocations - 34146427 + 34192813 id - 34146427 + 34192813 macro_id - 81163 + 81166 location - 776449 + 776483 kind @@ -12539,7 +12534,7 @@ 1 2 - 34146427 + 34192813 @@ -12555,7 +12550,7 @@ 1 2 - 34146427 + 34192813 @@ -12571,7 +12566,7 @@ 1 2 - 34146427 + 34192813 @@ -12587,12 +12582,12 @@ 1 2 - 16645 + 16599 2 3 - 16979 + 16922 3 @@ -12602,22 +12597,22 @@ 4 5 - 5348 + 5383 5 8 - 5890 + 5809 8 13 - 6259 + 6236 13 26 - 6282 + 6328 26 @@ -12626,18 +12621,18 @@ 61 - 205 - 6132 + 200 + 6098 - 205 - 1780 - 6109 + 200 + 1697 + 6121 - 1780 - 168526 - 2144 + 1716 + 168807 + 2294 @@ -12653,17 +12648,17 @@ 1 2 - 43365 + 43367 2 3 - 10616 + 10617 3 4 - 5267 + 5268 4 @@ -12699,12 +12694,12 @@ 1 2 - 75307 + 75310 2 3 - 5855 + 5856 @@ -12720,37 +12715,37 @@ 1 2 - 288503 + 287189 2 3 - 173542 + 173515 3 4 - 72460 + 72935 4 5 - 61036 + 60981 5 9 - 71745 + 71656 9 21 - 59365 + 60186 21 - 244557 - 49797 + 244764 + 50018 @@ -12766,12 +12761,12 @@ 1 2 - 729303 + 729335 2 350 - 47146 + 47148 @@ -12787,7 +12782,7 @@ 1 2 - 776449 + 776483 @@ -12806,8 +12801,8 @@ 11 - 2941582 - 2941583 + 2945478 + 2945479 11 @@ -12860,15 +12855,15 @@ macroparent - 30546697 + 30581550 id - 30546697 + 30581550 parent_id - 23742230 + 23776789 @@ -12882,7 +12877,7 @@ 1 2 - 30546697 + 30581550 @@ -12898,17 +12893,17 @@ 1 2 - 18336209 + 18370535 2 3 - 4553733 + 4553929 3 88 - 852287 + 852324 @@ -12918,15 +12913,15 @@ macrolocationbind - 4036713 + 4036895 id - 2826088 + 2826216 location - 2017695 + 2017786 @@ -12940,22 +12935,22 @@ 1 2 - 2225864 + 2225964 2 3 - 340555 + 340571 3 7 - 230140 + 230151 7 57 - 29527 + 29529 @@ -12971,22 +12966,22 @@ 1 2 - 1608335 + 1608407 2 3 - 177385 + 177393 3 8 - 156613 + 156621 8 723 - 75360 + 75364 @@ -12996,11 +12991,11 @@ macro_argument_unexpanded - 86236355 + 86329774 invocation - 26718268 + 26761716 argument_index @@ -13008,7 +13003,7 @@ text - 325032 + 325046 @@ -13022,22 +13017,22 @@ 1 2 - 7569459 + 7582881 2 3 - 10882564 + 10899357 3 4 - 6258953 + 6268860 4 67 - 2007291 + 2010617 @@ -13053,22 +13048,22 @@ 1 2 - 7640455 + 7654526 2 3 - 11032487 + 11049010 3 4 - 6089388 + 6099011 4 67 - 1955937 + 1959168 @@ -13088,12 +13083,12 @@ 41432 - 174136 + 174417 57 - 717107 - 2317844 + 718224 + 2321513 34 @@ -13136,57 +13131,57 @@ 1 2 - 37325 + 35816 2 3 - 64644 + 62756 3 4 - 16979 + 19412 4 5 - 45786 + 44773 5 - 8 - 25521 + 7 + 24427 - 8 + 7 12 - 16218 + 18790 12 16 - 21855 + 22006 16 23 - 25671 + 25614 23 42 - 24506 + 24703 42 129 - 24391 + 24588 129 - 522100 - 22132 + 522415 + 22156 @@ -13202,12 +13197,12 @@ 1 2 - 235062 + 235073 2 3 - 79468 + 79472 3 @@ -13222,11 +13217,11 @@ macro_argument_expanded - 86236355 + 86329774 invocation - 26718268 + 26761716 argument_index @@ -13234,7 +13229,7 @@ text - 196977 + 196985 @@ -13248,22 +13243,22 @@ 1 2 - 7569459 + 7582881 2 3 - 10882564 + 10899357 3 4 - 6258953 + 6268860 4 67 - 2007291 + 2010617 @@ -13279,22 +13274,22 @@ 1 2 - 10891544 + 10908372 2 3 - 9380960 + 9395798 3 4 - 5309284 + 5318101 4 9 - 1136479 + 1139444 @@ -13314,12 +13309,12 @@ 41432 - 174136 + 174417 57 - 717107 - 2317844 + 718224 + 2321513 34 @@ -13362,62 +13357,62 @@ 1 2 - 22016 + 21234 2 3 - 39745 + 38295 3 4 - 8875 + 10340 4 5 - 16818 + 15712 5 6 - 3054 + 3539 6 7 - 22720 + 22352 7 - 10 - 16149 + 9 + 14847 - 10 - 15 - 15769 + 9 + 14 + 12622 - 15 - 27 - 14939 + 14 + 20 + 14986 - 27 - 73 - 14893 + 20 + 49 + 15666 - 73 - 361 - 14835 + 49 + 169 + 14790 - 363 - 1059615 - 7158 + 169 + 1060455 + 12599 @@ -13433,17 +13428,17 @@ 1 2 - 99687 + 99691 2 3 - 82580 + 82584 3 66 - 14708 + 14709 @@ -13453,19 +13448,19 @@ functions - 4634561 + 4638253 id - 4634561 + 4638253 name - 1902794 + 1916013 kind - 3239 + 3264 @@ -13479,7 +13474,7 @@ 1 2 - 4634561 + 4638253 @@ -13495,7 +13490,7 @@ 1 2 - 4634561 + 4638253 @@ -13511,22 +13506,22 @@ 1 2 - 1492705 + 1503340 2 3 - 151353 + 152479 3 5 - 149501 + 150147 5 - 1692 - 109233 + 1666 + 110046 @@ -13542,12 +13537,12 @@ 1 2 - 1902331 + 1915546 2 3 - 462 + 466 @@ -13563,37 +13558,37 @@ 6 7 - 462 + 466 64 65 - 462 + 466 173 174 - 462 + 466 195 196 - 462 + 466 - 1355 - 1356 - 462 + 1350 + 1351 + 466 - 2400 - 2401 - 462 + 2372 + 2373 + 466 - 5820 - 5821 - 462 + 5787 + 5788 + 466 @@ -13609,37 +13604,37 @@ 3 4 - 462 + 466 33 34 - 462 + 466 39 40 - 462 + 466 94 95 - 462 + 466 195 196 - 462 + 466 243 244 - 462 + 466 - 3505 - 3506 - 462 + 3503 + 3504 + 466 @@ -13649,15 +13644,15 @@ function_entry_point - 1158061 + 1156415 id - 1148341 + 1146623 entry_point - 1158061 + 1156415 @@ -13671,12 +13666,12 @@ 1 2 - 1138622 + 1136831 2 3 - 9719 + 9792 @@ -13692,7 +13687,7 @@ 1 2 - 1158061 + 1156415 @@ -13702,15 +13697,15 @@ function_return_type - 4639653 + 4643382 id - 4634561 + 4638253 return_type - 990971 + 984818 @@ -13724,12 +13719,12 @@ 1 2 - 4629470 + 4633124 2 3 - 5091 + 5129 @@ -13745,22 +13740,22 @@ 1 2 - 512842 + 510128 2 3 - 376763 + 373503 3 10 - 74519 + 75073 10 - 2513 - 26845 + 2512 + 26112 @@ -13778,7 +13773,7 @@ traits - 2 + 1 handle @@ -13846,9 +13841,9 @@ 12 - 1 - 2 - 2 + 2 + 3 + 1 @@ -13862,9 +13857,9 @@ 12 - 1 - 2 - 2 + 2 + 3 + 1 @@ -13878,9 +13873,9 @@ 12 - 1 - 2 - 2 + 2 + 3 + 1 @@ -14082,48 +14077,48 @@ purefunctions - 100048 + 100053 id - 100048 + 100053 function_deleted - 138393 + 137557 id - 138393 + 137557 function_defaulted - 73131 + 73674 id - 73131 + 73674 member_function_this_type - 553553 + 553568 id - 553553 + 553568 this_type - 189963 + 189968 @@ -14137,7 +14132,7 @@ 1 2 - 553553 + 553568 @@ -14153,22 +14148,22 @@ 1 2 - 68554 + 68556 2 3 - 45514 + 45516 3 4 - 30554 + 30555 4 5 - 15559 + 15560 5 @@ -14178,7 +14173,7 @@ 7 66 - 14183 + 14184 @@ -14188,27 +14183,27 @@ fun_decls - 5000679 + 5007094 id - 4995588 + 5001965 function - 4492002 + 4494634 type_id - 989582 + 983419 name - 1806058 + 1818557 location - 3404294 + 3416556 @@ -14222,7 +14217,7 @@ 1 2 - 4995588 + 5001965 @@ -14238,12 +14233,12 @@ 1 2 - 4990497 + 4996835 2 3 - 5091 + 5129 @@ -14259,7 +14254,7 @@ 1 2 - 4995588 + 5001965 @@ -14275,7 +14270,7 @@ 1 2 - 4995588 + 5001965 @@ -14291,17 +14286,17 @@ 1 2 - 4066639 + 4066107 2 3 - 353157 + 355784 3 7 - 72205 + 72742 @@ -14317,12 +14312,12 @@ 1 2 - 4452660 + 4454998 2 3 - 39342 + 39635 @@ -14338,7 +14333,7 @@ 1 2 - 4492002 + 4494634 @@ -14354,17 +14349,17 @@ 1 2 - 4122644 + 4122529 2 4 - 368432 + 371172 5 6 - 925 + 932 @@ -14380,22 +14375,22 @@ 1 2 - 438786 + 435521 2 3 - 438786 + 435987 3 8 - 74519 + 75073 8 - 2758 - 37491 + 2757 + 36837 @@ -14411,22 +14406,22 @@ 1 2 - 522099 + 519454 2 3 - 368432 + 365110 3 11 - 75908 + 75540 11 - 2474 - 23142 + 2473 + 23314 @@ -14442,17 +14437,17 @@ 1 2 - 862297 + 856120 2 5 - 88868 + 89528 5 821 - 38416 + 37770 @@ -14468,22 +14463,22 @@ 1 2 - 759544 + 752136 2 3 - 130987 + 131495 3 - 11 - 76833 + 10 + 74607 - 11 - 2029 - 22217 + 10 + 2028 + 25180 @@ -14499,27 +14494,27 @@ 1 2 - 1225175 + 1233821 2 3 - 265215 + 267188 3 4 - 79148 + 80203 4 6 - 136542 + 136624 6 - 1726 - 99976 + 1700 + 100720 @@ -14535,22 +14530,22 @@ 1 2 - 1402911 + 1412879 2 3 - 150427 + 151546 3 5 - 143484 + 144085 5 - 1676 - 109233 + 1650 + 110046 @@ -14566,17 +14561,17 @@ 1 2 - 1589442 + 1600796 2 4 - 132839 + 134293 4 - 938 - 83776 + 925 + 83467 @@ -14592,27 +14587,27 @@ 1 2 - 1246004 + 1254804 2 3 - 291598 + 293766 3 4 - 78222 + 79270 4 8 - 137004 + 137557 8 - 661 - 53228 + 651 + 53157 @@ -14628,17 +14623,17 @@ 1 2 - 2947457 + 2961450 2 4 - 297152 + 295165 4 55 - 159684 + 159939 @@ -14654,17 +14649,17 @@ 1 2 - 3014108 + 3028597 2 6 - 264289 + 261592 6 55 - 125896 + 126366 @@ -14680,12 +14675,12 @@ 1 2 - 3193695 + 3207655 2 - 27 - 210598 + 25 + 208900 @@ -14701,12 +14696,12 @@ 1 2 - 3231650 + 3245425 2 13 - 172644 + 171130 @@ -14716,22 +14711,22 @@ fun_def - 1932417 + 1934665 id - 1932417 + 1934665 fun_specialized - 25919 + 26112 id - 25919 + 26112 @@ -14749,15 +14744,15 @@ fun_decl_specifiers - 2890063 + 2903163 id - 1683401 + 1687527 name - 2777 + 2797 @@ -14771,17 +14766,17 @@ 1 2 - 495254 + 490544 2 3 - 1169633 + 1178331 3 4 - 18514 + 18651 @@ -14797,32 +14792,32 @@ 50 51 - 462 + 466 203 204 - 462 + 466 209 210 - 462 + 466 - 657 - 658 - 462 + 639 + 640 + 466 2561 2562 - 462 + 466 2564 2565 - 462 + 466 @@ -14953,26 +14948,26 @@ fun_decl_empty_throws - 1926863 + 1926738 fun_decl - 1926863 + 1926738 fun_decl_noexcept - 61185 + 61190 fun_decl - 61185 + 61190 constant - 61080 + 61086 @@ -14986,7 +14981,7 @@ 1 2 - 61185 + 61190 @@ -15002,7 +14997,7 @@ 1 2 - 60976 + 60981 2 @@ -15017,11 +15012,11 @@ fun_decl_empty_noexcept - 874794 + 869643 fun_decl - 874794 + 869643 @@ -15126,19 +15121,19 @@ param_decl_bind - 7337169 + 7373083 id - 7337169 + 7373083 index - 7868 + 7927 fun_decl - 4202718 + 4217187 @@ -15152,7 +15147,7 @@ 1 2 - 7337169 + 7373083 @@ -15168,7 +15163,7 @@ 1 2 - 7337169 + 7373083 @@ -15184,72 +15179,72 @@ 2 3 - 925 + 932 5 6 - 462 + 466 7 8 - 462 + 466 10 11 - 925 + 932 11 12 - 462 + 466 12 13 - 925 + 932 13 14 - 462 + 466 25 26 - 462 + 466 78 79 - 462 + 466 245 246 - 462 + 466 636 637 - 462 + 466 1713 1714 - 462 + 466 - 3991 - 3992 - 462 + 3987 + 3988 + 466 - 9080 - 9081 - 462 + 9044 + 9045 + 466 @@ -15265,72 +15260,72 @@ 2 3 - 925 + 932 5 6 - 462 + 466 7 8 - 462 + 466 10 11 - 925 + 932 11 12 - 462 + 466 12 13 - 925 + 932 13 14 - 462 + 466 25 26 - 462 + 466 78 79 - 462 + 466 245 246 - 462 + 466 636 637 - 462 + 466 1713 1714 - 462 + 466 - 3991 - 3992 - 462 + 3987 + 3988 + 466 - 9080 - 9081 - 462 + 9044 + 9045 + 466 @@ -15346,22 +15341,22 @@ 1 2 - 2355466 + 2358062 2 3 - 1054382 + 1060358 3 4 - 498494 + 502201 4 18 - 294375 + 296564 @@ -15377,22 +15372,22 @@ 1 2 - 2355466 + 2358062 2 3 - 1054382 + 1060358 3 4 - 498494 + 502201 4 18 - 294375 + 296564 @@ -15402,27 +15397,27 @@ var_decls - 8461442 + 8487066 id - 8393866 + 8416189 variable - 7390397 + 7405258 type_id - 2376757 + 2379045 name - 661881 + 666804 location - 5278855 + 5305524 @@ -15436,7 +15431,7 @@ 1 2 - 8393866 + 8416189 @@ -15452,12 +15447,12 @@ 1 2 - 8326289 + 8348110 2 3 - 67576 + 68079 @@ -15473,7 +15468,7 @@ 1 2 - 8393866 + 8416189 @@ -15489,7 +15484,12 @@ 1 2 - 8393866 + 8413391 + + + 2 + 3 + 2797 @@ -15505,17 +15505,17 @@ 1 2 - 6545688 + 6554266 2 3 - 692430 + 697579 3 7 - 152279 + 153411 @@ -15531,12 +15531,12 @@ 1 2 - 7220530 + 7234127 2 4 - 169867 + 171130 @@ -15552,12 +15552,12 @@ 1 2 - 7276072 + 7290083 2 3 - 114325 + 115175 @@ -15573,12 +15573,12 @@ 1 2 - 6849783 + 6860623 2 4 - 540614 + 544634 @@ -15594,27 +15594,27 @@ 1 2 - 1466323 + 1464171 2 3 - 507751 + 509196 3 4 - 97199 + 97922 4 7 - 185604 + 186984 7 - 780 - 119879 + 762 + 120770 @@ -15630,22 +15630,22 @@ 1 2 - 1598699 + 1597532 2 3 - 483220 + 484482 3 7 - 185141 + 186518 7 - 742 - 109696 + 724 + 110512 @@ -15661,17 +15661,17 @@ 1 2 - 1873172 + 1872181 2 3 - 382317 + 384694 3 128 - 121267 + 122169 @@ -15687,22 +15687,22 @@ 1 2 - 1700990 + 1700117 2 3 - 400369 + 401481 3 8 - 186993 + 188383 8 - 595 - 88405 + 592 + 89062 @@ -15718,37 +15718,37 @@ 1 2 - 338346 + 340862 2 3 - 86090 + 86731 3 4 - 48136 + 48494 4 6 - 51376 + 51758 6 12 - 51839 + 52225 12 33 - 49988 + 50360 34 - 3249 - 36102 + 3213 + 36371 @@ -15764,37 +15764,37 @@ 1 2 - 365655 + 368374 2 3 - 77296 + 77871 3 4 - 44896 + 45230 4 6 - 49062 + 49427 6 14 - 52765 + 53157 14 56 - 50451 + 50826 56 - 3166 - 21754 + 3130 + 21915 @@ -15810,27 +15810,27 @@ 1 2 - 453134 + 456504 2 3 - 93033 + 93725 3 5 - 46285 + 46629 5 19 - 50451 + 50826 19 - 1947 - 18977 + 1917 + 19118 @@ -15846,32 +15846,32 @@ 1 2 - 375837 + 378632 2 3 - 89793 + 90461 3 5 - 59245 + 59685 5 9 - 50913 + 51292 9 21 - 49988 + 50360 21 - 1020 - 36102 + 1010 + 36371 @@ -15887,17 +15887,17 @@ 1 2 - 4462842 + 4490903 2 3 - 541539 + 531111 3 - 1751 - 274472 + 1725 + 283508 @@ -15913,17 +15913,17 @@ 1 2 - 4860434 + 4879795 2 17 - 407311 + 415004 17 - 1747 - 11108 + 1721 + 10724 @@ -15939,12 +15939,12 @@ 1 2 - 4935880 + 4955801 2 - 1529 - 342975 + 1503 + 349722 @@ -15960,12 +15960,12 @@ 1 2 - 5274689 + 5296198 2 - 24 - 4165 + 6 + 9325 @@ -15975,26 +15975,26 @@ var_def - 4020816 + 4023674 id - 4020816 + 4023674 var_decl_specifiers - 329552 + 310553 id - 329552 + 310553 name - 1388 + 1398 @@ -16008,7 +16008,7 @@ 1 2 - 329552 + 310553 @@ -16024,17 +16024,17 @@ 15 16 - 462 + 466 66 67 - 462 + 466 - 631 - 632 - 462 + 585 + 586 + 466 @@ -16055,19 +16055,19 @@ type_decls - 3242758 + 3241228 id - 3242758 + 3241228 type_id - 3192770 + 3190868 location - 3164073 + 3162424 @@ -16081,7 +16081,7 @@ 1 2 - 3242758 + 3241228 @@ -16097,7 +16097,7 @@ 1 2 - 3242758 + 3241228 @@ -16113,12 +16113,12 @@ 1 2 - 3151576 + 3149368 2 5 - 41194 + 41500 @@ -16134,12 +16134,12 @@ 1 2 - 3151576 + 3149368 2 5 - 41194 + 41500 @@ -16155,12 +16155,12 @@ 1 2 - 3123804 + 3122322 2 20 - 40268 + 40101 @@ -16176,12 +16176,12 @@ 1 2 - 3123804 + 3122322 2 20 - 40268 + 40101 @@ -16191,45 +16191,45 @@ type_def - 2627162 + 2623851 id - 2627162 + 2623851 type_decl_top - 746121 + 742810 type_decl - 746121 + 742810 namespace_decls - 308849 + 308863 id - 308849 + 308863 namespace_id - 1415 + 1416 location - 308849 + 308863 bodylocation - 308849 + 308863 @@ -16243,7 +16243,7 @@ 1 2 - 308849 + 308863 @@ -16259,7 +16259,7 @@ 1 2 - 308849 + 308863 @@ -16275,7 +16275,7 @@ 1 2 - 308849 + 308863 @@ -16489,7 +16489,7 @@ 1 2 - 308849 + 308863 @@ -16505,7 +16505,7 @@ 1 2 - 308849 + 308863 @@ -16521,7 +16521,7 @@ 1 2 - 308849 + 308863 @@ -16537,7 +16537,7 @@ 1 2 - 308849 + 308863 @@ -16553,7 +16553,7 @@ 1 2 - 308849 + 308863 @@ -16569,7 +16569,7 @@ 1 2 - 308849 + 308863 @@ -16579,19 +16579,19 @@ usings - 369357 + 369307 id - 369357 + 369307 element_id - 313815 + 315216 location - 246238 + 247603 @@ -16605,7 +16605,7 @@ 1 2 - 369357 + 369307 @@ -16621,7 +16621,7 @@ 1 2 - 369357 + 369307 @@ -16637,17 +16637,17 @@ 1 2 - 260124 + 262991 2 3 - 52302 + 50826 3 5 - 1388 + 1398 @@ -16663,17 +16663,17 @@ 1 2 - 260124 + 262991 2 3 - 52302 + 50826 3 5 - 1388 + 1398 @@ -16689,22 +16689,22 @@ 1 2 - 200878 + 202372 2 4 - 11108 + 10724 4 5 - 31011 + 31241 5 11 - 3239 + 3264 @@ -16720,22 +16720,22 @@ 1 2 - 200878 + 202372 2 4 - 11108 + 10724 4 5 - 31011 + 31241 5 11 - 3239 + 3264 @@ -16745,7 +16745,7 @@ using_container - 476661 + 476682 parent @@ -16753,7 +16753,7 @@ child - 302243 + 302256 @@ -16767,7 +16767,7 @@ 1 2 - 3365 + 3366 2 @@ -16823,17 +16823,17 @@ 1 2 - 222924 + 222934 2 3 - 52817 + 52819 3 11 - 24322 + 24323 13 @@ -16848,19 +16848,19 @@ static_asserts - 130539 + 130544 id - 130539 + 130544 condition - 130539 + 130544 message - 29483 + 29484 location @@ -16882,7 +16882,7 @@ 1 2 - 130539 + 130544 @@ -16898,7 +16898,7 @@ 1 2 - 130539 + 130544 @@ -16914,7 +16914,7 @@ 1 2 - 130539 + 130544 @@ -16930,7 +16930,7 @@ 1 2 - 130539 + 130544 @@ -16946,7 +16946,7 @@ 1 2 - 130539 + 130544 @@ -16962,7 +16962,7 @@ 1 2 - 130539 + 130544 @@ -16978,7 +16978,7 @@ 1 2 - 130539 + 130544 @@ -16994,7 +16994,7 @@ 1 2 - 130539 + 130544 @@ -17010,7 +17010,7 @@ 1 2 - 21969 + 21970 2 @@ -17020,7 +17020,7 @@ 3 4 - 2768 + 2769 4 @@ -17051,7 +17051,7 @@ 1 2 - 21969 + 21970 2 @@ -17061,7 +17061,7 @@ 3 4 - 2768 + 2769 4 @@ -17092,7 +17092,7 @@ 1 2 - 27368 + 27370 2 @@ -17113,7 +17113,7 @@ 1 2 - 23385 + 23386 2 @@ -17149,7 +17149,7 @@ 1 2 - 3133 + 3134 2 @@ -17159,12 +17159,12 @@ 3 4 - 1308 + 1309 5 6 - 3624 + 3625 6 @@ -17205,7 +17205,7 @@ 1 2 - 3133 + 3134 2 @@ -17215,12 +17215,12 @@ 3 4 - 1308 + 1309 5 6 - 3624 + 3625 6 @@ -17271,7 +17271,7 @@ 3 4 - 6028 + 6029 4 @@ -17297,7 +17297,7 @@ 2 3 - 6116 + 6117 3 @@ -17466,23 +17466,23 @@ params - 6702132 + 6733324 id - 6539671 + 6569654 function - 3862057 + 3873993 index - 7868 + 7927 type_id - 2182821 + 2183667 @@ -17496,7 +17496,7 @@ 1 2 - 6539671 + 6569654 @@ -17512,7 +17512,7 @@ 1 2 - 6539671 + 6569654 @@ -17528,12 +17528,12 @@ 1 2 - 6417014 + 6446086 2 4 - 122656 + 123568 @@ -17549,22 +17549,22 @@ 1 2 - 2249935 + 2251746 2 3 - 946537 + 951711 3 4 - 426288 + 429459 4 18 - 239295 + 241075 @@ -17580,22 +17580,22 @@ 1 2 - 2249935 + 2251746 2 3 - 946537 + 951711 3 4 - 426288 + 429459 4 18 - 239295 + 241075 @@ -17611,22 +17611,22 @@ 1 2 - 2547551 + 2549710 2 3 - 819715 + 825811 3 4 - 343438 + 345992 4 12 - 151353 + 152479 @@ -17642,72 +17642,72 @@ 2 3 - 925 + 932 4 5 - 462 + 466 6 7 - 462 + 466 8 9 - 925 + 932 9 10 - 462 + 466 10 11 - 925 + 932 11 12 - 462 + 466 19 20 - 462 + 466 64 65 - 462 + 466 194 195 - 462 + 466 517 518 - 462 + 466 1438 1439 - 462 + 466 - 3483 - 3484 - 462 + 3479 + 3480 + 466 - 8344 - 8345 - 462 + 8308 + 8309 + 466 @@ -17723,72 +17723,72 @@ 2 3 - 925 + 932 4 5 - 462 + 466 6 7 - 462 + 466 8 9 - 925 + 932 9 10 - 462 + 466 10 11 - 925 + 932 11 12 - 462 + 466 19 20 - 462 + 466 64 65 - 462 + 466 194 195 - 462 + 466 517 518 - 462 + 466 1438 1439 - 462 + 466 - 3483 - 3484 - 462 + 3479 + 3480 + 466 - 8344 - 8345 - 462 + 8308 + 8309 + 466 @@ -17804,67 +17804,67 @@ 1 2 - 925 + 932 3 4 - 462 + 466 4 5 - 462 + 466 5 6 - 462 + 466 6 7 - 1388 + 1398 7 8 - 925 + 932 11 12 - 462 + 466 42 43 - 462 + 466 106 107 - 462 + 466 228 229 - 462 + 466 582 583 - 462 + 466 - 1275 - 1276 - 462 + 1271 + 1272 + 466 - 3632 - 3633 - 462 + 3599 + 3600 + 466 @@ -17880,22 +17880,22 @@ 1 2 - 1485300 + 1483289 2 3 - 439248 + 440184 3 8 - 168941 + 170198 8 - 520 - 89330 + 518 + 89995 @@ -17911,22 +17911,22 @@ 1 2 - 1705155 + 1702915 2 3 - 246701 + 248069 3 9 - 167090 + 168333 9 - 504 - 63873 + 502 + 64348 @@ -17942,17 +17942,17 @@ 1 2 - 1756995 + 1756539 2 3 - 347603 + 348323 3 13 - 78222 + 78804 @@ -17962,15 +17962,15 @@ overrides - 159972 + 159979 new - 125139 + 125145 old - 15109 + 15110 @@ -17984,12 +17984,12 @@ 1 2 - 90313 + 90317 2 3 - 34820 + 34821 3 @@ -18050,19 +18050,19 @@ membervariables - 1054731 + 1054778 id - 1052936 + 1052983 type_id - 327180 + 327195 name - 450865 + 450885 @@ -18076,7 +18076,7 @@ 1 2 - 1051221 + 1051268 2 @@ -18097,7 +18097,7 @@ 1 2 - 1052936 + 1052983 @@ -18113,17 +18113,17 @@ 1 2 - 242623 + 242634 2 3 - 51811 + 51813 3 10 - 25486 + 25487 10 @@ -18144,22 +18144,22 @@ 1 2 - 254828 + 254839 2 3 - 46386 + 46388 3 40 - 24569 + 24570 41 2031 - 1395 + 1396 @@ -18175,22 +18175,22 @@ 1 2 - 294833 + 294846 2 3 - 86391 + 86395 3 5 - 41121 + 41123 5 646 - 28518 + 28519 @@ -18206,17 +18206,17 @@ 1 2 - 367225 + 367242 2 3 - 51651 + 51654 3 650 - 31988 + 31989 @@ -18226,11 +18226,11 @@ globalvariables - 301278 + 301284 id - 301270 + 301276 type_id @@ -18238,7 +18238,7 @@ name - 294738 + 294744 @@ -18252,7 +18252,7 @@ 1 2 - 301262 + 301268 2 @@ -18273,7 +18273,7 @@ 1 2 - 301270 + 301276 @@ -18299,17 +18299,17 @@ 3 7 - 117 + 116 7 - 68 + 67 106 - 76 + 67 169440 - 50 + 51 @@ -18335,17 +18335,17 @@ 3 7 - 112 + 111 7 - 105 + 102 106 - 106 + 104 168448 - 42 + 43 @@ -18361,7 +18361,7 @@ 1 2 - 290721 + 290727 2 @@ -18382,7 +18382,7 @@ 1 2 - 294139 + 294145 2 @@ -18397,19 +18397,19 @@ localvariables - 581183 + 581207 id - 581183 + 581207 type_id - 37872 + 37873 name - 91323 + 91326 @@ -18423,7 +18423,7 @@ 1 2 - 581183 + 581207 @@ -18439,7 +18439,7 @@ 1 2 - 581183 + 581207 @@ -18455,7 +18455,7 @@ 1 2 - 21188 + 21189 2 @@ -18496,7 +18496,7 @@ 1 2 - 26975 + 26976 2 @@ -18532,7 +18532,7 @@ 1 2 - 57519 + 57522 2 @@ -18547,7 +18547,7 @@ 5 15 - 7041 + 7042 15 @@ -18568,7 +18568,7 @@ 1 2 - 77146 + 77150 2 @@ -18578,7 +18578,7 @@ 3 1486 - 6701 + 6702 @@ -18588,11 +18588,11 @@ autoderivation - 149355 + 149368 var - 149355 + 149368 derivation_type @@ -18610,7 +18610,7 @@ 1 2 - 149355 + 149368 @@ -18656,11 +18656,11 @@ orphaned_variables - 37893 + 37894 var - 37893 + 37894 function @@ -18678,7 +18678,7 @@ 1 2 - 37893 + 37894 @@ -18694,7 +18694,7 @@ 1 2 - 31225 + 31226 2 @@ -18709,19 +18709,19 @@ enumconstants - 241267 + 241278 id - 241267 + 241278 parent - 28478 + 28479 index - 10210 + 10211 type_id @@ -18729,11 +18729,11 @@ name - 240988 + 240998 location - 221204 + 221214 @@ -18747,7 +18747,7 @@ 1 2 - 241267 + 241278 @@ -18763,7 +18763,7 @@ 1 2 - 241267 + 241278 @@ -18779,7 +18779,7 @@ 1 2 - 241267 + 241278 @@ -18795,7 +18795,7 @@ 1 2 - 241267 + 241278 @@ -18811,7 +18811,7 @@ 1 2 - 241267 + 241278 @@ -18959,7 +18959,7 @@ 1 2 - 28478 + 28479 @@ -19046,7 +19046,7 @@ 2 3 - 4187 + 4188 3 @@ -19056,7 +19056,7 @@ 4 5 - 3868 + 3869 5 @@ -19071,7 +19071,7 @@ 7 8 - 1395 + 1396 8 @@ -19112,7 +19112,7 @@ 3 4 - 1754 + 1755 4 @@ -19168,7 +19168,7 @@ 3 4 - 1754 + 1755 4 @@ -19214,7 +19214,7 @@ 1 2 - 10210 + 10211 @@ -19240,7 +19240,7 @@ 3 4 - 1754 + 1755 4 @@ -19296,7 +19296,7 @@ 3 4 - 1754 + 1755 4 @@ -19422,7 +19422,7 @@ 1 2 - 240708 + 240719 2 @@ -19443,7 +19443,7 @@ 1 2 - 240708 + 240719 2 @@ -19464,7 +19464,7 @@ 1 2 - 240988 + 240998 @@ -19480,7 +19480,7 @@ 1 2 - 240988 + 240998 @@ -19496,7 +19496,7 @@ 1 2 - 240708 + 240719 2 @@ -19517,7 +19517,7 @@ 1 2 - 220446 + 220456 2 @@ -19538,7 +19538,7 @@ 1 2 - 221204 + 221214 @@ -19554,7 +19554,7 @@ 1 2 - 220446 + 220456 2 @@ -19575,7 +19575,7 @@ 1 2 - 221204 + 221214 @@ -19591,7 +19591,7 @@ 1 2 - 220446 + 220456 2 @@ -19606,31 +19606,31 @@ builtintypes - 22679 + 22848 id - 22679 + 22848 name - 22679 + 22848 kind - 22679 + 22848 size - 3239 + 3264 sign - 1388 + 1398 alignment - 2314 + 2331 @@ -19644,7 +19644,7 @@ 1 2 - 22679 + 22848 @@ -19660,7 +19660,7 @@ 1 2 - 22679 + 22848 @@ -19676,7 +19676,7 @@ 1 2 - 22679 + 22848 @@ -19692,7 +19692,7 @@ 1 2 - 22679 + 22848 @@ -19708,7 +19708,7 @@ 1 2 - 22679 + 22848 @@ -19724,7 +19724,7 @@ 1 2 - 22679 + 22848 @@ -19740,7 +19740,7 @@ 1 2 - 22679 + 22848 @@ -19756,7 +19756,7 @@ 1 2 - 22679 + 22848 @@ -19772,7 +19772,7 @@ 1 2 - 22679 + 22848 @@ -19788,7 +19788,7 @@ 1 2 - 22679 + 22848 @@ -19804,7 +19804,7 @@ 1 2 - 22679 + 22848 @@ -19820,7 +19820,7 @@ 1 2 - 22679 + 22848 @@ -19836,7 +19836,7 @@ 1 2 - 22679 + 22848 @@ -19852,7 +19852,7 @@ 1 2 - 22679 + 22848 @@ -19868,7 +19868,7 @@ 1 2 - 22679 + 22848 @@ -19884,32 +19884,32 @@ 1 2 - 462 + 466 3 4 - 462 + 466 5 6 - 462 + 466 7 8 - 462 + 466 10 11 - 925 + 932 13 14 - 462 + 466 @@ -19925,32 +19925,32 @@ 1 2 - 462 + 466 3 4 - 462 + 466 5 6 - 462 + 466 7 8 - 462 + 466 10 11 - 925 + 932 13 14 - 462 + 466 @@ -19966,32 +19966,32 @@ 1 2 - 462 + 466 3 4 - 462 + 466 5 6 - 462 + 466 7 8 - 462 + 466 10 11 - 925 + 932 13 14 - 462 + 466 @@ -20007,12 +20007,12 @@ 1 2 - 925 + 932 3 4 - 2314 + 2331 @@ -20028,12 +20028,12 @@ 1 2 - 1851 + 1865 2 3 - 1388 + 1398 @@ -20049,17 +20049,17 @@ 6 7 - 462 + 466 12 13 - 462 + 466 31 32 - 462 + 466 @@ -20075,17 +20075,17 @@ 6 7 - 462 + 466 12 13 - 462 + 466 31 32 - 462 + 466 @@ -20101,17 +20101,17 @@ 6 7 - 462 + 466 12 13 - 462 + 466 31 32 - 462 + 466 @@ -20127,12 +20127,12 @@ 5 6 - 925 + 932 7 8 - 462 + 466 @@ -20148,7 +20148,7 @@ 5 6 - 1388 + 1398 @@ -20164,27 +20164,27 @@ 6 7 - 462 + 466 8 9 - 462 + 466 10 11 - 462 + 466 12 13 - 462 + 466 13 14 - 462 + 466 @@ -20200,27 +20200,27 @@ 6 7 - 462 + 466 8 9 - 462 + 466 10 11 - 462 + 466 12 13 - 462 + 466 13 14 - 462 + 466 @@ -20236,27 +20236,27 @@ 6 7 - 462 + 466 8 9 - 462 + 466 10 11 - 462 + 466 12 13 - 462 + 466 13 14 - 462 + 466 @@ -20272,7 +20272,7 @@ 2 3 - 2314 + 2331 @@ -20288,7 +20288,7 @@ 3 4 - 2314 + 2331 @@ -20298,23 +20298,23 @@ derivedtypes - 4324912 + 4327233 id - 4324912 + 4327233 name - 2161067 + 2151026 kind - 2777 + 2797 type_id - 2666967 + 2670947 @@ -20328,7 +20328,7 @@ 1 2 - 4324912 + 4327233 @@ -20344,7 +20344,7 @@ 1 2 - 4324912 + 4327233 @@ -20360,7 +20360,7 @@ 1 2 - 4324912 + 4327233 @@ -20376,17 +20376,17 @@ 1 2 - 1901406 + 1889434 2 5 - 162924 + 164602 5 - 1167 - 96736 + 1165 + 96989 @@ -20402,12 +20402,12 @@ 1 2 - 2160141 + 2150094 2 3 - 925 + 932 @@ -20423,17 +20423,17 @@ 1 2 - 1901406 + 1889434 2 5 - 162924 + 164602 5 - 1149 - 96736 + 1147 + 96989 @@ -20449,32 +20449,32 @@ 236 237 - 462 + 466 - 1085 - 1086 - 462 + 1072 + 1073 + 466 - 1148 - 1149 - 462 + 1146 + 1147 + 466 - 1221 - 1222 - 462 + 1217 + 1218 + 466 - 2177 - 2178 - 462 + 2164 + 2165 + 466 - 3477 - 3478 - 462 + 3445 + 3446 + 466 @@ -20490,32 +20490,32 @@ 1 2 - 462 + 466 201 202 - 462 + 466 - 610 - 611 - 462 + 606 + 607 + 466 - 768 - 769 - 462 + 755 + 756 + 466 - 1136 - 1137 - 462 + 1123 + 1124 + 466 - 1955 - 1956 - 462 + 1929 + 1930 + 466 @@ -20531,32 +20531,32 @@ 84 85 - 462 + 466 - 1085 - 1086 - 462 + 1072 + 1073 + 466 - 1148 - 1149 - 462 + 1146 + 1147 + 466 - 1221 - 1222 - 462 + 1217 + 1218 + 466 - 2132 - 2133 - 462 + 2119 + 2120 + 466 - 3477 - 3478 - 462 + 3445 + 3446 + 466 @@ -20572,22 +20572,22 @@ 1 2 - 1649150 + 1652555 2 3 - 558202 + 561421 3 4 - 354083 + 351587 4 72 - 105530 + 105383 @@ -20603,22 +20603,22 @@ 1 2 - 1660259 + 1663746 2 3 - 550796 + 553960 3 4 - 351306 + 348789 4 72 - 104605 + 104450 @@ -20634,22 +20634,22 @@ 1 2 - 1653316 + 1656752 2 3 - 561905 + 565151 3 4 - 353157 + 350655 4 6 - 98588 + 98388 @@ -20659,19 +20659,19 @@ pointerishsize - 3208044 + 3208121 id - 3208044 + 3208121 size - 462 + 466 alignment - 462 + 466 @@ -20685,7 +20685,7 @@ 1 2 - 3208044 + 3208121 @@ -20701,7 +20701,7 @@ 1 2 - 3208044 + 3208121 @@ -20715,9 +20715,9 @@ 12 - 6931 - 6932 - 462 + 6880 + 6881 + 466 @@ -20733,7 +20733,7 @@ 1 2 - 462 + 466 @@ -20747,9 +20747,9 @@ 12 - 6931 - 6932 - 462 + 6880 + 6881 + 466 @@ -20765,7 +20765,7 @@ 1 2 - 462 + 466 @@ -20775,23 +20775,23 @@ arraysizes - 87479 + 88130 id - 87479 + 88130 num_elements - 31474 + 31708 bytesize - 32862 + 33107 alignment - 1851 + 1865 @@ -20805,7 +20805,7 @@ 1 2 - 87479 + 88130 @@ -20821,7 +20821,7 @@ 1 2 - 87479 + 88130 @@ -20837,7 +20837,7 @@ 1 2 - 87479 + 88130 @@ -20853,27 +20853,27 @@ 1 2 - 1851 + 1865 2 3 - 23605 + 23781 3 5 - 2777 + 2797 5 13 - 2777 + 2797 13 14 - 462 + 466 @@ -20889,17 +20889,17 @@ 1 2 - 26382 + 26578 2 3 - 2314 + 2331 3 7 - 2777 + 2797 @@ -20915,17 +20915,17 @@ 1 2 - 26382 + 26578 2 3 - 2777 + 2797 3 5 - 2314 + 2331 @@ -20941,27 +20941,27 @@ 1 2 - 1851 + 1865 2 3 - 23605 + 23781 3 4 - 3239 + 3264 4 6 - 2314 + 2331 7 16 - 1851 + 1865 @@ -20977,17 +20977,17 @@ 1 2 - 27308 + 27511 2 3 - 3702 + 3730 3 5 - 1851 + 1865 @@ -21003,17 +21003,17 @@ 1 2 - 27308 + 27511 2 3 - 4628 + 4662 4 5 - 925 + 932 @@ -21029,22 +21029,22 @@ 5 6 - 462 + 466 16 17 - 462 + 466 31 32 - 462 + 466 137 138 - 462 + 466 @@ -21060,17 +21060,17 @@ 4 5 - 462 + 466 7 8 - 925 + 932 68 69 - 462 + 466 @@ -21086,22 +21086,22 @@ 4 5 - 462 + 466 7 8 - 462 + 466 8 9 - 462 + 466 68 69 - 462 + 466 @@ -21111,15 +21111,15 @@ typedefbase - 1722257 + 1722355 id - 1722257 + 1722355 type_id - 809037 + 809095 @@ -21133,7 +21133,7 @@ 1 2 - 1722257 + 1722355 @@ -21149,22 +21149,22 @@ 1 2 - 629258 + 629309 2 3 - 85024 + 85028 3 6 - 63307 + 63310 6 5437 - 31446 + 31447 @@ -21174,19 +21174,19 @@ decltypes - 172572 + 172581 id - 17342 + 17343 expr - 172572 + 172581 base_type - 10353 + 10354 parentheses_would_change_meaning @@ -21250,7 +21250,7 @@ 1 2 - 17342 + 17343 @@ -21266,7 +21266,7 @@ 1 2 - 17342 + 17343 @@ -21282,7 +21282,7 @@ 1 2 - 172572 + 172581 @@ -21298,7 +21298,7 @@ 1 2 - 172572 + 172581 @@ -21314,7 +21314,7 @@ 1 2 - 172572 + 172581 @@ -21330,7 +21330,7 @@ 1 2 - 7522 + 7523 2 @@ -21361,7 +21361,7 @@ 2 3 - 6374 + 6375 3 @@ -21402,7 +21402,7 @@ 1 2 - 10353 + 10354 @@ -21460,19 +21460,19 @@ usertypes - 5233032 + 5225787 id - 5233032 + 5225787 name - 1352460 + 1348530 kind - 5091 + 5129 @@ -21486,7 +21486,7 @@ 1 2 - 5233032 + 5225787 @@ -21502,7 +21502,7 @@ 1 2 - 5233032 + 5225787 @@ -21518,27 +21518,27 @@ 1 2 - 983565 + 979689 2 3 - 154593 + 153411 3 7 - 104605 + 104916 7 - 80 - 102290 + 59 + 101186 - 80 - 886 - 7405 + 60 + 874 + 9325 @@ -21554,17 +21554,17 @@ 1 2 - 1212215 + 1207708 2 3 - 124970 + 125900 3 7 - 15274 + 14921 @@ -21580,57 +21580,57 @@ 6 7 - 462 + 466 10 11 - 462 + 466 26 27 - 462 + 466 124 125 - 462 + 466 - 136 - 137 - 462 + 135 + 136 + 466 - 664 - 665 - 462 + 663 + 664 + 466 - 861 - 862 - 462 + 853 + 854 + 466 - 963 - 964 - 462 + 959 + 960 + 466 - 1761 - 1762 - 462 + 1751 + 1752 + 466 - 1869 - 1870 - 462 + 1836 + 1837 + 466 - 4886 - 4887 - 462 + 4844 + 4845 + 466 @@ -21646,57 +21646,57 @@ 5 6 - 462 + 466 6 7 - 462 + 466 14 15 - 462 + 466 30 31 - 462 + 466 - 44 - 45 - 462 + 43 + 44 + 466 - 126 - 127 - 462 + 125 + 126 + 466 - 268 - 269 - 462 + 267 + 268 + 466 - 373 - 374 - 462 + 371 + 372 + 466 438 439 - 462 + 466 - 748 - 749 - 462 + 740 + 741 + 466 - 1213 - 1214 - 462 + 1194 + 1195 + 466 @@ -21706,19 +21706,19 @@ usertypesize - 1712098 + 1703381 id - 1712098 + 1703381 size - 13422 + 13522 alignment - 2314 + 2331 @@ -21732,7 +21732,7 @@ 1 2 - 1712098 + 1703381 @@ -21748,7 +21748,7 @@ 1 2 - 1712098 + 1703381 @@ -21764,47 +21764,47 @@ 1 2 - 3239 + 3264 2 3 - 4165 + 4196 3 4 - 462 + 466 4 5 - 925 + 932 6 8 - 925 + 932 9 15 - 925 + 932 37 84 - 925 + 932 92 163 - 925 + 932 - 748 - 2506 - 925 + 740 + 2468 + 932 @@ -21820,17 +21820,17 @@ 1 2 - 10182 + 10258 2 3 - 2777 + 2797 3 4 - 462 + 466 @@ -21846,27 +21846,27 @@ 2 3 - 462 + 466 6 7 - 462 + 466 184 185 - 462 + 466 254 255 - 462 + 466 - 3253 - 3254 - 462 + 3207 + 3208 + 466 @@ -21882,27 +21882,27 @@ 1 2 - 462 + 466 2 3 - 462 + 466 3 4 - 462 + 466 9 10 - 462 + 466 22 23 - 462 + 466 @@ -21912,26 +21912,26 @@ usertype_final - 9517 + 9518 id - 9517 + 9518 usertype_uuid - 36324 + 36325 id - 36324 + 36325 uuid - 35952 + 35954 @@ -21945,7 +21945,7 @@ 1 2 - 36324 + 36325 @@ -21961,7 +21961,7 @@ 1 2 - 35581 + 35583 2 @@ -21976,15 +21976,15 @@ mangled_name - 9469077 + 9465823 id - 9469077 + 9465823 mangled_name - 3926394 + 3945802 @@ -21998,7 +21998,7 @@ 1 2 - 9469077 + 9465823 @@ -22014,22 +22014,22 @@ 1 2 - 2838223 + 2852803 2 3 - 521637 + 523184 3 6 - 331866 + 333868 6 - 886 - 234667 + 874 + 235946 @@ -22039,59 +22039,59 @@ is_pod_class - 534124 + 534147 id - 534124 + 534147 is_standard_layout_class - 1259889 + 1251540 id - 1259889 + 1251540 is_complete - 1651927 + 1642763 id - 1651927 + 1642763 is_class_template - 398517 + 397751 id - 398517 + 397751 class_instantiation - 1092099 + 1092146 to - 1090866 + 1090913 from - 70258 + 70261 @@ -22105,7 +22105,7 @@ 1 2 - 1089725 + 1089772 2 @@ -22126,7 +22126,7 @@ 1 2 - 20818 + 20819 2 @@ -22176,11 +22176,11 @@ class_template_argument - 2918517 + 2918643 type_id - 1329537 + 1329594 index @@ -22188,7 +22188,7 @@ arg_type - 856517 + 856554 @@ -22202,27 +22202,27 @@ 1 2 - 544130 + 544154 2 3 - 404524 + 404541 3 4 - 235639 + 235649 4 7 - 121139 + 121144 7 113 - 24103 + 24104 @@ -22238,22 +22238,22 @@ 1 2 - 569824 + 569849 2 3 - 416293 + 416311 3 4 - 248826 + 248837 4 113 - 94592 + 94596 @@ -22361,27 +22361,27 @@ 1 2 - 533421 + 533444 2 3 - 179086 + 179094 3 4 - 51757 + 51759 4 10 - 64333 + 64336 10 10167 - 27918 + 27920 @@ -22397,17 +22397,17 @@ 1 2 - 755700 + 755733 2 3 - 82569 + 82572 3 22 - 18247 + 18248 @@ -22417,19 +22417,19 @@ class_template_argument_value - 494791 + 494274 type_id - 305946 + 304025 index - 1851 + 1865 arg_value - 494791 + 494274 @@ -22443,17 +22443,17 @@ 1 2 - 251329 + 249002 2 3 - 52765 + 53157 3 4 - 1851 + 1865 @@ -22469,22 +22469,22 @@ 1 2 - 191621 + 188850 2 3 - 80536 + 81135 3 4 - 12034 + 12123 4 9 - 21754 + 21915 @@ -22500,22 +22500,22 @@ 18 19 - 462 + 466 92 93 - 462 + 466 - 297 - 298 - 462 + 292 + 293 + 466 - 376 - 377 - 462 + 372 + 373 + 466 @@ -22531,22 +22531,22 @@ 19 20 - 462 + 466 124 125 - 462 + 466 - 413 - 414 - 462 + 408 + 409 + 466 - 513 - 514 - 462 + 509 + 510 + 466 @@ -22562,7 +22562,7 @@ 1 2 - 494791 + 494274 @@ -22578,7 +22578,7 @@ 1 2 - 494791 + 494274 @@ -22588,15 +22588,15 @@ is_proxy_class_for - 62948 + 62950 id - 62948 + 62950 templ_param_id - 62948 + 62950 @@ -22610,7 +22610,7 @@ 1 2 - 62948 + 62950 @@ -22626,7 +22626,7 @@ 1 2 - 62948 + 62950 @@ -22636,19 +22636,19 @@ type_mentions - 4022409 + 4022590 id - 4022409 + 4022590 type_id - 197871 + 197880 location - 3988945 + 3989125 kind @@ -22666,7 +22666,7 @@ 1 2 - 4022409 + 4022590 @@ -22682,7 +22682,7 @@ 1 2 - 4022409 + 4022590 @@ -22698,7 +22698,7 @@ 1 2 - 4022409 + 4022590 @@ -22714,12 +22714,12 @@ 1 2 - 97440 + 97444 2 3 - 21697 + 21698 3 @@ -22734,22 +22734,22 @@ 5 7 - 14358 + 14359 7 12 - 15834 + 15835 12 27 - 15156 + 15157 27 8555 - 14398 + 14399 @@ -22765,12 +22765,12 @@ 1 2 - 97440 + 97444 2 3 - 21697 + 21698 3 @@ -22785,22 +22785,22 @@ 5 7 - 14358 + 14359 7 12 - 15834 + 15835 12 27 - 15156 + 15157 27 8555 - 14398 + 14399 @@ -22816,7 +22816,7 @@ 1 2 - 197871 + 197880 @@ -22832,12 +22832,12 @@ 1 2 - 3955481 + 3955660 2 3 - 33463 + 33465 @@ -22853,12 +22853,12 @@ 1 2 - 3955481 + 3955660 2 3 - 33463 + 33465 @@ -22874,7 +22874,7 @@ 1 2 - 3988945 + 3989125 @@ -22932,26 +22932,26 @@ is_function_template - 1396431 + 1401221 id - 1396431 + 1401221 function_instantiation - 907017 + 907042 to - 907017 + 907042 from - 146177 + 146181 @@ -22965,7 +22965,7 @@ 1 2 - 907017 + 907042 @@ -22981,12 +22981,12 @@ 1 2 - 101332 + 101335 2 3 - 14430 + 14431 3 @@ -22996,7 +22996,7 @@ 6 21 - 12066 + 12067 22 @@ -23011,11 +23011,11 @@ function_template_argument - 2342255 + 2342320 function_id - 1338103 + 1338140 index @@ -23023,7 +23023,7 @@ arg_type - 304985 + 304993 @@ -23037,22 +23037,22 @@ 1 2 - 682935 + 682954 2 3 - 395380 + 395391 3 4 - 189010 + 189015 4 15 - 70777 + 70779 @@ -23068,22 +23068,22 @@ 1 2 - 700577 + 700596 2 3 - 405294 + 405305 3 4 - 168828 + 168833 4 9 - 63403 + 63405 @@ -23231,27 +23231,27 @@ 1 2 - 186999 + 187004 2 3 - 44668 + 44669 3 5 - 23286 + 23287 5 16 - 23533 + 23534 16 107 - 23039 + 23040 108 @@ -23272,12 +23272,12 @@ 1 2 - 274818 + 274826 2 4 - 26038 + 26039 4 @@ -23292,11 +23292,11 @@ function_template_argument_value - 363519 + 363529 function_id - 195149 + 195155 index @@ -23304,7 +23304,7 @@ arg_value - 360873 + 360883 @@ -23318,7 +23318,7 @@ 1 2 - 185764 + 185769 2 @@ -23339,12 +23339,12 @@ 1 2 - 178319 + 178324 2 31 - 15312 + 15313 32 @@ -23487,7 +23487,7 @@ 1 2 - 358227 + 358237 2 @@ -23508,7 +23508,7 @@ 1 2 - 360873 + 360883 @@ -23518,26 +23518,26 @@ is_variable_template - 47274 + 47278 id - 47274 + 47278 variable_instantiation - 168077 + 168091 to - 168077 + 168091 from - 25729 + 25731 @@ -23551,7 +23551,7 @@ 1 2 - 168077 + 168091 @@ -23567,7 +23567,7 @@ 1 2 - 14015 + 14016 2 @@ -23607,11 +23607,11 @@ variable_template_argument - 295468 + 295493 variable_id - 159709 + 159723 index @@ -23619,7 +23619,7 @@ arg_type - 165462 + 165476 @@ -23633,17 +23633,17 @@ 1 2 - 81894 + 81901 2 3 - 49575 + 49580 3 4 - 18826 + 18827 4 @@ -23664,22 +23664,22 @@ 1 2 - 85555 + 85562 2 3 - 51876 + 51881 3 4 - 13701 + 13702 4 17 - 8576 + 8577 @@ -23807,17 +23807,17 @@ 1 2 - 133353 + 133364 2 3 - 18094 + 18095 3 15 - 12446 + 12447 17 @@ -23838,12 +23838,12 @@ 1 2 - 149564 + 149577 2 3 - 13805 + 13807 3 @@ -23858,11 +23858,11 @@ variable_template_argument_value - 11818 + 11819 variable_id - 7739 + 7740 index @@ -23870,7 +23870,7 @@ arg_value - 11818 + 11819 @@ -23993,7 +23993,7 @@ 1 2 - 11818 + 11819 @@ -24009,7 +24009,7 @@ 1 2 - 11818 + 11819 @@ -24019,15 +24019,15 @@ routinetypes - 547131 + 547147 id - 547131 + 547147 return_type - 285756 + 285764 @@ -24041,7 +24041,7 @@ 1 2 - 547131 + 547147 @@ -24057,7 +24057,7 @@ 1 2 - 248991 + 248998 2 @@ -24067,7 +24067,7 @@ 3 3594 - 15418 + 15419 @@ -24077,19 +24077,19 @@ routinetypeargs - 975697 + 982953 routine - 420271 + 423397 index - 7868 + 7927 type_id - 224947 + 226620 @@ -24103,27 +24103,27 @@ 1 2 - 151353 + 152479 2 3 - 133302 + 134293 3 4 - 62948 + 63416 4 5 - 45359 + 45697 5 18 - 27308 + 27511 @@ -24139,27 +24139,27 @@ 1 2 - 180976 + 182322 2 3 - 132839 + 133827 3 4 - 58319 + 58753 4 5 - 33325 + 33573 5 11 - 14811 + 14921 @@ -24175,67 +24175,67 @@ 2 3 - 925 + 932 4 5 - 462 + 466 6 7 - 462 + 466 8 9 - 925 + 932 9 10 - 462 + 466 10 11 - 1388 + 1398 13 14 - 462 + 466 28 29 - 462 + 466 59 60 - 462 + 466 157 158 - 462 + 466 293 294 - 462 + 466 581 582 - 462 + 466 908 909 - 462 + 466 @@ -24251,57 +24251,57 @@ 1 2 - 925 + 932 3 4 - 925 + 932 4 5 - 1388 + 1398 5 6 - 925 + 932 6 7 - 925 + 932 10 11 - 462 + 466 14 15 - 462 + 466 47 48 - 462 + 466 90 91 - 462 + 466 176 177 - 462 + 466 347 348 - 462 + 466 @@ -24317,27 +24317,27 @@ 1 2 - 145336 + 146417 2 3 - 30548 + 30775 3 5 - 16662 + 16786 5 12 - 18051 + 18185 12 111 - 14348 + 14455 @@ -24353,22 +24353,22 @@ 1 2 - 171256 + 172529 2 3 - 30548 + 30775 3 6 - 18514 + 18651 6 14 - 4628 + 4662 @@ -24378,19 +24378,19 @@ ptrtomembers - 37491 + 37770 id - 37491 + 37770 type_id - 37491 + 37770 class_id - 15274 + 15387 @@ -24404,7 +24404,7 @@ 1 2 - 37491 + 37770 @@ -24420,7 +24420,7 @@ 1 2 - 37491 + 37770 @@ -24436,7 +24436,7 @@ 1 2 - 37491 + 37770 @@ -24452,7 +24452,7 @@ 1 2 - 37491 + 37770 @@ -24468,17 +24468,17 @@ 1 2 - 13422 + 13522 8 9 - 1388 + 1398 28 29 - 462 + 466 @@ -24494,17 +24494,17 @@ 1 2 - 13422 + 13522 8 9 - 1388 + 1398 28 29 - 462 + 466 @@ -24514,15 +24514,15 @@ specifiers - 24531 + 24713 id - 24531 + 24713 str - 24531 + 24713 @@ -24536,7 +24536,7 @@ 1 2 - 24531 + 24713 @@ -24552,7 +24552,7 @@ 1 2 - 24531 + 24713 @@ -24562,15 +24562,15 @@ typespecifiers - 1287198 + 1289776 type_id - 1269147 + 1271591 spec_id - 3702 + 3730 @@ -24584,12 +24584,12 @@ 1 2 - 1251095 + 1253405 2 3 - 18051 + 18185 @@ -24605,42 +24605,42 @@ 8 9 - 462 + 466 36 37 - 462 + 466 51 52 - 462 + 466 86 87 - 462 + 466 105 106 - 462 + 466 219 220 - 462 + 466 - 223 - 224 - 462 + 221 + 222 + 466 - 2053 - 2054 - 462 + 2040 + 2041 + 466 @@ -24650,11 +24650,11 @@ funspecifiers - 12433939 + 12434284 func_id - 3820608 + 3820714 spec_id @@ -24672,27 +24672,27 @@ 1 2 - 315076 + 315085 2 3 - 545967 + 545982 3 4 - 1150998 + 1151030 4 5 - 1559292 + 1559335 5 8 - 249273 + 249280 @@ -24808,15 +24808,15 @@ varspecifiers - 2310106 + 2243353 var_id - 1234895 + 1223562 spec_id - 3702 + 3730 @@ -24830,22 +24830,22 @@ 1 2 - 723904 + 729288 2 3 - 199953 + 202372 3 4 - 57856 + 58287 4 5 - 253181 + 233614 @@ -24861,42 +24861,42 @@ 112 113 - 462 + 466 315 316 - 462 + 466 - 414 - 415 - 462 + 416 + 417 + 466 - 560 - 561 - 462 + 514 + 515 + 466 - 692 - 693 - 462 + 646 + 647 + 466 + + + 686 + 687 + 466 700 701 - 462 + 466 - 732 - 733 - 462 - - - 1466 - 1467 - 462 + 1422 + 1423 + 466 @@ -24906,11 +24906,11 @@ attributes - 737259 + 736276 id - 737259 + 736276 kind @@ -24926,7 +24926,7 @@ location - 483417 + 483459 @@ -24940,7 +24940,7 @@ 1 2 - 737259 + 736276 @@ -24956,7 +24956,7 @@ 1 2 - 737259 + 736276 @@ -24972,7 +24972,7 @@ 1 2 - 737259 + 736276 @@ -24988,7 +24988,7 @@ 1 2 - 737259 + 736276 @@ -25012,8 +25012,8 @@ 104 - 4714 - 4715 + 4704 + 4705 104 @@ -25156,8 +25156,8 @@ 104 - 1053 - 1054 + 1043 + 1044 104 @@ -25300,8 +25300,8 @@ 104 - 7026 - 7027 + 7016 + 7017 104 @@ -25381,17 +25381,17 @@ 1 2 - 425056 + 425824 2 3 - 37443 + 36923 3 201 - 20918 + 20710 @@ -25407,7 +25407,7 @@ 1 2 - 483417 + 483459 @@ -25423,7 +25423,7 @@ 1 2 - 479129 + 479170 2 @@ -25444,7 +25444,7 @@ 1 2 - 483417 + 483459 @@ -25454,27 +25454,27 @@ attribute_args - 406849 + 409874 id - 406849 + 409874 kind - 1388 + 1398 attribute - 295764 + 297963 index - 1388 + 1398 location - 324923 + 327340 @@ -25488,7 +25488,7 @@ 1 2 - 406849 + 409874 @@ -25504,7 +25504,7 @@ 1 2 - 406849 + 409874 @@ -25520,7 +25520,7 @@ 1 2 - 406849 + 409874 @@ -25536,7 +25536,7 @@ 1 2 - 406849 + 409874 @@ -25552,17 +25552,17 @@ 1 2 - 462 + 466 84 85 - 462 + 466 794 795 - 462 + 466 @@ -25578,17 +25578,17 @@ 1 2 - 462 + 466 84 85 - 462 + 466 606 607 - 462 + 466 @@ -25604,12 +25604,12 @@ 1 2 - 925 + 932 3 4 - 462 + 466 @@ -25625,17 +25625,17 @@ 1 2 - 462 + 466 54 55 - 462 + 466 674 675 - 462 + 466 @@ -25651,17 +25651,17 @@ 1 2 - 214301 + 215895 2 3 - 51839 + 52225 3 4 - 29622 + 29842 @@ -25677,12 +25677,12 @@ 1 2 - 271695 + 273716 2 3 - 24068 + 24247 @@ -25698,17 +25698,17 @@ 1 2 - 214301 + 215895 2 3 - 51839 + 52225 3 4 - 29622 + 29842 @@ -25724,17 +25724,17 @@ 1 2 - 214301 + 215895 2 3 - 51839 + 52225 3 4 - 29622 + 29842 @@ -25750,17 +25750,17 @@ 64 65 - 462 + 466 176 177 - 462 + 466 639 640 - 462 + 466 @@ -25776,12 +25776,12 @@ 1 2 - 925 + 932 3 4 - 462 + 466 @@ -25797,17 +25797,17 @@ 64 65 - 462 + 466 176 177 - 462 + 466 639 640 - 462 + 466 @@ -25823,17 +25823,17 @@ 34 35 - 462 + 466 140 141 - 462 + 466 528 529 - 462 + 466 @@ -25849,22 +25849,22 @@ 1 2 - 276786 + 278845 2 3 - 23142 + 23314 3 9 - 24531 + 24713 17 18 - 462 + 466 @@ -25880,12 +25880,12 @@ 1 2 - 312426 + 314750 2 3 - 12497 + 12590 @@ -25901,22 +25901,22 @@ 1 2 - 276786 + 278845 2 3 - 23142 + 23314 3 9 - 24531 + 24713 17 18 - 462 + 466 @@ -25932,7 +25932,7 @@ 1 2 - 324923 + 327340 @@ -25942,15 +25942,15 @@ attribute_arg_value - 38879 + 39168 arg - 38879 + 39168 value - 15737 + 15854 @@ -25964,7 +25964,7 @@ 1 2 - 38879 + 39168 @@ -25980,12 +25980,12 @@ 1 2 - 14348 + 14455 2 34 - 1388 + 1398 @@ -25995,15 +25995,15 @@ attribute_arg_type - 462 + 466 arg - 462 + 466 type_id - 462 + 466 @@ -26017,7 +26017,7 @@ 1 2 - 462 + 466 @@ -26033,7 +26033,7 @@ 1 2 - 462 + 466 @@ -26043,15 +26043,15 @@ attribute_arg_constant - 367506 + 370239 arg - 367506 + 370239 constant - 367506 + 370239 @@ -26065,7 +26065,7 @@ 1 2 - 367506 + 370239 @@ -26081,7 +26081,7 @@ 1 2 - 367506 + 370239 @@ -26144,15 +26144,15 @@ typeattributes - 85973 + 84934 type_id - 62022 + 62027 spec_id - 85973 + 84934 @@ -26166,17 +26166,17 @@ 1 2 - 55014 + 56065 2 - 3 - 5124 + 4 + 4288 - 3 + 12 13 - 1882 + 1673 @@ -26192,7 +26192,7 @@ 1 2 - 85973 + 84934 @@ -26202,15 +26202,15 @@ funcattributes - 647729 + 651416 func_id - 592401 + 442981 spec_id - 647729 + 651416 @@ -26224,12 +26224,22 @@ 1 2 - 554330 + 334334 2 - 7 - 38070 + 3 + 65281 + + + 3 + 6 + 34972 + + + 6 + 9 + 8393 @@ -26245,7 +26255,7 @@ 1 2 - 647729 + 651416 @@ -26361,15 +26371,15 @@ unspecifiedtype - 10141141 + 10137757 type_id - 10141141 + 10137757 unspecified_type_id - 6821549 + 6813527 @@ -26383,7 +26393,7 @@ 1 2 - 10141141 + 10137757 @@ -26399,17 +26409,17 @@ 1 2 - 4593830 + 4583230 2 3 - 1991662 + 1993418 3 - 147 - 236055 + 145 + 236878 @@ -26419,11 +26429,11 @@ member - 4925739 + 4925876 parent - 618791 + 618808 index @@ -26431,7 +26441,7 @@ child - 4880436 + 4880571 @@ -26445,42 +26455,42 @@ 1 3 - 18911 + 18912 3 4 - 320333 + 320342 4 5 - 38281 + 38283 5 7 - 53136 + 53137 7 10 - 52924 + 52925 10 15 - 50313 + 50314 15 24 - 49607 + 49609 24 251 - 35282 + 35283 @@ -26496,42 +26506,42 @@ 1 3 - 18911 + 18912 3 4 - 320262 + 320271 4 5 - 38317 + 38318 5 7 - 53241 + 53243 7 10 - 53277 + 53278 10 15 - 49925 + 49926 15 24 - 49678 + 49679 24 255 - 35177 + 35178 @@ -26689,7 +26699,7 @@ 1 2 - 4880436 + 4880571 @@ -26705,12 +26715,12 @@ 1 2 - 4836508 + 4836643 2 8 - 43927 + 43928 @@ -26720,15 +26730,15 @@ enclosingfunction - 121346 + 121352 child - 121346 + 121352 parent - 69278 + 69281 @@ -26742,7 +26752,7 @@ 1 2 - 121346 + 121352 @@ -26758,12 +26768,12 @@ 1 2 - 36575 + 36577 2 3 - 21521 + 21522 3 @@ -26783,15 +26793,15 @@ derivations - 368247 + 368257 derivation - 368247 + 368257 sub - 347712 + 347722 index @@ -26799,11 +26809,11 @@ super - 203864 + 203870 location - 38211 + 38212 @@ -26817,7 +26827,7 @@ 1 2 - 368247 + 368257 @@ -26833,7 +26843,7 @@ 1 2 - 368247 + 368257 @@ -26849,7 +26859,7 @@ 1 2 - 368247 + 368257 @@ -26865,7 +26875,7 @@ 1 2 - 368247 + 368257 @@ -26881,12 +26891,12 @@ 1 2 - 332541 + 332550 2 7 - 15171 + 15172 @@ -26902,12 +26912,12 @@ 1 2 - 332541 + 332550 2 7 - 15171 + 15172 @@ -26923,12 +26933,12 @@ 1 2 - 332541 + 332550 2 7 - 15171 + 15172 @@ -26944,12 +26954,12 @@ 1 2 - 332541 + 332550 2 7 - 15171 + 15172 @@ -27094,12 +27104,12 @@ 1 2 - 196525 + 196531 2 1216 - 7338 + 7339 @@ -27115,12 +27125,12 @@ 1 2 - 196525 + 196531 2 1216 - 7338 + 7339 @@ -27136,7 +27146,7 @@ 1 2 - 203405 + 203411 2 @@ -27157,7 +27167,7 @@ 1 2 - 200265 + 200271 2 @@ -27250,7 +27260,7 @@ 1 2 - 38211 + 38212 @@ -27266,7 +27276,7 @@ 1 2 - 31119 + 31120 2 @@ -27291,11 +27301,11 @@ derspecifiers - 370152 + 370163 der_id - 367859 + 367869 spec_id @@ -27313,7 +27323,7 @@ 1 2 - 365566 + 365576 2 @@ -27359,11 +27369,11 @@ direct_base_offsets - 338927 + 338936 der_id - 338927 + 338936 offset @@ -27381,7 +27391,7 @@ 1 2 - 338927 + 338936 @@ -27723,23 +27733,23 @@ frienddecls - 716101 + 716121 id - 716101 + 716121 type_id - 42445 + 42446 decl_id - 70283 + 70285 location - 6350 + 6351 @@ -27753,7 +27763,7 @@ 1 2 - 716101 + 716121 @@ -27769,7 +27779,7 @@ 1 2 - 716101 + 716121 @@ -27785,7 +27795,7 @@ 1 2 - 716101 + 716121 @@ -27913,7 +27923,7 @@ 1 2 - 40998 + 40999 2 @@ -27934,7 +27944,7 @@ 1 2 - 40540 + 40541 2 @@ -27980,7 +27990,7 @@ 1 2 - 40540 + 40541 2 @@ -28026,7 +28036,7 @@ 1 2 - 69613 + 69615 2 @@ -28104,19 +28114,19 @@ comments - 8773481 + 8774227 id - 8773481 + 8774227 contents - 3339997 + 3340281 location - 8773481 + 8774227 @@ -28130,7 +28140,7 @@ 1 2 - 8773481 + 8774227 @@ -28146,7 +28156,7 @@ 1 2 - 8773481 + 8774227 @@ -28162,17 +28172,17 @@ 1 2 - 3055511 + 3055770 2 7 - 250912 + 250934 7 32784 - 33573 + 33576 @@ -28188,17 +28198,17 @@ 1 2 - 3055511 + 3055770 2 7 - 250912 + 250934 7 32784 - 33573 + 33576 @@ -28214,7 +28224,7 @@ 1 2 - 8773481 + 8774227 @@ -28230,7 +28240,7 @@ 1 2 - 8773481 + 8774227 @@ -28240,15 +28250,15 @@ commentbinding - 3095107 + 3089682 id - 2450351 + 2444793 element - 3019199 + 3013209 @@ -28262,12 +28272,12 @@ 1 2 - 2369352 + 2367854 2 97 - 80999 + 76938 @@ -28283,12 +28293,12 @@ 1 2 - 2943291 + 2936736 2 3 - 75908 + 76472 @@ -28298,15 +28308,15 @@ exprconv - 7021833 + 7022151 converted - 7021833 + 7022151 conversion - 7021833 + 7022151 @@ -28320,7 +28330,7 @@ 1 2 - 7021833 + 7022151 @@ -28336,7 +28346,7 @@ 1 2 - 7021833 + 7022151 @@ -28346,22 +28356,22 @@ compgenerated - 8328174 + 8328406 id - 8328174 + 8328406 synthetic_destructor_call - 144282 + 144289 element - 111735 + 111741 i @@ -28369,7 +28379,7 @@ destructor_call - 129058 + 129064 @@ -28383,7 +28393,7 @@ 1 2 - 92037 + 92041 2 @@ -28409,7 +28419,7 @@ 1 2 - 92037 + 92041 2 @@ -28587,7 +28597,7 @@ 1 2 - 127019 + 127025 2 @@ -28608,7 +28618,7 @@ 1 2 - 129058 + 129064 @@ -28618,15 +28628,15 @@ namespaces - 12497 + 12123 id - 12497 + 12123 name - 10182 + 9792 @@ -28640,7 +28650,7 @@ 1 2 - 12497 + 12123 @@ -28656,17 +28666,17 @@ 1 2 - 8794 + 8393 2 3 - 462 + 466 3 4 - 925 + 932 @@ -28676,26 +28686,26 @@ namespace_inline - 1388 + 1398 id - 1388 + 1398 namespacembrs - 2390180 + 2382776 parentid - 10645 + 10258 memberid - 2390180 + 2382776 @@ -28709,57 +28719,52 @@ 1 2 - 1851 + 1865 2 - 3 - 925 - - - 3 4 - 462 + 932 4 5 - 925 + 932 5 7 - 925 + 932 7 8 - 925 + 932 8 12 - 925 + 932 17 30 - 925 + 932 43 47 - 925 + 932 52 143 - 925 + 932 - 253 - 4520 - 925 + 255 + 4466 + 932 @@ -28775,7 +28780,7 @@ 1 2 - 2390180 + 2382776 @@ -28785,19 +28790,19 @@ exprparents - 14182800 + 14183439 expr_id - 14182800 + 14183439 child_index - 14633 + 14634 parent_id - 9437908 + 9438333 @@ -28811,7 +28816,7 @@ 1 2 - 14182800 + 14183439 @@ -28827,7 +28832,7 @@ 1 2 - 14182800 + 14183439 @@ -28945,17 +28950,17 @@ 1 2 - 5400330 + 5400574 2 3 - 3700403 + 3700570 3 712 - 337173 + 337189 @@ -28971,17 +28976,17 @@ 1 2 - 5400330 + 5400574 2 3 - 3700403 + 3700570 3 712 - 337173 + 337189 @@ -28991,22 +28996,22 @@ expr_isload - 4981532 + 4981760 expr_id - 4981532 + 4981760 conversionkinds - 4220624 + 4220723 expr_id - 4220624 + 4220723 kind @@ -29024,7 +29029,7 @@ 1 2 - 4220624 + 4220723 @@ -29063,8 +29068,8 @@ 1 - 4131034 - 4131035 + 4131133 + 4131134 1 @@ -29075,11 +29080,11 @@ iscall - 2950586 + 2950725 caller - 2950586 + 2950725 kind @@ -29097,7 +29102,7 @@ 1 2 - 2950586 + 2950725 @@ -29133,11 +29138,11 @@ numtemplatearguments - 396226 + 396237 expr_id - 396226 + 396237 num @@ -29155,7 +29160,7 @@ 1 2 - 396226 + 396237 @@ -29211,15 +29216,15 @@ specialnamequalifyingelements - 462 + 466 id - 462 + 466 name - 462 + 466 @@ -29233,7 +29238,7 @@ 1 2 - 462 + 466 @@ -29249,7 +29254,7 @@ 1 2 - 462 + 466 @@ -29259,23 +29264,23 @@ namequalifiers - 1533160 + 1533233 id - 1533160 + 1533233 qualifiableelement - 1533160 + 1533233 qualifyingelement - 83386 + 83409 location - 305907 + 305921 @@ -29289,7 +29294,7 @@ 1 2 - 1533160 + 1533233 @@ -29305,7 +29310,7 @@ 1 2 - 1533160 + 1533233 @@ -29321,7 +29326,7 @@ 1 2 - 1533160 + 1533233 @@ -29337,7 +29342,7 @@ 1 2 - 1533160 + 1533233 @@ -29353,7 +29358,7 @@ 1 2 - 1533160 + 1533233 @@ -29369,7 +29374,7 @@ 1 2 - 1533160 + 1533233 @@ -29385,12 +29390,12 @@ 1 2 - 46602 + 46624 2 3 - 20589 + 20590 3 @@ -29421,12 +29426,12 @@ 1 2 - 46602 + 46624 2 3 - 20589 + 20590 3 @@ -29457,12 +29462,12 @@ 1 2 - 50938 + 50960 2 3 - 19500 + 19501 3 @@ -29472,7 +29477,7 @@ 4 8 - 6275 + 6276 8 @@ -29493,32 +29498,32 @@ 1 2 - 98214 + 98218 2 3 - 27458 + 27460 3 4 - 45870 + 45872 4 6 - 14075 + 14076 6 7 - 98847 + 98852 7 790 - 21440 + 21441 @@ -29534,32 +29539,32 @@ 1 2 - 98214 + 98218 2 3 - 27458 + 27460 3 4 - 45870 + 45872 4 6 - 14075 + 14076 6 7 - 98847 + 98852 7 790 - 21440 + 21441 @@ -29575,22 +29580,22 @@ 1 2 - 134344 + 134350 2 3 - 56818 + 56820 3 4 - 105935 + 105940 4 143 - 8809 + 8810 @@ -29600,15 +29605,15 @@ varbind - 6019061 + 6019333 expr - 6019061 + 6019333 var - 767247 + 767282 @@ -29622,7 +29627,7 @@ 1 2 - 6019061 + 6019333 @@ -29638,52 +29643,52 @@ 1 2 - 126011 + 126016 2 3 - 137644 + 137650 3 4 - 106115 + 106120 4 5 - 85069 + 85073 5 6 - 61186 + 61189 6 7 - 48032 + 48034 7 9 - 59521 + 59524 9 13 - 59172 + 59175 13 28 - 58781 + 58784 28 5137 - 25711 + 25713 @@ -29693,15 +29698,15 @@ funbind - 2953714 + 2953853 expr - 2950903 + 2951042 fun - 533714 + 533740 @@ -29715,7 +29720,7 @@ 1 2 - 2948091 + 2948231 2 @@ -29736,27 +29741,27 @@ 1 2 - 329684 + 329699 2 3 - 82178 + 82182 3 4 - 31853 + 31855 4 7 - 48067 + 48070 7 158 - 40030 + 40031 159 @@ -29771,11 +29776,11 @@ expr_allocator - 46608 + 46609 expr - 46608 + 46609 func @@ -29797,7 +29802,7 @@ 1 2 - 46608 + 46609 @@ -29813,7 +29818,7 @@ 1 2 - 46608 + 46609 @@ -29897,11 +29902,11 @@ expr_deallocator - 55394 + 55395 expr - 55394 + 55395 func @@ -29923,7 +29928,7 @@ 1 2 - 55394 + 55395 @@ -29939,7 +29944,7 @@ 1 2 - 55394 + 55395 @@ -30044,15 +30049,15 @@ expr_cond_guard - 656192 + 656221 cond - 656192 + 656221 guard - 656192 + 656221 @@ -30066,7 +30071,7 @@ 1 2 - 656192 + 656221 @@ -30082,7 +30087,7 @@ 1 2 - 656192 + 656221 @@ -30092,15 +30097,15 @@ expr_cond_true - 656189 + 656219 cond - 656189 + 656219 true - 656189 + 656219 @@ -30114,7 +30119,7 @@ 1 2 - 656189 + 656219 @@ -30130,7 +30135,7 @@ 1 2 - 656189 + 656219 @@ -30140,15 +30145,15 @@ expr_cond_false - 656192 + 656221 cond - 656192 + 656221 false - 656192 + 656221 @@ -30162,7 +30167,7 @@ 1 2 - 656192 + 656221 @@ -30178,7 +30183,7 @@ 1 2 - 656192 + 656221 @@ -30188,15 +30193,15 @@ values - 10758747 + 10759232 id - 10758747 + 10759232 str - 87858 + 87862 @@ -30210,7 +30215,7 @@ 1 2 - 10758747 + 10759232 @@ -30226,17 +30231,17 @@ 1 2 - 59403 + 59406 2 3 - 12367 + 12368 3 6 - 6920 + 6921 6 @@ -30256,15 +30261,15 @@ valuetext - 4757155 + 4757293 id - 4757155 + 4757293 text - 703935 + 703959 @@ -30278,7 +30283,7 @@ 1 2 - 4757155 + 4757293 @@ -30294,21 +30299,21 @@ 1 2 - 527534 + 527546 2 3 - 102488 + 102496 3 7 - 56764 + 56768 7 - 425881 + 425884 17149 @@ -30319,15 +30324,15 @@ valuebind - 11192235 + 11192739 val - 10758747 + 10759232 expr - 11192235 + 11192739 @@ -30341,12 +30346,12 @@ 1 2 - 10347766 + 10348232 2 7 - 410981 + 410999 @@ -30362,7 +30367,7 @@ 1 2 - 11192235 + 11192739 @@ -30372,15 +30377,15 @@ fieldoffsets - 1052936 + 1052983 id - 1052936 + 1052983 byteoffset - 22654 + 22655 bitoffset @@ -30398,7 +30403,7 @@ 1 2 - 1052936 + 1052983 @@ -30414,7 +30419,7 @@ 1 2 - 1052936 + 1052983 @@ -30430,7 +30435,7 @@ 1 2 - 13002 + 13003 2 @@ -30476,7 +30481,7 @@ 1 2 - 21976 + 21977 2 @@ -30573,11 +30578,11 @@ bitfield - 20918 + 20919 id - 20918 + 20919 bits @@ -30599,7 +30604,7 @@ 1 2 - 20918 + 20919 @@ -30615,7 +30620,7 @@ 1 2 - 20918 + 20919 @@ -30759,23 +30764,23 @@ initialisers - 1699633 + 1699706 init - 1699633 + 1699706 var - 722291 + 722379 expr - 1699633 + 1699706 location - 391082 + 391099 @@ -30789,7 +30794,7 @@ 1 2 - 1699633 + 1699706 @@ -30805,7 +30810,7 @@ 1 2 - 1699633 + 1699706 @@ -30821,7 +30826,7 @@ 1 2 - 1699633 + 1699706 @@ -30837,17 +30842,17 @@ 1 2 - 634099 + 634183 2 16 - 31491 + 31492 16 25 - 56701 + 56703 @@ -30863,17 +30868,17 @@ 1 2 - 634099 + 634183 2 16 - 31491 + 31492 16 25 - 56701 + 56703 @@ -30889,7 +30894,7 @@ 1 2 - 722285 + 722373 2 @@ -30910,7 +30915,7 @@ 1 2 - 1699633 + 1699706 @@ -30926,7 +30931,7 @@ 1 2 - 1699633 + 1699706 @@ -30942,7 +30947,7 @@ 1 2 - 1699633 + 1699706 @@ -30958,22 +30963,22 @@ 1 2 - 318704 + 318718 2 3 - 23863 + 23864 3 15 - 30666 + 30667 15 111551 - 17847 + 17848 @@ -30989,17 +30994,17 @@ 1 2 - 341391 + 341406 2 4 - 35638 + 35639 4 - 12805 - 14052 + 12811 + 14053 @@ -31015,22 +31020,22 @@ 1 2 - 318704 + 318718 2 3 - 23863 + 23864 3 15 - 30666 + 30667 15 111551 - 17847 + 17848 @@ -31040,26 +31045,26 @@ braced_initialisers - 41632 + 41634 init - 41632 + 41634 expr_ancestor - 133354 + 133360 exp - 133354 + 133360 ancestor - 92928 + 92932 @@ -31073,7 +31078,7 @@ 1 2 - 133354 + 133360 @@ -31089,12 +31094,12 @@ 1 2 - 67112 + 67115 2 3 - 18431 + 18432 3 @@ -31114,11 +31119,11 @@ exprs - 18356809 + 18357636 id - 18356809 + 18357636 kind @@ -31126,7 +31131,7 @@ location - 3592504 + 3592604 @@ -31140,7 +31145,7 @@ 1 2 - 18356809 + 18357636 @@ -31156,7 +31161,7 @@ 1 2 - 18356809 + 18357636 @@ -31206,7 +31211,7 @@ 653 - 830 + 832 282 @@ -31296,8 +31301,8 @@ 282 - 468 - 1019 + 469 + 1020 282 @@ -31324,31 +31329,31 @@ 1 2 - 1941829 + 1941777 2 3 - 838392 + 838486 3 4 - 247121 + 247163 4 8 - 284556 + 284529 8 155 - 269490 + 269533 155 - 53479 + 53477 11114 @@ -31365,22 +31370,22 @@ 1 2 - 2392674 + 2392776 2 3 - 875968 + 875922 3 6 - 306925 + 306969 6 - 26 - 16935 + 25 + 16936 @@ -31390,15 +31395,15 @@ expr_types - 18411726 + 18412556 id - 18356809 + 18357636 typeid - 880959 + 881000 value_category @@ -31416,12 +31421,12 @@ 1 2 - 18301891 + 18302715 2 3 - 54917 + 54920 @@ -31437,7 +31442,7 @@ 1 2 - 18356809 + 18357636 @@ -31453,42 +31458,42 @@ 1 2 - 316756 + 316771 2 3 - 172216 + 172204 3 4 - 69369 + 69372 4 5 - 68261 + 68284 5 7 - 69765 + 69729 7 12 - 69864 + 69828 12 35 - 66875 + 66898 35 - 73135 - 47850 + 73134 + 47911 @@ -31504,12 +31509,12 @@ 1 2 - 757899 + 757935 2 3 - 111834 + 111840 3 @@ -31533,13 +31538,13 @@ 19 - 235367 - 235368 + 235356 + 235357 19 - 684712 - 684713 + 684721 + 684722 19 @@ -31576,11 +31581,11 @@ new_allocated_type - 47667 + 47668 expr - 47667 + 47668 type_id @@ -31598,7 +31603,7 @@ 1 2 - 47667 + 47668 @@ -31619,7 +31624,7 @@ 2 3 - 14924 + 14925 3 @@ -31711,6 +31716,10 @@ field 2156 + + position + 41 + @@ -31805,6 +31814,52 @@ + + aggregate + position + + + 12 + + + 1 + 2 + 6503 + + + 2 + 3 + 500733 + + + 3 + 4 + 11095 + + + 4 + 5 + 88743 + + + 5 + 12 + 49719 + + + 12 + 13 + 190968 + + + 13 + 42 + 192 + + + + + initializer aggregate @@ -31842,6 +31897,22 @@ + + initializer + position + + + 12 + + + 1 + 2 + 4005406 + + + + + field aggregate @@ -31964,6 +32035,195 @@ + + field + position + + + 12 + + + 1 + 2 + 2153 + + + 2 + 3 + 3 + + + + + + + position + aggregate + + + 12 + + + 2 + 3 + 13 + + + 3 + 4 + 5 + + + 49 + 50 + 3 + + + 50 + 51 + 5 + + + 72 + 193 + 3 + + + 191160 + 194827 + 3 + + + 194928 + 206244 + 3 + + + 217398 + 329623 + 3 + + + 340717 + 847954 + 3 + + + + + + + position + initializer + + + 12 + + + 2 + 3 + 13 + + + 3 + 4 + 5 + + + 49 + 50 + 3 + + + 50 + 51 + 5 + + + 72 + 193 + 3 + + + 191160 + 194827 + 3 + + + 194928 + 206244 + 3 + + + 217398 + 329623 + 3 + + + 340717 + 847954 + 3 + + + + + + + position + field + + + 12 + + + 1 + 2 + 13 + + + 2 + 3 + 5 + + + 3 + 4 + 3 + + + 4 + 5 + 5 + + + 6 + 11 + 3 + + + 14 + 27 + 3 + + + 33 + 66 + 3 + + + 90 + 174 + 3 + + + 248 + 655 + 3 + + + + + @@ -31982,6 +32242,10 @@ element_index 17485 + + position + 17485 + @@ -32096,6 +32360,62 @@ + + aggregate + position + + + 12 + + + 1 + 2 + 7521 + + + 2 + 3 + 7791 + + + 3 + 4 + 17335 + + + 4 + 5 + 8012 + + + 5 + 6 + 5810 + + + 6 + 8 + 5006 + + + 8 + 11 + 5381 + + + 11 + 22 + 4985 + + + 22 + 17486 + 3774 + + + + + initializer aggregate @@ -32128,6 +32448,22 @@ + + initializer + position + + + 12 + + + 1 + 2 + 730401 + + + + + element_index aggregate @@ -32240,19 +32576,163 @@ + + element_index + position + + + 12 + + + 1 + 2 + 17485 + + + + + + + position + aggregate + + + 12 + + + 1 + 2 + 6580 + + + 2 + 3 + 2653 + + + 3 + 5 + 1308 + + + 5 + 6 + 1488 + + + 7 + 9 + 1059 + + + 9 + 15 + 1388 + + + 15 + 27 + 1379 + + + 27 + 198 + 1316 + + + 202 + 65616 + 314 + + + + + + + position + initializer + + + 12 + + + 1 + 2 + 6580 + + + 2 + 3 + 2653 + + + 3 + 5 + 1308 + + + 5 + 6 + 1488 + + + 7 + 9 + 1059 + + + 9 + 15 + 1388 + + + 15 + 27 + 1379 + + + 27 + 198 + 1316 + + + 202 + 65616 + 314 + + + + + + + position + element_index + + + 12 + + + 1 + 2 + 17485 + + + + + condition_decl_bind - 42425 + 42427 expr - 42425 + 42427 decl - 42425 + 42427 @@ -32266,7 +32746,7 @@ 1 2 - 42425 + 42427 @@ -32282,7 +32762,7 @@ 1 2 - 42425 + 42427 @@ -32292,15 +32772,15 @@ typeid_bind - 36482 + 36483 expr - 36482 + 36483 type_id - 16406 + 16407 @@ -32314,7 +32794,7 @@ 1 2 - 36482 + 36483 @@ -32345,15 +32825,15 @@ uuidof_bind - 20119 + 20120 expr - 20119 + 20120 type_id - 19924 + 19925 @@ -32367,7 +32847,7 @@ 1 2 - 20119 + 20120 @@ -32383,7 +32863,7 @@ 1 2 - 19760 + 19761 2 @@ -32398,15 +32878,15 @@ sizeof_bind - 198852 + 198861 expr - 198852 + 198861 type_id - 8167 + 8168 @@ -32420,7 +32900,7 @@ 1 2 - 198852 + 198861 @@ -32529,19 +33009,19 @@ lambdas - 21291 + 21449 expr - 21291 + 21449 default_capture - 462 + 466 has_explicit_return_type - 462 + 466 @@ -32555,7 +33035,7 @@ 1 2 - 21291 + 21449 @@ -32571,7 +33051,7 @@ 1 2 - 21291 + 21449 @@ -32587,7 +33067,7 @@ 46 47 - 462 + 466 @@ -32603,7 +33083,7 @@ 1 2 - 462 + 466 @@ -32619,7 +33099,7 @@ 46 47 - 462 + 466 @@ -32635,7 +33115,7 @@ 1 2 - 462 + 466 @@ -32645,35 +33125,35 @@ lambda_capture - 27771 + 27977 id - 27771 + 27977 lambda - 20365 + 20517 index - 925 + 932 field - 27771 + 27977 captured_by_reference - 462 + 466 is_implicit - 462 + 466 location - 2777 + 2797 @@ -32687,7 +33167,7 @@ 1 2 - 27771 + 27977 @@ -32703,7 +33183,7 @@ 1 2 - 27771 + 27977 @@ -32719,7 +33199,7 @@ 1 2 - 27771 + 27977 @@ -32735,7 +33215,7 @@ 1 2 - 27771 + 27977 @@ -32751,7 +33231,7 @@ 1 2 - 27771 + 27977 @@ -32767,7 +33247,7 @@ 1 2 - 27771 + 27977 @@ -32783,12 +33263,12 @@ 1 2 - 12959 + 13056 2 3 - 7405 + 7460 @@ -32804,12 +33284,12 @@ 1 2 - 12959 + 13056 2 3 - 7405 + 7460 @@ -32825,12 +33305,12 @@ 1 2 - 12959 + 13056 2 3 - 7405 + 7460 @@ -32846,7 +33326,7 @@ 1 2 - 20365 + 20517 @@ -32862,7 +33342,7 @@ 1 2 - 20365 + 20517 @@ -32878,12 +33358,12 @@ 1 2 - 12959 + 13056 2 3 - 7405 + 7460 @@ -32899,12 +33379,12 @@ 16 17 - 462 + 466 44 45 - 462 + 466 @@ -32920,12 +33400,12 @@ 16 17 - 462 + 466 44 45 - 462 + 466 @@ -32941,12 +33421,12 @@ 16 17 - 462 + 466 44 45 - 462 + 466 @@ -32962,7 +33442,7 @@ 1 2 - 925 + 932 @@ -32978,7 +33458,7 @@ 1 2 - 925 + 932 @@ -32994,12 +33474,12 @@ 2 3 - 462 + 466 4 5 - 462 + 466 @@ -33015,7 +33495,7 @@ 1 2 - 27771 + 27977 @@ -33031,7 +33511,7 @@ 1 2 - 27771 + 27977 @@ -33047,7 +33527,7 @@ 1 2 - 27771 + 27977 @@ -33063,7 +33543,7 @@ 1 2 - 27771 + 27977 @@ -33079,7 +33559,7 @@ 1 2 - 27771 + 27977 @@ -33095,7 +33575,7 @@ 1 2 - 27771 + 27977 @@ -33111,7 +33591,7 @@ 60 61 - 462 + 466 @@ -33127,7 +33607,7 @@ 44 45 - 462 + 466 @@ -33143,7 +33623,7 @@ 2 3 - 462 + 466 @@ -33159,7 +33639,7 @@ 60 61 - 462 + 466 @@ -33175,7 +33655,7 @@ 1 2 - 462 + 466 @@ -33191,7 +33671,7 @@ 6 7 - 462 + 466 @@ -33207,7 +33687,7 @@ 60 61 - 462 + 466 @@ -33223,7 +33703,7 @@ 44 45 - 462 + 466 @@ -33239,7 +33719,7 @@ 2 3 - 462 + 466 @@ -33255,7 +33735,7 @@ 60 61 - 462 + 466 @@ -33271,7 +33751,7 @@ 1 2 - 462 + 466 @@ -33287,7 +33767,7 @@ 6 7 - 462 + 466 @@ -33303,12 +33783,12 @@ 8 9 - 1851 + 1865 14 15 - 925 + 932 @@ -33324,12 +33804,12 @@ 8 9 - 1851 + 1865 14 15 - 925 + 932 @@ -33345,7 +33825,7 @@ 1 2 - 2777 + 2797 @@ -33361,12 +33841,12 @@ 8 9 - 1851 + 1865 14 15 - 925 + 932 @@ -33382,7 +33862,7 @@ 1 2 - 2777 + 2797 @@ -33398,7 +33878,7 @@ 1 2 - 2777 + 2797 @@ -33524,11 +34004,11 @@ stmts - 4653237 + 4653633 id - 4653237 + 4653633 kind @@ -33536,7 +34016,7 @@ location - 2284887 + 2285081 @@ -33550,7 +34030,7 @@ 1 2 - 4653237 + 4653633 @@ -33566,7 +34046,7 @@ 1 2 - 4653237 + 4653633 @@ -33794,22 +34274,22 @@ 1 2 - 1890475 + 1890636 2 4 - 175816 + 175831 4 12 - 176026 + 176041 12 687 - 42568 + 42572 @@ -33825,12 +34305,12 @@ 1 2 - 2227676 + 2227865 2 8 - 57211 + 57215 @@ -33984,15 +34464,15 @@ if_then - 724702 + 724735 if_stmt - 724702 + 724735 then_id - 724702 + 724735 @@ -34006,7 +34486,7 @@ 1 2 - 724702 + 724735 @@ -34022,7 +34502,7 @@ 1 2 - 724702 + 724735 @@ -34032,15 +34512,15 @@ if_else - 184361 + 184369 if_stmt - 184361 + 184369 else_id - 184361 + 184369 @@ -34054,7 +34534,7 @@ 1 2 - 184361 + 184369 @@ -34070,7 +34550,7 @@ 1 2 - 184361 + 184369 @@ -34128,15 +34608,15 @@ constexpr_if_then - 52504 + 52508 constexpr_if_stmt - 52504 + 52508 then_id - 52504 + 52508 @@ -34150,7 +34630,7 @@ 1 2 - 52504 + 52508 @@ -34166,7 +34646,7 @@ 1 2 - 52504 + 52508 @@ -34176,15 +34656,15 @@ constexpr_if_else - 30854 + 30856 constexpr_if_stmt - 30854 + 30856 else_id - 30854 + 30856 @@ -34198,7 +34678,7 @@ 1 2 - 30854 + 30856 @@ -34214,7 +34694,7 @@ 1 2 - 30854 + 30856 @@ -34224,15 +34704,15 @@ while_body - 30109 + 30110 while_stmt - 30109 + 30110 body_id - 30109 + 30110 @@ -34246,7 +34726,7 @@ 1 2 - 30109 + 30110 @@ -34262,7 +34742,7 @@ 1 2 - 30109 + 30110 @@ -34272,15 +34752,15 @@ do_body - 148625 + 148632 do_stmt - 148625 + 148632 body_id - 148625 + 148632 @@ -34294,7 +34774,7 @@ 1 2 - 148625 + 148632 @@ -34310,7 +34790,7 @@ 1 2 - 148625 + 148632 @@ -34368,7 +34848,7 @@ switch_case - 209633 + 209643 switch_stmt @@ -34380,7 +34860,7 @@ case_id - 209633 + 209643 @@ -34608,7 +35088,7 @@ 1 2 - 209633 + 209643 @@ -34624,7 +35104,7 @@ 1 2 - 209633 + 209643 @@ -34634,15 +35114,15 @@ switch_body - 20752 + 20753 switch_stmt - 20752 + 20753 body_id - 20752 + 20753 @@ -34656,7 +35136,7 @@ 1 2 - 20752 + 20753 @@ -34672,7 +35152,7 @@ 1 2 - 20752 + 20753 @@ -34682,15 +35162,15 @@ for_initialization - 53314 + 53317 for_stmt - 53314 + 53317 init_id - 53314 + 53317 @@ -34704,7 +35184,7 @@ 1 2 - 53314 + 53317 @@ -34720,7 +35200,7 @@ 1 2 - 53314 + 53317 @@ -34730,15 +35210,15 @@ for_condition - 55575 + 55578 for_stmt - 55575 + 55578 condition_id - 55575 + 55578 @@ -34752,7 +35232,7 @@ 1 2 - 55575 + 55578 @@ -34768,7 +35248,7 @@ 1 2 - 55575 + 55578 @@ -34778,15 +35258,15 @@ for_update - 53417 + 53419 for_stmt - 53417 + 53419 update_id - 53417 + 53419 @@ -34800,7 +35280,7 @@ 1 2 - 53417 + 53419 @@ -34816,7 +35296,7 @@ 1 2 - 53417 + 53419 @@ -34826,15 +35306,15 @@ for_body - 61453 + 61456 for_stmt - 61453 + 61456 body_id - 61453 + 61456 @@ -34848,7 +35328,7 @@ 1 2 - 61453 + 61456 @@ -34864,7 +35344,7 @@ 1 2 - 61453 + 61456 @@ -34874,11 +35354,11 @@ stmtparents - 4056317 + 4056493 id - 4056317 + 4056493 index @@ -34886,7 +35366,7 @@ parent - 1721231 + 1721306 @@ -34900,7 +35380,7 @@ 1 2 - 4056317 + 4056493 @@ -34916,7 +35396,7 @@ 1 2 - 4056317 + 4056493 @@ -35054,27 +35534,27 @@ 1 2 - 988379 + 988422 2 3 - 373323 + 373339 3 4 - 105844 + 105849 4 6 - 111345 + 111349 6 17 - 129966 + 129972 17 @@ -35095,27 +35575,27 @@ 1 2 - 988379 + 988422 2 3 - 373323 + 373339 3 4 - 105844 + 105849 4 6 - 111345 + 111349 6 17 - 129966 + 129972 17 @@ -35130,22 +35610,22 @@ ishandler - 65311 + 65314 block - 65311 + 65314 stmt_decl_bind - 585113 + 585138 stmt - 544999 + 545022 num @@ -35153,7 +35633,7 @@ decl - 585008 + 585033 @@ -35167,12 +35647,12 @@ 1 2 - 524137 + 524159 2 19 - 20861 + 20862 @@ -35188,12 +35668,12 @@ 1 2 - 524137 + 524159 2 19 - 20861 + 20862 @@ -35391,7 +35871,7 @@ 1 2 - 584971 + 584995 2 @@ -35412,7 +35892,7 @@ 1 2 - 585008 + 585033 @@ -35422,11 +35902,11 @@ stmt_decl_entry_bind - 527572 + 527594 stmt - 487760 + 487781 num @@ -35434,7 +35914,7 @@ decl_entry - 527514 + 527536 @@ -35448,12 +35928,12 @@ 1 2 - 467163 + 467183 2 19 - 20596 + 20597 @@ -35469,12 +35949,12 @@ 1 2 - 467163 + 467183 2 19 - 20596 + 20597 @@ -35672,7 +36152,7 @@ 1 2 - 527493 + 527515 3 @@ -35693,7 +36173,7 @@ 1 2 - 527514 + 527536 @@ -35703,15 +36183,15 @@ blockscope - 1414946 + 1415210 block - 1414946 + 1415210 enclosing - 1300621 + 1300035 @@ -35725,7 +36205,7 @@ 1 2 - 1414946 + 1415210 @@ -35741,12 +36221,12 @@ 1 2 - 1235821 + 1234753 2 13 - 64799 + 65281 @@ -35756,19 +36236,19 @@ jumpinfo - 254032 + 254043 id - 254032 + 254043 str - 21155 + 21156 target - 53053 + 53056 @@ -35782,7 +36262,7 @@ 1 2 - 254032 + 254043 @@ -35798,7 +36278,7 @@ 1 2 - 254032 + 254043 @@ -35819,12 +36299,12 @@ 3 4 - 4246 + 4247 4 5 - 1565 + 1566 5 @@ -35860,7 +36340,7 @@ 1 2 - 16719 + 16720 2 @@ -35896,7 +36376,7 @@ 2 3 - 26432 + 26433 3 @@ -35932,7 +36412,7 @@ 1 2 - 53053 + 53056 @@ -35942,11 +36422,11 @@ preprocdirects - 4427322 + 4427698 id - 4427322 + 4427698 kind @@ -35954,7 +36434,7 @@ location - 4424811 + 4425187 @@ -35968,7 +36448,7 @@ 1 2 - 4427322 + 4427698 @@ -35984,7 +36464,7 @@ 1 2 - 4427322 + 4427698 @@ -36122,7 +36602,7 @@ 1 2 - 4424707 + 4425083 25 @@ -36143,7 +36623,7 @@ 1 2 - 4424811 + 4425187 @@ -36153,15 +36633,15 @@ preprocpair - 1419111 + 1429665 begin - 1186758 + 1195584 elseelifend - 1419111 + 1429665 @@ -36175,17 +36655,17 @@ 1 2 - 970143 + 977357 2 3 - 206433 + 207968 3 11 - 10182 + 10258 @@ -36201,7 +36681,7 @@ 1 2 - 1419111 + 1429665 @@ -36211,41 +36691,41 @@ preproctrue - 770652 + 766125 branch - 770652 + 766125 preprocfalse - 321683 + 331070 branch - 321683 + 331070 preproctext - 3569469 + 3569772 id - 3569469 + 3569772 head - 2589246 + 2589465 body - 1514472 + 1514601 @@ -36259,7 +36739,7 @@ 1 2 - 3569469 + 3569772 @@ -36275,7 +36755,7 @@ 1 2 - 3569469 + 3569772 @@ -36291,12 +36771,12 @@ 1 2 - 2442296 + 2442503 2 740 - 146949 + 146962 @@ -36312,12 +36792,12 @@ 1 2 - 2527119 + 2527333 2 5 - 62126 + 62132 @@ -36333,17 +36813,17 @@ 1 2 - 1370974 + 1371090 2 6 - 113585 + 113595 6 11572 - 29912 + 29915 @@ -36359,17 +36839,17 @@ 1 2 - 1374007 + 1374124 2 7 - 113899 + 113908 7 2959 - 26566 + 26568 @@ -36379,15 +36859,15 @@ includes - 310575 + 312885 id - 310575 + 312885 included - 116176 + 117040 @@ -36401,7 +36881,7 @@ 1 2 - 310575 + 312885 @@ -36417,32 +36897,32 @@ 1 2 - 60633 + 61084 2 3 - 21754 + 21915 3 4 - 12497 + 12590 4 6 - 10182 + 10258 6 14 - 8794 + 8859 14 47 - 2314 + 2331 @@ -36500,11 +36980,11 @@ link_parent - 38562230 + 38563300 element - 4878989 + 4879124 link_target @@ -36522,17 +37002,17 @@ 1 2 - 648887 + 648905 2 9 - 25932 + 25933 9 10 - 4204168 + 4204285 diff --git a/cpp/ql/lib/upgrades/a5bb28ed29f73855d64cc5f939cef977fa8fd19a/aggregate_array_init.ql b/cpp/ql/lib/upgrades/a5bb28ed29f73855d64cc5f939cef977fa8fd19a/aggregate_array_init.ql new file mode 100644 index 00000000000..b8997aca069 --- /dev/null +++ b/cpp/ql/lib/upgrades/a5bb28ed29f73855d64cc5f939cef977fa8fd19a/aggregate_array_init.ql @@ -0,0 +1,11 @@ +class AggregateLiteral extends @aggregateliteral { + string toString() { none() } +} + +class Expr extends @expr { + string toString() { none() } +} + +from AggregateLiteral al, Expr init, int index, int position +where exprparents(init, position, al) and aggregate_array_init(al, init, index) +select al, init, index, position diff --git a/cpp/ql/lib/upgrades/a5bb28ed29f73855d64cc5f939cef977fa8fd19a/aggregate_field_init.ql b/cpp/ql/lib/upgrades/a5bb28ed29f73855d64cc5f939cef977fa8fd19a/aggregate_field_init.ql new file mode 100644 index 00000000000..b784f88cf0c --- /dev/null +++ b/cpp/ql/lib/upgrades/a5bb28ed29f73855d64cc5f939cef977fa8fd19a/aggregate_field_init.ql @@ -0,0 +1,15 @@ +class AggregateLiteral extends @aggregateliteral { + string toString() { none() } +} + +class Expr extends @expr { + string toString() { none() } +} + +class Field extends @membervariable { + string toString() { none() } +} + +from AggregateLiteral al, Expr init, Field field, int position +where exprparents(init, position, al) and aggregate_field_init(al, init, field) +select al, init, field, position diff --git a/cpp/ql/lib/upgrades/a5bb28ed29f73855d64cc5f939cef977fa8fd19a/old.dbscheme b/cpp/ql/lib/upgrades/a5bb28ed29f73855d64cc5f939cef977fa8fd19a/old.dbscheme new file mode 100644 index 00000000000..a5bb28ed29f --- /dev/null +++ b/cpp/ql/lib/upgrades/a5bb28ed29f73855d64cc5f939cef977fa8fd19a/old.dbscheme @@ -0,0 +1,2210 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * gcc -c f1.c f2.c f3.c + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/** + * Information about packages that provide code used during compilation. + * The `id` is just a unique identifier. + * The `namespace` is typically the name of the package manager that + * provided the package (e.g. "dpkg" or "yum"). + * The `package_name` is the name of the package, and `version` is its + * version (as a string). + */ +external_packages( + unique int id: @external_package, + string namespace : string ref, + string package_name : string ref, + string version : string ref +); + +/** + * Holds if File `fileid` was provided by package `package`. + */ +header_to_external_package( + int fileid : @file ref, + int package : @external_package ref +); + +/* + * Version history + */ + +svnentries( + unique int id : @svnentry, + string revision : string ref, + string author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + string action : string ref +) + +svnentrymsg( + unique int id : @svnentry ref, + string message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/* + * C++ dbscheme + */ + +@location = @location_stmt | @location_expr | @location_default ; + +/** + * The location of an element that is not an expression or a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + /** The location of an element that is not an expression or a statement. */ + unique int id: @location_default, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_stmt( + /** The location of a statement. */ + unique int id: @location_stmt, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of an expression. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_expr( + /** The location of an expression. */ + unique int id: @location_expr, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int 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_default ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +case @macroinvocation.kind of + 1 = @macro_expansion +| 2 = @other_macro_reference +; + +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +/* +case @function.kind of + 1 = @normal_function +| 2 = @constructor +| 3 = @destructor +| 4 = @conversion_function +| 5 = @operator +| 6 = @builtin_function // GCC built-in functions, e.g. __builtin___memcpy_chk +; +*/ + +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +function_entry_point( + int id: @function ref, + unique int entry_point: @stmt ref +); + +function_return_type( + int id: @function ref, + int return_type: @type ref +); + +/** + * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits` + * instance associated with it, and the variables representing the `handle` and `promise` + * for it. + */ +coroutine( + unique int function: @function ref, + int traits: @type ref, + int handle: @variable ref, + int promise: @variable ref +); + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +member_function_this_type( + unique int id: @function ref, + int this_type: @type ref +); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) +is_structured_binding(unique int id: @variable ref); + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @functionorblock ref, + int index: int ref, + int type_id: @type ref +); + +overrides( + int new: @function ref, + int old: @function ref +); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +orphaned_variables( + int var: @localvariable ref, + int function: @function ref +) + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/** + * Built-in types are the fundamental types, e.g., integral, floating, and void. + */ +case @builtintype.kind of + 1 = @errortype +| 2 = @unknowntype +| 3 = @void +| 4 = @boolean +| 5 = @char +| 6 = @unsigned_char +| 7 = @signed_char +| 8 = @short +| 9 = @unsigned_short +| 10 = @signed_short +| 11 = @int +| 12 = @unsigned_int +| 13 = @signed_int +| 14 = @long +| 15 = @unsigned_long +| 16 = @signed_long +| 17 = @long_long +| 18 = @unsigned_long_long +| 19 = @signed_long_long +// ... 20 Microsoft-specific __int8 +// ... 21 Microsoft-specific __int16 +// ... 22 Microsoft-specific __int32 +// ... 23 Microsoft-specific __int64 +| 24 = @float +| 25 = @double +| 26 = @long_double +| 27 = @complex_float // C99-specific _Complex float +| 28 = @complex_double // C99-specific _Complex double +| 29 = @complex_long_double // C99-specific _Complex long double +| 30 = @imaginary_float // C99-specific _Imaginary float +| 31 = @imaginary_double // C99-specific _Imaginary double +| 32 = @imaginary_long_double // C99-specific _Imaginary long double +| 33 = @wchar_t // Microsoft-specific +| 34 = @decltype_nullptr // C++11 +| 35 = @int128 // __int128 +| 36 = @unsigned_int128 // unsigned __int128 +| 37 = @signed_int128 // signed __int128 +| 38 = @float128 // __float128 +| 39 = @complex_float128 // _Complex __float128 +| 40 = @decimal32 // _Decimal32 +| 41 = @decimal64 // _Decimal64 +| 42 = @decimal128 // _Decimal128 +| 43 = @char16_t +| 44 = @char32_t +| 45 = @std_float32 // _Float32 +| 46 = @float32x // _Float32x +| 47 = @std_float64 // _Float64 +| 48 = @float64x // _Float64x +| 49 = @std_float128 // _Float128 +| 50 = @float128x // _Float128x +| 51 = @char8_t +| 52 = @float16 // _Float16 +| 53 = @complex_float16 // _Complex _Float16 +; + +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/** + * Derived types are types that are directly derived from existing types and + * point to, refer to, transform type data to return a new type. + */ +case @derivedtype.kind of + 1 = @pointer +| 2 = @reference +| 3 = @type_with_specifiers +| 4 = @array +| 5 = @gnu_vector +| 6 = @routineptr +| 7 = @routinereference +| 8 = @rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated +| 10 = @block +; + +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +/** + * An instance of the C++11 `decltype` operator. For example: + * ``` + * int a; + * decltype(1+a) b; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * would change the semantics of this decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ +#keyset[id, expr] +decltypes( + int id: @decltype, + int expr: @expr ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +/* +case @usertype.kind of + 1 = @struct +| 2 = @class +| 3 = @union +| 4 = @enum +| 5 = @typedef // classic C: typedef typedef type name +| 6 = @template +| 7 = @template_parameter +| 8 = @template_template_parameter +| 9 = @proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated +| 13 = @scoped_enum +| 14 = @using_alias // a using name = type style typedef +; +*/ + +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + string uuid: string ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +is_proxy_class_for( + unique int id: @usertype ref, + unique int templ_param_id: @usertype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location ref, + // a_symbol_reference_kind from the frontend. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); + +/* + Fixed point types + precision(1) = short, precision(2) = default, precision(3) = long + is_unsigned(1) = unsigned is_unsigned(2) = signed + is_fract_type(1) = declared with _Fract + saturating(1) = declared with _Sat +*/ +/* TODO +fixedpointtypes( + unique int id: @fixedpointtype, + int precision: int ref, + int is_unsigned: int ref, + int is_fract_type: int ref, + int saturating: int ref); +*/ + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +| 4 = @attribute_arg_constant_expr +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_constant( + unique int arg: @attribute_arg ref, + int constant: @expr ref +) +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + /* TODO | @fixedpointtype */ + | @routinetype + | @ptrtomember + | @decltype; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall( + unique int caller: @funbindexpr ref, + int kind: int ref +); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr + +@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr + +/* + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 3 = size_and_alignment + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_expr ref +); + +braced_initialisers( + int init: @initialiser ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_expr ref +); + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +| 330 = @isassignable +| 331 = @isaggregate +| 332 = @hasuniqueobjectrepresentations +| 333 = @builtinbitcast +| 334 = @builtinshuffle +| 335 = @blockassignexpr +| 336 = @issame +| 337 = @isfunction +| 338 = @islayoutcompatible +| 339 = @ispointerinterconvertiblebaseof +| 340 = @isarray +| 341 = @arrayrank +| 342 = @arrayextent +| 343 = @isarithmetic +| 344 = @iscompletetype +| 345 = @iscompound +| 346 = @isconst +| 347 = @isfloatingpoint +| 348 = @isfundamental +| 349 = @isintegral +| 350 = @islvaluereference +| 351 = @ismemberfunctionpointer +| 352 = @ismemberobjectpointer +| 353 = @ismemberpointer +| 354 = @isobject +| 355 = @ispointer +| 356 = @isreference +| 357 = @isrvaluereference +| 358 = @isscalar +| 359 = @issigned +| 360 = @isunsigned +| 361 = @isvoid +| 362 = @isvolatile +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + | @isassignable + | @isaggregate + | @hasuniqueobjectrepresentations + | @builtinbitcast + | @builtinshuffle + | @issame + | @isfunction + | @islayoutcompatible + | @ispointerinterconvertiblebaseof + | @isarray + | @arrayrank + | @arrayextent + | @isarithmetic + | @iscompletetype + | @iscompound + | @isconst + | @isfloatingpoint + | @isfundamental + | @isintegral + | @islvaluereference + | @ismemberfunctionpointer + | @ismemberobjectpointer + | @ismemberpointer + | @isobject + | @ispointer + | @isreference + | @isrvaluereference + | @isscalar + | @issigned + | @isunsigned + | @isvoid + | @isvolatile + ; + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. + */ +#keyset[aggregate, field] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. + */ +#keyset[aggregate, element_index] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof; + +sizeof_bind( + unique int expr: @runtime_sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_stmt ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +if_initialization( + unique int if_stmt: @stmt_if ref, + int init_id: @stmt ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_initialization( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int init_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +switch_initialization( + unique int switch_stmt: @stmt_switch ref, + int init_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +for_initialization( + unique int for_stmt: @stmt_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@functionorblock = @function | @stmt_block; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @functionorblock ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +link_targets( + unique int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target 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; diff --git a/cpp/ql/lib/upgrades/a5bb28ed29f73855d64cc5f939cef977fa8fd19a/semmlecode.cpp.dbscheme b/cpp/ql/lib/upgrades/a5bb28ed29f73855d64cc5f939cef977fa8fd19a/semmlecode.cpp.dbscheme new file mode 100644 index 00000000000..19887dbd333 --- /dev/null +++ b/cpp/ql/lib/upgrades/a5bb28ed29f73855d64cc5f939cef977fa8fd19a/semmlecode.cpp.dbscheme @@ -0,0 +1,2212 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * gcc -c f1.c f2.c f3.c + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/** + * Information about packages that provide code used during compilation. + * The `id` is just a unique identifier. + * The `namespace` is typically the name of the package manager that + * provided the package (e.g. "dpkg" or "yum"). + * The `package_name` is the name of the package, and `version` is its + * version (as a string). + */ +external_packages( + unique int id: @external_package, + string namespace : string ref, + string package_name : string ref, + string version : string ref +); + +/** + * Holds if File `fileid` was provided by package `package`. + */ +header_to_external_package( + int fileid : @file ref, + int package : @external_package ref +); + +/* + * Version history + */ + +svnentries( + unique int id : @svnentry, + string revision : string ref, + string author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + string action : string ref +) + +svnentrymsg( + unique int id : @svnentry ref, + string message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/* + * C++ dbscheme + */ + +@location = @location_stmt | @location_expr | @location_default ; + +/** + * The location of an element that is not an expression or a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + /** The location of an element that is not an expression or a statement. */ + unique int id: @location_default, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_stmt( + /** The location of a statement. */ + unique int id: @location_stmt, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of an expression. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_expr( + /** The location of an expression. */ + unique int id: @location_expr, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int 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_default ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +case @macroinvocation.kind of + 1 = @macro_expansion +| 2 = @other_macro_reference +; + +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +/* +case @function.kind of + 1 = @normal_function +| 2 = @constructor +| 3 = @destructor +| 4 = @conversion_function +| 5 = @operator +| 6 = @builtin_function // GCC built-in functions, e.g. __builtin___memcpy_chk +; +*/ + +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +function_entry_point( + int id: @function ref, + unique int entry_point: @stmt ref +); + +function_return_type( + int id: @function ref, + int return_type: @type ref +); + +/** + * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits` + * instance associated with it, and the variables representing the `handle` and `promise` + * for it. + */ +coroutine( + unique int function: @function ref, + int traits: @type ref, + int handle: @variable ref, + int promise: @variable ref +); + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +member_function_this_type( + unique int id: @function ref, + int this_type: @type ref +); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) +is_structured_binding(unique int id: @variable ref); + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @functionorblock ref, + int index: int ref, + int type_id: @type ref +); + +overrides( + int new: @function ref, + int old: @function ref +); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +orphaned_variables( + int var: @localvariable ref, + int function: @function ref +) + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/** + * Built-in types are the fundamental types, e.g., integral, floating, and void. + */ +case @builtintype.kind of + 1 = @errortype +| 2 = @unknowntype +| 3 = @void +| 4 = @boolean +| 5 = @char +| 6 = @unsigned_char +| 7 = @signed_char +| 8 = @short +| 9 = @unsigned_short +| 10 = @signed_short +| 11 = @int +| 12 = @unsigned_int +| 13 = @signed_int +| 14 = @long +| 15 = @unsigned_long +| 16 = @signed_long +| 17 = @long_long +| 18 = @unsigned_long_long +| 19 = @signed_long_long +// ... 20 Microsoft-specific __int8 +// ... 21 Microsoft-specific __int16 +// ... 22 Microsoft-specific __int32 +// ... 23 Microsoft-specific __int64 +| 24 = @float +| 25 = @double +| 26 = @long_double +| 27 = @complex_float // C99-specific _Complex float +| 28 = @complex_double // C99-specific _Complex double +| 29 = @complex_long_double // C99-specific _Complex long double +| 30 = @imaginary_float // C99-specific _Imaginary float +| 31 = @imaginary_double // C99-specific _Imaginary double +| 32 = @imaginary_long_double // C99-specific _Imaginary long double +| 33 = @wchar_t // Microsoft-specific +| 34 = @decltype_nullptr // C++11 +| 35 = @int128 // __int128 +| 36 = @unsigned_int128 // unsigned __int128 +| 37 = @signed_int128 // signed __int128 +| 38 = @float128 // __float128 +| 39 = @complex_float128 // _Complex __float128 +| 40 = @decimal32 // _Decimal32 +| 41 = @decimal64 // _Decimal64 +| 42 = @decimal128 // _Decimal128 +| 43 = @char16_t +| 44 = @char32_t +| 45 = @std_float32 // _Float32 +| 46 = @float32x // _Float32x +| 47 = @std_float64 // _Float64 +| 48 = @float64x // _Float64x +| 49 = @std_float128 // _Float128 +| 50 = @float128x // _Float128x +| 51 = @char8_t +| 52 = @float16 // _Float16 +| 53 = @complex_float16 // _Complex _Float16 +; + +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/** + * Derived types are types that are directly derived from existing types and + * point to, refer to, transform type data to return a new type. + */ +case @derivedtype.kind of + 1 = @pointer +| 2 = @reference +| 3 = @type_with_specifiers +| 4 = @array +| 5 = @gnu_vector +| 6 = @routineptr +| 7 = @routinereference +| 8 = @rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated +| 10 = @block +; + +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +/** + * An instance of the C++11 `decltype` operator. For example: + * ``` + * int a; + * decltype(1+a) b; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * would change the semantics of this decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ +#keyset[id, expr] +decltypes( + int id: @decltype, + int expr: @expr ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +/* +case @usertype.kind of + 1 = @struct +| 2 = @class +| 3 = @union +| 4 = @enum +| 5 = @typedef // classic C: typedef typedef type name +| 6 = @template +| 7 = @template_parameter +| 8 = @template_template_parameter +| 9 = @proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated +| 13 = @scoped_enum +| 14 = @using_alias // a using name = type style typedef +; +*/ + +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + string uuid: string ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +is_proxy_class_for( + unique int id: @usertype ref, + unique int templ_param_id: @usertype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location ref, + // a_symbol_reference_kind from the frontend. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); + +/* + Fixed point types + precision(1) = short, precision(2) = default, precision(3) = long + is_unsigned(1) = unsigned is_unsigned(2) = signed + is_fract_type(1) = declared with _Fract + saturating(1) = declared with _Sat +*/ +/* TODO +fixedpointtypes( + unique int id: @fixedpointtype, + int precision: int ref, + int is_unsigned: int ref, + int is_fract_type: int ref, + int saturating: int ref); +*/ + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +| 4 = @attribute_arg_constant_expr +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_constant( + unique int arg: @attribute_arg ref, + int constant: @expr ref +) +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + /* TODO | @fixedpointtype */ + | @routinetype + | @ptrtomember + | @decltype; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall( + unique int caller: @funbindexpr ref, + int kind: int ref +); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr + +@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr + +/* + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 3 = size_and_alignment + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_expr ref +); + +braced_initialisers( + int init: @initialiser ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_expr ref +); + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +| 330 = @isassignable +| 331 = @isaggregate +| 332 = @hasuniqueobjectrepresentations +| 333 = @builtinbitcast +| 334 = @builtinshuffle +| 335 = @blockassignexpr +| 336 = @issame +| 337 = @isfunction +| 338 = @islayoutcompatible +| 339 = @ispointerinterconvertiblebaseof +| 340 = @isarray +| 341 = @arrayrank +| 342 = @arrayextent +| 343 = @isarithmetic +| 344 = @iscompletetype +| 345 = @iscompound +| 346 = @isconst +| 347 = @isfloatingpoint +| 348 = @isfundamental +| 349 = @isintegral +| 350 = @islvaluereference +| 351 = @ismemberfunctionpointer +| 352 = @ismemberobjectpointer +| 353 = @ismemberpointer +| 354 = @isobject +| 355 = @ispointer +| 356 = @isreference +| 357 = @isrvaluereference +| 358 = @isscalar +| 359 = @issigned +| 360 = @isunsigned +| 361 = @isvoid +| 362 = @isvolatile +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + | @isassignable + | @isaggregate + | @hasuniqueobjectrepresentations + | @builtinbitcast + | @builtinshuffle + | @issame + | @isfunction + | @islayoutcompatible + | @ispointerinterconvertiblebaseof + | @isarray + | @arrayrank + | @arrayextent + | @isarithmetic + | @iscompletetype + | @iscompound + | @isconst + | @isfloatingpoint + | @isfundamental + | @isintegral + | @islvaluereference + | @ismemberfunctionpointer + | @ismemberobjectpointer + | @ismemberpointer + | @isobject + | @ispointer + | @isreference + | @isrvaluereference + | @isscalar + | @issigned + | @isunsigned + | @isvoid + | @isvolatile + ; + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref, + int position: int ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref, + int position: int ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof; + +sizeof_bind( + unique int expr: @runtime_sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_stmt ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +if_initialization( + unique int if_stmt: @stmt_if ref, + int init_id: @stmt ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_initialization( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int init_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +switch_initialization( + unique int switch_stmt: @stmt_switch ref, + int init_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +for_initialization( + unique int for_stmt: @stmt_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@functionorblock = @function | @stmt_block; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @functionorblock ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +link_targets( + unique int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target 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; diff --git a/cpp/ql/lib/upgrades/a5bb28ed29f73855d64cc5f939cef977fa8fd19a/upgrade.properties b/cpp/ql/lib/upgrades/a5bb28ed29f73855d64cc5f939cef977fa8fd19a/upgrade.properties new file mode 100644 index 00000000000..7b58d536070 --- /dev/null +++ b/cpp/ql/lib/upgrades/a5bb28ed29f73855d64cc5f939cef977fa8fd19a/upgrade.properties @@ -0,0 +1,4 @@ +description: Support repeated initializers, which are allowed in C with designated initializers. +compatibility: full +aggregate_field_init.rel: run aggregate_field_init.qlo +aggregate_array_init.rel: run aggregate_array_init.qlo diff --git a/cpp/ql/src/Likely Bugs/Memory Management/SuspiciousCallToStrncat.ql b/cpp/ql/src/Likely Bugs/Memory Management/SuspiciousCallToStrncat.ql index 0d46332a40a..37ad8fd7076 100644 --- a/cpp/ql/src/Likely Bugs/Memory Management/SuspiciousCallToStrncat.ql +++ b/cpp/ql/src/Likely Bugs/Memory Management/SuspiciousCallToStrncat.ql @@ -48,11 +48,11 @@ predicate case1(FunctionCall fc, Expr sizeArg, VariableAccess destArg) { * Holds if `fc` is a call to `strncat` with size argument `sizeArg` and destination * argument `destArg`, and `sizeArg` computes the value `sizeof (dest) - strlen (dest)`. */ -predicate case2(FunctionCall fc, Expr sizeArg, VariableAccess destArg) { - interestingCallWithArgs(fc, sizeArg, destArg) and +predicate case2(FunctionCall fc, Expr sizeArg, Expr destArg) { + interestingCallWithArgs(fc, pragma[only_bind_into](sizeArg), pragma[only_bind_into](destArg)) and exists(SubExpr sub, int n | // The destination buffer is an array of size n - destArg.getUnspecifiedType().(ArrayType).getSize() = n and + pragma[only_bind_out](destArg.getUnspecifiedType().(ArrayType).getSize()) = n and // The size argument is equivalent to a subtraction globalValueNumber(sizeArg).getAnExpr() = sub and // ... where the left side of the subtraction is the constant n diff --git a/cpp/ql/src/experimental/Likely Bugs/ArrayAccessProductFlow.ql b/cpp/ql/src/experimental/Likely Bugs/ArrayAccessProductFlow.ql index 61c0af6be26..39c54573b06 100644 --- a/cpp/ql/src/experimental/Likely Bugs/ArrayAccessProductFlow.ql +++ b/cpp/ql/src/experimental/Likely Bugs/ArrayAccessProductFlow.ql @@ -11,9 +11,9 @@ import cpp import experimental.semmle.code.cpp.dataflow.ProductFlow -import experimental.semmle.code.cpp.semantic.analysis.RangeAnalysis -import experimental.semmle.code.cpp.rangeanalysis.Bound -import experimental.semmle.code.cpp.semantic.SemanticExprSpecific +import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeAnalysis +import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticExprSpecific +import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.Bound import semmle.code.cpp.ir.IR import semmle.code.cpp.valuenumbering.GlobalValueNumbering import semmle.code.cpp.models.interfaces.Allocation diff --git a/cpp/ql/src/experimental/Likely Bugs/OverrunWriteProductFlow.ql b/cpp/ql/src/experimental/Likely Bugs/OverrunWriteProductFlow.ql index 5f6bf7d7166..7fde728e5bf 100644 --- a/cpp/ql/src/experimental/Likely Bugs/OverrunWriteProductFlow.ql +++ b/cpp/ql/src/experimental/Likely Bugs/OverrunWriteProductFlow.ql @@ -17,9 +17,8 @@ import experimental.semmle.code.cpp.dataflow.ProductFlow import semmle.code.cpp.ir.IR import semmle.code.cpp.models.interfaces.Allocation import semmle.code.cpp.models.interfaces.ArrayFunction -import experimental.semmle.code.cpp.semantic.analysis.RangeAnalysis -import experimental.semmle.code.cpp.semantic.SemanticBound -import experimental.semmle.code.cpp.semantic.SemanticExprSpecific +import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeAnalysis +import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticExprSpecific import DataFlow::PathGraph pragma[nomagic] diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-193/ConstantSizeArrayOffByOne.ql b/cpp/ql/src/experimental/Security/CWE/CWE-193/ConstantSizeArrayOffByOne.ql index 66346b7aea7..20cd6f639ef 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-193/ConstantSizeArrayOffByOne.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-193/ConstantSizeArrayOffByOne.ql @@ -10,9 +10,8 @@ * experimental */ -import experimental.semmle.code.cpp.semantic.analysis.RangeAnalysis -import experimental.semmle.code.cpp.semantic.SemanticBound -import experimental.semmle.code.cpp.semantic.SemanticExprSpecific +import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeAnalysis +import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticExprSpecific import semmle.code.cpp.ir.IR import semmle.code.cpp.ir.dataflow.DataFlow import PointerArithmeticToDerefFlow::PathGraph diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql b/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql index 4f1fdb5d08a..1fefbbfcf36 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql @@ -17,9 +17,8 @@ import cpp import experimental.semmle.code.cpp.dataflow.ProductFlow -import experimental.semmle.code.cpp.semantic.analysis.RangeAnalysis -import experimental.semmle.code.cpp.semantic.SemanticBound -import experimental.semmle.code.cpp.semantic.SemanticExprSpecific +import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeAnalysis +import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticExprSpecific import semmle.code.cpp.ir.IR pragma[nomagic] diff --git a/cpp/ql/test/library-tests/ir/modulus-analysis/ModulusAnalysis.ql b/cpp/ql/test/library-tests/ir/modulus-analysis/ModulusAnalysis.ql index e7c56c240df..30ca575b767 100644 --- a/cpp/ql/test/library-tests/ir/modulus-analysis/ModulusAnalysis.ql +++ b/cpp/ql/test/library-tests/ir/modulus-analysis/ModulusAnalysis.ql @@ -1,11 +1,11 @@ import cpp -import experimental.semmle.code.cpp.semantic.analysis.ModulusAnalysis -import experimental.semmle.code.cpp.semantic.Semantic -import experimental.semmle.code.cpp.semantic.analysis.RangeUtils -import experimental.semmle.code.cpp.semantic.analysis.FloatDelta -import experimental.semmle.code.cpp.semantic.analysis.RangeAnalysisSpecific -import experimental.semmle.code.cpp.semantic.analysis.RangeAnalysisImpl -import experimental.semmle.code.cpp.semantic.SemanticExprSpecific +import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.ModulusAnalysis +import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic +import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeUtils +import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.FloatDelta +import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeAnalysisSpecific +import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeAnalysisImpl +import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticExprSpecific import semmle.code.cpp.ir.IR as IR import TestUtilities.InlineExpectationsTest diff --git a/cpp/ql/test/library-tests/ir/range-analysis/Overflow.expected b/cpp/ql/test/library-tests/ir/range-analysis/Overflow.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/cpp/ql/test/library-tests/ir/range-analysis/Overflow.ql b/cpp/ql/test/library-tests/ir/range-analysis/Overflow.ql index 430fa7121e5..d20c68e59b9 100644 --- a/cpp/ql/test/library-tests/ir/range-analysis/Overflow.ql +++ b/cpp/ql/test/library-tests/ir/range-analysis/Overflow.ql @@ -1,5 +1,5 @@ import cpp -import experimental.semmle.code.cpp.semantic.analysis.SimpleRangeAnalysis +import semmle.code.cpp.rangeanalysis.new.SimpleRangeAnalysis import TestUtilities.InlineExpectationsTest class RangeAnalysisTest extends InlineExpectationsTest { diff --git a/cpp/ql/test/library-tests/ir/range-analysis/RangeAnalysis.ql b/cpp/ql/test/library-tests/ir/range-analysis/RangeAnalysis.ql index 9cae7bf9e72..6c79e56cc5b 100644 --- a/cpp/ql/test/library-tests/ir/range-analysis/RangeAnalysis.ql +++ b/cpp/ql/test/library-tests/ir/range-analysis/RangeAnalysis.ql @@ -1,7 +1,7 @@ import cpp -import experimental.semmle.code.cpp.semantic.analysis.RangeAnalysis -import experimental.semmle.code.cpp.semantic.Semantic -import experimental.semmle.code.cpp.semantic.SemanticExprSpecific +import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeAnalysis +import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic +import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticExprSpecific import semmle.code.cpp.ir.IR as IR import TestUtilities.InlineExpectationsTest diff --git a/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp b/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp index cb900be3abe..eed0a7d7e47 100644 --- a/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp +++ b/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp @@ -411,7 +411,7 @@ int test_mult03(int a, int b) { if (-17 <= a && a <= 11 && -13 <= b && b <= 23) { range(a); // $ range=<=11 range=>=-17 range(b); // $ range=<=23 range=>=-13 - int r = a*b; //3 $ overflow=+- -391 .. 25 + int r = a*b; // $ overflow=+- -391 .. 25 range(r); total += r; // $ overflow=+- range(total); @@ -566,11 +566,11 @@ unsigned int test_ternary01(unsigned int x) { y1 = x < 100 ? (range(x), x) : // $ range=<=99 (range(x), 10); // $ range=>=100 - range(y1); + range(y1); // $ range=<=99 y2 = x >= 100 ? (range(x), 10) : // $ range=>=100 (range(x), x); // $ range=<=99 - range(y2); + range(y2); // $ range=<=99 y3 = 0; y4 = 0; y5 = 0; @@ -580,14 +580,14 @@ unsigned int test_ternary01(unsigned int x) { if (x < 300) { range(x); // $ range=<=299 y3 = x ?: - (range(x), 5); // y3 < 300 - range(y3); + (range(x), 5); + range(y3); // $ range=<=299 y4 = x ?: - (range(x), 500); // y4 <= 500 - range(y4); + (range(x), 500); + range(y4); // $ range=<=500 y5 = (x+1) ?: (range(x), 500); // $ overflow=- range===-1 - range(y5); // y5 <= 300 + range(y5); // $ range=<=500 y6 = ((unsigned char)(x+1)) ?: (range(x), 5); // $ range=<=299 range(y6); // y6 < 256 @@ -608,11 +608,11 @@ unsigned int test_ternary02(unsigned int x) { y1 = x > 100 ? (range(x), x) : // $ range=>=101 (range(x), 110); // $ range=<=100 - range(y1); // y1 > 100 + range(y1); // $ range=>=101 y2 = x <= 100 ? (range(x), 110) : // $ range=<=100 (range(x), x); // $ range=>=101 - range(y2); // y2 > 100 + range(y2); // $ range=>=101 y3 = 1000; y4 = 1000; y5 = 1000; @@ -620,15 +620,15 @@ unsigned int test_ternary02(unsigned int x) { range(x); // $ range=>=300 y3 = (x-300) ?: (range(x), 5); // $ range===300 - range(y3); // y3 >= 0 + range(y3); // $ range=>=0 y4 = (x-200) ?: (range(x), 5); // $ range=<=200 range=>=300 - range(y4); // y4 >= 100 + range(y4); // $ SPURIOUS: range=>=5 MISSING: range=>=100 y5 = ((unsigned char)(x-200)) ?: (range(x), 5); // $ range=>=300 range(y5); // y6 >= 0 } - range(y1 + y2 + y3 + y4 + y5); // $ overflow=+ MISSING: range=">=... = ...:... ? ... : ...+0" range=">=call to range+0" + range(y1 + y2 + y3 + y4 + y5); // $ overflow=+ MISSING: range=">=call to range+207" range=">=... = ...:... ? ... : ...+0" range=">=call to range+0" return y1 + y2 + y3 + y4 + y5; // $ overflow=+ } @@ -640,15 +640,15 @@ unsigned int test_comma01(unsigned int x) { unsigned int y1; unsigned int y2; y1 = (++y, y); - range(y1); // $ range="==... ? ... : ...+1" + range(y1); // $ range=<=101 range="==... ? ... : ...+1" y2 = (y++, - range(y), // $ range="==++ ...:... = ...+1" range="==... ? ... : ...+2" + range(y), // $ range=<=102 range="==++ ...:... = ...+1" range="==... ? ... : ...+2" y += 3, - range(y), // $ range="==++ ...:... = ...+4" range="==... +++3" range="==... ? ... : ...+5" + range(y), // $ range=<=105 range="==++ ...:... = ...+4" range="==... +++3" range="==... ? ... : ...+5" y); - range(y2); // $ range="==++ ...:... = ...+4" range="==... +++3" range="==... ? ... : ...+5" - range(y1 + y2); // $ overflow=+ MISSING: range=">=++ ...:... = ...+5" range=">=... +++4" range=">=... += ...:... = ...+1" range=">=... ? ... : ...+6" - return y1 + y2; // $ overflow=+ + range(y2); // $ range=<=105 range="==++ ...:... = ...+4" range="==... +++3" range="==... ? ... : ...+5" + range(y1 + y2); // $ range=<=206 range="<=... ? ... : ...+106" MISSING: range=">=++ ...:... = ...+5" range=">=... +++4" range=">=... += ...:... = ...+1" range=">=... ? ... : ...+6" + return y1 + y2; } void test17() { @@ -683,27 +683,27 @@ int test_unsigned_mult01(unsigned int a, unsigned b) { range(a); // $ range=<=11 range=>=3 range(b); // $ range=<=23 range=>=5 int r = a*b; // 15 .. 253 - range(r); + range(r); // $ range=>=15 range=<=253 total += r; - range(total); // $ MISSING: range=>=1 + range(total); // $ range=>=15 range=<=253 } if (3 <= a && a <= 11 && 0 <= b && b <= 23) { range(a); // $ range=<=11 range=>=3 range(b); // $ range=<=23 range=>=0 int r = a*b; // 0 .. 253 - range(r); - total += r; // $ overflow=+ - range(total); // $ MISSING: range=">=(unsigned int)...+0" range=>=0 + range(r);// $ range=>=0 range=<=253 + total += r; + range(total); // $ range=">=(unsigned int)...+0" range=>=0 range=<=506 range="<=(unsigned int)...+253" } if (3 <= a && a <= 11 && 13 <= b && b <= 23) { range(a); // $ range=<=11 range=>=3 range(b); // $ range=<=23 range=>=13 int r = a*b; // 39 .. 253 - range(r); - total += r; // $ overflow=+ - range(total); // $ MISSING: range=">=(unsigned int)...+1" range=>=1 + range(r); // $ range=>=39 range=<=253 + total += r; + range(total); // $ range=>=39 range=<=759 range="<=(unsigned int)...+253" range="<=(unsigned int)...+506" range=">=(unsigned int)...+39" } - range(total); // $ MISSING: range=">=(unsigned int)...+0" range=>=0 + range(total); // $ range=>=0 range=<=759 range=">=(unsigned int)...+0" range="<=(unsigned int)...+506" range="<=(unsigned int)...+253" return total; } @@ -713,25 +713,25 @@ int test_unsigned_mult02(unsigned b) { if (5 <= b && b <= 23) { range(b); // $ range=<=23 range=>=5 int r = 11*b; // 55 .. 253 - range(r); + range(r); // $ range=>=55 range=<=253 total += r; - range(total); // $ MISSING: range=>=1 + range(total); // $ range=>=55 range=<=253 } if (0 <= b && b <= 23) { range(b); // $ range=<=23 range=>=0 int r = 11*b; // 0 .. 253 - range(r); - total += r; // $ overflow=+ - range(total); // $ MISSING: range=">=(unsigned int)...+0" range=>=0 + range(r); // $ range=>=0 range=<=253 + total += r; + range(total); // $ range=">=(unsigned int)...+0" range=>=0 range="<=(unsigned int)...+253" range=<=506 } if (13 <= b && b <= 23) { range(b); // $ range=<=23 range=>=13 int r = 11*b; // 143 .. 253 - range(r); - total += r; // $ overflow=+ - range(total); // $ MISSING: range=">=(unsigned int)...+1" range=>=1 + range(r); // $ range=>=143 range=<=253 + total += r; + range(total); // $ range="<=(unsigned int)...+253" range="<=(unsigned int)...+506" range=">=(unsigned int)...+143" range=>=143 range=<=759 } - range(total); // $ MISSING: range=">=(unsigned int)...+0" range=>=0 + range(total); // $ range=>=0 range=<=759 range=">=(unsigned int)...+0" range="<=(unsigned int)...+506" range="<=(unsigned int)...+253" return total; } @@ -888,7 +888,7 @@ void notequal_variations(short n, float f) { } if (n >= 5) { - if (2 * n - 10 == 0) { // $ overflow=+ Same as `n == 10/2` (modulo overflow) + if (2 * n - 10 == 0) { // $ overflow=+ range(n); // $ range=>=5 MISSING: range===5 return; } diff --git a/cpp/ql/test/library-tests/ir/sign-analysis/SignAnalysis.ql b/cpp/ql/test/library-tests/ir/sign-analysis/SignAnalysis.ql index 7b78b077a9b..8f95759ec7d 100644 --- a/cpp/ql/test/library-tests/ir/sign-analysis/SignAnalysis.ql +++ b/cpp/ql/test/library-tests/ir/sign-analysis/SignAnalysis.ql @@ -1,10 +1,10 @@ import cpp -import experimental.semmle.code.cpp.semantic.analysis.SignAnalysisCommon -import experimental.semmle.code.cpp.semantic.Semantic -import experimental.semmle.code.cpp.semantic.analysis.RangeUtils -import experimental.semmle.code.cpp.semantic.analysis.FloatDelta -import experimental.semmle.code.cpp.semantic.analysis.RangeAnalysisSpecific -import experimental.semmle.code.cpp.semantic.SemanticExprSpecific +import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.SignAnalysisCommon +import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic +import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeUtils +import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.FloatDelta +import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeAnalysisSpecific +import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticExprSpecific import semmle.code.cpp.ir.IR as IR import TestUtilities.InlineExpectationsTest diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll index 2790ff1465e..8e8661f82d5 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll @@ -239,6 +239,14 @@ module LocalFlow { scope = e2 and isSuccessor = true or + e1 = e2.(CheckedExpr).getExpr() and + scope = e2 and + isSuccessor = true + or + e1 = e2.(UncheckedExpr).getExpr() and + scope = e2 and + isSuccessor = true + or exists(WithExpr we | scope = we and isSuccessor = true diff --git a/csharp/ql/src/experimental/ir/implementation/raw/gvn/internal/ValueNumberingInternal.qll b/csharp/ql/src/experimental/ir/implementation/raw/gvn/internal/ValueNumberingInternal.qll index 2dc735f49df..85a28fbc677 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/gvn/internal/ValueNumberingInternal.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/gvn/internal/ValueNumberingInternal.qll @@ -159,26 +159,56 @@ private predicate fieldAddressValueNumber( tvalueNumber(instr.getObjectAddress()) = objectAddress } +pragma[nomagic] +private predicate binaryValueNumber0( + BinaryInstruction instr, IRFunction irFunc, Opcode opcode, boolean isLeft, + TValueNumber valueNumber +) { + not instr instanceof PointerArithmeticInstruction and + instr.getEnclosingIRFunction() = irFunc and + instr.getOpcode() = opcode and + ( + isLeft = true and + tvalueNumber(instr.getLeft()) = valueNumber + or + isLeft = false and + tvalueNumber(instr.getRight()) = valueNumber + ) +} + +pragma[assume_small_delta] private predicate binaryValueNumber( BinaryInstruction instr, IRFunction irFunc, Opcode opcode, TValueNumber leftOperand, TValueNumber rightOperand ) { - instr.getEnclosingIRFunction() = irFunc and - not instr instanceof PointerArithmeticInstruction and - instr.getOpcode() = opcode and - tvalueNumber(instr.getLeft()) = leftOperand and - tvalueNumber(instr.getRight()) = rightOperand + binaryValueNumber0(instr, irFunc, opcode, true, leftOperand) and + binaryValueNumber0(instr, irFunc, opcode, false, rightOperand) } -private predicate pointerArithmeticValueNumber( +pragma[nomagic] +private predicate pointerArithmeticValueNumber0( PointerArithmeticInstruction instr, IRFunction irFunc, Opcode opcode, int elementSize, - TValueNumber leftOperand, TValueNumber rightOperand + boolean isLeft, TValueNumber valueNumber ) { instr.getEnclosingIRFunction() = irFunc and instr.getOpcode() = opcode and instr.getElementSize() = elementSize and - tvalueNumber(instr.getLeft()) = leftOperand and - tvalueNumber(instr.getRight()) = rightOperand + ( + isLeft = true and + tvalueNumber(instr.getLeft()) = valueNumber + or + isLeft = false and + tvalueNumber(instr.getRight()) = valueNumber + ) +} + +pragma[assume_small_delta] +private predicate pointerArithmeticValueNumber( + PointerArithmeticInstruction instr, IRFunction irFunc, Opcode opcode, int elementSize, + TValueNumber leftOperand, TValueNumber rightOperand +) { + pointerArithmeticValueNumber0(instr, irFunc, opcode, elementSize, true, leftOperand) and + pointerArithmeticValueNumber0(instr, irFunc, opcode, elementSize, false, rightOperand) } private predicate unaryValueNumber( @@ -203,14 +233,29 @@ private predicate inheritanceConversionValueNumber( unique( | | instr.getDerivedClass()) = derivedClass } +pragma[nomagic] +private predicate loadTotalOverlapValueNumber0( + LoadTotalOverlapInstruction instr, IRFunction irFunc, IRType type, TValueNumber valueNumber, + boolean isAddress +) { + instr.getEnclosingIRFunction() = irFunc and + instr.getResultIRType() = type and + ( + isAddress = true and + tvalueNumberOfOperand(instr.getSourceAddressOperand()) = valueNumber + or + isAddress = false and + tvalueNumber(instr.getSourceValueOperand().getAnyDef()) = valueNumber + ) +} + +pragma[assume_small_delta] private predicate loadTotalOverlapValueNumber( LoadTotalOverlapInstruction instr, IRFunction irFunc, IRType type, TValueNumber memOperand, TValueNumber operand ) { - instr.getEnclosingIRFunction() = irFunc and - tvalueNumber(instr.getAnOperand().(MemoryOperand).getAnyDef()) = memOperand and - tvalueNumberOfOperand(instr.getAnOperand().(AddressOperand)) = operand and - instr.getResultIRType() = type + loadTotalOverlapValueNumber0(instr, irFunc, type, operand, true) and + loadTotalOverlapValueNumber0(instr, irFunc, type, memOperand, false) } /** diff --git a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/gvn/internal/ValueNumberingInternal.qll b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/gvn/internal/ValueNumberingInternal.qll index 2dc735f49df..85a28fbc677 100644 --- a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/gvn/internal/ValueNumberingInternal.qll +++ b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/gvn/internal/ValueNumberingInternal.qll @@ -159,26 +159,56 @@ private predicate fieldAddressValueNumber( tvalueNumber(instr.getObjectAddress()) = objectAddress } +pragma[nomagic] +private predicate binaryValueNumber0( + BinaryInstruction instr, IRFunction irFunc, Opcode opcode, boolean isLeft, + TValueNumber valueNumber +) { + not instr instanceof PointerArithmeticInstruction and + instr.getEnclosingIRFunction() = irFunc and + instr.getOpcode() = opcode and + ( + isLeft = true and + tvalueNumber(instr.getLeft()) = valueNumber + or + isLeft = false and + tvalueNumber(instr.getRight()) = valueNumber + ) +} + +pragma[assume_small_delta] private predicate binaryValueNumber( BinaryInstruction instr, IRFunction irFunc, Opcode opcode, TValueNumber leftOperand, TValueNumber rightOperand ) { - instr.getEnclosingIRFunction() = irFunc and - not instr instanceof PointerArithmeticInstruction and - instr.getOpcode() = opcode and - tvalueNumber(instr.getLeft()) = leftOperand and - tvalueNumber(instr.getRight()) = rightOperand + binaryValueNumber0(instr, irFunc, opcode, true, leftOperand) and + binaryValueNumber0(instr, irFunc, opcode, false, rightOperand) } -private predicate pointerArithmeticValueNumber( +pragma[nomagic] +private predicate pointerArithmeticValueNumber0( PointerArithmeticInstruction instr, IRFunction irFunc, Opcode opcode, int elementSize, - TValueNumber leftOperand, TValueNumber rightOperand + boolean isLeft, TValueNumber valueNumber ) { instr.getEnclosingIRFunction() = irFunc and instr.getOpcode() = opcode and instr.getElementSize() = elementSize and - tvalueNumber(instr.getLeft()) = leftOperand and - tvalueNumber(instr.getRight()) = rightOperand + ( + isLeft = true and + tvalueNumber(instr.getLeft()) = valueNumber + or + isLeft = false and + tvalueNumber(instr.getRight()) = valueNumber + ) +} + +pragma[assume_small_delta] +private predicate pointerArithmeticValueNumber( + PointerArithmeticInstruction instr, IRFunction irFunc, Opcode opcode, int elementSize, + TValueNumber leftOperand, TValueNumber rightOperand +) { + pointerArithmeticValueNumber0(instr, irFunc, opcode, elementSize, true, leftOperand) and + pointerArithmeticValueNumber0(instr, irFunc, opcode, elementSize, false, rightOperand) } private predicate unaryValueNumber( @@ -203,14 +233,29 @@ private predicate inheritanceConversionValueNumber( unique( | | instr.getDerivedClass()) = derivedClass } +pragma[nomagic] +private predicate loadTotalOverlapValueNumber0( + LoadTotalOverlapInstruction instr, IRFunction irFunc, IRType type, TValueNumber valueNumber, + boolean isAddress +) { + instr.getEnclosingIRFunction() = irFunc and + instr.getResultIRType() = type and + ( + isAddress = true and + tvalueNumberOfOperand(instr.getSourceAddressOperand()) = valueNumber + or + isAddress = false and + tvalueNumber(instr.getSourceValueOperand().getAnyDef()) = valueNumber + ) +} + +pragma[assume_small_delta] private predicate loadTotalOverlapValueNumber( LoadTotalOverlapInstruction instr, IRFunction irFunc, IRType type, TValueNumber memOperand, TValueNumber operand ) { - instr.getEnclosingIRFunction() = irFunc and - tvalueNumber(instr.getAnOperand().(MemoryOperand).getAnyDef()) = memOperand and - tvalueNumberOfOperand(instr.getAnOperand().(AddressOperand)) = operand and - instr.getResultIRType() = type + loadTotalOverlapValueNumber0(instr, irFunc, type, operand, true) and + loadTotalOverlapValueNumber0(instr, irFunc, type, memOperand, false) } /** diff --git a/csharp/ql/test/library-tests/dataflow/operators/Operator.cs b/csharp/ql/test/library-tests/dataflow/operators/Operator.cs new file mode 100644 index 00000000000..946a3b676cf --- /dev/null +++ b/csharp/ql/test/library-tests/dataflow/operators/Operator.cs @@ -0,0 +1,87 @@ +public class Operators +{ + + static void Sink(object o) { } + static T Source(object source) => throw null; + + public interface I where T : I + { + static virtual T operator *(T x, T y) => x; + static abstract T operator /(T x, T y); + static abstract T operator checked /(T x, T y); + } + + public class C : I + { + public static C operator +(C x, C y) => x; + + public static C operator checked -(C x, C y) => y; + public static C operator -(C x, C y) => x; + + public static C operator /(C x, C y) => y; + public static C operator checked /(C x, C y) => y; + } + + public void M1() + { + var x = Source(1); + var y = Source(2); + var z = x + y; + Sink(z); // $ hasValueFlow=1 + } + + public void M2() + { + var x = Source(3); + var y = Source(4); + var z = unchecked(x - y); + Sink(z); // $ hasValueFlow=3 + } + + public void M3() + { + var x = Source(5); + var y = Source(6); + var z = checked(x - y); + Sink(z); // $ hasValueFlow=6 + } + + public void M4Aux(T x, T y) where T : I + { + var z = x * y; + Sink(z); // $ hasValueFlow=7 + } + + public void M4() + { + var x = Source(7); + var y = Source(8); + M4Aux(x, y); + } + + public void M5Aux(T x, T y) where T : I + { + var z = x / y; + Sink(z); // $ hasValueFlow=10 + } + + public void M5() + { + var x = Source(9); + var y = Source(10); + M5Aux(x, y); + } + + public void M6Aux(T x, T y) where T : I + { + var z = checked(x / y); + Sink(z); // $ hasValueFlow=12 + } + + public void M6() + { + var x = Source(11); + var y = Source(12); + M6Aux(x, y); + } +} \ No newline at end of file diff --git a/csharp/ql/test/library-tests/dataflow/operators/operatorFlow.expected b/csharp/ql/test/library-tests/dataflow/operators/operatorFlow.expected new file mode 100644 index 00000000000..c5c80bf9f44 --- /dev/null +++ b/csharp/ql/test/library-tests/dataflow/operators/operatorFlow.expected @@ -0,0 +1,179 @@ +failures +edges +| Operator.cs:9:39:9:39 | x : C | Operator.cs:9:50:9:50 | access to parameter x : C | +| Operator.cs:9:39:9:39 | x : C | Operator.cs:9:50:9:50 | access to parameter x : C | +| Operator.cs:16:38:16:38 | x : C | Operator.cs:16:49:16:49 | access to parameter x : C | +| Operator.cs:16:38:16:38 | x : C | Operator.cs:16:49:16:49 | access to parameter x : C | +| Operator.cs:18:51:18:51 | y : C | Operator.cs:18:57:18:57 | access to parameter y : C | +| Operator.cs:18:51:18:51 | y : C | Operator.cs:18:57:18:57 | access to parameter y : C | +| Operator.cs:19:38:19:38 | x : C | Operator.cs:19:49:19:49 | access to parameter x : C | +| Operator.cs:19:38:19:38 | x : C | Operator.cs:19:49:19:49 | access to parameter x : C | +| Operator.cs:21:43:21:43 | y : C | Operator.cs:21:49:21:49 | access to parameter y : C | +| Operator.cs:21:43:21:43 | y : C | Operator.cs:21:49:21:49 | access to parameter y : C | +| Operator.cs:22:51:22:51 | y : C | Operator.cs:22:57:22:57 | access to parameter y : C | +| Operator.cs:22:51:22:51 | y : C | Operator.cs:22:57:22:57 | access to parameter y : C | +| Operator.cs:27:17:27:28 | call to method Source : C | Operator.cs:29:17:29:17 | access to local variable x : C | +| Operator.cs:27:17:27:28 | call to method Source : C | Operator.cs:29:17:29:17 | access to local variable x : C | +| Operator.cs:29:17:29:17 | access to local variable x : C | Operator.cs:16:38:16:38 | x : C | +| Operator.cs:29:17:29:17 | access to local variable x : C | Operator.cs:16:38:16:38 | x : C | +| Operator.cs:29:17:29:17 | access to local variable x : C | Operator.cs:29:17:29:21 | call to operator + : C | +| Operator.cs:29:17:29:17 | access to local variable x : C | Operator.cs:29:17:29:21 | call to operator + : C | +| Operator.cs:29:17:29:21 | call to operator + : C | Operator.cs:30:14:30:14 | access to local variable z | +| Operator.cs:29:17:29:21 | call to operator + : C | Operator.cs:30:14:30:14 | access to local variable z | +| Operator.cs:35:17:35:28 | call to method Source : C | Operator.cs:37:27:37:27 | access to local variable x : C | +| Operator.cs:35:17:35:28 | call to method Source : C | Operator.cs:37:27:37:27 | access to local variable x : C | +| Operator.cs:37:27:37:27 | access to local variable x : C | Operator.cs:19:38:19:38 | x : C | +| Operator.cs:37:27:37:27 | access to local variable x : C | Operator.cs:19:38:19:38 | x : C | +| Operator.cs:37:27:37:27 | access to local variable x : C | Operator.cs:37:27:37:31 | call to operator - : C | +| Operator.cs:37:27:37:27 | access to local variable x : C | Operator.cs:37:27:37:31 | call to operator - : C | +| Operator.cs:37:27:37:31 | call to operator - : C | Operator.cs:38:14:38:14 | access to local variable z | +| Operator.cs:37:27:37:31 | call to operator - : C | Operator.cs:38:14:38:14 | access to local variable z | +| Operator.cs:44:17:44:28 | call to method Source : C | Operator.cs:45:29:45:29 | access to local variable y : C | +| Operator.cs:44:17:44:28 | call to method Source : C | Operator.cs:45:29:45:29 | access to local variable y : C | +| Operator.cs:45:25:45:29 | call to operator checked - : C | Operator.cs:46:14:46:14 | access to local variable z | +| Operator.cs:45:25:45:29 | call to operator checked - : C | Operator.cs:46:14:46:14 | access to local variable z | +| Operator.cs:45:29:45:29 | access to local variable y : C | Operator.cs:18:51:18:51 | y : C | +| Operator.cs:45:29:45:29 | access to local variable y : C | Operator.cs:18:51:18:51 | y : C | +| Operator.cs:45:29:45:29 | access to local variable y : C | Operator.cs:45:25:45:29 | call to operator checked - : C | +| Operator.cs:45:29:45:29 | access to local variable y : C | Operator.cs:45:25:45:29 | call to operator checked - : C | +| Operator.cs:49:28:49:28 | x : C | Operator.cs:51:17:51:17 | access to parameter x : C | +| Operator.cs:49:28:49:28 | x : C | Operator.cs:51:17:51:17 | access to parameter x : C | +| Operator.cs:51:17:51:17 | access to parameter x : C | Operator.cs:9:39:9:39 | x : C | +| Operator.cs:51:17:51:17 | access to parameter x : C | Operator.cs:9:39:9:39 | x : C | +| Operator.cs:51:17:51:17 | access to parameter x : C | Operator.cs:51:17:51:21 | call to operator * : C | +| Operator.cs:51:17:51:17 | access to parameter x : C | Operator.cs:51:17:51:21 | call to operator * : C | +| Operator.cs:51:17:51:21 | call to operator * : C | Operator.cs:52:14:52:14 | (...) ... | +| Operator.cs:51:17:51:21 | call to operator * : C | Operator.cs:52:14:52:14 | (...) ... | +| Operator.cs:57:17:57:28 | call to method Source : C | Operator.cs:59:15:59:15 | access to local variable x : C | +| Operator.cs:57:17:57:28 | call to method Source : C | Operator.cs:59:15:59:15 | access to local variable x : C | +| Operator.cs:59:15:59:15 | access to local variable x : C | Operator.cs:49:28:49:28 | x : C | +| Operator.cs:59:15:59:15 | access to local variable x : C | Operator.cs:49:28:49:28 | x : C | +| Operator.cs:62:33:62:33 | y : C | Operator.cs:64:21:64:21 | access to parameter y : C | +| Operator.cs:62:33:62:33 | y : C | Operator.cs:64:21:64:21 | access to parameter y : C | +| Operator.cs:64:17:64:21 | call to operator / : C | Operator.cs:65:14:65:14 | (...) ... | +| Operator.cs:64:17:64:21 | call to operator / : C | Operator.cs:65:14:65:14 | (...) ... | +| Operator.cs:64:21:64:21 | access to parameter y : C | Operator.cs:21:43:21:43 | y : C | +| Operator.cs:64:21:64:21 | access to parameter y : C | Operator.cs:21:43:21:43 | y : C | +| Operator.cs:64:21:64:21 | access to parameter y : C | Operator.cs:64:17:64:21 | call to operator / : C | +| Operator.cs:64:21:64:21 | access to parameter y : C | Operator.cs:64:17:64:21 | call to operator / : C | +| Operator.cs:71:17:71:29 | call to method Source : C | Operator.cs:72:18:72:18 | access to local variable y : C | +| Operator.cs:71:17:71:29 | call to method Source : C | Operator.cs:72:18:72:18 | access to local variable y : C | +| Operator.cs:72:18:72:18 | access to local variable y : C | Operator.cs:62:33:62:33 | y : C | +| Operator.cs:72:18:72:18 | access to local variable y : C | Operator.cs:62:33:62:33 | y : C | +| Operator.cs:75:33:75:33 | y : C | Operator.cs:77:29:77:29 | access to parameter y : C | +| Operator.cs:75:33:75:33 | y : C | Operator.cs:77:29:77:29 | access to parameter y : C | +| Operator.cs:77:25:77:29 | call to operator checked / : C | Operator.cs:78:14:78:14 | (...) ... | +| Operator.cs:77:25:77:29 | call to operator checked / : C | Operator.cs:78:14:78:14 | (...) ... | +| Operator.cs:77:29:77:29 | access to parameter y : C | Operator.cs:22:51:22:51 | y : C | +| Operator.cs:77:29:77:29 | access to parameter y : C | Operator.cs:22:51:22:51 | y : C | +| Operator.cs:77:29:77:29 | access to parameter y : C | Operator.cs:77:25:77:29 | call to operator checked / : C | +| Operator.cs:77:29:77:29 | access to parameter y : C | Operator.cs:77:25:77:29 | call to operator checked / : C | +| Operator.cs:84:17:84:29 | call to method Source : C | Operator.cs:85:18:85:18 | access to local variable y : C | +| Operator.cs:84:17:84:29 | call to method Source : C | Operator.cs:85:18:85:18 | access to local variable y : C | +| Operator.cs:85:18:85:18 | access to local variable y : C | Operator.cs:75:33:75:33 | y : C | +| Operator.cs:85:18:85:18 | access to local variable y : C | Operator.cs:75:33:75:33 | y : C | +nodes +| Operator.cs:9:39:9:39 | x : C | semmle.label | x : C | +| Operator.cs:9:39:9:39 | x : C | semmle.label | x : C | +| Operator.cs:9:50:9:50 | access to parameter x : C | semmle.label | access to parameter x : C | +| Operator.cs:9:50:9:50 | access to parameter x : C | semmle.label | access to parameter x : C | +| Operator.cs:16:38:16:38 | x : C | semmle.label | x : C | +| Operator.cs:16:38:16:38 | x : C | semmle.label | x : C | +| Operator.cs:16:49:16:49 | access to parameter x : C | semmle.label | access to parameter x : C | +| Operator.cs:16:49:16:49 | access to parameter x : C | semmle.label | access to parameter x : C | +| Operator.cs:18:51:18:51 | y : C | semmle.label | y : C | +| Operator.cs:18:51:18:51 | y : C | semmle.label | y : C | +| Operator.cs:18:57:18:57 | access to parameter y : C | semmle.label | access to parameter y : C | +| Operator.cs:18:57:18:57 | access to parameter y : C | semmle.label | access to parameter y : C | +| Operator.cs:19:38:19:38 | x : C | semmle.label | x : C | +| Operator.cs:19:38:19:38 | x : C | semmle.label | x : C | +| Operator.cs:19:49:19:49 | access to parameter x : C | semmle.label | access to parameter x : C | +| Operator.cs:19:49:19:49 | access to parameter x : C | semmle.label | access to parameter x : C | +| Operator.cs:21:43:21:43 | y : C | semmle.label | y : C | +| Operator.cs:21:43:21:43 | y : C | semmle.label | y : C | +| Operator.cs:21:49:21:49 | access to parameter y : C | semmle.label | access to parameter y : C | +| Operator.cs:21:49:21:49 | access to parameter y : C | semmle.label | access to parameter y : C | +| Operator.cs:22:51:22:51 | y : C | semmle.label | y : C | +| Operator.cs:22:51:22:51 | y : C | semmle.label | y : C | +| Operator.cs:22:57:22:57 | access to parameter y : C | semmle.label | access to parameter y : C | +| Operator.cs:22:57:22:57 | access to parameter y : C | semmle.label | access to parameter y : C | +| Operator.cs:27:17:27:28 | call to method Source : C | semmle.label | call to method Source : C | +| Operator.cs:27:17:27:28 | call to method Source : C | semmle.label | call to method Source : C | +| Operator.cs:29:17:29:17 | access to local variable x : C | semmle.label | access to local variable x : C | +| Operator.cs:29:17:29:17 | access to local variable x : C | semmle.label | access to local variable x : C | +| Operator.cs:29:17:29:21 | call to operator + : C | semmle.label | call to operator + : C | +| Operator.cs:29:17:29:21 | call to operator + : C | semmle.label | call to operator + : C | +| Operator.cs:30:14:30:14 | access to local variable z | semmle.label | access to local variable z | +| Operator.cs:30:14:30:14 | access to local variable z | semmle.label | access to local variable z | +| Operator.cs:35:17:35:28 | call to method Source : C | semmle.label | call to method Source : C | +| Operator.cs:35:17:35:28 | call to method Source : C | semmle.label | call to method Source : C | +| Operator.cs:37:27:37:27 | access to local variable x : C | semmle.label | access to local variable x : C | +| Operator.cs:37:27:37:27 | access to local variable x : C | semmle.label | access to local variable x : C | +| Operator.cs:37:27:37:31 | call to operator - : C | semmle.label | call to operator - : C | +| Operator.cs:37:27:37:31 | call to operator - : C | semmle.label | call to operator - : C | +| Operator.cs:38:14:38:14 | access to local variable z | semmle.label | access to local variable z | +| Operator.cs:38:14:38:14 | access to local variable z | semmle.label | access to local variable z | +| Operator.cs:44:17:44:28 | call to method Source : C | semmle.label | call to method Source : C | +| Operator.cs:44:17:44:28 | call to method Source : C | semmle.label | call to method Source : C | +| Operator.cs:45:25:45:29 | call to operator checked - : C | semmle.label | call to operator checked - : C | +| Operator.cs:45:25:45:29 | call to operator checked - : C | semmle.label | call to operator checked - : C | +| Operator.cs:45:29:45:29 | access to local variable y : C | semmle.label | access to local variable y : C | +| Operator.cs:45:29:45:29 | access to local variable y : C | semmle.label | access to local variable y : C | +| Operator.cs:46:14:46:14 | access to local variable z | semmle.label | access to local variable z | +| Operator.cs:46:14:46:14 | access to local variable z | semmle.label | access to local variable z | +| Operator.cs:49:28:49:28 | x : C | semmle.label | x : C | +| Operator.cs:49:28:49:28 | x : C | semmle.label | x : C | +| Operator.cs:51:17:51:17 | access to parameter x : C | semmle.label | access to parameter x : C | +| Operator.cs:51:17:51:17 | access to parameter x : C | semmle.label | access to parameter x : C | +| Operator.cs:51:17:51:21 | call to operator * : C | semmle.label | call to operator * : C | +| Operator.cs:51:17:51:21 | call to operator * : C | semmle.label | call to operator * : C | +| Operator.cs:52:14:52:14 | (...) ... | semmle.label | (...) ... | +| Operator.cs:52:14:52:14 | (...) ... | semmle.label | (...) ... | +| Operator.cs:57:17:57:28 | call to method Source : C | semmle.label | call to method Source : C | +| Operator.cs:57:17:57:28 | call to method Source : C | semmle.label | call to method Source : C | +| Operator.cs:59:15:59:15 | access to local variable x : C | semmle.label | access to local variable x : C | +| Operator.cs:59:15:59:15 | access to local variable x : C | semmle.label | access to local variable x : C | +| Operator.cs:62:33:62:33 | y : C | semmle.label | y : C | +| Operator.cs:62:33:62:33 | y : C | semmle.label | y : C | +| Operator.cs:64:17:64:21 | call to operator / : C | semmle.label | call to operator / : C | +| Operator.cs:64:17:64:21 | call to operator / : C | semmle.label | call to operator / : C | +| Operator.cs:64:21:64:21 | access to parameter y : C | semmle.label | access to parameter y : C | +| Operator.cs:64:21:64:21 | access to parameter y : C | semmle.label | access to parameter y : C | +| Operator.cs:65:14:65:14 | (...) ... | semmle.label | (...) ... | +| Operator.cs:65:14:65:14 | (...) ... | semmle.label | (...) ... | +| Operator.cs:71:17:71:29 | call to method Source : C | semmle.label | call to method Source : C | +| Operator.cs:71:17:71:29 | call to method Source : C | semmle.label | call to method Source : C | +| Operator.cs:72:18:72:18 | access to local variable y : C | semmle.label | access to local variable y : C | +| Operator.cs:72:18:72:18 | access to local variable y : C | semmle.label | access to local variable y : C | +| Operator.cs:75:33:75:33 | y : C | semmle.label | y : C | +| Operator.cs:75:33:75:33 | y : C | semmle.label | y : C | +| Operator.cs:77:25:77:29 | call to operator checked / : C | semmle.label | call to operator checked / : C | +| Operator.cs:77:25:77:29 | call to operator checked / : C | semmle.label | call to operator checked / : C | +| Operator.cs:77:29:77:29 | access to parameter y : C | semmle.label | access to parameter y : C | +| Operator.cs:77:29:77:29 | access to parameter y : C | semmle.label | access to parameter y : C | +| Operator.cs:78:14:78:14 | (...) ... | semmle.label | (...) ... | +| Operator.cs:78:14:78:14 | (...) ... | semmle.label | (...) ... | +| Operator.cs:84:17:84:29 | call to method Source : C | semmle.label | call to method Source : C | +| Operator.cs:84:17:84:29 | call to method Source : C | semmle.label | call to method Source : C | +| Operator.cs:85:18:85:18 | access to local variable y : C | semmle.label | access to local variable y : C | +| Operator.cs:85:18:85:18 | access to local variable y : C | semmle.label | access to local variable y : C | +subpaths +| Operator.cs:29:17:29:17 | access to local variable x : C | Operator.cs:16:38:16:38 | x : C | Operator.cs:16:49:16:49 | access to parameter x : C | Operator.cs:29:17:29:21 | call to operator + : C | +| Operator.cs:29:17:29:17 | access to local variable x : C | Operator.cs:16:38:16:38 | x : C | Operator.cs:16:49:16:49 | access to parameter x : C | Operator.cs:29:17:29:21 | call to operator + : C | +| Operator.cs:37:27:37:27 | access to local variable x : C | Operator.cs:19:38:19:38 | x : C | Operator.cs:19:49:19:49 | access to parameter x : C | Operator.cs:37:27:37:31 | call to operator - : C | +| Operator.cs:37:27:37:27 | access to local variable x : C | Operator.cs:19:38:19:38 | x : C | Operator.cs:19:49:19:49 | access to parameter x : C | Operator.cs:37:27:37:31 | call to operator - : C | +| Operator.cs:45:29:45:29 | access to local variable y : C | Operator.cs:18:51:18:51 | y : C | Operator.cs:18:57:18:57 | access to parameter y : C | Operator.cs:45:25:45:29 | call to operator checked - : C | +| Operator.cs:45:29:45:29 | access to local variable y : C | Operator.cs:18:51:18:51 | y : C | Operator.cs:18:57:18:57 | access to parameter y : C | Operator.cs:45:25:45:29 | call to operator checked - : C | +| Operator.cs:51:17:51:17 | access to parameter x : C | Operator.cs:9:39:9:39 | x : C | Operator.cs:9:50:9:50 | access to parameter x : C | Operator.cs:51:17:51:21 | call to operator * : C | +| Operator.cs:51:17:51:17 | access to parameter x : C | Operator.cs:9:39:9:39 | x : C | Operator.cs:9:50:9:50 | access to parameter x : C | Operator.cs:51:17:51:21 | call to operator * : C | +| Operator.cs:64:21:64:21 | access to parameter y : C | Operator.cs:21:43:21:43 | y : C | Operator.cs:21:49:21:49 | access to parameter y : C | Operator.cs:64:17:64:21 | call to operator / : C | +| Operator.cs:64:21:64:21 | access to parameter y : C | Operator.cs:21:43:21:43 | y : C | Operator.cs:21:49:21:49 | access to parameter y : C | Operator.cs:64:17:64:21 | call to operator / : C | +| Operator.cs:77:29:77:29 | access to parameter y : C | Operator.cs:22:51:22:51 | y : C | Operator.cs:22:57:22:57 | access to parameter y : C | Operator.cs:77:25:77:29 | call to operator checked / : C | +| Operator.cs:77:29:77:29 | access to parameter y : C | Operator.cs:22:51:22:51 | y : C | Operator.cs:22:57:22:57 | access to parameter y : C | Operator.cs:77:25:77:29 | call to operator checked / : C | +#select +| Operator.cs:30:14:30:14 | access to local variable z | Operator.cs:27:17:27:28 | call to method Source : C | Operator.cs:30:14:30:14 | access to local variable z | $@ | Operator.cs:27:17:27:28 | call to method Source : C | call to method Source : C | +| Operator.cs:38:14:38:14 | access to local variable z | Operator.cs:35:17:35:28 | call to method Source : C | Operator.cs:38:14:38:14 | access to local variable z | $@ | Operator.cs:35:17:35:28 | call to method Source : C | call to method Source : C | +| Operator.cs:46:14:46:14 | access to local variable z | Operator.cs:44:17:44:28 | call to method Source : C | Operator.cs:46:14:46:14 | access to local variable z | $@ | Operator.cs:44:17:44:28 | call to method Source : C | call to method Source : C | +| Operator.cs:52:14:52:14 | (...) ... | Operator.cs:57:17:57:28 | call to method Source : C | Operator.cs:52:14:52:14 | (...) ... | $@ | Operator.cs:57:17:57:28 | call to method Source : C | call to method Source : C | +| Operator.cs:65:14:65:14 | (...) ... | Operator.cs:71:17:71:29 | call to method Source : C | Operator.cs:65:14:65:14 | (...) ... | $@ | Operator.cs:71:17:71:29 | call to method Source : C | call to method Source : C | +| Operator.cs:78:14:78:14 | (...) ... | Operator.cs:84:17:84:29 | call to method Source : C | Operator.cs:78:14:78:14 | (...) ... | $@ | Operator.cs:84:17:84:29 | call to method Source : C | call to method Source : C | diff --git a/csharp/ql/test/library-tests/dataflow/operators/operatorFlow.ql b/csharp/ql/test/library-tests/dataflow/operators/operatorFlow.ql new file mode 100644 index 00000000000..55578cf970c --- /dev/null +++ b/csharp/ql/test/library-tests/dataflow/operators/operatorFlow.ql @@ -0,0 +1,11 @@ +/** + * @kind path-problem + */ + +import csharp +import DataFlow::PathGraph +import TestUtilities.InlineFlowTest + +from DataFlow::PathNode source, DataFlow::PathNode sink, DefaultValueFlowConf conf +where conf.hasFlowPath(source, sink) +select sink, source, sink, "$@", source, source.toString() diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst index a50b6b11a85..d8a9e15faf5 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst @@ -30,7 +30,7 @@ The CodeQL library for JavaScript exposes the following extensible predicates: - **typeModel**\(type1, type2, path) - **summaryModel**\(type, path, input, output, kind) -See the [CLI documentation for how to load and use data extensions in a CodeQL evaluation run](https://docs.google.com/document/d/14IYCHX8wWuU-HTvJ2gPSdXQKHKYbWCHQKOgn8oLaa80/edit#heading=h.m0v53lpi6w2n) (internal access required). +See the `CLI documentation for how to load and use data extensions in a CodeQL evaluation run `__ (internal access required). We'll explain how to use these using a few examples, and provide some reference material at the end of this article. diff --git a/go/ql/lib/printAst.ql b/go/ql/lib/printAst.ql index 9d6d5c2d7b9..1ea2c9548d5 100644 --- a/go/ql/lib/printAst.ql +++ b/go/ql/lib/printAst.ql @@ -12,12 +12,12 @@ import semmle.go.PrintAst import ideContextual /** - * The source file to generate an AST from. + * Gets the source file to generate an AST from. */ external string selectedSourceFile(); /** - * Hook to customize the functions printed by this query. + * A hook to customize the functions printed by this query. */ class Cfg extends PrintAstConfiguration { override predicate shouldPrintFunction(FuncDecl func) { shouldPrintFile(func.getFile()) } diff --git a/go/ql/lib/semmle/go/Concepts.qll b/go/ql/lib/semmle/go/Concepts.qll index c6043ae46b3..2fb4e35d94b 100644 --- a/go/ql/lib/semmle/go/Concepts.qll +++ b/go/ql/lib/semmle/go/Concepts.qll @@ -115,7 +115,7 @@ module FileSystemAccess { /** A function that escapes meta-characters to prevent injection attacks. */ class EscapeFunction extends Function instanceof EscapeFunction::Range { /** - * The context that this function escapes for. + * Gets the context that this function escapes for. * * Currently, this can be "js", "html", or "url". */ @@ -132,7 +132,7 @@ module EscapeFunction { */ abstract class Range extends Function { /** - * The context that this function escapes for. + * Gets the context that this function escapes for. * * Currently, this can be `js', `html', or `url'. */ diff --git a/go/ql/lib/semmle/go/Files.qll b/go/ql/lib/semmle/go/Files.qll index b261b935318..11d7d337a41 100644 --- a/go/ql/lib/semmle/go/Files.qll +++ b/go/ql/lib/semmle/go/Files.qll @@ -181,7 +181,7 @@ class Folder extends Container, @folder { override string getURL() { result = "folder://" + this.getAbsolutePath() } } -/** Any file, including files that have not been extracted but are referred to as locations for errors. */ +/** A file, including files that have not been extracted but are referred to as locations for errors. */ class ExtractedOrExternalFile extends Container, @file, Documentable, ExprParent, GoModExprParent, DeclParent, ScopeNode { diff --git a/go/ql/lib/semmle/go/PrintAst.ql b/go/ql/lib/semmle/go/PrintAst.ql index 23b6b123b06..6e0c1ce06f3 100644 --- a/go/ql/lib/semmle/go/PrintAst.ql +++ b/go/ql/lib/semmle/go/PrintAst.ql @@ -9,7 +9,7 @@ import go import PrintAst /** - * Hook to customize the functions printed by this query. + * A hook to customize the functions printed by this query. */ class Cfg extends PrintAstConfiguration { override predicate shouldPrintFunction(FuncDecl func) { any() } diff --git a/go/ql/lib/semmle/go/PrintAst.qll b/go/ql/lib/semmle/go/PrintAst.qll index cf28be44f49..b15144ade97 100644 --- a/go/ql/lib/semmle/go/PrintAst.qll +++ b/go/ql/lib/semmle/go/PrintAst.qll @@ -5,7 +5,7 @@ import go /** - * Hook to customize the files and functions printed by this module. + * A hook to customize the files and functions printed by this module. * * For an AstNode to be printed, it always requires `shouldPrintFile(f)` to hold * for its containing file `f`, and additionally requires `shouldPrintFunction(fun)` diff --git a/go/ql/lib/semmle/go/Scopes.qll b/go/ql/lib/semmle/go/Scopes.qll index 385b52028d9..28a32fe3de5 100644 --- a/go/ql/lib/semmle/go/Scopes.qll +++ b/go/ql/lib/semmle/go/Scopes.qll @@ -602,7 +602,7 @@ private newtype TCallable = TFuncLitCallable(FuncLit l) /** - * This is either a `Function` or a `FuncLit`, because of limitations of both + * A `Function` or a `FuncLit`. We do it this way because of limitations of both * `Function` and `FuncDef`: * - `Function` is an entity, and therefore does not include function literals, and * - `FuncDef` is an AST node, and so is not extracted for functions from external libraries. diff --git a/go/ql/lib/semmle/go/StringOps.qll b/go/ql/lib/semmle/go/StringOps.qll index c3dc8fdb18d..db86f3864f7 100644 --- a/go/ql/lib/semmle/go/StringOps.qll +++ b/go/ql/lib/semmle/go/StringOps.qll @@ -581,7 +581,7 @@ module StringOps { } /** - * One of the operands in a string concatenation. + * An operand in a string concatenation. * * See `ConcatenationElement` for more information. */ diff --git a/go/ql/lib/semmle/go/Types.qll b/go/ql/lib/semmle/go/Types.qll index ea522b2e11e..026b009aa3f 100644 --- a/go/ql/lib/semmle/go/Types.qll +++ b/go/ql/lib/semmle/go/Types.qll @@ -172,7 +172,7 @@ class InvalidType extends @invalidtype, Type { /** A basic type. */ class BasicType extends @basictype, Type { } -/** Either the normal or literal boolean type */ +/** The normal boolean type or the literal boolean type */ class BoolType extends @booltype, BasicType { } /** The `bool` type of a non-literal expression */ @@ -317,7 +317,7 @@ class Complex128Type extends @complex128type, ComplexType { override string getName() { result = "complex128" } } -/** Either the normal or literal string type */ +/** The normal string type or the literal string type */ class StringType extends @stringtype, BasicType { } /** The `string` type of a non-literal expression */ diff --git a/go/ql/lib/semmle/go/controlflow/ControlFlowGraphImpl.qll b/go/ql/lib/semmle/go/controlflow/ControlFlowGraphImpl.qll index a3f79d756cc..a1d14003031 100644 --- a/go/ql/lib/semmle/go/controlflow/ControlFlowGraphImpl.qll +++ b/go/ql/lib/semmle/go/controlflow/ControlFlowGraphImpl.qll @@ -1305,10 +1305,10 @@ module CFG { exists(Completion inner | lastNode(this.getBody(), last, inner) and not inner.isNormal() | if inner = Break(this.getLabel()) then cmpl = Done() - else - if inner = Continue(this.getLabel()) - then none() - else cmpl = inner + else ( + not inner = Continue(this.getLabel()) and + cmpl = inner + ) ) } } diff --git a/go/ql/lib/semmle/go/dataflow/SSA.qll b/go/ql/lib/semmle/go/dataflow/SSA.qll index 54b49816391..97a9ac4e069 100644 --- a/go/ql/lib/semmle/go/dataflow/SSA.qll +++ b/go/ql/lib/semmle/go/dataflow/SSA.qll @@ -310,7 +310,7 @@ private newtype TSsaWithFields = TStep(SsaWithFields base, Field f) { exists(accessPathAux(base, f)) } /** - * Gets a representation of `nd` as an ssa-with-fields value if there is one. + * Gets a representation of `insn` as an ssa-with-fields value if there is one. */ private TSsaWithFields accessPath(IR::Instruction insn) { exists(SsaVariable v | insn = v.getAUse() | result = TRoot(v)) diff --git a/go/ql/lib/semmle/go/dataflow/barrierguardutil/RegexpCheck.qll b/go/ql/lib/semmle/go/dataflow/barrierguardutil/RegexpCheck.qll index 47593dcf537..795ffb11c44 100644 --- a/go/ql/lib/semmle/go/dataflow/barrierguardutil/RegexpCheck.qll +++ b/go/ql/lib/semmle/go/dataflow/barrierguardutil/RegexpCheck.qll @@ -5,7 +5,7 @@ import go /** - * A call to a regexp match function, considered as a barrier guard for sanitizing untrusted URLs. + * Holds if `resultNode` comes from a call to a regexp match function, considered as a barrier guard for sanitizing untrusted URLs. * * This is overapproximate: we do not attempt to reason about the correctness of the regexp. * diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll index 715330f87d9..23751641d5d 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll @@ -61,9 +61,8 @@ module Private { /** A data flow node that represents the output of a call. */ class OutNode extends Node { DataFlow::CallNode call; - int i; - OutNode() { this = call.getResult(i) } + OutNode() { this = call.getResult(_) } /** Gets the underlying call. */ DataFlowCall getCall() { result = call.asExpr() } @@ -753,13 +752,14 @@ module Public { * of the function. */ class ResultNode extends InstructionNode { - FuncDef fd; int i; ResultNode() { - exists(IR::ReturnInstruction ret | ret.getRoot() = fd | insn = ret.getResult(i)) - or - insn.(IR::ReadResultInstruction).reads(fd.getResultVar(i)) + exists(FuncDef fd | + exists(IR::ReturnInstruction ret | ret.getRoot() = fd | insn = ret.getResult(i)) + or + insn.(IR::ReadResultInstruction).reads(fd.getResultVar(i)) + ) } /** Gets the index of this result among all results of the function. */ @@ -1112,12 +1112,12 @@ module Public { */ class RangeElementNode extends Node { DataFlow::Node base; - IR::ExtractTupleElementInstruction extract; RangeElementNode() { - this.asInstruction() = extract and - extract.extractsElement(_, 1) and - extract.getBase().(IR::GetNextEntryInstruction).getDomain() = base.asInstruction() + exists(IR::ExtractTupleElementInstruction extract | extract = this.asInstruction() | + extract.extractsElement(_, 1) and + extract.getBase().(IR::GetNextEntryInstruction).getDomain() = base.asInstruction() + ) } /** Gets the data-flow node representing the base from which the element is read. */ diff --git a/go/ql/lib/semmle/go/dependencies/Dependencies.qll b/go/ql/lib/semmle/go/dependencies/Dependencies.qll index 5fc746e6987..d8c8ee52d29 100644 --- a/go/ql/lib/semmle/go/dependencies/Dependencies.qll +++ b/go/ql/lib/semmle/go/dependencies/Dependencies.qll @@ -28,9 +28,7 @@ abstract class Dependency extends Locatable { */ abstract predicate relevantForFile(File file); - /** - * An import of this dependency. - */ + /** Gets an import of this dependency. */ ImportSpec getAnImport() { result.getPath().regexpMatch("\\Q" + this.getDepPath() + "\\E(/.*)?") and this.relevantForFile(result.getFile()) @@ -86,7 +84,7 @@ class GoModDependency extends Dependency, GoModRequireLine { } /** - * Holds if this require line originally states dependency `path` had version `ver`. + * Holds if this require line originally states dependency `path` had version `v`. * * The actual info of this dependency can change based on `replace` directives in the same go.mod * file, which replace a dependency with another one. diff --git a/go/ql/lib/semmle/go/frameworks/Beego.qll b/go/ql/lib/semmle/go/frameworks/Beego.qll index 85334e83ab8..d76ac8f23a1 100644 --- a/go/ql/lib/semmle/go/frameworks/Beego.qll +++ b/go/ql/lib/semmle/go/frameworks/Beego.qll @@ -51,13 +51,9 @@ module Beego { */ private class BeegoInputSource extends UntrustedFlowSource::Range { string methodName; - FunctionOutput output; BeegoInputSource() { - exists(DataFlow::MethodCallNode c | this = output.getExitNode(c) | - c.getTarget().hasQualifiedName(contextPackagePath(), "BeegoInput", methodName) - ) and - ( + exists(FunctionOutput output | methodName = "Bind" and output.isParameter(0) or @@ -66,6 +62,10 @@ module Beego { "URI", "URL", "UserAgent" ] and output.isResult(0) + | + exists(DataFlow::MethodCallNode c | this = output.getExitNode(c) | + c.getTarget().hasQualifiedName(contextPackagePath(), "BeegoInput", methodName) + ) ) } @@ -81,16 +81,8 @@ module Beego { * `beego.Controller` sources of untrusted data. */ private class BeegoControllerSource extends UntrustedFlowSource::Range { - string methodName; - FunctionOutput output; - BeegoControllerSource() { - exists(DataFlow::MethodCallNode c | - c.getTarget().hasQualifiedName(packagePath(), "Controller", methodName) - | - this = output.getExitNode(c) - ) and - ( + exists(string methodName, FunctionOutput output | methodName = "ParseForm" and output.isParameter(0) or @@ -99,6 +91,12 @@ module Beego { or methodName = "GetFile" and output.isResult(1) + | + exists(DataFlow::MethodCallNode c | + c.getTarget().hasQualifiedName(packagePath(), "Controller", methodName) + | + this = output.getExitNode(c) + ) ) } } @@ -225,10 +223,8 @@ module Beego { } private class ContextResponseBody extends Http::ResponseBody::Range { - string name; - ContextResponseBody() { - exists(Method m | m.hasQualifiedName(contextPackagePath(), "Context", name) | + exists(Method m, string name | m.hasQualifiedName(contextPackagePath(), "Context", name) | name = "Abort" and this = m.getACall().getArgument(1) or name = "WriteString" and this = m.getACall().getArgument(0) @@ -326,16 +322,17 @@ module Beego { } private class RedirectMethods extends Http::Redirect::Range, DataFlow::CallNode { - string package; string className; RedirectMethods() { - ( - package = packagePath() and className = "Controller" - or - package = contextPackagePath() and className = "Context" - ) and - this = any(Method m | m.hasQualifiedName(package, className, "Redirect")).getACall() + exists(string package | + ( + package = packagePath() and className = "Controller" + or + package = contextPackagePath() and className = "Context" + ) and + this = any(Method m | m.hasQualifiedName(package, className, "Redirect")).getACall() + ) } override DataFlow::Node getUrl() { diff --git a/go/ql/lib/semmle/go/frameworks/Echo.qll b/go/ql/lib/semmle/go/frameworks/Echo.qll index c4d243b504c..2fde621cf44 100644 --- a/go/ql/lib/semmle/go/frameworks/Echo.qll +++ b/go/ql/lib/semmle/go/frameworks/Echo.qll @@ -43,17 +43,15 @@ private module Echo { * Models of `Context.Get/Set`. `Context` behaves like a map, with corresponding taint propagation. */ private class ContextMapModels extends TaintTracking::FunctionModel, Method { - string methodName; FunctionInput input; FunctionOutput output; ContextMapModels() { - ( + exists(string methodName | this.hasQualifiedName(packagePath(), "Context", methodName) | methodName = "Get" and input.isReceiver() and output.isResult() or methodName = "Set" and input.isParameter(1) and output.isReceiver() - ) and - this.hasQualifiedName(packagePath(), "Context", methodName) + ) } override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) { diff --git a/go/ql/lib/semmle/go/frameworks/K8sIoApiCoreV1.qll b/go/ql/lib/semmle/go/frameworks/K8sIoApiCoreV1.qll index ee860e762a2..02df3b4c766 100644 --- a/go/ql/lib/semmle/go/frameworks/K8sIoApiCoreV1.qll +++ b/go/ql/lib/semmle/go/frameworks/K8sIoApiCoreV1.qll @@ -10,20 +10,20 @@ module K8sIoApiCoreV1 { string packagePath() { result = package("k8s.io/api", "core/v1") } private class SecretDeepCopy extends TaintTracking::FunctionModel, Method { - string methodName; FunctionOutput output; SecretDeepCopy() { - ( + exists(string methodName | methodName in ["DeepCopy", "DeepCopyObject"] and output.isResult() or methodName = "DeepCopyInto" and output.isParameter(0) - ) and - this.hasQualifiedName(packagePath(), ["Secret", "SecretList"], methodName) + | + this.hasQualifiedName(packagePath(), ["Secret", "SecretList"], methodName) + ) } override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) { - inp.isReceiver() and outp = outp + inp.isReceiver() and outp = output } } diff --git a/go/ql/lib/semmle/go/frameworks/Revel.qll b/go/ql/lib/semmle/go/frameworks/Revel.qll index e5090a50caa..c23cf87fba2 100644 --- a/go/ql/lib/semmle/go/frameworks/Revel.qll +++ b/go/ql/lib/semmle/go/frameworks/Revel.qll @@ -201,11 +201,9 @@ module Revel { private class RevelHeaderMethods extends TaintTracking::FunctionModel { FunctionInput input; FunctionOutput output; - string name; RevelHeaderMethods() { - this.(Method).hasQualifiedName(packagePath(), "RevelHeader", name) and - ( + exists(string name | this.(Method).hasQualifiedName(packagePath(), "RevelHeader", name) | name = ["Add", "Set"] and input.isParameter([0, 1]) and output.isReceiver() or name = ["Get", "GetAll"] and input.isReceiver() and output.isResult() diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/NetHttp.qll b/go/ql/lib/semmle/go/frameworks/stdlib/NetHttp.qll index 965fbeca4fb..ced661cba64 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/NetHttp.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/NetHttp.qll @@ -57,13 +57,12 @@ module NetHttp { } private class MapWrite extends Http::HeaderWrite::Range, DataFlow::Node { - Write write; DataFlow::Node index; DataFlow::Node rhs; MapWrite() { this.getType().hasQualifiedName("net/http", "Header") and - write.writesElement(this, index, rhs) + any(Write write).writesElement(this, index, rhs) } override DataFlow::Node getName() { result = index } diff --git a/go/ql/lib/semmle/go/security/InsecureFeatureFlag.qll b/go/ql/lib/semmle/go/security/InsecureFeatureFlag.qll index 0006a9e9546..855d7746cf2 100644 --- a/go/ql/lib/semmle/go/security/InsecureFeatureFlag.qll +++ b/go/ql/lib/semmle/go/security/InsecureFeatureFlag.qll @@ -71,7 +71,7 @@ module InsecureFeatureFlag { } /** - * Flags suggesting an optional feature, perhaps deliberately insecure. + * A flag suggesting an optional feature, perhaps deliberately insecure. */ class SecurityFeatureFlag extends FlagKind { SecurityFeatureFlag() { this = "securityFeature" } diff --git a/go/ql/lib/semmle/go/security/SafeUrlFlowCustomizations.qll b/go/ql/lib/semmle/go/security/SafeUrlFlowCustomizations.qll index dbdb96a10a7..ec567167487 100644 --- a/go/ql/lib/semmle/go/security/SafeUrlFlowCustomizations.qll +++ b/go/ql/lib/semmle/go/security/SafeUrlFlowCustomizations.qll @@ -19,7 +19,7 @@ module SafeUrlFlow { /** An outgoing sanitizer edge for safe URL flow. */ abstract class SanitizerEdge extends DataFlow::Node { } - /** Standard library safe URL sources. */ + /** A standard library safe URL source. */ class StdlibSource extends Source, DataFlow::FieldReadNode { StdlibSource() { this.getField().hasQualifiedName("net/http", "Request", ["Host", "URL"]) } } diff --git a/go/ql/lib/semmle/go/security/UnsafeUnzipSymlink.qll b/go/ql/lib/semmle/go/security/UnsafeUnzipSymlink.qll index 976b3bc1c0e..6465917d705 100644 --- a/go/ql/lib/semmle/go/security/UnsafeUnzipSymlink.qll +++ b/go/ql/lib/semmle/go/security/UnsafeUnzipSymlink.qll @@ -14,7 +14,7 @@ module UnsafeUnzipSymlink { import UnsafeUnzipSymlinkCustomizations::UnsafeUnzipSymlink /** - * Taint-flow configuration tracking archive header fields flowing to a `path/filepath.EvalSymlinks` call. + * A taint-flow configuration tracking archive header fields flowing to a `path/filepath.EvalSymlinks` call. */ class EvalSymlinksConfiguration extends TaintTracking2::Configuration { EvalSymlinksConfiguration() { this = "Archive header field symlinks resolved" } @@ -41,7 +41,7 @@ module UnsafeUnzipSymlink { } /** - * Taint-flow configuration tracking archive header fields flowing to an `os.Symlink` call, + * A taint-flow configuration tracking archive header fields flowing to an `os.Symlink` call, * which never flow to a `path/filepath.EvalSymlinks` call. */ class SymlinkConfiguration extends TaintTracking::Configuration { diff --git a/go/ql/lib/semmle/go/security/ZipSlipCustomizations.qll b/go/ql/lib/semmle/go/security/ZipSlipCustomizations.qll index 4bc407f871d..276aae4c4db 100644 --- a/go/ql/lib/semmle/go/security/ZipSlipCustomizations.qll +++ b/go/ql/lib/semmle/go/security/ZipSlipCustomizations.qll @@ -61,7 +61,7 @@ module ZipSlip { } /** - * Excludes zipped file data from consideration for zip slip. + * A zipped file, excluded from for zip slip. */ class ZipFileOpen extends Sanitizer { ZipFileOpen() { diff --git a/go/ql/src/InconsistentCode/WrappedErrorAlwaysNil.ql b/go/ql/src/InconsistentCode/WrappedErrorAlwaysNil.ql index 93889b0a23e..48df6a9297d 100644 --- a/go/ql/src/InconsistentCode/WrappedErrorAlwaysNil.ql +++ b/go/ql/src/InconsistentCode/WrappedErrorAlwaysNil.ql @@ -16,7 +16,8 @@ import go string packagePath() { result = package("github.com/pkg/errors", "") } /** - * An equality test which guarantees that an expression is always `nil`. + * Holds if `g` is an equality test which guarantees that the expression `e` is + * either `nil` or not `nil`, depending on `outcome`. */ predicate nilTestGuard(DataFlow::Node g, Expr e, boolean outcome) { exists(DataFlow::EqualityTestNode eq, DataFlow::Node otherNode | diff --git a/go/ql/src/RedundantCode/Clones.qll b/go/ql/src/RedundantCode/Clones.qll index e98ff754733..6a198b7a3cb 100644 --- a/go/ql/src/RedundantCode/Clones.qll +++ b/go/ql/src/RedundantCode/Clones.qll @@ -19,7 +19,7 @@ class HashableNode extends AstNode { } /** - * An opaque integer describing the type of this AST node. + * Gets an opaque integer describing the type of this AST node. */ int getKind() { exists(int baseKind | diff --git a/go/ql/src/Security/CWE-020/MissingRegexpAnchor.ql b/go/ql/src/Security/CWE-020/MissingRegexpAnchor.ql index f19bee4b179..1a6739608ac 100644 --- a/go/ql/src/Security/CWE-020/MissingRegexpAnchor.ql +++ b/go/ql/src/Security/CWE-020/MissingRegexpAnchor.ql @@ -14,7 +14,7 @@ import go /** - * Holds if `src` is a pattern for a collection of alternatives where + * Holds if `re` is a pattern for a collection of alternatives where * only the first or last alternative is anchored, indicating a * precedence mistake explained by `msg`. * @@ -46,7 +46,7 @@ predicate isInterestingSemiAnchoredRegexpString(string re, string msg) { } /** - * Holds if `src` is an unanchored pattern for a URL, indicating a + * Holds if `re` is an unanchored pattern for a URL, indicating a * mistake explained by `msg`. */ bindingset[re] diff --git a/go/ql/src/Security/CWE-295/DisabledCertificateCheck.ql b/go/ql/src/Security/CWE-295/DisabledCertificateCheck.ql index e3132371d7d..ae83fbce8bc 100644 --- a/go/ql/src/Security/CWE-295/DisabledCertificateCheck.ql +++ b/go/ql/src/Security/CWE-295/DisabledCertificateCheck.ql @@ -38,7 +38,7 @@ predicate becomesPartOf(DataFlow::Node part, DataFlow::Node whole) { } /** - * Flags suggesting a deliberately insecure certificate setup. + * A flag suggesting a deliberately insecure certificate setup. */ class InsecureCertificateFlag extends FlagKind { InsecureCertificateFlag() { this = "insecureCertificate" } diff --git a/go/ql/src/Security/CWE-326/InsufficientKeySize.ql b/go/ql/src/Security/CWE-326/InsufficientKeySize.ql index 038a42b4971..f0485e91edd 100644 --- a/go/ql/src/Security/CWE-326/InsufficientKeySize.ql +++ b/go/ql/src/Security/CWE-326/InsufficientKeySize.ql @@ -14,7 +14,8 @@ import go import DataFlow::PathGraph /** - * RSA key length data flow tracking configuration. + * A data flow tracking configuration for tracking flow from RSA key length to + * calls to RSA key generation functions. */ class RsaKeyTrackingConfiguration extends DataFlow::Configuration { RsaKeyTrackingConfiguration() { this = "RsaKeyTrackingConfiguration" } diff --git a/go/ql/src/Security/CWE-327/InsecureTLS.ql b/go/ql/src/Security/CWE-327/InsecureTLS.ql index e067fa1a36a..854557e80dc 100644 --- a/go/ql/src/Security/CWE-327/InsecureTLS.ql +++ b/go/ql/src/Security/CWE-327/InsecureTLS.ql @@ -52,7 +52,8 @@ int getASecureTlsVersion() { int getATlsVersion() { result = getASecureTlsVersion() or isInsecureTlsVersion(result, _, _) } /** - * Flow of TLS versions into a `tls.Config` struct, to the `MinVersion` and `MaxVersion` fields. + * A taint-tracking configuration for tracking flow from TLS versions to the + * `tls.Config.MinVersion` and `tls.Config.MaxVersion` fields. */ class TlsVersionFlowConfig extends TaintTracking::Configuration { TlsVersionFlowConfig() { this = "TlsVersionFlowConfig" } @@ -152,8 +153,8 @@ predicate isInsecureTlsVersionFlow( } /** - * Flow of unsecure TLS cipher suites into a `tls.Config` struct, - * to the `CipherSuites` field. + * A taint-tracking configuration for tracking flow from insecure TLS cipher + * suites into a `tls.Config` struct, to the `CipherSuites` field. */ class TlsInsecureCipherSuitesFlowConfig extends TaintTracking::Configuration { TlsInsecureCipherSuitesFlowConfig() { this = "TlsInsecureCipherSuitesFlowConfig" } @@ -229,7 +230,7 @@ predicate isInsecureTlsCipherFlow(DataFlow::PathNode source, DataFlow::PathNode } /** - * Flags suggesting support for an old or legacy TLS version. + * A flag suggesting support for an old or legacy TLS version. * * We accept 'intermediate' because it appears to be common for TLS users * to define three profiles: modern, intermediate, legacy/old, perhaps based diff --git a/go/ql/src/Security/CWE-601/OpenUrlRedirect.ql b/go/ql/src/Security/CWE-601/OpenUrlRedirect.ql index 63c8b945ab3..d633161f916 100644 --- a/go/ql/src/Security/CWE-601/OpenUrlRedirect.ql +++ b/go/ql/src/Security/CWE-601/OpenUrlRedirect.ql @@ -24,5 +24,5 @@ where // this excludes flow from safe parts of request URLs, for example the full URL when the // doing a redirect from `http://` to `https://` not scfg.hasFlow(_, sink.getNode()) -select sink.getNode(), source, sink, "Untrusted URL redirection depends on a $@.", source.getNode(), - "user-provided value" +select sink.getNode(), source, sink, "This path to an untrusted URL redirection depends on a $@.", + source.getNode(), "user-provided value" diff --git a/go/ql/src/experimental/CWE-1004/AuthCookie.qll b/go/ql/src/experimental/CWE-1004/AuthCookie.qll index 8a4bc8d2163..676249c7b8c 100644 --- a/go/ql/src/experimental/CWE-1004/AuthCookie.qll +++ b/go/ql/src/experimental/CWE-1004/AuthCookie.qll @@ -65,7 +65,8 @@ private class SetCookieSink extends DataFlow::Node { } /** - * Tracks sensitive name to `net/http.SetCookie`. + * A taint-tracking configuration for tracking flow from sensitive names to + * `net/http.SetCookie`. */ class NameToNetHttpCookieTrackingConfiguration extends TaintTracking::Configuration { NameToNetHttpCookieTrackingConfiguration() { this = "NameToNetHttpCookieTrackingConfiguration" } @@ -84,7 +85,8 @@ class NameToNetHttpCookieTrackingConfiguration extends TaintTracking::Configurat } /** - * Tracks `bool` assigned to `HttpOnly` that flows into `net/http.SetCookie`. + * A taint-tracking configuration for tracking flow from `bool` assigned to + * `HttpOnly` that flows into `net/http.SetCookie`. */ class BoolToNetHttpCookieTrackingConfiguration extends TaintTracking::Configuration { BoolToNetHttpCookieTrackingConfiguration() { this = "BoolToNetHttpCookieTrackingConfiguration" } @@ -105,7 +107,8 @@ class BoolToNetHttpCookieTrackingConfiguration extends TaintTracking::Configurat } /** - * Tracks `HttpOnly` set to `false` to `gin-gonic/gin.Context.SetCookie`. + * A taint-tracking configuration for tracking flow from `HttpOnly` set to + * `false` to `gin-gonic/gin.Context.SetCookie`. */ class BoolToGinSetCookieTrackingConfiguration extends DataFlow::Configuration { BoolToGinSetCookieTrackingConfiguration() { this = "BoolToGinSetCookieTrackingConfiguration" } @@ -125,7 +128,8 @@ class BoolToGinSetCookieTrackingConfiguration extends DataFlow::Configuration { } /** - * Tracks sensitive name to `gin-gonic/gin.Context.SetCookie`. + * A taint-tracking configuration for tracking flow from sensitive names to + * `gin-gonic/gin.Context.SetCookie`. */ private class NameToGinSetCookieTrackingConfiguration extends DataFlow2::Configuration { NameToGinSetCookieTrackingConfiguration() { this = "NameToGinSetCookieTrackingConfiguration" } @@ -164,7 +168,8 @@ private class GorillaStoreSaveSink extends DataFlow::Node { } /** - * Tracks from gorilla cookie store creation to `gorilla/sessions.Session.Save`. + * A taint-tracking configuration for tracking flow from gorilla cookie store + * creation to `gorilla/sessions.Session.Save`. */ class GorillaCookieStoreSaveTrackingConfiguration extends DataFlow::Configuration { GorillaCookieStoreSaveTrackingConfiguration() { @@ -194,7 +199,8 @@ class GorillaCookieStoreSaveTrackingConfiguration extends DataFlow::Configuratio } /** - * Tracks session options to `gorilla/sessions.Session.Save`. + * A taint-tracking configuration for tracking flow from session options to + * `gorilla/sessions.Session.Save`. */ class GorillaSessionOptionsTrackingConfiguration extends TaintTracking::Configuration { GorillaSessionOptionsTrackingConfiguration() { @@ -219,7 +225,8 @@ class GorillaSessionOptionsTrackingConfiguration extends TaintTracking::Configur } /** - * Tracks `bool` assigned to `HttpOnly` that flows into `gorilla/sessions.Session.Save`. + * A taint-tracking configuration for tracking flow from a `bool` assigned to + * `HttpOnly` to `gorilla/sessions.Session.Save`. */ class BoolToGorillaSessionOptionsTrackingConfiguration extends TaintTracking::Configuration { BoolToGorillaSessionOptionsTrackingConfiguration() { diff --git a/go/ql/src/experimental/CWE-321/HardcodedKeysLib.qll b/go/ql/src/experimental/CWE-321/HardcodedKeysLib.qll index 5dc65a15098..12af9544b0e 100644 --- a/go/ql/src/experimental/CWE-321/HardcodedKeysLib.qll +++ b/go/ql/src/experimental/CWE-321/HardcodedKeysLib.qll @@ -79,6 +79,69 @@ module HardcodedKeys { } } + private class KatarasJwt extends Sink { + KatarasJwt() { + exists(string pkg | + pkg = package("github.com/kataras/jwt", "") and + ( + exists(DataFlow::MethodCallNode m | + // Model the `Register` method of the type `Keys` + // func (keys Keys) Register(alg Alg, kid string, pubKey PublicKey, privKey PrivateKey) + m.getTarget().hasQualifiedName(pkg, "Keys", "Register") + | + this = m.getArgument(3) + ) + or + exists(DataFlow::CallNode m, string names | + // Model the `Sign` method of the `SigningMethod` interface + // func Sign(alg Alg, key PrivateKey, claims interface{}, opts ...SignOption) ([]byte, error) + // func SignEncrypted(alg Alg, key PrivateKey, encrypt InjectFunc, claims interface{}, ...) ([]byte, error) + // func SignEncryptedWithHeader(alg Alg, key PrivateKey, encrypt InjectFunc, claims interface{}, ...) ([]byte, error) + // func SignWithHeader(alg Alg, key PrivateKey, claims interface{}, customHeader interface{}, ...) ([]byte, error) + m.getTarget().hasQualifiedName(pkg, names) and + names = ["Sign", "SignEncrypted", "SignEncryptedWithHeader", "SignWithHeader"] + | + this = m.getArgument(1) + ) + ) + ) + } + } + + private class IrisJwt extends Sink { + IrisJwt() { + exists(string pkg | + pkg = "github.com/kataras/iris/v12/middleware/jwt" and + ( + exists(DataFlow::CallNode m | + //func NewSigner(signatureAlg Alg, signatureKey interface{}, maxAge time.Duration) *Signer + m.getTarget().hasQualifiedName(pkg, "NewSigner") + | + this = m.getArgument(1) + ) + or + exists(Field f | + // Models the `key` field of the `Signer` type + // https://github.com/kataras/iris/blob/dccd57263617f5ca95d7621acfadf9dd37752dd6/middleware/jwt/signer.go#L17 + f.hasQualifiedName(pkg, "Signer", "Key") and + f.getAWrite().getRhs() = this + ) + ) + ) + } + } + + private class GogfJwtSign extends Sink { + GogfJwtSign() { + exists(Field f, string pkg | + pkg = package("github.com/gogf/gf-jwt", "") and + // https://github.com/gogf/gf-jwt/blob/40503f05bc0a2bcd7aeba550163112afbb5c221f/auth_jwt.go#L27 + f.hasQualifiedName(pkg, "GfJWTMiddleware", "Key") and + f.getAWrite().getRhs() = this + ) + } + } + private class GinJwtSign extends Sink { GinJwtSign() { exists(Field f | diff --git a/go/ql/src/experimental/CWE-327/CryptoLibraries.qll b/go/ql/src/experimental/CWE-327/CryptoLibraries.qll index 6db266273b5..5518067b668 100644 --- a/go/ql/src/experimental/CWE-327/CryptoLibraries.qll +++ b/go/ql/src/experimental/CWE-327/CryptoLibraries.qll @@ -161,7 +161,7 @@ abstract class CryptographicOperation extends DataFlow::Node { } /** - * Models cryptographic operations of the `crypto/md5` package. + * A cryptographic operation from the `crypto/md5` package. */ class Md5 extends CryptographicOperation, DataFlow::CallNode { Md5() { this.getTarget().hasQualifiedName("crypto/md5", ["New", "Sum"]) } @@ -174,7 +174,7 @@ class Md5 extends CryptographicOperation, DataFlow::CallNode { } /** - * Models cryptographic operations of the `crypto/sha1` package. + * A cryptographic operation from the `crypto/sha1` package. */ class Sha1 extends CryptographicOperation, DataFlow::CallNode { Sha1() { this.getTarget().hasQualifiedName("crypto/sha1", ["New", "Sum"]) } @@ -187,7 +187,7 @@ class Sha1 extends CryptographicOperation, DataFlow::CallNode { } /** - * Models cryptographic operations of the `crypto/des` package. + * A cryptographic operation from the `crypto/des` package. */ class Des extends CryptographicOperation, DataFlow::CallNode { Des() { this.getTarget().hasQualifiedName("crypto/des", ["NewCipher", "NewTripleDESCipher"]) } @@ -200,10 +200,10 @@ class Des extends CryptographicOperation, DataFlow::CallNode { } /** - * Models cryptographic operations of the `crypto/rc4` package. + * A cryptographic operation from the `crypto/rc4` package. */ class Rc4 extends CryptographicOperation, DataFlow::CallNode { - Rc4() { this.getTarget().hasQualifiedName("crypto/rc4", ["NewCipher"]) } + Rc4() { this.getTarget().hasQualifiedName("crypto/rc4", "NewCipher") } override Expr getInput() { result = this.getArgument(0).asExpr() } diff --git a/go/ql/src/experimental/CWE-79/HTMLTemplateEscapingPassthrough.ql b/go/ql/src/experimental/CWE-79/HTMLTemplateEscapingPassthrough.ql index eb6c7668f06..fd5fccacbc6 100644 --- a/go/ql/src/experimental/CWE-79/HTMLTemplateEscapingPassthrough.ql +++ b/go/ql/src/experimental/CWE-79/HTMLTemplateEscapingPassthrough.ql @@ -29,7 +29,7 @@ predicate flowsFromUntrustedToConversion( } /** - * Provides the names of the types that will not be escaped when passed to + * A name of a type that will not be escaped when passed to * a `html/template` template. */ class PassthroughTypeName extends string { diff --git a/go/ql/src/experimental/CWE-918/SSRF.qll b/go/ql/src/experimental/CWE-918/SSRF.qll index cf264c8c0b6..b6424511a21 100644 --- a/go/ql/src/experimental/CWE-918/SSRF.qll +++ b/go/ql/src/experimental/CWE-918/SSRF.qll @@ -132,7 +132,7 @@ module ServerSideRequestForgery { } /** - * If the tainted variable is a boolean or has numeric type is not possible to exploit a SSRF + * A value which has boolean or numeric type, considered as a sanitizer for SSRF. */ class NumSanitizer extends Sanitizer { NumSanitizer() { @@ -142,8 +142,8 @@ module ServerSideRequestForgery { } /** - * When we receive a body from a request, we can use certain tags on our struct's fields to hint - * the binding function to run some validations for that field. If these binding functions returns + * A body received from a request, where certain tags on our struct's fields have been used to hint + * to the binding function to run some validations for that field. If these binding functions returns * no error, then we consider these fields safe for SSRF. */ class BodySanitizer extends Sanitizer instanceof CheckedAlphanumericStructFieldRead { } diff --git a/go/ql/src/experimental/CWE-942/CorsMisconfiguration.ql b/go/ql/src/experimental/CWE-942/CorsMisconfiguration.ql index 7b2dcb12fcf..53e7c0e8730 100644 --- a/go/ql/src/experimental/CWE-942/CorsMisconfiguration.ql +++ b/go/ql/src/experimental/CWE-942/CorsMisconfiguration.ql @@ -166,7 +166,7 @@ class FlowsFromUntrusted extends TaintTracking::Configuration { } /** - * Holds if the provided `dst` is also destination of a `UntrustedFlowSource`. + * Holds if the provided `allowOriginHW` is also destination of a `UntrustedFlowSource`. */ predicate flowsToGuardedByCheckOnUntrusted(AllowOriginHeaderWrite allowOriginHW) { exists(FlowsFromUntrusted cfg, DataFlow::Node sink, ControlFlow::ConditionGuardNode cgn | diff --git a/go/ql/src/experimental/frameworks/CleverGo.qll b/go/ql/src/experimental/frameworks/CleverGo.qll index d4d3fa441d2..4b39ea005fd 100644 --- a/go/ql/src/experimental/frameworks/CleverGo.qll +++ b/go/ql/src/experimental/frameworks/CleverGo.qll @@ -175,18 +175,14 @@ private module CleverGo { * Models HTTP redirects. */ private class HttpRedirect extends Http::Redirect::Range, DataFlow::CallNode { - string package; DataFlow::Node urlNode; HttpRedirect() { // HTTP redirect models for package: clevergo.tech/clevergo@v0.5.2 - package = packagePath() and // Receiver type: Context - ( - // signature: func (*Context) Redirect(code int, url string) error - this = any(Method m | m.hasQualifiedName(package, "Context", "Redirect")).getACall() and - urlNode = this.getArgument(1) - ) + // signature: func (*Context) Redirect(code int, url string) error + this = any(Method m | m.hasQualifiedName(packagePath(), "Context", "Redirect")).getACall() and + urlNode = this.getArgument(1) } override DataFlow::Node getUrl() { result = urlNode } diff --git a/go/ql/src/experimental/frameworks/Fiber.qll b/go/ql/src/experimental/frameworks/Fiber.qll index 2a4a2285702..cfc65afdc1c 100644 --- a/go/ql/src/experimental/frameworks/Fiber.qll +++ b/go/ql/src/experimental/frameworks/Fiber.qll @@ -130,18 +130,14 @@ private module Fiber { * Models HTTP redirects. */ private class Redirect extends Http::Redirect::Range, DataFlow::CallNode { - string package; DataFlow::Node urlNode; Redirect() { // HTTP redirect models for package: github.com/gofiber/fiber@v1.14.6 - package = fiberPackagePath() and // Receiver type: Ctx - ( - // signature: func (*Ctx) Redirect(location string, status ...int) - this = any(Method m | m.hasQualifiedName(package, "Ctx", "Redirect")).getACall() and - urlNode = this.getArgument(0) - ) + // signature: func (*Ctx) Redirect(location string, status ...int) + this = any(Method m | m.hasQualifiedName(fiberPackagePath(), "Ctx", "Redirect")).getACall() and + urlNode = this.getArgument(0) } override DataFlow::Node getUrl() { result = urlNode } diff --git a/go/ql/test/experimental/CWE-321/HardcodedKeys.expected b/go/ql/test/experimental/CWE-321/HardcodedKeys.expected index fe0fb2d238d..873bb55b7c2 100644 --- a/go/ql/test/experimental/CWE-321/HardcodedKeys.expected +++ b/go/ql/test/experimental/CWE-321/HardcodedKeys.expected @@ -1,74 +1,126 @@ edges | HardcodedKeysBad.go:11:18:11:38 | type conversion | HardcodedKeysBad.go:19:28:19:39 | mySigningKey | | HardcodedKeysBad.go:11:25:11:37 | "AllYourBase" | HardcodedKeysBad.go:11:18:11:38 | type conversion | -| main.go:25:18:25:31 | type conversion | main.go:34:28:34:39 | mySigningKey | -| main.go:25:25:25:30 | "key1" | main.go:25:18:25:31 | type conversion | -| main.go:42:23:42:28 | "key2" | main.go:42:16:42:29 | type conversion | -| main.go:60:9:60:22 | type conversion | main.go:61:44:61:46 | key | -| main.go:60:16:60:21 | `key3` | main.go:60:9:60:22 | type conversion | -| main.go:65:9:65:22 | type conversion | main.go:66:66:66:68 | key | -| main.go:65:16:65:21 | "key4" | main.go:65:9:65:22 | type conversion | -| main.go:69:10:69:23 | type conversion | main.go:74:15:74:18 | key2 | -| main.go:69:17:69:22 | "key5" | main.go:69:10:69:23 | type conversion | -| main.go:80:9:80:22 | type conversion | main.go:84:41:84:43 | key | -| main.go:80:16:80:21 | "key6" | main.go:80:9:80:22 | type conversion | -| main.go:89:10:89:23 | type conversion | main.go:91:66:91:69 | key2 | -| main.go:89:17:89:22 | "key7" | main.go:89:10:89:23 | type conversion | -| main.go:97:9:97:22 | type conversion | main.go:102:30:102:32 | key | -| main.go:97:16:97:21 | "key8" | main.go:97:9:97:22 | type conversion | -| main.go:106:15:106:28 | type conversion | main.go:107:16:107:24 | sharedKey | -| main.go:106:22:106:27 | "key9" | main.go:106:15:106:28 | type conversion | -| main.go:110:23:110:37 | type conversion | main.go:113:16:113:30 | sharedKeyglobal | -| main.go:110:30:110:36 | "key10" | main.go:110:23:110:37 | type conversion | +| main.go:33:18:33:31 | type conversion | main.go:42:28:42:39 | mySigningKey | +| main.go:33:25:33:30 | "key1" | main.go:33:18:33:31 | type conversion | +| main.go:50:23:50:28 | "key2" | main.go:50:16:50:29 | type conversion | +| main.go:68:9:68:22 | type conversion | main.go:69:44:69:46 | key | +| main.go:68:16:68:21 | `key3` | main.go:68:9:68:22 | type conversion | +| main.go:73:9:73:22 | type conversion | main.go:74:66:74:68 | key | +| main.go:73:16:73:21 | "key4" | main.go:73:9:73:22 | type conversion | +| main.go:77:10:77:23 | type conversion | main.go:82:15:82:18 | key2 | +| main.go:77:17:77:22 | "key5" | main.go:77:10:77:23 | type conversion | +| main.go:88:9:88:22 | type conversion | main.go:92:41:92:43 | key | +| main.go:88:16:88:21 | "key6" | main.go:88:9:88:22 | type conversion | +| main.go:97:10:97:23 | type conversion | main.go:99:66:99:69 | key2 | +| main.go:97:17:97:22 | "key7" | main.go:97:10:97:23 | type conversion | +| main.go:105:9:105:22 | type conversion | main.go:110:30:110:32 | key | +| main.go:105:16:105:21 | "key8" | main.go:105:9:105:22 | type conversion | +| main.go:114:15:114:28 | type conversion | main.go:115:16:115:24 | sharedKey | +| main.go:114:22:114:27 | "key9" | main.go:114:15:114:28 | type conversion | +| main.go:118:23:118:37 | type conversion | main.go:121:16:121:30 | sharedKeyglobal | +| main.go:118:30:118:36 | "key10" | main.go:118:23:118:37 | type conversion | +| main.go:127:27:127:33 | "key11" | main.go:127:20:127:34 | type conversion | +| main.go:142:14:142:28 | type conversion | main.go:144:39:144:46 | mySecret | +| main.go:142:21:142:27 | "key12" | main.go:142:14:142:28 | type conversion | +| main.go:149:14:149:28 | type conversion | main.go:153:11:153:18 | mySecret | +| main.go:149:21:149:27 | "key13" | main.go:149:14:149:28 | type conversion | +| main.go:160:12:160:26 | type conversion | main.go:161:34:161:39 | secret | +| main.go:160:19:160:25 | "key14" | main.go:160:12:160:26 | type conversion | +| main.go:166:12:166:26 | type conversion | main.go:167:32:167:37 | secret | +| main.go:166:19:166:25 | "key15" | main.go:166:12:166:26 | type conversion | +| main.go:172:12:172:26 | type conversion | main.go:173:41:173:46 | secret | +| main.go:172:19:172:25 | "key16" | main.go:172:12:172:26 | type conversion | +| main.go:178:12:178:26 | type conversion | main.go:179:51:179:56 | secret | +| main.go:178:19:178:25 | "key17" | main.go:178:12:178:26 | type conversion | +| main.go:184:12:184:26 | type conversion | main.go:185:42:185:47 | secret | +| main.go:184:19:184:25 | "key18" | main.go:184:12:184:26 | type conversion | +| main.go:190:12:190:26 | type conversion | main.go:193:33:193:38 | secret | +| main.go:190:19:190:25 | "key19" | main.go:190:12:190:26 | type conversion | | sanitizer.go:17:9:17:21 | type conversion | sanitizer.go:18:44:18:46 | key | | sanitizer.go:17:16:17:20 | `key` | sanitizer.go:17:9:17:21 | type conversion | nodes | HardcodedKeysBad.go:11:18:11:38 | type conversion | semmle.label | type conversion | | HardcodedKeysBad.go:11:25:11:37 | "AllYourBase" | semmle.label | "AllYourBase" | | HardcodedKeysBad.go:19:28:19:39 | mySigningKey | semmle.label | mySigningKey | -| main.go:25:18:25:31 | type conversion | semmle.label | type conversion | -| main.go:25:25:25:30 | "key1" | semmle.label | "key1" | -| main.go:34:28:34:39 | mySigningKey | semmle.label | mySigningKey | -| main.go:42:16:42:29 | type conversion | semmle.label | type conversion | -| main.go:42:23:42:28 | "key2" | semmle.label | "key2" | -| main.go:60:9:60:22 | type conversion | semmle.label | type conversion | -| main.go:60:16:60:21 | `key3` | semmle.label | `key3` | -| main.go:61:44:61:46 | key | semmle.label | key | -| main.go:65:9:65:22 | type conversion | semmle.label | type conversion | -| main.go:65:16:65:21 | "key4" | semmle.label | "key4" | -| main.go:66:66:66:68 | key | semmle.label | key | -| main.go:69:10:69:23 | type conversion | semmle.label | type conversion | -| main.go:69:17:69:22 | "key5" | semmle.label | "key5" | -| main.go:74:15:74:18 | key2 | semmle.label | key2 | -| main.go:80:9:80:22 | type conversion | semmle.label | type conversion | -| main.go:80:16:80:21 | "key6" | semmle.label | "key6" | -| main.go:84:41:84:43 | key | semmle.label | key | -| main.go:89:10:89:23 | type conversion | semmle.label | type conversion | -| main.go:89:17:89:22 | "key7" | semmle.label | "key7" | -| main.go:91:66:91:69 | key2 | semmle.label | key2 | -| main.go:97:9:97:22 | type conversion | semmle.label | type conversion | -| main.go:97:16:97:21 | "key8" | semmle.label | "key8" | -| main.go:102:30:102:32 | key | semmle.label | key | -| main.go:106:15:106:28 | type conversion | semmle.label | type conversion | -| main.go:106:22:106:27 | "key9" | semmle.label | "key9" | -| main.go:107:16:107:24 | sharedKey | semmle.label | sharedKey | -| main.go:110:23:110:37 | type conversion | semmle.label | type conversion | -| main.go:110:30:110:36 | "key10" | semmle.label | "key10" | -| main.go:113:16:113:30 | sharedKeyglobal | semmle.label | sharedKeyglobal | +| main.go:33:18:33:31 | type conversion | semmle.label | type conversion | +| main.go:33:25:33:30 | "key1" | semmle.label | "key1" | +| main.go:42:28:42:39 | mySigningKey | semmle.label | mySigningKey | +| main.go:50:16:50:29 | type conversion | semmle.label | type conversion | +| main.go:50:23:50:28 | "key2" | semmle.label | "key2" | +| main.go:68:9:68:22 | type conversion | semmle.label | type conversion | +| main.go:68:16:68:21 | `key3` | semmle.label | `key3` | +| main.go:69:44:69:46 | key | semmle.label | key | +| main.go:73:9:73:22 | type conversion | semmle.label | type conversion | +| main.go:73:16:73:21 | "key4" | semmle.label | "key4" | +| main.go:74:66:74:68 | key | semmle.label | key | +| main.go:77:10:77:23 | type conversion | semmle.label | type conversion | +| main.go:77:17:77:22 | "key5" | semmle.label | "key5" | +| main.go:82:15:82:18 | key2 | semmle.label | key2 | +| main.go:88:9:88:22 | type conversion | semmle.label | type conversion | +| main.go:88:16:88:21 | "key6" | semmle.label | "key6" | +| main.go:92:41:92:43 | key | semmle.label | key | +| main.go:97:10:97:23 | type conversion | semmle.label | type conversion | +| main.go:97:17:97:22 | "key7" | semmle.label | "key7" | +| main.go:99:66:99:69 | key2 | semmle.label | key2 | +| main.go:105:9:105:22 | type conversion | semmle.label | type conversion | +| main.go:105:16:105:21 | "key8" | semmle.label | "key8" | +| main.go:110:30:110:32 | key | semmle.label | key | +| main.go:114:15:114:28 | type conversion | semmle.label | type conversion | +| main.go:114:22:114:27 | "key9" | semmle.label | "key9" | +| main.go:115:16:115:24 | sharedKey | semmle.label | sharedKey | +| main.go:118:23:118:37 | type conversion | semmle.label | type conversion | +| main.go:118:30:118:36 | "key10" | semmle.label | "key10" | +| main.go:121:16:121:30 | sharedKeyglobal | semmle.label | sharedKeyglobal | +| main.go:127:20:127:34 | type conversion | semmle.label | type conversion | +| main.go:127:27:127:33 | "key11" | semmle.label | "key11" | +| main.go:142:14:142:28 | type conversion | semmle.label | type conversion | +| main.go:142:21:142:27 | "key12" | semmle.label | "key12" | +| main.go:144:39:144:46 | mySecret | semmle.label | mySecret | +| main.go:149:14:149:28 | type conversion | semmle.label | type conversion | +| main.go:149:21:149:27 | "key13" | semmle.label | "key13" | +| main.go:153:11:153:18 | mySecret | semmle.label | mySecret | +| main.go:160:12:160:26 | type conversion | semmle.label | type conversion | +| main.go:160:19:160:25 | "key14" | semmle.label | "key14" | +| main.go:161:34:161:39 | secret | semmle.label | secret | +| main.go:166:12:166:26 | type conversion | semmle.label | type conversion | +| main.go:166:19:166:25 | "key15" | semmle.label | "key15" | +| main.go:167:32:167:37 | secret | semmle.label | secret | +| main.go:172:12:172:26 | type conversion | semmle.label | type conversion | +| main.go:172:19:172:25 | "key16" | semmle.label | "key16" | +| main.go:173:41:173:46 | secret | semmle.label | secret | +| main.go:178:12:178:26 | type conversion | semmle.label | type conversion | +| main.go:178:19:178:25 | "key17" | semmle.label | "key17" | +| main.go:179:51:179:56 | secret | semmle.label | secret | +| main.go:184:12:184:26 | type conversion | semmle.label | type conversion | +| main.go:184:19:184:25 | "key18" | semmle.label | "key18" | +| main.go:185:42:185:47 | secret | semmle.label | secret | +| main.go:190:12:190:26 | type conversion | semmle.label | type conversion | +| main.go:190:19:190:25 | "key19" | semmle.label | "key19" | +| main.go:193:33:193:38 | secret | semmle.label | secret | | sanitizer.go:17:9:17:21 | type conversion | semmle.label | type conversion | | sanitizer.go:17:16:17:20 | `key` | semmle.label | `key` | | sanitizer.go:18:44:18:46 | key | semmle.label | key | subpaths #select | HardcodedKeysBad.go:19:28:19:39 | mySigningKey | HardcodedKeysBad.go:11:25:11:37 | "AllYourBase" | HardcodedKeysBad.go:19:28:19:39 | mySigningKey | $@ is used to sign a JWT token. | HardcodedKeysBad.go:11:25:11:37 | "AllYourBase" | Hardcoded String | -| main.go:34:28:34:39 | mySigningKey | main.go:25:25:25:30 | "key1" | main.go:34:28:34:39 | mySigningKey | $@ is used to sign a JWT token. | main.go:25:25:25:30 | "key1" | Hardcoded String | -| main.go:42:16:42:29 | type conversion | main.go:42:23:42:28 | "key2" | main.go:42:16:42:29 | type conversion | $@ is used to sign a JWT token. | main.go:42:23:42:28 | "key2" | Hardcoded String | -| main.go:61:44:61:46 | key | main.go:60:16:60:21 | `key3` | main.go:61:44:61:46 | key | $@ is used to sign a JWT token. | main.go:60:16:60:21 | `key3` | Hardcoded String | -| main.go:66:66:66:68 | key | main.go:65:16:65:21 | "key4" | main.go:66:66:66:68 | key | $@ is used to sign a JWT token. | main.go:65:16:65:21 | "key4" | Hardcoded String | -| main.go:74:15:74:18 | key2 | main.go:69:17:69:22 | "key5" | main.go:74:15:74:18 | key2 | $@ is used to sign a JWT token. | main.go:69:17:69:22 | "key5" | Hardcoded String | -| main.go:84:41:84:43 | key | main.go:80:16:80:21 | "key6" | main.go:84:41:84:43 | key | $@ is used to sign a JWT token. | main.go:80:16:80:21 | "key6" | Hardcoded String | -| main.go:91:66:91:69 | key2 | main.go:89:17:89:22 | "key7" | main.go:91:66:91:69 | key2 | $@ is used to sign a JWT token. | main.go:89:17:89:22 | "key7" | Hardcoded String | -| main.go:102:30:102:32 | key | main.go:97:16:97:21 | "key8" | main.go:102:30:102:32 | key | $@ is used to sign a JWT token. | main.go:97:16:97:21 | "key8" | Hardcoded String | -| main.go:107:16:107:24 | sharedKey | main.go:106:22:106:27 | "key9" | main.go:107:16:107:24 | sharedKey | $@ is used to sign a JWT token. | main.go:106:22:106:27 | "key9" | Hardcoded String | -| main.go:113:16:113:30 | sharedKeyglobal | main.go:110:30:110:36 | "key10" | main.go:113:16:113:30 | sharedKeyglobal | $@ is used to sign a JWT token. | main.go:110:30:110:36 | "key10" | Hardcoded String | +| main.go:42:28:42:39 | mySigningKey | main.go:33:25:33:30 | "key1" | main.go:42:28:42:39 | mySigningKey | $@ is used to sign a JWT token. | main.go:33:25:33:30 | "key1" | Hardcoded String | +| main.go:50:16:50:29 | type conversion | main.go:50:23:50:28 | "key2" | main.go:50:16:50:29 | type conversion | $@ is used to sign a JWT token. | main.go:50:23:50:28 | "key2" | Hardcoded String | +| main.go:69:44:69:46 | key | main.go:68:16:68:21 | `key3` | main.go:69:44:69:46 | key | $@ is used to sign a JWT token. | main.go:68:16:68:21 | `key3` | Hardcoded String | +| main.go:74:66:74:68 | key | main.go:73:16:73:21 | "key4" | main.go:74:66:74:68 | key | $@ is used to sign a JWT token. | main.go:73:16:73:21 | "key4" | Hardcoded String | +| main.go:82:15:82:18 | key2 | main.go:77:17:77:22 | "key5" | main.go:82:15:82:18 | key2 | $@ is used to sign a JWT token. | main.go:77:17:77:22 | "key5" | Hardcoded String | +| main.go:92:41:92:43 | key | main.go:88:16:88:21 | "key6" | main.go:92:41:92:43 | key | $@ is used to sign a JWT token. | main.go:88:16:88:21 | "key6" | Hardcoded String | +| main.go:99:66:99:69 | key2 | main.go:97:17:97:22 | "key7" | main.go:99:66:99:69 | key2 | $@ is used to sign a JWT token. | main.go:97:17:97:22 | "key7" | Hardcoded String | +| main.go:110:30:110:32 | key | main.go:105:16:105:21 | "key8" | main.go:110:30:110:32 | key | $@ is used to sign a JWT token. | main.go:105:16:105:21 | "key8" | Hardcoded String | +| main.go:115:16:115:24 | sharedKey | main.go:114:22:114:27 | "key9" | main.go:115:16:115:24 | sharedKey | $@ is used to sign a JWT token. | main.go:114:22:114:27 | "key9" | Hardcoded String | +| main.go:121:16:121:30 | sharedKeyglobal | main.go:118:30:118:36 | "key10" | main.go:121:16:121:30 | sharedKeyglobal | $@ is used to sign a JWT token. | main.go:118:30:118:36 | "key10" | Hardcoded String | +| main.go:127:20:127:34 | type conversion | main.go:127:27:127:33 | "key11" | main.go:127:20:127:34 | type conversion | $@ is used to sign a JWT token. | main.go:127:27:127:33 | "key11" | Hardcoded String | +| main.go:144:39:144:46 | mySecret | main.go:142:21:142:27 | "key12" | main.go:144:39:144:46 | mySecret | $@ is used to sign a JWT token. | main.go:142:21:142:27 | "key12" | Hardcoded String | +| main.go:153:11:153:18 | mySecret | main.go:149:21:149:27 | "key13" | main.go:153:11:153:18 | mySecret | $@ is used to sign a JWT token. | main.go:149:21:149:27 | "key13" | Hardcoded String | +| main.go:161:34:161:39 | secret | main.go:160:19:160:25 | "key14" | main.go:161:34:161:39 | secret | $@ is used to sign a JWT token. | main.go:160:19:160:25 | "key14" | Hardcoded String | +| main.go:167:32:167:37 | secret | main.go:166:19:166:25 | "key15" | main.go:167:32:167:37 | secret | $@ is used to sign a JWT token. | main.go:166:19:166:25 | "key15" | Hardcoded String | +| main.go:173:41:173:46 | secret | main.go:172:19:172:25 | "key16" | main.go:173:41:173:46 | secret | $@ is used to sign a JWT token. | main.go:172:19:172:25 | "key16" | Hardcoded String | +| main.go:179:51:179:56 | secret | main.go:178:19:178:25 | "key17" | main.go:179:51:179:56 | secret | $@ is used to sign a JWT token. | main.go:178:19:178:25 | "key17" | Hardcoded String | +| main.go:185:42:185:47 | secret | main.go:184:19:184:25 | "key18" | main.go:185:42:185:47 | secret | $@ is used to sign a JWT token. | main.go:184:19:184:25 | "key18" | Hardcoded String | +| main.go:193:33:193:38 | secret | main.go:190:19:190:25 | "key19" | main.go:193:33:193:38 | secret | $@ is used to sign a JWT token. | main.go:190:19:190:25 | "key19" | Hardcoded String | | sanitizer.go:18:44:18:46 | key | sanitizer.go:17:16:17:20 | `key` | sanitizer.go:18:44:18:46 | key | $@ is used to sign a JWT token. | sanitizer.go:17:16:17:20 | `key` | Hardcoded String | diff --git a/go/ql/test/experimental/CWE-321/go.mod b/go/ql/test/experimental/CWE-321/go.mod index 1f78c4037c0..68e45a0217b 100644 --- a/go/ql/test/experimental/CWE-321/go.mod +++ b/go/ql/test/experimental/CWE-321/go.mod @@ -6,14 +6,33 @@ require ( github.com/appleboy/gin-jwt/v2 v2.8.0 github.com/cristalhq/jwt/v3 v3.1.0 github.com/go-kit/kit v0.12.0 - github.com/golang-jwt/jwt/v4 v4.4.1 + github.com/gogf/gf-jwt/v2 v2.0.1 + github.com/golang-jwt/jwt/v4 v4.5.0 + github.com/iris-contrib/middleware/jwt v0.0.0-20230311205048-b568fe9b470f + github.com/kataras/iris/v12 v12.2.0 + github.com/kataras/jwt v0.1.8 github.com/lestrrat/go-jwx v0.9.1 github.com/square/go-jose/v3 v3.0.0-20200630053402-0a67ce9b0693 gopkg.in/square/go-jose.v2 v2.6.0 ) require ( + github.com/BurntSushi/toml v1.2.1 // indirect + github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53 // indirect + github.com/CloudyKit/jet/v6 v6.2.0 // indirect + github.com/Joker/jade v1.1.3 // indirect + github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06 // indirect + github.com/andybalholm/brotli v1.0.5 // indirect + github.com/aymerick/douceur v0.2.0 // indirect + github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/clbanning/mxj/v2 v2.5.5 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect + github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 // indirect + github.com/fatih/color v1.13.0 // indirect + github.com/fatih/structs v1.1.0 // indirect + github.com/flosch/pongo2/v4 v4.0.2 // indirect + github.com/fsnotify/fsnotify v1.5.4 // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/gin-gonic/gin v1.7.7 // indirect github.com/go-kit/log v0.2.0 // indirect @@ -21,21 +40,58 @@ require ( github.com/go-playground/locales v0.13.0 // indirect github.com/go-playground/universal-translator v0.17.0 // indirect github.com/go-playground/validator/v10 v10.4.1 // indirect + github.com/go-redis/redis/v8 v8.11.5 // indirect + github.com/go-sql-driver/mysql v1.6.0 // indirect + github.com/gogf/gf/v2 v2.0.0-rc3 // indirect github.com/golang/protobuf v1.5.2 // indirect + github.com/golang/snappy v0.0.4 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/gorilla/css v1.0.0 // indirect + github.com/gorilla/websocket v1.5.0 // indirect + github.com/grokify/html-strip-tags-go v0.0.1 // indirect + github.com/iris-contrib/schema v0.0.6 // indirect + github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/kataras/blocks v0.0.7 // indirect + github.com/kataras/golog v0.1.8 // indirect + github.com/kataras/pio v0.0.11 // indirect + github.com/kataras/sitemap v0.0.6 // indirect + github.com/kataras/tunnel v0.0.4 // indirect + github.com/klauspost/compress v1.16.0 // indirect github.com/leodido/go-urn v1.2.0 // indirect github.com/lestrrat/go-pdebug v0.0.0-20180220043741-569c97477ae8 // indirect - github.com/mattn/go-isatty v0.0.14 // indirect + github.com/mailgun/raymond/v2 v2.0.48 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/mattn/go-colorable v0.1.9 // indirect + github.com/mattn/go-isatty v0.0.17 // indirect + github.com/mattn/go-runewidth v0.0.9 // indirect + github.com/microcosm-cc/bluemonday v1.0.23 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/pkg/errors v0.9.1 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/schollz/closestmatch v2.1.0+incompatible // indirect + github.com/sirupsen/logrus v1.8.1 // indirect + github.com/tdewolff/minify/v2 v2.12.4 // indirect + github.com/tdewolff/parse/v2 v2.6.4 // indirect github.com/ugorji/go/codec v1.1.7 // indirect - golang.org/x/crypto v0.0.0-20210915214749-c084706c2272 // indirect - golang.org/x/net v0.0.0-20210917221730-978cfadd31cf // indirect - golang.org/x/sys v0.0.0-20210917161153-d61c044b1678 // indirect - golang.org/x/text v0.3.7 // indirect + github.com/valyala/bytebufferpool v1.0.0 // indirect + github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect + github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect + github.com/yosssi/ace v0.0.5 // indirect + go.opentelemetry.io/otel v1.0.0 // indirect + go.opentelemetry.io/otel/sdk v1.0.0 // indirect + go.opentelemetry.io/otel/trace v1.0.0 // indirect + golang.org/x/crypto v0.7.0 // indirect + golang.org/x/net v0.8.0 // indirect + golang.org/x/sys v0.6.0 // indirect + golang.org/x/text v0.8.0 // indirect + golang.org/x/time v0.3.0 // indirect google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4 // indirect google.golang.org/grpc v1.40.0 // indirect - google.golang.org/protobuf v1.27.1 // indirect - gopkg.in/yaml.v2 v2.2.8 // indirect + google.golang.org/protobuf v1.29.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go/ql/test/experimental/CWE-321/main.go b/go/ql/test/experimental/CWE-321/main.go index 1e1f3ee45e4..d18dbf77203 100644 --- a/go/ql/test/experimental/CWE-321/main.go +++ b/go/ql/test/experimental/CWE-321/main.go @@ -1,13 +1,17 @@ package main //go:generate depstubber -vendor github.com/appleboy/gin-jwt/v2 GinJWTMiddleware New -//go:generate depstubber -vendor github.com/golang-jwt/jwt/v4 MapClaims,RegisteredClaims,SigningMethodRSA,SigningMethodHMAC,Token NewNumericDate,NewWithClaims +//go:generate depstubber -vendor github.com/golang-jwt/jwt/v4 MapClaims,RegisteredClaims,SigningMethodRSA,SigningMethodHMAC,Token NewNumericDate,NewWithClaims,New //go:generate depstubber -vendor github.com/gin-gonic/gin Context New //go:generate depstubber -vendor github.com/go-kit/kit/auth/jwt "" NewSigner //go:generate depstubber -vendor github.com/lestrrat/go-jwx/jwk "" New //go:generate depstubber -vendor github.com/square/go-jose/v3 Recipient NewEncrypter,NewSigner //go:generate depstubber -vendor gopkg.in/square/go-jose.v2 Recipient NewEncrypter,NewSigner //go:generate depstubber -vendor github.com/cristalhq/jwt/v3 Signer NewSignerHS,HS256 +//go:generate depstubber -vendor github.com/iris-contrib/middleware/jwt "" NewToken,NewTokenWithClaims +//go:generate depstubber -vendor github.com/kataras/iris/v12/middleware/jwt Signer,Verifier NewSigner,NewVerifier +//go:generate depstubber -vendor github.com/kataras/jwt Keys,Alg Sign,SignEncrypted,SignEncryptedWithHeader,SignWithHeader +//go:generate depstubber -vendor github.com/gogf/gf-jwt/v2 GfJWTMiddleware import ( "time" @@ -15,7 +19,11 @@ import ( jwt "github.com/appleboy/gin-jwt/v2" cristal "github.com/cristalhq/jwt/v3" gokit "github.com/go-kit/kit/auth/jwt" + gogf "github.com/gogf/gf-jwt/v2" gjwt "github.com/golang-jwt/jwt/v4" + iris "github.com/iris-contrib/middleware/jwt" + iris12 "github.com/kataras/iris/v12/middleware/jwt" + kataras "github.com/kataras/jwt" le "github.com/lestrrat/go-jwx/jwk" jose_v3 "github.com/square/go-jose/v3" jose_v2 "gopkg.in/square/go-jose.v2" @@ -113,6 +121,78 @@ func lejwt2() (interface{}, error) { return le.New(sharedKeyglobal) // BAD } +func gogfjwt() interface{} { + return &gogf.GfJWTMiddleware{ + Realm: "test zone", + Key: []byte("key11"), + Timeout: time.Minute * 5, + MaxRefresh: time.Minute * 5, + IdentityKey: "id", + TokenLookup: "header: Authorization, query: token, cookie: jwt", + TokenHeadName: "Bearer", + TimeFunc: time.Now, + Authenticator: nil, + Unauthorized: nil, + PayloadFunc: nil, + IdentityHandler: nil, + } +} + +func irisjwt() interface{} { + mySecret := []byte("key12") + token := iris.NewTokenWithClaims(nil, nil) + tokenString, _ := token.SignedString(mySecret) + return tokenString +} + +func iris12jwt2() interface{} { + mySecret := []byte("key13") + + s := &iris12.Signer{ + Alg: nil, + Key: mySecret, + MaxAge: 3 * time.Second, + } + return s +} + +func irisjwt3() interface{} { + secret := []byte("key14") + signer := iris12.NewSigner(nil, secret, 3*time.Second) + return signer +} + +func katarasJwt() interface{} { + secret := []byte("key15") + token, _ := kataras.Sign(nil, secret, nil, nil) + return token +} + +func katarasJwt2() interface{} { + secret := []byte("key16") + token, _ := kataras.SignEncrypted(nil, secret, nil, nil) + return token +} + +func katarasJwt3() interface{} { + secret := []byte("key17") + token, _ := kataras.SignEncryptedWithHeader(nil, secret, nil, nil, nil) + return token +} + +func katarasJwt4() interface{} { + secret := []byte("key18") + token, _ := kataras.SignWithHeader(nil, secret, nil, nil) + return token +} + +func katarasJwt5() { + secret := []byte("key19") + var keys kataras.Keys + var alg kataras.Alg + keys.Register(alg, "api", nil, secret) +} + func main() { return } diff --git a/go/ql/test/experimental/CWE-321/vendor/github.com/gin-gonic/gin/stub.go b/go/ql/test/experimental/CWE-321/vendor/github.com/gin-gonic/gin/stub.go index f941716f925..79c7a98ec0b 100644 --- a/go/ql/test/experimental/CWE-321/vendor/github.com/gin-gonic/gin/stub.go +++ b/go/ql/test/experimental/CWE-321/vendor/github.com/gin-gonic/gin/stub.go @@ -14,6 +14,7 @@ import ( multipart "mime/multipart" net "net" http "net/http" + template0 "text/template" time "time" ) @@ -388,7 +389,7 @@ type Engine struct { TrustedPlatform string MaxMultipartMemory int64 HTMLRender interface{} - FuncMap template.FuncMap + FuncMap template0.FuncMap } func (_ *Engine) Any(_ string, _ ...HandlerFunc) IRoutes { @@ -479,7 +480,7 @@ func (_ *Engine) SecureJsonPrefix(_ string) *Engine { func (_ *Engine) ServeHTTP(_ http.ResponseWriter, _ *http.Request) {} -func (_ *Engine) SetFuncMap(_ template.FuncMap) {} +func (_ *Engine) SetFuncMap(_ template0.FuncMap) {} func (_ *Engine) SetHTMLTemplate(_ *template.Template) {} diff --git a/go/ql/test/experimental/CWE-321/vendor/github.com/gogf/gf-jwt/v2/stub.go b/go/ql/test/experimental/CWE-321/vendor/github.com/gogf/gf-jwt/v2/stub.go new file mode 100644 index 00000000000..343b5f84dca --- /dev/null +++ b/go/ql/test/experimental/CWE-321/vendor/github.com/gogf/gf-jwt/v2/stub.go @@ -0,0 +1,90 @@ +// Code generated by depstubber. DO NOT EDIT. +// This is a simple stub for github.com/gogf/gf-jwt/v2, strictly for use in testing. + +// See the LICENSE file for information about the licensing of the original library. +// Source: github.com/gogf/gf-jwt/v2 (exports: GfJWTMiddleware; functions: ) + +// Package gf is a stub of github.com/gogf/gf-jwt/v2, generated by depstubber. +package gf + +import ( + context "context" + time "time" +) + +type GfJWTMiddleware struct { + Realm string + SigningAlgorithm string + Key []byte + KeyFunc func(interface{}) (interface{}, error) + Timeout time.Duration + MaxRefresh time.Duration + Authenticator func(context.Context) (interface{}, error) + Authorizator func(interface{}, context.Context) bool + PayloadFunc func(interface{}) MapClaims + Unauthorized func(context.Context, int, string) + IdentityHandler func(context.Context) interface{} + IdentityKey string + TokenLookup string + TokenHeadName string + TimeFunc func() time.Time + HTTPStatusMessageFunc func(error, context.Context) string + PrivKeyFile string + PrivKeyBytes []byte + PubKeyFile string + PrivateKeyPassphrase string + PubKeyBytes []byte + SendCookie bool + CookieMaxAge time.Duration + SecureCookie bool + CookieHTTPOnly bool + CookieDomain string + SendAuthorization bool + DisabledAbort bool + CookieName string + CacheAdapter interface{} +} + +func (_ *GfJWTMiddleware) CheckIfTokenExpire(_ context.Context) (interface{}, string, error) { + return nil, "", nil +} + +func (_ *GfJWTMiddleware) GetClaimsFromJWT(_ context.Context) (MapClaims, string, error) { + return nil, "", nil +} + +func (_ *GfJWTMiddleware) GetIdentity(_ context.Context) interface{} { + return nil +} + +func (_ *GfJWTMiddleware) GetPayload(_ context.Context) string { + return "" +} + +func (_ *GfJWTMiddleware) GetToken(_ context.Context) string { + return "" +} + +func (_ *GfJWTMiddleware) LoginHandler(_ context.Context) (string, time.Time) { + return "", time.Time{} +} + +func (_ *GfJWTMiddleware) LogoutHandler(_ context.Context) {} + +func (_ *GfJWTMiddleware) MiddlewareFunc() func(interface{}) { + return nil +} + +func (_ *GfJWTMiddleware) RefreshHandler(_ context.Context) (string, time.Time) { + return "", time.Time{} +} + +func (_ *GfJWTMiddleware) RefreshToken(_ context.Context) (string, time.Time, error) { + return "", time.Time{}, nil +} + +func (_ *GfJWTMiddleware) TokenGenerator(_ interface{}) (string, time.Time, error) { + return "", time.Time{}, nil +} + +type MapClaims map[string]interface{} diff --git a/go/ql/test/experimental/CWE-321/vendor/github.com/golang-jwt/jwt/v4/stub.go b/go/ql/test/experimental/CWE-321/vendor/github.com/golang-jwt/jwt/v4/stub.go index d83739d7fde..a64a6c31e32 100644 --- a/go/ql/test/experimental/CWE-321/vendor/github.com/golang-jwt/jwt/v4/stub.go +++ b/go/ql/test/experimental/CWE-321/vendor/github.com/golang-jwt/jwt/v4/stub.go @@ -2,7 +2,7 @@ // This is a simple stub for github.com/golang-jwt/jwt/v4, strictly for use in testing. // See the LICENSE file for information about the licensing of the original library. -// Source: github.com/golang-jwt/jwt/v4 (exports: MapClaims,RegisteredClaims,SigningMethodRSA,SigningMethodHMAC,Token; functions: NewNumericDate,NewWithClaims) +// Source: github.com/golang-jwt/jwt/v4 (exports: MapClaims,RegisteredClaims,SigningMethodRSA,SigningMethodHMAC,Token; functions: NewNumericDate,NewWithClaims,New) // Package jwt is a stub of github.com/golang-jwt/jwt/v4, generated by depstubber. package jwt @@ -52,6 +52,10 @@ func (_ MapClaims) VerifyNotBefore(_ int64, _ bool) bool { return false } +func New(_ SigningMethod) *Token { + return nil +} + func NewNumericDate(_ time.Time) *NumericDate { return nil } @@ -220,6 +224,10 @@ func (_ NumericDate) Zone() (string, int) { return "", 0 } +func (_ NumericDate) ZoneBounds() (time.Time, time.Time) { + return time.Time{}, time.Time{} +} + func (_ *NumericDate) GobDecode(_ []byte) error { return nil } diff --git a/go/ql/test/experimental/CWE-321/vendor/github.com/iris-contrib/middleware/jwt/stub.go b/go/ql/test/experimental/CWE-321/vendor/github.com/iris-contrib/middleware/jwt/stub.go new file mode 100644 index 00000000000..942d8731623 --- /dev/null +++ b/go/ql/test/experimental/CWE-321/vendor/github.com/iris-contrib/middleware/jwt/stub.go @@ -0,0 +1,29 @@ +// Package jwt is a stub of github.com/iris-contrib/middleware/jwt, manually generated. +package jwt + +import ( + gj "github.com/golang-jwt/jwt/v4" +) + +type ( + // Token for JWT. Different fields will be used depending on whether you're + // creating or parsing/verifying a token. + // + // A type alias for jwt.Token. + Token = gj.Token + // MapClaims type that uses the map[string]interface{} for JSON decoding + // This is the default claims type if you don't supply one + // + // A type alias for jwt.MapClaims. + MapClaims = gj.MapClaims + // Claims must just have a Valid method that determines + // if the token is invalid for any supported reason. + // + // A type alias for jwt.Claims. + Claims = gj.Claims +) + +var ( + NewToken = gj.New + NewTokenWithClaims = gj.NewWithClaims +) diff --git a/go/ql/test/experimental/CWE-321/vendor/github.com/kataras/iris/v12/middleware/jwt/stub.go b/go/ql/test/experimental/CWE-321/vendor/github.com/kataras/iris/v12/middleware/jwt/stub.go new file mode 100644 index 00000000000..750ed4a15ee --- /dev/null +++ b/go/ql/test/experimental/CWE-321/vendor/github.com/kataras/iris/v12/middleware/jwt/stub.go @@ -0,0 +1,81 @@ +// Code generated by depstubber. DO NOT EDIT. +// This is a simple stub for github.com/kataras/iris/v12/middleware/jwt, strictly for use in testing. + +// See the LICENSE file for information about the licensing of the original library. +// Source: github.com/kataras/iris/v12/middleware/jwt (exports: Signer,Verifier; functions: NewSigner,NewVerifier) + +// Package jwt is a stub of github.com/kataras/iris/v12/middleware/jwt, generated by depstubber. +package jwt + +import ( + time "time" +) + +type Blocklist interface { + Count() (int64, error) + Del(_ string) error + Has(_ string) (bool, error) + InvalidateToken(_ []byte, _ interface{}) error + ValidateToken(_ []byte, _ interface{}, _ error) error +} + +func NewSigner(_ interface{}, _ interface{}, _ time.Duration) *Signer { + return nil +} + +func NewVerifier(_ interface{}, _ interface{}, _ ...interface{}) *Verifier { + return nil +} + +type Signer struct { + Alg interface{} + Key interface{} + MaxAge time.Duration + Options []interface{} + Encrypt func([]byte) ([]byte, error) +} + +func (_ *Signer) NewTokenPair(_ interface{}, _ interface{}, _ time.Duration, _ ...interface{}) (interface{}, error) { + return nil, nil +} + +func (_ *Signer) Sign(_ interface{}, _ ...interface{}) ([]byte, error) { + return nil, nil +} + +func (_ *Signer) WithEncryption(_ []byte, _ []byte) *Signer { + return nil +} + +type TokenExtractor func(interface{}) string + +type Verifier struct { + Alg interface{} + Key interface{} + Decrypt func([]byte) ([]byte, error) + Extractors []TokenExtractor + Blocklist Blocklist + Validators []interface{} + ErrorHandler func(interface{}, error) + DisableContextUser bool +} + +func (_ *Verifier) RequestToken(_ interface{}) string { + return "" +} + +func (_ *Verifier) Verify(_ func() interface{}, _ ...interface{}) interface{} { + return nil +} + +func (_ *Verifier) VerifyToken(_ []byte, _ ...interface{}) (interface{}, error) { + return nil, nil +} + +func (_ *Verifier) WithDecryption(_ []byte, _ []byte) *Verifier { + return nil +} + +func (_ *Verifier) WithDefaultBlocklist() *Verifier { + return nil +} diff --git a/go/ql/test/experimental/CWE-321/vendor/github.com/kataras/jwt/stub.go b/go/ql/test/experimental/CWE-321/vendor/github.com/kataras/jwt/stub.go new file mode 100644 index 00000000000..ee94e737207 --- /dev/null +++ b/go/ql/test/experimental/CWE-321/vendor/github.com/kataras/jwt/stub.go @@ -0,0 +1,105 @@ +// Code generated by depstubber. DO NOT EDIT. +// This is a simple stub for github.com/kataras/jwt, strictly for use in testing. + +// See the LICENSE file for information about the licensing of the original library. +// Source: github.com/kataras/jwt (exports: Keys,Alg; functions: Sign,SignEncrypted,SignEncryptedWithHeader,SignWithHeader) + +// Package jwt is a stub of github.com/kataras/jwt, generated by depstubber. +package jwt + +import ( + time "time" +) + +type Alg interface { + Name() string + Sign(_ interface{}, _ []byte) ([]byte, error) + Verify(_ interface{}, _ []byte, _ []byte) error +} + +type Audience []string + +func (_ *Audience) UnmarshalJSON(_ []byte) error { + return nil +} + +type Claims struct { + NotBefore int64 + IssuedAt int64 + Expiry int64 + ID string + OriginID string + Issuer string + Subject string + Audience Audience +} + +func (_ Claims) Age() time.Duration { + return 0 +} + +func (_ Claims) ApplyClaims(_ *Claims) {} + +func (_ Claims) ExpiresAt() time.Time { + return time.Time{} +} + +func (_ Claims) Timeleft() time.Duration { + return 0 +} + +type InjectFunc func([]byte) ([]byte, error) + +type Key struct { + ID string + Alg Alg + Public interface{} + Private interface{} + MaxAge time.Duration + Encrypt InjectFunc + Decrypt InjectFunc +} + +type Keys map[string]*Key + +func (_ Keys) Get(_ string) (*Key, bool) { + return nil, false +} + +func (_ Keys) Register(_ Alg, _ string, _ interface{}, _ interface{}) {} + +func (_ Keys) SignToken(_ string, _ interface{}, _ ...SignOption) ([]byte, error) { + return nil, nil +} + +func (_ Keys) ValidateHeader(_ string, _ []byte) (Alg, interface{}, InjectFunc, error) { + return nil, nil, nil, nil +} + +func (_ Keys) VerifyToken(_ []byte, _ interface{}, _ ...TokenValidator) error { + return nil +} + +func Sign(_ Alg, _ interface{}, _ interface{}, _ ...SignOption) ([]byte, error) { + return nil, nil +} + +func SignEncrypted(_ Alg, _ interface{}, _ InjectFunc, _ interface{}, _ ...SignOption) ([]byte, error) { + return nil, nil +} + +func SignEncryptedWithHeader(_ Alg, _ interface{}, _ InjectFunc, _ interface{}, _ interface{}, _ ...SignOption) ([]byte, error) { + return nil, nil +} + +type SignOption interface { + ApplyClaims(_ *Claims) +} + +func SignWithHeader(_ Alg, _ interface{}, _ interface{}, _ interface{}, _ ...SignOption) ([]byte, error) { + return nil, nil +} + +type TokenValidator interface { + ValidateToken(_ []byte, _ Claims, _ error) error +} diff --git a/go/ql/test/experimental/CWE-321/vendor/modules.txt b/go/ql/test/experimental/CWE-321/vendor/modules.txt index 1a10cd454fb..61fe07b4540 100644 --- a/go/ql/test/experimental/CWE-321/vendor/modules.txt +++ b/go/ql/test/experimental/CWE-321/vendor/modules.txt @@ -4,15 +4,24 @@ github.com/appleboy/gin-jwt/v2 # github.com/cristalhq/jwt/v3 v3.1.0 ## explicit github.com/cristalhq/jwt/v3 -# github.com/gin-gonic/gin v1.7.7 -## explicit -github.com/gin-gonic/gin # github.com/go-kit/kit v0.12.0 ## explicit github.com/go-kit/kit -# github.com/golang-jwt/jwt/v4 v4.4.1 +# github.com/gogf/gf-jwt/v2 v2.0.1 +## explicit +github.com/gogf/gf-jwt/v2 +# github.com/golang-jwt/jwt/v4 v4.5.0 ## explicit github.com/golang-jwt/jwt/v4 +# github.com/iris-contrib/middleware/jwt v0.0.0-20230311205048-b568fe9b470f +## explicit +github.com/iris-contrib/middleware/jwt +# github.com/kataras/iris/v12 v12.2.0 +## explicit +github.com/kataras/iris/v12 +# github.com/kataras/jwt v0.1.8 +## explicit +github.com/kataras/jwt # github.com/lestrrat/go-jwx v0.9.1 ## explicit github.com/lestrrat/go-jwx @@ -22,12 +31,60 @@ github.com/square/go-jose/v3 # gopkg.in/square/go-jose.v2 v2.6.0 ## explicit gopkg.in/square/go-jose.v2 +# github.com/BurntSushi/toml v1.2.1 +## explicit +github.com/BurntSushi/toml +# github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53 +## explicit +github.com/CloudyKit/fastprinter +# github.com/CloudyKit/jet/v6 v6.2.0 +## explicit +github.com/CloudyKit/jet/v6 +# github.com/Joker/jade v1.1.3 +## explicit +github.com/Joker/jade +# github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06 +## explicit +github.com/Shopify/goreferrer +# github.com/andybalholm/brotli v1.0.5 +## explicit +github.com/andybalholm/brotli +# github.com/aymerick/douceur v0.2.0 +## explicit +github.com/aymerick/douceur +# github.com/cespare/xxhash/v2 v2.1.2 +## explicit +github.com/cespare/xxhash/v2 +# github.com/clbanning/mxj/v2 v2.5.5 +## explicit +github.com/clbanning/mxj/v2 # github.com/davecgh/go-spew v1.1.1 ## explicit github.com/davecgh/go-spew +# github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f +## explicit +github.com/dgryski/go-rendezvous +# github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 +## explicit +github.com/eknkc/amber +# github.com/fatih/color v1.13.0 +## explicit +github.com/fatih/color +# github.com/fatih/structs v1.1.0 +## explicit +github.com/fatih/structs +# github.com/flosch/pongo2/v4 v4.0.2 +## explicit +github.com/flosch/pongo2/v4 +# github.com/fsnotify/fsnotify v1.5.4 +## explicit +github.com/fsnotify/fsnotify # github.com/gin-contrib/sse v0.1.0 ## explicit github.com/gin-contrib/sse +# github.com/gin-gonic/gin v1.7.7 +## explicit +github.com/gin-gonic/gin # github.com/go-kit/log v0.2.0 ## explicit github.com/go-kit/log @@ -43,54 +100,165 @@ github.com/go-playground/universal-translator # github.com/go-playground/validator/v10 v10.4.1 ## explicit github.com/go-playground/validator/v10 +# github.com/go-redis/redis/v8 v8.11.5 +## explicit +github.com/go-redis/redis/v8 +# github.com/go-sql-driver/mysql v1.6.0 +## explicit +github.com/go-sql-driver/mysql +# github.com/gogf/gf/v2 v2.0.0-rc3 +## explicit +github.com/gogf/gf/v2 # github.com/golang/protobuf v1.5.2 ## explicit github.com/golang/protobuf +# github.com/golang/snappy v0.0.4 +## explicit +github.com/golang/snappy +# github.com/google/uuid v1.3.0 +## explicit +github.com/google/uuid +# github.com/gorilla/css v1.0.0 +## explicit +github.com/gorilla/css +# github.com/gorilla/websocket v1.5.0 +## explicit +github.com/gorilla/websocket +# github.com/grokify/html-strip-tags-go v0.0.1 +## explicit +github.com/grokify/html-strip-tags-go +# github.com/iris-contrib/schema v0.0.6 +## explicit +github.com/iris-contrib/schema +# github.com/josharian/intern v1.0.0 +## explicit +github.com/josharian/intern # github.com/json-iterator/go v1.1.12 ## explicit github.com/json-iterator/go +# github.com/kataras/blocks v0.0.7 +## explicit +github.com/kataras/blocks +# github.com/kataras/golog v0.1.8 +## explicit +github.com/kataras/golog +# github.com/kataras/pio v0.0.11 +## explicit +github.com/kataras/pio +# github.com/kataras/sitemap v0.0.6 +## explicit +github.com/kataras/sitemap +# github.com/kataras/tunnel v0.0.4 +## explicit +github.com/kataras/tunnel +# github.com/klauspost/compress v1.16.0 +## explicit +github.com/klauspost/compress # github.com/leodido/go-urn v1.2.0 ## explicit github.com/leodido/go-urn # github.com/lestrrat/go-pdebug v0.0.0-20180220043741-569c97477ae8 ## explicit github.com/lestrrat/go-pdebug -# github.com/mattn/go-isatty v0.0.14 +# github.com/mailgun/raymond/v2 v2.0.48 +## explicit +github.com/mailgun/raymond/v2 +# github.com/mailru/easyjson v0.7.7 +## explicit +github.com/mailru/easyjson +# github.com/mattn/go-colorable v0.1.9 +## explicit +github.com/mattn/go-colorable +# github.com/mattn/go-isatty v0.0.17 ## explicit github.com/mattn/go-isatty +# github.com/mattn/go-runewidth v0.0.9 +## explicit +github.com/mattn/go-runewidth +# github.com/microcosm-cc/bluemonday v1.0.23 +## explicit +github.com/microcosm-cc/bluemonday # github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd ## explicit github.com/modern-go/concurrent # github.com/modern-go/reflect2 v1.0.2 ## explicit github.com/modern-go/reflect2 +# github.com/olekukonko/tablewriter v0.0.5 +## explicit +github.com/olekukonko/tablewriter # github.com/pkg/errors v0.9.1 ## explicit github.com/pkg/errors +# github.com/russross/blackfriday/v2 v2.1.0 +## explicit +github.com/russross/blackfriday/v2 +# github.com/schollz/closestmatch v2.1.0+incompatible +## explicit +github.com/schollz/closestmatch +# github.com/sirupsen/logrus v1.8.1 +## explicit +github.com/sirupsen/logrus +# github.com/tdewolff/minify/v2 v2.12.4 +## explicit +github.com/tdewolff/minify/v2 +# github.com/tdewolff/parse/v2 v2.6.4 +## explicit +github.com/tdewolff/parse/v2 # github.com/ugorji/go/codec v1.1.7 ## explicit github.com/ugorji/go/codec -# golang.org/x/crypto v0.0.0-20210915214749-c084706c2272 +# github.com/valyala/bytebufferpool v1.0.0 +## explicit +github.com/valyala/bytebufferpool +# github.com/vmihailenco/msgpack/v5 v5.3.5 +## explicit +github.com/vmihailenco/msgpack/v5 +# github.com/vmihailenco/tagparser/v2 v2.0.0 +## explicit +github.com/vmihailenco/tagparser/v2 +# github.com/yosssi/ace v0.0.5 +## explicit +github.com/yosssi/ace +# go.opentelemetry.io/otel v1.0.0 +## explicit +go.opentelemetry.io/otel +# go.opentelemetry.io/otel/sdk v1.0.0 +## explicit +go.opentelemetry.io/otel/sdk +# go.opentelemetry.io/otel/trace v1.0.0 +## explicit +go.opentelemetry.io/otel/trace +# golang.org/x/crypto v0.7.0 ## explicit golang.org/x/crypto -# golang.org/x/net v0.0.0-20210917221730-978cfadd31cf +# golang.org/x/net v0.8.0 ## explicit golang.org/x/net -# golang.org/x/sys v0.0.0-20210917161153-d61c044b1678 +# golang.org/x/sys v0.6.0 ## explicit golang.org/x/sys -# golang.org/x/text v0.3.7 +# golang.org/x/text v0.8.0 ## explicit golang.org/x/text +# golang.org/x/time v0.3.0 +## explicit +golang.org/x/time # google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4 ## explicit google.golang.org/genproto # google.golang.org/grpc v1.40.0 ## explicit google.golang.org/grpc -# google.golang.org/protobuf v1.27.1 +# google.golang.org/protobuf v1.29.0 ## explicit google.golang.org/protobuf -# gopkg.in/yaml.v2 v2.2.8 +# gopkg.in/ini.v1 v1.67.0 +## explicit +gopkg.in/ini.v1 +# gopkg.in/yaml.v2 v2.4.0 ## explicit gopkg.in/yaml.v2 +# gopkg.in/yaml.v3 v3.0.1 +## explicit +gopkg.in/yaml.v3 diff --git a/go/ql/test/extractor-tests/diagnostics/Diagnostics.ql b/go/ql/test/extractor-tests/diagnostics/Diagnostics.ql index dd6bb45e6a0..ed6d8ac043d 100644 --- a/go/ql/test/extractor-tests/diagnostics/Diagnostics.ql +++ b/go/ql/test/extractor-tests/diagnostics/Diagnostics.ql @@ -44,7 +44,7 @@ class Diagnostic extends @diagnostic { } /** - * Wraps `Compilation`, removing the `.exe` suffixes from compilation descriptions + * A wrapper around a `Compilation`, removing the `.exe` suffixes from compilation descriptions * such that this test produces the same results on Windows and non-Windows platforms. */ class PlatformNeutralCompilation extends Compilation { diff --git a/go/ql/test/library-tests/semmle/go/Packages/package.ql b/go/ql/test/library-tests/semmle/go/Packages/package.ql index 41ee771ecdf..74644c44c0b 100644 --- a/go/ql/test/library-tests/semmle/go/Packages/package.ql +++ b/go/ql/test/library-tests/semmle/go/Packages/package.ql @@ -2,17 +2,18 @@ import go from string path where - ( - path = "github.com/nonexistent/v2/test" or // OK - path = "github.com/nonexistent/test" or // OK - path = "github.com/nonexistent//v//test" or // NOT OK - path = "github.com/nonexistent//v/test" or // NOT OK - path = "github.com/nonexistent/v//test" or // NOT OK - path = "github.com/nonexistent/v/asd/v2/test" or // NOT OK - path = "github.com/nonexistent/v/test" or // NOT OK - path = "github.com/nonexistent//v2//test" or // NOT OK - path = "github.com/nonexistent//v2/test" or // NOT OK - path = "github.com/nonexistent/v2//test" // NOT OK - ) and + path = + [ + "github.com/nonexistent/v2/test", // OK + "github.com/nonexistent/test", // OK + "github.com/nonexistent//v//test", // NOT OK + "github.com/nonexistent//v/test", // NOT OK + "github.com/nonexistent/v//test", // NOT OK + "github.com/nonexistent/v/asd/v2/test", // NOT OK + "github.com/nonexistent/v/test", // NOT OK + "github.com/nonexistent//v2//test", // NOT OK + "github.com/nonexistent//v2/test", // NOT OK + "github.com/nonexistent/v2//test" // NOT OK + ] and path = package("github.com/nonexistent", "test") select path diff --git a/go/ql/test/library-tests/semmle/go/Types/MethodCount.ql b/go/ql/test/library-tests/semmle/go/Types/MethodCount.ql index b4d3d2663fd..d0d3ee09b43 100644 --- a/go/ql/test/library-tests/semmle/go/Types/MethodCount.ql +++ b/go/ql/test/library-tests/semmle/go/Types/MethodCount.ql @@ -1,5 +1,5 @@ import go from Type t -where t.getPackage().getName().regexpMatch("main|pkg1|pkg2") +where t.getPackage().getName() = ["main", "pkg1", "pkg2"] select t.pp(), strictcount(t.getMethod(_)) diff --git a/go/ql/test/library-tests/semmle/go/Types/Methods.ql b/go/ql/test/library-tests/semmle/go/Types/Methods.ql index 2204612f64a..d00ee5865f4 100644 --- a/go/ql/test/library-tests/semmle/go/Types/Methods.ql +++ b/go/ql/test/library-tests/semmle/go/Types/Methods.ql @@ -1,5 +1,5 @@ import go from Type t, string m -where t.getPackage().getName().regexpMatch("main|pkg1|pkg2") +where t.getPackage().getName() = ["main", "pkg1", "pkg2"] select t.pp(), m, t.getMethod(m) diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Beego/OpenRedirect.expected b/go/ql/test/library-tests/semmle/go/frameworks/Beego/OpenRedirect.expected index 9a80d4698cc..ebdb44f02e2 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Beego/OpenRedirect.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Beego/OpenRedirect.expected @@ -8,5 +8,5 @@ nodes | test.go:312:20:312:34 | call to URL | semmle.label | call to URL | subpaths #select -| test.go:247:13:247:34 | call to GetString | test.go:247:13:247:34 | call to GetString | test.go:247:13:247:34 | call to GetString | Untrusted URL redirection depends on a $@. | test.go:247:13:247:34 | call to GetString | user-provided value | -| test.go:248:20:248:41 | call to GetString | test.go:248:20:248:41 | call to GetString | test.go:248:20:248:41 | call to GetString | Untrusted URL redirection depends on a $@. | test.go:248:20:248:41 | call to GetString | user-provided value | +| test.go:247:13:247:34 | call to GetString | test.go:247:13:247:34 | call to GetString | test.go:247:13:247:34 | call to GetString | This path to an untrusted URL redirection depends on a $@. | test.go:247:13:247:34 | call to GetString | user-provided value | +| test.go:248:20:248:41 | call to GetString | test.go:248:20:248:41 | call to GetString | test.go:248:20:248:41 | call to GetString | This path to an untrusted URL redirection depends on a $@. | test.go:248:20:248:41 | call to GetString | user-provided value | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Echo/OpenRedirect.expected b/go/ql/test/library-tests/semmle/go/frameworks/Echo/OpenRedirect.expected index 10ad0046423..5bdc5910dc3 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Echo/OpenRedirect.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Echo/OpenRedirect.expected @@ -14,5 +14,5 @@ nodes | test.go:191:21:191:32 | call to String | semmle.label | call to String | subpaths #select -| test.go:171:20:171:24 | param | test.go:170:11:170:32 | call to Param | test.go:171:20:171:24 | param | Untrusted URL redirection depends on a $@. | test.go:170:11:170:32 | call to Param | user-provided value | -| test.go:180:20:180:28 | ...+... | test.go:176:11:176:32 | call to Param | test.go:180:20:180:28 | ...+... | Untrusted URL redirection depends on a $@. | test.go:176:11:176:32 | call to Param | user-provided value | +| test.go:171:20:171:24 | param | test.go:170:11:170:32 | call to Param | test.go:171:20:171:24 | param | This path to an untrusted URL redirection depends on a $@. | test.go:170:11:170:32 | call to Param | user-provided value | +| test.go:180:20:180:28 | ...+... | test.go:176:11:176:32 | call to Param | test.go:180:20:180:28 | ...+... | This path to an untrusted URL redirection depends on a $@. | test.go:176:11:176:32 | call to Param | user-provided value | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Revel/OpenRedirect.expected b/go/ql/test/library-tests/semmle/go/frameworks/Revel/OpenRedirect.expected index 77436c0d149..a2321bb16fa 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Revel/OpenRedirect.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Revel/OpenRedirect.expected @@ -5,4 +5,4 @@ nodes | EndToEnd.go:94:20:94:49 | call to Get | semmle.label | call to Get | subpaths #select -| EndToEnd.go:94:20:94:49 | call to Get | EndToEnd.go:94:20:94:27 | selection of Params | EndToEnd.go:94:20:94:49 | call to Get | Untrusted URL redirection depends on a $@. | EndToEnd.go:94:20:94:27 | selection of Params | user-provided value | +| EndToEnd.go:94:20:94:49 | call to Get | EndToEnd.go:94:20:94:27 | selection of Params | EndToEnd.go:94:20:94:49 | call to Get | This path to an untrusted URL redirection depends on a $@. | EndToEnd.go:94:20:94:27 | selection of Params | user-provided value | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/QueryString.ql b/go/ql/test/library-tests/semmle/go/frameworks/SQL/QueryString.ql index d0b8848480c..9cde1ad1fbe 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/SQL/QueryString.ql +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/QueryString.ql @@ -8,10 +8,9 @@ class SqlTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "query" and - exists(SQL::Query q, SQL::QueryString qs, int qsLine | qs = q.getAQueryString() | + exists(SQL::Query q, SQL::QueryString qs | qs = q.getAQueryString() | q.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and - qs.hasLocationInfo(_, qsLine, _, _, _) and element = q.toString() and value = qs.toString() ) diff --git a/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected b/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected index f7e2677efef..d4de75b2cc6 100644 --- a/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected +++ b/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected @@ -112,14 +112,14 @@ nodes | stdlib.go:194:23:194:42 | call to EscapedPath | semmle.label | call to EscapedPath | subpaths #select -| OpenUrlRedirect.go:10:23:10:42 | call to Get | OpenUrlRedirect.go:10:23:10:28 | selection of Form | OpenUrlRedirect.go:10:23:10:42 | call to Get | Untrusted URL redirection depends on a $@. | OpenUrlRedirect.go:10:23:10:28 | selection of Form | user-provided value | -| stdlib.go:15:30:15:35 | target | stdlib.go:13:13:13:18 | selection of Form | stdlib.go:15:30:15:35 | target | Untrusted URL redirection depends on a $@. | stdlib.go:13:13:13:18 | selection of Form | user-provided value | -| stdlib.go:24:30:24:35 | target | stdlib.go:22:13:22:18 | selection of Form | stdlib.go:24:30:24:35 | target | Untrusted URL redirection depends on a $@. | stdlib.go:22:13:22:18 | selection of Form | user-provided value | -| stdlib.go:35:30:35:39 | ...+... | stdlib.go:31:13:31:18 | selection of Form | stdlib.go:35:30:35:39 | ...+... | Untrusted URL redirection depends on a $@. | stdlib.go:31:13:31:18 | selection of Form | user-provided value | -| stdlib.go:46:23:46:28 | target | stdlib.go:44:13:44:18 | selection of Form | stdlib.go:46:23:46:28 | target | Untrusted URL redirection depends on a $@. | stdlib.go:44:13:44:18 | selection of Form | user-provided value | -| stdlib.go:67:23:67:40 | ...+... | stdlib.go:64:13:64:18 | selection of Form | stdlib.go:67:23:67:40 | ...+... | Untrusted URL redirection depends on a $@. | stdlib.go:64:13:64:18 | selection of Form | user-provided value | -| stdlib.go:92:23:92:28 | target | stdlib.go:89:13:89:18 | selection of Form | stdlib.go:92:23:92:28 | target | Untrusted URL redirection depends on a $@. | stdlib.go:89:13:89:18 | selection of Form | user-provided value | -| stdlib.go:152:23:152:28 | target | stdlib.go:146:13:146:18 | selection of Form | stdlib.go:152:23:152:28 | target | Untrusted URL redirection depends on a $@. | stdlib.go:146:13:146:18 | selection of Form | user-provided value | -| stdlib.go:184:23:184:28 | target | stdlib.go:182:13:182:33 | call to FormValue | stdlib.go:184:23:184:28 | target | Untrusted URL redirection depends on a $@. | stdlib.go:182:13:182:33 | call to FormValue | user-provided value | -| stdlib.go:192:23:192:33 | selection of Path | stdlib.go:190:36:190:56 | call to FormValue | stdlib.go:192:23:192:33 | selection of Path | Untrusted URL redirection depends on a $@. | stdlib.go:190:36:190:56 | call to FormValue | user-provided value | -| stdlib.go:194:23:194:42 | call to EscapedPath | stdlib.go:190:36:190:56 | call to FormValue | stdlib.go:194:23:194:42 | call to EscapedPath | Untrusted URL redirection depends on a $@. | stdlib.go:190:36:190:56 | call to FormValue | user-provided value | +| OpenUrlRedirect.go:10:23:10:42 | call to Get | OpenUrlRedirect.go:10:23:10:28 | selection of Form | OpenUrlRedirect.go:10:23:10:42 | call to Get | This path to an untrusted URL redirection depends on a $@. | OpenUrlRedirect.go:10:23:10:28 | selection of Form | user-provided value | +| stdlib.go:15:30:15:35 | target | stdlib.go:13:13:13:18 | selection of Form | stdlib.go:15:30:15:35 | target | This path to an untrusted URL redirection depends on a $@. | stdlib.go:13:13:13:18 | selection of Form | user-provided value | +| stdlib.go:24:30:24:35 | target | stdlib.go:22:13:22:18 | selection of Form | stdlib.go:24:30:24:35 | target | This path to an untrusted URL redirection depends on a $@. | stdlib.go:22:13:22:18 | selection of Form | user-provided value | +| stdlib.go:35:30:35:39 | ...+... | stdlib.go:31:13:31:18 | selection of Form | stdlib.go:35:30:35:39 | ...+... | This path to an untrusted URL redirection depends on a $@. | stdlib.go:31:13:31:18 | selection of Form | user-provided value | +| stdlib.go:46:23:46:28 | target | stdlib.go:44:13:44:18 | selection of Form | stdlib.go:46:23:46:28 | target | This path to an untrusted URL redirection depends on a $@. | stdlib.go:44:13:44:18 | selection of Form | user-provided value | +| stdlib.go:67:23:67:40 | ...+... | stdlib.go:64:13:64:18 | selection of Form | stdlib.go:67:23:67:40 | ...+... | This path to an untrusted URL redirection depends on a $@. | stdlib.go:64:13:64:18 | selection of Form | user-provided value | +| stdlib.go:92:23:92:28 | target | stdlib.go:89:13:89:18 | selection of Form | stdlib.go:92:23:92:28 | target | This path to an untrusted URL redirection depends on a $@. | stdlib.go:89:13:89:18 | selection of Form | user-provided value | +| stdlib.go:152:23:152:28 | target | stdlib.go:146:13:146:18 | selection of Form | stdlib.go:152:23:152:28 | target | This path to an untrusted URL redirection depends on a $@. | stdlib.go:146:13:146:18 | selection of Form | user-provided value | +| stdlib.go:184:23:184:28 | target | stdlib.go:182:13:182:33 | call to FormValue | stdlib.go:184:23:184:28 | target | This path to an untrusted URL redirection depends on a $@. | stdlib.go:182:13:182:33 | call to FormValue | user-provided value | +| stdlib.go:192:23:192:33 | selection of Path | stdlib.go:190:36:190:56 | call to FormValue | stdlib.go:192:23:192:33 | selection of Path | This path to an untrusted URL redirection depends on a $@. | stdlib.go:190:36:190:56 | call to FormValue | user-provided value | +| stdlib.go:194:23:194:42 | call to EscapedPath | stdlib.go:190:36:190:56 | call to FormValue | stdlib.go:194:23:194:42 | call to EscapedPath | This path to an untrusted URL redirection depends on a $@. | stdlib.go:190:36:190:56 | call to FormValue | user-provided value | diff --git a/java/downgrades/7cbc85b1f3ecda39661ad4806dedbd0973d2c4c0/old.dbscheme b/java/downgrades/7cbc85b1f3ecda39661ad4806dedbd0973d2c4c0/old.dbscheme new file mode 100644 index 00000000000..7cbc85b1f3e --- /dev/null +++ b/java/downgrades/7cbc85b1f3ecda39661ad4806dedbd0973d2c4c0/old.dbscheme @@ -0,0 +1,1255 @@ +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * javac A.java B.java C.java + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * javac A.java B.java C.java + */ + unique int id : @compilation, + int kind: int ref, + string cwd : string ref, + string name : string ref +); + +case @compilation.kind of + 1 = @javacompilation +| 2 = @kotlincompilation +; + +compilation_started( + int id : @compilation ref +) + +compilation_info( + int id : @compilation ref, + string info_key: string ref, + string info_value: string ref +) + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--javac-args` + * 2 | A.java + * 3 | B.java + * 4 | C.java + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The expanded arguments that were passed to the extractor for a + * compiler invocation. This is similar to `compilation_args`, but + * for a `@@@someFile` argument, it includes the arguments from that + * file, rather than just taking the argument literally. + */ +#keyset[id, num] +compilation_expanded_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | A.java + * 1 | B.java + * 2 | C.java + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * For each file recorded in `compilation_compiling_files`, + * there will be a corresponding row in + * `compilation_compiling_files_completed` once extraction + * of that file is complete. The `result` will indicate the + * extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +#keyset[id, num] +compilation_compiling_files_completed( + int id : @compilation ref, + int num : int ref, + int result : int ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * The `cpu_seconds` and `elapsed_seconds` are the CPU time and elapsed + * time (respectively) that the original compilation (not the extraction) + * took for compiler invocation `id`. + */ +compilation_compiler_times( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + * The `result` will indicate the extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref, + int result : int ref +); + +diagnostics( + unique int id: @diagnostic, + string generated_by: string ref, // TODO: Sync this with the other languages? + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/* + * External artifacts + */ + +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +snapshotDate( + unique date snapshotDate : date ref +); + +sourceLocationPrefix( + string prefix : string ref +); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id : @duplication, + string relativePath : string ref, + int equivClass : int ref +); + +similarCode( + unique int id : @similarity, + string 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 +); + +/* + * SMAP + */ + +smap_header( + int outputFileId: @file ref, + string outputFilename: string ref, + string defaultStratum: string ref +); + +smap_files( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + string inputFileName: string ref, + int inputFileId: @file ref +); + +smap_lines( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + int inputStartLine: int ref, + int inputLineCount: int ref, + int outputStartLine: int ref, + int outputLineIncrement: int ref +); + +/* + * Locations and files + */ + +@location = @location_default ; + +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 +); + +hasLocation( + int locatableid: @locatable ref, + int id: @location ref +); + +@sourceline = @locatable ; + +#keyset[element_id] +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 +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/* + * Java + */ + +cupackage( + unique int id: @file ref, + int packageid: @package ref +); + +#keyset[fileid,keyName] +jarManifestMain( + int fileid: @file ref, + string keyName: string ref, + string value: string ref +); + +#keyset[fileid,entryName,keyName] +jarManifestEntries( + int fileid: @file ref, + string entryName: string ref, + string keyName: string ref, + string value: string ref +); + +packages( + unique int id: @package, + string nodeName: string ref +); + +primitives( + unique int id: @primitive, + string nodeName: string ref +); + +modifiers( + unique int id: @modifier, + string nodeName: string ref +); + +/** + * An errortype is used when the extractor is unable to extract a type + * correctly for some reason. + */ +error_type( + unique int id: @errortype +); + +classes_or_interfaces( + unique int id: @classorinterface, + string nodeName: string ref, + int parentid: @package ref, + int sourceid: @classorinterface ref +); + +file_class( + int id: @classorinterface ref +); + +class_object( + unique int id: @classorinterface ref, + unique int instance: @field ref +); + +type_companion_object( + unique int id: @classorinterface ref, + unique int instance: @field ref, + unique int companion_object: @classorinterface ref +); + +kt_nullable_types( + unique int id: @kt_nullable_type, + int classid: @reftype ref +) + +kt_notnull_types( + unique int id: @kt_notnull_type, + int classid: @reftype ref +) + +kt_type_alias( + unique int id: @kt_type_alias, + string name: string ref, + int kttypeid: @kt_type ref +) + +@kt_type = @kt_nullable_type | @kt_notnull_type + +isInterface( + unique int id: @classorinterface ref +); + +isRecord( + unique int id: @classorinterface ref +); + +fielddecls( + unique int id: @fielddecl, + int parentid: @reftype ref +); + +#keyset[fieldId] #keyset[fieldDeclId,pos] +fieldDeclaredIn( + int fieldId: @field ref, + int fieldDeclId: @fielddecl ref, + int pos: int ref +); + +fields( + unique int id: @field, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @field ref +); + +fieldsKotlinType( + unique int id: @field ref, + int kttypeid: @kt_type ref +); + +constrs( + unique int id: @constructor, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @constructor ref +); + +constrsKotlinType( + unique int id: @constructor ref, + int kttypeid: @kt_type ref +); + +methods( + unique int id: @method, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @method ref +); + +methodsKotlinType( + unique int id: @method ref, + int kttypeid: @kt_type ref +); + +#keyset[parentid,pos] +params( + unique int id: @param, + int typeid: @type ref, + int pos: int ref, + int parentid: @callable ref, + int sourceid: @param ref +); + +paramsKotlinType( + unique int id: @param ref, + int kttypeid: @kt_type ref +); + +paramName( + unique int id: @param ref, + string nodeName: string ref +); + +isVarargsParam( + int param: @param ref +); + +exceptions( + unique int id: @exception, + int typeid: @type ref, + int parentid: @callable ref +); + +isAnnotType( + int interfaceid: @classorinterface ref +); + +isAnnotElem( + int methodid: @method ref +); + +annotValue( + int parentid: @annotation ref, + int id2: @method ref, + unique int value: @expr ref +); + +isEnumType( + int classid: @classorinterface ref +); + +isEnumConst( + int fieldid: @field ref +); + +#keyset[parentid,pos] +typeVars( + unique int id: @typevariable, + string nodeName: string ref, + int pos: int ref, + int kind: int ref, // deprecated + int parentid: @classorinterfaceorcallable ref +); + +wildcards( + unique int id: @wildcard, + string nodeName: string ref, + int kind: int ref +); + +#keyset[parentid,pos] +typeBounds( + unique int id: @typebound, + int typeid: @reftype ref, + int pos: int ref, + int parentid: @boundedtype ref +); + +#keyset[parentid,pos] +typeArgs( + int argumentid: @reftype ref, + int pos: int ref, + int parentid: @classorinterfaceorcallable ref +); + +isParameterized( + int memberid: @member ref +); + +isRaw( + int memberid: @member ref +); + +erasure( + unique int memberid: @member ref, + int erasureid: @member ref +); + +#keyset[classid] #keyset[parent] +isAnonymClass( + int classid: @classorinterface ref, + int parent: @classinstancexpr ref +); + +#keyset[typeid] #keyset[parent] +isLocalClassOrInterface( + int typeid: @classorinterface ref, + int parent: @localtypedeclstmt ref +); + +isDefConstr( + int constructorid: @constructor ref +); + +#keyset[exprId] +lambdaKind( + int exprId: @lambdaexpr ref, + int bodyKind: int ref +); + +arrays( + unique int id: @array, + string nodeName: string ref, + int elementtypeid: @type ref, + int dimension: int ref, + int componenttypeid: @type ref +); + +enclInReftype( + unique int child: @reftype ref, + int parent: @reftype ref +); + +extendsReftype( + int id1: @reftype ref, + int id2: @classorinterface ref +); + +implInterface( + int id1: @classorarray ref, + int id2: @classorinterface ref +); + +permits( + int id1: @classorinterface ref, + int id2: @classorinterface ref +); + +hasModifier( + int id1: @modifiable ref, + int id2: @modifier ref +); + +imports( + unique int id: @import, + int holder: @classorinterfaceorpackage ref, + string name: string ref, + int kind: int ref +); + +#keyset[parent,idx] +stmts( + unique int id: @stmt, + int kind: int ref, + int parent: @stmtparent ref, + int idx: int ref, + int bodydecl: @callable ref +); + +@stmtparent = @callable | @stmt | @switchexpr | @whenexpr| @stmtexpr; + +case @stmt.kind of + 0 = @block +| 1 = @ifstmt +| 2 = @forstmt +| 3 = @enhancedforstmt +| 4 = @whilestmt +| 5 = @dostmt +| 6 = @trystmt +| 7 = @switchstmt +| 8 = @synchronizedstmt +| 9 = @returnstmt +| 10 = @throwstmt +| 11 = @breakstmt +| 12 = @continuestmt +| 13 = @emptystmt +| 14 = @exprstmt +| 15 = @labeledstmt +| 16 = @assertstmt +| 17 = @localvariabledeclstmt +| 18 = @localtypedeclstmt +| 19 = @constructorinvocationstmt +| 20 = @superconstructorinvocationstmt +| 21 = @case +| 22 = @catchclause +| 23 = @yieldstmt +| 24 = @errorstmt +| 25 = @whenbranch +; + +#keyset[parent,idx] +exprs( + unique int id: @expr, + int kind: int ref, + int typeid: @type ref, + int parent: @exprparent ref, + int idx: int ref +); + +exprsKotlinType( + unique int id: @expr ref, + int kttypeid: @kt_type ref +); + +callableEnclosingExpr( + unique int id: @expr ref, + int callable_id: @callable ref +); + +statementEnclosingExpr( + unique int id: @expr ref, + int statement_id: @stmt ref +); + +isParenthesized( + unique int id: @expr ref, + int parentheses: int ref +); + +case @expr.kind of + 1 = @arrayaccess +| 2 = @arraycreationexpr +| 3 = @arrayinit +| 4 = @assignexpr +| 5 = @assignaddexpr +| 6 = @assignsubexpr +| 7 = @assignmulexpr +| 8 = @assigndivexpr +| 9 = @assignremexpr +| 10 = @assignandexpr +| 11 = @assignorexpr +| 12 = @assignxorexpr +| 13 = @assignlshiftexpr +| 14 = @assignrshiftexpr +| 15 = @assignurshiftexpr +| 16 = @booleanliteral +| 17 = @integerliteral +| 18 = @longliteral +| 19 = @floatingpointliteral +| 20 = @doubleliteral +| 21 = @characterliteral +| 22 = @stringliteral +| 23 = @nullliteral +| 24 = @mulexpr +| 25 = @divexpr +| 26 = @remexpr +| 27 = @addexpr +| 28 = @subexpr +| 29 = @lshiftexpr +| 30 = @rshiftexpr +| 31 = @urshiftexpr +| 32 = @andbitexpr +| 33 = @orbitexpr +| 34 = @xorbitexpr +| 35 = @andlogicalexpr +| 36 = @orlogicalexpr +| 37 = @ltexpr +| 38 = @gtexpr +| 39 = @leexpr +| 40 = @geexpr +| 41 = @eqexpr +| 42 = @neexpr +| 43 = @postincexpr +| 44 = @postdecexpr +| 45 = @preincexpr +| 46 = @predecexpr +| 47 = @minusexpr +| 48 = @plusexpr +| 49 = @bitnotexpr +| 50 = @lognotexpr +| 51 = @castexpr +| 52 = @newexpr +| 53 = @conditionalexpr +| 54 = @parexpr // deprecated +| 55 = @instanceofexpr +| 56 = @localvariabledeclexpr +| 57 = @typeliteral +| 58 = @thisaccess +| 59 = @superaccess +| 60 = @varaccess +| 61 = @methodaccess +| 62 = @unannotatedtypeaccess +| 63 = @arraytypeaccess +| 64 = @packageaccess +| 65 = @wildcardtypeaccess +| 66 = @declannotation +| 67 = @uniontypeaccess +| 68 = @lambdaexpr +| 69 = @memberref +| 70 = @annotatedtypeaccess +| 71 = @typeannotation +| 72 = @intersectiontypeaccess +| 73 = @switchexpr +| 74 = @errorexpr +| 75 = @whenexpr +| 76 = @getclassexpr +| 77 = @safecastexpr +| 78 = @implicitcastexpr +| 79 = @implicitnotnullexpr +| 80 = @implicitcoerciontounitexpr +| 81 = @notinstanceofexpr +| 82 = @stmtexpr +| 83 = @stringtemplateexpr +| 84 = @notnullexpr +| 85 = @unsafecoerceexpr +| 86 = @valueeqexpr +| 87 = @valueneexpr +| 88 = @propertyref +; + +/** Holds if this `when` expression was written as an `if` expression. */ +when_if(unique int id: @whenexpr ref); + +/** Holds if this `when` branch was written as an `else` branch. */ +when_branch_else(unique int id: @whenbranch ref); + +@classinstancexpr = @newexpr | @lambdaexpr | @memberref | @propertyref + +@annotation = @declannotation | @typeannotation +@typeaccess = @unannotatedtypeaccess | @annotatedtypeaccess + +@assignment = @assignexpr + | @assignop; + +@unaryassignment = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr; + +@assignop = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + | @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignurshiftexpr; + +@literal = @booleanliteral + | @integerliteral + | @longliteral + | @floatingpointliteral + | @doubleliteral + | @characterliteral + | @stringliteral + | @nullliteral; + +@binaryexpr = @mulexpr + | @divexpr + | @remexpr + | @addexpr + | @subexpr + | @lshiftexpr + | @rshiftexpr + | @urshiftexpr + | @andbitexpr + | @orbitexpr + | @xorbitexpr + | @andlogicalexpr + | @orlogicalexpr + | @ltexpr + | @gtexpr + | @leexpr + | @geexpr + | @eqexpr + | @neexpr + | @valueeqexpr + | @valueneexpr; + +@unaryexpr = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr + | @minusexpr + | @plusexpr + | @bitnotexpr + | @lognotexpr + | @notnullexpr; + +@caller = @classinstancexpr + | @methodaccess + | @constructorinvocationstmt + | @superconstructorinvocationstmt; + +callableBinding( + unique int callerid: @caller ref, + int callee: @callable ref +); + +memberRefBinding( + unique int id: @expr ref, + int callable: @callable ref +); + +propertyRefGetBinding( + unique int id: @expr ref, + int getter: @callable ref +); + +propertyRefFieldBinding( + unique int id: @expr ref, + int field: @field ref +); + +propertyRefSetBinding( + unique int id: @expr ref, + int setter: @callable ref +); + +@exprparent = @stmt | @expr | @whenbranch | @callable | @field | @fielddecl | @classorinterface | @param | @localvar | @typevariable; + +variableBinding( + unique int expr: @varaccess ref, + int variable: @variable ref +); + +@variable = @localscopevariable | @field; + +@localscopevariable = @localvar | @param; + +localvars( + unique int id: @localvar, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @localvariabledeclexpr ref +); + +localvarsKotlinType( + unique int id: @localvar ref, + int kttypeid: @kt_type ref +); + +@namedexprorstmt = @breakstmt + | @continuestmt + | @labeledstmt + | @literal; + +namestrings( + string name: string ref, + string value: string ref, + unique int parent: @namedexprorstmt ref +); + +/* + * Modules + */ + +#keyset[name] +modules( + unique int id: @module, + string name: string ref +); + +isOpen( + int id: @module ref +); + +#keyset[fileId] +cumodule( + int fileId: @file ref, + int moduleId: @module ref +); + +@directive = @requires + | @exports + | @opens + | @uses + | @provides + +#keyset[directive] +directives( + int id: @module ref, + int directive: @directive ref +); + +requires( + unique int id: @requires, + int target: @module ref +); + +isTransitive( + int id: @requires ref +); + +isStatic( + int id: @requires ref +); + +exports( + unique int id: @exports, + int target: @package ref +); + +exportsTo( + int id: @exports ref, + int target: @module ref +); + +opens( + unique int id: @opens, + int target: @package ref +); + +opensTo( + int id: @opens ref, + int target: @module ref +); + +uses( + unique int id: @uses, + string serviceInterface: string ref +); + +provides( + unique int id: @provides, + string serviceInterface: string ref +); + +providesWith( + int id: @provides ref, + string serviceImpl: string ref +); + +/* + * Javadoc + */ + +javadoc( + unique int id: @javadoc +); + +isNormalComment( + int commentid : @javadoc ref +); + +isEolComment( + int commentid : @javadoc ref +); + +hasJavadoc( + int documentableid: @member ref, + int javadocid: @javadoc ref +); + +#keyset[parentid,idx] +javadocTag( + unique int id: @javadocTag, + string name: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +#keyset[parentid,idx] +javadocText( + unique int id: @javadocText, + string text: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +@javadocParent = @javadoc | @javadocTag; +@javadocElement = @javadocTag | @javadocText; + +@classorinterfaceorpackage = @classorinterface | @package; +@classorinterfaceorcallable = @classorinterface | @callable; +@boundedtype = @typevariable | @wildcard; +@reftype = @classorinterface | @array | @boundedtype | @errortype; +@classorarray = @classorinterface | @array; +@type = @primitive | @reftype; +@callable = @method | @constructor; + +/** A program element that has a name. */ +@element = @package | @modifier | @annotation | @errortype | + @locatableElement; + +@locatableElement = @file | @primitive | @classorinterface | @method | @constructor | @param | @exception | @field | + @boundedtype | @array | @localvar | @expr | @stmt | @import | @fielddecl | @kt_type | @kt_type_alias | + @kt_property; + +@modifiable = @member_modifiable| @param | @localvar | @typevariable; + +@member_modifiable = @classorinterface | @method | @constructor | @field | @kt_property; + +@member = @method | @constructor | @field | @reftype ; + +/** A program element that has a location. */ +@locatable = @typebound | @javadoc | @javadocTag | @javadocText | @xmllocatable | @ktcomment | + @locatableElement; + +@top = @element | @locatable | @folder; + +/* + * 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; + +/* + * configuration files with key value pairs + */ + +configs( + unique int id: @config +); + +configNames( + unique int id: @configName, + int config: @config ref, + string name: string ref +); + +configValues( + unique int id: @configValue, + int config: @config ref, + string value: string ref +); + +configLocations( + int locatable: @configLocatable ref, + int location: @location_default ref +); + +@configLocatable = @config | @configName | @configValue; + +ktComments( + unique int id: @ktcomment, + int kind: int ref, + string text : string ref +) + +ktCommentSections( + unique int id: @ktcommentsection, + int comment: @ktcomment ref, + string content : string ref +) + +ktCommentSectionNames( + unique int id: @ktcommentsection ref, + string name : string ref +) + +ktCommentSectionSubjectNames( + unique int id: @ktcommentsection ref, + string subjectname : string ref +) + +#keyset[id, owner] +ktCommentOwners( + int id: @ktcomment ref, + int owner: @top ref +) + +ktExtensionFunctions( + unique int id: @method ref, + int typeid: @type ref, + int kttypeid: @kt_type ref +) + +ktProperties( + unique int id: @kt_property, + string nodeName: string ref +) + +ktPropertyGetters( + unique int id: @kt_property ref, + int getter: @method ref +) + +ktPropertySetters( + unique int id: @kt_property ref, + int setter: @method ref +) + +ktPropertyBackingFields( + unique int id: @kt_property ref, + int backingField: @field ref +) + +ktSyntheticBody( + unique int id: @callable ref, + int kind: int ref + // 1: ENUM_VALUES + // 2: ENUM_VALUEOF +) + +ktLocalFunction( + unique int id: @method ref +) + +ktInitializerAssignment( + unique int id: @assignexpr ref +) + +ktPropertyDelegates( + unique int id: @kt_property ref, + unique int variableId: @variable ref +) + +/** + * If `id` is a compiler generated element, then the kind indicates the + * reason that the compiler generated it. + * See `Element.compilerGeneratedReason()` for an explanation of what + * each `kind` means. + */ +compiler_generated( + unique int id: @element ref, + int kind: int ref +) + +ktFunctionOriginalNames( + unique int id: @method ref, + string name: string ref +) + +ktDataClasses( + unique int id: @classorinterface ref +) diff --git a/java/downgrades/7cbc85b1f3ecda39661ad4806dedbd0973d2c4c0/semmlecode.dbscheme b/java/downgrades/7cbc85b1f3ecda39661ad4806dedbd0973d2c4c0/semmlecode.dbscheme new file mode 100644 index 00000000000..934bf10b4bd --- /dev/null +++ b/java/downgrades/7cbc85b1f3ecda39661ad4806dedbd0973d2c4c0/semmlecode.dbscheme @@ -0,0 +1,1242 @@ +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * javac A.java B.java C.java + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * javac A.java B.java C.java + */ + unique int id : @compilation, + int kind: int ref, + string cwd : string ref, + string name : string ref +); + +case @compilation.kind of + 1 = @javacompilation +| 2 = @kotlincompilation +; + +compilation_started( + int id : @compilation ref +) + +compilation_info( + int id : @compilation ref, + string info_key: string ref, + string info_value: string ref +) + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--javac-args` + * 2 | A.java + * 3 | B.java + * 4 | C.java + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | A.java + * 1 | B.java + * 2 | C.java + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * For each file recorded in `compilation_compiling_files`, + * there will be a corresponding row in + * `compilation_compiling_files_completed` once extraction + * of that file is complete. The `result` will indicate the + * extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +#keyset[id, num] +compilation_compiling_files_completed( + int id : @compilation ref, + int num : int ref, + int result : int ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * The `cpu_seconds` and `elapsed_seconds` are the CPU time and elapsed + * time (respectively) that the original compilation (not the extraction) + * took for compiler invocation `id`. + */ +compilation_compiler_times( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + * The `result` will indicate the extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref, + int result : int ref +); + +diagnostics( + unique int id: @diagnostic, + string generated_by: string ref, // TODO: Sync this with the other languages? + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/* + * External artifacts + */ + +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +snapshotDate( + unique date snapshotDate : date ref +); + +sourceLocationPrefix( + string prefix : string ref +); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id : @duplication, + string relativePath : string ref, + int equivClass : int ref +); + +similarCode( + unique int id : @similarity, + string 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 +); + +/* + * SMAP + */ + +smap_header( + int outputFileId: @file ref, + string outputFilename: string ref, + string defaultStratum: string ref +); + +smap_files( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + string inputFileName: string ref, + int inputFileId: @file ref +); + +smap_lines( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + int inputStartLine: int ref, + int inputLineCount: int ref, + int outputStartLine: int ref, + int outputLineIncrement: int ref +); + +/* + * Locations and files + */ + +@location = @location_default ; + +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 +); + +hasLocation( + int locatableid: @locatable ref, + int id: @location ref +); + +@sourceline = @locatable ; + +#keyset[element_id] +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 +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/* + * Java + */ + +cupackage( + unique int id: @file ref, + int packageid: @package ref +); + +#keyset[fileid,keyName] +jarManifestMain( + int fileid: @file ref, + string keyName: string ref, + string value: string ref +); + +#keyset[fileid,entryName,keyName] +jarManifestEntries( + int fileid: @file ref, + string entryName: string ref, + string keyName: string ref, + string value: string ref +); + +packages( + unique int id: @package, + string nodeName: string ref +); + +primitives( + unique int id: @primitive, + string nodeName: string ref +); + +modifiers( + unique int id: @modifier, + string nodeName: string ref +); + +/** + * An errortype is used when the extractor is unable to extract a type + * correctly for some reason. + */ +error_type( + unique int id: @errortype +); + +classes_or_interfaces( + unique int id: @classorinterface, + string nodeName: string ref, + int parentid: @package ref, + int sourceid: @classorinterface ref +); + +file_class( + int id: @classorinterface ref +); + +class_object( + unique int id: @classorinterface ref, + unique int instance: @field ref +); + +type_companion_object( + unique int id: @classorinterface ref, + unique int instance: @field ref, + unique int companion_object: @classorinterface ref +); + +kt_nullable_types( + unique int id: @kt_nullable_type, + int classid: @reftype ref +) + +kt_notnull_types( + unique int id: @kt_notnull_type, + int classid: @reftype ref +) + +kt_type_alias( + unique int id: @kt_type_alias, + string name: string ref, + int kttypeid: @kt_type ref +) + +@kt_type = @kt_nullable_type | @kt_notnull_type + +isInterface( + unique int id: @classorinterface ref +); + +isRecord( + unique int id: @classorinterface ref +); + +fielddecls( + unique int id: @fielddecl, + int parentid: @reftype ref +); + +#keyset[fieldId] #keyset[fieldDeclId,pos] +fieldDeclaredIn( + int fieldId: @field ref, + int fieldDeclId: @fielddecl ref, + int pos: int ref +); + +fields( + unique int id: @field, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @field ref +); + +fieldsKotlinType( + unique int id: @field ref, + int kttypeid: @kt_type ref +); + +constrs( + unique int id: @constructor, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @constructor ref +); + +constrsKotlinType( + unique int id: @constructor ref, + int kttypeid: @kt_type ref +); + +methods( + unique int id: @method, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @method ref +); + +methodsKotlinType( + unique int id: @method ref, + int kttypeid: @kt_type ref +); + +#keyset[parentid,pos] +params( + unique int id: @param, + int typeid: @type ref, + int pos: int ref, + int parentid: @callable ref, + int sourceid: @param ref +); + +paramsKotlinType( + unique int id: @param ref, + int kttypeid: @kt_type ref +); + +paramName( + unique int id: @param ref, + string nodeName: string ref +); + +isVarargsParam( + int param: @param ref +); + +exceptions( + unique int id: @exception, + int typeid: @type ref, + int parentid: @callable ref +); + +isAnnotType( + int interfaceid: @classorinterface ref +); + +isAnnotElem( + int methodid: @method ref +); + +annotValue( + int parentid: @annotation ref, + int id2: @method ref, + unique int value: @expr ref +); + +isEnumType( + int classid: @classorinterface ref +); + +isEnumConst( + int fieldid: @field ref +); + +#keyset[parentid,pos] +typeVars( + unique int id: @typevariable, + string nodeName: string ref, + int pos: int ref, + int kind: int ref, // deprecated + int parentid: @classorinterfaceorcallable ref +); + +wildcards( + unique int id: @wildcard, + string nodeName: string ref, + int kind: int ref +); + +#keyset[parentid,pos] +typeBounds( + unique int id: @typebound, + int typeid: @reftype ref, + int pos: int ref, + int parentid: @boundedtype ref +); + +#keyset[parentid,pos] +typeArgs( + int argumentid: @reftype ref, + int pos: int ref, + int parentid: @classorinterfaceorcallable ref +); + +isParameterized( + int memberid: @member ref +); + +isRaw( + int memberid: @member ref +); + +erasure( + unique int memberid: @member ref, + int erasureid: @member ref +); + +#keyset[classid] #keyset[parent] +isAnonymClass( + int classid: @classorinterface ref, + int parent: @classinstancexpr ref +); + +#keyset[typeid] #keyset[parent] +isLocalClassOrInterface( + int typeid: @classorinterface ref, + int parent: @localtypedeclstmt ref +); + +isDefConstr( + int constructorid: @constructor ref +); + +#keyset[exprId] +lambdaKind( + int exprId: @lambdaexpr ref, + int bodyKind: int ref +); + +arrays( + unique int id: @array, + string nodeName: string ref, + int elementtypeid: @type ref, + int dimension: int ref, + int componenttypeid: @type ref +); + +enclInReftype( + unique int child: @reftype ref, + int parent: @reftype ref +); + +extendsReftype( + int id1: @reftype ref, + int id2: @classorinterface ref +); + +implInterface( + int id1: @classorarray ref, + int id2: @classorinterface ref +); + +permits( + int id1: @classorinterface ref, + int id2: @classorinterface ref +); + +hasModifier( + int id1: @modifiable ref, + int id2: @modifier ref +); + +imports( + unique int id: @import, + int holder: @classorinterfaceorpackage ref, + string name: string ref, + int kind: int ref +); + +#keyset[parent,idx] +stmts( + unique int id: @stmt, + int kind: int ref, + int parent: @stmtparent ref, + int idx: int ref, + int bodydecl: @callable ref +); + +@stmtparent = @callable | @stmt | @switchexpr | @whenexpr| @stmtexpr; + +case @stmt.kind of + 0 = @block +| 1 = @ifstmt +| 2 = @forstmt +| 3 = @enhancedforstmt +| 4 = @whilestmt +| 5 = @dostmt +| 6 = @trystmt +| 7 = @switchstmt +| 8 = @synchronizedstmt +| 9 = @returnstmt +| 10 = @throwstmt +| 11 = @breakstmt +| 12 = @continuestmt +| 13 = @emptystmt +| 14 = @exprstmt +| 15 = @labeledstmt +| 16 = @assertstmt +| 17 = @localvariabledeclstmt +| 18 = @localtypedeclstmt +| 19 = @constructorinvocationstmt +| 20 = @superconstructorinvocationstmt +| 21 = @case +| 22 = @catchclause +| 23 = @yieldstmt +| 24 = @errorstmt +| 25 = @whenbranch +; + +#keyset[parent,idx] +exprs( + unique int id: @expr, + int kind: int ref, + int typeid: @type ref, + int parent: @exprparent ref, + int idx: int ref +); + +exprsKotlinType( + unique int id: @expr ref, + int kttypeid: @kt_type ref +); + +callableEnclosingExpr( + unique int id: @expr ref, + int callable_id: @callable ref +); + +statementEnclosingExpr( + unique int id: @expr ref, + int statement_id: @stmt ref +); + +isParenthesized( + unique int id: @expr ref, + int parentheses: int ref +); + +case @expr.kind of + 1 = @arrayaccess +| 2 = @arraycreationexpr +| 3 = @arrayinit +| 4 = @assignexpr +| 5 = @assignaddexpr +| 6 = @assignsubexpr +| 7 = @assignmulexpr +| 8 = @assigndivexpr +| 9 = @assignremexpr +| 10 = @assignandexpr +| 11 = @assignorexpr +| 12 = @assignxorexpr +| 13 = @assignlshiftexpr +| 14 = @assignrshiftexpr +| 15 = @assignurshiftexpr +| 16 = @booleanliteral +| 17 = @integerliteral +| 18 = @longliteral +| 19 = @floatingpointliteral +| 20 = @doubleliteral +| 21 = @characterliteral +| 22 = @stringliteral +| 23 = @nullliteral +| 24 = @mulexpr +| 25 = @divexpr +| 26 = @remexpr +| 27 = @addexpr +| 28 = @subexpr +| 29 = @lshiftexpr +| 30 = @rshiftexpr +| 31 = @urshiftexpr +| 32 = @andbitexpr +| 33 = @orbitexpr +| 34 = @xorbitexpr +| 35 = @andlogicalexpr +| 36 = @orlogicalexpr +| 37 = @ltexpr +| 38 = @gtexpr +| 39 = @leexpr +| 40 = @geexpr +| 41 = @eqexpr +| 42 = @neexpr +| 43 = @postincexpr +| 44 = @postdecexpr +| 45 = @preincexpr +| 46 = @predecexpr +| 47 = @minusexpr +| 48 = @plusexpr +| 49 = @bitnotexpr +| 50 = @lognotexpr +| 51 = @castexpr +| 52 = @newexpr +| 53 = @conditionalexpr +| 54 = @parexpr // deprecated +| 55 = @instanceofexpr +| 56 = @localvariabledeclexpr +| 57 = @typeliteral +| 58 = @thisaccess +| 59 = @superaccess +| 60 = @varaccess +| 61 = @methodaccess +| 62 = @unannotatedtypeaccess +| 63 = @arraytypeaccess +| 64 = @packageaccess +| 65 = @wildcardtypeaccess +| 66 = @declannotation +| 67 = @uniontypeaccess +| 68 = @lambdaexpr +| 69 = @memberref +| 70 = @annotatedtypeaccess +| 71 = @typeannotation +| 72 = @intersectiontypeaccess +| 73 = @switchexpr +| 74 = @errorexpr +| 75 = @whenexpr +| 76 = @getclassexpr +| 77 = @safecastexpr +| 78 = @implicitcastexpr +| 79 = @implicitnotnullexpr +| 80 = @implicitcoerciontounitexpr +| 81 = @notinstanceofexpr +| 82 = @stmtexpr +| 83 = @stringtemplateexpr +| 84 = @notnullexpr +| 85 = @unsafecoerceexpr +| 86 = @valueeqexpr +| 87 = @valueneexpr +| 88 = @propertyref +; + +/** Holds if this `when` expression was written as an `if` expression. */ +when_if(unique int id: @whenexpr ref); + +/** Holds if this `when` branch was written as an `else` branch. */ +when_branch_else(unique int id: @whenbranch ref); + +@classinstancexpr = @newexpr | @lambdaexpr | @memberref | @propertyref + +@annotation = @declannotation | @typeannotation +@typeaccess = @unannotatedtypeaccess | @annotatedtypeaccess + +@assignment = @assignexpr + | @assignop; + +@unaryassignment = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr; + +@assignop = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + | @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignurshiftexpr; + +@literal = @booleanliteral + | @integerliteral + | @longliteral + | @floatingpointliteral + | @doubleliteral + | @characterliteral + | @stringliteral + | @nullliteral; + +@binaryexpr = @mulexpr + | @divexpr + | @remexpr + | @addexpr + | @subexpr + | @lshiftexpr + | @rshiftexpr + | @urshiftexpr + | @andbitexpr + | @orbitexpr + | @xorbitexpr + | @andlogicalexpr + | @orlogicalexpr + | @ltexpr + | @gtexpr + | @leexpr + | @geexpr + | @eqexpr + | @neexpr + | @valueeqexpr + | @valueneexpr; + +@unaryexpr = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr + | @minusexpr + | @plusexpr + | @bitnotexpr + | @lognotexpr + | @notnullexpr; + +@caller = @classinstancexpr + | @methodaccess + | @constructorinvocationstmt + | @superconstructorinvocationstmt; + +callableBinding( + unique int callerid: @caller ref, + int callee: @callable ref +); + +memberRefBinding( + unique int id: @expr ref, + int callable: @callable ref +); + +propertyRefGetBinding( + unique int id: @expr ref, + int getter: @callable ref +); + +propertyRefFieldBinding( + unique int id: @expr ref, + int field: @field ref +); + +propertyRefSetBinding( + unique int id: @expr ref, + int setter: @callable ref +); + +@exprparent = @stmt | @expr | @whenbranch | @callable | @field | @fielddecl | @classorinterface | @param | @localvar | @typevariable; + +variableBinding( + unique int expr: @varaccess ref, + int variable: @variable ref +); + +@variable = @localscopevariable | @field; + +@localscopevariable = @localvar | @param; + +localvars( + unique int id: @localvar, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @localvariabledeclexpr ref +); + +localvarsKotlinType( + unique int id: @localvar ref, + int kttypeid: @kt_type ref +); + +@namedexprorstmt = @breakstmt + | @continuestmt + | @labeledstmt + | @literal; + +namestrings( + string name: string ref, + string value: string ref, + unique int parent: @namedexprorstmt ref +); + +/* + * Modules + */ + +#keyset[name] +modules( + unique int id: @module, + string name: string ref +); + +isOpen( + int id: @module ref +); + +#keyset[fileId] +cumodule( + int fileId: @file ref, + int moduleId: @module ref +); + +@directive = @requires + | @exports + | @opens + | @uses + | @provides + +#keyset[directive] +directives( + int id: @module ref, + int directive: @directive ref +); + +requires( + unique int id: @requires, + int target: @module ref +); + +isTransitive( + int id: @requires ref +); + +isStatic( + int id: @requires ref +); + +exports( + unique int id: @exports, + int target: @package ref +); + +exportsTo( + int id: @exports ref, + int target: @module ref +); + +opens( + unique int id: @opens, + int target: @package ref +); + +opensTo( + int id: @opens ref, + int target: @module ref +); + +uses( + unique int id: @uses, + string serviceInterface: string ref +); + +provides( + unique int id: @provides, + string serviceInterface: string ref +); + +providesWith( + int id: @provides ref, + string serviceImpl: string ref +); + +/* + * Javadoc + */ + +javadoc( + unique int id: @javadoc +); + +isNormalComment( + int commentid : @javadoc ref +); + +isEolComment( + int commentid : @javadoc ref +); + +hasJavadoc( + int documentableid: @member ref, + int javadocid: @javadoc ref +); + +#keyset[parentid,idx] +javadocTag( + unique int id: @javadocTag, + string name: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +#keyset[parentid,idx] +javadocText( + unique int id: @javadocText, + string text: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +@javadocParent = @javadoc | @javadocTag; +@javadocElement = @javadocTag | @javadocText; + +@classorinterfaceorpackage = @classorinterface | @package; +@classorinterfaceorcallable = @classorinterface | @callable; +@boundedtype = @typevariable | @wildcard; +@reftype = @classorinterface | @array | @boundedtype | @errortype; +@classorarray = @classorinterface | @array; +@type = @primitive | @reftype; +@callable = @method | @constructor; + +/** A program element that has a name. */ +@element = @package | @modifier | @annotation | @errortype | + @locatableElement; + +@locatableElement = @file | @primitive | @classorinterface | @method | @constructor | @param | @exception | @field | + @boundedtype | @array | @localvar | @expr | @stmt | @import | @fielddecl | @kt_type | @kt_type_alias | + @kt_property; + +@modifiable = @member_modifiable| @param | @localvar | @typevariable; + +@member_modifiable = @classorinterface | @method | @constructor | @field | @kt_property; + +@member = @method | @constructor | @field | @reftype ; + +/** A program element that has a location. */ +@locatable = @typebound | @javadoc | @javadocTag | @javadocText | @xmllocatable | @ktcomment | + @locatableElement; + +@top = @element | @locatable | @folder; + +/* + * 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; + +/* + * configuration files with key value pairs + */ + +configs( + unique int id: @config +); + +configNames( + unique int id: @configName, + int config: @config ref, + string name: string ref +); + +configValues( + unique int id: @configValue, + int config: @config ref, + string value: string ref +); + +configLocations( + int locatable: @configLocatable ref, + int location: @location_default ref +); + +@configLocatable = @config | @configName | @configValue; + +ktComments( + unique int id: @ktcomment, + int kind: int ref, + string text : string ref +) + +ktCommentSections( + unique int id: @ktcommentsection, + int comment: @ktcomment ref, + string content : string ref +) + +ktCommentSectionNames( + unique int id: @ktcommentsection ref, + string name : string ref +) + +ktCommentSectionSubjectNames( + unique int id: @ktcommentsection ref, + string subjectname : string ref +) + +#keyset[id, owner] +ktCommentOwners( + int id: @ktcomment ref, + int owner: @top ref +) + +ktExtensionFunctions( + unique int id: @method ref, + int typeid: @type ref, + int kttypeid: @kt_type ref +) + +ktProperties( + unique int id: @kt_property, + string nodeName: string ref +) + +ktPropertyGetters( + unique int id: @kt_property ref, + int getter: @method ref +) + +ktPropertySetters( + unique int id: @kt_property ref, + int setter: @method ref +) + +ktPropertyBackingFields( + unique int id: @kt_property ref, + int backingField: @field ref +) + +ktSyntheticBody( + unique int id: @callable ref, + int kind: int ref + // 1: ENUM_VALUES + // 2: ENUM_VALUEOF +) + +ktLocalFunction( + unique int id: @method ref +) + +ktInitializerAssignment( + unique int id: @assignexpr ref +) + +ktPropertyDelegates( + unique int id: @kt_property ref, + unique int variableId: @variable ref +) + +/** + * If `id` is a compiler generated element, then the kind indicates the + * reason that the compiler generated it. + * See `Element.compilerGeneratedReason()` for an explanation of what + * each `kind` means. + */ +compiler_generated( + unique int id: @element ref, + int kind: int ref +) + +ktFunctionOriginalNames( + unique int id: @method ref, + string name: string ref +) + +ktDataClasses( + unique int id: @classorinterface ref +) diff --git a/java/downgrades/7cbc85b1f3ecda39661ad4806dedbd0973d2c4c0/upgrade.properties b/java/downgrades/7cbc85b1f3ecda39661ad4806dedbd0973d2c4c0/upgrade.properties new file mode 100644 index 00000000000..0e9d417b1ee --- /dev/null +++ b/java/downgrades/7cbc85b1f3ecda39661ad4806dedbd0973d2c4c0/upgrade.properties @@ -0,0 +1,3 @@ +description: Remove compilation_expanded_args +compatibility: full +compilation_expanded_args.rel: delete diff --git a/java/ql/lib/change-notes/2023-03-22-expanded-args.md b/java/ql/lib/change-notes/2023-03-22-expanded-args.md new file mode 100644 index 00000000000..9d5fe32e6b8 --- /dev/null +++ b/java/ql/lib/change-notes/2023-03-22-expanded-args.md @@ -0,0 +1,4 @@ +--- +category: feature +--- +* Predicates `Compilation.getExpandedArgument` and `Compilation.getAnExpandedArgument` has been added. diff --git a/java/ql/lib/change-notes/2023-03-29-moved-configurations-for-queries.md b/java/ql/lib/change-notes/2023-03-29-moved-configurations-for-queries.md new file mode 100644 index 00000000000..e562d714894 --- /dev/null +++ b/java/ql/lib/change-notes/2023-03-29-moved-configurations-for-queries.md @@ -0,0 +1,10 @@ +--- +category: minorAnalysis +--- +* Added the `TaintedPathQuery.qll` library to provide the `TaintedPathFlow` and `TaintedPathLocalFlow` taint-tracking modules to reason about tainted path vulnerabilities. +* Added the `ZipSlipQuery.qll` library to provide the `ZipSlipFlow` taint-tracking module to reason about zip-slip vulnerabilities. +* Added the `InsecureBeanValidationQuery.qll` library to provide the `BeanValidationFlow` taint-tracking module to reason about bean validation vulnerabilities. +* Added the `XssQuery.qll` library to provide the `XssFlow` taint-tracking module to reason about cross site scripting vulnerabilities. +* Added the `LdapInjectionQuery.qll` library to provide the `LdapInjectionFlow` taint-tracking module to reason about LDAP injection vulnerabilities. +* Added the `ResponseSplittingQuery.qll` library to provide the `ResponseSplittingFlow` taint-tracking module to reason about response splitting vulnerabilities. +* Added the `ExternallyControlledFormatStringQuery.qll` library to provide the `ExternallyControlledFormatStringFlow` taint-tracking module to reason about externally controlled format string vulnerabilities. \ No newline at end of file diff --git a/java/ql/lib/change-notes/2023-03-31-compilation-names.md b/java/ql/lib/change-notes/2023-03-31-compilation-names.md new file mode 100644 index 00000000000..c581a585199 --- /dev/null +++ b/java/ql/lib/change-notes/2023-03-31-compilation-names.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The filenames embedded in `Compilation.toString()` now use `/` as the path separator on all platforms. diff --git a/java/ql/lib/config/semmlecode.dbscheme b/java/ql/lib/config/semmlecode.dbscheme index 934bf10b4bd..7cbc85b1f3e 100644 --- a/java/ql/lib/config/semmlecode.dbscheme +++ b/java/ql/lib/config/semmlecode.dbscheme @@ -60,6 +60,19 @@ compilation_args( string arg : string ref ); +/** + * The expanded arguments that were passed to the extractor for a + * compiler invocation. This is similar to `compilation_args`, but + * for a `@@@someFile` argument, it includes the arguments from that + * file, rather than just taking the argument literally. + */ +#keyset[id, num] +compilation_expanded_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + /** * The source files that are compiled by a compiler invocation. * If `id` is for the compiler invocation diff --git a/java/ql/lib/config/semmlecode.dbscheme.stats b/java/ql/lib/config/semmlecode.dbscheme.stats index 05a477fec73..f069e1773d8 100644 --- a/java/ql/lib/config/semmlecode.dbscheme.stats +++ b/java/ql/lib/config/semmlecode.dbscheme.stats @@ -2,7 +2,7 @@ @javacompilation - 8628 + 1138 @kotlincompilation @@ -10,7 +10,7 @@ @diagnostic - 64190 + 57106 @externalDataElement @@ -30,11 +30,11 @@ @folder - 293711 + 211876 @package - 121135 + 96053 @primitive @@ -56,6 +56,10 @@ @kt_nullable_type 262 + + @location_default + 82315299 + @kt_notnull_type 156265 @@ -68,10 +72,6 @@ @fielddecl 210035 - - @location_default - 82315299 - @field 2886451 @@ -110,7 +110,7 @@ @import - 441072 + 356137 @block @@ -118,7 +118,7 @@ @ifstmt - 188285 + 188282 @forstmt @@ -126,7 +126,7 @@ @enhancedforstmt - 23697 + 21607 @whilestmt @@ -150,7 +150,7 @@ @returnstmt - 345813 + 345793 @throwstmt @@ -174,7 +174,7 @@ @assertstmt - 15159 + 15158 @localvariabledeclstmt @@ -182,7 +182,7 @@ @localtypedeclstmt - 3533 + 3532 @constructorinvocationstmt @@ -194,7 +194,7 @@ @case - 107945 + 107927 @catchclause @@ -214,11 +214,11 @@ @whenbranch - 207293 + 207292 @arrayaccess - 409681 + 409677 @arraycreationexpr @@ -250,7 +250,7 @@ @assignandexpr - 3971 + 3970 @assignorexpr @@ -258,19 +258,19 @@ @booleanliteral - 589912 + 524468 @integerliteral - 1151458 + 1151446 @longliteral - 185904 + 185873 @floatingpointliteral - 2824996 + 2824967 @doubleliteral @@ -282,7 +282,7 @@ @stringliteral - 1262818 + 1262851 @nullliteral @@ -318,7 +318,7 @@ @urshiftexpr - 9644 + 9643 @andbitexpr @@ -358,7 +358,7 @@ @eqexpr - 104275 + 104273 @neexpr @@ -366,7 +366,7 @@ @postincexpr - 41859 + 41857 @postdecexpr @@ -382,7 +382,7 @@ @minusexpr - 744386 + 744379 @plusexpr @@ -394,11 +394,11 @@ @lognotexpr - 40111 + 40110 @castexpr - 93187 + 93185 @newexpr @@ -426,7 +426,7 @@ @superaccess - 53024 + 53021 @varaccess @@ -434,7 +434,7 @@ @methodaccess - 1512385 + 1512380 @unannotatedtypeaccess @@ -446,7 +446,7 @@ @wildcardtypeaccess - 74889 + 78834 @declannotation @@ -510,7 +510,7 @@ @errorexpr - 1 + 4 @whenexpr @@ -526,7 +526,7 @@ @implicitcastexpr - 28818 + 28817 @implicitnotnullexpr @@ -542,7 +542,7 @@ @stmtexpr - 50553 + 50550 @stringtemplateexpr @@ -566,7 +566,7 @@ @propertyref - 8440 + 8439 @localvar @@ -574,7 +574,7 @@ @module - 7965 + 6092 @requires @@ -582,19 +582,19 @@ @exports - 35013 + 26163 @opens - 165 + 716 @uses - 10786 + 7884 @provides - 2323 + 1792 @javadoc @@ -646,11 +646,11 @@ @ktcomment - 74439 + 116780 @ktcommentsection - 47690 + 74919 @kt_property @@ -660,23 +660,23 @@ compilations - 8628 + 2356 id - 8628 + 2356 kind - 165 + 94 cwd - 165 + 94 name - 8628 + 2356 @@ -690,7 +690,7 @@ 1 2 - 8628 + 2356 @@ -706,7 +706,7 @@ 1 2 - 8628 + 2356 @@ -722,7 +722,7 @@ 1 2 - 8628 + 2356 @@ -736,9 +736,9 @@ 12 - 52 - 53 - 165 + 25 + 26 + 94 @@ -754,7 +754,7 @@ 1 2 - 165 + 94 @@ -768,9 +768,9 @@ 12 - 52 - 53 - 165 + 25 + 26 + 94 @@ -784,9 +784,9 @@ 12 - 52 - 53 - 165 + 25 + 26 + 94 @@ -802,7 +802,7 @@ 1 2 - 165 + 94 @@ -816,9 +816,9 @@ 12 - 52 - 53 - 165 + 25 + 26 + 94 @@ -834,7 +834,7 @@ 1 2 - 8628 + 2356 @@ -850,7 +850,7 @@ 1 2 - 8628 + 2356 @@ -866,7 +866,7 @@ 1 2 - 8628 + 2356 @@ -1248,20 +1248,166 @@ - compilation_compiling_files - 62421 + compilation_expanded_args + 69428 id - 731 + 1138 num - 9199 + 45527 + + + arg + 54632 + + + + + id + num + + + 12 + + + 42 + 43 + 569 + + + 80 + 81 + 569 + + + + + + + id + arg + + + 12 + + + 40 + 41 + 569 + + + 78 + 79 + 569 + + + + + + + num + id + + + 12 + + + 1 + 2 + 21625 + + + 2 + 3 + 23901 + + + + + + + num + arg + + + 12 + + + 1 + 2 + 35283 + + + 2 + 3 + 10243 + + + + + + + arg + id + + + 12 + + + 1 + 2 + 42112 + + + 2 + 3 + 12519 + + + + + + + arg + num + + + 12 + + + 1 + 2 + 53494 + + + 2 + 3 + 1138 + + + + + + + + + compilation_compiling_files + 60809 + + + id + 757 + + + num + 9485 file - 62421 + 60809 @@ -1275,67 +1421,62 @@ 1 2 - 59 + 104 2 - 6 - 59 + 4 + 56 - 6 - 10 - 59 + 4 + 7 + 60 - 10 - 14 - 59 + 7 + 11 + 69 - 14 - 20 - 59 + 11 + 15 + 56 - 20 - 27 - 67 + 15 + 22 + 60 - 27 - 35 - 59 + 22 + 31 + 65 - 36 + 32 47 - 59 + 65 51 - 70 - 59 + 88 + 69 - 72 - 123 - 59 + 93 + 151 + 60 - 124 - 176 - 59 + 163 + 367 + 60 - 208 - 1130 - 59 - - - 1233 - 1234 - 7 + 441 + 2179 + 26 @@ -1351,67 +1492,62 @@ 1 2 - 59 + 104 2 - 6 - 59 + 4 + 56 - 6 - 10 - 59 + 4 + 7 + 60 - 10 - 14 - 59 + 7 + 11 + 69 - 14 - 20 - 59 + 11 + 15 + 56 - 20 - 27 - 67 + 15 + 22 + 60 - 27 - 35 - 59 + 22 + 31 + 65 - 36 + 32 47 - 59 + 65 51 - 70 - 59 + 88 + 69 - 72 - 123 - 59 + 93 + 151 + 60 - 124 - 176 - 59 + 163 + 367 + 60 - 208 - 1130 - 59 - - - 1233 - 1234 - 7 + 441 + 2179 + 26 @@ -1427,42 +1563,37 @@ 1 2 - 775 + 4080 2 3 - 4342 + 452 3 - 5 - 790 + 4 + 2552 - 5 - 6 - 880 + 4 + 7 + 805 - 6 - 8 - 686 + 7 + 17 + 827 - 8 - 16 - 768 + 17 + 104 + 714 - 16 - 42 - 701 - - - 42 - 99 - 253 + 105 + 175 + 52 @@ -1478,42 +1609,37 @@ 1 2 - 775 + 4080 2 3 - 4342 + 452 3 - 5 - 790 + 4 + 2552 - 5 - 6 - 880 + 4 + 7 + 805 - 6 - 8 - 686 + 7 + 17 + 827 - 8 - 16 - 768 + 17 + 104 + 714 - 16 - 42 - 701 - - - 42 - 99 - 253 + 105 + 175 + 52 @@ -1529,7 +1655,7 @@ 1 2 - 62421 + 60809 @@ -1545,7 +1671,7 @@ 1 2 - 62421 + 60809 @@ -1555,19 +1681,19 @@ compilation_compiling_files_completed - 62421 + 60809 id - 731 + 757 num - 9199 + 9485 result - 7 + 4 @@ -1581,67 +1707,62 @@ 1 2 - 59 + 104 2 - 6 - 59 + 4 + 56 - 6 - 10 - 59 + 4 + 7 + 60 - 10 - 14 - 59 + 7 + 11 + 69 - 14 - 20 - 59 + 11 + 15 + 56 - 20 - 27 - 67 + 15 + 22 + 60 - 27 - 35 - 59 + 22 + 31 + 65 - 36 + 32 47 - 59 + 65 51 - 70 - 59 + 88 + 69 - 72 - 123 - 59 + 93 + 151 + 60 - 124 - 176 - 59 + 163 + 367 + 60 - 208 - 1130 - 59 - - - 1233 - 1234 - 7 + 441 + 2179 + 26 @@ -1657,7 +1778,7 @@ 1 2 - 731 + 757 @@ -1673,42 +1794,37 @@ 1 2 - 775 + 4080 2 3 - 4342 + 452 3 - 5 - 790 + 4 + 2552 - 5 - 6 - 880 + 4 + 7 + 805 - 6 - 8 - 686 + 7 + 17 + 827 - 8 - 16 - 768 + 17 + 104 + 714 - 16 - 42 - 701 - - - 42 - 99 - 253 + 105 + 175 + 52 @@ -1724,7 +1840,7 @@ 1 2 - 9199 + 9485 @@ -1738,9 +1854,9 @@ 12 - 98 - 99 - 7 + 174 + 175 + 4 @@ -1754,9 +1870,9 @@ 12 - 1233 - 1234 - 7 + 2178 + 2179 + 4 @@ -1766,23 +1882,23 @@ compilation_time - 252612 + 166778 id - 731 + 238 num - 9207 + 30464 kind - 29 + 477 seconds - 123672 + 83269 @@ -1794,161 +1910,51 @@ 12 - 2 - 3 - 59 - - - 3 - 7 - 59 - - - 7 - 11 - 59 - - - 11 - 15 - 59 - - - 15 - 21 - 59 - - - 21 - 28 - 67 - - - 28 - 36 - 59 - - - 37 - 48 - 59 - - - 52 - 71 - 59 - - - 73 - 124 - 59 - - - 125 - 177 - 59 - - - 209 - 1131 - 59 - - - 1234 - 1235 - 7 - - - - - - - id - kind - - - 12 - - - 4 - 5 - 731 - - - - - - - id - seconds - - - 12 - - - 4 - 5 - 59 - - - 6 - 13 - 59 - - - 14 - 21 - 59 - - - 22 - 29 - 59 - - - 30 - 41 - 59 - - - 42 - 55 - 67 - - - 56 - 71 - 59 - - - 74 + 94 95 - 59 + 119 - 104 - 141 - 59 + 255 + 256 + 119 + + + + + + + id + kind + + + 12 + + + 4 + 5 + 238 + + + + + + + id + seconds + + + 12 + + + 188 + 189 + 119 - 146 - 247 - 59 - - - 250 - 353 - 59 - - - 418 - 2247 - 59 - - - 2436 - 2437 - 7 + 510 + 511 + 119 @@ -1964,42 +1970,12 @@ 1 2 - 775 + 19234 2 3 - 4342 - - - 3 - 5 - 790 - - - 5 - 6 - 880 - - - 6 - 8 - 686 - - - 8 - 16 - 768 - - - 16 - 42 - 701 - - - 42 - 99 - 261 + 11230 @@ -2015,7 +1991,7 @@ 4 5 - 9207 + 30464 @@ -2031,42 +2007,12 @@ 3 4 - 775 + 19353 5 6 - 4342 - - - 7 - 10 - 790 - - - 11 - 12 - 880 - - - 13 - 16 - 686 - - - 17 - 32 - 768 - - - 33 - 84 - 701 - - - 85 - 198 - 261 + 11110 @@ -2080,9 +2026,9 @@ 12 - 98 - 99 - 29 + 2 + 3 + 477 @@ -2096,9 +2042,9 @@ 12 - 1234 - 1235 - 29 + 255 + 256 + 477 @@ -2114,17 +2060,17 @@ 1 2 - 14 + 238 - 8222 - 8223 - 7 + 348 + 349 + 119 - 8364 - 8365 - 7 + 349 + 350 + 119 @@ -2140,12 +2086,12 @@ 1 2 - 122389 + 83150 2 - 99 - 1283 + 3 + 119 @@ -2161,12 +2107,12 @@ 1 2 - 121889 + 83150 - 2 - 1235 - 1783 + 255 + 256 + 119 @@ -2182,12 +2128,12 @@ 1 2 - 123582 + 83150 - 2 + 3 4 - 89 + 119 @@ -2197,23 +2143,23 @@ diagnostic_for - 64190 + 57106 diagnostic - 64190 + 57106 compilation - 716 + 374 file_number - 7 + 6678 file_number_diagnostic_number - 14475 + 1248 @@ -2227,7 +2173,7 @@ 1 2 - 64190 + 57106 @@ -2243,7 +2189,7 @@ 1 2 - 64190 + 57106 @@ -2259,7 +2205,7 @@ 1 2 - 64190 + 57106 @@ -2275,47 +2221,27 @@ 1 2 - 268 + 124 - 3 - 5 - 59 + 34 + 35 + 62 - 5 - 8 - 52 + 266 + 267 + 62 - 8 - 14 - 44 + 303 + 304 + 62 - 14 - 22 - 59 - - - 22 - 39 - 59 - - - 42 - 55 - 59 - - - 60 - 169 - 59 - - - 228 - 1941 - 52 + 310 + 311 + 62 @@ -2331,7 +2257,22 @@ 1 2 - 716 + 124 + + + 14 + 15 + 62 + + + 102 + 103 + 124 + + + 104 + 105 + 62 @@ -2347,47 +2288,22 @@ 1 2 - 268 - - - 3 - 5 - 59 - - - 5 - 8 - 52 + 124 8 - 14 - 44 + 9 + 62 - 14 - 22 - 59 + 15 + 16 + 62 - 22 - 39 - 59 - - - 42 - 55 - 59 - - - 60 - 169 - 59 - - - 228 - 1941 - 52 + 20 + 21 + 124 @@ -2401,9 +2317,44 @@ 12 - 8603 - 8604 - 7 + 1 + 5 + 312 + + + 6 + 7 + 3682 + + + 7 + 8 + 312 + + + 8 + 9 + 686 + + + 9 + 12 + 499 + + + 12 + 15 + 561 + + + 17 + 30 + 561 + + + 47 + 48 + 62 @@ -2417,9 +2368,19 @@ 12 - 96 - 97 - 7 + 1 + 3 + 436 + + + 3 + 4 + 5367 + + + 4 + 5 + 873 @@ -2433,9 +2394,39 @@ 12 - 1940 - 1941 - 7 + 1 + 2 + 124 + + + 2 + 3 + 3994 + + + 3 + 4 + 873 + + + 4 + 5 + 312 + + + 5 + 6 + 436 + + + 6 + 8 + 499 + + + 8 + 21 + 436 @@ -2448,45 +2439,70 @@ 12 - - 1 - 2 - 3290 - 2 3 - 238 + 312 3 4 - 5081 - - - 4 - 5 - 2439 + 124 5 6 - 261 - - - 6 - 7 - 1462 + 124 7 - 14 - 1208 + 8 + 124 - 14 - 97 - 492 + 9 + 10 + 62 + + + 12 + 13 + 62 + + + 21 + 22 + 62 + + + 25 + 26 + 62 + + + 39 + 40 + 62 + + + 47 + 48 + 62 + + + 77 + 78 + 62 + + + 321 + 322 + 62 + + + 324 + 325 + 62 @@ -2499,45 +2515,25 @@ 12 - - 1 - 2 - 3290 - 2 3 - 238 + 312 3 4 - 5081 + 436 4 5 - 2439 - - - 5 - 6 - 261 + 436 6 7 - 1462 - - - 7 - 14 - 1208 - - - 14 - 97 - 492 + 62 @@ -2553,7 +2549,67 @@ 1 2 - 14475 + 312 + + + 2 + 3 + 124 + + + 3 + 4 + 124 + + + 4 + 5 + 124 + + + 5 + 6 + 62 + + + 7 + 8 + 62 + + + 12 + 13 + 62 + + + 15 + 16 + 62 + + + 22 + 23 + 62 + + + 27 + 28 + 62 + + + 41 + 42 + 62 + + + 105 + 106 + 62 + + + 107 + 108 + 62 @@ -2684,23 +2740,23 @@ compilation_finished - 8628 + 2261 id - 8628 + 2261 cpu_seconds - 165 + 94 elapsed_seconds - 8628 + 2261 result - 165 + 94 @@ -2714,7 +2770,7 @@ 1 2 - 8628 + 2261 @@ -2730,7 +2786,7 @@ 1 2 - 8628 + 2261 @@ -2746,7 +2802,7 @@ 1 2 - 8628 + 2261 @@ -2760,9 +2816,9 @@ 12 - 52 - 53 - 165 + 24 + 25 + 94 @@ -2776,9 +2832,9 @@ 12 - 52 - 53 - 165 + 24 + 25 + 94 @@ -2794,7 +2850,7 @@ 1 2 - 165 + 94 @@ -2810,7 +2866,7 @@ 1 2 - 8628 + 2261 @@ -2826,7 +2882,7 @@ 1 2 - 8628 + 2261 @@ -2842,7 +2898,7 @@ 1 2 - 8628 + 2261 @@ -2856,9 +2912,9 @@ 12 - 52 - 53 - 165 + 24 + 25 + 94 @@ -2874,7 +2930,7 @@ 1 2 - 165 + 94 @@ -2888,9 +2944,9 @@ 12 - 52 - 53 - 165 + 24 + 25 + 94 @@ -2900,35 +2956,35 @@ diagnostics - 64190 + 57106 id - 64190 + 57106 generated_by - 7 + 124 severity - 29 + 62 error_tag - 7 + 62 error_message - 2604 + 1435 full_error_message - 7 + 39319 location - 7 + 312 @@ -2942,7 +2998,7 @@ 1 2 - 64190 + 57106 @@ -2958,7 +3014,7 @@ 1 2 - 64190 + 57106 @@ -2974,7 +3030,7 @@ 1 2 - 64190 + 57106 @@ -2990,7 +3046,7 @@ 1 2 - 64190 + 57106 @@ -3006,7 +3062,7 @@ 1 2 - 64190 + 57106 @@ -3022,7 +3078,7 @@ 1 2 - 64190 + 57106 @@ -3036,9 +3092,14 @@ 12 - 8603 - 8604 - 7 + 2 + 3 + 62 + + + 913 + 914 + 62 @@ -3052,9 +3113,9 @@ 12 - 4 - 5 - 7 + 1 + 2 + 124 @@ -3070,7 +3131,7 @@ 1 2 - 7 + 124 @@ -3084,9 +3145,14 @@ 12 - 349 - 350 - 7 + 2 + 3 + 62 + + + 21 + 22 + 62 @@ -3102,7 +3168,12 @@ 1 2 - 7 + 62 + + + 629 + 630 + 62 @@ -3118,7 +3189,12 @@ 1 2 - 7 + 62 + + + 4 + 5 + 62 @@ -3132,24 +3208,9 @@ 12 - 4 - 5 - 7 - - - 13 - 14 - 7 - - - 95 - 96 - 7 - - - 8491 - 8492 - 7 + 915 + 916 + 62 @@ -3163,9 +3224,9 @@ 12 - 1 - 2 - 29 + 2 + 3 + 62 @@ -3181,7 +3242,7 @@ 1 2 - 29 + 62 @@ -3195,24 +3256,9 @@ 12 - 4 - 5 - 7 - - - 13 - 14 - 7 - - - 95 - 96 - 7 - - - 237 - 238 - 7 + 23 + 24 + 62 @@ -3226,9 +3272,9 @@ 12 - 1 - 2 - 29 + 630 + 631 + 62 @@ -3242,9 +3288,9 @@ 12 - 1 - 2 - 29 + 5 + 6 + 62 @@ -3258,9 +3304,9 @@ 12 - 8603 - 8604 - 7 + 915 + 916 + 62 @@ -3274,9 +3320,9 @@ 12 - 1 - 2 - 7 + 2 + 3 + 62 @@ -3290,9 +3336,9 @@ 12 - 4 - 5 - 7 + 1 + 2 + 62 @@ -3306,9 +3352,9 @@ 12 - 349 - 350 - 7 + 23 + 24 + 62 @@ -3322,9 +3368,9 @@ 12 - 1 - 2 - 7 + 630 + 631 + 62 @@ -3338,9 +3384,9 @@ 12 - 1 - 2 - 7 + 5 + 6 + 62 @@ -3356,81 +3402,151 @@ 1 2 - 2290 + 312 2 - 9 - 201 + 3 + 249 + + + 4 + 7 + 124 + + + 7 + 10 + 124 + + + 13 + 16 + 124 + + + 19 + 23 + 124 + + + 25 + 27 + 124 + + + 48 + 81 + 124 + + + 314 + 315 + 124 + + + + + + + error_message + generated_by + + + 12 + + + 1 + 2 + 1435 + + + + + + + error_message + severity + + + 12 + + + 1 + 2 + 1435 + + + + + + + error_message + error_tag + + + 12 + + + 1 + 2 + 1435 + + + + + + + error_message + full_error_message + + + 12 + + + 1 + 2 + 312 + + + 2 + 3 + 249 + + + 4 + 6 + 124 + + + 6 + 8 + 124 9 - 3692 - 111 + 16 + 124 - - - - - - error_message - generated_by - - - 12 - - 1 - 2 - 2604 + 19 + 23 + 124 - - - - - - error_message - severity - - - 12 - - 1 - 2 - 2604 + 25 + 27 + 124 - - - - - - error_message - error_tag - - - 12 - - 1 - 2 - 2604 + 38 + 49 + 124 - - - - - - error_message - full_error_message - - - 12 - - 1 - 2 - 2604 + 80 + 315 + 124 @@ -3446,7 +3562,12 @@ 1 2 - 2604 + 1373 + + + 3 + 4 + 62 @@ -3460,9 +3581,14 @@ 12 - 8603 - 8604 - 7 + 1 + 2 + 37010 + + + 2 + 37 + 2309 @@ -3478,7 +3604,7 @@ 1 2 - 7 + 39319 @@ -3492,9 +3618,9 @@ 12 - 4 - 5 - 7 + 1 + 2 + 39319 @@ -3510,7 +3636,7 @@ 1 2 - 7 + 39319 @@ -3524,9 +3650,14 @@ 12 - 349 - 350 - 7 + 1 + 2 + 39257 + + + 2 + 3 + 62 @@ -3542,7 +3673,7 @@ 1 2 - 7 + 39319 @@ -3556,9 +3687,29 @@ 12 - 8603 - 8604 - 7 + 2 + 3 + 62 + + + 3 + 4 + 62 + + + 4 + 5 + 62 + + + 6 + 7 + 62 + + + 900 + 901 + 62 @@ -3574,7 +3725,7 @@ 1 2 - 7 + 312 @@ -3588,9 +3739,9 @@ 12 - 4 - 5 - 7 + 1 + 2 + 312 @@ -3606,7 +3757,7 @@ 1 2 - 7 + 312 @@ -3620,9 +3771,19 @@ 12 - 349 - 350 - 7 + 1 + 2 + 187 + + + 2 + 3 + 62 + + + 20 + 21 + 62 @@ -3638,7 +3799,17 @@ 1 2 - 7 + 187 + + + 3 + 4 + 62 + + + 624 + 625 + 62 @@ -7323,15 +7494,15 @@ folders - 293711 + 211876 id - 293711 + 211876 name - 293711 + 211876 @@ -7345,7 +7516,7 @@ 1 2 - 293711 + 211876 @@ -7361,7 +7532,7 @@ 1 2 - 293711 + 211876 @@ -7542,19 +7713,19 @@ jarManifestMain - 172742 + 132371 fileid - 13275 + 8960 keyName - 12611 + 9676 value - 89772 + 67858 @@ -7567,58 +7738,68 @@ 1 - 4 - 995 + 5 + 358 5 6 - 2323 + 1792 6 7 - 2157 + 1075 9 - 13 - 1161 + 10 + 358 13 15 - 1161 + 597 15 - 17 - 829 + 16 + 716 - 17 + 16 18 - 829 + 716 - 19 + 18 21 - 829 + 716 21 - 24 - 1161 + 23 + 477 - 24 + 23 + 26 + 597 + + + 26 27 - 1161 + 358 - 28 - 35 - 663 + 27 + 29 + 716 + + + 29 + 36 + 477 @@ -7633,63 +7814,68 @@ 1 - 4 - 995 + 5 + 358 5 6 - 2489 + 1792 6 7 - 1991 + 1075 8 - 10 - 663 + 11 + 597 - 10 - 12 - 995 - - - 12 + 11 13 - 663 + 597 14 15 - 995 + 597 15 + 16 + 597 + + + 16 17 - 1161 + 358 17 18 - 829 + 716 18 - 20 - 1161 + 19 + 358 + + + 19 + 21 + 716 21 - 24 - 1161 + 23 + 597 - 29 - 30 - 165 + 23 + 29 + 597 @@ -7705,47 +7891,42 @@ 1 2 - 5144 + 4420 2 - 3 - 829 - - - 3 4 - 829 + 716 - 5 - 8 - 995 + 4 + 6 + 597 - 10 - 20 - 995 + 6 + 12 + 836 - 24 - 28 - 829 + 18 + 30 + 836 - 28 - 31 - 995 + 30 + 34 + 716 - 32 - 38 - 995 + 34 + 42 + 836 - 39 - 81 - 995 + 42 + 76 + 716 @@ -7761,42 +7942,42 @@ 1 2 - 5807 + 4898 2 3 - 995 + 597 3 - 5 - 995 + 4 + 716 - 5 - 8 - 995 + 4 + 9 + 836 - 10 - 16 - 1161 + 13 + 18 + 716 - 17 - 26 - 1161 + 18 + 31 + 836 - 27 - 36 - 995 + 32 + 42 + 836 - 37 - 53 - 497 + 51 + 54 + 238 @@ -7812,22 +7993,17 @@ 1 2 - 75999 + 58659 2 - 3 - 4480 + 4 + 5615 - 3 - 6 - 6969 - - - 6 - 81 - 2323 + 4 + 76 + 3584 @@ -7843,17 +8019,17 @@ 1 2 - 75668 + 56269 2 3 - 8794 + 6570 3 - 6 - 5310 + 5 + 5017 @@ -7863,23 +8039,23 @@ jarManifestEntries - 46193 + 30196 fileid - 29 + 61 entryName - 46141 + 30124 keyName - 59 + 27 value - 46171 + 30158 @@ -7893,22 +8069,72 @@ 1 2 - 7 + 4 - 264 - 265 - 7 + 4 + 10 + 3 - 1520 - 1521 - 7 + 10 + 12 + 4 - 4400 - 4401 - 7 + 12 + 31 + 4 + + + 65 + 82 + 4 + + + 123 + 164 + 4 + + + 178 + 240 + 4 + + + 253 + 294 + 4 + + + 307 + 357 + 4 + + + 361 + 395 + 4 + + + 433 + 461 + 4 + + + 591 + 662 + 4 + + + 957 + 2267 + 4 + + + 3647 + 3762 + 3 @@ -7924,12 +8150,12 @@ 1 2 - 22 + 57 - 7 - 8 - 7 + 6 + 10 + 3 @@ -7943,24 +8169,74 @@ 12 - 4 - 5 - 7 + 1 + 2 + 4 - 264 - 265 - 7 + 3 + 8 + 4 - 1520 - 1521 - 7 + 9 + 13 + 4 - 4400 - 4401 - 7 + 24 + 66 + 4 + + + 70 + 124 + 4 + + + 127 + 179 + 4 + + + 195 + 254 + 4 + + + 265 + 308 + 4 + + + 320 + 362 + 4 + + + 381 + 434 + 4 + + + 434 + 592 + 4 + + + 618 + 958 + 4 + + + 1671 + 3648 + 4 + + + 3761 + 3762 + 1 @@ -7976,12 +8252,12 @@ 1 2 - 46133 + 30108 2 - 3 - 7 + 26 + 16 @@ -7997,12 +8273,12 @@ 1 2 - 46133 + 30121 - 7 - 8 - 7 + 6 + 10 + 3 @@ -8018,12 +8294,12 @@ 1 2 - 46126 + 30120 - 2 - 5 - 14 + 3 + 26 + 4 @@ -8039,12 +8315,22 @@ 1 2 - 52 + 21 + + + 2 + 3 + 3 3 4 - 7 + 1 + + + 32 + 33 + 1 @@ -8060,12 +8346,27 @@ 1 2 - 52 + 21 - 6183 - 6184 - 7 + 2 + 3 + 1 + + + 11 + 12 + 1 + + + 369 + 370 + 1 + + + 19366 + 19367 + 1 @@ -8081,12 +8382,22 @@ 1 2 - 52 + 22 - 6184 - 6185 - 7 + 2 + 3 + 1 + + + 369 + 370 + 1 + + + 19390 + 19391 + 1 @@ -8102,7 +8413,12 @@ 1 2 - 46171 + 30156 + + + 2 + 3 + 1 @@ -8118,7 +8434,12 @@ 1 2 - 46171 + 30156 + + + 11 + 12 + 1 @@ -8134,12 +8455,12 @@ 1 2 - 46148 + 30150 2 3 - 22 + 7 @@ -8149,15 +8470,15 @@ packages - 121135 + 96053 id - 121135 + 96053 nodeName - 121135 + 96053 @@ -8171,7 +8492,7 @@ 1 2 - 121135 + 96053 @@ -8187,7 +8508,7 @@ 1 2 - 121135 + 96053 @@ -8745,11 +9066,11 @@ file_class - 7249 + 17711 id - 7249 + 17711 @@ -12653,11 +12974,11 @@ isVarargsParam - 813764 + 684318 param - 813764 + 684318 @@ -12891,30 +13212,30 @@ isAnnotElem - 61065 + 49101 methodid - 61065 + 49101 annotValue - 1574925 + 1421553 parentid - 568174 + 1172586 id2 - 52104 + 1074 value - 1574925 + 1421553 @@ -12928,37 +13249,12 @@ 1 2 - 153493 + 1135381 2 - 3 - 252724 - - - 3 - 4 - 48951 - - - 4 - 6 - 26550 - - - 6 - 7 - 35179 - - - 7 - 9 - 46628 - - - 9 - 13 - 4646 + 18 + 37205 @@ -12974,37 +13270,12 @@ 1 2 - 138061 + 1133350 2 - 3 - 268157 - - - 3 - 4 - 47292 - - - 4 - 6 - 26052 - - - 6 - 8 - 39659 - - - 8 - 10 - 44139 - - - 10 - 13 - 4812 + 20 + 39235 @@ -13020,52 +13291,62 @@ 1 2 - 17091 + 198 2 3 - 5144 + 95 3 4 - 2655 + 88 - 4 - 6 - 4812 + 5 + 8 + 88 - 6 - 9 - 4314 + 8 + 16 + 88 - 9 - 15 - 4148 - - - 16 + 20 25 - 4314 + 88 - 27 - 86 - 3982 + 34 + 59 + 66 86 - 153 - 4148 + 102 + 80 - 164 - 1105 - 1493 + 121 + 185 + 51 + + + 203 + 684 + 80 + + + 1733 + 1734 + 125 + + + 1842 + 153327 + 22 @@ -13081,52 +13362,62 @@ 1 2 - 15266 + 198 2 3 - 6637 + 88 3 4 - 2820 + 88 4 - 6 - 3816 - - - 6 8 - 3816 + 95 8 - 10 - 4812 + 16 + 88 - 10 + 20 25 - 4148 + 88 - 25 - 53 - 3982 + 34 + 59 + 66 - 53 - 132 - 3982 + 86 + 102 + 80 - 134 - 1105 - 2820 + 127 + 185 + 51 + + + 203 + 684 + 80 + + + 1733 + 1734 + 88 + + + 1734 + 153327 + 58 @@ -13142,7 +13433,7 @@ 1 2 - 1574925 + 1421553 @@ -13158,7 +13449,7 @@ 1 2 - 1574925 + 1421553 @@ -14544,15 +14835,15 @@ isLocalClassOrInterface - 3533 + 3532 typeid - 3533 + 3532 parent - 3533 + 3532 @@ -14566,7 +14857,7 @@ 1 2 - 3533 + 3532 @@ -14582,7 +14873,7 @@ 1 2 - 3533 + 3532 @@ -14592,11 +14883,11 @@ isDefConstr - 139383 + 139376 constructorid - 139383 + 139376 @@ -15205,15 +15496,15 @@ implInterface - 3052687 + 3052545 id1 - 757298 + 757262 id2 - 2275569 + 2275463 @@ -15227,37 +15518,37 @@ 1 2 - 210035 + 210026 2 3 - 50057 + 50055 3 4 - 67415 + 67412 4 5 - 62041 + 62038 5 6 - 19333 + 19332 6 7 - 305943 + 305928 7 10 - 42471 + 42469 @@ -15273,12 +15564,12 @@ 1 2 - 2200149 + 2200047 2 63705 - 75420 + 75416 @@ -15288,15 +15579,15 @@ permits - 132 + 3703 id1 - 30 + 1075 id2 - 132 + 3703 @@ -15310,32 +15601,27 @@ 1 2 - 3 + 358 2 3 - 3 + 358 3 4 - 6 + 119 - 4 - 5 - 10 - - - 8 - 9 - 3 + 9 + 10 + 119 10 11 - 3 + 119 @@ -15351,7 +15637,7 @@ 1 2 - 132 + 3703 @@ -15469,23 +15755,23 @@ imports - 441072 + 356137 id - 441072 + 356137 holder - 52468 + 54477 name - 4282 + 8004 kind - 29 + 358 @@ -15499,7 +15785,7 @@ 1 2 - 441072 + 356137 @@ -15515,7 +15801,7 @@ 1 2 - 441072 + 356137 @@ -15531,7 +15817,7 @@ 1 2 - 441072 + 356137 @@ -15547,42 +15833,37 @@ 1 2 - 20638 + 24730 2 3 - 8976 + 8960 3 4 - 4991 + 5017 4 - 5 - 3335 + 6 + 4420 - 5 - 7 - 4096 + 6 + 10 + 4181 - 7 - 12 - 4305 + 10 + 30 + 4181 - 12 - 32 - 3984 - - - 32 - 1529 - 2141 + 31 + 113 + 2986 @@ -15598,12 +15879,12 @@ 1 2 - 50871 + 51132 2 - 54 - 1596 + 8 + 3345 @@ -15619,12 +15900,12 @@ 1 2 - 51200 + 51610 2 - 4 - 1268 + 3 + 2867 @@ -15640,27 +15921,32 @@ 1 2 - 2469 + 3584 2 3 - 962 + 1792 3 4 - 358 + 836 4 - 7 - 328 + 9 + 716 - 7 - 57945 - 164 + 9 + 32 + 716 + + + 45 + 2676 + 358 @@ -15676,38 +15962,43 @@ 1 2 - 4163 + 7048 2 - 6945 + 3 + 716 + + + 3 + 442 + 238 + + + + + + + name + kind + + + 12 + + + 1 + 2 + 7884 + + + 2 + 3 119 - - name - kind - - - 12 - - - 1 - 2 - 4275 - - - 3 - 4 - 7 - - - - - kind id @@ -15716,24 +16007,19 @@ 12 - 15 - 16 - 7 + 13 + 14 + 119 - 68 - 69 - 7 + 306 + 307 + 119 - 1170 - 1171 - 7 - - - 57861 - 57862 - 7 + 2662 + 2663 + 119 @@ -15747,24 +16033,19 @@ 12 - 10 - 11 - 7 + 5 + 6 + 119 - 25 - 26 - 7 + 39 + 40 + 119 - 257 - 258 - 7 - - - 6915 - 6916 - 7 + 436 + 437 + 119 @@ -15780,12 +16061,12 @@ 1 2 - 22 + 238 - 573 - 574 - 7 + 66 + 67 + 119 @@ -17679,15 +17960,15 @@ callableEnclosingExpr - 7299071 + 7298994 id - 7299071 + 7298994 callable_id - 19877 + 19876 @@ -17701,7 +17982,7 @@ 1 2 - 7299071 + 7298994 @@ -17792,15 +18073,15 @@ statementEnclosingExpr - 7258714 + 7258638 id - 7258714 + 7258638 statement_id - 525778 + 525773 @@ -17814,7 +18095,7 @@ 1 2 - 7258714 + 7258638 @@ -17830,7 +18111,7 @@ 1 3 - 29126 + 29125 3 @@ -17840,22 +18121,22 @@ 5 7 - 48474 + 48473 7 8 - 36042 + 36041 8 9 - 38145 + 38144 9 10 - 50447 + 50446 10 @@ -17865,7 +18146,7 @@ 11 12 - 127049 + 127048 12 @@ -17880,7 +18161,7 @@ 40 81 - 40222 + 40221 82 @@ -17970,15 +18251,15 @@ callableBinding - 1832520 + 1832514 callerid - 1832520 + 1832514 callee - 264311 + 264310 @@ -17992,7 +18273,7 @@ 1 2 - 1832520 + 1832514 @@ -18008,7 +18289,7 @@ 1 2 - 162995 + 162994 2 @@ -18144,12 +18425,12 @@ 1 2 - 1855 + 1854 2 3 - 3164 + 3163 3 @@ -18164,15 +18445,15 @@ propertyRefFieldBinding - 2 + 4 id - 2 + 4 field - 2 + 4 @@ -18186,7 +18467,7 @@ 1 2 - 2 + 4 @@ -18202,7 +18483,7 @@ 1 2 - 2 + 4 @@ -18719,11 +19000,11 @@ localvarsKotlinType - 149454 + 149446 id - 149454 + 149446 kttypeid @@ -18741,7 +19022,7 @@ 1 2 - 149454 + 149446 @@ -18767,19 +19048,19 @@ namestrings - 4022436 + 4022471 name - 23384 + 23402 value - 22166 + 22183 parent - 4022436 + 4022471 @@ -18793,7 +19074,7 @@ 1 2 - 23384 + 23402 @@ -18819,12 +19100,12 @@ 3 5 - 2150 + 2163 5 9 - 1769 + 1773 9 @@ -18860,7 +19141,7 @@ 1 2 - 21559 + 21576 2 @@ -18891,12 +19172,12 @@ 3 5 - 1912 + 1925 5 9 - 1665 + 1669 9 @@ -18932,7 +19213,7 @@ 1 2 - 4022436 + 4022471 @@ -18948,7 +19229,7 @@ 1 2 - 4022436 + 4022471 @@ -18958,15 +19239,15 @@ modules - 7965 + 6092 id - 7965 + 6092 name - 7965 + 6092 @@ -18980,7 +19261,7 @@ 1 2 - 7965 + 6092 @@ -18996,7 +19277,7 @@ 1 2 - 7965 + 6092 @@ -19017,15 +19298,15 @@ cumodule - 247580 + 188761 fileId - 247580 + 188761 moduleId - 1161 + 836 @@ -19039,7 +19320,7 @@ 1 2 - 247580 + 188761 @@ -19055,32 +19336,32 @@ 12 13 - 331 + 238 - 39 - 40 - 165 + 36 + 37 + 119 - 64 - 65 - 165 + 72 + 73 + 119 - 71 - 72 - 165 + 75 + 76 + 119 415 416 - 165 + 119 - 879 - 880 - 165 + 958 + 959 + 119 @@ -19090,15 +19371,15 @@ directives - 50279 + 37991 id - 1161 + 836 directive - 50279 + 37991 @@ -19112,37 +19393,37 @@ 3 4 - 165 + 119 4 5 - 165 + 119 7 8 - 165 + 119 9 10 - 165 + 119 43 44 - 165 + 119 89 90 - 165 + 119 - 148 - 149 - 165 + 163 + 164 + 119 @@ -19158,7 +19439,7 @@ 1 2 - 50279 + 37991 @@ -19261,11 +19542,11 @@ isTransitive - 829 + 597 id - 829 + 597 @@ -19283,15 +19564,15 @@ exports - 35013 + 26163 id - 35013 + 26163 target - 35013 + 26163 @@ -19305,7 +19586,7 @@ 1 2 - 35013 + 26163 @@ -19321,7 +19602,7 @@ 1 2 - 35013 + 26163 @@ -19331,15 +19612,15 @@ exportsTo - 28707 + 22579 id - 12279 + 9676 target - 7467 + 5734 @@ -19353,32 +19634,27 @@ 1 2 - 7301 + 5495 2 3 - 1825 + 1792 3 4 - 829 + 836 4 - 5 - 829 + 6 + 716 - 5 - 7 - 995 - - - 9 - 18 - 497 + 6 + 19 + 836 @@ -19394,42 +19670,47 @@ 1 2 - 1991 + 1672 2 3 - 1825 + 1194 3 4 - 663 + 716 4 5 - 663 + 358 5 6 - 663 + 477 6 7 - 331 + 238 8 10 - 663 + 477 - 11 + 10 13 - 663 + 358 + + + 13 + 14 + 238 @@ -19439,15 +19720,15 @@ opens - 165 + 716 id - 165 + 716 target - 165 + 716 @@ -19461,7 +19742,7 @@ 1 2 - 165 + 716 @@ -19477,7 +19758,7 @@ 1 2 - 165 + 716 @@ -19487,15 +19768,15 @@ opensTo - 165 + 716 id - 165 + 716 target - 165 + 238 @@ -19509,7 +19790,7 @@ 1 2 - 165 + 716 @@ -19525,7 +19806,12 @@ 1 2 - 165 + 119 + + + 5 + 6 + 119 @@ -19535,15 +19821,15 @@ uses - 10786 + 7884 id - 10786 + 7884 serviceInterface - 10786 + 7884 @@ -19557,7 +19843,7 @@ 1 2 - 10786 + 7884 @@ -19573,7 +19859,7 @@ 1 2 - 10786 + 7884 @@ -19583,15 +19869,15 @@ provides - 2323 + 1792 id - 2323 + 1792 serviceInterface - 2323 + 1792 @@ -19605,7 +19891,7 @@ 1 2 - 2323 + 1792 @@ -19621,7 +19907,7 @@ 1 2 - 2323 + 1792 @@ -19631,15 +19917,15 @@ providesWith - 5310 + 4181 id - 2323 + 1792 serviceImpl - 5310 + 4181 @@ -19653,22 +19939,27 @@ 1 2 - 1327 + 955 2 3 - 165 + 119 + + + 3 + 4 + 119 4 5 - 663 + 477 6 7 - 165 + 119 @@ -19684,7 +19975,7 @@ 1 2 - 5310 + 4181 @@ -25467,19 +25758,19 @@ ktComments - 74439 + 116780 id - 74439 + 116780 kind - 37 + 13 text - 51562 + 15129 @@ -25493,7 +25784,7 @@ 1 2 - 74439 + 116780 @@ -25509,7 +25800,7 @@ 1 2 - 74439 + 116780 @@ -25523,19 +25814,19 @@ 12 - 1196 - 1197 - 12 + 794 + 795 + 4 - 1284 - 1285 - 12 + 8820 + 8821 + 4 - 3517 - 3518 - 12 + 17201 + 17202 + 4 @@ -25549,19 +25840,19 @@ 12 - 17 - 18 - 12 + 20 + 21 + 4 - 1073 - 1074 - 12 + 680 + 681 + 4 - 3064 - 3065 - 12 + 2774 + 2775 + 4 @@ -25577,17 +25868,42 @@ 1 2 - 46101 + 6780 2 3 - 4232 + 692 3 - 572 - 1228 + 4 + 1506 + + + 4 + 5 + 126 + + + 5 + 6 + 3436 + + + 6 + 16 + 1258 + + + 16 + 32 + 1201 + + + 33 + 4236 + 126 @@ -25603,7 +25919,7 @@ 1 2 - 51562 + 15129 @@ -25613,19 +25929,19 @@ ktCommentSections - 47690 + 74919 id - 47690 + 74919 comment - 43655 + 74910 content - 40577 + 8109 @@ -25639,7 +25955,7 @@ 1 2 - 47690 + 74919 @@ -25655,7 +25971,7 @@ 1 2 - 47690 + 74919 @@ -25671,12 +25987,12 @@ 1 2 - 42029 + 74902 2 - 18 - 1626 + 3 + 8 @@ -25692,12 +26008,12 @@ 1 2 - 42029 + 74902 2 - 18 - 1626 + 3 + 8 @@ -25713,17 +26029,52 @@ 1 2 - 35910 + 3170 2 3 - 3910 + 522 3 - 63 - 757 + 5 + 518 + + + 5 + 6 + 962 + + + 6 + 9 + 622 + + + 9 + 10 + 34 + + + 10 + 11 + 718 + + + 11 + 21 + 675 + + + 21 + 37 + 622 + + + 42 + 504 + 261 @@ -25739,17 +26090,52 @@ 1 2 - 35997 + 3170 2 3 - 3835 + 522 3 - 56 - 744 + 5 + 518 + + + 5 + 6 + 962 + + + 6 + 9 + 622 + + + 9 + 10 + 34 + + + 10 + 11 + 718 + + + 11 + 21 + 675 + + + 21 + 37 + 622 + + + 42 + 504 + 261 @@ -25870,15 +26256,15 @@ ktCommentOwners - 68171 + 76609 id - 43432 + 74810 owner - 66520 + 71853 @@ -25892,22 +26278,12 @@ 1 2 - 28065 + 73186 2 - 3 - 9744 - - - 3 - 4 - 3649 - - - 4 6 - 1973 + 1624 @@ -25923,12 +26299,12 @@ 1 2 - 64881 + 69697 2 - 4 - 1638 + 5 + 2155 diff --git a/java/ql/lib/semmle/code/java/Compilation.qll b/java/ql/lib/semmle/code/java/Compilation.qll index c4b846edade..2610413c20b 100644 --- a/java/ql/lib/semmle/code/java/Compilation.qll +++ b/java/ql/lib/semmle/code/java/Compilation.qll @@ -83,6 +83,16 @@ class Compilation extends @compilation { */ string getArgument(int i) { compilation_args(this, i, result) } + /** + * Gets an expanded argument passed to the extractor on this invocation. + */ + string getAnExpandedArgument() { result = getExpandedArgument(_) } + + /** + * Gets the `i`th expanded argument passed to the extractor on this invocation. + */ + string getExpandedArgument(int i) { compilation_expanded_args(this, i, result) } + /** * Gets the total amount of CPU time spent processing all the files in the * compiler. diff --git a/java/ql/lib/semmle/code/java/frameworks/JsonIo.qll b/java/ql/lib/semmle/code/java/frameworks/JsonIo.qll index ab4c1b115d9..aa332bd78ed 100644 --- a/java/ql/lib/semmle/code/java/frameworks/JsonIo.qll +++ b/java/ql/lib/semmle/code/java/frameworks/JsonIo.qll @@ -42,8 +42,12 @@ class JsonIoUseMapsSetter extends MethodAccess { } } -/** A data flow configuration tracing flow from JsonIo safe settings. */ -class SafeJsonIoConfig extends DataFlow2::Configuration { +/** + * DEPRECATED: Use `SafeJsonIoFlow` instead. + * + * A data flow configuration tracing flow from JsonIo safe settings. + */ +deprecated class SafeJsonIoConfig extends DataFlow2::Configuration { SafeJsonIoConfig() { this = "UnsafeDeserialization::SafeJsonIoConfig" } override predicate isSource(DataFlow::Node src) { @@ -65,3 +69,30 @@ class SafeJsonIoConfig extends DataFlow2::Configuration { ) } } + +/** + * A data flow configuration tracing flow from JsonIo safe settings. + */ +module SafeJsonIoConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { + exists(MethodAccess ma | + ma instanceof JsonIoUseMapsSetter and + src.asExpr() = ma.getQualifier() + ) + } + + predicate isSink(DataFlow::Node sink) { + exists(MethodAccess ma | + ma.getMethod() instanceof JsonIoJsonToJavaMethod and + sink.asExpr() = ma.getArgument(1) + ) + or + exists(ClassInstanceExpr cie | + cie.getConstructor().getDeclaringType() instanceof JsonIoJsonReader and + sink.asExpr() = cie.getArgument(1) + ) + } +} + +/** Tracks flow from JsonIo safe settings. */ +module SafeJsonIoFlow = DataFlow::Global; diff --git a/java/ql/lib/semmle/code/java/frameworks/SnakeYaml.qll b/java/ql/lib/semmle/code/java/frameworks/SnakeYaml.qll index 3ea5d79c138..f21b9552061 100644 --- a/java/ql/lib/semmle/code/java/frameworks/SnakeYaml.qll +++ b/java/ql/lib/semmle/code/java/frameworks/SnakeYaml.qll @@ -4,8 +4,6 @@ import java import semmle.code.java.dataflow.DataFlow -import semmle.code.java.dataflow.DataFlow2 -import semmle.code.java.dataflow.DataFlow3 /** * The class `org.yaml.snakeyaml.constructor.SafeConstructor`. @@ -30,28 +28,28 @@ class Yaml extends RefType { Yaml() { this.getAnAncestor().hasQualifiedName("org.yaml.snakeyaml", "Yaml") } } -private class SafeYamlConstructionFlowConfig extends DataFlow3::Configuration { - SafeYamlConstructionFlowConfig() { this = "SnakeYaml::SafeYamlConstructionFlowConfig" } - - override predicate isSource(DataFlow::Node src) { - src.asExpr() instanceof SafeSnakeYamlConstruction - } - - override predicate isSink(DataFlow::Node sink) { sink = this.yamlClassInstanceExprArgument(_) } - - private DataFlow::ExprNode yamlClassInstanceExprArgument(ClassInstanceExpr cie) { - cie.getConstructedType() instanceof Yaml and - result.getExpr() = cie.getArgument(0) - } - - ClassInstanceExpr getSafeYaml() { this.hasFlowTo(this.yamlClassInstanceExprArgument(result)) } +private DataFlow::ExprNode yamlClassInstanceExprArgument(ClassInstanceExpr cie) { + cie.getConstructedType() instanceof Yaml and + result.getExpr() = cie.getArgument(0) } +private module SafeYamlConstructionFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeSnakeYamlConstruction } + + predicate isSink(DataFlow::Node sink) { sink = yamlClassInstanceExprArgument(_) } + + additional ClassInstanceExpr getSafeYaml() { + SafeYamlConstructionFlow::flowTo(yamlClassInstanceExprArgument(result)) + } +} + +private module SafeYamlConstructionFlow = DataFlow::Global; + /** * An instance of `Yaml` that does not allow arbitrary constructor to be called. */ private class SafeYaml extends ClassInstanceExpr { - SafeYaml() { exists(SafeYamlConstructionFlowConfig conf | conf.getSafeYaml() = this) } + SafeYaml() { SafeYamlConstructionFlowConfig::getSafeYaml() = this } } /** A call to a parse method of `Yaml`. */ @@ -65,23 +63,25 @@ private class SnakeYamlParse extends MethodAccess { } } -private class SafeYamlFlowConfig extends DataFlow2::Configuration { - SafeYamlFlowConfig() { this = "SnakeYaml::SafeYamlFlowConfig" } +private module SafeYamlFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeYaml } - override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeYaml } + predicate isSink(DataFlow::Node sink) { sink = yamlParseQualifier(_) } - override predicate isSink(DataFlow::Node sink) { sink = this.yamlParseQualifier(_) } - - private DataFlow::ExprNode yamlParseQualifier(SnakeYamlParse syp) { + additional DataFlow::ExprNode yamlParseQualifier(SnakeYamlParse syp) { result.getExpr() = syp.getQualifier() } - SnakeYamlParse getASafeSnakeYamlParse() { this.hasFlowTo(this.yamlParseQualifier(result)) } + additional SnakeYamlParse getASafeSnakeYamlParse() { + SafeYamlFlow::flowTo(yamlParseQualifier(result)) + } } +private module SafeYamlFlow = DataFlow::Global; + /** * A call to a parse method of `Yaml` that allows arbitrary constructor to be called. */ class UnsafeSnakeYamlParse extends SnakeYamlParse { - UnsafeSnakeYamlParse() { not exists(SafeYamlFlowConfig sy | sy.getASafeSnakeYamlParse() = this) } + UnsafeSnakeYamlParse() { not SafeYamlFlowConfig::getASafeSnakeYamlParse() = this } } diff --git a/java/ql/lib/semmle/code/java/regex/RegexFlowConfigs.qll b/java/ql/lib/semmle/code/java/regex/RegexFlowConfigs.qll index 5a913ccdef8..f517d6dec64 100644 --- a/java/ql/lib/semmle/code/java/regex/RegexFlowConfigs.qll +++ b/java/ql/lib/semmle/code/java/regex/RegexFlowConfigs.qll @@ -136,24 +136,22 @@ private class GuavaRegexFlowStep extends RegexAdditionalFlowStep { } } -private class RegexFlowConf extends DataFlow2::Configuration { - RegexFlowConf() { this = "RegexFlowConfig" } +private module RegexFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { node.asExpr() instanceof ExploitableStringLiteral } - override predicate isSource(DataFlow::Node node) { - node.asExpr() instanceof ExploitableStringLiteral - } + predicate isSink(DataFlow::Node node) { node instanceof RegexFlowSink } - override predicate isSink(DataFlow::Node node) { node instanceof RegexFlowSink } - - override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { any(RegexAdditionalFlowStep s).step(node1, node2) } - override predicate isBarrier(DataFlow::Node node) { + predicate isBarrier(DataFlow::Node node) { node.getEnclosingCallable().getDeclaringType() instanceof NonSecurityTestClass } } +private module RegexFlow = DataFlow::Global; + /** * Holds if `regex` is used as a regex, with the mode `mode` (if known). * If regex mode is not known, `mode` will be `"None"`. @@ -162,7 +160,7 @@ private class RegexFlowConf extends DataFlow2::Configuration { * and therefore may be relevant for ReDoS queries are considered. */ predicate usedAsRegex(StringLiteral regex, string mode, boolean match_full_string) { - any(RegexFlowConf c).hasFlow(DataFlow2::exprNode(regex), _) and + RegexFlow::flow(DataFlow::exprNode(regex), _) and mode = "None" and // TODO: proper mode detection (if matchesFullString(regex) then match_full_string = true else match_full_string = false) } @@ -172,9 +170,9 @@ predicate usedAsRegex(StringLiteral regex, string mode, boolean match_full_strin * as though it was implicitly surrounded by ^ and $. */ private predicate matchesFullString(StringLiteral regex) { - exists(RegexFlowConf c, RegexFlowSink sink | + exists(RegexFlowSink sink | sink.matchesFullString() and - c.hasFlow(DataFlow2::exprNode(regex), sink) + RegexFlow::flow(DataFlow::exprNode(regex), sink) ) } @@ -185,8 +183,8 @@ private predicate matchesFullString(StringLiteral regex) { * and therefore may be relevant for ReDoS queries are considered. */ predicate regexMatchedAgainst(StringLiteral regex, Expr str) { - exists(RegexFlowConf c, RegexFlowSink sink | + exists(RegexFlowSink sink | str = sink.getStringArgument() and - c.hasFlow(DataFlow2::exprNode(regex), sink) + RegexFlow::flow(DataFlow::exprNode(regex), sink) ) } diff --git a/java/ql/lib/semmle/code/java/security/AndroidSensitiveCommunicationQuery.qll b/java/ql/lib/semmle/code/java/security/AndroidSensitiveCommunicationQuery.qll index e0c9fbff800..e8d5a6d42d1 100644 --- a/java/ql/lib/semmle/code/java/security/AndroidSensitiveCommunicationQuery.qll +++ b/java/ql/lib/semmle/code/java/security/AndroidSensitiveCommunicationQuery.qll @@ -151,7 +151,10 @@ deprecated class SensitiveCommunicationConfig extends TaintTracking::Configurati } } -private module SensitiveCommunicationConfig implements DataFlow::ConfigSig { +/** + * Taint configuration tracking flow from variables containing sensitive information to broadcast Intents. + */ +module SensitiveCommunicationConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source.asExpr() instanceof SensitiveInfoExpr } predicate isSink(DataFlow::Node sink) { diff --git a/java/ql/lib/semmle/code/java/security/ArbitraryApkInstallationQuery.qll b/java/ql/lib/semmle/code/java/security/ArbitraryApkInstallationQuery.qll index d066f4974a1..9df15067be9 100644 --- a/java/ql/lib/semmle/code/java/security/ArbitraryApkInstallationQuery.qll +++ b/java/ql/lib/semmle/code/java/security/ArbitraryApkInstallationQuery.qll @@ -9,7 +9,7 @@ private import semmle.code.java.security.ArbitraryApkInstallation * A dataflow configuration for flow from an external source of an APK to the * `setData[AndType][AndNormalize]` method of an intent. */ -private module ApkInstallationConfig implements DataFlow::ConfigSig { +module ApkInstallationConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node node) { node instanceof ExternalApkSource } predicate isSink(DataFlow::Node node) { diff --git a/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidDatabaseQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidDatabaseQuery.qll index 7edd9e74c50..d995d11ce5b 100644 --- a/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidDatabaseQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidDatabaseQuery.qll @@ -29,16 +29,16 @@ class LocalDatabaseOpenMethodAccess extends Storable, Call { } override Expr getAnInput() { - exists(LocalDatabaseFlowConfig config, DataFlow::Node database | + exists(DataFlow::Node database | localDatabaseInput(database, result) and - config.hasFlow(DataFlow::exprNode(this), database) + LocalDatabaseFlow::flow(DataFlow::exprNode(this), database) ) } override Expr getAStore() { - exists(LocalDatabaseFlowConfig config, DataFlow::Node database | + exists(DataFlow::Node database | localDatabaseStore(database, result) and - config.hasFlow(DataFlow::exprNode(this), database) + LocalDatabaseFlow::flow(DataFlow::exprNode(this), database) ) } } @@ -93,19 +93,17 @@ private predicate localDatabaseStore(DataFlow::Node database, MethodAccess store ) } -private class LocalDatabaseFlowConfig extends DataFlow::Configuration { - LocalDatabaseFlowConfig() { this = "LocalDatabaseFlowConfig" } - - override predicate isSource(DataFlow::Node source) { +private module LocalDatabaseFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source.asExpr() instanceof LocalDatabaseOpenMethodAccess } - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { localDatabaseInput(sink, _) or localDatabaseStore(sink, _) } - override predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) { + predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) { // Adds a step for tracking databases through field flow, that is, a database is opened and // assigned to a field, and then an input or store method is called on that field elsewhere. exists(Field f | @@ -115,3 +113,5 @@ private class LocalDatabaseFlowConfig extends DataFlow::Configuration { ) } } + +private module LocalDatabaseFlow = DataFlow::Global; diff --git a/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidFilesystemQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidFilesystemQuery.qll index 89cc7ac021b..2641a3ab0df 100644 --- a/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidFilesystemQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidFilesystemQuery.qll @@ -24,16 +24,16 @@ class LocalFileOpenCall extends Storable { } override Expr getAnInput() { - exists(FilesystemFlowConfig conf, DataFlow::Node n | + exists(DataFlow::Node n | filesystemInput(n, result) and - conf.hasFlow(DataFlow::exprNode(this), n) + FilesystemFlow::flow(DataFlow::exprNode(this), n) ) } override Expr getAStore() { - exists(FilesystemFlowConfig conf, DataFlow::Node n | + exists(DataFlow::Node n | closesFile(n, result) and - conf.hasFlow(DataFlow::exprNode(this), n) + FilesystemFlow::flow(DataFlow::exprNode(this), n) ) } } @@ -79,17 +79,15 @@ private class CloseFileMethod extends Method { } } -private class FilesystemFlowConfig extends DataFlow::Configuration { - FilesystemFlowConfig() { this = "FilesystemFlowConfig" } +private module FilesystemFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { src.asExpr() instanceof LocalFileOpenCall } - override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof LocalFileOpenCall } - - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { filesystemInput(sink, _) or closesFile(sink, _) } - override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { // Add nested Writer constructors as extra data flow steps exists(ClassInstanceExpr cie | cie.getConstructedType().getAnAncestor().hasQualifiedName("java.io", "Writer") and @@ -98,3 +96,5 @@ private class FilesystemFlowConfig extends DataFlow::Configuration { ) } } + +private module FilesystemFlow = DataFlow::Global; diff --git a/java/ql/lib/semmle/code/java/security/CleartextStorageClassQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStorageClassQuery.qll index 3fe06a2de08..41e5c060816 100644 --- a/java/ql/lib/semmle/code/java/security/CleartextStorageClassQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CleartextStorageClassQuery.qll @@ -14,8 +14,8 @@ private class ClassCleartextStorageSink extends CleartextStorageSink { abstract class ClassStore extends Storable, ClassInstanceExpr { /** Gets an input, for example `input` in `instance.password = input`. */ override Expr getAnInput() { - exists(ClassStoreFlowConfig conf, DataFlow::Node instance | - conf.hasFlow(DataFlow::exprNode(this), instance) and + exists(DataFlow::Node instance | + ClassStoreFlow::flow(DataFlow::exprNode(this), instance) and result = getInstanceInput(instance, this.getConstructor().getDeclaringType()) ) } @@ -40,9 +40,9 @@ private class Serializable extends ClassStore { /** Gets a store, for example `outputStream.writeObject(instance)`. */ override Expr getAStore() { - exists(ClassStoreFlowConfig conf, DataFlow::Node n | + exists(DataFlow::Node n | serializableStore(n, result) and - conf.hasFlow(DataFlow::exprNode(this), n) + ClassStoreFlow::flow(DataFlow::exprNode(this), n) ) } } @@ -53,9 +53,9 @@ private class Marshallable extends ClassStore { /** Gets a store, for example `marshaller.marshal(instance)`. */ override Expr getAStore() { - exists(ClassStoreFlowConfig conf, DataFlow::Node n | + exists(DataFlow::Node n | marshallableStore(n, result) and - conf.hasFlow(DataFlow::exprNode(this), n) + ClassStoreFlow::flow(DataFlow::exprNode(this), n) ) } } @@ -73,20 +73,20 @@ private Expr getInstanceInput(DataFlow::Node instance, RefType t) { ) } -private class ClassStoreFlowConfig extends DataFlow::Configuration { - ClassStoreFlowConfig() { this = "ClassStoreFlowConfig" } +private module ClassStoreFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { src.asExpr() instanceof ClassStore } - override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof ClassStore } - - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { exists(getInstanceInput(sink, _)) or serializableStore(sink, _) or marshallableStore(sink, _) } - override int fieldFlowBranchLimit() { result = 1 } + int fieldFlowBranchLimit() { result = 1 } } +private module ClassStoreFlow = DataFlow::Global; + private predicate serializableStore(DataFlow::Node instance, Expr store) { exists(MethodAccess m | store = m and diff --git a/java/ql/lib/semmle/code/java/security/CleartextStorageCookieQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStorageCookieQuery.qll index bd071e7fef6..59c098281f1 100644 --- a/java/ql/lib/semmle/code/java/security/CleartextStorageCookieQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CleartextStorageCookieQuery.qll @@ -20,9 +20,9 @@ class Cookie extends Storable, ClassInstanceExpr { /** Gets a store, for example `response.addCookie(cookie);`. */ override Expr getAStore() { - exists(CookieToStoreFlowConfig conf, DataFlow::Node n | + exists(DataFlow::Node n | cookieStore(n, result) and - conf.hasFlow(DataFlow::exprNode(this), n) + CookieToStoreFlow::flow(DataFlow::exprNode(this), n) ) } } @@ -37,12 +37,12 @@ private predicate cookieStore(DataFlow::Node cookie, Expr store) { ) } -private class CookieToStoreFlowConfig extends DataFlow3::Configuration { - CookieToStoreFlowConfig() { this = "CookieToStoreFlowConfig" } +private module CookieToStoreFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { src.asExpr() instanceof Cookie } - override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof Cookie } - - override predicate isSink(DataFlow::Node sink) { cookieStore(sink, _) } + predicate isSink(DataFlow::Node sink) { cookieStore(sink, _) } } +private module CookieToStoreFlow = DataFlow::Global; + private Expr cookieInput(Cookie c) { result = c.getArgument(1) } diff --git a/java/ql/lib/semmle/code/java/security/CleartextStoragePropertiesQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStoragePropertiesQuery.qll index c75689c1fd2..f262104078e 100644 --- a/java/ql/lib/semmle/code/java/security/CleartextStoragePropertiesQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CleartextStoragePropertiesQuery.qll @@ -19,17 +19,17 @@ class Properties extends Storable, ClassInstanceExpr { /** Gets an input, for example `input` in `props.setProperty("password", input);`. */ override Expr getAnInput() { - exists(PropertiesFlowConfig conf, DataFlow::Node n | + exists(DataFlow::Node n | propertiesInput(n, result) and - conf.hasFlow(DataFlow::exprNode(this), n) + PropertiesFlow::flow(DataFlow::exprNode(this), n) ) } /** Gets a store, for example `props.store(outputStream, "...")`. */ override Expr getAStore() { - exists(PropertiesFlowConfig conf, DataFlow::Node n | + exists(DataFlow::Node n | propertiesStore(n, result) and - conf.hasFlow(DataFlow::exprNode(this), n) + PropertiesFlow::flow(DataFlow::exprNode(this), n) ) } } @@ -50,13 +50,13 @@ private predicate propertiesStore(DataFlow::Node prop, Expr store) { ) } -private class PropertiesFlowConfig extends DataFlow::Configuration { - PropertiesFlowConfig() { this = "PropertiesFlowConfig" } +private module PropertiesFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { src.asExpr() instanceof Properties } - override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof Properties } - - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { propertiesInput(sink, _) or propertiesStore(sink, _) } } + +private module PropertiesFlow = DataFlow::Global; diff --git a/java/ql/lib/semmle/code/java/security/CleartextStorageQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStorageQuery.qll index 8bd14b63ea6..0fdf69eb8a3 100644 --- a/java/ql/lib/semmle/code/java/security/CleartextStorageQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CleartextStorageQuery.qll @@ -21,9 +21,7 @@ class CleartextStorageAdditionalTaintStep extends Unit { class SensitiveSource extends Expr instanceof SensitiveExpr { /** Holds if this source flows to the `sink`. */ predicate flowsTo(Expr sink) { - exists(SensitiveSourceFlowConfig conf | - conf.hasFlow(DataFlow::exprNode(this), DataFlow::exprNode(sink)) - ) + SensitiveSourceFlow::flow(DataFlow::exprNode(this), DataFlow::exprNode(sink)) } } @@ -40,27 +38,25 @@ abstract class Storable extends Call { abstract Expr getAStore(); } -private class SensitiveSourceFlowConfig extends TaintTracking2::Configuration { - SensitiveSourceFlowConfig() { this = "SensitiveSourceFlowConfig" } +private module SensitiveSourceFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SensitiveExpr } - override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SensitiveExpr } + predicate isSink(DataFlow::Node sink) { sink instanceof CleartextStorageSink } - override predicate isSink(DataFlow::Node sink) { sink instanceof CleartextStorageSink } + predicate isBarrier(DataFlow::Node sanitizer) { sanitizer instanceof CleartextStorageSanitizer } - override predicate isSanitizer(DataFlow::Node sanitizer) { - sanitizer instanceof CleartextStorageSanitizer - } - - override predicate isAdditionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) { + predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) { any(CleartextStorageAdditionalTaintStep c).step(n1, n2) } } +private module SensitiveSourceFlow = TaintTracking::Global; + private class DefaultCleartextStorageSanitizer extends CleartextStorageSanitizer { DefaultCleartextStorageSanitizer() { this.getType() instanceof NumericType or this.getType() instanceof BooleanType or - exists(EncryptedValueFlowConfig conf | conf.hasFlow(_, this)) + EncryptedValueFlow::flowTo(this) } } @@ -76,12 +72,10 @@ private class EncryptedSensitiveMethodAccess extends MethodAccess { } /** Flow configuration for encryption methods flowing to inputs of persistent storage. */ -private class EncryptedValueFlowConfig extends DataFlow4::Configuration { - EncryptedValueFlowConfig() { this = "EncryptedValueFlowConfig" } +private module EncryptedValueFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { src.asExpr() instanceof EncryptedSensitiveMethodAccess } - override predicate isSource(DataFlow::Node src) { - src.asExpr() instanceof EncryptedSensitiveMethodAccess - } - - override predicate isSink(DataFlow::Node sink) { sink.asExpr() instanceof SensitiveExpr } + predicate isSink(DataFlow::Node sink) { sink.asExpr() instanceof SensitiveExpr } } + +private module EncryptedValueFlow = DataFlow::Global; diff --git a/java/ql/lib/semmle/code/java/security/CleartextStorageSharedPrefsQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStorageSharedPrefsQuery.qll index e67a2d1aa21..07764a251f7 100644 --- a/java/ql/lib/semmle/code/java/security/CleartextStorageSharedPrefsQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CleartextStorageSharedPrefsQuery.qll @@ -28,17 +28,17 @@ class SharedPreferencesEditorMethodAccess extends Storable, MethodAccess { /** Gets an input, for example `password` in `editor.putString("password", password);`. */ override Expr getAnInput() { - exists(SharedPreferencesFlowConfig conf, DataFlow::Node editor | + exists(DataFlow::Node editor | sharedPreferencesInput(editor, result) and - conf.hasFlow(DataFlow::exprNode(this), editor) + SharedPreferencesFlow::flow(DataFlow::exprNode(this), editor) ) } /** Gets a store, for example `editor.commit();`. */ override Expr getAStore() { - exists(SharedPreferencesFlowConfig conf, DataFlow::Node editor | + exists(DataFlow::Node editor | sharedPreferencesStore(editor, result) and - conf.hasFlow(DataFlow::exprNode(this), editor) + SharedPreferencesFlow::flow(DataFlow::exprNode(this), editor) ) } } @@ -65,15 +65,15 @@ private predicate sharedPreferencesStore(DataFlow::Node editor, MethodAccess m) } /** Flow from `SharedPreferences.Editor` to either a setter or a store method. */ -private class SharedPreferencesFlowConfig extends DataFlow::Configuration { - SharedPreferencesFlowConfig() { this = "SharedPreferencesFlowConfig" } - - override predicate isSource(DataFlow::Node src) { +private module SharedPreferencesFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SharedPreferencesEditorMethodAccess } - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { sharedPreferencesInput(sink, _) or sharedPreferencesStore(sink, _) } } + +private module SharedPreferencesFlow = DataFlow::Global; diff --git a/java/ql/lib/semmle/code/java/security/ConditionalBypassQuery.qll b/java/ql/lib/semmle/code/java/security/ConditionalBypassQuery.qll index 9bff32eac02..a45afda4105 100644 --- a/java/ql/lib/semmle/code/java/security/ConditionalBypassQuery.qll +++ b/java/ql/lib/semmle/code/java/security/ConditionalBypassQuery.qll @@ -37,9 +37,11 @@ private predicate endsWithStep(DataFlow::Node node1, DataFlow::Node node2) { } /** + * DEPRECATED: Use `ConditionalBypassFlow` instead. + * * A taint tracking configuration for untrusted data flowing to sensitive conditions. */ -class ConditionalBypassFlowConfig extends TaintTracking::Configuration { +deprecated class ConditionalBypassFlowConfig extends TaintTracking::Configuration { ConditionalBypassFlowConfig() { this = "ConditionalBypassFlowConfig" } override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } @@ -50,3 +52,21 @@ class ConditionalBypassFlowConfig extends TaintTracking::Configuration { endsWithStep(node1, node2) } } + +/** + * A taint tracking configuration for untrusted data flowing to sensitive conditions. + */ +module ConditionalBypassFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + + predicate isSink(DataFlow::Node sink) { conditionControlsMethod(_, sink.asExpr()) } + + predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + endsWithStep(node1, node2) + } +} + +/** + * Taint tracking flow for untrusted data flowing to sensitive conditions. + */ +module ConditionalBypassFlow = TaintTracking::Global; diff --git a/java/ql/lib/semmle/code/java/security/ExternalAPIs.qll b/java/ql/lib/semmle/code/java/security/ExternalAPIs.qll index ef23d28a076..89b24006475 100644 --- a/java/ql/lib/semmle/code/java/security/ExternalAPIs.qll +++ b/java/ql/lib/semmle/code/java/security/ExternalAPIs.qll @@ -98,8 +98,12 @@ class ExternalApiDataNode extends DataFlow::Node { /** DEPRECATED: Alias for ExternalApiDataNode */ deprecated class ExternalAPIDataNode = ExternalApiDataNode; -/** A configuration for tracking flow from `RemoteFlowSource`s to `ExternalApiDataNode`s. */ -class UntrustedDataToExternalApiConfig extends TaintTracking::Configuration { +/** + * DEPRECATED: Use `UntrustedDataToExternalApiFlow` instead. + * + * A configuration for tracking flow from `RemoteFlowSource`s to `ExternalApiDataNode`s. + */ +deprecated class UntrustedDataToExternalApiConfig extends TaintTracking::Configuration { UntrustedDataToExternalApiConfig() { this = "UntrustedDataToExternalAPIConfig" } override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } @@ -107,17 +111,29 @@ class UntrustedDataToExternalApiConfig extends TaintTracking::Configuration { override predicate isSink(DataFlow::Node sink) { sink instanceof ExternalApiDataNode } } +/** + * Taint tracking configuration for flow from `RemoteFlowSource`s to `ExternalApiDataNode`s. + */ +module UntrustedDataToExternalApiConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + + predicate isSink(DataFlow::Node sink) { sink instanceof ExternalApiDataNode } +} + +/** + * Tracks flow from untrusted data to external APIs. + */ +module UntrustedDataToExternalApiFlow = TaintTracking::Global; + /** DEPRECATED: Alias for UntrustedDataToExternalApiConfig */ deprecated class UntrustedDataToExternalAPIConfig = UntrustedDataToExternalApiConfig; /** A node representing untrusted data being passed to an external API. */ class UntrustedExternalApiDataNode extends ExternalApiDataNode { - UntrustedExternalApiDataNode() { any(UntrustedDataToExternalApiConfig c).hasFlow(_, this) } + UntrustedExternalApiDataNode() { UntrustedDataToExternalApiFlow::flowTo(this) } /** Gets a source of untrusted data which is passed to this external API data node. */ - DataFlow::Node getAnUntrustedSource() { - any(UntrustedDataToExternalApiConfig c).hasFlow(result, this) - } + DataFlow::Node getAnUntrustedSource() { UntrustedDataToExternalApiFlow::flow(result, this) } } /** DEPRECATED: Alias for UntrustedExternalApiDataNode */ diff --git a/java/ql/lib/semmle/code/java/security/ExternallyControlledFormatStringQuery.qll b/java/ql/lib/semmle/code/java/security/ExternallyControlledFormatStringQuery.qll new file mode 100644 index 00000000000..25d4e2b4fa5 --- /dev/null +++ b/java/ql/lib/semmle/code/java/security/ExternallyControlledFormatStringQuery.qll @@ -0,0 +1,26 @@ +/** Provides a taint-tracking configuration to reason about externally controlled format string vulnerabilities. */ + +import java +private import semmle.code.java.dataflow.FlowSources +private import semmle.code.java.StringFormat + +/** + * A taint-tracking configuration for externally controlled format string vulnerabilities. + */ +module ExternallyControlledFormatStringConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + + predicate isSink(DataFlow::Node sink) { + sink.asExpr() = any(StringFormat formatCall).getFormatArgument() + } + + predicate isBarrier(DataFlow::Node node) { + node.getType() instanceof NumericType or node.getType() instanceof BooleanType + } +} + +/** + * Taint-tracking flow for externally controlled format string vulnerabilities. + */ +module ExternallyControlledFormatStringFlow = + TaintTracking::Global; diff --git a/java/ql/lib/semmle/code/java/security/FragmentInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/FragmentInjectionQuery.qll index 94b1877a4a3..6164a6663a0 100644 --- a/java/ql/lib/semmle/code/java/security/FragmentInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/FragmentInjectionQuery.qll @@ -23,7 +23,11 @@ deprecated class FragmentInjectionTaintConf extends TaintTracking::Configuration } } -private module FragmentInjectionTaintConfig implements DataFlow::ConfigSig { +/** + * A taint-tracking configuration for unsafe user input + * that is used to create Android fragments dynamically. + */ +module FragmentInjectionTaintConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } predicate isSink(DataFlow::Node sink) { sink instanceof FragmentInjectionSink } diff --git a/java/ql/lib/semmle/code/java/security/HardcodedCredentialsApiCallQuery.qll b/java/ql/lib/semmle/code/java/security/HardcodedCredentialsApiCallQuery.qll index fb786710d66..6080cd188b3 100644 --- a/java/ql/lib/semmle/code/java/security/HardcodedCredentialsApiCallQuery.qll +++ b/java/ql/lib/semmle/code/java/security/HardcodedCredentialsApiCallQuery.qll @@ -7,9 +7,11 @@ import semmle.code.java.dataflow.DataFlow import HardcodedCredentials /** + * DEPRECATED: Use `HardcodedCredentialApiCallFlow` instead. + * * A data-flow configuration that tracks flow from a hard-coded credential in a call to a sensitive Java API which may compromise security. */ -class HardcodedCredentialApiCallConfiguration extends DataFlow::Configuration { +deprecated class HardcodedCredentialApiCallConfiguration extends DataFlow::Configuration { HardcodedCredentialApiCallConfiguration() { this = "HardcodedCredentialApiCallConfiguration" } override predicate isSource(DataFlow::Node n) { @@ -52,3 +54,53 @@ class HardcodedCredentialApiCallConfiguration extends DataFlow::Configuration { n.asExpr().(MethodAccess).getMethod() instanceof MethodSystemGetenv } } + +/** + * A data-flow configuration that tracks flow from a hard-coded credential in a call to a sensitive Java API which may compromise security. + */ +module HardcodedCredentialApiCallConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node n) { + n.asExpr() instanceof HardcodedExpr and + not n.asExpr().getEnclosingCallable() instanceof ToStringMethod + } + + predicate isSink(DataFlow::Node n) { n.asExpr() instanceof CredentialsApiSink } + + predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + node1.asExpr().getType() instanceof TypeString and + ( + exists(MethodAccess ma | ma.getMethod().hasName(["getBytes", "toCharArray"]) | + node2.asExpr() = ma and + ma.getQualifier() = node1.asExpr() + ) + or + // These base64 routines are usually taint propagators, and this is not a general + // TaintTracking::Configuration, so we must specifically include them here + // as a common transform applied to a constant before passing to a remote API. + exists(MethodAccess ma | + ma.getMethod() + .hasQualifiedName([ + "java.util", "cn.hutool.core.codec", "org.apache.shiro.codec", + "apache.commons.codec.binary", "org.springframework.util" + ], ["Base64$Encoder", "Base64$Decoder", "Base64", "Base64Utils"], + [ + "encode", "encodeToString", "decode", "decodeBase64", "encodeBase64", + "encodeBase64Chunked", "encodeBase64String", "encodeBase64URLSafe", + "encodeBase64URLSafeString" + ]) + | + node1.asExpr() = ma.getArgument(0) and + node2.asExpr() = ma + ) + ) + } + + predicate isBarrier(DataFlow::Node n) { + n.asExpr().(MethodAccess).getMethod() instanceof MethodSystemGetenv + } +} + +/** + * Tracks flow from a hard-coded credential in a call to a sensitive Java API which may compromise security. + */ +module HardcodedCredentialApiCallFlow = DataFlow::Global; diff --git a/java/ql/lib/semmle/code/java/security/HttpsUrlsQuery.qll b/java/ql/lib/semmle/code/java/security/HttpsUrlsQuery.qll index 50c76cefbca..cc827d34d46 100644 --- a/java/ql/lib/semmle/code/java/security/HttpsUrlsQuery.qll +++ b/java/ql/lib/semmle/code/java/security/HttpsUrlsQuery.qll @@ -6,9 +6,11 @@ import semmle.code.java.frameworks.Networking import semmle.code.java.security.HttpsUrls /** + * DEPRECATED: Use `HttpsStringToUrlOpenMethodFlow` instead. + * * A taint tracking configuration for HTTP connections. */ -class HttpStringToUrlOpenMethodFlowConfig extends TaintTracking::Configuration { +deprecated class HttpStringToUrlOpenMethodFlowConfig extends TaintTracking::Configuration { HttpStringToUrlOpenMethodFlowConfig() { this = "HttpStringToUrlOpenMethodFlowConfig" } override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof HttpStringLiteral } @@ -23,3 +25,25 @@ class HttpStringToUrlOpenMethodFlowConfig extends TaintTracking::Configuration { node.getType() instanceof PrimitiveType or node.getType() instanceof BoxedType } } + +/** + * A taint tracking configuration for HTTP connections. + */ +module HttpStringToUrlOpenMethodFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { src.asExpr() instanceof HttpStringLiteral } + + predicate isSink(DataFlow::Node sink) { sink instanceof UrlOpenSink } + + predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + any(HttpUrlsAdditionalTaintStep c).step(node1, node2) + } + + predicate isBarrier(DataFlow::Node node) { + node.getType() instanceof PrimitiveType or node.getType() instanceof BoxedType + } +} + +/** + * Detect taint flow of HTTP connections. + */ +module HttpStringToUrlOpenMethodFlow = TaintTracking::Global; diff --git a/java/ql/lib/semmle/code/java/security/ImplicitPendingIntentsQuery.qll b/java/ql/lib/semmle/code/java/security/ImplicitPendingIntentsQuery.qll index 814dc93f8d0..c02abb4de81 100644 --- a/java/ql/lib/semmle/code/java/security/ImplicitPendingIntentsQuery.qll +++ b/java/ql/lib/semmle/code/java/security/ImplicitPendingIntentsQuery.qll @@ -7,10 +7,12 @@ import semmle.code.java.frameworks.android.PendingIntent import semmle.code.java.security.ImplicitPendingIntents /** + * DEPRECATED: Use `ImplicitPendingIntentStartFlow` instead. + * * A taint tracking configuration for implicit `PendingIntent`s * being wrapped in another implicit `Intent` that gets started. */ -class ImplicitPendingIntentStartConf extends TaintTracking::Configuration { +deprecated class ImplicitPendingIntentStartConf extends TaintTracking::Configuration { ImplicitPendingIntentStartConf() { this = "ImplicitPendingIntentStartConf" } override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { @@ -52,3 +54,50 @@ class ImplicitPendingIntentStartConf extends TaintTracking::Configuration { c instanceof DataFlow::ArrayContent } } + +/** + * A taint tracking configuration for implicit `PendingIntent`s + * being wrapped in another implicit `Intent` that gets started. + */ +module ImplicitPendingIntentStartConfig implements DataFlow::StateConfigSig { + class FlowState = DataFlow::FlowState; + + predicate isSource(DataFlow::Node source, FlowState state) { + source.(ImplicitPendingIntentSource).hasState(state) + } + + predicate isSink(DataFlow::Node sink, FlowState state) { + sink.(ImplicitPendingIntentSink).hasState(state) + } + + predicate isBarrier(DataFlow::Node sanitizer) { sanitizer instanceof ExplicitIntentSanitizer } + + predicate isBarrier(DataFlow::Node node, FlowState state) { none() } + + predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + any(ImplicitPendingIntentAdditionalTaintStep c).step(node1, node2) + } + + predicate isAdditionalFlowStep( + DataFlow::Node node1, FlowState state1, DataFlow::Node node2, FlowState state2 + ) { + any(ImplicitPendingIntentAdditionalTaintStep c).step(node1, state1, node2, state2) + } + + predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) { + isSink(node, _) and + allowIntentExtrasImplicitRead(node, c) + or + isAdditionalFlowStep(node, _) and + c.(DataFlow::FieldContent).getType() instanceof PendingIntent + or + // Allow implicit reads of Intent arrays for steps like getActivities + // or sinks like startActivities + (isSink(node, _) or isAdditionalFlowStep(node, _, _, _)) and + node.getType().(Array).getElementType() instanceof TypeIntent and + c instanceof DataFlow::ArrayContent + } +} + +module ImplicitPendingIntentStartFlow = + TaintTracking::GlobalWithState; diff --git a/java/ql/lib/semmle/code/java/security/InsecureBasicAuthQuery.qll b/java/ql/lib/semmle/code/java/security/InsecureBasicAuthQuery.qll index 941aaafe580..60e16662d9a 100644 --- a/java/ql/lib/semmle/code/java/security/InsecureBasicAuthQuery.qll +++ b/java/ql/lib/semmle/code/java/security/InsecureBasicAuthQuery.qll @@ -6,10 +6,12 @@ import semmle.code.java.security.InsecureBasicAuth import semmle.code.java.dataflow.TaintTracking /** + * DEPRECATED: Use `InsecureBasicAuthFlow` instead. + * * A taint tracking configuration for the Basic authentication scheme * being used in HTTP connections. */ -class BasicAuthFlowConfig extends TaintTracking::Configuration { +deprecated class BasicAuthFlowConfig extends TaintTracking::Configuration { BasicAuthFlowConfig() { this = "InsecureBasicAuth::BasicAuthFlowConfig" } override predicate isSource(DataFlow::Node src) { src instanceof InsecureBasicAuthSource } @@ -20,3 +22,22 @@ class BasicAuthFlowConfig extends TaintTracking::Configuration { any(HttpUrlsAdditionalTaintStep c).step(node1, node2) } } + +/** + * A taint tracking configuration for the Basic authentication scheme + * being used in HTTP connections. + */ +module BasicAuthFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { src instanceof InsecureBasicAuthSource } + + predicate isSink(DataFlow::Node sink) { sink instanceof InsecureBasicAuthSink } + + predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + any(HttpUrlsAdditionalTaintStep c).step(node1, node2) + } +} + +/** + * Tracks flow for the Basic authentication scheme being used in HTTP connections. + */ +module InsecureBasicAuthFlow = TaintTracking::Global; diff --git a/java/ql/lib/semmle/code/java/security/InsecureBeanValidationQuery.qll b/java/ql/lib/semmle/code/java/security/InsecureBeanValidationQuery.qll new file mode 100644 index 00000000000..3d7c7f2fa94 --- /dev/null +++ b/java/ql/lib/semmle/code/java/security/InsecureBeanValidationQuery.qll @@ -0,0 +1,63 @@ +/** Provides classes and a taint tracking configuration to reason about insecure bean validation. */ + +import java +import semmle.code.java.dataflow.TaintTracking +import semmle.code.java.dataflow.FlowSources +private import semmle.code.java.dataflow.ExternalFlow + +/** + * A message interpolator Type that perform Expression Language (EL) evaluations. + */ +private class ELMessageInterpolatorType extends RefType { + ELMessageInterpolatorType() { + this.getASourceSupertype*() + .hasQualifiedName("org.hibernate.validator.messageinterpolation", + ["ResourceBundleMessageInterpolator", "ValueFormatterMessageInterpolator"]) + } +} + +/** + * A method call that sets the application's default message interpolator. + */ +class SetMessageInterpolatorCall extends MethodAccess { + SetMessageInterpolatorCall() { + exists(Method m, RefType t | + this.getMethod() = m and + m.getDeclaringType().getASourceSupertype*() = t and + ( + t.hasQualifiedName("javax.validation", ["Configuration", "ValidatorContext"]) and + m.getName() = "messageInterpolator" + or + t.hasQualifiedName("org.springframework.validation.beanvalidation", + ["CustomValidatorBean", "LocalValidatorFactoryBean"]) and + m.getName() = "setMessageInterpolator" + ) + ) + } + + /** + * Holds if the message interpolator is likely to be safe, because it does not process Java Expression Language expressions. + */ + predicate isSafe() { not this.getAnArgument().getType() instanceof ELMessageInterpolatorType } +} + +/** + * Taint tracking BeanValidationConfiguration describing the flow of data from user input + * to the argument of a method that builds constraint error messages. + */ +module BeanValidationConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + + predicate isSink(DataFlow::Node sink) { sink instanceof BeanValidationSink } +} + +/** Tracks flow from user input to the argument of a method that builds constraint error messages. */ +module BeanValidationFlow = TaintTracking::Global; + +/** + * A bean validation sink, such as method `buildConstraintViolationWithTemplate` + * declared on a subtype of `javax.validation.ConstraintValidatorContext`. + */ +private class BeanValidationSink extends DataFlow::Node { + BeanValidationSink() { sinkNode(this, "bean-validation") } +} diff --git a/java/ql/lib/semmle/code/java/security/InsecureTrustManagerQuery.qll b/java/ql/lib/semmle/code/java/security/InsecureTrustManagerQuery.qll index 22ab9bbcbc9..a7514ceff96 100644 --- a/java/ql/lib/semmle/code/java/security/InsecureTrustManagerQuery.qll +++ b/java/ql/lib/semmle/code/java/security/InsecureTrustManagerQuery.qll @@ -5,10 +5,12 @@ import semmle.code.java.dataflow.FlowSources import semmle.code.java.security.InsecureTrustManager /** + * DEPRECATED: Use `InsecureTrustManagerFlow` instead. + * * A configuration to model the flow of an insecure `TrustManager` * to the initialization of an SSL context. */ -class InsecureTrustManagerConfiguration extends DataFlow::Configuration { +deprecated class InsecureTrustManagerConfiguration extends DataFlow::Configuration { InsecureTrustManagerConfiguration() { this = "InsecureTrustManagerConfiguration" } override predicate isSource(DataFlow::Node source) { @@ -23,3 +25,21 @@ class InsecureTrustManagerConfiguration extends DataFlow::Configuration { c instanceof DataFlow::ArrayContent } } + +/** + * A configuration to model the flow of an insecure `TrustManager` + * to the initialization of an SSL context. + */ +module InsecureTrustManagerConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof InsecureTrustManagerSource } + + predicate isSink(DataFlow::Node sink) { sink instanceof InsecureTrustManagerSink } + + predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) { + (isSink(node) or isAdditionalFlowStep(node, _)) and + node.getType() instanceof Array and + c instanceof DataFlow::ArrayContent + } +} + +module InsecureTrustManagerFlow = DataFlow::Global; diff --git a/java/ql/lib/semmle/code/java/security/InsufficientKeySizeQuery.qll b/java/ql/lib/semmle/code/java/security/InsufficientKeySizeQuery.qll index eb416d9647b..d0d51ffbf08 100644 --- a/java/ql/lib/semmle/code/java/security/InsufficientKeySizeQuery.qll +++ b/java/ql/lib/semmle/code/java/security/InsufficientKeySizeQuery.qll @@ -3,8 +3,12 @@ import semmle.code.java.dataflow.DataFlow import semmle.code.java.security.InsufficientKeySize -/** A data flow configuration for tracking key sizes used in cryptographic algorithms. */ -class KeySizeConfiguration extends DataFlow::Configuration { +/** + * DEPRECATED: Use `KeySizeFlow` instead. + * + * A data flow configuration for tracking key sizes used in cryptographic algorithms. + */ +deprecated class KeySizeConfiguration extends DataFlow::Configuration { KeySizeConfiguration() { this = "KeySizeConfiguration" } override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { @@ -15,3 +19,30 @@ class KeySizeConfiguration extends DataFlow::Configuration { sink.(InsufficientKeySizeSink).hasState(state) } } + +/** + * A data flow configuration for tracking key sizes used in cryptographic algorithms. + */ +module KeySizeConfig implements DataFlow::StateConfigSig { + class FlowState = DataFlow::FlowState; + + predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { + source.(InsufficientKeySizeSource).hasState(state) + } + + predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { + sink.(InsufficientKeySizeSink).hasState(state) + } + + predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { none() } + + predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + none() + } +} + +/** Tracks key sizes used in cryptographic algorithms. */ +module KeySizeFlow = DataFlow::GlobalWithState; diff --git a/java/ql/lib/semmle/code/java/security/IntentUriPermissionManipulationQuery.qll b/java/ql/lib/semmle/code/java/security/IntentUriPermissionManipulationQuery.qll index 970cb4867fd..f563b4bf093 100644 --- a/java/ql/lib/semmle/code/java/security/IntentUriPermissionManipulationQuery.qll +++ b/java/ql/lib/semmle/code/java/security/IntentUriPermissionManipulationQuery.qll @@ -35,7 +35,10 @@ deprecated class IntentUriPermissionManipulationConf extends TaintTracking::Conf } } -private module IntentUriPermissionManipulationConfig implements DataFlow::ConfigSig { +/** + * A taint tracking configuration for user-provided Intents being returned to third party apps. + */ +module IntentUriPermissionManipulationConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } predicate isSink(DataFlow::Node sink) { sink instanceof IntentUriPermissionManipulationSink } diff --git a/java/ql/src/Security/CWE/CWE-090/LdapInjectionLib.qll b/java/ql/lib/semmle/code/java/security/LdapInjectionQuery.qll similarity index 78% rename from java/ql/src/Security/CWE/CWE-090/LdapInjectionLib.qll rename to java/ql/lib/semmle/code/java/security/LdapInjectionQuery.qll index d6ca8b1169d..c0f52cdf659 100644 --- a/java/ql/src/Security/CWE/CWE-090/LdapInjectionLib.qll +++ b/java/ql/lib/semmle/code/java/security/LdapInjectionQuery.qll @@ -1,3 +1,5 @@ +/** Provides a taint tracking configuration to reason about unvalidated user input that is used to construct LDAP queries. */ + import java import semmle.code.java.dataflow.FlowSources import semmle.code.java.security.LdapInjection @@ -17,4 +19,5 @@ module LdapInjectionFlowConfig implements DataFlow::ConfigSig { } } +/** Tracks flow from remote sources to LDAP injection vulnerabilities. */ module LdapInjectionFlow = TaintTracking::Global; diff --git a/java/ql/lib/semmle/code/java/security/LogInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/LogInjectionQuery.qll index a26e08d3edc..2610870b383 100644 --- a/java/ql/lib/semmle/code/java/security/LogInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/LogInjectionQuery.qll @@ -23,7 +23,10 @@ deprecated class LogInjectionConfiguration extends TaintTracking::Configuration } } -private module LogInjectionConfig implements DataFlow::ConfigSig { +/** + * A taint-tracking configuration for tracking untrusted user input used in log entries. + */ +module LogInjectionConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } predicate isSink(DataFlow::Node sink) { sink instanceof LogInjectionSink } diff --git a/java/ql/lib/semmle/code/java/security/MissingJWTSignatureCheckQuery.qll b/java/ql/lib/semmle/code/java/security/MissingJWTSignatureCheckQuery.qll index 818a4c664fe..c316da2f965 100644 --- a/java/ql/lib/semmle/code/java/security/MissingJWTSignatureCheckQuery.qll +++ b/java/ql/lib/semmle/code/java/security/MissingJWTSignatureCheckQuery.qll @@ -5,10 +5,12 @@ import semmle.code.java.dataflow.DataFlow import semmle.code.java.security.JWT /** + * DEPRECATED: Use `MissingJwtSignatureCheckFlow` instead. + * * Models flow from signing keys assignments to qualifiers of JWT insecure parsers. * This is used to determine whether a `JwtParser` performing unsafe parsing has a signing key set. */ -class MissingJwtSignatureCheckConf extends DataFlow::Configuration { +deprecated class MissingJwtSignatureCheckConf extends DataFlow::Configuration { MissingJwtSignatureCheckConf() { this = "SigningToExprDataFlow" } override predicate isSource(DataFlow::Node source) { @@ -21,3 +23,19 @@ class MissingJwtSignatureCheckConf extends DataFlow::Configuration { any(JwtParserWithInsecureParseAdditionalFlowStep c).step(node1, node2) } } + +/** + * Models flow from signing keys assignments to qualifiers of JWT insecure parsers. + * This is used to determine whether a `JwtParser` performing unsafe parsing has a signing key set. + */ +module MissingJwtSignatureCheckConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof JwtParserWithInsecureParseSource } + + predicate isSink(DataFlow::Node sink) { sink instanceof JwtParserWithInsecureParseSink } + + predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + any(JwtParserWithInsecureParseAdditionalFlowStep c).step(node1, node2) + } +} + +module MissingJwtSignatureCheckFlow = DataFlow::Global; diff --git a/java/ql/lib/semmle/code/java/security/PartialPathTraversalQuery.qll b/java/ql/lib/semmle/code/java/security/PartialPathTraversalQuery.qll index a43f90ae10d..1fd25df25aa 100644 --- a/java/ql/lib/semmle/code/java/security/PartialPathTraversalQuery.qll +++ b/java/ql/lib/semmle/code/java/security/PartialPathTraversalQuery.qll @@ -7,11 +7,13 @@ import semmle.code.java.dataflow.TaintTracking import semmle.code.java.dataflow.FlowSources /** + * DEPRECATED: Use `PartialPathTraversalFromRemoteFlow` instead. + * * A taint-tracking configuration for unsafe user input * that is used to validate against path traversal, but is insufficient * and remains vulnerable to Partial Path Traversal. */ -class PartialPathTraversalFromRemoteConfig extends TaintTracking::Configuration { +deprecated class PartialPathTraversalFromRemoteConfig extends TaintTracking::Configuration { PartialPathTraversalFromRemoteConfig() { this = "PartialPathTraversalFromRemoteConfig" } override predicate isSource(DataFlow::Node node) { node instanceof RemoteFlowSource } @@ -20,3 +22,20 @@ class PartialPathTraversalFromRemoteConfig extends TaintTracking::Configuration any(PartialPathTraversalMethodAccess ma).getQualifier() = node.asExpr() } } + +/** + * A taint-tracking configuration for unsafe user input + * that is used to validate against path traversal, but is insufficient + * and remains vulnerable to Partial Path Traversal. + */ +module PartialPathTraversalFromRemoteConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { node instanceof RemoteFlowSource } + + predicate isSink(DataFlow::Node node) { + any(PartialPathTraversalMethodAccess ma).getQualifier() = node.asExpr() + } +} + +/** Tracks flow of unsafe user input that is used to validate against path traversal, but is insufficient and remains vulnerable to Partial Path Traversal. */ +module PartialPathTraversalFromRemoteFlow = + TaintTracking::Global; diff --git a/java/ql/lib/semmle/code/java/security/RandomQuery.qll b/java/ql/lib/semmle/code/java/security/RandomQuery.qll index 1674cefdb70..b14191f4dd4 100644 --- a/java/ql/lib/semmle/code/java/security/RandomQuery.qll +++ b/java/ql/lib/semmle/code/java/security/RandomQuery.qll @@ -2,7 +2,7 @@ import java import semmle.code.java.dataflow.DefUse -import semmle.code.java.dataflow.DataFlow6 +import semmle.code.java.dataflow.DataFlow import RandomDataSource /** @@ -29,20 +29,18 @@ private predicate isSeeded(RValue use) { ) } -private class PredictableSeedFlowConfiguration extends DataFlow6::Configuration { - PredictableSeedFlowConfiguration() { this = "Random::PredictableSeedFlowConfiguration" } +private module PredictableSeedFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source.asExpr() instanceof PredictableSeedExpr } - override predicate isSource(DataFlow6::Node source) { - source.asExpr() instanceof PredictableSeedExpr - } + predicate isSink(DataFlow::Node sink) { isSeeding(sink.asExpr(), _) } - override predicate isSink(DataFlow6::Node sink) { isSeeding(sink.asExpr(), _) } - - override predicate isAdditionalFlowStep(DataFlow6::Node node1, DataFlow6::Node node2) { + predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { predictableCalcStep(node1.asExpr(), node2.asExpr()) } } +private module PredictableSeedFlow = DataFlow::Global; + private predicate predictableCalcStep(Expr e1, Expr e2) { e2.(BinaryExpr).hasOperands(e1, any(PredictableSeedExpr p)) or @@ -81,7 +79,7 @@ private predicate predictableCalcStep(Expr e1, Expr e2) { private predicate safelySeeded(RValue use) { exists(Expr arg | isSeeding(arg, use) and - not exists(PredictableSeedFlowConfiguration conf | conf.hasFlowToExpr(arg)) + not PredictableSeedFlow::flowToExpr(arg) ) or exists(GetRandomData da, RValue seeduse | @@ -118,9 +116,7 @@ private predicate isSeeding(Expr arg, RValue use) { private predicate isSeedingSource(Expr arg, RValue use, Expr source) { isSeeding(arg, use) and - exists(PredictableSeedFlowConfiguration conf | - conf.hasFlow(DataFlow6::exprNode(source), DataFlow6::exprNode(arg)) - ) + PredictableSeedFlow::flow(DataFlow::exprNode(source), DataFlow::exprNode(arg)) } private predicate isRandomSeeding(MethodAccess m, Expr arg) { diff --git a/java/ql/lib/semmle/code/java/security/ResponseSplittingQuery.qll b/java/ql/lib/semmle/code/java/security/ResponseSplittingQuery.qll new file mode 100644 index 00000000000..5ac4953422a --- /dev/null +++ b/java/ql/lib/semmle/code/java/security/ResponseSplittingQuery.qll @@ -0,0 +1,40 @@ +/** Provides a taint tracking configuration to reason about response splitting vulnerabilities. */ + +import java +private import semmle.code.java.dataflow.FlowSources +import semmle.code.java.security.ResponseSplitting + +/** + * A taint-tracking configuration for response splitting vulnerabilities. + */ +module ResponseSplittingConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { + source instanceof RemoteFlowSource and + not source instanceof SafeHeaderSplittingSource + } + + predicate isSink(DataFlow::Node sink) { sink instanceof HeaderSplittingSink } + + predicate isBarrier(DataFlow::Node node) { + node.getType() instanceof PrimitiveType + or + node.getType() instanceof BoxedType + or + exists(MethodAccess ma, string methodName, CompileTimeConstantExpr target | + node.asExpr() = ma and + ma.getMethod().hasQualifiedName("java.lang", "String", methodName) and + target = ma.getArgument(0) and + ( + methodName = "replace" and target.getIntValue() = [10, 13] // 10 == "\n", 13 == "\r" + or + methodName = "replaceAll" and + target.getStringValue().regexpMatch(".*([\n\r]|\\[\\^[^\\]\r\n]*\\]).*") + ) + ) + } +} + +/** + * Tracks flow from remote sources to response splitting vulnerabilities. + */ +module ResponseSplittingFlow = TaintTracking::Global; diff --git a/java/ql/lib/semmle/code/java/security/RsaWithoutOaepQuery.qll b/java/ql/lib/semmle/code/java/security/RsaWithoutOaepQuery.qll index 0d9df09bb74..848a1c2b990 100644 --- a/java/ql/lib/semmle/code/java/security/RsaWithoutOaepQuery.qll +++ b/java/ql/lib/semmle/code/java/security/RsaWithoutOaepQuery.qll @@ -26,7 +26,10 @@ deprecated class RsaWithoutOaepConfig extends DataFlow::Configuration { } } -private module RsaWithoutOaepConfig implements DataFlow::ConfigSig { +/** + * A configuration for finding RSA ciphers initialized without using OAEP padding. + */ +module RsaWithoutOaepConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node src) { exists(CompileTimeConstantExpr specExpr, string spec | specExpr.getStringValue() = spec and diff --git a/java/ql/lib/semmle/code/java/security/SensitiveLoggingQuery.qll b/java/ql/lib/semmle/code/java/security/SensitiveLoggingQuery.qll index ea687d32a0a..d9ed2b970b0 100644 --- a/java/ql/lib/semmle/code/java/security/SensitiveLoggingQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SensitiveLoggingQuery.qll @@ -49,7 +49,7 @@ deprecated class SensitiveLoggerConfiguration extends TaintTracking::Configurati } /** A data-flow configuration for identifying potentially-sensitive data flowing to a log output. */ -private module SensitiveLoggerConfig implements DataFlow::ConfigSig { +module SensitiveLoggerConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source.asExpr() instanceof CredentialExpr } predicate isSink(DataFlow::Node sink) { sinkNode(sink, "logging") } diff --git a/java/ql/lib/semmle/code/java/security/StaticInitializationVectorQuery.qll b/java/ql/lib/semmle/code/java/security/StaticInitializationVectorQuery.qll index 64dee88b7fd..38d426adc5a 100644 --- a/java/ql/lib/semmle/code/java/security/StaticInitializationVectorQuery.qll +++ b/java/ql/lib/semmle/code/java/security/StaticInitializationVectorQuery.qll @@ -83,25 +83,23 @@ private class ArrayUpdate extends Expr { /** * A config that tracks dataflow from creating an array to an operation that updates it. */ -private class ArrayUpdateConfig extends DataFlow2::Configuration { - ArrayUpdateConfig() { this = "ArrayUpdateConfig" } +private module ArrayUpdateConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source.asExpr() instanceof StaticByteArrayCreation } - override predicate isSource(DataFlow::Node source) { - source.asExpr() instanceof StaticByteArrayCreation - } + predicate isSink(DataFlow::Node sink) { sink.asExpr() = any(ArrayUpdate upd).getArray() } - override predicate isSink(DataFlow::Node sink) { sink.asExpr() = any(ArrayUpdate upd).getArray() } - - override predicate isBarrierOut(DataFlow::Node node) { this.isSink(node) } + predicate isBarrierOut(DataFlow::Node node) { isSink(node) } } +private module ArrayUpdateFlow = DataFlow::Global; + /** * A source that defines an array that doesn't get updated. */ private class StaticInitializationVectorSource extends DataFlow::Node { StaticInitializationVectorSource() { exists(StaticByteArrayCreation array | array = this.asExpr() | - not exists(ArrayUpdateConfig config | config.hasFlow(DataFlow2::exprNode(array), _)) and + not ArrayUpdateFlow::flow(DataFlow2::exprNode(array), _) and // Reduce FPs from utility methods that return an empty array in an exceptional case not exists(ReturnStmt ret | array.getADimension().(CompileTimeConstantExpr).getIntValue() = 0 and @@ -146,9 +144,11 @@ private predicate createInitializationVectorSpecStep(DataFlow::Node fromNode, Da } /** + * DEPRECATED: Use `StaticInitializationVectorFlow` instead. + * * A config that tracks dataflow to initializing a cipher with a static initialization vector. */ -class StaticInitializationVectorConfig extends TaintTracking::Configuration { +deprecated class StaticInitializationVectorConfig extends TaintTracking::Configuration { StaticInitializationVectorConfig() { this = "StaticInitializationVectorConfig" } override predicate isSource(DataFlow::Node source) { @@ -161,3 +161,19 @@ class StaticInitializationVectorConfig extends TaintTracking::Configuration { createInitializationVectorSpecStep(fromNode, toNode) } } + +/** + * A config that tracks dataflow to initializing a cipher with a static initialization vector. + */ +module StaticInitializationVectorConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof StaticInitializationVectorSource } + + predicate isSink(DataFlow::Node sink) { sink instanceof EncryptionInitializationSink } + + predicate isAdditionalFlowStep(DataFlow::Node fromNode, DataFlow::Node toNode) { + createInitializationVectorSpecStep(fromNode, toNode) + } +} + +/** Tracks the flow from a static initialization vector to the initialization of a cipher */ +module StaticInitializationVectorFlow = TaintTracking::Global; diff --git a/java/ql/lib/semmle/code/java/security/TaintedPathQuery.qll b/java/ql/lib/semmle/code/java/security/TaintedPathQuery.qll new file mode 100644 index 00000000000..27a54d0ecfa --- /dev/null +++ b/java/ql/lib/semmle/code/java/security/TaintedPathQuery.qll @@ -0,0 +1,104 @@ +/** Provides dataflow configurations for tainted path queries. */ + +import java +import semmle.code.java.frameworks.Networking +import semmle.code.java.dataflow.DataFlow +import semmle.code.java.dataflow.FlowSources +private import semmle.code.java.dataflow.ExternalFlow +import semmle.code.java.security.PathCreation +import semmle.code.java.security.PathSanitizer + +/** + * A unit class for adding additional taint steps. + * + * Extend this class to add additional taint steps that should apply to tainted path flow configurations. + */ +class TaintedPathAdditionalTaintStep extends Unit { + abstract predicate step(DataFlow::Node n1, DataFlow::Node n2); +} + +private class DefaultTaintedPathAdditionalTaintStep extends TaintedPathAdditionalTaintStep { + override predicate step(DataFlow::Node n1, DataFlow::Node n2) { + exists(Argument a | + a = n1.asExpr() and + a.getCall() = n2.asExpr() and + a = any(TaintPreservingUriCtorParam tpp).getAnArgument() + ) + } +} + +private class TaintPreservingUriCtorParam extends Parameter { + TaintPreservingUriCtorParam() { + exists(Constructor ctor, int idx, int nParams | + ctor.getDeclaringType() instanceof TypeUri and + this = ctor.getParameter(idx) and + nParams = ctor.getNumberOfParameters() + | + // URI(String scheme, String ssp, String fragment) + idx = 1 and nParams = 3 + or + // URI(String scheme, String host, String path, String fragment) + idx = [1, 2] and nParams = 4 + or + // URI(String scheme, String authority, String path, String query, String fragment) + idx = 2 and nParams = 5 + or + // URI(String scheme, String userInfo, String host, int port, String path, String query, String fragment) + idx = 4 and nParams = 7 + ) + } +} + +/** + * A taint-tracking configuration for tracking flow from remote sources to the creation of a path. + */ +module TaintedPathConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + + predicate isSink(DataFlow::Node sink) { + sink.asExpr() = any(PathCreation p).getAnInput() + or + sinkNode(sink, ["create-file", "read-file"]) + } + + predicate isBarrier(DataFlow::Node sanitizer) { + sanitizer.getType() instanceof BoxedType or + sanitizer.getType() instanceof PrimitiveType or + sanitizer.getType() instanceof NumberType or + sanitizer instanceof PathInjectionSanitizer + } + + predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) { + any(TaintedPathAdditionalTaintStep s).step(n1, n2) + } +} + +/** Tracks flow from remote sources to the creation of a path. */ +module TaintedPathFlow = TaintTracking::Global; + +/** + * A taint-tracking configuration for tracking flow from local user input to the creation of a path. + */ +module TaintedPathLocalConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof LocalUserInput } + + predicate isSink(DataFlow::Node sink) { + sink.asExpr() = any(PathCreation p).getAnInput() + or + sinkNode(sink, "create-file") + } + + predicate isBarrier(DataFlow::Node sanitizer) { + sanitizer.getType() instanceof BoxedType or + sanitizer.getType() instanceof PrimitiveType or + sanitizer.getType() instanceof NumberType or + sanitizer instanceof PathInjectionSanitizer + } + + predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) { + any(TaintedPathAdditionalTaintStep s).step(n1, n2) + } +} + +/** Tracks flow from local user input to the creation of a path. */ +module TaintedPathLocalFlow = TaintTracking::Global; diff --git a/java/ql/lib/semmle/code/java/security/UnsafeCertTrustQuery.qll b/java/ql/lib/semmle/code/java/security/UnsafeCertTrustQuery.qll index ee87fdc64ee..0b45e150c0c 100644 --- a/java/ql/lib/semmle/code/java/security/UnsafeCertTrustQuery.qll +++ b/java/ql/lib/semmle/code/java/security/UnsafeCertTrustQuery.qll @@ -6,9 +6,11 @@ import semmle.code.java.security.UnsafeCertTrust import semmle.code.java.security.Encryption /** + * DEPRECATED: Use `SslEndpointIdentificationFlow` instead. + * * A taint flow configuration for SSL connections created without a proper certificate trust configuration. */ -class SslEndpointIdentificationFlowConfig extends TaintTracking::Configuration { +deprecated class SslEndpointIdentificationFlowConfig extends TaintTracking::Configuration { SslEndpointIdentificationFlowConfig() { this = "SslEndpointIdentificationFlowConfig" } override predicate isSource(DataFlow::Node source) { source instanceof SslConnectionInit } @@ -20,30 +22,44 @@ class SslEndpointIdentificationFlowConfig extends TaintTracking::Configuration { } } +/** + * A taint flow configuration for SSL connections created without a proper certificate trust configuration. + */ +module SslEndpointIdentificationFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof SslConnectionInit } + + predicate isSink(DataFlow::Node sink) { sink instanceof SslConnectionCreation } + + predicate isBarrier(DataFlow::Node sanitizer) { sanitizer instanceof SslUnsafeCertTrustSanitizer } +} + +/** + * Taint flow for SSL connections created without a proper certificate trust configuration. + */ +module SslEndpointIdentificationFlow = TaintTracking::Global; + /** * An SSL object that was assigned a safe `SSLParameters` object and can be considered safe. */ private class SslConnectionWithSafeSslParameters extends SslUnsafeCertTrustSanitizer { SslConnectionWithSafeSslParameters() { - exists(SafeSslParametersFlowConfig config, DataFlow::Node safe, DataFlow::Node sanitizer | - config.hasFlowTo(safe) and + exists(DataFlow::Node safe, DataFlow::Node sanitizer | + SafeSslParametersFlow::flowTo(safe) and sanitizer = DataFlow::exprNode(safe.asExpr().(Argument).getCall().getQualifier()) and DataFlow::localFlow(sanitizer, this) ) } } -private class SafeSslParametersFlowConfig extends DataFlow2::Configuration { - SafeSslParametersFlowConfig() { this = "SafeSslParametersFlowConfig" } - - override predicate isSource(DataFlow::Node source) { +private module SafeSslParametersFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { exists(MethodAccess ma | ma instanceof SafeSetEndpointIdentificationAlgorithm and DataFlow::getInstanceArgument(ma) = source.(DataFlow::PostUpdateNode).getPreUpdateNode() ) } - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { exists(MethodAccess ma, RefType t | t instanceof SslSocket or t instanceof SslEngine | ma.getMethod().hasName("setSSLParameters") and ma.getMethod().getDeclaringType().getAnAncestor() = t and @@ -52,6 +68,8 @@ private class SafeSslParametersFlowConfig extends DataFlow2::Configuration { } } +private module SafeSslParametersFlow = DataFlow::Global; + /** * A call to `SSLParameters.setEndpointIdentificationAlgorithm` with a non-null and non-empty parameter. */ diff --git a/java/ql/lib/semmle/code/java/security/UnsafeContentUriResolutionQuery.qll b/java/ql/lib/semmle/code/java/security/UnsafeContentUriResolutionQuery.qll index b59c4b79655..424edace82a 100644 --- a/java/ql/lib/semmle/code/java/security/UnsafeContentUriResolutionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/UnsafeContentUriResolutionQuery.qll @@ -26,7 +26,10 @@ deprecated class UnsafeContentResolutionConf extends TaintTracking::Configuratio } } -private module UnsafeContentResolutionConfig implements DataFlow::ConfigSig { +/** + * A taint-tracking configuration to find paths from remote sources to content URI resolutions. + */ +module UnsafeContentResolutionConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node src) { src instanceof RemoteFlowSource } predicate isSink(DataFlow::Node sink) { sink instanceof ContentUriResolutionSink } diff --git a/java/ql/lib/semmle/code/java/security/UnsafeDeserializationQuery.qll b/java/ql/lib/semmle/code/java/security/UnsafeDeserializationQuery.qll index 6d0ff888d82..7e995e5cbaf 100644 --- a/java/ql/lib/semmle/code/java/security/UnsafeDeserializationQuery.qll +++ b/java/ql/lib/semmle/code/java/security/UnsafeDeserializationQuery.qll @@ -35,15 +35,13 @@ private class XmlDecoderReadObjectMethod extends Method { } } -private class SafeXStream extends DataFlow2::Configuration { - SafeXStream() { this = "UnsafeDeserialization::SafeXStream" } - - override predicate isSource(DataFlow::Node src) { +private module SafeXStreamConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { any(XStreamEnableWhiteListing ma).getQualifier().(VarAccess).getVariable().getAnAccess() = src.asExpr() } - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { exists(MethodAccess ma | sink.asExpr() = ma.getQualifier() and ma.getMethod() instanceof XStreamReadObjectMethod @@ -51,26 +49,26 @@ private class SafeXStream extends DataFlow2::Configuration { } } -private class SafeKryo extends DataFlow2::Configuration { - SafeKryo() { this = "UnsafeDeserialization::SafeKryo" } +private module SafeXStreamFlow = DataFlow::Global; - override predicate isSource(DataFlow::Node src) { +private module SafeKryoConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { any(KryoEnableWhiteListing ma).getQualifier().(VarAccess).getVariable().getAnAccess() = src.asExpr() } - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { exists(MethodAccess ma | sink.asExpr() = ma.getQualifier() and ma.getMethod() instanceof KryoReadObjectMethod ) } - override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.stepKryoPoolBuilderFactoryArgToConstructor(node1, node2) or - this.stepKryoPoolRunMethodAccessQualifierToFunctionalArgument(node1, node2) or - this.stepKryoPoolBuilderChainMethod(node1, node2) or - this.stepKryoPoolBorrowMethod(node1, node2) + predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + stepKryoPoolBuilderFactoryArgToConstructor(node1, node2) or + stepKryoPoolRunMethodAccessQualifierToFunctionalArgument(node1, node2) or + stepKryoPoolBuilderChainMethod(node1, node2) or + stepKryoPoolBorrowMethod(node1, node2) } /** @@ -126,6 +124,8 @@ private class SafeKryo extends DataFlow2::Configuration { } } +private module SafeKryoFlow = DataFlow::Global; + /** * Holds if `ma` is a call that deserializes data from `sink`. */ @@ -145,11 +145,11 @@ predicate unsafeDeserialization(MethodAccess ma, Expr sink) { or m instanceof XStreamReadObjectMethod and sink = ma.getAnArgument() and - not exists(SafeXStream sxs | sxs.hasFlowToExpr(ma.getQualifier())) + not SafeXStreamFlow::flowToExpr(ma.getQualifier()) or m instanceof KryoReadObjectMethod and sink = ma.getAnArgument() and - not exists(SafeKryo sk | sk.hasFlowToExpr(ma.getQualifier())) + not SafeKryoFlow::flowToExpr(ma.getQualifier()) or m instanceof MethodApacheSerializationUtilsDeserialize and sink = ma.getArgument(0) @@ -181,17 +181,17 @@ predicate unsafeDeserialization(MethodAccess ma, Expr sink) { ma.getMethod() instanceof ObjectMapperReadMethod and sink = ma.getArgument(0) and ( - exists(UnsafeTypeConfig config | config.hasFlowToExpr(ma.getAnArgument())) + UnsafeTypeFlow::flowToExpr(ma.getAnArgument()) or - exists(EnableJacksonDefaultTypingConfig config | config.hasFlowToExpr(ma.getQualifier())) + EnableJacksonDefaultTypingFlow::flowToExpr(ma.getQualifier()) or hasArgumentWithUnsafeJacksonAnnotation(ma) ) and - not exists(SafeObjectMapperConfig config | config.hasFlowToExpr(ma.getQualifier())) + not SafeObjectMapperFlow::flowToExpr(ma.getQualifier()) or m instanceof JabsorbUnmarshallMethod and sink = ma.getArgument(2) and - any(UnsafeTypeConfig config).hasFlowToExpr(ma.getArgument(1)) + UnsafeTypeFlow::flowToExpr(ma.getArgument(1)) or m instanceof JabsorbFromJsonMethod and sink = ma.getArgument(0) @@ -200,7 +200,7 @@ predicate unsafeDeserialization(MethodAccess ma, Expr sink) { sink = ma.getArgument(0) and ( // User controls the target type for deserialization - any(UnsafeTypeConfig c).hasFlowToExpr(ma.getArgument(1)) + UnsafeTypeFlow::flowToExpr(ma.getArgument(1)) or // jodd.json.JsonParser may be configured for unrestricted deserialization to user-specified types joddJsonParserConfiguredUnsafely(ma.getQualifier()) @@ -211,7 +211,7 @@ predicate unsafeDeserialization(MethodAccess ma, Expr sink) { or m instanceof GsonDeserializeMethod and sink = ma.getArgument(0) and - any(UnsafeTypeConfig config).hasFlowToExpr(ma.getArgument(1)) + UnsafeTypeFlow::flowToExpr(ma.getArgument(1)) ) } @@ -223,10 +223,80 @@ class UnsafeDeserializationSink extends DataFlow::ExprNode { MethodAccess getMethodAccess() { unsafeDeserialization(result, this.getExpr()) } } +/** Holds if `node` is a sanitizer for unsafe deserialization */ +private predicate isUnsafeDeserializationSanitizer(DataFlow::Node node) { + exists(ClassInstanceExpr cie | + cie.getConstructor().getDeclaringType() instanceof JsonIoJsonReader and + cie = node.asExpr() and + SafeJsonIoFlow::flowToExpr(cie.getArgument(1)) + ) + or + exists(MethodAccess ma | + ma.getMethod() instanceof JsonIoJsonToJavaMethod and + ma.getArgument(0) = node.asExpr() and + SafeJsonIoFlow::flowToExpr(ma.getArgument(1)) + ) + or + exists(MethodAccess ma | + // Sanitize the input to jodd.json.JsonParser.parse et al whenever it appears + // to be called with an explicit class argument limiting those types that can + // be instantiated during deserialization. + ma.getMethod() instanceof JoddJsonParseMethod and + ma.getArgument(1).getType() instanceof TypeClass and + not ma.getArgument(1) instanceof NullLiteral and + not ma.getArgument(1).getType().getName() = ["Class", "Class"] and + node.asExpr() = ma.getAnArgument() + ) + or + exists(MethodAccess ma | + // Sanitize the input to flexjson.JSONDeserializer.deserialize whenever it appears + // to be called with an explicit class argument limiting those types that can + // be instantiated during deserialization, or if the deserializer has already been + // configured to use a specified root class. + ma.getMethod() instanceof FlexjsonDeserializeMethod and + node.asExpr() = ma.getAnArgument() and + ( + ma.getArgument(1).getType() instanceof TypeClass and + not ma.getArgument(1) instanceof NullLiteral and + not ma.getArgument(1).getType().getName() = ["Class", "Class"] + or + isSafeFlexjsonDeserializer(ma.getQualifier()) + ) + ) +} + +/** Taint step for Unsafe deserialization */ +private predicate isUnsafeDeserializationTaintStep(DataFlow::Node pred, DataFlow::Node succ) { + exists(ClassInstanceExpr cie | + cie.getArgument(0) = pred.asExpr() and + cie = succ.asExpr() and + ( + cie.getConstructor().getDeclaringType() instanceof JsonIoJsonReader or + cie.getConstructor().getDeclaringType() instanceof YamlBeansReader or + cie.getConstructor().getDeclaringType().getAnAncestor() instanceof UnsafeHessianInput or + cie.getConstructor().getDeclaringType() instanceof BurlapInput + ) + ) + or + exists(MethodAccess ma | + ma.getMethod() instanceof BurlapInputInitMethod and + ma.getArgument(0) = pred.asExpr() and + ma.getQualifier() = succ.asExpr() + ) + or + createJacksonJsonParserStep(pred, succ) + or + createJacksonTreeNodeStep(pred, succ) + or + intentFlowsToParcel(pred, succ) +} + /** + * DEPRECATED: Use `UnsafeDeserializationFlow` instead. + * * Tracks flows from remote user input to a deserialization sink. */ -class UnsafeDeserializationConfig extends TaintTracking::Configuration { +deprecated class UnsafeDeserializationConfig extends TaintTracking::Configuration { UnsafeDeserializationConfig() { this = "UnsafeDeserializationConfig" } override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } @@ -234,72 +304,27 @@ class UnsafeDeserializationConfig extends TaintTracking::Configuration { override predicate isSink(DataFlow::Node sink) { sink instanceof UnsafeDeserializationSink } override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { - exists(ClassInstanceExpr cie | - cie.getArgument(0) = pred.asExpr() and - cie = succ.asExpr() and - ( - cie.getConstructor().getDeclaringType() instanceof JsonIoJsonReader or - cie.getConstructor().getDeclaringType() instanceof YamlBeansReader or - cie.getConstructor().getDeclaringType().getAnAncestor() instanceof UnsafeHessianInput or - cie.getConstructor().getDeclaringType() instanceof BurlapInput - ) - ) - or - exists(MethodAccess ma | - ma.getMethod() instanceof BurlapInputInitMethod and - ma.getArgument(0) = pred.asExpr() and - ma.getQualifier() = succ.asExpr() - ) - or - createJacksonJsonParserStep(pred, succ) - or - createJacksonTreeNodeStep(pred, succ) - or - intentFlowsToParcel(pred, succ) + isUnsafeDeserializationTaintStep(pred, succ) } - override predicate isSanitizer(DataFlow::Node node) { - exists(ClassInstanceExpr cie | - cie.getConstructor().getDeclaringType() instanceof JsonIoJsonReader and - cie = node.asExpr() and - exists(SafeJsonIoConfig sji | sji.hasFlowToExpr(cie.getArgument(1))) - ) - or - exists(MethodAccess ma | - ma.getMethod() instanceof JsonIoJsonToJavaMethod and - ma.getArgument(0) = node.asExpr() and - exists(SafeJsonIoConfig sji | sji.hasFlowToExpr(ma.getArgument(1))) - ) - or - exists(MethodAccess ma | - // Sanitize the input to jodd.json.JsonParser.parse et al whenever it appears - // to be called with an explicit class argument limiting those types that can - // be instantiated during deserialization. - ma.getMethod() instanceof JoddJsonParseMethod and - ma.getArgument(1).getType() instanceof TypeClass and - not ma.getArgument(1) instanceof NullLiteral and - not ma.getArgument(1).getType().getName() = ["Class", "Class"] and - node.asExpr() = ma.getAnArgument() - ) - or - exists(MethodAccess ma | - // Sanitize the input to flexjson.JSONDeserializer.deserialize whenever it appears - // to be called with an explicit class argument limiting those types that can - // be instantiated during deserialization, or if the deserializer has already been - // configured to use a specified root class. - ma.getMethod() instanceof FlexjsonDeserializeMethod and - node.asExpr() = ma.getAnArgument() and - ( - ma.getArgument(1).getType() instanceof TypeClass and - not ma.getArgument(1) instanceof NullLiteral and - not ma.getArgument(1).getType().getName() = ["Class", "Class"] - or - isSafeFlexjsonDeserializer(ma.getQualifier()) - ) - ) - } + override predicate isSanitizer(DataFlow::Node node) { isUnsafeDeserializationSanitizer(node) } } +/** Tracks flows from remote user input to a deserialization sink. */ +private module UnsafeDeserializationConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + + predicate isSink(DataFlow::Node sink) { sink instanceof UnsafeDeserializationSink } + + predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { + isUnsafeDeserializationTaintStep(pred, succ) + } + + predicate isBarrier(DataFlow::Node node) { isUnsafeDeserializationSanitizer(node) } +} + +module UnsafeDeserializationFlow = TaintTracking::Global; + /** * Gets a safe usage of the `use` method of Flexjson, which could be: * use(String, ...) where the path is null or @@ -350,18 +375,9 @@ predicate looksLikeResolveClassStep(DataFlow::Node fromNode, DataFlow::Node toNo ) } -/** - * Tracks flow from a remote source to a type descriptor (e.g. a `java.lang.Class` instance) - * passed to a deserialization method. - * - * If this is user-controlled, arbitrary code could be executed while instantiating the user-specified type. - */ -class UnsafeTypeConfig extends TaintTracking2::Configuration { - UnsafeTypeConfig() { this = "UnsafeTypeConfig" } - - override predicate isSource(DataFlow::Node src) { src instanceof RemoteFlowSource } - - override predicate isSink(DataFlow::Node sink) { +/** A sink representing an argument of a deserialization method */ +private class UnsafeTypeSink extends DataFlow::Node { + UnsafeTypeSink() { exists(MethodAccess ma, int i, Expr arg | i > 0 and ma.getArgument(i) = arg | ( ma.getMethod() instanceof ObjectMapperReadMethod @@ -378,25 +394,75 @@ class UnsafeTypeConfig extends TaintTracking2::Configuration { or arg.getType().(RefType).hasQualifiedName("java.lang.reflect", "Type") ) and - arg = sink.asExpr() + arg = this.asExpr() ) } +} + +private predicate isUnsafeTypeAdditionalTaintStep(DataFlow::Node fromNode, DataFlow::Node toNode) { + resolveClassStep(fromNode, toNode) or + looksLikeResolveClassStep(fromNode, toNode) or + intentFlowsToParcel(fromNode, toNode) +} + +/** + * DEPRECATED: Use `UnsafeTypeFlow` instead. + * + * Tracks flow from a remote source to a type descriptor (e.g. a `java.lang.Class` instance) + * passed to a deserialization method. + * + * If this is user-controlled, arbitrary code could be executed while instantiating the user-specified type. + */ +deprecated class UnsafeTypeConfig extends TaintTracking2::Configuration { + UnsafeTypeConfig() { this = "UnsafeTypeConfig" } + + override predicate isSource(DataFlow::Node src) { src instanceof RemoteFlowSource } + + override predicate isSink(DataFlow::Node sink) { sink instanceof UnsafeTypeSink } /** * Holds if `fromNode` to `toNode` is a dataflow step that resolves a class * or at least looks like resolving a class. */ override predicate isAdditionalTaintStep(DataFlow::Node fromNode, DataFlow::Node toNode) { - resolveClassStep(fromNode, toNode) or - looksLikeResolveClassStep(fromNode, toNode) or - intentFlowsToParcel(fromNode, toNode) + isUnsafeTypeAdditionalTaintStep(fromNode, toNode) } } /** + * Tracks flow from a remote source to a type descriptor (e.g. a `java.lang.Class` instance) + * passed to a deserialization method. + * + * If this is user-controlled, arbitrary code could be executed while instantiating the user-specified type. + */ +module UnsafeTypeConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { src instanceof RemoteFlowSource } + + predicate isSink(DataFlow::Node sink) { sink instanceof UnsafeTypeSink } + + /** + * Holds if `fromNode` to `toNode` is a dataflow step that resolves a class + * or at least looks like resolving a class. + */ + predicate isAdditionalFlowStep(DataFlow::Node fromNode, DataFlow::Node toNode) { + isUnsafeTypeAdditionalTaintStep(fromNode, toNode) + } +} + +/** + * Tracks flow from a remote source to a type descriptor (e.g. a `java.lang.Class` instance) + * passed to a deserialization method. + * + * If this is user-controlled, arbitrary code could be executed while instantiating the user-specified type. + */ +module UnsafeTypeFlow = TaintTracking::Global; + +/** + * DEPRECATED: Use `EnableJacksonDefaultTypingFlow` instead. + * * Tracks flow from `enableDefaultTyping` calls to a subsequent Jackson deserialization method call. */ -class EnableJacksonDefaultTypingConfig extends DataFlow2::Configuration { +deprecated class EnableJacksonDefaultTypingConfig extends DataFlow2::Configuration { EnableJacksonDefaultTypingConfig() { this = "EnableJacksonDefaultTypingConfig" } override predicate isSource(DataFlow::Node src) { @@ -406,13 +472,43 @@ class EnableJacksonDefaultTypingConfig extends DataFlow2::Configuration { override predicate isSink(DataFlow::Node sink) { sink instanceof ObjectMapperReadQualifier } } +private module EnableJacksonDefaultTypingConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { + any(EnableJacksonDefaultTyping ma).getQualifier() = src.asExpr() + } + + predicate isSink(DataFlow::Node sink) { sink instanceof ObjectMapperReadQualifier } +} + /** + * Tracks flow from `enableDefaultTyping` calls to a subsequent Jackson deserialization method call. + */ +module EnableJacksonDefaultTypingFlow = DataFlow::Global; + +/** Dataflow step that creates an `ObjectMapper` via a builder. */ +private predicate isObjectMapperBuilderAdditionalFlowStep( + DataFlow::Node fromNode, DataFlow::Node toNode +) { + exists(MethodAccess ma, Method m | m = ma.getMethod() | + m.getDeclaringType() instanceof MapperBuilder and + m.getReturnType() + .(RefType) + .hasQualifiedName("com.fasterxml.jackson.databind.json", + ["JsonMapper$Builder", "JsonMapper"]) and + fromNode.asExpr() = ma.getQualifier() and + ma = toNode.asExpr() + ) +} + +/** + * DEPRECATED: Use `SafeObjectMapperFlow` instead. + * * Tracks flow from calls that set a type validator to a subsequent Jackson deserialization method call, * including across builder method calls. * * Such a Jackson deserialization method call is safe because validation will likely prevent instantiating unexpected types. */ -class SafeObjectMapperConfig extends DataFlow2::Configuration { +deprecated class SafeObjectMapperConfig extends DataFlow2::Configuration { SafeObjectMapperConfig() { this = "SafeObjectMapperConfig" } override predicate isSource(DataFlow::Node src) { @@ -426,18 +522,38 @@ class SafeObjectMapperConfig extends DataFlow2::Configuration { * that configures or creates an `ObjectMapper` via a builder. */ override predicate isAdditionalFlowStep(DataFlow::Node fromNode, DataFlow::Node toNode) { - exists(MethodAccess ma, Method m | m = ma.getMethod() | - m.getDeclaringType() instanceof MapperBuilder and - m.getReturnType() - .(RefType) - .hasQualifiedName("com.fasterxml.jackson.databind.json", - ["JsonMapper$Builder", "JsonMapper"]) and - fromNode.asExpr() = ma.getQualifier() and - ma = toNode.asExpr() - ) + isObjectMapperBuilderAdditionalFlowStep(fromNode, toNode) } } +/** + * Tracks flow from calls that set a type validator to a subsequent Jackson deserialization method call, + * including across builder method calls. + * + * Such a Jackson deserialization method call is safe because validation will likely prevent instantiating unexpected types. + */ +module SafeObjectMapperConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { src instanceof SetPolymorphicTypeValidatorSource } + + predicate isSink(DataFlow::Node sink) { sink instanceof ObjectMapperReadQualifier } + + /** + * Holds if `fromNode` to `toNode` is a dataflow step + * that configures or creates an `ObjectMapper` via a builder. + */ + predicate isAdditionalFlowStep(DataFlow::Node fromNode, DataFlow::Node toNode) { + isObjectMapperBuilderAdditionalFlowStep(fromNode, toNode) + } +} + +/** + * Tracks flow from calls that set a type validator to a subsequent Jackson deserialization method call, + * including across builder method calls. + * + * Such a Jackson deserialization method call is safe because validation will likely prevent instantiating unexpected types. + */ +module SafeObjectMapperFlow = DataFlow::Global; + /** * A method that configures Jodd's JsonParser, either enabling dangerous deserialization to * arbitrary Java types or restricting the types that can be instantiated. @@ -454,20 +570,12 @@ private class JoddJsonParserConfigurationMethodQualifier extends DataFlow::ExprN } } -/** - * Configuration tracking flow from methods that configure `jodd.json.JsonParser`'s class - * instantiation feature to a `.parse` call on the same parser. - */ -private class JoddJsonParserConfigurationMethodConfig extends DataFlow2::Configuration { - JoddJsonParserConfigurationMethodConfig() { - this = "UnsafeDeserialization::JoddJsonParserConfigurationMethodConfig" - } - - override predicate isSource(DataFlow::Node src) { +private module JoddJsonParserConfigurationMethodConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { src instanceof JoddJsonParserConfigurationMethodQualifier } - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { exists(MethodAccess ma | ma.getMethod() instanceof JoddJsonParseMethod and sink.asExpr() = ma.getQualifier() // The class type argument @@ -475,6 +583,13 @@ private class JoddJsonParserConfigurationMethodConfig extends DataFlow2::Configu } } +/** + * Configuration tracking flow from methods that configure `jodd.json.JsonParser`'s class + * instantiation feature to a `.parse` call on the same parser. + */ +private module JoddJsonParserConfigurationMethodFlow = + DataFlow::Global; + /** * Gets the qualifier to a method call that configures a `jodd.json.JsonParser` instance unsafely. * @@ -512,10 +627,8 @@ private DataFlow::Node getASafelyConfiguredParser() { * and which never appears to be configured safely. */ private predicate joddJsonParserConfiguredUnsafely(Expr parserExpr) { - exists(DataFlow::Node parser, JoddJsonParserConfigurationMethodConfig config | - parser.asExpr() = parserExpr - | - config.hasFlow(getAnUnsafelyConfiguredParser(), parser) and - not config.hasFlow(getASafelyConfiguredParser(), parser) + exists(DataFlow::Node parser | parser.asExpr() = parserExpr | + JoddJsonParserConfigurationMethodFlow::flow(getAnUnsafelyConfiguredParser(), parser) and + not JoddJsonParserConfigurationMethodFlow::flow(getASafelyConfiguredParser(), parser) ) } diff --git a/java/ql/lib/semmle/code/java/security/XmlParsers.qll b/java/ql/lib/semmle/code/java/security/XmlParsers.qll index 8cdf962584d..dd28d8b0117 100644 --- a/java/ql/lib/semmle/code/java/security/XmlParsers.qll +++ b/java/ql/lib/semmle/code/java/security/XmlParsers.qll @@ -81,24 +81,18 @@ class DocumentBuilderParse extends XmlParserCall { override Expr getSink() { result = this.getArgument(0) } override predicate isSafe() { - exists(SafeDocumentBuilderToDocumentBuilderParseFlowConfig conf | - conf.hasFlowToExpr(this.getQualifier()) - ) + SafeDocumentBuilderToDocumentBuilderParseFlow::flowToExpr(this.getQualifier()) } } -private class SafeDocumentBuilderToDocumentBuilderParseFlowConfig extends DataFlow2::Configuration { - SafeDocumentBuilderToDocumentBuilderParseFlowConfig() { - this = "XmlParsers::SafeDocumentBuilderToDocumentBuilderParseFlowConfig" - } +private module SafeDocumentBuilderToDocumentBuilderParseFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeDocumentBuilder } - override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeDocumentBuilder } - - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { sink.asExpr() = any(DocumentBuilderParse dbp).getQualifier() } - override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { exists(RefType t, ReturnStmt ret, Method m | node2.asExpr().(ClassInstanceExpr).getConstructedType().getSourceDeclaration() = t and t.getASourceSupertype+().hasQualifiedName("java.lang", "ThreadLocal") and @@ -117,9 +111,12 @@ private class SafeDocumentBuilderToDocumentBuilderParseFlowConfig extends DataFl ) } - override int fieldFlowBranchLimit() { result = 0 } + int fieldFlowBranchLimit() { result = 0 } } +private module SafeDocumentBuilderToDocumentBuilderParseFlow = + DataFlow::Global; + /** * A `ParserConfig` specific to `DocumentBuilderFactory`. */ @@ -198,31 +195,27 @@ private class DocumentBuilderConstruction extends MethodAccess { } } -private class SafeDocumentBuilderFactoryToDocumentBuilderConstructionFlowConfig extends DataFlow3::Configuration +private module SafeDocumentBuilderFactoryToDocumentBuilderConstructionFlowConfig implements + DataFlow::ConfigSig { - SafeDocumentBuilderFactoryToDocumentBuilderConstructionFlowConfig() { - this = "XmlParsers::SafeDocumentBuilderFactoryToDocumentBuilderConstructionFlowConfig" - } + predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeDocumentBuilderFactory } - override predicate isSource(DataFlow::Node src) { - src.asExpr() instanceof SafeDocumentBuilderFactory - } - - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { sink.asExpr() = any(DocumentBuilderConstruction dbc).getQualifier() } - override int fieldFlowBranchLimit() { result = 0 } + int fieldFlowBranchLimit() { result = 0 } } +private module SafeDocumentBuilderFactoryToDocumentBuilderConstructionFlow = + DataFlow::Global; + /** * A `DocumentBuilder` created from a safely configured `DocumentBuilderFactory`. */ class SafeDocumentBuilder extends DocumentBuilderConstruction { SafeDocumentBuilder() { - exists(SafeDocumentBuilderFactoryToDocumentBuilderConstructionFlowConfig conf | - conf.hasFlowToExpr(this.getQualifier()) - ) + SafeDocumentBuilderFactoryToDocumentBuilderConstructionFlow::flowToExpr(this.getQualifier()) } } @@ -252,27 +245,24 @@ class XmlInputFactoryStreamReader extends XmlParserCall { } override predicate isSafe() { - exists(SafeXmlInputFactoryToXmlInputFactoryReaderFlowConfig conf | - conf.hasFlowToExpr(this.getQualifier()) - ) + SafeXmlInputFactoryToXmlInputFactoryReaderFlow::flowToExpr(this.getQualifier()) } } -private class SafeXmlInputFactoryToXmlInputFactoryReaderFlowConfig extends DataFlow2::Configuration { - SafeXmlInputFactoryToXmlInputFactoryReaderFlowConfig() { - this = "XmlParsers::SafeXmlInputFactoryToXmlInputFactoryReaderFlowConfig" - } +private module SafeXmlInputFactoryToXmlInputFactoryReaderFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeXmlInputFactory } - override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeXmlInputFactory } - - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { sink.asExpr() = any(XmlInputFactoryStreamReader xifsr).getQualifier() or sink.asExpr() = any(XmlInputFactoryEventReader xifer).getQualifier() } - override int fieldFlowBranchLimit() { result = 0 } + int fieldFlowBranchLimit() { result = 0 } } +private module SafeXmlInputFactoryToXmlInputFactoryReaderFlow = + DataFlow::Global; + /** A call to `XMLInputFactory.createEventReader`. */ class XmlInputFactoryEventReader extends XmlParserCall { XmlInputFactoryEventReader() { @@ -290,9 +280,7 @@ class XmlInputFactoryEventReader extends XmlParserCall { } override predicate isSafe() { - exists(SafeXmlInputFactoryToXmlInputFactoryReaderFlowConfig conf | - conf.hasFlowToExpr(this.getQualifier()) - ) + SafeXmlInputFactoryToXmlInputFactoryReaderFlow::flowToExpr(this.getQualifier()) } } @@ -387,27 +375,24 @@ class SaxBuilderParse extends XmlParserCall { override Expr getSink() { result = this.getArgument(0) } override predicate isSafe() { - exists(SafeSaxBuilderToSaxBuilderParseFlowConfig conf | conf.hasFlowToExpr(this.getQualifier())) + SafeSaxBuilderToSaxBuilderParseFlow::flowToExpr(this.getQualifier()) } } /** DEPRECATED: Alias for SaxBuilderParse */ deprecated class SAXBuilderParse = SaxBuilderParse; -private class SafeSaxBuilderToSaxBuilderParseFlowConfig extends DataFlow2::Configuration { - SafeSaxBuilderToSaxBuilderParseFlowConfig() { - this = "XmlParsers::SafeSAXBuilderToSAXBuilderParseFlowConfig" - } +private module SafeSaxBuilderToSaxBuilderParseFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeSaxBuilder } - override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeSaxBuilder } + predicate isSink(DataFlow::Node sink) { sink.asExpr() = any(SaxBuilderParse sax).getQualifier() } - override predicate isSink(DataFlow::Node sink) { - sink.asExpr() = any(SaxBuilderParse sax).getQualifier() - } - - override int fieldFlowBranchLimit() { result = 0 } + int fieldFlowBranchLimit() { result = 0 } } +private module SafeSaxBuilderToSaxBuilderParseFlow = + DataFlow::Global; + /** * A `ParserConfig` specific to `SAXBuilder`. */ @@ -478,9 +463,7 @@ class SaxParserParse extends XmlParserCall { override Expr getSink() { result = this.getArgument(0) } - override predicate isSafe() { - exists(SafeSaxParserFlowConfig sp | sp.hasFlowToExpr(this.getQualifier())) - } + override predicate isSafe() { SafeSaxParserFlow::flowToExpr(this.getQualifier()) } } /** DEPRECATED: Alias for SaxParserParse */ @@ -536,14 +519,10 @@ class SafeSaxParserFactory extends VarAccess { /** DEPRECATED: Alias for SafeSaxParserFactory */ deprecated class SafeSAXParserFactory = SafeSaxParserFactory; -private class SafeSaxParserFactoryToNewSaxParserFlowConfig extends DataFlow5::Configuration { - SafeSaxParserFactoryToNewSaxParserFlowConfig() { - this = "XmlParsers::SafeSAXParserFactoryToNewSAXParserFlowConfig" - } +private module SafeSaxParserFactoryToNewSaxParserFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeSaxParserFactory } - override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeSaxParserFactory } - - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { exists(MethodAccess ma, Method m | sink.asExpr() = ma.getQualifier() and ma.getMethod() = m and @@ -552,31 +531,32 @@ private class SafeSaxParserFactoryToNewSaxParserFlowConfig extends DataFlow5::Co ) } - override int fieldFlowBranchLimit() { result = 0 } + int fieldFlowBranchLimit() { result = 0 } } -private class SafeSaxParserFlowConfig extends DataFlow4::Configuration { - SafeSaxParserFlowConfig() { this = "XmlParsers::SafeSAXParserFlowConfig" } +private module SafeSaxParserFactoryToNewSaxParserFlow = + DataFlow::Global; - override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeSaxParser } +private module SafeSaxParserFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeSaxParser } - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { exists(MethodAccess ma | sink.asExpr() = ma.getQualifier() and ma.getMethod().getDeclaringType() instanceof SaxParser ) } - override int fieldFlowBranchLimit() { result = 0 } + int fieldFlowBranchLimit() { result = 0 } } +private module SafeSaxParserFlow = DataFlow::Global; + /** A `SaxParser` created from a safely configured `SaxParserFactory`. */ class SafeSaxParser extends MethodAccess { SafeSaxParser() { - exists(SafeSaxParserFactoryToNewSaxParserFlowConfig sdf | - this.getMethod().getDeclaringType() instanceof SaxParserFactory and - this.getMethod().hasName("newSAXParser") and - sdf.hasFlowToExpr(this.getQualifier()) - ) + this.getMethod().getDeclaringType() instanceof SaxParserFactory and + this.getMethod().hasName("newSAXParser") and + SafeSaxParserFactoryToNewSaxParserFlow::flowToExpr(this.getQualifier()) } } @@ -606,9 +586,7 @@ class SaxReaderRead extends XmlParserCall { override Expr getSink() { result = this.getArgument(0) } - override predicate isSafe() { - exists(SafeSaxReaderFlowConfig sr | sr.hasFlowToExpr(this.getQualifier())) - } + override predicate isSafe() { SafeSaxReaderFlow::flowToExpr(this.getQualifier()) } } /** DEPRECATED: Alias for SaxReaderRead */ @@ -628,20 +606,20 @@ class SaxReaderConfig extends ParserConfig { /** DEPRECATED: Alias for SaxReaderConfig */ deprecated class SAXReaderConfig = SaxReaderConfig; -private class SafeSaxReaderFlowConfig extends DataFlow4::Configuration { - SafeSaxReaderFlowConfig() { this = "XmlParsers::SafeSAXReaderFlowConfig" } +private module SafeSaxReaderFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeSaxReader } - override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeSaxReader } - - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { exists(MethodAccess ma | sink.asExpr() = ma.getQualifier() and ma.getMethod().getDeclaringType() instanceof SaxReader ) } - override int fieldFlowBranchLimit() { result = 0 } + int fieldFlowBranchLimit() { result = 0 } } +private module SafeSaxReaderFlow = DataFlow::Global; + /** A safely configured `SaxReader`. */ class SafeSaxReader extends VarAccess { SafeSaxReader() { @@ -715,18 +693,16 @@ class XmlReaderConfig extends ParserConfig { /** DEPRECATED: Alias for XmlReaderConfig */ deprecated class XMLReaderConfig = XmlReaderConfig; -private class ExplicitlySafeXmlReaderFlowConfig extends DataFlow3::Configuration { - ExplicitlySafeXmlReaderFlowConfig() { this = "XmlParsers::ExplicitlySafeXMLReaderFlowConfig" } +private module ExplicitlySafeXmlReaderFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { src.asExpr() instanceof ExplicitlySafeXmlReader } - override predicate isSource(DataFlow::Node src) { - src.asExpr() instanceof ExplicitlySafeXmlReader - } + predicate isSink(DataFlow::Node sink) { sink.asExpr() instanceof SafeXmlReaderFlowSink } - override predicate isSink(DataFlow::Node sink) { sink.asExpr() instanceof SafeXmlReaderFlowSink } - - override int fieldFlowBranchLimit() { result = 0 } + int fieldFlowBranchLimit() { result = 0 } } +private module ExplicitlySafeXmlReaderFlow = DataFlow::Global; + /** An argument to a safe XML reader. */ class SafeXmlReaderFlowSink extends Expr { SafeXmlReaderFlowSink() { @@ -774,40 +750,35 @@ class ExplicitlySafeXmlReader extends VarAccess { /** Holds if `SafeXmlReaderFlowSink` detects flow from this to `sink` */ predicate flowsTo(SafeXmlReaderFlowSink sink) { - any(ExplicitlySafeXmlReaderFlowConfig conf) - .hasFlow(DataFlow::exprNode(this), DataFlow::exprNode(sink)) + ExplicitlySafeXmlReaderFlow::flow(DataFlow::exprNode(this), DataFlow::exprNode(sink)) } } /** DEPRECATED: Alias for ExplicitlySafeXmlReader */ deprecated class ExplicitlySafeXMLReader = ExplicitlySafeXmlReader; -private class CreatedSafeXmlReaderFlowConfig extends DataFlow3::Configuration { - CreatedSafeXmlReaderFlowConfig() { this = "XmlParsers::CreatedSafeXMLReaderFlowConfig" } +private module CreatedSafeXmlReaderFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { src.asExpr() instanceof CreatedSafeXmlReader } - override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof CreatedSafeXmlReader } + predicate isSink(DataFlow::Node sink) { sink.asExpr() instanceof SafeXmlReaderFlowSink } - override predicate isSink(DataFlow::Node sink) { sink.asExpr() instanceof SafeXmlReaderFlowSink } - - override int fieldFlowBranchLimit() { result = 0 } + int fieldFlowBranchLimit() { result = 0 } } +private module CreatedSafeXmlReaderFlow = DataFlow::Global; + /** An `XmlReader` that is obtained from a safe source. */ class CreatedSafeXmlReader extends Call { CreatedSafeXmlReader() { //Obtained from SAXParser - exists(SafeSaxParserFlowConfig safeParser | - this.(MethodAccess).getMethod().getDeclaringType() instanceof SaxParser and - this.(MethodAccess).getMethod().hasName("getXMLReader") and - safeParser.hasFlowToExpr(this.getQualifier()) - ) + this.(MethodAccess).getMethod().getDeclaringType() instanceof SaxParser and + this.(MethodAccess).getMethod().hasName("getXMLReader") and + SafeSaxParserFlow::flowToExpr(this.getQualifier()) or //Obtained from SAXReader - exists(SafeSaxReaderFlowConfig safeReader | - this.(MethodAccess).getMethod().getDeclaringType() instanceof SaxReader and - this.(MethodAccess).getMethod().hasName("getXMLReader") and - safeReader.hasFlowToExpr(this.getQualifier()) - ) + this.(MethodAccess).getMethod().getDeclaringType() instanceof SaxReader and + this.(MethodAccess).getMethod().hasName("getXMLReader") and + SafeSaxReaderFlow::flowToExpr(this.getQualifier()) or exists(RefType secureReader, string package | this.(ClassInstanceExpr).getConstructedType() = secureReader and @@ -818,8 +789,7 @@ class CreatedSafeXmlReader extends Call { /** Holds if `CreatedSafeXmlReaderFlowConfig` detects flow from this to `sink` */ predicate flowsTo(SafeXmlReaderFlowSink sink) { - any(CreatedSafeXmlReaderFlowConfig conf) - .hasFlow(DataFlow::exprNode(this), DataFlow::exprNode(sink)) + CreatedSafeXmlReaderFlow::flow(DataFlow::exprNode(this), DataFlow::exprNode(sink)) } } @@ -975,26 +945,23 @@ class TransformerTransform extends XmlParserCall { override Expr getSink() { result = this.getArgument(0) } override predicate isSafe() { - exists(SafeTransformerToTransformerTransformFlowConfig st | - st.hasFlowToExpr(this.getQualifier()) - ) + SafeTransformerToTransformerTransformFlow::flowToExpr(this.getQualifier()) } } -private class SafeTransformerToTransformerTransformFlowConfig extends DataFlow2::Configuration { - SafeTransformerToTransformerTransformFlowConfig() { - this = "XmlParsers::SafeTransformerToTransformerTransformFlowConfig" - } +private module SafeTransformerToTransformerTransformFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeTransformer } - override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeTransformer } - - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { sink.asExpr() = any(TransformerTransform tt).getQualifier() } - override int fieldFlowBranchLimit() { result = 0 } + int fieldFlowBranchLimit() { result = 0 } } +private module SafeTransformerToTransformerTransformFlow = + DataFlow::Global; + /** A call to `Transformer.newTransformer` with source. */ class TransformerFactorySource extends XmlParserCall { TransformerFactorySource() { @@ -1007,9 +974,7 @@ class TransformerFactorySource extends XmlParserCall { override Expr getSink() { result = this.getArgument(0) } - override predicate isSafe() { - exists(SafeTransformerFactoryFlowConfig stf | stf.hasFlowToExpr(this.getQualifier())) - } + override predicate isSafe() { SafeTransformerFactoryFlow::flowToExpr(this.getQualifier()) } } /** A `ParserConfig` specific to `TransformerFactory`. */ @@ -1024,10 +989,12 @@ class TransformerFactoryConfig extends TransformerConfig { } /** + * DEPRECATED: Use `SafeTransformerFactoryFlow` instead. + * * A dataflow configuration that identifies `TransformerFactory` and `SAXTransformerFactory` * instances that have been safely configured. */ -class SafeTransformerFactoryFlowConfig extends DataFlow3::Configuration { +deprecated class SafeTransformerFactoryFlowConfig extends DataFlow3::Configuration { SafeTransformerFactoryFlowConfig() { this = "XmlParsers::SafeTransformerFactoryFlowConfig" } override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeTransformerFactory } @@ -1042,6 +1009,29 @@ class SafeTransformerFactoryFlowConfig extends DataFlow3::Configuration { override int fieldFlowBranchLimit() { result = 0 } } +/** + * A dataflow configuration that identifies `TransformerFactory` and `SAXTransformerFactory` + * instances that have been safely configured. + */ +module SafeTransformerFactoryFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeTransformerFactory } + + predicate isSink(DataFlow::Node sink) { + exists(MethodAccess ma | + sink.asExpr() = ma.getQualifier() and + ma.getMethod().getDeclaringType() instanceof TransformerFactory + ) + } + + int fieldFlowBranchLimit() { result = 0 } +} + +/** + * Identifies `TransformerFactory` and `SAXTransformerFactory` + * instances that have been safely configured. + */ +module SafeTransformerFactoryFlow = DataFlow::Global; + /** A safely configured `TransformerFactory`. */ class SafeTransformerFactory extends VarAccess { SafeTransformerFactory() { @@ -1059,11 +1049,11 @@ class SafeTransformerFactory extends VarAccess { /** A `Transformer` created from a safely configured `TransformerFactory`. */ class SafeTransformer extends MethodAccess { SafeTransformer() { - exists(SafeTransformerFactoryFlowConfig stf, Method m | + exists(Method m | this.getMethod() = m and m.getDeclaringType() instanceof TransformerFactory and m.hasName("newTransformer") and - stf.hasFlowToExpr(this.getQualifier()) + SafeTransformerFactoryFlow::flowToExpr(this.getQualifier()) ) } } @@ -1085,9 +1075,7 @@ class SaxTransformerFactoryNewXmlFilter extends XmlParserCall { override Expr getSink() { result = this.getArgument(0) } - override predicate isSafe() { - exists(SafeTransformerFactoryFlowConfig stf | stf.hasFlowToExpr(this.getQualifier())) - } + override predicate isSafe() { SafeTransformerFactoryFlow::flowToExpr(this.getQualifier()) } } /** DEPRECATED: Alias for SaxTransformerFactoryNewXmlFilter */ @@ -1123,26 +1111,23 @@ class SchemaFactoryNewSchema extends XmlParserCall { override Expr getSink() { result = this.getArgument(0) } override predicate isSafe() { - exists(SafeSchemaFactoryToSchemaFactoryNewSchemaFlowConfig ssf | - ssf.hasFlowToExpr(this.getQualifier()) - ) + SafeSchemaFactoryToSchemaFactoryNewSchemaFlow::flowToExpr(this.getQualifier()) } } -private class SafeSchemaFactoryToSchemaFactoryNewSchemaFlowConfig extends DataFlow2::Configuration { - SafeSchemaFactoryToSchemaFactoryNewSchemaFlowConfig() { - this = "XmlParsers::SafeSchemaFactoryToSchemaFactoryNewSchemaFlowConfig" - } +private module SafeSchemaFactoryToSchemaFactoryNewSchemaFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeSchemaFactory } - override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeSchemaFactory } - - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { sink.asExpr() = any(SchemaFactoryNewSchema sfns).getQualifier() } - override int fieldFlowBranchLimit() { result = 0 } + int fieldFlowBranchLimit() { result = 0 } } +private module SafeSchemaFactoryToSchemaFactoryNewSchemaFlow = + DataFlow::Global; + /** A safely configured `SchemaFactory`. */ class SafeSchemaFactory extends VarAccess { SafeSchemaFactory() { diff --git a/java/ql/lib/semmle/code/java/security/XssQuery.qll b/java/ql/lib/semmle/code/java/security/XssQuery.qll new file mode 100644 index 00000000000..5accb2ca585 --- /dev/null +++ b/java/ql/lib/semmle/code/java/security/XssQuery.qll @@ -0,0 +1,26 @@ +/** Provides a taint tracking configuration to track cross site scripting. */ + +import java +import semmle.code.java.dataflow.FlowSources +import semmle.code.java.dataflow.TaintTracking +import semmle.code.java.security.XSS + +/** + * A taint-tracking configuration for cross site scripting vulnerabilities. + */ +module XssConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + + predicate isSink(DataFlow::Node sink) { sink instanceof XssSink } + + predicate isBarrier(DataFlow::Node node) { node instanceof XssSanitizer } + + predicate isBarrierOut(DataFlow::Node node) { node instanceof XssSinkBarrier } + + predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + any(XssAdditionalTaintStep s).step(node1, node2) + } +} + +/** Tracks flow from remote sources to cross site scripting vulnerabilities. */ +module XssFlow = TaintTracking::Global; diff --git a/java/ql/lib/semmle/code/java/security/XxeQuery.qll b/java/ql/lib/semmle/code/java/security/XxeQuery.qll index e1df8a1e601..18f7dd9e357 100644 --- a/java/ql/lib/semmle/code/java/security/XxeQuery.qll +++ b/java/ql/lib/semmle/code/java/security/XxeQuery.qll @@ -1,7 +1,7 @@ /** Provides default definitions to be used in XXE queries. */ import java -private import semmle.code.java.dataflow.TaintTracking2 +private import semmle.code.java.dataflow.TaintTracking private import semmle.code.java.security.XmlParsers import semmle.code.java.security.Xxe @@ -11,7 +11,7 @@ import semmle.code.java.security.Xxe */ private class DefaultXxeSink extends XxeSink { DefaultXxeSink() { - not exists(SafeSaxSourceFlowConfig safeSource | safeSource.hasFlowTo(this)) and + not SafeSaxSourceFlow::flowTo(this) and exists(XmlParserCall parse | parse.getSink() = this.asExpr() and not parse.isSafe() @@ -22,14 +22,12 @@ private class DefaultXxeSink extends XxeSink { /** * A taint-tracking configuration for safe XML readers used to parse XML documents. */ -private class SafeSaxSourceFlowConfig extends TaintTracking2::Configuration { - SafeSaxSourceFlowConfig() { this = "SafeSaxSourceFlowConfig" } +private module SafeSaxSourceFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeSaxSource } - override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeSaxSource } + predicate isSink(DataFlow::Node sink) { sink.asExpr() = any(XmlParserCall parse).getSink() } - override predicate isSink(DataFlow::Node sink) { - sink.asExpr() = any(XmlParserCall parse).getSink() - } - - override int fieldFlowBranchLimit() { result = 0 } + int fieldFlowBranchLimit() { result = 0 } } + +private module SafeSaxSourceFlow = TaintTracking::Global; diff --git a/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll b/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll new file mode 100644 index 00000000000..6eaa372075b --- /dev/null +++ b/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll @@ -0,0 +1,44 @@ +/** Provides dataflow configurations to be used in ZipSlip queries. */ + +import java +import semmle.code.java.dataflow.TaintTracking +import semmle.code.java.security.PathSanitizer +private import semmle.code.java.dataflow.ExternalFlow + +/** + * A method that returns the name of an archive entry. + */ +private class ArchiveEntryNameMethod extends Method { + ArchiveEntryNameMethod() { + exists(RefType archiveEntry | + archiveEntry.hasQualifiedName("java.util.zip", "ZipEntry") or + archiveEntry.hasQualifiedName("org.apache.commons.compress.archivers", "ArchiveEntry") + | + this.getDeclaringType().getAnAncestor() = archiveEntry and + this.hasName("getName") + ) + } +} + +/** + * A taint-tracking configuration for reasoning about unsafe zip file extraction. + */ +module ZipSlipConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { + source.asExpr().(MethodAccess).getMethod() instanceof ArchiveEntryNameMethod + } + + predicate isSink(DataFlow::Node sink) { sink instanceof FileCreationSink } + + predicate isBarrier(DataFlow::Node node) { node instanceof PathInjectionSanitizer } +} + +/** Tracks flow from archive entries to file creation. */ +module ZipSlipFlow = TaintTracking::Global; + +/** + * A sink that represents a file creation, such as a file write, copy or move operation. + */ +private class FileCreationSink extends DataFlow::Node { + FileCreationSink() { sinkNode(this, "create-file") } +} diff --git a/java/ql/lib/semmle/code/java/security/regexp/PolynomialReDoSQuery.qll b/java/ql/lib/semmle/code/java/security/regexp/PolynomialReDoSQuery.qll index e85e130e381..4d7f963e968 100644 --- a/java/ql/lib/semmle/code/java/security/regexp/PolynomialReDoSQuery.qll +++ b/java/ql/lib/semmle/code/java/security/regexp/PolynomialReDoSQuery.qll @@ -65,7 +65,7 @@ deprecated predicate hasPolynomialReDoSResult( } /** A configuration for Polynomial ReDoS queries. */ -private module PolynomialRedosConfig implements DataFlow::ConfigSig { +module PolynomialRedosConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node src) { src instanceof RemoteFlowSource } predicate isSink(DataFlow::Node sink) { diff --git a/java/ql/lib/upgrades/934bf10b4bd34cf648893efcd1d0d7be9471d39f/old.dbscheme b/java/ql/lib/upgrades/934bf10b4bd34cf648893efcd1d0d7be9471d39f/old.dbscheme new file mode 100644 index 00000000000..934bf10b4bd --- /dev/null +++ b/java/ql/lib/upgrades/934bf10b4bd34cf648893efcd1d0d7be9471d39f/old.dbscheme @@ -0,0 +1,1242 @@ +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * javac A.java B.java C.java + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * javac A.java B.java C.java + */ + unique int id : @compilation, + int kind: int ref, + string cwd : string ref, + string name : string ref +); + +case @compilation.kind of + 1 = @javacompilation +| 2 = @kotlincompilation +; + +compilation_started( + int id : @compilation ref +) + +compilation_info( + int id : @compilation ref, + string info_key: string ref, + string info_value: string ref +) + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--javac-args` + * 2 | A.java + * 3 | B.java + * 4 | C.java + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | A.java + * 1 | B.java + * 2 | C.java + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * For each file recorded in `compilation_compiling_files`, + * there will be a corresponding row in + * `compilation_compiling_files_completed` once extraction + * of that file is complete. The `result` will indicate the + * extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +#keyset[id, num] +compilation_compiling_files_completed( + int id : @compilation ref, + int num : int ref, + int result : int ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * The `cpu_seconds` and `elapsed_seconds` are the CPU time and elapsed + * time (respectively) that the original compilation (not the extraction) + * took for compiler invocation `id`. + */ +compilation_compiler_times( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + * The `result` will indicate the extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref, + int result : int ref +); + +diagnostics( + unique int id: @diagnostic, + string generated_by: string ref, // TODO: Sync this with the other languages? + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/* + * External artifacts + */ + +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +snapshotDate( + unique date snapshotDate : date ref +); + +sourceLocationPrefix( + string prefix : string ref +); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id : @duplication, + string relativePath : string ref, + int equivClass : int ref +); + +similarCode( + unique int id : @similarity, + string 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 +); + +/* + * SMAP + */ + +smap_header( + int outputFileId: @file ref, + string outputFilename: string ref, + string defaultStratum: string ref +); + +smap_files( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + string inputFileName: string ref, + int inputFileId: @file ref +); + +smap_lines( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + int inputStartLine: int ref, + int inputLineCount: int ref, + int outputStartLine: int ref, + int outputLineIncrement: int ref +); + +/* + * Locations and files + */ + +@location = @location_default ; + +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 +); + +hasLocation( + int locatableid: @locatable ref, + int id: @location ref +); + +@sourceline = @locatable ; + +#keyset[element_id] +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 +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/* + * Java + */ + +cupackage( + unique int id: @file ref, + int packageid: @package ref +); + +#keyset[fileid,keyName] +jarManifestMain( + int fileid: @file ref, + string keyName: string ref, + string value: string ref +); + +#keyset[fileid,entryName,keyName] +jarManifestEntries( + int fileid: @file ref, + string entryName: string ref, + string keyName: string ref, + string value: string ref +); + +packages( + unique int id: @package, + string nodeName: string ref +); + +primitives( + unique int id: @primitive, + string nodeName: string ref +); + +modifiers( + unique int id: @modifier, + string nodeName: string ref +); + +/** + * An errortype is used when the extractor is unable to extract a type + * correctly for some reason. + */ +error_type( + unique int id: @errortype +); + +classes_or_interfaces( + unique int id: @classorinterface, + string nodeName: string ref, + int parentid: @package ref, + int sourceid: @classorinterface ref +); + +file_class( + int id: @classorinterface ref +); + +class_object( + unique int id: @classorinterface ref, + unique int instance: @field ref +); + +type_companion_object( + unique int id: @classorinterface ref, + unique int instance: @field ref, + unique int companion_object: @classorinterface ref +); + +kt_nullable_types( + unique int id: @kt_nullable_type, + int classid: @reftype ref +) + +kt_notnull_types( + unique int id: @kt_notnull_type, + int classid: @reftype ref +) + +kt_type_alias( + unique int id: @kt_type_alias, + string name: string ref, + int kttypeid: @kt_type ref +) + +@kt_type = @kt_nullable_type | @kt_notnull_type + +isInterface( + unique int id: @classorinterface ref +); + +isRecord( + unique int id: @classorinterface ref +); + +fielddecls( + unique int id: @fielddecl, + int parentid: @reftype ref +); + +#keyset[fieldId] #keyset[fieldDeclId,pos] +fieldDeclaredIn( + int fieldId: @field ref, + int fieldDeclId: @fielddecl ref, + int pos: int ref +); + +fields( + unique int id: @field, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @field ref +); + +fieldsKotlinType( + unique int id: @field ref, + int kttypeid: @kt_type ref +); + +constrs( + unique int id: @constructor, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @constructor ref +); + +constrsKotlinType( + unique int id: @constructor ref, + int kttypeid: @kt_type ref +); + +methods( + unique int id: @method, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @method ref +); + +methodsKotlinType( + unique int id: @method ref, + int kttypeid: @kt_type ref +); + +#keyset[parentid,pos] +params( + unique int id: @param, + int typeid: @type ref, + int pos: int ref, + int parentid: @callable ref, + int sourceid: @param ref +); + +paramsKotlinType( + unique int id: @param ref, + int kttypeid: @kt_type ref +); + +paramName( + unique int id: @param ref, + string nodeName: string ref +); + +isVarargsParam( + int param: @param ref +); + +exceptions( + unique int id: @exception, + int typeid: @type ref, + int parentid: @callable ref +); + +isAnnotType( + int interfaceid: @classorinterface ref +); + +isAnnotElem( + int methodid: @method ref +); + +annotValue( + int parentid: @annotation ref, + int id2: @method ref, + unique int value: @expr ref +); + +isEnumType( + int classid: @classorinterface ref +); + +isEnumConst( + int fieldid: @field ref +); + +#keyset[parentid,pos] +typeVars( + unique int id: @typevariable, + string nodeName: string ref, + int pos: int ref, + int kind: int ref, // deprecated + int parentid: @classorinterfaceorcallable ref +); + +wildcards( + unique int id: @wildcard, + string nodeName: string ref, + int kind: int ref +); + +#keyset[parentid,pos] +typeBounds( + unique int id: @typebound, + int typeid: @reftype ref, + int pos: int ref, + int parentid: @boundedtype ref +); + +#keyset[parentid,pos] +typeArgs( + int argumentid: @reftype ref, + int pos: int ref, + int parentid: @classorinterfaceorcallable ref +); + +isParameterized( + int memberid: @member ref +); + +isRaw( + int memberid: @member ref +); + +erasure( + unique int memberid: @member ref, + int erasureid: @member ref +); + +#keyset[classid] #keyset[parent] +isAnonymClass( + int classid: @classorinterface ref, + int parent: @classinstancexpr ref +); + +#keyset[typeid] #keyset[parent] +isLocalClassOrInterface( + int typeid: @classorinterface ref, + int parent: @localtypedeclstmt ref +); + +isDefConstr( + int constructorid: @constructor ref +); + +#keyset[exprId] +lambdaKind( + int exprId: @lambdaexpr ref, + int bodyKind: int ref +); + +arrays( + unique int id: @array, + string nodeName: string ref, + int elementtypeid: @type ref, + int dimension: int ref, + int componenttypeid: @type ref +); + +enclInReftype( + unique int child: @reftype ref, + int parent: @reftype ref +); + +extendsReftype( + int id1: @reftype ref, + int id2: @classorinterface ref +); + +implInterface( + int id1: @classorarray ref, + int id2: @classorinterface ref +); + +permits( + int id1: @classorinterface ref, + int id2: @classorinterface ref +); + +hasModifier( + int id1: @modifiable ref, + int id2: @modifier ref +); + +imports( + unique int id: @import, + int holder: @classorinterfaceorpackage ref, + string name: string ref, + int kind: int ref +); + +#keyset[parent,idx] +stmts( + unique int id: @stmt, + int kind: int ref, + int parent: @stmtparent ref, + int idx: int ref, + int bodydecl: @callable ref +); + +@stmtparent = @callable | @stmt | @switchexpr | @whenexpr| @stmtexpr; + +case @stmt.kind of + 0 = @block +| 1 = @ifstmt +| 2 = @forstmt +| 3 = @enhancedforstmt +| 4 = @whilestmt +| 5 = @dostmt +| 6 = @trystmt +| 7 = @switchstmt +| 8 = @synchronizedstmt +| 9 = @returnstmt +| 10 = @throwstmt +| 11 = @breakstmt +| 12 = @continuestmt +| 13 = @emptystmt +| 14 = @exprstmt +| 15 = @labeledstmt +| 16 = @assertstmt +| 17 = @localvariabledeclstmt +| 18 = @localtypedeclstmt +| 19 = @constructorinvocationstmt +| 20 = @superconstructorinvocationstmt +| 21 = @case +| 22 = @catchclause +| 23 = @yieldstmt +| 24 = @errorstmt +| 25 = @whenbranch +; + +#keyset[parent,idx] +exprs( + unique int id: @expr, + int kind: int ref, + int typeid: @type ref, + int parent: @exprparent ref, + int idx: int ref +); + +exprsKotlinType( + unique int id: @expr ref, + int kttypeid: @kt_type ref +); + +callableEnclosingExpr( + unique int id: @expr ref, + int callable_id: @callable ref +); + +statementEnclosingExpr( + unique int id: @expr ref, + int statement_id: @stmt ref +); + +isParenthesized( + unique int id: @expr ref, + int parentheses: int ref +); + +case @expr.kind of + 1 = @arrayaccess +| 2 = @arraycreationexpr +| 3 = @arrayinit +| 4 = @assignexpr +| 5 = @assignaddexpr +| 6 = @assignsubexpr +| 7 = @assignmulexpr +| 8 = @assigndivexpr +| 9 = @assignremexpr +| 10 = @assignandexpr +| 11 = @assignorexpr +| 12 = @assignxorexpr +| 13 = @assignlshiftexpr +| 14 = @assignrshiftexpr +| 15 = @assignurshiftexpr +| 16 = @booleanliteral +| 17 = @integerliteral +| 18 = @longliteral +| 19 = @floatingpointliteral +| 20 = @doubleliteral +| 21 = @characterliteral +| 22 = @stringliteral +| 23 = @nullliteral +| 24 = @mulexpr +| 25 = @divexpr +| 26 = @remexpr +| 27 = @addexpr +| 28 = @subexpr +| 29 = @lshiftexpr +| 30 = @rshiftexpr +| 31 = @urshiftexpr +| 32 = @andbitexpr +| 33 = @orbitexpr +| 34 = @xorbitexpr +| 35 = @andlogicalexpr +| 36 = @orlogicalexpr +| 37 = @ltexpr +| 38 = @gtexpr +| 39 = @leexpr +| 40 = @geexpr +| 41 = @eqexpr +| 42 = @neexpr +| 43 = @postincexpr +| 44 = @postdecexpr +| 45 = @preincexpr +| 46 = @predecexpr +| 47 = @minusexpr +| 48 = @plusexpr +| 49 = @bitnotexpr +| 50 = @lognotexpr +| 51 = @castexpr +| 52 = @newexpr +| 53 = @conditionalexpr +| 54 = @parexpr // deprecated +| 55 = @instanceofexpr +| 56 = @localvariabledeclexpr +| 57 = @typeliteral +| 58 = @thisaccess +| 59 = @superaccess +| 60 = @varaccess +| 61 = @methodaccess +| 62 = @unannotatedtypeaccess +| 63 = @arraytypeaccess +| 64 = @packageaccess +| 65 = @wildcardtypeaccess +| 66 = @declannotation +| 67 = @uniontypeaccess +| 68 = @lambdaexpr +| 69 = @memberref +| 70 = @annotatedtypeaccess +| 71 = @typeannotation +| 72 = @intersectiontypeaccess +| 73 = @switchexpr +| 74 = @errorexpr +| 75 = @whenexpr +| 76 = @getclassexpr +| 77 = @safecastexpr +| 78 = @implicitcastexpr +| 79 = @implicitnotnullexpr +| 80 = @implicitcoerciontounitexpr +| 81 = @notinstanceofexpr +| 82 = @stmtexpr +| 83 = @stringtemplateexpr +| 84 = @notnullexpr +| 85 = @unsafecoerceexpr +| 86 = @valueeqexpr +| 87 = @valueneexpr +| 88 = @propertyref +; + +/** Holds if this `when` expression was written as an `if` expression. */ +when_if(unique int id: @whenexpr ref); + +/** Holds if this `when` branch was written as an `else` branch. */ +when_branch_else(unique int id: @whenbranch ref); + +@classinstancexpr = @newexpr | @lambdaexpr | @memberref | @propertyref + +@annotation = @declannotation | @typeannotation +@typeaccess = @unannotatedtypeaccess | @annotatedtypeaccess + +@assignment = @assignexpr + | @assignop; + +@unaryassignment = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr; + +@assignop = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + | @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignurshiftexpr; + +@literal = @booleanliteral + | @integerliteral + | @longliteral + | @floatingpointliteral + | @doubleliteral + | @characterliteral + | @stringliteral + | @nullliteral; + +@binaryexpr = @mulexpr + | @divexpr + | @remexpr + | @addexpr + | @subexpr + | @lshiftexpr + | @rshiftexpr + | @urshiftexpr + | @andbitexpr + | @orbitexpr + | @xorbitexpr + | @andlogicalexpr + | @orlogicalexpr + | @ltexpr + | @gtexpr + | @leexpr + | @geexpr + | @eqexpr + | @neexpr + | @valueeqexpr + | @valueneexpr; + +@unaryexpr = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr + | @minusexpr + | @plusexpr + | @bitnotexpr + | @lognotexpr + | @notnullexpr; + +@caller = @classinstancexpr + | @methodaccess + | @constructorinvocationstmt + | @superconstructorinvocationstmt; + +callableBinding( + unique int callerid: @caller ref, + int callee: @callable ref +); + +memberRefBinding( + unique int id: @expr ref, + int callable: @callable ref +); + +propertyRefGetBinding( + unique int id: @expr ref, + int getter: @callable ref +); + +propertyRefFieldBinding( + unique int id: @expr ref, + int field: @field ref +); + +propertyRefSetBinding( + unique int id: @expr ref, + int setter: @callable ref +); + +@exprparent = @stmt | @expr | @whenbranch | @callable | @field | @fielddecl | @classorinterface | @param | @localvar | @typevariable; + +variableBinding( + unique int expr: @varaccess ref, + int variable: @variable ref +); + +@variable = @localscopevariable | @field; + +@localscopevariable = @localvar | @param; + +localvars( + unique int id: @localvar, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @localvariabledeclexpr ref +); + +localvarsKotlinType( + unique int id: @localvar ref, + int kttypeid: @kt_type ref +); + +@namedexprorstmt = @breakstmt + | @continuestmt + | @labeledstmt + | @literal; + +namestrings( + string name: string ref, + string value: string ref, + unique int parent: @namedexprorstmt ref +); + +/* + * Modules + */ + +#keyset[name] +modules( + unique int id: @module, + string name: string ref +); + +isOpen( + int id: @module ref +); + +#keyset[fileId] +cumodule( + int fileId: @file ref, + int moduleId: @module ref +); + +@directive = @requires + | @exports + | @opens + | @uses + | @provides + +#keyset[directive] +directives( + int id: @module ref, + int directive: @directive ref +); + +requires( + unique int id: @requires, + int target: @module ref +); + +isTransitive( + int id: @requires ref +); + +isStatic( + int id: @requires ref +); + +exports( + unique int id: @exports, + int target: @package ref +); + +exportsTo( + int id: @exports ref, + int target: @module ref +); + +opens( + unique int id: @opens, + int target: @package ref +); + +opensTo( + int id: @opens ref, + int target: @module ref +); + +uses( + unique int id: @uses, + string serviceInterface: string ref +); + +provides( + unique int id: @provides, + string serviceInterface: string ref +); + +providesWith( + int id: @provides ref, + string serviceImpl: string ref +); + +/* + * Javadoc + */ + +javadoc( + unique int id: @javadoc +); + +isNormalComment( + int commentid : @javadoc ref +); + +isEolComment( + int commentid : @javadoc ref +); + +hasJavadoc( + int documentableid: @member ref, + int javadocid: @javadoc ref +); + +#keyset[parentid,idx] +javadocTag( + unique int id: @javadocTag, + string name: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +#keyset[parentid,idx] +javadocText( + unique int id: @javadocText, + string text: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +@javadocParent = @javadoc | @javadocTag; +@javadocElement = @javadocTag | @javadocText; + +@classorinterfaceorpackage = @classorinterface | @package; +@classorinterfaceorcallable = @classorinterface | @callable; +@boundedtype = @typevariable | @wildcard; +@reftype = @classorinterface | @array | @boundedtype | @errortype; +@classorarray = @classorinterface | @array; +@type = @primitive | @reftype; +@callable = @method | @constructor; + +/** A program element that has a name. */ +@element = @package | @modifier | @annotation | @errortype | + @locatableElement; + +@locatableElement = @file | @primitive | @classorinterface | @method | @constructor | @param | @exception | @field | + @boundedtype | @array | @localvar | @expr | @stmt | @import | @fielddecl | @kt_type | @kt_type_alias | + @kt_property; + +@modifiable = @member_modifiable| @param | @localvar | @typevariable; + +@member_modifiable = @classorinterface | @method | @constructor | @field | @kt_property; + +@member = @method | @constructor | @field | @reftype ; + +/** A program element that has a location. */ +@locatable = @typebound | @javadoc | @javadocTag | @javadocText | @xmllocatable | @ktcomment | + @locatableElement; + +@top = @element | @locatable | @folder; + +/* + * 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; + +/* + * configuration files with key value pairs + */ + +configs( + unique int id: @config +); + +configNames( + unique int id: @configName, + int config: @config ref, + string name: string ref +); + +configValues( + unique int id: @configValue, + int config: @config ref, + string value: string ref +); + +configLocations( + int locatable: @configLocatable ref, + int location: @location_default ref +); + +@configLocatable = @config | @configName | @configValue; + +ktComments( + unique int id: @ktcomment, + int kind: int ref, + string text : string ref +) + +ktCommentSections( + unique int id: @ktcommentsection, + int comment: @ktcomment ref, + string content : string ref +) + +ktCommentSectionNames( + unique int id: @ktcommentsection ref, + string name : string ref +) + +ktCommentSectionSubjectNames( + unique int id: @ktcommentsection ref, + string subjectname : string ref +) + +#keyset[id, owner] +ktCommentOwners( + int id: @ktcomment ref, + int owner: @top ref +) + +ktExtensionFunctions( + unique int id: @method ref, + int typeid: @type ref, + int kttypeid: @kt_type ref +) + +ktProperties( + unique int id: @kt_property, + string nodeName: string ref +) + +ktPropertyGetters( + unique int id: @kt_property ref, + int getter: @method ref +) + +ktPropertySetters( + unique int id: @kt_property ref, + int setter: @method ref +) + +ktPropertyBackingFields( + unique int id: @kt_property ref, + int backingField: @field ref +) + +ktSyntheticBody( + unique int id: @callable ref, + int kind: int ref + // 1: ENUM_VALUES + // 2: ENUM_VALUEOF +) + +ktLocalFunction( + unique int id: @method ref +) + +ktInitializerAssignment( + unique int id: @assignexpr ref +) + +ktPropertyDelegates( + unique int id: @kt_property ref, + unique int variableId: @variable ref +) + +/** + * If `id` is a compiler generated element, then the kind indicates the + * reason that the compiler generated it. + * See `Element.compilerGeneratedReason()` for an explanation of what + * each `kind` means. + */ +compiler_generated( + unique int id: @element ref, + int kind: int ref +) + +ktFunctionOriginalNames( + unique int id: @method ref, + string name: string ref +) + +ktDataClasses( + unique int id: @classorinterface ref +) diff --git a/java/ql/lib/upgrades/934bf10b4bd34cf648893efcd1d0d7be9471d39f/semmlecode.dbscheme b/java/ql/lib/upgrades/934bf10b4bd34cf648893efcd1d0d7be9471d39f/semmlecode.dbscheme new file mode 100644 index 00000000000..7cbc85b1f3e --- /dev/null +++ b/java/ql/lib/upgrades/934bf10b4bd34cf648893efcd1d0d7be9471d39f/semmlecode.dbscheme @@ -0,0 +1,1255 @@ +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * javac A.java B.java C.java + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * javac A.java B.java C.java + */ + unique int id : @compilation, + int kind: int ref, + string cwd : string ref, + string name : string ref +); + +case @compilation.kind of + 1 = @javacompilation +| 2 = @kotlincompilation +; + +compilation_started( + int id : @compilation ref +) + +compilation_info( + int id : @compilation ref, + string info_key: string ref, + string info_value: string ref +) + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--javac-args` + * 2 | A.java + * 3 | B.java + * 4 | C.java + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The expanded arguments that were passed to the extractor for a + * compiler invocation. This is similar to `compilation_args`, but + * for a `@@@someFile` argument, it includes the arguments from that + * file, rather than just taking the argument literally. + */ +#keyset[id, num] +compilation_expanded_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | A.java + * 1 | B.java + * 2 | C.java + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * For each file recorded in `compilation_compiling_files`, + * there will be a corresponding row in + * `compilation_compiling_files_completed` once extraction + * of that file is complete. The `result` will indicate the + * extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +#keyset[id, num] +compilation_compiling_files_completed( + int id : @compilation ref, + int num : int ref, + int result : int ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * The `cpu_seconds` and `elapsed_seconds` are the CPU time and elapsed + * time (respectively) that the original compilation (not the extraction) + * took for compiler invocation `id`. + */ +compilation_compiler_times( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + * The `result` will indicate the extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref, + int result : int ref +); + +diagnostics( + unique int id: @diagnostic, + string generated_by: string ref, // TODO: Sync this with the other languages? + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/* + * External artifacts + */ + +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +snapshotDate( + unique date snapshotDate : date ref +); + +sourceLocationPrefix( + string prefix : string ref +); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id : @duplication, + string relativePath : string ref, + int equivClass : int ref +); + +similarCode( + unique int id : @similarity, + string 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 +); + +/* + * SMAP + */ + +smap_header( + int outputFileId: @file ref, + string outputFilename: string ref, + string defaultStratum: string ref +); + +smap_files( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + string inputFileName: string ref, + int inputFileId: @file ref +); + +smap_lines( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + int inputStartLine: int ref, + int inputLineCount: int ref, + int outputStartLine: int ref, + int outputLineIncrement: int ref +); + +/* + * Locations and files + */ + +@location = @location_default ; + +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 +); + +hasLocation( + int locatableid: @locatable ref, + int id: @location ref +); + +@sourceline = @locatable ; + +#keyset[element_id] +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 +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/* + * Java + */ + +cupackage( + unique int id: @file ref, + int packageid: @package ref +); + +#keyset[fileid,keyName] +jarManifestMain( + int fileid: @file ref, + string keyName: string ref, + string value: string ref +); + +#keyset[fileid,entryName,keyName] +jarManifestEntries( + int fileid: @file ref, + string entryName: string ref, + string keyName: string ref, + string value: string ref +); + +packages( + unique int id: @package, + string nodeName: string ref +); + +primitives( + unique int id: @primitive, + string nodeName: string ref +); + +modifiers( + unique int id: @modifier, + string nodeName: string ref +); + +/** + * An errortype is used when the extractor is unable to extract a type + * correctly for some reason. + */ +error_type( + unique int id: @errortype +); + +classes_or_interfaces( + unique int id: @classorinterface, + string nodeName: string ref, + int parentid: @package ref, + int sourceid: @classorinterface ref +); + +file_class( + int id: @classorinterface ref +); + +class_object( + unique int id: @classorinterface ref, + unique int instance: @field ref +); + +type_companion_object( + unique int id: @classorinterface ref, + unique int instance: @field ref, + unique int companion_object: @classorinterface ref +); + +kt_nullable_types( + unique int id: @kt_nullable_type, + int classid: @reftype ref +) + +kt_notnull_types( + unique int id: @kt_notnull_type, + int classid: @reftype ref +) + +kt_type_alias( + unique int id: @kt_type_alias, + string name: string ref, + int kttypeid: @kt_type ref +) + +@kt_type = @kt_nullable_type | @kt_notnull_type + +isInterface( + unique int id: @classorinterface ref +); + +isRecord( + unique int id: @classorinterface ref +); + +fielddecls( + unique int id: @fielddecl, + int parentid: @reftype ref +); + +#keyset[fieldId] #keyset[fieldDeclId,pos] +fieldDeclaredIn( + int fieldId: @field ref, + int fieldDeclId: @fielddecl ref, + int pos: int ref +); + +fields( + unique int id: @field, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @field ref +); + +fieldsKotlinType( + unique int id: @field ref, + int kttypeid: @kt_type ref +); + +constrs( + unique int id: @constructor, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @constructor ref +); + +constrsKotlinType( + unique int id: @constructor ref, + int kttypeid: @kt_type ref +); + +methods( + unique int id: @method, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @method ref +); + +methodsKotlinType( + unique int id: @method ref, + int kttypeid: @kt_type ref +); + +#keyset[parentid,pos] +params( + unique int id: @param, + int typeid: @type ref, + int pos: int ref, + int parentid: @callable ref, + int sourceid: @param ref +); + +paramsKotlinType( + unique int id: @param ref, + int kttypeid: @kt_type ref +); + +paramName( + unique int id: @param ref, + string nodeName: string ref +); + +isVarargsParam( + int param: @param ref +); + +exceptions( + unique int id: @exception, + int typeid: @type ref, + int parentid: @callable ref +); + +isAnnotType( + int interfaceid: @classorinterface ref +); + +isAnnotElem( + int methodid: @method ref +); + +annotValue( + int parentid: @annotation ref, + int id2: @method ref, + unique int value: @expr ref +); + +isEnumType( + int classid: @classorinterface ref +); + +isEnumConst( + int fieldid: @field ref +); + +#keyset[parentid,pos] +typeVars( + unique int id: @typevariable, + string nodeName: string ref, + int pos: int ref, + int kind: int ref, // deprecated + int parentid: @classorinterfaceorcallable ref +); + +wildcards( + unique int id: @wildcard, + string nodeName: string ref, + int kind: int ref +); + +#keyset[parentid,pos] +typeBounds( + unique int id: @typebound, + int typeid: @reftype ref, + int pos: int ref, + int parentid: @boundedtype ref +); + +#keyset[parentid,pos] +typeArgs( + int argumentid: @reftype ref, + int pos: int ref, + int parentid: @classorinterfaceorcallable ref +); + +isParameterized( + int memberid: @member ref +); + +isRaw( + int memberid: @member ref +); + +erasure( + unique int memberid: @member ref, + int erasureid: @member ref +); + +#keyset[classid] #keyset[parent] +isAnonymClass( + int classid: @classorinterface ref, + int parent: @classinstancexpr ref +); + +#keyset[typeid] #keyset[parent] +isLocalClassOrInterface( + int typeid: @classorinterface ref, + int parent: @localtypedeclstmt ref +); + +isDefConstr( + int constructorid: @constructor ref +); + +#keyset[exprId] +lambdaKind( + int exprId: @lambdaexpr ref, + int bodyKind: int ref +); + +arrays( + unique int id: @array, + string nodeName: string ref, + int elementtypeid: @type ref, + int dimension: int ref, + int componenttypeid: @type ref +); + +enclInReftype( + unique int child: @reftype ref, + int parent: @reftype ref +); + +extendsReftype( + int id1: @reftype ref, + int id2: @classorinterface ref +); + +implInterface( + int id1: @classorarray ref, + int id2: @classorinterface ref +); + +permits( + int id1: @classorinterface ref, + int id2: @classorinterface ref +); + +hasModifier( + int id1: @modifiable ref, + int id2: @modifier ref +); + +imports( + unique int id: @import, + int holder: @classorinterfaceorpackage ref, + string name: string ref, + int kind: int ref +); + +#keyset[parent,idx] +stmts( + unique int id: @stmt, + int kind: int ref, + int parent: @stmtparent ref, + int idx: int ref, + int bodydecl: @callable ref +); + +@stmtparent = @callable | @stmt | @switchexpr | @whenexpr| @stmtexpr; + +case @stmt.kind of + 0 = @block +| 1 = @ifstmt +| 2 = @forstmt +| 3 = @enhancedforstmt +| 4 = @whilestmt +| 5 = @dostmt +| 6 = @trystmt +| 7 = @switchstmt +| 8 = @synchronizedstmt +| 9 = @returnstmt +| 10 = @throwstmt +| 11 = @breakstmt +| 12 = @continuestmt +| 13 = @emptystmt +| 14 = @exprstmt +| 15 = @labeledstmt +| 16 = @assertstmt +| 17 = @localvariabledeclstmt +| 18 = @localtypedeclstmt +| 19 = @constructorinvocationstmt +| 20 = @superconstructorinvocationstmt +| 21 = @case +| 22 = @catchclause +| 23 = @yieldstmt +| 24 = @errorstmt +| 25 = @whenbranch +; + +#keyset[parent,idx] +exprs( + unique int id: @expr, + int kind: int ref, + int typeid: @type ref, + int parent: @exprparent ref, + int idx: int ref +); + +exprsKotlinType( + unique int id: @expr ref, + int kttypeid: @kt_type ref +); + +callableEnclosingExpr( + unique int id: @expr ref, + int callable_id: @callable ref +); + +statementEnclosingExpr( + unique int id: @expr ref, + int statement_id: @stmt ref +); + +isParenthesized( + unique int id: @expr ref, + int parentheses: int ref +); + +case @expr.kind of + 1 = @arrayaccess +| 2 = @arraycreationexpr +| 3 = @arrayinit +| 4 = @assignexpr +| 5 = @assignaddexpr +| 6 = @assignsubexpr +| 7 = @assignmulexpr +| 8 = @assigndivexpr +| 9 = @assignremexpr +| 10 = @assignandexpr +| 11 = @assignorexpr +| 12 = @assignxorexpr +| 13 = @assignlshiftexpr +| 14 = @assignrshiftexpr +| 15 = @assignurshiftexpr +| 16 = @booleanliteral +| 17 = @integerliteral +| 18 = @longliteral +| 19 = @floatingpointliteral +| 20 = @doubleliteral +| 21 = @characterliteral +| 22 = @stringliteral +| 23 = @nullliteral +| 24 = @mulexpr +| 25 = @divexpr +| 26 = @remexpr +| 27 = @addexpr +| 28 = @subexpr +| 29 = @lshiftexpr +| 30 = @rshiftexpr +| 31 = @urshiftexpr +| 32 = @andbitexpr +| 33 = @orbitexpr +| 34 = @xorbitexpr +| 35 = @andlogicalexpr +| 36 = @orlogicalexpr +| 37 = @ltexpr +| 38 = @gtexpr +| 39 = @leexpr +| 40 = @geexpr +| 41 = @eqexpr +| 42 = @neexpr +| 43 = @postincexpr +| 44 = @postdecexpr +| 45 = @preincexpr +| 46 = @predecexpr +| 47 = @minusexpr +| 48 = @plusexpr +| 49 = @bitnotexpr +| 50 = @lognotexpr +| 51 = @castexpr +| 52 = @newexpr +| 53 = @conditionalexpr +| 54 = @parexpr // deprecated +| 55 = @instanceofexpr +| 56 = @localvariabledeclexpr +| 57 = @typeliteral +| 58 = @thisaccess +| 59 = @superaccess +| 60 = @varaccess +| 61 = @methodaccess +| 62 = @unannotatedtypeaccess +| 63 = @arraytypeaccess +| 64 = @packageaccess +| 65 = @wildcardtypeaccess +| 66 = @declannotation +| 67 = @uniontypeaccess +| 68 = @lambdaexpr +| 69 = @memberref +| 70 = @annotatedtypeaccess +| 71 = @typeannotation +| 72 = @intersectiontypeaccess +| 73 = @switchexpr +| 74 = @errorexpr +| 75 = @whenexpr +| 76 = @getclassexpr +| 77 = @safecastexpr +| 78 = @implicitcastexpr +| 79 = @implicitnotnullexpr +| 80 = @implicitcoerciontounitexpr +| 81 = @notinstanceofexpr +| 82 = @stmtexpr +| 83 = @stringtemplateexpr +| 84 = @notnullexpr +| 85 = @unsafecoerceexpr +| 86 = @valueeqexpr +| 87 = @valueneexpr +| 88 = @propertyref +; + +/** Holds if this `when` expression was written as an `if` expression. */ +when_if(unique int id: @whenexpr ref); + +/** Holds if this `when` branch was written as an `else` branch. */ +when_branch_else(unique int id: @whenbranch ref); + +@classinstancexpr = @newexpr | @lambdaexpr | @memberref | @propertyref + +@annotation = @declannotation | @typeannotation +@typeaccess = @unannotatedtypeaccess | @annotatedtypeaccess + +@assignment = @assignexpr + | @assignop; + +@unaryassignment = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr; + +@assignop = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + | @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignurshiftexpr; + +@literal = @booleanliteral + | @integerliteral + | @longliteral + | @floatingpointliteral + | @doubleliteral + | @characterliteral + | @stringliteral + | @nullliteral; + +@binaryexpr = @mulexpr + | @divexpr + | @remexpr + | @addexpr + | @subexpr + | @lshiftexpr + | @rshiftexpr + | @urshiftexpr + | @andbitexpr + | @orbitexpr + | @xorbitexpr + | @andlogicalexpr + | @orlogicalexpr + | @ltexpr + | @gtexpr + | @leexpr + | @geexpr + | @eqexpr + | @neexpr + | @valueeqexpr + | @valueneexpr; + +@unaryexpr = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr + | @minusexpr + | @plusexpr + | @bitnotexpr + | @lognotexpr + | @notnullexpr; + +@caller = @classinstancexpr + | @methodaccess + | @constructorinvocationstmt + | @superconstructorinvocationstmt; + +callableBinding( + unique int callerid: @caller ref, + int callee: @callable ref +); + +memberRefBinding( + unique int id: @expr ref, + int callable: @callable ref +); + +propertyRefGetBinding( + unique int id: @expr ref, + int getter: @callable ref +); + +propertyRefFieldBinding( + unique int id: @expr ref, + int field: @field ref +); + +propertyRefSetBinding( + unique int id: @expr ref, + int setter: @callable ref +); + +@exprparent = @stmt | @expr | @whenbranch | @callable | @field | @fielddecl | @classorinterface | @param | @localvar | @typevariable; + +variableBinding( + unique int expr: @varaccess ref, + int variable: @variable ref +); + +@variable = @localscopevariable | @field; + +@localscopevariable = @localvar | @param; + +localvars( + unique int id: @localvar, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @localvariabledeclexpr ref +); + +localvarsKotlinType( + unique int id: @localvar ref, + int kttypeid: @kt_type ref +); + +@namedexprorstmt = @breakstmt + | @continuestmt + | @labeledstmt + | @literal; + +namestrings( + string name: string ref, + string value: string ref, + unique int parent: @namedexprorstmt ref +); + +/* + * Modules + */ + +#keyset[name] +modules( + unique int id: @module, + string name: string ref +); + +isOpen( + int id: @module ref +); + +#keyset[fileId] +cumodule( + int fileId: @file ref, + int moduleId: @module ref +); + +@directive = @requires + | @exports + | @opens + | @uses + | @provides + +#keyset[directive] +directives( + int id: @module ref, + int directive: @directive ref +); + +requires( + unique int id: @requires, + int target: @module ref +); + +isTransitive( + int id: @requires ref +); + +isStatic( + int id: @requires ref +); + +exports( + unique int id: @exports, + int target: @package ref +); + +exportsTo( + int id: @exports ref, + int target: @module ref +); + +opens( + unique int id: @opens, + int target: @package ref +); + +opensTo( + int id: @opens ref, + int target: @module ref +); + +uses( + unique int id: @uses, + string serviceInterface: string ref +); + +provides( + unique int id: @provides, + string serviceInterface: string ref +); + +providesWith( + int id: @provides ref, + string serviceImpl: string ref +); + +/* + * Javadoc + */ + +javadoc( + unique int id: @javadoc +); + +isNormalComment( + int commentid : @javadoc ref +); + +isEolComment( + int commentid : @javadoc ref +); + +hasJavadoc( + int documentableid: @member ref, + int javadocid: @javadoc ref +); + +#keyset[parentid,idx] +javadocTag( + unique int id: @javadocTag, + string name: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +#keyset[parentid,idx] +javadocText( + unique int id: @javadocText, + string text: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +@javadocParent = @javadoc | @javadocTag; +@javadocElement = @javadocTag | @javadocText; + +@classorinterfaceorpackage = @classorinterface | @package; +@classorinterfaceorcallable = @classorinterface | @callable; +@boundedtype = @typevariable | @wildcard; +@reftype = @classorinterface | @array | @boundedtype | @errortype; +@classorarray = @classorinterface | @array; +@type = @primitive | @reftype; +@callable = @method | @constructor; + +/** A program element that has a name. */ +@element = @package | @modifier | @annotation | @errortype | + @locatableElement; + +@locatableElement = @file | @primitive | @classorinterface | @method | @constructor | @param | @exception | @field | + @boundedtype | @array | @localvar | @expr | @stmt | @import | @fielddecl | @kt_type | @kt_type_alias | + @kt_property; + +@modifiable = @member_modifiable| @param | @localvar | @typevariable; + +@member_modifiable = @classorinterface | @method | @constructor | @field | @kt_property; + +@member = @method | @constructor | @field | @reftype ; + +/** A program element that has a location. */ +@locatable = @typebound | @javadoc | @javadocTag | @javadocText | @xmllocatable | @ktcomment | + @locatableElement; + +@top = @element | @locatable | @folder; + +/* + * 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; + +/* + * configuration files with key value pairs + */ + +configs( + unique int id: @config +); + +configNames( + unique int id: @configName, + int config: @config ref, + string name: string ref +); + +configValues( + unique int id: @configValue, + int config: @config ref, + string value: string ref +); + +configLocations( + int locatable: @configLocatable ref, + int location: @location_default ref +); + +@configLocatable = @config | @configName | @configValue; + +ktComments( + unique int id: @ktcomment, + int kind: int ref, + string text : string ref +) + +ktCommentSections( + unique int id: @ktcommentsection, + int comment: @ktcomment ref, + string content : string ref +) + +ktCommentSectionNames( + unique int id: @ktcommentsection ref, + string name : string ref +) + +ktCommentSectionSubjectNames( + unique int id: @ktcommentsection ref, + string subjectname : string ref +) + +#keyset[id, owner] +ktCommentOwners( + int id: @ktcomment ref, + int owner: @top ref +) + +ktExtensionFunctions( + unique int id: @method ref, + int typeid: @type ref, + int kttypeid: @kt_type ref +) + +ktProperties( + unique int id: @kt_property, + string nodeName: string ref +) + +ktPropertyGetters( + unique int id: @kt_property ref, + int getter: @method ref +) + +ktPropertySetters( + unique int id: @kt_property ref, + int setter: @method ref +) + +ktPropertyBackingFields( + unique int id: @kt_property ref, + int backingField: @field ref +) + +ktSyntheticBody( + unique int id: @callable ref, + int kind: int ref + // 1: ENUM_VALUES + // 2: ENUM_VALUEOF +) + +ktLocalFunction( + unique int id: @method ref +) + +ktInitializerAssignment( + unique int id: @assignexpr ref +) + +ktPropertyDelegates( + unique int id: @kt_property ref, + unique int variableId: @variable ref +) + +/** + * If `id` is a compiler generated element, then the kind indicates the + * reason that the compiler generated it. + * See `Element.compilerGeneratedReason()` for an explanation of what + * each `kind` means. + */ +compiler_generated( + unique int id: @element ref, + int kind: int ref +) + +ktFunctionOriginalNames( + unique int id: @method ref, + string name: string ref +) + +ktDataClasses( + unique int id: @classorinterface ref +) diff --git a/java/ql/lib/upgrades/934bf10b4bd34cf648893efcd1d0d7be9471d39f/upgrade.properties b/java/ql/lib/upgrades/934bf10b4bd34cf648893efcd1d0d7be9471d39f/upgrade.properties new file mode 100644 index 00000000000..652e17fd503 --- /dev/null +++ b/java/ql/lib/upgrades/934bf10b4bd34cf648893efcd1d0d7be9471d39f/upgrade.properties @@ -0,0 +1,2 @@ +description: Add compilation_expanded_args +compatibility: backwards diff --git a/java/ql/src/Security/CWE/CWE-020/UntrustedDataToExternalAPI.ql b/java/ql/src/Security/CWE/CWE-020/UntrustedDataToExternalAPI.ql index b4a2e209513..fdbb34b2247 100644 --- a/java/ql/src/Security/CWE/CWE-020/UntrustedDataToExternalAPI.ql +++ b/java/ql/src/Security/CWE/CWE-020/UntrustedDataToExternalAPI.ql @@ -13,10 +13,10 @@ import java import semmle.code.java.dataflow.FlowSources import semmle.code.java.dataflow.TaintTracking import semmle.code.java.security.ExternalAPIs -import DataFlow::PathGraph +import UntrustedDataToExternalApiFlow::PathGraph -from UntrustedDataToExternalApiConfig config, DataFlow::PathNode source, DataFlow::PathNode sink -where config.hasFlowPath(source, sink) +from UntrustedDataToExternalApiFlow::PathNode source, UntrustedDataToExternalApiFlow::PathNode sink +where UntrustedDataToExternalApiFlow::flowPath(source, sink) select sink, source, sink, "Call to " + sink.getNode().(ExternalApiDataNode).getMethodDescription() + " with untrusted data from $@.", source, source.toString() diff --git a/java/ql/src/Security/CWE/CWE-022/TaintedPath.ql b/java/ql/src/Security/CWE/CWE-022/TaintedPath.ql index 4058978f29a..2d73514d97b 100644 --- a/java/ql/src/Security/CWE/CWE-022/TaintedPath.ql +++ b/java/ql/src/Security/CWE/CWE-022/TaintedPath.ql @@ -14,36 +14,8 @@ */ import java -import semmle.code.java.dataflow.FlowSources -private import semmle.code.java.dataflow.ExternalFlow -import semmle.code.java.security.PathCreation -import semmle.code.java.security.PathSanitizer -import TaintedPathCommon - -module TaintedPathConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } - - predicate isSink(DataFlow::Node sink) { - sink.asExpr() = any(PathCreation p).getAnInput() - or - sinkNode(sink, ["create-file", "read-file"]) - } - - predicate isBarrier(DataFlow::Node sanitizer) { - sanitizer.getType() instanceof BoxedType or - sanitizer.getType() instanceof PrimitiveType or - sanitizer.getType() instanceof NumberType or - sanitizer instanceof PathInjectionSanitizer - } - - predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) { - any(TaintedPathAdditionalTaintStep s).step(n1, n2) - } -} - -module TaintedPath = TaintTracking::Global; - -import TaintedPath::PathGraph +import semmle.code.java.security.TaintedPathQuery +import TaintedPathFlow::PathGraph /** * Gets the data-flow node at which to report a path ending at `sink`. @@ -53,13 +25,13 @@ import TaintedPath::PathGraph * continue to report there; otherwise we report directly at `sink`. */ DataFlow::Node getReportingNode(DataFlow::Node sink) { - TaintedPath::flowTo(sink) and + TaintedPathFlow::flowTo(sink) and if exists(PathCreation pc | pc.getAnInput() = sink.asExpr()) then result.asExpr() = any(PathCreation pc | pc.getAnInput() = sink.asExpr()) else result = sink } -from TaintedPath::PathNode source, TaintedPath::PathNode sink -where TaintedPath::flowPath(source, sink) +from TaintedPathFlow::PathNode source, TaintedPathFlow::PathNode sink +where TaintedPathFlow::flowPath(source, sink) select getReportingNode(sink.getNode()), source, sink, "This path depends on a $@.", source.getNode(), "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-022/TaintedPathCommon.qll b/java/ql/src/Security/CWE/CWE-022/TaintedPathCommon.qll deleted file mode 100644 index 418931d9a0d..00000000000 --- a/java/ql/src/Security/CWE/CWE-022/TaintedPathCommon.qll +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Models a very basic guard for the tainted path queries. - */ - -import java -import semmle.code.java.frameworks.Networking -import semmle.code.java.dataflow.DataFlow - -/** - * A unit class for adding additional taint steps. - * - * Extend this class to add additional taint steps that should apply to tainted path flow configurations. - */ -class TaintedPathAdditionalTaintStep extends Unit { - abstract predicate step(DataFlow::Node n1, DataFlow::Node n2); -} - -private class DefaultTaintedPathAdditionalTaintStep extends TaintedPathAdditionalTaintStep { - override predicate step(DataFlow::Node n1, DataFlow::Node n2) { - exists(Argument a | - a = n1.asExpr() and - a.getCall() = n2.asExpr() and - a = any(TaintPreservingUriCtorParam tpp).getAnArgument() - ) - } -} - -private class TaintPreservingUriCtorParam extends Parameter { - TaintPreservingUriCtorParam() { - exists(Constructor ctor, int idx, int nParams | - ctor.getDeclaringType() instanceof TypeUri and - this = ctor.getParameter(idx) and - nParams = ctor.getNumberOfParameters() - | - // URI(String scheme, String ssp, String fragment) - idx = 1 and nParams = 3 - or - // URI(String scheme, String host, String path, String fragment) - idx = [1, 2] and nParams = 4 - or - // URI(String scheme, String authority, String path, String query, String fragment) - idx = 2 and nParams = 5 - or - // URI(String scheme, String userInfo, String host, int port, String path, String query, String fragment) - idx = 4 and nParams = 7 - ) - } -} diff --git a/java/ql/src/Security/CWE/CWE-022/TaintedPathLocal.ql b/java/ql/src/Security/CWE/CWE-022/TaintedPathLocal.ql index 94c2b0e68a0..c017b8a3aa9 100644 --- a/java/ql/src/Security/CWE/CWE-022/TaintedPathLocal.ql +++ b/java/ql/src/Security/CWE/CWE-022/TaintedPathLocal.ql @@ -14,35 +14,7 @@ */ import java -import semmle.code.java.dataflow.FlowSources -private import semmle.code.java.dataflow.ExternalFlow -import semmle.code.java.security.PathCreation -import semmle.code.java.security.PathSanitizer -import TaintedPathCommon - -module TaintedPathLocalConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof LocalUserInput } - - predicate isSink(DataFlow::Node sink) { - sink.asExpr() = any(PathCreation p).getAnInput() - or - sinkNode(sink, "create-file") - } - - predicate isBarrier(DataFlow::Node sanitizer) { - sanitizer.getType() instanceof BoxedType or - sanitizer.getType() instanceof PrimitiveType or - sanitizer.getType() instanceof NumberType or - sanitizer instanceof PathInjectionSanitizer - } - - predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) { - any(TaintedPathAdditionalTaintStep s).step(n1, n2) - } -} - -module TaintedPathLocalFlow = TaintTracking::Global; - +import semmle.code.java.security.TaintedPathQuery import TaintedPathLocalFlow::PathGraph /** diff --git a/java/ql/src/Security/CWE/CWE-022/ZipSlip.ql b/java/ql/src/Security/CWE/CWE-022/ZipSlip.ql index b1afdfe65a4..3488c97c057 100644 --- a/java/ql/src/Security/CWE/CWE-022/ZipSlip.ql +++ b/java/ql/src/Security/CWE/CWE-022/ZipSlip.ql @@ -13,48 +13,9 @@ */ import java -import semmle.code.java.controlflow.Guards -import semmle.code.java.dataflow.SSA -import semmle.code.java.dataflow.TaintTracking -import semmle.code.java.security.PathSanitizer -private import semmle.code.java.dataflow.ExternalFlow - -/** - * A method that returns the name of an archive entry. - */ -class ArchiveEntryNameMethod extends Method { - ArchiveEntryNameMethod() { - exists(RefType archiveEntry | - archiveEntry.hasQualifiedName("java.util.zip", "ZipEntry") or - archiveEntry.hasQualifiedName("org.apache.commons.compress.archivers", "ArchiveEntry") - | - this.getDeclaringType().getAnAncestor() = archiveEntry and - this.hasName("getName") - ) - } -} - -module ZipSlipConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { - source.asExpr().(MethodAccess).getMethod() instanceof ArchiveEntryNameMethod - } - - predicate isSink(DataFlow::Node sink) { sink instanceof FileCreationSink } - - predicate isBarrier(DataFlow::Node node) { node instanceof PathInjectionSanitizer } -} - -module ZipSlipFlow = TaintTracking::Global; - +import semmle.code.java.security.ZipSlipQuery import ZipSlipFlow::PathGraph -/** - * A sink that represents a file creation, such as a file write, copy or move operation. - */ -private class FileCreationSink extends DataFlow::Node { - FileCreationSink() { sinkNode(this, "create-file") } -} - from ZipSlipFlow::PathNode source, ZipSlipFlow::PathNode sink where ZipSlipFlow::flowPath(source, sink) select source.getNode(), source, sink, diff --git a/java/ql/src/Security/CWE/CWE-023/PartialPathTraversalBad.java b/java/ql/src/Security/CWE/CWE-023/PartialPathTraversalBad.java index e933679aa44..961d8c21c6b 100644 --- a/java/ql/src/Security/CWE/CWE-023/PartialPathTraversalBad.java +++ b/java/ql/src/Security/CWE/CWE-023/PartialPathTraversalBad.java @@ -1,7 +1,7 @@ public class PartialPathTraversalBad { public void example(File dir, File parent) throws IOException { if (!dir.getCanonicalPath().startsWith(parent.getCanonicalPath())) { - throw new IOException("Invalid directory: " + dir.getCanonicalPath()); + throw new IOException("Path traversal attempt: " + dir.getCanonicalPath()); } } } diff --git a/java/ql/src/Security/CWE/CWE-023/PartialPathTraversalFromRemote.ql b/java/ql/src/Security/CWE/CWE-023/PartialPathTraversalFromRemote.ql index 8ef4ab45853..ef62f433ae6 100644 --- a/java/ql/src/Security/CWE/CWE-023/PartialPathTraversalFromRemote.ql +++ b/java/ql/src/Security/CWE/CWE-023/PartialPathTraversalFromRemote.ql @@ -11,10 +11,12 @@ */ import semmle.code.java.security.PartialPathTraversalQuery -import DataFlow::PathGraph +import PartialPathTraversalFromRemoteFlow::PathGraph -from DataFlow::PathNode source, DataFlow::PathNode sink -where any(PartialPathTraversalFromRemoteConfig config).hasFlowPath(source, sink) +from + PartialPathTraversalFromRemoteFlow::PathNode source, + PartialPathTraversalFromRemoteFlow::PathNode sink +where PartialPathTraversalFromRemoteFlow::flowPath(source, sink) select sink.getNode(), source, sink, "Partial Path Traversal Vulnerability due to insufficient guard against path traversal from $@.", source, "user-supplied data" diff --git a/java/ql/src/Security/CWE/CWE-023/PartialPathTraversalGood.java b/java/ql/src/Security/CWE/CWE-023/PartialPathTraversalGood.java index baf4ef8545e..65392373a25 100644 --- a/java/ql/src/Security/CWE/CWE-023/PartialPathTraversalGood.java +++ b/java/ql/src/Security/CWE/CWE-023/PartialPathTraversalGood.java @@ -1,7 +1,9 @@ +import java.io.File; + public class PartialPathTraversalGood { public void example(File dir, File parent) throws IOException { - if (!dir.getCanonicalPath().startsWith(parent.getCanonicalPath() + File.separator)) { - throw new IOException("Invalid directory: " + dir.getCanonicalPath()); + if (!dir.toPath().normalize().startsWith(parent.toPath())) { + throw new IOException("Path traversal attempt: " + dir.getCanonicalPath()); } } } diff --git a/java/ql/src/Security/CWE/CWE-023/PartialPathTraversalRemainder.inc.qhelp b/java/ql/src/Security/CWE/CWE-023/PartialPathTraversalRemainder.inc.qhelp index 7703f5c52ff..342d38ac5c2 100644 --- a/java/ql/src/Security/CWE/CWE-023/PartialPathTraversalRemainder.inc.qhelp +++ b/java/ql/src/Security/CWE/CWE-023/PartialPathTraversalRemainder.inc.qhelp @@ -26,10 +26,9 @@ and not just children of parent, which is a security issue.

-In this example, the if statement checks if parent.getCanonicalPath() + File.separator -is a prefix of dir.getCanonicalPath(). Because parent.getCanonicalPath() + File.separator is -indeed slash-terminated, the user supplying dir can only access children of -parent, as desired. +In this example, the if statement checks if parent.toPath() +is a prefix of dir.normalize(). Because Path#startsWith does the correct check that +dir is a child of parent, users will not be able to access siblings of parent, as desired.

diff --git a/java/ql/src/Security/CWE/CWE-079/XSS.ql b/java/ql/src/Security/CWE/CWE-079/XSS.ql index dbec746eaf6..9ae92a7e362 100644 --- a/java/ql/src/Security/CWE/CWE-079/XSS.ql +++ b/java/ql/src/Security/CWE/CWE-079/XSS.ql @@ -12,25 +12,7 @@ */ import java -import semmle.code.java.dataflow.FlowSources -import semmle.code.java.security.XSS - -module XssConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } - - predicate isSink(DataFlow::Node sink) { sink instanceof XssSink } - - predicate isBarrier(DataFlow::Node node) { node instanceof XssSanitizer } - - predicate isBarrierOut(DataFlow::Node node) { node instanceof XssSinkBarrier } - - predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - any(XssAdditionalTaintStep s).step(node1, node2) - } -} - -module XssFlow = TaintTracking::Global; - +import semmle.code.java.security.XssQuery import XssFlow::PathGraph from XssFlow::PathNode source, XssFlow::PathNode sink diff --git a/java/ql/src/Security/CWE/CWE-090/LdapInjection.ql b/java/ql/src/Security/CWE/CWE-090/LdapInjection.ql index e879a33051d..e511cb8819c 100644 --- a/java/ql/src/Security/CWE/CWE-090/LdapInjection.ql +++ b/java/ql/src/Security/CWE/CWE-090/LdapInjection.ql @@ -13,7 +13,7 @@ import java import semmle.code.java.dataflow.FlowSources -import LdapInjectionLib +import semmle.code.java.security.LdapInjectionQuery import LdapInjectionFlow::PathGraph from LdapInjectionFlow::PathNode source, LdapInjectionFlow::PathNode sink diff --git a/java/ql/src/Security/CWE/CWE-094/InsecureBeanValidation.ql b/java/ql/src/Security/CWE/CWE-094/InsecureBeanValidation.ql index 5e957f23793..2dd0bf617ba 100644 --- a/java/ql/src/Security/CWE/CWE-094/InsecureBeanValidation.ql +++ b/java/ql/src/Security/CWE/CWE-094/InsecureBeanValidation.ql @@ -11,68 +11,9 @@ */ import java -import semmle.code.java.dataflow.TaintTracking -import semmle.code.java.dataflow.FlowSources -private import semmle.code.java.dataflow.ExternalFlow - -/** - * A message interpolator Type that perform Expression Language (EL) evaluations - */ -class ELMessageInterpolatorType extends RefType { - ELMessageInterpolatorType() { - this.getASourceSupertype*() - .hasQualifiedName("org.hibernate.validator.messageinterpolation", - ["ResourceBundleMessageInterpolator", "ValueFormatterMessageInterpolator"]) - } -} - -/** - * A method call that sets the application's default message interpolator. - */ -class SetMessageInterpolatorCall extends MethodAccess { - SetMessageInterpolatorCall() { - exists(Method m, RefType t | - this.getMethod() = m and - m.getDeclaringType().getASourceSupertype*() = t and - ( - t.hasQualifiedName("javax.validation", ["Configuration", "ValidatorContext"]) and - m.getName() = "messageInterpolator" - or - t.hasQualifiedName("org.springframework.validation.beanvalidation", - ["CustomValidatorBean", "LocalValidatorFactoryBean"]) and - m.getName() = "setMessageInterpolator" - ) - ) - } - - /** - * The message interpolator is likely to be safe, because it does not process Java Expression Language expressions. - */ - predicate isSafe() { not this.getAnArgument().getType() instanceof ELMessageInterpolatorType } -} - -/** - * Taint tracking BeanValidationConfiguration describing the flow of data from user input - * to the argument of a method that builds constraint error messages. - */ -module BeanValidationConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } - - predicate isSink(DataFlow::Node sink) { sink instanceof BeanValidationSink } -} - -module BeanValidationFlow = TaintTracking::Global; - +import semmle.code.java.security.InsecureBeanValidationQuery import BeanValidationFlow::PathGraph -/** - * A bean validation sink, such as method `buildConstraintViolationWithTemplate` - * declared on a subtype of `javax.validation.ConstraintValidatorContext`. - */ -private class BeanValidationSink extends DataFlow::Node { - BeanValidationSink() { sinkNode(this, "bean-validation") } -} - from BeanValidationFlow::PathNode source, BeanValidationFlow::PathNode sink where ( diff --git a/java/ql/src/Security/CWE/CWE-113/ResponseSplitting.ql b/java/ql/src/Security/CWE/CWE-113/ResponseSplitting.ql index 4fef0a620cd..2138d9187a1 100644 --- a/java/ql/src/Security/CWE/CWE-113/ResponseSplitting.ql +++ b/java/ql/src/Security/CWE/CWE-113/ResponseSplitting.ql @@ -12,42 +12,11 @@ */ import java -import semmle.code.java.dataflow.FlowSources -import semmle.code.java.security.ResponseSplitting +import semmle.code.java.security.ResponseSplittingQuery +import ResponseSplittingFlow::PathGraph -module ResponseSplittingConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { - source instanceof RemoteFlowSource and - not source instanceof SafeHeaderSplittingSource - } - - predicate isSink(DataFlow::Node sink) { sink instanceof HeaderSplittingSink } - - predicate isBarrier(DataFlow::Node node) { - node.getType() instanceof PrimitiveType - or - node.getType() instanceof BoxedType - or - exists(MethodAccess ma, string methodName, CompileTimeConstantExpr target | - node.asExpr() = ma and - ma.getMethod().hasQualifiedName("java.lang", "String", methodName) and - target = ma.getArgument(0) and - ( - methodName = "replace" and target.getIntValue() = [10, 13] // 10 == "\n", 13 == "\r" - or - methodName = "replaceAll" and - target.getStringValue().regexpMatch(".*([\n\r]|\\[\\^[^\\]\r\n]*\\]).*") - ) - ) - } -} - -module ResponseSplitting = TaintTracking::Global; - -import ResponseSplitting::PathGraph - -from ResponseSplitting::PathNode source, ResponseSplitting::PathNode sink -where ResponseSplitting::flowPath(source, sink) +from ResponseSplittingFlow::PathNode source, ResponseSplittingFlow::PathNode sink +where ResponseSplittingFlow::flowPath(source, sink) select sink.getNode(), source, sink, "This header depends on a $@, which may cause a response-splitting vulnerability.", source.getNode(), "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-1204/StaticInitializationVector.ql b/java/ql/src/Security/CWE/CWE-1204/StaticInitializationVector.ql index 669c4e6f946..258e0f87112 100644 --- a/java/ql/src/Security/CWE/CWE-1204/StaticInitializationVector.ql +++ b/java/ql/src/Security/CWE/CWE-1204/StaticInitializationVector.ql @@ -13,9 +13,9 @@ import java import semmle.code.java.security.StaticInitializationVectorQuery -import DataFlow::PathGraph +import StaticInitializationVectorFlow::PathGraph -from DataFlow::PathNode source, DataFlow::PathNode sink, StaticInitializationVectorConfig conf -where conf.hasFlowPath(source, sink) +from StaticInitializationVectorFlow::PathNode source, StaticInitializationVectorFlow::PathNode sink +where StaticInitializationVectorFlow::flowPath(source, sink) select sink.getNode(), source, sink, "A $@ should not be used for encryption.", source.getNode(), "static initialization vector" diff --git a/java/ql/src/Security/CWE/CWE-134/ExternallyControlledFormatString.ql b/java/ql/src/Security/CWE/CWE-134/ExternallyControlledFormatString.ql index a2d2e9005ef..fc5af977a33 100644 --- a/java/ql/src/Security/CWE/CWE-134/ExternallyControlledFormatString.ql +++ b/java/ql/src/Security/CWE/CWE-134/ExternallyControlledFormatString.ql @@ -11,24 +11,8 @@ */ import java -import semmle.code.java.dataflow.FlowSources +import semmle.code.java.security.ExternallyControlledFormatStringQuery import semmle.code.java.StringFormat - -module ExternallyControlledFormatStringConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } - - predicate isSink(DataFlow::Node sink) { - sink.asExpr() = any(StringFormat formatCall).getFormatArgument() - } - - predicate isBarrier(DataFlow::Node node) { - node.getType() instanceof NumericType or node.getType() instanceof BooleanType - } -} - -module ExternallyControlledFormatStringFlow = - TaintTracking::Global; - import ExternallyControlledFormatStringFlow::PathGraph from diff --git a/java/ql/src/Security/CWE/CWE-273/UnsafeCertTrust.ql b/java/ql/src/Security/CWE/CWE-273/UnsafeCertTrust.ql index 2925d588c74..eb5241ac87a 100644 --- a/java/ql/src/Security/CWE/CWE-273/UnsafeCertTrust.ql +++ b/java/ql/src/Security/CWE/CWE-273/UnsafeCertTrust.ql @@ -18,7 +18,5 @@ import semmle.code.java.security.UnsafeCertTrustQuery from Expr unsafeTrust where unsafeTrust instanceof RabbitMQEnableHostnameVerificationNotSet or - exists(SslEndpointIdentificationFlowConfig config | - config.hasFlowTo(DataFlow::exprNode(unsafeTrust)) - ) + SslEndpointIdentificationFlow::flowTo(DataFlow::exprNode(unsafeTrust)) select unsafeTrust, "Unsafe configuration of trusted certificates." diff --git a/java/ql/src/Security/CWE/CWE-295/InsecureTrustManager.ql b/java/ql/src/Security/CWE/CWE-295/InsecureTrustManager.ql index 755f2b5a4a7..4904c08b195 100644 --- a/java/ql/src/Security/CWE/CWE-295/InsecureTrustManager.ql +++ b/java/ql/src/Security/CWE/CWE-295/InsecureTrustManager.ql @@ -13,10 +13,10 @@ import java import semmle.code.java.dataflow.DataFlow import semmle.code.java.security.InsecureTrustManagerQuery -import DataFlow::PathGraph +import InsecureTrustManagerFlow::PathGraph -from DataFlow::PathNode source, DataFlow::PathNode sink -where any(InsecureTrustManagerConfiguration cfg).hasFlowPath(source, sink) +from InsecureTrustManagerFlow::PathNode source, InsecureTrustManagerFlow::PathNode sink +where InsecureTrustManagerFlow::flowPath(source, sink) select sink, source, sink, "This uses $@, which is defined in $@ and trusts any certificate.", source, "TrustManager", source.getNode().asExpr().(ClassInstanceExpr).getConstructedType() as type, type.nestedName() diff --git a/java/ql/src/Security/CWE/CWE-319/HttpsUrls.ql b/java/ql/src/Security/CWE/CWE-319/HttpsUrls.ql index 745a2d6dfad..4bcf99fd4b6 100644 --- a/java/ql/src/Security/CWE/CWE-319/HttpsUrls.ql +++ b/java/ql/src/Security/CWE/CWE-319/HttpsUrls.ql @@ -12,9 +12,9 @@ import java import semmle.code.java.security.HttpsUrlsQuery -import DataFlow::PathGraph +import HttpStringToUrlOpenMethodFlow::PathGraph -from DataFlow::PathNode source, DataFlow::PathNode sink -where any(HttpStringToUrlOpenMethodFlowConfig c).hasFlowPath(source, sink) +from HttpStringToUrlOpenMethodFlow::PathNode source, HttpStringToUrlOpenMethodFlow::PathNode sink +where HttpStringToUrlOpenMethodFlow::flowPath(source, sink) select sink.getNode(), source, sink, "URL may have been constructed with HTTP protocol, using $@.", source.getNode(), "this HTTP URL" diff --git a/java/ql/src/Security/CWE/CWE-326/InsufficientKeySize.ql b/java/ql/src/Security/CWE/CWE-326/InsufficientKeySize.ql index 2cf3d9115b3..39e4c3e64e5 100644 --- a/java/ql/src/Security/CWE/CWE-326/InsufficientKeySize.ql +++ b/java/ql/src/Security/CWE/CWE-326/InsufficientKeySize.ql @@ -13,10 +13,10 @@ import java import semmle.code.java.security.InsufficientKeySizeQuery -import DataFlow::PathGraph +import KeySizeFlow::PathGraph -from DataFlow::PathNode source, DataFlow::PathNode sink, KeySizeConfiguration cfg -where cfg.hasFlowPath(source, sink) +from KeySizeFlow::PathNode source, KeySizeFlow::PathNode sink +where KeySizeFlow::flowPath(source, sink) select sink.getNode(), source, sink, "This $@ is less than the recommended key size of " + source.getState() + " bits.", source.getNode(), "key size" diff --git a/java/ql/src/Security/CWE/CWE-347/MissingJWTSignatureCheck.ql b/java/ql/src/Security/CWE/CWE-347/MissingJWTSignatureCheck.ql index 648321ec3ab..077d7a67370 100644 --- a/java/ql/src/Security/CWE/CWE-347/MissingJWTSignatureCheck.ql +++ b/java/ql/src/Security/CWE/CWE-347/MissingJWTSignatureCheck.ql @@ -12,9 +12,9 @@ import java import semmle.code.java.security.MissingJWTSignatureCheckQuery -import DataFlow::PathGraph +import MissingJwtSignatureCheckFlow::PathGraph -from DataFlow::PathNode source, DataFlow::PathNode sink, MissingJwtSignatureCheckConf conf -where conf.hasFlowPath(source, sink) +from MissingJwtSignatureCheckFlow::PathNode source, MissingJwtSignatureCheckFlow::PathNode sink +where MissingJwtSignatureCheckFlow::flowPath(source, sink) select sink.getNode(), source, sink, "This parses a $@, but the signature is not verified.", source.getNode(), "JWT signing key" diff --git a/java/ql/src/Security/CWE/CWE-502/UnsafeDeserialization.ql b/java/ql/src/Security/CWE/CWE-502/UnsafeDeserialization.ql index d494d92e657..1c5660653a6 100644 --- a/java/ql/src/Security/CWE/CWE-502/UnsafeDeserialization.ql +++ b/java/ql/src/Security/CWE/CWE-502/UnsafeDeserialization.ql @@ -13,9 +13,9 @@ import java import semmle.code.java.security.UnsafeDeserializationQuery -import DataFlow::PathGraph +import UnsafeDeserializationFlow::PathGraph -from DataFlow::PathNode source, DataFlow::PathNode sink, UnsafeDeserializationConfig conf -where conf.hasFlowPath(source, sink) +from UnsafeDeserializationFlow::PathNode source, UnsafeDeserializationFlow::PathNode sink +where UnsafeDeserializationFlow::flowPath(source, sink) select sink.getNode().(UnsafeDeserializationSink).getMethodAccess(), source, sink, "Unsafe deserialization depends on a $@.", source.getNode(), "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-522/InsecureBasicAuth.ql b/java/ql/src/Security/CWE/CWE-522/InsecureBasicAuth.ql index 069245b4a3e..ae74b355e5f 100644 --- a/java/ql/src/Security/CWE/CWE-522/InsecureBasicAuth.ql +++ b/java/ql/src/Security/CWE/CWE-522/InsecureBasicAuth.ql @@ -16,9 +16,9 @@ import java import semmle.code.java.security.InsecureBasicAuthQuery -import DataFlow::PathGraph +import InsecureBasicAuthFlow::PathGraph -from DataFlow::PathNode source, DataFlow::PathNode sink, BasicAuthFlowConfig config -where config.hasFlowPath(source, sink) +from InsecureBasicAuthFlow::PathNode source, InsecureBasicAuthFlow::PathNode sink +where InsecureBasicAuthFlow::flowPath(source, sink) select sink.getNode(), source, sink, "Insecure basic authentication from a $@.", source.getNode(), "HTTP URL" diff --git a/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsApiCall.ql b/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsApiCall.ql index 2b84f4b8065..410cea0ed03 100644 --- a/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsApiCall.ql +++ b/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsApiCall.ql @@ -11,10 +11,9 @@ */ import semmle.code.java.security.HardcodedCredentialsApiCallQuery -import DataFlow::PathGraph +import HardcodedCredentialApiCallFlow::PathGraph -from - DataFlow::PathNode source, DataFlow::PathNode sink, HardcodedCredentialApiCallConfiguration conf -where conf.hasFlowPath(source, sink) +from HardcodedCredentialApiCallFlow::PathNode source, HardcodedCredentialApiCallFlow::PathNode sink +where HardcodedCredentialApiCallFlow::flowPath(source, sink) select source.getNode(), source, sink, "Hard-coded value flows to $@.", sink.getNode(), "sensitive API call" diff --git a/java/ql/src/Security/CWE/CWE-807/ConditionalBypass.ql b/java/ql/src/Security/CWE/CWE-807/ConditionalBypass.ql index 3cfa2079685..d012ae33810 100644 --- a/java/ql/src/Security/CWE/CWE-807/ConditionalBypass.ql +++ b/java/ql/src/Security/CWE/CWE-807/ConditionalBypass.ql @@ -15,15 +15,15 @@ import java import semmle.code.java.dataflow.DataFlow import semmle.code.java.security.ConditionalBypassQuery -import DataFlow::PathGraph +import ConditionalBypassFlow::PathGraph from - DataFlow::PathNode source, DataFlow::PathNode sink, MethodAccess m, Expr e, - ConditionalBypassFlowConfig conf + ConditionalBypassFlow::PathNode source, ConditionalBypassFlow::PathNode sink, MethodAccess m, + Expr e where conditionControlsMethod(m, e) and sink.getNode().asExpr() = e and - conf.hasFlowPath(source, sink) + ConditionalBypassFlow::flowPath(source, sink) select m, source, sink, "Sensitive method may not be executed depending on a $@, which flows from $@.", e, "this condition", source.getNode(), "user-controlled value" diff --git a/java/ql/src/Security/CWE/CWE-927/ImplicitPendingIntents.ql b/java/ql/src/Security/CWE/CWE-927/ImplicitPendingIntents.ql index 58eb6300868..f4065ceeae6 100644 --- a/java/ql/src/Security/CWE/CWE-927/ImplicitPendingIntents.ql +++ b/java/ql/src/Security/CWE/CWE-927/ImplicitPendingIntents.ql @@ -15,10 +15,10 @@ import java import semmle.code.java.dataflow.DataFlow import semmle.code.java.security.ImplicitPendingIntentsQuery -import DataFlow::PathGraph +import ImplicitPendingIntentStartFlow::PathGraph -from DataFlow::PathNode source, DataFlow::PathNode sink -where any(ImplicitPendingIntentStartConf conf).hasFlowPath(source, sink) +from ImplicitPendingIntentStartFlow::PathNode source, ImplicitPendingIntentStartFlow::PathNode sink +where ImplicitPendingIntentStartFlow::flowPath(source, sink) select sink.getNode(), source, sink, "$@ and sent to an unspecified third party through a PendingIntent.", source.getNode(), "An implicit Intent is created" diff --git a/java/ql/src/experimental/Security/CWE/CWE-611/XXELib.qll b/java/ql/src/experimental/Security/CWE/CWE-611/XXELib.qll index 3f44faa54d0..61008ae63aa 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-611/XXELib.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-611/XXELib.qll @@ -232,9 +232,7 @@ class SaxTransformerFactoryNewTransformerHandler extends XmlParserCall { override Expr getSink() { result = this.getArgument(0) } - override predicate isSafe() { - exists(SafeTransformerFactoryFlowConfig stf | stf.hasFlowToExpr(this.getQualifier())) - } + override predicate isSafe() { SafeTransformerFactoryFlow::flowToExpr(this.getQualifier()) } } /** DEPRECATED: Alias for SaxTransformerFactoryNewTransformerHandler */ diff --git a/java/ql/test/query-tests/security/CWE-023/semmle/tests/PartialPathTraversalFromRemoteTest.ql b/java/ql/test/query-tests/security/CWE-023/semmle/tests/PartialPathTraversalFromRemoteTest.ql index 7f441e62d4e..a07eb6892c3 100644 --- a/java/ql/test/query-tests/security/CWE-023/semmle/tests/PartialPathTraversalFromRemoteTest.ql +++ b/java/ql/test/query-tests/security/CWE-023/semmle/tests/PartialPathTraversalFromRemoteTest.ql @@ -1,21 +1,24 @@ import java -import TestUtilities.InlineFlowTest +import TestUtilities.InlineExpectationsTest import semmle.code.java.security.PartialPathTraversalQuery -class EnableLegacy extends EnableLegacyConfiguration { - EnableLegacy() { exists(this) } -} - class TestRemoteSource extends RemoteFlowSource { TestRemoteSource() { this.asParameter().hasName(["dir", "path"]) } override string getSourceType() { result = "TestSource" } } -class Test extends InlineFlowTest { - override DataFlow::Configuration getValueFlowConfig() { none() } +class Test extends InlineExpectationsTest { + Test() { this = "PartialPathTraversalFromRemoteTest" } - override TaintTracking::Configuration getTaintFlowConfig() { - result instanceof PartialPathTraversalFromRemoteConfig + override string getARelevantTag() { result = "hasTaintFlow" } + + override predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "hasTaintFlow" and + exists(DataFlow::Node sink | PartialPathTraversalFromRemoteFlow::flowTo(sink) | + sink.getLocation() = location and + element = sink.toString() and + value = "" + ) } } diff --git a/java/ql/test/query-tests/security/CWE-023/semmle/tests/PartialPathTraversalTest.java b/java/ql/test/query-tests/security/CWE-023/semmle/tests/PartialPathTraversalTest.java index b7c0256d075..af0fd776de1 100644 --- a/java/ql/test/query-tests/security/CWE-023/semmle/tests/PartialPathTraversalTest.java +++ b/java/ql/test/query-tests/security/CWE-023/semmle/tests/PartialPathTraversalTest.java @@ -225,6 +225,12 @@ public class PartialPathTraversalTest { } } + public void doesNotFlagOptimalSafeVersion(File dir, File parent) throws IOException { + if (!dir.toPath().normalize().startsWith(parent.toPath())) { // Safe + throw new IOException("Path traversal attempt: " + dir.getCanonicalPath()); + } + } + public void doesNotFlag() { "hello".startsWith("goodbye"); } diff --git a/java/ql/test/query-tests/security/CWE-1204/StaticInitializationVectorTest.ql b/java/ql/test/query-tests/security/CWE-1204/StaticInitializationVectorTest.ql index 653a3cefa7a..ceaf8e11a4f 100644 --- a/java/ql/test/query-tests/security/CWE-1204/StaticInitializationVectorTest.ql +++ b/java/ql/test/query-tests/security/CWE-1204/StaticInitializationVectorTest.ql @@ -9,7 +9,7 @@ class StaticInitializationVectorTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "staticInitializationVector" and - exists(DataFlow::Node sink, StaticInitializationVectorConfig conf | conf.hasFlowTo(sink) | + exists(DataFlow::Node sink | StaticInitializationVectorFlow::flowTo(sink) | sink.getLocation() = location and element = sink.toString() and value = "" diff --git a/java/ql/test/query-tests/security/CWE-273/UnsafeCertTrustTest.ql b/java/ql/test/query-tests/security/CWE-273/UnsafeCertTrustTest.ql index 344faa7f86b..fd18ccc27eb 100644 --- a/java/ql/test/query-tests/security/CWE-273/UnsafeCertTrustTest.ql +++ b/java/ql/test/query-tests/security/CWE-273/UnsafeCertTrustTest.ql @@ -12,9 +12,7 @@ class UnsafeCertTrustTest extends InlineExpectationsTest { exists(Expr unsafeTrust | unsafeTrust instanceof RabbitMQEnableHostnameVerificationNotSet or - exists(SslEndpointIdentificationFlowConfig config | - config.hasFlowTo(DataFlow::exprNode(unsafeTrust)) - ) + SslEndpointIdentificationFlow::flowTo(DataFlow::exprNode(unsafeTrust)) | unsafeTrust.getLocation() = location and element = unsafeTrust.toString() and diff --git a/java/ql/test/query-tests/security/CWE-295/InsecureTrustManager/InsecureTrustManagerTest.ql b/java/ql/test/query-tests/security/CWE-295/InsecureTrustManager/InsecureTrustManagerTest.ql index fb00ff33b34..0f068d04679 100644 --- a/java/ql/test/query-tests/security/CWE-295/InsecureTrustManager/InsecureTrustManagerTest.ql +++ b/java/ql/test/query-tests/security/CWE-295/InsecureTrustManager/InsecureTrustManagerTest.ql @@ -1,13 +1,18 @@ import java import semmle.code.java.security.InsecureTrustManagerQuery -import TestUtilities.InlineFlowTest +import TestUtilities.InlineExpectationsTest -class EnableLegacy extends EnableLegacyConfiguration { - EnableLegacy() { exists(this) } -} +class InsecureTrustManagerTest extends InlineExpectationsTest { + InsecureTrustManagerTest() { this = "InsecureTrustManagerTest" } -class InsecureTrustManagerTest extends InlineFlowTest { - override DataFlow::Configuration getValueFlowConfig() { - result = any(InsecureTrustManagerConfiguration c) + override string getARelevantTag() { result = "hasValueFlow" } + + override predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "hasValueFlow" and + exists(DataFlow::Node sink | InsecureTrustManagerFlow::flowTo(sink) | + sink.getLocation() = location and + element = sink.toString() and + value = "" + ) } } diff --git a/java/ql/test/query-tests/security/CWE-326/InsufficientKeySizeTest.ql b/java/ql/test/query-tests/security/CWE-326/InsufficientKeySizeTest.ql index 12f667a67f3..1384a36e4ce 100644 --- a/java/ql/test/query-tests/security/CWE-326/InsufficientKeySizeTest.ql +++ b/java/ql/test/query-tests/security/CWE-326/InsufficientKeySizeTest.ql @@ -9,7 +9,7 @@ class InsufficientKeySizeTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasInsufficientKeySize" and - exists(DataFlow::PathNode sink | exists(KeySizeConfiguration cfg | cfg.hasFlowPath(_, sink)) | + exists(KeySizeFlow::PathNode sink | KeySizeFlow::flowPath(_, sink) | sink.getNode().getLocation() = location and element = sink.getNode().toString() and value = "" diff --git a/java/ql/test/query-tests/security/CWE-347/MissingJWTSignatureCheckTest.ql b/java/ql/test/query-tests/security/CWE-347/MissingJWTSignatureCheckTest.ql index b4f4c1c445e..df6867bbefe 100644 --- a/java/ql/test/query-tests/security/CWE-347/MissingJWTSignatureCheckTest.ql +++ b/java/ql/test/query-tests/security/CWE-347/MissingJWTSignatureCheckTest.ql @@ -9,7 +9,7 @@ class HasMissingJwtSignatureCheckTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasMissingJwtSignatureCheck" and - exists(DataFlow::Node sink, MissingJwtSignatureCheckConf conf | conf.hasFlowTo(sink) | + exists(DataFlow::Node sink | MissingJwtSignatureCheckFlow::flowTo(sink) | sink.getLocation() = location and element = sink.toString() and value = "" diff --git a/java/ql/test/query-tests/security/CWE-502/UnsafeDeserialization.ql b/java/ql/test/query-tests/security/CWE-502/UnsafeDeserialization.ql index a2ba654a540..4d10c798e33 100644 --- a/java/ql/test/query-tests/security/CWE-502/UnsafeDeserialization.ql +++ b/java/ql/test/query-tests/security/CWE-502/UnsafeDeserialization.ql @@ -9,7 +9,7 @@ class UnsafeDeserializationTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "unsafeDeserialization" and - exists(DataFlow::Node sink, UnsafeDeserializationConfig conf | conf.hasFlowTo(sink) | + exists(DataFlow::Node sink | UnsafeDeserializationFlow::flowTo(sink) | sink.getLocation() = location and element = sink.toString() and value = "" diff --git a/java/ql/test/query-tests/security/CWE-522/InsecureBasicAuthTest.ql b/java/ql/test/query-tests/security/CWE-522/InsecureBasicAuthTest.ql index b593c5476ef..29057edce71 100644 --- a/java/ql/test/query-tests/security/CWE-522/InsecureBasicAuthTest.ql +++ b/java/ql/test/query-tests/security/CWE-522/InsecureBasicAuthTest.ql @@ -9,7 +9,7 @@ class HasInsecureBasicAuthTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasInsecureBasicAuth" and - exists(DataFlow::Node sink, BasicAuthFlowConfig conf | conf.hasFlowTo(sink) | + exists(DataFlow::Node sink | InsecureBasicAuthFlow::flowTo(sink) | sink.getLocation() = location and element = sink.toString() and value = "" diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsApiCall.ql b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsApiCall.ql index 79ce1738f38..7d7b8e2d2a5 100644 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsApiCall.ql +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsApiCall.ql @@ -9,9 +9,7 @@ class HardcodedCredentialsApiCallTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "HardcodedCredentialsApiCall" and - exists(DataFlow::Node sink, HardcodedCredentialApiCallConfiguration conf | - conf.hasFlow(_, sink) - | + exists(DataFlow::Node sink | HardcodedCredentialApiCallFlow::flowTo(sink) | sink.getLocation() = location and element = sink.toString() and value = "" diff --git a/java/ql/test/query-tests/security/CWE-807/semmle/tests/ConditionalBypassTest.ql b/java/ql/test/query-tests/security/CWE-807/semmle/tests/ConditionalBypassTest.ql index ef676d4a8f0..20ca408f1b2 100644 --- a/java/ql/test/query-tests/security/CWE-807/semmle/tests/ConditionalBypassTest.ql +++ b/java/ql/test/query-tests/security/CWE-807/semmle/tests/ConditionalBypassTest.ql @@ -9,7 +9,7 @@ class ConditionalBypassTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasConditionalBypassTest" and - exists(DataFlow::Node sink, ConditionalBypassFlowConfig conf | conf.hasFlowTo(sink) | + exists(DataFlow::Node sink | ConditionalBypassFlow::flowTo(sink) | sink.getLocation() = location and element = sink.toString() and value = "" diff --git a/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.ql b/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.ql index 871dcd2cef2..972653380aa 100644 --- a/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.ql +++ b/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.ql @@ -9,7 +9,7 @@ class ImplicitPendingIntentsTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasImplicitPendingIntent" and - exists(DataFlow::Node sink | any(ImplicitPendingIntentStartConf c).hasFlowTo(sink) | + exists(DataFlow::Node sink | ImplicitPendingIntentStartFlow::flowTo(sink) | sink.getLocation() = location and element = sink.toString() and value = "" diff --git a/javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java b/javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java index 3b86ed15f8e..346d31231df 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java +++ b/javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java @@ -1236,7 +1236,7 @@ protected DependencyInstallationResult preparePackagesAndDependencies(Set if (!extractor.getConfig().isExterns()) seenFiles = true; List errors = loc == null ? Collections.emptyList() : loc.getParseErrors(); for (ParseError err : errors) { - String msg = "A parse error occurred: " + StringUtil.escapeMarkdown(err.getMessage()) + String msg = "A parse error occurred: " + StringUtil.quoteWithBackticks(err.getMessage().trim()) + ". Check the syntax of the file. If the file is invalid, correct the error or [exclude](https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/customizing-code-scanning) the file from analysis."; // file, relative to the source root String relativeFilePath = null; diff --git a/javascript/ql/integration-tests/all-platforms/diagnostics/syntax-error/diagnostics.expected b/javascript/ql/integration-tests/all-platforms/diagnostics/syntax-error/diagnostics.expected index 0c4405ea92b..c1ee7485218 100644 --- a/javascript/ql/integration-tests/all-platforms/diagnostics/syntax-error/diagnostics.expected +++ b/javascript/ql/integration-tests/all-platforms/diagnostics/syntax-error/diagnostics.expected @@ -6,7 +6,7 @@ "startColumn": 4, "startLine": 1 }, - "markdownMessage": "A parse error occurred: Unexpected token. Check the syntax of the file. If the file is invalid, correct the error or [exclude](https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/customizing-code-scanning) the file from analysis.", + "markdownMessage": "A parse error occurred: `Unexpected token`. Check the syntax of the file. If the file is invalid, correct the error or [exclude](https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/customizing-code-scanning) the file from analysis.", "severity": "warning", "source": { "extractorName": "javascript", diff --git a/javascript/ql/lib/change-notes/2023-03-26-CryptoJS-progressive-hashing.md b/javascript/ql/lib/change-notes/2023-03-26-CryptoJS-progressive-hashing.md new file mode 100644 index 00000000000..7b76ab10298 --- /dev/null +++ b/javascript/ql/lib/change-notes/2023-03-26-CryptoJS-progressive-hashing.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The crypto-js module in `CryptoLibraries.qll` now supports progressive hashing with algo.update(). diff --git a/javascript/ql/lib/semmle/javascript/frameworks/CryptoLibraries.qll b/javascript/ql/lib/semmle/javascript/frameworks/CryptoLibraries.qll index 21d23f517f3..2fab10eacac 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/CryptoLibraries.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/CryptoLibraries.qll @@ -4,6 +4,7 @@ import javascript import semmle.javascript.Concepts::Cryptography +private import semmle.javascript.security.internal.CryptoAlgorithmNames /** * A key used in a cryptographic algorithm. @@ -148,7 +149,7 @@ private module BrowserIdCrypto { * A model of the Node.js builtin crypto library. */ private module NodeJSCrypto { - private class InstantiatedAlgorithm extends DataFlow::CallNode { + private class InstantiatedAlgorithm extends API::CallNode { private string algorithmName; InstantiatedAlgorithm() { @@ -165,11 +166,11 @@ private module NodeJSCrypto { * Also matches `createHash`, `createHmac`, `createSign` instead of `createCipher`. */ - exists(DataFlow::SourceNode mod | - mod = DataFlow::moduleImport("crypto") and - this = mod.getAMemberCall("create" + ["Hash", "Hmac", "Sign", "Cipher"]) and - algorithmName = this.getArgument(0).getStringValue() - ) + this = + API::moduleImport("crypto") + .getMember("create" + ["Hash", "Hmac", "Sign", "Cipher"]) + .getACall() and + algorithmName = this.getArgument(0).getStringValue() } CryptographicAlgorithm getAlgorithm() { result.matchesName(algorithmName) } @@ -196,13 +197,12 @@ private module NodeJSCrypto { // crypto.generateKeyPair(type, options, callback) // crypto.generateKeyPairSync(type, options) // crypto.generateKeySync(type, options) - exists(DataFlow::SourceNode mod, string keyType | + exists(string keyType | keyType = "Key" and symmetric = true or keyType = "KeyPair" and symmetric = false | - mod = DataFlow::moduleImport("crypto") and - this = mod.getAMemberCall("generate" + keyType + ["", "Sync"]) + this = API::moduleImport("crypto").getMember("generate" + keyType + ["", "Sync"]).getACall() ) } @@ -248,17 +248,15 @@ private module NodeJSCrypto { private class Key extends CryptographicKey { Key() { - exists(InstantiatedAlgorithm instantiation, string name | - name = "setPrivateKey" or - name = "sign" - | - this = instantiation.getAMethodCall(name).getArgument(0) - ) + this = + any(InstantiatedAlgorithm i) + .getReturn() + .getMember(["setPrivateKey", "sign"]) + .getParameter(0) + .asSink() or - exists(DataFlow::SourceNode mod, string name, DataFlow::InvokeNode call, int index | - mod = DataFlow::moduleImport("crypto") and - call = mod.getAMemberCall(name) and - this = call.getArgument(index) + exists(string name, int index | + this = API::moduleImport("crypto").getMember(name).getACall().getArgument(index) | index = 0 and (name = "privateDecrypt" or name = "privateEncrypt") @@ -274,15 +272,53 @@ private module NodeJSCrypto { * A model of the crypto-js library. */ private module CryptoJS { + private class InstantiatedAlgorithm extends DataFlow::CallNode { + private string algorithmName; + + InstantiatedAlgorithm() { + /* + * ``` + * const crypto = require("crypto-js"); + * const cipher = crypto.algo.SHA256.create(); + * ``` + * matched as: + * ``` + * const crypto = require("crypto-js"); + * const cipher = crypto.algo..create(); + * ``` + */ + + this = + API::moduleImport("crypto-js") + .getMember("algo") + .getMember(algorithmName) + .getMember("create") + .getACall() and + not isStrongPasswordHashingAlgorithm(algorithmName) + } + + CryptographicAlgorithm getAlgorithm() { result.matchesName(algorithmName) } + + private BlockMode getExplicitBlockMode() { result.matchesString(algorithmName) } + + BlockMode getBlockMode() { + isBlockEncryptionAlgorithm(this.getAlgorithm()) and + ( + if exists(this.getExplicitBlockMode()) + then result = this.getExplicitBlockMode() + else + // CBC is the default if not explicitly specified + result = "CBC" + ) + } + } + /** * Matches `CryptoJS.` and `require("crypto-js/")` */ private API::Node getAlgorithmNode(CryptographicAlgorithm algorithm) { exists(string algorithmName | algorithm.matchesName(algorithmName) | - exists(API::Node mod | mod = API::moduleImport("crypto-js") | - result = mod.getMember(algorithmName) or - result = mod.getMember("Hmac" + algorithmName) // they prefix Hmac - ) + result = API::moduleImport("crypto-js").getMember([algorithmName, "Hmac" + algorithmName]) or result = API::moduleImport("crypto-js/" + algorithmName) ) @@ -325,13 +361,44 @@ private module CryptoJS { input = result.getParameter(0) } + private API::CallNode getUpdatedApplication(API::Node input, InstantiatedAlgorithm instantiation) { + /* + * ``` + * var CryptoJS = require("crypto-js"); + * var hash = CryptoJS.algo.SHA256.create(); + * hash.update('message'); + * hash.update('password'); + * var hashInHex = hash.finalize(); + * ``` + * Matched as: + * ``` + * var CryptoJS = require("crypto-js"); + * var hash = CryptoJS.algo..create(); + * hash.update(); + * hash.update(); + * var hashInHex = hash.finalize(); + * ``` + * Also matches where `CryptoJS.algo.` has been + * replaced by `require("crypto-js/")` + */ + + result = instantiation.getAMemberCall("update") and + input = result.getParameter(0) + } + private class Apply extends CryptographicOperation::Range instanceof API::CallNode { API::Node input; CryptographicAlgorithm algorithm; // non-functional Apply() { - this = getEncryptionApplication(input, algorithm) or + this = getEncryptionApplication(input, algorithm) + or this = getDirectApplication(input, algorithm) + or + exists(InstantiatedAlgorithm instantiation | + this = getUpdatedApplication(input, instantiation) and + algorithm = instantiation.getAlgorithm() + ) } override DataFlow::Node getAnInput() { result = input.asSink() } @@ -427,13 +494,12 @@ private module TweetNaCl { * Also matches the "hash" method name, and the "nacl-fast" module. */ - exists(DataFlow::SourceNode mod, string name | + exists(string name | name = "hash" and algorithm.matchesName("SHA512") or name = "sign" and algorithm.matchesName("ed25519") | - (mod = DataFlow::moduleImport("nacl") or mod = DataFlow::moduleImport("nacl-fast")) and - this = mod.getAMemberCall(name) and + this = API::moduleImport(["nacl", "nacl-fast"]).getMember(name).getACall() and super.getArgument(0) = input ) } @@ -459,17 +525,13 @@ private module HashJs { */ private DataFlow::CallNode getAlgorithmNode(CryptographicAlgorithm algorithm) { exists(string algorithmName | algorithm.matchesName(algorithmName) | - result = DataFlow::moduleMember("hash.js", algorithmName).getACall() + result = API::moduleImport("hash.js").getMember(algorithmName).getACall() or - exists(DataFlow::SourceNode mod | - mod = DataFlow::moduleImport("hash.js/lib/hash/" + algorithmName) - or - exists(string size | - mod = DataFlow::moduleImport("hash.js/lib/hash/sha/" + size) and - algorithmName = "SHA" + size - ) - | - result = mod.getACall() + result = API::moduleImport("hash.js/lib/hash/" + algorithmName).getACall() + or + exists(string size | + result = API::moduleImport("hash.js/lib/hash/sha/" + size).getACall() and + algorithmName = "SHA" + size ) ) } @@ -509,10 +571,7 @@ private module HashJs { * A model of the forge library. */ private module Forge { - private DataFlow::SourceNode getAnImportNode() { - result = DataFlow::moduleImport("forge") or - result = DataFlow::moduleImport("node-forge") - } + private API::Node getAnImportNode() { result = API::moduleImport(["forge", "node-forge"]) } abstract private class Cipher extends DataFlow::CallNode { abstract CryptographicAlgorithm getAlgorithm(); @@ -524,14 +583,14 @@ private module Forge { private string blockModeString; KeyCipher() { - exists(DataFlow::SourceNode mod, string algorithmName | - mod = getAnImportNode() and - algorithm.matchesName(algorithmName) - | - exists(string createName, string cipherName, string cipherPrefix | + exists(string algorithmName | algorithm.matchesName(algorithmName) | + exists(string cipherName, string cipherPrefix | // `require('forge').cipher.createCipher("3DES-CBC").update("secret", "key");` - (createName = "createCipher" or createName = "createDecipher") and - this = mod.getAPropertyRead("cipher").getAMemberCall(createName) and + this = + getAnImportNode() + .getMember("cipher") + .getMember(["createCipher", "createDecipher"]) + .getACall() and this.getArgument(0).mayHaveStringValue(cipherName) and cipherName = cipherPrefix + "-" + blockModeString and blockModeString = ["CBC", "CFB", "CTR", "ECB", "GCM", "OFB"] and @@ -540,13 +599,13 @@ private module Forge { ) or // `require("forge").rc2.createEncryptionCipher("key").update("secret");` - exists(string createName | - createName = "createEncryptionCipher" or createName = "createDecryptionCipher" - | - this = mod.getAPropertyRead(algorithmName).getAMemberCall(createName) and - key = this.getArgument(0) and - blockModeString = algorithmName - ) + this = + getAnImportNode() + .getMember(algorithmName) + .getMember(["createEncryptionCipher", "createDecryptionCipher"]) + .getACall() and + key = this.getArgument(0) and + blockModeString = algorithmName ) } @@ -567,10 +626,7 @@ private module Forge { exists(string algorithmName | algorithm.matchesName(algorithmName) | // require("forge").md.md5.create().update('The quick brown fox jumps over the lazy dog'); this = - getAnImportNode() - .getAPropertyRead("md") - .getAPropertyRead(algorithmName) - .getAMemberCall("create") + getAnImportNode().getMember("md").getMember(algorithmName).getMember("create").getACall() ) } @@ -606,15 +662,17 @@ private module Forge { // var cipher = forge.rc2.createEncryptionCipher(key, 128); this = getAnImportNode() - .getAPropertyRead(any(string s | algorithm.matchesName(s))) - .getAMemberCall("createEncryptionCipher") + .getMember(any(string s | algorithm.matchesName(s))) + .getMember("createEncryptionCipher") + .getACall() or // var key = forge.random.getBytesSync(16); // var cipher = forge.cipher.createCipher('AES-CBC', key); this = getAnImportNode() - .getAPropertyRead("cipher") - .getAMemberCall(["createCipher", "createDecipher"]) and + .getMember("cipher") + .getMember(["createCipher", "createDecipher"]) + .getACall() and algorithm.matchesName(this.getArgument(0).getStringValue()) } @@ -643,12 +701,9 @@ private module Md5 { Apply() { // `require("md5")("message");` - exists(DataFlow::SourceNode mod | - mod = DataFlow::moduleImport("md5") and - algorithm.matchesName("MD5") and - this = mod.getACall() and - super.getArgument(0) = input - ) + algorithm.matchesName("MD5") and + this = API::moduleImport("md5").getACall() and + super.getArgument(0) = input } override DataFlow::Node getAnInput() { result = input } @@ -670,21 +725,12 @@ private module Bcrypt { Apply() { // `require("bcrypt").hash(password);` with minor naming variations - exists(DataFlow::SourceNode mod, string moduleName, string methodName | - algorithm.matchesName("BCRYPT") and - ( - moduleName = "bcrypt" or - moduleName = "bcryptjs" or - moduleName = "bcrypt-nodejs" - ) and - ( - methodName = "hash" or - methodName = "hashSync" - ) and - mod = DataFlow::moduleImport(moduleName) and - this = mod.getAMemberCall(methodName) and - super.getArgument(0) = input - ) + algorithm.matchesName("BCRYPT") and + this = + API::moduleImport(["bcrypt", "bcryptjs", "bcrypt-nodejs"]) + .getMember(["hash", "hashSync"]) + .getACall() and + super.getArgument(0) = input } override DataFlow::Node getAnInput() { result = input } @@ -706,13 +752,11 @@ private module Hasha { Apply() { // `require('hasha')('unicorn', { algorithm: "md5" });` - exists(DataFlow::SourceNode mod, string algorithmName, DataFlow::Node algorithmNameNode | - mod = DataFlow::moduleImport("hasha") and - this = mod.getACall() and + exists(string algorithmName | + this = API::moduleImport("hasha").getACall() and super.getArgument(0) = input and algorithm.matchesName(algorithmName) and - super.getOptionArgument(1, "algorithm") = algorithmNameNode and - algorithmNameNode.mayHaveStringValue(algorithmName) + super.getOptionArgument(1, "algorithm").mayHaveStringValue(algorithmName) ) } @@ -730,7 +774,7 @@ private module Hasha { */ private module ExpressJwt { private class Key extends CryptographicKey { - Key() { this = DataFlow::moduleMember("express-jwt", "sign").getACall().getArgument(1) } + Key() { this = API::moduleImport("express-jwt").getMember("sign").getACall().getArgument(1) } } } diff --git a/javascript/ql/src/Security/CWE-295/DisablingCertificateValidation.ql b/javascript/ql/src/Security/CWE-295/DisablingCertificateValidation.ql index 7fd76a635ec..d9f7267d425 100644 --- a/javascript/ql/src/Security/CWE-295/DisablingCertificateValidation.ql +++ b/javascript/ql/src/Security/CWE-295/DisablingCertificateValidation.ql @@ -19,6 +19,8 @@ DataFlow::InvokeNode tlsInvocation() { or result = DataFlow::moduleMember("https", "Agent").getAnInstantiation() or + result = DataFlow::moduleMember("https", "createServer").getACall() + or exists(DataFlow::NewNode new | new = DataFlow::moduleMember("tls", "TLSSocket").getAnInstantiation() | diff --git a/javascript/ql/src/Security/CWE-916/InsufficientPasswordHash.qhelp b/javascript/ql/src/Security/CWE-916/InsufficientPasswordHash.qhelp index 1efdbe694b1..f9e3a5b3857 100644 --- a/javascript/ql/src/Security/CWE-916/InsufficientPasswordHash.qhelp +++ b/javascript/ql/src/Security/CWE-916/InsufficientPasswordHash.qhelp @@ -37,7 +37,7 @@ the hash of a password.

- +

This is not secure, since the password can be efficiently @@ -46,7 +46,7 @@ algorithm:

- + diff --git a/javascript/ql/src/Security/CWE-916/examples/InsufficientPasswordHash_CryptoJS.js b/javascript/ql/src/Security/CWE-916/examples/InsufficientPasswordHash_CryptoJS.js new file mode 100644 index 00000000000..c0a621f85b1 --- /dev/null +++ b/javascript/ql/src/Security/CWE-916/examples/InsufficientPasswordHash_CryptoJS.js @@ -0,0 +1,8 @@ +const crypto = require('crypto-js') +function hashPassword(email, password) { + var algo = crypto.algo.SHA512.create() + algo.update(password, 'utf-8') // BAD + algo.update(email.toLowerCase(), 'utf-8') + var hash = algo.finalize() + return hash.toString(crypto.enc.Base64) +} \ No newline at end of file diff --git a/javascript/ql/src/Security/CWE-916/examples/InsufficientPasswordHash_CryptoJS_fixed b/javascript/ql/src/Security/CWE-916/examples/InsufficientPasswordHash_CryptoJS_fixed new file mode 100644 index 00000000000..909f09f8f4e --- /dev/null +++ b/javascript/ql/src/Security/CWE-916/examples/InsufficientPasswordHash_CryptoJS_fixed @@ -0,0 +1,8 @@ +const crypto = require('crypto-js') +function hashPassword(email, password) { + var algo = crypto.algo.PBKDF2.create() + algo.update(password, 'utf-8') // GOOD + algo.update(email.toLowerCase(), 'utf-8') + var hash = algo.finalize() + return hash.toString(crypto.enc.Base64) +} \ No newline at end of file diff --git a/javascript/ql/src/Security/CWE-916/examples/InsufficientPasswordHash.js b/javascript/ql/src/Security/CWE-916/examples/InsufficientPasswordHash_NodeJS.js similarity index 100% rename from javascript/ql/src/Security/CWE-916/examples/InsufficientPasswordHash.js rename to javascript/ql/src/Security/CWE-916/examples/InsufficientPasswordHash_NodeJS.js diff --git a/javascript/ql/src/Security/CWE-916/examples/InsufficientPasswordHash_fixed.js b/javascript/ql/src/Security/CWE-916/examples/InsufficientPasswordHash_NodeJS_fixed.js similarity index 100% rename from javascript/ql/src/Security/CWE-916/examples/InsufficientPasswordHash_fixed.js rename to javascript/ql/src/Security/CWE-916/examples/InsufficientPasswordHash_NodeJS_fixed.js diff --git a/javascript/ql/src/change-notes/2023-03-27-disabling-certificate-validation.md b/javascript/ql/src/change-notes/2023-03-27-disabling-certificate-validation.md new file mode 100644 index 00000000000..7e7f93e8b7d --- /dev/null +++ b/javascript/ql/src/change-notes/2023-03-27-disabling-certificate-validation.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The `DisablingCertificateValidation.ql` query has been updated to check `createServer` from `https` for disabled certificate validation. diff --git a/javascript/ql/test/query-tests/Security/CWE-295/DisablingCertificateValidation.expected b/javascript/ql/test/query-tests/Security/CWE-295/DisablingCertificateValidation.expected index a99ae396964..649326b7c6d 100644 --- a/javascript/ql/test/query-tests/Security/CWE-295/DisablingCertificateValidation.expected +++ b/javascript/ql/test/query-tests/Security/CWE-295/DisablingCertificateValidation.expected @@ -9,3 +9,4 @@ | tst.js:45:2:45:28 | rejectU ... !!false | Disabling certificate validation is strongly discouraged. | | tst.js:48:2:48:26 | rejectU ... : !true | Disabling certificate validation is strongly discouraged. | | tst.js:74:9:74:33 | rejectU ... : false | Disabling certificate validation is strongly discouraged. | +| tst.js:80:5:80:29 | rejectU ... : false | Disabling certificate validation is strongly discouraged. | diff --git a/javascript/ql/test/query-tests/Security/CWE-295/tst.js b/javascript/ql/test/query-tests/Security/CWE-295/tst.js index 8088b767e18..d64239d64db 100644 --- a/javascript/ql/test/query-tests/Security/CWE-295/tst.js +++ b/javascript/ql/test/query-tests/Security/CWE-295/tst.js @@ -74,4 +74,8 @@ function getSomeunsafeOptions() { rejectUnauthorized: false // NOT OK } } -new https.Agent(getSomeunsafeOptions()); \ No newline at end of file +new https.Agent(getSomeunsafeOptions()); + +https.createServer({ + rejectUnauthorized: false // NOT OK +}); \ No newline at end of file diff --git a/misc/codegen/generators/cppgen.py b/misc/codegen/generators/cppgen.py index f6a7f8d792c..1cd6cc36450 100644 --- a/misc/codegen/generators/cppgen.py +++ b/misc/codegen/generators/cppgen.py @@ -49,6 +49,7 @@ def _get_field(cls: schema.Class, p: schema.Property, add_or_none_except: typing is_optional=p.is_optional, is_repeated=p.is_repeated, is_predicate=p.is_predicate, + is_unordered=p.is_unordered, trap_name=trap_name, ) args.update(cpp.get_field_override(p.name)) diff --git a/misc/codegen/generators/dbschemegen.py b/misc/codegen/generators/dbschemegen.py index 05483748db5..8441b6fd61d 100755 --- a/misc/codegen/generators/dbschemegen.py +++ b/misc/codegen/generators/dbschemegen.py @@ -64,7 +64,16 @@ def cls_to_dbscheme(cls: schema.Class, lookup: typing.Dict[str, schema.Class], a ) # use property-specific tables for 1-to-many and 1-to-at-most-1 properties for f in cls.properties: - if f.is_repeated: + if f.is_unordered: + yield Table( + name=inflection.tableize(f"{cls.name}_{f.name}"), + columns=[ + Column("id", type=dbtype(cls.name)), + Column(inflection.singularize(f.name), dbtype(f.type, add_or_none_except)), + ], + dir=dir, + ) + elif f.is_repeated: yield Table( keyset=KeySet(["id", "index"]), name=inflection.tableize(f"{cls.name}_{f.name}"), diff --git a/misc/codegen/generators/qlgen.py b/misc/codegen/generators/qlgen.py index 68b3a6d7ef3..7affea51828 100755 --- a/misc/codegen/generators/qlgen.py +++ b/misc/codegen/generators/qlgen.py @@ -109,6 +109,7 @@ def get_ql_property(cls: schema.Class, prop: schema.Property, prev_child: str = prev_child=prev_child if prop.is_child else None, is_optional=prop.is_optional, is_predicate=prop.is_predicate, + is_unordered=prop.is_unordered, description=prop.description ) if prop.is_single: @@ -123,7 +124,7 @@ def get_ql_property(cls: schema.Class, prop: schema.Property, prev_child: str = singular=inflection.singularize(inflection.camelize(prop.name)), plural=inflection.pluralize(inflection.camelize(prop.name)), tablename=inflection.tableize(f"{cls.name}_{prop.name}"), - tableparams=["this", "index", "result"], + tableparams=["this", "index", "result"] if not prop.is_unordered else ["this", "result"], doc=_get_doc(cls, prop, plural=False), doc_plural=_get_doc(cls, prop, plural=True), ) @@ -255,7 +256,7 @@ def _get_all_properties_to_be_tested(cls: schema.Class, lookup: typing.Dict[str, # TODO here operations are duplicated, but should be better if we split ql and qltest generation p = get_ql_property(c, p) yield ql.PropertyForTest(p.getter, is_total=p.is_single or p.is_predicate, - type=p.type if not p.is_predicate else None, is_repeated=p.is_repeated) + type=p.type if not p.is_predicate else None, is_indexed=p.is_indexed) if p.is_repeated and not p.is_optional: yield ql.PropertyForTest(f"getNumberOf{p.plural}", type="int") elif p.is_optional and not p.is_repeated: diff --git a/misc/codegen/lib/cpp.py b/misc/codegen/lib/cpp.py index 9ca2d8e2ebc..eed7aba045c 100644 --- a/misc/codegen/lib/cpp.py +++ b/misc/codegen/lib/cpp.py @@ -36,6 +36,7 @@ class Field: base_type: str is_optional: bool = False is_repeated: bool = False + is_unordered: bool = False is_predicate: bool = False trap_name: str = None first: bool = False diff --git a/misc/codegen/lib/ql.py b/misc/codegen/lib/ql.py index ace39a61e0e..97165053fd0 100644 --- a/misc/codegen/lib/ql.py +++ b/misc/codegen/lib/ql.py @@ -36,6 +36,7 @@ class Property: first: bool = False is_optional: bool = False is_predicate: bool = False + is_unordered: bool = False prev_child: Optional[str] = None qltest_skip: bool = False description: List[str] = field(default_factory=list) @@ -49,7 +50,11 @@ class Property: @property def getter(self): - return f"get{self.singular}" if not self.is_predicate else self.singular + if self.is_predicate: + return self.singular + if self.is_unordered: + return self.indefinite_getter + return f"get{self.singular}" @property def indefinite_getter(self): @@ -77,6 +82,10 @@ class Property: def has_description(self) -> bool: return bool(self.description) + @property + def is_indexed(self) -> bool: + return self.is_repeated and not self.is_unordered + @dataclass class Base: @@ -188,7 +197,7 @@ class PropertyForTest: getter: str is_total: bool = True type: Optional[str] = None - is_repeated: bool = False + is_indexed: bool = False @dataclass diff --git a/misc/codegen/lib/schema.py b/misc/codegen/lib/schema.py index 5e2974ae87d..64a4720093b 100644 --- a/misc/codegen/lib/schema.py +++ b/misc/codegen/lib/schema.py @@ -25,6 +25,7 @@ class Property: OPTIONAL = auto() REPEATED_OPTIONAL = auto() PREDICATE = auto() + REPEATED_UNORDERED = auto() kind: Kind name: Optional[str] = None @@ -44,7 +45,11 @@ class Property: @property def is_repeated(self) -> bool: - return self.kind in (self.Kind.REPEATED, self.Kind.REPEATED_OPTIONAL) + return self.kind in (self.Kind.REPEATED, self.Kind.REPEATED_OPTIONAL, self.Kind.REPEATED_UNORDERED) + + @property + def is_unordered(self) -> bool: + return self.kind == self.Kind.REPEATED_UNORDERED @property def is_predicate(self) -> bool: @@ -65,6 +70,7 @@ RepeatedProperty = functools.partial(Property, Property.Kind.REPEATED) RepeatedOptionalProperty = functools.partial( Property, Property.Kind.REPEATED_OPTIONAL) PredicateProperty = functools.partial(Property, Property.Kind.PREDICATE) +RepeatedUnorderedProperty = functools.partial(Property, Property.Kind.REPEATED_UNORDERED) @dataclass diff --git a/misc/codegen/lib/schemadefs.py b/misc/codegen/lib/schemadefs.py index 6c9457490e7..f3bfd9840dc 100644 --- a/misc/codegen/lib/schemadefs.py +++ b/misc/codegen/lib/schemadefs.py @@ -8,6 +8,8 @@ class _ChildModifier(_schema.PropertyModifier): def modify(self, prop: _schema.Property): if prop.type is None or prop.type[0].islower(): raise _schema.Error("Non-class properties cannot be children") + if prop.is_unordered: + raise _schema.Error("Set properties cannot be children") prop.is_child = True @@ -77,7 +79,7 @@ class _Optionalizer(_schema.PropertyModifier): K = _schema.Property.Kind if prop.kind != K.SINGLE: raise _schema.Error( - "Optional should only be applied to simple property types") + "optional should only be applied to simple property types") prop.kind = K.OPTIONAL @@ -90,7 +92,15 @@ class _Listifier(_schema.PropertyModifier): prop.kind = K.REPEATED_OPTIONAL else: raise _schema.Error( - "Repeated should only be applied to simple or optional property types") + "list should only be applied to simple or optional property types") + + +class _Setifier(_schema.PropertyModifier): + def modify(self, prop: _schema.Property): + K = _schema.Property.Kind + if prop.kind != K.SINGLE: + raise _schema.Error("set should only be applied to simple property types") + prop.kind = K.REPEATED_UNORDERED class _TypeModifier: @@ -122,6 +132,7 @@ string = "string" predicate = _schema.predicate_marker optional = _TypeModifier(_Optionalizer()) list = _TypeModifier(_Listifier()) +set = _TypeModifier(_Setifier()) child = _ChildModifier() doc = _DocModifier diff --git a/misc/codegen/schemadefs.py b/misc/codegen/schemadefs.py deleted file mode 100644 index 6c9457490e7..00000000000 --- a/misc/codegen/schemadefs.py +++ /dev/null @@ -1,149 +0,0 @@ -from typing import Callable as _Callable -from misc.codegen.lib import schema as _schema -import inspect as _inspect -from dataclasses import dataclass as _dataclass - - -class _ChildModifier(_schema.PropertyModifier): - def modify(self, prop: _schema.Property): - if prop.type is None or prop.type[0].islower(): - raise _schema.Error("Non-class properties cannot be children") - prop.is_child = True - - -@_dataclass -class _DocModifier(_schema.PropertyModifier): - doc: str - - def modify(self, prop: _schema.Property): - if "\n" in self.doc or self.doc[-1] == ".": - raise _schema.Error("No newlines or trailing dots are allowed in doc, did you intend to use desc?") - prop.doc = self.doc - - -@_dataclass -class _DescModifier(_schema.PropertyModifier): - description: str - - def modify(self, prop: _schema.Property): - prop.description = _schema.split_doc(self.description) - - -def include(source: str): - # add to `includes` variable in calling context - _inspect.currentframe().f_back.f_locals.setdefault( - "__includes", []).append(source) - - -class _Namespace: - """ simple namespacing mechanism """ - - def __init__(self, **kwargs): - self.__dict__.update(kwargs) - - -qltest = _Namespace() -ql = _Namespace() -cpp = _Namespace() -synth = _Namespace() - - -@_dataclass -class _Pragma(_schema.PropertyModifier): - """ A class or property pragma. - For properties, it functions similarly to a `_PropertyModifier` with `|`, adding the pragma. - For schema classes it acts as a python decorator with `@`. - """ - pragma: str - - def __post_init__(self): - namespace, _, name = self.pragma.partition('_') - setattr(globals()[namespace], name, self) - - def modify(self, prop: _schema.Property): - prop.pragmas.append(self.pragma) - - def __call__(self, cls: type) -> type: - """ use this pragma as a decorator on classes """ - if "_pragmas" in cls.__dict__: # not using hasattr as we don't want to land on inherited pragmas - cls._pragmas.append(self.pragma) - else: - cls._pragmas = [self.pragma] - return cls - - -class _Optionalizer(_schema.PropertyModifier): - def modify(self, prop: _schema.Property): - K = _schema.Property.Kind - if prop.kind != K.SINGLE: - raise _schema.Error( - "Optional should only be applied to simple property types") - prop.kind = K.OPTIONAL - - -class _Listifier(_schema.PropertyModifier): - def modify(self, prop: _schema.Property): - K = _schema.Property.Kind - if prop.kind == K.SINGLE: - prop.kind = K.REPEATED - elif prop.kind == K.OPTIONAL: - prop.kind = K.REPEATED_OPTIONAL - else: - raise _schema.Error( - "Repeated should only be applied to simple or optional property types") - - -class _TypeModifier: - """ Modifies types using get item notation """ - - def __init__(self, modifier: _schema.PropertyModifier): - self.modifier = modifier - - def __getitem__(self, item): - return item | self.modifier - - -_ClassDecorator = _Callable[[type], type] - - -def _annotate(**kwargs) -> _ClassDecorator: - def f(cls: type) -> type: - for k, v in kwargs.items(): - setattr(cls, f"_{k}", v) - return cls - - return f - - -boolean = "boolean" -int = "int" -string = "string" - -predicate = _schema.predicate_marker -optional = _TypeModifier(_Optionalizer()) -list = _TypeModifier(_Listifier()) - -child = _ChildModifier() -doc = _DocModifier -desc = _DescModifier - -use_for_null = _annotate(null=True) - -_Pragma("qltest_skip") -_Pragma("qltest_collapse_hierarchy") -_Pragma("qltest_uncollapse_hierarchy") - -ql.default_doc_name = lambda doc: _annotate(doc_name=doc) -_Pragma("ql_internal") - -_Pragma("cpp_skip") - - -def group(name: str = "") -> _ClassDecorator: - return _annotate(group=name) - - -synth.from_class = lambda ref: _annotate(ipa=_schema.IpaInfo( - from_class=_schema.get_type_name(ref))) -synth.on_arguments = lambda **kwargs: _annotate( - ipa=_schema.IpaInfo(on_arguments={k: _schema.get_type_name(t) for k, t in kwargs.items()})) diff --git a/misc/codegen/templates/cpp_classes_cpp.mustache b/misc/codegen/templates/cpp_classes_cpp.mustache index d78c89fc3c7..725fc10c6ef 100644 --- a/misc/codegen/templates/cpp_classes_cpp.mustache +++ b/misc/codegen/templates/cpp_classes_cpp.mustache @@ -24,7 +24,7 @@ void {{name}}::emit({{^final}}TrapLabel<{{name}}Tag> id, {{/final}}std::ostream& {{#is_repeated}} for (auto i = 0u; i < {{field_name}}.size(); ++i) { {{^is_optional}} - out << {{trap_name}}Trap{id, i, {{field_name}}[i]} << '\n'; + out << {{trap_name}}Trap{id, {{^is_unordered}}i, {{/is_unordered}}{{field_name}}[i]} << '\n'; {{/is_optional}} {{#is_optional}} if ({{field_name}}[i]) out << {{trap_name}}Trap{id, i, *{{field_name}}[i]} << '\n'; diff --git a/misc/codegen/templates/ql_class.mustache b/misc/codegen/templates/ql_class.mustache index 173df3a75b9..862b46067c4 100644 --- a/misc/codegen/templates/ql_class.mustache +++ b/misc/codegen/templates/ql_class.mustache @@ -66,9 +66,9 @@ module Generated { * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the * behavior of both the `Immediate` and non-`Immediate` versions. */ - {{type}} getImmediate{{singular}}({{#is_repeated}}int index{{/is_repeated}}) { + {{type}} get{{#is_unordered}}An{{/is_unordered}}Immediate{{singular}}({{#is_indexed}}int index{{/is_indexed}}) { {{^ipa}} - result = Synth::convert{{type}}FromRaw(Synth::convert{{name}}ToRaw(this){{^root}}.(Raw::{{name}}){{/root}}.{{getter}}({{#is_repeated}}index{{/is_repeated}})) + result = Synth::convert{{type}}FromRaw(Synth::convert{{name}}ToRaw(this){{^root}}.(Raw::{{name}}){{/root}}.{{getter}}({{#is_indexed}}index{{/is_indexed}})) {{/ipa}} {{#ipa}} none() @@ -83,8 +83,8 @@ module Generated { {{/description}} {{/has_description}} */ - final {{type}} {{getter}}({{#is_repeated}}int index{{/is_repeated}}) { - result = getImmediate{{singular}}({{#is_repeated}}index{{/is_repeated}}).resolve() + final {{type}} {{getter}}({{#is_indexed}}int index{{/is_indexed}}) { + result = get{{#is_unordered}}An{{/is_unordered}}Immediate{{singular}}({{#is_indexed}}index{{/is_indexed}}).resolve() } {{/type_is_class}} @@ -97,9 +97,9 @@ module Generated { {{/description}} {{/has_description}} */ - {{type}} {{getter}}({{#is_repeated}}int index{{/is_repeated}}) { + {{type}} {{getter}}({{#is_indexed}}int index{{/is_indexed}}) { {{^ipa}} - {{^is_predicate}}result = {{/is_predicate}}Synth::convert{{name}}ToRaw(this){{^root}}.(Raw::{{name}}){{/root}}.{{getter}}({{#is_repeated}}index{{/is_repeated}}) + {{^is_predicate}}result = {{/is_predicate}}Synth::convert{{name}}ToRaw(this){{^root}}.(Raw::{{name}}){{/root}}.{{getter}}({{#is_indexed}}index{{/is_indexed}}) {{/ipa}} {{#ipa}} none() @@ -115,7 +115,7 @@ module Generated { exists({{getter}}({{#is_repeated}}index{{/is_repeated}})) } {{/is_optional}} - {{#is_repeated}} + {{#is_indexed}} /** * Gets any of the {{doc_plural}}. @@ -132,7 +132,15 @@ module Generated { result = count(int i | exists({{getter}}(i))) } {{/is_optional}} - {{/is_repeated}} + {{/is_indexed}} + {{#is_unordered}} + /** + * Gets the number of {{doc_plural}}. + */ + final int getNumberOf{{plural}}() { + result = count({{getter}}()) + } + {{/is_unordered}} {{/properties}} } } diff --git a/misc/codegen/templates/ql_db.mustache b/misc/codegen/templates/ql_db.mustache index 750cdb008a8..55a83514d6e 100644 --- a/misc/codegen/templates/ql_db.mustache +++ b/misc/codegen/templates/ql_db.mustache @@ -13,7 +13,7 @@ module Raw { {{/description}} {{/has_description}} */ - {{type}} {{getter}}({{#is_repeated}}int index{{/is_repeated}}) { + {{type}} {{getter}}({{#is_indexed}}int index{{/is_indexed}}) { {{tablename}}({{#tableparams}}{{^first}}, {{/first}}{{param}}{{/tableparams}}) } {{/properties}} diff --git a/misc/codegen/templates/ql_property_doc.mustache b/misc/codegen/templates/ql_property_doc.mustache index 483772d14f6..7f21c6461c9 100644 --- a/misc/codegen/templates/ql_property_doc.mustache +++ b/misc/codegen/templates/ql_property_doc.mustache @@ -1,6 +1,11 @@ {{^is_predicate}} +{{^is_unoredered}} Gets the {{#is_repeated}}`index`th {{/is_repeated}}{{doc}}{{#is_repeated}} (0-based){{/is_repeated}}{{#is_optional}}, if it exists{{/is_optional}}. +{{/is_unoredered}} {{/is_predicate}} {{#is_predicate}} Holds if {{doc}}. {{/is_predicate}} +{{#is_unordered}} +Gets any of the {{doc_plural}}. +{{/is_unordered}} diff --git a/misc/codegen/templates/ql_test_property.mustache b/misc/codegen/templates/ql_test_property.mustache index 5e81298089d..a0ba0a52d69 100644 --- a/misc/codegen/templates/ql_test_property.mustache +++ b/misc/codegen/templates/ql_test_property.mustache @@ -4,7 +4,7 @@ import {{elements_module}} import TestUtils {{#property}} -from {{class_name}} x{{#is_repeated}}, int index{{/is_repeated}} +from {{class_name}} x{{#is_indexed}}, int index{{/is_indexed}} where toBeTested(x) and not x.isUnknown() -select x, {{#is_repeated}}index, {{/is_repeated}}x.{{getter}}({{#is_repeated}}index{{/is_repeated}}) +select x, {{#is_indexed}}index, {{/is_indexed}}x.{{getter}}({{#is_indexed}}index{{/is_indexed}}) {{/property}} diff --git a/misc/codegen/test/test_cppgen.py b/misc/codegen/test/test_cppgen.py index 278f184fcbc..1bc7d150b2e 100644 --- a/misc/codegen/test/test_cppgen.py +++ b/misc/codegen/test/test_cppgen.py @@ -62,19 +62,20 @@ def test_two_class_hierarchy(generate): ("boolean", "bool"), ("MyClass", "TrapLabel"), ]) -@pytest.mark.parametrize("property_cls,optional,repeated,trap_name", [ - (schema.SingleProperty, False, False, None), - (schema.OptionalProperty, True, False, "MyClassProps"), - (schema.RepeatedProperty, False, True, "MyClassProps"), - (schema.RepeatedOptionalProperty, True, True, "MyClassProps"), +@pytest.mark.parametrize("property_cls,optional,repeated,unordered,trap_name", [ + (schema.SingleProperty, False, False, False, None), + (schema.OptionalProperty, True, False, False, "MyClassProps"), + (schema.RepeatedProperty, False, True, False, "MyClassProps"), + (schema.RepeatedOptionalProperty, True, True, False, "MyClassProps"), + (schema.RepeatedUnorderedProperty, False, True, True, "MyClassProps"), ]) -def test_class_with_field(generate, type, expected, property_cls, optional, repeated, trap_name): +def test_class_with_field(generate, type, expected, property_cls, optional, repeated, unordered, trap_name): assert generate([ schema.Class(name="MyClass", properties=[property_cls("prop", type)]), ]) == [ cpp.Class(name="MyClass", fields=[cpp.Field("prop", expected, is_optional=optional, - is_repeated=repeated, trap_name=trap_name)], + is_repeated=repeated, is_unordered=unordered, trap_name=trap_name)], trap_name="MyClasses", final=True) ] diff --git a/misc/codegen/test/test_dbschemegen.py b/misc/codegen/test/test_dbschemegen.py index 7a986538b06..86b9dd2fc84 100644 --- a/misc/codegen/test/test_dbschemegen.py +++ b/misc/codegen/test/test_dbschemegen.py @@ -168,6 +168,32 @@ def test_final_class_with_repeated_field(generate, property_cls, dir_param): ) +def test_final_class_with_repeated_unordered_field(generate, dir_param): + assert generate([ + schema.Class("Object", group=dir_param.input, properties=[ + schema.RepeatedUnorderedProperty("foo", "bar"), + ]), + ]) == dbscheme.Scheme( + src=schema_file.name, + includes=[], + declarations=[ + dbscheme.Table( + name="objects", + columns=[ + dbscheme.Column('id', '@object', binding=True), + ], dir=dir_param.expected, + ), + dbscheme.Table( + name="object_foos", + columns=[ + dbscheme.Column('id', '@object'), + dbscheme.Column('foo', 'bar'), + ], dir=dir_param.expected, + ), + ], + ) + + def test_final_class_with_predicate_field(generate, dir_param): assert generate([ schema.Class("Object", group=dir_param.input, properties=[ diff --git a/misc/codegen/test/test_ql.py b/misc/codegen/test/test_ql.py index 0006bbb96e4..6d1e2181194 100644 --- a/misc/codegen/test/test_ql.py +++ b/misc/codegen/test/test_ql.py @@ -27,19 +27,28 @@ def test_property_is_a_class(type, expected): assert [p.param for p in prop.tableparams] == expected_tableparams -@pytest.mark.parametrize("name,expected_getter", [ +indefinite_getters = [ ("Argument", "getAnArgument"), ("Element", "getAnElement"), ("Integer", "getAnInteger"), ("Operator", "getAnOperator"), ("Unit", "getAUnit"), ("Whatever", "getAWhatever"), -]) +] + + +@pytest.mark.parametrize("name,expected_getter", indefinite_getters) def test_property_indefinite_article(name, expected_getter): prop = ql.Property(name, plural="X") assert prop.indefinite_getter == expected_getter +@pytest.mark.parametrize("name,expected_getter", indefinite_getters) +def test_property_unordered_getter(name, expected_getter): + prop = ql.Property(name, plural="X", is_unordered=True) + assert prop.getter == expected_getter + + @pytest.mark.parametrize("plural,expected", [ (None, False), ("", False), @@ -50,6 +59,17 @@ def test_property_is_repeated(plural, expected): assert prop.is_repeated is expected +@pytest.mark.parametrize("plural,unordered,expected", [ + (None, False, False), + ("", False, False), + ("X", False, True), + ("X", True, False), +]) +def test_property_is_indexed(plural, unordered, expected): + prop = ql.Property("foo", "Foo", "props", ["result"], plural=plural, is_unordered=unordered) + assert prop.is_indexed is expected + + @pytest.mark.parametrize("is_optional,is_predicate,plural,expected", [ (False, False, None, True), (False, False, "", True), diff --git a/misc/codegen/test/test_qlgen.py b/misc/codegen/test/test_qlgen.py index f16b1404c2e..e6dd8d452cb 100644 --- a/misc/codegen/test/test_qlgen.py +++ b/misc/codegen/test/test_qlgen.py @@ -338,6 +338,23 @@ def test_repeated_property(generate_classes, is_child, prev_child): } +def test_repeated_unordered_property(generate_classes): + assert generate_classes([ + schema.Class("FakeRoot"), + schema.Class("MyObject", properties=[ + schema.RepeatedUnorderedProperty("foo", "bar")]), + ]) == { + "FakeRoot.qll": (a_ql_stub(name="FakeRoot", base_import=gen_import_prefix + "FakeRoot"), + a_ql_class(name="FakeRoot", final=True)), + "MyObject.qll": (a_ql_stub(name="MyObject", base_import=gen_import_prefix + "MyObject"), + a_ql_class(name="MyObject", final=True, properties=[ + ql.Property(singular="Foo", plural="Foos", type="bar", tablename="my_object_foos", + tableparams=["this", "result"], is_unordered=True, + doc="foo of this my object", doc_plural="foos of this my object"), + ])), + } + + @pytest.mark.parametrize("is_child,prev_child", [(False, None), (True, "")]) def test_repeated_optional_property(generate_classes, is_child, prev_child): assert generate_classes([ @@ -552,23 +569,28 @@ def test_test_partial_properties(opts, generate_tests): schema.Class("B", bases=["A"], properties=[ schema.RepeatedProperty("y", "bool"), schema.RepeatedOptionalProperty("z", "int"), + schema.RepeatedUnorderedProperty("w", "string"), ]), ]) == { "B/B.ql": a_ql_class_tester(class_name="B", properties=[ ql.PropertyForTest(getter="hasX"), ql.PropertyForTest(getter="getNumberOfYs", type="int"), + ql.PropertyForTest(getter="getNumberOfWs", type="int"), ]), "B/B_getX.ql": a_ql_property_tester(class_name="B", property=ql.PropertyForTest(getter="getX", is_total=False, type="string")), "B/B_getY.ql": a_ql_property_tester(class_name="B", property=ql.PropertyForTest(getter="getY", is_total=False, - is_repeated=True, + is_indexed=True, type="bool")), "B/B_getZ.ql": a_ql_property_tester(class_name="B", property=ql.PropertyForTest(getter="getZ", is_total=False, - is_repeated=True, - type="int")), + is_indexed=True, + type="int")), + "B/B_getAW.ql": a_ql_property_tester(class_name="B", + property=ql.PropertyForTest(getter="getAW", is_total=False, + type="string")), } @@ -589,7 +611,7 @@ def test_test_properties_deduplicated(opts, generate_tests): ]), "Final/Final_getY.ql": a_ql_property_tester(class_name="Final", property=ql.PropertyForTest(getter="getY", is_total=False, - is_repeated=True, + is_indexed=True, type="bool")), } diff --git a/misc/codegen/test/test_schemaloader.py b/misc/codegen/test/test_schemaloader.py index 9724a82da8f..9c9750818ea 100644 --- a/misc/codegen/test/test_schemaloader.py +++ b/misc/codegen/test/test_schemaloader.py @@ -167,6 +167,7 @@ def test_properties(): three: defs.list[defs.boolean] four: defs.list[defs.optional[defs.string]] five: defs.predicate + six: defs.set[defs.string] assert data.classes == { 'A': schema.Class('A', properties=[ @@ -175,6 +176,7 @@ def test_properties(): schema.RepeatedProperty('three', 'boolean'), schema.RepeatedOptionalProperty('four', 'string'), schema.PredicateProperty('five'), + schema.RepeatedUnorderedProperty('six', 'string'), ]), } @@ -193,6 +195,7 @@ def test_class_properties(): two: defs.optional[A] three: defs.list[A] four: defs.list[defs.optional[A]] + five: defs.set[A] assert data.classes == { 'A': schema.Class('A', derived={'B'}), @@ -201,6 +204,7 @@ def test_class_properties(): schema.OptionalProperty('two', 'A'), schema.RepeatedProperty('three', 'A'), schema.RepeatedOptionalProperty('four', 'A'), + schema.RepeatedUnorderedProperty('five', 'A'), ]), } @@ -213,6 +217,7 @@ def test_string_reference_class_properties(): two: defs.optional["A"] three: defs.list["A"] four: defs.list[defs.optional["A"]] + five: defs.set["A"] assert data.classes == { 'A': schema.Class('A', properties=[ @@ -220,6 +225,7 @@ def test_string_reference_class_properties(): schema.OptionalProperty('two', 'A'), schema.RepeatedProperty('three', 'A'), schema.RepeatedOptionalProperty('four', 'A'), + schema.RepeatedUnorderedProperty('five', 'A'), ]), } @@ -253,8 +259,8 @@ def test_children(): } -@pytest.mark.parametrize("spec", [defs.string, defs.int, defs.boolean, defs.predicate]) -def test_builtin_and_predicate_children_not_allowed(spec): +@pytest.mark.parametrize("spec", [defs.string, defs.int, defs.boolean, defs.predicate, defs.set["A"]]) +def test_builtin_predicate_and_set_children_not_allowed(spec): with pytest.raises(schema.Error): @load class data: diff --git a/ql/ql/src/codeql_ql/ast/Ast.qll b/ql/ql/src/codeql_ql/ast/Ast.qll index 4264cdf24db..818828d44fe 100644 --- a/ql/ql/src/codeql_ql/ast/Ast.qll +++ b/ql/ql/src/codeql_ql/ast/Ast.qll @@ -972,7 +972,7 @@ class Class extends TClass, TypeDeclaration, ModuleDeclaration { } /** Gets the class type defined by this class declaration. */ - Type getType() { result.getDeclaration() = this } + ClassType getType() { result.getDeclaration() = this } override AstNode getAChild(string pred) { result = super.getAChild(pred) diff --git a/ql/ql/test/type/type.expected b/ql/ql/test/type/type.expected index fd3a34c27f6..7089676858d 100644 --- a/ql/ql/test/type/type.expected +++ b/ql/ql/test/type/type.expected @@ -1,6 +1,4 @@ | Test.qll:4:15:4:18 | this | Test.qll:3:7:3:13 | Strings | -| Test.qll:4:15:4:18 | this | Test.qll:3:7:3:13 | Strings.Strings | -| Test.qll:4:15:4:18 | this | Test.qll:3:7:3:13 | Strings.extends | | Test.qll:4:22:4:76 | Set | file://:0:0:0:0 | string | | Test.qll:4:23:4:24 | String | file://:0:0:0:0 | string | | Test.qll:4:27:4:29 | String | file://:0:0:0:0 | string | @@ -13,8 +11,6 @@ | Test.qll:4:66:4:69 | String | file://:0:0:0:0 | string | | Test.qll:4:72:4:75 | String | file://:0:0:0:0 | string | | Test.qll:8:14:8:17 | this | Test.qll:7:7:7:12 | Floats | -| Test.qll:8:14:8:17 | this | Test.qll:7:7:7:12 | Floats.Floats | -| Test.qll:8:14:8:17 | this | Test.qll:7:7:7:12 | Floats.extends | | Test.qll:8:21:8:70 | Set | file://:0:0:0:0 | float | | Test.qll:8:22:8:24 | Float | file://:0:0:0:0 | float | | Test.qll:8:27:8:29 | Float | file://:0:0:0:0 | float | @@ -35,14 +31,10 @@ | Test.qll:13:45:13:49 | AddExpr | file://:0:0:0:0 | float | | Test.qll:13:49:13:49 | b | Test.qll:7:7:7:12 | Floats | | Test.qll:16:12:16:15 | this | Test.qll:15:7:15:10 | Base | -| Test.qll:16:12:16:15 | this | Test.qll:15:7:15:10 | Base.Base | -| Test.qll:16:12:16:15 | this | Test.qll:15:7:15:10 | Base.extends | | Test.qll:16:19:16:23 | String | file://:0:0:0:0 | string | | Test.qll:18:15:18:20 | result | file://:0:0:0:0 | int | | Test.qll:18:24:18:24 | Integer | file://:0:0:0:0 | int | | Test.qll:22:11:22:14 | this | Test.qll:21:7:21:9 | Sub | -| Test.qll:22:11:22:14 | this | Test.qll:21:7:21:9 | Sub.Sub | -| Test.qll:22:11:22:14 | this | Test.qll:21:7:21:9 | Sub.extends | | Test.qll:22:18:22:22 | String | file://:0:0:0:0 | string | | Test.qll:24:15:24:20 | result | file://:0:0:0:0 | int | | Test.qll:24:24:24:33 | Super | Test.qll:15:7:15:10 | Base | diff --git a/ruby/ql/lib/codeql/ruby/ApiGraphs.qll b/ruby/ql/lib/codeql/ruby/ApiGraphs.qll index 7f69f71d17f..35bdf1c25d3 100644 --- a/ruby/ql/lib/codeql/ruby/ApiGraphs.qll +++ b/ruby/ql/lib/codeql/ruby/ApiGraphs.qll @@ -584,7 +584,7 @@ module API { // If a call node is relevant as a use-node, treat its arguments as def-nodes argumentStep(_, useCandFwd(), rhs) or - defStep(_, trackDefNode(_), rhs) + defStep(_, defCand(), rhs) or rhs = any(EntryPoint entry).getASink() } diff --git a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/NetHttp.qll b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/NetHttp.qll index fbe27b6884c..eac0a928a1b 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/NetHttp.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/NetHttp.qll @@ -21,8 +21,8 @@ private import codeql.ruby.dataflow.internal.DataFlowImplForHttpClientLibraries */ class NetHttpRequest extends Http::Client::Request::Range, DataFlow::CallNode { private DataFlow::CallNode request; - private DataFlow::Node responseBody; private API::Node requestNode; + private boolean returnsResponseBody; NetHttpRequest() { exists(string method | @@ -32,12 +32,12 @@ class NetHttpRequest extends Http::Client::Request::Range, DataFlow::CallNode { // Net::HTTP.get(...) method = "get" and requestNode = API::getTopLevelMember("Net").getMember("HTTP").getReturn(method) and - responseBody = request + returnsResponseBody = true or // Net::HTTP.post(...).body method in ["post", "post_form"] and requestNode = API::getTopLevelMember("Net").getMember("HTTP").getReturn(method) and - responseBody = requestNode.getAMethodCall(["body", "read_body", "entity"]) + returnsResponseBody = false or // Net::HTTP.new(..).get(..).body method in [ @@ -45,7 +45,7 @@ class NetHttpRequest extends Http::Client::Request::Range, DataFlow::CallNode { "post", "post2", "request_post", "request" ] and requestNode = API::getTopLevelMember("Net").getMember("HTTP").getInstance().getReturn(method) and - responseBody = requestNode.getAMethodCall(["body", "read_body", "entity"]) + returnsResponseBody = false ) } @@ -64,7 +64,11 @@ class NetHttpRequest extends Http::Client::Request::Range, DataFlow::CallNode { ) } - override DataFlow::Node getResponseBody() { result = responseBody } + override DataFlow::Node getResponseBody() { + if returnsResponseBody = true + then result = this + else result = requestNode.getAMethodCall(["body", "read_body", "entity"]) + } /** Gets the value that controls certificate validation, if any. */ DataFlow::Node getCertificateValidationControllingValue() { diff --git a/ruby/ql/test/library-tests/frameworks/http_clients/HttpClients.expected b/ruby/ql/test/library-tests/frameworks/http_clients/HttpClients.expected index eae7e9b76a5..50d8303925f 100644 --- a/ruby/ql/test/library-tests/frameworks/http_clients/HttpClients.expected +++ b/ruby/ql/test/library-tests/frameworks/http_clients/HttpClients.expected @@ -1,80 +1,289 @@ -| Excon.rb:3:9:3:40 | call to get | Excon | Excon.rb:3:19:3:39 | "http://example.com/" | Excon.rb:4:1:4:10 | call to body | -| Excon.rb:6:9:6:60 | call to post | Excon | Excon.rb:6:20:6:40 | "http://example.com/" | Excon.rb:7:1:7:10 | call to body | -| Excon.rb:9:9:9:59 | call to put | Excon | Excon.rb:9:19:9:39 | "http://example.com/" | Excon.rb:10:1:10:10 | call to body | -| Excon.rb:12:9:12:61 | call to patch | Excon | Excon.rb:12:21:12:41 | "http://example.com/" | Excon.rb:13:1:13:10 | call to body | -| Excon.rb:15:9:15:43 | call to delete | Excon | Excon.rb:15:22:15:42 | "http://example.com/" | Excon.rb:16:1:16:10 | call to body | -| Excon.rb:18:9:18:41 | call to head | Excon | Excon.rb:18:20:18:40 | "http://example.com/" | Excon.rb:19:1:19:10 | call to body | -| Excon.rb:21:9:21:44 | call to options | Excon | Excon.rb:21:23:21:43 | "http://example.com/" | Excon.rb:22:1:22:10 | call to body | -| Excon.rb:24:9:24:42 | call to trace | Excon | Excon.rb:24:21:24:41 | "http://example.com/" | Excon.rb:25:1:25:10 | call to body | -| Excon.rb:28:9:28:34 | call to get | Excon | Excon.rb:27:25:27:44 | "http://example.com" | Excon.rb:29:1:29:10 | call to body | -| Excon.rb:28:9:28:34 | call to get | Excon | Excon.rb:28:31:28:33 | "/" | Excon.rb:29:1:29:10 | call to body | -| Excon.rb:31:10:31:39 | call to post | Excon | Excon.rb:27:25:27:44 | "http://example.com" | Excon.rb:32:1:32:11 | call to body | -| Excon.rb:31:10:31:39 | call to post | Excon | Excon.rb:31:33:31:38 | "/foo" | Excon.rb:32:1:32:11 | call to body | -| Excon.rb:35:9:35:34 | call to get | Excon | Excon.rb:34:37:34:56 | "http://example.com" | Excon.rb:36:1:36:10 | call to body | -| Excon.rb:35:9:35:34 | call to get | Excon | Excon.rb:35:31:35:33 | "/" | Excon.rb:36:1:36:10 | call to body | -| Excon.rb:38:10:38:39 | call to post | Excon | Excon.rb:34:37:34:56 | "http://example.com" | Excon.rb:39:1:39:11 | call to body | -| Excon.rb:38:10:38:39 | call to post | Excon | Excon.rb:38:33:38:38 | "/foo" | Excon.rb:39:1:39:11 | call to body | -| Faraday.rb:3:9:3:42 | call to get | Faraday | Faraday.rb:3:21:3:41 | "http://example.com/" | Faraday.rb:4:1:4:10 | call to body | -| Faraday.rb:6:9:6:62 | call to post | Faraday | Faraday.rb:6:22:6:42 | "http://example.com/" | Faraday.rb:7:1:7:10 | call to body | -| Faraday.rb:9:9:9:61 | call to put | Faraday | Faraday.rb:9:21:9:41 | "http://example.com/" | Faraday.rb:10:1:10:10 | call to body | -| Faraday.rb:12:9:12:63 | call to patch | Faraday | Faraday.rb:12:23:12:43 | "http://example.com/" | Faraday.rb:13:1:13:10 | call to body | -| Faraday.rb:15:9:15:45 | call to delete | Faraday | Faraday.rb:15:24:15:44 | "http://example.com/" | Faraday.rb:16:1:16:10 | call to body | -| Faraday.rb:18:9:18:43 | call to head | Faraday | Faraday.rb:18:22:18:42 | "http://example.com/" | Faraday.rb:19:1:19:10 | call to body | -| Faraday.rb:24:9:24:44 | call to trace | Faraday | Faraday.rb:24:23:24:43 | "http://example.com/" | Faraday.rb:25:1:25:10 | call to body | -| Faraday.rb:28:9:28:27 | call to get | Faraday | Faraday.rb:27:26:27:45 | "http://example.com" | Faraday.rb:29:1:29:10 | call to body | -| Faraday.rb:28:9:28:27 | call to get | Faraday | Faraday.rb:28:24:28:26 | "/" | Faraday.rb:29:1:29:10 | call to body | -| Faraday.rb:31:10:31:46 | call to post | Faraday | Faraday.rb:27:26:27:45 | "http://example.com" | Faraday.rb:32:1:32:11 | call to body | -| Faraday.rb:31:10:31:46 | call to post | Faraday | Faraday.rb:31:26:31:31 | "/foo" | Faraday.rb:32:1:32:11 | call to body | -| Faraday.rb:35:10:35:28 | call to get | Faraday | Faraday.rb:34:26:34:50 | Pair | Faraday.rb:36:1:36:11 | call to body | -| Faraday.rb:35:10:35:28 | call to get | Faraday | Faraday.rb:34:31:34:50 | "http://example.com" | Faraday.rb:36:1:36:11 | call to body | -| Faraday.rb:35:10:35:28 | call to get | Faraday | Faraday.rb:35:25:35:27 | "/" | Faraday.rb:36:1:36:11 | call to body | -| Faraday.rb:39:10:39:28 | call to get | Faraday | Faraday.rb:38:38:38:63 | Pair | Faraday.rb:40:1:40:11 | call to body | -| Faraday.rb:39:10:39:28 | call to get | Faraday | Faraday.rb:38:43:38:63 | "https://example.com" | Faraday.rb:40:1:40:11 | call to body | -| Faraday.rb:39:10:39:28 | call to get | Faraday | Faraday.rb:39:25:39:27 | "/" | Faraday.rb:40:1:40:11 | call to body | -| HttpClient.rb:3:9:3:45 | call to get | HTTPClient | HttpClient.rb:3:24:3:44 | "http://example.com/" | HttpClient.rb:4:1:4:10 | call to body | -| HttpClient.rb:6:9:6:65 | call to post | HTTPClient | HttpClient.rb:6:25:6:45 | "http://example.com/" | HttpClient.rb:7:1:7:13 | call to content | -| HttpClient.rb:9:9:9:64 | call to put | HTTPClient | HttpClient.rb:9:24:9:44 | "http://example.com/" | HttpClient.rb:10:1:10:15 | call to http_body | -| HttpClient.rb:12:9:12:48 | call to delete | HTTPClient | HttpClient.rb:12:27:12:47 | "http://example.com/" | HttpClient.rb:13:1:13:10 | call to dump | -| HttpClient.rb:15:9:15:46 | call to head | HTTPClient | HttpClient.rb:15:25:15:45 | "http://example.com/" | HttpClient.rb:16:1:16:10 | call to body | -| HttpClient.rb:18:9:18:49 | call to options | HTTPClient | HttpClient.rb:18:28:18:48 | "http://example.com/" | HttpClient.rb:19:1:19:13 | call to content | -| HttpClient.rb:21:9:21:47 | call to trace | HTTPClient | HttpClient.rb:21:26:21:46 | "http://example.com/" | HttpClient.rb:22:1:22:15 | call to http_body | -| HttpClient.rb:24:9:24:53 | call to get_content | HTTPClient | HttpClient.rb:24:32:24:52 | "http://example.com/" | HttpClient.rb:24:9:24:53 | call to get_content | -| HttpClient.rb:26:10:26:74 | call to post_content | HTTPClient | HttpClient.rb:26:34:26:54 | "http://example.com/" | HttpClient.rb:26:10:26:74 | call to post_content | -| Httparty.rb:5:1:5:35 | call to get | HTTParty | Httparty.rb:5:14:5:34 | "http://example.com/" | Httparty.rb:5:1:5:35 | call to get | -| Httparty.rb:7:1:7:55 | call to post | HTTParty | Httparty.rb:7:15:7:35 | "http://example.com/" | Httparty.rb:7:1:7:55 | call to post | -| Httparty.rb:9:1:9:54 | call to put | HTTParty | Httparty.rb:9:14:9:34 | "http://example.com/" | Httparty.rb:9:1:9:54 | call to put | -| Httparty.rb:11:1:11:56 | call to patch | HTTParty | Httparty.rb:11:16:11:36 | "http://example.com/" | Httparty.rb:11:1:11:56 | call to patch | -| Httparty.rb:15:9:15:46 | call to delete | HTTParty | Httparty.rb:15:25:15:45 | "http://example.com/" | Httparty.rb:16:1:16:10 | call to body | -| Httparty.rb:18:9:18:44 | call to head | HTTParty | Httparty.rb:18:23:18:43 | "http://example.com/" | Httparty.rb:19:1:19:10 | call to body | -| Httparty.rb:21:9:21:47 | call to options | HTTParty | Httparty.rb:21:26:21:46 | "http://example.com/" | Httparty.rb:22:1:22:10 | call to body | -| NetHttp.rb:4:1:4:18 | call to get | Net::HTTP | NetHttp.rb:4:15:4:17 | uri | NetHttp.rb:4:1:4:18 | call to get | -| NetHttp.rb:6:8:6:50 | call to post | Net::HTTP | NetHttp.rb:6:23:6:36 | call to parse | NetHttp.rb:7:1:7:9 | call to body | -| NetHttp.rb:6:8:6:50 | call to post | Net::HTTP | NetHttp.rb:6:23:6:36 | call to parse | NetHttp.rb:8:1:8:14 | call to read_body | -| NetHttp.rb:6:8:6:50 | call to post | Net::HTTP | NetHttp.rb:6:23:6:36 | call to parse | NetHttp.rb:9:1:9:11 | call to entity | -| NetHttp.rb:13:6:13:17 | call to get | Net::HTTP | NetHttp.rb:11:21:11:41 | "https://example.com" | NetHttp.rb:18:1:18:7 | call to body | -| NetHttp.rb:13:6:13:17 | call to get | Net::HTTP | NetHttp.rb:13:14:13:16 | "/" | NetHttp.rb:18:1:18:7 | call to body | -| NetHttp.rb:14:6:14:18 | call to post | Net::HTTP | NetHttp.rb:11:21:11:41 | "https://example.com" | NetHttp.rb:19:1:19:12 | call to read_body | -| NetHttp.rb:14:6:14:18 | call to post | Net::HTTP | NetHttp.rb:14:15:14:17 | "/" | NetHttp.rb:19:1:19:12 | call to read_body | -| NetHttp.rb:15:6:15:17 | call to put | Net::HTTP | NetHttp.rb:11:21:11:41 | "https://example.com" | NetHttp.rb:20:1:20:9 | call to entity | -| NetHttp.rb:15:6:15:17 | call to put | Net::HTTP | NetHttp.rb:15:14:15:16 | "/" | NetHttp.rb:20:1:20:9 | call to entity | -| NetHttp.rb:24:3:24:33 | call to get | Net::HTTP | NetHttp.rb:24:17:24:22 | domain | NetHttp.rb:27:1:27:28 | call to body | -| NetHttp.rb:24:3:24:33 | call to get | Net::HTTP | NetHttp.rb:24:29:24:32 | path | NetHttp.rb:27:1:27:28 | call to body | -| OpenURI.rb:3:9:3:41 | call to open | OpenURI | OpenURI.rb:3:21:3:40 | "http://example.com" | OpenURI.rb:4:1:4:10 | call to read | -| OpenURI.rb:6:9:6:34 | call to open | OpenURI | OpenURI.rb:6:14:6:33 | "http://example.com" | OpenURI.rb:7:1:7:15 | call to readlines | -| OpenURI.rb:9:9:9:38 | call to open | OpenURI | OpenURI.rb:9:18:9:37 | "http://example.com" | OpenURI.rb:10:1:10:10 | call to read | -| OpenURI.rb:15:9:15:47 | call to open_uri | OpenURI | OpenURI.rb:15:26:15:46 | "https://example.com" | OpenURI.rb:16:1:16:10 | call to read | -| RestClient.rb:3:9:3:45 | call to get | RestClient | RestClient.rb:3:24:3:44 | "http://example.com/" | RestClient.rb:4:1:4:10 | call to body | -| RestClient.rb:6:9:6:59 | call to post | RestClient | RestClient.rb:6:25:6:44 | "http://example.com" | RestClient.rb:7:1:7:10 | call to body | -| RestClient.rb:9:9:9:58 | call to put | RestClient | RestClient.rb:9:24:9:43 | "http://example.com" | RestClient.rb:10:1:10:10 | call to body | -| RestClient.rb:12:9:12:60 | call to patch | RestClient | RestClient.rb:12:26:12:45 | "http://example.com" | RestClient.rb:13:1:13:10 | call to body | -| RestClient.rb:15:9:15:47 | call to delete | RestClient | RestClient.rb:15:27:15:46 | "http://example.com" | RestClient.rb:16:1:16:10 | call to body | -| RestClient.rb:18:9:18:45 | call to head | RestClient | RestClient.rb:18:25:18:44 | "http://example.com" | RestClient.rb:19:1:19:10 | call to body | -| RestClient.rb:21:9:21:48 | call to options | RestClient | RestClient.rb:21:28:21:47 | "http://example.com" | RestClient.rb:22:1:22:10 | call to body | -| RestClient.rb:28:9:28:85 | call to execute | RestClient | RestClient.rb:28:56:28:84 | "http://example.com/resource" | RestClient.rb:29:1:29:10 | call to body | -| Typhoeus.rb:3:9:3:43 | call to get | Typhoeus | Typhoeus.rb:3:22:3:42 | "http://example.com/" | Typhoeus.rb:4:1:4:10 | call to body | -| Typhoeus.rb:6:9:6:63 | call to post | Typhoeus | Typhoeus.rb:6:23:6:43 | "http://example.com/" | Typhoeus.rb:7:1:7:10 | call to body | -| Typhoeus.rb:9:9:9:62 | call to put | Typhoeus | Typhoeus.rb:9:22:9:42 | "http://example.com/" | Typhoeus.rb:10:1:10:10 | call to body | -| Typhoeus.rb:12:9:12:64 | call to patch | Typhoeus | Typhoeus.rb:12:24:12:44 | "http://example.com/" | Typhoeus.rb:13:1:13:10 | call to body | -| Typhoeus.rb:15:9:15:46 | call to delete | Typhoeus | Typhoeus.rb:15:25:15:45 | "http://example.com/" | Typhoeus.rb:16:1:16:10 | call to body | -| Typhoeus.rb:18:9:18:44 | call to head | Typhoeus | Typhoeus.rb:18:23:18:43 | "http://example.com/" | Typhoeus.rb:19:1:19:10 | call to body | -| Typhoeus.rb:21:9:21:47 | call to options | Typhoeus | Typhoeus.rb:21:26:21:46 | "http://example.com/" | Typhoeus.rb:22:1:22:10 | call to body | +httpRequests +| Excon.rb:3:9:3:40 | call to get | +| Excon.rb:6:9:6:60 | call to post | +| Excon.rb:9:9:9:59 | call to put | +| Excon.rb:12:9:12:61 | call to patch | +| Excon.rb:15:9:15:43 | call to delete | +| Excon.rb:18:9:18:41 | call to head | +| Excon.rb:21:9:21:44 | call to options | +| Excon.rb:24:9:24:42 | call to trace | +| Excon.rb:28:9:28:34 | call to get | +| Excon.rb:31:10:31:39 | call to post | +| Excon.rb:35:9:35:34 | call to get | +| Excon.rb:38:10:38:39 | call to post | +| Faraday.rb:3:9:3:42 | call to get | +| Faraday.rb:6:9:6:62 | call to post | +| Faraday.rb:9:9:9:61 | call to put | +| Faraday.rb:12:9:12:63 | call to patch | +| Faraday.rb:15:9:15:45 | call to delete | +| Faraday.rb:18:9:18:43 | call to head | +| Faraday.rb:24:9:24:44 | call to trace | +| Faraday.rb:28:9:28:27 | call to get | +| Faraday.rb:31:10:31:46 | call to post | +| Faraday.rb:35:10:35:28 | call to get | +| Faraday.rb:39:10:39:28 | call to get | +| HttpClient.rb:3:9:3:45 | call to get | +| HttpClient.rb:6:9:6:65 | call to post | +| HttpClient.rb:9:9:9:64 | call to put | +| HttpClient.rb:12:9:12:48 | call to delete | +| HttpClient.rb:15:9:15:46 | call to head | +| HttpClient.rb:18:9:18:49 | call to options | +| HttpClient.rb:21:9:21:47 | call to trace | +| HttpClient.rb:24:9:24:53 | call to get_content | +| HttpClient.rb:26:10:26:74 | call to post_content | +| Httparty.rb:5:1:5:35 | call to get | +| Httparty.rb:7:1:7:55 | call to post | +| Httparty.rb:9:1:9:54 | call to put | +| Httparty.rb:11:1:11:56 | call to patch | +| Httparty.rb:15:9:15:46 | call to delete | +| Httparty.rb:18:9:18:44 | call to head | +| Httparty.rb:21:9:21:47 | call to options | +| NetHttp.rb:4:1:4:18 | call to get | +| NetHttp.rb:6:8:6:50 | call to post | +| NetHttp.rb:13:6:13:17 | call to get | +| NetHttp.rb:14:6:14:18 | call to post | +| NetHttp.rb:15:6:15:17 | call to put | +| NetHttp.rb:16:6:16:19 | call to patch | +| NetHttp.rb:24:3:24:33 | call to get | +| NetHttp.rb:29:1:29:32 | call to post | +| OpenURI.rb:3:9:3:41 | call to open | +| OpenURI.rb:6:9:6:34 | call to open | +| OpenURI.rb:9:9:9:38 | call to open | +| OpenURI.rb:12:9:12:45 | call to open | +| OpenURI.rb:15:9:15:47 | call to open_uri | +| RestClient.rb:3:9:3:45 | call to get | +| RestClient.rb:6:9:6:59 | call to post | +| RestClient.rb:9:9:9:58 | call to put | +| RestClient.rb:12:9:12:60 | call to patch | +| RestClient.rb:15:9:15:47 | call to delete | +| RestClient.rb:18:9:18:45 | call to head | +| RestClient.rb:21:9:21:48 | call to options | +| RestClient.rb:25:9:25:21 | call to get | +| RestClient.rb:28:9:28:85 | call to execute | +| Typhoeus.rb:3:9:3:43 | call to get | +| Typhoeus.rb:6:9:6:63 | call to post | +| Typhoeus.rb:9:9:9:62 | call to put | +| Typhoeus.rb:12:9:12:64 | call to patch | +| Typhoeus.rb:15:9:15:46 | call to delete | +| Typhoeus.rb:18:9:18:44 | call to head | +| Typhoeus.rb:21:9:21:47 | call to options | +getFramework +| Excon.rb:3:9:3:40 | call to get | Excon | +| Excon.rb:6:9:6:60 | call to post | Excon | +| Excon.rb:9:9:9:59 | call to put | Excon | +| Excon.rb:12:9:12:61 | call to patch | Excon | +| Excon.rb:15:9:15:43 | call to delete | Excon | +| Excon.rb:18:9:18:41 | call to head | Excon | +| Excon.rb:21:9:21:44 | call to options | Excon | +| Excon.rb:24:9:24:42 | call to trace | Excon | +| Excon.rb:28:9:28:34 | call to get | Excon | +| Excon.rb:31:10:31:39 | call to post | Excon | +| Excon.rb:35:9:35:34 | call to get | Excon | +| Excon.rb:38:10:38:39 | call to post | Excon | +| Faraday.rb:3:9:3:42 | call to get | Faraday | +| Faraday.rb:6:9:6:62 | call to post | Faraday | +| Faraday.rb:9:9:9:61 | call to put | Faraday | +| Faraday.rb:12:9:12:63 | call to patch | Faraday | +| Faraday.rb:15:9:15:45 | call to delete | Faraday | +| Faraday.rb:18:9:18:43 | call to head | Faraday | +| Faraday.rb:24:9:24:44 | call to trace | Faraday | +| Faraday.rb:28:9:28:27 | call to get | Faraday | +| Faraday.rb:31:10:31:46 | call to post | Faraday | +| Faraday.rb:35:10:35:28 | call to get | Faraday | +| Faraday.rb:39:10:39:28 | call to get | Faraday | +| HttpClient.rb:3:9:3:45 | call to get | HTTPClient | +| HttpClient.rb:6:9:6:65 | call to post | HTTPClient | +| HttpClient.rb:9:9:9:64 | call to put | HTTPClient | +| HttpClient.rb:12:9:12:48 | call to delete | HTTPClient | +| HttpClient.rb:15:9:15:46 | call to head | HTTPClient | +| HttpClient.rb:18:9:18:49 | call to options | HTTPClient | +| HttpClient.rb:21:9:21:47 | call to trace | HTTPClient | +| HttpClient.rb:24:9:24:53 | call to get_content | HTTPClient | +| HttpClient.rb:26:10:26:74 | call to post_content | HTTPClient | +| Httparty.rb:5:1:5:35 | call to get | HTTParty | +| Httparty.rb:7:1:7:55 | call to post | HTTParty | +| Httparty.rb:9:1:9:54 | call to put | HTTParty | +| Httparty.rb:11:1:11:56 | call to patch | HTTParty | +| Httparty.rb:15:9:15:46 | call to delete | HTTParty | +| Httparty.rb:18:9:18:44 | call to head | HTTParty | +| Httparty.rb:21:9:21:47 | call to options | HTTParty | +| NetHttp.rb:4:1:4:18 | call to get | Net::HTTP | +| NetHttp.rb:6:8:6:50 | call to post | Net::HTTP | +| NetHttp.rb:13:6:13:17 | call to get | Net::HTTP | +| NetHttp.rb:14:6:14:18 | call to post | Net::HTTP | +| NetHttp.rb:15:6:15:17 | call to put | Net::HTTP | +| NetHttp.rb:16:6:16:19 | call to patch | Net::HTTP | +| NetHttp.rb:24:3:24:33 | call to get | Net::HTTP | +| NetHttp.rb:29:1:29:32 | call to post | Net::HTTP | +| OpenURI.rb:3:9:3:41 | call to open | OpenURI | +| OpenURI.rb:6:9:6:34 | call to open | OpenURI | +| OpenURI.rb:9:9:9:38 | call to open | OpenURI | +| OpenURI.rb:12:9:12:45 | call to open | OpenURI | +| OpenURI.rb:15:9:15:47 | call to open_uri | OpenURI | +| RestClient.rb:3:9:3:45 | call to get | RestClient | +| RestClient.rb:6:9:6:59 | call to post | RestClient | +| RestClient.rb:9:9:9:58 | call to put | RestClient | +| RestClient.rb:12:9:12:60 | call to patch | RestClient | +| RestClient.rb:15:9:15:47 | call to delete | RestClient | +| RestClient.rb:18:9:18:45 | call to head | RestClient | +| RestClient.rb:21:9:21:48 | call to options | RestClient | +| RestClient.rb:25:9:25:21 | call to get | RestClient | +| RestClient.rb:28:9:28:85 | call to execute | RestClient | +| Typhoeus.rb:3:9:3:43 | call to get | Typhoeus | +| Typhoeus.rb:6:9:6:63 | call to post | Typhoeus | +| Typhoeus.rb:9:9:9:62 | call to put | Typhoeus | +| Typhoeus.rb:12:9:12:64 | call to patch | Typhoeus | +| Typhoeus.rb:15:9:15:46 | call to delete | Typhoeus | +| Typhoeus.rb:18:9:18:44 | call to head | Typhoeus | +| Typhoeus.rb:21:9:21:47 | call to options | Typhoeus | +getResponseBody +| Excon.rb:3:9:3:40 | call to get | Excon.rb:4:1:4:10 | call to body | +| Excon.rb:6:9:6:60 | call to post | Excon.rb:7:1:7:10 | call to body | +| Excon.rb:9:9:9:59 | call to put | Excon.rb:10:1:10:10 | call to body | +| Excon.rb:12:9:12:61 | call to patch | Excon.rb:13:1:13:10 | call to body | +| Excon.rb:15:9:15:43 | call to delete | Excon.rb:16:1:16:10 | call to body | +| Excon.rb:18:9:18:41 | call to head | Excon.rb:19:1:19:10 | call to body | +| Excon.rb:21:9:21:44 | call to options | Excon.rb:22:1:22:10 | call to body | +| Excon.rb:24:9:24:42 | call to trace | Excon.rb:25:1:25:10 | call to body | +| Excon.rb:28:9:28:34 | call to get | Excon.rb:29:1:29:10 | call to body | +| Excon.rb:31:10:31:39 | call to post | Excon.rb:32:1:32:11 | call to body | +| Excon.rb:35:9:35:34 | call to get | Excon.rb:36:1:36:10 | call to body | +| Excon.rb:38:10:38:39 | call to post | Excon.rb:39:1:39:11 | call to body | +| Faraday.rb:3:9:3:42 | call to get | Faraday.rb:4:1:4:10 | call to body | +| Faraday.rb:6:9:6:62 | call to post | Faraday.rb:7:1:7:10 | call to body | +| Faraday.rb:9:9:9:61 | call to put | Faraday.rb:10:1:10:10 | call to body | +| Faraday.rb:12:9:12:63 | call to patch | Faraday.rb:13:1:13:10 | call to body | +| Faraday.rb:15:9:15:45 | call to delete | Faraday.rb:16:1:16:10 | call to body | +| Faraday.rb:18:9:18:43 | call to head | Faraday.rb:19:1:19:10 | call to body | +| Faraday.rb:24:9:24:44 | call to trace | Faraday.rb:25:1:25:10 | call to body | +| Faraday.rb:28:9:28:27 | call to get | Faraday.rb:29:1:29:10 | call to body | +| Faraday.rb:31:10:31:46 | call to post | Faraday.rb:32:1:32:11 | call to body | +| Faraday.rb:35:10:35:28 | call to get | Faraday.rb:36:1:36:11 | call to body | +| Faraday.rb:39:10:39:28 | call to get | Faraday.rb:40:1:40:11 | call to body | +| HttpClient.rb:3:9:3:45 | call to get | HttpClient.rb:4:1:4:10 | call to body | +| HttpClient.rb:6:9:6:65 | call to post | HttpClient.rb:7:1:7:13 | call to content | +| HttpClient.rb:9:9:9:64 | call to put | HttpClient.rb:10:1:10:15 | call to http_body | +| HttpClient.rb:12:9:12:48 | call to delete | HttpClient.rb:13:1:13:10 | call to dump | +| HttpClient.rb:15:9:15:46 | call to head | HttpClient.rb:16:1:16:10 | call to body | +| HttpClient.rb:18:9:18:49 | call to options | HttpClient.rb:19:1:19:13 | call to content | +| HttpClient.rb:21:9:21:47 | call to trace | HttpClient.rb:22:1:22:15 | call to http_body | +| HttpClient.rb:24:9:24:53 | call to get_content | HttpClient.rb:24:9:24:53 | call to get_content | +| HttpClient.rb:26:10:26:74 | call to post_content | HttpClient.rb:26:10:26:74 | call to post_content | +| Httparty.rb:5:1:5:35 | call to get | Httparty.rb:5:1:5:35 | call to get | +| Httparty.rb:7:1:7:55 | call to post | Httparty.rb:7:1:7:55 | call to post | +| Httparty.rb:9:1:9:54 | call to put | Httparty.rb:9:1:9:54 | call to put | +| Httparty.rb:11:1:11:56 | call to patch | Httparty.rb:11:1:11:56 | call to patch | +| Httparty.rb:15:9:15:46 | call to delete | Httparty.rb:16:1:16:10 | call to body | +| Httparty.rb:18:9:18:44 | call to head | Httparty.rb:19:1:19:10 | call to body | +| Httparty.rb:21:9:21:47 | call to options | Httparty.rb:22:1:22:10 | call to body | +| NetHttp.rb:4:1:4:18 | call to get | NetHttp.rb:4:1:4:18 | call to get | +| NetHttp.rb:6:8:6:50 | call to post | NetHttp.rb:7:1:7:9 | call to body | +| NetHttp.rb:6:8:6:50 | call to post | NetHttp.rb:8:1:8:14 | call to read_body | +| NetHttp.rb:6:8:6:50 | call to post | NetHttp.rb:9:1:9:11 | call to entity | +| NetHttp.rb:13:6:13:17 | call to get | NetHttp.rb:18:1:18:7 | call to body | +| NetHttp.rb:14:6:14:18 | call to post | NetHttp.rb:19:1:19:12 | call to read_body | +| NetHttp.rb:15:6:15:17 | call to put | NetHttp.rb:20:1:20:9 | call to entity | +| NetHttp.rb:24:3:24:33 | call to get | NetHttp.rb:27:1:27:28 | call to body | +| OpenURI.rb:3:9:3:41 | call to open | OpenURI.rb:4:1:4:10 | call to read | +| OpenURI.rb:6:9:6:34 | call to open | OpenURI.rb:7:1:7:15 | call to readlines | +| OpenURI.rb:9:9:9:38 | call to open | OpenURI.rb:10:1:10:10 | call to read | +| OpenURI.rb:12:9:12:45 | call to open | OpenURI.rb:13:1:13:10 | call to read | +| OpenURI.rb:15:9:15:47 | call to open_uri | OpenURI.rb:16:1:16:10 | call to read | +| RestClient.rb:3:9:3:45 | call to get | RestClient.rb:4:1:4:10 | call to body | +| RestClient.rb:6:9:6:59 | call to post | RestClient.rb:7:1:7:10 | call to body | +| RestClient.rb:9:9:9:58 | call to put | RestClient.rb:10:1:10:10 | call to body | +| RestClient.rb:12:9:12:60 | call to patch | RestClient.rb:13:1:13:10 | call to body | +| RestClient.rb:15:9:15:47 | call to delete | RestClient.rb:16:1:16:10 | call to body | +| RestClient.rb:18:9:18:45 | call to head | RestClient.rb:19:1:19:10 | call to body | +| RestClient.rb:21:9:21:48 | call to options | RestClient.rb:22:1:22:10 | call to body | +| RestClient.rb:25:9:25:21 | call to get | RestClient.rb:26:1:26:10 | call to body | +| RestClient.rb:28:9:28:85 | call to execute | RestClient.rb:29:1:29:10 | call to body | +| Typhoeus.rb:3:9:3:43 | call to get | Typhoeus.rb:4:1:4:10 | call to body | +| Typhoeus.rb:6:9:6:63 | call to post | Typhoeus.rb:7:1:7:10 | call to body | +| Typhoeus.rb:9:9:9:62 | call to put | Typhoeus.rb:10:1:10:10 | call to body | +| Typhoeus.rb:12:9:12:64 | call to patch | Typhoeus.rb:13:1:13:10 | call to body | +| Typhoeus.rb:15:9:15:46 | call to delete | Typhoeus.rb:16:1:16:10 | call to body | +| Typhoeus.rb:18:9:18:44 | call to head | Typhoeus.rb:19:1:19:10 | call to body | +| Typhoeus.rb:21:9:21:47 | call to options | Typhoeus.rb:22:1:22:10 | call to body | +getAUrlPart +| Excon.rb:3:9:3:40 | call to get | Excon.rb:3:19:3:39 | "http://example.com/" | +| Excon.rb:6:9:6:60 | call to post | Excon.rb:6:20:6:40 | "http://example.com/" | +| Excon.rb:9:9:9:59 | call to put | Excon.rb:9:19:9:39 | "http://example.com/" | +| Excon.rb:12:9:12:61 | call to patch | Excon.rb:12:21:12:41 | "http://example.com/" | +| Excon.rb:15:9:15:43 | call to delete | Excon.rb:15:22:15:42 | "http://example.com/" | +| Excon.rb:18:9:18:41 | call to head | Excon.rb:18:20:18:40 | "http://example.com/" | +| Excon.rb:21:9:21:44 | call to options | Excon.rb:21:23:21:43 | "http://example.com/" | +| Excon.rb:24:9:24:42 | call to trace | Excon.rb:24:21:24:41 | "http://example.com/" | +| Excon.rb:28:9:28:34 | call to get | Excon.rb:27:25:27:44 | "http://example.com" | +| Excon.rb:28:9:28:34 | call to get | Excon.rb:28:31:28:33 | "/" | +| Excon.rb:31:10:31:39 | call to post | Excon.rb:27:25:27:44 | "http://example.com" | +| Excon.rb:31:10:31:39 | call to post | Excon.rb:31:33:31:38 | "/foo" | +| Excon.rb:35:9:35:34 | call to get | Excon.rb:34:37:34:56 | "http://example.com" | +| Excon.rb:35:9:35:34 | call to get | Excon.rb:35:31:35:33 | "/" | +| Excon.rb:38:10:38:39 | call to post | Excon.rb:34:37:34:56 | "http://example.com" | +| Excon.rb:38:10:38:39 | call to post | Excon.rb:38:33:38:38 | "/foo" | +| Faraday.rb:3:9:3:42 | call to get | Faraday.rb:3:21:3:41 | "http://example.com/" | +| Faraday.rb:6:9:6:62 | call to post | Faraday.rb:6:22:6:42 | "http://example.com/" | +| Faraday.rb:9:9:9:61 | call to put | Faraday.rb:9:21:9:41 | "http://example.com/" | +| Faraday.rb:12:9:12:63 | call to patch | Faraday.rb:12:23:12:43 | "http://example.com/" | +| Faraday.rb:15:9:15:45 | call to delete | Faraday.rb:15:24:15:44 | "http://example.com/" | +| Faraday.rb:18:9:18:43 | call to head | Faraday.rb:18:22:18:42 | "http://example.com/" | +| Faraday.rb:24:9:24:44 | call to trace | Faraday.rb:24:23:24:43 | "http://example.com/" | +| Faraday.rb:28:9:28:27 | call to get | Faraday.rb:27:26:27:45 | "http://example.com" | +| Faraday.rb:28:9:28:27 | call to get | Faraday.rb:28:24:28:26 | "/" | +| Faraday.rb:31:10:31:46 | call to post | Faraday.rb:27:26:27:45 | "http://example.com" | +| Faraday.rb:31:10:31:46 | call to post | Faraday.rb:31:26:31:31 | "/foo" | +| Faraday.rb:35:10:35:28 | call to get | Faraday.rb:34:26:34:50 | Pair | +| Faraday.rb:35:10:35:28 | call to get | Faraday.rb:34:31:34:50 | "http://example.com" | +| Faraday.rb:35:10:35:28 | call to get | Faraday.rb:35:25:35:27 | "/" | +| Faraday.rb:39:10:39:28 | call to get | Faraday.rb:38:38:38:63 | Pair | +| Faraday.rb:39:10:39:28 | call to get | Faraday.rb:38:43:38:63 | "https://example.com" | +| Faraday.rb:39:10:39:28 | call to get | Faraday.rb:39:25:39:27 | "/" | +| HttpClient.rb:3:9:3:45 | call to get | HttpClient.rb:3:24:3:44 | "http://example.com/" | +| HttpClient.rb:6:9:6:65 | call to post | HttpClient.rb:6:25:6:45 | "http://example.com/" | +| HttpClient.rb:9:9:9:64 | call to put | HttpClient.rb:9:24:9:44 | "http://example.com/" | +| HttpClient.rb:12:9:12:48 | call to delete | HttpClient.rb:12:27:12:47 | "http://example.com/" | +| HttpClient.rb:15:9:15:46 | call to head | HttpClient.rb:15:25:15:45 | "http://example.com/" | +| HttpClient.rb:18:9:18:49 | call to options | HttpClient.rb:18:28:18:48 | "http://example.com/" | +| HttpClient.rb:21:9:21:47 | call to trace | HttpClient.rb:21:26:21:46 | "http://example.com/" | +| HttpClient.rb:24:9:24:53 | call to get_content | HttpClient.rb:24:32:24:52 | "http://example.com/" | +| HttpClient.rb:26:10:26:74 | call to post_content | HttpClient.rb:26:34:26:54 | "http://example.com/" | +| Httparty.rb:5:1:5:35 | call to get | Httparty.rb:5:14:5:34 | "http://example.com/" | +| Httparty.rb:7:1:7:55 | call to post | Httparty.rb:7:15:7:35 | "http://example.com/" | +| Httparty.rb:9:1:9:54 | call to put | Httparty.rb:9:14:9:34 | "http://example.com/" | +| Httparty.rb:11:1:11:56 | call to patch | Httparty.rb:11:16:11:36 | "http://example.com/" | +| Httparty.rb:15:9:15:46 | call to delete | Httparty.rb:15:25:15:45 | "http://example.com/" | +| Httparty.rb:18:9:18:44 | call to head | Httparty.rb:18:23:18:43 | "http://example.com/" | +| Httparty.rb:21:9:21:47 | call to options | Httparty.rb:21:26:21:46 | "http://example.com/" | +| NetHttp.rb:4:1:4:18 | call to get | NetHttp.rb:4:15:4:17 | uri | +| NetHttp.rb:6:8:6:50 | call to post | NetHttp.rb:6:23:6:36 | call to parse | +| NetHttp.rb:13:6:13:17 | call to get | NetHttp.rb:11:21:11:41 | "https://example.com" | +| NetHttp.rb:13:6:13:17 | call to get | NetHttp.rb:13:14:13:16 | "/" | +| NetHttp.rb:14:6:14:18 | call to post | NetHttp.rb:11:21:11:41 | "https://example.com" | +| NetHttp.rb:14:6:14:18 | call to post | NetHttp.rb:14:15:14:17 | "/" | +| NetHttp.rb:15:6:15:17 | call to put | NetHttp.rb:11:21:11:41 | "https://example.com" | +| NetHttp.rb:15:6:15:17 | call to put | NetHttp.rb:15:14:15:16 | "/" | +| NetHttp.rb:16:6:16:19 | call to patch | NetHttp.rb:11:21:11:41 | "https://example.com" | +| NetHttp.rb:16:6:16:19 | call to patch | NetHttp.rb:16:16:16:18 | "/" | +| NetHttp.rb:24:3:24:33 | call to get | NetHttp.rb:24:17:24:22 | domain | +| NetHttp.rb:24:3:24:33 | call to get | NetHttp.rb:24:29:24:32 | path | +| NetHttp.rb:29:1:29:32 | call to post | NetHttp.rb:29:16:29:18 | uri | +| OpenURI.rb:3:9:3:41 | call to open | OpenURI.rb:3:21:3:40 | "http://example.com" | +| OpenURI.rb:6:9:6:34 | call to open | OpenURI.rb:6:14:6:33 | "http://example.com" | +| OpenURI.rb:9:9:9:38 | call to open | OpenURI.rb:9:18:9:37 | "http://example.com" | +| OpenURI.rb:15:9:15:47 | call to open_uri | OpenURI.rb:15:26:15:46 | "https://example.com" | +| RestClient.rb:3:9:3:45 | call to get | RestClient.rb:3:24:3:44 | "http://example.com/" | +| RestClient.rb:6:9:6:59 | call to post | RestClient.rb:6:25:6:44 | "http://example.com" | +| RestClient.rb:9:9:9:58 | call to put | RestClient.rb:9:24:9:43 | "http://example.com" | +| RestClient.rb:12:9:12:60 | call to patch | RestClient.rb:12:26:12:45 | "http://example.com" | +| RestClient.rb:15:9:15:47 | call to delete | RestClient.rb:15:27:15:46 | "http://example.com" | +| RestClient.rb:18:9:18:45 | call to head | RestClient.rb:18:25:18:44 | "http://example.com" | +| RestClient.rb:21:9:21:48 | call to options | RestClient.rb:21:28:21:47 | "http://example.com" | +| RestClient.rb:28:9:28:85 | call to execute | RestClient.rb:28:56:28:84 | "http://example.com/resource" | +| Typhoeus.rb:3:9:3:43 | call to get | Typhoeus.rb:3:22:3:42 | "http://example.com/" | +| Typhoeus.rb:6:9:6:63 | call to post | Typhoeus.rb:6:23:6:43 | "http://example.com/" | +| Typhoeus.rb:9:9:9:62 | call to put | Typhoeus.rb:9:22:9:42 | "http://example.com/" | +| Typhoeus.rb:12:9:12:64 | call to patch | Typhoeus.rb:12:24:12:44 | "http://example.com/" | +| Typhoeus.rb:15:9:15:46 | call to delete | Typhoeus.rb:15:25:15:45 | "http://example.com/" | +| Typhoeus.rb:18:9:18:44 | call to head | Typhoeus.rb:18:23:18:43 | "http://example.com/" | +| Typhoeus.rb:21:9:21:47 | call to options | Typhoeus.rb:21:26:21:46 | "http://example.com/" | diff --git a/ruby/ql/test/library-tests/frameworks/http_clients/HttpClients.ql b/ruby/ql/test/library-tests/frameworks/http_clients/HttpClients.ql index 0bcc883c364..7ccc8efbbde 100644 --- a/ruby/ql/test/library-tests/frameworks/http_clients/HttpClients.ql +++ b/ruby/ql/test/library-tests/frameworks/http_clients/HttpClients.ql @@ -1,10 +1,10 @@ import codeql.ruby.Concepts import codeql.ruby.DataFlow -query predicate httpRequests( - Http::Client::Request r, string framework, DataFlow::Node urlPart, DataFlow::Node responseBody -) { - r.getFramework() = framework and - r.getAUrlPart() = urlPart and - r.getResponseBody() = responseBody -} +query predicate httpRequests(Http::Client::Request r) { any() } + +query string getFramework(Http::Client::Request req) { result = req.getFramework() } + +query DataFlow::Node getResponseBody(Http::Client::Request req) { result = req.getResponseBody() } + +query DataFlow::Node getAUrlPart(Http::Client::Request req) { result = req.getAUrlPart() } diff --git a/ruby/ql/test/library-tests/frameworks/http_clients/NetHttp.rb b/ruby/ql/test/library-tests/frameworks/http_clients/NetHttp.rb index 12333be9f4e..608b46ece9a 100644 --- a/ruby/ql/test/library-tests/frameworks/http_clients/NetHttp.rb +++ b/ruby/ql/test/library-tests/frameworks/http_clients/NetHttp.rb @@ -25,3 +25,5 @@ def get(domain, path) end get("example.com", "/").body + +Net::HTTP.post(uri, "some_body") # note: response body not accessed diff --git a/swift/downgrades/e457bc35325b05725c00471da8843f293fe26f8d/module_decl_exported_modules.ql b/swift/downgrades/e457bc35325b05725c00471da8843f293fe26f8d/module_decl_exported_modules.ql new file mode 100644 index 00000000000..6f2f7125742 --- /dev/null +++ b/swift/downgrades/e457bc35325b05725c00471da8843f293fe26f8d/module_decl_exported_modules.ql @@ -0,0 +1,15 @@ +class Element extends @element { + string toString() { none() } +} + +int getExportedModuleIndex(Element m, Element i) { + i = + rank[result + 1](Element j, string name | + module_decl_exported_modules(m, j) and type_decls(j, name) + | + j order by name + ) +} + +from Element m, Element i +select m, getExportedModuleIndex(m, i), i diff --git a/swift/downgrades/e457bc35325b05725c00471da8843f293fe26f8d/module_decl_imported_modules.ql b/swift/downgrades/e457bc35325b05725c00471da8843f293fe26f8d/module_decl_imported_modules.ql new file mode 100644 index 00000000000..88093d6e5e5 --- /dev/null +++ b/swift/downgrades/e457bc35325b05725c00471da8843f293fe26f8d/module_decl_imported_modules.ql @@ -0,0 +1,15 @@ +class Element extends @element { + string toString() { none() } +} + +int getImportedModuleIndex(Element m, Element i) { + i = + rank[result + 1](Element j, string name | + module_decl_imported_modules(m, j) and type_decls(j, name) + | + j order by name + ) +} + +from Element m, Element i +select m, getImportedModuleIndex(m, i), i diff --git a/swift/downgrades/e457bc35325b05725c00471da8843f293fe26f8d/old.dbscheme b/swift/downgrades/e457bc35325b05725c00471da8843f293fe26f8d/old.dbscheme new file mode 100644 index 00000000000..e457bc35325 --- /dev/null +++ b/swift/downgrades/e457bc35325b05725c00471da8843f293fe26f8d/old.dbscheme @@ -0,0 +1,2598 @@ +// generated by codegen/codegen.py + +// from prefix.dbscheme +/** + * The source location of the snapshot. + */ +sourceLocationPrefix( + string prefix: string ref +); + + +// from schema.py + +@element = + @callable +| @file +| @generic_context +| @locatable +| @location +| @type +; + +#keyset[id] +element_is_unknown( + int id: @element ref +); + +@callable = + @abstract_closure_expr +| @abstract_function_decl +; + +#keyset[id] +callable_names( + int id: @callable ref, + string name: string ref +); + +#keyset[id] +callable_self_params( + int id: @callable ref, + int self_param: @param_decl_or_none ref +); + +#keyset[id, index] +callable_params( + int id: @callable ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +#keyset[id] +callable_bodies( + int id: @callable ref, + int body: @brace_stmt_or_none ref +); + +#keyset[id, index] +callable_captures( + int id: @callable ref, + int index: int ref, + int capture: @captured_decl_or_none ref +); + +@file = + @db_file +; + +#keyset[id] +files( + int id: @file ref, + string name: string ref +); + +#keyset[id] +file_is_successfully_extracted( + int id: @file ref +); + +@locatable = + @argument +| @ast_node +| @comment +| @diagnostics +| @error_element +; + +#keyset[id] +locatable_locations( + int id: @locatable ref, + int location: @location_or_none ref +); + +@location = + @db_location +; + +#keyset[id] +locations( + int id: @location ref, + int file: @file_or_none ref, + int start_line: int ref, + int start_column: int ref, + int end_line: int ref, + int end_column: int ref +); + +@ast_node = + @availability_info +| @availability_spec +| @case_label_item +| @condition_element +| @decl +| @expr +| @pattern +| @stmt +| @stmt_condition +| @type_repr +; + +comments( + unique int id: @comment, + string text: string ref +); + +db_files( + unique int id: @db_file +); + +db_locations( + unique int id: @db_location +); + +diagnostics( + unique int id: @diagnostics, + string text: string ref, + int kind: int ref +); + +@error_element = + @error_expr +| @error_type +| @overloaded_decl_ref_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_chain_result_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @unresolved_type +| @unresolved_type_conversion_expr +| @unspecified_element +; + +availability_infos( + unique int id: @availability_info +); + +#keyset[id] +availability_info_is_unavailable( + int id: @availability_info ref +); + +#keyset[id, index] +availability_info_specs( + int id: @availability_info ref, + int index: int ref, + int spec: @availability_spec_or_none ref +); + +@availability_spec = + @other_availability_spec +| @platform_version_availability_spec +; + +unspecified_elements( + unique int id: @unspecified_element, + string property: string ref, + string error: string ref +); + +#keyset[id] +unspecified_element_parents( + int id: @unspecified_element ref, + int parent: @element ref +); + +#keyset[id] +unspecified_element_indices( + int id: @unspecified_element ref, + int index: int ref +); + +other_availability_specs( + unique int id: @other_availability_spec +); + +platform_version_availability_specs( + unique int id: @platform_version_availability_spec, + string platform: string ref, + string version: string ref +); + +@decl = + @captured_decl +| @enum_case_decl +| @extension_decl +| @if_config_decl +| @import_decl +| @missing_member_decl +| @operator_decl +| @pattern_binding_decl +| @pound_diagnostic_decl +| @precedence_group_decl +| @top_level_code_decl +| @value_decl +; + +#keyset[id] +decls( //dir=decl + int id: @decl ref, + int module: @module_decl_or_none ref +); + +#keyset[id, index] +decl_members( //dir=decl + int id: @decl ref, + int index: int ref, + int member: @decl_or_none ref +); + +@generic_context = + @abstract_function_decl +| @extension_decl +| @generic_type_decl +| @subscript_decl +; + +#keyset[id, index] +generic_context_generic_type_params( //dir=decl + int id: @generic_context ref, + int index: int ref, + int generic_type_param: @generic_type_param_decl_or_none ref +); + +captured_decls( //dir=decl + unique int id: @captured_decl, + int decl: @value_decl_or_none ref +); + +#keyset[id] +captured_decl_is_direct( //dir=decl + int id: @captured_decl ref +); + +#keyset[id] +captured_decl_is_escaping( //dir=decl + int id: @captured_decl ref +); + +enum_case_decls( //dir=decl + unique int id: @enum_case_decl +); + +#keyset[id, index] +enum_case_decl_elements( //dir=decl + int id: @enum_case_decl ref, + int index: int ref, + int element: @enum_element_decl_or_none ref +); + +extension_decls( //dir=decl + unique int id: @extension_decl, + int extended_type_decl: @nominal_type_decl_or_none ref +); + +#keyset[id, index] +extension_decl_protocols( //dir=decl + int id: @extension_decl ref, + int index: int ref, + int protocol: @protocol_decl_or_none ref +); + +if_config_decls( //dir=decl + unique int id: @if_config_decl +); + +#keyset[id, index] +if_config_decl_active_elements( //dir=decl + int id: @if_config_decl ref, + int index: int ref, + int active_element: @ast_node_or_none ref +); + +import_decls( //dir=decl + unique int id: @import_decl +); + +#keyset[id] +import_decl_is_exported( //dir=decl + int id: @import_decl ref +); + +#keyset[id] +import_decl_imported_modules( //dir=decl + int id: @import_decl ref, + int imported_module: @module_decl_or_none ref +); + +#keyset[id, index] +import_decl_declarations( //dir=decl + int id: @import_decl ref, + int index: int ref, + int declaration: @value_decl_or_none ref +); + +missing_member_decls( //dir=decl + unique int id: @missing_member_decl, + string name: string ref +); + +@operator_decl = + @infix_operator_decl +| @postfix_operator_decl +| @prefix_operator_decl +; + +#keyset[id] +operator_decls( //dir=decl + int id: @operator_decl ref, + string name: string ref +); + +pattern_binding_decls( //dir=decl + unique int id: @pattern_binding_decl +); + +#keyset[id, index] +pattern_binding_decl_inits( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int init: @expr_or_none ref +); + +#keyset[id, index] +pattern_binding_decl_patterns( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int pattern: @pattern_or_none ref +); + +pound_diagnostic_decls( //dir=decl + unique int id: @pound_diagnostic_decl, + int kind: int ref, + int message: @string_literal_expr_or_none ref +); + +precedence_group_decls( //dir=decl + unique int id: @precedence_group_decl +); + +top_level_code_decls( //dir=decl + unique int id: @top_level_code_decl, + int body: @brace_stmt_or_none ref +); + +@value_decl = + @abstract_function_decl +| @abstract_storage_decl +| @enum_element_decl +| @type_decl +; + +#keyset[id] +value_decls( //dir=decl + int id: @value_decl ref, + int interface_type: @type_or_none ref +); + +@abstract_function_decl = + @constructor_decl +| @destructor_decl +| @func_decl +; + +@abstract_storage_decl = + @subscript_decl +| @var_decl +; + +#keyset[id, index] +abstract_storage_decl_accessor_decls( //dir=decl + int id: @abstract_storage_decl ref, + int index: int ref, + int accessor_decl: @accessor_decl_or_none ref +); + +enum_element_decls( //dir=decl + unique int id: @enum_element_decl, + string name: string ref +); + +#keyset[id, index] +enum_element_decl_params( //dir=decl + int id: @enum_element_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +infix_operator_decls( //dir=decl + unique int id: @infix_operator_decl +); + +#keyset[id] +infix_operator_decl_precedence_groups( //dir=decl + int id: @infix_operator_decl ref, + int precedence_group: @precedence_group_decl_or_none ref +); + +postfix_operator_decls( //dir=decl + unique int id: @postfix_operator_decl +); + +prefix_operator_decls( //dir=decl + unique int id: @prefix_operator_decl +); + +@type_decl = + @abstract_type_param_decl +| @generic_type_decl +| @module_decl +; + +#keyset[id] +type_decls( //dir=decl + int id: @type_decl ref, + string name: string ref +); + +#keyset[id, index] +type_decl_base_types( //dir=decl + int id: @type_decl ref, + int index: int ref, + int base_type: @type_or_none ref +); + +@abstract_type_param_decl = + @associated_type_decl +| @generic_type_param_decl +; + +constructor_decls( //dir=decl + unique int id: @constructor_decl +); + +destructor_decls( //dir=decl + unique int id: @destructor_decl +); + +@func_decl = + @accessor_decl +| @concrete_func_decl +; + +@generic_type_decl = + @nominal_type_decl +| @opaque_type_decl +| @type_alias_decl +; + +module_decls( //dir=decl + unique int id: @module_decl +); + +#keyset[id] +module_decl_is_builtin_module( //dir=decl + int id: @module_decl ref +); + +#keyset[id] +module_decl_is_system_module( //dir=decl + int id: @module_decl ref +); + +module_decl_imported_modules( //dir=decl + int id: @module_decl ref, + int imported_module: @module_decl_or_none ref +); + +module_decl_exported_modules( //dir=decl + int id: @module_decl ref, + int exported_module: @module_decl_or_none ref +); + +subscript_decls( //dir=decl + unique int id: @subscript_decl, + int element_type: @type_or_none ref +); + +#keyset[id, index] +subscript_decl_params( //dir=decl + int id: @subscript_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +@var_decl = + @concrete_var_decl +| @param_decl +; + +#keyset[id] +var_decls( //dir=decl + int id: @var_decl ref, + string name: string ref, + int type_: @type_or_none ref +); + +#keyset[id] +var_decl_attached_property_wrapper_types( //dir=decl + int id: @var_decl ref, + int attached_property_wrapper_type: @type_or_none ref +); + +#keyset[id] +var_decl_parent_patterns( //dir=decl + int id: @var_decl ref, + int parent_pattern: @pattern_or_none ref +); + +#keyset[id] +var_decl_parent_initializers( //dir=decl + int id: @var_decl ref, + int parent_initializer: @expr_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var: @var_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var: @var_decl_or_none ref +); + +accessor_decls( //dir=decl + unique int id: @accessor_decl +); + +#keyset[id] +accessor_decl_is_getter( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_setter( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_will_set( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_did_set( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_read( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_modify( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_unsafe_address( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_unsafe_mutable_address( //dir=decl + int id: @accessor_decl ref +); + +associated_type_decls( //dir=decl + unique int id: @associated_type_decl +); + +concrete_func_decls( //dir=decl + unique int id: @concrete_func_decl +); + +concrete_var_decls( //dir=decl + unique int id: @concrete_var_decl, + int introducer_int: int ref +); + +generic_type_param_decls( //dir=decl + unique int id: @generic_type_param_decl +); + +@nominal_type_decl = + @class_decl +| @enum_decl +| @protocol_decl +| @struct_decl +; + +#keyset[id] +nominal_type_decls( //dir=decl + int id: @nominal_type_decl ref, + int type_: @type_or_none ref +); + +opaque_type_decls( //dir=decl + unique int id: @opaque_type_decl, + int naming_declaration: @value_decl_or_none ref +); + +#keyset[id, index] +opaque_type_decl_opaque_generic_params( //dir=decl + int id: @opaque_type_decl ref, + int index: int ref, + int opaque_generic_param: @generic_type_param_type_or_none ref +); + +param_decls( //dir=decl + unique int id: @param_decl +); + +#keyset[id] +param_decl_is_inout( //dir=decl + int id: @param_decl ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_var_bindings( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_vars( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var: @var_decl_or_none ref +); + +type_alias_decls( //dir=decl + unique int id: @type_alias_decl, + int aliased_type: @type_or_none ref +); + +class_decls( //dir=decl + unique int id: @class_decl +); + +enum_decls( //dir=decl + unique int id: @enum_decl +); + +protocol_decls( //dir=decl + unique int id: @protocol_decl +); + +struct_decls( //dir=decl + unique int id: @struct_decl +); + +arguments( //dir=expr + unique int id: @argument, + string label: string ref, + int expr: @expr_or_none ref +); + +@expr = + @abstract_closure_expr +| @any_try_expr +| @applied_property_wrapper_expr +| @apply_expr +| @assign_expr +| @bind_optional_expr +| @capture_list_expr +| @collection_expr +| @decl_ref_expr +| @default_argument_expr +| @discard_assignment_expr +| @dot_syntax_base_ignored_expr +| @dynamic_type_expr +| @enum_is_case_expr +| @error_expr +| @explicit_cast_expr +| @force_value_expr +| @identity_expr +| @if_expr +| @implicit_conversion_expr +| @in_out_expr +| @key_path_application_expr +| @key_path_dot_expr +| @key_path_expr +| @lazy_initializer_expr +| @literal_expr +| @lookup_expr +| @make_temporarily_escapable_expr +| @obj_c_selector_expr +| @one_way_expr +| @opaque_value_expr +| @open_existential_expr +| @optional_evaluation_expr +| @other_constructor_decl_ref_expr +| @overloaded_decl_ref_expr +| @property_wrapper_value_placeholder_expr +| @rebind_self_in_constructor_expr +| @sequence_expr +| @super_ref_expr +| @tap_expr +| @tuple_element_expr +| @tuple_expr +| @type_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @vararg_expansion_expr +; + +#keyset[id] +expr_types( //dir=expr + int id: @expr ref, + int type_: @type_or_none ref +); + +@abstract_closure_expr = + @auto_closure_expr +| @closure_expr +; + +@any_try_expr = + @force_try_expr +| @optional_try_expr +| @try_expr +; + +#keyset[id] +any_try_exprs( //dir=expr + int id: @any_try_expr ref, + int sub_expr: @expr_or_none ref +); + +applied_property_wrapper_exprs( //dir=expr + unique int id: @applied_property_wrapper_expr, + int kind: int ref, + int value: @expr_or_none ref, + int param: @param_decl_or_none ref +); + +@apply_expr = + @binary_expr +| @call_expr +| @postfix_unary_expr +| @prefix_unary_expr +| @self_apply_expr +; + +#keyset[id] +apply_exprs( //dir=expr + int id: @apply_expr ref, + int function: @expr_or_none ref +); + +#keyset[id, index] +apply_expr_arguments( //dir=expr + int id: @apply_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +assign_exprs( //dir=expr + unique int id: @assign_expr, + int dest: @expr_or_none ref, + int source: @expr_or_none ref +); + +bind_optional_exprs( //dir=expr + unique int id: @bind_optional_expr, + int sub_expr: @expr_or_none ref +); + +capture_list_exprs( //dir=expr + unique int id: @capture_list_expr, + int closure_body: @closure_expr_or_none ref +); + +#keyset[id, index] +capture_list_expr_binding_decls( //dir=expr + int id: @capture_list_expr ref, + int index: int ref, + int binding_decl: @pattern_binding_decl_or_none ref +); + +@collection_expr = + @array_expr +| @dictionary_expr +; + +decl_ref_exprs( //dir=expr + unique int id: @decl_ref_expr, + int decl: @decl_or_none ref +); + +#keyset[id, index] +decl_ref_expr_replacement_types( //dir=expr + int id: @decl_ref_expr ref, + int index: int ref, + int replacement_type: @type_or_none ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_ordinary_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_distributed_thunk_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +default_argument_exprs( //dir=expr + unique int id: @default_argument_expr, + int param_decl: @param_decl_or_none ref, + int param_index: int ref +); + +#keyset[id] +default_argument_expr_caller_side_defaults( //dir=expr + int id: @default_argument_expr ref, + int caller_side_default: @expr_or_none ref +); + +discard_assignment_exprs( //dir=expr + unique int id: @discard_assignment_expr +); + +dot_syntax_base_ignored_exprs( //dir=expr + unique int id: @dot_syntax_base_ignored_expr, + int qualifier: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +dynamic_type_exprs( //dir=expr + unique int id: @dynamic_type_expr, + int base: @expr_or_none ref +); + +enum_is_case_exprs( //dir=expr + unique int id: @enum_is_case_expr, + int sub_expr: @expr_or_none ref, + int element: @enum_element_decl_or_none ref +); + +error_exprs( //dir=expr + unique int id: @error_expr +); + +@explicit_cast_expr = + @checked_cast_expr +| @coerce_expr +; + +#keyset[id] +explicit_cast_exprs( //dir=expr + int id: @explicit_cast_expr ref, + int sub_expr: @expr_or_none ref +); + +force_value_exprs( //dir=expr + unique int id: @force_value_expr, + int sub_expr: @expr_or_none ref +); + +@identity_expr = + @await_expr +| @dot_self_expr +| @paren_expr +| @unresolved_member_chain_result_expr +; + +#keyset[id] +identity_exprs( //dir=expr + int id: @identity_expr ref, + int sub_expr: @expr_or_none ref +); + +if_exprs( //dir=expr + unique int id: @if_expr, + int condition: @expr_or_none ref, + int then_expr: @expr_or_none ref, + int else_expr: @expr_or_none ref +); + +@implicit_conversion_expr = + @abi_safe_conversion_expr +| @any_hashable_erasure_expr +| @archetype_to_super_expr +| @array_to_pointer_expr +| @bridge_from_obj_c_expr +| @bridge_to_obj_c_expr +| @class_metatype_to_object_expr +| @collection_upcast_conversion_expr +| @conditional_bridge_from_obj_c_expr +| @covariant_function_conversion_expr +| @covariant_return_conversion_expr +| @derived_to_base_expr +| @destructure_tuple_expr +| @differentiable_function_expr +| @differentiable_function_extract_original_expr +| @erasure_expr +| @existential_metatype_to_object_expr +| @foreign_object_conversion_expr +| @function_conversion_expr +| @in_out_to_pointer_expr +| @inject_into_optional_expr +| @linear_function_expr +| @linear_function_extract_original_expr +| @linear_to_differentiable_function_expr +| @load_expr +| @metatype_conversion_expr +| @pointer_to_pointer_expr +| @protocol_metatype_to_object_expr +| @string_to_pointer_expr +| @underlying_to_opaque_expr +| @unevaluated_instance_expr +| @unresolved_type_conversion_expr +; + +#keyset[id] +implicit_conversion_exprs( //dir=expr + int id: @implicit_conversion_expr ref, + int sub_expr: @expr_or_none ref +); + +in_out_exprs( //dir=expr + unique int id: @in_out_expr, + int sub_expr: @expr_or_none ref +); + +key_path_application_exprs( //dir=expr + unique int id: @key_path_application_expr, + int base: @expr_or_none ref, + int key_path: @expr_or_none ref +); + +key_path_dot_exprs( //dir=expr + unique int id: @key_path_dot_expr +); + +key_path_exprs( //dir=expr + unique int id: @key_path_expr +); + +#keyset[id] +key_path_expr_roots( //dir=expr + int id: @key_path_expr ref, + int root: @type_repr_or_none ref +); + +#keyset[id] +key_path_expr_parsed_paths( //dir=expr + int id: @key_path_expr ref, + int parsed_path: @expr_or_none ref +); + +lazy_initializer_exprs( //dir=expr + unique int id: @lazy_initializer_expr, + int sub_expr: @expr_or_none ref +); + +@literal_expr = + @builtin_literal_expr +| @interpolated_string_literal_expr +| @nil_literal_expr +| @object_literal_expr +| @regex_literal_expr +; + +@lookup_expr = + @dynamic_lookup_expr +| @member_ref_expr +| @subscript_expr +; + +#keyset[id] +lookup_exprs( //dir=expr + int id: @lookup_expr ref, + int base: @expr_or_none ref +); + +#keyset[id] +lookup_expr_members( //dir=expr + int id: @lookup_expr ref, + int member: @decl_or_none ref +); + +make_temporarily_escapable_exprs( //dir=expr + unique int id: @make_temporarily_escapable_expr, + int escaping_closure: @opaque_value_expr_or_none ref, + int nonescaping_closure: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +obj_c_selector_exprs( //dir=expr + unique int id: @obj_c_selector_expr, + int sub_expr: @expr_or_none ref, + int method: @abstract_function_decl_or_none ref +); + +one_way_exprs( //dir=expr + unique int id: @one_way_expr, + int sub_expr: @expr_or_none ref +); + +opaque_value_exprs( //dir=expr + unique int id: @opaque_value_expr +); + +open_existential_exprs( //dir=expr + unique int id: @open_existential_expr, + int sub_expr: @expr_or_none ref, + int existential: @expr_or_none ref, + int opaque_expr: @opaque_value_expr_or_none ref +); + +optional_evaluation_exprs( //dir=expr + unique int id: @optional_evaluation_expr, + int sub_expr: @expr_or_none ref +); + +other_constructor_decl_ref_exprs( //dir=expr + unique int id: @other_constructor_decl_ref_expr, + int constructor_decl: @constructor_decl_or_none ref +); + +overloaded_decl_ref_exprs( //dir=expr + unique int id: @overloaded_decl_ref_expr +); + +#keyset[id, index] +overloaded_decl_ref_expr_possible_declarations( //dir=expr + int id: @overloaded_decl_ref_expr ref, + int index: int ref, + int possible_declaration: @value_decl_or_none ref +); + +property_wrapper_value_placeholder_exprs( //dir=expr + unique int id: @property_wrapper_value_placeholder_expr, + int placeholder: @opaque_value_expr_or_none ref +); + +#keyset[id] +property_wrapper_value_placeholder_expr_wrapped_values( //dir=expr + int id: @property_wrapper_value_placeholder_expr ref, + int wrapped_value: @expr_or_none ref +); + +rebind_self_in_constructor_exprs( //dir=expr + unique int id: @rebind_self_in_constructor_expr, + int sub_expr: @expr_or_none ref, + int self: @var_decl_or_none ref +); + +sequence_exprs( //dir=expr + unique int id: @sequence_expr +); + +#keyset[id, index] +sequence_expr_elements( //dir=expr + int id: @sequence_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +super_ref_exprs( //dir=expr + unique int id: @super_ref_expr, + int self: @var_decl_or_none ref +); + +tap_exprs( //dir=expr + unique int id: @tap_expr, + int body: @brace_stmt_or_none ref, + int var: @var_decl_or_none ref +); + +#keyset[id] +tap_expr_sub_exprs( //dir=expr + int id: @tap_expr ref, + int sub_expr: @expr_or_none ref +); + +tuple_element_exprs( //dir=expr + unique int id: @tuple_element_expr, + int sub_expr: @expr_or_none ref, + int index: int ref +); + +tuple_exprs( //dir=expr + unique int id: @tuple_expr +); + +#keyset[id, index] +tuple_expr_elements( //dir=expr + int id: @tuple_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +type_exprs( //dir=expr + unique int id: @type_expr +); + +#keyset[id] +type_expr_type_reprs( //dir=expr + int id: @type_expr ref, + int type_repr: @type_repr_or_none ref +); + +unresolved_decl_ref_exprs( //dir=expr + unique int id: @unresolved_decl_ref_expr +); + +#keyset[id] +unresolved_decl_ref_expr_names( //dir=expr + int id: @unresolved_decl_ref_expr ref, + string name: string ref +); + +unresolved_dot_exprs( //dir=expr + unique int id: @unresolved_dot_expr, + int base: @expr_or_none ref, + string name: string ref +); + +unresolved_member_exprs( //dir=expr + unique int id: @unresolved_member_expr, + string name: string ref +); + +unresolved_pattern_exprs( //dir=expr + unique int id: @unresolved_pattern_expr, + int sub_pattern: @pattern_or_none ref +); + +unresolved_specialize_exprs( //dir=expr + unique int id: @unresolved_specialize_expr, + int sub_expr: @expr_or_none ref +); + +vararg_expansion_exprs( //dir=expr + unique int id: @vararg_expansion_expr, + int sub_expr: @expr_or_none ref +); + +abi_safe_conversion_exprs( //dir=expr + unique int id: @abi_safe_conversion_expr +); + +any_hashable_erasure_exprs( //dir=expr + unique int id: @any_hashable_erasure_expr +); + +archetype_to_super_exprs( //dir=expr + unique int id: @archetype_to_super_expr +); + +array_exprs( //dir=expr + unique int id: @array_expr +); + +#keyset[id, index] +array_expr_elements( //dir=expr + int id: @array_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +array_to_pointer_exprs( //dir=expr + unique int id: @array_to_pointer_expr +); + +auto_closure_exprs( //dir=expr + unique int id: @auto_closure_expr +); + +await_exprs( //dir=expr + unique int id: @await_expr +); + +binary_exprs( //dir=expr + unique int id: @binary_expr +); + +bridge_from_obj_c_exprs( //dir=expr + unique int id: @bridge_from_obj_c_expr +); + +bridge_to_obj_c_exprs( //dir=expr + unique int id: @bridge_to_obj_c_expr +); + +@builtin_literal_expr = + @boolean_literal_expr +| @magic_identifier_literal_expr +| @number_literal_expr +| @string_literal_expr +; + +call_exprs( //dir=expr + unique int id: @call_expr +); + +@checked_cast_expr = + @conditional_checked_cast_expr +| @forced_checked_cast_expr +| @is_expr +; + +class_metatype_to_object_exprs( //dir=expr + unique int id: @class_metatype_to_object_expr +); + +closure_exprs( //dir=expr + unique int id: @closure_expr +); + +coerce_exprs( //dir=expr + unique int id: @coerce_expr +); + +collection_upcast_conversion_exprs( //dir=expr + unique int id: @collection_upcast_conversion_expr +); + +conditional_bridge_from_obj_c_exprs( //dir=expr + unique int id: @conditional_bridge_from_obj_c_expr +); + +covariant_function_conversion_exprs( //dir=expr + unique int id: @covariant_function_conversion_expr +); + +covariant_return_conversion_exprs( //dir=expr + unique int id: @covariant_return_conversion_expr +); + +derived_to_base_exprs( //dir=expr + unique int id: @derived_to_base_expr +); + +destructure_tuple_exprs( //dir=expr + unique int id: @destructure_tuple_expr +); + +dictionary_exprs( //dir=expr + unique int id: @dictionary_expr +); + +#keyset[id, index] +dictionary_expr_elements( //dir=expr + int id: @dictionary_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +differentiable_function_exprs( //dir=expr + unique int id: @differentiable_function_expr +); + +differentiable_function_extract_original_exprs( //dir=expr + unique int id: @differentiable_function_extract_original_expr +); + +dot_self_exprs( //dir=expr + unique int id: @dot_self_expr +); + +@dynamic_lookup_expr = + @dynamic_member_ref_expr +| @dynamic_subscript_expr +; + +erasure_exprs( //dir=expr + unique int id: @erasure_expr +); + +existential_metatype_to_object_exprs( //dir=expr + unique int id: @existential_metatype_to_object_expr +); + +force_try_exprs( //dir=expr + unique int id: @force_try_expr +); + +foreign_object_conversion_exprs( //dir=expr + unique int id: @foreign_object_conversion_expr +); + +function_conversion_exprs( //dir=expr + unique int id: @function_conversion_expr +); + +in_out_to_pointer_exprs( //dir=expr + unique int id: @in_out_to_pointer_expr +); + +inject_into_optional_exprs( //dir=expr + unique int id: @inject_into_optional_expr +); + +interpolated_string_literal_exprs( //dir=expr + unique int id: @interpolated_string_literal_expr +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_expr: @opaque_value_expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_count_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_count_expr: @expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_literal_capacity_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int literal_capacity_expr: @expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_appending_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int appending_expr: @tap_expr_or_none ref +); + +linear_function_exprs( //dir=expr + unique int id: @linear_function_expr +); + +linear_function_extract_original_exprs( //dir=expr + unique int id: @linear_function_extract_original_expr +); + +linear_to_differentiable_function_exprs( //dir=expr + unique int id: @linear_to_differentiable_function_expr +); + +load_exprs( //dir=expr + unique int id: @load_expr +); + +member_ref_exprs( //dir=expr + unique int id: @member_ref_expr +); + +#keyset[id] +member_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_ordinary_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_distributed_thunk_semantics( //dir=expr + int id: @member_ref_expr ref +); + +metatype_conversion_exprs( //dir=expr + unique int id: @metatype_conversion_expr +); + +nil_literal_exprs( //dir=expr + unique int id: @nil_literal_expr +); + +object_literal_exprs( //dir=expr + unique int id: @object_literal_expr, + int kind: int ref +); + +#keyset[id, index] +object_literal_expr_arguments( //dir=expr + int id: @object_literal_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +optional_try_exprs( //dir=expr + unique int id: @optional_try_expr +); + +paren_exprs( //dir=expr + unique int id: @paren_expr +); + +pointer_to_pointer_exprs( //dir=expr + unique int id: @pointer_to_pointer_expr +); + +postfix_unary_exprs( //dir=expr + unique int id: @postfix_unary_expr +); + +prefix_unary_exprs( //dir=expr + unique int id: @prefix_unary_expr +); + +protocol_metatype_to_object_exprs( //dir=expr + unique int id: @protocol_metatype_to_object_expr +); + +regex_literal_exprs( //dir=expr + unique int id: @regex_literal_expr, + string pattern: string ref, + int version: int ref +); + +@self_apply_expr = + @constructor_ref_call_expr +| @dot_syntax_call_expr +; + +#keyset[id] +self_apply_exprs( //dir=expr + int id: @self_apply_expr ref, + int base: @expr_or_none ref +); + +string_to_pointer_exprs( //dir=expr + unique int id: @string_to_pointer_expr +); + +subscript_exprs( //dir=expr + unique int id: @subscript_expr +); + +#keyset[id, index] +subscript_expr_arguments( //dir=expr + int id: @subscript_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +#keyset[id] +subscript_expr_has_direct_to_storage_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_ordinary_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_distributed_thunk_semantics( //dir=expr + int id: @subscript_expr ref +); + +try_exprs( //dir=expr + unique int id: @try_expr +); + +underlying_to_opaque_exprs( //dir=expr + unique int id: @underlying_to_opaque_expr +); + +unevaluated_instance_exprs( //dir=expr + unique int id: @unevaluated_instance_expr +); + +unresolved_member_chain_result_exprs( //dir=expr + unique int id: @unresolved_member_chain_result_expr +); + +unresolved_type_conversion_exprs( //dir=expr + unique int id: @unresolved_type_conversion_expr +); + +boolean_literal_exprs( //dir=expr + unique int id: @boolean_literal_expr, + boolean value: boolean ref +); + +conditional_checked_cast_exprs( //dir=expr + unique int id: @conditional_checked_cast_expr +); + +constructor_ref_call_exprs( //dir=expr + unique int id: @constructor_ref_call_expr +); + +dot_syntax_call_exprs( //dir=expr + unique int id: @dot_syntax_call_expr +); + +dynamic_member_ref_exprs( //dir=expr + unique int id: @dynamic_member_ref_expr +); + +dynamic_subscript_exprs( //dir=expr + unique int id: @dynamic_subscript_expr +); + +forced_checked_cast_exprs( //dir=expr + unique int id: @forced_checked_cast_expr +); + +is_exprs( //dir=expr + unique int id: @is_expr +); + +magic_identifier_literal_exprs( //dir=expr + unique int id: @magic_identifier_literal_expr, + string kind: string ref +); + +@number_literal_expr = + @float_literal_expr +| @integer_literal_expr +; + +string_literal_exprs( //dir=expr + unique int id: @string_literal_expr, + string value: string ref +); + +float_literal_exprs( //dir=expr + unique int id: @float_literal_expr, + string string_value: string ref +); + +integer_literal_exprs( //dir=expr + unique int id: @integer_literal_expr, + string string_value: string ref +); + +@pattern = + @any_pattern +| @binding_pattern +| @bool_pattern +| @enum_element_pattern +| @expr_pattern +| @is_pattern +| @named_pattern +| @optional_some_pattern +| @paren_pattern +| @tuple_pattern +| @typed_pattern +; + +any_patterns( //dir=pattern + unique int id: @any_pattern +); + +binding_patterns( //dir=pattern + unique int id: @binding_pattern, + int sub_pattern: @pattern_or_none ref +); + +bool_patterns( //dir=pattern + unique int id: @bool_pattern, + boolean value: boolean ref +); + +enum_element_patterns( //dir=pattern + unique int id: @enum_element_pattern, + int element: @enum_element_decl_or_none ref +); + +#keyset[id] +enum_element_pattern_sub_patterns( //dir=pattern + int id: @enum_element_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +expr_patterns( //dir=pattern + unique int id: @expr_pattern, + int sub_expr: @expr_or_none ref +); + +is_patterns( //dir=pattern + unique int id: @is_pattern +); + +#keyset[id] +is_pattern_cast_type_reprs( //dir=pattern + int id: @is_pattern ref, + int cast_type_repr: @type_repr_or_none ref +); + +#keyset[id] +is_pattern_sub_patterns( //dir=pattern + int id: @is_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +named_patterns( //dir=pattern + unique int id: @named_pattern, + string name: string ref +); + +optional_some_patterns( //dir=pattern + unique int id: @optional_some_pattern, + int sub_pattern: @pattern_or_none ref +); + +paren_patterns( //dir=pattern + unique int id: @paren_pattern, + int sub_pattern: @pattern_or_none ref +); + +tuple_patterns( //dir=pattern + unique int id: @tuple_pattern +); + +#keyset[id, index] +tuple_pattern_elements( //dir=pattern + int id: @tuple_pattern ref, + int index: int ref, + int element: @pattern_or_none ref +); + +typed_patterns( //dir=pattern + unique int id: @typed_pattern, + int sub_pattern: @pattern_or_none ref +); + +#keyset[id] +typed_pattern_type_reprs( //dir=pattern + int id: @typed_pattern ref, + int type_repr: @type_repr_or_none ref +); + +case_label_items( //dir=stmt + unique int id: @case_label_item, + int pattern: @pattern_or_none ref +); + +#keyset[id] +case_label_item_guards( //dir=stmt + int id: @case_label_item ref, + int guard: @expr_or_none ref +); + +condition_elements( //dir=stmt + unique int id: @condition_element +); + +#keyset[id] +condition_element_booleans( //dir=stmt + int id: @condition_element ref, + int boolean_: @expr_or_none ref +); + +#keyset[id] +condition_element_patterns( //dir=stmt + int id: @condition_element ref, + int pattern: @pattern_or_none ref +); + +#keyset[id] +condition_element_initializers( //dir=stmt + int id: @condition_element ref, + int initializer: @expr_or_none ref +); + +#keyset[id] +condition_element_availabilities( //dir=stmt + int id: @condition_element ref, + int availability: @availability_info_or_none ref +); + +@stmt = + @brace_stmt +| @break_stmt +| @case_stmt +| @continue_stmt +| @defer_stmt +| @fail_stmt +| @fallthrough_stmt +| @labeled_stmt +| @pound_assert_stmt +| @return_stmt +| @throw_stmt +| @yield_stmt +; + +stmt_conditions( //dir=stmt + unique int id: @stmt_condition +); + +#keyset[id, index] +stmt_condition_elements( //dir=stmt + int id: @stmt_condition ref, + int index: int ref, + int element: @condition_element_or_none ref +); + +brace_stmts( //dir=stmt + unique int id: @brace_stmt +); + +#keyset[id, index] +brace_stmt_elements( //dir=stmt + int id: @brace_stmt ref, + int index: int ref, + int element: @ast_node_or_none ref +); + +break_stmts( //dir=stmt + unique int id: @break_stmt +); + +#keyset[id] +break_stmt_target_names( //dir=stmt + int id: @break_stmt ref, + string target_name: string ref +); + +#keyset[id] +break_stmt_targets( //dir=stmt + int id: @break_stmt ref, + int target: @stmt_or_none ref +); + +case_stmts( //dir=stmt + unique int id: @case_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +case_stmt_labels( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int label: @case_label_item_or_none ref +); + +#keyset[id, index] +case_stmt_variables( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int variable: @var_decl_or_none ref +); + +continue_stmts( //dir=stmt + unique int id: @continue_stmt +); + +#keyset[id] +continue_stmt_target_names( //dir=stmt + int id: @continue_stmt ref, + string target_name: string ref +); + +#keyset[id] +continue_stmt_targets( //dir=stmt + int id: @continue_stmt ref, + int target: @stmt_or_none ref +); + +defer_stmts( //dir=stmt + unique int id: @defer_stmt, + int body: @brace_stmt_or_none ref +); + +fail_stmts( //dir=stmt + unique int id: @fail_stmt +); + +fallthrough_stmts( //dir=stmt + unique int id: @fallthrough_stmt, + int fallthrough_source: @case_stmt_or_none ref, + int fallthrough_dest: @case_stmt_or_none ref +); + +@labeled_stmt = + @do_catch_stmt +| @do_stmt +| @for_each_stmt +| @labeled_conditional_stmt +| @repeat_while_stmt +| @switch_stmt +; + +#keyset[id] +labeled_stmt_labels( //dir=stmt + int id: @labeled_stmt ref, + string label: string ref +); + +pound_assert_stmts( //dir=stmt + unique int id: @pound_assert_stmt, + int condition: @expr_or_none ref, + string message: string ref +); + +return_stmts( //dir=stmt + unique int id: @return_stmt +); + +#keyset[id] +return_stmt_results( //dir=stmt + int id: @return_stmt ref, + int result: @expr_or_none ref +); + +throw_stmts( //dir=stmt + unique int id: @throw_stmt, + int sub_expr: @expr_or_none ref +); + +yield_stmts( //dir=stmt + unique int id: @yield_stmt +); + +#keyset[id, index] +yield_stmt_results( //dir=stmt + int id: @yield_stmt ref, + int index: int ref, + int result: @expr_or_none ref +); + +do_catch_stmts( //dir=stmt + unique int id: @do_catch_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +do_catch_stmt_catches( //dir=stmt + int id: @do_catch_stmt ref, + int index: int ref, + int catch: @case_stmt_or_none ref +); + +do_stmts( //dir=stmt + unique int id: @do_stmt, + int body: @brace_stmt_or_none ref +); + +for_each_stmts( //dir=stmt + unique int id: @for_each_stmt, + int pattern: @pattern_or_none ref, + int sequence: @expr_or_none ref, + int body: @brace_stmt_or_none ref +); + +#keyset[id] +for_each_stmt_wheres( //dir=stmt + int id: @for_each_stmt ref, + int where: @expr_or_none ref +); + +@labeled_conditional_stmt = + @guard_stmt +| @if_stmt +| @while_stmt +; + +#keyset[id] +labeled_conditional_stmts( //dir=stmt + int id: @labeled_conditional_stmt ref, + int condition: @stmt_condition_or_none ref +); + +repeat_while_stmts( //dir=stmt + unique int id: @repeat_while_stmt, + int condition: @expr_or_none ref, + int body: @stmt_or_none ref +); + +switch_stmts( //dir=stmt + unique int id: @switch_stmt, + int expr: @expr_or_none ref +); + +#keyset[id, index] +switch_stmt_cases( //dir=stmt + int id: @switch_stmt ref, + int index: int ref, + int case_: @case_stmt_or_none ref +); + +guard_stmts( //dir=stmt + unique int id: @guard_stmt, + int body: @brace_stmt_or_none ref +); + +if_stmts( //dir=stmt + unique int id: @if_stmt, + int then: @stmt_or_none ref +); + +#keyset[id] +if_stmt_elses( //dir=stmt + int id: @if_stmt ref, + int else: @stmt_or_none ref +); + +while_stmts( //dir=stmt + unique int id: @while_stmt, + int body: @stmt_or_none ref +); + +@type = + @any_function_type +| @any_generic_type +| @any_metatype_type +| @builtin_type +| @dependent_member_type +| @dynamic_self_type +| @error_type +| @existential_type +| @in_out_type +| @l_value_type +| @module_type +| @parameterized_protocol_type +| @protocol_composition_type +| @reference_storage_type +| @substitutable_type +| @sugar_type +| @tuple_type +| @unresolved_type +; + +#keyset[id] +types( //dir=type + int id: @type ref, + string name: string ref, + int canonical_type: @type_or_none ref +); + +type_reprs( //dir=type + unique int id: @type_repr, + int type_: @type_or_none ref +); + +@any_function_type = + @function_type +| @generic_function_type +; + +#keyset[id] +any_function_types( //dir=type + int id: @any_function_type ref, + int result: @type_or_none ref +); + +#keyset[id, index] +any_function_type_param_types( //dir=type + int id: @any_function_type ref, + int index: int ref, + int param_type: @type_or_none ref +); + +#keyset[id] +any_function_type_is_throwing( //dir=type + int id: @any_function_type ref +); + +#keyset[id] +any_function_type_is_async( //dir=type + int id: @any_function_type ref +); + +@any_generic_type = + @nominal_or_bound_generic_nominal_type +| @unbound_generic_type +; + +#keyset[id] +any_generic_types( //dir=type + int id: @any_generic_type ref, + int declaration: @generic_type_decl_or_none ref +); + +#keyset[id] +any_generic_type_parents( //dir=type + int id: @any_generic_type ref, + int parent: @type_or_none ref +); + +@any_metatype_type = + @existential_metatype_type +| @metatype_type +; + +@builtin_type = + @any_builtin_integer_type +| @builtin_bridge_object_type +| @builtin_default_actor_storage_type +| @builtin_executor_type +| @builtin_float_type +| @builtin_job_type +| @builtin_native_object_type +| @builtin_raw_pointer_type +| @builtin_raw_unsafe_continuation_type +| @builtin_unsafe_value_buffer_type +| @builtin_vector_type +; + +dependent_member_types( //dir=type + unique int id: @dependent_member_type, + int base_type: @type_or_none ref, + int associated_type_decl: @associated_type_decl_or_none ref +); + +dynamic_self_types( //dir=type + unique int id: @dynamic_self_type, + int static_self_type: @type_or_none ref +); + +error_types( //dir=type + unique int id: @error_type +); + +existential_types( //dir=type + unique int id: @existential_type, + int constraint: @type_or_none ref +); + +in_out_types( //dir=type + unique int id: @in_out_type, + int object_type: @type_or_none ref +); + +l_value_types( //dir=type + unique int id: @l_value_type, + int object_type: @type_or_none ref +); + +module_types( //dir=type + unique int id: @module_type, + int module: @module_decl_or_none ref +); + +parameterized_protocol_types( //dir=type + unique int id: @parameterized_protocol_type, + int base: @protocol_type_or_none ref +); + +#keyset[id, index] +parameterized_protocol_type_args( //dir=type + int id: @parameterized_protocol_type ref, + int index: int ref, + int arg: @type_or_none ref +); + +protocol_composition_types( //dir=type + unique int id: @protocol_composition_type +); + +#keyset[id, index] +protocol_composition_type_members( //dir=type + int id: @protocol_composition_type ref, + int index: int ref, + int member: @type_or_none ref +); + +@reference_storage_type = + @unmanaged_storage_type +| @unowned_storage_type +| @weak_storage_type +; + +#keyset[id] +reference_storage_types( //dir=type + int id: @reference_storage_type ref, + int referent_type: @type_or_none ref +); + +@substitutable_type = + @archetype_type +| @generic_type_param_type +; + +@sugar_type = + @paren_type +| @syntax_sugar_type +| @type_alias_type +; + +tuple_types( //dir=type + unique int id: @tuple_type +); + +#keyset[id, index] +tuple_type_types( //dir=type + int id: @tuple_type ref, + int index: int ref, + int type_: @type_or_none ref +); + +#keyset[id, index] +tuple_type_names( //dir=type + int id: @tuple_type ref, + int index: int ref, + string name: string ref +); + +unresolved_types( //dir=type + unique int id: @unresolved_type +); + +@any_builtin_integer_type = + @builtin_integer_literal_type +| @builtin_integer_type +; + +@archetype_type = + @opaque_type_archetype_type +| @opened_archetype_type +| @primary_archetype_type +; + +#keyset[id] +archetype_types( //dir=type + int id: @archetype_type ref, + int interface_type: @type_or_none ref +); + +#keyset[id] +archetype_type_superclasses( //dir=type + int id: @archetype_type ref, + int superclass: @type_or_none ref +); + +#keyset[id, index] +archetype_type_protocols( //dir=type + int id: @archetype_type ref, + int index: int ref, + int protocol: @protocol_decl_or_none ref +); + +builtin_bridge_object_types( //dir=type + unique int id: @builtin_bridge_object_type +); + +builtin_default_actor_storage_types( //dir=type + unique int id: @builtin_default_actor_storage_type +); + +builtin_executor_types( //dir=type + unique int id: @builtin_executor_type +); + +builtin_float_types( //dir=type + unique int id: @builtin_float_type +); + +builtin_job_types( //dir=type + unique int id: @builtin_job_type +); + +builtin_native_object_types( //dir=type + unique int id: @builtin_native_object_type +); + +builtin_raw_pointer_types( //dir=type + unique int id: @builtin_raw_pointer_type +); + +builtin_raw_unsafe_continuation_types( //dir=type + unique int id: @builtin_raw_unsafe_continuation_type +); + +builtin_unsafe_value_buffer_types( //dir=type + unique int id: @builtin_unsafe_value_buffer_type +); + +builtin_vector_types( //dir=type + unique int id: @builtin_vector_type +); + +existential_metatype_types( //dir=type + unique int id: @existential_metatype_type +); + +function_types( //dir=type + unique int id: @function_type +); + +generic_function_types( //dir=type + unique int id: @generic_function_type +); + +#keyset[id, index] +generic_function_type_generic_params( //dir=type + int id: @generic_function_type ref, + int index: int ref, + int generic_param: @generic_type_param_type_or_none ref +); + +generic_type_param_types( //dir=type + unique int id: @generic_type_param_type +); + +metatype_types( //dir=type + unique int id: @metatype_type +); + +@nominal_or_bound_generic_nominal_type = + @bound_generic_type +| @nominal_type +; + +paren_types( //dir=type + unique int id: @paren_type, + int type_: @type_or_none ref +); + +@syntax_sugar_type = + @dictionary_type +| @unary_syntax_sugar_type +; + +type_alias_types( //dir=type + unique int id: @type_alias_type, + int decl: @type_alias_decl_or_none ref +); + +unbound_generic_types( //dir=type + unique int id: @unbound_generic_type +); + +unmanaged_storage_types( //dir=type + unique int id: @unmanaged_storage_type +); + +unowned_storage_types( //dir=type + unique int id: @unowned_storage_type +); + +weak_storage_types( //dir=type + unique int id: @weak_storage_type +); + +@bound_generic_type = + @bound_generic_class_type +| @bound_generic_enum_type +| @bound_generic_struct_type +; + +#keyset[id, index] +bound_generic_type_arg_types( //dir=type + int id: @bound_generic_type ref, + int index: int ref, + int arg_type: @type_or_none ref +); + +builtin_integer_literal_types( //dir=type + unique int id: @builtin_integer_literal_type +); + +builtin_integer_types( //dir=type + unique int id: @builtin_integer_type +); + +#keyset[id] +builtin_integer_type_widths( //dir=type + int id: @builtin_integer_type ref, + int width: int ref +); + +dictionary_types( //dir=type + unique int id: @dictionary_type, + int key_type: @type_or_none ref, + int value_type: @type_or_none ref +); + +@nominal_type = + @class_type +| @enum_type +| @protocol_type +| @struct_type +; + +opaque_type_archetype_types( //dir=type + unique int id: @opaque_type_archetype_type, + int declaration: @opaque_type_decl_or_none ref +); + +opened_archetype_types( //dir=type + unique int id: @opened_archetype_type +); + +primary_archetype_types( //dir=type + unique int id: @primary_archetype_type +); + +@unary_syntax_sugar_type = + @array_slice_type +| @optional_type +| @variadic_sequence_type +; + +#keyset[id] +unary_syntax_sugar_types( //dir=type + int id: @unary_syntax_sugar_type ref, + int base_type: @type_or_none ref +); + +array_slice_types( //dir=type + unique int id: @array_slice_type +); + +bound_generic_class_types( //dir=type + unique int id: @bound_generic_class_type +); + +bound_generic_enum_types( //dir=type + unique int id: @bound_generic_enum_type +); + +bound_generic_struct_types( //dir=type + unique int id: @bound_generic_struct_type +); + +class_types( //dir=type + unique int id: @class_type +); + +enum_types( //dir=type + unique int id: @enum_type +); + +optional_types( //dir=type + unique int id: @optional_type +); + +protocol_types( //dir=type + unique int id: @protocol_type +); + +struct_types( //dir=type + unique int id: @struct_type +); + +variadic_sequence_types( //dir=type + unique int id: @variadic_sequence_type +); + +@abstract_function_decl_or_none = + @abstract_function_decl +| @unspecified_element +; + +@accessor_decl_or_none = + @accessor_decl +| @unspecified_element +; + +@argument_or_none = + @argument +| @unspecified_element +; + +@associated_type_decl_or_none = + @associated_type_decl +| @unspecified_element +; + +@ast_node_or_none = + @ast_node +| @unspecified_element +; + +@availability_info_or_none = + @availability_info +| @unspecified_element +; + +@availability_spec_or_none = + @availability_spec +| @unspecified_element +; + +@brace_stmt_or_none = + @brace_stmt +| @unspecified_element +; + +@captured_decl_or_none = + @captured_decl +| @unspecified_element +; + +@case_label_item_or_none = + @case_label_item +| @unspecified_element +; + +@case_stmt_or_none = + @case_stmt +| @unspecified_element +; + +@closure_expr_or_none = + @closure_expr +| @unspecified_element +; + +@condition_element_or_none = + @condition_element +| @unspecified_element +; + +@constructor_decl_or_none = + @constructor_decl +| @unspecified_element +; + +@decl_or_none = + @decl +| @unspecified_element +; + +@enum_element_decl_or_none = + @enum_element_decl +| @unspecified_element +; + +@expr_or_none = + @expr +| @unspecified_element +; + +@file_or_none = + @file +| @unspecified_element +; + +@generic_type_decl_or_none = + @generic_type_decl +| @unspecified_element +; + +@generic_type_param_decl_or_none = + @generic_type_param_decl +| @unspecified_element +; + +@generic_type_param_type_or_none = + @generic_type_param_type +| @unspecified_element +; + +@location_or_none = + @location +| @unspecified_element +; + +@module_decl_or_none = + @module_decl +| @unspecified_element +; + +@nominal_type_decl_or_none = + @nominal_type_decl +| @unspecified_element +; + +@opaque_type_decl_or_none = + @opaque_type_decl +| @unspecified_element +; + +@opaque_value_expr_or_none = + @opaque_value_expr +| @unspecified_element +; + +@param_decl_or_none = + @param_decl +| @unspecified_element +; + +@pattern_or_none = + @pattern +| @unspecified_element +; + +@pattern_binding_decl_or_none = + @pattern_binding_decl +| @unspecified_element +; + +@precedence_group_decl_or_none = + @precedence_group_decl +| @unspecified_element +; + +@protocol_decl_or_none = + @protocol_decl +| @unspecified_element +; + +@protocol_type_or_none = + @protocol_type +| @unspecified_element +; + +@stmt_or_none = + @stmt +| @unspecified_element +; + +@stmt_condition_or_none = + @stmt_condition +| @unspecified_element +; + +@string_literal_expr_or_none = + @string_literal_expr +| @unspecified_element +; + +@tap_expr_or_none = + @tap_expr +| @unspecified_element +; + +@type_or_none = + @type +| @unspecified_element +; + +@type_alias_decl_or_none = + @type_alias_decl +| @unspecified_element +; + +@type_repr_or_none = + @type_repr +| @unspecified_element +; + +@value_decl_or_none = + @unspecified_element +| @value_decl +; + +@var_decl_or_none = + @unspecified_element +| @var_decl +; diff --git a/swift/downgrades/e457bc35325b05725c00471da8843f293fe26f8d/swift.dbscheme b/swift/downgrades/e457bc35325b05725c00471da8843f293fe26f8d/swift.dbscheme new file mode 100644 index 00000000000..e646f9e0308 --- /dev/null +++ b/swift/downgrades/e457bc35325b05725c00471da8843f293fe26f8d/swift.dbscheme @@ -0,0 +1,2602 @@ +// generated by codegen/codegen.py + +// from prefix.dbscheme +/** + * The source location of the snapshot. + */ +sourceLocationPrefix( + string prefix: string ref +); + + +// from schema.py + +@element = + @callable +| @file +| @generic_context +| @locatable +| @location +| @type +; + +#keyset[id] +element_is_unknown( + int id: @element ref +); + +@callable = + @abstract_closure_expr +| @abstract_function_decl +; + +#keyset[id] +callable_names( + int id: @callable ref, + string name: string ref +); + +#keyset[id] +callable_self_params( + int id: @callable ref, + int self_param: @param_decl_or_none ref +); + +#keyset[id, index] +callable_params( + int id: @callable ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +#keyset[id] +callable_bodies( + int id: @callable ref, + int body: @brace_stmt_or_none ref +); + +#keyset[id, index] +callable_captures( + int id: @callable ref, + int index: int ref, + int capture: @captured_decl_or_none ref +); + +@file = + @db_file +; + +#keyset[id] +files( + int id: @file ref, + string name: string ref +); + +#keyset[id] +file_is_successfully_extracted( + int id: @file ref +); + +@locatable = + @argument +| @ast_node +| @comment +| @diagnostics +| @error_element +; + +#keyset[id] +locatable_locations( + int id: @locatable ref, + int location: @location_or_none ref +); + +@location = + @db_location +; + +#keyset[id] +locations( + int id: @location ref, + int file: @file_or_none ref, + int start_line: int ref, + int start_column: int ref, + int end_line: int ref, + int end_column: int ref +); + +@ast_node = + @availability_info +| @availability_spec +| @case_label_item +| @condition_element +| @decl +| @expr +| @pattern +| @stmt +| @stmt_condition +| @type_repr +; + +comments( + unique int id: @comment, + string text: string ref +); + +db_files( + unique int id: @db_file +); + +db_locations( + unique int id: @db_location +); + +diagnostics( + unique int id: @diagnostics, + string text: string ref, + int kind: int ref +); + +@error_element = + @error_expr +| @error_type +| @overloaded_decl_ref_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_chain_result_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @unresolved_type +| @unresolved_type_conversion_expr +| @unspecified_element +; + +availability_infos( + unique int id: @availability_info +); + +#keyset[id] +availability_info_is_unavailable( + int id: @availability_info ref +); + +#keyset[id, index] +availability_info_specs( + int id: @availability_info ref, + int index: int ref, + int spec: @availability_spec_or_none ref +); + +@availability_spec = + @other_availability_spec +| @platform_version_availability_spec +; + +unspecified_elements( + unique int id: @unspecified_element, + string property: string ref, + string error: string ref +); + +#keyset[id] +unspecified_element_parents( + int id: @unspecified_element ref, + int parent: @element ref +); + +#keyset[id] +unspecified_element_indices( + int id: @unspecified_element ref, + int index: int ref +); + +other_availability_specs( + unique int id: @other_availability_spec +); + +platform_version_availability_specs( + unique int id: @platform_version_availability_spec, + string platform: string ref, + string version: string ref +); + +@decl = + @captured_decl +| @enum_case_decl +| @extension_decl +| @if_config_decl +| @import_decl +| @missing_member_decl +| @operator_decl +| @pattern_binding_decl +| @pound_diagnostic_decl +| @precedence_group_decl +| @top_level_code_decl +| @value_decl +; + +#keyset[id] +decls( //dir=decl + int id: @decl ref, + int module: @module_decl_or_none ref +); + +#keyset[id, index] +decl_members( //dir=decl + int id: @decl ref, + int index: int ref, + int member: @decl_or_none ref +); + +@generic_context = + @abstract_function_decl +| @extension_decl +| @generic_type_decl +| @subscript_decl +; + +#keyset[id, index] +generic_context_generic_type_params( //dir=decl + int id: @generic_context ref, + int index: int ref, + int generic_type_param: @generic_type_param_decl_or_none ref +); + +captured_decls( //dir=decl + unique int id: @captured_decl, + int decl: @value_decl_or_none ref +); + +#keyset[id] +captured_decl_is_direct( //dir=decl + int id: @captured_decl ref +); + +#keyset[id] +captured_decl_is_escaping( //dir=decl + int id: @captured_decl ref +); + +enum_case_decls( //dir=decl + unique int id: @enum_case_decl +); + +#keyset[id, index] +enum_case_decl_elements( //dir=decl + int id: @enum_case_decl ref, + int index: int ref, + int element: @enum_element_decl_or_none ref +); + +extension_decls( //dir=decl + unique int id: @extension_decl, + int extended_type_decl: @nominal_type_decl_or_none ref +); + +#keyset[id, index] +extension_decl_protocols( //dir=decl + int id: @extension_decl ref, + int index: int ref, + int protocol: @protocol_decl_or_none ref +); + +if_config_decls( //dir=decl + unique int id: @if_config_decl +); + +#keyset[id, index] +if_config_decl_active_elements( //dir=decl + int id: @if_config_decl ref, + int index: int ref, + int active_element: @ast_node_or_none ref +); + +import_decls( //dir=decl + unique int id: @import_decl +); + +#keyset[id] +import_decl_is_exported( //dir=decl + int id: @import_decl ref +); + +#keyset[id] +import_decl_imported_modules( //dir=decl + int id: @import_decl ref, + int imported_module: @module_decl_or_none ref +); + +#keyset[id, index] +import_decl_declarations( //dir=decl + int id: @import_decl ref, + int index: int ref, + int declaration: @value_decl_or_none ref +); + +missing_member_decls( //dir=decl + unique int id: @missing_member_decl, + string name: string ref +); + +@operator_decl = + @infix_operator_decl +| @postfix_operator_decl +| @prefix_operator_decl +; + +#keyset[id] +operator_decls( //dir=decl + int id: @operator_decl ref, + string name: string ref +); + +pattern_binding_decls( //dir=decl + unique int id: @pattern_binding_decl +); + +#keyset[id, index] +pattern_binding_decl_inits( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int init: @expr_or_none ref +); + +#keyset[id, index] +pattern_binding_decl_patterns( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int pattern: @pattern_or_none ref +); + +pound_diagnostic_decls( //dir=decl + unique int id: @pound_diagnostic_decl, + int kind: int ref, + int message: @string_literal_expr_or_none ref +); + +precedence_group_decls( //dir=decl + unique int id: @precedence_group_decl +); + +top_level_code_decls( //dir=decl + unique int id: @top_level_code_decl, + int body: @brace_stmt_or_none ref +); + +@value_decl = + @abstract_function_decl +| @abstract_storage_decl +| @enum_element_decl +| @type_decl +; + +#keyset[id] +value_decls( //dir=decl + int id: @value_decl ref, + int interface_type: @type_or_none ref +); + +@abstract_function_decl = + @constructor_decl +| @destructor_decl +| @func_decl +; + +@abstract_storage_decl = + @subscript_decl +| @var_decl +; + +#keyset[id, index] +abstract_storage_decl_accessor_decls( //dir=decl + int id: @abstract_storage_decl ref, + int index: int ref, + int accessor_decl: @accessor_decl_or_none ref +); + +enum_element_decls( //dir=decl + unique int id: @enum_element_decl, + string name: string ref +); + +#keyset[id, index] +enum_element_decl_params( //dir=decl + int id: @enum_element_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +infix_operator_decls( //dir=decl + unique int id: @infix_operator_decl +); + +#keyset[id] +infix_operator_decl_precedence_groups( //dir=decl + int id: @infix_operator_decl ref, + int precedence_group: @precedence_group_decl_or_none ref +); + +postfix_operator_decls( //dir=decl + unique int id: @postfix_operator_decl +); + +prefix_operator_decls( //dir=decl + unique int id: @prefix_operator_decl +); + +@type_decl = + @abstract_type_param_decl +| @generic_type_decl +| @module_decl +; + +#keyset[id] +type_decls( //dir=decl + int id: @type_decl ref, + string name: string ref +); + +#keyset[id, index] +type_decl_base_types( //dir=decl + int id: @type_decl ref, + int index: int ref, + int base_type: @type_or_none ref +); + +@abstract_type_param_decl = + @associated_type_decl +| @generic_type_param_decl +; + +constructor_decls( //dir=decl + unique int id: @constructor_decl +); + +destructor_decls( //dir=decl + unique int id: @destructor_decl +); + +@func_decl = + @accessor_decl +| @concrete_func_decl +; + +@generic_type_decl = + @nominal_type_decl +| @opaque_type_decl +| @type_alias_decl +; + +module_decls( //dir=decl + unique int id: @module_decl +); + +#keyset[id] +module_decl_is_builtin_module( //dir=decl + int id: @module_decl ref +); + +#keyset[id] +module_decl_is_system_module( //dir=decl + int id: @module_decl ref +); + +#keyset[id, index] +module_decl_imported_modules( //dir=decl + int id: @module_decl ref, + int index: int ref, + int imported_module: @module_decl_or_none ref +); + +#keyset[id, index] +module_decl_exported_modules( //dir=decl + int id: @module_decl ref, + int index: int ref, + int exported_module: @module_decl_or_none ref +); + +subscript_decls( //dir=decl + unique int id: @subscript_decl, + int element_type: @type_or_none ref +); + +#keyset[id, index] +subscript_decl_params( //dir=decl + int id: @subscript_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +@var_decl = + @concrete_var_decl +| @param_decl +; + +#keyset[id] +var_decls( //dir=decl + int id: @var_decl ref, + string name: string ref, + int type_: @type_or_none ref +); + +#keyset[id] +var_decl_attached_property_wrapper_types( //dir=decl + int id: @var_decl ref, + int attached_property_wrapper_type: @type_or_none ref +); + +#keyset[id] +var_decl_parent_patterns( //dir=decl + int id: @var_decl ref, + int parent_pattern: @pattern_or_none ref +); + +#keyset[id] +var_decl_parent_initializers( //dir=decl + int id: @var_decl ref, + int parent_initializer: @expr_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var: @var_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var: @var_decl_or_none ref +); + +accessor_decls( //dir=decl + unique int id: @accessor_decl +); + +#keyset[id] +accessor_decl_is_getter( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_setter( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_will_set( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_did_set( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_read( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_modify( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_unsafe_address( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_unsafe_mutable_address( //dir=decl + int id: @accessor_decl ref +); + +associated_type_decls( //dir=decl + unique int id: @associated_type_decl +); + +concrete_func_decls( //dir=decl + unique int id: @concrete_func_decl +); + +concrete_var_decls( //dir=decl + unique int id: @concrete_var_decl, + int introducer_int: int ref +); + +generic_type_param_decls( //dir=decl + unique int id: @generic_type_param_decl +); + +@nominal_type_decl = + @class_decl +| @enum_decl +| @protocol_decl +| @struct_decl +; + +#keyset[id] +nominal_type_decls( //dir=decl + int id: @nominal_type_decl ref, + int type_: @type_or_none ref +); + +opaque_type_decls( //dir=decl + unique int id: @opaque_type_decl, + int naming_declaration: @value_decl_or_none ref +); + +#keyset[id, index] +opaque_type_decl_opaque_generic_params( //dir=decl + int id: @opaque_type_decl ref, + int index: int ref, + int opaque_generic_param: @generic_type_param_type_or_none ref +); + +param_decls( //dir=decl + unique int id: @param_decl +); + +#keyset[id] +param_decl_is_inout( //dir=decl + int id: @param_decl ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_var_bindings( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_vars( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var: @var_decl_or_none ref +); + +type_alias_decls( //dir=decl + unique int id: @type_alias_decl, + int aliased_type: @type_or_none ref +); + +class_decls( //dir=decl + unique int id: @class_decl +); + +enum_decls( //dir=decl + unique int id: @enum_decl +); + +protocol_decls( //dir=decl + unique int id: @protocol_decl +); + +struct_decls( //dir=decl + unique int id: @struct_decl +); + +arguments( //dir=expr + unique int id: @argument, + string label: string ref, + int expr: @expr_or_none ref +); + +@expr = + @abstract_closure_expr +| @any_try_expr +| @applied_property_wrapper_expr +| @apply_expr +| @assign_expr +| @bind_optional_expr +| @capture_list_expr +| @collection_expr +| @decl_ref_expr +| @default_argument_expr +| @discard_assignment_expr +| @dot_syntax_base_ignored_expr +| @dynamic_type_expr +| @enum_is_case_expr +| @error_expr +| @explicit_cast_expr +| @force_value_expr +| @identity_expr +| @if_expr +| @implicit_conversion_expr +| @in_out_expr +| @key_path_application_expr +| @key_path_dot_expr +| @key_path_expr +| @lazy_initializer_expr +| @literal_expr +| @lookup_expr +| @make_temporarily_escapable_expr +| @obj_c_selector_expr +| @one_way_expr +| @opaque_value_expr +| @open_existential_expr +| @optional_evaluation_expr +| @other_constructor_decl_ref_expr +| @overloaded_decl_ref_expr +| @property_wrapper_value_placeholder_expr +| @rebind_self_in_constructor_expr +| @sequence_expr +| @super_ref_expr +| @tap_expr +| @tuple_element_expr +| @tuple_expr +| @type_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @vararg_expansion_expr +; + +#keyset[id] +expr_types( //dir=expr + int id: @expr ref, + int type_: @type_or_none ref +); + +@abstract_closure_expr = + @auto_closure_expr +| @closure_expr +; + +@any_try_expr = + @force_try_expr +| @optional_try_expr +| @try_expr +; + +#keyset[id] +any_try_exprs( //dir=expr + int id: @any_try_expr ref, + int sub_expr: @expr_or_none ref +); + +applied_property_wrapper_exprs( //dir=expr + unique int id: @applied_property_wrapper_expr, + int kind: int ref, + int value: @expr_or_none ref, + int param: @param_decl_or_none ref +); + +@apply_expr = + @binary_expr +| @call_expr +| @postfix_unary_expr +| @prefix_unary_expr +| @self_apply_expr +; + +#keyset[id] +apply_exprs( //dir=expr + int id: @apply_expr ref, + int function: @expr_or_none ref +); + +#keyset[id, index] +apply_expr_arguments( //dir=expr + int id: @apply_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +assign_exprs( //dir=expr + unique int id: @assign_expr, + int dest: @expr_or_none ref, + int source: @expr_or_none ref +); + +bind_optional_exprs( //dir=expr + unique int id: @bind_optional_expr, + int sub_expr: @expr_or_none ref +); + +capture_list_exprs( //dir=expr + unique int id: @capture_list_expr, + int closure_body: @closure_expr_or_none ref +); + +#keyset[id, index] +capture_list_expr_binding_decls( //dir=expr + int id: @capture_list_expr ref, + int index: int ref, + int binding_decl: @pattern_binding_decl_or_none ref +); + +@collection_expr = + @array_expr +| @dictionary_expr +; + +decl_ref_exprs( //dir=expr + unique int id: @decl_ref_expr, + int decl: @decl_or_none ref +); + +#keyset[id, index] +decl_ref_expr_replacement_types( //dir=expr + int id: @decl_ref_expr ref, + int index: int ref, + int replacement_type: @type_or_none ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_ordinary_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_distributed_thunk_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +default_argument_exprs( //dir=expr + unique int id: @default_argument_expr, + int param_decl: @param_decl_or_none ref, + int param_index: int ref +); + +#keyset[id] +default_argument_expr_caller_side_defaults( //dir=expr + int id: @default_argument_expr ref, + int caller_side_default: @expr_or_none ref +); + +discard_assignment_exprs( //dir=expr + unique int id: @discard_assignment_expr +); + +dot_syntax_base_ignored_exprs( //dir=expr + unique int id: @dot_syntax_base_ignored_expr, + int qualifier: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +dynamic_type_exprs( //dir=expr + unique int id: @dynamic_type_expr, + int base: @expr_or_none ref +); + +enum_is_case_exprs( //dir=expr + unique int id: @enum_is_case_expr, + int sub_expr: @expr_or_none ref, + int element: @enum_element_decl_or_none ref +); + +error_exprs( //dir=expr + unique int id: @error_expr +); + +@explicit_cast_expr = + @checked_cast_expr +| @coerce_expr +; + +#keyset[id] +explicit_cast_exprs( //dir=expr + int id: @explicit_cast_expr ref, + int sub_expr: @expr_or_none ref +); + +force_value_exprs( //dir=expr + unique int id: @force_value_expr, + int sub_expr: @expr_or_none ref +); + +@identity_expr = + @await_expr +| @dot_self_expr +| @paren_expr +| @unresolved_member_chain_result_expr +; + +#keyset[id] +identity_exprs( //dir=expr + int id: @identity_expr ref, + int sub_expr: @expr_or_none ref +); + +if_exprs( //dir=expr + unique int id: @if_expr, + int condition: @expr_or_none ref, + int then_expr: @expr_or_none ref, + int else_expr: @expr_or_none ref +); + +@implicit_conversion_expr = + @abi_safe_conversion_expr +| @any_hashable_erasure_expr +| @archetype_to_super_expr +| @array_to_pointer_expr +| @bridge_from_obj_c_expr +| @bridge_to_obj_c_expr +| @class_metatype_to_object_expr +| @collection_upcast_conversion_expr +| @conditional_bridge_from_obj_c_expr +| @covariant_function_conversion_expr +| @covariant_return_conversion_expr +| @derived_to_base_expr +| @destructure_tuple_expr +| @differentiable_function_expr +| @differentiable_function_extract_original_expr +| @erasure_expr +| @existential_metatype_to_object_expr +| @foreign_object_conversion_expr +| @function_conversion_expr +| @in_out_to_pointer_expr +| @inject_into_optional_expr +| @linear_function_expr +| @linear_function_extract_original_expr +| @linear_to_differentiable_function_expr +| @load_expr +| @metatype_conversion_expr +| @pointer_to_pointer_expr +| @protocol_metatype_to_object_expr +| @string_to_pointer_expr +| @underlying_to_opaque_expr +| @unevaluated_instance_expr +| @unresolved_type_conversion_expr +; + +#keyset[id] +implicit_conversion_exprs( //dir=expr + int id: @implicit_conversion_expr ref, + int sub_expr: @expr_or_none ref +); + +in_out_exprs( //dir=expr + unique int id: @in_out_expr, + int sub_expr: @expr_or_none ref +); + +key_path_application_exprs( //dir=expr + unique int id: @key_path_application_expr, + int base: @expr_or_none ref, + int key_path: @expr_or_none ref +); + +key_path_dot_exprs( //dir=expr + unique int id: @key_path_dot_expr +); + +key_path_exprs( //dir=expr + unique int id: @key_path_expr +); + +#keyset[id] +key_path_expr_roots( //dir=expr + int id: @key_path_expr ref, + int root: @type_repr_or_none ref +); + +#keyset[id] +key_path_expr_parsed_paths( //dir=expr + int id: @key_path_expr ref, + int parsed_path: @expr_or_none ref +); + +lazy_initializer_exprs( //dir=expr + unique int id: @lazy_initializer_expr, + int sub_expr: @expr_or_none ref +); + +@literal_expr = + @builtin_literal_expr +| @interpolated_string_literal_expr +| @nil_literal_expr +| @object_literal_expr +| @regex_literal_expr +; + +@lookup_expr = + @dynamic_lookup_expr +| @member_ref_expr +| @subscript_expr +; + +#keyset[id] +lookup_exprs( //dir=expr + int id: @lookup_expr ref, + int base: @expr_or_none ref +); + +#keyset[id] +lookup_expr_members( //dir=expr + int id: @lookup_expr ref, + int member: @decl_or_none ref +); + +make_temporarily_escapable_exprs( //dir=expr + unique int id: @make_temporarily_escapable_expr, + int escaping_closure: @opaque_value_expr_or_none ref, + int nonescaping_closure: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +obj_c_selector_exprs( //dir=expr + unique int id: @obj_c_selector_expr, + int sub_expr: @expr_or_none ref, + int method: @abstract_function_decl_or_none ref +); + +one_way_exprs( //dir=expr + unique int id: @one_way_expr, + int sub_expr: @expr_or_none ref +); + +opaque_value_exprs( //dir=expr + unique int id: @opaque_value_expr +); + +open_existential_exprs( //dir=expr + unique int id: @open_existential_expr, + int sub_expr: @expr_or_none ref, + int existential: @expr_or_none ref, + int opaque_expr: @opaque_value_expr_or_none ref +); + +optional_evaluation_exprs( //dir=expr + unique int id: @optional_evaluation_expr, + int sub_expr: @expr_or_none ref +); + +other_constructor_decl_ref_exprs( //dir=expr + unique int id: @other_constructor_decl_ref_expr, + int constructor_decl: @constructor_decl_or_none ref +); + +overloaded_decl_ref_exprs( //dir=expr + unique int id: @overloaded_decl_ref_expr +); + +#keyset[id, index] +overloaded_decl_ref_expr_possible_declarations( //dir=expr + int id: @overloaded_decl_ref_expr ref, + int index: int ref, + int possible_declaration: @value_decl_or_none ref +); + +property_wrapper_value_placeholder_exprs( //dir=expr + unique int id: @property_wrapper_value_placeholder_expr, + int placeholder: @opaque_value_expr_or_none ref +); + +#keyset[id] +property_wrapper_value_placeholder_expr_wrapped_values( //dir=expr + int id: @property_wrapper_value_placeholder_expr ref, + int wrapped_value: @expr_or_none ref +); + +rebind_self_in_constructor_exprs( //dir=expr + unique int id: @rebind_self_in_constructor_expr, + int sub_expr: @expr_or_none ref, + int self: @var_decl_or_none ref +); + +sequence_exprs( //dir=expr + unique int id: @sequence_expr +); + +#keyset[id, index] +sequence_expr_elements( //dir=expr + int id: @sequence_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +super_ref_exprs( //dir=expr + unique int id: @super_ref_expr, + int self: @var_decl_or_none ref +); + +tap_exprs( //dir=expr + unique int id: @tap_expr, + int body: @brace_stmt_or_none ref, + int var: @var_decl_or_none ref +); + +#keyset[id] +tap_expr_sub_exprs( //dir=expr + int id: @tap_expr ref, + int sub_expr: @expr_or_none ref +); + +tuple_element_exprs( //dir=expr + unique int id: @tuple_element_expr, + int sub_expr: @expr_or_none ref, + int index: int ref +); + +tuple_exprs( //dir=expr + unique int id: @tuple_expr +); + +#keyset[id, index] +tuple_expr_elements( //dir=expr + int id: @tuple_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +type_exprs( //dir=expr + unique int id: @type_expr +); + +#keyset[id] +type_expr_type_reprs( //dir=expr + int id: @type_expr ref, + int type_repr: @type_repr_or_none ref +); + +unresolved_decl_ref_exprs( //dir=expr + unique int id: @unresolved_decl_ref_expr +); + +#keyset[id] +unresolved_decl_ref_expr_names( //dir=expr + int id: @unresolved_decl_ref_expr ref, + string name: string ref +); + +unresolved_dot_exprs( //dir=expr + unique int id: @unresolved_dot_expr, + int base: @expr_or_none ref, + string name: string ref +); + +unresolved_member_exprs( //dir=expr + unique int id: @unresolved_member_expr, + string name: string ref +); + +unresolved_pattern_exprs( //dir=expr + unique int id: @unresolved_pattern_expr, + int sub_pattern: @pattern_or_none ref +); + +unresolved_specialize_exprs( //dir=expr + unique int id: @unresolved_specialize_expr, + int sub_expr: @expr_or_none ref +); + +vararg_expansion_exprs( //dir=expr + unique int id: @vararg_expansion_expr, + int sub_expr: @expr_or_none ref +); + +abi_safe_conversion_exprs( //dir=expr + unique int id: @abi_safe_conversion_expr +); + +any_hashable_erasure_exprs( //dir=expr + unique int id: @any_hashable_erasure_expr +); + +archetype_to_super_exprs( //dir=expr + unique int id: @archetype_to_super_expr +); + +array_exprs( //dir=expr + unique int id: @array_expr +); + +#keyset[id, index] +array_expr_elements( //dir=expr + int id: @array_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +array_to_pointer_exprs( //dir=expr + unique int id: @array_to_pointer_expr +); + +auto_closure_exprs( //dir=expr + unique int id: @auto_closure_expr +); + +await_exprs( //dir=expr + unique int id: @await_expr +); + +binary_exprs( //dir=expr + unique int id: @binary_expr +); + +bridge_from_obj_c_exprs( //dir=expr + unique int id: @bridge_from_obj_c_expr +); + +bridge_to_obj_c_exprs( //dir=expr + unique int id: @bridge_to_obj_c_expr +); + +@builtin_literal_expr = + @boolean_literal_expr +| @magic_identifier_literal_expr +| @number_literal_expr +| @string_literal_expr +; + +call_exprs( //dir=expr + unique int id: @call_expr +); + +@checked_cast_expr = + @conditional_checked_cast_expr +| @forced_checked_cast_expr +| @is_expr +; + +class_metatype_to_object_exprs( //dir=expr + unique int id: @class_metatype_to_object_expr +); + +closure_exprs( //dir=expr + unique int id: @closure_expr +); + +coerce_exprs( //dir=expr + unique int id: @coerce_expr +); + +collection_upcast_conversion_exprs( //dir=expr + unique int id: @collection_upcast_conversion_expr +); + +conditional_bridge_from_obj_c_exprs( //dir=expr + unique int id: @conditional_bridge_from_obj_c_expr +); + +covariant_function_conversion_exprs( //dir=expr + unique int id: @covariant_function_conversion_expr +); + +covariant_return_conversion_exprs( //dir=expr + unique int id: @covariant_return_conversion_expr +); + +derived_to_base_exprs( //dir=expr + unique int id: @derived_to_base_expr +); + +destructure_tuple_exprs( //dir=expr + unique int id: @destructure_tuple_expr +); + +dictionary_exprs( //dir=expr + unique int id: @dictionary_expr +); + +#keyset[id, index] +dictionary_expr_elements( //dir=expr + int id: @dictionary_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +differentiable_function_exprs( //dir=expr + unique int id: @differentiable_function_expr +); + +differentiable_function_extract_original_exprs( //dir=expr + unique int id: @differentiable_function_extract_original_expr +); + +dot_self_exprs( //dir=expr + unique int id: @dot_self_expr +); + +@dynamic_lookup_expr = + @dynamic_member_ref_expr +| @dynamic_subscript_expr +; + +erasure_exprs( //dir=expr + unique int id: @erasure_expr +); + +existential_metatype_to_object_exprs( //dir=expr + unique int id: @existential_metatype_to_object_expr +); + +force_try_exprs( //dir=expr + unique int id: @force_try_expr +); + +foreign_object_conversion_exprs( //dir=expr + unique int id: @foreign_object_conversion_expr +); + +function_conversion_exprs( //dir=expr + unique int id: @function_conversion_expr +); + +in_out_to_pointer_exprs( //dir=expr + unique int id: @in_out_to_pointer_expr +); + +inject_into_optional_exprs( //dir=expr + unique int id: @inject_into_optional_expr +); + +interpolated_string_literal_exprs( //dir=expr + unique int id: @interpolated_string_literal_expr +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_expr: @opaque_value_expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_count_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_count_expr: @expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_literal_capacity_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int literal_capacity_expr: @expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_appending_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int appending_expr: @tap_expr_or_none ref +); + +linear_function_exprs( //dir=expr + unique int id: @linear_function_expr +); + +linear_function_extract_original_exprs( //dir=expr + unique int id: @linear_function_extract_original_expr +); + +linear_to_differentiable_function_exprs( //dir=expr + unique int id: @linear_to_differentiable_function_expr +); + +load_exprs( //dir=expr + unique int id: @load_expr +); + +member_ref_exprs( //dir=expr + unique int id: @member_ref_expr +); + +#keyset[id] +member_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_ordinary_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_distributed_thunk_semantics( //dir=expr + int id: @member_ref_expr ref +); + +metatype_conversion_exprs( //dir=expr + unique int id: @metatype_conversion_expr +); + +nil_literal_exprs( //dir=expr + unique int id: @nil_literal_expr +); + +object_literal_exprs( //dir=expr + unique int id: @object_literal_expr, + int kind: int ref +); + +#keyset[id, index] +object_literal_expr_arguments( //dir=expr + int id: @object_literal_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +optional_try_exprs( //dir=expr + unique int id: @optional_try_expr +); + +paren_exprs( //dir=expr + unique int id: @paren_expr +); + +pointer_to_pointer_exprs( //dir=expr + unique int id: @pointer_to_pointer_expr +); + +postfix_unary_exprs( //dir=expr + unique int id: @postfix_unary_expr +); + +prefix_unary_exprs( //dir=expr + unique int id: @prefix_unary_expr +); + +protocol_metatype_to_object_exprs( //dir=expr + unique int id: @protocol_metatype_to_object_expr +); + +regex_literal_exprs( //dir=expr + unique int id: @regex_literal_expr, + string pattern: string ref, + int version: int ref +); + +@self_apply_expr = + @constructor_ref_call_expr +| @dot_syntax_call_expr +; + +#keyset[id] +self_apply_exprs( //dir=expr + int id: @self_apply_expr ref, + int base: @expr_or_none ref +); + +string_to_pointer_exprs( //dir=expr + unique int id: @string_to_pointer_expr +); + +subscript_exprs( //dir=expr + unique int id: @subscript_expr +); + +#keyset[id, index] +subscript_expr_arguments( //dir=expr + int id: @subscript_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +#keyset[id] +subscript_expr_has_direct_to_storage_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_ordinary_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_distributed_thunk_semantics( //dir=expr + int id: @subscript_expr ref +); + +try_exprs( //dir=expr + unique int id: @try_expr +); + +underlying_to_opaque_exprs( //dir=expr + unique int id: @underlying_to_opaque_expr +); + +unevaluated_instance_exprs( //dir=expr + unique int id: @unevaluated_instance_expr +); + +unresolved_member_chain_result_exprs( //dir=expr + unique int id: @unresolved_member_chain_result_expr +); + +unresolved_type_conversion_exprs( //dir=expr + unique int id: @unresolved_type_conversion_expr +); + +boolean_literal_exprs( //dir=expr + unique int id: @boolean_literal_expr, + boolean value: boolean ref +); + +conditional_checked_cast_exprs( //dir=expr + unique int id: @conditional_checked_cast_expr +); + +constructor_ref_call_exprs( //dir=expr + unique int id: @constructor_ref_call_expr +); + +dot_syntax_call_exprs( //dir=expr + unique int id: @dot_syntax_call_expr +); + +dynamic_member_ref_exprs( //dir=expr + unique int id: @dynamic_member_ref_expr +); + +dynamic_subscript_exprs( //dir=expr + unique int id: @dynamic_subscript_expr +); + +forced_checked_cast_exprs( //dir=expr + unique int id: @forced_checked_cast_expr +); + +is_exprs( //dir=expr + unique int id: @is_expr +); + +magic_identifier_literal_exprs( //dir=expr + unique int id: @magic_identifier_literal_expr, + string kind: string ref +); + +@number_literal_expr = + @float_literal_expr +| @integer_literal_expr +; + +string_literal_exprs( //dir=expr + unique int id: @string_literal_expr, + string value: string ref +); + +float_literal_exprs( //dir=expr + unique int id: @float_literal_expr, + string string_value: string ref +); + +integer_literal_exprs( //dir=expr + unique int id: @integer_literal_expr, + string string_value: string ref +); + +@pattern = + @any_pattern +| @binding_pattern +| @bool_pattern +| @enum_element_pattern +| @expr_pattern +| @is_pattern +| @named_pattern +| @optional_some_pattern +| @paren_pattern +| @tuple_pattern +| @typed_pattern +; + +any_patterns( //dir=pattern + unique int id: @any_pattern +); + +binding_patterns( //dir=pattern + unique int id: @binding_pattern, + int sub_pattern: @pattern_or_none ref +); + +bool_patterns( //dir=pattern + unique int id: @bool_pattern, + boolean value: boolean ref +); + +enum_element_patterns( //dir=pattern + unique int id: @enum_element_pattern, + int element: @enum_element_decl_or_none ref +); + +#keyset[id] +enum_element_pattern_sub_patterns( //dir=pattern + int id: @enum_element_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +expr_patterns( //dir=pattern + unique int id: @expr_pattern, + int sub_expr: @expr_or_none ref +); + +is_patterns( //dir=pattern + unique int id: @is_pattern +); + +#keyset[id] +is_pattern_cast_type_reprs( //dir=pattern + int id: @is_pattern ref, + int cast_type_repr: @type_repr_or_none ref +); + +#keyset[id] +is_pattern_sub_patterns( //dir=pattern + int id: @is_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +named_patterns( //dir=pattern + unique int id: @named_pattern, + string name: string ref +); + +optional_some_patterns( //dir=pattern + unique int id: @optional_some_pattern, + int sub_pattern: @pattern_or_none ref +); + +paren_patterns( //dir=pattern + unique int id: @paren_pattern, + int sub_pattern: @pattern_or_none ref +); + +tuple_patterns( //dir=pattern + unique int id: @tuple_pattern +); + +#keyset[id, index] +tuple_pattern_elements( //dir=pattern + int id: @tuple_pattern ref, + int index: int ref, + int element: @pattern_or_none ref +); + +typed_patterns( //dir=pattern + unique int id: @typed_pattern, + int sub_pattern: @pattern_or_none ref +); + +#keyset[id] +typed_pattern_type_reprs( //dir=pattern + int id: @typed_pattern ref, + int type_repr: @type_repr_or_none ref +); + +case_label_items( //dir=stmt + unique int id: @case_label_item, + int pattern: @pattern_or_none ref +); + +#keyset[id] +case_label_item_guards( //dir=stmt + int id: @case_label_item ref, + int guard: @expr_or_none ref +); + +condition_elements( //dir=stmt + unique int id: @condition_element +); + +#keyset[id] +condition_element_booleans( //dir=stmt + int id: @condition_element ref, + int boolean_: @expr_or_none ref +); + +#keyset[id] +condition_element_patterns( //dir=stmt + int id: @condition_element ref, + int pattern: @pattern_or_none ref +); + +#keyset[id] +condition_element_initializers( //dir=stmt + int id: @condition_element ref, + int initializer: @expr_or_none ref +); + +#keyset[id] +condition_element_availabilities( //dir=stmt + int id: @condition_element ref, + int availability: @availability_info_or_none ref +); + +@stmt = + @brace_stmt +| @break_stmt +| @case_stmt +| @continue_stmt +| @defer_stmt +| @fail_stmt +| @fallthrough_stmt +| @labeled_stmt +| @pound_assert_stmt +| @return_stmt +| @throw_stmt +| @yield_stmt +; + +stmt_conditions( //dir=stmt + unique int id: @stmt_condition +); + +#keyset[id, index] +stmt_condition_elements( //dir=stmt + int id: @stmt_condition ref, + int index: int ref, + int element: @condition_element_or_none ref +); + +brace_stmts( //dir=stmt + unique int id: @brace_stmt +); + +#keyset[id, index] +brace_stmt_elements( //dir=stmt + int id: @brace_stmt ref, + int index: int ref, + int element: @ast_node_or_none ref +); + +break_stmts( //dir=stmt + unique int id: @break_stmt +); + +#keyset[id] +break_stmt_target_names( //dir=stmt + int id: @break_stmt ref, + string target_name: string ref +); + +#keyset[id] +break_stmt_targets( //dir=stmt + int id: @break_stmt ref, + int target: @stmt_or_none ref +); + +case_stmts( //dir=stmt + unique int id: @case_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +case_stmt_labels( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int label: @case_label_item_or_none ref +); + +#keyset[id, index] +case_stmt_variables( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int variable: @var_decl_or_none ref +); + +continue_stmts( //dir=stmt + unique int id: @continue_stmt +); + +#keyset[id] +continue_stmt_target_names( //dir=stmt + int id: @continue_stmt ref, + string target_name: string ref +); + +#keyset[id] +continue_stmt_targets( //dir=stmt + int id: @continue_stmt ref, + int target: @stmt_or_none ref +); + +defer_stmts( //dir=stmt + unique int id: @defer_stmt, + int body: @brace_stmt_or_none ref +); + +fail_stmts( //dir=stmt + unique int id: @fail_stmt +); + +fallthrough_stmts( //dir=stmt + unique int id: @fallthrough_stmt, + int fallthrough_source: @case_stmt_or_none ref, + int fallthrough_dest: @case_stmt_or_none ref +); + +@labeled_stmt = + @do_catch_stmt +| @do_stmt +| @for_each_stmt +| @labeled_conditional_stmt +| @repeat_while_stmt +| @switch_stmt +; + +#keyset[id] +labeled_stmt_labels( //dir=stmt + int id: @labeled_stmt ref, + string label: string ref +); + +pound_assert_stmts( //dir=stmt + unique int id: @pound_assert_stmt, + int condition: @expr_or_none ref, + string message: string ref +); + +return_stmts( //dir=stmt + unique int id: @return_stmt +); + +#keyset[id] +return_stmt_results( //dir=stmt + int id: @return_stmt ref, + int result: @expr_or_none ref +); + +throw_stmts( //dir=stmt + unique int id: @throw_stmt, + int sub_expr: @expr_or_none ref +); + +yield_stmts( //dir=stmt + unique int id: @yield_stmt +); + +#keyset[id, index] +yield_stmt_results( //dir=stmt + int id: @yield_stmt ref, + int index: int ref, + int result: @expr_or_none ref +); + +do_catch_stmts( //dir=stmt + unique int id: @do_catch_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +do_catch_stmt_catches( //dir=stmt + int id: @do_catch_stmt ref, + int index: int ref, + int catch: @case_stmt_or_none ref +); + +do_stmts( //dir=stmt + unique int id: @do_stmt, + int body: @brace_stmt_or_none ref +); + +for_each_stmts( //dir=stmt + unique int id: @for_each_stmt, + int pattern: @pattern_or_none ref, + int sequence: @expr_or_none ref, + int body: @brace_stmt_or_none ref +); + +#keyset[id] +for_each_stmt_wheres( //dir=stmt + int id: @for_each_stmt ref, + int where: @expr_or_none ref +); + +@labeled_conditional_stmt = + @guard_stmt +| @if_stmt +| @while_stmt +; + +#keyset[id] +labeled_conditional_stmts( //dir=stmt + int id: @labeled_conditional_stmt ref, + int condition: @stmt_condition_or_none ref +); + +repeat_while_stmts( //dir=stmt + unique int id: @repeat_while_stmt, + int condition: @expr_or_none ref, + int body: @stmt_or_none ref +); + +switch_stmts( //dir=stmt + unique int id: @switch_stmt, + int expr: @expr_or_none ref +); + +#keyset[id, index] +switch_stmt_cases( //dir=stmt + int id: @switch_stmt ref, + int index: int ref, + int case_: @case_stmt_or_none ref +); + +guard_stmts( //dir=stmt + unique int id: @guard_stmt, + int body: @brace_stmt_or_none ref +); + +if_stmts( //dir=stmt + unique int id: @if_stmt, + int then: @stmt_or_none ref +); + +#keyset[id] +if_stmt_elses( //dir=stmt + int id: @if_stmt ref, + int else: @stmt_or_none ref +); + +while_stmts( //dir=stmt + unique int id: @while_stmt, + int body: @stmt_or_none ref +); + +@type = + @any_function_type +| @any_generic_type +| @any_metatype_type +| @builtin_type +| @dependent_member_type +| @dynamic_self_type +| @error_type +| @existential_type +| @in_out_type +| @l_value_type +| @module_type +| @parameterized_protocol_type +| @protocol_composition_type +| @reference_storage_type +| @substitutable_type +| @sugar_type +| @tuple_type +| @unresolved_type +; + +#keyset[id] +types( //dir=type + int id: @type ref, + string name: string ref, + int canonical_type: @type_or_none ref +); + +type_reprs( //dir=type + unique int id: @type_repr, + int type_: @type_or_none ref +); + +@any_function_type = + @function_type +| @generic_function_type +; + +#keyset[id] +any_function_types( //dir=type + int id: @any_function_type ref, + int result: @type_or_none ref +); + +#keyset[id, index] +any_function_type_param_types( //dir=type + int id: @any_function_type ref, + int index: int ref, + int param_type: @type_or_none ref +); + +#keyset[id] +any_function_type_is_throwing( //dir=type + int id: @any_function_type ref +); + +#keyset[id] +any_function_type_is_async( //dir=type + int id: @any_function_type ref +); + +@any_generic_type = + @nominal_or_bound_generic_nominal_type +| @unbound_generic_type +; + +#keyset[id] +any_generic_types( //dir=type + int id: @any_generic_type ref, + int declaration: @generic_type_decl_or_none ref +); + +#keyset[id] +any_generic_type_parents( //dir=type + int id: @any_generic_type ref, + int parent: @type_or_none ref +); + +@any_metatype_type = + @existential_metatype_type +| @metatype_type +; + +@builtin_type = + @any_builtin_integer_type +| @builtin_bridge_object_type +| @builtin_default_actor_storage_type +| @builtin_executor_type +| @builtin_float_type +| @builtin_job_type +| @builtin_native_object_type +| @builtin_raw_pointer_type +| @builtin_raw_unsafe_continuation_type +| @builtin_unsafe_value_buffer_type +| @builtin_vector_type +; + +dependent_member_types( //dir=type + unique int id: @dependent_member_type, + int base_type: @type_or_none ref, + int associated_type_decl: @associated_type_decl_or_none ref +); + +dynamic_self_types( //dir=type + unique int id: @dynamic_self_type, + int static_self_type: @type_or_none ref +); + +error_types( //dir=type + unique int id: @error_type +); + +existential_types( //dir=type + unique int id: @existential_type, + int constraint: @type_or_none ref +); + +in_out_types( //dir=type + unique int id: @in_out_type, + int object_type: @type_or_none ref +); + +l_value_types( //dir=type + unique int id: @l_value_type, + int object_type: @type_or_none ref +); + +module_types( //dir=type + unique int id: @module_type, + int module: @module_decl_or_none ref +); + +parameterized_protocol_types( //dir=type + unique int id: @parameterized_protocol_type, + int base: @protocol_type_or_none ref +); + +#keyset[id, index] +parameterized_protocol_type_args( //dir=type + int id: @parameterized_protocol_type ref, + int index: int ref, + int arg: @type_or_none ref +); + +protocol_composition_types( //dir=type + unique int id: @protocol_composition_type +); + +#keyset[id, index] +protocol_composition_type_members( //dir=type + int id: @protocol_composition_type ref, + int index: int ref, + int member: @type_or_none ref +); + +@reference_storage_type = + @unmanaged_storage_type +| @unowned_storage_type +| @weak_storage_type +; + +#keyset[id] +reference_storage_types( //dir=type + int id: @reference_storage_type ref, + int referent_type: @type_or_none ref +); + +@substitutable_type = + @archetype_type +| @generic_type_param_type +; + +@sugar_type = + @paren_type +| @syntax_sugar_type +| @type_alias_type +; + +tuple_types( //dir=type + unique int id: @tuple_type +); + +#keyset[id, index] +tuple_type_types( //dir=type + int id: @tuple_type ref, + int index: int ref, + int type_: @type_or_none ref +); + +#keyset[id, index] +tuple_type_names( //dir=type + int id: @tuple_type ref, + int index: int ref, + string name: string ref +); + +unresolved_types( //dir=type + unique int id: @unresolved_type +); + +@any_builtin_integer_type = + @builtin_integer_literal_type +| @builtin_integer_type +; + +@archetype_type = + @opaque_type_archetype_type +| @opened_archetype_type +| @primary_archetype_type +; + +#keyset[id] +archetype_types( //dir=type + int id: @archetype_type ref, + int interface_type: @type_or_none ref +); + +#keyset[id] +archetype_type_superclasses( //dir=type + int id: @archetype_type ref, + int superclass: @type_or_none ref +); + +#keyset[id, index] +archetype_type_protocols( //dir=type + int id: @archetype_type ref, + int index: int ref, + int protocol: @protocol_decl_or_none ref +); + +builtin_bridge_object_types( //dir=type + unique int id: @builtin_bridge_object_type +); + +builtin_default_actor_storage_types( //dir=type + unique int id: @builtin_default_actor_storage_type +); + +builtin_executor_types( //dir=type + unique int id: @builtin_executor_type +); + +builtin_float_types( //dir=type + unique int id: @builtin_float_type +); + +builtin_job_types( //dir=type + unique int id: @builtin_job_type +); + +builtin_native_object_types( //dir=type + unique int id: @builtin_native_object_type +); + +builtin_raw_pointer_types( //dir=type + unique int id: @builtin_raw_pointer_type +); + +builtin_raw_unsafe_continuation_types( //dir=type + unique int id: @builtin_raw_unsafe_continuation_type +); + +builtin_unsafe_value_buffer_types( //dir=type + unique int id: @builtin_unsafe_value_buffer_type +); + +builtin_vector_types( //dir=type + unique int id: @builtin_vector_type +); + +existential_metatype_types( //dir=type + unique int id: @existential_metatype_type +); + +function_types( //dir=type + unique int id: @function_type +); + +generic_function_types( //dir=type + unique int id: @generic_function_type +); + +#keyset[id, index] +generic_function_type_generic_params( //dir=type + int id: @generic_function_type ref, + int index: int ref, + int generic_param: @generic_type_param_type_or_none ref +); + +generic_type_param_types( //dir=type + unique int id: @generic_type_param_type +); + +metatype_types( //dir=type + unique int id: @metatype_type +); + +@nominal_or_bound_generic_nominal_type = + @bound_generic_type +| @nominal_type +; + +paren_types( //dir=type + unique int id: @paren_type, + int type_: @type_or_none ref +); + +@syntax_sugar_type = + @dictionary_type +| @unary_syntax_sugar_type +; + +type_alias_types( //dir=type + unique int id: @type_alias_type, + int decl: @type_alias_decl_or_none ref +); + +unbound_generic_types( //dir=type + unique int id: @unbound_generic_type +); + +unmanaged_storage_types( //dir=type + unique int id: @unmanaged_storage_type +); + +unowned_storage_types( //dir=type + unique int id: @unowned_storage_type +); + +weak_storage_types( //dir=type + unique int id: @weak_storage_type +); + +@bound_generic_type = + @bound_generic_class_type +| @bound_generic_enum_type +| @bound_generic_struct_type +; + +#keyset[id, index] +bound_generic_type_arg_types( //dir=type + int id: @bound_generic_type ref, + int index: int ref, + int arg_type: @type_or_none ref +); + +builtin_integer_literal_types( //dir=type + unique int id: @builtin_integer_literal_type +); + +builtin_integer_types( //dir=type + unique int id: @builtin_integer_type +); + +#keyset[id] +builtin_integer_type_widths( //dir=type + int id: @builtin_integer_type ref, + int width: int ref +); + +dictionary_types( //dir=type + unique int id: @dictionary_type, + int key_type: @type_or_none ref, + int value_type: @type_or_none ref +); + +@nominal_type = + @class_type +| @enum_type +| @protocol_type +| @struct_type +; + +opaque_type_archetype_types( //dir=type + unique int id: @opaque_type_archetype_type, + int declaration: @opaque_type_decl_or_none ref +); + +opened_archetype_types( //dir=type + unique int id: @opened_archetype_type +); + +primary_archetype_types( //dir=type + unique int id: @primary_archetype_type +); + +@unary_syntax_sugar_type = + @array_slice_type +| @optional_type +| @variadic_sequence_type +; + +#keyset[id] +unary_syntax_sugar_types( //dir=type + int id: @unary_syntax_sugar_type ref, + int base_type: @type_or_none ref +); + +array_slice_types( //dir=type + unique int id: @array_slice_type +); + +bound_generic_class_types( //dir=type + unique int id: @bound_generic_class_type +); + +bound_generic_enum_types( //dir=type + unique int id: @bound_generic_enum_type +); + +bound_generic_struct_types( //dir=type + unique int id: @bound_generic_struct_type +); + +class_types( //dir=type + unique int id: @class_type +); + +enum_types( //dir=type + unique int id: @enum_type +); + +optional_types( //dir=type + unique int id: @optional_type +); + +protocol_types( //dir=type + unique int id: @protocol_type +); + +struct_types( //dir=type + unique int id: @struct_type +); + +variadic_sequence_types( //dir=type + unique int id: @variadic_sequence_type +); + +@abstract_function_decl_or_none = + @abstract_function_decl +| @unspecified_element +; + +@accessor_decl_or_none = + @accessor_decl +| @unspecified_element +; + +@argument_or_none = + @argument +| @unspecified_element +; + +@associated_type_decl_or_none = + @associated_type_decl +| @unspecified_element +; + +@ast_node_or_none = + @ast_node +| @unspecified_element +; + +@availability_info_or_none = + @availability_info +| @unspecified_element +; + +@availability_spec_or_none = + @availability_spec +| @unspecified_element +; + +@brace_stmt_or_none = + @brace_stmt +| @unspecified_element +; + +@captured_decl_or_none = + @captured_decl +| @unspecified_element +; + +@case_label_item_or_none = + @case_label_item +| @unspecified_element +; + +@case_stmt_or_none = + @case_stmt +| @unspecified_element +; + +@closure_expr_or_none = + @closure_expr +| @unspecified_element +; + +@condition_element_or_none = + @condition_element +| @unspecified_element +; + +@constructor_decl_or_none = + @constructor_decl +| @unspecified_element +; + +@decl_or_none = + @decl +| @unspecified_element +; + +@enum_element_decl_or_none = + @enum_element_decl +| @unspecified_element +; + +@expr_or_none = + @expr +| @unspecified_element +; + +@file_or_none = + @file +| @unspecified_element +; + +@generic_type_decl_or_none = + @generic_type_decl +| @unspecified_element +; + +@generic_type_param_decl_or_none = + @generic_type_param_decl +| @unspecified_element +; + +@generic_type_param_type_or_none = + @generic_type_param_type +| @unspecified_element +; + +@location_or_none = + @location +| @unspecified_element +; + +@module_decl_or_none = + @module_decl +| @unspecified_element +; + +@nominal_type_decl_or_none = + @nominal_type_decl +| @unspecified_element +; + +@opaque_type_decl_or_none = + @opaque_type_decl +| @unspecified_element +; + +@opaque_value_expr_or_none = + @opaque_value_expr +| @unspecified_element +; + +@param_decl_or_none = + @param_decl +| @unspecified_element +; + +@pattern_or_none = + @pattern +| @unspecified_element +; + +@pattern_binding_decl_or_none = + @pattern_binding_decl +| @unspecified_element +; + +@precedence_group_decl_or_none = + @precedence_group_decl +| @unspecified_element +; + +@protocol_decl_or_none = + @protocol_decl +| @unspecified_element +; + +@protocol_type_or_none = + @protocol_type +| @unspecified_element +; + +@stmt_or_none = + @stmt +| @unspecified_element +; + +@stmt_condition_or_none = + @stmt_condition +| @unspecified_element +; + +@string_literal_expr_or_none = + @string_literal_expr +| @unspecified_element +; + +@tap_expr_or_none = + @tap_expr +| @unspecified_element +; + +@type_or_none = + @type +| @unspecified_element +; + +@type_alias_decl_or_none = + @type_alias_decl +| @unspecified_element +; + +@type_repr_or_none = + @type_repr +| @unspecified_element +; + +@value_decl_or_none = + @unspecified_element +| @value_decl +; + +@var_decl_or_none = + @unspecified_element +| @var_decl +; diff --git a/swift/downgrades/e457bc35325b05725c00471da8843f293fe26f8d/upgrade.properties b/swift/downgrades/e457bc35325b05725c00471da8843f293fe26f8d/upgrade.properties new file mode 100644 index 00000000000..160d55476c9 --- /dev/null +++ b/swift/downgrades/e457bc35325b05725c00471da8843f293fe26f8d/upgrade.properties @@ -0,0 +1,4 @@ +description: Revert turning exported and imported modules into unindexed sets +compatibility: full +module_decl_imported_modules.rel: run module_decl_imported_modules.ql +module_decl_exported_modules.rel: run module_decl_exported_modules.ql diff --git a/swift/extractor/SwiftExtractor.cpp b/swift/extractor/SwiftExtractor.cpp index 9638ac2949b..c331dcbc3c1 100644 --- a/swift/extractor/SwiftExtractor.cpp +++ b/swift/extractor/SwiftExtractor.cpp @@ -161,11 +161,12 @@ static std::unordered_set extractDeclarations( static std::unordered_set collectInputFilenames(swift::CompilerInstance& compiler) { // The frontend can be called in many different ways. // At each invocation we only extract system and builtin modules and any input source files that - // have an output associated with them. + // are primary inputs, or all of them if there are no primary inputs (whole module optimization) std::unordered_set sourceFiles; - auto inputFiles = compiler.getInvocation().getFrontendOptions().InputsAndOutputs.getAllInputs(); - for (auto& input : inputFiles) { - if (input.getType() == swift::file_types::TY_Swift && !input.outputFilename().empty()) { + const auto& inOuts = compiler.getInvocation().getFrontendOptions().InputsAndOutputs; + for (auto& input : inOuts.getAllInputs()) { + if (input.getType() == swift::file_types::TY_Swift && + (!inOuts.hasPrimaryInputs() || input.isPrimary())) { sourceFiles.insert(input.getFileName()); } } diff --git a/swift/integration-tests/posix-only/frontend-invocations/Files.expected b/swift/integration-tests/posix-only/frontend-invocations/Files.expected index 1e97daa9ab4..296a5d16513 100644 --- a/swift/integration-tests/posix-only/frontend-invocations/Files.expected +++ b/swift/integration-tests/posix-only/frontend-invocations/Files.expected @@ -6,6 +6,7 @@ | F1.swift:0:0:0:0 | F1.swift | | F2.swift:0:0:0:0 | F2.swift | | F3.swift:0:0:0:0 | F3.swift | +| F4.swift:0:0:0:0 | F4.swift | | F5.swift:0:0:0:0 | F5.swift | | G.swift:0:0:0:0 | G.swift | | H1.swift:0:0:0:0 | H1.swift | diff --git a/swift/ql/.generated.list b/swift/ql/.generated.list index 2a0d663241d..c58d03ef518 100644 --- a/swift/ql/.generated.list +++ b/swift/ql/.generated.list @@ -384,7 +384,7 @@ ql/lib/codeql/swift/generated/OtherAvailabilitySpec.qll 0e26a203b26ff0581b7396b0 ql/lib/codeql/swift/generated/ParentChild.qll 7d45d4e872e769f37a5b157ba422c48afe482552e44d94ff5f6a5a6449d672e7 6f7464ecd8ca04b6aa261139b36a162e5b0636237d514b8431ef4f97a1c603dc ql/lib/codeql/swift/generated/PlatformVersionAvailabilitySpec.qll f82d9ca416fe8bd59b5531b65b1c74c9f317b3297a6101544a11339a1cffce38 7f5c6d3309e66c134107afe55bae76dfc9a72cb7cdd6d4c3706b6b34cee09fa0 ql/lib/codeql/swift/generated/PureSynthConstructors.qll 173c0dd59396a1de26fe870e3bc2766c46de689da2a4d8807cb62023bbce1a98 173c0dd59396a1de26fe870e3bc2766c46de689da2a4d8807cb62023bbce1a98 -ql/lib/codeql/swift/generated/Raw.qll b1ad09374cf2d5556e0a409a59eea723a7280882ae144f68fd2dae362cb147b7 587433583a7e93c9a8534cb59409fd802e4b6587faf1367df9447d06be191c73 +ql/lib/codeql/swift/generated/Raw.qll 60bce9edc4af395d7c64959e1fb8abd6d0a79ea4920417e978783c3d357ef087 69d97b1a3a7e32834057fb95e9015fadbae4358af4f76b7e0c646f254c62f0ad ql/lib/codeql/swift/generated/Synth.qll af02e0b49fe7b488592687996cc74d9525d4e3fbc9d324820b310b356f4d2612 5c740a660721173e9e4e45eb701d373ca19ff14d61cdaea309b65871e0deea90 ql/lib/codeql/swift/generated/SynthConstructors.qll a1b3ca33017f82124286ccad317a05484fee144fb9c3cdd2e500ce38e5efcec4 a1b3ca33017f82124286ccad317a05484fee144fb9c3cdd2e500ce38e5efcec4 ql/lib/codeql/swift/generated/UnknownFile.qll 0fcf9beb8de79440bcdfff4bb6ab3dd139bd273e6c32754e05e6a632651e85f6 0fcf9beb8de79440bcdfff4bb6ab3dd139bd273e6c32754e05e6a632651e85f6 @@ -414,7 +414,7 @@ ql/lib/codeql/swift/generated/decl/IfConfigDecl.qll 58c1a02a3867105c61d29e2d9bc6 ql/lib/codeql/swift/generated/decl/ImportDecl.qll 8892cd34d182c6747e266e213f0239fd3402004370a9be6e52b9747d91a7b61b 2c07217ab1b7ebc39dc2cb20d45a2b1b899150cabd3b1a15cd8b1479bab64578 ql/lib/codeql/swift/generated/decl/InfixOperatorDecl.qll d98168fdf180f28582bae8ec0242c1220559235230a9c94e9f479708c561ea21 aad805aa74d63116b19f435983d6df6df31cef6a5bbd30d7c2944280b470dee6 ql/lib/codeql/swift/generated/decl/MissingMemberDecl.qll eaf8989eda461ec886a2e25c1e5e80fc4a409f079c8d28671e6e2127e3167479 d74b31b5dfa54ca5411cd5d41c58f1f76cfccc1e12b4f1fdeed398b4faae5355 -ql/lib/codeql/swift/generated/decl/ModuleDecl.qll 675135d140d273cd83e290cf433bcaebc48065d433e2cf8e570612b686d2fb53 d8cd5418205e05598800bf13e8aa01e6018b5c6727075381afd4c83136c29366 +ql/lib/codeql/swift/generated/decl/ModuleDecl.qll 0b809c371dae40cfdc7bf869c654158dc154e1551d8466c339742c7fdc26a5db 3d7efb0ccfd752d9f01624d21eba79067824b3910b11185c81f0b513b69e8c51 ql/lib/codeql/swift/generated/decl/NominalTypeDecl.qll 7e8980cd646e9dee91e429f738d6682b18c8f8974c9561c7b936fca01b56fdb2 513e55dd6a68d83a8e884c9a373ecd70eca8e3957e0f5f6c2b06696e4f56df88 ql/lib/codeql/swift/generated/decl/OpaqueTypeDecl.qll f2cdbc238b9ea67d5bc2defd8ec0455efafd7fdaeca5b2f72d0bbb16a8006d17 041724a6ec61b60291d2a68d228d5f106c02e1ba6bf3c1d3d0a6dda25777a0e5 ql/lib/codeql/swift/generated/decl/OperatorDecl.qll 3ffdc7ab780ee94a975f0ce3ae4252b52762ca8dbea6f0eb95f951e404c36a5b 25e39ccd868fa2d1fbce0eb7cbf8e9c2aca67d6fd42f76e247fb0fa74a51b230 @@ -720,9 +720,9 @@ ql/test/extractor-tests/generated/decl/ImportDecl/ImportDecl_getImportedModule.q ql/test/extractor-tests/generated/decl/ImportDecl/ImportDecl_getMember.ql 6d48d3a93bc96dba3bda71ec9d9d6282615c2228a58da6167c169fafaedb3e17 8560b23d0f52b845c81727ce09c0b2f9647965c83d7de165e8cd3d91be5bdd42 ql/test/extractor-tests/generated/decl/InfixOperatorDecl/MISSING_SOURCE.txt 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7 ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl.ql f9216e83077ebc0cb5a5bf2d7368af86167a1bfd378f9cd5592fd484a1bbc5dd 1c2de61cb064474340db10de4399c49f15eb0a5669e6dc9587d8b4f656b0134f +ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getAnExportedModule.ql 321619519c5cffefda78f11f2c85a199af76fccbfcc51126c7a558ba12fdfd80 30e48eb820ba9d7f3ec30bf4536c0f84280c5f2ca8c63427f6b77d74a092e68b +ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getAnImportedModule.ql 65fae5b1a7db3a11fd837ed78c663e8907306c36695ae73e4e29559755276fbe 3ddef1a7af7a636e66674fadb3e727ad18655a9ecb4c73fd3d6aca202f1191fb ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getBaseType.ql 54a4bd2cfa666271ae9092285bb7217b082c88483d614066cfb599fc8ab84305 8b24ab8e93efe3922cb192eb5de5f517763058782e83e8732153421adddd68e1 -ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getExportedModule.ql cfca012f0951c86560d892ea5eae182d5eda661c9484a0df71ef9c905123e8f6 dfebda4fcad0e2f2a2c944782a7355b3caeac569e5a45621c582bc1bb243b2cc -ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getImportedModule.ql 44018a788205592c59cd10072f8b8d0558100bb15fff4b3e490176e86193e5b1 cc9fe6571713af8a0e844ac5da682c24feb1a2be4535e3feeb4cbbafba91a414 ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getMember.ql a4663d47cf0a16a07167b9a64d56f8ba8e504a78142c7e216d1df69879df9130 3f6a4080e33bddd1e34fa25519d855811c256182055db4989be8150fcddd541b ql/test/extractor-tests/generated/decl/OpaqueTypeDecl/OpaqueTypeDecl.ql 16ccca5a90cc3133ab085ccb843416abc103f2fcf3423a84fbd7f5c15a5c7f17 242d7ea07842ee3fb0f9905b5cbc0ea744f1116c4591c5f133025260991bfdeb ql/test/extractor-tests/generated/decl/OpaqueTypeDecl/OpaqueTypeDecl_getBaseType.ql d030fd55ea5a5443c03e8ba1a024c03e3c68c96c948c850131f59fbac6409402 46816c1a75a4cf11db95884733382e46d5573b6c1116d5de0bfe5ae91fed4c3d diff --git a/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll b/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll index ab4743dadeb..6917f8ea209 100644 --- a/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll +++ b/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll @@ -99,6 +99,7 @@ private module Frameworks { private import codeql.swift.security.CleartextStorageDatabaseExtensions private import codeql.swift.security.PathInjectionExtensions private import codeql.swift.security.PredicateInjectionExtensions + private import codeql.swift.security.StringLengthConflationExtensions } /** diff --git a/swift/ql/lib/codeql/swift/elements/type/NominalType.qll b/swift/ql/lib/codeql/swift/elements/type/NominalType.qll index 9e1c4a9a8c0..4abc15e30f2 100644 --- a/swift/ql/lib/codeql/swift/elements/type/NominalType.qll +++ b/swift/ql/lib/codeql/swift/elements/type/NominalType.qll @@ -3,7 +3,7 @@ private import codeql.swift.elements.decl.NominalTypeDecl private import codeql.swift.elements.type.Type class NominalType extends Generated::NominalType { - Type getABaseType() { result = this.getDeclaration().(NominalTypeDecl).getABaseType() } + override Type getABaseType() { result = this.getDeclaration().(NominalTypeDecl).getABaseType() } NominalType getADerivedType() { result.getABaseType() = this } diff --git a/swift/ql/lib/codeql/swift/elements/type/Type.qll b/swift/ql/lib/codeql/swift/elements/type/Type.qll index b59da586b63..ec72e8aa9fd 100644 --- a/swift/ql/lib/codeql/swift/elements/type/Type.qll +++ b/swift/ql/lib/codeql/swift/elements/type/Type.qll @@ -11,4 +11,18 @@ class Type extends Generated::Type { * ``` */ Type getUnderlyingType() { result = this } + + /** + * Gets any base type of this type. For a `typealias`, this is a base type + * of the aliased type. For example in the following code, both `B` and + * `B_alias` have base type `A`. + * ``` + * class A {} + * + * class B : A {} + * + * typealias B_alias = B + * ``` + */ + Type getABaseType() { none() } } diff --git a/swift/ql/lib/codeql/swift/elements/type/TypeAliasType.qll b/swift/ql/lib/codeql/swift/elements/type/TypeAliasType.qll index b7b3045d9e0..1d8e8fb1fd2 100644 --- a/swift/ql/lib/codeql/swift/elements/type/TypeAliasType.qll +++ b/swift/ql/lib/codeql/swift/elements/type/TypeAliasType.qll @@ -13,4 +13,6 @@ class TypeAliasType extends Generated::TypeAliasType { Type getAliasedType() { result = this.getDecl().getAliasedType() } override Type getUnderlyingType() { result = this.getAliasedType().getUnderlyingType() } + + override Type getABaseType() { result = this.getAliasedType().getABaseType() } } diff --git a/swift/ql/lib/codeql/swift/generated/Raw.qll b/swift/ql/lib/codeql/swift/generated/Raw.qll index beb035d81c5..b081700ead4 100644 --- a/swift/ql/lib/codeql/swift/generated/Raw.qll +++ b/swift/ql/lib/codeql/swift/generated/Raw.qll @@ -419,13 +419,15 @@ module Raw { /** * Gets the `index`th imported module of this module declaration (0-based). + *Gets any of the imported modules of this module declaration. */ - ModuleDecl getImportedModule(int index) { module_decl_imported_modules(this, index, result) } + ModuleDecl getAnImportedModule() { module_decl_imported_modules(this, result) } /** * Gets the `index`th exported module of this module declaration (0-based). + *Gets any of the exported modules of this module declaration. */ - ModuleDecl getExportedModule(int index) { module_decl_exported_modules(this, index, result) } + ModuleDecl getAnExportedModule() { module_decl_exported_modules(this, result) } } class SubscriptDecl extends @subscript_decl, AbstractStorageDecl, GenericContext { diff --git a/swift/ql/lib/codeql/swift/generated/decl/ModuleDecl.qll b/swift/ql/lib/codeql/swift/generated/decl/ModuleDecl.qll index 4b10570ef7b..7f11f4a1cbd 100644 --- a/swift/ql/lib/codeql/swift/generated/decl/ModuleDecl.qll +++ b/swift/ql/lib/codeql/swift/generated/decl/ModuleDecl.qll @@ -23,62 +23,52 @@ module Generated { /** * Gets the `index`th imported module of this module declaration (0-based). + *Gets any of the imported modules of this module declaration. * * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the * behavior of both the `Immediate` and non-`Immediate` versions. */ - ModuleDecl getImmediateImportedModule(int index) { + ModuleDecl getAnImmediateImportedModule() { result = Synth::convertModuleDeclFromRaw(Synth::convertModuleDeclToRaw(this) .(Raw::ModuleDecl) - .getImportedModule(index)) + .getAnImportedModule()) } /** * Gets the `index`th imported module of this module declaration (0-based). + *Gets any of the imported modules of this module declaration. */ - final ModuleDecl getImportedModule(int index) { - result = getImmediateImportedModule(index).resolve() - } - - /** - * Gets any of the imported modules of this module declaration. - */ - final ModuleDecl getAnImportedModule() { result = getImportedModule(_) } + final ModuleDecl getAnImportedModule() { result = getAnImmediateImportedModule().resolve() } /** * Gets the number of imported modules of this module declaration. */ - final int getNumberOfImportedModules() { result = count(int i | exists(getImportedModule(i))) } + final int getNumberOfImportedModules() { result = count(getAnImportedModule()) } /** * Gets the `index`th exported module of this module declaration (0-based). + *Gets any of the exported modules of this module declaration. * * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the * behavior of both the `Immediate` and non-`Immediate` versions. */ - ModuleDecl getImmediateExportedModule(int index) { + ModuleDecl getAnImmediateExportedModule() { result = Synth::convertModuleDeclFromRaw(Synth::convertModuleDeclToRaw(this) .(Raw::ModuleDecl) - .getExportedModule(index)) + .getAnExportedModule()) } /** * Gets the `index`th exported module of this module declaration (0-based). + *Gets any of the exported modules of this module declaration. */ - final ModuleDecl getExportedModule(int index) { - result = getImmediateExportedModule(index).resolve() - } - - /** - * Gets any of the exported modules of this module declaration. - */ - final ModuleDecl getAnExportedModule() { result = getExportedModule(_) } + final ModuleDecl getAnExportedModule() { result = getAnImmediateExportedModule().resolve() } /** * Gets the number of exported modules of this module declaration. */ - final int getNumberOfExportedModules() { result = count(int i | exists(getExportedModule(i))) } + final int getNumberOfExportedModules() { result = count(getAnExportedModule()) } } } diff --git a/swift/ql/lib/codeql/swift/security/CleartextStorageDatabaseExtensions.qll b/swift/ql/lib/codeql/swift/security/CleartextStorageDatabaseExtensions.qll index e8529ff5d06..c1e3e62d6f4 100644 --- a/swift/ql/lib/codeql/swift/security/CleartextStorageDatabaseExtensions.qll +++ b/swift/ql/lib/codeql/swift/security/CleartextStorageDatabaseExtensions.qll @@ -49,7 +49,7 @@ private class CoreDataStore extends CleartextStorageDatabaseSink { // with `coreDataObj.data` is a sink. // (ideally this would be only members with the `@NSManaged` attribute) exists(NominalType t, Expr e | - t.getABaseType*().getName() = "NSManagedObject" and + t.getABaseType*().getUnderlyingType().getName() = "NSManagedObject" and this.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr() = e and e.getFullyConverted().getType() = t and not e.(DeclRefExpr).getDecl() instanceof SelfParamDecl @@ -67,7 +67,7 @@ private class RealmStore extends CleartextStorageDatabaseSink instanceof DataFlo // example in `realmObj.data = sensitive` the post-update node corresponding // with `realmObj.data` is a sink. exists(NominalType t, Expr e | - t.getABaseType*().getName() = "RealmSwiftObject" and + t.getABaseType*().getUnderlyingType().getName() = "RealmSwiftObject" and this.getPreUpdateNode().asExpr() = e and e.getFullyConverted().getType() = t and not e.(DeclRefExpr).getDecl() instanceof SelfParamDecl diff --git a/swift/ql/lib/codeql/swift/security/CleartextStorageDatabaseQuery.qll b/swift/ql/lib/codeql/swift/security/CleartextStorageDatabaseQuery.qll index e77f7f523bd..70b71606fcd 100644 --- a/swift/ql/lib/codeql/swift/security/CleartextStorageDatabaseQuery.qll +++ b/swift/ql/lib/codeql/swift/security/CleartextStorageDatabaseQuery.qll @@ -37,9 +37,10 @@ class CleartextStorageConfig extends TaintTracking::Configuration { // flow out from fields of an `NSManagedObject` or `RealmSwiftObject` at the sink, // for example in `realmObj.data = sensitive`. isSink(node) and - exists(ClassOrStructDecl cd, Decl cx | - cd.getABaseTypeDecl*().getName() = ["NSManagedObject", "RealmSwiftObject"] and - cx.asNominalTypeDecl() = cd and + exists(NominalTypeDecl d, Decl cx | + d.getType().getABaseType*().getUnderlyingType().getName() = + ["NSManagedObject", "RealmSwiftObject"] and + cx.asNominalTypeDecl() = d and c.getAReadContent().(DataFlow::Content::FieldContent).getField() = cx.getAMember() ) or diff --git a/swift/ql/lib/swift.dbscheme b/swift/ql/lib/swift.dbscheme index e646f9e0308..e457bc35325 100644 --- a/swift/ql/lib/swift.dbscheme +++ b/swift/ql/lib/swift.dbscheme @@ -482,17 +482,13 @@ module_decl_is_system_module( //dir=decl int id: @module_decl ref ); -#keyset[id, index] module_decl_imported_modules( //dir=decl int id: @module_decl ref, - int index: int ref, int imported_module: @module_decl_or_none ref ); -#keyset[id, index] module_decl_exported_modules( //dir=decl int id: @module_decl ref, - int index: int ref, int exported_module: @module_decl_or_none ref ); diff --git a/swift/ql/lib/upgrades/e646f9e0308ec7135c83c0fdf96896d2737a8013/old.dbscheme b/swift/ql/lib/upgrades/e646f9e0308ec7135c83c0fdf96896d2737a8013/old.dbscheme new file mode 100644 index 00000000000..e646f9e0308 --- /dev/null +++ b/swift/ql/lib/upgrades/e646f9e0308ec7135c83c0fdf96896d2737a8013/old.dbscheme @@ -0,0 +1,2602 @@ +// generated by codegen/codegen.py + +// from prefix.dbscheme +/** + * The source location of the snapshot. + */ +sourceLocationPrefix( + string prefix: string ref +); + + +// from schema.py + +@element = + @callable +| @file +| @generic_context +| @locatable +| @location +| @type +; + +#keyset[id] +element_is_unknown( + int id: @element ref +); + +@callable = + @abstract_closure_expr +| @abstract_function_decl +; + +#keyset[id] +callable_names( + int id: @callable ref, + string name: string ref +); + +#keyset[id] +callable_self_params( + int id: @callable ref, + int self_param: @param_decl_or_none ref +); + +#keyset[id, index] +callable_params( + int id: @callable ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +#keyset[id] +callable_bodies( + int id: @callable ref, + int body: @brace_stmt_or_none ref +); + +#keyset[id, index] +callable_captures( + int id: @callable ref, + int index: int ref, + int capture: @captured_decl_or_none ref +); + +@file = + @db_file +; + +#keyset[id] +files( + int id: @file ref, + string name: string ref +); + +#keyset[id] +file_is_successfully_extracted( + int id: @file ref +); + +@locatable = + @argument +| @ast_node +| @comment +| @diagnostics +| @error_element +; + +#keyset[id] +locatable_locations( + int id: @locatable ref, + int location: @location_or_none ref +); + +@location = + @db_location +; + +#keyset[id] +locations( + int id: @location ref, + int file: @file_or_none ref, + int start_line: int ref, + int start_column: int ref, + int end_line: int ref, + int end_column: int ref +); + +@ast_node = + @availability_info +| @availability_spec +| @case_label_item +| @condition_element +| @decl +| @expr +| @pattern +| @stmt +| @stmt_condition +| @type_repr +; + +comments( + unique int id: @comment, + string text: string ref +); + +db_files( + unique int id: @db_file +); + +db_locations( + unique int id: @db_location +); + +diagnostics( + unique int id: @diagnostics, + string text: string ref, + int kind: int ref +); + +@error_element = + @error_expr +| @error_type +| @overloaded_decl_ref_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_chain_result_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @unresolved_type +| @unresolved_type_conversion_expr +| @unspecified_element +; + +availability_infos( + unique int id: @availability_info +); + +#keyset[id] +availability_info_is_unavailable( + int id: @availability_info ref +); + +#keyset[id, index] +availability_info_specs( + int id: @availability_info ref, + int index: int ref, + int spec: @availability_spec_or_none ref +); + +@availability_spec = + @other_availability_spec +| @platform_version_availability_spec +; + +unspecified_elements( + unique int id: @unspecified_element, + string property: string ref, + string error: string ref +); + +#keyset[id] +unspecified_element_parents( + int id: @unspecified_element ref, + int parent: @element ref +); + +#keyset[id] +unspecified_element_indices( + int id: @unspecified_element ref, + int index: int ref +); + +other_availability_specs( + unique int id: @other_availability_spec +); + +platform_version_availability_specs( + unique int id: @platform_version_availability_spec, + string platform: string ref, + string version: string ref +); + +@decl = + @captured_decl +| @enum_case_decl +| @extension_decl +| @if_config_decl +| @import_decl +| @missing_member_decl +| @operator_decl +| @pattern_binding_decl +| @pound_diagnostic_decl +| @precedence_group_decl +| @top_level_code_decl +| @value_decl +; + +#keyset[id] +decls( //dir=decl + int id: @decl ref, + int module: @module_decl_or_none ref +); + +#keyset[id, index] +decl_members( //dir=decl + int id: @decl ref, + int index: int ref, + int member: @decl_or_none ref +); + +@generic_context = + @abstract_function_decl +| @extension_decl +| @generic_type_decl +| @subscript_decl +; + +#keyset[id, index] +generic_context_generic_type_params( //dir=decl + int id: @generic_context ref, + int index: int ref, + int generic_type_param: @generic_type_param_decl_or_none ref +); + +captured_decls( //dir=decl + unique int id: @captured_decl, + int decl: @value_decl_or_none ref +); + +#keyset[id] +captured_decl_is_direct( //dir=decl + int id: @captured_decl ref +); + +#keyset[id] +captured_decl_is_escaping( //dir=decl + int id: @captured_decl ref +); + +enum_case_decls( //dir=decl + unique int id: @enum_case_decl +); + +#keyset[id, index] +enum_case_decl_elements( //dir=decl + int id: @enum_case_decl ref, + int index: int ref, + int element: @enum_element_decl_or_none ref +); + +extension_decls( //dir=decl + unique int id: @extension_decl, + int extended_type_decl: @nominal_type_decl_or_none ref +); + +#keyset[id, index] +extension_decl_protocols( //dir=decl + int id: @extension_decl ref, + int index: int ref, + int protocol: @protocol_decl_or_none ref +); + +if_config_decls( //dir=decl + unique int id: @if_config_decl +); + +#keyset[id, index] +if_config_decl_active_elements( //dir=decl + int id: @if_config_decl ref, + int index: int ref, + int active_element: @ast_node_or_none ref +); + +import_decls( //dir=decl + unique int id: @import_decl +); + +#keyset[id] +import_decl_is_exported( //dir=decl + int id: @import_decl ref +); + +#keyset[id] +import_decl_imported_modules( //dir=decl + int id: @import_decl ref, + int imported_module: @module_decl_or_none ref +); + +#keyset[id, index] +import_decl_declarations( //dir=decl + int id: @import_decl ref, + int index: int ref, + int declaration: @value_decl_or_none ref +); + +missing_member_decls( //dir=decl + unique int id: @missing_member_decl, + string name: string ref +); + +@operator_decl = + @infix_operator_decl +| @postfix_operator_decl +| @prefix_operator_decl +; + +#keyset[id] +operator_decls( //dir=decl + int id: @operator_decl ref, + string name: string ref +); + +pattern_binding_decls( //dir=decl + unique int id: @pattern_binding_decl +); + +#keyset[id, index] +pattern_binding_decl_inits( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int init: @expr_or_none ref +); + +#keyset[id, index] +pattern_binding_decl_patterns( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int pattern: @pattern_or_none ref +); + +pound_diagnostic_decls( //dir=decl + unique int id: @pound_diagnostic_decl, + int kind: int ref, + int message: @string_literal_expr_or_none ref +); + +precedence_group_decls( //dir=decl + unique int id: @precedence_group_decl +); + +top_level_code_decls( //dir=decl + unique int id: @top_level_code_decl, + int body: @brace_stmt_or_none ref +); + +@value_decl = + @abstract_function_decl +| @abstract_storage_decl +| @enum_element_decl +| @type_decl +; + +#keyset[id] +value_decls( //dir=decl + int id: @value_decl ref, + int interface_type: @type_or_none ref +); + +@abstract_function_decl = + @constructor_decl +| @destructor_decl +| @func_decl +; + +@abstract_storage_decl = + @subscript_decl +| @var_decl +; + +#keyset[id, index] +abstract_storage_decl_accessor_decls( //dir=decl + int id: @abstract_storage_decl ref, + int index: int ref, + int accessor_decl: @accessor_decl_or_none ref +); + +enum_element_decls( //dir=decl + unique int id: @enum_element_decl, + string name: string ref +); + +#keyset[id, index] +enum_element_decl_params( //dir=decl + int id: @enum_element_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +infix_operator_decls( //dir=decl + unique int id: @infix_operator_decl +); + +#keyset[id] +infix_operator_decl_precedence_groups( //dir=decl + int id: @infix_operator_decl ref, + int precedence_group: @precedence_group_decl_or_none ref +); + +postfix_operator_decls( //dir=decl + unique int id: @postfix_operator_decl +); + +prefix_operator_decls( //dir=decl + unique int id: @prefix_operator_decl +); + +@type_decl = + @abstract_type_param_decl +| @generic_type_decl +| @module_decl +; + +#keyset[id] +type_decls( //dir=decl + int id: @type_decl ref, + string name: string ref +); + +#keyset[id, index] +type_decl_base_types( //dir=decl + int id: @type_decl ref, + int index: int ref, + int base_type: @type_or_none ref +); + +@abstract_type_param_decl = + @associated_type_decl +| @generic_type_param_decl +; + +constructor_decls( //dir=decl + unique int id: @constructor_decl +); + +destructor_decls( //dir=decl + unique int id: @destructor_decl +); + +@func_decl = + @accessor_decl +| @concrete_func_decl +; + +@generic_type_decl = + @nominal_type_decl +| @opaque_type_decl +| @type_alias_decl +; + +module_decls( //dir=decl + unique int id: @module_decl +); + +#keyset[id] +module_decl_is_builtin_module( //dir=decl + int id: @module_decl ref +); + +#keyset[id] +module_decl_is_system_module( //dir=decl + int id: @module_decl ref +); + +#keyset[id, index] +module_decl_imported_modules( //dir=decl + int id: @module_decl ref, + int index: int ref, + int imported_module: @module_decl_or_none ref +); + +#keyset[id, index] +module_decl_exported_modules( //dir=decl + int id: @module_decl ref, + int index: int ref, + int exported_module: @module_decl_or_none ref +); + +subscript_decls( //dir=decl + unique int id: @subscript_decl, + int element_type: @type_or_none ref +); + +#keyset[id, index] +subscript_decl_params( //dir=decl + int id: @subscript_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +@var_decl = + @concrete_var_decl +| @param_decl +; + +#keyset[id] +var_decls( //dir=decl + int id: @var_decl ref, + string name: string ref, + int type_: @type_or_none ref +); + +#keyset[id] +var_decl_attached_property_wrapper_types( //dir=decl + int id: @var_decl ref, + int attached_property_wrapper_type: @type_or_none ref +); + +#keyset[id] +var_decl_parent_patterns( //dir=decl + int id: @var_decl ref, + int parent_pattern: @pattern_or_none ref +); + +#keyset[id] +var_decl_parent_initializers( //dir=decl + int id: @var_decl ref, + int parent_initializer: @expr_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var: @var_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var: @var_decl_or_none ref +); + +accessor_decls( //dir=decl + unique int id: @accessor_decl +); + +#keyset[id] +accessor_decl_is_getter( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_setter( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_will_set( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_did_set( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_read( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_modify( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_unsafe_address( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_unsafe_mutable_address( //dir=decl + int id: @accessor_decl ref +); + +associated_type_decls( //dir=decl + unique int id: @associated_type_decl +); + +concrete_func_decls( //dir=decl + unique int id: @concrete_func_decl +); + +concrete_var_decls( //dir=decl + unique int id: @concrete_var_decl, + int introducer_int: int ref +); + +generic_type_param_decls( //dir=decl + unique int id: @generic_type_param_decl +); + +@nominal_type_decl = + @class_decl +| @enum_decl +| @protocol_decl +| @struct_decl +; + +#keyset[id] +nominal_type_decls( //dir=decl + int id: @nominal_type_decl ref, + int type_: @type_or_none ref +); + +opaque_type_decls( //dir=decl + unique int id: @opaque_type_decl, + int naming_declaration: @value_decl_or_none ref +); + +#keyset[id, index] +opaque_type_decl_opaque_generic_params( //dir=decl + int id: @opaque_type_decl ref, + int index: int ref, + int opaque_generic_param: @generic_type_param_type_or_none ref +); + +param_decls( //dir=decl + unique int id: @param_decl +); + +#keyset[id] +param_decl_is_inout( //dir=decl + int id: @param_decl ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_var_bindings( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_vars( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var: @var_decl_or_none ref +); + +type_alias_decls( //dir=decl + unique int id: @type_alias_decl, + int aliased_type: @type_or_none ref +); + +class_decls( //dir=decl + unique int id: @class_decl +); + +enum_decls( //dir=decl + unique int id: @enum_decl +); + +protocol_decls( //dir=decl + unique int id: @protocol_decl +); + +struct_decls( //dir=decl + unique int id: @struct_decl +); + +arguments( //dir=expr + unique int id: @argument, + string label: string ref, + int expr: @expr_or_none ref +); + +@expr = + @abstract_closure_expr +| @any_try_expr +| @applied_property_wrapper_expr +| @apply_expr +| @assign_expr +| @bind_optional_expr +| @capture_list_expr +| @collection_expr +| @decl_ref_expr +| @default_argument_expr +| @discard_assignment_expr +| @dot_syntax_base_ignored_expr +| @dynamic_type_expr +| @enum_is_case_expr +| @error_expr +| @explicit_cast_expr +| @force_value_expr +| @identity_expr +| @if_expr +| @implicit_conversion_expr +| @in_out_expr +| @key_path_application_expr +| @key_path_dot_expr +| @key_path_expr +| @lazy_initializer_expr +| @literal_expr +| @lookup_expr +| @make_temporarily_escapable_expr +| @obj_c_selector_expr +| @one_way_expr +| @opaque_value_expr +| @open_existential_expr +| @optional_evaluation_expr +| @other_constructor_decl_ref_expr +| @overloaded_decl_ref_expr +| @property_wrapper_value_placeholder_expr +| @rebind_self_in_constructor_expr +| @sequence_expr +| @super_ref_expr +| @tap_expr +| @tuple_element_expr +| @tuple_expr +| @type_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @vararg_expansion_expr +; + +#keyset[id] +expr_types( //dir=expr + int id: @expr ref, + int type_: @type_or_none ref +); + +@abstract_closure_expr = + @auto_closure_expr +| @closure_expr +; + +@any_try_expr = + @force_try_expr +| @optional_try_expr +| @try_expr +; + +#keyset[id] +any_try_exprs( //dir=expr + int id: @any_try_expr ref, + int sub_expr: @expr_or_none ref +); + +applied_property_wrapper_exprs( //dir=expr + unique int id: @applied_property_wrapper_expr, + int kind: int ref, + int value: @expr_or_none ref, + int param: @param_decl_or_none ref +); + +@apply_expr = + @binary_expr +| @call_expr +| @postfix_unary_expr +| @prefix_unary_expr +| @self_apply_expr +; + +#keyset[id] +apply_exprs( //dir=expr + int id: @apply_expr ref, + int function: @expr_or_none ref +); + +#keyset[id, index] +apply_expr_arguments( //dir=expr + int id: @apply_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +assign_exprs( //dir=expr + unique int id: @assign_expr, + int dest: @expr_or_none ref, + int source: @expr_or_none ref +); + +bind_optional_exprs( //dir=expr + unique int id: @bind_optional_expr, + int sub_expr: @expr_or_none ref +); + +capture_list_exprs( //dir=expr + unique int id: @capture_list_expr, + int closure_body: @closure_expr_or_none ref +); + +#keyset[id, index] +capture_list_expr_binding_decls( //dir=expr + int id: @capture_list_expr ref, + int index: int ref, + int binding_decl: @pattern_binding_decl_or_none ref +); + +@collection_expr = + @array_expr +| @dictionary_expr +; + +decl_ref_exprs( //dir=expr + unique int id: @decl_ref_expr, + int decl: @decl_or_none ref +); + +#keyset[id, index] +decl_ref_expr_replacement_types( //dir=expr + int id: @decl_ref_expr ref, + int index: int ref, + int replacement_type: @type_or_none ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_ordinary_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_distributed_thunk_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +default_argument_exprs( //dir=expr + unique int id: @default_argument_expr, + int param_decl: @param_decl_or_none ref, + int param_index: int ref +); + +#keyset[id] +default_argument_expr_caller_side_defaults( //dir=expr + int id: @default_argument_expr ref, + int caller_side_default: @expr_or_none ref +); + +discard_assignment_exprs( //dir=expr + unique int id: @discard_assignment_expr +); + +dot_syntax_base_ignored_exprs( //dir=expr + unique int id: @dot_syntax_base_ignored_expr, + int qualifier: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +dynamic_type_exprs( //dir=expr + unique int id: @dynamic_type_expr, + int base: @expr_or_none ref +); + +enum_is_case_exprs( //dir=expr + unique int id: @enum_is_case_expr, + int sub_expr: @expr_or_none ref, + int element: @enum_element_decl_or_none ref +); + +error_exprs( //dir=expr + unique int id: @error_expr +); + +@explicit_cast_expr = + @checked_cast_expr +| @coerce_expr +; + +#keyset[id] +explicit_cast_exprs( //dir=expr + int id: @explicit_cast_expr ref, + int sub_expr: @expr_or_none ref +); + +force_value_exprs( //dir=expr + unique int id: @force_value_expr, + int sub_expr: @expr_or_none ref +); + +@identity_expr = + @await_expr +| @dot_self_expr +| @paren_expr +| @unresolved_member_chain_result_expr +; + +#keyset[id] +identity_exprs( //dir=expr + int id: @identity_expr ref, + int sub_expr: @expr_or_none ref +); + +if_exprs( //dir=expr + unique int id: @if_expr, + int condition: @expr_or_none ref, + int then_expr: @expr_or_none ref, + int else_expr: @expr_or_none ref +); + +@implicit_conversion_expr = + @abi_safe_conversion_expr +| @any_hashable_erasure_expr +| @archetype_to_super_expr +| @array_to_pointer_expr +| @bridge_from_obj_c_expr +| @bridge_to_obj_c_expr +| @class_metatype_to_object_expr +| @collection_upcast_conversion_expr +| @conditional_bridge_from_obj_c_expr +| @covariant_function_conversion_expr +| @covariant_return_conversion_expr +| @derived_to_base_expr +| @destructure_tuple_expr +| @differentiable_function_expr +| @differentiable_function_extract_original_expr +| @erasure_expr +| @existential_metatype_to_object_expr +| @foreign_object_conversion_expr +| @function_conversion_expr +| @in_out_to_pointer_expr +| @inject_into_optional_expr +| @linear_function_expr +| @linear_function_extract_original_expr +| @linear_to_differentiable_function_expr +| @load_expr +| @metatype_conversion_expr +| @pointer_to_pointer_expr +| @protocol_metatype_to_object_expr +| @string_to_pointer_expr +| @underlying_to_opaque_expr +| @unevaluated_instance_expr +| @unresolved_type_conversion_expr +; + +#keyset[id] +implicit_conversion_exprs( //dir=expr + int id: @implicit_conversion_expr ref, + int sub_expr: @expr_or_none ref +); + +in_out_exprs( //dir=expr + unique int id: @in_out_expr, + int sub_expr: @expr_or_none ref +); + +key_path_application_exprs( //dir=expr + unique int id: @key_path_application_expr, + int base: @expr_or_none ref, + int key_path: @expr_or_none ref +); + +key_path_dot_exprs( //dir=expr + unique int id: @key_path_dot_expr +); + +key_path_exprs( //dir=expr + unique int id: @key_path_expr +); + +#keyset[id] +key_path_expr_roots( //dir=expr + int id: @key_path_expr ref, + int root: @type_repr_or_none ref +); + +#keyset[id] +key_path_expr_parsed_paths( //dir=expr + int id: @key_path_expr ref, + int parsed_path: @expr_or_none ref +); + +lazy_initializer_exprs( //dir=expr + unique int id: @lazy_initializer_expr, + int sub_expr: @expr_or_none ref +); + +@literal_expr = + @builtin_literal_expr +| @interpolated_string_literal_expr +| @nil_literal_expr +| @object_literal_expr +| @regex_literal_expr +; + +@lookup_expr = + @dynamic_lookup_expr +| @member_ref_expr +| @subscript_expr +; + +#keyset[id] +lookup_exprs( //dir=expr + int id: @lookup_expr ref, + int base: @expr_or_none ref +); + +#keyset[id] +lookup_expr_members( //dir=expr + int id: @lookup_expr ref, + int member: @decl_or_none ref +); + +make_temporarily_escapable_exprs( //dir=expr + unique int id: @make_temporarily_escapable_expr, + int escaping_closure: @opaque_value_expr_or_none ref, + int nonescaping_closure: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +obj_c_selector_exprs( //dir=expr + unique int id: @obj_c_selector_expr, + int sub_expr: @expr_or_none ref, + int method: @abstract_function_decl_or_none ref +); + +one_way_exprs( //dir=expr + unique int id: @one_way_expr, + int sub_expr: @expr_or_none ref +); + +opaque_value_exprs( //dir=expr + unique int id: @opaque_value_expr +); + +open_existential_exprs( //dir=expr + unique int id: @open_existential_expr, + int sub_expr: @expr_or_none ref, + int existential: @expr_or_none ref, + int opaque_expr: @opaque_value_expr_or_none ref +); + +optional_evaluation_exprs( //dir=expr + unique int id: @optional_evaluation_expr, + int sub_expr: @expr_or_none ref +); + +other_constructor_decl_ref_exprs( //dir=expr + unique int id: @other_constructor_decl_ref_expr, + int constructor_decl: @constructor_decl_or_none ref +); + +overloaded_decl_ref_exprs( //dir=expr + unique int id: @overloaded_decl_ref_expr +); + +#keyset[id, index] +overloaded_decl_ref_expr_possible_declarations( //dir=expr + int id: @overloaded_decl_ref_expr ref, + int index: int ref, + int possible_declaration: @value_decl_or_none ref +); + +property_wrapper_value_placeholder_exprs( //dir=expr + unique int id: @property_wrapper_value_placeholder_expr, + int placeholder: @opaque_value_expr_or_none ref +); + +#keyset[id] +property_wrapper_value_placeholder_expr_wrapped_values( //dir=expr + int id: @property_wrapper_value_placeholder_expr ref, + int wrapped_value: @expr_or_none ref +); + +rebind_self_in_constructor_exprs( //dir=expr + unique int id: @rebind_self_in_constructor_expr, + int sub_expr: @expr_or_none ref, + int self: @var_decl_or_none ref +); + +sequence_exprs( //dir=expr + unique int id: @sequence_expr +); + +#keyset[id, index] +sequence_expr_elements( //dir=expr + int id: @sequence_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +super_ref_exprs( //dir=expr + unique int id: @super_ref_expr, + int self: @var_decl_or_none ref +); + +tap_exprs( //dir=expr + unique int id: @tap_expr, + int body: @brace_stmt_or_none ref, + int var: @var_decl_or_none ref +); + +#keyset[id] +tap_expr_sub_exprs( //dir=expr + int id: @tap_expr ref, + int sub_expr: @expr_or_none ref +); + +tuple_element_exprs( //dir=expr + unique int id: @tuple_element_expr, + int sub_expr: @expr_or_none ref, + int index: int ref +); + +tuple_exprs( //dir=expr + unique int id: @tuple_expr +); + +#keyset[id, index] +tuple_expr_elements( //dir=expr + int id: @tuple_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +type_exprs( //dir=expr + unique int id: @type_expr +); + +#keyset[id] +type_expr_type_reprs( //dir=expr + int id: @type_expr ref, + int type_repr: @type_repr_or_none ref +); + +unresolved_decl_ref_exprs( //dir=expr + unique int id: @unresolved_decl_ref_expr +); + +#keyset[id] +unresolved_decl_ref_expr_names( //dir=expr + int id: @unresolved_decl_ref_expr ref, + string name: string ref +); + +unresolved_dot_exprs( //dir=expr + unique int id: @unresolved_dot_expr, + int base: @expr_or_none ref, + string name: string ref +); + +unresolved_member_exprs( //dir=expr + unique int id: @unresolved_member_expr, + string name: string ref +); + +unresolved_pattern_exprs( //dir=expr + unique int id: @unresolved_pattern_expr, + int sub_pattern: @pattern_or_none ref +); + +unresolved_specialize_exprs( //dir=expr + unique int id: @unresolved_specialize_expr, + int sub_expr: @expr_or_none ref +); + +vararg_expansion_exprs( //dir=expr + unique int id: @vararg_expansion_expr, + int sub_expr: @expr_or_none ref +); + +abi_safe_conversion_exprs( //dir=expr + unique int id: @abi_safe_conversion_expr +); + +any_hashable_erasure_exprs( //dir=expr + unique int id: @any_hashable_erasure_expr +); + +archetype_to_super_exprs( //dir=expr + unique int id: @archetype_to_super_expr +); + +array_exprs( //dir=expr + unique int id: @array_expr +); + +#keyset[id, index] +array_expr_elements( //dir=expr + int id: @array_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +array_to_pointer_exprs( //dir=expr + unique int id: @array_to_pointer_expr +); + +auto_closure_exprs( //dir=expr + unique int id: @auto_closure_expr +); + +await_exprs( //dir=expr + unique int id: @await_expr +); + +binary_exprs( //dir=expr + unique int id: @binary_expr +); + +bridge_from_obj_c_exprs( //dir=expr + unique int id: @bridge_from_obj_c_expr +); + +bridge_to_obj_c_exprs( //dir=expr + unique int id: @bridge_to_obj_c_expr +); + +@builtin_literal_expr = + @boolean_literal_expr +| @magic_identifier_literal_expr +| @number_literal_expr +| @string_literal_expr +; + +call_exprs( //dir=expr + unique int id: @call_expr +); + +@checked_cast_expr = + @conditional_checked_cast_expr +| @forced_checked_cast_expr +| @is_expr +; + +class_metatype_to_object_exprs( //dir=expr + unique int id: @class_metatype_to_object_expr +); + +closure_exprs( //dir=expr + unique int id: @closure_expr +); + +coerce_exprs( //dir=expr + unique int id: @coerce_expr +); + +collection_upcast_conversion_exprs( //dir=expr + unique int id: @collection_upcast_conversion_expr +); + +conditional_bridge_from_obj_c_exprs( //dir=expr + unique int id: @conditional_bridge_from_obj_c_expr +); + +covariant_function_conversion_exprs( //dir=expr + unique int id: @covariant_function_conversion_expr +); + +covariant_return_conversion_exprs( //dir=expr + unique int id: @covariant_return_conversion_expr +); + +derived_to_base_exprs( //dir=expr + unique int id: @derived_to_base_expr +); + +destructure_tuple_exprs( //dir=expr + unique int id: @destructure_tuple_expr +); + +dictionary_exprs( //dir=expr + unique int id: @dictionary_expr +); + +#keyset[id, index] +dictionary_expr_elements( //dir=expr + int id: @dictionary_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +differentiable_function_exprs( //dir=expr + unique int id: @differentiable_function_expr +); + +differentiable_function_extract_original_exprs( //dir=expr + unique int id: @differentiable_function_extract_original_expr +); + +dot_self_exprs( //dir=expr + unique int id: @dot_self_expr +); + +@dynamic_lookup_expr = + @dynamic_member_ref_expr +| @dynamic_subscript_expr +; + +erasure_exprs( //dir=expr + unique int id: @erasure_expr +); + +existential_metatype_to_object_exprs( //dir=expr + unique int id: @existential_metatype_to_object_expr +); + +force_try_exprs( //dir=expr + unique int id: @force_try_expr +); + +foreign_object_conversion_exprs( //dir=expr + unique int id: @foreign_object_conversion_expr +); + +function_conversion_exprs( //dir=expr + unique int id: @function_conversion_expr +); + +in_out_to_pointer_exprs( //dir=expr + unique int id: @in_out_to_pointer_expr +); + +inject_into_optional_exprs( //dir=expr + unique int id: @inject_into_optional_expr +); + +interpolated_string_literal_exprs( //dir=expr + unique int id: @interpolated_string_literal_expr +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_expr: @opaque_value_expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_count_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_count_expr: @expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_literal_capacity_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int literal_capacity_expr: @expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_appending_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int appending_expr: @tap_expr_or_none ref +); + +linear_function_exprs( //dir=expr + unique int id: @linear_function_expr +); + +linear_function_extract_original_exprs( //dir=expr + unique int id: @linear_function_extract_original_expr +); + +linear_to_differentiable_function_exprs( //dir=expr + unique int id: @linear_to_differentiable_function_expr +); + +load_exprs( //dir=expr + unique int id: @load_expr +); + +member_ref_exprs( //dir=expr + unique int id: @member_ref_expr +); + +#keyset[id] +member_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_ordinary_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_distributed_thunk_semantics( //dir=expr + int id: @member_ref_expr ref +); + +metatype_conversion_exprs( //dir=expr + unique int id: @metatype_conversion_expr +); + +nil_literal_exprs( //dir=expr + unique int id: @nil_literal_expr +); + +object_literal_exprs( //dir=expr + unique int id: @object_literal_expr, + int kind: int ref +); + +#keyset[id, index] +object_literal_expr_arguments( //dir=expr + int id: @object_literal_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +optional_try_exprs( //dir=expr + unique int id: @optional_try_expr +); + +paren_exprs( //dir=expr + unique int id: @paren_expr +); + +pointer_to_pointer_exprs( //dir=expr + unique int id: @pointer_to_pointer_expr +); + +postfix_unary_exprs( //dir=expr + unique int id: @postfix_unary_expr +); + +prefix_unary_exprs( //dir=expr + unique int id: @prefix_unary_expr +); + +protocol_metatype_to_object_exprs( //dir=expr + unique int id: @protocol_metatype_to_object_expr +); + +regex_literal_exprs( //dir=expr + unique int id: @regex_literal_expr, + string pattern: string ref, + int version: int ref +); + +@self_apply_expr = + @constructor_ref_call_expr +| @dot_syntax_call_expr +; + +#keyset[id] +self_apply_exprs( //dir=expr + int id: @self_apply_expr ref, + int base: @expr_or_none ref +); + +string_to_pointer_exprs( //dir=expr + unique int id: @string_to_pointer_expr +); + +subscript_exprs( //dir=expr + unique int id: @subscript_expr +); + +#keyset[id, index] +subscript_expr_arguments( //dir=expr + int id: @subscript_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +#keyset[id] +subscript_expr_has_direct_to_storage_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_ordinary_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_distributed_thunk_semantics( //dir=expr + int id: @subscript_expr ref +); + +try_exprs( //dir=expr + unique int id: @try_expr +); + +underlying_to_opaque_exprs( //dir=expr + unique int id: @underlying_to_opaque_expr +); + +unevaluated_instance_exprs( //dir=expr + unique int id: @unevaluated_instance_expr +); + +unresolved_member_chain_result_exprs( //dir=expr + unique int id: @unresolved_member_chain_result_expr +); + +unresolved_type_conversion_exprs( //dir=expr + unique int id: @unresolved_type_conversion_expr +); + +boolean_literal_exprs( //dir=expr + unique int id: @boolean_literal_expr, + boolean value: boolean ref +); + +conditional_checked_cast_exprs( //dir=expr + unique int id: @conditional_checked_cast_expr +); + +constructor_ref_call_exprs( //dir=expr + unique int id: @constructor_ref_call_expr +); + +dot_syntax_call_exprs( //dir=expr + unique int id: @dot_syntax_call_expr +); + +dynamic_member_ref_exprs( //dir=expr + unique int id: @dynamic_member_ref_expr +); + +dynamic_subscript_exprs( //dir=expr + unique int id: @dynamic_subscript_expr +); + +forced_checked_cast_exprs( //dir=expr + unique int id: @forced_checked_cast_expr +); + +is_exprs( //dir=expr + unique int id: @is_expr +); + +magic_identifier_literal_exprs( //dir=expr + unique int id: @magic_identifier_literal_expr, + string kind: string ref +); + +@number_literal_expr = + @float_literal_expr +| @integer_literal_expr +; + +string_literal_exprs( //dir=expr + unique int id: @string_literal_expr, + string value: string ref +); + +float_literal_exprs( //dir=expr + unique int id: @float_literal_expr, + string string_value: string ref +); + +integer_literal_exprs( //dir=expr + unique int id: @integer_literal_expr, + string string_value: string ref +); + +@pattern = + @any_pattern +| @binding_pattern +| @bool_pattern +| @enum_element_pattern +| @expr_pattern +| @is_pattern +| @named_pattern +| @optional_some_pattern +| @paren_pattern +| @tuple_pattern +| @typed_pattern +; + +any_patterns( //dir=pattern + unique int id: @any_pattern +); + +binding_patterns( //dir=pattern + unique int id: @binding_pattern, + int sub_pattern: @pattern_or_none ref +); + +bool_patterns( //dir=pattern + unique int id: @bool_pattern, + boolean value: boolean ref +); + +enum_element_patterns( //dir=pattern + unique int id: @enum_element_pattern, + int element: @enum_element_decl_or_none ref +); + +#keyset[id] +enum_element_pattern_sub_patterns( //dir=pattern + int id: @enum_element_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +expr_patterns( //dir=pattern + unique int id: @expr_pattern, + int sub_expr: @expr_or_none ref +); + +is_patterns( //dir=pattern + unique int id: @is_pattern +); + +#keyset[id] +is_pattern_cast_type_reprs( //dir=pattern + int id: @is_pattern ref, + int cast_type_repr: @type_repr_or_none ref +); + +#keyset[id] +is_pattern_sub_patterns( //dir=pattern + int id: @is_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +named_patterns( //dir=pattern + unique int id: @named_pattern, + string name: string ref +); + +optional_some_patterns( //dir=pattern + unique int id: @optional_some_pattern, + int sub_pattern: @pattern_or_none ref +); + +paren_patterns( //dir=pattern + unique int id: @paren_pattern, + int sub_pattern: @pattern_or_none ref +); + +tuple_patterns( //dir=pattern + unique int id: @tuple_pattern +); + +#keyset[id, index] +tuple_pattern_elements( //dir=pattern + int id: @tuple_pattern ref, + int index: int ref, + int element: @pattern_or_none ref +); + +typed_patterns( //dir=pattern + unique int id: @typed_pattern, + int sub_pattern: @pattern_or_none ref +); + +#keyset[id] +typed_pattern_type_reprs( //dir=pattern + int id: @typed_pattern ref, + int type_repr: @type_repr_or_none ref +); + +case_label_items( //dir=stmt + unique int id: @case_label_item, + int pattern: @pattern_or_none ref +); + +#keyset[id] +case_label_item_guards( //dir=stmt + int id: @case_label_item ref, + int guard: @expr_or_none ref +); + +condition_elements( //dir=stmt + unique int id: @condition_element +); + +#keyset[id] +condition_element_booleans( //dir=stmt + int id: @condition_element ref, + int boolean_: @expr_or_none ref +); + +#keyset[id] +condition_element_patterns( //dir=stmt + int id: @condition_element ref, + int pattern: @pattern_or_none ref +); + +#keyset[id] +condition_element_initializers( //dir=stmt + int id: @condition_element ref, + int initializer: @expr_or_none ref +); + +#keyset[id] +condition_element_availabilities( //dir=stmt + int id: @condition_element ref, + int availability: @availability_info_or_none ref +); + +@stmt = + @brace_stmt +| @break_stmt +| @case_stmt +| @continue_stmt +| @defer_stmt +| @fail_stmt +| @fallthrough_stmt +| @labeled_stmt +| @pound_assert_stmt +| @return_stmt +| @throw_stmt +| @yield_stmt +; + +stmt_conditions( //dir=stmt + unique int id: @stmt_condition +); + +#keyset[id, index] +stmt_condition_elements( //dir=stmt + int id: @stmt_condition ref, + int index: int ref, + int element: @condition_element_or_none ref +); + +brace_stmts( //dir=stmt + unique int id: @brace_stmt +); + +#keyset[id, index] +brace_stmt_elements( //dir=stmt + int id: @brace_stmt ref, + int index: int ref, + int element: @ast_node_or_none ref +); + +break_stmts( //dir=stmt + unique int id: @break_stmt +); + +#keyset[id] +break_stmt_target_names( //dir=stmt + int id: @break_stmt ref, + string target_name: string ref +); + +#keyset[id] +break_stmt_targets( //dir=stmt + int id: @break_stmt ref, + int target: @stmt_or_none ref +); + +case_stmts( //dir=stmt + unique int id: @case_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +case_stmt_labels( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int label: @case_label_item_or_none ref +); + +#keyset[id, index] +case_stmt_variables( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int variable: @var_decl_or_none ref +); + +continue_stmts( //dir=stmt + unique int id: @continue_stmt +); + +#keyset[id] +continue_stmt_target_names( //dir=stmt + int id: @continue_stmt ref, + string target_name: string ref +); + +#keyset[id] +continue_stmt_targets( //dir=stmt + int id: @continue_stmt ref, + int target: @stmt_or_none ref +); + +defer_stmts( //dir=stmt + unique int id: @defer_stmt, + int body: @brace_stmt_or_none ref +); + +fail_stmts( //dir=stmt + unique int id: @fail_stmt +); + +fallthrough_stmts( //dir=stmt + unique int id: @fallthrough_stmt, + int fallthrough_source: @case_stmt_or_none ref, + int fallthrough_dest: @case_stmt_or_none ref +); + +@labeled_stmt = + @do_catch_stmt +| @do_stmt +| @for_each_stmt +| @labeled_conditional_stmt +| @repeat_while_stmt +| @switch_stmt +; + +#keyset[id] +labeled_stmt_labels( //dir=stmt + int id: @labeled_stmt ref, + string label: string ref +); + +pound_assert_stmts( //dir=stmt + unique int id: @pound_assert_stmt, + int condition: @expr_or_none ref, + string message: string ref +); + +return_stmts( //dir=stmt + unique int id: @return_stmt +); + +#keyset[id] +return_stmt_results( //dir=stmt + int id: @return_stmt ref, + int result: @expr_or_none ref +); + +throw_stmts( //dir=stmt + unique int id: @throw_stmt, + int sub_expr: @expr_or_none ref +); + +yield_stmts( //dir=stmt + unique int id: @yield_stmt +); + +#keyset[id, index] +yield_stmt_results( //dir=stmt + int id: @yield_stmt ref, + int index: int ref, + int result: @expr_or_none ref +); + +do_catch_stmts( //dir=stmt + unique int id: @do_catch_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +do_catch_stmt_catches( //dir=stmt + int id: @do_catch_stmt ref, + int index: int ref, + int catch: @case_stmt_or_none ref +); + +do_stmts( //dir=stmt + unique int id: @do_stmt, + int body: @brace_stmt_or_none ref +); + +for_each_stmts( //dir=stmt + unique int id: @for_each_stmt, + int pattern: @pattern_or_none ref, + int sequence: @expr_or_none ref, + int body: @brace_stmt_or_none ref +); + +#keyset[id] +for_each_stmt_wheres( //dir=stmt + int id: @for_each_stmt ref, + int where: @expr_or_none ref +); + +@labeled_conditional_stmt = + @guard_stmt +| @if_stmt +| @while_stmt +; + +#keyset[id] +labeled_conditional_stmts( //dir=stmt + int id: @labeled_conditional_stmt ref, + int condition: @stmt_condition_or_none ref +); + +repeat_while_stmts( //dir=stmt + unique int id: @repeat_while_stmt, + int condition: @expr_or_none ref, + int body: @stmt_or_none ref +); + +switch_stmts( //dir=stmt + unique int id: @switch_stmt, + int expr: @expr_or_none ref +); + +#keyset[id, index] +switch_stmt_cases( //dir=stmt + int id: @switch_stmt ref, + int index: int ref, + int case_: @case_stmt_or_none ref +); + +guard_stmts( //dir=stmt + unique int id: @guard_stmt, + int body: @brace_stmt_or_none ref +); + +if_stmts( //dir=stmt + unique int id: @if_stmt, + int then: @stmt_or_none ref +); + +#keyset[id] +if_stmt_elses( //dir=stmt + int id: @if_stmt ref, + int else: @stmt_or_none ref +); + +while_stmts( //dir=stmt + unique int id: @while_stmt, + int body: @stmt_or_none ref +); + +@type = + @any_function_type +| @any_generic_type +| @any_metatype_type +| @builtin_type +| @dependent_member_type +| @dynamic_self_type +| @error_type +| @existential_type +| @in_out_type +| @l_value_type +| @module_type +| @parameterized_protocol_type +| @protocol_composition_type +| @reference_storage_type +| @substitutable_type +| @sugar_type +| @tuple_type +| @unresolved_type +; + +#keyset[id] +types( //dir=type + int id: @type ref, + string name: string ref, + int canonical_type: @type_or_none ref +); + +type_reprs( //dir=type + unique int id: @type_repr, + int type_: @type_or_none ref +); + +@any_function_type = + @function_type +| @generic_function_type +; + +#keyset[id] +any_function_types( //dir=type + int id: @any_function_type ref, + int result: @type_or_none ref +); + +#keyset[id, index] +any_function_type_param_types( //dir=type + int id: @any_function_type ref, + int index: int ref, + int param_type: @type_or_none ref +); + +#keyset[id] +any_function_type_is_throwing( //dir=type + int id: @any_function_type ref +); + +#keyset[id] +any_function_type_is_async( //dir=type + int id: @any_function_type ref +); + +@any_generic_type = + @nominal_or_bound_generic_nominal_type +| @unbound_generic_type +; + +#keyset[id] +any_generic_types( //dir=type + int id: @any_generic_type ref, + int declaration: @generic_type_decl_or_none ref +); + +#keyset[id] +any_generic_type_parents( //dir=type + int id: @any_generic_type ref, + int parent: @type_or_none ref +); + +@any_metatype_type = + @existential_metatype_type +| @metatype_type +; + +@builtin_type = + @any_builtin_integer_type +| @builtin_bridge_object_type +| @builtin_default_actor_storage_type +| @builtin_executor_type +| @builtin_float_type +| @builtin_job_type +| @builtin_native_object_type +| @builtin_raw_pointer_type +| @builtin_raw_unsafe_continuation_type +| @builtin_unsafe_value_buffer_type +| @builtin_vector_type +; + +dependent_member_types( //dir=type + unique int id: @dependent_member_type, + int base_type: @type_or_none ref, + int associated_type_decl: @associated_type_decl_or_none ref +); + +dynamic_self_types( //dir=type + unique int id: @dynamic_self_type, + int static_self_type: @type_or_none ref +); + +error_types( //dir=type + unique int id: @error_type +); + +existential_types( //dir=type + unique int id: @existential_type, + int constraint: @type_or_none ref +); + +in_out_types( //dir=type + unique int id: @in_out_type, + int object_type: @type_or_none ref +); + +l_value_types( //dir=type + unique int id: @l_value_type, + int object_type: @type_or_none ref +); + +module_types( //dir=type + unique int id: @module_type, + int module: @module_decl_or_none ref +); + +parameterized_protocol_types( //dir=type + unique int id: @parameterized_protocol_type, + int base: @protocol_type_or_none ref +); + +#keyset[id, index] +parameterized_protocol_type_args( //dir=type + int id: @parameterized_protocol_type ref, + int index: int ref, + int arg: @type_or_none ref +); + +protocol_composition_types( //dir=type + unique int id: @protocol_composition_type +); + +#keyset[id, index] +protocol_composition_type_members( //dir=type + int id: @protocol_composition_type ref, + int index: int ref, + int member: @type_or_none ref +); + +@reference_storage_type = + @unmanaged_storage_type +| @unowned_storage_type +| @weak_storage_type +; + +#keyset[id] +reference_storage_types( //dir=type + int id: @reference_storage_type ref, + int referent_type: @type_or_none ref +); + +@substitutable_type = + @archetype_type +| @generic_type_param_type +; + +@sugar_type = + @paren_type +| @syntax_sugar_type +| @type_alias_type +; + +tuple_types( //dir=type + unique int id: @tuple_type +); + +#keyset[id, index] +tuple_type_types( //dir=type + int id: @tuple_type ref, + int index: int ref, + int type_: @type_or_none ref +); + +#keyset[id, index] +tuple_type_names( //dir=type + int id: @tuple_type ref, + int index: int ref, + string name: string ref +); + +unresolved_types( //dir=type + unique int id: @unresolved_type +); + +@any_builtin_integer_type = + @builtin_integer_literal_type +| @builtin_integer_type +; + +@archetype_type = + @opaque_type_archetype_type +| @opened_archetype_type +| @primary_archetype_type +; + +#keyset[id] +archetype_types( //dir=type + int id: @archetype_type ref, + int interface_type: @type_or_none ref +); + +#keyset[id] +archetype_type_superclasses( //dir=type + int id: @archetype_type ref, + int superclass: @type_or_none ref +); + +#keyset[id, index] +archetype_type_protocols( //dir=type + int id: @archetype_type ref, + int index: int ref, + int protocol: @protocol_decl_or_none ref +); + +builtin_bridge_object_types( //dir=type + unique int id: @builtin_bridge_object_type +); + +builtin_default_actor_storage_types( //dir=type + unique int id: @builtin_default_actor_storage_type +); + +builtin_executor_types( //dir=type + unique int id: @builtin_executor_type +); + +builtin_float_types( //dir=type + unique int id: @builtin_float_type +); + +builtin_job_types( //dir=type + unique int id: @builtin_job_type +); + +builtin_native_object_types( //dir=type + unique int id: @builtin_native_object_type +); + +builtin_raw_pointer_types( //dir=type + unique int id: @builtin_raw_pointer_type +); + +builtin_raw_unsafe_continuation_types( //dir=type + unique int id: @builtin_raw_unsafe_continuation_type +); + +builtin_unsafe_value_buffer_types( //dir=type + unique int id: @builtin_unsafe_value_buffer_type +); + +builtin_vector_types( //dir=type + unique int id: @builtin_vector_type +); + +existential_metatype_types( //dir=type + unique int id: @existential_metatype_type +); + +function_types( //dir=type + unique int id: @function_type +); + +generic_function_types( //dir=type + unique int id: @generic_function_type +); + +#keyset[id, index] +generic_function_type_generic_params( //dir=type + int id: @generic_function_type ref, + int index: int ref, + int generic_param: @generic_type_param_type_or_none ref +); + +generic_type_param_types( //dir=type + unique int id: @generic_type_param_type +); + +metatype_types( //dir=type + unique int id: @metatype_type +); + +@nominal_or_bound_generic_nominal_type = + @bound_generic_type +| @nominal_type +; + +paren_types( //dir=type + unique int id: @paren_type, + int type_: @type_or_none ref +); + +@syntax_sugar_type = + @dictionary_type +| @unary_syntax_sugar_type +; + +type_alias_types( //dir=type + unique int id: @type_alias_type, + int decl: @type_alias_decl_or_none ref +); + +unbound_generic_types( //dir=type + unique int id: @unbound_generic_type +); + +unmanaged_storage_types( //dir=type + unique int id: @unmanaged_storage_type +); + +unowned_storage_types( //dir=type + unique int id: @unowned_storage_type +); + +weak_storage_types( //dir=type + unique int id: @weak_storage_type +); + +@bound_generic_type = + @bound_generic_class_type +| @bound_generic_enum_type +| @bound_generic_struct_type +; + +#keyset[id, index] +bound_generic_type_arg_types( //dir=type + int id: @bound_generic_type ref, + int index: int ref, + int arg_type: @type_or_none ref +); + +builtin_integer_literal_types( //dir=type + unique int id: @builtin_integer_literal_type +); + +builtin_integer_types( //dir=type + unique int id: @builtin_integer_type +); + +#keyset[id] +builtin_integer_type_widths( //dir=type + int id: @builtin_integer_type ref, + int width: int ref +); + +dictionary_types( //dir=type + unique int id: @dictionary_type, + int key_type: @type_or_none ref, + int value_type: @type_or_none ref +); + +@nominal_type = + @class_type +| @enum_type +| @protocol_type +| @struct_type +; + +opaque_type_archetype_types( //dir=type + unique int id: @opaque_type_archetype_type, + int declaration: @opaque_type_decl_or_none ref +); + +opened_archetype_types( //dir=type + unique int id: @opened_archetype_type +); + +primary_archetype_types( //dir=type + unique int id: @primary_archetype_type +); + +@unary_syntax_sugar_type = + @array_slice_type +| @optional_type +| @variadic_sequence_type +; + +#keyset[id] +unary_syntax_sugar_types( //dir=type + int id: @unary_syntax_sugar_type ref, + int base_type: @type_or_none ref +); + +array_slice_types( //dir=type + unique int id: @array_slice_type +); + +bound_generic_class_types( //dir=type + unique int id: @bound_generic_class_type +); + +bound_generic_enum_types( //dir=type + unique int id: @bound_generic_enum_type +); + +bound_generic_struct_types( //dir=type + unique int id: @bound_generic_struct_type +); + +class_types( //dir=type + unique int id: @class_type +); + +enum_types( //dir=type + unique int id: @enum_type +); + +optional_types( //dir=type + unique int id: @optional_type +); + +protocol_types( //dir=type + unique int id: @protocol_type +); + +struct_types( //dir=type + unique int id: @struct_type +); + +variadic_sequence_types( //dir=type + unique int id: @variadic_sequence_type +); + +@abstract_function_decl_or_none = + @abstract_function_decl +| @unspecified_element +; + +@accessor_decl_or_none = + @accessor_decl +| @unspecified_element +; + +@argument_or_none = + @argument +| @unspecified_element +; + +@associated_type_decl_or_none = + @associated_type_decl +| @unspecified_element +; + +@ast_node_or_none = + @ast_node +| @unspecified_element +; + +@availability_info_or_none = + @availability_info +| @unspecified_element +; + +@availability_spec_or_none = + @availability_spec +| @unspecified_element +; + +@brace_stmt_or_none = + @brace_stmt +| @unspecified_element +; + +@captured_decl_or_none = + @captured_decl +| @unspecified_element +; + +@case_label_item_or_none = + @case_label_item +| @unspecified_element +; + +@case_stmt_or_none = + @case_stmt +| @unspecified_element +; + +@closure_expr_or_none = + @closure_expr +| @unspecified_element +; + +@condition_element_or_none = + @condition_element +| @unspecified_element +; + +@constructor_decl_or_none = + @constructor_decl +| @unspecified_element +; + +@decl_or_none = + @decl +| @unspecified_element +; + +@enum_element_decl_or_none = + @enum_element_decl +| @unspecified_element +; + +@expr_or_none = + @expr +| @unspecified_element +; + +@file_or_none = + @file +| @unspecified_element +; + +@generic_type_decl_or_none = + @generic_type_decl +| @unspecified_element +; + +@generic_type_param_decl_or_none = + @generic_type_param_decl +| @unspecified_element +; + +@generic_type_param_type_or_none = + @generic_type_param_type +| @unspecified_element +; + +@location_or_none = + @location +| @unspecified_element +; + +@module_decl_or_none = + @module_decl +| @unspecified_element +; + +@nominal_type_decl_or_none = + @nominal_type_decl +| @unspecified_element +; + +@opaque_type_decl_or_none = + @opaque_type_decl +| @unspecified_element +; + +@opaque_value_expr_or_none = + @opaque_value_expr +| @unspecified_element +; + +@param_decl_or_none = + @param_decl +| @unspecified_element +; + +@pattern_or_none = + @pattern +| @unspecified_element +; + +@pattern_binding_decl_or_none = + @pattern_binding_decl +| @unspecified_element +; + +@precedence_group_decl_or_none = + @precedence_group_decl +| @unspecified_element +; + +@protocol_decl_or_none = + @protocol_decl +| @unspecified_element +; + +@protocol_type_or_none = + @protocol_type +| @unspecified_element +; + +@stmt_or_none = + @stmt +| @unspecified_element +; + +@stmt_condition_or_none = + @stmt_condition +| @unspecified_element +; + +@string_literal_expr_or_none = + @string_literal_expr +| @unspecified_element +; + +@tap_expr_or_none = + @tap_expr +| @unspecified_element +; + +@type_or_none = + @type +| @unspecified_element +; + +@type_alias_decl_or_none = + @type_alias_decl +| @unspecified_element +; + +@type_repr_or_none = + @type_repr +| @unspecified_element +; + +@value_decl_or_none = + @unspecified_element +| @value_decl +; + +@var_decl_or_none = + @unspecified_element +| @var_decl +; diff --git a/swift/ql/lib/upgrades/e646f9e0308ec7135c83c0fdf96896d2737a8013/swift.dbscheme b/swift/ql/lib/upgrades/e646f9e0308ec7135c83c0fdf96896d2737a8013/swift.dbscheme new file mode 100644 index 00000000000..e457bc35325 --- /dev/null +++ b/swift/ql/lib/upgrades/e646f9e0308ec7135c83c0fdf96896d2737a8013/swift.dbscheme @@ -0,0 +1,2598 @@ +// generated by codegen/codegen.py + +// from prefix.dbscheme +/** + * The source location of the snapshot. + */ +sourceLocationPrefix( + string prefix: string ref +); + + +// from schema.py + +@element = + @callable +| @file +| @generic_context +| @locatable +| @location +| @type +; + +#keyset[id] +element_is_unknown( + int id: @element ref +); + +@callable = + @abstract_closure_expr +| @abstract_function_decl +; + +#keyset[id] +callable_names( + int id: @callable ref, + string name: string ref +); + +#keyset[id] +callable_self_params( + int id: @callable ref, + int self_param: @param_decl_or_none ref +); + +#keyset[id, index] +callable_params( + int id: @callable ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +#keyset[id] +callable_bodies( + int id: @callable ref, + int body: @brace_stmt_or_none ref +); + +#keyset[id, index] +callable_captures( + int id: @callable ref, + int index: int ref, + int capture: @captured_decl_or_none ref +); + +@file = + @db_file +; + +#keyset[id] +files( + int id: @file ref, + string name: string ref +); + +#keyset[id] +file_is_successfully_extracted( + int id: @file ref +); + +@locatable = + @argument +| @ast_node +| @comment +| @diagnostics +| @error_element +; + +#keyset[id] +locatable_locations( + int id: @locatable ref, + int location: @location_or_none ref +); + +@location = + @db_location +; + +#keyset[id] +locations( + int id: @location ref, + int file: @file_or_none ref, + int start_line: int ref, + int start_column: int ref, + int end_line: int ref, + int end_column: int ref +); + +@ast_node = + @availability_info +| @availability_spec +| @case_label_item +| @condition_element +| @decl +| @expr +| @pattern +| @stmt +| @stmt_condition +| @type_repr +; + +comments( + unique int id: @comment, + string text: string ref +); + +db_files( + unique int id: @db_file +); + +db_locations( + unique int id: @db_location +); + +diagnostics( + unique int id: @diagnostics, + string text: string ref, + int kind: int ref +); + +@error_element = + @error_expr +| @error_type +| @overloaded_decl_ref_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_chain_result_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @unresolved_type +| @unresolved_type_conversion_expr +| @unspecified_element +; + +availability_infos( + unique int id: @availability_info +); + +#keyset[id] +availability_info_is_unavailable( + int id: @availability_info ref +); + +#keyset[id, index] +availability_info_specs( + int id: @availability_info ref, + int index: int ref, + int spec: @availability_spec_or_none ref +); + +@availability_spec = + @other_availability_spec +| @platform_version_availability_spec +; + +unspecified_elements( + unique int id: @unspecified_element, + string property: string ref, + string error: string ref +); + +#keyset[id] +unspecified_element_parents( + int id: @unspecified_element ref, + int parent: @element ref +); + +#keyset[id] +unspecified_element_indices( + int id: @unspecified_element ref, + int index: int ref +); + +other_availability_specs( + unique int id: @other_availability_spec +); + +platform_version_availability_specs( + unique int id: @platform_version_availability_spec, + string platform: string ref, + string version: string ref +); + +@decl = + @captured_decl +| @enum_case_decl +| @extension_decl +| @if_config_decl +| @import_decl +| @missing_member_decl +| @operator_decl +| @pattern_binding_decl +| @pound_diagnostic_decl +| @precedence_group_decl +| @top_level_code_decl +| @value_decl +; + +#keyset[id] +decls( //dir=decl + int id: @decl ref, + int module: @module_decl_or_none ref +); + +#keyset[id, index] +decl_members( //dir=decl + int id: @decl ref, + int index: int ref, + int member: @decl_or_none ref +); + +@generic_context = + @abstract_function_decl +| @extension_decl +| @generic_type_decl +| @subscript_decl +; + +#keyset[id, index] +generic_context_generic_type_params( //dir=decl + int id: @generic_context ref, + int index: int ref, + int generic_type_param: @generic_type_param_decl_or_none ref +); + +captured_decls( //dir=decl + unique int id: @captured_decl, + int decl: @value_decl_or_none ref +); + +#keyset[id] +captured_decl_is_direct( //dir=decl + int id: @captured_decl ref +); + +#keyset[id] +captured_decl_is_escaping( //dir=decl + int id: @captured_decl ref +); + +enum_case_decls( //dir=decl + unique int id: @enum_case_decl +); + +#keyset[id, index] +enum_case_decl_elements( //dir=decl + int id: @enum_case_decl ref, + int index: int ref, + int element: @enum_element_decl_or_none ref +); + +extension_decls( //dir=decl + unique int id: @extension_decl, + int extended_type_decl: @nominal_type_decl_or_none ref +); + +#keyset[id, index] +extension_decl_protocols( //dir=decl + int id: @extension_decl ref, + int index: int ref, + int protocol: @protocol_decl_or_none ref +); + +if_config_decls( //dir=decl + unique int id: @if_config_decl +); + +#keyset[id, index] +if_config_decl_active_elements( //dir=decl + int id: @if_config_decl ref, + int index: int ref, + int active_element: @ast_node_or_none ref +); + +import_decls( //dir=decl + unique int id: @import_decl +); + +#keyset[id] +import_decl_is_exported( //dir=decl + int id: @import_decl ref +); + +#keyset[id] +import_decl_imported_modules( //dir=decl + int id: @import_decl ref, + int imported_module: @module_decl_or_none ref +); + +#keyset[id, index] +import_decl_declarations( //dir=decl + int id: @import_decl ref, + int index: int ref, + int declaration: @value_decl_or_none ref +); + +missing_member_decls( //dir=decl + unique int id: @missing_member_decl, + string name: string ref +); + +@operator_decl = + @infix_operator_decl +| @postfix_operator_decl +| @prefix_operator_decl +; + +#keyset[id] +operator_decls( //dir=decl + int id: @operator_decl ref, + string name: string ref +); + +pattern_binding_decls( //dir=decl + unique int id: @pattern_binding_decl +); + +#keyset[id, index] +pattern_binding_decl_inits( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int init: @expr_or_none ref +); + +#keyset[id, index] +pattern_binding_decl_patterns( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int pattern: @pattern_or_none ref +); + +pound_diagnostic_decls( //dir=decl + unique int id: @pound_diagnostic_decl, + int kind: int ref, + int message: @string_literal_expr_or_none ref +); + +precedence_group_decls( //dir=decl + unique int id: @precedence_group_decl +); + +top_level_code_decls( //dir=decl + unique int id: @top_level_code_decl, + int body: @brace_stmt_or_none ref +); + +@value_decl = + @abstract_function_decl +| @abstract_storage_decl +| @enum_element_decl +| @type_decl +; + +#keyset[id] +value_decls( //dir=decl + int id: @value_decl ref, + int interface_type: @type_or_none ref +); + +@abstract_function_decl = + @constructor_decl +| @destructor_decl +| @func_decl +; + +@abstract_storage_decl = + @subscript_decl +| @var_decl +; + +#keyset[id, index] +abstract_storage_decl_accessor_decls( //dir=decl + int id: @abstract_storage_decl ref, + int index: int ref, + int accessor_decl: @accessor_decl_or_none ref +); + +enum_element_decls( //dir=decl + unique int id: @enum_element_decl, + string name: string ref +); + +#keyset[id, index] +enum_element_decl_params( //dir=decl + int id: @enum_element_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +infix_operator_decls( //dir=decl + unique int id: @infix_operator_decl +); + +#keyset[id] +infix_operator_decl_precedence_groups( //dir=decl + int id: @infix_operator_decl ref, + int precedence_group: @precedence_group_decl_or_none ref +); + +postfix_operator_decls( //dir=decl + unique int id: @postfix_operator_decl +); + +prefix_operator_decls( //dir=decl + unique int id: @prefix_operator_decl +); + +@type_decl = + @abstract_type_param_decl +| @generic_type_decl +| @module_decl +; + +#keyset[id] +type_decls( //dir=decl + int id: @type_decl ref, + string name: string ref +); + +#keyset[id, index] +type_decl_base_types( //dir=decl + int id: @type_decl ref, + int index: int ref, + int base_type: @type_or_none ref +); + +@abstract_type_param_decl = + @associated_type_decl +| @generic_type_param_decl +; + +constructor_decls( //dir=decl + unique int id: @constructor_decl +); + +destructor_decls( //dir=decl + unique int id: @destructor_decl +); + +@func_decl = + @accessor_decl +| @concrete_func_decl +; + +@generic_type_decl = + @nominal_type_decl +| @opaque_type_decl +| @type_alias_decl +; + +module_decls( //dir=decl + unique int id: @module_decl +); + +#keyset[id] +module_decl_is_builtin_module( //dir=decl + int id: @module_decl ref +); + +#keyset[id] +module_decl_is_system_module( //dir=decl + int id: @module_decl ref +); + +module_decl_imported_modules( //dir=decl + int id: @module_decl ref, + int imported_module: @module_decl_or_none ref +); + +module_decl_exported_modules( //dir=decl + int id: @module_decl ref, + int exported_module: @module_decl_or_none ref +); + +subscript_decls( //dir=decl + unique int id: @subscript_decl, + int element_type: @type_or_none ref +); + +#keyset[id, index] +subscript_decl_params( //dir=decl + int id: @subscript_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +@var_decl = + @concrete_var_decl +| @param_decl +; + +#keyset[id] +var_decls( //dir=decl + int id: @var_decl ref, + string name: string ref, + int type_: @type_or_none ref +); + +#keyset[id] +var_decl_attached_property_wrapper_types( //dir=decl + int id: @var_decl ref, + int attached_property_wrapper_type: @type_or_none ref +); + +#keyset[id] +var_decl_parent_patterns( //dir=decl + int id: @var_decl ref, + int parent_pattern: @pattern_or_none ref +); + +#keyset[id] +var_decl_parent_initializers( //dir=decl + int id: @var_decl ref, + int parent_initializer: @expr_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var: @var_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var: @var_decl_or_none ref +); + +accessor_decls( //dir=decl + unique int id: @accessor_decl +); + +#keyset[id] +accessor_decl_is_getter( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_setter( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_will_set( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_did_set( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_read( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_modify( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_unsafe_address( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_unsafe_mutable_address( //dir=decl + int id: @accessor_decl ref +); + +associated_type_decls( //dir=decl + unique int id: @associated_type_decl +); + +concrete_func_decls( //dir=decl + unique int id: @concrete_func_decl +); + +concrete_var_decls( //dir=decl + unique int id: @concrete_var_decl, + int introducer_int: int ref +); + +generic_type_param_decls( //dir=decl + unique int id: @generic_type_param_decl +); + +@nominal_type_decl = + @class_decl +| @enum_decl +| @protocol_decl +| @struct_decl +; + +#keyset[id] +nominal_type_decls( //dir=decl + int id: @nominal_type_decl ref, + int type_: @type_or_none ref +); + +opaque_type_decls( //dir=decl + unique int id: @opaque_type_decl, + int naming_declaration: @value_decl_or_none ref +); + +#keyset[id, index] +opaque_type_decl_opaque_generic_params( //dir=decl + int id: @opaque_type_decl ref, + int index: int ref, + int opaque_generic_param: @generic_type_param_type_or_none ref +); + +param_decls( //dir=decl + unique int id: @param_decl +); + +#keyset[id] +param_decl_is_inout( //dir=decl + int id: @param_decl ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_var_bindings( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_vars( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var: @var_decl_or_none ref +); + +type_alias_decls( //dir=decl + unique int id: @type_alias_decl, + int aliased_type: @type_or_none ref +); + +class_decls( //dir=decl + unique int id: @class_decl +); + +enum_decls( //dir=decl + unique int id: @enum_decl +); + +protocol_decls( //dir=decl + unique int id: @protocol_decl +); + +struct_decls( //dir=decl + unique int id: @struct_decl +); + +arguments( //dir=expr + unique int id: @argument, + string label: string ref, + int expr: @expr_or_none ref +); + +@expr = + @abstract_closure_expr +| @any_try_expr +| @applied_property_wrapper_expr +| @apply_expr +| @assign_expr +| @bind_optional_expr +| @capture_list_expr +| @collection_expr +| @decl_ref_expr +| @default_argument_expr +| @discard_assignment_expr +| @dot_syntax_base_ignored_expr +| @dynamic_type_expr +| @enum_is_case_expr +| @error_expr +| @explicit_cast_expr +| @force_value_expr +| @identity_expr +| @if_expr +| @implicit_conversion_expr +| @in_out_expr +| @key_path_application_expr +| @key_path_dot_expr +| @key_path_expr +| @lazy_initializer_expr +| @literal_expr +| @lookup_expr +| @make_temporarily_escapable_expr +| @obj_c_selector_expr +| @one_way_expr +| @opaque_value_expr +| @open_existential_expr +| @optional_evaluation_expr +| @other_constructor_decl_ref_expr +| @overloaded_decl_ref_expr +| @property_wrapper_value_placeholder_expr +| @rebind_self_in_constructor_expr +| @sequence_expr +| @super_ref_expr +| @tap_expr +| @tuple_element_expr +| @tuple_expr +| @type_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @vararg_expansion_expr +; + +#keyset[id] +expr_types( //dir=expr + int id: @expr ref, + int type_: @type_or_none ref +); + +@abstract_closure_expr = + @auto_closure_expr +| @closure_expr +; + +@any_try_expr = + @force_try_expr +| @optional_try_expr +| @try_expr +; + +#keyset[id] +any_try_exprs( //dir=expr + int id: @any_try_expr ref, + int sub_expr: @expr_or_none ref +); + +applied_property_wrapper_exprs( //dir=expr + unique int id: @applied_property_wrapper_expr, + int kind: int ref, + int value: @expr_or_none ref, + int param: @param_decl_or_none ref +); + +@apply_expr = + @binary_expr +| @call_expr +| @postfix_unary_expr +| @prefix_unary_expr +| @self_apply_expr +; + +#keyset[id] +apply_exprs( //dir=expr + int id: @apply_expr ref, + int function: @expr_or_none ref +); + +#keyset[id, index] +apply_expr_arguments( //dir=expr + int id: @apply_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +assign_exprs( //dir=expr + unique int id: @assign_expr, + int dest: @expr_or_none ref, + int source: @expr_or_none ref +); + +bind_optional_exprs( //dir=expr + unique int id: @bind_optional_expr, + int sub_expr: @expr_or_none ref +); + +capture_list_exprs( //dir=expr + unique int id: @capture_list_expr, + int closure_body: @closure_expr_or_none ref +); + +#keyset[id, index] +capture_list_expr_binding_decls( //dir=expr + int id: @capture_list_expr ref, + int index: int ref, + int binding_decl: @pattern_binding_decl_or_none ref +); + +@collection_expr = + @array_expr +| @dictionary_expr +; + +decl_ref_exprs( //dir=expr + unique int id: @decl_ref_expr, + int decl: @decl_or_none ref +); + +#keyset[id, index] +decl_ref_expr_replacement_types( //dir=expr + int id: @decl_ref_expr ref, + int index: int ref, + int replacement_type: @type_or_none ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_ordinary_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_distributed_thunk_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +default_argument_exprs( //dir=expr + unique int id: @default_argument_expr, + int param_decl: @param_decl_or_none ref, + int param_index: int ref +); + +#keyset[id] +default_argument_expr_caller_side_defaults( //dir=expr + int id: @default_argument_expr ref, + int caller_side_default: @expr_or_none ref +); + +discard_assignment_exprs( //dir=expr + unique int id: @discard_assignment_expr +); + +dot_syntax_base_ignored_exprs( //dir=expr + unique int id: @dot_syntax_base_ignored_expr, + int qualifier: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +dynamic_type_exprs( //dir=expr + unique int id: @dynamic_type_expr, + int base: @expr_or_none ref +); + +enum_is_case_exprs( //dir=expr + unique int id: @enum_is_case_expr, + int sub_expr: @expr_or_none ref, + int element: @enum_element_decl_or_none ref +); + +error_exprs( //dir=expr + unique int id: @error_expr +); + +@explicit_cast_expr = + @checked_cast_expr +| @coerce_expr +; + +#keyset[id] +explicit_cast_exprs( //dir=expr + int id: @explicit_cast_expr ref, + int sub_expr: @expr_or_none ref +); + +force_value_exprs( //dir=expr + unique int id: @force_value_expr, + int sub_expr: @expr_or_none ref +); + +@identity_expr = + @await_expr +| @dot_self_expr +| @paren_expr +| @unresolved_member_chain_result_expr +; + +#keyset[id] +identity_exprs( //dir=expr + int id: @identity_expr ref, + int sub_expr: @expr_or_none ref +); + +if_exprs( //dir=expr + unique int id: @if_expr, + int condition: @expr_or_none ref, + int then_expr: @expr_or_none ref, + int else_expr: @expr_or_none ref +); + +@implicit_conversion_expr = + @abi_safe_conversion_expr +| @any_hashable_erasure_expr +| @archetype_to_super_expr +| @array_to_pointer_expr +| @bridge_from_obj_c_expr +| @bridge_to_obj_c_expr +| @class_metatype_to_object_expr +| @collection_upcast_conversion_expr +| @conditional_bridge_from_obj_c_expr +| @covariant_function_conversion_expr +| @covariant_return_conversion_expr +| @derived_to_base_expr +| @destructure_tuple_expr +| @differentiable_function_expr +| @differentiable_function_extract_original_expr +| @erasure_expr +| @existential_metatype_to_object_expr +| @foreign_object_conversion_expr +| @function_conversion_expr +| @in_out_to_pointer_expr +| @inject_into_optional_expr +| @linear_function_expr +| @linear_function_extract_original_expr +| @linear_to_differentiable_function_expr +| @load_expr +| @metatype_conversion_expr +| @pointer_to_pointer_expr +| @protocol_metatype_to_object_expr +| @string_to_pointer_expr +| @underlying_to_opaque_expr +| @unevaluated_instance_expr +| @unresolved_type_conversion_expr +; + +#keyset[id] +implicit_conversion_exprs( //dir=expr + int id: @implicit_conversion_expr ref, + int sub_expr: @expr_or_none ref +); + +in_out_exprs( //dir=expr + unique int id: @in_out_expr, + int sub_expr: @expr_or_none ref +); + +key_path_application_exprs( //dir=expr + unique int id: @key_path_application_expr, + int base: @expr_or_none ref, + int key_path: @expr_or_none ref +); + +key_path_dot_exprs( //dir=expr + unique int id: @key_path_dot_expr +); + +key_path_exprs( //dir=expr + unique int id: @key_path_expr +); + +#keyset[id] +key_path_expr_roots( //dir=expr + int id: @key_path_expr ref, + int root: @type_repr_or_none ref +); + +#keyset[id] +key_path_expr_parsed_paths( //dir=expr + int id: @key_path_expr ref, + int parsed_path: @expr_or_none ref +); + +lazy_initializer_exprs( //dir=expr + unique int id: @lazy_initializer_expr, + int sub_expr: @expr_or_none ref +); + +@literal_expr = + @builtin_literal_expr +| @interpolated_string_literal_expr +| @nil_literal_expr +| @object_literal_expr +| @regex_literal_expr +; + +@lookup_expr = + @dynamic_lookup_expr +| @member_ref_expr +| @subscript_expr +; + +#keyset[id] +lookup_exprs( //dir=expr + int id: @lookup_expr ref, + int base: @expr_or_none ref +); + +#keyset[id] +lookup_expr_members( //dir=expr + int id: @lookup_expr ref, + int member: @decl_or_none ref +); + +make_temporarily_escapable_exprs( //dir=expr + unique int id: @make_temporarily_escapable_expr, + int escaping_closure: @opaque_value_expr_or_none ref, + int nonescaping_closure: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +obj_c_selector_exprs( //dir=expr + unique int id: @obj_c_selector_expr, + int sub_expr: @expr_or_none ref, + int method: @abstract_function_decl_or_none ref +); + +one_way_exprs( //dir=expr + unique int id: @one_way_expr, + int sub_expr: @expr_or_none ref +); + +opaque_value_exprs( //dir=expr + unique int id: @opaque_value_expr +); + +open_existential_exprs( //dir=expr + unique int id: @open_existential_expr, + int sub_expr: @expr_or_none ref, + int existential: @expr_or_none ref, + int opaque_expr: @opaque_value_expr_or_none ref +); + +optional_evaluation_exprs( //dir=expr + unique int id: @optional_evaluation_expr, + int sub_expr: @expr_or_none ref +); + +other_constructor_decl_ref_exprs( //dir=expr + unique int id: @other_constructor_decl_ref_expr, + int constructor_decl: @constructor_decl_or_none ref +); + +overloaded_decl_ref_exprs( //dir=expr + unique int id: @overloaded_decl_ref_expr +); + +#keyset[id, index] +overloaded_decl_ref_expr_possible_declarations( //dir=expr + int id: @overloaded_decl_ref_expr ref, + int index: int ref, + int possible_declaration: @value_decl_or_none ref +); + +property_wrapper_value_placeholder_exprs( //dir=expr + unique int id: @property_wrapper_value_placeholder_expr, + int placeholder: @opaque_value_expr_or_none ref +); + +#keyset[id] +property_wrapper_value_placeholder_expr_wrapped_values( //dir=expr + int id: @property_wrapper_value_placeholder_expr ref, + int wrapped_value: @expr_or_none ref +); + +rebind_self_in_constructor_exprs( //dir=expr + unique int id: @rebind_self_in_constructor_expr, + int sub_expr: @expr_or_none ref, + int self: @var_decl_or_none ref +); + +sequence_exprs( //dir=expr + unique int id: @sequence_expr +); + +#keyset[id, index] +sequence_expr_elements( //dir=expr + int id: @sequence_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +super_ref_exprs( //dir=expr + unique int id: @super_ref_expr, + int self: @var_decl_or_none ref +); + +tap_exprs( //dir=expr + unique int id: @tap_expr, + int body: @brace_stmt_or_none ref, + int var: @var_decl_or_none ref +); + +#keyset[id] +tap_expr_sub_exprs( //dir=expr + int id: @tap_expr ref, + int sub_expr: @expr_or_none ref +); + +tuple_element_exprs( //dir=expr + unique int id: @tuple_element_expr, + int sub_expr: @expr_or_none ref, + int index: int ref +); + +tuple_exprs( //dir=expr + unique int id: @tuple_expr +); + +#keyset[id, index] +tuple_expr_elements( //dir=expr + int id: @tuple_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +type_exprs( //dir=expr + unique int id: @type_expr +); + +#keyset[id] +type_expr_type_reprs( //dir=expr + int id: @type_expr ref, + int type_repr: @type_repr_or_none ref +); + +unresolved_decl_ref_exprs( //dir=expr + unique int id: @unresolved_decl_ref_expr +); + +#keyset[id] +unresolved_decl_ref_expr_names( //dir=expr + int id: @unresolved_decl_ref_expr ref, + string name: string ref +); + +unresolved_dot_exprs( //dir=expr + unique int id: @unresolved_dot_expr, + int base: @expr_or_none ref, + string name: string ref +); + +unresolved_member_exprs( //dir=expr + unique int id: @unresolved_member_expr, + string name: string ref +); + +unresolved_pattern_exprs( //dir=expr + unique int id: @unresolved_pattern_expr, + int sub_pattern: @pattern_or_none ref +); + +unresolved_specialize_exprs( //dir=expr + unique int id: @unresolved_specialize_expr, + int sub_expr: @expr_or_none ref +); + +vararg_expansion_exprs( //dir=expr + unique int id: @vararg_expansion_expr, + int sub_expr: @expr_or_none ref +); + +abi_safe_conversion_exprs( //dir=expr + unique int id: @abi_safe_conversion_expr +); + +any_hashable_erasure_exprs( //dir=expr + unique int id: @any_hashable_erasure_expr +); + +archetype_to_super_exprs( //dir=expr + unique int id: @archetype_to_super_expr +); + +array_exprs( //dir=expr + unique int id: @array_expr +); + +#keyset[id, index] +array_expr_elements( //dir=expr + int id: @array_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +array_to_pointer_exprs( //dir=expr + unique int id: @array_to_pointer_expr +); + +auto_closure_exprs( //dir=expr + unique int id: @auto_closure_expr +); + +await_exprs( //dir=expr + unique int id: @await_expr +); + +binary_exprs( //dir=expr + unique int id: @binary_expr +); + +bridge_from_obj_c_exprs( //dir=expr + unique int id: @bridge_from_obj_c_expr +); + +bridge_to_obj_c_exprs( //dir=expr + unique int id: @bridge_to_obj_c_expr +); + +@builtin_literal_expr = + @boolean_literal_expr +| @magic_identifier_literal_expr +| @number_literal_expr +| @string_literal_expr +; + +call_exprs( //dir=expr + unique int id: @call_expr +); + +@checked_cast_expr = + @conditional_checked_cast_expr +| @forced_checked_cast_expr +| @is_expr +; + +class_metatype_to_object_exprs( //dir=expr + unique int id: @class_metatype_to_object_expr +); + +closure_exprs( //dir=expr + unique int id: @closure_expr +); + +coerce_exprs( //dir=expr + unique int id: @coerce_expr +); + +collection_upcast_conversion_exprs( //dir=expr + unique int id: @collection_upcast_conversion_expr +); + +conditional_bridge_from_obj_c_exprs( //dir=expr + unique int id: @conditional_bridge_from_obj_c_expr +); + +covariant_function_conversion_exprs( //dir=expr + unique int id: @covariant_function_conversion_expr +); + +covariant_return_conversion_exprs( //dir=expr + unique int id: @covariant_return_conversion_expr +); + +derived_to_base_exprs( //dir=expr + unique int id: @derived_to_base_expr +); + +destructure_tuple_exprs( //dir=expr + unique int id: @destructure_tuple_expr +); + +dictionary_exprs( //dir=expr + unique int id: @dictionary_expr +); + +#keyset[id, index] +dictionary_expr_elements( //dir=expr + int id: @dictionary_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +differentiable_function_exprs( //dir=expr + unique int id: @differentiable_function_expr +); + +differentiable_function_extract_original_exprs( //dir=expr + unique int id: @differentiable_function_extract_original_expr +); + +dot_self_exprs( //dir=expr + unique int id: @dot_self_expr +); + +@dynamic_lookup_expr = + @dynamic_member_ref_expr +| @dynamic_subscript_expr +; + +erasure_exprs( //dir=expr + unique int id: @erasure_expr +); + +existential_metatype_to_object_exprs( //dir=expr + unique int id: @existential_metatype_to_object_expr +); + +force_try_exprs( //dir=expr + unique int id: @force_try_expr +); + +foreign_object_conversion_exprs( //dir=expr + unique int id: @foreign_object_conversion_expr +); + +function_conversion_exprs( //dir=expr + unique int id: @function_conversion_expr +); + +in_out_to_pointer_exprs( //dir=expr + unique int id: @in_out_to_pointer_expr +); + +inject_into_optional_exprs( //dir=expr + unique int id: @inject_into_optional_expr +); + +interpolated_string_literal_exprs( //dir=expr + unique int id: @interpolated_string_literal_expr +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_expr: @opaque_value_expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_count_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_count_expr: @expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_literal_capacity_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int literal_capacity_expr: @expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_appending_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int appending_expr: @tap_expr_or_none ref +); + +linear_function_exprs( //dir=expr + unique int id: @linear_function_expr +); + +linear_function_extract_original_exprs( //dir=expr + unique int id: @linear_function_extract_original_expr +); + +linear_to_differentiable_function_exprs( //dir=expr + unique int id: @linear_to_differentiable_function_expr +); + +load_exprs( //dir=expr + unique int id: @load_expr +); + +member_ref_exprs( //dir=expr + unique int id: @member_ref_expr +); + +#keyset[id] +member_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_ordinary_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_distributed_thunk_semantics( //dir=expr + int id: @member_ref_expr ref +); + +metatype_conversion_exprs( //dir=expr + unique int id: @metatype_conversion_expr +); + +nil_literal_exprs( //dir=expr + unique int id: @nil_literal_expr +); + +object_literal_exprs( //dir=expr + unique int id: @object_literal_expr, + int kind: int ref +); + +#keyset[id, index] +object_literal_expr_arguments( //dir=expr + int id: @object_literal_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +optional_try_exprs( //dir=expr + unique int id: @optional_try_expr +); + +paren_exprs( //dir=expr + unique int id: @paren_expr +); + +pointer_to_pointer_exprs( //dir=expr + unique int id: @pointer_to_pointer_expr +); + +postfix_unary_exprs( //dir=expr + unique int id: @postfix_unary_expr +); + +prefix_unary_exprs( //dir=expr + unique int id: @prefix_unary_expr +); + +protocol_metatype_to_object_exprs( //dir=expr + unique int id: @protocol_metatype_to_object_expr +); + +regex_literal_exprs( //dir=expr + unique int id: @regex_literal_expr, + string pattern: string ref, + int version: int ref +); + +@self_apply_expr = + @constructor_ref_call_expr +| @dot_syntax_call_expr +; + +#keyset[id] +self_apply_exprs( //dir=expr + int id: @self_apply_expr ref, + int base: @expr_or_none ref +); + +string_to_pointer_exprs( //dir=expr + unique int id: @string_to_pointer_expr +); + +subscript_exprs( //dir=expr + unique int id: @subscript_expr +); + +#keyset[id, index] +subscript_expr_arguments( //dir=expr + int id: @subscript_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +#keyset[id] +subscript_expr_has_direct_to_storage_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_ordinary_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_distributed_thunk_semantics( //dir=expr + int id: @subscript_expr ref +); + +try_exprs( //dir=expr + unique int id: @try_expr +); + +underlying_to_opaque_exprs( //dir=expr + unique int id: @underlying_to_opaque_expr +); + +unevaluated_instance_exprs( //dir=expr + unique int id: @unevaluated_instance_expr +); + +unresolved_member_chain_result_exprs( //dir=expr + unique int id: @unresolved_member_chain_result_expr +); + +unresolved_type_conversion_exprs( //dir=expr + unique int id: @unresolved_type_conversion_expr +); + +boolean_literal_exprs( //dir=expr + unique int id: @boolean_literal_expr, + boolean value: boolean ref +); + +conditional_checked_cast_exprs( //dir=expr + unique int id: @conditional_checked_cast_expr +); + +constructor_ref_call_exprs( //dir=expr + unique int id: @constructor_ref_call_expr +); + +dot_syntax_call_exprs( //dir=expr + unique int id: @dot_syntax_call_expr +); + +dynamic_member_ref_exprs( //dir=expr + unique int id: @dynamic_member_ref_expr +); + +dynamic_subscript_exprs( //dir=expr + unique int id: @dynamic_subscript_expr +); + +forced_checked_cast_exprs( //dir=expr + unique int id: @forced_checked_cast_expr +); + +is_exprs( //dir=expr + unique int id: @is_expr +); + +magic_identifier_literal_exprs( //dir=expr + unique int id: @magic_identifier_literal_expr, + string kind: string ref +); + +@number_literal_expr = + @float_literal_expr +| @integer_literal_expr +; + +string_literal_exprs( //dir=expr + unique int id: @string_literal_expr, + string value: string ref +); + +float_literal_exprs( //dir=expr + unique int id: @float_literal_expr, + string string_value: string ref +); + +integer_literal_exprs( //dir=expr + unique int id: @integer_literal_expr, + string string_value: string ref +); + +@pattern = + @any_pattern +| @binding_pattern +| @bool_pattern +| @enum_element_pattern +| @expr_pattern +| @is_pattern +| @named_pattern +| @optional_some_pattern +| @paren_pattern +| @tuple_pattern +| @typed_pattern +; + +any_patterns( //dir=pattern + unique int id: @any_pattern +); + +binding_patterns( //dir=pattern + unique int id: @binding_pattern, + int sub_pattern: @pattern_or_none ref +); + +bool_patterns( //dir=pattern + unique int id: @bool_pattern, + boolean value: boolean ref +); + +enum_element_patterns( //dir=pattern + unique int id: @enum_element_pattern, + int element: @enum_element_decl_or_none ref +); + +#keyset[id] +enum_element_pattern_sub_patterns( //dir=pattern + int id: @enum_element_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +expr_patterns( //dir=pattern + unique int id: @expr_pattern, + int sub_expr: @expr_or_none ref +); + +is_patterns( //dir=pattern + unique int id: @is_pattern +); + +#keyset[id] +is_pattern_cast_type_reprs( //dir=pattern + int id: @is_pattern ref, + int cast_type_repr: @type_repr_or_none ref +); + +#keyset[id] +is_pattern_sub_patterns( //dir=pattern + int id: @is_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +named_patterns( //dir=pattern + unique int id: @named_pattern, + string name: string ref +); + +optional_some_patterns( //dir=pattern + unique int id: @optional_some_pattern, + int sub_pattern: @pattern_or_none ref +); + +paren_patterns( //dir=pattern + unique int id: @paren_pattern, + int sub_pattern: @pattern_or_none ref +); + +tuple_patterns( //dir=pattern + unique int id: @tuple_pattern +); + +#keyset[id, index] +tuple_pattern_elements( //dir=pattern + int id: @tuple_pattern ref, + int index: int ref, + int element: @pattern_or_none ref +); + +typed_patterns( //dir=pattern + unique int id: @typed_pattern, + int sub_pattern: @pattern_or_none ref +); + +#keyset[id] +typed_pattern_type_reprs( //dir=pattern + int id: @typed_pattern ref, + int type_repr: @type_repr_or_none ref +); + +case_label_items( //dir=stmt + unique int id: @case_label_item, + int pattern: @pattern_or_none ref +); + +#keyset[id] +case_label_item_guards( //dir=stmt + int id: @case_label_item ref, + int guard: @expr_or_none ref +); + +condition_elements( //dir=stmt + unique int id: @condition_element +); + +#keyset[id] +condition_element_booleans( //dir=stmt + int id: @condition_element ref, + int boolean_: @expr_or_none ref +); + +#keyset[id] +condition_element_patterns( //dir=stmt + int id: @condition_element ref, + int pattern: @pattern_or_none ref +); + +#keyset[id] +condition_element_initializers( //dir=stmt + int id: @condition_element ref, + int initializer: @expr_or_none ref +); + +#keyset[id] +condition_element_availabilities( //dir=stmt + int id: @condition_element ref, + int availability: @availability_info_or_none ref +); + +@stmt = + @brace_stmt +| @break_stmt +| @case_stmt +| @continue_stmt +| @defer_stmt +| @fail_stmt +| @fallthrough_stmt +| @labeled_stmt +| @pound_assert_stmt +| @return_stmt +| @throw_stmt +| @yield_stmt +; + +stmt_conditions( //dir=stmt + unique int id: @stmt_condition +); + +#keyset[id, index] +stmt_condition_elements( //dir=stmt + int id: @stmt_condition ref, + int index: int ref, + int element: @condition_element_or_none ref +); + +brace_stmts( //dir=stmt + unique int id: @brace_stmt +); + +#keyset[id, index] +brace_stmt_elements( //dir=stmt + int id: @brace_stmt ref, + int index: int ref, + int element: @ast_node_or_none ref +); + +break_stmts( //dir=stmt + unique int id: @break_stmt +); + +#keyset[id] +break_stmt_target_names( //dir=stmt + int id: @break_stmt ref, + string target_name: string ref +); + +#keyset[id] +break_stmt_targets( //dir=stmt + int id: @break_stmt ref, + int target: @stmt_or_none ref +); + +case_stmts( //dir=stmt + unique int id: @case_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +case_stmt_labels( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int label: @case_label_item_or_none ref +); + +#keyset[id, index] +case_stmt_variables( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int variable: @var_decl_or_none ref +); + +continue_stmts( //dir=stmt + unique int id: @continue_stmt +); + +#keyset[id] +continue_stmt_target_names( //dir=stmt + int id: @continue_stmt ref, + string target_name: string ref +); + +#keyset[id] +continue_stmt_targets( //dir=stmt + int id: @continue_stmt ref, + int target: @stmt_or_none ref +); + +defer_stmts( //dir=stmt + unique int id: @defer_stmt, + int body: @brace_stmt_or_none ref +); + +fail_stmts( //dir=stmt + unique int id: @fail_stmt +); + +fallthrough_stmts( //dir=stmt + unique int id: @fallthrough_stmt, + int fallthrough_source: @case_stmt_or_none ref, + int fallthrough_dest: @case_stmt_or_none ref +); + +@labeled_stmt = + @do_catch_stmt +| @do_stmt +| @for_each_stmt +| @labeled_conditional_stmt +| @repeat_while_stmt +| @switch_stmt +; + +#keyset[id] +labeled_stmt_labels( //dir=stmt + int id: @labeled_stmt ref, + string label: string ref +); + +pound_assert_stmts( //dir=stmt + unique int id: @pound_assert_stmt, + int condition: @expr_or_none ref, + string message: string ref +); + +return_stmts( //dir=stmt + unique int id: @return_stmt +); + +#keyset[id] +return_stmt_results( //dir=stmt + int id: @return_stmt ref, + int result: @expr_or_none ref +); + +throw_stmts( //dir=stmt + unique int id: @throw_stmt, + int sub_expr: @expr_or_none ref +); + +yield_stmts( //dir=stmt + unique int id: @yield_stmt +); + +#keyset[id, index] +yield_stmt_results( //dir=stmt + int id: @yield_stmt ref, + int index: int ref, + int result: @expr_or_none ref +); + +do_catch_stmts( //dir=stmt + unique int id: @do_catch_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +do_catch_stmt_catches( //dir=stmt + int id: @do_catch_stmt ref, + int index: int ref, + int catch: @case_stmt_or_none ref +); + +do_stmts( //dir=stmt + unique int id: @do_stmt, + int body: @brace_stmt_or_none ref +); + +for_each_stmts( //dir=stmt + unique int id: @for_each_stmt, + int pattern: @pattern_or_none ref, + int sequence: @expr_or_none ref, + int body: @brace_stmt_or_none ref +); + +#keyset[id] +for_each_stmt_wheres( //dir=stmt + int id: @for_each_stmt ref, + int where: @expr_or_none ref +); + +@labeled_conditional_stmt = + @guard_stmt +| @if_stmt +| @while_stmt +; + +#keyset[id] +labeled_conditional_stmts( //dir=stmt + int id: @labeled_conditional_stmt ref, + int condition: @stmt_condition_or_none ref +); + +repeat_while_stmts( //dir=stmt + unique int id: @repeat_while_stmt, + int condition: @expr_or_none ref, + int body: @stmt_or_none ref +); + +switch_stmts( //dir=stmt + unique int id: @switch_stmt, + int expr: @expr_or_none ref +); + +#keyset[id, index] +switch_stmt_cases( //dir=stmt + int id: @switch_stmt ref, + int index: int ref, + int case_: @case_stmt_or_none ref +); + +guard_stmts( //dir=stmt + unique int id: @guard_stmt, + int body: @brace_stmt_or_none ref +); + +if_stmts( //dir=stmt + unique int id: @if_stmt, + int then: @stmt_or_none ref +); + +#keyset[id] +if_stmt_elses( //dir=stmt + int id: @if_stmt ref, + int else: @stmt_or_none ref +); + +while_stmts( //dir=stmt + unique int id: @while_stmt, + int body: @stmt_or_none ref +); + +@type = + @any_function_type +| @any_generic_type +| @any_metatype_type +| @builtin_type +| @dependent_member_type +| @dynamic_self_type +| @error_type +| @existential_type +| @in_out_type +| @l_value_type +| @module_type +| @parameterized_protocol_type +| @protocol_composition_type +| @reference_storage_type +| @substitutable_type +| @sugar_type +| @tuple_type +| @unresolved_type +; + +#keyset[id] +types( //dir=type + int id: @type ref, + string name: string ref, + int canonical_type: @type_or_none ref +); + +type_reprs( //dir=type + unique int id: @type_repr, + int type_: @type_or_none ref +); + +@any_function_type = + @function_type +| @generic_function_type +; + +#keyset[id] +any_function_types( //dir=type + int id: @any_function_type ref, + int result: @type_or_none ref +); + +#keyset[id, index] +any_function_type_param_types( //dir=type + int id: @any_function_type ref, + int index: int ref, + int param_type: @type_or_none ref +); + +#keyset[id] +any_function_type_is_throwing( //dir=type + int id: @any_function_type ref +); + +#keyset[id] +any_function_type_is_async( //dir=type + int id: @any_function_type ref +); + +@any_generic_type = + @nominal_or_bound_generic_nominal_type +| @unbound_generic_type +; + +#keyset[id] +any_generic_types( //dir=type + int id: @any_generic_type ref, + int declaration: @generic_type_decl_or_none ref +); + +#keyset[id] +any_generic_type_parents( //dir=type + int id: @any_generic_type ref, + int parent: @type_or_none ref +); + +@any_metatype_type = + @existential_metatype_type +| @metatype_type +; + +@builtin_type = + @any_builtin_integer_type +| @builtin_bridge_object_type +| @builtin_default_actor_storage_type +| @builtin_executor_type +| @builtin_float_type +| @builtin_job_type +| @builtin_native_object_type +| @builtin_raw_pointer_type +| @builtin_raw_unsafe_continuation_type +| @builtin_unsafe_value_buffer_type +| @builtin_vector_type +; + +dependent_member_types( //dir=type + unique int id: @dependent_member_type, + int base_type: @type_or_none ref, + int associated_type_decl: @associated_type_decl_or_none ref +); + +dynamic_self_types( //dir=type + unique int id: @dynamic_self_type, + int static_self_type: @type_or_none ref +); + +error_types( //dir=type + unique int id: @error_type +); + +existential_types( //dir=type + unique int id: @existential_type, + int constraint: @type_or_none ref +); + +in_out_types( //dir=type + unique int id: @in_out_type, + int object_type: @type_or_none ref +); + +l_value_types( //dir=type + unique int id: @l_value_type, + int object_type: @type_or_none ref +); + +module_types( //dir=type + unique int id: @module_type, + int module: @module_decl_or_none ref +); + +parameterized_protocol_types( //dir=type + unique int id: @parameterized_protocol_type, + int base: @protocol_type_or_none ref +); + +#keyset[id, index] +parameterized_protocol_type_args( //dir=type + int id: @parameterized_protocol_type ref, + int index: int ref, + int arg: @type_or_none ref +); + +protocol_composition_types( //dir=type + unique int id: @protocol_composition_type +); + +#keyset[id, index] +protocol_composition_type_members( //dir=type + int id: @protocol_composition_type ref, + int index: int ref, + int member: @type_or_none ref +); + +@reference_storage_type = + @unmanaged_storage_type +| @unowned_storage_type +| @weak_storage_type +; + +#keyset[id] +reference_storage_types( //dir=type + int id: @reference_storage_type ref, + int referent_type: @type_or_none ref +); + +@substitutable_type = + @archetype_type +| @generic_type_param_type +; + +@sugar_type = + @paren_type +| @syntax_sugar_type +| @type_alias_type +; + +tuple_types( //dir=type + unique int id: @tuple_type +); + +#keyset[id, index] +tuple_type_types( //dir=type + int id: @tuple_type ref, + int index: int ref, + int type_: @type_or_none ref +); + +#keyset[id, index] +tuple_type_names( //dir=type + int id: @tuple_type ref, + int index: int ref, + string name: string ref +); + +unresolved_types( //dir=type + unique int id: @unresolved_type +); + +@any_builtin_integer_type = + @builtin_integer_literal_type +| @builtin_integer_type +; + +@archetype_type = + @opaque_type_archetype_type +| @opened_archetype_type +| @primary_archetype_type +; + +#keyset[id] +archetype_types( //dir=type + int id: @archetype_type ref, + int interface_type: @type_or_none ref +); + +#keyset[id] +archetype_type_superclasses( //dir=type + int id: @archetype_type ref, + int superclass: @type_or_none ref +); + +#keyset[id, index] +archetype_type_protocols( //dir=type + int id: @archetype_type ref, + int index: int ref, + int protocol: @protocol_decl_or_none ref +); + +builtin_bridge_object_types( //dir=type + unique int id: @builtin_bridge_object_type +); + +builtin_default_actor_storage_types( //dir=type + unique int id: @builtin_default_actor_storage_type +); + +builtin_executor_types( //dir=type + unique int id: @builtin_executor_type +); + +builtin_float_types( //dir=type + unique int id: @builtin_float_type +); + +builtin_job_types( //dir=type + unique int id: @builtin_job_type +); + +builtin_native_object_types( //dir=type + unique int id: @builtin_native_object_type +); + +builtin_raw_pointer_types( //dir=type + unique int id: @builtin_raw_pointer_type +); + +builtin_raw_unsafe_continuation_types( //dir=type + unique int id: @builtin_raw_unsafe_continuation_type +); + +builtin_unsafe_value_buffer_types( //dir=type + unique int id: @builtin_unsafe_value_buffer_type +); + +builtin_vector_types( //dir=type + unique int id: @builtin_vector_type +); + +existential_metatype_types( //dir=type + unique int id: @existential_metatype_type +); + +function_types( //dir=type + unique int id: @function_type +); + +generic_function_types( //dir=type + unique int id: @generic_function_type +); + +#keyset[id, index] +generic_function_type_generic_params( //dir=type + int id: @generic_function_type ref, + int index: int ref, + int generic_param: @generic_type_param_type_or_none ref +); + +generic_type_param_types( //dir=type + unique int id: @generic_type_param_type +); + +metatype_types( //dir=type + unique int id: @metatype_type +); + +@nominal_or_bound_generic_nominal_type = + @bound_generic_type +| @nominal_type +; + +paren_types( //dir=type + unique int id: @paren_type, + int type_: @type_or_none ref +); + +@syntax_sugar_type = + @dictionary_type +| @unary_syntax_sugar_type +; + +type_alias_types( //dir=type + unique int id: @type_alias_type, + int decl: @type_alias_decl_or_none ref +); + +unbound_generic_types( //dir=type + unique int id: @unbound_generic_type +); + +unmanaged_storage_types( //dir=type + unique int id: @unmanaged_storage_type +); + +unowned_storage_types( //dir=type + unique int id: @unowned_storage_type +); + +weak_storage_types( //dir=type + unique int id: @weak_storage_type +); + +@bound_generic_type = + @bound_generic_class_type +| @bound_generic_enum_type +| @bound_generic_struct_type +; + +#keyset[id, index] +bound_generic_type_arg_types( //dir=type + int id: @bound_generic_type ref, + int index: int ref, + int arg_type: @type_or_none ref +); + +builtin_integer_literal_types( //dir=type + unique int id: @builtin_integer_literal_type +); + +builtin_integer_types( //dir=type + unique int id: @builtin_integer_type +); + +#keyset[id] +builtin_integer_type_widths( //dir=type + int id: @builtin_integer_type ref, + int width: int ref +); + +dictionary_types( //dir=type + unique int id: @dictionary_type, + int key_type: @type_or_none ref, + int value_type: @type_or_none ref +); + +@nominal_type = + @class_type +| @enum_type +| @protocol_type +| @struct_type +; + +opaque_type_archetype_types( //dir=type + unique int id: @opaque_type_archetype_type, + int declaration: @opaque_type_decl_or_none ref +); + +opened_archetype_types( //dir=type + unique int id: @opened_archetype_type +); + +primary_archetype_types( //dir=type + unique int id: @primary_archetype_type +); + +@unary_syntax_sugar_type = + @array_slice_type +| @optional_type +| @variadic_sequence_type +; + +#keyset[id] +unary_syntax_sugar_types( //dir=type + int id: @unary_syntax_sugar_type ref, + int base_type: @type_or_none ref +); + +array_slice_types( //dir=type + unique int id: @array_slice_type +); + +bound_generic_class_types( //dir=type + unique int id: @bound_generic_class_type +); + +bound_generic_enum_types( //dir=type + unique int id: @bound_generic_enum_type +); + +bound_generic_struct_types( //dir=type + unique int id: @bound_generic_struct_type +); + +class_types( //dir=type + unique int id: @class_type +); + +enum_types( //dir=type + unique int id: @enum_type +); + +optional_types( //dir=type + unique int id: @optional_type +); + +protocol_types( //dir=type + unique int id: @protocol_type +); + +struct_types( //dir=type + unique int id: @struct_type +); + +variadic_sequence_types( //dir=type + unique int id: @variadic_sequence_type +); + +@abstract_function_decl_or_none = + @abstract_function_decl +| @unspecified_element +; + +@accessor_decl_or_none = + @accessor_decl +| @unspecified_element +; + +@argument_or_none = + @argument +| @unspecified_element +; + +@associated_type_decl_or_none = + @associated_type_decl +| @unspecified_element +; + +@ast_node_or_none = + @ast_node +| @unspecified_element +; + +@availability_info_or_none = + @availability_info +| @unspecified_element +; + +@availability_spec_or_none = + @availability_spec +| @unspecified_element +; + +@brace_stmt_or_none = + @brace_stmt +| @unspecified_element +; + +@captured_decl_or_none = + @captured_decl +| @unspecified_element +; + +@case_label_item_or_none = + @case_label_item +| @unspecified_element +; + +@case_stmt_or_none = + @case_stmt +| @unspecified_element +; + +@closure_expr_or_none = + @closure_expr +| @unspecified_element +; + +@condition_element_or_none = + @condition_element +| @unspecified_element +; + +@constructor_decl_or_none = + @constructor_decl +| @unspecified_element +; + +@decl_or_none = + @decl +| @unspecified_element +; + +@enum_element_decl_or_none = + @enum_element_decl +| @unspecified_element +; + +@expr_or_none = + @expr +| @unspecified_element +; + +@file_or_none = + @file +| @unspecified_element +; + +@generic_type_decl_or_none = + @generic_type_decl +| @unspecified_element +; + +@generic_type_param_decl_or_none = + @generic_type_param_decl +| @unspecified_element +; + +@generic_type_param_type_or_none = + @generic_type_param_type +| @unspecified_element +; + +@location_or_none = + @location +| @unspecified_element +; + +@module_decl_or_none = + @module_decl +| @unspecified_element +; + +@nominal_type_decl_or_none = + @nominal_type_decl +| @unspecified_element +; + +@opaque_type_decl_or_none = + @opaque_type_decl +| @unspecified_element +; + +@opaque_value_expr_or_none = + @opaque_value_expr +| @unspecified_element +; + +@param_decl_or_none = + @param_decl +| @unspecified_element +; + +@pattern_or_none = + @pattern +| @unspecified_element +; + +@pattern_binding_decl_or_none = + @pattern_binding_decl +| @unspecified_element +; + +@precedence_group_decl_or_none = + @precedence_group_decl +| @unspecified_element +; + +@protocol_decl_or_none = + @protocol_decl +| @unspecified_element +; + +@protocol_type_or_none = + @protocol_type +| @unspecified_element +; + +@stmt_or_none = + @stmt +| @unspecified_element +; + +@stmt_condition_or_none = + @stmt_condition +| @unspecified_element +; + +@string_literal_expr_or_none = + @string_literal_expr +| @unspecified_element +; + +@tap_expr_or_none = + @tap_expr +| @unspecified_element +; + +@type_or_none = + @type +| @unspecified_element +; + +@type_alias_decl_or_none = + @type_alias_decl +| @unspecified_element +; + +@type_repr_or_none = + @type_repr +| @unspecified_element +; + +@value_decl_or_none = + @unspecified_element +| @value_decl +; + +@var_decl_or_none = + @unspecified_element +| @var_decl +; diff --git a/swift/ql/lib/upgrades/e646f9e0308ec7135c83c0fdf96896d2737a8013/upgrade.properties b/swift/ql/lib/upgrades/e646f9e0308ec7135c83c0fdf96896d2737a8013/upgrade.properties new file mode 100644 index 00000000000..def634ba268 --- /dev/null +++ b/swift/ql/lib/upgrades/e646f9e0308ec7135c83c0fdf96896d2737a8013/upgrade.properties @@ -0,0 +1,4 @@ +description: Turn exported and imported modules into unindexed sets +compatibility: full +module_decl_imported_modules.rel: reorder module_decl_imported_modules(int id, int index, int imported) id imported +module_decl_exported_modules.rel: reorder module_decl_exported_modules(int id, int index, int exported) id exported diff --git a/swift/ql/src/diagnostics/SuccessfullyExtractedLines.ql b/swift/ql/src/diagnostics/SuccessfullyExtractedLines.ql new file mode 100644 index 00000000000..59b1d5bc8bc --- /dev/null +++ b/swift/ql/src/diagnostics/SuccessfullyExtractedLines.ql @@ -0,0 +1,15 @@ +/** + * @name Successfully extracted lines + * @description Count all lines in source code in which something was extracted. Entities spanning multiple lines like multi-line strings or comments only contribute one line to this count. + * @kind metric + * @id swift/diagnostics/successfully-extracted-lines + * @tags summary + */ + +import swift + +select count(File f, int line | + exists(Location loc | + not loc instanceof UnknownLocation and loc.getFile() = f and loc.getStartLine() = line + ) + ) diff --git a/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getAnExportedModule.expected b/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getAnExportedModule.expected new file mode 100644 index 00000000000..271c68f34fd --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getAnExportedModule.expected @@ -0,0 +1 @@ +| file://:0:0:0:0 | Foo | file://:0:0:0:0 | Swift | diff --git a/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getExportedModule.ql b/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getAnExportedModule.ql similarity index 62% rename from swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getExportedModule.ql rename to swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getAnExportedModule.ql index 012f1501665..649b56793c8 100644 --- a/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getExportedModule.ql +++ b/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getAnExportedModule.ql @@ -2,6 +2,6 @@ import codeql.swift.elements import TestUtils -from ModuleDecl x, int index +from ModuleDecl x where toBeTested(x) and not x.isUnknown() -select x, index, x.getExportedModule(index) +select x, x.getAnExportedModule() diff --git a/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getAnImportedModule.expected b/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getAnImportedModule.expected new file mode 100644 index 00000000000..c711cd8b913 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getAnImportedModule.expected @@ -0,0 +1,9 @@ +| file://:0:0:0:0 | Foo | file://:0:0:0:0 | Swift | +| file://:0:0:0:0 | Foo | file://:0:0:0:0 | SwiftOnoneSupport | +| file://:0:0:0:0 | Foo | file://:0:0:0:0 | _Concurrency | +| file://:0:0:0:0 | Foo | file://:0:0:0:0 | _StringProcessing | +| file://:0:0:0:0 | __ObjC | file://:0:0:0:0 | Swift | +| file://:0:0:0:0 | default_module_name | file://:0:0:0:0 | Swift | +| file://:0:0:0:0 | default_module_name | file://:0:0:0:0 | SwiftOnoneSupport | +| file://:0:0:0:0 | default_module_name | file://:0:0:0:0 | _Concurrency | +| file://:0:0:0:0 | default_module_name | file://:0:0:0:0 | _StringProcessing | diff --git a/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getImportedModule.ql b/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getAnImportedModule.ql similarity index 62% rename from swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getImportedModule.ql rename to swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getAnImportedModule.ql index c5c8e83e23b..d7c95b74e73 100644 --- a/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getImportedModule.ql +++ b/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getAnImportedModule.ql @@ -2,6 +2,6 @@ import codeql.swift.elements import TestUtils -from ModuleDecl x, int index +from ModuleDecl x where toBeTested(x) and not x.isUnknown() -select x, index, x.getImportedModule(index) +select x, x.getAnImportedModule() diff --git a/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getExportedModule.expected b/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getExportedModule.expected deleted file mode 100644 index a0865f2c40a..00000000000 --- a/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getExportedModule.expected +++ /dev/null @@ -1 +0,0 @@ -| file://:0:0:0:0 | Foo | 0 | file://:0:0:0:0 | Swift | diff --git a/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getImportedModule.expected b/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getImportedModule.expected deleted file mode 100644 index ca1793b95ef..00000000000 --- a/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getImportedModule.expected +++ /dev/null @@ -1,9 +0,0 @@ -| file://:0:0:0:0 | Foo | 0 | file://:0:0:0:0 | Swift | -| file://:0:0:0:0 | Foo | 1 | file://:0:0:0:0 | _StringProcessing | -| file://:0:0:0:0 | Foo | 2 | file://:0:0:0:0 | _Concurrency | -| file://:0:0:0:0 | Foo | 3 | file://:0:0:0:0 | SwiftOnoneSupport | -| file://:0:0:0:0 | __ObjC | 0 | file://:0:0:0:0 | Swift | -| file://:0:0:0:0 | default_module_name | 0 | file://:0:0:0:0 | Swift | -| file://:0:0:0:0 | default_module_name | 1 | file://:0:0:0:0 | _StringProcessing | -| file://:0:0:0:0 | default_module_name | 2 | file://:0:0:0:0 | _Concurrency | -| file://:0:0:0:0 | default_module_name | 3 | file://:0:0:0:0 | SwiftOnoneSupport | diff --git a/swift/ql/test/library-tests/elements/type/nominaltype/nominaltype.expected b/swift/ql/test/library-tests/elements/type/nominaltype/nominaltype.expected index 0eb3c363ee8..dc37626854f 100644 --- a/swift/ql/test/library-tests/elements/type/nominaltype/nominaltype.expected +++ b/swift/ql/test/library-tests/elements/type/nominaltype/nominaltype.expected @@ -3,11 +3,11 @@ | nominaltype.swift:37:6:37:6 | a_optional_alias | A_optional_alias | A? | getAliasedType:A? | | nominaltype.swift:38:6:38:6 | b1 | B1 | B1 | getABaseType:A | | nominaltype.swift:39:6:39:6 | b2 | B2 | B2 | getABaseType:A_alias | -| nominaltype.swift:40:6:40:6 | b1_alias | B1_alias | B1 | getAliasedType:B1 | -| nominaltype.swift:41:6:41:6 | b2_alias | B2_alias | B2 | getAliasedType:B2 | +| nominaltype.swift:40:6:40:6 | b1_alias | B1_alias | B1 | getABaseType:A, getAliasedType:B1 | +| nominaltype.swift:41:6:41:6 | b2_alias | B2_alias | B2 | getABaseType:A_alias, getAliasedType:B2 | | nominaltype.swift:42:6:42:6 | p | P | P | | | nominaltype.swift:43:6:43:6 | p_alias | P_alias | P_alias | | | nominaltype.swift:44:6:44:6 | c1 | C1 | C1 | getABaseType:P | | nominaltype.swift:45:6:45:6 | c2 | C2 | C2 | getABaseType:P_alias | -| nominaltype.swift:46:6:46:6 | c1_alias | C1_alias | C1 | getAliasedType:C1 | -| nominaltype.swift:47:6:47:6 | c2_alias | C2_alias | C2 | getAliasedType:C2 | +| nominaltype.swift:46:6:46:6 | c1_alias | C1_alias | C1 | getABaseType:P, getAliasedType:C1 | +| nominaltype.swift:47:6:47:6 | c2_alias | C2_alias | C2 | getABaseType:P_alias, getAliasedType:C2 | diff --git a/swift/ql/test/library-tests/elements/type/nominaltype/nominaltype.ql b/swift/ql/test/library-tests/elements/type/nominaltype/nominaltype.ql index f5e01a8022b..c0ab33423bf 100644 --- a/swift/ql/test/library-tests/elements/type/nominaltype/nominaltype.ql +++ b/swift/ql/test/library-tests/elements/type/nominaltype/nominaltype.ql @@ -3,7 +3,7 @@ import swift string describe(Type t) { result = "getAliasedType:" + t.(TypeAliasType).getAliasedType() or - result = "getABaseType:" + t.(NominalType).getABaseType() + result = "getABaseType:" + t.getABaseType() } from VarDecl v, Type t diff --git a/swift/ql/test/query-tests/Diagnostics/SuccessfullyExtractedLines.expected b/swift/ql/test/query-tests/Diagnostics/SuccessfullyExtractedLines.expected new file mode 100644 index 00000000000..b5a514b9ffa --- /dev/null +++ b/swift/ql/test/query-tests/Diagnostics/SuccessfullyExtractedLines.expected @@ -0,0 +1 @@ +| 4 | diff --git a/swift/ql/test/query-tests/Diagnostics/SuccessfullyExtractedLines.qlref b/swift/ql/test/query-tests/Diagnostics/SuccessfullyExtractedLines.qlref new file mode 100644 index 00000000000..26996e64988 --- /dev/null +++ b/swift/ql/test/query-tests/Diagnostics/SuccessfullyExtractedLines.qlref @@ -0,0 +1 @@ +diagnostics/SuccessfullyExtractedLines.ql diff --git a/swift/ql/test/query-tests/Diagnostics/ignored.swift b/swift/ql/test/query-tests/Diagnostics/ignored.swift new file mode 100644 index 00000000000..f488af7e837 --- /dev/null +++ b/swift/ql/test/query-tests/Diagnostics/ignored.swift @@ -0,0 +1,3 @@ +//codeql-extractor-env: CODEQL_EXTRACTOR_SWIFT_RUN_UNDER=true + +func not_compiled() {} diff --git a/swift/ql/test/query-tests/Diagnostics/main.swift b/swift/ql/test/query-tests/Diagnostics/main.swift index e69de29bb2d..92d0406caac 100644 --- a/swift/ql/test/query-tests/Diagnostics/main.swift +++ b/swift/ql/test/query-tests/Diagnostics/main.swift @@ -0,0 +1,6 @@ + + +// a comment + + +func foo() {} diff --git a/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.expected b/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.expected index 540cdad43da..52c9a9e6bc7 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.expected +++ b/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.expected @@ -2,6 +2,7 @@ edges | file://:0:0:0:0 | self [value] : | file://:0:0:0:0 | .value : | | file://:0:0:0:0 | value : | file://:0:0:0:0 | [post] self [data] : | | file://:0:0:0:0 | value : | file://:0:0:0:0 | [post] self [notStoredBankAccountNumber] : | +| file://:0:0:0:0 | value : | file://:0:0:0:0 | [post] self [password] : | | file://:0:0:0:0 | value : | file://:0:0:0:0 | [post] self [value] : | | testCoreData2.swift:23:13:23:13 | value : | file://:0:0:0:0 | value : | | testCoreData2.swift:37:2:37:2 | [post] obj [myValue] : | testCoreData2.swift:37:2:37:2 | [post] obj | @@ -168,30 +169,36 @@ edges | testGRDB.swift:208:81:208:81 | password : | testGRDB.swift:208:80:208:89 | [...] | | testGRDB.swift:210:85:210:85 | password : | testGRDB.swift:210:84:210:93 | [...] | | testGRDB.swift:212:99:212:99 | password : | testGRDB.swift:212:98:212:107 | [...] | -| testRealm.swift:16:6:16:6 | value : | file://:0:0:0:0 | value : | -| testRealm.swift:34:2:34:2 | [post] a [data] : | testRealm.swift:34:2:34:2 | [post] a | -| testRealm.swift:34:11:34:11 | myPassword : | testRealm.swift:16:6:16:6 | value : | -| testRealm.swift:34:11:34:11 | myPassword : | testRealm.swift:34:2:34:2 | [post] a [data] : | -| testRealm.swift:42:2:42:2 | [post] c [data] : | testRealm.swift:42:2:42:2 | [post] c | -| testRealm.swift:42:11:42:11 | myPassword : | testRealm.swift:16:6:16:6 | value : | -| testRealm.swift:42:11:42:11 | myPassword : | testRealm.swift:42:2:42:2 | [post] c [data] : | -| testRealm.swift:52:2:52:3 | [post] ...! [data] : | testRealm.swift:52:2:52:3 | [post] ...! | -| testRealm.swift:52:12:52:12 | myPassword : | testRealm.swift:16:6:16:6 | value : | -| testRealm.swift:52:12:52:12 | myPassword : | testRealm.swift:52:2:52:3 | [post] ...! [data] : | -| testRealm.swift:59:2:59:2 | [post] g [data] : | testRealm.swift:59:2:59:2 | [post] g | -| testRealm.swift:59:11:59:11 | myPassword : | testRealm.swift:16:6:16:6 | value : | -| testRealm.swift:59:11:59:11 | myPassword : | testRealm.swift:59:2:59:2 | [post] g [data] : | +| testRealm.swift:27:6:27:6 | value : | file://:0:0:0:0 | value : | +| testRealm.swift:34:6:34:6 | value : | file://:0:0:0:0 | value : | +| testRealm.swift:41:2:41:2 | [post] a [data] : | testRealm.swift:41:2:41:2 | [post] a | +| testRealm.swift:41:11:41:11 | myPassword : | testRealm.swift:27:6:27:6 | value : | +| testRealm.swift:41:11:41:11 | myPassword : | testRealm.swift:41:2:41:2 | [post] a [data] : | +| testRealm.swift:49:2:49:2 | [post] c [data] : | testRealm.swift:49:2:49:2 | [post] c | +| testRealm.swift:49:11:49:11 | myPassword : | testRealm.swift:27:6:27:6 | value : | +| testRealm.swift:49:11:49:11 | myPassword : | testRealm.swift:49:2:49:2 | [post] c [data] : | +| testRealm.swift:59:2:59:3 | [post] ...! [data] : | testRealm.swift:59:2:59:3 | [post] ...! | +| testRealm.swift:59:12:59:12 | myPassword : | testRealm.swift:27:6:27:6 | value : | +| testRealm.swift:59:12:59:12 | myPassword : | testRealm.swift:59:2:59:3 | [post] ...! [data] : | +| testRealm.swift:66:2:66:2 | [post] g [data] : | testRealm.swift:66:2:66:2 | [post] g | +| testRealm.swift:66:11:66:11 | myPassword : | testRealm.swift:27:6:27:6 | value : | +| testRealm.swift:66:11:66:11 | myPassword : | testRealm.swift:66:2:66:2 | [post] g [data] : | +| testRealm.swift:73:2:73:2 | [post] h [password] : | testRealm.swift:73:2:73:2 | [post] h | +| testRealm.swift:73:15:73:15 | myPassword : | testRealm.swift:34:6:34:6 | value : | +| testRealm.swift:73:15:73:15 | myPassword : | testRealm.swift:73:2:73:2 | [post] h [password] : | nodes | file://:0:0:0:0 | .value2 : | semmle.label | .value2 : | | file://:0:0:0:0 | .value : | semmle.label | .value : | | file://:0:0:0:0 | .value : | semmle.label | .value : | | file://:0:0:0:0 | [post] self [data] : | semmle.label | [post] self [data] : | | file://:0:0:0:0 | [post] self [notStoredBankAccountNumber] : | semmle.label | [post] self [notStoredBankAccountNumber] : | +| file://:0:0:0:0 | [post] self [password] : | semmle.label | [post] self [password] : | | file://:0:0:0:0 | [post] self [value] : | semmle.label | [post] self [value] : | | file://:0:0:0:0 | self [value] : | semmle.label | self [value] : | | file://:0:0:0:0 | value : | semmle.label | value : | | file://:0:0:0:0 | value : | semmle.label | value : | | file://:0:0:0:0 | value : | semmle.label | value : | +| file://:0:0:0:0 | value : | semmle.label | value : | | testCoreData2.swift:23:13:23:13 | value : | semmle.label | value : | | testCoreData2.swift:37:2:37:2 | [post] obj | semmle.label | [post] obj | | testCoreData2.swift:37:2:37:2 | [post] obj [myValue] : | semmle.label | [post] obj [myValue] : | @@ -421,19 +428,23 @@ nodes | testGRDB.swift:210:85:210:85 | password : | semmle.label | password : | | testGRDB.swift:212:98:212:107 | [...] | semmle.label | [...] | | testGRDB.swift:212:99:212:99 | password : | semmle.label | password : | -| testRealm.swift:16:6:16:6 | value : | semmle.label | value : | -| testRealm.swift:34:2:34:2 | [post] a | semmle.label | [post] a | -| testRealm.swift:34:2:34:2 | [post] a [data] : | semmle.label | [post] a [data] : | -| testRealm.swift:34:11:34:11 | myPassword : | semmle.label | myPassword : | -| testRealm.swift:42:2:42:2 | [post] c | semmle.label | [post] c | -| testRealm.swift:42:2:42:2 | [post] c [data] : | semmle.label | [post] c [data] : | -| testRealm.swift:42:11:42:11 | myPassword : | semmle.label | myPassword : | -| testRealm.swift:52:2:52:3 | [post] ...! | semmle.label | [post] ...! | -| testRealm.swift:52:2:52:3 | [post] ...! [data] : | semmle.label | [post] ...! [data] : | -| testRealm.swift:52:12:52:12 | myPassword : | semmle.label | myPassword : | -| testRealm.swift:59:2:59:2 | [post] g | semmle.label | [post] g | -| testRealm.swift:59:2:59:2 | [post] g [data] : | semmle.label | [post] g [data] : | -| testRealm.swift:59:11:59:11 | myPassword : | semmle.label | myPassword : | +| testRealm.swift:27:6:27:6 | value : | semmle.label | value : | +| testRealm.swift:34:6:34:6 | value : | semmle.label | value : | +| testRealm.swift:41:2:41:2 | [post] a | semmle.label | [post] a | +| testRealm.swift:41:2:41:2 | [post] a [data] : | semmle.label | [post] a [data] : | +| testRealm.swift:41:11:41:11 | myPassword : | semmle.label | myPassword : | +| testRealm.swift:49:2:49:2 | [post] c | semmle.label | [post] c | +| testRealm.swift:49:2:49:2 | [post] c [data] : | semmle.label | [post] c [data] : | +| testRealm.swift:49:11:49:11 | myPassword : | semmle.label | myPassword : | +| testRealm.swift:59:2:59:3 | [post] ...! | semmle.label | [post] ...! | +| testRealm.swift:59:2:59:3 | [post] ...! [data] : | semmle.label | [post] ...! [data] : | +| testRealm.swift:59:12:59:12 | myPassword : | semmle.label | myPassword : | +| testRealm.swift:66:2:66:2 | [post] g | semmle.label | [post] g | +| testRealm.swift:66:2:66:2 | [post] g [data] : | semmle.label | [post] g [data] : | +| testRealm.swift:66:11:66:11 | myPassword : | semmle.label | myPassword : | +| testRealm.swift:73:2:73:2 | [post] h | semmle.label | [post] h | +| testRealm.swift:73:2:73:2 | [post] h [password] : | semmle.label | [post] h [password] : | +| testRealm.swift:73:15:73:15 | myPassword : | semmle.label | myPassword : | subpaths | testCoreData2.swift:43:35:43:35 | bankAccountNo : | testCoreData2.swift:23:13:23:13 | value : | file://:0:0:0:0 | [post] self [notStoredBankAccountNumber] : | testCoreData2.swift:43:2:43:2 | [post] obj [notStoredBankAccountNumber] : | | testCoreData2.swift:52:41:52:41 | bankAccountNo : | testCoreData2.swift:23:13:23:13 | value : | file://:0:0:0:0 | [post] self [notStoredBankAccountNumber] : | testCoreData2.swift:52:2:52:10 | [post] ...? [notStoredBankAccountNumber] : | @@ -449,10 +460,11 @@ subpaths | testCoreData2.swift:98:18:98:18 | d [value] : | testCoreData2.swift:70:9:70:9 | self [value] : | file://:0:0:0:0 | .value : | testCoreData2.swift:98:18:98:20 | .value : | | testCoreData2.swift:104:18:104:18 | e : | testCoreData2.swift:70:9:70:9 | self : | file://:0:0:0:0 | .value : | testCoreData2.swift:104:18:104:20 | .value : | | testCoreData2.swift:105:18:105:18 | e : | testCoreData2.swift:71:9:71:9 | self : | file://:0:0:0:0 | .value2 : | testCoreData2.swift:105:18:105:20 | .value2 : | -| testRealm.swift:34:11:34:11 | myPassword : | testRealm.swift:16:6:16:6 | value : | file://:0:0:0:0 | [post] self [data] : | testRealm.swift:34:2:34:2 | [post] a [data] : | -| testRealm.swift:42:11:42:11 | myPassword : | testRealm.swift:16:6:16:6 | value : | file://:0:0:0:0 | [post] self [data] : | testRealm.swift:42:2:42:2 | [post] c [data] : | -| testRealm.swift:52:12:52:12 | myPassword : | testRealm.swift:16:6:16:6 | value : | file://:0:0:0:0 | [post] self [data] : | testRealm.swift:52:2:52:3 | [post] ...! [data] : | -| testRealm.swift:59:11:59:11 | myPassword : | testRealm.swift:16:6:16:6 | value : | file://:0:0:0:0 | [post] self [data] : | testRealm.swift:59:2:59:2 | [post] g [data] : | +| testRealm.swift:41:11:41:11 | myPassword : | testRealm.swift:27:6:27:6 | value : | file://:0:0:0:0 | [post] self [data] : | testRealm.swift:41:2:41:2 | [post] a [data] : | +| testRealm.swift:49:11:49:11 | myPassword : | testRealm.swift:27:6:27:6 | value : | file://:0:0:0:0 | [post] self [data] : | testRealm.swift:49:2:49:2 | [post] c [data] : | +| testRealm.swift:59:12:59:12 | myPassword : | testRealm.swift:27:6:27:6 | value : | file://:0:0:0:0 | [post] self [data] : | testRealm.swift:59:2:59:3 | [post] ...! [data] : | +| testRealm.swift:66:11:66:11 | myPassword : | testRealm.swift:27:6:27:6 | value : | file://:0:0:0:0 | [post] self [data] : | testRealm.swift:66:2:66:2 | [post] g [data] : | +| testRealm.swift:73:15:73:15 | myPassword : | testRealm.swift:34:6:34:6 | value : | file://:0:0:0:0 | [post] self [password] : | testRealm.swift:73:2:73:2 | [post] h [password] : | #select | testCoreData2.swift:37:2:37:2 | obj | testCoreData2.swift:37:16:37:16 | bankAccountNo : | testCoreData2.swift:37:2:37:2 | [post] obj | This operation stores 'obj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:37:16:37:16 | bankAccountNo : | bankAccountNo | | testCoreData2.swift:39:2:39:2 | obj | testCoreData2.swift:39:28:39:28 | bankAccountNo : | testCoreData2.swift:39:2:39:2 | [post] obj | This operation stores 'obj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:39:28:39:28 | bankAccountNo : | bankAccountNo | @@ -542,7 +554,8 @@ subpaths | testGRDB.swift:208:80:208:89 | [...] | testGRDB.swift:208:81:208:81 | password : | testGRDB.swift:208:80:208:89 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:208:81:208:81 | password : | password | | testGRDB.swift:210:84:210:93 | [...] | testGRDB.swift:210:85:210:85 | password : | testGRDB.swift:210:84:210:93 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:210:85:210:85 | password : | password | | testGRDB.swift:212:98:212:107 | [...] | testGRDB.swift:212:99:212:99 | password : | testGRDB.swift:212:98:212:107 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:212:99:212:99 | password : | password | -| testRealm.swift:34:2:34:2 | a | testRealm.swift:34:11:34:11 | myPassword : | testRealm.swift:34:2:34:2 | [post] a | This operation stores 'a' in a database. It may contain unencrypted sensitive data from $@. | testRealm.swift:34:11:34:11 | myPassword : | myPassword | -| testRealm.swift:42:2:42:2 | c | testRealm.swift:42:11:42:11 | myPassword : | testRealm.swift:42:2:42:2 | [post] c | This operation stores 'c' in a database. It may contain unencrypted sensitive data from $@. | testRealm.swift:42:11:42:11 | myPassword : | myPassword | -| testRealm.swift:52:2:52:3 | ...! | testRealm.swift:52:12:52:12 | myPassword : | testRealm.swift:52:2:52:3 | [post] ...! | This operation stores '...!' in a database. It may contain unencrypted sensitive data from $@. | testRealm.swift:52:12:52:12 | myPassword : | myPassword | -| testRealm.swift:59:2:59:2 | g | testRealm.swift:59:11:59:11 | myPassword : | testRealm.swift:59:2:59:2 | [post] g | This operation stores 'g' in a database. It may contain unencrypted sensitive data from $@. | testRealm.swift:59:11:59:11 | myPassword : | myPassword | +| testRealm.swift:41:2:41:2 | a | testRealm.swift:41:11:41:11 | myPassword : | testRealm.swift:41:2:41:2 | [post] a | This operation stores 'a' in a database. It may contain unencrypted sensitive data from $@. | testRealm.swift:41:11:41:11 | myPassword : | myPassword | +| testRealm.swift:49:2:49:2 | c | testRealm.swift:49:11:49:11 | myPassword : | testRealm.swift:49:2:49:2 | [post] c | This operation stores 'c' in a database. It may contain unencrypted sensitive data from $@. | testRealm.swift:49:11:49:11 | myPassword : | myPassword | +| testRealm.swift:59:2:59:3 | ...! | testRealm.swift:59:12:59:12 | myPassword : | testRealm.swift:59:2:59:3 | [post] ...! | This operation stores '...!' in a database. It may contain unencrypted sensitive data from $@. | testRealm.swift:59:12:59:12 | myPassword : | myPassword | +| testRealm.swift:66:2:66:2 | g | testRealm.swift:66:11:66:11 | myPassword : | testRealm.swift:66:2:66:2 | [post] g | This operation stores 'g' in a database. It may contain unencrypted sensitive data from $@. | testRealm.swift:66:11:66:11 | myPassword : | myPassword | +| testRealm.swift:73:2:73:2 | h | testRealm.swift:73:15:73:15 | myPassword : | testRealm.swift:73:2:73:2 | [post] h | This operation stores 'h' in a database. It may contain unencrypted sensitive data from $@. | testRealm.swift:73:15:73:15 | myPassword : | myPassword | diff --git a/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected b/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected index 4f0e89775e4..ef794d4004a 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected +++ b/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected @@ -111,10 +111,13 @@ | testGRDB.swift:208:81:208:81 | password | label:password, type:credential | | testGRDB.swift:210:85:210:85 | password | label:password, type:credential | | testGRDB.swift:212:99:212:99 | password | label:password, type:credential | -| testRealm.swift:34:11:34:11 | myPassword | label:myPassword, type:credential | -| testRealm.swift:42:11:42:11 | myPassword | label:myPassword, type:credential | -| testRealm.swift:52:12:52:12 | myPassword | label:myPassword, type:credential | -| testRealm.swift:59:11:59:11 | myPassword | label:myPassword, type:credential | +| testRealm.swift:31:20:31:20 | .password | label:password, type:credential | +| testRealm.swift:41:11:41:11 | myPassword | label:myPassword, type:credential | +| testRealm.swift:49:11:49:11 | myPassword | label:myPassword, type:credential | +| testRealm.swift:59:12:59:12 | myPassword | label:myPassword, type:credential | +| testRealm.swift:66:11:66:11 | myPassword | label:myPassword, type:credential | +| testRealm.swift:73:2:73:4 | .password | label:password, type:credential | +| testRealm.swift:73:15:73:15 | myPassword | label:myPassword, type:credential | | testSend.swift:29:19:29:19 | passwordPlain | label:passwordPlain, type:credential | | testSend.swift:33:19:33:19 | passwordPlain | label:passwordPlain, type:credential | | testSend.swift:45:13:45:13 | password | label:password, type:credential | diff --git a/swift/ql/test/query-tests/Security/CWE-311/testRealm.swift b/swift/ql/test/query-tests/Security/CWE-311/testRealm.swift index 61ed4d9c2b6..8bcf9ce83f5 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/testRealm.swift +++ b/swift/ql/test/query-tests/Security/CWE-311/testRealm.swift @@ -10,12 +10,6 @@ class RealmSwiftObject { typealias Object = RealmSwiftObject -class MyRealmSwiftObject : RealmSwiftObject { - override init() { data = "" } - - var data: String -} - class Realm { func add(_ object: Object, update: UpdatePolicy = .error) {} @@ -27,7 +21,20 @@ class Realm { // --- tests --- -func test1(realm : Realm, myPassword : String, myHashedPassword : String) { +class MyRealmSwiftObject : RealmSwiftObject { + override init() { data = "" } + + var data: String +} + +class MyRealmSwiftObject2 : Object { + override init() { password = "" } + + var username: String? + var password: String? +} + +func test1(realm : Realm, myUsername: String, myPassword : String, myHashedPassword : String) { // add objects (within a transaction) ... let a = MyRealmSwiftObject() @@ -58,6 +65,13 @@ func test1(realm : Realm, myPassword : String, myHashedPassword : String) { g.data = "" // GOOD (not sensitive) g.data = myPassword // BAD g.data = "" // GOOD (not sensitive) + + // MyRealmSwiftObject2... + + let h = MyRealmSwiftObject2() + h.username = myUsername // GOOD (not sensitive) + h.password = myPassword // BAD + realm.add(h) } // limitation: its possible to configure a Realm DB to be stored encrypted, if this is done correctly diff --git a/swift/schema.py b/swift/schema.py index 2737ebf8ac4..828525627bd 100644 --- a/swift/schema.py +++ b/swift/schema.py @@ -272,8 +272,8 @@ class GenericTypeDecl(GenericContext, TypeDecl): class ModuleDecl(TypeDecl): is_builtin_module: predicate | doc("this module is the built-in one") is_system_module: predicate | doc("this module is a system one") - imported_modules: list["ModuleDecl"] - exported_modules: list["ModuleDecl"] + imported_modules: set["ModuleDecl"] + exported_modules: set["ModuleDecl"] class SubscriptDecl(AbstractStorageDecl, GenericContext): params: list[ParamDecl] | child