diff --git a/.github/workflows/check-qldoc.yml b/.github/workflows/check-qldoc.yml new file mode 100644 index 00000000000..b2c6e889181 --- /dev/null +++ b/.github/workflows/check-qldoc.yml @@ -0,0 +1,50 @@ +name: "Check QLdoc coverage" + +on: + pull_request: + paths: + - "*/ql/lib/**" + - .github/workflows/check-qldoc.yml + branches: + - main + - "rc/*" + +jobs: + qldoc: + runs-on: ubuntu-latest + + steps: + - name: Install CodeQL + run: | + gh extension install github/gh-codeql + gh codeql set-channel nightly + gh codeql version + env: + GITHUB_TOKEN: ${{ github.token }} + + - uses: actions/checkout@v2 + with: + fetch-depth: 2 + + - name: Check QLdoc coverage + shell: bash + run: | + EXIT_CODE=0 + changed_lib_packs="$(git diff --name-only --diff-filter=ACMRT HEAD^ HEAD | { grep -o '^[a-z]*/ql/lib' || true; } | sort -u)" + for pack_dir in ${changed_lib_packs}; do + lang="${pack_dir%/ql/lib}" + gh codeql generate library-doc-coverage --output="${RUNNER_TEMP}/${lang}-current.txt" --dir="${pack_dir}" + done + git checkout HEAD^ + for pack_dir in ${changed_lib_packs}; do + lang="${pack_dir%/ql/lib}" + gh codeql generate library-doc-coverage --output="${RUNNER_TEMP}/${lang}-baseline.txt" --dir="${pack_dir}" + awk -F, '{gsub(/"/,""); if ($4==0 && $6=="public") print "\""$3"\"" }' "${RUNNER_TEMP}/${lang}-current.txt" | sort -u > "${RUNNER_TEMP}/current-undocumented.txt" + awk -F, '{gsub(/"/,""); if ($4==0 && $6=="public") print "\""$3"\"" }' "${RUNNER_TEMP}/${lang}-baseline.txt" | sort -u > "${RUNNER_TEMP}/baseline-undocumented.txt" + UNDOCUMENTED="$(grep -f <(comm -13 "${RUNNER_TEMP}/baseline-undocumented.txt" "${RUNNER_TEMP}/current-undocumented.txt") "${RUNNER_TEMP}/${lang}-current.txt" || true)" + if [ -n "$UNDOCUMENTED" ]; then + echo "$UNDOCUMENTED" | awk -F, '{gsub(/"/,""); print "::warning file='"${pack_dir}"'/"$1",line="$2"::Missing QLdoc for "$5, $3 }' + EXIT_CODE=1 + fi + done + exit "${EXIT_CODE}" diff --git a/config/blame-deprecations.mjs b/config/blame-deprecations.mjs new file mode 100644 index 00000000000..82cc1f593c7 --- /dev/null +++ b/config/blame-deprecations.mjs @@ -0,0 +1,58 @@ +import fs from "fs"; +import path from "path"; +import cp from "child_process"; +function* walk(dir) { + for (const file of fs.readdirSync(dir)) { + const filePath = path.join(dir, file); + if (fs.statSync(filePath).isDirectory()) { + yield* walk(filePath); + } else { + yield filePath; + } + } +} + +function* deprecatedFiles(dir) { + for (const file of walk(dir)) { + if (file.endsWith(".ql") || file.endsWith(".qll")) { + const contents = fs.readFileSync(file, "utf8"); + if (/\sdeprecated\s/.test(contents)) { + yield file; + } + } + } +} + +const blameRegExp = + /^(\^?\w+)\s.+\s+(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} (?:\+|-)\d{4})\s+(\d+)\).*$/; + +function* deprecationMessages(dir) { + for (const file of deprecatedFiles(dir)) { + const blame = cp.execFileSync("git", ["blame", "--", file]); + const lines = blame.toString().split("\n"); + for (let i = 0; i < lines.length; i++) { + const line = lines[i]; + if (line.includes(" deprecated ")) { + try { + const [_, sha, time, lineNumber] = line.match(blameRegExp); + const date = new Date(time); + // check if it's within the last 14 months (a year, plus 2 months for safety, in case a PR was delayed) + if (date.getTime() >= Date.now() - 14 * 31 * 24 * 60 * 60 * 1000) { + continue; + } + const message = `${file}:${lineNumber} was last updated on ${date.getFullYear()}-${date.getMonth()}-${date.getDate()}`; + yield [message, date]; + } catch (e) { + console.log(e); + console.log("----"); + console.log(line); + console.log("----"); + process.exit(0); + } + } + } + } +} +[...deprecationMessages(".")] + .sort((a, b) => a[1].getTime() - b[1].getTime()) + .forEach((msg) => console.log(msg[0])); diff --git a/config/identical-files.json b/config/identical-files.json index daf764f15c6..ff4129d9776 100644 --- a/config/identical-files.json +++ b/config/identical-files.json @@ -73,6 +73,14 @@ "java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll", "csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll" ], + "Model as Data Generation Java/C# - Utils": [ + "java/ql/src/utils/model-generator/ModelGeneratorUtils.qll", + "csharp/ql/src/utils/model-generator/ModelGeneratorUtils.qll" + ], + "Model as Data Generation Java/C# - SummaryModels": [ + "java/ql/src/utils/model-generator/CaptureSummaryModels.qll", + "csharp/ql/src/utils/model-generator/CaptureSummaryModels.qll" + ], "Sign Java/C#": [ "java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/Sign.qll", "csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/Sign.qll" @@ -426,7 +434,6 @@ "python/ql/src/Lexical/CommentedOutCodeMetricOverview.inc.qhelp" ], "FLinesOfDuplicatedCodeCommon.inc.qhelp": [ - "cpp/ql/src/Metrics/Files/FLinesOfDuplicatedCodeCommon.inc.qhelp", "java/ql/src/Metrics/Files/FLinesOfDuplicatedCodeCommon.inc.qhelp", "javascript/ql/src/Metrics/FLinesOfDuplicatedCodeCommon.inc.qhelp", "python/ql/src/Metrics/FLinesOfDuplicatedCodeCommon.inc.qhelp" @@ -514,4 +521,4 @@ "ruby/ql/src/queries/security/cwe-020/HostnameRegexpShared.qll", "python/ql/src/Security/CWE-020/HostnameRegexpShared.qll" ] -} +} \ No newline at end of file diff --git a/cpp/downgrades/e9a518baf14f4322ac243578a8e1391386ff030f/old.dbscheme b/cpp/downgrades/e9a518baf14f4322ac243578a8e1391386ff030f/old.dbscheme new file mode 100644 index 00000000000..e9a518baf14 --- /dev/null +++ b/cpp/downgrades/e9a518baf14f4322ac243578a8e1391386ff030f/old.dbscheme @@ -0,0 +1,2096 @@ + +/** + * 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 @macroinvocations.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 + | 2 = constructor + | 3 = destructor + | 4 = conversion + | 5 = operator + | 6 = builtin // 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 +); + +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 = error + | 2 = unknown + | 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 = __int8 // Microsoft-specific + | 21 = __int16 // Microsoft-specific + | 22 = __int32 // Microsoft-specific + | 23 = __int64 // Microsoft-specific + | 24 = float + | 25 = double + | 26 = long_double + | 27 = _Complex_float // C99-specific + | 28 = _Complex_double // C99-specific + | 29 = _Complex_long double // C99-specific + | 30 = _Imaginary_float // C99-specific + | 31 = _Imaginary_double // C99-specific + | 32 = _Imaginary_long_double // C99-specific + | 33 = wchar_t // Microsoft-specific + | 34 = decltype_nullptr // C++11 + | 35 = __int128 + | 36 = unsigned___int128 + | 37 = signed___int128 + | 38 = __float128 + | 39 = _Complex___float128 + | 40 = _Decimal32 + | 41 = _Decimal64 + | 42 = _Decimal128 + | 43 = char16_t + | 44 = char32_t + | 45 = _Float32 + | 46 = _Float32x + | 47 = _Float64 + | 48 = _Float64x + | 49 = _Float128 + | 50 = _Float128x + | 51 = char8_t + ; +*/ +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 EDG frontend. See symbol_ref.h there. + 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 +; + +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_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 + +/* + 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 +); + +/** + * 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 // EDG 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 +; + +@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 + ; + +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_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_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 +); + +#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/e9a518baf14f4322ac243578a8e1391386ff030f/semmlecode.cpp.dbscheme b/cpp/downgrades/e9a518baf14f4322ac243578a8e1391386ff030f/semmlecode.cpp.dbscheme new file mode 100644 index 00000000000..bb0f279f2ac --- /dev/null +++ b/cpp/downgrades/e9a518baf14f4322ac243578a8e1391386ff030f/semmlecode.cpp.dbscheme @@ -0,0 +1,2096 @@ + +/** + * 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 @macroinvocations.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 + | 2 = constructor + | 3 = destructor + | 4 = conversion + | 5 = operator + | 6 = builtin // 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 +); + +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 = error + | 2 = unknown + | 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 = __int8 // Microsoft-specific + | 21 = __int16 // Microsoft-specific + | 22 = __int32 // Microsoft-specific + | 23 = __int64 // Microsoft-specific + | 24 = float + | 25 = double + | 26 = long_double + | 27 = _Complex_float // C99-specific + | 28 = _Complex_double // C99-specific + | 29 = _Complex_long double // C99-specific + | 30 = _Imaginary_float // C99-specific + | 31 = _Imaginary_double // C99-specific + | 32 = _Imaginary_long_double // C99-specific + | 33 = wchar_t // Microsoft-specific + | 34 = decltype_nullptr // C++11 + | 35 = __int128 + | 36 = unsigned___int128 + | 37 = signed___int128 + | 38 = __float128 + | 39 = _Complex___float128 + | 40 = _Decimal32 + | 41 = _Decimal64 + | 42 = _Decimal128 + | 43 = char16_t + | 44 = char32_t + | 45 = _Float32 + | 46 = _Float32x + | 47 = _Float64 + | 48 = _Float64x + | 49 = _Float128 + | 50 = _Float128x + | 51 = char8_t + ; +*/ +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, + unique 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 EDG frontend. See symbol_ref.h there. + 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 +; + +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_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 + +/* + 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 +); + +/** + * 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 // EDG 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 +; + +@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 + ; + +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_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_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 +); + +#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/e9a518baf14f4322ac243578a8e1391386ff030f/upgrade.properties b/cpp/downgrades/e9a518baf14f4322ac243578a8e1391386ff030f/upgrade.properties new file mode 100644 index 00000000000..000fa581cfa --- /dev/null +++ b/cpp/downgrades/e9a518baf14f4322ac243578a8e1391386ff030f/upgrade.properties @@ -0,0 +1,2 @@ +description: Remove uniqueness constraint from the uuid property +compatibility: full diff --git a/cpp/ql/lib/CHANGELOG.md b/cpp/ql/lib/CHANGELOG.md index abf6a3e48e7..d4603cef8b4 100644 --- a/cpp/ql/lib/CHANGELOG.md +++ b/cpp/ql/lib/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.0.11 + +### Minor Analysis Improvements + +* Many queries now support structured bindings, as structured bindings are now handled in the IR translation. + ## 0.0.10 ### New Features @@ -6,6 +12,7 @@ ## 0.0.9 + ## 0.0.8 ### Deprecated APIs diff --git a/cpp/ql/lib/DefaultOptions.qll b/cpp/ql/lib/DefaultOptions.qll index ae3ca205188..73a891bb554 100644 --- a/cpp/ql/lib/DefaultOptions.qll +++ b/cpp/ql/lib/DefaultOptions.qll @@ -54,11 +54,13 @@ class Options extends string { * * By default, this holds for `exit`, `_exit`, `abort`, `__assert_fail`, * `longjmp`, `__builtin_unreachable` and any function with a - * `noreturn` attribute. + * `noreturn` attribute or specifier. */ predicate exits(Function f) { f.getAnAttribute().hasName("noreturn") or + f.getASpecifier().hasName("noreturn") + or f.hasGlobalOrStdName([ "exit", "_exit", "abort", "__assert_fail", "longjmp", "__builtin_unreachable" ]) diff --git a/cpp/ql/lib/Options.qll b/cpp/ql/lib/Options.qll index b18aede94f2..a0a13881a94 100644 --- a/cpp/ql/lib/Options.qll +++ b/cpp/ql/lib/Options.qll @@ -39,7 +39,7 @@ class CustomOptions extends Options { * * By default, this holds for `exit`, `_exit`, `abort`, `__assert_fail`, * `longjmp`, `error`, `__builtin_unreachable` and any function with a - * `noreturn` attribute. + * `noreturn` attribute or specifier. */ override predicate exits(Function f) { Options.super.exits(f) } diff --git a/cpp/ql/lib/change-notes/2022-02-07-deleted-deprecations.md b/cpp/ql/lib/change-notes/2022-02-07-deleted-deprecations.md new file mode 100644 index 00000000000..e8da1e8e158 --- /dev/null +++ b/cpp/ql/lib/change-notes/2022-02-07-deleted-deprecations.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* All deprecated predicates/classes/modules that have been deprecated for over a year have been deleted. \ No newline at end of file diff --git a/cpp/ql/lib/change-notes/2022-02-07-deprecated-acronyms.md b/cpp/ql/lib/change-notes/2022-02-07-deprecated-acronyms.md new file mode 100644 index 00000000000..a79f286aacd --- /dev/null +++ b/cpp/ql/lib/change-notes/2022-02-07-deprecated-acronyms.md @@ -0,0 +1,5 @@ +--- +category: deprecated +--- +* Many classes/predicates/modules that had upper-case acronyms have been renamed to follow our style-guide. + The old name still exists as a deprecated alias. \ No newline at end of file diff --git a/cpp/ql/lib/change-notes/2022-03-10-template-implicit-copy.md b/cpp/ql/lib/change-notes/2022-03-10-template-implicit-copy.md new file mode 100644 index 00000000000..fe2afba6568 --- /dev/null +++ b/cpp/ql/lib/change-notes/2022-03-10-template-implicit-copy.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* `hasImplicitCopyConstructor` and `hasImplicitCopyAssignmentOperator` now correctly handle implicitly-deleted operators in templates. \ No newline at end of file diff --git a/cpp/ql/lib/change-notes/2022-03-14-c11-noreturn.md b/cpp/ql/lib/change-notes/2022-03-14-c11-noreturn.md new file mode 100644 index 00000000000..c74e1ab9820 --- /dev/null +++ b/cpp/ql/lib/change-notes/2022-03-14-c11-noreturn.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* `DefaultOptions::exits` now holds for C11 functions with the `_Noreturn` or `noreturn` specifier. diff --git a/cpp/ql/lib/change-notes/2022-03-14-taint-interface-cleanup.md b/cpp/ql/lib/change-notes/2022-03-14-taint-interface-cleanup.md new file mode 100644 index 00000000000..3481d507db3 --- /dev/null +++ b/cpp/ql/lib/change-notes/2022-03-14-taint-interface-cleanup.md @@ -0,0 +1,4 @@ +--- +category: breaking +--- +* The flow state variants of `isBarrier` and `isAdditionalFlowStep` are no longer exposed in the taint tracking library. The `isSanitizer` and `isAdditionalTaintStep` predicates should be used instead. diff --git a/cpp/ql/lib/change-notes/2022-02-24-structured-bindings-in-ir.md b/cpp/ql/lib/change-notes/released/0.0.11.md similarity index 71% rename from cpp/ql/lib/change-notes/2022-02-24-structured-bindings-in-ir.md rename to cpp/ql/lib/change-notes/released/0.0.11.md index debfa99a782..633eca26993 100644 --- a/cpp/ql/lib/change-notes/2022-02-24-structured-bindings-in-ir.md +++ b/cpp/ql/lib/change-notes/released/0.0.11.md @@ -1,4 +1,5 @@ ---- -category: minorAnalysis ---- +## 0.0.11 + +### Minor Analysis Improvements + * Many queries now support structured bindings, as structured bindings are now handled in the IR translation. diff --git a/cpp/ql/lib/codeql-pack.release.yml b/cpp/ql/lib/codeql-pack.release.yml index b740014e5ae..e679dc42092 100644 --- a/cpp/ql/lib/codeql-pack.release.yml +++ b/cpp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.10 +lastReleaseVersion: 0.0.11 diff --git a/cpp/ql/lib/cpp.qll b/cpp/ql/lib/cpp.qll index a989c9a6c9d..0a29f7b86ba 100644 --- a/cpp/ql/lib/cpp.qll +++ b/cpp/ql/lib/cpp.qll @@ -69,6 +69,4 @@ import semmle.code.cpp.Comments import semmle.code.cpp.Preprocessor import semmle.code.cpp.Iteration import semmle.code.cpp.NameQualifiers -import semmle.code.cpp.ObjectiveC -import semmle.code.cpp.exprs.ObjectiveC import DefaultOptions diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml index fe2ce10e49b..f76e7c23f6f 100644 --- a/cpp/ql/lib/qlpack.yml +++ b/cpp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-all -version: 0.0.11-dev +version: 0.0.12-dev groups: cpp dbscheme: semmlecode.cpp.dbscheme extractor: cpp diff --git a/cpp/ql/lib/semmle/code/cpp/Class.qll b/cpp/ql/lib/semmle/code/cpp/Class.qll index 64819a5e945..a91cedb9a0b 100644 --- a/cpp/ql/lib/semmle/code/cpp/Class.qll +++ b/cpp/ql/lib/semmle/code/cpp/Class.qll @@ -111,24 +111,6 @@ class Class extends UserType { result = this.getCanonicalMember(index).(TemplateVariable).getAnInstantiation() } - /** - * DEPRECATED: Use `getCanonicalMember(int)` or `getAMember(int)` instead. - * Gets the `index`th member of this class. - */ - deprecated Declaration getMember(int index) { - member(underlyingElement(this), index, unresolveElement(result)) - } - - /** - * DEPRECATED: As this includes a somewhat arbitrary number of - * template instantiations, it is unlikely to do what - * you need. - * Gets the number of members that this class has. This includes both - * templates that are in this class, and instantiations of those - * templates. - */ - deprecated int getNumMember() { result = count(this.getAMember()) } - /** * Gets a private member declared in this class, struct or union. * For template members, this may be either the template or an @@ -208,23 +190,6 @@ class Class extends UserType { */ deprecated predicate hasCopyConstructor() { this.getAMemberFunction() instanceof CopyConstructor } - /** - * Holds if this class has a copy assignment operator that is either - * explicitly declared (though possibly `= delete`) or is auto-generated, - * non-trivial and called from somewhere. - * - * DEPRECATED: There is more than one reasonable definition of what it means - * to have a copy assignment operator, and we do not want to promote one - * particular definition by naming it with this predicate. Having a copy - * assignment operator could mean that such a member is declared or defined - * in the source or that it is callable by a particular caller. For C++11, - * there's also a question of whether to include members that are defaulted - * or deleted. - */ - deprecated predicate hasCopyAssignmentOperator() { - this.getAMemberFunction() instanceof CopyAssignmentOperator - } - /** * Like accessOfBaseMember but returns multiple results if there are multiple * paths to `base` through the inheritance graph. @@ -286,6 +251,16 @@ class Class extends UserType { not this.implicitCopyConstructorDeleted() and forall(CopyConstructor cc | cc = this.getAMemberFunction() | cc.isCompilerGenerated() and not cc.isDeleted() + ) and + ( + not this instanceof ClassTemplateInstantiation + or + this.(ClassTemplateInstantiation).getTemplate().hasImplicitCopyConstructor() + ) and + ( + not this instanceof PartialClassTemplateSpecialization + or + this.(PartialClassTemplateSpecialization).getPrimaryTemplate().hasImplicitCopyConstructor() ) } @@ -301,6 +276,18 @@ class Class extends UserType { not this.implicitCopyAssignmentOperatorDeleted() and forall(CopyAssignmentOperator ca | ca = this.getAMemberFunction() | ca.isCompilerGenerated() and not ca.isDeleted() + ) and + ( + not this instanceof ClassTemplateInstantiation + or + this.(ClassTemplateInstantiation).getTemplate().hasImplicitCopyAssignmentOperator() + ) and + ( + not this instanceof PartialClassTemplateSpecialization + or + this.(PartialClassTemplateSpecialization) + .getPrimaryTemplate() + .hasImplicitCopyAssignmentOperator() ) } @@ -1070,31 +1057,6 @@ class PartialClassTemplateSpecialization extends ClassTemplateSpecialization { override string getAPrimaryQlClass() { result = "PartialClassTemplateSpecialization" } } -/** - * An "interface" is a class that only contains pure virtual functions (and contains - * at least one such function). For example: - * ``` - * class MyInterfaceClass { - * public: - * virtual void myMethod1() = 0; - * virtual void myMethod2() = 0; - * }; - * ``` - * - * DEPRECATED: This class is considered to be too specific for general usage. - */ -deprecated class Interface extends Class { - Interface() { - forex(Declaration m | - m.getDeclaringType() = this.getABaseClass*() and not compgenerated(unresolveElement(m)) - | - m instanceof PureVirtualFunction - ) - } - - override string getAPrimaryQlClass() { result = "Interface" } -} - /** * A class/struct derivation that is virtual. For example the derivation in * the following code is a `VirtualClassDerivation`: diff --git a/cpp/ql/lib/semmle/code/cpp/Element.qll b/cpp/ql/lib/semmle/code/cpp/Element.qll index 9273d1b31bf..a1afd61ded1 100644 --- a/cpp/ql/lib/semmle/code/cpp/Element.qll +++ b/cpp/ql/lib/semmle/code/cpp/Element.qll @@ -55,9 +55,6 @@ class ElementBase extends @element { cached string toString() { none() } - /** DEPRECATED: use `getAPrimaryQlClass` instead. */ - deprecated string getCanonicalQLClass() { result = this.getAPrimaryQlClass() } - /** * Gets a comma-separated list of the names of the primary CodeQL classes to which this element belongs. */ @@ -91,13 +88,6 @@ class Element extends ElementBase { */ predicate fromSource() { this.getFile().fromSource() } - /** - * Holds if this element may be from a library. - * - * DEPRECATED: always true. - */ - deprecated predicate fromLibrary() { this.getFile().fromLibrary() } - /** Gets the primary location of this element. */ Location getLocation() { none() } diff --git a/cpp/ql/lib/semmle/code/cpp/File.qll b/cpp/ql/lib/semmle/code/cpp/File.qll index 3b72533b4f4..398633edbd8 100644 --- a/cpp/ql/lib/semmle/code/cpp/File.qll +++ b/cpp/ql/lib/semmle/code/cpp/File.qll @@ -196,31 +196,11 @@ class Folder extends Container, @folder { */ deprecated string getName() { folders(underlyingElement(this), result) } - /** - * DEPRECATED: use `getAbsolutePath` instead. - * Holds if this element is named `name`. - */ - deprecated predicate hasName(string name) { name = this.getName() } - - /** - * DEPRECATED: use `getAbsolutePath` instead. - * Gets the full name of this folder. - */ - deprecated string getFullName() { result = this.getName() } - /** * DEPRECATED: use `getBaseName` instead. * Gets the last part of the folder name. */ deprecated string getShortName() { result = this.getBaseName() } - - /** - * DEPRECATED: use `getParentContainer` instead. - * Gets the parent folder. - */ - deprecated Folder getParent() { - containerparent(unresolveElement(result), underlyingElement(this)) - } } /** @@ -308,13 +288,6 @@ class File extends Container, @file { */ override predicate fromSource() { numlines(underlyingElement(this), _, _, _) } - /** - * Holds if this file may be from a library. - * - * DEPRECATED: For historical reasons this is true for any file. - */ - deprecated override predicate fromLibrary() { any() } - /** Gets the metric file. */ MetricFile getMetrics() { result = this } @@ -428,25 +401,3 @@ class CppFile extends File { override string getAPrimaryQlClass() { result = "CppFile" } } - -/** - * DEPRECATED: Objective-C is no longer supported. - * An Objective C source file, as determined by file extension. - * - * For the related notion of whether a file is compiled as Objective C - * code, use `File.compiledAsObjC`. - */ -deprecated class ObjCFile extends File { - ObjCFile() { none() } -} - -/** - * DEPRECATED: Objective-C is no longer supported. - * An Objective C++ source file, as determined by file extension. - * - * For the related notion of whether a file is compiled as Objective C++ - * code, use `File.compiledAsObjCpp`. - */ -deprecated class ObjCppFile extends File { - ObjCppFile() { none() } -} diff --git a/cpp/ql/lib/semmle/code/cpp/Location.qll b/cpp/ql/lib/semmle/code/cpp/Location.qll index 92b358d474c..cef6482496b 100644 --- a/cpp/ql/lib/semmle/code/cpp/Location.qll +++ b/cpp/ql/lib/semmle/code/cpp/Location.qll @@ -105,25 +105,6 @@ class Location extends @location { } } -/** - * DEPRECATED: Use `Location` instead. - * A location of an element. Not used for expressions or statements, which - * instead use LocationExpr and LocationStmt respectively. - */ -deprecated library class LocationDefault extends Location, @location_default { } - -/** - * DEPRECATED: Use `Location` instead. - * A location of a statement. - */ -deprecated library class LocationStmt extends Location, @location_stmt { } - -/** - * DEPRECATED: Use `Location` instead. - * A location of an expression. - */ -deprecated library class LocationExpr extends Location, @location_expr { } - /** * Gets the length of the longest line in file `f`. */ diff --git a/cpp/ql/lib/semmle/code/cpp/Macro.qll b/cpp/ql/lib/semmle/code/cpp/Macro.qll index 6d61ae7be7c..4378cec4857 100644 --- a/cpp/ql/lib/semmle/code/cpp/Macro.qll +++ b/cpp/ql/lib/semmle/code/cpp/Macro.qll @@ -30,16 +30,6 @@ class Macro extends PreprocessorDirective, @ppd_define { else result = "#define " + this.getHead() + " " + this.getBody() } - /** - * Holds if the body of the macro starts with an unmatched closing - * parenthesis. For example: - * - * #define RPAREN() ) - * - * DEPRECATED: This predicate has a misleading name. - */ - deprecated predicate isFunctionLike() { this.getBody().regexpMatch("[^(]*\\).*") } - /** * Gets the name of the macro. For example, `MAX` in * `#define MAX(x,y) (((x)>(y))?(x):(y))`. @@ -261,46 +251,6 @@ class MacroInvocation extends MacroAccess { string getExpandedArgument(int i) { macro_argument_expanded(underlyingElement(this), i, result) } } -/** - * A top-level expression generated by a macro invocation. - * - * DEPRECATED: Use `MacroInvocation.getExpr()` directly to get an - * expression generated at the top-level of a macro invocation. Use - * `MacroInvocation.getAnAffectedElement()` to get any element generated - * by a macro invocation. - */ -deprecated class MacroInvocationExpr extends Expr { - MacroInvocationExpr() { exists(MacroInvocation i | this = i.getExpr()) } - - /** - * Gets the macro invocation of which this is the top-level expression. - */ - MacroInvocation getInvocation() { result.getExpr() = this } - - /** Gets the name of the invoked macro. */ - string getMacroName() { result = this.getInvocation().getMacroName() } -} - -/** - * A top-level statement generated by a macro invocation. - * - * DEPRECATED: Use `MacroInvocation.getStmt()` directly to get a - * statement generated at the top-level of a macro invocation. Use - * `MacroInvocation.getAnAffectedElement()` to get any element generated - * by a macro invocation. - */ -deprecated class MacroInvocationStmt extends Stmt { - MacroInvocationStmt() { exists(MacroInvocation i | this = i.getStmt()) } - - /** - * Gets the macro invocation of which this is the top-level statement. - */ - MacroInvocation getInvocation() { result.getStmt() = this } - - /** Gets the name of the invoked macro. */ - string getMacroName() { result = this.getInvocation().getMacroName() } -} - /** Holds if `l` is the location of a macro. */ predicate macroLocation(Location l) { macrolocationbind(_, l) } diff --git a/cpp/ql/lib/semmle/code/cpp/MemberFunction.qll b/cpp/ql/lib/semmle/code/cpp/MemberFunction.qll index 03b1704549f..6243104c2a3 100644 --- a/cpp/ql/lib/semmle/code/cpp/MemberFunction.qll +++ b/cpp/ql/lib/semmle/code/cpp/MemberFunction.qll @@ -233,40 +233,6 @@ class ImplicitConversionFunction extends MemberFunction { Type getDestType() { none() } // overridden in subclasses } -/** - * DEPRECATED: as of C++11 this class does not correspond perfectly with the - * language definition of a converting constructor. - * - * A C++ constructor that also defines an implicit conversion. For example the - * function `MyClass` in the following code is a `ConversionConstructor`: - * ``` - * class MyClass { - * public: - * MyClass(const MyOtherClass &from) { - * ... - * } - * }; - * ``` - */ -deprecated class ConversionConstructor extends Constructor, ImplicitConversionFunction { - ConversionConstructor() { - strictcount(Parameter p | p = this.getAParameter() and not p.hasInitializer()) = 1 and - not this.hasSpecifier("explicit") - } - - override string getAPrimaryQlClass() { - not this instanceof CopyConstructor and - not this instanceof MoveConstructor and - result = "ConversionConstructor" - } - - /** Gets the type this `ConversionConstructor` takes as input. */ - override Type getSourceType() { result = this.getParameter(0).getType() } - - /** Gets the type this `ConversionConstructor` is a constructor of. */ - override Type getDestType() { result = this.getDeclaringType() } -} - private predicate hasCopySignature(MemberFunction f) { f.getParameter(0).getUnspecifiedType().(LValueReferenceType).getBaseType() = f.getDeclaringType() } diff --git a/cpp/ql/lib/semmle/code/cpp/Namespace.qll b/cpp/ql/lib/semmle/code/cpp/Namespace.qll index 47ebc9d35c5..129e1449c32 100644 --- a/cpp/ql/lib/semmle/code/cpp/Namespace.qll +++ b/cpp/ql/lib/semmle/code/cpp/Namespace.qll @@ -86,13 +86,6 @@ class Namespace extends NameQualifyingElement, @namespace { /** Holds if this namespace may be from source. */ override predicate fromSource() { this.getADeclaration().fromSource() } - /** - * Holds if this namespace is in a library. - * - * DEPRECATED: never holds. - */ - deprecated override predicate fromLibrary() { not this.fromSource() } - /** Gets the metric namespace. */ MetricNamespace getMetrics() { result = this } @@ -233,11 +226,6 @@ class GlobalNamespace extends Namespace { override Namespace getParentNamespace() { none() } - /** - * DEPRECATED: use `getName()`. - */ - deprecated string getFullName() { result = this.getName() } - override string getFriendlyName() { result = "(global namespace)" } } diff --git a/cpp/ql/lib/semmle/code/cpp/ObjectiveC.qll b/cpp/ql/lib/semmle/code/cpp/ObjectiveC.qll deleted file mode 100644 index 17da273d5a7..00000000000 --- a/cpp/ql/lib/semmle/code/cpp/ObjectiveC.qll +++ /dev/null @@ -1,196 +0,0 @@ -/** - * DEPRECATED: Objective-C is no longer supported. - */ - -import semmle.code.cpp.Class -private import semmle.code.cpp.internal.ResolveClass - -/** - * DEPRECATED: Objective-C is no longer supported. - * An Objective C class. - */ -deprecated class ObjectiveClass extends Class { - ObjectiveClass() { none() } -} - -/** - * DEPRECATED: Objective-C is no longer supported. - * An Objective C protocol. - */ -deprecated class Protocol extends Class { - Protocol() { none() } - - /** - * Holds if the type implements the protocol, either because the type - * itself does, or because it is a type conforming to the protocol. - */ - predicate isImplementedBy(Type t) { none() } -} - -/** - * DEPRECATED: Objective-C is no longer supported. - * A type which conforms to a protocol. Use `getAProtocol` to get a - * protocol that this type conforms to. - */ -deprecated class TypeConformingToProtocol extends DerivedType { - TypeConformingToProtocol() { none() } - - /** Gets a protocol that this type conforms to. */ - Protocol getAProtocol() { none() } - - /** Gets the size of this type. */ - override int getSize() { none() } - - override int getAlignment() { none() } -} - -/** - * DEPRECATED: Objective-C is no longer supported. - * An Objective C `@autoreleasepool` statement, for example - * `@autoreleasepool { int x; int y; }`. - */ -deprecated class AutoReleasePoolStmt extends Stmt { - AutoReleasePoolStmt() { none() } - - override string toString() { none() } - - /** Gets the body statement of this `@autoreleasepool` statement. */ - Stmt getStmt() { none() } - - override predicate mayBeImpure() { none() } - - override predicate mayBeGloballyImpure() { none() } -} - -/** - * DEPRECATED: Objective-C is no longer supported. - * An Objective C `@synchronized statement`, for example - * `@synchronized (x) { [x complicationOperation]; }`. - */ -deprecated class SynchronizedStmt extends Stmt { - SynchronizedStmt() { none() } - - override string toString() { none() } - - /** Gets the expression which gives the object to be locked. */ - Expr getLockedObject() { none() } - - /** Gets the body statement of this `@synchronized` statement. */ - Stmt getStmt() { none() } -} - -/** - * DEPRECATED: Objective-C is no longer supported. - * An Objective C for-in statement. - */ -deprecated class ForInStmt extends Loop { - ForInStmt() { none() } - - /** - * Gets the condition expression of the `while` statement that the - * `for...in` statement desugars into. - */ - override Expr getCondition() { none() } - - override Expr getControllingExpr() { none() } - - /** Gets the collection that the loop iterates over. */ - Expr getCollection() { none() } - - /** Gets the body of the loop. */ - override Stmt getStmt() { none() } - - override string toString() { none() } -} - -/** - * DEPRECATED: Objective-C is no longer supported. - * An Objective C category or class extension. - */ -deprecated class Category extends Class { - Category() { none() } -} - -/** - * DEPRECATED: Objective-C is no longer supported. - * An Objective C class extension. - */ -deprecated class ClassExtension extends Category { - ClassExtension() { none() } -} - -/** - * DEPRECATED: Objective-C is no longer supported. - * An Objective C try statement. - */ -deprecated class ObjcTryStmt extends TryStmt { - ObjcTryStmt() { none() } - - override string toString() { none() } - - /** Gets the finally clause of this try statement, if any. */ - FinallyBlock getFinallyClause() { none() } -} - -/** - * DEPRECATED: Objective-C is no longer supported. - * An Objective C `@finally` block. - */ -deprecated class FinallyBlock extends BlockStmt { - FinallyBlock() { none() } - - /** Gets the try statement corresponding to this finally block. */ - ObjcTryStmt getTryStmt() { none() } -} - -/** - * DEPRECATED: Objective-C is no longer supported. - * An Objective C `@property`. - */ -deprecated class Property extends Declaration { - Property() { none() } - - /** Gets the name of this property. */ - override string getName() { none() } - - /** - * Gets nothing (provided for compatibility with Declaration). - * - * For the attribute list following the `@property` keyword, use - * `getAnAttribute()`. - */ - override Specifier getASpecifier() { none() } - - /** - * Gets an attribute of this property (such as `readonly`, `nonatomic`, - * or `getter=isEnabled`). - */ - Attribute getAnAttribute() { none() } - - override Location getADeclarationLocation() { result = getLocation() } - - override Location getDefinitionLocation() { result = getLocation() } - - override Location getLocation() { none() } - - /** Gets the type of this property. */ - Type getType() { none() } - - /** - * Gets the instance method which is called to get the value of this - * property. - */ - MemberFunction getGetter() { none() } - - /** - * Gets the instance method which is called to set the value of this - * property (if it is a writable property). - */ - MemberFunction getSetter() { none() } - - /** - * Gets the instance variable which stores the property value (if this - * property was explicitly or automatically `@synthesize`d). - */ - MemberVariable getInstanceVariable() { none() } -} diff --git a/cpp/ql/lib/semmle/code/cpp/Parameter.qll b/cpp/ql/lib/semmle/code/cpp/Parameter.qll index 47b77b542c1..814fa734408 100644 --- a/cpp/ql/lib/semmle/code/cpp/Parameter.qll +++ b/cpp/ql/lib/semmle/code/cpp/Parameter.qll @@ -95,22 +95,6 @@ class Parameter extends LocalScopeVariable, @parameter { else result = this.getADeclarationEntry() } - /** - * Gets the name of this parameter in the given block (which should be - * the body of a function with which the parameter is associated). - * - * DEPRECATED: this method was used in a previous implementation of - * getName, but is no longer in use. - */ - deprecated string getNameInBlock(BlockStmt b) { - exists(ParameterDeclarationEntry pde | - pde.getFunctionDeclarationEntry().getBlock() = b and - this.getFunction().getBlock() = b and - pde.getVariable() = this and - result = pde.getName() - ) - } - /** * Holds if this parameter has a name. * diff --git a/cpp/ql/lib/semmle/code/cpp/Print.qll b/cpp/ql/lib/semmle/code/cpp/Print.qll index 64ae5b960d1..5df8f087689 100644 --- a/cpp/ql/lib/semmle/code/cpp/Print.qll +++ b/cpp/ql/lib/semmle/code/cpp/Print.qll @@ -8,9 +8,9 @@ private import PrintAST private predicate shouldPrintDeclaration(Declaration decl) { not decl instanceof Function or - not exists(PrintASTConfiguration c) + not exists(PrintAstConfiguration c) or - exists(PrintASTConfiguration config | config.shouldPrintFunction(decl)) + exists(PrintAstConfiguration config | config.shouldPrintFunction(decl)) } /** diff --git a/cpp/ql/lib/semmle/code/cpp/PrintAST.ql b/cpp/ql/lib/semmle/code/cpp/PrintAST.ql index e4c53030da5..bf7e345132c 100644 --- a/cpp/ql/lib/semmle/code/cpp/PrintAST.ql +++ b/cpp/ql/lib/semmle/code/cpp/PrintAST.ql @@ -12,7 +12,7 @@ import PrintAST * Temporarily tweak this class or make a copy to control which functions are * printed. */ -class Cfg extends PrintASTConfiguration { +class Cfg extends PrintAstConfiguration { /** * TWEAK THIS PREDICATE AS NEEDED. * Holds if the AST for `func` should be printed. diff --git a/cpp/ql/lib/semmle/code/cpp/PrintAST.qll b/cpp/ql/lib/semmle/code/cpp/PrintAST.qll index 86b39a285b0..7658d5cf17a 100644 --- a/cpp/ql/lib/semmle/code/cpp/PrintAST.qll +++ b/cpp/ql/lib/semmle/code/cpp/PrintAST.qll @@ -9,12 +9,12 @@ import cpp private import semmle.code.cpp.Print -private newtype TPrintASTConfiguration = MkPrintASTConfiguration() +private newtype TPrintAstConfiguration = MkPrintAstConfiguration() /** * The query can extend this class to control which functions are printed. */ -class PrintASTConfiguration extends TPrintASTConfiguration { +class PrintAstConfiguration extends TPrintAstConfiguration { /** * Gets a textual representation of this `PrintASTConfiguration`. */ @@ -27,8 +27,11 @@ class PrintASTConfiguration extends TPrintASTConfiguration { predicate shouldPrintFunction(Function func) { any() } } +/** DEPRECATED: Alias for PrintAstConfiguration */ +deprecated class PrintASTConfiguration = PrintAstConfiguration; + private predicate shouldPrintFunction(Function func) { - exists(PrintASTConfiguration config | config.shouldPrintFunction(func)) + exists(PrintAstConfiguration config | config.shouldPrintFunction(func)) } bindingset[s] @@ -85,8 +88,8 @@ private Function getEnclosingFunction(Locatable ast) { * Most nodes are just a wrapper around `Locatable`, but we do synthesize new * nodes for things like parameter lists and constructor init lists. */ -private newtype TPrintASTNode = - TASTNode(Locatable ast) { shouldPrintFunction(getEnclosingFunction(ast)) } or +private newtype TPrintAstNode = + TAstNode(Locatable ast) { shouldPrintFunction(getEnclosingFunction(ast)) } or TDeclarationEntryNode(DeclStmt stmt, DeclarationEntry entry) { // We create a unique node for each pair of (stmt, entry), to avoid having one node with // multiple parents due to extractor bug CPP-413. @@ -106,7 +109,7 @@ private newtype TPrintASTNode = /** * A node in the output tree. */ -class PrintASTNode extends TPrintASTNode { +class PrintAstNode extends TPrintAstNode { /** * Gets a textual representation of this node in the PrintAST output tree. */ @@ -116,17 +119,17 @@ class PrintASTNode extends TPrintASTNode { * Gets the child node at index `childIndex`. Child indices must be unique, * but need not be contiguous. */ - abstract PrintASTNode getChildInternal(int childIndex); + abstract PrintAstNode getChildInternal(int childIndex); /** * Gets the child node at index `childIndex`. * Adds edges to fully converted expressions, that are not part of the * regular parent/child relation traversal. */ - final PrintASTNode getChild(int childIndex) { + final PrintAstNode getChild(int childIndex) { // The exact value of `childIndex` doesn't matter, as long as we preserve the correct order. result = - rank[childIndex](PrintASTNode child, int nonConvertedIndex, boolean isConverted | + rank[childIndex](PrintAstNode child, int nonConvertedIndex, boolean isConverted | childAndAccessorPredicate(child, _, nonConvertedIndex, isConverted) | // Unconverted children come first, then sort by original child index within each group. @@ -138,11 +141,11 @@ class PrintASTNode extends TPrintASTNode { * Gets the node for the `.getFullyConverted()` version of the child originally at index * `childIndex`, if that node has any conversions. */ - private PrintASTNode getConvertedChild(int childIndex) { + private PrintAstNode getConvertedChild(int childIndex) { exists(Expr expr | - expr = getChildInternal(childIndex).(ASTNode).getAST() and + expr = getChildInternal(childIndex).(AstNode).getAst() and expr.getFullyConverted() instanceof Conversion and - result.(ASTNode).getAST() = expr.getFullyConverted() and + result.(AstNode).getAst() = expr.getFullyConverted() and not expr instanceof Conversion ) } @@ -166,12 +169,12 @@ class PrintASTNode extends TPrintASTNode { /** * Gets the children of this node. */ - final PrintASTNode getAChild() { result = getChild(_) } + final PrintAstNode getAChild() { result = getChild(_) } /** * Gets the parent of this node, if any. */ - final PrintASTNode getParent() { result.getAChild() = this } + final PrintAstNode getParent() { result.getAChild() = this } /** * Gets the location of this node in the source code. @@ -196,7 +199,7 @@ class PrintASTNode extends TPrintASTNode { * one result tuple, with `isConverted = false`. */ private predicate childAndAccessorPredicate( - PrintASTNode child, string childPredicate, int nonConvertedIndex, boolean isConverted + PrintAstNode child, string childPredicate, int nonConvertedIndex, boolean isConverted ) { child = getChildInternal(nonConvertedIndex) and childPredicate = getChildAccessorPredicateInternal(nonConvertedIndex) and @@ -234,12 +237,15 @@ class PrintASTNode extends TPrintASTNode { private Function getEnclosingFunction() { result = getParent*().(FunctionNode).getFunction() } } +/** DEPRECATED: Alias for PrintAstNode */ +deprecated class PrintASTNode = PrintAstNode; + /** * Class that restricts the elements that we compute `qlClass` for. */ private class PrintableElement extends Element { PrintableElement() { - exists(TASTNode(this)) + exists(TAstNode(this)) or exists(TDeclarationEntryNode(_, this)) or @@ -262,7 +268,7 @@ private string qlClass(PrintableElement el) { /** * A node representing an AST node. */ -abstract class BaseASTNode extends PrintASTNode { +abstract class BaseAstNode extends PrintAstNode { Locatable ast; override string toString() { result = qlClass(ast) + ast.toString() } @@ -272,25 +278,34 @@ abstract class BaseASTNode extends PrintASTNode { /** * Gets the AST represented by this node. */ - final Locatable getAST() { result = ast } + final Locatable getAst() { result = ast } + + /** DEPRECATED: Alias for getAst */ + deprecated Locatable getAST() { result = getAst() } } +/** DEPRECATED: Alias for BaseAstNode */ +deprecated class BaseASTNode = BaseAstNode; + /** * A node representing an AST node other than a `DeclarationEntry`. */ -abstract class ASTNode extends BaseASTNode, TASTNode { - ASTNode() { this = TASTNode(ast) } +abstract class AstNode extends BaseAstNode, TAstNode { + AstNode() { this = TAstNode(ast) } } +/** DEPRECATED: Alias for AstNode */ +deprecated class ASTNode = AstNode; + /** * A node representing an `Expr`. */ -class ExprNode extends ASTNode { +class ExprNode extends AstNode { Expr expr; ExprNode() { expr = ast } - override ASTNode getChildInternal(int childIndex) { result.getAST() = expr.getChild(childIndex) } + override AstNode getChildInternal(int childIndex) { result.getAst() = expr.getChild(childIndex) } override string getProperty(string key) { result = super.getProperty(key) @@ -306,7 +321,7 @@ class ExprNode extends ASTNode { } override string getChildAccessorPredicateInternal(int childIndex) { - result = getChildAccessorWithoutConversions(ast, getChildInternal(childIndex).getAST()) + result = getChildAccessorWithoutConversions(ast, getChildInternal(childIndex).getAst()) } /** @@ -334,9 +349,9 @@ class ConversionNode extends ExprNode { ConversionNode() { conv = expr } - override ASTNode getChildInternal(int childIndex) { + override AstNode getChildInternal(int childIndex) { childIndex = 0 and - result.getAST() = conv.getExpr() and + result.getAst() = conv.getExpr() and conv.getExpr() instanceof Conversion } } @@ -363,27 +378,27 @@ class CastNode extends ConversionNode { class StmtExprNode extends ExprNode { override StmtExpr expr; - override ASTNode getChildInternal(int childIndex) { + override AstNode getChildInternal(int childIndex) { childIndex = 0 and - result.getAST() = expr.getStmt() + result.getAst() = expr.getStmt() } } /** * A node representing a `DeclarationEntry`. */ -class DeclarationEntryNode extends BaseASTNode, TDeclarationEntryNode { +class DeclarationEntryNode extends BaseAstNode, TDeclarationEntryNode { override DeclarationEntry ast; DeclStmt declStmt; DeclarationEntryNode() { this = TDeclarationEntryNode(declStmt, ast) } - override PrintASTNode getChildInternal(int childIndex) { none() } + override PrintAstNode getChildInternal(int childIndex) { none() } override string getChildAccessorPredicateInternal(int childIndex) { none() } override string getProperty(string key) { - result = BaseASTNode.super.getProperty(key) + result = BaseAstNode.super.getProperty(key) or key = "Type" and result = qlClass(ast.getType()) + ast.getType().toString() @@ -396,9 +411,9 @@ class DeclarationEntryNode extends BaseASTNode, TDeclarationEntryNode { class VariableDeclarationEntryNode extends DeclarationEntryNode { override VariableDeclarationEntry ast; - override ASTNode getChildInternal(int childIndex) { + override AstNode getChildInternal(int childIndex) { childIndex = 0 and - result.getAST() = ast.getVariable().getInitializer() + result.getAst() = ast.getVariable().getInitializer() } override string getChildAccessorPredicateInternal(int childIndex) { @@ -410,23 +425,23 @@ class VariableDeclarationEntryNode extends DeclarationEntryNode { /** * A node representing a `Stmt`. */ -class StmtNode extends ASTNode { +class StmtNode extends AstNode { Stmt stmt; StmtNode() { stmt = ast } - override BaseASTNode getChildInternal(int childIndex) { + override BaseAstNode getChildInternal(int childIndex) { exists(Locatable child | child = stmt.getChild(childIndex) and ( - result.getAST() = child.(Expr) or - result.getAST() = child.(Stmt) + result.getAst() = child.(Expr) or + result.getAst() = child.(Stmt) ) ) } override string getChildAccessorPredicateInternal(int childIndex) { - result = getChildAccessorWithoutConversions(ast, getChildInternal(childIndex).getAST()) + result = getChildAccessorWithoutConversions(ast, getChildInternal(childIndex).getAst()) } } @@ -449,12 +464,12 @@ class DeclStmtNode extends StmtNode { /** * A node representing a `Parameter`. */ -class ParameterNode extends ASTNode { +class ParameterNode extends AstNode { Parameter param; ParameterNode() { param = ast } - final override PrintASTNode getChildInternal(int childIndex) { none() } + final override PrintAstNode getChildInternal(int childIndex) { none() } final override string getChildAccessorPredicateInternal(int childIndex) { none() } @@ -469,14 +484,14 @@ class ParameterNode extends ASTNode { /** * A node representing an `Initializer`. */ -class InitializerNode extends ASTNode { +class InitializerNode extends AstNode { Initializer init; InitializerNode() { init = ast } - override ASTNode getChildInternal(int childIndex) { + override AstNode getChildInternal(int childIndex) { childIndex = 0 and - result.getAST() = init.getExpr() + result.getAst() = init.getExpr() } override string getChildAccessorPredicateInternal(int childIndex) { @@ -488,7 +503,7 @@ class InitializerNode extends ASTNode { /** * A node representing the parameters of a `Function`. */ -class ParametersNode extends PrintASTNode, TParametersNode { +class ParametersNode extends PrintAstNode, TParametersNode { Function func; ParametersNode() { this = TParametersNode(func) } @@ -497,8 +512,8 @@ class ParametersNode extends PrintASTNode, TParametersNode { final override Location getLocation() { result = getRepresentativeLocation(func) } - override ASTNode getChildInternal(int childIndex) { - result.getAST() = func.getParameter(childIndex) + override AstNode getChildInternal(int childIndex) { + result.getAst() = func.getParameter(childIndex) } override string getChildAccessorPredicateInternal(int childIndex) { @@ -515,7 +530,7 @@ class ParametersNode extends PrintASTNode, TParametersNode { /** * A node representing the initializer list of a `Constructor`. */ -class ConstructorInitializersNode extends PrintASTNode, TConstructorInitializersNode { +class ConstructorInitializersNode extends PrintAstNode, TConstructorInitializersNode { Constructor ctor; ConstructorInitializersNode() { this = TConstructorInitializersNode(ctor) } @@ -524,8 +539,8 @@ class ConstructorInitializersNode extends PrintASTNode, TConstructorInitializers final override Location getLocation() { result = getRepresentativeLocation(ctor) } - final override ASTNode getChildInternal(int childIndex) { - result.getAST() = ctor.getInitializer(childIndex) + final override AstNode getChildInternal(int childIndex) { + result.getAst() = ctor.getInitializer(childIndex) } final override string getChildAccessorPredicateInternal(int childIndex) { @@ -542,7 +557,7 @@ class ConstructorInitializersNode extends PrintASTNode, TConstructorInitializers /** * A node representing the destruction list of a `Destructor`. */ -class DestructorDestructionsNode extends PrintASTNode, TDestructorDestructionsNode { +class DestructorDestructionsNode extends PrintAstNode, TDestructorDestructionsNode { Destructor dtor; DestructorDestructionsNode() { this = TDestructorDestructionsNode(dtor) } @@ -551,8 +566,8 @@ class DestructorDestructionsNode extends PrintASTNode, TDestructorDestructionsNo final override Location getLocation() { result = getRepresentativeLocation(dtor) } - final override ASTNode getChildInternal(int childIndex) { - result.getAST() = dtor.getDestruction(childIndex) + final override AstNode getChildInternal(int childIndex) { + result.getAst() = dtor.getDestruction(childIndex) } final override string getChildAccessorPredicateInternal(int childIndex) { @@ -569,14 +584,14 @@ class DestructorDestructionsNode extends PrintASTNode, TDestructorDestructionsNo /** * A node representing a `Function`. */ -class FunctionNode extends ASTNode { +class FunctionNode extends AstNode { Function func; FunctionNode() { func = ast } override string toString() { result = qlClass(func) + getIdentityString(func) } - override PrintASTNode getChildInternal(int childIndex) { + override PrintAstNode getChildInternal(int childIndex) { childIndex = 0 and result.(ParametersNode).getFunction() = func or @@ -584,7 +599,7 @@ class FunctionNode extends ASTNode { result.(ConstructorInitializersNode).getConstructor() = func or childIndex = 2 and - result.(ASTNode).getAST() = func.getEntryPoint() + result.(AstNode).getAst() = func.getEntryPoint() or childIndex = 3 and result.(DestructorDestructionsNode).getDestructor() = func @@ -603,7 +618,7 @@ class FunctionNode extends ASTNode { private int getOrder() { this = rank[result](FunctionNode node, Function function, string file, int line, int column | - node.getAST() = function and + node.getAst() = function and locationSortKeys(function, file, line, column) | node order by file, line, column, getIdentityString(function) @@ -856,7 +871,7 @@ private predicate namedExprChildPredicates(Expr expr, Element ele, string pred) } /** Holds if `node` belongs to the output tree, and its property `key` has the given `value`. */ -query predicate nodes(PrintASTNode node, string key, string value) { +query predicate nodes(PrintAstNode node, string key, string value) { node.shouldPrint() and value = node.getProperty(key) } @@ -865,7 +880,7 @@ query predicate nodes(PrintASTNode node, string key, string value) { * Holds if `target` is a child of `source` in the AST, and property `key` of the edge has the * given `value`. */ -query predicate edges(PrintASTNode source, PrintASTNode target, string key, string value) { +query predicate edges(PrintAstNode source, PrintAstNode target, string key, string value) { exists(int childIndex | source.shouldPrint() and target.shouldPrint() and diff --git a/cpp/ql/lib/semmle/code/cpp/Specifier.qll b/cpp/ql/lib/semmle/code/cpp/Specifier.qll index 69cccf06ffb..7a13b13e8c2 100644 --- a/cpp/ql/lib/semmle/code/cpp/Specifier.qll +++ b/cpp/ql/lib/semmle/code/cpp/Specifier.qll @@ -38,7 +38,7 @@ class FunctionSpecifier extends Specifier { /** * A C/C++ storage class specifier: `auto`, `register`, `static`, `extern`, - * or `mutable". + * or `mutable`. */ class StorageClassSpecifier extends Specifier { StorageClassSpecifier() { this.hasName(["auto", "register", "static", "extern", "mutable"]) } diff --git a/cpp/ql/lib/semmle/code/cpp/Type.qll b/cpp/ql/lib/semmle/code/cpp/Type.qll index f8552144ea8..e5fbd02d420 100644 --- a/cpp/ql/lib/semmle/code/cpp/Type.qll +++ b/cpp/ql/lib/semmle/code/cpp/Type.qll @@ -1085,50 +1085,6 @@ class DerivedType extends Type, @derivedtype { override predicate involvesTemplateParameter() { this.getBaseType().involvesTemplateParameter() } override Type stripType() { result = this.getBaseType().stripType() } - - /** - * Holds if this type has the `__autoreleasing` specifier or if it points to - * a type with the `__autoreleasing` specifier. - * - * DEPRECATED: use `hasSpecifier` directly instead. - */ - deprecated predicate isAutoReleasing() { - this.hasSpecifier("__autoreleasing") or - this.(PointerType).getBaseType().hasSpecifier("__autoreleasing") - } - - /** - * Holds if this type has the `__strong` specifier or if it points to - * a type with the `__strong` specifier. - * - * DEPRECATED: use `hasSpecifier` directly instead. - */ - deprecated predicate isStrong() { - this.hasSpecifier("__strong") or - this.(PointerType).getBaseType().hasSpecifier("__strong") - } - - /** - * Holds if this type has the `__unsafe_unretained` specifier or if it points - * to a type with the `__unsafe_unretained` specifier. - * - * DEPRECATED: use `hasSpecifier` directly instead. - */ - deprecated predicate isUnsafeRetained() { - this.hasSpecifier("__unsafe_unretained") or - this.(PointerType).getBaseType().hasSpecifier("__unsafe_unretained") - } - - /** - * Holds if this type has the `__weak` specifier or if it points to - * a type with the `__weak` specifier. - * - * DEPRECATED: use `hasSpecifier` directly instead. - */ - deprecated predicate isWeak() { - this.hasSpecifier("__weak") or - this.(PointerType).getBaseType().hasSpecifier("__weak") - } } /** diff --git a/cpp/ql/lib/semmle/code/cpp/TypedefType.qll b/cpp/ql/lib/semmle/code/cpp/TypedefType.qll index 51bcf6f6127..4721ecc2612 100644 --- a/cpp/ql/lib/semmle/code/cpp/TypedefType.qll +++ b/cpp/ql/lib/semmle/code/cpp/TypedefType.qll @@ -106,25 +106,4 @@ class NestedTypedefType extends TypedefType { NestedTypedefType() { this.isMember() } override string getAPrimaryQlClass() { result = "NestedTypedefType" } - - /** - * DEPRECATED: use `.hasSpecifier("private")` instead. - * - * Holds if this member is private. - */ - deprecated predicate isPrivate() { this.hasSpecifier("private") } - - /** - * DEPRECATED: `.hasSpecifier("protected")` instead. - * - * Holds if this member is protected. - */ - deprecated predicate isProtected() { this.hasSpecifier("protected") } - - /** - * DEPRECATED: use `.hasSpecifier("public")` instead. - * - * Holds if this member is public. - */ - deprecated predicate isPublic() { this.hasSpecifier("public") } } diff --git a/cpp/ql/lib/semmle/code/cpp/Variable.qll b/cpp/ql/lib/semmle/code/cpp/Variable.qll index 2c7d85f9cc8..2e3d6bf3ca2 100644 --- a/cpp/ql/lib/semmle/code/cpp/Variable.qll +++ b/cpp/ql/lib/semmle/code/cpp/Variable.qll @@ -556,24 +556,6 @@ class MemberVariable extends Variable, @membervariable { private Type getAType() { membervariables(underlyingElement(this), unresolveElement(result), _) } } -/** - * A C/C++ function pointer variable. - * - * DEPRECATED: use `Variable.getType() instanceof FunctionPointerType` instead. - */ -deprecated class FunctionPointerVariable extends Variable { - FunctionPointerVariable() { this.getType() instanceof FunctionPointerType } -} - -/** - * A C/C++ function pointer member variable. - * - * DEPRECATED: use `MemberVariable.getType() instanceof FunctionPointerType` instead. - */ -deprecated class FunctionPointerMemberVariable extends MemberVariable { - FunctionPointerMemberVariable() { this instanceof FunctionPointerVariable } -} - /** * A C++14 variable template. For example, in the following code the variable * template `v` defines a family of variables: diff --git a/cpp/ql/lib/semmle/code/cpp/XML.qll b/cpp/ql/lib/semmle/code/cpp/XML.qll index dc76884b73c..fb781a4683f 100755 --- a/cpp/ql/lib/semmle/code/cpp/XML.qll +++ b/cpp/ql/lib/semmle/code/cpp/XML.qll @@ -4,21 +4,14 @@ import semmle.files.FileSystem -private class TXMLLocatable = +private class TXmlLocatable = @xmldtd or @xmlelement or @xmlattribute or @xmlnamespace or @xmlcomment or @xmlcharacters; /** An XML element that has a location. */ -class XMLLocatable extends @xmllocatable, TXMLLocatable { +class XMLLocatable extends @xmllocatable, TXmlLocatable { /** Gets the source location for this element. */ Location getLocation() { xmllocations(this, result) } - /** - * DEPRECATED: Use `getLocation()` instead. - * - * Gets the source location for this element. - */ - deprecated Location getALocation() { result = this.getLocation() } - /** * Holds if this element is at the specified location. * The location spans column `startcolumn` of line `startline` to @@ -83,21 +76,6 @@ class XMLParent extends @xmlparent { /** Gets the number of places in the body of this XML parent where text occurs. */ int getNumberOfCharacterSets() { result = count(int pos | xmlChars(_, _, this, pos, _, _)) } - /** - * DEPRECATED: Internal. - * - * Append the character sequences of this XML parent from left to right, separated by a space, - * up to a specified (zero-based) index. - */ - deprecated string charsSetUpTo(int n) { - n = 0 and xmlChars(_, result, this, 0, _, _) - or - n > 0 and - exists(string chars | xmlChars(_, chars, this, n, _, _) | - result = this.charsSetUpTo(n - 1) + " " + chars - ) - } - /** * Gets the result of appending all the character sequences of this XML parent from * left to right, separated by a space. diff --git a/cpp/ql/lib/semmle/code/cpp/commons/Alloc.qll b/cpp/ql/lib/semmle/code/cpp/commons/Alloc.qll index a9597fc72b5..ce3f6993525 100644 --- a/cpp/ql/lib/semmle/code/cpp/commons/Alloc.qll +++ b/cpp/ql/lib/semmle/code/cpp/commons/Alloc.qll @@ -2,20 +2,6 @@ import cpp import semmle.code.cpp.models.interfaces.Allocation import semmle.code.cpp.models.interfaces.Deallocation -/** - * A library routine that allocates memory. - * - * DEPRECATED: Use the `AllocationFunction` class instead of this predicate. - */ -deprecated predicate allocationFunction(Function f) { f instanceof AllocationFunction } - -/** - * A call to a library routine that allocates memory. - * - * DEPRECATED: Use `AllocationExpr` instead (this also includes `new` expressions). - */ -deprecated predicate allocationCall(FunctionCall fc) { fc instanceof AllocationExpr } - /** * A library routine that frees memory. */ @@ -33,13 +19,6 @@ predicate freeCall(FunctionCall fc, Expr arg) { arg = fc.(DeallocationExpr).getF */ predicate isMemoryManagementExpr(Expr e) { isAllocationExpr(e) or e instanceof DeallocationExpr } -/** - * Is e an allocation from stdlib.h (`malloc`, `realloc` etc)? - * - * DEPRECATED: Use `AllocationExpr` instead (this also includes `new` expressions). - */ -deprecated predicate isStdLibAllocationExpr(Expr e) { allocationCall(e) } - /** * Is e some kind of allocation (`new`, `alloc`, `realloc` etc)? */ @@ -48,19 +27,3 @@ predicate isAllocationExpr(Expr e) { or e = any(NewOrNewArrayExpr new | not exists(new.getPlacementPointer())) } - -/** - * Is e some kind of allocation (`new`, `alloc`, `realloc` etc) with a fixed size? - * - * DEPRECATED: Use `AllocationExpr.getSizeBytes()` instead. - */ -deprecated predicate isFixedSizeAllocationExpr(Expr allocExpr, int size) { - size = allocExpr.(AllocationExpr).getSizeBytes() -} - -/** - * Is e some kind of deallocation (`delete`, `free`, `realloc` etc)? - * - * DEPRECATED: Use `DeallocationExpr` instead. - */ -deprecated predicate isDeallocationExpr(Expr e) { e instanceof DeallocationExpr } diff --git a/cpp/ql/lib/semmle/code/cpp/commons/Printf.qll b/cpp/ql/lib/semmle/code/cpp/commons/Printf.qll index 4a6566da45d..dc7b8352d4b 100644 --- a/cpp/ql/lib/semmle/code/cpp/commons/Printf.qll +++ b/cpp/ql/lib/semmle/code/cpp/commons/Printf.qll @@ -207,26 +207,6 @@ predicate variadicFormatter(Function f, string type, int formatParamIndex, int o callsVariadicFormatter(f, type, formatParamIndex, outputParamIndex) } -/** - * A standard function such as `vprintf` that has a format parameter - * and a variable argument list of type `va_arg`. - * - * DEPRECATED: Use the four argument version instead. - */ -deprecated predicate primitiveVariadicFormatter(TopLevelFunction f, int formatParamIndex) { - primitiveVariadicFormatter(f, _, formatParamIndex, _) -} - -/** - * Holds if `f` is a function such as `vprintf` that has a format parameter - * (at `formatParamIndex`) and a variable argument list of type `va_arg`. - * - * DEPRECATED: Use the four argument version instead. - */ -deprecated predicate variadicFormatter(Function f, int formatParamIndex) { - variadicFormatter(f, _, formatParamIndex, _) -} - /** * A function not in the standard library which takes a `printf`-like formatting * string and a variable number of arguments. @@ -428,13 +408,6 @@ class FormatLiteral extends Literal { */ FormattingFunctionCall getUse() { result.getFormat() = this } - /** - * Holds if the default meaning of `%s` is a `wchar_t *`, rather than - * a `char *` (either way, `%S` will have the opposite meaning). - * DEPRECATED: Use getDefaultCharType() instead. - */ - deprecated predicate isWideCharDefault() { this.getUse().getTarget().isWideCharDefault() } - /** * Gets the default character type expected for `%s` by this format literal. Typically * `char` or `wchar_t`. diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/BasicBlocks.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/BasicBlocks.qll index 34373d943af..11a7e8f9e64 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/BasicBlocks.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/BasicBlocks.qll @@ -223,20 +223,6 @@ class BasicBlock extends ControlFlowNodeBase { */ predicate inLoop() { this.getASuccessor+() = this } - /** - * DEPRECATED since version 1.11: this predicate does not match the standard - * definition of _loop header_. - * - * Holds if this basic block is in a loop of the control-flow graph and - * additionally has an incoming edge that is not part of any loop containing - * this basic block. A typical example would be the basic block that computes - * `x > 0` in an outermost loop `while (x > 0) { ... }`. - */ - deprecated predicate isLoopHeader() { - this.inLoop() and - exists(BasicBlock pred | pred = this.getAPredecessor() and not pred = this.getASuccessor+()) - } - /** * Holds if control flow may reach this basic block from a function entry * point or any handler of a reachable `try` statement. diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/ControlFlowGraph.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/ControlFlowGraph.qll index c7b3d1dc16f..846d8047982 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/ControlFlowGraph.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/ControlFlowGraph.qll @@ -65,7 +65,7 @@ class ControlFlowNode extends Locatable, ControlFlowNodeBase { * taken when this expression is true. */ ControlFlowNode getATrueSuccessor() { - qlCFGTrueSuccessor(this, result) and + qlCfgTrueSuccessor(this, result) and result = this.getASuccessor() } @@ -74,7 +74,7 @@ class ControlFlowNode extends Locatable, ControlFlowNodeBase { * taken when this expression is false. */ ControlFlowNode getAFalseSuccessor() { - qlCFGFalseSuccessor(this, result) and + qlCfgFalseSuccessor(this, result) and result = this.getASuccessor() } @@ -94,24 +94,6 @@ import ControlFlowGraphPublic */ class ControlFlowNodeBase extends ElementBase, @cfgnode { } -/** - * DEPRECATED: Use `ControlFlowNode.getATrueSuccessor()` instead. - * Holds when `n2` is a control-flow node such that the control-flow - * edge `(n1, n2)` may be taken when `n1` is an expression that is true. - */ -deprecated predicate truecond_base(ControlFlowNodeBase n1, ControlFlowNodeBase n2) { - qlCFGTrueSuccessor(n1, n2) -} - -/** - * DEPRECATED: Use `ControlFlowNode.getAFalseSuccessor()` instead. - * Holds when `n2` is a control-flow node such that the control-flow - * edge `(n1, n2)` may be taken when `n1` is an expression that is false. - */ -deprecated predicate falsecond_base(ControlFlowNodeBase n1, ControlFlowNodeBase n2) { - qlCFGFalseSuccessor(n1, n2) -} - /** * An abstract class that can be extended to add additional edges to the * control-flow graph. Instances of this class correspond to the source nodes @@ -139,7 +121,7 @@ abstract class AdditionalControlFlowEdge extends ControlFlowNodeBase { * `AdditionalControlFlowEdge`. Use this relation instead of `qlCFGSuccessor`. */ predicate successors_extended(ControlFlowNodeBase source, ControlFlowNodeBase target) { - qlCFGSuccessor(source, target) + qlCfgSuccessor(source, target) or source.(AdditionalControlFlowEdge).getAnEdgeTarget() = target } diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll index 2b222376a0b..d12eaa4e238 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll @@ -33,8 +33,8 @@ class GuardCondition extends Expr { or // the IR short-circuits if(!x) // don't produce a guard condition for `y = !x` and other non-short-circuited cases - not exists(Instruction inst | this.getFullyConverted() = inst.getAST()) and - exists(IRGuardCondition ir | this.(NotExpr).getOperand() = ir.getAST()) + not exists(Instruction inst | this.getFullyConverted() = inst.getAst()) and + exists(IRGuardCondition ir | this.(NotExpr).getOperand() = ir.getAst()) } /** @@ -146,8 +146,8 @@ private class GuardConditionFromBinaryLogicalOperator extends GuardCondition { */ private class GuardConditionFromShortCircuitNot extends GuardCondition, NotExpr { GuardConditionFromShortCircuitNot() { - not exists(Instruction inst | this.getFullyConverted() = inst.getAST()) and - exists(IRGuardCondition ir | this.getOperand() = ir.getAST()) + not exists(Instruction inst | this.getFullyConverted() = inst.getAst()) and + exists(IRGuardCondition ir | this.getOperand() = ir.getAst()) } override predicate controls(BasicBlock controlled, boolean testIsTrue) { @@ -241,7 +241,7 @@ private class GuardConditionFromIR extends GuardCondition { private predicate controlsBlock(BasicBlock controlled, boolean testIsTrue) { exists(IRBlock irb | forex(IRGuardCondition inst | inst = ir | inst.controls(irb, testIsTrue)) and - irb.getAnInstruction().getAST().(ControlFlowNode).getBasicBlock() = controlled and + irb.getAnInstruction().getAst().(ControlFlowNode).getBasicBlock() = controlled and not isUnreachedBlock(irb) ) } diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/LocalScopeVariableReachability.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/LocalScopeVariableReachability.qll deleted file mode 100644 index f6685865830..00000000000 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/LocalScopeVariableReachability.qll +++ /dev/null @@ -1,393 +0,0 @@ -/** - * DEPRECATED: Use `StackVariableReachability` instead. - */ - -import cpp - -/** - * DEPRECATED: Use `StackVariableReachability` instead. - * - * A reachability analysis for control-flow nodes involving stack variables. - * This defines sources, sinks, and any other configurable aspect of the - * analysis. Multiple analyses can coexist. To create an analysis, extend this - * class with a subclass whose characteristic predicate is a unique singleton - * string. For example, write - * - * ``` - * class MyAnalysisConfiguration extends LocalScopeVariableReachability { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Override `isBarrier`. - * } - * ``` - * - * Then, to query whether there is flow between some source and sink, call the - * `reaches` predicate on an instance of `MyAnalysisConfiguration`. - */ -abstract deprecated class LocalScopeVariableReachability extends string { - bindingset[this] - LocalScopeVariableReachability() { length() >= 0 } - - /** Holds if `node` is a source for the reachability analysis using variable `v`. */ - abstract predicate isSource(ControlFlowNode node, LocalScopeVariable v); - - /** Holds if `sink` is a (potential) sink for the reachability analysis using variable `v`. */ - abstract predicate isSink(ControlFlowNode node, LocalScopeVariable v); - - /** Holds if `node` is a barrier for the reachability analysis using variable `v`. */ - abstract predicate isBarrier(ControlFlowNode node, LocalScopeVariable v); - - /** - * Holds if the source node `source` can reach the sink `sink` without crossing - * a barrier. This is (almost) equivalent to the following QL predicate but - * uses basic blocks internally for better performance: - * - * ``` - * predicate reaches(ControlFlowNode source, SemanticStackVariable v, ControlFlowNode sink) { - * reachesImpl(source, v, sink) - * and - * isSink(sink, v) - * } - * - * predicate reachesImpl(ControlFlowNode source, SemanticStackVariable v, ControlFlowNode sink) { - * sink = source.getASuccessor() and isSource(source, v) - * or - * exists(ControlFlowNode mid | reachesImpl(source, v, mid) | - * not isBarrier(mid, v) - * and - * sink = mid.getASuccessor() - * ) - * } - * ``` - * - * In addition to using a better performing implementation, this analysis - * accounts for loops where the condition is provably true upon entry. - */ - predicate reaches(ControlFlowNode source, SemanticStackVariable v, ControlFlowNode sink) { - /* - * Implementation detail: the predicates in this class are a generalization of - * those in DefinitionsAndUses.qll, and should be kept in sync. - * - * Unfortunately, caching of abstract predicates does not work well, so the - * predicates in DefinitionsAndUses.qll cannot use this library. - */ - - exists(BasicBlock bb, int i | - this.isSource(source, v) and - bb.getNode(i) = source and - not bb.isUnreachable() - | - exists(int j | - j > i and - sink = bb.getNode(j) and - this.isSink(sink, v) and - not exists(int k | this.isBarrier(bb.getNode(k), v) | k in [i + 1 .. j - 1]) - ) - or - not exists(int k | this.isBarrier(bb.getNode(k), v) | k > i) and - this.bbSuccessorEntryReaches(bb, v, sink, _) - ) - } - - private predicate bbSuccessorEntryReaches( - BasicBlock bb, SemanticStackVariable v, ControlFlowNode node, - boolean skipsFirstLoopAlwaysTrueUponEntry - ) { - exists(BasicBlock succ, boolean succSkipsFirstLoopAlwaysTrueUponEntry | - bbSuccessorEntryReachesLoopInvariant(bb, succ, skipsFirstLoopAlwaysTrueUponEntry, - succSkipsFirstLoopAlwaysTrueUponEntry) - | - this.bbEntryReachesLocally(succ, v, node) and - succSkipsFirstLoopAlwaysTrueUponEntry = false - or - not this.isBarrier(succ.getNode(_), v) and - this.bbSuccessorEntryReaches(succ, v, node, succSkipsFirstLoopAlwaysTrueUponEntry) - ) - } - - private predicate bbEntryReachesLocally( - BasicBlock bb, SemanticStackVariable v, ControlFlowNode node - ) { - exists(int n | - node = bb.getNode(n) and - this.isSink(node, v) - | - not exists(this.firstBarrierIndexIn(bb, v)) - or - n <= this.firstBarrierIndexIn(bb, v) - ) - } - - private int firstBarrierIndexIn(BasicBlock bb, SemanticStackVariable v) { - result = min(int m | this.isBarrier(bb.getNode(m), v)) - } -} - -/** - * Holds if `bb` contains the entry point `loop` for a loop at position `i`. - * The condition of that loop is provably true upon entry but not provably - * true in general (if it were, the false-successor had already been removed - * from the CFG). - * - * Examples: - * ``` - * for (int i = 0; i < 2; i++) { } // always true upon entry - * for (int i = 0; true; i++) { } // always true - * ``` - */ -private predicate bbLoopEntryConditionAlwaysTrueAt(BasicBlock bb, int i, ControlFlowNode loop) { - exists(Expr condition | - loopConditionAlwaysTrueUponEntry(loop, condition) and - not conditionAlwaysTrue(condition) and - bb.getNode(i) = loop - ) -} - -/** - * Basic block `pred` contains all or part of the condition belonging to a loop, - * and there is an edge from `pred` to `succ` that concludes the condition. - * If the edge corrseponds with the loop condition being found to be `true`, then - * `skipsLoop` is `false`. Otherwise the edge corresponds with the loop condition - * being found to be `false` and `skipsLoop` is `true`. Non-concluding edges - * within a complex loop condition are not matched by this predicate. - */ -private predicate bbLoopConditionAlwaysTrueUponEntrySuccessor( - BasicBlock pred, BasicBlock succ, boolean skipsLoop -) { - exists(Expr cond | - loopConditionAlwaysTrueUponEntry(_, cond) and - cond.getAChild*() = pred.getEnd() and - succ = pred.getASuccessor() and - not cond.getAChild*() = succ.getStart() and - ( - succ = pred.getAFalseSuccessor() and - skipsLoop = true - or - succ = pred.getATrueSuccessor() and - skipsLoop = false - ) - ) -} - -/** - * Loop invariant for `bbSuccessorEntryReaches`: - * - * - `succ` is a successor of `pred`. - * - `predSkipsFirstLoopAlwaysTrueUponEntry`: whether the path from - * `pred` (via `succ`) skips the first loop where the condition is - * provably true upon entry. - * - `succSkipsFirstLoopAlwaysTrueUponEntry`: whether the path from - * `succ` skips the first loop where the condition is provably true - * upon entry. - * - If `pred` contains the entry point of a loop where the condition - * is provably true upon entry, then `succ` is not allowed to skip - * that loop (`succSkipsFirstLoopAlwaysTrueUponEntry = false`). - */ -predicate bbSuccessorEntryReachesLoopInvariant( - BasicBlock pred, BasicBlock succ, boolean predSkipsFirstLoopAlwaysTrueUponEntry, - boolean succSkipsFirstLoopAlwaysTrueUponEntry -) { - succ = pred.getASuccessor() and - (succSkipsFirstLoopAlwaysTrueUponEntry = true or succSkipsFirstLoopAlwaysTrueUponEntry = false) and - ( - // The edge from `pred` to `succ` is from a loop condition provably - // true upon entry, so the value of `predSkipsFirstLoopAlwaysTrueUponEntry` - // is determined by whether the true edge or the false edge is chosen, - // regardless of the value of `succSkipsFirstLoopAlwaysTrueUponEntry`. - bbLoopConditionAlwaysTrueUponEntrySuccessor(pred, succ, predSkipsFirstLoopAlwaysTrueUponEntry) - or - // The edge from `pred` to `succ` is _not_ from a loop condition provably - // true upon entry, so the values of `predSkipsFirstLoopAlwaysTrueUponEntry` - // and `succSkipsFirstLoopAlwaysTrueUponEntry` must be the same. - not bbLoopConditionAlwaysTrueUponEntrySuccessor(pred, succ, _) and - succSkipsFirstLoopAlwaysTrueUponEntry = predSkipsFirstLoopAlwaysTrueUponEntry and - // Moreover, if `pred` contains the entry point of a loop where the - // condition is provably true upon entry, then `succ` is not allowed - // to skip that loop, and hence `succSkipsFirstLoopAlwaysTrueUponEntry = false`. - ( - bbLoopEntryConditionAlwaysTrueAt(pred, _, _) - implies - succSkipsFirstLoopAlwaysTrueUponEntry = false - ) - ) -} - -/** - * DEPRECATED: Use `StackVariableReachabilityWithReassignment` instead. - * - * Reachability analysis for control-flow nodes involving stack variables. - * Unlike `LocalScopeVariableReachability`, this analysis takes variable - * reassignments into account. - * - * This class is used like `LocalScopeVariableReachability`, except that - * subclasses should override `isSourceActual` and `isSinkActual` instead of - * `isSource` and `isSink`, and that there is a `reachesTo` predicate in - * addition to `reaches`. - */ -abstract deprecated class LocalScopeVariableReachabilityWithReassignment extends LocalScopeVariableReachability { - bindingset[this] - LocalScopeVariableReachabilityWithReassignment() { length() >= 0 } - - /** Override this predicate rather than `isSource` (`isSource` is used internally). */ - abstract predicate isSourceActual(ControlFlowNode node, LocalScopeVariable v); - - /** Override this predicate rather than `isSink` (`isSink` is used internally). */ - abstract predicate isSinkActual(ControlFlowNode node, LocalScopeVariable v); - - /** - * Holds if the source node `source` can reach the sink `sink` without crossing - * a barrier, taking reassignments into account. This is (almost) equivalent - * to the following QL predicate, but uses basic blocks internally for better - * performance: - * - * ``` - * predicate reaches(ControlFlowNode source, SemanticStackVariable v, ControlFlowNode sink) { - * reachesImpl(source, v, sink) - * and - * isSinkActual(sink, v) - * } - * - * predicate reachesImpl(ControlFlowNode source, SemanticStackVariable v, ControlFlowNode sink) { - * isSourceActual(source, v) - * and - * ( - * sink = source.getASuccessor() - * or - * exists(ControlFlowNode mid, SemanticStackVariable v0 | reachesImpl(source, v0, mid) | - * // ordinary successor - * not isBarrier(mid, v) and - * sink = mid.getASuccessor() and - * v = v0 - * or - * // reassigned from v0 to v - * exprDefinition(v, mid, v0.getAnAccess()) and - * sink = mid.getASuccessor() - * ) - * ) - * } - * ``` - * - * In addition to using a better performing implementation, this analysis - * accounts for loops where the condition is provably true upon entry. - */ - override predicate reaches(ControlFlowNode source, SemanticStackVariable v, ControlFlowNode sink) { - this.reachesTo(source, v, sink, _) - } - - /** - * As `reaches`, but also specifies the last variable it was reassigned to (`v0`). - */ - predicate reachesTo( - ControlFlowNode source, SemanticStackVariable v, ControlFlowNode sink, SemanticStackVariable v0 - ) { - exists(ControlFlowNode def | - this.actualSourceReaches(source, v, def, v0) and - LocalScopeVariableReachability.super.reaches(def, v0, sink) and - this.isSinkActual(sink, v0) - ) - } - - private predicate actualSourceReaches( - ControlFlowNode source, SemanticStackVariable v, ControlFlowNode def, SemanticStackVariable v0 - ) { - this.isSourceActual(source, v) and def = source and v0 = v - or - exists(ControlFlowNode source1, SemanticStackVariable v1 | - this.actualSourceReaches(source, v, source1, v1) - | - this.reassignment(source1, v1, def, v0) - ) - } - - private predicate reassignment( - ControlFlowNode source, SemanticStackVariable v, ControlFlowNode def, SemanticStackVariable v0 - ) { - LocalScopeVariableReachability.super.reaches(source, v, def) and - exprDefinition(v0, def, v.getAnAccess()) - } - - final override predicate isSource(ControlFlowNode node, LocalScopeVariable v) { - this.isSourceActual(node, v) - or - // Reassignment generates a new (non-actual) source - this.reassignment(_, _, node, v) - } - - final override predicate isSink(ControlFlowNode node, LocalScopeVariable v) { - this.isSinkActual(node, v) - or - // Reassignment generates a new (non-actual) sink - exprDefinition(_, node, v.getAnAccess()) - } -} - -/** - * DEPRECATED: Use `StackVariableReachabilityExt` instead. - * - * Same as `LocalScopeVariableReachability`, but `isBarrier` works on control-flow - * edges rather than nodes and is therefore parameterized by the original - * source node as well. Otherwise, this class is used like - * `LocalScopeVariableReachability`. - */ -abstract deprecated class LocalScopeVariableReachabilityExt extends string { - bindingset[this] - LocalScopeVariableReachabilityExt() { length() >= 0 } - - /** `node` is a source for the reachability analysis using variable `v`. */ - abstract predicate isSource(ControlFlowNode node, LocalScopeVariable v); - - /** `sink` is a (potential) sink for the reachability analysis using variable `v`. */ - abstract predicate isSink(ControlFlowNode node, LocalScopeVariable v); - - /** `node` is a barrier for the reachability analysis using variable `v` and starting from `source`. */ - abstract predicate isBarrier( - ControlFlowNode source, ControlFlowNode node, ControlFlowNode next, LocalScopeVariable v - ); - - /** See `LocalScopeVariableReachability.reaches`. */ - predicate reaches(ControlFlowNode source, SemanticStackVariable v, ControlFlowNode sink) { - exists(BasicBlock bb, int i | - this.isSource(source, v) and - bb.getNode(i) = source and - not bb.isUnreachable() - | - exists(int j | - j > i and - sink = bb.getNode(j) and - this.isSink(sink, v) and - not exists(int k | this.isBarrier(source, bb.getNode(k), bb.getNode(k + 1), v) | - k in [i .. j - 1] - ) - ) - or - not exists(int k | this.isBarrier(source, bb.getNode(k), bb.getNode(k + 1), v) | k >= i) and - this.bbSuccessorEntryReaches(source, bb, v, sink, _) - ) - } - - private predicate bbSuccessorEntryReaches( - ControlFlowNode source, BasicBlock bb, SemanticStackVariable v, ControlFlowNode node, - boolean skipsFirstLoopAlwaysTrueUponEntry - ) { - exists(BasicBlock succ, boolean succSkipsFirstLoopAlwaysTrueUponEntry | - bbSuccessorEntryReachesLoopInvariant(bb, succ, skipsFirstLoopAlwaysTrueUponEntry, - succSkipsFirstLoopAlwaysTrueUponEntry) and - not this.isBarrier(source, bb.getEnd(), succ.getStart(), v) - | - this.bbEntryReachesLocally(source, succ, v, node) and - succSkipsFirstLoopAlwaysTrueUponEntry = false - or - not exists(int k | this.isBarrier(source, succ.getNode(k), succ.getNode(k + 1), v)) and - this.bbSuccessorEntryReaches(source, succ, v, node, succSkipsFirstLoopAlwaysTrueUponEntry) - ) - } - - private predicate bbEntryReachesLocally( - ControlFlowNode source, BasicBlock bb, SemanticStackVariable v, ControlFlowNode node - ) { - this.isSource(source, v) and - exists(int n | node = bb.getNode(n) and this.isSink(node, v) | - not exists(int m | m < n | this.isBarrier(source, bb.getNode(m), bb.getNode(m + 1), v)) - ) - } -} diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/Nullness.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/Nullness.qll index 69d2166a1d2..40c975873b4 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/Nullness.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/Nullness.qll @@ -156,15 +156,6 @@ class AnalysedExpr extends Expr { this.isValidCheck(v) and result = this.getATrueSuccessor() } - /** - * DEPRECATED: Use `getNonNullSuccessor` instead, which does the same. - */ - deprecated ControlFlowNode getValidSuccessor(LocalScopeVariable v) { - this.isValidCheck(v) and result = this.getATrueSuccessor() - or - this.isNullCheck(v) and result = this.getAFalseSuccessor() - } - /** * Holds if this is a `VariableAccess` of `v` nested inside a condition. */ diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/SSA.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/SSA.qll index c7af3fe4326..4732cd06184 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/SSA.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/SSA.qll @@ -10,10 +10,13 @@ import SSAUtils * The SSA logic comes in two versions: the standard SSA and range-analysis RangeSSA. * This class provides the standard SSA logic. */ -library class StandardSSA extends SSAHelper { - StandardSSA() { this = 0 } +library class StandardSsa extends SsaHelper { + StandardSsa() { this = 0 } } +/** DEPRECATED: Alias for StandardSsa */ +deprecated class StandardSSA = StandardSsa; + /** * A definition of one or more SSA variables, including phi node definitions. * An _SSA variable_, as defined in the literature, is effectively the pair of @@ -27,22 +30,22 @@ library class StandardSSA extends SSAHelper { * statically seen to be unreachable. */ class SsaDefinition extends ControlFlowNodeBase { - SsaDefinition() { exists(StandardSSA x | x.ssa_defn(_, this, _, _)) } + SsaDefinition() { exists(StandardSsa x | x.ssa_defn(_, this, _, _)) } /** * Gets a variable corresponding to an SSA StackVariable defined by * this definition. */ - StackVariable getAVariable() { exists(StandardSSA x | x.ssa_defn(result, this, _, _)) } + StackVariable getAVariable() { exists(StandardSsa x | x.ssa_defn(result, this, _, _)) } /** * Gets a string representation of the SSA variable represented by the pair * `(this, v)`. */ - string toString(StackVariable v) { exists(StandardSSA x | result = x.toString(this, v)) } + string toString(StackVariable v) { exists(StandardSsa x | result = x.toString(this, v)) } /** Gets a use of the SSA variable represented by the pair `(this, v)`. */ - VariableAccess getAUse(StackVariable v) { exists(StandardSSA x | result = x.getAUse(this, v)) } + VariableAccess getAUse(StackVariable v) { exists(StandardSsa x | result = x.getAUse(this, v)) } /** * Gets the control-flow node for this definition. This will usually be the @@ -62,7 +65,7 @@ class SsaDefinition extends ControlFlowNodeBase { BasicBlock getBasicBlock() { result.contains(this.getDefinition()) } /** Holds if this definition is a phi node for variable `v`. */ - predicate isPhiNode(StackVariable v) { exists(StandardSSA x | x.phi_node(v, this)) } + predicate isPhiNode(StackVariable v) { exists(StandardSsa x | x.phi_node(v, this)) } /** Gets the location of this definition. */ Location getLocation() { result = this.(ControlFlowNode).getLocation() } @@ -124,7 +127,7 @@ class SsaDefinition extends ControlFlowNodeBase { /** Holds if `(this, v)` reaches the end of basic block `b`. */ predicate reachesEndOfBB(StackVariable v, BasicBlock b) { - exists(StandardSSA x | x.ssaDefinitionReachesEndOfBB(v, this, b)) + exists(StandardSsa x | x.ssaDefinitionReachesEndOfBB(v, this, b)) } /** @@ -147,15 +150,4 @@ class SsaDefinition extends ControlFlowNodeBase { Expr getAnUltimateDefiningValue(StackVariable v) { result = this.getAnUltimateSsaDefinition(v).getDefiningValue(v) } - - /** - * DEPRECATED: this is the old name for `getAnUltimateDefiningValue`. The - * name was confusing as it seemed analogous to `getDefinition` rather than - * `getDefiningValue`. The SSA libraries for other languages use the name - * `getAnUltimateSsaDefinition` to refer to a predicate named - * `getAnUltimateSsaDefinition` in this class. - */ - deprecated Expr getAnUltimateDefinition(StackVariable v) { - result = this.getAnUltimateDefiningValue(v) - } } diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/SSAUtils.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/SSAUtils.qll index b7d0742fac6..2252864c249 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/SSAUtils.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/SSAUtils.qll @@ -114,10 +114,10 @@ private predicate live_at_exit_of_bb(StackVariable v, BasicBlock b) { /** Common SSA logic for standard SSA and range-analysis SSA. */ cached -library class SSAHelper extends int { +library class SsaHelper extends int { /* 0 = StandardSSA, 1 = RangeSSA */ cached - SSAHelper() { this in [0 .. 1] } + SsaHelper() { this in [0 .. 1] } /** * Override to insert a custom phi node for variable `v` at the start of @@ -311,3 +311,6 @@ library class SSAHelper extends int { ssa_use(v, result, _, _) } } + +/** DEPRECATED: Alias for SsaHelper */ +deprecated class SSAHelper = SsaHelper; diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/internal/CFG.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/internal/CFG.qll index ca1964a43c3..96f03c931bf 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/internal/CFG.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/internal/CFG.qll @@ -447,26 +447,6 @@ private predicate skipInitializer(Initializer init) { ) } -/** - * Holds if `e` is an expression in a static initializer that must be evaluated - * at run time. This predicate computes "is non-const" instead of "is const" in - * order to avoid recursion through forall. - */ -private predicate runtimeExprInStaticInitializer(Expr e) { - inStaticInitializer(e) and - if e instanceof AggregateLiteral - then runtimeExprInStaticInitializer(e.getAChild()) - else not e.getFullyConverted().isConstant() -} - -/** Holds if `e` is part of the initializer of a local static variable. */ -private predicate inStaticInitializer(Expr e) { - exists(LocalVariable local | - local.isStatic() and - e.getParent+() = local.getInitializer() - ) -} - /** * Gets the `i`th child of `n` in control-flow order, where the `i`-indexes are * contiguous, and the first index is 0. @@ -1379,7 +1359,7 @@ private module Cached { * true-successors and false-successors. */ cached - predicate qlCFGSuccessor(Node n1, Node n2) { + predicate qlCfgSuccessor(Node n1, Node n2) { exists(Node memberNode, Pos memberPos | subEdgeIncludingDestructors(any(Pos at | at.isAt()), n1, memberNode, memberPos) and normalGroupMember(memberNode, memberPos, n2) @@ -1388,23 +1368,32 @@ private module Cached { conditionalSuccessor(n1, _, n2) } + /** DEPRECATED: Alias for qlCfgSuccessor */ + deprecated predicate qlCFGSuccessor = qlCfgSuccessor/2; + /** * Holds if `n2` is a control-flow node such that the control-flow * edge `(n1, n2)` may be taken when `n1` is an expression that is true. */ cached - predicate qlCFGTrueSuccessor(Node n1, Node n2) { + predicate qlCfgTrueSuccessor(Node n1, Node n2) { conditionalSuccessor(n1, true, n2) and not conditionalSuccessor(n1, false, n2) } + /** DEPRECATED: Alias for qlCfgTrueSuccessor */ + deprecated predicate qlCFGTrueSuccessor = qlCfgTrueSuccessor/2; + /** * Holds if `n2` is a control-flow node such that the control-flow * edge `(n1, n2)` may be taken when `n1` is an expression that is false. */ cached - predicate qlCFGFalseSuccessor(Node n1, Node n2) { + predicate qlCfgFalseSuccessor(Node n1, Node n2) { conditionalSuccessor(n1, false, n2) and not conditionalSuccessor(n1, true, n2) } + + /** DEPRECATED: Alias for qlCfgFalseSuccessor */ + deprecated predicate qlCFGFalseSuccessor = qlCfgFalseSuccessor/2; } diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/internal/ConstantExprs.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/internal/ConstantExprs.qll index a561771fe01..923533ee2fd 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/internal/ConstantExprs.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/internal/ConstantExprs.qll @@ -188,8 +188,8 @@ private predicate nonAnalyzableFunction(Function f) { */ private predicate impossibleFalseEdge(Expr condition, Node succ) { conditionAlwaysTrue(condition) and - qlCFGFalseSuccessor(condition, succ) and - not qlCFGTrueSuccessor(condition, succ) + qlCfgFalseSuccessor(condition, succ) and + not qlCfgTrueSuccessor(condition, succ) } /** @@ -197,8 +197,8 @@ private predicate impossibleFalseEdge(Expr condition, Node succ) { */ private predicate impossibleTrueEdge(Expr condition, Node succ) { conditionAlwaysFalse(condition) and - qlCFGTrueSuccessor(condition, succ) and - not qlCFGFalseSuccessor(condition, succ) + qlCfgTrueSuccessor(condition, succ) and + not qlCfgFalseSuccessor(condition, succ) } /** @@ -960,9 +960,9 @@ library class ConditionEvaluator extends ExprEvaluator { ConditionEvaluator() { this = 0 } override predicate interesting(Expr e) { - qlCFGFalseSuccessor(e, _) + qlCfgFalseSuccessor(e, _) or - qlCFGTrueSuccessor(e, _) + qlCfgTrueSuccessor(e, _) } } diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/TaintTracking.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/TaintTracking.qll index 895bbdc7e22..e10eb8e15a5 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/TaintTracking.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/TaintTracking.qll @@ -20,10 +20,4 @@ import semmle.code.cpp.dataflow.DataFlow2 module TaintTracking { import semmle.code.cpp.dataflow.internal.tainttracking1.TaintTrackingImpl - private import semmle.code.cpp.dataflow.TaintTracking2 - - /** - * DEPRECATED: Use TaintTracking2::Configuration instead. - */ - deprecated class Configuration2 = TaintTracking2::Configuration; } diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/FlowVar.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/FlowVar.qll index c2fe9815836..6a2b087c2e1 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/FlowVar.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/FlowVar.qll @@ -113,10 +113,6 @@ private module PartialDefinitions { abstract class PartialDefinition extends Expr { ControlFlowNode node; - abstract deprecated predicate partiallyDefines(Variable v); - - abstract deprecated predicate partiallyDefinesThis(ThisExpr e); - /** * Gets the subBasicBlock where this `PartialDefinition` is defined. */ @@ -189,10 +185,6 @@ private module PartialDefinitions { ) } - deprecated override predicate partiallyDefines(Variable v) { v = collection } - - deprecated override predicate partiallyDefinesThis(ThisExpr e) { none() } - override predicate definesExpressions(Expr inner, Expr outer) { inner = innerDefinedExpr and outer = this @@ -217,12 +209,6 @@ private module PartialDefinitions { VariablePartialDefinition() { innerDefinedExpr = getInnerDefinedExpr(this, node) } - deprecated override predicate partiallyDefines(Variable v) { - innerDefinedExpr = v.getAnAccess() - } - - deprecated override predicate partiallyDefinesThis(ThisExpr e) { innerDefinedExpr = e } - /** * Holds if this partial definition may modify `inner` (or what it points * to) through `outer`. These expressions will never be `Conversion`s. diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll index 43555af1af9..b344ea9a864 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll @@ -64,13 +64,30 @@ abstract class Configuration extends DataFlow::Configuration { override predicate isSource(DataFlow::Node source) { none() } /** - * Holds if `sink` is a relevant taint sink. + * Holds if `source` is a relevant taint source with the given initial + * `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } + + /** + * Holds if `sink` is a relevant taint sink * * The smaller this predicate is, the faster `hasFlow()` will converge. */ // overridden to provide taint-tracking specific qldoc override predicate isSink(DataFlow::Node sink) { none() } + /** + * Holds if `sink` is a relevant taint sink accepting `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } + /** Holds if the node `node` is a taint sanitizer. */ predicate isSanitizer(DataFlow::Node node) { none() } @@ -79,6 +96,16 @@ abstract class Configuration extends DataFlow::Configuration { defaultTaintSanitizer(node) } + /** + * Holds if the node `node` is a taint sanitizer when the flow state is + * `state`. + */ + predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } + + final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { + this.isSanitizer(node, state) + } + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } @@ -107,6 +134,25 @@ abstract class Configuration extends DataFlow::Configuration { defaultAdditionalTaintStep(node1, node2) } + /** + * Holds if the additional taint propagation step from `node1` to `node2` + * must be taken into account in the analysis. This step is only applicable + * in `state1` and updates the flow state to `state2`. + */ + predicate isAdditionalTaintStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + none() + } + + final override predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + this.isAdditionalTaintStep(node1, state1, node2, state2) + } + override predicate allowImplicitRead(DataFlow::Node node, DataFlow::Content c) { (this.isSink(node) or this.isAdditionalTaintStep(node, _)) and defaultImplicitTaintRead(node, c) diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll index 43555af1af9..b344ea9a864 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll @@ -64,13 +64,30 @@ abstract class Configuration extends DataFlow::Configuration { override predicate isSource(DataFlow::Node source) { none() } /** - * Holds if `sink` is a relevant taint sink. + * Holds if `source` is a relevant taint source with the given initial + * `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } + + /** + * Holds if `sink` is a relevant taint sink * * The smaller this predicate is, the faster `hasFlow()` will converge. */ // overridden to provide taint-tracking specific qldoc override predicate isSink(DataFlow::Node sink) { none() } + /** + * Holds if `sink` is a relevant taint sink accepting `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } + /** Holds if the node `node` is a taint sanitizer. */ predicate isSanitizer(DataFlow::Node node) { none() } @@ -79,6 +96,16 @@ abstract class Configuration extends DataFlow::Configuration { defaultTaintSanitizer(node) } + /** + * Holds if the node `node` is a taint sanitizer when the flow state is + * `state`. + */ + predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } + + final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { + this.isSanitizer(node, state) + } + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } @@ -107,6 +134,25 @@ abstract class Configuration extends DataFlow::Configuration { defaultAdditionalTaintStep(node1, node2) } + /** + * Holds if the additional taint propagation step from `node1` to `node2` + * must be taken into account in the analysis. This step is only applicable + * in `state1` and updates the flow state to `state2`. + */ + predicate isAdditionalTaintStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + none() + } + + final override predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + this.isAdditionalTaintStep(node1, state1, node2, state2) + } + override predicate allowImplicitRead(DataFlow::Node node, DataFlow::Content c) { (this.isSink(node) or this.isAdditionalTaintStep(node, _)) and defaultImplicitTaintRead(node, c) diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/Assignment.qll b/cpp/ql/lib/semmle/code/cpp/exprs/Assignment.qll index 065fae8aa70..fd03220c183 100644 --- a/cpp/ql/lib/semmle/code/cpp/exprs/Assignment.qll +++ b/cpp/ql/lib/semmle/code/cpp/exprs/Assignment.qll @@ -226,13 +226,6 @@ class AssignPointerSubExpr extends AssignOperation, @assignpsubexpr { * ``` */ class ConditionDeclExpr extends Expr, @condition_decl { - /** - * DEPRECATED: Use `getVariableAccess()` or `getInitializingExpr()` instead. - * - * Gets the access using the condition for this declaration. - */ - deprecated Expr getExpr() { result = this.getChild(0) } - override string getAPrimaryQlClass() { result = "ConditionDeclExpr" } /** diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll b/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll index dcbedde4475..309d98cd694 100644 --- a/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll +++ b/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll @@ -118,11 +118,6 @@ class BuiltInNoOp extends BuiltInOperation, @noopexpr { override string getAPrimaryQlClass() { result = "BuiltInNoOp" } } -/** - * DEPRECATED: Use `BuiltInOperationBuiltInOffsetOf` instead. - */ -deprecated class BuiltInOperationOffsetOf = BuiltInOperationBuiltInOffsetOf; - /** * A C/C++ `__builtin_offsetof` built-in operation (used by some implementations * of `offsetof`). The operation retains its semantics even in the presence @@ -465,11 +460,6 @@ class BuiltInOperationIsUnion extends BuiltInOperation, @isunionexpr { override string getAPrimaryQlClass() { result = "BuiltInOperationIsUnion" } } -/** - * DEPRECATED: Use `BuiltInOperationBuiltInTypesCompatibleP` instead. - */ -deprecated class BuiltInOperationBuiltInTypes = BuiltInOperationBuiltInTypesCompatibleP; - /** * A C++ `__builtin_types_compatible_p` built-in operation (used by some * implementations of the `` header). diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/Cast.qll b/cpp/ql/lib/semmle/code/cpp/exprs/Cast.qll index 701cfbfd636..3cb8946c198 100644 --- a/cpp/ql/lib/semmle/code/cpp/exprs/Cast.qll +++ b/cpp/ql/lib/semmle/code/cpp/exprs/Cast.qll @@ -666,13 +666,6 @@ class TypeidOperator extends Expr, @type_id { */ Type getResultType() { typeid_bind(underlyingElement(this), unresolveElement(result)) } - /** - * DEPRECATED: Use `getResultType()` instead. - * - * Gets the type that is returned by this typeid expression. - */ - deprecated Type getSpecifiedType() { result = this.getResultType() } - override string getAPrimaryQlClass() { result = "TypeidOperator" } /** @@ -731,13 +724,6 @@ class SizeofExprOperator extends SizeofOperator { /** Gets the contained expression. */ Expr getExprOperand() { result = this.getChild(0) } - /** - * DEPRECATED: Use `getExprOperand()` instead - * - * Gets the contained expression. - */ - deprecated Expr getExpr() { result = this.getExprOperand() } - override string toString() { result = "sizeof()" } override predicate mayBeImpure() { this.getExprOperand().mayBeImpure() } @@ -759,13 +745,6 @@ class SizeofTypeOperator extends SizeofOperator { /** Gets the contained type. */ Type getTypeOperand() { sizeof_bind(underlyingElement(this), unresolveElement(result)) } - /** - * DEPRECATED: Use `getTypeOperand()` instead - * - * Gets the contained type. - */ - deprecated Type getSpecifiedType() { result = this.getTypeOperand() } - override string toString() { result = "sizeof(" + this.getTypeOperand().getName() + ")" } override predicate mayBeImpure() { none() } @@ -794,11 +773,6 @@ class AlignofExprOperator extends AlignofOperator { */ Expr getExprOperand() { result = this.getChild(0) } - /** - * DEPRECATED: Use `getExprOperand()` instead. - */ - deprecated Expr getExpr() { result = this.getExprOperand() } - override string toString() { result = "alignof()" } } @@ -814,11 +788,6 @@ class AlignofTypeOperator extends AlignofOperator { /** Gets the contained type. */ Type getTypeOperand() { sizeof_bind(underlyingElement(this), unresolveElement(result)) } - /** - * DEPRECATED: Use `getTypeOperand()` instead. - */ - deprecated Type getSpecifiedType() { result = this.getTypeOperand() } - override string toString() { result = "alignof(" + this.getTypeOperand().getName() + ")" } } diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/ComparisonOperation.qll b/cpp/ql/lib/semmle/code/cpp/exprs/ComparisonOperation.qll index 5ae0155fdb3..2c6387f1844 100644 --- a/cpp/ql/lib/semmle/code/cpp/exprs/ComparisonOperation.qll +++ b/cpp/ql/lib/semmle/code/cpp/exprs/ComparisonOperation.qll @@ -48,16 +48,6 @@ class NEExpr extends EqualityOperation, @neexpr { class RelationalOperation extends ComparisonOperation, @rel_op_expr { override int getPrecedence() { result = 10 } - /** - * DEPRECATED: Use `getGreaterOperand()` instead. - */ - deprecated Expr getLarge() { result = getGreaterOperand() } - - /** - * DEPRECATED: Use `getLesserOperand()` instead. - */ - deprecated Expr getSmall() { result = getLesserOperand() } - /** * Gets the operand on the "greater" (or "greater-or-equal") side * of this relational expression, that is, the side that is larger diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll b/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll index a10a94f357d..14399078231 100644 --- a/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll +++ b/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll @@ -114,13 +114,6 @@ class Expr extends StmtParent, @expr { */ Type getUnspecifiedType() { result = this.getType().getUnspecifiedType() } - /** - * Gets an integer indicating the type of expression that this represents. - * - * DEPRECATED: use the subclasses of `Expr` rather than relying on this predicate. - */ - deprecated int getKind() { exprs(underlyingElement(this), result, _) } - /** Gets a textual representation of this expression. */ override string toString() { none() } diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/Literal.qll b/cpp/ql/lib/semmle/code/cpp/exprs/Literal.qll index 18ca03740ac..93609763ec3 100644 --- a/cpp/ql/lib/semmle/code/cpp/exprs/Literal.qll +++ b/cpp/ql/lib/semmle/code/cpp/exprs/Literal.qll @@ -164,16 +164,6 @@ class HexLiteral extends Literal { class AggregateLiteral extends Expr, @aggregateliteral { override string getAPrimaryQlClass() { result = "AggregateLiteral" } - /** - * DEPRECATED: Use ClassAggregateLiteral.getFieldExpr() instead. - * - * Gets the expression within the aggregate literal that is used to initialise field `f`, - * if this literal is being used to initialise a class/struct instance. - */ - deprecated Expr getCorrespondingExpr(Field f) { - result = this.(ClassAggregateLiteral).getFieldExpr(f) - } - override predicate mayBeImpure() { this.getAChild().mayBeImpure() } override predicate mayBeGloballyImpure() { this.getAChild().mayBeGloballyImpure() } diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/ObjectiveC.qll b/cpp/ql/lib/semmle/code/cpp/exprs/ObjectiveC.qll deleted file mode 100644 index c651ae9b153..00000000000 --- a/cpp/ql/lib/semmle/code/cpp/exprs/ObjectiveC.qll +++ /dev/null @@ -1,297 +0,0 @@ -/** - * DEPRECATED: Objective-C is no longer supported. - */ - -import semmle.code.cpp.exprs.Expr -import semmle.code.cpp.Class -import semmle.code.cpp.ObjectiveC -private import semmle.code.cpp.internal.ResolveClass - -/** - * DEPRECATED: Objective-C is no longer supported. - * An Objective C message expression, for example `[myColor changeColorToRed:5.0 green:2.0 blue:6.0]`. - */ -deprecated class MessageExpr extends Expr, Call { - MessageExpr() { none() } - - override string toString() { none() } - - /** - * Gets the selector of this message expression, for example `-changeColorToRed:green:blue:`. - */ - string getSelector() { none() } - - /** - * Gets the function invoked by this message expression, as inferred by the compiler. - * - * If the compiler could infer the type of the receiver, and that type had a method - * whose name matched the selector, then the result of this predicate is said method. - * Otherwise this predicate has no result. - * - * In all cases, actual function dispatch isn't performed until runtime, but the - * lack of a static target is often cause for concern. - */ - MemberFunction getStaticTarget() { none() } - - /** - * Provided for compatibility with Call. It is the same as the static target. - */ - override MemberFunction getTarget() { none() } - - /** - * Holds if the compiler could infer a function as the target of this message. - * - * In all cases, actual function dispatch isn't performed until runtime, but the - * lack of a static target is often cause for concern. - */ - predicate hasStaticTarget() { none() } - - /** - * Gets the number of arguments passed by this message expression. - * - * In most cases, this equals the number of colons in the selector, but this needn't be the - * case for variadic methods like "-initWithFormat:", which can have more than one argument. - */ - override int getNumberOfArguments() { none() } - - /** - * Gets an argument passed by this message expression. - */ - override Expr getAnArgument() { none() } - - /** - * Gets the nth argument passed by this message expression. - * - * The range of `n` is [`0` .. `getNumberOfArguments()`]. - */ - override Expr getArgument(int n) { none() } - - override int getPrecedence() { none() } -} - -/** - * DEPRECATED: Objective-C is no longer supported. - * An Objective C message expression whose receiver is `super`, for example `[super init]`. - */ -deprecated class SuperMessageExpr extends MessageExpr { - SuperMessageExpr() { none() } -} - -/** - * DEPRECATED: Objective-C is no longer supported. - * An Objective C message expression whose receiver is the name of a class, and - * is therefore calling a class method rather than an instance method. This occurs - * most commonly for the "+alloc", "+new", and "+class" selectors. - */ -deprecated class ClassMessageExpr extends MessageExpr { - ClassMessageExpr() { none() } - - /** - * Gets the class which is the receiver of this message. - */ - Type getReceiver() { none() } -} - -/** - * DEPRECATED: Objective-C is no longer supported. - * An Objective C message expression whose receiver is an expression (which includes the - * common case of the receiver being "self"). - */ -deprecated class ExprMessageExpr extends MessageExpr { - ExprMessageExpr() { none() } - - /** - * Gets the expression which gives the receiver of this message. - */ - Expr getReceiver() { none() } - - /** - * Gets the Objective C class of which the receiving expression is an instance. - * - * If the receiving expression has type `id` or type `id

` for some protocol `P`, - * then there will be no result. If the receiving expression has type `C*` or type - * `C

*` for some protocol `P`, then the result will be the type `C`. - */ - ObjectiveClass getReceiverClass() { none() } - - /** - * Gets the Objective C classes and/or protocols which are statically implemented - * by the receiving expression. - * - * If the receiving expression has type `id`, then there will be no result. - * If the receiving expression has type `id

`, then `P` will be the sole result. - * If the receiving expression has type `C*`, then `C` will be the sole result. - * If the receiving expression has type `C

*`, then `C` and `P` will both be results. - */ - Class getAReceiverClassOrProtocol() { none() } -} - -/** - * DEPRECATED: Objective-C is no longer supported. - * An access to an Objective C property using dot syntax. - * - * Such accesses are de-sugared into a message expression to the property's getter or setter. - */ -deprecated class PropertyAccess extends ExprMessageExpr { - PropertyAccess() { none() } - - /** - * Gets the property being accessed by this expression. - */ - Property getProperty() { none() } -} - -/** - * DEPRECATED: Objective-C is no longer supported. - * An Objective C `@selector` expression, for example `@selector(driveForDistance:)`. - */ -deprecated class AtSelectorExpr extends Expr { - AtSelectorExpr() { none() } - - override string toString() { none() } - - /** - * Gets the selector of this `@selector` expression, for example `driveForDistance:`. - */ - string getSelector() { none() } -} - -/** - * DEPRECATED: Objective-C is no longer supported. - * An Objective C `@protocol` expression, for example `@protocol(SomeProtocol)`. - */ -deprecated class AtProtocolExpr extends Expr { - AtProtocolExpr() { none() } - - override string toString() { none() } - - /** - * Gets the protocol of this `@protocol` expression, for example `SomeProtocol`. - */ - Protocol getProtocol() { none() } -} - -/** - * DEPRECATED: Objective-C is no longer supported. - * An Objective C `@encode` expression, for example `@encode(int *)`. - */ -deprecated class AtEncodeExpr extends Expr { - AtEncodeExpr() { none() } - - override string toString() { none() } - - /** - * Gets the type this `@encode` expression encodes, for example `int *`. - */ - Type getEncodedType() { none() } -} - -/** - * DEPRECATED: Objective-C is no longer supported. - * An Objective C throw expression. - */ -deprecated class ObjcThrowExpr extends ThrowExpr { - ObjcThrowExpr() { none() } - - override string toString() { none() } -} - -/** - * DEPRECATED: Objective-C is no longer supported. - * An Objective C throw expression with no argument (which causes the - * current exception to be re-thrown). - */ -deprecated class ObjcReThrowExpr extends ReThrowExpr, ObjcThrowExpr { - ObjcReThrowExpr() { none() } - - override string toString() { none() } -} - -/** - * DEPRECATED: Objective-C is no longer supported. - * An Objective C @ expression which boxes a single value, such as @(22). - */ -deprecated class AtExpr extends UnaryOperation { - AtExpr() { none() } - - override string toString() { none() } - - override string getOperator() { none() } -} - -/** - * DEPRECATED: Objective-C is no longer supported. - * An Objective C @[...] literal. - */ -deprecated class ArrayLiteral extends Expr { - ArrayLiteral() { none() } - - /** Gets a textual representation of this array literal. */ - override string toString() { none() } - - /** An element of the array */ - Expr getElement(int i) { none() } -} - -/** - * DEPRECATED: Objective-C is no longer supported. - * An Objective C @{...} literal. - */ -deprecated class DictionaryLiteral extends Expr { - DictionaryLiteral() { none() } - - /** Gets a textual representation of this dictionary literal. */ - override string toString() { none() } -} - -/** - * DEPRECATED: Objective-C is no longer supported. - * An Objective C @"..." string literal. - */ -deprecated class ObjCLiteralString extends TextLiteral { - ObjCLiteralString() { none() } -} - -/** - * DEPRECATED: Objective-C is no longer supported. - * An Objective C/C++ overloaded subscripting access expression. - * - * Either - * obj[idx] - * or - * obj[idx] = expr - */ -deprecated class SubscriptExpr extends Expr { - SubscriptExpr() { none() } - - /** - * Gets the object expression being subscripted. - */ - Expr getSubscriptBase() { none() } - - /** - * Gets the expression giving the index into the object. - */ - Expr getSubscriptIndex() { none() } - - /** - * Gets the expression being assigned (if this is an assignment). - */ - Expr getAssignedExpr() { none() } - - override string toString() { none() } -} - -/** - * DEPRECATED: Objective-C is no longer supported. - * An Objective C _cmd expression. - */ -deprecated class CmdExpr extends Expr { - CmdExpr() { none() } - - override string toString() { none() } - - override predicate mayBeImpure() { none() } - - override predicate mayBeGloballyImpure() { none() } -} diff --git a/cpp/ql/lib/semmle/code/cpp/headers/MultipleInclusion.qll b/cpp/ql/lib/semmle/code/cpp/headers/MultipleInclusion.qll index 5a12af29694..8698b47ff63 100644 --- a/cpp/ql/lib/semmle/code/cpp/headers/MultipleInclusion.qll +++ b/cpp/ql/lib/semmle/code/cpp/headers/MultipleInclusion.qll @@ -39,19 +39,6 @@ class CorrectIncludeGuard extends IncludeGuardedHeader { PreprocessorEndif getEndif() { correctIncludeGuard(this, _, _, result, _) } } -/** - * DEPRECATED: no longer useful. - */ -deprecated class NotIncludedGuard extends IncludeGuardedHeader { - NotIncludedGuard() { none() } - - /** Gets the `#ifndef` directive used to prevent multiple inclusion of this file. */ - PreprocessorIfndef getIfndef() { result.getFile() = this } - - /** Gets the `#endif` directive closing this file. */ - PreprocessorEndif getEndif() { result.getFile() = this } -} - /** * A file with no code in it. */ diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll index c6942b7adfe..be5403734ce 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll @@ -129,11 +129,11 @@ private class FromGlobalVarTaintTrackingCfg extends TaintTracking2::Configuratio } private predicate readsVariable(LoadInstruction load, Variable var) { - load.getSourceAddress().(VariableAddressInstruction).getASTVariable() = var + load.getSourceAddress().(VariableAddressInstruction).getAstVariable() = var } private predicate writesVariable(StoreInstruction store, Variable var) { - store.getDestinationAddress().(VariableAddressInstruction).getASTVariable() = var + store.getDestinationAddress().(VariableAddressInstruction).getAstVariable() = var } /** @@ -489,9 +489,9 @@ module TaintedWithPath { /** Gets the element that `pathNode` wraps, if any. */ Element getElementFromPathNode(PathNode pathNode) { exists(DataFlow::Node node | node = pathNode.(WrapPathNode).inner().getNode() | - result = node.asInstruction().getAST() + result = node.asInstruction().getAst() or - result = node.asOperand().getDef().getAST() + result = node.asOperand().getDef().getAst() ) or result = pathNode.(EndpointPathNode).inner() diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/MustFlow.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/MustFlow.qll new file mode 100644 index 00000000000..1f3ea2a4d3d --- /dev/null +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/MustFlow.qll @@ -0,0 +1,270 @@ +/** + * This file provides a library for inter-procedural must-flow data flow analysis. + * Unlike `DataFlow.qll`, the analysis provided by this file checks whether data _must_ flow + * from a source to a _sink_. + */ + +private import cpp +import semmle.code.cpp.ir.dataflow.DataFlow +private import semmle.code.cpp.ir.IR + +/** + * A configuration of a data flow analysis that performs must-flow analysis. This is different + * from `DataFlow.qll` which performs may-flow analysis (i.e., it finds paths where the source _may_ + * flow to the sink). + * + * Like in `DataFlow.qll`, each use of the `MustFlow.qll` library must define its own unique extension + * of this abstract class. To create a configuration, extend this class with a subclass whose + * characteristic predicate is a unique singleton string and override `isSource`, `isSink` (and + * `isAdditionalFlowStep` if additional steps are required). + */ +abstract class MustFlowConfiguration extends string { + bindingset[this] + MustFlowConfiguration() { any() } + + /** + * Holds if `source` is a relevant data flow source. + */ + abstract predicate isSource(DataFlow::Node source); + + /** + * Holds if `sink` is a relevant data flow sink. + */ + abstract predicate isSink(DataFlow::Node sink); + + /** + * Holds if the additional flow step from `node1` to `node2` must be taken + * into account in the analysis. + */ + predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { none() } + + /** + * Holds if data must flow from `source` to `sink` for this configuration. + * + * The corresponding paths are generated from the end-points and the graph + * included in the module `PathGraph`. + */ + final predicate hasFlowPath(MustFlowPathNode source, MustFlowPathSink sink) { + this.isSource(source.getNode()) and + source.getASuccessor+() = sink + } +} + +/** Holds if `node` flows from a source. */ +pragma[nomagic] +private predicate flowsFromSource(DataFlow::Node node, MustFlowConfiguration config) { + config.isSource(node) + or + exists(DataFlow::Node mid | + step(mid, node, config) and + flowsFromSource(mid, pragma[only_bind_into](config)) + ) +} + +/** Holds if `node` flows to a sink. */ +pragma[nomagic] +private predicate flowsToSink(DataFlow::Node node, MustFlowConfiguration config) { + flowsFromSource(node, pragma[only_bind_into](config)) and + ( + config.isSink(node) + or + exists(DataFlow::Node mid | + step(node, mid, config) and + flowsToSink(mid, pragma[only_bind_into](config)) + ) + ) +} + +cached +private module Cached { + /** Holds if `p` is the `n`'th parameter of the non-virtual function `f`. */ + private predicate parameterOf(Parameter p, Function f, int n) { + not f.isVirtual() and f.getParameter(n) = p + } + + /** + * Holds if `instr` is the `n`'th argument to a call to the non-virtual function `f`, and + * `init` is the corresponding initialization instruction that receives the value of `instr` in `f`. + */ + private predicate flowIntoParameter( + Function f, int n, CallInstruction call, Instruction instr, InitializeParameterInstruction init + ) { + not f.isVirtual() and + call.getPositionalArgument(n) = instr and + f = call.getStaticCallTarget() and + getEnclosingNonVirtualFunctionInitializeParameter(init, f) and + init.getParameter().getIndex() = pragma[only_bind_into](pragma[only_bind_out](n)) + } + + /** + * Holds if `instr` is an argument to a call to the function `f`, and `init` is the + * corresponding initialization instruction that receives the value of `instr` in `f`. + */ + pragma[noinline] + private predicate getPositionalArgumentInitParam( + CallInstruction call, Instruction instr, InitializeParameterInstruction init, Function f + ) { + exists(int n | + parameterOf(_, f, n) and + flowIntoParameter(f, pragma[only_bind_into](pragma[only_bind_out](n)), call, instr, init) + ) + } + + /** + * Holds if `instr` is the qualifier to a call to the non-virtual function `f`, and + * `init` is the corresponding initialization instruction that receives the value of + * `instr` in `f`. + */ + pragma[noinline] + private predicate getThisArgumentInitParam( + CallInstruction call, Instruction instr, InitializeParameterInstruction init, Function f + ) { + not f.isVirtual() and + call.getStaticCallTarget() = f and + getEnclosingNonVirtualFunctionInitializeParameter(init, f) and + call.getThisArgument() = instr and + init.getIRVariable() instanceof IRThisVariable + } + + /** Holds if `f` is the enclosing non-virtual function of `init`. */ + private predicate getEnclosingNonVirtualFunctionInitializeParameter( + InitializeParameterInstruction init, Function f + ) { + not f.isVirtual() and + init.getEnclosingFunction() = f + } + + /** Holds if `f` is the enclosing non-virtual function of `init`. */ + private predicate getEnclosingNonVirtualFunctionInitializeIndirection( + InitializeIndirectionInstruction init, Function f + ) { + not f.isVirtual() and + init.getEnclosingFunction() = f + } + + /** + * Holds if `instr` is an argument (or argument indirection) to a call, and + * `succ` is the corresponding initialization instruction in the call target. + */ + private predicate flowThroughCallable(Instruction argument, Instruction parameter) { + // Flow from an argument to a parameter + exists(CallInstruction call, InitializeParameterInstruction init | init = parameter | + getPositionalArgumentInitParam(call, argument, init, call.getStaticCallTarget()) + or + getThisArgumentInitParam(call, argument, init, call.getStaticCallTarget()) + ) + or + // Flow from argument indirection to parameter indirection + exists( + CallInstruction call, ReadSideEffectInstruction read, InitializeIndirectionInstruction init + | + init = parameter and + read.getPrimaryInstruction() = call and + getEnclosingNonVirtualFunctionInitializeIndirection(init, call.getStaticCallTarget()) + | + exists(int n | + read.getSideEffectOperand().getAnyDef() = argument and + read.getIndex() = pragma[only_bind_into](n) and + init.getParameter().getIndex() = pragma[only_bind_into](n) + ) + or + call.getThisArgument() = argument and + init.getIRVariable() instanceof IRThisVariable + ) + } + + private predicate instructionToOperandStep(Instruction instr, Operand operand) { + operand.getDef() = instr + } + + /** + * Holds if data flows from `operand` to `instr`. + * + * This predicate ignores flow through `PhiInstruction`s to create a 'must flow' relation. + */ + private predicate operandToInstructionStep(Operand operand, Instruction instr) { + instr.(CopyInstruction).getSourceValueOperand() = operand + or + instr.(ConvertInstruction).getUnaryOperand() = operand + or + instr.(CheckedConvertOrNullInstruction).getUnaryOperand() = operand + or + instr.(InheritanceConversionInstruction).getUnaryOperand() = operand + or + instr.(ChiInstruction).getTotalOperand() = operand + } + + cached + predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { + instructionToOperandStep(nodeFrom.asInstruction(), nodeTo.asOperand()) + or + flowThroughCallable(nodeFrom.asInstruction(), nodeTo.asInstruction()) + or + operandToInstructionStep(nodeFrom.asOperand(), nodeTo.asInstruction()) + } +} + +/** Holds if `nodeFrom` flows to `nodeTo`. */ +private predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo, MustFlowConfiguration config) { + exists(config) and + Cached::step(nodeFrom, nodeTo) + or + config.isAdditionalFlowStep(nodeFrom, nodeTo) +} + +private newtype TLocalPathNode = + MkLocalPathNode(DataFlow::Node n, MustFlowConfiguration config) { + flowsToSink(n, config) and + ( + config.isSource(n) + or + exists(MustFlowPathNode mid | step(mid.getNode(), n, config)) + ) + } + +/** A `Node` that is in a path from a source to a sink. */ +class MustFlowPathNode extends TLocalPathNode { + DataFlow::Node n; + + MustFlowPathNode() { this = MkLocalPathNode(n, _) } + + /** Gets the underlying node. */ + DataFlow::Node getNode() { result = n } + + /** Gets a textual representation of this node. */ + string toString() { result = n.toString() } + + /** Gets the location of this element. */ + Location getLocation() { result = n.getLocation() } + + /** Gets a successor node, if any. */ + MustFlowPathNode getASuccessor() { + step(this.getNode(), result.getNode(), this.getConfiguration()) + } + + /** Gets the associated configuration. */ + MustFlowConfiguration getConfiguration() { this = MkLocalPathNode(_, result) } +} + +private class MustFlowPathSink extends MustFlowPathNode { + MustFlowPathSink() { this.getConfiguration().isSink(this.getNode()) } +} + +/** + * Provides the query predicates needed to include a graph in a path-problem query. + */ +module PathGraph { + private predicate reach(MustFlowPathNode n) { + n instanceof MustFlowPathSink or reach(n.getASuccessor()) + } + + /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ + query predicate edges(MustFlowPathNode a, MustFlowPathNode b) { + a.getASuccessor() = b and reach(b) + } + + /** Holds if `n` is a node in the graph of data flow path explanations. */ + query predicate nodes(MustFlowPathNode n, string key, string val) { + reach(n) and key = "semmle.label" and val = n.toString() + } +} diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/ResolveCall.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/ResolveCall.qll index f25386d3ba8..bcf2fa8c7db 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/ResolveCall.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/ResolveCall.qll @@ -17,7 +17,7 @@ private import semmle.code.cpp.ir.IR */ Function resolveCall(Call call) { exists(CallInstruction callInstruction | - callInstruction.getAST() = call and + callInstruction.getAst() = call and result = viableCallable(callInstruction) ) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/TaintTracking.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/TaintTracking.qll index c95fcd3f574..7eada0bb244 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/TaintTracking.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/TaintTracking.qll @@ -20,10 +20,4 @@ import semmle.code.cpp.ir.dataflow.DataFlow2 module TaintTracking { import semmle.code.cpp.ir.dataflow.internal.tainttracking1.TaintTrackingImpl - private import semmle.code.cpp.ir.dataflow.TaintTracking2 - - /** - * DEPRECATED: Use TaintTracking2::Configuration instead. - */ - deprecated class Configuration2 = TaintTracking2::Configuration; } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowDispatch.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowDispatch.qll index 509ee01ec07..c0bdb656e0e 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowDispatch.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowDispatch.qll @@ -116,12 +116,12 @@ private module VirtualDispatch { /** Holds if `addressInstr` is an instruction that produces the address of `var`. */ private predicate addressOfGlobal(Instruction addressInstr, GlobalOrNamespaceVariable var) { // Access directly to the global variable - addressInstr.(VariableAddressInstruction).getASTVariable() = var + addressInstr.(VariableAddressInstruction).getAstVariable() = var or // Access to a field on a global union exists(FieldAddressInstruction fa | fa = addressInstr and - fa.getObjectAddress().(VariableAddressInstruction).getASTVariable() = var and + fa.getObjectAddress().(VariableAddressInstruction).getAstVariable() = var and fa.getField().getDeclaringType() instanceof Union ) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll index 75b530e937d..c629550bc3a 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll @@ -158,14 +158,6 @@ class Node extends TIRDataFlowNode { */ Expr asPartialDefinition() { result = this.(PartialDefinitionNode).getDefinedExpr() } - /** - * DEPRECATED: See UninitializedNode. - * - * Gets the uninitialized local variable corresponding to this node, if - * any. - */ - deprecated LocalVariable asUninitialized() { none() } - /** * Gets an upper bound on the type of this node. */ @@ -439,7 +431,7 @@ class SsaPhiNode extends Node, TSsaPhiNode { SsaPhiNode() { this = TSsaPhiNode(phi) } - /* Get the phi node associated with this node. */ + /** Gets the phi node associated with this node. */ Ssa::PhiNode getPhiNode() { result = phi } override Declaration getEnclosingCallable() { result = this.getFunction() } @@ -560,22 +552,6 @@ class ParameterIndirectionNode extends ParameterNode { override string toString() { result = "*" + instr.getIRVariable().toString() } } -/** - * DEPRECATED: Data flow was never an accurate way to determine what - * expressions might be uninitialized. It errs on the side of saying that - * everything is uninitialized, and this is even worse in the IR because the IR - * doesn't use syntactic hints to rule out variables that are definitely - * initialized. - * - * The value of an uninitialized local variable, viewed as a node in a data - * flow graph. - */ -deprecated class UninitializedNode extends Node { - UninitializedNode() { none() } - - LocalVariable getLocalVariable() { none() } -} - /** * A node associated with an object after an operation that might have * changed its state. @@ -725,14 +701,6 @@ InstructionNode instructionNode(Instruction instr) { result.getInstruction() = i */ OperandNode operandNode(Operand operand) { result.getOperand() = operand } -/** - * DEPRECATED: use `definitionByReferenceNodeFromArgument` instead. - * - * Gets the `Node` corresponding to a definition by reference of the variable - * that is passed as `argument` of a call. - */ -deprecated DefinitionByReferenceNode definitionByReferenceNode(Expr e) { result.getArgument() = e } - /** * Gets the `Node` corresponding to the value of evaluating `e` or any of its * conversions. There is no result if `e` is a `Conversion`. For data flowing diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImplCommon.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImplCommon.qll index 19bf1d4f27d..eed0d050735 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImplCommon.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImplCommon.qll @@ -287,20 +287,6 @@ private module SsaDefReaches { ) } - /** - * Holds if the SSA definition of `v` at `def` reaches uncertain SSA definition - * `redef` in the same basic block, without crossing another SSA definition of `v`. - */ - predicate ssaDefReachesUncertainDefWithinBlock( - SourceVariable v, Definition def, UncertainWriteDefinition redef - ) { - exists(BasicBlock bb, int rnk, int i | - ssaDefReachesRank(bb, def, rnk, v) and - rnk = ssaRefRank(bb, i, v, SsaDef()) - 1 and - redef.definesAt(v, bb, i) - ) - } - /** * Same as `ssaRefRank()`, but restricted to a particular SSA definition `def`. */ diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingImpl.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingImpl.qll index 43555af1af9..b344ea9a864 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingImpl.qll @@ -64,13 +64,30 @@ abstract class Configuration extends DataFlow::Configuration { override predicate isSource(DataFlow::Node source) { none() } /** - * Holds if `sink` is a relevant taint sink. + * Holds if `source` is a relevant taint source with the given initial + * `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } + + /** + * Holds if `sink` is a relevant taint sink * * The smaller this predicate is, the faster `hasFlow()` will converge. */ // overridden to provide taint-tracking specific qldoc override predicate isSink(DataFlow::Node sink) { none() } + /** + * Holds if `sink` is a relevant taint sink accepting `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } + /** Holds if the node `node` is a taint sanitizer. */ predicate isSanitizer(DataFlow::Node node) { none() } @@ -79,6 +96,16 @@ abstract class Configuration extends DataFlow::Configuration { defaultTaintSanitizer(node) } + /** + * Holds if the node `node` is a taint sanitizer when the flow state is + * `state`. + */ + predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } + + final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { + this.isSanitizer(node, state) + } + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } @@ -107,6 +134,25 @@ abstract class Configuration extends DataFlow::Configuration { defaultAdditionalTaintStep(node1, node2) } + /** + * Holds if the additional taint propagation step from `node1` to `node2` + * must be taken into account in the analysis. This step is only applicable + * in `state1` and updates the flow state to `state2`. + */ + predicate isAdditionalTaintStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + none() + } + + final override predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + this.isAdditionalTaintStep(node1, state1, node2, state2) + } + override predicate allowImplicitRead(DataFlow::Node node, DataFlow::Content c) { (this.isSink(node) or this.isAdditionalTaintStep(node, _)) and defaultImplicitTaintRead(node, c) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingImpl.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingImpl.qll index 43555af1af9..b344ea9a864 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingImpl.qll @@ -64,13 +64,30 @@ abstract class Configuration extends DataFlow::Configuration { override predicate isSource(DataFlow::Node source) { none() } /** - * Holds if `sink` is a relevant taint sink. + * Holds if `source` is a relevant taint source with the given initial + * `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } + + /** + * Holds if `sink` is a relevant taint sink * * The smaller this predicate is, the faster `hasFlow()` will converge. */ // overridden to provide taint-tracking specific qldoc override predicate isSink(DataFlow::Node sink) { none() } + /** + * Holds if `sink` is a relevant taint sink accepting `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } + /** Holds if the node `node` is a taint sanitizer. */ predicate isSanitizer(DataFlow::Node node) { none() } @@ -79,6 +96,16 @@ abstract class Configuration extends DataFlow::Configuration { defaultTaintSanitizer(node) } + /** + * Holds if the node `node` is a taint sanitizer when the flow state is + * `state`. + */ + predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } + + final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { + this.isSanitizer(node, state) + } + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } @@ -107,6 +134,25 @@ abstract class Configuration extends DataFlow::Configuration { defaultAdditionalTaintStep(node1, node2) } + /** + * Holds if the additional taint propagation step from `node1` to `node2` + * must be taken into account in the analysis. This step is only applicable + * in `state1` and updates the flow state to `state2`. + */ + predicate isAdditionalTaintStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + none() + } + + final override predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + this.isAdditionalTaintStep(node1, state1, node2, state2) + } + override predicate allowImplicitRead(DataFlow::Node node, DataFlow::Content c) { (this.isSink(node) or this.isAdditionalTaintStep(node, _)) and defaultImplicitTaintRead(node, c) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking3/TaintTrackingImpl.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking3/TaintTrackingImpl.qll index 43555af1af9..b344ea9a864 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking3/TaintTrackingImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking3/TaintTrackingImpl.qll @@ -64,13 +64,30 @@ abstract class Configuration extends DataFlow::Configuration { override predicate isSource(DataFlow::Node source) { none() } /** - * Holds if `sink` is a relevant taint sink. + * Holds if `source` is a relevant taint source with the given initial + * `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } + + /** + * Holds if `sink` is a relevant taint sink * * The smaller this predicate is, the faster `hasFlow()` will converge. */ // overridden to provide taint-tracking specific qldoc override predicate isSink(DataFlow::Node sink) { none() } + /** + * Holds if `sink` is a relevant taint sink accepting `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } + /** Holds if the node `node` is a taint sanitizer. */ predicate isSanitizer(DataFlow::Node node) { none() } @@ -79,6 +96,16 @@ abstract class Configuration extends DataFlow::Configuration { defaultTaintSanitizer(node) } + /** + * Holds if the node `node` is a taint sanitizer when the flow state is + * `state`. + */ + predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } + + final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { + this.isSanitizer(node, state) + } + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } @@ -107,6 +134,25 @@ abstract class Configuration extends DataFlow::Configuration { defaultAdditionalTaintStep(node1, node2) } + /** + * Holds if the additional taint propagation step from `node1` to `node2` + * must be taken into account in the analysis. This step is only applicable + * in `state1` and updates the flow state to `state2`. + */ + predicate isAdditionalTaintStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + none() + } + + final override predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + this.isAdditionalTaintStep(node1, state1, node2, state2) + } + override predicate allowImplicitRead(DataFlow::Node node, DataFlow::Content c) { (this.isSink(node) or this.isAdditionalTaintStep(node, _)) and defaultImplicitTaintRead(node, c) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll index 146fc270738..ca4708857a7 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll @@ -55,7 +55,10 @@ class IRVariable extends TIRVariable { * Gets the AST node that declared this variable, or that introduced this * variable as part of the AST-to-IR translation. */ - Language::AST getAST() { none() } + Language::AST getAst() { none() } + + /** DEPRECATED: Alias for getAst */ + deprecated Language::AST getAST() { result = getAst() } /** * Gets an identifier string for the variable. This identifier is unique @@ -66,7 +69,7 @@ class IRVariable extends TIRVariable { /** * Gets the source location of this variable. */ - final Language::Location getLocation() { result = getAST().getLocation() } + final Language::Location getLocation() { result = getAst().getLocation() } /** * Gets the IR for the function that references this variable. @@ -90,7 +93,10 @@ class IRUserVariable extends IRVariable, TIRUserVariable { final override string toString() { result = getVariable().toString() } - final override Language::AST getAST() { result = var } + final override Language::AST getAst() { result = var } + + /** DEPRECATED: Alias for getAst */ + deprecated override Language::AST getAST() { result = getAst() } final override string getUniqueId() { result = getVariable().toString() + " " + getVariable().getLocation().toString() @@ -157,7 +163,10 @@ class IRGeneratedVariable extends IRVariable { final override Language::LanguageType getLanguageType() { result = type } - final override Language::AST getAST() { result = ast } + final override Language::AST getAst() { result = ast } + + /** DEPRECATED: Alias for getAst */ + deprecated override Language::AST getAST() { result = getAst() } override string toString() { result = getBaseString() + getLocationString() } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll index 1c2cc493338..e5a908bbf9a 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll @@ -41,7 +41,7 @@ class Instruction extends Construction::TStageInstruction { } /** Gets a textual representation of this element. */ - final string toString() { result = this.getOpcode().toString() + ": " + this.getAST().toString() } + final string toString() { result = this.getOpcode().toString() + ": " + this.getAst().toString() } /** * Gets a string showing the result, opcode, and operands of the instruction, equivalent to what @@ -136,7 +136,7 @@ class Instruction extends Construction::TStageInstruction { string getResultId() { this.shouldGenerateDumpStrings() and result = - this.getResultPrefix() + this.getAST().getLocation().getStartLine() + "_" + this.getLineRank() + this.getResultPrefix() + this.getAst().getLocation().getStartLine() + "_" + this.getLineRank() } /** @@ -208,12 +208,15 @@ class Instruction extends Construction::TStageInstruction { /** * Gets the AST that caused this instruction to be generated. */ - final Language::AST getAST() { result = Construction::getInstructionAST(this) } + final Language::AST getAst() { result = Construction::getInstructionAst(this) } + + /** DEPRECATED: Alias for getAst */ + deprecated Language::AST getAST() { result = this.getAst() } /** * Gets the location of the source code for this instruction. */ - final Language::Location getLocation() { result = this.getAST().getLocation() } + final Language::Location getLocation() { result = this.getAst().getLocation() } /** * Gets the `Expr` whose result is computed by this instruction, if any. The `Expr` may be a @@ -459,7 +462,10 @@ class VariableInstruction extends Instruction { /** * Gets the AST variable that this instruction's IR variable refers to, if one exists. */ - final Language::Variable getASTVariable() { result = var.(IRUserVariable).getVariable() } + final Language::Variable getAstVariable() { result = var.(IRUserVariable).getVariable() } + + /** DEPRECATED: Alias for getAstVariable */ + deprecated Language::Variable getASTVariable() { result = this.getAstVariable() } } /** diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Operand.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Operand.qll index 89b82657c3b..c1e997d5844 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Operand.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Operand.qll @@ -18,7 +18,7 @@ private import internal.OperandInternal * of `TOperand` that are used in this stage. */ private class TStageOperand = - TRegisterOperand or TNonSSAMemoryOperand or TPhiOperand or TChiOperand; + TRegisterOperand or TNonSsaMemoryOperand or TPhiOperand or TChiOperand; /** * A known location. Testing `loc instanceof KnownLocation` will account for non existing locations, as @@ -38,7 +38,7 @@ class Operand extends TStageOperand { // Ensure that the operand does not refer to instructions from earlier stages that are unreachable here exists(Instruction use, Instruction def | this = registerOperand(use, _, def)) or - exists(Instruction use | this = nonSSAMemoryOperand(use, _)) + exists(Instruction use | this = nonSsaMemoryOperand(use, _)) or exists(Instruction use, Instruction def, IRBlock predecessorBlock | this = phiOperand(use, def, predecessorBlock, _) or @@ -209,7 +209,7 @@ class Operand extends TStageOperand { class MemoryOperand extends Operand { cached MemoryOperand() { - this instanceof TNonSSAMemoryOperand or + this instanceof TNonSsaMemoryOperand or this instanceof TPhiOperand or this instanceof TChiOperand } @@ -249,7 +249,7 @@ class NonPhiOperand extends Operand { NonPhiOperand() { this = registerOperand(useInstr, tag, _) or - this = nonSSAMemoryOperand(useInstr, tag) or + this = nonSsaMemoryOperand(useInstr, tag) or this = chiOperand(useInstr, tag) } @@ -299,7 +299,7 @@ class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, TNonPhiMemoryOpe cached NonPhiMemoryOperand() { - this = nonSSAMemoryOperand(useInstr, tag) + this = nonSsaMemoryOperand(useInstr, tag) or this = chiOperand(useInstr, tag) } 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 fdb645e03f0..2dc735f49df 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 @@ -99,7 +99,7 @@ private predicate filteredNumberableInstruction(Instruction instr) { // count rather than strictcount to handle missing AST elements // separate instanceof and inline casts to avoid failed casts with a count of 0 instr instanceof VariableAddressInstruction and - count(instr.(VariableAddressInstruction).getIRVariable().getAST()) != 1 + count(instr.(VariableAddressInstruction).getIRVariable().getAst()) != 1 or instr instanceof ConstantInstruction and count(instr.getResultIRType()) != 1 @@ -121,7 +121,7 @@ private predicate variableAddressValueNumber( // The underlying AST element is used as value-numbering key instead of the // `IRVariable` to work around a problem where a variable or expression with // multiple types gives rise to multiple `IRVariable`s. - unique( | | instr.getIRVariable().getAST()) = ast + unique( | | instr.getIRVariable().getAst()) = ast } private predicate initializeParameterValueNumber( @@ -131,7 +131,7 @@ private predicate initializeParameterValueNumber( // The underlying AST element is used as value-numbering key instead of the // `IRVariable` to work around a problem where a variable or expression with // multiple types gives rise to multiple `IRVariable`s. - instr.getIRVariable().getAST() = var + instr.getIRVariable().getAst() = var } private predicate constantValueNumber( diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasConfiguration.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasConfiguration.qll index 8ba91d70087..7e12ebc1c90 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasConfiguration.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasConfiguration.qll @@ -2,12 +2,12 @@ private import AliasConfigurationInternal private import semmle.code.cpp.ir.implementation.unaliased_ssa.IR private import cpp private import AliasAnalysis -private import semmle.code.cpp.ir.implementation.unaliased_ssa.internal.SimpleSSA as UnaliasedSSA +private import semmle.code.cpp.ir.implementation.unaliased_ssa.internal.SimpleSSA as UnaliasedSsa private newtype TAllocation = TVariableAllocation(IRVariable var) { // Only model variables that were not already handled in unaliased SSA. - not UnaliasedSSA::canReuseSSAForVariable(var) + not UnaliasedSsa::canReuseSsaForVariable(var) } or TIndirectParameterAllocation(IRAutomaticVariable var) { exists(InitializeIndirectionInstruction instr | instr.getIRVariable() = var) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasedSSA.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasedSSA.qll index acdae2b758a..76a99026d59 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasedSSA.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasedSSA.qll @@ -133,7 +133,10 @@ abstract class MemoryLocation extends TMemoryLocation { */ predicate isAlwaysAllocatedOnStack() { none() } - final predicate canReuseSSA() { none() } + final predicate canReuseSsa() { none() } + + /** DEPRECATED: Alias for canReuseSsa */ + deprecated predicate canReuseSSA() { canReuseSsa() } } /** @@ -569,13 +572,16 @@ private Overlap getVariableMemoryLocationOverlap( * Holds if the def/use information for the result of `instr` can be reused from the previous * iteration of the IR. */ -predicate canReuseSSAForOldResult(Instruction instr) { OldSSA::canReuseSSAForMemoryResult(instr) } +predicate canReuseSsaForOldResult(Instruction instr) { OldSSA::canReuseSsaForMemoryResult(instr) } + +/** DEPRECATED: Alias for canReuseSsaForOldResult */ +deprecated predicate canReuseSSAForOldResult = canReuseSsaForOldResult/1; bindingset[result, b] private boolean unbindBool(boolean b) { result != b.booleanNot() } MemoryLocation getResultMemoryLocation(Instruction instr) { - not canReuseSSAForOldResult(instr) and + not canReuseSsaForOldResult(instr) and exists(MemoryAccessKind kind, boolean isMayAccess | kind = instr.getResultMemoryAccess() and (if instr.hasResultMayMemoryAccess() then isMayAccess = true else isMayAccess = false) and @@ -608,7 +614,7 @@ MemoryLocation getResultMemoryLocation(Instruction instr) { } MemoryLocation getOperandMemoryLocation(MemoryOperand operand) { - not canReuseSSAForOldResult(operand.getAnyDef()) and + not canReuseSsaForOldResult(operand.getAnyDef()) and exists(MemoryAccessKind kind, boolean isMayAccess | kind = operand.getMemoryAccess() and (if operand.hasMayReadMemoryAccess() then isMayAccess = true else isMayAccess = false) and diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/OperandInternal.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/OperandInternal.qll index b47c20e97ef..c7a5389901b 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/OperandInternal.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/OperandInternal.qll @@ -1,2 +1,2 @@ private import semmle.code.cpp.ir.implementation.internal.TOperand -import AliasedSSAOperands +import AliasedSsaOperands diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/PrintSSA.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/PrintSSA.qll index 72bb239c153..c7487872512 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/PrintSSA.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/PrintSSA.qll @@ -2,7 +2,7 @@ private import SSAConstructionInternal private import OldIR private import Alias private import SSAConstruction -private import DebugSSA +private import DebugSsa bindingset[offset] private string getKeySuffixForOffset(int offset) { diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConsistency.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConsistency.qll index 5686bb439eb..1c75529be00 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConsistency.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConsistency.qll @@ -1,2 +1,2 @@ private import SSAConstruction as SSA -import SSA::SSAConsistency +import SSA::SsaConsistency diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll index 5092e921cb3..13ec2ca4ca4 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll @@ -112,7 +112,7 @@ private module Cached { exists(Alias::getResultMemoryLocation(oldInstruction)) or // This result was already modeled by a previous iteration of SSA. - Alias::canReuseSSAForOldResult(oldInstruction) + Alias::canReuseSsaForOldResult(oldInstruction) } cached @@ -182,7 +182,7 @@ private module Cached { * unreachable, this predicate will recurse through any degenerate `Phi` instructions to find the * true definition. */ - private Instruction getNewDefinitionFromOldSSA(OldIR::MemoryOperand oldOperand, Overlap overlap) { + private Instruction getNewDefinitionFromOldSsa(OldIR::MemoryOperand oldOperand, Overlap overlap) { exists(Overlap originalOverlap | originalOverlap = oldOperand.getDefinitionOverlap() and ( @@ -191,7 +191,7 @@ private module Cached { or exists(OldIR::PhiInputOperand phiOperand, Overlap phiOperandOverlap | phiOperand = getDegeneratePhiOperand(oldOperand.getAnyDef()) and - result = getNewDefinitionFromOldSSA(phiOperand, phiOperandOverlap) and + result = getNewDefinitionFromOldSsa(phiOperand, phiOperandOverlap) and overlap = combineOverlap(pragma[only_bind_out](phiOperandOverlap), pragma[only_bind_out](originalOverlap)) @@ -233,7 +233,7 @@ private module Cached { ) or exists(OldIR::NonPhiMemoryOperand oldOperand | - result = getNewDefinitionFromOldSSA(oldOperand, overlap) and + result = getNewDefinitionFromOldSsa(oldOperand, overlap) and oldOperand.getUse() = instruction and tag = oldOperand.getOperandTag() ) @@ -307,13 +307,13 @@ private module Cached { * Gets the new definition instruction for the operand of `instr` that flows from the block * `newPredecessorBlock`, based on that operand's definition in the old IR. */ - private Instruction getNewPhiOperandDefinitionFromOldSSA( + private Instruction getNewPhiOperandDefinitionFromOldSsa( Instruction instr, IRBlock newPredecessorBlock, Overlap overlap ) { exists(OldIR::PhiInstruction oldPhi, OldIR::PhiInputOperand oldOperand | oldPhi = getOldInstruction(instr) and oldOperand = oldPhi.getInputOperand(getOldBlock(newPredecessorBlock)) and - result = getNewDefinitionFromOldSSA(oldOperand, overlap) + result = getNewDefinitionFromOldSsa(oldOperand, overlap) ) } @@ -333,7 +333,7 @@ private module Cached { overlap = Alias::getOverlap(actualDefLocation, useLocation) ) or - result = getNewPhiOperandDefinitionFromOldSSA(instr, newPredecessorBlock, overlap) + result = getNewPhiOperandDefinitionFromOldSsa(instr, newPredecessorBlock, overlap) } cached @@ -412,17 +412,17 @@ private module Cached { } cached - Language::AST getInstructionAST(Instruction instr) { - result = getOldInstruction(instr).getAST() + Language::AST getInstructionAst(Instruction instr) { + result = getOldInstruction(instr).getAst() or exists(RawIR::Instruction blockStartInstr | instr = phiInstruction(blockStartInstr, _) and - result = blockStartInstr.getAST() + result = blockStartInstr.getAst() ) or exists(RawIR::Instruction primaryInstr | instr = chiInstruction(primaryInstr) and - result = primaryInstr.getAST() + result = primaryInstr.getAst() ) or exists(IRFunctionBase irFunc | @@ -430,6 +430,12 @@ private module Cached { ) } + /** DEPRECATED: Alias for getInstructionAst */ + cached + deprecated Language::AST getInstructionAST(Instruction instr) { + result = getInstructionAst(instr) + } + cached Language::LanguageType getInstructionResultType(Instruction instr) { result = instr.(RawIR::Instruction).getResultLanguageType() @@ -975,35 +981,41 @@ module DefUse { } } -predicate canReuseSSAForMemoryResult(Instruction instruction) { +predicate canReuseSsaForMemoryResult(Instruction instruction) { exists(OldInstruction oldInstruction | oldInstruction = getOldInstruction(instruction) and ( // The previous iteration said it was reusable, so we should mark it as reusable as well. - Alias::canReuseSSAForOldResult(oldInstruction) + Alias::canReuseSsaForOldResult(oldInstruction) or // The current alias analysis says it is reusable. - Alias::getResultMemoryLocation(oldInstruction).canReuseSSA() + Alias::getResultMemoryLocation(oldInstruction).canReuseSsa() ) ) or exists(Alias::MemoryLocation defLocation | // This is a `Phi` for a reusable location, so the result of the `Phi` is reusable as well. instruction = phiInstruction(_, defLocation) and - defLocation.canReuseSSA() + defLocation.canReuseSsa() ) // We don't support reusing SSA for any location that could create a `Chi` instruction. } +/** DEPRECATED: Alias for canReuseSsaForMemoryResult */ +deprecated predicate canReuseSSAForMemoryResult = canReuseSsaForMemoryResult/1; + /** * Expose some of the internal predicates to PrintSSA.qll. We do this by publically importing those modules in the * `DebugSSA` module, which is then imported by PrintSSA. */ -module DebugSSA { +module DebugSsa { import PhiInsertion import DefUse } +/** DEPRECATED: Alias for DebugSsa */ +deprecated module DebugSSA = DebugSsa; + import CachedForDebugging cached @@ -1038,7 +1050,7 @@ private module CachedForDebugging { private OldIR::IRTempVariable getOldTempVariable(IRTempVariable var) { result.getEnclosingFunction() = var.getEnclosingFunction() and - result.getAST() = var.getAST() and + result.getAst() = var.getAst() and result.getTag() = var.getTag() } @@ -1061,7 +1073,7 @@ private module CachedForDebugging { int maxValue() { result = 2147483647 } } -module SSAConsistency { +module SsaConsistency { /** * Holds if a `MemoryOperand` has more than one `MemoryLocation` assigned by alias analysis. */ @@ -1114,6 +1126,9 @@ module SSAConsistency { } } +/** DEPRECATED: Alias for SsaConsistency */ +deprecated module SSAConsistency = SsaConsistency; + /** * Provides the portion of the parameterized IR interface that is used to construct the SSA stages * of the IR. The raw stage of the IR does not expose these predicates. diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstructionInternal.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstructionInternal.qll index a1ce2629cc2..74919a57870 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstructionInternal.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstructionInternal.qll @@ -2,7 +2,7 @@ import semmle.code.cpp.ir.implementation.unaliased_ssa.IR as OldIR import semmle.code.cpp.ir.implementation.unaliased_ssa.internal.reachability.ReachableBlock as Reachability import semmle.code.cpp.ir.implementation.unaliased_ssa.internal.reachability.Dominance as Dominance import semmle.code.cpp.ir.implementation.aliased_ssa.IR as NewIR -import semmle.code.cpp.ir.implementation.internal.TInstruction::AliasedSSAInstructions as SSAInstructions +import semmle.code.cpp.ir.implementation.internal.TInstruction::AliasedSsaInstructions as SSAInstructions import semmle.code.cpp.ir.internal.IRCppLanguage as Language import AliasedSSA as Alias -import semmle.code.cpp.ir.implementation.internal.TOperand::AliasedSSAOperands as SSAOperands +import semmle.code.cpp.ir.implementation.internal.TOperand::AliasedSsaOperands as SSAOperands diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/internal/TInstruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/internal/TInstruction.qll index 4b3f19cbdde..5a7099d9fa2 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/internal/TInstruction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/internal/TInstruction.qll @@ -19,24 +19,24 @@ newtype TInstruction = ) { IRConstruction::Raw::hasInstruction(tag1, tag2) } or - TUnaliasedSSAPhiInstruction( - TRawInstruction blockStartInstr, UnaliasedSSA::SSA::MemoryLocation memoryLocation + TUnaliasedSsaPhiInstruction( + TRawInstruction blockStartInstr, UnaliasedSsa::SSA::MemoryLocation memoryLocation ) { - UnaliasedSSA::SSA::hasPhiInstruction(blockStartInstr, memoryLocation) + UnaliasedSsa::SSA::hasPhiInstruction(blockStartInstr, memoryLocation) } or - TUnaliasedSSAChiInstruction(TRawInstruction primaryInstruction) { none() } or - TUnaliasedSSAUnreachedInstruction(IRFunctionBase irFunc) { - UnaliasedSSA::SSA::hasUnreachedInstruction(irFunc) + TUnaliasedSsaChiInstruction(TRawInstruction primaryInstruction) { none() } or + TUnaliasedSsaUnreachedInstruction(IRFunctionBase irFunc) { + UnaliasedSsa::SSA::hasUnreachedInstruction(irFunc) } or - TAliasedSSAPhiInstruction( + TAliasedSsaPhiInstruction( TRawInstruction blockStartInstr, AliasedSSA::SSA::MemoryLocation memoryLocation ) { AliasedSSA::SSA::hasPhiInstruction(blockStartInstr, memoryLocation) } or - TAliasedSSAChiInstruction(TRawInstruction primaryInstruction) { + TAliasedSsaChiInstruction(TRawInstruction primaryInstruction) { AliasedSSA::SSA::hasChiInstruction(primaryInstruction) } or - TAliasedSSAUnreachedInstruction(IRFunctionBase irFunc) { + TAliasedSsaUnreachedInstruction(IRFunctionBase irFunc) { AliasedSSA::SSA::hasUnreachedInstruction(irFunc) } @@ -46,58 +46,64 @@ newtype TInstruction = * These wrappers are not parameterized because it is not possible to invoke an IPA constructor via * a class alias. */ -module UnaliasedSSAInstructions { - class TPhiInstruction = TUnaliasedSSAPhiInstruction; +module UnaliasedSsaInstructions { + class TPhiInstruction = TUnaliasedSsaPhiInstruction; TPhiInstruction phiInstruction( - TRawInstruction blockStartInstr, UnaliasedSSA::SSA::MemoryLocation memoryLocation + TRawInstruction blockStartInstr, UnaliasedSsa::SSA::MemoryLocation memoryLocation ) { - result = TUnaliasedSSAPhiInstruction(blockStartInstr, memoryLocation) + result = TUnaliasedSsaPhiInstruction(blockStartInstr, memoryLocation) } TRawInstruction reusedPhiInstruction(TRawInstruction blockStartInstr) { none() } - class TChiInstruction = TUnaliasedSSAChiInstruction; + class TChiInstruction = TUnaliasedSsaChiInstruction; TChiInstruction chiInstruction(TRawInstruction primaryInstruction) { - result = TUnaliasedSSAChiInstruction(primaryInstruction) + result = TUnaliasedSsaChiInstruction(primaryInstruction) } - class TUnreachedInstruction = TUnaliasedSSAUnreachedInstruction; + class TUnreachedInstruction = TUnaliasedSsaUnreachedInstruction; TUnreachedInstruction unreachedInstruction(IRFunctionBase irFunc) { - result = TUnaliasedSSAUnreachedInstruction(irFunc) + result = TUnaliasedSsaUnreachedInstruction(irFunc) } } +/** DEPRECATED: Alias for UnaliasedSsaInstructions */ +deprecated module UnaliasedSSAInstructions = UnaliasedSsaInstructions; + /** * Provides wrappers for the constructors of each branch of `TInstruction` that is used by the * aliased SSA stage. * These wrappers are not parameterized because it is not possible to invoke an IPA constructor via * a class alias. */ -module AliasedSSAInstructions { - class TPhiInstruction = TAliasedSSAPhiInstruction or TUnaliasedSSAPhiInstruction; +module AliasedSsaInstructions { + class TPhiInstruction = TAliasedSsaPhiInstruction or TUnaliasedSsaPhiInstruction; TPhiInstruction phiInstruction( TRawInstruction blockStartInstr, AliasedSSA::SSA::MemoryLocation memoryLocation ) { - result = TAliasedSSAPhiInstruction(blockStartInstr, memoryLocation) + result = TAliasedSsaPhiInstruction(blockStartInstr, memoryLocation) } TPhiInstruction reusedPhiInstruction(TRawInstruction blockStartInstr) { - result = TUnaliasedSSAPhiInstruction(blockStartInstr, _) + result = TUnaliasedSsaPhiInstruction(blockStartInstr, _) } - class TChiInstruction = TAliasedSSAChiInstruction; + class TChiInstruction = TAliasedSsaChiInstruction; TChiInstruction chiInstruction(TRawInstruction primaryInstruction) { - result = TAliasedSSAChiInstruction(primaryInstruction) + result = TAliasedSsaChiInstruction(primaryInstruction) } - class TUnreachedInstruction = TAliasedSSAUnreachedInstruction; + class TUnreachedInstruction = TAliasedSsaUnreachedInstruction; TUnreachedInstruction unreachedInstruction(IRFunctionBase irFunc) { - result = TAliasedSSAUnreachedInstruction(irFunc) + result = TAliasedSsaUnreachedInstruction(irFunc) } } + +/** DEPRECATED: Alias for AliasedSsaInstructions */ +deprecated module AliasedSSAInstructions = AliasedSsaInstructions; diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/internal/TInstructionInternal.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/internal/TInstructionInternal.qll index adaaaca9cd8..2c9ac1c4b80 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/internal/TInstructionInternal.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/internal/TInstructionInternal.qll @@ -1,4 +1,4 @@ import semmle.code.cpp.ir.internal.IRCppLanguage as Language import semmle.code.cpp.ir.implementation.raw.internal.IRConstruction as IRConstruction -import semmle.code.cpp.ir.implementation.unaliased_ssa.internal.SSAConstruction as UnaliasedSSA +import semmle.code.cpp.ir.implementation.unaliased_ssa.internal.SSAConstruction as UnaliasedSsa import semmle.code.cpp.ir.implementation.aliased_ssa.internal.SSAConstruction as AliasedSSA diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/internal/TOperand.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/internal/TOperand.qll index e86494af03a..bc69754fe32 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/internal/TOperand.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/internal/TOperand.qll @@ -31,7 +31,7 @@ private module Internal { TNoOperand() { none() } or // Can be "removed" later when there's unreachable code // These operands can be reused across all three stages. They just get different defs. - TNonSSAMemoryOperand(Raw::Instruction useInstr, MemoryOperandTag tag) { + TNonSsaMemoryOperand(Raw::Instruction useInstr, MemoryOperandTag tag) { // Has no definition in raw but will get definitions later useInstr.getOpcode().hasOperand(tag) } or @@ -49,11 +49,11 @@ private module Internal { // important that we use the same definition of "is variable aliased" across // the phases. TAliasedPhiOperand( - TAliasedSSAPhiInstruction useInstr, Aliased::IRBlock predecessorBlock, Overlap overlap + TAliasedSsaPhiInstruction useInstr, Aliased::IRBlock predecessorBlock, Overlap overlap ) { exists(AliasedConstruction::getPhiOperandDefinition(useInstr, predecessorBlock, overlap)) } or - TAliasedChiOperand(TAliasedSSAChiInstruction useInstr, ChiOperandTag tag) { any() } + TAliasedChiOperand(TAliasedSsaChiInstruction useInstr, ChiOperandTag tag) { any() } } /** @@ -72,13 +72,21 @@ private module Shared { result = Internal::TRegisterOperand(useInstr, tag, defInstr) } - class TNonSSAMemoryOperand = Internal::TNonSSAMemoryOperand; + class TNonSsaMemoryOperand = Internal::TNonSsaMemoryOperand; + + /** DEPRECATED: Alias for TNonSsaMemoryOperand */ + deprecated class TNonSSAMemoryOperand = TNonSsaMemoryOperand; /** * Returns the non-Phi memory operand with the specified parameters. */ - TNonSSAMemoryOperand nonSSAMemoryOperand(TRawInstruction useInstr, MemoryOperandTag tag) { - result = Internal::TNonSSAMemoryOperand(useInstr, tag) + TNonSsaMemoryOperand nonSsaMemoryOperand(TRawInstruction useInstr, MemoryOperandTag tag) { + result = Internal::TNonSsaMemoryOperand(useInstr, tag) + } + + /** DEPRECATED: Alias for nonSsaMemoryOperand */ + deprecated TNonSSAMemoryOperand nonSSAMemoryOperand(TRawInstruction useInstr, MemoryOperandTag tag) { + result = nonSsaMemoryOperand(useInstr, tag) } } @@ -95,7 +103,7 @@ module RawOperands { class TChiOperand = Internal::TNoOperand; - class TNonPhiMemoryOperand = TNonSSAMemoryOperand or TChiOperand; + class TNonPhiMemoryOperand = TNonSsaMemoryOperand or TChiOperand; /** * Returns the Phi operand with the specified parameters. @@ -126,14 +134,14 @@ module RawOperands { * These wrappers are not parameterized because it is not possible to invoke an IPA constructor via * a class alias. */ -module UnaliasedSSAOperands { +module UnaliasedSsaOperands { import Shared class TPhiOperand = Internal::TUnaliasedPhiOperand; class TChiOperand = Internal::TNoOperand; - class TNonPhiMemoryOperand = TNonSSAMemoryOperand or TChiOperand; + class TNonPhiMemoryOperand = TNonSsaMemoryOperand or TChiOperand; /** * Returns the Phi operand with the specified parameters. @@ -159,20 +167,23 @@ module UnaliasedSSAOperands { TChiOperand chiOperand(Unaliased::Instruction useInstr, ChiOperandTag tag) { none() } } +/** DEPRECATED: Alias for UnaliasedSsaOperands */ +deprecated module UnaliasedSSAOperands = UnaliasedSsaOperands; + /** * Provides wrappers for the constructors of each branch of `TOperand` that is used by the * asliased SSA stage. * These wrappers are not parameterized because it is not possible to invoke an IPA constructor via * a class alias. */ -module AliasedSSAOperands { +module AliasedSsaOperands { import Shared class TPhiOperand = Internal::TAliasedPhiOperand or Internal::TUnaliasedPhiOperand; class TChiOperand = Internal::TAliasedChiOperand; - class TNonPhiMemoryOperand = TNonSSAMemoryOperand or TChiOperand; + class TNonPhiMemoryOperand = TNonSsaMemoryOperand or TChiOperand; /** * Returns the Phi operand with the specified parameters. @@ -202,7 +213,10 @@ module AliasedSSAOperands { /** * Returns the Chi operand with the specified parameters. */ - TChiOperand chiOperand(TAliasedSSAChiInstruction useInstr, ChiOperandTag tag) { + TChiOperand chiOperand(TAliasedSsaChiInstruction useInstr, ChiOperandTag tag) { result = Internal::TAliasedChiOperand(useInstr, tag) } } + +/** DEPRECATED: Alias for AliasedSsaOperands */ +deprecated module AliasedSSAOperands = AliasedSsaOperands; diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRVariable.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRVariable.qll index 146fc270738..ca4708857a7 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRVariable.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRVariable.qll @@ -55,7 +55,10 @@ class IRVariable extends TIRVariable { * Gets the AST node that declared this variable, or that introduced this * variable as part of the AST-to-IR translation. */ - Language::AST getAST() { none() } + Language::AST getAst() { none() } + + /** DEPRECATED: Alias for getAst */ + deprecated Language::AST getAST() { result = getAst() } /** * Gets an identifier string for the variable. This identifier is unique @@ -66,7 +69,7 @@ class IRVariable extends TIRVariable { /** * Gets the source location of this variable. */ - final Language::Location getLocation() { result = getAST().getLocation() } + final Language::Location getLocation() { result = getAst().getLocation() } /** * Gets the IR for the function that references this variable. @@ -90,7 +93,10 @@ class IRUserVariable extends IRVariable, TIRUserVariable { final override string toString() { result = getVariable().toString() } - final override Language::AST getAST() { result = var } + final override Language::AST getAst() { result = var } + + /** DEPRECATED: Alias for getAst */ + deprecated override Language::AST getAST() { result = getAst() } final override string getUniqueId() { result = getVariable().toString() + " " + getVariable().getLocation().toString() @@ -157,7 +163,10 @@ class IRGeneratedVariable extends IRVariable { final override Language::LanguageType getLanguageType() { result = type } - final override Language::AST getAST() { result = ast } + final override Language::AST getAst() { result = ast } + + /** DEPRECATED: Alias for getAst */ + deprecated override Language::AST getAST() { result = getAst() } override string toString() { result = getBaseString() + getLocationString() } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll index 1c2cc493338..e5a908bbf9a 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll @@ -41,7 +41,7 @@ class Instruction extends Construction::TStageInstruction { } /** Gets a textual representation of this element. */ - final string toString() { result = this.getOpcode().toString() + ": " + this.getAST().toString() } + final string toString() { result = this.getOpcode().toString() + ": " + this.getAst().toString() } /** * Gets a string showing the result, opcode, and operands of the instruction, equivalent to what @@ -136,7 +136,7 @@ class Instruction extends Construction::TStageInstruction { string getResultId() { this.shouldGenerateDumpStrings() and result = - this.getResultPrefix() + this.getAST().getLocation().getStartLine() + "_" + this.getLineRank() + this.getResultPrefix() + this.getAst().getLocation().getStartLine() + "_" + this.getLineRank() } /** @@ -208,12 +208,15 @@ class Instruction extends Construction::TStageInstruction { /** * Gets the AST that caused this instruction to be generated. */ - final Language::AST getAST() { result = Construction::getInstructionAST(this) } + final Language::AST getAst() { result = Construction::getInstructionAst(this) } + + /** DEPRECATED: Alias for getAst */ + deprecated Language::AST getAST() { result = this.getAst() } /** * Gets the location of the source code for this instruction. */ - final Language::Location getLocation() { result = this.getAST().getLocation() } + final Language::Location getLocation() { result = this.getAst().getLocation() } /** * Gets the `Expr` whose result is computed by this instruction, if any. The `Expr` may be a @@ -459,7 +462,10 @@ class VariableInstruction extends Instruction { /** * Gets the AST variable that this instruction's IR variable refers to, if one exists. */ - final Language::Variable getASTVariable() { result = var.(IRUserVariable).getVariable() } + final Language::Variable getAstVariable() { result = var.(IRUserVariable).getVariable() } + + /** DEPRECATED: Alias for getAstVariable */ + deprecated Language::Variable getASTVariable() { result = this.getAstVariable() } } /** diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Operand.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Operand.qll index 89b82657c3b..c1e997d5844 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Operand.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Operand.qll @@ -18,7 +18,7 @@ private import internal.OperandInternal * of `TOperand` that are used in this stage. */ private class TStageOperand = - TRegisterOperand or TNonSSAMemoryOperand or TPhiOperand or TChiOperand; + TRegisterOperand or TNonSsaMemoryOperand or TPhiOperand or TChiOperand; /** * A known location. Testing `loc instanceof KnownLocation` will account for non existing locations, as @@ -38,7 +38,7 @@ class Operand extends TStageOperand { // Ensure that the operand does not refer to instructions from earlier stages that are unreachable here exists(Instruction use, Instruction def | this = registerOperand(use, _, def)) or - exists(Instruction use | this = nonSSAMemoryOperand(use, _)) + exists(Instruction use | this = nonSsaMemoryOperand(use, _)) or exists(Instruction use, Instruction def, IRBlock predecessorBlock | this = phiOperand(use, def, predecessorBlock, _) or @@ -209,7 +209,7 @@ class Operand extends TStageOperand { class MemoryOperand extends Operand { cached MemoryOperand() { - this instanceof TNonSSAMemoryOperand or + this instanceof TNonSsaMemoryOperand or this instanceof TPhiOperand or this instanceof TChiOperand } @@ -249,7 +249,7 @@ class NonPhiOperand extends Operand { NonPhiOperand() { this = registerOperand(useInstr, tag, _) or - this = nonSSAMemoryOperand(useInstr, tag) or + this = nonSsaMemoryOperand(useInstr, tag) or this = chiOperand(useInstr, tag) } @@ -299,7 +299,7 @@ class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, TNonPhiMemoryOpe cached NonPhiMemoryOperand() { - this = nonSSAMemoryOperand(useInstr, tag) + this = nonSsaMemoryOperand(useInstr, tag) or this = chiOperand(useInstr, tag) } 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 fdb645e03f0..2dc735f49df 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 @@ -99,7 +99,7 @@ private predicate filteredNumberableInstruction(Instruction instr) { // count rather than strictcount to handle missing AST elements // separate instanceof and inline casts to avoid failed casts with a count of 0 instr instanceof VariableAddressInstruction and - count(instr.(VariableAddressInstruction).getIRVariable().getAST()) != 1 + count(instr.(VariableAddressInstruction).getIRVariable().getAst()) != 1 or instr instanceof ConstantInstruction and count(instr.getResultIRType()) != 1 @@ -121,7 +121,7 @@ private predicate variableAddressValueNumber( // The underlying AST element is used as value-numbering key instead of the // `IRVariable` to work around a problem where a variable or expression with // multiple types gives rise to multiple `IRVariable`s. - unique( | | instr.getIRVariable().getAST()) = ast + unique( | | instr.getIRVariable().getAst()) = ast } private predicate initializeParameterValueNumber( @@ -131,7 +131,7 @@ private predicate initializeParameterValueNumber( // The underlying AST element is used as value-numbering key instead of the // `IRVariable` to work around a problem where a variable or expression with // multiple types gives rise to multiple `IRVariable`s. - instr.getIRVariable().getAST() = var + instr.getIRVariable().getAst() = var } private predicate constantValueNumber( diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll index e8fcf3fcdf3..16158a4c73a 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll @@ -48,7 +48,7 @@ module Raw { cached predicate hasTempVariable(Function func, Locatable ast, TempVariableTag tag, CppType type) { exists(TranslatedElement element | - element.getAST() = ast and + element.getAst() = ast and func = element.getFunction() and element.hasTempVariable(tag, type) ) @@ -75,7 +75,7 @@ module Raw { tag = getInstructionTag(instruction) and ( result = element.getInstructionVariable(tag) or - result.(IRStringLiteral).getAST() = element.getInstructionStringLiteral(tag) + result.(IRStringLiteral).getAst() = element.getInstructionStringLiteral(tag) ) ) } @@ -339,7 +339,7 @@ Instruction getInstructionBackEdgeSuccessor(Instruction instruction, EdgeKind ki // such a `goto` creates a back edge. exists(TranslatedElement s, GotoStmt goto | not isStrictlyForwardGoto(goto) and - goto = s.getAST() and + goto = s.getAst() and exists(InstructionTag tag | result = s.getInstructionSuccessor(tag, kind) and instruction = s.getInstruction(tag) @@ -352,8 +352,13 @@ private predicate isStrictlyForwardGoto(GotoStmt goto) { goto.getLocation().isBefore(goto.getTarget().getLocation()) } -Locatable getInstructionAST(TStageInstruction instr) { - result = getInstructionTranslatedElement(instr).getAST() +Locatable getInstructionAst(TStageInstruction instr) { + result = getInstructionTranslatedElement(instr).getAst() +} + +/** DEPRECATED: Alias for getInstructionAst */ +deprecated Locatable getInstructionAST(TStageInstruction instr) { + result = getInstructionAst(instr) } CppType getInstructionResultType(TStageInstruction instr) { diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll index 8ef5334b598..66c601736af 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll @@ -175,7 +175,10 @@ abstract class TranslatedSideEffects extends TranslatedElement { /** Gets the expression whose side effects are being modeled. */ abstract Expr getExpr(); - final override Locatable getAST() { result = getExpr() } + final override Locatable getAst() { result = getExpr() } + + /** DEPRECATED: Alias for getAst */ + deprecated override Locatable getAST() { result = getAst() } final override Function getFunction() { result = getExpr().getEnclosingFunction() } @@ -522,7 +525,10 @@ class TranslatedArgumentExprSideEffect extends TranslatedArgumentSideEffect, this = TTranslatedArgumentExprSideEffect(call, arg, index, sideEffectOpcode) } - final override Locatable getAST() { result = arg } + final override Locatable getAst() { result = arg } + + /** DEPRECATED: Alias for getAst */ + deprecated override Locatable getAST() { result = getAst() } final override Type getIndirectionType() { result = arg.getUnspecifiedType().(DerivedType).getBaseType() @@ -553,7 +559,10 @@ class TranslatedStructorQualifierSideEffect extends TranslatedArgumentSideEffect index = -1 } - final override Locatable getAST() { result = call } + final override Locatable getAst() { result = call } + + /** DEPRECATED: Alias for getAst */ + deprecated override Locatable getAST() { result = getAst() } final override Type getIndirectionType() { result = call.getTarget().getDeclaringType() } @@ -574,7 +583,10 @@ class TranslatedCallSideEffect extends TranslatedSideEffect, TTranslatedCallSide TranslatedCallSideEffect() { this = TTranslatedCallSideEffect(expr, sideEffectOpcode) } - override Locatable getAST() { result = expr } + override Locatable getAst() { result = expr } + + /** DEPRECATED: Alias for getAst */ + deprecated override Locatable getAST() { result = getAst() } override Expr getPrimaryExpr() { result = expr } @@ -612,7 +624,10 @@ class TranslatedAllocationSideEffect extends TranslatedSideEffect, TTranslatedAl TranslatedAllocationSideEffect() { this = TTranslatedAllocationSideEffect(expr) } - override Locatable getAST() { result = expr } + override Locatable getAst() { result = expr } + + /** DEPRECATED: Alias for getAst */ + deprecated override Locatable getAST() { result = getAst() } override Expr getPrimaryExpr() { result = expr } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCondition.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCondition.qll index 0779d6fbda5..528acf4498b 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCondition.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCondition.qll @@ -19,7 +19,10 @@ abstract class TranslatedCondition extends TranslatedElement { final override string toString() { result = expr.toString() } - final override Locatable getAST() { result = expr } + final override Locatable getAst() { result = expr } + + /** DEPRECATED: Alias for getAst */ + deprecated override Locatable getAST() { result = getAst() } final ConditionContext getConditionContext() { result = getParent() } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedDeclarationEntry.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedDeclarationEntry.qll index de63b81c876..36f1ce9443d 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedDeclarationEntry.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedDeclarationEntry.qll @@ -14,7 +14,7 @@ private import TranslatedInitialization * `entry`. */ TranslatedDeclarationEntry getTranslatedDeclarationEntry(DeclarationEntry entry) { - result.getAST() = entry + result.getAst() = entry } /** @@ -37,7 +37,10 @@ abstract class TranslatedDeclarationEntry extends TranslatedElement, TTranslated final override string toString() { result = entry.toString() } - final override Locatable getAST() { result = entry } + final override Locatable getAst() { result = entry } + + /** DEPRECATED: Alias for getAst */ + deprecated override Locatable getAST() { result = getAst() } } /** @@ -223,7 +226,10 @@ class TranslatedStaticLocalVariableInitialization extends TranslatedElement, final override string toString() { result = "init: " + entry.toString() } - final override Locatable getAST() { result = entry } + final override Locatable getAst() { result = entry } + + /** DEPRECATED: Alias for getAst */ + deprecated override Locatable getAST() { result = getAst() } final override LocalVariable getVariable() { result = var } @@ -254,7 +260,10 @@ class TranslatedRangeBasedForVariableDeclaration extends TranslatedLocalVariable override string toString() { result = var.toString() } - override Locatable getAST() { result = var } + override Locatable getAst() { result = var } + + /** DEPRECATED: Alias for getAst */ + deprecated override Locatable getAST() { result = getAst() } override Function getFunction() { result = forStmt.getEnclosingFunction() } @@ -262,7 +271,7 @@ class TranslatedRangeBasedForVariableDeclaration extends TranslatedLocalVariable } TranslatedConditionDecl getTranslatedConditionDecl(ConditionDeclExpr expr) { - result.getAST() = expr + result.getAst() = expr } /** @@ -280,7 +289,10 @@ class TranslatedConditionDecl extends TranslatedLocalVariableDeclaration, TTrans override string toString() { result = "decl: " + conditionDeclExpr.toString() } - override Locatable getAST() { result = conditionDeclExpr } + override Locatable getAst() { result = conditionDeclExpr } + + /** DEPRECATED: Alias for getAst */ + deprecated override Locatable getAST() { result = getAst() } override Function getFunction() { result = conditionDeclExpr.getEnclosingFunction() } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll index 8034e9e2bd1..c9ac4d0e6d9 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll @@ -31,7 +31,7 @@ IRUserVariable getIRUserVariable(Function func, Variable var) { } IRTempVariable getIRTempVariable(Locatable ast, TempVariableTag tag) { - result.getAST() = ast and + result.getAst() = ast and result.getTag() = tag } @@ -730,7 +730,10 @@ abstract class TranslatedElement extends TTranslatedElement { /** * Gets the AST node being translated. */ - abstract Locatable getAST(); + abstract Locatable getAst(); + + /** DEPRECATED: Alias for getAst */ + deprecated Locatable getAST() { result = getAst() } /** * Get the first instruction to be executed in the evaluation of this element. @@ -929,16 +932,16 @@ abstract class TranslatedElement extends TTranslatedElement { */ final IRTempVariable getTempVariable(TempVariableTag tag) { exists(Locatable ast | - result.getAST() = ast and + result.getAst() = ast and result.getTag() = tag and - hasTempVariableAndAST(tag, ast) + hasTempVariableAndAst(tag, ast) ) } pragma[noinline] - private predicate hasTempVariableAndAST(TempVariableTag tag, Locatable ast) { + private predicate hasTempVariableAndAst(TempVariableTag tag, Locatable ast) { hasTempVariable(tag, _) and - ast = getAST() + ast = getAst() } /** diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll index 1b761a85640..4449b03a84a 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll @@ -74,7 +74,10 @@ abstract class TranslatedExpr extends TranslatedElement { expr.isGLValueCategory() } - final override Locatable getAST() { result = expr } + final override Locatable getAst() { result = expr } + + /** DEPRECATED: Alias for getAst */ + deprecated override Locatable getAST() { result = this.getAst() } final override Function getFunction() { result = expr.getEnclosingFunction() } @@ -1709,7 +1712,7 @@ abstract class TranslatedAllocationSize extends TranslatedExpr, TTranslatedAlloc } TranslatedAllocationSize getTranslatedAllocationSize(NewOrNewArrayExpr newExpr) { - result.getAST() = newExpr + result.getAst() = newExpr } /** @@ -1875,7 +1878,7 @@ class TranslatedAllocatorCall extends TTranslatedAllocatorCall, TranslatedDirect } TranslatedAllocatorCall getTranslatedAllocatorCall(NewOrNewArrayExpr newExpr) { - result.getAST() = newExpr + result.getAst() = newExpr } /** diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedFunction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedFunction.qll index 2fa4548fc3c..0f781cb2244 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedFunction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedFunction.qll @@ -15,7 +15,7 @@ private import VarArgs /** * Gets the `TranslatedFunction` that represents function `func`. */ -TranslatedFunction getTranslatedFunction(Function func) { result.getAST() = func } +TranslatedFunction getTranslatedFunction(Function func) { result.getAst() = func } /** * Gets the size, in bytes, of the variable used to represent the `...` parameter in a varargs @@ -65,7 +65,10 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction { final override string toString() { result = func.toString() } - final override Locatable getAST() { result = func } + final override Locatable getAst() { result = func } + + /** DEPRECATED: Alias for getAst */ + deprecated override Locatable getAST() { result = getAst() } /** * Gets the function being translated. @@ -344,7 +347,7 @@ TranslatedThisParameter getTranslatedThisParameter(Function func) { result.getFu /** * Gets the `TranslatedPositionalParameter` that represents parameter `param`. */ -TranslatedPositionalParameter getTranslatedParameter(Parameter param) { result.getAST() = param } +TranslatedPositionalParameter getTranslatedParameter(Parameter param) { result.getAst() = param } /** * Gets the `TranslatedEllipsisParameter` for function `func`, if one exists. @@ -457,7 +460,10 @@ class TranslatedThisParameter extends TranslatedParameter, TTranslatedThisParame final override string toString() { result = "this" } - final override Locatable getAST() { result = func } + final override Locatable getAst() { result = func } + + /** DEPRECATED: Alias for getAst */ + deprecated override Locatable getAST() { result = getAst() } final override Function getFunction() { result = func } @@ -489,7 +495,10 @@ class TranslatedPositionalParameter extends TranslatedParameter, TTranslatedPara final override string toString() { result = param.toString() } - final override Locatable getAST() { result = param } + final override Locatable getAst() { result = param } + + /** DEPRECATED: Alias for getAst */ + deprecated override Locatable getAST() { result = getAst() } final override Function getFunction() { result = param.getFunction() or @@ -526,7 +535,10 @@ class TranslatedEllipsisParameter extends TranslatedParameter, TTranslatedEllips final override string toString() { result = "..." } - final override Locatable getAST() { result = func } + final override Locatable getAst() { result = func } + + /** DEPRECATED: Alias for getAst */ + deprecated override Locatable getAST() { result = getAst() } final override Function getFunction() { result = func } @@ -544,7 +556,7 @@ class TranslatedEllipsisParameter extends TranslatedParameter, TTranslatedEllips } private TranslatedConstructorInitList getTranslatedConstructorInitList(Function func) { - result.getAST() = func + result.getAst() = func } /** @@ -561,7 +573,10 @@ class TranslatedConstructorInitList extends TranslatedElement, InitializationCon override string toString() { result = "ctor init: " + func.toString() } - override Locatable getAST() { result = func } + override Locatable getAst() { result = func } + + /** DEPRECATED: Alias for getAst */ + deprecated override Locatable getAST() { result = getAst() } override TranslatedElement getChild(int id) { exists(ConstructorFieldInit fieldInit | @@ -611,7 +626,7 @@ class TranslatedConstructorInitList extends TranslatedElement, InitializationCon } private TranslatedDestructorDestructionList getTranslatedDestructorDestructionList(Function func) { - result.getAST() = func + result.getAst() = func } /** @@ -629,7 +644,10 @@ class TranslatedDestructorDestructionList extends TranslatedElement, override string toString() { result = "dtor destruction: " + func.toString() } - override Locatable getAST() { result = func } + override Locatable getAst() { result = func } + + /** DEPRECATED: Alias for getAst */ + deprecated override Locatable getAST() { result = getAst() } override TranslatedElement getChild(int id) { exists(DestructorFieldDestruction fieldDestruction | @@ -667,14 +685,17 @@ class TranslatedDestructorDestructionList extends TranslatedElement, } } -TranslatedReadEffects getTranslatedReadEffects(Function func) { result.getAST() = func } +TranslatedReadEffects getTranslatedReadEffects(Function func) { result.getAst() = func } class TranslatedReadEffects extends TranslatedElement, TTranslatedReadEffects { Function func; TranslatedReadEffects() { this = TTranslatedReadEffects(func) } - override Locatable getAST() { result = func } + override Locatable getAst() { result = func } + + /** DEPRECATED: Alias for getAst */ + deprecated override Locatable getAST() { result = getAst() } override Function getFunction() { result = func } @@ -718,11 +739,11 @@ class TranslatedReadEffects extends TranslatedElement, TTranslatedReadEffects { } private TranslatedThisReadEffect getTranslatedThisReadEffect(Function func) { - result.getAST() = func + result.getAst() = func } private TranslatedParameterReadEffect getTranslatedParameterReadEffect(Parameter param) { - result.getAST() = param + result.getAst() = param } abstract class TranslatedReadEffect extends TranslatedElement { @@ -758,7 +779,10 @@ class TranslatedThisReadEffect extends TranslatedReadEffect, TTranslatedThisRead TranslatedThisReadEffect() { this = TTranslatedThisReadEffect(func) } - override Locatable getAST() { result = func } + override Locatable getAst() { result = func } + + /** DEPRECATED: Alias for getAst */ + deprecated override Locatable getAST() { result = getAst() } override Function getFunction() { result = func } @@ -781,7 +805,10 @@ class TranslatedParameterReadEffect extends TranslatedReadEffect, TTranslatedPar TranslatedParameterReadEffect() { this = TTranslatedParameterReadEffect(param) } - override Locatable getAST() { result = param } + override Locatable getAst() { result = param } + + /** DEPRECATED: Alias for getAst */ + deprecated override Locatable getAST() { result = getAst() } override string toString() { result = "read effect: " + param.toString() } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedInitialization.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedInitialization.qll index 23d6ad133cf..1a9d7ad9d70 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedInitialization.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedInitialization.qll @@ -139,7 +139,10 @@ abstract class TranslatedInitialization extends TranslatedElement, TTranslatedIn final override Function getFunction() { result = expr.getEnclosingFunction() } - final override Locatable getAST() { result = expr } + final override Locatable getAst() { result = expr } + + /** DEPRECATED: Alias for getAst */ + deprecated override Locatable getAST() { result = getAst() } /** * Gets the expression that is doing the initialization. @@ -461,11 +464,11 @@ class TranslatedConstructorInitialization extends TranslatedDirectInitialization TranslatedFieldInitialization getTranslatedFieldInitialization( ClassAggregateLiteral initList, Field field ) { - result.getAST() = initList and result.getField() = field + result.getAst() = initList and result.getField() = field } TranslatedFieldInitialization getTranslatedConstructorFieldInitialization(ConstructorFieldInit init) { - result.getAST() = init + result.getAst() = init } /** @@ -478,7 +481,10 @@ abstract class TranslatedFieldInitialization extends TranslatedElement { final override string toString() { result = ast.toString() + "." + field.toString() } - final override Locatable getAST() { result = ast } + final override Locatable getAst() { result = ast } + + /** DEPRECATED: Alias for getAst */ + deprecated override Locatable getAST() { result = getAst() } final override Function getFunction() { result = ast.getEnclosingFunction() } @@ -622,7 +628,10 @@ abstract class TranslatedElementInitialization extends TranslatedElement { result = initList.toString() + "[" + getElementIndex().toString() + "]" } - final override Locatable getAST() { result = initList } + final override Locatable getAst() { result = initList } + + /** DEPRECATED: Alias for getAst */ + deprecated override Locatable getAST() { result = getAst() } final override Function getFunction() { result = initList.getEnclosingFunction() } @@ -802,7 +811,10 @@ class TranslatedElementValueInitialization extends TranslatedElementInitializati abstract class TranslatedStructorCallFromStructor extends TranslatedElement, StructorCallContext { FunctionCall call; - final override Locatable getAST() { result = call } + final override Locatable getAst() { result = call } + + /** DEPRECATED: Alias for getAst */ + deprecated override Locatable getAST() { result = getAst() } final override TranslatedElement getChild(int id) { id = 0 and @@ -864,7 +876,7 @@ abstract class TranslatedConstructorCallFromConstructor extends TranslatedStruct } TranslatedConstructorCallFromConstructor getTranslatedConstructorBaseInit(ConstructorBaseInit init) { - result.getAST() = init + result.getAst() = init } /** @@ -904,7 +916,7 @@ class TranslatedConstructorBaseInit extends TranslatedConstructorCallFromConstru TranslatedDestructorBaseDestruction getTranslatedDestructorBaseDestruction( DestructorBaseDestruction destruction ) { - result.getAST() = destruction + result.getAst() = destruction } /** @@ -928,7 +940,10 @@ class TranslatedConstructorBareInit extends TranslatedElement, TTranslatedConstr TranslatedConstructorBareInit() { this = TTranslatedConstructorBareInit(init) } - override Locatable getAST() { result = init } + override Locatable getAst() { result = init } + + /** DEPRECATED: Alias for getAst */ + deprecated override Locatable getAST() { result = getAst() } final override string toString() { result = "construct base (no constructor)" } @@ -948,5 +963,5 @@ class TranslatedConstructorBareInit extends TranslatedElement, TTranslatedConstr } TranslatedConstructorBareInit getTranslatedConstructorBareInit(ConstructorInit init) { - result.getAST() = init + result.getAst() = init } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll index 2bc3b5bc3ef..eb195286339 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll @@ -11,7 +11,7 @@ private import TranslatedExpr private import TranslatedFunction private import TranslatedInitialization -TranslatedStmt getTranslatedStmt(Stmt stmt) { result.getAST() = stmt } +TranslatedStmt getTranslatedStmt(Stmt stmt) { result.getAst() = stmt } abstract class TranslatedStmt extends TranslatedElement, TTranslatedStmt { Stmt stmt; @@ -20,7 +20,10 @@ abstract class TranslatedStmt extends TranslatedElement, TTranslatedStmt { final override string toString() { result = stmt.toString() } - final override Locatable getAST() { result = stmt } + final override Locatable getAst() { result = stmt } + + /** DEPRECATED: Alias for getAst */ + deprecated override Locatable getAST() { result = getAst() } final override Function getFunction() { result = stmt.getEnclosingFunction() } } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/reachability/DominanceInternal.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/reachability/DominanceInternal.qll index cee8fa1543b..aaa4cc7bd53 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/reachability/DominanceInternal.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/reachability/DominanceInternal.qll @@ -1,7 +1,5 @@ private import ReachableBlock as Reachability -private module ReachabilityGraph = Reachability::Graph; - module Graph { import Reachability::Graph diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll index 146fc270738..ca4708857a7 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll @@ -55,7 +55,10 @@ class IRVariable extends TIRVariable { * Gets the AST node that declared this variable, or that introduced this * variable as part of the AST-to-IR translation. */ - Language::AST getAST() { none() } + Language::AST getAst() { none() } + + /** DEPRECATED: Alias for getAst */ + deprecated Language::AST getAST() { result = getAst() } /** * Gets an identifier string for the variable. This identifier is unique @@ -66,7 +69,7 @@ class IRVariable extends TIRVariable { /** * Gets the source location of this variable. */ - final Language::Location getLocation() { result = getAST().getLocation() } + final Language::Location getLocation() { result = getAst().getLocation() } /** * Gets the IR for the function that references this variable. @@ -90,7 +93,10 @@ class IRUserVariable extends IRVariable, TIRUserVariable { final override string toString() { result = getVariable().toString() } - final override Language::AST getAST() { result = var } + final override Language::AST getAst() { result = var } + + /** DEPRECATED: Alias for getAst */ + deprecated override Language::AST getAST() { result = getAst() } final override string getUniqueId() { result = getVariable().toString() + " " + getVariable().getLocation().toString() @@ -157,7 +163,10 @@ class IRGeneratedVariable extends IRVariable { final override Language::LanguageType getLanguageType() { result = type } - final override Language::AST getAST() { result = ast } + final override Language::AST getAst() { result = ast } + + /** DEPRECATED: Alias for getAst */ + deprecated override Language::AST getAST() { result = getAst() } override string toString() { result = getBaseString() + getLocationString() } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll index 1c2cc493338..e5a908bbf9a 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll @@ -41,7 +41,7 @@ class Instruction extends Construction::TStageInstruction { } /** Gets a textual representation of this element. */ - final string toString() { result = this.getOpcode().toString() + ": " + this.getAST().toString() } + final string toString() { result = this.getOpcode().toString() + ": " + this.getAst().toString() } /** * Gets a string showing the result, opcode, and operands of the instruction, equivalent to what @@ -136,7 +136,7 @@ class Instruction extends Construction::TStageInstruction { string getResultId() { this.shouldGenerateDumpStrings() and result = - this.getResultPrefix() + this.getAST().getLocation().getStartLine() + "_" + this.getLineRank() + this.getResultPrefix() + this.getAst().getLocation().getStartLine() + "_" + this.getLineRank() } /** @@ -208,12 +208,15 @@ class Instruction extends Construction::TStageInstruction { /** * Gets the AST that caused this instruction to be generated. */ - final Language::AST getAST() { result = Construction::getInstructionAST(this) } + final Language::AST getAst() { result = Construction::getInstructionAst(this) } + + /** DEPRECATED: Alias for getAst */ + deprecated Language::AST getAST() { result = this.getAst() } /** * Gets the location of the source code for this instruction. */ - final Language::Location getLocation() { result = this.getAST().getLocation() } + final Language::Location getLocation() { result = this.getAst().getLocation() } /** * Gets the `Expr` whose result is computed by this instruction, if any. The `Expr` may be a @@ -459,7 +462,10 @@ class VariableInstruction extends Instruction { /** * Gets the AST variable that this instruction's IR variable refers to, if one exists. */ - final Language::Variable getASTVariable() { result = var.(IRUserVariable).getVariable() } + final Language::Variable getAstVariable() { result = var.(IRUserVariable).getVariable() } + + /** DEPRECATED: Alias for getAstVariable */ + deprecated Language::Variable getASTVariable() { result = this.getAstVariable() } } /** diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Operand.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Operand.qll index 89b82657c3b..c1e997d5844 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Operand.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Operand.qll @@ -18,7 +18,7 @@ private import internal.OperandInternal * of `TOperand` that are used in this stage. */ private class TStageOperand = - TRegisterOperand or TNonSSAMemoryOperand or TPhiOperand or TChiOperand; + TRegisterOperand or TNonSsaMemoryOperand or TPhiOperand or TChiOperand; /** * A known location. Testing `loc instanceof KnownLocation` will account for non existing locations, as @@ -38,7 +38,7 @@ class Operand extends TStageOperand { // Ensure that the operand does not refer to instructions from earlier stages that are unreachable here exists(Instruction use, Instruction def | this = registerOperand(use, _, def)) or - exists(Instruction use | this = nonSSAMemoryOperand(use, _)) + exists(Instruction use | this = nonSsaMemoryOperand(use, _)) or exists(Instruction use, Instruction def, IRBlock predecessorBlock | this = phiOperand(use, def, predecessorBlock, _) or @@ -209,7 +209,7 @@ class Operand extends TStageOperand { class MemoryOperand extends Operand { cached MemoryOperand() { - this instanceof TNonSSAMemoryOperand or + this instanceof TNonSsaMemoryOperand or this instanceof TPhiOperand or this instanceof TChiOperand } @@ -249,7 +249,7 @@ class NonPhiOperand extends Operand { NonPhiOperand() { this = registerOperand(useInstr, tag, _) or - this = nonSSAMemoryOperand(useInstr, tag) or + this = nonSsaMemoryOperand(useInstr, tag) or this = chiOperand(useInstr, tag) } @@ -299,7 +299,7 @@ class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, TNonPhiMemoryOpe cached NonPhiMemoryOperand() { - this = nonSSAMemoryOperand(useInstr, tag) + this = nonSsaMemoryOperand(useInstr, tag) or this = chiOperand(useInstr, tag) } 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 fdb645e03f0..2dc735f49df 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 @@ -99,7 +99,7 @@ private predicate filteredNumberableInstruction(Instruction instr) { // count rather than strictcount to handle missing AST elements // separate instanceof and inline casts to avoid failed casts with a count of 0 instr instanceof VariableAddressInstruction and - count(instr.(VariableAddressInstruction).getIRVariable().getAST()) != 1 + count(instr.(VariableAddressInstruction).getIRVariable().getAst()) != 1 or instr instanceof ConstantInstruction and count(instr.getResultIRType()) != 1 @@ -121,7 +121,7 @@ private predicate variableAddressValueNumber( // The underlying AST element is used as value-numbering key instead of the // `IRVariable` to work around a problem where a variable or expression with // multiple types gives rise to multiple `IRVariable`s. - unique( | | instr.getIRVariable().getAST()) = ast + unique( | | instr.getIRVariable().getAst()) = ast } private predicate initializeParameterValueNumber( @@ -131,7 +131,7 @@ private predicate initializeParameterValueNumber( // The underlying AST element is used as value-numbering key instead of the // `IRVariable` to work around a problem where a variable or expression with // multiple types gives rise to multiple `IRVariable`s. - instr.getIRVariable().getAST() = var + instr.getIRVariable().getAst() = var } private predicate constantValueNumber( diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/OperandInternal.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/OperandInternal.qll index 80e06a381a1..369f7c317f9 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/OperandInternal.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/OperandInternal.qll @@ -1,2 +1,2 @@ private import semmle.code.cpp.ir.implementation.internal.TOperand -import UnaliasedSSAOperands +import UnaliasedSsaOperands diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/PrintSSA.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/PrintSSA.qll index 72bb239c153..c7487872512 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/PrintSSA.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/PrintSSA.qll @@ -2,7 +2,7 @@ private import SSAConstructionInternal private import OldIR private import Alias private import SSAConstruction -private import DebugSSA +private import DebugSsa bindingset[offset] private string getKeySuffixForOffset(int offset) { diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConsistency.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConsistency.qll index 5686bb439eb..1c75529be00 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConsistency.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConsistency.qll @@ -1,2 +1,2 @@ private import SSAConstruction as SSA -import SSA::SSAConsistency +import SSA::SsaConsistency diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll index 5092e921cb3..13ec2ca4ca4 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll @@ -112,7 +112,7 @@ private module Cached { exists(Alias::getResultMemoryLocation(oldInstruction)) or // This result was already modeled by a previous iteration of SSA. - Alias::canReuseSSAForOldResult(oldInstruction) + Alias::canReuseSsaForOldResult(oldInstruction) } cached @@ -182,7 +182,7 @@ private module Cached { * unreachable, this predicate will recurse through any degenerate `Phi` instructions to find the * true definition. */ - private Instruction getNewDefinitionFromOldSSA(OldIR::MemoryOperand oldOperand, Overlap overlap) { + private Instruction getNewDefinitionFromOldSsa(OldIR::MemoryOperand oldOperand, Overlap overlap) { exists(Overlap originalOverlap | originalOverlap = oldOperand.getDefinitionOverlap() and ( @@ -191,7 +191,7 @@ private module Cached { or exists(OldIR::PhiInputOperand phiOperand, Overlap phiOperandOverlap | phiOperand = getDegeneratePhiOperand(oldOperand.getAnyDef()) and - result = getNewDefinitionFromOldSSA(phiOperand, phiOperandOverlap) and + result = getNewDefinitionFromOldSsa(phiOperand, phiOperandOverlap) and overlap = combineOverlap(pragma[only_bind_out](phiOperandOverlap), pragma[only_bind_out](originalOverlap)) @@ -233,7 +233,7 @@ private module Cached { ) or exists(OldIR::NonPhiMemoryOperand oldOperand | - result = getNewDefinitionFromOldSSA(oldOperand, overlap) and + result = getNewDefinitionFromOldSsa(oldOperand, overlap) and oldOperand.getUse() = instruction and tag = oldOperand.getOperandTag() ) @@ -307,13 +307,13 @@ private module Cached { * Gets the new definition instruction for the operand of `instr` that flows from the block * `newPredecessorBlock`, based on that operand's definition in the old IR. */ - private Instruction getNewPhiOperandDefinitionFromOldSSA( + private Instruction getNewPhiOperandDefinitionFromOldSsa( Instruction instr, IRBlock newPredecessorBlock, Overlap overlap ) { exists(OldIR::PhiInstruction oldPhi, OldIR::PhiInputOperand oldOperand | oldPhi = getOldInstruction(instr) and oldOperand = oldPhi.getInputOperand(getOldBlock(newPredecessorBlock)) and - result = getNewDefinitionFromOldSSA(oldOperand, overlap) + result = getNewDefinitionFromOldSsa(oldOperand, overlap) ) } @@ -333,7 +333,7 @@ private module Cached { overlap = Alias::getOverlap(actualDefLocation, useLocation) ) or - result = getNewPhiOperandDefinitionFromOldSSA(instr, newPredecessorBlock, overlap) + result = getNewPhiOperandDefinitionFromOldSsa(instr, newPredecessorBlock, overlap) } cached @@ -412,17 +412,17 @@ private module Cached { } cached - Language::AST getInstructionAST(Instruction instr) { - result = getOldInstruction(instr).getAST() + Language::AST getInstructionAst(Instruction instr) { + result = getOldInstruction(instr).getAst() or exists(RawIR::Instruction blockStartInstr | instr = phiInstruction(blockStartInstr, _) and - result = blockStartInstr.getAST() + result = blockStartInstr.getAst() ) or exists(RawIR::Instruction primaryInstr | instr = chiInstruction(primaryInstr) and - result = primaryInstr.getAST() + result = primaryInstr.getAst() ) or exists(IRFunctionBase irFunc | @@ -430,6 +430,12 @@ private module Cached { ) } + /** DEPRECATED: Alias for getInstructionAst */ + cached + deprecated Language::AST getInstructionAST(Instruction instr) { + result = getInstructionAst(instr) + } + cached Language::LanguageType getInstructionResultType(Instruction instr) { result = instr.(RawIR::Instruction).getResultLanguageType() @@ -975,35 +981,41 @@ module DefUse { } } -predicate canReuseSSAForMemoryResult(Instruction instruction) { +predicate canReuseSsaForMemoryResult(Instruction instruction) { exists(OldInstruction oldInstruction | oldInstruction = getOldInstruction(instruction) and ( // The previous iteration said it was reusable, so we should mark it as reusable as well. - Alias::canReuseSSAForOldResult(oldInstruction) + Alias::canReuseSsaForOldResult(oldInstruction) or // The current alias analysis says it is reusable. - Alias::getResultMemoryLocation(oldInstruction).canReuseSSA() + Alias::getResultMemoryLocation(oldInstruction).canReuseSsa() ) ) or exists(Alias::MemoryLocation defLocation | // This is a `Phi` for a reusable location, so the result of the `Phi` is reusable as well. instruction = phiInstruction(_, defLocation) and - defLocation.canReuseSSA() + defLocation.canReuseSsa() ) // We don't support reusing SSA for any location that could create a `Chi` instruction. } +/** DEPRECATED: Alias for canReuseSsaForMemoryResult */ +deprecated predicate canReuseSSAForMemoryResult = canReuseSsaForMemoryResult/1; + /** * Expose some of the internal predicates to PrintSSA.qll. We do this by publically importing those modules in the * `DebugSSA` module, which is then imported by PrintSSA. */ -module DebugSSA { +module DebugSsa { import PhiInsertion import DefUse } +/** DEPRECATED: Alias for DebugSsa */ +deprecated module DebugSSA = DebugSsa; + import CachedForDebugging cached @@ -1038,7 +1050,7 @@ private module CachedForDebugging { private OldIR::IRTempVariable getOldTempVariable(IRTempVariable var) { result.getEnclosingFunction() = var.getEnclosingFunction() and - result.getAST() = var.getAST() and + result.getAst() = var.getAst() and result.getTag() = var.getTag() } @@ -1061,7 +1073,7 @@ private module CachedForDebugging { int maxValue() { result = 2147483647 } } -module SSAConsistency { +module SsaConsistency { /** * Holds if a `MemoryOperand` has more than one `MemoryLocation` assigned by alias analysis. */ @@ -1114,6 +1126,9 @@ module SSAConsistency { } } +/** DEPRECATED: Alias for SsaConsistency */ +deprecated module SSAConsistency = SsaConsistency; + /** * Provides the portion of the parameterized IR interface that is used to construct the SSA stages * of the IR. The raw stage of the IR does not expose these predicates. diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstructionInternal.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstructionInternal.qll index 70d44e03267..8f64bff29f2 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstructionInternal.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstructionInternal.qll @@ -3,7 +3,7 @@ import semmle.code.cpp.ir.implementation.raw.internal.reachability.ReachableBloc import semmle.code.cpp.ir.implementation.raw.internal.reachability.Dominance as Dominance import semmle.code.cpp.ir.implementation.unaliased_ssa.IR as NewIR import semmle.code.cpp.ir.implementation.raw.internal.IRConstruction as RawStage -import semmle.code.cpp.ir.implementation.internal.TInstruction::UnaliasedSSAInstructions as SSAInstructions +import semmle.code.cpp.ir.implementation.internal.TInstruction::UnaliasedSsaInstructions as SSAInstructions import semmle.code.cpp.ir.internal.IRCppLanguage as Language import SimpleSSA as Alias -import semmle.code.cpp.ir.implementation.internal.TOperand::UnaliasedSSAOperands as SSAOperands +import semmle.code.cpp.ir.implementation.internal.TOperand::UnaliasedSsaOperands as SSAOperands diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SimpleSSA.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SimpleSSA.qll index f3e02c9f6a8..ec2e6f5ef34 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SimpleSSA.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SimpleSSA.qll @@ -41,11 +41,14 @@ predicate isVariableModeled(Allocation var) { * subsequent iterations will recompute SSA for any variable that we assumed did not escape, but * actually would have escaped if we had used a sound escape analysis. */ -predicate canReuseSSAForVariable(IRAutomaticVariable var) { +predicate canReuseSsaForVariable(IRAutomaticVariable var) { isVariableModeled(var) and not allocationEscapes(var) } +/** DEPRECATED: Alias for canReuseSsaForVariable */ +deprecated predicate canReuseSSAForVariable = canReuseSsaForVariable/1; + private newtype TMemoryLocation = MkMemoryLocation(Allocation var) { isVariableModeled(var) } private MemoryLocation getMemoryLocation(Allocation var) { result.getAllocation() = var } @@ -69,10 +72,16 @@ class MemoryLocation extends TMemoryLocation { final string getUniqueId() { result = var.getUniqueId() } - final predicate canReuseSSA() { canReuseSSAForVariable(var) } + final predicate canReuseSsa() { canReuseSsaForVariable(var) } + + /** DEPRECATED: Alias for canReuseSsa */ + deprecated predicate canReuseSSA() { canReuseSsa() } } -predicate canReuseSSAForOldResult(Instruction instr) { none() } +predicate canReuseSsaForOldResult(Instruction instr) { none() } + +/** DEPRECATED: Alias for canReuseSsaForOldResult */ +deprecated predicate canReuseSSAForOldResult = canReuseSsaForOldResult/1; /** * Represents a set of `MemoryLocation`s that cannot overlap with diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/reachability/DominanceInternal.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/reachability/DominanceInternal.qll index cee8fa1543b..aaa4cc7bd53 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/reachability/DominanceInternal.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/reachability/DominanceInternal.qll @@ -1,7 +1,5 @@ private import ReachableBlock as Reachability -private module ReachabilityGraph = Reachability::Graph; - module Graph { import Reachability::Graph diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll index ed201a14587..e360fa7b2bb 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll @@ -23,8 +23,6 @@ private class Printf extends FormattingFunction, AliasFunction { override int getFormatParameterIndex() { result = 0 } - deprecated override predicate isWideCharDefault() { hasName(["wprintf", "wprintf_s"]) } - override predicate isOutputGlobal() { any() } override predicate parameterNeverEscapes(int n) { n = 0 } @@ -49,8 +47,6 @@ private class Fprintf extends FormattingFunction { override int getFormatParameterIndex() { result = 1 } - deprecated override predicate isWideCharDefault() { hasName("fwprintf") } - override int getOutputParameterIndex(boolean isStream) { result = 0 and isStream = true } } @@ -77,15 +73,6 @@ private class Sprintf extends FormattingFunction { not exists(getDefinition().getFile().getRelativePath()) } - deprecated override predicate isWideCharDefault() { - getParameter(getFormatParameterIndex()) - .getType() - .getUnspecifiedType() - .(PointerType) - .getBaseType() - .getSize() > 1 - } - override int getFormatParameterIndex() { hasName("g_strdup_printf") and result = 0 or @@ -133,15 +120,6 @@ private class SnprintfImpl extends Snprintf { else result = getFirstFormatArgumentIndex() - 1 } - deprecated override predicate isWideCharDefault() { - getParameter(getFormatParameterIndex()) - .getType() - .getUnspecifiedType() - .(PointerType) - .getBaseType() - .getSize() > 1 - } - override int getOutputParameterIndex(boolean isStream) { result = 0 and isStream = false } override int getFirstFormatArgumentIndex() { @@ -182,15 +160,6 @@ private class StringCchPrintf extends FormattingFunction { if getName().matches("%Ex") then result = 5 else result = 2 } - deprecated override predicate isWideCharDefault() { - getParameter(getFormatParameterIndex()) - .getType() - .getUnspecifiedType() - .(PointerType) - .getBaseType() - .getSize() > 1 - } - override int getOutputParameterIndex(boolean isStream) { result = 0 and isStream = false } override int getSizeParameterIndex() { result = 1 } diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/FormattingFunction.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/FormattingFunction.qll index 9630bb13e18..1202895cca2 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/interfaces/FormattingFunction.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/interfaces/FormattingFunction.qll @@ -52,14 +52,6 @@ abstract class FormattingFunction extends ArrayFunction, TaintFunction { */ predicate isMicrosoft() { anyFileCompiledAsMicrosoft() } - /** - * Holds if the default meaning of `%s` is a `wchar_t *`, rather than - * a `char *` (either way, `%S` will have the opposite meaning). - * - * DEPRECATED: Use getDefaultCharType() instead. - */ - deprecated predicate isWideCharDefault() { none() } - /** * Gets the character type used in the format string for this function. */ @@ -116,13 +108,6 @@ abstract class FormattingFunction extends ArrayFunction, TaintFunction { */ int getOutputParameterIndex(boolean isStream) { none() } - /** - * Gets the position at which the output parameter, if any, occurs. - * - * DEPRECATED: use `getOutputParameterIndex(boolean isStream)` instead. - */ - deprecated int getOutputParameterIndex() { result = getOutputParameterIndex(_) } - /** * Holds if this function outputs to a global stream such as standard output, * standard error or a system log. For example `printf`. diff --git a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/RangeSSA.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/RangeSSA.qll index d2d2fbd5b3c..02cd5cb7876 100644 --- a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/RangeSSA.qll +++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/RangeSSA.qll @@ -29,8 +29,8 @@ private import RangeAnalysisUtils * The SSA logic comes in two versions: the standard SSA and range-analysis RangeSSA. * This class provides the range-analysis SSA logic. */ -library class RangeSSA extends SSAHelper { - RangeSSA() { this = 1 } +library class RangeSsa extends SsaHelper { + RangeSsa() { this = 1 } /** * Add a phi node on the out-edge of a guard. @@ -40,6 +40,9 @@ library class RangeSSA extends SSAHelper { } } +/** DEPRECATED: Alias for RangeSsa */ +deprecated class RangeSSA = RangeSsa; + private predicate guard_defn(VariableAccess v, Expr guard, BasicBlock b, boolean branch) { guardCondition(guard, v, branch) and guardSuccessor(guard, branch, b) @@ -67,22 +70,22 @@ private predicate guardSuccessor(Expr guard, boolean branch, BasicBlock succ) { * nodes. */ class RangeSsaDefinition extends ControlFlowNodeBase { - RangeSsaDefinition() { exists(RangeSSA x | x.ssa_defn(_, this, _, _)) } + RangeSsaDefinition() { exists(RangeSsa x | x.ssa_defn(_, this, _, _)) } /** * Gets a variable corresponding to a SSA StackVariable defined by * this definition. */ - StackVariable getAVariable() { exists(RangeSSA x | x.ssa_defn(result, this, _, _)) } + StackVariable getAVariable() { exists(RangeSsa x | x.ssa_defn(result, this, _, _)) } /** * A string representation of the SSA variable represented by the pair * `(this, v)`. */ - string toString(StackVariable v) { exists(RangeSSA x | result = x.toString(this, v)) } + string toString(StackVariable v) { exists(RangeSsa x | result = x.toString(this, v)) } /** Gets a use of the SSA variable represented by the pair `(this, v)`. */ - VariableAccess getAUse(StackVariable v) { exists(RangeSSA x | result = x.getAUse(this, v)) } + VariableAccess getAUse(StackVariable v) { exists(RangeSsa x | result = x.getAUse(this, v)) } /** Gets the control flow node for this definition. */ ControlFlowNode getDefinition() { result = this } @@ -91,7 +94,7 @@ class RangeSsaDefinition extends ControlFlowNodeBase { BasicBlock getBasicBlock() { result.contains(this.getDefinition()) } /** Whether this definition is a phi node for variable `v`. */ - predicate isPhiNode(StackVariable v) { exists(RangeSSA x | x.phi_node(v, this)) } + predicate isPhiNode(StackVariable v) { exists(RangeSsa x | x.phi_node(v, this)) } /** * DEPRECATED: Use isGuardPhi/4 instead @@ -172,6 +175,6 @@ class RangeSsaDefinition extends ControlFlowNodeBase { * Holds if this definition of the variable `v` reached the end of the basic block `b`. */ predicate reachesEndOfBB(StackVariable v, BasicBlock b) { - exists(RangeSSA x | x.ssaDefinitionReachesEndOfBB(v, this, b)) + exists(RangeSsa x | x.ssaDefinitionReachesEndOfBB(v, this, b)) } } diff --git a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/SimpleRangeAnalysis.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/SimpleRangeAnalysis.qll index 0be94ed4e62..e4f562af582 100644 --- a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/SimpleRangeAnalysis.qll +++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/SimpleRangeAnalysis.qll @@ -705,24 +705,6 @@ private float getTruncatedUpperBounds(Expr expr) { result = exprMaxVal(expr) } -/** - * Holds if the expression might overflow negatively. This predicate - * does not consider the possibility that the expression might overflow - * due to a conversion. - * - * DEPRECATED: use `exprMightOverflowNegatively` instead. - */ -deprecated predicate negative_overflow(Expr expr) { exprMightOverflowNegatively(expr) } - -/** - * Holds if the expression might overflow positively. This predicate - * does not consider the possibility that the expression might overflow - * due to a conversion. - * - * DEPRECATED: use `exprMightOverflowPositively` instead. - */ -deprecated predicate positive_overflow(Expr expr) { exprMightOverflowPositively(expr) } - /** Only to be called by `getTruncatedLowerBounds`. */ private float getLowerBoundsImpl(Expr expr) { ( diff --git a/cpp/ql/lib/semmle/code/cpp/security/Encryption.qll b/cpp/ql/lib/semmle/code/cpp/security/Encryption.qll index 55ef606483c..120b154b787 100644 --- a/cpp/ql/lib/semmle/code/cpp/security/Encryption.qll +++ b/cpp/ql/lib/semmle/code/cpp/security/Encryption.qll @@ -84,31 +84,3 @@ string getSecureAlgorithmRegex() { "(^|.*[A-Z]{2}|.*[^a-zA-Z0-9])(" + strictconcat(getASecureAlgorithmName().toLowerCase(), "|") + ")([^a-z0-9].*|$)" } - -/** - * DEPRECATED: Terminology has been updated. Use `getAnInsecureAlgorithmName()` - * instead. - */ -deprecated string algorithmBlacklist() { result = getAnInsecureAlgorithmName() } - -/** - * DEPRECATED: Terminology has been updated. Use - * `getAnInsecureHashAlgorithmName()` instead. - */ -deprecated string hashAlgorithmBlacklist() { result = getAnInsecureHashAlgorithmName() } - -/** - * DEPRECATED: Terminology has been updated. Use `getInsecureAlgorithmRegex()` instead. - */ -deprecated string algorithmBlacklistRegex() { result = getInsecureAlgorithmRegex() } - -/** - * DEPRECATED: Terminology has been updated. Use `getASecureAlgorithmName()` - * instead. - */ -deprecated string algorithmWhitelist() { result = getASecureAlgorithmName() } - -/** - * DEPRECATED: Terminology has been updated. Use `getSecureAlgorithmRegex()` instead. - */ -deprecated string algorithmWhitelistRegex() { result = getSecureAlgorithmRegex() } diff --git a/cpp/ql/lib/semmle/code/cpp/stmts/Block.qll b/cpp/ql/lib/semmle/code/cpp/stmts/Block.qll index 5fe8798cebb..871709de119 100644 --- a/cpp/ql/lib/semmle/code/cpp/stmts/Block.qll +++ b/cpp/ql/lib/semmle/code/cpp/stmts/Block.qll @@ -126,9 +126,3 @@ class BlockStmt extends Stmt, @stmt_block { override predicate mayBeGloballyImpure() { this.getAStmt().mayBeGloballyImpure() } } - -/** - * DEPRECATED: This is now called `BlockStmt` to avoid confusion with - * `BasicBlock`. - */ -deprecated class Block = BlockStmt; diff --git a/cpp/ql/lib/semmle/code/cpp/stmts/Stmt.qll b/cpp/ql/lib/semmle/code/cpp/stmts/Stmt.qll index 5b157a54ce8..ef311e6fc45 100644 --- a/cpp/ql/lib/semmle/code/cpp/stmts/Stmt.qll +++ b/cpp/ql/lib/semmle/code/cpp/stmts/Stmt.qll @@ -61,13 +61,6 @@ class Stmt extends StmtParent, @stmt { override Location getLocation() { stmts(underlyingElement(this), _, result) } - /** - * Gets an int indicating the type of statement that this represents. - * - * DEPRECATED: use the subclasses of `Stmt` rather than relying on this predicate. - */ - deprecated int getKind() { stmts(underlyingElement(this), result, _) } - override string toString() { none() } override Function getControlFlowScope() { result = this.getEnclosingFunction() } @@ -1230,38 +1223,6 @@ class SwitchCase extends Stmt, @stmt_switch_case { */ int getChildNum() { switch_case(_, result, underlyingElement(this)) } - /** - * DEPRECATED: use `SwitchCase.getAStmt` or `ControlFlowNode.getASuccessor` - * rather than this predicate. - * - * Gets the `BlockStmt` statement immediately following this 'switch case' - * statement, if any. - * - * For example, for - * ``` - * switch (i) { - * case 5: - * x = 1; - * break; - * case 6: - * case 7: - * { x = 2; break; } - * default: - * { x = 3; } - * x = 4; - * break; - * } - * ``` - * the `case 7:` has result `{ x = 2; break; }`, `default:` has result - * `{ x = 3; }`, and the others have no result. - */ - deprecated BlockStmt getLabelledStmt() { - exists(int i, Stmt parent | - this = parent.getChild(i) and - result = parent.getChild(i + 1) - ) - } - /** * Gets the next `SwitchCase` belonging to the same 'switch' * statement, if any. @@ -1741,23 +1702,6 @@ class Handler extends Stmt, @stmt_handler { override predicate mayBeGloballyImpure() { none() } } -/** - * DEPRECATED: Objective-C is no longer supported. - * The end of a 'finally' clause. - * - * This has no concrete representation in the source, but makes the - * control flow graph easier to use. - */ -deprecated class FinallyEnd extends Stmt { - FinallyEnd() { none() } - - override string toString() { result = "" } - - override predicate mayBeImpure() { none() } - - override predicate mayBeGloballyImpure() { none() } -} - /** * A C/C++ 'try' statement. * diff --git a/cpp/ql/lib/semmle/code/cpp/valuenumbering/GlobalValueNumberingImpl.qll b/cpp/ql/lib/semmle/code/cpp/valuenumbering/GlobalValueNumberingImpl.qll index f9231e24725..d5e69d31254 100644 --- a/cpp/ql/lib/semmle/code/cpp/valuenumbering/GlobalValueNumberingImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/valuenumbering/GlobalValueNumberingImpl.qll @@ -89,7 +89,7 @@ private ControlFlowNode getControlFlowEntry(ControlFlowNode node) { * graph so that we can use the dominator tree to find the most recent * side-effect. */ -private predicate sideEffectCFG(ControlFlowNode src, ControlFlowNode dst) { +private predicate sideEffectCfg(ControlFlowNode src, ControlFlowNode dst) { src.getASuccessor() = dst or // Add an edge from the entry point to any node that might have a side @@ -103,7 +103,7 @@ private predicate sideEffectCFG(ControlFlowNode src, ControlFlowNode dst) { * the side-effect CFG. */ private predicate iDomEffect(ControlFlowNode dominator, ControlFlowNode node) = - idominance(functionEntry/1, sideEffectCFG/2)(_, dominator, node) + idominance(functionEntry/1, sideEffectCfg/2)(_, dominator, node) /** * Gets the most recent side effect. To be more precise, `result` is a diff --git a/cpp/ql/lib/semmlecode.cpp.dbscheme b/cpp/ql/lib/semmlecode.cpp.dbscheme index bb0f279f2ac..e9a518baf14 100644 --- a/cpp/ql/lib/semmlecode.cpp.dbscheme +++ b/cpp/ql/lib/semmlecode.cpp.dbscheme @@ -703,7 +703,7 @@ usertype_final(unique int id: @usertype ref); usertype_uuid( unique int id: @usertype ref, - unique string uuid: string ref + string uuid: string ref ); mangled_name( diff --git a/cpp/ql/lib/semmlecode.cpp.dbscheme.stats b/cpp/ql/lib/semmlecode.cpp.dbscheme.stats index 07abcbbef90..472bfd55aaf 100644 --- a/cpp/ql/lib/semmlecode.cpp.dbscheme.stats +++ b/cpp/ql/lib/semmlecode.cpp.dbscheme.stats @@ -1,39132 +1,39549 @@ - -@compilation -9440 - - -@externalDataElement -65 - - -@external_package -119 - - -@svnentry -575525 - - -@location_default -8719593 - - -@location_stmt -2179578 - - -@location_expr -9756708 - - -@diagnostic -67893 - - -@file -59320 - - -@folder -10817 - - -@macroinvocation -34675701 - - -@function -3658482 - - -@fun_decl -3730234 - - -@var_decl -5296821 - - -@type_decl -1316547 - - -@namespace_decl -135267 - - -@using -287692 - - -@static_assert -130452 - - -@parameter -4572935 - - -@membervariable -302107 - - -@globalvariable -301143 - - -@localvariable -520392 - - -@enumconstant -93691 - - -@builtintype -509 - - -@derivedtype -4408457 - - -@decltype -46454 - - -@usertype -4144306 - - -@mangledname -478020 - - -@type_mention -1674881 - - -@routinetype -421539 - - -@ptrtomember -12486 - - -@specifier -498 - - -@gnuattribute -414234 - - -@stdattribute -363 - - -@declspec -57736 - - -@msattribute -3 - - -@alignas -1723 - - -@attribute_arg_empty -1 - - -@attribute_arg_token -15700 - - -@attribute_arg_constant -146454 - - -@attribute_arg_type -54 - - -@derivation -385706 - - -@frienddecl -237444 - - -@comment -1561817 - - -@namespace -7597 - - -@specialnamequalifyingelement -10 - - -@namequalifier -1119060 - - -@value -8774622 - - -@initialiser -1662175 - - -@errorexpr -48145 - - -@address_of -440386 - - -@reference_to -1045861 - - -@indirect -294699 - - -@ref_indirect -1239321 - - -@array_to_pointer -997247 - - -@vacuous_destructor_call -5061 - - -@assume -3280 - - -@parexpr -3000807 - - -@arithnegexpr -652982 - - -@unaryplusexpr -184 - - -@complementexpr -28032 - - -@notexpr -338408 - - -@conjugation -1 - - -@realpartexpr -65 - - -@imagpartexpr -65 - - -@postincrexpr -43048 - - -@postdecrexpr -5402 - - -@preincrexpr -61791 - - -@predecrexpr -24506 - - -@conditionalexpr -154485 - - -@addexpr -246779 - - -@subexpr -135008 - - -@mulexpr -140641 - - -@divexpr -63732 - - -@remexpr -4539 - - -@jmulexpr -1 - - -@jdivexpr -1 - - -@fjaddexpr -1 - - -@jfaddexpr -1 - - -@fjsubexpr -1 - - -@jfsubexpr -1 - - -@paddexpr -87270 - - -@psubexpr -21970 - - -@pdiffexpr -24788 - - -@lshiftexpr -350576 - - -@rshiftexpr -71789 - - -@andexpr -257998 - - -@orexpr -143145 - - -@xorexpr -37313 - - -@eqexpr -212665 - - -@neexpr -88475 - - -@gtexpr -43945 - - -@ltexpr -51329 - - -@geexpr -22366 - - -@leexpr -213944 - - -@minexpr -1 - - -@maxexpr -1 - - -@assignexpr -551753 - - -@assignaddexpr -68313 - - -@assignsubexpr -7863 - - -@assignmulexpr -6828 - - -@assigndivexpr -2048 - - -@assignremexpr -270 - - -@assignlshiftexpr -598 - - -@assignrshiftexpr -4513 - - -@assignandexpr -7190 - - -@assignorexpr -17576 - - -@assignxorexpr -21997 - - -@assignpaddexpr -13024 - - -@assignpsubexpr -577 - - -@andlogicalexpr -130955 - - -@orlogicalexpr -74652 - - -@commaexpr -10611 - - -@subscriptexpr -166218 - - -@virtfunptrexpr -1 - - -@callexpr -224123 - - -@vastartexpr -3657 - - -@vaargexpr -975 - - -@vaendexpr -491 - - -@vacopyexpr -30 - - -@varaccess -5309798 - - -@thisaccess -1165266 - - -@new_expr -31757 - - -@delete_expr -5896 - - -@throw_expr -22056 - - -@condition_decl -6947 - - -@braced_init_list -119 - - -@type_id -4368 - - -@runtime_sizeof -279225 - - -@runtime_alignof -1561 - - -@sizeof_pack -466 - - -@expr_stmt -156574 - - -@routineexpr -2239747 - - -@type_operand -123457 - - -@offsetofexpr -33641 - - -@hasassignexpr -2 - - -@hascopyexpr -2 - - -@hasnothrowassign -3 - - -@hasnothrowconstr -3 - - -@hasnothrowcopy -5 - - -@hastrivialassign -2 - - -@hastrivialconstr -3 - - -@hastrivialcopy -2 - - -@hasuserdestr -3 - - -@hasvirtualdestr -3 - - -@isabstractexpr -3 - - -@isbaseofexpr -38 - - -@isclassexpr -214 - - -@isconvtoexpr -12 - - -@isemptyexpr -162 - - -@isenumexpr -21 - - -@ispodexpr -596 - - -@ispolyexpr -3 - - -@isunionexpr -5 - - -@typescompexpr -44908 - - -@intaddrexpr -1 - - -@hastrivialdestructor -108 - - -@literal -4380637 - - -@uuidof -844 - - -@aggregateliteral -915561 - - -@delete_array_expr -1333 - - -@new_array_expr -5287 - - -@foldexpr -4 - - -@ctordirectinit -89137 - - -@ctorvirtualinit -6156 - - -@ctorfieldinit -193753 - - -@ctordelegatinginit -726 - - -@dtordirectdestruct -28798 - - -@dtorvirtualdestruct -2406 - - -@dtorfielddestruct -29557 - - -@static_cast -212243 - - -@reinterpret_cast -30758 - - -@const_cast -5245 - - -@dynamic_cast -975 - - -@c_style_cast -4235362 - - -@lambdaexpr -12660 - - -@param_ref -84888 - - -@noopexpr -38 - - -@istriviallyconstructibleexpr -3 - - -@isdestructibleexpr -4 - - -@isnothrowdestructibleexpr -5 - - -@istriviallydestructibleexpr -5 - - -@istriviallyassignableexpr -3 - - -@isnothrowassignableexpr -3 - - -@istrivialexpr -43 - - -@isstandardlayoutexpr -2 - - -@istriviallycopyableexpr -2330 - - -@isliteraltypeexpr -2 - - -@hastrivialmoveconstructorexpr -3 - - -@hastrivialmoveassignexpr -3 - - -@hasnothrowmoveassignexpr -4 - - -@isconstructibleexpr -3 - - -@isnothrowconstructibleexpr -3 - - -@hasfinalizerexpr -1 - - -@isdelegateexpr -1 - - -@isinterfaceclassexpr -1 - - -@isrefarrayexpr -1 - - -@isrefclassexpr -1 - - -@issealedexpr -1 - - -@issimplevalueclassexpr -1 - - -@isvalueclassexpr -1 - - -@isfinalexpr -162 - - -@noexceptexpr -17320 - - -@builtinshufflevector -1 - - -@builtinchooseexpr -7405 - - -@builtinaddressof -3923 - - -@vec_fill -1 - - -@builtinconvertvector -1 - - -@builtincomplex -4 - - -@spaceshipexpr -1 - - -@co_await -6 - - -@co_yield -1 - - -@temp_init -241259 - - -@lambdacapture -21618 - - -@stmt_expr -1267720 - - -@stmt_if -524673 - - -@stmt_while -30641 - - -@stmt_goto -111468 - - -@stmt_label -81577 - - -@stmt_return -1116898 - - -@stmt_block -1309643 - - -@stmt_end_test_while -149931 - - -@stmt_for -32103 - - -@stmt_switch_case -271721 - - -@stmt_switch -53308 - - -@stmt_asm -241548 - - -@stmt_try_block -17753 - - -@stmt_microsoft_try -168 - - -@stmt_decl -605017 - - -@stmt_set_vla_size -11 - - -@stmt_vla_decl -8 - - -@stmt_assigned_goto -9139 - - -@stmt_empty -102194 - - -@stmt_continue -8080 - - -@stmt_break -224116 - - -@stmt_range_based_for -21 - - -@stmt_handler -21612 - - -@stmt_constexpr_if -3 - - -@stmt_co_return -2 - - -@ppd_if -154267 - - -@ppd_ifdef -60371 - - -@ppd_ifndef -82352 - - -@ppd_elif -20387 - - -@ppd_else -56990 - - -@ppd_endif -296991 - - -@ppd_plain_include -287356 - - -@ppd_define -314344 - - -@ppd_undef -19021 - - -@ppd_line -12495 - - -@ppd_error -43 - - -@ppd_pragma -36507 - - -@ppd_objc_import -2 - - -@ppd_include_next -86 - - -@ppd_warning -1 - - -@link_target -574 - - -@xmldtd -1 - - -@xmlelement -1270313 - - -@xmlattribute -1202020 - - -@xmlnamespace -4185 - - -@xmlcomment -26812 - - -@xmlcharacters -439958 - - - -compilations -9440 - - -id -9440 - - -cwd -10 - - - - -id -cwd - - -12 - - -1 -2 -9440 - - - - - - -cwd -id - - -12 - - -871 -872 -10 - - - - - - - - -compilation_args -376128 - - -id -4323 - - -num -162 - - -arg -18625 - - - - -id -num - - -12 - - -13 -77 -324 - - -85 -86 -9 - - -89 -90 -3202 - - -90 -92 -221 - - -92 -96 -267 - - -99 -101 -298 - - - - - - -id -arg - - -12 - - -13 -77 -324 - - -82 -83 -9 - - -88 -89 -3204 - - -89 -90 -158 - - -90 -92 -327 - - -94 -97 -299 - - - - - - -num -id - - -12 - - -2 -185 -13 - - -347 -2449 -11 - - -2454 -2455 -14 - - -2456 -2530 -13 - - -2530 -2534 -13 - - -2534 -2539 -13 - - -2539 -2544 -13 - - -2550 -2595 -9 - - -2604 -2607 -13 - - -2607 -2618 -13 - - -2619 -2643 -13 - - -2648 -2649 -1 - - -2653 -2654 -21 - - - - - - -num -arg - - -12 - - -1 -4 -11 - - -5 -7 -14 - - -7 -8 -19 - - -8 -9 -14 - - -9 -10 -16 - - -10 -11 -9 - - -11 -13 -8 - - -13 -14 -9 - - -14 -18 -13 - - -18 -26 -13 - - -30 -90 -13 - - -140 -1349 -13 - - -1739 -2534 -6 - - - - - - -arg -id - - -12 - - -1 -2 -17722 - - -2 -2654 -902 - - - - - - -arg -num - - -12 - - -1 -2 -18286 - - -2 -55 -339 - - - - - - - - -compilation_compiling_files -9440 - - -id -9440 - - -num -10 - - -file -4790 - - - - -id -num - - -12 - - -1 -2 -9440 - - - - - - -id -file - - -12 - - -1 -2 -9440 - - - - - - -num -id - - -12 - - -871 -872 -10 - - - - - - -num -file - - -12 - - -442 -443 -10 - - - - - - -file -id - - -12 - - -1 -2 -270 - - -2 -3 -4498 - - -3 -14 -21 - - - - - - -file -num - - -12 - - -1 -2 -4790 - - - - - - - - -compilation_time -37675 - - -id -9418 - - -num -10 - - -kind -43 - - -seconds -11868 - - - - -id -num - - -12 - - -1 -2 -9418 - - - - - - -id -kind - - -12 - - -4 -5 -9418 - - - - - - -id -seconds - - -12 - - -3 -4 -2850 - - -4 -5 -6568 - - - - - - -num -id - - -12 - - -869 -870 -10 - - - - - - -num -kind - - -12 - - -4 -5 -10 - - - - - - -num -seconds - - -12 - - -1095 -1096 -10 - - - - - - -kind -id - - -12 - - -869 -870 -43 - - - - - - -kind -num - - -12 - - -1 -2 -43 - - - - - - -kind -seconds - - -12 - - -7 -8 -10 - - -12 -13 -10 - - -579 -580 -10 - - -647 -648 -10 - - - - - - -seconds -id - - -12 - - -1 -2 -8053 - - -2 -3 -2254 - - -3 -5 -997 - - -5 -632 -563 - - - - - - -seconds -num - - -12 - - -1 -2 -11868 - - - - - - -seconds -kind - - -12 - - -1 -2 -10253 - - -2 -3 -1604 - - -3 -4 -10 - - - - - - - - -diagnostic_for -837183 - - -diagnostic -67893 - - -compilation -9115 - - -file_number -10 - - -file_number_diagnostic_number -6427 - - - - -diagnostic -compilation - - -12 - - -1 -2 -9147 - - -2 -3 -56079 - - -254 -840 -2666 - - - - - - -diagnostic -file_number - - -12 - - -1 -2 -67893 - - - - - - -diagnostic -file_number_diagnostic_number - - -12 - - -1 -2 -67893 - - - - - - -compilation -diagnostic - - -12 - - -2 -3 -21 - - -7 -8 -5744 - - -8 -9 -596 - - -247 -248 -1842 - - -263 -444 -715 - - -446 -594 -195 - - - - - - -compilation -file_number - - -12 - - -1 -2 -9115 - - - - - - -compilation -file_number_diagnostic_number - - -12 - - -2 -3 -21 - - -7 -8 -5744 - - -8 -9 -596 - - -247 -248 -1842 - - -263 -444 -715 - - -446 -594 -195 - - - - - - -file_number -diagnostic - - -12 - - -6264 -6265 -10 - - - - - - -file_number -compilation - - -12 - - -841 -842 -10 - - - - - - -file_number -file_number_diagnostic_number - - -12 - - -593 -594 -10 - - - - - - -file_number_diagnostic_number -diagnostic - - -12 - - -1 -2 -2644 - - -2 -5 -574 - - -5 -6 -942 - - -7 -14 -509 - - -15 -16 -54 - - -17 -18 -563 - - -18 -23 -433 - - -26 -40 -520 - - -42 -842 -184 - - - - - - -file_number_diagnostic_number -compilation - - -12 - - -4 -9 -552 - - -10 -11 -942 - - -14 -27 -509 - - -30 -31 -54 - - -34 -35 -563 - - -36 -45 -433 - - -52 -79 -520 - - -84 -85 -173 - - -254 -255 -2590 - - -309 -842 -86 - - - - - - -file_number_diagnostic_number -file_number - - -12 - - -1 -2 -6427 - - - - - - - - -compilation_finished -9440 - - -id -9440 - - -cpu_seconds -7619 - - -elapsed_seconds -195 - - - - -id -cpu_seconds - - -12 - - -1 -2 -9440 - - - - - - -id -elapsed_seconds - - -12 - - -1 -2 -9440 - - - - - - -cpu_seconds -id - - -12 - - -1 -2 -6449 - - -2 -3 -856 - - -3 -11 -314 - - - - - - -cpu_seconds -elapsed_seconds - - -12 - - -1 -2 -7045 - - -2 -3 -574 - - - - - - -elapsed_seconds -id - - -12 - - -1 -2 -54 - - -3 -4 -21 - - -6 -7 -10 - - -7 -8 -10 - - -8 -9 -10 - - -17 -18 -10 - - -26 -27 -10 - - -34 -35 -10 - - -124 -125 -10 - - -125 -126 -10 - - -140 -141 -10 - - -174 -175 -10 - - -199 -200 -10 - - - - - - -elapsed_seconds -cpu_seconds - - -12 - - -1 -2 -54 - - -3 -4 -21 - - -6 -7 -10 - - -7 -8 -10 - - -8 -9 -10 - - -17 -18 -10 - - -26 -27 -10 - - -34 -35 -10 - - -95 -96 -10 - - -106 -107 -10 - - -118 -119 -10 - - -148 -149 -10 - - -180 -181 -10 - - - - - - - - -externalData -130 - - -id -65 - - -path -10 - - -column -21 - - -value -130 - - - - -id -path - - -12 - - -1 -2 -65 - - - - - - -id -column - - -12 - - -2 -3 -65 - - - - - - -id -value - - -12 - - -2 -3 -65 - - - - - - -path -id - - -12 - - -6 -7 -10 - - - - - - -path -column - - -12 - - -2 -3 -10 - - - - - - -path -value - - -12 - - -12 -13 -10 - - - - - - -column -id - - -12 - - -6 -7 -21 - - - - - - -column -path - - -12 - - -1 -2 -21 - - - - - - -column -value - - -12 - - -6 -7 -21 - - - - - - -value -id - - -12 - - -1 -2 -130 - - - - - - -value -path - - -12 - - -1 -2 -130 - - - - - - -value -column - - -12 - - -1 -2 -130 - - - - - - - - -sourceLocationPrefix -10 - - -prefix -10 - - - - - -external_packages -119 - - -id -119 - - -namespace -10 - - -package_name -119 - - -version -119 - - - - -id -namespace - - -12 - - -1 -2 -119 - - - - - - -id -package_name - - -12 - - -1 -2 -119 - - - - - - -id -version - - -12 - - -1 -2 -119 - - - - - - -namespace -id - - -12 - - -11 -12 -10 - - - - - - -namespace -package_name - - -12 - - -11 -12 -10 - - - - - - -namespace -version - - -12 - - -11 -12 -10 - - - - - - -package_name -id - - -12 - - -1 -2 -119 - - - - - - -package_name -namespace - - -12 - - -1 -2 -119 - - - - - - -package_name -version - - -12 - - -1 -2 -119 - - - - - - -version -id - - -12 - - -1 -2 -119 - - - - - - -version -namespace - - -12 - - -1 -2 -119 - - - - - - -version -package_name - - -12 - - -1 -2 -119 - - - - - - - - -header_to_external_package -8432 - - -fileid -8432 - - -package -119 - - - - -fileid -package - - -12 - - -1 -2 -8432 - - - - - - -package -fileid - - -12 - - -1 -2 -32 - - -2 -3 -10 - - -15 -16 -21 - - -63 -64 -10 - - -71 -72 -10 - - -86 -87 -10 - - -253 -254 -10 - - -270 -271 -10 - - - - - - - - -svnentries -575525 - - -id -575525 - - -revision -575525 - - -author -19539 - - -revisionDate -547759 - - -changeSize -1 - - - - -id -revision - - -12 - - -1 -2 -575525 - - - - - - -id -author - - -12 - - -1 -2 -575525 - - - - - - -id -revisionDate - - -12 - - -1 -2 -575525 - - - - - - -id -changeSize - - -12 - - -1 -2 -575525 - - - - - - -revision -id - - -12 - - -1 -2 -575525 - - - - - - -revision -author - - -12 - - -1 -2 -575525 - - - - - - -revision -revisionDate - - -12 - - -1 -2 -575525 - - - - - - -revision -changeSize - - -12 - - -1 -2 -575525 - - - - - - -author -id - - -12 - - -1 -2 -7913 - - -2 -3 -2531 - - -3 -4 -1388 - - -4 -6 -1523 - - -6 -10 -1529 - - -10 -20 -1509 - - -20 -52 -1488 - - -52 -568 -1466 - - -569 -16582 -192 - - - - - - -author -revision - - -12 - - -1 -2 -7913 - - -2 -3 -2531 - - -3 -4 -1388 - - -4 -6 -1523 - - -6 -10 -1529 - - -10 -20 -1509 - - -20 -52 -1488 - - -52 -568 -1466 - - -569 -16582 -192 - - - - - - -author -revisionDate - - -12 - - -1 -2 -7996 - - -2 -3 -2509 - - -3 -4 -1379 - - -4 -6 -1520 - - -6 -10 -1529 - - -10 -20 -1507 - - -20 -52 -1474 - - -52 -662 -1466 - - -663 -16573 -159 - - - - - - -author -changeSize - - -12 - - -1 -2 -19539 - - - - - - -revisionDate -id - - -12 - - -1 -2 -531878 - - -2 -100 -15881 - - - - - - -revisionDate -revision - - -12 - - -1 -2 -531878 - - -2 -100 -15881 - - - - - - -revisionDate -author - - -12 - - -1 -2 -542505 - - -2 -17 -5254 - - - - - - -revisionDate -changeSize - - -12 - - -1 -2 -547759 - - - - - - -changeSize -id - - -12 - - -575525 -575526 -1 - - - - - - -changeSize -revision - - -12 - - -575525 -575526 -1 - - - - - - -changeSize -author - - -12 - - -19539 -19540 -1 - - - - - - -changeSize -revisionDate - - -12 - - -547759 -547760 -1 - - - - - - - - -svnaffectedfiles -1314068 - - -id -531628 - - -file -90924 - - -action -1 - - - - -id -file - - -12 - - -1 -2 -337698 - - -2 -3 -77525 - - -3 -4 -43024 - - -4 -7 -46689 - - -7 -16635 -26692 - - - - - - -id -action - - -12 - - -1 -2 -531628 - - - - - - -file -id - - -12 - - -1 -2 -11819 - - -2 -3 -18230 - - -3 -4 -9501 - - -4 -5 -6656 - - -5 -6 -5012 - - -6 -8 -7103 - - -8 -11 -6788 - - -11 -16 -6996 - - -16 -26 -7180 - - -26 -54 -6824 - - -54 -3572 -4815 - - - - - - -file -action - - -12 - - -1 -2 -90924 - - - - - - -action -id - - -12 - - -531628 -531629 -1 - - - - - - -action -file - - -12 - - -90924 -90925 -1 - - - - - - - - -svnentrymsg -575525 - - -id -575525 - - -message -568305 - - - - -id -message - - -12 - - -1 -2 -575525 - - - - - - -message -id - - -12 - - -1 -2 -565381 - - -2 -142 -2924 - - - - - - - - -svnchurn -46790 - - -commit -22361 - - -file -16124 - - -addedLines -910 - - -deletedLines -787 - - - - -commit -file - - -12 - - -1 -2 -15208 - - -2 -3 -3101 - - -3 -4 -1746 - - -4 -8 -1774 - - -8 -246 -532 - - - - - - -commit -addedLines - - -12 - - -1 -2 -16074 - - -2 -3 -3323 - - -3 -4 -1561 - - -4 -118 -1403 - - - - - - -commit -deletedLines - - -12 - - -1 -2 -16799 - - -2 -3 -3286 - - -3 -5 -1763 - - -5 -113 -513 - - - - - - -file -commit - - -12 - - -1 -2 -8618 - - -2 -3 -2956 - - -3 -4 -1426 - - -4 -6 -1364 - - -6 -12 -1210 - - -12 -448 -550 - - - - - - -file -addedLines - - -12 - - -1 -2 -9240 - - -2 -3 -3129 - - -3 -4 -1393 - - -4 -6 -1239 - - -6 -59 -1123 - - - - - - -file -deletedLines - - -12 - - -1 -2 -9525 - - -2 -3 -3192 - - -3 -4 -1401 - - -4 -7 -1387 - - -7 -70 -619 - - - - - - -addedLines -commit - - -12 - - -1 -2 -446 - - -2 -3 -133 - - -3 -4 -70 - - -4 -6 -68 - - -6 -12 -70 - - -12 -57 -69 - - -57 -6874 -54 - - - - - - -addedLines -file - - -12 - - -1 -2 -445 - - -2 -3 -132 - - -3 -4 -69 - - -4 -6 -68 - - -6 -12 -73 - - -12 -58 -69 - - -58 -6663 -54 - - - - - - -addedLines -deletedLines - - -12 - - -1 -2 -621 - - -2 -3 -96 - - -3 -7 -81 - - -7 -34 -70 - - -34 -727 -42 - - - - - - -deletedLines -commit - - -12 - - -1 -2 -439 - - -2 -3 -116 - - -3 -4 -48 - - -4 -8 -67 - - -8 -28 -60 - - -28 -6794 -57 - - - - - - -deletedLines -file - - -12 - - -1 -2 -437 - - -2 -3 -113 - - -3 -4 -49 - - -4 -7 -61 - - -7 -19 -60 - - -19 -770 -60 - - -985 -7318 -7 - - - - - - -deletedLines -addedLines - - -12 - - -1 -2 -545 - - -2 -3 -72 - - -3 -7 -69 - - -7 -30 -60 - - -30 -871 -41 - - - - - - - - -locations_default -8719593 - - -id -8719593 - - -container -70137 - - -startLine -148869 - - -startColumn -5397 - - -endLine -148696 - - -endColumn -10502 - - - - -id -container - - -12 - - -1 -2 -8719593 - - - - - - -id -startLine - - -12 - - -1 -2 -8719593 - - - - - - -id -startColumn - - -12 - - -1 -2 -8719593 - - - - - - -id -endLine - - -12 - - -1 -2 -8719593 - - - - - - -id -endColumn - - -12 - - -1 -2 -8719593 - - - - - - -container -id - - -12 - - -1 -2 -11391 - - -2 -19 -6026 - - -19 -25 -5419 - - -25 -31 -5451 - - -31 -41 -5755 - - -41 -54 -5462 - - -54 -72 -5538 - - -72 -99 -5354 - - -99 -137 -5321 - - -137 -220 -5267 - - -220 -430 -5267 - - -430 -20913 -3880 - - - - - - -container -startLine - - -12 - - -1 -2 -11391 - - -2 -15 -5939 - - -15 -20 -6069 - - -20 -25 -5484 - - -25 -32 -6026 - - -32 -41 -5614 - - -41 -53 -5657 - - -53 -71 -5527 - - -71 -99 -5386 - - -99 -158 -5267 - - -158 -351 -5300 - - -351 -9356 -2471 - - - - - - -container -startColumn - - -12 - - -1 -2 -11391 - - -2 -4 -5939 - - -4 -8 -6470 - - -8 -11 -5332 - - -11 -14 -5712 - - -14 -18 -6178 - - -18 -23 -5690 - - -23 -29 -5766 - - -29 -37 -5625 - - -37 -50 -5603 - - -50 -78 -5321 - - -78 -168 -1105 - - - - - - -container -endLine - - -12 - - -1 -2 -11391 - - -2 -15 -5917 - - -15 -20 -6091 - - -20 -25 -5430 - - -25 -32 -6037 - - -32 -41 -5603 - - -41 -53 -5657 - - -53 -70 -5321 - - -70 -96 -5278 - - -96 -153 -5332 - - -153 -333 -5289 - - -333 -9356 -2785 - - - - - - -container -endColumn - - -12 - - -1 -2 -11391 - - -2 -14 -5668 - - -14 -19 -6048 - - -19 -23 -5646 - - -23 -28 -6340 - - -28 -33 -5451 - - -33 -40 -5885 - - -40 -47 -5289 - - -47 -57 -5538 - - -57 -69 -5571 - - -69 -91 -5267 - - -91 -336 -2037 - - - - - - -startLine -id - - -12 - - -1 -2 -30489 - - -2 -3 -17818 - - -3 -4 -17742 - - -4 -5 -9603 - - -5 -7 -13548 - - -7 -9 -13255 - - -9 -13 -13049 - - -13 -32 -11434 - - -32 -128 -11185 - - -128 -6472 -10741 - - - - - - -startLine -container - - -12 - - -1 -2 -55006 - - -2 -3 -33047 - - -3 -4 -9787 - - -4 -5 -8334 - - -5 -8 -12757 - - -8 -27 -11358 - - -27 -123 -11207 - - -123 -6472 -7370 - - - - - - -startLine -startColumn - - -12 - - -1 -2 -31584 - - -2 -3 -17656 - - -3 -4 -19563 - - -4 -5 -9473 - - -5 -7 -13754 - - -7 -9 -13667 - - -9 -13 -12562 - - -13 -27 -11348 - - -27 -62 -11218 - - -62 -153 -8042 - - - - - - -startLine -endLine - - -12 - - -1 -2 -111649 - - -2 -3 -17211 - - -3 -7 -12388 - - -7 -184 -7619 - - - - - - -startLine -endColumn - - -12 - - -1 -2 -31432 - - -2 -3 -17569 - - -3 -4 -18425 - - -4 -5 -9754 - - -5 -7 -13570 - - -7 -9 -13613 - - -9 -13 -12583 - - -13 -29 -11521 - - -29 -74 -11185 - - -74 -258 -9212 - - - - - - -startColumn -id - - -12 - - -1 -2 -867 - - -2 -3 -997 - - -3 -5 -498 - - -5 -8 -476 - - -8 -16 -433 - - -16 -37 -411 - - -37 -119 -411 - - -124 -512 -411 - - -522 -5004 -411 - - -5044 -19250 -411 - - -19714 -201002 -65 - - - - - - -startColumn -container - - -12 - - -1 -2 -2319 - - -2 -3 -487 - - -3 -6 -422 - - -6 -15 -433 - - -15 -55 -411 - - -59 -228 -411 - - -231 -1213 -411 - - -1274 -2356 -411 - - -2555 -6472 -86 - - - - - - -startColumn -startLine - - -12 - - -1 -2 -899 - - -2 -3 -986 - - -3 -4 -260 - - -4 -6 -466 - - -6 -10 -422 - - -10 -20 -411 - - -20 -55 -411 - - -56 -194 -411 - - -196 -844 -411 - - -863 -1976 -411 - - -1976 -6604 -303 - - - - - - -startColumn -endLine - - -12 - - -1 -2 -899 - - -2 -3 -986 - - -3 -4 -260 - - -4 -6 -466 - - -6 -10 -422 - - -10 -20 -411 - - -20 -55 -411 - - -56 -194 -411 - - -206 -843 -411 - - -863 -1977 -411 - - -1980 -6583 -303 - - - - - - -startColumn -endColumn - - -12 - - -1 -2 -2449 - - -2 -3 -487 - - -3 -7 -487 - - -7 -13 -422 - - -13 -28 -411 - - -28 -49 -422 - - -50 -103 -411 - - -105 -428 -303 - - - - - - -endLine -id - - -12 - - -1 -2 -30207 - - -2 -3 -17851 - - -3 -4 -17602 - - -4 -5 -9754 - - -5 -7 -13613 - - -7 -9 -13299 - - -9 -13 -12898 - - -13 -31 -11326 - - -31 -125 -11207 - - -125 -6472 -10936 - - - - - - -endLine -container - - -12 - - -1 -2 -54724 - - -2 -3 -32949 - - -3 -4 -9754 - - -4 -5 -8443 - - -5 -8 -12952 - - -8 -27 -11196 - - -27 -121 -11163 - - -121 -6472 -7511 - - - - - - -endLine -startLine - - -12 - - -1 -2 -110869 - - -2 -3 -17049 - - -3 -7 -11933 - - -7 -46 -8844 - - - - - - -endLine -startColumn - - -12 - - -1 -2 -31280 - - -2 -3 -17732 - - -3 -4 -19509 - - -4 -5 -9494 - - -5 -6 -7771 - - -6 -7 -6058 - - -7 -9 -13678 - - -9 -13 -12562 - - -13 -27 -11358 - - -27 -62 -11218 - - -62 -153 -8031 - - - - - - -endLine -endColumn - - -12 - - -1 -2 -31183 - - -2 -3 -17537 - - -3 -4 -18414 - - -4 -5 -9819 - - -5 -7 -13656 - - -7 -9 -13613 - - -9 -13 -12637 - - -13 -29 -11380 - - -29 -74 -11196 - - -74 -258 -9256 - - - - - - -endColumn -id - - -12 - - -1 -2 -4151 - - -2 -3 -1159 - - -3 -4 -758 - - -4 -5 -639 - - -5 -9 -867 - - -9 -36 -791 - - -36 -256 -791 - - -257 -7244 -791 - - -7397 -25755 -552 - - - - - - -endColumn -container - - -12 - - -1 -2 -4769 - - -2 -3 -1257 - - -3 -4 -953 - - -4 -7 -899 - - -7 -31 -791 - - -32 -356 -791 - - -377 -2696 -791 - - -2701 -6472 -249 - - - - - - -endColumn -startLine - - -12 - - -1 -2 -4183 - - -2 -3 -1148 - - -3 -4 -791 - - -4 -5 -628 - - -5 -9 -845 - - -9 -34 -791 - - -34 -221 -791 - - -233 -1884 -791 - - -1885 -4894 -531 - - - - - - -endColumn -startColumn - - -12 - - -1 -2 -4801 - - -2 -3 -1311 - - -3 -4 -942 - - -4 -7 -899 - - -7 -22 -802 - - -22 -45 -791 - - -45 -81 -812 - - -81 -84 -140 - - - - - - -endColumn -endLine - - -12 - - -1 -2 -4183 - - -2 -3 -1148 - - -3 -4 -802 - - -4 -5 -628 - - -5 -9 -845 - - -9 -33 -802 - - -34 -234 -791 - - -240 -1928 -791 - - -1951 -4895 -509 - - - - - - - - -locations_stmt -2179578 - - -id -2179578 - - -container -3177 - - -startLine -296783 - - -startColumn -1229 - - -endLine -294982 - - -endColumn -1493 - - - - -id -container - - -12 - - -1 -2 -2179578 - - - - - - -id -startLine - - -12 - - -1 -2 -2179578 - - - - - - -id -startColumn - - -12 - - -1 -2 -2179578 - - - - - - -id -endLine - - -12 - - -1 -2 -2179578 - - - - - - -id -endColumn - - -12 - - -1 -2 -2179578 - - - - - - -container -id - - -12 - - -1 -7 -288 - - -7 -17 -258 - - -17 -30 -251 - - -30 -53 -239 - - -53 -89 -245 - - -89 -140 -239 - - -140 -213 -245 - - -215 -297 -239 - - -302 -462 -239 - - -464 -739 -239 - - -743 -1085 -239 - - -1099 -1959 -239 - - -1972 -53712 -208 - - - - - - -container -startLine - - -12 - - -1 -6 -239 - - -6 -13 -239 - - -13 -23 -245 - - -23 -37 -239 - - -37 -65 -239 - - -65 -101 -245 - - -102 -155 -239 - - -158 -212 -239 - - -214 -325 -239 - - -328 -516 -239 - - -526 -738 -239 - - -738 -1166 -239 - - -1169 -3598 -239 - - -3809 -38985 -49 - - - - - - -container -startColumn - - -12 - - -1 -2 -24 - - -2 -3 -571 - - -3 -5 -202 - - -5 -8 -288 - - -8 -14 -245 - - -14 -20 -264 - - -20 -29 -251 - - -29 -39 -251 - - -39 -51 -251 - - -51 -63 -264 - - -63 -78 -245 - - -78 -107 -245 - - -107 -126 -67 - - - - - - -container -endLine - - -12 - - -1 -5 -239 - - -5 -13 -282 - - -13 -24 -264 - - -24 -41 -245 - - -43 -67 -239 - - -67 -103 -239 - - -103 -163 -245 - - -163 -230 -239 - - -231 -369 -239 - - -369 -581 -239 - - -581 -811 -239 - - -818 -1418 -239 - - -1423 -38575 -221 - - - - - - -container -endColumn - - -12 - - -1 -4 -282 - - -4 -7 -258 - - -7 -13 -245 - - -13 -21 -251 - - -21 -29 -239 - - -29 -40 -282 - - -40 -49 -264 - - -49 -60 -258 - - -60 -73 -245 - - -73 -84 -239 - - -84 -97 -239 - - -97 -120 -239 - - -120 -172 -129 - - - - - - -startLine -id - - -12 - - -1 -2 -113822 - - -2 -3 -78757 - - -3 -4 -31327 - - -4 -6 -25205 - - -6 -16 -22538 - - -16 -128 -22347 - - -128 -222 -2784 - - - - - - -startLine -container - - -12 - - -1 -2 -175591 - - -2 -3 -52052 - - -3 -5 -22741 - - -5 -13 -22415 - - -13 -125 -22298 - - -125 -176 -1684 - - - - - - -startLine -startColumn - - -12 - - -1 -2 -130841 - - -2 -3 -73207 - - -3 -4 -31204 - - -4 -7 -26846 - - -7 -17 -23085 - - -17 -45 -11597 - - - - - - -startLine -endLine - - -12 - - -1 -2 -191719 - - -2 -3 -47768 - - -3 -4 -21726 - - -4 -9 -23202 - - -9 -30 -12366 - - - - - - -startLine -endColumn - - -12 - - -1 -2 -156052 - - -2 -3 -62630 - - -3 -4 -21093 - - -4 -9 -24707 - - -9 -31 -22464 - - -31 -73 -9833 - - - - - - -startColumn -id - - -12 - - -1 -2 -135 - - -2 -3 -79 - - -3 -6 -110 - - -6 -15 -98 - - -15 -29 -104 - - -29 -69 -98 - - -72 -145 -98 - - -149 -318 -98 - - -321 -581 -98 - - -585 -893 -98 - - -905 -2476 -98 - - -2724 -38142 -98 - - -63637 -75127 -12 - - - - - - -startColumn -container - - -12 - - -1 -2 -141 - - -2 -3 -86 - - -3 -5 -73 - - -5 -10 -98 - - -11 -18 -98 - - -18 -32 -104 - - -34 -64 -98 - - -66 -92 -98 - - -92 -130 -98 - - -131 -174 -98 - - -174 -208 -104 - - -208 -298 -98 - - -298 -498 -30 - - - - - - -startColumn -startLine - - -12 - - -1 -2 -135 - - -2 -3 -79 - - -3 -6 -110 - - -6 -15 -98 - - -15 -29 -104 - - -29 -68 -98 - - -70 -143 -98 - - -143 -313 -104 - - -319 -555 -98 - - -603 -830 -98 - - -832 -2107 -98 - - -2438 -15462 -98 - - -18292 -18293 -6 - - - - - - -startColumn -endLine - - -12 - - -1 -2 -135 - - -2 -3 -79 - - -3 -6 -110 - - -6 -15 -98 - - -15 -29 -104 - - -29 -68 -98 - - -70 -144 -98 - - -146 -308 -98 - - -314 -542 -98 - - -554 -801 -98 - - -819 -2028 -98 - - -2086 -15270 -98 - - -15556 -18380 -12 - - - - - - -startColumn -endColumn - - -12 - - -1 -2 -153 - - -2 -3 -92 - - -3 -4 -86 - - -4 -6 -98 - - -6 -7 -55 - - -7 -9 -104 - - -9 -12 -98 - - -12 -15 -98 - - -15 -26 -104 - - -26 -35 -98 - - -35 -46 -98 - - -46 -114 -98 - - -131 -203 -43 - - - - - - -endLine -id - - -12 - - -1 -2 -116170 - - -2 -3 -72937 - - -3 -4 -31948 - - -4 -6 -25709 - - -6 -16 -23140 - - -16 -126 -22138 - - -126 -229 -2937 - - - - - - -endLine -container - - -12 - - -1 -2 -175302 - - -2 -3 -52249 - - -3 -5 -22206 - - -5 -14 -23521 - - -14 -172 -21702 - - - - - - -endLine -startLine - - -12 - - -1 -2 -194005 - - -2 -3 -42943 - - -3 -4 -20940 - - -4 -8 -22458 - - -8 -32 -14634 - - - - - - -endLine -startColumn - - -12 - - -1 -2 -133004 - - -2 -3 -68069 - - -3 -4 -32489 - - -4 -7 -26723 - - -7 -16 -22163 - - -16 -46 -12532 - - - - - - -endLine -endColumn - - -12 - - -1 -2 -155948 - - -2 -3 -62494 - - -3 -4 -21401 - - -4 -9 -23890 - - -9 -34 -22415 - - -34 -73 -8832 - - - - - - -endColumn -id - - -12 - - -1 -2 -184 - - -2 -4 -135 - - -4 -7 -104 - - -7 -15 -122 - - -16 -43 -116 - - -56 -131 -122 - - -134 -276 -116 - - -283 -620 -116 - - -650 -1179 -116 - - -1220 -2551 -116 - - -2686 -5415 -116 - - -5429 -26558 -116 - - -36191 -36192 -6 - - - - - - -endColumn -container - - -12 - - -1 -2 -215 - - -2 -3 -86 - - -3 -6 -135 - - -6 -12 -129 - - -13 -25 -116 - - -25 -51 -116 - - -55 -89 -116 - - -92 -152 -116 - - -153 -210 -116 - - -210 -266 -116 - - -270 -310 -116 - - -312 -512 -110 - - - - - - -endColumn -startLine - - -12 - - -1 -2 -184 - - -2 -4 -135 - - -4 -7 -104 - - -7 -15 -122 - - -16 -43 -116 - - -51 -125 -116 - - -128 -254 -116 - - -264 -570 -116 - - -590 -943 -116 - - -1020 -1875 -116 - - -1902 -3509 -116 - - -3526 -7422 -116 - - -8516 -9009 -12 - - - - - - -endColumn -startColumn - - -12 - - -1 -2 -202 - - -2 -3 -116 - - -3 -4 -86 - - -4 -6 -135 - - -6 -10 -129 - - -10 -13 -122 - - -13 -16 -122 - - -16 -22 -122 - - -22 -31 -122 - - -31 -38 -129 - - -38 -43 -122 - - -43 -174 -79 - - - - - - -endColumn -endLine - - -12 - - -1 -2 -184 - - -2 -4 -135 - - -4 -7 -104 - - -7 -15 -122 - - -16 -43 -116 - - -51 -124 -116 - - -127 -251 -116 - - -261 -556 -116 - - -584 -934 -116 - - -1007 -1816 -116 - - -1894 -3330 -116 - - -3448 -6941 -116 - - -8353 -8659 -12 - - - - - - - - -locations_expr -9756708 - - -id -9756708 - - -container -3574 - - -startLine -195321 - - -startColumn -386 - - -endLine -195640 - - -endColumn -456 - - - - -id -container - - -12 - - -1 -2 -9756708 - - - - - - -id -startLine - - -12 - - -1 -2 -9756708 - - - - - - -id -startColumn - - -12 - - -1 -2 -9756708 - - - - - - -id -endLine - - -12 - - -1 -2 -9756708 - - - - - - -id -endColumn - - -12 - - -1 -2 -9756708 - - - - - - -container -id - - -12 - - -1 -4 -319 - - -4 -10 -269 - - -10 -34 -269 - - -34 -108 -269 - - -108 -205 -270 - - -205 -322 -270 - - -322 -485 -271 - - -486 -746 -269 - - -746 -1181 -269 - - -1181 -1853 -269 - - -1857 -3184 -269 - - -3187 -7084 -269 - - -7174 -43241 -269 - - -43580 -491727 -23 - - - - - - -container -startLine - - -12 - - -1 -3 -302 - - -3 -7 -316 - - -7 -17 -271 - - -17 -36 -277 - - -36 -61 -272 - - -61 -89 -273 - - -89 -137 -270 - - -137 -205 -271 - - -205 -335 -269 - - -335 -524 -269 - - -524 -946 -269 - - -947 -2043 -269 - - -2045 -142752 -246 - - - - - - -container -startColumn - - -12 - - -1 -3 -304 - - -3 -7 -303 - - -7 -17 -272 - - -17 -35 -269 - - -35 -51 -283 - - -51 -63 -290 - - -63 -73 -292 - - -73 -83 -282 - - -83 -92 -271 - - -92 -104 -274 - - -104 -120 -277 - - -120 -145 -270 - - -145 -330 -187 - - - - - - -container -endLine - - -12 - - -1 -3 -302 - - -3 -7 -313 - - -7 -17 -274 - - -17 -36 -275 - - -36 -61 -272 - - -61 -89 -270 - - -89 -137 -270 - - -137 -205 -270 - - -205 -337 -269 - - -337 -533 -269 - - -533 -946 -269 - - -947 -2071 -269 - - -2077 -143560 -252 - - - - - - -container -endColumn - - -12 - - -1 -3 -282 - - -3 -7 -298 - - -7 -19 -282 - - -19 -43 -284 - - -43 -61 -287 - - -61 -74 -294 - - -74 -85 -279 - - -85 -96 -286 - - -96 -107 -280 - - -107 -121 -280 - - -121 -139 -274 - - -139 -167 -271 - - -167 -416 -177 - - - - - - -startLine -id - - -12 - - -1 -2 -7506 - - -2 -3 -28155 - - -3 -4 -37070 - - -4 -5 -16164 - - -5 -6 -10348 - - -6 -8 -16992 - - -8 -11 -17633 - - -11 -16 -16438 - - -16 -25 -15790 - - -25 -97 -14716 - - -97 -4266 -14509 - - - - - - -startLine -container - - -12 - - -1 -2 -100560 - - -2 -3 -34005 - - -3 -4 -12707 - - -4 -5 -12439 - - -5 -12 -15112 - - -12 -95 -14670 - - -95 -1342 -5828 - - - - - - -startLine -startColumn - - -12 - - -1 -2 -7668 - - -2 -3 -28146 - - -3 -4 -37760 - - -4 -5 -16417 - - -5 -6 -11671 - - -6 -7 -12742 - - -7 -9 -16572 - - -9 -12 -15812 - - -12 -18 -16484 - - -18 -39 -14870 - - -39 -118 -14836 - - -118 -201 -2343 - - - - - - -startLine -endLine - - -12 - - -1 -2 -93569 - - -2 -3 -68359 - - -3 -4 -13336 - - -4 -8 -16334 - - -8 -60 -3723 - - - - - - -startLine -endColumn - - -12 - - -1 -2 -17044 - - -2 -3 -34830 - - -3 -4 -22935 - - -4 -5 -15998 - - -5 -6 -18855 - - -6 -8 -12903 - - -8 -10 -13538 - - -10 -14 -15565 - - -14 -21 -14781 - - -21 -61 -14731 - - -61 -184 -14141 - - - - - - -startColumn -id - - -12 - - -1 -2 -31 - - -2 -4 -29 - - -4 -8 -29 - - -8 -23 -29 - - -24 -63 -30 - - -75 -225 -29 - - -232 -684 -29 - - -694 -1672 -29 - - -1751 -4184 -29 - - -4489 -15276 -29 - - -16143 -46384 -29 - - -48765 -86984 -29 - - -87199 -224328 -29 - - -237383 -712891 -6 - - - - - - -startColumn -container - - -12 - - -1 -2 -76 - - -2 -3 -25 - - -3 -7 -31 - - -7 -19 -30 - - -19 -53 -29 - - -55 -130 -29 - - -132 -341 -29 - - -344 -777 -29 - - -778 -1426 -29 - - -1471 -2095 -29 - - -2118 -2433 -29 - - -2437 -2810 -21 - - - - - - -startColumn -startLine - - -12 - - -1 -2 -41 - - -2 -4 -30 - - -4 -9 -29 - - -9 -28 -30 - - -31 -113 -29 - - -120 -349 -29 - - -356 -880 -29 - - -919 -2301 -29 - - -2307 -5125 -29 - - -5505 -12957 -29 - - -13031 -18247 -29 - - -18468 -26386 -29 - - -26397 -108382 -24 - - - - - - -startColumn -endLine - - -12 - - -1 -2 -41 - - -2 -4 -30 - - -4 -9 -29 - - -9 -28 -30 - - -31 -113 -29 - - -120 -349 -29 - - -356 -880 -29 - - -919 -2301 -29 - - -2307 -5126 -29 - - -5507 -12959 -29 - - -13028 -18367 -29 - - -18468 -26374 -29 - - -26393 -108398 -24 - - - - - - -startColumn -endColumn - - -12 - - -1 -2 -34 - - -2 -3 -37 - - -3 -5 -33 - - -5 -9 -29 - - -9 -18 -30 - - -18 -40 -30 - - -42 -51 -29 - - -51 -73 -29 - - -74 -99 -29 - - -99 -136 -29 - - -136 -166 -30 - - -166 -181 -29 - - -181 -293 -18 - - - - - - -endLine -id - - -12 - - -1 -2 -7754 - - -2 -3 -40765 - - -3 -4 -7734 - - -4 -5 -29998 - - -5 -6 -10878 - - -6 -7 -12021 - - -7 -9 -15602 - - -9 -13 -17880 - - -13 -19 -14695 - - -19 -34 -14922 - - -34 -233 -14683 - - -233 -4272 -8708 - - - - - - -endLine -container - - -12 - - -1 -2 -100438 - - -2 -3 -34143 - - -3 -4 -12560 - - -4 -5 -12621 - - -5 -11 -14795 - - -11 -88 -14707 - - -88 -1343 -6376 - - - - - - -endLine -startLine - - -12 - - -1 -2 -118668 - - -2 -3 -22776 - - -3 -4 -30958 - - -4 -7 -17210 - - -7 -23 -6028 - - - - - - -endLine -startColumn - - -12 - - -1 -2 -7907 - - -2 -3 -40677 - - -3 -4 -8232 - - -4 -5 -30893 - - -5 -6 -10994 - - -6 -7 -13979 - - -7 -9 -16931 - - -9 -12 -16730 - - -12 -18 -16864 - - -18 -38 -14833 - - -38 -116 -14846 - - -116 -201 -2754 - - - - - - -endLine -endColumn - - -12 - - -1 -2 -32161 - - -2 -3 -18779 - - -3 -4 -8001 - - -4 -5 -30465 - - -5 -6 -18987 - - -6 -8 -17087 - - -8 -11 -16321 - - -11 -16 -15572 - - -16 -27 -14835 - - -27 -94 -14740 - - -94 -184 -8692 - - - - - - -endColumn -id - - -12 - - -1 -2 -28 - - -2 -3 -38 - - -3 -9 -38 - - -9 -15 -37 - - -15 -34 -35 - - -34 -173 -35 - - -174 -506 -35 - - -522 -1595 -35 - - -1667 -5254 -35 - - -5327 -18561 -35 - - -20354 -51707 -35 - - -54831 -117890 -35 - - -117994 -185975 -35 - - - - - - -endColumn -container - - -12 - - -1 -2 -99 - - -2 -3 -42 - - -3 -8 -37 - - -8 -28 -36 - - -28 -70 -35 - - -70 -207 -35 - - -226 -589 -35 - - -602 -1192 -35 - - -1208 -1967 -35 - - -1970 -2479 -35 - - -2482 -2650 -32 - - - - - - -endColumn -startLine - - -12 - - -1 -2 -44 - - -2 -4 -38 - - -4 -10 -32 - - -10 -16 -37 - - -16 -50 -35 - - -52 -234 -35 - - -243 -667 -35 - - -682 -2061 -35 - - -2070 -5994 -35 - - -6052 -12974 -35 - - -13162 -20941 -35 - - -20996 -28030 -35 - - -29280 -55693 -25 - - - - - - -endColumn -startColumn - - -12 - - -1 -2 -45 - - -2 -3 -56 - - -3 -5 -37 - - -5 -13 -36 - - -13 -35 -37 - - -35 -54 -35 - - -54 -64 -36 - - -65 -82 -36 - - -82 -102 -36 - - -102 -125 -38 - - -125 -135 -35 - - -135 -156 -29 - - - - - - -endColumn -endLine - - -12 - - -1 -2 -44 - - -2 -4 -38 - - -4 -10 -32 - - -10 -16 -37 - - -16 -50 -35 - - -52 -234 -35 - - -243 -666 -35 - - -682 -2062 -35 - - -2067 -5995 -35 - - -6041 -12938 -35 - - -13154 -20904 -35 - - -21020 -28041 -35 - - -29290 -55694 -25 - - - - - - - - -numlines -493411 - - -element_id -486528 - - -num_lines -9234 - - -num_code -7207 - - -num_comment -3891 - - - - -element_id -num_lines - - -12 - - -1 -2 -479722 - - -2 -7 -6806 - - - - - - -element_id -num_code - - -12 - - -1 -2 -479776 - - -2 -7 -6752 - - - - - - -element_id -num_comment - - -12 - - -1 -2 -486452 - - -2 -3 -75 - - - - - - -num_lines -element_id - - -12 - - -1 -2 -4205 - - -2 -3 -1235 - - -3 -4 -693 - - -4 -6 -726 - - -6 -12 -693 - - -12 -24 -704 - - -24 -121 -693 - - -121 -7771 -281 - - - - - - -num_lines -num_code - - -12 - - -1 -2 -4270 - - -2 -3 -1246 - - -3 -4 -704 - - -4 -6 -747 - - -6 -11 -802 - - -11 -18 -726 - - -18 -30 -704 - - -30 -32 -32 - - - - - - -num_lines -num_comment - - -12 - - -1 -2 -4259 - - -2 -3 -1246 - - -3 -4 -715 - - -4 -6 -758 - - -6 -11 -834 - - -11 -17 -715 - - -17 -27 -704 - - - - - - -num_code -element_id - - -12 - - -1 -2 -3143 - - -2 -3 -845 - - -3 -4 -617 - - -4 -6 -552 - - -6 -10 -596 - - -10 -22 -585 - - -22 -101 -541 - - -101 -7978 -325 - - - - - - -num_code -num_lines - - -12 - - -1 -2 -3164 - - -2 -3 -877 - - -3 -4 -628 - - -4 -6 -552 - - -6 -10 -628 - - -10 -21 -606 - - -21 -35 -541 - - -35 -42 -205 - - - - - - -num_code -num_comment - - -12 - - -1 -2 -3154 - - -2 -3 -899 - - -3 -4 -628 - - -4 -6 -531 - - -6 -9 -552 - - -9 -17 -552 - - -17 -27 -574 - - -27 -34 -314 - - - - - - -num_comment -element_id - - -12 - - -1 -2 -1864 - - -2 -3 -401 - - -3 -4 -292 - - -4 -7 -325 - - -7 -13 -325 - - -14 -38 -292 - - -39 -280 -292 - - -286 -36252 -97 - - - - - - -num_comment -num_lines - - -12 - - -1 -2 -1875 - - -2 -3 -411 - - -3 -4 -260 - - -4 -7 -336 - - -7 -13 -325 - - -13 -35 -292 - - -35 -90 -292 - - -91 -119 -97 - - - - - - -num_comment -num_code - - -12 - - -1 -2 -1875 - - -2 -3 -411 - - -3 -4 -270 - - -4 -7 -325 - - -7 -12 -303 - - -12 -33 -292 - - -33 -82 -292 - - -82 -108 -119 - - - - - - - - -diagnostics -67893 - - -id -67893 - - -severity -21 - - -error_tag -75 - - -error_message -97 - - -full_error_message -58789 - - -location -119 - - - - -id -severity - - -12 - - -1 -2 -67893 - - - - - - -id -error_tag - - -12 - - -1 -2 -67893 - - - - - - -id -error_message - - -12 - - -1 -2 -67893 - - - - - - -id -full_error_message - - -12 - - -1 -2 -67893 - - - - - - -id -location - - -12 - - -1 -2 -67893 - - - - - - -severity -id - - -12 - - -2 -3 -10 - - -6262 -6263 -10 - - - - - - -severity -error_tag - - -12 - - -1 -2 -10 - - -6 -7 -10 - - - - - - -severity -error_message - - -12 - - -1 -2 -10 - - -8 -9 -10 - - - - - - -severity -full_error_message - - -12 - - -2 -3 -10 - - -5422 -5423 -10 - - - - - - -severity -location - - -12 - - -2 -3 -10 - - -9 -10 -10 - - - - - - -error_tag -id - - -12 - - -1 -2 -10 - - -2 -3 -21 - - -5 -6 -10 - - -417 -418 -10 - - -841 -842 -10 - - -4996 -4997 -10 - - - - - - -error_tag -severity - - -12 - - -1 -2 -75 - - - - - - -error_tag -error_message - - -12 - - -1 -2 -65 - - -3 -4 -10 - - - - - - -error_tag -full_error_message - - -12 - - -1 -2 -21 - - -2 -3 -21 - - -5 -6 -10 - - -417 -418 -10 - - -4996 -4997 -10 - - - - - - -error_tag -location - - -12 - - -1 -2 -43 - - -2 -3 -21 - - -5 -6 -10 - - - - - - -error_message -id - - -12 - - -1 -2 -10 - - -2 -3 -21 - - -5 -6 -10 - - -10 -11 -10 - - -75 -76 -10 - - -332 -333 -10 - - -841 -842 -10 - - -4996 -4997 -10 - - - - - - -error_message -severity - - -12 - - -1 -2 -97 - - - - - - -error_message -error_tag - - -12 - - -1 -2 -97 - - - - - - -error_message -full_error_message - - -12 - - -1 -2 -21 - - -2 -3 -21 - - -5 -6 -10 - - -10 -11 -10 - - -75 -76 -10 - - -332 -333 -10 - - -4996 -4997 -10 - - - - - - -error_message -location - - -12 - - -1 -2 -65 - - -2 -3 -21 - - -5 -6 -10 - - - - - - -full_error_message -id - - -12 - - -1 -2 -58778 - - -841 -842 -10 - - - - - - -full_error_message -severity - - -12 - - -1 -2 -58789 - - - - - - -full_error_message -error_tag - - -12 - - -1 -2 -58789 - - - - - - -full_error_message -error_message - - -12 - - -1 -2 -58789 - - - - - - -full_error_message -location - - -12 - - -1 -2 -58789 - - - - - - -location -id - - -12 - - -1 -2 -108 - - -6254 -6255 -10 - - - - - - -location -severity - - -12 - - -1 -2 -119 - - - - - - -location -error_tag - - -12 - - -1 -2 -108 - - -3 -4 -10 - - - - - - -location -error_message - - -12 - - -1 -2 -108 - - -5 -6 -10 - - - - - - -location -full_error_message - - -12 - - -1 -2 -108 - - -5414 -5415 -10 - - - - - - - - -files -59320 - - -id -59320 - - -name -59320 - - - - -id -name - - -12 - - -1 -2 -59320 - - - - - - -name -id - - -12 - - -1 -2 -59320 - - - - - - - - -folders -10817 - - -id -10817 - - -name -10817 - - - - -id -name - - -12 - - -1 -2 -10817 - - - - - - -name -id - - -12 - - -1 -2 -10817 - - - - - - - - -containerparent -70115 - - -parent -10817 - - -child -70115 - - - - -parent -child - - -12 - - -1 -2 -4931 - - -2 -3 -1387 - - -3 -4 -606 - - -4 -6 -997 - - -6 -10 -802 - - -10 -14 -856 - - -14 -30 -823 - - -30 -153 -411 - - - - - - -child -parent - - -12 - - -1 -2 -70115 - - - - - - - - -fileannotations -5090321 - - -id -4769 - - -kind -21 - - -name -53987 - - -value -44124 - - - - -id -kind - - -12 - - -1 -2 -130 - - -2 -3 -4638 - - - - - - -id -name - - -12 - - -1 -100 -357 - - -111 -222 -357 - - -224 -290 -357 - - -295 -448 -357 - - -448 -527 -357 - - -533 -623 -390 - - -623 -713 -357 - - -726 -901 -357 - - -901 -931 -75 - - -933 -934 -1365 - - -1080 -1671 -357 - - -1693 -2286 -75 - - - - - - -id -value - - -12 - - -1 -112 -357 - - -117 -272 -357 - - -272 -360 -357 - - -379 -633 -357 - - -634 -737 -357 - - -737 -952 -357 - - -952 -1069 -357 - - -1083 -1498 -249 - - -1498 -1499 -1365 - - -1501 -1871 -357 - - -1968 -4072 -292 - - - - - - -kind -id - - -12 - - -428 -429 -10 - - -440 -441 -10 - - - - - - -kind -name - - -12 - - -2 -3 -10 - - -4979 -4980 -10 - - - - - - -kind -value - - -12 - - -1 -2 -10 - - -4071 -4072 -10 - - - - - - -name -id - - -12 - - -1 -2 -8822 - - -2 -3 -5961 - - -3 -6 -4465 - - -6 -8 -4400 - - -8 -14 -4357 - - -14 -18 -3869 - - -18 -21 -4194 - - -21 -34 -4346 - - -34 -128 -4324 - - -129 -236 -4107 - - -236 -395 -4064 - - -395 -440 -1073 - - - - - - -name -kind - - -12 - - -1 -2 -53987 - - - - - - -name -value - - -12 - - -1 -2 -9863 - - -2 -3 -7955 - - -3 -4 -2460 - - -4 -6 -3912 - - -6 -10 -4823 - - -10 -14 -3446 - - -14 -18 -4443 - - -18 -23 -4151 - - -23 -44 -4346 - - -44 -97 -4107 - - -97 -405 -4053 - - -421 -1907 -422 - - - - - - -value -id - - -12 - - -1 -2 -6817 - - -2 -5 -2146 - - -5 -8 -3197 - - -8 -21 -3392 - - -21 -23 -2438 - - -23 -25 -3977 - - -25 -40 -3197 - - -40 -195 -3479 - - -195 -207 -3468 - - -207 -273 -3620 - - -273 -327 -3327 - - -328 -407 -3793 - - -407 -441 -1268 - - - - - - -value -kind - - -12 - - -1 -2 -44113 - - -2 -3 -10 - - - - - - -value -name - - -12 - - -1 -2 -6839 - - -2 -5 -2482 - - -5 -8 -3349 - - -8 -16 -3457 - - -16 -18 -2980 - - -18 -21 -3696 - - -21 -31 -3836 - - -31 -41 -3490 - - -41 -54 -3490 - - -54 -80 -3370 - - -80 -108 -3316 - - -108 -130 -3360 - - -130 -149 -455 - - - - - - - - -inmacroexpansion -60947411 - - -id -15711684 - - -inv -2534941 - - - - -id -inv - - -12 - - -1 -2 -3622961 - - -2 -3 -2447710 - - -3 -4 -1901765 - - -4 -5 -1934999 - - -5 -6 -1869000 - - -6 -7 -969866 - - -7 -8 -1533539 - - -8 -11 -1256082 - - -11 -6193 -175759 - - - - - - -inv -id - - -12 - - -1 -2 -617221 - - -2 -3 -370194 - - -3 -4 -158077 - - -4 -5 -257870 - - -5 -7 -184829 - - -7 -9 -150858 - - -9 -12 -222012 - - -12 -22 -203086 - - -22 -45 -191643 - - -45 -153127 -179147 - - - - - - - - -affectedbymacroexpansion -35536226 - - -id -4085077 - - -inv -3283853 - - - - -id -inv - - -12 - - -1 -2 -1342436 - - -2 -3 -719533 - - -3 -4 -683055 - - -4 -6 -321085 - - -6 -10 -313623 - - -10 -24 -308123 - - -24 -64 -310009 - - -64 -9803 -87208 - - - - - - -inv -id - - -12 - - -1 -2 -253292 - - -2 -3 -210096 - - -3 -4 -202616 - - -4 -5 -258141 - - -5 -6 -301644 - - -6 -7 -247926 - - -7 -8 -231166 - - -8 -9 -228049 - - -9 -10 -182555 - - -10 -12 -285738 - - -12 -16 -297490 - - -16 -23 -275437 - - -23 -60 -249014 - - -60 -526 -60681 - - - - - - - - -macroinvocations -34675701 - - -id -34675701 - - -macro_id -80282 - - -location -752316 - - -kind -21 - - - - -id -macro_id - - -12 - - -1 -2 -34675701 - - - - - - -id -location - - -12 - - -1 -2 -34675701 - - - - - - -id -kind - - -12 - - -1 -2 -34675701 - - - - - - -macro_id -id - - -12 - - -1 -2 -17136 - - -2 -3 -16778 - - -3 -4 -3761 - - -4 -6 -7034 - - -6 -11 -7392 - - -11 -21 -6405 - - -21 -47 -6188 - - -47 -151 -6069 - - -151 -1013 -6026 - - -1014 -196742 -3490 - - - - - - -macro_id -location - - -12 - - -1 -2 -42715 - - -2 -3 -10621 - - -3 -4 -5278 - - -4 -6 -6893 - - -6 -13 -6644 - - -13 -66 -6037 - - -66 -3614 -2091 - - - - - - -macro_id -kind - - -12 - - -1 -2 -74212 - - -2 -3 -6069 - - - - - - -location -id - - -12 - - -1 -2 -285069 - - -2 -3 -194240 - - -3 -4 -45143 - - -4 -5 -55916 - - -5 -9 -68457 - - -9 -26 -60523 - - -26 -257817 -42964 - - - - - - -location -macro_id - - -12 - - -1 -2 -704181 - - -2 -354 -48134 - - - - - - -location -kind - - -12 - - -1 -2 -752316 - - - - - - -kind -id - - -12 - - -21794 -21795 -10 - - -3177447 -3177448 -10 - - - - - - -kind -macro_id - - -12 - - -2221 -2222 -10 - - -5746 -5747 -10 - - - - - - -kind -location - - -12 - - -6578 -6579 -10 - - -62832 -62833 -10 - - - - - - - - -macroparent -31212468 - - -id -31212468 - - -parent_id -24288060 - - - - -id -parent_id - - -12 - - -1 -2 -31212468 - - - - - - -parent_id -id - - -12 - - -1 -2 -18677382 - - -2 -3 -4783954 - - -3 -88 -826723 - - - - - - - - -macrolocationbind -4019158 - - -id -2802505 - - -location -2006328 - - - - -id -location - - -12 - - -1 -2 -2201458 - - -2 -3 -339388 - - -3 -7 -231860 - - -7 -57 -29796 - - - - - - -location -id - - -12 - - -1 -2 -1604130 - - -2 -3 -171086 - - -3 -8 -155542 - - -8 -723 -75567 - - - - - - - - -macro_argument_unexpanded -91317451 - - -invocation -26939874 - - -argument_index -715 - - -text -309012 - - - - -invocation -argument_index - - -12 - - -1 -2 -7463526 - - -2 -3 -11300240 - - -3 -4 -6167062 - - -4 -67 -2009044 - - - - - - -invocation -text - - -12 - - -1 -2 -7530509 - - -2 -3 -11447007 - - -3 -4 -6003116 - - -4 -67 -1959240 - - - - - - -argument_index -invocation - - -12 - - -50779 -50780 -628 - - -50981 -185359 -54 - - -754342 -2485521 -32 - - - - - - -argument_index -text - - -12 - - -2 -3 -628 - - -13 -1004 -54 - - -6629 -19723 -32 - - - - - - -text -invocation - - -12 - - -1 -2 -37588 - - -2 -3 -61759 - - -3 -4 -14252 - - -4 -5 -41761 - - -5 -8 -25416 - - -8 -12 -15466 - - -12 -16 -20918 - - -16 -23 -25709 - - -23 -43 -23205 - - -43 -154 -23216 - - -154 -566476 -19715 - - - - - - -text -argument_index - - -12 - - -1 -2 -223418 - - -2 -3 -75415 - - -3 -9 -10177 - - - - - - - - -macro_argument_expanded -91317451 - - -invocation -26939874 - - -argument_index -715 - - -text -187228 - - - - -invocation -argument_index - - -12 - - -1 -2 -7463526 - - -2 -3 -11300240 - - -3 -4 -6167062 - - -4 -67 -2009044 - - - - - - -invocation -text - - -12 - - -1 -2 -10915238 - - -2 -3 -9757326 - - -3 -4 -5190905 - - -4 -9 -1076404 - - - - - - -argument_index -invocation - - -12 - - -50779 -50780 -628 - - -50981 -185359 -54 - - -754342 -2485521 -32 - - - - - - -argument_index -text - - -12 - - -1 -2 -617 - - -2 -76 -54 - - -869 -13996 -43 - - - - - - -text -invocation - - -12 - - -1 -2 -22717 - - -2 -3 -38694 - - -3 -4 -6449 - - -4 -5 -15293 - - -5 -6 -3468 - - -6 -7 -21883 - - -7 -9 -14599 - - -9 -15 -16225 - - -15 -31 -14914 - - -31 -97 -14198 - - -97 -559 -14057 - - -560 -1126278 -4725 - - - - - - -text -argument_index - - -12 - - -1 -2 -94513 - - -2 -3 -78559 - - -3 -6 -14079 - - -6 -66 -75 - - - - - - - - -functions -3658482 - - -id -3658482 - - -name -292298 - - -kind -75 - - - - -id -name - - -12 - - -1 -2 -3658482 - - - - - - -id -kind - - -12 - - -1 -2 -3658482 - - - - - - -name -id - - -12 - - -1 -2 -195541 - - -2 -3 -29091 - - -3 -5 -26912 - - -5 -12 -21948 - - -12 -123481 -18805 - - - - - - -name -kind - - -12 - - -1 -2 -290304 - - -2 -3 -1994 - - - - - - -kind -id - - -12 - - -32 -33 -10 - - -479 -480 -10 - - -2829 -2830 -10 - - -6206 -6207 -10 - - -66392 -66393 -10 - - -114718 -114719 -10 - - -146882 -146883 -10 - - - - - - -kind -name - - -12 - - -11 -12 -10 - - -42 -43 -10 - - -230 -231 -10 - - -1495 -1496 -10 - - -2829 -2830 -10 - - -3603 -3604 -10 - - -18942 -18943 -10 - - - - - - - - -function_entry_point -996664 - - -id -993781 - - -entry_point -996664 - - - - -id -entry_point - - -12 - - -1 -2 -991169 - - -2 -9 -2612 - - - - - - -entry_point -id - - -12 - - -1 -2 -996664 - - - - - - - - -function_return_type -3668529 - - -id -3658016 - - -return_type -1011394 - - - - -id -return_type - - -12 - - -1 -2 -3647990 - - -2 -6 -10025 - - - - - - -return_type -id - - -12 - - -1 -2 -295658 - - -2 -3 -654745 - - -3 -105613 -60989 - - - - - - - - -coroutine -2 - - -function -2 - - -traits -2 - - -handle -2 - - -promise -2 - - - - -function -traits - - -12 - - -1 -2 -2 - - - - - - -function -handle - - -12 - - -1 -2 -2 - - - - - - -function -promise - - -12 - - -1 -2 -2 - - - - - - -traits -function - - -12 - - -1 -2 -2 - - - - - - -traits -handle - - -12 - - -1 -2 -2 - - - - - - -traits -promise - - -12 - - -1 -2 -2 - - - - - - -handle -function - - -12 - - -1 -2 -2 - - - - - - -handle -traits - - -12 - - -1 -2 -2 - - - - - - -handle -promise - - -12 - - -1 -2 -2 - - - - - - -promise -function - - -12 - - -1 -2 -2 - - - - - - -promise -traits - - -12 - - -1 -2 -2 - - - - - - -promise -handle - - -12 - - -1 -2 -2 - - - - - - - - -coroutine_new -2 - - -function -2 - - -new -1 - - - - -function -new - - -12 - - -1 -2 -2 - - - - - - -new -function - - -12 - - -2 -3 -1 - - - - - - - - -coroutine_delete -2 - - -function -2 - - -delete -1 - - - - -function -delete - - -12 - - -1 -2 -2 - - - - - - -delete -function - - -12 - - -2 -3 -1 - - - - - - - - -purefunctions -20715 - - -id -20715 - - - - - -function_deleted -55526 - - -id -55526 - - - - - -function_defaulted -12778 - - -id -12778 - - - - - -member_function_this_type -517224 - - -id -517224 - - -this_type -169365 - - - - -id -this_type - - -12 - - -1 -2 -517224 - - - - - - -this_type -id - - -12 - - -1 -2 -61813 - - -2 -3 -44037 - - -3 -4 -22035 - - -4 -5 -14838 - - -5 -7 -13526 - - -7 -36 -12724 - - -40 -87 -390 - - - - - - - - -fun_decls -3733464 - - -id -3730234 - - -function -3566244 - - -type_id -998474 - - -name -261115 - - -location -786132 - - - - -id -function - - -12 - - -1 -2 -3730234 - - - - - - -id -type_id - - -12 - - -1 -2 -3727286 - - -2 -4 -2948 - - - - - - -id -name - - -12 - - -1 -2 -3730234 - - - - - - -id -location - - -12 - - -1 -2 -3730234 - - - - - - -function -id - - -12 - - -1 -2 -3431649 - - -2 -9 -134595 - - - - - - -function -type_id - - -12 - - -1 -2 -3549780 - - -2 -6 -16464 - - - - - - -function -name - - -12 - - -1 -2 -3566244 - - - - - - -function -location - - -12 - - -1 -2 -3479621 - - -2 -9 -86623 - - - - - - -type_id -id - - -12 - - -1 -2 -277048 - - -2 -3 -653141 - - -3 -110973 -68283 - - - - - - -type_id -function - - -12 - - -1 -2 -288743 - - -2 -3 -649532 - - -3 -104729 -60198 - - - - - - -type_id -name - - -12 - - -1 -2 -932715 - - -2 -8223 -65758 - - - - - - -type_id -location - - -12 - - -1 -2 -902215 - - -2 -6 -79209 - - -6 -24198 -17049 - - - - - - -name -id - - -12 - - -1 -2 -154159 - - -2 -3 -30023 - - -3 -4 -16344 - - -4 -6 -20062 - - -6 -13 -20929 - - -13 -9944 -19585 - - -123729 -123730 -10 - - - - - - -name -function - - -12 - - -1 -2 -164672 - - -2 -3 -29264 - - -3 -4 -14827 - - -4 -7 -22349 - - -7 -23 -19737 - - -23 -123465 -10264 - - - - - - -name -type_id - - -12 - - -1 -2 -228903 - - -2 -5 -20669 - - -5 -63247 -11543 - - - - - - -name -location - - -12 - - -1 -2 -168477 - - -2 -3 -43528 - - -3 -4 -16409 - - -4 -8 -20897 - - -8 -8921 -11803 - - - - - - -location -id - - -12 - - -1 -2 -516530 - - -2 -3 -130379 - - -3 -4 -50681 - - -4 -13 -61358 - - -13 -3043 -27183 - - - - - - -location -function - - -12 - - -1 -2 -531281 - - -2 -3 -143190 - - -3 -7 -65780 - - -7 -3043 -45880 - - - - - - -location -type_id - - -12 - - -1 -2 -681604 - - -2 -3 -62355 - - -3 -1522 -42173 - - - - - - -location -name - - -12 - - -1 -2 -742691 - - -2 -134 -43441 - - - - - - - - -fun_def -1230856 - - -id -1230856 - - - - - -fun_specialized -6411 - - -id -6411 - - - - - -fun_implicit -14 - - -id -14 - - - - - -fun_decl_specifiers -485928 - - -id -261005 - - -name -6 - - - - -id -name - - -12 - - -1 -2 -69347 - - -2 -3 -158393 - - -3 -4 -33264 - - - - - - -name -id - - -12 - - -24036 -24037 -1 - - -34427 -34428 -1 - - -79541 -79542 -1 - - -160143 -160144 -1 - - - - - - - - -fun_decl_throws -7 - - -fun_decl -7 - - -index -1 - - -type_id -2 - - - - -fun_decl -index - - -12 - - -1 -2 -7 - - - - - - -fun_decl -type_id - - -12 - - -1 -2 -7 - - - - - - -index -fun_decl - - -12 - - -7 -8 -1 - - - - - - -index -type_id - - -12 - - -2 -3 -1 - - - - - - -type_id -fun_decl - - -12 - - -1 -2 -1 - - -6 -7 -1 - - - - - - -type_id -index - - -12 - - -1 -2 -2 - - - - - - - - -fun_decl_empty_throws -1620964 - - -fun_decl -1620964 - - - - - -fun_decl_noexcept -32527 - - -fun_decl -31746 - - -constant -32407 - - - - -fun_decl -constant - - -12 - - -1 -2 -30966 - - -2 -3 -780 - - - - - - -constant -fun_decl - - -12 - - -1 -2 -32288 - - -2 -3 -119 - - - - - - - - -fun_decl_empty_noexcept -401889 - - -fun_decl -401889 - - - - - -fun_decl_typedef_type -173 - - -fun_decl -173 - - -typedeftype_id -86 - - - - -fun_decl -typedeftype_id - - -12 - - -1 -2 -173 - - - - - - -typedeftype_id -fun_decl - - -12 - - -2 -3 -86 - - - - - - - - -param_decl_bind -4596444 - - -id -4596444 - - -index -693 - - -fun_decl -3035277 - - - - -id -index - - -12 - - -1 -2 -4596444 - - - - - - -id -fun_decl - - -12 - - -1 -2 -4596444 - - - - - - -index -id - - -12 - - -1 -2 -346 - - -4 -5 -140 - - -6 -118 -54 - - -191 -616 -54 - - -886 -5115 -54 - - -14149 -280041 -43 - - - - - - -index -fun_decl - - -12 - - -1 -2 -346 - - -4 -5 -140 - - -6 -118 -54 - - -191 -616 -54 - - -886 -5115 -54 - - -14149 -280041 -43 - - - - - - -fun_decl -id - - -12 - - -1 -2 -2169165 - - -2 -3 -472882 - - -3 -4 -239871 - - -4 -65 -153357 - - - - - - -fun_decl -index - - -12 - - -1 -2 -2169165 - - -2 -3 -472882 - - -3 -4 -239871 - - -4 -65 -153357 - - - - - - - - -var_decls -5305568 - - -id -5296821 - - -variable -5071603 - - -type_id -1983812 - - -name -124829 - - -location -1218002 - - - - -id -variable - - -12 - - -1 -2 -5296821 - - - - - - -id -type_id - - -12 - - -1 -2 -5288258 - - -2 -4 -8562 - - - - - - -id -name - - -12 - - -1 -2 -5296821 - - - - - - -id -location - - -12 - - -1 -2 -5296777 - - -2 -3 -43 - - - - - - -variable -id - - -12 - - -1 -2 -4886293 - - -2 -9 -185309 - - - - - - -variable -type_id - - -12 - - -1 -2 -5036670 - - -2 -7 -34933 - - - - - - -variable -name - - -12 - - -1 -2 -5054239 - - -2 -3 -17363 - - - - - - -variable -location - - -12 - - -1 -2 -4964657 - - -2 -9 -106945 - - - - - - -type_id -id - - -12 - - -1 -2 -1561936 - - -2 -3 -226215 - - -3 -11 -155091 - - -11 -5924 -40569 - - - - - - -type_id -variable - - -12 - - -1 -2 -1585846 - - -2 -3 -217088 - - -3 -13 -149325 - - -13 -5424 -31551 - - - - - - -type_id -name - - -12 - - -1 -2 -1811043 - - -2 -5 -149422 - - -5 -772 -23346 - - - - - - -type_id -location - - -12 - - -1 -2 -1737523 - - -2 -4 -152685 - - -4 -3608 -93603 - - - - - - -name -id - - -12 - - -1 -2 -51483 - - -2 -3 -19054 - - -3 -4 -10784 - - -4 -5 -7597 - - -5 -8 -10394 - - -8 -15 -9397 - - -15 -47 -9418 - - -47 -165594 -6698 - - - - - - -name -variable - - -12 - - -1 -2 -54269 - - -2 -3 -18610 - - -3 -4 -11673 - - -4 -6 -11066 - - -6 -11 -10611 - - -11 -27 -9375 - - -27 -164566 -9223 - - - - - - -name -type_id - - -12 - - -1 -2 -75405 - - -2 -3 -16702 - - -3 -4 -8757 - - -4 -7 -10350 - - -7 -27 -9408 - - -27 -125771 -4205 - - - - - - -name -location - - -12 - - -1 -2 -71969 - - -2 -3 -18805 - - -3 -4 -6893 - - -4 -7 -11055 - - -7 -21 -9635 - - -21 -10073 -6470 - - - - - - -location -id - - -12 - - -1 -2 -881958 - - -2 -3 -147406 - - -3 -6 -112104 - - -6 -128414 -76532 - - - - - - -location -variable - - -12 - - -1 -2 -930147 - - -2 -3 -113232 - - -3 -6 -101472 - - -6 -128188 -73150 - - - - - - -location -type_id - - -12 - - -1 -2 -1043010 - - -2 -3 -84119 - - -3 -118352 -90871 - - - - - - -location -name - - -12 - - -1 -2 -1209135 - - -2 -52 -8866 - - - - - - - - -var_def -2408907 - - -id -2408907 - - - - - -var_decl_specifiers -309614 - - -id -309614 - - -name -4 - - - - -id -name - - -12 - - -1 -2 -309614 - - - - - - -name -id - - -12 - - -32 -33 -1 - - -38 -39 -1 - - -2971 -2972 -1 - - -306573 -306574 -1 - - - - - - - - -is_structured_binding -10 - - -id -10 - - - - - -type_decls -1316547 - - -id -1316547 - - -type_id -1285169 - - -location -1074107 - - - - -id -type_id - - -12 - - -1 -2 -1316547 - - - - - - -id -location - - -12 - - -1 -2 -1316547 - - - - - - -type_id -id - - -12 - - -1 -2 -1262343 - - -2 -24 -22826 - - - - - - -type_id -location - - -12 - - -1 -2 -1263622 - - -2 -24 -21547 - - - - - - -location -id - - -12 - - -1 -2 -1019295 - - -2 -506 -54811 - - - - - - -location -type_id - - -12 - - -1 -2 -1020758 - - -2 -506 -53348 - - - - - - - - -type_def -926754 - - -id -926754 - - - - - -type_decl_top -265548 - - -type_decl -265548 - - - - - -namespace_decls -135267 - - -id -135267 - - -namespace_id -7587 - - -location -120819 - - -bodylocation -121144 - - - - -id -namespace_id - - -12 - - -1 -2 -135267 - - - - - - -id -location - - -12 - - -1 -2 -135267 - - - - - - -id -bodylocation - - -12 - - -1 -2 -135267 - - - - - - -namespace_id -id - - -12 - - -1 -2 -3576 - - -2 -3 -1073 - - -3 -4 -411 - - -4 -7 -639 - - -7 -13 -585 - - -13 -27 -585 - - -28 -163 -574 - - -172 -3743 -140 - - - - - - -namespace_id -location - - -12 - - -1 -2 -3576 - - -2 -3 -1073 - - -3 -4 -411 - - -4 -7 -639 - - -7 -13 -585 - - -13 -27 -585 - - -28 -163 -574 - - -172 -3743 -140 - - - - - - -namespace_id -bodylocation - - -12 - - -1 -2 -3576 - - -2 -3 -1073 - - -3 -4 -411 - - -4 -7 -639 - - -7 -13 -585 - - -13 -27 -585 - - -28 -163 -574 - - -172 -3742 -140 - - - - - - -location -id - - -12 - - -1 -2 -112538 - - -2 -8 -8280 - - - - - - -location -namespace_id - - -12 - - -1 -2 -112538 - - -2 -8 -8280 - - - - - - -location -bodylocation - - -12 - - -1 -2 -120082 - - -2 -3 -737 - - - - - - -bodylocation -id - - -12 - - -1 -2 -113221 - - -2 -11 -7923 - - - - - - -bodylocation -namespace_id - - -12 - - -1 -2 -113221 - - -2 -9 -7923 - - - - - - -bodylocation -location - - -12 - - -1 -2 -120754 - - -2 -5 -390 - - - - - - - - -usings -287692 - - -id -287692 - - -element_id -45522 - - -location -23574 - - - - -id -element_id - - -12 - - -1 -2 -287692 - - - - - - -id -location - - -12 - - -1 -2 -287692 - - - - - - -element_id -id - - -12 - - -1 -2 -38596 - - -2 -4 -3706 - - -4 -127 -3219 - - - - - - -element_id -location - - -12 - - -1 -2 -38596 - - -2 -4 -3706 - - -4 -127 -3219 - - - - - - -location -id - - -12 - - -1 -2 -17851 - - -2 -3 -2200 - - -3 -18 -1777 - - -18 -382 -1745 - - - - - - -location -element_id - - -12 - - -1 -2 -17851 - - -2 -3 -2200 - - -3 -18 -1777 - - -18 -382 -1745 - - - - - - - - -using_container -452397 - - -parent -11022 - - -child -287692 - - - - -parent -child - - -12 - - -1 -2 -3154 - - -2 -4 -932 - - -4 -6 -411 - - -6 -7 -2698 - - -7 -17 -921 - - -19 -143 -758 - - -178 -179 -1246 - - -179 -202 -834 - - -202 -501 -65 - - - - - - -child -parent - - -12 - - -1 -2 -212991 - - -2 -3 -49782 - - -3 -11 -22869 - - -13 -47 -2048 - - - - - - - - -static_asserts -130452 - - -id -130452 - - -condition -130452 - - -message -29660 - - -location -16694 - - -enclosing -1721 - - - - -id -condition - - -12 - - -1 -2 -130452 - - - - - - -id -message - - -12 - - -1 -2 -130452 - - - - - - -id -location - - -12 - - -1 -2 -130452 - - - - - - -id -enclosing - - -12 - - -1 -2 -130452 - - - - - - -condition -id - - -12 - - -1 -2 -130452 - - - - - - -condition -message - - -12 - - -1 -2 -130452 - - - - - - -condition -location - - -12 - - -1 -2 -130452 - - - - - - -condition -enclosing - - -12 - - -1 -2 -130452 - - - - - - -message -id - - -12 - - -1 -2 -22073 - - -2 -3 -422 - - -3 -4 -2825 - - -4 -11 -1442 - - -12 -17 -2345 - - -17 -513 -552 - - - - - - -message -condition - - -12 - - -1 -2 -22073 - - -2 -3 -422 - - -3 -4 -2825 - - -4 -11 -1442 - - -12 -17 -2345 - - -17 -513 -552 - - - - - - -message -location - - -12 - - -1 -2 -27510 - - -2 -33 -2150 - - - - - - -message -enclosing - - -12 - - -1 -2 -23476 - - -2 -3 -181 - - -3 -4 -2650 - - -4 -11 -1299 - - -12 -21 -2052 - - - - - - -location -id - - -12 - - -1 -2 -2897 - - -2 -3 -2760 - - -3 -4 -1325 - - -5 -6 -3722 - - -6 -7 -175 - - -14 -15 -2033 - - -16 -17 -38 - - -17 -18 -3397 - - -19 -52 -344 - - - - - - -location -condition - - -12 - - -1 -2 -2897 - - -2 -3 -2760 - - -3 -4 -1325 - - -5 -6 -3722 - - -6 -7 -175 - - -14 -15 -2033 - - -16 -17 -38 - - -17 -18 -3397 - - -19 -52 -344 - - - - - - -location -message - - -12 - - -1 -2 -4410 - - -2 -3 -5976 - - -3 -4 -6119 - - -4 -7 -188 - - - - - - -location -enclosing - - -12 - - -1 -2 -3436 - - -2 -3 -6184 - - -3 -4 -1123 - - -4 -5 -3709 - - -5 -6 -188 - - -13 -14 -2033 - - -16 -21 -19 - - - - - - -enclosing -id - - -12 - - -1 -2 -1169 - - -2 -3 -129 - - -3 -7 -136 - - -9 -108 -136 - - -170 -347 -129 - - -348 -10697 -19 - - - - - - -enclosing -condition - - -12 - - -1 -2 -1169 - - -2 -3 -129 - - -3 -7 -136 - - -9 -108 -136 - - -170 -347 -129 - - -348 -10697 -19 - - - - - - -enclosing -message - - -12 - - -1 -2 -1325 - - -2 -5 -136 - - -5 -180 -129 - - -211 -2870 -129 - - - - - - -enclosing -location - - -12 - - -1 -2 -1312 - - -2 -5 -149 - - -5 -180 -129 - - -211 -1886 -129 - - - - - - - - -params -4589800 - - -id -4572935 - - -function -3007660 - - -index -693 - - -type_id -1834606 - - - - -id -function - - -12 - - -1 -2 -4572273 - - -2 -69 -661 - - - - - - -id -index - - -12 - - -1 -2 -4572935 - - - - - - -id -type_id - - -12 - - -1 -2 -4558064 - - -2 -4 -14870 - - - - - - -function -id - - -12 - - -1 -2 -2140887 - - -2 -3 -469349 - - -3 -4 -241595 - - -4 -65 -155828 - - - - - - -function -index - - -12 - - -1 -2 -2140887 - - -2 -3 -469349 - - -3 -4 -241595 - - -4 -65 -155828 - - - - - - -function -type_id - - -12 - - -1 -2 -2255896 - - -2 -3 -465458 - - -3 -5 -251350 - - -5 -20 -34954 - - - - - - -index -id - - -12 - - -1 -2 -346 - - -4 -5 -140 - - -6 -118 -54 - - -191 -616 -54 - - -884 -5095 -54 - - -14377 -277321 -43 - - - - - - -index -function - - -12 - - -1 -2 -346 - - -4 -5 -140 - - -6 -118 -54 - - -191 -616 -54 - - -884 -5095 -54 - - -14377 -277493 -43 - - - - - - -index -type_id - - -12 - - -1 -2 -346 - - -2 -3 -140 - - -4 -37 -54 - - -38 -104 -54 - - -171 -1179 -54 - - -2870 -151119 -43 - - - - - - -type_id -id - - -12 - - -1 -2 -1486737 - - -2 -3 -184518 - - -3 -14 -137781 - - -14 -5175 -25568 - - - - - - -type_id -function - - -12 - - -1 -2 -1506355 - - -2 -3 -177679 - - -3 -23 -138074 - - -23 -4690 -12497 - - - - - - -type_id -index - - -12 - - -1 -2 -1724311 - - -2 -65 -110294 - - - - - - - - -overrides -158806 - - -new -124352 - - -old -15440 - - - - -new -old - - -12 - - -1 -2 -89904 - - -2 -3 -34441 - - -3 -4 -6 - - - - - - -old -new - - -12 - - -1 -2 -8113 - - -2 -3 -2013 - - -3 -4 -870 - - -4 -5 -1260 - - -5 -10 -1227 - - -10 -43 -1162 - - -44 -218 -792 - - - - - - - - -membervariables -308142 - - -id -300035 - - -type_id -56417 - - -name -94717 - - - - -id -type_id - - -12 - - -1 -2 -292000 - - -2 -5 -8035 - - - - - - -id -name - - -12 - - -1 -2 -300035 - - - - - - -type_id -id - - -12 - - -1 -2 -40463 - - -2 -3 -7041 - - -3 -6 -4586 - - -6 -423 -4235 - - -460 -3062 -90 - - - - - - -type_id -name - - -12 - - -1 -2 -44789 - - -2 -3 -5326 - - -3 -9 -4462 - - -9 -1352 -1838 - - - - - - -name -id - - -12 - - -1 -2 -63303 - - -2 -3 -16272 - - -3 -5 -8288 - - -5 -1294 -6853 - - - - - - -name -type_id - - -12 - - -1 -2 -75353 - - -2 -3 -12998 - - -3 -421 -6366 - - - - - - - - -globalvariables -301151 - - -id -301143 - - -type_id -1460 - - -name -295146 - - - - -id -type_id - - -12 - - -1 -2 -301135 - - -2 -3 -8 - - - - - - -id -name - - -12 - - -1 -2 -301143 - - - - - - -type_id -id - - -12 - - -1 -2 -1013 - - -2 -3 -167 - - -3 -7 -118 - - -7 -64 -110 - - -66 -169462 -52 - - - - - - -type_id -name - - -12 - - -1 -2 -1049 - - -2 -3 -141 - - -3 -7 -117 - - -7 -102 -110 - - -105 -168513 -43 - - - - - - -name -id - - -12 - - -1 -2 -291383 - - -2 -33 -3763 - - - - - - -name -type_id - - -12 - - -1 -2 -294545 - - -2 -12 -601 - - - - - - - - -localvariables -520470 - - -id -520392 - - -type_id -47453 - - -name -75119 - - - - -id -type_id - - -12 - - -1 -2 -520314 - - -2 -3 -77 - - - - - - -id -name - - -12 - - -1 -2 -520392 - - - - - - -type_id -id - - -12 - - -1 -2 -26432 - - -2 -3 -6749 - - -3 -4 -2851 - - -4 -6 -4053 - - -6 -13 -3800 - - -13 -3196 -3559 - - -4920 -4921 -6 - - - - - - -type_id -name - - -12 - - -1 -2 -35643 - - -2 -3 -4865 - - -3 -5 -4261 - - -5 -1158 -2682 - - - - - - -name -id - - -12 - - -1 -2 -42892 - - -2 -3 -12894 - - -3 -4 -5079 - - -4 -7 -6710 - - -7 -31 -5696 - - -31 -6112 -1844 - - - - - - -name -type_id - - -12 - - -1 -2 -63634 - - -2 -3 -6379 - - -3 -819 -5105 - - - - - - - - -autoderivation -19481 - - -var -19481 - - -derivation_type -32 - - - - -var -derivation_type - - -12 - - -1 -2 -19481 - - - - - - -derivation_type -var - - -12 - - -20 -21 -6 - - -39 -40 -6 - - -161 -162 -6 - - -475 -476 -6 - - -2304 -2305 -6 - - - - - - - - -enumconstants -93691 - - -id -93691 - - -parent -7996 - - -index -7567 - - -type_id -7853 - - -name -72787 - - -location -75749 - - - - -id -parent - - -12 - - -1 -2 -93691 - - - - - - -id -index - - -12 - - -1 -2 -93691 - - - - - - -id -type_id - - -12 - - -1 -2 -93691 - - - - - - -id -name - - -12 - - -1 -2 -93691 - - - - - - -id -location - - -12 - - -1 -2 -93691 - - - - - - -parent -id - - -12 - - -1 -2 -1591 - - -2 -3 -818 - - -3 -4 -2448 - - -4 -5 -578 - - -5 -6 -578 - - -6 -9 -727 - - -9 -16 -610 - - -16 -392 -604 - - -426 -1166 -38 - - - - - - -parent -index - - -12 - - -1 -2 -1591 - - -2 -3 -831 - - -3 -4 -2494 - - -4 -5 -571 - - -5 -6 -584 - - -6 -9 -701 - - -9 -17 -623 - - -17 -1166 -597 - - - - - - -parent -type_id - - -12 - - -1 -2 -7255 - - -2 -3 -740 - - - - - - -parent -name - - -12 - - -1 -2 -1591 - - -2 -3 -831 - - -3 -4 -2494 - - -4 -5 -571 - - -5 -6 -584 - - -6 -9 -701 - - -9 -17 -623 - - -17 -1166 -597 - - - - - - -parent -location - - -12 - - -1 -2 -1630 - - -2 -3 -831 - - -3 -4 -2448 - - -4 -5 -578 - - -5 -6 -558 - - -6 -9 -701 - - -9 -16 -610 - - -16 -427 -604 - - -466 -1166 -32 - - - - - - -index -id - - -12 - - -1 -2 -2604 - - -2 -3 -928 - - -3 -4 -922 - - -4 -7 -571 - - -7 -10 -688 - - -10 -11 -350 - - -11 -12 -552 - - -12 -30 -597 - - -30 -1253 -350 - - - - - - -index -parent - - -12 - - -1 -2 -2604 - - -2 -3 -928 - - -3 -4 -922 - - -4 -7 -571 - - -7 -9 -675 - - -9 -11 -363 - - -11 -12 -552 - - -12 -29 -597 - - -29 -1232 -350 - - - - - - -index -type_id - - -12 - - -1 -2 -2604 - - -2 -3 -928 - - -3 -4 -922 - - -4 -7 -571 - - -7 -9 -675 - - -9 -11 -363 - - -11 -12 -552 - - -12 -28 -597 - - -28 -1210 -350 - - - - - - -index -name - - -12 - - -1 -2 -2604 - - -2 -3 -928 - - -3 -4 -922 - - -4 -7 -571 - - -7 -10 -688 - - -10 -11 -350 - - -11 -12 -552 - - -12 -28 -597 - - -28 -674 -350 - - - - - - -index -location - - -12 - - -1 -2 -2604 - - -2 -3 -928 - - -3 -4 -922 - - -4 -7 -571 - - -7 -10 -688 - - -10 -11 -350 - - -11 -12 -552 - - -12 -28 -597 - - -28 -774 -350 - - - - - - -type_id -id - - -12 - - -1 -2 -1591 - - -2 -3 -799 - - -3 -4 -2422 - - -4 -5 -558 - - -5 -6 -558 - - -6 -9 -701 - - -9 -16 -597 - - -16 -470 -591 - - -479 -1166 -32 - - - - - - -type_id -parent - - -12 - - -1 -2 -7847 - - -137 -138 -6 - - - - - - -type_id -index - - -12 - - -1 -2 -1591 - - -2 -3 -811 - - -3 -4 -2468 - - -4 -5 -552 - - -5 -6 -565 - - -6 -9 -675 - - -9 -17 -610 - - -17 -1166 -578 - - - - - - -type_id -name - - -12 - - -1 -2 -1591 - - -2 -3 -811 - - -3 -4 -2468 - - -4 -5 -552 - - -5 -6 -565 - - -6 -9 -675 - - -9 -17 -610 - - -17 -1166 -578 - - - - - - -type_id -location - - -12 - - -1 -2 -1630 - - -2 -3 -811 - - -3 -4 -2422 - - -4 -5 -558 - - -5 -6 -539 - - -6 -9 -675 - - -9 -16 -597 - - -16 -470 -591 - - -621 -1166 -25 - - - - - - -name -id - - -12 - - -1 -2 -65440 - - -2 -3 -6827 - - -3 -239 -519 - - - - - - -name -parent - - -12 - - -1 -2 -66083 - - -2 -3 -6184 - - -3 -239 -519 - - - - - - -name -index - - -12 - - -1 -2 -67772 - - -2 -13 -5014 - - - - - - -name -type_id - - -12 - - -1 -2 -61049 - - -2 -3 -11218 - - -3 -239 -519 - - - - - - -name -location - - -12 - - -1 -2 -70318 - - -2 -23 -2468 - - - - - - -location -id - - -12 - - -1 -2 -70468 - - -2 -229 -5281 - - - - - - -location -parent - - -12 - - -1 -2 -70578 - - -2 -229 -5170 - - - - - - -location -index - - -12 - - -1 -2 -72157 - - -2 -17 -3592 - - - - - - -location -type_id - - -12 - - -1 -2 -65544 - - -2 -3 -9951 - - -3 -229 -253 - - - - - - -location -name - - -12 - - -1 -2 -75580 - - -2 -27 -168 - - - - - - - - -builtintypes -509 - - -id -509 - - -name -509 - - -kind -509 - - -size -75 - - -sign -32 - - -alignment -54 - - - - -id -name - - -12 - - -1 -2 -509 - - - - - - -id -kind - - -12 - - -1 -2 -509 - - - - - - -id -size - - -12 - - -1 -2 -509 - - - - - - -id -sign - - -12 - - -1 -2 -509 - - - - - - -id -alignment - - -12 - - -1 -2 -509 - - - - - - -name -id - - -12 - - -1 -2 -509 - - - - - - -name -kind - - -12 - - -1 -2 -509 - - - - - - -name -size - - -12 - - -1 -2 -509 - - - - - - -name -sign - - -12 - - -1 -2 -509 - - - - - - -name -alignment - - -12 - - -1 -2 -509 - - - - - - -kind -id - - -12 - - -1 -2 -509 - - - - - - -kind -name - - -12 - - -1 -2 -509 - - - - - - -kind -size - - -12 - - -1 -2 -509 - - - - - - -kind -sign - - -12 - - -1 -2 -509 - - - - - - -kind -alignment - - -12 - - -1 -2 -509 - - - - - - -size -id - - -12 - - -1 -2 -10 - - -2 -3 -10 - - -4 -5 -10 - - -7 -8 -10 - - -9 -10 -10 - - -11 -12 -10 - - -13 -14 -10 - - - - - - -size -name - - -12 - - -1 -2 -10 - - -2 -3 -10 - - -4 -5 -10 - - -7 -8 -10 - - -9 -10 -10 - - -11 -12 -10 - - -13 -14 -10 - - - - - - -size -kind - - -12 - - -1 -2 -10 - - -2 -3 -10 - - -4 -5 -10 - - -7 -8 -10 - - -9 -10 -10 - - -11 -12 -10 - - -13 -14 -10 - - - - - - -size -sign - - -12 - - -1 -2 -21 - - -3 -4 -54 - - - - - - -size -alignment - - -12 - - -1 -2 -54 - - -2 -3 -21 - - - - - - -sign -id - - -12 - - -6 -7 -10 - - -12 -13 -10 - - -29 -30 -10 - - - - - - -sign -name - - -12 - - -6 -7 -10 - - -12 -13 -10 - - -29 -30 -10 - - - - - - -sign -kind - - -12 - - -6 -7 -10 - - -12 -13 -10 - - -29 -30 -10 - - - - - - -sign -size - - -12 - - -5 -6 -21 - - -7 -8 -10 - - - - - - -sign -alignment - - -12 - - -5 -6 -32 - - - - - - -alignment -id - - -12 - - -4 -5 -10 - - -8 -9 -10 - - -10 -11 -10 - - -12 -13 -10 - - -13 -14 -10 - - - - - - -alignment -name - - -12 - - -4 -5 -10 - - -8 -9 -10 - - -10 -11 -10 - - -12 -13 -10 - - -13 -14 -10 - - - - - - -alignment -kind - - -12 - - -4 -5 -10 - - -8 -9 -10 - - -10 -11 -10 - - -12 -13 -10 - - -13 -14 -10 - - - - - - -alignment -size - - -12 - - -1 -2 -10 - - -2 -3 -43 - - - - - - -alignment -sign - - -12 - - -3 -4 -54 - - - - - - - - -derivedtypes -4408457 - - -id -4408457 - - -name -2176199 - - -kind -86 - - -type_id -2578132 - - - - -id -name - - -12 - - -1 -2 -4408457 - - - - - - -id -kind - - -12 - - -1 -2 -4408457 - - - - - - -id -type_id - - -12 - - -1 -2 -4408457 - - - - - - -name -id - - -12 - - -1 -2 -1573891 - - -2 -3 -488328 - - -3 -45171 -113980 - - - - - - -name -kind - - -12 - - -1 -2 -2176167 - - -2 -3 -32 - - - - - - -name -type_id - - -12 - - -1 -2 -1574130 - - -2 -3 -488100 - - -3 -45153 -113969 - - - - - - -kind -id - - -12 - - -21 -22 -10 - - -62 -63 -10 - - -2069 -2070 -10 - - -31133 -31134 -10 - - -45223 -45224 -10 - - -61016 -61017 -10 - - -96858 -96859 -10 - - -170348 -170349 -10 - - - - - - -kind -name - - -12 - - -1 -2 -10 - - -13 -14 -10 - - -39 -40 -10 - - -1155 -1156 -10 - - -17432 -17433 -10 - - -40934 -40935 -10 - - -48321 -48322 -10 - - -92888 -92889 -10 - - - - - - -kind -type_id - - -12 - - -12 -13 -10 - - -21 -22 -10 - - -983 -984 -10 - - -31133 -31134 -10 - - -45223 -45224 -10 - - -61016 -61017 -10 - - -96527 -96528 -10 - - -170348 -170349 -10 - - - - - - -type_id -id - - -12 - - -1 -2 -1521486 - - -2 -3 -365026 - - -3 -4 -620527 - - -4 -202 -71091 - - - - - - -type_id -name - - -12 - - -1 -2 -1522689 - - -2 -3 -364874 - - -3 -4 -619476 - - -4 -198 -71091 - - - - - - -type_id -kind - - -12 - - -1 -2 -1523003 - - -2 -3 -366143 - - -3 -4 -619433 - - -4 -7 -69552 - - - - - - - - -pointerishsize -3335520 - - -id -3335520 - - -size -21 - - -alignment -10 - - - - -id -size - - -12 - - -1 -2 -3335520 - - - - - - -id -alignment - - -12 - - -1 -2 -3335520 - - - - - - -size -id - - -12 - - -21 -22 -10 - - -307720 -307721 -10 - - - - - - -size -alignment - - -12 - - -1 -2 -21 - - - - - - -alignment -id - - -12 - - -307741 -307742 -10 - - - - - - -alignment -size - - -12 - - -2 -3 -10 - - - - - - - - -arraysizes -16995 - - -id -16995 - - -num_elements -2135 - - -bytesize -2482 - - -alignment -75 - - - - -id -num_elements - - -12 - - -1 -2 -16995 - - - - - - -id -bytesize - - -12 - - -1 -2 -16995 - - - - - - -id -alignment - - -12 - - -1 -2 -16995 - - - - - - -num_elements -id - - -12 - - -1 -2 -162 - - -2 -3 -1257 - - -3 -4 -75 - - -4 -5 -173 - - -5 -13 -162 - - -13 -25 -162 - - -38 -116 -140 - - - - - - -num_elements -bytesize - - -12 - - -1 -2 -1571 - - -2 -3 -216 - - -3 -4 -119 - - -4 -6 -162 - - -6 -11 -65 - - - - - - -num_elements -alignment - - -12 - - -1 -2 -1571 - - -2 -3 -238 - - -3 -4 -140 - - -4 -7 -162 - - -7 -8 -21 - - - - - - -bytesize -id - - -12 - - -1 -2 -151 - - -2 -3 -1387 - - -3 -4 -108 - - -4 -6 -205 - - -6 -9 -195 - - -9 -18 -205 - - -21 -56 -195 - - -59 -75 -32 - - - - - - -bytesize -num_elements - - -12 - - -1 -2 -1885 - - -2 -3 -346 - - -3 -6 -216 - - -6 -7 -32 - - - - - - -bytesize -alignment - - -12 - - -1 -2 -1929 - - -2 -3 -281 - - -3 -5 -227 - - -5 -7 -43 - - - - - - -alignment -id - - -12 - - -18 -19 -21 - - -33 -34 -10 - - -50 -51 -10 - - -181 -182 -10 - - -407 -408 -10 - - -861 -862 -10 - - - - - - -alignment -num_elements - - -12 - - -4 -5 -10 - - -5 -6 -10 - - -13 -14 -10 - - -16 -17 -10 - - -39 -40 -10 - - -41 -42 -10 - - -190 -191 -10 - - - - - - -alignment -bytesize - - -12 - - -1 -2 -10 - - -2 -3 -10 - - -14 -15 -10 - - -17 -18 -10 - - -41 -42 -10 - - -54 -55 -10 - - -191 -192 -10 - - - - - - - - -typedefbase -1798090 - - -id -1798090 - - -type_id -837313 - - - - -id -type_id - - -12 - - -1 -2 -1798090 - - - - - - -type_id -id - - -12 - - -1 -2 -648849 - - -2 -3 -86937 - - -3 -6 -68695 - - -6 -5503 -32830 - - - - - - - - -decltypes -46454 - - -id -46454 - - -expr -42932 - - -base_type -8530 - - -parentheses_would_change_meaning -21 - - - - -id -expr - - -12 - - -1 -2 -46454 - - - - - - -id -base_type - - -12 - - -1 -2 -46454 - - - - - - -id -parentheses_would_change_meaning - - -12 - - -1 -2 -46454 - - - - - - -expr -id - - -12 - - -1 -2 -39691 - - -2 -4 -3240 - - - - - - -expr -base_type - - -12 - - -1 -2 -39691 - - -2 -4 -3240 - - - - - - -expr -parentheses_would_change_meaning - - -12 - - -1 -2 -42932 - - - - - - -base_type -id - - -12 - - -1 -2 -5755 - - -2 -3 -2492 - - -3 -274 -281 - - - - - - -base_type -expr - - -12 - - -1 -2 -2286 - - -2 -3 -5636 - - -3 -2451 -606 - - - - - - -base_type -parentheses_would_change_meaning - - -12 - - -1 -2 -8530 - - - - - - -parentheses_would_change_meaning -id - - -12 - - -8 -9 -10 - - -1356 -1357 -10 - - - - - - -parentheses_would_change_meaning -expr - - -12 - - -8 -9 -10 - - -3953 -3954 -10 - - - - - - -parentheses_would_change_meaning -base_type - - -12 - - -8 -9 -10 - - -779 -780 -10 - - - - - - - - -usertypes -4144306 - - -id -4144306 - - -name -868886 - - -kind -119 - - - - -id -name - - -12 - - -1 -2 -4144306 - - - - - - -id -kind - - -12 - - -1 -2 -4144306 - - - - - - -name -id - - -12 - - -1 -2 -570463 - - -2 -3 -192539 - - -3 -7 -68500 - - -7 -32725 -37382 - - - - - - -name -kind - - -12 - - -1 -2 -816860 - - -2 -10 -52025 - - - - - - -kind -id - - -12 - - -23 -24 -10 - - -372 -373 -10 - - -776 -777 -10 - - -1938 -1939 -10 - - -4229 -4230 -10 - - -16782 -16783 -10 - - -17797 -17798 -10 - - -20548 -20549 -10 - - -75592 -75593 -10 - - -95191 -95192 -10 - - -149113 -149114 -10 - - - - - - -kind -name - - -12 - - -16 -17 -10 - - -38 -39 -21 - - -418 -419 -10 - - -560 -561 -10 - - -780 -781 -10 - - -2853 -2854 -10 - - -4550 -4551 -10 - - -9138 -9139 -10 - - -11663 -11664 -10 - - -55440 -55441 -10 - - - - - - - - -usertypesize -1370156 - - -id -1370156 - - -size -1463 - - -alignment -86 - - - - -id -size - - -12 - - -1 -2 -1370156 - - - - - - -id -alignment - - -12 - - -1 -2 -1370156 - - - - - - -size -id - - -12 - - -1 -2 -422 - - -2 -3 -195 - - -3 -4 -65 - - -4 -5 -86 - - -5 -8 -119 - - -8 -12 -108 - - -12 -17 -119 - - -19 -38 -119 - - -42 -261 -119 - - -284 -99362 -108 - - - - - - -size -alignment - - -12 - - -1 -2 -1203 - - -2 -3 -173 - - -3 -6 -86 - - - - - - -alignment -id - - -12 - - -1 -2 -10 - - -3 -4 -10 - - -7 -8 -10 - - -50 -51 -10 - - -54 -55 -10 - - -2327 -2328 -10 - - -10108 -10109 -10 - - -113863 -113864 -10 - - - - - - -alignment -size - - -12 - - -1 -2 -21 - - -3 -4 -10 - - -8 -9 -10 - - -12 -13 -10 - - -17 -18 -10 - - -25 -26 -10 - - -106 -107 -10 - - - - - - - - -usertype_final -1312 - - -id -1312 - - - - - -usertype_uuid -4826 - - -id -4826 - - -uuid -4826 - - - - -id -uuid - - -12 - - -1 -2 -4826 - - - - - - -uuid -id - - -12 - - -1 -2 -4826 - - - - - - - - -mangled_name -4141065 - - -id -4141065 - - -mangled_name -478020 - - - - -id -mangled_name - - -12 - - -1 -2 -4141065 - - - - - - -mangled_name -id - - -12 - - -1 -2 -288667 - - -2 -3 -61563 - - -3 -4 -32949 - - -4 -7 -36537 - - -7 -24 -36634 - - -24 -8580 -21666 - - - - - - - - -is_pod_class -582213 - - -id -582213 - - - - - -is_standard_layout_class -1145425 - - -id -1145425 - - - - - -is_complete -1348901 - - -id -1348901 - - - - - -is_class_template -222714 - - -id -222714 - - - - - -class_instantiation -1144049 - - -to -1142499 - - -from -67232 - - - - -to -from - - -12 - - -1 -2 -1141036 - - -2 -4 -1463 - - - - - - -from -to - - -12 - - -1 -2 -19726 - - -2 -3 -11857 - - -3 -4 -6774 - - -4 -5 -4563 - - -5 -7 -5571 - - -7 -11 -5982 - - -11 -20 -5137 - - -20 -84 -5050 - - -84 -4845 -2568 - - - - - - - - -class_template_argument -3000322 - - -type_id -1376323 - - -index -1213 - - -arg_type -850742 - - - - -type_id -index - - -12 - - -1 -2 -560264 - - -2 -3 -428660 - - -3 -4 -242126 - - -4 -7 -121372 - - -7 -113 -23899 - - - - - - -type_id -arg_type - - -12 - - -1 -2 -586190 - - -2 -3 -440746 - - -3 -4 -255425 - - -4 -113 -93960 - - - - - - -index -type_id - - -12 - - -1 -2 -10 - - -2 -3 -769 - - -3 -26 -97 - - -29 -64 -97 - - -69 -435 -97 - - -616 -9358 -97 - - -13712 -123907 -43 - - - - - - -index -arg_type - - -12 - - -1 -2 -10 - - -2 -3 -769 - - -3 -14 -108 - - -14 -26 -97 - - -29 -148 -97 - - -198 -3602 -97 - - -11971 -41372 -32 - - - - - - -arg_type -type_id - - -12 - - -1 -2 -516183 - - -2 -3 -185136 - - -3 -4 -56047 - - -4 -11 -66603 - - -11 -11852 -26771 - - - - - - -arg_type -index - - -12 - - -1 -2 -737629 - - -2 -3 -94426 - - -3 -22 -18685 - - - - - - - - -class_template_argument_value -342536 - - -type_id -221229 - - -index -151 - - -arg_value -325172 - - - - -type_id -index - - -12 - - -1 -2 -199129 - - -2 -3 -13548 - - -3 -14 -8551 - - - - - - -type_id -arg_value - - -12 - - -1 -2 -187640 - - -2 -3 -16724 - - -3 -37 -16594 - - -44 -171 -270 - - - - - - -index -type_id - - -12 - - -8 -9 -54 - - -20 -21 -10 - - -25 -26 -10 - - -206 -207 -10 - - -389 -390 -10 - - -552 -553 -10 - - -1310 -1311 -10 - - -5430 -5431 -10 - - -5675 -5676 -10 - - -9813 -9814 -10 - - - - - - -index -arg_value - - -12 - - -8 -9 -54 - - -20 -21 -10 - - -42 -43 -10 - - -311 -312 -10 - - -514 -515 -10 - - -715 -716 -10 - - -1597 -1598 -10 - - -6347 -6348 -10 - - -8321 -8322 -10 - - -12094 -12095 -10 - - - - - - -arg_value -type_id - - -12 - - -1 -2 -308123 - - -2 -4 -17049 - - - - - - -arg_value -index - - -12 - - -1 -2 -325172 - - - - - - - - -is_proxy_class_for -45836 - - -id -45836 - - -templ_param_id -45836 - - - - -id -templ_param_id - - -12 - - -1 -2 -45836 - - - - - - -templ_param_id -id - - -12 - - -1 -2 -45836 - - - - - - - - -type_mentions -1674881 - - -id -1674881 - - -type_id -67096 - - -location -1644422 - - -kind -12 - - - - -id -type_id - - -12 - - -1 -2 -1674881 - - - - - - -id -location - - -12 - - -1 -2 -1674881 - - - - - - -id -kind - - -12 - - -1 -2 -1674881 - - - - - - -type_id -id - - -12 - - -1 -2 -30024 - - -2 -3 -12283 - - -3 -4 -3631 - - -4 -7 -6054 - - -7 -13 -5138 - - -13 -35 -5183 - - -35 -9490 -4781 - - - - - - -type_id -location - - -12 - - -1 -2 -30024 - - -2 -3 -12283 - - -3 -4 -3631 - - -4 -7 -6054 - - -7 -13 -5138 - - -13 -35 -5183 - - -35 -9490 -4781 - - - - - - -type_id -kind - - -12 - - -1 -2 -65856 - - -2 -3 -1240 - - - - - - -location -id - - -12 - - -1 -2 -1614300 - - -2 -5 -30121 - - - - - - -location -type_id - - -12 - - -1 -2 -1614300 - - -2 -5 -30121 - - - - - - -location -kind - - -12 - - -1 -2 -1644422 - - - - - - -kind -id - - -12 - - -685 -686 -6 - - -257149 -257150 -6 - - - - - - -kind -type_id - - -12 - - -207 -208 -6 - - -10313 -10314 -6 - - - - - - -kind -location - - -12 - - -677 -678 -6 - - -252468 -252469 -6 - - - - - - - - -is_function_template -972255 - - -id -972255 - - - - - -function_instantiation -700030 - - -to -700030 - - -from -127821 - - - - -to -from - - -12 - - -1 -2 -700030 - - - - - - -from -to - - -12 - - -1 -2 -60295 - - -2 -3 -30478 - - -3 -4 -7261 - - -4 -5 -8714 - - -5 -10 -9884 - - -10 -71 -9592 - - -71 -653 -1593 - - - - - - - - -function_template_argument -1888193 - - -function_id -1042035 - - -index -216 - - -arg_type -334493 - - - - -function_id -index - - -12 - - -1 -2 -576761 - - -2 -3 -287605 - - -3 -4 -126271 - - -4 -21 -51397 - - - - - - -function_id -arg_type - - -12 - - -1 -2 -591014 - - -2 -3 -285318 - - -3 -4 -109644 - - -4 -21 -56057 - - - - - - -index -function_id - - -12 - - -4 -5 -10 - - -7 -8 -10 - - -17 -18 -10 - - -39 -40 -10 - - -65 -66 -10 - - -152 -153 -10 - - -241 -242 -10 - - -328 -329 -10 - - -425 -426 -10 - - -523 -524 -10 - - -758 -759 -10 - - -1011 -1012 -10 - - -1520 -1521 -10 - - -1705 -1706 -10 - - -2571 -2572 -10 - - -2915 -2916 -10 - - -5729 -5730 -10 - - -18257 -18258 -10 - - -44058 -44059 -10 - - -90976 -90977 -10 - - - - - - -index -arg_type - - -12 - - -4 -5 -10 - - -7 -8 -10 - - -14 -15 -10 - - -22 -23 -10 - - -32 -33 -10 - - -54 -55 -10 - - -60 -61 -10 - - -62 -63 -10 - - -78 -79 -10 - - -91 -92 -10 - - -140 -141 -10 - - -214 -215 -10 - - -242 -243 -10 - - -317 -318 -10 - - -521 -522 -10 - - -694 -695 -10 - - -1488 -1489 -10 - - -3726 -3727 -10 - - -8711 -8712 -10 - - -17522 -17523 -10 - - - - - - -arg_type -function_id - - -12 - - -1 -2 -223483 - - -2 -3 -44590 - - -3 -6 -27346 - - -6 -19 -25308 - - -19 -2030 -13765 - - - - - - -arg_type -index - - -12 - - -1 -2 -311147 - - -2 -12 -23346 - - - - - - - - -function_template_argument_value -197655 - - -function_id -105829 - - -index -151 - - -arg_value -170363 - - - - -function_id -index - - -12 - - -1 -2 -100377 - - -2 -14 -5451 - - - - - - -function_id -arg_value - - -12 - - -1 -2 -83967 - - -2 -3 -15987 - - -3 -119 -5874 - - - - - - -index -function_id - - -12 - - -3 -4 -65 - - -5 -6 -10 - - -6 -7 -10 - - -111 -112 -10 - - -445 -446 -10 - - -861 -862 -10 - - -2152 -2153 -10 - - -2453 -2454 -10 - - -4262 -4263 -10 - - - - - - -index -arg_value - - -12 - - -5 -6 -65 - - -7 -8 -10 - - -8 -9 -10 - - -169 -170 -10 - - -408 -409 -10 - - -1024 -1025 -10 - - -2547 -2548 -10 - - -4912 -4913 -10 - - -6613 -6614 -10 - - - - - - -arg_value -function_id - - -12 - - -1 -2 -143569 - - -2 -3 -26294 - - -3 -4 -498 - - - - - - -arg_value -index - - -12 - - -1 -2 -170363 - - - - - - - - -is_variable_template -17602 - - -id -17602 - - - - - -variable_instantiation -35388 - - -to -35388 - - -from -6394 - - - - -to -from - - -12 - - -1 -2 -35388 - - - - - - -from -to - - -12 - - -1 -2 -2211 - - -2 -3 -1885 - - -3 -4 -357 - - -4 -5 -726 - - -5 -9 -531 - - -9 -21 -487 - - -24 -288 -195 - - - - - - - - -variable_template_argument -5476 - - -variable_id -844 - - -index -32 - - -arg_type -4196 - - - - -variable_id -index - - -12 - - -1 -2 -682 - - -2 -3 -123 - - -3 -5 -38 - - - - - - -variable_id -arg_type - - -12 - - -1 -2 -370 - - -2 -3 -129 - - -3 -4 -64 - - -4 -6 -71 - - -6 -8 -71 - - -8 -13 -64 - - -13 -85 -64 - - -202 -203 -6 - - - - - - -index -variable_id - - -12 - - -3 -4 -6 - - -6 -7 -6 - - -10 -11 -6 - - -20 -21 -6 - - -125 -126 -6 - - - - - - -index -arg_type - - -12 - - -21 -22 -6 - - -83 -84 -6 - - -115 -116 -6 - - -139 -140 -6 - - -322 -323 -6 - - - - - - -arg_type -variable_id - - -12 - - -1 -2 -3475 - - -2 -3 -474 - - -3 -11 -246 - - - - - - -arg_type -index - - -12 - - -1 -2 -3982 - - -2 -4 -214 - - - - - - - - -variable_template_argument_value -136 - - -variable_id -19 - - -index -12 - - -arg_value -136 - - - - -variable_id -index - - -12 - - -1 -2 -12 - - -2 -3 -6 - - - - - - -variable_id -arg_value - - -12 - - -3 -4 -12 - - -15 -16 -6 - - - - - - -index -variable_id - - -12 - - -1 -2 -6 - - -3 -4 -6 - - - - - - -index -arg_value - - -12 - - -6 -7 -6 - - -15 -16 -6 - - - - - - -arg_value -variable_id - - -12 - - -1 -2 -136 - - - - - - -arg_value -index - - -12 - - -1 -2 -136 - - - - - - - - -routinetypes -421539 - - -id -421539 - - -return_type -173397 - - - - -id -return_type - - -12 - - -1 -2 -421539 - - - - - - -return_type -id - - -12 - - -1 -2 -139917 - - -2 -3 -17580 - - -3 -10 -13342 - - -10 -8267 -2557 - - - - - - - - -routinetypeargs -704387 - - -routine -344519 - - -index -346 - - -type_id -202391 - - - - -routine -index - - -12 - - -1 -2 -158418 - - -2 -3 -94112 - - -3 -4 -53066 - - -4 -6 -31421 - - -6 -33 -7500 - - - - - - -routine -type_id - - -12 - - -1 -2 -182632 - - -2 -3 -94925 - - -3 -4 -46563 - - -4 -22 -20398 - - - - - - -index -routine - - -12 - - -1 -2 -119 - - -2 -7 -21 - - -10 -16 -21 - - -19 -33 -21 - - -51 -72 -21 - - -90 -111 -21 - - -134 -193 -21 - - -262 -356 -21 - - -464 -693 -21 - - -1438 -3592 -21 - - -8487 -17171 -21 - - -31786 -31787 -10 - - - - - - -index -type_id - - -12 - - -1 -2 -119 - - -2 -5 -21 - - -6 -10 -21 - - -11 -22 -21 - - -32 -36 -21 - - -37 -41 -21 - - -43 -82 -21 - - -124 -183 -21 - - -248 -346 -21 - - -466 -1095 -21 - - -2669 -6025 -21 - - -13431 -13432 -10 - - - - - - -type_id -routine - - -12 - - -1 -2 -120526 - - -2 -3 -40265 - - -3 -4 -12963 - - -4 -7 -16420 - - -7 -1325 -12215 - - - - - - -type_id -index - - -12 - - -1 -2 -151709 - - -2 -3 -38835 - - -3 -33 -11846 - - - - - - - - -ptrtomembers -12486 - - -id -12486 - - -type_id -9288 - - -class_id -6286 - - - - -id -type_id - - -12 - - -1 -2 -12486 - - - - - - -id -class_id - - -12 - - -1 -2 -12486 - - - - - - -type_id -id - - -12 - - -1 -2 -8931 - - -2 -111 -357 - - - - - - -type_id -class_id - - -12 - - -1 -2 -8931 - - -2 -111 -357 - - - - - - -class_id -id - - -12 - - -1 -2 -5278 - - -2 -3 -509 - - -8 -65 -498 - - - - - - -class_id -type_id - - -12 - - -1 -2 -5278 - - -2 -3 -509 - - -8 -65 -498 - - - - - - - - -specifiers -498 - - -id -498 - - -str -498 - - - - -id -str - - -12 - - -1 -2 -498 - - - - - - -str -id - - -12 - - -1 -2 -498 - - - - - - - - -typespecifiers -1316038 - - -type_id -1309231 - - -spec_id -75 - - - - -type_id -spec_id - - -12 - - -1 -2 -1302424 - - -2 -3 -6806 - - - - - - -spec_id -type_id - - -12 - - -102 -103 -10 - - -222 -223 -10 - - -598 -599 -10 - - -957 -958 -10 - - -2363 -2364 -10 - - -20785 -20786 -10 - - -96393 -96394 -10 - - - - - - - - -funspecifiers -11898581 - - -func_id -3610802 - - -spec_id -173 - - - - -func_id -spec_id - - -12 - - -1 -2 -332055 - - -2 -3 -428379 - - -3 -4 -865569 - - -4 -5 -1867415 - - -5 -8 -117383 - - - - - - -spec_id -func_id - - -12 - - -50 -51 -10 - - -181 -182 -10 - - -491 -492 -10 - - -592 -593 -10 - - -662 -663 -10 - - -5721 -5722 -10 - - -9634 -9635 -10 - - -10714 -10715 -10 - - -12941 -12942 -10 - - -15383 -15384 -10 - - -28391 -28392 -10 - - -34167 -34168 -10 - - -160563 -160564 -10 - - -240969 -240970 -10 - - -271992 -271993 -10 - - -305333 -305334 -10 - - - - - - - - -varspecifiers -1110252 - - -var_id -923337 - - -spec_id -64 - - - - -var_id -spec_id - - -12 - - -1 -2 -784946 - - -2 -3 -91515 - - -3 -5 -46874 - - - - - - -spec_id -var_id - - -12 - - -17 -18 -6 - - -160 -161 -6 - - -446 -447 -6 - - -5881 -5882 -6 - - -8410 -8411 -6 - - -8752 -8753 -6 - - -11326 -11327 -6 - - -13439 -13440 -6 - - -42420 -42421 -6 - - -80063 -80064 -6 - - - - - - - - -attributes -414234 - - -id -414234 - - -kind -1 - - -name -55 - - -name_space -1 - - -location -90620 - - - - -id -kind - - -12 - - -1 -2 -414234 - - - - - - -id -name - - -12 - - -1 -2 -414234 - - - - - - -id -name_space - - -12 - - -1 -2 -414234 - - - - - - -id -location - - -12 - - -1 -2 -414234 - - - - - - -kind -id - - -12 - - -254158 -254159 -1 - - - - - - -kind -name - - -12 - - -34 -35 -1 - - - - - - -kind -name_space - - -12 - - -1 -2 -1 - - - - - - -kind -location - - -12 - - -55601 -55602 -1 - - - - - - -name -id - - -12 - - -1 -2 -3 - - -4 -5 -3 - - -6 -10 -4 - - -25 -42 -4 - - -46 -61 -4 - - -75 -164 -4 - - -225 -444 -4 - - -648 -780 -4 - - -807 -1148 -4 - - -3562 -12538 -4 - - -26224 -35247 -4 - - -41457 -49796 -4 - - - - - - -name -kind - - -12 - - -1 -2 -55 - - - - - - -name -name_space - - -12 - - -1 -2 -55 - - - - - - -name -location - - -12 - - -1 -3 -4 - - -4 -7 -4 - - -9 -26 -4 - - -32 -50 -4 - - -58 -75 -4 - - -151 -235 -4 - - -440 -628 -4 - - -645 -776 -4 - - -818 -3958 -4 - - -11143 -16981 -4 - - -19805 -21504 -4 - - -22415 -22416 -1 - - - - - - -name_space -id - - -12 - - -254158 -254159 -1 - - - - - - -name_space -kind - - -12 - - -1 -2 -1 - - - - - - -name_space -name - - -12 - - -34 -35 -1 - - - - - - -name_space -location - - -12 - - -55601 -55602 -1 - - - - - - -location -id - - -12 - - -1 -2 -26763 - - -2 -3 -5319 - - -3 -4 -30032 - - -4 -8 -7396 - - -8 -9 -17719 - - -9 -73 -3388 - - - - - - -location -kind - - -12 - - -1 -2 -90620 - - - - - - -location -name - - -12 - - -1 -2 -28450 - - -2 -3 -4685 - - -3 -4 -49730 - - -4 -9 -7373 - - -9 -10 -379 - - - - - - -location -name_space - - -12 - - -1 -2 -90620 - - - - - - - - -attribute_args -152801 - - -id -152801 - - -kind -3 - - -attribute -151500 - - -index -6 - - -location -57431 - - - - -id -kind - - -12 - - -1 -2 -152801 - - - - - - -id -attribute - - -12 - - -1 -2 -152801 - - - - - - -id -index - - -12 - - -1 -2 -152801 - - - - - - -id -location - - -12 - - -1 -2 -152801 - - - - - - -kind -id - - -12 - - -3879 -3880 -1 - - -89859 -89860 -1 - - - - - - -kind -attribute - - -12 - - -3879 -3880 -1 - - -89377 -89378 -1 - - - - - - -kind -index - - -12 - - -1 -2 -1 - - -4 -5 -1 - - - - - - -kind -location - - -12 - - -3807 -3808 -1 - - -34991 -34992 -1 - - - - - - -attribute -id - - -12 - - -1 -2 -150721 - - -2 -5 -779 - - - - - - -attribute -kind - - -12 - - -1 -2 -151010 - - -2 -3 -490 - - - - - - -attribute -index - - -12 - - -1 -2 -150721 - - -2 -5 -779 - - - - - - -attribute -location - - -12 - - -1 -2 -150726 - - -2 -5 -774 - - - - - - -index -id - - -12 - - -1 -2 -1 - - -319 -320 -1 - - -478 -479 -1 - - -92940 -92941 -1 - - - - - - -index -kind - - -12 - - -1 -2 -4 - - -2 -3 -1 - - - - - - -index -attribute - - -12 - - -1 -2 -1 - - -319 -320 -1 - - -478 -479 -1 - - -92955 -92956 -1 - - - - - - -index -location - - -12 - - -1 -2 -1 - - -252 -253 -1 - - -410 -411 -1 - - -34581 -34582 -1 - - - - - - -location -id - - -12 - - -1 -2 -27328 - - -2 -3 -8439 - - -3 -5 -2889 - - -5 -6 -17621 - - -6 -37 -1152 - - - - - - -location -kind - - -12 - - -1 -2 -51629 - - -2 -3 -5802 - - - - - - -location -attribute - - -12 - - -1 -2 -27314 - - -2 -3 -8455 - - -3 -5 -2888 - - -5 -6 -17621 - - -6 -37 -1152 - - - - - - -location -index - - -12 - - -1 -2 -57427 - - -3 -4 -4 - - - - - - - - -attribute_arg_value -152776 - - -arg -152776 - - -value -2190 - - - - -arg -value - - -12 - - -1 -2 -152776 - - - - - - -value -arg - - -12 - - -1 -2 -1732 - - -2 -3 -156 - - -3 -10 -167 - - -10 -23976 -133 - - - - - - - - -attribute_arg_type -54 - - -arg -54 - - -type_id -32 - - - - -arg -type_id - - -12 - - -1 -2 -54 - - - - - - -type_id -arg - - -12 - - -1 -2 -10 - - -2 -3 -21 - - - - - - - - -attribute_arg_name -6 - - -arg -6 - - -name -5 - - - - -arg -name - - -12 - - -1 -2 -6 - - - - - - -name -arg - - -12 - - -1 -2 -4 - - -2 -3 -1 - - - - - - - - -typeattributes -19097 - - -type_id -17732 - - -spec_id -19097 - - - - -type_id -spec_id - - -12 - - -1 -2 -17038 - - -2 -34 -693 - - - - - - -spec_id -type_id - - -12 - - -1 -2 -19097 - - - - - - - - -funcattributes -300785 - - -func_id -162277 - - -spec_id -300785 - - - - -func_id -spec_id - - -12 - - -1 -2 -88595 - - -2 -3 -12432 - - -3 -4 -59266 - - -4 -14 -1983 - - - - - - -spec_id -func_id - - -12 - - -1 -2 -300785 - - - - - - - - -varattributes -371223 - - -var_id -322421 - - -spec_id -371223 - - - - -var_id -spec_id - - -12 - - -1 -2 -273655 - - -2 -3 -48763 - - -14 -15 -3 - - - - - - -spec_id -var_id - - -12 - - -1 -2 -371223 - - - - - - - - -stmtattributes -986 - - -stmt_id -986 - - -spec_id -986 - - - - -stmt_id -spec_id - - -12 - - -1 -2 -986 - - - - - - -spec_id -stmt_id - - -12 - - -1 -2 -986 - - - - - - - - -unspecifiedtype -9002061 - - -type_id -9002061 - - -unspecified_type_id -4949385 - - - - -type_id -unspecified_type_id - - -12 - - -1 -2 -9002061 - - - - - - -unspecified_type_id -type_id - - -12 - - -1 -2 -2701086 - - -2 -3 -1937281 - - -3 -7950 -311017 - - - - - - - - -member -5094949 - - -parent -804764 - - -index -2644 - - -child -5079548 - - - - -parent -index - - -12 - - -1 -3 -70343 - - -3 -4 -381479 - - -4 -5 -94416 - - -5 -7 -68793 - - -7 -9 -59396 - - -9 -15 -63850 - - -15 -47 -60469 - - -47 -245 -6015 - - - - - - -parent -child - - -12 - - -1 -3 -69812 - - -3 -4 -375930 - - -4 -5 -97841 - - -5 -7 -68685 - - -7 -9 -59461 - - -9 -15 -64772 - - -15 -42 -60555 - - -42 -281 -7706 - - - - - - -index -parent - - -12 - - -1 -2 -487 - - -2 -5 -238 - - -5 -10 -227 - - -10 -64 -205 - - -65 -137 -205 - - -144 -213 -205 - - -219 -295 -205 - - -299 -393 -216 - - -393 -649 -205 - - -649 -3628 -205 - - -3644 -31598 -205 - - -65753 -73573 -32 - - - - - - -index -child - - -12 - - -1 -2 -476 - - -2 -5 -195 - - -5 -9 -205 - - -9 -22 -205 - - -25 -132 -205 - - -132 -199 -205 - - -199 -279 -205 - - -279 -366 -205 - - -382 -480 -205 - - -489 -1630 -205 - - -1771 -8155 -205 - - -8939 -74519 -119 - - - - - - -child -parent - - -12 - - -1 -2 -5079548 - - - - - - -child -index - - -12 - - -1 -2 -5064362 - - -2 -7 -15185 - - - - - - - - -enclosingfunction -123615 - - -child -123615 - - -parent -70570 - - - - -child -parent - - -12 - - -1 -2 -123615 - - - - - - -parent -child - - -12 - - -1 -2 -37892 - - -2 -3 -20832 - - -3 -4 -6459 - - -4 -7 -5310 - - -7 -45 -75 - - - - - - - - -derivations -385706 - - -derivation -385706 - - -sub -360192 - - -index -65 - - -super -232945 - - -location -85961 - - - - -derivation -sub - - -12 - - -1 -2 -385706 - - - - - - -derivation -index - - -12 - - -1 -2 -385706 - - - - - - -derivation -super - - -12 - - -1 -2 -385706 - - - - - - -derivation -location - - -12 - - -1 -2 -385706 - - - - - - -sub -derivation - - -12 - - -1 -2 -337886 - - -2 -7 -22306 - - - - - - -sub -index - - -12 - - -1 -2 -347392 - - -2 -7 -12800 - - - - - - -sub -super - - -12 - - -1 -2 -337897 - - -2 -7 -22295 - - - - - - -sub -location - - -12 - - -1 -2 -347381 - - -2 -7 -12811 - - - - - - -index -derivation - - -12 - - -1 -2 -10 - - -4 -5 -10 - - -44 -45 -10 - - -234 -235 -10 - - -1182 -1183 -10 - - -34121 -34122 -10 - - - - - - -index -sub - - -12 - - -1 -2 -10 - - -4 -5 -10 - - -44 -45 -10 - - -234 -235 -10 - - -1181 -1182 -10 - - -33232 -33233 -10 - - - - - - -index -super - - -12 - - -1 -2 -10 - - -3 -4 -10 - - -29 -30 -10 - - -84 -85 -10 - - -652 -653 -10 - - -20767 -20768 -10 - - - - - - -index -location - - -12 - - -1 -2 -10 - - -4 -5 -10 - - -17 -18 -10 - - -51 -52 -10 - - -255 -256 -10 - - -7606 -7607 -10 - - - - - - -super -derivation - - -12 - - -1 -2 -218324 - - -2 -1142 -14621 - - - - - - -super -sub - - -12 - - -1 -2 -218335 - - -2 -1142 -14610 - - - - - - -super -index - - -12 - - -1 -2 -232501 - - -2 -4 -444 - - - - - - -super -location - - -12 - - -1 -2 -225673 - - -2 -439 -7272 - - - - - - -location -derivation - - -12 - - -1 -2 -65574 - - -2 -3 -8291 - - -3 -7 -6535 - - -7 -795 -5560 - - - - - - -location -sub - - -12 - - -1 -2 -67785 - - -2 -3 -6297 - - -3 -8 -6958 - - -8 -795 -4920 - - - - - - -location -index - - -12 - - -1 -2 -85940 - - -2 -4 -21 - - - - - - -location -super - - -12 - - -1 -2 -68479 - - -2 -3 -8107 - - -3 -9 -6449 - - -9 -795 -2926 - - - - - - - - -derspecifiers -388058 - - -der_id -385674 - - -spec_id -43 - - - - -der_id -spec_id - - -12 - - -1 -2 -383289 - - -2 -3 -2384 - - - - - - -spec_id -der_id - - -12 - - -220 -221 -10 - - -263 -264 -10 - - -987 -988 -10 - - -34333 -34334 -10 - - - - - - - - -direct_base_offsets -306931 - - -der_id -306931 - - -offset -195 - - - - -der_id -offset - - -12 - - -1 -2 -306931 - - - - - - -offset -der_id - - -12 - - -1 -2 -32 - - -2 -3 -21 - - -4 -5 -21 - - -5 -6 -10 - - -6 -7 -10 - - -7 -8 -21 - - -8 -9 -10 - - -10 -11 -10 - - -11 -12 -10 - - -21 -22 -10 - - -86 -87 -10 - - -214 -215 -10 - - -27928 -27929 -10 - - - - - - - - -virtual_base_offsets -6264 - - -sub -3468 - - -super -476 - - -offset -238 - - - - -sub -super - - -12 - - -1 -2 -2731 - - -2 -4 -303 - - -4 -7 -249 - - -7 -11 -184 - - - - - - -sub -offset - - -12 - - -1 -2 -2926 - - -2 -4 -292 - - -4 -8 -249 - - - - - - -super -sub - - -12 - - -1 -2 -75 - - -2 -3 -43 - - -3 -4 -54 - - -4 -5 -86 - - -5 -7 -32 - - -8 -13 -43 - - -13 -15 -43 - - -15 -23 -43 - - -24 -60 -43 - - -196 -197 -10 - - - - - - -super -offset - - -12 - - -1 -2 -270 - - -2 -3 -75 - - -4 -6 -32 - - -6 -8 -43 - - -8 -10 -43 - - -14 -15 -10 - - - - - - -offset -sub - - -12 - - -2 -3 -32 - - -4 -5 -10 - - -5 -6 -21 - - -6 -8 -21 - - -8 -9 -32 - - -10 -12 -21 - - -14 -19 -21 - - -20 -27 -21 - - -28 -31 -21 - - -36 -97 -21 - - -97 -98 -10 - - - - - - -offset -super - - -12 - - -1 -2 -75 - - -2 -3 -32 - - -3 -4 -43 - - -5 -7 -21 - - -7 -10 -21 - - -12 -14 -21 - - -21 -29 -21 - - - - - - - - -frienddecls -237444 - - -id -237444 - - -type_id -26966 - - -decl_id -48405 - - -location -7218 - - - - -id -type_id - - -12 - - -1 -2 -237444 - - - - - - -id -decl_id - - -12 - - -1 -2 -237444 - - - - - - -id -location - - -12 - - -1 -2 -237444 - - - - - - -type_id -id - - -12 - - -1 -2 -6145 - - -2 -3 -10112 - - -3 -5 -1961 - - -5 -6 -899 - - -6 -8 -2286 - - -8 -19 -2091 - - -21 -43 -2081 - - -43 -162 -1387 - - - - - - -type_id -decl_id - - -12 - - -1 -2 -6145 - - -2 -3 -10112 - - -3 -5 -1961 - - -5 -6 -899 - - -6 -8 -2286 - - -8 -19 -2091 - - -21 -43 -2081 - - -43 -162 -1387 - - - - - - -type_id -location - - -12 - - -1 -2 -25405 - - -2 -31 -1560 - - - - - - -decl_id -id - - -12 - - -1 -2 -33242 - - -2 -3 -4931 - - -3 -7 -3966 - - -7 -23 -3761 - - -23 -394 -2503 - - - - - - -decl_id -type_id - - -12 - - -1 -2 -33242 - - -2 -3 -4931 - - -3 -7 -3966 - - -7 -23 -3761 - - -23 -394 -2503 - - - - - - -decl_id -location - - -12 - - -1 -2 -47874 - - -2 -46 -531 - - - - - - -location -id - - -12 - - -1 -2 -6167 - - -2 -3 -932 - - -3 -21129 -119 - - - - - - -location -type_id - - -12 - - -1 -2 -6785 - - -2 -2097 -433 - - - - - - -location -decl_id - - -12 - - -1 -2 -6178 - - -2 -3 -921 - - -3 -3830 -119 - - - - - - - - -comments -1561817 - - -id -1561817 - - -contents -774990 - - -location -1561817 - - - - -id -contents - - -12 - - -1 -2 -1561817 - - - - - - -id -location - - -12 - - -1 -2 -1561817 - - - - - - -contents -id - - -12 - - -1 -2 -656176 - - -2 -3 -74223 - - -3 -10738 -44590 - - - - - - -contents -location - - -12 - - -1 -2 -656176 - - -2 -3 -74223 - - -3 -10738 -44590 - - - - - - -location -id - - -12 - - -1 -2 -1561817 - - - - - - -location -contents - - -12 - - -1 -2 -1561817 - - - - - - - - -commentbinding -704994 - - -id -611185 - - -element -676553 - - - - -id -element - - -12 - - -1 -2 -550520 - - -2 -3 -48514 - - -3 -97 -12150 - - - - - - -element -id - - -12 - - -1 -2 -648112 - - -2 -3 -28440 - - - - - - - - -exprconv -6470964 - - -converted -6470955 - - -conversion -6470964 - - - - -converted -conversion - - -12 - - -1 -2 -6470947 - - -2 -4 -8 - - - - - - -conversion -converted - - -12 - - -1 -2 -6470964 - - - - - - - - -compgenerated -6859342 - - -id -6859342 - - - - - -synthetic_destructor_call -58919 - - -element -45858 - - -i -303 - - -destructor_call -48893 - - - - -element -i - - -12 - - -1 -2 -36526 - - -2 -3 -6687 - - -3 -29 -2644 - - - - - - -element -destructor_call - - -12 - - -1 -2 -36526 - - -2 -3 -6687 - - -3 -29 -2644 - - - - - - -i -element - - -12 - - -1 -2 -227 - - -2 -8 -21 - - -23 -48 -21 - - -244 -862 -21 - - -4231 -4232 -10 - - - - - - -i -destructor_call - - -12 - - -1 -2 -227 - - -2 -8 -21 - - -22 -42 -21 - - -187 -667 -21 - - -3565 -3566 -10 - - - - - - -destructor_call -element - - -12 - - -1 -2 -43116 - - -2 -3 -3576 - - -3 -26 -2200 - - - - - - -destructor_call -i - - -12 - - -1 -2 -48893 - - - - - - - - -namespaces -7597 - - -id -7597 - - -name -4086 - - - - -id -name - - -12 - - -1 -2 -7597 - - - - - - -name -id - - -12 - - -1 -2 -3435 - - -2 -3 -411 - - -3 -139 -238 - - - - - - - - -namespace_inline -151 - - -id -151 - - - - - -namespacembrs -1584090 - - -parentid -7077 - - -memberid -1584090 - - - - -parentid -memberid - - -12 - - -1 -2 -726 - - -2 -3 -791 - - -3 -4 -346 - - -4 -5 -520 - - -5 -7 -552 - - -7 -12 -574 - - -12 -19 -531 - - -19 -34 -541 - - -36 -52 -574 - - -52 -105 -531 - - -105 -230 -541 - - -231 -744 -531 - - -778 -39452 -314 - - - - - - -memberid -parentid - - -12 - - -1 -2 -1584090 - - - - - - - - -exprparents -13432189 - - -expr_id -13432000 - - -child_index -3118 - - -parent_id -9515340 - - - - -expr_id -child_index - - -12 - - -1 -2 -13431994 - - -2 -3 -6 - - - - - - -expr_id -parent_id - - -12 - - -1 -2 -13431818 - - -2 -4 -181 - - - - - - -child_index -expr_id - - -12 - - -1 -2 -71 - - -2 -3 -643 - - -3 -4 -1649 - - -4 -46 -240 - - -46 -56 -233 - - -56 -3654 -233 - - -6420 -1188854 -45 - - - - - - -child_index -parent_id - - -12 - - -1 -2 -71 - - -2 -3 -643 - - -3 -4 -1649 - - -4 -31 -240 - - -31 -41 -233 - - -41 -3639 -233 - - -6405 -1188867 -45 - - - - - - -parent_id -expr_id - - -12 - - -1 -2 -6748421 - - -2 -3 -2184263 - - -3 -1681 -582655 - - - - - - -parent_id -child_index - - -12 - - -1 -2 -6748441 - - -2 -3 -2184243 - - -3 -480 -582655 - - - - - - - - -expr_isload -5009424 - - -expr_id -5009424 - - - - - -conversionkinds -4246766 - - -expr_id -4246766 - - -kind -6 - - - - -expr_id -kind - - -12 - - -1 -2 -4246766 - - - - - - -kind -expr_id - - -12 - - -2189 -2190 -1 - - -3368 -3369 -1 - - -13714 -13715 -1 - - -26502 -26503 -1 - - -45529 -45530 -1 - - -4155464 -4155465 -1 - - - - - - - - -iscall -2293539 - - -caller -2293539 - - -kind -32 - - - - -caller -kind - - -12 - - -1 -2 -2293539 - - - - - - -kind -caller - - -12 - - -1386 -1387 -10 - - -6427 -6428 -10 - - -203793 -203794 -10 - - - - - - - - -numtemplatearguments -162776 - - -expr_id -162776 - - -num -43 - - - - -expr_id -num - - -12 - - -1 -2 -162776 - - - - - - -num -expr_id - - -12 - - -3 -4 -10 - - -41 -42 -10 - - -669 -670 -10 - - -14305 -14306 -10 - - - - - - - - -specialnamequalifyingelements -10 - - -id -10 - - -name -10 - - - - -id -name - - -12 - - -1 -2 -10 - - - - - - -name -id - - -12 - - -1 -2 -10 - - - - - - - - -namequalifiers -1119060 - - -id -1119060 - - -qualifiableelement -1119060 - - -qualifyingelement -38800 - - -location -504119 - - - - -id -qualifiableelement - - -12 - - -1 -2 -1119060 - - - - - - -id -qualifyingelement - - -12 - - -1 -2 -1119060 - - - - - - -id -location - - -12 - - -1 -2 -1119060 - - - - - - -qualifiableelement -id - - -12 - - -1 -2 -1119060 - - - - - - -qualifiableelement -qualifyingelement - - -12 - - -1 -2 -1119060 - - - - - - -qualifiableelement -location - - -12 - - -1 -2 -1119060 - - - - - - -qualifyingelement -id - - -12 - - -1 -2 -18890 - - -2 -3 -8035 - - -3 -4 -4975 - - -4 -11 -3079 - - -11 -121 -2910 - - -124 -24963 -909 - - - - - - -qualifyingelement -qualifiableelement - - -12 - - -1 -2 -18890 - - -2 -3 -8035 - - -3 -4 -4975 - - -4 -11 -3079 - - -11 -121 -2910 - - -124 -24963 -909 - - - - - - -qualifyingelement -location - - -12 - - -1 -2 -24749 - - -2 -3 -4670 - - -3 -4 -3709 - - -4 -11 -3027 - - -11 -16750 -2643 - - - - - - -location -id - - -12 - - -1 -2 -380150 - - -2 -3 -56638 - - -3 -7 -41762 - - -7 -381 -25568 - - - - - - -location -qualifiableelement - - -12 - - -1 -2 -380150 - - -2 -3 -56638 - - -3 -7 -41762 - - -7 -381 -25568 - - - - - - -location -qualifyingelement - - -12 - - -1 -2 -444298 - - -2 -3 -44477 - - -3 -190 -15343 - - - - - - - - -varbind -5425985 - - -expr -5425862 - - -var -1530372 - - - - -expr -var - - -12 - - -1 -2 -5425738 - - -2 -3 -123 - - - - - - -var -expr - - -12 - - -1 -2 -678893 - - -2 -3 -308409 - - -3 -4 -232367 - - -4 -5 -92671 - - -5 -9 -132849 - - -9 -6150 -85181 - - - - - - - - -funbind -2412732 - - -expr -2116341 - - -fun -433346 - - - - -expr -fun - - -12 - - -1 -2 -1820189 - - -2 -3 -295975 - - -3 -5 -175 - - - - - - -fun -expr - - -12 - - -1 -2 -251653 - - -2 -3 -75463 - - -3 -4 -31180 - - -4 -7 -33850 - - -7 -37 -33376 - - -37 -6664 -7821 - - - - - - - - -expr_allocator -29979 - - -expr -29979 - - -func -119 - - -form -10 - - - - -expr -func - - -12 - - -1 -2 -29979 - - - - - - -expr -form - - -12 - - -1 -2 -29979 - - - - - - -func -expr - - -12 - - -1 -2 -32 - - -3 -4 -10 - - -5 -6 -10 - - -6 -7 -10 - - -7 -8 -21 - - -42 -43 -10 - - -1327 -1328 -10 - - -1366 -1367 -10 - - - - - - -func -form - - -12 - - -1 -2 -119 - - - - - - -form -expr - - -12 - - -2766 -2767 -10 - - - - - - -form -func - - -12 - - -11 -12 -10 - - - - - - - - -expr_deallocator -32917 - - -expr -32917 - - -func -130 - - -form -21 - - - - -expr -func - - -12 - - -1 -2 -32917 - - - - - - -expr -form - - -12 - - -1 -2 -32917 - - - - - - -func -expr - - -12 - - -1 -2 -32 - - -2 -3 -21 - - -3 -4 -10 - - -6 -7 -10 - - -7 -8 -21 - - -118 -119 -10 - - -1274 -1275 -10 - - -1615 -1616 -10 - - - - - - -func -form - - -12 - - -1 -2 -130 - - - - - - -form -expr - - -12 - - -1284 -1285 -10 - - -1753 -1754 -10 - - - - - - -form -func - - -12 - - -4 -5 -10 - - -8 -9 -10 - - - - - - - - -expr_cond_two_operand -612 - - -cond -612 - - - - - -expr_cond_guard -154485 - - -cond -154485 - - -guard -154485 - - - - -cond -guard - - -12 - - -1 -2 -154485 - - - - - - -guard -cond - - -12 - - -1 -2 -154485 - - - - - - - - -expr_cond_true -154485 - - -cond -154485 - - -true -154485 - - - - -cond -true - - -12 - - -1 -2 -154485 - - - - - - -true -cond - - -12 - - -1 -2 -154485 - - - - - - - - -expr_cond_false -154485 - - -cond -154485 - - -false -154485 - - - - -cond -false - - -12 - - -1 -2 -154485 - - - - - - -false -cond - - -12 - - -1 -2 -154485 - - - - - - - - -values -8774622 - - -id -8774622 - - -str -651637 - - - - -id -str - - -12 - - -1 -2 -8774622 - - - - - - -str -id - - -12 - - -1 -2 -540186 - - -2 -3 -65496 - - -3 -4040441 -45955 - - - - - - - - -valuetext -4778502 - - -id -4778502 - - -text -706785 - - - - -id -text - - -12 - - -1 -2 -4778502 - - - - - - -text -id - - -12 - - -1 -2 -529394 - - -2 -3 -102965 - - -3 -7 -57061 - - -7 -427516 -17365 - - - - - - - - -valuebind -9496119 - - -val -8768412 - - -expr -9496119 - - - - -val -expr - - -12 - - -1 -2 -8041464 - - -2 -3 -726192 - - -3 -6 -756 - - - - - - -expr -val - - -12 - - -1 -2 -9496119 - - - - - - - - -fieldoffsets -250750 - - -id -250750 - - -byteoffset -8983 - - -bitoffset -51 - - - - -id -byteoffset - - -12 - - -1 -2 -250750 - - - - - - -id -bitoffset - - -12 - - -1 -2 -250750 - - - - - - -byteoffset -id - - -12 - - -1 -2 -6106 - - -2 -3 -779 - - -3 -6 -747 - - -6 -17 -675 - - -17 -11719 -675 - - - - - - -byteoffset -bitoffset - - -12 - - -1 -2 -8542 - - -2 -9 -441 - - - - - - -bitoffset -id - - -12 - - -83 -84 -6 - - -87 -88 -6 - - -102 -103 -6 - - -122 -123 -6 - - -127 -128 -6 - - -153 -154 -6 - - -195 -196 -6 - - -37732 -37733 -6 - - - - - - -bitoffset -byteoffset - - -12 - - -40 -41 -6 - - -44 -45 -6 - - -45 -46 -6 - - -52 -53 -6 - - -54 -55 -6 - - -58 -59 -6 - - -66 -67 -6 - - -1383 -1384 -6 - - - - - - - - -bitfield -13845 - - -id -13845 - - -bits -68 - - -declared_bits -68 - - - - -id -bits - - -12 - - -1 -2 -13845 - - - - - - -id -declared_bits - - -12 - - -1 -2 -13845 - - - - - - -bits -id - - -12 - - -1 -2 -14 - - -2 -3 -8 - - -3 -4 -8 - - -4 -5 -6 - - -5 -6 -3 - - -6 -7 -4 - - -8 -14 -4 - - -17 -36 -4 - - -37 -94 -4 - - -97 -152 -4 - - -2106 -5611 -3 - - - - - - -bits -declared_bits - - -12 - - -1 -2 -68 - - - - - - -declared_bits -id - - -12 - - -1 -2 -14 - - -2 -3 -8 - - -3 -4 -8 - - -4 -5 -6 - - -5 -6 -3 - - -6 -7 -4 - - -8 -14 -4 - - -17 -36 -4 - - -37 -94 -4 - - -97 -152 -4 - - -2106 -5611 -3 - - - - - - -declared_bits -bits - - -12 - - -1 -2 -68 - - - - - - - - -initialisers -1662175 - - -init -1662175 - - -var -641756 - - -expr -1662175 - - -location -318179 - - - - -init -var - - -12 - - -1 -2 -1662175 - - - - - - -init -expr - - -12 - - -1 -2 -1662175 - - - - - - -init -location - - -12 - - -1 -2 -1662175 - - - - - - -var -init - - -12 - - -1 -2 -555333 - - -2 -16 -28660 - - -16 -17 -48973 - - -17 -53 -8789 - - - - - - -var -expr - - -12 - - -1 -2 -555333 - - -2 -16 -28660 - - -16 -17 -48973 - - -17 -53 -8789 - - - - - - -var -location - - -12 - - -1 -2 -641743 - - -2 -3 -12 - - - - - - -expr -init - - -12 - - -1 -2 -1662175 - - - - - - -expr -var - - -12 - - -1 -2 -1662175 - - - - - - -expr -location - - -12 - - -1 -2 -1662175 - - - - - - -location -init - - -12 - - -1 -2 -245703 - - -2 -3 -23690 - - -3 -7 -24210 - - -7 -65 -24048 - - -67 -109109 -526 - - - - - - -location -var - - -12 - - -1 -2 -268251 - - -2 -3 -24931 - - -3 -22 -23885 - - -22 -12503 -1110 - - - - - - -location -expr - - -12 - - -1 -2 -245703 - - -2 -3 -23690 - - -3 -7 -24210 - - -7 -65 -24048 - - -67 -109109 -526 - - - - - - - - -expr_ancestor -65325 - - -exp -64631 - - -ancestor -46563 - - - - -exp -ancestor - - -12 - - -1 -2 -64002 - - -2 -4 -628 - - - - - - -ancestor -exp - - -12 - - -1 -2 -34543 - - -2 -3 -9592 - - -3 -29 -2427 - - - - - - - - -exprs -18461258 - - -id -18461258 - - -kind -1094 - - -location -3585917 - - - - -id -kind - - -12 - - -1 -2 -18461258 - - - - - - -id -location - - -12 - - -1 -2 -18461258 - - - - - - -kind -id - - -12 - - -2 -14 -86 - - -15 -50 -86 - - -50 -90 -86 - - -90 -223 -86 - - -306 -472 -86 - - -484 -715 -86 - - -866 -2036 -86 - - -2167 -2960 -86 - - -3202 -4443 -86 - - -4720 -6423 -86 - - -6723 -13439 -86 - - -17876 -100489 -86 - - -114342 -428357 -54 - - - - - - -kind -location - - -12 - - -1 -4 -97 - - -4 -14 -97 - - -14 -24 -86 - - -24 -38 -86 - - -38 -134 -86 - - -144 -259 -86 - - -270 -481 -86 - - -481 -1076 -86 - - -1099 -1408 -86 - - -1427 -2051 -86 - - -2060 -4561 -86 - - -5889 -59193 -86 - - -60309 -118611 -32 - - - - - - -location -id - - -12 - - -1 -2 -1649719 - - -2 -3 -725837 - - -3 -4 -318788 - - -4 -5 -272431 - - -5 -9 -311028 - - -9 -45 -269006 - - -45 -143462 -39106 - - - - - - -location -kind - - -12 - - -1 -2 -2542158 - - -2 -3 -786154 - - -3 -30 -257604 - - - - - - - - -expr_types -18609954 - - -id -18457486 - - -typeid -1280368 - - -value_category -32 - - - - -id -typeid - - -12 - - -1 -2 -18306730 - - -2 -4 -150755 - - - - - - -id -value_category - - -12 - - -1 -2 -18457486 - - - - - - -typeid -id - - -12 - - -1 -2 -468861 - - -2 -3 -252672 - - -3 -4 -107476 - - -4 -5 -88617 - - -5 -8 -114110 - - -8 -13 -96724 - - -13 -36 -97331 - - -36 -126306 -54572 - - - - - - -typeid -value_category - - -12 - - -1 -2 -1115749 - - -2 -3 -155026 - - -3 -4 -9592 - - - - - - -value_category -id - - -12 - - -7302 -7303 -10 - - -383285 -383286 -10 - - -1312333 -1312334 -10 - - - - - - -value_category -typeid - - -12 - - -1649 -1650 -10 - - -32129 -32130 -10 - - -100424 -100425 -10 - - - - - - - - -new_allocated_type -31757 - - -expr -31757 - - -type_id -16323 - - - - -expr -type_id - - -12 - - -1 -2 -31757 - - - - - - -type_id -expr - - -12 - - -1 -2 -10220 - - -2 -3 -3674 - - -3 -5 -1387 - - -5 -107 -1040 - - - - - - - - -new_array_allocated_type -5287 - - -expr -5287 - - -type_id -2273 - - - - -expr -type_id - - -12 - - -1 -2 -5287 - - - - - - -type_id -expr - - -12 - - -1 -2 -32 - - -2 -3 -2013 - - -3 -7 -175 - - -8 -15 -51 - - - - - - - - -aggregate_field_init -4011083 - - -aggregate -849492 - - -initializer -4010900 - - -field -2207 - - - - -aggregate -initializer - - -12 - - -1 -2 -6536 - - -2 -3 -501609 - - -3 -4 -11344 - - -4 -5 -88845 - - -5 -12 -49882 - - -12 -13 -191083 - - -13 -42 -193 - - - - - - -aggregate -field - - -12 - - -1 -2 -6535 - - -2 -3 -501577 - - -3 -4 -11344 - - -4 -5 -88851 - - -5 -12 -49908 - - -12 -13 -191083 - - -13 -42 -194 - - - - - - -initializer -aggregate - - -12 - - -1 -2 -4010900 - - - - - - -initializer -field - - -12 - - -1 -2 -4010717 - - -2 -3 -183 - - - - - - -field -aggregate - - -12 - - -1 -2 -814 - - -2 -3 -194 - - -3 -7 -194 - - -7 -13 -174 - - -13 -22 -176 - - -22 -47 -168 - - -49 -113 -166 - - -115 -410 -168 - - -417 -288626 -153 - - - - - - -field -initializer - - -12 - - -1 -2 -814 - - -2 -3 -194 - - -3 -7 -194 - - -7 -13 -174 - - -13 -22 -176 - - -22 -47 -168 - - -49 -113 -166 - - -115 -410 -168 - - -417 -288626 -153 - - - - - - - - -aggregate_array_init -731690 - - -aggregate -65759 - - -initializer -731690 - - -element_index -17485 - - - - -aggregate -initializer - - -12 - - -1 -2 -7541 - - -2 -3 -7819 - - -3 -4 -17355 - - -4 -5 -8024 - - -5 -6 -5817 - - -6 -8 -5016 - - -8 -11 -5394 - - -11 -22 -5004 - - -22 -17486 -3789 - - - - - - -aggregate -element_index - - -12 - - -1 -2 -7541 - - -2 -3 -7819 - - -3 -4 -17355 - - -4 -5 -8024 - - -5 -6 -5817 - - -6 -8 -5016 - - -8 -11 -5394 - - -11 -22 -5004 - - -22 -17486 -3789 - - - - - - -initializer -aggregate - - -12 - - -1 -2 -731690 - - - - - - -initializer -element_index - - -12 - - -1 -2 -731690 - - - - - - -element_index -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 -65759 -314 - - - - - - -element_index -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 -65759 -314 - - - - - - - - -condition_decl_bind -6947 - - -expr -6947 - - -decl -6947 - - - - -expr -decl - - -12 - - -1 -2 -6947 - - - - - - -decl -expr - - -12 - - -1 -2 -6947 - - - - - - - - -typeid_bind -4368 - - -expr -4368 - - -type_id -2319 - - - - -expr -type_id - - -12 - - -1 -2 -4368 - - - - - - -type_id -expr - - -12 - - -1 -2 -1159 - - -2 -3 -888 - - -3 -6 -205 - - -6 -17 -65 - - - - - - - - -uuidof_bind -844 - - -expr -844 - - -type_id -643 - - - - -expr -type_id - - -12 - - -1 -2 -844 - - - - - - -type_id -expr - - -12 - - -1 -2 -474 - - -2 -3 -136 - - -3 -4 -32 - - - - - - - - -sizeof_bind -157116 - - -expr -157116 - - -type_id -2704 - - - - -expr -type_id - - -12 - - -1 -2 -157116 - - - - - - -type_id -expr - - -12 - - -1 -2 -1063 - - -2 -3 -356 - - -3 -4 -202 - - -4 -9 -202 - - -9 -32 -129 - - -34 -36 -233 - - -36 -68 -202 - - -68 -114 -202 - - -119 -6844 -110 - - - - - - - - -code_block -15 - - -block -15 - - -routine -15 - - - - -block -routine - - -12 - - -1 -2 -15 - - - - - - -routine -block - - -12 - - -1 -2 -15 - - - - - - - - -lambdas -12660 - - -expr -12660 - - -default_capture -19 - - -has_explicit_return_type -12 - - - - -expr -default_capture - - -12 - - -1 -2 -12660 - - - - - - -expr -has_explicit_return_type - - -12 - - -1 -2 -12660 - - - - - - -default_capture -expr - - -12 - - -278 -279 -6 - - -700 -701 -6 - - -971 -972 -6 - - - - - - -default_capture -has_explicit_return_type - - -12 - - -2 -3 -19 - - - - - - -has_explicit_return_type -expr - - -12 - - -832 -833 -6 - - -1117 -1118 -6 - - - - - - -has_explicit_return_type -default_capture - - -12 - - -3 -4 -12 - - - - - - - - -lambda_capture -21618 - - -id -21618 - - -lambda -10153 - - -index -110 - - -field -21618 - - -captured_by_reference -12 - - -is_implicit -12 - - -location -13849 - - - - -id -lambda - - -12 - - -1 -2 -21618 - - - - - - -id -index - - -12 - - -1 -2 -21618 - - - - - - -id -field - - -12 - - -1 -2 -21618 - - - - - - -id -captured_by_reference - - -12 - - -1 -2 -21618 - - - - - - -id -is_implicit - - -12 - - -1 -2 -21618 - - - - - - -id -location - - -12 - - -1 -2 -21618 - - - - - - -lambda -id - - -12 - - -1 -2 -5131 - - -2 -3 -2345 - - -3 -4 -1247 - - -4 -6 -909 - - -6 -18 -519 - - - - - - -lambda -index - - -12 - - -1 -2 -5131 - - -2 -3 -2345 - - -3 -4 -1247 - - -4 -6 -909 - - -6 -18 -519 - - - - - - -lambda -field - - -12 - - -1 -2 -5131 - - -2 -3 -2345 - - -3 -4 -1247 - - -4 -6 -909 - - -6 -18 -519 - - - - - - -lambda -captured_by_reference - - -12 - - -1 -2 -9691 - - -2 -3 -461 - - - - - - -lambda -is_implicit - - -12 - - -1 -2 -10133 - - -2 -3 -19 - - - - - - -lambda -location - - -12 - - -1 -2 -5606 - - -2 -3 -2468 - - -3 -4 -1026 - - -4 -7 -811 - - -7 -18 -240 - - - - - - -index -id - - -12 - - -1 -2 -6 - - -2 -3 -6 - - -3 -4 -6 - - -4 -5 -6 - - -6 -7 -6 - - -10 -11 -6 - - -12 -13 -6 - - -16 -17 -6 - - -18 -19 -6 - - -23 -24 -6 - - -45 -46 -6 - - -80 -81 -6 - - -140 -141 -6 - - -220 -221 -6 - - -412 -413 -6 - - -773 -774 -6 - - -1563 -1564 -6 - - - - - - -index -lambda - - -12 - - -1 -2 -6 - - -2 -3 -6 - - -3 -4 -6 - - -4 -5 -6 - - -6 -7 -6 - - -10 -11 -6 - - -12 -13 -6 - - -16 -17 -6 - - -18 -19 -6 - - -23 -24 -6 - - -45 -46 -6 - - -80 -81 -6 - - -140 -141 -6 - - -220 -221 -6 - - -412 -413 -6 - - -773 -774 -6 - - -1563 -1564 -6 - - - - - - -index -field - - -12 - - -1 -2 -6 - - -2 -3 -6 - - -3 -4 -6 - - -4 -5 -6 - - -6 -7 -6 - - -10 -11 -6 - - -12 -13 -6 - - -16 -17 -6 - - -18 -19 -6 - - -23 -24 -6 - - -45 -46 -6 - - -80 -81 -6 - - -140 -141 -6 - - -220 -221 -6 - - -412 -413 -6 - - -773 -774 -6 - - -1563 -1564 -6 - - - - - - -index -captured_by_reference - - -12 - - -1 -2 -25 - - -2 -3 -84 - - - - - - -index -is_implicit - - -12 - - -1 -2 -64 - - -2 -3 -45 - - - - - - -index -location - - -12 - - -1 -2 -6 - - -2 -3 -6 - - -3 -4 -6 - - -4 -5 -6 - - -6 -7 -6 - - -9 -10 -6 - - -11 -12 -6 - - -14 -15 -6 - - -16 -17 -6 - - -21 -22 -6 - - -40 -41 -6 - - -64 -65 -6 - - -99 -100 -6 - - -176 -177 -6 - - -349 -350 -6 - - -589 -590 -6 - - -932 -933 -6 - - - - - - -field -id - - -12 - - -1 -2 -21618 - - - - - - -field -lambda - - -12 - - -1 -2 -21618 - - - - - - -field -index - - -12 - - -1 -2 -21618 - - - - - - -field -captured_by_reference - - -12 - - -1 -2 -21618 - - - - - - -field -is_implicit - - -12 - - -1 -2 -21618 - - - - - - -field -location - - -12 - - -1 -2 -21618 - - - - - - -captured_by_reference -id - - -12 - - -1201 -1202 -6 - - -2127 -2128 -6 - - - - - - -captured_by_reference -lambda - - -12 - - -613 -614 -6 - - -1021 -1022 -6 - - - - - - -captured_by_reference -index - - -12 - - -13 -14 -6 - - -17 -18 -6 - - - - - - -captured_by_reference -field - - -12 - - -1201 -1202 -6 - - -2127 -2128 -6 - - - - - - -captured_by_reference -is_implicit - - -12 - - -2 -3 -12 - - - - - - -captured_by_reference -location - - -12 - - -544 -545 -6 - - -1591 -1592 -6 - - - - - - -is_implicit -id - - -12 - - -848 -849 -6 - - -2480 -2481 -6 - - - - - - -is_implicit -lambda - - -12 - - -637 -638 -6 - - -929 -930 -6 - - - - - - -is_implicit -index - - -12 - - -7 -8 -6 - - -17 -18 -6 - - - - - - -is_implicit -field - - -12 - - -848 -849 -6 - - -2480 -2481 -6 - - - - - - -is_implicit -captured_by_reference - - -12 - - -2 -3 -12 - - - - - - -is_implicit -location - - -12 - - -330 -331 -6 - - -1802 -1803 -6 - - - - - - -location -id - - -12 - - -1 -2 -12485 - - -2 -6 -1039 - - -6 -68 -324 - - - - - - -location -lambda - - -12 - - -1 -2 -12926 - - -2 -68 -922 - - - - - - -location -index - - -12 - - -1 -2 -13316 - - -2 -8 -532 - - - - - - -location -field - - -12 - - -1 -2 -12485 - - -2 -6 -1039 - - -6 -68 -324 - - - - - - -location -captured_by_reference - - -12 - - -1 -2 -13829 - - -2 -3 -19 - - - - - - -location -is_implicit - - -12 - - -1 -2 -13849 - - - - - - - - -fold -4 - - -expr -4 - - -operator -4 - - -is_left_fold -2 - - - - -expr -operator - - -12 - - -1 -2 -4 - - - - - - -expr -is_left_fold - - -12 - - -1 -2 -4 - - - - - - -operator -expr - - -12 - - -1 -2 -4 - - - - - - -operator -is_left_fold - - -12 - - -1 -2 -4 - - - - - - -is_left_fold -expr - - -12 - - -2 -3 -2 - - - - - - -is_left_fold -operator - - -12 - - -2 -3 -2 - - - - - - - - -stmts -4651977 - - -id -4651977 - - -kind -116 - - -location -2016407 - - - - -id -kind - - -12 - - -1 -2 -4651977 - - - - - - -id -location - - -12 - - -1 -2 -4651977 - - - - - - -kind -id - - -12 - - -26 -27 -6 - - -553 -554 -6 - - -828 -829 -6 - - -1443 -1444 -6 - - -1582 -1583 -6 - - -1908 -1909 -6 - - -2445 -2446 -6 - - -3327 -3328 -6 - - -3570 -3571 -6 - - -4942 -4943 -6 - - -15732 -15733 -6 - - -15997 -15998 -6 - - -20983 -20984 -6 - - -68504 -68505 -6 - - -87453 -87454 -6 - - -109229 -109230 -6 - - -182456 -182457 -6 - - -195155 -195156 -6 - - - - - - -kind -location - - -12 - - -26 -27 -6 - - -414 -415 -6 - - -785 -786 -6 - - -1053 -1054 -6 - - -1285 -1286 -6 - - -1329 -1330 -6 - - -1370 -1371 -6 - - -2027 -2028 -6 - - -2301 -2302 -6 - - -2430 -2431 -6 - - -6908 -6909 -6 - - -8367 -8368 -6 - - -10976 -10977 -6 - - -36004 -36005 -6 - - -42618 -42619 -6 - - -45224 -45225 -6 - - -80548 -80549 -6 - - -96139 -96140 -6 - - - - - - -location -id - - -12 - - -1 -2 -1715650 - - -2 -4 -176807 - - -4 -1671 -123949 - - - - - - -location -kind - - -12 - - -1 -2 -1952279 - - -2 -10 -64128 - - - - - - - - -type_vla -1 - - -type_id -1 - - -decl -1 - - - - -type_id -decl - - -12 - - -1 -2 -1 - - - - - - -decl -type_id - - -12 - - -1 -2 -1 - - - - - - - - -variable_vla -8 - - -var -8 - - -decl -8 - - - - -var -decl - - -12 - - -1 -2 -8 - - - - - - -decl -var - - -12 - - -1 -2 -8 - - - - - - - - -if_then -524673 - - -if_stmt -524673 - - -then_id -524673 - - - - -if_stmt -then_id - - -12 - - -1 -2 -524673 - - - - - - -then_id -if_stmt - - -12 - - -1 -2 -524673 - - - - - - - - -if_else -148314 - - -if_stmt -148314 - - -else_id -148314 - - - - -if_stmt -else_id - - -12 - - -1 -2 -148314 - - - - - - -else_id -if_stmt - - -12 - - -1 -2 -148314 - - - - - - - - -constexpr_if_then -3 - - -constexpr_if_stmt -3 - - -then_id -3 - - - - -constexpr_if_stmt -then_id - - -12 - - -1 -2 -3 - - - - - - -then_id -constexpr_if_stmt - - -12 - - -1 -2 -3 - - - - - - - - -constexpr_if_else -1 - - -constexpr_if_stmt -1 - - -else_id -1 - - - - -constexpr_if_stmt -else_id - - -12 - - -1 -2 -1 - - - - - - -else_id -constexpr_if_stmt - - -12 - - -1 -2 -1 - - - - - - - - -while_body -30641 - - -while_stmt -30641 - - -body_id -30641 - - - - -while_stmt -body_id - - -12 - - -1 -2 -30641 - - - - - - -body_id -while_stmt - - -12 - - -1 -2 -30641 - - - - - - - - -do_body -149931 - - -do_stmt -149931 - - -body_id -149931 - - - - -do_stmt -body_id - - -12 - - -1 -2 -149931 - - - - - - -body_id -do_stmt - - -12 - - -1 -2 -149931 - - - - - - - - -switch_case -271721 - - -switch_stmt -53308 - - -index -264 - - -case_id -271721 - - - - -switch_stmt -index - - -12 - - -1 -5 -4059 - - -5 -6 -47188 - - -6 -163 -2060 - - - - - - -switch_stmt -case_id - - -12 - - -1 -5 -4059 - - -5 -6 -47188 - - -6 -163 -2060 - - - - - - -index -switch_stmt - - -12 - - -1 -2 -138 - - -2 -5 -22 - - -6 -17 -24 - - -17 -36 -21 - - -36 -86 -21 - - -91 -474 -21 - - -606 -32709 -14 - - - - - - -index -case_id - - -12 - - -1 -2 -138 - - -2 -5 -22 - - -6 -17 -24 - - -17 -36 -21 - - -36 -86 -21 - - -91 -474 -21 - - -606 -32709 -14 - - - - - - -case_id -switch_stmt - - -12 - - -1 -2 -271721 - - - - - - -case_id -index - - -12 - - -1 -2 -271721 - - - - - - - - -switch_body -53308 - - -switch_stmt -53308 - - -body_id -53308 - - - - -switch_stmt -body_id - - -12 - - -1 -2 -53308 - - - - - - -body_id -switch_stmt - - -12 - - -1 -2 -53308 - - - - - - - - -for_initialization -29667 - - -for_stmt -29667 - - -init_id -29667 - - - - -for_stmt -init_id - - -12 - - -1 -2 -29667 - - - - - - -init_id -for_stmt - - -12 - - -1 -2 -29667 - - - - - - - - -for_condition -31505 - - -for_stmt -31505 - - -condition_id -31505 - - - - -for_stmt -condition_id - - -12 - - -1 -2 -31505 - - - - - - -condition_id -for_stmt - - -12 - - -1 -2 -31505 - - - - - - - - -for_update -29407 - - -for_stmt -29407 - - -update_id -29407 - - - - -for_stmt -update_id - - -12 - - -1 -2 -29407 - - - - - - -update_id -for_stmt - - -12 - - -1 -2 -29407 - - - - - - - - -for_body -32103 - - -for_stmt -32103 - - -body_id -32103 - - - - -for_stmt -body_id - - -12 - - -1 -2 -32103 - - - - - - -body_id -for_stmt - - -12 - - -1 -2 -32103 - - - - - - - - -stmtparents -4113351 - - -id -4113351 - - -index -12615 - - -parent -1738665 - - - - -id -index - - -12 - - -1 -2 -4113351 - - - - - - -id -parent - - -12 - - -1 -2 -4113351 - - - - - - -index -id - - -12 - - -1 -2 -3962 - - -2 -3 -1078 - - -3 -4 -513 - - -4 -5 -1474 - - -7 -8 -1032 - - -8 -12 -818 - - -12 -29 -1110 - - -29 -37 -896 - - -37 -74 -961 - - -74 -192180 -766 - - - - - - -index -parent - - -12 - - -1 -2 -3962 - - -2 -3 -1078 - - -3 -4 -513 - - -4 -5 -1474 - - -7 -8 -1032 - - -8 -12 -818 - - -12 -29 -1110 - - -29 -37 -896 - - -37 -74 -961 - - -74 -192180 -766 - - - - - - -parent -id - - -12 - - -1 -2 -990323 - - -2 -3 -382079 - - -3 -4 -108209 - - -4 -6 -113841 - - -6 -17 -131575 - - -17 -1943 -12634 - - - - - - -parent -index - - -12 - - -1 -2 -990323 - - -2 -3 -382079 - - -3 -4 -108209 - - -4 -6 -113841 - - -6 -17 -131575 - - -17 -1943 -12634 - - - - - - - - -ishandler -21612 - - -block -21612 - - - - - -stmt_decl_bind -531383 - - -stmt -524523 - - -num -51 - - -decl -531383 - - - - -stmt -num - - -12 - - -1 -2 -519092 - - -2 -9 -5430 - - - - - - -stmt -decl - - -12 - - -1 -2 -519073 - - -2 -9 -5450 - - - - - - -num -stmt - - -12 - - -1 -2 -6 - - -4 -5 -6 - - -7 -8 -6 - - -9 -10 -6 - - -24 -25 -6 - - -172 -173 -6 - - -836 -837 -6 - - -80746 -80747 -6 - - - - - - -num -decl - - -12 - - -1 -2 -6 - - -4 -5 -6 - - -7 -8 -6 - - -9 -10 -6 - - -24 -25 -6 - - -172 -173 -6 - - -836 -837 -6 - - -80749 -80750 -6 - - - - - - -decl -stmt - - -12 - - -1 -2 -531383 - - - - - - -decl -num - - -12 - - -1 -2 -531383 - - - - - - - - -stmt_decl_entry_bind -498005 - - -stmt -454241 - - -num -444 - - -decl_entry -474016 - - - - -stmt -num - - -12 - - -1 -2 -422673 - - -2 -274 -31568 - - - - - - -stmt -decl_entry - - -12 - - -1 -2 -422673 - - -2 -15 -31568 - - - - - - -num -stmt - - -12 - - -8 -9 -6 - - -11 -12 -213 - - -13 -14 -1 - - -15 -16 -190 - - -17 -278706 -32 - - - - - - -num -decl_entry - - -12 - - -8 -9 -6 - - -11 -12 -213 - - -13 -14 -190 - - -15 -267734 -34 - - - - - - -decl_entry -stmt - - -12 - - -1 -2 -462337 - - -2 -17 -11679 - - - - - - -decl_entry -num - - -12 - - -1 -2 -473936 - - -2 -273 -79 - - - - - - - - -blockscope -1309621 - - -block -1309621 - - -enclosing -1173021 - - - - -block -enclosing - - -12 - - -1 -2 -1309621 - - - - - - -enclosing -block - - -12 - - -1 -2 -1093573 - - -2 -509 -79447 - - - - - - - - -jumpinfo -351037 - - -id -351037 - - -str -5914 - - -target -81577 - - - - -id -str - - -12 - - -1 -2 -351037 - - - - - - -id -target - - -12 - - -1 -2 -351037 - - - - - - -str -id - - -12 - - -2 -3 -3212 - - -3 -4 -796 - - -4 -5 -686 - - -5 -7 -487 - - -7 -15 -459 - - -15 -181398 -272 - - - - - - -str -target - - -12 - - -1 -2 -4703 - - -2 -3 -674 - - -3 -12 -456 - - -12 -38931 -79 - - - - - - -target -id - - -12 - - -1 -2 -254 - - -2 -3 -19879 - - -3 -4 -7102 - - -4 -5 -3572 - - -5 -6 -38447 - - -6 -7 -10579 - - -7 -166 -1742 - - - - - - -target -str - - -12 - - -1 -2 -81577 - - - - - - - - -preprocdirects -1308115 - - -id -1308115 - - -kind -140 - - -location -1301872 - - - - -id -kind - - -12 - - -1 -2 -1308115 - - - - - - -id -location - - -12 - - -1 -2 -1308115 - - - - - - -kind -id - - -12 - - -4 -5 -10 - - -8 -9 -10 - - -500 -501 -10 - - -967 -968 -10 - - -1755 -1756 -10 - - -1881 -1882 -10 - - -5258 -5259 -10 - - -5570 -5571 -10 - - -7598 -7599 -10 - - -14233 -14234 -10 - - -26512 -26513 -10 - - -27401 -27402 -10 - - -29002 -29003 -10 - - - - - - -kind -location - - -12 - - -4 -5 -10 - - -7 -8 -10 - - -500 -501 -10 - - -967 -968 -10 - - -1755 -1756 -10 - - -1881 -1882 -10 - - -5258 -5259 -10 - - -5570 -5571 -10 - - -7598 -7599 -10 - - -14233 -14234 -10 - - -26170 -26171 -10 - - -27401 -27402 -10 - - -28769 -28770 -10 - - - - - - -location -id - - -12 - - -1 -2 -1301546 - - -2 -235 -325 - - - - - - -location -kind - - -12 - - -1 -2 -1301872 - - - - - - - - -preprocpair -374369 - - -begin -296991 - - -elseelifend -374369 - - - - -begin -elseelifend - - -12 - - -1 -2 -235829 - - -2 -3 -53911 - - -3 -53 -7251 - - - - - - -elseelifend -begin - - -12 - - -1 -2 -374369 - - - - - - - - -preproctrue -164618 - - -branch -164618 - - - - - -preprocfalse -117730 - - -branch -117730 - - - - - -preproctext -954122 - - -id -954122 - - -head -458142 - - -body -173528 - - - - -id -head - - -12 - - -1 -2 -954122 - - - - - - -id -body - - -12 - - -1 -2 -954122 - - - - - - -head -id - - -12 - - -1 -2 -341918 - - -2 -3 -77258 - - -3 -19 -34369 - - -19 -752 -4595 - - - - - - -head -body - - -12 - - -1 -2 -436714 - - -2 -38 -21428 - - - - - - -body -id - - -12 - - -1 -2 -163079 - - -2 -64816 -10448 - - - - - - -body -head - - -12 - - -1 -2 -164542 - - -2 -21810 -8985 - - - - - - - - -includes -287443 - - -id -287443 - - -included -53966 - - - - -id -included - - -12 - - -1 -2 -287443 - - - - - - -included -id - - -12 - - -1 -2 -26576 - - -2 -3 -8855 - - -3 -4 -4563 - - -4 -6 -4790 - - -6 -11 -4140 - - -11 -41 -4064 - - -41 -763 -975 - - - - - - - - -link_targets -574 - - -id -574 - - -binary -574 - - - - -id -binary - - -12 - - -1 -2 -574 - - - - - - -binary -id - - -12 - - -1 -2 -574 - - - - - - - - -link_parent -18584884 - - -element -5164827 - - -link_target -574 - - - - -element -link_target - - -12 - - -1 -2 -1543684 - - -2 -3 -1943264 - - -3 -4 -754223 - - -4 -6 -422385 - - -6 -29 -402680 - - -29 -45 -98589 - - - - - - -link_target -element - - -12 - - -2 -3 -86 - - -5 -559 -43 - - -2834 -6256 -43 - - -6663 -8713 -43 - - -10268 -13146 -43 - - -13433 -20518 -43 - - -25549 -27566 -43 - - -27680 -33162 -43 - - -34917 -40444 -43 - - -42525 -46022 -43 - - -47794 -58086 -43 - - -58594 -139377 -43 - - -388296 -388297 -10 - - - - - - - - -xmlEncoding -39724 - - -id -39724 - - -encoding -1 - - - - -id -encoding - - -12 - - -1 -2 -39724 - - - - - - -encoding -id - - -12 - - -39724 -39725 -1 - - - - - - - - -xmlDTDs -1 - - -id -1 - - -root -1 - - -publicId -1 - - -systemId -1 - - -fileid -1 - - - - -id -root - - -12 - - -1 -2 -1 - - - - - - -id -publicId - - -12 - - -1 -2 -1 - - - - - - -id -systemId - - -12 - - -1 -2 -1 - - - - - - -id -fileid - - -12 - - -1 -2 -1 - - - - - - -root -id - - -12 - - -1 -2 -1 - - - - - - -root -publicId - - -12 - - -1 -2 -1 - - - - - - -root -systemId - - -12 - - -1 -2 -1 - - - - - - -root -fileid - - -12 - - -1 -2 -1 - - - - - - -publicId -id - - -12 - - -1 -2 -1 - - - - - - -publicId -root - - -12 - - -1 -2 -1 - - - - - - -publicId -systemId - - -12 - - -1 -2 -1 - - - - - - -publicId -fileid - - -12 - - -1 -2 -1 - - - - - - -systemId -id - - -12 - - -1 -2 -1 - - - - - - -systemId -root - - -12 - - -1 -2 -1 - - - - - - -systemId -publicId - - -12 - - -1 -2 -1 - - - - - - -systemId -fileid - - -12 - - -1 -2 -1 - - - - - - -fileid -id - - -12 - - -1 -2 -1 - - - - - - -fileid -root - - -12 - - -1 -2 -1 - - - - - - -fileid -publicId - - -12 - - -1 -2 -1 - - - - - - -fileid -systemId - - -12 - - -1 -2 -1 - - - - - - - - -xmlElements -1270313 - - -id -1270313 - - -name -4655 - - -parentid -578021 - - -idx -35122 - - -fileid -39721 - - - - -id -name - - -12 - - -1 -2 -1270313 - - - - - - -id -parentid - - -12 - - -1 -2 -1270313 - - - - - - -id -idx - - -12 - - -1 -2 -1270313 - - - - - - -id -fileid - - -12 - - -1 -2 -1270313 - - - - - - -name -id - - -12 - - -1 -2 -420 - - -2 -5 -156 - - -5 -6 -3832 - - -6 -310317 -247 - - - - - - -name -parentid - - -12 - - -1 -2 -456 - - -2 -5 -150 - - -5 -6 -3829 - - -6 -161565 -220 - - - - - - -name -idx - - -12 - - -1 -2 -4358 - - -2 -35123 -297 - - - - - - -name -fileid - - -12 - - -1 -2 -486 - - -2 -5 -133 - - -5 -6 -3831 - - -6 -14503 -205 - - - - - - -parentid -id - - -12 - - -1 -2 -371969 - - -2 -3 -62095 - - -3 -4 -104113 - - -4 -35123 -39844 - - - - - - -parentid -name - - -12 - - -1 -2 -500482 - - -2 -3 -17866 - - -3 -4 -49117 - - -4 -45 -10556 - - - - - - -parentid -idx - - -12 - - -1 -2 -371969 - - -2 -3 -62095 - - -3 -4 -104113 - - -4 -35123 -39844 - - - - - - -parentid -fileid - - -12 - - -1 -2 -578021 - - - - - - -idx -id - - -12 - - -2 -3 -606 - - -4 -5 -17851 - - -5 -6 -6533 - - -6 -7 -859 - - -7 -8 -4471 - - -9 -16 -2719 - - -16 -578022 -2083 - - - - - - -idx -name - - -12 - - -1 -2 -18457 - - -2 -3 -6533 - - -3 -4 -6178 - - -4 -8 -2624 - - -8 -4397 -1330 - - - - - - -idx -parentid - - -12 - - -2 -3 -606 - - -4 -5 -17851 - - -5 -6 -6533 - - -6 -7 -859 - - -7 -8 -4471 - - -9 -16 -2719 - - -16 -578022 -2083 - - - - - - -idx -fileid - - -12 - - -2 -3 -606 - - -4 -5 -17851 - - -5 -6 -6533 - - -6 -7 -859 - - -7 -8 -4471 - - -9 -16 -2719 - - -16 -39722 -2083 - - - - - - -fileid -id - - -12 - - -1 -2 -20457 - - -2 -3 -3115 - - -3 -7 -3026 - - -7 -8 -3588 - - -8 -9 -2220 - - -9 -11 -3099 - - -11 -19 -3087 - - -19 -114506 -1129 - - - - - - -fileid -name - - -12 - - -1 -2 -20459 - - -2 -3 -3458 - - -3 -5 -2569 - - -5 -7 -2172 - - -7 -8 -6158 - - -8 -9 -3501 - - -9 -46 -1404 - - - - - - -fileid -parentid - - -12 - - -1 -2 -20457 - - -2 -3 -3870 - - -3 -5 -2152 - - -5 -6 -2876 - - -6 -7 -2720 - - -7 -8 -4132 - - -8 -14 -3096 - - -14 -31079 -418 - - - - - - -fileid -idx - - -12 - - -1 -2 -25894 - - -2 -3 -5301 - - -3 -4 -3787 - - -4 -6 -3268 - - -6 -35123 -1471 - - - - - - - - -xmlAttrs -1202020 - - -id -1202020 - - -elementid -760198 - - -name -3649 - - -value -121803 - - -idx -2000 - - -fileid -39448 - - - - -id -elementid - - -12 - - -1 -2 -1202020 - - - - - - -id -name - - -12 - - -1 -2 -1202020 - - - - - - -id -value - - -12 - - -1 -2 -1202020 - - - - - - -id -idx - - -12 - - -1 -2 -1202020 - - - - - - -id -fileid - - -12 - - -1 -2 -1202020 - - - - - - -elementid -id - - -12 - - -1 -2 -425697 - - -2 -3 -249659 - - -3 -4 -66474 - - -4 -2001 -18368 - - - - - - -elementid -name - - -12 - - -1 -2 -425778 - - -2 -3 -249579 - - -3 -4 -66475 - - -4 -2001 -18366 - - - - - - -elementid -value - - -12 - - -1 -2 -466237 - - -2 -3 -266291 - - -3 -46 -27670 - - - - - - -elementid -idx - - -12 - - -1 -2 -425697 - - -2 -3 -249659 - - -3 -4 -66474 - - -4 -2001 -18368 - - - - - - -elementid -fileid - - -12 - - -1 -2 -760198 - - - - - - -name -id - - -12 - - -1 -2 -3467 - - -2 -262475 -182 - - - - - - -name -elementid - - -12 - - -1 -2 -3467 - - -2 -262475 -182 - - - - - - -name -value - - -12 - - -1 -2 -3501 - - -2 -54146 -148 - - - - - - -name -idx - - -12 - - -1 -2 -3531 - - -2 -11 -118 - - - - - - -name -fileid - - -12 - - -1 -2 -3491 - - -2 -21768 -158 - - - - - - -value -id - - -12 - - -1 -2 -72032 - - -2 -3 -42366 - - -3 -199269 -7405 - - - - - - -value -elementid - - -12 - - -1 -2 -72036 - - -2 -3 -42374 - - -3 -199269 -7393 - - - - - - -value -name - - -12 - - -1 -2 -116722 - - -2 -2041 -5081 - - - - - - -value -idx - - -12 - - -1 -2 -117957 - - -2 -2001 -3846 - - - - - - -value -fileid - - -12 - - -1 -2 -86306 - - -2 -3 -28570 - - -3 -4175 -6927 - - - - - - -idx -id - - -12 - - -1 -2 -1955 - - -2 -760199 -45 - - - - - - -idx -elementid - - -12 - - -1 -2 -1955 - - -2 -760199 -45 - - - - - - -idx -name - - -12 - - -1 -2 -1955 - - -2 -189 -45 - - - - - - -idx -value - - -12 - - -1 -2 -1955 - - -2 -116643 -45 - - - - - - -idx -fileid - - -12 - - -1 -2 -1955 - - -2 -39449 -45 - - - - - - -fileid -id - - -12 - - -1 -2 -22884 - - -2 -4 -2565 - - -4 -6 -2294 - - -6 -7 -3299 - - -7 -9 -3272 - - -9 -16 -3143 - - -16 -129952 -1991 - - - - - - -fileid -elementid - - -12 - - -1 -2 -23890 - - -2 -4 -2131 - - -4 -5 -1971 - - -5 -6 -4096 - - -6 -8 -3519 - - -8 -16 -3137 - - -16 -106600 -704 - - - - - - -fileid -name - - -12 - - -1 -2 -22946 - - -2 -3 -2338 - - -3 -4 -2726 - - -4 -5 -2824 - - -5 -6 -2994 - - -6 -7 -3876 - - -7 -2002 -1744 - - - - - - -fileid -value - - -12 - - -1 -2 -22916 - - -2 -4 -2772 - - -4 -5 -2112 - - -5 -6 -3510 - - -6 -8 -1993 - - -8 -11 -3365 - - -11 -50357 -2780 - - - - - - -fileid -idx - - -12 - - -1 -2 -26133 - - -2 -3 -9699 - - -3 -5 -3511 - - -5 -2001 -105 - - - - - - - - -xmlNs -71201 - - -id -4185 - - -prefixName -958 - - -URI -4185 - - -fileid -39544 - - - - -id -prefixName - - -12 - - -1 -2 -2602 - - -2 -3 -1553 - - -3 -872 -30 - - - - - - -id -URI - - -12 - - -1 -2 -4185 - - - - - - -id -fileid - - -12 - - -1 -6 -274 - - -6 -7 -3825 - - -7 -24905 -86 - - - - - - -prefixName -id - - -12 - - -1 -2 -915 - - -2 -4054 -43 - - - - - - -prefixName -URI - - -12 - - -1 -2 -915 - - -2 -4054 -43 - - - - - - -prefixName -fileid - - -12 - - -1 -2 -828 - - -2 -5 -73 - - -5 -24903 -57 - - - - - - -URI -id - - -12 - - -1 -2 -4185 - - - - - - -URI -prefixName - - -12 - - -1 -2 -2602 - - -2 -3 -1553 - - -3 -872 -30 - - - - - - -URI -fileid - - -12 - - -1 -6 -274 - - -6 -7 -3825 - - -7 -24905 -86 - - - - - - -fileid -id - - -12 - - -1 -2 -11655 - - -2 -3 -26146 - - -3 -8 -1743 - - - - - - -fileid -prefixName - - -12 - - -1 -2 -11653 - - -2 -3 -25982 - - -3 -31 -1909 - - - - - - -fileid -URI - - -12 - - -1 -2 -11655 - - -2 -3 -26146 - - -3 -8 -1743 - - - - - - - - -xmlHasNs -1139730 - - -elementId -1139730 - - -nsId -4136 - - -fileid -39537 - - - - -elementId -nsId - - -12 - - -1 -2 -1139730 - - - - - - -elementId -fileid - - -12 - - -1 -2 -1139730 - - - - - - -nsId -elementId - - -12 - - -1 -5 -234 - - -5 -6 -3824 - - -6 -643289 -78 - - - - - - -nsId -fileid - - -12 - - -1 -5 -257 - - -5 -6 -3823 - - -6 -24759 -56 - - - - - - -fileid -elementId - - -12 - - -1 -2 -3669 - - -2 -3 -20429 - - -3 -7 -2536 - - -7 -8 -3473 - - -8 -9 -2258 - - -9 -11 -3036 - - -11 -18 -2966 - - -18 -147552 -1170 - - - - - - -fileid -nsId - - -12 - - -1 -2 -18261 - - -2 -3 -21032 - - -3 -8 -244 - - - - - - - - -xmlComments -26812 - - -id -26812 - - -text -22933 - - -parentid -26546 - - -fileid -26368 - - - - -id -text - - -12 - - -1 -2 -26812 - - - - - - -id -parentid - - -12 - - -1 -2 -26812 - - - - - - -id -fileid - - -12 - - -1 -2 -26812 - - - - - - -text -id - - -12 - - -1 -2 -21517 - - -2 -62 -1416 - - - - - - -text -parentid - - -12 - - -1 -2 -21519 - - -2 -62 -1414 - - - - - - -text -fileid - - -12 - - -1 -2 -21522 - - -2 -62 -1411 - - - - - - -parentid -id - - -12 - - -1 -2 -26379 - - -2 -17 -167 - - - - - - -parentid -text - - -12 - - -1 -2 -26379 - - -2 -17 -167 - - - - - - -parentid -fileid - - -12 - - -1 -2 -26546 - - - - - - -fileid -id - - -12 - - -1 -2 -26161 - - -2 -17 -207 - - - - - - -fileid -text - - -12 - - -1 -2 -26165 - - -2 -17 -203 - - - - - - -fileid -parentid - - -12 - - -1 -2 -26223 - - -2 -10 -145 - - - - - - - - -xmlChars -439958 - - -id -439958 - - -text -100518 - - -parentid -433851 - - -idx -4 - - -isCDATA -1 - - -fileid -26494 - - - - -id -text - - -12 - - -1 -2 -439958 - - - - - - -id -parentid - - -12 - - -1 -2 -439958 - - - - - - -id -idx - - -12 - - -1 -2 -439958 - - - - - - -id -isCDATA - - -12 - - -1 -2 -439958 - - - - - - -id -fileid - - -12 - - -1 -2 -439958 - - - - - - -text -id - - -12 - - -1 -2 -60389 - - -2 -4 -3811 - - -4 -5 -29257 - - -5 -23171 -7061 - - - - - - -text -parentid - - -12 - - -1 -2 -60389 - - -2 -4 -3811 - - -4 -5 -29257 - - -5 -23171 -7061 - - - - - - -text -idx - - -12 - - -1 -2 -100517 - - -2 -3 -1 - - - - - - -text -isCDATA - - -12 - - -1 -2 -100518 - - - - - - -text -fileid - - -12 - - -1 -2 -61284 - - -2 -4 -4205 - - -4 -5 -28328 - - -5 -351 -6701 - - - - - - -parentid -id - - -12 - - -1 -2 -429716 - - -2 -5 -4135 - - - - - - -parentid -text - - -12 - - -1 -2 -429716 - - -2 -5 -4135 - - - - - - -parentid -idx - - -12 - - -1 -2 -429716 - - -2 -5 -4135 - - - - - - -parentid -isCDATA - - -12 - - -1 -2 -433851 - - - - - - -parentid -fileid - - -12 - - -1 -2 -433851 - - - - - - -idx -id - - -12 - - -80 -81 -1 - - -1892 -1893 -1 - - -4135 -4136 -1 - - -433851 -433852 -1 - - - - - - -idx -text - - -12 - - -1 -2 -1 - - -3 -4 -1 - - -16 -17 -1 - - -100499 -100500 -1 - - - - - - -idx -parentid - - -12 - - -80 -81 -1 - - -1892 -1893 -1 - - -4135 -4136 -1 - - -433851 -433852 -1 - - - - - - -idx -isCDATA - - -12 - - -1 -2 -4 - - - - - - -idx -fileid - - -12 - - -4 -5 -1 - - -46 -47 -1 - - -97 -98 -1 - - -26494 -26495 -1 - - - - - - -isCDATA -id - - -12 - - -439958 -439959 -1 - - - - - - -isCDATA -text - - -12 - - -100518 -100519 -1 - - - - - - -isCDATA -parentid - - -12 - - -433851 -433852 -1 - - - - - - -isCDATA -idx - - -12 - - -4 -5 -1 - - - - - - -isCDATA -fileid - - -12 - - -26494 -26495 -1 - - - - - - -fileid -id - - -12 - - -1 -2 -25303 - - -2 -35123 -1191 - - - - - - -fileid -text - - -12 - - -1 -2 -25765 - - -2 -35123 -729 - - - - - - -fileid -parentid - - -12 - - -1 -2 -25312 - - -2 -35123 -1182 - - - - - - -fileid -idx - - -12 - - -1 -2 -26397 - - -2 -5 -97 - - - - - - -fileid -isCDATA - - -12 - - -1 -2 -26494 - - - - - - - - -xmllocations -3051056 - - -xmlElement -2982460 - - -location -3051056 - - - - -xmlElement -location - - -12 - - -1 -2 -2978326 - - -2 -24903 -4134 - - - - - - -location -xmlElement - - -12 - - -1 -2 -3051056 - - - - - - - - + + + @compilation + 9999 + + + @externalDataElement + 65 + + + @external_package + 4 + + + @svnentry + 575525 + + + @location_stmt + 3805195 + + + @location_default + 30199622 + + + @location_expr + 13127189 + + + @diagnostic + 667106 + + + @file + 124610 + + + @folder + 15576 + + + @macroinvocation + 34062185 + + + @function + 4759741 + + + @fun_decl + 5131684 + + + @type_decl + 3292736 + + + @namespace_decl + 307863 + + + @using + 375719 + + + @static_assert + 130790 + + + @var_decl + 8586319 + + + @parameter + 6696867 + + + @membervariable + 1050009 + + + @globalvariable + 300708 + + + @localvariable + 581746 + + + @enumconstant + 240596 + + + @builtintype + 22184 + + + @derivedtype + 4456239 + + + @decltype + 31152 + + + @usertype + 5362968 + + + @mangledname + 1733994 + + + @type_mention + 4011226 + + + @routinetype + 543059 + + + @ptrtomember + 38232 + + + @specifier + 25016 + + + @gnuattribute + 663644 + + + @stdattribute + 468476 + + + @alignas + 8968 + + + @declspec + 238528 + + + @msattribute + 3 + + + @attribute_arg_token + 25960 + + + @attribute_arg_constant + 324742 + + + @attribute_arg_type + 1535 + + + @attribute_arg_empty + 1 + + + @derivation + 397280 + + + @frienddecl + 710038 + + + @comment + 9024167 + + + @namespace + 12744 + + + @specialnamequalifyingelement + 472 + + + @namequalifier + 1593457 + + + @value + 10645398 + + + @initialiser + 1736804 + + + @delete_array_expr + 1413 + + + @new_array_expr + 5113 + + + @ctordirectinit + 111984 + + + @ctorvirtualinit + 6546 + + + @ctorfieldinit + 199374 + + + @ctordelegatinginit + 7857 + + + @dtordirectdestruct + 41421 + + + @dtorvirtualdestruct + 4093 + + + @dtorfielddestruct + 41351 + + + @static_cast + 212170 + + + @reinterpret_cast + 30881 + + + @const_cast + 35398 + + + @c_style_cast + 4209375 + + + @lambdaexpr + 21712 + + + @param_ref + 403726 + + + @errorexpr + 54470 + + + @address_of + 438806 + + + @reference_to + 1615323 + + + @indirect + 292094 + + + @ref_indirect + 1941936 + + + @array_to_pointer + 1424786 + + + @vacuous_destructor_call + 8711 + + + @parexpr + 3572304 + + + @arithnegexpr + 650877 + + + @unaryplusexpr + 2903 + + + @complementexpr + 27785 + + + @notexpr + 277973 + + + @postincrexpr + 61769 + + + @postdecrexpr + 41857 + + + @preincrexpr + 70302 + + + @predecrexpr + 26107 + + + @conditionalexpr + 654457 + + + @addexpr + 400330 + + + @subexpr + 339317 + + + @mulexpr + 305870 + + + @divexpr + 133721 + + + @remexpr + 15707 + + + @paddexpr + 86499 + + + @psubexpr + 49678 + + + @pdiffexpr + 35608 + + + @lshiftexpr + 562948 + + + @rshiftexpr + 141607 + + + @andexpr + 491783 + + + @orexpr + 146257 + + + @xorexpr + 53934 + + + @eqexpr + 468840 + + + @neexpr + 300391 + + + @gtexpr + 101009 + + + @ltexpr + 108562 + + + @geexpr + 58985 + + + @leexpr + 212126 + + + @assignexpr + 933354 + + + @assignaddexpr + 68222 + + + @assignsubexpr + 15624 + + + @assignmulexpr + 7586 + + + @assigndivexpr + 4971 + + + @assignremexpr + 1625 + + + @assignlshiftexpr + 2704 + + + @assignrshiftexpr + 4495 + + + @assignandexpr + 5780 + + + @assignorexpr + 23853 + + + @assignxorexpr + 21802 + + + @assignpaddexpr + 13576 + + + @assignpsubexpr + 1148 + + + @andlogicalexpr + 248991 + + + @orlogicalexpr + 863957 + + + @commaexpr + 181070 + + + @subscriptexpr + 367945 + + + @callexpr + 310110 + + + @vastartexpr + 3713 + + + @vaendexpr + 2832 + + + @varaccess + 6005942 + + + @thisaccess + 1129204 + + + @new_expr + 55240 + + + @delete_expr + 11649 + + + @throw_expr + 21806 + + + @condition_decl + 38495 + + + @braced_init_list + 1005 + + + @type_id + 36173 + + + @runtime_sizeof + 289248 + + + @runtime_alignof + 48208 + + + @sizeof_pack + 5664 + + + @routineexpr + 3065607 + + + @type_operand + 1125950 + + + @offsetofexpr + 20101 + + + @isemptyexpr + 2310 + + + @ispodexpr + 637 + + + @hastrivialdestructor + 472 + + + @literal + 4351842 + + + @aggregateliteral + 913874 + + + @istrivialexpr + 944 + + + @istriviallycopyableexpr + 3776 + + + @isfinalexpr + 2100 + + + @noexceptexpr + 35718 + + + @builtinaddressof + 13189 + + + @temp_init + 759580 + + + @assume + 3209 + + + @conjugation + 1 + + + @realpartexpr + 69 + + + @imagpartexpr + 69 + + + @jmulexpr + 1 + + + @jdivexpr + 1 + + + @fjaddexpr + 1 + + + @jfaddexpr + 1 + + + @fjsubexpr + 1 + + + @jfsubexpr + 1 + + + @minexpr + 1 + + + @maxexpr + 1 + + + @virtfunptrexpr + 1 + + + @vaargexpr + 950 + + + @vacopyexpr + 139 + + + @expr_stmt + 94922 + + + @hasassignexpr + 2 + + + @hascopyexpr + 2 + + + @hasnothrowassign + 3 + + + @hasnothrowconstr + 3 + + + @hasnothrowcopy + 5 + + + @hastrivialassign + 2 + + + @hastrivialconstr + 3 + + + @hastrivialcopy + 2 + + + @hasuserdestr + 3 + + + @hasvirtualdestr + 3 + + + @isabstractexpr + 17 + + + @isbaseofexpr + 37 + + + @isclassexpr + 1841 + + + @isconvtoexpr + 1155 + + + @isenumexpr + 1260 + + + @ispolyexpr + 3 + + + @isunionexpr + 5 + + + @typescompexpr + 562376 + + + @intaddrexpr + 1 + + + @uuidof + 20051 + + + @foldexpr + 4 + + + @dynamic_cast + 1042 + + + @noopexpr + 37 + + + @istriviallyconstructibleexpr + 2836 + + + @isdestructibleexpr + 4 + + + @isnothrowdestructibleexpr + 5 + + + @istriviallydestructibleexpr + 5 + + + @istriviallyassignableexpr + 525 + + + @isnothrowassignableexpr + 2100 + + + @isstandardlayoutexpr + 840 + + + @isliteraltypeexpr + 2 + + + @hastrivialmoveconstructorexpr + 3 + + + @hastrivialmoveassignexpr + 3 + + + @hasnothrowmoveassignexpr + 4 + + + @isconstructibleexpr + 2731 + + + @isnothrowconstructibleexpr + 4831 + + + @hasfinalizerexpr + 1 + + + @isdelegateexpr + 1 + + + @isinterfaceclassexpr + 1 + + + @isrefarrayexpr + 1 + + + @isrefclassexpr + 1 + + + @issealedexpr + 1 + + + @issimplevalueclassexpr + 1 + + + @isvalueclassexpr + 1 + + + @builtinshufflevector + 1 + + + @builtinchooseexpr + 9135 + + + @vec_fill + 1 + + + @builtinconvertvector + 1 + + + @builtincomplex + 4 + + + @spaceshipexpr + 1 + + + @co_await + 6 + + + @co_yield + 1 + + + @lambdacapture + 28320 + + + @stmt_expr + 1480310 + + + @stmt_if + 723123 + + + @stmt_while + 30265 + + + @stmt_goto + 110482 + + + @stmt_label + 53042 + + + @stmt_return + 1310769 + + + @stmt_block + 1451428 + + + @stmt_end_test_while + 148593 + + + @stmt_for + 61319 + + + @stmt_switch_case + 190914 + + + @stmt_switch + 20900 + + + @stmt_asm + 110581 + + + @stmt_try_block + 42591 + + + @stmt_decl + 609675 + + + @stmt_empty + 193503 + + + @stmt_continue + 22506 + + + @stmt_break + 102528 + + + @stmt_range_based_for + 8496 + + + @stmt_handler + 59279 + + + @stmt_microsoft_try + 163 + + + @stmt_set_vla_size + 26 + + + @stmt_vla_decl + 21 + + + @stmt_assigned_goto + 9058 + + + @stmt_constexpr_if + 52624 + + + @stmt_co_return + 2 + + + @ppd_if + 671197 + + + @ppd_ifdef + 266213 + + + @ppd_ifndef + 269517 + + + @ppd_elif + 25488 + + + @ppd_else + 211460 + + + @ppd_endif + 1206927 + + + @ppd_plain_include + 314830 + + + @ppd_define + 2443222 + + + @ppd_undef + 264325 + + + @ppd_pragma + 313333 + + + @ppd_include_next + 1888 + + + @ppd_line + 27783 + + + @ppd_error + 46 + + + @ppd_objc_import + 2 + + + @ppd_warning + 1 + + + @link_target + 1471 + + + @xmldtd + 1 + + + @xmlelement + 1270313 + + + @xmlattribute + 1202020 + + + @xmlnamespace + 4185 + + + @xmlcomment + 26812 + + + @xmlcharacters + 439958 + + + + + compilations + 9999 + + + id + 9999 + + + cwd + 11 + + + + + id + cwd + + + 12 + + + 1 + 2 + 9999 + + + + + + + cwd + id + + + 12 + + + 863 + 864 + 11 + + + + + + + + + compilation_args + 656105 + + + id + 5544 + + + num + 712 + + + arg + 34648 + + + + + id + num + + + 12 + + + 23 + 69 + 489 + + + 71 + 102 + 276 + + + 126 + 127 + 3889 + + + 127 + 129 + 58 + + + 131 + 132 + 819 + + + 134 + 135 + 10 + + + + + + + id + arg + + + 12 + + + 23 + 57 + 489 + + + 57 + 106 + 292 + + + 106 + 107 + 3852 + + + 107 + 109 + 79 + + + 109 + 110 + 819 + + + 111 + 112 + 10 + + + + + + + num + id + + + 12 + + + 2 + 168 + 42 + + + 898 + 899 + 133 + + + 911 + 930 + 58 + + + 930 + 938 + 58 + + + 938 + 951 + 58 + + + 970 + 989 + 37 + + + 999 + 1000 + 74 + + + 1001 + 1013 + 58 + + + 1018 + 1040 + 63 + + + 1041 + 1042 + 5 + + + 1042 + 1043 + 122 + + + + + + + num + arg + + + 12 + + + 1 + 5 + 63 + + + 5 + 6 + 63 + + + 6 + 8 + 58 + + + 8 + 13 + 53 + + + 13 + 14 + 31 + + + 14 + 15 + 47 + + + 15 + 16 + 42 + + + 16 + 18 + 63 + + + 18 + 22 + 58 + + + 22 + 26 + 58 + + + 27 + 36 + 58 + + + 36 + 169 + 58 + + + 169 + 819 + 53 + + + + + + + arg + id + + + 12 + + + 1 + 2 + 32573 + + + 2 + 1043 + 2075 + + + + + + + arg + num + + + 12 + + + 1 + 2 + 33435 + + + 2 + 56 + 1213 + + + + + + + + + compilation_compiling_files + 11494 + + + id + 1988 + + + num + 3301 + + + file + 9983 + + + + + id + num + + + 12 + + + 1 + 2 + 994 + + + 2 + 3 + 119 + + + 3 + 4 + 119 + + + 4 + 5 + 238 + + + 5 + 8 + 119 + + + 8 + 9 + 119 + + + 9 + 13 + 159 + + + 21 + 84 + 119 + + + + + + + id + file + + + 12 + + + 1 + 2 + 994 + + + 2 + 3 + 119 + + + 3 + 4 + 119 + + + 4 + 5 + 238 + + + 5 + 8 + 119 + + + 8 + 9 + 119 + + + 9 + 13 + 159 + + + 21 + 84 + 119 + + + + + + + num + id + + + 12 + + + 1 + 2 + 1750 + + + 2 + 3 + 715 + + + 3 + 4 + 357 + + + 4 + 13 + 278 + + + 13 + 51 + 198 + + + + + + + num + file + + + 12 + + + 1 + 2 + 1750 + + + 2 + 3 + 715 + + + 3 + 4 + 357 + + + 4 + 13 + 278 + + + 13 + 49 + 198 + + + + + + + file + id + + + 12 + + + 1 + 2 + 8989 + + + 2 + 4 + 835 + + + 4 + 6 + 159 + + + + + + + file + num + + + 12 + + + 1 + 2 + 9148 + + + 2 + 4 + 795 + + + 4 + 5 + 39 + + + + + + + + + compilation_time + 45979 + + + id + 1988 + + + num + 3301 + + + kind + 159 + + + seconds + 13762 + + + + + id + num + + + 12 + + + 1 + 2 + 994 + + + 2 + 3 + 119 + + + 3 + 4 + 119 + + + 4 + 5 + 238 + + + 5 + 8 + 119 + + + 8 + 9 + 119 + + + 9 + 13 + 159 + + + 21 + 84 + 119 + + + + + + + id + kind + + + 12 + + + 4 + 5 + 1988 + + + + + + + id + seconds + + + 12 + + + 3 + 4 + 278 + + + 4 + 5 + 715 + + + 6 + 7 + 119 + + + 9 + 11 + 119 + + + 11 + 12 + 238 + + + 13 + 17 + 119 + + + 18 + 20 + 119 + + + 21 + 26 + 159 + + + 44 + 132 + 119 + + + + + + + num + id + + + 12 + + + 1 + 2 + 1750 + + + 2 + 3 + 715 + + + 3 + 4 + 357 + + + 4 + 13 + 278 + + + 13 + 51 + 198 + + + + + + + num + kind + + + 12 + + + 4 + 5 + 3301 + + + + + + + num + seconds + + + 12 + + + 3 + 4 + 1073 + + + 4 + 5 + 676 + + + 5 + 6 + 238 + + + 6 + 7 + 437 + + + 7 + 8 + 159 + + + 8 + 10 + 238 + + + 11 + 28 + 278 + + + 29 + 93 + 198 + + + + + + + kind + id + + + 12 + + + 50 + 51 + 159 + + + + + + + kind + num + + + 12 + + + 83 + 84 + 159 + + + + + + + kind + seconds + + + 12 + + + 3 + 4 + 39 + + + 5 + 6 + 39 + + + 167 + 168 + 39 + + + 178 + 179 + 39 + + + + + + + seconds + id + + + 12 + + + 1 + 2 + 8591 + + + 2 + 3 + 3420 + + + 3 + 4 + 1312 + + + 4 + 40 + 437 + + + + + + + seconds + num + + + 12 + + + 1 + 2 + 8591 + + + 2 + 3 + 2744 + + + 3 + 4 + 1551 + + + 4 + 64 + 875 + + + + + + + seconds + kind + + + 12 + + + 1 + 2 + 13483 + + + 2 + 3 + 278 + + + + + + + + + diagnostic_for + 917206 + + + diagnostic + 667106 + + + compilation + 1890 + + + file_number + 105 + + + file_number_diagnostic_number + 105144 + + + + + diagnostic + compilation + + + 12 + + + 1 + 2 + 465220 + + + 2 + 3 + 177937 + + + 3 + 9 + 23949 + + + + + + + diagnostic + file_number + + + 12 + + + 1 + 2 + 667106 + + + + + + + diagnostic + file_number_diagnostic_number + + + 12 + + + 1 + 2 + 633284 + + + 2 + 5 + 33822 + + + + + + + compilation + diagnostic + + + 12 + + + 37 + 38 + 105 + + + 78 + 79 + 210 + + + 119 + 120 + 105 + + + 155 + 156 + 105 + + + 156 + 157 + 210 + + + 352 + 353 + 105 + + + 353 + 354 + 105 + + + 710 + 711 + 105 + + + 756 + 757 + 630 + + + 1001 + 1002 + 210 + + + + + + + compilation + file_number + + + 12 + + + 1 + 2 + 1890 + + + + + + + compilation + file_number_diagnostic_number + + + 12 + + + 37 + 38 + 105 + + + 78 + 79 + 210 + + + 119 + 120 + 105 + + + 155 + 156 + 105 + + + 156 + 157 + 210 + + + 352 + 353 + 105 + + + 353 + 354 + 105 + + + 710 + 711 + 105 + + + 756 + 757 + 630 + + + 1001 + 1002 + 210 + + + + + + + file_number + diagnostic + + + 12 + + + 6351 + 6352 + 105 + + + + + + + file_number + compilation + + + 12 + + + 18 + 19 + 105 + + + + + + + file_number + file_number_diagnostic_number + + + 12 + + + 1001 + 1002 + 105 + + + + + + + file_number_diagnostic_number + diagnostic + + + 12 + + + 2 + 3 + 25734 + + + 6 + 7 + 12814 + + + 7 + 8 + 105 + + + 8 + 9 + 42015 + + + 9 + 10 + 8193 + + + 10 + 11 + 525 + + + 11 + 12 + 9978 + + + 12 + 14 + 5777 + + + + + + + file_number_diagnostic_number + compilation + + + 12 + + + 2 + 3 + 25734 + + + 8 + 9 + 4831 + + + 9 + 10 + 37499 + + + 10 + 11 + 105 + + + 11 + 12 + 20587 + + + 13 + 16 + 8193 + + + 17 + 19 + 8193 + + + + + + + file_number_diagnostic_number + file_number + + + 12 + + + 1 + 2 + 105144 + + + + + + + + + compilation_finished + 9999 + + + id + 9999 + + + cpu_seconds + 8319 + + + elapsed_seconds + 139 + + + + + id + cpu_seconds + + + 12 + + + 1 + 2 + 9999 + + + + + + + id + elapsed_seconds + + + 12 + + + 1 + 2 + 9999 + + + + + + + cpu_seconds + id + + + 12 + + + 1 + 2 + 7160 + + + 2 + 3 + 915 + + + 3 + 11 + 243 + + + + + + + cpu_seconds + elapsed_seconds + + + 12 + + + 1 + 2 + 8064 + + + 2 + 3 + 254 + + + + + + + elapsed_seconds + id + + + 12 + + + 1 + 2 + 11 + + + 3 + 4 + 11 + + + 4 + 5 + 11 + + + 6 + 7 + 11 + + + 7 + 8 + 11 + + + 13 + 14 + 11 + + + 23 + 24 + 11 + + + 64 + 65 + 11 + + + 95 + 96 + 11 + + + 136 + 137 + 11 + + + 254 + 255 + 11 + + + 257 + 258 + 11 + + + + + + + elapsed_seconds + cpu_seconds + + + 12 + + + 1 + 2 + 11 + + + 3 + 4 + 11 + + + 4 + 5 + 11 + + + 6 + 7 + 11 + + + 7 + 8 + 11 + + + 13 + 14 + 11 + + + 22 + 23 + 11 + + + 63 + 64 + 11 + + + 91 + 92 + 11 + + + 94 + 95 + 11 + + + 203 + 204 + 11 + + + 233 + 234 + 11 + + + + + + + + + externalData + 130 + + + id + 65 + + + path + 10 + + + column + 21 + + + value + 130 + + + + + id + path + + + 12 + + + 1 + 2 + 65 + + + + + + + id + column + + + 12 + + + 2 + 3 + 65 + + + + + + + id + value + + + 12 + + + 2 + 3 + 65 + + + + + + + path + id + + + 12 + + + 6 + 7 + 10 + + + + + + + path + column + + + 12 + + + 2 + 3 + 10 + + + + + + + path + value + + + 12 + + + 12 + 13 + 10 + + + + + + + column + id + + + 12 + + + 6 + 7 + 21 + + + + + + + column + path + + + 12 + + + 1 + 2 + 21 + + + + + + + column + value + + + 12 + + + 6 + 7 + 21 + + + + + + + value + id + + + 12 + + + 1 + 2 + 130 + + + + + + + value + path + + + 12 + + + 1 + 2 + 130 + + + + + + + value + column + + + 12 + + + 1 + 2 + 130 + + + + + + + + + sourceLocationPrefix + 472 + + + prefix + 472 + + + + + + external_packages + 4 + + + id + 4 + + + namespace + 1 + + + package_name + 4 + + + version + 4 + + + + + id + namespace + + + 12 + + + 1 + 2 + 4 + + + + + + + id + package_name + + + 12 + + + 1 + 2 + 4 + + + + + + + id + version + + + 12 + + + 1 + 2 + 4 + + + + + + + namespace + id + + + 12 + + + 4 + 5 + 1 + + + + + + + namespace + package_name + + + 12 + + + 4 + 5 + 1 + + + + + + + namespace + version + + + 12 + + + 4 + 5 + 1 + + + + + + + package_name + id + + + 12 + + + 1 + 2 + 4 + + + + + + + package_name + namespace + + + 12 + + + 1 + 2 + 4 + + + + + + + package_name + version + + + 12 + + + 1 + 2 + 4 + + + + + + + version + id + + + 12 + + + 1 + 2 + 4 + + + + + + + version + namespace + + + 12 + + + 1 + 2 + 4 + + + + + + + version + package_name + + + 12 + + + 1 + 2 + 4 + + + + + + + + + header_to_external_package + 92 + + + fileid + 92 + + + package + 4 + + + + + fileid + package + + + 12 + + + 1 + 2 + 92 + + + + + + + package + fileid + + + 12 + + + 1 + 2 + 1 + + + 5 + 6 + 1 + + + 6 + 7 + 1 + + + 80 + 81 + 1 + + + + + + + + + svnentries + 575525 + + + id + 575525 + + + revision + 575525 + + + author + 19539 + + + revisionDate + 547759 + + + changeSize + 1 + + + + + id + revision + + + 12 + + + 1 + 2 + 575525 + + + + + + + id + author + + + 12 + + + 1 + 2 + 575525 + + + + + + + id + revisionDate + + + 12 + + + 1 + 2 + 575525 + + + + + + + id + changeSize + + + 12 + + + 1 + 2 + 575525 + + + + + + + revision + id + + + 12 + + + 1 + 2 + 575525 + + + + + + + revision + author + + + 12 + + + 1 + 2 + 575525 + + + + + + + revision + revisionDate + + + 12 + + + 1 + 2 + 575525 + + + + + + + revision + changeSize + + + 12 + + + 1 + 2 + 575525 + + + + + + + author + id + + + 12 + + + 1 + 2 + 7913 + + + 2 + 3 + 2531 + + + 3 + 4 + 1388 + + + 4 + 6 + 1523 + + + 6 + 10 + 1529 + + + 10 + 20 + 1509 + + + 20 + 52 + 1488 + + + 52 + 568 + 1466 + + + 569 + 16582 + 192 + + + + + + + author + revision + + + 12 + + + 1 + 2 + 7913 + + + 2 + 3 + 2531 + + + 3 + 4 + 1388 + + + 4 + 6 + 1523 + + + 6 + 10 + 1529 + + + 10 + 20 + 1509 + + + 20 + 52 + 1488 + + + 52 + 568 + 1466 + + + 569 + 16582 + 192 + + + + + + + author + revisionDate + + + 12 + + + 1 + 2 + 7996 + + + 2 + 3 + 2509 + + + 3 + 4 + 1379 + + + 4 + 6 + 1520 + + + 6 + 10 + 1529 + + + 10 + 20 + 1507 + + + 20 + 52 + 1474 + + + 52 + 662 + 1466 + + + 663 + 16573 + 159 + + + + + + + author + changeSize + + + 12 + + + 1 + 2 + 19539 + + + + + + + revisionDate + id + + + 12 + + + 1 + 2 + 531878 + + + 2 + 100 + 15881 + + + + + + + revisionDate + revision + + + 12 + + + 1 + 2 + 531878 + + + 2 + 100 + 15881 + + + + + + + revisionDate + author + + + 12 + + + 1 + 2 + 542505 + + + 2 + 17 + 5254 + + + + + + + revisionDate + changeSize + + + 12 + + + 1 + 2 + 547759 + + + + + + + changeSize + id + + + 12 + + + 575525 + 575526 + 1 + + + + + + + changeSize + revision + + + 12 + + + 575525 + 575526 + 1 + + + + + + + changeSize + author + + + 12 + + + 19539 + 19540 + 1 + + + + + + + changeSize + revisionDate + + + 12 + + + 547759 + 547760 + 1 + + + + + + + + + svnaffectedfiles + 1314068 + + + id + 531628 + + + file + 90924 + + + action + 1 + + + + + id + file + + + 12 + + + 1 + 2 + 337698 + + + 2 + 3 + 77525 + + + 3 + 4 + 43024 + + + 4 + 7 + 46689 + + + 7 + 16635 + 26692 + + + + + + + id + action + + + 12 + + + 1 + 2 + 531628 + + + + + + + file + id + + + 12 + + + 1 + 2 + 11819 + + + 2 + 3 + 18230 + + + 3 + 4 + 9501 + + + 4 + 5 + 6656 + + + 5 + 6 + 5012 + + + 6 + 8 + 7103 + + + 8 + 11 + 6788 + + + 11 + 16 + 6996 + + + 16 + 26 + 7180 + + + 26 + 54 + 6824 + + + 54 + 3572 + 4815 + + + + + + + file + action + + + 12 + + + 1 + 2 + 90924 + + + + + + + action + id + + + 12 + + + 531628 + 531629 + 1 + + + + + + + action + file + + + 12 + + + 90924 + 90925 + 1 + + + + + + + + + svnentrymsg + 575525 + + + id + 575525 + + + message + 568305 + + + + + id + message + + + 12 + + + 1 + 2 + 575525 + + + + + + + message + id + + + 12 + + + 1 + 2 + 565381 + + + 2 + 142 + 2924 + + + + + + + + + svnchurn + 46790 + + + commit + 22361 + + + file + 16124 + + + addedLines + 910 + + + deletedLines + 787 + + + + + commit + file + + + 12 + + + 1 + 2 + 15208 + + + 2 + 3 + 3101 + + + 3 + 4 + 1746 + + + 4 + 8 + 1774 + + + 8 + 246 + 532 + + + + + + + commit + addedLines + + + 12 + + + 1 + 2 + 16074 + + + 2 + 3 + 3323 + + + 3 + 4 + 1561 + + + 4 + 118 + 1403 + + + + + + + commit + deletedLines + + + 12 + + + 1 + 2 + 16799 + + + 2 + 3 + 3286 + + + 3 + 5 + 1763 + + + 5 + 113 + 513 + + + + + + + file + commit + + + 12 + + + 1 + 2 + 8618 + + + 2 + 3 + 2956 + + + 3 + 4 + 1426 + + + 4 + 6 + 1364 + + + 6 + 12 + 1210 + + + 12 + 448 + 550 + + + + + + + file + addedLines + + + 12 + + + 1 + 2 + 9240 + + + 2 + 3 + 3129 + + + 3 + 4 + 1393 + + + 4 + 6 + 1239 + + + 6 + 59 + 1123 + + + + + + + file + deletedLines + + + 12 + + + 1 + 2 + 9525 + + + 2 + 3 + 3192 + + + 3 + 4 + 1401 + + + 4 + 7 + 1387 + + + 7 + 70 + 619 + + + + + + + addedLines + commit + + + 12 + + + 1 + 2 + 446 + + + 2 + 3 + 133 + + + 3 + 4 + 70 + + + 4 + 6 + 68 + + + 6 + 12 + 70 + + + 12 + 57 + 69 + + + 57 + 6874 + 54 + + + + + + + addedLines + file + + + 12 + + + 1 + 2 + 445 + + + 2 + 3 + 132 + + + 3 + 4 + 69 + + + 4 + 6 + 68 + + + 6 + 12 + 73 + + + 12 + 58 + 69 + + + 58 + 6663 + 54 + + + + + + + addedLines + deletedLines + + + 12 + + + 1 + 2 + 621 + + + 2 + 3 + 96 + + + 3 + 7 + 81 + + + 7 + 34 + 70 + + + 34 + 727 + 42 + + + + + + + deletedLines + commit + + + 12 + + + 1 + 2 + 439 + + + 2 + 3 + 116 + + + 3 + 4 + 48 + + + 4 + 8 + 67 + + + 8 + 28 + 60 + + + 28 + 6794 + 57 + + + + + + + deletedLines + file + + + 12 + + + 1 + 2 + 437 + + + 2 + 3 + 113 + + + 3 + 4 + 49 + + + 4 + 7 + 61 + + + 7 + 19 + 60 + + + 19 + 770 + 60 + + + 985 + 7318 + 7 + + + + + + + deletedLines + addedLines + + + 12 + + + 1 + 2 + 545 + + + 2 + 3 + 72 + + + 3 + 7 + 69 + + + 7 + 30 + 60 + + + 30 + 871 + 41 + + + + + + + + + locations_default + 30199622 + + + id + 30199622 + + + container + 140186 + + + startLine + 2121681 + + + startColumn + 37288 + + + endLine + 2124985 + + + endColumn + 48616 + + + + + id + container + + + 12 + + + 1 + 2 + 30199622 + + + + + + + id + startLine + + + 12 + + + 1 + 2 + 30199622 + + + + + + + id + startColumn + + + 12 + + + 1 + 2 + 30199622 + + + + + + + id + endLine + + + 12 + + + 1 + 2 + 30199622 + + + + + + + id + endColumn + + + 12 + + + 1 + 2 + 30199622 + + + + + + + container + id + + + 12 + + + 1 + 2 + 16048 + + + 2 + 12 + 10856 + + + 13 + 20 + 11800 + + + 21 + 36 + 11328 + + + 36 + 55 + 11328 + + + 55 + 77 + 10856 + + + 77 + 102 + 10856 + + + 102 + 146 + 10856 + + + 148 + 223 + 10856 + + + 226 + 350 + 11800 + + + 358 + 628 + 10856 + + + 671 + 1926 + 10856 + + + 2171 + 2380 + 1888 + + + + + + + container + startLine + + + 12 + + + 1 + 2 + 16048 + + + 2 + 9 + 10856 + + + 9 + 16 + 11800 + + + 16 + 25 + 11328 + + + 25 + 40 + 10856 + + + 40 + 57 + 10856 + + + 58 + 72 + 10856 + + + 73 + 99 + 10856 + + + 101 + 141 + 12272 + + + 148 + 226 + 10856 + + + 226 + 365 + 10856 + + + 372 + 1253 + 10856 + + + 1452 + 1616 + 1888 + + + + + + + container + startColumn + + + 12 + + + 1 + 2 + 16048 + + + 2 + 4 + 8968 + + + 4 + 5 + 7552 + + + 5 + 6 + 7552 + + + 6 + 8 + 12272 + + + 8 + 13 + 11800 + + + 13 + 17 + 10856 + + + 17 + 25 + 11328 + + + 25 + 31 + 11800 + + + 31 + 38 + 10856 + + + 38 + 52 + 10856 + + + 52 + 64 + 10856 + + + 65 + 77 + 9440 + + + + + + + container + endLine + + + 12 + + + 1 + 2 + 16048 + + + 2 + 9 + 10856 + + + 9 + 16 + 11800 + + + 16 + 25 + 11328 + + + 25 + 40 + 10856 + + + 40 + 57 + 10856 + + + 58 + 71 + 10856 + + + 72 + 97 + 10856 + + + 97 + 140 + 11800 + + + 140 + 225 + 11328 + + + 225 + 365 + 10856 + + + 372 + 1253 + 10856 + + + 1449 + 1613 + 1888 + + + + + + + container + endColumn + + + 12 + + + 1 + 2 + 16048 + + + 2 + 10 + 11328 + + + 10 + 14 + 10856 + + + 14 + 21 + 11328 + + + 22 + 31 + 11328 + + + 31 + 39 + 12744 + + + 39 + 48 + 12272 + + + 48 + 56 + 11800 + + + 56 + 64 + 11800 + + + 64 + 72 + 10856 + + + 72 + 77 + 11328 + + + 77 + 90 + 8496 + + + + + + + startLine + id + + + 12 + + + 1 + 2 + 598507 + + + 2 + 3 + 302085 + + + 3 + 4 + 190691 + + + 4 + 6 + 171339 + + + 6 + 10 + 192579 + + + 10 + 16 + 161427 + + + 16 + 24 + 159539 + + + 24 + 42 + 159539 + + + 42 + 142 + 159539 + + + 142 + 298 + 26432 + + + + + + + startLine + container + + + 12 + + + 1 + 2 + 881241 + + + 2 + 3 + 262437 + + + 3 + 4 + 135466 + + + 4 + 7 + 195883 + + + 7 + 11 + 177475 + + + 11 + 16 + 161899 + + + 16 + 29 + 159539 + + + 29 + 298 + 147738 + + + + + + + startLine + startColumn + + + 12 + + + 1 + 2 + 625884 + + + 2 + 3 + 296893 + + + 3 + 4 + 203435 + + + 4 + 6 + 195411 + + + 6 + 9 + 178891 + + + 9 + 13 + 167091 + + + 13 + 19 + 178419 + + + 19 + 29 + 162843 + + + 29 + 52 + 112810 + + + + + + + startLine + endLine + + + 12 + + + 1 + 2 + 1552910 + + + 2 + 3 + 345510 + + + 3 + 5 + 171811 + + + 5 + 16 + 51449 + + + + + + + startLine + endColumn + + + 12 + + + 1 + 2 + 601811 + + + 2 + 3 + 305389 + + + 3 + 4 + 194939 + + + 4 + 6 + 174171 + + + 6 + 9 + 165675 + + + 9 + 14 + 172755 + + + 14 + 20 + 164259 + + + 20 + 31 + 171339 + + + 31 + 58 + 160955 + + + 58 + 67 + 10384 + + + + + + + startColumn + id + + + 12 + + + 1 + 31 + 2832 + + + 42 + 85 + 2832 + + + 86 + 128 + 2832 + + + 129 + 230 + 2832 + + + 247 + 292 + 2832 + + + 292 + 360 + 2832 + + + 377 + 459 + 2832 + + + 476 + 559 + 2832 + + + 565 + 620 + 2832 + + + 625 + 689 + 2832 + + + 700 + 795 + 2832 + + + 820 + 1546 + 2832 + + + 1698 + 5668 + 2832 + + + 15394 + 15395 + 472 + + + + + + + startColumn + container + + + 12 + + + 1 + 18 + 2832 + + + 23 + 35 + 3304 + + + 37 + 43 + 2832 + + + 44 + 61 + 2832 + + + 65 + 73 + 2832 + + + 73 + 83 + 2832 + + + 83 + 96 + 2832 + + + 96 + 100 + 2832 + + + 101 + 103 + 2832 + + + 104 + 108 + 2832 + + + 108 + 115 + 2832 + + + 116 + 150 + 3304 + + + 152 + 298 + 2360 + + + + + + + startColumn + startLine + + + 12 + + + 1 + 19 + 2832 + + + 30 + 72 + 2832 + + + 83 + 122 + 2832 + + + 123 + 204 + 2832 + + + 213 + 262 + 2832 + + + 264 + 324 + 2832 + + + 324 + 380 + 2832 + + + 404 + 439 + 2832 + + + 455 + 475 + 2832 + + + 477 + 510 + 2832 + + + 517 + 579 + 2832 + + + 588 + 836 + 2832 + + + 1112 + 2199 + 2832 + + + 2401 + 2402 + 472 + + + + + + + startColumn + endLine + + + 12 + + + 1 + 19 + 2832 + + + 30 + 72 + 2832 + + + 83 + 122 + 2832 + + + 123 + 204 + 2832 + + + 213 + 262 + 2832 + + + 264 + 324 + 2832 + + + 324 + 380 + 2832 + + + 405 + 439 + 2832 + + + 455 + 475 + 2832 + + + 476 + 509 + 2832 + + + 520 + 578 + 2832 + + + 588 + 835 + 2832 + + + 1115 + 2200 + 2832 + + + 2409 + 2410 + 472 + + + + + + + startColumn + endColumn + + + 12 + + + 1 + 7 + 2832 + + + 7 + 10 + 1888 + + + 10 + 13 + 2832 + + + 13 + 19 + 2832 + + + 19 + 23 + 2832 + + + 23 + 25 + 3304 + + + 25 + 31 + 2832 + + + 31 + 36 + 2832 + + + 38 + 41 + 2360 + + + 41 + 46 + 3304 + + + 46 + 50 + 3304 + + + 51 + 62 + 2832 + + + 63 + 81 + 2832 + + + 85 + 86 + 472 + + + + + + + endLine + id + + + 12 + + + 1 + 2 + 600867 + + + 2 + 3 + 301141 + + + 3 + 4 + 198243 + + + 4 + 6 + 165203 + + + 6 + 10 + 189275 + + + 10 + 16 + 163315 + + + 16 + 24 + 161899 + + + 24 + 43 + 162371 + + + 43 + 145 + 160011 + + + 146 + 298 + 22656 + + + + + + + endLine + container + + + 12 + + + 1 + 2 + 883129 + + + 2 + 3 + 275181 + + + 3 + 5 + 194467 + + + 5 + 8 + 177947 + + + 8 + 12 + 159539 + + + 12 + 18 + 171811 + + + 18 + 39 + 160011 + + + 39 + 298 + 102898 + + + + + + + endLine + startLine + + + 12 + + + 1 + 2 + 1542998 + + + 2 + 3 + 354006 + + + 3 + 5 + 170395 + + + 5 + 10 + 57585 + + + + + + + endLine + startColumn + + + 12 + + + 1 + 2 + 625412 + + + 2 + 3 + 301613 + + + 3 + 4 + 204852 + + + 4 + 6 + 194467 + + + 6 + 9 + 175115 + + + 9 + 13 + 172755 + + + 13 + 19 + 179363 + + + 19 + 30 + 165203 + + + 30 + 52 + 106202 + + + + + + + endLine + endColumn + + + 12 + + + 1 + 2 + 605115 + + + 2 + 3 + 305389 + + + 3 + 4 + 200603 + + + 4 + 6 + 168507 + + + 6 + 9 + 164259 + + + 9 + 14 + 174171 + + + 14 + 20 + 161899 + + + 20 + 30 + 159539 + + + 30 + 54 + 159539 + + + 54 + 66 + 25960 + + + + + + + endColumn + id + + + 12 + + + 1 + 2 + 5192 + + + 2 + 8 + 3776 + + + 9 + 184 + 3776 + + + 196 + 295 + 3776 + + + 297 + 492 + 3776 + + + 506 + 553 + 3776 + + + 560 + 632 + 3776 + + + 638 + 760 + 3776 + + + 763 + 871 + 3776 + + + 878 + 1082 + 3776 + + + 1085 + 1286 + 3776 + + + 1307 + 1590 + 3776 + + + 1674 + 2430 + 1888 + + + + + + + endColumn + container + + + 12 + + + 1 + 2 + 5664 + + + 2 + 6 + 3776 + + + 6 + 65 + 3776 + + + 69 + 99 + 3776 + + + 99 + 112 + 4248 + + + 113 + 122 + 3776 + + + 124 + 140 + 3776 + + + 143 + 153 + 3776 + + + 153 + 160 + 3776 + + + 160 + 172 + 3776 + + + 172 + 176 + 3776 + + + 176 + 208 + 3776 + + + 240 + 298 + 944 + + + + + + + endColumn + startLine + + + 12 + + + 1 + 2 + 5664 + + + 2 + 8 + 3776 + + + 9 + 106 + 3776 + + + 152 + 242 + 3776 + + + 253 + 333 + 3776 + + + 339 + 430 + 3776 + + + 434 + 490 + 3776 + + + 493 + 572 + 3776 + + + 572 + 623 + 3776 + + + 629 + 696 + 3776 + + + 703 + 814 + 3776 + + + 822 + 994 + 3776 + + + 1107 + 1175 + 1416 + + + + + + + endColumn + startColumn + + + 12 + + + 1 + 2 + 6136 + + + 2 + 4 + 3776 + + + 4 + 8 + 3776 + + + 8 + 14 + 3776 + + + 14 + 22 + 3776 + + + 22 + 29 + 4248 + + + 29 + 35 + 4248 + + + 35 + 39 + 3304 + + + 39 + 42 + 3304 + + + 42 + 44 + 3304 + + + 44 + 46 + 3776 + + + 46 + 50 + 4248 + + + 51 + 53 + 944 + + + + + + + endColumn + endLine + + + 12 + + + 1 + 2 + 5664 + + + 2 + 8 + 3776 + + + 9 + 153 + 3776 + + + 157 + 243 + 3776 + + + 250 + 333 + 3776 + + + 341 + 432 + 3776 + + + 432 + 488 + 3776 + + + 495 + 571 + 3776 + + + 573 + 621 + 3776 + + + 628 + 700 + 3776 + + + 703 + 815 + 3776 + + + 819 + 994 + 3776 + + + 1108 + 1177 + 1416 + + + + + + + + + locations_stmt + 3805195 + + + id + 3805195 + + + container + 3076 + + + startLine + 199402 + + + startColumn + 1866 + + + endLine + 193680 + + + endColumn + 2358 + + + + + id + container + + + 12 + + + 1 + 2 + 3805195 + + + + + + + id + startLine + + + 12 + + + 1 + 2 + 3805195 + + + + + + + id + startColumn + + + 12 + + + 1 + 2 + 3805195 + + + + + + + id + endLine + + + 12 + + + 1 + 2 + 3805195 + + + + + + + id + endColumn + + + 12 + + + 1 + 2 + 3805195 + + + + + + + container + id + + + 12 + + + 1 + 13 + 246 + + + 16 + 48 + 246 + + + 61 + 175 + 246 + + + 176 + 417 + 246 + + + 436 + 608 + 246 + + + 621 + 797 + 246 + + + 848 + 1139 + 246 + + + 1158 + 1417 + 246 + + + 1453 + 1715 + 246 + + + 1771 + 2252 + 246 + + + 2282 + 2669 + 246 + + + 2736 + 3751 + 246 + + + 3768 + 4993 + 123 + + + + + + + container + startLine + + + 12 + + + 1 + 13 + 246 + + + 16 + 47 + 246 + + + 48 + 161 + 246 + + + 169 + 371 + 266 + + + 393 + 586 + 246 + + + 602 + 783 + 246 + + + 845 + 1120 + 246 + + + 1131 + 1390 + 246 + + + 1394 + 1692 + 246 + + + 1726 + 2208 + 246 + + + 2225 + 2680 + 246 + + + 2777 + 3643 + 246 + + + 3885 + 4846 + 102 + + + + + + + container + startColumn + + + 12 + + + 1 + 3 + 225 + + + 3 + 7 + 266 + + + 7 + 9 + 205 + + + 9 + 11 + 246 + + + 11 + 13 + 225 + + + 13 + 14 + 225 + + + 14 + 16 + 246 + + + 16 + 17 + 164 + + + 17 + 19 + 205 + + + 19 + 21 + 184 + + + 21 + 23 + 246 + + + 23 + 29 + 246 + + + 29 + 43 + 246 + + + 48 + 60 + 143 + + + + + + + container + endLine + + + 12 + + + 1 + 11 + 246 + + + 12 + 34 + 246 + + + 43 + 132 + 246 + + + 134 + 282 + 246 + + + 294 + 452 + 246 + + + 459 + 601 + 246 + + + 609 + 831 + 246 + + + 838 + 1062 + 246 + + + 1071 + 1265 + 246 + + + 1323 + 1679 + 246 + + + 1688 + 2006 + 246 + + + 2044 + 2758 + 246 + + + 2776 + 3873 + 123 + + + + + + + container + endColumn + + + 12 + + + 1 + 8 + 246 + + + 8 + 21 + 246 + + + 22 + 45 + 246 + + + 45 + 56 + 246 + + + 56 + 63 + 266 + + + 63 + 67 + 246 + + + 67 + 69 + 246 + + + 69 + 71 + 225 + + + 71 + 72 + 246 + + + 72 + 74 + 246 + + + 74 + 76 + 246 + + + 76 + 80 + 246 + + + 81 + 96 + 123 + + + + + + + startLine + id + + + 12 + + + 1 + 2 + 21492 + + + 2 + 3 + 15258 + + + 3 + 4 + 12448 + + + 4 + 6 + 14417 + + + 6 + 8 + 12489 + + + 8 + 11 + 16673 + + + 11 + 16 + 17226 + + + 16 + 22 + 15319 + + + 22 + 29 + 16939 + + + 29 + 37 + 17329 + + + 37 + 45 + 15053 + + + 45 + 56 + 16140 + + + 56 + 73 + 8613 + + + + + + + startLine + container + + + 12 + + + 1 + 2 + 22251 + + + 2 + 3 + 15688 + + + 3 + 4 + 12653 + + + 4 + 6 + 14355 + + + 6 + 8 + 12694 + + + 8 + 11 + 17534 + + + 11 + 16 + 16324 + + + 16 + 22 + 16181 + + + 22 + 29 + 16919 + + + 29 + 36 + 15955 + + + 36 + 44 + 16283 + + + 44 + 54 + 15606 + + + 54 + 69 + 6952 + + + + + + + startLine + startColumn + + + 12 + + + 1 + 2 + 26763 + + + 2 + 3 + 20795 + + + 3 + 4 + 16775 + + + 4 + 5 + 16037 + + + 5 + 6 + 17391 + + + 6 + 7 + 19811 + + + 7 + 8 + 22702 + + + 8 + 9 + 20344 + + + 9 + 10 + 14971 + + + 10 + 12 + 16611 + + + 12 + 18 + 7198 + + + + + + + startLine + endLine + + + 12 + + + 1 + 2 + 34515 + + + 2 + 3 + 25737 + + + 3 + 4 + 18395 + + + 4 + 5 + 16181 + + + 5 + 6 + 12756 + + + 6 + 7 + 11997 + + + 7 + 8 + 10151 + + + 8 + 9 + 10951 + + + 9 + 10 + 10705 + + + 10 + 11 + 10500 + + + 11 + 12 + 10151 + + + 12 + 14 + 15750 + + + 14 + 24 + 11607 + + + + + + + startLine + endColumn + + + 12 + + + 1 + 2 + 22087 + + + 2 + 3 + 16160 + + + 3 + 4 + 12920 + + + 4 + 6 + 16037 + + + 6 + 8 + 14663 + + + 8 + 10 + 13166 + + + 10 + 14 + 18252 + + + 14 + 18 + 16980 + + + 18 + 22 + 17534 + + + 22 + 26 + 18457 + + + 26 + 30 + 16345 + + + 30 + 36 + 15196 + + + 36 + 42 + 1599 + + + + + + + startColumn + id + + + 12 + + + 1 + 2 + 225 + + + 2 + 3 + 143 + + + 3 + 7 + 164 + + + 7 + 12 + 143 + + + 12 + 20 + 164 + + + 21 + 53 + 143 + + + 54 + 74 + 143 + + + 78 + 92 + 143 + + + 92 + 134 + 143 + + + 134 + 228 + 143 + + + 228 + 2062 + 143 + + + 3245 + 40863 + 143 + + + 53257 + 53258 + 20 + + + + + + + startColumn + container + + + 12 + + + 1 + 2 + 287 + + + 2 + 3 + 102 + + + 3 + 5 + 164 + + + 5 + 8 + 164 + + + 8 + 13 + 143 + + + 13 + 18 + 143 + + + 18 + 22 + 143 + + + 22 + 24 + 143 + + + 24 + 29 + 143 + + + 33 + 42 + 143 + + + 47 + 109 + 143 + + + 116 + 150 + 143 + + + + + + + startColumn + startLine + + + 12 + + + 1 + 2 + 225 + + + 2 + 3 + 143 + + + 3 + 7 + 164 + + + 7 + 12 + 143 + + + 12 + 20 + 164 + + + 21 + 53 + 143 + + + 54 + 74 + 143 + + + 77 + 88 + 143 + + + 90 + 131 + 143 + + + 134 + 224 + 143 + + + 226 + 1699 + 143 + + + 2430 + 7900 + 143 + + + 8302 + 8303 + 20 + + + + + + + startColumn + endLine + + + 12 + + + 1 + 2 + 225 + + + 2 + 3 + 143 + + + 3 + 7 + 164 + + + 7 + 12 + 143 + + + 12 + 20 + 164 + + + 21 + 53 + 143 + + + 54 + 74 + 143 + + + 77 + 88 + 143 + + + 90 + 130 + 143 + + + 134 + 221 + 143 + + + 226 + 1414 + 143 + + + 2290 + 7741 + 143 + + + 8096 + 8097 + 20 + + + + + + + startColumn + endColumn + + + 12 + + + 1 + 2 + 287 + + + 2 + 3 + 143 + + + 3 + 4 + 82 + + + 4 + 5 + 164 + + + 5 + 8 + 164 + + + 8 + 11 + 143 + + + 11 + 15 + 164 + + + 15 + 19 + 143 + + + 19 + 26 + 143 + + + 28 + 35 + 143 + + + 41 + 69 + 143 + + + 70 + 104 + 143 + + + + + + + endLine + id + + + 12 + + + 1 + 2 + 17370 + + + 2 + 3 + 14376 + + + 3 + 4 + 11464 + + + 4 + 6 + 15565 + + + 6 + 8 + 12469 + + + 8 + 11 + 15422 + + + 11 + 15 + 14601 + + + 15 + 21 + 16058 + + + 21 + 27 + 15381 + + + 27 + 34 + 14909 + + + 34 + 42 + 15709 + + + 42 + 52 + 15975 + + + 52 + 130 + 14376 + + + + + + + endLine + container + + + 12 + + + 1 + 2 + 24897 + + + 2 + 3 + 16099 + + + 3 + 4 + 12735 + + + 4 + 6 + 15627 + + + 6 + 8 + 14971 + + + 8 + 11 + 15852 + + + 11 + 16 + 17411 + + + 16 + 20 + 14560 + + + 20 + 26 + 17124 + + + 26 + 32 + 16222 + + + 32 + 39 + 14827 + + + 39 + 59 + 13350 + + + + + + + endLine + startLine + + + 12 + + + 1 + 2 + 32403 + + + 2 + 3 + 23707 + + + 3 + 4 + 18416 + + + 4 + 5 + 15114 + + + 5 + 6 + 13843 + + + 6 + 7 + 11648 + + + 7 + 8 + 11710 + + + 8 + 9 + 10889 + + + 9 + 10 + 10151 + + + 10 + 12 + 17924 + + + 12 + 15 + 17678 + + + 15 + 100 + 10192 + + + + + + + endLine + startColumn + + + 12 + + + 1 + 2 + 24897 + + + 2 + 3 + 20344 + + + 3 + 4 + 16796 + + + 4 + 5 + 17760 + + + 5 + 6 + 18539 + + + 6 + 7 + 20385 + + + 7 + 8 + 22374 + + + 8 + 9 + 18703 + + + 9 + 10 + 12899 + + + 10 + 12 + 14991 + + + 12 + 18 + 5988 + + + + + + + endLine + endColumn + + + 12 + + + 1 + 2 + 24650 + + + 2 + 3 + 16591 + + + 3 + 4 + 12510 + + + 4 + 6 + 17780 + + + 6 + 8 + 15299 + + + 8 + 10 + 12797 + + + 10 + 13 + 14376 + + + 13 + 16 + 14991 + + + 16 + 19 + 14622 + + + 19 + 22 + 14007 + + + 22 + 26 + 17083 + + + 26 + 31 + 15299 + + + 31 + 39 + 3670 + + + + + + + endColumn + id + + + 12 + + + 1 + 2 + 184 + + + 2 + 4 + 184 + + + 4 + 7 + 164 + + + 7 + 16 + 184 + + + 23 + 133 + 184 + + + 151 + 393 + 184 + + + 394 + 681 + 184 + + + 708 + 1137 + 184 + + + 1138 + 1674 + 184 + + + 1885 + 2795 + 184 + + + 2939 + 4095 + 184 + + + 4142 + 4771 + 184 + + + 5032 + 15460 + 164 + + + + + + + endColumn + container + + + 12 + + + 1 + 2 + 205 + + + 2 + 3 + 184 + + + 3 + 6 + 184 + + + 6 + 21 + 184 + + + 31 + 70 + 205 + + + 74 + 96 + 184 + + + 97 + 108 + 184 + + + 108 + 114 + 184 + + + 115 + 118 + 164 + + + 118 + 122 + 205 + + + 122 + 123 + 123 + + + 123 + 125 + 184 + + + 125 + 149 + 164 + + + + + + + endColumn + startLine + + + 12 + + + 1 + 2 + 184 + + + 2 + 4 + 184 + + + 4 + 7 + 164 + + + 7 + 15 + 184 + + + 22 + 130 + 184 + + + 145 + 378 + 184 + + + 385 + 652 + 184 + + + 666 + 964 + 184 + + + 999 + 1431 + 184 + + + 1587 + 2171 + 184 + + + 2264 + 2917 + 184 + + + 2947 + 3215 + 184 + + + 3417 + 5822 + 164 + + + + + + + endColumn + startColumn + + + 12 + + + 1 + 2 + 205 + + + 2 + 3 + 164 + + + 3 + 5 + 205 + + + 5 + 8 + 184 + + + 8 + 12 + 184 + + + 12 + 14 + 123 + + + 14 + 16 + 184 + + + 16 + 19 + 123 + + + 19 + 21 + 164 + + + 21 + 23 + 184 + + + 23 + 25 + 184 + + + 25 + 28 + 184 + + + 28 + 33 + 205 + + + 45 + 57 + 61 + + + + + + + endColumn + endLine + + + 12 + + + 1 + 2 + 205 + + + 2 + 4 + 164 + + + 4 + 7 + 205 + + + 7 + 27 + 184 + + + 40 + 132 + 184 + + + 142 + 329 + 184 + + + 366 + 583 + 184 + + + 613 + 968 + 184 + + + 1056 + 1409 + 184 + + + 1420 + 2035 + 184 + + + 2066 + 2627 + 184 + + + 2651 + 3073 + 184 + + + 3086 + 4522 + 123 + + + + + + + + + locations_expr + 13127189 + + + id + 13127189 + + + container + 4347 + + + startLine + 191486 + + + startColumn + 2460 + + + endLine + 191465 + + + endColumn + 2789 + + + + + id + container + + + 12 + + + 1 + 2 + 13127189 + + + + + + + id + startLine + + + 12 + + + 1 + 2 + 13127189 + + + + + + + id + startColumn + + + 12 + + + 1 + 2 + 13127189 + + + + + + + id + endLine + + + 12 + + + 1 + 2 + 13127189 + + + + + + + id + endColumn + + + 12 + + + 1 + 2 + 13127189 + + + + + + + container + id + + + 12 + + + 1 + 2 + 369 + + + 2 + 6 + 266 + + + 6 + 10 + 348 + + + 10 + 34 + 328 + + + 46 + 136 + 328 + + + 166 + 594 + 328 + + + 677 + 1614 + 328 + + + 1623 + 2416 + 328 + + + 2490 + 3669 + 328 + + + 3705 + 5161 + 328 + + + 5341 + 6838 + 328 + + + 7344 + 9012 + 328 + + + 9073 + 13259 + 328 + + + 13617 + 18812 + 82 + + + + + + + container + startLine + + + 12 + + + 1 + 2 + 451 + + + 2 + 5 + 348 + + + 5 + 10 + 328 + + + 10 + 22 + 328 + + + 24 + 87 + 328 + + + 97 + 207 + 328 + + + 213 + 437 + 328 + + + 454 + 689 + 328 + + + 719 + 977 + 328 + + + 997 + 1292 + 328 + + + 1332 + 1781 + 328 + + + 1851 + 2320 + 328 + + + 2491 + 4241 + 266 + + + + + + + container + startColumn + + + 12 + + + 1 + 2 + 451 + + + 2 + 5 + 389 + + + 5 + 10 + 369 + + + 10 + 27 + 328 + + + 27 + 55 + 369 + + + 55 + 64 + 348 + + + 64 + 67 + 246 + + + 67 + 69 + 369 + + + 69 + 70 + 307 + + + 70 + 71 + 184 + + + 71 + 72 + 307 + + + 72 + 74 + 266 + + + 74 + 83 + 328 + + + 90 + 108 + 82 + + + + + + + container + endLine + + + 12 + + + 1 + 2 + 451 + + + 2 + 5 + 348 + + + 5 + 10 + 328 + + + 10 + 22 + 328 + + + 24 + 87 + 328 + + + 97 + 207 + 328 + + + 214 + 437 + 328 + + + 454 + 691 + 328 + + + 719 + 978 + 328 + + + 998 + 1293 + 328 + + + 1332 + 1785 + 328 + + + 1855 + 2324 + 328 + + + 2500 + 4416 + 266 + + + + + + + container + endColumn + + + 12 + + + 1 + 2 + 410 + + + 2 + 5 + 389 + + + 5 + 9 + 328 + + + 9 + 29 + 328 + + + 30 + 55 + 328 + + + 55 + 69 + 389 + + + 69 + 73 + 348 + + + 73 + 75 + 328 + + + 75 + 76 + 123 + + + 76 + 77 + 410 + + + 77 + 79 + 348 + + + 79 + 83 + 328 + + + 83 + 116 + 287 + + + + + + + startLine + id + + + 12 + + + 1 + 5 + 16078 + + + 5 + 9 + 16447 + + + 9 + 15 + 15996 + + + 15 + 23 + 15073 + + + 23 + 32 + 15114 + + + 32 + 44 + 14971 + + + 44 + 60 + 14724 + + + 60 + 80 + 14807 + + + 80 + 103 + 14581 + + + 103 + 130 + 14786 + + + 130 + 159 + 14560 + + + 159 + 194 + 14560 + + + 194 + 302 + 9782 + + + + + + + startLine + container + + + 12 + + + 1 + 2 + 23461 + + + 2 + 3 + 15586 + + + 3 + 4 + 11320 + + + 4 + 6 + 16324 + + + 6 + 8 + 13597 + + + 8 + 11 + 16406 + + + 11 + 16 + 17329 + + + 16 + 21 + 16406 + + + 21 + 28 + 16611 + + + 28 + 35 + 15955 + + + 35 + 43 + 15934 + + + 43 + 60 + 12551 + + + + + + + startLine + startColumn + + + 12 + + + 1 + 4 + 15934 + + + 4 + 7 + 17493 + + + 7 + 11 + 16652 + + + 11 + 16 + 17370 + + + 16 + 21 + 17473 + + + 21 + 26 + 15032 + + + 26 + 31 + 16140 + + + 31 + 36 + 17698 + + + 36 + 40 + 15791 + + + 40 + 44 + 16529 + + + 44 + 49 + 16591 + + + 49 + 63 + 8777 + + + + + + + startLine + endLine + + + 12 + + + 1 + 2 + 101762 + + + 2 + 3 + 44564 + + + 3 + 4 + 27501 + + + 4 + 6 + 14540 + + + 6 + 23 + 3117 + + + + + + + startLine + endColumn + + + 12 + + + 1 + 4 + 16919 + + + 4 + 7 + 16611 + + + 7 + 11 + 16386 + + + 11 + 16 + 16181 + + + 16 + 21 + 16406 + + + 21 + 27 + 16734 + + + 27 + 33 + 16406 + + + 33 + 38 + 14458 + + + 38 + 43 + 15504 + + + 43 + 47 + 14745 + + + 47 + 52 + 16714 + + + 52 + 65 + 14376 + + + 66 + 70 + 41 + + + + + + + startColumn + id + + + 12 + + + 1 + 2 + 307 + + + 2 + 4 + 184 + + + 4 + 8 + 205 + + + 8 + 26 + 205 + + + 43 + 251 + 184 + + + 279 + 840 + 184 + + + 951 + 1889 + 184 + + + 2097 + 4180 + 184 + + + 4240 + 7018 + 184 + + + 7166 + 11389 + 184 + + + 12326 + 15119 + 184 + + + 15349 + 30165 + 184 + + + 30211 + 49562 + 82 + + + + + + + startColumn + container + + + 12 + + + 1 + 2 + 328 + + + 2 + 3 + 123 + + + 3 + 4 + 143 + + + 4 + 6 + 184 + + + 7 + 28 + 184 + + + 41 + 98 + 184 + + + 103 + 122 + 184 + + + 123 + 130 + 205 + + + 132 + 138 + 184 + + + 138 + 142 + 205 + + + 142 + 144 + 184 + + + 144 + 148 + 184 + + + 149 + 155 + 164 + + + + + + + startColumn + startLine + + + 12 + + + 1 + 2 + 307 + + + 2 + 4 + 184 + + + 4 + 7 + 184 + + + 7 + 19 + 184 + + + 20 + 151 + 184 + + + 196 + 585 + 184 + + + 622 + 1287 + 184 + + + 1368 + 2342 + 184 + + + 2570 + 3505 + 184 + + + 3522 + 4711 + 184 + + + 4732 + 5298 + 184 + + + 5332 + 5999 + 184 + + + 6158 + 6996 + 123 + + + + + + + startColumn + endLine + + + 12 + + + 1 + 2 + 307 + + + 2 + 4 + 184 + + + 4 + 7 + 184 + + + 7 + 19 + 184 + + + 20 + 151 + 184 + + + 196 + 585 + 184 + + + 647 + 1289 + 184 + + + 1368 + 2346 + 184 + + + 2573 + 3511 + 184 + + + 3528 + 4712 + 184 + + + 4735 + 5324 + 184 + + + 5346 + 6023 + 184 + + + 6202 + 7039 + 123 + + + + + + + startColumn + endColumn + + + 12 + + + 1 + 2 + 328 + + + 2 + 3 + 123 + + + 3 + 5 + 184 + + + 5 + 9 + 184 + + + 9 + 13 + 184 + + + 13 + 20 + 184 + + + 20 + 30 + 184 + + + 30 + 42 + 184 + + + 44 + 59 + 184 + + + 59 + 69 + 205 + + + 69 + 74 + 184 + + + 74 + 83 + 184 + + + 83 + 96 + 143 + + + + + + + endLine + id + + + 12 + + + 1 + 5 + 16099 + + + 5 + 9 + 16447 + + + 9 + 15 + 15770 + + + 15 + 23 + 15053 + + + 23 + 32 + 15606 + + + 32 + 44 + 14704 + + + 44 + 60 + 14458 + + + 60 + 80 + 15237 + + + 80 + 103 + 14478 + + + 103 + 130 + 14786 + + + 130 + 159 + 14458 + + + 159 + 193 + 14376 + + + 193 + 299 + 9987 + + + + + + + endLine + container + + + 12 + + + 1 + 2 + 23461 + + + 2 + 3 + 15524 + + + 3 + 4 + 11320 + + + 4 + 6 + 16016 + + + 6 + 8 + 13453 + + + 8 + 11 + 16468 + + + 11 + 15 + 14458 + + + 15 + 20 + 16673 + + + 20 + 26 + 14971 + + + 26 + 33 + 16119 + + + 33 + 40 + 14724 + + + 40 + 49 + 14724 + + + 49 + 60 + 3547 + + + + + + + endLine + startLine + + + 12 + + + 1 + 2 + 95343 + + + 2 + 3 + 49835 + + + 3 + 4 + 29306 + + + 4 + 6 + 15565 + + + 6 + 11 + 1415 + + + + + + + endLine + startColumn + + + 12 + + + 1 + 4 + 15791 + + + 4 + 7 + 17411 + + + 7 + 11 + 16447 + + + 11 + 16 + 17309 + + + 16 + 21 + 17268 + + + 21 + 26 + 15114 + + + 26 + 31 + 16263 + + + 31 + 36 + 17678 + + + 36 + 40 + 15340 + + + 40 + 44 + 16591 + + + 44 + 49 + 16734 + + + 49 + 63 + 9515 + + + + + + + endLine + endColumn + + + 12 + + + 1 + 4 + 17144 + + + 4 + 7 + 16755 + + + 7 + 11 + 16386 + + + 11 + 16 + 16837 + + + 16 + 21 + 15975 + + + 21 + 26 + 14478 + + + 26 + 32 + 16119 + + + 32 + 37 + 14376 + + + 37 + 42 + 15832 + + + 42 + 46 + 14232 + + + 46 + 51 + 17247 + + + 51 + 59 + 14458 + + + 59 + 69 + 1620 + + + + + + + endColumn + id + + + 12 + + + 1 + 2 + 225 + + + 2 + 4 + 225 + + + 4 + 10 + 205 + + + 10 + 16 + 246 + + + 16 + 51 + 225 + + + 56 + 615 + 225 + + + 834 + 2288 + 225 + + + 2328 + 4150 + 225 + + + 4177 + 7133 + 225 + + + 8237 + 11757 + 225 + + + 12358 + 15463 + 225 + + + 15685 + 18241 + 225 + + + 18731 + 19130 + 82 + + + + + + + endColumn + container + + + 12 + + + 1 + 2 + 328 + + + 2 + 4 + 205 + + + 4 + 6 + 205 + + + 6 + 12 + 225 + + + 12 + 41 + 225 + + + 50 + 113 + 225 + + + 113 + 128 + 225 + + + 128 + 135 + 205 + + + 135 + 139 + 225 + + + 139 + 146 + 225 + + + 146 + 148 + 225 + + + 148 + 152 + 225 + + + 152 + 153 + 41 + + + + + + + endColumn + startLine + + + 12 + + + 1 + 2 + 307 + + + 2 + 4 + 164 + + + 4 + 8 + 246 + + + 8 + 15 + 225 + + + 18 + 53 + 225 + + + 74 + 491 + 225 + + + 512 + 1332 + 225 + + + 1392 + 2419 + 225 + + + 2763 + 3740 + 225 + + + 3801 + 4530 + 225 + + + 4641 + 5303 + 225 + + + 5377 + 5735 + 225 + + + 5747 + 5806 + 41 + + + + + + + endColumn + startColumn + + + 12 + + + 1 + 2 + 266 + + + 2 + 4 + 205 + + + 4 + 9 + 246 + + + 9 + 14 + 246 + + + 14 + 21 + 225 + + + 21 + 28 + 246 + + + 28 + 36 + 246 + + + 36 + 42 + 246 + + + 42 + 49 + 246 + + + 49 + 59 + 225 + + + 59 + 65 + 184 + + + 66 + 71 + 205 + + + + + + + endColumn + endLine + + + 12 + + + 1 + 2 + 307 + + + 2 + 4 + 164 + + + 4 + 8 + 246 + + + 8 + 15 + 225 + + + 17 + 53 + 225 + + + 74 + 473 + 225 + + + 500 + 1302 + 225 + + + 1356 + 2389 + 225 + + + 2626 + 3666 + 225 + + + 3731 + 4489 + 225 + + + 4638 + 5281 + 225 + + + 5366 + 5729 + 225 + + + 5734 + 5796 + 41 + + + + + + + + + numlines + 1411307 + + + element_id + 1404227 + + + num_lines + 103842 + + + num_code + 85433 + + + num_comment + 59945 + + + + + element_id + num_lines + + + 12 + + + 1 + 2 + 1397147 + + + 2 + 3 + 7080 + + + + + + + element_id + num_code + + + 12 + + + 1 + 2 + 1398091 + + + 2 + 3 + 6136 + + + + + + + element_id + num_comment + + + 12 + + + 1 + 2 + 1404227 + + + + + + + num_lines + element_id + + + 12 + + + 1 + 2 + 69385 + + + 2 + 3 + 14160 + + + 3 + 5 + 8496 + + + 5 + 63 + 8024 + + + 79 + 926 + 3776 + + + + + + + num_lines + num_code + + + 12 + + + 1 + 2 + 71745 + + + 2 + 3 + 14160 + + + 3 + 4 + 7552 + + + 4 + 6 + 8968 + + + 6 + 7 + 1416 + + + + + + + num_lines + num_comment + + + 12 + + + 1 + 2 + 70801 + + + 2 + 3 + 16992 + + + 3 + 4 + 9912 + + + 4 + 7 + 6136 + + + + + + + num_code + element_id + + + 12 + + + 1 + 2 + 52393 + + + 2 + 3 + 15104 + + + 3 + 5 + 6608 + + + 5 + 42 + 6608 + + + 45 + 927 + 4720 + + + + + + + num_code + num_lines + + + 12 + + + 1 + 2 + 52393 + + + 2 + 3 + 17464 + + + 3 + 5 + 6136 + + + 5 + 8 + 7080 + + + 8 + 12 + 2360 + + + + + + + num_code + num_comment + + + 12 + + + 1 + 2 + 52865 + + + 2 + 3 + 16520 + + + 3 + 5 + 7552 + + + 5 + 7 + 5192 + + + 7 + 10 + 3304 + + + + + + + num_comment + element_id + + + 12 + + + 1 + 2 + 34928 + + + 2 + 3 + 8496 + + + 3 + 4 + 4720 + + + 4 + 6 + 4720 + + + 6 + 11 + 5192 + + + 17 + 2622 + 1888 + + + + + + + num_comment + num_lines + + + 12 + + + 1 + 2 + 34928 + + + 2 + 3 + 8496 + + + 3 + 4 + 4720 + + + 4 + 6 + 4720 + + + 6 + 8 + 4720 + + + 10 + 37 + 2360 + + + + + + + num_comment + num_code + + + 12 + + + 1 + 2 + 34928 + + + 2 + 3 + 8496 + + + 3 + 4 + 4720 + + + 4 + 6 + 4720 + + + 6 + 10 + 4720 + + + 10 + 37 + 2360 + + + + + + + + + diagnostics + 667106 + + + id + 667106 + + + severity + 210 + + + error_tag + 7142 + + + error_message + 50629 + + + full_error_message + 666371 + + + location + 366903 + + + + + id + severity + + + 12 + + + 1 + 2 + 667106 + + + + + + + id + error_tag + + + 12 + + + 1 + 2 + 667106 + + + + + + + id + error_message + + + 12 + + + 1 + 2 + 667106 + + + + + + + id + full_error_message + + + 12 + + + 1 + 2 + 667106 + + + + + + + id + location + + + 12 + + + 1 + 2 + 667106 + + + + + + + severity + id + + + 12 + + + 375 + 376 + 105 + + + 5976 + 5977 + 105 + + + + + + + severity + error_tag + + + 12 + + + 4 + 5 + 105 + + + 64 + 65 + 105 + + + + + + + severity + error_message + + + 12 + + + 6 + 7 + 105 + + + 476 + 477 + 105 + + + + + + + severity + full_error_message + + + 12 + + + 375 + 376 + 105 + + + 5969 + 5970 + 105 + + + + + + + severity + location + + + 12 + + + 211 + 212 + 105 + + + 3378 + 3379 + 105 + + + + + + + error_tag + id + + + 12 + + + 1 + 2 + 735 + + + 2 + 3 + 735 + + + 3 + 4 + 525 + + + 4 + 6 + 630 + + + 6 + 8 + 630 + + + 8 + 14 + 630 + + + 14 + 17 + 525 + + + 18 + 30 + 630 + + + 33 + 51 + 630 + + + 52 + 149 + 630 + + + 200 + 808 + 630 + + + 845 + 1335 + 210 + + + + + + + error_tag + severity + + + 12 + + + 1 + 2 + 7142 + + + + + + + error_tag + error_message + + + 12 + + + 1 + 2 + 4726 + + + 2 + 3 + 630 + + + 3 + 4 + 420 + + + 4 + 6 + 630 + + + 6 + 53 + 630 + + + 249 + 250 + 105 + + + + + + + error_tag + full_error_message + + + 12 + + + 1 + 2 + 840 + + + 2 + 3 + 735 + + + 3 + 4 + 525 + + + 4 + 6 + 630 + + + 6 + 8 + 630 + + + 8 + 14 + 525 + + + 14 + 17 + 525 + + + 18 + 30 + 630 + + + 33 + 51 + 630 + + + 52 + 149 + 630 + + + 200 + 808 + 630 + + + 845 + 1335 + 210 + + + + + + + error_tag + location + + + 12 + + + 1 + 2 + 1155 + + + 2 + 3 + 840 + + + 3 + 4 + 735 + + + 4 + 5 + 420 + + + 5 + 6 + 420 + + + 6 + 8 + 525 + + + 8 + 13 + 630 + + + 14 + 25 + 630 + + + 25 + 51 + 630 + + + 57 + 219 + 630 + + + 382 + 733 + 525 + + + + + + + error_message + id + + + 12 + + + 1 + 2 + 20377 + + + 2 + 3 + 10503 + + + 3 + 4 + 2415 + + + 4 + 5 + 4411 + + + 5 + 7 + 3991 + + + 7 + 14 + 4096 + + + 14 + 67 + 3886 + + + 75 + 1335 + 945 + + + + + + + error_message + severity + + + 12 + + + 1 + 2 + 50629 + + + + + + + error_message + error_tag + + + 12 + + + 1 + 2 + 50629 + + + + + + + error_message + full_error_message + + + 12 + + + 1 + 2 + 20482 + + + 2 + 3 + 10503 + + + 3 + 4 + 2415 + + + 4 + 5 + 4411 + + + 5 + 7 + 3991 + + + 7 + 14 + 3991 + + + 14 + 67 + 3886 + + + 75 + 1335 + 945 + + + + + + + error_message + location + + + 12 + + + 1 + 2 + 32352 + + + 2 + 3 + 5987 + + + 3 + 5 + 3886 + + + 5 + 9 + 3886 + + + 9 + 86 + 3886 + + + 130 + 733 + 630 + + + + + + + full_error_message + id + + + 12 + + + 1 + 2 + 666266 + + + 8 + 9 + 105 + + + + + + + full_error_message + severity + + + 12 + + + 1 + 2 + 666371 + + + + + + + full_error_message + error_tag + + + 12 + + + 1 + 2 + 666371 + + + + + + + full_error_message + error_message + + + 12 + + + 1 + 2 + 666371 + + + + + + + full_error_message + location + + + 12 + + + 1 + 2 + 666371 + + + + + + + location + id + + + 12 + + + 1 + 2 + 184554 + + + 2 + 3 + 134345 + + + 3 + 5 + 31721 + + + 5 + 17 + 16281 + + + + + + + location + severity + + + 12 + + + 1 + 2 + 356819 + + + 2 + 3 + 10083 + + + + + + + location + error_tag + + + 12 + + + 1 + 2 + 349361 + + + 2 + 5 + 17541 + + + + + + + location + error_message + + + 12 + + + 1 + 2 + 348836 + + + 2 + 5 + 18066 + + + + + + + location + full_error_message + + + 12 + + + 1 + 2 + 184659 + + + 2 + 3 + 134345 + + + 3 + 5 + 31721 + + + 5 + 17 + 16176 + + + + + + + + + files + 124610 + + + id + 124610 + + + name + 124610 + + + + + id + name + + + 12 + + + 1 + 2 + 124610 + + + + + + + name + id + + + 12 + + + 1 + 2 + 124610 + + + + + + + + + folders + 15576 + + + id + 15576 + + + name + 15576 + + + + + id + name + + + 12 + + + 1 + 2 + 15576 + + + + + + + name + id + + + 12 + + + 1 + 2 + 15576 + + + + + + + + + containerparent + 139242 + + + parent + 15576 + + + child + 139242 + + + + + parent + child + + + 12 + + + 1 + 2 + 6608 + + + 2 + 3 + 3304 + + + 3 + 5 + 1416 + + + 5 + 12 + 1416 + + + 23 + 28 + 1416 + + + 40 + 67 + 1416 + + + + + + + child + parent + + + 12 + + + 1 + 2 + 139242 + + + + + + + + + fileannotations + 5264964 + + + id + 5028 + + + kind + 23 + + + name + 56220 + + + value + 47263 + + + + + id + kind + + + 12 + + + 1 + 2 + 173 + + + 2 + 3 + 4854 + + + + + + + id + name + + + 12 + + + 1 + 102 + 393 + + + 102 + 225 + 382 + + + 227 + 299 + 382 + + + 301 + 452 + 405 + + + 452 + 555 + 382 + + + 559 + 626 + 382 + + + 626 + 716 + 382 + + + 729 + 904 + 382 + + + 904 + 934 + 81 + + + 936 + 937 + 1459 + + + 1083 + 2036 + 382 + + + 2293 + 2294 + 11 + + + + + + + id + value + + + 12 + + + 1 + 114 + 393 + + + 114 + 275 + 382 + + + 275 + 363 + 382 + + + 393 + 638 + 382 + + + 643 + 744 + 382 + + + 751 + 955 + 382 + + + 955 + 1087 + 382 + + + 1088 + 1501 + 254 + + + 1501 + 1502 + 1459 + + + 1504 + 1874 + 382 + + + 1972 + 4080 + 243 + + + + + + + kind + id + + + 12 + + + 419 + 420 + 11 + + + 434 + 435 + 11 + + + + + + + kind + name + + + 12 + + + 2 + 3 + 11 + + + 4850 + 4851 + 11 + + + + + + + kind + value + + + 12 + + + 1 + 2 + 11 + + + 4079 + 4080 + 11 + + + + + + + name + id + + + 12 + + + 1 + 2 + 9095 + + + 2 + 3 + 6384 + + + 3 + 5 + 4287 + + + 5 + 9 + 4379 + + + 9 + 14 + 4090 + + + 14 + 18 + 4287 + + + 18 + 20 + 4843 + + + 20 + 34 + 4333 + + + 34 + 128 + 4623 + + + 128 + 229 + 4229 + + + 229 + 387 + 4356 + + + 387 + 434 + 1309 + + + + + + + name + kind + + + 12 + + + 1 + 2 + 56220 + + + + + + + name + value + + + 12 + + + 1 + 2 + 9107 + + + 2 + 3 + 8273 + + + 3 + 4 + 2630 + + + 4 + 6 + 4634 + + + 6 + 9 + 4240 + + + 9 + 14 + 4321 + + + 14 + 17 + 4240 + + + 17 + 22 + 4715 + + + 22 + 41 + 4321 + + + 41 + 82 + 4275 + + + 82 + 157 + 4217 + + + 158 + 1895 + 1239 + + + + + + + value + id + + + 12 + + + 1 + 2 + 7346 + + + 2 + 5 + 2294 + + + 5 + 8 + 3418 + + + 8 + 15 + 3626 + + + 15 + 17 + 2607 + + + 17 + 19 + 4252 + + + 19 + 34 + 3418 + + + 34 + 189 + 3719 + + + 189 + 201 + 3707 + + + 201 + 266 + 3649 + + + 266 + 321 + 3777 + + + 322 + 399 + 4055 + + + 399 + 435 + 1390 + + + + + + + value + kind + + + 12 + + + 1 + 2 + 47251 + + + 2 + 3 + 11 + + + + + + + value + name + + + 12 + + + 1 + 2 + 7369 + + + 2 + 5 + 2653 + + + 5 + 8 + 3603 + + + 8 + 15 + 3649 + + + 15 + 17 + 2908 + + + 17 + 19 + 3684 + + + 19 + 29 + 3603 + + + 29 + 39 + 3765 + + + 39 + 48 + 3707 + + + 48 + 74 + 3661 + + + 74 + 102 + 3545 + + + 102 + 119 + 3696 + + + 119 + 146 + 1413 + + + + + + + + + inmacroexpansion + 109305879 + + + id + 17940692 + + + inv + 2681885 + + + + + id + inv + + + 12 + + + 1 + 3 + 1565908 + + + 3 + 5 + 1071272 + + + 5 + 6 + 1179734 + + + 6 + 7 + 4799673 + + + 7 + 8 + 6358947 + + + 8 + 9 + 2595071 + + + 9 + 150 + 370084 + + + + + + + inv + id + + + 12 + + + 1 + 2 + 371830 + + + 2 + 3 + 540079 + + + 3 + 4 + 349893 + + + 4 + 7 + 199801 + + + 7 + 8 + 206276 + + + 8 + 9 + 240865 + + + 9 + 10 + 2201 + + + 10 + 11 + 324110 + + + 11 + 337 + 223895 + + + 339 + 422 + 201369 + + + 422 + 7616 + 21561 + + + + + + + + + affectedbymacroexpansion + 35538114 + + + id + 5134928 + + + inv + 2772993 + + + + + id + inv + + + 12 + + + 1 + 2 + 2804021 + + + 2 + 3 + 557759 + + + 3 + 4 + 263786 + + + 4 + 5 + 563401 + + + 5 + 12 + 390245 + + + 12 + 50 + 405678 + + + 50 + 9900 + 150035 + + + + + + + inv + id + + + 12 + + + 1 + 4 + 228146 + + + 4 + 7 + 230808 + + + 7 + 9 + 219545 + + + 9 + 12 + 250025 + + + 12 + 13 + 332565 + + + 13 + 14 + 164888 + + + 14 + 15 + 297580 + + + 15 + 16 + 121327 + + + 16 + 17 + 275438 + + + 17 + 18 + 146319 + + + 18 + 20 + 251068 + + + 20 + 25 + 208095 + + + 25 + 109 + 47183 + + + + + + + + + macroinvocations + 34062185 + + + id + 34062185 + + + macro_id + 81572 + + + location + 779877 + + + kind + 23 + + + + + id + macro_id + + + 12 + + + 1 + 2 + 34062185 + + + + + + + id + location + + + 12 + + + 1 + 2 + 34062185 + + + + + + + id + kind + + + 12 + + + 1 + 2 + 34062185 + + + + + + + macro_id + id + + + 12 + + + 1 + 2 + 16835 + + + 2 + 3 + 17322 + + + 3 + 4 + 3846 + + + 4 + 6 + 7323 + + + 6 + 11 + 7265 + + + 11 + 21 + 6546 + + + 21 + 47 + 6257 + + + 47 + 143 + 6117 + + + 143 + 934 + 6152 + + + 934 + 168391 + 3904 + + + + + + + macro_id + location + + + 12 + + + 1 + 2 + 43648 + + + 2 + 3 + 10648 + + + 3 + 4 + 5295 + + + 4 + 6 + 7010 + + + 6 + 13 + 6627 + + + 13 + 66 + 6152 + + + 66 + 3614 + 2189 + + + + + + + macro_id + kind + + + 12 + + + 1 + 2 + 75732 + + + 2 + 3 + 5839 + + + + + + + location + id + + + 12 + + + 1 + 2 + 297219 + + + 2 + 3 + 195287 + + + 3 + 4 + 48978 + + + 4 + 5 + 57610 + + + 5 + 8 + 59059 + + + 8 + 17 + 59267 + + + 17 + 934 + 58572 + + + 942 + 244474 + 3881 + + + + + + + location + macro_id + + + 12 + + + 1 + 2 + 732509 + + + 2 + 350 + 47367 + + + + + + + location + kind + + + 12 + + + 1 + 2 + 779877 + + + + + + + kind + id + + + 12 + + + 21085 + 21086 + 11 + + + 2918595 + 2918596 + 11 + + + + + + + kind + macro_id + + + 12 + + + 2123 + 2124 + 11 + + + 5421 + 5422 + 11 + + + + + + + kind + location + + + 12 + + + 6289 + 6290 + 11 + + + 61017 + 61018 + 11 + + + + + + + + + macroparent + 30544569 + + + id + 30544569 + + + parent_id + 23768631 + + + + + id + parent_id + + + 12 + + + 1 + 2 + 30544569 + + + + + + + parent_id + id + + + 12 + + + 1 + 2 + 18363231 + + + 2 + 3 + 4552338 + + + 3 + 88 + 853060 + + + + + + + + + macrolocationbind + 3984360 + + + id + 2778691 + + + location + 1988314 + + + + + id + location + + + 12 + + + 1 + 2 + 2182951 + + + 2 + 3 + 336419 + + + 3 + 7 + 229799 + + + 7 + 57 + 29521 + + + + + + + location + id + + + 12 + + + 1 + 2 + 1589477 + + + 2 + 3 + 169635 + + + 3 + 8 + 154222 + + + 8 + 723 + 74979 + + + + + + + + + macro_argument_unexpanded + 86422356 + + + invocation + 26658798 + + + argument_index + 764 + + + text + 326615 + + + + + invocation + argument_index + + + 12 + + + 1 + 2 + 7473686 + + + 2 + 3 + 10892801 + + + 3 + 4 + 6274590 + + + 4 + 67 + 2017720 + + + + + + + invocation + text + + + 12 + + + 1 + 2 + 7545213 + + + 2 + 3 + 11043502 + + + 3 + 4 + 6104017 + + + 4 + 67 + 1966065 + + + + + + + argument_index + invocation + + + 12 + + + 41253 + 41254 + 672 + + + 41455 + 174137 + 57 + + + 715654 + 2300744 + 34 + + + + + + + argument_index + text + + + 12 + + + 2 + 3 + 672 + + + 13 + 995 + 57 + + + 6559 + 19569 + 34 + + + + + + + text + invocation + + + 12 + + + 1 + 2 + 39998 + + + 2 + 3 + 66161 + + + 3 + 4 + 14947 + + + 4 + 5 + 44065 + + + 5 + 7 + 24761 + + + 7 + 12 + 18643 + + + 12 + 16 + 22281 + + + 16 + 23 + 26673 + + + 23 + 43 + 24784 + + + 43 + 164 + 24506 + + + 164 + 521728 + 19790 + + + + + + + text + argument_index + + + 12 + + + 1 + 2 + 236190 + + + 2 + 3 + 79869 + + + 3 + 9 + 10555 + + + + + + + + + macro_argument_expanded + 86422356 + + + invocation + 26658798 + + + argument_index + 764 + + + text + 197906 + + + + + invocation + argument_index + + + 12 + + + 1 + 2 + 7473686 + + + 2 + 3 + 10892801 + + + 3 + 4 + 6274590 + + + 4 + 67 + 2017720 + + + + + + + invocation + text + + + 12 + + + 1 + 2 + 10794971 + + + 2 + 3 + 9400379 + + + 3 + 4 + 5321625 + + + 4 + 9 + 1141821 + + + + + + + argument_index + invocation + + + 12 + + + 41253 + 41254 + 672 + + + 41455 + 174137 + 57 + + + 715654 + 2300744 + 34 + + + + + + + argument_index + text + + + 12 + + + 1 + 2 + 660 + + + 2 + 76 + 57 + + + 870 + 13871 + 46 + + + + + + + text + invocation + + + 12 + + + 1 + 2 + 24008 + + + 2 + 3 + 41238 + + + 3 + 4 + 6940 + + + 4 + 5 + 15874 + + + 5 + 6 + 3835 + + + 6 + 7 + 23324 + + + 7 + 9 + 15457 + + + 9 + 15 + 17345 + + + 15 + 30 + 14842 + + + 30 + 89 + 14947 + + + 90 + 505 + 14854 + + + 510 + 1054483 + 5237 + + + + + + + text + argument_index + + + 12 + + + 1 + 2 + 100112 + + + 2 + 3 + 83009 + + + 3 + 66 + 14785 + + + + + + + + + functions + 4759741 + + + id + 4759741 + + + name + 1941845 + + + kind + 3304 + + + + + id + name + + + 12 + + + 1 + 2 + 4759741 + + + + + + + id + kind + + + 12 + + + 1 + 2 + 4759741 + + + + + + + name + id + + + 12 + + + 1 + 2 + 1523173 + + + 2 + 3 + 153875 + + + 3 + 5 + 151986 + + + 5 + 1754 + 112810 + + + + + + + name + kind + + + 12 + + + 1 + 2 + 1941373 + + + 2 + 3 + 472 + + + + + + + kind + id + + + 12 + + + 6 + 7 + 472 + + + 64 + 65 + 472 + + + 173 + 174 + 472 + + + 195 + 196 + 472 + + + 1365 + 1366 + 472 + + + 2462 + 2463 + 472 + + + 5819 + 5820 + 472 + + + + + + + kind + name + + + 12 + + + 3 + 4 + 472 + + + 33 + 34 + 472 + + + 39 + 40 + 472 + + + 94 + 95 + 472 + + + 195 + 196 + 472 + + + 246 + 247 + 472 + + + 3505 + 3506 + 472 + + + + + + + + + function_entry_point + 1180967 + + + id + 1171054 + + + entry_point + 1180967 + + + + + id + entry_point + + + 12 + + + 1 + 2 + 1161142 + + + 2 + 3 + 9912 + + + + + + + entry_point + id + + + 12 + + + 1 + 2 + 1180967 + + + + + + + + + function_return_type + 4768237 + + + id + 4759741 + + + return_type + 1027092 + + + + + id + return_type + + + 12 + + + 1 + 2 + 4752660 + + + 2 + 5 + 7080 + + + + + + + return_type + id + + + 12 + + + 1 + 2 + 524874 + + + 2 + 3 + 398847 + + + 3 + 11 + 78825 + + + 11 + 2523 + 24544 + + + + + + + + + coroutine + 2 + + + function + 2 + + + traits + 2 + + + handle + 2 + + + promise + 2 + + + + + function + traits + + + 12 + + + 1 + 2 + 2 + + + + + + + function + handle + + + 12 + + + 1 + 2 + 2 + + + + + + + function + promise + + + 12 + + + 1 + 2 + 2 + + + + + + + traits + function + + + 12 + + + 1 + 2 + 2 + + + + + + + traits + handle + + + 12 + + + 1 + 2 + 2 + + + + + + + traits + promise + + + 12 + + + 1 + 2 + 2 + + + + + + + handle + function + + + 12 + + + 1 + 2 + 2 + + + + + + + handle + traits + + + 12 + + + 1 + 2 + 2 + + + + + + + handle + promise + + + 12 + + + 1 + 2 + 2 + + + + + + + promise + function + + + 12 + + + 1 + 2 + 2 + + + + + + + promise + traits + + + 12 + + + 1 + 2 + 2 + + + + + + + promise + handle + + + 12 + + + 1 + 2 + 2 + + + + + + + + + coroutine_new + 2 + + + function + 2 + + + new + 1 + + + + + function + new + + + 12 + + + 1 + 2 + 2 + + + + + + + new + function + + + 12 + + + 2 + 3 + 1 + + + + + + + + + coroutine_delete + 2 + + + function + 2 + + + delete + 1 + + + + + function + delete + + + 12 + + + 1 + 2 + 2 + + + + + + + delete + function + + + 12 + + + 2 + 3 + 1 + + + + + + + + + purefunctions + 99735 + + + id + 99735 + + + + + + function_deleted + 141130 + + + id + 141130 + + + + + + function_defaulted + 74577 + + + id + 74577 + + + + + + member_function_this_type + 549916 + + + id + 549916 + + + this_type + 188354 + + + + + id + this_type + + + 12 + + + 1 + 2 + 549916 + + + + + + + this_type + id + + + 12 + + + 1 + 2 + 68044 + + + 2 + 3 + 45024 + + + 3 + 4 + 30331 + + + 4 + 5 + 15428 + + + 5 + 7 + 15497 + + + 7 + 66 + 14028 + + + + + + + + + fun_decls + 5136876 + + + id + 5131684 + + + function + 4611530 + + + type_id + 1023788 + + + name + 1843196 + + + location + 3473987 + + + + + id + function + + + 12 + + + 1 + 2 + 5131684 + + + + + + + id + type_id + + + 12 + + + 1 + 2 + 5126492 + + + 2 + 3 + 5192 + + + + + + + id + name + + + 12 + + + 1 + 2 + 5131684 + + + + + + + id + location + + + 12 + + + 1 + 2 + 5131684 + + + + + + + function + id + + + 12 + + + 1 + 2 + 4172561 + + + 2 + 3 + 364391 + + + 3 + 7 + 74577 + + + + + + + function + type_id + + + 12 + + + 1 + 2 + 4569521 + + + 2 + 5 + 42008 + + + + + + + function + name + + + 12 + + + 1 + 2 + 4611530 + + + + + + + function + location + + + 12 + + + 1 + 2 + 4229674 + + + 2 + 4 + 380439 + + + 4 + 6 + 1416 + + + + + + + type_id + id + + + 12 + + + 1 + 2 + 447464 + + + 2 + 3 + 462097 + + + 3 + 9 + 79769 + + + 9 + 2775 + 34456 + + + + + + + type_id + function + + + 12 + + + 1 + 2 + 532426 + + + 2 + 3 + 390351 + + + 3 + 11 + 77409 + + + 11 + 2484 + 23600 + + + + + + + type_id + name + + + 12 + + + 1 + 2 + 893985 + + + 2 + 5 + 90625 + + + 5 + 824 + 39176 + + + + + + + type_id + location + + + 12 + + + 1 + 2 + 789199 + + + 2 + 3 + 133578 + + + 3 + 11 + 78353 + + + 11 + 2032 + 22656 + + + + + + + name + id + + + 12 + + + 1 + 2 + 1250824 + + + 2 + 3 + 269517 + + + 3 + 4 + 80713 + + + 4 + 6 + 139714 + + + 6 + 1788 + 102426 + + + + + + + name + function + + + 12 + + + 1 + 2 + 1432076 + + + 2 + 3 + 152930 + + + 3 + 5 + 146322 + + + 5 + 1738 + 111866 + + + + + + + name + type_id + + + 12 + + + 1 + 2 + 1622295 + + + 2 + 4 + 135466 + + + 4 + 969 + 85433 + + + + + + + name + location + + + 12 + + + 1 + 2 + 1272064 + + + 2 + 3 + 297365 + + + 3 + 4 + 79769 + + + 4 + 8 + 139714 + + + 8 + 666 + 54281 + + + + + + + location + id + + + 12 + + + 1 + 2 + 3005754 + + + 2 + 4 + 304445 + + + 4 + 55 + 163787 + + + + + + + location + function + + + 12 + + + 1 + 2 + 3073724 + + + 2 + 6 + 270933 + + + 6 + 55 + 129330 + + + + + + + location + type_id + + + 12 + + + 1 + 2 + 3256863 + + + 2 + 27 + 217124 + + + + + + + location + name + + + 12 + + + 1 + 2 + 3296512 + + + 2 + 13 + 177475 + + + + + + + + + fun_def + 1970638 + + + id + 1970638 + + + + + + fun_specialized + 26432 + + + id + 26432 + + + + + + fun_implicit + 198 + + + id + 198 + + + + + + fun_decl_specifiers + 2947225 + + + id + 1716697 + + + name + 2832 + + + + + id + name + + + 12 + + + 1 + 2 + 505049 + + + 2 + 3 + 1192767 + + + 3 + 4 + 18880 + + + + + + + name + id + + + 12 + + + 50 + 51 + 472 + + + 203 + 204 + 472 + + + 209 + 210 + 472 + + + 657 + 658 + 472 + + + 2561 + 2562 + 472 + + + 2564 + 2565 + 472 + + + + + + + + + fun_decl_throws + 7 + + + fun_decl + 7 + + + index + 1 + + + type_id + 2 + + + + + fun_decl + index + + + 12 + + + 1 + 2 + 7 + + + + + + + fun_decl + type_id + + + 12 + + + 1 + 2 + 7 + + + + + + + index + fun_decl + + + 12 + + + 7 + 8 + 1 + + + + + + + index + type_id + + + 12 + + + 2 + 3 + 1 + + + + + + + type_id + fun_decl + + + 12 + + + 1 + 2 + 1 + + + 6 + 7 + 1 + + + + + + + type_id + index + + + 12 + + + 1 + 2 + 2 + + + + + + + + + fun_decl_empty_throws + 2002263 + + + fun_decl + 2002263 + + + + + + fun_decl_noexcept + 61343 + + + fun_decl + 61343 + + + constant + 61238 + + + + + fun_decl + constant + + + 12 + + + 1 + 2 + 61343 + + + + + + + constant + fun_decl + + + 12 + + + 1 + 2 + 61133 + + + 2 + 3 + 105 + + + + + + + + + fun_decl_empty_noexcept + 890209 + + + fun_decl + 890209 + + + + + + fun_decl_typedef_type + 2891 + + + fun_decl + 2891 + + + typedeftype_id + 130 + + + + + fun_decl + typedeftype_id + + + 12 + + + 1 + 2 + 2891 + + + + + + + typedeftype_id + fun_decl + + + 12 + + + 1 + 2 + 42 + + + 2 + 3 + 12 + + + 3 + 4 + 12 + + + 5 + 13 + 8 + + + 16 + 17 + 12 + + + 17 + 18 + 4 + + + 21 + 22 + 8 + + + 25 + 43 + 8 + + + 46 + 55 + 8 + + + 87 + 128 + 8 + + + 158 + 159 + 4 + + + + + + + + + param_decl_bind + 7511554 + + + id + 7511554 + + + index + 8024 + + + fun_decl + 4315108 + + + + + id + index + + + 12 + + + 1 + 2 + 7511554 + + + + + + + id + fun_decl + + + 12 + + + 1 + 2 + 7511554 + + + + + + + index + id + + + 12 + + + 2 + 3 + 944 + + + 5 + 6 + 472 + + + 7 + 8 + 472 + + + 10 + 11 + 944 + + + 11 + 12 + 472 + + + 12 + 13 + 944 + + + 13 + 14 + 472 + + + 25 + 26 + 472 + + + 78 + 79 + 472 + + + 245 + 246 + 472 + + + 636 + 637 + 472 + + + 1713 + 1714 + 472 + + + 3991 + 3992 + 472 + + + 9142 + 9143 + 472 + + + + + + + index + fun_decl + + + 12 + + + 2 + 3 + 944 + + + 5 + 6 + 472 + + + 7 + 8 + 472 + + + 10 + 11 + 944 + + + 11 + 12 + 472 + + + 12 + 13 + 944 + + + 13 + 14 + 472 + + + 25 + 26 + 472 + + + 78 + 79 + 472 + + + 245 + 246 + 472 + + + 636 + 637 + 472 + + + 1713 + 1714 + 472 + + + 3991 + 3992 + 472 + + + 9142 + 9143 + 472 + + + + + + + fun_decl + id + + + 12 + + + 1 + 2 + 2431319 + + + 2 + 3 + 1075237 + + + 3 + 4 + 508353 + + + 4 + 18 + 300197 + + + + + + + fun_decl + index + + + 12 + + + 1 + 2 + 2431319 + + + 2 + 3 + 1075237 + + + 3 + 4 + 508353 + + + 4 + 18 + 300197 + + + + + + + + + var_decls + 8655233 + + + id + 8586319 + + + variable + 7559699 + + + type_id + 2453031 + + + name + 674973 + + + location + 5383265 + + + + + id + variable + + + 12 + + + 1 + 2 + 8586319 + + + + + + + id + type_id + + + 12 + + + 1 + 2 + 8517406 + + + 2 + 3 + 68913 + + + + + + + id + name + + + 12 + + + 1 + 2 + 8586319 + + + + + + + id + location + + + 12 + + + 1 + 2 + 8586319 + + + + + + + variable + id + + + 12 + + + 1 + 2 + 6694978 + + + 2 + 3 + 709429 + + + 3 + 7 + 155291 + + + + + + + variable + type_id + + + 12 + + + 1 + 2 + 7386000 + + + 2 + 4 + 173699 + + + + + + + variable + name + + + 12 + + + 1 + 2 + 7442169 + + + 2 + 3 + 117530 + + + + + + + variable + location + + + 12 + + + 1 + 2 + 7005089 + + + 2 + 4 + 554610 + + + + + + + type_id + id + + + 12 + + + 1 + 2 + 1525061 + + + 2 + 3 + 517794 + + + 3 + 4 + 99121 + + + 4 + 7 + 189275 + + + 7 + 780 + 121778 + + + + + + + type_id + variable + + + 12 + + + 1 + 2 + 1660056 + + + 2 + 3 + 492777 + + + 3 + 7 + 188803 + + + 7 + 742 + 111394 + + + + + + + type_id + name + + + 12 + + + 1 + 2 + 1939485 + + + 2 + 3 + 389879 + + + 3 + 128 + 123666 + + + + + + + type_id + location + + + 12 + + + 1 + 2 + 1763898 + + + 2 + 3 + 408287 + + + 3 + 8 + 190691 + + + 8 + 595 + 90153 + + + + + + + name + id + + + 12 + + + 1 + 2 + 345038 + + + 2 + 3 + 87793 + + + 3 + 4 + 49088 + + + 4 + 6 + 52393 + + + 6 + 12 + 52865 + + + 12 + 33 + 50976 + + + 34 + 3311 + 36816 + + + + + + + name + variable + + + 12 + + + 1 + 2 + 372887 + + + 2 + 3 + 78825 + + + 3 + 4 + 45784 + + + 4 + 6 + 50032 + + + 6 + 14 + 53809 + + + 14 + 56 + 51449 + + + 56 + 3228 + 22184 + + + + + + + name + type_id + + + 12 + + + 1 + 2 + 462097 + + + 2 + 3 + 94873 + + + 3 + 5 + 47200 + + + 5 + 19 + 51449 + + + 19 + 2009 + 19352 + + + + + + + name + location + + + 12 + + + 1 + 2 + 383271 + + + 2 + 3 + 91569 + + + 3 + 5 + 60417 + + + 5 + 9 + 51921 + + + 9 + 21 + 50976 + + + 21 + 1020 + 36816 + + + + + + + location + id + + + 12 + + + 1 + 2 + 4551113 + + + 2 + 3 + 552250 + + + 3 + 1813 + 279901 + + + + + + + location + variable + + + 12 + + + 1 + 2 + 4956568 + + + 2 + 17 + 415840 + + + 17 + 1809 + 10856 + + + + + + + location + type_id + + + 12 + + + 1 + 2 + 5033506 + + + 2 + 1591 + 349758 + + + + + + + location + name + + + 12 + + + 1 + 2 + 5379017 + + + 2 + 24 + 4248 + + + + + + + + + var_def + 4097512 + + + id + 4097512 + + + + + + var_decl_specifiers + 336070 + + + id + 336070 + + + name + 1416 + + + + + id + name + + + 12 + + + 1 + 2 + 336070 + + + + + + + name + id + + + 12 + + + 15 + 16 + 472 + + + 66 + 67 + 472 + + + 631 + 632 + 472 + + + + + + + + + is_structured_binding + 10 + + + id + 10 + + + + + + type_decls + 3292736 + + + id + 3292736 + + + type_id + 3241759 + + + location + 3212494 + + + + + id + type_id + + + 12 + + + 1 + 2 + 3292736 + + + + + + + id + location + + + 12 + + + 1 + 2 + 3292736 + + + + + + + type_id + id + + + 12 + + + 1 + 2 + 3199750 + + + 2 + 5 + 42008 + + + + + + + type_id + location + + + 12 + + + 1 + 2 + 3199750 + + + 2 + 5 + 42008 + + + + + + + location + id + + + 12 + + + 1 + 2 + 3171430 + + + 2 + 20 + 41064 + + + + + + + location + type_id + + + 12 + + + 1 + 2 + 3171430 + + + 2 + 20 + 41064 + + + + + + + + + type_def + 2666852 + + + id + 2666852 + + + + + + type_decl_top + 758990 + + + type_decl + 758990 + + + + + + namespace_decls + 307863 + + + id + 307863 + + + namespace_id + 1418 + + + location + 307863 + + + bodylocation + 307863 + + + + + id + namespace_id + + + 12 + + + 1 + 2 + 307863 + + + + + + + id + location + + + 12 + + + 1 + 2 + 307863 + + + + + + + id + bodylocation + + + 12 + + + 1 + 2 + 307863 + + + + + + + namespace_id + id + + + 12 + + + 1 + 2 + 296 + + + 2 + 3 + 157 + + + 3 + 6 + 126 + + + 6 + 14 + 107 + + + 14 + 30 + 107 + + + 30 + 57 + 119 + + + 57 + 80 + 113 + + + 80 + 127 + 107 + + + 129 + 199 + 107 + + + 201 + 504 + 107 + + + 512 + 12128 + 69 + + + + + + + namespace_id + location + + + 12 + + + 1 + 2 + 296 + + + 2 + 3 + 157 + + + 3 + 6 + 126 + + + 6 + 14 + 107 + + + 14 + 30 + 107 + + + 30 + 57 + 119 + + + 57 + 80 + 113 + + + 80 + 127 + 107 + + + 129 + 199 + 107 + + + 201 + 504 + 107 + + + 512 + 12128 + 69 + + + + + + + namespace_id + bodylocation + + + 12 + + + 1 + 2 + 296 + + + 2 + 3 + 157 + + + 3 + 6 + 126 + + + 6 + 14 + 107 + + + 14 + 30 + 107 + + + 30 + 57 + 119 + + + 57 + 80 + 113 + + + 80 + 127 + 107 + + + 129 + 199 + 107 + + + 201 + 504 + 107 + + + 512 + 12128 + 69 + + + + + + + location + id + + + 12 + + + 1 + 2 + 307863 + + + + + + + location + namespace_id + + + 12 + + + 1 + 2 + 307863 + + + + + + + location + bodylocation + + + 12 + + + 1 + 2 + 307863 + + + + + + + bodylocation + id + + + 12 + + + 1 + 2 + 307863 + + + + + + + bodylocation + namespace_id + + + 12 + + + 1 + 2 + 307863 + + + + + + + bodylocation + location + + + 12 + + + 1 + 2 + 307863 + + + + + + + + + usings + 375719 + + + id + 375719 + + + element_id + 319078 + + + location + 250164 + + + + + id + element_id + + + 12 + + + 1 + 2 + 375719 + + + + + + + id + location + + + 12 + + + 1 + 2 + 375719 + + + + + + + element_id + id + + + 12 + + + 1 + 2 + 264325 + + + 2 + 3 + 53337 + + + 3 + 5 + 1416 + + + + + + + element_id + location + + + 12 + + + 1 + 2 + 264325 + + + 2 + 3 + 53337 + + + 3 + 5 + 1416 + + + + + + + location + id + + + 12 + + + 1 + 2 + 203907 + + + 2 + 4 + 11328 + + + 4 + 5 + 31624 + + + 5 + 11 + 3304 + + + + + + + location + element_id + + + 12 + + + 1 + 2 + 203907 + + + 2 + 4 + 11328 + + + 4 + 5 + 31624 + + + 5 + 11 + 3304 + + + + + + + + + using_container + 479100 + + + parent + 11308 + + + child + 303777 + + + + + parent + child + + + 12 + + + 1 + 2 + 3348 + + + 2 + 4 + 961 + + + 4 + 6 + 428 + + + 6 + 7 + 2560 + + + 7 + 17 + 926 + + + 19 + 143 + 787 + + + 178 + 179 + 1332 + + + 179 + 183 + 880 + + + 201 + 488 + 81 + + + + + + + child + parent + + + 12 + + + 1 + 2 + 224046 + + + 2 + 3 + 53091 + + + 3 + 11 + 24448 + + + 13 + 41 + 2189 + + + + + + + + + static_asserts + 130790 + + + id + 130790 + + + condition + 130790 + + + message + 29535 + + + location + 16816 + + + enclosing + 1948 + + + + + id + condition + + + 12 + + + 1 + 2 + 130790 + + + + + + + id + message + + + 12 + + + 1 + 2 + 130790 + + + + + + + id + location + + + 12 + + + 1 + 2 + 130790 + + + + + + + id + enclosing + + + 12 + + + 1 + 2 + 130790 + + + + + + + condition + id + + + 12 + + + 1 + 2 + 130790 + + + + + + + condition + message + + + 12 + + + 1 + 2 + 130790 + + + + + + + condition + location + + + 12 + + + 1 + 2 + 130790 + + + + + + + condition + enclosing + + + 12 + + + 1 + 2 + 130790 + + + + + + + message + id + + + 12 + + + 1 + 2 + 22006 + + + 2 + 3 + 403 + + + 3 + 4 + 2774 + + + 4 + 11 + 1425 + + + 12 + 17 + 2383 + + + 17 + 513 + 542 + + + + + + + message + condition + + + 12 + + + 1 + 2 + 22006 + + + 2 + 3 + 403 + + + 3 + 4 + 2774 + + + 4 + 11 + 1425 + + + 12 + 17 + 2383 + + + 17 + 513 + 542 + + + + + + + message + location + + + 12 + + + 1 + 2 + 27416 + + + 2 + 33 + 2118 + + + + + + + message + enclosing + + + 12 + + + 1 + 2 + 23425 + + + 2 + 3 + 189 + + + 3 + 4 + 2572 + + + 4 + 11 + 1267 + + + 12 + 21 + 2080 + + + + + + + location + id + + + 12 + + + 1 + 2 + 3133 + + + 2 + 3 + 2705 + + + 3 + 4 + 1311 + + + 5 + 6 + 3632 + + + 6 + 13 + 182 + + + 14 + 15 + 2055 + + + 16 + 17 + 37 + + + 17 + 18 + 3411 + + + 19 + 52 + 346 + + + + + + + location + condition + + + 12 + + + 1 + 2 + 3133 + + + 2 + 3 + 2705 + + + 3 + 4 + 1311 + + + 5 + 6 + 3632 + + + 6 + 13 + 182 + + + 14 + 15 + 2055 + + + 16 + 17 + 37 + + + 17 + 18 + 3411 + + + 19 + 52 + 346 + + + + + + + location + message + + + 12 + + + 1 + 2 + 4634 + + + 2 + 3 + 5958 + + + 3 + 4 + 6040 + + + 4 + 7 + 182 + + + + + + + location + enclosing + + + 12 + + + 1 + 2 + 3739 + + + 2 + 3 + 6129 + + + 3 + 4 + 1084 + + + 4 + 5 + 3600 + + + 5 + 6 + 189 + + + 13 + 14 + 2055 + + + 16 + 21 + 18 + + + + + + + enclosing + id + + + 12 + + + 1 + 2 + 1380 + + + 2 + 3 + 138 + + + 3 + 10 + 163 + + + 10 + 180 + 138 + + + 209 + 11052 + 126 + + + + + + + enclosing + condition + + + 12 + + + 1 + 2 + 1380 + + + 2 + 3 + 138 + + + 3 + 10 + 163 + + + 10 + 180 + 138 + + + 209 + 11052 + 126 + + + + + + + enclosing + message + + + 12 + + + 1 + 2 + 1551 + + + 2 + 6 + 151 + + + 9 + 210 + 170 + + + 223 + 2936 + 75 + + + + + + + enclosing + location + + + 12 + + + 1 + 2 + 1538 + + + 2 + 5 + 157 + + + 5 + 210 + 176 + + + 223 + 1929 + 75 + + + + + + + + + params + 6863014 + + + id + 6696867 + + + function + 3967709 + + + index + 8024 + + + type_id + 2256204 + + + + + id + function + + + 12 + + + 1 + 2 + 6696867 + + + + + + + id + index + + + 12 + + + 1 + 2 + 6696867 + + + + + + + id + type_id + + + 12 + + + 1 + 2 + 6571312 + + + 2 + 4 + 125554 + + + + + + + function + id + + + 12 + + + 1 + 2 + 2325117 + + + 2 + 3 + 963842 + + + 3 + 4 + 434720 + + + 4 + 18 + 244028 + + + + + + + function + index + + + 12 + + + 1 + 2 + 2325117 + + + 2 + 3 + 963842 + + + 3 + 4 + 434720 + + + 4 + 18 + 244028 + + + + + + + function + type_id + + + 12 + + + 1 + 2 + 2628619 + + + 2 + 3 + 834040 + + + 3 + 4 + 350702 + + + 4 + 12 + 154347 + + + + + + + index + id + + + 12 + + + 2 + 3 + 944 + + + 4 + 5 + 472 + + + 6 + 7 + 472 + + + 8 + 9 + 944 + + + 9 + 10 + 472 + + + 10 + 11 + 944 + + + 11 + 12 + 472 + + + 19 + 20 + 472 + + + 64 + 65 + 472 + + + 194 + 195 + 472 + + + 517 + 518 + 472 + + + 1438 + 1439 + 472 + + + 3480 + 3481 + 472 + + + 8406 + 8407 + 472 + + + + + + + index + function + + + 12 + + + 2 + 3 + 944 + + + 4 + 5 + 472 + + + 6 + 7 + 472 + + + 8 + 9 + 944 + + + 9 + 10 + 472 + + + 10 + 11 + 944 + + + 11 + 12 + 472 + + + 19 + 20 + 472 + + + 64 + 65 + 472 + + + 194 + 195 + 472 + + + 517 + 518 + 472 + + + 1438 + 1439 + 472 + + + 3480 + 3481 + 472 + + + 8406 + 8407 + 472 + + + + + + + index + type_id + + + 12 + + + 1 + 2 + 944 + + + 3 + 4 + 472 + + + 4 + 5 + 472 + + + 5 + 6 + 472 + + + 6 + 7 + 1416 + + + 7 + 8 + 944 + + + 11 + 12 + 472 + + + 42 + 43 + 472 + + + 106 + 107 + 472 + + + 228 + 229 + 472 + + + 582 + 583 + 472 + + + 1275 + 1276 + 472 + + + 3696 + 3697 + 472 + + + + + + + type_id + id + + + 12 + + + 1 + 2 + 1544886 + + + 2 + 3 + 447936 + + + 3 + 8 + 172283 + + + 8 + 522 + 91097 + + + + + + + type_id + function + + + 12 + + + 1 + 2 + 1769090 + + + 2 + 3 + 251580 + + + 3 + 9 + 170395 + + + 9 + 506 + 65137 + + + + + + + type_id + index + + + 12 + + + 1 + 2 + 1821955 + + + 2 + 3 + 354478 + + + 3 + 13 + 79769 + + + + + + + + + overrides + 160287 + + + new + 125386 + + + old + 15139 + + + + + new + old + + + 12 + + + 1 + 2 + 90491 + + + 2 + 3 + 34888 + + + 3 + 4 + 6 + + + + + + + old + new + + + 12 + + + 1 + 2 + 7945 + + + 2 + 3 + 1910 + + + 3 + 4 + 989 + + + 4 + 5 + 1324 + + + 5 + 11 + 1216 + + + 11 + 60 + 1166 + + + 61 + 231 + 586 + + + + + + + + + membervariables + 1051799 + + + id + 1050009 + + + type_id + 326270 + + + name + 449611 + + + + + id + type_id + + + 12 + + + 1 + 2 + 1048298 + + + 2 + 4 + 1710 + + + + + + + id + name + + + 12 + + + 1 + 2 + 1050009 + + + + + + + type_id + id + + + 12 + + + 1 + 2 + 241948 + + + 2 + 3 + 51667 + + + 3 + 10 + 25415 + + + 10 + 4152 + 7238 + + + + + + + type_id + name + + + 12 + + + 1 + 2 + 254119 + + + 2 + 3 + 46257 + + + 3 + 40 + 24501 + + + 41 + 2031 + 1392 + + + + + + + name + id + + + 12 + + + 1 + 2 + 294013 + + + 2 + 3 + 86151 + + + 3 + 5 + 41007 + + + 5 + 646 + 28438 + + + + + + + name + type_id + + + 12 + + + 1 + 2 + 366204 + + + 2 + 3 + 51508 + + + 3 + 650 + 31899 + + + + + + + + + globalvariables + 300716 + + + id + 300708 + + + type_id + 1405 + + + name + 294738 + + + + + id + type_id + + + 12 + + + 1 + 2 + 300700 + + + 2 + 3 + 8 + + + + + + + id + name + + + 12 + + + 1 + 2 + 300708 + + + + + + + type_id + id + + + 12 + + + 1 + 2 + 977 + + + 2 + 3 + 159 + + + 3 + 7 + 114 + + + 7 + 77 + 106 + + + 83 + 169397 + 49 + + + + + + + type_id + name + + + 12 + + + 1 + 2 + 1010 + + + 2 + 3 + 135 + + + 3 + 7 + 112 + + + 7 + 105 + 106 + + + 106 + 168448 + 42 + + + + + + + name + id + + + 12 + + + 1 + 2 + 290989 + + + 2 + 33 + 3749 + + + + + + + name + type_id + + + 12 + + + 1 + 2 + 294142 + + + 2 + 12 + 596 + + + + + + + + + localvariables + 581746 + + + id + 581746 + + + type_id + 37913 + + + name + 91411 + + + + + id + type_id + + + 12 + + + 1 + 2 + 581746 + + + + + + + id + name + + + 12 + + + 1 + 2 + 581746 + + + + + + + type_id + id + + + 12 + + + 1 + 2 + 21213 + + + 2 + 3 + 5413 + + + 3 + 4 + 2479 + + + 4 + 7 + 3413 + + + 7 + 18 + 2879 + + + 18 + 15847 + 2513 + + + + + + + type_id + name + + + 12 + + + 1 + 2 + 27001 + + + 2 + 3 + 4606 + + + 3 + 5 + 2946 + + + 5 + 31 + 2845 + + + 31 + 3455 + 512 + + + + + + + name + id + + + 12 + + + 1 + 2 + 57575 + + + 2 + 3 + 14421 + + + 3 + 5 + 8389 + + + 5 + 15 + 7048 + + + 15 + 5176 + 3976 + + + + + + + name + type_id + + + 12 + + + 1 + 2 + 77221 + + + 2 + 3 + 7481 + + + 3 + 1486 + 6708 + + + + + + + + + autoderivation + 149996 + + + var + 149996 + + + derivation_type + 525 + + + + + var + derivation_type + + + 12 + + + 1 + 2 + 149996 + + + + + + + derivation_type + var + + + 12 + + + 33 + 34 + 105 + + + 90 + 91 + 105 + + + 353 + 354 + 105 + + + 392 + 393 + 105 + + + 560 + 561 + 105 + + + + + + + + + enumconstants + 240596 + + + id + 240596 + + + parent + 28399 + + + index + 10182 + + + type_id + 39 + + + name + 240318 + + + location + 220589 + + + + + id + parent + + + 12 + + + 1 + 2 + 240596 + + + + + + + id + index + + + 12 + + + 1 + 2 + 240596 + + + + + + + id + type_id + + + 12 + + + 1 + 2 + 240596 + + + + + + + id + name + + + 12 + + + 1 + 2 + 240596 + + + + + + + id + location + + + 12 + + + 1 + 2 + 240596 + + + + + + + parent + id + + + 12 + + + 1 + 2 + 994 + + + 2 + 3 + 4017 + + + 3 + 4 + 5767 + + + 4 + 5 + 3897 + + + 5 + 6 + 3062 + + + 6 + 7 + 1829 + + + 7 + 8 + 1471 + + + 8 + 11 + 2585 + + + 11 + 17 + 2346 + + + 17 + 84 + 2147 + + + 94 + 257 + 278 + + + + + + + parent + index + + + 12 + + + 1 + 2 + 994 + + + 2 + 3 + 4017 + + + 3 + 4 + 5767 + + + 4 + 5 + 3897 + + + 5 + 6 + 3062 + + + 6 + 7 + 1829 + + + 7 + 8 + 1471 + + + 8 + 11 + 2585 + + + 11 + 17 + 2346 + + + 17 + 84 + 2147 + + + 94 + 257 + 278 + + + + + + + parent + type_id + + + 12 + + + 1 + 2 + 28399 + + + + + + + parent + name + + + 12 + + + 1 + 2 + 994 + + + 2 + 3 + 4017 + + + 3 + 4 + 5767 + + + 4 + 5 + 3897 + + + 5 + 6 + 3062 + + + 6 + 7 + 1829 + + + 7 + 8 + 1471 + + + 8 + 11 + 2585 + + + 11 + 17 + 2346 + + + 17 + 84 + 2147 + + + 94 + 257 + 278 + + + + + + + parent + location + + + 12 + + + 1 + 2 + 1431 + + + 2 + 3 + 4176 + + + 3 + 4 + 5807 + + + 4 + 5 + 3858 + + + 5 + 6 + 3062 + + + 6 + 7 + 1789 + + + 7 + 8 + 1392 + + + 8 + 11 + 2505 + + + 11 + 17 + 2227 + + + 17 + 257 + 2147 + + + + + + + index + id + + + 12 + + + 1 + 2 + 2028 + + + 2 + 3 + 1630 + + + 3 + 4 + 1750 + + + 4 + 5 + 875 + + + 5 + 9 + 795 + + + 9 + 12 + 835 + + + 12 + 20 + 875 + + + 20 + 69 + 795 + + + 77 + 715 + 596 + + + + + + + index + parent + + + 12 + + + 1 + 2 + 2028 + + + 2 + 3 + 1630 + + + 3 + 4 + 1750 + + + 4 + 5 + 875 + + + 5 + 9 + 795 + + + 9 + 12 + 835 + + + 12 + 20 + 875 + + + 20 + 69 + 795 + + + 77 + 715 + 596 + + + + + + + index + type_id + + + 12 + + + 1 + 2 + 10182 + + + + + + + index + name + + + 12 + + + 1 + 2 + 2028 + + + 2 + 3 + 1630 + + + 3 + 4 + 1750 + + + 4 + 5 + 875 + + + 5 + 9 + 795 + + + 9 + 12 + 835 + + + 12 + 20 + 875 + + + 20 + 69 + 795 + + + 77 + 712 + 596 + + + + + + + index + location + + + 12 + + + 1 + 2 + 2028 + + + 2 + 3 + 1630 + + + 3 + 4 + 1750 + + + 4 + 5 + 875 + + + 5 + 9 + 795 + + + 9 + 12 + 835 + + + 12 + 20 + 875 + + + 20 + 69 + 795 + + + 77 + 715 + 596 + + + + + + + type_id + id + + + 12 + + + 6049 + 6050 + 39 + + + + + + + type_id + parent + + + 12 + + + 714 + 715 + 39 + + + + + + + type_id + index + + + 12 + + + 256 + 257 + 39 + + + + + + + type_id + name + + + 12 + + + 6042 + 6043 + 39 + + + + + + + type_id + location + + + 12 + + + 5546 + 5547 + 39 + + + + + + + name + id + + + 12 + + + 1 + 2 + 240039 + + + 2 + 3 + 278 + + + + + + + name + parent + + + 12 + + + 1 + 2 + 240039 + + + 2 + 3 + 278 + + + + + + + name + index + + + 12 + + + 1 + 2 + 240318 + + + + + + + name + type_id + + + 12 + + + 1 + 2 + 240318 + + + + + + + name + location + + + 12 + + + 1 + 2 + 240039 + + + 2 + 3 + 278 + + + + + + + location + id + + + 12 + + + 1 + 2 + 219834 + + + 2 + 205 + 755 + + + + + + + location + parent + + + 12 + + + 1 + 2 + 220589 + + + + + + + location + index + + + 12 + + + 1 + 2 + 219834 + + + 2 + 205 + 755 + + + + + + + location + type_id + + + 12 + + + 1 + 2 + 220589 + + + + + + + location + name + + + 12 + + + 1 + 2 + 219834 + + + 2 + 205 + 755 + + + + + + + + + builtintypes + 22184 + + + id + 22184 + + + name + 22184 + + + kind + 22184 + + + size + 3304 + + + sign + 1416 + + + alignment + 2360 + + + + + id + name + + + 12 + + + 1 + 2 + 22184 + + + + + + + id + kind + + + 12 + + + 1 + 2 + 22184 + + + + + + + id + size + + + 12 + + + 1 + 2 + 22184 + + + + + + + id + sign + + + 12 + + + 1 + 2 + 22184 + + + + + + + id + alignment + + + 12 + + + 1 + 2 + 22184 + + + + + + + name + id + + + 12 + + + 1 + 2 + 22184 + + + + + + + name + kind + + + 12 + + + 1 + 2 + 22184 + + + + + + + name + size + + + 12 + + + 1 + 2 + 22184 + + + + + + + name + sign + + + 12 + + + 1 + 2 + 22184 + + + + + + + name + alignment + + + 12 + + + 1 + 2 + 22184 + + + + + + + kind + id + + + 12 + + + 1 + 2 + 22184 + + + + + + + kind + name + + + 12 + + + 1 + 2 + 22184 + + + + + + + kind + size + + + 12 + + + 1 + 2 + 22184 + + + + + + + kind + sign + + + 12 + + + 1 + 2 + 22184 + + + + + + + kind + alignment + + + 12 + + + 1 + 2 + 22184 + + + + + + + size + id + + + 12 + + + 1 + 2 + 472 + + + 2 + 3 + 472 + + + 4 + 5 + 472 + + + 7 + 8 + 472 + + + 9 + 10 + 472 + + + 11 + 12 + 472 + + + 13 + 14 + 472 + + + + + + + size + name + + + 12 + + + 1 + 2 + 472 + + + 2 + 3 + 472 + + + 4 + 5 + 472 + + + 7 + 8 + 472 + + + 9 + 10 + 472 + + + 11 + 12 + 472 + + + 13 + 14 + 472 + + + + + + + size + kind + + + 12 + + + 1 + 2 + 472 + + + 2 + 3 + 472 + + + 4 + 5 + 472 + + + 7 + 8 + 472 + + + 9 + 10 + 472 + + + 11 + 12 + 472 + + + 13 + 14 + 472 + + + + + + + size + sign + + + 12 + + + 1 + 2 + 944 + + + 3 + 4 + 2360 + + + + + + + size + alignment + + + 12 + + + 1 + 2 + 2360 + + + 2 + 3 + 944 + + + + + + + sign + id + + + 12 + + + 6 + 7 + 472 + + + 12 + 13 + 472 + + + 29 + 30 + 472 + + + + + + + sign + name + + + 12 + + + 6 + 7 + 472 + + + 12 + 13 + 472 + + + 29 + 30 + 472 + + + + + + + sign + kind + + + 12 + + + 6 + 7 + 472 + + + 12 + 13 + 472 + + + 29 + 30 + 472 + + + + + + + sign + size + + + 12 + + + 5 + 6 + 944 + + + 7 + 8 + 472 + + + + + + + sign + alignment + + + 12 + + + 5 + 6 + 1416 + + + + + + + alignment + id + + + 12 + + + 4 + 5 + 472 + + + 8 + 9 + 472 + + + 10 + 11 + 472 + + + 12 + 13 + 472 + + + 13 + 14 + 472 + + + + + + + alignment + name + + + 12 + + + 4 + 5 + 472 + + + 8 + 9 + 472 + + + 10 + 11 + 472 + + + 12 + 13 + 472 + + + 13 + 14 + 472 + + + + + + + alignment + kind + + + 12 + + + 4 + 5 + 472 + + + 8 + 9 + 472 + + + 10 + 11 + 472 + + + 12 + 13 + 472 + + + 13 + 14 + 472 + + + + + + + alignment + size + + + 12 + + + 1 + 2 + 472 + + + 2 + 3 + 1888 + + + + + + + alignment + sign + + + 12 + + + 3 + 4 + 2360 + + + + + + + + + derivedtypes + 4456239 + + + id + 4456239 + + + name + 2235907 + + + kind + 2832 + + + type_id + 2752285 + + + + + id + name + + + 12 + + + 1 + 2 + 4456239 + + + + + + + id + kind + + + 12 + + + 1 + 2 + 4456239 + + + + + + + id + type_id + + + 12 + + + 1 + 2 + 4456239 + + + + + + + name + id + + + 12 + + + 1 + 2 + 1961670 + + + 2 + 5 + 175587 + + + 5 + 1173 + 98649 + + + + + + + name + kind + + + 12 + + + 1 + 2 + 2234963 + + + 2 + 3 + 944 + + + + + + + name + type_id + + + 12 + + + 1 + 2 + 1961670 + + + 2 + 5 + 175587 + + + 5 + 1155 + 98649 + + + + + + + kind + id + + + 12 + + + 198 + 199 + 472 + + + 1118 + 1119 + 472 + + + 1154 + 1155 + 472 + + + 1223 + 1224 + 472 + + + 2208 + 2209 + 472 + + + 3540 + 3541 + 472 + + + + + + + kind + name + + + 12 + + + 1 + 2 + 472 + + + 164 + 165 + 472 + + + 611 + 612 + 472 + + + 796 + 797 + 472 + + + 1161 + 1162 + 472 + + + 2006 + 2007 + 472 + + + + + + + kind + type_id + + + 12 + + + 83 + 84 + 472 + + + 1118 + 1119 + 472 + + + 1154 + 1155 + 472 + + + 1223 + 1224 + 472 + + + 2163 + 2164 + 472 + + + 3540 + 3541 + 472 + + + + + + + type_id + id + + + 12 + + + 1 + 2 + 1698289 + + + 2 + 3 + 570659 + + + 3 + 4 + 375719 + + + 4 + 54 + 107618 + + + + + + + type_id + name + + + 12 + + + 1 + 2 + 1709617 + + + 2 + 3 + 563107 + + + 3 + 4 + 372887 + + + 4 + 54 + 106674 + + + + + + + type_id + kind + + + 12 + + + 1 + 2 + 1702537 + + + 2 + 3 + 574435 + + + 3 + 4 + 374775 + + + 4 + 6 + 100537 + + + + + + + + + pointerishsize + 3320584 + + + id + 3320584 + + + size + 472 + + + alignment + 472 + + + + + id + size + + + 12 + + + 1 + 2 + 3320584 + + + + + + + id + alignment + + + 12 + + + 1 + 2 + 3320584 + + + + + + + size + id + + + 12 + + + 7035 + 7036 + 472 + + + + + + + size + alignment + + + 12 + + + 1 + 2 + 472 + + + + + + + alignment + id + + + 12 + + + 7035 + 7036 + 472 + + + + + + + alignment + size + + + 12 + + + 1 + 2 + 472 + + + + + + + + + arraysizes + 71745 + + + id + 71745 + + + num_elements + 23600 + + + bytesize + 26432 + + + alignment + 1888 + + + + + id + num_elements + + + 12 + + + 1 + 2 + 71745 + + + + + + + id + bytesize + + + 12 + + + 1 + 2 + 71745 + + + + + + + id + alignment + + + 12 + + + 1 + 2 + 71745 + + + + + + + num_elements + id + + + 12 + + + 1 + 2 + 2360 + + + 2 + 3 + 15104 + + + 3 + 4 + 1416 + + + 4 + 6 + 1888 + + + 6 + 11 + 1888 + + + 12 + 14 + 944 + + + + + + + num_elements + bytesize + + + 12 + + + 1 + 2 + 18408 + + + 2 + 3 + 2360 + + + 3 + 4 + 1888 + + + 4 + 7 + 944 + + + + + + + num_elements + alignment + + + 12 + + + 1 + 2 + 18408 + + + 2 + 3 + 2832 + + + 3 + 4 + 1416 + + + 4 + 5 + 944 + + + + + + + bytesize + id + + + 12 + + + 1 + 2 + 2832 + + + 2 + 3 + 16992 + + + 3 + 4 + 3304 + + + 4 + 8 + 2360 + + + 11 + 16 + 944 + + + + + + + bytesize + num_elements + + + 12 + + + 1 + 2 + 21712 + + + 2 + 3 + 3304 + + + 3 + 5 + 1416 + + + + + + + bytesize + alignment + + + 12 + + + 1 + 2 + 22184 + + + 2 + 3 + 3304 + + + 4 + 5 + 944 + + + + + + + alignment + id + + + 12 + + + 5 + 6 + 472 + + + 16 + 17 + 472 + + + 31 + 32 + 472 + + + 100 + 101 + 472 + + + + + + + alignment + num_elements + + + 12 + + + 4 + 5 + 472 + + + 7 + 8 + 944 + + + 50 + 51 + 472 + + + + + + + alignment + bytesize + + + 12 + + + 4 + 5 + 472 + + + 7 + 8 + 472 + + + 8 + 9 + 472 + + + 50 + 51 + 472 + + + + + + + + + typedefbase + 1731312 + + + id + 1731312 + + + type_id + 809076 + + + + + id + type_id + + + 12 + + + 1 + 2 + 1731312 + + + + + + + type_id + id + + + 12 + + + 1 + 2 + 628341 + + + 2 + 3 + 84469 + + + 3 + 6 + 64632 + + + 6 + 5443 + 31632 + + + + + + + + + decltypes + 354722 + + + id + 23891 + + + expr + 354722 + + + base_type + 17137 + + + parentheses_would_change_meaning + 17 + + + + + id + expr + + + 12 + + + 1 + 2 + 5945 + + + 2 + 3 + 7472 + + + 3 + 4 + 3251 + + + 4 + 7 + 1993 + + + 7 + 18 + 1993 + + + 18 + 42 + 2011 + + + 42 + 1767 + 1221 + + + + + + + id + base_type + + + 12 + + + 1 + 2 + 23891 + + + + + + + id + parentheses_would_change_meaning + + + 12 + + + 1 + 2 + 23891 + + + + + + + expr + id + + + 12 + + + 1 + 2 + 354722 + + + + + + + expr + base_type + + + 12 + + + 1 + 2 + 354722 + + + + + + + expr + parentheses_would_change_meaning + + + 12 + + + 1 + 2 + 354722 + + + + + + + base_type + id + + + 12 + + + 1 + 2 + 14442 + + + 2 + 3 + 2209 + + + 3 + 149 + 485 + + + + + + + base_type + expr + + + 12 + + + 1 + 2 + 1796 + + + 2 + 3 + 7329 + + + 3 + 4 + 3071 + + + 4 + 5 + 1419 + + + 5 + 11 + 1365 + + + 11 + 43 + 1562 + + + 43 + 6569 + 592 + + + + + + + base_type + parentheses_would_change_meaning + + + 12 + + + 1 + 2 + 17137 + + + + + + + parentheses_would_change_meaning + id + + + 12 + + + 1330 + 1331 + 17 + + + + + + + parentheses_would_change_meaning + expr + + + 12 + + + 19747 + 19748 + 17 + + + + + + + parentheses_would_change_meaning + base_type + + + 12 + + + 954 + 955 + 17 + + + + + + + + + usertypes + 5362968 + + + id + 5362968 + + + name + 1392427 + + + kind + 5192 + + + + + id + name + + + 12 + + + 1 + 2 + 5362968 + + + + + + + id + kind + + + 12 + + + 1 + 2 + 5362968 + + + + + + + name + id + + + 12 + + + 1 + 2 + 1009627 + + + 2 + 3 + 162371 + + + 3 + 7 + 108562 + + + 7 + 81 + 104786 + + + 92 + 885 + 7080 + + + + + + + name + kind + + + 12 + + + 1 + 2 + 1247992 + + + 2 + 3 + 128858 + + + 3 + 7 + 15576 + + + + + + + kind + id + + + 12 + + + 6 + 7 + 472 + + + 10 + 11 + 472 + + + 26 + 27 + 472 + + + 121 + 122 + 472 + + + 138 + 139 + 472 + + + 690 + 691 + 472 + + + 862 + 863 + 472 + + + 963 + 964 + 472 + + + 1770 + 1771 + 472 + + + 1913 + 1914 + 472 + + + 4863 + 4864 + 472 + + + + + + + kind + name + + + 12 + + + 5 + 6 + 472 + + + 6 + 7 + 472 + + + 14 + 15 + 472 + + + 30 + 31 + 472 + + + 44 + 45 + 472 + + + 124 + 125 + 472 + + + 269 + 270 + 472 + + + 373 + 374 + 472 + + + 433 + 434 + 472 + + + 749 + 750 + 472 + + + 1250 + 1251 + 472 + + + + + + + + + usertypesize + 1766258 + + + id + 1766258 + + + size + 13688 + + + alignment + 2360 + + + + + id + size + + + 12 + + + 1 + 2 + 1766258 + + + + + + + id + alignment + + + 12 + + + 1 + 2 + 1766258 + + + + + + + size + id + + + 12 + + + 1 + 2 + 3304 + + + 2 + 3 + 4248 + + + 3 + 4 + 472 + + + 4 + 5 + 944 + + + 6 + 8 + 944 + + + 9 + 15 + 944 + + + 37 + 84 + 944 + + + 92 + 160 + 944 + + + 748 + 2552 + 944 + + + + + + + size + alignment + + + 12 + + + 1 + 2 + 10384 + + + 2 + 3 + 2832 + + + 3 + 4 + 472 + + + + + + + alignment + id + + + 12 + + + 2 + 3 + 472 + + + 6 + 7 + 472 + + + 181 + 182 + 472 + + + 254 + 255 + 472 + + + 3299 + 3300 + 472 + + + + + + + alignment + size + + + 12 + + + 1 + 2 + 472 + + + 2 + 3 + 472 + + + 3 + 4 + 472 + + + 9 + 10 + 472 + + + 22 + 23 + 472 + + + + + + + + + usertype_final + 9558 + + + id + 9558 + + + + + + usertype_uuid + 36206 + + + id + 36206 + + + uuid + 36206 + + + + + id + uuid + + + 12 + + + 1 + 2 + 36206 + + + + + + + uuid + id + + + 12 + + + 1 + 2 + 36206 + + + + + + + + + mangled_name + 5283199 + + + id + 5283199 + + + mangled_name + 1236664 + + + + + id + mangled_name + + + 12 + + + 1 + 2 + 5283199 + + + + + + + mangled_name + id + + + 12 + + + 1 + 2 + 733502 + + + 2 + 3 + 178419 + + + 3 + 4 + 82601 + + + 4 + 6 + 85905 + + + 6 + 14 + 99121 + + + 14 + 885 + 57113 + + + + + + + + + is_pod_class + 559630 + + + id + 559630 + + + + + + is_standard_layout_class + 1306521 + + + id + 1306521 + + + + + + is_complete + 1706313 + + + id + 1706313 + + + + + + is_class_template + 406871 + + + id + 406871 + + + + + + class_instantiation + 1132350 + + + to + 1132350 + + + from + 171811 + + + + + to + from + + + 12 + + + 1 + 2 + 1132350 + + + + + + + from + to + + + 12 + + + 1 + 2 + 60417 + + + 2 + 3 + 29736 + + + 3 + 4 + 16048 + + + 4 + 5 + 14160 + + + 5 + 7 + 15576 + + + 7 + 14 + 15576 + + + 14 + 34 + 13216 + + + 34 + 84 + 7080 + + + + + + + + + class_template_argument + 2984763 + + + type_id + 1362392 + + + index + 1297 + + + arg_type + 873917 + + + + + type_id + index + + + 12 + + + 1 + 2 + 553906 + + + 2 + 3 + 419705 + + + 3 + 4 + 242829 + + + 4 + 7 + 121721 + + + 7 + 113 + 24228 + + + + + + + type_id + arg_type + + + 12 + + + 1 + 2 + 578853 + + + 2 + 3 + 432393 + + + 3 + 4 + 256363 + + + 4 + 113 + 94781 + + + + + + + index + type_id + + + 12 + + + 1 + 2 + 11 + + + 2 + 3 + 822 + + + 3 + 26 + 104 + + + 29 + 64 + 104 + + + 69 + 411 + 104 + + + 592 + 8760 + 104 + + + 12939 + 114739 + 46 + + + + + + + index + arg_type + + + 12 + + + 1 + 2 + 11 + + + 2 + 3 + 822 + + + 3 + 14 + 115 + + + 14 + 26 + 104 + + + 28 + 145 + 104 + + + 195 + 3458 + 104 + + + 11165 + 39733 + 34 + + + + + + + arg_type + type_id + + + 12 + + + 1 + 2 + 536062 + + + 2 + 3 + 191313 + + + 3 + 4 + 53972 + + + 4 + 11 + 67088 + + + 11 + 10817 + 25479 + + + + + + + arg_type + index + + + 12 + + + 1 + 2 + 762763 + + + 2 + 3 + 94156 + + + 3 + 22 + 16998 + + + + + + + + + class_template_argument_value + 506465 + + + type_id + 314830 + + + index + 1888 + + + arg_value + 506465 + + + + + type_id + index + + + 12 + + + 1 + 2 + 259133 + + + 2 + 3 + 53809 + + + 3 + 4 + 1888 + + + + + + + type_id + arg_value + + + 12 + + + 1 + 2 + 199187 + + + 2 + 3 + 81185 + + + 3 + 4 + 12272 + + + 4 + 9 + 22184 + + + + + + + index + type_id + + + 12 + + + 18 + 19 + 472 + + + 92 + 93 + 472 + + + 299 + 300 + 472 + + + 380 + 381 + 472 + + + + + + + index + arg_value + + + 12 + + + 19 + 20 + 472 + + + 124 + 125 + 472 + + + 410 + 411 + 472 + + + 520 + 521 + 472 + + + + + + + arg_value + type_id + + + 12 + + + 1 + 2 + 506465 + + + + + + + arg_value + index + + + 12 + + + 1 + 2 + 506465 + + + + + + + + + is_proxy_class_for + 65137 + + + id + 65137 + + + templ_param_id + 65137 + + + + + id + templ_param_id + + + 12 + + + 1 + 2 + 65137 + + + + + + + templ_param_id + id + + + 12 + + + 1 + 2 + 65137 + + + + + + + + + type_mentions + 4011226 + + + id + 4011226 + + + type_id + 197321 + + + location + 3977856 + + + kind + 39 + + + + + id + type_id + + + 12 + + + 1 + 2 + 4011226 + + + + + + + id + location + + + 12 + + + 1 + 2 + 4011226 + + + + + + + id + kind + + + 12 + + + 1 + 2 + 4011226 + + + + + + + type_id + id + + + 12 + + + 1 + 2 + 97169 + + + 2 + 3 + 21637 + + + 3 + 4 + 8193 + + + 4 + 5 + 10739 + + + 5 + 7 + 14318 + + + 7 + 12 + 15790 + + + 12 + 27 + 15114 + + + 27 + 8555 + 14358 + + + + + + + type_id + location + + + 12 + + + 1 + 2 + 97169 + + + 2 + 3 + 21637 + + + 3 + 4 + 8193 + + + 4 + 5 + 10739 + + + 5 + 7 + 14318 + + + 7 + 12 + 15790 + + + 12 + 27 + 15114 + + + 27 + 8555 + 14358 + + + + + + + type_id + kind + + + 12 + + + 1 + 2 + 197321 + + + + + + + location + id + + + 12 + + + 1 + 2 + 3944485 + + + 2 + 3 + 33370 + + + + + + + location + type_id + + + 12 + + + 1 + 2 + 3944485 + + + 2 + 3 + 33370 + + + + + + + location + kind + + + 12 + + + 1 + 2 + 3977856 + + + + + + + kind + id + + + 12 + + + 100849 + 100850 + 39 + + + + + + + kind + type_id + + + 12 + + + 4961 + 4962 + 39 + + + + + + + kind + location + + + 12 + + + 100010 + 100011 + 39 + + + + + + + + + is_function_template + 1418387 + + + id + 1418387 + + + + + + function_instantiation + 895034 + + + to + 895034 + + + from + 144729 + + + + + to + from + + + 12 + + + 1 + 2 + 895034 + + + + + + + from + to + + + 12 + + + 1 + 2 + 100124 + + + 2 + 3 + 14448 + + + 3 + 6 + 11964 + + + 6 + 21 + 11964 + + + 22 + 864 + 6227 + + + + + + + + + function_template_argument + 2313992 + + + function_id + 1303055 + + + index + 559 + + + arg_type + 302683 + + + + + function_id + index + + + 12 + + + 1 + 2 + 668792 + + + 2 + 3 + 388709 + + + 3 + 4 + 175375 + + + 4 + 15 + 70178 + + + + + + + function_id + arg_type + + + 12 + + + 1 + 2 + 683870 + + + 2 + 3 + 393991 + + + 3 + 4 + 146583 + + + 4 + 9 + 78609 + + + + + + + index + function_id + + + 12 + + + 1 + 2 + 209 + + + 7 + 8 + 34 + + + 35 + 36 + 34 + + + 108 + 109 + 34 + + + 164 + 165 + 34 + + + 294 + 295 + 34 + + + 849 + 850 + 34 + + + 3198 + 3199 + 34 + + + 8582 + 8583 + 34 + + + 17395 + 17396 + 34 + + + 34286 + 34287 + 34 + + + + + + + index + arg_type + + + 12 + + + 1 + 2 + 209 + + + 3 + 4 + 34 + + + 11 + 12 + 34 + + + 22 + 23 + 34 + + + 30 + 31 + 34 + + + 61 + 62 + 34 + + + 134 + 135 + 34 + + + 452 + 453 + 34 + + + 1127 + 1128 + 34 + + + 2404 + 2405 + 34 + + + 5836 + 5837 + 34 + + + + + + + arg_type + function_id + + + 12 + + + 1 + 2 + 185521 + + + 2 + 3 + 44534 + + + 3 + 5 + 23334 + + + 5 + 16 + 23369 + + + 16 + 113 + 25118 + + + 126 + 955 + 804 + + + + + + + arg_type + index + + + 12 + + + 1 + 2 + 272771 + + + 2 + 4 + 25818 + + + 4 + 17 + 4093 + + + + + + + + + function_template_argument_value + 358342 + + + function_id + 179083 + + + index + 559 + + + arg_value + 355719 + + + + + function_id + index + + + 12 + + + 1 + 2 + 169778 + + + 2 + 8 + 9305 + + + + + + + function_id + arg_value + + + 12 + + + 1 + 2 + 149417 + + + 2 + 3 + 20535 + + + 3 + 97 + 9130 + + + + + + + index + function_id + + + 12 + + + 1 + 2 + 209 + + + 2 + 3 + 69 + + + 11 + 12 + 34 + + + 26 + 27 + 34 + + + 94 + 95 + 34 + + + 314 + 315 + 34 + + + 709 + 710 + 34 + + + 964 + 965 + 34 + + + 1187 + 1188 + 34 + + + 2148 + 2149 + 34 + + + + + + + index + arg_value + + + 12 + + + 1 + 2 + 209 + + + 2 + 3 + 69 + + + 60 + 61 + 34 + + + 80 + 81 + 34 + + + 141 + 142 + 34 + + + 533 + 534 + 34 + + + 1550 + 1551 + 34 + + + 1821 + 1822 + 34 + + + 2202 + 2203 + 34 + + + 3771 + 3772 + 34 + + + + + + + arg_value + function_id + + + 12 + + + 1 + 2 + 353095 + + + 2 + 3 + 2623 + + + + + + + arg_value + index + + + 12 + + + 1 + 2 + 355719 + + + + + + + + + is_variable_template + 42225 + + + id + 42225 + + + + + + variable_instantiation + 48633 + + + to + 48633 + + + from + 24894 + + + + + to + from + + + 12 + + + 1 + 2 + 48633 + + + + + + + from + to + + + 12 + + + 1 + 2 + 14390 + + + 2 + 3 + 7667 + + + 3 + 8 + 1785 + + + 8 + 14 + 1050 + + + + + + + + + variable_template_argument + 328248 + + + variable_id + 26469 + + + index + 1785 + + + arg_type + 217116 + + + + + variable_id + index + + + 12 + + + 1 + 2 + 16176 + + + 2 + 3 + 5672 + + + 3 + 4 + 3886 + + + 4 + 17 + 735 + + + + + + + variable_id + arg_type + + + 12 + + + 1 + 2 + 5987 + + + 2 + 3 + 5251 + + + 3 + 4 + 1995 + + + 4 + 5 + 1155 + + + 5 + 6 + 2415 + + + 6 + 8 + 2310 + + + 8 + 11 + 2205 + + + 11 + 18 + 2415 + + + 18 + 67 + 1995 + + + 80 + 515 + 735 + + + + + + + index + variable_id + + + 12 + + + 1 + 2 + 105 + + + 2 + 3 + 630 + + + 3 + 4 + 420 + + + 5 + 6 + 210 + + + 27 + 28 + 105 + + + 42 + 43 + 105 + + + 79 + 80 + 105 + + + 248 + 249 + 105 + + + + + + + index + arg_type + + + 12 + + + 1 + 2 + 105 + + + 12 + 13 + 630 + + + 13 + 14 + 105 + + + 14 + 15 + 315 + + + 24 + 25 + 105 + + + 32 + 33 + 105 + + + 128 + 129 + 105 + + + 436 + 437 + 105 + + + 636 + 637 + 105 + + + 890 + 891 + 105 + + + + + + + arg_type + variable_id + + + 12 + + + 1 + 2 + 181088 + + + 2 + 3 + 20902 + + + 3 + 37 + 15125 + + + + + + + arg_type + index + + + 12 + + + 1 + 2 + 199890 + + + 2 + 5 + 16806 + + + 5 + 6 + 420 + + + + + + + + + variable_template_argument_value + 15650 + + + variable_id + 2836 + + + index + 420 + + + arg_value + 12079 + + + + + variable_id + index + + + 12 + + + 1 + 2 + 2625 + + + 2 + 3 + 210 + + + + + + + variable_id + arg_value + + + 12 + + + 2 + 3 + 420 + + + 3 + 4 + 105 + + + 4 + 5 + 1365 + + + 5 + 6 + 210 + + + 6 + 7 + 210 + + + 8 + 9 + 210 + + + 12 + 17 + 210 + + + 20 + 21 + 105 + + + + + + + index + variable_id + + + 12 + + + 2 + 3 + 105 + + + 6 + 7 + 105 + + + 8 + 9 + 105 + + + 13 + 14 + 105 + + + + + + + index + arg_value + + + 12 + + + 12 + 13 + 105 + + + 30 + 31 + 105 + + + 33 + 34 + 105 + + + 40 + 41 + 105 + + + + + + + arg_value + variable_id + + + 12 + + + 1 + 2 + 8508 + + + 2 + 3 + 3571 + + + + + + + arg_value + index + + + 12 + + + 1 + 2 + 12079 + + + + + + + + + routinetypes + 543059 + + + id + 543059 + + + return_type + 283826 + + + + + id + return_type + + + 12 + + + 1 + 2 + 543059 + + + + + + + return_type + id + + + 12 + + + 1 + 2 + 247373 + + + 2 + 3 + 21165 + + + 3 + 3594 + 15288 + + + + + + + + + routinetypeargs + 996883 + + + routine + 430472 + + + index + 8024 + + + type_id + 230340 + + + + + routine + index + + + 12 + + + 1 + 2 + 156235 + + + 2 + 3 + 135938 + + + 3 + 4 + 64193 + + + 4 + 5 + 46256 + + + 5 + 18 + 27848 + + + + + + + routine + type_id + + + 12 + + + 1 + 2 + 186443 + + + 2 + 3 + 135466 + + + 3 + 4 + 59473 + + + 4 + 5 + 33984 + + + 5 + 11 + 15104 + + + + + + + index + routine + + + 12 + + + 2 + 3 + 944 + + + 4 + 5 + 472 + + + 6 + 7 + 472 + + + 8 + 9 + 944 + + + 9 + 10 + 472 + + + 10 + 11 + 1416 + + + 13 + 14 + 472 + + + 28 + 29 + 472 + + + 59 + 60 + 472 + + + 157 + 158 + 472 + + + 293 + 294 + 472 + + + 581 + 582 + 472 + + + 912 + 913 + 472 + + + + + + + index + type_id + + + 12 + + + 1 + 2 + 944 + + + 3 + 4 + 944 + + + 4 + 5 + 1416 + + + 5 + 6 + 944 + + + 6 + 7 + 944 + + + 10 + 11 + 472 + + + 14 + 15 + 472 + + + 47 + 48 + 472 + + + 90 + 91 + 472 + + + 176 + 177 + 472 + + + 349 + 350 + 472 + + + + + + + type_id + routine + + + 12 + + + 1 + 2 + 149154 + + + 2 + 3 + 31152 + + + 3 + 5 + 16992 + + + 5 + 12 + 18408 + + + 12 + 113 + 14632 + + + + + + + type_id + index + + + 12 + + + 1 + 2 + 175587 + + + 2 + 3 + 31152 + + + 3 + 6 + 18880 + + + 6 + 14 + 4720 + + + + + + + + + ptrtomembers + 38232 + + + id + 38232 + + + type_id + 38232 + + + class_id + 15576 + + + + + id + type_id + + + 12 + + + 1 + 2 + 38232 + + + + + + + id + class_id + + + 12 + + + 1 + 2 + 38232 + + + + + + + type_id + id + + + 12 + + + 1 + 2 + 38232 + + + + + + + type_id + class_id + + + 12 + + + 1 + 2 + 38232 + + + + + + + class_id + id + + + 12 + + + 1 + 2 + 13688 + + + 8 + 9 + 1416 + + + 28 + 29 + 472 + + + + + + + class_id + type_id + + + 12 + + + 1 + 2 + 13688 + + + 8 + 9 + 1416 + + + 28 + 29 + 472 + + + + + + + + + specifiers + 25016 + + + id + 25016 + + + str + 25016 + + + + + id + str + + + 12 + + + 1 + 2 + 25016 + + + + + + + str + id + + + 12 + + + 1 + 2 + 25016 + + + + + + + + + typespecifiers + 1326345 + + + type_id + 1307937 + + + spec_id + 3776 + + + + + type_id + spec_id + + + 12 + + + 1 + 2 + 1289529 + + + 2 + 3 + 18408 + + + + + + + spec_id + type_id + + + 12 + + + 8 + 9 + 472 + + + 36 + 37 + 472 + + + 51 + 52 + 472 + + + 86 + 87 + 472 + + + 105 + 106 + 472 + + + 219 + 220 + 472 + + + 221 + 222 + 472 + + + 2084 + 2085 + 472 + + + + + + + + + funspecifiers + 12993924 + + + func_id + 3955310 + + + spec_id + 699 + + + + + func_id + spec_id + + + 12 + + + 1 + 2 + 312758 + + + 2 + 3 + 540295 + + + 3 + 4 + 1132682 + + + 4 + 5 + 1734095 + + + 5 + 8 + 235478 + + + + + + + spec_id + func_id + + + 12 + + + 13 + 14 + 69 + + + 98 + 99 + 34 + + + 200 + 201 + 34 + + + 296 + 297 + 34 + + + 304 + 305 + 34 + + + 572 + 573 + 34 + + + 716 + 717 + 34 + + + 1599 + 1600 + 34 + + + 1646 + 1647 + 34 + + + 3782 + 3783 + 34 + + + 3872 + 3873 + 34 + + + 5095 + 5096 + 34 + + + 6814 + 6815 + 34 + + + 9270 + 9271 + 34 + + + 12058 + 12059 + 34 + + + 53280 + 53281 + 34 + + + 80172 + 80173 + 34 + + + 91598 + 91599 + 34 + + + 100025 + 100026 + 34 + + + + + + + + + varspecifiers + 2352966 + + + var_id + 1257904 + + + spec_id + 3776 + + + + + var_id + spec_id + + + 12 + + + 1 + 2 + 738222 + + + 2 + 3 + 202491 + + + 3 + 4 + 59001 + + + 4 + 5 + 258189 + + + + + + + spec_id + var_id + + + 12 + + + 112 + 113 + 472 + + + 315 + 316 + 472 + + + 411 + 412 + 472 + + + 560 + 561 + 472 + + + 692 + 693 + 472 + + + 700 + 701 + 472 + + + 732 + 733 + 472 + + + 1463 + 1464 + 472 + + + + + + + + + attributes + 696623 + + + id + 696623 + + + kind + 315 + + + name + 1575 + + + name_space + 210 + + + location + 484652 + + + + + id + kind + + + 12 + + + 1 + 2 + 696623 + + + + + + + id + name + + + 12 + + + 1 + 2 + 696623 + + + + + + + id + name_space + + + 12 + + + 1 + 2 + 696623 + + + + + + + id + location + + + 12 + + + 1 + 2 + 696623 + + + + + + + kind + id + + + 12 + + + 4 + 5 + 105 + + + 2168 + 2169 + 105 + + + 4460 + 4461 + 105 + + + + + + + kind + name + + + 12 + + + 1 + 2 + 105 + + + 5 + 6 + 105 + + + 11 + 12 + 105 + + + + + + + kind + name_space + + + 12 + + + 1 + 2 + 210 + + + 2 + 3 + 105 + + + + + + + kind + location + + + 12 + + + 2 + 3 + 105 + + + 2055 + 2056 + 105 + + + 2557 + 2558 + 105 + + + + + + + name + id + + + 12 + + + 1 + 2 + 210 + + + 2 + 3 + 105 + + + 4 + 5 + 210 + + + 5 + 6 + 105 + + + 9 + 10 + 105 + + + 14 + 15 + 105 + + + 16 + 17 + 105 + + + 24 + 25 + 105 + + + 86 + 87 + 105 + + + 115 + 116 + 105 + + + 659 + 660 + 105 + + + 1760 + 1761 + 105 + + + 3932 + 3933 + 105 + + + + + + + name + kind + + + 12 + + + 1 + 2 + 1365 + + + 2 + 3 + 210 + + + + + + + name + name_space + + + 12 + + + 1 + 2 + 1575 + + + + + + + name + location + + + 12 + + + 1 + 2 + 315 + + + 2 + 3 + 210 + + + 4 + 5 + 105 + + + 6 + 7 + 105 + + + 9 + 10 + 105 + + + 14 + 15 + 105 + + + 18 + 19 + 105 + + + 59 + 60 + 105 + + + 72 + 73 + 105 + + + 331 + 332 + 105 + + + 1756 + 1757 + 105 + + + 2379 + 2380 + 105 + + + + + + + name_space + id + + + 12 + + + 5 + 6 + 105 + + + 6627 + 6628 + 105 + + + + + + + name_space + kind + + + 12 + + + 1 + 2 + 105 + + + 3 + 4 + 105 + + + + + + + name_space + name + + + 12 + + + 1 + 2 + 105 + + + 14 + 15 + 105 + + + + + + + name_space + location + + + 12 + + + 1 + 2 + 105 + + + 4613 + 4614 + 105 + + + + + + + location + id + + + 12 + + + 1 + 2 + 443372 + + + 2 + 9 + 36868 + + + 9 + 201 + 4411 + + + + + + + location + kind + + + 12 + + + 1 + 2 + 484652 + + + + + + + location + name + + + 12 + + + 1 + 2 + 480346 + + + 2 + 3 + 4306 + + + + + + + location + name_space + + + 12 + + + 1 + 2 + 484652 + + + + + + + + + attribute_args + 351174 + + + id + 351174 + + + kind + 1416 + + + attribute + 269045 + + + index + 1416 + + + location + 328046 + + + + + id + kind + + + 12 + + + 1 + 2 + 351174 + + + + + + + id + attribute + + + 12 + + + 1 + 2 + 351174 + + + + + + + id + index + + + 12 + + + 1 + 2 + 351174 + + + + + + + id + location + + + 12 + + + 1 + 2 + 351174 + + + + + + + kind + id + + + 12 + + + 1 + 2 + 472 + + + 55 + 56 + 472 + + + 688 + 689 + 472 + + + + + + + kind + attribute + + + 12 + + + 1 + 2 + 472 + + + 55 + 56 + 472 + + + 536 + 537 + 472 + + + + + + + kind + index + + + 12 + + + 1 + 2 + 944 + + + 3 + 4 + 472 + + + + + + + kind + location + + + 12 + + + 1 + 2 + 472 + + + 55 + 56 + 472 + + + 666 + 667 + 472 + + + + + + + attribute + id + + + 12 + + + 1 + 2 + 202963 + + + 2 + 3 + 50032 + + + 3 + 4 + 16048 + + + + + + + attribute + kind + + + 12 + + + 1 + 2 + 258661 + + + 2 + 3 + 10384 + + + + + + + attribute + index + + + 12 + + + 1 + 2 + 202963 + + + 2 + 3 + 50032 + + + 3 + 4 + 16048 + + + + + + + attribute + location + + + 12 + + + 1 + 2 + 202963 + + + 2 + 3 + 50032 + + + 3 + 4 + 16048 + + + + + + + index + id + + + 12 + + + 34 + 35 + 472 + + + 140 + 141 + 472 + + + 570 + 571 + 472 + + + + + + + index + kind + + + 12 + + + 1 + 2 + 944 + + + 3 + 4 + 472 + + + + + + + index + attribute + + + 12 + + + 34 + 35 + 472 + + + 140 + 141 + 472 + + + 570 + 571 + 472 + + + + + + + index + location + + + 12 + + + 34 + 35 + 472 + + + 140 + 141 + 472 + + + 521 + 522 + 472 + + + + + + + location + id + + + 12 + + + 1 + 2 + 313886 + + + 2 + 16 + 14160 + + + + + + + location + kind + + + 12 + + + 1 + 2 + 315302 + + + 2 + 3 + 12744 + + + + + + + location + attribute + + + 12 + + + 1 + 2 + 313886 + + + 2 + 16 + 14160 + + + + + + + location + index + + + 12 + + + 1 + 2 + 328046 + + + + + + + + + attribute_arg_value + 350702 + + + arg + 350702 + + + value + 32568 + + + + + arg + value + + + 12 + + + 1 + 2 + 350702 + + + + + + + value + arg + + + 12 + + + 1 + 2 + 14632 + + + 2 + 3 + 12272 + + + 3 + 14 + 2832 + + + 15 + 247 + 2832 + + + + + + + + + attribute_arg_type + 1535 + + + arg + 1535 + + + type_id + 1354 + + + + + arg + type_id + + + 12 + + + 1 + 2 + 1535 + + + + + + + type_id + arg + + + 12 + + + 1 + 2 + 1264 + + + 3 + 4 + 90 + + + + + + + + + attribute_arg_name + 6 + + + arg + 6 + + + name + 5 + + + + + arg + name + + + 12 + + + 1 + 2 + 6 + + + + + + + name + arg + + + 12 + + + 1 + 2 + 4 + + + 2 + 3 + 1 + + + + + + + + + typeattributes + 60817 + + + type_id + 60397 + + + spec_id + 60817 + + + + + type_id + spec_id + + + 12 + + + 1 + 2 + 59977 + + + 2 + 3 + 420 + + + + + + + spec_id + type_id + + + 12 + + + 1 + 2 + 60817 + + + + + + + + + funcattributes + 637684 + + + func_id + 448880 + + + spec_id + 637684 + + + + + func_id + spec_id + + + 12 + + + 1 + 2 + 342678 + + + 2 + 3 + 65137 + + + 3 + 6 + 40120 + + + 6 + 7 + 944 + + + + + + + spec_id + func_id + + + 12 + + + 1 + 2 + 637684 + + + + + + + + + varattributes + 371048 + + + var_id + 322247 + + + spec_id + 371048 + + + + + var_id + spec_id + + + 12 + + + 1 + 2 + 273482 + + + 2 + 3 + 48762 + + + 14 + 15 + 3 + + + + + + + spec_id + var_id + + + 12 + + + 1 + 2 + 371048 + + + + + + + + + stmtattributes + 1008 + + + stmt_id + 1008 + + + spec_id + 1008 + + + + + stmt_id + spec_id + + + 12 + + + 1 + 2 + 1008 + + + + + + + spec_id + stmt_id + + + 12 + + + 1 + 2 + 1008 + + + + + + + + + unspecifiedtype + 10417715 + + + type_id + 10417715 + + + unspecified_type_id + 6996120 + + + + + type_id + unspecified_type_id + + + 12 + + + 1 + 2 + 10417715 + + + + + + + unspecified_type_id + type_id + + + 12 + + + 1 + 2 + 4696963 + + + 2 + 3 + 2054184 + + + 3 + 147 + 244972 + + + + + + + + + member + 5120282 + + + parent + 692861 + + + index + 8746 + + + child + 5057871 + + + + + parent + index + + + 12 + + + 1 + 3 + 18716 + + + 3 + 4 + 396265 + + + 4 + 5 + 38727 + + + 5 + 7 + 52616 + + + 7 + 10 + 52476 + + + 10 + 16 + 57164 + + + 16 + 30 + 52581 + + + 30 + 251 + 24313 + + + + + + + parent + child + + + 12 + + + 1 + 3 + 18716 + + + 3 + 4 + 396230 + + + 4 + 5 + 38692 + + + 5 + 7 + 52791 + + + 7 + 10 + 52791 + + + 10 + 16 + 56919 + + + 16 + 29 + 52371 + + + 29 + 253 + 24348 + + + + + + + index + parent + + + 12 + + + 1 + 2 + 1399 + + + 2 + 3 + 804 + + + 3 + 4 + 944 + + + 5 + 22 + 769 + + + 22 + 43 + 664 + + + 43 + 61 + 699 + + + 62 + 113 + 664 + + + 114 + 185 + 664 + + + 186 + 331 + 664 + + + 367 + 1282 + 664 + + + 1418 + 5994 + 664 + + + 7270 + 19474 + 139 + + + + + + + index + child + + + 12 + + + 1 + 2 + 804 + + + 2 + 3 + 874 + + + 3 + 4 + 1154 + + + 4 + 16 + 734 + + + 16 + 33 + 664 + + + 34 + 58 + 664 + + + 58 + 93 + 699 + + + 97 + 135 + 664 + + + 140 + 253 + 664 + + + 253 + 601 + 664 + + + 611 + 2463 + 664 + + + 2610 + 19486 + 489 + + + + + + + child + parent + + + 12 + + + 1 + 2 + 5057871 + + + + + + + child + index + + + 12 + + + 1 + 2 + 4996578 + + + 2 + 5 + 61292 + + + + + + + + + enclosingfunction + 121976 + + + child + 121976 + + + parent + 69638 + + + + + child + parent + + + 12 + + + 1 + 2 + 121976 + + + + + + + parent + child + + + 12 + + + 1 + 2 + 36765 + + + 2 + 3 + 21633 + + + 3 + 4 + 6117 + + + 4 + 45 + 5121 + + + + + + + + + derivations + 397280 + + + derivation + 397280 + + + sub + 376919 + + + index + 209 + + + super + 228236 + + + location + 37887 + + + + + derivation + sub + + + 12 + + + 1 + 2 + 397280 + + + + + + + derivation + index + + + 12 + + + 1 + 2 + 397280 + + + + + + + derivation + super + + + 12 + + + 1 + 2 + 397280 + + + + + + + derivation + location + + + 12 + + + 1 + 2 + 397280 + + + + + + + sub + derivation + + + 12 + + + 1 + 2 + 361876 + + + 2 + 7 + 15043 + + + + + + + sub + index + + + 12 + + + 1 + 2 + 361876 + + + 2 + 7 + 15043 + + + + + + + sub + super + + + 12 + + + 1 + 2 + 361876 + + + 2 + 7 + 15043 + + + + + + + sub + location + + + 12 + + + 1 + 2 + 361876 + + + 2 + 7 + 15043 + + + + + + + index + derivation + + + 12 + + + 25 + 26 + 104 + + + 77 + 78 + 34 + + + 430 + 431 + 34 + + + 10774 + 10775 + 34 + + + + + + + index + sub + + + 12 + + + 25 + 26 + 104 + + + 77 + 78 + 34 + + + 430 + 431 + 34 + + + 10774 + 10775 + 34 + + + + + + + index + super + + + 12 + + + 23 + 24 + 34 + + + 25 + 26 + 69 + + + 35 + 36 + 34 + + + 261 + 262 + 34 + + + 6169 + 6170 + 34 + + + + + + + index + location + + + 12 + + + 1 + 2 + 104 + + + 9 + 10 + 34 + + + 66 + 67 + 34 + + + 1005 + 1006 + 34 + + + + + + + super + derivation + + + 12 + + + 1 + 2 + 220960 + + + 2 + 1076 + 7276 + + + + + + + super + sub + + + 12 + + + 1 + 2 + 220960 + + + 2 + 1076 + 7276 + + + + + + + super + index + + + 12 + + + 1 + 2 + 227781 + + + 2 + 4 + 454 + + + + + + + super + location + + + 12 + + + 1 + 2 + 224668 + + + 2 + 108 + 3568 + + + + + + + location + derivation + + + 12 + + + 1 + 2 + 28197 + + + 2 + 5 + 3043 + + + 5 + 16 + 2973 + + + 17 + 133 + 2973 + + + 154 + 656 + 699 + + + + + + + location + sub + + + 12 + + + 1 + 2 + 28197 + + + 2 + 5 + 3043 + + + 5 + 16 + 2973 + + + 17 + 133 + 2973 + + + 154 + 656 + 699 + + + + + + + location + index + + + 12 + + + 1 + 2 + 37887 + + + + + + + location + super + + + 12 + + + 1 + 2 + 30611 + + + 2 + 5 + 3218 + + + 5 + 55 + 2868 + + + 60 + 656 + 1189 + + + + + + + + + derspecifiers + 399169 + + + der_id + 396895 + + + spec_id + 139 + + + + + der_id + spec_id + + + 12 + + + 1 + 2 + 394621 + + + 2 + 3 + 2273 + + + + + + + spec_id + der_id + + + 12 + + + 65 + 66 + 34 + + + 93 + 94 + 34 + + + 1132 + 1133 + 34 + + + 10120 + 10121 + 34 + + + + + + + + + direct_base_offsets + 368208 + + + der_id + 368208 + + + offset + 349 + + + + + der_id + offset + + + 12 + + + 1 + 2 + 368208 + + + + + + + offset + der_id + + + 12 + + + 1 + 2 + 34 + + + 2 + 3 + 104 + + + 3 + 4 + 69 + + + 4 + 5 + 69 + + + 85 + 86 + 34 + + + 10419 + 10420 + 34 + + + + + + + + + virtual_base_offsets + 6674 + + + sub + 3684 + + + super + 509 + + + offset + 254 + + + + + sub + super + + + 12 + + + 1 + 2 + 2896 + + + 2 + 4 + 324 + + + 4 + 7 + 266 + + + 7 + 11 + 196 + + + + + + + sub + offset + + + 12 + + + 1 + 2 + 3105 + + + 2 + 4 + 312 + + + 4 + 8 + 266 + + + + + + + super + sub + + + 12 + + + 1 + 2 + 81 + + + 2 + 3 + 46 + + + 3 + 4 + 57 + + + 4 + 5 + 92 + + + 5 + 7 + 34 + + + 8 + 13 + 46 + + + 13 + 15 + 46 + + + 15 + 23 + 46 + + + 24 + 60 + 46 + + + 194 + 195 + 11 + + + + + + + super + offset + + + 12 + + + 1 + 2 + 289 + + + 2 + 3 + 81 + + + 4 + 6 + 34 + + + 6 + 8 + 46 + + + 8 + 10 + 46 + + + 14 + 15 + 11 + + + + + + + offset + sub + + + 12 + + + 2 + 3 + 34 + + + 4 + 5 + 11 + + + 5 + 6 + 23 + + + 6 + 8 + 23 + + + 8 + 9 + 34 + + + 10 + 12 + 23 + + + 14 + 15 + 11 + + + 18 + 19 + 23 + + + 26 + 29 + 23 + + + 30 + 37 + 23 + + + 96 + 98 + 23 + + + + + + + offset + super + + + 12 + + + 1 + 2 + 81 + + + 2 + 3 + 34 + + + 3 + 4 + 46 + + + 5 + 7 + 23 + + + 7 + 10 + 23 + + + 12 + 14 + 23 + + + 21 + 29 + 23 + + + + + + + + + frienddecls + 710038 + + + id + 710038 + + + type_id + 42085 + + + decl_id + 69688 + + + location + 6297 + + + + + id + type_id + + + 12 + + + 1 + 2 + 710038 + + + + + + + id + decl_id + + + 12 + + + 1 + 2 + 710038 + + + + + + + id + location + + + 12 + + + 1 + 2 + 710038 + + + + + + + type_id + id + + + 12 + + + 1 + 2 + 6157 + + + 2 + 3 + 13119 + + + 3 + 6 + 2938 + + + 6 + 10 + 3183 + + + 10 + 17 + 3253 + + + 17 + 24 + 3323 + + + 25 + 36 + 3288 + + + 37 + 55 + 3218 + + + 55 + 103 + 3603 + + + + + + + type_id + decl_id + + + 12 + + + 1 + 2 + 6157 + + + 2 + 3 + 13119 + + + 3 + 6 + 2938 + + + 6 + 10 + 3183 + + + 10 + 17 + 3253 + + + 17 + 24 + 3323 + + + 25 + 36 + 3288 + + + 37 + 55 + 3218 + + + 55 + 103 + 3603 + + + + + + + type_id + location + + + 12 + + + 1 + 2 + 40651 + + + 2 + 13 + 1434 + + + + + + + decl_id + id + + + 12 + + + 1 + 2 + 40196 + + + 2 + 3 + 5842 + + + 3 + 8 + 5982 + + + 8 + 15 + 5387 + + + 15 + 32 + 5247 + + + 32 + 71 + 5247 + + + 72 + 160 + 1784 + + + + + + + decl_id + type_id + + + 12 + + + 1 + 2 + 40196 + + + 2 + 3 + 5842 + + + 3 + 8 + 5982 + + + 8 + 15 + 5387 + + + 15 + 32 + 5247 + + + 32 + 71 + 5247 + + + 72 + 160 + 1784 + + + + + + + decl_id + location + + + 12 + + + 1 + 2 + 69023 + + + 2 + 5 + 664 + + + + + + + location + id + + + 12 + + + 1 + 2 + 5912 + + + 2 + 20106 + 384 + + + + + + + location + type_id + + + 12 + + + 1 + 2 + 6157 + + + 2 + 1105 + 139 + + + + + + + location + decl_id + + + 12 + + + 1 + 2 + 5947 + + + 2 + 1837 + 349 + + + + + + + + + comments + 9024167 + + + id + 9024167 + + + contents + 3546138 + + + location + 9024167 + + + + + id + contents + + + 12 + + + 1 + 2 + 9024167 + + + + + + + id + location + + + 12 + + + 1 + 2 + 9024167 + + + + + + + contents + id + + + 12 + + + 1 + 2 + 3255074 + + + 2 + 10 + 268901 + + + 10 + 32841 + 22163 + + + + + + + contents + location + + + 12 + + + 1 + 2 + 3255074 + + + 2 + 10 + 268901 + + + 10 + 32841 + 22163 + + + + + + + location + id + + + 12 + + + 1 + 2 + 9024167 + + + + + + + location + contents + + + 12 + + + 1 + 2 + 9024167 + + + + + + + + + commentbinding + 3153021 + + + id + 2495512 + + + element + 3075612 + + + + + id + element + + + 12 + + + 1 + 2 + 2412911 + + + 2 + 97 + 82601 + + + + + + + element + id + + + 12 + + + 1 + 2 + 2998202 + + + 2 + 3 + 77409 + + + + + + + + + exprconv + 7003263 + + + converted + 7003263 + + + conversion + 7003263 + + + + + converted + conversion + + + 12 + + + 1 + 2 + 7003263 + + + + + + + conversion + converted + + + 12 + + + 1 + 2 + 7003263 + + + + + + + + + compgenerated + 8432513 + + + id + 8432513 + + + + + + synthetic_destructor_call + 132767 + + + element + 103217 + + + i + 305 + + + destructor_call + 117462 + + + + + element + i + + + 12 + + + 1 + 2 + 85325 + + + 2 + 3 + 11801 + + + 3 + 18 + 6089 + + + + + + + element + destructor_call + + + 12 + + + 1 + 2 + 85325 + + + 2 + 3 + 11801 + + + 3 + 18 + 6089 + + + + + + + i + element + + + 12 + + + 1 + 2 + 17 + + + 2 + 3 + 53 + + + 3 + 4 + 17 + + + 4 + 5 + 53 + + + 6 + 7 + 17 + + + 11 + 12 + 17 + + + 20 + 21 + 17 + + + 34 + 35 + 17 + + + 65 + 66 + 17 + + + 152 + 153 + 17 + + + 339 + 340 + 17 + + + 996 + 997 + 17 + + + 5746 + 5747 + 17 + + + + + + + i + destructor_call + + + 12 + + + 1 + 2 + 17 + + + 2 + 3 + 53 + + + 3 + 4 + 17 + + + 4 + 5 + 53 + + + 6 + 7 + 17 + + + 11 + 12 + 17 + + + 20 + 21 + 17 + + + 34 + 35 + 17 + + + 65 + 66 + 17 + + + 151 + 152 + 17 + + + 338 + 339 + 17 + + + 995 + 996 + 17 + + + 4897 + 4898 + 17 + + + + + + + destructor_call + element + + + 12 + + + 1 + 2 + 115450 + + + 2 + 26 + 2011 + + + + + + + destructor_call + i + + + 12 + + + 1 + 2 + 117462 + + + + + + + + + namespaces + 12744 + + + id + 12744 + + + name + 10384 + + + + + id + name + + + 12 + + + 1 + 2 + 12744 + + + + + + + name + id + + + 12 + + + 1 + 2 + 8968 + + + 2 + 3 + 472 + + + 3 + 4 + 944 + + + + + + + + + namespace_inline + 1416 + + + id + 1416 + + + + + + namespacembrs + 2473800 + + + parentid + 10856 + + + memberid + 2473800 + + + + + parentid + memberid + + + 12 + + + 1 + 2 + 1888 + + + 2 + 3 + 944 + + + 3 + 4 + 472 + + + 4 + 5 + 944 + + + 5 + 7 + 944 + + + 7 + 8 + 944 + + + 8 + 12 + 944 + + + 17 + 30 + 944 + + + 43 + 47 + 944 + + + 52 + 143 + 944 + + + 247 + 4603 + 944 + + + + + + + memberid + parentid + + + 12 + + + 1 + 2 + 2473800 + + + + + + + + + exprparents + 14151887 + + + expr_id + 14151887 + + + child_index + 14601 + + + parent_id + 9417337 + + + + + expr_id + child_index + + + 12 + + + 1 + 2 + 14151887 + + + + + + + expr_id + parent_id + + + 12 + + + 1 + 2 + 14151887 + + + + + + + child_index + expr_id + + + 12 + + + 1 + 2 + 2809 + + + 2 + 3 + 1107 + + + 3 + 4 + 266 + + + 4 + 5 + 6542 + + + 5 + 8 + 1209 + + + 8 + 11 + 1189 + + + 11 + 53 + 1107 + + + 56 + 389706 + 369 + + + + + + + child_index + parent_id + + + 12 + + + 1 + 2 + 2809 + + + 2 + 3 + 1107 + + + 3 + 4 + 266 + + + 4 + 5 + 6542 + + + 5 + 8 + 1209 + + + 8 + 11 + 1189 + + + 11 + 53 + 1107 + + + 56 + 389706 + 369 + + + + + + + parent_id + expr_id + + + 12 + + + 1 + 2 + 5388560 + + + 2 + 3 + 3692338 + + + 3 + 712 + 336438 + + + + + + + parent_id + child_index + + + 12 + + + 1 + 2 + 5388560 + + + 2 + 3 + 3692338 + + + 3 + 712 + 336438 + + + + + + + + + expr_isload + 4944556 + + + expr_id + 4944556 + + + + + + conversionkinds + 4220603 + + + expr_id + 4220603 + + + kind + 6 + + + + + expr_id + kind + + + 12 + + + 1 + 2 + 4220603 + + + + + + + kind + expr_id + + + 12 + + + 2139 + 2140 + 1 + + + 3252 + 3253 + 1 + + + 13430 + 13431 + 1 + + + 26288 + 26289 + 1 + + + 44458 + 44459 + 1 + + + 4131036 + 4131037 + 1 + + + + + + + + + iscall + 3095893 + + + caller + 3095893 + + + kind + 53 + + + + + caller + kind + + + 12 + + + 1 + 2 + 3095893 + + + + + + + kind + caller + + + 12 + + + 1389 + 1390 + 17 + + + 2512 + 2513 + 17 + + + 168444 + 168445 + 17 + + + + + + + + + numtemplatearguments + 553810 + + + expr_id + 553810 + + + num + 71 + + + + + expr_id + num + + + 12 + + + 1 + 2 + 553810 + + + + + + + num + expr_id + + + 12 + + + 26 + 27 + 17 + + + 28 + 29 + 17 + + + 220 + 221 + 17 + + + 30556 + 30557 + 17 + + + + + + + + + specialnamequalifyingelements + 472 + + + id + 472 + + + name + 472 + + + + + id + name + + + 12 + + + 1 + 2 + 472 + + + + + + + name + id + + + 12 + + + 1 + 2 + 472 + + + + + + + + + namequalifiers + 1593457 + + + id + 1593457 + + + qualifiableelement + 1593457 + + + qualifyingelement + 74044 + + + location + 273366 + + + + + id + qualifiableelement + + + 12 + + + 1 + 2 + 1593457 + + + + + + + id + qualifyingelement + + + 12 + + + 1 + 2 + 1593457 + + + + + + + id + location + + + 12 + + + 1 + 2 + 1593457 + + + + + + + qualifiableelement + id + + + 12 + + + 1 + 2 + 1593457 + + + + + + + qualifiableelement + qualifyingelement + + + 12 + + + 1 + 2 + 1593457 + + + + + + + qualifiableelement + location + + + 12 + + + 1 + 2 + 1593457 + + + + + + + qualifyingelement + id + + + 12 + + + 1 + 2 + 46848 + + + 2 + 3 + 12322 + + + 3 + 4 + 5802 + + + 4 + 11 + 5622 + + + 11 + 31104 + 3448 + + + + + + + qualifyingelement + qualifiableelement + + + 12 + + + 1 + 2 + 46848 + + + 2 + 3 + 12322 + + + 3 + 4 + 5802 + + + 4 + 11 + 5622 + + + 11 + 31104 + 3448 + + + + + + + qualifyingelement + location + + + 12 + + + 1 + 2 + 50477 + + + 2 + 3 + 10885 + + + 3 + 4 + 6089 + + + 4 + 15 + 5604 + + + 15 + 7095 + 987 + + + + + + + location + id + + + 12 + + + 1 + 2 + 85792 + + + 2 + 3 + 24160 + + + 3 + 4 + 41621 + + + 4 + 6 + 12736 + + + 6 + 7 + 89547 + + + 7 + 2135 + 19508 + + + + + + + location + qualifiableelement + + + 12 + + + 1 + 2 + 85792 + + + 2 + 3 + 24160 + + + 3 + 4 + 41621 + + + 4 + 6 + 12736 + + + 6 + 7 + 89547 + + + 7 + 2135 + 19508 + + + + + + + location + qualifyingelement + + + 12 + + + 1 + 2 + 118270 + + + 2 + 3 + 50782 + + + 3 + 4 + 95942 + + + 4 + 152 + 8370 + + + + + + + + + varbind + 6005942 + + + expr + 6005942 + + + var + 765575 + + + + + expr + var + + + 12 + + + 1 + 2 + 6005942 + + + + + + + var + expr + + + 12 + + + 1 + 2 + 125736 + + + 2 + 3 + 137344 + + + 3 + 4 + 105884 + + + 4 + 5 + 84883 + + + 5 + 6 + 61053 + + + 6 + 7 + 47927 + + + 7 + 9 + 59392 + + + 9 + 13 + 59043 + + + 13 + 28 + 58653 + + + 28 + 5137 + 25655 + + + + + + + + + funbind + 3098283 + + + expr + 3094672 + + + fun + 512404 + + + + + expr + fun + + + 12 + + + 1 + 2 + 3091061 + + + 2 + 3 + 3610 + + + + + + + fun + expr + + + 12 + + + 1 + 2 + 298514 + + + 2 + 3 + 85810 + + + 3 + 4 + 36160 + + + 4 + 7 + 42968 + + + 7 + 35 + 38603 + + + 35 + 4943 + 10346 + + + + + + + + + expr_allocator + 54190 + + + expr + 54190 + + + func + 104 + + + form + 34 + + + + + expr + func + + + 12 + + + 1 + 2 + 54190 + + + + + + + expr + form + + + 12 + + + 1 + 2 + 54190 + + + + + + + func + expr + + + 12 + + + 1 + 2 + 34 + + + 585 + 586 + 34 + + + 963 + 964 + 34 + + + + + + + func + form + + + 12 + + + 1 + 2 + 104 + + + + + + + form + expr + + + 12 + + + 1549 + 1550 + 34 + + + + + + + form + func + + + 12 + + + 3 + 4 + 34 + + + + + + + + + expr_deallocator + 62901 + + + expr + 62901 + + + func + 104 + + + form + 69 + + + + + expr + func + + + 12 + + + 1 + 2 + 62901 + + + + + + + expr + form + + + 12 + + + 1 + 2 + 62901 + + + + + + + func + expr + + + 12 + + + 1 + 2 + 34 + + + 847 + 848 + 34 + + + 950 + 951 + 34 + + + + + + + func + form + + + 12 + + + 1 + 2 + 104 + + + + + + + form + expr + + + 12 + + + 848 + 849 + 34 + + + 950 + 951 + 34 + + + + + + + form + func + + + 12 + + + 1 + 2 + 34 + + + 2 + 3 + 34 + + + + + + + + + expr_cond_two_operand + 484 + + + cond + 484 + + + + + + expr_cond_guard + 654457 + + + cond + 654457 + + + guard + 654457 + + + + + cond + guard + + + 12 + + + 1 + 2 + 654457 + + + + + + + guard + cond + + + 12 + + + 1 + 2 + 654457 + + + + + + + + + expr_cond_true + 654455 + + + cond + 654455 + + + true + 654455 + + + + + cond + true + + + 12 + + + 1 + 2 + 654455 + + + + + + + true + cond + + + 12 + + + 1 + 2 + 654455 + + + + + + + + + expr_cond_false + 654457 + + + cond + 654457 + + + false + 654457 + + + + + cond + false + + + 12 + + + 1 + 2 + 654457 + + + + + + + false + cond + + + 12 + + + 1 + 2 + 654457 + + + + + + + + + values + 10645398 + + + id + 10645398 + + + str + 86632 + + + + + id + str + + + 12 + + + 1 + 2 + 10645398 + + + + + + + str + id + + + 12 + + + 1 + 2 + 58704 + + + 2 + 3 + 12259 + + + 3 + 6 + 6746 + + + 6 + 62 + 6512 + + + 62 + 451065 + 2410 + + + + + + + + + valuetext + 4756700 + + + id + 4756700 + + + text + 703927 + + + + + id + text + + + 12 + + + 1 + 2 + 4756700 + + + + + + + text + id + + + 12 + + + 1 + 2 + 527530 + + + 2 + 3 + 102489 + + + 3 + 7 + 56761 + + + 7 + 425881 + 17147 + + + + + + + + + valuebind + 11082271 + + + val + 10645398 + + + expr + 11082271 + + + + + val + expr + + + 12 + + + 1 + 2 + 10231303 + + + 2 + 7 + 414094 + + + + + + + expr + val + + + 12 + + + 1 + 2 + 11082271 + + + + + + + + + fieldoffsets + 1050009 + + + id + 1050009 + + + byteoffset + 22591 + + + bitoffset + 318 + + + + + id + byteoffset + + + 12 + + + 1 + 2 + 1050009 + + + + + + + id + bitoffset + + + 12 + + + 1 + 2 + 1050009 + + + + + + + byteoffset + id + + + 12 + + + 1 + 2 + 12966 + + + 2 + 3 + 1710 + + + 3 + 5 + 1789 + + + 5 + 12 + 1909 + + + 12 + 35 + 1710 + + + 35 + 205 + 1710 + + + 244 + 5638 + 795 + + + + + + + byteoffset + bitoffset + + + 12 + + + 1 + 2 + 21915 + + + 2 + 9 + 676 + + + + + + + bitoffset + id + + + 12 + + + 29 + 30 + 39 + + + 30 + 31 + 39 + + + 33 + 34 + 39 + + + 36 + 37 + 39 + + + 42 + 43 + 39 + + + 43 + 44 + 39 + + + 55 + 56 + 39 + + + 26131 + 26132 + 39 + + + + + + + bitoffset + byteoffset + + + 12 + + + 11 + 12 + 159 + + + 12 + 13 + 79 + + + 13 + 14 + 39 + + + 568 + 569 + 39 + + + + + + + + + bitfield + 21007 + + + id + 21007 + + + bits + 2625 + + + declared_bits + 2625 + + + + + id + bits + + + 12 + + + 1 + 2 + 21007 + + + + + + + id + declared_bits + + + 12 + + + 1 + 2 + 21007 + + + + + + + bits + id + + + 12 + + + 1 + 2 + 735 + + + 2 + 3 + 630 + + + 3 + 4 + 210 + + + 4 + 5 + 210 + + + 5 + 6 + 210 + + + 6 + 8 + 210 + + + 8 + 11 + 210 + + + 12 + 115 + 210 + + + + + + + bits + declared_bits + + + 12 + + + 1 + 2 + 2625 + + + + + + + declared_bits + id + + + 12 + + + 1 + 2 + 735 + + + 2 + 3 + 630 + + + 3 + 4 + 210 + + + 4 + 5 + 210 + + + 5 + 6 + 210 + + + 6 + 8 + 210 + + + 8 + 11 + 210 + + + 12 + 115 + 210 + + + + + + + declared_bits + bits + + + 12 + + + 1 + 2 + 2625 + + + + + + + + + initialisers + 1736804 + + + init + 1736804 + + + var + 719782 + + + expr + 1736804 + + + location + 391526 + + + + + init + var + + + 12 + + + 1 + 2 + 1736804 + + + + + + + init + expr + + + 12 + + + 1 + 2 + 1736804 + + + + + + + init + location + + + 12 + + + 1 + 2 + 1736804 + + + + + + + var + init + + + 12 + + + 1 + 2 + 631170 + + + 2 + 16 + 31717 + + + 16 + 25 + 56851 + + + 25 + 112 + 44 + + + + + + + var + expr + + + 12 + + + 1 + 2 + 631170 + + + 2 + 16 + 31717 + + + 16 + 25 + 56851 + + + 25 + 112 + 44 + + + + + + + var + location + + + 12 + + + 1 + 2 + 719700 + + + 2 + 4 + 81 + + + + + + + expr + init + + + 12 + + + 1 + 2 + 1736804 + + + + + + + expr + var + + + 12 + + + 1 + 2 + 1736804 + + + + + + + expr + location + + + 12 + + + 1 + 2 + 1736804 + + + + + + + location + init + + + 12 + + + 1 + 2 + 318848 + + + 2 + 3 + 23904 + + + 3 + 15 + 30865 + + + 15 + 111462 + 17907 + + + + + + + location + var + + + 12 + + + 1 + 2 + 341914 + + + 2 + 4 + 35670 + + + 4 + 12741 + 13941 + + + + + + + location + expr + + + 12 + + + 1 + 2 + 318848 + + + 2 + 3 + 23904 + + + 3 + 15 + 30865 + + + 15 + 111462 + 17907 + + + + + + + + + expr_ancestor + 121360 + + + exp + 121360 + + + ancestor + 84661 + + + + + exp + ancestor + + + 12 + + + 1 + 2 + 121360 + + + + + + + ancestor + exp + + + 12 + + + 1 + 2 + 61219 + + + 2 + 3 + 16741 + + + 3 + 8 + 6466 + + + 8 + 18 + 233 + + + + + + + + + exprs + 18298854 + + + id + 18298854 + + + kind + 8670 + + + location + 7747846 + + + + + id + kind + + + 12 + + + 1 + 2 + 18298854 + + + + + + + id + location + + + 12 + + + 1 + 2 + 18298854 + + + + + + + kind + id + + + 12 + + + 1 + 6 + 632 + + + 6 + 12 + 632 + + + 18 + 28 + 541 + + + 29 + 45 + 722 + + + 45 + 88 + 722 + + + 89 + 122 + 722 + + + 152 + 234 + 722 + + + 241 + 441 + 722 + + + 504 + 778 + 722 + + + 802 + 1049 + 722 + + + 1117 + 2286 + 722 + + + 2424 + 9743 + 722 + + + 22722 + 53144 + 361 + + + + + + + kind + location + + + 12 + + + 1 + 3 + 722 + + + 3 + 4 + 541 + + + 4 + 13 + 722 + + + 13 + 24 + 722 + + + 24 + 37 + 722 + + + 41 + 101 + 722 + + + 102 + 175 + 722 + + + 180 + 279 + 722 + + + 281 + 499 + 722 + + + 565 + 774 + 722 + + + 813 + 1643 + 722 + + + 1728 + 13946 + 722 + + + 15037 + 33170 + 180 + + + + + + + location + id + + + 12 + + + 1 + 2 + 5161708 + + + 2 + 3 + 1378731 + + + 3 + 5 + 662723 + + + 5 + 14777 + 544682 + + + + + + + location + kind + + + 12 + + + 1 + 2 + 5999730 + + + 2 + 3 + 1427591 + + + 3 + 26 + 320523 + + + + + + + + + expr_types + 18356354 + + + id + 18298854 + + + typeid + 806338 + + + value_category + 53 + + + + + id + typeid + + + 12 + + + 1 + 2 + 18241425 + + + 2 + 5 + 57428 + + + + + + + id + value_category + + + 12 + + + 1 + 2 + 18298854 + + + + + + + typeid + id + + + 12 + + + 1 + 2 + 278288 + + + 2 + 3 + 160556 + + + 3 + 4 + 69787 + + + 4 + 5 + 57051 + + + 5 + 7 + 62027 + + + 7 + 12 + 67236 + + + 12 + 35 + 61758 + + + 35 + 78725 + 49632 + + + + + + + typeid + value_category + + + 12 + + + 1 + 2 + 695684 + + + 2 + 3 + 100271 + + + 3 + 4 + 10382 + + + + + + + value_category + id + + + 12 + + + 11948 + 11949 + 17 + + + 253514 + 253515 + 17 + + + 753215 + 753216 + 17 + + + + + + + value_category + typeid + + + 12 + + + 1415 + 1416 + 17 + + + 11760 + 11761 + 17 + + + 38451 + 38452 + 17 + + + + + + + + + new_allocated_type + 55240 + + + expr + 55240 + + + type_id + 27952 + + + + + expr + type_id + + + 12 + + + 1 + 2 + 55240 + + + + + + + type_id + expr + + + 12 + + + 1 + 2 + 9095 + + + 2 + 3 + 15987 + + + 3 + 6 + 2134 + + + 6 + 28 + 734 + + + + + + + + + new_array_allocated_type + 5113 + + + expr + 5113 + + + type_id + 2200 + + + + + expr + type_id + + + 12 + + + 1 + 2 + 5113 + + + + + + + type_id + expr + + + 12 + + + 1 + 2 + 31 + + + 2 + 3 + 1948 + + + 3 + 7 + 170 + + + 8 + 15 + 50 + + + + + + + + + aggregate_field_init + 4005579 + + + aggregate + 847953 + + + initializer + 4005406 + + + field + 2156 + + + + + aggregate + initializer + + + 12 + + + 1 + 2 + 6503 + + + 2 + 3 + 500733 + + + 3 + 4 + 11095 + + + 4 + 5 + 88743 + + + 5 + 12 + 49719 + + + 12 + 13 + 190968 + + + 13 + 42 + 192 + + + + + + + aggregate + field + + + 12 + + + 1 + 2 + 6502 + + + 2 + 3 + 500702 + + + 3 + 4 + 11095 + + + 4 + 5 + 88750 + + + 5 + 12 + 49743 + + + 12 + 13 + 190968 + + + 13 + 42 + 193 + + + + + + + initializer + aggregate + + + 12 + + + 1 + 2 + 4005406 + + + + + + + initializer + field + + + 12 + + + 1 + 2 + 4005233 + + + 2 + 3 + 173 + + + + + + + field + aggregate + + + 12 + + + 1 + 2 + 782 + + + 2 + 3 + 202 + + + 3 + 6 + 158 + + + 6 + 12 + 184 + + + 12 + 21 + 163 + + + 21 + 44 + 164 + + + 46 + 106 + 171 + + + 108 + 383 + 167 + + + 394 + 190920 + 163 + + + 288611 + 288612 + 2 + + + + + + + field + initializer + + + 12 + + + 1 + 2 + 782 + + + 2 + 3 + 202 + + + 3 + 6 + 158 + + + 6 + 12 + 184 + + + 12 + 21 + 163 + + + 21 + 44 + 164 + + + 46 + 106 + 171 + + + 108 + 383 + 167 + + + 394 + 190920 + 163 + + + 288611 + 288612 + 2 + + + + + + + + + aggregate_array_init + 730401 + + + aggregate + 65615 + + + initializer + 730401 + + + element_index + 17485 + + + + + aggregate + initializer + + + 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 + + + + + + + aggregate + element_index + + + 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 + + + 12 + + + 1 + 2 + 730401 + + + + + + + initializer + element_index + + + 12 + + + 1 + 2 + 730401 + + + + + + + element_index + 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 + + + + + + + element_index + 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 + + + + + + + + + condition_decl_bind + 38495 + + + expr + 38495 + + + decl + 38495 + + + + + expr + decl + + + 12 + + + 1 + 2 + 38495 + + + + + + + decl + expr + + + 12 + + + 1 + 2 + 38495 + + + + + + + + + typeid_bind + 36173 + + + expr + 36173 + + + type_id + 16267 + + + + + expr + type_id + + + 12 + + + 1 + 2 + 36173 + + + + + + + type_id + expr + + + 12 + + + 1 + 2 + 15847 + + + 3 + 328 + 419 + + + + + + + + + uuidof_bind + 20051 + + + expr + 20051 + + + type_id + 19856 + + + + + expr + type_id + + + 12 + + + 1 + 2 + 20051 + + + + + + + type_id + expr + + + 12 + + + 1 + 2 + 19692 + + + 2 + 4 + 163 + + + + + + + + + sizeof_bind + 191840 + + + expr + 191840 + + + type_id + 8193 + + + + + expr + type_id + + + 12 + + + 1 + 2 + 191840 + + + + + + + type_id + expr + + + 12 + + + 1 + 2 + 2697 + + + 2 + 3 + 2330 + + + 3 + 4 + 776 + + + 4 + 5 + 750 + + + 5 + 6 + 212 + + + 6 + 9 + 723 + + + 9 + 133 + 649 + + + 164 + 18023 + 53 + + + + + + + + + code_block + 15 + + + block + 15 + + + routine + 15 + + + + + block + routine + + + 12 + + + 1 + 2 + 15 + + + + + + + routine + block + + + 12 + + + 1 + 2 + 15 + + + + + + + + + lambdas + 21712 + + + expr + 21712 + + + default_capture + 472 + + + has_explicit_return_type + 472 + + + + + expr + default_capture + + + 12 + + + 1 + 2 + 21712 + + + + + + + expr + has_explicit_return_type + + + 12 + + + 1 + 2 + 21712 + + + + + + + default_capture + expr + + + 12 + + + 46 + 47 + 472 + + + + + + + default_capture + has_explicit_return_type + + + 12 + + + 1 + 2 + 472 + + + + + + + has_explicit_return_type + expr + + + 12 + + + 46 + 47 + 472 + + + + + + + has_explicit_return_type + default_capture + + + 12 + + + 1 + 2 + 472 + + + + + + + + + lambda_capture + 28320 + + + id + 28320 + + + lambda + 20768 + + + index + 944 + + + field + 28320 + + + captured_by_reference + 472 + + + is_implicit + 472 + + + location + 2832 + + + + + id + lambda + + + 12 + + + 1 + 2 + 28320 + + + + + + + id + index + + + 12 + + + 1 + 2 + 28320 + + + + + + + id + field + + + 12 + + + 1 + 2 + 28320 + + + + + + + id + captured_by_reference + + + 12 + + + 1 + 2 + 28320 + + + + + + + id + is_implicit + + + 12 + + + 1 + 2 + 28320 + + + + + + + id + location + + + 12 + + + 1 + 2 + 28320 + + + + + + + lambda + id + + + 12 + + + 1 + 2 + 13216 + + + 2 + 3 + 7552 + + + + + + + lambda + index + + + 12 + + + 1 + 2 + 13216 + + + 2 + 3 + 7552 + + + + + + + lambda + field + + + 12 + + + 1 + 2 + 13216 + + + 2 + 3 + 7552 + + + + + + + lambda + captured_by_reference + + + 12 + + + 1 + 2 + 20768 + + + + + + + lambda + is_implicit + + + 12 + + + 1 + 2 + 20768 + + + + + + + lambda + location + + + 12 + + + 1 + 2 + 13216 + + + 2 + 3 + 7552 + + + + + + + index + id + + + 12 + + + 16 + 17 + 472 + + + 44 + 45 + 472 + + + + + + + index + lambda + + + 12 + + + 16 + 17 + 472 + + + 44 + 45 + 472 + + + + + + + index + field + + + 12 + + + 16 + 17 + 472 + + + 44 + 45 + 472 + + + + + + + index + captured_by_reference + + + 12 + + + 1 + 2 + 944 + + + + + + + index + is_implicit + + + 12 + + + 1 + 2 + 944 + + + + + + + index + location + + + 12 + + + 2 + 3 + 472 + + + 4 + 5 + 472 + + + + + + + field + id + + + 12 + + + 1 + 2 + 28320 + + + + + + + field + lambda + + + 12 + + + 1 + 2 + 28320 + + + + + + + field + index + + + 12 + + + 1 + 2 + 28320 + + + + + + + field + captured_by_reference + + + 12 + + + 1 + 2 + 28320 + + + + + + + field + is_implicit + + + 12 + + + 1 + 2 + 28320 + + + + + + + field + location + + + 12 + + + 1 + 2 + 28320 + + + + + + + captured_by_reference + id + + + 12 + + + 60 + 61 + 472 + + + + + + + captured_by_reference + lambda + + + 12 + + + 44 + 45 + 472 + + + + + + + captured_by_reference + index + + + 12 + + + 2 + 3 + 472 + + + + + + + captured_by_reference + field + + + 12 + + + 60 + 61 + 472 + + + + + + + captured_by_reference + is_implicit + + + 12 + + + 1 + 2 + 472 + + + + + + + captured_by_reference + location + + + 12 + + + 6 + 7 + 472 + + + + + + + is_implicit + id + + + 12 + + + 60 + 61 + 472 + + + + + + + is_implicit + lambda + + + 12 + + + 44 + 45 + 472 + + + + + + + is_implicit + index + + + 12 + + + 2 + 3 + 472 + + + + + + + is_implicit + field + + + 12 + + + 60 + 61 + 472 + + + + + + + is_implicit + captured_by_reference + + + 12 + + + 1 + 2 + 472 + + + + + + + is_implicit + location + + + 12 + + + 6 + 7 + 472 + + + + + + + location + id + + + 12 + + + 8 + 9 + 1888 + + + 14 + 15 + 944 + + + + + + + location + lambda + + + 12 + + + 8 + 9 + 1888 + + + 14 + 15 + 944 + + + + + + + location + index + + + 12 + + + 1 + 2 + 2832 + + + + + + + location + field + + + 12 + + + 8 + 9 + 1888 + + + 14 + 15 + 944 + + + + + + + location + captured_by_reference + + + 12 + + + 1 + 2 + 2832 + + + + + + + location + is_implicit + + + 12 + + + 1 + 2 + 2832 + + + + + + + + + fold + 4 + + + expr + 4 + + + operator + 4 + + + is_left_fold + 2 + + + + + expr + operator + + + 12 + + + 1 + 2 + 4 + + + + + + + expr + is_left_fold + + + 12 + + + 1 + 2 + 4 + + + + + + + operator + expr + + + 12 + + + 1 + 2 + 4 + + + + + + + operator + is_left_fold + + + 12 + + + 1 + 2 + 4 + + + + + + + is_left_fold + expr + + + 12 + + + 2 + 3 + 2 + + + + + + + is_left_fold + operator + + + 12 + + + 2 + 3 + 2 + + + + + + + + + stmts + 4689495 + + + id + 4689495 + + + kind + 1995 + + + location + 2293751 + + + + + id + kind + + + 12 + + + 1 + 2 + 4689495 + + + + + + + id + location + + + 12 + + + 1 + 2 + 4689495 + + + + + + + kind + id + + + 12 + + + 1 + 2 + 105 + + + 18 + 19 + 105 + + + 22 + 23 + 105 + + + 46 + 47 + 105 + + + 75 + 76 + 105 + + + 83 + 84 + 105 + + + 102 + 103 + 105 + + + 154 + 155 + 105 + + + 242 + 243 + 105 + + + 284 + 285 + 105 + + + 383 + 384 + 105 + + + 418 + 419 + 105 + + + 501 + 502 + 105 + + + 1324 + 1325 + 105 + + + 2629 + 2630 + 105 + + + 4606 + 4607 + 105 + + + 8935 + 8936 + 105 + + + 11547 + 11548 + 105 + + + 13275 + 13276 + 105 + + + + + + + kind + location + + + 12 + + + 1 + 2 + 105 + + + 8 + 9 + 105 + + + 18 + 19 + 105 + + + 45 + 46 + 105 + + + 50 + 51 + 105 + + + 56 + 57 + 105 + + + 74 + 75 + 105 + + + 88 + 89 + 105 + + + 101 + 102 + 105 + + + 128 + 129 + 105 + + + 209 + 210 + 105 + + + 252 + 253 + 105 + + + 368 + 369 + 105 + + + 641 + 642 + 105 + + + 1742 + 1743 + 105 + + + 2183 + 2184 + 105 + + + 4210 + 4211 + 105 + + + 6065 + 6066 + 105 + + + 6529 + 6530 + 105 + + + + + + + location + id + + + 12 + + + 1 + 2 + 1897016 + + + 2 + 4 + 177201 + + + 4 + 12 + 176466 + + + 12 + 684 + 43066 + + + + + + + location + kind + + + 12 + + + 1 + 2 + 2234613 + + + 2 + 8 + 59137 + + + + + + + + + type_vla + 1 + + + type_id + 1 + + + decl + 1 + + + + + type_id + decl + + + 12 + + + 1 + 2 + 1 + + + + + + + decl + type_id + + + 12 + + + 1 + 2 + 1 + + + + + + + + + variable_vla + 21 + + + var + 21 + + + decl + 21 + + + + + var + decl + + + 12 + + + 1 + 2 + 21 + + + + + + + decl + var + + + 12 + + + 1 + 2 + 21 + + + + + + + + + if_then + 723123 + + + if_stmt + 723123 + + + then_id + 723123 + + + + + if_stmt + then_id + + + 12 + + + 1 + 2 + 723123 + + + + + + + then_id + if_stmt + + + 12 + + + 1 + 2 + 723123 + + + + + + + + + if_else + 183959 + + + if_stmt + 183959 + + + else_id + 183959 + + + + + if_stmt + else_id + + + 12 + + + 1 + 2 + 183959 + + + + + + + else_id + if_stmt + + + 12 + + + 1 + 2 + 183959 + + + + + + + + + constexpr_if_then + 52624 + + + constexpr_if_stmt + 52624 + + + then_id + 52624 + + + + + constexpr_if_stmt + then_id + + + 12 + + + 1 + 2 + 52624 + + + + + + + then_id + constexpr_if_stmt + + + 12 + + + 1 + 2 + 52624 + + + + + + + + + constexpr_if_else + 30986 + + + constexpr_if_stmt + 30986 + + + else_id + 30986 + + + + + constexpr_if_stmt + else_id + + + 12 + + + 1 + 2 + 30986 + + + + + + + else_id + constexpr_if_stmt + + + 12 + + + 1 + 2 + 30986 + + + + + + + + + while_body + 30265 + + + while_stmt + 30265 + + + body_id + 30265 + + + + + while_stmt + body_id + + + 12 + + + 1 + 2 + 30265 + + + + + + + body_id + while_stmt + + + 12 + + + 1 + 2 + 30265 + + + + + + + + + do_body + 148593 + + + do_stmt + 148593 + + + body_id + 148593 + + + + + do_stmt + body_id + + + 12 + + + 1 + 2 + 148593 + + + + + + + body_id + do_stmt + + + 12 + + + 1 + 2 + 148593 + + + + + + + + + switch_case + 190914 + + + switch_stmt + 10275 + + + index + 4418 + + + case_id + 190914 + + + + + switch_stmt + index + + + 12 + + + 2 + 3 + 53 + + + 3 + 4 + 2263 + + + 4 + 5 + 1652 + + + 5 + 6 + 1005 + + + 6 + 7 + 754 + + + 7 + 9 + 718 + + + 9 + 10 + 970 + + + 10 + 11 + 323 + + + 11 + 14 + 862 + + + 14 + 31 + 826 + + + 36 + 247 + 844 + + + + + + + switch_stmt + case_id + + + 12 + + + 2 + 3 + 53 + + + 3 + 4 + 2263 + + + 4 + 5 + 1652 + + + 5 + 6 + 1005 + + + 6 + 7 + 754 + + + 7 + 9 + 718 + + + 9 + 10 + 970 + + + 10 + 11 + 323 + + + 11 + 14 + 862 + + + 14 + 31 + 826 + + + 36 + 247 + 844 + + + + + + + index + switch_stmt + + + 12 + + + 14 + 15 + 1167 + + + 18 + 19 + 538 + + + 32 + 33 + 1904 + + + 33 + 62 + 377 + + + 66 + 296 + 341 + + + 351 + 573 + 89 + + + + + + + index + case_id + + + 12 + + + 14 + 15 + 1167 + + + 18 + 19 + 538 + + + 32 + 33 + 1904 + + + 33 + 62 + 377 + + + 66 + 296 + 341 + + + 351 + 573 + 89 + + + + + + + case_id + switch_stmt + + + 12 + + + 1 + 2 + 190914 + + + + + + + case_id + index + + + 12 + + + 1 + 2 + 190914 + + + + + + + + + switch_body + 20900 + + + switch_stmt + 20900 + + + body_id + 20900 + + + + + switch_stmt + body_id + + + 12 + + + 1 + 2 + 20900 + + + + + + + body_id + switch_stmt + + + 12 + + + 1 + 2 + 20900 + + + + + + + + + for_initialization + 53198 + + + for_stmt + 53198 + + + init_id + 53198 + + + + + for_stmt + init_id + + + 12 + + + 1 + 2 + 53198 + + + + + + + init_id + for_stmt + + + 12 + + + 1 + 2 + 53198 + + + + + + + + + for_condition + 55454 + + + for_stmt + 55454 + + + condition_id + 55454 + + + + + for_stmt + condition_id + + + 12 + + + 1 + 2 + 55454 + + + + + + + condition_id + for_stmt + + + 12 + + + 1 + 2 + 55454 + + + + + + + + + for_update + 53301 + + + for_stmt + 53301 + + + update_id + 53301 + + + + + for_stmt + update_id + + + 12 + + + 1 + 2 + 53301 + + + + + + + update_id + for_stmt + + + 12 + + + 1 + 2 + 53301 + + + + + + + + + for_body + 61319 + + + for_stmt + 61319 + + + body_id + 61319 + + + + + for_stmt + body_id + + + 12 + + + 1 + 2 + 61319 + + + + + + + body_id + for_stmt + + + 12 + + + 1 + 2 + 61319 + + + + + + + + + stmtparents + 4064694 + + + id + 4064694 + + + index + 12245 + + + parent + 1724432 + + + + + id + index + + + 12 + + + 1 + 2 + 4064694 + + + + + + + id + parent + + + 12 + + + 1 + 2 + 4064694 + + + + + + + index + id + + + 12 + + + 1 + 2 + 4022 + + + 2 + 3 + 1002 + + + 3 + 4 + 220 + + + 4 + 5 + 1557 + + + 7 + 8 + 1021 + + + 8 + 12 + 794 + + + 12 + 29 + 1078 + + + 29 + 38 + 920 + + + 41 + 77 + 926 + + + 77 + 196938 + 699 + + + + + + + index + parent + + + 12 + + + 1 + 2 + 4022 + + + 2 + 3 + 1002 + + + 3 + 4 + 220 + + + 4 + 5 + 1557 + + + 7 + 8 + 1021 + + + 8 + 12 + 794 + + + 12 + 29 + 1078 + + + 29 + 38 + 920 + + + 41 + 77 + 926 + + + 77 + 196938 + 699 + + + + + + + parent + id + + + 12 + + + 1 + 2 + 989567 + + + 2 + 3 + 374640 + + + 3 + 4 + 106047 + + + 4 + 6 + 111564 + + + 6 + 17 + 130216 + + + 17 + 1943 + 12396 + + + + + + + parent + index + + + 12 + + + 1 + 2 + 989567 + + + 2 + 3 + 374640 + + + 3 + 4 + 106047 + + + 4 + 6 + 111564 + + + 6 + 17 + 130216 + + + 17 + 1943 + 12396 + + + + + + + + + ishandler + 59279 + + + block + 59279 + + + + + + stmt_decl_bind + 585681 + + + stmt + 545527 + + + num + 75 + + + decl + 585576 + + + + + stmt + num + + + 12 + + + 1 + 2 + 524646 + + + 2 + 19 + 20881 + + + + + + + stmt + decl + + + 12 + + + 1 + 2 + 524646 + + + 2 + 19 + 20881 + + + + + + + num + stmt + + + 12 + + + 1 + 2 + 8 + + + 3 + 4 + 4 + + + 4 + 5 + 4 + + + 8 + 9 + 4 + + + 9 + 10 + 4 + + + 10 + 11 + 8 + + + 16 + 17 + 4 + + + 42 + 43 + 4 + + + 89 + 90 + 4 + + + 128 + 129 + 4 + + + 218 + 219 + 4 + + + 390 + 391 + 4 + + + 1086 + 1087 + 4 + + + 2570 + 2571 + 4 + + + 4968 + 4969 + 4 + + + 129788 + 129789 + 4 + + + + + + + num + decl + + + 12 + + + 1 + 2 + 8 + + + 3 + 4 + 4 + + + 4 + 5 + 4 + + + 8 + 9 + 4 + + + 9 + 10 + 4 + + + 10 + 11 + 8 + + + 16 + 17 + 4 + + + 42 + 43 + 4 + + + 89 + 90 + 4 + + + 128 + 129 + 4 + + + 218 + 219 + 4 + + + 390 + 391 + 4 + + + 1086 + 1087 + 4 + + + 2570 + 2571 + 4 + + + 4968 + 4969 + 4 + + + 129763 + 129764 + 4 + + + + + + + decl + stmt + + + 12 + + + 1 + 2 + 585538 + + + 2 + 6 + 37 + + + + + + + decl + num + + + 12 + + + 1 + 2 + 585576 + + + + + + + + + stmt_decl_entry_bind + 528084 + + + stmt + 488233 + + + num + 75 + + + decl_entry + 528025 + + + + + stmt + num + + + 12 + + + 1 + 2 + 467616 + + + 2 + 19 + 20616 + + + + + + + stmt + decl_entry + + + 12 + + + 1 + 2 + 467616 + + + 2 + 19 + 20616 + + + + + + + num + stmt + + + 12 + + + 1 + 2 + 8 + + + 3 + 4 + 4 + + + 4 + 5 + 4 + + + 8 + 9 + 4 + + + 9 + 10 + 4 + + + 10 + 11 + 8 + + + 16 + 17 + 4 + + + 42 + 43 + 4 + + + 89 + 90 + 4 + + + 128 + 129 + 4 + + + 218 + 219 + 4 + + + 390 + 391 + 4 + + + 1086 + 1087 + 4 + + + 2561 + 2562 + 4 + + + 4905 + 4906 + 4 + + + 116157 + 116158 + 4 + + + + + + + num + decl_entry + + + 12 + + + 1 + 2 + 8 + + + 3 + 4 + 4 + + + 4 + 5 + 4 + + + 8 + 9 + 4 + + + 9 + 10 + 4 + + + 10 + 11 + 8 + + + 16 + 17 + 4 + + + 42 + 43 + 4 + + + 89 + 90 + 4 + + + 128 + 129 + 4 + + + 218 + 219 + 4 + + + 390 + 391 + 4 + + + 1086 + 1087 + 4 + + + 2561 + 2562 + 4 + + + 4905 + 4906 + 4 + + + 116143 + 116144 + 4 + + + + + + + decl_entry + stmt + + + 12 + + + 1 + 2 + 528004 + + + 3 + 6 + 21 + + + + + + + decl_entry + num + + + 12 + + + 1 + 2 + 528025 + + + + + + + + + blockscope + 1442932 + + + block + 1442932 + + + enclosing + 1326345 + + + + + block + enclosing + + + 12 + + + 1 + 2 + 1442932 + + + + + + + enclosing + block + + + 12 + + + 1 + 2 + 1260264 + + + 2 + 13 + 66081 + + + + + + + + + jumpinfo + 253977 + + + id + 253977 + + + str + 21151 + + + target + 53042 + + + + + id + str + + + 12 + + + 1 + 2 + 253977 + + + + + + + id + target + + + 12 + + + 1 + 2 + 253977 + + + + + + + str + id + + + 12 + + + 2 + 3 + 9874 + + + 3 + 4 + 4246 + + + 4 + 5 + 1565 + + + 5 + 6 + 1340 + + + 6 + 10 + 1699 + + + 10 + 22 + 1620 + + + 22 + 13723 + 804 + + + + + + + str + target + + + 12 + + + 1 + 2 + 16716 + + + 2 + 3 + 2631 + + + 3 + 10 + 1687 + + + 10 + 3326 + 115 + + + + + + + target + id + + + 12 + + + 1 + 2 + 24 + + + 2 + 3 + 26426 + + + 3 + 4 + 12896 + + + 4 + 5 + 5342 + + + 5 + 8 + 4690 + + + 8 + 2124 + 3661 + + + + + + + target + str + + + 12 + + + 1 + 2 + 53042 + + + + + + + + + preprocdirects + 4447274 + + + id + 4447274 + + + kind + 1050 + + + location + 4444753 + + + + + id + kind + + + 12 + + + 1 + 2 + 4447274 + + + + + + + id + location + + + 12 + + + 1 + 2 + 4447274 + + + + + + + kind + id + + + 12 + + + 121 + 122 + 105 + + + 693 + 694 + 105 + + + 794 + 795 + 105 + + + 917 + 918 + 105 + + + 1697 + 1698 + 105 + + + 1785 + 1786 + 105 + + + 2983 + 2984 + 105 + + + 3799 + 3800 + 105 + + + 6290 + 6291 + 105 + + + 23260 + 23261 + 105 + + + + + + + kind + location + + + 12 + + + 121 + 122 + 105 + + + 693 + 694 + 105 + + + 794 + 795 + 105 + + + 917 + 918 + 105 + + + 1697 + 1698 + 105 + + + 1785 + 1786 + 105 + + + 2983 + 2984 + 105 + + + 3799 + 3800 + 105 + + + 6290 + 6291 + 105 + + + 23236 + 23237 + 105 + + + + + + + location + id + + + 12 + + + 1 + 2 + 4444648 + + + 25 + 26 + 105 + + + + + + + location + kind + + + 12 + + + 1 + 2 + 4444753 + + + + + + + + + preprocpair + 1443876 + + + begin + 1206927 + + + elseelifend + 1443876 + + + + + begin + elseelifend + + + 12 + + + 1 + 2 + 986027 + + + 2 + 3 + 210516 + + + 3 + 11 + 10384 + + + + + + + elseelifend + begin + + + 12 + + + 1 + 2 + 1443876 + + + + + + + + + preproctrue + 784479 + + + branch + 784479 + + + + + + preprocfalse + 325686 + + + branch + 325686 + + + + + + preproctext + 3585423 + + + id + 3585423 + + + head + 2599941 + + + body + 1520449 + + + + + id + head + + + 12 + + + 1 + 2 + 3585423 + + + + + + + id + body + + + 12 + + + 1 + 2 + 3585423 + + + + + + + head + id + + + 12 + + + 1 + 2 + 2452360 + + + 2 + 740 + 147580 + + + + + + + head + body + + + 12 + + + 1 + 2 + 2537548 + + + 2 + 5 + 62393 + + + + + + + body + id + + + 12 + + + 1 + 2 + 1376334 + + + 2 + 6 + 114073 + + + 6 + 11582 + 30041 + + + + + + + body + head + + + 12 + + + 1 + 2 + 1379380 + + + 2 + 7 + 114388 + + + 7 + 2959 + 26680 + + + + + + + + + includes + 316718 + + + id + 316718 + + + included + 118474 + + + + + id + included + + + 12 + + + 1 + 2 + 316718 + + + + + + + included + id + + + 12 + + + 1 + 2 + 61833 + + + 2 + 3 + 22184 + + + 3 + 4 + 12744 + + + 4 + 6 + 10384 + + + 6 + 14 + 8968 + + + 14 + 47 + 2360 + + + + + + + + + link_targets + 1471 + + + id + 1471 + + + binary + 1471 + + + + + id + binary + + + 12 + + + 1 + 2 + 1471 + + + + + + + binary + id + + + 12 + + + 1 + 2 + 1471 + + + + + + + + + link_parent + 40018704 + + + element + 5094359 + + + link_target + 349 + + + + + element + link_target + + + 12 + + + 1 + 2 + 694015 + + + 2 + 9 + 43135 + + + 9 + 10 + 4357208 + + + + + + + link_target + element + + + 12 + + + 3 + 4 + 34 + + + 124724 + 124725 + 34 + + + 124828 + 124829 + 34 + + + 124926 + 124927 + 34 + + + 124964 + 124965 + 34 + + + 124978 + 124979 + 34 + + + 124980 + 124981 + 34 + + + 126863 + 126864 + 34 + + + 132946 + 132947 + 34 + + + 134697 + 134698 + 34 + + + + + + + + + xmlEncoding + 39724 + + + id + 39724 + + + encoding + 1 + + + + + id + encoding + + + 12 + + + 1 + 2 + 39724 + + + + + + + encoding + id + + + 12 + + + 39724 + 39725 + 1 + + + + + + + + + xmlDTDs + 1 + + + id + 1 + + + root + 1 + + + publicId + 1 + + + systemId + 1 + + + fileid + 1 + + + + + id + root + + + 12 + + + 1 + 2 + 1 + + + + + + + id + publicId + + + 12 + + + 1 + 2 + 1 + + + + + + + id + systemId + + + 12 + + + 1 + 2 + 1 + + + + + + + id + fileid + + + 12 + + + 1 + 2 + 1 + + + + + + + root + id + + + 12 + + + 1 + 2 + 1 + + + + + + + root + publicId + + + 12 + + + 1 + 2 + 1 + + + + + + + root + systemId + + + 12 + + + 1 + 2 + 1 + + + + + + + root + fileid + + + 12 + + + 1 + 2 + 1 + + + + + + + publicId + id + + + 12 + + + 1 + 2 + 1 + + + + + + + publicId + root + + + 12 + + + 1 + 2 + 1 + + + + + + + publicId + systemId + + + 12 + + + 1 + 2 + 1 + + + + + + + publicId + fileid + + + 12 + + + 1 + 2 + 1 + + + + + + + systemId + id + + + 12 + + + 1 + 2 + 1 + + + + + + + systemId + root + + + 12 + + + 1 + 2 + 1 + + + + + + + systemId + publicId + + + 12 + + + 1 + 2 + 1 + + + + + + + systemId + fileid + + + 12 + + + 1 + 2 + 1 + + + + + + + fileid + id + + + 12 + + + 1 + 2 + 1 + + + + + + + fileid + root + + + 12 + + + 1 + 2 + 1 + + + + + + + fileid + publicId + + + 12 + + + 1 + 2 + 1 + + + + + + + fileid + systemId + + + 12 + + + 1 + 2 + 1 + + + + + + + + + xmlElements + 1270313 + + + id + 1270313 + + + name + 4655 + + + parentid + 578021 + + + idx + 35122 + + + fileid + 39721 + + + + + id + name + + + 12 + + + 1 + 2 + 1270313 + + + + + + + id + parentid + + + 12 + + + 1 + 2 + 1270313 + + + + + + + id + idx + + + 12 + + + 1 + 2 + 1270313 + + + + + + + id + fileid + + + 12 + + + 1 + 2 + 1270313 + + + + + + + name + id + + + 12 + + + 1 + 2 + 420 + + + 2 + 5 + 156 + + + 5 + 6 + 3832 + + + 6 + 310317 + 247 + + + + + + + name + parentid + + + 12 + + + 1 + 2 + 456 + + + 2 + 5 + 150 + + + 5 + 6 + 3829 + + + 6 + 161565 + 220 + + + + + + + name + idx + + + 12 + + + 1 + 2 + 4358 + + + 2 + 35123 + 297 + + + + + + + name + fileid + + + 12 + + + 1 + 2 + 486 + + + 2 + 5 + 133 + + + 5 + 6 + 3831 + + + 6 + 14503 + 205 + + + + + + + parentid + id + + + 12 + + + 1 + 2 + 371969 + + + 2 + 3 + 62095 + + + 3 + 4 + 104113 + + + 4 + 35123 + 39844 + + + + + + + parentid + name + + + 12 + + + 1 + 2 + 500482 + + + 2 + 3 + 17866 + + + 3 + 4 + 49117 + + + 4 + 45 + 10556 + + + + + + + parentid + idx + + + 12 + + + 1 + 2 + 371969 + + + 2 + 3 + 62095 + + + 3 + 4 + 104113 + + + 4 + 35123 + 39844 + + + + + + + parentid + fileid + + + 12 + + + 1 + 2 + 578021 + + + + + + + idx + id + + + 12 + + + 2 + 3 + 606 + + + 4 + 5 + 17851 + + + 5 + 6 + 6533 + + + 6 + 7 + 859 + + + 7 + 8 + 4471 + + + 9 + 16 + 2719 + + + 16 + 578022 + 2083 + + + + + + + idx + name + + + 12 + + + 1 + 2 + 18457 + + + 2 + 3 + 6533 + + + 3 + 4 + 6178 + + + 4 + 8 + 2624 + + + 8 + 4397 + 1330 + + + + + + + idx + parentid + + + 12 + + + 2 + 3 + 606 + + + 4 + 5 + 17851 + + + 5 + 6 + 6533 + + + 6 + 7 + 859 + + + 7 + 8 + 4471 + + + 9 + 16 + 2719 + + + 16 + 578022 + 2083 + + + + + + + idx + fileid + + + 12 + + + 2 + 3 + 606 + + + 4 + 5 + 17851 + + + 5 + 6 + 6533 + + + 6 + 7 + 859 + + + 7 + 8 + 4471 + + + 9 + 16 + 2719 + + + 16 + 39722 + 2083 + + + + + + + fileid + id + + + 12 + + + 1 + 2 + 20457 + + + 2 + 3 + 3115 + + + 3 + 7 + 3026 + + + 7 + 8 + 3588 + + + 8 + 9 + 2220 + + + 9 + 11 + 3099 + + + 11 + 19 + 3087 + + + 19 + 114506 + 1129 + + + + + + + fileid + name + + + 12 + + + 1 + 2 + 20459 + + + 2 + 3 + 3458 + + + 3 + 5 + 2569 + + + 5 + 7 + 2172 + + + 7 + 8 + 6158 + + + 8 + 9 + 3501 + + + 9 + 46 + 1404 + + + + + + + fileid + parentid + + + 12 + + + 1 + 2 + 20457 + + + 2 + 3 + 3870 + + + 3 + 5 + 2152 + + + 5 + 6 + 2876 + + + 6 + 7 + 2720 + + + 7 + 8 + 4132 + + + 8 + 14 + 3096 + + + 14 + 31079 + 418 + + + + + + + fileid + idx + + + 12 + + + 1 + 2 + 25894 + + + 2 + 3 + 5301 + + + 3 + 4 + 3787 + + + 4 + 6 + 3268 + + + 6 + 35123 + 1471 + + + + + + + + + xmlAttrs + 1202020 + + + id + 1202020 + + + elementid + 760198 + + + name + 3649 + + + value + 121803 + + + idx + 2000 + + + fileid + 39448 + + + + + id + elementid + + + 12 + + + 1 + 2 + 1202020 + + + + + + + id + name + + + 12 + + + 1 + 2 + 1202020 + + + + + + + id + value + + + 12 + + + 1 + 2 + 1202020 + + + + + + + id + idx + + + 12 + + + 1 + 2 + 1202020 + + + + + + + id + fileid + + + 12 + + + 1 + 2 + 1202020 + + + + + + + elementid + id + + + 12 + + + 1 + 2 + 425697 + + + 2 + 3 + 249659 + + + 3 + 4 + 66474 + + + 4 + 2001 + 18368 + + + + + + + elementid + name + + + 12 + + + 1 + 2 + 425778 + + + 2 + 3 + 249579 + + + 3 + 4 + 66475 + + + 4 + 2001 + 18366 + + + + + + + elementid + value + + + 12 + + + 1 + 2 + 466237 + + + 2 + 3 + 266291 + + + 3 + 46 + 27670 + + + + + + + elementid + idx + + + 12 + + + 1 + 2 + 425697 + + + 2 + 3 + 249659 + + + 3 + 4 + 66474 + + + 4 + 2001 + 18368 + + + + + + + elementid + fileid + + + 12 + + + 1 + 2 + 760198 + + + + + + + name + id + + + 12 + + + 1 + 2 + 3467 + + + 2 + 262475 + 182 + + + + + + + name + elementid + + + 12 + + + 1 + 2 + 3467 + + + 2 + 262475 + 182 + + + + + + + name + value + + + 12 + + + 1 + 2 + 3501 + + + 2 + 54146 + 148 + + + + + + + name + idx + + + 12 + + + 1 + 2 + 3531 + + + 2 + 11 + 118 + + + + + + + name + fileid + + + 12 + + + 1 + 2 + 3491 + + + 2 + 21768 + 158 + + + + + + + value + id + + + 12 + + + 1 + 2 + 72032 + + + 2 + 3 + 42366 + + + 3 + 199269 + 7405 + + + + + + + value + elementid + + + 12 + + + 1 + 2 + 72036 + + + 2 + 3 + 42374 + + + 3 + 199269 + 7393 + + + + + + + value + name + + + 12 + + + 1 + 2 + 116722 + + + 2 + 2041 + 5081 + + + + + + + value + idx + + + 12 + + + 1 + 2 + 117957 + + + 2 + 2001 + 3846 + + + + + + + value + fileid + + + 12 + + + 1 + 2 + 86306 + + + 2 + 3 + 28570 + + + 3 + 4175 + 6927 + + + + + + + idx + id + + + 12 + + + 1 + 2 + 1955 + + + 2 + 760199 + 45 + + + + + + + idx + elementid + + + 12 + + + 1 + 2 + 1955 + + + 2 + 760199 + 45 + + + + + + + idx + name + + + 12 + + + 1 + 2 + 1955 + + + 2 + 189 + 45 + + + + + + + idx + value + + + 12 + + + 1 + 2 + 1955 + + + 2 + 116643 + 45 + + + + + + + idx + fileid + + + 12 + + + 1 + 2 + 1955 + + + 2 + 39449 + 45 + + + + + + + fileid + id + + + 12 + + + 1 + 2 + 22884 + + + 2 + 4 + 2565 + + + 4 + 6 + 2294 + + + 6 + 7 + 3299 + + + 7 + 9 + 3272 + + + 9 + 16 + 3143 + + + 16 + 129952 + 1991 + + + + + + + fileid + elementid + + + 12 + + + 1 + 2 + 23890 + + + 2 + 4 + 2131 + + + 4 + 5 + 1971 + + + 5 + 6 + 4096 + + + 6 + 8 + 3519 + + + 8 + 16 + 3137 + + + 16 + 106600 + 704 + + + + + + + fileid + name + + + 12 + + + 1 + 2 + 22946 + + + 2 + 3 + 2338 + + + 3 + 4 + 2726 + + + 4 + 5 + 2824 + + + 5 + 6 + 2994 + + + 6 + 7 + 3876 + + + 7 + 2002 + 1744 + + + + + + + fileid + value + + + 12 + + + 1 + 2 + 22916 + + + 2 + 4 + 2772 + + + 4 + 5 + 2112 + + + 5 + 6 + 3510 + + + 6 + 8 + 1993 + + + 8 + 11 + 3365 + + + 11 + 50357 + 2780 + + + + + + + fileid + idx + + + 12 + + + 1 + 2 + 26133 + + + 2 + 3 + 9699 + + + 3 + 5 + 3511 + + + 5 + 2001 + 105 + + + + + + + + + xmlNs + 71201 + + + id + 4185 + + + prefixName + 958 + + + URI + 4185 + + + fileid + 39544 + + + + + id + prefixName + + + 12 + + + 1 + 2 + 2602 + + + 2 + 3 + 1553 + + + 3 + 872 + 30 + + + + + + + id + URI + + + 12 + + + 1 + 2 + 4185 + + + + + + + id + fileid + + + 12 + + + 1 + 6 + 274 + + + 6 + 7 + 3825 + + + 7 + 24905 + 86 + + + + + + + prefixName + id + + + 12 + + + 1 + 2 + 915 + + + 2 + 4054 + 43 + + + + + + + prefixName + URI + + + 12 + + + 1 + 2 + 915 + + + 2 + 4054 + 43 + + + + + + + prefixName + fileid + + + 12 + + + 1 + 2 + 828 + + + 2 + 5 + 73 + + + 5 + 24903 + 57 + + + + + + + URI + id + + + 12 + + + 1 + 2 + 4185 + + + + + + + URI + prefixName + + + 12 + + + 1 + 2 + 2602 + + + 2 + 3 + 1553 + + + 3 + 872 + 30 + + + + + + + URI + fileid + + + 12 + + + 1 + 6 + 274 + + + 6 + 7 + 3825 + + + 7 + 24905 + 86 + + + + + + + fileid + id + + + 12 + + + 1 + 2 + 11655 + + + 2 + 3 + 26146 + + + 3 + 8 + 1743 + + + + + + + fileid + prefixName + + + 12 + + + 1 + 2 + 11653 + + + 2 + 3 + 25982 + + + 3 + 31 + 1909 + + + + + + + fileid + URI + + + 12 + + + 1 + 2 + 11655 + + + 2 + 3 + 26146 + + + 3 + 8 + 1743 + + + + + + + + + xmlHasNs + 1139730 + + + elementId + 1139730 + + + nsId + 4136 + + + fileid + 39537 + + + + + elementId + nsId + + + 12 + + + 1 + 2 + 1139730 + + + + + + + elementId + fileid + + + 12 + + + 1 + 2 + 1139730 + + + + + + + nsId + elementId + + + 12 + + + 1 + 5 + 234 + + + 5 + 6 + 3824 + + + 6 + 643289 + 78 + + + + + + + nsId + fileid + + + 12 + + + 1 + 5 + 257 + + + 5 + 6 + 3823 + + + 6 + 24759 + 56 + + + + + + + fileid + elementId + + + 12 + + + 1 + 2 + 3669 + + + 2 + 3 + 20429 + + + 3 + 7 + 2536 + + + 7 + 8 + 3473 + + + 8 + 9 + 2258 + + + 9 + 11 + 3036 + + + 11 + 18 + 2966 + + + 18 + 147552 + 1170 + + + + + + + fileid + nsId + + + 12 + + + 1 + 2 + 18261 + + + 2 + 3 + 21032 + + + 3 + 8 + 244 + + + + + + + + + xmlComments + 26812 + + + id + 26812 + + + text + 22933 + + + parentid + 26546 + + + fileid + 26368 + + + + + id + text + + + 12 + + + 1 + 2 + 26812 + + + + + + + id + parentid + + + 12 + + + 1 + 2 + 26812 + + + + + + + id + fileid + + + 12 + + + 1 + 2 + 26812 + + + + + + + text + id + + + 12 + + + 1 + 2 + 21517 + + + 2 + 62 + 1416 + + + + + + + text + parentid + + + 12 + + + 1 + 2 + 21519 + + + 2 + 62 + 1414 + + + + + + + text + fileid + + + 12 + + + 1 + 2 + 21522 + + + 2 + 62 + 1411 + + + + + + + parentid + id + + + 12 + + + 1 + 2 + 26379 + + + 2 + 17 + 167 + + + + + + + parentid + text + + + 12 + + + 1 + 2 + 26379 + + + 2 + 17 + 167 + + + + + + + parentid + fileid + + + 12 + + + 1 + 2 + 26546 + + + + + + + fileid + id + + + 12 + + + 1 + 2 + 26161 + + + 2 + 17 + 207 + + + + + + + fileid + text + + + 12 + + + 1 + 2 + 26165 + + + 2 + 17 + 203 + + + + + + + fileid + parentid + + + 12 + + + 1 + 2 + 26223 + + + 2 + 10 + 145 + + + + + + + + + xmlChars + 439958 + + + id + 439958 + + + text + 100518 + + + parentid + 433851 + + + idx + 4 + + + isCDATA + 1 + + + fileid + 26494 + + + + + id + text + + + 12 + + + 1 + 2 + 439958 + + + + + + + id + parentid + + + 12 + + + 1 + 2 + 439958 + + + + + + + id + idx + + + 12 + + + 1 + 2 + 439958 + + + + + + + id + isCDATA + + + 12 + + + 1 + 2 + 439958 + + + + + + + id + fileid + + + 12 + + + 1 + 2 + 439958 + + + + + + + text + id + + + 12 + + + 1 + 2 + 60389 + + + 2 + 4 + 3811 + + + 4 + 5 + 29257 + + + 5 + 23171 + 7061 + + + + + + + text + parentid + + + 12 + + + 1 + 2 + 60389 + + + 2 + 4 + 3811 + + + 4 + 5 + 29257 + + + 5 + 23171 + 7061 + + + + + + + text + idx + + + 12 + + + 1 + 2 + 100517 + + + 2 + 3 + 1 + + + + + + + text + isCDATA + + + 12 + + + 1 + 2 + 100518 + + + + + + + text + fileid + + + 12 + + + 1 + 2 + 61284 + + + 2 + 4 + 4205 + + + 4 + 5 + 28328 + + + 5 + 351 + 6701 + + + + + + + parentid + id + + + 12 + + + 1 + 2 + 429716 + + + 2 + 5 + 4135 + + + + + + + parentid + text + + + 12 + + + 1 + 2 + 429716 + + + 2 + 5 + 4135 + + + + + + + parentid + idx + + + 12 + + + 1 + 2 + 429716 + + + 2 + 5 + 4135 + + + + + + + parentid + isCDATA + + + 12 + + + 1 + 2 + 433851 + + + + + + + parentid + fileid + + + 12 + + + 1 + 2 + 433851 + + + + + + + idx + id + + + 12 + + + 80 + 81 + 1 + + + 1892 + 1893 + 1 + + + 4135 + 4136 + 1 + + + 433851 + 433852 + 1 + + + + + + + idx + text + + + 12 + + + 1 + 2 + 1 + + + 3 + 4 + 1 + + + 16 + 17 + 1 + + + 100499 + 100500 + 1 + + + + + + + idx + parentid + + + 12 + + + 80 + 81 + 1 + + + 1892 + 1893 + 1 + + + 4135 + 4136 + 1 + + + 433851 + 433852 + 1 + + + + + + + idx + isCDATA + + + 12 + + + 1 + 2 + 4 + + + + + + + idx + fileid + + + 12 + + + 4 + 5 + 1 + + + 46 + 47 + 1 + + + 97 + 98 + 1 + + + 26494 + 26495 + 1 + + + + + + + isCDATA + id + + + 12 + + + 439958 + 439959 + 1 + + + + + + + isCDATA + text + + + 12 + + + 100518 + 100519 + 1 + + + + + + + isCDATA + parentid + + + 12 + + + 433851 + 433852 + 1 + + + + + + + isCDATA + idx + + + 12 + + + 4 + 5 + 1 + + + + + + + isCDATA + fileid + + + 12 + + + 26494 + 26495 + 1 + + + + + + + fileid + id + + + 12 + + + 1 + 2 + 25303 + + + 2 + 35123 + 1191 + + + + + + + fileid + text + + + 12 + + + 1 + 2 + 25765 + + + 2 + 35123 + 729 + + + + + + + fileid + parentid + + + 12 + + + 1 + 2 + 25312 + + + 2 + 35123 + 1182 + + + + + + + fileid + idx + + + 12 + + + 1 + 2 + 26397 + + + 2 + 5 + 97 + + + + + + + fileid + isCDATA + + + 12 + + + 1 + 2 + 26494 + + + + + + + + + xmllocations + 3051056 + + + xmlElement + 2982460 + + + location + 3051056 + + + + + xmlElement + location + + + 12 + + + 1 + 2 + 2978326 + + + 2 + 24903 + 4134 + + + + + + + location + xmlElement + + + 12 + + + 1 + 2 + 3051056 + + + + + + + + diff --git a/cpp/ql/lib/upgrades/bb0f279f2acd793105a347d589b5afc8715d94c4/old.dbscheme b/cpp/ql/lib/upgrades/bb0f279f2acd793105a347d589b5afc8715d94c4/old.dbscheme new file mode 100644 index 00000000000..bb0f279f2ac --- /dev/null +++ b/cpp/ql/lib/upgrades/bb0f279f2acd793105a347d589b5afc8715d94c4/old.dbscheme @@ -0,0 +1,2096 @@ + +/** + * 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 @macroinvocations.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 + | 2 = constructor + | 3 = destructor + | 4 = conversion + | 5 = operator + | 6 = builtin // 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 +); + +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 = error + | 2 = unknown + | 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 = __int8 // Microsoft-specific + | 21 = __int16 // Microsoft-specific + | 22 = __int32 // Microsoft-specific + | 23 = __int64 // Microsoft-specific + | 24 = float + | 25 = double + | 26 = long_double + | 27 = _Complex_float // C99-specific + | 28 = _Complex_double // C99-specific + | 29 = _Complex_long double // C99-specific + | 30 = _Imaginary_float // C99-specific + | 31 = _Imaginary_double // C99-specific + | 32 = _Imaginary_long_double // C99-specific + | 33 = wchar_t // Microsoft-specific + | 34 = decltype_nullptr // C++11 + | 35 = __int128 + | 36 = unsigned___int128 + | 37 = signed___int128 + | 38 = __float128 + | 39 = _Complex___float128 + | 40 = _Decimal32 + | 41 = _Decimal64 + | 42 = _Decimal128 + | 43 = char16_t + | 44 = char32_t + | 45 = _Float32 + | 46 = _Float32x + | 47 = _Float64 + | 48 = _Float64x + | 49 = _Float128 + | 50 = _Float128x + | 51 = char8_t + ; +*/ +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, + unique 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 EDG frontend. See symbol_ref.h there. + 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 +; + +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_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 + +/* + 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 +); + +/** + * 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 // EDG 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 +; + +@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 + ; + +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_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_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 +); + +#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/bb0f279f2acd793105a347d589b5afc8715d94c4/semmlecode.cpp.dbscheme b/cpp/ql/lib/upgrades/bb0f279f2acd793105a347d589b5afc8715d94c4/semmlecode.cpp.dbscheme new file mode 100644 index 00000000000..e9a518baf14 --- /dev/null +++ b/cpp/ql/lib/upgrades/bb0f279f2acd793105a347d589b5afc8715d94c4/semmlecode.cpp.dbscheme @@ -0,0 +1,2096 @@ + +/** + * 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 @macroinvocations.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 + | 2 = constructor + | 3 = destructor + | 4 = conversion + | 5 = operator + | 6 = builtin // 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 +); + +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 = error + | 2 = unknown + | 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 = __int8 // Microsoft-specific + | 21 = __int16 // Microsoft-specific + | 22 = __int32 // Microsoft-specific + | 23 = __int64 // Microsoft-specific + | 24 = float + | 25 = double + | 26 = long_double + | 27 = _Complex_float // C99-specific + | 28 = _Complex_double // C99-specific + | 29 = _Complex_long double // C99-specific + | 30 = _Imaginary_float // C99-specific + | 31 = _Imaginary_double // C99-specific + | 32 = _Imaginary_long_double // C99-specific + | 33 = wchar_t // Microsoft-specific + | 34 = decltype_nullptr // C++11 + | 35 = __int128 + | 36 = unsigned___int128 + | 37 = signed___int128 + | 38 = __float128 + | 39 = _Complex___float128 + | 40 = _Decimal32 + | 41 = _Decimal64 + | 42 = _Decimal128 + | 43 = char16_t + | 44 = char32_t + | 45 = _Float32 + | 46 = _Float32x + | 47 = _Float64 + | 48 = _Float64x + | 49 = _Float128 + | 50 = _Float128x + | 51 = char8_t + ; +*/ +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 EDG frontend. See symbol_ref.h there. + 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 +; + +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_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 + +/* + 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 +); + +/** + * 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 // EDG 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 +; + +@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 + ; + +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_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_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 +); + +#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/bb0f279f2acd793105a347d589b5afc8715d94c4/upgrade.properties b/cpp/ql/lib/upgrades/bb0f279f2acd793105a347d589b5afc8715d94c4/upgrade.properties new file mode 100644 index 00000000000..000fa581cfa --- /dev/null +++ b/cpp/ql/lib/upgrades/bb0f279f2acd793105a347d589b5afc8715d94c4/upgrade.properties @@ -0,0 +1,2 @@ +description: Remove uniqueness constraint from the uuid property +compatibility: full diff --git a/cpp/ql/src/CHANGELOG.md b/cpp/ql/src/CHANGELOG.md index 283c0a92996..2125fbac519 100644 --- a/cpp/ql/src/CHANGELOG.md +++ b/cpp/ql/src/CHANGELOG.md @@ -1,3 +1,24 @@ +## 0.0.11 + +### Breaking Changes + +* The deprecated queries `cpp/duplicate-block`, `cpp/duplicate-function`, `cpp/duplicate-class`, `cpp/duplicate-file`, `cpp/mostly-duplicate-function`,`cpp/similar-file`, `cpp/duplicated-lines-in-files` have been removed. + +### Deprecated Predicates and Classes + +* The predicates and classes in the `CodeDuplication` library have been deprecated. + +### New Queries + +* A new query titled "Use of expired stack-address" (`cpp/using-expired-stack-address`) has been added. + This query finds accesses to expired stack-allocated memory that escaped via a global variable. +* A new `cpp/insufficient-key-size` query has been added to the default query suite for C/C++. The query finds uses of certain cryptographic algorithms where the key size is too small to provide adequate encryption strength. + +### Minor Analysis Improvements + +* The "Failure to use HTTPS URLs" (`cpp/non-https-url`) has been improved reducing false positive results, and its precision has been increased to 'high'. +* The `cpp/system-data-exposure` query has been modernized and has converted to a `path-problem` query. There are now fewer false positive results. + ## 0.0.10 ### Deprecated Classes diff --git a/cpp/ql/src/Critical/OverflowDestination.ql b/cpp/ql/src/Critical/OverflowDestination.ql index 94d46001660..6d41281e443 100644 --- a/cpp/ql/src/Critical/OverflowDestination.ql +++ b/cpp/ql/src/Critical/OverflowDestination.ql @@ -2,7 +2,7 @@ * @name Copy function using source size * @description Calling a copy operation with a size derived from the source * buffer instead of the destination buffer may result in a buffer overflow. - * @kind problem + * @kind path-problem * @id cpp/overflow-destination * @problem.severity warning * @security-severity 9.3 @@ -14,7 +14,10 @@ */ import cpp -import semmle.code.cpp.security.TaintTracking +import semmle.code.cpp.ir.dataflow.TaintTracking +import semmle.code.cpp.controlflow.IRGuards +import semmle.code.cpp.security.FlowSources +import DataFlow::PathGraph /** * Holds if `fc` is a call to a copy operation where the size argument contains @@ -27,9 +30,9 @@ predicate sourceSized(FunctionCall fc, Expr src) { fc.getTarget().hasGlobalOrStdName(["strncpy", "strncat", "memcpy", "memmove"]) and exists(Expr dest, Expr size, Variable v | fc.getArgument(0) = dest and - fc.getArgument(1) = src and + fc.getArgument(1).getFullyConverted() = src and fc.getArgument(2) = size and - src = v.getAnAccess() and + src = v.getAnAccess().getFullyConverted() and size.getAChild+() = v.getAnAccess() and // exception: `dest` is also referenced in the size argument not exists(Variable other | @@ -45,9 +48,49 @@ predicate sourceSized(FunctionCall fc, Expr src) { ) } -from FunctionCall fc, Expr vuln, Expr taintSource +predicate readsVariable(LoadInstruction load, Variable var) { + load.getSourceAddress().(VariableAddressInstruction).getAstVariable() = var +} + +predicate hasUpperBoundsCheck(Variable var) { + exists(RelationalOperation oper, VariableAccess access | + oper.getAnOperand() = access and + access.getTarget() = var and + // Comparing to 0 is not an upper bound check + not oper.getAnOperand().getValue() = "0" + ) +} + +predicate nodeIsBarrierEqualityCandidate(DataFlow::Node node, Operand access, Variable checkedVar) { + readsVariable(node.asInstruction(), checkedVar) and + any(IRGuardCondition guard).ensuresEq(access, _, _, node.asInstruction().getBlock(), true) +} + +class OverflowDestinationConfig extends TaintTracking::Configuration { + OverflowDestinationConfig() { this = "OverflowDestinationConfig" } + + override predicate isSource(DataFlow::Node source) { source instanceof FlowSource } + + override predicate isSink(DataFlow::Node sink) { sourceSized(_, sink.asConvertedExpr()) } + + override predicate isSanitizer(DataFlow::Node node) { + exists(Variable checkedVar | + readsVariable(node.asInstruction(), checkedVar) and + hasUpperBoundsCheck(checkedVar) + ) + or + exists(Variable checkedVar, Operand access | + readsVariable(access.getDef(), checkedVar) and + nodeIsBarrierEqualityCandidate(node, access, checkedVar) + ) + } +} + +from + FunctionCall fc, OverflowDestinationConfig conf, DataFlow::PathNode source, + DataFlow::PathNode sink where - sourceSized(fc, vuln) and - tainted(taintSource, vuln) -select fc, + conf.hasFlowPath(source, sink) and + sourceSized(fc, sink.getNode().asConvertedExpr()) +select fc, source, sink, "To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size." diff --git a/cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql b/cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql index c75fb8b639d..dc5a0848296 100644 --- a/cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql +++ b/cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql @@ -18,157 +18,72 @@ import cpp // recomputing the IR. private import semmle.code.cpp.valuenumbering.GlobalValueNumbering import semmle.code.cpp.ir.IR -import semmle.code.cpp.ir.dataflow.DataFlow::DataFlow +import semmle.code.cpp.ir.dataflow.MustFlow +import PathGraph /** Holds if `f` has a name that we intrepret as evidence of intentionally returning the value of the stack pointer. */ predicate intentionallyReturnsStackPointer(Function f) { f.getName().toLowerCase().matches(["%stack%", "%sp%"]) } -/** - * Holds if `source` is a node that represents the use of a stack variable - */ -predicate isSource(Node source) { - exists(VariableAddressInstruction var, Function func | - var = source.asInstruction() and - func = var.getEnclosingFunction() and - var.getASTVariable() instanceof StackVariable and - // Pointer-to-member types aren't properly handled in the dbscheme. - not var.getResultType() instanceof PointerToMemberType and - // Rule out FPs caused by extraction errors. - not any(ErrorExpr e).getEnclosingFunction() = func and - not intentionallyReturnsStackPointer(func) - ) -} +class ReturnStackAllocatedMemoryConfig extends MustFlowConfiguration { + ReturnStackAllocatedMemoryConfig() { this = "ReturnStackAllocatedMemoryConfig" } -/** - * Holds if `sink` is a node that represents the `StoreInstruction` that is subsequently used in - * a `ReturnValueInstruction`. We use the `StoreInstruction` instead of the instruction that defines the - * `ReturnValueInstruction`'s source value oprand because the former has better location information. - */ -predicate isSink(Node sink) { - exists(StoreInstruction store | - store.getDestinationAddress().(VariableAddressInstruction).getIRVariable() instanceof - IRReturnVariable and - sink.asOperand() = store.getSourceValueOperand() - ) -} - -/** Holds if `node1` _must_ flow to `node2`. */ -predicate step(Node node1, Node node2) { - instructionToOperandStep(node1.asInstruction(), node2.asOperand()) - or - operandToInstructionStep(node1.asOperand(), node2.asInstruction()) -} - -predicate instructionToOperandStep(Instruction instr, Operand operand) { operand.getDef() = instr } - -/** - * Holds if `operand` flows to the result of `instr`. - * - * This predicate ignores flow through `PhiInstruction`s to create a 'must flow' relation. It also - * intentionally conflates addresses of fields and their object, and pointer offsets with their - * base pointer as this allows us to detect cases where an object's address flows to a return statement - * via a field. For example: - * - * ```cpp - * struct S { int x, y }; - * int* test() { - * S s; - * return &s.x; // BAD: &s.x is an address of a variable on the stack. - * } - * ``` - */ -predicate operandToInstructionStep(Operand operand, Instruction instr) { - instr.(CopyInstruction).getSourceValueOperand() = operand - or - instr.(ConvertInstruction).getUnaryOperand() = operand - or - instr.(CheckedConvertOrNullInstruction).getUnaryOperand() = operand - or - instr.(InheritanceConversionInstruction).getUnaryOperand() = operand - or - instr.(FieldAddressInstruction).getObjectAddressOperand() = operand - or - instr.(PointerOffsetInstruction).getLeftOperand() = operand -} - -/** Holds if a source node flows to `n`. */ -predicate branchlessLocalFlow0(Node n) { - isSource(n) - or - exists(Node mid | - branchlessLocalFlow0(mid) and - step(mid, n) - ) -} - -/** Holds if `n` is reachable through some source node, and `n` also eventually reaches a sink. */ -predicate branchlessLocalFlow1(Node n) { - branchlessLocalFlow0(n) and - ( - isSink(n) - or - exists(Node mid | - branchlessLocalFlow1(mid) and - step(n, mid) - ) - ) -} - -newtype TLocalPathNode = - TLocalPathNodeMid(Node n) { - branchlessLocalFlow1(n) and - ( - isSource(n) or - exists(LocalPathNodeMid mid | step(mid.getNode(), n)) + override predicate isSource(DataFlow::Node source) { + // Holds if `source` is a node that represents the use of a stack variable + exists(VariableAddressInstruction var, Function func | + var = source.asInstruction() and + func = var.getEnclosingFunction() and + var.getAstVariable() instanceof StackVariable and + // Pointer-to-member types aren't properly handled in the dbscheme. + not var.getResultType() instanceof PointerToMemberType and + // Rule out FPs caused by extraction errors. + not any(ErrorExpr e).getEnclosingFunction() = func and + not intentionallyReturnsStackPointer(func) ) } -abstract class LocalPathNode extends TLocalPathNode { - Node n; + override predicate isSink(DataFlow::Node sink) { + // Holds if `sink` is a node that represents the `StoreInstruction` that is subsequently used in + // a `ReturnValueInstruction`. + // We use the `StoreInstruction` instead of the instruction that defines the + // `ReturnValueInstruction`'s source value oprand because the former has better location information. + exists(StoreInstruction store | + store.getDestinationAddress().(VariableAddressInstruction).getIRVariable() instanceof + IRReturnVariable and + sink.asOperand() = store.getSourceValueOperand() + ) + } - /** Gets the underlying node. */ - Node getNode() { result = n } - - /** Gets a textual representation of this node. */ - string toString() { result = n.toString() } - - /** Gets the location of this element. */ - Location getLocation() { result = n.getLocation() } - - /** Gets a successor `LocalPathNode`, if any. */ - LocalPathNode getASuccessor() { step(this.getNode(), result.getNode()) } + /** + * This configuration intentionally conflates addresses of fields and their object, and pointer offsets + * with their base pointer as this allows us to detect cases where an object's address flows to a + * return statement via a field. For example: + * + * ```cpp + * struct S { int x, y }; + * int* test() { + * S s; + * return &s.x; // BAD: &s.x is an address of a variable on the stack. + * } + * ``` + */ + override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + node2.asInstruction().(FieldAddressInstruction).getObjectAddressOperand() = node1.asOperand() + or + node2.asInstruction().(PointerOffsetInstruction).getLeftOperand() = node1.asOperand() + } } -class LocalPathNodeMid extends LocalPathNode, TLocalPathNodeMid { - LocalPathNodeMid() { this = TLocalPathNodeMid(n) } -} - -class LocalPathNodeSink extends LocalPathNodeMid { - LocalPathNodeSink() { isSink(this.getNode()) } -} - -/** - * Holds if `source` is a source node, `sink` is a sink node, and there's flow - * from `source` to `sink` using `step` relation. - */ -predicate hasFlow(LocalPathNode source, LocalPathNodeSink sink) { - isSource(source.getNode()) and - source.getASuccessor+() = sink -} - -predicate reach(LocalPathNode n) { n instanceof LocalPathNodeSink or reach(n.getASuccessor()) } - -query predicate edges(LocalPathNode a, LocalPathNode b) { a.getASuccessor() = b and reach(b) } - -query predicate nodes(LocalPathNode n, string key, string val) { - reach(n) and key = "semmle.label" and val = n.toString() -} - -from LocalPathNode source, LocalPathNodeSink sink, VariableAddressInstruction var +from + MustFlowPathNode source, MustFlowPathNode sink, VariableAddressInstruction var, + ReturnStackAllocatedMemoryConfig conf, Function f where - hasFlow(source, sink) and - source.getNode().asInstruction() = var -select sink.getNode(), source, sink, "May return stack-allocated memory from $@.", var.getAST(), - var.getAST().toString() + conf.hasFlowPath(source, sink) and + source.getNode().asInstruction() = var and + // Only raise an alert if we're returning from the _same_ callable as the on that + // declared the stack variable. + var.getEnclosingFunction() = pragma[only_bind_into](f) and + sink.getNode().getEnclosingCallable() = pragma[only_bind_into](f) +select sink.getNode(), source, sink, "May return stack-allocated memory from $@.", var.getAst(), + var.getAst().toString() diff --git a/cpp/ql/src/Likely Bugs/Memory Management/UsingExpiredStackAddress.ql b/cpp/ql/src/Likely Bugs/Memory Management/UsingExpiredStackAddress.ql index af847701f85..27aeabbaf49 100644 --- a/cpp/ql/src/Likely Bugs/Memory Management/UsingExpiredStackAddress.ql +++ b/cpp/ql/src/Likely Bugs/Memory Management/UsingExpiredStackAddress.ql @@ -19,7 +19,7 @@ import semmle.code.cpp.valuenumbering.GlobalValueNumbering import semmle.code.cpp.ir.IR predicate instructionHasVariable(VariableAddressInstruction vai, StackVariable var, Function f) { - var = vai.getASTVariable() and + var = vai.getAstVariable() and f = vai.getEnclosingFunction() and // Pointer-to-member types aren't properly handled in the dbscheme. not vai.getResultType() instanceof PointerToMemberType and @@ -108,7 +108,7 @@ predicate inheritanceConversionTypes( /** Gets the HashCons value of an address computed by `instr`, if any. */ TGlobalAddress globalAddress(Instruction instr) { - result = TGlobalVariable(instr.(VariableAddressInstruction).getASTVariable()) + result = TGlobalVariable(instr.(VariableAddressInstruction).getAstVariable()) or not instr instanceof LoadInstruction and result = globalAddress(instr.(CopyInstruction).getSourceValue()) diff --git a/cpp/ql/src/Likely Bugs/OO/UnsafeUseOfThis.ql b/cpp/ql/src/Likely Bugs/OO/UnsafeUseOfThis.ql index 04325e8497e..32a97a4c8d3 100644 --- a/cpp/ql/src/Likely Bugs/OO/UnsafeUseOfThis.ql +++ b/cpp/ql/src/Likely Bugs/OO/UnsafeUseOfThis.ql @@ -17,169 +17,47 @@ import cpp // We don't actually use the global value numbering library in this query, but without it we end up // recomputing the IR. -private import semmle.code.cpp.valuenumbering.GlobalValueNumbering -private import semmle.code.cpp.ir.IR +import semmle.code.cpp.valuenumbering.GlobalValueNumbering +import semmle.code.cpp.ir.IR +import semmle.code.cpp.ir.dataflow.MustFlow +import PathGraph -bindingset[n, result] -int unbind(int n) { result >= n and result <= n } +class UnsafeUseOfThisConfig extends MustFlowConfiguration { + UnsafeUseOfThisConfig() { this = "UnsafeUseOfThisConfig" } -/** Holds if `p` is the `n`'th parameter of the non-virtual function `f`. */ -predicate parameterOf(Parameter p, Function f, int n) { - not f.isVirtual() and f.getParameter(n) = p -} + override predicate isSource(DataFlow::Node source) { isSource(source, _, _) } -/** - * Holds if `instr` is the `n`'th argument to a call to the non-virtual function `f`, and - * `init` is the corresponding initiazation instruction that receives the value of `instr` in `f`. - */ -predicate flowIntoParameter( - CallInstruction call, Instruction instr, Function f, int n, InitializeParameterInstruction init -) { - not f.isVirtual() and - call.getPositionalArgument(n) = instr and - f = call.getStaticCallTarget() and - getEnclosingNonVirtualFunctionInitializeParameter(init, f) and - init.getParameter().getIndex() = unbind(n) -} - -/** - * Holds if `instr` is an argument to a call to the function `f`, and `init` is the - * corresponding initialization instruction that receives the value of `instr` in `f`. - */ -pragma[noinline] -predicate getPositionalArgumentInitParam( - CallInstruction call, Instruction instr, InitializeParameterInstruction init, Function f -) { - exists(int n | - parameterOf(_, f, n) and - flowIntoParameter(call, instr, f, unbind(n), init) - ) -} - -/** - * Holds if `instr` is the qualifier to a call to the non-virtual function `f`, and - * `init` is the corresponding initiazation instruction that receives the value of - * `instr` in `f`. - */ -pragma[noinline] -predicate getThisArgumentInitParam( - CallInstruction call, Instruction instr, InitializeParameterInstruction init, Function f -) { - not f.isVirtual() and - call.getStaticCallTarget() = f and - getEnclosingNonVirtualFunctionInitializeParameter(init, f) and - call.getThisArgument() = instr and - init.getIRVariable() instanceof IRThisVariable + override predicate isSink(DataFlow::Node sink) { isSink(sink, _) } } /** Holds if `instr` is a `this` pointer used by the call instruction `call`. */ -predicate isSink(Instruction instr, CallInstruction call) { +predicate isSink(DataFlow::Node sink, CallInstruction call) { exists(PureVirtualFunction func | call.getStaticCallTarget() = func and - call.getThisArgument() = instr and + call.getThisArgument() = sink.asInstruction() and // Weed out implicit calls to destructors of a base class not func instanceof Destructor ) } /** Holds if `init` initializes the `this` pointer in class `c`. */ -predicate isSource(InitializeParameterInstruction init, string msg, Class c) { - ( - exists(Constructor func | - not func instanceof CopyConstructor and - not func instanceof MoveConstructor and - func = init.getEnclosingFunction() and - msg = "construction" - ) - or - init.getEnclosingFunction() instanceof Destructor and msg = "destruction" - ) and - init.getIRVariable() instanceof IRThisVariable and - init.getEnclosingFunction().getDeclaringType() = c -} - -/** - * Holds if `instr` flows to a sink (which is a use of the value of `instr` as a `this` pointer). - */ -predicate flowsToSink(Instruction instr, Instruction sink) { - flowsFromSource(instr) and - ( - isSink(instr, _) and instr = sink - or - exists(Instruction mid | - successor(instr, mid) and - flowsToSink(mid, sink) - ) +predicate isSource(DataFlow::Node source, string msg, Class c) { + exists(InitializeParameterInstruction init | init = source.asInstruction() | + ( + exists(Constructor func | + not func instanceof CopyConstructor and + not func instanceof MoveConstructor and + func = init.getEnclosingFunction() and + msg = "construction" + ) + or + init.getEnclosingFunction() instanceof Destructor and msg = "destruction" + ) and + init.getIRVariable() instanceof IRThisVariable and + init.getEnclosingFunction().getDeclaringType() = c ) } -/** Holds if `instr` flows from a source. */ -predicate flowsFromSource(Instruction instr) { - isSource(instr, _, _) - or - exists(Instruction mid | - successor(mid, instr) and - flowsFromSource(mid) - ) -} - -/** Holds if `f` is the enclosing non-virtual function of `init`. */ -predicate getEnclosingNonVirtualFunctionInitializeParameter( - InitializeParameterInstruction init, Function f -) { - not f.isVirtual() and - init.getEnclosingFunction() = f -} - -/** Holds if `f` is the enclosing non-virtual function of `init`. */ -predicate getEnclosingNonVirtualFunctionInitializeIndirection( - InitializeIndirectionInstruction init, Function f -) { - not f.isVirtual() and - init.getEnclosingFunction() = f -} - -/** - * Holds if `instr` is an argument (or argument indirection) to a call, and - * `succ` is the corresponding initialization instruction in the call target. - */ -predicate flowThroughCallable(Instruction instr, Instruction succ) { - // Flow from an argument to a parameter - exists(CallInstruction call, InitializeParameterInstruction init | init = succ | - getPositionalArgumentInitParam(call, instr, init, call.getStaticCallTarget()) - or - getThisArgumentInitParam(call, instr, init, call.getStaticCallTarget()) - ) - or - // Flow from argument indirection to parameter indirection - exists( - CallInstruction call, ReadSideEffectInstruction read, InitializeIndirectionInstruction init - | - init = succ and - read.getPrimaryInstruction() = call and - getEnclosingNonVirtualFunctionInitializeIndirection(init, call.getStaticCallTarget()) - | - exists(int n | - read.getSideEffectOperand().getAnyDef() = instr and - read.getIndex() = n and - init.getParameter().getIndex() = unbind(n) - ) - or - call.getThisArgument() = instr and - init.getIRVariable() instanceof IRThisVariable - ) -} - -/** Holds if `instr` flows to `succ`. */ -predicate successor(Instruction instr, Instruction succ) { - succ.(CopyInstruction).getSourceValue() = instr or - succ.(CheckedConvertOrNullInstruction).getUnary() = instr or - succ.(ChiInstruction).getTotal() = instr or - succ.(ConvertInstruction).getUnary() = instr or - succ.(InheritanceConversionInstruction).getUnary() = instr or - flowThroughCallable(instr, succ) -} - /** * Holds if: * - `source` is an initialization of a `this` pointer of type `sourceClass`, and @@ -188,22 +66,19 @@ predicate successor(Instruction instr, Instruction succ) { * - `msg` is a string describing whether `source` is from a constructor or destructor. */ predicate flows( - Instruction source, string msg, Class sourceClass, Instruction sink, CallInstruction call + MustFlowPathNode source, string msg, Class sourceClass, MustFlowPathNode sink, + CallInstruction call ) { - isSource(source, msg, sourceClass) and - flowsToSink(source, sink) and - isSink(sink, call) + exists(UnsafeUseOfThisConfig conf | + conf.hasFlowPath(source, sink) and + isSource(source.getNode(), msg, sourceClass) and + isSink(sink.getNode(), call) + ) } -query predicate edges(Instruction a, Instruction b) { successor(a, b) and flowsToSink(b, _) } - -query predicate nodes(Instruction n, string key, string val) { - flowsToSink(n, _) and - key = "semmle.label" and - val = n.toString() -} - -from Instruction source, Instruction sink, CallInstruction call, string msg, Class sourceClass +from + MustFlowPathNode source, MustFlowPathNode sink, CallInstruction call, string msg, + Class sourceClass where flows(source, msg, sourceClass, sink, call) and // Only raise an alert if there is no override of the pure virtual function in any base class. diff --git a/cpp/ql/src/Likely Bugs/RedundantNullCheckSimple.ql b/cpp/ql/src/Likely Bugs/RedundantNullCheckSimple.ql index 65ba665dff2..8d7a07f4335 100644 --- a/cpp/ql/src/Likely Bugs/RedundantNullCheckSimple.ql +++ b/cpp/ql/src/Likely Bugs/RedundantNullCheckSimple.ql @@ -52,7 +52,7 @@ predicate explicitNullTestOfInstruction(Instruction checked, Instruction bool) { pragma[noinline] predicate candidateResult(LoadInstruction checked, ValueNumber value, IRBlock dominator) { explicitNullTestOfInstruction(checked, _) and - not checked.getAST().isInMacroExpansion() and + not checked.getAst().isInMacroExpansion() and value.getAnInstruction() = checked and dominator.dominates(checked.getBlock()) } diff --git a/cpp/ql/src/Metrics/Files/FLinesOfDuplicatedCode.qhelp b/cpp/ql/src/Metrics/Files/FLinesOfDuplicatedCode.qhelp deleted file mode 100644 index 80dd9f98e63..00000000000 --- a/cpp/ql/src/Metrics/Files/FLinesOfDuplicatedCode.qhelp +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/cpp/ql/src/Metrics/Files/FLinesOfDuplicatedCode.ql b/cpp/ql/src/Metrics/Files/FLinesOfDuplicatedCode.ql deleted file mode 100644 index 8b46df05adc..00000000000 --- a/cpp/ql/src/Metrics/Files/FLinesOfDuplicatedCode.ql +++ /dev/null @@ -1,27 +0,0 @@ -/** - * @deprecated - * @name Duplicated lines in files - * @description The number of lines in a file, including code, comment - * and whitespace lines, which are duplicated in at least - * one other place. - * @kind treemap - * @treemap.warnOn highValues - * @metricType file - * @metricAggregate avg sum max - * @id cpp/duplicated-lines-in-files - * @tags testability - * modularity - */ - -import external.CodeDuplication - -from File f, int n -where - n = - count(int line | - exists(DuplicateBlock d | d.sourceFile() = f | - line in [d.sourceStartLine() .. d.sourceEndLine()] - ) and - not whitelistedLineForDuplication(f, line) - ) -select f, n order by n desc diff --git a/cpp/ql/src/Metrics/Files/FLinesOfDuplicatedCodeCommon.inc.qhelp b/cpp/ql/src/Metrics/Files/FLinesOfDuplicatedCodeCommon.inc.qhelp deleted file mode 100644 index 6fc36156c11..00000000000 --- a/cpp/ql/src/Metrics/Files/FLinesOfDuplicatedCodeCommon.inc.qhelp +++ /dev/null @@ -1,35 +0,0 @@ - - - - -

-This metric measures the number of lines in a file that are contained within a block that is duplicated elsewhere. These lines may include code, comments and whitespace, and the duplicate block may be in this file or in another file. -

- -

-A file that contains many lines that are duplicated within the code base is problematic -for a number of reasons. -

- - - - - - -

-Refactor files with lots of duplicated code to extract the common code into -a shared library or module. -

- -
- - - -
  • Wikipedia: Duplicate code.
  • -
  • M. Fowler, Refactoring. Addison-Wesley, 1999.
  • - - -
    - diff --git a/cpp/ql/src/Security/CWE/CWE-020/CountUntrustedDataToExternalAPI.ql b/cpp/ql/src/Security/CWE/CWE-020/CountUntrustedDataToExternalAPI.ql index 8c75e8da6e2..bebff32a5c1 100644 --- a/cpp/ql/src/Security/CWE/CWE-020/CountUntrustedDataToExternalAPI.ql +++ b/cpp/ql/src/Security/CWE/CWE-020/CountUntrustedDataToExternalAPI.ql @@ -11,7 +11,7 @@ import cpp import ExternalAPIs -from ExternalAPIUsedWithUntrustedData externalAPI -select externalAPI, count(externalAPI.getUntrustedDataNode()) as numberOfUses, - externalAPI.getNumberOfUntrustedSources() as numberOfUntrustedSources order by +from ExternalApiUsedWithUntrustedData externalApi +select externalApi, count(externalApi.getUntrustedDataNode()) as numberOfUses, + externalApi.getNumberOfUntrustedSources() as numberOfUntrustedSources order by numberOfUntrustedSources desc diff --git a/cpp/ql/src/Security/CWE/CWE-020/ExternalAPIs.qll b/cpp/ql/src/Security/CWE/CWE-020/ExternalAPIs.qll index 29d5b20cfc4..0636dcbe11b 100644 --- a/cpp/ql/src/Security/CWE/CWE-020/ExternalAPIs.qll +++ b/cpp/ql/src/Security/CWE/CWE-020/ExternalAPIs.qll @@ -9,28 +9,31 @@ private import semmle.code.cpp.models.interfaces.Taint import ExternalAPIsSpecific /** A node representing untrusted data being passed to an external API. */ -class UntrustedExternalAPIDataNode extends ExternalAPIDataNode { - UntrustedExternalAPIDataNode() { any(UntrustedDataToExternalAPIConfig c).hasFlow(_, this) } +class UntrustedExternalApiDataNode extends ExternalApiDataNode { + UntrustedExternalApiDataNode() { any(UntrustedDataToExternalApiConfig c).hasFlow(_, 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) + any(UntrustedDataToExternalApiConfig c).hasFlow(result, this) } } -private newtype TExternalAPI = - TExternalAPIParameter(Function f, int index) { - exists(UntrustedExternalAPIDataNode n | +/** DEPRECATED: Alias for UntrustedExternalApiDataNode */ +deprecated class UntrustedExternalAPIDataNode = UntrustedExternalApiDataNode; + +private newtype TExternalApi = + TExternalApiParameter(Function f, int index) { + exists(UntrustedExternalApiDataNode n | f = n.getExternalFunction() and index = n.getIndex() ) } /** An external API which is used with untrusted data. */ -class ExternalAPIUsedWithUntrustedData extends TExternalAPI { +class ExternalApiUsedWithUntrustedData extends TExternalApi { /** Gets a possibly untrusted use of this external API. */ - UntrustedExternalAPIDataNode getUntrustedDataNode() { - this = TExternalAPIParameter(result.getExternalFunction(), result.getIndex()) + UntrustedExternalApiDataNode getUntrustedDataNode() { + this = TExternalApiParameter(result.getExternalFunction(), result.getIndex()) } /** Gets the number of untrusted sources used with this external API. */ @@ -43,8 +46,11 @@ class ExternalAPIUsedWithUntrustedData extends TExternalAPI { exists(Function f, int index, string indexString | if index = -1 then indexString = "qualifier" else indexString = "param " + index | - this = TExternalAPIParameter(f, index) and + this = TExternalApiParameter(f, index) and result = f.toString() + " [" + indexString + "]" ) } } + +/** DEPRECATED: Alias for ExternalApiUsedWithUntrustedData */ +deprecated class ExternalAPIUsedWithUntrustedData = ExternalApiUsedWithUntrustedData; diff --git a/cpp/ql/src/Security/CWE/CWE-020/ExternalAPIsSpecific.qll b/cpp/ql/src/Security/CWE/CWE-020/ExternalAPIsSpecific.qll index 5e710c9548d..db236b510b9 100644 --- a/cpp/ql/src/Security/CWE/CWE-020/ExternalAPIsSpecific.qll +++ b/cpp/ql/src/Security/CWE/CWE-020/ExternalAPIsSpecific.qll @@ -8,11 +8,11 @@ import semmle.code.cpp.models.interfaces.DataFlow import SafeExternalAPIFunction /** A node representing untrusted data being passed to an external API. */ -class ExternalAPIDataNode extends DataFlow::Node { +class ExternalApiDataNode extends DataFlow::Node { Call call; int i; - ExternalAPIDataNode() { + ExternalApiDataNode() { // Argument to call to a function ( this.asExpr() = call.getArgument(i) @@ -27,7 +27,7 @@ class ExternalAPIDataNode extends DataFlow::Node { not f instanceof DataFlowFunction and not f instanceof TaintFunction and // Not a call to a known safe external API - not f instanceof SafeExternalAPIFunction + not f instanceof SafeExternalApiFunction ) } @@ -41,9 +41,12 @@ class ExternalAPIDataNode extends DataFlow::Node { string getFunctionDescription() { result = this.getExternalFunction().toString() } } -/** A configuration for tracking flow from `RemoteFlowSource`s to `ExternalAPIDataNode`s. */ -class UntrustedDataToExternalAPIConfig extends TaintTracking::Configuration { - UntrustedDataToExternalAPIConfig() { this = "UntrustedDataToExternalAPIConfig" } +/** DEPRECATED: Alias for ExternalApiDataNode */ +deprecated class ExternalAPIDataNode = ExternalApiDataNode; + +/** A configuration for tracking flow from `RemoteFlowSource`s to `ExternalApiDataNode`s. */ +class UntrustedDataToExternalApiConfig extends TaintTracking::Configuration { + UntrustedDataToExternalApiConfig() { this = "UntrustedDataToExternalAPIConfig" } override predicate isSource(DataFlow::Node source) { exists(RemoteFlowSourceFunction remoteFlow | @@ -52,5 +55,8 @@ class UntrustedDataToExternalAPIConfig extends TaintTracking::Configuration { ) } - override predicate isSink(DataFlow::Node sink) { sink instanceof ExternalAPIDataNode } + override predicate isSink(DataFlow::Node sink) { sink instanceof ExternalApiDataNode } } + +/** DEPRECATED: Alias for UntrustedDataToExternalApiConfig */ +deprecated class UntrustedDataToExternalAPIConfig = UntrustedDataToExternalApiConfig; diff --git a/cpp/ql/src/Security/CWE/CWE-020/IRCountUntrustedDataToExternalAPI.ql b/cpp/ql/src/Security/CWE/CWE-020/IRCountUntrustedDataToExternalAPI.ql index 4d0c2174809..69911c22c6a 100644 --- a/cpp/ql/src/Security/CWE/CWE-020/IRCountUntrustedDataToExternalAPI.ql +++ b/cpp/ql/src/Security/CWE/CWE-020/IRCountUntrustedDataToExternalAPI.ql @@ -11,7 +11,7 @@ import cpp import ir.ExternalAPIs -from ExternalAPIUsedWithUntrustedData externalAPI -select externalAPI, count(externalAPI.getUntrustedDataNode()) as numberOfUses, - externalAPI.getNumberOfUntrustedSources() as numberOfUntrustedSources order by +from ExternalApiUsedWithUntrustedData externalApi +select externalApi, count(externalApi.getUntrustedDataNode()) as numberOfUses, + externalApi.getNumberOfUntrustedSources() as numberOfUntrustedSources order by numberOfUntrustedSources desc diff --git a/cpp/ql/src/Security/CWE/CWE-020/IRUntrustedDataToExternalAPI.ql b/cpp/ql/src/Security/CWE/CWE-020/IRUntrustedDataToExternalAPI.ql index 47a0bf14b7f..4860fc5356f 100644 --- a/cpp/ql/src/Security/CWE/CWE-020/IRUntrustedDataToExternalAPI.ql +++ b/cpp/ql/src/Security/CWE/CWE-020/IRUntrustedDataToExternalAPI.ql @@ -15,8 +15,8 @@ import ir.ExternalAPIs import semmle.code.cpp.security.FlowSources import DataFlow::PathGraph -from UntrustedDataToExternalAPIConfig config, DataFlow::PathNode source, DataFlow::PathNode sink +from UntrustedDataToExternalApiConfig config, DataFlow::PathNode source, DataFlow::PathNode sink where config.hasFlowPath(source, sink) select sink, source, sink, - "Call to " + sink.getNode().(ExternalAPIDataNode).getExternalFunction().toString() + + "Call to " + sink.getNode().(ExternalApiDataNode).getExternalFunction().toString() + " with untrusted data from $@.", source, source.getNode().(RemoteFlowSource).getSourceType() diff --git a/cpp/ql/src/Security/CWE/CWE-020/SafeExternalAPIFunction.qll b/cpp/ql/src/Security/CWE/CWE-020/SafeExternalAPIFunction.qll index 5eb0b23d914..de59e82e552 100644 --- a/cpp/ql/src/Security/CWE/CWE-020/SafeExternalAPIFunction.qll +++ b/cpp/ql/src/Security/CWE/CWE-020/SafeExternalAPIFunction.qll @@ -8,11 +8,14 @@ private import semmle.code.cpp.models.interfaces.SideEffect /** * A `Function` that is considered a "safe" external API from a security perspective. */ -abstract class SafeExternalAPIFunction extends Function { } +abstract class SafeExternalApiFunction extends Function { } + +/** DEPRECATED: Alias for SafeExternalApiFunction */ +deprecated class SafeExternalAPIFunction = SafeExternalApiFunction; /** The default set of "safe" external APIs. */ -private class DefaultSafeExternalAPIFunction extends SafeExternalAPIFunction { - DefaultSafeExternalAPIFunction() { +private class DefaultSafeExternalApiFunction extends SafeExternalApiFunction { + DefaultSafeExternalApiFunction() { // If a function does not write to any of its arguments, we consider it safe to // pass untrusted data to it. This means that string functions such as `strcmp` // and `strlen`, as well as memory functions such as `memcmp`, are considered safe. diff --git a/cpp/ql/src/Security/CWE/CWE-020/UntrustedDataToExternalAPI.ql b/cpp/ql/src/Security/CWE/CWE-020/UntrustedDataToExternalAPI.ql index b85a5b26a7f..01067425190 100644 --- a/cpp/ql/src/Security/CWE/CWE-020/UntrustedDataToExternalAPI.ql +++ b/cpp/ql/src/Security/CWE/CWE-020/UntrustedDataToExternalAPI.ql @@ -14,8 +14,8 @@ import semmle.code.cpp.dataflow.TaintTracking import ExternalAPIs import DataFlow::PathGraph -from UntrustedDataToExternalAPIConfig config, DataFlow::PathNode source, DataFlow::PathNode sink +from UntrustedDataToExternalApiConfig config, DataFlow::PathNode source, DataFlow::PathNode sink where config.hasFlowPath(source, sink) select sink, source, sink, - "Call to " + sink.getNode().(ExternalAPIDataNode).getExternalFunction().toString() + + "Call to " + sink.getNode().(ExternalApiDataNode).getExternalFunction().toString() + " with untrusted data from $@.", source, source.toString() diff --git a/cpp/ql/src/Security/CWE/CWE-020/ir/ExternalAPIs.qll b/cpp/ql/src/Security/CWE/CWE-020/ir/ExternalAPIs.qll index 29d5b20cfc4..0636dcbe11b 100644 --- a/cpp/ql/src/Security/CWE/CWE-020/ir/ExternalAPIs.qll +++ b/cpp/ql/src/Security/CWE/CWE-020/ir/ExternalAPIs.qll @@ -9,28 +9,31 @@ private import semmle.code.cpp.models.interfaces.Taint import ExternalAPIsSpecific /** A node representing untrusted data being passed to an external API. */ -class UntrustedExternalAPIDataNode extends ExternalAPIDataNode { - UntrustedExternalAPIDataNode() { any(UntrustedDataToExternalAPIConfig c).hasFlow(_, this) } +class UntrustedExternalApiDataNode extends ExternalApiDataNode { + UntrustedExternalApiDataNode() { any(UntrustedDataToExternalApiConfig c).hasFlow(_, 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) + any(UntrustedDataToExternalApiConfig c).hasFlow(result, this) } } -private newtype TExternalAPI = - TExternalAPIParameter(Function f, int index) { - exists(UntrustedExternalAPIDataNode n | +/** DEPRECATED: Alias for UntrustedExternalApiDataNode */ +deprecated class UntrustedExternalAPIDataNode = UntrustedExternalApiDataNode; + +private newtype TExternalApi = + TExternalApiParameter(Function f, int index) { + exists(UntrustedExternalApiDataNode n | f = n.getExternalFunction() and index = n.getIndex() ) } /** An external API which is used with untrusted data. */ -class ExternalAPIUsedWithUntrustedData extends TExternalAPI { +class ExternalApiUsedWithUntrustedData extends TExternalApi { /** Gets a possibly untrusted use of this external API. */ - UntrustedExternalAPIDataNode getUntrustedDataNode() { - this = TExternalAPIParameter(result.getExternalFunction(), result.getIndex()) + UntrustedExternalApiDataNode getUntrustedDataNode() { + this = TExternalApiParameter(result.getExternalFunction(), result.getIndex()) } /** Gets the number of untrusted sources used with this external API. */ @@ -43,8 +46,11 @@ class ExternalAPIUsedWithUntrustedData extends TExternalAPI { exists(Function f, int index, string indexString | if index = -1 then indexString = "qualifier" else indexString = "param " + index | - this = TExternalAPIParameter(f, index) and + this = TExternalApiParameter(f, index) and result = f.toString() + " [" + indexString + "]" ) } } + +/** DEPRECATED: Alias for ExternalApiUsedWithUntrustedData */ +deprecated class ExternalAPIUsedWithUntrustedData = ExternalApiUsedWithUntrustedData; diff --git a/cpp/ql/src/Security/CWE/CWE-020/ir/ExternalAPIsSpecific.qll b/cpp/ql/src/Security/CWE/CWE-020/ir/ExternalAPIsSpecific.qll index 994e76d6ced..b0fa685d1a4 100644 --- a/cpp/ql/src/Security/CWE/CWE-020/ir/ExternalAPIsSpecific.qll +++ b/cpp/ql/src/Security/CWE/CWE-020/ir/ExternalAPIsSpecific.qll @@ -8,11 +8,11 @@ private import semmle.code.cpp.models.interfaces.DataFlow import SafeExternalAPIFunction /** A node representing untrusted data being passed to an external API. */ -class ExternalAPIDataNode extends DataFlow::Node { +class ExternalApiDataNode extends DataFlow::Node { Call call; int i; - ExternalAPIDataNode() { + ExternalApiDataNode() { // Argument to call to a function ( this.asExpr() = call.getArgument(i) @@ -27,7 +27,7 @@ class ExternalAPIDataNode extends DataFlow::Node { not f instanceof DataFlowFunction and not f instanceof TaintFunction and // Not a call to a known safe external API - not f instanceof SafeExternalAPIFunction + not f instanceof SafeExternalApiFunction ) } @@ -41,11 +41,17 @@ class ExternalAPIDataNode extends DataFlow::Node { string getFunctionDescription() { result = this.getExternalFunction().toString() } } -/** A configuration for tracking flow from `RemoteFlowSource`s to `ExternalAPIDataNode`s. */ -class UntrustedDataToExternalAPIConfig extends TaintTracking::Configuration { - UntrustedDataToExternalAPIConfig() { this = "UntrustedDataToExternalAPIConfigIR" } +/** DEPRECATED: Alias for ExternalApiDataNode */ +deprecated class ExternalAPIDataNode = ExternalApiDataNode; + +/** A configuration for tracking flow from `RemoteFlowSource`s to `ExternalApiDataNode`s. */ +class UntrustedDataToExternalApiConfig extends TaintTracking::Configuration { + UntrustedDataToExternalApiConfig() { this = "UntrustedDataToExternalAPIConfigIR" } override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } - override predicate isSink(DataFlow::Node sink) { sink instanceof ExternalAPIDataNode } + override predicate isSink(DataFlow::Node sink) { sink instanceof ExternalApiDataNode } } + +/** DEPRECATED: Alias for UntrustedDataToExternalApiConfig */ +deprecated class UntrustedDataToExternalAPIConfig = UntrustedDataToExternalApiConfig; diff --git a/cpp/ql/src/Security/CWE/CWE-020/ir/SafeExternalAPIFunction.qll b/cpp/ql/src/Security/CWE/CWE-020/ir/SafeExternalAPIFunction.qll index 5eb0b23d914..de59e82e552 100644 --- a/cpp/ql/src/Security/CWE/CWE-020/ir/SafeExternalAPIFunction.qll +++ b/cpp/ql/src/Security/CWE/CWE-020/ir/SafeExternalAPIFunction.qll @@ -8,11 +8,14 @@ private import semmle.code.cpp.models.interfaces.SideEffect /** * A `Function` that is considered a "safe" external API from a security perspective. */ -abstract class SafeExternalAPIFunction extends Function { } +abstract class SafeExternalApiFunction extends Function { } + +/** DEPRECATED: Alias for SafeExternalApiFunction */ +deprecated class SafeExternalAPIFunction = SafeExternalApiFunction; /** The default set of "safe" external APIs. */ -private class DefaultSafeExternalAPIFunction extends SafeExternalAPIFunction { - DefaultSafeExternalAPIFunction() { +private class DefaultSafeExternalApiFunction extends SafeExternalApiFunction { + DefaultSafeExternalApiFunction() { // If a function does not write to any of its arguments, we consider it safe to // pass untrusted data to it. This means that string functions such as `strcmp` // and `strlen`, as well as memory functions such as `memcmp`, are considered safe. diff --git a/cpp/ql/src/Security/CWE/CWE-089/SqlTainted.ql b/cpp/ql/src/Security/CWE/CWE-089/SqlTainted.ql index 92c8b9a2bd5..1f8a5023864 100644 --- a/cpp/ql/src/Security/CWE/CWE-089/SqlTainted.ql +++ b/cpp/ql/src/Security/CWE/CWE-089/SqlTainted.ql @@ -18,15 +18,15 @@ import semmle.code.cpp.security.FunctionWithWrappers import semmle.code.cpp.security.TaintTracking import TaintedWithPath -class SQLLikeFunction extends FunctionWithWrappers { - SQLLikeFunction() { sqlArgument(this.getName(), _) } +class SqlLikeFunction extends FunctionWithWrappers { + SqlLikeFunction() { sqlArgument(this.getName(), _) } override predicate interestingArg(int arg) { sqlArgument(this.getName(), arg) } } class Configuration extends TaintTrackingConfiguration { override predicate isSink(Element tainted) { - exists(SQLLikeFunction runSql | runSql.outermostWrapperFunctionCall(tainted, _)) + exists(SqlLikeFunction runSql | runSql.outermostWrapperFunctionCall(tainted, _)) } override predicate isBarrier(Expr e) { @@ -43,7 +43,7 @@ class Configuration extends TaintTrackingConfiguration { } from - SQLLikeFunction runSql, Expr taintedArg, Expr taintSource, PathNode sourceNode, PathNode sinkNode, + SqlLikeFunction runSql, Expr taintedArg, Expr taintSource, PathNode sourceNode, PathNode sinkNode, string taintCause, string callChain where runSql.outermostWrapperFunctionCall(taintedArg, callChain) and diff --git a/cpp/ql/src/Security/CWE/CWE-129/ImproperArrayIndexValidation.ql b/cpp/ql/src/Security/CWE/CWE-129/ImproperArrayIndexValidation.ql index 0621def4d98..f16bb1e25d9 100644 --- a/cpp/ql/src/Security/CWE/CWE-129/ImproperArrayIndexValidation.ql +++ b/cpp/ql/src/Security/CWE/CWE-129/ImproperArrayIndexValidation.ql @@ -3,18 +3,22 @@ * @description Accessing an array without first checking * that the index is within the bounds of the array can * cause undefined behavior and can also be a security risk. - * @kind problem + * @kind path-problem * @id cpp/unclear-array-index-validation * @problem.severity warning * @security-severity 8.8 + * @precision low * @tags security * external/cwe/cwe-129 */ import cpp -import semmle.code.cpp.controlflow.Guards -private import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils -import semmle.code.cpp.security.TaintTracking +import semmle.code.cpp.controlflow.IRGuards +import semmle.code.cpp.security.FlowSources +import semmle.code.cpp.ir.dataflow.TaintTracking +import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils +import DataFlow::PathGraph +import semmle.code.cpp.security.Security predicate hasUpperBound(VariableAccess offsetExpr) { exists(BasicBlock controlled, StackVariable offsetVar, SsaDefinition def | @@ -32,11 +36,92 @@ predicate linearBoundControls(BasicBlock controlled, SsaDefinition def, StackVar ) } -from Expr origin, ArrayExpr arrayExpr, VariableAccess offsetExpr +predicate readsVariable(LoadInstruction load, Variable var) { + load.getSourceAddress().(VariableAddressInstruction).getAstVariable() = var +} + +predicate hasUpperBoundsCheck(Variable var) { + exists(RelationalOperation oper, VariableAccess access | + oper.getAnOperand() = access and + access.getTarget() = var and + // Comparing to 0 is not an upper bound check + not oper.getAnOperand().getValue() = "0" + ) +} + +predicate nodeIsBarrierEqualityCandidate(DataFlow::Node node, Operand access, Variable checkedVar) { + readsVariable(node.asInstruction(), checkedVar) and + any(IRGuardCondition guard).ensuresEq(access, _, _, node.asInstruction().getBlock(), true) +} + +predicate isFlowSource(FlowSource source, string sourceType) { sourceType = source.getSourceType() } + +predicate predictableInstruction(Instruction instr) { + instr instanceof ConstantInstruction + or + instr instanceof StringConstantInstruction + or + // This could be a conversion on a string literal + predictableInstruction(instr.(UnaryInstruction).getUnary()) +} + +class ImproperArrayIndexValidationConfig extends TaintTracking::Configuration { + ImproperArrayIndexValidationConfig() { this = "ImproperArrayIndexValidationConfig" } + + override predicate isSource(DataFlow::Node source) { isFlowSource(source, _) } + + override predicate isSanitizer(DataFlow::Node node) { + hasUpperBound(node.asExpr()) + or + // These barriers are ported from `DefaultTaintTracking` because this query is quite noisy + // otherwise. + exists(Variable checkedVar | + readsVariable(node.asInstruction(), checkedVar) and + hasUpperBoundsCheck(checkedVar) + ) + or + exists(Variable checkedVar, Operand access | + readsVariable(access.getDef(), checkedVar) and + nodeIsBarrierEqualityCandidate(node, access, checkedVar) + ) + or + // Don't use dataflow into binary instructions if both operands are unpredictable + exists(BinaryInstruction iTo | + iTo = node.asInstruction() and + not predictableInstruction(iTo.getLeft()) and + not predictableInstruction(iTo.getRight()) and + // propagate taint from either the pointer or the offset, regardless of predictability + not iTo instanceof PointerArithmeticInstruction + ) + or + // don't use dataflow through calls to pure functions if two or more operands + // are unpredictable + exists(Instruction iFrom1, Instruction iFrom2, CallInstruction iTo | + iTo = node.asInstruction() and + isPureFunction(iTo.getStaticCallTarget().getName()) and + iFrom1 = iTo.getAnArgument() and + iFrom2 = iTo.getAnArgument() and + not predictableInstruction(iFrom1) and + not predictableInstruction(iFrom2) and + iFrom1 != iFrom2 + ) + } + + override predicate isSink(DataFlow::Node sink) { + exists(ArrayExpr arrayExpr, VariableAccess offsetExpr | + offsetExpr = arrayExpr.getArrayOffset() and + sink.asExpr() = offsetExpr and + not hasUpperBound(offsetExpr) + ) + } +} + +from + ImproperArrayIndexValidationConfig conf, DataFlow::PathNode source, DataFlow::PathNode sink, + string sourceType where - tainted(origin, offsetExpr) and - offsetExpr = arrayExpr.getArrayOffset() and - not hasUpperBound(offsetExpr) -select offsetExpr, + conf.hasFlowPath(source, sink) and + isFlowSource(source.getNode(), sourceType) +select sink.getNode(), source, sink, "$@ flows to here and is used in an array indexing expression, potentially causing an invalid access.", - origin, "User-provided value" + source.getNode(), sourceType diff --git a/cpp/ql/src/Security/CWE/CWE-190/TaintedAllocationSize.ql b/cpp/ql/src/Security/CWE/CWE-190/TaintedAllocationSize.ql index 585875798cc..49de733d381 100644 --- a/cpp/ql/src/Security/CWE/CWE-190/TaintedAllocationSize.ql +++ b/cpp/ql/src/Security/CWE/CWE-190/TaintedAllocationSize.ql @@ -15,55 +15,89 @@ import cpp import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis -import semmle.code.cpp.security.TaintTracking -import TaintedWithPath +import semmle.code.cpp.ir.dataflow.TaintTracking +import semmle.code.cpp.ir.IR +import semmle.code.cpp.controlflow.IRGuards +import semmle.code.cpp.security.FlowSources +import DataFlow::PathGraph /** * Holds if `alloc` is an allocation, and `tainted` is a child of it that is a * taint sink. */ -predicate allocSink(Expr alloc, Expr tainted) { - isAllocationExpr(alloc) and - tainted = alloc.getAChild() and - tainted.getUnspecifiedType() instanceof IntegralType -} - -class TaintedAllocationSizeConfiguration extends TaintTrackingConfiguration { - override predicate isSink(Element tainted) { allocSink(_, tainted) } - - override predicate isBarrier(Expr e) { - super.isBarrier(e) - or - // There can be two separate reasons for `convertedExprMightOverflow` not holding: - // 1. `e` really cannot overflow. - // 2. `e` isn't analyzable. - // If we didn't rule out case 2 we would place barriers on anything that isn't analyzable. - ( - e instanceof UnaryArithmeticOperation or - e instanceof BinaryArithmeticOperation or - e instanceof AssignArithmeticOperation - ) and - not convertedExprMightOverflow(e) - or - // Subtracting two pointers is either well-defined (and the result will likely be small), or - // terribly undefined and dangerous. Here, we assume that the programmer has ensured that the - // result is well-defined (i.e., the two pointers point to the same object), and thus the result - // will likely be small. - e = any(PointerDiffExpr diff).getAnOperand() - } -} - -predicate taintedAllocSize( - Expr source, Expr alloc, PathNode sourceNode, PathNode sinkNode, string taintCause -) { - isUserInput(source, taintCause) and - exists(Expr tainted | - allocSink(alloc, tainted) and - taintedWithPath(source, tainted, sourceNode, sinkNode) +predicate allocSink(Expr alloc, DataFlow::Node sink) { + exists(Expr e | e = sink.asConvertedExpr() | + isAllocationExpr(alloc) and + e = alloc.getAChild() and + e.getUnspecifiedType() instanceof IntegralType ) } -from Expr source, Expr alloc, PathNode sourceNode, PathNode sinkNode, string taintCause -where taintedAllocSize(source, alloc, sourceNode, sinkNode, taintCause) -select alloc, sourceNode, sinkNode, "This allocation size is derived from $@ and might overflow", - source, "user input (" + taintCause + ")" +predicate readsVariable(LoadInstruction load, Variable var) { + load.getSourceAddress().(VariableAddressInstruction).getAstVariable() = var +} + +predicate hasUpperBoundsCheck(Variable var) { + exists(RelationalOperation oper, VariableAccess access | + oper.getAnOperand() = access and + access.getTarget() = var and + // Comparing to 0 is not an upper bound check + not oper.getAnOperand().getValue() = "0" + ) +} + +predicate nodeIsBarrierEqualityCandidate(DataFlow::Node node, Operand access, Variable checkedVar) { + readsVariable(node.asInstruction(), checkedVar) and + any(IRGuardCondition guard).ensuresEq(access, _, _, node.asInstruction().getBlock(), true) +} + +predicate isFlowSource(FlowSource source, string sourceType) { sourceType = source.getSourceType() } + +class TaintedAllocationSizeConfiguration extends TaintTracking::Configuration { + TaintedAllocationSizeConfiguration() { this = "TaintedAllocationSizeConfiguration" } + + override predicate isSource(DataFlow::Node source) { isFlowSource(source, _) } + + override predicate isSink(DataFlow::Node sink) { allocSink(_, sink) } + + override predicate isSanitizer(DataFlow::Node node) { + exists(Expr e | e = node.asExpr() | + // There can be two separate reasons for `convertedExprMightOverflow` not holding: + // 1. `e` really cannot overflow. + // 2. `e` isn't analyzable. + // If we didn't rule out case 2 we would place barriers on anything that isn't analyzable. + ( + e instanceof UnaryArithmeticOperation or + e instanceof BinaryArithmeticOperation or + e instanceof AssignArithmeticOperation + ) and + not convertedExprMightOverflow(e) + or + // Subtracting two pointers is either well-defined (and the result will likely be small), or + // terribly undefined and dangerous. Here, we assume that the programmer has ensured that the + // result is well-defined (i.e., the two pointers point to the same object), and thus the result + // will likely be small. + e = any(PointerDiffExpr diff).getAnOperand() + ) + or + exists(Variable checkedVar | + readsVariable(node.asInstruction(), checkedVar) and + hasUpperBoundsCheck(checkedVar) + ) + or + exists(Variable checkedVar, Operand access | + readsVariable(access.getDef(), checkedVar) and + nodeIsBarrierEqualityCandidate(node, access, checkedVar) + ) + } +} + +from + Expr alloc, DataFlow::PathNode source, DataFlow::PathNode sink, string taintCause, + TaintedAllocationSizeConfiguration conf +where + isFlowSource(source.getNode(), taintCause) and + conf.hasFlowPath(source, sink) and + allocSink(alloc, sink.getNode()) +select alloc, source, sink, "This allocation size is derived from $@ and might overflow", + source.getNode(), "user input (" + taintCause + ")" diff --git a/cpp/ql/src/Security/CWE/CWE-319/UseOfHttp.ql b/cpp/ql/src/Security/CWE/CWE-319/UseOfHttp.ql index 1410873a06b..13e72842fba 100644 --- a/cpp/ql/src/Security/CWE/CWE-319/UseOfHttp.ql +++ b/cpp/ql/src/Security/CWE/CWE-319/UseOfHttp.ql @@ -3,6 +3,7 @@ * @description Non-HTTPS connections can be intercepted by third parties. * @kind path-problem * @problem.severity warning + * @security-severity 8.1 * @precision high * @id cpp/non-https-url * @tags security diff --git a/cpp/ql/src/Security/CWE/CWE-326/InsufficientKeySize.c b/cpp/ql/src/Security/CWE/CWE-326/InsufficientKeySize.c new file mode 100644 index 00000000000..0d4ba9feb8f --- /dev/null +++ b/cpp/ql/src/Security/CWE/CWE-326/InsufficientKeySize.c @@ -0,0 +1,8 @@ +void encrypt_with_openssl(EVP_PKEY_CTX *ctx) { + + // BAD: only 1024 bits for an RSA key + EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, 1024); + + // GOOD: 2048 bits for an RSA key + EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, 2048); +} \ No newline at end of file diff --git a/cpp/ql/src/Security/CWE/CWE-326/InsufficientKeySize.qhelp b/cpp/ql/src/Security/CWE/CWE-326/InsufficientKeySize.qhelp new file mode 100644 index 00000000000..a0402119ba8 --- /dev/null +++ b/cpp/ql/src/Security/CWE/CWE-326/InsufficientKeySize.qhelp @@ -0,0 +1,38 @@ + + + +

    Using cryptographic algorithms with a small key size can leave data vulnerable to being decrypted.

    + +

    Many cryptographic algorithms provided by cryptography libraries can be configured with key sizes that are +vulnerable to brute force attacks. Using such a key size means that an attacker may be able to easily decrypt the +encrypted data.

    + +
    + + +

    Ensure that you use a strong, modern cryptographic algorithm. Use at least AES-128 or RSA-2048.

    + +
    + + +

    The following code shows an example of using the openssl library to generate an RSA key. +When creating a key, you must specify which key size to use. The first example uses 1024 bits, which is not +considered sufficient. The second example uses 2048 bits, which is currently considered sufficient.

    + + + +
    + + +
  • NIST, FIPS 140 Annex a: +Approved Security Functions.
  • +
  • NIST, SP 800-131A: +Transitions: Recommendation for Transitioning the Use of Cryptographic Algorithms and Key Lengths.
  • + + + +
    +
    diff --git a/cpp/ql/src/Security/CWE/CWE-326/InsufficientKeySize.ql b/cpp/ql/src/Security/CWE/CWE-326/InsufficientKeySize.ql new file mode 100644 index 00000000000..202e9fb225d --- /dev/null +++ b/cpp/ql/src/Security/CWE/CWE-326/InsufficientKeySize.ql @@ -0,0 +1,64 @@ +/** + * @name Use of a cryptographic algorithm with insufficient key size + * @description Using cryptographic algorithms with too small a key size can + * allow an attacker to compromise security. + * @kind path-problem + * @problem.severity error + * @security-severity 7.5 + * @precision high + * @id cpp/insufficient-key-size + * @tags security + * external/cwe/cwe-326 + */ + +import cpp +import semmle.code.cpp.ir.dataflow.DataFlow +import semmle.code.cpp.ir.IR +import DataFlow::PathGraph + +// Gets the recommended minimum key size (in bits) of `func`, the name of an encryption function that accepts a key size as parameter `paramIndex` +int getMinimumKeyStrength(string func, int paramIndex) { + func = + [ + "EVP_PKEY_CTX_set_dsa_paramgen_bits", "DSA_generate_parameters_ex", + "EVP_PKEY_CTX_set_rsa_keygen_bits", "RSA_generate_key_ex", "RSA_generate_key_fips", + "EVP_PKEY_CTX_set_dh_paramgen_prime_len", "DH_generate_parameters_ex" + ] and + paramIndex = 1 and + result = 2048 +} + +class KeyStrengthFlow extends DataFlow::Configuration { + KeyStrengthFlow() { this = "KeyStrengthFlow" } + + override predicate isSource(DataFlow::Node node) { + exists(int bits | + node.asInstruction().(IntegerConstantInstruction).getValue().toInt() = bits and + bits < getMinimumKeyStrength(_, _) and + bits > 0 // exclude sentinel values + ) + } + + override predicate isSink(DataFlow::Node node) { + exists(FunctionCall fc, string name, int param | + node.asExpr() = fc.getArgument(param) and + fc.getTarget().hasGlobalName(name) and + exists(getMinimumKeyStrength(name, param)) + ) + } +} + +from + DataFlow::PathNode source, DataFlow::PathNode sink, KeyStrengthFlow conf, FunctionCall fc, + int param, string name, int minimumBits, int bits +where + conf.hasFlowPath(source, sink) and + sink.getNode().asExpr() = fc.getArgument(param) and + fc.getTarget().hasGlobalName(name) and + minimumBits = getMinimumKeyStrength(name, param) and + bits = source.getNode().asInstruction().(ConstantValueInstruction).getValue().toInt() and + bits < minimumBits and + bits != 0 +select fc, source, sink, + "The key size $@ is less than the recommended key size of " + minimumBits.toString() + " bits.", + source, bits.toString() diff --git a/cpp/ql/src/Security/CWE/CWE-497/ExposedSystemData.ql b/cpp/ql/src/Security/CWE/CWE-497/ExposedSystemData.ql index 2a3fbfa793e..31a152a167a 100644 --- a/cpp/ql/src/Security/CWE/CWE-497/ExposedSystemData.ql +++ b/cpp/ql/src/Security/CWE/CWE-497/ExposedSystemData.ql @@ -6,7 +6,7 @@ * @kind path-problem * @problem.severity warning * @security-severity 6.5 - * @precision medium + * @precision high * @id cpp/system-data-exposure * @tags security * external/cwe/cwe-497 @@ -46,8 +46,8 @@ class EnvData extends SystemData { /** * Data originating from a call to `mysql_get_client_info()`. */ -class SQLClientInfo extends SystemData { - SQLClientInfo() { this.(FunctionCall).getTarget().hasName("mysql_get_client_info") } +class SqlClientInfo extends SystemData { + SqlClientInfo() { this.(FunctionCall).getTarget().hasName("mysql_get_client_info") } override Expr getAnExpr() { result = this } } @@ -63,8 +63,8 @@ private predicate sqlConnectInfo(FunctionCall source, VariableAccess use) { /** * Data passed into an SQL connect function. */ -class SQLConnectInfo extends SystemData { - SQLConnectInfo() { sqlConnectInfo(this, _) } +class SqlConnectInfo extends SystemData { + SqlConnectInfo() { sqlConnectInfo(this, _) } override Expr getAnExpr() { sqlConnectInfo(this, result) } } diff --git a/cpp/ql/src/change-notes/2022-02-10-system-data-exposure.md b/cpp/ql/src/change-notes/2022-02-10-system-data-exposure.md deleted file mode 100644 index 2492920de70..00000000000 --- a/cpp/ql/src/change-notes/2022-02-10-system-data-exposure.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* The `cpp/system-data-exposure` query has been modernized and has converted to a `path-problem` query. There are now fewer false positive results. diff --git a/cpp/ql/src/change-notes/2022-02-22-using-expired-stack-address.md b/cpp/ql/src/change-notes/2022-02-22-using-expired-stack-address.md deleted file mode 100644 index 6da48a433da..00000000000 --- a/cpp/ql/src/change-notes/2022-02-22-using-expired-stack-address.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: newQuery ---- - -- A new query titled "Use of expired stack-address" (`cpp/using-expired-stack-address`) has been added. - This query finds accesses to expired stack-allocated memory that escaped via a global variable. diff --git a/cpp/ql/src/change-notes/2022-02-24-non-https-url.md b/cpp/ql/src/change-notes/2022-02-24-non-https-url.md deleted file mode 100644 index ac1523d5e53..00000000000 --- a/cpp/ql/src/change-notes/2022-02-24-non-https-url.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* The "Failure to use HTTPS URLs" (`cpp/non-https-url`) has been improved reducing false positive results, and its precision has been increased to 'high'. diff --git a/cpp/ql/src/change-notes/2022-03-07-system-data-exposure.md b/cpp/ql/src/change-notes/2022-03-07-system-data-exposure.md new file mode 100644 index 00000000000..372a3a8391b --- /dev/null +++ b/cpp/ql/src/change-notes/2022-03-07-system-data-exposure.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The `cpp/system-data-exposure` query has been increased from `medium` to `high` precision, following a number of improvements to the query logic. diff --git a/cpp/ql/src/change-notes/2022-03-10-port-three-queries-to-taint-tracking.md b/cpp/ql/src/change-notes/2022-03-10-port-three-queries-to-taint-tracking.md new file mode 100644 index 00000000000..249249152f7 --- /dev/null +++ b/cpp/ql/src/change-notes/2022-03-10-port-three-queries-to-taint-tracking.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The `cpp/overflow-destination`, `cpp/unclear-array-index-validation`, and `cpp/uncontrolled-allocation-size` queries have been modernized and converted to `path-problem` queries and provide more true positive results. diff --git a/cpp/ql/src/change-notes/released/0.0.11.md b/cpp/ql/src/change-notes/released/0.0.11.md new file mode 100644 index 00000000000..589cd05a6fb --- /dev/null +++ b/cpp/ql/src/change-notes/released/0.0.11.md @@ -0,0 +1,20 @@ +## 0.0.11 + +### Breaking Changes + +* The deprecated queries `cpp/duplicate-block`, `cpp/duplicate-function`, `cpp/duplicate-class`, `cpp/duplicate-file`, `cpp/mostly-duplicate-function`,`cpp/similar-file`, `cpp/duplicated-lines-in-files` have been removed. + +### Deprecated Predicates and Classes + +* The predicates and classes in the `CodeDuplication` library have been deprecated. + +### New Queries + +* A new query titled "Use of expired stack-address" (`cpp/using-expired-stack-address`) has been added. + This query finds accesses to expired stack-allocated memory that escaped via a global variable. +* A new `cpp/insufficient-key-size` query has been added to the default query suite for C/C++. The query finds uses of certain cryptographic algorithms where the key size is too small to provide adequate encryption strength. + +### Minor Analysis Improvements + +* The "Failure to use HTTPS URLs" (`cpp/non-https-url`) has been improved reducing false positive results, and its precision has been increased to 'high'. +* The `cpp/system-data-exposure` query has been modernized and has converted to a `path-problem` query. There are now fewer false positive results. diff --git a/cpp/ql/src/codeql-pack.release.yml b/cpp/ql/src/codeql-pack.release.yml index b740014e5ae..e679dc42092 100644 --- a/cpp/ql/src/codeql-pack.release.yml +++ b/cpp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.10 +lastReleaseVersion: 0.0.11 diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-190/DangerousUseOfTransformationAfterOperation.cpp b/cpp/ql/src/experimental/Security/CWE/CWE-190/DangerousUseOfTransformationAfterOperation.cpp new file mode 100644 index 00000000000..6a16e992471 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-190/DangerousUseOfTransformationAfterOperation.cpp @@ -0,0 +1,5 @@ +... + vUnsignedLong = (unsigned long)(vUnsignedInt*vUnsignedInt); // BAD +... + vUnsignedLong = ((unsigned long)vUnsignedInt*vUnsignedInt); // GOOD +... diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-190/DangerousUseOfTransformationAfterOperation.qhelp b/cpp/ql/src/experimental/Security/CWE/CWE-190/DangerousUseOfTransformationAfterOperation.qhelp new file mode 100644 index 00000000000..458b5e50866 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-190/DangerousUseOfTransformationAfterOperation.qhelp @@ -0,0 +1,24 @@ + + + +

    Search for places where the result of the multiplication is subjected to explicit conversion, not the arguments. Therefore, during the multiplication period, you can lose meaningful data.

    + + +
    + + +

    The following example demonstrates erroneous and fixed methods for working with type conversion.

    + + +
    + + +
  • + CERT C Coding Standard: + INT30-C. Ensure that unsigned integer operations do not wrap. +
  • + +
    +
    diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-190/DangerousUseOfTransformationAfterOperation.ql b/cpp/ql/src/experimental/Security/CWE/CWE-190/DangerousUseOfTransformationAfterOperation.ql new file mode 100644 index 00000000000..0bebc69a8bf --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-190/DangerousUseOfTransformationAfterOperation.ql @@ -0,0 +1,102 @@ +/** + * @name Dangerous use of transformation after operation. + * @description By using the transformation after the operation, you are doing a pointless and dangerous action. + * @kind problem + * @id cpp/dangerous-use-of-transformation-after-operation + * @problem.severity warning + * @precision medium + * @tags correctness + * security + * external/cwe/cwe-190 + */ + +import cpp + +/** Returns the number of the expression in the function call arguments. */ +int argumentPosition(FunctionCall fc, Expr exp, int n) { + n in [0 .. fc.getNumberOfArguments() - 1] and + fc.getArgument(n) = exp and + result = n +} + +/** Holds if a nonsensical type conversion situation is found. */ +predicate conversionDoneLate(MulExpr mexp) { + exists(Expr e1, Expr e2 | + mexp.hasOperands(e1, e2) and + not e1.isConstant() and + not e1.hasConversion() and + not e1.hasConversion() and + ( + e2.isConstant() or + not e2.hasConversion() + ) and + mexp.getConversion().hasExplicitConversion() and + mexp.getConversion() instanceof ParenthesisExpr and + mexp.getConversion().getConversion() instanceof CStyleCast and + mexp.getConversion().getConversion().getType().getSize() > mexp.getType().getSize() and + mexp.getConversion().getConversion().getType().getSize() > e2.getType().getSize() and + mexp.getConversion().getConversion().getType().getSize() > e1.getType().getSize() and + exists(Expr e0 | + e0.(AssignExpr).getRValue() = mexp.getParent*() and + e0.(AssignExpr).getLValue().getType().getSize() = + mexp.getConversion().getConversion().getType().getSize() + or + mexp.getEnclosingElement().(ComparisonOperation).hasOperands(mexp, e0) and + e0.getType().getSize() = mexp.getConversion().getConversion().getType().getSize() + or + e0.(FunctionCall) + .getTarget() + .getParameter(argumentPosition(e0.(FunctionCall), mexp, _)) + .getType() + .getSize() = mexp.getConversion().getConversion().getType().getSize() + ) + ) +} + +/** Holds if the situation of a possible signed overflow used in pointer arithmetic is found. */ +predicate signSmallerWithEqualSizes(MulExpr mexp) { + exists(Expr e1, Expr e2 | + mexp.hasOperands(e1, e2) and + not e1.isConstant() and + not e1.hasConversion() and + not e1.hasConversion() and + ( + e2.isConstant() or + not e2.hasConversion() + ) and + mexp.getConversion+().getUnderlyingType().getSize() = e1.getUnderlyingType().getSize() and + ( + e2.isConstant() or + mexp.getConversion+().getUnderlyingType().getSize() = e2.getUnderlyingType().getSize() + ) and + mexp.getConversion+().getUnderlyingType().getSize() = e1.getUnderlyingType().getSize() and + exists(AssignExpr ae | + ae.getRValue() = mexp.getParent*() and + ae.getRValue().getUnderlyingType().(IntegralType).isUnsigned() and + ae.getLValue().getUnderlyingType().(IntegralType).isSigned() and + ( + not exists(DivExpr de | mexp.getParent*() = de) + or + exists(DivExpr de, Expr ec | + e2.isConstant() and + de.hasOperands(mexp.getParent*(), ec) and + ec.isConstant() and + e2.getValue().toInt() > ec.getValue().toInt() + ) + ) and + exists(PointerAddExpr pa | + ae.getASuccessor+() = pa and + pa.getAnOperand().(VariableAccess).getTarget() = ae.getLValue().(VariableAccess).getTarget() + ) + ) + ) +} + +from MulExpr mexp, string msg +where + conversionDoneLate(mexp) and + msg = "This transformation is applied after multiplication." + or + signSmallerWithEqualSizes(mexp) and + msg = "Possible signed overflow followed by offset of the pointer out of bounds." +select mexp, msg diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-200/ExposureSensitiveInformationUnauthorizedActor.cpp b/cpp/ql/src/experimental/Security/CWE/CWE-200/ExposureSensitiveInformationUnauthorizedActor.cpp new file mode 100644 index 00000000000..4e29879a94d --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-200/ExposureSensitiveInformationUnauthorizedActor.cpp @@ -0,0 +1,10 @@ +... + FILE *fp = fopen(filename,"w"); // BAD +... + umask(S_IXUSR|S_IRWXG|S_IRWXO); + FILE *fp; + fp = fopen(filename,"w"); // GOOD + chmod(filename,S_IRUSR|S_IWUSR); + fprintf(fp,"%s\n","data to file"); + fclose(fp); +... diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-200/ExposureSensitiveInformationUnauthorizedActor.qhelp b/cpp/ql/src/experimental/Security/CWE/CWE-200/ExposureSensitiveInformationUnauthorizedActor.qhelp new file mode 100644 index 00000000000..e46dd08f57e --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-200/ExposureSensitiveInformationUnauthorizedActor.qhelp @@ -0,0 +1,24 @@ + + + +

    When creating a file using a library function such as fopen, the access rights for the newly created file are not specified as part of the call. Instead these rights are determined by the system unless the programmer takes specific measures, such as calling the Posix umask function at some point before the call to fopen. For some applications, the default access rights assigned by the system are not sufficient to protect a file against access by an attacker.

    + + +
    + + +

    The following example demonstrates erroneous and fixed methods for working with files.

    + + +
    + + +
  • + CERT C Coding Standard: + FIO06-C. Create files with appropriate access permissions. +
  • + +
    +
    diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-200/ExposureSensitiveInformationUnauthorizedActor.ql b/cpp/ql/src/experimental/Security/CWE/CWE-200/ExposureSensitiveInformationUnauthorizedActor.ql new file mode 100644 index 00000000000..ec32ccd4bfc --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-200/ExposureSensitiveInformationUnauthorizedActor.ql @@ -0,0 +1,65 @@ +/** + * @name Writing to a file without setting permissions. + * @description Lack of restriction on file access rights can be unsafe. + * @kind problem + * @id cpp/work-with-file-without-permissions-rights + * @problem.severity warning + * @precision medium + * @tags correctness + * maintainability + * security + * external/cwe/cwe-200 + * external/cwe/cwe-264 + */ + +import cpp +import semmle.code.cpp.valuenumbering.GlobalValueNumbering + +/** Holds for a function `f` that has an argument at index `apos` used to read the file. */ +predicate numberArgumentRead(Function f, int apos) { + f.hasGlobalOrStdName("fgets") and apos = 2 + or + f.hasGlobalOrStdName("fread") and apos = 3 + or + f.hasGlobalOrStdName("read") and apos = 0 + or + f.hasGlobalOrStdName("fscanf") and apos = 0 +} + +/** Holds for a function `f` that has an argument at index `apos` used to write to file */ +predicate numberArgumentWrite(Function f, int apos) { + f.hasGlobalOrStdName("fprintf") and apos = 0 + or + f.hasGlobalOrStdName("fputs") and apos = 1 + or + f.hasGlobalOrStdName("write") and apos = 0 + or + f.hasGlobalOrStdName("fwrite") and apos = 3 + or + f.hasGlobalOrStdName("fflush") and apos = 0 +} + +from FunctionCall fc +where + // a file is opened + ( + fc.getTarget().hasGlobalOrStdName("fopen") or + fc.getTarget().hasGlobalOrStdName("open") + ) and + fc.getNumberOfArguments() = 2 and + // the file is used for writing (but not reading) + exists(FunctionCall fctmp, int i | + numberArgumentWrite(fctmp.getTarget(), i) and + globalValueNumber(fc) = globalValueNumber(fctmp.getArgument(i)) + ) and + not exists(FunctionCall fctmp, int i | + numberArgumentRead(fctmp.getTarget(), i) and + globalValueNumber(fc) = globalValueNumber(fctmp.getArgument(i)) + ) and + // a file creation mode is not set globally by `umask` anywhere in the program + not exists(FunctionCall fctmp | + fctmp.getTarget().hasGlobalOrStdName("umask") or + fctmp.getTarget().hasGlobalOrStdName("fchmod") or + fctmp.getTarget().hasGlobalOrStdName("chmod") + ) +select fc, "You may have forgotten to restrict access rights when working with a file." diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-377/InsecureTemporaryFile.ql b/cpp/ql/src/experimental/Security/CWE/CWE-377/InsecureTemporaryFile.ql index 877b67cbbf8..0852cb90918 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-377/InsecureTemporaryFile.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-377/InsecureTemporaryFile.ql @@ -13,30 +13,6 @@ import cpp import semmle.code.cpp.valuenumbering.GlobalValueNumbering -/** Holds for a function `f` that has an argument at index `apos` used to read the file. */ -predicate numberArgumentRead(Function f, int apos) { - f.hasGlobalOrStdName("fgets") and apos = 2 - or - f.hasGlobalOrStdName("fread") and apos = 3 - or - f.hasGlobalOrStdName("read") and apos = 0 - or - f.hasGlobalOrStdName("fscanf") and apos = 0 -} - -/** Holds for a function `f` that has an argument at index `apos` used to write to file */ -predicate numberArgumentWrite(Function f, int apos) { - f.hasGlobalOrStdName("fprintf") and apos = 0 - or - f.hasGlobalOrStdName("fputs") and apos = 1 - or - f.hasGlobalOrStdName("write") and apos = 0 - or - f.hasGlobalOrStdName("fwrite") and apos = 3 - or - f.hasGlobalOrStdName("fflush") and apos = 0 -} - from FunctionCall fc, string msg where // search for functions for generating a name, without a guarantee of the absence of a file during the period of work with it. @@ -59,54 +35,4 @@ where ) and msg = "Finding the name of a file that does not exist does not mean that it will not be exist at the next operation." - or - // finding places to work with a file without setting permissions, but with predictable names. - ( - fc.getTarget().hasGlobalOrStdName("fopen") or - fc.getTarget().hasGlobalOrStdName("open") - ) and - fc.getNumberOfArguments() = 2 and - exists(FunctionCall fctmp, int i | - numberArgumentWrite(fctmp.getTarget(), i) and - globalValueNumber(fc) = globalValueNumber(fctmp.getArgument(i)) - ) and - not exists(FunctionCall fctmp, int i | - numberArgumentRead(fctmp.getTarget(), i) and - globalValueNumber(fc) = globalValueNumber(fctmp.getArgument(i)) - ) and - exists(FunctionCall fctmp | - ( - fctmp.getTarget().hasGlobalOrStdName("strcat") or - fctmp.getTarget().hasGlobalOrStdName("strcpy") - ) and - globalValueNumber(fc.getArgument(0)) = globalValueNumber(fctmp.getAnArgument()) - or - fctmp.getTarget().hasGlobalOrStdName("getenv") and - globalValueNumber(fc.getArgument(0)) = globalValueNumber(fctmp) - or - ( - fctmp.getTarget().hasGlobalOrStdName("asprintf") or - fctmp.getTarget().hasGlobalOrStdName("vasprintf") or - fctmp.getTarget().hasGlobalOrStdName("xasprintf") or - fctmp.getTarget().hasGlobalOrStdName("xvasprintf ") - ) and - exists(Variable vrtmp | - vrtmp = fc.getArgument(0).(VariableAccess).getTarget() and - vrtmp = fctmp.getArgument(0).(AddressOfExpr).getAddressable() and - not vrtmp instanceof Field - ) - ) and - not exists(FunctionCall fctmp | - ( - fctmp.getTarget().hasGlobalOrStdName("umask") or - fctmp.getTarget().hasGlobalOrStdName("fchmod") or - fctmp.getTarget().hasGlobalOrStdName("chmod") - ) and - ( - fc.getBasicBlock().getASuccessor*() = fctmp.getBasicBlock() or - fctmp.getBasicBlock().getASuccessor*() = fc.getBasicBlock() - ) - ) and - msg = - "Creating a file for writing without evaluating its existence and setting permissions can be unsafe." select fc, msg diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-754/ImproperCheckReturnValueScanf.cpp b/cpp/ql/src/experimental/Security/CWE/CWE-754/ImproperCheckReturnValueScanf.cpp new file mode 100644 index 00000000000..4928db37a17 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-754/ImproperCheckReturnValueScanf.cpp @@ -0,0 +1,10 @@ +... + r = scanf("%i", &i); + if (r == 1) // GOOD + return i; + else + return -1; +... + scanf("%i", &i); // BAD + return i; +... diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-754/ImproperCheckReturnValueScanf.qhelp b/cpp/ql/src/experimental/Security/CWE/CWE-754/ImproperCheckReturnValueScanf.qhelp new file mode 100644 index 00000000000..ab40910f5d3 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-754/ImproperCheckReturnValueScanf.qhelp @@ -0,0 +1,27 @@ + + + +

    The `scanf` family functions does not require the memory pointed to by its additional pointer arguments to be initialized before calling. The user is required to check the return value of `scanf` and similar functions to establish how many of the additional arguments were assigned values. Not checking the return value and reading one of the arguments not assigned a value is undefined behavior and may have unexpected consequences.

    +
    + + +

    +The user should check the return value of `scanf` and related functions and check that any additional argument was assigned a value before reading the additional argument. +

    +
    + +

    The first first example below is correct, as value of `i` is only read once it is checked that `scanf` has read one item. The second example is incorrect, as the return value of `scanf` is not checked, and as `scanf` might have failed to read any item before returning.

    + + +
    + + +
  • + CERT C Coding Standard: + EXP12-C. Do not ignore values returned by functions. +
  • + +
    +
    diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-754/ImproperCheckReturnValueScanf.ql b/cpp/ql/src/experimental/Security/CWE/CWE-754/ImproperCheckReturnValueScanf.ql new file mode 100644 index 00000000000..5f296752c1c --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-754/ImproperCheckReturnValueScanf.ql @@ -0,0 +1,103 @@ +/** + * @name Improper check of return value of scanf + * @description Not checking the return value of scanf and related functions may lead to undefined behavior. + * @kind problem + * @id cpp/improper-check-return-value-scanf + * @problem.severity warning + * @precision medium + * @tags correctness + * security + * external/cwe/cwe-754 + * external/cwe/cwe-908 + */ + +import cpp +import semmle.code.cpp.commons.Exclusions + +/** Returns the position of the first argument being filled. */ +int posArgumentInFunctionCall(FunctionCall fc) { + ( + fc.getTarget().hasGlobalOrStdName(["scanf", "scanf_s"]) and + result = 1 + or + fc.getTarget().hasGlobalOrStdName(["fscanf", "sscanf", "fscanf_s", "sscanf_s"]) and + result = 2 + ) +} + +/** Holds if a function argument was not initialized but used after the call. */ +predicate argumentIsNotInitializedAndIsUsed(Variable vt, FunctionCall fc) { + // Fillable argument was not initialized. + vt instanceof LocalScopeVariable and + not vt.getAnAssignment().getASuccessor+() = fc and + ( + not vt.hasInitializer() + or + exists(Expr e, Variable v | + e = vt.getInitializer().getExpr() and + v = e.(AddressOfExpr).getOperand().(VariableAccess).getTarget() and + ( + not v.hasInitializer() and + not v.getAnAssignment().getASuccessor+() = fc + ) + ) + ) and + not exists(AssignExpr ae | + ae.getLValue() = vt.getAnAccess().getParent() and + ae.getASuccessor+() = fc + ) and + not exists(FunctionCall f0 | + f0.getAnArgument().getAChild() = vt.getAnAccess() and + f0.getASuccessor+() = fc + ) and + exists(Expr e0 | + // After the call, the completed arguments are assigned or returned as the result of the operation of the upper function. + fc.getASuccessor+() = e0 and + ( + ( + e0.(Assignment).getRValue().(VariableAccess).getTarget() = vt or + e0.(Assignment).getRValue().(ArrayExpr).getArrayBase().(VariableAccess).getTarget() = vt + ) + or + e0.getEnclosingStmt() instanceof ReturnStmt and + e0.(VariableAccess).getTarget() = vt + or + not exists(Expr e1 | + fc.getASuccessor+() = e1 and + e1.(VariableAccess).getTarget() = vt + ) + ) + ) +} + +from FunctionCall fc, int i +where + // Function return value is not evaluated. + fc instanceof ExprInVoidContext and + not isFromMacroDefinition(fc) and + i in [posArgumentInFunctionCall(fc) .. fc.getNumberOfArguments() - 1] and + ( + argumentIsNotInitializedAndIsUsed(fc.getArgument(i).(VariableAccess).getTarget(), fc) or + argumentIsNotInitializedAndIsUsed(fc.getArgument(i) + .(AddressOfExpr) + .getOperand() + .(VariableAccess) + .getTarget(), fc) or + argumentIsNotInitializedAndIsUsed(fc.getArgument(i) + .(ArrayExpr) + .getArrayBase() + .(VariableAccess) + .getTarget(), fc) + ) and + // After the call, filled arguments are not evaluated. + not exists(Expr e0, int i1 | + i1 in [posArgumentInFunctionCall(fc) .. fc.getNumberOfArguments() - 1] and + fc.getASuccessor+() = e0 and + e0.getEnclosingElement() instanceof ComparisonOperation and + ( + e0.(VariableAccess).getTarget() = fc.getArgument(i1).(VariableAccess).getTarget() or + e0.(VariableAccess).getTarget() = + fc.getArgument(i1).(AddressOfExpr).getOperand().(VariableAccess).getTarget() + ) + ) +select fc, "Unchecked return value for call to '" + fc.getTarget().getName() + "'." diff --git a/cpp/ql/src/external/CodeDuplication.qll b/cpp/ql/src/external/CodeDuplication.qll index 26fe883fc2f..e50323f7087 100644 --- a/cpp/ql/src/external/CodeDuplication.qll +++ b/cpp/ql/src/external/CodeDuplication.qll @@ -2,14 +2,14 @@ import cpp -private newtype TDuplicationOrSimilarity = MKDuplicationOrSimilarity() +deprecated private newtype TDuplicationOrSimilarity = MKDuplicationOrSimilarity() /** * DEPRECATED: This class is no longer used. * * A token block used for detection of duplicate and similar code. */ -class Copy extends TDuplicationOrSimilarity { +deprecated class Copy extends TDuplicationOrSimilarity { /** Gets the index of the token in this block starting at the location `loc`, if any. */ int tokenStartingAt(Location loc) { none() } @@ -63,7 +63,7 @@ class Copy extends TDuplicationOrSimilarity { * * A block of duplicated code. */ -class DuplicateBlock extends Copy { +deprecated class DuplicateBlock extends Copy { override string toString() { result = "Duplicate code: " + this.sourceLines() + " duplicated lines." } @@ -74,21 +74,29 @@ class DuplicateBlock extends Copy { * * A block of similar code. */ -class SimilarBlock extends Copy { +deprecated class SimilarBlock extends Copy { override string toString() { result = "Similar code: " + this.sourceLines() + " almost duplicated lines." } } -/** Gets a function with a body and a location. */ -FunctionDeclarationEntry sourceMethod() { +/** + * DEPRECATED: The `CodeDuplication` library will be removed in a future release. + * + * Gets a function with a body and a location. + */ +deprecated FunctionDeclarationEntry sourceMethod() { result.isDefinition() and exists(result.getLocation()) and numlines(unresolveElement(result.getFunction()), _, _, _) } -/** Gets the number of member functions in `c` with a body and a location. */ -int numberOfSourceMethods(Class c) { +/** + * DEPRECATED: The `CodeDuplication` library will be removed in a future release. + * + * Gets the number of member functions in `c` with a body and a location. + */ +deprecated int numberOfSourceMethods(Class c) { result = count(FunctionDeclarationEntry m | m = sourceMethod() and @@ -96,7 +104,7 @@ int numberOfSourceMethods(Class c) { ) } -private predicate blockCoversStatement(int equivClass, int first, int last, Stmt stmt) { +deprecated private predicate blockCoversStatement(int equivClass, int first, int last, Stmt stmt) { exists(DuplicateBlock b, Location loc | stmt.getLocation() = loc and first = b.tokenStartingAt(loc) and @@ -105,13 +113,13 @@ private predicate blockCoversStatement(int equivClass, int first, int last, Stmt ) } -private Stmt statementInMethod(FunctionDeclarationEntry m) { +deprecated private Stmt statementInMethod(FunctionDeclarationEntry m) { result.getParent+() = m.getBlock() and not result.getLocation() instanceof UnknownStmtLocation and not result instanceof BlockStmt } -private predicate duplicateStatement( +deprecated private predicate duplicateStatement( FunctionDeclarationEntry m1, FunctionDeclarationEntry m2, Stmt s1, Stmt s2 ) { exists(int equivClass, int first, int last | @@ -125,31 +133,39 @@ private predicate duplicateStatement( } /** + * DEPRECATED: Information on duplicated statements is no longer available. + * * Holds if `m1` is a function with `total` lines, and `m2` is a function * that has `duplicate` lines in common with `m1`. */ -predicate duplicateStatements( +deprecated predicate duplicateStatements( FunctionDeclarationEntry m1, FunctionDeclarationEntry m2, int duplicate, int total ) { duplicate = strictcount(Stmt s | duplicateStatement(m1, m2, s, _)) and total = strictcount(statementInMethod(m1)) } -/** Holds if `m` and other are identical functions. */ -predicate duplicateMethod(FunctionDeclarationEntry m, FunctionDeclarationEntry other) { +/** + * DEPRECATED: Information on duplicated methods is no longer available. + * + * Holds if `m` and other are identical functions. + */ +deprecated predicate duplicateMethod(FunctionDeclarationEntry m, FunctionDeclarationEntry other) { exists(int total | duplicateStatements(m, other, total, total)) } /** + * DEPRECATED: Information on similar lines is no longer available. + * * INTERNAL: do not use. * * Holds if `line` in `f` is similar to a line somewhere else. */ -predicate similarLines(File f, int line) { +deprecated predicate similarLines(File f, int line) { exists(SimilarBlock b | b.sourceFile() = f and line in [b.sourceStartLine() .. b.sourceEndLine()]) } -private predicate similarLinesPerEquivalenceClass(int equivClass, int lines, File f) { +deprecated private predicate similarLinesPerEquivalenceClass(int equivClass, int lines, File f) { lines = strictsum(SimilarBlock b, int toSum | (b.sourceFile() = f and b.getEquivalenceClass() = equivClass) and @@ -159,7 +175,7 @@ private predicate similarLinesPerEquivalenceClass(int equivClass, int lines, Fil ) } -private predicate similarLinesCoveredFiles(File f, File otherFile) { +deprecated private predicate similarLinesCoveredFiles(File f, File otherFile) { exists(int numLines | numLines = f.getMetrics().getNumberOfLines() | exists(int coveredApprox | coveredApprox = @@ -175,8 +191,12 @@ private predicate similarLinesCoveredFiles(File f, File otherFile) { ) } -/** Holds if `coveredLines` lines of `f` are similar to lines in `otherFile`. */ -predicate similarLinesCovered(File f, int coveredLines, File otherFile) { +/** + * DEPRECATED: Information on similar lines is no longer available. + * + * Holds if `coveredLines` lines of `f` are similar to lines in `otherFile`. + */ +deprecated predicate similarLinesCovered(File f, int coveredLines, File otherFile) { exists(int numLines | numLines = f.getMetrics().getNumberOfLines() | similarLinesCoveredFiles(f, otherFile) and exists(int notCovered | @@ -191,17 +211,19 @@ predicate similarLinesCovered(File f, int coveredLines, File otherFile) { } /** + * DEPRECATED: Information on duplicate lines is no longer available. + * * INTERNAL: do not use. * * Holds if `line` in `f` is duplicated by a line somewhere else. */ -predicate duplicateLines(File f, int line) { +deprecated predicate duplicateLines(File f, int line) { exists(DuplicateBlock b | b.sourceFile() = f and line in [b.sourceStartLine() .. b.sourceEndLine()] ) } -private predicate duplicateLinesPerEquivalenceClass(int equivClass, int lines, File f) { +deprecated private predicate duplicateLinesPerEquivalenceClass(int equivClass, int lines, File f) { lines = strictsum(DuplicateBlock b, int toSum | (b.sourceFile() = f and b.getEquivalenceClass() = equivClass) and @@ -211,8 +233,12 @@ private predicate duplicateLinesPerEquivalenceClass(int equivClass, int lines, F ) } -/** Holds if `coveredLines` lines of `f` are duplicates of lines in `otherFile`. */ -predicate duplicateLinesCovered(File f, int coveredLines, File otherFile) { +/** + * DEPRECATED: Information on duplicate lines is no longer available. + * + * Holds if `coveredLines` lines of `f` are duplicates of lines in `otherFile`. + */ +deprecated predicate duplicateLinesCovered(File f, int coveredLines, File otherFile) { exists(int numLines | numLines = f.getMetrics().getNumberOfLines() | exists(int coveredApprox | coveredApprox = @@ -236,8 +262,12 @@ predicate duplicateLinesCovered(File f, int coveredLines, File otherFile) { ) } -/** Holds if most of `f` (`percent`%) is similar to `other`. */ -predicate similarFiles(File f, File other, int percent) { +/** + * DEPRECATED: Information on similar files is no longer available. + * + * Holds if most of `f` (`percent`%) is similar to `other`. + */ +deprecated predicate similarFiles(File f, File other, int percent) { exists(int covered, int total | similarLinesCovered(f, covered, other) and total = f.getMetrics().getNumberOfLines() and @@ -247,8 +277,12 @@ predicate similarFiles(File f, File other, int percent) { not duplicateFiles(f, other, _) } -/** Holds if most of `f` (`percent`%) is duplicated by `other`. */ -predicate duplicateFiles(File f, File other, int percent) { +/** + * DEPRECATED: Information on duplicate files is no longer available. + * + * Holds if most of `f` (`percent`%) is duplicated by `other`. + */ +deprecated predicate duplicateFiles(File f, File other, int percent) { exists(int covered, int total | duplicateLinesCovered(f, covered, other) and total = f.getMetrics().getNumberOfLines() and @@ -258,10 +292,12 @@ predicate duplicateFiles(File f, File other, int percent) { } /** + * DEPRECATED: Information on duplciate classes is no longer available. + * * Holds if most member functions of `c` (`numDup` out of `total`) are * duplicates of member functions in `other`. */ -predicate mostlyDuplicateClassBase(Class c, Class other, int numDup, int total) { +deprecated predicate mostlyDuplicateClassBase(Class c, Class other, int numDup, int total) { numDup = strictcount(FunctionDeclarationEntry m1 | exists(FunctionDeclarationEntry m2 | @@ -277,11 +313,13 @@ predicate mostlyDuplicateClassBase(Class c, Class other, int numDup, int total) } /** + * DEPRECATED: Information on duplciate classes is no longer available. + * * Holds if most member functions of `c` are duplicates of member functions in * `other`. Provides the human-readable `message` to describe the amount of * duplication. */ -predicate mostlyDuplicateClass(Class c, Class other, string message) { +deprecated predicate mostlyDuplicateClass(Class c, Class other, string message) { exists(int numDup, int total | mostlyDuplicateClassBase(c, other, numDup, total) and ( @@ -305,21 +343,31 @@ predicate mostlyDuplicateClass(Class c, Class other, string message) { ) } -/** Holds if `f` and `other` are similar or duplicates. */ -predicate fileLevelDuplication(File f, File other) { +/** + * DEPRECATED: Information on file duplication is no longer available. + * + * Holds if `f` and `other` are similar or duplicates. + */ +deprecated predicate fileLevelDuplication(File f, File other) { similarFiles(f, other, _) or duplicateFiles(f, other, _) } /** + * DEPRECATED: Information on class duplication is no longer available. + * * Holds if most member functions of `c` are duplicates of member functions in * `other`. */ -predicate classLevelDuplication(Class c, Class other) { mostlyDuplicateClass(c, other, _) } +deprecated predicate classLevelDuplication(Class c, Class other) { + mostlyDuplicateClass(c, other, _) +} /** + * DEPRECATED: The CodeDuplication library will be removed in a future release. + * * Holds if `line` in `f` should be allowed to be duplicated. This is the case * for `#include` directives. */ -predicate whitelistedLineForDuplication(File f, int line) { +deprecated predicate whitelistedLineForDuplication(File f, int line) { exists(Include i | i.getFile() = f and i.getLocation().getStartLine() = line) } diff --git a/cpp/ql/src/external/DuplicateBlock.ql b/cpp/ql/src/external/DuplicateBlock.ql deleted file mode 100644 index 3fdef9b510d..00000000000 --- a/cpp/ql/src/external/DuplicateBlock.ql +++ /dev/null @@ -1,27 +0,0 @@ -/** - * @deprecated - * @name Duplicate code - * @description This block of code is duplicated elsewhere. If possible, the shared code should be refactored so there is only one occurrence left. It may not always be possible to address these issues; other duplicate code checks (such as duplicate function, duplicate class) give subsets of the results with higher confidence. - * @kind problem - * @id cpp/duplicate-block - * @problem.severity recommendation - * @precision medium - * @tags testability - * maintainability - * duplicate-code - * non-attributable - */ - -import CodeDuplication - -from DuplicateBlock d, DuplicateBlock other, int lines, File otherFile, int otherLine -where - lines = d.sourceLines() and - lines > 10 and - other.getEquivalenceClass() = d.getEquivalenceClass() and - other != d and - otherFile = other.sourceFile() and - otherLine = other.sourceStartLine() -select d, - "Duplicate code: " + lines + " lines are duplicated at " + otherFile.getBaseName() + ":" + - otherLine diff --git a/cpp/ql/src/external/DuplicateFunction.qhelp b/cpp/ql/src/external/DuplicateFunction.qhelp deleted file mode 100644 index 8e81c11e5e6..00000000000 --- a/cpp/ql/src/external/DuplicateFunction.qhelp +++ /dev/null @@ -1,43 +0,0 @@ - - - - - -

    A function should never be duplicated verbatim in several places in the code. Of course -the severity of this anti-pattern is higher for longer functions than for extremely short -functions of one or two statements, but there are usually better ways of achieving the same -effect.

    - -
    - -

    Code duplication in general is highly undesirable for a range of reasons: The artificially -inflated amount of code hinders comprehension, and ranges of similar but subtly different lines -can mask the real purpose or intention behind a function. There is also a risk of -update anomalies, where only one of several copies of the code is updated to address a defect or -add a feature.

    - -

    In the case of function duplication, how to address the issue depends on the functions themselves -and on the precise classes in which the duplication occurs. At its simplest, the duplication can -be addressed by removing all but one of the duplicate function definitions and making -callers of the removed functions refer to the (now canonical) single remaining definition -instead.

    - -

    This may not be possible for reasons of visibility or accessibility. A common example might -be where two classes implement the same functionality but neither is a subtype of the other, -so it is not possible to inherit a single function definition. In such cases, introducing a -common superclass to share the duplicated code is a viable option. Alternatively, if the functions -don't need access to private object state, they can be moved to a shared utility class that -just provides the functionality itself.

    - -
    - - -
  • Elmar Juergens, Florian Deissenboeck, Benjamin Hummel, and Stefan Wagner. 2009. -Do code clones matter? In Proceedings of the 31st International Conference on -Software Engineering (ICSE '09). IEEE Computer Society, Washington, DC, USA, -485-495.
  • - -
    -
    diff --git a/cpp/ql/src/external/DuplicateFunction.ql b/cpp/ql/src/external/DuplicateFunction.ql deleted file mode 100644 index 1a861867fcb..00000000000 --- a/cpp/ql/src/external/DuplicateFunction.ql +++ /dev/null @@ -1,39 +0,0 @@ -/** - * @deprecated - * @name Duplicate function - * @description There is another identical implementation of this function. Extract the code to a common file or superclass or delegate to improve sharing. - * @kind problem - * @id cpp/duplicate-function - * @problem.severity recommendation - * @precision medium - * @tags testability - * maintainability - * duplicate-code - * non-attributable - */ - -import cpp -import CodeDuplication - -predicate relevant(FunctionDeclarationEntry m) { - exists(Location loc | - loc = m.getBlock().getLocation() and - ( - loc.getStartLine() + 5 < loc.getEndLine() and not m.getName().matches("get%") - or - loc.getStartLine() + 10 < loc.getEndLine() - ) - ) -} - -from FunctionDeclarationEntry m, FunctionDeclarationEntry other -where - duplicateMethod(m, other) and - relevant(m) and - not m.getFunction().isConstructedFrom(_) and - not other.getFunction().isConstructedFrom(_) and - not fileLevelDuplication(m.getFile(), other.getFile()) and - not classLevelDuplication(m.getFunction().getDeclaringType(), - other.getFunction().getDeclaringType()) -select m, "Function " + m.getName() + " is duplicated at $@.", other, - other.getFile().getBaseName() + ":" + other.getLocation().getStartLine().toString() diff --git a/cpp/ql/src/external/MostlyDuplicateClass.qhelp b/cpp/ql/src/external/MostlyDuplicateClass.qhelp deleted file mode 100644 index 113eb6bf243..00000000000 --- a/cpp/ql/src/external/MostlyDuplicateClass.qhelp +++ /dev/null @@ -1,45 +0,0 @@ - - - - - -

    In cases where several methods are duplicated between two (or more) classes, -the classes themselves are highlighted as "mostly duplicate", rather than creating a large -number of method-level warnings. The same caveats apply here, too.

    - -
    - -

    Code duplication in general is highly undesirable for a range of reasons: The artificially -inflated amount of code hinders comprehension, and ranges of similar but subtly different lines -can mask the real purpose or intention behind a method. There's also an omnipresent risk of -update anomalies, where only one of several copies of the code is updated to address a defect or -add a feature.

    - -

    While completely duplicated classes are rare, they are usually a sign of a simple -oversight (or deliberate copy/paste) on a developer's part. Usually the required remedy -action is to remove all but one of them.

    - -

    It is far more common to see duplication of many methods between two classes, leaving just -a few that are actually different. Such situations warrant close inspection. Are the differences -deliberate or a result of an inconsistent update to one of the clones? If the latter, then -treating the classes as completely duplicate and eliminating all but one (while preserving any -corrections or new features that may have been introduced) is the best course. If two classes serve -genuinely different purposes but almost all of their methods are the same, that can be a sign -that there is a missing level of abstraction. Introducing a common superclass to define the -common methods and sharing the code is likely to prevent many problems in the long term.

    - -

    Modern IDEs may provide refactoring support for this sort of transformation, usually -under the names of "Pull up" or "Extract supertype".

    - -
    - - -
  • Elmar Juergens, Florian Deissenboeck, Benjamin Hummel, and Stefan Wagner. 2009. -Do code clones matter? In Proceedings of the 31st International Conference on -Software Engineering (ICSE '09). IEEE Computer Society, Washington, DC, USA, -485-495.
  • - -
    -
    diff --git a/cpp/ql/src/external/MostlyDuplicateClass.ql b/cpp/ql/src/external/MostlyDuplicateClass.ql deleted file mode 100644 index 20b9f39214e..00000000000 --- a/cpp/ql/src/external/MostlyDuplicateClass.ql +++ /dev/null @@ -1,24 +0,0 @@ -/** - * @deprecated - * @name Mostly duplicate class - * @description More than 80% of the methods in this class are duplicated in another class. Create a common supertype to improve code sharing. - * @kind problem - * @id cpp/duplicate-class - * @problem.severity recommendation - * @precision medium - * @tags testability - * maintainability - * duplicate-code - * non-attributable - */ - -import cpp -import CodeDuplication - -from Class c, Class other, string message -where - mostlyDuplicateClass(c, other, message) and - not c.isConstructedFrom(_) and - not other.isConstructedFrom(_) and - not fileLevelDuplication(c.getFile(), _) -select c, message, other, other.getQualifiedName() diff --git a/cpp/ql/src/external/MostlyDuplicateFile.qhelp b/cpp/ql/src/external/MostlyDuplicateFile.qhelp deleted file mode 100644 index b3b319f346b..00000000000 --- a/cpp/ql/src/external/MostlyDuplicateFile.qhelp +++ /dev/null @@ -1,46 +0,0 @@ - - - - - -

    In cases where most of a file's lines have been duplicated in one or more other -files, the files themselves are highlighted as "mostly duplicate", rather than -creating a large number of method-level or class-level warnings. The same caveats -apply here, too.

    - -
    - -

    Code duplication in general is highly undesirable for a range of reasons: The artificially -inflated amount of code hinders comprehension, and ranges of similar but subtly different lines -can mask the real purpose or intention behind a method. There's also an omnipresent risk of -update anomalies, where only one of several copies of the code is updated to address a defect or -add a feature.

    - -

    While completely duplicated files are rare, they are usually a sign of a simple -oversight (or deliberate copy/paste) on a developer's part. Usually the required remedy -action is to remove all but one of them. A common exception may arise from generated code -that simply occurs in several places in the source tree; the check can be adapted to -exclude such results.

    - -

    It is far more common to see duplication of many lines between two files, leaving just -a few that are actually different. Such situations warrant close inspection. Are the differences -deliberate or a result of an inconsistent update to one of the clones? If the latter, then -treating the files as completely duplicate and eliminating all but one (while preserving any -corrections or new features that may have been introduced) is the best course. If two files serve -genuinely different purposes but almost all of their lines are the same, that can be a sign -that there is a missing level of abstraction. Look for ways to share the functionality, either -by extracting a utility class for parts of it or by encapsulating the common parts into a new -super class of any classes involved.

    - -
    - - -
  • Elmar Juergens, Florian Deissenboeck, Benjamin Hummel, and Stefan Wagner. 2009. -Do code clones matter? In Proceedings of the 31st International Conference on -Software Engineering (ICSE '09). IEEE Computer Society, Washington, DC, USA, -485-495.
  • - -
    -
    diff --git a/cpp/ql/src/external/MostlyDuplicateFile.ql b/cpp/ql/src/external/MostlyDuplicateFile.ql deleted file mode 100644 index 8cb23a432d2..00000000000 --- a/cpp/ql/src/external/MostlyDuplicateFile.ql +++ /dev/null @@ -1,21 +0,0 @@ -/** - * @deprecated - * @name Mostly duplicate file - * @description There is another file that shares a lot of the code with this file. Merge the two files to improve maintainability. - * @kind problem - * @id cpp/duplicate-file - * @problem.severity recommendation - * @precision medium - * @tags testability - * maintainability - * duplicate-code - * non-attributable - */ - -import cpp -import CodeDuplication - -from File f, File other, int percent -where duplicateFiles(f, other, percent) -select f, percent + "% of the lines in " + f.getBaseName() + " are copies of lines in $@.", other, - other.getBaseName() diff --git a/cpp/ql/src/external/MostlyDuplicateFunction.qhelp b/cpp/ql/src/external/MostlyDuplicateFunction.qhelp deleted file mode 100644 index a981eef6e87..00000000000 --- a/cpp/ql/src/external/MostlyDuplicateFunction.qhelp +++ /dev/null @@ -1,55 +0,0 @@ - - - - -

    A "mostly duplicate function" is a function for which there is at least one -almost exact duplicate somewhere else in the code, but for which there are no -exact duplicates. There will be minor typographical differences between this -function and any "mostly duplicate function" to which it corresponds (for -example, comments and small code changes), preventing an exact match. Pairs of -such functions are sometimes referred to as "similar".

    - -

    This class of problem can often be more insidious than mere duplication, because the two -implementations have diverged. This may be on purpose (when a function is copy-and-pasted -and adapted to a new context) or accidentally (when a correction is only introduced in one of -several identical pieces of code), and to address the problem one needs to understand which -of the two situations applies.

    - -
    - -

    Code duplication in general is highly undesirable for a range of reasons: The artificially -inflated amount of code hinders comprehension, and ranges of similar but subtly different lines -can mask the real purpose or intention behind a function. There's also a risk of -update anomalies, where only one of several copies of the code is updated to address a defect or -add a feature.

    - -

    In the case of function similarity, how to address the issue depends on the functions -themselves and on the precise classes in which they occur. At its simplest, if the differences -are accidental, the problem can be addressed by unifying the functions to behave identically. -Then, we can remove all but one of the duplicate function definitions and make -callers of the removed functions refer to the (now canonical) single remaining definition -instead.

    - -

    In more complex cases, look for ways of encapsulating the commonality and sharing it while -retaining the differences in functionality. Perhaps the function can be moved to a single place -and given an additional parameter, allowing it to cover all use cases? Alternatively, there -may be a common preprocessing or postprocessing step which can be extracted to its own (shared) -function, leaving only the specific parts in the existing functions.

    - -

    Modern IDEs may provide refactoring support for this sort of transformation. Relevant -refactorings might be "Extract function", "Change function signature", "Pull up" or "Extract -supertype".

    - -
    - - -
  • Elmar Juergens, Florian Deissenboeck, Benjamin Hummel, and Stefan Wagner. 2009. -Do code clones matter? In Proceedings of the 31st International Conference on -Software Engineering (ICSE '09). IEEE Computer Society, Washington, DC, USA, -485-495.
  • - - -
    -
    diff --git a/cpp/ql/src/external/MostlyDuplicateFunction.ql b/cpp/ql/src/external/MostlyDuplicateFunction.ql deleted file mode 100644 index 8a7454e4c97..00000000000 --- a/cpp/ql/src/external/MostlyDuplicateFunction.ql +++ /dev/null @@ -1,31 +0,0 @@ -/** - * @deprecated - * @name Mostly duplicate function - * @description There is another function that shares a lot of the code with this one. Extract the code to a common file/superclass or delegate to improve sharing. - * @kind problem - * @id cpp/mostly-duplicate-function - * @problem.severity recommendation - * @precision medium - * @tags testability - * duplicate-code - * non-attributable - */ - -import cpp -import CodeDuplication - -from FunctionDeclarationEntry m, int covered, int total, FunctionDeclarationEntry other, int percent -where - duplicateStatements(m, other, covered, total) and - covered != total and - total > 5 and - covered * 100 / total = percent and - percent > 80 and - not m.getFunction().isConstructedFrom(_) and - not other.getFunction().isConstructedFrom(_) and - not duplicateMethod(m, other) and - not classLevelDuplication(m.getFunction().getDeclaringType(), - other.getFunction().getDeclaringType()) and - not fileLevelDuplication(m.getFile(), other.getFile()) -select m, percent + "% of the statements in " + m.getName() + " are duplicated in $@.", other, - other.getFunction().getQualifiedName() diff --git a/cpp/ql/src/external/MostlySimilarFile.qhelp b/cpp/ql/src/external/MostlySimilarFile.qhelp deleted file mode 100644 index e1a41a16321..00000000000 --- a/cpp/ql/src/external/MostlySimilarFile.qhelp +++ /dev/null @@ -1,39 +0,0 @@ - - - - - -

    Two lines are defined as similar if they are either identical or contain only very minor -differences. In cases where most of the lines in a file have corresponding "similar" lines in another file, -the files themselves are highlighted as "mostly similar", instead of creating a large number of method-level or class-level -warnings. The same caveats apply here, too.

    - -
    - -

    Code duplication in general is highly undesirable for a range of reasons: The artificially -inflated amount of code hinders comprehension, and ranges of similar but subtly different lines -can mask the real purpose or intention behind a method. There's also an omnipresent risk of -update anomalies, where only one of several copies of the code is updated to address a defect or -add a feature.

    - -

    With files that are marked as mostly similar, special care should be taken. Why are -they almost the same, and why are there differences? If the differences are accidental (for -example from corrections that were only applied to one copy), then unifying the files and removing -all but one is the best thing to do. If the files have genuinely different tasks, it is worth -thinking about the reasons for the similarity. Can some of the shared code be extracted into -methods (perhaps with additional parameters, to cover the differences in behavior)? Should it -be moved into a utility class or file that is accessible to all current implementations, or -should a new level of abstraction be introduced?

    - -
    - - -
  • Elmar Juergens, Florian Deissenboeck, Benjamin Hummel, and Stefan Wagner. 2009. -Do code clones matter? In Proceedings of the 31st International Conference on -Software Engineering (ICSE '09). IEEE Computer Society, Washington, DC, USA, -485-495.
  • - -
    -
    diff --git a/cpp/ql/src/external/MostlySimilarFile.ql b/cpp/ql/src/external/MostlySimilarFile.ql deleted file mode 100644 index 81a6ed02d6c..00000000000 --- a/cpp/ql/src/external/MostlySimilarFile.ql +++ /dev/null @@ -1,21 +0,0 @@ -/** - * @deprecated - * @name Mostly similar file - * @description There is another file that shares a lot of the code with this file. Notice that names of variables and types may have been changed. Merge the two files to improve maintainability. - * @kind problem - * @id cpp/similar-file - * @problem.severity recommendation - * @precision medium - * @tags testability - * maintainability - * duplicate-code - * non-attributable - */ - -import cpp -import CodeDuplication - -from File f, File other, int percent -where similarFiles(f, other, percent) -select f, percent + "% of the lines in " + f.getBaseName() + " are similar to lines in $@.", other, - other.getBaseName() diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 97.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 97.ql index 872a7443e6e..58b83e4bd13 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 97.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 97.ql @@ -27,13 +27,13 @@ predicate containsArray(Type t) { ) } -predicate functionAPIViolation(MemberFunction f) { +predicate functionApiViolation(MemberFunction f) { f.isPublic() and containsArray(f.getAParameter().getType()) } from MemberFunction m where - functionAPIViolation(m) and + functionApiViolation(m) and not m.getDeclaringType() instanceof Struct select m, "Raw arrays should not be used in interfaces. A container class should be used instead." diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 186.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 186.ql index ed713c4b109..4c1f8cfdd7f 100644 --- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 186.ql +++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 186.ql @@ -12,13 +12,13 @@ import cpp // whether f is to be considered an API entry point, and hence reachable by default -predicate isAPI(Function f) { +predicate isApi(Function f) { f.hasName("main") or f.(MemberFunction).hasSpecifier("public") } predicate unusedFunction(Function f) { - not isAPI(f) and + not isApi(f) and not exists(FunctionCall c | c.getTarget() = f) and not exists(Access acc | acc.getTarget() = f) and f.hasDefinition() diff --git a/cpp/ql/src/printAst.ql b/cpp/ql/src/printAst.ql index f800fa3be3e..ae6b3052ec7 100644 --- a/cpp/ql/src/printAst.ql +++ b/cpp/ql/src/printAst.ql @@ -16,7 +16,7 @@ import definitions */ external string selectedSourceFile(); -class Cfg extends PrintASTConfiguration { +class Cfg extends PrintAstConfiguration { /** * Holds if the AST for `func` should be printed. * Print All functions from the selected file. diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml index 78d0169a538..a9d08527b8c 100644 --- a/cpp/ql/src/qlpack.yml +++ b/cpp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-queries -version: 0.0.11-dev +version: 0.0.12-dev groups: - cpp - queries diff --git a/cpp/ql/test/TestUtilities/InlineExpectationsTest.qll b/cpp/ql/test/TestUtilities/InlineExpectationsTest.qll index 7d605a491ee..a4d264b2703 100644 --- a/cpp/ql/test/TestUtilities/InlineExpectationsTest.qll +++ b/cpp/ql/test/TestUtilities/InlineExpectationsTest.qll @@ -124,7 +124,9 @@ abstract class InlineExpectationsTest extends string { abstract predicate hasActualResult(Location location, string element, string tag, string value); /** - * Like `hasActualResult`, but returns results that do not require a matching annotation. + * Holds if there is an optional result on the specified location. + * + * This is similar to `hasActualResult`, but returns results that do not require a matching annotation. * A failure will still arise if there is an annotation that does not match any results, but not vice versa. * Override this predicate to specify optional results. */ diff --git a/cpp/ql/test/TestUtilities/dataflow/FlowTestCommon.qll b/cpp/ql/test/TestUtilities/dataflow/FlowTestCommon.qll index 87602ef0e4c..5841412331d 100644 --- a/cpp/ql/test/TestUtilities/dataflow/FlowTestCommon.qll +++ b/cpp/ql/test/TestUtilities/dataflow/FlowTestCommon.qll @@ -42,8 +42,8 @@ class IRFlowTest extends InlineExpectationsTest { } } -class ASTFlowTest extends InlineExpectationsTest { - ASTFlowTest() { this = "ASTFlowTest" } +class AstFlowTest extends InlineExpectationsTest { + AstFlowTest() { this = "ASTFlowTest" } override string getARelevantTag() { result = "ast" } @@ -69,3 +69,6 @@ class ASTFlowTest extends InlineExpectationsTest { ) } } + +/** DEPRECATED: Alias for AstFlowTest */ +deprecated class ASTFlowTest = AstFlowTest; diff --git a/cpp/ql/test/examples/expressions/PrintAST.expected b/cpp/ql/test/examples/expressions/PrintAST.expected index eb81accc996..68ade61e255 100644 --- a/cpp/ql/test/examples/expressions/PrintAST.expected +++ b/cpp/ql/test/examples/expressions/PrintAST.expected @@ -128,7 +128,7 @@ ConstructorCall.cpp: # 1| : #-----| getParameter(0): [Parameter] (unnamed parameter 0) #-----| Type = [RValueReferenceType] C && -# 3| [ConversionConstructor] void C::C(int) +# 3| [Constructor] void C::C(int) # 3| : # 3| getParameter(0): [Parameter] i # 3| Type = [IntType] int diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/DangerousUseOfTransformationAfterOperation/DangerousUseOfTransformationAfterOperation.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/DangerousUseOfTransformationAfterOperation/DangerousUseOfTransformationAfterOperation.expected new file mode 100644 index 00000000000..dd37faf2d56 --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/DangerousUseOfTransformationAfterOperation/DangerousUseOfTransformationAfterOperation.expected @@ -0,0 +1,4 @@ +| test.cpp:9:8:9:12 | ... * ... | Possible signed overflow followed by offset of the pointer out of bounds. | +| test.cpp:13:24:13:28 | ... * ... | This transformation is applied after multiplication. | +| test.cpp:16:28:16:32 | ... * ... | This transformation is applied after multiplication. | +| test.cpp:19:22:19:26 | ... * ... | This transformation is applied after multiplication. | diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/DangerousUseOfTransformationAfterOperation/DangerousUseOfTransformationAfterOperation.qlref b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/DangerousUseOfTransformationAfterOperation/DangerousUseOfTransformationAfterOperation.qlref new file mode 100644 index 00000000000..84f717acda7 --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/DangerousUseOfTransformationAfterOperation/DangerousUseOfTransformationAfterOperation.qlref @@ -0,0 +1 @@ +experimental/Security/CWE/CWE-190/DangerousUseOfTransformationAfterOperation.ql diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/DangerousUseOfTransformationAfterOperation/test.cpp b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/DangerousUseOfTransformationAfterOperation/test.cpp new file mode 100644 index 00000000000..472c8ac0afa --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/DangerousUseOfTransformationAfterOperation/test.cpp @@ -0,0 +1,23 @@ +void testCall (unsigned long); +void functionWork(char aA[10],unsigned int aUI) { + + unsigned long aL; + char *aP; + int aI; + + aI = (aUI*8)/10; // GOOD + aI = aUI*8; // BAD + aP = aA+aI; + aI = (int)aUI*8; // GOOD + + aL = (unsigned long)(aI*aI); // BAD + aL = ((unsigned long)aI*aI); // GOOD + + testCall((unsigned long)(aI*aI)); // BAD + testCall(((unsigned long)aI*aI)); // GOOD + + if((unsigned long)(aI*aI) > aL) // BAD + return; + if(((unsigned long)aI*aI) > aL) // GOOD + return; +} diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-200/test1/ExposureSensitiveInformationUnauthorizedActor.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-200/test1/ExposureSensitiveInformationUnauthorizedActor.expected new file mode 100644 index 00000000000..0e9e0870680 --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-200/test1/ExposureSensitiveInformationUnauthorizedActor.expected @@ -0,0 +1 @@ +| test.cpp:12:8:12:12 | call to fopen | You may have forgotten to restrict access rights when working with a file. | diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-200/test1/ExposureSensitiveInformationUnauthorizedActor.qlref b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-200/test1/ExposureSensitiveInformationUnauthorizedActor.qlref new file mode 100644 index 00000000000..0fa00ffe3ab --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-200/test1/ExposureSensitiveInformationUnauthorizedActor.qlref @@ -0,0 +1 @@ +experimental/Security/CWE/CWE-200/ExposureSensitiveInformationUnauthorizedActor.ql diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-200/test1/test.cpp b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-200/test1/test.cpp new file mode 100644 index 00000000000..6323d617ff1 --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-200/test1/test.cpp @@ -0,0 +1,17 @@ +typedef int FILE; +FILE *fopen(const char *filename, const char *mode); +int umask(int pmode); +int chmod(char * filename,int pmode); +int fprintf(FILE *fp,const char *fmt, ...); +int fclose(FILE *stream); + +int main(int argc, char *argv[]) +{ + //umask(0022); + FILE *fp; + fp = fopen("myFile.txt","w"); // BAD + //chmod("myFile.txt",0644); + fprintf(fp,"%s\n","data to file"); + fclose(fp); + return 0; +} diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-200/test2/ExposureSensitiveInformationUnauthorizedActor.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-200/test2/ExposureSensitiveInformationUnauthorizedActor.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-200/test2/ExposureSensitiveInformationUnauthorizedActor.qlref b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-200/test2/ExposureSensitiveInformationUnauthorizedActor.qlref new file mode 100644 index 00000000000..0fa00ffe3ab --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-200/test2/ExposureSensitiveInformationUnauthorizedActor.qlref @@ -0,0 +1 @@ +experimental/Security/CWE/CWE-200/ExposureSensitiveInformationUnauthorizedActor.ql diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-200/test2/test.cpp b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-200/test2/test.cpp new file mode 100644 index 00000000000..27a86d49937 --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-200/test2/test.cpp @@ -0,0 +1,17 @@ +typedef int FILE; +FILE *fopen(const char *filename, const char *mode); +int umask(int pmode); +int chmod(char * filename,int pmode); +int fprintf(FILE *fp,const char *fmt, ...); +int fclose(FILE *stream); + +int main(int argc, char *argv[]) +{ + umask(0022); + FILE *fp; + fp = fopen("myFile.txt","w"); // GOOD + chmod("myFile.txt",0644); + fprintf(fp,"%s\n","data to file"); + fclose(fp); + return 0; +} diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-200/test3/ExposureSensitiveInformationUnauthorizedActor.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-200/test3/ExposureSensitiveInformationUnauthorizedActor.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-200/test3/ExposureSensitiveInformationUnauthorizedActor.qlref b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-200/test3/ExposureSensitiveInformationUnauthorizedActor.qlref new file mode 100644 index 00000000000..0fa00ffe3ab --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-200/test3/ExposureSensitiveInformationUnauthorizedActor.qlref @@ -0,0 +1 @@ +experimental/Security/CWE/CWE-200/ExposureSensitiveInformationUnauthorizedActor.ql diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-200/test3/test.cpp b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-200/test3/test.cpp new file mode 100644 index 00000000000..cadf28ca6ec --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-200/test3/test.cpp @@ -0,0 +1,18 @@ +typedef int FILE; +FILE *fopen(const char *filename, const char *mode); +int umask(int pmode); +int chmod(char * filename,int pmode); +int fprintf(FILE *fp,const char *fmt, ...); +char *fgets(char *str, int num, FILE *stream); +int fclose(FILE *stream); + +int main(int argc, char *argv[]) +{ + FILE *fp; + char buf[128]; + fp = fopen("myFile.txt","r+"); // BAD [NOT DETECTED] + fgets(buf,128,fp); + fprintf(fp,"%s\n","data to file"); + fclose(fp); + return 0; +} diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-377/semmle/tests/InsecureTemporaryFile.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-377/semmle/tests/InsecureTemporaryFile.expected index b0632edcd2a..545b301922a 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-377/semmle/tests/InsecureTemporaryFile.expected +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-377/semmle/tests/InsecureTemporaryFile.expected @@ -1,2 +1 @@ | test.cpp:16:20:16:25 | call to tmpnam | Finding the name of a file that does not exist does not mean that it will not be exist at the next operation. | -| test.cpp:42:8:42:12 | call to fopen | Creating a file for writing without evaluating its existence and setting permissions can be unsafe. | diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-377/semmle/tests/test.cpp b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-377/semmle/tests/test.cpp index ceffdf11fa9..07efea49e78 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-377/semmle/tests/test.cpp +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-377/semmle/tests/test.cpp @@ -39,7 +39,7 @@ int funcTest3() FILE *fp; char filename[80]; strcat(filename, "/tmp/tmp.name"); - fp = fopen(filename,"w"); // BAD + fp = fopen(filename,"w"); // BAD [NOT DETECTED] fprintf(fp,"%s\n","data to file"); fclose(fp); return 0; diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-754/semmle/tests/ImproperCheckReturnValueScanf.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-754/semmle/tests/ImproperCheckReturnValueScanf.expected new file mode 100644 index 00000000000..85a929ed39c --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-754/semmle/tests/ImproperCheckReturnValueScanf.expected @@ -0,0 +1,8 @@ +| test.cpp:52:3:52:7 | call to scanf | Unchecked return value for call to 'scanf'. | +| test.cpp:53:3:53:7 | call to scanf | Unchecked return value for call to 'scanf'. | +| test.cpp:54:3:54:7 | call to scanf | Unchecked return value for call to 'scanf'. | +| test.cpp:105:3:105:7 | call to scanf | Unchecked return value for call to 'scanf'. | +| test.cpp:106:3:106:7 | call to scanf | Unchecked return value for call to 'scanf'. | +| test.cpp:107:3:107:7 | call to scanf | Unchecked return value for call to 'scanf'. | +| test.cpp:115:3:115:7 | call to scanf | Unchecked return value for call to 'scanf'. | +| test.cpp:120:3:120:7 | call to scanf | Unchecked return value for call to 'scanf'. | diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-754/semmle/tests/ImproperCheckReturnValueScanf.qlref b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-754/semmle/tests/ImproperCheckReturnValueScanf.qlref new file mode 100644 index 00000000000..f0cb9dd57c1 --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-754/semmle/tests/ImproperCheckReturnValueScanf.qlref @@ -0,0 +1 @@ +experimental/Security/CWE/CWE-754/ImproperCheckReturnValueScanf.ql diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-754/semmle/tests/test.cpp b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-754/semmle/tests/test.cpp new file mode 100644 index 00000000000..b9608b757b9 --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-754/semmle/tests/test.cpp @@ -0,0 +1,129 @@ +int scanf(const char *format, ...); +int sscanf(const char *str, const char *format, ...); +int globalVal; +char * globalVala; +int * globalValp; +char globalVala2; +int functionWork1(int retIndex) { + int i; + char a[10]; + int b; + int *p = &b; + if (scanf("%i", &i) != 1) // GOOD + return -1; + if (scanf("%s", a) != 1) // GOOD + return -1; + if (scanf("%i", p) != 1) // GOOD + return -1; + if(retIndex == 0) + return (int)*a; + if(retIndex == 1) + return *p; + return i; +} + +int functionWork1_(int retIndex) { + int i; + char a[10]; + int b; + int *p = &b; + int r; + r = scanf("%i", &i); + if (r != 1) // GOOD + return -1; + r = scanf("%s", a); + if (r == 1) // GOOD + return -1; + r = scanf("%i", p); + if (r != 1) // GOOD + return -1; + if(retIndex == 0) + return (int)*a; + if(retIndex == 1) + return *p; + return i; +} + +int functionWork1b(int retIndex) { + int i; + char a[10]; + int b; + int *p = &b; + scanf("%i", &i); // BAD + scanf("%s", a); // BAD + scanf("%i", p); // BAD + if(retIndex == 0) + return (int)*a; + if(retIndex == 1) + return *p; + return i; +} +int functionWork1_() { + int i; + scanf("%i",&i); // BAD [NOT DETECTED] + if(i<10) + return -1; + return i; +} +int functionWork2(int retIndex) { + int i = 0; + char a[10] = ""; + int b = 1; + int *p = &b; + scanf("%i", &i); // GOOD:Argument initialized even when scanf fails. + scanf("%s", a); // GOOD:Argument initialized even when scanf fails. + scanf("%i", p); // GOOD:Argument initialized even when scanf fails. + if(retIndex == 0) + return (int)*a; + if(retIndex == 1) + return *p; + return i; +} + +int functionWork2_(int retIndex) { + int i; + i = 0; + char a[10]; + a[0] = '\0'; + int b; + b=1; + int *p = &b; + scanf("%i", &i); // GOOD:Argument initialized even when scanf fails. + scanf("%s", a); // GOOD:Argument initialized even when scanf fails. + scanf("%i", p); // GOOD:Argument initialized even when scanf fails. + if(retIndex == 0) + return (int)*a; + if(retIndex == 1) + return *p; + return i; +} +int functionWork2b() { + int i; + char a[10]; + int b; + int *p = &b; + scanf("%i", &i); // BAD + scanf("%s", a); // BAD + scanf("%i", p); // BAD + globalVal = i; + globalVala = a; + globalValp = p; + return 0; +} +int functionWork2b_() { + char a[10]; + scanf("%s", a); // BAD + globalVala2 = a[0]; + return 0; +} +int functionWork3b(int * i) { + scanf("%i", i); // BAD + return 0; +} +int functionWork3() { + char number[] = "42"; + int d; + sscanf(number, "%d", &d); // GOOD: sscanf always succeeds + if (d < 16) + return -1; +} diff --git a/cpp/ql/test/library-tests/cpp11_g/cfg.ql b/cpp/ql/test/library-tests/cpp11_g/cfg.ql index 5fe85186273..105b4e709ee 100644 --- a/cpp/ql/test/library-tests/cpp11_g/cfg.ql +++ b/cpp/ql/test/library-tests/cpp11_g/cfg.ql @@ -1,5 +1,4 @@ import cpp -import semmle.code.cpp.exprs.ObjectiveC string arguments(Function f, int i) { result = "," and i = -1 diff --git a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_path_to_sink/tainted.ql b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_path_to_sink/tainted.ql index c1477d788ca..1737bb0bb33 100644 --- a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_path_to_sink/tainted.ql +++ b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_path_to_sink/tainted.ql @@ -67,8 +67,8 @@ class IRDefaultTaintTrackingTest extends InlineExpectationsTest { } } -class ASTTaintTrackingTest extends InlineExpectationsTest { - ASTTaintTrackingTest() { this = "ASTTaintTrackingTest" } +class AstTaintTrackingTest extends InlineExpectationsTest { + AstTaintTrackingTest() { this = "ASTTaintTrackingTest" } override string getARelevantTag() { result = "ast" } diff --git a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/tainted.ql b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/tainted.ql index 5784906862b..61014bbd48f 100644 --- a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/tainted.ql +++ b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/tainted.ql @@ -55,8 +55,8 @@ class IRDefaultTaintTrackingTest extends InlineExpectationsTest { } } -class ASTTaintTrackingTest extends InlineExpectationsTest { - ASTTaintTrackingTest() { this = "ASTTaintTrackingTest" } +class AstTaintTrackingTest extends InlineExpectationsTest { + AstTaintTrackingTest() { this = "ASTTaintTrackingTest" } override string getARelevantTag() { result = "ast" } diff --git a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/globals/global.ql b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/globals/global.ql index 953b15a9f9c..a9a4a1af231 100644 --- a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/globals/global.ql +++ b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/globals/global.ql @@ -27,8 +27,8 @@ class IRGlobalDefaultTaintTrackingTest extends InlineExpectationsTest { } } -class ASTGlobalDefaultTaintTrackingTest extends InlineExpectationsTest { - ASTGlobalDefaultTaintTrackingTest() { this = "ASTGlobalDefaultTaintTrackingTest" } +class AstGlobalDefaultTaintTrackingTest extends InlineExpectationsTest { + AstGlobalDefaultTaintTrackingTest() { this = "ASTGlobalDefaultTaintTrackingTest" } override string getARelevantTag() { result = "ast" } diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.ql b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.ql index 331956083ad..63c20affad1 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.ql +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.ql @@ -1,6 +1,6 @@ import TestUtilities.dataflow.FlowTestCommon -module ASTTest { +module AstTest { private import semmle.code.cpp.dataflow.DataFlow /** @@ -18,8 +18,8 @@ module ASTTest { } /** Common data flow configuration to be used by tests. */ - class ASTTestAllocationConfig extends DataFlow::Configuration { - ASTTestAllocationConfig() { this = "ASTTestAllocationConfig" } + class AstTestAllocationConfig extends DataFlow::Configuration { + AstTestAllocationConfig() { this = "ASTTestAllocationConfig" } override predicate isSource(DataFlow::Node source) { source.asExpr().(FunctionCall).getTarget().getName() = "source" @@ -100,10 +100,10 @@ module IRTest { } private predicate readsVariable(LoadInstruction load, Variable var) { - load.getSourceAddress().(VariableAddressInstruction).getASTVariable() = var + load.getSourceAddress().(VariableAddressInstruction).getAstVariable() = var } private predicate writesVariable(StoreInstruction store, Variable var) { - store.getDestinationAddress().(VariableAddressInstruction).getASTVariable() = var + store.getDestinationAddress().(VariableAddressInstruction).getAstVariable() = var } } diff --git a/cpp/ql/test/library-tests/dataflow/fields/ASTConfiguration.qll b/cpp/ql/test/library-tests/dataflow/fields/ASTConfiguration.qll index 67017f63abd..39d6cff3492 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/ASTConfiguration.qll +++ b/cpp/ql/test/library-tests/dataflow/fields/ASTConfiguration.qll @@ -1,8 +1,8 @@ private import semmle.code.cpp.dataflow.DataFlow private import DataFlow -class ASTConf extends Configuration { - ASTConf() { this = "ASTFieldFlowConf" } +class AstConf extends Configuration { + AstConf() { this = "ASTFieldFlowConf" } override predicate isSource(Node src) { src.asExpr() instanceof NewExpr @@ -30,3 +30,6 @@ class ASTConf extends Configuration { b.asExpr().(AddressOfExpr).getOperand() = a.asExpr() } } + +/** DEPRECATED: Alias for AstConf */ +deprecated class ASTConf = AstConf; diff --git a/cpp/ql/test/library-tests/dataflow/fields/Nodes.qll b/cpp/ql/test/library-tests/dataflow/fields/Nodes.qll index eb6f3247b82..2c3186b3dfa 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/Nodes.qll +++ b/cpp/ql/test/library-tests/dataflow/fields/Nodes.qll @@ -3,7 +3,7 @@ private import semmle.code.cpp.dataflow.DataFlow as AST private import cpp private newtype TNode = - TASTNode(AST::DataFlow::Node n) or + TAstNode(AST::DataFlow::Node n) or TIRNode(IR::DataFlow::Node n) class Node extends TNode { @@ -11,23 +11,32 @@ class Node extends TNode { IR::DataFlow::Node asIR() { none() } - AST::DataFlow::Node asAST() { none() } + AST::DataFlow::Node asAst() { none() } + + /** DEPRECATED: Alias for asAst */ + deprecated AST::DataFlow::Node asAST() { result = asAst() } Location getLocation() { none() } } -class ASTNode extends Node, TASTNode { +class AstNode extends Node, TAstNode { AST::DataFlow::Node n; - ASTNode() { this = TASTNode(n) } + AstNode() { this = TAstNode(n) } override string toString() { result = n.toString() } - override AST::DataFlow::Node asAST() { result = n } + override AST::DataFlow::Node asAst() { result = n } + + /** DEPRECATED: Alias for asAst */ + deprecated override AST::DataFlow::Node asAST() { result = asAst() } override Location getLocation() { result = n.getLocation() } } +/** DEPRECATED: Alias for AstNode */ +deprecated class ASTNode = AstNode; + class IRNode extends Node, TIRNode { IR::DataFlow::Node n; diff --git a/cpp/ql/test/library-tests/dataflow/fields/flow.ql b/cpp/ql/test/library-tests/dataflow/fields/flow.ql index 23a7281c718..f902afd33db 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/flow.ql +++ b/cpp/ql/test/library-tests/dataflow/fields/flow.ql @@ -1,6 +1,6 @@ import TestUtilities.dataflow.FlowTestCommon -module ASTTest { +module AstTest { private import ASTConfiguration } diff --git a/cpp/ql/test/library-tests/dataflow/fields/partial-definition-diff.ql b/cpp/ql/test/library-tests/dataflow/fields/partial-definition-diff.ql index fae4b06da5a..3baba1a02ff 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/partial-definition-diff.ql +++ b/cpp/ql/test/library-tests/dataflow/fields/partial-definition-diff.ql @@ -7,8 +7,8 @@ import semmle.code.cpp.ir.dataflow.DataFlow::DataFlow as IR import semmle.code.cpp.dataflow.DataFlow::DataFlow as AST import Nodes -class ASTPartialDefNode extends ASTNode { - ASTPartialDefNode() { exists(n.asPartialDefinition()) } +class AstPartialDefNode extends AstNode { + AstPartialDefNode() { exists(n.asPartialDefinition()) } override string toString() { result = n.asPartialDefinition().toString() } } @@ -29,7 +29,7 @@ where msg = "IR only" or exists(AST::Node astNode, Expr partial | - node.asAST() = astNode and + node.asAst() = astNode and partial = astNode.asPartialDefinition() and not exists(IR::Node otherNode | otherNode.asPartialDefinition() = partial) ) and diff --git a/cpp/ql/test/library-tests/dataflow/fields/path-flow.ql b/cpp/ql/test/library-tests/dataflow/fields/path-flow.ql index 1772a3d6ad2..b1aeadfbb60 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/path-flow.ql +++ b/cpp/ql/test/library-tests/dataflow/fields/path-flow.ql @@ -7,6 +7,6 @@ import ASTConfiguration import cpp import DataFlow::PathGraph -from DataFlow::PathNode src, DataFlow::PathNode sink, ASTConf conf +from DataFlow::PathNode src, DataFlow::PathNode sink, AstConf conf where conf.hasFlowPath(src, sink) select sink, src, sink, sink + " flows from $@", src, src.toString() diff --git a/cpp/ql/test/library-tests/dataflow/smart-pointers-taint/taint.ql b/cpp/ql/test/library-tests/dataflow/smart-pointers-taint/taint.ql index 4f18139b2af..d16552d983d 100644 --- a/cpp/ql/test/library-tests/dataflow/smart-pointers-taint/taint.ql +++ b/cpp/ql/test/library-tests/dataflow/smart-pointers-taint/taint.ql @@ -1,10 +1,10 @@ import TestUtilities.dataflow.FlowTestCommon -module ASTTest { +module AstTest { private import semmle.code.cpp.dataflow.TaintTracking - class ASTSmartPointerTaintConfig extends TaintTracking::Configuration { - ASTSmartPointerTaintConfig() { this = "ASTSmartPointerTaintConfig" } + class AstSmartPointerTaintConfig extends TaintTracking::Configuration { + AstSmartPointerTaintConfig() { this = "ASTSmartPointerTaintConfig" } override predicate isSource(DataFlow::Node source) { source.asExpr().(FunctionCall).getTarget().getName() = "source" diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.ql b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.ql index 4bf7420a9fd..bd513adcef2 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.ql +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.ql @@ -38,13 +38,13 @@ module TaintModels { } } -module ASTTest { +module AstTest { private import semmle.code.cpp.dataflow.TaintTracking private import semmle.code.cpp.models.interfaces.Taint /** Common data flow configuration to be used by tests. */ - class ASTTestAllocationConfig extends TaintTracking::Configuration { - ASTTestAllocationConfig() { this = "ASTTestAllocationConfig" } + class AstTestAllocationConfig extends TaintTracking::Configuration { + AstTestAllocationConfig() { this = "ASTTestAllocationConfig" } override predicate isSource(DataFlow::Node source) { source.asExpr().(FunctionCall).getTarget().getName() = "source" diff --git a/cpp/ql/test/library-tests/depends_initializers/InitializerCFG.ql b/cpp/ql/test/library-tests/depends_initializers/InitializerCFG.ql index fdb42979dc5..a9c52dd8223 100644 --- a/cpp/ql/test/library-tests/depends_initializers/InitializerCFG.ql +++ b/cpp/ql/test/library-tests/depends_initializers/InitializerCFG.ql @@ -1,7 +1,7 @@ import cpp -Function getCFGFunction(Initializer i) { result = i.getASuccessor*() } +Function getCfgFunction(Initializer i) { result = i.getASuccessor*() } from Initializer i, string f -where if exists(getCFGFunction(i)) then f = getCFGFunction(i).toString() else f = "" +where if exists(getCfgFunction(i)) then f = getCfgFunction(i).toString() else f = "" select i, f diff --git a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected index 9d3ca2171ce..86884faf491 100644 --- a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected +++ b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected @@ -5401,7 +5401,7 @@ ir.cpp: # 600| : # 600| getParameter(0): [Parameter] (unnamed parameter 0) # 600| Type = [RValueReferenceType] String && -# 601| [ConversionConstructor] void String::String(char const*) +# 601| [Constructor] void String::String(char const*) # 601| : # 601| getParameter(0): [Parameter] (unnamed parameter 0) # 601| Type = [PointerType] const char * @@ -10630,7 +10630,7 @@ ir.cpp: # 1330| : #-----| getParameter(0): [Parameter] (unnamed parameter 0) #-----| Type = [RValueReferenceType] constructor_only && -# 1335| [ConversionConstructor] void constructor_only::constructor_only(int) +# 1335| [Constructor] void constructor_only::constructor_only(int) # 1335| : # 1335| getParameter(0): [Parameter] x # 1335| Type = [IntType] int diff --git a/cpp/ql/test/library-tests/ir/ir/PrintAST.ql b/cpp/ql/test/library-tests/ir/ir/PrintAST.ql index e107c80de02..471b12ed3e5 100644 --- a/cpp/ql/test/library-tests/ir/ir/PrintAST.ql +++ b/cpp/ql/test/library-tests/ir/ir/PrintAST.ql @@ -6,6 +6,6 @@ private import cpp private import semmle.code.cpp.PrintAST private import PrintConfig -private class PrintConfig extends PrintASTConfiguration { +private class PrintConfig extends PrintAstConfiguration { override predicate shouldPrintFunction(Function func) { shouldDumpFunction(func) } } diff --git a/cpp/ql/test/library-tests/ir/points_to/points_to.ql b/cpp/ql/test/library-tests/ir/points_to/points_to.ql index b639a235ee8..6cc7b7efb34 100644 --- a/cpp/ql/test/library-tests/ir/points_to/points_to.ql +++ b/cpp/ql/test/library-tests/ir/points_to/points_to.ql @@ -40,7 +40,7 @@ module Raw { } } -module UnaliasedSSA { +module UnaliasedSsa { private import semmle.code.cpp.ir.implementation.unaliased_ssa.IR private import semmle.code.cpp.ir.implementation.aliased_ssa.internal.AliasedSSA @@ -49,8 +49,8 @@ module UnaliasedSSA { result = getOperandMemoryLocation(instr.getAnOperand()) } - class UnaliasedSSAPointsToTest extends InlineExpectationsTest { - UnaliasedSSAPointsToTest() { this = "UnaliasedSSAPointsToTest" } + class UnaliasedSsaPointsToTest extends InlineExpectationsTest { + UnaliasedSsaPointsToTest() { this = "UnaliasedSSAPointsToTest" } override string getARelevantTag() { result = "ussa" } diff --git a/cpp/ql/test/library-tests/special_members/generated_copy/assign.expected b/cpp/ql/test/library-tests/special_members/generated_copy/assign.expected index eec36e7e39c..28c90cb5233 100644 --- a/cpp/ql/test/library-tests/special_members/generated_copy/assign.expected +++ b/cpp/ql/test/library-tests/special_members/generated_copy/assign.expected @@ -11,6 +11,7 @@ | difference::Base | can | does NOT | have implicit copy assignment | | difference::OnlyAssign | can | does | have implicit copy assignment | | difference::OnlyCtor | can NOT | does NOT | have implicit copy assignment | +| instantiated_explicit_ctor::Wrapper | can | does | have implicit copy assignment | | moves::MoveAssign | can NOT | does NOT | have implicit copy assignment | | moves::MoveCtor | can NOT | does NOT | have implicit copy assignment | | private_cc::C | can | does NOT | have implicit copy assignment | diff --git a/cpp/ql/test/library-tests/special_members/generated_copy/copy.cpp b/cpp/ql/test/library-tests/special_members/generated_copy/copy.cpp index 8d68cfdc09e..fac52670bca 100644 --- a/cpp/ql/test/library-tests/special_members/generated_copy/copy.cpp +++ b/cpp/ql/test/library-tests/special_members/generated_copy/copy.cpp @@ -131,3 +131,21 @@ namespace difference { class OnlyAssign : Base { }; } + +namespace instantiated_explicit_ctor { + template + class Wrapper { + public: + Wrapper(Wrapper &other) { + m_t = other.m_t; + } + + Wrapper() { + m_t = 0; + } + private: + T m_t; + }; + + Wrapper wrapped_int; +} diff --git a/cpp/ql/test/library-tests/special_members/generated_copy/ctor.expected b/cpp/ql/test/library-tests/special_members/generated_copy/ctor.expected index 22745978bf8..90a3f811e5d 100644 --- a/cpp/ql/test/library-tests/special_members/generated_copy/ctor.expected +++ b/cpp/ql/test/library-tests/special_members/generated_copy/ctor.expected @@ -11,6 +11,7 @@ | difference::Base | can | does NOT | have implicit copy constructor | | difference::OnlyAssign | can NOT | does NOT | have implicit copy constructor | | difference::OnlyCtor | can | does | have implicit copy constructor | +| instantiated_explicit_ctor::Wrapper | can | does NOT | have implicit copy constructor | | moves::MoveAssign | can NOT | does NOT | have implicit copy constructor | | moves::MoveCtor | can NOT | does NOT | have implicit copy constructor | | private_cc::C | can | does NOT | have implicit copy constructor | diff --git a/cpp/ql/test/library-tests/special_members/generated_copy/functions.expected b/cpp/ql/test/library-tests/special_members/generated_copy/functions.expected index 22282641b37..434b950e35c 100644 --- a/cpp/ql/test/library-tests/special_members/generated_copy/functions.expected +++ b/cpp/ql/test/library-tests/special_members/generated_copy/functions.expected @@ -86,5 +86,9 @@ | copy.cpp:131:9:131:9 | OnlyAssign | deleted | | | copy.cpp:131:9:131:9 | operator= | | | | copy.cpp:131:9:131:9 | operator= | | | +| copy.cpp:137:9:137:9 | operator= | | | +| copy.cpp:139:5:139:11 | Wrapper | | | +| copy.cpp:143:5:143:5 | Wrapper | | | +| copy.cpp:143:5:143:11 | Wrapper | | | | file://:0:0:0:0 | operator= | | | | file://:0:0:0:0 | operator= | | | diff --git a/cpp/ql/test/library-tests/stmt_expr/cfg.ql b/cpp/ql/test/library-tests/stmt_expr/cfg.ql index b6699eaee11..772ee7d3888 100644 --- a/cpp/ql/test/library-tests/stmt_expr/cfg.ql +++ b/cpp/ql/test/library-tests/stmt_expr/cfg.ql @@ -1,5 +1,4 @@ import cpp -import semmle.code.cpp.exprs.ObjectiveC from ControlFlowNode x, ControlFlowNode y, string entryPoint where diff --git a/cpp/ql/test/library-tests/variables/variables/variable.expected b/cpp/ql/test/library-tests/variables/variables/variable.expected index e99ff83d440..05756351a88 100644 --- a/cpp/ql/test/library-tests/variables/variables/variable.expected +++ b/cpp/ql/test/library-tests/variables/variables/variable.expected @@ -30,7 +30,6 @@ | variables.cpp:15:12:15:13 | v1 | file://:0:0:0:0 | int[10] | StaticStorageDurationVariable | | static | | variables.cpp:15:21:15:22 | pv | file://:0:0:0:0 | int * | GlobalVariable | | static | | variables.cpp:15:21:15:22 | pv | file://:0:0:0:0 | int * | StaticStorageDurationVariable | | static | -| variables.cpp:17:7:17:8 | fp | file://:0:0:0:0 | ..(*)(..) | FunctionPointerVariable | | | | variables.cpp:17:7:17:8 | fp | file://:0:0:0:0 | ..(*)(..) | GlobalVariable | | | | variables.cpp:17:7:17:8 | fp | file://:0:0:0:0 | ..(*)(..) | StaticStorageDurationVariable | | | | variables.cpp:19:7:19:8 | v2 | file://:0:0:0:0 | float[3] | GlobalVariable | | | diff --git a/cpp/ql/test/query-tests/Critical/UnsafeUseOfThis/UnsafeUseOfThis.expected b/cpp/ql/test/query-tests/Critical/UnsafeUseOfThis/UnsafeUseOfThis.expected index 2b1512242d1..6ea50ab7d8e 100644 --- a/cpp/ql/test/query-tests/Critical/UnsafeUseOfThis/UnsafeUseOfThis.expected +++ b/cpp/ql/test/query-tests/Critical/UnsafeUseOfThis/UnsafeUseOfThis.expected @@ -1,61 +1,103 @@ edges -| test.cpp:7:3:7:3 | InitializeParameter: B | test.cpp:8:12:8:15 | Load: this | -| test.cpp:8:12:8:15 | Load: this | test.cpp:34:16:34:16 | InitializeParameter: x | -| test.cpp:11:8:11:8 | InitializeParameter: b | test.cpp:12:5:12:5 | Load: b | -| test.cpp:12:5:12:5 | CopyValue: (reference dereference) | test.cpp:12:5:12:5 | ConvertToNonVirtualBase: (A)... | -| test.cpp:12:5:12:5 | Load: b | test.cpp:12:5:12:5 | CopyValue: (reference dereference) | -| test.cpp:15:3:15:4 | InitializeParameter: ~B | test.cpp:16:5:16:5 | Load: this | -| test.cpp:16:5:16:5 | Load: this | file://:0:0:0:0 | ConvertToNonVirtualBase: (A *)... | -| test.cpp:21:3:21:3 | InitializeParameter: C | test.cpp:21:13:21:13 | ConvertToNonVirtualBase: call to B | -| test.cpp:21:3:21:3 | InitializeParameter: C | test.cpp:22:12:22:15 | Load: this | -| test.cpp:21:3:21:3 | InitializeParameter: C | test.cpp:25:7:25:10 | Load: this | -| test.cpp:21:13:21:13 | ConvertToNonVirtualBase: call to B | test.cpp:7:3:7:3 | InitializeParameter: B | -| test.cpp:22:12:22:15 | ConvertToNonVirtualBase: (B *)... | test.cpp:34:16:34:16 | InitializeParameter: x | -| test.cpp:22:12:22:15 | Load: this | test.cpp:22:12:22:15 | ConvertToNonVirtualBase: (B *)... | -| test.cpp:25:7:25:10 | ConvertToNonVirtualBase: (B *)... | test.cpp:25:7:25:10 | ConvertToNonVirtualBase: (A *)... | -| test.cpp:25:7:25:10 | Load: this | test.cpp:25:7:25:10 | ConvertToNonVirtualBase: (B *)... | -| test.cpp:31:3:31:3 | InitializeParameter: D | test.cpp:31:12:31:15 | Load: this | -| test.cpp:31:11:31:15 | ConvertToNonVirtualBase: (B)... | test.cpp:31:11:31:15 | CopyValue: (reference to) | -| test.cpp:31:11:31:15 | CopyValue: (reference to) | test.cpp:11:8:11:8 | InitializeParameter: b | -| test.cpp:31:11:31:15 | CopyValue: * ... | test.cpp:31:11:31:15 | ConvertToNonVirtualBase: (B)... | -| test.cpp:31:12:31:15 | Load: this | test.cpp:31:11:31:15 | CopyValue: * ... | -| test.cpp:34:16:34:16 | InitializeParameter: x | test.cpp:35:3:35:3 | Load: x | -| test.cpp:35:3:35:3 | Load: x | test.cpp:35:3:35:3 | ConvertToNonVirtualBase: (A *)... | -| test.cpp:47:3:47:3 | InitializeParameter: F | test.cpp:48:10:48:13 | Load: this | -| test.cpp:48:10:48:13 | ConvertToNonVirtualBase: (E *)... | test.cpp:48:6:48:13 | ConvertToNonVirtualBase: (A *)... | -| test.cpp:48:10:48:13 | Load: this | test.cpp:48:10:48:13 | ConvertToNonVirtualBase: (E *)... | +| test.cpp:7:3:7:3 | this | test.cpp:8:12:8:15 | Load | +| test.cpp:8:12:8:15 | Load | test.cpp:8:12:8:15 | this | +| test.cpp:8:12:8:15 | this | test.cpp:34:16:34:16 | x | +| test.cpp:11:8:11:8 | b | test.cpp:12:5:12:5 | Load | +| test.cpp:12:5:12:5 | (reference dereference) | test.cpp:12:5:12:5 | Unary | +| test.cpp:12:5:12:5 | Load | test.cpp:12:5:12:5 | b | +| test.cpp:12:5:12:5 | Unary | test.cpp:12:5:12:5 | (A)... | +| test.cpp:12:5:12:5 | Unary | test.cpp:12:5:12:5 | (reference dereference) | +| test.cpp:12:5:12:5 | b | test.cpp:12:5:12:5 | Unary | +| test.cpp:15:3:15:4 | this | test.cpp:16:5:16:5 | Load | +| test.cpp:16:5:16:5 | Load | test.cpp:16:5:16:5 | this | +| test.cpp:16:5:16:5 | Unary | file://:0:0:0:0 | (A *)... | +| test.cpp:16:5:16:5 | this | test.cpp:16:5:16:5 | Unary | +| test.cpp:21:3:21:3 | Unary | test.cpp:21:13:21:13 | ConvertToNonVirtualBase | +| test.cpp:21:3:21:3 | this | test.cpp:21:3:21:3 | Unary | +| test.cpp:21:3:21:3 | this | test.cpp:22:12:22:15 | Load | +| test.cpp:21:3:21:3 | this | test.cpp:25:7:25:10 | Load | +| test.cpp:21:13:21:13 | ConvertToNonVirtualBase | test.cpp:7:3:7:3 | this | +| test.cpp:22:12:22:15 | (B *)... | test.cpp:34:16:34:16 | x | +| test.cpp:22:12:22:15 | Load | test.cpp:22:12:22:15 | this | +| test.cpp:22:12:22:15 | Unary | test.cpp:22:12:22:15 | (B *)... | +| test.cpp:22:12:22:15 | this | test.cpp:22:12:22:15 | Unary | +| test.cpp:25:7:25:10 | (B *)... | test.cpp:25:7:25:10 | Unary | +| test.cpp:25:7:25:10 | Load | test.cpp:25:7:25:10 | this | +| test.cpp:25:7:25:10 | Unary | test.cpp:25:7:25:10 | (A *)... | +| test.cpp:25:7:25:10 | Unary | test.cpp:25:7:25:10 | (B *)... | +| test.cpp:25:7:25:10 | this | test.cpp:25:7:25:10 | Unary | +| test.cpp:31:3:31:3 | this | test.cpp:31:12:31:15 | Load | +| test.cpp:31:11:31:15 | (B)... | test.cpp:31:11:31:15 | Unary | +| test.cpp:31:11:31:15 | (reference to) | test.cpp:11:8:11:8 | b | +| test.cpp:31:11:31:15 | * ... | test.cpp:31:11:31:15 | Unary | +| test.cpp:31:11:31:15 | Unary | test.cpp:31:11:31:15 | (B)... | +| test.cpp:31:11:31:15 | Unary | test.cpp:31:11:31:15 | (reference to) | +| test.cpp:31:12:31:15 | Load | test.cpp:31:12:31:15 | this | +| test.cpp:31:12:31:15 | Unary | test.cpp:31:11:31:15 | * ... | +| test.cpp:31:12:31:15 | this | test.cpp:31:12:31:15 | Unary | +| test.cpp:34:16:34:16 | x | test.cpp:35:3:35:3 | Load | +| test.cpp:35:3:35:3 | Load | test.cpp:35:3:35:3 | x | +| test.cpp:35:3:35:3 | Unary | test.cpp:35:3:35:3 | (A *)... | +| test.cpp:35:3:35:3 | x | test.cpp:35:3:35:3 | Unary | +| test.cpp:47:3:47:3 | this | test.cpp:48:10:48:13 | Load | +| test.cpp:48:10:48:13 | (E *)... | test.cpp:48:10:48:13 | Unary | +| test.cpp:48:10:48:13 | Load | test.cpp:48:10:48:13 | this | +| test.cpp:48:10:48:13 | Unary | test.cpp:48:6:48:13 | (A *)... | +| test.cpp:48:10:48:13 | Unary | test.cpp:48:10:48:13 | (E *)... | +| test.cpp:48:10:48:13 | this | test.cpp:48:10:48:13 | Unary | nodes -| file://:0:0:0:0 | ConvertToNonVirtualBase: (A *)... | semmle.label | ConvertToNonVirtualBase: (A *)... | -| test.cpp:7:3:7:3 | InitializeParameter: B | semmle.label | InitializeParameter: B | -| test.cpp:8:12:8:15 | Load: this | semmle.label | Load: this | -| test.cpp:11:8:11:8 | InitializeParameter: b | semmle.label | InitializeParameter: b | -| test.cpp:12:5:12:5 | ConvertToNonVirtualBase: (A)... | semmle.label | ConvertToNonVirtualBase: (A)... | -| test.cpp:12:5:12:5 | CopyValue: (reference dereference) | semmle.label | CopyValue: (reference dereference) | -| test.cpp:12:5:12:5 | Load: b | semmle.label | Load: b | -| test.cpp:15:3:15:4 | InitializeParameter: ~B | semmle.label | InitializeParameter: ~B | -| test.cpp:16:5:16:5 | Load: this | semmle.label | Load: this | -| test.cpp:21:3:21:3 | InitializeParameter: C | semmle.label | InitializeParameter: C | -| test.cpp:21:13:21:13 | ConvertToNonVirtualBase: call to B | semmle.label | ConvertToNonVirtualBase: call to B | -| test.cpp:22:12:22:15 | ConvertToNonVirtualBase: (B *)... | semmle.label | ConvertToNonVirtualBase: (B *)... | -| test.cpp:22:12:22:15 | Load: this | semmle.label | Load: this | -| test.cpp:25:7:25:10 | ConvertToNonVirtualBase: (A *)... | semmle.label | ConvertToNonVirtualBase: (A *)... | -| test.cpp:25:7:25:10 | ConvertToNonVirtualBase: (B *)... | semmle.label | ConvertToNonVirtualBase: (B *)... | -| test.cpp:25:7:25:10 | Load: this | semmle.label | Load: this | -| test.cpp:31:3:31:3 | InitializeParameter: D | semmle.label | InitializeParameter: D | -| test.cpp:31:11:31:15 | ConvertToNonVirtualBase: (B)... | semmle.label | ConvertToNonVirtualBase: (B)... | -| test.cpp:31:11:31:15 | CopyValue: (reference to) | semmle.label | CopyValue: (reference to) | -| test.cpp:31:11:31:15 | CopyValue: * ... | semmle.label | CopyValue: * ... | -| test.cpp:31:12:31:15 | Load: this | semmle.label | Load: this | -| test.cpp:34:16:34:16 | InitializeParameter: x | semmle.label | InitializeParameter: x | -| test.cpp:35:3:35:3 | ConvertToNonVirtualBase: (A *)... | semmle.label | ConvertToNonVirtualBase: (A *)... | -| test.cpp:35:3:35:3 | Load: x | semmle.label | Load: x | -| test.cpp:47:3:47:3 | InitializeParameter: F | semmle.label | InitializeParameter: F | -| test.cpp:48:6:48:13 | ConvertToNonVirtualBase: (A *)... | semmle.label | ConvertToNonVirtualBase: (A *)... | -| test.cpp:48:10:48:13 | ConvertToNonVirtualBase: (E *)... | semmle.label | ConvertToNonVirtualBase: (E *)... | -| test.cpp:48:10:48:13 | Load: this | semmle.label | Load: this | +| file://:0:0:0:0 | (A *)... | semmle.label | (A *)... | +| test.cpp:7:3:7:3 | this | semmle.label | this | +| test.cpp:8:12:8:15 | Load | semmle.label | Load | +| test.cpp:8:12:8:15 | this | semmle.label | this | +| test.cpp:11:8:11:8 | b | semmle.label | b | +| test.cpp:12:5:12:5 | (A)... | semmle.label | (A)... | +| test.cpp:12:5:12:5 | (reference dereference) | semmle.label | (reference dereference) | +| test.cpp:12:5:12:5 | Load | semmle.label | Load | +| test.cpp:12:5:12:5 | Unary | semmle.label | Unary | +| test.cpp:12:5:12:5 | Unary | semmle.label | Unary | +| test.cpp:12:5:12:5 | b | semmle.label | b | +| test.cpp:15:3:15:4 | this | semmle.label | this | +| test.cpp:16:5:16:5 | Load | semmle.label | Load | +| test.cpp:16:5:16:5 | Unary | semmle.label | Unary | +| test.cpp:16:5:16:5 | this | semmle.label | this | +| test.cpp:21:3:21:3 | Unary | semmle.label | Unary | +| test.cpp:21:3:21:3 | this | semmle.label | this | +| test.cpp:21:13:21:13 | ConvertToNonVirtualBase | semmle.label | ConvertToNonVirtualBase | +| test.cpp:22:12:22:15 | (B *)... | semmle.label | (B *)... | +| test.cpp:22:12:22:15 | Load | semmle.label | Load | +| test.cpp:22:12:22:15 | Unary | semmle.label | Unary | +| test.cpp:22:12:22:15 | this | semmle.label | this | +| test.cpp:25:7:25:10 | (A *)... | semmle.label | (A *)... | +| test.cpp:25:7:25:10 | (B *)... | semmle.label | (B *)... | +| test.cpp:25:7:25:10 | Load | semmle.label | Load | +| test.cpp:25:7:25:10 | Unary | semmle.label | Unary | +| test.cpp:25:7:25:10 | Unary | semmle.label | Unary | +| test.cpp:25:7:25:10 | this | semmle.label | this | +| test.cpp:31:3:31:3 | this | semmle.label | this | +| test.cpp:31:11:31:15 | (B)... | semmle.label | (B)... | +| test.cpp:31:11:31:15 | (reference to) | semmle.label | (reference to) | +| test.cpp:31:11:31:15 | * ... | semmle.label | * ... | +| test.cpp:31:11:31:15 | Unary | semmle.label | Unary | +| test.cpp:31:11:31:15 | Unary | semmle.label | Unary | +| test.cpp:31:12:31:15 | Load | semmle.label | Load | +| test.cpp:31:12:31:15 | Unary | semmle.label | Unary | +| test.cpp:31:12:31:15 | this | semmle.label | this | +| test.cpp:34:16:34:16 | x | semmle.label | x | +| test.cpp:35:3:35:3 | (A *)... | semmle.label | (A *)... | +| test.cpp:35:3:35:3 | Load | semmle.label | Load | +| test.cpp:35:3:35:3 | Unary | semmle.label | Unary | +| test.cpp:35:3:35:3 | x | semmle.label | x | +| test.cpp:47:3:47:3 | this | semmle.label | this | +| test.cpp:48:6:48:13 | (A *)... | semmle.label | (A *)... | +| test.cpp:48:10:48:13 | (E *)... | semmle.label | (E *)... | +| test.cpp:48:10:48:13 | Load | semmle.label | Load | +| test.cpp:48:10:48:13 | Unary | semmle.label | Unary | +| test.cpp:48:10:48:13 | Unary | semmle.label | Unary | +| test.cpp:48:10:48:13 | this | semmle.label | this | #select -| test.cpp:12:7:12:7 | call to f | test.cpp:31:3:31:3 | InitializeParameter: D | test.cpp:12:5:12:5 | ConvertToNonVirtualBase: (A)... | Call to pure virtual function during construction | -| test.cpp:16:5:16:5 | call to f | test.cpp:15:3:15:4 | InitializeParameter: ~B | file://:0:0:0:0 | ConvertToNonVirtualBase: (A *)... | Call to pure virtual function during destruction | -| test.cpp:25:13:25:13 | call to f | test.cpp:21:3:21:3 | InitializeParameter: C | test.cpp:25:7:25:10 | ConvertToNonVirtualBase: (A *)... | Call to pure virtual function during construction | -| test.cpp:35:6:35:6 | call to f | test.cpp:7:3:7:3 | InitializeParameter: B | test.cpp:35:3:35:3 | ConvertToNonVirtualBase: (A *)... | Call to pure virtual function during construction | -| test.cpp:35:6:35:6 | call to f | test.cpp:21:3:21:3 | InitializeParameter: C | test.cpp:35:3:35:3 | ConvertToNonVirtualBase: (A *)... | Call to pure virtual function during construction | +| test.cpp:12:7:12:7 | call to f | test.cpp:31:3:31:3 | this | test.cpp:12:5:12:5 | (A)... | Call to pure virtual function during construction | +| test.cpp:16:5:16:5 | call to f | test.cpp:15:3:15:4 | this | file://:0:0:0:0 | (A *)... | Call to pure virtual function during destruction | +| test.cpp:25:13:25:13 | call to f | test.cpp:21:3:21:3 | this | test.cpp:25:7:25:10 | (A *)... | Call to pure virtual function during construction | +| test.cpp:35:6:35:6 | call to f | test.cpp:7:3:7:3 | this | test.cpp:35:3:35:3 | (A *)... | Call to pure virtual function during construction | +| test.cpp:35:6:35:6 | call to f | test.cpp:21:3:21:3 | this | test.cpp:35:3:35:3 | (A *)... | Call to pure virtual function during construction | diff --git a/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ReturnStackAllocatedMemory/ReturnStackAllocatedMemory.expected b/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ReturnStackAllocatedMemory/ReturnStackAllocatedMemory.expected index 8f9d91fc1ad..6b8a59793a3 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ReturnStackAllocatedMemory/ReturnStackAllocatedMemory.expected +++ b/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ReturnStackAllocatedMemory/ReturnStackAllocatedMemory.expected @@ -100,6 +100,12 @@ edges | test.cpp:190:10:190:13 | Unary | test.cpp:190:10:190:13 | (reference dereference) | | test.cpp:190:10:190:13 | Unary | test.cpp:190:10:190:13 | (reference to) | | test.cpp:190:10:190:13 | pRef | test.cpp:190:10:190:13 | Unary | +| test.cpp:225:14:225:15 | px | test.cpp:226:10:226:11 | Load | +| test.cpp:226:10:226:11 | Load | test.cpp:226:10:226:11 | px | +| test.cpp:226:10:226:11 | px | test.cpp:226:10:226:11 | StoreValue | +| test.cpp:231:16:231:17 | & ... | test.cpp:225:14:225:15 | px | +| test.cpp:231:17:231:17 | Unary | test.cpp:231:16:231:17 | & ... | +| test.cpp:231:17:231:17 | x | test.cpp:231:17:231:17 | Unary | nodes | test.cpp:17:9:17:11 | & ... | semmle.label | & ... | | test.cpp:17:9:17:11 | StoreValue | semmle.label | StoreValue | @@ -215,6 +221,13 @@ nodes | test.cpp:190:10:190:13 | Unary | semmle.label | Unary | | test.cpp:190:10:190:13 | Unary | semmle.label | Unary | | test.cpp:190:10:190:13 | pRef | semmle.label | pRef | +| test.cpp:225:14:225:15 | px | semmle.label | px | +| test.cpp:226:10:226:11 | Load | semmle.label | Load | +| test.cpp:226:10:226:11 | StoreValue | semmle.label | StoreValue | +| test.cpp:226:10:226:11 | px | semmle.label | px | +| test.cpp:231:16:231:17 | & ... | semmle.label | & ... | +| test.cpp:231:17:231:17 | Unary | semmle.label | Unary | +| test.cpp:231:17:231:17 | x | semmle.label | x | #select | test.cpp:17:9:17:11 | StoreValue | test.cpp:17:10:17:11 | mc | test.cpp:17:9:17:11 | StoreValue | May return stack-allocated memory from $@. | test.cpp:17:10:17:11 | mc | mc | | test.cpp:25:9:25:11 | StoreValue | test.cpp:23:18:23:19 | mc | test.cpp:25:9:25:11 | StoreValue | May return stack-allocated memory from $@. | test.cpp:23:18:23:19 | mc | mc | diff --git a/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ReturnStackAllocatedMemory/test.cpp b/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ReturnStackAllocatedMemory/test.cpp index a1726169654..2b53f9c0adf 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ReturnStackAllocatedMemory/test.cpp +++ b/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ReturnStackAllocatedMemory/test.cpp @@ -220,4 +220,13 @@ auto make_read_port() void* get_sp() { int p; return (void*)&p; // GOOD: The function name makes it sound like the programmer intended to get the value of the stack pointer. +} + +int* id(int* px) { + return px; // GOOD +} + +void f() { + int x; + int* px = id(&x); // GOOD } \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverflowDestination.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverflowDestination.expected index e69de29bb2d..e217064d1df 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverflowDestination.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverflowDestination.expected @@ -0,0 +1,4 @@ +edges +nodes +subpaths +#select diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/OverflowDestination.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/OverflowDestination.expected index 7f79034b954..2a9b25cb541 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/OverflowDestination.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/OverflowDestination.expected @@ -1,4 +1,43 @@ -| overflowdestination.cpp:30:2:30:8 | call to strncpy | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. | -| overflowdestination.cpp:46:2:46:7 | call to memcpy | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. | -| overflowdestination.cpp:53:2:53:7 | call to memcpy | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. | -| overflowdestination.cpp:64:2:64:7 | call to memcpy | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. | +edges +| overflowdestination.cpp:27:9:27:12 | argv | overflowdestination.cpp:30:17:30:20 | (const char *)... | +| overflowdestination.cpp:43:8:43:10 | fgets output argument | overflowdestination.cpp:46:15:46:17 | (const void *)... | +| overflowdestination.cpp:50:52:50:54 | *src | overflowdestination.cpp:50:52:50:54 | ReturnIndirection | +| overflowdestination.cpp:50:52:50:54 | src | overflowdestination.cpp:53:15:53:17 | (const void *)... | +| overflowdestination.cpp:57:52:57:54 | *src | overflowdestination.cpp:64:16:64:19 | (const void *)... | +| overflowdestination.cpp:57:52:57:54 | src | overflowdestination.cpp:64:16:64:19 | (const void *)... | +| overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:75:30:75:32 | src | +| overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:75:30:75:32 | src indirection | +| overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:76:30:76:32 | src | +| overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:76:30:76:32 | src indirection | +| overflowdestination.cpp:75:30:75:32 | overflowdest_test2 output argument | overflowdestination.cpp:76:30:76:32 | src | +| overflowdestination.cpp:75:30:75:32 | overflowdest_test2 output argument | overflowdestination.cpp:76:30:76:32 | src indirection | +| overflowdestination.cpp:75:30:75:32 | src | overflowdestination.cpp:50:52:50:54 | src | +| overflowdestination.cpp:75:30:75:32 | src indirection | overflowdestination.cpp:50:52:50:54 | *src | +| overflowdestination.cpp:75:30:75:32 | src indirection | overflowdestination.cpp:75:30:75:32 | overflowdest_test2 output argument | +| overflowdestination.cpp:76:30:76:32 | src | overflowdestination.cpp:57:52:57:54 | src | +| overflowdestination.cpp:76:30:76:32 | src indirection | overflowdestination.cpp:57:52:57:54 | *src | +nodes +| overflowdestination.cpp:27:9:27:12 | argv | semmle.label | argv | +| overflowdestination.cpp:30:17:30:20 | (const char *)... | semmle.label | (const char *)... | +| overflowdestination.cpp:43:8:43:10 | fgets output argument | semmle.label | fgets output argument | +| overflowdestination.cpp:46:15:46:17 | (const void *)... | semmle.label | (const void *)... | +| overflowdestination.cpp:50:52:50:54 | *src | semmle.label | *src | +| overflowdestination.cpp:50:52:50:54 | ReturnIndirection | semmle.label | ReturnIndirection | +| overflowdestination.cpp:50:52:50:54 | src | semmle.label | src | +| overflowdestination.cpp:53:15:53:17 | (const void *)... | semmle.label | (const void *)... | +| overflowdestination.cpp:57:52:57:54 | *src | semmle.label | *src | +| overflowdestination.cpp:57:52:57:54 | src | semmle.label | src | +| overflowdestination.cpp:64:16:64:19 | (const void *)... | semmle.label | (const void *)... | +| overflowdestination.cpp:73:8:73:10 | fgets output argument | semmle.label | fgets output argument | +| overflowdestination.cpp:75:30:75:32 | overflowdest_test2 output argument | semmle.label | overflowdest_test2 output argument | +| overflowdestination.cpp:75:30:75:32 | src | semmle.label | src | +| overflowdestination.cpp:75:30:75:32 | src indirection | semmle.label | src indirection | +| overflowdestination.cpp:76:30:76:32 | src | semmle.label | src | +| overflowdestination.cpp:76:30:76:32 | src indirection | semmle.label | src indirection | +subpaths +| overflowdestination.cpp:75:30:75:32 | src indirection | overflowdestination.cpp:50:52:50:54 | *src | overflowdestination.cpp:50:52:50:54 | ReturnIndirection | overflowdestination.cpp:75:30:75:32 | overflowdest_test2 output argument | +#select +| overflowdestination.cpp:30:2:30:8 | call to strncpy | overflowdestination.cpp:27:9:27:12 | argv | overflowdestination.cpp:30:17:30:20 | (const char *)... | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. | +| overflowdestination.cpp:46:2:46:7 | call to memcpy | overflowdestination.cpp:43:8:43:10 | fgets output argument | overflowdestination.cpp:46:15:46:17 | (const void *)... | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. | +| overflowdestination.cpp:53:2:53:7 | call to memcpy | overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:53:15:53:17 | (const void *)... | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. | +| overflowdestination.cpp:64:2:64:7 | call to memcpy | overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:64:16:64:19 | (const void *)... | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-129/SAMATE/ImproperArrayIndexValidation/ImproperArrayIndexValidation.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-129/SAMATE/ImproperArrayIndexValidation/ImproperArrayIndexValidation.expected index 008ff07b800..5f8be65d740 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-129/SAMATE/ImproperArrayIndexValidation/ImproperArrayIndexValidation.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-129/SAMATE/ImproperArrayIndexValidation/ImproperArrayIndexValidation.expected @@ -1 +1,8 @@ -| CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_01.c:52:20:52:23 | data | $@ flows to here and is used in an array indexing expression, potentially causing an invalid access. | CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_01.c:30:19:30:29 | inputBuffer | User-provided value | +edges +| CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_01.c:30:19:30:29 | fgets output argument | CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_01.c:52:20:52:23 | data | +nodes +| CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_01.c:30:19:30:29 | fgets output argument | semmle.label | fgets output argument | +| CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_01.c:52:20:52:23 | data | semmle.label | data | +subpaths +#select +| CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_01.c:52:20:52:23 | data | CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_01.c:30:19:30:29 | fgets output argument | CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_01.c:52:20:52:23 | data | $@ flows to here and is used in an array indexing expression, potentially causing an invalid access. | CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_01.c:30:19:30:29 | fgets output argument | String read by fgets | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-129/semmle/ImproperArrayIndexValidation/ImproperArrayIndexValidation.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-129/semmle/ImproperArrayIndexValidation/ImproperArrayIndexValidation.expected index 8efbc165c86..97aa43e7bd1 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-129/semmle/ImproperArrayIndexValidation/ImproperArrayIndexValidation.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-129/semmle/ImproperArrayIndexValidation/ImproperArrayIndexValidation.expected @@ -1,3 +1,26 @@ -| test1.c:18:16:18:16 | i | $@ flows to here and is used in an array indexing expression, potentially causing an invalid access. | test1.c:8:16:8:19 | argv | User-provided value | -| test1.c:33:11:33:11 | i | $@ flows to here and is used in an array indexing expression, potentially causing an invalid access. | test1.c:8:16:8:19 | argv | User-provided value | -| test1.c:53:15:53:15 | j | $@ flows to here and is used in an array indexing expression, potentially causing an invalid access. | test1.c:8:16:8:19 | argv | User-provided value | +edges +| test1.c:8:16:8:19 | argv | test1.c:9:9:9:9 | i | +| test1.c:8:16:8:19 | argv | test1.c:11:9:11:9 | i | +| test1.c:8:16:8:19 | argv | test1.c:13:9:13:9 | i | +| test1.c:9:9:9:9 | i | test1.c:16:16:16:16 | i | +| test1.c:11:9:11:9 | i | test1.c:32:16:32:16 | i | +| test1.c:13:9:13:9 | i | test1.c:48:16:48:16 | i | +| test1.c:16:16:16:16 | i | test1.c:18:16:18:16 | i | +| test1.c:32:16:32:16 | i | test1.c:33:11:33:11 | i | +| test1.c:48:16:48:16 | i | test1.c:53:15:53:15 | j | +nodes +| test1.c:8:16:8:19 | argv | semmle.label | argv | +| test1.c:9:9:9:9 | i | semmle.label | i | +| test1.c:11:9:11:9 | i | semmle.label | i | +| test1.c:13:9:13:9 | i | semmle.label | i | +| test1.c:16:16:16:16 | i | semmle.label | i | +| test1.c:18:16:18:16 | i | semmle.label | i | +| test1.c:32:16:32:16 | i | semmle.label | i | +| test1.c:33:11:33:11 | i | semmle.label | i | +| test1.c:48:16:48:16 | i | semmle.label | i | +| test1.c:53:15:53:15 | j | semmle.label | j | +subpaths +#select +| test1.c:18:16:18:16 | i | test1.c:8:16:8:19 | argv | test1.c:18:16:18:16 | i | $@ flows to here and is used in an array indexing expression, potentially causing an invalid access. | test1.c:8:16:8:19 | argv | a command-line argument | +| test1.c:33:11:33:11 | i | test1.c:8:16:8:19 | argv | test1.c:33:11:33:11 | i | $@ flows to here and is used in an array indexing expression, potentially causing an invalid access. | test1.c:8:16:8:19 | argv | a command-line argument | +| test1.c:53:15:53:15 | j | test1.c:8:16:8:19 | argv | test1.c:53:15:53:15 | j | $@ flows to here and is used in an array indexing expression, potentially causing an invalid access. | test1.c:8:16:8:19 | argv | a command-line argument | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/TaintedAllocationSize/TaintedAllocationSize.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/TaintedAllocationSize/TaintedAllocationSize.expected index 2bee2123b7c..aa131cca152 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/TaintedAllocationSize/TaintedAllocationSize.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/TaintedAllocationSize/TaintedAllocationSize.expected @@ -1,62 +1,20 @@ edges -| test.cpp:40:21:40:24 | argv | test.cpp:43:38:43:44 | (size_t)... | -| test.cpp:40:21:40:24 | argv | test.cpp:43:38:43:44 | (size_t)... | -| test.cpp:40:21:40:24 | argv | test.cpp:43:38:43:44 | tainted | -| test.cpp:40:21:40:24 | argv | test.cpp:43:38:43:44 | tainted | -| test.cpp:40:21:40:24 | argv | test.cpp:43:38:43:44 | tainted | | test.cpp:40:21:40:24 | argv | test.cpp:43:38:43:44 | tainted | | test.cpp:40:21:40:24 | argv | test.cpp:44:38:44:63 | ... * ... | -| test.cpp:40:21:40:24 | argv | test.cpp:44:38:44:63 | ... * ... | -| test.cpp:40:21:40:24 | argv | test.cpp:44:38:44:63 | ... * ... | -| test.cpp:40:21:40:24 | argv | test.cpp:44:38:44:63 | ... * ... | | test.cpp:40:21:40:24 | argv | test.cpp:46:38:46:63 | ... + ... | -| test.cpp:40:21:40:24 | argv | test.cpp:46:38:46:63 | ... + ... | -| test.cpp:40:21:40:24 | argv | test.cpp:46:38:46:63 | ... + ... | -| test.cpp:40:21:40:24 | argv | test.cpp:46:38:46:63 | ... + ... | -| test.cpp:40:21:40:24 | argv | test.cpp:49:32:49:35 | (size_t)... | -| test.cpp:40:21:40:24 | argv | test.cpp:49:32:49:35 | (size_t)... | -| test.cpp:40:21:40:24 | argv | test.cpp:49:32:49:35 | size | -| test.cpp:40:21:40:24 | argv | test.cpp:49:32:49:35 | size | -| test.cpp:40:21:40:24 | argv | test.cpp:49:32:49:35 | size | | test.cpp:40:21:40:24 | argv | test.cpp:49:32:49:35 | size | | test.cpp:40:21:40:24 | argv | test.cpp:50:26:50:29 | size | -| test.cpp:40:21:40:24 | argv | test.cpp:50:26:50:29 | size | -| test.cpp:40:21:40:24 | argv | test.cpp:50:26:50:29 | size | -| test.cpp:40:21:40:24 | argv | test.cpp:50:26:50:29 | size | -| test.cpp:40:21:40:24 | argv | test.cpp:53:35:53:60 | ... * ... | -| test.cpp:40:21:40:24 | argv | test.cpp:53:35:53:60 | ... * ... | -| test.cpp:40:21:40:24 | argv | test.cpp:53:35:53:60 | ... * ... | | test.cpp:40:21:40:24 | argv | test.cpp:53:35:53:60 | ... * ... | | test.cpp:124:18:124:23 | call to getenv | test.cpp:128:24:128:41 | ... * ... | -| test.cpp:124:18:124:23 | call to getenv | test.cpp:128:24:128:41 | ... * ... | -| test.cpp:124:18:124:31 | (const char *)... | test.cpp:128:24:128:41 | ... * ... | -| test.cpp:124:18:124:31 | (const char *)... | test.cpp:128:24:128:41 | ... * ... | | test.cpp:133:19:133:24 | call to getenv | test.cpp:135:10:135:27 | ... * ... | -| test.cpp:133:19:133:24 | call to getenv | test.cpp:135:10:135:27 | ... * ... | -| test.cpp:133:19:133:32 | (const char *)... | test.cpp:135:10:135:27 | ... * ... | -| test.cpp:133:19:133:32 | (const char *)... | test.cpp:135:10:135:27 | ... * ... | | test.cpp:148:20:148:25 | call to getenv | test.cpp:152:11:152:28 | ... * ... | -| test.cpp:148:20:148:25 | call to getenv | test.cpp:152:11:152:28 | ... * ... | -| test.cpp:148:20:148:33 | (const char *)... | test.cpp:152:11:152:28 | ... * ... | -| test.cpp:148:20:148:33 | (const char *)... | test.cpp:152:11:152:28 | ... * ... | -| test.cpp:209:8:209:23 | ReturnValue | test.cpp:241:9:241:24 | call to get_tainted_size | | test.cpp:209:8:209:23 | ReturnValue | test.cpp:241:9:241:24 | call to get_tainted_size | | test.cpp:211:14:211:19 | call to getenv | test.cpp:209:8:209:23 | ReturnValue | -| test.cpp:211:14:211:27 | (const char *)... | test.cpp:209:8:209:23 | ReturnValue | -| test.cpp:224:23:224:23 | s | test.cpp:225:21:225:21 | s | | test.cpp:224:23:224:23 | s | test.cpp:225:21:225:21 | s | | test.cpp:230:21:230:21 | s | test.cpp:231:21:231:21 | s | -| test.cpp:230:21:230:21 | s | test.cpp:231:21:231:21 | s | -| test.cpp:237:24:237:29 | call to getenv | test.cpp:239:9:239:18 | (size_t)... | -| test.cpp:237:24:237:29 | call to getenv | test.cpp:239:9:239:18 | local_size | | test.cpp:237:24:237:29 | call to getenv | test.cpp:239:9:239:18 | local_size | | test.cpp:237:24:237:29 | call to getenv | test.cpp:245:11:245:20 | local_size | | test.cpp:237:24:237:29 | call to getenv | test.cpp:247:10:247:19 | local_size | -| test.cpp:237:24:237:37 | (const char *)... | test.cpp:239:9:239:18 | (size_t)... | -| test.cpp:237:24:237:37 | (const char *)... | test.cpp:239:9:239:18 | local_size | -| test.cpp:237:24:237:37 | (const char *)... | test.cpp:239:9:239:18 | local_size | -| test.cpp:237:24:237:37 | (const char *)... | test.cpp:245:11:245:20 | local_size | -| test.cpp:237:24:237:37 | (const char *)... | test.cpp:247:10:247:19 | local_size | | test.cpp:245:11:245:20 | local_size | test.cpp:224:23:224:23 | s | | test.cpp:247:10:247:19 | local_size | test.cpp:230:21:230:21 | s | | test.cpp:251:2:251:9 | (reference dereference) [post update] | test.cpp:289:17:289:20 | size [post update] | @@ -64,112 +22,57 @@ edges | test.cpp:251:18:251:23 | call to getenv | test.cpp:251:2:251:9 | (reference dereference) [post update] | | test.cpp:251:18:251:23 | call to getenv | test.cpp:289:17:289:20 | size [post update] | | test.cpp:251:18:251:23 | call to getenv | test.cpp:305:18:305:21 | size [post update] | -| test.cpp:251:18:251:31 | (const char *)... | test.cpp:251:2:251:9 | (reference dereference) [post update] | -| test.cpp:251:18:251:31 | (const char *)... | test.cpp:289:17:289:20 | size [post update] | -| test.cpp:251:18:251:31 | (const char *)... | test.cpp:305:18:305:21 | size [post update] | | test.cpp:259:20:259:25 | call to getenv | test.cpp:263:11:263:29 | ... * ... | -| test.cpp:259:20:259:25 | call to getenv | test.cpp:263:11:263:29 | ... * ... | -| test.cpp:259:20:259:33 | (const char *)... | test.cpp:263:11:263:29 | ... * ... | -| test.cpp:259:20:259:33 | (const char *)... | test.cpp:263:11:263:29 | ... * ... | -| test.cpp:289:17:289:20 | size [post update] | test.cpp:291:11:291:28 | ... * ... | | test.cpp:289:17:289:20 | size [post update] | test.cpp:291:11:291:28 | ... * ... | | test.cpp:305:18:305:21 | size [post update] | test.cpp:308:10:308:27 | ... * ... | -| test.cpp:305:18:305:21 | size [post update] | test.cpp:308:10:308:27 | ... * ... | -subpaths nodes | test.cpp:40:21:40:24 | argv | semmle.label | argv | -| test.cpp:40:21:40:24 | argv | semmle.label | argv | -| test.cpp:43:38:43:44 | (size_t)... | semmle.label | (size_t)... | -| test.cpp:43:38:43:44 | (size_t)... | semmle.label | (size_t)... | -| test.cpp:43:38:43:44 | tainted | semmle.label | tainted | -| test.cpp:43:38:43:44 | tainted | semmle.label | tainted | | test.cpp:43:38:43:44 | tainted | semmle.label | tainted | | test.cpp:44:38:44:63 | ... * ... | semmle.label | ... * ... | -| test.cpp:44:38:44:63 | ... * ... | semmle.label | ... * ... | -| test.cpp:44:38:44:63 | ... * ... | semmle.label | ... * ... | | test.cpp:46:38:46:63 | ... + ... | semmle.label | ... + ... | -| test.cpp:46:38:46:63 | ... + ... | semmle.label | ... + ... | -| test.cpp:46:38:46:63 | ... + ... | semmle.label | ... + ... | -| test.cpp:49:32:49:35 | (size_t)... | semmle.label | (size_t)... | -| test.cpp:49:32:49:35 | (size_t)... | semmle.label | (size_t)... | -| test.cpp:49:32:49:35 | size | semmle.label | size | -| test.cpp:49:32:49:35 | size | semmle.label | size | | test.cpp:49:32:49:35 | size | semmle.label | size | | test.cpp:50:26:50:29 | size | semmle.label | size | -| test.cpp:50:26:50:29 | size | semmle.label | size | -| test.cpp:50:26:50:29 | size | semmle.label | size | -| test.cpp:53:35:53:60 | ... * ... | semmle.label | ... * ... | -| test.cpp:53:35:53:60 | ... * ... | semmle.label | ... * ... | | test.cpp:53:35:53:60 | ... * ... | semmle.label | ... * ... | | test.cpp:124:18:124:23 | call to getenv | semmle.label | call to getenv | -| test.cpp:124:18:124:31 | (const char *)... | semmle.label | (const char *)... | -| test.cpp:128:24:128:41 | ... * ... | semmle.label | ... * ... | -| test.cpp:128:24:128:41 | ... * ... | semmle.label | ... * ... | | test.cpp:128:24:128:41 | ... * ... | semmle.label | ... * ... | | test.cpp:133:19:133:24 | call to getenv | semmle.label | call to getenv | -| test.cpp:133:19:133:32 | (const char *)... | semmle.label | (const char *)... | -| test.cpp:135:10:135:27 | ... * ... | semmle.label | ... * ... | -| test.cpp:135:10:135:27 | ... * ... | semmle.label | ... * ... | | test.cpp:135:10:135:27 | ... * ... | semmle.label | ... * ... | | test.cpp:148:20:148:25 | call to getenv | semmle.label | call to getenv | -| test.cpp:148:20:148:33 | (const char *)... | semmle.label | (const char *)... | -| test.cpp:152:11:152:28 | ... * ... | semmle.label | ... * ... | -| test.cpp:152:11:152:28 | ... * ... | semmle.label | ... * ... | | test.cpp:152:11:152:28 | ... * ... | semmle.label | ... * ... | | test.cpp:209:8:209:23 | ReturnValue | semmle.label | ReturnValue | | test.cpp:211:14:211:19 | call to getenv | semmle.label | call to getenv | -| test.cpp:211:14:211:27 | (const char *)... | semmle.label | (const char *)... | | test.cpp:224:23:224:23 | s | semmle.label | s | | test.cpp:225:21:225:21 | s | semmle.label | s | -| test.cpp:225:21:225:21 | s | semmle.label | s | -| test.cpp:225:21:225:21 | s | semmle.label | s | | test.cpp:230:21:230:21 | s | semmle.label | s | | test.cpp:231:21:231:21 | s | semmle.label | s | -| test.cpp:231:21:231:21 | s | semmle.label | s | -| test.cpp:231:21:231:21 | s | semmle.label | s | | test.cpp:237:24:237:29 | call to getenv | semmle.label | call to getenv | -| test.cpp:237:24:237:37 | (const char *)... | semmle.label | (const char *)... | -| test.cpp:239:9:239:18 | (size_t)... | semmle.label | (size_t)... | -| test.cpp:239:9:239:18 | (size_t)... | semmle.label | (size_t)... | | test.cpp:239:9:239:18 | local_size | semmle.label | local_size | -| test.cpp:239:9:239:18 | local_size | semmle.label | local_size | -| test.cpp:239:9:239:18 | local_size | semmle.label | local_size | -| test.cpp:241:9:241:24 | call to get_tainted_size | semmle.label | call to get_tainted_size | -| test.cpp:241:9:241:24 | call to get_tainted_size | semmle.label | call to get_tainted_size | | test.cpp:241:9:241:24 | call to get_tainted_size | semmle.label | call to get_tainted_size | | test.cpp:245:11:245:20 | local_size | semmle.label | local_size | | test.cpp:247:10:247:19 | local_size | semmle.label | local_size | | test.cpp:251:2:251:9 | (reference dereference) [post update] | semmle.label | (reference dereference) [post update] | -| test.cpp:251:2:251:9 | out_size [post update] | semmle.label | out_size [post update] | | test.cpp:251:18:251:23 | call to getenv | semmle.label | call to getenv | -| test.cpp:251:18:251:31 | (const char *)... | semmle.label | (const char *)... | | test.cpp:259:20:259:25 | call to getenv | semmle.label | call to getenv | -| test.cpp:259:20:259:33 | (const char *)... | semmle.label | (const char *)... | -| test.cpp:263:11:263:29 | ... * ... | semmle.label | ... * ... | -| test.cpp:263:11:263:29 | ... * ... | semmle.label | ... * ... | | test.cpp:263:11:263:29 | ... * ... | semmle.label | ... * ... | | test.cpp:289:17:289:20 | size [post update] | semmle.label | size [post update] | | test.cpp:291:11:291:28 | ... * ... | semmle.label | ... * ... | -| test.cpp:291:11:291:28 | ... * ... | semmle.label | ... * ... | -| test.cpp:291:11:291:28 | ... * ... | semmle.label | ... * ... | | test.cpp:305:18:305:21 | size [post update] | semmle.label | size [post update] | | test.cpp:308:10:308:27 | ... * ... | semmle.label | ... * ... | -| test.cpp:308:10:308:27 | ... * ... | semmle.label | ... * ... | -| test.cpp:308:10:308:27 | ... * ... | semmle.label | ... * ... | +subpaths #select -| test.cpp:43:31:43:36 | call to malloc | test.cpp:40:21:40:24 | argv | test.cpp:43:38:43:44 | tainted | This allocation size is derived from $@ and might overflow | test.cpp:40:21:40:24 | argv | user input (argv) | -| test.cpp:44:31:44:36 | call to malloc | test.cpp:40:21:40:24 | argv | test.cpp:44:38:44:63 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:40:21:40:24 | argv | user input (argv) | -| test.cpp:46:31:46:36 | call to malloc | test.cpp:40:21:40:24 | argv | test.cpp:46:38:46:63 | ... + ... | This allocation size is derived from $@ and might overflow | test.cpp:40:21:40:24 | argv | user input (argv) | -| test.cpp:49:25:49:30 | call to malloc | test.cpp:40:21:40:24 | argv | test.cpp:49:32:49:35 | size | This allocation size is derived from $@ and might overflow | test.cpp:40:21:40:24 | argv | user input (argv) | -| test.cpp:50:17:50:30 | new[] | test.cpp:40:21:40:24 | argv | test.cpp:50:26:50:29 | size | This allocation size is derived from $@ and might overflow | test.cpp:40:21:40:24 | argv | user input (argv) | -| test.cpp:53:21:53:27 | call to realloc | test.cpp:40:21:40:24 | argv | test.cpp:53:35:53:60 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:40:21:40:24 | argv | user input (argv) | -| test.cpp:128:17:128:22 | call to malloc | test.cpp:124:18:124:23 | call to getenv | test.cpp:128:24:128:41 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:124:18:124:23 | call to getenv | user input (getenv) | -| test.cpp:135:3:135:8 | call to malloc | test.cpp:133:19:133:24 | call to getenv | test.cpp:135:10:135:27 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:133:19:133:24 | call to getenv | user input (getenv) | -| test.cpp:152:4:152:9 | call to malloc | test.cpp:148:20:148:25 | call to getenv | test.cpp:152:11:152:28 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:148:20:148:25 | call to getenv | user input (getenv) | -| test.cpp:225:14:225:19 | call to malloc | test.cpp:237:24:237:29 | call to getenv | test.cpp:225:21:225:21 | s | This allocation size is derived from $@ and might overflow | test.cpp:237:24:237:29 | call to getenv | user input (getenv) | -| test.cpp:231:14:231:19 | call to malloc | test.cpp:237:24:237:29 | call to getenv | test.cpp:231:21:231:21 | s | This allocation size is derived from $@ and might overflow | test.cpp:237:24:237:29 | call to getenv | user input (getenv) | -| test.cpp:239:2:239:7 | call to malloc | test.cpp:237:24:237:29 | call to getenv | test.cpp:239:9:239:18 | local_size | This allocation size is derived from $@ and might overflow | test.cpp:237:24:237:29 | call to getenv | user input (getenv) | -| test.cpp:241:2:241:7 | call to malloc | test.cpp:211:14:211:19 | call to getenv | test.cpp:241:9:241:24 | call to get_tainted_size | This allocation size is derived from $@ and might overflow | test.cpp:211:14:211:19 | call to getenv | user input (getenv) | -| test.cpp:263:4:263:9 | call to malloc | test.cpp:259:20:259:25 | call to getenv | test.cpp:263:11:263:29 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:259:20:259:25 | call to getenv | user input (getenv) | -| test.cpp:291:4:291:9 | call to malloc | test.cpp:251:18:251:23 | call to getenv | test.cpp:291:11:291:28 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:251:18:251:23 | call to getenv | user input (getenv) | -| test.cpp:308:3:308:8 | call to malloc | test.cpp:251:18:251:23 | call to getenv | test.cpp:308:10:308:27 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:251:18:251:23 | call to getenv | user input (getenv) | +| test.cpp:43:31:43:36 | call to malloc | test.cpp:40:21:40:24 | argv | test.cpp:43:38:43:44 | tainted | This allocation size is derived from $@ and might overflow | test.cpp:40:21:40:24 | argv | user input (a command-line argument) | +| test.cpp:44:31:44:36 | call to malloc | test.cpp:40:21:40:24 | argv | test.cpp:44:38:44:63 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:40:21:40:24 | argv | user input (a command-line argument) | +| test.cpp:46:31:46:36 | call to malloc | test.cpp:40:21:40:24 | argv | test.cpp:46:38:46:63 | ... + ... | This allocation size is derived from $@ and might overflow | test.cpp:40:21:40:24 | argv | user input (a command-line argument) | +| test.cpp:49:25:49:30 | call to malloc | test.cpp:40:21:40:24 | argv | test.cpp:49:32:49:35 | size | This allocation size is derived from $@ and might overflow | test.cpp:40:21:40:24 | argv | user input (a command-line argument) | +| test.cpp:50:17:50:30 | new[] | test.cpp:40:21:40:24 | argv | test.cpp:50:26:50:29 | size | This allocation size is derived from $@ and might overflow | test.cpp:40:21:40:24 | argv | user input (a command-line argument) | +| test.cpp:53:21:53:27 | call to realloc | test.cpp:40:21:40:24 | argv | test.cpp:53:35:53:60 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:40:21:40:24 | argv | user input (a command-line argument) | +| test.cpp:128:17:128:22 | call to malloc | test.cpp:124:18:124:23 | call to getenv | test.cpp:128:24:128:41 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:124:18:124:23 | call to getenv | user input (an environment variable) | +| test.cpp:135:3:135:8 | call to malloc | test.cpp:133:19:133:24 | call to getenv | test.cpp:135:10:135:27 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:133:19:133:24 | call to getenv | user input (an environment variable) | +| test.cpp:152:4:152:9 | call to malloc | test.cpp:148:20:148:25 | call to getenv | test.cpp:152:11:152:28 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:148:20:148:25 | call to getenv | user input (an environment variable) | +| test.cpp:225:14:225:19 | call to malloc | test.cpp:237:24:237:29 | call to getenv | test.cpp:225:21:225:21 | s | This allocation size is derived from $@ and might overflow | test.cpp:237:24:237:29 | call to getenv | user input (an environment variable) | +| test.cpp:231:14:231:19 | call to malloc | test.cpp:237:24:237:29 | call to getenv | test.cpp:231:21:231:21 | s | This allocation size is derived from $@ and might overflow | test.cpp:237:24:237:29 | call to getenv | user input (an environment variable) | +| test.cpp:239:2:239:7 | call to malloc | test.cpp:237:24:237:29 | call to getenv | test.cpp:239:9:239:18 | local_size | This allocation size is derived from $@ and might overflow | test.cpp:237:24:237:29 | call to getenv | user input (an environment variable) | +| test.cpp:241:2:241:7 | call to malloc | test.cpp:211:14:211:19 | call to getenv | test.cpp:241:9:241:24 | call to get_tainted_size | This allocation size is derived from $@ and might overflow | test.cpp:211:14:211:19 | call to getenv | user input (an environment variable) | +| test.cpp:263:4:263:9 | call to malloc | test.cpp:259:20:259:25 | call to getenv | test.cpp:263:11:263:29 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:259:20:259:25 | call to getenv | user input (an environment variable) | +| test.cpp:291:4:291:9 | call to malloc | test.cpp:251:18:251:23 | call to getenv | test.cpp:291:11:291:28 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:251:18:251:23 | call to getenv | user input (an environment variable) | +| test.cpp:308:3:308:8 | call to malloc | test.cpp:251:18:251:23 | call to getenv | test.cpp:308:10:308:27 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:251:18:251:23 | call to getenv | user input (an environment variable) | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-326/InsufficientKeySize.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-326/InsufficientKeySize.expected new file mode 100644 index 00000000000..ca20f65bec7 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-326/InsufficientKeySize.expected @@ -0,0 +1,10 @@ +edges +nodes +| test.cpp:34:45:34:48 | 1024 | semmle.label | 1024 | +| test.cpp:35:49:35:52 | 1024 | semmle.label | 1024 | +| test.cpp:37:43:37:46 | 1024 | semmle.label | 1024 | +subpaths +#select +| test.cpp:34:5:34:38 | call to EVP_PKEY_CTX_set_dsa_paramgen_bits | test.cpp:34:45:34:48 | 1024 | test.cpp:34:45:34:48 | 1024 | The key size $@ is less than the recommended key size of 2048 bits. | test.cpp:34:45:34:48 | 1024 | 1024 | +| test.cpp:35:5:35:42 | call to EVP_PKEY_CTX_set_dh_paramgen_prime_len | test.cpp:35:49:35:52 | 1024 | test.cpp:35:49:35:52 | 1024 | The key size $@ is less than the recommended key size of 2048 bits. | test.cpp:35:49:35:52 | 1024 | 1024 | +| test.cpp:37:5:37:36 | call to EVP_PKEY_CTX_set_rsa_keygen_bits | test.cpp:37:43:37:46 | 1024 | test.cpp:37:43:37:46 | 1024 | The key size $@ is less than the recommended key size of 2048 bits. | test.cpp:37:43:37:46 | 1024 | 1024 | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-326/InsufficientKeySize.qlref b/cpp/ql/test/query-tests/Security/CWE/CWE-326/InsufficientKeySize.qlref new file mode 100644 index 00000000000..e869f87150a --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-326/InsufficientKeySize.qlref @@ -0,0 +1 @@ +Security/CWE/CWE-326/InsufficientKeySize.ql \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-326/test.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-326/test.cpp new file mode 100644 index 00000000000..18780fc05c0 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-326/test.cpp @@ -0,0 +1,38 @@ + + +typedef int EVP_CIPHER; +typedef int EVP_MD; + +const EVP_CIPHER *EVP_aes_128_ctr(); +const EVP_CIPHER *EVP_aes_192_ctr(); +const EVP_CIPHER *EVP_aes_256_ctr(); + +const EVP_MD *EVP_sha224(); +const EVP_MD *EVP_sha256(); +const EVP_MD *EVP_sha384(); +const EVP_MD *EVP_sha512(); + + +class EVP_PKEY_CTX; + + // int is a curve ID rather than a bit width +int EVP_PKEY_CTX_set_ec_paramgen_curve_nid(EVP_PKEY_CTX*, int); + +int EVP_PKEY_CTX_set_dsa_paramgen_bits(EVP_PKEY_CTX*, int); +int EVP_PKEY_CTX_set_dh_paramgen_prime_len(EVP_PKEY_CTX*, int); + +// RSA sets bits per-key rather than with parameters +int EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX*, int); + +void test1(EVP_PKEY_CTX *ctx) { + EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, 2048); + EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, 2048); + // RSA sets bits per-key rather than with parameters + EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, 2048); + + // low key sizes + EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, 1024); + EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, 1024); + // RSA sets bits per-key rather than with parameters + EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, 1024); +} \ No newline at end of file diff --git a/cpp/ql/test/query-tests/jsf/4.13 Functions/AV Rule 114/test.c b/cpp/ql/test/query-tests/jsf/4.13 Functions/AV Rule 114/test.c index 82c860c6e9b..fcda0b8087a 100644 --- a/cpp/ql/test/query-tests/jsf/4.13 Functions/AV Rule 114/test.c +++ b/cpp/ql/test/query-tests/jsf/4.13 Functions/AV Rule 114/test.c @@ -1,4 +1,4 @@ - +// semmle-extractor-options: -std=c11 int f1(void) { int x = 1; return 2; @@ -99,3 +99,9 @@ int f14() { __asm__("rdtsc"); // GOOD } + +_Noreturn void f15(); + +int f16() { + f15(); // GOOD +} diff --git a/cpp/ql/test/query-tests/jsf/4.13 Functions/AV Rule 114/test.cpp b/cpp/ql/test/query-tests/jsf/4.13 Functions/AV Rule 114/test.cpp index 875c9ec4f75..c68ad23805c 100644 --- a/cpp/ql/test/query-tests/jsf/4.13 Functions/AV Rule 114/test.cpp +++ b/cpp/ql/test/query-tests/jsf/4.13 Functions/AV Rule 114/test.cpp @@ -1,4 +1,4 @@ - +// semmle-extractor-options: -std=c++11 class MyValue { public: MyValue(int _val) : val(_val) {}; @@ -164,3 +164,9 @@ int g19(int x) return x; // GOOD } + +[[noreturn]] void g20(); + +int g21() { + g20(); // GOOD +} diff --git a/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/BuildScripts.cs b/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/BuildScripts.cs index eab6df32c65..304c8a68b6f 100644 --- a/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/BuildScripts.cs +++ b/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/BuildScripts.cs @@ -51,7 +51,7 @@ namespace Semmle.Autobuild.CSharp.Tests int IBuildActions.RunProcess(string cmd, string args, string? workingDirectory, IDictionary? env, out IList stdOut) { - var pattern = cmd + " " + args; + var pattern = string.IsNullOrEmpty(args) ? cmd : cmd + " " + args; RunProcessIn.Add(pattern); if (!RunProcessOut.TryGetValue(pattern, out var str)) @@ -62,7 +62,7 @@ namespace Semmle.Autobuild.CSharp.Tests RunProcessWorkingDirectory.TryGetValue(pattern, out var wd); if (wd != workingDirectory) - throw new ArgumentException("Missing RunProcessWorkingDirectory " + pattern); + throw new ArgumentException($"Unexpected RunProcessWorkingDirectory, got {wd ?? "null"} expected {workingDirectory ?? "null"} in {pattern}"); if (!RunProcess.TryGetValue(pattern, out var ret)) throw new ArgumentException("Missing RunProcess " + pattern); @@ -72,12 +72,12 @@ namespace Semmle.Autobuild.CSharp.Tests int IBuildActions.RunProcess(string cmd, string args, string? workingDirectory, IDictionary? env) { - var pattern = cmd + " " + args; + var pattern = string.IsNullOrEmpty(args) ? cmd : cmd + " " + args; RunProcessIn.Add(pattern); RunProcessWorkingDirectory.TryGetValue(pattern, out var wd); if (wd != workingDirectory) - throw new ArgumentException("Missing RunProcessWorkingDirectory " + pattern); + throw new ArgumentException($"Unexpected RunProcessWorkingDirectory, got {wd ?? "null"} expected {workingDirectory ?? "null"} in {pattern}"); if (!RunProcess.TryGetValue(pattern, out var ret)) throw new ArgumentException("Missing RunProcess " + pattern); @@ -255,7 +255,7 @@ namespace Semmle.Autobuild.CSharp.Tests [Fact] public void TestAnd1() { - var cmd = BuildScript.Create("abc", "def ghi", false, null, null) & BuildScript.Create("odasa", null, false, null, null); + var cmd = BuildScript.Create("abc", "def ghi", false, null, null) & BuildScript.Create("codeql", null, false, null, null); actions.RunProcess["abc def ghi"] = 1; cmd.Run(actions, StartCallback, EndCallback); @@ -269,14 +269,14 @@ namespace Semmle.Autobuild.CSharp.Tests [Fact] public void TestAnd2() { - var cmd = BuildScript.Create("odasa", null, false, null, null) & BuildScript.Create("abc", "def ghi", false, null, null); + var cmd = BuildScript.Create("codeql", null, false, null, null) & BuildScript.Create("abc", "def ghi", false, null, null); actions.RunProcess["abc def ghi"] = 1; - actions.RunProcess["odasa "] = 0; + actions.RunProcess["codeql"] = 0; cmd.Run(actions, StartCallback, EndCallback); - Assert.Equal("odasa ", actions.RunProcessIn[0]); - Assert.Equal("odasa ", startCallbackIn[0]); + Assert.Equal("codeql", actions.RunProcessIn[0]); + Assert.Equal("codeql", startCallbackIn[0]); Assert.Equal("", endCallbackIn[0]); Assert.Equal(0, endCallbackReturn[0]); @@ -289,14 +289,14 @@ namespace Semmle.Autobuild.CSharp.Tests [Fact] public void TestOr1() { - var cmd = BuildScript.Create("odasa", null, false, null, null) | BuildScript.Create("abc", "def ghi", false, null, null); + var cmd = BuildScript.Create("codeql", null, false, null, null) | BuildScript.Create("abc", "def ghi", false, null, null); actions.RunProcess["abc def ghi"] = 1; - actions.RunProcess["odasa "] = 0; + actions.RunProcess["codeql"] = 0; cmd.Run(actions, StartCallback, EndCallback); - Assert.Equal("odasa ", actions.RunProcessIn[0]); - Assert.Equal("odasa ", startCallbackIn[0]); + Assert.Equal("codeql", actions.RunProcessIn[0]); + Assert.Equal("codeql", startCallbackIn[0]); Assert.Equal("", endCallbackIn[0]); Assert.Equal(0, endCallbackReturn[0]); Assert.Equal(1, endCallbackReturn.Count); @@ -305,10 +305,10 @@ namespace Semmle.Autobuild.CSharp.Tests [Fact] public void TestOr2() { - var cmd = BuildScript.Create("abc", "def ghi", false, null, null) | BuildScript.Create("odasa", null, false, null, null); + var cmd = BuildScript.Create("abc", "def ghi", false, null, null) | BuildScript.Create("codeql", null, false, null, null); actions.RunProcess["abc def ghi"] = 1; - actions.RunProcess["odasa "] = 0; + actions.RunProcess["codeql"] = 0; cmd.Run(actions, StartCallback, EndCallback); Assert.Equal("abc def ghi", actions.RunProcessIn[0]); @@ -316,8 +316,8 @@ namespace Semmle.Autobuild.CSharp.Tests Assert.Equal("", endCallbackIn[0]); Assert.Equal(1, endCallbackReturn[0]); - Assert.Equal("odasa ", actions.RunProcessIn[1]); - Assert.Equal("odasa ", startCallbackIn[1]); + Assert.Equal("codeql", actions.RunProcessIn[1]); + Assert.Equal("codeql", startCallbackIn[1]); Assert.Equal("", endCallbackIn[1]); Assert.Equal(0, endCallbackReturn[1]); } @@ -385,9 +385,6 @@ namespace Semmle.Autobuild.CSharp.Tests actions.GetEnvironmentVariable[$"CODEQL_EXTRACTOR_{codeqlUpperLanguage}_ROOT"] = $@"C:\codeql\{codeqlUpperLanguage.ToLowerInvariant()}"; actions.GetEnvironmentVariable["CODEQL_JAVA_HOME"] = @"C:\codeql\tools\java"; actions.GetEnvironmentVariable["CODEQL_PLATFORM"] = isWindows ? "win64" : "linux64"; - actions.GetEnvironmentVariable["SEMMLE_DIST"] = @"C:\odasa"; - actions.GetEnvironmentVariable["SEMMLE_JAVA_HOME"] = @"C:\odasa\tools\java"; - actions.GetEnvironmentVariable["SEMMLE_PLATFORM_TOOLS"] = @"C:\odasa\tools"; actions.GetEnvironmentVariable["LGTM_INDEX_VSTOOLS_VERSION"] = vsToolsVersion; actions.GetEnvironmentVariable["LGTM_INDEX_MSBUILD_ARGUMENTS"] = msBuildArguments; actions.GetEnvironmentVariable["LGTM_INDEX_MSBUILD_PLATFORM"] = msBuildPlatform; @@ -416,7 +413,7 @@ namespace Semmle.Autobuild.CSharp.Tests actions.RunProcess["cmd.exe /C dotnet --info"] = 0; actions.RunProcess[@"cmd.exe /C dotnet clean C:\Project\test.csproj"] = 0; actions.RunProcess[@"cmd.exe /C dotnet restore C:\Project\test.csproj"] = 0; - actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --auto dotnet build --no-incremental /p:UseSharedCompilation=false C:\Project\test.csproj"] = 0; + actions.RunProcess[@"cmd.exe /C dotnet build --no-incremental /p:UseSharedCompilation=false C:\Project\test.csproj"] = 0; actions.FileExists["csharp.log"] = true; actions.FileExists[@"C:\Project\test.csproj"] = true; actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = ""; @@ -443,7 +440,7 @@ namespace Semmle.Autobuild.CSharp.Tests actions.RunProcess["dotnet --info"] = 0; actions.RunProcess[@"dotnet clean C:\Project/test.csproj"] = 0; actions.RunProcess[@"dotnet restore C:\Project/test.csproj"] = 0; - actions.RunProcess[@"C:\odasa/tools/odasa index --auto dotnet build --no-incremental /p:UseSharedCompilation=false C:\Project/test.csproj"] = 0; + actions.RunProcess[@"dotnet build --no-incremental /p:UseSharedCompilation=false C:\Project/test.csproj"] = 0; actions.FileExists["csharp.log"] = true; actions.FileExists[@"C:\Project/test.csproj"] = true; actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = ""; @@ -601,7 +598,7 @@ namespace Semmle.Autobuild.CSharp.Tests [Fact] public void TestLinuxBuildCommand() { - actions.RunProcess[@"C:\odasa/tools/odasa index --auto ""./build.sh --skip-tests"""] = 0; + actions.RunProcess["./build.sh --skip-tests"] = 0; actions.FileExists["csharp.log"] = true; actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = ""; actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_SOURCE_ARCHIVE_DIR"] = ""; @@ -622,8 +619,8 @@ namespace Semmle.Autobuild.CSharp.Tests actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = ""; actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_SOURCE_ARCHIVE_DIR"] = ""; actions.RunProcess[@"/bin/chmod u+x C:\Project/build/build.sh"] = 0; - actions.RunProcess[@"C:\odasa/tools/odasa index --auto C:\Project/build/build.sh"] = 0; - actions.RunProcessWorkingDirectory[@"C:\odasa/tools/odasa index --auto C:\Project/build/build.sh"] = @"C:\Project/build"; + actions.RunProcess[@"C:\Project/build/build.sh"] = 0; + actions.RunProcessWorkingDirectory[@"C:\Project/build/build.sh"] = @"C:\Project/build"; actions.FileExists["csharp.log"] = true; var autobuilder = CreateAutoBuilder(false); @@ -639,8 +636,8 @@ namespace Semmle.Autobuild.CSharp.Tests actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_SOURCE_ARCHIVE_DIR"] = ""; actions.RunProcess[@"/bin/chmod u+x C:\Project/build.sh"] = 0; - actions.RunProcess[@"C:\odasa/tools/odasa index --auto C:\Project/build.sh"] = 0; - actions.RunProcessWorkingDirectory[@"C:\odasa/tools/odasa index --auto C:\Project/build.sh"] = @"C:\Project"; + actions.RunProcess[@"C:\Project/build.sh"] = 0; + actions.RunProcessWorkingDirectory[@"C:\Project/build.sh"] = @"C:\Project"; actions.FileExists["csharp.log"] = false; var autobuilder = CreateAutoBuilder(false); @@ -656,8 +653,8 @@ namespace Semmle.Autobuild.CSharp.Tests actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_SOURCE_ARCHIVE_DIR"] = ""; actions.RunProcess[@"/bin/chmod u+x C:\Project/build.sh"] = 0; - actions.RunProcess[@"C:\odasa/tools/odasa index --auto C:\Project/build.sh"] = 5; - actions.RunProcessWorkingDirectory[@"C:\odasa/tools/odasa index --auto C:\Project/build.sh"] = @"C:\Project"; + actions.RunProcess[@"C:\Project/build.sh"] = 5; + actions.RunProcessWorkingDirectory[@"C:\Project/build.sh"] = @"C:\Project"; actions.FileExists["csharp.log"] = true; var autobuilder = CreateAutoBuilder(false); @@ -671,8 +668,8 @@ namespace Semmle.Autobuild.CSharp.Tests actions.EnumerateDirectories[@"C:\Project"] = ""; actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = ""; actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_SOURCE_ARCHIVE_DIR"] = ""; - actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --auto C:\Project\build.bat"] = 0; - actions.RunProcessWorkingDirectory[@"cmd.exe /C C:\odasa\tools\odasa index --auto C:\Project\build.bat"] = @"C:\Project"; + actions.RunProcess[@"cmd.exe /C C:\Project\build.bat"] = 0; + actions.RunProcessWorkingDirectory[@"cmd.exe /C C:\Project\build.bat"] = @"C:\Project"; actions.FileExists["csharp.log"] = true; var autobuilder = CreateAutoBuilder(true); @@ -686,10 +683,10 @@ namespace Semmle.Autobuild.CSharp.Tests actions.EnumerateDirectories[@"C:\Project"] = ""; actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = ""; actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_SOURCE_ARCHIVE_DIR"] = ""; - actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --auto C:\Project\build.bat"] = 1; - actions.RunProcessWorkingDirectory[@"cmd.exe /C C:\odasa\tools\odasa index --auto C:\Project\build.bat"] = @"C:\Project"; + actions.RunProcess[@"cmd.exe /C C:\Project\build.bat"] = 1; + actions.RunProcessWorkingDirectory[@"cmd.exe /C C:\Project\build.bat"] = @"C:\Project"; actions.RunProcess[@"cmd.exe /C C:\codeql\tools\java\bin\java -jar C:\codeql\csharp\tools\extractor-asp.jar ."] = 0; - actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --xml --extensions config"] = 0; + actions.RunProcess[@"cmd.exe /C C:\codeql\tools\codeql index --xml --extensions config"] = 0; actions.FileExists["csharp.log"] = true; var autobuilder = CreateAutoBuilder(true, ignoreErrors: "true"); @@ -699,9 +696,9 @@ namespace Semmle.Autobuild.CSharp.Tests [Fact] public void TestWindowsCmdIgnoreErrors() { - actions.RunProcess["cmd.exe /C C:\\odasa\\tools\\odasa index --auto ^\"build.cmd --skip-tests^\""] = 3; + actions.RunProcess["cmd.exe /C ^\"build.cmd --skip-tests^\""] = 3; actions.RunProcess[@"cmd.exe /C C:\codeql\tools\java\bin\java -jar C:\codeql\csharp\tools\extractor-asp.jar ."] = 0; - actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --xml --extensions config"] = 0; + actions.RunProcess[@"cmd.exe /C C:\codeql\tools\codeql index --xml --extensions config"] = 0; actions.FileExists["csharp.log"] = true; SkipVsWhere(); @@ -718,9 +715,9 @@ namespace Semmle.Autobuild.CSharp.Tests public void TestWindowCSharpMsBuild() { actions.RunProcess[@"cmd.exe /C C:\Project\.nuget\nuget.exe restore C:\Project\test1.sln -DisableParallelProcessing"] = 0; - actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && C:\\odasa\\tools\\odasa index --auto msbuild C:\\Project\\test1.sln /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0; + actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test1.sln /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0; actions.RunProcess[@"cmd.exe /C C:\Project\.nuget\nuget.exe restore C:\Project\test2.sln -DisableParallelProcessing"] = 0; - actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && C:\\odasa\\tools\\odasa index --auto msbuild C:\\Project\\test2.sln /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0; + actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test2.sln /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0; actions.FileExists["csharp.log"] = true; actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"] = false; actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"] = false; @@ -749,9 +746,9 @@ namespace Semmle.Autobuild.CSharp.Tests public void TestWindowCSharpMsBuildMultipleSolutions() { actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\test1.csproj -DisableParallelProcessing"] = 0; - actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && C:\\odasa\\tools\\odasa index --auto msbuild C:\\Project\\test1.csproj /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0; + actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test1.csproj /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0; actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\test2.csproj -DisableParallelProcessing"] = 0; - actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && C:\\odasa\\tools\\odasa index --auto msbuild C:\\Project\\test2.csproj /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0; + actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test2.csproj /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0; actions.FileExists["csharp.log"] = true; actions.FileExists[@"C:\Project\test1.csproj"] = true; actions.FileExists[@"C:\Project\test2.csproj"] = true; @@ -794,7 +791,7 @@ namespace Semmle.Autobuild.CSharp.Tests public void TestWindowCSharpMsBuildFailed() { actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\test1.sln -DisableParallelProcessing"] = 0; - actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && C:\\odasa\\tools\\odasa index --auto msbuild C:\\Project\\test1.sln /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 1; + actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test1.sln /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 1; actions.FileExists["csharp.log"] = true; actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"] = false; actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"] = false; @@ -820,8 +817,8 @@ namespace Semmle.Autobuild.CSharp.Tests [Fact] public void TestSkipNugetMsBuild() { - actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && C:\\odasa\\tools\\odasa index --auto msbuild C:\\Project\\test1.sln /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0; - actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && C:\\odasa\\tools\\odasa index --auto msbuild C:\\Project\\test2.sln /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0; + actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test1.sln /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0; + actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test2.sln /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0; actions.FileExists["csharp.log"] = true; actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"] = false; actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"] = false; @@ -865,7 +862,7 @@ namespace Semmle.Autobuild.CSharp.Tests actions.RunProcess["dotnet --info"] = 0; actions.RunProcess[@"dotnet clean C:\Project/test.csproj"] = 0; actions.RunProcess[@"dotnet restore C:\Project/test.csproj"] = 0; - actions.RunProcess[@"C:\odasa/tools/odasa index --auto dotnet build --no-incremental /p:UseSharedCompilation=false --no-restore C:\Project/test.csproj"] = 0; + actions.RunProcess[@"dotnet build --no-incremental /p:UseSharedCompilation=false --no-restore C:\Project/test.csproj"] = 0; actions.FileExists["csharp.log"] = true; actions.FileExists[@"C:\Project/test.csproj"] = true; actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = ""; @@ -897,7 +894,7 @@ namespace Semmle.Autobuild.CSharp.Tests actions.RunProcess[@"C:\Project/.dotnet/dotnet --info"] = 0; actions.RunProcess[@"C:\Project/.dotnet/dotnet clean C:\Project/test.csproj"] = 0; actions.RunProcess[@"C:\Project/.dotnet/dotnet restore C:\Project/test.csproj"] = 0; - actions.RunProcess[@"C:\odasa/tools/odasa index --auto C:\Project/.dotnet/dotnet build --no-incremental /p:UseSharedCompilation=false C:\Project/test.csproj"] = 0; + actions.RunProcess[@"C:\Project/.dotnet/dotnet build --no-incremental /p:UseSharedCompilation=false C:\Project/test.csproj"] = 0; actions.FileExists["csharp.log"] = true; actions.FileExists["test.csproj"] = true; actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = ""; @@ -932,7 +929,7 @@ namespace Semmle.Autobuild.CSharp.Tests actions.RunProcess[@"C:\Project/.dotnet/dotnet --info"] = 0; actions.RunProcess[@"C:\Project/.dotnet/dotnet clean C:\Project/test.csproj"] = 0; actions.RunProcess[@"C:\Project/.dotnet/dotnet restore C:\Project/test.csproj"] = 0; - actions.RunProcess[@"C:\odasa/tools/odasa index --auto C:\Project/.dotnet/dotnet build --no-incremental /p:UseSharedCompilation=false C:\Project/test.csproj"] = 0; + actions.RunProcess[@"C:\Project/.dotnet/dotnet build --no-incremental /p:UseSharedCompilation=false C:\Project/test.csproj"] = 0; actions.FileExists["csharp.log"] = true; actions.FileExists["test.csproj"] = true; actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = ""; @@ -963,7 +960,7 @@ namespace Semmle.Autobuild.CSharp.Tests actions.RunProcess[@"cmd.exe /C C:\Project\.dotnet\dotnet --info"] = 0; actions.RunProcess[@"cmd.exe /C C:\Project\.dotnet\dotnet clean C:\Project\test.csproj"] = 0; actions.RunProcess[@"cmd.exe /C C:\Project\.dotnet\dotnet restore C:\Project\test.csproj"] = 0; - actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --auto C:\Project\.dotnet\dotnet build --no-incremental /p:UseSharedCompilation=false C:\Project\test.csproj"] = 0; + actions.RunProcess[@"cmd.exe /C C:\Project\.dotnet\dotnet build --no-incremental /p:UseSharedCompilation=false C:\Project\test.csproj"] = 0; actions.FileExists["csharp.log"] = true; actions.FileExists[@"C:\Project\test.csproj"] = true; actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = ""; @@ -1011,7 +1008,7 @@ namespace Semmle.Autobuild.CSharp.Tests { actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\dirs.proj -DisableParallelProcessing"] = 1; actions.RunProcess[@"cmd.exe /C C:\Project\.nuget\nuget.exe restore C:\Project\dirs.proj -DisableParallelProcessing"] = 0; - actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && C:\\odasa\\tools\\odasa index --auto msbuild C:\\Project\\dirs.proj /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0; + actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\dirs.proj /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0; actions.FileExists["csharp.log"] = true; actions.FileExists[@"C:\Project\a\test.csproj"] = true; actions.FileExists[@"C:\Project\dirs.proj"] = true; @@ -1055,7 +1052,7 @@ namespace Semmle.Autobuild.CSharp.Tests { actions.RunProcess[@"nuget restore C:\Project/dirs.proj -DisableParallelProcessing"] = 1; actions.RunProcess[@"mono C:\Project/.nuget/nuget.exe restore C:\Project/dirs.proj -DisableParallelProcessing"] = 0; - actions.RunProcess[@"C:\odasa/tools/odasa index --auto msbuild C:\Project/dirs.proj /p:UseSharedCompilation=false /t:rebuild /p:MvcBuildViews=true"] = 0; + actions.RunProcess[@"msbuild C:\Project/dirs.proj /p:UseSharedCompilation=false /t:rebuild /p:MvcBuildViews=true"] = 0; actions.FileExists["csharp.log"] = true; actions.FileExists[@"C:\Project/a/test.csproj"] = true; actions.FileExists[@"C:\Project/dirs.proj"] = true; diff --git a/csharp/autobuilder/Semmle.Autobuild.CSharp/DotNetRule.cs b/csharp/autobuilder/Semmle.Autobuild.CSharp/DotNetRule.cs index 3d7a1168e30..18603809d34 100644 --- a/csharp/autobuilder/Semmle.Autobuild.CSharp/DotNetRule.cs +++ b/csharp/autobuilder/Semmle.Autobuild.CSharp/DotNetRule.cs @@ -240,7 +240,7 @@ namespace Semmle.Autobuild.CSharp private static BuildScript GetBuildScript(Autobuilder builder, string? dotNetPath, IDictionary? environment, string projOrSln) { var build = new CommandBuilder(builder.Actions, null, environment); - var script = builder.MaybeIndex(build, DotNetCommand(builder.Actions, dotNetPath)). + var script = build.RunCommand(DotNetCommand(builder.Actions, dotNetPath)). Argument("build"). Argument("--no-incremental"); diff --git a/csharp/autobuilder/Semmle.Autobuild.CSharp/StandaloneBuildRule.cs b/csharp/autobuilder/Semmle.Autobuild.CSharp/StandaloneBuildRule.cs index e98f94f3b44..fa6523e37ae 100644 --- a/csharp/autobuilder/Semmle.Autobuild.CSharp/StandaloneBuildRule.cs +++ b/csharp/autobuilder/Semmle.Autobuild.CSharp/StandaloneBuildRule.cs @@ -17,10 +17,6 @@ namespace Semmle.Autobuild.CSharp { standalone = builder.Actions.PathCombine(builder.CodeQLExtractorLangRoot, "tools", builder.CodeQlPlatform, "Semmle.Extraction.CSharp.Standalone"); } - else if (builder.SemmlePlatformTools is not null) - { - standalone = builder.Actions.PathCombine(builder.SemmlePlatformTools, "csharp", "Semmle.Extraction.CSharp.Standalone"); - } else { return BuildScript.Failure; diff --git a/csharp/autobuilder/Semmle.Autobuild.Shared/Autobuilder.cs b/csharp/autobuilder/Semmle.Autobuild.Shared/Autobuilder.cs index 408672f7b97..d90175d245a 100644 --- a/csharp/autobuilder/Semmle.Autobuild.Shared/Autobuilder.cs +++ b/csharp/autobuilder/Semmle.Autobuild.Shared/Autobuilder.cs @@ -190,19 +190,15 @@ namespace Semmle.Autobuild.Shared }); CodeQLExtractorLangRoot = Actions.GetEnvironmentVariable($"CODEQL_EXTRACTOR_{this.Options.Language.UpperCaseName}_ROOT"); - SemmlePlatformTools = Actions.GetEnvironmentVariable("SEMMLE_PLATFORM_TOOLS"); - CodeQlPlatform = Actions.GetEnvironmentVariable("CODEQL_PLATFORM"); TrapDir = Actions.GetEnvironmentVariable($"CODEQL_EXTRACTOR_{this.Options.Language.UpperCaseName}_TRAP_DIR") ?? - Actions.GetEnvironmentVariable("TRAP_FOLDER") ?? - throw new InvalidEnvironmentException($"The environment variable CODEQL_EXTRACTOR_{this.Options.Language.UpperCaseName}_TRAP_DIR or TRAP_FOLDER has not been set."); + throw new InvalidEnvironmentException($"The environment variable CODEQL_EXTRACTOR_{this.Options.Language.UpperCaseName}_TRAP_DIR has not been set."); SourceArchiveDir = Actions.GetEnvironmentVariable($"CODEQL_EXTRACTOR_{this.Options.Language.UpperCaseName}_SOURCE_ARCHIVE_DIR") ?? - Actions.GetEnvironmentVariable("SOURCE_ARCHIVE") ?? - throw new InvalidEnvironmentException($"The environment variable CODEQL_EXTRACTOR_{this.Options.Language.UpperCaseName}_SOURCE_ARCHIVE_DIR or SOURCE_ARCHIVE has not been set."); + throw new InvalidEnvironmentException($"The environment variable CODEQL_EXTRACTOR_{this.Options.Language.UpperCaseName}_SOURCE_ARCHIVE_DIR has not been set."); } protected string TrapDir { get; } @@ -264,34 +260,9 @@ namespace Semmle.Autobuild.Shared /// public string? CodeQLExtractorLangRoot { get; } - /// - /// Value of SEMMLE_PLATFORM_TOOLS environment variable. - /// - public string? SemmlePlatformTools { get; } - /// /// Value of CODEQL_PLATFORM environment variable. /// public string? CodeQlPlatform { get; } - - /// - /// The absolute path of the odasa executable. - /// null if we are running in CodeQL. - /// - public string? Odasa - { - get - { - var semmleDist = Actions.GetEnvironmentVariable("SEMMLE_DIST"); - return semmleDist is null ? null : Actions.PathCombine(semmleDist, "tools", "odasa"); - } - } - - /// - /// Construct a command that executed the given wrapped in - /// an odasa --index, unless indexing has been disabled, in which case - /// is run directly. - /// - public CommandBuilder MaybeIndex(CommandBuilder builder, string cmd) => Odasa is null ? builder.RunCommand(cmd) : builder.IndexCommand(Odasa, cmd); } } diff --git a/csharp/autobuilder/Semmle.Autobuild.Shared/BuildCommandAutoRule.cs b/csharp/autobuilder/Semmle.Autobuild.Shared/BuildCommandAutoRule.cs index fbb109f0b4c..b6cb0737630 100644 --- a/csharp/autobuilder/Semmle.Autobuild.Shared/BuildCommandAutoRule.cs +++ b/csharp/autobuilder/Semmle.Autobuild.Shared/BuildCommandAutoRule.cs @@ -58,7 +58,7 @@ namespace Semmle.Autobuild.Shared if (vsTools is not null) command.CallBatFile(vsTools.Path); - builder.MaybeIndex(command, scriptPath); + command.RunCommand(scriptPath); return command.Script; }); } diff --git a/csharp/autobuilder/Semmle.Autobuild.Shared/BuildCommandRule.cs b/csharp/autobuilder/Semmle.Autobuild.Shared/BuildCommandRule.cs index 453d3c4f9ad..6db4cfa139d 100644 --- a/csharp/autobuilder/Semmle.Autobuild.Shared/BuildCommandRule.cs +++ b/csharp/autobuilder/Semmle.Autobuild.Shared/BuildCommandRule.cs @@ -26,7 +26,7 @@ var vsTools = MsBuildRule.GetVcVarsBatFile(builder); if (vsTools is not null) command.CallBatFile(vsTools.Path); - builder.MaybeIndex(command, builder.Options.BuildCommand); + command.RunCommand(builder.Options.BuildCommand); return command.Script; }); diff --git a/csharp/autobuilder/Semmle.Autobuild.Shared/BuildScript.cs b/csharp/autobuilder/Semmle.Autobuild.Shared/BuildScript.cs index 679db860c49..9840d63c5e4 100644 --- a/csharp/autobuilder/Semmle.Autobuild.Shared/BuildScript.cs +++ b/csharp/autobuilder/Semmle.Autobuild.Shared/BuildScript.cs @@ -70,7 +70,7 @@ namespace Semmle.Autobuild.Shared this.environment = environment; } - public override string ToString() => exe + " " + arguments; + public override string ToString() => arguments.Length > 0 ? exe + " " + arguments : exe; public override int Run(IBuildActions actions, Action startCallback, Action exitCallBack) { diff --git a/csharp/autobuilder/Semmle.Autobuild.Shared/CommandBuilder.cs b/csharp/autobuilder/Semmle.Autobuild.Shared/CommandBuilder.cs index e3b7bdbab34..2064380772f 100644 --- a/csharp/autobuilder/Semmle.Autobuild.Shared/CommandBuilder.cs +++ b/csharp/autobuilder/Semmle.Autobuild.Shared/CommandBuilder.cs @@ -45,11 +45,6 @@ namespace Semmle.Autobuild.Shared this.silent = silent; } - private void OdasaIndex(string odasa) - { - RunCommand(odasa, "index --auto"); - } - public CommandBuilder CallBatFile(string batFile, string? argumentsOpt = null) { NextCommand(); @@ -59,21 +54,6 @@ namespace Semmle.Autobuild.Shared return this; } - /// - /// Perform odasa index on a given command or BAT file. - /// - /// The odasa executable. - /// The command to run. - /// Additional arguments. - /// this for chaining calls. - public CommandBuilder IndexCommand(string odasa, string command, string? argumentsOpt = null) - { - OdasaIndex(odasa); - QuoteArgument(command); - Argument(argumentsOpt); - return this; - } - private static readonly char[] specialChars = { ' ', '\t', '\n', '\v', '\"' }; private static readonly char[] cmdMetacharacter = { '(', ')', '%', '!', '^', '\"', '<', '>', '&', '|' }; diff --git a/csharp/autobuilder/Semmle.Autobuild.Shared/MsBuildRule.cs b/csharp/autobuilder/Semmle.Autobuild.Shared/MsBuildRule.cs index 1a938f81a32..55dbf31ba1b 100644 --- a/csharp/autobuilder/Semmle.Autobuild.Shared/MsBuildRule.cs +++ b/csharp/autobuilder/Semmle.Autobuild.Shared/MsBuildRule.cs @@ -95,7 +95,7 @@ namespace Semmle.Autobuild.Shared command.RunCommand("set Platform=&& type NUL", quoteExe: false); } - builder.MaybeIndex(command, msBuild); + command.RunCommand(msBuild); command.QuoteArgument(projectOrSolution.FullPath); command.Argument("/p:UseSharedCompilation=false"); diff --git a/csharp/config/tracer/linux/csharp-compiler-settings b/csharp/config/tracer/linux/csharp-compiler-settings deleted file mode 100644 index f62c33a450b..00000000000 --- a/csharp/config/tracer/linux/csharp-compiler-settings +++ /dev/null @@ -1,14 +0,0 @@ -**/mcs.exe: -**/csc.exe: - invoke ${env.SEMMLE_PLATFORM_TOOLS}/csharp/Semmle.Extraction.CSharp.Driver - prepend --compiler - prepend "${compiler}" - prepend --cil -**/mono*: -**/dotnet: - invoke ${odasa_tools}/extract-csharp.sh -**/msbuild: -**/xbuild: - replace yes - invoke ${compiler} - append /p:UseSharedCompilation=false diff --git a/csharp/config/tracer/linux/extract-csharp.sh b/csharp/config/tracer/linux/extract-csharp.sh deleted file mode 100755 index 00bf654d792..00000000000 --- a/csharp/config/tracer/linux/extract-csharp.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash -echo extract-csharp.sh: Called with arguments: "$@" - -extractor=$SEMMLE_PLATFORM_TOOLS/csharp/Semmle.Extraction.CSharp.Driver - -for i in "$@" -do - shift - if [[ `basename -- "$i"` =~ csc.exe|mcs.exe|csc.dll ]] - then - echo extract-csharp.sh: exec $extractor --cil $@ - exec "$extractor" --compiler $i --cil $@ - fi -done - -echo extract-csharp.sh: Not a compiler invocation diff --git a/csharp/config/tracer/windows/csharp-compiler-settings b/csharp/config/tracer/windows/csharp-compiler-settings deleted file mode 100644 index 24ffb8e37a3..00000000000 --- a/csharp/config/tracer/windows/csharp-compiler-settings +++ /dev/null @@ -1,9 +0,0 @@ -**\fakes*.exe: -**\moles*.exe: - order compiler - trace no -**\csc*.exe: - invoke ${env.SEMMLE_PLATFORM_TOOLS}\csharp\Semmle.Extraction.CSharp.Driver.exe - prepend --compiler - prepend "${compiler}" - prepend --cil diff --git a/csharp/extractor/Semmle.Extraction.CIL.Driver/Program.cs b/csharp/extractor/Semmle.Extraction.CIL.Driver/Program.cs index 9e72f560854..b4664103962 100644 --- a/csharp/extractor/Semmle.Extraction.CIL.Driver/Program.cs +++ b/csharp/extractor/Semmle.Extraction.CIL.Driver/Program.cs @@ -20,11 +20,11 @@ namespace Semmle.Extraction.CIL.Driver Console.WriteLine(" path A directory/dll/exe to analyze"); } - private static void ExtractAssembly(Layout layout, string assemblyPath, ILogger logger, CommonOptions options) + private static void ExtractAssembly(string assemblyPath, ILogger logger, CommonOptions options) { var sw = new Stopwatch(); sw.Start(); - Analyser.ExtractCIL(layout, assemblyPath, logger, options, out _, out _); + Analyser.ExtractCIL(assemblyPath, logger, options, out _, out _); sw.Stop(); logger.Log(Severity.Info, " {0} ({1})", assemblyPath, sw.Elapsed); } @@ -38,12 +38,11 @@ namespace Semmle.Extraction.CIL.Driver } var options = new ExtractorOptions(args); - var layout = new Layout(); using var logger = new ConsoleLogger(options.Verbosity); var actions = options.AssembliesToExtract .Select(asm => asm.Filename) - .Select(filename => () => ExtractAssembly(layout, filename, logger, options)) + .Select(filename => () => ExtractAssembly(filename, logger, options)) .ToArray(); foreach (var missingRef in options.MissingReferences) diff --git a/csharp/extractor/Semmle.Extraction.CIL/Analyser.cs b/csharp/extractor/Semmle.Extraction.CIL/Analyser.cs index e78843148af..e5b78592fb3 100644 --- a/csharp/extractor/Semmle.Extraction.CIL/Analyser.cs +++ b/csharp/extractor/Semmle.Extraction.CIL/Analyser.cs @@ -25,7 +25,7 @@ namespace Semmle.Extraction.CIL /// Whether to extract PDBs. /// The path of the trap file. /// Whether the file was extracted (false=cached). - public static void ExtractCIL(Layout layout, string assemblyPath, ILogger logger, CommonOptions options, out string trapFile, out bool extracted) + public static void ExtractCIL(string assemblyPath, ILogger logger, CommonOptions options, out string trapFile, out bool extracted) { trapFile = ""; extracted = false; @@ -35,8 +35,7 @@ namespace Semmle.Extraction.CIL var pathTransformer = new PathTransformer(canonicalPathCache); var extractor = new TracingExtractor(assemblyPath, logger, pathTransformer, options); var transformedAssemblyPath = pathTransformer.Transform(assemblyPath); - var project = layout.LookupProjectOrDefault(transformedAssemblyPath); - using var trapWriter = project.CreateTrapWriter(logger, transformedAssemblyPath.WithSuffix(".cil"), options.TrapCompression, discardDuplicates: true); + using var trapWriter = transformedAssemblyPath.WithSuffix(".cil").CreateTrapWriter(logger, options.TrapCompression, discardDuplicates: true); trapFile = trapWriter.TrapFile; if (!options.Cache || !System.IO.File.Exists(trapFile)) { diff --git a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Extractor.cs b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Extractor.cs new file mode 100644 index 00000000000..97a25d200f7 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Extractor.cs @@ -0,0 +1,149 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Semmle.Util; +using Semmle.Util.Logging; + +namespace Semmle.Extraction.CSharp.Standalone +{ + public static class Extractor + { + + private static IEnumerable GetResolvedReferencesStandalone(IEnumerable referencePaths, BlockingCollection references) + { + return referencePaths.Select(path => () => + { + var reference = MetadataReference.CreateFromFile(path); + references.Add(reference); + }); + } + + private static void AnalyseStandalone( + StandaloneAnalyser analyser, + IEnumerable sources, + IEnumerable referencePaths, + CommonOptions options, + IProgressMonitor progressMonitor, + Stopwatch stopwatch) + { + CSharp.Extractor.Analyse(stopwatch, analyser, options, + references => GetResolvedReferencesStandalone(referencePaths, references), + (analyser, syntaxTrees) => CSharp.Extractor.ReadSyntaxTrees(sources, analyser, null, null, syntaxTrees), + (syntaxTrees, references) => CSharpCompilation.Create("csharp.dll", syntaxTrees, references), + (compilation, options) => analyser.Initialize(compilation, options), + () => { }, + _ => { }, + () => + { + foreach (var type in analyser.MissingNamespaces) + { + progressMonitor.MissingNamespace(type); + } + + foreach (var type in analyser.MissingTypes) + { + progressMonitor.MissingType(type); + } + + progressMonitor.MissingSummary(analyser.MissingTypes.Count(), analyser.MissingNamespaces.Count()); + }); + } + + private static void ExtractStandalone( + IEnumerable sources, + IEnumerable referencePaths, + IProgressMonitor pm, + ILogger logger, + CommonOptions options) + { + var stopwatch = new Stopwatch(); + stopwatch.Start(); + + var canonicalPathCache = CanonicalPathCache.Create(logger, 1000); + var pathTransformer = new PathTransformer(canonicalPathCache); + + using var analyser = new StandaloneAnalyser(pm, logger, false, pathTransformer); + try + { + AnalyseStandalone(analyser, sources, referencePaths, options, pm, stopwatch); + } + catch (Exception ex) // lgtm[cs/catch-of-all-exceptions] + { + analyser.Logger.Log(Severity.Error, " Unhandled exception: {0}", ex); + } + } + + private class ExtractionProgress : IProgressMonitor + { + public ExtractionProgress(ILogger output) + { + logger = output; + } + + private readonly ILogger logger; + + public void Analysed(int item, int total, string source, string output, TimeSpan time, AnalysisAction action) + { + logger.Log(Severity.Info, "[{0}/{1}] {2} ({3})", item, total, source, + action == AnalysisAction.Extracted + ? time.ToString() + : action == AnalysisAction.Excluded + ? "excluded" + : "up to date"); + } + + public void MissingType(string type) + { + logger.Log(Severity.Debug, "Missing type {0}", type); + } + + public void MissingNamespace(string @namespace) + { + logger.Log(Severity.Info, "Missing namespace {0}", @namespace); + } + + public void MissingSummary(int missingTypes, int missingNamespaces) + { + logger.Log(Severity.Info, "Failed to resolve {0} types in {1} namespaces", missingTypes, missingNamespaces); + } + } + + public static ExitCode Run(Options options) + { + var stopwatch = new Stopwatch(); + stopwatch.Start(); + + using var logger = new ConsoleLogger(options.Verbosity); + logger.Log(Severity.Info, "Running C# standalone extractor"); + using var a = new Analysis(logger, options); + var sourceFileCount = a.Extraction.Sources.Count; + + if (sourceFileCount == 0) + { + logger.Log(Severity.Error, "No source files found"); + return ExitCode.Errors; + } + + if (!options.SkipExtraction) + { + using var fileLogger = CSharp.Extractor.MakeLogger(options.Verbosity, false); + + logger.Log(Severity.Info, ""); + logger.Log(Severity.Info, "Extracting..."); + ExtractStandalone( + a.Extraction.Sources, + a.References, + new ExtractionProgress(logger), + fileLogger, + options); + logger.Log(Severity.Info, $"Extraction completed in {stopwatch.Elapsed}"); + } + + return ExitCode.Ok; + } + } +} \ No newline at end of file diff --git a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Program.cs b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Program.cs index e2c973ee60f..6266eb09f93 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Program.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Program.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using Semmle.BuildAnalyser; using Semmle.Util.Logging; @@ -52,11 +53,10 @@ namespace Semmle.Extraction.CSharp.Standalone { public static int Main(string[] args) { - Extractor.SetInvariantCulture(); + CSharp.Extractor.SetInvariantCulture(); var options = Options.Create(args); // options.CIL = true; // To do: Enable this - using var output = new ConsoleLogger(options.Verbosity); if (options.Help) { @@ -67,69 +67,7 @@ namespace Semmle.Extraction.CSharp.Standalone if (options.Errors) return 1; - var start = DateTime.Now; - - output.Log(Severity.Info, "Running C# standalone extractor"); - using var a = new Analysis(output, options); - var sourceFileCount = a.Extraction.Sources.Count; - - if (sourceFileCount == 0) - { - output.Log(Severity.Error, "No source files found"); - return 1; - } - - if (!options.SkipExtraction) - { - using var fileLogger = new FileLogger(options.Verbosity, Extractor.GetCSharpLogPath()); - - output.Log(Severity.Info, ""); - output.Log(Severity.Info, "Extracting..."); - Extractor.ExtractStandalone( - a.Extraction.Sources, - a.References, - new ExtractionProgress(output), - fileLogger, - options); - output.Log(Severity.Info, $"Extraction completed in {DateTime.Now - start}"); - } - - return 0; - } - - private class ExtractionProgress : IProgressMonitor - { - public ExtractionProgress(ILogger output) - { - logger = output; - } - - private readonly ILogger logger; - - public void Analysed(int item, int total, string source, string output, TimeSpan time, AnalysisAction action) - { - logger.Log(Severity.Info, "[{0}/{1}] {2} ({3})", item, total, source, - action == AnalysisAction.Extracted - ? time.ToString() - : action == AnalysisAction.Excluded - ? "excluded" - : "up to date"); - } - - public void MissingType(string type) - { - logger.Log(Severity.Debug, "Missing type {0}", type); - } - - public void MissingNamespace(string @namespace) - { - logger.Log(Severity.Info, "Missing namespace {0}", @namespace); - } - - public void MissingSummary(int missingTypes, int missingNamespaces) - { - logger.Log(Severity.Info, "Failed to resolve {0} types in {1} namespaces", missingTypes, missingNamespaces); - } + return (int)Extractor.Run(options); } } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Runtime.cs b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Runtime.cs index 1fbe016fc76..4b76efc3d65 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Runtime.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Runtime.cs @@ -84,7 +84,7 @@ namespace Semmle.Extraction.CSharp.Standalone foreach (var r in DesktopRuntimes) yield return r; - // A bad choice if it's the self-contained runtime distributed in odasa dist. + // A bad choice if it's the self-contained runtime distributed in codeql dist. yield return ExecutingRuntime; } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/StandaloneAnalyser.cs b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/StandaloneAnalyser.cs similarity index 87% rename from csharp/extractor/Semmle.Extraction.CSharp/Extractor/StandaloneAnalyser.cs rename to csharp/extractor/Semmle.Extraction.CSharp.Standalone/StandaloneAnalyser.cs index 9173ab35217..310f7eb1553 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/StandaloneAnalyser.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/StandaloneAnalyser.cs @@ -11,10 +11,9 @@ namespace Semmle.Extraction.CSharp { } - public void InitializeStandalone(CSharpCompilation compilationIn, CommonOptions options) + public void Initialize(CSharpCompilation compilationIn, CommonOptions options) { compilation = compilationIn; - layout = new Layout(); extractor = new StandaloneExtractor(Logger, PathTransformer, options); this.options = options; LogExtractorInfo(Extraction.Extractor.Version); diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Analyser.cs b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Analyser.cs index 336a76ffbdc..a2b7669c3bb 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Analyser.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Analyser.cs @@ -18,7 +18,6 @@ namespace Semmle.Extraction.CSharp { protected Extraction.Extractor? extractor; protected CSharpCompilation? compilation; - protected Layout? layout; protected CommonOptions? options; private readonly object progressMutex = new object(); @@ -125,8 +124,7 @@ namespace Semmle.Extraction.CSharp var assemblyPath = r.FilePath!; var transformedAssemblyPath = PathTransformer.Transform(assemblyPath); - var projectLayout = layout.LookupProjectOrDefault(transformedAssemblyPath); - using var trapWriter = projectLayout.CreateTrapWriter(Logger, transformedAssemblyPath, options.TrapCompression, discardDuplicates: true); + using var trapWriter = transformedAssemblyPath.CreateTrapWriter(Logger, options.TrapCompression, discardDuplicates: true); var skipExtraction = options.Cache && File.Exists(trapWriter.TrapFile); @@ -178,7 +176,7 @@ namespace Semmle.Extraction.CSharp { var stopwatch = new Stopwatch(); stopwatch.Start(); - CIL.Analyser.ExtractCIL(layout, r.FilePath!, Logger, options, out var trapFile, out var extracted); + CIL.Analyser.ExtractCIL(r.FilePath!, Logger, options, out var trapFile, out var extracted); stopwatch.Stop(); ReportProgress(r.FilePath, trapFile, stopwatch.Elapsed, extracted ? AnalysisAction.Extracted : AnalysisAction.UpToDate); } @@ -192,44 +190,35 @@ namespace Semmle.Extraction.CSharp var sourcePath = tree.FilePath; var transformedSourcePath = PathTransformer.Transform(sourcePath); - var projectLayout = layout.LookupProjectOrNull(transformedSourcePath); - var excluded = projectLayout is null; - var trapPath = excluded ? "" : projectLayout!.GetTrapPath(Logger, transformedSourcePath, options.TrapCompression); + var trapPath = transformedSourcePath.GetTrapPath(Logger, options.TrapCompression); var upToDate = false; - if (!excluded) + // compilation.Clone() is used to allow symbols to be garbage collected. + using var trapWriter = transformedSourcePath.CreateTrapWriter(Logger, options.TrapCompression, discardDuplicates: false); + + upToDate = options.Fast && FileIsUpToDate(sourcePath, trapWriter.TrapFile); + + if (!upToDate) { - // compilation.Clone() is used to allow symbols to be garbage collected. - using var trapWriter = projectLayout!.CreateTrapWriter(Logger, transformedSourcePath, options.TrapCompression, discardDuplicates: false); + var cx = new Context(extractor, compilation.Clone(), trapWriter, new SourceScope(tree), addAssemblyTrapPrefix); + // Ensure that the file itself is populated in case the source file is totally empty + var root = tree.GetRoot(); + Entities.File.Create(cx, root.SyntaxTree.FilePath); - upToDate = options.Fast && FileIsUpToDate(sourcePath, trapWriter.TrapFile); - - if (!upToDate) + var csNode = (CSharpSyntaxNode)root; + var directiveVisitor = new DirectiveVisitor(cx); + csNode.Accept(directiveVisitor); + foreach (var branch in directiveVisitor.BranchesTaken) { - var cx = new Context(extractor, compilation.Clone(), trapWriter, new SourceScope(tree), addAssemblyTrapPrefix); - // Ensure that the file itself is populated in case the source file is totally empty - var root = tree.GetRoot(); - Entities.File.Create(cx, root.SyntaxTree.FilePath); - - var csNode = (CSharpSyntaxNode)root; - var directiveVisitor = new DirectiveVisitor(cx); - csNode.Accept(directiveVisitor); - foreach (var branch in directiveVisitor.BranchesTaken) - { - cx.TrapStackSuffix.Add(branch); - } - csNode.Accept(new CompilationUnitVisitor(cx)); - cx.PopulateAll(); - CommentPopulator.ExtractCommentBlocks(cx, cx.CommentGenerator); - cx.PopulateAll(); + cx.TrapStackSuffix.Add(branch); } + csNode.Accept(new CompilationUnitVisitor(cx)); + cx.PopulateAll(); + CommentPopulator.ExtractCommentBlocks(cx, cx.CommentGenerator); + cx.PopulateAll(); } - ReportProgress(sourcePath, trapPath, stopwatch.Elapsed, excluded - ? AnalysisAction.Excluded - : upToDate - ? AnalysisAction.UpToDate - : AnalysisAction.Extracted); + ReportProgress(sourcePath, trapPath, stopwatch.Elapsed, upToDate ? AnalysisAction.UpToDate : AnalysisAction.Extracted); } catch (Exception ex) // lgtm[cs/catch-of-all-exceptions] { diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Extractor.cs b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Extractor.cs index 25829a35068..8d63c6288bf 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Extractor.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Extractor.cs @@ -16,15 +16,15 @@ using System.Threading; namespace Semmle.Extraction.CSharp { + public enum ExitCode + { + Ok, // Everything worked perfectly + Errors, // Trap was generated but there were processing errors + Failed // Trap could not be generated + } + public static class Extractor { - public enum ExitCode - { - Ok, // Everything worked perfectly - Errors, // Trap was generated but there were processing errors - Failed // Trap could not be generated - } - private class LogProgressMonitor : IProgressMonitor { private readonly ILogger logger; @@ -69,6 +69,14 @@ namespace Semmle.Extraction.CSharp Thread.CurrentThread.CurrentUICulture = culture; } + public static ILogger MakeLogger(Verbosity verbosity, bool includeConsole) + { + var fileLogger = new FileLogger(verbosity, GetCSharpLogPath()); + return includeConsole + ? new CombinedLogger(new ConsoleLogger(verbosity), fileLogger) + : (ILogger)fileLogger; + } + /// /// Command-line driver for the extractor. /// @@ -89,10 +97,7 @@ namespace Semmle.Extraction.CSharp var options = Options.CreateWithEnvironment(args); Entities.Compilation.Settings = (Directory.GetCurrentDirectory(), options.CompilerArguments.ToArray()); - var fileLogger = new FileLogger(options.Verbosity, GetCSharpLogPath()); - using var logger = options.Console - ? new CombinedLogger(new ConsoleLogger(options.Verbosity), fileLogger) - : (ILogger)fileLogger; + using var logger = MakeLogger(options.Verbosity, options.Console); if (Environment.GetEnvironmentVariable("SEMMLE_CLRTRACER") == "1" && !options.ClrTracer) { @@ -276,7 +281,7 @@ namespace Semmle.Extraction.CSharp /// The constructed syntax trees will be added (thread-safely) to the supplied /// list . /// - private static IEnumerable ReadSyntaxTrees(IEnumerable sources, Analyser analyser, CSharpParseOptions? parseOptions, Encoding? encoding, IList ret) + public static IEnumerable ReadSyntaxTrees(IEnumerable sources, Analyser analyser, CSharpParseOptions? parseOptions, Encoding? encoding, IList ret) { return sources.Select(path => () => { @@ -298,31 +303,7 @@ namespace Semmle.Extraction.CSharp }); } - public static void ExtractStandalone( - IEnumerable sources, - IEnumerable referencePaths, - IProgressMonitor pm, - ILogger logger, - CommonOptions options) - { - var stopwatch = new Stopwatch(); - stopwatch.Start(); - - var canonicalPathCache = CanonicalPathCache.Create(logger, 1000); - var pathTransformer = new PathTransformer(canonicalPathCache); - - using var analyser = new StandaloneAnalyser(pm, logger, false, pathTransformer); - try - { - AnalyseStandalone(analyser, sources, referencePaths, options, pm, stopwatch); - } - catch (Exception ex) // lgtm[cs/catch-of-all-exceptions] - { - analyser.Logger.Log(Severity.Error, " Unhandled exception: {0}", ex); - } - } - - private static ExitCode Analyse(Stopwatch stopwatch, Analyser analyser, CommonOptions options, + public static ExitCode Analyse(Stopwatch stopwatch, Analyser analyser, CommonOptions options, Func, IEnumerable> getResolvedReferenceTasks, Func, IEnumerable> getSyntaxTreeTasks, Func, IEnumerable, CSharpCompilation> getCompilation, @@ -395,37 +376,6 @@ namespace Semmle.Extraction.CSharp return analyser.TotalErrors == 0 ? ExitCode.Ok : ExitCode.Errors; } - private static void AnalyseStandalone( - StandaloneAnalyser analyser, - IEnumerable sources, - IEnumerable referencePaths, - CommonOptions options, - IProgressMonitor progressMonitor, - Stopwatch stopwatch) - { - Analyse(stopwatch, analyser, options, - references => GetResolvedReferencesStandalone(referencePaths, references), - (analyser, syntaxTrees) => ReadSyntaxTrees(sources, analyser, null, null, syntaxTrees), - (syntaxTrees, references) => CSharpCompilation.Create("csharp.dll", syntaxTrees, references), - (compilation, options) => analyser.InitializeStandalone(compilation, options), - () => { }, - _ => { }, - () => - { - foreach (var type in analyser.MissingNamespaces) - { - progressMonitor.MissingNamespace(type); - } - - foreach (var type in analyser.MissingTypes) - { - progressMonitor.MissingType(type); - } - - progressMonitor.MissingSummary(analyser.MissingTypes.Count(), analyser.MissingNamespaces.Count()); - }); - } - private static ExitCode AnalyseTracing( TracingAnalyser analyser, CSharpCommandLineArguments compilerArguments, @@ -468,15 +418,6 @@ namespace Semmle.Extraction.CSharp () => { }); } - private static IEnumerable GetResolvedReferencesStandalone(IEnumerable referencePaths, BlockingCollection references) - { - return referencePaths.Select(path => () => - { - var reference = MetadataReference.CreateFromFile(path); - references.Add(reference); - }); - } - /// /// Gets the path to the `csharp.log` file written to by the C# extractor. /// @@ -511,19 +452,6 @@ namespace Semmle.Extraction.CSharp if (!string.IsNullOrEmpty(codeQlLogDir)) return codeQlLogDir; - var snapshot = Environment.GetEnvironmentVariable("ODASA_SNAPSHOT"); - if (!string.IsNullOrEmpty(snapshot)) - return Path.Combine(snapshot, "log"); - - var buildErrorDir = Environment.GetEnvironmentVariable("ODASA_BUILD_ERROR_DIR"); - if (!string.IsNullOrEmpty(buildErrorDir)) - // Used by `qltest` - return buildErrorDir; - - var traps = Environment.GetEnvironmentVariable("TRAP_FOLDER"); - if (!string.IsNullOrEmpty(traps)) - return traps; - return Directory.GetCurrentDirectory(); } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Options.cs b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Options.cs index 8501e1a0e42..7b4e0e95ea3 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Options.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Options.cs @@ -40,8 +40,7 @@ namespace Semmle.Extraction.CSharp public static Options CreateWithEnvironment(string[] arguments) { var options = new Options(); - var extractionOptions = Environment.GetEnvironmentVariable("SEMMLE_EXTRACTOR_OPTIONS") ?? - Environment.GetEnvironmentVariable("LGTM_INDEX_EXTRACTOR"); + var extractionOptions = Environment.GetEnvironmentVariable("LGTM_INDEX_EXTRACTOR"); var argsList = new List(arguments); diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/TracingAnalyser.cs b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/TracingAnalyser.cs index 4c15d053a93..8681ded3f09 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/TracingAnalyser.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/TracingAnalyser.cs @@ -46,7 +46,6 @@ namespace Semmle.Extraction.CSharp { if (!init) throw new InternalError("EndInitialize called without BeginInitialize returning true"); - this.layout = new Layout(); this.options = options; this.compilation = compilation; this.extractor = new TracingExtractor(GetOutputName(compilation, commandLineArguments), Logger, PathTransformer, options); @@ -202,8 +201,7 @@ namespace Semmle.Extraction.CSharp var assemblyPath = ((TracingExtractor?)extractor).OutputPath; var transformedAssemblyPath = PathTransformer.Transform(assemblyPath); var assembly = compilation.Assembly; - var projectLayout = layout.LookupProjectOrDefault(transformedAssemblyPath); - var trapWriter = projectLayout.CreateTrapWriter(Logger, transformedAssemblyPath, options.TrapCompression, discardDuplicates: false); + var trapWriter = transformedAssemblyPath.CreateTrapWriter(Logger, options.TrapCompression, discardDuplicates: false); compilationTrapFile = trapWriter; // Dispose later var cx = new Context(extractor, compilation.Clone(), trapWriter, new AssemblyScope(assembly, assemblyPath), addAssemblyTrapPrefix); diff --git a/csharp/extractor/Semmle.Extraction.Tests/Layout.cs b/csharp/extractor/Semmle.Extraction.Tests/Layout.cs deleted file mode 100644 index 58470fa8caa..00000000000 --- a/csharp/extractor/Semmle.Extraction.Tests/Layout.cs +++ /dev/null @@ -1,231 +0,0 @@ -using System.IO; -using Xunit; -using Semmle.Util.Logging; -using System.Runtime.InteropServices; - -namespace Semmle.Extraction.Tests -{ - internal struct TransformedPathStub : PathTransformer.ITransformedPath - { - private readonly string value; - public TransformedPathStub(string value) => this.value = value; - public string Value => value; - - public string Extension => throw new System.NotImplementedException(); - - public string NameWithoutExtension => throw new System.NotImplementedException(); - - public PathTransformer.ITransformedPath ParentDirectory => throw new System.NotImplementedException(); - - public string DatabaseId => throw new System.NotImplementedException(); - - public PathTransformer.ITransformedPath WithSuffix(string suffix) - { - throw new System.NotImplementedException(); - } - } - - public class Layout - { - private readonly ILogger logger = new LoggerMock(); - - [Fact] - public void TestDefaultLayout() - { - var layout = new Semmle.Extraction.Layout(null, null, null); - var project = layout.LookupProjectOrNull(new TransformedPathStub("foo.cs")); - - Assert.NotNull(project); - - // All files are mapped when there's no layout file. - Assert.True(layout.FileInLayout(new TransformedPathStub("foo.cs"))); - - // Test trap filename - var tmpDir = Path.GetTempPath(); - Directory.SetCurrentDirectory(tmpDir); - if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) - { - // `Directory.SetCurrentDirectory()` seems to slightly change the path on macOS, - // so adjusting it: - Assert.NotEqual(Directory.GetCurrentDirectory(), tmpDir); - tmpDir = "/private" + tmpDir; - // Remove trailing slash: - Assert.Equal('/', tmpDir[tmpDir.Length - 1]); - tmpDir = tmpDir.Substring(0, tmpDir.Length - 1); - Assert.Equal(Directory.GetCurrentDirectory(), tmpDir); - } - var f1 = project!.GetTrapPath(logger, new TransformedPathStub("foo.cs"), TrapWriter.CompressionMode.Gzip); - var g1 = TrapWriter.NestPaths(logger, tmpDir, "foo.cs.trap.gz"); - Assert.Equal(f1, g1); - - // Test trap file generation - var trapwriterFilename = project.GetTrapPath(logger, new TransformedPathStub("foo.cs"), TrapWriter.CompressionMode.Gzip); - using (var trapwriter = project.CreateTrapWriter(logger, new TransformedPathStub("foo.cs"), TrapWriter.CompressionMode.Gzip, discardDuplicates: false)) - { - trapwriter.Emit("1=*"); - Assert.False(File.Exists(trapwriterFilename)); - } - Assert.True(File.Exists(trapwriterFilename)); - File.Delete(trapwriterFilename); - } - - [Fact] - public void TestLayoutFile() - { - File.WriteAllLines("layout.txt", new string[] - { - "# Section", - "TRAP_FOLDER=" + Path.GetFullPath("snapshot\\trap"), - "ODASA_DB=snapshot\\db-csharp", - "SOURCE_ARCHIVE=" + Path.GetFullPath("snapshot\\archive"), - "ODASA_BUILD_ERROR_DIR=snapshot\build-errors", - "-foo.cs", - "bar.cs", - "-excluded", - "excluded/foo.cs", - "included" - }); - - var layout = new Semmle.Extraction.Layout(null, null, "layout.txt"); - - // Test general pattern matching - Assert.True(layout.FileInLayout(new TransformedPathStub("bar.cs"))); - Assert.False(layout.FileInLayout(new TransformedPathStub("foo.cs"))); - Assert.False(layout.FileInLayout(new TransformedPathStub("goo.cs"))); - Assert.False(layout.FileInLayout(new TransformedPathStub("excluded/bar.cs"))); - Assert.True(layout.FileInLayout(new TransformedPathStub("excluded/foo.cs"))); - Assert.True(layout.FileInLayout(new TransformedPathStub("included/foo.cs"))); - - // Test the trap file - var project = layout.LookupProjectOrNull(new TransformedPathStub("bar.cs")); - Assert.NotNull(project); - var trapwriterFilename = project!.GetTrapPath(logger, new TransformedPathStub("bar.cs"), TrapWriter.CompressionMode.Gzip); - Assert.Equal(TrapWriter.NestPaths(logger, Path.GetFullPath("snapshot\\trap"), "bar.cs.trap.gz"), - trapwriterFilename); - - // Test the source archive - var trapWriter = project.CreateTrapWriter(logger, new TransformedPathStub("bar.cs"), TrapWriter.CompressionMode.Gzip, discardDuplicates: false); - trapWriter.Archive("layout.txt", new TransformedPathStub("layout.txt"), System.Text.Encoding.ASCII); - var writtenFile = TrapWriter.NestPaths(logger, Path.GetFullPath("snapshot\\archive"), "layout.txt"); - Assert.True(File.Exists(writtenFile)); - File.Delete("layout.txt"); - } - - [Fact] - public void TestTrapOverridesLayout() - { - // When you specify both a trap file and a layout, use the trap file. - var layout = new Semmle.Extraction.Layout(Path.GetFullPath("snapshot\\trap"), null, "something.txt"); - Assert.True(layout.FileInLayout(new TransformedPathStub("bar.cs"))); - var subProject = layout.LookupProjectOrNull(new TransformedPathStub("foo.cs")); - Assert.NotNull(subProject); - var f1 = subProject!.GetTrapPath(logger, new TransformedPathStub("foo.cs"), TrapWriter.CompressionMode.Gzip); - var g1 = TrapWriter.NestPaths(logger, Path.GetFullPath("snapshot\\trap"), "foo.cs.trap.gz"); - Assert.Equal(f1, g1); - } - - [Fact] - public void TestMultipleSections() - { - File.WriteAllLines("layout.txt", new string[] - { - "# Section 1", - "TRAP_FOLDER=" + Path.GetFullPath("snapshot\\trap1"), - "ODASA_DB=snapshot\\db-csharp", - "SOURCE_ARCHIVE=" + Path.GetFullPath("snapshot\\archive1"), - "ODASA_BUILD_ERROR_DIR=snapshot\build-errors", - "foo.cs", - "# Section 2", - "TRAP_FOLDER=" + Path.GetFullPath("snapshot\\trap2"), - "ODASA_DB=snapshot\\db-csharp", - "SOURCE_ARCHIVE=" + Path.GetFullPath("snapshot\\archive2"), - "ODASA_BUILD_ERROR_DIR=snapshot\build-errors", - "bar.cs", - }); - - var layout = new Semmle.Extraction.Layout(null, null, "layout.txt"); - - // Use Section 2 - Assert.True(layout.FileInLayout(new TransformedPathStub("bar.cs"))); - var subProject = layout.LookupProjectOrNull(new TransformedPathStub("bar.cs")); - Assert.NotNull(subProject); - var f1 = subProject!.GetTrapPath(logger, new TransformedPathStub("bar.cs"), TrapWriter.CompressionMode.Gzip); - var g1 = TrapWriter.NestPaths(logger, Path.GetFullPath("snapshot\\trap2"), "bar.cs.trap.gz"); - Assert.Equal(f1, g1); - - // Use Section 1 - Assert.True(layout.FileInLayout(new TransformedPathStub("foo.cs"))); - subProject = layout.LookupProjectOrNull(new TransformedPathStub("foo.cs")); - Assert.NotNull(subProject); - var f2 = subProject!.GetTrapPath(logger, new TransformedPathStub("foo.cs"), TrapWriter.CompressionMode.Gzip); - var g2 = TrapWriter.NestPaths(logger, Path.GetFullPath("snapshot\\trap1"), "foo.cs.trap.gz"); - Assert.Equal(f2, g2); - - // boo.dll is not in the layout, so use layout from first section. - Assert.False(layout.FileInLayout(new TransformedPathStub("boo.dll"))); - var f3 = layout.LookupProjectOrDefault(new TransformedPathStub("boo.dll")).GetTrapPath(logger, new TransformedPathStub("boo.dll"), TrapWriter.CompressionMode.Gzip); - var g3 = TrapWriter.NestPaths(logger, Path.GetFullPath("snapshot\\trap1"), "boo.dll.trap.gz"); - Assert.Equal(f3, g3); - - // boo.cs is not in the layout, so return null - Assert.False(layout.FileInLayout(new TransformedPathStub("boo.cs"))); - Assert.Null(layout.LookupProjectOrNull(new TransformedPathStub("boo.cs"))); - } - - [Fact] - public void MissingLayout() - { - Assert.Throws(() => - new Semmle.Extraction.Layout(null, null, "nosuchfile.txt")); - } - - [Fact] - public void EmptyLayout() - { - File.Create("layout.txt").Close(); - Assert.Throws(() => - new Semmle.Extraction.Layout(null, null, "layout.txt")); - } - - [Fact] - public void InvalidLayout() - { - File.WriteAllLines("layout.txt", new string[] - { - "# Section 1" - }); - - Assert.Throws(() => - new Semmle.Extraction.Layout(null, null, "layout.txt")); - } - - private sealed class LoggerMock : ILogger - { - public void Dispose() { } - - public void Log(Severity s, string text) { } - } - } - - internal static class TrapWriterTestExtensions - { - public static void Emit(this TrapWriter trapFile, string s) - { - trapFile.Emit(new StringTrapEmitter(s)); - } - - private class StringTrapEmitter : ITrapEmitter - { - private readonly string content; - public StringTrapEmitter(string content) - { - this.content = content; - } - - public void EmitTrap(TextWriter trapFile) - { - trapFile.Write(content); - } - } - } -} diff --git a/csharp/extractor/Semmle.Extraction.Tests/Options.cs b/csharp/extractor/Semmle.Extraction.Tests/Options.cs index 8ad9d3de027..9b17320fbaa 100644 --- a/csharp/extractor/Semmle.Extraction.Tests/Options.cs +++ b/csharp/extractor/Semmle.Extraction.Tests/Options.cs @@ -14,7 +14,6 @@ namespace Semmle.Extraction.Tests public OptionsTests() { - Environment.SetEnvironmentVariable("SEMMLE_EXTRACTOR_OPTIONS", ""); Environment.SetEnvironmentVariable("LGTM_INDEX_EXTRACTOR", ""); } @@ -126,14 +125,14 @@ namespace Semmle.Extraction.Tests [Fact] public void EnvironmentVariables() { - Environment.SetEnvironmentVariable("SEMMLE_EXTRACTOR_OPTIONS", "--cil c"); + Environment.SetEnvironmentVariable("LGTM_INDEX_EXTRACTOR", "--cil c"); options = CSharp.Options.CreateWithEnvironment(new string[] { "a", "b" }); Assert.True(options.CIL); Assert.Equal("a", options.CompilerArguments[0]); Assert.Equal("b", options.CompilerArguments[1]); Assert.Equal("c", options.CompilerArguments[2]); - Environment.SetEnvironmentVariable("SEMMLE_EXTRACTOR_OPTIONS", ""); + Environment.SetEnvironmentVariable("LGTM_INDEX_EXTRACTOR", ""); Environment.SetEnvironmentVariable("LGTM_INDEX_EXTRACTOR", "--nocil"); options = CSharp.Options.CreateWithEnvironment(new string[] { "--cil" }); Assert.False(options.CIL); diff --git a/csharp/extractor/Semmle.Extraction/Layout.cs b/csharp/extractor/Semmle.Extraction/Layout.cs deleted file mode 100644 index 549c49b4fb7..00000000000 --- a/csharp/extractor/Semmle.Extraction/Layout.cs +++ /dev/null @@ -1,204 +0,0 @@ -using Semmle.Util.Logging; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; - -namespace Semmle.Extraction -{ - /// - /// An extractor layout file. - /// Represents the layout of projects into trap folders and source archives. - /// - public sealed class Layout - { - /// - /// Exception thrown when the layout file is invalid. - /// - public class InvalidLayoutException : Exception - { - public InvalidLayoutException(string file, string message) : - base("ODASA_CSHARP_LAYOUT " + file + " " + message) - { - } - } - - /// - /// List of blocks in the layout file. - /// - private readonly List blocks; - - /// - /// A subproject in the layout file. - /// - public class SubProject - { - /// - /// The trap folder, or null for current directory. - /// - public string? TRAP_FOLDER { get; } - - /// - /// The source archive, or null to skip. - /// - public string? SOURCE_ARCHIVE { get; } - - public SubProject(string? traps, string? archive) - { - TRAP_FOLDER = traps; - SOURCE_ARCHIVE = archive; - } - - /// - /// Gets the name of the trap file for a given source/assembly file. - /// - /// The source file. - /// The full filepath of the trap file. - public string GetTrapPath(ILogger logger, PathTransformer.ITransformedPath srcFile, TrapWriter.CompressionMode trapCompression) => - TrapWriter.TrapPath(logger, TRAP_FOLDER, srcFile, trapCompression); - - /// - /// Creates a trap writer for a given source/assembly file. - /// - /// The source file. - /// A newly created TrapWriter. - public TrapWriter CreateTrapWriter(ILogger logger, PathTransformer.ITransformedPath srcFile, TrapWriter.CompressionMode trapCompression, bool discardDuplicates) => - new TrapWriter(logger, srcFile, TRAP_FOLDER, SOURCE_ARCHIVE, trapCompression, discardDuplicates); - } - - private readonly SubProject defaultProject; - - /// - /// Finds the suitable directories for a given source file. - /// Returns null if not included in the layout. - /// - /// The file to look up. - /// The relevant subproject, or null if not found. - public SubProject? LookupProjectOrNull(PathTransformer.ITransformedPath sourceFile) - { - if (!useLayoutFile) - return defaultProject; - - return blocks - .Where(block => block.Matches(sourceFile)) - .Select(block => block.Directories) - .FirstOrDefault(); - } - - /// - /// Finds the suitable directories for a given source file. - /// Returns the default project if not included in the layout. - /// - /// The file to look up. - /// The relevant subproject, or DefaultProject if not found. - public SubProject LookupProjectOrDefault(PathTransformer.ITransformedPath sourceFile) - { - return LookupProjectOrNull(sourceFile) ?? defaultProject; - } - - private readonly bool useLayoutFile; - - /// - /// Default constructor reads parameters from the environment. - /// - public Layout() : this( - Environment.GetEnvironmentVariable("CODEQL_EXTRACTOR_CSHARP_TRAP_DIR") ?? Environment.GetEnvironmentVariable("TRAP_FOLDER"), - Environment.GetEnvironmentVariable("CODEQL_EXTRACTOR_CSHARP_SOURCE_ARCHIVE_DIR") ?? Environment.GetEnvironmentVariable("SOURCE_ARCHIVE"), - Environment.GetEnvironmentVariable("ODASA_CSHARP_LAYOUT")) - { - } - - /// - /// Creates the project layout. Reads the layout file if specified. - /// - /// Directory for trap files, or null to use layout/current directory. - /// Directory for source archive, or null for layout/no archive. - /// Path of layout file, or null for no layout. - /// Failed to read layout file. - public Layout(string? traps, string? archive, string? layout) - { - useLayoutFile = string.IsNullOrEmpty(traps) && !string.IsNullOrEmpty(layout); - blocks = new List(); - - if (useLayoutFile) - { - ReadLayoutFile(layout!); - defaultProject = blocks[0].Directories; - } - else - { - defaultProject = new SubProject(traps, archive); - } - } - - /// - /// Is the source file included in the layout? - /// - /// The absolute path of the file to query. - /// True iff there is no layout file or the layout file specifies the file. - public bool FileInLayout(PathTransformer.ITransformedPath path) => LookupProjectOrNull(path) is not null; - - private void ReadLayoutFile(string layout) - { - try - { - var lines = File.ReadAllLines(layout); - - var i = 0; - while (!lines[i].StartsWith("#")) - i++; - while (i < lines.Length) - { - var block = new LayoutBlock(lines, ref i); - blocks.Add(block); - } - - if (blocks.Count == 0) - throw new InvalidLayoutException(layout, "contains no blocks"); - } - catch (IOException ex) - { - throw new InvalidLayoutException(layout, ex.Message); - } - catch (IndexOutOfRangeException) - { - throw new InvalidLayoutException(layout, "is invalid"); - } - } - } - - internal sealed class LayoutBlock - { - private readonly List filePatterns = new List(); - - public Layout.SubProject Directories { get; } - - private static string? ReadVariable(string name, string line) - { - var prefix = name + "="; - if (!line.StartsWith(prefix)) - return null; - return line.Substring(prefix.Length).Trim(); - } - - public LayoutBlock(string[] lines, ref int i) - { - // first line: #name - i++; - var trapFolder = ReadVariable("TRAP_FOLDER", lines[i++]); - // Don't care about ODASA_DB. - ReadVariable("ODASA_DB", lines[i++]); - var sourceArchive = ReadVariable("SOURCE_ARCHIVE", lines[i++]); - - Directories = new Layout.SubProject(trapFolder, sourceArchive); - // Don't care about ODASA_BUILD_ERROR_DIR. - ReadVariable("ODASA_BUILD_ERROR_DIR", lines[i++]); - while (i < lines.Length && !lines[i].StartsWith("#")) - { - filePatterns.Add(new FilePattern(lines[i++])); - } - } - - public bool Matches(PathTransformer.ITransformedPath path) => FilePattern.Matches(filePatterns, path.Value, out var _); - } -} diff --git a/csharp/extractor/Semmle.Extraction/PathTransformer.cs b/csharp/extractor/Semmle.Extraction/PathTransformer.cs index 4611e079454..7e4ce24bdc6 100644 --- a/csharp/extractor/Semmle.Extraction/PathTransformer.cs +++ b/csharp/extractor/Semmle.Extraction/PathTransformer.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.IO; using System.Diagnostics.CodeAnalysis; using Semmle.Util; +using Semmle.Util.Logging; namespace Semmle.Extraction { @@ -35,6 +36,20 @@ namespace Semmle.Extraction ITransformedPath WithSuffix(string suffix); string DatabaseId { get; } + + /// + /// Gets the name of the trap file for this file. + /// + /// The full filepath of the trap file. + public string GetTrapPath(ILogger logger, TrapWriter.CompressionMode trapCompression) => + TrapWriter.TrapPath(logger, Environment.GetEnvironmentVariable("CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"), this, trapCompression); + + /// + /// Creates a trap writer for this file. + /// + /// A newly created TrapWriter. + public TrapWriter CreateTrapWriter(ILogger logger, TrapWriter.CompressionMode trapCompression, bool discardDuplicates) => + new(logger, this, Environment.GetEnvironmentVariable("CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"), Environment.GetEnvironmentVariable("CODEQL_EXTRACTOR_CSHARP_SOURCE_ARCHIVE_DIR"), trapCompression, discardDuplicates); } private struct TransformedPath : ITransformedPath diff --git a/csharp/extractor/Semmle.Util/CanonicalPathCache.cs b/csharp/extractor/Semmle.Util/CanonicalPathCache.cs index 1288cf6d7b6..9b56d3e4f1f 100644 --- a/csharp/extractor/Semmle.Util/CanonicalPathCache.cs +++ b/csharp/extractor/Semmle.Util/CanonicalPathCache.cs @@ -234,9 +234,7 @@ namespace Semmle.Util /// A new CanonicalPathCache. public static CanonicalPathCache Create(ILogger logger, int maxCapacity) { - var preserveSymlinks = - Environment.GetEnvironmentVariable("CODEQL_PRESERVE_SYMLINKS") == "true" || - Environment.GetEnvironmentVariable("SEMMLE_PRESERVE_SYMLINKS") == "true"; + var preserveSymlinks = Environment.GetEnvironmentVariable("CODEQL_PRESERVE_SYMLINKS") == "true"; return Create(logger, maxCapacity, preserveSymlinks ? CanonicalPathCache.Symlinks.Preserve : CanonicalPathCache.Symlinks.Follow); } diff --git a/csharp/extractor/Semmle.Util/Logger.cs b/csharp/extractor/Semmle.Util/Logger.cs index 5307ad0fcd9..1182046f693 100644 --- a/csharp/extractor/Semmle.Util/Logger.cs +++ b/csharp/extractor/Semmle.Util/Logger.cs @@ -74,7 +74,7 @@ namespace Semmle.Util.Logging } catch (Exception ex) // lgtm[cs/catch-of-all-exceptions] { - Console.Error.WriteLine("SEMMLE: Couldn't initialise C# extractor output: " + ex.Message + "\n" + ex.StackTrace); + Console.Error.WriteLine("CodeQL: Couldn't initialise C# extractor output: " + ex.Message + "\n" + ex.StackTrace); Console.Error.Flush(); throw; } diff --git a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md index 229de990843..1fa8e6a97a1 100644 --- a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md @@ -1,3 +1,5 @@ +## 1.0.5 + ## 1.0.4 ## 1.0.3 diff --git a/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.0.5.md b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.0.5.md new file mode 100644 index 00000000000..ac0f13f1f5e --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.0.5.md @@ -0,0 +1 @@ +## 1.0.5 diff --git a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml index 03f7ea71b58..42da17b3841 100644 --- a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml +++ b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.4 +lastReleaseVersion: 1.0.5 diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml index 97b3f928fa9..2306b6e3f7a 100644 --- a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-all -version: 1.0.5-dev +version: 1.0.6-dev groups: - csharp - solorigate diff --git a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md index 229de990843..1fa8e6a97a1 100644 --- a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md @@ -1,3 +1,5 @@ +## 1.0.5 + ## 1.0.4 ## 1.0.3 diff --git a/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.0.5.md b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.0.5.md new file mode 100644 index 00000000000..ac0f13f1f5e --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.0.5.md @@ -0,0 +1 @@ +## 1.0.5 diff --git a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml index 03f7ea71b58..42da17b3841 100644 --- a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml +++ b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.4 +lastReleaseVersion: 1.0.5 diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml index e428de5b82d..e066d816c4b 100644 --- a/csharp/ql/campaigns/Solorigate/src/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-queries -version: 1.0.5-dev +version: 1.0.6-dev groups: - csharp - solorigate diff --git a/csharp/ql/lib/CHANGELOG.md b/csharp/ql/lib/CHANGELOG.md index 193709d1260..68e312fb659 100644 --- a/csharp/ql/lib/CHANGELOG.md +++ b/csharp/ql/lib/CHANGELOG.md @@ -1,3 +1,21 @@ +## 0.0.11 + +### Breaking Changes + +* The C# extractor no longer supports the following legacy environment variables: +``` +ODASA_BUILD_ERROR_DIR +ODASA_CSHARP_LAYOUT +ODASA_SNAPSHOT +SEMMLE_DIST +SEMMLE_EXTRACTOR_OPTIONS +SEMMLE_PLATFORM_TOOLS +SEMMLE_PRESERVE_SYMLINKS +SOURCE_ARCHIVE +TRAP_FOLDER +``` +* `codeql test run` now extracts source code recursively from sub folders. This may break existing tests that have other tests in nested sub folders, as those will now get the nested test code included. + ## 0.0.10 ## 0.0.9 diff --git a/csharp/ql/lib/change-notes/2022-02-07-deleted-deprecations.md b/csharp/ql/lib/change-notes/2022-02-07-deleted-deprecations.md new file mode 100644 index 00000000000..e8da1e8e158 --- /dev/null +++ b/csharp/ql/lib/change-notes/2022-02-07-deleted-deprecations.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* All deprecated predicates/classes/modules that have been deprecated for over a year have been deleted. \ No newline at end of file diff --git a/csharp/ql/lib/change-notes/2022-02-07-deprecated-acronyms.md b/csharp/ql/lib/change-notes/2022-02-07-deprecated-acronyms.md new file mode 100644 index 00000000000..a79f286aacd --- /dev/null +++ b/csharp/ql/lib/change-notes/2022-02-07-deprecated-acronyms.md @@ -0,0 +1,5 @@ +--- +category: deprecated +--- +* Many classes/predicates/modules that had upper-case acronyms have been renamed to follow our style-guide. + The old name still exists as a deprecated alias. \ No newline at end of file diff --git a/csharp/ql/lib/change-notes/2022-03-14-taint-interface-cleanup.md b/csharp/ql/lib/change-notes/2022-03-14-taint-interface-cleanup.md new file mode 100644 index 00000000000..3481d507db3 --- /dev/null +++ b/csharp/ql/lib/change-notes/2022-03-14-taint-interface-cleanup.md @@ -0,0 +1,4 @@ +--- +category: breaking +--- +* The flow state variants of `isBarrier` and `isAdditionalFlowStep` are no longer exposed in the taint tracking library. The `isSanitizer` and `isAdditionalTaintStep` predicates should be used instead. diff --git a/csharp/ql/lib/change-notes/released/0.0.11.md b/csharp/ql/lib/change-notes/released/0.0.11.md new file mode 100644 index 00000000000..fb37f9e3758 --- /dev/null +++ b/csharp/ql/lib/change-notes/released/0.0.11.md @@ -0,0 +1,17 @@ +## 0.0.11 + +### Breaking Changes + +* The C# extractor no longer supports the following legacy environment variables: +``` +ODASA_BUILD_ERROR_DIR +ODASA_CSHARP_LAYOUT +ODASA_SNAPSHOT +SEMMLE_DIST +SEMMLE_EXTRACTOR_OPTIONS +SEMMLE_PLATFORM_TOOLS +SEMMLE_PRESERVE_SYMLINKS +SOURCE_ARCHIVE +TRAP_FOLDER +``` +* `codeql test run` now extracts source code recursively from sub folders. This may break existing tests that have other tests in nested sub folders, as those will now get the nested test code included. diff --git a/csharp/ql/lib/codeql-pack.release.yml b/csharp/ql/lib/codeql-pack.release.yml index b740014e5ae..e679dc42092 100644 --- a/csharp/ql/lib/codeql-pack.release.yml +++ b/csharp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.10 +lastReleaseVersion: 0.0.11 diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index 786e7dcd2aa..d17d3a6388c 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-all -version: 0.0.11-dev +version: 0.0.12-dev groups: csharp dbscheme: semmlecode.csharp.dbscheme extractor: csharp diff --git a/csharp/ql/lib/semmle/code/asp/WebConfig.qll b/csharp/ql/lib/semmle/code/asp/WebConfig.qll index 16d5393afc2..024d60ca450 100644 --- a/csharp/ql/lib/semmle/code/asp/WebConfig.qll +++ b/csharp/ql/lib/semmle/code/asp/WebConfig.qll @@ -7,67 +7,88 @@ import csharp /** * A `Web.config` file. */ -class WebConfigXML extends XMLFile { - WebConfigXML() { this.getName().matches("%Web.config") } +class WebConfigXml extends XMLFile { + WebConfigXml() { this.getName().matches("%Web.config") } } +/** DEPRECATED: Alias for WebConfigXml */ +deprecated class WebConfigXML = WebConfigXml; + /** A `` tag in an ASP.NET configuration file. */ -class ConfigurationXMLElement extends XMLElement { - ConfigurationXMLElement() { this.getName().toLowerCase() = "configuration" } +class ConfigurationXmlElement extends XMLElement { + ConfigurationXmlElement() { this.getName().toLowerCase() = "configuration" } } +/** DEPRECATED: Alias for ConfigurationXmlElement */ +deprecated class ConfigurationXMLElement = ConfigurationXmlElement; + /** A `` tag in an ASP.NET configuration file. */ -class LocationXMLElement extends XMLElement { - LocationXMLElement() { - this.getParent() instanceof ConfigurationXMLElement and +class LocationXmlElement extends XMLElement { + LocationXmlElement() { + this.getParent() instanceof ConfigurationXmlElement and this.getName().toLowerCase() = "location" } } +/** DEPRECATED: Alias for LocationXmlElement */ +deprecated class LocationXMLElement = LocationXmlElement; + /** A `` tag in an ASP.NET configuration file. */ -class SystemWebXMLElement extends XMLElement { - SystemWebXMLElement() { +class SystemWebXmlElement extends XMLElement { + SystemWebXmlElement() { ( - this.getParent() instanceof ConfigurationXMLElement + this.getParent() instanceof ConfigurationXmlElement or - this.getParent() instanceof LocationXMLElement + this.getParent() instanceof LocationXmlElement ) and this.getName().toLowerCase() = "system.web" } } +/** DEPRECATED: Alias for SystemWebXmlElement */ +deprecated class SystemWebXMLElement = SystemWebXmlElement; + /** A `` tag in an ASP.NET configuration file. */ -class SystemWebServerXMLElement extends XMLElement { - SystemWebServerXMLElement() { +class SystemWebServerXmlElement extends XMLElement { + SystemWebServerXmlElement() { ( - this.getParent() instanceof ConfigurationXMLElement + this.getParent() instanceof ConfigurationXmlElement or - this.getParent() instanceof LocationXMLElement + this.getParent() instanceof LocationXmlElement ) and this.getName().toLowerCase() = "system.webserver" } } +/** DEPRECATED: Alias for SystemWebServerXmlElement */ +deprecated class SystemWebServerXMLElement = SystemWebServerXmlElement; + /** A `` tag in an ASP.NET configuration file. */ -class CustomErrorsXMLElement extends XMLElement { - CustomErrorsXMLElement() { - this.getParent() instanceof SystemWebXMLElement and +class CustomErrorsXmlElement extends XMLElement { + CustomErrorsXmlElement() { + this.getParent() instanceof SystemWebXmlElement and this.getName().toLowerCase() = "customerrors" } } +/** DEPRECATED: Alias for CustomErrorsXmlElement */ +deprecated class CustomErrorsXMLElement = CustomErrorsXmlElement; + /** A `` tag in an ASP.NET configuration file. */ -class HttpRuntimeXMLElement extends XMLElement { - HttpRuntimeXMLElement() { - this.getParent() instanceof SystemWebXMLElement and +class HttpRuntimeXmlElement extends XMLElement { + HttpRuntimeXmlElement() { + this.getParent() instanceof SystemWebXmlElement and this.getName().toLowerCase() = "httpruntime" } } +/** DEPRECATED: Alias for HttpRuntimeXmlElement */ +deprecated class HttpRuntimeXMLElement = HttpRuntimeXmlElement; + /** A `` tag under `` in an ASP.NET configuration file. */ class FormsElement extends XMLElement { FormsElement() { - this = any(SystemWebXMLElement sw).getAChild("authentication").getAChild("forms") + this = any(SystemWebXmlElement sw).getAChild("authentication").getAChild("forms") } /** @@ -85,7 +106,7 @@ class FormsElement extends XMLElement { /** A `` tag in an ASP.NET configuration file. */ class HttpCookiesElement extends XMLElement { - HttpCookiesElement() { this = any(SystemWebXMLElement sw).getAChild("httpCookies") } + HttpCookiesElement() { this = any(SystemWebXmlElement sw).getAChild("httpCookies") } /** * Gets attribute's `httpOnlyCookies` value. diff --git a/csharp/ql/lib/semmle/code/cil/Declaration.qll b/csharp/ql/lib/semmle/code/cil/Declaration.qll index 178b5c9966e..9d35eeba9f9 100644 --- a/csharp/ql/lib/semmle/code/cil/Declaration.qll +++ b/csharp/ql/lib/semmle/code/cil/Declaration.qll @@ -23,13 +23,6 @@ class Declaration extends DotNet::Declaration, Element, @cil_declaration { } override Declaration getUnboundDeclaration() { result = this } - - /** - * DEPRECATED: Use `isUnboundDeclaration()` instead. - * - * Holds if this declaration is a source declaration. - */ - deprecated final predicate isSourceDeclaration() { this.isUnboundDeclaration() } } private CS::Declaration toCSharpNonTypeParameter(Declaration d) { result.matchesHandle(d) } diff --git a/csharp/ql/lib/semmle/code/cil/internal/SsaImplCommon.qll b/csharp/ql/lib/semmle/code/cil/internal/SsaImplCommon.qll index 19bf1d4f27d..eed0d050735 100644 --- a/csharp/ql/lib/semmle/code/cil/internal/SsaImplCommon.qll +++ b/csharp/ql/lib/semmle/code/cil/internal/SsaImplCommon.qll @@ -287,20 +287,6 @@ private module SsaDefReaches { ) } - /** - * Holds if the SSA definition of `v` at `def` reaches uncertain SSA definition - * `redef` in the same basic block, without crossing another SSA definition of `v`. - */ - predicate ssaDefReachesUncertainDefWithinBlock( - SourceVariable v, Definition def, UncertainWriteDefinition redef - ) { - exists(BasicBlock bb, int rnk, int i | - ssaDefReachesRank(bb, def, rnk, v) and - rnk = ssaRefRank(bb, i, v, SsaDef()) - 1 and - redef.definesAt(v, bb, i) - ) - } - /** * Same as `ssaRefRank()`, but restricted to a particular SSA definition `def`. */ diff --git a/csharp/ql/lib/semmle/code/csharp/Callable.qll b/csharp/ql/lib/semmle/code/csharp/Callable.qll index 41641a9d032..839d6b3ae0f 100644 --- a/csharp/ql/lib/semmle/code/csharp/Callable.qll +++ b/csharp/ql/lib/semmle/code/csharp/Callable.qll @@ -64,11 +64,6 @@ class Callable extends DotNet::Callable, Parameterizable, ExprOrStmtParent, @cal result = this.getExpressionBody() } - /** - * DEPRECATED: Use `getBody()` instead. - */ - deprecated final ControlFlowElement getABody() { result = this.getBody() } - override predicate hasBody() { exists(this.getBody()) } /** @@ -151,11 +146,6 @@ class Callable extends DotNet::Callable, Parameterizable, ExprOrStmtParent, @cal not result = this.(Constructor).getInitializer() } - /** - * DEPRECATED: Use `getExpressionBody()` instead. - */ - deprecated final Expr getAnExpressionBody() { result = this.getExpressionBody() } - /** Holds if this callable has an expression body. */ final predicate hasExpressionBody() { exists(this.getExpressionBody()) } diff --git a/csharp/ql/lib/semmle/code/csharp/Comments.qll b/csharp/ql/lib/semmle/code/csharp/Comments.qll index 9a611b851e8..e4070ec48ca 100644 --- a/csharp/ql/lib/semmle/code/csharp/Comments.qll +++ b/csharp/ql/lib/semmle/code/csharp/Comments.qll @@ -11,7 +11,7 @@ import Location /** * A single line of comment. * - * Either a single line comment (`SinglelineComment`), an XML comment (`XmlComment`), + * Either a single line comment (`SinglelineComment`), an XML comment (`XmlCommentLine`), * or a line in a multi-line comment (`MultilineComment`). */ class CommentLine extends @commentline { @@ -66,7 +66,7 @@ class MultilineComment extends CommentLine, @multilinecomment { * /// * ``` */ -class XmlComment extends CommentLine, @xmldoccomment { +class XmlCommentLine extends CommentLine, @xmldoccomment { override string toString() { result = "/// ..." } private string xmlAttributeRegex() { @@ -196,7 +196,7 @@ class CommentBlock extends @commentblock { /** Holds if this block consists entirely of XML comments. */ predicate isXmlCommentBlock() { - forall(CommentLine l | l = getAChild() | l instanceof XmlComment) + forall(CommentLine l | l = getAChild() | l instanceof XmlCommentLine) } /** Gets a `CommentLine` containing text. */ diff --git a/csharp/ql/lib/semmle/code/csharp/XML.qll b/csharp/ql/lib/semmle/code/csharp/XML.qll index dc76884b73c..fb781a4683f 100755 --- a/csharp/ql/lib/semmle/code/csharp/XML.qll +++ b/csharp/ql/lib/semmle/code/csharp/XML.qll @@ -4,21 +4,14 @@ import semmle.files.FileSystem -private class TXMLLocatable = +private class TXmlLocatable = @xmldtd or @xmlelement or @xmlattribute or @xmlnamespace or @xmlcomment or @xmlcharacters; /** An XML element that has a location. */ -class XMLLocatable extends @xmllocatable, TXMLLocatable { +class XMLLocatable extends @xmllocatable, TXmlLocatable { /** Gets the source location for this element. */ Location getLocation() { xmllocations(this, result) } - /** - * DEPRECATED: Use `getLocation()` instead. - * - * Gets the source location for this element. - */ - deprecated Location getALocation() { result = this.getLocation() } - /** * Holds if this element is at the specified location. * The location spans column `startcolumn` of line `startline` to @@ -83,21 +76,6 @@ class XMLParent extends @xmlparent { /** Gets the number of places in the body of this XML parent where text occurs. */ int getNumberOfCharacterSets() { result = count(int pos | xmlChars(_, _, this, pos, _, _)) } - /** - * DEPRECATED: Internal. - * - * Append the character sequences of this XML parent from left to right, separated by a space, - * up to a specified (zero-based) index. - */ - deprecated string charsSetUpTo(int n) { - n = 0 and xmlChars(_, result, this, 0, _, _) - or - n > 0 and - exists(string chars | xmlChars(_, chars, this, n, _, _) | - result = this.charsSetUpTo(n - 1) + " " + chars - ) - } - /** * Gets the result of appending all the character sequences of this XML parent from * left to right, separated by a space. diff --git a/csharp/ql/lib/semmle/code/csharp/commons/Assertions.qll b/csharp/ql/lib/semmle/code/csharp/commons/Assertions.qll index 4f364147395..df8ae6ea6ed 100644 --- a/csharp/ql/lib/semmle/code/csharp/commons/Assertions.qll +++ b/csharp/ql/lib/semmle/code/csharp/commons/Assertions.qll @@ -59,13 +59,6 @@ abstract class AssertMethod extends Method { /** Gets the failure type if the assertion fails for argument `i`, if any. */ abstract AssertionFailure getAssertionFailure(int i); - - /** - * DEPRECATED: Use `getAssertionFailure(_)` instead. - * - * Gets the exception being thrown if the assertion fails, if any. - */ - deprecated final Class getExceptionClass() { this.getAssertionFailure(_).isException(result) } } /** A Boolean assertion method. */ @@ -76,34 +69,6 @@ abstract class BooleanAssertMethod extends AssertMethod { override int getAnAssertionIndex() { result = this.getAnAssertionIndex(_) } } -/** A positive assertion method. */ -deprecated class AssertTrueMethod extends AssertMethod { - private BooleanAssertMethod m; - - AssertTrueMethod() { - this = m and - exists(m.getAnAssertionIndex(true)) - } - - final override int getAnAssertionIndex() { result = m.getAnAssertionIndex() } - - final override AssertionFailure getAssertionFailure(int i) { result = m.getAssertionFailure(i) } -} - -/** A negated assertion method. */ -deprecated class AssertFalseMethod extends AssertMethod { - private BooleanAssertMethod m; - - AssertFalseMethod() { - this = m and - exists(m.getAnAssertionIndex(false)) - } - - final override int getAnAssertionIndex() { result = m.getAnAssertionIndex() } - - final override AssertionFailure getAssertionFailure(int i) { result = m.getAssertionFailure(i) } -} - /** A nullness assertion method. */ abstract class NullnessAssertMethod extends AssertMethod { /** @@ -115,34 +80,6 @@ abstract class NullnessAssertMethod extends AssertMethod { override int getAnAssertionIndex() { result = this.getAnAssertionIndex(_) } } -/** A `null` assertion method. */ -deprecated class AssertNullMethod extends AssertMethod { - private NullnessAssertMethod m; - - AssertNullMethod() { - this = m and - exists(m.getAnAssertionIndex(true)) - } - - final override int getAnAssertionIndex() { result = m.getAnAssertionIndex() } - - final override AssertionFailure getAssertionFailure(int i) { result = m.getAssertionFailure(i) } -} - -/** A non-`null` assertion method. */ -deprecated class AssertNonNullMethod extends AssertMethod { - private NullnessAssertMethod m; - - AssertNonNullMethod() { - this = m and - exists(m.getAnAssertionIndex(false)) - } - - final override int getAnAssertionIndex() { result = m.getAnAssertionIndex() } - - final override AssertionFailure getAssertionFailure(int i) { result = m.getAssertionFailure(i) } -} - /** An assertion, that is, a call to an assertion method. */ class Assertion extends MethodCall { private AssertMethod target; @@ -160,108 +97,6 @@ class Assertion extends MethodCall { result = this.getArgumentForParameter(p) ) } - - /** - * DEPRECATED: Use `getExpr(_)` instead. - * - * Gets an expression that this assertion pertains to. - */ - deprecated Expr getExpr() { result = this.getExpr(_) } - - /** - * Holds if basic block `succ` is immediately dominated by this assertion. - * That is, `succ` can only be reached from the callable entry point by - * going via *some* basic block `pred` containing this assertion, and `pred` - * is an immediate predecessor of `succ`. - * - * Moreover, this assertion corresponds to multiple control flow nodes, - * which is why - * - * ```ql - * exists(BasicBlock bb | - * bb.getANode() = this.getAControlFlowNode() | - * bb.immediatelyDominates(succ) - * ) - * ``` - * - * does not work. - */ - pragma[nomagic] - deprecated private predicate immediatelyDominatesBlockSplit(BasicBlock succ) { - // Only calculate dominance by explicit recursion for split nodes; - // all other nodes can use regular CFG dominance - this instanceof SplitControlFlowElement and - exists(BasicBlock bb | bb.getANode() = this.getAControlFlowNode() | - succ = bb.getASuccessor() and - forall(BasicBlock pred | pred = succ.getAPredecessor() and pred != bb | - succ.dominates(pred) - or - // `pred` might be another split of this element - pred.getANode().getElement() = this - ) - ) - } - - pragma[noinline] - deprecated private predicate strictlyDominatesJoinBlockPredecessor(JoinBlock jb, int i) { - this.strictlyDominatesSplit(jb.getJoinBlockPredecessor(i)) - } - - deprecated private predicate strictlyDominatesJoinBlockSplit(JoinBlock jb, int i) { - i = -1 and - this.strictlyDominatesJoinBlockPredecessor(jb, _) - or - this.strictlyDominatesJoinBlockSplit(jb, i - 1) and - ( - this.strictlyDominatesJoinBlockPredecessor(jb, i) - or - this.getAControlFlowNode().getBasicBlock() = jb.getJoinBlockPredecessor(i) - ) - } - - pragma[nomagic] - deprecated private predicate strictlyDominatesSplit(BasicBlock bb) { - this.immediatelyDominatesBlockSplit(bb) - or - // Equivalent with - // - // ```ql - // exists(JoinBlockPredecessor pred | pred = bb.getAPredecessor() | - // this.strictlyDominatesSplit(pred) - // ) and - // forall(JoinBlockPredecessor pred | pred = bb.getAPredecessor() | - // this.strictlyDominatesSplit(pred) - // or - // this.getAControlFlowNode().getBasicBlock() = pred - // ) - // ``` - // - // but uses no universal recursion for better performance. - exists(int last | last = max(int i | exists(bb.(JoinBlock).getJoinBlockPredecessor(i))) | - this.strictlyDominatesJoinBlockSplit(bb, last) - ) - or - not bb instanceof JoinBlock and - this.strictlyDominatesSplit(bb.getAPredecessor()) - } - - /** - * DEPRECATED: Use `getExpr().controlsBlock()` instead. - * - * Holds if this assertion strictly dominates basic block `bb`. That is, `bb` - * can only be reached from the callable entry point by going via *some* basic - * block containing this element. - * - * This predicate is different from - * `this.getAControlFlowNode().getBasicBlock().strictlyDominates(bb)` - * in that it takes control flow splitting into account. - */ - pragma[nomagic] - deprecated predicate strictlyDominates(BasicBlock bb) { - this.strictlyDominatesSplit(bb) - or - this.getAControlFlowNode().getBasicBlock().strictlyDominates(bb) - } } /** A trivially failing assertion, for example `Debug.Assert(false)`. */ @@ -551,16 +386,6 @@ class ForwarderBooleanAssertMethod extends BooleanAssertMethod { } } -/** A method that forwards to a positive assertion method. */ -deprecated class ForwarderAssertTrueMethod extends ForwarderBooleanAssertMethod { - ForwarderAssertTrueMethod() { exists(this.getAnAssertionIndex(true)) } -} - -/** A method that forwards to a negated assertion method. */ -deprecated class ForwarderAssertFalseMethod extends ForwarderBooleanAssertMethod { - ForwarderAssertFalseMethod() { exists(this.getAnAssertionIndex(false)) } -} - /** A method that forwards to a nullness assertion method. */ class ForwarderNullnessAssertMethod extends NullnessAssertMethod { private ForwarderAssertMethod forwarder; @@ -580,15 +405,5 @@ class ForwarderNullnessAssertMethod extends NullnessAssertMethod { } } -/** A method that forwards to a `null` assertion method. */ -deprecated class ForwarderAssertNullMethod extends ForwarderNullnessAssertMethod { - ForwarderAssertNullMethod() { exists(this.getAnAssertionIndex(true)) } -} - -/** A method that forwards to a non-`null` assertion method. */ -deprecated class ForwarderAssertNonNullMethod extends ForwarderNullnessAssertMethod { - ForwarderAssertNonNullMethod() { exists(this.getAnAssertionIndex(false)) } -} - /** Holds if expression `e` appears in an assertion. */ predicate isExprInAssertion(Expr e) { e = any(Assertion a).getExpr(_).getAChildExpr*() } diff --git a/csharp/ql/lib/semmle/code/csharp/commons/StructuralComparison.qll b/csharp/ql/lib/semmle/code/csharp/commons/StructuralComparison.qll index ceac3b03aca..90755f2976c 100644 --- a/csharp/ql/lib/semmle/code/csharp/commons/StructuralComparison.qll +++ b/csharp/ql/lib/semmle/code/csharp/commons/StructuralComparison.qll @@ -5,6 +5,36 @@ import csharp +abstract private class GvnKind extends TGvnKind { + abstract string toString(); +} + +private class GvnKindExpr extends GvnKind, TGvnKindExpr { + private int kind; + + GvnKindExpr() { this = TGvnKindExpr(kind) } + + override string toString() { result = "Expr(" + kind + ")" } +} + +private class GvnKindStmt extends GvnKind, TGvnKindStmt { + private int kind; + + GvnKindStmt() { this = TGvnKindStmt(kind) } + + override string toString() { result = "Stmt(" + kind + ")" } +} + +private class GvnKindDeclaration extends GvnKind, TGvnKindDeclaration { + private int kind; + private boolean isTargetThis; + private Declaration d; + + GvnKindDeclaration() { this = TGvnKindDeclaration(kind, isTargetThis, d) } + + override string toString() { result = "Expr(" + kind + ")," + isTargetThis + "," + d } +} + /** Gets the declaration referenced by the expression `e`, if any. */ private Declaration referenceAttribute(Expr e) { result = e.(MethodCall).getTarget() @@ -14,17 +44,158 @@ private Declaration referenceAttribute(Expr e) { result = e.(Access).getTarget() } -/** Gets the AST node kind element `e`. */ -private int elementKind(ControlFlowElement e) { - expressions(e, result, _) +/** Gets a Boolean indicating whether the target of the expression `e` is `this`. */ +private boolean isTargetThis(Expr e) { + result = true and e.(MemberAccess).targetIsThisInstance() or - exists(int k | statements(e, k) | result = -k) + result = false and not e.(MemberAccess).targetIsThisInstance() } -private int getNumberOfActualChildren(ControlFlowElement e) { - if e.(MemberAccess).targetIsThisInstance() - then result = e.getNumberOfChildren() - 1 - else result = e.getNumberOfChildren() +/** + * A global value number (GVN) for a control flow element. + * + * GVNs are used to map control flow elements to a representation that + * omits location information, that is, two elements that are structurally + * equal will be mapped to the same GVN. + */ +class Gvn extends TGvn { + /** Gets the string representation of this global value number. */ + string toString() { none() } +} + +private class ConstantGvn extends Gvn, TConstantGvn { + override string toString() { this = TConstantGvn(result) } +} + +private class GvnNil extends Gvn, TGvnNil { + private GvnKind kind; + + GvnNil() { this = TGvnNil(kind) } + + override string toString() { result = "(kind:" + kind + ")" } +} + +private class GvnCons extends Gvn, TGvnCons { + private Gvn head; + private Gvn tail; + + GvnCons() { this = TGvnCons(head, tail) } + + override string toString() { result = "(" + head + " :: " + tail + ")" } +} + +pragma[noinline] +private predicate gvnKindDeclaration(Expr e, int kind, boolean isTargetThis, Declaration d) { + isTargetThis = isTargetThis(e) and + // guard against elements with multiple declaration targets (DB inconsistency), + // which may result in a combinatorial explosion + d = unique(Declaration d0 | d0 = referenceAttribute(e) | d0) and + expressions(e, kind, _) +} + +/** + * Gets the `GvnKind` of the element `cfe`. + * + * In case `cfe` is a reference attribute, we encode the entire declaration and whether + * the target is semantically equivalent to `this`. + */ +private GvnKind getGvnKind(ControlFlowElement cfe) { + exists(int kind, boolean isTargetThis, Declaration d | + gvnKindDeclaration(cfe, kind, isTargetThis, d) and + result = TGvnKindDeclaration(kind, isTargetThis, d) + ) + or + exists(int kind | + not exists(referenceAttribute(cfe)) and + expressions(cfe, kind, _) and + result = TGvnKindExpr(kind) + or + statements(cfe, kind) and + result = TGvnKindStmt(kind) + ) +} + +private Gvn toGvn(ControlFlowElement cfe, GvnKind kind, int index) { + kind = getGvnKind(cfe) and + result = TGvnNil(kind) and + index = -1 + or + exists(Gvn head, Gvn tail | + toGvnCons(cfe, kind, index, head, tail) and + result = TGvnCons(head, tail) + ) +} + +private int getNumberOfActualChildren(ControlFlowElement cfe) { + if cfe.(MemberAccess).targetIsThisInstance() + then result = cfe.getNumberOfChildren() - 1 + else result = cfe.getNumberOfChildren() +} + +private ControlFlowElement getRankedChild(ControlFlowElement cfe, int rnk) { + result = + rank[rnk + 1](ControlFlowElement child, int j | + child = cfe.getChild(j) and + ( + j >= 0 + or + j = -1 and not cfe.(MemberAccess).targetIsThisInstance() + ) + | + child order by j + ) +} + +pragma[noinline] +private Gvn toGvnChild(ControlFlowElement cfe, int index) { + result = toGvn(getRankedChild(cfe, index)) +} + +pragma[noinline] +private predicate toGvnCons(ControlFlowElement cfe, GvnKind kind, int index, Gvn head, Gvn tail) { + tail = toGvn(cfe, kind, index - 1) and + head = toGvnChild(cfe, index) +} + +cached +private module Cached { + cached + newtype TGvnKind = + TGvnKindExpr(int kind) { expressions(_, kind, _) } or + TGvnKindStmt(int kind) { statements(_, kind) } or + TGvnKindDeclaration(int kind, boolean thisTarget, Declaration d) { + exists(Expr e | + d = referenceAttribute(e) and thisTarget = isTargetThis(e) and expressions(e, kind, _) + ) + } + + cached + newtype TGvn = + TConstantGvn(string s) { s = any(Expr e).getValue() } or + TGvnNil(GvnKind gkind) or + TGvnCons(Gvn head, Gvn tail) { toGvnCons(_, _, _, head, tail) } + + /** Gets the global value number of the element `cfe`. */ + cached + Gvn toGvnCached(ControlFlowElement cfe) { + result = TConstantGvn(cfe.(Expr).getValue()) + or + not exists(cfe.(Expr).getValue()) and + exists(GvnKind kind, int index | + result = toGvn(cfe, kind, index - 1) and + index = getNumberOfActualChildren(cfe) + ) + } +} + +private import Cached + +predicate toGvn = toGvnCached/1; + +pragma[inline] +private predicate sameGvn(ControlFlowElement x, ControlFlowElement y) { + pragma[only_bind_into](toGvn(pragma[only_bind_out](x))) = + pragma[only_bind_into](toGvn(pragma[only_bind_out](y))) } /** @@ -57,87 +228,12 @@ abstract class StructuralComparisonConfiguration extends string { */ abstract predicate candidate(ControlFlowElement x, ControlFlowElement y); - private predicate candidateInternal(ControlFlowElement x, ControlFlowElement y) { - candidate(x, y) - or - exists(ControlFlowElement xParent, ControlFlowElement yParent, int i | - candidateInternalChild(xParent, i, x, yParent) - | - y = yParent.getChild(i) - ) - } - - pragma[noinline] - private predicate candidateInternalChild( - ControlFlowElement x, int i, ControlFlowElement xChild, ControlFlowElement y - ) { - candidateInternal(x, y) and - xChild = x.getChild(i) - } - - private predicate sameByValue(Expr x, Expr y) { sameByValueAux(x, y, y.getValue()) } - - pragma[nomagic] - private predicate sameByValueAux(Expr x, Expr y, string value) { - candidateInternal(x, y) and - value = x.getValue() - } - - private ControlFlowElement getRankedChild(ControlFlowElement cfe, int rnk, int i) { - (candidateInternal(cfe, _) or candidateInternal(_, cfe)) and - i = - rank[rnk](int j | - exists(ControlFlowElement child | child = cfe.getChild(j) | - not (j = -1 and cfe.(MemberAccess).targetIsThisInstance()) - ) - ) and - result = cfe.getChild(i) - } - - pragma[nomagic] - private predicate sameByStructure0( - ControlFlowElement x, ControlFlowElement y, int elementKind, int children - ) { - candidateInternal(x, y) and - elementKind = elementKind(x) and - children = getNumberOfActualChildren(x) and - not (x.(Expr).hasValue() and y.(Expr).hasValue()) - } - - pragma[nomagic] - private predicate sameByStructure(ControlFlowElement x, ControlFlowElement y, int i) { - i = 0 and - // At least one of `x` and `y` must not have a value, they must have - // the same kind, and the same number of children - sameByStructure0(x, y, elementKind(y), getNumberOfActualChildren(y)) and - // If one of them has a reference attribute, they should both reference - // the same node - (exists(referenceAttribute(x)) implies referenceAttribute(x) = referenceAttribute(y)) and - // x is a member access on `this` iff y is - (x.(MemberAccess).targetIsThisInstance() implies y.(MemberAccess).targetIsThisInstance()) and - (y.(MemberAccess).targetIsThisInstance() implies x.(MemberAccess).targetIsThisInstance()) - or - exists(int j | sameByStructure(x, y, i - 1) | - sameInternal(getRankedChild(x, i, j), getRankedChild(y, i, j)) - ) - } - - pragma[nomagic] - private predicate sameInternal(ControlFlowElement x, ControlFlowElement y) { - sameByValue(x, y) - or - sameByStructure(x, y, getNumberOfActualChildren(x)) - } - /** * Holds if elements `x` and `y` structurally equal. `x` and `y` must be * flagged as candidates for structural equality, that is, * `candidate(x, y)` must hold. */ - predicate same(ControlFlowElement x, ControlFlowElement y) { - candidate(x, y) and - sameInternal(x, y) - } + predicate same(ControlFlowElement x, ControlFlowElement y) { candidate(x, y) and sameGvn(x, y) } } /** @@ -183,86 +279,11 @@ module Internal { */ abstract predicate candidate(ControlFlowElement x, ControlFlowElement y); - private predicate candidateInternal(ControlFlowElement x, ControlFlowElement y) { - candidate(x, y) - or - exists(ControlFlowElement xParent, ControlFlowElement yParent, int i | - candidateInternalChild(xParent, i, x, yParent) - | - y = yParent.getChild(i) - ) - } - - pragma[noinline] - private predicate candidateInternalChild( - ControlFlowElement x, int i, ControlFlowElement xChild, ControlFlowElement y - ) { - candidateInternal(x, y) and - xChild = x.getChild(i) - } - - private predicate sameByValue(Expr x, Expr y) { sameByValueAux(x, y, y.getValue()) } - - pragma[nomagic] - private predicate sameByValueAux(Expr x, Expr y, string value) { - candidateInternal(x, y) and - value = x.getValue() - } - - private ControlFlowElement getRankedChild(ControlFlowElement cfe, int rnk, int i) { - (candidateInternal(cfe, _) or candidateInternal(_, cfe)) and - i = - rank[rnk](int j | - exists(ControlFlowElement child | child = cfe.getChild(j) | - not (j = -1 and cfe.(MemberAccess).targetIsThisInstance()) - ) - ) and - result = cfe.getChild(i) - } - - pragma[nomagic] - private predicate sameByStructure0( - ControlFlowElement x, ControlFlowElement y, int elementKind, int children - ) { - candidateInternal(x, y) and - elementKind = elementKind(x) and - children = getNumberOfActualChildren(x) and - not (x.(Expr).hasValue() and y.(Expr).hasValue()) - } - - pragma[nomagic] - private predicate sameByStructure(ControlFlowElement x, ControlFlowElement y, int i) { - i = 0 and - // At least one of `x` and `y` must not have a value, they must have - // the same kind, and the same number of children - sameByStructure0(x, y, elementKind(y), getNumberOfActualChildren(y)) and - // If one of them has a reference attribute, they should both reference - // the same node - (exists(referenceAttribute(x)) implies referenceAttribute(x) = referenceAttribute(y)) and - // x is a member access on `this` iff y is - (x.(MemberAccess).targetIsThisInstance() implies y.(MemberAccess).targetIsThisInstance()) and - (y.(MemberAccess).targetIsThisInstance() implies x.(MemberAccess).targetIsThisInstance()) - or - exists(int j | sameByStructure(x, y, i - 1) | - sameInternal(getRankedChild(x, i, j), getRankedChild(y, i, j)) - ) - } - - pragma[nomagic] - private predicate sameInternal(ControlFlowElement x, ControlFlowElement y) { - sameByValue(x, y) - or - sameByStructure(x, y, getNumberOfActualChildren(x)) - } - /** * Holds if elements `x` and `y` structurally equal. `x` and `y` must be * flagged as candidates for structural equality, that is, * `candidate(x, y)` must hold. */ - predicate same(ControlFlowElement x, ControlFlowElement y) { - candidate(x, y) and - sameInternal(x, y) - } + predicate same(ControlFlowElement x, ControlFlowElement y) { candidate(x, y) and sameGvn(x, y) } } } diff --git a/csharp/ql/lib/semmle/code/csharp/controlflow/ControlFlowElement.qll b/csharp/ql/lib/semmle/code/csharp/controlflow/ControlFlowElement.qll index 9e7fd92d2a4..6c6a66c4ac2 100644 --- a/csharp/ql/lib/semmle/code/csharp/controlflow/ControlFlowElement.qll +++ b/csharp/ql/lib/semmle/code/csharp/controlflow/ControlFlowElement.qll @@ -227,35 +227,4 @@ class ControlFlowElement extends ExprOrStmtParent, @control_flow_element { cb.getLastNode() = this.getAControlFlowNode() and cb.controls(controlled, s) } - - /** DEPRECATED: Use `controlsBlock/3` instead. */ - deprecated predicate controlsBlock(BasicBlock controlled, ConditionalSuccessor s) { - this.controlsBlock(controlled, s, _) - } - - /** - * DEPRECATED. - * - * Holds if control flow element `controlled` is controlled by this control flow - * element with conditional value `s`. That is, `controlled` can only be reached - * from the callable entry point by going via the `s` edge out of this element. - * - * This predicate is different from - * - * ```ql - * exists(ConditionBlock cb | - * cb.getLastNode() = this.getAControlFlowNode() | - * cb.controls(controlled.getAControlFlowNode().getBasicBlock(), s) - * ) - * ``` - * - * as control flow splitting is taken into account. - */ - // potentially very large predicate, so must be inlined - pragma[inline] - deprecated predicate controlsElement(ControlFlowElement controlled, ConditionalSuccessor s) { - forex(BasicBlock bb | bb = controlled.getAControlFlowNode().getBasicBlock() | - this.controlsBlock(bb, s) - ) - } } diff --git a/csharp/ql/lib/semmle/code/csharp/controlflow/Guards.qll b/csharp/ql/lib/semmle/code/csharp/controlflow/Guards.qll index 7e9b8f7818a..062be133c58 100644 --- a/csharp/ql/lib/semmle/code/csharp/controlflow/Guards.qll +++ b/csharp/ql/lib/semmle/code/csharp/controlflow/Guards.qll @@ -1000,7 +1000,7 @@ module Internal { // The predicates in this module should be evaluated in the same stage as the CFG // construction stage. This is to avoid recomputation of pre-basic-blocks and // pre-SSA predicates - private module PreCFG { + private module PreCfg { private import semmle.code.csharp.controlflow.internal.PreBasicBlocks as PreBasicBlocks private import semmle.code.csharp.controlflow.internal.PreSsa @@ -1414,7 +1414,7 @@ module Internal { } cached - private module CachedWithCFG { + private module CachedWithCfg { private import semmle.code.csharp.Caching cached @@ -1719,10 +1719,10 @@ module Internal { } } - import CachedWithCFG + import CachedWithCfg } - import PreCFG + import PreCfg private predicate interestingDescendantCandidate(Expr e) { guardControls(e, _, _) diff --git a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/Splitting.qll b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/Splitting.qll index b6b0c95ddc0..02fb893cb7f 100644 --- a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/Splitting.qll +++ b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/Splitting.qll @@ -511,13 +511,6 @@ module FinallySplitting { predicate isEntryNode() { first(try.getFinally(), this) } } - /** A control flow element that does not belong to a `finally` block. */ - private class NonFinallyControlFlowElement extends ControlFlowElement { - NonFinallyControlFlowElement() { - not this = any(Statements::TryStmtTree t).getAFinallyDescendant() - } - } - /** * A split for elements belonging to a `finally` block, which determines how to * continue execution after leaving the `finally` block. For example, in diff --git a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/SuccessorType.qll b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/SuccessorType.qll index 76da2fb62ef..154ab9423b9 100644 --- a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/SuccessorType.qll +++ b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/SuccessorType.qll @@ -26,9 +26,6 @@ private newtype TSuccessorType = class SuccessorType extends TSuccessorType { /** Gets a textual representation of successor type. */ string toString() { none() } - - /** Holds if this successor type matches completion `c`. */ - deprecated predicate matchesCompletion(Completion c) { this = c.getAMatchingSuccessorType() } } /** Provides different types of control flow successor types. */ diff --git a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/pressa/SsaImplCommon.qll b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/pressa/SsaImplCommon.qll index 19bf1d4f27d..eed0d050735 100644 --- a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/pressa/SsaImplCommon.qll +++ b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/pressa/SsaImplCommon.qll @@ -287,20 +287,6 @@ private module SsaDefReaches { ) } - /** - * Holds if the SSA definition of `v` at `def` reaches uncertain SSA definition - * `redef` in the same basic block, without crossing another SSA definition of `v`. - */ - predicate ssaDefReachesUncertainDefWithinBlock( - SourceVariable v, Definition def, UncertainWriteDefinition redef - ) { - exists(BasicBlock bb, int rnk, int i | - ssaDefReachesRank(bb, def, rnk, v) and - rnk = ssaRefRank(bb, i, v, SsaDef()) - 1 and - redef.definesAt(v, bb, i) - ) - } - /** * Same as `ssaRefRank()`, but restricted to a particular SSA definition `def`. */ diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/ModulusAnalysis.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/ModulusAnalysis.qll index 2a58cba6209..b919d143a39 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/ModulusAnalysis.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/ModulusAnalysis.qll @@ -111,13 +111,6 @@ private predicate evenlyDivisibleExpr(Expr e, int factor) { ) } -/** - * Holds if `rix` is the number of input edges to `phi`. - */ -private predicate maxPhiInputRank(SsaPhiNode phi, int rix) { - rix = max(int r | rankedPhiInput(phi, _, _, r)) -} - /** * Gets the remainder of `val` modulo `mod`. * diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/SSA.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/SSA.qll index 80b7d5d6d36..e900b36a023 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/SSA.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/SSA.qll @@ -427,11 +427,6 @@ module Ssa { not result instanceof PhiNode } - /** - * DEPRECATED: Use `definesAt/3` instead. - */ - deprecated predicate definesAt(ControlFlow::BasicBlock bb, int i) { this.definesAt(_, bb, i) } - /** * Gets the syntax element associated with this SSA definition, if any. * This is either an expression, for example `x = 0`, a parameter, or a @@ -655,14 +650,6 @@ module Ssa { override Location getLocation() { result = this.getQualifierDefinition().getLocation() } } - /** - * An SSA definition that has no actual semantics, but simply serves to - * merge or filter data flow. - * - * Phi nodes are the canonical (and currently only) example. - */ - deprecated class PseudoDefinition = PhiNode; - /** * An SSA phi node, that is, a pseudo definition for a variable at a point * in the flow graph where otherwise two or more definitions for the variable 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 87593b2dcd3..f9f4a4ad50d 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll @@ -2026,3 +2026,8 @@ abstract class SyntheticField extends string { /** Gets the type of this synthetic field. */ Type getType() { result instanceof ObjectType } } + +/** + * Holds if the the content `c` is a container. + */ +predicate containerContent(DataFlow::Content c) { c instanceof DataFlow::ElementContent } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll index b6d749e18fd..7151b5cb29f 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll @@ -204,12 +204,6 @@ class Content extends TContent { /** Gets the location of this content. */ Location getLocation() { none() } - - /** Gets the type of the object containing this content. */ - deprecated Gvn::GvnType getContainerType() { none() } - - /** Gets the type of this content. */ - deprecated Gvn::GvnType getType() { none() } } /** A reference to a field. */ @@ -224,12 +218,6 @@ class FieldContent extends Content, TFieldContent { override string toString() { result = "field " + f.getName() } override Location getLocation() { result = f.getLocation() } - - deprecated override Gvn::GvnType getContainerType() { - result = Gvn::getGlobalValueNumber(f.getDeclaringType()) - } - - deprecated override Gvn::GvnType getType() { result = Gvn::getGlobalValueNumber(f.getType()) } } /** A reference to a synthetic field. */ @@ -256,12 +244,6 @@ class PropertyContent extends Content, TPropertyContent { override string toString() { result = "property " + p.getName() } override Location getLocation() { result = p.getLocation() } - - deprecated override Gvn::GvnType getContainerType() { - result = Gvn::getGlobalValueNumber(p.getDeclaringType()) - } - - deprecated override Gvn::GvnType getType() { result = Gvn::getGlobalValueNumber(p.getType()) } } /** A reference to an element in a collection. */ diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImplCommon.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImplCommon.qll index 19bf1d4f27d..eed0d050735 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImplCommon.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImplCommon.qll @@ -287,20 +287,6 @@ private module SsaDefReaches { ) } - /** - * Holds if the SSA definition of `v` at `def` reaches uncertain SSA definition - * `redef` in the same basic block, without crossing another SSA definition of `v`. - */ - predicate ssaDefReachesUncertainDefWithinBlock( - SourceVariable v, Definition def, UncertainWriteDefinition redef - ) { - exists(BasicBlock bb, int rnk, int i | - ssaDefReachesRank(bb, def, rnk, v) and - rnk = ssaRefRank(bb, i, v, SsaDef()) - 1 and - redef.definesAt(v, bb, i) - ) - } - /** * Same as `ssaRefRank()`, but restricted to a particular SSA definition `def`. */ diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll index f2e99db0663..2df41e00299 100755 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll @@ -31,8 +31,6 @@ predicate defaultTaintSanitizerGuard(DataFlow::BarrierGuard guard) { none() } bindingset[node] predicate defaultImplicitTaintRead(DataFlow::Node node, DataFlow::Content c) { none() } -deprecated predicate localAdditionalTaintStep = defaultAdditionalTaintStep/2; - private CIL::DataFlowNode asCilDataFlowNode(DataFlow::Node node) { result = node.asParameter() or result = node.asExpr() diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/basessa/SsaImplCommon.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/basessa/SsaImplCommon.qll index 19bf1d4f27d..eed0d050735 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/basessa/SsaImplCommon.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/basessa/SsaImplCommon.qll @@ -287,20 +287,6 @@ private module SsaDefReaches { ) } - /** - * Holds if the SSA definition of `v` at `def` reaches uncertain SSA definition - * `redef` in the same basic block, without crossing another SSA definition of `v`. - */ - predicate ssaDefReachesUncertainDefWithinBlock( - SourceVariable v, Definition def, UncertainWriteDefinition redef - ) { - exists(BasicBlock bb, int rnk, int i | - ssaDefReachesRank(bb, def, rnk, v) and - rnk = ssaRefRank(bb, i, v, SsaDef()) - 1 and - redef.definesAt(v, bb, i) - ) - } - /** * Same as `ssaRefRank()`, but restricted to a particular SSA definition `def`. */ diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/ModulusAnalysisSpecific.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/ModulusAnalysisSpecific.qll index 030020ede63..74aee61e690 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/ModulusAnalysisSpecific.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/ModulusAnalysisSpecific.qll @@ -43,37 +43,4 @@ module Private { predicate ssaUpdateStep = RU::ssaUpdateStep/3; Expr getABasicBlockExpr(BasicBlock bb) { result = bb.getANode() } - - private class PhiInputEdgeBlock extends BasicBlock { - PhiInputEdgeBlock() { this = any(SsaReadPositionPhiInputEdge edge).getOrigBlock() } - } - - int getId(PhiInputEdgeBlock bb) { - exists(CfgImpl::ControlFlowTree::Range_ t | CfgImpl::ControlFlowTree::idOf(t, result) | - t = bb.getFirstNode().getElement() - or - t = bb.(CS::ControlFlow::BasicBlocks::EntryBlock).getCallable() - ) - } - - private string getSplitString(PhiInputEdgeBlock bb) { - result = bb.getFirstNode().(CS::ControlFlow::Nodes::ElementNode).getSplitsString() - or - not exists(bb.getFirstNode().(CS::ControlFlow::Nodes::ElementNode).getSplitsString()) and - result = "" - } - - /** - * Holds if `inp` is an input to `phi` along `edge` and this input has index `r` - * in an arbitrary 1-based numbering of the input edges to `phi`. - */ - predicate rankedPhiInput(SsaPhiNode phi, SsaVariable inp, SsaReadPositionPhiInputEdge edge, int r) { - edge.phiInput(phi, inp) and - edge = - rank[r](SsaReadPositionPhiInputEdge e | - e.phiInput(phi, _) - | - e order by getId(e.getOrigBlock()), getSplitString(e.getOrigBlock()) - ) - } } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll index e450c11b5ab..08335f6680d 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll @@ -3,6 +3,7 @@ */ private import SsaReadPositionSpecific +import SsaReadPositionSpecific::Public private newtype TSsaReadPosition = TSsaReadPositionBlock(BasicBlock bb) { bb = getAReadBasicBlock(_) } or @@ -55,3 +56,10 @@ class SsaReadPositionPhiInputEdge extends SsaReadPosition, TSsaReadPositionPhiIn override string toString() { result = "edge" } } + +/** + * Holds if `rix` is the number of input edges to `phi`. + */ +predicate maxPhiInputRank(SsaPhiNode phi, int rix) { + rix = max(int r | rankedPhiInput(phi, _, _, r)) +} diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/SsaReadPositionSpecific.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/SsaReadPositionSpecific.qll index 7afd9a2a33d..6b91651691d 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/SsaReadPositionSpecific.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/SsaReadPositionSpecific.qll @@ -3,6 +3,8 @@ */ private import csharp +private import SsaReadPositionCommon +private import semmle.code.csharp.controlflow.internal.ControlFlowGraphImpl as CfgImpl class SsaVariable = Ssa::Definition; @@ -14,3 +16,41 @@ class BasicBlock = ControlFlow::BasicBlock; BasicBlock getAReadBasicBlock(SsaVariable v) { result = v.getARead().getAControlFlowNode().getBasicBlock() } + +private class PhiInputEdgeBlock extends BasicBlock { + PhiInputEdgeBlock() { this = any(SsaReadPositionPhiInputEdge edge).getOrigBlock() } +} + +private int getId(PhiInputEdgeBlock bb) { + exists(CfgImpl::ControlFlowTree::Range_ t | CfgImpl::ControlFlowTree::idOf(t, result) | + t = bb.getFirstNode().getElement() + or + t = bb.(ControlFlow::BasicBlocks::EntryBlock).getCallable() + ) +} + +private string getSplitString(PhiInputEdgeBlock bb) { + result = bb.getFirstNode().(ControlFlow::Nodes::ElementNode).getSplitsString() + or + not exists(bb.getFirstNode().(ControlFlow::Nodes::ElementNode).getSplitsString()) and + result = "" +} + +/** + * Declarations to be exposed to users of SsaReadPositionCommon. + */ +module Public { + /** + * Holds if `inp` is an input to `phi` along `edge` and this input has index `r` + * in an arbitrary 1-based numbering of the input edges to `phi`. + */ + predicate rankedPhiInput(SsaPhiNode phi, SsaVariable inp, SsaReadPositionPhiInputEdge edge, int r) { + edge.phiInput(phi, inp) and + edge = + rank[r](SsaReadPositionPhiInputEdge e | + e.phiInput(phi, _) + | + e order by getId(e.getOrigBlock()), getSplitString(e.getOrigBlock()) + ) + } +} diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll index 43555af1af9..b344ea9a864 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll @@ -64,13 +64,30 @@ abstract class Configuration extends DataFlow::Configuration { override predicate isSource(DataFlow::Node source) { none() } /** - * Holds if `sink` is a relevant taint sink. + * Holds if `source` is a relevant taint source with the given initial + * `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } + + /** + * Holds if `sink` is a relevant taint sink * * The smaller this predicate is, the faster `hasFlow()` will converge. */ // overridden to provide taint-tracking specific qldoc override predicate isSink(DataFlow::Node sink) { none() } + /** + * Holds if `sink` is a relevant taint sink accepting `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } + /** Holds if the node `node` is a taint sanitizer. */ predicate isSanitizer(DataFlow::Node node) { none() } @@ -79,6 +96,16 @@ abstract class Configuration extends DataFlow::Configuration { defaultTaintSanitizer(node) } + /** + * Holds if the node `node` is a taint sanitizer when the flow state is + * `state`. + */ + predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } + + final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { + this.isSanitizer(node, state) + } + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } @@ -107,6 +134,25 @@ abstract class Configuration extends DataFlow::Configuration { defaultAdditionalTaintStep(node1, node2) } + /** + * Holds if the additional taint propagation step from `node1` to `node2` + * must be taken into account in the analysis. This step is only applicable + * in `state1` and updates the flow state to `state2`. + */ + predicate isAdditionalTaintStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + none() + } + + final override predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + this.isAdditionalTaintStep(node1, state1, node2, state2) + } + override predicate allowImplicitRead(DataFlow::Node node, DataFlow::Content c) { (this.isSink(node) or this.isAdditionalTaintStep(node, _)) and defaultImplicitTaintRead(node, c) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll index 43555af1af9..b344ea9a864 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll @@ -64,13 +64,30 @@ abstract class Configuration extends DataFlow::Configuration { override predicate isSource(DataFlow::Node source) { none() } /** - * Holds if `sink` is a relevant taint sink. + * Holds if `source` is a relevant taint source with the given initial + * `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } + + /** + * Holds if `sink` is a relevant taint sink * * The smaller this predicate is, the faster `hasFlow()` will converge. */ // overridden to provide taint-tracking specific qldoc override predicate isSink(DataFlow::Node sink) { none() } + /** + * Holds if `sink` is a relevant taint sink accepting `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } + /** Holds if the node `node` is a taint sanitizer. */ predicate isSanitizer(DataFlow::Node node) { none() } @@ -79,6 +96,16 @@ abstract class Configuration extends DataFlow::Configuration { defaultTaintSanitizer(node) } + /** + * Holds if the node `node` is a taint sanitizer when the flow state is + * `state`. + */ + predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } + + final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { + this.isSanitizer(node, state) + } + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } @@ -107,6 +134,25 @@ abstract class Configuration extends DataFlow::Configuration { defaultAdditionalTaintStep(node1, node2) } + /** + * Holds if the additional taint propagation step from `node1` to `node2` + * must be taken into account in the analysis. This step is only applicable + * in `state1` and updates the flow state to `state2`. + */ + predicate isAdditionalTaintStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + none() + } + + final override predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + this.isAdditionalTaintStep(node1, state1, node2, state2) + } + override predicate allowImplicitRead(DataFlow::Node node, DataFlow::Content c) { (this.isSink(node) or this.isAdditionalTaintStep(node, _)) and defaultImplicitTaintRead(node, c) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking3/TaintTrackingImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking3/TaintTrackingImpl.qll index 43555af1af9..b344ea9a864 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking3/TaintTrackingImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking3/TaintTrackingImpl.qll @@ -64,13 +64,30 @@ abstract class Configuration extends DataFlow::Configuration { override predicate isSource(DataFlow::Node source) { none() } /** - * Holds if `sink` is a relevant taint sink. + * Holds if `source` is a relevant taint source with the given initial + * `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } + + /** + * Holds if `sink` is a relevant taint sink * * The smaller this predicate is, the faster `hasFlow()` will converge. */ // overridden to provide taint-tracking specific qldoc override predicate isSink(DataFlow::Node sink) { none() } + /** + * Holds if `sink` is a relevant taint sink accepting `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } + /** Holds if the node `node` is a taint sanitizer. */ predicate isSanitizer(DataFlow::Node node) { none() } @@ -79,6 +96,16 @@ abstract class Configuration extends DataFlow::Configuration { defaultTaintSanitizer(node) } + /** + * Holds if the node `node` is a taint sanitizer when the flow state is + * `state`. + */ + predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } + + final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { + this.isSanitizer(node, state) + } + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } @@ -107,6 +134,25 @@ abstract class Configuration extends DataFlow::Configuration { defaultAdditionalTaintStep(node1, node2) } + /** + * Holds if the additional taint propagation step from `node1` to `node2` + * must be taken into account in the analysis. This step is only applicable + * in `state1` and updates the flow state to `state2`. + */ + predicate isAdditionalTaintStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + none() + } + + final override predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + this.isAdditionalTaintStep(node1, state1, node2, state2) + } + override predicate allowImplicitRead(DataFlow::Node node, DataFlow::Content c) { (this.isSink(node) or this.isAdditionalTaintStep(node, _)) and defaultImplicitTaintRead(node, c) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking4/TaintTrackingImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking4/TaintTrackingImpl.qll index 43555af1af9..b344ea9a864 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking4/TaintTrackingImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking4/TaintTrackingImpl.qll @@ -64,13 +64,30 @@ abstract class Configuration extends DataFlow::Configuration { override predicate isSource(DataFlow::Node source) { none() } /** - * Holds if `sink` is a relevant taint sink. + * Holds if `source` is a relevant taint source with the given initial + * `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } + + /** + * Holds if `sink` is a relevant taint sink * * The smaller this predicate is, the faster `hasFlow()` will converge. */ // overridden to provide taint-tracking specific qldoc override predicate isSink(DataFlow::Node sink) { none() } + /** + * Holds if `sink` is a relevant taint sink accepting `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } + /** Holds if the node `node` is a taint sanitizer. */ predicate isSanitizer(DataFlow::Node node) { none() } @@ -79,6 +96,16 @@ abstract class Configuration extends DataFlow::Configuration { defaultTaintSanitizer(node) } + /** + * Holds if the node `node` is a taint sanitizer when the flow state is + * `state`. + */ + predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } + + final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { + this.isSanitizer(node, state) + } + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } @@ -107,6 +134,25 @@ abstract class Configuration extends DataFlow::Configuration { defaultAdditionalTaintStep(node1, node2) } + /** + * Holds if the additional taint propagation step from `node1` to `node2` + * must be taken into account in the analysis. This step is only applicable + * in `state1` and updates the flow state to `state2`. + */ + predicate isAdditionalTaintStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + none() + } + + final override predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + this.isAdditionalTaintStep(node1, state1, node2, state2) + } + override predicate allowImplicitRead(DataFlow::Node node, DataFlow::Content c) { (this.isSink(node) or this.isAdditionalTaintStep(node, _)) and defaultImplicitTaintRead(node, c) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking5/TaintTrackingImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking5/TaintTrackingImpl.qll index 43555af1af9..b344ea9a864 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking5/TaintTrackingImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking5/TaintTrackingImpl.qll @@ -64,13 +64,30 @@ abstract class Configuration extends DataFlow::Configuration { override predicate isSource(DataFlow::Node source) { none() } /** - * Holds if `sink` is a relevant taint sink. + * Holds if `source` is a relevant taint source with the given initial + * `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } + + /** + * Holds if `sink` is a relevant taint sink * * The smaller this predicate is, the faster `hasFlow()` will converge. */ // overridden to provide taint-tracking specific qldoc override predicate isSink(DataFlow::Node sink) { none() } + /** + * Holds if `sink` is a relevant taint sink accepting `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } + /** Holds if the node `node` is a taint sanitizer. */ predicate isSanitizer(DataFlow::Node node) { none() } @@ -79,6 +96,16 @@ abstract class Configuration extends DataFlow::Configuration { defaultTaintSanitizer(node) } + /** + * Holds if the node `node` is a taint sanitizer when the flow state is + * `state`. + */ + predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } + + final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { + this.isSanitizer(node, state) + } + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } @@ -107,6 +134,25 @@ abstract class Configuration extends DataFlow::Configuration { defaultAdditionalTaintStep(node1, node2) } + /** + * Holds if the additional taint propagation step from `node1` to `node2` + * must be taken into account in the analysis. This step is only applicable + * in `state1` and updates the flow state to `state2`. + */ + predicate isAdditionalTaintStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + none() + } + + final override predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + this.isAdditionalTaintStep(node1, state1, node2, state2) + } + override predicate allowImplicitRead(DataFlow::Node node, DataFlow::Content c) { (this.isSink(node) or this.isAdditionalTaintStep(node, _)) and defaultImplicitTaintRead(node, c) diff --git a/csharp/ql/lib/semmle/code/csharp/exprs/Creation.qll b/csharp/ql/lib/semmle/code/csharp/exprs/Creation.qll index c3bf63b1779..79dc36fd48d 100644 --- a/csharp/ql/lib/semmle/code/csharp/exprs/Creation.qll +++ b/csharp/ql/lib/semmle/code/csharp/exprs/Creation.qll @@ -435,10 +435,10 @@ class AnonymousFunctionExpr extends Expr, Callable, Modifiable, @anonymous_funct * A lambda expression, for example `(int x) => x + 1`. */ class LambdaExpr extends AnonymousFunctionExpr, @lambda_expr { - /* Holds if this lambda expression has explicit return type. */ + /** Holds if this lambda expression has explicit return type. */ predicate hasExplicitReturnType() { lambda_expr_return_type(this, _) } - /* Gets the explicit return type of this lambda expression, if any. */ + /** Gets the explicit return type of this lambda expression, if any. */ Type getExplicitReturnType() { lambda_expr_return_type(this, getTypeRef(result)) } override string toString() { result = "(...) => ..." } diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll index 2ffbfe6e7e1..54fa60e03f2 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll @@ -170,40 +170,6 @@ class InvalidFormatString extends StringLiteral { } } -/** Provides a dataflow configuration for format strings. */ -deprecated module FormatFlow { - private import semmle.code.csharp.dataflow.DataFlow - - private class FormatConfiguration extends DataFlow2::Configuration { - FormatConfiguration() { this = "format" } - - override predicate isSource(DataFlow::Node n) { n.asExpr() instanceof StringLiteral } - - override predicate isSink(DataFlow::Node n) { - exists(FormatCall c | n.asExpr() = c.getFormatExpr()) - } - } - - deprecated query predicate nodes = DataFlow2::PathGraph::nodes/3; - - deprecated query predicate edges = DataFlow2::PathGraph::edges/2; - - deprecated class PathNode = DataFlow2::PathNode; - - /** - * Holds if there is flow from string literal `lit` to the format string in - * `call`. `litNode` and `formatNode` are the corresponding data-flow path - * nodes. - */ - deprecated predicate hasFlowPath( - StringLiteral lit, PathNode litNode, FormatCall call, PathNode formatNode - ) { - litNode.getNode().asExpr() = lit and - formatNode.getNode().asExpr() = call.getFormatExpr() and - any(FormatConfiguration conf).hasFlowPath(litNode, formatNode) - } -} - /** * A method call to a method that formats a string, for example a call * to `string.Format()`. @@ -229,14 +195,6 @@ class FormatCall extends MethodCall { this.getArgument(this.getFirstArgument()).getType() instanceof ArrayType } - /** - * DEPRECATED: Use `FormatFlow::hasFlowPath()` instead. - * - * Gets a format string. Global data flow analysis is applied to retrieve all - * sources that can reach this method call. - */ - deprecated StringLiteral getAFormatSource() { FormatFlow::hasFlowPath(result, _, this, _) } - /** * Gets the number of supplied arguments (excluding the format string and format * provider). Does not return a value if the arguments are supplied in an array, @@ -255,11 +213,4 @@ class FormatCall extends MethodCall { index = this.getASuppliedArgument() and result = this.getArgument(this.getFirstArgument() + index) } - - /** Gets a supplied argument that is not used in the format string `src`. */ - deprecated int getAnUnusedArgument(ValidFormatString src) { - result = this.getASuppliedArgument() and - FormatFlow::hasFlowPath(src, _, this, _) and - not result = src.getAnInsert() - } } diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/ServiceStack.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/ServiceStack.qll index 4f914899a98..bf4a72b4174 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/ServiceStack.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/ServiceStack.qll @@ -24,13 +24,6 @@ private class ServiceClass extends Class { } } -/** Top-level Request DTO types */ -private class RequestDTO extends Class { - RequestDTO() { - this.getABaseType*().getABaseInterface().hasQualifiedName("ServiceStack", "IReturn") - } -} - /** Flow sources for the ServiceStack framework */ module Sources { private import semmle.code.csharp.security.dataflow.flowsources.Remote diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Linq.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Linq.qll index c2453755d69..349fd65750f 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Linq.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Linq.qll @@ -2,14 +2,14 @@ * Provides classes related to the namespace `System.Linq`. */ -private import csharp as csharp +private import csharp as CSharp private import semmle.code.csharp.frameworks.System as System private import semmle.code.csharp.dataflow.ExternalFlow as ExternalFlow /** Definitions relating to the `System.Linq` namespace. */ module SystemLinq { /** The `System.Linq` namespace. */ - class Namespace extends csharp::Namespace { + class Namespace extends CSharp::Namespace { Namespace() { this.getParentNamespace() instanceof System::SystemNamespace and this.hasUndecoratedName("Linq") @@ -17,7 +17,7 @@ module SystemLinq { } /** A class in the `System.Linq` namespace. */ - class Class extends csharp::Class { + class Class extends CSharp::Class { Class() { this.getNamespace() instanceof Namespace } } @@ -26,10 +26,10 @@ module SystemLinq { SystemLinqEnumerableClass() { this.hasName("Enumerable") } /** Gets a `Count()` method. */ - csharp::ExtensionMethod getACountMethod() { result = this.getAMethod("Count<>") } + CSharp::ExtensionMethod getACountMethod() { result = this.getAMethod("Count<>") } /** Gets an `Any()` method. */ - csharp::ExtensionMethod getAnAnyMethod() { result = this.getAMethod("Any<>") } + CSharp::ExtensionMethod getAnAnyMethod() { result = this.getAMethod("Any<>") } } } diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/data/Common.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/data/Common.qll index e35bbc341ac..0901b400362 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/data/Common.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/data/Common.qll @@ -2,14 +2,14 @@ * Provides classes related to the namespace `System.Data.Common`. */ -private import csharp as csharp +private import csharp as CSharp private import semmle.code.csharp.frameworks.system.Data as Data private import semmle.code.csharp.dataflow.ExternalFlow as ExternalFlow /** Definitions relating to the `System.Data.Common` namespace. */ module SystemDataCommon { /** The `System.Data.Common` namespace. */ - class Namespace extends csharp::Namespace { + class Namespace extends CSharp::Namespace { Namespace() { this.getParentNamespace() instanceof Data::SystemDataNamespace and this.hasName("Common") @@ -17,7 +17,7 @@ module SystemDataCommon { } /** A class in the `System.Data.Common` namespace. */ - class Class extends csharp::Class { + class Class extends CSharp::Class { Class() { this.getNamespace() instanceof Namespace } } diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/data/Entity.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/data/Entity.qll index 5109db04af6..a5067d860ed 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/data/Entity.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/data/Entity.qll @@ -2,13 +2,13 @@ * Provides classes related to the Entity Framework namespace `System.Data.Entity`. */ -private import csharp as csharp +private import csharp as CSharp private import semmle.code.csharp.frameworks.system.Data as Data /** Definitions relating to the `System.Data.Entity` namespace. */ module SystemDataEntity { /** The `System.Data.Entity` namespace. */ - class Namespace extends csharp::Namespace { + class Namespace extends CSharp::Namespace { Namespace() { this.getParentNamespace() instanceof Data::SystemDataNamespace and this.hasName("Entity") @@ -16,7 +16,7 @@ module SystemDataEntity { } /** A class in the `System.Data.Entity` namespace. */ - class Class extends csharp::Class { + class Class extends CSharp::Class { Class() { this.getNamespace() instanceof Namespace } } @@ -25,28 +25,28 @@ module SystemDataEntity { Database() { this.hasName("Database") } /** Gets the `ExecuteSqlCommand` method. */ - csharp::Method getExecuteSqlCommandMethod() { result = this.getAMethod("ExecuteSqlCommand") } + CSharp::Method getExecuteSqlCommandMethod() { result = this.getAMethod("ExecuteSqlCommand") } /** Gets the `ExecuteSqlCommandAsync` method. */ - csharp::Method getExecuteSqlCommandAsyncMethod() { + CSharp::Method getExecuteSqlCommandAsyncMethod() { result = this.getAMethod("ExecuteSqlCommandAsync") } /** Gets the `SqlQuery` method. */ - csharp::Method getSqlQueryMethod() { result = this.getAMethod("SqlQuery") } + CSharp::Method getSqlQueryMethod() { result = this.getAMethod("SqlQuery") } } /** The `System.Data.Entity.DbSet` class. */ class DbSet extends Class { DbSet() { - this.getUnboundDeclaration().(csharp::UnboundGenericClass).getUndecoratedName() = "DbSet" + this.getUnboundDeclaration().(CSharp::UnboundGenericClass).getUndecoratedName() = "DbSet" } /** Gets the `SqlQuery` method. */ - csharp::Method getSqlQueryMethod() { result = this.getAMethod("SqlQuery") } + CSharp::Method getSqlQueryMethod() { result = this.getAMethod("SqlQuery") } /** Gets the `DbSet` type, if any. */ - csharp::Type getDbSetType() { result = this.(csharp::ConstructedType).getTypeArgument(0) } + CSharp::Type getDbSetType() { result = this.(CSharp::ConstructedType).getTypeArgument(0) } } /** The `System.Data.Entity.DbContext` class. */ @@ -55,23 +55,23 @@ module SystemDataEntity { } /** A user provided sub type of `DbContext`. */ - class CustomDbContext extends csharp::Class { + class CustomDbContext extends CSharp::Class { CustomDbContext() { this.fromSource() and this.getABaseType+() instanceof DbContext } /** Gets a property that has the type `DbSet`. */ - csharp::Property getADbSetProperty() { + CSharp::Property getADbSetProperty() { result = this.getAProperty() and result.getType() instanceof DbSet } } /** An Entity Framework entity, as referenced from a `CustomDbContext`. */ - class Entity extends csharp::Class { + class Entity extends CSharp::Class { Entity() { - exists(CustomDbContext dbContext, csharp::Property p | + exists(CustomDbContext dbContext, CSharp::Property p | p = dbContext.getADbSetProperty() and this = p.getType().(DbSet).getDbSetType() ) @@ -82,7 +82,7 @@ module SystemDataEntity { /** Definitions relating to the `System.Data.Entity.Infrastructure` namespace. */ module SystemDataEntityInfrastructure { /** The `System.Data.Entity.Infrastructure` namespace. */ - class Namespace extends csharp::Namespace { + class Namespace extends CSharp::Namespace { Namespace() { this.getParentNamespace() instanceof SystemDataEntity::Namespace and this.hasName("Infrastructure") @@ -90,7 +90,7 @@ module SystemDataEntityInfrastructure { } /** A class in the `System.Data.Entity.Infrastructure` namespace. */ - class Class extends csharp::Class { + class Class extends CSharp::Class { Class() { this.getNamespace() instanceof Namespace } } @@ -99,7 +99,7 @@ module SystemDataEntityInfrastructure { DbRawSqlQuery() { this.getABaseType*() .getUnboundDeclaration() - .(csharp::UnboundGenericClass) + .(CSharp::UnboundGenericClass) .getUndecoratedName() = "DbRawSqlQuery" } } diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/linq/Expressions.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/linq/Expressions.qll index c4126834d20..41c057ea51d 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/linq/Expressions.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/linq/Expressions.qll @@ -2,13 +2,13 @@ * Provides classes related to the namespace `System.Linq.Expressions`. */ -private import csharp as csharp +private import csharp as CSharp private import semmle.code.csharp.frameworks.system.Linq /** Definitions relating to the `System.Linq.Expressions` namespace. */ module SystemLinqExpressions { /** The `System.Linq.Expressions` namespace. */ - class Namespace extends csharp::Namespace { + class Namespace extends CSharp::Namespace { Namespace() { this.getParentNamespace() instanceof SystemLinq::Namespace and this.hasName("Expressions") @@ -16,12 +16,12 @@ module SystemLinqExpressions { } /** A class in the `System.Linq.Expressions` namespace. */ - class Class extends csharp::Class { + class Class extends CSharp::Class { Class() { this.getNamespace() instanceof Namespace } } /** The `Expression` class. */ - class ExpressionDelegate extends Class, csharp::UnboundGenericClass { + class ExpressionDelegate extends Class, CSharp::UnboundGenericClass { ExpressionDelegate() { this.hasName("Expression<>") } } @@ -30,20 +30,20 @@ module SystemLinqExpressions { * or a type of the form `Expression`, where `T` is an actual * `delegate` type. */ - class DelegateExtType extends csharp::Type { - csharp::DelegateType dt; + class DelegateExtType extends CSharp::Type { + CSharp::DelegateType dt; DelegateExtType() { this = dt or this = - any(csharp::ConstructedClass cc | + any(CSharp::ConstructedClass cc | cc.getUnboundGeneric() instanceof ExpressionDelegate and dt = cc.getTypeArgument(0) ) } /** Gets the underlying `delegate` type. */ - csharp::DelegateType getDelegateType() { result = dt } + CSharp::DelegateType getDelegateType() { result = dt } } } diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/xml/XPath.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/xml/XPath.qll index 9374d7c282f..7e703f44608 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/xml/XPath.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/xml/XPath.qll @@ -1,20 +1,20 @@ /** Provides classes related to the namespace `System.Xml.XPath`. */ -import csharp as csharp -private import semmle.code.csharp.frameworks.system.Xml as xml +private import csharp as CSharp +private import semmle.code.csharp.frameworks.system.Xml as Xml /** Definitions relating to the `System.Xml.XPath` namespace. */ module SystemXmlXPath { /** The `System.Xml.XPath` namespace. */ - class Namespace extends csharp::Namespace { + class Namespace extends CSharp::Namespace { Namespace() { - this.getParentNamespace() instanceof xml::SystemXmlNamespace and + this.getParentNamespace() instanceof Xml::SystemXmlNamespace and this.hasName("XPath") } } /** A class in the `System.Xml.XPath` namespace. */ - class Class extends csharp::Class { + class Class extends CSharp::Class { Class() { this.getNamespace() instanceof Namespace } } @@ -28,17 +28,17 @@ module SystemXmlXPath { XPathNavigator() { this.hasName("XPathNavigator") } /** Gets a method that selects nodes. */ - csharp::Method getASelectMethod() { + CSharp::Method getASelectMethod() { result = this.getAMethod() and result.getName().matches("Select%") } /** Gets the `Compile` method. */ - csharp::Method getCompileMethod() { result = this.getAMethod("Compile") } + CSharp::Method getCompileMethod() { result = this.getAMethod("Compile") } /** Gets an `Evaluate` method. */ - csharp::Method getAnEvaluateMethod() { result = this.getAMethod("Evaluate") } + CSharp::Method getAnEvaluateMethod() { result = this.getAMethod("Evaluate") } /** Gets a `Matches` method. */ - csharp::Method getAMatchesMethod() { result = this.getAMethod("Matches") } + CSharp::Method getAMatchesMethod() { result = this.getAMethod("Matches") } } } diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExternalAPIsQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExternalAPIsQuery.qll index 34cff98208d..6b6b49e3a60 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExternalAPIsQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExternalAPIsQuery.qll @@ -12,15 +12,18 @@ private import semmle.code.csharp.dataflow.FlowSummary /** * A callable that is considered a "safe" external API from a security perspective. */ -abstract class SafeExternalAPICallable extends Callable { } +abstract class SafeExternalApiCallable extends Callable { } -private class SummarizedCallableSafe extends SafeExternalAPICallable { +/** DEPRECATED: Alias for SafeExternalApiCallable */ +deprecated class SafeExternalAPICallable = SafeExternalApiCallable; + +private class SummarizedCallableSafe extends SafeExternalApiCallable { SummarizedCallableSafe() { this instanceof SummarizedCallable } } /** The default set of "safe" external APIs. */ -private class DefaultSafeExternalAPICallable extends SafeExternalAPICallable { - DefaultSafeExternalAPICallable() { +private class DefaultSafeExternalApiCallable extends SafeExternalApiCallable { + DefaultSafeExternalApiCallable() { this instanceof EqualsMethod or this instanceof IEquatableEqualsMethod or this = any(SystemObjectClass s).getEqualsMethod() or @@ -36,11 +39,11 @@ private class DefaultSafeExternalAPICallable extends SafeExternalAPICallable { } /** A node representing data being passed to an external API. */ -class ExternalAPIDataNode extends DataFlow::Node { +class ExternalApiDataNode extends DataFlow::Node { Call call; int i; - ExternalAPIDataNode() { + ExternalApiDataNode() { ( // Argument to call this.asExpr() = call.getArgument(i) @@ -59,7 +62,7 @@ class ExternalAPIDataNode extends DataFlow::Node { m.fromSource() ) and // Not a call to a known safe external API - not call.getTarget().getUnboundDeclaration() instanceof SafeExternalAPICallable + not call.getTarget().getUnboundDeclaration() instanceof SafeExternalApiCallable } /** Gets the called API callable. */ @@ -72,38 +75,47 @@ class ExternalAPIDataNode extends DataFlow::Node { string getCallableDescription() { result = this.getCallable().getQualifiedName() } } -/** A configuration for tracking flow from `RemoteFlowSource`s to `ExternalAPIDataNode`s. */ -class UntrustedDataToExternalAPIConfig extends TaintTracking::Configuration { - UntrustedDataToExternalAPIConfig() { this = "UntrustedDataToExternalAPIConfig" } +/** DEPRECATED: Alias for ExternalApiDataNode */ +deprecated class ExternalAPIDataNode = ExternalApiDataNode; + +/** A configuration for tracking flow from `RemoteFlowSource`s to `ExternalApiDataNode`s. */ +class UntrustedDataToExternalApiConfig extends TaintTracking::Configuration { + UntrustedDataToExternalApiConfig() { this = "UntrustedDataToExternalAPIConfig" } override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } - override predicate isSink(DataFlow::Node sink) { sink instanceof ExternalAPIDataNode } + override predicate isSink(DataFlow::Node sink) { sink instanceof ExternalApiDataNode } } -/** A node representing untrusted data being passed to an external API. */ -class UntrustedExternalAPIDataNode extends ExternalAPIDataNode { - private UntrustedDataToExternalAPIConfig c; +/** DEPRECATED: Alias for UntrustedDataToExternalApiConfig */ +deprecated class UntrustedDataToExternalAPIConfig = UntrustedDataToExternalApiConfig; - UntrustedExternalAPIDataNode() { c.hasFlow(_, this) } +/** A node representing untrusted data being passed to an external API. */ +class UntrustedExternalApiDataNode extends ExternalApiDataNode { + private UntrustedDataToExternalApiConfig c; + + UntrustedExternalApiDataNode() { c.hasFlow(_, this) } /** Gets a source of untrusted data which is passed to this external API data node. */ DataFlow::Node getAnUntrustedSource() { c.hasFlow(result, this) } } -private newtype TExternalAPI = - TExternalAPIParameter(Callable m, int index) { - exists(UntrustedExternalAPIDataNode n | +/** DEPRECATED: Alias for UntrustedExternalApiDataNode */ +deprecated class UntrustedExternalAPIDataNode = UntrustedExternalApiDataNode; + +private newtype TExternalApi = + TExternalApiParameter(Callable m, int index) { + exists(UntrustedExternalApiDataNode n | m = n.getCallable().getUnboundDeclaration() and index = n.getIndex() ) } /** An external API which is used with untrusted data. */ -class ExternalAPIUsedWithUntrustedData extends TExternalAPI { +class ExternalApiUsedWithUntrustedData extends TExternalApi { /** Gets a possibly untrusted use of this external API. */ - UntrustedExternalAPIDataNode getUntrustedDataNode() { - this = TExternalAPIParameter(result.getCallable().getUnboundDeclaration(), result.getIndex()) + UntrustedExternalApiDataNode getUntrustedDataNode() { + this = TExternalApiParameter(result.getCallable().getUnboundDeclaration(), result.getIndex()) } /** Gets the number of untrusted sources used with this external API. */ @@ -116,10 +128,13 @@ class ExternalAPIUsedWithUntrustedData extends TExternalAPI { exists(Callable m, int index, string indexString | if index = -1 then indexString = "qualifier" else indexString = "param " + index | - this = TExternalAPIParameter(m, index) and + this = TExternalApiParameter(m, index) and result = m.getDeclaringType().getQualifiedName() + "." + m.toStringWithTypes() + " [" + indexString + "]" ) } } + +/** DEPRECATED: Alias for ExternalApiUsedWithUntrustedData */ +deprecated class ExternalAPIUsedWithUntrustedData = ExternalApiUsedWithUntrustedData; diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/LDAPInjectionQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/LDAPInjectionQuery.qll index 5aa27202f4f..6f985463763 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/LDAPInjectionQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/LDAPInjectionQuery.qll @@ -117,12 +117,15 @@ class SearchRequestFilterSink extends Sink { * * This will match the encoding methods provided by the AntiXSS library. */ -class LDAPEncodeSanitizer extends Sanitizer { - LDAPEncodeSanitizer() { +class LdapEncodeSanitizer extends Sanitizer { + LdapEncodeSanitizer() { this.getExpr().(MethodCall).getTarget().getName().regexpMatch("(?i)LDAP.*Encode.*") } } +/** DEPRECATED: Alias for LdapEncodeSanitizer */ +deprecated class LDAPEncodeSanitizer = LdapEncodeSanitizer; + private class SimpleTypeSanitizer extends Sanitizer, SimpleTypeSanitizedExpr { } private class GuidSanitizer extends Sanitizer, GuidSanitizedExpr { } diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/XMLEntityInjectionQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/XMLEntityInjectionQuery.qll index cf27d2db49b..d49ecd7c900 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/XMLEntityInjectionQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/XMLEntityInjectionQuery.qll @@ -28,10 +28,10 @@ abstract class Sink extends DataFlow::ExprNode { abstract string getReason(); } -private class InsecureXMLSink extends Sink { +private class InsecureXmlSink extends Sink { private string reason; - InsecureXMLSink() { + InsecureXmlSink() { exists(InsecureXML::InsecureXmlProcessing r | r.isUnsafe(reason) | this.getExpr() = r.getAnArgument() ) diff --git a/csharp/ql/lib/semmle/code/dotnet/Declaration.qll b/csharp/ql/lib/semmle/code/dotnet/Declaration.qll index 60e434f9ae6..046cb99944e 100644 --- a/csharp/ql/lib/semmle/code/dotnet/Declaration.qll +++ b/csharp/ql/lib/semmle/code/dotnet/Declaration.qll @@ -21,13 +21,6 @@ class Declaration extends NamedElement, @dotnet_declaration { /** Gets the type containing this declaration, if any. */ Type getDeclaringType() { none() } - /** - * DEPRECATED: Use `getUnboundDeclaration()` instaed. - * - * Gets the unbound version of this declaration. - */ - deprecated final Declaration getSourceDeclaration() { result = this.getUnboundDeclaration() } - /** * Gets the unbound version of this declaration, that is, the declaration where * all type arguments have been removed. For example, in diff --git a/csharp/ql/src/CHANGELOG.md b/csharp/ql/src/CHANGELOG.md index ce70794f289..dc356239a96 100644 --- a/csharp/ql/src/CHANGELOG.md +++ b/csharp/ql/src/CHANGELOG.md @@ -1,3 +1,13 @@ +## 0.0.11 + +### Minor Analysis Improvements + +* Casts to `dynamic` are excluded from the useless upcasts check (`cs/useless-upcast`). +* The C# extractor now accepts an extractor option `buildless`, which is used to decide what type of extraction that should be performed. If `true` then buildless (standalone) extraction will be performed. Otherwise tracing extraction will be performed (default). +The option is added via `codeql database create --language=csharp -Obuildless=true ...`. +* The C# extractor now accepts an extractor option `trap.compression`, which is used to decide the compression format for TRAP files. The legal values are `brotli` (default), `gzip` or `none`. +The option is added via `codeql database create --language=csharp -Otrap.compression=value ...`. + ## 0.0.10 ### Query Metadata Changes diff --git a/csharp/ql/src/Documentation/Documentation.qll b/csharp/ql/src/Documentation/Documentation.qll index 19fd1d5dd8a..c15f53027c3 100644 --- a/csharp/ql/src/Documentation/Documentation.qll +++ b/csharp/ql/src/Documentation/Documentation.qll @@ -26,7 +26,7 @@ class SourceMethodOrConstructor extends SourceDeclaration, Callable { } /** Gets an XML comment bound to this declaration. */ -XmlComment getADeclarationXmlComment(Declaration d) { +XmlCommentLine getADeclarationXmlComment(Declaration d) { result = getADeclarationCommentBlock(d).getAChild() } @@ -58,7 +58,7 @@ predicate isDocumentationNeeded(Modifiable decl) { } /** An XML comment containing a `` tag. */ -class ReturnsXmlComment extends XmlComment { +class ReturnsXmlComment extends XmlCommentLine { ReturnsXmlComment() { this.getOpenTag(_) = "returns" } /** Holds if the element in this comment has a body at offset `offset`. */ @@ -72,7 +72,7 @@ class ReturnsXmlComment extends XmlComment { } /** An XML comment containing an `` tag. */ -class ExceptionXmlComment extends XmlComment { +class ExceptionXmlComment extends XmlCommentLine { ExceptionXmlComment() { this.getOpenTag(_) = "exception" } /** Gets a `cref` attribute at offset `offset`, if any. */ @@ -83,7 +83,7 @@ class ExceptionXmlComment extends XmlComment { } /** An XML comment containing a `` tag. */ -class ParamXmlComment extends XmlComment { +class ParamXmlComment extends XmlCommentLine { ParamXmlComment() { this.getOpenTag(_) = "param" } /** Gets the name of this parameter at offset `offset`. */ @@ -94,7 +94,7 @@ class ParamXmlComment extends XmlComment { } /** An XML comment containing a `` tag. */ -class TypeparamXmlComment extends XmlComment { +class TypeparamXmlComment extends XmlCommentLine { TypeparamXmlComment() { this.getOpenTag(_) = "typeparam" } /** Gets the `name` attribute of this element at offset `offset`. */ @@ -105,7 +105,7 @@ class TypeparamXmlComment extends XmlComment { } /** An XML comment containing a `` tag. */ -class SummaryXmlComment extends XmlComment { +class SummaryXmlComment extends XmlCommentLine { SummaryXmlComment() { this.getOpenTag(_) = "summary" } /** Holds if the element in this comment has a body at offset `offset`. */ @@ -119,6 +119,6 @@ class SummaryXmlComment extends XmlComment { } /** An XML comment containing an `` tag. */ -class InheritDocXmlComment extends XmlComment { +class InheritDocXmlComment extends XmlCommentLine { InheritDocXmlComment() { this.getOpenTag(_) = "inheritdoc" } } diff --git a/csharp/ql/src/Likely Bugs/EqualityCheckOnFloats.ql b/csharp/ql/src/Likely Bugs/EqualityCheckOnFloats.ql index 5cbbbb83751..1884cd5cc5f 100644 --- a/csharp/ql/src/Likely Bugs/EqualityCheckOnFloats.ql +++ b/csharp/ql/src/Likely Bugs/EqualityCheckOnFloats.ql @@ -11,13 +11,6 @@ import csharp -class ZeroFloatLiteral extends FloatLiteral { - ZeroFloatLiteral() { - this.getValue() = "0" or - this.getValue() = "0.0" - } -} - from EqualityOperation e where e.getAnOperand().getType() instanceof FloatingPointType and diff --git a/csharp/ql/src/Security Features/CWE-011/ASPNetDebug.ql b/csharp/ql/src/Security Features/CWE-011/ASPNetDebug.ql index 3bccd9b0331..8477401fe17 100644 --- a/csharp/ql/src/Security Features/CWE-011/ASPNetDebug.ql +++ b/csharp/ql/src/Security Features/CWE-011/ASPNetDebug.ql @@ -17,7 +17,7 @@ import csharp import semmle.code.asp.WebConfig -from SystemWebXMLElement web, XMLAttribute debugAttribute +from SystemWebXmlElement web, XMLAttribute debugAttribute where debugAttribute = web.getAChild("compilation").getAttribute("debug") and not debugAttribute.getValue().toLowerCase() = "false" diff --git a/csharp/ql/src/Security Features/CWE-016/ASPNetMaxRequestLength.ql b/csharp/ql/src/Security Features/CWE-016/ASPNetMaxRequestLength.ql index 5a527c96084..d6b4da2c258 100644 --- a/csharp/ql/src/Security Features/CWE-016/ASPNetMaxRequestLength.ql +++ b/csharp/ql/src/Security Features/CWE-016/ASPNetMaxRequestLength.ql @@ -14,7 +14,7 @@ import csharp import semmle.code.asp.WebConfig -from SystemWebXMLElement web, XMLAttribute maxReqLength +from SystemWebXmlElement web, XMLAttribute maxReqLength where maxReqLength = web.getAChild(any(string s | s.toLowerCase() = "httpruntime")) diff --git a/csharp/ql/src/Security Features/CWE-016/ASPNetPagesValidateRequest.ql b/csharp/ql/src/Security Features/CWE-016/ASPNetPagesValidateRequest.ql index f093a888446..3a8208c270f 100644 --- a/csharp/ql/src/Security Features/CWE-016/ASPNetPagesValidateRequest.ql +++ b/csharp/ql/src/Security Features/CWE-016/ASPNetPagesValidateRequest.ql @@ -13,7 +13,7 @@ import csharp import semmle.code.asp.WebConfig -from SystemWebXMLElement web, XMLAttribute requestvalidateAttribute +from SystemWebXmlElement web, XMLAttribute requestvalidateAttribute where requestvalidateAttribute = web.getAChild("pages").getAttribute("validateRequest") and requestvalidateAttribute.getValue().toLowerCase() = "false" diff --git a/csharp/ql/src/Security Features/CWE-020/ExternalAPIsUsedWithUntrustedData.ql b/csharp/ql/src/Security Features/CWE-020/ExternalAPIsUsedWithUntrustedData.ql index 8b6a657ecd4..b07b1093ec8 100644 --- a/csharp/ql/src/Security Features/CWE-020/ExternalAPIsUsedWithUntrustedData.ql +++ b/csharp/ql/src/Security Features/CWE-020/ExternalAPIsUsedWithUntrustedData.ql @@ -11,7 +11,7 @@ import csharp import semmle.code.csharp.security.dataflow.ExternalAPIsQuery -from ExternalAPIUsedWithUntrustedData externalAPI -select externalAPI, count(externalAPI.getUntrustedDataNode()) as numberOfUses, - externalAPI.getNumberOfUntrustedSources() as numberOfUntrustedSources order by +from ExternalApiUsedWithUntrustedData externalApi +select externalApi, count(externalApi.getUntrustedDataNode()) as numberOfUses, + externalApi.getNumberOfUntrustedSources() as numberOfUntrustedSources order by numberOfUntrustedSources desc diff --git a/csharp/ql/src/Security Features/CWE-020/UntrustedDataToExternalAPI.ql b/csharp/ql/src/Security Features/CWE-020/UntrustedDataToExternalAPI.ql index 3db73db09d4..aaf18f7f312 100644 --- a/csharp/ql/src/Security Features/CWE-020/UntrustedDataToExternalAPI.ql +++ b/csharp/ql/src/Security Features/CWE-020/UntrustedDataToExternalAPI.ql @@ -14,8 +14,8 @@ import semmle.code.csharp.dataflow.TaintTracking import semmle.code.csharp.security.dataflow.ExternalAPIsQuery import DataFlow::PathGraph -from UntrustedDataToExternalAPIConfig config, DataFlow::PathNode source, DataFlow::PathNode sink +from UntrustedDataToExternalApiConfig config, DataFlow::PathNode source, DataFlow::PathNode sink where config.hasFlowPath(source, sink) select sink, source, sink, - "Call to " + sink.getNode().(ExternalAPIDataNode).getCallableDescription() + + "Call to " + sink.getNode().(ExternalApiDataNode).getCallableDescription() + " with untrusted data from $@.", source, source.toString() diff --git a/csharp/ql/src/Security Features/CWE-248/MissingASPNETGlobalErrorHandler.ql b/csharp/ql/src/Security Features/CWE-248/MissingASPNETGlobalErrorHandler.ql index 416608b9115..1e7a9a4ddb1 100644 --- a/csharp/ql/src/Security Features/CWE-248/MissingASPNETGlobalErrorHandler.ql +++ b/csharp/ql/src/Security Features/CWE-248/MissingASPNETGlobalErrorHandler.ql @@ -24,7 +24,7 @@ class Application_Error extends Method { } } -from CustomErrorsXMLElement customError +from CustomErrorsXmlElement customError where // `` must be set to "off" to be dangerous customError.getAttributeValue("mode").toLowerCase() = "off" and diff --git a/csharp/ql/src/Security Features/CWE-451/MissingXFrameOptions.ql b/csharp/ql/src/Security Features/CWE-451/MissingXFrameOptions.ql index 67f3ae1d7b8..9e51b663038 100644 --- a/csharp/ql/src/Security Features/CWE-451/MissingXFrameOptions.ql +++ b/csharp/ql/src/Security Features/CWE-451/MissingXFrameOptions.ql @@ -19,7 +19,7 @@ import semmle.code.csharp.frameworks.system.Web /** * Holds if the `Web.config` file `webConfig` adds an `X-Frame-Options` header. */ -predicate hasWebConfigXFrameOptions(WebConfigXML webConfig) { +predicate hasWebConfigXFrameOptions(WebConfigXml webConfig) { // Looking for an entry in `webConfig` that looks like this: // ```xml // @@ -52,7 +52,7 @@ predicate hasCodeXFrameOptions() { ) } -from WebConfigXML webConfig +from WebConfigXml webConfig where not hasWebConfigXFrameOptions(webConfig) and not hasCodeXFrameOptions() diff --git a/csharp/ql/src/Security Features/CWE-548/ASPNetDirectoryListing.ql b/csharp/ql/src/Security Features/CWE-548/ASPNetDirectoryListing.ql index 9416fa32f0a..2337ecfc4cf 100644 --- a/csharp/ql/src/Security Features/CWE-548/ASPNetDirectoryListing.ql +++ b/csharp/ql/src/Security Features/CWE-548/ASPNetDirectoryListing.ql @@ -13,7 +13,7 @@ import csharp import semmle.code.asp.WebConfig -from SystemWebServerXMLElement ws, XMLAttribute a +from SystemWebServerXmlElement ws, XMLAttribute a where ws.getAChild("directoryBrowse").getAttribute("enabled") = a and a.getValue() = "true" diff --git a/csharp/ql/src/Security Features/HeaderCheckingDisabled.ql b/csharp/ql/src/Security Features/HeaderCheckingDisabled.ql index 631b408a5a3..5d0958d06f9 100644 --- a/csharp/ql/src/Security Features/HeaderCheckingDisabled.ql +++ b/csharp/ql/src/Security Features/HeaderCheckingDisabled.ql @@ -27,7 +27,7 @@ where ) or // header checking is disabled in a configuration file - exists(HttpRuntimeXMLElement e, XMLAttribute a | + exists(HttpRuntimeXmlElement e, XMLAttribute a | a = e.getAttribute("enableHeaderChecking") and a.getValue().toLowerCase() = "false" and a = l diff --git a/csharp/ql/src/change-notes/2022-02-23-extractor-option-compression.md b/csharp/ql/src/change-notes/2022-02-23-extractor-option-compression.md deleted file mode 100644 index 533426ec2e7..00000000000 --- a/csharp/ql/src/change-notes/2022-02-23-extractor-option-compression.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -category: minorAnalysis ---- -* The C# extractor now accepts an extractor option `trap.compression`, which is used to decide the compression format for TRAP files. The legal values are `brotli` (default), `gzip` or `none`. -The option is added via `codeql database create --language=csharp -Otrap.compression=value ...`. diff --git a/csharp/ql/src/change-notes/2022-02-24-buildless-extractor-option.md b/csharp/ql/src/change-notes/2022-02-24-buildless-extractor-option.md deleted file mode 100644 index 84dc3281a20..00000000000 --- a/csharp/ql/src/change-notes/2022-02-24-buildless-extractor-option.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -category: minorAnalysis ---- -* The C# extractor now accepts an extractor option `buildless`, which is used to decide what type of extraction that should be performed. If `true` then buildless (standalone) extraction will be performed. Otherwise tracing extraction will be performed (default). -The option is added via `codeql database create --language=csharp -Obuildless=true ...`. \ No newline at end of file diff --git a/csharp/ql/src/change-notes/2022-02-28-useless-upcast.md b/csharp/ql/src/change-notes/2022-02-28-useless-upcast.md deleted file mode 100644 index b3d2462f803..00000000000 --- a/csharp/ql/src/change-notes/2022-02-28-useless-upcast.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Casts to `dynamic` are excluded from the useless upcasts check (`cs/useless-upcast`). \ No newline at end of file diff --git a/csharp/ql/src/change-notes/released/0.0.11.md b/csharp/ql/src/change-notes/released/0.0.11.md new file mode 100644 index 00000000000..68db1093830 --- /dev/null +++ b/csharp/ql/src/change-notes/released/0.0.11.md @@ -0,0 +1,9 @@ +## 0.0.11 + +### Minor Analysis Improvements + +* Casts to `dynamic` are excluded from the useless upcasts check (`cs/useless-upcast`). +* The C# extractor now accepts an extractor option `buildless`, which is used to decide what type of extraction that should be performed. If `true` then buildless (standalone) extraction will be performed. Otherwise tracing extraction will be performed (default). +The option is added via `codeql database create --language=csharp -Obuildless=true ...`. +* The C# extractor now accepts an extractor option `trap.compression`, which is used to decide the compression format for TRAP files. The legal values are `brotli` (default), `gzip` or `none`. +The option is added via `codeql database create --language=csharp -Otrap.compression=value ...`. diff --git a/csharp/ql/src/codeql-pack.release.yml b/csharp/ql/src/codeql-pack.release.yml index b740014e5ae..e679dc42092 100644 --- a/csharp/ql/src/codeql-pack.release.yml +++ b/csharp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.10 +lastReleaseVersion: 0.0.11 diff --git a/csharp/ql/src/experimental/ir/implementation/internal/TInstruction.qll b/csharp/ql/src/experimental/ir/implementation/internal/TInstruction.qll index 4b3f19cbdde..5a7099d9fa2 100644 --- a/csharp/ql/src/experimental/ir/implementation/internal/TInstruction.qll +++ b/csharp/ql/src/experimental/ir/implementation/internal/TInstruction.qll @@ -19,24 +19,24 @@ newtype TInstruction = ) { IRConstruction::Raw::hasInstruction(tag1, tag2) } or - TUnaliasedSSAPhiInstruction( - TRawInstruction blockStartInstr, UnaliasedSSA::SSA::MemoryLocation memoryLocation + TUnaliasedSsaPhiInstruction( + TRawInstruction blockStartInstr, UnaliasedSsa::SSA::MemoryLocation memoryLocation ) { - UnaliasedSSA::SSA::hasPhiInstruction(blockStartInstr, memoryLocation) + UnaliasedSsa::SSA::hasPhiInstruction(blockStartInstr, memoryLocation) } or - TUnaliasedSSAChiInstruction(TRawInstruction primaryInstruction) { none() } or - TUnaliasedSSAUnreachedInstruction(IRFunctionBase irFunc) { - UnaliasedSSA::SSA::hasUnreachedInstruction(irFunc) + TUnaliasedSsaChiInstruction(TRawInstruction primaryInstruction) { none() } or + TUnaliasedSsaUnreachedInstruction(IRFunctionBase irFunc) { + UnaliasedSsa::SSA::hasUnreachedInstruction(irFunc) } or - TAliasedSSAPhiInstruction( + TAliasedSsaPhiInstruction( TRawInstruction blockStartInstr, AliasedSSA::SSA::MemoryLocation memoryLocation ) { AliasedSSA::SSA::hasPhiInstruction(blockStartInstr, memoryLocation) } or - TAliasedSSAChiInstruction(TRawInstruction primaryInstruction) { + TAliasedSsaChiInstruction(TRawInstruction primaryInstruction) { AliasedSSA::SSA::hasChiInstruction(primaryInstruction) } or - TAliasedSSAUnreachedInstruction(IRFunctionBase irFunc) { + TAliasedSsaUnreachedInstruction(IRFunctionBase irFunc) { AliasedSSA::SSA::hasUnreachedInstruction(irFunc) } @@ -46,58 +46,64 @@ newtype TInstruction = * These wrappers are not parameterized because it is not possible to invoke an IPA constructor via * a class alias. */ -module UnaliasedSSAInstructions { - class TPhiInstruction = TUnaliasedSSAPhiInstruction; +module UnaliasedSsaInstructions { + class TPhiInstruction = TUnaliasedSsaPhiInstruction; TPhiInstruction phiInstruction( - TRawInstruction blockStartInstr, UnaliasedSSA::SSA::MemoryLocation memoryLocation + TRawInstruction blockStartInstr, UnaliasedSsa::SSA::MemoryLocation memoryLocation ) { - result = TUnaliasedSSAPhiInstruction(blockStartInstr, memoryLocation) + result = TUnaliasedSsaPhiInstruction(blockStartInstr, memoryLocation) } TRawInstruction reusedPhiInstruction(TRawInstruction blockStartInstr) { none() } - class TChiInstruction = TUnaliasedSSAChiInstruction; + class TChiInstruction = TUnaliasedSsaChiInstruction; TChiInstruction chiInstruction(TRawInstruction primaryInstruction) { - result = TUnaliasedSSAChiInstruction(primaryInstruction) + result = TUnaliasedSsaChiInstruction(primaryInstruction) } - class TUnreachedInstruction = TUnaliasedSSAUnreachedInstruction; + class TUnreachedInstruction = TUnaliasedSsaUnreachedInstruction; TUnreachedInstruction unreachedInstruction(IRFunctionBase irFunc) { - result = TUnaliasedSSAUnreachedInstruction(irFunc) + result = TUnaliasedSsaUnreachedInstruction(irFunc) } } +/** DEPRECATED: Alias for UnaliasedSsaInstructions */ +deprecated module UnaliasedSSAInstructions = UnaliasedSsaInstructions; + /** * Provides wrappers for the constructors of each branch of `TInstruction` that is used by the * aliased SSA stage. * These wrappers are not parameterized because it is not possible to invoke an IPA constructor via * a class alias. */ -module AliasedSSAInstructions { - class TPhiInstruction = TAliasedSSAPhiInstruction or TUnaliasedSSAPhiInstruction; +module AliasedSsaInstructions { + class TPhiInstruction = TAliasedSsaPhiInstruction or TUnaliasedSsaPhiInstruction; TPhiInstruction phiInstruction( TRawInstruction blockStartInstr, AliasedSSA::SSA::MemoryLocation memoryLocation ) { - result = TAliasedSSAPhiInstruction(blockStartInstr, memoryLocation) + result = TAliasedSsaPhiInstruction(blockStartInstr, memoryLocation) } TPhiInstruction reusedPhiInstruction(TRawInstruction blockStartInstr) { - result = TUnaliasedSSAPhiInstruction(blockStartInstr, _) + result = TUnaliasedSsaPhiInstruction(blockStartInstr, _) } - class TChiInstruction = TAliasedSSAChiInstruction; + class TChiInstruction = TAliasedSsaChiInstruction; TChiInstruction chiInstruction(TRawInstruction primaryInstruction) { - result = TAliasedSSAChiInstruction(primaryInstruction) + result = TAliasedSsaChiInstruction(primaryInstruction) } - class TUnreachedInstruction = TAliasedSSAUnreachedInstruction; + class TUnreachedInstruction = TAliasedSsaUnreachedInstruction; TUnreachedInstruction unreachedInstruction(IRFunctionBase irFunc) { - result = TAliasedSSAUnreachedInstruction(irFunc) + result = TAliasedSsaUnreachedInstruction(irFunc) } } + +/** DEPRECATED: Alias for AliasedSsaInstructions */ +deprecated module AliasedSSAInstructions = AliasedSsaInstructions; diff --git a/csharp/ql/src/experimental/ir/implementation/internal/TInstructionInternal.qll b/csharp/ql/src/experimental/ir/implementation/internal/TInstructionInternal.qll index 978d2c41aa7..252f390bf55 100644 --- a/csharp/ql/src/experimental/ir/implementation/internal/TInstructionInternal.qll +++ b/csharp/ql/src/experimental/ir/implementation/internal/TInstructionInternal.qll @@ -1,4 +1,4 @@ import experimental.ir.internal.IRCSharpLanguage as Language import experimental.ir.implementation.raw.internal.IRConstruction as IRConstruction -import experimental.ir.implementation.unaliased_ssa.internal.SSAConstruction as UnaliasedSSA +import experimental.ir.implementation.unaliased_ssa.internal.SSAConstruction as UnaliasedSsa import AliasedSSAStub as AliasedSSA diff --git a/csharp/ql/src/experimental/ir/implementation/internal/TOperand.qll b/csharp/ql/src/experimental/ir/implementation/internal/TOperand.qll index 20fe77f8223..6327c603901 100644 --- a/csharp/ql/src/experimental/ir/implementation/internal/TOperand.qll +++ b/csharp/ql/src/experimental/ir/implementation/internal/TOperand.qll @@ -29,7 +29,7 @@ private module Internal { TNoOperand() { none() } or // Can be "removed" later when there's unreachable code // These operands can be reused across all three stages. They just get different defs. - TNonSSAMemoryOperand(Raw::Instruction useInstr, MemoryOperandTag tag) { + TNonSsaMemoryOperand(Raw::Instruction useInstr, MemoryOperandTag tag) { // Has no definition in raw but will get definitions later useInstr.getOpcode().hasOperand(tag) } or @@ -57,13 +57,21 @@ private module Shared { result = Internal::TRegisterOperand(useInstr, tag, defInstr) } - class TNonSSAMemoryOperand = Internal::TNonSSAMemoryOperand; + class TNonSsaMemoryOperand = Internal::TNonSsaMemoryOperand; + + /** DEPRECATED: Alias for TNonSsaMemoryOperand */ + deprecated class TNonSSAMemoryOperand = TNonSsaMemoryOperand; /** * Returns the non-Phi memory operand with the specified parameters. */ - TNonSSAMemoryOperand nonSSAMemoryOperand(TRawInstruction useInstr, MemoryOperandTag tag) { - result = Internal::TNonSSAMemoryOperand(useInstr, tag) + TNonSsaMemoryOperand nonSsaMemoryOperand(TRawInstruction useInstr, MemoryOperandTag tag) { + result = Internal::TNonSsaMemoryOperand(useInstr, tag) + } + + /** DEPRECATED: Alias for nonSsaMemoryOperand */ + deprecated TNonSSAMemoryOperand nonSSAMemoryOperand(TRawInstruction useInstr, MemoryOperandTag tag) { + result = nonSsaMemoryOperand(useInstr, tag) } } @@ -80,7 +88,7 @@ module RawOperands { class TChiOperand = Internal::TNoOperand; - class TNonPhiMemoryOperand = TNonSSAMemoryOperand or TChiOperand; + class TNonPhiMemoryOperand = TNonSsaMemoryOperand or TChiOperand; /** * Returns the Phi operand with the specified parameters. @@ -114,14 +122,14 @@ module RawOperands { * These wrappers are not parameterized because it is not possible to invoke an IPA constructor via * a class alias. */ -module UnaliasedSSAOperands { +module UnaliasedSsaOperands { import Shared class TPhiOperand = Internal::TUnaliasedPhiOperand; class TChiOperand = Internal::TNoOperand; - class TNonPhiMemoryOperand = TNonSSAMemoryOperand or TChiOperand; + class TNonPhiMemoryOperand = TNonSsaMemoryOperand or TChiOperand; /** * Returns the Phi operand with the specified parameters. @@ -148,3 +156,6 @@ module UnaliasedSSAOperands { */ TChiOperand chiOperand(Unaliased::Instruction useInstr, ChiOperandTag tag) { none() } } + +/** DEPRECATED: Alias for UnaliasedSsaOperands */ +deprecated module UnaliasedSSAOperands = UnaliasedSsaOperands; diff --git a/csharp/ql/src/experimental/ir/implementation/raw/IRVariable.qll b/csharp/ql/src/experimental/ir/implementation/raw/IRVariable.qll index 146fc270738..ca4708857a7 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/IRVariable.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/IRVariable.qll @@ -55,7 +55,10 @@ class IRVariable extends TIRVariable { * Gets the AST node that declared this variable, or that introduced this * variable as part of the AST-to-IR translation. */ - Language::AST getAST() { none() } + Language::AST getAst() { none() } + + /** DEPRECATED: Alias for getAst */ + deprecated Language::AST getAST() { result = getAst() } /** * Gets an identifier string for the variable. This identifier is unique @@ -66,7 +69,7 @@ class IRVariable extends TIRVariable { /** * Gets the source location of this variable. */ - final Language::Location getLocation() { result = getAST().getLocation() } + final Language::Location getLocation() { result = getAst().getLocation() } /** * Gets the IR for the function that references this variable. @@ -90,7 +93,10 @@ class IRUserVariable extends IRVariable, TIRUserVariable { final override string toString() { result = getVariable().toString() } - final override Language::AST getAST() { result = var } + final override Language::AST getAst() { result = var } + + /** DEPRECATED: Alias for getAst */ + deprecated override Language::AST getAST() { result = getAst() } final override string getUniqueId() { result = getVariable().toString() + " " + getVariable().getLocation().toString() @@ -157,7 +163,10 @@ class IRGeneratedVariable extends IRVariable { final override Language::LanguageType getLanguageType() { result = type } - final override Language::AST getAST() { result = ast } + final override Language::AST getAst() { result = ast } + + /** DEPRECATED: Alias for getAst */ + deprecated override Language::AST getAST() { result = getAst() } override string toString() { result = getBaseString() + getLocationString() } diff --git a/csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll b/csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll index 1c2cc493338..e5a908bbf9a 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll @@ -41,7 +41,7 @@ class Instruction extends Construction::TStageInstruction { } /** Gets a textual representation of this element. */ - final string toString() { result = this.getOpcode().toString() + ": " + this.getAST().toString() } + final string toString() { result = this.getOpcode().toString() + ": " + this.getAst().toString() } /** * Gets a string showing the result, opcode, and operands of the instruction, equivalent to what @@ -136,7 +136,7 @@ class Instruction extends Construction::TStageInstruction { string getResultId() { this.shouldGenerateDumpStrings() and result = - this.getResultPrefix() + this.getAST().getLocation().getStartLine() + "_" + this.getLineRank() + this.getResultPrefix() + this.getAst().getLocation().getStartLine() + "_" + this.getLineRank() } /** @@ -208,12 +208,15 @@ class Instruction extends Construction::TStageInstruction { /** * Gets the AST that caused this instruction to be generated. */ - final Language::AST getAST() { result = Construction::getInstructionAST(this) } + final Language::AST getAst() { result = Construction::getInstructionAst(this) } + + /** DEPRECATED: Alias for getAst */ + deprecated Language::AST getAST() { result = this.getAst() } /** * Gets the location of the source code for this instruction. */ - final Language::Location getLocation() { result = this.getAST().getLocation() } + final Language::Location getLocation() { result = this.getAst().getLocation() } /** * Gets the `Expr` whose result is computed by this instruction, if any. The `Expr` may be a @@ -459,7 +462,10 @@ class VariableInstruction extends Instruction { /** * Gets the AST variable that this instruction's IR variable refers to, if one exists. */ - final Language::Variable getASTVariable() { result = var.(IRUserVariable).getVariable() } + final Language::Variable getAstVariable() { result = var.(IRUserVariable).getVariable() } + + /** DEPRECATED: Alias for getAstVariable */ + deprecated Language::Variable getASTVariable() { result = this.getAstVariable() } } /** diff --git a/csharp/ql/src/experimental/ir/implementation/raw/Operand.qll b/csharp/ql/src/experimental/ir/implementation/raw/Operand.qll index 89b82657c3b..c1e997d5844 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/Operand.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/Operand.qll @@ -18,7 +18,7 @@ private import internal.OperandInternal * of `TOperand` that are used in this stage. */ private class TStageOperand = - TRegisterOperand or TNonSSAMemoryOperand or TPhiOperand or TChiOperand; + TRegisterOperand or TNonSsaMemoryOperand or TPhiOperand or TChiOperand; /** * A known location. Testing `loc instanceof KnownLocation` will account for non existing locations, as @@ -38,7 +38,7 @@ class Operand extends TStageOperand { // Ensure that the operand does not refer to instructions from earlier stages that are unreachable here exists(Instruction use, Instruction def | this = registerOperand(use, _, def)) or - exists(Instruction use | this = nonSSAMemoryOperand(use, _)) + exists(Instruction use | this = nonSsaMemoryOperand(use, _)) or exists(Instruction use, Instruction def, IRBlock predecessorBlock | this = phiOperand(use, def, predecessorBlock, _) or @@ -209,7 +209,7 @@ class Operand extends TStageOperand { class MemoryOperand extends Operand { cached MemoryOperand() { - this instanceof TNonSSAMemoryOperand or + this instanceof TNonSsaMemoryOperand or this instanceof TPhiOperand or this instanceof TChiOperand } @@ -249,7 +249,7 @@ class NonPhiOperand extends Operand { NonPhiOperand() { this = registerOperand(useInstr, tag, _) or - this = nonSSAMemoryOperand(useInstr, tag) or + this = nonSsaMemoryOperand(useInstr, tag) or this = chiOperand(useInstr, tag) } @@ -299,7 +299,7 @@ class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, TNonPhiMemoryOpe cached NonPhiMemoryOperand() { - this = nonSSAMemoryOperand(useInstr, tag) + this = nonSsaMemoryOperand(useInstr, tag) or this = chiOperand(useInstr, tag) } 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 fdb645e03f0..2dc735f49df 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 @@ -99,7 +99,7 @@ private predicate filteredNumberableInstruction(Instruction instr) { // count rather than strictcount to handle missing AST elements // separate instanceof and inline casts to avoid failed casts with a count of 0 instr instanceof VariableAddressInstruction and - count(instr.(VariableAddressInstruction).getIRVariable().getAST()) != 1 + count(instr.(VariableAddressInstruction).getIRVariable().getAst()) != 1 or instr instanceof ConstantInstruction and count(instr.getResultIRType()) != 1 @@ -121,7 +121,7 @@ private predicate variableAddressValueNumber( // The underlying AST element is used as value-numbering key instead of the // `IRVariable` to work around a problem where a variable or expression with // multiple types gives rise to multiple `IRVariable`s. - unique( | | instr.getIRVariable().getAST()) = ast + unique( | | instr.getIRVariable().getAst()) = ast } private predicate initializeParameterValueNumber( @@ -131,7 +131,7 @@ private predicate initializeParameterValueNumber( // The underlying AST element is used as value-numbering key instead of the // `IRVariable` to work around a problem where a variable or expression with // multiple types gives rise to multiple `IRVariable`s. - instr.getIRVariable().getAST() = var + instr.getIRVariable().getAst() = var } private predicate constantValueNumber( diff --git a/csharp/ql/src/experimental/ir/implementation/raw/internal/IRConstruction.qll b/csharp/ql/src/experimental/ir/implementation/raw/internal/IRConstruction.qll index 956a95e0667..032026e7969 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/internal/IRConstruction.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/internal/IRConstruction.qll @@ -62,7 +62,7 @@ module Raw { Callable callable, Language::AST ast, TempVariableTag tag, CSharpType type ) { exists(TranslatedElement element | - element.getAST() = ast and + element.getAst() = ast and callable = element.getFunction() and element.hasTempVariable(tag, type) ) @@ -105,7 +105,7 @@ module Raw { tag = getInstructionTag(instruction) and ( result = element.getInstructionVariable(tag) or - result.(IRStringLiteral).getAST() = element.getInstructionStringLiteral(tag) + result.(IRStringLiteral).getAst() = element.getInstructionStringLiteral(tag) ) ) } @@ -357,7 +357,7 @@ private module Cached { exists(TranslatedElement s, GotoStmt goto | goto instanceof GotoStmt and not isStrictlyForwardGoto(goto) and - goto = s.getAST() and + goto = s.getAst() and exists(InstructionTag tag | result = s.getInstructionSuccessor(tag, kind) and instruction = s.getInstruction(tag) @@ -372,8 +372,14 @@ private module Cached { } cached - Language::AST getInstructionAST(Instruction instruction) { - result = getInstructionTranslatedElement(instruction).getAST() + Language::AST getInstructionAst(Instruction instruction) { + result = getInstructionTranslatedElement(instruction).getAst() + } + + /** DEPRECATED: Alias for getInstructionAst */ + cached + deprecated Language::AST getInstructionAST(Instruction instruction) { + result = getInstructionAst(instruction) } cached diff --git a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedCondition.qll b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedCondition.qll index 99833c70d0b..fe555344b2f 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedCondition.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedCondition.qll @@ -15,7 +15,10 @@ abstract class TranslatedCondition extends ConditionBase { final override string toString() { result = expr.toString() } - final override Language::AST getAST() { result = expr } + final override Language::AST getAst() { result = expr } + + /** DEPRECATED: Alias for getAst */ + deprecated override Language::AST getAST() { result = this.getAst() } final Expr getExpr() { result = expr } diff --git a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedDeclaration.qll b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedDeclaration.qll index 9b4fbbba723..74d72f4f438 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedDeclaration.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedDeclaration.qll @@ -14,7 +14,7 @@ private import common.TranslatedDeclarationBase * `entry`. */ TranslatedLocalDeclaration getTranslatedLocalDeclaration(LocalVariableDeclExpr declExpr) { - result.getAST() = declExpr + result.getAst() = declExpr } /** @@ -29,7 +29,10 @@ abstract class TranslatedLocalDeclaration extends TranslatedElement, TTranslated final override string toString() { result = expr.toString() } - final override Language::AST getAST() { result = expr } + final override Language::AST getAst() { result = expr } + + /** DEPRECATED: Alias for getAst */ + deprecated override Language::AST getAST() { result = this.getAst() } } /** diff --git a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedElement.qll b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedElement.qll index ea1ad7931cb..d44b2f453f1 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedElement.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedElement.qll @@ -27,7 +27,7 @@ IRUserVariable getIRUserVariable(Language::Function func, Language::Variable var } IRTempVariable getIRTempVariable(Language::AST ast, TempVariableTag tag) { - result.getAST() = ast and + result.getAst() = ast and result.getTag() = tag } @@ -365,7 +365,10 @@ abstract class TranslatedElement extends TTranslatedElement { /** * Gets the AST node being translated. */ - abstract Language::AST getAST(); + abstract Language::AST getAst(); + + /** DEPRECATED: Alias for getAst */ + deprecated Language::AST getAST() { result = this.getAst() } /** * Get the first instruction to be executed in the evaluation of this element. @@ -558,7 +561,7 @@ abstract class TranslatedElement extends TTranslatedElement { * Gets the temporary variable generated by this element with tag `tag`. */ final IRTempVariable getTempVariable(TempVariableTag tag) { - result.getAST() = this.getAST() and + result.getAst() = this.getAst() and result.getTag() = tag and this.hasTempVariable(tag, _) } diff --git a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedExpr.qll b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedExpr.qll index 4f4c1a5f073..a3327d6775c 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedExpr.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedExpr.qll @@ -62,7 +62,10 @@ abstract class TranslatedExpr extends TranslatedExprBase { */ final Type getResultType() { result = expr.getType() } - final override Language::AST getAST() { result = expr } + final override Language::AST getAst() { result = expr } + + /** DEPRECATED: Alias for getAst */ + deprecated override Language::AST getAST() { result = this.getAst() } final override Callable getFunction() { result = expr.getEnclosingCallable() } @@ -577,9 +580,9 @@ class TranslatedArrayAccess extends TranslatedNonConstantExpr { result = this.getInstruction(ElementsAddressTag(0)) or // The successor of an offset expression is a `PointerAdd` expression. - child = this.getOffsetOperand(child.getAST().getIndex()) and - child.getAST().getIndex() >= 0 and - result = this.getInstruction(PointerAddTag(child.getAST().getIndex())) + child = this.getOffsetOperand(child.getAst().getIndex()) and + child.getAst().getIndex() >= 0 and + result = this.getInstruction(PointerAddTag(child.getAst().getIndex())) } override Instruction getResult() { @@ -2039,7 +2042,7 @@ class TranslatedObjectCreation extends TranslatedCreation { // Since calls are also expressions, we can't // use the predicate getTranslatedExpr (since that would // also return `this`). - result.getAST() = this.getAST() + result.getAst() = this.getAst() } override predicate needsLoad() { expr.getObjectType().isValueType() } diff --git a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedFunction.qll b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedFunction.qll index 94b48b0985d..24f340a8718 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedFunction.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedFunction.qll @@ -15,7 +15,7 @@ private import experimental.ir.internal.IRCSharpLanguage as Language /** * Gets the `TranslatedFunction` that represents function `callable`. */ -TranslatedFunction getTranslatedFunction(Callable callable) { result.getAST() = callable } +TranslatedFunction getTranslatedFunction(Callable callable) { result.getAst() = callable } /** * Represents the IR translation of a function. This is the root element for @@ -28,7 +28,10 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction { final override string toString() { result = callable.toString() } - final override Language::AST getAST() { result = callable } + final override Language::AST getAst() { result = callable } + + /** DEPRECATED: Alias for getAst */ + deprecated override Language::AST getAST() { result = this.getAst() } /** * Gets the function being translated. @@ -269,7 +272,7 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction { /** * Gets the `TranslatedParameter` that represents parameter `param`. */ -TranslatedParameter getTranslatedParameter(Parameter param) { result.getAST() = param } +TranslatedParameter getTranslatedParameter(Parameter param) { result.getAst() = param } /** * Represents the IR translation of a function parameter, including the @@ -282,7 +285,10 @@ class TranslatedParameter extends TranslatedElement, TTranslatedParameter { final override string toString() { result = param.toString() } - final override Language::AST getAST() { result = param } + final override Language::AST getAst() { result = param } + + /** DEPRECATED: Alias for getAst */ + deprecated override Language::AST getAST() { result = this.getAst() } final override Callable getFunction() { result = param.getCallable() } diff --git a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedInitialization.qll b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedInitialization.qll index 77e41c15e72..3df60c9f80d 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedInitialization.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedInitialization.qll @@ -51,7 +51,10 @@ abstract class TranslatedInitialization extends TranslatedElement, TTranslatedIn final override Callable getFunction() { result = expr.getEnclosingCallable() } - final override Language::AST getAST() { result = expr } + final override Language::AST getAst() { result = expr } + + /** DEPRECATED: Alias for getAst */ + deprecated override Language::AST getAST() { result = this.getAst() } /** * Gets the expression that is doing the initialization. @@ -206,7 +209,10 @@ abstract class TranslatedElementInitialization extends TranslatedElement { result = initList.toString() + "[" + this.getElementIndex().toString() + "]" } - final override Language::AST getAST() { result = initList } + final override Language::AST getAst() { result = initList } + + /** DEPRECATED: Alias for getAst */ + deprecated override Language::AST getAST() { result = this.getAst() } final override Callable getFunction() { result = initList.getEnclosingCallable() } @@ -310,7 +316,10 @@ abstract class TranslatedConstructorCallFromConstructor extends TranslatedElemen ConstructorCallContext { Call call; - final override Language::AST getAST() { result = call } + final override Language::AST getAst() { result = call } + + /** DEPRECATED: Alias for getAst */ + deprecated override Language::AST getAST() { result = this.getAst() } final override TranslatedElement getChild(int id) { id = 0 and result = this.getConstructorCall() @@ -327,7 +336,7 @@ abstract class TranslatedConstructorCallFromConstructor extends TranslatedElemen } TranslatedConstructorInitializer getTranslatedConstructorInitializer(ConstructorInitializer ci) { - result.getAST() = ci + result.getAst() = ci } /** diff --git a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedStmt.qll b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedStmt.qll index ac69a9c0f28..d95a73e4e42 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedStmt.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedStmt.qll @@ -15,7 +15,7 @@ private import experimental.ir.internal.IRUtilities private import desugar.Foreach private import desugar.Lock -TranslatedStmt getTranslatedStmt(Stmt stmt) { result.getAST() = stmt } +TranslatedStmt getTranslatedStmt(Stmt stmt) { result.getAst() = stmt } abstract class TranslatedStmt extends TranslatedElement, TTranslatedStmt { Stmt stmt; @@ -24,7 +24,10 @@ abstract class TranslatedStmt extends TranslatedElement, TTranslatedStmt { final override string toString() { result = stmt.toString() } - final override Language::AST getAST() { result = stmt } + final override Language::AST getAst() { result = stmt } + + /** DEPRECATED: Alias for getAst */ + deprecated override Language::AST getAST() { result = this.getAst() } final override Callable getFunction() { result = stmt.getEnclosingCallable() } } diff --git a/csharp/ql/src/experimental/ir/implementation/raw/internal/desugar/Delegate.qll b/csharp/ql/src/experimental/ir/implementation/raw/internal/desugar/Delegate.qll index f7c80e497fa..5e51073900e 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/internal/desugar/Delegate.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/internal/desugar/Delegate.qll @@ -27,10 +27,10 @@ private import experimental.ir.implementation.raw.internal.common.TranslatedExpr */ module DelegateElements { TranslatedDelegateConstructorCall getConstructor(DelegateCreation generatedBy) { - result.getAST() = generatedBy + result.getAst() = generatedBy } - TranslatedDelegateInvokeCall getInvoke(DelegateCall generatedBy) { result.getAST() = generatedBy } + TranslatedDelegateInvokeCall getInvoke(DelegateCall generatedBy) { result.getAst() = generatedBy } int noGeneratedElements(Element generatedBy) { ( diff --git a/csharp/ql/src/experimental/ir/implementation/raw/internal/desugar/Foreach.qll b/csharp/ql/src/experimental/ir/implementation/raw/internal/desugar/Foreach.qll index 195072ed124..bc8ec748648 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/internal/desugar/Foreach.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/internal/desugar/Foreach.qll @@ -56,9 +56,9 @@ private import internal.TranslatedCompilerGeneratedElement * Module that exposes the functions needed for the translation of the `foreach` stmt. */ module ForeachElements { - TranslatedForeachTry getTry(ForeachStmt generatedBy) { result.getAST() = generatedBy } + TranslatedForeachTry getTry(ForeachStmt generatedBy) { result.getAst() = generatedBy } - TranslatedForeachEnumerator getEnumDecl(ForeachStmt generatedBy) { result.getAST() = generatedBy } + TranslatedForeachEnumerator getEnumDecl(ForeachStmt generatedBy) { result.getAst() = generatedBy } int noGeneratedElements() { result = 13 } } @@ -71,14 +71,14 @@ private class TranslatedForeachTry extends TranslatedCompilerGeneratedTry, override TranslatedElement getFinally() { exists(TranslatedForeachFinally ff | - ff.getAST() = generatedBy and + ff.getAst() = generatedBy and result = ff ) } override TranslatedElement getBody() { exists(TranslatedForeachWhile fw | - fw.getAST() = generatedBy and + fw.getAst() = generatedBy and result = fw ) } @@ -96,7 +96,7 @@ private class TranslatedForeachFinally extends TranslatedCompilerGeneratedBlock, override TranslatedElement getStmt(int index) { index = 0 and exists(TranslatedForeachDispose fd | - fd.getAST() = generatedBy and + fd.getAst() = generatedBy and result = fd ) } @@ -147,14 +147,14 @@ class TranslatedForeachWhile extends TranslatedCompilerGeneratedStmt, ConditionC TranslatedElement getInit() { exists(TranslatedForeachIterVar iv | - iv.getAST() = generatedBy and + iv.getAst() = generatedBy and result = iv ) } ValueConditionBase getCondition() { exists(TranslatedForeachWhileCondition cond | - cond.getAST() = generatedBy and + cond.getAst() = generatedBy and result = cond ) } @@ -180,7 +180,7 @@ private class TranslatedForeachMoveNext extends TranslatedCompilerGeneratedCall, override TranslatedExprBase getQualifier() { exists(TranslatedMoveNextEnumAcc acc | - acc.getAST() = generatedBy and + acc.getAst() = generatedBy and result = acc ) } @@ -230,7 +230,7 @@ private class TranslatedForeachCurrent extends TranslatedCompilerGeneratedCall, override TranslatedExprBase getQualifier() { exists(TranslatedForeachCurrentEnumAcc acc | - acc.getAST() = generatedBy and + acc.getAst() = generatedBy and result = acc ) } @@ -263,7 +263,7 @@ private class TranslatedForeachDispose extends TranslatedCompilerGeneratedCall, override TranslatedExprBase getQualifier() { exists(TranslatedForeachDisposeEnumAcc acc | - acc.getAST() = generatedBy and + acc.getAst() = generatedBy and result = acc ) } @@ -282,7 +282,7 @@ private class TranslatedForeachWhileCondition extends TranslatedCompilerGenerate override TranslatedCompilerGeneratedCall getValueExpr() { exists(TranslatedForeachMoveNext mn | - mn.getAST() = generatedBy and + mn.getAst() = generatedBy and result = mn ) } @@ -311,7 +311,7 @@ private class TranslatedForeachEnumerator extends TranslatedCompilerGeneratedDec override TranslatedCompilerGeneratedCall getInitialization() { exists(TranslatedForeachGetEnumerator ge | - ge.getAST() = generatedBy and + ge.getAst() = generatedBy and result = ge ) } @@ -339,7 +339,7 @@ private class TranslatedForeachIterVar extends TranslatedCompilerGeneratedDeclar override TranslatedCompilerGeneratedCall getInitialization() { exists(TranslatedForeachCurrent crtProp | - crtProp.getAST() = generatedBy and + crtProp.getAst() = generatedBy and result = crtProp ) } @@ -361,7 +361,7 @@ private class TranslatedMoveNextEnumAcc extends TTranslatedCompilerGeneratedElem override Type getVariableType() { exists(TranslatedForeachGetEnumerator ge | - ge.getAST() = generatedBy and + ge.getAst() = generatedBy and result = ge.getCallResultType() ) } @@ -393,7 +393,7 @@ private class TranslatedForeachCurrentEnumAcc extends TTranslatedCompilerGenerat override Type getVariableType() { exists(TranslatedForeachGetEnumerator ge | - ge.getAST() = generatedBy and + ge.getAst() = generatedBy and result = ge.getCallResultType() ) } @@ -425,7 +425,7 @@ private class TranslatedForeachDisposeEnumAcc extends TTranslatedCompilerGenerat override Type getVariableType() { exists(TranslatedForeachGetEnumerator ge | - ge.getAST() = generatedBy and + ge.getAst() = generatedBy and result = ge.getCallResultType() ) } diff --git a/csharp/ql/src/experimental/ir/implementation/raw/internal/desugar/Lock.qll b/csharp/ql/src/experimental/ir/implementation/raw/internal/desugar/Lock.qll index c83957d9b94..e061a1371b2 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/internal/desugar/Lock.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/internal/desugar/Lock.qll @@ -42,12 +42,12 @@ private import internal.TranslatedCompilerGeneratedExpr * Module that exposes the functions needed for the translation of the `lock` stmt. */ module LockElements { - TranslatedLockedVarDecl getLockedVarDecl(LockStmt generatedBy) { result.getAST() = generatedBy } + TranslatedLockedVarDecl getLockedVarDecl(LockStmt generatedBy) { result.getAst() = generatedBy } - TranslatedLockTry getTry(LockStmt generatedBy) { result.getAST() = generatedBy } + TranslatedLockTry getTry(LockStmt generatedBy) { result.getAst() = generatedBy } TranslatedLockWasTakenDecl getLockWasTakenDecl(LockStmt generatedBy) { - result.getAST() = generatedBy + result.getAst() = generatedBy } int noGeneratedElements() { result = 14 } @@ -64,14 +64,14 @@ private class TranslatedLockTry extends TranslatedCompilerGeneratedTry, override TranslatedElement getFinally() { exists(TranslatedLockFinally fin | - fin.getAST() = generatedBy and + fin.getAst() = generatedBy and result = fin ) } override TranslatedElement getBody() { exists(TranslatedLockTryBody ltb | - ltb.getAST() = generatedBy and + ltb.getAst() = generatedBy and result = ltb ) } @@ -89,7 +89,7 @@ private class TranslatedLockTryBody extends TranslatedCompilerGeneratedBlock, override TranslatedElement getStmt(int index) { index = 0 and exists(TranslatedMonitorEnter me | - me.getAST() = generatedBy and + me.getAst() = generatedBy and result = me ) or @@ -110,7 +110,7 @@ private class TranslatedLockFinally extends TranslatedCompilerGeneratedBlock, override TranslatedElement getStmt(int index) { index = 0 and exists(TranslatedFinallyIf fif | - fif.getAST() = generatedBy and + fif.getAst() = generatedBy and result = fif ) } @@ -138,7 +138,7 @@ private class TranslatedMonitorExit extends TranslatedCompilerGeneratedCall, override TranslatedExprBase getArgument(int id) { id = 0 and exists(TranslatedMonitorExitVarAcc var | - var.getAST() = generatedBy and + var.getAst() = generatedBy and result = var ) } @@ -170,13 +170,13 @@ private class TranslatedMonitorEnter extends TranslatedCompilerGeneratedCall, override TranslatedExprBase getArgument(int id) { id = 0 and exists(TranslatedMonitorEnterVarAcc var | - var.getAST() = generatedBy and + var.getAst() = generatedBy and result = var ) or id = 1 and exists(TranslatedLockWasTakenRefArg refArg | - refArg.getAST() = generatedBy and + refArg.getAst() = generatedBy and result = refArg ) } @@ -197,7 +197,7 @@ private class TranslatedIfCondition extends TranslatedCompilerGeneratedValueCond override TranslatedCompilerGeneratedExpr getValueExpr() { exists(TranslatedLockWasTakenCondVarAcc condVar | - condVar.getAST() = generatedBy and + condVar.getAst() = generatedBy and result = condVar ) } @@ -216,14 +216,14 @@ private class TranslatedFinallyIf extends TranslatedCompilerGeneratedIfStmt, override TranslatedCompilerGeneratedValueCondition getCondition() { exists(TranslatedIfCondition cond | - cond.getAST() = generatedBy and + cond.getAst() = generatedBy and result = cond ) } override TranslatedCompilerGeneratedCall getThen() { exists(TranslatedMonitorExit me | - me.getAST() = generatedBy and + me.getAst() = generatedBy and result = me ) } @@ -271,7 +271,7 @@ private class TranslatedLockWasTakenDecl extends TranslatedCompilerGeneratedDecl override TranslatedCompilerGeneratedExpr getInitialization() { exists(TranslatedWasTakenConst const | - const.getAST() = generatedBy and + const.getAst() = generatedBy and result = const ) } diff --git a/csharp/ql/src/experimental/ir/implementation/raw/internal/desugar/internal/TranslatedCompilerGeneratedElement.qll b/csharp/ql/src/experimental/ir/implementation/raw/internal/desugar/internal/TranslatedCompilerGeneratedElement.qll index 1eb7520eda4..ffcc400a9bc 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/internal/desugar/internal/TranslatedCompilerGeneratedElement.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/internal/desugar/internal/TranslatedCompilerGeneratedElement.qll @@ -18,5 +18,8 @@ abstract class TranslatedCompilerGeneratedElement extends TranslatedElement, final override Callable getFunction() { result = generatedBy.getEnclosingCallable() } - final override Language::AST getAST() { result = generatedBy } + final override Language::AST getAst() { result = generatedBy } + + /** DEPRECATED: Alias for getAst */ + deprecated override Language::AST getAST() { result = getAst() } } diff --git a/csharp/ql/src/experimental/ir/implementation/raw/internal/reachability/DominanceInternal.qll b/csharp/ql/src/experimental/ir/implementation/raw/internal/reachability/DominanceInternal.qll index cee8fa1543b..aaa4cc7bd53 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/internal/reachability/DominanceInternal.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/internal/reachability/DominanceInternal.qll @@ -1,7 +1,5 @@ private import ReachableBlock as Reachability -private module ReachabilityGraph = Reachability::Graph; - module Graph { import Reachability::Graph diff --git a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IRVariable.qll b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IRVariable.qll index 146fc270738..ca4708857a7 100644 --- a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IRVariable.qll +++ b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IRVariable.qll @@ -55,7 +55,10 @@ class IRVariable extends TIRVariable { * Gets the AST node that declared this variable, or that introduced this * variable as part of the AST-to-IR translation. */ - Language::AST getAST() { none() } + Language::AST getAst() { none() } + + /** DEPRECATED: Alias for getAst */ + deprecated Language::AST getAST() { result = getAst() } /** * Gets an identifier string for the variable. This identifier is unique @@ -66,7 +69,7 @@ class IRVariable extends TIRVariable { /** * Gets the source location of this variable. */ - final Language::Location getLocation() { result = getAST().getLocation() } + final Language::Location getLocation() { result = getAst().getLocation() } /** * Gets the IR for the function that references this variable. @@ -90,7 +93,10 @@ class IRUserVariable extends IRVariable, TIRUserVariable { final override string toString() { result = getVariable().toString() } - final override Language::AST getAST() { result = var } + final override Language::AST getAst() { result = var } + + /** DEPRECATED: Alias for getAst */ + deprecated override Language::AST getAST() { result = getAst() } final override string getUniqueId() { result = getVariable().toString() + " " + getVariable().getLocation().toString() @@ -157,7 +163,10 @@ class IRGeneratedVariable extends IRVariable { final override Language::LanguageType getLanguageType() { result = type } - final override Language::AST getAST() { result = ast } + final override Language::AST getAst() { result = ast } + + /** DEPRECATED: Alias for getAst */ + deprecated override Language::AST getAST() { result = getAst() } override string toString() { result = getBaseString() + getLocationString() } diff --git a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Instruction.qll b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Instruction.qll index 1c2cc493338..e5a908bbf9a 100644 --- a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Instruction.qll +++ b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Instruction.qll @@ -41,7 +41,7 @@ class Instruction extends Construction::TStageInstruction { } /** Gets a textual representation of this element. */ - final string toString() { result = this.getOpcode().toString() + ": " + this.getAST().toString() } + final string toString() { result = this.getOpcode().toString() + ": " + this.getAst().toString() } /** * Gets a string showing the result, opcode, and operands of the instruction, equivalent to what @@ -136,7 +136,7 @@ class Instruction extends Construction::TStageInstruction { string getResultId() { this.shouldGenerateDumpStrings() and result = - this.getResultPrefix() + this.getAST().getLocation().getStartLine() + "_" + this.getLineRank() + this.getResultPrefix() + this.getAst().getLocation().getStartLine() + "_" + this.getLineRank() } /** @@ -208,12 +208,15 @@ class Instruction extends Construction::TStageInstruction { /** * Gets the AST that caused this instruction to be generated. */ - final Language::AST getAST() { result = Construction::getInstructionAST(this) } + final Language::AST getAst() { result = Construction::getInstructionAst(this) } + + /** DEPRECATED: Alias for getAst */ + deprecated Language::AST getAST() { result = this.getAst() } /** * Gets the location of the source code for this instruction. */ - final Language::Location getLocation() { result = this.getAST().getLocation() } + final Language::Location getLocation() { result = this.getAst().getLocation() } /** * Gets the `Expr` whose result is computed by this instruction, if any. The `Expr` may be a @@ -459,7 +462,10 @@ class VariableInstruction extends Instruction { /** * Gets the AST variable that this instruction's IR variable refers to, if one exists. */ - final Language::Variable getASTVariable() { result = var.(IRUserVariable).getVariable() } + final Language::Variable getAstVariable() { result = var.(IRUserVariable).getVariable() } + + /** DEPRECATED: Alias for getAstVariable */ + deprecated Language::Variable getASTVariable() { result = this.getAstVariable() } } /** diff --git a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Operand.qll b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Operand.qll index 89b82657c3b..c1e997d5844 100644 --- a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Operand.qll +++ b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Operand.qll @@ -18,7 +18,7 @@ private import internal.OperandInternal * of `TOperand` that are used in this stage. */ private class TStageOperand = - TRegisterOperand or TNonSSAMemoryOperand or TPhiOperand or TChiOperand; + TRegisterOperand or TNonSsaMemoryOperand or TPhiOperand or TChiOperand; /** * A known location. Testing `loc instanceof KnownLocation` will account for non existing locations, as @@ -38,7 +38,7 @@ class Operand extends TStageOperand { // Ensure that the operand does not refer to instructions from earlier stages that are unreachable here exists(Instruction use, Instruction def | this = registerOperand(use, _, def)) or - exists(Instruction use | this = nonSSAMemoryOperand(use, _)) + exists(Instruction use | this = nonSsaMemoryOperand(use, _)) or exists(Instruction use, Instruction def, IRBlock predecessorBlock | this = phiOperand(use, def, predecessorBlock, _) or @@ -209,7 +209,7 @@ class Operand extends TStageOperand { class MemoryOperand extends Operand { cached MemoryOperand() { - this instanceof TNonSSAMemoryOperand or + this instanceof TNonSsaMemoryOperand or this instanceof TPhiOperand or this instanceof TChiOperand } @@ -249,7 +249,7 @@ class NonPhiOperand extends Operand { NonPhiOperand() { this = registerOperand(useInstr, tag, _) or - this = nonSSAMemoryOperand(useInstr, tag) or + this = nonSsaMemoryOperand(useInstr, tag) or this = chiOperand(useInstr, tag) } @@ -299,7 +299,7 @@ class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, TNonPhiMemoryOpe cached NonPhiMemoryOperand() { - this = nonSSAMemoryOperand(useInstr, tag) + this = nonSsaMemoryOperand(useInstr, tag) or this = chiOperand(useInstr, tag) } 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 fdb645e03f0..2dc735f49df 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 @@ -99,7 +99,7 @@ private predicate filteredNumberableInstruction(Instruction instr) { // count rather than strictcount to handle missing AST elements // separate instanceof and inline casts to avoid failed casts with a count of 0 instr instanceof VariableAddressInstruction and - count(instr.(VariableAddressInstruction).getIRVariable().getAST()) != 1 + count(instr.(VariableAddressInstruction).getIRVariable().getAst()) != 1 or instr instanceof ConstantInstruction and count(instr.getResultIRType()) != 1 @@ -121,7 +121,7 @@ private predicate variableAddressValueNumber( // The underlying AST element is used as value-numbering key instead of the // `IRVariable` to work around a problem where a variable or expression with // multiple types gives rise to multiple `IRVariable`s. - unique( | | instr.getIRVariable().getAST()) = ast + unique( | | instr.getIRVariable().getAst()) = ast } private predicate initializeParameterValueNumber( @@ -131,7 +131,7 @@ private predicate initializeParameterValueNumber( // The underlying AST element is used as value-numbering key instead of the // `IRVariable` to work around a problem where a variable or expression with // multiple types gives rise to multiple `IRVariable`s. - instr.getIRVariable().getAST() = var + instr.getIRVariable().getAst() = var } private predicate constantValueNumber( diff --git a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/OperandInternal.qll b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/OperandInternal.qll index 88a4e6f8551..e522599abe9 100644 --- a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/OperandInternal.qll +++ b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/OperandInternal.qll @@ -1,2 +1,2 @@ private import experimental.ir.implementation.internal.TOperand -import UnaliasedSSAOperands +import UnaliasedSsaOperands diff --git a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/PrintSSA.qll b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/PrintSSA.qll index 72bb239c153..c7487872512 100644 --- a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/PrintSSA.qll +++ b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/PrintSSA.qll @@ -2,7 +2,7 @@ private import SSAConstructionInternal private import OldIR private import Alias private import SSAConstruction -private import DebugSSA +private import DebugSsa bindingset[offset] private string getKeySuffixForOffset(int offset) { diff --git a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SSAConsistency.qll b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SSAConsistency.qll index 5686bb439eb..1c75529be00 100644 --- a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SSAConsistency.qll +++ b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SSAConsistency.qll @@ -1,2 +1,2 @@ private import SSAConstruction as SSA -import SSA::SSAConsistency +import SSA::SsaConsistency diff --git a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll index 5092e921cb3..13ec2ca4ca4 100644 --- a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll +++ b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll @@ -112,7 +112,7 @@ private module Cached { exists(Alias::getResultMemoryLocation(oldInstruction)) or // This result was already modeled by a previous iteration of SSA. - Alias::canReuseSSAForOldResult(oldInstruction) + Alias::canReuseSsaForOldResult(oldInstruction) } cached @@ -182,7 +182,7 @@ private module Cached { * unreachable, this predicate will recurse through any degenerate `Phi` instructions to find the * true definition. */ - private Instruction getNewDefinitionFromOldSSA(OldIR::MemoryOperand oldOperand, Overlap overlap) { + private Instruction getNewDefinitionFromOldSsa(OldIR::MemoryOperand oldOperand, Overlap overlap) { exists(Overlap originalOverlap | originalOverlap = oldOperand.getDefinitionOverlap() and ( @@ -191,7 +191,7 @@ private module Cached { or exists(OldIR::PhiInputOperand phiOperand, Overlap phiOperandOverlap | phiOperand = getDegeneratePhiOperand(oldOperand.getAnyDef()) and - result = getNewDefinitionFromOldSSA(phiOperand, phiOperandOverlap) and + result = getNewDefinitionFromOldSsa(phiOperand, phiOperandOverlap) and overlap = combineOverlap(pragma[only_bind_out](phiOperandOverlap), pragma[only_bind_out](originalOverlap)) @@ -233,7 +233,7 @@ private module Cached { ) or exists(OldIR::NonPhiMemoryOperand oldOperand | - result = getNewDefinitionFromOldSSA(oldOperand, overlap) and + result = getNewDefinitionFromOldSsa(oldOperand, overlap) and oldOperand.getUse() = instruction and tag = oldOperand.getOperandTag() ) @@ -307,13 +307,13 @@ private module Cached { * Gets the new definition instruction for the operand of `instr` that flows from the block * `newPredecessorBlock`, based on that operand's definition in the old IR. */ - private Instruction getNewPhiOperandDefinitionFromOldSSA( + private Instruction getNewPhiOperandDefinitionFromOldSsa( Instruction instr, IRBlock newPredecessorBlock, Overlap overlap ) { exists(OldIR::PhiInstruction oldPhi, OldIR::PhiInputOperand oldOperand | oldPhi = getOldInstruction(instr) and oldOperand = oldPhi.getInputOperand(getOldBlock(newPredecessorBlock)) and - result = getNewDefinitionFromOldSSA(oldOperand, overlap) + result = getNewDefinitionFromOldSsa(oldOperand, overlap) ) } @@ -333,7 +333,7 @@ private module Cached { overlap = Alias::getOverlap(actualDefLocation, useLocation) ) or - result = getNewPhiOperandDefinitionFromOldSSA(instr, newPredecessorBlock, overlap) + result = getNewPhiOperandDefinitionFromOldSsa(instr, newPredecessorBlock, overlap) } cached @@ -412,17 +412,17 @@ private module Cached { } cached - Language::AST getInstructionAST(Instruction instr) { - result = getOldInstruction(instr).getAST() + Language::AST getInstructionAst(Instruction instr) { + result = getOldInstruction(instr).getAst() or exists(RawIR::Instruction blockStartInstr | instr = phiInstruction(blockStartInstr, _) and - result = blockStartInstr.getAST() + result = blockStartInstr.getAst() ) or exists(RawIR::Instruction primaryInstr | instr = chiInstruction(primaryInstr) and - result = primaryInstr.getAST() + result = primaryInstr.getAst() ) or exists(IRFunctionBase irFunc | @@ -430,6 +430,12 @@ private module Cached { ) } + /** DEPRECATED: Alias for getInstructionAst */ + cached + deprecated Language::AST getInstructionAST(Instruction instr) { + result = getInstructionAst(instr) + } + cached Language::LanguageType getInstructionResultType(Instruction instr) { result = instr.(RawIR::Instruction).getResultLanguageType() @@ -975,35 +981,41 @@ module DefUse { } } -predicate canReuseSSAForMemoryResult(Instruction instruction) { +predicate canReuseSsaForMemoryResult(Instruction instruction) { exists(OldInstruction oldInstruction | oldInstruction = getOldInstruction(instruction) and ( // The previous iteration said it was reusable, so we should mark it as reusable as well. - Alias::canReuseSSAForOldResult(oldInstruction) + Alias::canReuseSsaForOldResult(oldInstruction) or // The current alias analysis says it is reusable. - Alias::getResultMemoryLocation(oldInstruction).canReuseSSA() + Alias::getResultMemoryLocation(oldInstruction).canReuseSsa() ) ) or exists(Alias::MemoryLocation defLocation | // This is a `Phi` for a reusable location, so the result of the `Phi` is reusable as well. instruction = phiInstruction(_, defLocation) and - defLocation.canReuseSSA() + defLocation.canReuseSsa() ) // We don't support reusing SSA for any location that could create a `Chi` instruction. } +/** DEPRECATED: Alias for canReuseSsaForMemoryResult */ +deprecated predicate canReuseSSAForMemoryResult = canReuseSsaForMemoryResult/1; + /** * Expose some of the internal predicates to PrintSSA.qll. We do this by publically importing those modules in the * `DebugSSA` module, which is then imported by PrintSSA. */ -module DebugSSA { +module DebugSsa { import PhiInsertion import DefUse } +/** DEPRECATED: Alias for DebugSsa */ +deprecated module DebugSSA = DebugSsa; + import CachedForDebugging cached @@ -1038,7 +1050,7 @@ private module CachedForDebugging { private OldIR::IRTempVariable getOldTempVariable(IRTempVariable var) { result.getEnclosingFunction() = var.getEnclosingFunction() and - result.getAST() = var.getAST() and + result.getAst() = var.getAst() and result.getTag() = var.getTag() } @@ -1061,7 +1073,7 @@ private module CachedForDebugging { int maxValue() { result = 2147483647 } } -module SSAConsistency { +module SsaConsistency { /** * Holds if a `MemoryOperand` has more than one `MemoryLocation` assigned by alias analysis. */ @@ -1114,6 +1126,9 @@ module SSAConsistency { } } +/** DEPRECATED: Alias for SsaConsistency */ +deprecated module SSAConsistency = SsaConsistency; + /** * Provides the portion of the parameterized IR interface that is used to construct the SSA stages * of the IR. The raw stage of the IR does not expose these predicates. diff --git a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SSAConstructionInternal.qll b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SSAConstructionInternal.qll index 8f726b81345..005ea53b018 100644 --- a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SSAConstructionInternal.qll +++ b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SSAConstructionInternal.qll @@ -3,7 +3,7 @@ import experimental.ir.implementation.raw.internal.reachability.ReachableBlock a import experimental.ir.implementation.raw.internal.reachability.Dominance as Dominance import experimental.ir.implementation.unaliased_ssa.IR as NewIR import experimental.ir.implementation.raw.internal.IRConstruction as RawStage -import experimental.ir.implementation.internal.TInstruction::UnaliasedSSAInstructions as SSAInstructions +import experimental.ir.implementation.internal.TInstruction::UnaliasedSsaInstructions as SSAInstructions import experimental.ir.internal.IRCSharpLanguage as Language import SimpleSSA as Alias -import experimental.ir.implementation.internal.TOperand::UnaliasedSSAOperands as SSAOperands +import experimental.ir.implementation.internal.TOperand::UnaliasedSsaOperands as SSAOperands diff --git a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SimpleSSA.qll b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SimpleSSA.qll index f3e02c9f6a8..ec2e6f5ef34 100644 --- a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SimpleSSA.qll +++ b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SimpleSSA.qll @@ -41,11 +41,14 @@ predicate isVariableModeled(Allocation var) { * subsequent iterations will recompute SSA for any variable that we assumed did not escape, but * actually would have escaped if we had used a sound escape analysis. */ -predicate canReuseSSAForVariable(IRAutomaticVariable var) { +predicate canReuseSsaForVariable(IRAutomaticVariable var) { isVariableModeled(var) and not allocationEscapes(var) } +/** DEPRECATED: Alias for canReuseSsaForVariable */ +deprecated predicate canReuseSSAForVariable = canReuseSsaForVariable/1; + private newtype TMemoryLocation = MkMemoryLocation(Allocation var) { isVariableModeled(var) } private MemoryLocation getMemoryLocation(Allocation var) { result.getAllocation() = var } @@ -69,10 +72,16 @@ class MemoryLocation extends TMemoryLocation { final string getUniqueId() { result = var.getUniqueId() } - final predicate canReuseSSA() { canReuseSSAForVariable(var) } + final predicate canReuseSsa() { canReuseSsaForVariable(var) } + + /** DEPRECATED: Alias for canReuseSsa */ + deprecated predicate canReuseSSA() { canReuseSsa() } } -predicate canReuseSSAForOldResult(Instruction instr) { none() } +predicate canReuseSsaForOldResult(Instruction instr) { none() } + +/** DEPRECATED: Alias for canReuseSsaForOldResult */ +deprecated predicate canReuseSSAForOldResult = canReuseSsaForOldResult/1; /** * Represents a set of `MemoryLocation`s that cannot overlap with diff --git a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/reachability/DominanceInternal.qll b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/reachability/DominanceInternal.qll index cee8fa1543b..aaa4cc7bd53 100644 --- a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/reachability/DominanceInternal.qll +++ b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/reachability/DominanceInternal.qll @@ -1,7 +1,5 @@ private import ReachableBlock as Reachability -private module ReachabilityGraph = Reachability::Graph; - module Graph { import Reachability::Graph diff --git a/csharp/ql/src/experimental/ir/internal/CSharpType.qll b/csharp/ql/src/experimental/ir/internal/CSharpType.qll index 02dee3edff9..d87596ae643 100644 --- a/csharp/ql/src/experimental/ir/internal/CSharpType.qll +++ b/csharp/ql/src/experimental/ir/internal/CSharpType.qll @@ -88,15 +88,6 @@ predicate hasAddressType(int byteSize) { */ predicate hasFunctionAddressType(int byteSize) { byteSize = getTypeSize(any(NullType type)) } -private int getBaseClassSize(ValueOrRefType type) { - if exists(type.getBaseClass()) then result = getContentSize(type.getBaseClass()) else result = 0 -} - -private int getContentSize(ValueOrRefType type) { - result = - getBaseClassSize(type) + sum(Field field | not field.isStatic() | getTypeSize(field.getType())) -} - private predicate isOpaqueType(ValueOrRefType type) { type instanceof Struct or type instanceof NullableType or diff --git a/csharp/ql/src/experimental/ir/internal/IRGuards.qll b/csharp/ql/src/experimental/ir/internal/IRGuards.qll index a87788eb9a0..91e2208c6f7 100644 --- a/csharp/ql/src/experimental/ir/internal/IRGuards.qll +++ b/csharp/ql/src/experimental/ir/internal/IRGuards.qll @@ -28,8 +28,8 @@ class GuardCondition extends Expr { or // the IR short-circuits if(!x) // don't produce a guard condition for `y = !x` and other non-short-circuited cases - not exists(Instruction inst | this = inst.getAST()) and - exists(IRGuardCondition ir | this.(LogicalNotExpr).getOperand() = ir.getAST()) + not exists(Instruction inst | this = inst.getAst()) and + exists(IRGuardCondition ir | this.(LogicalNotExpr).getOperand() = ir.getAst()) } /** @@ -172,8 +172,8 @@ private class GuardConditionFromBinaryLogicalOperator extends GuardCondition { */ private class GuardConditionFromShortCircuitNot extends GuardCondition, LogicalNotExpr { GuardConditionFromShortCircuitNot() { - not exists(Instruction inst | this = inst.getAST()) and - exists(IRGuardCondition ir | this.getOperand() = ir.getAST()) + not exists(Instruction inst | this = inst.getAst()) and + exists(IRGuardCondition ir | this.getOperand() = ir.getAst()) } override predicate controls(BasicBlock controlled, boolean testIsTrue) { @@ -267,7 +267,7 @@ private class GuardConditionFromIR extends GuardCondition { private predicate controlsBlock1(BasicBlock controlled, boolean testIsTrue) { exists(IRBlock irb | forex(IRGuardCondition inst | inst = ir | inst.controls(irb, testIsTrue)) and - irb.getAnInstruction().getAST().(ControlFlowElement).getAControlFlowNode().getBasicBlock() = + irb.getAnInstruction().getAst().(ControlFlowElement).getAControlFlowNode().getBasicBlock() = controlled and not isUnreachedBlock(irb) ) diff --git a/csharp/ql/src/experimental/ir/rangeanalysis/RangeAnalysis.qll b/csharp/ql/src/experimental/ir/rangeanalysis/RangeAnalysis.qll index ccc6b9ea30e..ebdca09414f 100644 --- a/csharp/ql/src/experimental/ir/rangeanalysis/RangeAnalysis.qll +++ b/csharp/ql/src/experimental/ir/rangeanalysis/RangeAnalysis.qll @@ -623,7 +623,7 @@ private predicate boundedInstruction( ) or exists(PropertyAccess pa | - i.(CallInstruction).getAST() = pa and + i.(CallInstruction).getAst() = pa and pa.getProperty().getName() = "Length" and b instanceof ZeroBound and delta = origdelta and diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml index 4938eea6697..a15e7a8f71d 100644 --- a/csharp/ql/src/qlpack.yml +++ b/csharp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-queries -version: 0.0.11-dev +version: 0.0.12-dev groups: - csharp - queries diff --git a/csharp/ql/src/utils/model-generator/CaptureSummaryModels.ql b/csharp/ql/src/utils/model-generator/CaptureSummaryModels.ql new file mode 100644 index 00000000000..9cc931af0fa --- /dev/null +++ b/csharp/ql/src/utils/model-generator/CaptureSummaryModels.ql @@ -0,0 +1,91 @@ +/** + * @name Capture summary models. + * @description Finds applicable summary models to be used by other queries. + * @id csharp/utils/model-generator/summary-models + */ + +private import CaptureSummaryModels + +/** + * Capture fluent APIs that return `this`. + * Example of a fluent API: + * ```csharp + * public class BasicFlow { + * public BasicFlow ReturnThis(object input) + * { + * // some side effect + * return this; + * } + * ``` + * Captured Model: + * ```Summaries;BasicFlow;false;ReturnThis;(System.Object);Argument[Qualifier];ReturnValue;value``` + * Capture APIs that transfer taint from an input parameter to an output return + * value or parameter. + * Allows a sequence of read steps followed by a sequence of store steps. + * + * Examples: + * + * ```csharp + * public class BasicFlow { + * private string tainted; + * + * public String ReturnField() + * { + * return tainted; + * } + * + * public void AssignFieldToArray(object[] target) + * { + * target[0] = tainted; + * } + * } + * ``` + * Captured Models: + * ``` + * Summaries;BasicFlow;false;ReturnField;();Argument[Qualifier];ReturnValue;taint | + * Summaries;BasicFlow;false;AssignFieldToArray;(System.Object[]);Argument[Qualifier];Argument[0].Element;taint + * ``` + * + * ```csharp + * public class BasicFlow { + * private string tainted; + * + * public void SetField(string s) + * { + * tainted = s; + * } + * } + * ``` + * Captured Model: + * ```Summaries;BasicFlow;false;SetField;(System.String);Argument[0];Argument[Qualifier];taint``` + * + * ```csharp + * public class BasicFlow { + * public void ReturnSubstring(string s) + * { + * return s.Substring(0, 1); + * } + * } + * ``` + * Captured Model: + * ```Summaries;BasicFlow;false;ReturnSubstring;(System.String);Argument[0];ReturnValue;taint``` + * + * ```csharp + * public class BasicFlow { + * public void AssignToArray(int data, int[] target) + * { + * target[0] = data; + * } + * } + * ``` + * Captured Model: + * ```Summaries;BasicFlow;false;AssignToArray;(System.Int32,System.Int32[]);Argument[0];Argument[1].Element;taint``` + */ +private string captureFlow(TargetApi api) { + result = captureQualifierFlow(api) or + result = captureThroughFlow(api) +} + +from TargetApi api, string flow +where flow = captureFlow(api) +select flow order by flow diff --git a/csharp/ql/src/utils/model-generator/CaptureSummaryModels.qll b/csharp/ql/src/utils/model-generator/CaptureSummaryModels.qll new file mode 100644 index 00000000000..1c7df39d97f --- /dev/null +++ b/csharp/ql/src/utils/model-generator/CaptureSummaryModels.qll @@ -0,0 +1,98 @@ +/** + * Provides classes and predicates related to capturing summary models + * of the Standard or a 3rd party library. + */ + +import CaptureSummaryModelsSpecific + +/** + * Gets the summary model of `api`, if it follows the `fluent` programming pattern (returns `this`). + */ +string captureQualifierFlow(TargetApi api) { + exists(ReturnNodeExt ret | + api = returnNodeEnclosingCallable(ret) and + isOwnInstanceAccessNode(ret) + ) and + result = asValueModel(api, qualifierString(), "ReturnValue") +} + +/** + * A FlowState representing a tainted read. + */ +private class TaintRead extends DataFlow::FlowState { + TaintRead() { this = "TaintRead" } +} + +/** + * A FlowState representing a tainted write. + */ +private class TaintStore extends DataFlow::FlowState { + TaintStore() { this = "TaintStore" } +} + +/** + * A TaintTracking Configuration used for tracking flow through APIs. + * The sources are the parameters of an API and the sinks are the return values (excluding `this`) and parameters. + * + * This can be used to generate Flow summaries for APIs from parameter to return. + */ +class ThroughFlowConfig extends TaintTracking::Configuration { + ThroughFlowConfig() { this = "ThroughFlowConfig" } + + override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { + source instanceof DataFlow::ParameterNode and + source.getEnclosingCallable() instanceof TargetApi and + state instanceof TaintRead + } + + override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { + sink instanceof ReturnNodeExt and + not isOwnInstanceAccessNode(sink) and + not exists(captureQualifierFlow(sink.asExpr().getEnclosingCallable())) and + (state instanceof TaintRead or state instanceof TaintStore) + } + + override predicate isAdditionalTaintStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + exists(TypedContent tc | + store(node1, tc, node2, _) and + isRelevantContent(tc.getContent()) and + (state1 instanceof TaintRead or state1 instanceof TaintStore) and + state2 instanceof TaintStore + ) + or + exists(DataFlow::Content c | + readStep(node1, c, node2) and + isRelevantContent(c) and + state1 instanceof TaintRead and + state2 instanceof TaintRead + ) + } + + override predicate isSanitizer(DataFlow::Node n) { + exists(Type t | t = n.getType() and not isRelevantType(t)) + } + + override DataFlow::FlowFeature getAFeature() { + result instanceof DataFlow::FeatureEqualSourceSinkCallContext + } +} + +/** + * Gets the summary model(s) of `api`, if there is flow from parameters to return value or parameter. + */ +string captureThroughFlow(TargetApi api) { + exists( + ThroughFlowConfig config, DataFlow::ParameterNode p, ReturnNodeExt returnNodeExt, string input, + string output + | + config.hasFlow(p, returnNodeExt) and + returnNodeExt.getEnclosingCallable() = api and + input = parameterNodeAsInput(p) and + output = returnNodeAsOutput(returnNodeExt) and + input != output and + result = asTaintModel(api, input, output) + ) +} diff --git a/csharp/ql/src/utils/model-generator/CaptureSummaryModelsSpecific.qll b/csharp/ql/src/utils/model-generator/CaptureSummaryModelsSpecific.qll new file mode 100644 index 00000000000..305dd775727 --- /dev/null +++ b/csharp/ql/src/utils/model-generator/CaptureSummaryModelsSpecific.qll @@ -0,0 +1,15 @@ +/** + * Provides predicates related to capturing summary models of the Standard or a 3rd party library. + */ + +import csharp +import semmle.code.csharp.dataflow.TaintTracking +import semmle.code.csharp.dataflow.internal.DataFlowImplCommon +import semmle.code.csharp.dataflow.internal.DataFlowPrivate +import ModelGeneratorUtils + +Callable returnNodeEnclosingCallable(ReturnNodeExt ret) { result = getNodeEnclosingCallable(ret) } + +predicate isOwnInstanceAccessNode(ReturnNode node) { node.asExpr() instanceof ThisAccess } + +string qualifierString() { result = "Argument[Qualifier]" } diff --git a/csharp/ql/src/utils/model-generator/ModelGeneratorUtils.qll b/csharp/ql/src/utils/model-generator/ModelGeneratorUtils.qll new file mode 100644 index 00000000000..05e3d6cbf38 --- /dev/null +++ b/csharp/ql/src/utils/model-generator/ModelGeneratorUtils.qll @@ -0,0 +1,71 @@ +import ModelGeneratorUtilsSpecific + +/** + * Holds if data can flow from `node1` to `node2` either via a read or a write of an intermediate field `f`. + */ +predicate isRelevantTaintStep(DataFlow::Node node1, DataFlow::Node node2) { + exists(DataFlow::Content f | + readStep(node1, f, node2) and + if f instanceof DataFlow::FieldContent + then isRelevantType(f.(DataFlow::FieldContent).getField().getType()) + else + if f instanceof DataFlow::SyntheticFieldContent + then isRelevantType(f.(DataFlow::SyntheticFieldContent).getField().getType()) + else any() + ) + or + exists(DataFlow::Content f | storeStep(node1, f, node2) | containerContent(f)) +} + +/** + * Holds if content `c` is either a field or synthetic field of a relevant type + * or a container like content. + */ +predicate isRelevantContent(DataFlow::Content c) { + isRelevantType(c.(DataFlow::FieldContent).getField().getType()) or + isRelevantType(c.(DataFlow::SyntheticFieldContent).getField().getType()) or + containerContent(c) +} + +/** + * Gets the summary model for `api` with `input`, `output` and `kind`. + */ +bindingset[input, output, kind] +string asSummaryModel(TargetApi api, string input, string output, string kind) { + result = + asPartialModel(api) + input + ";" // + + output + ";" // + + kind +} + +/** + * Gets the value summary model for `api` with `input` and `output`. + */ +bindingset[input, output] +string asValueModel(TargetApi api, string input, string output) { + result = asSummaryModel(api, input, output, "value") +} + +/** + * Gets the taint summary model for `api` with `input` and `output`. + */ +bindingset[input, output] +string asTaintModel(TargetApi api, string input, string output) { + result = asSummaryModel(api, input, output, "taint") +} + +/** + * Gets the sink model for `api` with `input` and `kind`. + */ +bindingset[input, kind] +string asSinkModel(TargetApi api, string input, string kind) { + result = asPartialModel(api) + input + ";" + kind +} + +/** + * Gets the source model for `api` with `output` and `kind`. + */ +bindingset[output, kind] +string asSourceModel(TargetApi api, string output, string kind) { + result = asPartialModel(api) + output + ";" + kind +} diff --git a/csharp/ql/src/utils/model-generator/ModelGeneratorUtilsSpecific.qll b/csharp/ql/src/utils/model-generator/ModelGeneratorUtilsSpecific.qll new file mode 100644 index 00000000000..2df238e4ce6 --- /dev/null +++ b/csharp/ql/src/utils/model-generator/ModelGeneratorUtilsSpecific.qll @@ -0,0 +1,102 @@ +import csharp +import semmle.code.csharp.dataflow.internal.DataFlowPrivate +private import semmle.code.csharp.commons.Util +private import semmle.code.csharp.dataflow.internal.DataFlowImplCommon +private import semmle.code.csharp.dataflow.internal.DataFlowDispatch + +private predicate isRelevantForModels(Callable api) { not api instanceof MainMethod } + +/** + * A class of Callables that are relevant for generating summary, source and sinks models for. + * + * In the Standard library and 3rd party libraries it the Callables that can be called + * from outside the library itself. + */ +class TargetApi extends Callable { + TargetApi() { + [this.(Modifiable), this.(Accessor).getDeclaration()].isEffectivelyPublic() and + this.fromSource() and + isRelevantForModels(this) + } +} + +private string parameterQualifiedTypeNamesToString(TargetApi api) { + result = + concat(Parameter p, int i | + p = api.getParameter(i) + | + p.getType().getQualifiedName(), "," order by i + ) +} + +/** Holds if the summary should apply for all overrides of this. */ +private predicate isBaseCallableOrPrototype(TargetApi api) { + api.getDeclaringType() instanceof Interface + or + exists(Modifiable m | m = [api.(Modifiable), api.(Accessor).getDeclaration()] | + m.isAbstract() + or + api.getDeclaringType().(Modifiable).isAbstract() and m.(Virtualizable).isVirtual() + ) +} + +/** Gets a string representing whether the summary should apply for all overrides of this. */ +private string getCallableOverride(TargetApi api) { + if isBaseCallableOrPrototype(api) then result = "true" else result = "false" +} + +/** Computes the first 6 columns for CSV rows. */ +string asPartialModel(TargetApi api) { + exists(string namespace, string type | + api.getDeclaringType().hasQualifiedName(namespace, type) and + result = + namespace + ";" // + + type + ";" // + + getCallableOverride(api) + ";" // + + api.getName() + ";" // + + "(" + parameterQualifiedTypeNamesToString(api) + ")" // + + /* ext + */ ";" // + ) +} + +/** + * Holds for type `t` for fields that are relevant as an intermediate + * read or write step in the data flow analysis. + */ +predicate isRelevantType(Type t) { not t instanceof Enum } + +private predicate isPrimitiveTypeUsedForBulkData(Type t) { + t.getName().regexpMatch("byte|char|Byte|Char") +} + +private string parameterAccess(Parameter p) { + if + p.getType() instanceof ArrayType and + not isPrimitiveTypeUsedForBulkData(p.getType().(ArrayType).getElementType()) + then result = "Argument[" + p.getPosition() + "].Element" + else result = "Argument[" + p.getPosition() + "]" +} + +/** + * Gets the model string representation of the parameter node `p`. + */ +string parameterNodeAsInput(DataFlow::ParameterNode p) { + result = parameterAccess(p.asParameter()) + or + result = "Argument[Qualifier]" and p instanceof InstanceParameterNode +} + +/** + * Gets the model string represention of the the return node `node`. + */ +string returnNodeAsOutput(ReturnNodeExt node) { + if node.getKind() instanceof ValueReturnKind + then result = "ReturnValue" + else + exists(ParameterPosition pos | pos = node.getKind().(ParamUpdateReturnKind).getPosition() | + result = parameterAccess(node.getEnclosingCallable().getParameter(pos.getPosition())) + or + pos.isThisParameter() and + result = "Argument[Qualifier]" + ) +} diff --git a/csharp/ql/test/TestUtilities/InlineExpectationsTest.qll b/csharp/ql/test/TestUtilities/InlineExpectationsTest.qll index 7d605a491ee..a4d264b2703 100644 --- a/csharp/ql/test/TestUtilities/InlineExpectationsTest.qll +++ b/csharp/ql/test/TestUtilities/InlineExpectationsTest.qll @@ -124,7 +124,9 @@ abstract class InlineExpectationsTest extends string { abstract predicate hasActualResult(Location location, string element, string tag, string value); /** - * Like `hasActualResult`, but returns results that do not require a matching annotation. + * Holds if there is an optional result on the specified location. + * + * This is similar to `hasActualResult`, but returns results that do not require a matching annotation. * A failure will still arise if there is an annotation that does not match any results, but not vice versa. * Override this predicate to specify optional results. */ diff --git a/csharp/ql/test/experimental/ir/offbyone/OffByOneRA.ql b/csharp/ql/test/experimental/ir/offbyone/OffByOneRA.ql index 7518386e6d2..38386d47568 100644 --- a/csharp/ql/test/experimental/ir/offbyone/OffByOneRA.ql +++ b/csharp/ql/test/experimental/ir/offbyone/OffByOneRA.ql @@ -10,17 +10,17 @@ predicate boundedArrayAccess(ElementAccess aa, int k) { exists(Instruction index, Instruction usage, Bound b, int delta | ( // indexer access - usage.(CallInstruction).getAST() = aa + usage.(CallInstruction).getAst() = aa or // array access - usage.(PointerAddInstruction).getAST() = aa + usage.(PointerAddInstruction).getAst() = aa ) and usage.getAnOperand().getDef() = index and boundedInstruction(index, b, delta, true, _) | exists(PropertyAccess pa | k = delta and - b.getInstruction().getAST() = pa and + b.getInstruction().getAst() = pa and pa.getProperty().getName() = "Length" and pa.(QualifiableExpr).getQualifier().(VariableAccess).getTarget() = aa.getQualifier().(VariableAccess).getTarget() diff --git a/csharp/ql/test/library-tests/comments/Comments.ql b/csharp/ql/test/library-tests/comments/Comments.ql index 5ef8d3d75b9..84957e2252f 100644 --- a/csharp/ql/test/library-tests/comments/Comments.ql +++ b/csharp/ql/test/library-tests/comments/Comments.ql @@ -21,6 +21,8 @@ query predicate multilineComment( commentLine(c, l, numLines, text, rawText) } -query predicate xmlComment(CommentBlock c, XmlComment l, int numLines, string text, string rawText) { +query predicate xmlComment( + CommentBlock c, XmlCommentLine l, int numLines, string text, string rawText +) { commentLine(c, l, numLines, text, rawText) } diff --git a/csharp/ql/test/library-tests/structuralcomparison/StructuralComparison.cs b/csharp/ql/test/library-tests/structuralcomparison/StructuralComparison.cs new file mode 100644 index 00000000000..c27746a7765 --- /dev/null +++ b/csharp/ql/test/library-tests/structuralcomparison/StructuralComparison.cs @@ -0,0 +1,54 @@ +using System; + +public class Class +{ + private readonly int x = 0; + private readonly int y = 1; + + public int M0() => 0; + public int M1(int a) => a; + public int M2(int v1, int v2) => v1 + v2; + + + public void M3() + { + var z1 = x + y; + var z2 = x + y; + } + + public void M4() + { + var z3 = M1(x); + var z4 = M1(x); + var z5 = M1(y); + var z6 = M0(); + var z7 = M2(x, y) + M2(x, y); + M2(x, y); + M2(y, x); + M2(y, x); + } +} + +public class BaseClass +{ + public int Field; + public object Prop { get; set; } +} + +public class DerivedClass : BaseClass +{ + public void M4() + { + var x1 = base.Field; + var x2 = Field; + var x3 = this.Field; + } + + public void M5() + { + var y1 = base.Prop; + var y2 = Prop; + var y3 = this.Prop; + } +} + diff --git a/csharp/ql/test/library-tests/structuralcomparison/structuralComparison.expected b/csharp/ql/test/library-tests/structuralcomparison/structuralComparison.expected new file mode 100644 index 00000000000..cdabf17445b --- /dev/null +++ b/csharp/ql/test/library-tests/structuralcomparison/structuralComparison.expected @@ -0,0 +1,179 @@ +same +| StructuralComparison.cs:15:18:15:18 | access to field x | StructuralComparison.cs:16:18:16:18 | access to field x | +| StructuralComparison.cs:15:18:15:22 | ... + ... | StructuralComparison.cs:16:18:16:22 | ... + ... | +| StructuralComparison.cs:15:22:15:22 | access to field y | StructuralComparison.cs:16:22:16:22 | access to field y | +| StructuralComparison.cs:21:18:21:22 | call to method M1 | StructuralComparison.cs:22:18:22:22 | call to method M1 | +| StructuralComparison.cs:21:21:21:21 | access to field x | StructuralComparison.cs:22:21:22:21 | access to field x | +| StructuralComparison.cs:21:21:21:21 | access to field x | StructuralComparison.cs:25:21:25:21 | access to field x | +| StructuralComparison.cs:21:21:21:21 | access to field x | StructuralComparison.cs:25:32:25:32 | access to field x | +| StructuralComparison.cs:21:21:21:21 | access to field x | StructuralComparison.cs:26:12:26:12 | access to field x | +| StructuralComparison.cs:21:21:21:21 | access to field x | StructuralComparison.cs:27:15:27:15 | access to field x | +| StructuralComparison.cs:21:21:21:21 | access to field x | StructuralComparison.cs:28:15:28:15 | access to field x | +| StructuralComparison.cs:22:21:22:21 | access to field x | StructuralComparison.cs:25:21:25:21 | access to field x | +| StructuralComparison.cs:22:21:22:21 | access to field x | StructuralComparison.cs:25:32:25:32 | access to field x | +| StructuralComparison.cs:22:21:22:21 | access to field x | StructuralComparison.cs:26:12:26:12 | access to field x | +| StructuralComparison.cs:22:21:22:21 | access to field x | StructuralComparison.cs:27:15:27:15 | access to field x | +| StructuralComparison.cs:22:21:22:21 | access to field x | StructuralComparison.cs:28:15:28:15 | access to field x | +| StructuralComparison.cs:23:21:23:21 | access to field y | StructuralComparison.cs:25:24:25:24 | access to field y | +| StructuralComparison.cs:23:21:23:21 | access to field y | StructuralComparison.cs:25:35:25:35 | access to field y | +| StructuralComparison.cs:23:21:23:21 | access to field y | StructuralComparison.cs:26:15:26:15 | access to field y | +| StructuralComparison.cs:23:21:23:21 | access to field y | StructuralComparison.cs:27:12:27:12 | access to field y | +| StructuralComparison.cs:23:21:23:21 | access to field y | StructuralComparison.cs:28:12:28:12 | access to field y | +| StructuralComparison.cs:25:18:25:25 | call to method M2 | StructuralComparison.cs:25:29:25:36 | call to method M2 | +| StructuralComparison.cs:25:18:25:25 | call to method M2 | StructuralComparison.cs:26:9:26:16 | call to method M2 | +| StructuralComparison.cs:25:21:25:21 | access to field x | StructuralComparison.cs:25:32:25:32 | access to field x | +| StructuralComparison.cs:25:21:25:21 | access to field x | StructuralComparison.cs:26:12:26:12 | access to field x | +| StructuralComparison.cs:25:21:25:21 | access to field x | StructuralComparison.cs:27:15:27:15 | access to field x | +| StructuralComparison.cs:25:21:25:21 | access to field x | StructuralComparison.cs:28:15:28:15 | access to field x | +| StructuralComparison.cs:25:24:25:24 | access to field y | StructuralComparison.cs:25:35:25:35 | access to field y | +| StructuralComparison.cs:25:24:25:24 | access to field y | StructuralComparison.cs:26:15:26:15 | access to field y | +| StructuralComparison.cs:25:24:25:24 | access to field y | StructuralComparison.cs:27:12:27:12 | access to field y | +| StructuralComparison.cs:25:24:25:24 | access to field y | StructuralComparison.cs:28:12:28:12 | access to field y | +| StructuralComparison.cs:25:29:25:36 | call to method M2 | StructuralComparison.cs:26:9:26:16 | call to method M2 | +| StructuralComparison.cs:25:32:25:32 | access to field x | StructuralComparison.cs:26:12:26:12 | access to field x | +| StructuralComparison.cs:25:32:25:32 | access to field x | StructuralComparison.cs:27:15:27:15 | access to field x | +| StructuralComparison.cs:25:32:25:32 | access to field x | StructuralComparison.cs:28:15:28:15 | access to field x | +| StructuralComparison.cs:25:35:25:35 | access to field y | StructuralComparison.cs:26:15:26:15 | access to field y | +| StructuralComparison.cs:25:35:25:35 | access to field y | StructuralComparison.cs:27:12:27:12 | access to field y | +| StructuralComparison.cs:25:35:25:35 | access to field y | StructuralComparison.cs:28:12:28:12 | access to field y | +| StructuralComparison.cs:26:12:26:12 | access to field x | StructuralComparison.cs:27:15:27:15 | access to field x | +| StructuralComparison.cs:26:12:26:12 | access to field x | StructuralComparison.cs:28:15:28:15 | access to field x | +| StructuralComparison.cs:26:15:26:15 | access to field y | StructuralComparison.cs:27:12:27:12 | access to field y | +| StructuralComparison.cs:26:15:26:15 | access to field y | StructuralComparison.cs:28:12:28:12 | access to field y | +| StructuralComparison.cs:27:9:27:16 | call to method M2 | StructuralComparison.cs:28:9:28:16 | call to method M2 | +| StructuralComparison.cs:27:9:27:17 | ...; | StructuralComparison.cs:28:9:28:17 | ...; | +| StructuralComparison.cs:27:12:27:12 | access to field y | StructuralComparison.cs:28:12:28:12 | access to field y | +| StructuralComparison.cs:27:15:27:15 | access to field x | StructuralComparison.cs:28:15:28:15 | access to field x | +| StructuralComparison.cs:42:18:42:27 | access to field Field | StructuralComparison.cs:43:18:43:22 | access to field Field | +| StructuralComparison.cs:42:18:42:27 | access to field Field | StructuralComparison.cs:44:18:44:27 | access to field Field | +| StructuralComparison.cs:43:18:43:22 | access to field Field | StructuralComparison.cs:44:18:44:27 | access to field Field | +| StructuralComparison.cs:49:18:49:26 | access to property Prop | StructuralComparison.cs:50:18:50:21 | access to property Prop | +| StructuralComparison.cs:49:18:49:26 | access to property Prop | StructuralComparison.cs:51:18:51:26 | access to property Prop | +| StructuralComparison.cs:50:18:50:21 | access to property Prop | StructuralComparison.cs:51:18:51:26 | access to property Prop | +gvn +| StructuralComparison.cs:5:26:5:26 | access to field x | (kind:Expr(16),true,x) | +| StructuralComparison.cs:5:26:5:26 | this access | (kind:Expr(12)) | +| StructuralComparison.cs:5:26:5:30 | ... = ... | ((kind:Expr(16),true,x) :: (0 :: (kind:Expr(63)))) | +| StructuralComparison.cs:5:30:5:30 | 0 | 0 | +| StructuralComparison.cs:6:26:6:26 | access to field y | (kind:Expr(16),true,y) | +| StructuralComparison.cs:6:26:6:26 | this access | (kind:Expr(12)) | +| StructuralComparison.cs:6:26:6:30 | ... = ... | ((kind:Expr(16),true,y) :: (1 :: (kind:Expr(63)))) | +| StructuralComparison.cs:6:30:6:30 | 1 | 1 | +| StructuralComparison.cs:8:24:8:24 | 0 | 0 | +| StructuralComparison.cs:9:29:9:29 | access to parameter a | (kind:Expr(15),false,a) | +| StructuralComparison.cs:10:38:10:39 | access to parameter v1 | (kind:Expr(15),false,v1) | +| StructuralComparison.cs:10:38:10:44 | ... + ... | ((kind:Expr(15),false,v2) :: ((kind:Expr(15),false,v1) :: (kind:Expr(44)))) | +| StructuralComparison.cs:10:43:10:44 | access to parameter v2 | (kind:Expr(15),false,v2) | +| StructuralComparison.cs:14:5:17:5 | {...} | ((((kind:Expr(14),false,z2) :: (((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: (kind:Expr(44)))) :: (kind:Expr(83)))) :: (kind:Stmt(22))) :: ((((kind:Expr(14),false,z1) :: (((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: (kind:Expr(44)))) :: (kind:Expr(83)))) :: (kind:Stmt(22))) :: (kind:Stmt(1)))) | +| StructuralComparison.cs:15:9:15:23 | ... ...; | (((kind:Expr(14),false,z1) :: (((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: (kind:Expr(44)))) :: (kind:Expr(83)))) :: (kind:Stmt(22))) | +| StructuralComparison.cs:15:13:15:14 | access to local variable z1 | (kind:Expr(14),false,z1) | +| StructuralComparison.cs:15:13:15:22 | Int32 z1 = ... | ((kind:Expr(14),false,z1) :: (((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: (kind:Expr(44)))) :: (kind:Expr(83)))) | +| StructuralComparison.cs:15:18:15:18 | access to field x | (kind:Expr(16),true,x) | +| StructuralComparison.cs:15:18:15:18 | this access | (kind:Expr(12),false,Class) | +| StructuralComparison.cs:15:18:15:22 | ... + ... | ((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: (kind:Expr(44)))) | +| StructuralComparison.cs:15:22:15:22 | access to field y | (kind:Expr(16),true,y) | +| StructuralComparison.cs:15:22:15:22 | this access | (kind:Expr(12),false,Class) | +| StructuralComparison.cs:16:9:16:23 | ... ...; | (((kind:Expr(14),false,z2) :: (((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: (kind:Expr(44)))) :: (kind:Expr(83)))) :: (kind:Stmt(22))) | +| StructuralComparison.cs:16:13:16:14 | access to local variable z2 | (kind:Expr(14),false,z2) | +| StructuralComparison.cs:16:13:16:22 | Int32 z2 = ... | ((kind:Expr(14),false,z2) :: (((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: (kind:Expr(44)))) :: (kind:Expr(83)))) | +| StructuralComparison.cs:16:18:16:18 | access to field x | (kind:Expr(16),true,x) | +| StructuralComparison.cs:16:18:16:18 | this access | (kind:Expr(12),false,Class) | +| StructuralComparison.cs:16:18:16:22 | ... + ... | ((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: (kind:Expr(44)))) | +| StructuralComparison.cs:16:22:16:22 | access to field y | (kind:Expr(16),true,y) | +| StructuralComparison.cs:16:22:16:22 | this access | (kind:Expr(12),false,Class) | +| StructuralComparison.cs:20:5:29:5 | {...} | ((((kind:Expr(16),true,x) :: ((kind:Expr(16),true,y) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M2)))) :: (kind:Stmt(2))) :: ((((kind:Expr(16),true,x) :: ((kind:Expr(16),true,y) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M2)))) :: (kind:Stmt(2))) :: ((((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M2)))) :: (kind:Stmt(2))) :: ((((kind:Expr(14),false,z7) :: ((((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M2)))) :: (((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M2)))) :: (kind:Expr(44)))) :: (kind:Expr(83)))) :: (kind:Stmt(22))) :: ((((kind:Expr(14),false,z6) :: (((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M0)) :: (kind:Expr(83)))) :: (kind:Stmt(22))) :: ((((kind:Expr(14),false,z5) :: (((kind:Expr(16),true,y) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M1))) :: (kind:Expr(83)))) :: (kind:Stmt(22))) :: ((((kind:Expr(14),false,z4) :: (((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M1))) :: (kind:Expr(83)))) :: (kind:Stmt(22))) :: ((((kind:Expr(14),false,z3) :: (((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M1))) :: (kind:Expr(83)))) :: (kind:Stmt(22))) :: (kind:Stmt(1)))))))))) | +| StructuralComparison.cs:21:9:21:23 | ... ...; | (((kind:Expr(14),false,z3) :: (((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M1))) :: (kind:Expr(83)))) :: (kind:Stmt(22))) | +| StructuralComparison.cs:21:13:21:14 | access to local variable z3 | (kind:Expr(14),false,z3) | +| StructuralComparison.cs:21:13:21:22 | Int32 z3 = ... | ((kind:Expr(14),false,z3) :: (((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M1))) :: (kind:Expr(83)))) | +| StructuralComparison.cs:21:18:21:22 | call to method M1 | ((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M1))) | +| StructuralComparison.cs:21:18:21:22 | this access | (kind:Expr(12),false,Class) | +| StructuralComparison.cs:21:21:21:21 | access to field x | (kind:Expr(16),true,x) | +| StructuralComparison.cs:21:21:21:21 | this access | (kind:Expr(12),false,Class) | +| StructuralComparison.cs:22:9:22:23 | ... ...; | (((kind:Expr(14),false,z4) :: (((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M1))) :: (kind:Expr(83)))) :: (kind:Stmt(22))) | +| StructuralComparison.cs:22:13:22:14 | access to local variable z4 | (kind:Expr(14),false,z4) | +| StructuralComparison.cs:22:13:22:22 | Int32 z4 = ... | ((kind:Expr(14),false,z4) :: (((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M1))) :: (kind:Expr(83)))) | +| StructuralComparison.cs:22:18:22:22 | call to method M1 | ((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M1))) | +| StructuralComparison.cs:22:18:22:22 | this access | (kind:Expr(12),false,Class) | +| StructuralComparison.cs:22:21:22:21 | access to field x | (kind:Expr(16),true,x) | +| StructuralComparison.cs:22:21:22:21 | this access | (kind:Expr(12),false,Class) | +| StructuralComparison.cs:23:9:23:23 | ... ...; | (((kind:Expr(14),false,z5) :: (((kind:Expr(16),true,y) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M1))) :: (kind:Expr(83)))) :: (kind:Stmt(22))) | +| StructuralComparison.cs:23:13:23:14 | access to local variable z5 | (kind:Expr(14),false,z5) | +| StructuralComparison.cs:23:13:23:22 | Int32 z5 = ... | ((kind:Expr(14),false,z5) :: (((kind:Expr(16),true,y) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M1))) :: (kind:Expr(83)))) | +| StructuralComparison.cs:23:18:23:22 | call to method M1 | ((kind:Expr(16),true,y) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M1))) | +| StructuralComparison.cs:23:18:23:22 | this access | (kind:Expr(12),false,Class) | +| StructuralComparison.cs:23:21:23:21 | access to field y | (kind:Expr(16),true,y) | +| StructuralComparison.cs:23:21:23:21 | this access | (kind:Expr(12),false,Class) | +| StructuralComparison.cs:24:9:24:22 | ... ...; | (((kind:Expr(14),false,z6) :: (((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M0)) :: (kind:Expr(83)))) :: (kind:Stmt(22))) | +| StructuralComparison.cs:24:13:24:14 | access to local variable z6 | (kind:Expr(14),false,z6) | +| StructuralComparison.cs:24:13:24:21 | Int32 z6 = ... | ((kind:Expr(14),false,z6) :: (((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M0)) :: (kind:Expr(83)))) | +| StructuralComparison.cs:24:18:24:21 | call to method M0 | ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M0)) | +| StructuralComparison.cs:24:18:24:21 | this access | (kind:Expr(12),false,Class) | +| StructuralComparison.cs:25:9:25:37 | ... ...; | (((kind:Expr(14),false,z7) :: ((((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M2)))) :: (((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M2)))) :: (kind:Expr(44)))) :: (kind:Expr(83)))) :: (kind:Stmt(22))) | +| StructuralComparison.cs:25:13:25:14 | access to local variable z7 | (kind:Expr(14),false,z7) | +| StructuralComparison.cs:25:13:25:36 | Int32 z7 = ... | ((kind:Expr(14),false,z7) :: ((((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M2)))) :: (((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M2)))) :: (kind:Expr(44)))) :: (kind:Expr(83)))) | +| StructuralComparison.cs:25:18:25:25 | call to method M2 | ((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M2)))) | +| StructuralComparison.cs:25:18:25:25 | this access | (kind:Expr(12),false,Class) | +| StructuralComparison.cs:25:18:25:36 | ... + ... | (((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M2)))) :: (((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M2)))) :: (kind:Expr(44)))) | +| StructuralComparison.cs:25:21:25:21 | access to field x | (kind:Expr(16),true,x) | +| StructuralComparison.cs:25:21:25:21 | this access | (kind:Expr(12),false,Class) | +| StructuralComparison.cs:25:24:25:24 | access to field y | (kind:Expr(16),true,y) | +| StructuralComparison.cs:25:24:25:24 | this access | (kind:Expr(12),false,Class) | +| StructuralComparison.cs:25:29:25:36 | call to method M2 | ((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M2)))) | +| StructuralComparison.cs:25:29:25:36 | this access | (kind:Expr(12),false,Class) | +| StructuralComparison.cs:25:32:25:32 | access to field x | (kind:Expr(16),true,x) | +| StructuralComparison.cs:25:32:25:32 | this access | (kind:Expr(12),false,Class) | +| StructuralComparison.cs:25:35:25:35 | access to field y | (kind:Expr(16),true,y) | +| StructuralComparison.cs:25:35:25:35 | this access | (kind:Expr(12),false,Class) | +| StructuralComparison.cs:26:9:26:16 | call to method M2 | ((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M2)))) | +| StructuralComparison.cs:26:9:26:16 | this access | (kind:Expr(12),false,Class) | +| StructuralComparison.cs:26:9:26:17 | ...; | (((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M2)))) :: (kind:Stmt(2))) | +| StructuralComparison.cs:26:12:26:12 | access to field x | (kind:Expr(16),true,x) | +| StructuralComparison.cs:26:12:26:12 | this access | (kind:Expr(12),false,Class) | +| StructuralComparison.cs:26:15:26:15 | access to field y | (kind:Expr(16),true,y) | +| StructuralComparison.cs:26:15:26:15 | this access | (kind:Expr(12),false,Class) | +| StructuralComparison.cs:27:9:27:16 | call to method M2 | ((kind:Expr(16),true,x) :: ((kind:Expr(16),true,y) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M2)))) | +| StructuralComparison.cs:27:9:27:16 | this access | (kind:Expr(12),false,Class) | +| StructuralComparison.cs:27:9:27:17 | ...; | (((kind:Expr(16),true,x) :: ((kind:Expr(16),true,y) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M2)))) :: (kind:Stmt(2))) | +| StructuralComparison.cs:27:12:27:12 | access to field y | (kind:Expr(16),true,y) | +| StructuralComparison.cs:27:12:27:12 | this access | (kind:Expr(12),false,Class) | +| StructuralComparison.cs:27:15:27:15 | access to field x | (kind:Expr(16),true,x) | +| StructuralComparison.cs:27:15:27:15 | this access | (kind:Expr(12),false,Class) | +| StructuralComparison.cs:28:9:28:16 | call to method M2 | ((kind:Expr(16),true,x) :: ((kind:Expr(16),true,y) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M2)))) | +| StructuralComparison.cs:28:9:28:16 | this access | (kind:Expr(12),false,Class) | +| StructuralComparison.cs:28:9:28:17 | ...; | (((kind:Expr(16),true,x) :: ((kind:Expr(16),true,y) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M2)))) :: (kind:Stmt(2))) | +| StructuralComparison.cs:28:12:28:12 | access to field y | (kind:Expr(16),true,y) | +| StructuralComparison.cs:28:12:28:12 | this access | (kind:Expr(12),false,Class) | +| StructuralComparison.cs:28:15:28:15 | access to field x | (kind:Expr(16),true,x) | +| StructuralComparison.cs:28:15:28:15 | this access | (kind:Expr(12),false,Class) | +| StructuralComparison.cs:41:5:45:5 | {...} | ((((kind:Expr(14),false,x3) :: ((kind:Expr(16),true,Field) :: (kind:Expr(83)))) :: (kind:Stmt(22))) :: ((((kind:Expr(14),false,x2) :: ((kind:Expr(16),true,Field) :: (kind:Expr(83)))) :: (kind:Stmt(22))) :: ((((kind:Expr(14),false,x1) :: ((kind:Expr(16),true,Field) :: (kind:Expr(83)))) :: (kind:Stmt(22))) :: (kind:Stmt(1))))) | +| StructuralComparison.cs:42:9:42:28 | ... ...; | (((kind:Expr(14),false,x1) :: ((kind:Expr(16),true,Field) :: (kind:Expr(83)))) :: (kind:Stmt(22))) | +| StructuralComparison.cs:42:13:42:14 | access to local variable x1 | (kind:Expr(14),false,x1) | +| StructuralComparison.cs:42:13:42:27 | Int32 x1 = ... | ((kind:Expr(14),false,x1) :: ((kind:Expr(16),true,Field) :: (kind:Expr(83)))) | +| StructuralComparison.cs:42:18:42:21 | base access | (kind:Expr(13),false,BaseClass) | +| StructuralComparison.cs:42:18:42:27 | access to field Field | (kind:Expr(16),true,Field) | +| StructuralComparison.cs:43:9:43:23 | ... ...; | (((kind:Expr(14),false,x2) :: ((kind:Expr(16),true,Field) :: (kind:Expr(83)))) :: (kind:Stmt(22))) | +| StructuralComparison.cs:43:13:43:14 | access to local variable x2 | (kind:Expr(14),false,x2) | +| StructuralComparison.cs:43:13:43:22 | Int32 x2 = ... | ((kind:Expr(14),false,x2) :: ((kind:Expr(16),true,Field) :: (kind:Expr(83)))) | +| StructuralComparison.cs:43:18:43:22 | access to field Field | (kind:Expr(16),true,Field) | +| StructuralComparison.cs:43:18:43:22 | this access | (kind:Expr(12),false,DerivedClass) | +| StructuralComparison.cs:44:9:44:28 | ... ...; | (((kind:Expr(14),false,x3) :: ((kind:Expr(16),true,Field) :: (kind:Expr(83)))) :: (kind:Stmt(22))) | +| StructuralComparison.cs:44:13:44:14 | access to local variable x3 | (kind:Expr(14),false,x3) | +| StructuralComparison.cs:44:13:44:27 | Int32 x3 = ... | ((kind:Expr(14),false,x3) :: ((kind:Expr(16),true,Field) :: (kind:Expr(83)))) | +| StructuralComparison.cs:44:18:44:21 | this access | (kind:Expr(12),false,DerivedClass) | +| StructuralComparison.cs:44:18:44:27 | access to field Field | (kind:Expr(16),true,Field) | +| StructuralComparison.cs:48:5:52:5 | {...} | ((((kind:Expr(14),false,y3) :: ((kind:Expr(17),true,Prop) :: (kind:Expr(83)))) :: (kind:Stmt(22))) :: ((((kind:Expr(14),false,y2) :: ((kind:Expr(17),true,Prop) :: (kind:Expr(83)))) :: (kind:Stmt(22))) :: ((((kind:Expr(14),false,y1) :: ((kind:Expr(17),true,Prop) :: (kind:Expr(83)))) :: (kind:Stmt(22))) :: (kind:Stmt(1))))) | +| StructuralComparison.cs:49:9:49:27 | ... ...; | (((kind:Expr(14),false,y1) :: ((kind:Expr(17),true,Prop) :: (kind:Expr(83)))) :: (kind:Stmt(22))) | +| StructuralComparison.cs:49:13:49:14 | access to local variable y1 | (kind:Expr(14),false,y1) | +| StructuralComparison.cs:49:13:49:26 | Object y1 = ... | ((kind:Expr(14),false,y1) :: ((kind:Expr(17),true,Prop) :: (kind:Expr(83)))) | +| StructuralComparison.cs:49:18:49:21 | base access | (kind:Expr(13),false,BaseClass) | +| StructuralComparison.cs:49:18:49:26 | access to property Prop | (kind:Expr(17),true,Prop) | +| StructuralComparison.cs:50:9:50:22 | ... ...; | (((kind:Expr(14),false,y2) :: ((kind:Expr(17),true,Prop) :: (kind:Expr(83)))) :: (kind:Stmt(22))) | +| StructuralComparison.cs:50:13:50:14 | access to local variable y2 | (kind:Expr(14),false,y2) | +| StructuralComparison.cs:50:13:50:21 | Object y2 = ... | ((kind:Expr(14),false,y2) :: ((kind:Expr(17),true,Prop) :: (kind:Expr(83)))) | +| StructuralComparison.cs:50:18:50:21 | access to property Prop | (kind:Expr(17),true,Prop) | +| StructuralComparison.cs:50:18:50:21 | this access | (kind:Expr(12),false,DerivedClass) | +| StructuralComparison.cs:51:9:51:27 | ... ...; | (((kind:Expr(14),false,y3) :: ((kind:Expr(17),true,Prop) :: (kind:Expr(83)))) :: (kind:Stmt(22))) | +| StructuralComparison.cs:51:13:51:14 | access to local variable y3 | (kind:Expr(14),false,y3) | +| StructuralComparison.cs:51:13:51:26 | Object y3 = ... | ((kind:Expr(14),false,y3) :: ((kind:Expr(17),true,Prop) :: (kind:Expr(83)))) | +| StructuralComparison.cs:51:18:51:21 | this access | (kind:Expr(12),false,DerivedClass) | +| StructuralComparison.cs:51:18:51:26 | access to property Prop | (kind:Expr(17),true,Prop) | diff --git a/csharp/ql/test/library-tests/structuralcomparison/structuralComparison.ql b/csharp/ql/test/library-tests/structuralcomparison/structuralComparison.ql new file mode 100644 index 00000000000..fa94374a1dc --- /dev/null +++ b/csharp/ql/test/library-tests/structuralcomparison/structuralComparison.ql @@ -0,0 +1,34 @@ +import csharp +import semmle.code.csharp.commons.StructuralComparison + +private class StructuralComparisonTest extends StructuralComparisonConfiguration { + StructuralComparisonTest() { this = "StructuralComparisonTest" } + + /** + * All pairs of controls flow elements found in the source and within the same + * enclosing callable excluding all instances of `ThisAccess` to reduce the size + * of the output. + */ + override predicate candidate(ControlFlowElement e1, ControlFlowElement e2) { + e1.fromSource() and + e2.fromSource() and + e1 != e2 and + e1.getEnclosingCallable() = e2.getEnclosingCallable() and + not e1 instanceof ThisAccess + } +} + +query predicate same(ControlFlowElement e1, ControlFlowElement e2) { + exists(StructuralComparisonTest sct, Location l1, Location l2 | + sct.same(e1, e2) and + l1 = e1.getLocation() and + l2 = e2.getLocation() and + ( + l1.getStartLine() < l2.getStartLine() + or + l1.getStartLine() = l2.getStartLine() and l1.getStartColumn() < l2.getStartColumn() + ) + ) +} + +query predicate gvn(ControlFlowElement e, Gvn gvn) { gvn = toGvn(e) and e.fromSource() } diff --git a/csharp/ql/test/shared/FlowSummaries.qll b/csharp/ql/test/shared/FlowSummaries.qll index 6afa16a744a..f2cdea8a99f 100644 --- a/csharp/ql/test/shared/FlowSummaries.qll +++ b/csharp/ql/test/shared/FlowSummaries.qll @@ -27,7 +27,7 @@ abstract class IncludeSummarizedCallable extends RelevantSummarizedCallable { ) } - /** Gets a string representing, whether the summary should apply for all overrides of this. */ + /** Gets a string representing whether the summary should apply for all overrides of this. */ private string getCallableOverride() { if this.isBaseCallableOrPrototype() then result = "true" else result = "false" } diff --git a/csharp/ql/test/utils/model-generator/CaptureSummaryModels.expected b/csharp/ql/test/utils/model-generator/CaptureSummaryModels.expected new file mode 100644 index 00000000000..38c6c527247 --- /dev/null +++ b/csharp/ql/test/utils/model-generator/CaptureSummaryModels.expected @@ -0,0 +1,11 @@ +| Summaries;BasicFlow;false;AssignFieldToArray;(System.Object[]);Argument[Qualifier];Argument[0].Element;taint | +| Summaries;BasicFlow;false;AssignToArray;(System.Int32,System.Int32[]);Argument[0];Argument[1].Element;taint | +| Summaries;BasicFlow;false;ReturnArrayElement;(System.Int32[]);Argument[0].Element;ReturnValue;taint | +| Summaries;BasicFlow;false;ReturnField;();Argument[Qualifier];ReturnValue;taint | +| Summaries;BasicFlow;false;ReturnParam0;(System.String,System.Object);Argument[0];ReturnValue;taint | +| Summaries;BasicFlow;false;ReturnParam1;(System.String,System.Object);Argument[1];ReturnValue;taint | +| Summaries;BasicFlow;false;ReturnParamMultiple;(System.Object,System.Object);Argument[0];ReturnValue;taint | +| Summaries;BasicFlow;false;ReturnParamMultiple;(System.Object,System.Object);Argument[1];ReturnValue;taint | +| Summaries;BasicFlow;false;ReturnSubstring;(System.String);Argument[0];ReturnValue;taint | +| Summaries;BasicFlow;false;ReturnThis;(System.Object);Argument[Qualifier];ReturnValue;value | +| Summaries;BasicFlow;false;SetField;(System.String);Argument[0];Argument[Qualifier];taint | diff --git a/csharp/ql/test/utils/model-generator/CaptureSummaryModels.qlref b/csharp/ql/test/utils/model-generator/CaptureSummaryModels.qlref new file mode 100644 index 00000000000..1ebf2afb19b --- /dev/null +++ b/csharp/ql/test/utils/model-generator/CaptureSummaryModels.qlref @@ -0,0 +1 @@ +utils/model-generator/CaptureSummaryModels.ql \ No newline at end of file diff --git a/csharp/ql/test/utils/model-generator/Summaries.cs b/csharp/ql/test/utils/model-generator/Summaries.cs new file mode 100644 index 00000000000..7d47ae694bb --- /dev/null +++ b/csharp/ql/test/utils/model-generator/Summaries.cs @@ -0,0 +1,58 @@ +using System; + +namespace Summaries; + +public class BasicFlow +{ + private string tainted; + + public BasicFlow ReturnThis(object input) + { + return this; + } + + public string ReturnParam0(string input0, object input1) + { + return input0; + } + + public object ReturnParam1(string input0, object input1) + { + return input1; + } + + public object ReturnParamMultiple(object input0, object input1) + { + return (System.DateTime.Now.DayOfWeek == System.DayOfWeek.Monday) ? input0 : input1; + } + + public string ReturnSubstring(string s) + { + return s.Substring(0, 1); + } + + public int ReturnArrayElement(int[] input) + { + return input[0]; + } + + public void AssignToArray(int data, int[] target) + { + target[0] = data; + } + + public void SetField(string s) + { + tainted = s; + } + + public string ReturnField() + { + return tainted; + } + + public void AssignFieldToArray(object[] target) + { + target[0] = tainted; + } +} diff --git a/docs/codeql/support/reusables/frameworks.rst b/docs/codeql/support/reusables/frameworks.rst index c214eb926ce..93280c6732a 100644 --- a/docs/codeql/support/reusables/frameworks.rst +++ b/docs/codeql/support/reusables/frameworks.rst @@ -173,7 +173,12 @@ Python built-in support starlette, Asynchronous Server Gateway Interface (ASGI) python-ldap, Lightweight Directory Access Protocol (LDAP) ldap3, Lightweight Directory Access Protocol (LDAP) + httpx, HTTP client + pycurl, HTTP client requests, HTTP client + urllib, HTTP client + urllib2, HTTP client + urllib3, HTTP client dill, Serialization PyYAML, Serialization ruamel.yaml, Serialization @@ -206,5 +211,6 @@ Python built-in support pycryptodomex, Cryptography library rsa, Cryptography library MarkupSafe, Escaping Library + libtaxii, TAXII utility library libxml2, XML processing library lxml, XML processing library diff --git a/java/documentation/library-coverage/coverage.csv b/java/documentation/library-coverage/coverage.csv index 13287d2972c..09e7e73293a 100644 --- a/java/documentation/library-coverage/coverage.csv +++ b/java/documentation/library-coverage/coverage.csv @@ -1,112 +1,116 @@ -package,sink,source,summary,sink:bean-validation,sink:create-file,sink:groovy,sink:header-splitting,sink:information-leak,sink:intent-start,sink:jexl,sink:jndi-injection,sink:ldap,sink:logging,sink:mvel,sink:ognl-injection,sink:open-url,sink:pending-intent-sent,sink:set-hostname-verifier,sink:sql,sink:url-open-stream,sink:url-redirect,sink:write-file,sink:xpath,sink:xslt,sink:xss,source:android-widget,source:contentprovider,source:remote,summary:taint,summary:value -android.app,16,,103,,,,,,7,,,,,,,,9,,,,,,,,,,,,18,85 -android.content,24,27,100,,,,,,16,,,,,,,,,,8,,,,,,,,27,,31,69 -android.database,59,,30,,,,,,,,,,,,,,,,59,,,,,,,,,,30, -android.net,,,60,,,,,,,,,,,,,,,,,,,,,,,,,,45,15 -android.os,,,122,,,,,,,,,,,,,,,,,,,,,,,,,,41,81 -android.util,6,16,,,,,,,,,,,6,,,,,,,,,,,,,,,16,, -android.webkit,3,2,,,,,,,,,,,,,,,,,,,,,,,3,,,2,, -android.widget,,1,1,,,,,,,,,,,,,,,,,,,,,,,1,,,1, -androidx.slice,2,5,88,,,,,,,,,,,,,,2,,,,,,,,,,5,,27,61 -cn.hutool.core.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,1, -com.esotericsoftware.kryo.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,1, -com.esotericsoftware.kryo5.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,1, -com.fasterxml.jackson.core,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,1, -com.fasterxml.jackson.databind,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,6, -com.google.common.base,,,85,,,,,,,,,,,,,,,,,,,,,,,,,,62,23 -com.google.common.cache,,,17,,,,,,,,,,,,,,,,,,,,,,,,,,,17 -com.google.common.collect,,,553,,,,,,,,,,,,,,,,,,,,,,,,,,2,551 -com.google.common.flogger,29,,,,,,,,,,,,29,,,,,,,,,,,,,,,,, -com.google.common.io,6,,73,,,,,,,,,,,,,,,,,6,,,,,,,,,72,1 -com.opensymphony.xwork2.ognl,3,,,,,,,,,,,,,,3,,,,,,,,,,,,,,, -com.unboundid.ldap.sdk,17,,,,,,,,,,,17,,,,,,,,,,,,,,,,,, -flexjson,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,1 -groovy.lang,26,,,,,26,,,,,,,,,,,,,,,,,,,,,,,, -groovy.util,5,,,,,5,,,,,,,,,,,,,,,,,,,,,,,, -jakarta.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,2,,,7,, -jakarta.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,100,23 -jakarta.ws.rs.client,1,,,,,,,,,,,,,,,1,,,,,,,,,,,,,, -jakarta.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,9,, -jakarta.ws.rs.core,2,,149,,,,,,,,,,,,,,,,,,2,,,,,,,,94,55 -java.beans,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,1, -java.io,37,,31,,15,,,,,,,,,,,,,,,,,22,,,,,,,31, -java.lang,8,,58,,,,,,,,,,8,,,,,,,,,,,,,,,,46,12 -java.net,10,3,7,,,,,,,,,,,,,10,,,,,,,,,,,,3,7, -java.nio,15,,6,,13,,,,,,,,,,,,,,,,,2,,,,,,,6, -java.sql,7,,,,,,,,,,,,,,,,,,7,,,,,,,,,,, -java.util,34,,438,,,,,,,,,,34,,,,,,,,,,,,,,,,24,414 -javax.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,2,,,7,, -javax.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,100,23 -javax.management.remote,2,,,,,,,,,,2,,,,,,,,,,,,,,,,,,, -javax.naming,7,,,,,,,,,,6,1,,,,,,,,,,,,,,,,,, -javax.net.ssl,2,,,,,,,,,,,,,,,,,2,,,,,,,,,,,, -javax.script,1,,,,,,,,,,,,,1,,,,,,,,,,,,,,,, -javax.servlet,4,21,2,,,,3,1,,,,,,,,,,,,,,,,,,,,21,2, -javax.validation,1,1,,1,,,,,,,,,,,,,,,,,,,,,,,,1,, -javax.ws.rs.client,1,,,,,,,,,,,,,,,1,,,,,,,,,,,,,, -javax.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,9,, -javax.ws.rs.core,3,,149,,,,1,,,,,,,,,,,,,,2,,,,,,,,94,55 -javax.xml.transform,1,,6,,,,,,,,,,,,,,,,,,,,,1,,,,,6, -javax.xml.xpath,3,,,,,,,,,,,,,,,,,,,,,,3,,,,,,, -jodd.json,,,10,,,,,,,,,,,,,,,,,,,,,,,,,,,10 -net.sf.saxon.s9api,5,,,,,,,,,,,,,,,,,,,,,,,5,,,,,, -ognl,6,,,,,,,,,,,,,,6,,,,,,,,,,,,,,, -org.apache.commons.codec,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,6, -org.apache.commons.collections,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,17,783 -org.apache.commons.collections4,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,17,783 -org.apache.commons.io,93,2,565,,78,,,,,,,,,,,15,,,,,,,,,,,,2,551,14 -org.apache.commons.jexl2,15,,,,,,,,,15,,,,,,,,,,,,,,,,,,,, -org.apache.commons.jexl3,15,,,,,,,,,15,,,,,,,,,,,,,,,,,,,, -org.apache.commons.lang3,,,424,,,,,,,,,,,,,,,,,,,,,,,,,,293,131 -org.apache.commons.logging,6,,,,,,,,,,,,6,,,,,,,,,,,,,,,,, -org.apache.commons.ognl,6,,,,,,,,,,,,,,6,,,,,,,,,,,,,,, -org.apache.commons.text,,,272,,,,,,,,,,,,,,,,,,,,,,,,,,220,52 -org.apache.directory.ldap.client.api,1,,,,,,,,,,,1,,,,,,,,,,,,,,,,,, -org.apache.hc.core5.function,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,1, -org.apache.hc.core5.http,1,2,39,,,,,,,,,,,,,,,,,,,,,,1,,,2,39, -org.apache.hc.core5.net,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,2, -org.apache.hc.core5.util,,,24,,,,,,,,,,,,,,,,,,,,,,,,,,18,6 -org.apache.http,27,3,70,,,,,,,,,,,,,25,,,,,,,,,2,,,3,62,8 -org.apache.ibatis.jdbc,6,,,,,,,,,,,,,,,,,,6,,,,,,,,,,, -org.apache.log4j,11,,,,,,,,,,,,11,,,,,,,,,,,,,,,,, -org.apache.logging.log4j,359,,8,,,,,,,,,,359,,,,,,,,,,,,,,,,4,4 -org.apache.shiro.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,1, -org.apache.shiro.jndi,1,,,,,,,,,,1,,,,,,,,,,,,,,,,,,, -org.codehaus.groovy.control,1,,,,,1,,,,,,,,,,,,,,,,,,,,,,,, -org.dom4j,20,,,,,,,,,,,,,,,,,,,,,,20,,,,,,, -org.hibernate,7,,,,,,,,,,,,,,,,,,7,,,,,,,,,,, -org.jboss.logging,324,,,,,,,,,,,,324,,,,,,,,,,,,,,,,, -org.jooq,1,,,,,,,,,,,,,,,,,,1,,,,,,,,,,, -org.json,,,236,,,,,,,,,,,,,,,,,,,,,,,,,,198,38 -org.mvel2,16,,,,,,,,,,,,,16,,,,,,,,,,,,,,,, -org.scijava.log,13,,,,,,,,,,,,13,,,,,,,,,,,,,,,,, -org.slf4j,55,,6,,,,,,,,,,55,,,,,,,,,,,,,,,,2,4 -org.springframework.beans,,,26,,,,,,,,,,,,,,,,,,,,,,,,,,,26 -org.springframework.cache,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,13 -org.springframework.context,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,3, -org.springframework.http,14,,70,,,,,,,,,,,,,14,,,,,,,,,,,,,60,10 -org.springframework.jdbc.core,10,,,,,,,,,,,,,,,,,,10,,,,,,,,,,, -org.springframework.jdbc.object,9,,,,,,,,,,,,,,,,,,9,,,,,,,,,,, -org.springframework.jndi,1,,,,,,,,,,1,,,,,,,,,,,,,,,,,,, -org.springframework.ldap,47,,,,,,,,,,33,14,,,,,,,,,,,,,,,,,, -org.springframework.security.web.savedrequest,,6,,,,,,,,,,,,,,,,,,,,,,,,,,6,, -org.springframework.ui,,,32,,,,,,,,,,,,,,,,,,,,,,,,,,,32 -org.springframework.util,,,139,,,,,,,,,,,,,,,,,,,,,,,,,,87,52 -org.springframework.validation,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,13, -org.springframework.web.client,13,3,,,,,,,,,,,,,,13,,,,,,,,,,,,3,, -org.springframework.web.context.request,,8,,,,,,,,,,,,,,,,,,,,,,,,,,8,, -org.springframework.web.multipart,,12,13,,,,,,,,,,,,,,,,,,,,,,,,,12,13, -org.springframework.web.reactive.function.client,2,,,,,,,,,,,,,,,2,,,,,,,,,,,,,, -org.springframework.web.util,,,163,,,,,,,,,,,,,,,,,,,,,,,,,,138,25 -org.xml.sax,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,1, -org.xmlpull.v1,,3,,,,,,,,,,,,,,,,,,,,,,,,,,3,, -play.mvc,,4,,,,,,,,,,,,,,,,,,,,,,,,,,4,, -ratpack.core.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,3, -ratpack.core.handling,,6,4,,,,,,,,,,,,,,,,,,,,,,,,,6,4, -ratpack.core.http,,10,10,,,,,,,,,,,,,,,,,,,,,,,,,10,10, -ratpack.exec,,,48,,,,,,,,,,,,,,,,,,,,,,,,,,,48 -ratpack.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,3, -ratpack.func,,,35,,,,,,,,,,,,,,,,,,,,,,,,,,,35 -ratpack.handling,,6,4,,,,,,,,,,,,,,,,,,,,,,,,,6,4, -ratpack.http,,10,10,,,,,,,,,,,,,,,,,,,,,,,,,10,10, -ratpack.util,,,35,,,,,,,,,,,,,,,,,,,,,,,,,,,35 +package,sink,source,summary,sink:bean-validation,sink:create-file,sink:groovy,sink:header-splitting,sink:information-leak,sink:intent-start,sink:jdbc-url,sink:jexl,sink:jndi-injection,sink:ldap,sink:logging,sink:mvel,sink:ognl-injection,sink:open-url,sink:pending-intent-sent,sink:set-hostname-verifier,sink:sql,sink:url-open-stream,sink:url-redirect,sink:write-file,sink:xpath,sink:xslt,sink:xss,source:android-widget,source:contentprovider,source:remote,summary:taint,summary:value +android.app,16,,103,,,,,,7,,,,,,,,,9,,,,,,,,,,,,18,85 +android.content,24,27,100,,,,,,16,,,,,,,,,,,8,,,,,,,,27,,31,69 +android.database,59,,30,,,,,,,,,,,,,,,,,59,,,,,,,,,,30, +android.net,,,60,,,,,,,,,,,,,,,,,,,,,,,,,,,45,15 +android.os,,,122,,,,,,,,,,,,,,,,,,,,,,,,,,,41,81 +android.util,6,16,,,,,,,,,,,,6,,,,,,,,,,,,,,,16,, +android.webkit,3,2,,,,,,,,,,,,,,,,,,,,,,,,3,,,2,, +android.widget,,1,1,,,,,,,,,,,,,,,,,,,,,,,,1,,,1, +androidx.slice,2,5,88,,,,,,,,,,,,,,,2,,,,,,,,,,5,,27,61 +cn.hutool.core.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +com.esotericsoftware.kryo.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +com.esotericsoftware.kryo5.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +com.fasterxml.jackson.core,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +com.fasterxml.jackson.databind,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,6, +com.google.common.base,,,85,,,,,,,,,,,,,,,,,,,,,,,,,,,62,23 +com.google.common.cache,,,17,,,,,,,,,,,,,,,,,,,,,,,,,,,,17 +com.google.common.collect,,,553,,,,,,,,,,,,,,,,,,,,,,,,,,,2,551 +com.google.common.flogger,29,,,,,,,,,,,,,29,,,,,,,,,,,,,,,,, +com.google.common.io,6,,73,,,,,,,,,,,,,,,,,,6,,,,,,,,,72,1 +com.opensymphony.xwork2.ognl,3,,,,,,,,,,,,,,,3,,,,,,,,,,,,,,, +com.unboundid.ldap.sdk,17,,,,,,,,,,,,17,,,,,,,,,,,,,,,,,, +com.zaxxer.hikari,2,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,, +flexjson,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,1 +groovy.lang,26,,,,,26,,,,,,,,,,,,,,,,,,,,,,,,, +groovy.util,5,,,,,5,,,,,,,,,,,,,,,,,,,,,,,,, +jakarta.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,,2,,,7,, +jakarta.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23 +jakarta.ws.rs.client,1,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,, +jakarta.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,9,, +jakarta.ws.rs.core,2,,149,,,,,,,,,,,,,,,,,,,2,,,,,,,,94,55 +java.beans,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +java.io,37,,31,,15,,,,,,,,,,,,,,,,,,22,,,,,,,31, +java.lang,8,,58,,,,,,,,,,,8,,,,,,,,,,,,,,,,46,12 +java.net,10,3,7,,,,,,,,,,,,,,10,,,,,,,,,,,,3,7, +java.nio,15,,6,,13,,,,,,,,,,,,,,,,,,2,,,,,,,6, +java.sql,11,,,,,,,,,4,,,,,,,,,,7,,,,,,,,,,, +java.util,34,,438,,,,,,,,,,,34,,,,,,,,,,,,,,,,24,414 +javax.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,,2,,,7,, +javax.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23 +javax.management.remote,2,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,, +javax.naming,7,,,,,,,,,,,6,1,,,,,,,,,,,,,,,,,, +javax.net.ssl,2,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,, +javax.script,1,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,, +javax.servlet,4,21,2,,,,3,1,,,,,,,,,,,,,,,,,,,,,21,2, +javax.validation,1,1,,1,,,,,,,,,,,,,,,,,,,,,,,,,1,, +javax.ws.rs.client,1,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,, +javax.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,9,, +javax.ws.rs.core,3,,149,,,,1,,,,,,,,,,,,,,,2,,,,,,,,94,55 +javax.xml.transform,1,,6,,,,,,,,,,,,,,,,,,,,,,1,,,,,6, +javax.xml.xpath,3,,,,,,,,,,,,,,,,,,,,,,,3,,,,,,, +jodd.json,,,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,10 +net.sf.saxon.s9api,5,,,,,,,,,,,,,,,,,,,,,,,,5,,,,,, +ognl,6,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,, +org.apache.commons.codec,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,6, +org.apache.commons.collections,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783 +org.apache.commons.collections4,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783 +org.apache.commons.io,93,2,565,,78,,,,,,,,,,,,15,,,,,,,,,,,,2,551,14 +org.apache.commons.jexl2,15,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,, +org.apache.commons.jexl3,15,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,, +org.apache.commons.lang3,,,424,,,,,,,,,,,,,,,,,,,,,,,,,,,293,131 +org.apache.commons.logging,6,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,, +org.apache.commons.ognl,6,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,, +org.apache.commons.text,,,272,,,,,,,,,,,,,,,,,,,,,,,,,,,220,52 +org.apache.directory.ldap.client.api,1,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,, +org.apache.hc.core5.function,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +org.apache.hc.core5.http,1,2,39,,,,,,,,,,,,,,,,,,,,,,,1,,,2,39, +org.apache.hc.core5.net,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,2, +org.apache.hc.core5.util,,,24,,,,,,,,,,,,,,,,,,,,,,,,,,,18,6 +org.apache.http,27,3,70,,,,,,,,,,,,,,25,,,,,,,,,2,,,3,62,8 +org.apache.ibatis.jdbc,6,,,,,,,,,,,,,,,,,,,6,,,,,,,,,,, +org.apache.log4j,11,,,,,,,,,,,,,11,,,,,,,,,,,,,,,,, +org.apache.logging.log4j,359,,8,,,,,,,,,,,359,,,,,,,,,,,,,,,,4,4 +org.apache.shiro.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +org.apache.shiro.jndi,1,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,, +org.codehaus.groovy.control,1,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,, +org.dom4j,20,,,,,,,,,,,,,,,,,,,,,,,20,,,,,,, +org.hibernate,7,,,,,,,,,,,,,,,,,,,7,,,,,,,,,,, +org.jboss.logging,324,,,,,,,,,,,,,324,,,,,,,,,,,,,,,,, +org.jdbi.v3.core,6,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,, +org.jooq,1,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,, +org.json,,,236,,,,,,,,,,,,,,,,,,,,,,,,,,,198,38 +org.mvel2,16,,,,,,,,,,,,,,16,,,,,,,,,,,,,,,, +org.scijava.log,13,,,,,,,,,,,,,13,,,,,,,,,,,,,,,,, +org.slf4j,55,,6,,,,,,,,,,,55,,,,,,,,,,,,,,,,2,4 +org.springframework.beans,,,26,,,,,,,,,,,,,,,,,,,,,,,,,,,,26 +org.springframework.boot.jdbc,1,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,, +org.springframework.cache,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,13 +org.springframework.context,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,3, +org.springframework.http,14,,70,,,,,,,,,,,,,,14,,,,,,,,,,,,,60,10 +org.springframework.jdbc.core,10,,,,,,,,,,,,,,,,,,,10,,,,,,,,,,, +org.springframework.jdbc.datasource,4,,,,,,,,,4,,,,,,,,,,,,,,,,,,,,, +org.springframework.jdbc.object,9,,,,,,,,,,,,,,,,,,,9,,,,,,,,,,, +org.springframework.jndi,1,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,, +org.springframework.ldap,47,,,,,,,,,,,33,14,,,,,,,,,,,,,,,,,, +org.springframework.security.web.savedrequest,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,6,, +org.springframework.ui,,,32,,,,,,,,,,,,,,,,,,,,,,,,,,,,32 +org.springframework.util,,,139,,,,,,,,,,,,,,,,,,,,,,,,,,,87,52 +org.springframework.validation,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,13, +org.springframework.web.client,13,3,,,,,,,,,,,,,,,13,,,,,,,,,,,,3,, +org.springframework.web.context.request,,8,,,,,,,,,,,,,,,,,,,,,,,,,,,8,, +org.springframework.web.multipart,,12,13,,,,,,,,,,,,,,,,,,,,,,,,,,12,13, +org.springframework.web.reactive.function.client,2,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,, +org.springframework.web.util,,,163,,,,,,,,,,,,,,,,,,,,,,,,,,,138,25 +org.xml.sax,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +org.xmlpull.v1,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,3,, +play.mvc,,4,,,,,,,,,,,,,,,,,,,,,,,,,,,4,, +ratpack.core.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,3, +ratpack.core.handling,,6,4,,,,,,,,,,,,,,,,,,,,,,,,,,6,4, +ratpack.core.http,,10,10,,,,,,,,,,,,,,,,,,,,,,,,,,10,10, +ratpack.exec,,,48,,,,,,,,,,,,,,,,,,,,,,,,,,,,48 +ratpack.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,3, +ratpack.func,,,35,,,,,,,,,,,,,,,,,,,,,,,,,,,,35 +ratpack.handling,,6,4,,,,,,,,,,,,,,,,,,,,,,,,,,6,4, +ratpack.http,,10,10,,,,,,,,,,,,,,,,,,,,,,,,,,10,10, +ratpack.util,,,35,,,,,,,,,,,,,,,,,,,,,,,,,,,,35 diff --git a/java/documentation/library-coverage/coverage.rst b/java/documentation/library-coverage/coverage.rst index 84470186ecc..c666f7e5d54 100644 --- a/java/documentation/library-coverage/coverage.rst +++ b/java/documentation/library-coverage/coverage.rst @@ -15,9 +15,9 @@ Java framework & library support `Apache HttpComponents `_,"``org.apache.hc.core5.*``, ``org.apache.http``",5,136,28,,,3,,,,25 `Google Guava `_,``com.google.common.*``,,728,35,,6,,,,, `JSON-java `_,``org.json``,,236,,,,,,,, - Java Standard Library,``java.*``,3,541,111,28,,,7,,,10 + Java Standard Library,``java.*``,3,541,115,28,,,7,,,10 Java extensions,"``javax.*``, ``jakarta.*``",54,552,32,,,4,,1,1,2 - `Spring `_,``org.springframework.*``,29,472,96,,,,19,14,,29 - Others,"``androidx.slice``, ``cn.hutool.core.codec``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.opensymphony.xwork2.ognl``, ``com.unboundid.ldap.sdk``, ``flexjson``, ``groovy.lang``, ``groovy.util``, ``jodd.json``, ``net.sf.saxon.s9api``, ``ognl``, ``org.apache.commons.codec``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.logging.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.hibernate``, ``org.jboss.logging``, ``org.jooq``, ``org.mvel2``, ``org.scijava.log``, ``org.slf4j``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``",44,283,921,,,,14,18,, - Totals,,183,6225,1424,106,6,10,107,33,1,81 + `Spring `_,``org.springframework.*``,29,472,101,,,,19,14,,29 + Others,"``androidx.slice``, ``cn.hutool.core.codec``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.opensymphony.xwork2.ognl``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``groovy.lang``, ``groovy.util``, ``jodd.json``, ``net.sf.saxon.s9api``, ``ognl``, ``org.apache.commons.codec``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.logging.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.hibernate``, ``org.jboss.logging``, ``org.jdbi.v3.core``, ``org.jooq``, ``org.mvel2``, ``org.scijava.log``, ``org.slf4j``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``",44,283,929,,,,14,18,, + Totals,,183,6225,1441,106,6,10,107,33,1,81 diff --git a/java/ql/lib/CHANGELOG.md b/java/ql/lib/CHANGELOG.md index 9d066ac3d17..db971f8c7dd 100644 --- a/java/ql/lib/CHANGELOG.md +++ b/java/ql/lib/CHANGELOG.md @@ -1,3 +1,15 @@ +## 0.0.11 + +### New Features + +* Added `hasDescendant(RefType anc, Type sub)` +* Added `RefType.getADescendant()` +* Added `RefType.getAStrictAncestor()` + +### Minor Analysis Improvements + + * Add support for `CharacterLiteral` in `CompileTimeConstantExpr.getStringValue()` + ## 0.0.10 ### New Features diff --git a/java/ql/lib/change-notes/2022-02-07-deleted-deprecations.md b/java/ql/lib/change-notes/2022-02-07-deleted-deprecations.md new file mode 100644 index 00000000000..e8da1e8e158 --- /dev/null +++ b/java/ql/lib/change-notes/2022-02-07-deleted-deprecations.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* All deprecated predicates/classes/modules that have been deprecated for over a year have been deleted. \ No newline at end of file diff --git a/java/ql/lib/change-notes/2022-02-07-deprecated-acronyms.md b/java/ql/lib/change-notes/2022-02-07-deprecated-acronyms.md new file mode 100644 index 00000000000..a79f286aacd --- /dev/null +++ b/java/ql/lib/change-notes/2022-02-07-deprecated-acronyms.md @@ -0,0 +1,5 @@ +--- +category: deprecated +--- +* Many classes/predicates/modules that had upper-case acronyms have been renamed to follow our style-guide. + The old name still exists as a deprecated alias. \ No newline at end of file diff --git a/java/ql/lib/change-notes/2022-02-21-type-hierarchy.md b/java/ql/lib/change-notes/2022-02-21-type-hierarchy.md deleted file mode 100644 index 5911c33d131..00000000000 --- a/java/ql/lib/change-notes/2022-02-21-type-hierarchy.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: feature ---- -* Added `hasDescendant(RefType anc, Type sub)` -* Added `RefType.getADescendant()` -* Added `RefType.getAStrictAncestor()` diff --git a/java/ql/lib/change-notes/2022-03-11-revert-8325.md b/java/ql/lib/change-notes/2022-03-11-revert-8325.md new file mode 100644 index 00000000000..d38d6327819 --- /dev/null +++ b/java/ql/lib/change-notes/2022-03-11-revert-8325.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- + * Re-removed support for `CharacterLiteral` from `CompileTimeConstantExpr.getStringValue()` to restore the convention that that predicate only applies to `String`-typed constants. diff --git a/java/ql/lib/change-notes/2022-03-14-new-jdbc-ssrf-sinks.md b/java/ql/lib/change-notes/2022-03-14-new-jdbc-ssrf-sinks.md new file mode 100644 index 00000000000..c154b12cfad --- /dev/null +++ b/java/ql/lib/change-notes/2022-03-14-new-jdbc-ssrf-sinks.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- + * Added support for detection of SSRF via JDBC database URLs, including connections made using the standard library (`java.sql`), Hikari Connection Pool, JDBI and Spring JDBC. diff --git a/java/ql/lib/change-notes/2022-03-14-taint-interface-cleanup.md b/java/ql/lib/change-notes/2022-03-14-taint-interface-cleanup.md new file mode 100644 index 00000000000..3481d507db3 --- /dev/null +++ b/java/ql/lib/change-notes/2022-03-14-taint-interface-cleanup.md @@ -0,0 +1,4 @@ +--- +category: breaking +--- +* The flow state variants of `isBarrier` and `isAdditionalFlowStep` are no longer exposed in the taint tracking library. The `isSanitizer` and `isAdditionalTaintStep` predicates should be used instead. diff --git a/java/ql/lib/change-notes/released/0.0.11.md b/java/ql/lib/change-notes/released/0.0.11.md new file mode 100644 index 00000000000..4ea71b83f53 --- /dev/null +++ b/java/ql/lib/change-notes/released/0.0.11.md @@ -0,0 +1,11 @@ +## 0.0.11 + +### New Features + +* Added `hasDescendant(RefType anc, Type sub)` +* Added `RefType.getADescendant()` +* Added `RefType.getAStrictAncestor()` + +### Minor Analysis Improvements + + * Add support for `CharacterLiteral` in `CompileTimeConstantExpr.getStringValue()` diff --git a/java/ql/lib/codeql-pack.release.yml b/java/ql/lib/codeql-pack.release.yml index b740014e5ae..e679dc42092 100644 --- a/java/ql/lib/codeql-pack.release.yml +++ b/java/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.10 +lastReleaseVersion: 0.0.11 diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index 694ff807403..41d541a67fb 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-all -version: 0.0.11-dev +version: 0.0.12-dev groups: java dbscheme: config/semmlecode.dbscheme extractor: java diff --git a/java/ql/lib/semmle/code/java/Expr.qll b/java/ql/lib/semmle/code/java/Expr.qll index 5a991d8814c..4f3c458c186 100755 --- a/java/ql/lib/semmle/code/java/Expr.qll +++ b/java/ql/lib/semmle/code/java/Expr.qll @@ -1666,7 +1666,10 @@ class LValue extends VarAccess { * (such as (`+=`), both the RHS and the LHS of the compound assignment * are source expressions of the assignment. */ - Expr getRHS() { exists(Assignment e | e.getDest() = this and e.getSource() = result) } + Expr getRhs() { exists(Assignment e | e.getDest() = this and e.getSource() = result) } + + /** DEPRECATED: Alias for getRhs */ + deprecated Expr getRHS() { result = this.getRhs() } } /** diff --git a/java/ql/lib/semmle/code/java/Statement.qll b/java/ql/lib/semmle/code/java/Statement.qll index 31c81f46c0f..c05d478c79a 100755 --- a/java/ql/lib/semmle/code/java/Statement.qll +++ b/java/ql/lib/semmle/code/java/Statement.qll @@ -82,12 +82,6 @@ class BlockStmt extends Stmt, @block { override string getAPrimaryQlClass() { result = "BlockStmt" } } -/** - * DEPRECATED: This is now called `BlockStmt` to avoid confusion with - * `BasicBlock`. - */ -deprecated class Block = BlockStmt; - /** A block with only a single statement. */ class SingletonBlock extends BlockStmt { SingletonBlock() { this.getNumStmt() = 1 } @@ -103,14 +97,6 @@ class SingletonBlock extends BlockStmt { abstract class ConditionalStmt extends Stmt { /** Gets the boolean condition of this conditional statement. */ abstract Expr getCondition(); - - /** - * Gets the statement that is executed whenever the condition - * of this branch statement evaluates to `true`. - * - * DEPRECATED: use `ConditionNode.getATrueSuccessor()` instead. - */ - abstract deprecated Stmt getTrueSuccessor(); } /** An `if` statement. */ @@ -121,12 +107,6 @@ class IfStmt extends ConditionalStmt, @ifstmt { /** Gets the `then` branch of this `if` statement. */ Stmt getThen() { result.isNthChildOf(this, 1) } - /** - * Gets the statement that is executed whenever the condition - * of this branch statement evaluates to `true`. - */ - deprecated override Stmt getTrueSuccessor() { result = this.getThen() } - /** Gets the `else` branch of this `if` statement. */ Stmt getElse() { result.isNthChildOf(this, 2) } @@ -174,12 +154,6 @@ class ForStmt extends ConditionalStmt, @forstmt { /** Gets the body of this `for` loop. */ Stmt getStmt() { result.getParent() = this and result.getIndex() = 2 } - /** - * Gets the statement that is executed whenever the condition - * of this branch statement evaluates to true. - */ - deprecated override Stmt getTrueSuccessor() { result = this.getStmt() } - /** * Gets a variable that is used as an iteration variable: it is defined, * updated or tested in the head of the `for` statement. @@ -238,12 +212,6 @@ class WhileStmt extends ConditionalStmt, @whilestmt { /** Gets the body of this `while` loop. */ Stmt getStmt() { result.getParent() = this } - /** - * Gets the statement that is executed whenever the condition - * of this branch statement evaluates to true. - */ - deprecated override Stmt getTrueSuccessor() { result = this.getStmt() } - override string pp() { result = "while (...) " + this.getStmt().pp() } override string toString() { result = "while (...)" } @@ -261,12 +229,6 @@ class DoStmt extends ConditionalStmt, @dostmt { /** Gets the body of this `do` loop. */ Stmt getStmt() { result.getParent() = this } - /** - * Gets the statement that is executed whenever the condition - * of this branch statement evaluates to `true`. - */ - deprecated override Stmt getTrueSuccessor() { result = this.getStmt() } - override string pp() { result = "do " + this.getStmt().pp() + " while (...)" } override string toString() { result = "do ... while (...)" } diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index c8f1ff47bd2..631c47583e6 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -131,6 +131,8 @@ private module Frameworks { private import semmle.code.java.security.XPath private import semmle.code.java.security.XsltInjection private import semmle.code.java.frameworks.Jdbc + private import semmle.code.java.frameworks.Jdbi + private import semmle.code.java.frameworks.HikariCP private import semmle.code.java.frameworks.SpringJdbc private import semmle.code.java.frameworks.MyBatis private import semmle.code.java.frameworks.Hibernate diff --git a/java/ql/lib/semmle/code/java/dataflow/ModulusAnalysis.qll b/java/ql/lib/semmle/code/java/dataflow/ModulusAnalysis.qll index 2a58cba6209..b919d143a39 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ModulusAnalysis.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ModulusAnalysis.qll @@ -111,13 +111,6 @@ private predicate evenlyDivisibleExpr(Expr e, int factor) { ) } -/** - * Holds if `rix` is the number of input edges to `phi`. - */ -private predicate maxPhiInputRank(SsaPhiNode phi, int rix) { - rix = max(int r | rankedPhiInput(phi, _, _, r)) -} - /** * Gets the remainder of `val` modulo `mod`. * diff --git a/java/ql/lib/semmle/code/java/dataflow/RangeAnalysis.qll b/java/ql/lib/semmle/code/java/dataflow/RangeAnalysis.qll index de7aca88434..47c3cdd9db6 100644 --- a/java/ql/lib/semmle/code/java/dataflow/RangeAnalysis.qll +++ b/java/ql/lib/semmle/code/java/dataflow/RangeAnalysis.qll @@ -725,6 +725,26 @@ private predicate boundedPhiCandValidForEdge( ) } +/** + * Holds if `b + delta` is a valid bound for `phi`'s `rix`th input edge. + * - `upper = true` : `phi <= b + delta` + * - `upper = false` : `phi >= b + delta` + */ +private predicate boundedPhiStep( + SsaPhiNode phi, Bound b, int delta, boolean upper, boolean fromBackEdge, int origdelta, + Reason reason, int rix +) { + exists(SsaVariable inp, SsaReadPositionPhiInputEdge edge | + rankedPhiInput(phi, inp, edge, rix) and + boundedPhiCandValidForEdge(phi, b, delta, upper, fromBackEdge, origdelta, reason, inp, edge) and + ( + rix = 1 + or + boundedPhiStep(phi, b, delta, upper, fromBackEdge, origdelta, reason, rix - 1) + ) + ) +} + /** * Holds if `b + delta` is a valid bound for `phi`. * - `upper = true` : `phi <= b + delta` @@ -734,8 +754,9 @@ private predicate boundedPhi( SsaPhiNode phi, Bound b, int delta, boolean upper, boolean fromBackEdge, int origdelta, Reason reason ) { - forex(SsaVariable inp, SsaReadPositionPhiInputEdge edge | edge.phiInput(phi, inp) | - boundedPhiCandValidForEdge(phi, b, delta, upper, fromBackEdge, origdelta, reason, inp, edge) + exists(int r | + boundedPhiStep(phi, b, delta, upper, fromBackEdge, origdelta, reason, r) and + maxPhiInputRank(phi, r) ) } diff --git a/java/ql/lib/semmle/code/java/dataflow/SSA.qll b/java/ql/lib/semmle/code/java/dataflow/SSA.qll index f67a211198b..7dc646c179a 100644 --- a/java/ql/lib/semmle/code/java/dataflow/SSA.qll +++ b/java/ql/lib/semmle/code/java/dataflow/SSA.qll @@ -920,7 +920,7 @@ class SsaVariable extends TSsaVariable { } /** Gets the `ControlFlowNode` at which this SSA variable is defined. */ - ControlFlowNode getCFGNode() { + ControlFlowNode getCfgNode() { this = TSsaPhiNode(_, result) or this = TSsaCertainUpdate(_, result, _, _) or this = TSsaUncertainUpdate(_, result, _, _) or @@ -928,14 +928,17 @@ class SsaVariable extends TSsaVariable { this = TSsaUntracked(_, result) } + /** DEPRECATED: Alias for getCfgNode */ + deprecated ControlFlowNode getCFGNode() { result = this.getCfgNode() } + /** Gets a textual representation of this SSA variable. */ string toString() { none() } /** Gets the source location for this element. */ - Location getLocation() { result = this.getCFGNode().getLocation() } + Location getLocation() { result = this.getCfgNode().getLocation() } /** Gets the `BasicBlock` in which this SSA variable is defined. */ - BasicBlock getBasicBlock() { result = this.getCFGNode().getBasicBlock() } + BasicBlock getBasicBlock() { result = this.getCfgNode().getBasicBlock() } /** Gets an access of this SSA variable. */ RValue getAUse() { @@ -990,7 +993,7 @@ class SsaUpdate extends SsaVariable { class SsaExplicitUpdate extends SsaUpdate, TSsaCertainUpdate { SsaExplicitUpdate() { exists(VariableUpdate upd | - upd = this.getCFGNode() and getDestVar(upd) = this.getSourceVariable() + upd = this.getCfgNode() and getDestVar(upd) = this.getSourceVariable() ) } @@ -998,7 +1001,7 @@ class SsaExplicitUpdate extends SsaUpdate, TSsaCertainUpdate { /** Gets the `VariableUpdate` defining the SSA variable. */ VariableUpdate getDefiningExpr() { - result = this.getCFGNode() and getDestVar(result) = this.getSourceVariable() + result = this.getCfgNode() and getDestVar(result) = this.getSourceVariable() } } @@ -1018,10 +1021,10 @@ class SsaImplicitUpdate extends SsaUpdate { private string getKind() { this = TSsaUntracked(_, _) and result = "untracked" or - certainVariableUpdate(this.getSourceVariable().getQualifier(), this.getCFGNode(), _, _) and + certainVariableUpdate(this.getSourceVariable().getQualifier(), this.getCfgNode(), _, _) and result = "explicit qualifier" or - if uncertainVariableUpdate(this.getSourceVariable().getQualifier(), this.getCFGNode(), _, _) + if uncertainVariableUpdate(this.getSourceVariable().getQualifier(), this.getCfgNode(), _, _) then if exists(this.getANonLocalUpdate()) then result = "nonlocal + nonlocal qualifier" @@ -1038,7 +1041,7 @@ class SsaImplicitUpdate extends SsaUpdate { exists(SsaSourceField f, Callable setter | f = this.getSourceVariable() and relevantFieldUpdate(setter, f.getField(), result) and - updatesNamedField(this.getCFGNode(), f, setter) + updatesNamedField(this.getCfgNode(), f, setter) ) } @@ -1051,8 +1054,8 @@ class SsaImplicitUpdate extends SsaUpdate { */ predicate assignsUnknownValue() { this = TSsaUntracked(_, _) or - certainVariableUpdate(this.getSourceVariable().getQualifier(), this.getCFGNode(), _, _) or - uncertainVariableUpdate(this.getSourceVariable().getQualifier(), this.getCFGNode(), _, _) + certainVariableUpdate(this.getSourceVariable().getQualifier(), this.getCfgNode(), _, _) or + uncertainVariableUpdate(this.getSourceVariable().getQualifier(), this.getCfgNode(), _, _) } } @@ -1086,7 +1089,7 @@ class SsaImplicitInit extends SsaVariable, TSsaEntryDef { */ predicate isParameterDefinition(Parameter p) { this.getSourceVariable() = TLocalVar(p.getCallable(), p) and - p.getCallable().getBody() = this.getCFGNode() + p.getCallable().getBody() = this.getCfgNode() } } @@ -1098,7 +1101,7 @@ class SsaPhiNode extends SsaVariable, TSsaPhiNode { SsaVariable getAPhiInput() { exists(BasicBlock phiPred, TrackedVar v | v = this.getSourceVariable() and - this.getCFGNode().(BasicBlock).getABBPredecessor() = phiPred and + this.getCfgNode().(BasicBlock).getABBPredecessor() = phiPred and ssaDefReachesEndOfBlock(v, result, phiPred) ) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/BaseSSA.qll b/java/ql/lib/semmle/code/java/dataflow/internal/BaseSSA.qll index 218fe6ef287..f44ed438596 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/BaseSSA.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/BaseSSA.qll @@ -476,18 +476,21 @@ class BaseSsaVariable extends TBaseSsaVariable { } /** Gets the `ControlFlowNode` at which this SSA variable is defined. */ - ControlFlowNode getCFGNode() { + ControlFlowNode getCfgNode() { this = TSsaPhiNode(_, result) or this = TSsaUpdate(_, result, _, _) or this = TSsaEntryDef(_, result) } + /** DEPRECATED: Alias for getCfgNode */ + deprecated ControlFlowNode getCFGNode() { result = this.getCfgNode() } + string toString() { none() } - Location getLocation() { result = this.getCFGNode().getLocation() } + Location getLocation() { result = this.getCfgNode().getLocation() } /** Gets the `BasicBlock` in which this SSA variable is defined. */ - BasicBlock getBasicBlock() { result = this.getCFGNode().getBasicBlock() } + BasicBlock getBasicBlock() { result = this.getCfgNode().getBasicBlock() } /** Gets an access of this SSA variable. */ RValue getAUse() { ssaDefReachesUse(_, this, result) } @@ -533,7 +536,7 @@ class BaseSsaVariable extends TBaseSsaVariable { class BaseSsaUpdate extends BaseSsaVariable, TSsaUpdate { BaseSsaUpdate() { exists(VariableUpdate upd | - upd = this.getCFGNode() and getDestVar(upd) = this.getSourceVariable() + upd = this.getCfgNode() and getDestVar(upd) = this.getSourceVariable() ) } @@ -541,7 +544,7 @@ class BaseSsaUpdate extends BaseSsaVariable, TSsaUpdate { /** Gets the `VariableUpdate` defining the SSA variable. */ VariableUpdate getDefiningExpr() { - result = this.getCFGNode() and getDestVar(result) = this.getSourceVariable() + result = this.getCfgNode() and getDestVar(result) = this.getSourceVariable() } } @@ -562,7 +565,7 @@ class BaseSsaImplicitInit extends BaseSsaVariable, TSsaEntryDef { */ predicate isParameterDefinition(Parameter p) { this.getSourceVariable() = TLocalVar(p.getCallable(), p) and - p.getCallable().getBody() = this.getCFGNode() + p.getCallable().getBody() = this.getCfgNode() } } @@ -574,7 +577,7 @@ class BaseSsaPhiNode extends BaseSsaVariable, TSsaPhiNode { BaseSsaVariable getAPhiInput() { exists(BasicBlock phiPred, BaseSsaSourceVariable v | v = this.getSourceVariable() and - this.getCFGNode().(BasicBlock).getABBPredecessor() = phiPred and + this.getCfgNode().(BasicBlock).getABBPredecessor() = phiPred and ssaDefReachesEndOfBlock(v, result, phiPred) ) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll index 49798e484dd..30031931ed9 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll @@ -416,3 +416,13 @@ private class MyConsistencyConfiguration extends Consistency::ConsistencyConfigu n.getType() instanceof ImmutableType or n instanceof ImplicitVarargsArray } } + +/** + * Holds if the the content `c` is a container. + */ +predicate containerContent(Content c) { + c instanceof ArrayContent or + c instanceof CollectionContent or + c instanceof MapKeyContent or + c instanceof MapValueContent +} diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImplSpecific.qll b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImplSpecific.qll index eb59ee5f06a..f4fbcf0045f 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImplSpecific.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImplSpecific.qll @@ -196,7 +196,7 @@ predicate interpretInputSpecific(string c, InterpretNode mid, InterpretNode n) { exists(FieldWrite fw | c = "" and fw.getField() = mid.asElement() and - n.asNode().asExpr() = fw.getRHS() + n.asNode().asExpr() = fw.getRhs() ) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll b/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll index d408e3f5e0b..b1422e89552 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll @@ -62,13 +62,6 @@ private module Cached { ) } - private predicate containerContent(DataFlow::Content c) { - c instanceof DataFlow::ArrayContent or - c instanceof DataFlow::CollectionContent or - c instanceof DataFlow::MapKeyContent or - c instanceof DataFlow::MapValueContent - } - /** * Holds if taint can flow in one local step from `src` to `sink` excluding * local data flow steps. That is, `src` and `sink` are likely to represent diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/ModulusAnalysisSpecific.qll b/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/ModulusAnalysisSpecific.qll index fc17dbfd979..c5d5bc98009 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/ModulusAnalysisSpecific.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/ModulusAnalysisSpecific.qll @@ -111,24 +111,4 @@ module Private { predicate ssaUpdateStep = RU::ssaUpdateStep/3; Expr getABasicBlockExpr(BasicBlock bb) { result = bb.getANode() } - - private predicate id(BasicBlock x, BasicBlock y) { x = y } - - private predicate idOf(BasicBlock x, int y) = equivalenceRelation(id/2)(x, y) - - private int getId(BasicBlock bb) { idOf(bb, result) } - - /** - * Holds if `inp` is an input to `phi` along `edge` and this input has index `r` - * in an arbitrary 1-based numbering of the input edges to `phi`. - */ - predicate rankedPhiInput(SsaPhiNode phi, SsaVariable inp, SsaReadPositionPhiInputEdge edge, int r) { - edge.phiInput(phi, inp) and - edge = - rank[r](SsaReadPositionPhiInputEdge e | - e.phiInput(phi, _) - | - e order by getId(e.getOrigBlock()) - ) - } } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll b/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll index e450c11b5ab..08335f6680d 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll @@ -3,6 +3,7 @@ */ private import SsaReadPositionSpecific +import SsaReadPositionSpecific::Public private newtype TSsaReadPosition = TSsaReadPositionBlock(BasicBlock bb) { bb = getAReadBasicBlock(_) } or @@ -55,3 +56,10 @@ class SsaReadPositionPhiInputEdge extends SsaReadPosition, TSsaReadPositionPhiIn override string toString() { result = "edge" } } + +/** + * Holds if `rix` is the number of input edges to `phi`. + */ +predicate maxPhiInputRank(SsaPhiNode phi, int rix) { + rix = max(int r | rankedPhiInput(phi, _, _, r)) +} diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SsaReadPositionSpecific.qll b/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SsaReadPositionSpecific.qll index dcfc3d69e32..410dc6b5cfe 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SsaReadPositionSpecific.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SsaReadPositionSpecific.qll @@ -4,6 +4,7 @@ private import semmle.code.java.dataflow.SSA as Ssa private import semmle.code.java.controlflow.BasicBlocks as BB +private import SsaReadPositionCommon class SsaVariable = Ssa::SsaVariable; @@ -13,3 +14,28 @@ class BasicBlock = BB::BasicBlock; /** Gets a basic block in which SSA variable `v` is read. */ BasicBlock getAReadBasicBlock(SsaVariable v) { result = v.getAUse().getBasicBlock() } + +private predicate id(BasicBlock x, BasicBlock y) { x = y } + +private predicate idOf(BasicBlock x, int y) = equivalenceRelation(id/2)(x, y) + +private int getId(BasicBlock bb) { idOf(bb, result) } + +/** + * Declarations to be exposed to users of SsaReadPositionCommon + */ +module Public { + /** + * Holds if `inp` is an input to `phi` along `edge` and this input has index `r` + * in an arbitrary 1-based numbering of the input edges to `phi`. + */ + predicate rankedPhiInput(SsaPhiNode phi, SsaVariable inp, SsaReadPositionPhiInputEdge edge, int r) { + edge.phiInput(phi, inp) and + edge = + rank[r](SsaReadPositionPhiInputEdge e | + e.phiInput(phi, _) + | + e order by getId(e.getOrigBlock()) + ) + } +} diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingImpl.qll index 43555af1af9..b344ea9a864 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingImpl.qll @@ -64,13 +64,30 @@ abstract class Configuration extends DataFlow::Configuration { override predicate isSource(DataFlow::Node source) { none() } /** - * Holds if `sink` is a relevant taint sink. + * Holds if `source` is a relevant taint source with the given initial + * `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } + + /** + * Holds if `sink` is a relevant taint sink * * The smaller this predicate is, the faster `hasFlow()` will converge. */ // overridden to provide taint-tracking specific qldoc override predicate isSink(DataFlow::Node sink) { none() } + /** + * Holds if `sink` is a relevant taint sink accepting `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } + /** Holds if the node `node` is a taint sanitizer. */ predicate isSanitizer(DataFlow::Node node) { none() } @@ -79,6 +96,16 @@ abstract class Configuration extends DataFlow::Configuration { defaultTaintSanitizer(node) } + /** + * Holds if the node `node` is a taint sanitizer when the flow state is + * `state`. + */ + predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } + + final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { + this.isSanitizer(node, state) + } + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } @@ -107,6 +134,25 @@ abstract class Configuration extends DataFlow::Configuration { defaultAdditionalTaintStep(node1, node2) } + /** + * Holds if the additional taint propagation step from `node1` to `node2` + * must be taken into account in the analysis. This step is only applicable + * in `state1` and updates the flow state to `state2`. + */ + predicate isAdditionalTaintStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + none() + } + + final override predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + this.isAdditionalTaintStep(node1, state1, node2, state2) + } + override predicate allowImplicitRead(DataFlow::Node node, DataFlow::Content c) { (this.isSink(node) or this.isAdditionalTaintStep(node, _)) and defaultImplicitTaintRead(node, c) diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingImpl.qll index 43555af1af9..b344ea9a864 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingImpl.qll @@ -64,13 +64,30 @@ abstract class Configuration extends DataFlow::Configuration { override predicate isSource(DataFlow::Node source) { none() } /** - * Holds if `sink` is a relevant taint sink. + * Holds if `source` is a relevant taint source with the given initial + * `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } + + /** + * Holds if `sink` is a relevant taint sink * * The smaller this predicate is, the faster `hasFlow()` will converge. */ // overridden to provide taint-tracking specific qldoc override predicate isSink(DataFlow::Node sink) { none() } + /** + * Holds if `sink` is a relevant taint sink accepting `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } + /** Holds if the node `node` is a taint sanitizer. */ predicate isSanitizer(DataFlow::Node node) { none() } @@ -79,6 +96,16 @@ abstract class Configuration extends DataFlow::Configuration { defaultTaintSanitizer(node) } + /** + * Holds if the node `node` is a taint sanitizer when the flow state is + * `state`. + */ + predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } + + final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { + this.isSanitizer(node, state) + } + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } @@ -107,6 +134,25 @@ abstract class Configuration extends DataFlow::Configuration { defaultAdditionalTaintStep(node1, node2) } + /** + * Holds if the additional taint propagation step from `node1` to `node2` + * must be taken into account in the analysis. This step is only applicable + * in `state1` and updates the flow state to `state2`. + */ + predicate isAdditionalTaintStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + none() + } + + final override predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + this.isAdditionalTaintStep(node1, state1, node2, state2) + } + override predicate allowImplicitRead(DataFlow::Node node, DataFlow::Content c) { (this.isSink(node) or this.isAdditionalTaintStep(node, _)) and defaultImplicitTaintRead(node, c) diff --git a/java/ql/lib/semmle/code/java/deadcode/EntryPoints.qll b/java/ql/lib/semmle/code/java/deadcode/EntryPoints.qll index cbb29066102..027e2392252 100644 --- a/java/ql/lib/semmle/code/java/deadcode/EntryPoints.qll +++ b/java/ql/lib/semmle/code/java/deadcode/EntryPoints.qll @@ -427,8 +427,8 @@ class PersistenceCallbackMethod extends CallableEntryPoint { * A source class which is referred to by fully qualified name in the value of an arbitrary XML * attribute which has a name containing "className" or "ClassName". */ -class ArbitraryXMLEntryPoint extends ReflectivelyConstructedClass { - ArbitraryXMLEntryPoint() { +class ArbitraryXmlEntryPoint extends ReflectivelyConstructedClass { + ArbitraryXmlEntryPoint() { this.fromSource() and exists(XMLAttribute attribute | attribute.getName() = "className" or @@ -446,6 +446,9 @@ class ArbitraryXMLEntryPoint extends ReflectivelyConstructedClass { } } +/** DEPRECATED: Alias for ArbitraryXmlEntryPoint */ +deprecated class ArbitraryXMLEntryPoint = ArbitraryXmlEntryPoint; + /** A Selenium PageObject, created by a call to PageFactory.initElements(..). */ class SeleniumPageObjectEntryPoint extends ReflectivelyConstructedClass { SeleniumPageObjectEntryPoint() { this instanceof SeleniumPageObject } diff --git a/java/ql/lib/semmle/code/java/deadcode/SpringEntryPoints.qll b/java/ql/lib/semmle/code/java/deadcode/SpringEntryPoints.qll index 4929ba2b7f2..562c7ef7c1c 100644 --- a/java/ql/lib/semmle/code/java/deadcode/SpringEntryPoints.qll +++ b/java/ql/lib/semmle/code/java/deadcode/SpringEntryPoints.qll @@ -13,7 +13,7 @@ class SpringInjectionCallableEntryPoint extends CallableEntryPoint { this instanceof SpringBeanReflectivelyConstructed or // A setter method specified in the context. this instanceof SpringBeanPropertySetterMethod or - exists(this.(SpringBeanXMLAutowiredSetterMethod).getInjectedBean()) or + exists(this.(SpringBeanXmlAutowiredSetterMethod).getInjectedBean()) or this instanceof SpringBeanAutowiredCallable } } diff --git a/java/ql/lib/semmle/code/java/deadcode/WebEntryPoints.qll b/java/ql/lib/semmle/code/java/deadcode/WebEntryPoints.qll index b061502fffe..836ad5a1f55 100644 --- a/java/ql/lib/semmle/code/java/deadcode/WebEntryPoints.qll +++ b/java/ql/lib/semmle/code/java/deadcode/WebEntryPoints.qll @@ -14,7 +14,7 @@ class ServletConstructedClass extends ReflectivelyConstructedClass { // referred to as a servlet-class in at least one. If no `web.xml` files are found, we assume // that XML extraction was not enabled, and therefore consider all `Servlet` classes as live. ( - isWebXMLIncluded() + isWebXmlIncluded() implies exists(WebServletClass servletClass | this = servletClass.getClass()) ) @@ -29,12 +29,12 @@ class ServletConstructedClass extends ReflectivelyConstructedClass { */ class ServletListenerClass extends ReflectivelyConstructedClass { ServletListenerClass() { - this.getAnAncestor() instanceof ServletWebXMLListenerType and + this.getAnAncestor() instanceof ServletWebXmlListenerType and // If we have seen any `web.xml` files, this listener will be considered to be live only if it is // referred to as a listener-class in at least one. If no `web.xml` files are found, we assume // that XML extraction was not enabled, and therefore consider all listener classes as live. ( - isWebXMLIncluded() + isWebXmlIncluded() implies exists(WebListenerClass listenerClass | this = listenerClass.getClass()) ) @@ -51,7 +51,7 @@ class ServletFilterClass extends ReflectivelyConstructedClass { // If we have seen any `web.xml` files, this filter will be considered to be live only if it is // referred to as a filter-class in at least one. If no `web.xml` files are found, we assume // that XML extraction was not enabled, and therefore consider all filter classes as live. - (isWebXMLIncluded() implies exists(WebFilterClass filterClass | this = filterClass.getClass())) + (isWebXmlIncluded() implies exists(WebFilterClass filterClass | this = filterClass.getClass())) } } diff --git a/java/ql/lib/semmle/code/java/frameworks/Camel.qll b/java/ql/lib/semmle/code/java/frameworks/Camel.qll index 09bfa73d460..0d7161e5f8f 100644 --- a/java/ql/lib/semmle/code/java/frameworks/Camel.qll +++ b/java/ql/lib/semmle/code/java/frameworks/Camel.qll @@ -12,7 +12,7 @@ import semmle.code.java.frameworks.camel.CamelJavaAnnotations */ class CamelToURI extends string { CamelToURI() { - exists(SpringCamelXMLToElement toXMLElement | this = toXMLElement.getURI()) or + exists(SpringCamelXmlToElement toXmlElement | this = toXmlElement.getURI()) or exists(CamelJavaDSLToDecl toJavaDSL | this = toJavaDSL.getURI()) } } @@ -56,17 +56,17 @@ class CamelToBeanURI extends CamelToURI { */ class CamelTargetClass extends Class { CamelTargetClass() { - exists(SpringCamelXMLBeanRef camelXMLBeanRef | + exists(SpringCamelXmlBeanRef camelXmlBeanRef | // A target may be defined by referencing an existing Spring Bean. - this = camelXMLBeanRef.getRefBean().getClass() + this = camelXmlBeanRef.getRefBean().getClass() or // A target may be defined by referencing a class, which Apache Camel will create into a bean. - this = camelXMLBeanRef.getBeanType() + this = camelXmlBeanRef.getBeanType() ) or exists(CamelToBeanURI toBeanURI | this = toBeanURI.getRefBean().getClass()) or - exists(SpringCamelXMLMethodElement xmlMethod | + exists(SpringCamelXmlMethodElement xmlMethod | this = xmlMethod.getRefBean().getClass() or this = xmlMethod.getBeanType() ) diff --git a/java/ql/lib/semmle/code/java/frameworks/HikariCP.qll b/java/ql/lib/semmle/code/java/frameworks/HikariCP.qll new file mode 100644 index 00000000000..30b4ba63405 --- /dev/null +++ b/java/ql/lib/semmle/code/java/frameworks/HikariCP.qll @@ -0,0 +1,17 @@ +/** + * Definitions of sinks in the Hikari Connection Pool library. + */ + +import java +import semmle.code.java.dataflow.ExternalFlow + +private class SsrfSinkCsv extends SinkModelCsv { + override predicate row(string row) { + row = + [ + //"package;type;overrides;name;signature;ext;spec;kind" + "com.zaxxer.hikari;HikariConfig;false;HikariConfig;(Properties);;Argument[0];jdbc-url", + "com.zaxxer.hikari;HikariConfig;false;setJdbcUrl;(String);;Argument[0];jdbc-url" + ] + } +} diff --git a/java/ql/lib/semmle/code/java/frameworks/Jdbc.qll b/java/ql/lib/semmle/code/java/frameworks/Jdbc.qll index b851842dfd3..5a20399f9db 100644 --- a/java/ql/lib/semmle/code/java/frameworks/Jdbc.qll +++ b/java/ql/lib/semmle/code/java/frameworks/Jdbc.qll @@ -52,3 +52,16 @@ private class SqlSinkCsv extends SinkModelCsv { ] } } + +private class SsrfSinkCsv extends SinkModelCsv { + override predicate row(string row) { + row = + [ + //"package;type;overrides;name;signature;ext;spec;kind" + "java.sql;DriverManager;false;getConnection;(String);;Argument[0];jdbc-url", + "java.sql;DriverManager;false;getConnection;(String,Properties);;Argument[0];jdbc-url", + "java.sql;DriverManager;false;getConnection;(String,String,String);;Argument[0];jdbc-url", + "java.sql;Driver;false;connect;(String,Properties);;Argument[0];jdbc-url" + ] + } +} diff --git a/java/ql/lib/semmle/code/java/frameworks/Jdbi.qll b/java/ql/lib/semmle/code/java/frameworks/Jdbi.qll new file mode 100644 index 00000000000..a2984805ce7 --- /dev/null +++ b/java/ql/lib/semmle/code/java/frameworks/Jdbi.qll @@ -0,0 +1,21 @@ +/** + * Definitions of sinks in the JDBI library. + */ + +import java +import semmle.code.java.dataflow.ExternalFlow + +private class SsrfSinkCsv extends SinkModelCsv { + override predicate row(string row) { + row = + [ + //"package;type;overrides;name;signature;ext;spec;kind" + "org.jdbi.v3.core;Jdbi;false;create;(String);;Argument[0];jdbc-url", + "org.jdbi.v3.core;Jdbi;false;create;(String,Properties);;Argument[0];jdbc-url", + "org.jdbi.v3.core;Jdbi;false;create;(String,String,String);;Argument[0];jdbc-url", + "org.jdbi.v3.core;Jdbi;false;open;(String);;Argument[0];jdbc-url", + "org.jdbi.v3.core;Jdbi;false;open;(String,Properties);;Argument[0];jdbc-url", + "org.jdbi.v3.core;Jdbi;false;open;(String,String,String);;Argument[0];jdbc-url" + ] + } +} diff --git a/java/ql/lib/semmle/code/java/frameworks/Networking.qll b/java/ql/lib/semmle/code/java/frameworks/Networking.qll index 1ab9c74e0ca..66a798f40d3 100644 --- a/java/ql/lib/semmle/code/java/frameworks/Networking.qll +++ b/java/ql/lib/semmle/code/java/frameworks/Networking.qll @@ -4,7 +4,7 @@ import semmle.code.java.Type -/** The type `java.net.URLConnection`. */ +/** The type `java.net.UrlConnection`. */ class TypeUrlConnection extends RefType { TypeUrlConnection() { this.hasQualifiedName("java.net", "URLConnection") } } @@ -29,15 +29,18 @@ class TypeUri extends RefType { TypeUri() { this.hasQualifiedName("java.net", "URI") } } -/** The method `java.net.URLConnection::getInputStream`. */ -class URLConnectionGetInputStreamMethod extends Method { - URLConnectionGetInputStreamMethod() { +/** The method `java.net.UrlConnection::getInputStream`. */ +class UrlConnectionGetInputStreamMethod extends Method { + UrlConnectionGetInputStreamMethod() { this.getDeclaringType() instanceof TypeUrlConnection and this.hasName("getInputStream") and this.hasNoParameters() } } +/** DEPRECATED: Alias for UrlConnectionGetInputStreamMethod */ +deprecated class URLConnectionGetInputStreamMethod = UrlConnectionGetInputStreamMethod; + /** The method `java.net.Socket::getInputStream`. */ class SocketGetInputStreamMethod extends Method { SocketGetInputStreamMethod() { diff --git a/java/ql/lib/semmle/code/java/frameworks/Servlets.qll b/java/ql/lib/semmle/code/java/frameworks/Servlets.qll index 81f334015bd..de82d49a7aa 100644 --- a/java/ql/lib/semmle/code/java/frameworks/Servlets.qll +++ b/java/ql/lib/semmle/code/java/frameworks/Servlets.qll @@ -120,14 +120,17 @@ library class HttpServletRequestGetHeaderNamesMethod extends Method { /** * The method `getRequestURL()` declared in `javax.servlet.http.HttpServletRequest`. */ -class HttpServletRequestGetRequestURLMethod extends Method { - HttpServletRequestGetRequestURLMethod() { +class HttpServletRequestGetRequestUrlMethod extends Method { + HttpServletRequestGetRequestUrlMethod() { this.getDeclaringType() instanceof HttpServletRequest and this.hasName("getRequestURL") and this.getNumberOfParameters() = 0 } } +/** DEPRECATED: Alias for HttpServletRequestGetRequestUrlMethod */ +deprecated class HttpServletRequestGetRequestURLMethod = HttpServletRequestGetRequestUrlMethod; + /** * The method `getRequestURI()` declared in `javax.servlet.http.HttpServletRequest`. */ @@ -318,8 +321,8 @@ class ServletClass extends Class { * Note: There are a number of other listener interfaces in the `javax.servlet` package that cannot * be configured in `web.xml` and therefore are not covered by this class. */ -class ServletWebXMLListenerType extends RefType { - ServletWebXMLListenerType() { +class ServletWebXmlListenerType extends RefType { + ServletWebXmlListenerType() { this.hasQualifiedName("javax.servlet", "ServletContextAttributeListener") or this.hasQualifiedName("javax.servlet", "ServletContextListener") or this.hasQualifiedName("javax.servlet", "ServletRequestAttributeListener") or @@ -333,6 +336,9 @@ class ServletWebXMLListenerType extends RefType { } } +/** DEPRECATED: Alias for ServletWebXmlListenerType */ +deprecated class ServletWebXMLListenerType = ServletWebXmlListenerType; + /** Holds if `m` is a request handler method (for example `doGet` or `doPost`). */ predicate isServletRequestMethod(Method m) { m.getDeclaringType() instanceof ServletClass and diff --git a/java/ql/lib/semmle/code/java/frameworks/SpringJdbc.qll b/java/ql/lib/semmle/code/java/frameworks/SpringJdbc.qll index ed7cdfd527f..067c686b912 100644 --- a/java/ql/lib/semmle/code/java/frameworks/SpringJdbc.qll +++ b/java/ql/lib/semmle/code/java/frameworks/SpringJdbc.qll @@ -37,3 +37,17 @@ private class SqlSinkCsv extends SinkModelCsv { ] } } + +private class SsrfSinkCsv extends SinkModelCsv { + override predicate row(string row) { + row = + [ + //"package;type;overrides;name;signature;ext;spec;kind" + "org.springframework.boot.jdbc;DataSourceBuilder;false;url;(String);;Argument[0];jdbc-url", + "org.springframework.jdbc.datasource;AbstractDriverBasedDataSource;false;setUrl;(String);;Argument[0];jdbc-url", + "org.springframework.jdbc.datasource;DriverManagerDataSource;false;DriverManagerDataSource;(String);;Argument[0];jdbc-url", + "org.springframework.jdbc.datasource;DriverManagerDataSource;false;DriverManagerDataSource;(String,String,String);;Argument[0];jdbc-url", + "org.springframework.jdbc.datasource;DriverManagerDataSource;false;DriverManagerDataSource;(String,Properties);;Argument[0];jdbc-url" + ] + } +} diff --git a/java/ql/lib/semmle/code/java/frameworks/UnboundId.qll b/java/ql/lib/semmle/code/java/frameworks/UnboundId.qll index 88156da0264..2bac6eb5ce2 100644 --- a/java/ql/lib/semmle/code/java/frameworks/UnboundId.qll +++ b/java/ql/lib/semmle/code/java/frameworks/UnboundId.qll @@ -25,12 +25,15 @@ class TypeUnboundIdLdapFilter extends Class { } /** The class `com.unboundid.ldap.sdk.LDAPConnection`. */ -class TypeUnboundIdLDAPConnection extends Class { - TypeUnboundIdLDAPConnection() { +class TypeUnboundIdLdapConnection extends Class { + TypeUnboundIdLdapConnection() { this.hasQualifiedName("com.unboundid.ldap.sdk", "LDAPConnection") } } +/** DEPRECATED: Alias for TypeUnboundIdLdapConnection */ +deprecated class TypeUnboundIdLDAPConnection = TypeUnboundIdLdapConnection; + /*--- Methods ---*/ /** A method with the name `setBaseDN` declared in `com.unboundid.ldap.sdk.SearchRequest`. */ class MethodUnboundIdSearchRequestSetBaseDN extends Method { @@ -89,25 +92,36 @@ class MethodUnboundIdFilterSimplifyFilter extends Method { } /** A method with the name `search` declared in `com.unboundid.ldap.sdk.LDAPConnection`. */ -class MethodUnboundIdLDAPConnectionSearch extends Method { - MethodUnboundIdLDAPConnectionSearch() { - this.getDeclaringType() instanceof TypeUnboundIdLDAPConnection and +class MethodUnboundIdLdapConnectionSearch extends Method { + MethodUnboundIdLdapConnectionSearch() { + this.getDeclaringType() instanceof TypeUnboundIdLdapConnection and this.hasName("search") } } +/** DEPRECATED: Alias for MethodUnboundIdLdapConnectionSearch */ +deprecated class MethodUnboundIdLDAPConnectionSearch = MethodUnboundIdLdapConnectionSearch; + /** A method with the name `asyncSearch` declared in `com.unboundid.ldap.sdk.LDAPConnection`. */ -class MethodUnboundIdLDAPConnectionAsyncSearch extends Method { - MethodUnboundIdLDAPConnectionAsyncSearch() { - this.getDeclaringType() instanceof TypeUnboundIdLDAPConnection and +class MethodUnboundIdLdapConnectionAsyncSearch extends Method { + MethodUnboundIdLdapConnectionAsyncSearch() { + this.getDeclaringType() instanceof TypeUnboundIdLdapConnection and this.hasName("asyncSearch") } } +/** DEPRECATED: Alias for MethodUnboundIdLdapConnectionAsyncSearch */ +deprecated class MethodUnboundIdLDAPConnectionAsyncSearch = + MethodUnboundIdLdapConnectionAsyncSearch; + /** A method with the name `searchForEntry` declared in `com.unboundid.ldap.sdk.LDAPConnection`. */ -class MethodUnboundIdLDAPConnectionSearchForEntry extends Method { - MethodUnboundIdLDAPConnectionSearchForEntry() { - this.getDeclaringType() instanceof TypeUnboundIdLDAPConnection and +class MethodUnboundIdLdapConnectionSearchForEntry extends Method { + MethodUnboundIdLdapConnectionSearchForEntry() { + this.getDeclaringType() instanceof TypeUnboundIdLdapConnection and this.hasName("searchForEntry") } } + +/** DEPRECATED: Alias for MethodUnboundIdLdapConnectionSearchForEntry */ +deprecated class MethodUnboundIdLDAPConnectionSearchForEntry = + MethodUnboundIdLdapConnectionSearchForEntry; diff --git a/java/ql/lib/semmle/code/java/frameworks/gwt/GwtXml.qll b/java/ql/lib/semmle/code/java/frameworks/gwt/GwtXml.qll index 3ac223be2d5..f3d5c58c0ce 100644 --- a/java/ql/lib/semmle/code/java/frameworks/gwt/GwtXml.qll +++ b/java/ql/lib/semmle/code/java/frameworks/gwt/GwtXml.qll @@ -5,7 +5,7 @@ import semmle.code.xml.XML /** * Holds if any `*.gwt.xml` files are included in this snapshot. */ -predicate isGwtXmlIncluded() { exists(GwtXmlFile webXML) } +predicate isGwtXmlIncluded() { exists(GwtXmlFile webXml) } /** A GWT module XML file with a `.gwt.xml` suffix. */ class GwtXmlFile extends XMLFile { diff --git a/java/ql/lib/semmle/code/java/frameworks/jOOQ.qll b/java/ql/lib/semmle/code/java/frameworks/jOOQ.qll index 8a6ee13ec57..0e74408bca1 100644 --- a/java/ql/lib/semmle/code/java/frameworks/jOOQ.qll +++ b/java/ql/lib/semmle/code/java/frameworks/jOOQ.qll @@ -10,8 +10,8 @@ import semmle.code.java.dataflow.ExternalFlow * and is prone to SQL injection. * https://www.jooq.org/doc/current/manual/sql-building/plain-sql/ */ -private class PlainSQLType extends Annotation { - PlainSQLType() { this.getType().hasQualifiedName("org.jooq", "PlainSQL") } +private class PlainSqlType extends Annotation { + PlainSqlType() { this.getType().hasQualifiedName("org.jooq", "PlainSQL") } } /** @@ -19,7 +19,7 @@ private class PlainSQLType extends Annotation { * first argument. */ predicate jOOQSqlMethod(Method m) { - m.getAnAnnotation() instanceof PlainSQLType and + m.getAnAnnotation() instanceof PlainSqlType and m.getParameterType(0) instanceof TypeString } diff --git a/java/ql/lib/semmle/code/java/frameworks/jackson/JacksonSerializability.qll b/java/ql/lib/semmle/code/java/frameworks/jackson/JacksonSerializability.qll index bf87e7fbc57..1fb2e377841 100644 --- a/java/ql/lib/semmle/code/java/frameworks/jackson/JacksonSerializability.qll +++ b/java/ql/lib/semmle/code/java/frameworks/jackson/JacksonSerializability.qll @@ -14,14 +14,17 @@ private import semmle.code.java.dataflow.ExternalFlow /** * A `@com.fasterxml.jackson.annotation.JsonIgnore` annoation. */ -class JacksonJSONIgnoreAnnotation extends NonReflectiveAnnotation { - JacksonJSONIgnoreAnnotation() { +class JacksonJsonIgnoreAnnotation extends NonReflectiveAnnotation { + JacksonJsonIgnoreAnnotation() { exists(AnnotationType anntp | anntp = this.getType() | anntp.hasQualifiedName("com.fasterxml.jackson.annotation", "JsonIgnore") ) } } +/** DEPRECATED: Alias for JacksonJsonIgnoreAnnotation */ +deprecated class JacksonJSONIgnoreAnnotation = JacksonJsonIgnoreAnnotation; + /** A type whose values may be serialized using the Jackson JSON framework. */ abstract class JacksonSerializableType extends Type { } @@ -143,7 +146,7 @@ class JacksonSerializableField extends SerializableField { not superType instanceof TypeObject and superType.fromSource() ) and - not this.getAnAnnotation() instanceof JacksonJSONIgnoreAnnotation + not this.getAnAnnotation() instanceof JacksonJsonIgnoreAnnotation } } @@ -155,7 +158,7 @@ class JacksonDeserializableField extends DeserializableField { not superType instanceof TypeObject and superType.fromSource() ) and - not this.getAnAnnotation() instanceof JacksonJSONIgnoreAnnotation + not this.getAnAnnotation() instanceof JacksonJsonIgnoreAnnotation } } diff --git a/java/ql/lib/semmle/code/java/frameworks/javaee/JavaServerFaces.qll b/java/ql/lib/semmle/code/java/frameworks/javaee/JavaServerFaces.qll index 1d6c08c4862..326bfe34381 100644 --- a/java/ql/lib/semmle/code/java/frameworks/javaee/JavaServerFaces.qll +++ b/java/ql/lib/semmle/code/java/frameworks/javaee/JavaServerFaces.qll @@ -67,8 +67,8 @@ class FacesComponent extends Class { ) or // Or in an XML file - exists(FacesConfigComponentClass componentClassXML | - this = componentClassXML.getFacesComponentClass() + exists(FacesConfigComponentClass componentClassXml | + this = componentClassXml.getFacesComponentClass() ) ) } diff --git a/java/ql/lib/semmle/code/java/frameworks/javaee/PersistenceXML.qll b/java/ql/lib/semmle/code/java/frameworks/javaee/PersistenceXML.qll index 82fc32baca2..077c2baf862 100644 --- a/java/ql/lib/semmle/code/java/frameworks/javaee/PersistenceXML.qll +++ b/java/ql/lib/semmle/code/java/frameworks/javaee/PersistenceXML.qll @@ -8,8 +8,8 @@ import java /** * A JavaEE persistence configuration XML file (persistence.xml). */ -class PersistenceXMLFile extends XMLFile { - PersistenceXMLFile() { this.getStem() = "persistence" } +class PersistenceXmlFile extends XMLFile { + PersistenceXmlFile() { this.getStem() = "persistence" } /** Gets the root XML element in this `persistence.xml` file. */ PersistenceXmlRoot getRoot() { result = this.getAChild() } @@ -26,10 +26,13 @@ class PersistenceXMLFile extends XMLFile { } } +/** DEPRECATED: Alias for PersistenceXmlFile */ +deprecated class PersistenceXMLFile = PersistenceXmlFile; + /** The root `persistence` XML element in a `persistence.xml` file. */ class PersistenceXmlRoot extends XMLElement { PersistenceXmlRoot() { - this.getParent() instanceof PersistenceXMLFile and + this.getParent() instanceof PersistenceXmlFile and this.getName() = "persistence" } diff --git a/java/ql/lib/semmle/code/java/frameworks/javaee/ejb/EJB.qll b/java/ql/lib/semmle/code/java/frameworks/javaee/ejb/EJB.qll index 58968c753ac..5a65891020a 100644 --- a/java/ql/lib/semmle/code/java/frameworks/javaee/ejb/EJB.qll +++ b/java/ql/lib/semmle/code/java/frameworks/javaee/ejb/EJB.qll @@ -22,7 +22,7 @@ class SessionEJB extends EJB { this.getAnAnnotation().getType().hasName("Stateless") or this.getAnAnnotation().getType().hasName("Stateful") or // XML deployment descriptor. - exists(EjbJarXMLFile f | + exists(EjbJarXmlFile f | this.getQualifiedName() = f.getASessionElement().getAnEjbClassElement().getACharactersSet().getCharacters() ) @@ -121,7 +121,7 @@ class StatefulSessionEJB extends SessionEJB { this.getAnAnnotation().getType().hasName("Stateful") or // XML deployment descriptor. - exists(EjbJarXMLFile f, EjbJarSessionElement se | + exists(EjbJarXmlFile f, EjbJarSessionElement se | se = f.getASessionElement() and this.getQualifiedName() = se.getAnEjbClassElement().getACharactersSet().getCharacters() and se.getASessionTypeElement().isStateful() @@ -138,7 +138,7 @@ class StatelessSessionEJB extends SessionEJB { this.getAnAnnotation().getType().hasName("Stateless") or // XML deployment descriptor. - exists(EjbJarXMLFile f, EjbJarSessionElement se | + exists(EjbJarXmlFile f, EjbJarSessionElement se | se = f.getASessionElement() and this.getQualifiedName() = se.getAnEjbClassElement().getACharactersSet().getCharacters() and se.getASessionTypeElement().isStateless() @@ -158,7 +158,7 @@ class MessageDrivenBean extends EJB { this.getAnAnnotation().getType().hasName("MessageDriven") or // XML deployment descriptor. - exists(EjbJarXMLFile f | + exists(EjbJarXmlFile f | this.getQualifiedName() = f.getAMessageDrivenElement().getAnEjbClassElement().getACharactersSet().getCharacters() ) @@ -174,7 +174,7 @@ class EntityEJB extends EJB { this instanceof EntityBean or // XML deployment descriptor. - exists(EjbJarXMLFile f | + exists(EjbJarXmlFile f | this.getQualifiedName() = f.getAnEntityElement().getAnEjbClassElement().getACharactersSet().getCharacters() ) @@ -245,14 +245,14 @@ abstract class BusinessInterface extends Interface { */ class XmlSpecifiedBusinessInterface extends BusinessInterface { XmlSpecifiedBusinessInterface() { - exists(EjbJarXMLFile f | + exists(EjbJarXmlFile f | this.getQualifiedName() = f.getASessionElement().getABusinessElement().getACharactersSet().getCharacters() ) } override SessionEJB getAnEJB() { - exists(EjbJarXMLFile f, EjbJarSessionElement se | + exists(EjbJarXmlFile f, EjbJarSessionElement se | se = f.getASessionElement() and this.getQualifiedName() = se.getABusinessElement().getACharactersSet().getCharacters() and result.getQualifiedName() = se.getAnEjbClassElement().getACharactersSet().getCharacters() @@ -260,14 +260,14 @@ class XmlSpecifiedBusinessInterface extends BusinessInterface { } override predicate isDeclaredLocal() { - exists(EjbJarXMLFile f | + exists(EjbJarXmlFile f | this.getQualifiedName() = f.getASessionElement().getABusinessLocalElement().getACharactersSet().getCharacters() ) } override predicate isDeclaredRemote() { - exists(EjbJarXMLFile f | + exists(EjbJarXmlFile f | this.getQualifiedName() = f.getASessionElement().getABusinessRemoteElement().getACharactersSet().getCharacters() ) @@ -411,7 +411,7 @@ class ExtendedRemoteInterface extends LegacyEjbRemoteInterface, RemoteEJBInterfa /** A legacy remote interface specified within an XML deployment descriptor. */ class XmlSpecifiedRemoteInterface extends LegacyEjbRemoteInterface { XmlSpecifiedRemoteInterface() { - exists(EjbJarXMLFile f | + exists(EjbJarXmlFile f | this.getQualifiedName() = f.getASessionElement().getARemoteElement().getACharactersSet().getCharacters() ) @@ -422,7 +422,7 @@ class XmlSpecifiedRemoteInterface extends LegacyEjbRemoteInterface { * for this legacy EJB remote interface. */ SessionEJB getAnEJB() { - exists(EjbJarXMLFile f, EjbJarSessionElement se | + exists(EjbJarXmlFile f, EjbJarSessionElement se | se = f.getASessionElement() and this.getQualifiedName() = se.getARemoteElement().getACharactersSet().getCharacters() and result.getQualifiedName() = se.getAnEjbClassElement().getACharactersSet().getCharacters() @@ -453,7 +453,7 @@ class AnnotatedRemoteHomeInterface extends LegacyEjbRemoteHomeInterface { /** A legacy remote home interface specified within an XML deployment descriptor. */ class XmlSpecifiedRemoteHomeInterface extends LegacyEjbRemoteHomeInterface { XmlSpecifiedRemoteHomeInterface() { - exists(EjbJarXMLFile f | + exists(EjbJarXmlFile f | this.getQualifiedName() = f.getASessionElement().getARemoteHomeElement().getACharactersSet().getCharacters() ) @@ -461,7 +461,7 @@ class XmlSpecifiedRemoteHomeInterface extends LegacyEjbRemoteHomeInterface { /** Gets an EJB to which this interface belongs. */ SessionEJB getAnEJB() { - exists(EjbJarXMLFile f, EjbJarSessionElement se | + exists(EjbJarXmlFile f, EjbJarSessionElement se | se = f.getASessionElement() and this.getQualifiedName() = se.getARemoteHomeElement().getACharactersSet().getCharacters() and result.getQualifiedName() = se.getAnEjbClassElement().getACharactersSet().getCharacters() @@ -478,7 +478,7 @@ class ExtendedLocalInterface extends LegacyEjbLocalInterface, LocalEJBInterface /** A legacy local interface specified within an XML deployment descriptor. */ class XmlSpecifiedLocalInterface extends LegacyEjbLocalInterface { XmlSpecifiedLocalInterface() { - exists(EjbJarXMLFile f | + exists(EjbJarXmlFile f | this.getQualifiedName() = f.getASessionElement().getALocalElement().getACharactersSet().getCharacters() ) @@ -486,7 +486,7 @@ class XmlSpecifiedLocalInterface extends LegacyEjbLocalInterface { /** Gets an EJB to which this interface belongs. */ SessionEJB getAnEJB() { - exists(EjbJarXMLFile f, EjbJarSessionElement se | + exists(EjbJarXmlFile f, EjbJarSessionElement se | se = f.getASessionElement() and this.getQualifiedName() = se.getALocalElement().getACharactersSet().getCharacters() and result.getQualifiedName() = se.getAnEjbClassElement().getACharactersSet().getCharacters() @@ -517,7 +517,7 @@ class AnnotatedLocalHomeInterface extends LegacyEjbLocalHomeInterface { /** A legacy local home interface specified within an XML deployment descriptor. */ class XmlSpecifiedLocalHomeInterface extends LegacyEjbLocalHomeInterface { XmlSpecifiedLocalHomeInterface() { - exists(EjbJarXMLFile f | + exists(EjbJarXmlFile f | this.getQualifiedName() = f.getASessionElement().getALocalHomeElement().getACharactersSet().getCharacters() ) @@ -525,7 +525,7 @@ class XmlSpecifiedLocalHomeInterface extends LegacyEjbLocalHomeInterface { /** Gets an EJB to which this interface belongs. */ SessionEJB getAnEJB() { - exists(EjbJarXMLFile f, EjbJarSessionElement se | + exists(EjbJarXmlFile f, EjbJarSessionElement se | se = f.getASessionElement() and this.getQualifiedName() = se.getALocalHomeElement().getACharactersSet().getCharacters() and result.getQualifiedName() = se.getAnEjbClassElement().getACharactersSet().getCharacters() diff --git a/java/ql/lib/semmle/code/java/frameworks/javaee/ejb/EJBJarXML.qll b/java/ql/lib/semmle/code/java/frameworks/javaee/ejb/EJBJarXML.qll index db89836ff9d..4122869ecdb 100644 --- a/java/ql/lib/semmle/code/java/frameworks/javaee/ejb/EJBJarXML.qll +++ b/java/ql/lib/semmle/code/java/frameworks/javaee/ejb/EJBJarXML.qll @@ -8,8 +8,8 @@ import java /** * An EJB deployment descriptor XML file named `ejb-jar.xml`. */ -class EjbJarXMLFile extends XMLFile { - EjbJarXMLFile() { this.getStem() = "ejb-jar" } +class EjbJarXmlFile extends XMLFile { + EjbJarXmlFile() { this.getStem() = "ejb-jar" } /** Gets the root `ejb-jar` XML element of this `ejb-jar.xml` file. */ EjbJarRootElement getRoot() { result = this.getAChild() } @@ -35,10 +35,13 @@ class EjbJarXMLFile extends XMLFile { } } +/** DEPRECATED: Alias for EjbJarXmlFile */ +deprecated class EjbJarXMLFile = EjbJarXmlFile; + /** The root `ejb-jar` XML element in an `ejb-jar.xml` file. */ class EjbJarRootElement extends XMLElement { EjbJarRootElement() { - this.getParent() instanceof EjbJarXMLFile and + this.getParent() instanceof EjbJarXmlFile and this.getName() = "ejb-jar" } diff --git a/java/ql/lib/semmle/code/java/frameworks/javaee/ejb/EJBRestrictions.qll b/java/ql/lib/semmle/code/java/frameworks/javaee/ejb/EJBRestrictions.qll index e5e459c93bc..23e1518c916 100644 --- a/java/ql/lib/semmle/code/java/frameworks/javaee/ejb/EJBRestrictions.qll +++ b/java/ql/lib/semmle/code/java/frameworks/javaee/ejb/EJBRestrictions.qll @@ -9,26 +9,6 @@ import EJB /** A method or constructor that may not be called from an EJB. */ abstract class ForbiddenCallable extends Callable { } -/** - * Specialized version of the `polyCalls(..)` predicate for the use - * case of finding "shortest" call chains from EJBs to forbidden - * methods. This is the same as `polyCalls(..)`, with two exceptions: - * - * - It does not consider calls into an EJB method. - * - It does not consider calls from "forbidden callables". - */ -private predicate ejbPolyCalls(Callable origin, Callable target) { - origin.polyCalls(target) and - not exists(EJB ejb | target = ejb.getACallable()) and - not origin instanceof ForbiddenCallable -} - -private predicate ejbPolyCallsPlus(Callable origin, Callable target) { - exists(EJB ejb | origin = ejb.getACallable() | ejbPolyCalls(origin, target)) - or - exists(Callable mid | ejbPolyCallsPlus(origin, mid) and ejbPolyCalls(mid, target)) -} - /** * Holds if there exists a call chain from an EJB-`Callable` `origin` to a `ForbiddenCallable` `target` * that does not contain any intermediate EJB-`Callable` or `ForbiddenCallable`, diff --git a/java/ql/lib/semmle/code/java/frameworks/javaee/jsf/JSFFacesContextXML.qll b/java/ql/lib/semmle/code/java/frameworks/javaee/jsf/JSFFacesContextXML.qll index 2d6721298a9..657df736c4c 100644 --- a/java/ql/lib/semmle/code/java/frameworks/javaee/jsf/JSFFacesContextXML.qll +++ b/java/ql/lib/semmle/code/java/frameworks/javaee/jsf/JSFFacesContextXML.qll @@ -8,19 +8,22 @@ import default * A JSF "application configuration resources file", typically called `faces-config.xml`, which * contains the configuration for a JSF application */ -class FacesConfigXMLFile extends XMLFile { - FacesConfigXMLFile() { +class FacesConfigXmlFile extends XMLFile { + FacesConfigXmlFile() { // Contains a single top-level XML node named "faces-Config". count(XMLElement e | e = this.getAChild()) = 1 and this.getAChild().getName() = "faces-config" } } +/** DEPRECATED: Alias for FacesConfigXmlFile */ +deprecated class FacesConfigXMLFile = FacesConfigXmlFile; + /** * An XML element in a `FacesConfigXMLFile`. */ -class FacesConfigXMLElement extends XMLElement { - FacesConfigXMLElement() { this.getFile() instanceof FacesConfigXMLFile } +class FacesConfigXmlElement extends XMLElement { + FacesConfigXmlElement() { this.getFile() instanceof FacesConfigXmlFile } /** * Gets the value for this element, with leading and trailing whitespace trimmed. @@ -28,17 +31,20 @@ class FacesConfigXMLElement extends XMLElement { string getValue() { result = this.allCharactersString().trim() } } +/** DEPRECATED: Alias for FacesConfigXmlElement */ +deprecated class FacesConfigXMLElement = FacesConfigXmlElement; + /** * An element in a JSF config file that declares a managed bean. */ -class FacesConfigManagedBean extends FacesConfigXMLElement { +class FacesConfigManagedBean extends FacesConfigXmlElement { FacesConfigManagedBean() { this.getName() = "managed-bean" } } /** * An element in a JSF config file that declares the Class of a managed bean. */ -class FacesConfigManagedBeanClass extends FacesConfigXMLElement { +class FacesConfigManagedBeanClass extends FacesConfigXmlElement { FacesConfigManagedBeanClass() { this.getName() = "managed-bean-class" and this.getParent() instanceof FacesConfigManagedBean @@ -53,14 +59,14 @@ class FacesConfigManagedBeanClass extends FacesConfigXMLElement { /** * An element in a JSF config file that declares a custom component. */ -class FacesConfigComponent extends FacesConfigXMLElement { +class FacesConfigComponent extends FacesConfigXmlElement { FacesConfigComponent() { this.getName() = "component" } } /** * An element in a JSF config file that declares the Class of a faces component. */ -class FacesConfigComponentClass extends FacesConfigXMLElement { +class FacesConfigComponentClass extends FacesConfigXmlElement { FacesConfigComponentClass() { this.getName() = "component-class" and this.getParent() instanceof FacesConfigComponent diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringAbstractRef.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringAbstractRef.qll index 685c22779f3..4dd4b0ab947 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringAbstractRef.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringAbstractRef.qll @@ -3,7 +3,7 @@ import semmle.code.java.frameworks.spring.SpringXMLElement import semmle.code.java.frameworks.spring.SpringBean /** A common supertype of `SpringRef` and `SpringIdRef`. */ -class SpringAbstractRef extends SpringXMLElement { +class SpringAbstractRef extends SpringXmlElement { SpringAbstractRef() { this.getName() = "idref" or this.getName() = "ref" @@ -29,7 +29,7 @@ class SpringAbstractRef extends SpringXMLElement { } /** Holds if `other` is also a reference and points to the same bean as this reference. */ - override predicate isSimilar(SpringXMLElement other) { + override predicate isSimilar(SpringXmlElement other) { exists(SpringAbstractRef otherRef | otherRef = other and this.getBean() = otherRef.getBean() diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringAlias.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringAlias.qll index a3aa0fd38ac..cbc4f025dac 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringAlias.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringAlias.qll @@ -3,7 +3,7 @@ import semmle.code.java.frameworks.spring.SpringXMLElement import semmle.code.java.frameworks.spring.SpringBean /** An `` element in Spring XML files. */ -class SpringAlias extends SpringXMLElement { +class SpringAlias extends SpringXmlElement { SpringAlias() { this.getName() = "alias" } /** Gets the value of the `alias` attribute. */ diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringArgType.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringArgType.qll index 285c34d48e4..bddf5f01f9e 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringArgType.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringArgType.qll @@ -2,7 +2,7 @@ import java import semmle.code.java.frameworks.spring.SpringXMLElement /** An `` element in Spring XML files. */ -class SpringArgType extends SpringXMLElement { +class SpringArgType extends SpringXmlElement { SpringArgType() { this.getName() = "arg-type" } /** Gets the value of the `match` attribute. */ diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringAttribute.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringAttribute.qll index 1f2f2a13e68..a20eef4d0d7 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringAttribute.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringAttribute.qll @@ -2,7 +2,7 @@ import java import semmle.code.java.frameworks.spring.SpringXMLElement /** An `` element in Spring XML files. */ -class SpringAttribute extends SpringXMLElement { +class SpringAttribute extends SpringXmlElement { SpringAttribute() { this.getName() = "attribute" } /** Gets the value of the `key` attribute. */ diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringAutowire.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringAutowire.qll index f387b40a547..b99dafecc65 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringAutowire.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringAutowire.qll @@ -58,8 +58,8 @@ class SpringBeanPropertySetterMethod extends Method { * * Confusingly, this is a different form of autowiring to the `@Autowired` annotation. */ -class SpringBeanXMLAutowiredSetterMethod extends Method { - SpringBeanXMLAutowiredSetterMethod() { +class SpringBeanXmlAutowiredSetterMethod extends Method { + SpringBeanXmlAutowiredSetterMethod() { // The bean as marked with some form of autowiring in the XML file. exists(string xmlAutowire | xmlAutowire = this.getDeclaringType().(SpringBeanRefType).getSpringBean().getAutowire() @@ -100,6 +100,9 @@ class SpringBeanXMLAutowiredSetterMethod extends Method { } } +/** DEPRECATED: Alias for SpringBeanXmlAutowiredSetterMethod */ +deprecated class SpringBeanXMLAutowiredSetterMethod = SpringBeanXmlAutowiredSetterMethod; + /** * A callable that is annotated with `@Autowired`. * diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringBean.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringBean.qll index 17a19c9a228..6b7636203e1 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringBean.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringBean.qll @@ -12,7 +12,7 @@ import semmle.code.java.frameworks.spring.SpringReplacedMethod */ /** A `` element in a Spring XML file. */ -class SpringBean extends SpringXMLElement { +class SpringBean extends SpringXmlElement { SpringBean() { this.getName() = "bean" and // Do not capture Camel beans, which are different @@ -268,7 +268,7 @@ class SpringBean extends SpringXMLElement { /** * Holds if this bean element has the same bean identifier as `other`. */ - override predicate isSimilar(SpringXMLElement other) { + override predicate isSimilar(SpringXmlElement other) { this.getBeanIdentifier() = other.(SpringBean).getBeanIdentifier() } diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringCamel.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringCamel.qll index 3cbbf6acf11..656837e6d5e 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringCamel.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringCamel.qll @@ -9,56 +9,71 @@ import semmle.code.java.frameworks.spring.SpringBean /** * An Apache Camel element in a Spring Beans file. */ -class SpringCamelXMLElement extends SpringXMLElement { - SpringCamelXMLElement() { getNamespace().getURI() = "http://camel.apache.org/schema/spring" } +class SpringCamelXmlElement extends SpringXmlElement { + SpringCamelXmlElement() { getNamespace().getURI() = "http://camel.apache.org/schema/spring" } } +/** DEPRECATED: Alias for SpringCamelXmlElement */ +deprecated class SpringCamelXMLElement = SpringCamelXmlElement; + /** * An element in a Spring beans file that defines an Apache Camel context. * * All Apache Camel Spring elements are nested within a `` or a ``. */ -class SpringCamelXMLContext extends SpringCamelXMLElement { - SpringCamelXMLContext() { getName() = "camelContext" } +class SpringCamelXmlContext extends SpringCamelXmlElement { + SpringCamelXmlContext() { getName() = "camelContext" } } +/** DEPRECATED: Alias for SpringCamelXmlContext */ +deprecated class SpringCamelXMLContext = SpringCamelXmlContext; + /** * An element in a Spring beans file that defines an Apache Camel route context. * * A `` is a fragment, containing route definitions, that can be included within a * ``. */ -class SpringCamelXMLRouteContext extends SpringCamelXMLElement { - SpringCamelXMLRouteContext() { getName() = "routeContext" } +class SpringCamelXmlRouteContext extends SpringCamelXmlElement { + SpringCamelXmlRouteContext() { getName() = "routeContext" } } +/** DEPRECATED: Alias for SpringCamelXmlRouteContext */ +deprecated class SpringCamelXMLRouteContext = SpringCamelXmlRouteContext; + /** * An element in a Spring beans files that defines an Apache Camel route. * * A Camel `` element defines how messages that match certain criteria are handled by Apache * Camel. */ -class SpringCamelXMLRoute extends SpringCamelXMLElement { - SpringCamelXMLRoute() { +class SpringCamelXmlRoute extends SpringCamelXmlElement { + SpringCamelXmlRoute() { // A route must either be in a `` or a ``. ( - getParent() instanceof SpringCamelXMLRouteContext or - getParent() instanceof SpringCamelXMLContext + getParent() instanceof SpringCamelXmlRouteContext or + getParent() instanceof SpringCamelXmlContext ) and getName() = "route" } } +/** DEPRECATED: Alias for SpringCamelXmlRoute */ +deprecated class SpringCamelXMLRoute = SpringCamelXmlRoute; + /** * An element in a Spring bean file that is logically contained in an Apache Camel route. */ -class SpringCamelXMLRouteElement extends SpringCamelXMLElement { - SpringCamelXMLRouteElement() { - getParent() instanceof SpringCamelXMLRoute or - getParent() instanceof SpringCamelXMLRouteElement +class SpringCamelXmlRouteElement extends SpringCamelXmlElement { + SpringCamelXmlRouteElement() { + getParent() instanceof SpringCamelXmlRoute or + getParent() instanceof SpringCamelXmlRouteElement } } +/** DEPRECATED: Alias for SpringCamelXmlRouteElement */ +deprecated class SpringCamelXMLRouteElement = SpringCamelXmlRouteElement; + /** * A reference to a Spring bean in an Apache Camel route defined in a Spring beans file. * @@ -66,8 +81,8 @@ class SpringCamelXMLRouteElement extends SpringCamelXMLElement { * specifies a Spring bean that should be called in response to messages that match the enclosing * route. */ -class SpringCamelXMLBeanRef extends SpringCamelXMLRouteElement { - SpringCamelXMLBeanRef() { getName() = "bean" } +class SpringCamelXmlBeanRef extends SpringCamelXmlRouteElement { + SpringCamelXmlBeanRef() { getName() = "bean" } /** * Gets the Spring bean that is referenced by this route bean definition, if any. @@ -83,6 +98,9 @@ class SpringCamelXMLBeanRef extends SpringCamelXMLRouteElement { RefType getBeanType() { result.getQualifiedName() = getAttribute("beanType").getValue() } } +/** DEPRECATED: Alias for SpringCamelXmlBeanRef */ +deprecated class SpringCamelXMLBeanRef = SpringCamelXmlBeanRef; + /** * A declaration of a target in an Apache Camel route defined in a Spring beans file. * @@ -90,8 +108,8 @@ class SpringCamelXMLBeanRef extends SpringCamelXMLRouteElement { * determines the type of the target. For example, if the scheme is "bean:" then the rest of the uri * consists of a bean name and optional method name. */ -class SpringCamelXMLToElement extends SpringCamelXMLRouteElement { - SpringCamelXMLToElement() { getName() = "to" } +class SpringCamelXmlToElement extends SpringCamelXmlRouteElement { + SpringCamelXmlToElement() { getName() = "to" } /** * Gets the URI attribute for this `` element. @@ -99,6 +117,9 @@ class SpringCamelXMLToElement extends SpringCamelXMLRouteElement { string getURI() { result = getAttribute("uri").getValue() } } +/** DEPRECATED: Alias for SpringCamelXmlToElement */ +deprecated class SpringCamelXMLToElement = SpringCamelXmlToElement; + /** * A declaration of a Apache Camel "method" expression defined in a Spring beans file. * @@ -107,8 +128,8 @@ class SpringCamelXMLToElement extends SpringCamelXMLRouteElement { * (when the "ref" or "bean" attributes are used), or a type that should be instantiated as a bean * (if "beanType" is used. */ -class SpringCamelXMLMethodElement extends SpringCamelXMLElement { - SpringCamelXMLMethodElement() { getName() = "method" } +class SpringCamelXmlMethodElement extends SpringCamelXmlElement { + SpringCamelXmlMethodElement() { getName() = "method" } /** * Gets the `SpringBean` that this method expression refers to. @@ -123,3 +144,6 @@ class SpringCamelXMLMethodElement extends SpringCamelXMLElement { */ RefType getBeanType() { result.getQualifiedName() = getAttribute("beanType").getValue() } } + +/** DEPRECATED: Alias for SpringCamelXmlMethodElement */ +deprecated class SpringCamelXMLMethodElement = SpringCamelXmlMethodElement; diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringComponentScan.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringComponentScan.qll index b2b507414d1..1c037adefd6 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringComponentScan.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringComponentScan.qll @@ -8,8 +8,8 @@ import semmle.code.xml.WebXML * An element in a Spring configuration file that configures which packages are considered to be * "base" packages when performing the Spring component scan. */ -class SpringXMLComponentScan extends SpringXMLElement { - SpringXMLComponentScan() { +class SpringXmlComponentScan extends SpringXmlElement { + SpringXmlComponentScan() { this.getName() = "component-scan" and this.getNamespace().getPrefix() = "context" } @@ -23,6 +23,9 @@ class SpringXMLComponentScan extends SpringXMLElement { string getAProfileExpr() { result = this.getSpringBeanFile().getAProfileExpr() } } +/** DEPRECATED: Alias for SpringXmlComponentScan */ +deprecated class SpringXMLComponentScan = SpringXmlComponentScan; + /** * An annotation of a class that configures which packages are considered to be "base" packages * when performing the Spring component scan. @@ -59,11 +62,11 @@ class SpringBasePackage extends string { exists(string basePackages | // Interpret the contexts of the `web.xml` "contextConfigLocation" parameter as a base package, // but only if the appropriate context class is chosen. - exists(WebXMLFile webXML | - webXML.getContextParamValue("contextClass") = + exists(WebXmlFile webXml | + webXml.getContextParamValue("contextClass") = "org.springframework.web.context.support.AnnotationConfigWebApplicationContext" | - basePackages = webXML.getContextParamValue("contextConfigLocation") + basePackages = webXml.getContextParamValue("contextConfigLocation") ) or exists(SpringComponent c, Annotation componentScan | @@ -75,7 +78,7 @@ class SpringBasePackage extends string { c.isLive() ) or - exists(SpringXMLComponentScan xmlComponentScan | + exists(SpringXmlComponentScan xmlComponentScan | basePackages = xmlComponentScan.getBasePackages() and // The component scan profile must be active, if one is specified. ( @@ -110,7 +113,7 @@ class SpringComponentAnnotation extends AnnotationType { * In order for Spring XML to be "enabled", XML must have been indexed into the snapshot, and that * XML must contain the appropriate Spring configuration files. */ -private predicate isSpringXMLEnabled() { exists(SpringXMLElement springXMLElement) } +private predicate isSpringXmlEnabled() { exists(SpringXmlElement springXmlElement) } /** * A Spring component class, identified by the presence of a particular annotation. @@ -178,7 +181,7 @@ class SpringComponent extends RefType { // only validate whether this class is ever picked up if XML indexing is enabled. If it's // enabled, then the package of this class must belong in one of the packages defined as a base // package. - not isSpringXMLEnabled() + not isSpringXmlEnabled() or exists(SpringBasePackage sbp | this.getPackage().getName().prefix(sbp.length() + 1) = sbp + "." or diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringConstructorArg.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringConstructorArg.qll index d9762d792f9..e434e53ca3d 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringConstructorArg.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringConstructorArg.qll @@ -5,7 +5,7 @@ import semmle.code.java.frameworks.spring.SpringAbstractRef import semmle.code.java.frameworks.spring.SpringValue /** A `` element in a Spring XML file. */ -class SpringConstructorArg extends SpringXMLElement { +class SpringConstructorArg extends SpringXmlElement { SpringConstructorArg() { this.getName() = "constructor-arg" } /** Holds if this `constructor-arg` element has an `index` attribute. */ diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringDescription.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringDescription.qll index a6a803a6275..34cf13a9571 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringDescription.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringDescription.qll @@ -6,6 +6,6 @@ import semmle.code.java.frameworks.spring.SpringXMLElement * * Its contents can be accessed using `SpringXMLElement.getContentString()`. */ -class SpringDescription extends SpringXMLElement { +class SpringDescription extends SpringXmlElement { SpringDescription() { this.getName() = "description" } } diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringEntry.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringEntry.qll index 128d1abd548..8ec02002af5 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringEntry.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringEntry.qll @@ -6,7 +6,7 @@ import semmle.code.java.frameworks.spring.SpringKey import semmle.code.java.frameworks.spring.SpringValue /** An `` element in Spring XML files. */ -class SpringEntry extends SpringXMLElement { +class SpringEntry extends SpringXmlElement { SpringEntry() { this.getName() = "entry" } /** Holds if this `entry` has a `key` attribute. */ diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringFlex.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringFlex.qll index 7ed0f78fd37..0d18749a63e 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringFlex.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringFlex.qll @@ -9,7 +9,7 @@ import semmle.code.java.frameworks.spring.SpringComponentScan import semmle.code.java.frameworks.spring.SpringXMLElement /** Represents a `` element in Spring XML files. */ -class SpringRemotingDestination extends SpringXMLElement { +class SpringRemotingDestination extends SpringXmlElement { SpringRemotingDestination() { this.getName() = "remoting-destination" } /** @@ -55,7 +55,12 @@ class SpringRemotingDestinationClass extends Class { /** * Gets the XML configuration of the remoting destination, if it was configured in XML. */ - SpringRemotingDestination getRemotingDestinationXML() { this = result.getSpringBean().getClass() } + SpringRemotingDestination getRemotingDestinationXml() { this = result.getSpringBean().getClass() } + + /** DEPRECATED: Alias for getRemotingDestinationXml */ + deprecated SpringRemotingDestination getRemotingDestinationXML() { + result = this.getRemotingDestinationXml() + } /** * Holds if the class is operating on an "include" or "exclude" basis. @@ -70,7 +75,7 @@ class SpringRemotingDestinationClass extends Class { m.hasAnnotation("org.springframework.flex.remoting", "RemotingInclude") ) or - exists(this.getRemotingDestinationXML().getAnIncludeMethod()) + exists(this.getRemotingDestinationXml().getAnIncludeMethod()) } /** @@ -81,10 +86,10 @@ class SpringRemotingDestinationClass extends Class { if this.isIncluding() then result.hasAnnotation("org.springframework.flex.remoting", "RemotingInclude") or - result.getName() = this.getRemotingDestinationXML().getAnIncludeMethod() + result.getName() = this.getRemotingDestinationXml().getAnIncludeMethod() else ( not result.hasAnnotation("org.springframework.flex.remoting", "RemotingExclude") and - not result.getName() = this.getRemotingDestinationXML().getAnExcludeMethod() + not result.getName() = this.getRemotingDestinationXml().getAnExcludeMethod() ) } } diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringImport.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringImport.qll index 72290764540..688a14da32e 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringImport.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringImport.qll @@ -2,7 +2,7 @@ import java import semmle.code.java.frameworks.spring.SpringXMLElement /** An `` element in a Spring XML file. */ -class SpringImport extends SpringXMLElement { +class SpringImport extends SpringXmlElement { SpringImport() { this.getName() = "import" } /** Gets the value of the `resource` attribute. */ diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringKey.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringKey.qll index 1b993b6bf9d..5f07b227706 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringKey.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringKey.qll @@ -2,6 +2,6 @@ import java import semmle.code.java.frameworks.spring.SpringXMLElement /** A `` element in Spring XML files. */ -class SpringKey extends SpringXMLElement { +class SpringKey extends SpringXmlElement { SpringKey() { this.getName() = "key" } } diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringLookupMethod.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringLookupMethod.qll index 81ef06c14c5..9dba22a3cb7 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringLookupMethod.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringLookupMethod.qll @@ -3,7 +3,7 @@ import semmle.code.java.frameworks.spring.SpringXMLElement import semmle.code.java.frameworks.spring.SpringBean /** A `` element in a Spring XML file. */ -class SpringLookupMethod extends SpringXMLElement { +class SpringLookupMethod extends SpringXmlElement { SpringLookupMethod() { this.getName() = "lookup-method" } /** Gets the value of the `bean` attribute. */ diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringMergable.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringMergable.qll index 2898a1d1e70..baef7d3b91a 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringMergable.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringMergable.qll @@ -4,7 +4,7 @@ import semmle.code.java.frameworks.spring.SpringXMLElement /** * A common superclass for mergeable Spring XML elements (`list`, `map`). */ -/*abstract*/ class SpringMergable extends SpringXMLElement { +/*abstract*/ class SpringMergable extends SpringXmlElement { string getMergeRaw() { result = this.getAttributeValueWithDefault("merge") } /** Holds if this element is merged, taking `default-merged` values in `` into account. */ diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringMeta.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringMeta.qll index 6e42dad820e..640305b313a 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringMeta.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringMeta.qll @@ -2,7 +2,7 @@ import java import semmle.code.java.frameworks.spring.SpringXMLElement /** A `` element in Spring XML files. */ -class SpringMeta extends SpringXMLElement { +class SpringMeta extends SpringXmlElement { SpringMeta() { this.getName() = "meta" } /** Gets the value of the `key` attribute. */ diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringNull.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringNull.qll index b46a888b4e0..c3f2c00a2b7 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringNull.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringNull.qll @@ -2,6 +2,6 @@ import java import semmle.code.java.frameworks.spring.SpringXMLElement /** A `` element in Spring XML files. */ -class SpringNull extends SpringXMLElement { +class SpringNull extends SpringXmlElement { SpringNull() { this.getName() = "null" } } diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringProp.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringProp.qll index fb4964e4b61..771370a3e7a 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringProp.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringProp.qll @@ -2,7 +2,7 @@ import java import semmle.code.java.frameworks.spring.SpringXMLElement /** A `` element in Spring XML files. */ -class SpringProp extends SpringXMLElement { +class SpringProp extends SpringXmlElement { SpringProp() { this.getName() = "prop" } /** Gets the value of the `key` attribute. */ diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringProperty.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringProperty.qll index cdf6a1f9bd0..06d5daefaa1 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringProperty.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringProperty.qll @@ -6,7 +6,7 @@ import semmle.code.java.frameworks.spring.SpringList import semmle.code.java.frameworks.spring.SpringValue /** A `` element in Spring XML files. */ -class SpringProperty extends SpringXMLElement { +class SpringProperty extends SpringXmlElement { SpringProperty() { this.getName() = "property" } override string toString() { result = this.getPropertyName() } @@ -55,7 +55,7 @@ class SpringProperty extends SpringXMLElement { * Holds if this property is similar to another property. * Currently only checks the property name and references to beans. */ - override predicate isSimilar(SpringXMLElement element) { + override predicate isSimilar(SpringXmlElement element) { exists(SpringProperty other | other = element and this.getPropertyName() = other.getPropertyName() | diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringQualifier.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringQualifier.qll index 3ac11e9e5f3..eb57b37efe0 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringQualifier.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringQualifier.qll @@ -2,7 +2,7 @@ import java import semmle.code.java.frameworks.spring.SpringXMLElement /** A `` element in a Spring XML file. */ -class SpringQualifier extends SpringXMLElement { +class SpringQualifier extends SpringXmlElement { SpringQualifier() { this.getName() = "qualifier" } /** Gets the name of the Java class of this qualifier. */ diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringReplacedMethod.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringReplacedMethod.qll index ae2e827e703..47e8d182898 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringReplacedMethod.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringReplacedMethod.qll @@ -3,7 +3,7 @@ import semmle.code.java.frameworks.spring.SpringXMLElement import semmle.code.java.frameworks.spring.SpringBean /** A `` element in a Spring XML file. */ -class SpringReplacedMethod extends SpringXMLElement { +class SpringReplacedMethod extends SpringXmlElement { SpringReplacedMethod() { this.getName() = "replaced-method" } /** Gets the value of the `name` attribute. */ diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringValue.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringValue.qll index 73c4098a8c2..55854d60f9c 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringValue.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringValue.qll @@ -2,7 +2,7 @@ import java import semmle.code.java.frameworks.spring.SpringXMLElement /** A `` element in a Spring XML file. */ -class SpringValue extends SpringXMLElement { +class SpringValue extends SpringXmlElement { SpringValue() { this.getName() = "value" } /** Gets the value of the `type` attribute. */ diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringXMLElement.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringXMLElement.qll index 943285d99a8..adaf69c5890 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringXMLElement.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringXMLElement.qll @@ -3,11 +3,11 @@ import semmle.code.java.frameworks.spring.SpringBeanFile import semmle.code.java.frameworks.spring.SpringBean /** A common superclass for all Spring XML elements. */ -class SpringXMLElement extends XMLElement { - SpringXMLElement() { this.getFile() instanceof SpringBeanFile } +class SpringXmlElement extends XMLElement { + SpringXmlElement() { this.getFile() instanceof SpringBeanFile } /** Gets a child of this Spring XML element. */ - SpringXMLElement getASpringChild() { result = this.getAChild() } + SpringXmlElement getASpringChild() { result = this.getAChild() } /** Gets the bean file of this XML element. */ SpringBeanFile getSpringBeanFile() { result = this.getFile() } @@ -27,13 +27,16 @@ class SpringXMLElement extends XMLElement { SpringBean getEnclosingBean() { if this instanceof SpringBean then result = this - else result = this.getParent().(SpringXMLElement).getEnclosingBean() + else result = this.getParent().(SpringXmlElement).getEnclosingBean() } /** * Overridden by subclasses. Used to match `value`, `property` and `ref` elements for similarity. */ - predicate isSimilar(SpringXMLElement other) { none() } + predicate isSimilar(SpringXmlElement other) { none() } string getContentString() { result = this.allCharactersString() } } + +/** DEPRECATED: Alias for SpringXmlElement */ +deprecated class SpringXMLElement = SpringXmlElement; diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/metrics/MetricSpringBean.qll b/java/ql/lib/semmle/code/java/frameworks/spring/metrics/MetricSpringBean.qll index 9cac47fa281..ffbc5c9e5ec 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/metrics/MetricSpringBean.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/metrics/MetricSpringBean.qll @@ -2,7 +2,7 @@ import semmle.code.java.frameworks.spring.SpringBean import semmle.code.java.frameworks.spring.SpringBeanFile import semmle.code.java.frameworks.spring.SpringEntry -predicate springDepends(SpringBean b1, SpringBean b2, SpringXMLElement cause) { +predicate springDepends(SpringBean b1, SpringBean b2, SpringXmlElement cause) { b1 != b2 and b1.getBeanParent() = b2 and cause = b1 @@ -63,7 +63,7 @@ class MetricSpringBean extends SpringBean { this.getSpringBeanFile() = result.getSpringBeanFile() } - SpringXMLElement getBeanDependencyCause(SpringBean dependency) { + SpringXmlElement getBeanDependencyCause(SpringBean dependency) { springDepends(this, dependency, result) } } diff --git a/java/ql/lib/semmle/code/java/frameworks/struts/StrutsActions.qll b/java/ql/lib/semmle/code/java/frameworks/struts/StrutsActions.qll index ebe6716e4f5..4d50dbf92ab 100644 --- a/java/ql/lib/semmle/code/java/frameworks/struts/StrutsActions.qll +++ b/java/ql/lib/semmle/code/java/frameworks/struts/StrutsActions.qll @@ -6,7 +6,7 @@ import semmle.code.java.frameworks.struts.StrutsXML * Gets the custom struts mapper class used for this `refType`, if any. */ private string getStrutsMapperClass(RefType refType) { - result = getRootXMLFile(refType).getConstantValue("struts.mapper.class") + result = getRootXmlFile(refType).getConstantValue("struts.mapper.class") } /** @@ -21,7 +21,7 @@ class Struts2ActionClass extends Class { or // If there is a struts.xml file, then any class that is specified as an action is considered // to be reflectively constructed. - exists(StrutsXMLAction strutsAction | this = strutsAction.getActionClass()) + exists(StrutsXmlAction strutsAction | this = strutsAction.getActionClass()) or // We have determined that this is an action class due to the conventions plugin. this instanceof Struts2ConventionActionClass @@ -64,7 +64,7 @@ class Struts2ActionClass extends Class { any() else ( // Use the default mapping - exists(StrutsXMLAction strutsAction | + exists(StrutsXmlAction strutsAction | this = strutsAction.getActionClass() and result = strutsAction.getActionMethod() ) diff --git a/java/ql/lib/semmle/code/java/frameworks/struts/StrutsConventions.qll b/java/ql/lib/semmle/code/java/frameworks/struts/StrutsConventions.qll index 0f38147ad13..fd9f14d4c6f 100644 --- a/java/ql/lib/semmle/code/java/frameworks/struts/StrutsConventions.qll +++ b/java/ql/lib/semmle/code/java/frameworks/struts/StrutsConventions.qll @@ -53,7 +53,7 @@ private predicate isStrutsConventionPluginUsed(RefType refType) { strutsConventionAnnotationUsedInFolder(getSourceFolder(refType.getCompilationUnit())) or // The struts configuration file for this file sets a convention property - getRootXMLFile(refType).getAConstant().getName().matches("struts.convention%") + getRootXmlFile(refType).getAConstant().getName().matches("struts.convention%") or // We've found the POM for this RefType, and it includes a dependency on the convention plugin exists(Pom pom | @@ -68,7 +68,7 @@ private predicate isStrutsConventionPluginUsed(RefType refType) { * We guess by identifying the "nearest" `struts.xml` configuration file, i.e. the Struts * configuration file with the lowest common ancestor to this file. */ -StrutsXMLFile getRootXMLFile(RefType refType) { +StrutsXmlFile getRootXmlFile(RefType refType) { exists(StrutsFolder strutsFolder | strutsFolder = refType.getFile().getParentContainer*() and strutsFolder.isUnique() @@ -77,14 +77,17 @@ StrutsXMLFile getRootXMLFile(RefType refType) { ) } +/** DEPRECATED: Alias for getRootXmlFile */ +deprecated StrutsXMLFile getRootXMLFile(RefType refType) { result = getRootXmlFile(refType) } + /** * Gets the suffix used for automatically identifying actions when using the convention plugin. * * If no configuration is supplied, or identified, the default is "Action". */ private string getConventionSuffix(RefType refType) { - if exists(getRootXMLFile(refType).getConstantValue("struts.convention.action.suffix")) - then result = getRootXMLFile(refType).getConstantValue("struts.convention.action.suffix") + if exists(getRootXmlFile(refType).getConstantValue("struts.convention.action.suffix")) + then result = getRootXmlFile(refType).getConstantValue("struts.convention.action.suffix") else result = "Action" } diff --git a/java/ql/lib/semmle/code/java/frameworks/struts/StrutsXML.qll b/java/ql/lib/semmle/code/java/frameworks/struts/StrutsXML.qll index 8e69c5d9a83..77285d98175 100644 --- a/java/ql/lib/semmle/code/java/frameworks/struts/StrutsXML.qll +++ b/java/ql/lib/semmle/code/java/frameworks/struts/StrutsXML.qll @@ -4,13 +4,16 @@ import semmle.code.xml.XML /** * Holds if any struts XML files are included in this snapshot. */ -predicate isStrutsXMLIncluded() { exists(StrutsXMLFile strutsXML) } +predicate isStrutsXmlIncluded() { exists(StrutsXmlFile strutsXml) } + +/** DEPRECATED: Alias for isStrutsXmlIncluded */ +deprecated predicate isStrutsXMLIncluded = isStrutsXmlIncluded/0; /** * A struts 2 configuration file. */ -abstract class StrutsXMLFile extends XMLFile { - StrutsXMLFile() { +abstract class StrutsXmlFile extends XMLFile { + StrutsXmlFile() { // Contains a single top-level XML node named "struts". count(XMLElement e | e = this.getAChild()) = 1 and this.getAChild().getName() = "struts" @@ -19,55 +22,64 @@ abstract class StrutsXMLFile extends XMLFile { /** * Gets a "root" struts configuration file that includes this file. */ - StrutsRootXMLFile getARoot() { result.getAnIncludedFile() = this } + StrutsRootXmlFile getARoot() { result.getAnIncludedFile() = this } /** * Gets a directly included file. */ - StrutsXMLFile getADirectlyIncludedFile() { - exists(StrutsXMLInclude include | include.getFile() = this | result = include.getIncludedFile()) + StrutsXmlFile getADirectlyIncludedFile() { + exists(StrutsXmlInclude include | include.getFile() = this | result = include.getIncludedFile()) } /** * Gets a transitively included file. */ - StrutsXMLFile getAnIncludedFile() { result = this.getADirectlyIncludedFile*() } + StrutsXmlFile getAnIncludedFile() { result = this.getADirectlyIncludedFile*() } /** * Gets a `` defined in this file, or an included file. */ - StrutsXMLConstant getAConstant() { result.getFile() = this.getAnIncludedFile() } + StrutsXmlConstant getAConstant() { result.getFile() = this.getAnIncludedFile() } /** * Gets the value of the constant with the given `name`. */ string getConstantValue(string name) { - exists(StrutsXMLConstant constant | constant = this.getAConstant() | + exists(StrutsXmlConstant constant | constant = this.getAConstant() | constant.getConstantName() = name and result = constant.getConstantValue() ) } } +/** DEPRECATED: Alias for StrutsXmlFile */ +deprecated class StrutsXMLFile = StrutsXmlFile; + /** * A Struts 2 "root" configuration XML file directly read by struts. * * Root configurations either have the name `struts.xml` or `struts-plugin.xml`. */ -class StrutsRootXMLFile extends StrutsXMLFile { - StrutsRootXMLFile() { +class StrutsRootXmlFile extends StrutsXmlFile { + StrutsRootXmlFile() { this.getBaseName() = "struts.xml" or this.getBaseName() = "struts-plugin.xml" } } +/** DEPRECATED: Alias for StrutsRootXmlFile */ +deprecated class StrutsRootXMLFile = StrutsRootXmlFile; + /** * A Struts 2 configuration XML file included, directly or indirectly, by a root Struts configuration. */ -class StrutsIncludedXMLFile extends StrutsXMLFile { - StrutsIncludedXMLFile() { exists(StrutsXMLInclude include | this = include.getIncludedFile()) } +class StrutsIncludedXmlFile extends StrutsXmlFile { + StrutsIncludedXmlFile() { exists(StrutsXmlInclude include | this = include.getIncludedFile()) } } +/** DEPRECATED: Alias for StrutsIncludedXmlFile */ +deprecated class StrutsIncludedXMLFile = StrutsIncludedXmlFile; + /** * A Folder which has one or more Struts 2 root configurations. */ @@ -75,7 +87,7 @@ class StrutsFolder extends Folder { StrutsFolder() { exists(Container c | c = this.getAChildContainer() | c instanceof StrutsFolder or - c instanceof StrutsXMLFile + c instanceof StrutsXmlFile ) } @@ -87,7 +99,7 @@ class StrutsFolder extends Folder { /** * Gets a struts root configuration that applies to this folder. */ - StrutsRootXMLFile getAStrutsRootFile() { + StrutsRootXmlFile getAStrutsRootFile() { result = this.getAChildContainer() or result = this.getAChildContainer().(StrutsFolder).getAStrutsRootFile() } @@ -96,8 +108,8 @@ class StrutsFolder extends Folder { /** * An XML element in a `StrutsXMLFile`. */ -class StrutsXMLElement extends XMLElement { - StrutsXMLElement() { this.getFile() instanceof StrutsXMLFile } +class StrutsXmlElement extends XMLElement { + StrutsXmlElement() { this.getFile() instanceof StrutsXmlFile } /** * Gets the value for this element, with leading and trailing whitespace trimmed. @@ -105,14 +117,17 @@ class StrutsXMLElement extends XMLElement { string getValue() { result = this.allCharactersString().trim() } } +/** DEPRECATED: Alias for StrutsXmlElement */ +deprecated class StrutsXMLElement = StrutsXmlElement; + /** * A `` element within a `struts.xml` file. * * This indicates that the file specified in the `file` attribute should be included in the struts * configuration. The file is looked up using the classpath. */ -class StrutsXMLInclude extends StrutsXMLElement { - StrutsXMLInclude() { this.getName() = "include" } +class StrutsXmlInclude extends StrutsXmlElement { + StrutsXmlInclude() { this.getName() = "include" } /** * Gets the XMLFile that we believe is included by this include statement. @@ -127,6 +142,9 @@ class StrutsXMLInclude extends StrutsXMLElement { } } +/** DEPRECATED: Alias for StrutsXmlInclude */ +deprecated class StrutsXMLInclude = StrutsXmlInclude; + /** * Escape a string for use as the matcher in a string.match(..) call. */ @@ -150,8 +168,8 @@ private predicate strutsWildcardMatching(string matches, string wildcardstring) /** * A `` element within a `struts.xml` file. */ -class StrutsXMLAction extends StrutsXMLElement { - StrutsXMLAction() { this.getName() = "action" } +class StrutsXmlAction extends StrutsXmlElement { + StrutsXmlAction() { this.getName() = "action" } /** * Gets the `Class` that is referenced by this Struts action. @@ -175,13 +193,19 @@ class StrutsXMLAction extends StrutsXMLElement { } } +/** DEPRECATED: Alias for StrutsXmlAction */ +deprecated class StrutsXMLAction = StrutsXmlAction; + /** * A `` property, representing a configuration parameter to struts. */ -class StrutsXMLConstant extends StrutsXMLElement { - StrutsXMLConstant() { this.getName() = "constant" } +class StrutsXmlConstant extends StrutsXmlElement { + StrutsXmlConstant() { this.getName() = "constant" } string getConstantName() { result = this.getAttribute("name").getValue() } string getConstantValue() { result = this.getAttribute("value").getValue() } } + +/** DEPRECATED: Alias for StrutsXmlConstant */ +deprecated class StrutsXMLConstant = StrutsXmlConstant; diff --git a/java/ql/lib/semmle/code/java/security/Encryption.qll b/java/ql/lib/semmle/code/java/security/Encryption.qll index e87ecd13043..218539418b0 100644 --- a/java/ql/lib/semmle/code/java/security/Encryption.qll +++ b/java/ql/lib/semmle/code/java/security/Encryption.qll @@ -17,10 +17,14 @@ class X509TrustManager extends RefType { X509TrustManager() { this.hasQualifiedName("javax.net.ssl", "X509TrustManager") } } -class HttpsURLConnection extends RefType { - HttpsURLConnection() { this.hasQualifiedName("javax.net.ssl", "HttpsURLConnection") } +/** The `javax.net.ssl.HttpsURLConnection` class. */ +class HttpsUrlConnection extends RefType { + HttpsUrlConnection() { this.hasQualifiedName("javax.net.ssl", "HttpsURLConnection") } } +/** DEPRECATED: Alias for HttpsUrlConnection */ +deprecated class HttpsURLConnection = HttpsUrlConnection; + class SSLSocketFactory extends RefType { SSLSocketFactory() { this.hasQualifiedName("javax.net.ssl", "SSLSocketFactory") } } @@ -105,22 +109,22 @@ class CreateSslEngineMethod extends Method { class SetConnectionFactoryMethod extends Method { SetConnectionFactoryMethod() { this.hasName("setSSLSocketFactory") and - this.getDeclaringType().getAnAncestor() instanceof HttpsURLConnection + this.getDeclaringType().getAnAncestor() instanceof HttpsUrlConnection } } class SetHostnameVerifierMethod extends Method { SetHostnameVerifierMethod() { this.hasName("setHostnameVerifier") and - this.getDeclaringType().getAnAncestor() instanceof HttpsURLConnection + this.getDeclaringType().getAnAncestor() instanceof HttpsUrlConnection } } -/** The `setDefaultHostnameVerifier` method of the class `javax.net.ssl.HttpsURLConnection`. */ +/** The `setDefaultHostnameVerifier` method of the class `javax.net.ssl.HttpsUrlConnection`. */ class SetDefaultHostnameVerifierMethod extends Method { SetDefaultHostnameVerifierMethod() { this.hasName("setDefaultHostnameVerifier") and - this.getDeclaringType().getAnAncestor() instanceof HttpsURLConnection + this.getDeclaringType().getAnAncestor() instanceof HttpsUrlConnection } } @@ -244,34 +248,6 @@ string getSecureAlgorithmRegex() { result = algorithmRegex(secureAlgorithmString(max(int i | exists(rankedSecureAlgorithm(i))))) } -/** - * DEPRECATED: Terminology has been updated. Use `getAnInsecureAlgorithmName()` - * instead. - */ -deprecated string algorithmBlacklist() { result = getAnInsecureAlgorithmName() } - -/** - * DEPRECATED: Terminology has been updated. Use - * `getAnInsecureHashAlgorithmName()` instead. - */ -deprecated string hashAlgorithmBlacklist() { result = getAnInsecureHashAlgorithmName() } - -/** - * DEPRECATED: Terminology has been updated. Use `getInsecureAlgorithmRegex()` instead. - */ -deprecated string algorithmBlacklistRegex() { result = getInsecureAlgorithmRegex() } - -/** - * DEPRECATED: Terminology has been updated. Use `getASecureAlgorithmName()` - * instead. - */ -deprecated string algorithmWhitelist() { result = getASecureAlgorithmName() } - -/** - * DEPRECATED: Terminology has been updated. Use `getSecureAlgorithmRegex()` instead. - */ -deprecated string algorithmWhitelistRegex() { result = getSecureAlgorithmRegex() } - /** * Any use of a cryptographic element that specifies an encryption * algorithm. For example, methods returning ciphers, decryption methods, diff --git a/java/ql/lib/semmle/code/java/security/ExternalAPIs.qll b/java/ql/lib/semmle/code/java/security/ExternalAPIs.qll index 0aee4aaf802..b4b8ea7fdd9 100644 --- a/java/ql/lib/semmle/code/java/security/ExternalAPIs.qll +++ b/java/ql/lib/semmle/code/java/security/ExternalAPIs.qll @@ -10,11 +10,14 @@ import semmle.code.java.dataflow.TaintTracking /** * A `Method` that is considered a "safe" external API from a security perspective. */ -abstract class SafeExternalAPIMethod extends Method { } +abstract class SafeExternalApiMethod extends Method { } + +/** DEPRECATED: Alias for SafeExternalApiMethod */ +deprecated class SafeExternalAPIMethod = SafeExternalApiMethod; /** The default set of "safe" external APIs. */ -private class DefaultSafeExternalAPIMethod extends SafeExternalAPIMethod { - DefaultSafeExternalAPIMethod() { +private class DefaultSafeExternalApiMethod extends SafeExternalApiMethod { + DefaultSafeExternalApiMethod() { this instanceof EqualsMethod or this.getName().regexpMatch("size|length|compareTo|getClass|lastIndexOf") @@ -53,11 +56,11 @@ private class DefaultSafeExternalAPIMethod extends SafeExternalAPIMethod { } /** A node representing data being passed to an external API. */ -class ExternalAPIDataNode extends DataFlow::Node { +class ExternalApiDataNode extends DataFlow::Node { Call call; int i; - ExternalAPIDataNode() { + ExternalApiDataNode() { ( // Argument to call to a method this.asExpr() = call.getArgument(i) @@ -79,7 +82,7 @@ class ExternalAPIDataNode extends DataFlow::Node { not exists(DataFlow::Node next | TaintTracking::localTaintStep(this, next)) and not exists(DataFlow::Node next | TaintTracking::defaultAdditionalTaintStep(this, next)) and // Not a call to a known safe external API - not call.getCallee() instanceof SafeExternalAPIMethod + not call.getCallee() instanceof SafeExternalApiMethod } /** Gets the called API `Method`. */ @@ -95,38 +98,47 @@ class ExternalAPIDataNode extends DataFlow::Node { } } -/** A configuration for tracking flow from `RemoteFlowSource`s to `ExternalAPIDataNode`s. */ -class UntrustedDataToExternalAPIConfig extends TaintTracking::Configuration { - UntrustedDataToExternalAPIConfig() { this = "UntrustedDataToExternalAPIConfig" } +/** DEPRECATED: Alias for ExternalApiDataNode */ +deprecated class ExternalAPIDataNode = ExternalApiDataNode; + +/** A configuration for tracking flow from `RemoteFlowSource`s to `ExternalApiDataNode`s. */ +class UntrustedDataToExternalApiConfig extends TaintTracking::Configuration { + UntrustedDataToExternalApiConfig() { this = "UntrustedDataToExternalAPIConfig" } override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } - override predicate isSink(DataFlow::Node sink) { sink instanceof ExternalAPIDataNode } + override predicate isSink(DataFlow::Node sink) { sink instanceof ExternalApiDataNode } } +/** 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) } +class UntrustedExternalApiDataNode extends ExternalApiDataNode { + UntrustedExternalApiDataNode() { any(UntrustedDataToExternalApiConfig c).hasFlow(_, 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) + any(UntrustedDataToExternalApiConfig c).hasFlow(result, this) } } -private newtype TExternalAPI = - TExternalAPIParameter(Method m, int index) { - exists(UntrustedExternalAPIDataNode n | +/** DEPRECATED: Alias for UntrustedExternalApiDataNode */ +deprecated class UntrustedExternalAPIDataNode = UntrustedExternalApiDataNode; + +private newtype TExternalApi = + TExternalApiParameter(Method m, int index) { + exists(UntrustedExternalApiDataNode n | m = n.getMethod() and index = n.getIndex() ) } /** An external API which is used with untrusted data. */ -class ExternalAPIUsedWithUntrustedData extends TExternalAPI { +class ExternalApiUsedWithUntrustedData extends TExternalApi { /** Gets a possibly untrusted use of this external API. */ - UntrustedExternalAPIDataNode getUntrustedDataNode() { - this = TExternalAPIParameter(result.getMethod(), result.getIndex()) + UntrustedExternalApiDataNode getUntrustedDataNode() { + this = TExternalApiParameter(result.getMethod(), result.getIndex()) } /** Gets the number of untrusted sources used with this external API. */ @@ -139,9 +151,12 @@ class ExternalAPIUsedWithUntrustedData extends TExternalAPI { exists(Method m, int index, string indexString | if index = -1 then indexString = "qualifier" else indexString = "param " + index | - this = TExternalAPIParameter(m, index) and + this = TExternalApiParameter(m, index) and result = m.getDeclaringType().getQualifiedName() + "." + m.getSignature() + " [" + indexString + "]" ) } } + +/** DEPRECATED: Alias for ExternalApiUsedWithUntrustedData */ +deprecated class ExternalAPIUsedWithUntrustedData = ExternalApiUsedWithUntrustedData; diff --git a/java/ql/lib/semmle/code/java/security/ImplicitPendingIntentsQuery.qll b/java/ql/lib/semmle/code/java/security/ImplicitPendingIntentsQuery.qll index 836b0dec30f..6a400d479a6 100644 --- a/java/ql/lib/semmle/code/java/security/ImplicitPendingIntentsQuery.qll +++ b/java/ql/lib/semmle/code/java/security/ImplicitPendingIntentsQuery.qll @@ -29,7 +29,7 @@ class ImplicitPendingIntentStartConf extends TaintTracking::Configuration { any(ImplicitPendingIntentAdditionalTaintStep c).step(node1, node2) } - override predicate isAdditionalFlowStep( + override predicate isAdditionalTaintStep( DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, DataFlow::FlowState state2 ) { diff --git a/java/ql/lib/semmle/code/java/security/RequestForgery.qll b/java/ql/lib/semmle/code/java/security/RequestForgery.qll index b7d3e4a8a77..e6efc13c8a5 100644 --- a/java/ql/lib/semmle/code/java/security/RequestForgery.qll +++ b/java/ql/lib/semmle/code/java/security/RequestForgery.qll @@ -7,6 +7,7 @@ import semmle.code.java.frameworks.spring.Spring import semmle.code.java.frameworks.JaxWS import semmle.code.java.frameworks.javase.Http import semmle.code.java.dataflow.DataFlow +import semmle.code.java.frameworks.Properties private import semmle.code.java.dataflow.StringPrefixes private import semmle.code.java.dataflow.ExternalFlow @@ -33,6 +34,20 @@ private class DefaultRequestForgeryAdditionalTaintStep extends RequestForgeryAdd } } +private class TypePropertiesRequestForgeryAdditionalTaintStep extends RequestForgeryAdditionalTaintStep { + override predicate propagatesTaint(DataFlow::Node pred, DataFlow::Node succ) { + exists(MethodAccess ma | + // Properties props = new Properties(); + // props.setProperty("jdbcUrl", tainted); + // Propagate tainted value to the qualifier `props` + ma.getMethod() instanceof PropertiesSetPropertyMethod and + ma.getArgument(0).(CompileTimeConstantExpr).getStringValue() = "jdbcUrl" and + pred.asExpr() = ma.getArgument(1) and + succ.asExpr() = ma.getQualifier() + ) + } +} + /** A data flow sink for server-side request forgery (SSRF) vulnerabilities. */ abstract class RequestForgerySink extends DataFlow::Node { } @@ -40,6 +55,10 @@ private class UrlOpenSinkAsRequestForgerySink extends RequestForgerySink { UrlOpenSinkAsRequestForgerySink() { sinkNode(this, "open-url") } } +private class JdbcUrlSinkAsRequestForgerySink extends RequestForgerySink { + JdbcUrlSinkAsRequestForgerySink() { sinkNode(this, "jdbc-url") } +} + /** A sanitizer for request forgery vulnerabilities. */ abstract class RequestForgerySanitizer extends DataFlow::Node { } diff --git a/java/ql/lib/semmle/code/java/security/RequestForgeryConfig.qll b/java/ql/lib/semmle/code/java/security/RequestForgeryConfig.qll index c93d3089dc9..c8a59f65b0e 100644 --- a/java/ql/lib/semmle/code/java/security/RequestForgeryConfig.qll +++ b/java/ql/lib/semmle/code/java/security/RequestForgeryConfig.qll @@ -18,7 +18,7 @@ class RequestForgeryConfiguration extends TaintTracking::Configuration { // Exclude results of remote HTTP requests: fetching something else based on that result // is no worse than following a redirect returned by the remote server, and typically // we're requesting a resource via https which we trust to only send us to safe URLs. - not source.asExpr().(MethodAccess).getCallee() instanceof URLConnectionGetInputStreamMethod + not source.asExpr().(MethodAccess).getCallee() instanceof UrlConnectionGetInputStreamMethod } override predicate isSink(DataFlow::Node sink) { sink instanceof RequestForgerySink } diff --git a/java/ql/lib/semmle/code/java/security/SensitiveLoggingQuery.qll b/java/ql/lib/semmle/code/java/security/SensitiveLoggingQuery.qll new file mode 100644 index 00000000000..df0db54f159 --- /dev/null +++ b/java/ql/lib/semmle/code/java/security/SensitiveLoggingQuery.qll @@ -0,0 +1,26 @@ +/** Provides configurations for sensitive logging queries. */ + +import java +import semmle.code.java.dataflow.ExternalFlow +import semmle.code.java.dataflow.TaintTracking +import semmle.code.java.security.SensitiveActions +import DataFlow + +/** A variable that may hold sensitive information, judging by its name. * */ +class CredentialExpr extends Expr { + CredentialExpr() { + exists(Variable v | this = v.getAnAccess() | + v.getName().regexpMatch([getCommonSensitiveInfoRegex(), "(?i).*(username).*"]) and + not v.isFinal() + ) + } +} + +/** A data-flow configuration for identifying potentially-sensitive data flowing to a log output. */ +class SensitiveLoggerConfiguration extends TaintTracking::Configuration { + SensitiveLoggerConfiguration() { this = "SensitiveLoggerConfiguration" } + + override predicate isSource(DataFlow::Node source) { source.asExpr() instanceof CredentialExpr } + + override predicate isSink(DataFlow::Node sink) { sinkNode(sink, "logging") } +} diff --git a/java/ql/lib/semmle/code/java/security/UnsafeDeserializationQuery.qll b/java/ql/lib/semmle/code/java/security/UnsafeDeserializationQuery.qll index 71a2492c70c..6d0ff888d82 100644 --- a/java/ql/lib/semmle/code/java/security/UnsafeDeserializationQuery.qll +++ b/java/ql/lib/semmle/code/java/security/UnsafeDeserializationQuery.qll @@ -28,8 +28,8 @@ private class ObjectInputStreamReadObjectMethod extends Method { } } -private class XMLDecoderReadObjectMethod extends Method { - XMLDecoderReadObjectMethod() { +private class XmlDecoderReadObjectMethod extends Method { + XmlDecoderReadObjectMethod() { this.getDeclaringType().hasQualifiedName("java.beans", "XMLDecoder") and this.hasName("readObject") } @@ -140,7 +140,7 @@ predicate unsafeDeserialization(MethodAccess ma, Expr sink) { .hasQualifiedName("org.apache.commons.io.serialization", "ValidatingObjectInputStream") ) or - m instanceof XMLDecoderReadObjectMethod and + m instanceof XmlDecoderReadObjectMethod and sink = ma.getQualifier() or m instanceof XStreamReadObjectMethod and diff --git a/java/ql/lib/semmle/code/java/security/XSS.qll b/java/ql/lib/semmle/code/java/security/XSS.qll index 6053e3f4511..23bda5b9964 100644 --- a/java/ql/lib/semmle/code/java/security/XSS.qll +++ b/java/ql/lib/semmle/code/java/security/XSS.qll @@ -50,8 +50,8 @@ private class DefaultXssSink extends XssSink { } /** A default sanitizer that considers numeric and boolean typed data safe for writing to output. */ -private class DefaultXSSSanitizer extends XssSanitizer { - DefaultXSSSanitizer() { +private class DefaultXssSanitizer extends XssSanitizer { + DefaultXssSanitizer() { this.getType() instanceof NumericType or this.getType() instanceof BooleanType or // Match `org.springframework.web.util.HtmlUtils.htmlEscape` and possibly other methods like it. diff --git a/java/ql/lib/semmle/code/java/security/XmlParsers.qll b/java/ql/lib/semmle/code/java/security/XmlParsers.qll index 376e7481590..0e925e435ba 100644 --- a/java/ql/lib/semmle/code/java/security/XmlParsers.qll +++ b/java/ql/lib/semmle/code/java/security/XmlParsers.qll @@ -358,21 +358,24 @@ class SafeXmlInputFactory extends VarAccess { /** * The class `org.jdom.input.SAXBuilder.` */ -class SAXBuilder extends RefType { - SAXBuilder() { +class SaxBuilder extends RefType { + SaxBuilder() { this.hasQualifiedName("org.jdom.input", "SAXBuilder") or this.hasQualifiedName("org.jdom2.input", "SAXBuilder") } } +/** DEPRECATED: Alias for SaxBuilder */ +deprecated class SAXBuilder = SaxBuilder; + /** * A call to `SAXBuilder.build.` */ -class SAXBuilderParse extends XmlParserCall { - SAXBuilderParse() { +class SaxBuilderParse extends XmlParserCall { + SaxBuilderParse() { exists(Method m | m = this.getMethod() and - m.getDeclaringType() instanceof SAXBuilder and + m.getDeclaringType() instanceof SaxBuilder and m.hasName("build") ) } @@ -380,19 +383,22 @@ class SAXBuilderParse extends XmlParserCall { override Expr getSink() { result = this.getArgument(0) } override predicate isSafe() { - exists(SafeSAXBuilderToSAXBuilderParseFlowConfig conf | conf.hasFlowToExpr(this.getQualifier())) + exists(SafeSaxBuilderToSaxBuilderParseFlowConfig conf | conf.hasFlowToExpr(this.getQualifier())) } } -private class SafeSAXBuilderToSAXBuilderParseFlowConfig extends DataFlow2::Configuration { - SafeSAXBuilderToSAXBuilderParseFlowConfig() { +/** DEPRECATED: Alias for SaxBuilderParse */ +deprecated class SAXBuilderParse = SaxBuilderParse; + +private class SafeSaxBuilderToSaxBuilderParseFlowConfig extends DataFlow2::Configuration { + SafeSaxBuilderToSaxBuilderParseFlowConfig() { this = "XmlParsers::SafeSAXBuilderToSAXBuilderParseFlowConfig" } - override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeSAXBuilder } + override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeSaxBuilder } override predicate isSink(DataFlow::Node sink) { - sink.asExpr() = any(SAXBuilderParse sax).getQualifier() + sink.asExpr() = any(SaxBuilderParse sax).getQualifier() } override int fieldFlowBranchLimit() { result = 0 } @@ -401,22 +407,25 @@ private class SafeSAXBuilderToSAXBuilderParseFlowConfig extends DataFlow2::Confi /** * A `ParserConfig` specific to `SAXBuilder`. */ -class SAXBuilderConfig extends ParserConfig { - SAXBuilderConfig() { +class SaxBuilderConfig extends ParserConfig { + SaxBuilderConfig() { exists(Method m | m = this.getMethod() and - m.getDeclaringType() instanceof SAXBuilder and + m.getDeclaringType() instanceof SaxBuilder and m.hasName("setFeature") ) } } -/** A safely configured `SAXBuilder`. */ -class SafeSAXBuilder extends VarAccess { - SafeSAXBuilder() { +/** DEPRECATED: Alias for SaxBuilderConfig */ +deprecated class SAXBuilderConfig = SaxBuilderConfig; + +/** A safely configured `SaxBuilder`. */ +class SafeSaxBuilder extends VarAccess { + SafeSaxBuilder() { exists(Variable v | v = this.getVariable() and - exists(SAXBuilderConfig config | config.getQualifier() = v.getAnAccess() | + exists(SaxBuilderConfig config | config.getQualifier() = v.getAnAccess() | config .enables(any(ConstantStringExpr s | s.getStringValue() = "http://apache.org/xml/features/disallow-doctype-decl" @@ -426,6 +435,9 @@ class SafeSAXBuilder extends VarAccess { } } +/** DEPRECATED: Alias for SafeSaxBuilder */ +deprecated class SafeSAXBuilder = SafeSaxBuilder; + /* * The case in * https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#jaxb-unmarshaller @@ -435,21 +447,27 @@ class SafeSAXBuilder extends VarAccess { /** * The class `javax.xml.parsers.SAXParser`. */ -class SAXParser extends RefType { - SAXParser() { this.hasQualifiedName("javax.xml.parsers", "SAXParser") } +class SaxParser extends RefType { + SaxParser() { this.hasQualifiedName("javax.xml.parsers", "SAXParser") } } -/** The class `javax.xml.parsers.SAXParserFactory`. */ -class SAXParserFactory extends RefType { - SAXParserFactory() { this.hasQualifiedName("javax.xml.parsers", "SAXParserFactory") } +/** DEPRECATED: Alias for SaxParser */ +deprecated class SAXParser = SaxParser; + +/** The class `javax.xml.parsers.SaxParserFactory`. */ +class SaxParserFactory extends RefType { + SaxParserFactory() { this.hasQualifiedName("javax.xml.parsers", "SAXParserFactory") } } -/** A call to `SAXParser.parse`. */ -class SAXParserParse extends XmlParserCall { - SAXParserParse() { +/** DEPRECATED: Alias for SaxParserFactory */ +deprecated class SAXParserFactory = SaxParserFactory; + +/** A call to `SaxParser.parse`. */ +class SaxParserParse extends XmlParserCall { + SaxParserParse() { exists(Method m | m = this.getMethod() and - m.getDeclaringType() instanceof SAXParser and + m.getDeclaringType() instanceof SaxParser and m.hasName("parse") ) } @@ -457,44 +475,50 @@ class SAXParserParse extends XmlParserCall { override Expr getSink() { result = this.getArgument(0) } override predicate isSafe() { - exists(SafeSAXParserFlowConfig sp | sp.hasFlowToExpr(this.getQualifier())) + exists(SafeSaxParserFlowConfig sp | sp.hasFlowToExpr(this.getQualifier())) } } -/** A `ParserConfig` that is specific to `SAXParserFactory`. */ -class SAXParserFactoryConfig extends ParserConfig { - SAXParserFactoryConfig() { +/** DEPRECATED: Alias for SaxParserParse */ +deprecated class SAXParserParse = SaxParserParse; + +/** A `ParserConfig` that is specific to `SaxParserFactory`. */ +class SaxParserFactoryConfig extends ParserConfig { + SaxParserFactoryConfig() { exists(Method m | m = this.getMethod() and - m.getDeclaringType() instanceof SAXParserFactory and + m.getDeclaringType() instanceof SaxParserFactory and m.hasName("setFeature") ) } } +/** DEPRECATED: Alias for SaxParserFactoryConfig */ +deprecated class SAXParserFactoryConfig = SaxParserFactoryConfig; + /** * A safely configured `SAXParserFactory`. */ -class SafeSAXParserFactory extends VarAccess { - SafeSAXParserFactory() { +class SafeSaxParserFactory extends VarAccess { + SafeSaxParserFactory() { exists(Variable v | v = this.getVariable() | - exists(SAXParserFactoryConfig config | config.getQualifier() = v.getAnAccess() | + exists(SaxParserFactoryConfig config | config.getQualifier() = v.getAnAccess() | config.enables(singleSafeConfig()) ) or - exists(SAXParserFactoryConfig config | config.getQualifier() = v.getAnAccess() | + exists(SaxParserFactoryConfig config | config.getQualifier() = v.getAnAccess() | config .disables(any(ConstantStringExpr s | s.getStringValue() = "http://xml.org/sax/features/external-general-entities" )) ) and - exists(SAXParserFactoryConfig config | config.getQualifier() = v.getAnAccess() | + exists(SaxParserFactoryConfig config | config.getQualifier() = v.getAnAccess() | config .disables(any(ConstantStringExpr s | s.getStringValue() = "http://xml.org/sax/features/external-parameter-entities" )) ) and - exists(SAXParserFactoryConfig config | config.getQualifier() = v.getAnAccess() | + exists(SaxParserFactoryConfig config | config.getQualifier() = v.getAnAccess() | config .disables(any(ConstantStringExpr s | s.getStringValue() = @@ -505,18 +529,21 @@ class SafeSAXParserFactory extends VarAccess { } } -private class SafeSAXParserFactoryToNewSAXParserFlowConfig extends DataFlow5::Configuration { - SafeSAXParserFactoryToNewSAXParserFlowConfig() { +/** DEPRECATED: Alias for SafeSaxParserFactory */ +deprecated class SafeSAXParserFactory = SafeSaxParserFactory; + +private class SafeSaxParserFactoryToNewSaxParserFlowConfig extends DataFlow5::Configuration { + SafeSaxParserFactoryToNewSaxParserFlowConfig() { this = "XmlParsers::SafeSAXParserFactoryToNewSAXParserFlowConfig" } - override 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) { exists(MethodAccess ma, Method m | sink.asExpr() = ma.getQualifier() and ma.getMethod() = m and - m.getDeclaringType() instanceof SAXParserFactory and + m.getDeclaringType() instanceof SaxParserFactory and m.hasName("newSAXParser") ) } @@ -524,45 +551,51 @@ private class SafeSAXParserFactoryToNewSAXParserFlowConfig extends DataFlow5::Co override int fieldFlowBranchLimit() { result = 0 } } -private class SafeSAXParserFlowConfig extends DataFlow4::Configuration { - SafeSAXParserFlowConfig() { this = "XmlParsers::SafeSAXParserFlowConfig" } +private class SafeSaxParserFlowConfig extends DataFlow4::Configuration { + SafeSaxParserFlowConfig() { this = "XmlParsers::SafeSAXParserFlowConfig" } - override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeSAXParser } + override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeSaxParser } override predicate isSink(DataFlow::Node sink) { exists(MethodAccess ma | - sink.asExpr() = ma.getQualifier() and ma.getMethod().getDeclaringType() instanceof SAXParser + sink.asExpr() = ma.getQualifier() and ma.getMethod().getDeclaringType() instanceof SaxParser ) } override int fieldFlowBranchLimit() { result = 0 } } -/** A `SAXParser` created from a safely configured `SAXParserFactory`. */ -class SafeSAXParser extends MethodAccess { - SafeSAXParser() { - exists(SafeSAXParserFactoryToNewSAXParserFlowConfig sdf | - this.getMethod().getDeclaringType() instanceof SAXParserFactory and +/** 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()) ) } } +/** DEPRECATED: Alias for SafeSaxParser */ +deprecated class SafeSAXParser = SafeSaxParser; + /* SAXReader: https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#saxreader */ /** * The class `org.dom4j.io.SAXReader`. */ -class SAXReader extends RefType { - SAXReader() { this.hasQualifiedName("org.dom4j.io", "SAXReader") } +class SaxReader extends RefType { + SaxReader() { this.hasQualifiedName("org.dom4j.io", "SAXReader") } } -/** A call to `SAXReader.read`. */ -class SAXReaderRead extends XmlParserCall { - SAXReaderRead() { +/** DEPRECATED: Alias for SaxReader */ +deprecated class SAXReader = SaxReader; + +/** A call to `SaxReader.read`. */ +class SaxReaderRead extends XmlParserCall { + SaxReaderRead() { exists(Method m | m = this.getMethod() and - m.getDeclaringType() instanceof SAXReader and + m.getDeclaringType() instanceof SaxReader and m.hasName("read") ) } @@ -570,52 +603,58 @@ class SAXReaderRead extends XmlParserCall { override Expr getSink() { result = this.getArgument(0) } override predicate isSafe() { - exists(SafeSAXReaderFlowConfig sr | sr.hasFlowToExpr(this.getQualifier())) + exists(SafeSaxReaderFlowConfig sr | sr.hasFlowToExpr(this.getQualifier())) } } -/** A `ParserConfig` specific to `SAXReader`. */ -class SAXReaderConfig extends ParserConfig { - SAXReaderConfig() { +/** DEPRECATED: Alias for SaxReaderRead */ +deprecated class SAXReaderRead = SaxReaderRead; + +/** A `ParserConfig` specific to `SaxReader`. */ +class SaxReaderConfig extends ParserConfig { + SaxReaderConfig() { exists(Method m | m = this.getMethod() and - m.getDeclaringType() instanceof SAXReader and + m.getDeclaringType() instanceof SaxReader and m.hasName("setFeature") ) } } -private class SafeSAXReaderFlowConfig extends DataFlow4::Configuration { - SafeSAXReaderFlowConfig() { this = "XmlParsers::SafeSAXReaderFlowConfig" } +/** DEPRECATED: Alias for SaxReaderConfig */ +deprecated class SAXReaderConfig = SaxReaderConfig; - override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeSAXReader } +private class SafeSaxReaderFlowConfig extends DataFlow4::Configuration { + SafeSaxReaderFlowConfig() { this = "XmlParsers::SafeSAXReaderFlowConfig" } + + override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeSaxReader } override predicate isSink(DataFlow::Node sink) { exists(MethodAccess ma | - sink.asExpr() = ma.getQualifier() and ma.getMethod().getDeclaringType() instanceof SAXReader + sink.asExpr() = ma.getQualifier() and ma.getMethod().getDeclaringType() instanceof SaxReader ) } override int fieldFlowBranchLimit() { result = 0 } } -/** A safely configured `SAXReader`. */ -class SafeSAXReader extends VarAccess { - SafeSAXReader() { +/** A safely configured `SaxReader`. */ +class SafeSaxReader extends VarAccess { + SafeSaxReader() { exists(Variable v | v = this.getVariable() | - exists(SAXReaderConfig config | config.getQualifier() = v.getAnAccess() | + exists(SaxReaderConfig config | config.getQualifier() = v.getAnAccess() | config .disables(any(ConstantStringExpr s | s.getStringValue() = "http://xml.org/sax/features/external-general-entities" )) ) and - exists(SAXReaderConfig config | config.getQualifier() = v.getAnAccess() | + exists(SaxReaderConfig config | config.getQualifier() = v.getAnAccess() | config .disables(any(ConstantStringExpr s | s.getStringValue() = "http://xml.org/sax/features/external-parameter-entities" )) ) and - exists(SAXReaderConfig config | config.getQualifier() = v.getAnAccess() | + exists(SaxReaderConfig config | config.getQualifier() = v.getAnAccess() | config .enables(any(ConstantStringExpr s | s.getStringValue() = "http://apache.org/xml/features/disallow-doctype-decl" @@ -625,18 +664,24 @@ class SafeSAXReader extends VarAccess { } } +/** DEPRECATED: Alias for SafeSaxReader */ +deprecated class SafeSAXReader = SafeSaxReader; + /* https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#xmlreader */ -/** The class `org.xml.sax.XMLReader`. */ -class XMLReader extends RefType { - XMLReader() { this.hasQualifiedName("org.xml.sax", "XMLReader") } +/** The class `org.xml.sax.XmlReader`. */ +class XmlReader extends RefType { + XmlReader() { this.hasQualifiedName("org.xml.sax", "XMLReader") } } -/** A call to `XMLReader.read`. */ -class XMLReaderParse extends XmlParserCall { - XMLReaderParse() { +/** DEPRECATED: Alias for XmlReader */ +deprecated class XMLReader = XmlReader; + +/** A call to `XmlReader.read`. */ +class XmlReaderParse extends XmlParserCall { + XmlReaderParse() { exists(Method m | m = this.getMethod() and - m.getDeclaringType() instanceof XMLReader and + m.getDeclaringType() instanceof XmlReader and m.hasName("parse") ) } @@ -644,59 +689,69 @@ class XMLReaderParse extends XmlParserCall { override Expr getSink() { result = this.getArgument(0) } override predicate isSafe() { - exists(ExplicitlySafeXMLReader sr | sr.flowsTo(this.getQualifier())) or - exists(CreatedSafeXMLReader cr | cr.flowsTo(this.getQualifier())) + exists(ExplicitlySafeXmlReader sr | sr.flowsTo(this.getQualifier())) or + exists(CreatedSafeXmlReader cr | cr.flowsTo(this.getQualifier())) } } -/** A `ParserConfig` specific to the `XMLReader`. */ -class XMLReaderConfig extends ParserConfig { - XMLReaderConfig() { +/** DEPRECATED: Alias for XmlReaderParse */ +deprecated class XMLReaderParse = XmlReaderParse; + +/** A `ParserConfig` specific to the `XmlReader`. */ +class XmlReaderConfig extends ParserConfig { + XmlReaderConfig() { exists(Method m | m = this.getMethod() and - m.getDeclaringType() instanceof XMLReader and + m.getDeclaringType() instanceof XmlReader and m.hasName("setFeature") ) } } -private class ExplicitlySafeXMLReaderFlowConfig extends DataFlow3::Configuration { - ExplicitlySafeXMLReaderFlowConfig() { this = "XmlParsers::ExplicitlySafeXMLReaderFlowConfig" } +/** DEPRECATED: Alias for XmlReaderConfig */ +deprecated class XMLReaderConfig = XmlReaderConfig; + +private class ExplicitlySafeXmlReaderFlowConfig extends DataFlow3::Configuration { + ExplicitlySafeXmlReaderFlowConfig() { this = "XmlParsers::ExplicitlySafeXMLReaderFlowConfig" } override predicate isSource(DataFlow::Node src) { - src.asExpr() instanceof ExplicitlySafeXMLReader + src.asExpr() instanceof ExplicitlySafeXmlReader } - override predicate isSink(DataFlow::Node sink) { sink.asExpr() instanceof SafeXMLReaderFlowSink } + override predicate isSink(DataFlow::Node sink) { sink.asExpr() instanceof SafeXmlReaderFlowSink } override int fieldFlowBranchLimit() { result = 0 } } -class SafeXMLReaderFlowSink extends Expr { - SafeXMLReaderFlowSink() { - this = any(XMLReaderParse p).getQualifier() or - this = any(ConstructedSAXSource s).getArgument(0) or - this = any(SAXSourceSetReader s).getArgument(0) +/** An argument to a safe XML reader. */ +class SafeXmlReaderFlowSink extends Expr { + SafeXmlReaderFlowSink() { + this = any(XmlReaderParse p).getQualifier() or + this = any(ConstructedSaxSource s).getArgument(0) or + this = any(SaxSourceSetReader s).getArgument(0) } } -/** An `XMLReader` that is explicitly configured to be safe. */ -class ExplicitlySafeXMLReader extends VarAccess { - ExplicitlySafeXMLReader() { +/** DEPRECATED: Alias for SafeXmlReaderFlowSink */ +deprecated class SafeXMLReaderFlowSink = SafeXmlReaderFlowSink; + +/** An `XmlReader` that is explicitly configured to be safe. */ +class ExplicitlySafeXmlReader extends VarAccess { + ExplicitlySafeXmlReader() { exists(Variable v | v = this.getVariable() | - exists(XMLReaderConfig config | config.getQualifier() = v.getAnAccess() | + exists(XmlReaderConfig config | config.getQualifier() = v.getAnAccess() | config .disables(any(ConstantStringExpr s | s.getStringValue() = "http://xml.org/sax/features/external-general-entities" )) ) and - exists(XMLReaderConfig config | config.getQualifier() = v.getAnAccess() | + exists(XmlReaderConfig config | config.getQualifier() = v.getAnAccess() | config .disables(any(ConstantStringExpr s | s.getStringValue() = "http://xml.org/sax/features/external-parameter-entities" )) ) and - exists(XMLReaderConfig config | config.getQualifier() = v.getAnAccess() | + exists(XmlReaderConfig config | config.getQualifier() = v.getAnAccess() | config .disables(any(ConstantStringExpr s | s.getStringValue() = @@ -704,7 +759,7 @@ class ExplicitlySafeXMLReader extends VarAccess { )) ) or - exists(XMLReaderConfig config | config.getQualifier() = v.getAnAccess() | + exists(XmlReaderConfig config | config.getQualifier() = v.getAnAccess() | config .enables(any(ConstantStringExpr s | s.getStringValue() = "http://apache.org/xml/features/disallow-doctype-decl" @@ -713,35 +768,39 @@ class ExplicitlySafeXMLReader extends VarAccess { ) } - predicate flowsTo(SafeXMLReaderFlowSink sink) { - any(ExplicitlySafeXMLReaderFlowConfig conf) + /** Holds if `SafeXmlReaderFlowSink` detects flow from this to `sink` */ + predicate flowsTo(SafeXmlReaderFlowSink sink) { + any(ExplicitlySafeXmlReaderFlowConfig conf) .hasFlow(DataFlow::exprNode(this), DataFlow::exprNode(sink)) } } -private class CreatedSafeXMLReaderFlowConfig extends DataFlow3::Configuration { - CreatedSafeXMLReaderFlowConfig() { this = "XmlParsers::CreatedSafeXMLReaderFlowConfig" } +/** DEPRECATED: Alias for ExplicitlySafeXmlReader */ +deprecated class ExplicitlySafeXMLReader = ExplicitlySafeXmlReader; - override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof CreatedSafeXMLReader } +private class CreatedSafeXmlReaderFlowConfig extends DataFlow3::Configuration { + CreatedSafeXmlReaderFlowConfig() { this = "XmlParsers::CreatedSafeXMLReaderFlowConfig" } - override predicate isSink(DataFlow::Node sink) { sink.asExpr() instanceof SafeXMLReaderFlowSink } + override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof CreatedSafeXmlReader } + + override predicate isSink(DataFlow::Node sink) { sink.asExpr() instanceof SafeXmlReaderFlowSink } override int fieldFlowBranchLimit() { result = 0 } } -/** An `XMLReader` that is obtained from a safe source. */ -class CreatedSafeXMLReader extends Call { - CreatedSafeXMLReader() { +/** 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 + exists(SafeSaxParserFlowConfig safeParser | + this.(MethodAccess).getMethod().getDeclaringType() instanceof SaxParser and this.(MethodAccess).getMethod().hasName("getXMLReader") and safeParser.hasFlowToExpr(this.getQualifier()) ) or //Obtained from SAXReader - exists(SafeSAXReaderFlowConfig safeReader | - this.(MethodAccess).getMethod().getDeclaringType() instanceof SAXReader and + exists(SafeSaxReaderFlowConfig safeReader | + this.(MethodAccess).getMethod().getDeclaringType() instanceof SaxReader and this.(MethodAccess).getMethod().hasName("getXMLReader") and safeReader.hasFlowToExpr(this.getQualifier()) ) @@ -753,28 +812,35 @@ class CreatedSafeXMLReader extends Call { ) } - predicate flowsTo(SafeXMLReaderFlowSink sink) { - any(CreatedSafeXMLReaderFlowConfig conf) + /** Holds if `CreatedSafeXmlReaderFlowConfig` detects flow from this to `sink` */ + predicate flowsTo(SafeXmlReaderFlowSink sink) { + any(CreatedSafeXmlReaderFlowConfig conf) .hasFlow(DataFlow::exprNode(this), DataFlow::exprNode(sink)) } } +/** DEPRECATED: Alias for CreatedSafeXmlReader */ +deprecated class CreatedSafeXMLReader = CreatedSafeXmlReader; + /* * SAXSource in * https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#jaxb-unmarshaller */ -/** The class `javax.xml.transform.sax.SAXSource` */ -class SAXSource extends RefType { - SAXSource() { this.hasQualifiedName("javax.xml.transform.sax", "SAXSource") } +/** The class `javax.xml.transform.sax.SaxSource` */ +class SaxSource extends RefType { + SaxSource() { this.hasQualifiedName("javax.xml.transform.sax", "SAXSource") } } -/** A call to the constructor of `SAXSource` with `XMLReader` and `InputSource`. */ -class ConstructedSAXSource extends ClassInstanceExpr { - ConstructedSAXSource() { - this.getConstructedType() instanceof SAXSource and +/** DEPRECATED: Alias for SaxSource */ +deprecated class SAXSource = SaxSource; + +/** A call to the constructor of `SaxSource` with `XmlReader` and `InputSource`. */ +class ConstructedSaxSource extends ClassInstanceExpr { + ConstructedSaxSource() { + this.getConstructedType() instanceof SaxSource and this.getNumArgument() = 2 and - this.getArgument(0).getType() instanceof XMLReader + this.getArgument(0).getType() instanceof XmlReader } /** @@ -782,40 +848,49 @@ class ConstructedSAXSource extends ClassInstanceExpr { */ Expr getSink() { result = this.getArgument(1) } - /** Holds if the resulting `SAXSource` is safe. */ + /** Holds if the resulting `SaxSource` is safe. */ predicate isSafe() { - exists(CreatedSafeXMLReader safeReader | safeReader.flowsTo(this.getArgument(0))) or - exists(ExplicitlySafeXMLReader safeReader | safeReader.flowsTo(this.getArgument(0))) + exists(CreatedSafeXmlReader safeReader | safeReader.flowsTo(this.getArgument(0))) or + exists(ExplicitlySafeXmlReader safeReader | safeReader.flowsTo(this.getArgument(0))) } } -/** A call to the `SAXSource.setXMLReader` method. */ -class SAXSourceSetReader extends MethodAccess { - SAXSourceSetReader() { +/** DEPRECATED: Alias for ConstructedSaxSource */ +deprecated class ConstructedSAXSource = ConstructedSaxSource; + +/** A call to the `SaxSource.setXMLReader` method. */ +class SaxSourceSetReader extends MethodAccess { + SaxSourceSetReader() { exists(Method m | m = this.getMethod() and - m.getDeclaringType() instanceof SAXSource and + m.getDeclaringType() instanceof SaxSource and m.hasName("setXMLReader") ) } } -/** A `SAXSource` that is safe to use. */ -class SafeSAXSource extends Expr { - SafeSAXSource() { +/** DEPRECATED: Alias for SaxSourceSetReader */ +deprecated class SAXSourceSetReader = SaxSourceSetReader; + +/** A `SaxSource` that is safe to use. */ +class SafeSaxSource extends Expr { + SafeSaxSource() { exists(Variable v | v = this.(VarAccess).getVariable() | - exists(SAXSourceSetReader s | s.getQualifier() = v.getAnAccess() | + exists(SaxSourceSetReader s | s.getQualifier() = v.getAnAccess() | ( - exists(CreatedSafeXMLReader safeReader | safeReader.flowsTo(s.getArgument(0))) or - exists(ExplicitlySafeXMLReader safeReader | safeReader.flowsTo(s.getArgument(0))) + exists(CreatedSafeXmlReader safeReader | safeReader.flowsTo(s.getArgument(0))) or + exists(ExplicitlySafeXmlReader safeReader | safeReader.flowsTo(s.getArgument(0))) ) ) ) or - this.(ConstructedSAXSource).isSafe() + this.(ConstructedSaxSource).isSafe() } } +/** DEPRECATED: Alias for SafeSaxSource */ +deprecated class SafeSAXSource = SafeSaxSource; + /* Transformer: https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#transformerfactory */ /** An access to a method use for configuring a transformer or schema. */ abstract class TransformerConfig extends MethodAccess { @@ -992,8 +1067,8 @@ class SafeTransformer extends MethodAccess { */ /** A call to `SAXTransformerFactory.newFilter`. */ -class SAXTransformerFactoryNewXMLFilter extends XmlParserCall { - SAXTransformerFactoryNewXMLFilter() { +class SaxTransformerFactoryNewXmlFilter extends XmlParserCall { + SaxTransformerFactoryNewXmlFilter() { exists(Method m | this.getMethod() = m and m.getDeclaringType().hasQualifiedName("javax.xml.transform.sax", "SAXTransformerFactory") and @@ -1008,6 +1083,9 @@ class SAXTransformerFactoryNewXMLFilter extends XmlParserCall { } } +/** DEPRECATED: Alias for SaxTransformerFactoryNewXmlFilter */ +deprecated class SAXTransformerFactoryNewXMLFilter = SaxTransformerFactoryNewXmlFilter; + /* Schema: https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#schemafactory */ /** The class `javax.xml.validation.SchemaFactory`. */ class SchemaFactory extends RefType { @@ -1116,8 +1194,8 @@ class XPathEvaluate extends XmlParserCall { // Sink methods in simplexml http://simple.sourceforge.net/home.php /** A call to `read` or `validate` in `Persister`. */ -class SimpleXMLPersisterCall extends XmlParserCall { - SimpleXMLPersisterCall() { +class SimpleXmlPersisterCall extends XmlParserCall { + SimpleXmlPersisterCall() { exists(Method m | this.getMethod() = m and (m.hasName("validate") or m.hasName("read")) and @@ -1130,9 +1208,12 @@ class SimpleXMLPersisterCall extends XmlParserCall { override predicate isSafe() { none() } } +/** DEPRECATED: Alias for SimpleXmlPersisterCall */ +deprecated class SimpleXMLPersisterCall = SimpleXmlPersisterCall; + /** A call to `provide` in `Provider`. */ -class SimpleXMLProviderCall extends XmlParserCall { - SimpleXMLProviderCall() { +class SimpleXmlProviderCall extends XmlParserCall { + SimpleXmlProviderCall() { exists(Method m | this.getMethod() = m and m.hasName("provide") and @@ -1148,9 +1229,12 @@ class SimpleXMLProviderCall extends XmlParserCall { override predicate isSafe() { none() } } +/** DEPRECATED: Alias for SimpleXmlProviderCall */ +deprecated class SimpleXMLProviderCall = SimpleXmlProviderCall; + /** A call to `read` in `NodeBuilder`. */ -class SimpleXMLNodeBuilderCall extends XmlParserCall { - SimpleXMLNodeBuilderCall() { +class SimpleXmlNodeBuilderCall extends XmlParserCall { + SimpleXmlNodeBuilderCall() { exists(Method m | this.getMethod() = m and m.hasName("read") and @@ -1163,9 +1247,12 @@ class SimpleXMLNodeBuilderCall extends XmlParserCall { override predicate isSafe() { none() } } +/** DEPRECATED: Alias for SimpleXmlNodeBuilderCall */ +deprecated class SimpleXMLNodeBuilderCall = SimpleXmlNodeBuilderCall; + /** A call to the `format` method of the `Formatter`. */ -class SimpleXMLFormatterCall extends XmlParserCall { - SimpleXMLFormatterCall() { +class SimpleXmlFormatterCall extends XmlParserCall { + SimpleXmlFormatterCall() { exists(Method m | this.getMethod() = m and m.hasName("format") and @@ -1178,6 +1265,9 @@ class SimpleXMLFormatterCall extends XmlParserCall { override predicate isSafe() { none() } } +/** DEPRECATED: Alias for SimpleXmlFormatterCall */ +deprecated class SimpleXMLFormatterCall = SimpleXmlFormatterCall; + /** A configuration for secure processing. */ Expr configSecureProcessing() { result.(ConstantStringExpr).getStringValue() = diff --git a/java/ql/lib/semmle/code/java/security/XsltInjection.qll b/java/ql/lib/semmle/code/java/security/XsltInjection.qll index 75288492004..db96879181c 100644 --- a/java/ql/lib/semmle/code/java/security/XsltInjection.qll +++ b/java/ql/lib/semmle/code/java/security/XsltInjection.qll @@ -112,7 +112,7 @@ private predicate documentBuilderStep(DataFlow::Node n1, DataFlow::Node n2) { * `new DOMSource(tainted)`. */ private predicate domSourceStep(DataFlow::Node n1, DataFlow::Node n2) { - exists(ConstructorCall cc | cc.getConstructedType() instanceof TypeDOMSource | + exists(ConstructorCall cc | cc.getConstructedType() instanceof TypeDomSource | n1.asExpr() = cc.getAnArgument() and n2.asExpr() = cc ) @@ -179,8 +179,8 @@ private class TypeStAXSource extends Class { } /** The class `javax.xml.transform.dom.DOMSource`. */ -private class TypeDOMSource extends Class { - TypeDOMSource() { this.hasQualifiedName("javax.xml.transform.dom", "DOMSource") } +private class TypeDomSource extends Class { + TypeDomSource() { this.hasQualifiedName("javax.xml.transform.dom", "DOMSource") } } /** The interface `javax.xml.transform.Templates`. */ diff --git a/java/ql/lib/semmle/code/xml/WebXML.qll b/java/ql/lib/semmle/code/xml/WebXML.qll index c7dec5fd600..67e46b10026 100644 --- a/java/ql/lib/semmle/code/xml/WebXML.qll +++ b/java/ql/lib/semmle/code/xml/WebXML.qll @@ -3,13 +3,16 @@ import java /** * Holds if any `web.xml` files are included in this snapshot. */ -predicate isWebXMLIncluded() { exists(WebXMLFile webXML) } +predicate isWebXmlIncluded() { exists(WebXmlFile webXml) } + +/** DEPRECATED: Alias for isWebXmlIncluded */ +deprecated predicate isWebXMLIncluded = isWebXmlIncluded/0; /** * A deployment descriptor file, typically called `web.xml`. */ -class WebXMLFile extends XMLFile { - WebXMLFile() { +class WebXmlFile extends XMLFile { + WebXmlFile() { count(XMLElement e | e = this.getAChild()) = 1 and this.getAChild().getName() = "web-app" } @@ -28,11 +31,14 @@ class WebXMLFile extends XMLFile { } } +/** DEPRECATED: Alias for WebXmlFile */ +deprecated class WebXMLFile = WebXmlFile; + /** * An XML element in a `WebXMLFile`. */ -class WebXMLElement extends XMLElement { - WebXMLElement() { this.getFile() instanceof WebXMLFile } +class WebXmlElement extends XMLElement { + WebXmlElement() { this.getFile() instanceof WebXmlFile } /** * Gets the value for this element, with leading and trailing whitespace trimmed. @@ -40,10 +46,13 @@ class WebXMLElement extends XMLElement { string getValue() { result = this.allCharactersString().trim() } } +/** DEPRECATED: Alias for WebXmlElement */ +deprecated class WebXMLElement = WebXmlElement; + /** * A `` element in a `web.xml` file. */ -class WebContextParameter extends WebXMLElement { +class WebContextParameter extends WebXmlElement { WebContextParameter() { this.getName() = "context-param" } /** @@ -60,28 +69,28 @@ class WebContextParameter extends WebXMLElement { /** * A `` element in a `web.xml` file. */ -class WebContextParamName extends WebXMLElement { +class WebContextParamName extends WebXmlElement { WebContextParamName() { this.getName() = "param-name" } } /** * A `` element in a `web.xml` file. */ -class WebContextParamValue extends WebXMLElement { +class WebContextParamValue extends WebXmlElement { WebContextParamValue() { this.getName() = "param-value" } } /** * A `` element in a `web.xml` file. */ -class WebFilter extends WebXMLElement { +class WebFilter extends WebXmlElement { WebFilter() { this.getName() = "filter" } } /** * A `` element in a `web.xml` file, nested under a `` element. */ -class WebFilterClass extends WebXMLElement { +class WebFilterClass extends WebXmlElement { WebFilterClass() { this.getName() = "filter-class" and this.getParent() instanceof WebFilter @@ -93,14 +102,14 @@ class WebFilterClass extends WebXMLElement { /** * A `` element in a `web.xml` file. */ -class WebServlet extends WebXMLElement { +class WebServlet extends WebXmlElement { WebServlet() { this.getName() = "servlet" } } /** * A `` element in a `web.xml` file, nested under a `` element. */ -class WebServletClass extends WebXMLElement { +class WebServletClass extends WebXmlElement { WebServletClass() { this.getName() = "servlet-class" and this.getParent() instanceof WebServlet @@ -112,14 +121,14 @@ class WebServletClass extends WebXMLElement { /** * A `` element in a `web.xml` file. */ -class WebListener extends WebXMLElement { +class WebListener extends WebXmlElement { WebListener() { this.getName() = "listener" } } /** * A `` element in a `web.xml` file, nested under a `` element. */ -class WebListenerClass extends WebXMLElement { +class WebListenerClass extends WebXmlElement { WebListenerClass() { this.getName() = "listener-class" and this.getParent() instanceof WebListener @@ -134,7 +143,7 @@ class WebListenerClass extends WebXMLElement { /** * An `` element in a `web.xml` file. */ -class WebErrorPage extends WebXMLElement { +class WebErrorPage extends WebXmlElement { WebErrorPage() { this.getName() = "error-page" } /** @@ -151,7 +160,7 @@ class WebErrorPage extends WebXMLElement { /** * An `` element in a `web.xml` file, nested under an `` element. */ -class WebErrorPageType extends WebXMLElement { +class WebErrorPageType extends WebXmlElement { WebErrorPageType() { this.getName() = "exception-type" and this.getParent() instanceof WebErrorPage @@ -161,7 +170,7 @@ class WebErrorPageType extends WebXMLElement { /** * A `` element in a `web.xml` file, nested under an `` element. */ -class WebErrorPageLocation extends WebXMLElement { +class WebErrorPageLocation extends WebXmlElement { WebErrorPageLocation() { this.getName() = "location" and this.getParent() instanceof WebErrorPage diff --git a/java/ql/lib/semmle/code/xml/XML.qll b/java/ql/lib/semmle/code/xml/XML.qll index dc76884b73c..fb781a4683f 100755 --- a/java/ql/lib/semmle/code/xml/XML.qll +++ b/java/ql/lib/semmle/code/xml/XML.qll @@ -4,21 +4,14 @@ import semmle.files.FileSystem -private class TXMLLocatable = +private class TXmlLocatable = @xmldtd or @xmlelement or @xmlattribute or @xmlnamespace or @xmlcomment or @xmlcharacters; /** An XML element that has a location. */ -class XMLLocatable extends @xmllocatable, TXMLLocatable { +class XMLLocatable extends @xmllocatable, TXmlLocatable { /** Gets the source location for this element. */ Location getLocation() { xmllocations(this, result) } - /** - * DEPRECATED: Use `getLocation()` instead. - * - * Gets the source location for this element. - */ - deprecated Location getALocation() { result = this.getLocation() } - /** * Holds if this element is at the specified location. * The location spans column `startcolumn` of line `startline` to @@ -83,21 +76,6 @@ class XMLParent extends @xmlparent { /** Gets the number of places in the body of this XML parent where text occurs. */ int getNumberOfCharacterSets() { result = count(int pos | xmlChars(_, _, this, pos, _, _)) } - /** - * DEPRECATED: Internal. - * - * Append the character sequences of this XML parent from left to right, separated by a space, - * up to a specified (zero-based) index. - */ - deprecated string charsSetUpTo(int n) { - n = 0 and xmlChars(_, result, this, 0, _, _) - or - n > 0 and - exists(string chars | xmlChars(_, chars, this, n, _, _) | - result = this.charsSetUpTo(n - 1) + " " + chars - ) - } - /** * Gets the result of appending all the character sequences of this XML parent from * left to right, separated by a space. diff --git a/java/ql/src/CHANGELOG.md b/java/ql/src/CHANGELOG.md index 72a5dc97064..b2887d972db 100644 --- a/java/ql/src/CHANGELOG.md +++ b/java/ql/src/CHANGELOG.md @@ -1,3 +1,5 @@ +## 0.0.11 + ## 0.0.10 ### Breaking Changes diff --git a/java/ql/src/Frameworks/Spring/Architecture/Refactoring Opportunities/UnusedBean.ql b/java/ql/src/Frameworks/Spring/Architecture/Refactoring Opportunities/UnusedBean.ql index 32a83c26acf..504825807fd 100644 --- a/java/ql/src/Frameworks/Spring/Architecture/Refactoring Opportunities/UnusedBean.ql +++ b/java/ql/src/Frameworks/Spring/Architecture/Refactoring Opportunities/UnusedBean.ql @@ -100,7 +100,7 @@ class SpringPureClass extends Class { // Setter method by autowiring, either in the XML or by annotation c = this.getAMethod().(SpringBeanAutowiredCallable) or - c = this.getAMethod().(SpringBeanXMLAutowiredSetterMethod) + c = this.getAMethod().(SpringBeanXmlAutowiredSetterMethod) ) } } @@ -189,7 +189,7 @@ class LiveSpringBean extends SpringBean { ) or // Injected by autowired specified in XML - exists(SpringBeanXMLAutowiredSetterMethod setterMethod | + exists(SpringBeanXmlAutowiredSetterMethod setterMethod | // The config method must be on a live bean setterMethod.getDeclaringType().(SpringBeanRefType).getSpringBean() instanceof LiveSpringBean diff --git a/java/ql/src/Frameworks/Spring/Violations of Best Practice/UseShortcutForms.ql b/java/ql/src/Frameworks/Spring/Violations of Best Practice/UseShortcutForms.ql index 1d924dc9d6d..b7aad1b85fb 100644 --- a/java/ql/src/Frameworks/Spring/Violations of Best Practice/UseShortcutForms.ql +++ b/java/ql/src/Frameworks/Spring/Violations of Best Practice/UseShortcutForms.ql @@ -51,7 +51,7 @@ class SpringPropertyUseShortcut extends SpringProperty { } } -from SpringXMLElement springElement, string msg +from SpringXmlElement springElement, string msg where exists(SpringConstructorArgUseShortcut cons | cons = springElement and msg = cons.getMessage()) or diff --git a/java/ql/src/Likely Bugs/Concurrency/BusyWait.ql b/java/ql/src/Likely Bugs/Concurrency/BusyWait.ql index 22ed091e052..e9b160222bc 100644 --- a/java/ql/src/Likely Bugs/Concurrency/BusyWait.ql +++ b/java/ql/src/Likely Bugs/Concurrency/BusyWait.ql @@ -16,13 +16,6 @@ import java -class ReachFromStmt extends Stmt { - ReachFromStmt() { - exists(Method m | m.getBody() = this) or - exists(WhileStmt w | w.getStmt() = this) - } -} - class SleepMethod extends Method { SleepMethod() { this.getName() = "sleep" and diff --git a/java/ql/src/Likely Bugs/Termination/ConstantLoopCondition.ql b/java/ql/src/Likely Bugs/Termination/ConstantLoopCondition.ql index 41be2be2c52..3d0b45dabed 100644 --- a/java/ql/src/Likely Bugs/Termination/ConstantLoopCondition.ql +++ b/java/ql/src/Likely Bugs/Termination/ConstantLoopCondition.ql @@ -74,8 +74,8 @@ where ) and // None of the ssa variables in `cond` are updated inside the loop. forex(SsaVariable ssa, RValue use | ssa.getAUse() = use and use.getParent*() = cond | - not ssa.getCFGNode().getEnclosingStmt().getEnclosingStmt*() = loop or - ssa.getCFGNode().(Expr).getParent*() = loop.(ForStmt).getAnInit() + not ssa.getCfgNode().getEnclosingStmt().getEnclosingStmt*() = loop or + ssa.getCfgNode().(Expr).getParent*() = loop.(ForStmt).getAnInit() ) and // And `cond` does not use method calls, field reads, or array reads. not exists(MethodAccess ma | ma.getParent*() = cond) and diff --git a/java/ql/src/Performance/ConcatenationInLoops.ql b/java/ql/src/Performance/ConcatenationInLoops.ql index 2f0d771026b..e4280678e4b 100644 --- a/java/ql/src/Performance/ConcatenationInLoops.ql +++ b/java/ql/src/Performance/ConcatenationInLoops.ql @@ -15,11 +15,6 @@ import semmle.code.java.Expr import semmle.code.java.Statement import semmle.code.java.JDK -/** A use of `+` that has type `String`. */ -class StringCat extends AddExpr { - StringCat() { this.getType() instanceof TypeString } -} - /** * An assignment of the form * diff --git a/java/ql/src/Security/CWE/CWE-020/ExternalAPIsUsedWithUntrustedData.ql b/java/ql/src/Security/CWE/CWE-020/ExternalAPIsUsedWithUntrustedData.ql index f9643429d72..23c82397de0 100644 --- a/java/ql/src/Security/CWE/CWE-020/ExternalAPIsUsedWithUntrustedData.ql +++ b/java/ql/src/Security/CWE/CWE-020/ExternalAPIsUsedWithUntrustedData.ql @@ -12,7 +12,7 @@ import java import semmle.code.java.security.ExternalAPIs import semmle.code.java.dataflow.DataFlow -from ExternalAPIUsedWithUntrustedData externalAPI -select externalAPI, count(externalAPI.getUntrustedDataNode()) as numberOfUses, - externalAPI.getNumberOfUntrustedSources() as numberOfUntrustedSources order by +from ExternalApiUsedWithUntrustedData externalApi +select externalApi, count(externalApi.getUntrustedDataNode()) as numberOfUses, + externalApi.getNumberOfUntrustedSources() as numberOfUntrustedSources order by numberOfUntrustedSources desc diff --git a/java/ql/src/Security/CWE/CWE-020/UntrustedDataToExternalAPI.ql b/java/ql/src/Security/CWE/CWE-020/UntrustedDataToExternalAPI.ql index 63c66ffa9d0..b4a2e209513 100644 --- a/java/ql/src/Security/CWE/CWE-020/UntrustedDataToExternalAPI.ql +++ b/java/ql/src/Security/CWE/CWE-020/UntrustedDataToExternalAPI.ql @@ -15,8 +15,8 @@ import semmle.code.java.dataflow.TaintTracking import semmle.code.java.security.ExternalAPIs import DataFlow::PathGraph -from UntrustedDataToExternalAPIConfig config, DataFlow::PathNode source, DataFlow::PathNode sink +from UntrustedDataToExternalApiConfig config, DataFlow::PathNode source, DataFlow::PathNode sink where config.hasFlowPath(source, sink) select sink, source, sink, - "Call to " + sink.getNode().(ExternalAPIDataNode).getMethodDescription() + + "Call to " + sink.getNode().(ExternalApiDataNode).getMethodDescription() + " with untrusted data from $@.", source, source.toString() diff --git a/java/ql/src/Security/CWE/CWE-079/XSS.ql b/java/ql/src/Security/CWE/CWE-079/XSS.ql index 885a6f7a47b..c488a5d08d4 100644 --- a/java/ql/src/Security/CWE/CWE-079/XSS.ql +++ b/java/ql/src/Security/CWE/CWE-079/XSS.ql @@ -16,8 +16,8 @@ import semmle.code.java.dataflow.FlowSources import semmle.code.java.security.XSS import DataFlow::PathGraph -class XSSConfig extends TaintTracking::Configuration { - XSSConfig() { this = "XSSConfig" } +class XssConfig extends TaintTracking::Configuration { + XssConfig() { this = "XSSConfig" } override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } @@ -32,7 +32,7 @@ class XSSConfig extends TaintTracking::Configuration { } } -from DataFlow::PathNode source, DataFlow::PathNode sink, XSSConfig conf +from DataFlow::PathNode source, DataFlow::PathNode sink, XssConfig conf where conf.hasFlowPath(source, sink) select sink.getNode(), source, sink, "Cross-site scripting vulnerability due to $@.", source.getNode(), "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-079/XSSLocal.ql b/java/ql/src/Security/CWE/CWE-079/XSSLocal.ql index e16a9bbc2e9..da318a5b7cb 100644 --- a/java/ql/src/Security/CWE/CWE-079/XSSLocal.ql +++ b/java/ql/src/Security/CWE/CWE-079/XSSLocal.ql @@ -16,15 +16,15 @@ import semmle.code.java.dataflow.FlowSources import semmle.code.java.security.XSS import DataFlow::PathGraph -class XSSLocalConfig extends TaintTracking::Configuration { - XSSLocalConfig() { this = "XSSLocalConfig" } +class XssLocalConfig extends TaintTracking::Configuration { + XssLocalConfig() { this = "XSSLocalConfig" } override predicate isSource(DataFlow::Node source) { source instanceof LocalUserInput } override predicate isSink(DataFlow::Node sink) { sink instanceof XssSink } } -from DataFlow::PathNode source, DataFlow::PathNode sink, XSSLocalConfig conf +from DataFlow::PathNode source, DataFlow::PathNode sink, XssLocalConfig conf where conf.hasFlowPath(source, sink) select sink.getNode(), source, sink, "Cross-site scripting vulnerability due to $@.", source.getNode(), "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-319/UseSSL.ql b/java/ql/src/Security/CWE/CWE-319/UseSSL.ql index 1b267af52cf..ba3dee696dd 100644 --- a/java/ql/src/Security/CWE/CWE-319/UseSSL.ql +++ b/java/ql/src/Security/CWE/CWE-319/UseSSL.ql @@ -14,8 +14,8 @@ import java import semmle.code.java.dataflow.TypeFlow import semmle.code.java.security.Encryption -class URLConnection extends RefType { - URLConnection() { +class UrlConnection extends RefType { + UrlConnection() { this.getAnAncestor().hasQualifiedName("java.net", "URLConnection") and not this.hasName("JarURLConnection") } @@ -29,7 +29,7 @@ from MethodAccess m, Class c, string type where m.getQualifier().getType() = c and ( - c instanceof URLConnection and type = "connection" + c instanceof UrlConnection and type = "connection" or c instanceof Socket and type = "socket" ) and diff --git a/java/ql/src/experimental/Security/CWE/CWE-532/SensitiveInfoLog.java b/java/ql/src/Security/CWE/CWE-532/SensitiveInfoLog.java similarity index 91% rename from java/ql/src/experimental/Security/CWE/CWE-532/SensitiveInfoLog.java rename to java/ql/src/Security/CWE/CWE-532/SensitiveInfoLog.java index e1f7354b912..b64b80e0fdd 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-532/SensitiveInfoLog.java +++ b/java/ql/src/Security/CWE/CWE-532/SensitiveInfoLog.java @@ -14,5 +14,6 @@ public static void main(String[] args) { String password = "Pass@0rd"; // GOOD: user password is never written to debug log + logger.debug("User password changed") } } diff --git a/java/ql/src/experimental/Security/CWE/CWE-532/SensitiveInfoLog.qhelp b/java/ql/src/Security/CWE/CWE-532/SensitiveInfoLog.qhelp similarity index 100% rename from java/ql/src/experimental/Security/CWE/CWE-532/SensitiveInfoLog.qhelp rename to java/ql/src/Security/CWE/CWE-532/SensitiveInfoLog.qhelp diff --git a/java/ql/src/Security/CWE/CWE-532/SensitiveInfoLog.ql b/java/ql/src/Security/CWE/CWE-532/SensitiveInfoLog.ql new file mode 100644 index 00000000000..6f32b9768cb --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-532/SensitiveInfoLog.ql @@ -0,0 +1,21 @@ +/** + * @name Insertion of sensitive information into log files + * @description Writing sensitive information to log files can allow that + * information to be leaked to an attacker more easily. + * @kind path-problem + * @problem.severity warning + * @security-severity 7.5 + * @precision medium + * @id java/sensitive-log + * @tags security + * external/cwe/cwe-532 + */ + +import java +import semmle.code.java.security.SensitiveLoggingQuery +import PathGraph + +from SensitiveLoggerConfiguration cfg, DataFlow::PathNode source, DataFlow::PathNode sink +where cfg.hasFlowPath(source, sink) +select sink.getNode(), source, sink, "This $@ is written to a log file.", source.getNode(), + "potentially sensitive information" diff --git a/java/ql/src/Security/CWE/CWE-611/XXE.ql b/java/ql/src/Security/CWE/CWE-611/XXE.ql index bfcedb19d17..b50c9c7fef8 100644 --- a/java/ql/src/Security/CWE/CWE-611/XXE.ql +++ b/java/ql/src/Security/CWE/CWE-611/XXE.ql @@ -19,10 +19,10 @@ import semmle.code.java.dataflow.FlowSources import semmle.code.java.dataflow.TaintTracking2 import DataFlow::PathGraph -class SafeSAXSourceFlowConfig extends TaintTracking2::Configuration { - SafeSAXSourceFlowConfig() { this = "XmlParsers::SafeSAXSourceFlowConfig" } +class SafeSaxSourceFlowConfig extends TaintTracking2::Configuration { + SafeSaxSourceFlowConfig() { this = "XmlParsers::SafeSAXSourceFlowConfig" } - override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeSAXSource } + override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeSaxSource } override predicate isSink(DataFlow::Node sink) { sink.asExpr() = any(XmlParserCall parse).getSink() @@ -33,7 +33,7 @@ class SafeSAXSourceFlowConfig extends TaintTracking2::Configuration { class UnsafeXxeSink extends DataFlow::ExprNode { UnsafeXxeSink() { - not exists(SafeSAXSourceFlowConfig safeSource | safeSource.hasFlowTo(this)) and + not exists(SafeSaxSourceFlowConfig safeSource | safeSource.hasFlowTo(this)) and exists(XmlParserCall parse | parse.getSink() = this.getExpr() and not parse.isSafe() diff --git a/java/ql/src/Telemetry/ExternalAPI.qll b/java/ql/src/Telemetry/ExternalAPI.qll index c3bd101662d..e8a1e007c12 100644 --- a/java/ql/src/Telemetry/ExternalAPI.qll +++ b/java/ql/src/Telemetry/ExternalAPI.qll @@ -12,8 +12,8 @@ private import semmle.code.java.dataflow.TaintTracking /** * An external API from either the Java Standard Library or a 3rd party library. */ -class ExternalAPI extends Callable { - ExternalAPI() { not this.fromSource() } +class ExternalApi extends Callable { + ExternalApi() { not this.fromSource() } /** Holds if this API is not worth supporting */ predicate isUninteresting() { this.isTestLibrary() or this.isParameterlessConstructor() } @@ -80,6 +80,9 @@ class ExternalAPI extends Callable { predicate isSupported() { this.hasSummary() or this.isSource() or this.isSink() } } +/** DEPRECATED: Alias for ExternalApi */ +deprecated class ExternalAPI = ExternalApi; + private class TestLibrary extends RefType { TestLibrary() { this.getPackage() diff --git a/java/ql/src/Telemetry/ExternalLibraryUsage.ql b/java/ql/src/Telemetry/ExternalLibraryUsage.ql index 93052f19d3b..fd29d2fbea0 100644 --- a/java/ql/src/Telemetry/ExternalLibraryUsage.ql +++ b/java/ql/src/Telemetry/ExternalLibraryUsage.ql @@ -12,7 +12,7 @@ import ExternalAPI from int usages, string jarname where usages = - strictcount(Call c, ExternalAPI a | + strictcount(Call c, ExternalApi a | c.getCallee().getSourceDeclaration() = a and not c.getFile() instanceof GeneratedFile and a.jarContainer() = jarname and diff --git a/java/ql/src/Telemetry/SupportedExternalSinks.ql b/java/ql/src/Telemetry/SupportedExternalSinks.ql index f39794a23be..fc831f9fa59 100644 --- a/java/ql/src/Telemetry/SupportedExternalSinks.ql +++ b/java/ql/src/Telemetry/SupportedExternalSinks.ql @@ -10,7 +10,7 @@ import java import ExternalAPI import semmle.code.java.GeneratedFiles -from ExternalAPI api, int usages +from ExternalApi api, int usages where not api.isUninteresting() and api.isSink() and diff --git a/java/ql/src/Telemetry/SupportedExternalSources.ql b/java/ql/src/Telemetry/SupportedExternalSources.ql index 91d51cd72fa..9e526007b00 100644 --- a/java/ql/src/Telemetry/SupportedExternalSources.ql +++ b/java/ql/src/Telemetry/SupportedExternalSources.ql @@ -10,7 +10,7 @@ import java import ExternalAPI import semmle.code.java.GeneratedFiles -from ExternalAPI api, int usages +from ExternalApi api, int usages where not api.isUninteresting() and api.isSource() and diff --git a/java/ql/src/Telemetry/SupportedExternalTaint.ql b/java/ql/src/Telemetry/SupportedExternalTaint.ql index 71721923dea..7e7032a4730 100644 --- a/java/ql/src/Telemetry/SupportedExternalTaint.ql +++ b/java/ql/src/Telemetry/SupportedExternalTaint.ql @@ -10,7 +10,7 @@ import java import ExternalAPI import semmle.code.java.GeneratedFiles -from ExternalAPI api, int usages +from ExternalApi api, int usages where not api.isUninteresting() and api.hasSummary() and diff --git a/java/ql/src/Telemetry/UnsupportedExternalAPIs.ql b/java/ql/src/Telemetry/UnsupportedExternalAPIs.ql index e79e4938438..ab9df45091d 100644 --- a/java/ql/src/Telemetry/UnsupportedExternalAPIs.ql +++ b/java/ql/src/Telemetry/UnsupportedExternalAPIs.ql @@ -10,7 +10,7 @@ import java import ExternalAPI import semmle.code.java.GeneratedFiles -from ExternalAPI api, int usages +from ExternalApi api, int usages where not api.isUninteresting() and not api.isSupported() and diff --git a/java/ql/src/Violations of Best Practice/Dead Code/DeadLocals.qll b/java/ql/src/Violations of Best Practice/Dead Code/DeadLocals.qll index a138351e656..82933aa9bac 100644 --- a/java/ql/src/Violations of Best Practice/Dead Code/DeadLocals.qll +++ b/java/ql/src/Violations of Best Practice/Dead Code/DeadLocals.qll @@ -44,8 +44,8 @@ predicate overwritten(SsaExplicitUpdate ssa) { not deadLocal(overwrite) and not overwrite.getDefiningExpr() instanceof LocalVariableDeclExpr and exists(BasicBlock bb1, BasicBlock bb2, int i, int j | - bb1.getNode(i) = ssa.getCFGNode() and - bb2.getNode(j) = overwrite.getCFGNode() + bb1.getNode(i) = ssa.getCfgNode() and + bb2.getNode(j) = overwrite.getCfgNode() | bb1.getABBSuccessor+() = bb2 or diff --git a/java/ql/src/change-notes/2022-03-11-sensitive-logging.md b/java/ql/src/change-notes/2022-03-11-sensitive-logging.md new file mode 100644 index 00000000000..cfc4693b1cb --- /dev/null +++ b/java/ql/src/change-notes/2022-03-11-sensitive-logging.md @@ -0,0 +1,4 @@ +--- +category: newQuery +--- +* The query "Insertion of sensitive information into log files" (`java/sensitive-logging`) has been promoted from experimental to the main query pack. This query was originally [submitted as an experimental query by @luchua-bc](https://github.com/github/codeql/pull/3090). \ No newline at end of file diff --git a/java/ql/src/change-notes/released/0.0.11.md b/java/ql/src/change-notes/released/0.0.11.md new file mode 100644 index 00000000000..eba254bd51f --- /dev/null +++ b/java/ql/src/change-notes/released/0.0.11.md @@ -0,0 +1 @@ +## 0.0.11 diff --git a/java/ql/src/codeql-pack.release.yml b/java/ql/src/codeql-pack.release.yml index b740014e5ae..e679dc42092 100644 --- a/java/ql/src/codeql-pack.release.yml +++ b/java/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.10 +lastReleaseVersion: 0.0.11 diff --git a/java/ql/src/experimental/Security/CWE/CWE-036/OpenStream.ql b/java/ql/src/experimental/Security/CWE/CWE-036/OpenStream.ql index 871d6bb4737..238f586ff21 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-036/OpenStream.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-036/OpenStream.ql @@ -16,8 +16,8 @@ import semmle.code.java.dataflow.FlowSources import semmle.code.java.dataflow.ExternalFlow import DataFlow::PathGraph -class URLConstructor extends ClassInstanceExpr { - URLConstructor() { this.getConstructor().getDeclaringType() instanceof TypeUrl } +class UrlConstructor extends ClassInstanceExpr { + UrlConstructor() { this.getConstructor().getDeclaringType() instanceof TypeUrl } Expr stringArg() { // Query only in URL's that were constructed by calling the single parameter string constructor. @@ -27,28 +27,21 @@ class URLConstructor extends ClassInstanceExpr { } } -class URLOpenStreamMethod extends Method { - URLOpenStreamMethod() { - this.getDeclaringType() instanceof TypeUrl and - this.getName() = "openStream" - } -} - -class RemoteURLToOpenStreamFlowConfig extends TaintTracking::Configuration { - RemoteURLToOpenStreamFlowConfig() { this = "OpenStream::RemoteURLToOpenStreamFlowConfig" } +class RemoteUrlToOpenStreamFlowConfig extends TaintTracking::Configuration { + RemoteUrlToOpenStreamFlowConfig() { this = "OpenStream::RemoteURLToOpenStreamFlowConfig" } override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } override predicate isSink(DataFlow::Node sink) { exists(MethodAccess m | - sink.asExpr() = m.getQualifier() and m.getMethod() instanceof URLOpenStreamMethod + sink.asExpr() = m.getQualifier() and m.getMethod() instanceof UrlOpenStreamMethod ) or sinkNode(sink, "url-open-stream") } override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { - exists(URLConstructor u | + exists(UrlConstructor u | node1.asExpr() = u.stringArg() and node2.asExpr() = u ) @@ -58,6 +51,6 @@ class RemoteURLToOpenStreamFlowConfig extends TaintTracking::Configuration { from DataFlow::PathNode source, DataFlow::PathNode sink, MethodAccess call where sink.getNode().asExpr() = call.getQualifier() and - any(RemoteURLToOpenStreamFlowConfig c).hasFlowPath(source, sink) + any(RemoteUrlToOpenStreamFlowConfig c).hasFlowPath(source, sink) select call, source, sink, "URL on which openStream is called may have been constructed from remote source" diff --git a/java/ql/src/experimental/Security/CWE/CWE-089/MyBatisCommonLib.qll b/java/ql/src/experimental/Security/CWE/CWE-089/MyBatisCommonLib.qll index f43f9a34128..b7f01ce06cd 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-089/MyBatisCommonLib.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-089/MyBatisCommonLib.qll @@ -45,7 +45,7 @@ class ListType extends RefType { } /** Holds if the specified `method` uses MyBatis Mapper XMLElement `mmxx`. */ -predicate myBatisMapperXMLElementFromMethod(Method method, MyBatisMapperXMLElement mmxx) { +predicate myBatisMapperXmlElementFromMethod(Method method, MyBatisMapperXmlElement mmxx) { exists(MyBatisMapperSqlOperation mbmxe | mbmxe.getMapperMethod() = method | mbmxe.getAChild*() = mmxx or @@ -56,6 +56,9 @@ predicate myBatisMapperXMLElementFromMethod(Method method, MyBatisMapperXMLEleme ) } +/** DEPRECATED: Alias for myBatisMapperXmlElementFromMethod */ +deprecated predicate myBatisMapperXMLElementFromMethod = myBatisMapperXmlElementFromMethod/2; + /** Holds if the specified `method` has Ibatis Sql operation annotation `isoa`. */ predicate myBatisSqlOperationAnnotationFromMethod(Method method, IbatisSqlOperationAnnotation isoa) { exists(MyBatisSqlOperationAnnotationMethod msoam | diff --git a/java/ql/src/experimental/Security/CWE/CWE-089/MyBatisMapperXmlSqlInjection.ql b/java/ql/src/experimental/Security/CWE/CWE-089/MyBatisMapperXmlSqlInjection.ql index 908234fa3f3..9aeb95ea94a 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-089/MyBatisMapperXmlSqlInjection.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-089/MyBatisMapperXmlSqlInjection.ql @@ -45,11 +45,11 @@ private class MyBatisMapperXmlSqlInjectionConfiguration extends TaintTracking::C from MyBatisMapperXmlSqlInjectionConfiguration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, - MyBatisMapperXMLElement mmxe, MethodAccess ma, string unsafeExpression + MyBatisMapperXmlElement mmxe, MethodAccess ma, string unsafeExpression where cfg.hasFlowPath(source, sink) and ma.getAnArgument() = sink.getNode().asExpr() and - myBatisMapperXMLElementFromMethod(ma.getMethod(), mmxe) and + myBatisMapperXmlElementFromMethod(ma.getMethod(), mmxe) and unsafeExpression = getAMybatisXmlSetValue(mmxe) and ( isMybatisXmlOrAnnotationSqlInjection(sink.getNode(), ma, unsafeExpression) diff --git a/java/ql/src/experimental/Security/CWE/CWE-1004/InsecureTomcatConfig.ql b/java/ql/src/experimental/Security/CWE/CWE-1004/InsecureTomcatConfig.ql index c8bff52333d..fbc3e0536b1 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-1004/InsecureTomcatConfig.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-1004/InsecureTomcatConfig.ql @@ -17,10 +17,10 @@ private class HttpOnlyConfig extends WebContextParameter { string getParamValueElementValue() { result = this.getParamValue().getValue() } - predicate isHTTPOnlySet() { this.getParamValueElementValue().toLowerCase() = "false" } + predicate isHttpOnlySet() { this.getParamValueElementValue().toLowerCase() = "false" } } from HttpOnlyConfig config -where config.isHTTPOnlySet() +where config.isHttpOnlySet() select config, "httpOnly should be enabled in tomcat config file to help mitigate cross-site scripting (XSS) attacks" diff --git a/java/ql/src/experimental/Security/CWE/CWE-532/SensitiveInfoLog.ql b/java/ql/src/experimental/Security/CWE/CWE-532/SensitiveInfoLog.ql deleted file mode 100644 index b84143d0b80..00000000000 --- a/java/ql/src/experimental/Security/CWE/CWE-532/SensitiveInfoLog.ql +++ /dev/null @@ -1,49 +0,0 @@ -/** - * @name Insertion of sensitive information into log files - * @description Writing sensitive information to log files can give valuable - * guidance to an attacker or expose sensitive user information. - * @kind path-problem - * @problem.severity warning - * @precision medium - * @id java/sensitiveinfo-in-logfile - * @tags security - * external/cwe/cwe-532 - */ - -import java -import semmle.code.java.dataflow.ExternalFlow -import semmle.code.java.dataflow.TaintTracking -import semmle.code.java.security.SensitiveActions -import DataFlow -import PathGraph - -/** - * Gets a regular expression for matching names of variables that indicate the value being held may contain sensitive information - */ -private string getACredentialRegex() { result = "(?i)(.*username|url).*" } - -/** Variable keeps sensitive information judging by its name * */ -class CredentialExpr extends Expr { - CredentialExpr() { - exists(Variable v | this = v.getAnAccess() | - v.getName().regexpMatch([getCommonSensitiveInfoRegex(), getACredentialRegex()]) - ) - } -} - -class LoggerConfiguration extends DataFlow::Configuration { - LoggerConfiguration() { this = "Logger Configuration" } - - override predicate isSource(DataFlow::Node source) { source.asExpr() instanceof CredentialExpr } - - override predicate isSink(DataFlow::Node sink) { sinkNode(sink, "logging") } - - override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - TaintTracking::localTaintStep(node1, node2) - } -} - -from LoggerConfiguration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) -select sink.getNode(), source, sink, "Outputting $@ to log.", source.getNode(), - "sensitive information" diff --git a/java/ql/src/experimental/Security/CWE/CWE-548/InsecureDirectoryConfig.ql b/java/ql/src/experimental/Security/CWE/CWE-548/InsecureDirectoryConfig.ql index c1667abdd3d..1ef4fb4d1f6 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-548/InsecureDirectoryConfig.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-548/InsecureDirectoryConfig.ql @@ -27,7 +27,7 @@ private class DefaultTomcatServlet extends WebServletClass { /** * The `` element in a `web.xml` file, nested under a `` element controlling directory listing. */ -class DirectoryListingInitParam extends WebXMLElement { +class DirectoryListingInitParam extends WebXmlElement { DirectoryListingInitParam() { this.getName() = "init-param" and this.getAChild("param-name").getTextValue() = "listings" and diff --git a/java/ql/src/experimental/Security/CWE/CWE-552/UnsafeUrlForward.ql b/java/ql/src/experimental/Security/CWE/CWE-552/UnsafeUrlForward.ql index 12f6b29d692..94cdaafa553 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-552/UnsafeUrlForward.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-552/UnsafeUrlForward.ql @@ -23,7 +23,7 @@ class UnsafeUrlForwardFlowConfig extends TaintTracking::Configuration { not exists(MethodAccess ma, Method m | ma.getMethod() = m | ( m instanceof HttpServletRequestGetRequestURIMethod or - m instanceof HttpServletRequestGetRequestURLMethod or + m instanceof HttpServletRequestGetRequestUrlMethod or m instanceof HttpServletRequestGetPathMethod ) and ma = source.asExpr() 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 267b4bdef1d..996eca35850 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-611/XXELib.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-611/XXELib.qll @@ -204,17 +204,20 @@ private class SafeDigesterFlowConfig extends DataFlow4::Configuration { override int fieldFlowBranchLimit() { result = 0 } } -/** The class `java.beans.XMLDecoder`. */ -class XMLDecoder extends RefType { - XMLDecoder() { this.hasQualifiedName("java.beans", "XMLDecoder") } +/** The class `java.beans.XmlDecoder`. */ +class XmlDecoder extends RefType { + XmlDecoder() { this.hasQualifiedName("java.beans", "XMLDecoder") } } -/** A call to `XMLDecoder.readObject`. */ -class XMLDecoderReadObject extends XmlParserCall { - XMLDecoderReadObject() { +/** DEPRECATED: Alias for XmlDecoder */ +deprecated class XMLDecoder = XmlDecoder; + +/** A call to `XmlDecoder.readObject`. */ +class XmlDecoderReadObject extends XmlParserCall { + XmlDecoderReadObject() { exists(Method m | this.getMethod() = m and - m.getDeclaringType() instanceof XMLDecoder and + m.getDeclaringType() instanceof XmlDecoder and m.hasName("readObject") ) } @@ -224,6 +227,9 @@ class XMLDecoderReadObject extends XmlParserCall { override predicate isSafe() { none() } } +/** DEPRECATED: Alias for XmlDecoderReadObject */ +deprecated class XMLDecoderReadObject = XmlDecoderReadObject; + private predicate constantStringExpr(Expr e, string val) { e.(CompileTimeConstantExpr).getStringValue() = val or @@ -235,8 +241,8 @@ private predicate constantStringExpr(Expr e, string val) { } /** A call to `SAXTransformerFactory.newTransformerHandler`. */ -class SAXTransformerFactoryNewTransformerHandler extends XmlParserCall { - SAXTransformerFactoryNewTransformerHandler() { +class SaxTransformerFactoryNewTransformerHandler extends XmlParserCall { + SaxTransformerFactoryNewTransformerHandler() { exists(Method m | this.getMethod() = m and m.getDeclaringType().hasQualifiedName("javax.xml.transform.sax", "SAXTransformerFactory") and @@ -251,6 +257,10 @@ class SAXTransformerFactoryNewTransformerHandler extends XmlParserCall { } } +/** DEPRECATED: Alias for SaxTransformerFactoryNewTransformerHandler */ +deprecated class SAXTransformerFactoryNewTransformerHandler = + SaxTransformerFactoryNewTransformerHandler; + /** An expression that always has the same string value. */ private class ConstantStringExpr extends Expr { string value; diff --git a/java/ql/src/experimental/Security/CWE/CWE-759/HashWithoutSalt.ql b/java/ql/src/experimental/Security/CWE/CWE-759/HashWithoutSalt.ql index 42213de55f6..bea7faff694 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-759/HashWithoutSalt.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-759/HashWithoutSalt.ql @@ -36,16 +36,6 @@ class MessageDigest extends RefType { MessageDigest() { this.hasQualifiedName("java.security", "MessageDigest") } } -/** The method call `MessageDigest.getInstance(...)` */ -class MDConstructor extends StaticMethodAccess { - MDConstructor() { - exists(Method m | m = this.getMethod() | - m.getDeclaringType() instanceof MessageDigest and - m.hasName("getInstance") - ) - } -} - /** The method `digest()` declared in `java.security.MessageDigest`. */ class MDDigestMethod extends Method { MDDigestMethod() { diff --git a/java/ql/src/experimental/semmle/code/java/PathSanitizer.qll b/java/ql/src/experimental/semmle/code/java/PathSanitizer.qll index 9e76410a6ff..aba7bba5238 100644 --- a/java/ql/src/experimental/semmle/code/java/PathSanitizer.qll +++ b/java/ql/src/experimental/semmle/code/java/PathSanitizer.qll @@ -102,7 +102,7 @@ private class BlockListBarrierGuard extends PathTraversalBarrierGuard instanceof * A guard that considers a string safe because it is checked for URL encoding sequences, * having previously been checked against a block-list of forbidden values. */ -private class URLEncodingBarrierGuard extends PathTraversalBarrierGuard instanceof UrlEncodingGuard { +private class UrlEncodingBarrierGuard extends PathTraversalBarrierGuard instanceof UrlEncodingGuard { override predicate checks(Expr e, boolean branch) { e = super.getCheckedExpr() and branch = false and diff --git a/java/ql/src/experimental/semmle/code/xml/StrutsXML.qll b/java/ql/src/experimental/semmle/code/xml/StrutsXML.qll index 00580fe1e79..709a05dae0d 100644 --- a/java/ql/src/experimental/semmle/code/xml/StrutsXML.qll +++ b/java/ql/src/experimental/semmle/code/xml/StrutsXML.qll @@ -3,18 +3,21 @@ import java /** * A deployment descriptor file, typically called `struts.xml`. */ -class StrutsXMLFile extends XMLFile { - StrutsXMLFile() { +class StrutsXmlFile extends XMLFile { + StrutsXmlFile() { count(XMLElement e | e = this.getAChild()) = 1 and this.getAChild().getName() = "struts" } } +/** DEPRECATED: Alias for StrutsXmlFile */ +deprecated class StrutsXMLFile = StrutsXmlFile; + /** * An XML element in a `StrutsXMLFile`. */ -class StrutsXMLElement extends XMLElement { - StrutsXMLElement() { this.getFile() instanceof StrutsXMLFile } +class StrutsXmlElement extends XMLElement { + StrutsXmlElement() { this.getFile() instanceof StrutsXmlFile } /** * Gets the value for this element, with leading and trailing whitespace trimmed. @@ -22,10 +25,13 @@ class StrutsXMLElement extends XMLElement { string getValue() { result = this.allCharactersString().trim() } } +/** DEPRECATED: Alias for StrutsXmlElement */ +deprecated class StrutsXMLElement = StrutsXmlElement; + /** * A `` element in a `StrutsXMLFile`. */ -class ConstantParameter extends StrutsXMLElement { +class ConstantParameter extends StrutsXmlElement { ConstantParameter() { this.getName() = "constant" } /** diff --git a/java/ql/src/meta/ssa/AmbiguousToString.ql b/java/ql/src/meta/ssa/AmbiguousToString.ql index ef9439705de..817685cf609 100644 --- a/java/ql/src/meta/ssa/AmbiguousToString.ql +++ b/java/ql/src/meta/ssa/AmbiguousToString.ql @@ -22,6 +22,6 @@ where or multipleToString(ssa) and problem = "SSA variable with multiple 'toString()' results for " ) and - n = ssa.getCFGNode() and + n = ssa.getCfgNode() and v = ssa.getSourceVariable().getVariable() select n, problem + v diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml index 4be8ebddff7..b27efa16aca 100644 --- a/java/ql/src/qlpack.yml +++ b/java/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-queries -version: 0.0.11-dev +version: 0.0.12-dev groups: - java - queries diff --git a/java/ql/src/semmle/code/xml/MyBatisMapperXML.qll b/java/ql/src/semmle/code/xml/MyBatisMapperXML.qll index 5eff757a93d..856729dcce5 100644 --- a/java/ql/src/semmle/code/xml/MyBatisMapperXML.qll +++ b/java/ql/src/semmle/code/xml/MyBatisMapperXML.qll @@ -7,18 +7,21 @@ import java /** * MyBatis Mapper XML file. */ -class MyBatisMapperXMLFile extends XMLFile { - MyBatisMapperXMLFile() { +class MyBatisMapperXmlFile extends XMLFile { + MyBatisMapperXmlFile() { count(XMLElement e | e = this.getAChild()) = 1 and this.getAChild().getName() = "mapper" } } +/** DEPRECATED: Alias for MyBatisMapperXmlFile */ +deprecated class MyBatisMapperXMLFile = MyBatisMapperXmlFile; + /** * An XML element in a `MyBatisMapperXMLFile`. */ -class MyBatisMapperXMLElement extends XMLElement { - MyBatisMapperXMLElement() { this.getFile() instanceof MyBatisMapperXMLFile } +class MyBatisMapperXmlElement extends XMLElement { + MyBatisMapperXmlElement() { this.getFile() instanceof MyBatisMapperXmlFile } /** * Gets the value for this element, with leading and trailing whitespace trimmed. @@ -33,10 +36,13 @@ class MyBatisMapperXMLElement extends XMLElement { } } +/** DEPRECATED: Alias for MyBatisMapperXmlElement */ +deprecated class MyBatisMapperXMLElement = MyBatisMapperXmlElement; + /** * An MyBatis Mapper sql operation element. */ -abstract class MyBatisMapperSqlOperation extends MyBatisMapperXMLElement { +abstract class MyBatisMapperSqlOperation extends MyBatisMapperXmlElement { /** * Gets the value of the `id` attribute of MyBatis Mapper sql operation element. */ @@ -52,7 +58,7 @@ abstract class MyBatisMapperSqlOperation extends MyBatisMapperXMLElement { */ Method getMapperMethod() { result.getName() = this.getId() and - result.getDeclaringType() = this.getParent().(MyBatisMapperXMLElement).getNamespaceRefType() + result.getDeclaringType() = this.getParent().(MyBatisMapperXmlElement).getNamespaceRefType() } } @@ -87,7 +93,7 @@ class MyBatisMapperSelect extends MyBatisMapperSqlOperation { /** * A `` element in a `MyBatisMapperXMLElement`. */ -class MyBatisMapperSql extends MyBatisMapperXMLElement { +class MyBatisMapperSql extends MyBatisMapperXmlElement { MyBatisMapperSql() { this.getName() = "sql" } /** @@ -99,7 +105,7 @@ class MyBatisMapperSql extends MyBatisMapperXMLElement { /** * A `` element in a `MyBatisMapperXMLElement`. */ -class MyBatisMapperInclude extends MyBatisMapperXMLElement { +class MyBatisMapperInclude extends MyBatisMapperXmlElement { MyBatisMapperInclude() { this.getName() = "include" } /** @@ -111,6 +117,6 @@ class MyBatisMapperInclude extends MyBatisMapperXMLElement { /** * A `` element in a `MyBatisMapperXMLElement`. */ -class MyBatisMapperForeach extends MyBatisMapperXMLElement { +class MyBatisMapperForeach extends MyBatisMapperXmlElement { MyBatisMapperForeach() { this.getName() = "foreach" } } diff --git a/java/ql/src/utils/model-generator/CaptureSinkModels.ql b/java/ql/src/utils/model-generator/CaptureSinkModels.ql index aab52da3058..9f574cf84c9 100644 --- a/java/ql/src/utils/model-generator/CaptureSinkModels.ql +++ b/java/ql/src/utils/model-generator/CaptureSinkModels.ql @@ -43,7 +43,7 @@ string asInputArgument(DataFlow::Node source) { result = "Argument[-1]" } -string captureSink(TargetAPI api) { +string captureSink(TargetApi api) { exists(DataFlow::Node src, DataFlow::Node sink, PropagateToSinkConfiguration config, string kind | config.hasFlow(src, sink) and sinkNode(sink, kind) and @@ -53,6 +53,6 @@ string captureSink(TargetAPI api) { ) } -from TargetAPI api, string sink +from TargetApi api, string sink where sink = captureSink(api) select sink order by sink diff --git a/java/ql/src/utils/model-generator/CaptureSourceModels.ql b/java/ql/src/utils/model-generator/CaptureSourceModels.ql index 7cb9d2f19b3..e36ba324068 100644 --- a/java/ql/src/utils/model-generator/CaptureSourceModels.ql +++ b/java/ql/src/utils/model-generator/CaptureSourceModels.ql @@ -22,7 +22,7 @@ class FromSourceConfiguration extends TaintTracking::Configuration { override predicate isSource(DataFlow::Node source) { sourceNode(source, _) } override predicate isSink(DataFlow::Node sink) { - exists(TargetAPI c | + exists(TargetApi c | sink instanceof ReturnNodeExt and sink.getEnclosingCallable() = c and c.isPublic() and @@ -39,7 +39,7 @@ class FromSourceConfiguration extends TaintTracking::Configuration { } } -string captureSource(TargetAPI api) { +string captureSource(TargetApi api) { exists(DataFlow::Node source, DataFlow::Node sink, FromSourceConfiguration config, string kind | config.hasFlow(source, sink) and sourceNode(source, kind) and @@ -48,6 +48,6 @@ string captureSource(TargetAPI api) { ) } -from TargetAPI api, string sink +from TargetApi api, string sink where sink = captureSource(api) select sink order by sink diff --git a/java/ql/src/utils/model-generator/CaptureSummaryModels.ql b/java/ql/src/utils/model-generator/CaptureSummaryModels.ql index 280e0a19d7d..69acd4ad5a9 100644 --- a/java/ql/src/utils/model-generator/CaptureSummaryModels.ql +++ b/java/ql/src/utils/model-generator/CaptureSummaryModels.ql @@ -4,23 +4,12 @@ * @id java/utils/model-generator/summary-models */ -import java -import semmle.code.java.dataflow.TaintTracking -import semmle.code.java.dataflow.internal.DataFlowImplCommon -import semmle.code.java.dataflow.internal.DataFlowNodes -import semmle.code.java.dataflow.internal.DataFlowPrivate -import semmle.code.java.dataflow.InstanceAccess -import ModelGeneratorUtils - -string captureFlow(TargetAPI api) { - result = captureQualifierFlow(api) or - result = captureThroughFlow(api) -} +private import CaptureSummaryModels /** * Capture fluent APIs that return `this`. * Example of a fluent API: - * ``` + * ```java * public class Foo { * public Foo someAPI() { * // some side-effect @@ -28,75 +17,14 @@ string captureFlow(TargetAPI api) { * } * } * ``` - */ -string captureQualifierFlow(TargetAPI api) { - exists(ReturnStmt rtn | - rtn.getEnclosingCallable() = api and - rtn.getResult().(ThisAccess).isOwnInstanceAccess() - ) and - result = asValueModel(api, "Argument[-1]", "ReturnValue") -} - -class TaintRead extends DataFlow::FlowState { - TaintRead() { this = "TaintRead" } -} - -class TaintStore extends DataFlow::FlowState { - TaintStore() { this = "TaintStore" } -} - -class ThroughFlowConfig extends TaintTracking::Configuration { - ThroughFlowConfig() { this = "ThroughFlowConfig" } - - override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { - source instanceof DataFlow::ParameterNode and - source.getEnclosingCallable() instanceof TargetAPI and - state instanceof TaintRead - } - - override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { - sink instanceof ReturnNodeExt and - not sink.(ReturnNode).asExpr().(ThisAccess).isOwnInstanceAccess() and - not exists(captureQualifierFlow(sink.asExpr().getEnclosingCallable())) and - (state instanceof TaintRead or state instanceof TaintStore) - } - - override predicate isAdditionalFlowStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - exists(TypedContent tc | - store(node1, tc, node2, _) and - isRelevantContent(tc.getContent()) and - (state1 instanceof TaintRead or state1 instanceof TaintStore) and - state2 instanceof TaintStore - ) - or - exists(DataFlow::Content c | - readStep(node1, c, node2) and - isRelevantContent(c) and - state1 instanceof TaintRead and - state2 instanceof TaintRead - ) - } - - override predicate isSanitizer(DataFlow::Node n) { - exists(Type t | t = n.getType() and not isRelevantType(t)) - } - - override DataFlow::FlowFeature getAFeature() { - result instanceof DataFlow::FeatureEqualSourceSinkCallContext - } -} - -/** + * * Capture APIs that transfer taint from an input parameter to an output return * value or parameter. * Allows a sequence of read steps followed by a sequence of store steps. * * Examples: * - * ``` + * ```java * public class Foo { * private String tainted; * @@ -109,13 +37,13 @@ class ThroughFlowConfig extends TaintTracking::Configuration { * } * } * ``` - * Captured Model: + * Captured Models: * ``` * p;Foo;true;returnsTainted;;Argument[-1];ReturnValue;taint * p;Foo;true;putsTaintIntoParameter;(List);Argument[-1];Argument[0];taint * ``` * - * ``` + * ```java * public class Foo { * private String tainted; * public void doSomething(String input) { @@ -123,9 +51,9 @@ class ThroughFlowConfig extends TaintTracking::Configuration { * } * ``` * Captured Model: - * `p;Foo;true;doSomething;(String);Argument[0];Argument[-1];taint` + * ```p;Foo;true;doSomething;(String);Argument[0];Argument[-1];taint``` * - * ``` + * ```java * public class Foo { * public String returnData(String tainted) { * return tainted.substring(0,10) @@ -133,9 +61,9 @@ class ThroughFlowConfig extends TaintTracking::Configuration { * } * ``` * Captured Model: - * `p;Foo;true;returnData;;Argument[0];ReturnValue;taint` + * ```p;Foo;true;returnData;;Argument[0];ReturnValue;taint``` * - * ``` + * ```java * public class Foo { * public void addToList(String tainted, List foo) { * foo.add(tainted); @@ -143,22 +71,13 @@ class ThroughFlowConfig extends TaintTracking::Configuration { * } * ``` * Captured Model: - * `p;Foo;true;addToList;;Argument[0];Argument[1];taint` + * ```p;Foo;true;addToList;;Argument[0];Argument[1];taint``` */ -string captureThroughFlow(TargetAPI api) { - exists( - ThroughFlowConfig config, DataFlow::ParameterNode p, ReturnNodeExt returnNodeExt, string input, - string output - | - config.hasFlow(p, returnNodeExt) and - returnNodeExt.getEnclosingCallable() = api and - input = parameterNodeAsInput(p) and - output = returnNodeAsOutput(returnNodeExt) and - input != output and - result = asTaintModel(api, input, output) - ) +string captureFlow(TargetApi api) { + result = captureQualifierFlow(api) or + result = captureThroughFlow(api) } -from TargetAPI api, string flow +from TargetApi api, string flow where flow = captureFlow(api) select flow order by flow diff --git a/java/ql/src/utils/model-generator/CaptureSummaryModels.qll b/java/ql/src/utils/model-generator/CaptureSummaryModels.qll new file mode 100644 index 00000000000..1c7df39d97f --- /dev/null +++ b/java/ql/src/utils/model-generator/CaptureSummaryModels.qll @@ -0,0 +1,98 @@ +/** + * Provides classes and predicates related to capturing summary models + * of the Standard or a 3rd party library. + */ + +import CaptureSummaryModelsSpecific + +/** + * Gets the summary model of `api`, if it follows the `fluent` programming pattern (returns `this`). + */ +string captureQualifierFlow(TargetApi api) { + exists(ReturnNodeExt ret | + api = returnNodeEnclosingCallable(ret) and + isOwnInstanceAccessNode(ret) + ) and + result = asValueModel(api, qualifierString(), "ReturnValue") +} + +/** + * A FlowState representing a tainted read. + */ +private class TaintRead extends DataFlow::FlowState { + TaintRead() { this = "TaintRead" } +} + +/** + * A FlowState representing a tainted write. + */ +private class TaintStore extends DataFlow::FlowState { + TaintStore() { this = "TaintStore" } +} + +/** + * A TaintTracking Configuration used for tracking flow through APIs. + * The sources are the parameters of an API and the sinks are the return values (excluding `this`) and parameters. + * + * This can be used to generate Flow summaries for APIs from parameter to return. + */ +class ThroughFlowConfig extends TaintTracking::Configuration { + ThroughFlowConfig() { this = "ThroughFlowConfig" } + + override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { + source instanceof DataFlow::ParameterNode and + source.getEnclosingCallable() instanceof TargetApi and + state instanceof TaintRead + } + + override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { + sink instanceof ReturnNodeExt and + not isOwnInstanceAccessNode(sink) and + not exists(captureQualifierFlow(sink.asExpr().getEnclosingCallable())) and + (state instanceof TaintRead or state instanceof TaintStore) + } + + override predicate isAdditionalTaintStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + exists(TypedContent tc | + store(node1, tc, node2, _) and + isRelevantContent(tc.getContent()) and + (state1 instanceof TaintRead or state1 instanceof TaintStore) and + state2 instanceof TaintStore + ) + or + exists(DataFlow::Content c | + readStep(node1, c, node2) and + isRelevantContent(c) and + state1 instanceof TaintRead and + state2 instanceof TaintRead + ) + } + + override predicate isSanitizer(DataFlow::Node n) { + exists(Type t | t = n.getType() and not isRelevantType(t)) + } + + override DataFlow::FlowFeature getAFeature() { + result instanceof DataFlow::FeatureEqualSourceSinkCallContext + } +} + +/** + * Gets the summary model(s) of `api`, if there is flow from parameters to return value or parameter. + */ +string captureThroughFlow(TargetApi api) { + exists( + ThroughFlowConfig config, DataFlow::ParameterNode p, ReturnNodeExt returnNodeExt, string input, + string output + | + config.hasFlow(p, returnNodeExt) and + returnNodeExt.getEnclosingCallable() = api and + input = parameterNodeAsInput(p) and + output = returnNodeAsOutput(returnNodeExt) and + input != output and + result = asTaintModel(api, input, output) + ) +} diff --git a/java/ql/src/utils/model-generator/CaptureSummaryModelsSpecific.qll b/java/ql/src/utils/model-generator/CaptureSummaryModelsSpecific.qll new file mode 100644 index 00000000000..8a57fde63f9 --- /dev/null +++ b/java/ql/src/utils/model-generator/CaptureSummaryModelsSpecific.qll @@ -0,0 +1,21 @@ +/** + * Provides predicates related to capturing summary models of the Standard or a 3rd party library. + */ + +import java +import semmle.code.java.dataflow.TaintTracking +import semmle.code.java.dataflow.internal.DataFlowImplCommon +import semmle.code.java.dataflow.internal.DataFlowNodes +import semmle.code.java.dataflow.internal.DataFlowPrivate +import semmle.code.java.dataflow.InstanceAccess +import ModelGeneratorUtils + +Callable returnNodeEnclosingCallable(ReturnNodeExt ret) { + result = getNodeEnclosingCallable(ret).asCallable() +} + +predicate isOwnInstanceAccessNode(ReturnNode node) { + node.asExpr().(ThisAccess).isOwnInstanceAccess() +} + +string qualifierString() { result = "Argument[-1]" } diff --git a/java/ql/src/utils/model-generator/ModelGeneratorUtils.qll b/java/ql/src/utils/model-generator/ModelGeneratorUtils.qll index f990a2e2fad..05e3d6cbf38 100644 --- a/java/ql/src/utils/model-generator/ModelGeneratorUtils.qll +++ b/java/ql/src/utils/model-generator/ModelGeneratorUtils.qll @@ -1,140 +1,8 @@ -import java -private import semmle.code.java.dataflow.ExternalFlow -private import semmle.code.java.dataflow.internal.ContainerFlow -private import semmle.code.java.dataflow.internal.DataFlowImplCommon -private import semmle.code.java.dataflow.DataFlow -private import semmle.code.java.dataflow.internal.DataFlowPrivate - -Method superImpl(Method m) { - result = m.getAnOverride() and - not exists(result.getAnOverride()) and - not m instanceof ToStringMethod -} - -class TargetAPI extends Callable { - TargetAPI() { - this.isPublic() and - this.fromSource() and - ( - this.getDeclaringType().isPublic() or - superImpl(this).getDeclaringType().isPublic() - ) and - isRelevantForModels(this) - } -} - -private string isExtensible(RefType ref) { - if ref.isFinal() then result = "false" else result = "true" -} - -predicate isRelevantForModels(Callable api) { - not isInTestFile(api.getCompilationUnit().getFile()) and - not isJdkInternal(api.getCompilationUnit()) and - not api instanceof MainMethod -} - -private predicate isInTestFile(File file) { - file.getAbsolutePath().matches("%src/test/%") or - file.getAbsolutePath().matches("%/guava-tests/%") or - file.getAbsolutePath().matches("%/guava-testlib/%") -} - -private predicate isJdkInternal(CompilationUnit cu) { - cu.getPackage().getName().matches("org.graalvm%") or - cu.getPackage().getName().matches("com.sun%") or - cu.getPackage().getName().matches("javax.swing%") or - cu.getPackage().getName().matches("java.awt%") or - cu.getPackage().getName().matches("sun%") or - cu.getPackage().getName().matches("jdk.%") or - cu.getPackage().getName().matches("java2d.%") or - cu.getPackage().getName().matches("build.tools.%") or - cu.getPackage().getName().matches("propertiesparser.%") or - cu.getPackage().getName().matches("org.jcp.%") or - cu.getPackage().getName().matches("org.w3c.%") or - cu.getPackage().getName().matches("org.ietf.jgss.%") or - cu.getPackage().getName().matches("org.xml.sax%") or - cu.getPackage().getName() = "compileproperties" or - cu.getPackage().getName() = "netscape.javascript" or - cu.getPackage().getName() = "" -} - -bindingset[input, output] -string asTaintModel(TargetAPI api, string input, string output) { - result = asSummaryModel(api, input, output, "taint") -} - -bindingset[input, output] -string asValueModel(TargetAPI api, string input, string output) { - result = asSummaryModel(api, input, output, "value") -} - -bindingset[input, output, kind] -string asSummaryModel(TargetAPI api, string input, string output, string kind) { - result = - asPartialModel(api) + input + ";" // - + output + ";" // - + kind -} - -bindingset[input, kind] -string asSinkModel(TargetAPI api, string input, string kind) { - result = asPartialModel(api) + input + ";" + kind -} - -bindingset[output, kind] -string asSourceModel(TargetAPI api, string output, string kind) { - result = asPartialModel(api) + output + ";" + kind -} +import ModelGeneratorUtilsSpecific /** - * Computes the first 6 columns for CSV rows. + * Holds if data can flow from `node1` to `node2` either via a read or a write of an intermediate field `f`. */ -private string asPartialModel(TargetAPI api) { - result = - typeAsSummaryModel(api) + ";" // - + isExtensible(bestTypeForModel(api)) + ";" // - + api.getName() + ";" // - + paramsString(api) + ";" // - + /* ext + */ ";" // -} - -/** - * Returns the appropriate type name for the model. Either the type - * declaring the method or the supertype introducing the method. - */ -private string typeAsSummaryModel(TargetAPI api) { result = typeAsModel(bestTypeForModel(api)) } - -private RefType bestTypeForModel(TargetAPI api) { - if exists(superImpl(api)) - then superImpl(api).fromSource() and result = superImpl(api).getDeclaringType() - else result = api.getDeclaringType() -} - -private string typeAsModel(RefType type) { - result = type.getCompilationUnit().getPackage().getName() + ";" + type.nestedName() -} - -predicate isRelevantType(Type t) { - not t instanceof TypeClass and - not t instanceof EnumType and - not t instanceof PrimitiveType and - not t instanceof BoxedType and - not t.(RefType).getAnAncestor().hasQualifiedName("java.lang", "Number") and - not t.(RefType).getAnAncestor().hasQualifiedName("java.nio.charset", "Charset") and - ( - not t.(Array).getElementType() instanceof PrimitiveType or - isPrimitiveTypeUsedForBulkData(t.(Array).getElementType()) - ) and - ( - not t.(Array).getElementType() instanceof BoxedType or - isPrimitiveTypeUsedForBulkData(t.(Array).getElementType()) - ) and - ( - not t.(CollectionType).getElementType() instanceof BoxedType or - isPrimitiveTypeUsedForBulkData(t.(CollectionType).getElementType()) - ) -} - predicate isRelevantTaintStep(DataFlow::Node node1, DataFlow::Node node2) { exists(DataFlow::Content f | readStep(node1, f, node2) and @@ -146,50 +14,58 @@ predicate isRelevantTaintStep(DataFlow::Node node1, DataFlow::Node node2) { else any() ) or - exists(DataFlow::Content f | storeStep(node1, f, node2) | - f instanceof DataFlow::ArrayContent or - f instanceof DataFlow::CollectionContent or - f instanceof DataFlow::MapKeyContent or - f instanceof DataFlow::MapValueContent - ) + exists(DataFlow::Content f | storeStep(node1, f, node2) | containerContent(f)) } -predicate isRelevantContent(DataFlow::Content f) { - isRelevantType(f.(DataFlow::FieldContent).getField().getType()) or - f instanceof DataFlow::ArrayContent or - f instanceof DataFlow::CollectionContent or - f instanceof DataFlow::MapKeyContent or - f instanceof DataFlow::MapValueContent +/** + * Holds if content `c` is either a field or synthetic field of a relevant type + * or a container like content. + */ +predicate isRelevantContent(DataFlow::Content c) { + isRelevantType(c.(DataFlow::FieldContent).getField().getType()) or + isRelevantType(c.(DataFlow::SyntheticFieldContent).getField().getType()) or + containerContent(c) } -string parameterNodeAsInput(DataFlow::ParameterNode p) { - result = parameterAccess(p.asParameter()) - or - result = "Argument[-1]" and p instanceof DataFlow::InstanceParameterNode +/** + * Gets the summary model for `api` with `input`, `output` and `kind`. + */ +bindingset[input, output, kind] +string asSummaryModel(TargetApi api, string input, string output, string kind) { + result = + asPartialModel(api) + input + ";" // + + output + ";" // + + kind } -string returnNodeAsOutput(ReturnNodeExt node) { - if node.getKind() instanceof ValueReturnKind - then result = "ReturnValue" - else - exists(int pos | pos = node.getKind().(ParamUpdateReturnKind).getPosition() | - result = parameterAccess(node.getEnclosingCallable().getParameter(pos)) - or - result = "Argument[-1]" and pos = -1 - ) +/** + * Gets the value summary model for `api` with `input` and `output`. + */ +bindingset[input, output] +string asValueModel(TargetApi api, string input, string output) { + result = asSummaryModel(api, input, output, "value") } -string parameterAccess(Parameter p) { - if - p.getType() instanceof Array and - not isPrimitiveTypeUsedForBulkData(p.getType().(Array).getElementType()) - then result = "Argument[" + p.getPosition() + "].ArrayElement" - else - if p.getType() instanceof ContainerType - then result = "Argument[" + p.getPosition() + "].Element" - else result = "Argument[" + p.getPosition() + "]" +/** + * Gets the taint summary model for `api` with `input` and `output`. + */ +bindingset[input, output] +string asTaintModel(TargetApi api, string input, string output) { + result = asSummaryModel(api, input, output, "taint") } -predicate isPrimitiveTypeUsedForBulkData(Type t) { - t.getName().regexpMatch("byte|char|Byte|Character") +/** + * Gets the sink model for `api` with `input` and `kind`. + */ +bindingset[input, kind] +string asSinkModel(TargetApi api, string input, string kind) { + result = asPartialModel(api) + input + ";" + kind +} + +/** + * Gets the source model for `api` with `output` and `kind`. + */ +bindingset[output, kind] +string asSourceModel(TargetApi api, string output, string kind) { + result = asPartialModel(api) + output + ";" + kind } diff --git a/java/ql/src/utils/model-generator/ModelGeneratorUtilsSpecific.qll b/java/ql/src/utils/model-generator/ModelGeneratorUtilsSpecific.qll new file mode 100644 index 00000000000..6832f0773a9 --- /dev/null +++ b/java/ql/src/utils/model-generator/ModelGeneratorUtilsSpecific.qll @@ -0,0 +1,156 @@ +import java +import semmle.code.java.dataflow.internal.DataFlowPrivate +import semmle.code.java.dataflow.DataFlow +private import semmle.code.java.dataflow.ExternalFlow +private import semmle.code.java.dataflow.internal.ContainerFlow +private import semmle.code.java.dataflow.internal.DataFlowImplCommon + +Method superImpl(Method m) { + result = m.getAnOverride() and + not exists(result.getAnOverride()) and + not m instanceof ToStringMethod +} + +private predicate isInTestFile(File file) { + file.getAbsolutePath().matches("%src/test/%") or + file.getAbsolutePath().matches("%/guava-tests/%") or + file.getAbsolutePath().matches("%/guava-testlib/%") +} + +private predicate isJdkInternal(CompilationUnit cu) { + cu.getPackage().getName().matches("org.graalvm%") or + cu.getPackage().getName().matches("com.sun%") or + cu.getPackage().getName().matches("javax.swing%") or + cu.getPackage().getName().matches("java.awt%") or + cu.getPackage().getName().matches("sun%") or + cu.getPackage().getName().matches("jdk.%") or + cu.getPackage().getName().matches("java2d.%") or + cu.getPackage().getName().matches("build.tools.%") or + cu.getPackage().getName().matches("propertiesparser.%") or + cu.getPackage().getName().matches("org.jcp.%") or + cu.getPackage().getName().matches("org.w3c.%") or + cu.getPackage().getName().matches("org.ietf.jgss.%") or + cu.getPackage().getName().matches("org.xml.sax%") or + cu.getPackage().getName() = "compileproperties" or + cu.getPackage().getName() = "netscape.javascript" or + cu.getPackage().getName() = "" +} + +predicate isRelevantForModels(Callable api) { + not isInTestFile(api.getCompilationUnit().getFile()) and + not isJdkInternal(api.getCompilationUnit()) and + not api instanceof MainMethod +} + +/** + * A class of Callables that are relevant for generating summary, source and sinks models for. + * + * In the Standard library and 3rd party libraries it the Callables that can be called + * from outside the library itself. + */ +class TargetApi extends Callable { + TargetApi() { + this.isPublic() and + this.fromSource() and + ( + this.getDeclaringType().isPublic() or + superImpl(this).getDeclaringType().isPublic() + ) and + isRelevantForModels(this) + } +} + +private string isExtensible(RefType ref) { + if ref.isFinal() then result = "false" else result = "true" +} + +private string typeAsModel(RefType type) { + result = type.getCompilationUnit().getPackage().getName() + ";" + type.nestedName() +} + +private RefType bestTypeForModel(TargetApi api) { + if exists(superImpl(api)) + then superImpl(api).fromSource() and result = superImpl(api).getDeclaringType() + else result = api.getDeclaringType() +} + +/** + * Returns the appropriate type name for the model. Either the type + * declaring the method or the supertype introducing the method. + */ +private string typeAsSummaryModel(TargetApi api) { result = typeAsModel(bestTypeForModel(api)) } + +/** + * Computes the first 6 columns for CSV rows. + */ +string asPartialModel(TargetApi api) { + result = + typeAsSummaryModel(api) + ";" // + + isExtensible(bestTypeForModel(api)) + ";" // + + api.getName() + ";" // + + paramsString(api) + ";" // + + /* ext + */ ";" // +} + +private predicate isPrimitiveTypeUsedForBulkData(Type t) { + t.getName().regexpMatch("byte|char|Byte|Character") +} + +/** + * Holds for type `t` for fields that are relevant as an intermediate + * read or write step in the data flow analysis. + */ +predicate isRelevantType(Type t) { + not t instanceof TypeClass and + not t instanceof EnumType and + not t instanceof PrimitiveType and + not t instanceof BoxedType and + not t.(RefType).getAnAncestor().hasQualifiedName("java.lang", "Number") and + not t.(RefType).getAnAncestor().hasQualifiedName("java.nio.charset", "Charset") and + ( + not t.(Array).getElementType() instanceof PrimitiveType or + isPrimitiveTypeUsedForBulkData(t.(Array).getElementType()) + ) and + ( + not t.(Array).getElementType() instanceof BoxedType or + isPrimitiveTypeUsedForBulkData(t.(Array).getElementType()) + ) and + ( + not t.(CollectionType).getElementType() instanceof BoxedType or + isPrimitiveTypeUsedForBulkData(t.(CollectionType).getElementType()) + ) +} + +private string parameterAccess(Parameter p) { + if + p.getType() instanceof Array and + not isPrimitiveTypeUsedForBulkData(p.getType().(Array).getElementType()) + then result = "Argument[" + p.getPosition() + "].ArrayElement" + else + if p.getType() instanceof ContainerType + then result = "Argument[" + p.getPosition() + "].Element" + else result = "Argument[" + p.getPosition() + "]" +} + +/** + * Gets the model string representation of the parameter node `p`. + */ +string parameterNodeAsInput(DataFlow::ParameterNode p) { + result = parameterAccess(p.asParameter()) + or + result = "Argument[-1]" and p instanceof DataFlow::InstanceParameterNode +} + +/** + * Gets the model string represention of the the return node `node`. + */ +string returnNodeAsOutput(ReturnNodeExt node) { + if node.getKind() instanceof ValueReturnKind + then result = "ReturnValue" + else + exists(int pos | pos = node.getKind().(ParamUpdateReturnKind).getPosition() | + result = parameterAccess(node.getEnclosingCallable().getParameter(pos)) + or + result = "Argument[-1]" and pos = -1 + ) +} diff --git a/java/ql/test/TestUtilities/InlineExpectationsTest.qll b/java/ql/test/TestUtilities/InlineExpectationsTest.qll index 7d605a491ee..a4d264b2703 100644 --- a/java/ql/test/TestUtilities/InlineExpectationsTest.qll +++ b/java/ql/test/TestUtilities/InlineExpectationsTest.qll @@ -124,7 +124,9 @@ abstract class InlineExpectationsTest extends string { abstract predicate hasActualResult(Location location, string element, string tag, string value); /** - * Like `hasActualResult`, but returns results that do not require a matching annotation. + * Holds if there is an optional result on the specified location. + * + * This is similar to `hasActualResult`, but returns results that do not require a matching annotation. * A failure will still arise if there is an annotation that does not match any results, but not vice versa. * Override this predicate to specify optional results. */ diff --git a/java/ql/test/library-tests/constants/getBooleanValue.ql b/java/ql/test/library-tests/constants/getBooleanValue.ql index 2b10d95ff9b..460af42d3c3 100644 --- a/java/ql/test/library-tests/constants/getBooleanValue.ql +++ b/java/ql/test/library-tests/constants/getBooleanValue.ql @@ -1,9 +1,9 @@ import semmle.code.java.Variable -from Variable v, Expr init, RefType enclosing, boolean constant +from Variable v, CompileTimeConstantExpr init, RefType enclosing, boolean constant where v.getInitializer() = init and init.getEnclosingCallable().getDeclaringType() = enclosing and enclosing.hasQualifiedName("constants", "Values") and - constant = init.(CompileTimeConstantExpr).getBooleanValue() + constant = init.getBooleanValue() select init, constant diff --git a/java/ql/test/library-tests/constants/getIntValue.ql b/java/ql/test/library-tests/constants/getIntValue.ql index dbb2c5bd967..5fc5b108032 100644 --- a/java/ql/test/library-tests/constants/getIntValue.ql +++ b/java/ql/test/library-tests/constants/getIntValue.ql @@ -1,9 +1,9 @@ import semmle.code.java.Variable -from Variable v, Expr init, RefType enclosing, int constant +from Variable v, CompileTimeConstantExpr init, RefType enclosing, int constant where v.getInitializer() = init and init.getEnclosingCallable().getDeclaringType() = enclosing and enclosing.hasQualifiedName("constants", "Values") and - constant = init.(CompileTimeConstantExpr).getIntValue() + constant = init.getIntValue() select init, constant diff --git a/java/ql/test/library-tests/frameworks/JaxWs/JaxRs.ql b/java/ql/test/library-tests/frameworks/JaxWs/JaxRs.ql index bc4916c217c..1b266b35ee5 100644 --- a/java/ql/test/library-tests/frameworks/JaxWs/JaxRs.ql +++ b/java/ql/test/library-tests/frameworks/JaxWs/JaxRs.ql @@ -55,7 +55,7 @@ class JaxRsTest extends InlineExpectationsTest { or tag = "ResourceMethodOnResourceClass" and exists(JaxRsResourceMethod resourceMethod | - resourceMethod = any(JaxRsResourceClass ResourceClass).getAResourceMethod() + resourceMethod = any(JaxRsResourceClass resourceClass).getAResourceMethod() | resourceMethod.getLocation() = location and element = resourceMethod.toString() and diff --git a/java/ql/test/library-tests/ssa/ssaDef.ql b/java/ql/test/library-tests/ssa/ssaDef.ql index 9f08ddc0c40..c487c539e78 100644 --- a/java/ql/test/library-tests/ssa/ssaDef.ql +++ b/java/ql/test/library-tests/ssa/ssaDef.ql @@ -9,4 +9,4 @@ where or not exists(ssa.toString()) and s = "error" ) -select v, ssa.getCFGNode(), s +select v, ssa.getCfgNode(), s diff --git a/java/ql/test/library-tests/ssa/ssaPhi.ql b/java/ql/test/library-tests/ssa/ssaPhi.ql index 11fc2d8d595..8aa0942e90a 100644 --- a/java/ql/test/library-tests/ssa/ssaPhi.ql +++ b/java/ql/test/library-tests/ssa/ssaPhi.ql @@ -3,4 +3,4 @@ import semmle.code.java.dataflow.SSA from SsaPhiNode ssa, SsaSourceVariable v, SsaVariable phiInput where ssa.getAPhiInput() = phiInput and ssa.getSourceVariable() = v -select v, ssa.getCFGNode(), phiInput.getCFGNode() +select v, ssa.getCfgNode(), phiInput.getCfgNode() diff --git a/java/ql/test/library-tests/ssa/ssaUse.ql b/java/ql/test/library-tests/ssa/ssaUse.ql index 53414a88064..cab6f47c955 100644 --- a/java/ql/test/library-tests/ssa/ssaUse.ql +++ b/java/ql/test/library-tests/ssa/ssaUse.ql @@ -3,4 +3,4 @@ import semmle.code.java.dataflow.SSA from SsaVariable ssa, SsaSourceVariable v, Expr use where use = ssa.getAUse() and ssa.getSourceVariable() = v -select v, ssa.getCFGNode(), ssa.toString(), use +select v, ssa.getCfgNode(), ssa.toString(), use diff --git a/java/ql/test/library-tests/structure/TypeGetCompilationUnit.ql b/java/ql/test/library-tests/structure/TypeGetCompilationUnit.ql index f3a335b8fc0..c0143989b1e 100644 --- a/java/ql/test/library-tests/structure/TypeGetCompilationUnit.ql +++ b/java/ql/test/library-tests/structure/TypeGetCompilationUnit.ql @@ -2,8 +2,8 @@ import semmle.code.java.Type predicate typeIsInCU(Type tpe, CompilationUnit cu) { tpe.getCompilationUnit() = cu } -from Type tpe, CompilationUnit Ajava +from Type tpe, CompilationUnit aJava where - Ajava.hasName("A") and - typeIsInCU(tpe, Ajava) + aJava.hasName("A") and + typeIsInCU(tpe, aJava) select tpe diff --git a/java/ql/test/query-tests/security/CWE-079/semmle/tests/XSS.ql b/java/ql/test/query-tests/security/CWE-079/semmle/tests/XSS.ql index 6bfde865e85..afb0f7ae3e1 100644 --- a/java/ql/test/query-tests/security/CWE-079/semmle/tests/XSS.ql +++ b/java/ql/test/query-tests/security/CWE-079/semmle/tests/XSS.ql @@ -3,8 +3,8 @@ import semmle.code.java.dataflow.FlowSources import semmle.code.java.security.XSS import TestUtilities.InlineExpectationsTest -class XSSConfig extends TaintTracking::Configuration { - XSSConfig() { this = "XSSConfig" } +class XssConfig extends TaintTracking::Configuration { + XssConfig() { this = "XSSConfig" } override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } @@ -24,7 +24,7 @@ class XssTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "xss" and - exists(DataFlow::Node src, DataFlow::Node sink, XSSConfig conf | conf.hasFlow(src, sink) | + exists(DataFlow::Node src, DataFlow::Node sink, XssConfig conf | conf.hasFlow(src, sink) | sink.getLocation() = location and element = sink.toString() and value = "" diff --git a/java/ql/test/query-tests/security/CWE-532/SensitiveLogInfo.expected b/java/ql/test/query-tests/security/CWE-532/SensitiveLogInfo.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/query-tests/security/CWE-532/SensitiveLogInfo.ql b/java/ql/test/query-tests/security/CWE-532/SensitiveLogInfo.ql new file mode 100644 index 00000000000..aac128a263d --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-532/SensitiveLogInfo.ql @@ -0,0 +1,11 @@ +import java +import TestUtilities.InlineFlowTest +import semmle.code.java.security.SensitiveLoggingQuery + +class HasFlowTest extends InlineFlowTest { + override DataFlow::Configuration getTaintFlowConfig() { + result instanceof SensitiveLoggerConfiguration + } + + override DataFlow::Configuration getValueFlowConfig() { none() } +} diff --git a/java/ql/test/query-tests/security/CWE-532/Test.java b/java/ql/test/query-tests/security/CWE-532/Test.java new file mode 100644 index 00000000000..d70355651a3 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-532/Test.java @@ -0,0 +1,16 @@ +import org.apache.logging.log4j.Logger; + +class Test { + void test(String password) { + Logger logger = null; + + logger.info("User's password is: " + password); // $ hasTaintFlow + } + + void test2(String authToken) { + Logger logger = null; + + logger.error("Auth failed for: " + authToken); // $ hasTaintFlow + } + +} \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-532/options b/java/ql/test/query-tests/security/CWE-532/options new file mode 100644 index 00000000000..01138ecc34b --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-532/options @@ -0,0 +1 @@ +//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/apache-log4j-1.2.17:${testdir}/../../../stubs/apache-log4j-2.14.1:${testdir}/../../../stubs/apache-commons-logging-1.2:${testdir}/../../../stubs/jboss-logging-3.4.2:${testdir}/../../../stubs/slf4j-2.0.0:${testdir}/../../../stubs/scijava-common-2.87.1:${testdir}/../../../stubs/flogger-0.7.1:${testdir}/../../../stubs/google-android-9.0.0 \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-918/JdbcUrlSSRF.java b/java/ql/test/query-tests/security/CWE-918/JdbcUrlSSRF.java new file mode 100644 index 00000000000..fa202ef0373 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-918/JdbcUrlSSRF.java @@ -0,0 +1,91 @@ +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.sql.DriverManager; +import java.sql.Driver; +import java.sql.SQLException; +import java.io.IOException; +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; +import java.util.*; +import org.springframework.jdbc.datasource.*; +import org.jdbi.v3.core.Jdbi; +import org.springframework.boot.jdbc.DataSourceBuilder; + +public class JdbcUrlSSRF extends HttpServlet { + + protected void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + + String jdbcUrl = request.getParameter("jdbcUrl"); + Driver driver = new org.postgresql.Driver(); + DataSourceBuilder dsBuilder = new DataSourceBuilder(); + + try { + driver.connect(jdbcUrl, null); // $ SSRF + + DriverManager.getConnection(jdbcUrl); // $ SSRF + DriverManager.getConnection(jdbcUrl, "user", "password"); // $ SSRF + DriverManager.getConnection(jdbcUrl, null); // $ SSRF + + dsBuilder.url(jdbcUrl); // $ SSRF + } + catch(SQLException e) {} + } + + protected void doPost(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + + String jdbcUrl = request.getParameter("jdbcUrl"); + HikariConfig config = new HikariConfig(); + + config.setJdbcUrl(jdbcUrl); // $ SSRF + config.setUsername("database_username"); + config.setPassword("database_password"); + + HikariDataSource ds = new HikariDataSource(); + ds.setJdbcUrl(jdbcUrl); // $ SSRF + + Properties props = new Properties(); + props.setProperty("driverClassName", "org.postgresql.Driver"); + props.setProperty("jdbcUrl", jdbcUrl); + + HikariConfig config2 = new HikariConfig(props); // $ SSRF + } + + protected void doPut(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + + String jdbcUrl = request.getParameter("jdbcUrl"); + + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + + dataSource.setDriverClassName("org.postgresql.Driver"); + dataSource.setUrl(jdbcUrl); // $ SSRF + + DriverManagerDataSource dataSource2 = new DriverManagerDataSource(jdbcUrl); // $ SSRF + dataSource2.setDriverClassName("org.postgresql.Driver"); + + DriverManagerDataSource dataSource3 = new DriverManagerDataSource(jdbcUrl, "user", "pass"); // $ SSRF + dataSource3.setDriverClassName("org.postgresql.Driver"); + + DriverManagerDataSource dataSource4 = new DriverManagerDataSource(jdbcUrl, null); // $ SSRF + dataSource4.setDriverClassName("org.postgresql.Driver"); + } + + protected void doDelete(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + + String jdbcUrl = request.getParameter("jdbcUrl"); + + Jdbi.create(jdbcUrl); // $ SSRF + Jdbi.create(jdbcUrl, null); // $ SSRF + Jdbi.create(jdbcUrl, "user", "pass"); // $ SSRF + + Jdbi.open(jdbcUrl); // $ SSRF + Jdbi.open(jdbcUrl, null); // $ SSRF + Jdbi.open(jdbcUrl, "user", "pass"); // $ SSRF + } + +} \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-918/options b/java/ql/test/query-tests/security/CWE-918/options index 87db9eacec3..5776b35fe9f 100644 --- a/java/ql/test/query-tests/security/CWE-918/options +++ b/java/ql/test/query-tests/security/CWE-918/options @@ -1,2 +1,2 @@ -//semmle-extractor-options: --javac-args -source 11 -target 11 -cp ${testdir}/../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/javax-ws-rs-api-2.1.1:${testdir}/../../../stubs/javax-ws-rs-api-3.0.0:${testdir}/../../../stubs/apache-http-4.4.13/:${testdir}/../../../stubs/servlet-api-2.4/:${testdir}/../../../stubs/projectreactor-3.4.3/ +//semmle-extractor-options: --javac-args -source 11 -target 11 -cp ${testdir}/../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/javax-ws-rs-api-2.1.1:${testdir}/../../../stubs/javax-ws-rs-api-3.0.0:${testdir}/../../../stubs/apache-http-4.4.13/:${testdir}/../../../stubs/servlet-api-2.4/:${testdir}/../../../stubs/projectreactor-3.4.3/:${testdir}/../../../stubs/postgresql-42.3.3/:${testdir}/../../../stubs/HikariCP-3.4.5/:${testdir}/../../../stubs/spring-jdbc-5.3.8/:${testdir}/../../../stubs/jdbi3-core-3.27.2/ diff --git a/java/ql/test/stubs/HikariCP-3.4.5/com/zaxxer/hikari/HikariConfig.java b/java/ql/test/stubs/HikariCP-3.4.5/com/zaxxer/hikari/HikariConfig.java new file mode 100644 index 00000000000..f8ae9aaccb9 --- /dev/null +++ b/java/ql/test/stubs/HikariCP-3.4.5/com/zaxxer/hikari/HikariConfig.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2013, 2014 Brett Wooldridge + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.zaxxer.hikari; + + +public class HikariConfig implements HikariConfigMXBean { + + private String jdbcUrl; + + public HikariConfig() { + } + + public HikariConfig(java.util.Properties properties) { + + } + + public HikariConfig(String propertyFileName) { + } + + public String getJdbcUrl() { + return jdbcUrl; + } + + public void setJdbcUrl(String jdbcUrl) { + this.jdbcUrl = jdbcUrl; + } + + public long getConnectionTimeout() { return 0; } + + public void setConnectionTimeout(long connectionTimeoutMs) {} + + public long getValidationTimeout() { return 0; } + + public void setValidationTimeout(long validationTimeoutMs) {} + + public long getIdleTimeout() { return 0; } + + public void setIdleTimeout(long idleTimeoutMs) {} + + public long getLeakDetectionThreshold() { return 0; } + + public void setLeakDetectionThreshold(long leakDetectionThresholdMs) {} + + public long getMaxLifetime() { return 0; } + + public void setMaxLifetime(long maxLifetimeMs) {} + + public int getMinimumIdle() { return 0; } + + public void setMinimumIdle(int minIdle) {} + + public int getMaximumPoolSize() { return 0; } + + public void setMaximumPoolSize(int maxPoolSize) {} + + public void setPassword(String password) {} + + public void setUsername(String username) {} + + public String getPoolName() {return "";} + + public String getCatalog() {return "";} + + public void setCatalog(String catalog) {} +} \ No newline at end of file diff --git a/java/ql/test/stubs/HikariCP-3.4.5/com/zaxxer/hikari/HikariConfigMXBean.java b/java/ql/test/stubs/HikariCP-3.4.5/com/zaxxer/hikari/HikariConfigMXBean.java new file mode 100644 index 00000000000..2e510d53360 --- /dev/null +++ b/java/ql/test/stubs/HikariCP-3.4.5/com/zaxxer/hikari/HikariConfigMXBean.java @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2013 Brett Wooldridge + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.zaxxer.hikari; + +/** + * The javax.management MBean for a Hikari pool configuration. + * + * @author Brett Wooldridge + */ +public interface HikariConfigMXBean +{ + /** + * Get the maximum number of milliseconds that a client will wait for a connection from the pool. If this + * time is exceeded without a connection becoming available, a SQLException will be thrown from + * {@link javax.sql.DataSource#getConnection()}. + * + * @return the connection timeout in milliseconds + */ + long getConnectionTimeout(); + + /** + * Set the maximum number of milliseconds that a client will wait for a connection from the pool. If this + * time is exceeded without a connection becoming available, a SQLException will be thrown from + * {@link javax.sql.DataSource#getConnection()}. + * + * @param connectionTimeoutMs the connection timeout in milliseconds + */ + void setConnectionTimeout(long connectionTimeoutMs); + + /** + * Get the maximum number of milliseconds that the pool will wait for a connection to be validated as + * alive. + * + * @return the validation timeout in milliseconds + */ + long getValidationTimeout(); + + /** + * Sets the maximum number of milliseconds that the pool will wait for a connection to be validated as + * alive. + * + * @param validationTimeoutMs the validation timeout in milliseconds + */ + void setValidationTimeout(long validationTimeoutMs); + + /** + * This property controls the maximum amount of time (in milliseconds) that a connection is allowed to sit + * idle in the pool. Whether a connection is retired as idle or not is subject to a maximum variation of +30 + * seconds, and average variation of +15 seconds. A connection will never be retired as idle before this timeout. + * A value of 0 means that idle connections are never removed from the pool. + * + * @return the idle timeout in milliseconds + */ + long getIdleTimeout(); + + /** + * This property controls the maximum amount of time (in milliseconds) that a connection is allowed to sit + * idle in the pool. Whether a connection is retired as idle or not is subject to a maximum variation of +30 + * seconds, and average variation of +15 seconds. A connection will never be retired as idle before this timeout. + * A value of 0 means that idle connections are never removed from the pool. + * + * @param idleTimeoutMs the idle timeout in milliseconds + */ + void setIdleTimeout(long idleTimeoutMs); + + /** + * This property controls the amount of time that a connection can be out of the pool before a message is + * logged indicating a possible connection leak. A value of 0 means leak detection is disabled. + * + * @return the connection leak detection threshold in milliseconds + */ + long getLeakDetectionThreshold(); + + /** + * This property controls the amount of time that a connection can be out of the pool before a message is + * logged indicating a possible connection leak. A value of 0 means leak detection is disabled. + * + * @param leakDetectionThresholdMs the connection leak detection threshold in milliseconds + */ + void setLeakDetectionThreshold(long leakDetectionThresholdMs); + + /** + * This property controls the maximum lifetime of a connection in the pool. When a connection reaches this + * timeout, even if recently used, it will be retired from the pool. An in-use connection will never be + * retired, only when it is idle will it be removed. + * + * @return the maximum connection lifetime in milliseconds + */ + long getMaxLifetime(); + + /** + * This property controls the maximum lifetime of a connection in the pool. When a connection reaches this + * timeout, even if recently used, it will be retired from the pool. An in-use connection will never be + * retired, only when it is idle will it be removed. + * + * @param maxLifetimeMs the maximum connection lifetime in milliseconds + */ + void setMaxLifetime(long maxLifetimeMs); + + /** + * The property controls the minimum number of idle connections that HikariCP tries to maintain in the pool, + * including both idle and in-use connections. If the idle connections dip below this value, HikariCP will + * make a best effort to restore them quickly and efficiently. + * + * @return the minimum number of connections in the pool + */ + int getMinimumIdle(); + + /** + * The property controls the minimum number of idle connections that HikariCP tries to maintain in the pool, + * including both idle and in-use connections. If the idle connections dip below this value, HikariCP will + * make a best effort to restore them quickly and efficiently. + * + * @param minIdle the minimum number of idle connections in the pool to maintain + */ + void setMinimumIdle(int minIdle); + + /** + * The property controls the maximum number of connections that HikariCP will keep in the pool, + * including both idle and in-use connections. + * + * @return the maximum number of connections in the pool + */ + int getMaximumPoolSize(); + + /** + * The property controls the maximum size that the pool is allowed to reach, including both idle and in-use + * connections. Basically this value will determine the maximum number of actual connections to the database + * backend. + *

    + * When the pool reaches this size, and no idle connections are available, calls to getConnection() will + * block for up to connectionTimeout milliseconds before timing out. + * + * @param maxPoolSize the maximum number of connections in the pool + */ + void setMaximumPoolSize(int maxPoolSize); + + /** + * Set the password used for authentication. Changing this at runtime will apply to new connections only. + * Altering this at runtime only works for DataSource-based connections, not Driver-class or JDBC URL-based + * connections. + * + * @param password the database password + */ + void setPassword(String password); + + /** + * Set the username used for authentication. Changing this at runtime will apply to new connections only. + * Altering this at runtime only works for DataSource-based connections, not Driver-class or JDBC URL-based + * connections. + * + * @param username the database username + */ + void setUsername(String username); + + + /** + * The name of the connection pool. + * + * @return the name of the connection pool + */ + String getPoolName(); + + /** + * Get the default catalog name to be set on connections. + * + * @return the default catalog name + */ + String getCatalog(); + + /** + * Set the default catalog name to be set on connections. + *

    + * WARNING: THIS VALUE SHOULD ONLY BE CHANGED WHILE THE POOL IS SUSPENDED, AFTER CONNECTIONS HAVE BEEN EVICTED. + * + * @param catalog the catalog name, or null + */ + void setCatalog(String catalog); +} diff --git a/java/ql/test/stubs/HikariCP-3.4.5/com/zaxxer/hikari/HikariDataSource.java b/java/ql/test/stubs/HikariCP-3.4.5/com/zaxxer/hikari/HikariDataSource.java new file mode 100644 index 00000000000..2823f6dc3ce --- /dev/null +++ b/java/ql/test/stubs/HikariCP-3.4.5/com/zaxxer/hikari/HikariDataSource.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2013 Brett Wooldridge + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.zaxxer.hikari; + +import javax.sql.DataSource; +import java.io.Closeable; +import java.sql.*; +import java.util.logging.Logger; + + +public class HikariDataSource extends HikariConfig implements DataSource, Closeable { + + public HikariDataSource() { + } + + public HikariDataSource(HikariConfig configuration) { + } + + public Connection getConnection() throws SQLException { + return null; + } + + public Connection getConnection(String username, String password) + throws SQLException { + return null; + } + + public java.io.PrintWriter getLogWriter() throws SQLException { + return null; + } + + public void setLogWriter(java.io.PrintWriter out) throws SQLException { + } + + public void setLoginTimeout(int seconds) throws SQLException { + } + + public int getLoginTimeout() throws SQLException { + return 0; + } + + public Logger getParentLogger() throws SQLFeatureNotSupportedException { + return null; + } + + public T unwrap(java.lang.Class iface) throws java.sql.SQLException { + return null; + } + + public boolean isWrapperFor(java.lang.Class iface) throws java.sql.SQLException { + return true; + } + + public void close() { + } +} \ No newline at end of file diff --git a/java/ql/test/stubs/jdbi3-core-3.27.2/org/jdbi/v3/core/Handle.java b/java/ql/test/stubs/jdbi3-core-3.27.2/org/jdbi/v3/core/Handle.java new file mode 100644 index 00000000000..f6183d30603 --- /dev/null +++ b/java/ql/test/stubs/jdbi3-core-3.27.2/org/jdbi/v3/core/Handle.java @@ -0,0 +1,30 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jdbi.v3.core; + +import java.io.Closeable; +import java.sql.Connection; +import org.jdbi.v3.core.config.Configurable; + + +/** + * This represents a connection to the database system. It is a wrapper around + * a JDBC Connection object. Handle provides essential methods for transaction + * management, statement creation, and other operations tied to the database session. + */ +public class Handle implements Closeable, Configurable { + + public void close() { + } +} \ No newline at end of file diff --git a/java/ql/test/stubs/jdbi3-core-3.27.2/org/jdbi/v3/core/Jdbi.java b/java/ql/test/stubs/jdbi3-core-3.27.2/org/jdbi/v3/core/Jdbi.java new file mode 100644 index 00000000000..ca7d10180c0 --- /dev/null +++ b/java/ql/test/stubs/jdbi3-core-3.27.2/org/jdbi/v3/core/Jdbi.java @@ -0,0 +1,78 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jdbi.v3.core; + +import org.jdbi.v3.core.config.Configurable; +import java.util.Properties; + +public class Jdbi implements Configurable { + + public static Jdbi create(final String url) { + return null; + } + + /** + * Creates a new {@link Jdbi} instance from a database URL. + * + * @param url JDBC URL for connections + * @param properties Properties to pass to DriverManager.getConnection(url, props) for each new handle + * + * @return a Jdbi which uses {@link DriverManager} as a connection factory. + */ + public static Jdbi create(final String url, final Properties properties) { + return null; + } + + /** + * Creates a new {@link Jdbi} instance from a database URL. + * + * @param url JDBC URL for connections + * @param username User name for connection authentication + * @param password Password for connection authentication + * + * @return a Jdbi which uses {@link DriverManager} as a connection factory. + */ + public static Jdbi create(final String url, final String username, final String password) { + return null; + } + + public static Handle open(final String url) { + return null; + } + + /** + * Obtain a handle with just a JDBC URL + * + * @param url JDBC Url + * @param username JDBC username for authentication + * @param password JDBC password for authentication + * + * @return newly opened Handle + */ + public static Handle open(final String url, final String username, final String password) { + return null; + } + + /** + * Obtain a handle with just a JDBC URL + * + * @param url JDBC Url + * @param props JDBC properties + * + * @return newly opened Handle + */ + public static Handle open(final String url, final Properties props) { + return null; + } +} \ No newline at end of file diff --git a/java/ql/test/stubs/jdbi3-core-3.27.2/org/jdbi/v3/core/config/Configurable.java b/java/ql/test/stubs/jdbi3-core-3.27.2/org/jdbi/v3/core/config/Configurable.java new file mode 100644 index 00000000000..ae3f5ebf6bc --- /dev/null +++ b/java/ql/test/stubs/jdbi3-core-3.27.2/org/jdbi/v3/core/config/Configurable.java @@ -0,0 +1,24 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jdbi.v3.core.config; + + +/** + * A type with access to access and modify arbitrary Jdbi configuration. + * + * @param The subtype that implements this interface. + */ +public interface Configurable { +} + diff --git a/java/ql/test/stubs/postgresql-42.3.3/org/postgresql/Driver.java b/java/ql/test/stubs/postgresql-42.3.3/org/postgresql/Driver.java new file mode 100644 index 00000000000..e84ba28d55e --- /dev/null +++ b/java/ql/test/stubs/postgresql-42.3.3/org/postgresql/Driver.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2003, PostgreSQL Global Development Group + * See the LICENSE file in the project root for more information. + */ +package org.postgresql; + +import java.util.logging.Logger; +import java.sql.*; + +public class Driver implements java.sql.Driver { + + public Connection connect(String url, java.util.Properties info) throws SQLException { + return null; + } + + public boolean acceptsURL(String url) throws SQLException { + return true; + } + + public DriverPropertyInfo[] getPropertyInfo(String url, java.util.Properties info) + throws SQLException { + return null; + } + + public int getMajorVersion() { + return 0; + } + + public int getMinorVersion() { + return 0; + } + + + public boolean jdbcCompliant() { + return true; + } + + + public Logger getParentLogger() throws SQLFeatureNotSupportedException { + return null; + } +} diff --git a/java/ql/test/stubs/spring-jdbc-5.3.8/org/springframework/jdbc/datasource/AbstractDataSource.java b/java/ql/test/stubs/spring-jdbc-5.3.8/org/springframework/jdbc/datasource/AbstractDataSource.java new file mode 100644 index 00000000000..5645c259de3 --- /dev/null +++ b/java/ql/test/stubs/spring-jdbc-5.3.8/org/springframework/jdbc/datasource/AbstractDataSource.java @@ -0,0 +1,90 @@ +/* + * Copyright 2002-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.jdbc.datasource; + +import java.io.PrintWriter; +import java.sql.SQLException; +import java.util.logging.Logger; + +import javax.sql.DataSource; + +public abstract class AbstractDataSource implements DataSource { + + + /** + * Returns 0, indicating the default system timeout is to be used. + */ + @Override + public int getLoginTimeout() throws SQLException { + return 0; + } + + /** + * Setting a login timeout is not supported. + */ + @Override + public void setLoginTimeout(int timeout) throws SQLException { + throw new UnsupportedOperationException("setLoginTimeout"); + } + + /** + * LogWriter methods are not supported. + */ + @Override + public PrintWriter getLogWriter() { + throw new UnsupportedOperationException("getLogWriter"); + } + + /** + * LogWriter methods are not supported. + */ + @Override + public void setLogWriter(PrintWriter pw) throws SQLException { + throw new UnsupportedOperationException("setLogWriter"); + } + + + //--------------------------------------------------------------------- + // Implementation of JDBC 4.0's Wrapper interface + //--------------------------------------------------------------------- + + @Override + @SuppressWarnings("unchecked") + public T unwrap(Class iface) throws SQLException { + if (iface.isInstance(this)) { + return (T) this; + } + throw new SQLException("DataSource of type [" + getClass().getName() + + "] cannot be unwrapped as [" + iface.getName() + "]"); + } + + @Override + public boolean isWrapperFor(Class iface) throws SQLException { + return iface.isInstance(this); + } + + + //--------------------------------------------------------------------- + // Implementation of JDBC 4.1's getParentLogger method + //--------------------------------------------------------------------- + + @Override + public Logger getParentLogger() { + return null; + } + +} diff --git a/java/ql/test/stubs/spring-jdbc-5.3.8/org/springframework/jdbc/datasource/AbstractDriverBasedDataSource.java b/java/ql/test/stubs/spring-jdbc-5.3.8/org/springframework/jdbc/datasource/AbstractDriverBasedDataSource.java new file mode 100644 index 00000000000..b2182d1194d --- /dev/null +++ b/java/ql/test/stubs/spring-jdbc-5.3.8/org/springframework/jdbc/datasource/AbstractDriverBasedDataSource.java @@ -0,0 +1,201 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.jdbc.datasource; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.Properties; + +public abstract class AbstractDriverBasedDataSource extends AbstractDataSource { + + private String url; + + private String username; + + private String password; + + private String catalog; + + private String schema; + + private Properties connectionProperties; + + + /** + * Set the JDBC URL to use for connecting through the Driver. + * @see java.sql.Driver#connect(String, java.util.Properties) + */ + public void setUrl(String url) { + this.url = (url != null ? url.trim() : null); + } + + /** + * Return the JDBC URL to use for connecting through the Driver. + */ + public String getUrl() { + return this.url; + } + + /** + * Set the JDBC username to use for connecting through the Driver. + * @see java.sql.Driver#connect(String, java.util.Properties) + */ + public void setUsername(String username) { + this.username = username; + } + + /** + * Return the JDBC username to use for connecting through the Driver. + */ + public String getUsername() { + return this.username; + } + + /** + * Set the JDBC password to use for connecting through the Driver. + * @see java.sql.Driver#connect(String, java.util.Properties) + */ + public void setPassword(String password) { + this.password = password; + } + + /** + * Return the JDBC password to use for connecting through the Driver. + */ + public String getPassword() { + return this.password; + } + + /** + * Specify a database catalog to be applied to each Connection. + * @since 4.3.2 + * @see Connection#setCatalog + */ + public void setCatalog(String catalog) { + this.catalog = catalog; + } + + /** + * Return the database catalog to be applied to each Connection, if any. + * @since 4.3.2 + */ + public String getCatalog() { + return this.catalog; + } + + /** + * Specify a database schema to be applied to each Connection. + * @since 4.3.2 + * @see Connection#setSchema + */ + public void setSchema(String schema) { + this.schema = schema; + } + + /** + * Return the database schema to be applied to each Connection, if any. + * @since 4.3.2 + */ + public String getSchema() { + return this.schema; + } + + /** + * Specify arbitrary connection properties as key/value pairs, + * to be passed to the Driver. + *

    Can also contain "user" and "password" properties. However, + * any "username" and "password" bean properties specified on this + * DataSource will override the corresponding connection properties. + * @see java.sql.Driver#connect(String, java.util.Properties) + */ + public void setConnectionProperties(Properties connectionProperties) { + this.connectionProperties = connectionProperties; + } + + /** + * Return the connection properties to be passed to the Driver, if any. + */ + public Properties getConnectionProperties() { + return this.connectionProperties; + } + + + /** + * This implementation delegates to {@code getConnectionFromDriver}, + * using the default username and password of this DataSource. + * @see #getConnectionFromDriver(String, String) + * @see #setUsername + * @see #setPassword + */ + @Override + public Connection getConnection() throws SQLException { + return getConnectionFromDriver(getUsername(), getPassword()); + } + + /** + * This implementation delegates to {@code getConnectionFromDriver}, + * using the given username and password. + * @see #getConnectionFromDriver(String, String) + */ + @Override + public Connection getConnection(String username, String password) throws SQLException { + return getConnectionFromDriver(username, password); + } + + + /** + * Build properties for the Driver, including the given username and password (if any), + * and obtain a corresponding Connection. + * @param username the name of the user + * @param password the password to use + * @return the obtained Connection + * @throws SQLException in case of failure + * @see java.sql.Driver#connect(String, java.util.Properties) + */ + protected Connection getConnectionFromDriver(String username, String password) throws SQLException { + Properties mergedProps = new Properties(); + Properties connProps = getConnectionProperties(); + if (connProps != null) { + mergedProps.putAll(connProps); + } + if (username != null) { + mergedProps.setProperty("user", username); + } + if (password != null) { + mergedProps.setProperty("password", password); + } + + Connection con = getConnectionFromDriver(mergedProps); + if (this.catalog != null) { + con.setCatalog(this.catalog); + } + if (this.schema != null) { + con.setSchema(this.schema); + } + return con; + } + + /** + * Obtain a Connection using the given properties. + *

    Template method to be implemented by subclasses. + * @param props the merged connection properties + * @return the obtained Connection + * @throws SQLException in case of failure + */ + protected abstract Connection getConnectionFromDriver(Properties props) throws SQLException; + +} diff --git a/java/ql/test/stubs/spring-jdbc-5.3.8/org/springframework/jdbc/datasource/DriverManagerDataSource.java b/java/ql/test/stubs/spring-jdbc-5.3.8/org/springframework/jdbc/datasource/DriverManagerDataSource.java new file mode 100644 index 00000000000..d4fb9545347 --- /dev/null +++ b/java/ql/test/stubs/spring-jdbc-5.3.8/org/springframework/jdbc/datasource/DriverManagerDataSource.java @@ -0,0 +1,94 @@ +/* + * Copyright 2002-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.jdbc.datasource; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.Properties; + +public class DriverManagerDataSource extends AbstractDriverBasedDataSource { + + /** + * Constructor for bean-style configuration. + */ + public DriverManagerDataSource() { + } + + /** + * Create a new DriverManagerDataSource with the given JDBC URL, + * not specifying a username or password for JDBC access. + * @param url the JDBC URL to use for accessing the DriverManager + * @see java.sql.DriverManager#getConnection(String) + */ + public DriverManagerDataSource(String url) { + } + + /** + * Create a new DriverManagerDataSource with the given standard + * DriverManager parameters. + * @param url the JDBC URL to use for accessing the DriverManager + * @param username the JDBC username to use for accessing the DriverManager + * @param password the JDBC password to use for accessing the DriverManager + * @see java.sql.DriverManager#getConnection(String, String, String) + */ + public DriverManagerDataSource(String url, String username, String password) { + } + + /** + * Create a new DriverManagerDataSource with the given JDBC URL, + * not specifying a username or password for JDBC access. + * @param url the JDBC URL to use for accessing the DriverManager + * @param conProps the JDBC connection properties + * @see java.sql.DriverManager#getConnection(String) + */ + public DriverManagerDataSource(String url, Properties conProps) { + } + + + /** + * Set the JDBC driver class name. This driver will get initialized + * on startup, registering itself with the JDK's DriverManager. + *

    NOTE: DriverManagerDataSource is primarily intended for accessing + * pre-registered JDBC drivers. If you need to register a new driver, + * consider using {@link SimpleDriverDataSource} instead. Alternatively, consider + * initializing the JDBC driver yourself before instantiating this DataSource. + * The "driverClassName" property is mainly preserved for backwards compatibility, + * as well as for migrating between Commons DBCP and this DataSource. + * @see java.sql.DriverManager#registerDriver(java.sql.Driver) + * @see SimpleDriverDataSource + */ + public void setDriverClassName(String driverClassName) { + } + + + @Override + protected Connection getConnectionFromDriver(Properties props) throws SQLException { + String url = getUrl(); + return getConnectionFromDriverManager(url, props); + } + + /** + * Getting a Connection using the nasty static from DriverManager is extracted + * into a protected method to allow for easy unit testing. + * @see java.sql.DriverManager#getConnection(String, java.util.Properties) + */ + protected Connection getConnectionFromDriverManager(String url, Properties props) throws SQLException { + return DriverManager.getConnection(url, props); + } + +} diff --git a/java/ql/test/stubs/springframework-5.3.8/org/springframework/boot/jdbc/DataSourceBuilder.java b/java/ql/test/stubs/springframework-5.3.8/org/springframework/boot/jdbc/DataSourceBuilder.java new file mode 100644 index 00000000000..d85bb46dfd7 --- /dev/null +++ b/java/ql/test/stubs/springframework-5.3.8/org/springframework/boot/jdbc/DataSourceBuilder.java @@ -0,0 +1,27 @@ +/* + * Copyright 2012-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jdbc; + +import javax.sql.DataSource; + +public final class DataSourceBuilder { + + public DataSourceBuilder url(String url) { + return this; + } + +} \ No newline at end of file diff --git a/javascript/ql/examples/snippets/jsxattribute.ql b/javascript/ql/examples/snippets/jsxattribute.ql index ad7a6458667..b55abc09dd0 100644 --- a/javascript/ql/examples/snippets/jsxattribute.ql +++ b/javascript/ql/examples/snippets/jsxattribute.ql @@ -8,6 +8,6 @@ import javascript -from JSXAttribute a +from JsxAttribute a where a.getName() = "dangerouslySetInnerHTML" select a diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll index bec90be46cc..637255da80c 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll @@ -4,7 +4,7 @@ * Configures boosting for adaptive threat modeling (ATM). */ -private import javascript as raw +private import javascript as JS import EndpointTypes /** @@ -28,23 +28,23 @@ import EndpointTypes * `isAdditionalFlowStep` with a more generalised definition of additional edges. See * `NosqlInjectionATM.qll` for an example of doing this. */ -abstract class ATMConfig extends string { +abstract class AtmConfig extends string { bindingset[this] - ATMConfig() { any() } + AtmConfig() { any() } /** * EXPERIMENTAL. This API may change in the future. * * Holds if `source` is a known source of flow. */ - predicate isKnownSource(raw::DataFlow::Node source) { none() } + predicate isKnownSource(JS::DataFlow::Node source) { none() } /** * EXPERIMENTAL. This API may change in the future. * * Holds if `sink` is a known sink of flow. */ - predicate isKnownSink(raw::DataFlow::Node sink) { none() } + predicate isKnownSink(JS::DataFlow::Node sink) { none() } /** * EXPERIMENTAL. This API may change in the future. @@ -52,7 +52,7 @@ abstract class ATMConfig extends string { * Holds if the candidate source `candidateSource` predicted by the machine learning model should be * an effective source, i.e. one considered as a possible source of flow in the boosted query. */ - predicate isEffectiveSource(raw::DataFlow::Node candidateSource) { none() } + predicate isEffectiveSource(JS::DataFlow::Node candidateSource) { none() } /** * EXPERIMENTAL. This API may change in the future. @@ -60,29 +60,7 @@ abstract class ATMConfig extends string { * Holds if the candidate sink `candidateSink` predicted by the machine learning model should be * an effective sink, i.e. one considered as a possible sink of flow in the boosted query. */ - predicate isEffectiveSink(raw::DataFlow::Node candidateSink) { none() } - - /** - * EXPERIMENTAL. This API may change in the future. - * - * Holds if the candidate sink `candidateSink` predicted by the machine learning model should be - * an effective sink that overrides the score provided by the machine learning model with the - * score `score` for reason `why`. The effective sinks identified by this predicate MUST be a - * subset of those identified by the `isEffectiveSink` predicate. - * - * For example, in the ATM external API query, we use this method to ensure the ATM external API - * query produces the same results as the standard external API query, but assigns flows - * involving sinks that are filtered out by the endpoint filters a score of 0. - * - * This predicate can be phased out once we no longer need to rely on predicates like - * `paddedScore` in the ATM CodeQL libraries to add scores to alert messages in a way that works - * with lexical sort orders. - */ - predicate isEffectiveSinkWithOverridingScore( - raw::DataFlow::Node candidateSink, float score, string why - ) { - none() - } + predicate isEffectiveSink(JS::DataFlow::Node candidateSink) { none() } /** * EXPERIMENTAL. This API may change in the future. @@ -110,3 +88,6 @@ abstract class ATMConfig extends string { */ float getScoreCutoff() { result = 0.0 } } + +/** DEPRECATED: Alias for AtmConfig */ +deprecated class ATMConfig = AtmConfig; diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/AdaptiveThreatModeling.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/AdaptiveThreatModeling.qll index 678182f3987..002a5c8fe8e 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/AdaptiveThreatModeling.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/AdaptiveThreatModeling.qll @@ -4,8 +4,7 @@ * Provides information about the results of boosted queries for use in adaptive threat modeling (ATM). */ -private import javascript as raw -private import raw::DataFlow as DataFlow +private import javascript::DataFlow as DataFlow import ATMConfig private import BaseScoring private import EndpointScoring as EndpointScoring diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/BaseScoring.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/BaseScoring.qll index 1af5966997a..a6787196bbb 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/BaseScoring.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/BaseScoring.qll @@ -12,7 +12,7 @@ external predicate availableMlModels( ); /** Get the ATM configuration. */ -ATMConfig getCfg() { any() } +AtmConfig getCfg() { any() } /** * A string containing scoring information produced by a scoring model. diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/CoreKnowledge.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/CoreKnowledge.qll index 4f0ad84b238..23ba238ff99 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/CoreKnowledge.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/CoreKnowledge.qll @@ -61,7 +61,7 @@ predicate isArgumentToKnownLibrarySinkFunction(DataFlow::Node n) { * This corresponds to known sinks from security queries whose sources include remote flow and * DOM-based sources. */ -predicate isKnownExternalAPIQuerySink(DataFlow::Node n) { +predicate isKnownExternalApiQuerySink(DataFlow::Node n) { n instanceof Xxe::Sink or n instanceof TaintedPath::Sink or n instanceof XpathInjection::Sink or @@ -86,11 +86,14 @@ predicate isKnownExternalAPIQuerySink(DataFlow::Node n) { n instanceof HttpToFileAccess::Sink } +/** DEPRECATED: Alias for isKnownExternalApiQuerySink */ +deprecated predicate isKnownExternalAPIQuerySink = isKnownExternalApiQuerySink/1; + /** * Holds if the node `n` is a known sink in a modeled library. */ predicate isKnownLibrarySink(DataFlow::Node n) { - isKnownExternalAPIQuerySink(n) or + isKnownExternalApiQuerySink(n) or n instanceof CleartextLogging::Sink or n instanceof StackTraceExposure::Sink or n instanceof ShellCommandInjectionFromEnvironment::Sink or @@ -207,7 +210,7 @@ predicate isOtherModeledArgument(DataFlow::Node n, FilteringReason reason) { DatabaseAccess and reason instanceof DatabaseAccessReason or - call = DOM::domValueRef() and reason instanceof DOMReason + call = DOM::domValueRef() and reason instanceof DomReason or call.getCalleeName() = "next" and exists(DataFlow::FunctionNode f | call = f.getLastParameter().getACall()) and diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointScoring.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointScoring.qll index 0ce13b3e180..a0d7fd528d3 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointScoring.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointScoring.qll @@ -62,14 +62,11 @@ private float getScoreForSource(DataFlow::Node source) { private float getScoreForSink(DataFlow::Node sink) { if getCfg().isKnownSink(sink) then result = 1.0 - else - if getCfg().isEffectiveSinkWithOverridingScore(sink, result, _) - then any() - else ( - // This restriction on `sink` has no semantic effect but improves performance. - getCfg().isEffectiveSink(sink) and - ModelScoring::endpointScores(sink, getCfg().getASinkEndpointType().getEncoding(), result) - ) + else ( + // This restriction on `sink` has no semantic effect but improves performance. + getCfg().isEffectiveSink(sink) and + ModelScoring::endpointScores(sink, getCfg().getASinkEndpointType().getEncoding(), result) + ) } class EndpointScoringResults extends ScoringResults { @@ -109,10 +106,6 @@ class EndpointScoringResults extends ScoringResults { result = "known" and getCfg().isKnownSink(sink) or not getCfg().isKnownSink(sink) and - getCfg().isEffectiveSinkWithOverridingScore(sink, _, result) - or - not getCfg().isKnownSink(sink) and - not getCfg().isEffectiveSinkWithOverridingScore(sink, _, _) and result = "predicted (scores: " + concat(EndpointType type, float score | @@ -127,29 +120,21 @@ class EndpointScoringResults extends ScoringResults { override predicate shouldResultBeIncluded(DataFlow::Node source, DataFlow::Node sink) { if getCfg().isKnownSink(sink) then any() - else - if getCfg().isEffectiveSinkWithOverridingScore(sink, _, _) - then - exists(float score | - getCfg().isEffectiveSinkWithOverridingScore(sink, score, _) and - score >= getCfg().getScoreCutoff() - ) - else ( - // This restriction on `sink` has no semantic effect but improves performance. - getCfg().isEffectiveSink(sink) and - exists(float sinkScore | - ModelScoring::endpointScores(sink, getCfg().getASinkEndpointType().getEncoding(), - sinkScore) and - // Include the endpoint if (a) the query endpoint type scores higher than all other - // endpoint types, or (b) the query endpoint type scores at least - // 0.5 - (getCfg().getScoreCutoff() / 2). - sinkScore >= - [ - max(float s | ModelScoring::endpointScores(sink, _, s)), - 0.5 - getCfg().getScoreCutoff() / 2 - ] - ) + else ( + // This restriction on `sink` has no semantic effect but improves performance. + getCfg().isEffectiveSink(sink) and + exists(float sinkScore | + ModelScoring::endpointScores(sink, getCfg().getASinkEndpointType().getEncoding(), sinkScore) and + // Include the endpoint if (a) the query endpoint type scores higher than all other + // endpoint types, or (b) the query endpoint type scores at least + // 0.5 - (getCfg().getScoreCutoff() / 2). + sinkScore >= + [ + max(float s | ModelScoring::endpointScores(sink, _, s)), + 0.5 - getCfg().getScoreCutoff() / 2 + ] ) + ) } } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/FilteringReasons.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/FilteringReasons.qll index 063cf567fc9..4b0cdb986e8 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/FilteringReasons.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/FilteringReasons.qll @@ -24,7 +24,7 @@ newtype TFilteringReason = TMembershipCandidateTestReason() or TFileSystemAccessReason() or TDatabaseAccessReason() or - TDOMReason() or + TDomReason() or TNextFunctionCallReason() or TArgumentToArrayReason() or TArgumentToBuiltinGlobalVarRefReason() or @@ -161,12 +161,15 @@ class DatabaseAccessReason extends NotASinkReason, TDatabaseAccessReason { override int getEncoding() { result = 21 } } -class DOMReason extends NotASinkReason, TDOMReason { +class DomReason extends NotASinkReason, TDomReason { override string getDescription() { result = "DOM" } override int getEncoding() { result = 22 } } +/** DEPRECATED: Alias for DomReason */ +deprecated class DOMReason = DomReason; + class NextFunctionCallReason extends NotASinkReason, TNextFunctionCallReason { override string getDescription() { result = "NextFunctionCall" } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/FunctionBodyFeatures.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/FunctionBodyFeatures.qll index 6459a30250f..4b1a5778cc0 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/FunctionBodyFeatures.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/FunctionBodyFeatures.qll @@ -10,7 +10,7 @@ private import FeaturizationConfig /** * Gets a tokenized representation of the AST node for use in the `enclosingFunctionBody` feature. */ -string getTokenizedAstNode(ASTNode node) { +string getTokenizedAstNode(AstNode node) { // e.g. `x` -> "x" result = node.(Identifier).getName() or @@ -35,12 +35,15 @@ string getTokenizedAstNode(ASTNode node) { /** Gets an AST node within the function `f` that we should featurize. */ pragma[inline] -ASTNode getAnASTNodeToFeaturize(Function f) { +AstNode getAnAstNodeToFeaturize(Function f) { result.getParent*() = f and // Don't featurize the function name as part of the function body tokens not result = f.getIdentifier() } +/** DEPRECATED: Alias for getAnAstNodeToFeaturize */ +deprecated ASTNode getAnASTNodeToFeaturize(Function f) { result = getAnAstNodeToFeaturize(f) } + /** * Gets a function that contains the endpoint. * @@ -72,7 +75,7 @@ private int getMaxNumAstNodes() { result = 1024 } private int getNumAstNodesInFunction(Function function) { // Restrict the values `function` can take on function = getAFunctionForEndpoint(_) and - result = count(getAnASTNodeToFeaturize(function)) + result = count(getAnAstNodeToFeaturize(function)) } /** @@ -121,16 +124,19 @@ Function getRepresentativeFunctionForEndpoint(DataFlow::Node endpoint) { } /** Returns an AST node within the function `f` that an associated token feature. */ -ASTNode getAnASTNodeWithAFeature(Function f) { +AstNode getAnAstNodeWithAFeature(Function f) { // Performance optimization: Restrict the set of functions to those containing an endpoint to featurize. f = getRepresentativeFunctionForEndpoint(any(FeaturizationConfig cfg).getAnEndpointToFeaturize()) and - result = getAnASTNodeToFeaturize(f) + result = getAnAstNodeToFeaturize(f) } +/** DEPRECATED: Alias for getAnAstNodeWithAFeature */ +deprecated ASTNode getAnASTNodeWithAFeature(Function f) { result = getAnAstNodeWithAFeature(f) } + /** Returns the number of source-code characters in a function. */ int getNumCharsInFunction(Function f) { result = - strictsum(ASTNode node | node = getAnASTNodeWithAFeature(f) | getTokenizedAstNode(node).length()) + strictsum(AstNode node | node = getAnAstNodeWithAFeature(f) | getTokenizedAstNode(node).length()) } /** @@ -149,8 +155,8 @@ string getBodyTokensFeature(Function function) { // large body features are replaced by the absent token. // // We count nodes instead of tokens because tokens are often not unique. - strictcount(ASTNode node | - node = getAnASTNodeToFeaturize(function) and + strictcount(AstNode node | + node = getAnAstNodeToFeaturize(function) and exists(getTokenizedAstNode(node)) ) <= 256 and // Performance optimization: If a function has more than getMaxChars() characters in its body subtokens, @@ -161,8 +167,8 @@ string getBodyTokensFeature(Function function) { // The use of a nested exists here allows us to avoid duplicates due to two AST nodes in the // same location featurizing to the same token. By using a nested exists, we take only unique // (location, token) pairs. - exists(ASTNode node | - node = getAnASTNodeToFeaturize(function) and + exists(AstNode node | + node = getAnAstNodeToFeaturize(function) and token = getTokenizedAstNode(node) and l = node.getLocation() ) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll index ed5ac92ba58..2d5b2a58510 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll @@ -87,8 +87,8 @@ module SinkEndpointFilter { } } -class NosqlInjectionATMConfig extends ATMConfig { - NosqlInjectionATMConfig() { this = "NosqlInjectionATMConfig" } +class NosqlInjectionAtmConfig extends AtmConfig { + NosqlInjectionAtmConfig() { this = "NosqlInjectionATMConfig" } override predicate isKnownSource(DataFlow::Node source) { source instanceof NosqlInjection::Source or TaintedObject::isSource(source, _) @@ -103,7 +103,10 @@ class NosqlInjectionATMConfig extends ATMConfig { override EndpointType getASinkEndpointType() { result instanceof NosqlInjectionSinkType } } -/** Holds if src -> trg is an additional flow step in the non-boosted NoSQL injection security query. */ +/** DEPRECATED: Alias for NosqlInjectionAtmConfig */ +deprecated class NosqlInjectionATMConfig = NosqlInjectionAtmConfig; + +/** Holds if src -> trg is an additional flow step in the non-boosted NoSql injection security query. */ predicate isBaseAdditionalFlowStep( DataFlow::Node src, DataFlow::Node trg, DataFlow::FlowLabel inlbl, DataFlow::FlowLabel outlbl ) { @@ -112,7 +115,7 @@ predicate isBaseAdditionalFlowStep( // additional flow step to track taint through NoSQL query objects inlbl = TaintedObject::label() and outlbl = TaintedObject::label() and - exists(NoSQL::Query query, DataFlow::SourceNode queryObj | + exists(NoSql::Query query, DataFlow::SourceNode queryObj | queryObj.flowsToExpr(query) and queryObj.flowsTo(trg) and src = queryObj.getAPropertyWrite().getRhs() @@ -120,13 +123,17 @@ predicate isBaseAdditionalFlowStep( } /** + * Gets a value that is (transitively) written to `query`, where `query` is a NoSQL sink. + * * This predicate allows us to propagate data flow through property writes and array constructors * within a query object, enabling the security query to pick up NoSQL injection vulnerabilities * involving more complex queries. */ DataFlow::Node getASubexpressionWithinQuery(DataFlow::Node query) { + any(NosqlInjectionAtmConfig cfg).isEffectiveSink(query) and exists(DataFlow::SourceNode receiver | - receiver.flowsTo(getASubexpressionWithinQuery*(query.getALocalSource())) and + receiver = [getASubexpressionWithinQuery(query), query].getALocalSource() + | result = [receiver.getAPropertyWrite().getRhs(), receiver.(DataFlow::ArrayCreationNode).getAnElement()] ) @@ -152,7 +159,7 @@ class Configuration extends TaintTracking::Configuration { sink.(NosqlInjection::Sink).getAFlowLabel() = label or // Allow effective sinks to have any taint label - any(NosqlInjectionATMConfig cfg).isEffectiveSink(sink) + any(NosqlInjectionAtmConfig cfg).isEffectiveSink(sink) } override predicate isSanitizer(DataFlow::Node node) { @@ -171,7 +178,7 @@ class Configuration extends TaintTracking::Configuration { isBaseAdditionalFlowStep(src, trg, inlbl, outlbl) or // relaxed version of previous step to track taint through unmodeled NoSQL query objects - any(NosqlInjectionATMConfig cfg).isEffectiveSink(trg) and + any(NosqlInjectionAtmConfig cfg).isEffectiveSink(trg) and src = getASubexpressionWithinQuery(trg) } } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/SqlInjectionATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/SqlInjectionATM.qll index 86ceadf4f84..b3b722fb0fc 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/SqlInjectionATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/SqlInjectionATM.qll @@ -60,8 +60,8 @@ module SinkEndpointFilter { } } -class SqlInjectionATMConfig extends ATMConfig { - SqlInjectionATMConfig() { this = "SqlInjectionATMConfig" } +class SqlInjectionAtmConfig extends AtmConfig { + SqlInjectionAtmConfig() { this = "SqlInjectionATMConfig" } override predicate isKnownSource(DataFlow::Node source) { source instanceof SqlInjection::Source } @@ -74,6 +74,9 @@ class SqlInjectionATMConfig extends ATMConfig { override EndpointType getASinkEndpointType() { result instanceof SqlInjectionSinkType } } +/** DEPRECATED: Alias for SqlInjectionAtmConfig */ +deprecated class SqlInjectionATMConfig = SqlInjectionAtmConfig; + /** * A taint-tracking configuration for reasoning about SQL injection vulnerabilities. * @@ -86,7 +89,7 @@ class Configuration extends TaintTracking::Configuration { override predicate isSource(DataFlow::Node source) { source instanceof SqlInjection::Source } override predicate isSink(DataFlow::Node sink) { - sink instanceof SqlInjection::Sink or any(SqlInjectionATMConfig cfg).isEffectiveSink(sink) + sink instanceof SqlInjection::Sink or any(SqlInjectionAtmConfig cfg).isEffectiveSink(sink) } override predicate isSanitizer(DataFlow::Node node) { diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/TaintedPathATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/TaintedPathATM.qll index 908bab9fd51..109fd357007 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/TaintedPathATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/TaintedPathATM.qll @@ -59,8 +59,8 @@ module SinkEndpointFilter { } } -class TaintedPathATMConfig extends ATMConfig { - TaintedPathATMConfig() { this = "TaintedPathATMConfig" } +class TaintedPathAtmConfig extends AtmConfig { + TaintedPathAtmConfig() { this = "TaintedPathATMConfig" } override predicate isKnownSource(DataFlow::Node source) { source instanceof TaintedPath::Source } @@ -73,6 +73,9 @@ class TaintedPathATMConfig extends ATMConfig { override EndpointType getASinkEndpointType() { result instanceof TaintedPathSinkType } } +/** DEPRECATED: Alias for TaintedPathAtmConfig */ +deprecated class TaintedPathATMConfig = TaintedPathAtmConfig; + /** * A taint-tracking configuration for reasoning about path injection vulnerabilities. * @@ -88,7 +91,7 @@ class Configuration extends TaintTracking::Configuration { label = sink.(TaintedPath::Sink).getAFlowLabel() or // Allow effective sinks to have any taint label - any(TaintedPathATMConfig cfg).isEffectiveSink(sink) + any(TaintedPathAtmConfig cfg).isEffectiveSink(sink) } override predicate isSanitizer(DataFlow::Node node) { node instanceof TaintedPath::Sanitizer } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssATM.qll index 009db55b86a..796fc94c64e 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssATM.qll @@ -60,8 +60,8 @@ module SinkEndpointFilter { } } -class DomBasedXssATMConfig extends ATMConfig { - DomBasedXssATMConfig() { this = "DomBasedXssATMConfig" } +class DomBasedXssAtmConfig extends AtmConfig { + DomBasedXssAtmConfig() { this = "DomBasedXssATMConfig" } override predicate isKnownSource(DataFlow::Node source) { source instanceof DomBasedXss::Source } @@ -74,6 +74,9 @@ class DomBasedXssATMConfig extends ATMConfig { override EndpointType getASinkEndpointType() { result instanceof XssSinkType } } +/** DEPRECATED: Alias for DomBasedXssAtmConfig */ +deprecated class DomBasedXssATMConfig = DomBasedXssAtmConfig; + /** * A taint-tracking configuration for reasoning about XSS vulnerabilities. * @@ -87,7 +90,7 @@ class Configuration extends TaintTracking::Configuration { override predicate isSink(DataFlow::Node sink) { sink instanceof DomBasedXss::Sink or - any(DomBasedXssATMConfig cfg).isEffectiveSink(sink) + any(DomBasedXssAtmConfig cfg).isEffectiveSink(sink) } override predicate isSanitizer(DataFlow::Node node) { diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/qlpack.yml b/javascript/ql/experimental/adaptivethreatmodeling/lib/qlpack.yml index 9389534628f..ba0709c7553 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/qlpack.yml +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-experimental-atm-lib -version: 0.0.6 +version: 0.1.1 extractor: javascript library: true groups: diff --git a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/DebugResultInclusion.ql b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/DebugResultInclusion.ql index 9be2929fd41..215103358ea 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/DebugResultInclusion.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/DebugResultInclusion.ql @@ -33,7 +33,7 @@ string getDescriptionForAlertCandidate( ) { result = "excluded[reason=" + getAReasonSinkExcluded(sinkCandidate, query) + "]" or - getATMCfg(query).isKnownSink(sinkCandidate) and + getAtmCfg(query).isKnownSink(sinkCandidate) and result = "excluded[reason=known-sink]" or not exists(getAReasonSinkExcluded(sinkCandidate, query)) and diff --git a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/CountSourcesAndSinks.ql b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/CountSourcesAndSinks.ql index 997c61bc096..dca511762b0 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/CountSourcesAndSinks.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/CountSourcesAndSinks.ql @@ -20,7 +20,7 @@ import semmle.javascript.security.dataflow.DeepObjectResourceExhaustionQuery as import semmle.javascript.security.dataflow.DifferentKindsComparisonBypassQuery as DifferentKindsComparisonBypass import semmle.javascript.security.dataflow.DomBasedXssQuery as DomBasedXss import semmle.javascript.security.dataflow.ExceptionXssQuery as ExceptionXss -import semmle.javascript.security.dataflow.ExternalAPIUsedWithUntrustedDataQuery as ExternalAPIUsedWithUntrustedData +import semmle.javascript.security.dataflow.ExternalAPIUsedWithUntrustedDataQuery as ExternalApiUsedWithUntrustedData import semmle.javascript.security.dataflow.FileAccessToHttpQuery as FileAccessToHttp import semmle.javascript.security.dataflow.HardcodedCredentialsQuery as HardcodedCredentials import semmle.javascript.security.dataflow.HardcodedDataInterpretedAsCodeQuery as HardcodedDataInterpretedAsCode diff --git a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointData.qll b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointData.qll index bea47423797..695945fb28f 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointData.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointData.qll @@ -23,17 +23,20 @@ import NoFeaturizationRestrictionsConfig import Queries /** Gets the ATM configuration object for the specified query. */ -ATMConfig getATMCfg(Query query) { +AtmConfig getAtmCfg(Query query) { query instanceof NosqlInjectionQuery and - result instanceof NosqlInjectionATM::NosqlInjectionATMConfig + result instanceof NosqlInjectionATM::NosqlInjectionAtmConfig or - query instanceof SqlInjectionQuery and result instanceof SqlInjectionATM::SqlInjectionATMConfig + query instanceof SqlInjectionQuery and result instanceof SqlInjectionATM::SqlInjectionAtmConfig or - query instanceof TaintedPathQuery and result instanceof TaintedPathATM::TaintedPathATMConfig + query instanceof TaintedPathQuery and result instanceof TaintedPathATM::TaintedPathAtmConfig or - query instanceof XssQuery and result instanceof XssATM::DomBasedXssATMConfig + query instanceof XssQuery and result instanceof XssATM::DomBasedXssAtmConfig } +/** DEPRECATED: Alias for getAtmCfg */ +deprecated ATMConfig getATMCfg(Query query) { result = getAtmCfg(query) } + /** Gets the ATM data flow configuration for the specified query. */ DataFlow::Configuration getDataFlowCfg(Query query) { query instanceof NosqlInjectionQuery and result instanceof NosqlInjectionATM::Configuration @@ -47,7 +50,7 @@ DataFlow::Configuration getDataFlowCfg(Query query) { /** Gets a known sink for the specified query. */ private DataFlow::Node getASink(Query query) { - getATMCfg(query).isKnownSink(result) and + getAtmCfg(query).isKnownSink(result) and // Only consider the source code for the project being analyzed. exists(result.getFile().getRelativePath()) } @@ -71,10 +74,7 @@ private DataFlow::Node getANotASink(NotASinkReason reason) { * specified query. */ private DataFlow::Node getAnUnknown(Query query) { - ( - getATMCfg(query).isEffectiveSink(result) or - getATMCfg(query).isEffectiveSinkWithOverridingScore(result, _, _) - ) and + getAtmCfg(query).isEffectiveSink(result) and not result = getASink(query) and // Only consider the source code for the project being analyzed. exists(result.getFile().getRelativePath()) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointMapping.ql b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointMapping.ql new file mode 100644 index 00000000000..bc625ded300 --- /dev/null +++ b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointMapping.ql @@ -0,0 +1,28 @@ +/* + * For internal use only. + * + * Maps ML-powered queries to their `EndpointType` for clearer labelling while evaluating ML model during training. + */ + +import experimental.adaptivethreatmodeling.SqlInjectionATM as SqlInjectionATM +import experimental.adaptivethreatmodeling.NosqlInjectionATM as NosqlInjectionATM +import experimental.adaptivethreatmodeling.TaintedPathATM as TaintedPathATM +import experimental.adaptivethreatmodeling.XssATM as XssATM +import experimental.adaptivethreatmodeling.AdaptiveThreatModeling + +from string queryName, AtmConfig c, EndpointType e +where + ( + queryName = "SqlInjectionATM.ql" and + c instanceof SqlInjectionATM::SqlInjectionAtmConfig + or + queryName = "NosqlInjectionATM.ql" and + c instanceof NosqlInjectionATM::NosqlInjectionAtmConfig + or + queryName = "TaintedPathInjectionATM.ql" and + c instanceof TaintedPathATM::TaintedPathAtmConfig + or + queryName = "XssATM.ql" and c instanceof XssATM::DomBasedXssAtmConfig + ) and + e = c.getASinkEndpointType() +select queryName, e.getEncoding() as endpointTypeEncoded diff --git a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractMisclassifiedEndpointFeatures.ql b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractMisclassifiedEndpointFeatures.ql index f05048f8cdc..b09eed5964d 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractMisclassifiedEndpointFeatures.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractMisclassifiedEndpointFeatures.ql @@ -19,8 +19,8 @@ EndpointType getEndpointType() { result instanceof NosqlInjectionSinkType } DataFlow::Node getAPositiveEndpoint() { result instanceof NosqlInjection::Sink } /** An ATM configuration to find misclassified endpoints of type `getEndpointType()`. */ -class ExtractMisclassifiedEndpointsATMConfig extends ATMConfig { - ExtractMisclassifiedEndpointsATMConfig() { this = "ExtractMisclassifiedEndpointsATMConfig" } +class ExtractMisclassifiedEndpointsAtmConfig extends AtmConfig { + ExtractMisclassifiedEndpointsAtmConfig() { this = "ExtractMisclassifiedEndpointsATMConfig" } override predicate isEffectiveSink(DataFlow::Node sinkCandidate) { sinkCandidate = getAPositiveEndpoint() @@ -31,7 +31,7 @@ class ExtractMisclassifiedEndpointsATMConfig extends ATMConfig { /** Get an endpoint from `getAPositiveEndpoint()` that is incorrectly excluded from the results. */ DataFlow::Node getAMisclassifedEndpoint() { - any(ExtractMisclassifiedEndpointsATMConfig config).isEffectiveSink(result) and + any(ExtractMisclassifiedEndpointsAtmConfig config).isEffectiveSink(result) and not any(ScoringResults results).shouldResultBeIncluded(_, result) } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/src/qlpack.yml b/javascript/ql/experimental/adaptivethreatmodeling/src/qlpack.yml index 8520659433d..10959ad8fdf 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/src/qlpack.yml +++ b/javascript/ql/experimental/adaptivethreatmodeling/src/qlpack.yml @@ -1,6 +1,6 @@ name: codeql/javascript-experimental-atm-queries language: javascript -version: 0.0.6 +version: 0.1.1 suites: codeql-suites defaultSuiteFile: codeql-suites/javascript-atm-code-scanning.qls groups: diff --git a/javascript/ql/lib/CHANGELOG.md b/javascript/ql/lib/CHANGELOG.md index b7b52ff7c15..d916a226c7f 100644 --- a/javascript/ql/lib/CHANGELOG.md +++ b/javascript/ql/lib/CHANGELOG.md @@ -1,3 +1,13 @@ +## 0.0.12 + +### Major Analysis Improvements + +* Added support for TypeScript 4.6. + +### Minor Analysis Improvements + +* Added sources from the [`jszip`](https://www.npmjs.com/package/jszip) library to the `js/zipslip` query. + ## 0.0.11 ## 0.0.10 diff --git a/javascript/ql/lib/Expressions/DOMProperties.qll b/javascript/ql/lib/Expressions/DOMProperties.qll index 7ff1884fb1b..17f53f8a366 100644 --- a/javascript/ql/lib/Expressions/DOMProperties.qll +++ b/javascript/ql/lib/Expressions/DOMProperties.qll @@ -4,15 +4,16 @@ import semmle.javascript.Externs -/** Holds if `et` is a root interface of the DOM type hierarchy. */ -predicate isDOMRootType(ExternalType et) { - exists(string n | n = et.getName() | n = "EventTarget" or n = "StyleSheet") -} +/** DEPRECATED: Alias for isDomRootType */ +deprecated predicate isDOMRootType = isDomRootType/1; /** Holds if `p` is declared as a property of a DOM class or interface. */ pragma[nomagic] -predicate isDOMProperty(string p) { +predicate isDomProperty(string p) { exists(ExternalMemberDecl emd | emd.getName() = p | - isDOMRootType(emd.getDeclaringType().getASupertype*()) + isDomRootType(emd.getDeclaringType().getASupertype*()) ) } + +/** DEPRECATED: Alias for isDomProperty */ +deprecated predicate isDOMProperty = isDomProperty/1; diff --git a/javascript/ql/lib/Expressions/ExprHasNoEffect.qll b/javascript/ql/lib/Expressions/ExprHasNoEffect.qll index 220eef15a4a..691424f3b71 100644 --- a/javascript/ql/lib/Expressions/ExprHasNoEffect.qll +++ b/javascript/ql/lib/Expressions/ExprHasNoEffect.qll @@ -143,7 +143,7 @@ predicate hasNoEffect(Expr e) { // don't complain about declarations not isDeclaration(e) and // exclude DOM properties, which sometimes have magical auto-update properties - not isDOMProperty(e.(PropAccess).getPropertyName()) and + not isDomProperty(e.(PropAccess).getPropertyName()) and // exclude xUnit.js annotations not e instanceof XUnitAnnotation and // exclude common patterns that are most likely intentional diff --git a/javascript/ql/lib/change-notes/2022-02-04-jszip.md b/javascript/ql/lib/change-notes/2022-02-04-jszip.md deleted file mode 100644 index cc00e02efb5..00000000000 --- a/javascript/ql/lib/change-notes/2022-02-04-jszip.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Added sources from the [`jszip`](https://www.npmjs.com/package/jszip) library to the `js/zipslip` query. \ No newline at end of file diff --git a/javascript/ql/lib/change-notes/2022-02-07-deleted-deprecations.md b/javascript/ql/lib/change-notes/2022-02-07-deleted-deprecations.md new file mode 100644 index 00000000000..e8da1e8e158 --- /dev/null +++ b/javascript/ql/lib/change-notes/2022-02-07-deleted-deprecations.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* All deprecated predicates/classes/modules that have been deprecated for over a year have been deleted. \ No newline at end of file diff --git a/javascript/ql/lib/change-notes/2022-02-07-deprecated-acronyms.md b/javascript/ql/lib/change-notes/2022-02-07-deprecated-acronyms.md new file mode 100644 index 00000000000..a79f286aacd --- /dev/null +++ b/javascript/ql/lib/change-notes/2022-02-07-deprecated-acronyms.md @@ -0,0 +1,5 @@ +--- +category: deprecated +--- +* Many classes/predicates/modules that had upper-case acronyms have been renamed to follow our style-guide. + The old name still exists as a deprecated alias. \ No newline at end of file diff --git a/javascript/ql/lib/change-notes/2022-02-07-deprecated-modules.md b/javascript/ql/lib/change-notes/2022-02-07-deprecated-modules.md new file mode 100644 index 00000000000..561f68a150c --- /dev/null +++ b/javascript/ql/lib/change-notes/2022-02-07-deprecated-modules.md @@ -0,0 +1,5 @@ +--- +category: deprecated +--- +* Some modules that started with a lowercase letter have been renamed to follow our style-guide. + The old name still exists as a deprecated alias. \ No newline at end of file diff --git a/javascript/ql/lib/change-notes/2022-02-14-deprecated-predicates.md b/javascript/ql/lib/change-notes/2022-02-14-deprecated-predicates.md new file mode 100644 index 00000000000..1b8bc1d53e8 --- /dev/null +++ b/javascript/ql/lib/change-notes/2022-02-14-deprecated-predicates.md @@ -0,0 +1,5 @@ +--- +category: deprecated +--- +* Some predicates from `DefUse.qll`, `DataFlow.qll`, `TaintTracking.qll`, `DOM.qll`, `Definitions.qll` that weren't used by any query have been deprecated. + The documentation for each predicate points to an alternative. diff --git a/javascript/ql/lib/change-notes/2022-02-22-typescript-4-6.md b/javascript/ql/lib/change-notes/2022-02-22-typescript-4-6.md deleted file mode 100644 index 8413cd02601..00000000000 --- a/javascript/ql/lib/change-notes/2022-02-22-typescript-4-6.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: majorAnalysis ---- -* Added support for TypeScript 4.6. \ No newline at end of file diff --git a/javascript/ql/lib/change-notes/released/0.0.12.md b/javascript/ql/lib/change-notes/released/0.0.12.md new file mode 100644 index 00000000000..90747f5b02f --- /dev/null +++ b/javascript/ql/lib/change-notes/released/0.0.12.md @@ -0,0 +1,9 @@ +## 0.0.12 + +### Major Analysis Improvements + +* Added support for TypeScript 4.6. + +### Minor Analysis Improvements + +* Added sources from the [`jszip`](https://www.npmjs.com/package/jszip) library to the `js/zipslip` query. diff --git a/javascript/ql/lib/codeql-pack.release.yml b/javascript/ql/lib/codeql-pack.release.yml index e679dc42092..997fb8da83c 100644 --- a/javascript/ql/lib/codeql-pack.release.yml +++ b/javascript/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.11 +lastReleaseVersion: 0.0.12 diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index 70fbb4bac8f..306591ab074 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-all -version: 0.0.12-dev +version: 0.0.13-dev groups: javascript dbscheme: semmlecode.javascript.dbscheme extractor: javascript diff --git a/javascript/ql/lib/semmle/javascript/AMD.qll b/javascript/ql/lib/semmle/javascript/AMD.qll index 4efa29f4873..0bab2511552 100644 --- a/javascript/ql/lib/semmle/javascript/AMD.qll +++ b/javascript/ql/lib/semmle/javascript/AMD.qll @@ -185,11 +185,6 @@ class AmdModuleDefinition extends CallExpr { } } -/** - * DEPRECATED: Use `AmdModuleDefinition` instead. - */ -deprecated class AMDModuleDefinition = AmdModuleDefinition; - /** An AMD dependency, considered as a path expression. */ private class AmdDependencyPath extends PathExprCandidate { AmdDependencyPath() { @@ -327,8 +322,3 @@ class AmdModule extends Module { result = getDefine().getModuleExpr().flow() } } - -/** - * DEPRECATED: Use `AmdModule` instead. - */ -deprecated class AMDModule = AmdModule; diff --git a/javascript/ql/lib/semmle/javascript/AST.qll b/javascript/ql/lib/semmle/javascript/AST.qll index d4f2de4b170..895922f952f 100644 --- a/javascript/ql/lib/semmle/javascript/AST.qll +++ b/javascript/ql/lib/semmle/javascript/AST.qll @@ -22,7 +22,7 @@ private import semmle.javascript.internal.CachedStages * abs(-42); * ``` */ -class ASTNode extends @ast_node, NodeInStmtContainer { +class AstNode extends @ast_node, NodeInStmtContainer { override Location getLocation() { hasLocation(this, result) } override File getFile() { @@ -84,7 +84,7 @@ class ASTNode extends @ast_node, NodeInStmtContainer { * _Note_: The indices of child nodes are considered an implementation detail and may * change between versions of the extractor. */ - ASTNode getChild(int i) { + AstNode getChild(int i) { result = this.getChildExpr(i) or result = this.getChildStmt(i) or properties(result, this, i, _, _) or @@ -101,7 +101,7 @@ class ASTNode extends @ast_node, NodeInStmtContainer { TypeExpr getChildTypeExpr(int i) { typeexprs(result, _, this, i, _) } /** Gets a child node of this node. */ - ASTNode getAChild() { result = this.getChild(_) } + AstNode getAChild() { result = this.getChild(_) } /** Gets a child expression of this node. */ Expr getAChildExpr() { result = this.getChildExpr(_) } @@ -120,7 +120,7 @@ class ASTNode extends @ast_node, NodeInStmtContainer { /** Gets the parent node of this node, if any. */ cached - ASTNode getParent() { Stages::Ast::ref() and this = result.getAChild() } + AstNode getParent() { Stages::Ast::ref() and this = result.getAChild() } /** Gets the first control flow node belonging to this syntactic entity. */ ControlFlowNode getFirstControlFlowNode() { result = this } @@ -184,6 +184,9 @@ class ASTNode extends @ast_node, NodeInStmtContainer { } } +/** DEPRECATED: Alias for AstNode */ +deprecated class ASTNode = AstNode; + /** * Holds if the given file is a `.d.ts` file. */ @@ -334,7 +337,10 @@ class EventHandlerCode extends @event_handler, CodeInAttribute { } * Click me * ``` */ -class JavaScriptURL extends @javascript_url, CodeInAttribute { } +class JavaScriptUrl extends @javascript_url, CodeInAttribute { } + +/** DEPRECATED: Alias for JavaScriptUrl */ +deprecated class JavaScriptURL = JavaScriptUrl; /** * A toplevel syntactic entity containing Closure-style externs definitions. @@ -361,7 +367,7 @@ class Externs extends TopLevel { * i = 9 * ``` */ -class ExprOrStmt extends @expr_or_stmt, ControlFlowNode, ASTNode { } +class ExprOrStmt extends @expr_or_stmt, ControlFlowNode, AstNode { } /** * A program element that contains statements, but isn't itself @@ -375,7 +381,7 @@ class ExprOrStmt extends @expr_or_stmt, ControlFlowNode, ASTNode { } * } * ``` */ -class StmtContainer extends @stmt_container, ASTNode { +class StmtContainer extends @stmt_container, AstNode { /** Gets the innermost enclosing container in which this container is nested. */ cached StmtContainer getEnclosingContainer() { none() } @@ -405,7 +411,7 @@ class StmtContainer extends @stmt_container, ASTNode { * For scripts or modules, this is the container itself; for functions, * it is the function body. */ - ASTNode getBody() { result = this } + AstNode getBody() { result = this } /** * Gets the (unique) entry node of the control flow graph for this toplevel or function. @@ -470,7 +476,7 @@ module AST { * function id(x) { return x; } // function declaration * ``` */ - class ValueNode extends ASTNode, @dataflownode { + class ValueNode extends AstNode, @dataflownode { /** Gets type inference results for this element. */ DataFlow::AnalyzedNode analyze() { result = DataFlow::valueNode(this).analyze() } diff --git a/javascript/ql/lib/semmle/javascript/Aliases.qll b/javascript/ql/lib/semmle/javascript/Aliases.qll index 3211145517a..021cca85120 100644 --- a/javascript/ql/lib/semmle/javascript/Aliases.qll +++ b/javascript/ql/lib/semmle/javascript/Aliases.qll @@ -13,11 +13,6 @@ class ArrayAccess = IndexExpr; class AssignOp = CompoundAssignExpr; -/** - * DEPRECATED: The name `BlockStmt` is now preferred in all languages. - */ -deprecated class Block = BlockStmt; - class BoolLiteral = BooleanLiteral; class CaseStmt = Case; @@ -67,302 +62,3 @@ class ThisAccess = ThisExpr; class VariableAccess = VarAccess; class XorBitwiseExpr = XOrExpr; - -// Aliases for deprecated predicates from the dbscheme -/** - * Alias for the predicate `is_externs` defined in the .dbscheme. - * Use `TopLevel#isExterns()` instead. - */ -deprecated predicate isExterns(TopLevel toplevel) { is_externs(toplevel) } - -/** - * Alias for the predicate `is_module` defined in the .dbscheme. - * Use the `Module` class in `Module.qll` instead. - */ -deprecated predicate isModule(TopLevel toplevel) { is_module(toplevel) } - -/** - * Alias for the predicate `is_nodejs` defined in the .dbscheme. - * Use `NodeModule` from `NodeJS.qll` instead. - */ -deprecated predicate isNodejs(TopLevel toplevel) { is_nodejs(toplevel) } - -/** - * Alias for the predicate `is_es2015_module` defined in the .dbscheme. - * Use `ES2015Module` from `ES2015Modules.qll` instead. - */ -deprecated predicate isES2015Module(TopLevel toplevel) { is_es2015_module(toplevel) } - -/** - * Alias for the predicate `is_closure_module` defined in the .dbscheme. - */ -deprecated predicate isClosureModule(TopLevel toplevel) { is_closure_module(toplevel) } - -/** - * Alias for the predicate `stmt_containers` defined in the .dbscheme. - * Use `ASTNode#getContainer()` instead. - */ -deprecated predicate stmtContainers(Stmt stmt, StmtContainer container) { - stmt_containers(stmt, container) -} - -/** - * Alias for the predicate `jump_targets` defined in the .dbscheme. - * Use `JumpStmt#getTarget()` instead. - */ -deprecated predicate jumpTargets(Stmt jump, Stmt target) { jump_targets(jump, target) } - -/** - * Alias for the predicate `is_instantiated` defined in the .dbscheme. - * Use `NamespaceDeclaration#isInstantiated() instead.` - */ -deprecated predicate isInstantiated(NamespaceDeclaration decl) { is_instantiated(decl) } - -/** - * Alias for the predicate `has_declare_keyword` defined in the .dbscheme. - */ -deprecated predicate hasDeclareKeyword(ASTNode stmt) { has_declare_keyword(stmt) } - -/** - * Alias for the predicate `is_for_await_of` defined in the .dbscheme. - * Use `ForOfStmt#isAwait()` instead. - */ -deprecated predicate isForAwaitOf(ForOfStmt forof) { is_for_await_of(forof) } - -/** - * Alias for the predicate `enclosing_stmt` defined in the .dbscheme. - * Use `ExprOrType#getEnclosingStmt` instead. - */ -deprecated predicate enclosingStmt(ExprOrType expr, Stmt stmt) { enclosing_stmt(expr, stmt) } - -/** - * Alias for the predicate `expr_containers` defined in the .dbscheme. - * Use `ASTNode#getContainer()` instead. - */ -deprecated predicate exprContainers(ExprOrType expr, StmtContainer container) { - expr_containers(expr, container) -} - -/** - * Alias for the predicate `array_size` defined in the .dbscheme. - * Use `ArrayExpr#getSize()` instead. - */ -deprecated predicate arraySize(Expr ae, int sz) { array_size(ae, sz) } - -/** - * Alias for the predicate `is_delegating` defined in the .dbscheme. - * Use `YieldExpr#isDelegating()` instead. - */ -deprecated predicate isDelegating(YieldExpr yield) { is_delegating(yield) } - -/** - * Alias for the predicate `is_arguments_object` defined in the .dbscheme. - * Use the `ArgumentsVariable` class instead. - */ -deprecated predicate isArgumentsObject(Variable id) { is_arguments_object(id) } - -/** - * Alias for the predicate `is_computed` defined in the .dbscheme. - * Use the `isComputed()` method on the `MemberDeclaration`/`Property`/`PropertyPattern` class instead. - */ -deprecated predicate isComputed(Property prop) { is_computed(prop) } - -/** - * Alias for the predicate `is_method` defined in the .dbscheme. - * Use the `isMethod()` method on the `MemberDeclaration`/`Property` class instead. - */ -deprecated predicate isMethod(Property prop) { is_method(prop) } - -/** - * Alias for the predicate `is_static` defined in the .dbscheme. - * Use `MemberDeclaration#isStatic()` instead. - */ -deprecated predicate isStatic(Property prop) { is_static(prop) } - -/** - * Alias for the predicate `is_abstract_member` defined in the .dbscheme. - * Use `MemberDeclaration#isAbstract()` instead. - */ -deprecated predicate isAbstractMember(Property prop) { is_abstract_member(prop) } - -/** - * Alias for the predicate `is_const_enum` defined in the .dbscheme. - * Use `EnumDeclaration#isConst()` instead. - */ -deprecated predicate isConstEnum(EnumDeclaration id) { is_const_enum(id) } - -/** - * Alias for the predicate `is_abstract_class` defined in the .dbscheme. - * Use `ClassDefinition#isAbstract()` instead. - */ -deprecated predicate isAbstractClass(ClassDeclStmt id) { is_abstract_class(id) } - -/** - * Alias for the predicate `has_public_keyword` defined in the .dbscheme. - * Use `MemberDeclaration#hasPublicKeyword() instead. - */ -deprecated predicate hasPublicKeyword(Property prop) { has_public_keyword(prop) } - -/** - * Alias for the predicate `has_private_keyword` defined in the .dbscheme. - * Use `MemberDeclaration#isPrivate() instead. - */ -deprecated predicate hasPrivateKeyword(Property prop) { has_private_keyword(prop) } - -/** - * Alias for the predicate `has_protected_keyword` defined in the .dbscheme. - * Use `MemberDeclaration#isProtected() instead. - */ -deprecated predicate hasProtectedKeyword(Property prop) { has_protected_keyword(prop) } - -/** - * Alias for the predicate `has_readonly_keyword` defined in the .dbscheme. - * Use `FieldDeclaration#isReadonly()` instead. - */ -deprecated predicate hasReadonlyKeyword(Property prop) { has_readonly_keyword(prop) } - -/** - * Alias for the predicate `has_type_keyword` defined in the .dbscheme. - * Use the `isTypeOnly` method on the `ImportDeclaration`/`ExportDeclaration` classes instead. - */ -deprecated predicate hasTypeKeyword(ASTNode id) { has_type_keyword(id) } - -/** - * Alias for the predicate `is_optional_member` defined in the .dbscheme. - * Use `FieldDeclaration#isOptional()` instead. - */ -deprecated predicate isOptionalMember(Property id) { is_optional_member(id) } - -/** - * Alias for the predicate `has_definite_assignment_assertion` defined in the .dbscheme. - * Use the `hasDefiniteAssignmentAssertion` method on the `FieldDeclaration`/`VariableDeclarator` classes instead. - */ -deprecated predicate hasDefiniteAssignmentAssertion(ASTNode id) { - has_definite_assignment_assertion(id) -} - -/** - * Alias for the predicate `is_optional_parameter_declaration` defined in the .dbscheme. - * Use `Parameter#isDeclaredOptional()` instead. - */ -deprecated predicate isOptionalParameterDeclaration(Parameter parameter) { - is_optional_parameter_declaration(parameter) -} - -/** - * Alias for the predicate `has_asserts_keyword` defined in the .dbscheme. - * Use `PredicateTypeExpr#hasAssertsKeyword() instead. - */ -deprecated predicate hasAssertsKeyword(PredicateTypeExpr node) { has_asserts_keyword(node) } - -/** - * Alias for the predicate `js_parse_errors` defined in the .dbscheme. - * Use the `JSParseError` class instead. - */ -deprecated predicate jsParseErrors(JSParseError id, TopLevel toplevel, string message, string line) { - js_parse_errors(id, toplevel, message, line) -} - -/** - * Alias for the predicate `regexp_parse_errors` defined in the .dbscheme. - * Use the `RegExpParseError` class instead. - */ -deprecated predicate regexpParseErrors(RegExpParseError id, RegExpTerm regexp, string message) { - regexp_parse_errors(id, regexp, message) -} - -/** - * Alias for the predicate `is_greedy` defined in the .dbscheme. - * Use `RegExpQuantifier#isGreedy` instead. - */ -deprecated predicate isGreedy(RegExpQuantifier id) { is_greedy(id) } - -/** - * Alias for the predicate `range_quantifier_lower_bound` defined in the .dbscheme. - * Use `RegExpRange#getLowerBound()` instead. - */ -deprecated predicate rangeQuantifierLowerBound(RegExpRange id, int lo) { - range_quantifier_lower_bound(id, lo) -} - -/** - * Alias for the predicate `range_quantifier_upper_bound` defined in the .dbscheme. - * Use `RegExpRange#getUpperBound() instead. - */ -deprecated predicate rangeQuantifierUpperBound(RegExpRange id, int hi) { - range_quantifier_upper_bound(id, hi) -} - -/** - * Alias for the predicate `is_capture` defined in the .dbscheme. - * Use `RegExpGroup#isCapture()` instead. - */ -deprecated predicate isCapture(RegExpGroup id, int number) { is_capture(id, number) } - -/** - * Alias for the predicate `is_named_capture` defined in the .dbscheme. - * Use `RegExpGroup#isNamed()` instead. - */ -deprecated predicate isNamedCapture(RegExpGroup id, string name) { is_named_capture(id, name) } - -/** - * Alias for the predicate `is_inverted` defined in the .dbscheme. - * Use `RegExpCharacterClass#isInverted()` instead. - */ -deprecated predicate isInverted(RegExpCharacterClass id) { is_inverted(id) } - -/** - * Alias for the predicate `regexp_const_value` defined in the .dbscheme. - * Use `RegExpConstant#getValue()` instead. - */ -deprecated predicate regexpConstValue(RegExpConstant id, string value) { - regexp_const_value(id, value) -} - -/** - * Alias for the predicate `char_class_escape` defined in the .dbscheme. - * Use `RegExpCharacterClassEscape#getValue()` instead. - */ -deprecated predicate charClassEscape(RegExpCharacterClassEscape id, string value) { - char_class_escape(id, value) -} - -/** - * Alias for the predicate `named_backref` defined in the .dbscheme. - * Use `RegExpBackRef#getName()` instead. - */ -deprecated predicate namedBackref(RegExpBackRef id, string name) { named_backref(id, name) } - -/** - * Alias for the predicate `unicode_property_escapename` defined in the .dbscheme. - * Use `RegExpUnicodePropertyEscape#getName()` instead. - */ -deprecated predicate unicodePropertyEscapeName(RegExpUnicodePropertyEscape id, string name) { - unicode_property_escapename(id, name) -} - -/** - * Alias for the predicate `unicode_property_escapevalue` defined in the .dbscheme. - * Use `RegExpUnicodePropertyEscape#getValue()` instead. - */ -deprecated predicate unicodePropertyEscapeValue(RegExpUnicodePropertyEscape id, string value) { - unicode_property_escapevalue(id, value) -} - -/** - * Alias for the predicate `is_generator` defined in the .dbscheme. - * Use `Function#isGenerator()` instead. - */ -deprecated predicate isGenerator(Function fun) { is_generator(fun) } - -/** - * Alias for the predicate `has_rest_parameter` defined in the .dbscheme. - * Use `Function#hasRestParameter()` instead. - */ -deprecated predicate hasRestParameter(Function fun) { has_rest_parameter(fun) } - -/** - * Alias for the predicate `is_async` defined in the .dbscheme. - * Use `Function#isAsync()` instead. - */ -deprecated predicate isAsync(Function fun) { is_async(fun) } diff --git a/javascript/ql/lib/semmle/javascript/ApiGraphs.qll b/javascript/ql/lib/semmle/javascript/ApiGraphs.qll index 57dcf6f2eec..c9c283746db 100644 --- a/javascript/ql/lib/semmle/javascript/ApiGraphs.qll +++ b/javascript/ql/lib/semmle/javascript/ApiGraphs.qll @@ -109,7 +109,7 @@ module API { */ cached Node getMember(string m) { - Stages::APIStage::ref() and + Stages::ApiStage::ref() and result = this.getASuccessor(Label::member(m)) } @@ -119,7 +119,7 @@ module API { */ cached Node getUnknownMember() { - Stages::APIStage::ref() and + Stages::ApiStage::ref() and result = this.getASuccessor(Label::unknownMember()) } @@ -129,7 +129,7 @@ module API { */ cached Node getAMember() { - Stages::APIStage::ref() and + Stages::ApiStage::ref() and result = this.getMember(_) or result = this.getUnknownMember() @@ -148,7 +148,7 @@ module API { */ cached Node getInstance() { - Stages::APIStage::ref() and + Stages::ApiStage::ref() and result = this.getASuccessor(Label::instance()) } @@ -160,7 +160,7 @@ module API { */ cached Node getParameter(int i) { - Stages::APIStage::ref() and + Stages::ApiStage::ref() and result = this.getASuccessor(Label::parameter(i)) } @@ -182,7 +182,7 @@ module API { */ cached Node getReceiver() { - Stages::APIStage::ref() and + Stages::ApiStage::ref() and result = this.getASuccessor(Label::receiver()) } @@ -196,7 +196,7 @@ module API { */ cached Node getAParameter() { - Stages::APIStage::ref() and + Stages::ApiStage::ref() and result = this.getParameter(_) or result = this.getReceiver() @@ -210,7 +210,7 @@ module API { */ cached Node getReturn() { - Stages::APIStage::ref() and + Stages::ApiStage::ref() and result = this.getASuccessor(Label::return()) } @@ -220,7 +220,7 @@ module API { */ cached Node getPromised() { - Stages::APIStage::ref() and + Stages::ApiStage::ref() and result = this.getASuccessor(Label::promised()) } @@ -229,7 +229,7 @@ module API { */ cached Node getPromisedError() { - Stages::APIStage::ref() and + Stages::ApiStage::ref() and result = this.getASuccessor(Label::promisedError()) } @@ -892,7 +892,7 @@ module API { */ cached predicate edge(TApiNode pred, Label::ApiLabel lbl, TApiNode succ) { - Stages::APIStage::ref() and + Stages::ApiStage::ref() and exists(string m | pred = MkRoot() and lbl = Label::moduleLabel(m) @@ -1251,7 +1251,7 @@ private predicate exports(string m, string prop, DataFlow::Node rhs) { /** Gets the definition of module `m`. */ private Module importableModule(string m) { - exists(NPMPackage pkg, PackageJSON json | json = pkg.getPackageJSON() and not json.isPrivate() | + exists(NpmPackage pkg, PackageJson json | json = pkg.getPackageJson() and not json.isPrivate() | result = pkg.getMainModule() and not result.isExterns() and m = pkg.getPackageName() diff --git a/javascript/ql/lib/semmle/javascript/Arrays.qll b/javascript/ql/lib/semmle/javascript/Arrays.qll index 8461c44d699..bc0af1a06fd 100644 --- a/javascript/ql/lib/semmle/javascript/Arrays.qll +++ b/javascript/ql/lib/semmle/javascript/Arrays.qll @@ -152,15 +152,12 @@ private module ArrayDataFlow { /** * A node that reads or writes an element from an array inside a for-loop. */ - private class ArrayIndexingAccess extends DataFlow::Node { - DataFlow::PropRef read; - + private class ArrayIndexingAccess extends DataFlow::Node instanceof DataFlow::PropRef { ArrayIndexingAccess() { - read = this and TTNumber() = - unique(InferredType type | type = read.getPropertyNameExpr().flow().analyze().getAType()) and + unique(InferredType type | type = super.getPropertyNameExpr().flow().analyze().getAType()) and exists(VarAccess i, ExprOrVarDecl init | - i = read.getPropertyNameExpr() and init = any(ForStmt f).getInit() + i = super.getPropertyNameExpr() and init = any(ForStmt f).getInit() | i.getVariable().getADefinition() = init or i.getVariable().getADefinition().(VariableDeclarator).getDeclStmt() = init diff --git a/javascript/ql/lib/semmle/javascript/CFG.qll b/javascript/ql/lib/semmle/javascript/CFG.qll index a37fedc1ec0..4daf849bc3d 100644 --- a/javascript/ql/lib/semmle/javascript/CFG.qll +++ b/javascript/ql/lib/semmle/javascript/CFG.qll @@ -347,7 +347,7 @@ class ControlFlowNode extends @cfg_node, Locatable, NodeInStmtContainer { then result = "function in " + any(MethodDeclaration mem | mem.getBody() = this) else if this instanceof @decorator_list - then result = "parameter decorators of " + this.(ASTNode).getParent().(Function).describe() + then result = "parameter decorators of " + this.(AstNode).getParent().(Function).describe() else result = toString() } } diff --git a/javascript/ql/lib/semmle/javascript/CanonicalNames.qll b/javascript/ql/lib/semmle/javascript/CanonicalNames.qll index 7435be7131a..fc25314af95 100644 --- a/javascript/ql/lib/semmle/javascript/CanonicalNames.qll +++ b/javascript/ql/lib/semmle/javascript/CanonicalNames.qll @@ -48,7 +48,7 @@ class CanonicalName extends @symbol { string getExternalModuleName() { symbol_module(this, result) or - exists(PackageJSON pkg | + exists(PackageJson pkg | getModule() = pkg.getMainModule() and result = pkg.getPackageName() ) @@ -160,7 +160,7 @@ class CanonicalName extends @symbol { /** * Gets a definition of the entity with this canonical name. */ - ASTNode getADefinition() { none() } + AstNode getADefinition() { none() } /** * Gets a use that refers to the entity with this canonical name. diff --git a/javascript/ql/lib/semmle/javascript/CharacterEscapes.qll b/javascript/ql/lib/semmle/javascript/CharacterEscapes.qll index 6f95ed1c30a..1a19112cee3 100644 --- a/javascript/ql/lib/semmle/javascript/CharacterEscapes.qll +++ b/javascript/ql/lib/semmle/javascript/CharacterEscapes.qll @@ -32,7 +32,7 @@ module CharacterEscapes { * Holds if `n` is delimited by `delim` and contains `rawStringNode` with the raw string value `raw`. */ private predicate hasRawStringAndQuote( - DataFlow::ValueNode n, string delim, ASTNode rawStringNode, string raw + DataFlow::ValueNode n, string delim, AstNode rawStringNode, string raw ) { rawStringNode = n.asExpr() and raw = rawStringNode.(StringLiteral).getRawValue() and @@ -52,7 +52,7 @@ module CharacterEscapes { * * The character is the `i`th character of `rawStringNode`'s raw string value. */ - string getAnIdentityEscapedCharacter(DataFlow::Node n, ASTNode rawStringNode, int i) { + string getAnIdentityEscapedCharacter(DataFlow::Node n, AstNode rawStringNode, int i) { exists(string delim, string raw, string additionalEscapeChars | hasRawStringAndQuote(n, delim, rawStringNode, raw) and if rawStringNode instanceof RegExpLiteral @@ -80,7 +80,7 @@ module CharacterEscapes { * The character is the `i`th character of the raw string value of `rawStringNode`. */ string getALikelyRegExpPatternMistake( - RegExpPatternSource src, string mistake, ASTNode rawStringNode, int i + RegExpPatternSource src, string mistake, AstNode rawStringNode, int i ) { result = getAnIdentityEscapedCharacter(src, rawStringNode, i) and ( diff --git a/javascript/ql/lib/semmle/javascript/DOM.qll b/javascript/ql/lib/semmle/javascript/DOM.qll index 67f75ce7fa9..bca70363c67 100644 --- a/javascript/ql/lib/semmle/javascript/DOM.qll +++ b/javascript/ql/lib/semmle/javascript/DOM.qll @@ -76,10 +76,10 @@ module DOM { /** * A JSX element, viewed as an `ElementDefinition`. */ - private class JsxElementDefinition extends ElementDefinition, @jsx_element instanceof JSXElement { - override string getName() { result = JSXElement.super.getName() } + private class JsxElementDefinition extends ElementDefinition, @jsx_element instanceof JsxElement { + override string getName() { result = JsxElement.super.getName() } - override AttributeDefinition getAttribute(int i) { result = JSXElement.super.getAttribute(i) } + override AttributeDefinition getAttribute(int i) { result = JsxElement.super.getAttribute(i) } override ElementDefinition getParent() { result = super.getJsxParent() } } @@ -139,7 +139,7 @@ module DOM { * A JSX attribute, viewed as an `AttributeDefinition`. */ private class JsxAttributeDefinition extends AttributeDefinition, @jsx_attribute { - JSXAttribute attr; + JsxAttribute attr; JsxAttributeDefinition() { this = attr } @@ -323,7 +323,7 @@ module DOM { private class DefaultRange extends Range { DefaultRange() { - this.asExpr().(VarAccess).getVariable() instanceof DOMGlobalVariable + this.asExpr().(VarAccess).getVariable() instanceof DomGlobalVariable or exists(DataFlow::PropRead read | this = read and @@ -392,7 +392,7 @@ module DOM { */ private DataFlow::SourceNode domEventSource() { // e.g.

    e.target}/> - exists(JSXAttribute attr | attr.getName().matches("on%") | + exists(JsxAttribute attr | attr.getName().matches("on%") | result = attr.getValue().flow().getABoundFunctionValue(0).getParameter(0) ) or diff --git a/javascript/ql/lib/semmle/javascript/DefUse.qll b/javascript/ql/lib/semmle/javascript/DefUse.qll index 6fa0b438370..a36c682d766 100644 --- a/javascript/ql/lib/semmle/javascript/DefUse.qll +++ b/javascript/ql/lib/semmle/javascript/DefUse.qll @@ -249,8 +249,9 @@ class VarUse extends ControlFlowNode, @varref { /** * Holds if the definition of `v` in `def` reaches `use` along some control flow path * without crossing another definition of `v`. + * DEPRECATED: Use the `SSA.qll` library instead. */ -predicate definitionReaches(Variable v, VarDef def, VarUse use) { +deprecated predicate definitionReaches(Variable v, VarDef def, VarUse use) { v = use.getVariable() and exists(BasicBlock bb, int i, int next | next = nextDefAfter(bb, v, i, def) | exists(int j | j in [i + 1 .. next - 1] | bb.useAt(j, v, use)) @@ -265,16 +266,20 @@ predicate definitionReaches(Variable v, VarDef def, VarUse use) { /** * Holds if the definition of local variable `v` in `def` reaches `use` along some control flow path * without crossing another definition of `v`. + * DEPRECATED: Use the `SSA.qll` library instead. */ -predicate localDefinitionReaches(LocalVariable v, VarDef def, VarUse use) { +deprecated predicate localDefinitionReaches(LocalVariable v, VarDef def, VarUse use) { exists(SsaExplicitDefinition ssa | ssa.defines(def, v) and ssa = getAPseudoDefinitionInput*(use.getSsaVariable().getDefinition()) ) } -/** Holds if `nd` is a pseudo-definition and the result is one of its inputs. */ -private SsaDefinition getAPseudoDefinitionInput(SsaDefinition nd) { +/** + * Holds if `nd` is a pseudo-definition and the result is one of its inputs. + * DEPRECATED: Use the `SSA.qll` library instead. + */ +deprecated private SsaDefinition getAPseudoDefinitionInput(SsaDefinition nd) { result = nd.(SsaPseudoDefinition).getAnInput() } @@ -282,7 +287,7 @@ private SsaDefinition getAPseudoDefinitionInput(SsaDefinition nd) { * Holds if `d` is a definition of `v` at index `i` in `bb`, and the result is the next index * in `bb` after `i` at which the same variable is defined, or `bb.length()` if there is none. */ -private int nextDefAfter(BasicBlock bb, Variable v, int i, VarDef d) { +deprecated private int nextDefAfter(BasicBlock bb, Variable v, int i, VarDef d) { bb.defAt(i, v, d) and result = min(int jj | @@ -296,8 +301,9 @@ private int nextDefAfter(BasicBlock bb, Variable v, int i, VarDef d) { * * This is the case if there is a path from `earlier` to `later` that does not cross * another definition of `v`. + * DEPRECATED: Use the `SSA.qll` library instead. */ -predicate localDefinitionOverwrites(LocalVariable v, VarDef earlier, VarDef later) { +deprecated predicate localDefinitionOverwrites(LocalVariable v, VarDef earlier, VarDef later) { exists(BasicBlock bb, int i, int next | next = nextDefAfter(bb, v, i, earlier) | bb.defAt(next, v, later) or diff --git a/javascript/ql/lib/semmle/javascript/DynamicPropertyAccess.qll b/javascript/ql/lib/semmle/javascript/DynamicPropertyAccess.qll index b7308ca5ad4..0a647964ccf 100644 --- a/javascript/ql/lib/semmle/javascript/DynamicPropertyAccess.qll +++ b/javascript/ql/lib/semmle/javascript/DynamicPropertyAccess.qll @@ -181,16 +181,7 @@ class DynamicPropRead extends DataFlow::SourceNode, DataFlow::ValueNode { * dst[x][y] = src[y]; * ``` */ - predicate hasDominatingAssignment() { - exists(DataFlow::PropWrite write, BasicBlock bb, int i, int j, SsaVariable ssaVar | - write = getBase().getALocalSource().getAPropertyWrite() and - bb.getNode(i) = write.getWriteNode() and - bb.getNode(j) = astNode and - i < j and - write.getPropertyNameExpr() = ssaVar.getAUse() and - astNode.getIndex() = ssaVar.getAUse() - ) - } + predicate hasDominatingAssignment() { AccessPath::DominatingPaths::hasDominatingWrite(this) } } /** diff --git a/javascript/ql/lib/semmle/javascript/E4X.qll b/javascript/ql/lib/semmle/javascript/E4X.qll index e8e224e1e51..f69990138c8 100644 --- a/javascript/ql/lib/semmle/javascript/E4X.qll +++ b/javascript/ql/lib/semmle/javascript/E4X.qll @@ -14,7 +14,10 @@ module E4X { * * * ``` */ - class XMLAnyName extends Expr, @e4x_xml_anyname { } + class XmlAnyName extends Expr, @e4x_xml_anyname { } + + /** DEPRECATED: Alias for XmlAnyName */ + deprecated class XMLAnyName = XmlAnyName; /** * An E4X qualified identifier. @@ -29,7 +32,7 @@ module E4X { * Note that qualified identifiers are not currently supported by the parser, so snapshots * will not usually contain any. */ - class XMLQualifiedIdentifier extends Expr, @e4x_xml_qualident { + class XmlQualifiedIdentifier extends Expr, @e4x_xml_qualident { /** * Gets the left operand of this qualified identifier, which is either * an identifier or a wildcard. @@ -54,6 +57,9 @@ module E4X { } } + /** DEPRECATED: Alias for XmlQualifiedIdentifier */ + deprecated class XMLQualifiedIdentifier = XmlQualifiedIdentifier; + /** * An E4X attribute selector. * @@ -64,7 +70,7 @@ module E4X { * @[p] * ``` */ - class XMLAttributeSelector extends Expr, @e4x_xml_attribute_selector { + class XmlAttributeSelector extends Expr, @e4x_xml_attribute_selector { /** * Gets the selected attribute, which is either a static name (that is, a * wildcard identifier or a possibly qualified name), or an arbitrary @@ -83,6 +89,9 @@ module E4X { } } + /** DEPRECATED: Alias for XmlAttributeSelector */ + deprecated class XMLAttributeSelector = XmlAttributeSelector; + /** * An E4X filter expression. * @@ -92,7 +101,7 @@ module E4X { * employees.(@id == 0 || @id == 1) * ``` */ - class XMLFilterExpression extends Expr, @e4x_xml_filter_expression { + class XmlFilterExpression extends Expr, @e4x_xml_filter_expression { /** * Gets the left operand of this filter expression. */ @@ -108,6 +117,9 @@ module E4X { } } + /** DEPRECATED: Alias for XmlFilterExpression */ + deprecated class XMLFilterExpression = XmlFilterExpression; + /** * An E4X "dot-dot" expression. * @@ -117,7 +129,7 @@ module E4X { * e..name * ``` */ - class XMLDotDotExpression extends Expr, @e4x_xml_dotdotexpr { + class XmlDotDotExpression extends Expr, @e4x_xml_dotdotexpr { /** * Gets the base expression of this dot-dot expression. */ @@ -132,4 +144,7 @@ module E4X { result = getBase().getFirstControlFlowNode() } } + + /** DEPRECATED: Alias for XmlDotDotExpression */ + deprecated class XMLDotDotExpression = XmlDotDotExpression; } diff --git a/javascript/ql/lib/semmle/javascript/ES2015Modules.qll b/javascript/ql/lib/semmle/javascript/ES2015Modules.qll index 4a8777d46ec..7ee6311393b 100644 --- a/javascript/ql/lib/semmle/javascript/ES2015Modules.qll +++ b/javascript/ql/lib/semmle/javascript/ES2015Modules.qll @@ -647,13 +647,6 @@ abstract class ReExportDeclaration extends ExportDeclaration { /** Gets the path of the module from which this declaration re-exports. */ abstract ConstantString getImportedPath(); - /** - * DEPRECATED. Use `getReExportedES2015Module()` instead. - * - * Gets the module from which this declaration re-exports. - */ - deprecated ES2015Module getImportedModule() { result = getReExportedModule() } - /** Gets the module from which this declaration re-exports, if it is an ES2015 module. */ ES2015Module getReExportedES2015Module() { result = getReExportedModule() } diff --git a/javascript/ql/lib/semmle/javascript/Expr.qll b/javascript/ql/lib/semmle/javascript/Expr.qll index b99b4c71be8..69dbdd11451 100644 --- a/javascript/ql/lib/semmle/javascript/Expr.qll +++ b/javascript/ql/lib/semmle/javascript/Expr.qll @@ -2744,7 +2744,7 @@ class Decorator extends @decorator, Expr { * } * ``` */ -class Decoratable extends ASTNode { +class Decoratable extends AstNode { Decoratable() { this instanceof ClassDefinition or this instanceof Property or diff --git a/javascript/ql/lib/semmle/javascript/Externs.qll b/javascript/ql/lib/semmle/javascript/Externs.qll index 5fe855a46a8..157b4b3f4cf 100644 --- a/javascript/ql/lib/semmle/javascript/Externs.qll +++ b/javascript/ql/lib/semmle/javascript/Externs.qll @@ -64,7 +64,7 @@ import javascript * Object.prototype.hasOwnProperty = function(p) {}; * */ -abstract class ExternalDecl extends ASTNode { +abstract class ExternalDecl extends AstNode { /** Gets the name of this declaration. */ abstract string getName(); @@ -125,7 +125,7 @@ abstract class ExternalVarDecl extends ExternalDecl { * * The result can be either a function or an expression. */ - abstract ASTNode getInit(); + abstract AstNode getInit(); /** * Gets a JSDoc tag associated with this declaration. @@ -179,7 +179,7 @@ class ExternalGlobalFunctionDecl extends ExternalGlobalDecl, FunctionDeclStmt { /** Gets the name of this declaration. */ override string getName() { result = FunctionDeclStmt.super.getName() } - override ASTNode getInit() { result = this } + override AstNode getInit() { result = this } } /** @@ -336,7 +336,7 @@ class ExternalInstanceMemberDecl extends ExternalMemberDecl { * function(p) {}; // external function entity * */ -class ExternalEntity extends ASTNode { +class ExternalEntity extends AstNode { ExternalEntity() { exists(ExternalVarDecl d | d.getInit() = this) } /** Gets the variable declaration to which this entity belongs. */ diff --git a/javascript/ql/lib/semmle/javascript/GlobalAccessPaths.qll b/javascript/ql/lib/semmle/javascript/GlobalAccessPaths.qll index 924e8f0a166..967729d3fd4 100644 --- a/javascript/ql/lib/semmle/javascript/GlobalAccessPaths.qll +++ b/javascript/ql/lib/semmle/javascript/GlobalAccessPaths.qll @@ -7,31 +7,6 @@ private import semmle.javascript.dataflow.InferredTypes private import semmle.javascript.dataflow.internal.FlowSteps as FlowSteps private import semmle.javascript.internal.CachedStages -deprecated module GlobalAccessPath { - /** - * DEPRECATED. Instead use `AccessPath::getAReferenceTo` with the result and parameter reversed. - */ - pragma[inline] - string fromReference(DataFlow::Node node) { node = AccessPath::getAReferenceTo(result) } - - /** - * DEPRECATED. Instead use `AccessPath::getAnAssignmentTo` with the result and parameter reversed. - */ - pragma[inline] - string fromRhs(DataFlow::Node node) { node = AccessPath::getAnAssignmentTo(result) } - - /** - * DEPRECATED. Use `AccessPath::getAReferenceOrAssignmentTo`. - */ - pragma[inline] - string getAccessPath(DataFlow::Node node) { - result = fromReference(node) - or - not exists(fromReference(node)) and - result = fromRhs(node) - } -} - /** * Provides predicates for associating access paths with data flow nodes. * @@ -557,7 +532,7 @@ module AccessPath { */ cached predicate hasDominatingWrite(DataFlow::PropRead read) { - Stages::FlowSteps::ref() and + Stages::TypeTracking::ref() and // within the same basic block. exists(ReachableBasicBlock bb, Root root, string path, int ranking | read.asExpr() = rankedAccessPath(bb, root, path, ranking, AccessPathRead()) and @@ -569,6 +544,21 @@ module AccessPath { read.asExpr() = getAccessTo(root, path, AccessPathRead()) and getAWriteBlock(root, path).strictlyDominates(read.getBasicBlock()) ) + or + // Dynamic write where the same variable is used to index the read and write (in the same basic block) + // For example, this is true for `dst[x]` on line 2 below: + // ```js + // dst[x] = {}; + // dst[x][y] = src[y]; + // ``` + exists(DataFlow::PropWrite write, BasicBlock bb, int i, int j, SsaVariable ssaVar | + write = read.getBase().getALocalSource().getAPropertyWrite() and + bb.getNode(i) = write.getWriteNode() and + bb.getNode(j) = read.asExpr() and + i < j and + write.getPropertyNameExpr() = ssaVar.getAUse() and + read.getPropertyNameExpr() = ssaVar.getAUse() + ) } } } diff --git a/javascript/ql/lib/semmle/javascript/JSDoc.qll b/javascript/ql/lib/semmle/javascript/JSDoc.qll index 2621c92e3c6..b2b7548886f 100644 --- a/javascript/ql/lib/semmle/javascript/JSDoc.qll +++ b/javascript/ql/lib/semmle/javascript/JSDoc.qll @@ -55,7 +55,7 @@ class JSDoc extends @jsdoc, Locatable { * } * */ -abstract class Documentable extends ASTNode { +abstract class Documentable extends AstNode { /** Gets the JSDoc comment for this element, if any. */ cached JSDoc getDocumentation() { diff --git a/javascript/ql/lib/semmle/javascript/JSON.qll b/javascript/ql/lib/semmle/javascript/JSON.qll index ed3f6f69637..d474965051e 100644 --- a/javascript/ql/lib/semmle/javascript/JSON.qll +++ b/javascript/ql/lib/semmle/javascript/JSON.qll @@ -19,14 +19,14 @@ import javascript * { "value": 0 } * ``` */ -class JSONValue extends @json_value, Locatable { +class JsonValue extends @json_value, Locatable { override Location getLocation() { json_locations(this, result) } /** Gets the parent value to which this value belongs, if any. */ - JSONValue getParent() { json(this, _, result, _, _) } + JsonValue getParent() { json(this, _, result, _, _) } /** Gets the `i`th child value of this value. */ - JSONValue getChild(int i) { json(result, _, this, i, _) } + JsonValue getChild(int i) { json(result, _, this, i, _) } /** Holds if this JSON value is the top level element in its enclosing file. */ predicate isTopLevel() { not exists(getParent()) } @@ -42,23 +42,26 @@ class JSONValue extends @json_value, Locatable { } /** If this is an object, gets the value of property `name`. */ - JSONValue getPropValue(string name) { json_properties(this, name, result) } + JsonValue getPropValue(string name) { json_properties(this, name, result) } /** If this is an array, gets the value of the `i`th element. */ - JSONValue getElementValue(int i) { result = this.(JSONArray).getChild(i) } + JsonValue getElementValue(int i) { result = this.(JsonArray).getChild(i) } /** If this is a string constant, gets the value of the string. */ - string getStringValue() { result = this.(JSONString).getValue() } + string getStringValue() { result = this.(JsonString).getValue() } /** If this is an integer constant, gets its numeric value. */ - int getIntValue() { result = this.(JSONNumber).getValue().toInt() } + int getIntValue() { result = this.(JsonNumber).getValue().toInt() } /** If this is a boolean constant, gets its boolean value. */ - boolean getBooleanValue() { result.toString() = this.(JSONBoolean).getValue() } + boolean getBooleanValue() { result.toString() = this.(JsonBoolean).getValue() } - override string getAPrimaryQlClass() { result = "JSONValue" } + override string getAPrimaryQlClass() { result = "JsonValue" } } +/** DEPRECATED: Alias for JsonValue */ +deprecated class JSONValue = JsonValue; + /** * A JSON-encoded primitive value. * @@ -72,7 +75,7 @@ class JSONValue extends @json_value, Locatable { * "a string" * ``` */ -abstract class JSONPrimitiveValue extends JSONValue { +abstract class JsonPrimitiveValue extends JsonValue { /** Gets a string representation of the encoded value. */ string getValue() { json_literals(result, _, this) } @@ -80,6 +83,9 @@ abstract class JSONPrimitiveValue extends JSONValue { string getRawValue() { json_literals(_, result, this) } } +/** DEPRECATED: Alias for JsonPrimitiveValue */ +deprecated class JSONPrimitiveValue = JsonPrimitiveValue; + /** * A JSON-encoded null value. * @@ -89,10 +95,13 @@ abstract class JSONPrimitiveValue extends JSONValue { * null * ``` */ -class JSONNull extends @json_null, JSONPrimitiveValue { - override string getAPrimaryQlClass() { result = "JSONNull" } +class JsonNull extends @json_null, JsonPrimitiveValue { + override string getAPrimaryQlClass() { result = "JsonNull" } } +/** DEPRECATED: Alias for JsonNull */ +deprecated class JSONNull = JsonNull; + /** * A JSON-encoded Boolean value. * @@ -103,10 +112,13 @@ class JSONNull extends @json_null, JSONPrimitiveValue { * false * ``` */ -class JSONBoolean extends @json_boolean, JSONPrimitiveValue { - override string getAPrimaryQlClass() { result = "JSONBoolean" } +class JsonBoolean extends @json_boolean, JsonPrimitiveValue { + override string getAPrimaryQlClass() { result = "JsonBoolean" } } +/** DEPRECATED: Alias for JsonBoolean */ +deprecated class JSONBoolean = JsonBoolean; + /** * A JSON-encoded number. * @@ -117,10 +129,13 @@ class JSONBoolean extends @json_boolean, JSONPrimitiveValue { * 1.0 * ``` */ -class JSONNumber extends @json_number, JSONPrimitiveValue { - override string getAPrimaryQlClass() { result = "JSONNumber" } +class JsonNumber extends @json_number, JsonPrimitiveValue { + override string getAPrimaryQlClass() { result = "JsonNumber" } } +/** DEPRECATED: Alias for JsonNumber */ +deprecated class JSONNumber = JsonNumber; + /** * A JSON-encoded string value. * @@ -130,10 +145,13 @@ class JSONNumber extends @json_number, JSONPrimitiveValue { * "a string" * ``` */ -class JSONString extends @json_string, JSONPrimitiveValue { - override string getAPrimaryQlClass() { result = "JSONString" } +class JsonString extends @json_string, JsonPrimitiveValue { + override string getAPrimaryQlClass() { result = "JsonString" } } +/** DEPRECATED: Alias for JsonString */ +deprecated class JSONString = JsonString; + /** * A JSON-encoded array. * @@ -143,13 +161,16 @@ class JSONString extends @json_string, JSONPrimitiveValue { * [ 1, 2, 3 ] * ``` */ -class JSONArray extends @json_array, JSONValue { - override string getAPrimaryQlClass() { result = "JSONArray" } +class JsonArray extends @json_array, JsonValue { + override string getAPrimaryQlClass() { result = "JsonArray" } /** Gets the string value of the `i`th element of this array. */ string getElementStringValue(int i) { result = getElementValue(i).getStringValue() } } +/** DEPRECATED: Alias for JsonArray */ +deprecated class JSONArray = JsonArray; + /** * A JSON-encoded object. * @@ -159,18 +180,24 @@ class JSONArray extends @json_array, JSONValue { * { "value": 0 } * ``` */ -class JSONObject extends @json_object, JSONValue { - override string getAPrimaryQlClass() { result = "JSONObject" } +class JsonObject extends @json_object, JsonValue { + override string getAPrimaryQlClass() { result = "JsonObject" } /** Gets the string value of property `name` of this object. */ string getPropStringValue(string name) { result = getPropValue(name).getStringValue() } } +/** DEPRECATED: Alias for JsonObject */ +deprecated class JSONObject = JsonObject; + /** * An error reported by the JSON parser. */ -class JSONParseError extends @json_parse_error, Error { +class JsonParseError extends @json_parse_error, Error { override Location getLocation() { json_locations(this, result) } override string getMessage() { json_errors(this, result) } } + +/** DEPRECATED: Alias for JsonParseError */ +deprecated class JSONParseError = JsonParseError; diff --git a/javascript/ql/lib/semmle/javascript/JSX.qll b/javascript/ql/lib/semmle/javascript/JSX.qll index 4080964886e..f89f02abb54 100644 --- a/javascript/ql/lib/semmle/javascript/JSX.qll +++ b/javascript/ql/lib/semmle/javascript/JSX.qll @@ -15,7 +15,7 @@ import javascript * <>

    Title

    Some text * ``` */ -class JSXNode extends Expr, @jsx_element { +class JsxNode extends Expr, @jsx_element { /** Gets the `i`th element in the body of this element or fragment. */ Expr getBodyElement(int i) { i >= 0 and result = getChildExpr(-i - 2) } @@ -25,11 +25,14 @@ class JSXNode extends Expr, @jsx_element { /** * Gets the parent JSX element or fragment of this element. */ - JSXNode getJsxParent() { this = result.getABodyElement() } + JsxNode getJsxParent() { this = result.getABodyElement() } - override string getAPrimaryQlClass() { result = "JSXNode" } + override string getAPrimaryQlClass() { result = "JsxNode" } } +/** DEPRECATED: Alias for JsxNode */ +deprecated class JSXNode = JsxNode; + /** * A JSX element. * @@ -40,39 +43,45 @@ class JSXNode extends Expr, @jsx_element { * * ``` */ -class JSXElement extends JSXNode { - JSXName name; +class JsxElement extends JsxNode { + JsxName name; - JSXElement() { name = getChildExpr(-1) } + JsxElement() { name = getChildExpr(-1) } /** Gets the expression denoting the name of this element. */ - JSXName getNameExpr() { result = name } + JsxName getNameExpr() { result = name } /** Gets the name of this element. */ string getName() { result = name.getValue() } /** Gets the `i`th attribute of this element. */ - JSXAttribute getAttribute(int i) { properties(result, this, i, _, _) } + JsxAttribute getAttribute(int i) { properties(result, this, i, _, _) } /** Gets an attribute of this element. */ - JSXAttribute getAnAttribute() { result = getAttribute(_) } + JsxAttribute getAnAttribute() { result = getAttribute(_) } /** Gets the attribute of this element with the given name, if any. */ - JSXAttribute getAttributeByName(string n) { result = getAnAttribute() and result.getName() = n } + JsxAttribute getAttributeByName(string n) { result = getAnAttribute() and result.getName() = n } override ControlFlowNode getFirstControlFlowNode() { result = getNameExpr().getFirstControlFlowNode() } - override string getAPrimaryQlClass() { result = "JSXElement" } + override string getAPrimaryQlClass() { result = "JsxElement" } /** * Holds if this JSX element is a HTML element. * That is, the name starts with a lowercase letter. */ - predicate isHTMLElement() { getName().regexpMatch("[a-z].*") } + predicate isHtmlElement() { getName().regexpMatch("[a-z].*") } + + /** DEPRECATED: Alias for isHtmlElement */ + deprecated predicate isHTMLElement() { isHtmlElement() } } +/** DEPRECATED: Alias for JsxElement */ +deprecated class JSXElement = JsxElement; + /** * A JSX fragment. * @@ -82,8 +91,8 @@ class JSXElement extends JSXNode { * <>

    Title

    Some text * ``` */ -class JSXFragment extends JSXNode { - JSXFragment() { not exists(getChildExpr(-1)) } +class JsxFragment extends JsxNode { + JsxFragment() { not exists(getChildExpr(-1)) } override ControlFlowNode getFirstControlFlowNode() { result = getBodyElement(0).getFirstControlFlowNode() @@ -91,9 +100,12 @@ class JSXFragment extends JSXNode { not exists(getABodyElement()) and result = this } - override string getAPrimaryQlClass() { result = "JSXFragment" } + override string getAPrimaryQlClass() { result = "JsxFragment" } } +/** DEPRECATED: Alias for JsxFragment */ +deprecated class JSXFragment = JsxFragment; + /** * An attribute of a JSX element, including spread attributes. * @@ -105,13 +117,13 @@ class JSXFragment extends JSXNode { *
    // `{...attrs}` is a (spread) attribute * ``` */ -class JSXAttribute extends ASTNode, @jsx_attribute { +class JsxAttribute extends AstNode, @jsx_attribute { /** * Gets the expression denoting the name of this attribute. * * This is not defined for spread attributes. */ - JSXName getNameExpr() { result = getChildExpr(0) } + JsxName getNameExpr() { result = getChildExpr(0) } /** * Gets the name of this attribute. @@ -127,7 +139,7 @@ class JSXAttribute extends ASTNode, @jsx_attribute { string getStringValue() { result = getValue().getStringValue() } /** Gets the JSX element to which this attribute belongs. */ - JSXElement getElement() { this = result.getAnAttribute() } + JsxElement getElement() { this = result.getAnAttribute() } override ControlFlowNode getFirstControlFlowNode() { result = getNameExpr().getFirstControlFlowNode() @@ -137,9 +149,12 @@ class JSXAttribute extends ASTNode, @jsx_attribute { override string toString() { properties(this, _, _, _, result) } - override string getAPrimaryQlClass() { result = "JSXAttribute" } + override string getAPrimaryQlClass() { result = "JsxAttribute" } } +/** DEPRECATED: Alias for JsxAttribute */ +deprecated class JSXAttribute = JsxAttribute; + /** * A spread attribute of a JSX element. * @@ -149,8 +164,8 @@ class JSXAttribute extends ASTNode, @jsx_attribute { *
    // `{...attrs}` is a spread attribute * ``` */ -class JSXSpreadAttribute extends JSXAttribute { - JSXSpreadAttribute() { not exists(getNameExpr()) } +class JsxSpreadAttribute extends JsxAttribute { + JsxSpreadAttribute() { not exists(getNameExpr()) } override SpreadElement getValue() { // override for more precise result type @@ -158,6 +173,9 @@ class JSXSpreadAttribute extends JSXAttribute { } } +/** DEPRECATED: Alias for JsxSpreadAttribute */ +deprecated class JSXSpreadAttribute = JsxSpreadAttribute; + /** * A namespace-qualified name such as `n:a`. * @@ -167,7 +185,7 @@ class JSXSpreadAttribute extends JSXAttribute { * html:href * ``` */ -class JSXQualifiedName extends Expr, @jsx_qualified_name { +class JsxQualifiedName extends Expr, @jsx_qualified_name { /** Gets the namespace component of this qualified name. */ Identifier getNamespace() { result = getChildExpr(0) } @@ -178,9 +196,12 @@ class JSXQualifiedName extends Expr, @jsx_qualified_name { result = getNamespace().getFirstControlFlowNode() } - override string getAPrimaryQlClass() { result = "JSXQualifiedName" } + override string getAPrimaryQlClass() { result = "JsxQualifiedName" } } +/** DEPRECATED: Alias for JsxQualifiedName */ +deprecated class JSXQualifiedName = JsxQualifiedName; + /** * A name of an JSX element or attribute (which is * always an identifier, a dot expression, or a qualified @@ -194,12 +215,12 @@ class JSXQualifiedName extends Expr, @jsx_qualified_name { * data.path * ``` */ -class JSXName extends Expr { - JSXName() { +class JsxName extends Expr { + JsxName() { this instanceof Identifier or this instanceof ThisExpr or - this.(DotExpr).getBase() instanceof JSXName or - this instanceof JSXQualifiedName + this.(DotExpr).getBase() instanceof JsxName or + this instanceof JsxQualifiedName } /** @@ -209,10 +230,10 @@ class JSXName extends Expr { result = this.(Identifier).getName() or exists(DotExpr dot | dot = this | - result = dot.getBase().(JSXName).getValue() + "." + dot.getPropertyName() + result = dot.getBase().(JsxName).getValue() + "." + dot.getPropertyName() ) or - exists(JSXQualifiedName qual | qual = this | + exists(JsxQualifiedName qual | qual = this | result = qual.getNamespace().getName() + ":" + qual.getName().getName() ) or @@ -221,6 +242,9 @@ class JSXName extends Expr { } } +/** DEPRECATED: Alias for JsxName */ +deprecated class JSXName = JsxName; + /** * An interpolating expression that interpolates nothing. * @@ -230,10 +254,13 @@ class JSXName extends Expr { * { /* TBD */ } * */ -class JSXEmptyExpr extends Expr, @jsx_empty_expr { - override string getAPrimaryQlClass() { result = "JSXEmptyExpr" } +class JsxEmptyExpr extends Expr, @jsx_empty_expr { + override string getAPrimaryQlClass() { result = "JsxEmptyExpr" } } +/** DEPRECATED: Alias for JsxEmptyExpr */ +deprecated class JSXEmptyExpr = JsxEmptyExpr; + /** * A legacy `@jsx` pragma. * @@ -243,12 +270,18 @@ class JSXEmptyExpr extends Expr, @jsx_empty_expr { * @jsx React.DOM * ``` */ -class JSXPragma extends JSDocTag { - JSXPragma() { getTitle() = "jsx" } +class JsxPragma extends JSDocTag { + JsxPragma() { getTitle() = "jsx" } /** * Gets the DOM name specified by the pragma; for `@jsx React.DOM`, * the result is `React.DOM`. */ - string getDOMName() { result = getDescription().trim() } + string getDomName() { result = getDescription().trim() } + + /** DEPRECATED: Alias for getDomName */ + deprecated string getDOMName() { result = getDomName() } } + +/** DEPRECATED: Alias for JsxPragma */ +deprecated class JSXPragma = JsxPragma; diff --git a/javascript/ql/lib/semmle/javascript/JsonStringifiers.qll b/javascript/ql/lib/semmle/javascript/JsonStringifiers.qll index 8f6edd312cd..03ca152471f 100644 --- a/javascript/ql/lib/semmle/javascript/JsonStringifiers.qll +++ b/javascript/ql/lib/semmle/javascript/JsonStringifiers.qll @@ -64,7 +64,7 @@ class JSON2CSVTaintStep extends TaintTracking::SharedTaintStep { * This is not quite a `JSON.stringify` call, as it e.g. does not wrap keys in double quotes. * It's therefore modeled as a taint-step rather than as a `JSON.stringify` call. */ -class PrettyJSONTaintStep extends TaintTracking::SharedTaintStep { +class PrettyJsonTaintStep extends TaintTracking::SharedTaintStep { override predicate step(DataFlow::Node pred, DataFlow::Node succ) { exists(API::CallNode call | call = API::moduleImport("prettyjson").getMember("render").getACall() @@ -74,3 +74,6 @@ class PrettyJSONTaintStep extends TaintTracking::SharedTaintStep { ) } } + +/** DEPRECATED: Alias for PrettyJsonTaintStep */ +deprecated class PrettyJSONTaintStep = PrettyJsonTaintStep; diff --git a/javascript/ql/lib/semmle/javascript/Modules.qll b/javascript/ql/lib/semmle/javascript/Modules.qll index 9e2a4ac3fce..8c36044bb24 100644 --- a/javascript/ql/lib/semmle/javascript/Modules.qll +++ b/javascript/ql/lib/semmle/javascript/Modules.qll @@ -27,76 +27,6 @@ abstract class Module extends TopLevel { /** Gets a symbol exported by this module. */ string getAnExportedSymbol() { exists(this.getAnExportedValue(result)) } - /** - * DEPRECATED. Use `getAnExportedValue` instead. - * - * Holds if this module explicitly exports symbol `name` at the - * program element `export`. - * - * Note that in some module systems (notably CommonJS and AMD) - * modules are arbitrary objects that export all their - * properties. This predicate only considers properties - * that are explicitly defined on the module object. - * - * Symbols defined in another module that are re-exported by - * this module are only sometimes considered. - */ - deprecated predicate exports(string name, ASTNode export) { - this instanceof AmdModule and - exists(DataFlow::PropWrite pwn | export = pwn.getAstNode() | - pwn.getBase().analyze().getAValue() = this.(AmdModule).getDefine().getAModuleExportsValue() and - name = pwn.getPropertyName() - ) - or - this instanceof Closure::ClosureModule and - exists(DataFlow::PropWrite write, Expr base | - write.getAstNode() = export and - write.writes(base.flow(), name, _) and - ( - base = this.(Closure::ClosureModule).getExportsVariable().getAReference() - or - base = this.(Closure::ClosureModule).getExportsVariable().getAnAssignedExpr() - ) - ) - or - this instanceof NodeModule and - ( - // a property write whose base is `exports` or `module.exports` - exists(DataFlow::PropWrite pwn | export = pwn.getAstNode() | - pwn.getBase() = this.(NodeModule).getAModuleExportsNode() and - name = pwn.getPropertyName() - ) - or - // a re-export using spread-operator. E.g. `const foo = require("./foo"); module.exports = {bar: bar, ...foo};` - exists(ObjectExpr obj | obj = this.(NodeModule).getAModuleExportsNode().asExpr() | - obj.getAProperty() - .(SpreadProperty) - .getInit() - .(SpreadElement) - .getOperand() - .flow() - .getALocalSource() - .asExpr() - .(Import) - .getImportedModule() - .exports(name, export) - ) - or - // an externs definition (where appropriate) - exists(PropAccess pacc | export = pacc | - pacc.getBase() = this.(NodeModule).getAModuleExportsNode().asExpr() and - name = pacc.getPropertyName() and - this.isExterns() and - exists(pacc.getDocumentation()) - ) - ) - or - this instanceof ES2015Module and - exists(ExportDeclaration ed | ed = this.(ES2015Module).getAnExport() and ed = export | - ed.exportsAs(_, name) - ) - } - /** * Get a value that is explicitly exported from this module with under `name`. * @@ -188,7 +118,7 @@ abstract class Module extends TopLevel { * An import in a module, which may be an ECMAScript 2015-style * `import` statement, a CommonJS-style `require` import, or an AMD dependency. */ -abstract class Import extends ASTNode { +abstract class Import extends AstNode { /** Gets the module in which this import appears. */ abstract Module getEnclosingModule(); @@ -275,26 +205,13 @@ abstract class Import extends ASTNode { abstract DataFlow::Node getImportedModuleNode(); } -/** - * DEPRECATED. Use `PathExpr` instead. - * - * A path expression that appears in a module and is resolved relative to it. - */ -abstract deprecated class PathExprInModule extends PathExpr { - PathExprInModule() { - this.(Expr).getTopLevel() instanceof Module - or - this.(Comment).getTopLevel() instanceof Module - } -} - /** * Gets a module imported from another package in the same repository. * * No support for importing from folders inside the other package. */ private Module resolveNeighbourPackage(PathString importPath) { - exists(PackageJSON json | importPath = json.getPackageName() and result = json.getMainModule()) + exists(PackageJson json | importPath = json.getPackageName() and result = json.getMainModule()) or exists(string package | result.getFile().getParentContainer() = getPackageFolder(package) and @@ -307,7 +224,7 @@ private Module resolveNeighbourPackage(PathString importPath) { */ pragma[noinline] private Folder getPackageFolder(string package) { - exists(PackageJSON json | + exists(PackageJson json | json.getPackageName() = package and result = json.getFile().getParentContainer() ) diff --git a/javascript/ql/lib/semmle/javascript/NPM.qll b/javascript/ql/lib/semmle/javascript/NPM.qll index 03d62b3aac6..bfd1098d351 100644 --- a/javascript/ql/lib/semmle/javascript/NPM.qll +++ b/javascript/ql/lib/semmle/javascript/NPM.qll @@ -6,8 +6,8 @@ import javascript private import NodeModuleResolutionImpl /** A `package.json` configuration object. */ -class PackageJSON extends JSONObject { - PackageJSON() { +class PackageJson extends JsonObject { + PackageJson() { this.getJsonFile().getBaseName() = "package.json" and this.isTopLevel() } @@ -22,7 +22,7 @@ class PackageJSON extends JSONObject { string getDescription() { result = this.getPropStringValue("description") } /** Gets the array of keywords for this package. */ - JSONArray getKeywords() { result = this.getPropValue("keywords") } + JsonArray getKeywords() { result = this.getPropValue("keywords") } /** Gets a keyword for this package. */ string getAKeyword() { result = this.getKeywords().getElementStringValue(_) } @@ -45,7 +45,7 @@ class PackageJSON extends JSONObject { } /** Gets the array of files for this package. */ - JSONArray getFiles() { result = this.getPropValue("files") } + JsonArray getFiles() { result = this.getPropValue("files") } /** Gets a file for this package. */ string getAFile() { result = this.getFiles().getElementStringValue(_) } @@ -67,16 +67,16 @@ class PackageJSON extends JSONObject { } /** Gets information about the directories of this package. */ - JSONObject getDirectories() { result = this.getPropValue("directories") } + JsonObject getDirectories() { result = this.getPropValue("directories") } /** Gets repository information for this package. */ RepositoryInfo getRepository() { result = this.getPropValue("repository") } /** Gets information about the scripts of this package. */ - JSONObject getScripts() { result = this.getPropValue("scripts") } + JsonObject getScripts() { result = this.getPropValue("scripts") } /** Gets configuration information for this package. */ - JSONObject getConfig() { result = this.getPropValue("config") } + JsonObject getConfig() { result = this.getPropValue("config") } /** Gets the dependencies of this package. */ PackageDependencies getDependencies() { result = this.getPropValue("dependencies") } @@ -131,10 +131,10 @@ class PackageJSON extends JSONObject { PackageDependencies getEngines() { result = this.getPropValue("engines") } /** Holds if this package has strict engine requirements. */ - predicate isEngineStrict() { this.getPropValue("engineStrict").(JSONBoolean).getValue() = "true" } + predicate isEngineStrict() { this.getPropValue("engineStrict").(JsonBoolean).getValue() = "true" } /** Gets information about operating systems supported by this package. */ - JSONArray getOSs() { result = this.getPropValue("os") } + JsonArray getOSs() { result = this.getPropValue("os") } /** Gets an operating system supported by this package. */ string getWhitelistedOS() { @@ -150,7 +150,7 @@ class PackageJSON extends JSONObject { } /** Gets information about platforms supported by this package. */ - JSONArray getCPUs() { result = this.getPropValue("cpu") } + JsonArray getCPUs() { result = this.getPropValue("cpu") } /** Gets a platform supported by this package. */ string getWhitelistedCPU() { @@ -166,13 +166,13 @@ class PackageJSON extends JSONObject { } /** Holds if this package prefers to be installed globally. */ - predicate isPreferGlobal() { this.getPropValue("preferGlobal").(JSONBoolean).getValue() = "true" } + predicate isPreferGlobal() { this.getPropValue("preferGlobal").(JsonBoolean).getValue() = "true" } /** Holds if this is a private package. */ - predicate isPrivate() { this.getPropValue("private").(JSONBoolean).getValue() = "true" } + predicate isPrivate() { this.getPropValue("private").(JsonBoolean).getValue() = "true" } /** Gets publishing configuration information about this package. */ - JSONValue getPublishConfig() { result = this.getPropValue("publishConfig") } + JsonValue getPublishConfig() { result = this.getPropValue("publishConfig") } /** * Gets the main module of this package. @@ -182,13 +182,16 @@ class PackageJSON extends JSONObject { } } +/** DEPRECATED: Alias for PackageJson */ +deprecated class PackageJSON = PackageJson; + /** * A representation of bug tracker information for an NPM package. */ -class BugTrackerInfo extends JSONValue { +class BugTrackerInfo extends JsonValue { BugTrackerInfo() { - exists(PackageJSON pkg | pkg.getPropValue("bugs") = this) and - (this instanceof JSONObject or this instanceof JSONString) + exists(PackageJson pkg | pkg.getPropValue("bugs") = this) and + (this instanceof JsonObject or this instanceof JsonString) } /** Gets the bug tracker URL. */ @@ -204,13 +207,13 @@ class BugTrackerInfo extends JSONValue { /** * A representation of contributor information for an NPM package. */ -class ContributorInfo extends JSONValue { +class ContributorInfo extends JsonValue { ContributorInfo() { - exists(PackageJSON pkg | + exists(PackageJson pkg | this = pkg.getPropValue("author") or this = pkg.getPropValue("contributors").getElementValue(_) ) and - (this instanceof JSONObject or this instanceof JSONString) + (this instanceof JsonObject or this instanceof JsonString) } /** @@ -244,8 +247,8 @@ class ContributorInfo extends JSONValue { /** * A representation of repository information for an NPM package. */ -class RepositoryInfo extends JSONObject { - RepositoryInfo() { exists(PackageJSON pkg | this = pkg.getPropValue("repository")) } +class RepositoryInfo extends JsonObject { + RepositoryInfo() { exists(PackageJson pkg | this = pkg.getPropValue("repository")) } /** Gets the repository type. */ string getType() { result = this.getPropStringValue("type") } @@ -257,9 +260,9 @@ class RepositoryInfo extends JSONObject { /** * A representation of package dependencies for an NPM package. */ -class PackageDependencies extends JSONObject { +class PackageDependencies extends JsonObject { PackageDependencies() { - exists(PackageJSON pkg, string name | + exists(PackageJson pkg, string name | name.regexpMatch("(.+D|d)ependencies|engines") and this = pkg.getPropValue(name) ) @@ -272,11 +275,11 @@ class PackageDependencies extends JSONObject { /** * An NPM package. */ -class NPMPackage extends @folder { +class NpmPackage extends @folder { /** The `package.json` file of this package. */ - PackageJSON pkg; + PackageJson pkg; - NPMPackage() { pkg.getJsonFile().getParentContainer() = this } + NpmPackage() { pkg.getJsonFile().getParentContainer() = this } /** Gets a textual representation of this package. */ string toString() { result = this.(Folder).toString() } @@ -285,10 +288,13 @@ class NPMPackage extends @folder { string getPath() { result = this.(Folder).getAbsolutePath() } /** Gets the `package.json` object of this package. */ - PackageJSON getPackageJSON() { result = pkg } + PackageJson getPackageJson() { result = pkg } + + /** DEPRECATED: Alias for getPackageJson */ + deprecated PackageJSON getPackageJSON() { result = this.getPackageJson() } /** Gets the name of this package. */ - string getPackageName() { result = this.getPackageJSON().getPackageName() } + string getPackageName() { result = this.getPackageJson().getPackageName() } /** Gets the `node_modules` folder of this package. */ Folder getNodeModulesFolder() { @@ -325,6 +331,9 @@ class NPMPackage extends @folder { predicate declaresDependency(string p, string v) { pkg.declaresDependency(p, v) } } +/** DEPRECATED: Alias for NpmPackage */ +deprecated class NPMPackage = NpmPackage; + /** * Gets the parent folder of `c`, provided that they belong to the same NPM * package; that is, `c` must not be a `node_modules` folder. diff --git a/javascript/ql/lib/semmle/javascript/NodeModuleResolutionImpl.qll b/javascript/ql/lib/semmle/javascript/NodeModuleResolutionImpl.qll index cb2481861ee..6df85792a56 100644 --- a/javascript/ql/lib/semmle/javascript/NodeModuleResolutionImpl.qll +++ b/javascript/ql/lib/semmle/javascript/NodeModuleResolutionImpl.qll @@ -60,7 +60,7 @@ File loadAsFile(Require req, int rootPriority, int priority) { */ File loadAsDirectory(Require req, int rootPriority, int priority) { exists(Folder dir | dir = req.getImportedPath().resolve(rootPriority) | - result = resolveMainModule(dir.(NPMPackage).getPackageJSON(), priority) or + result = resolveMainModule(dir.(NpmPackage).getPackageJson(), priority) or result = tryExtensions(dir, "index", priority - (numberOfExtensions() + 1)) ) } @@ -90,7 +90,7 @@ private string getStem(string name) { result = name.regexpCapture("(.+?)(?:\\.([ /** * Gets the main module described by `pkg` with the given `priority`. */ -File resolveMainModule(PackageJSON pkg, int priority) { +File resolveMainModule(PackageJson pkg, int priority) { exists(PathExpr main | main = MainModulePath::of(pkg) | result = main.resolve() and priority = 0 or @@ -144,14 +144,17 @@ private string getASrcFolderName() { result = ["ts", "js", "src", "lib"] } * module of the package. */ class MainModulePath extends PathExpr, @json_string { - PackageJSON pkg; + PackageJson pkg; MainModulePath() { this = pkg.getPropValue(["main", "module"]) } /** Gets the `package.json` file in which this path occurs. */ - PackageJSON getPackageJSON() { result = pkg } + PackageJson getPackageJson() { result = pkg } - override string getValue() { result = this.(JSONString).getValue() } + /** DEPRECATED: Alias for getPackageJson */ + deprecated PackageJSON getPackageJSON() { result = getPackageJson() } + + override string getValue() { result = this.(JsonString).getValue() } override Folder getAdditionalSearchRoot(int priority) { priority = 0 and @@ -160,7 +163,7 @@ class MainModulePath extends PathExpr, @json_string { } module MainModulePath { - MainModulePath of(PackageJSON pkg) { result.getPackageJSON() = pkg } + MainModulePath of(PackageJson pkg) { result.getPackageJson() = pkg } } /** @@ -169,17 +172,20 @@ module MainModulePath { * For performance reasons this only exists if there is no "main" field in the `package.json` file. */ private class FilesPath extends PathExpr, @json_string { - PackageJSON pkg; + PackageJson pkg; FilesPath() { - this = pkg.getPropValue("files").(JSONArray).getElementValue(_) and + this = pkg.getPropValue("files").(JsonArray).getElementValue(_) and not exists(MainModulePath::of(pkg)) } /** Gets the `package.json` file in which this path occurs. */ - PackageJSON getPackageJSON() { result = pkg } + PackageJson getPackageJson() { result = pkg } - override string getValue() { result = this.(JSONString).getValue() } + /** DEPRECATED: Alias for getPackageJson */ + deprecated PackageJSON getPackageJSON() { result = getPackageJson() } + + override string getValue() { result = this.(JsonString).getValue() } override Folder getAdditionalSearchRoot(int priority) { priority = 0 and @@ -188,5 +194,5 @@ private class FilesPath extends PathExpr, @json_string { } private module FilesPath { - FilesPath of(PackageJSON pkg) { result.getPackageJSON() = pkg } + FilesPath of(PackageJson pkg) { result.getPackageJson() = pkg } } diff --git a/javascript/ql/lib/semmle/javascript/PackageExports.qll b/javascript/ql/lib/semmle/javascript/PackageExports.qll index 2895ad7232c..82bcb842859 100644 --- a/javascript/ql/lib/semmle/javascript/PackageExports.qll +++ b/javascript/ql/lib/semmle/javascript/PackageExports.qll @@ -52,7 +52,7 @@ private import NodeModuleResolutionImpl as NodeModule private DataFlow::Node getAValueExportedByPackage() { // The base case, an export from a named `package.json` file. result = - getAnExportFromModule(any(PackageJSON pack | exists(pack.getPackageName())).getMainModule()) + getAnExportFromModule(any(PackageJson pack | exists(pack.getPackageName())).getMainModule()) or // module.exports.bar.baz = result; exists(DataFlow::PropWrite write | @@ -133,7 +133,7 @@ private DataFlow::Node getAValueExportedByPackage() { DataFlow::globalVarRef("define").getACall().getArgument(1) = prev.getALocalUse() and func.getFile() = min(int j, File f | - f = NodeModule::resolveMainModule(any(PackageJSON pack | exists(pack.getPackageName())), j) + f = NodeModule::resolveMainModule(any(PackageJson pack | exists(pack.getPackageName())), j) | f order by j ) diff --git a/javascript/ql/lib/semmle/javascript/Paths.qll b/javascript/ql/lib/semmle/javascript/Paths.qll index 11904b3069e..e22d5ad6132 100644 --- a/javascript/ql/lib/semmle/javascript/Paths.qll +++ b/javascript/ql/lib/semmle/javascript/Paths.qll @@ -212,7 +212,7 @@ private module TypeScriptOutDir { * Gets a folder of TypeScript files that is compiled to JavaScript files in `outdir` relative to a `parent`. */ string getOriginalTypeScriptFolder(string outdir, Folder parent) { - exists(JSONObject tsconfig | + exists(JsonObject tsconfig | outdir = removeLeadingSlash(getOutDir(tsconfig, parent)) and result = removeLeadingSlash(getEffectiveRootDirFromTSConfig(tsconfig)) ) @@ -229,7 +229,7 @@ private module TypeScriptOutDir { /** * Gets the `outDir` option from a tsconfig file from the folder `parent`. */ - private string getOutDir(JSONObject tsconfig, Folder parent) { + private string getOutDir(JsonObject tsconfig, Folder parent) { tsconfig.getFile().getBaseName().regexpMatch("tsconfig.*\\.json") and tsconfig.isTopLevel() and tsconfig.getFile().getParentContainer() = parent and @@ -241,7 +241,7 @@ private module TypeScriptOutDir { * Based on the tsconfig.json file `tsconfig`. */ pragma[inline] - private string getEffectiveRootDirFromTSConfig(JSONObject tsconfig) { + private string getEffectiveRootDirFromTSConfig(JsonObject tsconfig) { // if an explicit "rootDir" option exists, then use that. result = getRootDir(tsconfig) or @@ -273,7 +273,7 @@ private module TypeScriptOutDir { * Can have multiple results if the includes are from multiple folders. */ pragma[inline] - private string getARootDirFromInclude(JSONObject tsconfig) { + private string getARootDirFromInclude(JsonObject tsconfig) { result = getRootFolderFromPath(tsconfig.getPropValue("include").getElementValue(_).getStringValue()) } @@ -282,7 +282,7 @@ private module TypeScriptOutDir { * Gets the value of the "rootDir" option from a tsconfig.json. */ pragma[inline] - private string getRootDir(JSONObject tsconfig) { + private string getRootDir(JsonObject tsconfig) { result = tsconfig.getPropValue("compilerOptions").getPropValue("rootDir").getStringValue() } } diff --git a/javascript/ql/lib/semmle/javascript/PrintAst.qll b/javascript/ql/lib/semmle/javascript/PrintAst.qll index 98abe183af1..f60b19ccb4e 100644 --- a/javascript/ql/lib/semmle/javascript/PrintAst.qll +++ b/javascript/ql/lib/semmle/javascript/PrintAst.qll @@ -54,26 +54,26 @@ private string getQlClass(Locatable el) { */ private newtype TPrintAstNode = // JavaScript / TypeScript - TElementNode(ASTNode el) { shouldPrint(el, _) and not isNotNeeded(el) } or + TElementNode(AstNode el) { shouldPrint(el, _) and not isNotNeeded(el) } or TParametersNode(Function f) { shouldPrint(f, _) and not isNotNeeded(f) } or TTypeParametersNode(TypeParameterized f) { shouldPrint(f, _) and not isNotNeeded(f) } or - TJSXAttributesNode(JSXElement n) { shouldPrint(n, _) and not isNotNeeded(n) } or - TJSXBodyElementsNode(JSXNode n) { shouldPrint(n, _) and not isNotNeeded(n) } or + TJsxAttributesNode(JsxElement n) { shouldPrint(n, _) and not isNotNeeded(n) } or + TJsxBodyElementsNode(JsxNode n) { shouldPrint(n, _) and not isNotNeeded(n) } or TInvokeArgumentsNode(InvokeExpr n) { shouldPrint(n, _) and not isNotNeeded(n) } or TInvokeTypeArgumentsNode(InvokeExpr invk) { shouldPrint(invk, _) and not isNotNeeded(invk) } or // JSON - TJSONNode(JSONValue value) { shouldPrint(value, _) and not isNotNeeded(value) } or + TJsonNode(JsonValue value) { shouldPrint(value, _) and not isNotNeeded(value) } or // YAML - TYAMLNode(YAMLNode n) { shouldPrint(n, _) and not isNotNeeded(n) } or - TYAMLMappingNode(YAMLMapping mapping, int i) { + TYamlNode(YAMLNode n) { shouldPrint(n, _) and not isNotNeeded(n) } or + TYamlMappingNode(YAMLMapping mapping, int i) { shouldPrint(mapping, _) and not isNotNeeded(mapping) and exists(mapping.getKeyNode(i)) } or // HTML - THTMLElementNode(HTML::Element e) { shouldPrint(e, _) and not isNotNeeded(e) } or - THTMLAttributesNodes(HTML::Element e) { shouldPrint(e, _) and not isNotNeeded(e) } or - THTMLAttributeNode(HTML::Attribute attr) { shouldPrint(attr, _) and not isNotNeeded(attr) } or - THTMLScript(Script script) { shouldPrint(script, _) and not isNotNeeded(script) } or - THTMLCodeInAttr(CodeInAttribute attr) { shouldPrint(attr, _) and not isNotNeeded(attr) } or + THtmlElementNode(HTML::Element e) { shouldPrint(e, _) and not isNotNeeded(e) } or + THtmlAttributesNodes(HTML::Element e) { shouldPrint(e, _) and not isNotNeeded(e) } or + THtmlAttributeNode(HTML::Attribute attr) { shouldPrint(attr, _) and not isNotNeeded(attr) } or + THtmlScript(Script script) { shouldPrint(script, _) and not isNotNeeded(script) } or + THtmlCodeInAttr(CodeInAttribute attr) { shouldPrint(attr, _) and not isNotNeeded(attr) } or TRegExpTermNode(RegExpTerm term) { shouldPrint(term, _) and term.isUsedAsRegExp() and @@ -168,7 +168,7 @@ private module PrintJavaScript { * For example by aggregating all the parameters of a function under a single child node. */ class ElementNode extends PrintAstNode, TElementNode { - ASTNode element; + AstNode element; ElementNode() { this = TElementNode(element) and @@ -183,10 +183,10 @@ private module PrintJavaScript { /** * Gets the `ASTNode` represented by this node. */ - final ASTNode getElement() { result = element } + final AstNode getElement() { result = element } override PrintAstNode getChild(int childIndex) { - exists(ASTNode el | result.(ElementNode).getElement() = el | + exists(AstNode el | result.(ElementNode).getElement() = el | el = this.getChildNode(childIndex) ) } @@ -195,16 +195,16 @@ private module PrintJavaScript { * Gets the `i`th child of `element`. * Can be overriden in subclasses to get more specific behavior for `getChild()`. */ - ASTNode getChildNode(int childIndex) { result = getLocationSortedChild(element, childIndex) } + AstNode getChildNode(int childIndex) { result = getLocationSortedChild(element, childIndex) } } - /** Provides predicates for pretty printing `ASTNode`s. */ + /** Provides predicates for pretty printing `AstNode`s. */ private module PrettyPrinting { /** * Gets a pretty string representation of `element`. * Either the result is `ASTNode::toString`, or a custom made string representation of `element`. */ - string print(ASTNode element) { + string print(AstNode element) { shouldPrint(element, _) and ( result = element.toString().regexpReplaceAll("(\\\\n|\\\\r|\\\\t| )+", " ") and @@ -217,7 +217,7 @@ private module PrintJavaScript { /** * Gets a string representing `a`. */ - private string repr(ASTNode a) { + private string repr(AstNode a) { shouldPrint(a, _) and ( exists(DeclStmt decl | decl = a | @@ -252,9 +252,9 @@ private module PrintJavaScript { } } - private ASTNode getLocationSortedChild(ASTNode parent, int i) { + private AstNode getLocationSortedChild(AstNode parent, int i) { result = - rank[i](ASTNode child, int childIndex | + rank[i](AstNode child, int childIndex | child = parent.getChild(childIndex) | child @@ -370,62 +370,77 @@ private module PrintJavaScript { * 2: An aggregate node for all the attributes (for example `href={foo}` in ``). * 3: An aggregate node for all the body element (for example `foo` in `foo`). */ - class JSXNodeNode extends ElementNode { - override JSXNode element; + class JsxNodeNode extends ElementNode { + override JsxNode element; override PrintAstNode getChild(int childIndex) { - childIndex = 0 and result.(ElementNode).getElement() = element.(JSXElement).getNameExpr() + childIndex = 0 and result.(ElementNode).getElement() = element.(JsxElement).getNameExpr() or childIndex = 1 and exists(element.getABodyElement()) and - result.(JSXBodyElementsNode).getJSXNode() = element + result.(JsxBodyElementsNode).getJsxNode() = element or childIndex = 2 and - exists(element.(JSXElement).getAttribute(_)) and - result.(JSXAttributesNode).getJSXElement() = element + exists(element.(JsxElement).getAttribute(_)) and + result.(JsxAttributesNode).getJsxElement() = element } } + /** DEPRECATED: Alias for JsxNodeNode */ + deprecated class JSXNodeNode = JsxNodeNode; + /** * An aggregate node representing all the attributes in a `JSXNode`. */ - class JSXAttributesNode extends PrintAstNode, TJSXAttributesNode { - JSXElement n; + class JsxAttributesNode extends PrintAstNode, TJsxAttributesNode { + JsxElement n; - JSXAttributesNode() { this = TJSXAttributesNode(n) and exists(n.getAttribute(_)) } + JsxAttributesNode() { this = TJsxAttributesNode(n) and exists(n.getAttribute(_)) } override string toString() { result = "(Attributes)" } /** * Gets the `JSXElement` for which this node represents the attributes. */ - JSXElement getJSXElement() { result = n } + JsxElement getJsxElement() { result = n } + + /** DEPRECATED: Alias for getJsxElement */ + deprecated JSXElement getJSXElement() { result = this.getJsxElement() } override PrintAstNode getChild(int childIndex) { result.(ElementNode).getElement() = n.getAttribute(childIndex) } } + /** DEPRECATED: Alias for JsxAttributesNode */ + deprecated class JSXAttributesNode = JsxAttributesNode; + /** * An aggregate node representing all the body elements in a `JSXNode`. */ - class JSXBodyElementsNode extends PrintAstNode, TJSXBodyElementsNode { - JSXNode n; + class JsxBodyElementsNode extends PrintAstNode, TJsxBodyElementsNode { + JsxNode n; - JSXBodyElementsNode() { this = TJSXBodyElementsNode(n) and exists(n.getBodyElement(_)) } + JsxBodyElementsNode() { this = TJsxBodyElementsNode(n) and exists(n.getBodyElement(_)) } override string toString() { result = "(Body)" } /** * Gets the `JSXNode` for which this node represents the body elements. */ - JSXNode getJSXNode() { result = n } + JsxNode getJsxNode() { result = n } + + /** DEPRECATED: Alias for getJsxNode */ + deprecated JSXNode getJSXNode() { result = this.getJsxNode() } override PrintAstNode getChild(int childIndex) { result.(ElementNode).getElement() = n.getBodyElement(childIndex) } } + /** DEPRECATED: Alias for JsxBodyElementsNode */ + deprecated class JSXBodyElementsNode = JsxBodyElementsNode; + /** * A node representing any `ASTNode` that has type-parameters. * @@ -484,7 +499,7 @@ private module PrintJavaScript { class ParameterNode extends ElementNode { override Parameter element; - override ASTNode getChildNode(int childIndex) { + override AstNode getChildNode(int childIndex) { childIndex = 0 and result = element.getTypeAnnotation() or childIndex = 1 and result = element.getDefault() @@ -535,14 +550,14 @@ private module PrintJavaScript { /** * Classes for printing JSON AST. */ -private module PrintJSON { +private module PrintJson { /** * A print node representing a JSON value in a .json file. */ - class JSONNode extends PrintAstNode, TJSONNode { - JSONValue value; + class JsonNode extends PrintAstNode, TJsonNode { + JsonValue value; - JSONNode() { this = TJSONNode(value) } + JsonNode() { this = TJsonNode(value) } override string toString() { result = getQlClass(value) + PrettyPrinting::print(value) } @@ -551,22 +566,25 @@ private module PrintJSON { /** * Gets the `JSONValue` represented by this node. */ - final JSONValue getValue() { result = value } + final JsonValue getValue() { result = value } override PrintAstNode getChild(int childIndex) { - exists(JSONValue child | result.(JSONNode).getValue() = child | + exists(JsonValue child | result.(JsonNode).getValue() = child | child = value.getChild(childIndex) ) } } + /** DEPRECATED: Alias for JsonNode */ + deprecated class JSONNode = JsonNode; + /** Provied predicates for pretty printing JSON. */ private module PrettyPrinting { /** * Gets a string representation of `n`. * Either using the default `JSONValue::toString`, or a custom printing of the JSON value. */ - string print(JSONValue n) { + string print(JsonValue n) { shouldPrint(n, _) and ( result = n.toString().regexpReplaceAll("(\\\\n|\\\\r|\\\\t| )+", " ") and @@ -577,20 +595,20 @@ private module PrintJSON { } /** Gets a string representing `n`. */ - private string repr(JSONValue n) { + private string repr(JsonValue n) { shouldPrint(n, _) and ( - exists(JSONObject obj, string name, JSONValue prop | obj = n | + exists(JsonObject obj, string name, JsonValue prop | obj = n | prop = obj.getPropValue(name) and prop = obj.getChild(0) and result = "{" + name + ": ...}" ) or - n instanceof JSONObject and not exists(n.getChild(_)) and result = "{}" + n instanceof JsonObject and not exists(n.getChild(_)) and result = "{}" or - result = n.(JSONPrimitiveValue).getRawValue() + result = n.(JsonPrimitiveValue).getRawValue() or - exists(JSONArray arr | arr = n | + exists(JsonArray arr | arr = n | result = "[]" and not exists(arr.getChild(_)) or result = "[" + repr(arr.getChild(0)) + "]" and not exists(arr.getChild(1)) @@ -605,14 +623,14 @@ private module PrintJSON { /** * Classes for printing YAML AST. */ -module PrintYAML { +module PrintYaml { /** * A print node representing a YAML value in a .yml file. */ - class YAMLNodeNode extends PrintAstNode, TYAMLNode { + class YamlNodeNode extends PrintAstNode, TYamlNode { YAMLNode node; - YAMLNodeNode() { this = TYAMLNode(node) } + YamlNodeNode() { this = TYamlNode(node) } override string toString() { result = getQlClass(node) + node.toString() } @@ -624,33 +642,39 @@ module PrintYAML { final YAMLNode getValue() { result = node } override PrintAstNode getChild(int childIndex) { - exists(YAMLNode child | result.(YAMLNodeNode).getValue() = child | + exists(YAMLNode child | result.(YamlNodeNode).getValue() = child | child = node.getChildNode(childIndex) ) } } + /** DEPRECATED: Alias for YamlNodeNode */ + deprecated class YAMLNodeNode = YamlNodeNode; + /** * A print node representing a `YAMLMapping`. * * Each child of this node aggregates the key and value of a mapping. */ - class YAMLMappingNode extends YAMLNodeNode { + class YamlMappingNode extends YamlNodeNode { override YAMLMapping node; override PrintAstNode getChild(int childIndex) { - exists(YAMLMappingMapNode map | map = result | map.maps(node, childIndex)) + exists(YamlMappingMapNode map | map = result | map.maps(node, childIndex)) } } + /** DEPRECATED: Alias for YamlMappingNode */ + deprecated class YAMLMappingNode = YamlMappingNode; + /** * A print node representing the `i`th mapping in `mapping`. */ - class YAMLMappingMapNode extends PrintAstNode, TYAMLMappingNode { + class YamlMappingMapNode extends PrintAstNode, TYamlMappingNode { YAMLMapping mapping; int i; - YAMLMappingMapNode() { this = TYAMLMappingNode(mapping, i) } + YamlMappingMapNode() { this = TYamlMappingNode(mapping, i) } override string toString() { result = "(Mapping " + i + ")" and not exists(mapping.getKeyNode(i).(YAMLScalar).getValue()) @@ -667,24 +691,30 @@ module PrintYAML { } override PrintAstNode getChild(int childIndex) { - childIndex = 0 and result.(YAMLNodeNode).getValue() = mapping.getKeyNode(i) + childIndex = 0 and result.(YamlNodeNode).getValue() = mapping.getKeyNode(i) or - childIndex = 1 and result.(YAMLNodeNode).getValue() = mapping.getValueNode(i) + childIndex = 1 and result.(YamlNodeNode).getValue() = mapping.getValueNode(i) } } + + /** DEPRECATED: Alias for YamlMappingMapNode */ + deprecated class YAMLMappingMapNode = YamlMappingMapNode; } +/** DEPRECATED: Alias for PrintYaml */ +deprecated module PrintYAML = PrintYaml; + /** * Classes for printing HTML AST. */ -module PrintHTML { +module PrintHtml { /** * A print node representing an HTML node in a .html file. */ - class HTMLElementNode extends PrintAstNode, THTMLElementNode { + class HtmlElementNode extends PrintAstNode, THtmlElementNode { HTML::Element element; - HTMLElementNode() { this = THTMLElementNode(element) } + HtmlElementNode() { this = THtmlElementNode(element) } override string toString() { result = getQlClass(element) + "<" + element.getName() + " ..." } @@ -696,36 +726,42 @@ module PrintHTML { final HTML::Element getElement() { result = element } override PrintAstNode getChild(int childIndex) { - childIndex = -1 and result.(HTMLAttributesNodes).getElement() = element + childIndex = -1 and result.(HtmlAttributesNodes).getElement() = element or - exists(HTML::Element child | result.(HTMLElementNode).getElement() = child | + exists(HTML::Element child | result.(HtmlElementNode).getElement() = child | child = element.getChild(childIndex) ) } } + /** DEPRECATED: Alias for HtmlElementNode */ + deprecated class HTMLElementNode = HtmlElementNode; + /** * A print node representing an HTML node in a .html file. */ - class HTMLScriptElementNode extends HTMLElementNode { + class HtmlScriptElementNode extends HtmlElementNode { override HTML::ScriptElement element; override PrintAstNode getChild(int childIndex) { - childIndex = -200 and result.(HTMLScript).getScript() = element.getScript() + childIndex = -200 and result.(HtmlScript).getScript() = element.getScript() or result = super.getChild(childIndex) } } + /** DEPRECATED: Alias for HtmlScriptElementNode */ + deprecated class HTMLScriptElementNode = HtmlScriptElementNode; + /** * A print node representing the code inside a `