From 39c52c9ecfaae715e1548c228b63ea34c481b346 Mon Sep 17 00:00:00 2001 From: Chad Bentz <1760475+felickz@users.noreply.github.com> Date: Thu, 16 Mar 2023 11:27:23 -0400 Subject: [PATCH 001/238] add security-severity to code scanning query list --- misc/scripts/generate-code-scanning-query-list.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/misc/scripts/generate-code-scanning-query-list.py b/misc/scripts/generate-code-scanning-query-list.py index 606bdf91c559..531e125951e9 100644 --- a/misc/scripts/generate-code-scanning-query-list.py +++ b/misc/scripts/generate-code-scanning-query-list.py @@ -159,7 +159,7 @@ def subprocess_run(cmd): csvwriter = csv.writer(sys.stdout) csvwriter.writerow([ "Query filename", "Suite", "Query name", "Query ID", - "Kind", "Severity", "Precision", "Tags" + "Kind", "Severity", "Security score", "Precision", "Tags" ]) # Iterate over all languages and packs, and resolve which queries are part of those packs @@ -197,6 +197,7 @@ def subprocess_run(cmd): get_query_metadata('id', meta, queryfile_nwo), get_query_metadata('kind', meta, queryfile_nwo), get_query_metadata('problem.severity', meta, queryfile_nwo), + get_query_metadata('security-severity', meta, queryfile_nwo), get_query_metadata('precision', meta, queryfile_nwo), get_query_metadata('tags', meta, queryfile_nwo) ]) From ee3085e15eb368d2a60f8dee779071156ef4d422 Mon Sep 17 00:00:00 2001 From: Chad Bentz <1760475+felickz@users.noreply.github.com> Date: Thu, 14 Dec 2023 14:09:14 -0500 Subject: [PATCH 002/238] Update generate-code-scanning-query-list.py --- misc/scripts/generate-code-scanning-query-list.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/scripts/generate-code-scanning-query-list.py b/misc/scripts/generate-code-scanning-query-list.py index 531e125951e9..55437feb3b74 100644 --- a/misc/scripts/generate-code-scanning-query-list.py +++ b/misc/scripts/generate-code-scanning-query-list.py @@ -8,7 +8,7 @@ """ This script collects CodeQL queries that are part of code scanning query packs -and prints CSV data to stdout that describes which packs contain which queries. +and prints CSV data to stdout that describes which suites in the pack contain which queries. Errors are printed to stderr. This script requires that 'git' and 'codeql' commands are on the PATH. It'll try to automatically set the CodeQL search path correctly, From 0515b12305c844e0ce1d5dcd8e03eb62e4350b5c Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Mon, 25 Mar 2024 11:36:21 +0100 Subject: [PATCH 003/238] JS: Add example of bad NodeJS detection Notice the TRAP lines ``` is_module(#20001) is_es2015_module(#20001) ``` --- .../extractor/tests/node/input/detection.js | 6 + .../tests/node/output/trap/detection.js.trap | 203 ++++++++++++++++++ 2 files changed, 209 insertions(+) create mode 100644 javascript/extractor/tests/node/input/detection.js create mode 100644 javascript/extractor/tests/node/output/trap/detection.js.trap diff --git a/javascript/extractor/tests/node/input/detection.js b/javascript/extractor/tests/node/input/detection.js new file mode 100644 index 000000000000..7c182f394f2a --- /dev/null +++ b/javascript/extractor/tests/node/input/detection.js @@ -0,0 +1,6 @@ +// the comment below (with 'import' on line starting with whitespace) caused the +// extractor to think it was a es2015 module and not a commonjs module. +/* + import +*/ +const fs = require('fs'); diff --git a/javascript/extractor/tests/node/output/trap/detection.js.trap b/javascript/extractor/tests/node/output/trap/detection.js.trap new file mode 100644 index 000000000000..1da6b26f89cd --- /dev/null +++ b/javascript/extractor/tests/node/output/trap/detection.js.trap @@ -0,0 +1,203 @@ +#10000=@"/detection.js;sourcefile" +files(#10000,"/detection.js") +#10001=@"/;folder" +folders(#10001,"/") +containerparent(#10001,#10000) +#10002=@"loc,{#10000},0,0,0,0" +locations_default(#10002,#10000,0,0,0,0) +hasLocation(#10000,#10002) +#20000=@"global_scope" +scopes(#20000,0) +#20001=@"script;{#10000},1,1" +#20002=* +comments(#20002,0,#20001," the comment below (with 'import' on line starting with whitespace) caused the","// the ... sed the") +#20003=@"loc,{#10000},1,1,1,80" +locations_default(#20003,#10000,1,1,1,80) +hasLocation(#20002,#20003) +#20004=* +comments(#20004,0,#20001," extractor to think it was a es2015 module and not a commonjs module.","// extr ... module.") +#20005=@"loc,{#10000},2,1,2,71" +locations_default(#20005,#10000,2,1,2,71) +hasLocation(#20004,#20005) +#20006=* +comments(#20006,1,#20001," + import +","/*\n import\n*/") +#20007=@"loc,{#10000},3,1,5,2" +locations_default(#20007,#10000,3,1,5,2) +hasLocation(#20006,#20007) +#20008=* +lines(#20008,#20001,"// the comment below (with 'import' on line starting with whitespace) caused the"," +") +hasLocation(#20008,#20003) +#20009=* +lines(#20009,#20001,"// extractor to think it was a es2015 module and not a commonjs module."," +") +hasLocation(#20009,#20005) +#20010=* +lines(#20010,#20001,"/*"," +") +#20011=@"loc,{#10000},3,1,3,2" +locations_default(#20011,#10000,3,1,3,2) +hasLocation(#20010,#20011) +#20012=* +lines(#20012,#20001," import"," +") +#20013=@"loc,{#10000},4,1,4,8" +locations_default(#20013,#10000,4,1,4,8) +hasLocation(#20012,#20013) +indentation(#10000,4," ",2) +#20014=* +lines(#20014,#20001,"*/"," +") +#20015=@"loc,{#10000},5,1,5,2" +locations_default(#20015,#10000,5,1,5,2) +hasLocation(#20014,#20015) +#20016=* +lines(#20016,#20001,"const fs = require('fs');"," +") +#20017=@"loc,{#10000},6,1,6,25" +locations_default(#20017,#10000,6,1,6,25) +hasLocation(#20016,#20017) +numlines(#20001,6,1,5) +#20018=* +tokeninfo(#20018,7,#20001,0,"const") +#20019=@"loc,{#10000},6,1,6,5" +locations_default(#20019,#10000,6,1,6,5) +hasLocation(#20018,#20019) +next_token(#20002,#20018) +next_token(#20004,#20018) +next_token(#20006,#20018) +#20020=* +tokeninfo(#20020,6,#20001,1,"fs") +#20021=@"loc,{#10000},6,7,6,8" +locations_default(#20021,#10000,6,7,6,8) +hasLocation(#20020,#20021) +#20022=* +tokeninfo(#20022,8,#20001,2,"=") +#20023=@"loc,{#10000},6,10,6,10" +locations_default(#20023,#10000,6,10,6,10) +hasLocation(#20022,#20023) +#20024=* +tokeninfo(#20024,6,#20001,3,"require") +#20025=@"loc,{#10000},6,12,6,18" +locations_default(#20025,#10000,6,12,6,18) +hasLocation(#20024,#20025) +#20026=* +tokeninfo(#20026,8,#20001,4,"(") +#20027=@"loc,{#10000},6,19,6,19" +locations_default(#20027,#10000,6,19,6,19) +hasLocation(#20026,#20027) +#20028=* +tokeninfo(#20028,4,#20001,5,"'fs'") +#20029=@"loc,{#10000},6,20,6,23" +locations_default(#20029,#10000,6,20,6,23) +hasLocation(#20028,#20029) +#20030=* +tokeninfo(#20030,8,#20001,6,")") +#20031=@"loc,{#10000},6,24,6,24" +locations_default(#20031,#10000,6,24,6,24) +hasLocation(#20030,#20031) +#20032=* +tokeninfo(#20032,8,#20001,7,";") +#20033=@"loc,{#10000},6,25,6,25" +locations_default(#20033,#10000,6,25,6,25) +hasLocation(#20032,#20033) +#20034=* +tokeninfo(#20034,0,#20001,8,"") +#20035=@"loc,{#10000},7,1,7,0" +locations_default(#20035,#10000,7,1,7,0) +hasLocation(#20034,#20035) +toplevels(#20001,0) +#20036=@"loc,{#10000},1,1,7,0" +locations_default(#20036,#10000,1,1,7,0) +hasLocation(#20001,#20036) +#20037=@"var;{global};{#20000}" +variables(#20037,"global",#20000) +#20038=@"var;{process};{#20000}" +variables(#20038,"process",#20000) +#20039=@"var;{console};{#20000}" +variables(#20039,"console",#20000) +#20040=@"var;{Buffer};{#20000}" +variables(#20040,"Buffer",#20000) +#20041=@"module;{#10000},1,1" +scopes(#20041,3) +scopenodes(#20001,#20041) +scopenesting(#20041,#20000) +#20042=@"var;{require};{#20041}" +variables(#20042,"require",#20041) +#20043=@"var;{module};{#20041}" +variables(#20043,"module",#20041) +#20044=@"var;{exports};{#20041}" +variables(#20044,"exports",#20041) +#20045=@"var;{__filename};{#20041}" +variables(#20045,"__filename",#20041) +#20046=@"var;{__dirname};{#20041}" +variables(#20046,"__dirname",#20041) +#20047=@"var;{arguments};{#20041}" +variables(#20047,"arguments",#20041) +is_module(#20001) +is_es2015_module(#20001) +#20048=@"var;{fs};{#20041}" +variables(#20048,"fs",#20041) +#20049=* +stmts(#20049,22,#20001,0,"const f ... ('fs');") +hasLocation(#20049,#20017) +stmt_containers(#20049,#20001) +#20050=* +exprs(#20050,64,#20049,0,"fs = require('fs')") +#20051=@"loc,{#10000},6,7,6,24" +locations_default(#20051,#10000,6,7,6,24) +hasLocation(#20050,#20051) +enclosing_stmt(#20050,#20049) +expr_containers(#20050,#20001) +#20052=* +exprs(#20052,78,#20050,0,"fs") +hasLocation(#20052,#20021) +enclosing_stmt(#20052,#20049) +expr_containers(#20052,#20001) +literals("fs","fs",#20052) +decl(#20052,#20048) +#20053=* +exprs(#20053,13,#20050,1,"require('fs')") +#20054=@"loc,{#10000},6,12,6,24" +locations_default(#20054,#10000,6,12,6,24) +hasLocation(#20053,#20054) +enclosing_stmt(#20053,#20049) +expr_containers(#20053,#20001) +#20055=* +exprs(#20055,79,#20053,-1,"require") +hasLocation(#20055,#20025) +enclosing_stmt(#20055,#20049) +expr_containers(#20055,#20001) +literals("require","require",#20055) +bind(#20055,#20042) +#20056=* +exprs(#20056,4,#20053,0,"'fs'") +hasLocation(#20056,#20029) +enclosing_stmt(#20056,#20049) +expr_containers(#20056,#20001) +literals("fs","'fs'",#20056) +#20057=* +regexpterm(#20057,14,#20056,0,"fs") +#20058=@"loc,{#10000},6,21,6,22" +locations_default(#20058,#10000,6,21,6,22) +hasLocation(#20057,#20058) +regexp_const_value(#20057,"fs") +#20059=* +entry_cfg_node(#20059,#20001) +#20060=@"loc,{#10000},1,1,1,0" +locations_default(#20060,#10000,1,1,1,0) +hasLocation(#20059,#20060) +#20061=* +exit_cfg_node(#20061,#20001) +hasLocation(#20061,#20035) +successor(#20049,#20052) +successor(#20056,#20053) +successor(#20055,#20056) +successor(#20053,#20050) +successor(#20052,#20055) +successor(#20050,#20061) +successor(#20059,#20049) +numlines(#10000,6,1,5) +filetype(#10000,"javascript") From cd84500c567e5c7b4cb4cfd7672f5270813cdd3e Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Tue, 26 Mar 2024 16:55:14 +0100 Subject: [PATCH 004/238] JS: Extractor: Separate base detector logic into own file Should hopefully make it easier to review these changes to have it split into its' own commit :) --- .../semmle/js/extractor/AbstractDetector.java | 113 ++++++++++++++++ .../semmle/js/extractor/NodeJSDetector.java | 124 +----------------- 2 files changed, 120 insertions(+), 117 deletions(-) create mode 100644 javascript/extractor/src/com/semmle/js/extractor/AbstractDetector.java diff --git a/javascript/extractor/src/com/semmle/js/extractor/AbstractDetector.java b/javascript/extractor/src/com/semmle/js/extractor/AbstractDetector.java new file mode 100644 index 000000000000..b8a5f1df0fcf --- /dev/null +++ b/javascript/extractor/src/com/semmle/js/extractor/AbstractDetector.java @@ -0,0 +1,113 @@ +package com.semmle.js.extractor; + +import com.semmle.js.ast.AssignmentExpression; +import com.semmle.js.ast.BlockStatement; +import com.semmle.js.ast.CallExpression; +import com.semmle.js.ast.Expression; +import com.semmle.js.ast.ExpressionStatement; +import com.semmle.js.ast.IFunction; +import com.semmle.js.ast.Identifier; +import com.semmle.js.ast.IfStatement; +import com.semmle.js.ast.MemberExpression; +import com.semmle.js.ast.Node; +import com.semmle.js.ast.ParenthesizedExpression; +import com.semmle.js.ast.Program; +import com.semmle.js.ast.Statement; +import com.semmle.js.ast.TryStatement; +import com.semmle.js.ast.UnaryExpression; +import com.semmle.js.ast.VariableDeclaration; +import com.semmle.js.ast.VariableDeclarator; +import java.util.List; + +/** + * A utility base class for running detection logic on statements/expressions by + * visiting each node. It performs recursive decent into assignment expressions and + * callee expressions for call-expressions (to handle detection of `foo` in `foo()()`) + * */ +public abstract class AbstractDetector { + protected boolean programDetection(Node ast) { + if (!(ast instanceof Program)) return false; + + return visitStatements(((Program) ast).getBody()); + } + + protected boolean visitStatements(List stmts) { + for (Statement stmt : stmts) if (visitStatement(stmt)) return true; + return false; + } + + protected boolean visitStatement(Statement stmt) { + if (stmt instanceof ExpressionStatement) { + Expression e = stripParens(((ExpressionStatement) stmt).getExpression()); + + // check whether `e` is an iife; if so, recursively check its body + + // strip off unary operators to handle `!function(){...}()` + if (e instanceof UnaryExpression) e = ((UnaryExpression) e).getArgument(); + + if (e instanceof CallExpression && ((CallExpression) e).getArguments().isEmpty()) { + Expression callee = stripParens(((CallExpression) e).getCallee()); + if (callee instanceof IFunction) { + Node body = ((IFunction) callee).getBody(); + if (body instanceof BlockStatement) + return visitStatements(((BlockStatement) body).getBody()); + } + } + + if (visitExpression(e)) return true; + + } else if (stmt instanceof VariableDeclaration) { + for (VariableDeclarator decl : ((VariableDeclaration) stmt).getDeclarations()) { + Expression init = stripParens(decl.getInit()); + if (visitExpression(init)) return true; + } + + } else if (stmt instanceof TryStatement) { + return visitStatement(((TryStatement) stmt).getBlock()); + + } else if (stmt instanceof BlockStatement) { + return visitStatements(((BlockStatement) stmt).getBody()); + + } else if (stmt instanceof IfStatement) { + IfStatement is = (IfStatement) stmt; + return visitStatement(is.getConsequent()) + || visitStatement(is.getAlternate()); + } + + return false; + } + + private static Expression stripParens(Expression e) { + if (e instanceof ParenthesizedExpression) + return stripParens(((ParenthesizedExpression) e).getExpression()); + return e; + } + + /** + * Recursively check {@code e} if it's a call or an assignment. + */ + protected boolean visitExpression(Expression e) { + if (e instanceof CallExpression) { + CallExpression call = (CallExpression) e; + Expression callee = call.getCallee(); + // recurse, to handle things like `foo()()` + if (visitExpression(callee)) return true; + return false; + } else if (e instanceof MemberExpression) { + return visitExpression(((MemberExpression) e).getObject()); + } else if (e instanceof AssignmentExpression) { + AssignmentExpression assgn = (AssignmentExpression) e; + + // filter out compound assignments + if (!"=".equals(assgn.getOperator())) return false; + + return visitExpression(assgn.getRight()); + } + return false; + } + + /** Is {@code e} an identifier with name {@code name}? */ + protected static boolean isIdentifier(Expression e, String name) { + return e instanceof Identifier && name.equals(((Identifier) e).getName()); + } +} diff --git a/javascript/extractor/src/com/semmle/js/extractor/NodeJSDetector.java b/javascript/extractor/src/com/semmle/js/extractor/NodeJSDetector.java index d848afd0d87a..a9fa2c9d8500 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/NodeJSDetector.java +++ b/javascript/extractor/src/com/semmle/js/extractor/NodeJSDetector.java @@ -1,132 +1,30 @@ package com.semmle.js.extractor; import com.semmle.js.ast.AssignmentExpression; -import com.semmle.js.ast.BlockStatement; import com.semmle.js.ast.CallExpression; import com.semmle.js.ast.Expression; -import com.semmle.js.ast.ExpressionStatement; -import com.semmle.js.ast.IFunction; -import com.semmle.js.ast.Identifier; -import com.semmle.js.ast.IfStatement; import com.semmle.js.ast.MemberExpression; import com.semmle.js.ast.Node; -import com.semmle.js.ast.ParenthesizedExpression; -import com.semmle.js.ast.Program; -import com.semmle.js.ast.Statement; -import com.semmle.js.ast.TryStatement; -import com.semmle.js.ast.UnaryExpression; -import com.semmle.js.ast.VariableDeclaration; -import com.semmle.js.ast.VariableDeclarator; -import java.util.List; /** A utility class for detecting Node.js code. */ -public class NodeJSDetector { +public class NodeJSDetector extends AbstractDetector { /** * Is {@code ast} a program that looks like Node.js code, that is, does it contain a top-level - * {@code require} or an export? + * {@code require} or an {@code module.exports = ...}/{@code exports = ...}? */ public static boolean looksLikeNodeJS(Node ast) { - if (!(ast instanceof Program)) return false; - - return hasToplevelRequireOrExport(((Program) ast).getBody()); - } - - /** - * Does this program contain a statement that looks like a Node.js {@code require} or an export? - * - *

We recursively traverse argument-less immediately invoked function expressions (i.e., no UMD - * modules), but not loops or if statements. - */ - private static boolean hasToplevelRequireOrExport(List stmts) { - for (Statement stmt : stmts) if (hasToplevelRequireOrExport(stmt)) return true; - return false; + return new NodeJSDetector().programDetection(ast); } - private static boolean hasToplevelRequireOrExport(Statement stmt) { - if (stmt instanceof ExpressionStatement) { - Expression e = stripParens(((ExpressionStatement) stmt).getExpression()); - - // check whether `e` is an iife; if so, recursively check its body - - // strip off unary operators to handle `!function(){...}()` - if (e instanceof UnaryExpression) e = ((UnaryExpression) e).getArgument(); - - if (e instanceof CallExpression && ((CallExpression) e).getArguments().isEmpty()) { - Expression callee = stripParens(((CallExpression) e).getCallee()); - if (callee instanceof IFunction) { - Node body = ((IFunction) callee).getBody(); - if (body instanceof BlockStatement) - return hasToplevelRequireOrExport(((BlockStatement) body).getBody()); - } - } - - if (isRequireCall(e) || isExport(e)) return true; - - } else if (stmt instanceof VariableDeclaration) { - for (VariableDeclarator decl : ((VariableDeclaration) stmt).getDeclarations()) { - Expression init = stripParens(decl.getInit()); - if (isRequireCall(init) || isExport(init)) return true; - } - - } else if (stmt instanceof TryStatement) { - return hasToplevelRequireOrExport(((TryStatement) stmt).getBlock()); - - } else if (stmt instanceof BlockStatement) { - return hasToplevelRequireOrExport(((BlockStatement) stmt).getBody()); - - } else if (stmt instanceof IfStatement) { - IfStatement is = (IfStatement) stmt; - return hasToplevelRequireOrExport(is.getConsequent()) - || hasToplevelRequireOrExport(is.getAlternate()); - } - - return false; - } - - private static Expression stripParens(Expression e) { - if (e instanceof ParenthesizedExpression) - return stripParens(((ParenthesizedExpression) e).getExpression()); - return e; - } - - /** - * Is {@code e} a call to a function named {@code require} with one argument, or an assignment - * whose right hand side is the result of such a call? - */ - private static boolean isRequireCall(Expression e) { + @Override + protected boolean visitExpression(Expression e) { + // require('...') if (e instanceof CallExpression) { CallExpression call = (CallExpression) e; Expression callee = call.getCallee(); if (isIdentifier(callee, "require") && call.getArguments().size() == 1) return true; - if (isRequireCall(callee)) return true; - return false; - } else if (e instanceof MemberExpression) { - return isRequireCall(((MemberExpression) e).getObject()); - } else if (e instanceof AssignmentExpression) { - AssignmentExpression assgn = (AssignmentExpression) e; - - // filter out compound assignments - if (!"=".equals(assgn.getOperator())) return false; - - return isRequireCall(assgn.getRight()); } - return false; - } - /** - * Does {@code e} look like a Node.js export? - * - *

Currently, three kinds of exports are recognised: - * - *

    - *
  • exports.foo = ... - *
  • module.exports = ... - *
  • module.exports.foo = ... - *
- * - * Detection is done recursively, so foo = exports.foo = ... is handled correctly. - */ - private static boolean isExport(Expression e) { if (e instanceof AssignmentExpression) { AssignmentExpression assgn = (AssignmentExpression) e; @@ -149,12 +47,9 @@ private static boolean isExport(Expression e) { if (isModuleExports(targetBase)) return true; } } - - // recursively check right hand side - return isExport(assgn.getRight()); } - return false; + return super.visitExpression(e); } /** Is {@code me} a member expression {@code module.exports}? */ @@ -163,9 +58,4 @@ private static boolean isModuleExports(MemberExpression me) { && isIdentifier(me.getObject(), "module") && isIdentifier(me.getProperty(), "exports"); } - - /** Is {@code e} an identifier with name {@code name}? */ - private static boolean isIdentifier(Expression e, String name) { - return e instanceof Identifier && name.equals(((Identifier) e).getName()); - } } From 04a0740ccb693782703430faa098d39ef9a15031 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Mon, 25 Mar 2024 13:17:15 +0100 Subject: [PATCH 005/238] JS: Extractor: More robust ES2015 checking Created shared AbstractDetector to not duplicate all the tedious logic ;) I took inspiration from the tests in `javascript/extractor/tests/esnext/input/dynamic-import.js` --- .../semmle/js/extractor/ES2015Detector.java | 34 +++++++++++ .../com/semmle/js/extractor/JSExtractor.java | 20 +++++++ .../semmle/js/extractor/test/AllTests.java | 1 + .../extractor/test/ES2015DetectorTests.java | 58 +++++++++++++++++++ .../tests/node/output/trap/detection.js.trap | 2 +- 5 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 javascript/extractor/src/com/semmle/js/extractor/ES2015Detector.java create mode 100644 javascript/extractor/test/com/semmle/js/extractor/test/ES2015DetectorTests.java diff --git a/javascript/extractor/src/com/semmle/js/extractor/ES2015Detector.java b/javascript/extractor/src/com/semmle/js/extractor/ES2015Detector.java new file mode 100644 index 000000000000..3ba63963dabe --- /dev/null +++ b/javascript/extractor/src/com/semmle/js/extractor/ES2015Detector.java @@ -0,0 +1,34 @@ +package com.semmle.js.extractor; + +import com.semmle.js.ast.DynamicImport; +import com.semmle.js.ast.ExportDeclaration; +import com.semmle.js.ast.Expression; +import com.semmle.js.ast.ImportDeclaration; +import com.semmle.js.ast.Node; +import com.semmle.js.ast.Statement; + +/** A utility class for detecting Node.js code. */ +public class ES2015Detector extends AbstractDetector { + /** + * Is {@code ast} a program that uses ES2015 import/export code? + */ + public static boolean looksLikeES2015(Node ast) { + return new ES2015Detector().programDetection(ast); + } + + @Override + protected boolean visitStatement(Statement stmt) { + if (stmt instanceof ImportDeclaration || stmt instanceof ExportDeclaration) { + return true; + } + return super.visitStatement(stmt); + } + + @Override + protected boolean visitExpression(Expression e) { + if (e instanceof DynamicImport) { + return true; + } + return super.visitExpression(e); + } +} diff --git a/javascript/extractor/src/com/semmle/js/extractor/JSExtractor.java b/javascript/extractor/src/com/semmle/js/extractor/JSExtractor.java index 6b4b05fcf616..a8e20fdc0d90 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/JSExtractor.java +++ b/javascript/extractor/src/com/semmle/js/extractor/JSExtractor.java @@ -58,6 +58,26 @@ public Pair extract( JSParser.Result parserRes = JSParser.parse(config, sourceType, source, textualExtractor.getMetrics()); + + // Check if we guessed wrong with the regex in `establishSourceType`, (which could + // happen due to a block-comment line starting with ' import'). + if (config.getSourceType() == SourceType.AUTO && sourceType != SourceType.SCRIPT) { + boolean wrongGuess = false; + + if (sourceType == SourceType.MODULE) { + // check that we did see an import/export declaration + wrongGuess = ES2015Detector.looksLikeES2015(parserRes.getAST()) == false; + } else if (sourceType == SourceType.CLOSURE_MODULE ) { + // TODO + } + + if (wrongGuess) { + sourceType = SourceType.SCRIPT; + parserRes = + JSParser.parse(config, sourceType, source, textualExtractor.getMetrics()); + } + } + return extract(textualExtractor, source, toplevelKind, scopeManager, sourceType, parserRes); } diff --git a/javascript/extractor/test/com/semmle/js/extractor/test/AllTests.java b/javascript/extractor/test/com/semmle/js/extractor/test/AllTests.java index 7487e68efc01..6a51b2e69c4d 100644 --- a/javascript/extractor/test/com/semmle/js/extractor/test/AllTests.java +++ b/javascript/extractor/test/com/semmle/js/extractor/test/AllTests.java @@ -18,6 +18,7 @@ @SuiteClasses({ JSXTests.class, NodeJSDetectorTests.class, + ES2015DetectorTests.class, TrapTests.class, ObjectRestSpreadTests.class, ClassPropertiesTests.class, diff --git a/javascript/extractor/test/com/semmle/js/extractor/test/ES2015DetectorTests.java b/javascript/extractor/test/com/semmle/js/extractor/test/ES2015DetectorTests.java new file mode 100644 index 000000000000..669824c076f4 --- /dev/null +++ b/javascript/extractor/test/com/semmle/js/extractor/test/ES2015DetectorTests.java @@ -0,0 +1,58 @@ +package com.semmle.js.extractor.test; + +import com.semmle.js.ast.Node; +import com.semmle.js.extractor.ES2015Detector; +import com.semmle.js.extractor.ExtractionMetrics; +import com.semmle.js.extractor.ExtractorConfig; +import com.semmle.js.extractor.ExtractorConfig.SourceType; +import com.semmle.js.parser.JSParser; +import com.semmle.js.parser.JSParser.Result; +import org.junit.Assert; +import org.junit.Test; + +public class ES2015DetectorTests { + // using `experimental: true` as we do in real extractor, see `extractSource` method + // in `AutoBuild.java` + private static final ExtractorConfig CONFIG = new ExtractorConfig(true); + + private void isES2015(String src, boolean expected) { + Result res = JSParser.parse(CONFIG, SourceType.MODULE, src, new ExtractionMetrics()); + Node ast = res.getAST(); + Assert.assertNotNull(ast); + Assert.assertTrue(ES2015Detector.looksLikeES2015(ast) == expected); + } + + @Test + public void testImport() { + isES2015("import * as fs from 'fs';", true); + } + + @Test + public void testExport() { + isES2015("export function foo() { };", true); + } + + @Test + public void testDynamicImport() { + isES2015("import('fs');", true); + } + + @Test + public void testDynamicImportAssign() { + isES2015("var fs = import('fs');", true); + } + + @Test + public void testDynamicImportThen() { + isES2015("import('o').then((o) => {});", true); + } + + @Test + public void importInBlockComment() { + isES2015("/*\n" + + " import * from 'fs';\n" + + "*/\n" + + "const fs = require('fs');", + false); + } +} diff --git a/javascript/extractor/tests/node/output/trap/detection.js.trap b/javascript/extractor/tests/node/output/trap/detection.js.trap index 1da6b26f89cd..81e56c20609b 100644 --- a/javascript/extractor/tests/node/output/trap/detection.js.trap +++ b/javascript/extractor/tests/node/output/trap/detection.js.trap @@ -137,7 +137,6 @@ variables(#20046,"__dirname",#20041) #20047=@"var;{arguments};{#20041}" variables(#20047,"arguments",#20041) is_module(#20001) -is_es2015_module(#20001) #20048=@"var;{fs};{#20041}" variables(#20048,"fs",#20041) #20049=* @@ -199,5 +198,6 @@ successor(#20053,#20050) successor(#20052,#20055) successor(#20050,#20061) successor(#20059,#20049) +is_nodejs(#20001) numlines(#10000,6,1,5) filetype(#10000,"javascript") From 1d51d182ec4fba8c3c21aca83b2e8434f2828f69 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Tue, 26 Mar 2024 13:28:38 +0100 Subject: [PATCH 006/238] JS: Extractor: Explain how to make `replaceExpectedOutput` work now with bazel --- .../test/com/semmle/js/extractor/test/BUILD.bazel | 3 +++ .../test/com/semmle/js/extractor/test/TrapTests.java | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/javascript/extractor/test/com/semmle/js/extractor/test/BUILD.bazel b/javascript/extractor/test/com/semmle/js/extractor/test/BUILD.bazel index 45d6790e8a98..1bad97bb7cc8 100644 --- a/javascript/extractor/test/com/semmle/js/extractor/test/BUILD.bazel +++ b/javascript/extractor/test/com/semmle/js/extractor/test/BUILD.bazel @@ -12,6 +12,9 @@ java_test( "TS_WRAPPER_ZIP": "$(rlocationpath //javascript/extractor/lib/typescript)", }, test_class = "com.semmle.js.extractor.test.AllTests", + # To use `replaceExpectedOutput` you need to uncomment the following line + # (to be allowed to override the .trap files on disk) + # tags = ["no-sandbox"], deps = [ "//javascript/extractor", "//javascript/extractor:deps", diff --git a/javascript/extractor/test/com/semmle/js/extractor/test/TrapTests.java b/javascript/extractor/test/com/semmle/js/extractor/test/TrapTests.java index 5991ac6669a4..6daf56cc56e1 100644 --- a/javascript/extractor/test/com/semmle/js/extractor/test/TrapTests.java +++ b/javascript/extractor/test/com/semmle/js/extractor/test/TrapTests.java @@ -161,6 +161,14 @@ public void close() { byte[] actual_utf8_bytes = StringUtil.stringToBytes(sw.toString()); String actual = new String(actual_utf8_bytes, Charset.forName("UTF-8")); File trap = new File(outputDir, f.getName() + ".trap"); + // NOTE: If you want to replace expected output, you MUST change + // the way this test is run under bazel to escape the bazel + // sandbox. Add `tags = ["no-sandbox"]` to the test rule in + // javascript/extractor/test/com/semmle/js/extractor/test/BUILD.bazel + // + // if you have problems with too much caching, you need to find the right bazel command, + // and run `./build --bazel test ... --cache_test_results=no` + // (at least I had problems getting the "no-cache" tag to work) boolean replaceExpectedOutput = false; if (replaceExpectedOutput) { System.out.println("Replacing expected output for " + trap); From 60944a9bcbec317ed426fe50994fad1909ba614e Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Tue, 26 Mar 2024 13:29:45 +0100 Subject: [PATCH 007/238] JS: Accept new trap files As I see it, these all seem to have invalid code initially anyway, but this is definitely something a JS expert should review :) --- .../trap/anonFunctionWithoutParens.js.trap | 24 +-- .../flow/output/trap/anonIndexer.js.trap | 24 +-- .../trap/declared-module-imports.js.trap | 24 +-- .../flow/output/trap/exportOpaqueType.js.trap | 24 +-- .../trap/importTypeInDeclaredModule.js.trap | 24 +-- .../tests/flow/output/trap/variance.js.trap | 158 +++++++++--------- 6 files changed, 121 insertions(+), 157 deletions(-) diff --git a/javascript/extractor/tests/flow/output/trap/anonFunctionWithoutParens.js.trap b/javascript/extractor/tests/flow/output/trap/anonFunctionWithoutParens.js.trap index 999173d6a30d..154751cda15d 100644 --- a/javascript/extractor/tests/flow/output/trap/anonFunctionWithoutParens.js.trap +++ b/javascript/extractor/tests/flow/output/trap/anonFunctionWithoutParens.js.trap @@ -72,20 +72,14 @@ locations_default(#20025,#10000,1,40,1,39) hasLocation(#20024,#20025) toplevels(#20001,0) hasLocation(#20001,#20003) -#20026=@"module;{#10000},1,1" -scopes(#20026,3) -scopenodes(#20001,#20026) -scopenesting(#20026,#20000) -is_module(#20001) -is_es2015_module(#20001) -#20027=* -entry_cfg_node(#20027,#20001) -#20028=@"loc,{#10000},1,1,1,0" -locations_default(#20028,#10000,1,1,1,0) -hasLocation(#20027,#20028) -#20029=* -exit_cfg_node(#20029,#20001) -hasLocation(#20029,#20025) -successor(#20027,#20029) +#20026=* +entry_cfg_node(#20026,#20001) +#20027=@"loc,{#10000},1,1,1,0" +locations_default(#20027,#10000,1,1,1,0) +hasLocation(#20026,#20027) +#20028=* +exit_cfg_node(#20028,#20001) +hasLocation(#20028,#20025) +successor(#20026,#20028) numlines(#10000,1,1,0) filetype(#10000,"javascript") diff --git a/javascript/extractor/tests/flow/output/trap/anonIndexer.js.trap b/javascript/extractor/tests/flow/output/trap/anonIndexer.js.trap index fbfaf50aaee6..6f75d1228b72 100644 --- a/javascript/extractor/tests/flow/output/trap/anonIndexer.js.trap +++ b/javascript/extractor/tests/flow/output/trap/anonIndexer.js.trap @@ -85,20 +85,14 @@ toplevels(#20001,0) #20030=@"loc,{#10000},1,1,2,0" locations_default(#20030,#10000,1,1,2,0) hasLocation(#20001,#20030) -#20031=@"module;{#10000},1,1" -scopes(#20031,3) -scopenodes(#20001,#20031) -scopenesting(#20031,#20000) -is_module(#20001) -is_es2015_module(#20001) -#20032=* -entry_cfg_node(#20032,#20001) -#20033=@"loc,{#10000},1,1,1,0" -locations_default(#20033,#10000,1,1,1,0) -hasLocation(#20032,#20033) -#20034=* -exit_cfg_node(#20034,#20001) -hasLocation(#20034,#20029) -successor(#20032,#20034) +#20031=* +entry_cfg_node(#20031,#20001) +#20032=@"loc,{#10000},1,1,1,0" +locations_default(#20032,#10000,1,1,1,0) +hasLocation(#20031,#20032) +#20033=* +exit_cfg_node(#20033,#20001) +hasLocation(#20033,#20029) +successor(#20031,#20033) numlines(#10000,1,1,0) filetype(#10000,"javascript") diff --git a/javascript/extractor/tests/flow/output/trap/declared-module-imports.js.trap b/javascript/extractor/tests/flow/output/trap/declared-module-imports.js.trap index 1eedda348e34..1588e279e76c 100644 --- a/javascript/extractor/tests/flow/output/trap/declared-module-imports.js.trap +++ b/javascript/extractor/tests/flow/output/trap/declared-module-imports.js.trap @@ -128,20 +128,14 @@ toplevels(#20001,0) #20045=@"loc,{#10000},1,1,5,0" locations_default(#20045,#10000,1,1,5,0) hasLocation(#20001,#20045) -#20046=@"module;{#10000},1,1" -scopes(#20046,3) -scopenodes(#20001,#20046) -scopenesting(#20046,#20000) -is_module(#20001) -is_es2015_module(#20001) -#20047=* -entry_cfg_node(#20047,#20001) -#20048=@"loc,{#10000},1,1,1,0" -locations_default(#20048,#10000,1,1,1,0) -hasLocation(#20047,#20048) -#20049=* -exit_cfg_node(#20049,#20001) -hasLocation(#20049,#20044) -successor(#20047,#20049) +#20046=* +entry_cfg_node(#20046,#20001) +#20047=@"loc,{#10000},1,1,1,0" +locations_default(#20047,#10000,1,1,1,0) +hasLocation(#20046,#20047) +#20048=* +exit_cfg_node(#20048,#20001) +hasLocation(#20048,#20044) +successor(#20046,#20048) numlines(#10000,4,4,0) filetype(#10000,"javascript") diff --git a/javascript/extractor/tests/flow/output/trap/exportOpaqueType.js.trap b/javascript/extractor/tests/flow/output/trap/exportOpaqueType.js.trap index 5cdd7537e30f..5b8c2c2b7d97 100644 --- a/javascript/extractor/tests/flow/output/trap/exportOpaqueType.js.trap +++ b/javascript/extractor/tests/flow/output/trap/exportOpaqueType.js.trap @@ -70,20 +70,14 @@ toplevels(#20001,0) #20024=@"loc,{#10000},1,1,2,0" locations_default(#20024,#10000,1,1,2,0) hasLocation(#20001,#20024) -#20025=@"module;{#10000},1,1" -scopes(#20025,3) -scopenodes(#20001,#20025) -scopenesting(#20025,#20000) -is_module(#20001) -is_es2015_module(#20001) -#20026=* -entry_cfg_node(#20026,#20001) -#20027=@"loc,{#10000},1,1,1,0" -locations_default(#20027,#10000,1,1,1,0) -hasLocation(#20026,#20027) -#20028=* -exit_cfg_node(#20028,#20001) -hasLocation(#20028,#20023) -successor(#20026,#20028) +#20025=* +entry_cfg_node(#20025,#20001) +#20026=@"loc,{#10000},1,1,1,0" +locations_default(#20026,#10000,1,1,1,0) +hasLocation(#20025,#20026) +#20027=* +exit_cfg_node(#20027,#20001) +hasLocation(#20027,#20023) +successor(#20025,#20027) numlines(#10000,1,1,0) filetype(#10000,"javascript") diff --git a/javascript/extractor/tests/flow/output/trap/importTypeInDeclaredModule.js.trap b/javascript/extractor/tests/flow/output/trap/importTypeInDeclaredModule.js.trap index 188033df9a15..8c4b5a30f4a1 100644 --- a/javascript/extractor/tests/flow/output/trap/importTypeInDeclaredModule.js.trap +++ b/javascript/extractor/tests/flow/output/trap/importTypeInDeclaredModule.js.trap @@ -205,20 +205,14 @@ toplevels(#20001,0) #20071=@"loc,{#10000},1,1,11,2" locations_default(#20071,#10000,1,1,11,2) hasLocation(#20001,#20071) -#20072=@"module;{#10000},1,1" -scopes(#20072,3) -scopenodes(#20001,#20072) -scopenesting(#20072,#20000) -is_module(#20001) -is_es2015_module(#20001) -#20073=* -entry_cfg_node(#20073,#20001) -#20074=@"loc,{#10000},1,1,1,0" -locations_default(#20074,#10000,1,1,1,0) -hasLocation(#20073,#20074) -#20075=* -exit_cfg_node(#20075,#20001) -hasLocation(#20075,#20070) -successor(#20073,#20075) +#20072=* +entry_cfg_node(#20072,#20001) +#20073=@"loc,{#10000},1,1,1,0" +locations_default(#20073,#10000,1,1,1,0) +hasLocation(#20072,#20073) +#20074=* +exit_cfg_node(#20074,#20001) +hasLocation(#20074,#20070) +successor(#20072,#20074) numlines(#10000,11,10,0) filetype(#10000,"javascript") diff --git a/javascript/extractor/tests/flow/output/trap/variance.js.trap b/javascript/extractor/tests/flow/output/trap/variance.js.trap index b6955639fe9d..cd1ea42f2284 100644 --- a/javascript/extractor/tests/flow/output/trap/variance.js.trap +++ b/javascript/extractor/tests/flow/output/trap/variance.js.trap @@ -160,95 +160,89 @@ toplevels(#20001,0) #20057=@"loc,{#10000},1,1,7,1" locations_default(#20057,#10000,1,1,7,1) hasLocation(#20001,#20057) -#20058=@"module;{#10000},1,1" -scopes(#20058,3) -scopenodes(#20001,#20058) -scopenesting(#20058,#20000) -is_module(#20001) -is_es2015_module(#20001) -#20059=@"var;{Foo};{#20058}" -variables(#20059,"Foo",#20058) -#20060=@"local_type_name;{Foo};{#20058}" -local_type_names(#20060,"Foo",#20058) -#20061=* -stmts(#20061,26,#20001,0,"class F ... : int\n}") -#20062=@"loc,{#10000},5,1,7,1" -locations_default(#20062,#10000,5,1,7,1) -hasLocation(#20061,#20062) -stmt_containers(#20061,#20001) +#20058=@"var;{Foo};{#20000}" +variables(#20058,"Foo",#20000) +#20059=@"local_type_name;{Foo};{#20000}" +local_type_names(#20059,"Foo",#20000) +#20060=* +stmts(#20060,26,#20001,0,"class F ... : int\n}") +#20061=@"loc,{#10000},5,1,7,1" +locations_default(#20061,#10000,5,1,7,1) +hasLocation(#20060,#20061) +stmt_containers(#20060,#20001) +#20062=* +exprs(#20062,78,#20060,0,"Foo") +hasLocation(#20062,#20043) +enclosing_stmt(#20062,#20060) +expr_containers(#20062,#20001) +literals("Foo","Foo",#20062) +decl(#20062,#20058) +typedecl(#20062,#20059) #20063=* -exprs(#20063,78,#20061,0,"Foo") -hasLocation(#20063,#20043) -enclosing_stmt(#20063,#20061) -expr_containers(#20063,#20001) -literals("Foo","Foo",#20063) -decl(#20063,#20059) -typedecl(#20063,#20060) +scopes(#20063,10) +scopenodes(#20060,#20063) +scopenesting(#20063,#20000) #20064=* -scopes(#20064,10) -scopenodes(#20061,#20064) -scopenesting(#20064,#20058) -#20065=* -properties(#20065,#20061,2,8,"+x: int") -#20066=@"loc,{#10000},6,3,6,9" -locations_default(#20066,#10000,6,3,6,9) -hasLocation(#20065,#20066) +properties(#20064,#20060,2,8,"+x: int") +#20065=@"loc,{#10000},6,3,6,9" +locations_default(#20065,#10000,6,3,6,9) +hasLocation(#20064,#20065) +#20066=* #20067=* +exprs(#20067,0,#20064,0,"x") +hasLocation(#20067,#20049) +expr_containers(#20067,#20066) +literals("x","x",#20067) #20068=* -exprs(#20068,0,#20065,0,"x") -hasLocation(#20068,#20049) -expr_containers(#20068,#20067) -literals("x","x",#20068) -#20069=* -properties(#20069,#20061,3,0,"constructor() {}") -#20070=@"loc,{#10000},5,11,5,10" -locations_default(#20070,#10000,5,11,5,10) -hasLocation(#20069,#20070) +properties(#20068,#20060,3,0,"constructor() {}") +#20069=@"loc,{#10000},5,11,5,10" +locations_default(#20069,#10000,5,11,5,10) +hasLocation(#20068,#20069) +#20070=* +exprs(#20070,0,#20068,0,"constructor") +hasLocation(#20070,#20069) +enclosing_stmt(#20070,#20060) +expr_containers(#20070,#20001) +literals("constructor","constructor",#20070) +exprs(#20066,9,#20068,1,"() {}") +hasLocation(#20066,#20069) +enclosing_stmt(#20066,#20060) +expr_containers(#20066,#20001) #20071=* -exprs(#20071,0,#20069,0,"constructor") -hasLocation(#20071,#20070) -enclosing_stmt(#20071,#20061) -expr_containers(#20071,#20001) -literals("constructor","constructor",#20071) -exprs(#20067,9,#20069,1,"() {}") -hasLocation(#20067,#20070) -enclosing_stmt(#20067,#20061) -expr_containers(#20067,#20001) -#20072=* -scopes(#20072,1) -scopenodes(#20067,#20072) -scopenesting(#20072,#20064) -#20073=@"var;{arguments};{#20072}" -variables(#20073,"arguments",#20072) -is_arguments_object(#20073) +scopes(#20071,1) +scopenodes(#20066,#20071) +scopenesting(#20071,#20063) +#20072=@"var;{arguments};{#20071}" +variables(#20072,"arguments",#20071) +is_arguments_object(#20072) +#20073=* +stmts(#20073,1,#20066,-2,"{}") +hasLocation(#20073,#20069) +stmt_containers(#20073,#20066) +is_method(#20068) #20074=* -stmts(#20074,1,#20067,-2,"{}") -hasLocation(#20074,#20070) -stmt_containers(#20074,#20067) -is_method(#20069) -#20075=* -entry_cfg_node(#20075,#20001) -#20076=@"loc,{#10000},1,1,1,0" -locations_default(#20076,#10000,1,1,1,0) -hasLocation(#20075,#20076) +entry_cfg_node(#20074,#20001) +#20075=@"loc,{#10000},1,1,1,0" +locations_default(#20075,#10000,1,1,1,0) +hasLocation(#20074,#20075) +#20076=* +exit_cfg_node(#20076,#20001) +hasLocation(#20076,#20056) +successor(#20067,#20064) +successor(#20066,#20068) #20077=* -exit_cfg_node(#20077,#20001) -hasLocation(#20077,#20056) -successor(#20068,#20065) -successor(#20067,#20069) +entry_cfg_node(#20077,#20066) +hasLocation(#20077,#20069) +successor(#20064,#20073) #20078=* -entry_cfg_node(#20078,#20067) -hasLocation(#20078,#20070) -successor(#20065,#20074) -#20079=* -exit_cfg_node(#20079,#20067) -hasLocation(#20079,#20070) -successor(#20074,#20079) -successor(#20078,#20068) -successor(#20071,#20067) -successor(#20069,#20061) -successor(#20063,#20071) -successor(#20061,#20077) -successor(#20075,#20063) +exit_cfg_node(#20078,#20066) +hasLocation(#20078,#20069) +successor(#20073,#20078) +successor(#20077,#20067) +successor(#20070,#20066) +successor(#20068,#20060) +successor(#20062,#20070) +successor(#20060,#20076) +successor(#20074,#20062) numlines(#10000,7,6,0) filetype(#10000,"javascript") From df463e51c1a39f36b63ef1a9d72a9a2f3bc70842 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Tue, 26 Mar 2024 17:02:47 +0100 Subject: [PATCH 008/238] JS: Extractor: Fix `experimental` flag value for NodeJSDetectorTests --- .../com/semmle/js/extractor/test/NodeJSDetectorTests.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/javascript/extractor/test/com/semmle/js/extractor/test/NodeJSDetectorTests.java b/javascript/extractor/test/com/semmle/js/extractor/test/NodeJSDetectorTests.java index 14d5b323e7c3..ead1d1265612 100644 --- a/javascript/extractor/test/com/semmle/js/extractor/test/NodeJSDetectorTests.java +++ b/javascript/extractor/test/com/semmle/js/extractor/test/NodeJSDetectorTests.java @@ -11,7 +11,9 @@ import org.junit.Test; public class NodeJSDetectorTests { - private static final ExtractorConfig CONFIG = new ExtractorConfig(false); + // using `experimental: true` as we do in real extractor, see `extractSource` method + // in `AutoBuild.java` + private static final ExtractorConfig CONFIG = new ExtractorConfig(true); private void isNodeJS(String src, boolean expected) { Result res = JSParser.parse(CONFIG, SourceType.SCRIPT, src, new ExtractionMetrics()); From f33222c83b6cde203153152cf7bf572da7133cb9 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Tue, 2 Apr 2024 11:10:53 +0200 Subject: [PATCH 009/238] JS: Add change-note --- .../change-notes/2024-04-02-more-robust-commonjs-detection.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 javascript/ql/lib/change-notes/2024-04-02-more-robust-commonjs-detection.md diff --git a/javascript/ql/lib/change-notes/2024-04-02-more-robust-commonjs-detection.md b/javascript/ql/lib/change-notes/2024-04-02-more-robust-commonjs-detection.md new file mode 100644 index 000000000000..45c3879c39cc --- /dev/null +++ b/javascript/ql/lib/change-notes/2024-04-02-more-robust-commonjs-detection.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Improved detection of whether a file uses CommonJS module system. From f77f91ef4935208707467e36f3c4a2247414e140 Mon Sep 17 00:00:00 2001 From: Chad Bentz <1760475+felickz@users.noreply.github.com> Date: Tue, 16 Apr 2024 16:02:15 -0400 Subject: [PATCH 010/238] move security-severity to end of column list in csv Co-authored-by: Rasmus Wriedt Larsen --- misc/scripts/generate-code-scanning-query-list.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/misc/scripts/generate-code-scanning-query-list.py b/misc/scripts/generate-code-scanning-query-list.py index 55437feb3b74..94b15a33886d 100644 --- a/misc/scripts/generate-code-scanning-query-list.py +++ b/misc/scripts/generate-code-scanning-query-list.py @@ -159,7 +159,7 @@ def subprocess_run(cmd): csvwriter = csv.writer(sys.stdout) csvwriter.writerow([ "Query filename", "Suite", "Query name", "Query ID", - "Kind", "Severity", "Security score", "Precision", "Tags" + "Kind", "Severity", "Precision", "Tags", "Security score" ]) # Iterate over all languages and packs, and resolve which queries are part of those packs @@ -197,7 +197,7 @@ def subprocess_run(cmd): get_query_metadata('id', meta, queryfile_nwo), get_query_metadata('kind', meta, queryfile_nwo), get_query_metadata('problem.severity', meta, queryfile_nwo), - get_query_metadata('security-severity', meta, queryfile_nwo), get_query_metadata('precision', meta, queryfile_nwo), - get_query_metadata('tags', meta, queryfile_nwo) + get_query_metadata('tags', meta, queryfile_nwo), + get_query_metadata('security-severity', meta, queryfile_nwo), ]) From ce711f7d2f9fba540dc2a72d70038e9eb39d30a2 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Tue, 23 Apr 2024 09:40:44 +0200 Subject: [PATCH 011/238] Python: Move dataflow tests out of experimental --- .../dataflow/TestUtil/DataflowQueryTest.qll | 0 .../dataflow/TestUtil/FlowTest.qll | 0 .../dataflow/TestUtil/LocalFlowStepTest.qll | 0 .../dataflow/TestUtil/MaximalFlowTest.qll | 0 .../dataflow/TestUtil/NormalDataflowTest.qll | 0 .../dataflow/TestUtil/NormalTaintTrackingTest.qll | 0 .../dataflow/TestUtil/RoutingTest.qll | 0 .../dataflow/TestUtil/UnresolvedCalls.qll | 0 .../dataflow/basic/allFlowsConfig.qll | 0 .../dataflow/basic/callGraph.expected | 0 .../{experimental => library-tests}/dataflow/basic/callGraph.ql | 0 .../dataflow/basic/callGraphSinks.expected | 0 .../dataflow/basic/callGraphSinks.ql | 0 .../dataflow/basic/callGraphSources.expected | 0 .../dataflow/basic/callGraphSources.ql | 0 .../dataflow/basic/global.expected | 0 .../test/{experimental => library-tests}/dataflow/basic/global.ql | 0 .../dataflow/basic/globalStep.expected | 0 .../{experimental => library-tests}/dataflow/basic/globalStep.ql | 0 .../{experimental => library-tests}/dataflow/basic/local.expected | 0 .../test/{experimental => library-tests}/dataflow/basic/local.ql | 0 .../dataflow/basic/localFlowStepTest.expected | 0 .../dataflow/basic/localFlowStepTest.ql | 0 .../dataflow/basic/localStep.expected | 0 .../{experimental => library-tests}/dataflow/basic/localStep.ql | 0 .../dataflow/basic/maximalFlowTest.expected | 0 .../dataflow/basic/maximalFlowTest.ql | 0 .../dataflow/basic/maximalFlows.expected | 0 .../dataflow/basic/maximalFlows.ql | 0 .../dataflow/basic/maximalFlowsConfig.qll | 0 .../{experimental => library-tests}/dataflow/basic/sinks.expected | 0 .../test/{experimental => library-tests}/dataflow/basic/sinks.ql | 0 .../dataflow/basic/sources.expected | 0 .../{experimental => library-tests}/dataflow/basic/sources.ql | 0 .../test/{experimental => library-tests}/dataflow/basic/test.py | 0 .../{experimental => library-tests}/dataflow/callGraphConfig.qll | 0 .../dataflow/callgraph_crosstalk/Arguments.expected | 0 .../dataflow/callgraph_crosstalk/Arguments.ql | 0 .../dataflow/callgraph_crosstalk/options | 0 .../dataflow/callgraph_crosstalk/test.py | 0 .../dataflow/calls/DataFlowCallTest.expected | 0 .../dataflow/calls/DataFlowCallTest.ql | 0 .../dataflow/calls/new_cls_param.py | 0 .../test/{experimental => library-tests}/dataflow/calls/test.py | 0 .../dataflow/consistency/class_scope.py | 0 .../dataflow/consistency/modeling-consistency.expected | 0 .../dataflow/consistency/modeling-consistency.ql | 0 .../dataflow/consistency/module.py | 0 .../{experimental => library-tests}/dataflow/consistency/test.py | 0 .../dataflow/coverage-py2/argumentRoutingTest.expected | 0 .../dataflow/coverage-py2/argumentRoutingTest.qlref | 0 .../dataflow/coverage-py2/classes.py | 0 .../{experimental => library-tests}/dataflow/coverage-py2/options | 0 .../dataflow/coverage-py3/argumentRoutingTest.expected | 0 .../dataflow/coverage-py3/argumentRoutingTest.qlref | 0 .../dataflow/coverage-py3/classes.py | 0 .../{experimental => library-tests}/dataflow/coverage-py3/options | 0 .../dataflow/coverage/NormalDataflowTest.expected | 0 .../dataflow/coverage/NormalDataflowTest.ql | 0 .../dataflow/coverage/argumentPassing.py | 0 .../dataflow/coverage/argumentPassing_bad_flow_test.py | 0 .../dataflow/coverage/argumentRoutingTest.expected | 0 .../dataflow/coverage/argumentRoutingTest.ql | 0 .../{experimental => library-tests}/dataflow/coverage/classes.py | 0 .../dataflow/coverage/datamodel.py | 0 .../dataflow/coverage/localFlow.expected | 0 .../dataflow/coverage/localFlow.ql | 0 .../{experimental => library-tests}/dataflow/coverage/loops.py | 0 .../dataflow/coverage/module_level.py | 0 .../{experimental => library-tests}/dataflow/coverage/test.py | 0 .../dataflow/coverage/test_builtins.py | 0 .../dataflow/def-use-flow/def_use_counts.expected | 0 .../dataflow/def-use-flow/def_use_counts.ql | 0 .../dataflow/def-use-flow/def_use_flow.py | 0 .../dataflow/enclosing-callable/EnclosingCallable.expected | 0 .../dataflow/enclosing-callable/EnclosingCallable.ql | 0 .../dataflow/enclosing-callable/class_example.py | 0 .../dataflow/enclosing-callable/generator.py | 0 .../dataflow/exceptions/NormalDataflowTest.expected | 0 .../dataflow/exceptions/NormalDataflowTest.ql | 0 .../{experimental => library-tests}/dataflow/exceptions/test.py | 0 .../dataflow/exceptions/test_group.py | 0 .../dataflow/fieldflow/NormalDataflowTest.expected | 0 .../dataflow/fieldflow/NormalDataflowTest.ql | 0 .../dataflow/fieldflow/UnresolvedCalls.expected | 0 .../dataflow/fieldflow/UnresolvedCalls.ql | 0 .../{experimental => library-tests}/dataflow/fieldflow/options | 0 .../{experimental => library-tests}/dataflow/fieldflow/test.py | 0 .../dataflow/fieldflow/test_dict.py | 0 .../dataflow/fieldflow/test_global.py | 0 .../dataflow/global-flow/accesses.expected | 0 .../dataflow/global-flow/accesses.ql | 0 .../{experimental => library-tests}/dataflow/global-flow/known.py | 0 .../{experimental => library-tests}/dataflow/global-flow/test.py | 0 .../{experimental => library-tests}/dataflow/import-star/deux.py | 0 .../dataflow/import-star/global.expected | 0 .../dataflow/import-star/global.ql | 0 .../{experimental => library-tests}/dataflow/import-star/one.py | 0 .../{experimental => library-tests}/dataflow/import-star/test1.py | 0 .../{experimental => library-tests}/dataflow/import-star/test2.py | 0 .../{experimental => library-tests}/dataflow/import-star/test3.py | 0 .../{experimental => library-tests}/dataflow/import-star/three.py | 0 .../{experimental => library-tests}/dataflow/import-star/trois.py | 0 .../{experimental => library-tests}/dataflow/import-star/two.py | 0 .../{experimental => library-tests}/dataflow/import-star/un.py | 0 .../dataflow/match/NormalDataflowTest.expected | 0 .../dataflow/match/NormalDataflowTest.ql | 0 .../test/{experimental => library-tests}/dataflow/match/test.py | 0 .../dataflow/method-calls/test.expected | 0 .../{experimental => library-tests}/dataflow/method-calls/test.py | 0 .../{experimental => library-tests}/dataflow/method-calls/test.ql | 0 .../dataflow/model-summaries/InlineTaintTest.expected | 0 .../dataflow/model-summaries/InlineTaintTest.ext.yml | 0 .../dataflow/model-summaries/InlineTaintTest.ql | 0 .../dataflow/model-summaries/NormalDataflowTest.expected | 0 .../dataflow/model-summaries/NormalDataflowTest.ext.yml | 0 .../dataflow/model-summaries/NormalDataflowTest.ql | 0 .../dataflow/model-summaries/model_summaries.py | 0 .../dataflow/module-initialization/base.py | 0 .../dataflow/module-initialization/localFlow.expected | 0 .../dataflow/module-initialization/localFlow.ql | 0 .../dataflow/module-initialization/m1.py | 0 .../dataflow/module-initialization/multiphase.py | 0 .../dataflow/module-initialization/test.py | 0 .../dataflow/module-initialization/testOnce.py | 0 python/ql/test/{experimental => library-tests}/dataflow/options | 0 .../dataflow/path-graph/PathNodes.expected | 0 .../dataflow/path-graph/PathNodes.ql | 0 .../{experimental => library-tests}/dataflow/path-graph/test.py | 0 .../{experimental => library-tests}/dataflow/pep_328/__init__.py | 0 .../dataflow/pep_328/package/__init__.py | 0 .../dataflow/pep_328/package/moduleA.py | 0 .../dataflow/pep_328/package/subpackage1/__init__.py | 0 .../dataflow/pep_328/package/subpackage1/moduleX.py | 0 .../dataflow/pep_328/package/subpackage1/moduleY.py | 0 .../dataflow/pep_328/package/subpackage2/__init__.py | 0 .../dataflow/pep_328/package/subpackage2/moduleZ.py | 0 .../{experimental => library-tests}/dataflow/pep_328/start.py | 0 .../dataflow/qll-private-imports/README.md | 0 .../dataflow/qll-private-imports/Test.expected | 0 .../dataflow/qll-private-imports/Test.ql | 0 .../dataflow/qll-private-imports/test.py | 0 .../dataflow/regression/custom_dataflow.expected | 0 .../dataflow/regression/custom_dataflow.ql | 0 .../dataflow/regression/dataflow.expected | 0 .../dataflow/regression/dataflow.ql | 0 .../{experimental => library-tests}/dataflow/regression/module.py | 0 .../{experimental => library-tests}/dataflow/regression/test.py | 0 .../dataflow/sensitive-data/TestSensitiveDataSources.expected | 0 .../dataflow/sensitive-data/TestSensitiveDataSources.ql | 0 .../dataflow/sensitive-data/test.py | 0 .../dataflow/strange-essaflow/test.py | 0 .../dataflow/strange-essaflow/testFlow.expected | 0 .../dataflow/strange-essaflow/testFlow.ql | 0 .../dataflow/summaries-checks/dummy.py | 0 .../dataflow/summaries-checks/invalid-spec.expected | 0 .../dataflow/summaries-checks/invalid-spec.ql | 0 .../dataflow/summaries-checks/missing-attribute-content.expected | 0 .../dataflow/summaries-checks/missing-attribute-content.ql | 0 .../dataflow/summaries/InlineTaintTest.expected | 0 .../dataflow/summaries/InlineTaintTest.ql | 0 .../dataflow/summaries/NormalTaintTrackingTest.expected | 0 .../dataflow/summaries/NormalTaintTrackingTest.ql | 0 .../dataflow/summaries/TestSummaries.qll | 0 .../dataflow/summaries/conflicting_summaries.py | 0 .../dataflow/summaries/extracted_package/__init__.py | 0 .../dataflow/summaries/extracted_package/functions.py | 0 .../dataflow/summaries/summaries.expected | 0 .../dataflow/summaries/summaries.py | 0 .../dataflow/summaries/summaries.ql | 0 .../dataflow/tainttracking/TestTaintLib.qll | 0 .../dataflow/tainttracking/basic/GlobalTaintTracking.expected | 0 .../dataflow/tainttracking/basic/GlobalTaintTracking.ql | 0 .../dataflow/tainttracking/basic/LocalTaintStep.expected | 0 .../dataflow/tainttracking/basic/LocalTaintStep.ql | 0 .../dataflow/tainttracking/basic/test.py | 0 .../tainttracking/commonSanitizer/InlineTaintTest.expected | 0 .../dataflow/tainttracking/commonSanitizer/InlineTaintTest.ql | 0 .../tainttracking/commonSanitizer/test_string_const_compare.py | 0 .../tainttracking/customSanitizer/InlineTaintTest.expected | 0 .../dataflow/tainttracking/customSanitizer/InlineTaintTest.ql | 0 .../dataflow/tainttracking/customSanitizer/test.py | 0 .../dataflow/tainttracking/customSanitizer/test_logical.py | 0 .../dataflow/tainttracking/customSanitizer/test_reference.py | 0 .../defaultAdditionalTaintStep-py3/InlineTaintTest.expected | 0 .../defaultAdditionalTaintStep-py3/InlineTaintTest.ql | 0 .../dataflow/tainttracking/defaultAdditionalTaintStep-py3/options | 0 .../defaultAdditionalTaintStep-py3/test_collections.py | 0 .../tainttracking/defaultAdditionalTaintStep-py3/test_pathlib.py | 0 .../tainttracking/defaultAdditionalTaintStep-py3/test_string.py | 0 .../defaultAdditionalTaintStep-py3/test_unpacking.py | 0 .../defaultAdditionalTaintStep/InlineTaintTest.expected | 0 .../tainttracking/defaultAdditionalTaintStep/InlineTaintTest.ql | 0 .../tainttracking/defaultAdditionalTaintStep/test_async.py | 0 .../tainttracking/defaultAdditionalTaintStep/test_attr.py | 0 .../tainttracking/defaultAdditionalTaintStep/test_collections.py | 0 .../dataflow/tainttracking/defaultAdditionalTaintStep/test_for.py | 0 .../tainttracking/defaultAdditionalTaintStep/test_string.py | 0 .../tainttracking/defaultAdditionalTaintStep/test_unpacking.py | 0 .../tainttracking/defaultAdditionalTaintStep/test_with.py | 0 .../tainttracking/generator-flow/InlineTaintTest.expected | 0 .../dataflow/tainttracking/generator-flow/InlineTaintTest.ql | 0 .../tainttracking/generator-flow/NormalDataflowTest.expected | 0 .../dataflow/tainttracking/generator-flow/NormalDataflowTest.ql | 0 .../dataflow/tainttracking/generator-flow/test_dataflow.py | 0 .../dataflow/tainttracking/generator-flow/test_taint.py | 0 .../dataflow/tainttracking/taintlib.py | 0 .../tainttracking/unwanted-global-flow/InlineTaintTest.expected | 0 .../tainttracking/unwanted-global-flow/InlineTaintTest.ql | 0 .../dataflow/tainttracking/unwanted-global-flow/test.py | 0 .../test/{experimental => library-tests}/dataflow/testConfig.qll | 0 .../{experimental => library-tests}/dataflow/testTaintConfig.qll | 0 .../ql/test/{experimental => library-tests}/dataflow/testlib.py | 0 .../dataflow/typetracking-summaries/TestSummaries.qll | 0 .../dataflow/typetracking-summaries/summaries.py | 0 .../dataflow/typetracking-summaries/tracked.expected | 0 .../dataflow/typetracking-summaries/tracked.ql | 0 .../dataflow/typetracking/attribute_tests.py | 0 .../dataflow/typetracking/content_test.py | 0 .../dataflow/typetracking/import_as_attr.py | 0 .../dataflow/typetracking/import_as_attr_dotted.py | 0 .../dataflow/typetracking/moduleattr.expected | 0 .../dataflow/typetracking/moduleattr.ql | 0 .../dataflow/typetracking/multiple_callables.py | 0 .../dataflow/typetracking/mymodule.py | 0 .../{experimental => library-tests}/dataflow/typetracking/test.py | 0 .../dataflow/typetracking/tracked.expected | 0 .../dataflow/typetracking/tracked.ql | 0 .../dataflow/typetracking_imports/README.md | 0 .../dataflow/typetracking_imports/highlight_problem.expected | 0 .../dataflow/typetracking_imports/highlight_problem.ql | 0 .../dataflow/typetracking_imports/options | 0 .../dataflow/typetracking_imports/pkg/__init__.py | 0 .../dataflow/typetracking_imports/pkg/alias_only_direct.py | 0 .../dataflow/typetracking_imports/pkg/alias_problem.py | 0 .../dataflow/typetracking_imports/pkg/alias_problem_fixed.py | 0 .../dataflow/typetracking_imports/pkg/alias_star.py | 0 .../dataflow/typetracking_imports/pkg/foo_def.py | 0 .../dataflow/typetracking_imports/pkg/other.py | 0 .../dataflow/typetracking_imports/pkg/problem_absolute_import.py | 0 .../dataflow/typetracking_imports/pkg/use.py | 0 .../dataflow/typetracking_imports/pkg/works_absolute_import.py | 0 .../dataflow/typetracking_imports/tracked.expected | 0 .../dataflow/typetracking_imports/tracked.qlref | 0 .../dataflow/use-use-flow/read_explosion.py | 0 .../dataflow/use-use-flow/use-use-counts.expected | 0 .../dataflow/use-use-flow/use-use-counts.ql | 0 .../ql/test/{experimental => library-tests}/dataflow/validTest.py | 0 .../dataflow/variable-capture/CaptureTest.expected | 0 .../dataflow/variable-capture/CaptureTest.ql | 0 .../dataflow/variable-capture/by_value.py | 0 .../variable-capture/dataflow-capture-consistency.expected | 0 .../dataflow/variable-capture/dataflow-capture-consistency.ql | 0 .../dataflow/variable-capture/dict.py | 0 .../dataflow/variable-capture/global.py | 0 .../dataflow/variable-capture/in.py | 0 .../dataflow/variable-capture/nonlocal.py | 0 .../dataflow/variable-capture/test_collections.py | 0 .../dataflow/variable-capture/test_fields.py | 0 .../dataflow/variable-capture/test_library_calls.py | 0 260 files changed, 0 insertions(+), 0 deletions(-) rename python/ql/test/{experimental => library-tests}/dataflow/TestUtil/DataflowQueryTest.qll (100%) rename python/ql/test/{experimental => library-tests}/dataflow/TestUtil/FlowTest.qll (100%) rename python/ql/test/{experimental => library-tests}/dataflow/TestUtil/LocalFlowStepTest.qll (100%) rename python/ql/test/{experimental => library-tests}/dataflow/TestUtil/MaximalFlowTest.qll (100%) rename python/ql/test/{experimental => library-tests}/dataflow/TestUtil/NormalDataflowTest.qll (100%) rename python/ql/test/{experimental => library-tests}/dataflow/TestUtil/NormalTaintTrackingTest.qll (100%) rename python/ql/test/{experimental => library-tests}/dataflow/TestUtil/RoutingTest.qll (100%) rename python/ql/test/{experimental => library-tests}/dataflow/TestUtil/UnresolvedCalls.qll (100%) rename python/ql/test/{experimental => library-tests}/dataflow/basic/allFlowsConfig.qll (100%) rename python/ql/test/{experimental => library-tests}/dataflow/basic/callGraph.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/basic/callGraph.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/basic/callGraphSinks.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/basic/callGraphSinks.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/basic/callGraphSources.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/basic/callGraphSources.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/basic/global.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/basic/global.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/basic/globalStep.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/basic/globalStep.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/basic/local.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/basic/local.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/basic/localFlowStepTest.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/basic/localFlowStepTest.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/basic/localStep.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/basic/localStep.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/basic/maximalFlowTest.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/basic/maximalFlowTest.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/basic/maximalFlows.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/basic/maximalFlows.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/basic/maximalFlowsConfig.qll (100%) rename python/ql/test/{experimental => library-tests}/dataflow/basic/sinks.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/basic/sinks.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/basic/sources.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/basic/sources.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/basic/test.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/callGraphConfig.qll (100%) rename python/ql/test/{experimental => library-tests}/dataflow/callgraph_crosstalk/Arguments.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/callgraph_crosstalk/Arguments.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/callgraph_crosstalk/options (100%) rename python/ql/test/{experimental => library-tests}/dataflow/callgraph_crosstalk/test.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/calls/DataFlowCallTest.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/calls/DataFlowCallTest.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/calls/new_cls_param.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/calls/test.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/consistency/class_scope.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/consistency/modeling-consistency.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/consistency/modeling-consistency.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/consistency/module.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/consistency/test.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/coverage-py2/argumentRoutingTest.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/coverage-py2/argumentRoutingTest.qlref (100%) rename python/ql/test/{experimental => library-tests}/dataflow/coverage-py2/classes.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/coverage-py2/options (100%) rename python/ql/test/{experimental => library-tests}/dataflow/coverage-py3/argumentRoutingTest.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/coverage-py3/argumentRoutingTest.qlref (100%) rename python/ql/test/{experimental => library-tests}/dataflow/coverage-py3/classes.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/coverage-py3/options (100%) rename python/ql/test/{experimental => library-tests}/dataflow/coverage/NormalDataflowTest.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/coverage/NormalDataflowTest.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/coverage/argumentPassing.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/coverage/argumentPassing_bad_flow_test.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/coverage/argumentRoutingTest.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/coverage/argumentRoutingTest.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/coverage/classes.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/coverage/datamodel.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/coverage/localFlow.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/coverage/localFlow.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/coverage/loops.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/coverage/module_level.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/coverage/test.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/coverage/test_builtins.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/def-use-flow/def_use_counts.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/def-use-flow/def_use_counts.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/def-use-flow/def_use_flow.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/enclosing-callable/EnclosingCallable.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/enclosing-callable/EnclosingCallable.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/enclosing-callable/class_example.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/enclosing-callable/generator.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/exceptions/NormalDataflowTest.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/exceptions/NormalDataflowTest.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/exceptions/test.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/exceptions/test_group.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/fieldflow/NormalDataflowTest.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/fieldflow/NormalDataflowTest.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/fieldflow/UnresolvedCalls.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/fieldflow/UnresolvedCalls.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/fieldflow/options (100%) rename python/ql/test/{experimental => library-tests}/dataflow/fieldflow/test.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/fieldflow/test_dict.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/fieldflow/test_global.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/global-flow/accesses.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/global-flow/accesses.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/global-flow/known.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/global-flow/test.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/import-star/deux.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/import-star/global.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/import-star/global.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/import-star/one.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/import-star/test1.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/import-star/test2.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/import-star/test3.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/import-star/three.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/import-star/trois.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/import-star/two.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/import-star/un.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/match/NormalDataflowTest.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/match/NormalDataflowTest.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/match/test.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/method-calls/test.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/method-calls/test.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/method-calls/test.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/model-summaries/InlineTaintTest.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/model-summaries/InlineTaintTest.ext.yml (100%) rename python/ql/test/{experimental => library-tests}/dataflow/model-summaries/InlineTaintTest.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/model-summaries/NormalDataflowTest.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/model-summaries/NormalDataflowTest.ext.yml (100%) rename python/ql/test/{experimental => library-tests}/dataflow/model-summaries/NormalDataflowTest.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/model-summaries/model_summaries.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/module-initialization/base.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/module-initialization/localFlow.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/module-initialization/localFlow.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/module-initialization/m1.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/module-initialization/multiphase.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/module-initialization/test.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/module-initialization/testOnce.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/options (100%) rename python/ql/test/{experimental => library-tests}/dataflow/path-graph/PathNodes.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/path-graph/PathNodes.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/path-graph/test.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/pep_328/__init__.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/pep_328/package/__init__.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/pep_328/package/moduleA.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/pep_328/package/subpackage1/__init__.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/pep_328/package/subpackage1/moduleX.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/pep_328/package/subpackage1/moduleY.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/pep_328/package/subpackage2/__init__.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/pep_328/package/subpackage2/moduleZ.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/pep_328/start.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/qll-private-imports/README.md (100%) rename python/ql/test/{experimental => library-tests}/dataflow/qll-private-imports/Test.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/qll-private-imports/Test.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/qll-private-imports/test.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/regression/custom_dataflow.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/regression/custom_dataflow.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/regression/dataflow.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/regression/dataflow.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/regression/module.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/regression/test.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/sensitive-data/TestSensitiveDataSources.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/sensitive-data/TestSensitiveDataSources.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/sensitive-data/test.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/strange-essaflow/test.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/strange-essaflow/testFlow.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/strange-essaflow/testFlow.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/summaries-checks/dummy.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/summaries-checks/invalid-spec.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/summaries-checks/invalid-spec.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/summaries-checks/missing-attribute-content.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/summaries-checks/missing-attribute-content.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/summaries/InlineTaintTest.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/summaries/InlineTaintTest.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/summaries/NormalTaintTrackingTest.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/summaries/NormalTaintTrackingTest.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/summaries/TestSummaries.qll (100%) rename python/ql/test/{experimental => library-tests}/dataflow/summaries/conflicting_summaries.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/summaries/extracted_package/__init__.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/summaries/extracted_package/functions.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/summaries/summaries.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/summaries/summaries.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/summaries/summaries.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/tainttracking/TestTaintLib.qll (100%) rename python/ql/test/{experimental => library-tests}/dataflow/tainttracking/basic/GlobalTaintTracking.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/tainttracking/basic/GlobalTaintTracking.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/tainttracking/basic/LocalTaintStep.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/tainttracking/basic/LocalTaintStep.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/tainttracking/basic/test.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/tainttracking/commonSanitizer/InlineTaintTest.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/tainttracking/commonSanitizer/InlineTaintTest.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/tainttracking/commonSanitizer/test_string_const_compare.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/tainttracking/customSanitizer/InlineTaintTest.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/tainttracking/customSanitizer/InlineTaintTest.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/tainttracking/customSanitizer/test.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/tainttracking/customSanitizer/test_logical.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/tainttracking/customSanitizer/test_reference.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/tainttracking/defaultAdditionalTaintStep-py3/InlineTaintTest.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/tainttracking/defaultAdditionalTaintStep-py3/InlineTaintTest.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/tainttracking/defaultAdditionalTaintStep-py3/options (100%) rename python/ql/test/{experimental => library-tests}/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_collections.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_pathlib.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_string.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_unpacking.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/tainttracking/defaultAdditionalTaintStep/InlineTaintTest.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/tainttracking/defaultAdditionalTaintStep/InlineTaintTest.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/tainttracking/defaultAdditionalTaintStep/test_async.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/tainttracking/defaultAdditionalTaintStep/test_attr.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/tainttracking/defaultAdditionalTaintStep/test_for.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/tainttracking/defaultAdditionalTaintStep/test_string.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/tainttracking/defaultAdditionalTaintStep/test_unpacking.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/tainttracking/defaultAdditionalTaintStep/test_with.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/tainttracking/generator-flow/InlineTaintTest.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/tainttracking/generator-flow/InlineTaintTest.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/tainttracking/generator-flow/NormalDataflowTest.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/tainttracking/generator-flow/NormalDataflowTest.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/tainttracking/generator-flow/test_dataflow.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/tainttracking/generator-flow/test_taint.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/tainttracking/taintlib.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/tainttracking/unwanted-global-flow/InlineTaintTest.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/tainttracking/unwanted-global-flow/InlineTaintTest.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/tainttracking/unwanted-global-flow/test.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/testConfig.qll (100%) rename python/ql/test/{experimental => library-tests}/dataflow/testTaintConfig.qll (100%) rename python/ql/test/{experimental => library-tests}/dataflow/testlib.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/typetracking-summaries/TestSummaries.qll (100%) rename python/ql/test/{experimental => library-tests}/dataflow/typetracking-summaries/summaries.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/typetracking-summaries/tracked.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/typetracking-summaries/tracked.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/typetracking/attribute_tests.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/typetracking/content_test.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/typetracking/import_as_attr.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/typetracking/import_as_attr_dotted.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/typetracking/moduleattr.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/typetracking/moduleattr.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/typetracking/multiple_callables.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/typetracking/mymodule.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/typetracking/test.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/typetracking/tracked.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/typetracking/tracked.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/typetracking_imports/README.md (100%) rename python/ql/test/{experimental => library-tests}/dataflow/typetracking_imports/highlight_problem.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/typetracking_imports/highlight_problem.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/typetracking_imports/options (100%) rename python/ql/test/{experimental => library-tests}/dataflow/typetracking_imports/pkg/__init__.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/typetracking_imports/pkg/alias_only_direct.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/typetracking_imports/pkg/alias_problem.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/typetracking_imports/pkg/alias_problem_fixed.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/typetracking_imports/pkg/alias_star.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/typetracking_imports/pkg/foo_def.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/typetracking_imports/pkg/other.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/typetracking_imports/pkg/problem_absolute_import.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/typetracking_imports/pkg/use.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/typetracking_imports/pkg/works_absolute_import.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/typetracking_imports/tracked.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/typetracking_imports/tracked.qlref (100%) rename python/ql/test/{experimental => library-tests}/dataflow/use-use-flow/read_explosion.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/use-use-flow/use-use-counts.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/use-use-flow/use-use-counts.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/validTest.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/variable-capture/CaptureTest.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/variable-capture/CaptureTest.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/variable-capture/by_value.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/variable-capture/dataflow-capture-consistency.expected (100%) rename python/ql/test/{experimental => library-tests}/dataflow/variable-capture/dataflow-capture-consistency.ql (100%) rename python/ql/test/{experimental => library-tests}/dataflow/variable-capture/dict.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/variable-capture/global.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/variable-capture/in.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/variable-capture/nonlocal.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/variable-capture/test_collections.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/variable-capture/test_fields.py (100%) rename python/ql/test/{experimental => library-tests}/dataflow/variable-capture/test_library_calls.py (100%) diff --git a/python/ql/test/experimental/dataflow/TestUtil/DataflowQueryTest.qll b/python/ql/test/library-tests/dataflow/TestUtil/DataflowQueryTest.qll similarity index 100% rename from python/ql/test/experimental/dataflow/TestUtil/DataflowQueryTest.qll rename to python/ql/test/library-tests/dataflow/TestUtil/DataflowQueryTest.qll diff --git a/python/ql/test/experimental/dataflow/TestUtil/FlowTest.qll b/python/ql/test/library-tests/dataflow/TestUtil/FlowTest.qll similarity index 100% rename from python/ql/test/experimental/dataflow/TestUtil/FlowTest.qll rename to python/ql/test/library-tests/dataflow/TestUtil/FlowTest.qll diff --git a/python/ql/test/experimental/dataflow/TestUtil/LocalFlowStepTest.qll b/python/ql/test/library-tests/dataflow/TestUtil/LocalFlowStepTest.qll similarity index 100% rename from python/ql/test/experimental/dataflow/TestUtil/LocalFlowStepTest.qll rename to python/ql/test/library-tests/dataflow/TestUtil/LocalFlowStepTest.qll diff --git a/python/ql/test/experimental/dataflow/TestUtil/MaximalFlowTest.qll b/python/ql/test/library-tests/dataflow/TestUtil/MaximalFlowTest.qll similarity index 100% rename from python/ql/test/experimental/dataflow/TestUtil/MaximalFlowTest.qll rename to python/ql/test/library-tests/dataflow/TestUtil/MaximalFlowTest.qll diff --git a/python/ql/test/experimental/dataflow/TestUtil/NormalDataflowTest.qll b/python/ql/test/library-tests/dataflow/TestUtil/NormalDataflowTest.qll similarity index 100% rename from python/ql/test/experimental/dataflow/TestUtil/NormalDataflowTest.qll rename to python/ql/test/library-tests/dataflow/TestUtil/NormalDataflowTest.qll diff --git a/python/ql/test/experimental/dataflow/TestUtil/NormalTaintTrackingTest.qll b/python/ql/test/library-tests/dataflow/TestUtil/NormalTaintTrackingTest.qll similarity index 100% rename from python/ql/test/experimental/dataflow/TestUtil/NormalTaintTrackingTest.qll rename to python/ql/test/library-tests/dataflow/TestUtil/NormalTaintTrackingTest.qll diff --git a/python/ql/test/experimental/dataflow/TestUtil/RoutingTest.qll b/python/ql/test/library-tests/dataflow/TestUtil/RoutingTest.qll similarity index 100% rename from python/ql/test/experimental/dataflow/TestUtil/RoutingTest.qll rename to python/ql/test/library-tests/dataflow/TestUtil/RoutingTest.qll diff --git a/python/ql/test/experimental/dataflow/TestUtil/UnresolvedCalls.qll b/python/ql/test/library-tests/dataflow/TestUtil/UnresolvedCalls.qll similarity index 100% rename from python/ql/test/experimental/dataflow/TestUtil/UnresolvedCalls.qll rename to python/ql/test/library-tests/dataflow/TestUtil/UnresolvedCalls.qll diff --git a/python/ql/test/experimental/dataflow/basic/allFlowsConfig.qll b/python/ql/test/library-tests/dataflow/basic/allFlowsConfig.qll similarity index 100% rename from python/ql/test/experimental/dataflow/basic/allFlowsConfig.qll rename to python/ql/test/library-tests/dataflow/basic/allFlowsConfig.qll diff --git a/python/ql/test/experimental/dataflow/basic/callGraph.expected b/python/ql/test/library-tests/dataflow/basic/callGraph.expected similarity index 100% rename from python/ql/test/experimental/dataflow/basic/callGraph.expected rename to python/ql/test/library-tests/dataflow/basic/callGraph.expected diff --git a/python/ql/test/experimental/dataflow/basic/callGraph.ql b/python/ql/test/library-tests/dataflow/basic/callGraph.ql similarity index 100% rename from python/ql/test/experimental/dataflow/basic/callGraph.ql rename to python/ql/test/library-tests/dataflow/basic/callGraph.ql diff --git a/python/ql/test/experimental/dataflow/basic/callGraphSinks.expected b/python/ql/test/library-tests/dataflow/basic/callGraphSinks.expected similarity index 100% rename from python/ql/test/experimental/dataflow/basic/callGraphSinks.expected rename to python/ql/test/library-tests/dataflow/basic/callGraphSinks.expected diff --git a/python/ql/test/experimental/dataflow/basic/callGraphSinks.ql b/python/ql/test/library-tests/dataflow/basic/callGraphSinks.ql similarity index 100% rename from python/ql/test/experimental/dataflow/basic/callGraphSinks.ql rename to python/ql/test/library-tests/dataflow/basic/callGraphSinks.ql diff --git a/python/ql/test/experimental/dataflow/basic/callGraphSources.expected b/python/ql/test/library-tests/dataflow/basic/callGraphSources.expected similarity index 100% rename from python/ql/test/experimental/dataflow/basic/callGraphSources.expected rename to python/ql/test/library-tests/dataflow/basic/callGraphSources.expected diff --git a/python/ql/test/experimental/dataflow/basic/callGraphSources.ql b/python/ql/test/library-tests/dataflow/basic/callGraphSources.ql similarity index 100% rename from python/ql/test/experimental/dataflow/basic/callGraphSources.ql rename to python/ql/test/library-tests/dataflow/basic/callGraphSources.ql diff --git a/python/ql/test/experimental/dataflow/basic/global.expected b/python/ql/test/library-tests/dataflow/basic/global.expected similarity index 100% rename from python/ql/test/experimental/dataflow/basic/global.expected rename to python/ql/test/library-tests/dataflow/basic/global.expected diff --git a/python/ql/test/experimental/dataflow/basic/global.ql b/python/ql/test/library-tests/dataflow/basic/global.ql similarity index 100% rename from python/ql/test/experimental/dataflow/basic/global.ql rename to python/ql/test/library-tests/dataflow/basic/global.ql diff --git a/python/ql/test/experimental/dataflow/basic/globalStep.expected b/python/ql/test/library-tests/dataflow/basic/globalStep.expected similarity index 100% rename from python/ql/test/experimental/dataflow/basic/globalStep.expected rename to python/ql/test/library-tests/dataflow/basic/globalStep.expected diff --git a/python/ql/test/experimental/dataflow/basic/globalStep.ql b/python/ql/test/library-tests/dataflow/basic/globalStep.ql similarity index 100% rename from python/ql/test/experimental/dataflow/basic/globalStep.ql rename to python/ql/test/library-tests/dataflow/basic/globalStep.ql diff --git a/python/ql/test/experimental/dataflow/basic/local.expected b/python/ql/test/library-tests/dataflow/basic/local.expected similarity index 100% rename from python/ql/test/experimental/dataflow/basic/local.expected rename to python/ql/test/library-tests/dataflow/basic/local.expected diff --git a/python/ql/test/experimental/dataflow/basic/local.ql b/python/ql/test/library-tests/dataflow/basic/local.ql similarity index 100% rename from python/ql/test/experimental/dataflow/basic/local.ql rename to python/ql/test/library-tests/dataflow/basic/local.ql diff --git a/python/ql/test/experimental/dataflow/basic/localFlowStepTest.expected b/python/ql/test/library-tests/dataflow/basic/localFlowStepTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/basic/localFlowStepTest.expected rename to python/ql/test/library-tests/dataflow/basic/localFlowStepTest.expected diff --git a/python/ql/test/experimental/dataflow/basic/localFlowStepTest.ql b/python/ql/test/library-tests/dataflow/basic/localFlowStepTest.ql similarity index 100% rename from python/ql/test/experimental/dataflow/basic/localFlowStepTest.ql rename to python/ql/test/library-tests/dataflow/basic/localFlowStepTest.ql diff --git a/python/ql/test/experimental/dataflow/basic/localStep.expected b/python/ql/test/library-tests/dataflow/basic/localStep.expected similarity index 100% rename from python/ql/test/experimental/dataflow/basic/localStep.expected rename to python/ql/test/library-tests/dataflow/basic/localStep.expected diff --git a/python/ql/test/experimental/dataflow/basic/localStep.ql b/python/ql/test/library-tests/dataflow/basic/localStep.ql similarity index 100% rename from python/ql/test/experimental/dataflow/basic/localStep.ql rename to python/ql/test/library-tests/dataflow/basic/localStep.ql diff --git a/python/ql/test/experimental/dataflow/basic/maximalFlowTest.expected b/python/ql/test/library-tests/dataflow/basic/maximalFlowTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/basic/maximalFlowTest.expected rename to python/ql/test/library-tests/dataflow/basic/maximalFlowTest.expected diff --git a/python/ql/test/experimental/dataflow/basic/maximalFlowTest.ql b/python/ql/test/library-tests/dataflow/basic/maximalFlowTest.ql similarity index 100% rename from python/ql/test/experimental/dataflow/basic/maximalFlowTest.ql rename to python/ql/test/library-tests/dataflow/basic/maximalFlowTest.ql diff --git a/python/ql/test/experimental/dataflow/basic/maximalFlows.expected b/python/ql/test/library-tests/dataflow/basic/maximalFlows.expected similarity index 100% rename from python/ql/test/experimental/dataflow/basic/maximalFlows.expected rename to python/ql/test/library-tests/dataflow/basic/maximalFlows.expected diff --git a/python/ql/test/experimental/dataflow/basic/maximalFlows.ql b/python/ql/test/library-tests/dataflow/basic/maximalFlows.ql similarity index 100% rename from python/ql/test/experimental/dataflow/basic/maximalFlows.ql rename to python/ql/test/library-tests/dataflow/basic/maximalFlows.ql diff --git a/python/ql/test/experimental/dataflow/basic/maximalFlowsConfig.qll b/python/ql/test/library-tests/dataflow/basic/maximalFlowsConfig.qll similarity index 100% rename from python/ql/test/experimental/dataflow/basic/maximalFlowsConfig.qll rename to python/ql/test/library-tests/dataflow/basic/maximalFlowsConfig.qll diff --git a/python/ql/test/experimental/dataflow/basic/sinks.expected b/python/ql/test/library-tests/dataflow/basic/sinks.expected similarity index 100% rename from python/ql/test/experimental/dataflow/basic/sinks.expected rename to python/ql/test/library-tests/dataflow/basic/sinks.expected diff --git a/python/ql/test/experimental/dataflow/basic/sinks.ql b/python/ql/test/library-tests/dataflow/basic/sinks.ql similarity index 100% rename from python/ql/test/experimental/dataflow/basic/sinks.ql rename to python/ql/test/library-tests/dataflow/basic/sinks.ql diff --git a/python/ql/test/experimental/dataflow/basic/sources.expected b/python/ql/test/library-tests/dataflow/basic/sources.expected similarity index 100% rename from python/ql/test/experimental/dataflow/basic/sources.expected rename to python/ql/test/library-tests/dataflow/basic/sources.expected diff --git a/python/ql/test/experimental/dataflow/basic/sources.ql b/python/ql/test/library-tests/dataflow/basic/sources.ql similarity index 100% rename from python/ql/test/experimental/dataflow/basic/sources.ql rename to python/ql/test/library-tests/dataflow/basic/sources.ql diff --git a/python/ql/test/experimental/dataflow/basic/test.py b/python/ql/test/library-tests/dataflow/basic/test.py similarity index 100% rename from python/ql/test/experimental/dataflow/basic/test.py rename to python/ql/test/library-tests/dataflow/basic/test.py diff --git a/python/ql/test/experimental/dataflow/callGraphConfig.qll b/python/ql/test/library-tests/dataflow/callGraphConfig.qll similarity index 100% rename from python/ql/test/experimental/dataflow/callGraphConfig.qll rename to python/ql/test/library-tests/dataflow/callGraphConfig.qll diff --git a/python/ql/test/experimental/dataflow/callgraph_crosstalk/Arguments.expected b/python/ql/test/library-tests/dataflow/callgraph_crosstalk/Arguments.expected similarity index 100% rename from python/ql/test/experimental/dataflow/callgraph_crosstalk/Arguments.expected rename to python/ql/test/library-tests/dataflow/callgraph_crosstalk/Arguments.expected diff --git a/python/ql/test/experimental/dataflow/callgraph_crosstalk/Arguments.ql b/python/ql/test/library-tests/dataflow/callgraph_crosstalk/Arguments.ql similarity index 100% rename from python/ql/test/experimental/dataflow/callgraph_crosstalk/Arguments.ql rename to python/ql/test/library-tests/dataflow/callgraph_crosstalk/Arguments.ql diff --git a/python/ql/test/experimental/dataflow/callgraph_crosstalk/options b/python/ql/test/library-tests/dataflow/callgraph_crosstalk/options similarity index 100% rename from python/ql/test/experimental/dataflow/callgraph_crosstalk/options rename to python/ql/test/library-tests/dataflow/callgraph_crosstalk/options diff --git a/python/ql/test/experimental/dataflow/callgraph_crosstalk/test.py b/python/ql/test/library-tests/dataflow/callgraph_crosstalk/test.py similarity index 100% rename from python/ql/test/experimental/dataflow/callgraph_crosstalk/test.py rename to python/ql/test/library-tests/dataflow/callgraph_crosstalk/test.py diff --git a/python/ql/test/experimental/dataflow/calls/DataFlowCallTest.expected b/python/ql/test/library-tests/dataflow/calls/DataFlowCallTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/calls/DataFlowCallTest.expected rename to python/ql/test/library-tests/dataflow/calls/DataFlowCallTest.expected diff --git a/python/ql/test/experimental/dataflow/calls/DataFlowCallTest.ql b/python/ql/test/library-tests/dataflow/calls/DataFlowCallTest.ql similarity index 100% rename from python/ql/test/experimental/dataflow/calls/DataFlowCallTest.ql rename to python/ql/test/library-tests/dataflow/calls/DataFlowCallTest.ql diff --git a/python/ql/test/experimental/dataflow/calls/new_cls_param.py b/python/ql/test/library-tests/dataflow/calls/new_cls_param.py similarity index 100% rename from python/ql/test/experimental/dataflow/calls/new_cls_param.py rename to python/ql/test/library-tests/dataflow/calls/new_cls_param.py diff --git a/python/ql/test/experimental/dataflow/calls/test.py b/python/ql/test/library-tests/dataflow/calls/test.py similarity index 100% rename from python/ql/test/experimental/dataflow/calls/test.py rename to python/ql/test/library-tests/dataflow/calls/test.py diff --git a/python/ql/test/experimental/dataflow/consistency/class_scope.py b/python/ql/test/library-tests/dataflow/consistency/class_scope.py similarity index 100% rename from python/ql/test/experimental/dataflow/consistency/class_scope.py rename to python/ql/test/library-tests/dataflow/consistency/class_scope.py diff --git a/python/ql/test/experimental/dataflow/consistency/modeling-consistency.expected b/python/ql/test/library-tests/dataflow/consistency/modeling-consistency.expected similarity index 100% rename from python/ql/test/experimental/dataflow/consistency/modeling-consistency.expected rename to python/ql/test/library-tests/dataflow/consistency/modeling-consistency.expected diff --git a/python/ql/test/experimental/dataflow/consistency/modeling-consistency.ql b/python/ql/test/library-tests/dataflow/consistency/modeling-consistency.ql similarity index 100% rename from python/ql/test/experimental/dataflow/consistency/modeling-consistency.ql rename to python/ql/test/library-tests/dataflow/consistency/modeling-consistency.ql diff --git a/python/ql/test/experimental/dataflow/consistency/module.py b/python/ql/test/library-tests/dataflow/consistency/module.py similarity index 100% rename from python/ql/test/experimental/dataflow/consistency/module.py rename to python/ql/test/library-tests/dataflow/consistency/module.py diff --git a/python/ql/test/experimental/dataflow/consistency/test.py b/python/ql/test/library-tests/dataflow/consistency/test.py similarity index 100% rename from python/ql/test/experimental/dataflow/consistency/test.py rename to python/ql/test/library-tests/dataflow/consistency/test.py diff --git a/python/ql/test/experimental/dataflow/coverage-py2/argumentRoutingTest.expected b/python/ql/test/library-tests/dataflow/coverage-py2/argumentRoutingTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/coverage-py2/argumentRoutingTest.expected rename to python/ql/test/library-tests/dataflow/coverage-py2/argumentRoutingTest.expected diff --git a/python/ql/test/experimental/dataflow/coverage-py2/argumentRoutingTest.qlref b/python/ql/test/library-tests/dataflow/coverage-py2/argumentRoutingTest.qlref similarity index 100% rename from python/ql/test/experimental/dataflow/coverage-py2/argumentRoutingTest.qlref rename to python/ql/test/library-tests/dataflow/coverage-py2/argumentRoutingTest.qlref diff --git a/python/ql/test/experimental/dataflow/coverage-py2/classes.py b/python/ql/test/library-tests/dataflow/coverage-py2/classes.py similarity index 100% rename from python/ql/test/experimental/dataflow/coverage-py2/classes.py rename to python/ql/test/library-tests/dataflow/coverage-py2/classes.py diff --git a/python/ql/test/experimental/dataflow/coverage-py2/options b/python/ql/test/library-tests/dataflow/coverage-py2/options similarity index 100% rename from python/ql/test/experimental/dataflow/coverage-py2/options rename to python/ql/test/library-tests/dataflow/coverage-py2/options diff --git a/python/ql/test/experimental/dataflow/coverage-py3/argumentRoutingTest.expected b/python/ql/test/library-tests/dataflow/coverage-py3/argumentRoutingTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/coverage-py3/argumentRoutingTest.expected rename to python/ql/test/library-tests/dataflow/coverage-py3/argumentRoutingTest.expected diff --git a/python/ql/test/experimental/dataflow/coverage-py3/argumentRoutingTest.qlref b/python/ql/test/library-tests/dataflow/coverage-py3/argumentRoutingTest.qlref similarity index 100% rename from python/ql/test/experimental/dataflow/coverage-py3/argumentRoutingTest.qlref rename to python/ql/test/library-tests/dataflow/coverage-py3/argumentRoutingTest.qlref diff --git a/python/ql/test/experimental/dataflow/coverage-py3/classes.py b/python/ql/test/library-tests/dataflow/coverage-py3/classes.py similarity index 100% rename from python/ql/test/experimental/dataflow/coverage-py3/classes.py rename to python/ql/test/library-tests/dataflow/coverage-py3/classes.py diff --git a/python/ql/test/experimental/dataflow/coverage-py3/options b/python/ql/test/library-tests/dataflow/coverage-py3/options similarity index 100% rename from python/ql/test/experimental/dataflow/coverage-py3/options rename to python/ql/test/library-tests/dataflow/coverage-py3/options diff --git a/python/ql/test/experimental/dataflow/coverage/NormalDataflowTest.expected b/python/ql/test/library-tests/dataflow/coverage/NormalDataflowTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/coverage/NormalDataflowTest.expected rename to python/ql/test/library-tests/dataflow/coverage/NormalDataflowTest.expected diff --git a/python/ql/test/experimental/dataflow/coverage/NormalDataflowTest.ql b/python/ql/test/library-tests/dataflow/coverage/NormalDataflowTest.ql similarity index 100% rename from python/ql/test/experimental/dataflow/coverage/NormalDataflowTest.ql rename to python/ql/test/library-tests/dataflow/coverage/NormalDataflowTest.ql diff --git a/python/ql/test/experimental/dataflow/coverage/argumentPassing.py b/python/ql/test/library-tests/dataflow/coverage/argumentPassing.py similarity index 100% rename from python/ql/test/experimental/dataflow/coverage/argumentPassing.py rename to python/ql/test/library-tests/dataflow/coverage/argumentPassing.py diff --git a/python/ql/test/experimental/dataflow/coverage/argumentPassing_bad_flow_test.py b/python/ql/test/library-tests/dataflow/coverage/argumentPassing_bad_flow_test.py similarity index 100% rename from python/ql/test/experimental/dataflow/coverage/argumentPassing_bad_flow_test.py rename to python/ql/test/library-tests/dataflow/coverage/argumentPassing_bad_flow_test.py diff --git a/python/ql/test/experimental/dataflow/coverage/argumentRoutingTest.expected b/python/ql/test/library-tests/dataflow/coverage/argumentRoutingTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/coverage/argumentRoutingTest.expected rename to python/ql/test/library-tests/dataflow/coverage/argumentRoutingTest.expected diff --git a/python/ql/test/experimental/dataflow/coverage/argumentRoutingTest.ql b/python/ql/test/library-tests/dataflow/coverage/argumentRoutingTest.ql similarity index 100% rename from python/ql/test/experimental/dataflow/coverage/argumentRoutingTest.ql rename to python/ql/test/library-tests/dataflow/coverage/argumentRoutingTest.ql diff --git a/python/ql/test/experimental/dataflow/coverage/classes.py b/python/ql/test/library-tests/dataflow/coverage/classes.py similarity index 100% rename from python/ql/test/experimental/dataflow/coverage/classes.py rename to python/ql/test/library-tests/dataflow/coverage/classes.py diff --git a/python/ql/test/experimental/dataflow/coverage/datamodel.py b/python/ql/test/library-tests/dataflow/coverage/datamodel.py similarity index 100% rename from python/ql/test/experimental/dataflow/coverage/datamodel.py rename to python/ql/test/library-tests/dataflow/coverage/datamodel.py diff --git a/python/ql/test/experimental/dataflow/coverage/localFlow.expected b/python/ql/test/library-tests/dataflow/coverage/localFlow.expected similarity index 100% rename from python/ql/test/experimental/dataflow/coverage/localFlow.expected rename to python/ql/test/library-tests/dataflow/coverage/localFlow.expected diff --git a/python/ql/test/experimental/dataflow/coverage/localFlow.ql b/python/ql/test/library-tests/dataflow/coverage/localFlow.ql similarity index 100% rename from python/ql/test/experimental/dataflow/coverage/localFlow.ql rename to python/ql/test/library-tests/dataflow/coverage/localFlow.ql diff --git a/python/ql/test/experimental/dataflow/coverage/loops.py b/python/ql/test/library-tests/dataflow/coverage/loops.py similarity index 100% rename from python/ql/test/experimental/dataflow/coverage/loops.py rename to python/ql/test/library-tests/dataflow/coverage/loops.py diff --git a/python/ql/test/experimental/dataflow/coverage/module_level.py b/python/ql/test/library-tests/dataflow/coverage/module_level.py similarity index 100% rename from python/ql/test/experimental/dataflow/coverage/module_level.py rename to python/ql/test/library-tests/dataflow/coverage/module_level.py diff --git a/python/ql/test/experimental/dataflow/coverage/test.py b/python/ql/test/library-tests/dataflow/coverage/test.py similarity index 100% rename from python/ql/test/experimental/dataflow/coverage/test.py rename to python/ql/test/library-tests/dataflow/coverage/test.py diff --git a/python/ql/test/experimental/dataflow/coverage/test_builtins.py b/python/ql/test/library-tests/dataflow/coverage/test_builtins.py similarity index 100% rename from python/ql/test/experimental/dataflow/coverage/test_builtins.py rename to python/ql/test/library-tests/dataflow/coverage/test_builtins.py diff --git a/python/ql/test/experimental/dataflow/def-use-flow/def_use_counts.expected b/python/ql/test/library-tests/dataflow/def-use-flow/def_use_counts.expected similarity index 100% rename from python/ql/test/experimental/dataflow/def-use-flow/def_use_counts.expected rename to python/ql/test/library-tests/dataflow/def-use-flow/def_use_counts.expected diff --git a/python/ql/test/experimental/dataflow/def-use-flow/def_use_counts.ql b/python/ql/test/library-tests/dataflow/def-use-flow/def_use_counts.ql similarity index 100% rename from python/ql/test/experimental/dataflow/def-use-flow/def_use_counts.ql rename to python/ql/test/library-tests/dataflow/def-use-flow/def_use_counts.ql diff --git a/python/ql/test/experimental/dataflow/def-use-flow/def_use_flow.py b/python/ql/test/library-tests/dataflow/def-use-flow/def_use_flow.py similarity index 100% rename from python/ql/test/experimental/dataflow/def-use-flow/def_use_flow.py rename to python/ql/test/library-tests/dataflow/def-use-flow/def_use_flow.py diff --git a/python/ql/test/experimental/dataflow/enclosing-callable/EnclosingCallable.expected b/python/ql/test/library-tests/dataflow/enclosing-callable/EnclosingCallable.expected similarity index 100% rename from python/ql/test/experimental/dataflow/enclosing-callable/EnclosingCallable.expected rename to python/ql/test/library-tests/dataflow/enclosing-callable/EnclosingCallable.expected diff --git a/python/ql/test/experimental/dataflow/enclosing-callable/EnclosingCallable.ql b/python/ql/test/library-tests/dataflow/enclosing-callable/EnclosingCallable.ql similarity index 100% rename from python/ql/test/experimental/dataflow/enclosing-callable/EnclosingCallable.ql rename to python/ql/test/library-tests/dataflow/enclosing-callable/EnclosingCallable.ql diff --git a/python/ql/test/experimental/dataflow/enclosing-callable/class_example.py b/python/ql/test/library-tests/dataflow/enclosing-callable/class_example.py similarity index 100% rename from python/ql/test/experimental/dataflow/enclosing-callable/class_example.py rename to python/ql/test/library-tests/dataflow/enclosing-callable/class_example.py diff --git a/python/ql/test/experimental/dataflow/enclosing-callable/generator.py b/python/ql/test/library-tests/dataflow/enclosing-callable/generator.py similarity index 100% rename from python/ql/test/experimental/dataflow/enclosing-callable/generator.py rename to python/ql/test/library-tests/dataflow/enclosing-callable/generator.py diff --git a/python/ql/test/experimental/dataflow/exceptions/NormalDataflowTest.expected b/python/ql/test/library-tests/dataflow/exceptions/NormalDataflowTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/exceptions/NormalDataflowTest.expected rename to python/ql/test/library-tests/dataflow/exceptions/NormalDataflowTest.expected diff --git a/python/ql/test/experimental/dataflow/exceptions/NormalDataflowTest.ql b/python/ql/test/library-tests/dataflow/exceptions/NormalDataflowTest.ql similarity index 100% rename from python/ql/test/experimental/dataflow/exceptions/NormalDataflowTest.ql rename to python/ql/test/library-tests/dataflow/exceptions/NormalDataflowTest.ql diff --git a/python/ql/test/experimental/dataflow/exceptions/test.py b/python/ql/test/library-tests/dataflow/exceptions/test.py similarity index 100% rename from python/ql/test/experimental/dataflow/exceptions/test.py rename to python/ql/test/library-tests/dataflow/exceptions/test.py diff --git a/python/ql/test/experimental/dataflow/exceptions/test_group.py b/python/ql/test/library-tests/dataflow/exceptions/test_group.py similarity index 100% rename from python/ql/test/experimental/dataflow/exceptions/test_group.py rename to python/ql/test/library-tests/dataflow/exceptions/test_group.py diff --git a/python/ql/test/experimental/dataflow/fieldflow/NormalDataflowTest.expected b/python/ql/test/library-tests/dataflow/fieldflow/NormalDataflowTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/fieldflow/NormalDataflowTest.expected rename to python/ql/test/library-tests/dataflow/fieldflow/NormalDataflowTest.expected diff --git a/python/ql/test/experimental/dataflow/fieldflow/NormalDataflowTest.ql b/python/ql/test/library-tests/dataflow/fieldflow/NormalDataflowTest.ql similarity index 100% rename from python/ql/test/experimental/dataflow/fieldflow/NormalDataflowTest.ql rename to python/ql/test/library-tests/dataflow/fieldflow/NormalDataflowTest.ql diff --git a/python/ql/test/experimental/dataflow/fieldflow/UnresolvedCalls.expected b/python/ql/test/library-tests/dataflow/fieldflow/UnresolvedCalls.expected similarity index 100% rename from python/ql/test/experimental/dataflow/fieldflow/UnresolvedCalls.expected rename to python/ql/test/library-tests/dataflow/fieldflow/UnresolvedCalls.expected diff --git a/python/ql/test/experimental/dataflow/fieldflow/UnresolvedCalls.ql b/python/ql/test/library-tests/dataflow/fieldflow/UnresolvedCalls.ql similarity index 100% rename from python/ql/test/experimental/dataflow/fieldflow/UnresolvedCalls.ql rename to python/ql/test/library-tests/dataflow/fieldflow/UnresolvedCalls.ql diff --git a/python/ql/test/experimental/dataflow/fieldflow/options b/python/ql/test/library-tests/dataflow/fieldflow/options similarity index 100% rename from python/ql/test/experimental/dataflow/fieldflow/options rename to python/ql/test/library-tests/dataflow/fieldflow/options diff --git a/python/ql/test/experimental/dataflow/fieldflow/test.py b/python/ql/test/library-tests/dataflow/fieldflow/test.py similarity index 100% rename from python/ql/test/experimental/dataflow/fieldflow/test.py rename to python/ql/test/library-tests/dataflow/fieldflow/test.py diff --git a/python/ql/test/experimental/dataflow/fieldflow/test_dict.py b/python/ql/test/library-tests/dataflow/fieldflow/test_dict.py similarity index 100% rename from python/ql/test/experimental/dataflow/fieldflow/test_dict.py rename to python/ql/test/library-tests/dataflow/fieldflow/test_dict.py diff --git a/python/ql/test/experimental/dataflow/fieldflow/test_global.py b/python/ql/test/library-tests/dataflow/fieldflow/test_global.py similarity index 100% rename from python/ql/test/experimental/dataflow/fieldflow/test_global.py rename to python/ql/test/library-tests/dataflow/fieldflow/test_global.py diff --git a/python/ql/test/experimental/dataflow/global-flow/accesses.expected b/python/ql/test/library-tests/dataflow/global-flow/accesses.expected similarity index 100% rename from python/ql/test/experimental/dataflow/global-flow/accesses.expected rename to python/ql/test/library-tests/dataflow/global-flow/accesses.expected diff --git a/python/ql/test/experimental/dataflow/global-flow/accesses.ql b/python/ql/test/library-tests/dataflow/global-flow/accesses.ql similarity index 100% rename from python/ql/test/experimental/dataflow/global-flow/accesses.ql rename to python/ql/test/library-tests/dataflow/global-flow/accesses.ql diff --git a/python/ql/test/experimental/dataflow/global-flow/known.py b/python/ql/test/library-tests/dataflow/global-flow/known.py similarity index 100% rename from python/ql/test/experimental/dataflow/global-flow/known.py rename to python/ql/test/library-tests/dataflow/global-flow/known.py diff --git a/python/ql/test/experimental/dataflow/global-flow/test.py b/python/ql/test/library-tests/dataflow/global-flow/test.py similarity index 100% rename from python/ql/test/experimental/dataflow/global-flow/test.py rename to python/ql/test/library-tests/dataflow/global-flow/test.py diff --git a/python/ql/test/experimental/dataflow/import-star/deux.py b/python/ql/test/library-tests/dataflow/import-star/deux.py similarity index 100% rename from python/ql/test/experimental/dataflow/import-star/deux.py rename to python/ql/test/library-tests/dataflow/import-star/deux.py diff --git a/python/ql/test/experimental/dataflow/import-star/global.expected b/python/ql/test/library-tests/dataflow/import-star/global.expected similarity index 100% rename from python/ql/test/experimental/dataflow/import-star/global.expected rename to python/ql/test/library-tests/dataflow/import-star/global.expected diff --git a/python/ql/test/experimental/dataflow/import-star/global.ql b/python/ql/test/library-tests/dataflow/import-star/global.ql similarity index 100% rename from python/ql/test/experimental/dataflow/import-star/global.ql rename to python/ql/test/library-tests/dataflow/import-star/global.ql diff --git a/python/ql/test/experimental/dataflow/import-star/one.py b/python/ql/test/library-tests/dataflow/import-star/one.py similarity index 100% rename from python/ql/test/experimental/dataflow/import-star/one.py rename to python/ql/test/library-tests/dataflow/import-star/one.py diff --git a/python/ql/test/experimental/dataflow/import-star/test1.py b/python/ql/test/library-tests/dataflow/import-star/test1.py similarity index 100% rename from python/ql/test/experimental/dataflow/import-star/test1.py rename to python/ql/test/library-tests/dataflow/import-star/test1.py diff --git a/python/ql/test/experimental/dataflow/import-star/test2.py b/python/ql/test/library-tests/dataflow/import-star/test2.py similarity index 100% rename from python/ql/test/experimental/dataflow/import-star/test2.py rename to python/ql/test/library-tests/dataflow/import-star/test2.py diff --git a/python/ql/test/experimental/dataflow/import-star/test3.py b/python/ql/test/library-tests/dataflow/import-star/test3.py similarity index 100% rename from python/ql/test/experimental/dataflow/import-star/test3.py rename to python/ql/test/library-tests/dataflow/import-star/test3.py diff --git a/python/ql/test/experimental/dataflow/import-star/three.py b/python/ql/test/library-tests/dataflow/import-star/three.py similarity index 100% rename from python/ql/test/experimental/dataflow/import-star/three.py rename to python/ql/test/library-tests/dataflow/import-star/three.py diff --git a/python/ql/test/experimental/dataflow/import-star/trois.py b/python/ql/test/library-tests/dataflow/import-star/trois.py similarity index 100% rename from python/ql/test/experimental/dataflow/import-star/trois.py rename to python/ql/test/library-tests/dataflow/import-star/trois.py diff --git a/python/ql/test/experimental/dataflow/import-star/two.py b/python/ql/test/library-tests/dataflow/import-star/two.py similarity index 100% rename from python/ql/test/experimental/dataflow/import-star/two.py rename to python/ql/test/library-tests/dataflow/import-star/two.py diff --git a/python/ql/test/experimental/dataflow/import-star/un.py b/python/ql/test/library-tests/dataflow/import-star/un.py similarity index 100% rename from python/ql/test/experimental/dataflow/import-star/un.py rename to python/ql/test/library-tests/dataflow/import-star/un.py diff --git a/python/ql/test/experimental/dataflow/match/NormalDataflowTest.expected b/python/ql/test/library-tests/dataflow/match/NormalDataflowTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/match/NormalDataflowTest.expected rename to python/ql/test/library-tests/dataflow/match/NormalDataflowTest.expected diff --git a/python/ql/test/experimental/dataflow/match/NormalDataflowTest.ql b/python/ql/test/library-tests/dataflow/match/NormalDataflowTest.ql similarity index 100% rename from python/ql/test/experimental/dataflow/match/NormalDataflowTest.ql rename to python/ql/test/library-tests/dataflow/match/NormalDataflowTest.ql diff --git a/python/ql/test/experimental/dataflow/match/test.py b/python/ql/test/library-tests/dataflow/match/test.py similarity index 100% rename from python/ql/test/experimental/dataflow/match/test.py rename to python/ql/test/library-tests/dataflow/match/test.py diff --git a/python/ql/test/experimental/dataflow/method-calls/test.expected b/python/ql/test/library-tests/dataflow/method-calls/test.expected similarity index 100% rename from python/ql/test/experimental/dataflow/method-calls/test.expected rename to python/ql/test/library-tests/dataflow/method-calls/test.expected diff --git a/python/ql/test/experimental/dataflow/method-calls/test.py b/python/ql/test/library-tests/dataflow/method-calls/test.py similarity index 100% rename from python/ql/test/experimental/dataflow/method-calls/test.py rename to python/ql/test/library-tests/dataflow/method-calls/test.py diff --git a/python/ql/test/experimental/dataflow/method-calls/test.ql b/python/ql/test/library-tests/dataflow/method-calls/test.ql similarity index 100% rename from python/ql/test/experimental/dataflow/method-calls/test.ql rename to python/ql/test/library-tests/dataflow/method-calls/test.ql diff --git a/python/ql/test/experimental/dataflow/model-summaries/InlineTaintTest.expected b/python/ql/test/library-tests/dataflow/model-summaries/InlineTaintTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/model-summaries/InlineTaintTest.expected rename to python/ql/test/library-tests/dataflow/model-summaries/InlineTaintTest.expected diff --git a/python/ql/test/experimental/dataflow/model-summaries/InlineTaintTest.ext.yml b/python/ql/test/library-tests/dataflow/model-summaries/InlineTaintTest.ext.yml similarity index 100% rename from python/ql/test/experimental/dataflow/model-summaries/InlineTaintTest.ext.yml rename to python/ql/test/library-tests/dataflow/model-summaries/InlineTaintTest.ext.yml diff --git a/python/ql/test/experimental/dataflow/model-summaries/InlineTaintTest.ql b/python/ql/test/library-tests/dataflow/model-summaries/InlineTaintTest.ql similarity index 100% rename from python/ql/test/experimental/dataflow/model-summaries/InlineTaintTest.ql rename to python/ql/test/library-tests/dataflow/model-summaries/InlineTaintTest.ql diff --git a/python/ql/test/experimental/dataflow/model-summaries/NormalDataflowTest.expected b/python/ql/test/library-tests/dataflow/model-summaries/NormalDataflowTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/model-summaries/NormalDataflowTest.expected rename to python/ql/test/library-tests/dataflow/model-summaries/NormalDataflowTest.expected diff --git a/python/ql/test/experimental/dataflow/model-summaries/NormalDataflowTest.ext.yml b/python/ql/test/library-tests/dataflow/model-summaries/NormalDataflowTest.ext.yml similarity index 100% rename from python/ql/test/experimental/dataflow/model-summaries/NormalDataflowTest.ext.yml rename to python/ql/test/library-tests/dataflow/model-summaries/NormalDataflowTest.ext.yml diff --git a/python/ql/test/experimental/dataflow/model-summaries/NormalDataflowTest.ql b/python/ql/test/library-tests/dataflow/model-summaries/NormalDataflowTest.ql similarity index 100% rename from python/ql/test/experimental/dataflow/model-summaries/NormalDataflowTest.ql rename to python/ql/test/library-tests/dataflow/model-summaries/NormalDataflowTest.ql diff --git a/python/ql/test/experimental/dataflow/model-summaries/model_summaries.py b/python/ql/test/library-tests/dataflow/model-summaries/model_summaries.py similarity index 100% rename from python/ql/test/experimental/dataflow/model-summaries/model_summaries.py rename to python/ql/test/library-tests/dataflow/model-summaries/model_summaries.py diff --git a/python/ql/test/experimental/dataflow/module-initialization/base.py b/python/ql/test/library-tests/dataflow/module-initialization/base.py similarity index 100% rename from python/ql/test/experimental/dataflow/module-initialization/base.py rename to python/ql/test/library-tests/dataflow/module-initialization/base.py diff --git a/python/ql/test/experimental/dataflow/module-initialization/localFlow.expected b/python/ql/test/library-tests/dataflow/module-initialization/localFlow.expected similarity index 100% rename from python/ql/test/experimental/dataflow/module-initialization/localFlow.expected rename to python/ql/test/library-tests/dataflow/module-initialization/localFlow.expected diff --git a/python/ql/test/experimental/dataflow/module-initialization/localFlow.ql b/python/ql/test/library-tests/dataflow/module-initialization/localFlow.ql similarity index 100% rename from python/ql/test/experimental/dataflow/module-initialization/localFlow.ql rename to python/ql/test/library-tests/dataflow/module-initialization/localFlow.ql diff --git a/python/ql/test/experimental/dataflow/module-initialization/m1.py b/python/ql/test/library-tests/dataflow/module-initialization/m1.py similarity index 100% rename from python/ql/test/experimental/dataflow/module-initialization/m1.py rename to python/ql/test/library-tests/dataflow/module-initialization/m1.py diff --git a/python/ql/test/experimental/dataflow/module-initialization/multiphase.py b/python/ql/test/library-tests/dataflow/module-initialization/multiphase.py similarity index 100% rename from python/ql/test/experimental/dataflow/module-initialization/multiphase.py rename to python/ql/test/library-tests/dataflow/module-initialization/multiphase.py diff --git a/python/ql/test/experimental/dataflow/module-initialization/test.py b/python/ql/test/library-tests/dataflow/module-initialization/test.py similarity index 100% rename from python/ql/test/experimental/dataflow/module-initialization/test.py rename to python/ql/test/library-tests/dataflow/module-initialization/test.py diff --git a/python/ql/test/experimental/dataflow/module-initialization/testOnce.py b/python/ql/test/library-tests/dataflow/module-initialization/testOnce.py similarity index 100% rename from python/ql/test/experimental/dataflow/module-initialization/testOnce.py rename to python/ql/test/library-tests/dataflow/module-initialization/testOnce.py diff --git a/python/ql/test/experimental/dataflow/options b/python/ql/test/library-tests/dataflow/options similarity index 100% rename from python/ql/test/experimental/dataflow/options rename to python/ql/test/library-tests/dataflow/options diff --git a/python/ql/test/experimental/dataflow/path-graph/PathNodes.expected b/python/ql/test/library-tests/dataflow/path-graph/PathNodes.expected similarity index 100% rename from python/ql/test/experimental/dataflow/path-graph/PathNodes.expected rename to python/ql/test/library-tests/dataflow/path-graph/PathNodes.expected diff --git a/python/ql/test/experimental/dataflow/path-graph/PathNodes.ql b/python/ql/test/library-tests/dataflow/path-graph/PathNodes.ql similarity index 100% rename from python/ql/test/experimental/dataflow/path-graph/PathNodes.ql rename to python/ql/test/library-tests/dataflow/path-graph/PathNodes.ql diff --git a/python/ql/test/experimental/dataflow/path-graph/test.py b/python/ql/test/library-tests/dataflow/path-graph/test.py similarity index 100% rename from python/ql/test/experimental/dataflow/path-graph/test.py rename to python/ql/test/library-tests/dataflow/path-graph/test.py diff --git a/python/ql/test/experimental/dataflow/pep_328/__init__.py b/python/ql/test/library-tests/dataflow/pep_328/__init__.py similarity index 100% rename from python/ql/test/experimental/dataflow/pep_328/__init__.py rename to python/ql/test/library-tests/dataflow/pep_328/__init__.py diff --git a/python/ql/test/experimental/dataflow/pep_328/package/__init__.py b/python/ql/test/library-tests/dataflow/pep_328/package/__init__.py similarity index 100% rename from python/ql/test/experimental/dataflow/pep_328/package/__init__.py rename to python/ql/test/library-tests/dataflow/pep_328/package/__init__.py diff --git a/python/ql/test/experimental/dataflow/pep_328/package/moduleA.py b/python/ql/test/library-tests/dataflow/pep_328/package/moduleA.py similarity index 100% rename from python/ql/test/experimental/dataflow/pep_328/package/moduleA.py rename to python/ql/test/library-tests/dataflow/pep_328/package/moduleA.py diff --git a/python/ql/test/experimental/dataflow/pep_328/package/subpackage1/__init__.py b/python/ql/test/library-tests/dataflow/pep_328/package/subpackage1/__init__.py similarity index 100% rename from python/ql/test/experimental/dataflow/pep_328/package/subpackage1/__init__.py rename to python/ql/test/library-tests/dataflow/pep_328/package/subpackage1/__init__.py diff --git a/python/ql/test/experimental/dataflow/pep_328/package/subpackage1/moduleX.py b/python/ql/test/library-tests/dataflow/pep_328/package/subpackage1/moduleX.py similarity index 100% rename from python/ql/test/experimental/dataflow/pep_328/package/subpackage1/moduleX.py rename to python/ql/test/library-tests/dataflow/pep_328/package/subpackage1/moduleX.py diff --git a/python/ql/test/experimental/dataflow/pep_328/package/subpackage1/moduleY.py b/python/ql/test/library-tests/dataflow/pep_328/package/subpackage1/moduleY.py similarity index 100% rename from python/ql/test/experimental/dataflow/pep_328/package/subpackage1/moduleY.py rename to python/ql/test/library-tests/dataflow/pep_328/package/subpackage1/moduleY.py diff --git a/python/ql/test/experimental/dataflow/pep_328/package/subpackage2/__init__.py b/python/ql/test/library-tests/dataflow/pep_328/package/subpackage2/__init__.py similarity index 100% rename from python/ql/test/experimental/dataflow/pep_328/package/subpackage2/__init__.py rename to python/ql/test/library-tests/dataflow/pep_328/package/subpackage2/__init__.py diff --git a/python/ql/test/experimental/dataflow/pep_328/package/subpackage2/moduleZ.py b/python/ql/test/library-tests/dataflow/pep_328/package/subpackage2/moduleZ.py similarity index 100% rename from python/ql/test/experimental/dataflow/pep_328/package/subpackage2/moduleZ.py rename to python/ql/test/library-tests/dataflow/pep_328/package/subpackage2/moduleZ.py diff --git a/python/ql/test/experimental/dataflow/pep_328/start.py b/python/ql/test/library-tests/dataflow/pep_328/start.py similarity index 100% rename from python/ql/test/experimental/dataflow/pep_328/start.py rename to python/ql/test/library-tests/dataflow/pep_328/start.py diff --git a/python/ql/test/experimental/dataflow/qll-private-imports/README.md b/python/ql/test/library-tests/dataflow/qll-private-imports/README.md similarity index 100% rename from python/ql/test/experimental/dataflow/qll-private-imports/README.md rename to python/ql/test/library-tests/dataflow/qll-private-imports/README.md diff --git a/python/ql/test/experimental/dataflow/qll-private-imports/Test.expected b/python/ql/test/library-tests/dataflow/qll-private-imports/Test.expected similarity index 100% rename from python/ql/test/experimental/dataflow/qll-private-imports/Test.expected rename to python/ql/test/library-tests/dataflow/qll-private-imports/Test.expected diff --git a/python/ql/test/experimental/dataflow/qll-private-imports/Test.ql b/python/ql/test/library-tests/dataflow/qll-private-imports/Test.ql similarity index 100% rename from python/ql/test/experimental/dataflow/qll-private-imports/Test.ql rename to python/ql/test/library-tests/dataflow/qll-private-imports/Test.ql diff --git a/python/ql/test/experimental/dataflow/qll-private-imports/test.py b/python/ql/test/library-tests/dataflow/qll-private-imports/test.py similarity index 100% rename from python/ql/test/experimental/dataflow/qll-private-imports/test.py rename to python/ql/test/library-tests/dataflow/qll-private-imports/test.py diff --git a/python/ql/test/experimental/dataflow/regression/custom_dataflow.expected b/python/ql/test/library-tests/dataflow/regression/custom_dataflow.expected similarity index 100% rename from python/ql/test/experimental/dataflow/regression/custom_dataflow.expected rename to python/ql/test/library-tests/dataflow/regression/custom_dataflow.expected diff --git a/python/ql/test/experimental/dataflow/regression/custom_dataflow.ql b/python/ql/test/library-tests/dataflow/regression/custom_dataflow.ql similarity index 100% rename from python/ql/test/experimental/dataflow/regression/custom_dataflow.ql rename to python/ql/test/library-tests/dataflow/regression/custom_dataflow.ql diff --git a/python/ql/test/experimental/dataflow/regression/dataflow.expected b/python/ql/test/library-tests/dataflow/regression/dataflow.expected similarity index 100% rename from python/ql/test/experimental/dataflow/regression/dataflow.expected rename to python/ql/test/library-tests/dataflow/regression/dataflow.expected diff --git a/python/ql/test/experimental/dataflow/regression/dataflow.ql b/python/ql/test/library-tests/dataflow/regression/dataflow.ql similarity index 100% rename from python/ql/test/experimental/dataflow/regression/dataflow.ql rename to python/ql/test/library-tests/dataflow/regression/dataflow.ql diff --git a/python/ql/test/experimental/dataflow/regression/module.py b/python/ql/test/library-tests/dataflow/regression/module.py similarity index 100% rename from python/ql/test/experimental/dataflow/regression/module.py rename to python/ql/test/library-tests/dataflow/regression/module.py diff --git a/python/ql/test/experimental/dataflow/regression/test.py b/python/ql/test/library-tests/dataflow/regression/test.py similarity index 100% rename from python/ql/test/experimental/dataflow/regression/test.py rename to python/ql/test/library-tests/dataflow/regression/test.py diff --git a/python/ql/test/experimental/dataflow/sensitive-data/TestSensitiveDataSources.expected b/python/ql/test/library-tests/dataflow/sensitive-data/TestSensitiveDataSources.expected similarity index 100% rename from python/ql/test/experimental/dataflow/sensitive-data/TestSensitiveDataSources.expected rename to python/ql/test/library-tests/dataflow/sensitive-data/TestSensitiveDataSources.expected diff --git a/python/ql/test/experimental/dataflow/sensitive-data/TestSensitiveDataSources.ql b/python/ql/test/library-tests/dataflow/sensitive-data/TestSensitiveDataSources.ql similarity index 100% rename from python/ql/test/experimental/dataflow/sensitive-data/TestSensitiveDataSources.ql rename to python/ql/test/library-tests/dataflow/sensitive-data/TestSensitiveDataSources.ql diff --git a/python/ql/test/experimental/dataflow/sensitive-data/test.py b/python/ql/test/library-tests/dataflow/sensitive-data/test.py similarity index 100% rename from python/ql/test/experimental/dataflow/sensitive-data/test.py rename to python/ql/test/library-tests/dataflow/sensitive-data/test.py diff --git a/python/ql/test/experimental/dataflow/strange-essaflow/test.py b/python/ql/test/library-tests/dataflow/strange-essaflow/test.py similarity index 100% rename from python/ql/test/experimental/dataflow/strange-essaflow/test.py rename to python/ql/test/library-tests/dataflow/strange-essaflow/test.py diff --git a/python/ql/test/experimental/dataflow/strange-essaflow/testFlow.expected b/python/ql/test/library-tests/dataflow/strange-essaflow/testFlow.expected similarity index 100% rename from python/ql/test/experimental/dataflow/strange-essaflow/testFlow.expected rename to python/ql/test/library-tests/dataflow/strange-essaflow/testFlow.expected diff --git a/python/ql/test/experimental/dataflow/strange-essaflow/testFlow.ql b/python/ql/test/library-tests/dataflow/strange-essaflow/testFlow.ql similarity index 100% rename from python/ql/test/experimental/dataflow/strange-essaflow/testFlow.ql rename to python/ql/test/library-tests/dataflow/strange-essaflow/testFlow.ql diff --git a/python/ql/test/experimental/dataflow/summaries-checks/dummy.py b/python/ql/test/library-tests/dataflow/summaries-checks/dummy.py similarity index 100% rename from python/ql/test/experimental/dataflow/summaries-checks/dummy.py rename to python/ql/test/library-tests/dataflow/summaries-checks/dummy.py diff --git a/python/ql/test/experimental/dataflow/summaries-checks/invalid-spec.expected b/python/ql/test/library-tests/dataflow/summaries-checks/invalid-spec.expected similarity index 100% rename from python/ql/test/experimental/dataflow/summaries-checks/invalid-spec.expected rename to python/ql/test/library-tests/dataflow/summaries-checks/invalid-spec.expected diff --git a/python/ql/test/experimental/dataflow/summaries-checks/invalid-spec.ql b/python/ql/test/library-tests/dataflow/summaries-checks/invalid-spec.ql similarity index 100% rename from python/ql/test/experimental/dataflow/summaries-checks/invalid-spec.ql rename to python/ql/test/library-tests/dataflow/summaries-checks/invalid-spec.ql diff --git a/python/ql/test/experimental/dataflow/summaries-checks/missing-attribute-content.expected b/python/ql/test/library-tests/dataflow/summaries-checks/missing-attribute-content.expected similarity index 100% rename from python/ql/test/experimental/dataflow/summaries-checks/missing-attribute-content.expected rename to python/ql/test/library-tests/dataflow/summaries-checks/missing-attribute-content.expected diff --git a/python/ql/test/experimental/dataflow/summaries-checks/missing-attribute-content.ql b/python/ql/test/library-tests/dataflow/summaries-checks/missing-attribute-content.ql similarity index 100% rename from python/ql/test/experimental/dataflow/summaries-checks/missing-attribute-content.ql rename to python/ql/test/library-tests/dataflow/summaries-checks/missing-attribute-content.ql diff --git a/python/ql/test/experimental/dataflow/summaries/InlineTaintTest.expected b/python/ql/test/library-tests/dataflow/summaries/InlineTaintTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/summaries/InlineTaintTest.expected rename to python/ql/test/library-tests/dataflow/summaries/InlineTaintTest.expected diff --git a/python/ql/test/experimental/dataflow/summaries/InlineTaintTest.ql b/python/ql/test/library-tests/dataflow/summaries/InlineTaintTest.ql similarity index 100% rename from python/ql/test/experimental/dataflow/summaries/InlineTaintTest.ql rename to python/ql/test/library-tests/dataflow/summaries/InlineTaintTest.ql diff --git a/python/ql/test/experimental/dataflow/summaries/NormalTaintTrackingTest.expected b/python/ql/test/library-tests/dataflow/summaries/NormalTaintTrackingTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/summaries/NormalTaintTrackingTest.expected rename to python/ql/test/library-tests/dataflow/summaries/NormalTaintTrackingTest.expected diff --git a/python/ql/test/experimental/dataflow/summaries/NormalTaintTrackingTest.ql b/python/ql/test/library-tests/dataflow/summaries/NormalTaintTrackingTest.ql similarity index 100% rename from python/ql/test/experimental/dataflow/summaries/NormalTaintTrackingTest.ql rename to python/ql/test/library-tests/dataflow/summaries/NormalTaintTrackingTest.ql diff --git a/python/ql/test/experimental/dataflow/summaries/TestSummaries.qll b/python/ql/test/library-tests/dataflow/summaries/TestSummaries.qll similarity index 100% rename from python/ql/test/experimental/dataflow/summaries/TestSummaries.qll rename to python/ql/test/library-tests/dataflow/summaries/TestSummaries.qll diff --git a/python/ql/test/experimental/dataflow/summaries/conflicting_summaries.py b/python/ql/test/library-tests/dataflow/summaries/conflicting_summaries.py similarity index 100% rename from python/ql/test/experimental/dataflow/summaries/conflicting_summaries.py rename to python/ql/test/library-tests/dataflow/summaries/conflicting_summaries.py diff --git a/python/ql/test/experimental/dataflow/summaries/extracted_package/__init__.py b/python/ql/test/library-tests/dataflow/summaries/extracted_package/__init__.py similarity index 100% rename from python/ql/test/experimental/dataflow/summaries/extracted_package/__init__.py rename to python/ql/test/library-tests/dataflow/summaries/extracted_package/__init__.py diff --git a/python/ql/test/experimental/dataflow/summaries/extracted_package/functions.py b/python/ql/test/library-tests/dataflow/summaries/extracted_package/functions.py similarity index 100% rename from python/ql/test/experimental/dataflow/summaries/extracted_package/functions.py rename to python/ql/test/library-tests/dataflow/summaries/extracted_package/functions.py diff --git a/python/ql/test/experimental/dataflow/summaries/summaries.expected b/python/ql/test/library-tests/dataflow/summaries/summaries.expected similarity index 100% rename from python/ql/test/experimental/dataflow/summaries/summaries.expected rename to python/ql/test/library-tests/dataflow/summaries/summaries.expected diff --git a/python/ql/test/experimental/dataflow/summaries/summaries.py b/python/ql/test/library-tests/dataflow/summaries/summaries.py similarity index 100% rename from python/ql/test/experimental/dataflow/summaries/summaries.py rename to python/ql/test/library-tests/dataflow/summaries/summaries.py diff --git a/python/ql/test/experimental/dataflow/summaries/summaries.ql b/python/ql/test/library-tests/dataflow/summaries/summaries.ql similarity index 100% rename from python/ql/test/experimental/dataflow/summaries/summaries.ql rename to python/ql/test/library-tests/dataflow/summaries/summaries.ql diff --git a/python/ql/test/experimental/dataflow/tainttracking/TestTaintLib.qll b/python/ql/test/library-tests/dataflow/tainttracking/TestTaintLib.qll similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/TestTaintLib.qll rename to python/ql/test/library-tests/dataflow/tainttracking/TestTaintLib.qll diff --git a/python/ql/test/experimental/dataflow/tainttracking/basic/GlobalTaintTracking.expected b/python/ql/test/library-tests/dataflow/tainttracking/basic/GlobalTaintTracking.expected similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/basic/GlobalTaintTracking.expected rename to python/ql/test/library-tests/dataflow/tainttracking/basic/GlobalTaintTracking.expected diff --git a/python/ql/test/experimental/dataflow/tainttracking/basic/GlobalTaintTracking.ql b/python/ql/test/library-tests/dataflow/tainttracking/basic/GlobalTaintTracking.ql similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/basic/GlobalTaintTracking.ql rename to python/ql/test/library-tests/dataflow/tainttracking/basic/GlobalTaintTracking.ql diff --git a/python/ql/test/experimental/dataflow/tainttracking/basic/LocalTaintStep.expected b/python/ql/test/library-tests/dataflow/tainttracking/basic/LocalTaintStep.expected similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/basic/LocalTaintStep.expected rename to python/ql/test/library-tests/dataflow/tainttracking/basic/LocalTaintStep.expected diff --git a/python/ql/test/experimental/dataflow/tainttracking/basic/LocalTaintStep.ql b/python/ql/test/library-tests/dataflow/tainttracking/basic/LocalTaintStep.ql similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/basic/LocalTaintStep.ql rename to python/ql/test/library-tests/dataflow/tainttracking/basic/LocalTaintStep.ql diff --git a/python/ql/test/experimental/dataflow/tainttracking/basic/test.py b/python/ql/test/library-tests/dataflow/tainttracking/basic/test.py similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/basic/test.py rename to python/ql/test/library-tests/dataflow/tainttracking/basic/test.py diff --git a/python/ql/test/experimental/dataflow/tainttracking/commonSanitizer/InlineTaintTest.expected b/python/ql/test/library-tests/dataflow/tainttracking/commonSanitizer/InlineTaintTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/commonSanitizer/InlineTaintTest.expected rename to python/ql/test/library-tests/dataflow/tainttracking/commonSanitizer/InlineTaintTest.expected diff --git a/python/ql/test/experimental/dataflow/tainttracking/commonSanitizer/InlineTaintTest.ql b/python/ql/test/library-tests/dataflow/tainttracking/commonSanitizer/InlineTaintTest.ql similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/commonSanitizer/InlineTaintTest.ql rename to python/ql/test/library-tests/dataflow/tainttracking/commonSanitizer/InlineTaintTest.ql diff --git a/python/ql/test/experimental/dataflow/tainttracking/commonSanitizer/test_string_const_compare.py b/python/ql/test/library-tests/dataflow/tainttracking/commonSanitizer/test_string_const_compare.py similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/commonSanitizer/test_string_const_compare.py rename to python/ql/test/library-tests/dataflow/tainttracking/commonSanitizer/test_string_const_compare.py diff --git a/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.expected b/python/ql/test/library-tests/dataflow/tainttracking/customSanitizer/InlineTaintTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.expected rename to python/ql/test/library-tests/dataflow/tainttracking/customSanitizer/InlineTaintTest.expected diff --git a/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.ql b/python/ql/test/library-tests/dataflow/tainttracking/customSanitizer/InlineTaintTest.ql similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.ql rename to python/ql/test/library-tests/dataflow/tainttracking/customSanitizer/InlineTaintTest.ql diff --git a/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/test.py b/python/ql/test/library-tests/dataflow/tainttracking/customSanitizer/test.py similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/customSanitizer/test.py rename to python/ql/test/library-tests/dataflow/tainttracking/customSanitizer/test.py diff --git a/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/test_logical.py b/python/ql/test/library-tests/dataflow/tainttracking/customSanitizer/test_logical.py similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/customSanitizer/test_logical.py rename to python/ql/test/library-tests/dataflow/tainttracking/customSanitizer/test_logical.py diff --git a/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/test_reference.py b/python/ql/test/library-tests/dataflow/tainttracking/customSanitizer/test_reference.py similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/customSanitizer/test_reference.py rename to python/ql/test/library-tests/dataflow/tainttracking/customSanitizer/test_reference.py diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/InlineTaintTest.expected b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/InlineTaintTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/InlineTaintTest.expected rename to python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/InlineTaintTest.expected diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/InlineTaintTest.ql b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/InlineTaintTest.ql similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/InlineTaintTest.ql rename to python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/InlineTaintTest.ql diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/options b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/options similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/options rename to python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/options diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_collections.py b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_collections.py similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_collections.py rename to python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_collections.py diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_pathlib.py b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_pathlib.py similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_pathlib.py rename to python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_pathlib.py diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_string.py b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_string.py similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_string.py rename to python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_string.py diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_unpacking.py b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_unpacking.py similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_unpacking.py rename to python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_unpacking.py diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/InlineTaintTest.expected b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/InlineTaintTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/InlineTaintTest.expected rename to python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/InlineTaintTest.expected diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/InlineTaintTest.ql b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/InlineTaintTest.ql similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/InlineTaintTest.ql rename to python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/InlineTaintTest.ql diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_async.py b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_async.py similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_async.py rename to python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_async.py diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_attr.py b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_attr.py similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_attr.py rename to python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_attr.py diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py rename to python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_for.py b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_for.py similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_for.py rename to python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_for.py diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_string.py b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_string.py similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_string.py rename to python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_string.py diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_unpacking.py b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_unpacking.py similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_unpacking.py rename to python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_unpacking.py diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_with.py b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_with.py similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_with.py rename to python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_with.py diff --git a/python/ql/test/experimental/dataflow/tainttracking/generator-flow/InlineTaintTest.expected b/python/ql/test/library-tests/dataflow/tainttracking/generator-flow/InlineTaintTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/generator-flow/InlineTaintTest.expected rename to python/ql/test/library-tests/dataflow/tainttracking/generator-flow/InlineTaintTest.expected diff --git a/python/ql/test/experimental/dataflow/tainttracking/generator-flow/InlineTaintTest.ql b/python/ql/test/library-tests/dataflow/tainttracking/generator-flow/InlineTaintTest.ql similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/generator-flow/InlineTaintTest.ql rename to python/ql/test/library-tests/dataflow/tainttracking/generator-flow/InlineTaintTest.ql diff --git a/python/ql/test/experimental/dataflow/tainttracking/generator-flow/NormalDataflowTest.expected b/python/ql/test/library-tests/dataflow/tainttracking/generator-flow/NormalDataflowTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/generator-flow/NormalDataflowTest.expected rename to python/ql/test/library-tests/dataflow/tainttracking/generator-flow/NormalDataflowTest.expected diff --git a/python/ql/test/experimental/dataflow/tainttracking/generator-flow/NormalDataflowTest.ql b/python/ql/test/library-tests/dataflow/tainttracking/generator-flow/NormalDataflowTest.ql similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/generator-flow/NormalDataflowTest.ql rename to python/ql/test/library-tests/dataflow/tainttracking/generator-flow/NormalDataflowTest.ql diff --git a/python/ql/test/experimental/dataflow/tainttracking/generator-flow/test_dataflow.py b/python/ql/test/library-tests/dataflow/tainttracking/generator-flow/test_dataflow.py similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/generator-flow/test_dataflow.py rename to python/ql/test/library-tests/dataflow/tainttracking/generator-flow/test_dataflow.py diff --git a/python/ql/test/experimental/dataflow/tainttracking/generator-flow/test_taint.py b/python/ql/test/library-tests/dataflow/tainttracking/generator-flow/test_taint.py similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/generator-flow/test_taint.py rename to python/ql/test/library-tests/dataflow/tainttracking/generator-flow/test_taint.py diff --git a/python/ql/test/experimental/dataflow/tainttracking/taintlib.py b/python/ql/test/library-tests/dataflow/tainttracking/taintlib.py similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/taintlib.py rename to python/ql/test/library-tests/dataflow/tainttracking/taintlib.py diff --git a/python/ql/test/experimental/dataflow/tainttracking/unwanted-global-flow/InlineTaintTest.expected b/python/ql/test/library-tests/dataflow/tainttracking/unwanted-global-flow/InlineTaintTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/unwanted-global-flow/InlineTaintTest.expected rename to python/ql/test/library-tests/dataflow/tainttracking/unwanted-global-flow/InlineTaintTest.expected diff --git a/python/ql/test/experimental/dataflow/tainttracking/unwanted-global-flow/InlineTaintTest.ql b/python/ql/test/library-tests/dataflow/tainttracking/unwanted-global-flow/InlineTaintTest.ql similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/unwanted-global-flow/InlineTaintTest.ql rename to python/ql/test/library-tests/dataflow/tainttracking/unwanted-global-flow/InlineTaintTest.ql diff --git a/python/ql/test/experimental/dataflow/tainttracking/unwanted-global-flow/test.py b/python/ql/test/library-tests/dataflow/tainttracking/unwanted-global-flow/test.py similarity index 100% rename from python/ql/test/experimental/dataflow/tainttracking/unwanted-global-flow/test.py rename to python/ql/test/library-tests/dataflow/tainttracking/unwanted-global-flow/test.py diff --git a/python/ql/test/experimental/dataflow/testConfig.qll b/python/ql/test/library-tests/dataflow/testConfig.qll similarity index 100% rename from python/ql/test/experimental/dataflow/testConfig.qll rename to python/ql/test/library-tests/dataflow/testConfig.qll diff --git a/python/ql/test/experimental/dataflow/testTaintConfig.qll b/python/ql/test/library-tests/dataflow/testTaintConfig.qll similarity index 100% rename from python/ql/test/experimental/dataflow/testTaintConfig.qll rename to python/ql/test/library-tests/dataflow/testTaintConfig.qll diff --git a/python/ql/test/experimental/dataflow/testlib.py b/python/ql/test/library-tests/dataflow/testlib.py similarity index 100% rename from python/ql/test/experimental/dataflow/testlib.py rename to python/ql/test/library-tests/dataflow/testlib.py diff --git a/python/ql/test/experimental/dataflow/typetracking-summaries/TestSummaries.qll b/python/ql/test/library-tests/dataflow/typetracking-summaries/TestSummaries.qll similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking-summaries/TestSummaries.qll rename to python/ql/test/library-tests/dataflow/typetracking-summaries/TestSummaries.qll diff --git a/python/ql/test/experimental/dataflow/typetracking-summaries/summaries.py b/python/ql/test/library-tests/dataflow/typetracking-summaries/summaries.py similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking-summaries/summaries.py rename to python/ql/test/library-tests/dataflow/typetracking-summaries/summaries.py diff --git a/python/ql/test/experimental/dataflow/typetracking-summaries/tracked.expected b/python/ql/test/library-tests/dataflow/typetracking-summaries/tracked.expected similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking-summaries/tracked.expected rename to python/ql/test/library-tests/dataflow/typetracking-summaries/tracked.expected diff --git a/python/ql/test/experimental/dataflow/typetracking-summaries/tracked.ql b/python/ql/test/library-tests/dataflow/typetracking-summaries/tracked.ql similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking-summaries/tracked.ql rename to python/ql/test/library-tests/dataflow/typetracking-summaries/tracked.ql diff --git a/python/ql/test/experimental/dataflow/typetracking/attribute_tests.py b/python/ql/test/library-tests/dataflow/typetracking/attribute_tests.py similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking/attribute_tests.py rename to python/ql/test/library-tests/dataflow/typetracking/attribute_tests.py diff --git a/python/ql/test/experimental/dataflow/typetracking/content_test.py b/python/ql/test/library-tests/dataflow/typetracking/content_test.py similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking/content_test.py rename to python/ql/test/library-tests/dataflow/typetracking/content_test.py diff --git a/python/ql/test/experimental/dataflow/typetracking/import_as_attr.py b/python/ql/test/library-tests/dataflow/typetracking/import_as_attr.py similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking/import_as_attr.py rename to python/ql/test/library-tests/dataflow/typetracking/import_as_attr.py diff --git a/python/ql/test/experimental/dataflow/typetracking/import_as_attr_dotted.py b/python/ql/test/library-tests/dataflow/typetracking/import_as_attr_dotted.py similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking/import_as_attr_dotted.py rename to python/ql/test/library-tests/dataflow/typetracking/import_as_attr_dotted.py diff --git a/python/ql/test/experimental/dataflow/typetracking/moduleattr.expected b/python/ql/test/library-tests/dataflow/typetracking/moduleattr.expected similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking/moduleattr.expected rename to python/ql/test/library-tests/dataflow/typetracking/moduleattr.expected diff --git a/python/ql/test/experimental/dataflow/typetracking/moduleattr.ql b/python/ql/test/library-tests/dataflow/typetracking/moduleattr.ql similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking/moduleattr.ql rename to python/ql/test/library-tests/dataflow/typetracking/moduleattr.ql diff --git a/python/ql/test/experimental/dataflow/typetracking/multiple_callables.py b/python/ql/test/library-tests/dataflow/typetracking/multiple_callables.py similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking/multiple_callables.py rename to python/ql/test/library-tests/dataflow/typetracking/multiple_callables.py diff --git a/python/ql/test/experimental/dataflow/typetracking/mymodule.py b/python/ql/test/library-tests/dataflow/typetracking/mymodule.py similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking/mymodule.py rename to python/ql/test/library-tests/dataflow/typetracking/mymodule.py diff --git a/python/ql/test/experimental/dataflow/typetracking/test.py b/python/ql/test/library-tests/dataflow/typetracking/test.py similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking/test.py rename to python/ql/test/library-tests/dataflow/typetracking/test.py diff --git a/python/ql/test/experimental/dataflow/typetracking/tracked.expected b/python/ql/test/library-tests/dataflow/typetracking/tracked.expected similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking/tracked.expected rename to python/ql/test/library-tests/dataflow/typetracking/tracked.expected diff --git a/python/ql/test/experimental/dataflow/typetracking/tracked.ql b/python/ql/test/library-tests/dataflow/typetracking/tracked.ql similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking/tracked.ql rename to python/ql/test/library-tests/dataflow/typetracking/tracked.ql diff --git a/python/ql/test/experimental/dataflow/typetracking_imports/README.md b/python/ql/test/library-tests/dataflow/typetracking_imports/README.md similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking_imports/README.md rename to python/ql/test/library-tests/dataflow/typetracking_imports/README.md diff --git a/python/ql/test/experimental/dataflow/typetracking_imports/highlight_problem.expected b/python/ql/test/library-tests/dataflow/typetracking_imports/highlight_problem.expected similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking_imports/highlight_problem.expected rename to python/ql/test/library-tests/dataflow/typetracking_imports/highlight_problem.expected diff --git a/python/ql/test/experimental/dataflow/typetracking_imports/highlight_problem.ql b/python/ql/test/library-tests/dataflow/typetracking_imports/highlight_problem.ql similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking_imports/highlight_problem.ql rename to python/ql/test/library-tests/dataflow/typetracking_imports/highlight_problem.ql diff --git a/python/ql/test/experimental/dataflow/typetracking_imports/options b/python/ql/test/library-tests/dataflow/typetracking_imports/options similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking_imports/options rename to python/ql/test/library-tests/dataflow/typetracking_imports/options diff --git a/python/ql/test/experimental/dataflow/typetracking_imports/pkg/__init__.py b/python/ql/test/library-tests/dataflow/typetracking_imports/pkg/__init__.py similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking_imports/pkg/__init__.py rename to python/ql/test/library-tests/dataflow/typetracking_imports/pkg/__init__.py diff --git a/python/ql/test/experimental/dataflow/typetracking_imports/pkg/alias_only_direct.py b/python/ql/test/library-tests/dataflow/typetracking_imports/pkg/alias_only_direct.py similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking_imports/pkg/alias_only_direct.py rename to python/ql/test/library-tests/dataflow/typetracking_imports/pkg/alias_only_direct.py diff --git a/python/ql/test/experimental/dataflow/typetracking_imports/pkg/alias_problem.py b/python/ql/test/library-tests/dataflow/typetracking_imports/pkg/alias_problem.py similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking_imports/pkg/alias_problem.py rename to python/ql/test/library-tests/dataflow/typetracking_imports/pkg/alias_problem.py diff --git a/python/ql/test/experimental/dataflow/typetracking_imports/pkg/alias_problem_fixed.py b/python/ql/test/library-tests/dataflow/typetracking_imports/pkg/alias_problem_fixed.py similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking_imports/pkg/alias_problem_fixed.py rename to python/ql/test/library-tests/dataflow/typetracking_imports/pkg/alias_problem_fixed.py diff --git a/python/ql/test/experimental/dataflow/typetracking_imports/pkg/alias_star.py b/python/ql/test/library-tests/dataflow/typetracking_imports/pkg/alias_star.py similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking_imports/pkg/alias_star.py rename to python/ql/test/library-tests/dataflow/typetracking_imports/pkg/alias_star.py diff --git a/python/ql/test/experimental/dataflow/typetracking_imports/pkg/foo_def.py b/python/ql/test/library-tests/dataflow/typetracking_imports/pkg/foo_def.py similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking_imports/pkg/foo_def.py rename to python/ql/test/library-tests/dataflow/typetracking_imports/pkg/foo_def.py diff --git a/python/ql/test/experimental/dataflow/typetracking_imports/pkg/other.py b/python/ql/test/library-tests/dataflow/typetracking_imports/pkg/other.py similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking_imports/pkg/other.py rename to python/ql/test/library-tests/dataflow/typetracking_imports/pkg/other.py diff --git a/python/ql/test/experimental/dataflow/typetracking_imports/pkg/problem_absolute_import.py b/python/ql/test/library-tests/dataflow/typetracking_imports/pkg/problem_absolute_import.py similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking_imports/pkg/problem_absolute_import.py rename to python/ql/test/library-tests/dataflow/typetracking_imports/pkg/problem_absolute_import.py diff --git a/python/ql/test/experimental/dataflow/typetracking_imports/pkg/use.py b/python/ql/test/library-tests/dataflow/typetracking_imports/pkg/use.py similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking_imports/pkg/use.py rename to python/ql/test/library-tests/dataflow/typetracking_imports/pkg/use.py diff --git a/python/ql/test/experimental/dataflow/typetracking_imports/pkg/works_absolute_import.py b/python/ql/test/library-tests/dataflow/typetracking_imports/pkg/works_absolute_import.py similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking_imports/pkg/works_absolute_import.py rename to python/ql/test/library-tests/dataflow/typetracking_imports/pkg/works_absolute_import.py diff --git a/python/ql/test/experimental/dataflow/typetracking_imports/tracked.expected b/python/ql/test/library-tests/dataflow/typetracking_imports/tracked.expected similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking_imports/tracked.expected rename to python/ql/test/library-tests/dataflow/typetracking_imports/tracked.expected diff --git a/python/ql/test/experimental/dataflow/typetracking_imports/tracked.qlref b/python/ql/test/library-tests/dataflow/typetracking_imports/tracked.qlref similarity index 100% rename from python/ql/test/experimental/dataflow/typetracking_imports/tracked.qlref rename to python/ql/test/library-tests/dataflow/typetracking_imports/tracked.qlref diff --git a/python/ql/test/experimental/dataflow/use-use-flow/read_explosion.py b/python/ql/test/library-tests/dataflow/use-use-flow/read_explosion.py similarity index 100% rename from python/ql/test/experimental/dataflow/use-use-flow/read_explosion.py rename to python/ql/test/library-tests/dataflow/use-use-flow/read_explosion.py diff --git a/python/ql/test/experimental/dataflow/use-use-flow/use-use-counts.expected b/python/ql/test/library-tests/dataflow/use-use-flow/use-use-counts.expected similarity index 100% rename from python/ql/test/experimental/dataflow/use-use-flow/use-use-counts.expected rename to python/ql/test/library-tests/dataflow/use-use-flow/use-use-counts.expected diff --git a/python/ql/test/experimental/dataflow/use-use-flow/use-use-counts.ql b/python/ql/test/library-tests/dataflow/use-use-flow/use-use-counts.ql similarity index 100% rename from python/ql/test/experimental/dataflow/use-use-flow/use-use-counts.ql rename to python/ql/test/library-tests/dataflow/use-use-flow/use-use-counts.ql diff --git a/python/ql/test/experimental/dataflow/validTest.py b/python/ql/test/library-tests/dataflow/validTest.py similarity index 100% rename from python/ql/test/experimental/dataflow/validTest.py rename to python/ql/test/library-tests/dataflow/validTest.py diff --git a/python/ql/test/experimental/dataflow/variable-capture/CaptureTest.expected b/python/ql/test/library-tests/dataflow/variable-capture/CaptureTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/variable-capture/CaptureTest.expected rename to python/ql/test/library-tests/dataflow/variable-capture/CaptureTest.expected diff --git a/python/ql/test/experimental/dataflow/variable-capture/CaptureTest.ql b/python/ql/test/library-tests/dataflow/variable-capture/CaptureTest.ql similarity index 100% rename from python/ql/test/experimental/dataflow/variable-capture/CaptureTest.ql rename to python/ql/test/library-tests/dataflow/variable-capture/CaptureTest.ql diff --git a/python/ql/test/experimental/dataflow/variable-capture/by_value.py b/python/ql/test/library-tests/dataflow/variable-capture/by_value.py similarity index 100% rename from python/ql/test/experimental/dataflow/variable-capture/by_value.py rename to python/ql/test/library-tests/dataflow/variable-capture/by_value.py diff --git a/python/ql/test/experimental/dataflow/variable-capture/dataflow-capture-consistency.expected b/python/ql/test/library-tests/dataflow/variable-capture/dataflow-capture-consistency.expected similarity index 100% rename from python/ql/test/experimental/dataflow/variable-capture/dataflow-capture-consistency.expected rename to python/ql/test/library-tests/dataflow/variable-capture/dataflow-capture-consistency.expected diff --git a/python/ql/test/experimental/dataflow/variable-capture/dataflow-capture-consistency.ql b/python/ql/test/library-tests/dataflow/variable-capture/dataflow-capture-consistency.ql similarity index 100% rename from python/ql/test/experimental/dataflow/variable-capture/dataflow-capture-consistency.ql rename to python/ql/test/library-tests/dataflow/variable-capture/dataflow-capture-consistency.ql diff --git a/python/ql/test/experimental/dataflow/variable-capture/dict.py b/python/ql/test/library-tests/dataflow/variable-capture/dict.py similarity index 100% rename from python/ql/test/experimental/dataflow/variable-capture/dict.py rename to python/ql/test/library-tests/dataflow/variable-capture/dict.py diff --git a/python/ql/test/experimental/dataflow/variable-capture/global.py b/python/ql/test/library-tests/dataflow/variable-capture/global.py similarity index 100% rename from python/ql/test/experimental/dataflow/variable-capture/global.py rename to python/ql/test/library-tests/dataflow/variable-capture/global.py diff --git a/python/ql/test/experimental/dataflow/variable-capture/in.py b/python/ql/test/library-tests/dataflow/variable-capture/in.py similarity index 100% rename from python/ql/test/experimental/dataflow/variable-capture/in.py rename to python/ql/test/library-tests/dataflow/variable-capture/in.py diff --git a/python/ql/test/experimental/dataflow/variable-capture/nonlocal.py b/python/ql/test/library-tests/dataflow/variable-capture/nonlocal.py similarity index 100% rename from python/ql/test/experimental/dataflow/variable-capture/nonlocal.py rename to python/ql/test/library-tests/dataflow/variable-capture/nonlocal.py diff --git a/python/ql/test/experimental/dataflow/variable-capture/test_collections.py b/python/ql/test/library-tests/dataflow/variable-capture/test_collections.py similarity index 100% rename from python/ql/test/experimental/dataflow/variable-capture/test_collections.py rename to python/ql/test/library-tests/dataflow/variable-capture/test_collections.py diff --git a/python/ql/test/experimental/dataflow/variable-capture/test_fields.py b/python/ql/test/library-tests/dataflow/variable-capture/test_fields.py similarity index 100% rename from python/ql/test/experimental/dataflow/variable-capture/test_fields.py rename to python/ql/test/library-tests/dataflow/variable-capture/test_fields.py diff --git a/python/ql/test/experimental/dataflow/variable-capture/test_library_calls.py b/python/ql/test/library-tests/dataflow/variable-capture/test_library_calls.py similarity index 100% rename from python/ql/test/experimental/dataflow/variable-capture/test_library_calls.py rename to python/ql/test/library-tests/dataflow/variable-capture/test_library_calls.py From e0e405bb313095649ffd7578062575533656916f Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Fri, 19 Apr 2024 10:39:45 +0200 Subject: [PATCH 012/238] Python: replace dataflow-test location in files --- config/identical-files.json | 6 +++--- .../lib/semmle/python/dataflow/new/SensitiveDataSources.qll | 2 +- .../semmle/python/dataflow/new/internal/DataFlowPublic.qll | 2 +- python/ql/test/library-tests/dataflow/coverage/datamodel.py | 2 +- python/ql/test/library-tests/dataflow/coverage/test.py | 2 +- .../ql/test/library-tests/frameworks/stdlib-py3/Decoding.py | 2 +- .../ql/test/library-tests/frameworks/stdlib-py3/Encoding.py | 2 +- python/ql/test/library-tests/frameworks/stdlib/Decoding.py | 2 +- python/ql/test/library-tests/frameworks/stdlib/Encoding.py | 2 +- 9 files changed, 11 insertions(+), 11 deletions(-) diff --git a/config/identical-files.json b/config/identical-files.json index a8b1368f1af4..d810e30c0c8e 100644 --- a/config/identical-files.json +++ b/config/identical-files.json @@ -362,7 +362,7 @@ "java/ql/lib/semmle/code/java/security/internal/EncryptionKeySizes.qll" ], "Python model summaries test extension": [ - "python/ql/test/experimental/dataflow/model-summaries/InlineTaintTest.ext.yml", - "python/ql/test/experimental/dataflow/model-summaries/NormalDataflowTest.ext.yml" + "python/ql/test/library-tests/dataflow/model-summaries/InlineTaintTest.ext.yml", + "python/ql/test/library-tests/dataflow/model-summaries/NormalDataflowTest.ext.yml" ] -} \ No newline at end of file +} diff --git a/python/ql/lib/semmle/python/dataflow/new/SensitiveDataSources.qll b/python/ql/lib/semmle/python/dataflow/new/SensitiveDataSources.qll index 705c4476fb13..c12358f6db91 100644 --- a/python/ql/lib/semmle/python/dataflow/new/SensitiveDataSources.qll +++ b/python/ql/lib/semmle/python/dataflow/new/SensitiveDataSources.qll @@ -89,7 +89,7 @@ private module SensitiveDataModeling { */ DataFlow::Node sensitiveLookupStringConst(SensitiveDataClassification classification) { // Note: If this is implemented with type-tracking, we will get cross-talk as - // illustrated in python/ql/test/experimental/dataflow/sensitive-data/test.py + // illustrated in python/ql/test/library-tests/dataflow/sensitive-data/test.py exists(DataFlow::LocalSourceNode source | source.asExpr().(StringLiteral).getText() = sensitiveString(classification) and source.flowsTo(result) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll index 9b9caf28ad3c..4192241d619a 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll @@ -638,7 +638,7 @@ newtype TContent = // name = any(AccessPathToken a).getAnArgument("Attribute") // instead we use a qltest to alert if we write a new summary in QL that uses an // attribute -- see - // python/ql/test/experimental/dataflow/summaries-checks/missing-attribute-content.ql + // python/ql/test/library-tests/dataflow/summaries-checks/missing-attribute-content.ql attr in ["re", "string", "pattern"] or // diff --git a/python/ql/test/library-tests/dataflow/coverage/datamodel.py b/python/ql/test/library-tests/dataflow/coverage/datamodel.py index 89d9b0a819a1..22111a0abbd1 100644 --- a/python/ql/test/library-tests/dataflow/coverage/datamodel.py +++ b/python/ql/test/library-tests/dataflow/coverage/datamodel.py @@ -6,7 +6,7 @@ # A thorough covering of methods in that document is found in classes.py. # # Intended sources should be the variable `SOURCE` and intended sinks should be -# arguments to the function `SINK` (see python/ql/test/experimental/dataflow/testConfig.qll). +# arguments to the function `SINK` (see python/ql/test/library-tests/dataflow/testConfig.qll). import sys import os diff --git a/python/ql/test/library-tests/dataflow/coverage/test.py b/python/ql/test/library-tests/dataflow/coverage/test.py index eb14fb1dd0b5..a2ea9cccd676 100644 --- a/python/ql/test/library-tests/dataflow/coverage/test.py +++ b/python/ql/test/library-tests/dataflow/coverage/test.py @@ -2,7 +2,7 @@ # Headings refer to https://docs.python.org/3/reference/expressions.html, # and are selected whenever they incur dataflow. # Intended sources should be the variable `SOURCE` and intended sinks should be -# arguments to the function `SINK` (see python/ql/test/experimental/dataflow/testConfig.qll). +# arguments to the function `SINK` (see python/ql/test/library-tests/dataflow/testConfig.qll). # # Functions whose name ends with "_with_local_flow" will also be tested for local flow. # diff --git a/python/ql/test/library-tests/frameworks/stdlib-py3/Decoding.py b/python/ql/test/library-tests/frameworks/stdlib-py3/Decoding.py index 11cca46bdf7c..ec82bd2f1a73 100644 --- a/python/ql/test/library-tests/frameworks/stdlib-py3/Decoding.py +++ b/python/ql/test/library-tests/frameworks/stdlib-py3/Decoding.py @@ -1,6 +1,6 @@ import base64 -# TODO: These tests should be merged with python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_string.py +# TODO: These tests should be merged with python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_string.py base64.a85decode(payload) # $ decodeInput=payload decodeOutput=base64.a85decode(..) decodeFormat=Ascii85 base64.b85decode(payload) # $ decodeInput=payload decodeOutput=base64.b85decode(..) decodeFormat=Base85 base64.decodebytes(payload) # $ decodeInput=payload decodeOutput=base64.decodebytes(..) decodeFormat=Base64 diff --git a/python/ql/test/library-tests/frameworks/stdlib-py3/Encoding.py b/python/ql/test/library-tests/frameworks/stdlib-py3/Encoding.py index 7aea6a5e579b..493e22a6048b 100644 --- a/python/ql/test/library-tests/frameworks/stdlib-py3/Encoding.py +++ b/python/ql/test/library-tests/frameworks/stdlib-py3/Encoding.py @@ -1,6 +1,6 @@ import base64 -# TODO: These tests should be merged with python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_string.py +# TODO: These tests should be merged with python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_string.py base64.a85encode(bs) # $ encodeInput=bs encodeOutput=base64.a85encode(..) encodeFormat=Ascii85 base64.b85encode(bs)# $ encodeInput=bs encodeOutput=base64.b85encode(..) encodeFormat=Base85 base64.encodebytes(bs)# $ encodeInput=bs encodeOutput=base64.encodebytes(..) encodeFormat=Base64 diff --git a/python/ql/test/library-tests/frameworks/stdlib/Decoding.py b/python/ql/test/library-tests/frameworks/stdlib/Decoding.py index a977cb2793a5..6cd0be5740cd 100644 --- a/python/ql/test/library-tests/frameworks/stdlib/Decoding.py +++ b/python/ql/test/library-tests/frameworks/stdlib/Decoding.py @@ -26,7 +26,7 @@ shelve.open(filepath) # $ decodeInput=filepath decodeOutput=shelve.open(..) decodeFormat=pickle decodeMayExecuteInput getAPathArgument=filepath shelve.open(filename=filepath) # $ decodeInput=filepath decodeOutput=shelve.open(..) decodeFormat=pickle decodeMayExecuteInput getAPathArgument=filepath -# TODO: These tests should be merged with python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_string.py +# TODO: These tests should be merged with python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_string.py base64.b64decode(payload) # $ decodeInput=payload decodeOutput=base64.b64decode(..) decodeFormat=Base64 base64.standard_b64decode(payload) # $ decodeInput=payload decodeOutput=base64.standard_b64decode(..) decodeFormat=Base64 base64.urlsafe_b64decode(payload) # $ decodeInput=payload decodeOutput=base64.urlsafe_b64decode(..) decodeFormat=Base64 diff --git a/python/ql/test/library-tests/frameworks/stdlib/Encoding.py b/python/ql/test/library-tests/frameworks/stdlib/Encoding.py index 38f4372faa26..5573709a05f8 100644 --- a/python/ql/test/library-tests/frameworks/stdlib/Encoding.py +++ b/python/ql/test/library-tests/frameworks/stdlib/Encoding.py @@ -5,7 +5,7 @@ pickle.dumps(obj) # $ MISSING: encodeInput=obj encodeOutput=pickle.dumps(..) encodeFormat=pickle encodeMayExecuteInput marshal.dumps(obj) # $ MISSING: encodeInput=obj encodeOutput=marshal.dumps(..) encodeFormat=marshal encodeMayExecuteInput -# TODO: These tests should be merged with python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_string.py +# TODO: These tests should be merged with python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_string.py base64.b64encode(bs) # $ encodeInput=bs encodeOutput=base64.b64encode(..) encodeFormat=Base64 base64.standard_b64encode(bs) # $ encodeInput=bs encodeOutput=base64.standard_b64encode(..) encodeFormat=Base64 base64.urlsafe_b64encode(bs) # $ encodeInput=bs encodeOutput=base64.urlsafe_b64encode(..) encodeFormat=Base64 From bb00d6919aa6b8bbf01c5a097fac3d4cde4c7cc4 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Fri, 19 Apr 2024 10:47:25 +0200 Subject: [PATCH 013/238] Python: Move dataflow TestUtil to importable location --- .../TestUtil => TestUtilities/dataflow}/DataflowQueryTest.qll | 0 .../dataflow/TestUtil => TestUtilities/dataflow}/FlowTest.qll | 0 .../TestUtil => TestUtilities/dataflow}/LocalFlowStepTest.qll | 0 .../TestUtil => TestUtilities/dataflow}/MaximalFlowTest.qll | 0 .../dataflow}/NormalDataflowTest.qll | 4 ++-- .../dataflow}/NormalTaintTrackingTest.qll | 4 ++-- .../TestUtil => TestUtilities/dataflow}/RoutingTest.qll | 0 .../TestUtil => TestUtilities/dataflow}/UnresolvedCalls.qll | 0 .../dataflow/callGraphConfig.qll | 0 .../{library-tests => TestUtilities}/dataflow/testConfig.qll | 0 .../dataflow/testTaintConfig.qll | 0 python/ql/test/experimental/meta/debug/dataflowTestPaths.ql | 2 +- .../Security/CWE-022-UnsafeUnpacking/DataflowQueryTest.ql | 2 +- .../query-tests/Security/CWE-409/DataflowQueryTest.ql | 2 +- .../ql/test/library-tests/dataflow/basic/localFlowStepTest.ql | 2 +- .../ql/test/library-tests/dataflow/basic/maximalFlowTest.ql | 2 +- .../library-tests/dataflow/coverage/NormalDataflowTest.ql | 2 +- .../library-tests/dataflow/coverage/argumentRoutingTest.ql | 2 +- .../library-tests/dataflow/exceptions/NormalDataflowTest.ql | 2 +- .../library-tests/dataflow/fieldflow/NormalDataflowTest.ql | 2 +- .../test/library-tests/dataflow/fieldflow/UnresolvedCalls.ql | 2 +- .../test/library-tests/dataflow/match/NormalDataflowTest.ql | 2 +- .../dataflow/model-summaries/NormalDataflowTest.ql | 2 +- .../library-tests/dataflow/module-initialization/localFlow.ql | 2 +- python/ql/test/library-tests/dataflow/path-graph/PathNodes.ql | 2 +- python/ql/test/library-tests/dataflow/regression/dataflow.ql | 2 +- .../dataflow/summaries/NormalTaintTrackingTest.ql | 2 +- python/ql/test/library-tests/dataflow/summaries/summaries.ql | 2 +- .../tainttracking/generator-flow/NormalDataflowTest.ql | 2 +- .../library-tests/dataflow/variable-capture/CaptureTest.ql | 2 +- .../library-tests/frameworks/django-orm/NormalDataflowTest.ql | 2 +- .../Security/CWE-022-PathInjection/DataflowQueryTest.ql | 2 +- .../Security/CWE-078-CommandInjection/DataflowQueryTest.ql | 2 +- .../DataflowQueryTest.ql | 2 +- .../Security/CWE-943-NoSqlInjection/DataflowQueryTest.ql | 2 +- 35 files changed, 28 insertions(+), 28 deletions(-) rename python/ql/test/{library-tests/dataflow/TestUtil => TestUtilities/dataflow}/DataflowQueryTest.qll (100%) rename python/ql/test/{library-tests/dataflow/TestUtil => TestUtilities/dataflow}/FlowTest.qll (100%) rename python/ql/test/{library-tests/dataflow/TestUtil => TestUtilities/dataflow}/LocalFlowStepTest.qll (100%) rename python/ql/test/{library-tests/dataflow/TestUtil => TestUtilities/dataflow}/MaximalFlowTest.qll (100%) rename python/ql/test/{library-tests/dataflow/TestUtil => TestUtilities/dataflow}/NormalDataflowTest.qll (93%) rename python/ql/test/{library-tests/dataflow/TestUtil => TestUtilities/dataflow}/NormalTaintTrackingTest.qll (92%) rename python/ql/test/{library-tests/dataflow/TestUtil => TestUtilities/dataflow}/RoutingTest.qll (100%) rename python/ql/test/{library-tests/dataflow/TestUtil => TestUtilities/dataflow}/UnresolvedCalls.qll (100%) rename python/ql/test/{library-tests => TestUtilities}/dataflow/callGraphConfig.qll (100%) rename python/ql/test/{library-tests => TestUtilities}/dataflow/testConfig.qll (100%) rename python/ql/test/{library-tests => TestUtilities}/dataflow/testTaintConfig.qll (100%) diff --git a/python/ql/test/library-tests/dataflow/TestUtil/DataflowQueryTest.qll b/python/ql/test/TestUtilities/dataflow/DataflowQueryTest.qll similarity index 100% rename from python/ql/test/library-tests/dataflow/TestUtil/DataflowQueryTest.qll rename to python/ql/test/TestUtilities/dataflow/DataflowQueryTest.qll diff --git a/python/ql/test/library-tests/dataflow/TestUtil/FlowTest.qll b/python/ql/test/TestUtilities/dataflow/FlowTest.qll similarity index 100% rename from python/ql/test/library-tests/dataflow/TestUtil/FlowTest.qll rename to python/ql/test/TestUtilities/dataflow/FlowTest.qll diff --git a/python/ql/test/library-tests/dataflow/TestUtil/LocalFlowStepTest.qll b/python/ql/test/TestUtilities/dataflow/LocalFlowStepTest.qll similarity index 100% rename from python/ql/test/library-tests/dataflow/TestUtil/LocalFlowStepTest.qll rename to python/ql/test/TestUtilities/dataflow/LocalFlowStepTest.qll diff --git a/python/ql/test/library-tests/dataflow/TestUtil/MaximalFlowTest.qll b/python/ql/test/TestUtilities/dataflow/MaximalFlowTest.qll similarity index 100% rename from python/ql/test/library-tests/dataflow/TestUtil/MaximalFlowTest.qll rename to python/ql/test/TestUtilities/dataflow/MaximalFlowTest.qll diff --git a/python/ql/test/library-tests/dataflow/TestUtil/NormalDataflowTest.qll b/python/ql/test/TestUtilities/dataflow/NormalDataflowTest.qll similarity index 93% rename from python/ql/test/library-tests/dataflow/TestUtil/NormalDataflowTest.qll rename to python/ql/test/TestUtilities/dataflow/NormalDataflowTest.qll index 51516faac8af..b89738b100ed 100644 --- a/python/ql/test/library-tests/dataflow/TestUtil/NormalDataflowTest.qll +++ b/python/ql/test/TestUtilities/dataflow/NormalDataflowTest.qll @@ -1,6 +1,6 @@ import python -import experimental.dataflow.TestUtil.FlowTest -import experimental.dataflow.testConfig +import TestUtilities.dataflow.FlowTest +import TestUtilities.dataflow.testConfig private import semmle.python.dataflow.new.internal.PrintNode module DataFlowTest implements FlowTestSig { diff --git a/python/ql/test/library-tests/dataflow/TestUtil/NormalTaintTrackingTest.qll b/python/ql/test/TestUtilities/dataflow/NormalTaintTrackingTest.qll similarity index 92% rename from python/ql/test/library-tests/dataflow/TestUtil/NormalTaintTrackingTest.qll rename to python/ql/test/TestUtilities/dataflow/NormalTaintTrackingTest.qll index 23262dfb3e57..e63e962df4d5 100644 --- a/python/ql/test/library-tests/dataflow/TestUtil/NormalTaintTrackingTest.qll +++ b/python/ql/test/TestUtilities/dataflow/NormalTaintTrackingTest.qll @@ -1,6 +1,6 @@ import python -import experimental.dataflow.TestUtil.FlowTest -import experimental.dataflow.testTaintConfig +import TestUtilities.dataflow.FlowTest +import TestUtilities.dataflow.testTaintConfig private import semmle.python.dataflow.new.internal.PrintNode module DataFlowTest implements FlowTestSig { diff --git a/python/ql/test/library-tests/dataflow/TestUtil/RoutingTest.qll b/python/ql/test/TestUtilities/dataflow/RoutingTest.qll similarity index 100% rename from python/ql/test/library-tests/dataflow/TestUtil/RoutingTest.qll rename to python/ql/test/TestUtilities/dataflow/RoutingTest.qll diff --git a/python/ql/test/library-tests/dataflow/TestUtil/UnresolvedCalls.qll b/python/ql/test/TestUtilities/dataflow/UnresolvedCalls.qll similarity index 100% rename from python/ql/test/library-tests/dataflow/TestUtil/UnresolvedCalls.qll rename to python/ql/test/TestUtilities/dataflow/UnresolvedCalls.qll diff --git a/python/ql/test/library-tests/dataflow/callGraphConfig.qll b/python/ql/test/TestUtilities/dataflow/callGraphConfig.qll similarity index 100% rename from python/ql/test/library-tests/dataflow/callGraphConfig.qll rename to python/ql/test/TestUtilities/dataflow/callGraphConfig.qll diff --git a/python/ql/test/library-tests/dataflow/testConfig.qll b/python/ql/test/TestUtilities/dataflow/testConfig.qll similarity index 100% rename from python/ql/test/library-tests/dataflow/testConfig.qll rename to python/ql/test/TestUtilities/dataflow/testConfig.qll diff --git a/python/ql/test/library-tests/dataflow/testTaintConfig.qll b/python/ql/test/TestUtilities/dataflow/testTaintConfig.qll similarity index 100% rename from python/ql/test/library-tests/dataflow/testTaintConfig.qll rename to python/ql/test/TestUtilities/dataflow/testTaintConfig.qll diff --git a/python/ql/test/experimental/meta/debug/dataflowTestPaths.ql b/python/ql/test/experimental/meta/debug/dataflowTestPaths.ql index 78d783033f57..4c0ab8986868 100644 --- a/python/ql/test/experimental/meta/debug/dataflowTestPaths.ql +++ b/python/ql/test/experimental/meta/debug/dataflowTestPaths.ql @@ -9,7 +9,7 @@ // 3. if necessary, look at partial paths by (un)commenting appropriate lines import python import semmle.python.dataflow.new.DataFlow -import experimental.dataflow.testConfig +import TestUtilities.dataflow.testConfig module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } diff --git a/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/DataflowQueryTest.ql b/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/DataflowQueryTest.ql index ed7d650f536d..9cbf6dd6ad8a 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/DataflowQueryTest.ql +++ b/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/DataflowQueryTest.ql @@ -1,4 +1,4 @@ import python -import experimental.dataflow.TestUtil.DataflowQueryTest +import TestUtilities.dataflow.DataflowQueryTest import experimental.Security.UnsafeUnpackQuery import FromTaintTrackingConfig diff --git a/python/ql/test/experimental/query-tests/Security/CWE-409/DataflowQueryTest.ql b/python/ql/test/experimental/query-tests/Security/CWE-409/DataflowQueryTest.ql index 24a2c302b989..c1724c29d2cf 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-409/DataflowQueryTest.ql +++ b/python/ql/test/experimental/query-tests/Security/CWE-409/DataflowQueryTest.ql @@ -1,4 +1,4 @@ import python -import experimental.dataflow.TestUtil.DataflowQueryTest +import TestUtilities.dataflow.DataflowQueryTest import experimental.semmle.python.security.DecompressionBomb import FromTaintTrackingConfig diff --git a/python/ql/test/library-tests/dataflow/basic/localFlowStepTest.ql b/python/ql/test/library-tests/dataflow/basic/localFlowStepTest.ql index 6dca01901569..881592eeaeb9 100644 --- a/python/ql/test/library-tests/dataflow/basic/localFlowStepTest.ql +++ b/python/ql/test/library-tests/dataflow/basic/localFlowStepTest.ql @@ -1 +1 @@ -import experimental.dataflow.TestUtil.LocalFlowStepTest +import TestUtilities.dataflow.LocalFlowStepTest diff --git a/python/ql/test/library-tests/dataflow/basic/maximalFlowTest.ql b/python/ql/test/library-tests/dataflow/basic/maximalFlowTest.ql index 618dae382f1b..64867eb89da5 100644 --- a/python/ql/test/library-tests/dataflow/basic/maximalFlowTest.ql +++ b/python/ql/test/library-tests/dataflow/basic/maximalFlowTest.ql @@ -1 +1 @@ -import experimental.dataflow.TestUtil.MaximalFlowTest +import TestUtilities.dataflow.MaximalFlowTest diff --git a/python/ql/test/library-tests/dataflow/coverage/NormalDataflowTest.ql b/python/ql/test/library-tests/dataflow/coverage/NormalDataflowTest.ql index 3ee344d0b871..f7e55d12ded6 100644 --- a/python/ql/test/library-tests/dataflow/coverage/NormalDataflowTest.ql +++ b/python/ql/test/library-tests/dataflow/coverage/NormalDataflowTest.ql @@ -1,2 +1,2 @@ import python -import experimental.dataflow.TestUtil.NormalDataflowTest +import TestUtilities.dataflow.NormalDataflowTest diff --git a/python/ql/test/library-tests/dataflow/coverage/argumentRoutingTest.ql b/python/ql/test/library-tests/dataflow/coverage/argumentRoutingTest.ql index 1a4e860f555c..02b503824d48 100644 --- a/python/ql/test/library-tests/dataflow/coverage/argumentRoutingTest.ql +++ b/python/ql/test/library-tests/dataflow/coverage/argumentRoutingTest.ql @@ -1,7 +1,7 @@ import python import semmle.python.dataflow.new.DataFlow private import semmle.python.dataflow.new.internal.DataFlowPrivate as DataFlowPrivate -import experimental.dataflow.TestUtil.RoutingTest +import TestUtilities.dataflow.RoutingTest module Argument1RoutingTest implements RoutingTestSig { class Argument = Unit; diff --git a/python/ql/test/library-tests/dataflow/exceptions/NormalDataflowTest.ql b/python/ql/test/library-tests/dataflow/exceptions/NormalDataflowTest.ql index 3ee344d0b871..f7e55d12ded6 100644 --- a/python/ql/test/library-tests/dataflow/exceptions/NormalDataflowTest.ql +++ b/python/ql/test/library-tests/dataflow/exceptions/NormalDataflowTest.ql @@ -1,2 +1,2 @@ import python -import experimental.dataflow.TestUtil.NormalDataflowTest +import TestUtilities.dataflow.NormalDataflowTest diff --git a/python/ql/test/library-tests/dataflow/fieldflow/NormalDataflowTest.ql b/python/ql/test/library-tests/dataflow/fieldflow/NormalDataflowTest.ql index 3ee344d0b871..f7e55d12ded6 100644 --- a/python/ql/test/library-tests/dataflow/fieldflow/NormalDataflowTest.ql +++ b/python/ql/test/library-tests/dataflow/fieldflow/NormalDataflowTest.ql @@ -1,2 +1,2 @@ import python -import experimental.dataflow.TestUtil.NormalDataflowTest +import TestUtilities.dataflow.NormalDataflowTest diff --git a/python/ql/test/library-tests/dataflow/fieldflow/UnresolvedCalls.ql b/python/ql/test/library-tests/dataflow/fieldflow/UnresolvedCalls.ql index 3c7498bd6518..299339dacf80 100644 --- a/python/ql/test/library-tests/dataflow/fieldflow/UnresolvedCalls.ql +++ b/python/ql/test/library-tests/dataflow/fieldflow/UnresolvedCalls.ql @@ -1,5 +1,5 @@ import python -import experimental.dataflow.TestUtil.UnresolvedCalls +import TestUtilities.dataflow.UnresolvedCalls private import semmle.python.dataflow.new.DataFlow module IgnoreDictMethod implements UnresolvedCallExpectationsSig { diff --git a/python/ql/test/library-tests/dataflow/match/NormalDataflowTest.ql b/python/ql/test/library-tests/dataflow/match/NormalDataflowTest.ql index 3ee344d0b871..f7e55d12ded6 100644 --- a/python/ql/test/library-tests/dataflow/match/NormalDataflowTest.ql +++ b/python/ql/test/library-tests/dataflow/match/NormalDataflowTest.ql @@ -1,2 +1,2 @@ import python -import experimental.dataflow.TestUtil.NormalDataflowTest +import TestUtilities.dataflow.NormalDataflowTest diff --git a/python/ql/test/library-tests/dataflow/model-summaries/NormalDataflowTest.ql b/python/ql/test/library-tests/dataflow/model-summaries/NormalDataflowTest.ql index 3ee344d0b871..f7e55d12ded6 100644 --- a/python/ql/test/library-tests/dataflow/model-summaries/NormalDataflowTest.ql +++ b/python/ql/test/library-tests/dataflow/model-summaries/NormalDataflowTest.ql @@ -1,2 +1,2 @@ import python -import experimental.dataflow.TestUtil.NormalDataflowTest +import TestUtilities.dataflow.NormalDataflowTest diff --git a/python/ql/test/library-tests/dataflow/module-initialization/localFlow.ql b/python/ql/test/library-tests/dataflow/module-initialization/localFlow.ql index 22a0f88d77e9..36aa6e007a75 100644 --- a/python/ql/test/library-tests/dataflow/module-initialization/localFlow.ql +++ b/python/ql/test/library-tests/dataflow/module-initialization/localFlow.ql @@ -1,6 +1,6 @@ // This query should be more focused yet. import python -import experimental.dataflow.TestUtil.FlowTest +import TestUtilities.dataflow.FlowTest private import semmle.python.dataflow.new.internal.PrintNode private import semmle.python.dataflow.new.internal.DataFlowPrivate as DP diff --git a/python/ql/test/library-tests/dataflow/path-graph/PathNodes.ql b/python/ql/test/library-tests/dataflow/path-graph/PathNodes.ql index c403d588d492..8100e999491c 100644 --- a/python/ql/test/library-tests/dataflow/path-graph/PathNodes.ql +++ b/python/ql/test/library-tests/dataflow/path-graph/PathNodes.ql @@ -5,7 +5,7 @@ import python import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking -import experimental.dataflow.testConfig +import TestUtilities.dataflow.testConfig import TestUtilities.InlineExpectationsTest module TestTaintFlow = TaintTracking::Global; diff --git a/python/ql/test/library-tests/dataflow/regression/dataflow.ql b/python/ql/test/library-tests/dataflow/regression/dataflow.ql index 39763fa48143..27645d084b87 100644 --- a/python/ql/test/library-tests/dataflow/regression/dataflow.ql +++ b/python/ql/test/library-tests/dataflow/regression/dataflow.ql @@ -6,7 +6,7 @@ */ import python -import experimental.dataflow.testConfig +import TestUtilities.dataflow.testConfig from DataFlow::Node source, DataFlow::Node sink where TestFlow::flow(source, sink) diff --git a/python/ql/test/library-tests/dataflow/summaries/NormalTaintTrackingTest.ql b/python/ql/test/library-tests/dataflow/summaries/NormalTaintTrackingTest.ql index afb44b6b2edb..59376d7a53c1 100644 --- a/python/ql/test/library-tests/dataflow/summaries/NormalTaintTrackingTest.ql +++ b/python/ql/test/library-tests/dataflow/summaries/NormalTaintTrackingTest.ql @@ -1,3 +1,3 @@ import python private import TestSummaries -import experimental.dataflow.TestUtil.NormalTaintTrackingTest +import TestUtilities.dataflow.NormalTaintTrackingTest diff --git a/python/ql/test/library-tests/dataflow/summaries/summaries.ql b/python/ql/test/library-tests/dataflow/summaries/summaries.ql index e2a61cd6f463..4b5e79d28869 100644 --- a/python/ql/test/library-tests/dataflow/summaries/summaries.ql +++ b/python/ql/test/library-tests/dataflow/summaries/summaries.ql @@ -8,7 +8,7 @@ import TestFlow::PathGraph import semmle.python.dataflow.new.TaintTracking import semmle.python.dataflow.new.internal.FlowSummaryImpl import semmle.python.ApiGraphs -import experimental.dataflow.testTaintConfig +import TestUtilities.dataflow.testTaintConfig private import TestSummaries query predicate invalidSpecComponent(SummarizedCallable sc, string s, string c) { diff --git a/python/ql/test/library-tests/dataflow/tainttracking/generator-flow/NormalDataflowTest.ql b/python/ql/test/library-tests/dataflow/tainttracking/generator-flow/NormalDataflowTest.ql index 3ee344d0b871..f7e55d12ded6 100644 --- a/python/ql/test/library-tests/dataflow/tainttracking/generator-flow/NormalDataflowTest.ql +++ b/python/ql/test/library-tests/dataflow/tainttracking/generator-flow/NormalDataflowTest.ql @@ -1,2 +1,2 @@ import python -import experimental.dataflow.TestUtil.NormalDataflowTest +import TestUtilities.dataflow.NormalDataflowTest diff --git a/python/ql/test/library-tests/dataflow/variable-capture/CaptureTest.ql b/python/ql/test/library-tests/dataflow/variable-capture/CaptureTest.ql index a1c754e8ee54..f81101741517 100644 --- a/python/ql/test/library-tests/dataflow/variable-capture/CaptureTest.ql +++ b/python/ql/test/library-tests/dataflow/variable-capture/CaptureTest.ql @@ -1,7 +1,7 @@ import python import semmle.python.dataflow.new.DataFlow import TestUtilities.InlineExpectationsTest -import experimental.dataflow.testConfig +import TestUtilities.dataflow.testConfig module CaptureTest implements TestSig { string getARelevantTag() { result = "captured" } diff --git a/python/ql/test/library-tests/frameworks/django-orm/NormalDataflowTest.ql b/python/ql/test/library-tests/frameworks/django-orm/NormalDataflowTest.ql index 3ee344d0b871..f7e55d12ded6 100644 --- a/python/ql/test/library-tests/frameworks/django-orm/NormalDataflowTest.ql +++ b/python/ql/test/library-tests/frameworks/django-orm/NormalDataflowTest.ql @@ -1,2 +1,2 @@ import python -import experimental.dataflow.TestUtil.NormalDataflowTest +import TestUtilities.dataflow.NormalDataflowTest diff --git a/python/ql/test/query-tests/Security/CWE-022-PathInjection/DataflowQueryTest.ql b/python/ql/test/query-tests/Security/CWE-022-PathInjection/DataflowQueryTest.ql index 90761391ce79..a0cdc79b17d7 100644 --- a/python/ql/test/query-tests/Security/CWE-022-PathInjection/DataflowQueryTest.ql +++ b/python/ql/test/query-tests/Security/CWE-022-PathInjection/DataflowQueryTest.ql @@ -1,4 +1,4 @@ import python -import experimental.dataflow.TestUtil.DataflowQueryTest +import TestUtilities.dataflow.DataflowQueryTest import semmle.python.security.dataflow.PathInjectionQuery import FromTaintTrackingStateConfig diff --git a/python/ql/test/query-tests/Security/CWE-078-CommandInjection/DataflowQueryTest.ql b/python/ql/test/query-tests/Security/CWE-078-CommandInjection/DataflowQueryTest.ql index df745b4ee8c3..26350c3db65b 100644 --- a/python/ql/test/query-tests/Security/CWE-078-CommandInjection/DataflowQueryTest.ql +++ b/python/ql/test/query-tests/Security/CWE-078-CommandInjection/DataflowQueryTest.ql @@ -1,4 +1,4 @@ import python -import experimental.dataflow.TestUtil.DataflowQueryTest +import TestUtilities.dataflow.DataflowQueryTest import semmle.python.security.dataflow.CommandInjectionQuery import FromTaintTrackingConfig diff --git a/python/ql/test/query-tests/Security/CWE-078-UnsafeShellCommandConstruction/DataflowQueryTest.ql b/python/ql/test/query-tests/Security/CWE-078-UnsafeShellCommandConstruction/DataflowQueryTest.ql index b2602b2b25c7..521527e7e4f0 100644 --- a/python/ql/test/query-tests/Security/CWE-078-UnsafeShellCommandConstruction/DataflowQueryTest.ql +++ b/python/ql/test/query-tests/Security/CWE-078-UnsafeShellCommandConstruction/DataflowQueryTest.ql @@ -1,4 +1,4 @@ import python -import experimental.dataflow.TestUtil.DataflowQueryTest +import TestUtilities.dataflow.DataflowQueryTest import semmle.python.security.dataflow.UnsafeShellCommandConstructionQuery import FromTaintTrackingConfig diff --git a/python/ql/test/query-tests/Security/CWE-943-NoSqlInjection/DataflowQueryTest.ql b/python/ql/test/query-tests/Security/CWE-943-NoSqlInjection/DataflowQueryTest.ql index b665aefd6fb3..5123e883d9cf 100644 --- a/python/ql/test/query-tests/Security/CWE-943-NoSqlInjection/DataflowQueryTest.ql +++ b/python/ql/test/query-tests/Security/CWE-943-NoSqlInjection/DataflowQueryTest.ql @@ -1,4 +1,4 @@ import python -import experimental.dataflow.TestUtil.DataflowQueryTest +import TestUtilities.dataflow.DataflowQueryTest import semmle.python.security.dataflow.NoSqlInjectionQuery import FromTaintTrackingStateConfig From 1bc085c8f74e836241b88f5cdf8962414bb7ec1f Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Tue, 23 Apr 2024 09:42:35 +0200 Subject: [PATCH 014/238] Python: Fixup for `callGraphConfig` --- python/ql/test/library-tests/dataflow/basic/callGraph.ql | 2 +- python/ql/test/library-tests/dataflow/basic/callGraphSinks.ql | 2 +- python/ql/test/library-tests/dataflow/basic/callGraphSources.ql | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/python/ql/test/library-tests/dataflow/basic/callGraph.ql b/python/ql/test/library-tests/dataflow/basic/callGraph.ql index 98416af1d0f3..f0e28c33dc6a 100644 --- a/python/ql/test/library-tests/dataflow/basic/callGraph.ql +++ b/python/ql/test/library-tests/dataflow/basic/callGraph.ql @@ -1,4 +1,4 @@ -import experimental.dataflow.callGraphConfig +import TestUtilities.dataflow.callGraphConfig from DataFlow::Node source, DataFlow::Node sink where diff --git a/python/ql/test/library-tests/dataflow/basic/callGraphSinks.ql b/python/ql/test/library-tests/dataflow/basic/callGraphSinks.ql index 7cdf3cd94d17..472d6ccaa374 100644 --- a/python/ql/test/library-tests/dataflow/basic/callGraphSinks.ql +++ b/python/ql/test/library-tests/dataflow/basic/callGraphSinks.ql @@ -1,4 +1,4 @@ -import experimental.dataflow.callGraphConfig +import TestUtilities.dataflow.callGraphConfig from DataFlow::Node sink where diff --git a/python/ql/test/library-tests/dataflow/basic/callGraphSources.ql b/python/ql/test/library-tests/dataflow/basic/callGraphSources.ql index 8a0229c8f20e..05b26caf3c07 100644 --- a/python/ql/test/library-tests/dataflow/basic/callGraphSources.ql +++ b/python/ql/test/library-tests/dataflow/basic/callGraphSources.ql @@ -1,4 +1,4 @@ -import experimental.dataflow.callGraphConfig +import TestUtilities.dataflow.callGraphConfig from DataFlow::Node source where From 830b83f65331e574ee9b3ad5646a97b80e64247f Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 23 Apr 2024 13:07:20 +0200 Subject: [PATCH 015/238] Dataflow: Use doublyBoundedFastTC. --- shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index 9dfbc3e0bcda..31ff3fbb231d 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -3874,7 +3874,12 @@ module MakeImpl Lang> { n1.getANonHiddenSuccessor(_) = n2 and directReach(n2) } - private predicate pathSuccPlus(PathNodeImpl n1, PathNodeImpl n2) = fastTC(pathSucc/2)(n1, n2) + private predicate tcSrc(PathNodeImpl n) { n.isFlowSource() or n.isSource(_) } + + private predicate tcSink(PathNodeImpl n) { n.isFlowSink() or n instanceof PathNodeSink } + + private predicate pathSuccPlus(PathNodeImpl n1, PathNodeImpl n2) = + doublyBoundedFastTC(pathSucc/2, tcSrc/1, tcSink/1)(n1, n2) /** * A `Node` augmented with a call context (except for sinks) and an access path. From e4f23b31c69f36187f150015137bed94c94d3196 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 23 Apr 2024 20:04:08 +0200 Subject: [PATCH 016/238] JS: Add quotes around package name to correct parsing --- .../lib/semmle/javascript/frameworks/data/ModelsAsData.qll | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/frameworks/data/ModelsAsData.qll b/javascript/ql/lib/semmle/javascript/frameworks/data/ModelsAsData.qll index adfd683a4977..fc3077d89865 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/data/ModelsAsData.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/data/ModelsAsData.qll @@ -108,7 +108,11 @@ module ModelExport { } predicate exposedName(API::Node node, string type, string path) { - node = API::moduleExport(type) and path = "" + exists(string moduleName | + node = API::moduleExport(moduleName) and + path = "" and + type = "'" + moduleName + "'" + ) } predicate suggestedName(API::Node node, string type) { From 9d00f660f18d5c7f46c90efae15a868e865706e1 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 23 Apr 2024 20:08:21 +0200 Subject: [PATCH 017/238] Update ModelGeneration.expected --- .../ModelGeneration/ModelGeneration.expected | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/javascript/ql/test/library-tests/ModelGeneration/ModelGeneration.expected b/javascript/ql/test/library-tests/ModelGeneration/ModelGeneration.expected index 26547b2814f0..7a5cae4f796d 100644 --- a/javascript/ql/test/library-tests/ModelGeneration/ModelGeneration.expected +++ b/javascript/ql/test/library-tests/ModelGeneration/ModelGeneration.expected @@ -1,17 +1,17 @@ typeModel -| (aliases).Alias1 | aliases | Member[Alias1] | -| (aliases).Alias1 | aliases | Member[Alias2] | -| (aliases).Alias1 | aliases | Member[Alias3].Member[x] | -| (aliases).Alias1 | aliases | Member[Alias4].Member[x].Member[x] | -| (aliases).Alias1 | aliases | Member[AliasedClass] | +| (aliases).Alias1 | 'aliases' | Member[Alias1] | +| (aliases).Alias1 | 'aliases' | Member[Alias2] | +| (aliases).Alias1 | 'aliases' | Member[Alias3].Member[x] | +| (aliases).Alias1 | 'aliases' | Member[Alias4].Member[x].Member[x] | +| (aliases).Alias1 | 'aliases' | Member[AliasedClass] | | (aliases).Alias1.prototype | (aliases).Alias1 | Instance | | (aliases).Alias1.prototype | (aliases).Alias1.prototype.foo | ReturnValue | | (aliases).Alias1.prototype.foo | (aliases).Alias1.prototype | Member[foo] | -| (long-access-path).a.shortcut.d | long-access-path | Member[a].Member[b].Member[c].Member[d] | -| (long-access-path).a.shortcut.d | long-access-path | Member[a].Member[shortcut].Member[d] | +| (long-access-path).a.shortcut.d | 'long-access-path' | Member[a].Member[b].Member[c].Member[d] | +| (long-access-path).a.shortcut.d | 'long-access-path' | Member[a].Member[shortcut].Member[d] | | (long-access-path).a.shortcut.d.e | (long-access-path).a.shortcut.d | Member[e] | -| (reexport).func | reexport | Member[func] | -| (return-this).FluentInterface | return-this | Member[FluentInterface] | +| (reexport).func | 'reexport' | Member[func] | +| (return-this).FluentInterface | 'return-this' | Member[FluentInterface] | | (return-this).FluentInterface.prototype | (return-this).FluentInterface | Instance | | (return-this).FluentInterface.prototype | (return-this).FluentInterface.prototype.bar | ReturnValue | | (return-this).FluentInterface.prototype | (return-this).FluentInterface.prototype.baz | ReturnValue | @@ -21,45 +21,45 @@ typeModel | (return-this).FluentInterface.prototype.foo | (return-this).FluentInterface.prototype | Member[foo] | | (return-this).FluentInterface.prototype.notFluent | (return-this).FluentInterface.prototype | Member[notFluent] | | (return-this).FluentInterface.prototype.notFluent2 | (return-this).FluentInterface.prototype | Member[notFluent2] | -| (root-function).PublicClass | root-function | Member[PublicClass] | +| (root-function).PublicClass | 'root-function' | Member[PublicClass] | +| (root-function).PublicClass.prototype | 'root-function' | ReturnValue | | (root-function).PublicClass.prototype | (root-function).PublicClass | Instance | -| (root-function).PublicClass.prototype | root-function | ReturnValue | | (root-function).PublicClass.prototype.method | (root-function).PublicClass.prototype | Member[method] | -| (semi-internal-class).PublicClass | semi-internal-class | Member[PublicClass] | +| (semi-internal-class).PublicClass | 'semi-internal-class' | Member[PublicClass] | | (semi-internal-class).PublicClass.prototype | (semi-internal-class).PublicClass | Instance | | (semi-internal-class).PublicClass.prototype | (semi-internal-class).SemiInternalClass.prototype.method | ReturnValue | | (semi-internal-class).PublicClass.prototype | (semi-internal-class).getAnonymous~expr2 | ReturnValue | | (semi-internal-class).PublicClass.prototype.publicMethod | (semi-internal-class).PublicClass.prototype | Member[publicMethod] | | (semi-internal-class).SemiInternalClass.prototype | (semi-internal-class).get | ReturnValue | | (semi-internal-class).SemiInternalClass.prototype.method | (semi-internal-class).SemiInternalClass.prototype | Member[method] | -| (semi-internal-class).get | semi-internal-class | Member[get] | -| (semi-internal-class).getAnonymous | semi-internal-class | Member[getAnonymous] | +| (semi-internal-class).get | 'semi-internal-class' | Member[get] | +| (semi-internal-class).getAnonymous | 'semi-internal-class' | Member[getAnonymous] | | (semi-internal-class).getAnonymous~expr1 | (semi-internal-class).getAnonymous | ReturnValue | | (semi-internal-class).getAnonymous~expr2 | (semi-internal-class).getAnonymous~expr1 | Member[method] | -| (subclass).A | subclass | Member[A] | +| (subclass).A | 'subclass' | Member[A] | | (subclass).A.prototype | (subclass).A | Instance | | (subclass).A.prototype | (subclass).B.prototype | | | (subclass).A.prototype | (subclass).ExposedMidSubClass.prototype~expr1 | | | (subclass).A.prototype.a | (subclass).A.prototype | Member[a] | -| (subclass).B | subclass | Member[B] | +| (subclass).B | 'subclass' | Member[B] | | (subclass).B.prototype | (subclass).B | Instance | | (subclass).B.prototype | (subclass).C.prototype | | | (subclass).B.prototype.b | (subclass).B.prototype | Member[b] | -| (subclass).C | subclass | Member[C] | +| (subclass).C | 'subclass' | Member[C] | | (subclass).C.prototype | (subclass).C | Instance | | (subclass).C.prototype.c | (subclass).C.prototype | Member[c] | -| (subclass).D | subclass | Member[D] | +| (subclass).D | 'subclass' | Member[D] | | (subclass).D.prototype | (subclass).D | Instance | | (subclass).D.prototype.d | (subclass).D.prototype | Member[d] | -| (subclass).ExposedMidSubClass | subclass | Member[ExposedMidSubClass] | +| (subclass).ExposedMidSubClass | 'subclass' | Member[ExposedMidSubClass] | | (subclass).ExposedMidSubClass.prototype | (subclass).ExposedMidSubClass | Instance | | (subclass).ExposedMidSubClass.prototype.m | (subclass).ExposedMidSubClass.prototype | Member[m] | | (subclass).ExposedMidSubClass.prototype~expr1 | (subclass).ExposedMidSubClass.prototype | | +| upstream-lib | 'reexport' | Member[lib] | | upstream-lib | (reexport).func | ReturnValue | -| upstream-lib | reexport | Member[lib] | | upstream-lib.Type | (subclass).D.prototype | | -| upstream-lib.XYZ | reexport | Member[x].Member[y].Member[z] | -| upstream-lib.XYZ | reexport | Member[xy].Member[z] | +| upstream-lib.XYZ | 'reexport' | Member[x].Member[y].Member[z] | +| upstream-lib.XYZ | 'reexport' | Member[xy].Member[z] | summaryModel | (aliases).Alias1.prototype | | | Member[foo].ReturnValue | type | | (return-this).FluentInterface.prototype | | | Member[bar].ReturnValue | type | From db07c162e43e6a24a9fde8bab631cf05135f5c07 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 23 Apr 2024 20:25:55 +0200 Subject: [PATCH 018/238] JS: Allow generated models to use (package) --- .../frameworks/data/ModelsAsData.qll | 2 +- .../data/internal/ApiGraphModelsSpecific.qll | 8 ++++ .../ModelGeneration/ModelGeneration.expected | 44 +++++++++---------- .../frameworks/data/test.expected | 1 + .../frameworks/data/test.ext.yml | 3 +- .../library-tests/frameworks/data/test.js | 2 + 6 files changed, 36 insertions(+), 24 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/frameworks/data/ModelsAsData.qll b/javascript/ql/lib/semmle/javascript/frameworks/data/ModelsAsData.qll index fc3077d89865..6e95955749b4 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/data/ModelsAsData.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/data/ModelsAsData.qll @@ -111,7 +111,7 @@ module ModelExport { exists(string moduleName | node = API::moduleExport(moduleName) and path = "" and - type = "'" + moduleName + "'" + type = "(" + moduleName + ")" ) } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModelsSpecific.qll b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModelsSpecific.qll index 1a7b7e9bf32a..1b616a199bc0 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModelsSpecific.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModelsSpecific.qll @@ -34,6 +34,11 @@ class Location = JS::Location; * * Type names have form `package.type` or just `package` if referring to the package export * object. If `package` contains a `.` character it must be enclosed in single quotes, such as `'package'.type`. + * + * A type name of form `(package)` may also be used when refering to the package export object. + * We allow this syntax as an alternative to the above, so models generated based on `EndpointNaming` look more consistent. + * However, access paths are deliberately not parsed here, as we can not handle aliasing at this stage. + * The model generator must explicitly generate the step between `(package)` and `(package).foo`, for example. */ bindingset[rawType] predicate parseTypeString(string rawType, string package, string qualifiedName) { @@ -42,6 +47,9 @@ predicate parseTypeString(string rawType, string package, string qualifiedName) package = rawType.regexpCapture(regexp, 1).regexpReplaceAll("^'|'$", "") and qualifiedName = rawType.regexpCapture(regexp, 2).regexpReplaceAll("^\\.", "") ) + or + package = rawType.regexpCapture("[(]([^)]+)[)]", 1) and + qualifiedName = "" } /** diff --git a/javascript/ql/test/library-tests/ModelGeneration/ModelGeneration.expected b/javascript/ql/test/library-tests/ModelGeneration/ModelGeneration.expected index 7a5cae4f796d..d983b77b5383 100644 --- a/javascript/ql/test/library-tests/ModelGeneration/ModelGeneration.expected +++ b/javascript/ql/test/library-tests/ModelGeneration/ModelGeneration.expected @@ -1,17 +1,17 @@ typeModel -| (aliases).Alias1 | 'aliases' | Member[Alias1] | -| (aliases).Alias1 | 'aliases' | Member[Alias2] | -| (aliases).Alias1 | 'aliases' | Member[Alias3].Member[x] | -| (aliases).Alias1 | 'aliases' | Member[Alias4].Member[x].Member[x] | -| (aliases).Alias1 | 'aliases' | Member[AliasedClass] | +| (aliases).Alias1 | (aliases) | Member[Alias1] | +| (aliases).Alias1 | (aliases) | Member[Alias2] | +| (aliases).Alias1 | (aliases) | Member[Alias3].Member[x] | +| (aliases).Alias1 | (aliases) | Member[Alias4].Member[x].Member[x] | +| (aliases).Alias1 | (aliases) | Member[AliasedClass] | | (aliases).Alias1.prototype | (aliases).Alias1 | Instance | | (aliases).Alias1.prototype | (aliases).Alias1.prototype.foo | ReturnValue | | (aliases).Alias1.prototype.foo | (aliases).Alias1.prototype | Member[foo] | -| (long-access-path).a.shortcut.d | 'long-access-path' | Member[a].Member[b].Member[c].Member[d] | -| (long-access-path).a.shortcut.d | 'long-access-path' | Member[a].Member[shortcut].Member[d] | +| (long-access-path).a.shortcut.d | (long-access-path) | Member[a].Member[b].Member[c].Member[d] | +| (long-access-path).a.shortcut.d | (long-access-path) | Member[a].Member[shortcut].Member[d] | | (long-access-path).a.shortcut.d.e | (long-access-path).a.shortcut.d | Member[e] | -| (reexport).func | 'reexport' | Member[func] | -| (return-this).FluentInterface | 'return-this' | Member[FluentInterface] | +| (reexport).func | (reexport) | Member[func] | +| (return-this).FluentInterface | (return-this) | Member[FluentInterface] | | (return-this).FluentInterface.prototype | (return-this).FluentInterface | Instance | | (return-this).FluentInterface.prototype | (return-this).FluentInterface.prototype.bar | ReturnValue | | (return-this).FluentInterface.prototype | (return-this).FluentInterface.prototype.baz | ReturnValue | @@ -21,45 +21,45 @@ typeModel | (return-this).FluentInterface.prototype.foo | (return-this).FluentInterface.prototype | Member[foo] | | (return-this).FluentInterface.prototype.notFluent | (return-this).FluentInterface.prototype | Member[notFluent] | | (return-this).FluentInterface.prototype.notFluent2 | (return-this).FluentInterface.prototype | Member[notFluent2] | -| (root-function).PublicClass | 'root-function' | Member[PublicClass] | -| (root-function).PublicClass.prototype | 'root-function' | ReturnValue | +| (root-function).PublicClass | (root-function) | Member[PublicClass] | +| (root-function).PublicClass.prototype | (root-function) | ReturnValue | | (root-function).PublicClass.prototype | (root-function).PublicClass | Instance | | (root-function).PublicClass.prototype.method | (root-function).PublicClass.prototype | Member[method] | -| (semi-internal-class).PublicClass | 'semi-internal-class' | Member[PublicClass] | +| (semi-internal-class).PublicClass | (semi-internal-class) | Member[PublicClass] | | (semi-internal-class).PublicClass.prototype | (semi-internal-class).PublicClass | Instance | | (semi-internal-class).PublicClass.prototype | (semi-internal-class).SemiInternalClass.prototype.method | ReturnValue | | (semi-internal-class).PublicClass.prototype | (semi-internal-class).getAnonymous~expr2 | ReturnValue | | (semi-internal-class).PublicClass.prototype.publicMethod | (semi-internal-class).PublicClass.prototype | Member[publicMethod] | | (semi-internal-class).SemiInternalClass.prototype | (semi-internal-class).get | ReturnValue | | (semi-internal-class).SemiInternalClass.prototype.method | (semi-internal-class).SemiInternalClass.prototype | Member[method] | -| (semi-internal-class).get | 'semi-internal-class' | Member[get] | -| (semi-internal-class).getAnonymous | 'semi-internal-class' | Member[getAnonymous] | +| (semi-internal-class).get | (semi-internal-class) | Member[get] | +| (semi-internal-class).getAnonymous | (semi-internal-class) | Member[getAnonymous] | | (semi-internal-class).getAnonymous~expr1 | (semi-internal-class).getAnonymous | ReturnValue | | (semi-internal-class).getAnonymous~expr2 | (semi-internal-class).getAnonymous~expr1 | Member[method] | -| (subclass).A | 'subclass' | Member[A] | +| (subclass).A | (subclass) | Member[A] | | (subclass).A.prototype | (subclass).A | Instance | | (subclass).A.prototype | (subclass).B.prototype | | | (subclass).A.prototype | (subclass).ExposedMidSubClass.prototype~expr1 | | | (subclass).A.prototype.a | (subclass).A.prototype | Member[a] | -| (subclass).B | 'subclass' | Member[B] | +| (subclass).B | (subclass) | Member[B] | | (subclass).B.prototype | (subclass).B | Instance | | (subclass).B.prototype | (subclass).C.prototype | | | (subclass).B.prototype.b | (subclass).B.prototype | Member[b] | -| (subclass).C | 'subclass' | Member[C] | +| (subclass).C | (subclass) | Member[C] | | (subclass).C.prototype | (subclass).C | Instance | | (subclass).C.prototype.c | (subclass).C.prototype | Member[c] | -| (subclass).D | 'subclass' | Member[D] | +| (subclass).D | (subclass) | Member[D] | | (subclass).D.prototype | (subclass).D | Instance | | (subclass).D.prototype.d | (subclass).D.prototype | Member[d] | -| (subclass).ExposedMidSubClass | 'subclass' | Member[ExposedMidSubClass] | +| (subclass).ExposedMidSubClass | (subclass) | Member[ExposedMidSubClass] | | (subclass).ExposedMidSubClass.prototype | (subclass).ExposedMidSubClass | Instance | | (subclass).ExposedMidSubClass.prototype.m | (subclass).ExposedMidSubClass.prototype | Member[m] | | (subclass).ExposedMidSubClass.prototype~expr1 | (subclass).ExposedMidSubClass.prototype | | -| upstream-lib | 'reexport' | Member[lib] | +| upstream-lib | (reexport) | Member[lib] | | upstream-lib | (reexport).func | ReturnValue | | upstream-lib.Type | (subclass).D.prototype | | -| upstream-lib.XYZ | 'reexport' | Member[x].Member[y].Member[z] | -| upstream-lib.XYZ | 'reexport' | Member[xy].Member[z] | +| upstream-lib.XYZ | (reexport) | Member[x].Member[y].Member[z] | +| upstream-lib.XYZ | (reexport) | Member[xy].Member[z] | summaryModel | (aliases).Alias1.prototype | | | Member[foo].ReturnValue | type | | (return-this).FluentInterface.prototype | | | Member[bar].ReturnValue | type | diff --git a/javascript/ql/test/library-tests/frameworks/data/test.expected b/javascript/ql/test/library-tests/frameworks/data/test.expected index 843b1f32d5bc..d9b9d7e18e27 100644 --- a/javascript/ql/test/library-tests/frameworks/data/test.expected +++ b/javascript/ql/test/library-tests/frameworks/data/test.expected @@ -78,6 +78,7 @@ taintFlow | test.js:265:6:265:39 | new MyS ... ource() | test.js:265:6:265:39 | new MyS ... ource() | | test.js:269:10:269:31 | this.ba ... ource() | test.js:269:10:269:31 | this.ba ... ource() | | test.js:272:6:272:40 | new MyS ... ource() | test.js:272:6:272:40 | new MyS ... ource() | +| test.js:274:6:274:39 | testlib ... eName() | test.js:274:6:274:39 | testlib ... eName() | isSink | test.js:54:18:54:25 | source() | test-sink | | test.js:55:22:55:29 | source() | test-sink | diff --git a/javascript/ql/test/library-tests/frameworks/data/test.ext.yml b/javascript/ql/test/library-tests/frameworks/data/test.ext.yml index 2387cc03978a..8aec67669138 100644 --- a/javascript/ql/test/library-tests/frameworks/data/test.ext.yml +++ b/javascript/ql/test/library-tests/frameworks/data/test.ext.yml @@ -10,6 +10,7 @@ extensions: - ['testlib', 'Member[MethodDecorator].DecoratedMember.Parameter[0]', 'test-source'] - ['testlib', 'Member[ParamDecoratorSource].DecoratedParameter', 'test-source'] - ['testlib', 'Member[getSource].ReturnValue', 'test-source'] + - ['(testlib)', 'Member[parenthesizedPackageName].ReturnValue', 'test-source'] - addsTo: pack: codeql/javascript-all @@ -73,4 +74,4 @@ extensions: data: - ['ABC', 'Member[a].Member[b].WithArity[0].ReturnValue.Member[c]'] - ['LeftRight', 'Member[left].TypeVar[LeftRight].Member[right]'] - - ['LeftRight', 'Member[x]'] \ No newline at end of file + - ['LeftRight', 'Member[x]'] diff --git a/javascript/ql/test/library-tests/frameworks/data/test.js b/javascript/ql/test/library-tests/frameworks/data/test.js index bbcb10418a12..97bb49f8cf71 100644 --- a/javascript/ql/test/library-tests/frameworks/data/test.js +++ b/javascript/ql/test/library-tests/frameworks/data/test.js @@ -270,3 +270,5 @@ class MySubclass2 extends MySubclass { } } sink(new MySubclass2().baseclassSource()); // NOT OK + +sink(testlib.parenthesizedPackageName()); // NOT OK From f3daba510bd772cbc878212ae12ef123d4db134e Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Wed, 24 Apr 2024 11:57:34 +0200 Subject: [PATCH 019/238] C#: Fix `global.json` and `packages.config` lookup --- .../Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs | 2 +- .../Semmle.Extraction.CSharp.DependencyFetching/FileContent.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs index c573c5ff4e68..74c1a37154d5 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs @@ -143,7 +143,7 @@ private static BuildScript DownloadDotNet(IBuildActions actions, ILogger logger, // See https://docs.microsoft.com/en-us/dotnet/core/tools/global-json var versions = new List(); - foreach (var path in files.Where(p => p.EndsWith("global.json", StringComparison.Ordinal))) + foreach (var path in files.Where(p => p.EndsWith(Path.DirectorySeparatorChar + "global.json", StringComparison.Ordinal))) { try { diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/FileContent.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/FileContent.cs index 44cff0a80852..467289c7e0db 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/FileContent.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/FileContent.cs @@ -184,7 +184,7 @@ private void DoInitialize() { try { - var isPackagesConfig = file.EndsWith("packages.config", StringComparison.OrdinalIgnoreCase); + var isPackagesConfig = file.EndsWith(Path.DirectorySeparatorChar + "packages.config", StringComparison.OrdinalIgnoreCase); foreach (ReadOnlySpan line in unsafeFileReader.ReadLines(file)) { From 95d579d9de7542ff5d31b60ca40445cbf28f71cb Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 24 Apr 2024 12:22:11 +0200 Subject: [PATCH 020/238] Data flow: Fix bad join ``` Evaluated relational algebra for predicate _DataFlowImpl::Impl::ret__#count_range@d112335l with tuple counts: 285176 ~2% {3} r1 = SCAN `_DataFlowDispatch::DataFlowCall.getEnclosingCallable/0#dispred#b7b78b19_DataFlowImpl::Impl::returnCallEdge1/4#d02cae42_2301#join_rhs` ON FIRST 2 OUTPUT Lhs.0, Lhs.2, Rhs.2, Lhs.1, Rhs.3 39070 ~8% {6} | JOIN WITH `DataFlowImplCommon::Cached::viableImplInCallContextExt/2#58e931ad` ON FIRST 3 OUTPUT Lhs.0, Lhs.3, Lhs.1, Lhs.2, Lhs.4, _ 39070 ~0% {6} | REWRITE WITH Out.5 := 1 return r1 ``` --- .../codeql/dataflow/internal/DataFlowImpl.qll | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index 9dfbc3e0bcda..de9f718b347c 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -1142,6 +1142,14 @@ module MakeImpl Lang> { ) } + pragma[nomagic] + private predicate returnCallEdgeInCtx1( + DataFlowCallable c, SndLevelScopeOption scope, DataFlowCall call, NodeEx out, DataFlowCall ctx + ) { + returnCallEdge1(c, scope, call, out) and + c = viableImplInCallContextExt(call, ctx) + } + private int ctxDispatchFanoutOnReturn(NodeEx out, DataFlowCall ctx) { exists(DataFlowCall call, DataFlowCallable c | simpleDispatchFanoutOnReturn(call, out) > 1 and @@ -1151,8 +1159,7 @@ module MakeImpl Lang> { mayBenefitFromCallContextExt(call, _) and result = count(DataFlowCallable tgt, SndLevelScopeOption scope | - tgt = viableImplInCallContextExt(call, ctx) and - returnCallEdge1(tgt, scope, call, out) + returnCallEdgeInCtx1(tgt, scope, call, out, ctx) ) ) } From 8f2e51faa6641905bc29dfa28bc5df09fd575c1f Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Wed, 24 Apr 2024 12:32:49 +0100 Subject: [PATCH 021/238] Ruby: do fewer regexp matches in SensitiveActions --- .../codeql/ruby/security/SensitiveActions.qll | 55 +++++++++++++------ 1 file changed, 37 insertions(+), 18 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/security/SensitiveActions.qll b/ruby/ql/lib/codeql/ruby/security/SensitiveActions.qll index cc01ab4078bf..34beb33604b7 100644 --- a/ruby/ql/lib/codeql/ruby/security/SensitiveActions.qll +++ b/ruby/ql/lib/codeql/ruby/security/SensitiveActions.qll @@ -28,17 +28,13 @@ abstract class SensitiveNode extends DataFlow::Node { } /** A method call that might produce sensitive data. */ -class SensitiveCall extends SensitiveNode instanceof DataFlow::CallNode { +abstract class SensitiveCall extends SensitiveNode { } + +private class SensitiveDataMethodNameCall extends SensitiveCall instanceof DataFlow::CallNode { SensitiveDataClassification classification; - SensitiveCall() { + SensitiveDataMethodNameCall() { classification = this.getMethodName().(SensitiveDataMethodName).getClassification() - or - // This is particularly to pick up methods with an argument like "password", which - // may indicate a lookup. - exists(string s | super.getArgument(_).asExpr().getConstantValue().isStringlikeValue(s) | - nameIndicatesSensitiveData(s, classification) - ) } override string describe() { result = "a call to " + super.getMethodName() } @@ -46,6 +42,23 @@ class SensitiveCall extends SensitiveNode instanceof DataFlow::CallNode { override SensitiveDataClassification getClassification() { result = classification } } +private class SensitiveArgumentCall extends SensitiveCall instanceof DataFlow::CallNode { + string argName; + + SensitiveArgumentCall() { + // This is particularly to pick up methods with an argument like "password", which may indicate + // a lookup. + super.getArgument(_).asExpr().getConstantValue().isStringlikeValue(argName) and + nameIndicatesSensitiveData(argName) + } + + override string describe() { result = "a call to " + super.getMethodName() } + + override SensitiveDataClassification getClassification() { + nameIndicatesSensitiveData(argName, result) + } +} + /** An access to a variable or hash value that might contain sensitive data. */ abstract class SensitiveVariableAccess extends SensitiveNode { string name; @@ -93,7 +106,7 @@ private string unprefixedVariableName(string name) { result = name.regexpReplace /** A write to a variable or property that might contain sensitive data. */ private class BasicSensitiveWrite extends SensitiveWrite { - SensitiveDataClassification classification; + string unprefixedName; BasicSensitiveWrite() { exists(string name | @@ -111,23 +124,29 @@ private class BasicSensitiveWrite extends SensitiveWrite { */ writesProperty(this, name) and - nameIndicatesSensitiveData(unprefixedVariableName(name), classification) + unprefixedName = unprefixedVariableName(name) and + nameIndicatesSensitiveData(unprefixedName) ) } /** Gets a classification of the kind of sensitive data the write might handle. */ - SensitiveDataClassification getClassification() { result = classification } + SensitiveDataClassification getClassification() { + nameIndicatesSensitiveData(unprefixedName, result) + } } /** An access to a variable or hash value that might contain sensitive data. */ private class BasicSensitiveVariableAccess extends SensitiveVariableAccess { - SensitiveDataClassification classification; + string unprefixedName; BasicSensitiveVariableAccess() { - nameIndicatesSensitiveData(unprefixedVariableName(name), classification) + unprefixedName = unprefixedVariableName(name) and + nameIndicatesSensitiveData(unprefixedName) } - override SensitiveDataClassification getClassification() { result = classification } + override SensitiveDataClassification getClassification() { + nameIndicatesSensitiveData(unprefixedName, result) + } } /** A method name that suggests it may be sensitive. */ @@ -143,11 +162,11 @@ abstract class SensitiveDataMethodName extends SensitiveMethodName { /** A method name that might return sensitive credential data. */ class CredentialsMethodName extends SensitiveDataMethodName { - SensitiveDataClassification classification; - - CredentialsMethodName() { nameIndicatesSensitiveData(this, classification) } + CredentialsMethodName() { nameIndicatesSensitiveData(this) } - override SensitiveDataClassification getClassification() { result = classification } + override SensitiveDataClassification getClassification() { + nameIndicatesSensitiveData(this, result) + } } /** From 4a97f9589017937fd4f40f9a9a2d7c76e1b01452 Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Wed, 24 Apr 2024 13:47:25 +0200 Subject: [PATCH 022/238] Improve code quality --- .../DotNet.cs | 2 +- .../FileContent.cs | 2 +- .../DotnetSourceGeneratorBase.cs | 26 +------------ csharp/extractor/Semmle.Util/FileUtils.cs | 37 +++++++++++++++++++ 4 files changed, 40 insertions(+), 27 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs index 74c1a37154d5..95e8fe0675f4 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs @@ -143,7 +143,7 @@ private static BuildScript DownloadDotNet(IBuildActions actions, ILogger logger, // See https://docs.microsoft.com/en-us/dotnet/core/tools/global-json var versions = new List(); - foreach (var path in files.Where(p => p.EndsWith(Path.DirectorySeparatorChar + "global.json", StringComparison.Ordinal))) + foreach (var path in files.Where(p => string.Equals(FileUtils.SafeGetFileName(p, logger), "global.json", StringComparison.OrdinalIgnoreCase))) { try { diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/FileContent.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/FileContent.cs index 467289c7e0db..f33329046cf6 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/FileContent.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/FileContent.cs @@ -184,7 +184,7 @@ private void DoInitialize() { try { - var isPackagesConfig = file.EndsWith(Path.DirectorySeparatorChar + "packages.config", StringComparison.OrdinalIgnoreCase); + var isPackagesConfig = string.Equals(FileUtils.SafeGetFileName(file, logger), "packages.config", StringComparison.OrdinalIgnoreCase); foreach (ReadOnlySpan line in unsafeFileReader.ReadLines(file)) { diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/SourceGenerators/DotnetSourceGeneratorBase.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/SourceGenerators/DotnetSourceGeneratorBase.cs index 4d353ffbeea4..461590348df7 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/SourceGenerators/DotnetSourceGeneratorBase.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/SourceGenerators/DotnetSourceGeneratorBase.cs @@ -55,7 +55,7 @@ protected override IEnumerable Run() // group additional files by closes project file: var projects = fileProvider.Projects - .Select(p => (File: p, Directory: SafeGetDirectoryName(p))) + .Select(p => (File: p, Directory: FileUtils.SafeGetDirectoryName(p, logger))) .Where(p => p.Directory.Length > 0); var groupedFiles = new Dictionary>(); @@ -93,30 +93,6 @@ protected override IEnumerable Run() } } - private string SafeGetDirectoryName(string fileName) - { - try - { - var dir = Path.GetDirectoryName(fileName); - if (dir is null) - { - return ""; - } - - if (!dir.EndsWith(Path.DirectorySeparatorChar)) - { - dir += Path.DirectorySeparatorChar; - } - - return dir; - } - catch (Exception ex) - { - logger.LogDebug($"Failed to get directory name for {fileName}: {ex.Message}"); - return ""; - } - } - protected abstract ICollection AdditionalFiles { get; } protected abstract string FileType { get; } diff --git a/csharp/extractor/Semmle.Util/FileUtils.cs b/csharp/extractor/Semmle.Util/FileUtils.cs index 4a22877e3c10..4d9052bcc4ea 100644 --- a/csharp/extractor/Semmle.Util/FileUtils.cs +++ b/csharp/extractor/Semmle.Util/FileUtils.cs @@ -185,5 +185,42 @@ public static FileInfo CreateTemporaryFile(string extension, out bool shouldClea return new FileInfo(outputPath); } + + public static string SafeGetDirectoryName(string path, ILogger logger) + { + try + { + var dir = Path.GetDirectoryName(path); + if (dir is null) + { + return ""; + } + + if (!dir.EndsWith(Path.DirectorySeparatorChar)) + { + dir += Path.DirectorySeparatorChar; + } + + return dir; + } + catch (Exception ex) + { + logger.LogDebug($"Failed to get directory name for {path}: {ex.Message}"); + return ""; + } + } + + public static string? SafeGetFileName(string path, ILogger logger) + { + try + { + return Path.GetFileName(path); + } + catch (Exception ex) + { + logger.LogDebug($"Failed to get file name for {path}: {ex.Message}"); + return null; + } + } } } From 3ef7a0932ad9249539bb90dc3f4f1e3bb46fae6e Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 20 Mar 2024 10:50:59 +0000 Subject: [PATCH 023/238] Add flow through string concatenation --- go/ql/src/Security/CWE-020/IncompleteHostnameRegexp.ql | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/go/ql/src/Security/CWE-020/IncompleteHostnameRegexp.ql b/go/ql/src/Security/CWE-020/IncompleteHostnameRegexp.ql index 48731179127e..0392f09e801d 100644 --- a/go/ql/src/Security/CWE-020/IncompleteHostnameRegexp.ql +++ b/go/ql/src/Security/CWE-020/IncompleteHostnameRegexp.ql @@ -101,6 +101,10 @@ module IncompleteHostNameRegexpConfig implements DataFlow::ConfigSig { ) and not regexpGuardsError(sink) } + + predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + StringOps::Concatenation::taintStep(node1, node2) + } } module Flow = DataFlow::Global; From 0000c72329e778f15542c3764cdad8b6f3a8beb1 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 20 Mar 2024 11:01:50 +0000 Subject: [PATCH 024/238] Remove attempt at avoiding duplicate alerts --- go/ql/src/Security/CWE-020/IncompleteHostnameRegexp.ql | 5 ----- 1 file changed, 5 deletions(-) diff --git a/go/ql/src/Security/CWE-020/IncompleteHostnameRegexp.ql b/go/ql/src/Security/CWE-020/IncompleteHostnameRegexp.ql index 0392f09e801d..e114d924475c 100644 --- a/go/ql/src/Security/CWE-020/IncompleteHostnameRegexp.ql +++ b/go/ql/src/Security/CWE-020/IncompleteHostnameRegexp.ql @@ -84,11 +84,6 @@ module IncompleteHostNameRegexpConfig implements DataFlow::ConfigSig { exists(Expr e | e = source.asExpr() and isIncompleteHostNameRegexpPattern(e.getStringValue(), hostPart) - | - e instanceof StringLit - or - e instanceof AddExpr and - not isIncompleteHostNameRegexpPattern(e.(AddExpr).getAnOperand().getStringValue(), _) ) } From 89623072916531254942b03cda2491539f178bb1 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 23 Apr 2024 21:13:55 +0100 Subject: [PATCH 025/238] Add second good go file to tests --- .../CWE-020/IncompleteHostnameRegexpGood2.go | 2 +- .../IncompleteHostnameRegexpGood2.go | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/IncompleteHostnameRegexpGood2.go diff --git a/go/ql/src/Security/CWE-020/IncompleteHostnameRegexpGood2.go b/go/ql/src/Security/CWE-020/IncompleteHostnameRegexpGood2.go index 7c5df3f67426..c6c3fc069815 100644 --- a/go/ql/src/Security/CWE-020/IncompleteHostnameRegexpGood2.go +++ b/go/ql/src/Security/CWE-020/IncompleteHostnameRegexpGood2.go @@ -6,7 +6,7 @@ import ( "regexp" ) -func checkRedirectGood(req *http.Request, via []*http.Request) error { +func checkRedirectGood2(req *http.Request, via []*http.Request) error { // GOOD: the host of `req.URL` must be `example.com`, `www.example.com` or `beta.example.com` re := `^((www|beta)\.)?example\.com/` if matched, _ := regexp.MatchString(re, req.URL.Host); matched { diff --git a/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/IncompleteHostnameRegexpGood2.go b/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/IncompleteHostnameRegexpGood2.go new file mode 100644 index 000000000000..c6c3fc069815 --- /dev/null +++ b/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/IncompleteHostnameRegexpGood2.go @@ -0,0 +1,16 @@ +package main + +import ( + "errors" + "net/http" + "regexp" +) + +func checkRedirectGood2(req *http.Request, via []*http.Request) error { + // GOOD: the host of `req.URL` must be `example.com`, `www.example.com` or `beta.example.com` + re := `^((www|beta)\.)?example\.com/` + if matched, _ := regexp.MatchString(re, req.URL.Host); matched { + return nil + } + return errors.New("Invalid redirect") +} From fd306ed79be81f5305fbba653f8e88e967dce552 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 24 Apr 2024 12:19:11 +0100 Subject: [PATCH 026/238] Exclude constant names from sources to avoid duplicate results --- go/ql/src/Security/CWE-020/IncompleteHostnameRegexp.ql | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/go/ql/src/Security/CWE-020/IncompleteHostnameRegexp.ql b/go/ql/src/Security/CWE-020/IncompleteHostnameRegexp.ql index e114d924475c..03018ee1c32d 100644 --- a/go/ql/src/Security/CWE-020/IncompleteHostnameRegexp.ql +++ b/go/ql/src/Security/CWE-020/IncompleteHostnameRegexp.ql @@ -81,9 +81,12 @@ predicate regexpGuardsError(RegexpPattern regexp) { module IncompleteHostNameRegexpConfig implements DataFlow::ConfigSig { additional predicate isSourceString(DataFlow::Node source, string hostPart) { - exists(Expr e | - e = source.asExpr() and - isIncompleteHostNameRegexpPattern(e.getStringValue(), hostPart) + exists(Expr e | e = source.asExpr() | + isIncompleteHostNameRegexpPattern(e.getStringValue(), hostPart) and + // Exclude constant names to avoid duplicate results, because the string + // literals which they are initialised with are also considered as + // sources. + not e instanceof ConstantName ) } From 41409424795de9b79bc8ddbd4c64e73b50578059 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 24 Apr 2024 12:20:18 +0100 Subject: [PATCH 027/238] Update tests --- .../IncompleteHostnameRegexp.expected | 18 +++++++++++---- .../CWE-020/IncompleteHostnameRegexp/main.go | 22 ++++++++++++++++++- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/IncompleteHostnameRegexp.expected b/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/IncompleteHostnameRegexp.expected index 4486b4e0962f..c9ba782fd56b 100644 --- a/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/IncompleteHostnameRegexp.expected +++ b/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/IncompleteHostnameRegexp.expected @@ -1,12 +1,22 @@ edges | IncompleteHostnameRegexp.go:11:8:11:36 | "^((www\|beta).)?example.com/" | IncompleteHostnameRegexp.go:12:38:12:39 | re | provenance | | +| main.go:49:21:49:45 | `https://www.example.com` | main.go:62:15:62:25 | sourceConst | provenance | | +| main.go:62:15:62:25 | sourceConst | main.go:65:15:65:23 | localVar3 | provenance | | nodes | IncompleteHostnameRegexp.go:11:8:11:36 | "^((www\|beta).)?example.com/" | semmle.label | "^((www\|beta).)?example.com/" | | IncompleteHostnameRegexp.go:12:38:12:39 | re | semmle.label | re | -| main.go:39:60:39:79 | "^test2.github.com$" | semmle.label | "^test2.github.com$" | -| main.go:44:15:44:39 | `https://www.example.com` | semmle.label | `https://www.example.com` | +| main.go:40:60:40:79 | "^test2.github.com$" | semmle.label | "^test2.github.com$" | +| main.go:45:15:45:39 | `https://www.example.com` | semmle.label | `https://www.example.com` | +| main.go:49:21:49:45 | `https://www.example.com` | semmle.label | `https://www.example.com` | +| main.go:56:15:56:34 | ...+... | semmle.label | ...+... | +| main.go:58:15:58:42 | ...+... | semmle.label | ...+... | +| main.go:62:15:62:25 | sourceConst | semmle.label | sourceConst | +| main.go:65:15:65:23 | localVar3 | semmle.label | localVar3 | subpaths #select | IncompleteHostnameRegexp.go:11:8:11:36 | "^((www\|beta).)?example.com/" | IncompleteHostnameRegexp.go:11:8:11:36 | "^((www\|beta).)?example.com/" | IncompleteHostnameRegexp.go:12:38:12:39 | re | This regular expression has an unescaped dot before ')?example.com', so it might match more hosts than expected when $@. | IncompleteHostnameRegexp.go:12:38:12:39 | re | the regular expression is used | -| main.go:39:60:39:79 | "^test2.github.com$" | main.go:39:60:39:79 | "^test2.github.com$" | main.go:39:60:39:79 | "^test2.github.com$" | This regular expression has an unescaped dot before 'github.com', so it might match more hosts than expected when $@. | main.go:39:60:39:79 | "^test2.github.com$" | the regular expression is used | -| main.go:44:15:44:39 | `https://www.example.com` | main.go:44:15:44:39 | `https://www.example.com` | main.go:44:15:44:39 | `https://www.example.com` | This regular expression has an unescaped dot before 'example.com', so it might match more hosts than expected when $@. | main.go:44:15:44:39 | `https://www.example.com` | the regular expression is used | +| main.go:40:60:40:79 | "^test2.github.com$" | main.go:40:60:40:79 | "^test2.github.com$" | main.go:40:60:40:79 | "^test2.github.com$" | This regular expression has an unescaped dot before 'github.com', so it might match more hosts than expected when $@. | main.go:40:60:40:79 | "^test2.github.com$" | the regular expression is used | +| main.go:45:15:45:39 | `https://www.example.com` | main.go:45:15:45:39 | `https://www.example.com` | main.go:45:15:45:39 | `https://www.example.com` | This regular expression has an unescaped dot before 'example.com', so it might match more hosts than expected when $@. | main.go:45:15:45:39 | `https://www.example.com` | the regular expression is used | +| main.go:49:21:49:45 | `https://www.example.com` | main.go:49:21:49:45 | `https://www.example.com` | main.go:65:15:65:23 | localVar3 | This regular expression has an unescaped dot before 'example.com', so it might match more hosts than expected when $@. | main.go:65:15:65:23 | localVar3 | the regular expression is used | +| main.go:56:15:56:34 | ...+... | main.go:56:15:56:34 | ...+... | main.go:56:15:56:34 | ...+... | This regular expression has an unescaped dot before 'example.com', so it might match more hosts than expected when $@. | main.go:56:15:56:34 | ...+... | the regular expression is used | +| main.go:58:15:58:42 | ...+... | main.go:58:15:58:42 | ...+... | main.go:58:15:58:42 | ...+... | This regular expression has an unescaped dot before 'example.com', so it might match more hosts than expected when $@. | main.go:58:15:58:42 | ...+... | the regular expression is used | diff --git a/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/main.go b/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/main.go index fb1e5b77b516..7eda0d7255a2 100644 --- a/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/main.go +++ b/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/main.go @@ -3,10 +3,11 @@ package main import ( - "github.com/elazarl/goproxy" "net/http" "regexp" "time" + + "github.com/elazarl/goproxy" ) func Match(notARegex string) bool { @@ -44,3 +45,22 @@ func main() { regexp.Match(`https://www.example.com`, []byte("")) // NOT OK regexp.Match(`https://www\.example\.com`, []byte("")) // OK } + +const sourceConst = `https://www.example.com` +const firstHalfConst = `https://www.example.` + +func concatenateStrings() { + firstHalf := `https://www.example.` + regexp.Match(firstHalf+`com`, []byte("")) // MISSING: NOT OK + + regexp.Match(firstHalfConst+`com`, []byte("")) // NOT OK + + regexp.Match(`https://www.example.`+`com`, []byte("")) // NOT OK +} + +func avoidDuplicateResults() { + localVar1 := sourceConst + localVar2 := localVar1 + localVar3 := localVar2 + regexp.Match(localVar3, []byte("")) // NOT OK +} From c61177cf42d45784910d6999b625592f3f2fbb2d Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 24 Apr 2024 14:18:51 +0100 Subject: [PATCH 028/238] Add change note --- .../src/change-notes/2024-04-24-incomplete-hostname-regexp.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 go/ql/src/change-notes/2024-04-24-incomplete-hostname-regexp.md diff --git a/go/ql/src/change-notes/2024-04-24-incomplete-hostname-regexp.md b/go/ql/src/change-notes/2024-04-24-incomplete-hostname-regexp.md new file mode 100644 index 000000000000..3e7f0d593ec1 --- /dev/null +++ b/go/ql/src/change-notes/2024-04-24-incomplete-hostname-regexp.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The query `go/incomplete-hostname-regexp` now recognizes more sources involving concatenation of string literals and also follows flow through string concatenation. This may lead to more alerts. From 9f5782b67b4d62b410d2a1002c44983b260de55c Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 24 Apr 2024 15:49:48 +0200 Subject: [PATCH 029/238] Bazel: introduce buildifier formatting This introduces tooling and enforcement for formatting bazel files. The tooling is provided as a bazel run target from [keith/buildifier-prebuilt](https://github.com/keith/buildifier-prebuilt). This is used in a [`pre-commit`](https://pre-commit.com/) hook for those having that installed. In turn this is used in a CI check. Relying on a `pre-commit` action gives us easy checking that buildifying did not change anything in the files and printing the diff, without having to hand-roll the check ourselves. This enforcement will make usage of gazelle easier, as gazelle itself might reformat files, even outside of `go`. Having them properly formatted will allow gazelle to leave them unchanged, without needing to configure awkward exclude directives. --- .github/workflows/buildifier.yml | 26 +++++++++++++++++++++ .pre-commit-config.yaml | 10 ++++---- BUILD.bazel | 9 +++++++ MODULE.bazel | 2 ++ javascript/BUILD.bazel | 2 +- javascript/extractor/BUILD.bazel | 2 +- misc/codegen/BUILD.bazel | 2 -- misc/codegen/generators/BUILD.bazel | 2 -- python/extractor/tsg-python/tsp/BUILD.bazel | 2 +- swift/extractor/BUILD.bazel | 10 ++++---- swift/logging/BUILD.bazel | 2 +- 11 files changed, 52 insertions(+), 17 deletions(-) create mode 100644 .github/workflows/buildifier.yml diff --git a/.github/workflows/buildifier.yml b/.github/workflows/buildifier.yml new file mode 100644 index 000000000000..d5cea415d257 --- /dev/null +++ b/.github/workflows/buildifier.yml @@ -0,0 +1,26 @@ +name: Check bazel formatting + +on: + pull_request: + paths: + - "**.bazel" + - "**.bzl" + branches: + - main + - "rc/*" + +permissions: + contents: read + +jobs: + check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: pre-commit/action@646c83fcd040023954eafda54b4db0192ce70507 + with: + extra_args: buildifier --all-files --show-diff-on-failure + - if: failure() + run: | + echo "In order to format all files, please run:" + echo " bazel run //:buildifier" diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 383bc1103837..7fddd1929d4f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -20,13 +20,15 @@ repos: - id: autopep8 files: ^misc/codegen/.*\.py - - repo: https://github.com/warchant/pre-commit-buildifier - rev: 0.0.2 + - repo: local hooks: - id: buildifier + name: Format bazel files + files: \.(bazel|bzl) + language: system + entry: bazel run //:buildifier + pass_filenames: false - - repo: local - hooks: - id: codeql-format name: Fix QL file formatting files: \.qll?$ diff --git a/BUILD.bazel b/BUILD.bazel index e69de29bb2d1..3ccdcda5f129 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -0,0 +1,9 @@ +load("@buildifier_prebuilt//:rules.bzl", "buildifier") + +buildifier( + name = "buildifier", + exclude_patterns = [ + "./.git/*", + ], + lint_mode = "fix", +) diff --git a/MODULE.bazel b/MODULE.bazel index 4e1fe0d9f7cb..c834acab7aec 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -22,6 +22,8 @@ bazel_dep(name = "abseil-cpp", version = "20240116.0", repo_name = "absl") bazel_dep(name = "nlohmann_json", version = "3.11.3", repo_name = "json") bazel_dep(name = "fmt", version = "10.0.0") +bazel_dep(name = "buildifier_prebuilt", version = "6.4.0", dev_dependency = True) + pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip") pip.parse( hub_name = "codegen_deps", diff --git a/javascript/BUILD.bazel b/javascript/BUILD.bazel index eacfa554a8e1..18315a098138 100644 --- a/javascript/BUILD.bazel +++ b/javascript/BUILD.bazel @@ -1,5 +1,5 @@ -load("@semmle_code//:dist.bzl", "dist") load("@rules_pkg//pkg:mappings.bzl", "pkg_files") +load("@semmle_code//:dist.bzl", "dist") load("@semmle_code//buildutils-internal:zipmerge.bzl", "zipmerge") package(default_visibility = ["//visibility:public"]) diff --git a/javascript/extractor/BUILD.bazel b/javascript/extractor/BUILD.bazel index 6793287c22f7..360dc9370f94 100644 --- a/javascript/extractor/BUILD.bazel +++ b/javascript/extractor/BUILD.bazel @@ -1,5 +1,5 @@ -load("@semmle_code//:common.bzl", "codeql_fat_jar", "codeql_java_project") load("@rules_pkg//pkg:mappings.bzl", "pkg_files") +load("@semmle_code//:common.bzl", "codeql_fat_jar", "codeql_java_project") java_library( name = "deps", diff --git a/misc/codegen/BUILD.bazel b/misc/codegen/BUILD.bazel index 102e52fb10b8..52a5c0011345 100644 --- a/misc/codegen/BUILD.bazel +++ b/misc/codegen/BUILD.bazel @@ -1,5 +1,3 @@ -load("@codegen_deps//:requirements.bzl", "requirement") - py_binary( name = "codegen", srcs = ["codegen.py"], diff --git a/misc/codegen/generators/BUILD.bazel b/misc/codegen/generators/BUILD.bazel index df328a7df7f4..f731c42ce23a 100644 --- a/misc/codegen/generators/BUILD.bazel +++ b/misc/codegen/generators/BUILD.bazel @@ -1,5 +1,3 @@ -load("@codegen_deps//:requirements.bzl", "requirement") - py_library( name = "generators", srcs = glob(["*.py"]), diff --git a/python/extractor/tsg-python/tsp/BUILD.bazel b/python/extractor/tsg-python/tsp/BUILD.bazel index e3389fce1ccd..1f7ec006c657 100644 --- a/python/extractor/tsg-python/tsp/BUILD.bazel +++ b/python/extractor/tsg-python/tsp/BUILD.bazel @@ -1,6 +1,6 @@ +load("@py_deps//:defs.bzl", "aliases", "all_crate_deps") load("@rules_rust//cargo:defs.bzl", "cargo_build_script") load("@rules_rust//rust:defs.bzl", "rust_library") -load("@py_deps//:defs.bzl", "aliases", "all_crate_deps") package(default_visibility = ["//visibility:public"]) diff --git a/swift/extractor/BUILD.bazel b/swift/extractor/BUILD.bazel index 42c1105053cc..3acdbf014e34 100644 --- a/swift/extractor/BUILD.bazel +++ b/swift/extractor/BUILD.bazel @@ -1,5 +1,5 @@ -load("//swift:rules.bzl", "swift_cc_binary") load("//misc/bazel:pkg_runfiles.bzl", "pkg_runfiles") +load("//swift:rules.bzl", "swift_cc_binary") swift_cc_binary( name = "extractor.real", @@ -7,6 +7,10 @@ swift_cc_binary( "*.h", "*.cpp", ]), + linkopts = select({ + "@platforms//os:macos": ["-headerpad_max_install_names"], + "//conditions:default": [], + }), visibility = ["//swift:__pkg__"], deps = [ "//swift/extractor/config", @@ -17,10 +21,6 @@ swift_cc_binary( "//swift/third_party/swift-llvm-support", "@absl//absl/strings", ], - linkopts = select({ - "@platforms//os:macos": ["-headerpad_max_install_names"], - "//conditions:default": [], - }), ) sh_binary( diff --git a/swift/logging/BUILD.bazel b/swift/logging/BUILD.bazel index cd2f33441664..1d6192b3c13a 100644 --- a/swift/logging/BUILD.bazel +++ b/swift/logging/BUILD.bazel @@ -4,10 +4,10 @@ cc_library( hdrs = glob(["*.h"]), visibility = ["//visibility:public"], deps = [ + "//shared/cpp:extractor_shared", "@absl//absl/strings", "@binlog", "@fmt", "@json", - "//shared/cpp:extractor_shared", ], ) From 9af9873e04dedfae430d40eeeffc6e9125ade6e7 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 24 Apr 2024 16:20:54 +0200 Subject: [PATCH 030/238] CI: add names to steps --- .github/workflows/buildifier.yml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/workflows/buildifier.yml b/.github/workflows/buildifier.yml index d5cea415d257..f2a9dc880906 100644 --- a/.github/workflows/buildifier.yml +++ b/.github/workflows/buildifier.yml @@ -16,11 +16,15 @@ jobs: check: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: pre-commit/action@646c83fcd040023954eafda54b4db0192ce70507 + - name: Checkout + uses: actions/checkout@v4 + - name: Check bazel formatting + uses: pre-commit/action@646c83fcd040023954eafda54b4db0192ce70507 with: extra_args: buildifier --all-files --show-diff-on-failure - - if: failure() + - name: Print rectifying command + if: failure() run: | - echo "In order to format all files, please run:" + echo "In order to format all bazel files, please run:" echo " bazel run //:buildifier" + exit 1 From 9def57250dfe303cacf80daefbe5e2dabb818613 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 24 Apr 2024 16:34:07 +0200 Subject: [PATCH 031/238] CI: make reporting better --- .github/workflows/buildifier.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/buildifier.yml b/.github/workflows/buildifier.yml index f2a9dc880906..3cdfb046c584 100644 --- a/.github/workflows/buildifier.yml +++ b/.github/workflows/buildifier.yml @@ -21,10 +21,11 @@ jobs: - name: Check bazel formatting uses: pre-commit/action@646c83fcd040023954eafda54b4db0192ce70507 with: - extra_args: buildifier --all-files --show-diff-on-failure - - name: Print rectifying command + extra_args: buildifier --all-files 2>&1 | tee check_output + - name: Report if: failure() run: | + sed -ne '/diff --git/,$ p' check_output echo "In order to format all bazel files, please run:" echo " bazel run //:buildifier" exit 1 From 196b6d7a1d1921b322b64db775c1d3d349ea0c7a Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 24 Apr 2024 16:43:20 +0200 Subject: [PATCH 032/238] CI: simplify reporting --- .github/workflows/buildifier.yml | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/.github/workflows/buildifier.yml b/.github/workflows/buildifier.yml index 3cdfb046c584..82444d0440af 100644 --- a/.github/workflows/buildifier.yml +++ b/.github/workflows/buildifier.yml @@ -21,11 +21,8 @@ jobs: - name: Check bazel formatting uses: pre-commit/action@646c83fcd040023954eafda54b4db0192ce70507 with: - extra_args: buildifier --all-files 2>&1 | tee check_output - - name: Report - if: failure() - run: | - sed -ne '/diff --git/,$ p' check_output - echo "In order to format all bazel files, please run:" - echo " bazel run //:buildifier" - exit 1 + extra_args: > + buildifier --all-files 2>&1 || + ( + echo -e "In order to format all bazel files, please run:\n bazel run //:buildifier"; exit 1 + ) From 95ec4e8d26dea482dd54e9d56038734e32dbabbc Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Wed, 24 Apr 2024 21:47:47 +0200 Subject: [PATCH 033/238] C++: Fix comment in IR test --- cpp/ql/test/library-tests/ir/ir/ir.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/test/library-tests/ir/ir/ir.cpp b/cpp/ql/test/library-tests/ir/ir/ir.cpp index 17bfd2f90893..95b639aac6bf 100644 --- a/cpp/ql/test/library-tests/ir/ir/ir.cpp +++ b/cpp/ql/test/library-tests/ir/ir/ir.cpp @@ -2432,7 +2432,7 @@ void initialization_with_temp_destructor() { } void param_with_destructor_by_value(ClassWithDestructor c) { - // The call to ~ClassWithDestructor::ClassWithDestructor() seems to be missing here. + // The call to ~ClassWithDestructor::ClassWithDestructor() happens on the side of the caller } void param_with_destructor_by_pointer(ClassWithDestructor* c) { From 393f6b76664ee13517cd9c9cee918867f3432d1b Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 24 Apr 2024 17:04:57 +0200 Subject: [PATCH 034/238] Go: add gazelle-generated `BUILD` files --- .pre-commit-config.yaml | 7 +++++ MODULE.bazel | 7 +++++ go/extractor/.gitattributes | 1 + go/extractor/BUILD.bazel | 23 ++++++++++++++++ go/extractor/autobuilder/BUILD.bazel | 24 +++++++++++++++++ go/extractor/cli/go-autobuilder/BUILD.bazel | 22 +++++++++++++++ go/extractor/cli/go-bootstrap/BUILD.bazel | 14 ++++++++++ go/extractor/cli/go-build-runner/BUILD.bazel | 18 +++++++++++++ go/extractor/cli/go-extractor/BUILD.bazel | 18 +++++++++++++ go/extractor/cli/go-gen-dbscheme/BUILD.bazel | 15 +++++++++++ go/extractor/cli/go-tokenizer/BUILD.bazel | 14 ++++++++++ go/extractor/dbscheme/BUILD.bazel | 15 +++++++++++ go/extractor/diagnostics/BUILD.bazel | 8 ++++++ go/extractor/project/BUILD.bazel | 21 +++++++++++++++ go/extractor/srcarchive/BUILD.bazel | 17 ++++++++++++ go/extractor/toolchain/BUILD.bazel | 18 +++++++++++++ go/extractor/trap/BUILD.bazel | 23 ++++++++++++++++ go/extractor/util/BUILD.bazel | 14 ++++++++++ .../x/mod/internal/lazyregexp/BUILD.bazel | 9 +++++++ .../golang.org/x/mod/modfile/BUILD.bazel | 19 +++++++++++++ .../golang.org/x/mod/module/BUILD.bazel | 16 +++++++++++ .../golang.org/x/mod/semver/BUILD.bazel | 9 +++++++ .../x/tools/go/gcexportdata/BUILD.bazel | 13 +++++++++ .../go/internal/packagesdriver/BUILD.bazel | 10 +++++++ .../x/tools/go/packages/BUILD.bazel | 25 +++++++++++++++++ .../x/tools/go/types/objectpath/BUILD.bazel | 10 +++++++ .../x/tools/internal/event/BUILD.bazel | 17 ++++++++++++ .../x/tools/internal/event/core/BUILD.bazel | 17 ++++++++++++ .../x/tools/internal/event/keys/BUILD.bazel | 14 ++++++++++ .../x/tools/internal/event/label/BUILD.bazel | 9 +++++++ .../x/tools/internal/event/tag/BUILD.bazel | 10 +++++++ .../x/tools/internal/gcimporter/BUILD.bazel | 27 +++++++++++++++++++ .../x/tools/internal/gocommand/BUILD.bazel | 20 ++++++++++++++ .../internal/packagesinternal/BUILD.bazel | 9 +++++++ .../x/tools/internal/pkgbits/BUILD.bazel | 21 +++++++++++++++ .../tools/internal/tokeninternal/BUILD.bazel | 9 +++++++ .../x/tools/internal/typeparams/BUILD.bazel | 15 +++++++++++ .../tools/internal/typesinternal/BUILD.bazel | 14 ++++++++++ .../x/tools/internal/versions/BUILD.bazel | 15 +++++++++++ go/gazelle/BUILD.bazel | 8 ++++++ go/rules.bzl | 0 41 files changed, 595 insertions(+) create mode 100644 go/extractor/.gitattributes create mode 100644 go/extractor/BUILD.bazel create mode 100644 go/extractor/autobuilder/BUILD.bazel create mode 100644 go/extractor/cli/go-autobuilder/BUILD.bazel create mode 100644 go/extractor/cli/go-bootstrap/BUILD.bazel create mode 100644 go/extractor/cli/go-build-runner/BUILD.bazel create mode 100644 go/extractor/cli/go-extractor/BUILD.bazel create mode 100644 go/extractor/cli/go-gen-dbscheme/BUILD.bazel create mode 100644 go/extractor/cli/go-tokenizer/BUILD.bazel create mode 100644 go/extractor/dbscheme/BUILD.bazel create mode 100644 go/extractor/diagnostics/BUILD.bazel create mode 100644 go/extractor/project/BUILD.bazel create mode 100644 go/extractor/srcarchive/BUILD.bazel create mode 100644 go/extractor/toolchain/BUILD.bazel create mode 100644 go/extractor/trap/BUILD.bazel create mode 100644 go/extractor/util/BUILD.bazel create mode 100644 go/extractor/vendor/golang.org/x/mod/internal/lazyregexp/BUILD.bazel create mode 100644 go/extractor/vendor/golang.org/x/mod/modfile/BUILD.bazel create mode 100644 go/extractor/vendor/golang.org/x/mod/module/BUILD.bazel create mode 100644 go/extractor/vendor/golang.org/x/mod/semver/BUILD.bazel create mode 100644 go/extractor/vendor/golang.org/x/tools/go/gcexportdata/BUILD.bazel create mode 100644 go/extractor/vendor/golang.org/x/tools/go/internal/packagesdriver/BUILD.bazel create mode 100644 go/extractor/vendor/golang.org/x/tools/go/packages/BUILD.bazel create mode 100644 go/extractor/vendor/golang.org/x/tools/go/types/objectpath/BUILD.bazel create mode 100644 go/extractor/vendor/golang.org/x/tools/internal/event/BUILD.bazel create mode 100644 go/extractor/vendor/golang.org/x/tools/internal/event/core/BUILD.bazel create mode 100644 go/extractor/vendor/golang.org/x/tools/internal/event/keys/BUILD.bazel create mode 100644 go/extractor/vendor/golang.org/x/tools/internal/event/label/BUILD.bazel create mode 100644 go/extractor/vendor/golang.org/x/tools/internal/event/tag/BUILD.bazel create mode 100644 go/extractor/vendor/golang.org/x/tools/internal/gcimporter/BUILD.bazel create mode 100644 go/extractor/vendor/golang.org/x/tools/internal/gocommand/BUILD.bazel create mode 100644 go/extractor/vendor/golang.org/x/tools/internal/packagesinternal/BUILD.bazel create mode 100644 go/extractor/vendor/golang.org/x/tools/internal/pkgbits/BUILD.bazel create mode 100644 go/extractor/vendor/golang.org/x/tools/internal/tokeninternal/BUILD.bazel create mode 100644 go/extractor/vendor/golang.org/x/tools/internal/typeparams/BUILD.bazel create mode 100644 go/extractor/vendor/golang.org/x/tools/internal/typesinternal/BUILD.bazel create mode 100644 go/extractor/vendor/golang.org/x/tools/internal/versions/BUILD.bazel create mode 100644 go/gazelle/BUILD.bazel create mode 100644 go/rules.bzl diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 383bc1103837..4e81bcc7711c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -27,6 +27,13 @@ repos: - repo: local hooks: + - id: gazelle + name: Check gazelle-generated BUILD files + files: go/extractor/.* + language: system + entry: bazel run //go/gazelle + pass_filenames: false + - id: codeql-format name: Fix QL file formatting files: \.qll?$ diff --git a/MODULE.bazel b/MODULE.bazel index 4e1fe0d9f7cb..2dc9dd0a7bb5 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -14,6 +14,7 @@ local_path_override( # see https://registry.bazel.build/ for a list of available packages bazel_dep(name = "platforms", version = "0.0.8") +bazel_dep(name = "rules_go", version = "0.47.0") bazel_dep(name = "rules_pkg", version = "0.10.1") bazel_dep(name = "rules_nodejs", version = "6.0.3") bazel_dep(name = "rules_python", version = "0.31.0") @@ -22,6 +23,8 @@ bazel_dep(name = "abseil-cpp", version = "20240116.0", repo_name = "absl") bazel_dep(name = "nlohmann_json", version = "3.11.3", repo_name = "json") bazel_dep(name = "fmt", version = "10.0.0") +bazel_dep(name = "gazelle", version = "0.36.0", dev_dependency = True) + pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip") pip.parse( hub_name = "codegen_deps", @@ -50,6 +53,10 @@ node.toolchain( ) use_repo(node, "nodejs", "nodejs_toolchains") +go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk") +go_sdk.download(version = "1.22.2") +go_sdk.host() + register_toolchains( "@nodejs_toolchains//:all", ) diff --git a/go/extractor/.gitattributes b/go/extractor/.gitattributes new file mode 100644 index 000000000000..e406d4136778 --- /dev/null +++ b/go/extractor/.gitattributes @@ -0,0 +1 @@ +/*/**/BUILD.bazel linguist-generated=true diff --git a/go/extractor/BUILD.bazel b/go/extractor/BUILD.bazel new file mode 100644 index 000000000000..ea99340e7d75 --- /dev/null +++ b/go/extractor/BUILD.bazel @@ -0,0 +1,23 @@ +load("@rules_go//go:def.bzl", "go_library") + +# gazelle:prefix github.com/github/codeql-go/extractor + +go_library( + name = "extractor", + srcs = [ + "extractor.go", + "gomodextractor.go", + "semaphore.go", + ], + importpath = "github.com/github/codeql-go/extractor", + visibility = ["//visibility:public"], + deps = [ + "//go/extractor/dbscheme", + "//go/extractor/diagnostics", + "//go/extractor/srcarchive", + "//go/extractor/trap", + "//go/extractor/util", + "//go/extractor/vendor/golang.org/x/mod/modfile", + "//go/extractor/vendor/golang.org/x/tools/go/packages", + ], +) diff --git a/go/extractor/autobuilder/BUILD.bazel b/go/extractor/autobuilder/BUILD.bazel new file mode 100644 index 000000000000..b81b15816aa8 --- /dev/null +++ b/go/extractor/autobuilder/BUILD.bazel @@ -0,0 +1,24 @@ +load("@rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "autobuilder", + srcs = [ + "autobuilder.go", + "build-environment.go", + ], + importpath = "github.com/github/codeql-go/extractor/autobuilder", + visibility = ["//visibility:public"], + deps = [ + "//go/extractor/diagnostics", + "//go/extractor/project", + "//go/extractor/toolchain", + "//go/extractor/util", + "//go/extractor/vendor/golang.org/x/mod/semver", + ], +) + +go_test( + name = "autobuilder_test", + srcs = ["build-environment_test.go"], + embed = [":autobuilder"], +) diff --git a/go/extractor/cli/go-autobuilder/BUILD.bazel b/go/extractor/cli/go-autobuilder/BUILD.bazel new file mode 100644 index 000000000000..b53227b9f1bb --- /dev/null +++ b/go/extractor/cli/go-autobuilder/BUILD.bazel @@ -0,0 +1,22 @@ +load("@rules_go//go:def.bzl", "go_binary", "go_library") + +go_library( + name = "go-autobuilder_lib", + srcs = ["go-autobuilder.go"], + importpath = "github.com/github/codeql-go/extractor/cli/go-autobuilder", + visibility = ["//visibility:private"], + deps = [ + "//go/extractor/autobuilder", + "//go/extractor/diagnostics", + "//go/extractor/project", + "//go/extractor/toolchain", + "//go/extractor/util", + "//go/extractor/vendor/golang.org/x/mod/semver", + ], +) + +go_binary( + name = "go-autobuilder", + embed = [":go-autobuilder_lib"], + visibility = ["//visibility:public"], +) diff --git a/go/extractor/cli/go-bootstrap/BUILD.bazel b/go/extractor/cli/go-bootstrap/BUILD.bazel new file mode 100644 index 000000000000..15255227f9a4 --- /dev/null +++ b/go/extractor/cli/go-bootstrap/BUILD.bazel @@ -0,0 +1,14 @@ +load("@rules_go//go:def.bzl", "go_binary", "go_library") + +go_library( + name = "go-bootstrap_lib", + srcs = ["go-bootstrap.go"], + importpath = "github.com/github/codeql-go/extractor/cli/go-bootstrap", + visibility = ["//visibility:private"], +) + +go_binary( + name = "go-bootstrap", + embed = [":go-bootstrap_lib"], + visibility = ["//visibility:public"], +) diff --git a/go/extractor/cli/go-build-runner/BUILD.bazel b/go/extractor/cli/go-build-runner/BUILD.bazel new file mode 100644 index 000000000000..fc407c3e1724 --- /dev/null +++ b/go/extractor/cli/go-build-runner/BUILD.bazel @@ -0,0 +1,18 @@ +load("@rules_go//go:def.bzl", "go_binary", "go_library") + +go_library( + name = "go-build-runner_lib", + srcs = ["go-build-runner.go"], + importpath = "github.com/github/codeql-go/extractor/cli/go-build-runner", + visibility = ["//visibility:private"], + deps = [ + "//go/extractor/autobuilder", + "//go/extractor/util", + ], +) + +go_binary( + name = "go-build-runner", + embed = [":go-build-runner_lib"], + visibility = ["//visibility:public"], +) diff --git a/go/extractor/cli/go-extractor/BUILD.bazel b/go/extractor/cli/go-extractor/BUILD.bazel new file mode 100644 index 000000000000..9419c6f8ba93 --- /dev/null +++ b/go/extractor/cli/go-extractor/BUILD.bazel @@ -0,0 +1,18 @@ +load("@rules_go//go:def.bzl", "go_binary", "go_library") + +go_library( + name = "go-extractor_lib", + srcs = ["go-extractor.go"], + importpath = "github.com/github/codeql-go/extractor/cli/go-extractor", + visibility = ["//visibility:private"], + deps = [ + "//go/extractor", + "//go/extractor/diagnostics", + ], +) + +go_binary( + name = "go-extractor", + embed = [":go-extractor_lib"], + visibility = ["//visibility:public"], +) diff --git a/go/extractor/cli/go-gen-dbscheme/BUILD.bazel b/go/extractor/cli/go-gen-dbscheme/BUILD.bazel new file mode 100644 index 000000000000..1fbd75998c23 --- /dev/null +++ b/go/extractor/cli/go-gen-dbscheme/BUILD.bazel @@ -0,0 +1,15 @@ +load("@rules_go//go:def.bzl", "go_binary", "go_library") + +go_library( + name = "go-gen-dbscheme_lib", + srcs = ["go-gen-dbscheme.go"], + importpath = "github.com/github/codeql-go/extractor/cli/go-gen-dbscheme", + visibility = ["//visibility:private"], + deps = ["//go/extractor/dbscheme"], +) + +go_binary( + name = "go-gen-dbscheme", + embed = [":go-gen-dbscheme_lib"], + visibility = ["//visibility:public"], +) diff --git a/go/extractor/cli/go-tokenizer/BUILD.bazel b/go/extractor/cli/go-tokenizer/BUILD.bazel new file mode 100644 index 000000000000..f55baecc69f3 --- /dev/null +++ b/go/extractor/cli/go-tokenizer/BUILD.bazel @@ -0,0 +1,14 @@ +load("@rules_go//go:def.bzl", "go_binary", "go_library") + +go_library( + name = "go-tokenizer_lib", + srcs = ["go-tokenizer.go"], + importpath = "github.com/github/codeql-go/extractor/cli/go-tokenizer", + visibility = ["//visibility:private"], +) + +go_binary( + name = "go-tokenizer", + embed = [":go-tokenizer_lib"], + visibility = ["//visibility:public"], +) diff --git a/go/extractor/dbscheme/BUILD.bazel b/go/extractor/dbscheme/BUILD.bazel new file mode 100644 index 000000000000..efaf51684d74 --- /dev/null +++ b/go/extractor/dbscheme/BUILD.bazel @@ -0,0 +1,15 @@ +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "dbscheme", + srcs = [ + "dbscheme.go", + "tables.go", + ], + importpath = "github.com/github/codeql-go/extractor/dbscheme", + visibility = ["//visibility:public"], + deps = [ + "//go/extractor/trap", + "//go/extractor/vendor/golang.org/x/tools/go/packages", + ], +) diff --git a/go/extractor/diagnostics/BUILD.bazel b/go/extractor/diagnostics/BUILD.bazel new file mode 100644 index 000000000000..8b218dc1317c --- /dev/null +++ b/go/extractor/diagnostics/BUILD.bazel @@ -0,0 +1,8 @@ +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "diagnostics", + srcs = ["diagnostics.go"], + importpath = "github.com/github/codeql-go/extractor/diagnostics", + visibility = ["//visibility:public"], +) diff --git a/go/extractor/project/BUILD.bazel b/go/extractor/project/BUILD.bazel new file mode 100644 index 000000000000..dd49b3b320f8 --- /dev/null +++ b/go/extractor/project/BUILD.bazel @@ -0,0 +1,21 @@ +load("@rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "project", + srcs = ["project.go"], + importpath = "github.com/github/codeql-go/extractor/project", + visibility = ["//visibility:public"], + deps = [ + "//go/extractor/diagnostics", + "//go/extractor/toolchain", + "//go/extractor/util", + "//go/extractor/vendor/golang.org/x/mod/modfile", + "//go/extractor/vendor/golang.org/x/mod/semver", + ], +) + +go_test( + name = "project_test", + srcs = ["project_test.go"], + embed = [":project"], +) diff --git a/go/extractor/srcarchive/BUILD.bazel b/go/extractor/srcarchive/BUILD.bazel new file mode 100644 index 000000000000..90664c90190e --- /dev/null +++ b/go/extractor/srcarchive/BUILD.bazel @@ -0,0 +1,17 @@ +load("@rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "srcarchive", + srcs = [ + "projectlayout.go", + "srcarchive.go", + ], + importpath = "github.com/github/codeql-go/extractor/srcarchive", + visibility = ["//visibility:public"], +) + +go_test( + name = "srcarchive_test", + srcs = ["projectlayout_test.go"], + embed = [":srcarchive"], +) diff --git a/go/extractor/toolchain/BUILD.bazel b/go/extractor/toolchain/BUILD.bazel new file mode 100644 index 000000000000..d1ce09c26329 --- /dev/null +++ b/go/extractor/toolchain/BUILD.bazel @@ -0,0 +1,18 @@ +load("@rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "toolchain", + srcs = ["toolchain.go"], + importpath = "github.com/github/codeql-go/extractor/toolchain", + visibility = ["//visibility:public"], + deps = [ + "//go/extractor/util", + "//go/extractor/vendor/golang.org/x/mod/semver", + ], +) + +go_test( + name = "toolchain_test", + srcs = ["toolchain_test.go"], + embed = [":toolchain"], +) diff --git a/go/extractor/trap/BUILD.bazel b/go/extractor/trap/BUILD.bazel new file mode 100644 index 000000000000..6c3f67b32478 --- /dev/null +++ b/go/extractor/trap/BUILD.bazel @@ -0,0 +1,23 @@ +load("@rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "trap", + srcs = [ + "labels.go", + "trapwriter.go", + "util.go", + ], + importpath = "github.com/github/codeql-go/extractor/trap", + visibility = ["//visibility:public"], + deps = [ + "//go/extractor/srcarchive", + "//go/extractor/util", + "//go/extractor/vendor/golang.org/x/tools/go/packages", + ], +) + +go_test( + name = "trap_test", + srcs = ["trapwriter_test.go"], + embed = [":trap"], +) diff --git a/go/extractor/util/BUILD.bazel b/go/extractor/util/BUILD.bazel new file mode 100644 index 000000000000..787a627b5bcc --- /dev/null +++ b/go/extractor/util/BUILD.bazel @@ -0,0 +1,14 @@ +load("@rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "util", + srcs = ["util.go"], + importpath = "github.com/github/codeql-go/extractor/util", + visibility = ["//visibility:public"], +) + +go_test( + name = "util_test", + srcs = ["util_test.go"], + embed = [":util"], +) diff --git a/go/extractor/vendor/golang.org/x/mod/internal/lazyregexp/BUILD.bazel b/go/extractor/vendor/golang.org/x/mod/internal/lazyregexp/BUILD.bazel new file mode 100644 index 000000000000..33c06c34bec7 --- /dev/null +++ b/go/extractor/vendor/golang.org/x/mod/internal/lazyregexp/BUILD.bazel @@ -0,0 +1,9 @@ +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "lazyregexp", + srcs = ["lazyre.go"], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/mod/internal/lazyregexp", + importpath = "golang.org/x/mod/internal/lazyregexp", + visibility = ["//go/extractor/vendor/golang.org/x/mod:__subpackages__"], +) diff --git a/go/extractor/vendor/golang.org/x/mod/modfile/BUILD.bazel b/go/extractor/vendor/golang.org/x/mod/modfile/BUILD.bazel new file mode 100644 index 000000000000..7b5a78d785cf --- /dev/null +++ b/go/extractor/vendor/golang.org/x/mod/modfile/BUILD.bazel @@ -0,0 +1,19 @@ +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "modfile", + srcs = [ + "print.go", + "read.go", + "rule.go", + "work.go", + ], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/mod/modfile", + importpath = "golang.org/x/mod/modfile", + visibility = ["//visibility:public"], + deps = [ + "//go/extractor/vendor/golang.org/x/mod/internal/lazyregexp", + "//go/extractor/vendor/golang.org/x/mod/module", + "//go/extractor/vendor/golang.org/x/mod/semver", + ], +) diff --git a/go/extractor/vendor/golang.org/x/mod/module/BUILD.bazel b/go/extractor/vendor/golang.org/x/mod/module/BUILD.bazel new file mode 100644 index 000000000000..46ff4dbb7d14 --- /dev/null +++ b/go/extractor/vendor/golang.org/x/mod/module/BUILD.bazel @@ -0,0 +1,16 @@ +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "module", + srcs = [ + "module.go", + "pseudo.go", + ], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/mod/module", + importpath = "golang.org/x/mod/module", + visibility = ["//visibility:public"], + deps = [ + "//go/extractor/vendor/golang.org/x/mod/internal/lazyregexp", + "//go/extractor/vendor/golang.org/x/mod/semver", + ], +) diff --git a/go/extractor/vendor/golang.org/x/mod/semver/BUILD.bazel b/go/extractor/vendor/golang.org/x/mod/semver/BUILD.bazel new file mode 100644 index 000000000000..5b54efe19818 --- /dev/null +++ b/go/extractor/vendor/golang.org/x/mod/semver/BUILD.bazel @@ -0,0 +1,9 @@ +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "semver", + srcs = ["semver.go"], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/mod/semver", + importpath = "golang.org/x/mod/semver", + visibility = ["//visibility:public"], +) diff --git a/go/extractor/vendor/golang.org/x/tools/go/gcexportdata/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/go/gcexportdata/BUILD.bazel new file mode 100644 index 000000000000..57f503f1cb23 --- /dev/null +++ b/go/extractor/vendor/golang.org/x/tools/go/gcexportdata/BUILD.bazel @@ -0,0 +1,13 @@ +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "gcexportdata", + srcs = [ + "gcexportdata.go", + "importer.go", + ], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/tools/go/gcexportdata", + importpath = "golang.org/x/tools/go/gcexportdata", + visibility = ["//visibility:public"], + deps = ["//go/extractor/vendor/golang.org/x/tools/internal/gcimporter"], +) diff --git a/go/extractor/vendor/golang.org/x/tools/go/internal/packagesdriver/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/go/internal/packagesdriver/BUILD.bazel new file mode 100644 index 000000000000..962442de1e00 --- /dev/null +++ b/go/extractor/vendor/golang.org/x/tools/go/internal/packagesdriver/BUILD.bazel @@ -0,0 +1,10 @@ +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "packagesdriver", + srcs = ["sizes.go"], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/tools/go/internal/packagesdriver", + importpath = "golang.org/x/tools/go/internal/packagesdriver", + visibility = ["//go/extractor/vendor/golang.org/x/tools/go:__subpackages__"], + deps = ["//go/extractor/vendor/golang.org/x/tools/internal/gocommand"], +) diff --git a/go/extractor/vendor/golang.org/x/tools/go/packages/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/go/packages/BUILD.bazel new file mode 100644 index 000000000000..1cad8baca98a --- /dev/null +++ b/go/extractor/vendor/golang.org/x/tools/go/packages/BUILD.bazel @@ -0,0 +1,25 @@ +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "packages", + srcs = [ + "doc.go", + "external.go", + "golist.go", + "golist_overlay.go", + "loadmode_string.go", + "packages.go", + "visit.go", + ], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/tools/go/packages", + importpath = "golang.org/x/tools/go/packages", + visibility = ["//visibility:public"], + deps = [ + "//go/extractor/vendor/golang.org/x/tools/go/gcexportdata", + "//go/extractor/vendor/golang.org/x/tools/go/internal/packagesdriver", + "//go/extractor/vendor/golang.org/x/tools/internal/gocommand", + "//go/extractor/vendor/golang.org/x/tools/internal/packagesinternal", + "//go/extractor/vendor/golang.org/x/tools/internal/typesinternal", + "//go/extractor/vendor/golang.org/x/tools/internal/versions", + ], +) diff --git a/go/extractor/vendor/golang.org/x/tools/go/types/objectpath/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/go/types/objectpath/BUILD.bazel new file mode 100644 index 000000000000..1029221f434c --- /dev/null +++ b/go/extractor/vendor/golang.org/x/tools/go/types/objectpath/BUILD.bazel @@ -0,0 +1,10 @@ +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "objectpath", + srcs = ["objectpath.go"], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/tools/go/types/objectpath", + importpath = "golang.org/x/tools/go/types/objectpath", + visibility = ["//visibility:public"], + deps = ["//go/extractor/vendor/golang.org/x/tools/internal/typeparams"], +) diff --git a/go/extractor/vendor/golang.org/x/tools/internal/event/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/internal/event/BUILD.bazel new file mode 100644 index 000000000000..b882fef0d8cc --- /dev/null +++ b/go/extractor/vendor/golang.org/x/tools/internal/event/BUILD.bazel @@ -0,0 +1,17 @@ +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "event", + srcs = [ + "doc.go", + "event.go", + ], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/tools/internal/event", + importpath = "golang.org/x/tools/internal/event", + visibility = ["//go/extractor/vendor/golang.org/x/tools:__subpackages__"], + deps = [ + "//go/extractor/vendor/golang.org/x/tools/internal/event/core", + "//go/extractor/vendor/golang.org/x/tools/internal/event/keys", + "//go/extractor/vendor/golang.org/x/tools/internal/event/label", + ], +) diff --git a/go/extractor/vendor/golang.org/x/tools/internal/event/core/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/internal/event/core/BUILD.bazel new file mode 100644 index 000000000000..36bd68eed9f9 --- /dev/null +++ b/go/extractor/vendor/golang.org/x/tools/internal/event/core/BUILD.bazel @@ -0,0 +1,17 @@ +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "core", + srcs = [ + "event.go", + "export.go", + "fast.go", + ], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/tools/internal/event/core", + importpath = "golang.org/x/tools/internal/event/core", + visibility = ["//go/extractor/vendor/golang.org/x/tools:__subpackages__"], + deps = [ + "//go/extractor/vendor/golang.org/x/tools/internal/event/keys", + "//go/extractor/vendor/golang.org/x/tools/internal/event/label", + ], +) diff --git a/go/extractor/vendor/golang.org/x/tools/internal/event/keys/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/internal/event/keys/BUILD.bazel new file mode 100644 index 000000000000..f1674735052e --- /dev/null +++ b/go/extractor/vendor/golang.org/x/tools/internal/event/keys/BUILD.bazel @@ -0,0 +1,14 @@ +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "keys", + srcs = [ + "keys.go", + "standard.go", + "util.go", + ], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/tools/internal/event/keys", + importpath = "golang.org/x/tools/internal/event/keys", + visibility = ["//go/extractor/vendor/golang.org/x/tools:__subpackages__"], + deps = ["//go/extractor/vendor/golang.org/x/tools/internal/event/label"], +) diff --git a/go/extractor/vendor/golang.org/x/tools/internal/event/label/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/internal/event/label/BUILD.bazel new file mode 100644 index 000000000000..2329754d6cfc --- /dev/null +++ b/go/extractor/vendor/golang.org/x/tools/internal/event/label/BUILD.bazel @@ -0,0 +1,9 @@ +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "label", + srcs = ["label.go"], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/tools/internal/event/label", + importpath = "golang.org/x/tools/internal/event/label", + visibility = ["//go/extractor/vendor/golang.org/x/tools:__subpackages__"], +) diff --git a/go/extractor/vendor/golang.org/x/tools/internal/event/tag/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/internal/event/tag/BUILD.bazel new file mode 100644 index 000000000000..276dc5f4489a --- /dev/null +++ b/go/extractor/vendor/golang.org/x/tools/internal/event/tag/BUILD.bazel @@ -0,0 +1,10 @@ +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "tag", + srcs = ["tag.go"], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/tools/internal/event/tag", + importpath = "golang.org/x/tools/internal/event/tag", + visibility = ["//go/extractor/vendor/golang.org/x/tools:__subpackages__"], + deps = ["//go/extractor/vendor/golang.org/x/tools/internal/event/keys"], +) diff --git a/go/extractor/vendor/golang.org/x/tools/internal/gcimporter/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/internal/gcimporter/BUILD.bazel new file mode 100644 index 000000000000..1879fe0dadf5 --- /dev/null +++ b/go/extractor/vendor/golang.org/x/tools/internal/gcimporter/BUILD.bazel @@ -0,0 +1,27 @@ +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "gcimporter", + srcs = [ + "bimport.go", + "exportdata.go", + "gcimporter.go", + "iexport.go", + "iimport.go", + "newInterface10.go", + "newInterface11.go", + "support_go117.go", + "support_go118.go", + "unified_no.go", + "ureader_no.go", + "ureader_yes.go", + ], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/tools/internal/gcimporter", + importpath = "golang.org/x/tools/internal/gcimporter", + visibility = ["//go/extractor/vendor/golang.org/x/tools:__subpackages__"], + deps = [ + "//go/extractor/vendor/golang.org/x/tools/go/types/objectpath", + "//go/extractor/vendor/golang.org/x/tools/internal/pkgbits", + "//go/extractor/vendor/golang.org/x/tools/internal/tokeninternal", + ], +) diff --git a/go/extractor/vendor/golang.org/x/tools/internal/gocommand/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/internal/gocommand/BUILD.bazel new file mode 100644 index 000000000000..58f7091b49c0 --- /dev/null +++ b/go/extractor/vendor/golang.org/x/tools/internal/gocommand/BUILD.bazel @@ -0,0 +1,20 @@ +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "gocommand", + srcs = [ + "invoke.go", + "vendor.go", + "version.go", + ], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/tools/internal/gocommand", + importpath = "golang.org/x/tools/internal/gocommand", + visibility = ["//go/extractor/vendor/golang.org/x/tools:__subpackages__"], + deps = [ + "//go/extractor/vendor/golang.org/x/mod/semver", + "//go/extractor/vendor/golang.org/x/tools/internal/event", + "//go/extractor/vendor/golang.org/x/tools/internal/event/keys", + "//go/extractor/vendor/golang.org/x/tools/internal/event/label", + "//go/extractor/vendor/golang.org/x/tools/internal/event/tag", + ], +) diff --git a/go/extractor/vendor/golang.org/x/tools/internal/packagesinternal/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/internal/packagesinternal/BUILD.bazel new file mode 100644 index 000000000000..3ed918c94899 --- /dev/null +++ b/go/extractor/vendor/golang.org/x/tools/internal/packagesinternal/BUILD.bazel @@ -0,0 +1,9 @@ +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "packagesinternal", + srcs = ["packages.go"], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/tools/internal/packagesinternal", + importpath = "golang.org/x/tools/internal/packagesinternal", + visibility = ["//go/extractor/vendor/golang.org/x/tools:__subpackages__"], +) diff --git a/go/extractor/vendor/golang.org/x/tools/internal/pkgbits/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/internal/pkgbits/BUILD.bazel new file mode 100644 index 000000000000..820e8f04c9b5 --- /dev/null +++ b/go/extractor/vendor/golang.org/x/tools/internal/pkgbits/BUILD.bazel @@ -0,0 +1,21 @@ +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "pkgbits", + srcs = [ + "codes.go", + "decoder.go", + "doc.go", + "encoder.go", + "flags.go", + "frames_go1.go", + "frames_go17.go", + "reloc.go", + "support.go", + "sync.go", + "syncmarker_string.go", + ], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/tools/internal/pkgbits", + importpath = "golang.org/x/tools/internal/pkgbits", + visibility = ["//go/extractor/vendor/golang.org/x/tools:__subpackages__"], +) diff --git a/go/extractor/vendor/golang.org/x/tools/internal/tokeninternal/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/internal/tokeninternal/BUILD.bazel new file mode 100644 index 000000000000..ff66085dbdba --- /dev/null +++ b/go/extractor/vendor/golang.org/x/tools/internal/tokeninternal/BUILD.bazel @@ -0,0 +1,9 @@ +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "tokeninternal", + srcs = ["tokeninternal.go"], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/tools/internal/tokeninternal", + importpath = "golang.org/x/tools/internal/tokeninternal", + visibility = ["//go/extractor/vendor/golang.org/x/tools:__subpackages__"], +) diff --git a/go/extractor/vendor/golang.org/x/tools/internal/typeparams/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/internal/typeparams/BUILD.bazel new file mode 100644 index 000000000000..266816d9ea27 --- /dev/null +++ b/go/extractor/vendor/golang.org/x/tools/internal/typeparams/BUILD.bazel @@ -0,0 +1,15 @@ +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "typeparams", + srcs = [ + "common.go", + "coretype.go", + "normalize.go", + "termlist.go", + "typeterm.go", + ], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/tools/internal/typeparams", + importpath = "golang.org/x/tools/internal/typeparams", + visibility = ["//go/extractor/vendor/golang.org/x/tools:__subpackages__"], +) diff --git a/go/extractor/vendor/golang.org/x/tools/internal/typesinternal/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/internal/typesinternal/BUILD.bazel new file mode 100644 index 000000000000..c03b8a36ef7a --- /dev/null +++ b/go/extractor/vendor/golang.org/x/tools/internal/typesinternal/BUILD.bazel @@ -0,0 +1,14 @@ +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "typesinternal", + srcs = [ + "errorcode.go", + "errorcode_string.go", + "types.go", + "types_118.go", + ], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/tools/internal/typesinternal", + importpath = "golang.org/x/tools/internal/typesinternal", + visibility = ["//go/extractor/vendor/golang.org/x/tools:__subpackages__"], +) diff --git a/go/extractor/vendor/golang.org/x/tools/internal/versions/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/internal/versions/BUILD.bazel new file mode 100644 index 000000000000..6d7ffd0ac686 --- /dev/null +++ b/go/extractor/vendor/golang.org/x/tools/internal/versions/BUILD.bazel @@ -0,0 +1,15 @@ +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "versions", + srcs = [ + "gover.go", + "types.go", + "types_go121.go", + "types_go122.go", + "versions.go", + ], + importmap = "github.com/github/codeql-go/extractor/vendor/golang.org/x/tools/internal/versions", + importpath = "golang.org/x/tools/internal/versions", + visibility = ["//go/extractor/vendor/golang.org/x/tools:__subpackages__"], +) diff --git a/go/gazelle/BUILD.bazel b/go/gazelle/BUILD.bazel new file mode 100644 index 000000000000..7c9b34edb3a6 --- /dev/null +++ b/go/gazelle/BUILD.bazel @@ -0,0 +1,8 @@ +load("@gazelle//:def.bzl", "gazelle") + +gazelle( + name = "gazelle", + extra_args = [ + "go/extractor", + ], +) diff --git a/go/rules.bzl b/go/rules.bzl new file mode 100644 index 000000000000..e69de29bb2d1 From 4ca8faa9c944faa1005046c2c5cef3f6d68131b3 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 25 Apr 2024 09:14:59 +0200 Subject: [PATCH 035/238] Go: introduce universal binaries on macOS --- MODULE.bazel | 3 ++- go/BUILD.bazel | 0 go/extractor/BUILD.bazel | 1 + go/extractor/cli/go-autobuilder/BUILD.bazel | 5 ++-- go/extractor/cli/go-bootstrap/BUILD.bazel | 5 ++-- go/extractor/cli/go-build-runner/BUILD.bazel | 5 ++-- go/extractor/cli/go-extractor/BUILD.bazel | 5 ++-- go/extractor/cli/go-gen-dbscheme/BUILD.bazel | 5 ++-- go/extractor/cli/go-tokenizer/BUILD.bazel | 5 ++-- go/rules.bzl | 5 ++++ misc/bazel/universal_binary.bzl | 24 ++++++++++++++++++++ 11 files changed, 50 insertions(+), 13 deletions(-) create mode 100644 go/BUILD.bazel create mode 100644 misc/bazel/universal_binary.bzl diff --git a/MODULE.bazel b/MODULE.bazel index 2dc9dd0a7bb5..7a85ab51a96c 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -13,7 +13,8 @@ local_path_override( # see https://registry.bazel.build/ for a list of available packages -bazel_dep(name = "platforms", version = "0.0.8") +bazel_dep(name = "apple_support", version = "1.15.1") +bazel_dep(name = "platforms", version = "0.0.9") bazel_dep(name = "rules_go", version = "0.47.0") bazel_dep(name = "rules_pkg", version = "0.10.1") bazel_dep(name = "rules_nodejs", version = "6.0.3") diff --git a/go/BUILD.bazel b/go/BUILD.bazel new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/go/extractor/BUILD.bazel b/go/extractor/BUILD.bazel index ea99340e7d75..040b42273140 100644 --- a/go/extractor/BUILD.bazel +++ b/go/extractor/BUILD.bazel @@ -1,6 +1,7 @@ load("@rules_go//go:def.bzl", "go_library") # gazelle:prefix github.com/github/codeql-go/extractor +# gazelle:map_kind go_binary codeql_go_binary //go:rules.bzl go_library( name = "extractor", diff --git a/go/extractor/cli/go-autobuilder/BUILD.bazel b/go/extractor/cli/go-autobuilder/BUILD.bazel index b53227b9f1bb..bf1235b33aa0 100644 --- a/go/extractor/cli/go-autobuilder/BUILD.bazel +++ b/go/extractor/cli/go-autobuilder/BUILD.bazel @@ -1,4 +1,5 @@ -load("@rules_go//go:def.bzl", "go_binary", "go_library") +load("@rules_go//go:def.bzl", "go_library") +load("//go:rules.bzl", "codeql_go_binary") go_library( name = "go-autobuilder_lib", @@ -15,7 +16,7 @@ go_library( ], ) -go_binary( +codeql_go_binary( name = "go-autobuilder", embed = [":go-autobuilder_lib"], visibility = ["//visibility:public"], diff --git a/go/extractor/cli/go-bootstrap/BUILD.bazel b/go/extractor/cli/go-bootstrap/BUILD.bazel index 15255227f9a4..7bdd6d6e70f9 100644 --- a/go/extractor/cli/go-bootstrap/BUILD.bazel +++ b/go/extractor/cli/go-bootstrap/BUILD.bazel @@ -1,4 +1,5 @@ -load("@rules_go//go:def.bzl", "go_binary", "go_library") +load("@rules_go//go:def.bzl", "go_library") +load("//go:rules.bzl", "codeql_go_binary") go_library( name = "go-bootstrap_lib", @@ -7,7 +8,7 @@ go_library( visibility = ["//visibility:private"], ) -go_binary( +codeql_go_binary( name = "go-bootstrap", embed = [":go-bootstrap_lib"], visibility = ["//visibility:public"], diff --git a/go/extractor/cli/go-build-runner/BUILD.bazel b/go/extractor/cli/go-build-runner/BUILD.bazel index fc407c3e1724..15557d751cf4 100644 --- a/go/extractor/cli/go-build-runner/BUILD.bazel +++ b/go/extractor/cli/go-build-runner/BUILD.bazel @@ -1,4 +1,5 @@ -load("@rules_go//go:def.bzl", "go_binary", "go_library") +load("@rules_go//go:def.bzl", "go_library") +load("//go:rules.bzl", "codeql_go_binary") go_library( name = "go-build-runner_lib", @@ -11,7 +12,7 @@ go_library( ], ) -go_binary( +codeql_go_binary( name = "go-build-runner", embed = [":go-build-runner_lib"], visibility = ["//visibility:public"], diff --git a/go/extractor/cli/go-extractor/BUILD.bazel b/go/extractor/cli/go-extractor/BUILD.bazel index 9419c6f8ba93..be426331868c 100644 --- a/go/extractor/cli/go-extractor/BUILD.bazel +++ b/go/extractor/cli/go-extractor/BUILD.bazel @@ -1,4 +1,5 @@ -load("@rules_go//go:def.bzl", "go_binary", "go_library") +load("@rules_go//go:def.bzl", "go_library") +load("//go:rules.bzl", "codeql_go_binary") go_library( name = "go-extractor_lib", @@ -11,7 +12,7 @@ go_library( ], ) -go_binary( +codeql_go_binary( name = "go-extractor", embed = [":go-extractor_lib"], visibility = ["//visibility:public"], diff --git a/go/extractor/cli/go-gen-dbscheme/BUILD.bazel b/go/extractor/cli/go-gen-dbscheme/BUILD.bazel index 1fbd75998c23..06c0d0f61f18 100644 --- a/go/extractor/cli/go-gen-dbscheme/BUILD.bazel +++ b/go/extractor/cli/go-gen-dbscheme/BUILD.bazel @@ -1,4 +1,5 @@ -load("@rules_go//go:def.bzl", "go_binary", "go_library") +load("@rules_go//go:def.bzl", "go_library") +load("//go:rules.bzl", "codeql_go_binary") go_library( name = "go-gen-dbscheme_lib", @@ -8,7 +9,7 @@ go_library( deps = ["//go/extractor/dbscheme"], ) -go_binary( +codeql_go_binary( name = "go-gen-dbscheme", embed = [":go-gen-dbscheme_lib"], visibility = ["//visibility:public"], diff --git a/go/extractor/cli/go-tokenizer/BUILD.bazel b/go/extractor/cli/go-tokenizer/BUILD.bazel index f55baecc69f3..3fc5b464c7c5 100644 --- a/go/extractor/cli/go-tokenizer/BUILD.bazel +++ b/go/extractor/cli/go-tokenizer/BUILD.bazel @@ -1,4 +1,5 @@ -load("@rules_go//go:def.bzl", "go_binary", "go_library") +load("@rules_go//go:def.bzl", "go_library") +load("//go:rules.bzl", "codeql_go_binary") go_library( name = "go-tokenizer_lib", @@ -7,7 +8,7 @@ go_library( visibility = ["//visibility:private"], ) -go_binary( +codeql_go_binary( name = "go-tokenizer", embed = [":go-tokenizer_lib"], visibility = ["//visibility:public"], diff --git a/go/rules.bzl b/go/rules.bzl index e69de29bb2d1..4ef798001d2a 100644 --- a/go/rules.bzl +++ b/go/rules.bzl @@ -0,0 +1,5 @@ +load("@rules_go//go:def.bzl", "go_binary") +load("//misc/bazel:universal_binary.bzl", "wrap_as_universal_binary") + +def codeql_go_binary(**kwargs): + wrap_as_universal_binary(go_binary, **kwargs) diff --git a/misc/bazel/universal_binary.bzl b/misc/bazel/universal_binary.bzl new file mode 100644 index 000000000000..85881356d0eb --- /dev/null +++ b/misc/bazel/universal_binary.bzl @@ -0,0 +1,24 @@ +load("@apple_support//rules:universal_binary.bzl", _universal_binary = "universal_binary") + +def wrap_as_universal_binary(rule, *, name, visibility = None, **kwargs): + internal_name = "internal/%s" % name + universal_name = "universal/%s" % name + rule( + name = internal_name, + visibility = ["//visibility:private"], + **kwargs + ) + _universal_binary( + name = universal_name, + target_compatible_with = ["@platforms//os:macos"], + binary = internal_name, + visibility = ["//visibility:private"], + ) + native.alias( + name = name, + actual = select({ + "@platforms//os:macos": universal_name, + "//conditions:default": internal_name, + }), + visibility = visibility, + ) From 15c1fd942558d2a5d5023dc5f17dfdd8dedd9757 Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Thu, 25 Apr 2024 10:39:53 +0200 Subject: [PATCH 036/238] C#: Improve log messages --- .../DependencyManager.cs | 1 + .../DotNet.cs | 4 +-- .../DotNetCliInvoker.cs | 5 ++-- .../FileProvider.cs | 29 ++++++++++++------- .../NugetExeWrapper.cs | 24 ++++++--------- .../NugetPackageRestorer.cs | 4 +-- .../Extractor.cs | 9 ++++-- 7 files changed, 42 insertions(+), 34 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs index d0e68defac16..d5450affd930 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs @@ -191,6 +191,7 @@ void exitCallback(int ret, string msg, bool silent) private HashSet AddFrameworkDlls(HashSet dllLocations) { + logger.LogInfo("Adding .NET Framework DLLs"); var frameworkLocations = new HashSet(); var frameworkReferences = Environment.GetEnvironmentVariable(EnvironmentVariableNames.DotnetFrameworkReferences); diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs index 95e8fe0675f4..f1f1862049ac 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs @@ -91,9 +91,9 @@ public bool AddPackage(string folder, string package) return dotnetCliInvoker.RunCommand(args); } - public IList GetListedRuntimes() => GetResultList("--list-runtimes", null, false); + public IList GetListedRuntimes() => GetResultList("--list-runtimes", null, true); - public IList GetListedSdks() => GetResultList("--list-sdks", null, false); + public IList GetListedSdks() => GetResultList("--list-sdks", null, true); private IList GetResultList(string args, string? workingDirectory = null, bool silent = true) { diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs index 1802521e28d3..126780212270 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs @@ -19,6 +19,7 @@ public DotNetCliInvoker(ILogger logger, string exec) { this.logger = logger; this.Exec = exec; + logger.LogInfo($"Using .NET CLI executable: '{Exec}'"); } private ProcessStartInfo MakeDotnetStartInfo(string args, string? workingDirectory) @@ -43,7 +44,7 @@ private ProcessStartInfo MakeDotnetStartInfo(string args, string? workingDirecto private bool RunCommandAux(string args, string? workingDirectory, out IList output, bool silent) { var dirLog = string.IsNullOrWhiteSpace(workingDirectory) ? "" : $" in {workingDirectory}"; - logger.LogInfo($"Running {Exec} {args}{dirLog}"); + logger.LogInfo($"Running '{Exec} {args}'{dirLog}"); var pi = MakeDotnetStartInfo(args, workingDirectory); var threadId = Environment.CurrentManagedThreadId; void onOut(string s) => logger.Log(silent ? Severity.Debug : Severity.Info, s, threadId); @@ -51,7 +52,7 @@ private bool RunCommandAux(string args, string? workingDirectory, out IList dlls; private readonly Lazy nugetConfigs; private readonly Lazy globalJsons; + private readonly Lazy packagesConfigs; private readonly Lazy razorViews; private readonly Lazy resources; private readonly Lazy rootNugetConfig; @@ -32,31 +33,38 @@ public FileProvider(DirectoryInfo sourceDir, ILogger logger) all = GetAllFiles(); allNonBinary = new Lazy(() => all.Where(f => !binaryFileExtensions.Contains(f.Extension.ToLowerInvariant())).ToArray()); - smallNonBinary = new Lazy(() => - { - var ret = SelectSmallFiles(allNonBinary.Value).SelectFileNames().ToArray(); - logger.LogInfo($"Found {ret.Length} small non-binary files in {SourceDir}."); - return ret; - }); + smallNonBinary = new Lazy(() => ReturnAndLogFiles("small non-binary", SelectSmallFiles(allNonBinary.Value).SelectFileNames().ToArray())); sources = new Lazy(() => SelectTextFileNamesByExtension("source", ".cs")); projects = new Lazy(() => SelectTextFileNamesByExtension("project", ".csproj")); solutions = new Lazy(() => SelectTextFileNamesByExtension("solution", ".sln")); dlls = new Lazy(() => SelectBinaryFileNamesByExtension("DLL", ".dll")); - nugetConfigs = new Lazy(() => allNonBinary.Value.SelectFileNamesByName("nuget.config").ToArray()); - globalJsons = new Lazy(() => allNonBinary.Value.SelectFileNamesByName("global.json").ToArray()); + nugetConfigs = new Lazy(() => SelectTextFileNamesByName("nuget.config")); + globalJsons = new Lazy(() => SelectTextFileNamesByName("global.json")); + packagesConfigs = new Lazy(() => SelectTextFileNamesByName("packages.config")); razorViews = new Lazy(() => SelectTextFileNamesByExtension("razor view", ".cshtml", ".razor")); resources = new Lazy(() => SelectTextFileNamesByExtension("resource", ".resx")); rootNugetConfig = new Lazy(() => all.SelectRootFiles(SourceDir).SelectFileNamesByName("nuget.config").FirstOrDefault()); } - private string[] SelectTextFileNamesByExtension(string filetype, params string[] extensions) + private string[] ReturnAndLogFiles(string filetype, IEnumerable files) { - var ret = allNonBinary.Value.SelectFileNamesByExtension(extensions).ToArray(); + var ret = files.ToArray(); logger.LogInfo($"Found {ret.Length} {filetype} files in {SourceDir}."); return ret; } + private string[] SelectTextFileNamesByExtension(string filetype, params string[] extensions) + => ReturnAndLogFiles(filetype, allNonBinary.Value.SelectFileNamesByExtension(extensions)); + + private string[] SelectTextFileNamesByName(string name) + { + var ret = allNonBinary.Value.SelectFileNamesByName(name).ToArray(); + var ending = ret.Length == 0 ? "." : $": {string.Join(", ", ret.OrderBy(s => s))}."; + logger.LogInfo($"Found {ret.Length} {name} files in {SourceDir}{ending}"); + return ret; + } + private string[] SelectBinaryFileNamesByExtension(string filetype, params string[] extensions) { var ret = all.SelectFileNamesByExtension(extensions).ToArray(); @@ -117,6 +125,7 @@ private FileInfo[] GetAllFiles() public ICollection NugetConfigs => nugetConfigs.Value; public string? RootNugetConfig => rootNugetConfig.Value; public IEnumerable GlobalJsons => globalJsons.Value; + public ICollection PackagesConfigs => packagesConfigs.Value; public ICollection RazorViews => razorViews.Value; public ICollection Resources => resources.Value; } diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetExeWrapper.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetExeWrapper.cs index 01b4eb6b5f4b..8537e4b5e0ee 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetExeWrapper.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetExeWrapper.cs @@ -20,9 +20,9 @@ internal class NugetExeWrapper : IDisposable /// /// The list of package files. /// - private readonly FileInfo[] packageFiles; + private readonly ICollection packageFiles; - public int PackageCount => packageFiles.Length; + public int PackageCount => packageFiles.Count; private readonly string? backupNugetConfig; private readonly string? nugetConfigPath; @@ -37,23 +37,21 @@ internal class NugetExeWrapper : IDisposable /// /// Create the package manager for a specified source tree. /// - public NugetExeWrapper(string sourceDir, TemporaryDirectory packageDirectory, Util.Logging.ILogger logger) + public NugetExeWrapper(FileProvider fileProvider, TemporaryDirectory packageDirectory, Util.Logging.ILogger logger) { this.packageDirectory = packageDirectory; this.logger = logger; - packageFiles = new DirectoryInfo(sourceDir) - .EnumerateFiles("packages.config", SearchOption.AllDirectories) - .ToArray(); + packageFiles = fileProvider.PackagesConfigs; - if (packageFiles.Length > 0) + if (packageFiles.Count > 0) { - logger.LogInfo($"Found {packageFiles.Length} packages.config files, trying to use nuget.exe for package restore"); - nugetExe = ResolveNugetExe(sourceDir); + logger.LogInfo($"Found packages.config files, trying to use nuget.exe for package restore"); + nugetExe = ResolveNugetExe(fileProvider.SourceDir.FullName); if (HasNoPackageSource()) { // We only modify or add a top level nuget.config file - nugetConfigPath = Path.Combine(sourceDir, "nuget.config"); + nugetConfigPath = Path.Combine(fileProvider.SourceDir.FullName, "nuget.config"); try { if (File.Exists(nugetConfigPath)) @@ -86,10 +84,6 @@ public NugetExeWrapper(string sourceDir, TemporaryDirectory packageDirectory, Ut } } } - else - { - logger.LogInfo("Found no packages.config file"); - } } /// @@ -195,7 +189,7 @@ private bool TryRestoreNugetPackage(string package) /// public int InstallPackages() { - return packageFiles.Count(package => TryRestoreNugetPackage(package.FullName)); + return packageFiles.Count(package => TryRestoreNugetPackage(package)); } private bool HasNoPackageSource() diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs index 735e4a676c68..baf23a0d0cc7 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs @@ -105,7 +105,7 @@ public HashSet Restore() : [unresponsiveMissingPackageLocation]; } - using (var nuget = new NugetExeWrapper(fileProvider.SourceDir.FullName, legacyPackageDirectory, logger)) + using (var nuget = new NugetExeWrapper(fileProvider, legacyPackageDirectory, logger)) { var count = nuget.InstallPackages(); @@ -178,7 +178,7 @@ private List GetReachableFallbackNugetFeeds() logger.LogInfo($"No fallback Nuget feeds specified. Using default feed: {PublicNugetOrgFeed}"); } - logger.LogInfo($"Checking fallback Nuget feed reachability on feeds: {string.Join(", ", fallbackFeeds.OrderBy(f => f))}"); + logger.LogInfo($"Checking fallback Nuget feed reachability on feeds: {string.Join(", ", fallbackFeeds.OrderBy(f => f))}"); var (initialTimeout, tryCount) = GetFeedRequestSettings(isFallback: true); var reachableFallbackFeeds = fallbackFeeds.Where(feed => IsFeedReachable(feed, initialTimeout, tryCount, allowExceptions: false)).ToList(); if (reachableFallbackFeeds.Count == 0) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Extractor.cs b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Extractor.cs index fac8523989ec..63d4ff0e83a8 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Extractor.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Extractor.cs @@ -121,17 +121,20 @@ public void Started(int item, int total, string source) public void MissingType(string type) { - logger.Log(Severity.Debug, "Missing type {0}", type); + logger.LogDebug($"Missing type {type}"); } public void MissingNamespace(string @namespace) { - logger.Log(Severity.Info, "Missing namespace {0}", @namespace); + logger.LogInfo($"Missing namespace {@namespace}"); } public void MissingSummary(int missingTypes, int missingNamespaces) { - logger.Log(Severity.Info, "Failed to resolve {0} types in {1} namespaces", missingTypes, missingNamespaces); + if (missingTypes > 0 || missingNamespaces > 0) + { + logger.LogInfo($"Failed to resolve {missingTypes} types in {missingNamespaces} namespaces"); + } } } From 05819a52ef15a456af6fdc11daebe23a1badd84f Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Thu, 25 Apr 2024 13:20:21 +0200 Subject: [PATCH 037/238] C++: Print destructors for children of statements that are again statements --- cpp/ql/lib/semmle/code/cpp/PrintAST.qll | 26 +++ .../library-tests/ir/ir/PrintAST.expected | 108 +++++++++++++ .../library-tests/ir/ir/aliased_ir.expected | 153 ++++++++++++++++++ cpp/ql/test/library-tests/ir/ir/ir.cpp | 17 ++ .../test/library-tests/ir/ir/raw_ir.expected | 128 +++++++++++++++ 5 files changed, 432 insertions(+) diff --git a/cpp/ql/lib/semmle/code/cpp/PrintAST.qll b/cpp/ql/lib/semmle/code/cpp/PrintAST.qll index beabef322d20..b515a346bf3b 100644 --- a/cpp/ql/lib/semmle/code/cpp/PrintAST.qll +++ b/cpp/ql/lib/semmle/code/cpp/PrintAST.qll @@ -463,6 +463,25 @@ class StmtNode extends AstNode { } } +/** + * A node representing a child of a `Stmt` that is itself a `Stmt`. + */ +class ChildStmtNode extends StmtNode { + Stmt childStmt; + + ChildStmtNode() { exists(Stmt parent | parent.getAChild() = childStmt and childStmt = ast) } + + override BaseAstNode getChildInternal(int childIndex) { + result = super.getChildInternal(childIndex) + or + exists(int destructorIndex | + result.getAst() = childStmt.getImplicitDestructorCall(destructorIndex) and + childIndex = + destructorIndex + max(int index | exists(childStmt.getChild(index)) or index = 0) + 1 + ) + } +} + /** * A node representing a `DeclStmt`. */ @@ -674,6 +693,13 @@ class FunctionNode extends FunctionOrGlobalOrNamespaceVariableNode { private string getChildAccessorWithoutConversions(Locatable parent, Element child) { shouldPrintDeclaration(getAnEnclosingDeclaration(parent)) and ( + exists(Stmt s, int i | s.getChild(i) = parent | + exists(int n | + s.getChild(i).(Stmt).getImplicitDestructorCall(n) = child and + result = "getImplicitDestructorCall(" + n + ")" + ) + ) + or exists(Stmt s | s = parent | namedStmtChildPredicates(s, child, result) or diff --git a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected index 1f6a29b57ed6..e0d2da046b2e 100644 --- a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected +++ b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected @@ -22334,6 +22334,114 @@ ir.cpp: # 2480| Type = [Struct] B # 2480| ValueCategory = xvalue # 2481| getStmt(1): [ReturnStmt] return ... +# 2484| [TopLevelFunction] void destructor_without_block(bool) +# 2484| : +# 2484| getParameter(0): [Parameter] b +# 2484| Type = [BoolType] bool +# 2485| getEntryPoint(): [BlockStmt] { ... } +# 2486| getStmt(0): [IfStmt] if (...) ... +# 2486| getCondition(): [VariableAccess] b +# 2486| Type = [BoolType] bool +# 2486| ValueCategory = prvalue(load) +# 2487| getThen(): [DeclStmt] declaration +# 2487| getDeclarationEntry(0): [VariableDeclarationEntry] definition of c +# 2487| Type = [Class] ClassWithDestructor +# 2487| getVariable().getInitializer(): [Initializer] initializer for c +# 2487| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2487| Type = [VoidType] void +# 2487| ValueCategory = prvalue +#-----| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +#-----| Type = [VoidType] void +#-----| ValueCategory = prvalue +#-----| getQualifier(): [VariableAccess] c +#-----| Type = [Class] ClassWithDestructor +#-----| ValueCategory = lvalue +# 2489| getStmt(1): [IfStmt] if (...) ... +# 2489| getCondition(): [VariableAccess] b +# 2489| Type = [BoolType] bool +# 2489| ValueCategory = prvalue(load) +# 2490| getThen(): [DeclStmt] declaration +# 2490| getDeclarationEntry(0): [VariableDeclarationEntry] definition of d +# 2490| Type = [Class] ClassWithDestructor +# 2490| getVariable().getInitializer(): [Initializer] initializer for d +# 2490| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2490| Type = [VoidType] void +# 2490| ValueCategory = prvalue +#-----| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +#-----| Type = [VoidType] void +#-----| ValueCategory = prvalue +#-----| getQualifier(): [VariableAccess] d +#-----| Type = [Class] ClassWithDestructor +#-----| ValueCategory = lvalue +# 2492| getElse(): [DeclStmt] declaration +# 2492| getDeclarationEntry(0): [VariableDeclarationEntry] definition of e +# 2492| Type = [Class] ClassWithDestructor +# 2492| getVariable().getInitializer(): [Initializer] initializer for e +# 2492| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2492| Type = [VoidType] void +# 2492| ValueCategory = prvalue +#-----| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +#-----| Type = [VoidType] void +#-----| ValueCategory = prvalue +#-----| getQualifier(): [VariableAccess] e +#-----| Type = [Class] ClassWithDestructor +#-----| ValueCategory = lvalue +# 2494| getStmt(2): [WhileStmt] while (...) ... +# 2494| getCondition(): [VariableAccess] b +# 2494| Type = [BoolType] bool +# 2494| ValueCategory = prvalue(load) +# 2495| getStmt(): [DeclStmt] declaration +# 2495| getDeclarationEntry(0): [VariableDeclarationEntry] definition of f +# 2495| Type = [Class] ClassWithDestructor +# 2495| getVariable().getInitializer(): [Initializer] initializer for f +# 2495| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2495| Type = [VoidType] void +# 2495| ValueCategory = prvalue +#-----| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +#-----| Type = [VoidType] void +#-----| ValueCategory = prvalue +#-----| getQualifier(): [VariableAccess] f +#-----| Type = [Class] ClassWithDestructor +#-----| ValueCategory = lvalue +# 2497| getStmt(3): [ForStmt] for(...;...;...) ... +# 2497| getInitialization(): [DeclStmt] declaration +# 2497| getDeclarationEntry(0): [VariableDeclarationEntry] definition of i +# 2497| Type = [IntType] int +# 2497| getVariable().getInitializer(): [Initializer] initializer for i +# 2497| getExpr(): [Literal] 0 +# 2497| Type = [IntType] int +# 2497| Value = [Literal] 0 +# 2497| ValueCategory = prvalue +# 2497| getCondition(): [LTExpr] ... < ... +# 2497| Type = [BoolType] bool +# 2497| ValueCategory = prvalue +# 2497| getLesserOperand(): [VariableAccess] i +# 2497| Type = [IntType] int +# 2497| ValueCategory = prvalue(load) +# 2497| getGreaterOperand(): [Literal] 42 +# 2497| Type = [IntType] int +# 2497| Value = [Literal] 42 +# 2497| ValueCategory = prvalue +# 2497| getUpdate(): [PrefixIncrExpr] ++ ... +# 2497| Type = [IntType] int +# 2497| ValueCategory = lvalue +# 2497| getOperand(): [VariableAccess] i +# 2497| Type = [IntType] int +# 2497| ValueCategory = lvalue +# 2498| getStmt(): [DeclStmt] declaration +# 2498| getDeclarationEntry(0): [VariableDeclarationEntry] definition of g +# 2498| Type = [Class] ClassWithDestructor +# 2498| getVariable().getInitializer(): [Initializer] initializer for g +# 2498| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2498| Type = [VoidType] void +# 2498| ValueCategory = prvalue +#-----| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +#-----| Type = [VoidType] void +#-----| ValueCategory = prvalue +#-----| getQualifier(): [VariableAccess] g +#-----| Type = [Class] ClassWithDestructor +#-----| ValueCategory = lvalue +# 2499| getStmt(4): [ReturnStmt] return ... perf-regression.cpp: # 4| [CopyAssignmentOperator] Big& Big::operator=(Big const&) # 4| : diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected index 51e12b7a6e5d..3d3a56e790e9 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected @@ -17805,6 +17805,159 @@ ir.cpp: # 2478| v2478_6(void) = AliasedUse : ~m2480_20 # 2478| v2478_7(void) = ExitFunction : +# 2484| void destructor_without_block(bool) +# 2484| Block 0 +# 2484| v2484_1(void) = EnterFunction : +# 2484| m2484_2(unknown) = AliasedDefinition : +# 2484| m2484_3(unknown) = InitializeNonLocal : +# 2484| m2484_4(unknown) = Chi : total:m2484_2, partial:m2484_3 +# 2484| r2484_5(glval) = VariableAddress[b] : +# 2484| m2484_6(bool) = InitializeParameter[b] : &:r2484_5 +# 2486| r2486_1(glval) = VariableAddress[b] : +# 2486| r2486_2(bool) = Load[b] : &:r2486_1, m2484_6 +# 2486| v2486_3(void) = ConditionalBranch : r2486_2 +#-----| False -> Block 2 +#-----| True -> Block 1 + +# 2487| Block 1 +# 2487| r2487_1(glval) = VariableAddress[c] : +# 2487| m2487_2(ClassWithDestructor) = Uninitialized[c] : &:r2487_1 +# 2487| r2487_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2487| v2487_4(void) = Call[ClassWithDestructor] : func:r2487_3, this:r2487_1 +# 2487| m2487_5(unknown) = ^CallSideEffect : ~m2484_4 +# 2487| m2487_6(unknown) = Chi : total:m2484_4, partial:m2487_5 +# 2487| m2487_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2487_1 +# 2487| m2487_8(ClassWithDestructor) = Chi : total:m2487_2, partial:m2487_7 +#-----| r0_1(glval) = VariableAddress[c] : +#-----| r0_2(glval) = FunctionAddress[~ClassWithDestructor] : +#-----| v0_3(void) = Call[~ClassWithDestructor] : func:r0_2, this:r0_1 +#-----| m0_4(unknown) = ^CallSideEffect : ~m2487_6 +#-----| m0_5(unknown) = Chi : total:m2487_6, partial:m0_4 +#-----| v0_6(void) = ^IndirectReadSideEffect[-1] : &:r0_1, m2487_8 +#-----| m0_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r0_1 +#-----| m0_8(ClassWithDestructor) = Chi : total:m2487_8, partial:m0_7 +#-----| Goto -> Block 2 + +# 2489| Block 2 +# 2489| m2489_1(unknown) = Phi : from 0:~m2484_4, from 1:~m0_5 +# 2489| r2489_2(glval) = VariableAddress[b] : +# 2489| r2489_3(bool) = Load[b] : &:r2489_2, m2484_6 +# 2489| v2489_4(void) = ConditionalBranch : r2489_3 +#-----| False -> Block 4 +#-----| True -> Block 3 + +# 2490| Block 3 +# 2490| r2490_1(glval) = VariableAddress[d] : +# 2490| m2490_2(ClassWithDestructor) = Uninitialized[d] : &:r2490_1 +# 2490| r2490_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2490| v2490_4(void) = Call[ClassWithDestructor] : func:r2490_3, this:r2490_1 +# 2490| m2490_5(unknown) = ^CallSideEffect : ~m2489_1 +# 2490| m2490_6(unknown) = Chi : total:m2489_1, partial:m2490_5 +# 2490| m2490_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2490_1 +# 2490| m2490_8(ClassWithDestructor) = Chi : total:m2490_2, partial:m2490_7 +#-----| r0_9(glval) = VariableAddress[d] : +#-----| r0_10(glval) = FunctionAddress[~ClassWithDestructor] : +#-----| v0_11(void) = Call[~ClassWithDestructor] : func:r0_10, this:r0_9 +#-----| m0_12(unknown) = ^CallSideEffect : ~m2490_6 +#-----| m0_13(unknown) = Chi : total:m2490_6, partial:m0_12 +#-----| v0_14(void) = ^IndirectReadSideEffect[-1] : &:r0_9, m2490_8 +#-----| m0_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r0_9 +#-----| m0_16(ClassWithDestructor) = Chi : total:m2490_8, partial:m0_15 +#-----| Goto -> Block 5 + +# 2492| Block 4 +# 2492| r2492_1(glval) = VariableAddress[e] : +# 2492| m2492_2(ClassWithDestructor) = Uninitialized[e] : &:r2492_1 +# 2492| r2492_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2492| v2492_4(void) = Call[ClassWithDestructor] : func:r2492_3, this:r2492_1 +# 2492| m2492_5(unknown) = ^CallSideEffect : ~m2489_1 +# 2492| m2492_6(unknown) = Chi : total:m2489_1, partial:m2492_5 +# 2492| m2492_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2492_1 +# 2492| m2492_8(ClassWithDestructor) = Chi : total:m2492_2, partial:m2492_7 +#-----| r0_17(glval) = VariableAddress[e] : +#-----| r0_18(glval) = FunctionAddress[~ClassWithDestructor] : +#-----| v0_19(void) = Call[~ClassWithDestructor] : func:r0_18, this:r0_17 +#-----| m0_20(unknown) = ^CallSideEffect : ~m2492_6 +#-----| m0_21(unknown) = Chi : total:m2492_6, partial:m0_20 +#-----| v0_22(void) = ^IndirectReadSideEffect[-1] : &:r0_17, m2492_8 +#-----| m0_23(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r0_17 +#-----| m0_24(ClassWithDestructor) = Chi : total:m2492_8, partial:m0_23 +#-----| Goto -> Block 5 + +# 2494| Block 5 +# 2494| m2494_1(unknown) = Phi : from 3:~m0_13, from 4:~m0_21, from 6:~m0_29 +# 2494| r2494_2(glval) = VariableAddress[b] : +# 2494| r2494_3(bool) = Load[b] : &:r2494_2, m2484_6 +# 2494| v2494_4(void) = ConditionalBranch : r2494_3 +#-----| False -> Block 7 +#-----| True -> Block 6 + +# 2495| Block 6 +# 2495| r2495_1(glval) = VariableAddress[f] : +# 2495| m2495_2(ClassWithDestructor) = Uninitialized[f] : &:r2495_1 +# 2495| r2495_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2495| v2495_4(void) = Call[ClassWithDestructor] : func:r2495_3, this:r2495_1 +# 2495| m2495_5(unknown) = ^CallSideEffect : ~m2494_1 +# 2495| m2495_6(unknown) = Chi : total:m2494_1, partial:m2495_5 +# 2495| m2495_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2495_1 +# 2495| m2495_8(ClassWithDestructor) = Chi : total:m2495_2, partial:m2495_7 +#-----| r0_25(glval) = VariableAddress[f] : +#-----| r0_26(glval) = FunctionAddress[~ClassWithDestructor] : +#-----| v0_27(void) = Call[~ClassWithDestructor] : func:r0_26, this:r0_25 +#-----| m0_28(unknown) = ^CallSideEffect : ~m2495_6 +#-----| m0_29(unknown) = Chi : total:m2495_6, partial:m0_28 +#-----| v0_30(void) = ^IndirectReadSideEffect[-1] : &:r0_25, m2495_8 +#-----| m0_31(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r0_25 +#-----| m0_32(ClassWithDestructor) = Chi : total:m2495_8, partial:m0_31 +#-----| Goto (back edge) -> Block 5 + +# 2497| Block 7 +# 2497| r2497_1(glval) = VariableAddress[i] : +# 2497| r2497_2(int) = Constant[0] : +# 2497| m2497_3(int) = Store[i] : &:r2497_1, r2497_2 +#-----| Goto -> Block 8 + +# 2497| Block 8 +# 2497| m2497_4(unknown) = Phi : from 7:~m2494_1, from 9:~m0_37 +# 2497| m2497_5(int) = Phi : from 7:m2497_3, from 9:m2497_15 +# 2497| r2497_6(glval) = VariableAddress[i] : +# 2497| r2497_7(int) = Load[i] : &:r2497_6, m2497_5 +# 2497| r2497_8(int) = Constant[42] : +# 2497| r2497_9(bool) = CompareLT : r2497_7, r2497_8 +# 2497| v2497_10(void) = ConditionalBranch : r2497_9 +#-----| False -> Block 10 +#-----| True -> Block 9 + +# 2498| Block 9 +# 2498| r2498_1(glval) = VariableAddress[g] : +# 2498| m2498_2(ClassWithDestructor) = Uninitialized[g] : &:r2498_1 +# 2498| r2498_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2498| v2498_4(void) = Call[ClassWithDestructor] : func:r2498_3, this:r2498_1 +# 2498| m2498_5(unknown) = ^CallSideEffect : ~m2497_4 +# 2498| m2498_6(unknown) = Chi : total:m2497_4, partial:m2498_5 +# 2498| m2498_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2498_1 +# 2498| m2498_8(ClassWithDestructor) = Chi : total:m2498_2, partial:m2498_7 +#-----| r0_33(glval) = VariableAddress[g] : +#-----| r0_34(glval) = FunctionAddress[~ClassWithDestructor] : +#-----| v0_35(void) = Call[~ClassWithDestructor] : func:r0_34, this:r0_33 +#-----| m0_36(unknown) = ^CallSideEffect : ~m2498_6 +#-----| m0_37(unknown) = Chi : total:m2498_6, partial:m0_36 +#-----| v0_38(void) = ^IndirectReadSideEffect[-1] : &:r0_33, m2498_8 +#-----| m0_39(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r0_33 +#-----| m0_40(ClassWithDestructor) = Chi : total:m2498_8, partial:m0_39 +# 2497| r2497_11(glval) = VariableAddress[i] : +# 2497| r2497_12(int) = Load[i] : &:r2497_11, m2497_5 +# 2497| r2497_13(int) = Constant[1] : +# 2497| r2497_14(int) = Add : r2497_12, r2497_13 +# 2497| m2497_15(int) = Store[i] : &:r2497_11, r2497_14 +#-----| Goto (back edge) -> Block 8 + +# 2499| Block 10 +# 2499| v2499_1(void) = NoOp : +# 2484| v2484_7(void) = ReturnVoid : +# 2484| v2484_8(void) = AliasedUse : ~m2497_4 +# 2484| v2484_9(void) = ExitFunction : + perf-regression.cpp: # 6| void Big::Big() # 6| Block 0 diff --git a/cpp/ql/test/library-tests/ir/ir/ir.cpp b/cpp/ql/test/library-tests/ir/ir/ir.cpp index 95b639aac6bf..c8840fd0b56e 100644 --- a/cpp/ql/test/library-tests/ir/ir/ir.cpp +++ b/cpp/ql/test/library-tests/ir/ir/ir.cpp @@ -2481,4 +2481,21 @@ namespace rvalue_conversion_with_destructor { } } +void destructor_without_block(bool b) +{ + if (b) + ClassWithDestructor c; + + if (b) + ClassWithDestructor d; + else + ClassWithDestructor e; + + while (b) + ClassWithDestructor f; + + for(int i = 0; i < 42; ++i) + ClassWithDestructor g; +} + // semmle-extractor-options: -std=c++20 --clang diff --git a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected index 7c0a525d0ca0..6ff42a28cb35 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -16244,6 +16244,134 @@ ir.cpp: # 2478| v2478_5(void) = AliasedUse : ~m? # 2478| v2478_6(void) = ExitFunction : +# 2484| void destructor_without_block(bool) +# 2484| Block 0 +# 2484| v2484_1(void) = EnterFunction : +# 2484| mu2484_2(unknown) = AliasedDefinition : +# 2484| mu2484_3(unknown) = InitializeNonLocal : +# 2484| r2484_4(glval) = VariableAddress[b] : +# 2484| mu2484_5(bool) = InitializeParameter[b] : &:r2484_4 +# 2486| r2486_1(glval) = VariableAddress[b] : +# 2486| r2486_2(bool) = Load[b] : &:r2486_1, ~m? +# 2486| v2486_3(void) = ConditionalBranch : r2486_2 +#-----| False -> Block 2 +#-----| True -> Block 1 + +# 2487| Block 1 +# 2487| r2487_1(glval) = VariableAddress[c] : +# 2487| mu2487_2(ClassWithDestructor) = Uninitialized[c] : &:r2487_1 +# 2487| r2487_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2487| v2487_4(void) = Call[ClassWithDestructor] : func:r2487_3, this:r2487_1 +# 2487| mu2487_5(unknown) = ^CallSideEffect : ~m? +# 2487| mu2487_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2487_1 +#-----| r0_1(glval) = VariableAddress[c] : +#-----| r0_2(glval) = FunctionAddress[~ClassWithDestructor] : +#-----| v0_3(void) = Call[~ClassWithDestructor] : func:r0_2, this:r0_1 +#-----| mu0_4(unknown) = ^CallSideEffect : ~m? +#-----| v0_5(void) = ^IndirectReadSideEffect[-1] : &:r0_1, ~m? +#-----| mu0_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r0_1 +#-----| Goto -> Block 2 + +# 2489| Block 2 +# 2489| r2489_1(glval) = VariableAddress[b] : +# 2489| r2489_2(bool) = Load[b] : &:r2489_1, ~m? +# 2489| v2489_3(void) = ConditionalBranch : r2489_2 +#-----| False -> Block 4 +#-----| True -> Block 3 + +# 2490| Block 3 +# 2490| r2490_1(glval) = VariableAddress[d] : +# 2490| mu2490_2(ClassWithDestructor) = Uninitialized[d] : &:r2490_1 +# 2490| r2490_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2490| v2490_4(void) = Call[ClassWithDestructor] : func:r2490_3, this:r2490_1 +# 2490| mu2490_5(unknown) = ^CallSideEffect : ~m? +# 2490| mu2490_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2490_1 +#-----| r0_7(glval) = VariableAddress[d] : +#-----| r0_8(glval) = FunctionAddress[~ClassWithDestructor] : +#-----| v0_9(void) = Call[~ClassWithDestructor] : func:r0_8, this:r0_7 +#-----| mu0_10(unknown) = ^CallSideEffect : ~m? +#-----| v0_11(void) = ^IndirectReadSideEffect[-1] : &:r0_7, ~m? +#-----| mu0_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r0_7 +#-----| Goto -> Block 5 + +# 2492| Block 4 +# 2492| r2492_1(glval) = VariableAddress[e] : +# 2492| mu2492_2(ClassWithDestructor) = Uninitialized[e] : &:r2492_1 +# 2492| r2492_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2492| v2492_4(void) = Call[ClassWithDestructor] : func:r2492_3, this:r2492_1 +# 2492| mu2492_5(unknown) = ^CallSideEffect : ~m? +# 2492| mu2492_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2492_1 +#-----| r0_13(glval) = VariableAddress[e] : +#-----| r0_14(glval) = FunctionAddress[~ClassWithDestructor] : +#-----| v0_15(void) = Call[~ClassWithDestructor] : func:r0_14, this:r0_13 +#-----| mu0_16(unknown) = ^CallSideEffect : ~m? +#-----| v0_17(void) = ^IndirectReadSideEffect[-1] : &:r0_13, ~m? +#-----| mu0_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r0_13 +#-----| Goto -> Block 5 + +# 2494| Block 5 +# 2494| r2494_1(glval) = VariableAddress[b] : +# 2494| r2494_2(bool) = Load[b] : &:r2494_1, ~m? +# 2494| v2494_3(void) = ConditionalBranch : r2494_2 +#-----| False -> Block 7 +#-----| True -> Block 6 + +# 2495| Block 6 +# 2495| r2495_1(glval) = VariableAddress[f] : +# 2495| mu2495_2(ClassWithDestructor) = Uninitialized[f] : &:r2495_1 +# 2495| r2495_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2495| v2495_4(void) = Call[ClassWithDestructor] : func:r2495_3, this:r2495_1 +# 2495| mu2495_5(unknown) = ^CallSideEffect : ~m? +# 2495| mu2495_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2495_1 +#-----| r0_19(glval) = VariableAddress[f] : +#-----| r0_20(glval) = FunctionAddress[~ClassWithDestructor] : +#-----| v0_21(void) = Call[~ClassWithDestructor] : func:r0_20, this:r0_19 +#-----| mu0_22(unknown) = ^CallSideEffect : ~m? +#-----| v0_23(void) = ^IndirectReadSideEffect[-1] : &:r0_19, ~m? +#-----| mu0_24(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r0_19 +#-----| Goto (back edge) -> Block 5 + +# 2497| Block 7 +# 2497| r2497_1(glval) = VariableAddress[i] : +# 2497| r2497_2(int) = Constant[0] : +# 2497| mu2497_3(int) = Store[i] : &:r2497_1, r2497_2 +#-----| Goto -> Block 8 + +# 2497| Block 8 +# 2497| r2497_4(glval) = VariableAddress[i] : +# 2497| r2497_5(int) = Load[i] : &:r2497_4, ~m? +# 2497| r2497_6(int) = Constant[42] : +# 2497| r2497_7(bool) = CompareLT : r2497_5, r2497_6 +# 2497| v2497_8(void) = ConditionalBranch : r2497_7 +#-----| False -> Block 10 +#-----| True -> Block 9 + +# 2498| Block 9 +# 2498| r2498_1(glval) = VariableAddress[g] : +# 2498| mu2498_2(ClassWithDestructor) = Uninitialized[g] : &:r2498_1 +# 2498| r2498_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2498| v2498_4(void) = Call[ClassWithDestructor] : func:r2498_3, this:r2498_1 +# 2498| mu2498_5(unknown) = ^CallSideEffect : ~m? +# 2498| mu2498_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2498_1 +#-----| r0_25(glval) = VariableAddress[g] : +#-----| r0_26(glval) = FunctionAddress[~ClassWithDestructor] : +#-----| v0_27(void) = Call[~ClassWithDestructor] : func:r0_26, this:r0_25 +#-----| mu0_28(unknown) = ^CallSideEffect : ~m? +#-----| v0_29(void) = ^IndirectReadSideEffect[-1] : &:r0_25, ~m? +#-----| mu0_30(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r0_25 +# 2497| r2497_9(glval) = VariableAddress[i] : +# 2497| r2497_10(int) = Load[i] : &:r2497_9, ~m? +# 2497| r2497_11(int) = Constant[1] : +# 2497| r2497_12(int) = Add : r2497_10, r2497_11 +# 2497| mu2497_13(int) = Store[i] : &:r2497_9, r2497_12 +#-----| Goto (back edge) -> Block 8 + +# 2499| Block 10 +# 2499| v2499_1(void) = NoOp : +# 2484| v2484_6(void) = ReturnVoid : +# 2484| v2484_7(void) = AliasedUse : ~m? +# 2484| v2484_8(void) = ExitFunction : + perf-regression.cpp: # 6| void Big::Big() # 6| Block 0 From d0c9e3f7ad64be3606267552e8bc9f49e721b4fe Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 25 Apr 2024 13:33:17 +0200 Subject: [PATCH 038/238] JS: Expose InternalModuleNaming --- .../ql/lib/semmle/javascript/endpoints/EndpointNaming.qll | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/endpoints/EndpointNaming.qll b/javascript/ql/lib/semmle/javascript/endpoints/EndpointNaming.qll index 9e514d4c9f41..8fcb83729c48 100644 --- a/javascript/ql/lib/semmle/javascript/endpoints/EndpointNaming.qll +++ b/javascript/ql/lib/semmle/javascript/endpoints/EndpointNaming.qll @@ -432,7 +432,7 @@ string renderName(string package, string name) { result = join("(" + package + " * These names are not necessarily part of a package's public API, and so we only used them * as a fallback when a publicly-accessible access path cannot be found. */ -private module InternalModuleNaming { +module InternalModuleNaming { /** Gets the path to `folder` relative to its enclosing non-private `package.json` file. */ private string getPackageRelativePathFromFolder(Folder folder) { exists(PackageJson json | @@ -446,7 +446,10 @@ private module InternalModuleNaming { getPackageRelativePathFromFolder(folder.getParentContainer()) + "/" + folder.getBaseName() } - private string getPackageRelativePath(Module mod) { + /** + * Gets the path to `mod` relative to its enclosing package, including the package name. + */ + string getPackageRelativePath(Module mod) { exists(PackageJson json, string relativePath | not json.isPrivate() and json.getExportedModule(relativePath) = mod and From dd9183c3457d60cc3bece3f9cbafac3c416ce040 Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Thu, 25 Apr 2024 14:38:26 +0200 Subject: [PATCH 039/238] Code quality improvements --- .../Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs index f1f1862049ac..642403271ff3 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs @@ -91,9 +91,9 @@ public bool AddPackage(string folder, string package) return dotnetCliInvoker.RunCommand(args); } - public IList GetListedRuntimes() => GetResultList("--list-runtimes", null, true); + public IList GetListedRuntimes() => GetResultList("--list-runtimes"); - public IList GetListedSdks() => GetResultList("--list-sdks", null, true); + public IList GetListedSdks() => GetResultList("--list-sdks"); private IList GetResultList(string args, string? workingDirectory = null, bool silent = true) { From 15a6308c7232c32df6e39c279180a8c27ef553e8 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Thu, 25 Apr 2024 14:04:00 +0100 Subject: [PATCH 040/238] Go: Refactor condition for `EmitInvalidToolchainVersion` into separate function --- go/extractor/project/project.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/go/extractor/project/project.go b/go/extractor/project/project.go index 4f6f6542f75f..1d915282b951 100644 --- a/go/extractor/project/project.go +++ b/go/extractor/project/project.go @@ -179,6 +179,13 @@ func findGoModFiles(root string) []string { // A regular expression for the Go toolchain version syntax. var toolchainVersionRe *regexp.Regexp = regexp.MustCompile(`(?m)^([0-9]+\.[0-9]+\.[0-9]+)$`) +// Returns true if the `go.mod` file specifies a Go language version, that version is `1.21` or greater, and +// there is no `toolchain` directive, and the Go language version is not a valid toolchain version. +func hasInvalidToolchainVersion(modFile *modfile.File) bool { + return modFile.Toolchain == nil && modFile.Go != nil && + !toolchainVersionRe.Match([]byte(modFile.Go.Version)) && semver.Compare("v"+modFile.Go.Version, "v1.21.0") >= 0 +} + // Given a list of `go.mod` file paths, try to parse them all. The resulting array of `GoModule` objects // will be the same length as the input array and the objects will contain at least the `go.mod` path. // If parsing the corresponding file is successful, then the parsed contents will also be available. @@ -209,8 +216,7 @@ func LoadGoModules(emitDiagnostics bool, goModFilePaths []string) []*GoModule { // there is no `toolchain` directive, check that it is a valid Go toolchain version. Otherwise, // `go` commands which try to download the right version of the Go toolchain will fail. We detect // this situation and emit a diagnostic. - if modFile.Toolchain == nil && modFile.Go != nil && - !toolchainVersionRe.Match([]byte(modFile.Go.Version)) && semver.Compare("v"+modFile.Go.Version, "v1.21.0") >= 0 { + if hasInvalidToolchainVersion(modFile) { diagnostics.EmitInvalidToolchainVersion(goModFilePath, modFile.Go.Version) } } From f33d7ee80d8ae835e0244666ef87e41884d1fcc5 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Thu, 25 Apr 2024 14:09:47 +0100 Subject: [PATCH 041/238] Go: Add unit tests for `hasInvalidToolchainVersion` --- go/extractor/project/project_test.go | 37 ++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/go/extractor/project/project_test.go b/go/extractor/project/project_test.go index f2de420773f9..b7485960b5fd 100644 --- a/go/extractor/project/project_test.go +++ b/go/extractor/project/project_test.go @@ -3,6 +3,8 @@ package project import ( "path/filepath" "testing" + + "golang.org/x/mod/modfile" ) func testStartsWithAnyOf(t *testing.T, path string, prefix string, expectation bool) { @@ -25,3 +27,38 @@ func TestStartsWithAnyOf(t *testing.T) { testStartsWithAnyOf(t, filepath.Join("foo", "bar"), "bar", false) testStartsWithAnyOf(t, filepath.Join("foo", "bar"), filepath.Join("foo", "baz"), false) } + +func testHasInvalidToolchainVersion(t *testing.T, contents string) bool { + modFile, err := modfile.Parse("test.go", []byte(contents), nil) + + if err != nil { + t.Errorf("Unable to parse %s: %s.\n", contents, err.Error()) + } + + return hasInvalidToolchainVersion(modFile) +} + +func TestHasInvalidToolchainVersion(t *testing.T) { + invalid := []string{ + "go 1.21\n", + "go 1.22\n", + } + + for _, v := range invalid { + if !testHasInvalidToolchainVersion(t, v) { + t.Errorf("Expected testHasInvalidToolchainVersion(\"%s\") to be true, but got false", v) + } + } + + valid := []string{ + "go 1.20\n", + "go 1.21.1\n", + "go 1.22\n\ntoolchain go1.22.0\n", + } + + for _, v := range valid { + if testHasInvalidToolchainVersion(t, v) { + t.Errorf("Expected testHasInvalidToolchainVersion(\"%s\") to be false, but got true", v) + } + } +} From b8cfff6d199a616785d5bcc97690046db91dd141 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Thu, 25 Apr 2024 14:10:26 +0100 Subject: [PATCH 042/238] Go: Use `Parse` instead of `ParseLax`, since we need `toolchain` directives --- go/extractor/project/project.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/extractor/project/project.go b/go/extractor/project/project.go index 1d915282b951..215d7c6bc4ff 100644 --- a/go/extractor/project/project.go +++ b/go/extractor/project/project.go @@ -203,7 +203,7 @@ func LoadGoModules(emitDiagnostics bool, goModFilePaths []string) []*GoModule { continue } - modFile, err := modfile.ParseLax(goModFilePath, modFileSrc, nil) + modFile, err := modfile.Parse(goModFilePath, modFileSrc, nil) if err != nil { log.Printf("Unable to parse %s: %s.\n", goModFilePath, err.Error()) From 6daf80cdd001fa3d409614fbd242d1b9cb37ddad Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Thu, 25 Apr 2024 15:34:44 +0200 Subject: [PATCH 043/238] C#: Add integration test with multiple project files that have disjoint dependencies. --- .../Assemblies.expected | 165 ++++++++++++++++++ .../Assemblies.ql | 17 ++ .../Program.cs | 6 + .../global.json | 5 + .../standalone1.csproj | 16 ++ .../standalone2.csproj | 16 ++ .../test.py | 3 + 7 files changed, 228 insertions(+) create mode 100644 csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/Assemblies.expected create mode 100644 csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/Assemblies.ql create mode 100644 csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/Program.cs create mode 100644 csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/global.json create mode 100644 csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/standalone1.csproj create mode 100644 csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/standalone2.csproj create mode 100644 csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/test.py diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/Assemblies.expected b/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/Assemblies.expected new file mode 100644 index 000000000000..8ad98c213790 --- /dev/null +++ b/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/Assemblies.expected @@ -0,0 +1,165 @@ +| [...]/avalara.avatax/23.11.0/lib/netstandard2.0/Avalara.AvaTax.RestClient.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/Microsoft.CSharp.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/Microsoft.VisualBasic.Core.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/Microsoft.VisualBasic.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/Microsoft.Win32.Primitives.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/Microsoft.Win32.Registry.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.AppContext.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Buffers.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Collections.Concurrent.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Collections.Immutable.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Collections.NonGeneric.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Collections.Specialized.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Collections.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.ComponentModel.Annotations.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.ComponentModel.DataAnnotations.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.ComponentModel.EventBasedAsync.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.ComponentModel.Primitives.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.ComponentModel.TypeConverter.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.ComponentModel.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Configuration.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Console.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Core.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Data.Common.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Data.DataSetExtensions.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Data.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Diagnostics.Contracts.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Diagnostics.Debug.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Diagnostics.DiagnosticSource.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Diagnostics.FileVersionInfo.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Diagnostics.Process.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Diagnostics.StackTrace.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Diagnostics.TextWriterTraceListener.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Diagnostics.Tools.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Diagnostics.TraceSource.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Diagnostics.Tracing.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Drawing.Primitives.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Drawing.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Dynamic.Runtime.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Formats.Asn1.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Formats.Tar.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Globalization.Calendars.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Globalization.Extensions.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Globalization.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.Compression.Brotli.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.Compression.FileSystem.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.Compression.ZipFile.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.Compression.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.FileSystem.AccessControl.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.FileSystem.DriveInfo.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.FileSystem.Primitives.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.FileSystem.Watcher.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.FileSystem.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.IsolatedStorage.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.MemoryMappedFiles.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.Pipes.AccessControl.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.Pipes.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.UnmanagedMemoryStream.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Linq.Expressions.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Linq.Parallel.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Linq.Queryable.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Linq.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Memory.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.Http.Json.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.Http.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.HttpListener.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.Mail.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.NameResolution.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.NetworkInformation.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.Ping.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.Primitives.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.Quic.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.Requests.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.Security.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.ServicePoint.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.Sockets.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.WebClient.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.WebHeaderCollection.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.WebProxy.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.WebSockets.Client.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.WebSockets.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Numerics.Vectors.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Numerics.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.ObjectModel.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Reflection.DispatchProxy.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Reflection.Emit.ILGeneration.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Reflection.Emit.Lightweight.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Reflection.Emit.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Reflection.Extensions.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Reflection.Metadata.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Reflection.Primitives.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Reflection.TypeExtensions.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Reflection.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Resources.Reader.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Resources.ResourceManager.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Resources.Writer.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.CompilerServices.Unsafe.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.CompilerServices.VisualC.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.Extensions.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.Handles.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.InteropServices.JavaScript.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.InteropServices.RuntimeInformation.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.InteropServices.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.Intrinsics.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.Loader.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.Numerics.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.Serialization.Formatters.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.Serialization.Json.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.Serialization.Primitives.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.Serialization.Xml.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.Serialization.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.AccessControl.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.Claims.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.Cryptography.Algorithms.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.Cryptography.Cng.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.Cryptography.Csp.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.Cryptography.Encoding.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.Cryptography.OpenSsl.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.Cryptography.Primitives.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.Cryptography.X509Certificates.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.Cryptography.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.Principal.Windows.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.Principal.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.SecureString.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.ServiceModel.Web.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.ServiceProcess.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Text.Encoding.CodePages.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Text.Encoding.Extensions.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Text.Encoding.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Text.Encodings.Web.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Text.Json.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Text.RegularExpressions.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Threading.Channels.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Threading.Overlapped.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Threading.Tasks.Dataflow.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Threading.Tasks.Extensions.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Threading.Tasks.Parallel.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Threading.Tasks.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Threading.Thread.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Threading.ThreadPool.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Threading.Timer.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Threading.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Transactions.Local.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Transactions.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.ValueTuple.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Web.HttpUtility.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Web.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Windows.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Xml.Linq.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Xml.ReaderWriter.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Xml.Serialization.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Xml.XDocument.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Xml.XPath.XDocument.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Xml.XPath.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Xml.XmlDocument.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Xml.XmlSerializer.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Xml.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/WindowsBase.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/mscorlib.dll | +| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/netstandard.dll | +| [...]/newtonsoft.json/12.0.1/lib/netstandard2.0/Newtonsoft.Json.dll | diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/Assemblies.ql b/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/Assemblies.ql new file mode 100644 index 000000000000..b78ceee2d8f8 --- /dev/null +++ b/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/Assemblies.ql @@ -0,0 +1,17 @@ +import csharp + +private string getPath(Assembly a) { + not a.getCompilation().getOutputAssembly() = a and + exists(string s | s = a.getFile().getAbsolutePath() | + result = + "[...]" + + s.substring(s.indexOf("test-db/working/") + "test-db/working/".length() + 16 + + "/packages".length(), s.length()) + or + result = s and + not exists(s.indexOf("test-db/working/")) + ) +} + +from Assembly a +select getPath(a) diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/Program.cs b/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/Program.cs new file mode 100644 index 000000000000..39a9e95bb6e3 --- /dev/null +++ b/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/Program.cs @@ -0,0 +1,6 @@ +class Program +{ + static void Main(string[] args) + { + } +} \ No newline at end of file diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/global.json b/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/global.json new file mode 100644 index 000000000000..d54915e8d4d0 --- /dev/null +++ b/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/global.json @@ -0,0 +1,5 @@ +{ + "sdk": { + "version": "8.0.101" + } +} diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/standalone1.csproj b/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/standalone1.csproj new file mode 100644 index 000000000000..67d37d1a7608 --- /dev/null +++ b/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/standalone1.csproj @@ -0,0 +1,16 @@ + + + + Exe + net8.0 + + + + + + + + + + + diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/standalone2.csproj b/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/standalone2.csproj new file mode 100644 index 000000000000..05fb5c1aa487 --- /dev/null +++ b/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/standalone2.csproj @@ -0,0 +1,16 @@ + + + + Exe + net8.0 + + + + + + + + + + + diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/test.py b/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/test.py new file mode 100644 index 000000000000..a17966e148a9 --- /dev/null +++ b/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/test.py @@ -0,0 +1,3 @@ +from create_database_utils import * + +run_codeql_database_create([], lang="csharp", extra_args=["--build-mode=none"]) From 0124b0749f9dd3a58e8dada7611ce04a7ff11c72 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Thu, 18 Apr 2024 09:29:49 +0200 Subject: [PATCH 044/238] C#: Do not run dotnet restore in parallel for projects in the same folder. --- .../NugetPackageRestorer.cs | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs index 735e4a676c68..d76ad1a676ae 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs @@ -240,21 +240,25 @@ private void RestoreProjects(IEnumerable projects, out IEnumerable(); var sync = new object(); - Parallel.ForEach(projects, new ParallelOptions { MaxDegreeOfParallelism = DependencyManager.Threads }, project => + var projectGroups = projects.GroupBy(Path.GetDirectoryName); + Parallel.ForEach(projectGroups, new ParallelOptions { MaxDegreeOfParallelism = DependencyManager.Threads }, projectGroup => { - logger.LogInfo($"Restoring project {project}..."); - var res = dotnet.Restore(new(project, PackageDirectory.DirInfo.FullName, ForceDotnetRefAssemblyFetching: true)); - lock (sync) + foreach (var project in projectGroup) { - if (res.Success) - { - successCount++; - } - if (res.HasNugetPackageSourceError) + logger.LogInfo($"Restoring project {project}..."); + var res = dotnet.Restore(new(project, PackageDirectory.DirInfo.FullName, ForceDotnetRefAssemblyFetching: true)); + lock (sync) { - nugetSourceFailures++; + if (res.Success) + { + successCount++; + } + if (res.HasNugetPackageSourceError) + { + nugetSourceFailures++; + } + assetFiles.AddRange(res.AssetsFilePaths); } - assetFiles.AddRange(res.AssetsFilePaths); } }); assets = assetFiles; From 131d0b911fcddaf92911c2eaeed7a7391286498f Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Thu, 25 Apr 2024 14:12:56 +0200 Subject: [PATCH 045/238] C#: Inline dependency collection from asset files per group. --- .../Assets.cs | 46 ++++--- .../DependencyContainer.cs | 18 ++- .../DependencyManager.cs | 2 - .../NugetPackageRestorer.cs | 32 +++-- .../Semmle.Extraction.Tests/Assets.cs | 118 ++++++++---------- 5 files changed, 118 insertions(+), 98 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/Assets.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/Assets.cs index a59991b4b837..511db0871d9a 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/Assets.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/Assets.cs @@ -16,6 +16,11 @@ internal class Assets { private readonly ILogger logger; + /// + /// Contains the dependencies found in the parsed asset files. + /// + public DependencyContainer Dependencies { get; } = new(); + internal Assets(ILogger logger) { this.logger = logger; @@ -72,7 +77,7 @@ private record class ReferenceInfo(string? Type, Dictionary? Com /// "json.net" /// } /// - private void AddPackageDependencies(JObject json, DependencyContainer dependencies) + private void AddPackageDependencies(JObject json) { // If there is more than one framework we need to pick just one. // To ensure stability we pick one based on the lexicographic order of @@ -107,13 +112,13 @@ private void AddPackageDependencies(JObject json, DependencyContainer dependenci // If this is a framework reference then include everything. if (FrameworkPackageNames.AllFrameworks.Any(framework => name.StartsWith(framework))) { - dependencies.AddFramework(name); + Dependencies.AddFramework(name); } return; } info.Compile - .ForEach(r => dependencies.Add(name, r.Key)); + .ForEach(r => Dependencies.Add(name, r.Key)); }); return; @@ -149,7 +154,7 @@ private void AddPackageDependencies(JObject json, DependencyContainer dependenci /// "microsoft.netcore.app.ref" /// } /// - private void AddFrameworkDependencies(JObject json, DependencyContainer dependencies) + private void AddFrameworkDependencies(JObject json) { var frameworks = json @@ -178,7 +183,7 @@ private void AddFrameworkDependencies(JObject json, DependencyContainer dependen references .Properties() - .ForEach(f => dependencies.AddFramework($"{f.Name}.Ref".ToLowerInvariant())); + .ForEach(f => Dependencies.AddFramework($"{f.Name}.Ref".ToLowerInvariant())); } /// @@ -186,13 +191,13 @@ private void AddFrameworkDependencies(JObject json, DependencyContainer dependen /// (together with used package information) required for compilation. /// /// True if parsing succeeds, otherwise false. - public bool TryParse(string json, DependencyContainer dependencies) + public bool TryParse(string json) { try { var obj = JObject.Parse(json); - AddPackageDependencies(obj, dependencies); - AddFrameworkDependencies(obj, dependencies); + AddPackageDependencies(obj); + AddFrameworkDependencies(obj); return true; } catch (Exception e) @@ -217,19 +222,24 @@ private static bool TryReadAllText(string path, ILogger logger, [NotNullWhen(ret } } - public static DependencyContainer GetCompilationDependencies(ILogger logger, IEnumerable assets) + /// + /// Add the dependencies from the assets file to the dependencies. + /// + /// Path to an asset file. + public void AddDependencies(string asset) { - var parser = new Assets(logger); - var dependencies = new DependencyContainer(); - assets.ForEach(asset => + if (TryReadAllText(asset, logger, out var json)) { - if (TryReadAllText(asset, logger, out var json)) - { - parser.TryParse(json, dependencies); - } - }); - return dependencies; + TryParse(json); + } } + + /// + /// Add the dependencies from the assets files to the dependencies. + /// + /// Collection of paths to asset files. + public void AddDependenciesRange(IEnumerable assets) => + assets.ForEach(AddDependencies); } internal static class JsonExtensions diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyContainer.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyContainer.cs index d3858f17fe18..6251fa321243 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyContainer.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyContainer.cs @@ -12,7 +12,7 @@ internal class DependencyContainer /// /// Paths to dependencies required for compilation. /// - public List Paths { get; } = new(); + public HashSet Paths { get; } = new(); /// /// Packages that are used as a part of the required dependencies. @@ -68,4 +68,18 @@ public void AddFramework(string framework) Packages.Add(GetPackageName(p)); } } -} \ No newline at end of file + + internal static class DependencyContainerExtensions + { + /// + /// Flatten a list of containers into a single container. + /// + public static DependencyContainer Flatten(this IEnumerable container) => + container.Aggregate(new DependencyContainer(), (acc, c) => + { + acc.Paths.UnionWith(c.Paths); + acc.Packages.UnionWith(c.Packages); + return acc; + }); + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs index d0e68defac16..ff9230e7c9b7 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs @@ -3,8 +3,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Security.Cryptography; -using System.Text; using System.Threading.Tasks; using Semmle.Util; diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs index d76ad1a676ae..371b33dfecaa 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs @@ -144,11 +144,12 @@ public HashSet Restore() logger.LogError($"Failed to restore Nuget packages with nuget.exe: {exc.Message}"); } - var restoredProjects = RestoreSolutions(out var assets1); + var restoredProjects = RestoreSolutions(out var container); var projects = fileProvider.Projects.Except(restoredProjects); - RestoreProjects(projects, out var assets2); + RestoreProjects(projects, out var containers); - var dependencies = Assets.GetCompilationDependencies(logger, assets1.Union(assets2)); + containers.Add(container); + var dependencies = containers.Flatten(); var paths = dependencies .Paths @@ -198,14 +199,14 @@ private List GetReachableFallbackNugetFeeds() /// As opposed to RestoreProjects this is not run in parallel using PLINQ /// as `dotnet restore` on a solution already uses multiple threads for restoring /// the projects (this can be disabled with the `--disable-parallel` flag). - /// Populates assets with the relative paths to the assets files generated by the restore. + /// Populates dependencies with the relevant dependencies from the assets files generated by the restore. /// Returns a list of projects that are up to date with respect to restore. /// - private IEnumerable RestoreSolutions(out IEnumerable assets) + private IEnumerable RestoreSolutions(out DependencyContainer dependencies) { var successCount = 0; var nugetSourceFailures = 0; - var assetFiles = new List(); + var assets = new Assets(logger); var projects = fileProvider.Solutions.SelectMany(solution => { logger.LogInfo($"Restoring solution {solution}..."); @@ -218,10 +219,10 @@ private IEnumerable RestoreSolutions(out IEnumerable assets) { nugetSourceFailures++; } - assetFiles.AddRange(res.AssetsFilePaths); + assets.AddDependenciesRange(res.AssetsFilePaths); return res.RestoredProjects; }).ToList(); - assets = assetFiles; + dependencies = assets.Dependencies; compilationInfoContainer.CompilationInfos.Add(("Successfully restored solution files", successCount.ToString())); compilationInfoContainer.CompilationInfos.Add(("Failed solution restore with package source error", nugetSourceFailures.ToString())); compilationInfoContainer.CompilationInfos.Add(("Restored projects through solution files", projects.Count.ToString())); @@ -231,22 +232,24 @@ private IEnumerable RestoreSolutions(out IEnumerable assets) /// /// Executes `dotnet restore` on all projects in projects. /// This is done in parallel for performance reasons. - /// Populates assets with the relative paths to the assets files generated by the restore. + /// Populates dependencies with the relative paths to the assets files generated by the restore. /// /// A list of paths to project files. - private void RestoreProjects(IEnumerable projects, out IEnumerable assets) + private void RestoreProjects(IEnumerable projects, out List dependencies) { var successCount = 0; var nugetSourceFailures = 0; - var assetFiles = new List(); + List collectedDependencies = []; var sync = new object(); var projectGroups = projects.GroupBy(Path.GetDirectoryName); Parallel.ForEach(projectGroups, new ParallelOptions { MaxDegreeOfParallelism = DependencyManager.Threads }, projectGroup => { + var assets = new Assets(logger); foreach (var project in projectGroup) { logger.LogInfo($"Restoring project {project}..."); var res = dotnet.Restore(new(project, PackageDirectory.DirInfo.FullName, ForceDotnetRefAssemblyFetching: true)); + assets.AddDependenciesRange(res.AssetsFilePaths); lock (sync) { if (res.Success) @@ -257,11 +260,14 @@ private void RestoreProjects(IEnumerable projects, out IEnumerable From 181a063bb9c9b2b29a7713d997afe5c46002bb85 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Thu, 25 Apr 2024 15:38:39 +0200 Subject: [PATCH 046/238] C#: Update expected test output. --- .../standalone_dependencies_multi_project/Assemblies.expected | 1 + 1 file changed, 1 insertion(+) diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/Assemblies.expected b/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/Assemblies.expected index 8ad98c213790..2d54c0155a43 100644 --- a/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/Assemblies.expected +++ b/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/Assemblies.expected @@ -1,4 +1,5 @@ | [...]/avalara.avatax/23.11.0/lib/netstandard2.0/Avalara.AvaTax.RestClient.dll | +| [...]/microsoft.bcl.asyncinterfaces/8.0.0/lib/netstandard2.1/Microsoft.Bcl.AsyncInterfaces.dll | | [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/Microsoft.CSharp.dll | | [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/Microsoft.VisualBasic.Core.dll | | [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/Microsoft.VisualBasic.dll | From 14d04903dc9f858e9d58f8bd0b6152218f0143f0 Mon Sep 17 00:00:00 2001 From: Florin Coada Date: Thu, 25 Apr 2024 14:40:44 +0100 Subject: [PATCH 047/238] Update codeql-changelog index.rst to include codeql-cli-2.17.1 --- .../codeql-changelog/codeql-cli-2.17.1.rst | 106 ++++++++++++++++++ .../codeql-changelog/index.rst | 1 + 2 files changed, 107 insertions(+) create mode 100644 docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.17.1.rst diff --git a/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.17.1.rst b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.17.1.rst new file mode 100644 index 000000000000..e0e09d2a2270 --- /dev/null +++ b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.17.1.rst @@ -0,0 +1,106 @@ +.. _codeql-cli-2.17.1: + +========================== +CodeQL 2.17.1 (2024-04-24) +========================== + +.. contents:: Contents + :depth: 2 + :local: + :backlinks: none + +This is an overview of changes in the CodeQL CLI and relevant CodeQL query and library packs. For additional updates on changes to the CodeQL code scanning experience, check out the `code scanning section on the GitHub blog `__, `relevant GitHub Changelog updates `__, `changes in the CodeQL extension for Visual Studio Code `__, and the `CodeQL Action changelog `__. + +Security Coverage +----------------- + +CodeQL 2.17.1 runs a total of 412 security queries when configured with the Default suite (covering 160 CWE). The Extended suite enables an additional 130 queries (covering 34 more CWE). 2 security queries have been added with this release. + +CodeQL CLI +---------- + +Deprecations +~~~~~~~~~~~~ + +* The :code:`--mode` option and :code:`-m` alias to :code:`codeql database create`, + :code:`codeql database cleanup`, and :code:`codeql dataset cleanup` has been deprecated. Instead, use the new :code:`--cache-cleanup` option, which has identical behavior. + +Improvements +~~~~~~~~~~~~ + +* Improved the diagnostic message produced when no code is processed when creating a database. If a build mode was specified using + :code:`--build-mode`, the message is now tailored to your build mode. + +Miscellaneous +~~~~~~~~~~~~~ + +* The :code:`scc` tool used by the CodeQL CLI to calculate source code baseline information has been updated to version `3.2.0 `__. + +Query Packs +----------- + +Minor Analysis Improvements +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Java +"""" + +* The :code:`java/unknown-javadoc-parameter` now accepts :code:`@param` tags that apply to the parameters of a record. + +JavaScript/TypeScript +""""""""""""""""""""" + +* :code:`API::Node#getInstance()` now includes instances of subclasses, include transitive subclasses. + The same changes applies to uses of the :code:`Instance` token in data extensions. + +New Queries +~~~~~~~~~~~ + +Ruby +"""" + +* Added a new query, :code:`rb/insecure-mass-assignment`, for finding instances of mass assignment operations accepting arbitrary parameters from remote user input. +* Added a new query, :code:`rb/csrf-protection-not-enabled`, to detect cases where Cross-Site Request Forgery protection is not enabled in Ruby on Rails controllers. + +Language Libraries +------------------ + +Minor Analysis Improvements +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +C# +"" + +* Extracting suppress nullable warning expressions did not work when applied directly to a method call (like :code:`System.Console.Readline()!`). This has been fixed. + +Golang +"""""" + +* Data flow through variables declared in statements of the form :code:`x := y.(type)` at the beginning of type switches has been fixed, which may result in more alerts. +* Added strings.ReplaceAll, http.ParseMultipartForm sanitizers and remove path sanitizer. + +Java +"""" + +* About 6,700 summary models and 6,800 neutral summary models for the JDK that were generated using data flow have been added. This may lead to new alerts being reported. + +Python +"""""" + +* Improved the type-tracking capabilities (and therefore also API graphs) to allow tracking items in tuples and dictionaries. + +Shared Libraries +---------------- + +New Features +~~~~~~~~~~~~ + +Dataflow Analysis +""""""""""""""""" + +* The :code:`PathGraph` result of a data flow computation has been augmented with model provenance information for each of the flow steps. Any qltests that include the edges relation in their output (for example, :code:`.qlref`\ s that reference path-problem queries) will need to be have their expected output updated accordingly. + +Type-flow Analysis +"""""""""""""""""" + +* Initial release. Adds a library to implement type-flow analysis. diff --git a/docs/codeql/codeql-overview/codeql-changelog/index.rst b/docs/codeql/codeql-overview/codeql-changelog/index.rst index 222e133ed190..3662d5fccff4 100644 --- a/docs/codeql/codeql-overview/codeql-changelog/index.rst +++ b/docs/codeql/codeql-overview/codeql-changelog/index.rst @@ -11,6 +11,7 @@ A list of queries for each suite and language `is available here Date: Thu, 25 Apr 2024 14:52:36 +0100 Subject: [PATCH 048/238] C++: Fix typo. --- .../CWE/CWE-125/DangerousWorksWithMultibyteOrWideCharacters.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-125/DangerousWorksWithMultibyteOrWideCharacters.ql b/cpp/ql/src/experimental/Security/CWE/CWE-125/DangerousWorksWithMultibyteOrWideCharacters.ql index 12a44be0d1fc..6529bf6cdf89 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-125/DangerousWorksWithMultibyteOrWideCharacters.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-125/DangerousWorksWithMultibyteOrWideCharacters.ql @@ -24,7 +24,7 @@ predicate exprMayBeString(Expr exp) { fctmp.getAnArgument().(VariableAccess).getTarget() = exp.(VariableAccess).getTarget() or globalValueNumber(fctmp.getAnArgument()) = globalValueNumber(exp) ) and - fctmp.getTarget().hasName(["strlen", "strcat", "strncat", "strcpy", "sptintf", "printf"]) + fctmp.getTarget().hasName(["strlen", "strcat", "strncat", "strcpy", "sprintf", "printf"]) ) or exists(AssignExpr astmp | From bbd80ec7a4891b24f263bd3f3171485abb0729d6 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 25 Apr 2024 16:15:20 +0100 Subject: [PATCH 049/238] C++: Add some more test cases. --- .../CWE-022/semmle/tests/TaintedPath.expected | 26 +++++++++++++++--- .../CWE/CWE-022/semmle/tests/stdlib.h | 2 ++ .../Security/CWE/CWE-022/semmle/tests/test.c | 27 ++++++++++++++++--- 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/TaintedPath.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/TaintedPath.expected index 1a1bf6081e21..4706b9729678 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/TaintedPath.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/TaintedPath.expected @@ -1,11 +1,17 @@ edges | test.c:8:27:8:30 | **argv | test.c:9:23:9:29 | *access to array | provenance | | | test.c:8:27:8:30 | **argv | test.c:31:22:31:28 | *access to array | provenance | | -| test.c:8:27:8:30 | **argv | test.c:57:10:57:16 | *access to array | provenance | | +| test.c:8:27:8:30 | **argv | test.c:69:14:69:20 | *access to array | provenance | | | test.c:9:23:9:29 | *access to array | test.c:17:11:17:18 | *fileName | provenance | TaintFunction | | test.c:31:22:31:28 | *access to array | test.c:32:11:32:18 | *fileName | provenance | | | test.c:37:17:37:24 | scanf output argument | test.c:38:11:38:18 | *fileName | provenance | | | test.c:43:17:43:24 | scanf output argument | test.c:44:11:44:18 | *fileName | provenance | | +| test.c:48:21:48:26 | *call to getenv | test.c:48:21:48:26 | *call to getenv | provenance | | +| test.c:48:21:48:26 | *call to getenv | test.c:49:11:49:17 | *tainted | provenance | | +| test.c:54:21:54:26 | *call to getenv | test.c:55:11:55:16 | *buffer | provenance | TaintFunction | +| test.c:54:21:54:26 | *call to getenv | test.c:56:11:56:16 | *buffer | provenance | TaintFunction | +| test.c:74:13:74:18 | read output argument | test.c:76:11:76:16 | *buffer | provenance | | +| test.c:75:13:75:18 | read output argument | test.c:76:11:76:16 | *buffer | provenance | | nodes | test.c:8:27:8:30 | **argv | semmle.label | **argv | | test.c:9:23:9:29 | *access to array | semmle.label | *access to array | @@ -16,11 +22,25 @@ nodes | test.c:38:11:38:18 | *fileName | semmle.label | *fileName | | test.c:43:17:43:24 | scanf output argument | semmle.label | scanf output argument | | test.c:44:11:44:18 | *fileName | semmle.label | *fileName | -| test.c:57:10:57:16 | *access to array | semmle.label | *access to array | +| test.c:48:21:48:26 | *call to getenv | semmle.label | *call to getenv | +| test.c:48:21:48:26 | *call to getenv | semmle.label | *call to getenv | +| test.c:49:11:49:17 | *tainted | semmle.label | *tainted | +| test.c:54:21:54:26 | *call to getenv | semmle.label | *call to getenv | +| test.c:55:11:55:16 | *buffer | semmle.label | *buffer | +| test.c:56:11:56:16 | *buffer | semmle.label | *buffer | +| test.c:69:14:69:20 | *access to array | semmle.label | *access to array | +| test.c:74:13:74:18 | read output argument | semmle.label | read output argument | +| test.c:75:13:75:18 | read output argument | semmle.label | read output argument | +| test.c:76:11:76:16 | *buffer | semmle.label | *buffer | subpaths #select | test.c:17:11:17:18 | fileName | test.c:8:27:8:30 | **argv | test.c:17:11:17:18 | *fileName | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:8:27:8:30 | **argv | user input (a command-line argument) | | test.c:32:11:32:18 | fileName | test.c:8:27:8:30 | **argv | test.c:32:11:32:18 | *fileName | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:8:27:8:30 | **argv | user input (a command-line argument) | | test.c:38:11:38:18 | fileName | test.c:37:17:37:24 | scanf output argument | test.c:38:11:38:18 | *fileName | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:37:17:37:24 | scanf output argument | user input (value read by scanf) | | test.c:44:11:44:18 | fileName | test.c:43:17:43:24 | scanf output argument | test.c:44:11:44:18 | *fileName | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:43:17:43:24 | scanf output argument | user input (value read by scanf) | -| test.c:57:10:57:16 | access to array | test.c:8:27:8:30 | **argv | test.c:57:10:57:16 | *access to array | This argument to a file access function is derived from $@ and then passed to read(fileName), which calls fopen(filename). | test.c:8:27:8:30 | **argv | user input (a command-line argument) | +| test.c:49:11:49:17 | tainted | test.c:48:21:48:26 | *call to getenv | test.c:49:11:49:17 | *tainted | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:48:21:48:26 | *call to getenv | user input (an environment variable) | +| test.c:55:11:55:16 | buffer | test.c:54:21:54:26 | *call to getenv | test.c:55:11:55:16 | *buffer | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:54:21:54:26 | *call to getenv | user input (an environment variable) | +| test.c:56:11:56:16 | buffer | test.c:54:21:54:26 | *call to getenv | test.c:56:11:56:16 | *buffer | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:54:21:54:26 | *call to getenv | user input (an environment variable) | +| test.c:69:14:69:20 | access to array | test.c:8:27:8:30 | **argv | test.c:69:14:69:20 | *access to array | This argument to a file access function is derived from $@ and then passed to readFile(fileName), which calls fopen(filename). | test.c:8:27:8:30 | **argv | user input (a command-line argument) | +| test.c:76:11:76:16 | buffer | test.c:74:13:74:18 | read output argument | test.c:76:11:76:16 | *buffer | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:74:13:74:18 | read output argument | user input (buffer read by read) | +| test.c:76:11:76:16 | buffer | test.c:75:13:75:18 | read output argument | test.c:76:11:76:16 | *buffer | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:75:13:75:18 | read output argument | user input (buffer read by read) | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/stdlib.h b/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/stdlib.h index 5b6483480f73..53344da57d6d 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/stdlib.h +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/stdlib.h @@ -6,6 +6,7 @@ typedef struct {} FILE; #define FILENAME_MAX 1000 typedef unsigned long size_t; +typedef signed long ssize_t; FILE *fopen(const char *filename, const char *mode); int sprintf(char *s, const char *format, ...); @@ -15,3 +16,4 @@ int scanf(const char *format, ...); void *malloc(size_t size); double strtod(const char *ptr, char **endptr); char *getenv(const char *name); +ssize_t read(int fd, void *buffer, size_t count); diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/test.c b/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/test.c index 824db8f16ada..4c4782758324 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/test.c +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/test.c @@ -7,7 +7,7 @@ int main(int argc, char** argv) { char *userAndFile = argv[2]; - + { char fileBuffer[FILENAME_MAX] = "/home/"; char *fileName = fileBuffer; @@ -44,6 +44,18 @@ int main(int argc, char** argv) { fopen(fileName, "wb+"); // BAD } + { + char *tainted = getenv("A_STRING"); + fopen(tainted, "wb+"); // BAD + } + + { + char buffer[1024]; + strncpy(buffer, getenv("A_STRING"), 1024); + fopen(buffer, "wb+"); // BAD + fopen(buffer, "wb+"); // (we don't want a duplicate result here) + } + { char *aNumber = getenv("A_NUMBER"); double number = strtod(aNumber, 0); @@ -53,11 +65,18 @@ int main(int argc, char** argv) { } { - void read(const char *fileName); - read(argv[1]); // BAD + void readFile(const char *fileName); + readFile(argv[1]); // BAD + } + + { + char buffer[1024]; + read(0, buffer, 1024); + read(0, buffer, 1024); + fopen(buffer, "wb+"); // BAD [duplicated with both sources] } } -void read(char *fileName) { +void readFile(char *fileName) { fopen(fileName, "wb+"); } From 15123a7b409c137d8fe5241bbd1e428e25ccfa6a Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 25 Apr 2024 16:19:38 +0100 Subject: [PATCH 050/238] C++: Reduce duplication. --- cpp/ql/src/Security/CWE/CWE-022/TaintedPath.ql | 5 +++++ .../Security/CWE/CWE-022/semmle/tests/TaintedPath.expected | 3 --- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/cpp/ql/src/Security/CWE/CWE-022/TaintedPath.ql b/cpp/ql/src/Security/CWE/CWE-022/TaintedPath.ql index 4e626d0bc773..94a9cacf9f49 100644 --- a/cpp/ql/src/Security/CWE/CWE-022/TaintedPath.ql +++ b/cpp/ql/src/Security/CWE/CWE-022/TaintedPath.ql @@ -88,6 +88,11 @@ module TaintedPathConfig implements DataFlow::ConfigSig { hasUpperBoundsCheck(checkedVar) ) } + + predicate isBarrierOut(DataFlow::Node node) { + // make sinks barriers so that we only report the closest instance + isSink(node) + } } module TaintedPath = TaintTracking::Global; diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/TaintedPath.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/TaintedPath.expected index 4706b9729678..f8b96c81b1eb 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/TaintedPath.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/TaintedPath.expected @@ -9,7 +9,6 @@ edges | test.c:48:21:48:26 | *call to getenv | test.c:48:21:48:26 | *call to getenv | provenance | | | test.c:48:21:48:26 | *call to getenv | test.c:49:11:49:17 | *tainted | provenance | | | test.c:54:21:54:26 | *call to getenv | test.c:55:11:55:16 | *buffer | provenance | TaintFunction | -| test.c:54:21:54:26 | *call to getenv | test.c:56:11:56:16 | *buffer | provenance | TaintFunction | | test.c:74:13:74:18 | read output argument | test.c:76:11:76:16 | *buffer | provenance | | | test.c:75:13:75:18 | read output argument | test.c:76:11:76:16 | *buffer | provenance | | nodes @@ -27,7 +26,6 @@ nodes | test.c:49:11:49:17 | *tainted | semmle.label | *tainted | | test.c:54:21:54:26 | *call to getenv | semmle.label | *call to getenv | | test.c:55:11:55:16 | *buffer | semmle.label | *buffer | -| test.c:56:11:56:16 | *buffer | semmle.label | *buffer | | test.c:69:14:69:20 | *access to array | semmle.label | *access to array | | test.c:74:13:74:18 | read output argument | semmle.label | read output argument | | test.c:75:13:75:18 | read output argument | semmle.label | read output argument | @@ -40,7 +38,6 @@ subpaths | test.c:44:11:44:18 | fileName | test.c:43:17:43:24 | scanf output argument | test.c:44:11:44:18 | *fileName | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:43:17:43:24 | scanf output argument | user input (value read by scanf) | | test.c:49:11:49:17 | tainted | test.c:48:21:48:26 | *call to getenv | test.c:49:11:49:17 | *tainted | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:48:21:48:26 | *call to getenv | user input (an environment variable) | | test.c:55:11:55:16 | buffer | test.c:54:21:54:26 | *call to getenv | test.c:55:11:55:16 | *buffer | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:54:21:54:26 | *call to getenv | user input (an environment variable) | -| test.c:56:11:56:16 | buffer | test.c:54:21:54:26 | *call to getenv | test.c:56:11:56:16 | *buffer | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:54:21:54:26 | *call to getenv | user input (an environment variable) | | test.c:69:14:69:20 | access to array | test.c:8:27:8:30 | **argv | test.c:69:14:69:20 | *access to array | This argument to a file access function is derived from $@ and then passed to readFile(fileName), which calls fopen(filename). | test.c:8:27:8:30 | **argv | user input (a command-line argument) | | test.c:76:11:76:16 | buffer | test.c:74:13:74:18 | read output argument | test.c:76:11:76:16 | *buffer | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:74:13:74:18 | read output argument | user input (buffer read by read) | | test.c:76:11:76:16 | buffer | test.c:75:13:75:18 | read output argument | test.c:76:11:76:16 | *buffer | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:75:13:75:18 | read output argument | user input (buffer read by read) | From 553871678a4f8ce4114a3bf2810a6d526498e33d Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 25 Apr 2024 16:52:01 +0100 Subject: [PATCH 051/238] C++: Change note. --- cpp/ql/src/change-notes/2024-04-25-path-injection.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 cpp/ql/src/change-notes/2024-04-25-path-injection.md diff --git a/cpp/ql/src/change-notes/2024-04-25-path-injection.md b/cpp/ql/src/change-notes/2024-04-25-path-injection.md new file mode 100644 index 000000000000..9989a7dc6221 --- /dev/null +++ b/cpp/ql/src/change-notes/2024-04-25-path-injection.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The "Uncontrolled data used in path expression" query (`cpp/path-injection`) query produces fewer near-duplicate results. From baa31e1469a40d8a67d446165ffe7c8b1f84e5cc Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Thu, 25 Apr 2024 22:19:28 +0200 Subject: [PATCH 052/238] delete outdated deprecations --- .../valuenumbering/GlobalValueNumbering.qll | 1 - .../GlobalValueNumberingImpl.qll | 616 ------------------ csharp/ql/lib/semmle/code/csharp/Callable.qll | 13 - .../semmle/code/csharp/exprs/Assignment.qll | 6 - .../code/csharp/exprs/BitwiseOperation.qll | 6 - .../security/dataflow/ExternalAPIsQuery.qll | 11 - go/ql/lib/semmle/go/security/FlowSources.qll | 2 - java/ql/lib/semmle/code/java/Expr.qll | 18 - .../java/dataflow/internal/DataFlowImpl1.qll | 8 - .../java/dataflow/internal/DataFlowImpl2.qll | 8 - .../java/dataflow/internal/DataFlowImpl3.qll | 8 - .../java/dataflow/internal/DataFlowImpl4.qll | 8 - .../java/dataflow/internal/DataFlowImpl5.qll | 8 - .../java/dataflow/internal/DataFlowImpl6.qll | 8 - .../semmle/code/java/regex/RegexTreeView.qll | 8 - .../ql/lib/semmle/javascript/Concepts.qll | 11 +- .../ql/lib/semmle/javascript/Regexp.qll | 14 - .../javascript/security/BadTagFilterQuery.qll | 8 - .../security/OverlyLargeRangeQuery.qll | 8 - .../security/regexp/RegexpMatching.qll | 9 - .../Security/CWE-020/HostnameRegexpShared.qll | 7 - .../lib/semmle/python/dataflow/new/Regexp.qll | 14 - .../Security/CWE-020/HostnameRegexpShared.qll | 8 - ruby/ql/lib/codeql/ruby/Regexp.qll | 14 - .../security/cwe-020/HostnameRegexpShared.qll | 8 - 25 files changed, 1 insertion(+), 829 deletions(-) delete mode 100644 cpp/ql/lib/semmle/code/cpp/valuenumbering/GlobalValueNumbering.qll delete mode 100644 cpp/ql/lib/semmle/code/cpp/valuenumbering/GlobalValueNumberingImpl.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/BadTagFilterQuery.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/OverlyLargeRangeQuery.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/regexp/RegexpMatching.qll delete mode 100644 javascript/ql/src/Security/CWE-020/HostnameRegexpShared.qll delete mode 100644 python/ql/src/Security/CWE-020/HostnameRegexpShared.qll delete mode 100644 ruby/ql/src/queries/security/cwe-020/HostnameRegexpShared.qll diff --git a/cpp/ql/lib/semmle/code/cpp/valuenumbering/GlobalValueNumbering.qll b/cpp/ql/lib/semmle/code/cpp/valuenumbering/GlobalValueNumbering.qll deleted file mode 100644 index cb28edc07b99..000000000000 --- a/cpp/ql/lib/semmle/code/cpp/valuenumbering/GlobalValueNumbering.qll +++ /dev/null @@ -1 +0,0 @@ -import semmle.code.cpp.ir.internal.ASTValueNumbering diff --git a/cpp/ql/lib/semmle/code/cpp/valuenumbering/GlobalValueNumberingImpl.qll b/cpp/ql/lib/semmle/code/cpp/valuenumbering/GlobalValueNumberingImpl.qll deleted file mode 100644 index 8f43e19c7b55..000000000000 --- a/cpp/ql/lib/semmle/code/cpp/valuenumbering/GlobalValueNumberingImpl.qll +++ /dev/null @@ -1,616 +0,0 @@ -/** - * DEPRECATED: This library has been replaced with a newer version which - * provides better performance and precision. Use - * `semmle.code.cpp.valuenumbering.GlobalValueNumbering` instead. - * - * Provides an implementation of Global Value Numbering. - * See https://en.wikipedia.org/wiki/Global_value_numbering - * - * The predicate `globalValueNumber` converts an expression into a `GVN`, - * which is an abstract type representing the value of the expression. If - * two expressions have the same `GVN` then they compute the same value. - * For example: - * - * ``` - * void f(int x, int y) { - * g(x+y, x+y); - * } - * ``` - * - * In this example, both arguments in the call to `g` compute the same value, - * so both arguments have the same `GVN`. In other words, we can find - * this call with the following query: - * - * ``` - * from FunctionCall call, GVN v - * where v = globalValueNumber(call.getArgument(0)) - * and v = globalValueNumber(call.getArgument(1)) - * select call - * ``` - * - * The analysis is conservative, so two expressions might have different - * `GVN`s even though the actually always compute the same value. The most - * common reason for this is that the analysis cannot prove that there - * are no side-effects that might cause the computed value to change. - */ - -/* - * Note to developers: the correctness of this module depends on the - * definitions of GVN, globalValueNumber, and analyzableExpr being kept in - * sync with each other. If you change this module then make sure that the - * change is symmetric across all three. - */ - -import cpp -private import semmle.code.cpp.controlflow.SSA - -/** - * Holds if the result is a control flow node that might change the - * value of any global variable. This is used in the implementation - * of `GVN_OtherVariable`, because we need to be quite conservative when - * we assign a value number to a global variable. For example: - * - * ``` - * x = g+1; - * dosomething(); - * y = g+1; - * ``` - * - * It is not safe to assign the same value number to both instances - * of `g+1` in this example, because the call to `dosomething` might - * change the value of `g`. - */ -private ControlFlowNode nodeWithPossibleSideEffect() { - result instanceof Call - or - // If the lhs of an assignment is not analyzable by SSA, then - // we need to treat the assignment as having a possible side-effect. - result instanceof Assignment and not result instanceof SsaDefinition - or - result instanceof CrementOperation and not result instanceof SsaDefinition - or - exists(LocalVariable v | - result = v.getInitializer().getExpr() and not result instanceof SsaDefinition - ) - or - result instanceof AsmStmt -} - -/** - * Gets the entry node of the control flow graph of which `node` is a - * member. - */ -cached -private ControlFlowNode getControlFlowEntry(ControlFlowNode node) { - result = node.getControlFlowScope().getEntryPoint() and - result.getASuccessor*() = node -} - -/** - * Holds if there is a control flow edge from `src` to `dst` or - * if `dst` is an expression with a possible side-effect. The idea - * is to treat side effects as entry points in the control flow - * graph so that we can use the dominator tree to find the most recent - * side-effect. - */ -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 - // effect. - dst = nodeWithPossibleSideEffect() and - src = getControlFlowEntry(dst) -} - -/** - * Holds if `dominator` is the immediate dominator of `node` in - * the side-effect CFG. - */ -private predicate iDomEffect(ControlFlowNode dominator, ControlFlowNode node) = - idominance(functionEntry/1, sideEffectCfg/2)(_, dominator, node) - -/** - * Gets the most recent side effect. To be more precise, `result` is a - * dominator of `node` and no side-effects can occur between `result` and - * `node`. - * - * `sideEffectCFG` has an edge from the function entry to every node with a - * side-effect. This means that every node with a side-effect has the - * function entry as its immediate dominator. So if node `x` dominates node - * `y` then there can be no side effects between `x` and `y` unless `x` is - * the function entry. So the optimal choice for `result` has the function - * entry as its immediate dominator. - * - * Example: - * - * ``` - * 000: int f(int a, int b, int *p) { - * 001: int r = 0; - * 002: if (a) { - * 003: if (b) { - * 004: sideEffect1(); - * 005: } - * 006: } else { - * 007: sideEffect2(); - * 008: } - * 009: if (a) { - * 010: r++; // Not a side-effect, because r is an SSA variable. - * 011: } - * 012: if (b) { - * 013: r++; // Not a side-effect, because r is an SSA variable. - * 014: } - * 015: return *p; - * 016: } - * ``` - * - * Suppose we want to find the most recent side-effect for the dereference - * of `p` on line 015. The `sideEffectCFG` has an edge from the function - * entry (line 000) to the side effects at lines 004 and 007. Therefore, - * the immediate dominator tree looks like this: - * - * 000 - 001 - 002 - 003 - * - 004 - * - 007 - * - 009 - 010 - * - 012 - 013 - * - 015 - * - * The immediate dominator path to line 015 is 000 - 009 - 012 - 015. - * Therefore, the most recent side effect for line 015 is line 009. - */ -cached -private ControlFlowNode mostRecentSideEffect(ControlFlowNode node) { - exists(ControlFlowNode entry | - functionEntry(entry) and - iDomEffect(entry, result) and - iDomEffect*(result, node) - ) -} - -/** Used to represent the "global value number" of an expression. */ -cached -private newtype GvnBase = - GVN_IntConst(int val, Type t) { mk_IntConst(val, t, _) } or - GVN_FloatConst(float val, Type t) { mk_FloatConst(val, t, _) } or - // If the local variable does not have a defining value, then - // we use the SsaDefinition as its global value number. - GVN_UndefinedStackVariable(StackVariable x, SsaDefinition def) { - mk_UndefinedStackVariable(x, def, _) - } or - // Variables with no SSA information. As a crude (but safe) - // approximation, we use `mostRecentSideEffect` to compute a definition - // location for the variable. This ensures that two instances of the same - // global variable will only get the same value number if they are - // guaranteed to have the same value. - GVN_OtherVariable(Variable x, ControlFlowNode dominator) { mk_OtherVariable(x, dominator, _) } or - deprecated GVN_FieldAccess(GVN s, Field f) { - mk_DotFieldAccess(s, f, _) or - mk_PointerFieldAccess_with_deref(s, f, _) or - mk_ImplicitThisFieldAccess_with_deref(s, f, _) - } or - // Dereference a pointer. The value might have changed since the last - // time the pointer was dereferenced, so we need to include a definition - // location. As a crude (but safe) approximation, we use - // `mostRecentSideEffect` to compute a definition location. - deprecated GVN_Deref(GVN p, ControlFlowNode dominator) { - mk_Deref(p, dominator, _) or - mk_PointerFieldAccess(p, _, dominator, _) or - mk_ImplicitThisFieldAccess_with_qualifier(p, _, dominator, _) - } or - GVN_ThisExpr(Function fcn) { - mk_ThisExpr(fcn, _) or - mk_ImplicitThisFieldAccess(fcn, _, _, _) - } or - deprecated GVN_Conversion(Type t, GVN child) { mk_Conversion(t, child, _) } or - deprecated GVN_BinaryOp(GVN lhs, GVN rhs, string opname) { mk_BinaryOp(lhs, rhs, opname, _) } or - deprecated GVN_UnaryOp(GVN child, string opname) { mk_UnaryOp(child, opname, _) } or - deprecated GVN_ArrayAccess(GVN x, GVN i, ControlFlowNode dominator) { - mk_ArrayAccess(x, i, dominator, _) - } or - // Any expression that is not handled by the cases above is - // given a unique number based on the expression itself. - GVN_Unanalyzable(Expr e) { not analyzableExpr(e) } - -/** - * A Global Value Number. A GVN is an abstract representation of the value - * computed by an expression. The relationship between `Expr` and `GVN` is - * many-to-one: every `Expr` has exactly one `GVN`, but multiple - * expressions can have the same `GVN`. If two expressions have the same - * `GVN`, it means that they compute the same value at run time. The `GVN` - * is an opaque value, so you cannot deduce what the run-time value of an - * expression will be from its `GVN`. The only use for the `GVN` of an - * expression is to find other expressions that compute the same value. - * Use the predicate `globalValueNumber` to get the `GVN` for an `Expr`. - * - * Note: `GVN` has `toString` and `getLocation` methods, so that it can be - * displayed in a results list. These work by picking an arbitrary - * expression with this `GVN` and using its `toString` and `getLocation` - * methods. - */ -deprecated class GVN extends GvnBase { - GVN() { this instanceof GvnBase } - - /** Gets an expression that has this GVN. */ - Expr getAnExpr() { this = globalValueNumber(result) } - - /** Gets the kind of the GVN. This can be useful for debugging. */ - string getKind() { - if this instanceof GVN_IntConst - then result = "IntConst" - else - if this instanceof GVN_FloatConst - then result = "FloatConst" - else - if this instanceof GVN_UndefinedStackVariable - then result = "UndefinedStackVariable" - else - if this instanceof GVN_OtherVariable - then result = "OtherVariable" - else - if this instanceof GVN_FieldAccess - then result = "FieldAccess" - else - if this instanceof GVN_Deref - then result = "Deref" - else - if this instanceof GVN_ThisExpr - then result = "ThisExpr" - else - if this instanceof GVN_Conversion - then result = "Conversion" - else - if this instanceof GVN_BinaryOp - then result = "BinaryOp" - else - if this instanceof GVN_UnaryOp - then result = "UnaryOp" - else - if this instanceof GVN_ArrayAccess - then result = "ArrayAccess" - else - if this instanceof GVN_Unanalyzable - then result = "Unanalyzable" - else result = "error" - } - - /** - * Gets an example of an expression with this GVN. - * This is useful for things like implementing toString(). - */ - private Expr exampleExpr() { - // Pick the expression with the minimum source location string. This is - // just an arbitrary way to pick an expression with this `GVN`. - result = min(Expr e | this = globalValueNumber(e) | e order by e.getLocation().toString()) - } - - /** Gets a textual representation of this element. */ - string toString() { result = this.exampleExpr().toString() } - - /** Gets the primary location of this element. */ - Location getLocation() { result = this.exampleExpr().getLocation() } -} - -private predicate analyzableIntConst(Expr e) { - strictcount(e.getValue().toInt()) = 1 and - strictcount(e.getUnspecifiedType()) = 1 -} - -private predicate mk_IntConst(int val, Type t, Expr e) { - analyzableIntConst(e) and - val = e.getValue().toInt() and - t = e.getUnspecifiedType() -} - -private predicate analyzableFloatConst(Expr e) { - strictcount(e.getValue().toFloat()) = 1 and - strictcount(e.getUnspecifiedType()) = 1 and - not analyzableIntConst(e) -} - -private predicate mk_FloatConst(float val, Type t, Expr e) { - analyzableFloatConst(e) and - val = e.getValue().toFloat() and - t = e.getUnspecifiedType() -} - -private predicate analyzableStackVariable(VariableAccess access) { - strictcount(SsaDefinition def | def.getAUse(_) = access | def) = 1 and - strictcount(SsaDefinition def, Variable v | def.getAUse(v) = access | v) = 1 and - count(SsaDefinition def, Variable v | - def.getAUse(v) = access - | - def.getDefiningValue(v).getFullyConverted() - ) <= 1 and - not analyzableConst(access) -} - -// Note: this predicate only has a result if the access has no -// defining value. If there is a defining value, then there is no -// need to generate a fresh `GVN` for the access because `globalValueNumber` -// will follow the chain and use the GVN of the defining value. -private predicate mk_UndefinedStackVariable( - StackVariable x, SsaDefinition def, VariableAccess access -) { - analyzableStackVariable(access) and - access = def.getAUse(x) and - not exists(def.getDefiningValue(x)) -} - -private predicate analyzableDotFieldAccess(DotFieldAccess access) { - strictcount(access.getTarget()) = 1 and - strictcount(access.getQualifier().getFullyConverted()) = 1 and - not analyzableConst(access) -} - -deprecated private predicate mk_DotFieldAccess(GVN qualifier, Field target, DotFieldAccess access) { - analyzableDotFieldAccess(access) and - target = access.getTarget() and - qualifier = globalValueNumber(access.getQualifier().getFullyConverted()) -} - -private predicate analyzablePointerFieldAccess(PointerFieldAccess access) { - strictcount(mostRecentSideEffect(access)) = 1 and - strictcount(access.getTarget()) = 1 and - strictcount(access.getQualifier().getFullyConverted()) = 1 and - not analyzableConst(access) -} - -deprecated private predicate mk_PointerFieldAccess( - GVN qualifier, Field target, ControlFlowNode dominator, PointerFieldAccess access -) { - analyzablePointerFieldAccess(access) and - dominator = mostRecentSideEffect(access) and - target = access.getTarget() and - qualifier = globalValueNumber(access.getQualifier().getFullyConverted()) -} - -/** - * `obj->field` is equivalent to `(*obj).field`, so we need to wrap an - * extra `GVN_Deref` around the qualifier. - */ -deprecated private predicate mk_PointerFieldAccess_with_deref( - GVN new_qualifier, Field target, PointerFieldAccess access -) { - exists(GVN qualifier, ControlFlowNode dominator | - mk_PointerFieldAccess(qualifier, target, dominator, access) and - new_qualifier = GVN_Deref(qualifier, dominator) - ) -} - -private predicate analyzableImplicitThisFieldAccess(ImplicitThisFieldAccess access) { - strictcount(mostRecentSideEffect(access)) = 1 and - strictcount(access.getTarget()) = 1 and - strictcount(access.getEnclosingFunction()) = 1 and - not analyzableConst(access) -} - -private predicate mk_ImplicitThisFieldAccess( - Function fcn, Field target, ControlFlowNode dominator, ImplicitThisFieldAccess access -) { - analyzableImplicitThisFieldAccess(access) and - dominator = mostRecentSideEffect(access) and - target = access.getTarget() and - fcn = access.getEnclosingFunction() -} - -deprecated private predicate mk_ImplicitThisFieldAccess_with_qualifier( - GVN qualifier, Field target, ControlFlowNode dominator, ImplicitThisFieldAccess access -) { - exists(Function fcn | - mk_ImplicitThisFieldAccess(fcn, target, dominator, access) and - qualifier = GVN_ThisExpr(fcn) - ) -} - -deprecated private predicate mk_ImplicitThisFieldAccess_with_deref( - GVN new_qualifier, Field target, ImplicitThisFieldAccess access -) { - exists(GVN qualifier, ControlFlowNode dominator | - mk_ImplicitThisFieldAccess_with_qualifier(qualifier, target, dominator, access) and - new_qualifier = GVN_Deref(qualifier, dominator) - ) -} - -/** - * Holds if `access` is an access of a variable that does - * not have SSA information. (For example, because the variable - * is global.) - */ -private predicate analyzableOtherVariable(VariableAccess access) { - not access instanceof FieldAccess and - not exists(SsaDefinition def | access = def.getAUse(_)) and - strictcount(access.getTarget()) = 1 and - strictcount(mostRecentSideEffect(access)) = 1 and - not analyzableConst(access) -} - -private predicate mk_OtherVariable(Variable x, ControlFlowNode dominator, VariableAccess access) { - analyzableOtherVariable(access) and - x = access.getTarget() and - dominator = mostRecentSideEffect(access) -} - -private predicate analyzableConversion(Conversion conv) { - strictcount(conv.getUnspecifiedType()) = 1 and - strictcount(conv.getExpr()) = 1 and - not analyzableConst(conv) -} - -deprecated private predicate mk_Conversion(Type t, GVN child, Conversion conv) { - analyzableConversion(conv) and - t = conv.getUnspecifiedType() and - child = globalValueNumber(conv.getExpr()) -} - -private predicate analyzableBinaryOp(BinaryOperation op) { - op.isPure() and - strictcount(op.getLeftOperand().getFullyConverted()) = 1 and - strictcount(op.getRightOperand().getFullyConverted()) = 1 and - strictcount(op.getOperator()) = 1 and - not analyzableConst(op) -} - -deprecated private predicate mk_BinaryOp(GVN lhs, GVN rhs, string opname, BinaryOperation op) { - analyzableBinaryOp(op) and - lhs = globalValueNumber(op.getLeftOperand().getFullyConverted()) and - rhs = globalValueNumber(op.getRightOperand().getFullyConverted()) and - opname = op.getOperator() -} - -private predicate analyzableUnaryOp(UnaryOperation op) { - not op instanceof PointerDereferenceExpr and - op.isPure() and - strictcount(op.getOperand().getFullyConverted()) = 1 and - strictcount(op.getOperator()) = 1 and - not analyzableConst(op) -} - -deprecated private predicate mk_UnaryOp(GVN child, string opname, UnaryOperation op) { - analyzableUnaryOp(op) and - child = globalValueNumber(op.getOperand().getFullyConverted()) and - opname = op.getOperator() -} - -private predicate analyzableThisExpr(ThisExpr thisExpr) { - strictcount(thisExpr.getEnclosingFunction()) = 1 and - not analyzableConst(thisExpr) -} - -private predicate mk_ThisExpr(Function fcn, ThisExpr thisExpr) { - analyzableThisExpr(thisExpr) and - fcn = thisExpr.getEnclosingFunction() -} - -private predicate analyzableArrayAccess(ArrayExpr ae) { - strictcount(ae.getArrayBase().getFullyConverted()) = 1 and - strictcount(ae.getArrayOffset().getFullyConverted()) = 1 and - strictcount(mostRecentSideEffect(ae)) = 1 and - not analyzableConst(ae) -} - -deprecated private predicate mk_ArrayAccess( - GVN base, GVN offset, ControlFlowNode dominator, ArrayExpr ae -) { - analyzableArrayAccess(ae) and - base = globalValueNumber(ae.getArrayBase().getFullyConverted()) and - offset = globalValueNumber(ae.getArrayOffset().getFullyConverted()) and - dominator = mostRecentSideEffect(ae) -} - -private predicate analyzablePointerDereferenceExpr(PointerDereferenceExpr deref) { - strictcount(deref.getOperand().getFullyConverted()) = 1 and - strictcount(mostRecentSideEffect(deref)) = 1 and - not analyzableConst(deref) -} - -deprecated private predicate mk_Deref(GVN p, ControlFlowNode dominator, PointerDereferenceExpr deref) { - analyzablePointerDereferenceExpr(deref) and - p = globalValueNumber(deref.getOperand().getFullyConverted()) and - dominator = mostRecentSideEffect(deref) -} - -/** Gets the global value number of expression `e`. */ -cached -deprecated GVN globalValueNumber(Expr e) { - exists(int val, Type t | - mk_IntConst(val, t, e) and - result = GVN_IntConst(val, t) - ) - or - exists(float val, Type t | - mk_FloatConst(val, t, e) and - result = GVN_FloatConst(val, t) - ) - or - // Local variable with a defining value. - exists(StackVariable x, SsaDefinition def | - analyzableStackVariable(e) and - e = def.getAUse(x) and - result = globalValueNumber(def.getDefiningValue(x).getFullyConverted()) - ) - or - // Local variable without a defining value. - exists(StackVariable x, SsaDefinition def | - mk_UndefinedStackVariable(x, def, e) and - result = GVN_UndefinedStackVariable(x, def) - ) - or - // Variable with no SSA information. - exists(Variable x, ControlFlowNode dominator | - mk_OtherVariable(x, dominator, e) and - result = GVN_OtherVariable(x, dominator) - ) - or - exists(GVN qualifier, Field target | - mk_DotFieldAccess(qualifier, target, e) and - result = GVN_FieldAccess(qualifier, target) - ) - or - exists(GVN qualifier, Field target | - mk_PointerFieldAccess_with_deref(qualifier, target, e) and - result = GVN_FieldAccess(qualifier, target) - ) - or - exists(GVN qualifier, Field target | - mk_ImplicitThisFieldAccess_with_deref(qualifier, target, e) and - result = GVN_FieldAccess(qualifier, target) - ) - or - exists(Function fcn | - mk_ThisExpr(fcn, e) and - result = GVN_ThisExpr(fcn) - ) - or - exists(Type t, GVN child | - mk_Conversion(t, child, e) and - result = GVN_Conversion(t, child) - ) - or - exists(GVN lhs, GVN rhs, string opname | - mk_BinaryOp(lhs, rhs, opname, e) and - result = GVN_BinaryOp(lhs, rhs, opname) - ) - or - exists(GVN child, string opname | - mk_UnaryOp(child, opname, e) and - result = GVN_UnaryOp(child, opname) - ) - or - exists(GVN x, GVN i, ControlFlowNode dominator | - mk_ArrayAccess(x, i, dominator, e) and - result = GVN_ArrayAccess(x, i, dominator) - ) - or - exists(GVN p, ControlFlowNode dominator | - mk_Deref(p, dominator, e) and - result = GVN_Deref(p, dominator) - ) - or - not analyzableExpr(e) and result = GVN_Unanalyzable(e) -} - -private predicate analyzableConst(Expr e) { - analyzableIntConst(e) or - analyzableFloatConst(e) -} - -/** - * Holds if the expression is explicitly handled by `globalValueNumber`. - * Unanalyzable expressions still need to be given a global value number, - * but it will be a unique number that is not shared with any other - * expression. - */ -private predicate analyzableExpr(Expr e) { - analyzableConst(e) or - analyzableStackVariable(e) or - analyzableDotFieldAccess(e) or - analyzablePointerFieldAccess(e) or - analyzableImplicitThisFieldAccess(e) or - analyzableOtherVariable(e) or - analyzableConversion(e) or - analyzableBinaryOp(e) or - analyzableUnaryOp(e) or - analyzableThisExpr(e) or - analyzableArrayAccess(e) or - analyzablePointerDereferenceExpr(e) -} diff --git a/csharp/ql/lib/semmle/code/csharp/Callable.qll b/csharp/ql/lib/semmle/code/csharp/Callable.qll index 9cd365c2ecd6..59cffa8d39e5 100644 --- a/csharp/ql/lib/semmle/code/csharp/Callable.qll +++ b/csharp/ql/lib/semmle/code/csharp/Callable.qll @@ -527,13 +527,6 @@ class Destructor extends Callable, Member, Attributable, @destructor { * (`BinaryOperator`), or a conversion operator (`ConversionOperator`). */ class Operator extends Callable, Member, Attributable, Overridable, @operator { - /** - * DEPRECATED: use `getFunctionName()` instead. - * - * Gets the assembly name of this operator. - */ - deprecated string getAssemblyName() { result = this.getFunctionName() } - override string getName() { operators(this, _, result, _, _, _) } override string getUndecoratedName() { operators(this, _, result, _, _, _) } @@ -989,9 +982,6 @@ class LeftShiftOperator extends BinaryOperator { override string getAPrimaryQlClass() { result = "LeftShiftOperator" } } -/** DEPRECATED: Alias for LeftShiftOperator. */ -deprecated class LShiftOperator = LeftShiftOperator; - /** * A user-defined right shift operator (`>>`), for example * @@ -1007,9 +997,6 @@ class RightShiftOperator extends BinaryOperator { override string getAPrimaryQlClass() { result = "RightShiftOperator" } } -/** DEPRECATED: Alias for RightShiftOperator. */ -deprecated class RShiftOperator = RightShiftOperator; - /** * A user-defined unsigned right shift operator (`>>>`), for example * diff --git a/csharp/ql/lib/semmle/code/csharp/exprs/Assignment.qll b/csharp/ql/lib/semmle/code/csharp/exprs/Assignment.qll index 14da6da266f7..a5576f023d7b 100644 --- a/csharp/ql/lib/semmle/code/csharp/exprs/Assignment.qll +++ b/csharp/ql/lib/semmle/code/csharp/exprs/Assignment.qll @@ -192,9 +192,6 @@ class AssignLeftShiftExpr extends AssignBitwiseOperation, @assign_lshift_expr { override string getAPrimaryQlClass() { result = "AssignLeftShiftExpr" } } -/** DEPRECATED: Alias for AssignLeftShipExpr. */ -deprecated class AssignLShiftExpr = AssignLeftShiftExpr; - /** * A right-shift assignment operation, for example `x >>= y`. */ @@ -204,9 +201,6 @@ class AssignRightShiftExpr extends AssignBitwiseOperation, @assign_rshift_expr { override string getAPrimaryQlClass() { result = "AssignRightShiftExpr" } } -/** DEPRECATED: Alias for AssignRightShiftExpr. */ -deprecated class AssignRShiftExpr = AssignRightShiftExpr; - /** * An unsigned right-shift assignment operation, for example `x >>>= y`. */ diff --git a/csharp/ql/lib/semmle/code/csharp/exprs/BitwiseOperation.qll b/csharp/ql/lib/semmle/code/csharp/exprs/BitwiseOperation.qll index d32485a51f8e..d818a1d08f87 100644 --- a/csharp/ql/lib/semmle/code/csharp/exprs/BitwiseOperation.qll +++ b/csharp/ql/lib/semmle/code/csharp/exprs/BitwiseOperation.qll @@ -47,9 +47,6 @@ class LeftShiftExpr extends BinaryBitwiseOperation, @lshift_expr { override string getAPrimaryQlClass() { result = "LeftShiftExpr" } } -/** DEPRECATED: Alias for LeftShiftExpr. */ -deprecated class LShiftExpr = LeftShiftExpr; - /** * A right-shift operation, for example `x >> y`. */ @@ -59,9 +56,6 @@ class RightShiftExpr extends BinaryBitwiseOperation, @rshift_expr { override string getAPrimaryQlClass() { result = "RightShiftExpr" } } -/** DEPRECATED: Alias for RightShiftExpr. */ -deprecated class RShiftExpr = RightShiftExpr; - /** * An unsigned right-shift operation, for example `x >>> y`. */ 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 a0d0ada957a5..41888fc25571 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExternalAPIsQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExternalAPIsQuery.qll @@ -71,17 +71,6 @@ class ExternalApiDataNode extends DataFlow::Node { predicate hasQualifiedName(string qualifier, string name) { this.getCallable().hasFullyQualifiedName(qualifier, name) } - - /** - * DEPRECATED: Use hasQualifiedName/2 instead. - * - * Gets the description of the callable being called. - */ - deprecated string getCallableDescription() { - exists(string qualifier, string name | - this.hasQualifiedName(qualifier, name) and result = getQualifiedName(qualifier, name) - ) - } } /** diff --git a/go/ql/lib/semmle/go/security/FlowSources.qll b/go/ql/lib/semmle/go/security/FlowSources.qll index 6de620c79e42..cf77dade35ab 100644 --- a/go/ql/lib/semmle/go/security/FlowSources.qll +++ b/go/ql/lib/semmle/go/security/FlowSources.qll @@ -39,6 +39,4 @@ module RemoteFlowSource { class MaDRemoteSource extends Range { MaDRemoteSource() { ExternalFlow::sourceNode(this, "remote") } } - - deprecated class CsvRemoteSource = MaDRemoteSource; } diff --git a/java/ql/lib/semmle/code/java/Expr.qll b/java/ql/lib/semmle/code/java/Expr.qll index e0208b4df9e4..1862319e30bb 100644 --- a/java/ql/lib/semmle/code/java/Expr.qll +++ b/java/ql/lib/semmle/code/java/Expr.qll @@ -511,9 +511,6 @@ class AssignLeftShiftExpr extends AssignOp, @assignlshiftexpr { override string getAPrimaryQlClass() { result = "AssignLeftShiftExpr" } } -/** DEPRECATED: Alias for AssignLeftShiftExpr. */ -deprecated class AssignLShiftExpr = AssignLeftShiftExpr; - /** A compound assignment expression using the `>>=` operator. */ class AssignRightShiftExpr extends AssignOp, @assignrshiftexpr { override string getOp() { result = ">>=" } @@ -521,9 +518,6 @@ class AssignRightShiftExpr extends AssignOp, @assignrshiftexpr { override string getAPrimaryQlClass() { result = "AssignRightShiftExpr" } } -/** DEPRECATED: Alias for AssignRightShiftExpr. */ -deprecated class AssignRShiftExpr = AssignRightShiftExpr; - /** A compound assignment expression using the `>>>=` operator. */ class AssignUnsignedRightShiftExpr extends AssignOp, @assignurshiftexpr { override string getOp() { result = ">>>=" } @@ -531,9 +525,6 @@ class AssignUnsignedRightShiftExpr extends AssignOp, @assignurshiftexpr { override string getAPrimaryQlClass() { result = "AssignUnsignedRightShiftExpr" } } -/** DEPRECATED: Alias for AssignUnsignedRightShiftExpr. */ -deprecated class AssignURShiftExpr = AssignUnsignedRightShiftExpr; - /** A common super-class to represent constant literals. */ class Literal extends Expr, @literal { /** @@ -793,9 +784,6 @@ class LeftShiftExpr extends BinaryExpr, @lshiftexpr { override string getAPrimaryQlClass() { result = "LeftShiftExpr" } } -/** DEPRECATED: Alias for LeftShiftExpr. */ -deprecated class LShiftExpr = LeftShiftExpr; - /** A binary expression using the `>>` operator. */ class RightShiftExpr extends BinaryExpr, @rshiftexpr { override string getOp() { result = " >> " } @@ -803,9 +791,6 @@ class RightShiftExpr extends BinaryExpr, @rshiftexpr { override string getAPrimaryQlClass() { result = "RightShiftExpr" } } -/** DEPRECATED: Alias for RightShiftExpr. */ -deprecated class RShiftExpr = RightShiftExpr; - /** A binary expression using the `>>>` operator. */ class UnsignedRightShiftExpr extends BinaryExpr, @urshiftexpr { override string getOp() { result = " >>> " } @@ -813,9 +798,6 @@ class UnsignedRightShiftExpr extends BinaryExpr, @urshiftexpr { override string getAPrimaryQlClass() { result = "UnsignedRightShiftExpr" } } -/** DEPRECATED: Alias for UnsignedRightShiftExpr. */ -deprecated class URShiftExpr = UnsignedRightShiftExpr; - /** A binary expression using the `&` operator. */ class AndBitwiseExpr extends BinaryExpr, @andbitexpr { override string getOp() { result = " & " } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl1.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl1.qll index c3ba9fb0014c..04b058c75653 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl1.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl1.qll @@ -168,14 +168,6 @@ abstract deprecated class Configuration extends string { */ predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - /** - * DEPRECATED: Use `FlowExploration` instead. - * - * Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev` - * measured in approximate number of interprocedural steps. - */ - deprecated int explorationLimit() { none() } - /** * Holds if hidden nodes should be included in the data flow graph. * diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll index c3ba9fb0014c..04b058c75653 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll @@ -168,14 +168,6 @@ abstract deprecated class Configuration extends string { */ predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - /** - * DEPRECATED: Use `FlowExploration` instead. - * - * Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev` - * measured in approximate number of interprocedural steps. - */ - deprecated int explorationLimit() { none() } - /** * Holds if hidden nodes should be included in the data flow graph. * diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll index c3ba9fb0014c..04b058c75653 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll @@ -168,14 +168,6 @@ abstract deprecated class Configuration extends string { */ predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - /** - * DEPRECATED: Use `FlowExploration` instead. - * - * Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev` - * measured in approximate number of interprocedural steps. - */ - deprecated int explorationLimit() { none() } - /** * Holds if hidden nodes should be included in the data flow graph. * diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll index c3ba9fb0014c..04b058c75653 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll @@ -168,14 +168,6 @@ abstract deprecated class Configuration extends string { */ predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - /** - * DEPRECATED: Use `FlowExploration` instead. - * - * Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev` - * measured in approximate number of interprocedural steps. - */ - deprecated int explorationLimit() { none() } - /** * Holds if hidden nodes should be included in the data flow graph. * diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll index c3ba9fb0014c..04b058c75653 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll @@ -168,14 +168,6 @@ abstract deprecated class Configuration extends string { */ predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - /** - * DEPRECATED: Use `FlowExploration` instead. - * - * Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev` - * measured in approximate number of interprocedural steps. - */ - deprecated int explorationLimit() { none() } - /** * Holds if hidden nodes should be included in the data flow graph. * diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll index c3ba9fb0014c..04b058c75653 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll @@ -168,14 +168,6 @@ abstract deprecated class Configuration extends string { */ predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - /** - * DEPRECATED: Use `FlowExploration` instead. - * - * Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev` - * measured in approximate number of interprocedural steps. - */ - deprecated int explorationLimit() { none() } - /** * Holds if hidden nodes should be included in the data flow graph. * diff --git a/java/ql/lib/semmle/code/java/regex/RegexTreeView.qll b/java/ql/lib/semmle/code/java/regex/RegexTreeView.qll index 7575ccb62135..a07d7c741faa 100644 --- a/java/ql/lib/semmle/code/java/regex/RegexTreeView.qll +++ b/java/ql/lib/semmle/code/java/regex/RegexTreeView.qll @@ -1162,14 +1162,6 @@ module Impl implements RegexTreeViewSig { root.getLiteral().isIgnoreCase() } - /** - * Gets the flags for `root`, or the empty string if `root` has no flags. - */ - additional deprecated string getFlags(RegExpTerm root) { - root.isRootTerm() and - result = root.getLiteral().getFlags() - } - /** * Holds if `root` has the `s` flag for multi-line matching. */ diff --git a/javascript/ql/lib/semmle/javascript/Concepts.qll b/javascript/ql/lib/semmle/javascript/Concepts.qll index 01970490374c..14102556a874 100644 --- a/javascript/ql/lib/semmle/javascript/Concepts.qll +++ b/javascript/ql/lib/semmle/javascript/Concepts.qll @@ -125,16 +125,7 @@ module Cryptography { * extend `CryptographicOperation::Range` instead. */ class CryptographicOperation extends SC::CryptographicOperation instanceof CryptographicOperation::Range - { - /** - * DEPRECATED. This predicate has been renamed to `getAnInput`. - * - * To implement `CryptographicOperation`, please extend - * `CryptographicOperation::Range` and implement `getAnInput` instead of - * extending this class directly. - */ - deprecated final DataFlow::Node getInput() { result = this.getAnInput() } - } + { } class EncryptionAlgorithm = SC::EncryptionAlgorithm; diff --git a/javascript/ql/lib/semmle/javascript/Regexp.qll b/javascript/ql/lib/semmle/javascript/Regexp.qll index 3c190af44764..27ad339c733e 100644 --- a/javascript/ql/lib/semmle/javascript/Regexp.qll +++ b/javascript/ql/lib/semmle/javascript/Regexp.qll @@ -1022,20 +1022,6 @@ predicate isInterpretedAsRegExp(DataFlow::Node source) { ) } -/** - * Provides utility predicates related to regular expressions. - */ -deprecated module RegExpPatterns { - /** - * Gets a pattern that matches common top-level domain names in lower case. - * DEPRECATED: use the similarly named predicate from `HostnameRegex` from the `regex` pack instead. - */ - deprecated string getACommonTld() { - // according to ranking by http://google.com/search?q=site:.<> - result = "(?:com|org|edu|gov|uk|net|io)(?![a-z0-9])" - } -} - /** * Gets a node whose value may flow (inter-procedurally) to `re`, where it is interpreted * as a part of a regular expression. diff --git a/javascript/ql/lib/semmle/javascript/security/BadTagFilterQuery.qll b/javascript/ql/lib/semmle/javascript/security/BadTagFilterQuery.qll deleted file mode 100644 index 0bc83143e8ca..000000000000 --- a/javascript/ql/lib/semmle/javascript/security/BadTagFilterQuery.qll +++ /dev/null @@ -1,8 +0,0 @@ -/** - * Provides predicates for reasoning about bad tag filter vulnerabilities. - */ - -private import regexp.RegExpTreeView::RegExpTreeView as TreeView -// BadTagFilterQuery should be used directly from the shared pack, and not from this file. -deprecated private import codeql.regex.nfa.BadTagFilterQuery::Make as Dep -import Dep diff --git a/javascript/ql/lib/semmle/javascript/security/OverlyLargeRangeQuery.qll b/javascript/ql/lib/semmle/javascript/security/OverlyLargeRangeQuery.qll deleted file mode 100644 index 2053afe95f8c..000000000000 --- a/javascript/ql/lib/semmle/javascript/security/OverlyLargeRangeQuery.qll +++ /dev/null @@ -1,8 +0,0 @@ -/** - * Classes and predicates for working with suspicious character ranges. - */ - -private import regexp.RegExpTreeView::RegExpTreeView as TreeView -// OverlyLargeRangeQuery should be used directly from the shared pack, and not from this file. -deprecated private import codeql.regex.OverlyLargeRangeQuery::Make as Dep -import Dep diff --git a/javascript/ql/lib/semmle/javascript/security/regexp/RegexpMatching.qll b/javascript/ql/lib/semmle/javascript/security/regexp/RegexpMatching.qll deleted file mode 100644 index cfc0f4992406..000000000000 --- a/javascript/ql/lib/semmle/javascript/security/regexp/RegexpMatching.qll +++ /dev/null @@ -1,9 +0,0 @@ -/** - * Provides predicates for reasoning about which strings are matched by a regular expression, - * and for testing which capture groups are filled when a particular regexp matches a string. - */ - -private import RegExpTreeView::RegExpTreeView as TreeView -// RegexpMatching should be used directly from the shared pack, and not from this file. -deprecated private import codeql.regex.nfa.RegexpMatching::Make as Dep -import Dep diff --git a/javascript/ql/src/Security/CWE-020/HostnameRegexpShared.qll b/javascript/ql/src/Security/CWE-020/HostnameRegexpShared.qll deleted file mode 100644 index 524be45c6539..000000000000 --- a/javascript/ql/src/Security/CWE-020/HostnameRegexpShared.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Provides predicates for reasoning about regular expressions - * that match URLs and hostname patterns. - */ - -deprecated import semmle.javascript.security.regexp.HostnameRegexp as Dep -import Dep diff --git a/python/ql/lib/semmle/python/dataflow/new/Regexp.qll b/python/ql/lib/semmle/python/dataflow/new/Regexp.qll index e1f824b2935c..1f13b3847d7b 100644 --- a/python/ql/lib/semmle/python/dataflow/new/Regexp.qll +++ b/python/ql/lib/semmle/python/dataflow/new/Regexp.qll @@ -7,20 +7,6 @@ private import semmle.python.regex private import semmle.python.dataflow.new.DataFlow private import semmle.python.regexp.internal.RegExpTracking -/** - * Provides utility predicates related to regular expressions. - */ -deprecated module RegExpPatterns { - /** - * Gets a pattern that matches common top-level domain names in lower case. - * DEPRECATED: use the similarly named predicate from `HostnameRegex` from the `regex` pack instead. - */ - deprecated string getACommonTld() { - // according to ranking by http://google.com/search?q=site:.<> - result = "(?:com|org|edu|gov|uk|net|io)(?![a-z0-9])" - } -} - /** * A node whose value may flow to a position where it is interpreted * as a part of a regular expression. diff --git a/python/ql/src/Security/CWE-020/HostnameRegexpShared.qll b/python/ql/src/Security/CWE-020/HostnameRegexpShared.qll deleted file mode 100644 index d15714d406aa..000000000000 --- a/python/ql/src/Security/CWE-020/HostnameRegexpShared.qll +++ /dev/null @@ -1,8 +0,0 @@ -/** - * Provides predicates for reasoning about regular expressions - * that match URLs and hostname patterns. - */ - -// HostnameRegexp should be used directly from the shared regex pack, and not from this file. -deprecated private import semmle.python.security.regexp.HostnameRegex as Dep -import Dep diff --git a/ruby/ql/lib/codeql/ruby/Regexp.qll b/ruby/ql/lib/codeql/ruby/Regexp.qll index 1abcee8d2d16..41d01707fb1f 100644 --- a/ruby/ql/lib/codeql/ruby/Regexp.qll +++ b/ruby/ql/lib/codeql/ruby/Regexp.qll @@ -14,20 +14,6 @@ private import codeql.ruby.DataFlow private import codeql.ruby.ApiGraphs private import codeql.ruby.Concepts -/** - * Provides utility predicates related to regular expressions. - */ -deprecated module RegExpPatterns { - /** - * Gets a pattern that matches common top-level domain names in lower case. - * DEPRECATED: use the similarly named predicate from `HostnameRegex` from the `regex` pack instead. - */ - deprecated string getACommonTld() { - // according to ranking by http://google.com/search?q=site:.<> - result = "(?:com|org|edu|gov|uk|net|io)(?![a-z0-9])" - } -} - /** * A node whose value may flow to a position where it is interpreted * as a part of a regular expression. diff --git a/ruby/ql/src/queries/security/cwe-020/HostnameRegexpShared.qll b/ruby/ql/src/queries/security/cwe-020/HostnameRegexpShared.qll deleted file mode 100644 index dc3ed9aeaf77..000000000000 --- a/ruby/ql/src/queries/security/cwe-020/HostnameRegexpShared.qll +++ /dev/null @@ -1,8 +0,0 @@ -/** - * Provides predicates for reasoning about regular expressions - * that match URLs and hostname patterns. - */ - -// HostnameRegexp should be used directly from the shared regex pack, and not from this file. -deprecated import codeql.ruby.security.regexp.HostnameRegexp as Dep -import Dep From fb376a1cfdd8a502d97273062616fd8408cb8264 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Thu, 25 Apr 2024 22:31:11 +0200 Subject: [PATCH 053/238] revert the deletion of explorationLimit. It'll be deleted along with the entire class later --- .../semmle/code/java/dataflow/internal/DataFlowImpl1.qll | 8 ++++++++ .../semmle/code/java/dataflow/internal/DataFlowImpl2.qll | 8 ++++++++ .../semmle/code/java/dataflow/internal/DataFlowImpl3.qll | 8 ++++++++ .../semmle/code/java/dataflow/internal/DataFlowImpl4.qll | 8 ++++++++ .../semmle/code/java/dataflow/internal/DataFlowImpl5.qll | 8 ++++++++ .../semmle/code/java/dataflow/internal/DataFlowImpl6.qll | 8 ++++++++ 6 files changed, 48 insertions(+) diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl1.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl1.qll index 04b058c75653..c3ba9fb0014c 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl1.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl1.qll @@ -168,6 +168,14 @@ abstract deprecated class Configuration extends string { */ predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } + /** + * DEPRECATED: Use `FlowExploration` instead. + * + * Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev` + * measured in approximate number of interprocedural steps. + */ + deprecated int explorationLimit() { none() } + /** * Holds if hidden nodes should be included in the data flow graph. * diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll index 04b058c75653..c3ba9fb0014c 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll @@ -168,6 +168,14 @@ abstract deprecated class Configuration extends string { */ predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } + /** + * DEPRECATED: Use `FlowExploration` instead. + * + * Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev` + * measured in approximate number of interprocedural steps. + */ + deprecated int explorationLimit() { none() } + /** * Holds if hidden nodes should be included in the data flow graph. * diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll index 04b058c75653..c3ba9fb0014c 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll @@ -168,6 +168,14 @@ abstract deprecated class Configuration extends string { */ predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } + /** + * DEPRECATED: Use `FlowExploration` instead. + * + * Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev` + * measured in approximate number of interprocedural steps. + */ + deprecated int explorationLimit() { none() } + /** * Holds if hidden nodes should be included in the data flow graph. * diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll index 04b058c75653..c3ba9fb0014c 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll @@ -168,6 +168,14 @@ abstract deprecated class Configuration extends string { */ predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } + /** + * DEPRECATED: Use `FlowExploration` instead. + * + * Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev` + * measured in approximate number of interprocedural steps. + */ + deprecated int explorationLimit() { none() } + /** * Holds if hidden nodes should be included in the data flow graph. * diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll index 04b058c75653..c3ba9fb0014c 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll @@ -168,6 +168,14 @@ abstract deprecated class Configuration extends string { */ predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } + /** + * DEPRECATED: Use `FlowExploration` instead. + * + * Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev` + * measured in approximate number of interprocedural steps. + */ + deprecated int explorationLimit() { none() } + /** * Holds if hidden nodes should be included in the data flow graph. * diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll index 04b058c75653..c3ba9fb0014c 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll @@ -168,6 +168,14 @@ abstract deprecated class Configuration extends string { */ predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } + /** + * DEPRECATED: Use `FlowExploration` instead. + * + * Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev` + * measured in approximate number of interprocedural steps. + */ + deprecated int explorationLimit() { none() } + /** * Holds if hidden nodes should be included in the data flow graph. * From d7c784ef2f31bb39cc9418d984bd42c03bb1fb25 Mon Sep 17 00:00:00 2001 From: Mario Campos Date: Thu, 25 Apr 2024 16:29:37 -0500 Subject: [PATCH 054/238] Initial commit of experimental query cpp/guarded-free. --- .../Best Practices/GuardedFree.cpp | 11 +++++ .../Best Practices/GuardedFree.qhelp | 18 +++++++ .../Best Practices/GuardedFree.ql | 48 +++++++++++++++++++ 3 files changed, 77 insertions(+) create mode 100644 cpp/ql/src/experimental/Best Practices/GuardedFree.cpp create mode 100644 cpp/ql/src/experimental/Best Practices/GuardedFree.qhelp create mode 100644 cpp/ql/src/experimental/Best Practices/GuardedFree.ql diff --git a/cpp/ql/src/experimental/Best Practices/GuardedFree.cpp b/cpp/ql/src/experimental/Best Practices/GuardedFree.cpp new file mode 100644 index 000000000000..5242e3da8f5e --- /dev/null +++ b/cpp/ql/src/experimental/Best Practices/GuardedFree.cpp @@ -0,0 +1,11 @@ +void test() +{ + char *foo = malloc(100); + + // BAD + if (foo) + free(foo); + + // GOOD + free(foo); +} \ No newline at end of file diff --git a/cpp/ql/src/experimental/Best Practices/GuardedFree.qhelp b/cpp/ql/src/experimental/Best Practices/GuardedFree.qhelp new file mode 100644 index 000000000000..77fdd4670008 --- /dev/null +++ b/cpp/ql/src/experimental/Best Practices/GuardedFree.qhelp @@ -0,0 +1,18 @@ + + + +

The free function, which deallocates heap memory, may accept a NULL pointer and take no action. Therefore, it is unnecessary to check its argument for the value of NULL before a function call to free. As such, these guards may hinder performance and readability.

+
+ +

A function call to free should not depend upon the value of its argument. Delete the if condition preceeding a function call to free when its only purpose is to check the value of the pointer to be freed.

+
+ + + + +
  • + The Open Group Base Specifications Issue 7, 2018 Edition: + free - free allocated memory +
  • +
    +
    \ No newline at end of file diff --git a/cpp/ql/src/experimental/Best Practices/GuardedFree.ql b/cpp/ql/src/experimental/Best Practices/GuardedFree.ql new file mode 100644 index 000000000000..ec8f39c491d7 --- /dev/null +++ b/cpp/ql/src/experimental/Best Practices/GuardedFree.ql @@ -0,0 +1,48 @@ +/** + * @name Guarded Free + * @description NULL-condition guards before function calls to the memory-deallocation + * function free(3) are unnecessary, because passing NULL to free(3) is a no-op. + * @kind problem + * @problem.severity recommendation + * @precision very-high + * @id cpp/guarded-free + * @tags maintainability + * readability + * experimental + */ + +import cpp + +class FreeCall extends FunctionCall { + FreeCall() { this.getTarget().hasName("free") } +} + +from IfStmt stmt, FreeCall fc, Variable v +where + stmt.getThen() = fc.getEnclosingStmt() and + ( + stmt.getCondition() = v.getAnAccess() and + fc.getArgument(0) = v.getAnAccess() + or + exists(PointerDereferenceExpr cond, PointerDereferenceExpr arg | + fc.getArgument(0) = arg and + stmt.getCondition() = cond and + cond.getOperand+() = v.getAnAccess() and + arg.getOperand+() = v.getAnAccess() + ) + or + exists(ArrayExpr cond, ArrayExpr arg | + fc.getArgument(0) = arg and + stmt.getCondition() = cond and + cond.getArrayBase+() = v.getAnAccess() and + arg.getArrayBase+() = v.getAnAccess() + ) + or + exists(NEExpr eq | + fc.getArgument(0) = v.getAnAccess() and + stmt.getCondition() = eq and + eq.getAnOperand() = v.getAnAccess() and + eq.getAnOperand().getValue() = "0" + ) + ) +select stmt, "unnecessary NULL check before call to $@", fc, "free" From e55f2c53092e4972f7020375e97c6dc9ee08fba8 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Fri, 26 Apr 2024 06:52:57 +0200 Subject: [PATCH 055/238] reinroduce `GLobalValueNumbering.qll`, that one was supposed to stay --- .../lib/semmle/code/cpp/valuenumbering/GlobalValueNumbering.qll | 1 + 1 file changed, 1 insertion(+) create mode 100644 cpp/ql/lib/semmle/code/cpp/valuenumbering/GlobalValueNumbering.qll diff --git a/cpp/ql/lib/semmle/code/cpp/valuenumbering/GlobalValueNumbering.qll b/cpp/ql/lib/semmle/code/cpp/valuenumbering/GlobalValueNumbering.qll new file mode 100644 index 000000000000..cb28edc07b99 --- /dev/null +++ b/cpp/ql/lib/semmle/code/cpp/valuenumbering/GlobalValueNumbering.qll @@ -0,0 +1 @@ +import semmle.code.cpp.ir.internal.ASTValueNumbering From 0468c5d0bf1f00d18aac583f9b293114380f2e55 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Fri, 26 Apr 2024 07:58:35 +0200 Subject: [PATCH 056/238] delete some tests of the old GVN library --- .../GlobalValueNumbering/ast_gvn.expected | 41 ------ .../GlobalValueNumbering/ast_gvn.ql | 11 -- .../ast_uniqueness.expected | 3 - .../GlobalValueNumbering/ast_uniqueness.ql | 8 -- .../diff_ir_expr.expected | 130 ------------------ .../GlobalValueNumbering/diff_ir_expr.ql | 15 -- 6 files changed, 208 deletions(-) delete mode 100644 cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_gvn.expected delete mode 100644 cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_gvn.ql delete mode 100644 cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_uniqueness.expected delete mode 100644 cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_uniqueness.ql delete mode 100644 cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/diff_ir_expr.expected delete mode 100644 cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/diff_ir_expr.ql diff --git a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_gvn.expected b/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_gvn.expected deleted file mode 100644 index 69c21b5e0b1d..000000000000 --- a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_gvn.expected +++ /dev/null @@ -1,41 +0,0 @@ -WARNING: Type GVN has been deprecated and may be removed in future (ast_gvn.ql:4,6-9) -| test.cpp:5:3:5:3 | x | 5:c3-c3 6:c3-c3 | -| test.cpp:5:7:5:8 | p0 | 5:c7-c8 6:c7-c8 | -| test.cpp:5:7:5:13 | ... + ... | 5:c7-c13 6:c7-c13 7:c7-c7 | -| test.cpp:5:12:5:13 | p1 | 5:c12-c13 6:c12-c13 | -| test.cpp:16:3:16:3 | x | 16:c3-c3 17:c3-c3 | -| test.cpp:16:7:16:8 | p0 | 16:c7-c8 17:c7-c8 | -| test.cpp:16:7:16:13 | ... + ... | 16:c7-c13 17:c7-c13 | -| test.cpp:16:7:16:24 | ... + ... | 16:c7-c24 17:c7-c24 18:c7-c7 | -| test.cpp:16:12:16:13 | p1 | 16:c12-c13 17:c12-c13 | -| test.cpp:16:17:16:24 | global01 | 16:c17-c24 17:c17-c24 | -| test.cpp:29:7:29:8 | p0 | 29:c7-c8 31:c7-c8 | -| test.cpp:29:7:29:13 | ... + ... | 29:c7-c13 31:c7-c13 | -| test.cpp:29:12:29:13 | p1 | 29:c12-c13 31:c12-c13 | -| test.cpp:31:7:31:24 | ... + ... | 31:c7-c24 32:c7-c7 | -| test.cpp:43:7:43:8 | p0 | 43:c7-c8 45:c7-c8 | -| test.cpp:43:7:43:13 | ... + ... | 43:c7-c13 45:c7-c13 | -| test.cpp:43:12:43:13 | p1 | 43:c12-c13 45:c12-c13 | -| test.cpp:44:9:44:9 | 0 | 44:c9-c9 51:c25-c25 53:c18-c21 56:c39-c42 59:c17-c20 88:c12-c12 | -| test.cpp:45:7:45:24 | ... + ... | 45:c7-c24 46:c7-c7 | -| test.cpp:53:10:53:13 | (int)... | 53:c10-c13 56:c21-c24 | -| test.cpp:53:10:53:13 | * ... | 53:c10-c13 56:c21-c24 | -| test.cpp:53:11:53:13 | str | 53:c11-c13 56:c22-c24 | -| test.cpp:53:18:53:21 | 0 | 53:c18-c21 56:c39-c42 59:c17-c20 | -| test.cpp:56:13:56:16 | (int)... | 56:c13-c16 56:c31-c34 59:c9-c12 | -| test.cpp:56:13:56:16 | * ... | 56:c13-c16 56:c31-c34 59:c9-c12 | -| test.cpp:56:14:56:16 | ptr | 56:c14-c16 56:c32-c34 56:c47-c49 59:c10-c12 | -| test.cpp:62:5:62:10 | result | 62:c5-c10 65:c10-c15 | -| test.cpp:77:20:77:30 | (signed short)... | 77:c20-c30 79:c7-c7 | -| test.cpp:79:11:79:14 | vals | 79:c11-c14 79:c24-c27 | -| test.cpp:105:11:105:12 | (Base *)... | 105:c11-c12 106:c14-c35 107:c11-c12 | -| test.cpp:105:11:105:12 | pd | 105:c11-c12 106:c33-c34 | -| test.cpp:105:15:105:15 | b | 105:c15-c15 107:c15-c15 109:c10-c10 | -| test.cpp:125:11:125:12 | pa | 125:c11-c12 126:c11-c12 128:c3-c4 129:c11-c12 | -| test.cpp:125:15:125:15 | x | 125:c15-c15 126:c15-c15 128:c7-c7 | -| test.cpp:136:11:136:18 | global_a | 136:c11-c18 137:c11-c18 139:c3-c10 | -| test.cpp:136:21:136:21 | x | 136:c21-c21 137:c21-c21 139:c13-c13 | -| test.cpp:144:11:144:12 | pa | 144:c11-c12 145:c11-c12 147:c3-c4 149:c11-c12 | -| test.cpp:145:15:145:15 | y | 145:c15-c15 147:c7-c7 | -| test.cpp:153:11:153:18 | global_a | 153:c11-c18 154:c11-c18 156:c3-c10 | -| test.cpp:153:21:153:21 | x | 153:c21-c21 154:c21-c21 | diff --git a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_gvn.ql b/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_gvn.ql deleted file mode 100644 index 84d0a7b3672d..000000000000 --- a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_gvn.ql +++ /dev/null @@ -1,11 +0,0 @@ -import cpp -import semmle.code.cpp.valuenumbering.GlobalValueNumberingImpl - -from GVN g -where strictcount(g.getAnExpr()) > 1 -select g, - strictconcat(Location loc | - loc = g.getAnExpr().getLocation() - | - loc.getStartLine() + ":c" + loc.getStartColumn() + "-c" + loc.getEndColumn(), " " - ) diff --git a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_uniqueness.expected b/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_uniqueness.expected deleted file mode 100644 index d94d58ad5eac..000000000000 --- a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_uniqueness.expected +++ /dev/null @@ -1,3 +0,0 @@ -WARNING: Predicate globalValueNumber has been deprecated and may be removed in future (ast_uniqueness.ql:7,13-30) -WARNING: Predicate globalValueNumber has been deprecated and may be removed in future (ast_uniqueness.ql:8,30-47) -WARNING: Type GVN has been deprecated and may be removed in future (ast_uniqueness.ql:8,18-21) diff --git a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_uniqueness.ql b/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_uniqueness.ql deleted file mode 100644 index bc6dbf94bf7c..000000000000 --- a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_uniqueness.ql +++ /dev/null @@ -1,8 +0,0 @@ -import cpp -import semmle.code.cpp.valuenumbering.GlobalValueNumberingImpl - -// Every expression should have exactly one GVN. -// So this query should have zero results. -from Expr e -where count(globalValueNumber(e)) != 1 -select e, concat(GVN g | g = globalValueNumber(e) | g.getKind(), ", ") diff --git a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/diff_ir_expr.expected b/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/diff_ir_expr.expected deleted file mode 100644 index 810c83f197f9..000000000000 --- a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/diff_ir_expr.expected +++ /dev/null @@ -1,130 +0,0 @@ -WARNING: Predicate globalValueNumber has been deprecated and may be removed in future (diff_ir_expr.ql:8,29-51) -| test.cpp:5:3:5:13 | ... = ... | test.cpp:5:3:5:13 | ... = ... | AST only | -| test.cpp:6:3:6:13 | ... = ... | test.cpp:6:3:6:13 | ... = ... | AST only | -| test.cpp:7:3:7:7 | ... = ... | test.cpp:7:3:7:7 | ... = ... | AST only | -| test.cpp:16:3:16:24 | ... = ... | test.cpp:16:3:16:24 | ... = ... | AST only | -| test.cpp:17:3:17:24 | ... = ... | test.cpp:17:3:17:24 | ... = ... | AST only | -| test.cpp:18:3:18:7 | ... = ... | test.cpp:18:3:18:7 | ... = ... | AST only | -| test.cpp:29:3:29:3 | x | test.cpp:31:3:31:3 | x | IR only | -| test.cpp:29:3:29:24 | ... = ... | test.cpp:29:3:29:24 | ... = ... | AST only | -| test.cpp:30:3:30:17 | call to change_global02 | test.cpp:30:3:30:17 | call to change_global02 | AST only | -| test.cpp:31:3:31:3 | x | test.cpp:29:3:29:3 | x | IR only | -| test.cpp:31:3:31:24 | ... = ... | test.cpp:31:3:31:24 | ... = ... | AST only | -| test.cpp:32:3:32:7 | ... = ... | test.cpp:32:3:32:7 | ... = ... | AST only | -| test.cpp:43:3:43:3 | x | test.cpp:45:3:45:3 | x | IR only | -| test.cpp:43:3:43:24 | ... = ... | test.cpp:43:3:43:24 | ... = ... | AST only | -| test.cpp:43:7:43:24 | ... + ... | test.cpp:45:7:45:24 | ... + ... | IR only | -| test.cpp:43:7:43:24 | ... + ... | test.cpp:46:7:46:7 | x | IR only | -| test.cpp:43:17:43:24 | global03 | test.cpp:45:17:45:24 | global03 | IR only | -| test.cpp:44:3:44:5 | * ... | test.cpp:44:4:44:5 | p2 | IR only | -| test.cpp:44:3:44:9 | ... = ... | test.cpp:44:3:44:9 | ... = ... | AST only | -| test.cpp:44:4:44:5 | p2 | test.cpp:44:3:44:5 | * ... | IR only | -| test.cpp:44:9:44:9 | 0 | test.cpp:51:25:51:25 | 0 | AST only | -| test.cpp:44:9:44:9 | 0 | test.cpp:53:18:53:21 | (int)... | AST only | -| test.cpp:44:9:44:9 | 0 | test.cpp:56:39:56:42 | (int)... | AST only | -| test.cpp:44:9:44:9 | 0 | test.cpp:59:17:59:20 | (int)... | AST only | -| test.cpp:44:9:44:9 | 0 | test.cpp:88:12:88:12 | 0 | AST only | -| test.cpp:45:3:45:3 | x | test.cpp:43:3:43:3 | x | IR only | -| test.cpp:45:3:45:24 | ... = ... | test.cpp:45:3:45:24 | ... = ... | AST only | -| test.cpp:45:7:45:24 | ... + ... | test.cpp:43:7:43:24 | ... + ... | IR only | -| test.cpp:45:17:45:24 | global03 | test.cpp:43:17:43:24 | global03 | IR only | -| test.cpp:46:3:46:7 | ... = ... | test.cpp:46:3:46:7 | ... = ... | AST only | -| test.cpp:46:7:46:7 | x | test.cpp:43:7:43:24 | ... + ... | IR only | -| test.cpp:51:25:51:25 | 0 | test.cpp:44:9:44:9 | 0 | AST only | -| test.cpp:51:25:51:25 | 0 | test.cpp:53:18:53:21 | (int)... | AST only | -| test.cpp:51:25:51:25 | 0 | test.cpp:56:39:56:42 | (int)... | AST only | -| test.cpp:51:25:51:25 | 0 | test.cpp:59:17:59:20 | (int)... | AST only | -| test.cpp:51:25:51:25 | 0 | test.cpp:88:12:88:12 | 0 | AST only | -| test.cpp:51:25:51:25 | (unsigned int)... | test.cpp:51:25:51:25 | (unsigned int)... | AST only | -| test.cpp:53:10:53:13 | (int)... | test.cpp:53:10:53:13 | (int)... | AST only | -| test.cpp:53:10:53:13 | (int)... | test.cpp:56:21:56:24 | (int)... | AST only | -| test.cpp:53:18:53:21 | (int)... | test.cpp:44:9:44:9 | 0 | AST only | -| test.cpp:53:18:53:21 | (int)... | test.cpp:51:25:51:25 | 0 | AST only | -| test.cpp:53:18:53:21 | (int)... | test.cpp:53:18:53:21 | (int)... | AST only | -| test.cpp:53:18:53:21 | (int)... | test.cpp:56:39:56:42 | (int)... | AST only | -| test.cpp:53:18:53:21 | (int)... | test.cpp:59:17:59:20 | (int)... | AST only | -| test.cpp:53:18:53:21 | (int)... | test.cpp:88:12:88:12 | 0 | AST only | -| test.cpp:55:5:55:15 | ... = ... | test.cpp:55:5:55:15 | ... = ... | AST only | -| test.cpp:56:12:56:25 | (...) | test.cpp:56:12:56:25 | (...) | AST only | -| test.cpp:56:12:56:43 | ... && ... | test.cpp:56:12:56:43 | ... && ... | AST only | -| test.cpp:56:13:56:16 | (int)... | test.cpp:56:13:56:16 | (int)... | AST only | -| test.cpp:56:13:56:16 | (int)... | test.cpp:56:31:56:34 | (int)... | AST only | -| test.cpp:56:13:56:16 | (int)... | test.cpp:59:9:59:12 | (int)... | AST only | -| test.cpp:56:21:56:24 | (int)... | test.cpp:53:10:53:13 | (int)... | AST only | -| test.cpp:56:21:56:24 | (int)... | test.cpp:56:21:56:24 | (int)... | AST only | -| test.cpp:56:30:56:43 | (...) | test.cpp:56:30:56:43 | (...) | AST only | -| test.cpp:56:31:56:34 | (int)... | test.cpp:56:13:56:16 | (int)... | AST only | -| test.cpp:56:31:56:34 | (int)... | test.cpp:56:31:56:34 | (int)... | AST only | -| test.cpp:56:31:56:34 | (int)... | test.cpp:59:9:59:12 | (int)... | AST only | -| test.cpp:56:39:56:42 | (int)... | test.cpp:44:9:44:9 | 0 | AST only | -| test.cpp:56:39:56:42 | (int)... | test.cpp:51:25:51:25 | 0 | AST only | -| test.cpp:56:39:56:42 | (int)... | test.cpp:53:18:53:21 | (int)... | AST only | -| test.cpp:56:39:56:42 | (int)... | test.cpp:56:39:56:42 | (int)... | AST only | -| test.cpp:56:39:56:42 | (int)... | test.cpp:59:17:59:20 | (int)... | AST only | -| test.cpp:56:39:56:42 | (int)... | test.cpp:88:12:88:12 | 0 | AST only | -| test.cpp:56:47:56:51 | ... ++ | test.cpp:56:47:56:51 | ... ++ | AST only | -| test.cpp:59:9:59:12 | (int)... | test.cpp:56:13:56:16 | (int)... | AST only | -| test.cpp:59:9:59:12 | (int)... | test.cpp:56:31:56:34 | (int)... | AST only | -| test.cpp:59:9:59:12 | (int)... | test.cpp:59:9:59:12 | (int)... | AST only | -| test.cpp:59:17:59:20 | (int)... | test.cpp:44:9:44:9 | 0 | AST only | -| test.cpp:59:17:59:20 | (int)... | test.cpp:51:25:51:25 | 0 | AST only | -| test.cpp:59:17:59:20 | (int)... | test.cpp:53:18:53:21 | (int)... | AST only | -| test.cpp:59:17:59:20 | (int)... | test.cpp:56:39:56:42 | (int)... | AST only | -| test.cpp:59:17:59:20 | (int)... | test.cpp:59:17:59:20 | (int)... | AST only | -| test.cpp:59:17:59:20 | (int)... | test.cpp:88:12:88:12 | 0 | AST only | -| test.cpp:62:5:62:12 | ... ++ | test.cpp:62:5:62:12 | ... ++ | AST only | -| test.cpp:77:20:77:28 | call to getAValue | test.cpp:79:7:79:7 | v | IR only | -| test.cpp:77:20:77:30 | (signed short)... | test.cpp:77:20:77:30 | (signed short)... | AST only | -| test.cpp:77:20:77:30 | (signed short)... | test.cpp:79:7:79:7 | v | AST only | -| test.cpp:79:7:79:7 | (int)... | test.cpp:79:7:79:7 | (int)... | AST only | -| test.cpp:79:7:79:7 | v | test.cpp:77:20:77:28 | call to getAValue | IR only | -| test.cpp:79:7:79:7 | v | test.cpp:77:20:77:30 | (signed short)... | AST only | -| test.cpp:79:11:79:20 | (int)... | test.cpp:79:11:79:20 | (int)... | AST only | -| test.cpp:79:24:79:33 | (int)... | test.cpp:79:24:79:33 | (int)... | AST only | -| test.cpp:80:5:80:19 | ... = ... | test.cpp:80:5:80:19 | ... = ... | AST only | -| test.cpp:80:9:80:19 | (signed short)... | test.cpp:80:9:80:19 | (signed short)... | AST only | -| test.cpp:88:3:88:20 | ... = ... | test.cpp:88:3:88:20 | ... = ... | AST only | -| test.cpp:88:12:88:12 | 0 | test.cpp:44:9:44:9 | 0 | AST only | -| test.cpp:88:12:88:12 | 0 | test.cpp:51:25:51:25 | 0 | AST only | -| test.cpp:88:12:88:12 | 0 | test.cpp:53:18:53:21 | (int)... | AST only | -| test.cpp:88:12:88:12 | 0 | test.cpp:56:39:56:42 | (int)... | AST only | -| test.cpp:88:12:88:12 | 0 | test.cpp:59:17:59:20 | (int)... | AST only | -| test.cpp:88:12:88:12 | (void *)... | test.cpp:88:12:88:12 | (void *)... | AST only | -| test.cpp:92:11:92:16 | ... = ... | test.cpp:92:15:92:16 | 10 | IR only | -| test.cpp:92:11:92:16 | ... = ... | test.cpp:93:10:93:10 | x | IR only | -| test.cpp:92:15:92:16 | 10 | test.cpp:92:11:92:16 | ... = ... | IR only | -| test.cpp:92:15:92:16 | 10 | test.cpp:93:10:93:10 | x | IR only | -| test.cpp:93:10:93:10 | x | test.cpp:92:11:92:16 | ... = ... | IR only | -| test.cpp:93:10:93:10 | x | test.cpp:92:15:92:16 | 10 | IR only | -| test.cpp:105:11:105:12 | (Base *)... | test.cpp:105:11:105:12 | (Base *)... | AST only | -| test.cpp:105:11:105:12 | (Base *)... | test.cpp:106:14:106:35 | static_cast... | AST only | -| test.cpp:105:11:105:12 | (Base *)... | test.cpp:107:11:107:12 | pb | AST only | -| test.cpp:105:11:105:12 | pd | test.cpp:107:11:107:12 | pb | IR only | -| test.cpp:106:14:106:35 | static_cast... | test.cpp:105:11:105:12 | (Base *)... | AST only | -| test.cpp:106:14:106:35 | static_cast... | test.cpp:106:14:106:35 | static_cast... | AST only | -| test.cpp:106:14:106:35 | static_cast... | test.cpp:107:11:107:12 | pb | AST only | -| test.cpp:106:33:106:34 | pd | test.cpp:107:11:107:12 | pb | IR only | -| test.cpp:107:11:107:12 | pb | test.cpp:105:11:105:12 | (Base *)... | AST only | -| test.cpp:107:11:107:12 | pb | test.cpp:105:11:105:12 | pd | IR only | -| test.cpp:107:11:107:12 | pb | test.cpp:106:14:106:35 | static_cast... | AST only | -| test.cpp:107:11:107:12 | pb | test.cpp:106:33:106:34 | pd | IR only | -| test.cpp:113:3:113:5 | a | test.cpp:115:3:115:5 | a | IR only | -| test.cpp:115:3:115:5 | a | test.cpp:113:3:113:5 | a | IR only | -| test.cpp:125:15:125:15 | x | test.cpp:128:7:128:7 | x | AST only | -| test.cpp:126:15:126:15 | x | test.cpp:128:7:128:7 | x | AST only | -| test.cpp:128:3:128:11 | ... = ... | test.cpp:128:3:128:11 | ... = ... | AST only | -| test.cpp:128:7:128:7 | x | test.cpp:125:15:125:15 | x | AST only | -| test.cpp:128:7:128:7 | x | test.cpp:126:15:126:15 | x | AST only | -| test.cpp:128:11:128:11 | n | test.cpp:129:15:129:15 | x | IR only | -| test.cpp:129:15:129:15 | x | test.cpp:128:11:128:11 | n | IR only | -| test.cpp:136:21:136:21 | x | test.cpp:139:13:139:13 | x | AST only | -| test.cpp:137:21:137:21 | x | test.cpp:139:13:139:13 | x | AST only | -| test.cpp:139:3:139:24 | ... = ... | test.cpp:139:3:139:24 | ... = ... | AST only | -| test.cpp:139:13:139:13 | x | test.cpp:136:21:136:21 | x | AST only | -| test.cpp:139:13:139:13 | x | test.cpp:137:21:137:21 | x | AST only | -| test.cpp:144:15:144:15 | x | test.cpp:149:15:149:15 | x | IR only | -| test.cpp:145:15:145:15 | y | test.cpp:147:7:147:7 | y | AST only | -| test.cpp:147:3:147:18 | ... = ... | test.cpp:147:3:147:18 | ... = ... | AST only | -| test.cpp:147:7:147:7 | y | test.cpp:145:15:145:15 | y | AST only | -| test.cpp:149:15:149:15 | x | test.cpp:144:15:144:15 | x | IR only | -| test.cpp:156:3:156:17 | ... = ... | test.cpp:156:3:156:17 | ... = ... | AST only | diff --git a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/diff_ir_expr.ql b/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/diff_ir_expr.ql deleted file mode 100644 index 7b897f39dbd9..000000000000 --- a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/diff_ir_expr.ql +++ /dev/null @@ -1,15 +0,0 @@ -import cpp -import semmle.code.cpp.valuenumbering.GlobalValueNumberingImpl as AST -import semmle.code.cpp.ir.internal.ASTValueNumbering as IR -import semmle.code.cpp.ir.IR - -Expr ir(Expr e) { result = IR::globalValueNumber(e).getAnExpr() } - -Expr ast(Expr e) { result = AST::globalValueNumber(e).getAnExpr() } - -from Expr e, Expr evn, string note -where - evn = ast(e) and not evn = ir(e) and note = "AST only" - or - evn = ir(e) and not evn = ast(e) and note = "IR only" -select e, evn, note From 7d9a68bf173511af23c94bbd04560c42a123dc09 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 26 Apr 2024 11:19:22 +0200 Subject: [PATCH 057/238] Go: wrap gazelle to regenerate from scratch and add header --- go/extractor/autobuilder/BUILD.bazel | 2 ++ go/extractor/cli/go-autobuilder/BUILD.bazel | 2 ++ go/extractor/cli/go-bootstrap/BUILD.bazel | 2 ++ go/extractor/cli/go-build-runner/BUILD.bazel | 2 ++ go/extractor/cli/go-extractor/BUILD.bazel | 2 ++ go/extractor/cli/go-gen-dbscheme/BUILD.bazel | 2 ++ go/extractor/cli/go-tokenizer/BUILD.bazel | 2 ++ go/extractor/dbscheme/BUILD.bazel | 2 ++ go/extractor/diagnostics/BUILD.bazel | 2 ++ go/extractor/project/BUILD.bazel | 2 ++ go/extractor/srcarchive/BUILD.bazel | 2 ++ go/extractor/toolchain/BUILD.bazel | 2 ++ go/extractor/trap/BUILD.bazel | 2 ++ go/extractor/util/BUILD.bazel | 2 ++ .../x/mod/internal/lazyregexp/BUILD.bazel | 2 ++ .../vendor/golang.org/x/mod/modfile/BUILD.bazel | 2 ++ .../vendor/golang.org/x/mod/module/BUILD.bazel | 2 ++ .../vendor/golang.org/x/mod/semver/BUILD.bazel | 2 ++ .../x/tools/go/gcexportdata/BUILD.bazel | 2 ++ .../tools/go/internal/packagesdriver/BUILD.bazel | 2 ++ .../golang.org/x/tools/go/packages/BUILD.bazel | 2 ++ .../x/tools/go/types/objectpath/BUILD.bazel | 2 ++ .../x/tools/internal/event/BUILD.bazel | 2 ++ .../x/tools/internal/event/core/BUILD.bazel | 2 ++ .../x/tools/internal/event/keys/BUILD.bazel | 2 ++ .../x/tools/internal/event/label/BUILD.bazel | 2 ++ .../x/tools/internal/event/tag/BUILD.bazel | 2 ++ .../x/tools/internal/gcimporter/BUILD.bazel | 2 ++ .../x/tools/internal/gocommand/BUILD.bazel | 2 ++ .../tools/internal/packagesinternal/BUILD.bazel | 2 ++ .../x/tools/internal/pkgbits/BUILD.bazel | 2 ++ .../x/tools/internal/tokeninternal/BUILD.bazel | 2 ++ .../x/tools/internal/typeparams/BUILD.bazel | 2 ++ .../x/tools/internal/typesinternal/BUILD.bazel | 2 ++ .../x/tools/internal/versions/BUILD.bazel | 2 ++ go/gazelle/BUILD.bazel | 11 ++++++++--- go/gazelle/gazelle.py | 16 ++++++++++++++++ 37 files changed, 94 insertions(+), 3 deletions(-) create mode 100644 go/gazelle/gazelle.py diff --git a/go/extractor/autobuilder/BUILD.bazel b/go/extractor/autobuilder/BUILD.bazel index b81b15816aa8..e40dc3a03215 100644 --- a/go/extractor/autobuilder/BUILD.bazel +++ b/go/extractor/autobuilder/BUILD.bazel @@ -1,3 +1,5 @@ +# generated running `bazel run //go/gazelle`, do not edit + load("@rules_go//go:def.bzl", "go_library", "go_test") go_library( diff --git a/go/extractor/cli/go-autobuilder/BUILD.bazel b/go/extractor/cli/go-autobuilder/BUILD.bazel index bf1235b33aa0..7abf4600d946 100644 --- a/go/extractor/cli/go-autobuilder/BUILD.bazel +++ b/go/extractor/cli/go-autobuilder/BUILD.bazel @@ -1,3 +1,5 @@ +# generated running `bazel run //go/gazelle`, do not edit + load("@rules_go//go:def.bzl", "go_library") load("//go:rules.bzl", "codeql_go_binary") diff --git a/go/extractor/cli/go-bootstrap/BUILD.bazel b/go/extractor/cli/go-bootstrap/BUILD.bazel index 7bdd6d6e70f9..86b08dfa1210 100644 --- a/go/extractor/cli/go-bootstrap/BUILD.bazel +++ b/go/extractor/cli/go-bootstrap/BUILD.bazel @@ -1,3 +1,5 @@ +# generated running `bazel run //go/gazelle`, do not edit + load("@rules_go//go:def.bzl", "go_library") load("//go:rules.bzl", "codeql_go_binary") diff --git a/go/extractor/cli/go-build-runner/BUILD.bazel b/go/extractor/cli/go-build-runner/BUILD.bazel index 15557d751cf4..e91c45306106 100644 --- a/go/extractor/cli/go-build-runner/BUILD.bazel +++ b/go/extractor/cli/go-build-runner/BUILD.bazel @@ -1,3 +1,5 @@ +# generated running `bazel run //go/gazelle`, do not edit + load("@rules_go//go:def.bzl", "go_library") load("//go:rules.bzl", "codeql_go_binary") diff --git a/go/extractor/cli/go-extractor/BUILD.bazel b/go/extractor/cli/go-extractor/BUILD.bazel index be426331868c..769e4a7b09bc 100644 --- a/go/extractor/cli/go-extractor/BUILD.bazel +++ b/go/extractor/cli/go-extractor/BUILD.bazel @@ -1,3 +1,5 @@ +# generated running `bazel run //go/gazelle`, do not edit + load("@rules_go//go:def.bzl", "go_library") load("//go:rules.bzl", "codeql_go_binary") diff --git a/go/extractor/cli/go-gen-dbscheme/BUILD.bazel b/go/extractor/cli/go-gen-dbscheme/BUILD.bazel index 06c0d0f61f18..9de6d2198f81 100644 --- a/go/extractor/cli/go-gen-dbscheme/BUILD.bazel +++ b/go/extractor/cli/go-gen-dbscheme/BUILD.bazel @@ -1,3 +1,5 @@ +# generated running `bazel run //go/gazelle`, do not edit + load("@rules_go//go:def.bzl", "go_library") load("//go:rules.bzl", "codeql_go_binary") diff --git a/go/extractor/cli/go-tokenizer/BUILD.bazel b/go/extractor/cli/go-tokenizer/BUILD.bazel index 3fc5b464c7c5..8ce0c76be266 100644 --- a/go/extractor/cli/go-tokenizer/BUILD.bazel +++ b/go/extractor/cli/go-tokenizer/BUILD.bazel @@ -1,3 +1,5 @@ +# generated running `bazel run //go/gazelle`, do not edit + load("@rules_go//go:def.bzl", "go_library") load("//go:rules.bzl", "codeql_go_binary") diff --git a/go/extractor/dbscheme/BUILD.bazel b/go/extractor/dbscheme/BUILD.bazel index efaf51684d74..496a5ccdf49d 100644 --- a/go/extractor/dbscheme/BUILD.bazel +++ b/go/extractor/dbscheme/BUILD.bazel @@ -1,3 +1,5 @@ +# generated running `bazel run //go/gazelle`, do not edit + load("@rules_go//go:def.bzl", "go_library") go_library( diff --git a/go/extractor/diagnostics/BUILD.bazel b/go/extractor/diagnostics/BUILD.bazel index 8b218dc1317c..9b0c148db320 100644 --- a/go/extractor/diagnostics/BUILD.bazel +++ b/go/extractor/diagnostics/BUILD.bazel @@ -1,3 +1,5 @@ +# generated running `bazel run //go/gazelle`, do not edit + load("@rules_go//go:def.bzl", "go_library") go_library( diff --git a/go/extractor/project/BUILD.bazel b/go/extractor/project/BUILD.bazel index dd49b3b320f8..0048adf91641 100644 --- a/go/extractor/project/BUILD.bazel +++ b/go/extractor/project/BUILD.bazel @@ -1,3 +1,5 @@ +# generated running `bazel run //go/gazelle`, do not edit + load("@rules_go//go:def.bzl", "go_library", "go_test") go_library( diff --git a/go/extractor/srcarchive/BUILD.bazel b/go/extractor/srcarchive/BUILD.bazel index 90664c90190e..e72e2e7ca08a 100644 --- a/go/extractor/srcarchive/BUILD.bazel +++ b/go/extractor/srcarchive/BUILD.bazel @@ -1,3 +1,5 @@ +# generated running `bazel run //go/gazelle`, do not edit + load("@rules_go//go:def.bzl", "go_library", "go_test") go_library( diff --git a/go/extractor/toolchain/BUILD.bazel b/go/extractor/toolchain/BUILD.bazel index d1ce09c26329..fde8d327e9e2 100644 --- a/go/extractor/toolchain/BUILD.bazel +++ b/go/extractor/toolchain/BUILD.bazel @@ -1,3 +1,5 @@ +# generated running `bazel run //go/gazelle`, do not edit + load("@rules_go//go:def.bzl", "go_library", "go_test") go_library( diff --git a/go/extractor/trap/BUILD.bazel b/go/extractor/trap/BUILD.bazel index 6c3f67b32478..6cc7c4983b2e 100644 --- a/go/extractor/trap/BUILD.bazel +++ b/go/extractor/trap/BUILD.bazel @@ -1,3 +1,5 @@ +# generated running `bazel run //go/gazelle`, do not edit + load("@rules_go//go:def.bzl", "go_library", "go_test") go_library( diff --git a/go/extractor/util/BUILD.bazel b/go/extractor/util/BUILD.bazel index 787a627b5bcc..8b8869cac524 100644 --- a/go/extractor/util/BUILD.bazel +++ b/go/extractor/util/BUILD.bazel @@ -1,3 +1,5 @@ +# generated running `bazel run //go/gazelle`, do not edit + load("@rules_go//go:def.bzl", "go_library", "go_test") go_library( diff --git a/go/extractor/vendor/golang.org/x/mod/internal/lazyregexp/BUILD.bazel b/go/extractor/vendor/golang.org/x/mod/internal/lazyregexp/BUILD.bazel index 33c06c34bec7..deb5dc2b019a 100644 --- a/go/extractor/vendor/golang.org/x/mod/internal/lazyregexp/BUILD.bazel +++ b/go/extractor/vendor/golang.org/x/mod/internal/lazyregexp/BUILD.bazel @@ -1,3 +1,5 @@ +# generated running `bazel run //go/gazelle`, do not edit + load("@rules_go//go:def.bzl", "go_library") go_library( diff --git a/go/extractor/vendor/golang.org/x/mod/modfile/BUILD.bazel b/go/extractor/vendor/golang.org/x/mod/modfile/BUILD.bazel index 7b5a78d785cf..097bacb107ce 100644 --- a/go/extractor/vendor/golang.org/x/mod/modfile/BUILD.bazel +++ b/go/extractor/vendor/golang.org/x/mod/modfile/BUILD.bazel @@ -1,3 +1,5 @@ +# generated running `bazel run //go/gazelle`, do not edit + load("@rules_go//go:def.bzl", "go_library") go_library( diff --git a/go/extractor/vendor/golang.org/x/mod/module/BUILD.bazel b/go/extractor/vendor/golang.org/x/mod/module/BUILD.bazel index 46ff4dbb7d14..3bf5ae9997d1 100644 --- a/go/extractor/vendor/golang.org/x/mod/module/BUILD.bazel +++ b/go/extractor/vendor/golang.org/x/mod/module/BUILD.bazel @@ -1,3 +1,5 @@ +# generated running `bazel run //go/gazelle`, do not edit + load("@rules_go//go:def.bzl", "go_library") go_library( diff --git a/go/extractor/vendor/golang.org/x/mod/semver/BUILD.bazel b/go/extractor/vendor/golang.org/x/mod/semver/BUILD.bazel index 5b54efe19818..760be56c9e08 100644 --- a/go/extractor/vendor/golang.org/x/mod/semver/BUILD.bazel +++ b/go/extractor/vendor/golang.org/x/mod/semver/BUILD.bazel @@ -1,3 +1,5 @@ +# generated running `bazel run //go/gazelle`, do not edit + load("@rules_go//go:def.bzl", "go_library") go_library( diff --git a/go/extractor/vendor/golang.org/x/tools/go/gcexportdata/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/go/gcexportdata/BUILD.bazel index 57f503f1cb23..5d68c2fe989e 100644 --- a/go/extractor/vendor/golang.org/x/tools/go/gcexportdata/BUILD.bazel +++ b/go/extractor/vendor/golang.org/x/tools/go/gcexportdata/BUILD.bazel @@ -1,3 +1,5 @@ +# generated running `bazel run //go/gazelle`, do not edit + load("@rules_go//go:def.bzl", "go_library") go_library( diff --git a/go/extractor/vendor/golang.org/x/tools/go/internal/packagesdriver/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/go/internal/packagesdriver/BUILD.bazel index 962442de1e00..2ef27e2c88af 100644 --- a/go/extractor/vendor/golang.org/x/tools/go/internal/packagesdriver/BUILD.bazel +++ b/go/extractor/vendor/golang.org/x/tools/go/internal/packagesdriver/BUILD.bazel @@ -1,3 +1,5 @@ +# generated running `bazel run //go/gazelle`, do not edit + load("@rules_go//go:def.bzl", "go_library") go_library( diff --git a/go/extractor/vendor/golang.org/x/tools/go/packages/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/go/packages/BUILD.bazel index 1cad8baca98a..03d3e3b01585 100644 --- a/go/extractor/vendor/golang.org/x/tools/go/packages/BUILD.bazel +++ b/go/extractor/vendor/golang.org/x/tools/go/packages/BUILD.bazel @@ -1,3 +1,5 @@ +# generated running `bazel run //go/gazelle`, do not edit + load("@rules_go//go:def.bzl", "go_library") go_library( diff --git a/go/extractor/vendor/golang.org/x/tools/go/types/objectpath/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/go/types/objectpath/BUILD.bazel index 1029221f434c..374c5c601bc8 100644 --- a/go/extractor/vendor/golang.org/x/tools/go/types/objectpath/BUILD.bazel +++ b/go/extractor/vendor/golang.org/x/tools/go/types/objectpath/BUILD.bazel @@ -1,3 +1,5 @@ +# generated running `bazel run //go/gazelle`, do not edit + load("@rules_go//go:def.bzl", "go_library") go_library( diff --git a/go/extractor/vendor/golang.org/x/tools/internal/event/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/internal/event/BUILD.bazel index b882fef0d8cc..200e436fcd4b 100644 --- a/go/extractor/vendor/golang.org/x/tools/internal/event/BUILD.bazel +++ b/go/extractor/vendor/golang.org/x/tools/internal/event/BUILD.bazel @@ -1,3 +1,5 @@ +# generated running `bazel run //go/gazelle`, do not edit + load("@rules_go//go:def.bzl", "go_library") go_library( diff --git a/go/extractor/vendor/golang.org/x/tools/internal/event/core/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/internal/event/core/BUILD.bazel index 36bd68eed9f9..a16713f536ce 100644 --- a/go/extractor/vendor/golang.org/x/tools/internal/event/core/BUILD.bazel +++ b/go/extractor/vendor/golang.org/x/tools/internal/event/core/BUILD.bazel @@ -1,3 +1,5 @@ +# generated running `bazel run //go/gazelle`, do not edit + load("@rules_go//go:def.bzl", "go_library") go_library( diff --git a/go/extractor/vendor/golang.org/x/tools/internal/event/keys/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/internal/event/keys/BUILD.bazel index f1674735052e..1feefdf1a834 100644 --- a/go/extractor/vendor/golang.org/x/tools/internal/event/keys/BUILD.bazel +++ b/go/extractor/vendor/golang.org/x/tools/internal/event/keys/BUILD.bazel @@ -1,3 +1,5 @@ +# generated running `bazel run //go/gazelle`, do not edit + load("@rules_go//go:def.bzl", "go_library") go_library( diff --git a/go/extractor/vendor/golang.org/x/tools/internal/event/label/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/internal/event/label/BUILD.bazel index 2329754d6cfc..a4430ba0a17c 100644 --- a/go/extractor/vendor/golang.org/x/tools/internal/event/label/BUILD.bazel +++ b/go/extractor/vendor/golang.org/x/tools/internal/event/label/BUILD.bazel @@ -1,3 +1,5 @@ +# generated running `bazel run //go/gazelle`, do not edit + load("@rules_go//go:def.bzl", "go_library") go_library( diff --git a/go/extractor/vendor/golang.org/x/tools/internal/event/tag/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/internal/event/tag/BUILD.bazel index 276dc5f4489a..d2c87f41a8ae 100644 --- a/go/extractor/vendor/golang.org/x/tools/internal/event/tag/BUILD.bazel +++ b/go/extractor/vendor/golang.org/x/tools/internal/event/tag/BUILD.bazel @@ -1,3 +1,5 @@ +# generated running `bazel run //go/gazelle`, do not edit + load("@rules_go//go:def.bzl", "go_library") go_library( diff --git a/go/extractor/vendor/golang.org/x/tools/internal/gcimporter/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/internal/gcimporter/BUILD.bazel index 1879fe0dadf5..56da3b0130e2 100644 --- a/go/extractor/vendor/golang.org/x/tools/internal/gcimporter/BUILD.bazel +++ b/go/extractor/vendor/golang.org/x/tools/internal/gcimporter/BUILD.bazel @@ -1,3 +1,5 @@ +# generated running `bazel run //go/gazelle`, do not edit + load("@rules_go//go:def.bzl", "go_library") go_library( diff --git a/go/extractor/vendor/golang.org/x/tools/internal/gocommand/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/internal/gocommand/BUILD.bazel index 58f7091b49c0..7e64f94b95cb 100644 --- a/go/extractor/vendor/golang.org/x/tools/internal/gocommand/BUILD.bazel +++ b/go/extractor/vendor/golang.org/x/tools/internal/gocommand/BUILD.bazel @@ -1,3 +1,5 @@ +# generated running `bazel run //go/gazelle`, do not edit + load("@rules_go//go:def.bzl", "go_library") go_library( diff --git a/go/extractor/vendor/golang.org/x/tools/internal/packagesinternal/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/internal/packagesinternal/BUILD.bazel index 3ed918c94899..2d2b7dc5b33c 100644 --- a/go/extractor/vendor/golang.org/x/tools/internal/packagesinternal/BUILD.bazel +++ b/go/extractor/vendor/golang.org/x/tools/internal/packagesinternal/BUILD.bazel @@ -1,3 +1,5 @@ +# generated running `bazel run //go/gazelle`, do not edit + load("@rules_go//go:def.bzl", "go_library") go_library( diff --git a/go/extractor/vendor/golang.org/x/tools/internal/pkgbits/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/internal/pkgbits/BUILD.bazel index 820e8f04c9b5..cce327470517 100644 --- a/go/extractor/vendor/golang.org/x/tools/internal/pkgbits/BUILD.bazel +++ b/go/extractor/vendor/golang.org/x/tools/internal/pkgbits/BUILD.bazel @@ -1,3 +1,5 @@ +# generated running `bazel run //go/gazelle`, do not edit + load("@rules_go//go:def.bzl", "go_library") go_library( diff --git a/go/extractor/vendor/golang.org/x/tools/internal/tokeninternal/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/internal/tokeninternal/BUILD.bazel index ff66085dbdba..c0f6cc8fb13a 100644 --- a/go/extractor/vendor/golang.org/x/tools/internal/tokeninternal/BUILD.bazel +++ b/go/extractor/vendor/golang.org/x/tools/internal/tokeninternal/BUILD.bazel @@ -1,3 +1,5 @@ +# generated running `bazel run //go/gazelle`, do not edit + load("@rules_go//go:def.bzl", "go_library") go_library( diff --git a/go/extractor/vendor/golang.org/x/tools/internal/typeparams/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/internal/typeparams/BUILD.bazel index 266816d9ea27..9c2dc20b6c65 100644 --- a/go/extractor/vendor/golang.org/x/tools/internal/typeparams/BUILD.bazel +++ b/go/extractor/vendor/golang.org/x/tools/internal/typeparams/BUILD.bazel @@ -1,3 +1,5 @@ +# generated running `bazel run //go/gazelle`, do not edit + load("@rules_go//go:def.bzl", "go_library") go_library( diff --git a/go/extractor/vendor/golang.org/x/tools/internal/typesinternal/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/internal/typesinternal/BUILD.bazel index c03b8a36ef7a..653752ab7152 100644 --- a/go/extractor/vendor/golang.org/x/tools/internal/typesinternal/BUILD.bazel +++ b/go/extractor/vendor/golang.org/x/tools/internal/typesinternal/BUILD.bazel @@ -1,3 +1,5 @@ +# generated running `bazel run //go/gazelle`, do not edit + load("@rules_go//go:def.bzl", "go_library") go_library( diff --git a/go/extractor/vendor/golang.org/x/tools/internal/versions/BUILD.bazel b/go/extractor/vendor/golang.org/x/tools/internal/versions/BUILD.bazel index 6d7ffd0ac686..85d428debf54 100644 --- a/go/extractor/vendor/golang.org/x/tools/internal/versions/BUILD.bazel +++ b/go/extractor/vendor/golang.org/x/tools/internal/versions/BUILD.bazel @@ -1,3 +1,5 @@ +# generated running `bazel run //go/gazelle`, do not edit + load("@rules_go//go:def.bzl", "go_library") go_library( diff --git a/go/gazelle/BUILD.bazel b/go/gazelle/BUILD.bazel index 7c9b34edb3a6..3d81b50590a9 100644 --- a/go/gazelle/BUILD.bazel +++ b/go/gazelle/BUILD.bazel @@ -1,8 +1,13 @@ load("@gazelle//:def.bzl", "gazelle") gazelle( + name = "_gazelle", +) + +py_binary( name = "gazelle", - extra_args = [ - "go/extractor", - ], + srcs = ["gazelle.py"], + args = ["$(rlocationpath :_gazelle)"], + data = [":_gazelle"], + deps = ["@rules_python//python/runfiles"], ) diff --git a/go/gazelle/gazelle.py b/go/gazelle/gazelle.py new file mode 100644 index 000000000000..200f3c3ed6b1 --- /dev/null +++ b/go/gazelle/gazelle.py @@ -0,0 +1,16 @@ +import sys +import pathlib +import subprocess +from python.runfiles import runfiles + +this = pathlib.Path(__file__).resolve() +go_extractor_dir = this.parents[1] / "extractor" +gazelle = runfiles.Create().Rlocation(sys.argv[1]) +for build_file in go_extractor_dir.glob("*/**/BUILD.bazel"): + build_file.unlink() + +subprocess.check_call([gazelle, "go/extractor"]) + +for build_file in go_extractor_dir.glob("*/**/BUILD.bazel"): + contents = build_file.read_text() + build_file.write_text(f"# generated running `bazel run //go/gazelle`, do not edit\n\n{contents}") From 3ad9c026a5c59b8a23d5541a1251fc611dd89988 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 26 Apr 2024 11:20:47 +0200 Subject: [PATCH 058/238] Go: remove `go_sdk.host` It's not required, and it can't work from the internal repository. --- MODULE.bazel | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 7a85ab51a96c..16697403dccc 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -23,8 +23,7 @@ bazel_dep(name = "bazel_skylib", version = "1.5.0") bazel_dep(name = "abseil-cpp", version = "20240116.0", repo_name = "absl") bazel_dep(name = "nlohmann_json", version = "3.11.3", repo_name = "json") bazel_dep(name = "fmt", version = "10.0.0") - -bazel_dep(name = "gazelle", version = "0.36.0", dev_dependency = True) +bazel_dep(name = "gazelle", version = "0.36.0") pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip") pip.parse( @@ -56,7 +55,6 @@ use_repo(node, "nodejs", "nodejs_toolchains") go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk") go_sdk.download(version = "1.22.2") -go_sdk.host() register_toolchains( "@nodejs_toolchains//:all", From 925a2cca7e6a5c8231b37f67df3de469ddf50925 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 26 Apr 2024 12:01:23 +0200 Subject: [PATCH 059/238] Go: create whole extractor pack with bazel --- go/BUILD.bazel | 59 +++++++++++++++++++++++++++++++++++++ go/codeql-tools/BUILD.bazel | 28 ++++++++++++++++++ go/create_extractor_pack.py | 16 ++++++++++ go/downgrades/BUILD.bazel | 12 ++++++++ go/extractor/BUILD.bazel | 31 +++++++++++++++++++ 5 files changed, 146 insertions(+) create mode 100644 go/codeql-tools/BUILD.bazel create mode 100644 go/create_extractor_pack.py create mode 100644 go/downgrades/BUILD.bazel diff --git a/go/BUILD.bazel b/go/BUILD.bazel index e69de29bb2d1..5736912310a8 100644 --- a/go/BUILD.bazel +++ b/go/BUILD.bazel @@ -0,0 +1,59 @@ +load("@rules_pkg//pkg:mappings.bzl", "pkg_filegroup", "pkg_files") +load("@rules_pkg//pkg:install.bzl", "pkg_install") +load("//:defs.bzl", "codeql_platform") + +pkg_files( + name = "resources", + srcs = [ + "LICENSE", + "codeql-extractor.yml", + "ql/lib/go.dbscheme", + "ql/lib/go.dbscheme.stats", + ], +) + +pkg_filegroup( + name = "extractor-pack-generic", + srcs = [ + ":resources", + "//go/codeql-tools", + "//go/downgrades", + "//go/extractor:tokenizer", + ], + visibility = ["//visibility:public"], +) + +pkg_files( + name = "extractor-pack-arch", + srcs = [ + "//go/extractor/cli/go-autobuilder", + "//go/extractor/cli/go-bootstrap", + "//go/extractor/cli/go-build-runner", + "//go/extractor/cli/go-extractor", + "//go/extractor/cli/go-gen-dbscheme", + "//go/extractor/cli/go-tokenizer", + ], + prefix = "tools/" + codeql_platform, + visibility = ["//visibility:public"], +) + +pkg_filegroup( + name = "extractor-pack", + srcs = [ + ":extractor-pack-arch", + ":extractor-pack-generic", + ], + visibility = ["//visibility:public"], +) + +pkg_install( + name = "_create_extractor_pack", + srcs = [":extractor-pack"], +) + +py_binary( + name = "create-extractor-pack", + srcs = ["create_extractor_pack.py"], + main = "create_extractor_pack.py", + deps = [":_create_extractor_pack"], +) diff --git a/go/codeql-tools/BUILD.bazel b/go/codeql-tools/BUILD.bazel new file mode 100644 index 000000000000..4e839b4774b5 --- /dev/null +++ b/go/codeql-tools/BUILD.bazel @@ -0,0 +1,28 @@ +load("@rules_pkg//pkg:mappings.bzl", "pkg_attributes", "pkg_filegroup", "pkg_files") + +pkg_files( + name = "executables", + srcs = glob(["*.sh"]), + attributes = pkg_attributes(mode = "0755"), +) + +pkg_files( + name = "non-executables", + srcs = glob( + ["*"], + exclude = [ + "*.sh", + "BUILD.bazel", + ], + ), +) + +pkg_filegroup( + name = "codeql-tools", + srcs = [ + ":executables", + ":non-executables", + ], + prefix = "tools", + visibility = ["//go:__pkg__"], +) diff --git a/go/create_extractor_pack.py b/go/create_extractor_pack.py new file mode 100644 index 000000000000..08665a2d8dc9 --- /dev/null +++ b/go/create_extractor_pack.py @@ -0,0 +1,16 @@ +import os +import pathlib +import shutil +import sys +from go._create_extractor_pack_install_script import main + +try: + workspace_dir = pathlib.Path(os.environ['BUILD_WORKSPACE_DIRECTORY']) +except KeyError: + print("this should be run with bazel run", file=sys.stderr) + sys.exit(1) + +dest_dir = workspace_dir / 'go' / 'build' / 'codeql-extractor-go' +shutil.rmtree(dest_dir, ignore_errors=True) +os.environ['DESTDIR'] = str(dest_dir) +main(sys.argv) diff --git a/go/downgrades/BUILD.bazel b/go/downgrades/BUILD.bazel new file mode 100644 index 000000000000..68c15741a9f6 --- /dev/null +++ b/go/downgrades/BUILD.bazel @@ -0,0 +1,12 @@ +load("@rules_pkg//pkg:mappings.bzl", "pkg_files", "strip_prefix") + +pkg_files( + name = "downgrades", + srcs = glob( + ["**"], + exclude = ["BUILD.bazel"], + ), + prefix = "downgrades", + strip_prefix = strip_prefix.from_pkg(), + visibility = ["//go:__pkg__"], +) diff --git a/go/extractor/BUILD.bazel b/go/extractor/BUILD.bazel index 040b42273140..cb7bc3ac8ef2 100644 --- a/go/extractor/BUILD.bazel +++ b/go/extractor/BUILD.bazel @@ -1,4 +1,5 @@ load("@rules_go//go:def.bzl", "go_library") +load("@rules_pkg//pkg:mappings.bzl", "pkg_files") # gazelle:prefix github.com/github/codeql-go/extractor # gazelle:map_kind go_binary codeql_go_binary //go:rules.bzl @@ -22,3 +23,33 @@ go_library( "//go/extractor/vendor/golang.org/x/tools/go/packages", ], ) + +java_library( + name = "tokenizer-deps", + srcs = [ + "net/sourceforge/pmd/cpd/AbstractLanguage.java", + "net/sourceforge/pmd/cpd/SourceCode.java", + "net/sourceforge/pmd/cpd/TokenEntry.java", + "net/sourceforge/pmd/cpd/Tokenizer.java", + ], +) + +java_library( + name = "tokenizer-jar", + srcs = [ + "net/sourceforge/pmd/cpd/GoLanguage.java", + "opencsv/CSVParser.java", + "opencsv/CSVReader.java", + ], + deps = [":tokenizer-deps"], +) + +pkg_files( + name = "tokenizer", + srcs = [":tokenizer-jar"], + prefix = "tools", + renames = { + ":tokenizer-jar": "tokenizer.jar", + }, + visibility = ["//go:__pkg__"], +) From 06f987ad580466386d5a076eb8602feda214b357 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 23 Apr 2024 15:43:25 +0200 Subject: [PATCH 060/238] Java: Add test example of a supported sink defined in QL. --- .../SupportedExternalApis.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.java b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.java index 880d183aecdb..8fd5f679824e 100644 --- a/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.java +++ b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.java @@ -1,10 +1,13 @@ +import java.io.File; +import java.io.FileWriter; +import java.io.InputStream; +import java.io.IOException; +import java.net.URL; import java.time.Duration; import java.util.HashMap; import java.util.Map; -import java.io.InputStream; -import java.net.URL; -import java.io.File; -import java.io.FileWriter; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.ServletException; import org.apache.commons.io.FileUtils; class SupportedExternalApis { @@ -30,4 +33,8 @@ public static void main(String[] args) throws Exception { file.compareTo(file); // supported neutral sink (compareTo) } + + public static void doSendRedirect(HttpServletResponse req) throws ServletException, IOException { + req.sendRedirect("myredirect"); // supported sink (sendRedirect) + } } From acb2bbb2a36702d9c0d7b08c3ddab6103e1a12ff Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 22 Apr 2024 11:21:13 +0200 Subject: [PATCH 061/238] Java: Identify more APIs as supported in the telemetry queries (as QL defined sources). --- .../semmle/code/java/dataflow/ApiSources.qll | 69 +++++++++++++++++++ .../semmle/code/java/dataflow/FlowSources.qll | 8 ++- .../CleartextStorageAndroidDatabaseQuery.qll | 11 ++- ...CleartextStorageAndroidFilesystemQuery.qll | 9 ++- .../security/CleartextStorageCookieQuery.qll | 9 ++- .../CleartextStorageSharedPrefsQuery.qll | 13 +++- .../ImproperIntentVerificationQuery.qll | 13 +++- .../java/security/StackTraceExposureQuery.qll | 7 +- java/ql/lib/semmle/code/java/security/XSS.qll | 9 ++- .../code/java/security/ZipSlipQuery.qll | 13 +++- java/ql/src/Telemetry/ExternalApi.qll | 5 +- 11 files changed, 143 insertions(+), 23 deletions(-) create mode 100644 java/ql/lib/semmle/code/java/dataflow/ApiSources.qll diff --git a/java/ql/lib/semmle/code/java/dataflow/ApiSources.qll b/java/ql/lib/semmle/code/java/dataflow/ApiSources.qll new file mode 100644 index 000000000000..61025262cb52 --- /dev/null +++ b/java/ql/lib/semmle/code/java/dataflow/ApiSources.qll @@ -0,0 +1,69 @@ +/** Provides classes representing various flow sources for data flow / taint tracking. */ + +private import semmle.code.java.dataflow.DataFlow +private import semmle.code.java.dataflow.ExternalFlow + +/** + * A data flow source node. + */ +abstract class SourceNode extends DataFlow::Node { } + +/** + * Module that adds all API like sources to `SourceNode`, excluding some sources for cryptography based + * queries, and queries where sources are not succifiently defined (eg. using broad method name matching). + */ +private module ApiSources { + private import FlowSources as FlowSources + private import semmle.code.java.security.ArbitraryApkInstallation as ArbitraryApkInstallation + private import semmle.code.java.security.CleartextStorageAndroidDatabaseQuery as CleartextStorageAndroidDatabaseQuery + private import semmle.code.java.security.CleartextStorageAndroidFilesystemQuery as CleartextStorageAndroidFilesystemQuery + private import semmle.code.java.security.CleartextStorageCookieQuery as CleartextStorageCookieQuery + private import semmle.code.java.security.CleartextStorageSharedPrefsQuery as CleartextStorageSharedPrefsQuery + private import semmle.code.java.security.ImplicitPendingIntentsQuery as ImplicitPendingIntentsQuery + private import semmle.code.java.security.ImproperIntentVerificationQuery as ImproperIntentVerificationQuery + private import semmle.code.java.security.InsecureTrustManager as InsecureTrustManager + private import semmle.code.java.security.JWT as Jwt + private import semmle.code.java.security.StackTraceExposureQuery as StackTraceExposureQuery + private import semmle.code.java.security.ZipSlipQuery as ZipSlipQuery + + private class FlowSourcesSourceNode extends SourceNode instanceof FlowSources::SourceNode { } + + private class ArbitraryApkInstallationSources extends SourceNode instanceof ArbitraryApkInstallation::ExternalApkSource + { } + + private class CleartextStorageAndroidDatabaseQuerySources extends SourceNode instanceof CleartextStorageAndroidDatabaseQuery::LocalDatabaseOpenMethodCallSource + { } + + private class CleartextStorageAndroidFilesystemQuerySources extends SourceNode instanceof CleartextStorageAndroidFilesystemQuery::LocalFileOpenCallSource + { } + + private class CleartextStorageCookieQuerySources extends SourceNode instanceof CleartextStorageCookieQuery::CookieSource + { } + + private class CleartextStorageSharedPrefsQuerySources extends SourceNode instanceof CleartextStorageSharedPrefsQuery::SharedPreferencesEditorMethodCallSource + { } + + private class ImplicitPendingIntentsQuerySources extends SourceNode instanceof ImplicitPendingIntentsQuery::ImplicitPendingIntentSource + { } + + private class ImproperIntentVerificationQuerySources extends SourceNode instanceof ImproperIntentVerificationQuery::VerifiedIntentConfigSource + { } + + private class InsecureTrustManagerSources extends SourceNode instanceof InsecureTrustManager::InsecureTrustManagerSource + { } + + private class JwtSources extends SourceNode instanceof Jwt::JwtParserWithInsecureParseSource { } + + private class StackTraceExposureQuerySources extends SourceNode instanceof StackTraceExposureQuery::GetMessageFlowSource + { } + + private class ZipSlipQuerySources extends SourceNode instanceof ZipSlipQuery::ArchiveEntryNameMethodSource + { } + + /** + * Add all models as data sources. + */ + private class SourceNodeExternal extends SourceNode { + SourceNodeExternal() { sourceNode(this, _) } + } +} diff --git a/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll b/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll index 425eb3ccaa60..49d7bda4e448 100644 --- a/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll +++ b/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll @@ -194,15 +194,17 @@ private class AndroidExternalStorageSource extends RemoteFlowSource { } /** Class for `tainted` user input. */ -abstract class UserInput extends DataFlow::Node { } +abstract class UserInput extends SourceNode { } /** * Input that may be controlled by a remote user. */ -private class RemoteUserInput extends UserInput instanceof RemoteFlowSource { } +private class RemoteUserInput extends UserInput instanceof RemoteFlowSource { + override string getThreatModel() { result = RemoteFlowSource.super.getThreatModel() } +} /** A node with input that may be controlled by a local user. */ -abstract class LocalUserInput extends UserInput, SourceNode { +abstract class LocalUserInput extends UserInput { override string getThreatModel() { result = "local" } } diff --git a/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidDatabaseQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidDatabaseQuery.qll index b42389a1df6e..7f306298a45e 100644 --- a/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidDatabaseQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidDatabaseQuery.qll @@ -96,10 +96,15 @@ private predicate localDatabaseStore(DataFlow::Node database, MethodCall store) ) } +/** + * A class of local database open method call source nodes. + */ +class LocalDatabaseOpenMethodCallSource extends DataFlow::Node { + LocalDatabaseOpenMethodCallSource() { this.asExpr() instanceof LocalDatabaseOpenMethodCall } +} + private module LocalDatabaseFlowConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { - source.asExpr() instanceof LocalDatabaseOpenMethodCall - } + predicate isSource(DataFlow::Node source) { source instanceof LocalDatabaseOpenMethodCallSource } predicate isSink(DataFlow::Node sink) { localDatabaseInput(sink, _) or diff --git a/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidFilesystemQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidFilesystemQuery.qll index d7097f1ecf23..0759b4c061b0 100644 --- a/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidFilesystemQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidFilesystemQuery.qll @@ -79,8 +79,15 @@ private class CloseFileMethod extends Method { } } +/** + * A class of local file open call source nodes. + */ +class LocalFileOpenCallSource extends DataFlow::Node { + LocalFileOpenCallSource() { this.asExpr() instanceof LocalFileOpenCall } +} + private module FilesystemFlowConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node src) { src.asExpr() instanceof LocalFileOpenCall } + predicate isSource(DataFlow::Node src) { src instanceof LocalFileOpenCallSource } predicate isSink(DataFlow::Node sink) { filesystemInput(sink, _) or diff --git a/java/ql/lib/semmle/code/java/security/CleartextStorageCookieQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStorageCookieQuery.qll index 2b6534e8cbda..af55c29e91c4 100644 --- a/java/ql/lib/semmle/code/java/security/CleartextStorageCookieQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CleartextStorageCookieQuery.qll @@ -37,8 +37,15 @@ private predicate cookieStore(DataFlow::Node cookie, Expr store) { ) } +/** + * A class of cookie source nodes. + */ +class CookieSource extends DataFlow::Node { + CookieSource() { this.asExpr() instanceof Cookie } +} + private module CookieToStoreFlowConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node src) { src.asExpr() instanceof Cookie } + predicate isSource(DataFlow::Node src) { src instanceof CookieSource } predicate isSink(DataFlow::Node sink) { cookieStore(sink, _) } } diff --git a/java/ql/lib/semmle/code/java/security/CleartextStorageSharedPrefsQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStorageSharedPrefsQuery.qll index 39e1ffa3c75d..3f690aeb6f19 100644 --- a/java/ql/lib/semmle/code/java/security/CleartextStorageSharedPrefsQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CleartextStorageSharedPrefsQuery.qll @@ -67,11 +67,18 @@ private predicate sharedPreferencesStore(DataFlow::Node editor, MethodCall m) { editor.asExpr() = m.getQualifier().getUnderlyingExpr() } +/** + * A shared preferences editor method call source nodes. + */ +class SharedPreferencesEditorMethodCallSource extends DataFlow::Node { + SharedPreferencesEditorMethodCallSource() { + this.asExpr() instanceof SharedPreferencesEditorMethodCall + } +} + /** Flow from `SharedPreferences.Editor` to either a setter or a store method. */ private module SharedPreferencesFlowConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node src) { - src.asExpr() instanceof SharedPreferencesEditorMethodCall - } + predicate isSource(DataFlow::Node src) { src instanceof SharedPreferencesEditorMethodCallSource } predicate isSink(DataFlow::Node sink) { sharedPreferencesInput(sink, _) or diff --git a/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll b/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll index bca045bc8e42..92bcac5b50e0 100644 --- a/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll +++ b/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll @@ -13,11 +13,18 @@ private class OnReceiveMethod extends Method { Parameter getIntentParameter() { result = this.getParameter(1) } } +/** + * A class of verified intent source nodes. + */ +class VerifiedIntentConfigSource extends DataFlow::Node { + VerifiedIntentConfigSource() { + this.asParameter() = any(OnReceiveMethod orm).getIntentParameter() + } +} + /** A configuration to detect whether the `action` of an `Intent` is checked. */ private module VerifiedIntentConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node src) { - src.asParameter() = any(OnReceiveMethod orm).getIntentParameter() - } + predicate isSource(DataFlow::Node src) { src instanceof VerifiedIntentConfigSource } predicate isSink(DataFlow::Node sink) { exists(MethodCall ma | diff --git a/java/ql/lib/semmle/code/java/security/StackTraceExposureQuery.qll b/java/ql/lib/semmle/code/java/security/StackTraceExposureQuery.qll index dba9492d137b..2e4b31b7785e 100644 --- a/java/ql/lib/semmle/code/java/security/StackTraceExposureQuery.qll +++ b/java/ql/lib/semmle/code/java/security/StackTraceExposureQuery.qll @@ -19,7 +19,7 @@ private class PrintStackTraceMethod extends Method { } private module ServletWriterSourceToPrintStackTraceMethodFlowConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node src) { src.asExpr() instanceof XssVulnerableWriterSource } + predicate isSource(DataFlow::Node src) { src instanceof XssVulnerableWriterSourceNode } predicate isSink(DataFlow::Node sink) { exists(MethodCall ma | @@ -95,7 +95,10 @@ predicate stringifiedStackFlowsExternally(DataFlow::Node externalExpr, Expr stac ) } -private class GetMessageFlowSource extends DataFlow::Node { +/** + * A class of get message source nodes. + */ +class GetMessageFlowSource extends DataFlow::Node { GetMessageFlowSource() { exists(Method method | this.asExpr().(MethodCall).getMethod() = method | method.hasName("getMessage") and diff --git a/java/ql/lib/semmle/code/java/security/XSS.qll b/java/ql/lib/semmle/code/java/security/XSS.qll index 9edee5823bfc..aa69e5e7865f 100644 --- a/java/ql/lib/semmle/code/java/security/XSS.qll +++ b/java/ql/lib/semmle/code/java/security/XSS.qll @@ -62,7 +62,7 @@ private class DefaultXssSanitizer extends XssSanitizer { /** A configuration that tracks data from a servlet writer to an output method. */ private module XssVulnerableWriterSourceToWritingMethodFlowConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node src) { src.asExpr() instanceof XssVulnerableWriterSource } + predicate isSource(DataFlow::Node src) { src instanceof XssVulnerableWriterSourceNode } predicate isSink(DataFlow::Node sink) { exists(MethodCall ma | @@ -105,6 +105,13 @@ class XssVulnerableWriterSource extends MethodCall { } } +/** + * A class of xss vulnerable writer source nodes. + */ +class XssVulnerableWriterSourceNode extends DataFlow::Node { + XssVulnerableWriterSourceNode() { this.asExpr() instanceof XssVulnerableWriterSource } +} + /** * Holds if `s` is an HTTP Content-Type vulnerable to XSS. */ diff --git a/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll b/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll index 7ba99a31e268..f6f3b1bf27c4 100644 --- a/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll +++ b/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll @@ -21,13 +21,20 @@ private class ArchiveEntryNameMethod extends Method { } } +/** + * A class of entry name method source nodes. + */ +class ArchiveEntryNameMethodSource extends DataFlow::Node { + ArchiveEntryNameMethodSource() { + this.asExpr().(MethodCall).getMethod() instanceof ArchiveEntryNameMethod + } +} + /** * A taint-tracking configuration for reasoning about unsafe zip file extraction. */ module ZipSlipConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { - source.asExpr().(MethodCall).getMethod() instanceof ArchiveEntryNameMethod - } + predicate isSource(DataFlow::Node source) { source instanceof ArchiveEntryNameMethodSource } predicate isSink(DataFlow::Node sink) { sink instanceof FileCreationSink } diff --git a/java/ql/src/Telemetry/ExternalApi.qll b/java/ql/src/Telemetry/ExternalApi.qll index 47527dfbb46a..cbf2875e9d1f 100644 --- a/java/ql/src/Telemetry/ExternalApi.qll +++ b/java/ql/src/Telemetry/ExternalApi.qll @@ -1,6 +1,7 @@ /** Provides classes and predicates related to handling APIs from external libraries. */ private import java +private import semmle.code.java.dataflow.ApiSources as ApiSources private import semmle.code.java.dataflow.DataFlow private import semmle.code.java.dataflow.ExternalFlow private import semmle.code.java.dataflow.FlowSources @@ -69,9 +70,7 @@ class ExternalApi extends Callable { } pragma[nomagic] - predicate isSource() { - this.getAnOutput() instanceof RemoteFlowSource or sourceNode(this.getAnOutput(), _) - } + predicate isSource() { this.getAnOutput() instanceof ApiSources::SourceNode } /** Holds if this API is a known sink. */ pragma[nomagic] From 9db32f4d26ac81ec32378a7d0efc2c55a8b1da15 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 23 Apr 2024 13:27:08 +0200 Subject: [PATCH 062/238] Java: Identify more APIs as supported in the telemetry queries (as QL defined sinks). --- .../semmle/code/java/dataflow/ApiSinks.qll | 122 ++++++++++++++++++ .../AndroidSensitiveCommunicationQuery.qll | 17 ++- .../CleartextStorageAndroidDatabaseQuery.qll | 12 +- ...CleartextStorageAndroidFilesystemQuery.qll | 15 ++- .../security/CleartextStorageCookieQuery.qll | 9 +- .../CleartextStorageSharedPrefsQuery.qll | 15 ++- .../ExternallyControlledFormatStringQuery.qll | 11 +- .../security/SensitiveResultReceiverQuery.qll | 17 ++- .../code/java/security/SensitiveUiQuery.qll | 19 ++- ...TempDirLocalInformationDisclosureQuery.qll | 17 ++- .../security/WebviewDebuggingEnabledQuery.qll | 19 ++- java/ql/src/Telemetry/ExternalApi.qll | 3 +- 12 files changed, 232 insertions(+), 44 deletions(-) create mode 100644 java/ql/lib/semmle/code/java/dataflow/ApiSinks.qll diff --git a/java/ql/lib/semmle/code/java/dataflow/ApiSinks.qll b/java/ql/lib/semmle/code/java/dataflow/ApiSinks.qll new file mode 100644 index 000000000000..0dae848c15da --- /dev/null +++ b/java/ql/lib/semmle/code/java/dataflow/ApiSinks.qll @@ -0,0 +1,122 @@ +/** Provides classes representing various flow sinks for data flow / taint tracking. */ + +private import semmle.code.java.dataflow.DataFlow +private import semmle.code.java.dataflow.ExternalFlow + +/** + * A data flow sink node. + */ +abstract class SinkNode extends DataFlow::Node { } + +/** + * Module that adds all API like sinks to `SinkNode`, excluding sinks for cryptography based + * queries, and queries where sinks are not succifiently defined (eg. using broad method name matching). + */ +private module ApiSinks { + private import semmle.code.java.security.AndroidSensitiveCommunicationQuery as AndroidSensitiveCommunicationQuery + private import semmle.code.java.security.ArbitraryApkInstallation as ArbitraryApkInstallation + private import semmle.code.java.security.CleartextStorageAndroidDatabaseQuery as CleartextStorageAndroidDatabaseQuery + private import semmle.code.java.security.CleartextStorageAndroidFilesystemQuery as CleartextStorageAndroidFilesystemQuery + private import semmle.code.java.security.CleartextStorageCookieQuery as CleartextStorageCookieQuery + private import semmle.code.java.security.CleartextStorageSharedPrefsQuery as CleartextStorageSharedPrefsQuery + private import semmle.code.java.security.ExternallyControlledFormatStringQuery as ExternallyControlledFormatStringQuery + private import semmle.code.java.security.InsecureBasicAuth as InsecureBasicAuth + private import semmle.code.java.security.IntentUriPermissionManipulation as IntentUriPermissionManipulation + private import semmle.code.java.security.InsecureLdapAuth as InsecureLdapAuth + private import semmle.code.java.security.InsecureTrustManager as InsecureTrustManager + private import semmle.code.java.security.JndiInjection as JndiInjection + private import semmle.code.java.security.JWT as Jwt + private import semmle.code.java.security.OgnlInjection as OgnlInjection + private import semmle.code.java.security.SensitiveResultReceiverQuery as SensitiveResultReceiverQuery + private import semmle.code.java.security.SensitiveUiQuery as SensitiveUiQuery + private import semmle.code.java.security.SpelInjection as SpelInjection + private import semmle.code.java.security.SpelInjectionQuery as SpelInjectionQuery + private import semmle.code.java.security.QueryInjection as QueryInjection + private import semmle.code.java.security.TempDirLocalInformationDisclosureQuery as TempDirLocalInformationDisclosureQuery + private import semmle.code.java.security.UnsafeAndroidAccess as UnsafeAndroidAccess + private import semmle.code.java.security.UnsafeContentUriResolution as UnsafeContentUriResolution + private import semmle.code.java.security.UnsafeDeserializationQuery as UnsafeDeserializationQuery + private import semmle.code.java.security.UrlRedirect as UrlRedirect + private import semmle.code.java.security.WebviewDebuggingEnabledQuery as WebviewDebuggingEnabledQuery + private import semmle.code.java.security.XPath as Xpath + private import semmle.code.java.security.XSS as Xss + + private class AndoidIntentRedirectionQuerySinks extends SinkNode instanceof AndroidSensitiveCommunicationQuery::SensitiveCommunicationSink + { } + + private class ArbitraryApkInstallationSinks extends SinkNode instanceof ArbitraryApkInstallation::SetDataSink + { } + + private class CleartextStorageAndroidDatabaseQuerySinks extends SinkNode instanceof CleartextStorageAndroidDatabaseQuery::LocalDatabaseSink + { } + + private class CleartextStorageAndroidFilesystemQuerySinks extends SinkNode instanceof CleartextStorageAndroidFilesystemQuery::LocalFileSink + { } + + private class CleartextStorageCookieQuerySinks extends SinkNode instanceof CleartextStorageCookieQuery::CookieStoreSink + { } + + private class CleartextStorageSharedPrefsQuerySinks extends SinkNode instanceof CleartextStorageSharedPrefsQuery::SharedPreferencesSink + { } + + private class ExternallyControlledFormatStringQuerySinks extends SinkNode instanceof ExternallyControlledFormatStringQuery::StringFormatSink + { } + + private class InsecureBasicAuthSinks extends SinkNode instanceof InsecureBasicAuth::InsecureBasicAuthSink + { } + + private class InsecureTrustManagerSinks extends SinkNode instanceof InsecureTrustManager::InsecureTrustManagerSink + { } + + private class IntentUriPermissionManipulationSinks extends SinkNode instanceof IntentUriPermissionManipulation::IntentUriPermissionManipulationSink + { } + + private class InsecureLdapAuthSinks extends SinkNode instanceof InsecureLdapAuth::InsecureLdapUrlSink + { } + + private class JndiInjectionSinks extends SinkNode instanceof JndiInjection::JndiInjectionSink { } + + private class JwtSinks extends SinkNode instanceof Jwt::JwtParserWithInsecureParseSink { } + + private class OgnlInjectionSinks extends SinkNode instanceof OgnlInjection::OgnlInjectionSink { } + + private class SensitiveResultReceiverQuerySinks extends SinkNode instanceof SensitiveResultReceiverQuery::SensitiveResultReceiverSink + { } + + private class SensitiveUiQuerySinks extends SinkNode instanceof SensitiveUiQuery::TextFieldSink { + } + + private class SpelInjectionSinks extends SinkNode instanceof SpelInjection::SpelExpressionEvaluationSink + { } + + private class QueryInjectionSinks extends SinkNode instanceof QueryInjection::QueryInjectionSink { + } + + private class TempDirLocalInformationDisclosureSinks extends SinkNode instanceof TempDirLocalInformationDisclosureQuery::MethodFileDirectoryCreationSink + { } + + private class UnsafeAndroidAccessSinks extends SinkNode instanceof UnsafeAndroidAccess::UrlResourceSink + { } + + private class UnsafeContentUriResolutionSinks extends SinkNode instanceof UnsafeContentUriResolution::ContentUriResolutionSink + { } + + private class UnsafeDeserializationQuerySinks extends SinkNode instanceof UnsafeDeserializationQuery::UnsafeDeserializationSink + { } + + private class UrlRedirectSinks extends SinkNode instanceof UrlRedirect::UrlRedirectSink { } + + private class WebviewDebugEnabledQuery extends SinkNode instanceof WebviewDebuggingEnabledQuery::WebviewDebugSink + { } + + private class XPathSinks extends SinkNode instanceof Xpath::XPathInjectionSink { } + + private class XssSinks extends SinkNode instanceof Xss::XssSink { } + + /** + * Add all models as data sinks. + */ + private class SinkNodeExternal extends SinkNode { + SinkNodeExternal() { sinkNode(this, _) } + } +} diff --git a/java/ql/lib/semmle/code/java/security/AndroidSensitiveCommunicationQuery.qll b/java/ql/lib/semmle/code/java/security/AndroidSensitiveCommunicationQuery.qll index 53adc7132c5e..9773d00849fd 100644 --- a/java/ql/lib/semmle/code/java/security/AndroidSensitiveCommunicationQuery.qll +++ b/java/ql/lib/semmle/code/java/security/AndroidSensitiveCommunicationQuery.qll @@ -151,17 +151,24 @@ deprecated class SensitiveCommunicationConfig extends TaintTracking::Configurati } } +/** + * A class of sensitive communication sink nodes. + */ +class SensitiveCommunicationSink extends DataFlow::Node { + SensitiveCommunicationSink() { + isSensitiveBroadcastSink(this) + or + isStartActivityOrServiceSink(this) + } +} + /** * Taint configuration tracking flow from variables containing sensitive information to broadcast Intents. */ module SensitiveCommunicationConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source.asExpr() instanceof SensitiveInfoExpr } - predicate isSink(DataFlow::Node sink) { - isSensitiveBroadcastSink(sink) - or - isStartActivityOrServiceSink(sink) - } + predicate isSink(DataFlow::Node sink) { sink instanceof SensitiveCommunicationSink } /** * Holds if broadcast doesn't specify receiving package name of the 3rd party app diff --git a/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidDatabaseQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidDatabaseQuery.qll index 7f306298a45e..5d212ea45f23 100644 --- a/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidDatabaseQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidDatabaseQuery.qll @@ -103,13 +103,17 @@ class LocalDatabaseOpenMethodCallSource extends DataFlow::Node { LocalDatabaseOpenMethodCallSource() { this.asExpr() instanceof LocalDatabaseOpenMethodCall } } +/** + * A class of local database sink nodes. + */ +class LocalDatabaseSink extends DataFlow::Node { + LocalDatabaseSink() { localDatabaseInput(this, _) or localDatabaseStore(this, _) } +} + private module LocalDatabaseFlowConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof LocalDatabaseOpenMethodCallSource } - predicate isSink(DataFlow::Node sink) { - localDatabaseInput(sink, _) or - localDatabaseStore(sink, _) - } + predicate isSink(DataFlow::Node sink) { sink instanceof LocalDatabaseSink } predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) { // Adds a step for tracking databases through field flow, that is, a database is opened and diff --git a/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidFilesystemQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidFilesystemQuery.qll index 0759b4c061b0..90749120fce6 100644 --- a/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidFilesystemQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidFilesystemQuery.qll @@ -86,13 +86,20 @@ class LocalFileOpenCallSource extends DataFlow::Node { LocalFileOpenCallSource() { this.asExpr() instanceof LocalFileOpenCall } } +/** + * A class of local file sink nodes. + */ +class LocalFileSink extends DataFlow::Node { + LocalFileSink() { + filesystemInput(this, _) or + closesFile(this, _) + } +} + private module FilesystemFlowConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node src) { src instanceof LocalFileOpenCallSource } - predicate isSink(DataFlow::Node sink) { - filesystemInput(sink, _) or - closesFile(sink, _) - } + predicate isSink(DataFlow::Node sink) { sink instanceof LocalFileSink } predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { // Add nested Writer constructors as extra data flow steps diff --git a/java/ql/lib/semmle/code/java/security/CleartextStorageCookieQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStorageCookieQuery.qll index af55c29e91c4..379d52eb5497 100644 --- a/java/ql/lib/semmle/code/java/security/CleartextStorageCookieQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CleartextStorageCookieQuery.qll @@ -44,10 +44,17 @@ class CookieSource extends DataFlow::Node { CookieSource() { this.asExpr() instanceof Cookie } } +/** + * A class of cookie store sink nodes. + */ +class CookieStoreSink extends DataFlow::Node { + CookieStoreSink() { cookieStore(this, _) } +} + private module CookieToStoreFlowConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node src) { src instanceof CookieSource } - predicate isSink(DataFlow::Node sink) { cookieStore(sink, _) } + predicate isSink(DataFlow::Node sink) { sink instanceof CookieStoreSink } } private module CookieToStoreFlow = DataFlow::Global; diff --git a/java/ql/lib/semmle/code/java/security/CleartextStorageSharedPrefsQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStorageSharedPrefsQuery.qll index 3f690aeb6f19..c09fb3cc61a6 100644 --- a/java/ql/lib/semmle/code/java/security/CleartextStorageSharedPrefsQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CleartextStorageSharedPrefsQuery.qll @@ -76,14 +76,21 @@ class SharedPreferencesEditorMethodCallSource extends DataFlow::Node { } } +/** + * A class of shared preferences sink nodes. + */ +class SharedPreferencesSink extends DataFlow::Node { + SharedPreferencesSink() { + sharedPreferencesInput(this, _) or + sharedPreferencesStore(this, _) + } +} + /** Flow from `SharedPreferences.Editor` to either a setter or a store method. */ private module SharedPreferencesFlowConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node src) { src instanceof SharedPreferencesEditorMethodCallSource } - predicate isSink(DataFlow::Node sink) { - sharedPreferencesInput(sink, _) or - sharedPreferencesStore(sink, _) - } + predicate isSink(DataFlow::Node sink) { sink instanceof SharedPreferencesSink } } private module SharedPreferencesFlow = DataFlow::Global; diff --git a/java/ql/lib/semmle/code/java/security/ExternallyControlledFormatStringQuery.qll b/java/ql/lib/semmle/code/java/security/ExternallyControlledFormatStringQuery.qll index a71ebc964f64..2fc622325dea 100644 --- a/java/ql/lib/semmle/code/java/security/ExternallyControlledFormatStringQuery.qll +++ b/java/ql/lib/semmle/code/java/security/ExternallyControlledFormatStringQuery.qll @@ -4,15 +4,20 @@ import java private import semmle.code.java.dataflow.FlowSources private import semmle.code.java.StringFormat +/** + * A class of string format sink nodes. + */ +class StringFormatSink extends DataFlow::Node { + StringFormatSink() { this.asExpr() = any(StringFormat formatCall).getFormatArgument() } +} + /** * A taint-tracking configuration for externally controlled format string vulnerabilities. */ module ExternallyControlledFormatStringConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof ThreatModelFlowSource } - predicate isSink(DataFlow::Node sink) { - sink.asExpr() = any(StringFormat formatCall).getFormatArgument() - } + predicate isSink(DataFlow::Node sink) { sink instanceof StringFormatSink } predicate isBarrier(DataFlow::Node node) { node.getType() instanceof NumericType or node.getType() instanceof BooleanType diff --git a/java/ql/lib/semmle/code/java/security/SensitiveResultReceiverQuery.qll b/java/ql/lib/semmle/code/java/security/SensitiveResultReceiverQuery.qll index 63d6d88d83cb..13a4b562a50e 100644 --- a/java/ql/lib/semmle/code/java/security/SensitiveResultReceiverQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SensitiveResultReceiverQuery.qll @@ -50,15 +50,22 @@ deprecated private class SensitiveResultReceiverConf extends TaintTracking::Conf } } -private module SensitiveResultReceiverConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node node) { node.asExpr() instanceof SensitiveExpr } - - predicate isSink(DataFlow::Node node) { +/** + * A class of sensitive result receiver sink nodes. + */ +class SensitiveResultReceiverSink extends DataFlow::Node { + SensitiveResultReceiverSink() { exists(ResultReceiverSendCall call | untrustedResultReceiverSend(_, call) and - node.asExpr() = call.getSentData() + this.asExpr() = call.getSentData() ) } +} + +private module SensitiveResultReceiverConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { node.asExpr() instanceof SensitiveExpr } + + predicate isSink(DataFlow::Node node) { node instanceof SensitiveResultReceiverSink } predicate allowImplicitRead(DataFlow::Node n, DataFlow::ContentSet c) { isSink(n) and exists(c) } } diff --git a/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll b/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll index 38a5aeb93cf9..884ab40a3239 100644 --- a/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll @@ -53,16 +53,23 @@ private class MaskCall extends MethodCall { } } -/** A configuration for tracking sensitive information to text fields. */ -private module TextFieldTrackingConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SensitiveExpr } - - predicate isSink(DataFlow::Node sink) { +/** + * A class of test field sink nodes. + */ +class TextFieldSink extends DataFlow::Node { + TextFieldSink() { exists(SetTextCall call | - sink.asExpr() = call.getStringArgument() and + this.asExpr() = call.getStringArgument() and not setTextCallIsMasked(call) ) } +} + +/** A configuration for tracking sensitive information to text fields. */ +private module TextFieldTrackingConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SensitiveExpr } + + predicate isSink(DataFlow::Node sink) { sink instanceof TextFieldSink } predicate isBarrier(DataFlow::Node node) { node instanceof SimpleTypeSanitizer } diff --git a/java/ql/lib/semmle/code/java/security/TempDirLocalInformationDisclosureQuery.qll b/java/ql/lib/semmle/code/java/security/TempDirLocalInformationDisclosureQuery.qll index 843db3b5934b..970363fe5439 100644 --- a/java/ql/lib/semmle/code/java/security/TempDirLocalInformationDisclosureQuery.qll +++ b/java/ql/lib/semmle/code/java/security/TempDirLocalInformationDisclosureQuery.qll @@ -153,6 +153,17 @@ module TempDirSystemGetPropertyToCreateConfig implements DataFlow::ConfigSig { module TempDirSystemGetPropertyToCreate = TaintTracking::Global; +/** + * A class of method file directory creation sink nodes. + */ +class MethodFileDirectoryCreationSink extends DataFlow::Node { + MethodFileDirectoryCreationSink() { + exists(MethodCall ma | ma.getMethod() instanceof MethodFileDirectoryCreation | + ma.getQualifier() = this.asExpr() + ) + } +} + /** * Configuration that tracks calls to to `mkdir` or `mkdirs` that are are directly on the temp directory system property. * Examples: @@ -172,11 +183,7 @@ module TempDirSystemGetPropertyDirectlyToMkdirConfig implements DataFlow::Config ) } - predicate isSink(DataFlow::Node node) { - exists(MethodCall ma | ma.getMethod() instanceof MethodFileDirectoryCreation | - ma.getQualifier() = node.asExpr() - ) - } + predicate isSink(DataFlow::Node node) { node instanceof MethodFileDirectoryCreationSink } predicate isBarrier(DataFlow::Node sanitizer) { isFileConstructorArgument(sanitizer.asExpr(), _, _) diff --git a/java/ql/lib/semmle/code/java/security/WebviewDebuggingEnabledQuery.qll b/java/ql/lib/semmle/code/java/security/WebviewDebuggingEnabledQuery.qll index 00b9c715f752..d2a21be95e0a 100644 --- a/java/ql/lib/semmle/code/java/security/WebviewDebuggingEnabledQuery.qll +++ b/java/ql/lib/semmle/code/java/security/WebviewDebuggingEnabledQuery.qll @@ -44,18 +44,25 @@ deprecated class WebviewDebugEnabledConfig extends DataFlow::Configuration { } } +/** + * A class of webview debug sink nodes. + */ +class WebviewDebugSink extends DataFlow::Node { + WebviewDebugSink() { + exists(MethodCall ma | + ma.getMethod().hasQualifiedName("android.webkit", "WebView", "setWebContentsDebuggingEnabled") and + this.asExpr() = ma.getArgument(0) + ) + } +} + /** A configuration to find instances of `setWebContentDebuggingEnabled` called with `true` values. */ module WebviewDebugEnabledConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node node) { node.asExpr().(BooleanLiteral).getBooleanValue() = true } - predicate isSink(DataFlow::Node node) { - exists(MethodCall ma | - ma.getMethod().hasQualifiedName("android.webkit", "WebView", "setWebContentsDebuggingEnabled") and - node.asExpr() = ma.getArgument(0) - ) - } + predicate isSink(DataFlow::Node node) { node instanceof WebviewDebugSink } predicate isBarrier(DataFlow::Node node) { exists(Guard debug | isDebugCheck(debug) and debug.controls(node.asExpr().getBasicBlock(), _)) diff --git a/java/ql/src/Telemetry/ExternalApi.qll b/java/ql/src/Telemetry/ExternalApi.qll index cbf2875e9d1f..a548593c36a3 100644 --- a/java/ql/src/Telemetry/ExternalApi.qll +++ b/java/ql/src/Telemetry/ExternalApi.qll @@ -2,6 +2,7 @@ private import java private import semmle.code.java.dataflow.ApiSources as ApiSources +private import semmle.code.java.dataflow.ApiSinks as ApiSinks private import semmle.code.java.dataflow.DataFlow private import semmle.code.java.dataflow.ExternalFlow private import semmle.code.java.dataflow.FlowSources @@ -74,7 +75,7 @@ class ExternalApi extends Callable { /** Holds if this API is a known sink. */ pragma[nomagic] - predicate isSink() { sinkNode(this.getAnInput(), _) } + predicate isSink() { this.getAnInput() instanceof ApiSinks::SinkNode } /** Holds if this API is a known neutral. */ pragma[nomagic] From b754706e444ab66aa958c1c36206ae793ed4280a Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 23 Apr 2024 15:45:16 +0200 Subject: [PATCH 063/238] Java: Update SupportedExternalApi expected test output. --- .../SupportedExternalApis/SupportedExternalApis.expected | 1 + 1 file changed, 1 insertion(+) diff --git a/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected index 68dc7169533f..d08da075f3fd 100644 --- a/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected +++ b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected @@ -13,4 +13,5 @@ | java.util.Map#put(Object,Object) | 1 | | java.util.Map$Entry#getKey() | 1 | | java.util.Set#iterator() | 1 | +| javax.servlet.http.HttpServletResponse#sendRedirect(String) | 1 | | org.apache.commons.io.FileUtils#deleteDirectory(File) | 1 | From 14d88eb3ce7b7bf99ead67688791ea415d465630 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Fri, 26 Apr 2024 12:56:28 +0200 Subject: [PATCH 064/238] add change-notes --- cpp/ql/lib/change-notes/2024-04-26-outdated-deprecations.md | 4 ++++ .../ql/lib/change-notes/2024-04-26-outdated-deprecations.md | 6 ++++++ go/ql/lib/change-notes/2024-04-26-outdated-deprecations.md | 4 ++++ .../ql/lib/change-notes/2024-04-26-outdated-deprecations.md | 4 ++++ .../ql/lib/change-notes/2024-04-26-outdated-deprecations.md | 6 ++++++ .../ql/lib/change-notes/2024-04-26-outdated-deprecations.md | 5 +++++ .../ql/lib/change-notes/2024-04-26-outdated-deprecations.md | 5 +++++ 7 files changed, 34 insertions(+) create mode 100644 cpp/ql/lib/change-notes/2024-04-26-outdated-deprecations.md create mode 100644 csharp/ql/lib/change-notes/2024-04-26-outdated-deprecations.md create mode 100644 go/ql/lib/change-notes/2024-04-26-outdated-deprecations.md create mode 100644 java/ql/lib/change-notes/2024-04-26-outdated-deprecations.md create mode 100644 javascript/ql/lib/change-notes/2024-04-26-outdated-deprecations.md create mode 100644 python/ql/lib/change-notes/2024-04-26-outdated-deprecations.md create mode 100644 ruby/ql/lib/change-notes/2024-04-26-outdated-deprecations.md diff --git a/cpp/ql/lib/change-notes/2024-04-26-outdated-deprecations.md b/cpp/ql/lib/change-notes/2024-04-26-outdated-deprecations.md new file mode 100644 index 000000000000..61a02a9613d4 --- /dev/null +++ b/cpp/ql/lib/change-notes/2024-04-26-outdated-deprecations.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Deleted the deprecated `GlobalValueNumberingImpl.qll` implementation. diff --git a/csharp/ql/lib/change-notes/2024-04-26-outdated-deprecations.md b/csharp/ql/lib/change-notes/2024-04-26-outdated-deprecations.md new file mode 100644 index 000000000000..2ac740557260 --- /dev/null +++ b/csharp/ql/lib/change-notes/2024-04-26-outdated-deprecations.md @@ -0,0 +1,6 @@ +--- +category: minorAnalysis +--- +* Deleted the deprecated `getAssemblyName` predicate from the `Operator` class. Use `getFunctionName` instead. +* Deleted the deprecated `LShiftOperator`, `RShiftOperator`, `AssignLShiftExpr`, `AssignRShiftExpr`, `LShiftExpr`, and `RShiftExpr` aliases. +* Deleted the deprecated `getCallableDescription` predicate from the `ExternalApiDataNode` class. Use `hasQualifiedName` instead. \ No newline at end of file diff --git a/go/ql/lib/change-notes/2024-04-26-outdated-deprecations.md b/go/ql/lib/change-notes/2024-04-26-outdated-deprecations.md new file mode 100644 index 000000000000..6723f78df122 --- /dev/null +++ b/go/ql/lib/change-notes/2024-04-26-outdated-deprecations.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Deleted the deprecated `CsvRemoteSource` alias. Use `MaDRemoteSource` instead. \ No newline at end of file diff --git a/java/ql/lib/change-notes/2024-04-26-outdated-deprecations.md b/java/ql/lib/change-notes/2024-04-26-outdated-deprecations.md new file mode 100644 index 000000000000..de3190492d39 --- /dev/null +++ b/java/ql/lib/change-notes/2024-04-26-outdated-deprecations.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Deleted the deprecated `AssignLShiftExpr`, `AssignRShiftExpr`, `AssignURShiftExpr`, `LShiftExpr`, `RShiftExpr`, and `URShiftExpr` aliases. diff --git a/javascript/ql/lib/change-notes/2024-04-26-outdated-deprecations.md b/javascript/ql/lib/change-notes/2024-04-26-outdated-deprecations.md new file mode 100644 index 000000000000..36444c07ac77 --- /dev/null +++ b/javascript/ql/lib/change-notes/2024-04-26-outdated-deprecations.md @@ -0,0 +1,6 @@ +--- +category: minorAnalysis +--- +* Deleted the deprecated `getInput` predicate from the `CryptographicOperation` class. Use `getAnInput` instead. +* Deleted the deprecated `RegExpPatterns` module from `Regexp.qll`. +* Deleted the deprecated `semmle/javascript/security/BadTagFilterQuery.qll`, `semmle/javascript/security/OverlyLargeRangeQuery.qll`, `semmle/javascript/security/regexp/RegexpMatching.qll`, and `Security/CWE-020/HostnameRegexpShared.qll` files. \ No newline at end of file diff --git a/python/ql/lib/change-notes/2024-04-26-outdated-deprecations.md b/python/ql/lib/change-notes/2024-04-26-outdated-deprecations.md new file mode 100644 index 000000000000..469060fd5be5 --- /dev/null +++ b/python/ql/lib/change-notes/2024-04-26-outdated-deprecations.md @@ -0,0 +1,5 @@ +--- +category: minorAnalysis +--- +* Deleted the deprecated `RegExpPatterns` module from `Regexp.qll`. +* Deleted the deprecated `Security/CWE-020/HostnameRegexpShared.qll` file. \ No newline at end of file diff --git a/ruby/ql/lib/change-notes/2024-04-26-outdated-deprecations.md b/ruby/ql/lib/change-notes/2024-04-26-outdated-deprecations.md new file mode 100644 index 000000000000..1ad9ef373827 --- /dev/null +++ b/ruby/ql/lib/change-notes/2024-04-26-outdated-deprecations.md @@ -0,0 +1,5 @@ +--- +category: minorAnalysis +--- +* Deleted the deprecated `RegExpPatterns` module from `Regexp.qll`. +* Deleted the deprecated `security/cwe-020/HostnameRegexpShared.qll` file. \ No newline at end of file From 19b2e56d0276518c1c6559536338b61e2451acf6 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 26 Apr 2024 13:38:10 +0200 Subject: [PATCH 065/238] Go: group BUILD and dbscheme generation target --- .pre-commit-config.yaml | 8 ++++---- go/BUILD.bazel | 28 ++++++++++++++++++++++++++++ go/gazelle/BUILD.bazel | 13 ------------- go/{gazelle/gazelle.py => gen.py} | 12 ++++++++++-- 4 files changed, 42 insertions(+), 19 deletions(-) delete mode 100644 go/gazelle/BUILD.bazel rename go/{gazelle/gazelle.py => gen.py} (56%) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4e81bcc7711c..899ddd71b898 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -27,11 +27,11 @@ repos: - repo: local hooks: - - id: gazelle - name: Check gazelle-generated BUILD files - files: go/extractor/.* + - id: go-gen + name: Check checked in generated files in go + files: go/.* language: system - entry: bazel run //go/gazelle + entry: bazel run //go:gen pass_filenames: false - id: codeql-format diff --git a/go/BUILD.bazel b/go/BUILD.bazel index 5736912310a8..c5f32c5309f9 100644 --- a/go/BUILD.bazel +++ b/go/BUILD.bazel @@ -1,7 +1,26 @@ load("@rules_pkg//pkg:mappings.bzl", "pkg_filegroup", "pkg_files") load("@rules_pkg//pkg:install.bzl", "pkg_install") +load("@bazel_skylib//rules:native_binary.bzl", "native_binary") +load("@gazelle//:def.bzl", "gazelle") load("//:defs.bzl", "codeql_platform") +gazelle( + name = "_gazelle", +) + +_gen_binaries = [ + ":_gazelle", + "//go/extractor/cli/go-gen-dbscheme", +] + +py_binary( + name = "gen", + srcs = ["gen.py"], + args = ["$(rlocationpath %s)" % bin for bin in _gen_binaries], + data = _gen_binaries, + deps = ["@rules_python//python/runfiles"], +) + pkg_files( name = "resources", srcs = [ @@ -57,3 +76,12 @@ py_binary( main = "create_extractor_pack.py", deps = [":_create_extractor_pack"], ) + +native_binary( + name = "gen-dbscheme", + src = "//go/extractor/cli/go-gen-dbscheme", + out = "go-gen-dbscheme", + args = [ + "$$BUILD_WORKSPACE_DIRECTORY/go/ql/lib/go.dbscheme", + ], +) diff --git a/go/gazelle/BUILD.bazel b/go/gazelle/BUILD.bazel deleted file mode 100644 index 3d81b50590a9..000000000000 --- a/go/gazelle/BUILD.bazel +++ /dev/null @@ -1,13 +0,0 @@ -load("@gazelle//:def.bzl", "gazelle") - -gazelle( - name = "_gazelle", -) - -py_binary( - name = "gazelle", - srcs = ["gazelle.py"], - args = ["$(rlocationpath :_gazelle)"], - data = [":_gazelle"], - deps = ["@rules_python//python/runfiles"], -) diff --git a/go/gazelle/gazelle.py b/go/gen.py similarity index 56% rename from go/gazelle/gazelle.py rename to go/gen.py index 200f3c3ed6b1..7b7e9d732376 100644 --- a/go/gazelle/gazelle.py +++ b/go/gen.py @@ -4,13 +4,21 @@ from python.runfiles import runfiles this = pathlib.Path(__file__).resolve() -go_extractor_dir = this.parents[1] / "extractor" -gazelle = runfiles.Create().Rlocation(sys.argv[1]) +go_extractor_dir = this.parent / "extractor" +go_dbscheme = this.parent / "ql" / "lib" / "go.dbscheme" +r = runfiles.Create() +gazelle, go_gen_dbscheme = map(r.Rlocation, sys.argv[1:]) + +print("clearing generated BUILD files") for build_file in go_extractor_dir.glob("*/**/BUILD.bazel"): build_file.unlink() +print("running gazelle") subprocess.check_call([gazelle, "go/extractor"]) +print("adding header to generated BUILD files") for build_file in go_extractor_dir.glob("*/**/BUILD.bazel"): contents = build_file.read_text() build_file.write_text(f"# generated running `bazel run //go/gazelle`, do not edit\n\n{contents}") + +subprocess.check_call([go_gen_dbscheme, go_dbscheme]) From bfa189e2ac2c251518cb61f9665f0970b36e099d Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 26 Apr 2024 13:48:44 +0200 Subject: [PATCH 066/238] Go: use a dbscheme generated during the build in `extractor-pack` --- go/BUILD.bazel | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/go/BUILD.bazel b/go/BUILD.bazel index c5f32c5309f9..d327a406f5fa 100644 --- a/go/BUILD.bazel +++ b/go/BUILD.bazel @@ -21,13 +21,23 @@ py_binary( deps = ["@rules_python//python/runfiles"], ) +# this is an internal copy of the dbscheme to be used by extractor-pack +# this allows the extractor-pack target to be independent and up-to-date with respect to +# having run //go:gen to update the checked in files +genrule( + name = "dbscheme", + outs = ["go.dbscheme"], + cmd = "$(execpath //go/extractor/cli/go-gen-dbscheme) $@", + tools = ["//go/extractor/cli/go-gen-dbscheme"], +) + pkg_files( name = "resources", srcs = [ "LICENSE", "codeql-extractor.yml", - "ql/lib/go.dbscheme", "ql/lib/go.dbscheme.stats", + ":dbscheme", ], ) From 2482519cd3c9b9bd6a17216bed2f86d1a98f6450 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 26 Apr 2024 13:09:59 +0100 Subject: [PATCH 067/238] DataFlow: Cached second level scope. --- shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll | 5 +++-- .../dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index de9f718b347c..10c7efdf045f 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -1119,9 +1119,10 @@ module MakeImpl Lang> { pragma[nomagic] private SndLevelScopeOption getScope(RetNodeEx ret) { - result = SndLevelScopeOption::some(getSecondLevelScope(ret.asNode())) + result = SndLevelScopeOption::some(getSecondLevelScopeCached(ret.asNode())) or - result instanceof SndLevelScopeOption::None and not exists(getSecondLevelScope(ret.asNode())) + result instanceof SndLevelScopeOption::None and + not exists(getSecondLevelScopeCached(ret.asNode())) } pragma[nomagic] diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll index 38c3bba3254f..9524ca9d9aba 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll @@ -616,6 +616,9 @@ module MakeImplCommon Lang> { cached predicate forceCachingInSameStage() { any() } + cached + DataFlowSecondLevelScope getSecondLevelScopeCached(Node n) { result = getSecondLevelScope(n) } + cached predicate nodeEnclosingCallable(Node n, DataFlowCallable c) { c = nodeGetEnclosingCallable(n) } From f95b33049e2dec145af2c47e47cbe08c0bcf3a94 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Thu, 25 Apr 2024 16:44:55 +0200 Subject: [PATCH 068/238] Java: Improve the Api sources and sinks implementation. --- .../semmle/code/java/dataflow/ApiSinks.qll | 143 ++++-------------- .../semmle/code/java/dataflow/ApiSources.qll | 74 ++------- .../semmle/code/java/dataflow/FlowSinks.qll | 18 +++ .../semmle/code/java/dataflow/FlowSources.qll | 15 ++ .../AndroidSensitiveCommunicationQuery.qll | 3 +- .../security/ArbitraryApkInstallation.qll | 5 +- .../CleartextStorageAndroidDatabaseQuery.qll | 6 +- ...CleartextStorageAndroidFilesystemQuery.qll | 8 +- .../security/CleartextStorageCookieQuery.qll | 6 +- .../CleartextStorageSharedPrefsQuery.qll | 6 +- .../ExternallyControlledFormatStringQuery.qll | 3 +- .../java/security/ImplicitPendingIntents.qll | 3 +- .../ImproperIntentVerificationQuery.qll | 3 +- .../code/java/security/InsecureBasicAuth.qll | 3 +- .../code/java/security/InsecureLdapAuth.qll | 3 +- .../java/security/InsecureTrustManager.qll | 5 +- .../IntentUriPermissionManipulation.qll | 3 +- java/ql/lib/semmle/code/java/security/JWT.qll | 6 +- .../code/java/security/JndiInjection.qll | 3 +- .../code/java/security/OgnlInjection.qll | 3 +- .../code/java/security/QueryInjection.qll | 3 +- .../security/SensitiveResultReceiverQuery.qll | 3 +- .../code/java/security/SensitiveUiQuery.qll | 5 +- .../code/java/security/SpelInjection.qll | 3 +- .../java/security/StackTraceExposureQuery.qll | 3 +- ...TempDirLocalInformationDisclosureQuery.qll | 3 +- .../java/security/UnsafeAndroidAccess.qll | 3 +- .../security/UnsafeContentUriResolution.qll | 3 +- .../security/UnsafeDeserializationQuery.qll | 3 +- .../semmle/code/java/security/UrlRedirect.qll | 5 +- .../security/WebviewDebuggingEnabledQuery.qll | 3 +- .../lib/semmle/code/java/security/XPath.qll | 3 +- java/ql/lib/semmle/code/java/security/XSS.qll | 6 +- .../code/java/security/ZipSlipQuery.qll | 3 +- 34 files changed, 154 insertions(+), 214 deletions(-) create mode 100644 java/ql/lib/semmle/code/java/dataflow/FlowSinks.qll diff --git a/java/ql/lib/semmle/code/java/dataflow/ApiSinks.qll b/java/ql/lib/semmle/code/java/dataflow/ApiSinks.qll index 0dae848c15da..c600bb1672d8 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ApiSinks.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ApiSinks.qll @@ -1,122 +1,39 @@ /** Provides classes representing various flow sinks for data flow / taint tracking. */ -private import semmle.code.java.dataflow.DataFlow -private import semmle.code.java.dataflow.ExternalFlow +private import semmle.code.java.dataflow.FlowSinks as FlowSinks -/** - * A data flow sink node. - */ -abstract class SinkNode extends DataFlow::Node { } +final class SinkNode = FlowSinks::ApiSinkNode; /** * Module that adds all API like sinks to `SinkNode`, excluding sinks for cryptography based * queries, and queries where sinks are not succifiently defined (eg. using broad method name matching). */ -private module ApiSinks { - private import semmle.code.java.security.AndroidSensitiveCommunicationQuery as AndroidSensitiveCommunicationQuery - private import semmle.code.java.security.ArbitraryApkInstallation as ArbitraryApkInstallation - private import semmle.code.java.security.CleartextStorageAndroidDatabaseQuery as CleartextStorageAndroidDatabaseQuery - private import semmle.code.java.security.CleartextStorageAndroidFilesystemQuery as CleartextStorageAndroidFilesystemQuery - private import semmle.code.java.security.CleartextStorageCookieQuery as CleartextStorageCookieQuery - private import semmle.code.java.security.CleartextStorageSharedPrefsQuery as CleartextStorageSharedPrefsQuery - private import semmle.code.java.security.ExternallyControlledFormatStringQuery as ExternallyControlledFormatStringQuery - private import semmle.code.java.security.InsecureBasicAuth as InsecureBasicAuth - private import semmle.code.java.security.IntentUriPermissionManipulation as IntentUriPermissionManipulation - private import semmle.code.java.security.InsecureLdapAuth as InsecureLdapAuth - private import semmle.code.java.security.InsecureTrustManager as InsecureTrustManager - private import semmle.code.java.security.JndiInjection as JndiInjection - private import semmle.code.java.security.JWT as Jwt - private import semmle.code.java.security.OgnlInjection as OgnlInjection - private import semmle.code.java.security.SensitiveResultReceiverQuery as SensitiveResultReceiverQuery - private import semmle.code.java.security.SensitiveUiQuery as SensitiveUiQuery - private import semmle.code.java.security.SpelInjection as SpelInjection - private import semmle.code.java.security.SpelInjectionQuery as SpelInjectionQuery - private import semmle.code.java.security.QueryInjection as QueryInjection - private import semmle.code.java.security.TempDirLocalInformationDisclosureQuery as TempDirLocalInformationDisclosureQuery - private import semmle.code.java.security.UnsafeAndroidAccess as UnsafeAndroidAccess - private import semmle.code.java.security.UnsafeContentUriResolution as UnsafeContentUriResolution - private import semmle.code.java.security.UnsafeDeserializationQuery as UnsafeDeserializationQuery - private import semmle.code.java.security.UrlRedirect as UrlRedirect - private import semmle.code.java.security.WebviewDebuggingEnabledQuery as WebviewDebuggingEnabledQuery - private import semmle.code.java.security.XPath as Xpath - private import semmle.code.java.security.XSS as Xss - - private class AndoidIntentRedirectionQuerySinks extends SinkNode instanceof AndroidSensitiveCommunicationQuery::SensitiveCommunicationSink - { } - - private class ArbitraryApkInstallationSinks extends SinkNode instanceof ArbitraryApkInstallation::SetDataSink - { } - - private class CleartextStorageAndroidDatabaseQuerySinks extends SinkNode instanceof CleartextStorageAndroidDatabaseQuery::LocalDatabaseSink - { } - - private class CleartextStorageAndroidFilesystemQuerySinks extends SinkNode instanceof CleartextStorageAndroidFilesystemQuery::LocalFileSink - { } - - private class CleartextStorageCookieQuerySinks extends SinkNode instanceof CleartextStorageCookieQuery::CookieStoreSink - { } - - private class CleartextStorageSharedPrefsQuerySinks extends SinkNode instanceof CleartextStorageSharedPrefsQuery::SharedPreferencesSink - { } - - private class ExternallyControlledFormatStringQuerySinks extends SinkNode instanceof ExternallyControlledFormatStringQuery::StringFormatSink - { } - - private class InsecureBasicAuthSinks extends SinkNode instanceof InsecureBasicAuth::InsecureBasicAuthSink - { } - - private class InsecureTrustManagerSinks extends SinkNode instanceof InsecureTrustManager::InsecureTrustManagerSink - { } - - private class IntentUriPermissionManipulationSinks extends SinkNode instanceof IntentUriPermissionManipulation::IntentUriPermissionManipulationSink - { } - - private class InsecureLdapAuthSinks extends SinkNode instanceof InsecureLdapAuth::InsecureLdapUrlSink - { } - - private class JndiInjectionSinks extends SinkNode instanceof JndiInjection::JndiInjectionSink { } - - private class JwtSinks extends SinkNode instanceof Jwt::JwtParserWithInsecureParseSink { } - - private class OgnlInjectionSinks extends SinkNode instanceof OgnlInjection::OgnlInjectionSink { } - - private class SensitiveResultReceiverQuerySinks extends SinkNode instanceof SensitiveResultReceiverQuery::SensitiveResultReceiverSink - { } - - private class SensitiveUiQuerySinks extends SinkNode instanceof SensitiveUiQuery::TextFieldSink { - } - - private class SpelInjectionSinks extends SinkNode instanceof SpelInjection::SpelExpressionEvaluationSink - { } - - private class QueryInjectionSinks extends SinkNode instanceof QueryInjection::QueryInjectionSink { - } - - private class TempDirLocalInformationDisclosureSinks extends SinkNode instanceof TempDirLocalInformationDisclosureQuery::MethodFileDirectoryCreationSink - { } - - private class UnsafeAndroidAccessSinks extends SinkNode instanceof UnsafeAndroidAccess::UrlResourceSink - { } - - private class UnsafeContentUriResolutionSinks extends SinkNode instanceof UnsafeContentUriResolution::ContentUriResolutionSink - { } - - private class UnsafeDeserializationQuerySinks extends SinkNode instanceof UnsafeDeserializationQuery::UnsafeDeserializationSink - { } - - private class UrlRedirectSinks extends SinkNode instanceof UrlRedirect::UrlRedirectSink { } - - private class WebviewDebugEnabledQuery extends SinkNode instanceof WebviewDebuggingEnabledQuery::WebviewDebugSink - { } - - private class XPathSinks extends SinkNode instanceof Xpath::XPathInjectionSink { } - - private class XssSinks extends SinkNode instanceof Xss::XssSink { } - - /** - * Add all models as data sinks. - */ - private class SinkNodeExternal extends SinkNode { - SinkNodeExternal() { sinkNode(this, _) } - } +private module AllApiSinks { + private import semmle.code.java.security.AndroidSensitiveCommunicationQuery + private import semmle.code.java.security.ArbitraryApkInstallation + private import semmle.code.java.security.CleartextStorageAndroidDatabaseQuery + private import semmle.code.java.security.CleartextStorageAndroidFilesystemQuery + private import semmle.code.java.security.CleartextStorageCookieQuery + private import semmle.code.java.security.CleartextStorageSharedPrefsQuery + private import semmle.code.java.security.ExternallyControlledFormatStringQuery + private import semmle.code.java.security.InsecureBasicAuth + private import semmle.code.java.security.IntentUriPermissionManipulation + private import semmle.code.java.security.InsecureLdapAuth + private import semmle.code.java.security.InsecureTrustManager + private import semmle.code.java.security.JndiInjection + private import semmle.code.java.security.JWT + private import semmle.code.java.security.OgnlInjection + private import semmle.code.java.security.SensitiveResultReceiverQuery + private import semmle.code.java.security.SensitiveUiQuery + private import semmle.code.java.security.SpelInjection + private import semmle.code.java.security.SpelInjectionQuery + private import semmle.code.java.security.QueryInjection + private import semmle.code.java.security.TempDirLocalInformationDisclosureQuery + private import semmle.code.java.security.UnsafeAndroidAccess + private import semmle.code.java.security.UnsafeContentUriResolution + private import semmle.code.java.security.UnsafeDeserializationQuery + private import semmle.code.java.security.UrlRedirect + private import semmle.code.java.security.WebviewDebuggingEnabledQuery + private import semmle.code.java.security.XPath + private import semmle.code.java.security.XSS } diff --git a/java/ql/lib/semmle/code/java/dataflow/ApiSources.qll b/java/ql/lib/semmle/code/java/dataflow/ApiSources.qll index 61025262cb52..5f825ad5445f 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ApiSources.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ApiSources.qll @@ -1,69 +1,23 @@ /** Provides classes representing various flow sources for data flow / taint tracking. */ -private import semmle.code.java.dataflow.DataFlow -private import semmle.code.java.dataflow.ExternalFlow +private import semmle.code.java.dataflow.FlowSources as FlowSources -/** - * A data flow source node. - */ -abstract class SourceNode extends DataFlow::Node { } +final class SourceNode = FlowSources::ApiSourceNode; /** * Module that adds all API like sources to `SourceNode`, excluding some sources for cryptography based * queries, and queries where sources are not succifiently defined (eg. using broad method name matching). */ -private module ApiSources { - private import FlowSources as FlowSources - private import semmle.code.java.security.ArbitraryApkInstallation as ArbitraryApkInstallation - private import semmle.code.java.security.CleartextStorageAndroidDatabaseQuery as CleartextStorageAndroidDatabaseQuery - private import semmle.code.java.security.CleartextStorageAndroidFilesystemQuery as CleartextStorageAndroidFilesystemQuery - private import semmle.code.java.security.CleartextStorageCookieQuery as CleartextStorageCookieQuery - private import semmle.code.java.security.CleartextStorageSharedPrefsQuery as CleartextStorageSharedPrefsQuery - private import semmle.code.java.security.ImplicitPendingIntentsQuery as ImplicitPendingIntentsQuery - private import semmle.code.java.security.ImproperIntentVerificationQuery as ImproperIntentVerificationQuery - private import semmle.code.java.security.InsecureTrustManager as InsecureTrustManager - private import semmle.code.java.security.JWT as Jwt - private import semmle.code.java.security.StackTraceExposureQuery as StackTraceExposureQuery - private import semmle.code.java.security.ZipSlipQuery as ZipSlipQuery - - private class FlowSourcesSourceNode extends SourceNode instanceof FlowSources::SourceNode { } - - private class ArbitraryApkInstallationSources extends SourceNode instanceof ArbitraryApkInstallation::ExternalApkSource - { } - - private class CleartextStorageAndroidDatabaseQuerySources extends SourceNode instanceof CleartextStorageAndroidDatabaseQuery::LocalDatabaseOpenMethodCallSource - { } - - private class CleartextStorageAndroidFilesystemQuerySources extends SourceNode instanceof CleartextStorageAndroidFilesystemQuery::LocalFileOpenCallSource - { } - - private class CleartextStorageCookieQuerySources extends SourceNode instanceof CleartextStorageCookieQuery::CookieSource - { } - - private class CleartextStorageSharedPrefsQuerySources extends SourceNode instanceof CleartextStorageSharedPrefsQuery::SharedPreferencesEditorMethodCallSource - { } - - private class ImplicitPendingIntentsQuerySources extends SourceNode instanceof ImplicitPendingIntentsQuery::ImplicitPendingIntentSource - { } - - private class ImproperIntentVerificationQuerySources extends SourceNode instanceof ImproperIntentVerificationQuery::VerifiedIntentConfigSource - { } - - private class InsecureTrustManagerSources extends SourceNode instanceof InsecureTrustManager::InsecureTrustManagerSource - { } - - private class JwtSources extends SourceNode instanceof Jwt::JwtParserWithInsecureParseSource { } - - private class StackTraceExposureQuerySources extends SourceNode instanceof StackTraceExposureQuery::GetMessageFlowSource - { } - - private class ZipSlipQuerySources extends SourceNode instanceof ZipSlipQuery::ArchiveEntryNameMethodSource - { } - - /** - * Add all models as data sources. - */ - private class SourceNodeExternal extends SourceNode { - SourceNodeExternal() { sourceNode(this, _) } - } +private module AllApiSources { + private import semmle.code.java.security.ArbitraryApkInstallation + private import semmle.code.java.security.CleartextStorageAndroidDatabaseQuery + private import semmle.code.java.security.CleartextStorageAndroidFilesystemQuery + private import semmle.code.java.security.CleartextStorageCookieQuery + private import semmle.code.java.security.CleartextStorageSharedPrefsQuery + private import semmle.code.java.security.ImplicitPendingIntentsQuery + private import semmle.code.java.security.ImproperIntentVerificationQuery + private import semmle.code.java.security.InsecureTrustManager + private import semmle.code.java.security.JWT + private import semmle.code.java.security.StackTraceExposureQuery + private import semmle.code.java.security.ZipSlipQuery } diff --git a/java/ql/lib/semmle/code/java/dataflow/FlowSinks.qll b/java/ql/lib/semmle/code/java/dataflow/FlowSinks.qll new file mode 100644 index 000000000000..3b7fd191779c --- /dev/null +++ b/java/ql/lib/semmle/code/java/dataflow/FlowSinks.qll @@ -0,0 +1,18 @@ +/** Provides classes representing various flow sinks for data flow / taint tracking. */ + +private import java +private import semmle.code.java.dataflow.ExternalFlow +private import semmle.code.java.dataflow.DataFlow + +/** + * A data flow sink node for an API, which should be considered + * supported for a modeling perspective. + */ +abstract class ApiSinkNode extends DataFlow::Node { } + +/** + * Add all models as data sinks. + */ +private class ApiSinkNodeExternal extends ApiSinkNode { + ApiSinkNodeExternal() { sinkNode(this, _) } +} diff --git a/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll b/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll index 49d7bda4e448..f28cc9984871 100644 --- a/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll +++ b/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll @@ -387,3 +387,18 @@ class AndroidJavascriptInterfaceMethodParameter extends RemoteFlowSource { result = "Parameter of method with JavascriptInterface annotation" } } + +/** + * A data flow source node for an API, which should be considered + * supported for a modeling perspective. + */ +abstract class ApiSourceNode extends DataFlow::Node { } + +private class AddSourceNodes extends ApiSourceNode instanceof SourceNode { } + +/** + * Add all models as data sources. + */ +private class ApiSourceNodeExternal extends ApiSourceNode { + ApiSourceNodeExternal() { sourceNode(this, _) } +} diff --git a/java/ql/lib/semmle/code/java/security/AndroidSensitiveCommunicationQuery.qll b/java/ql/lib/semmle/code/java/security/AndroidSensitiveCommunicationQuery.qll index 9773d00849fd..607ced09b2cf 100644 --- a/java/ql/lib/semmle/code/java/security/AndroidSensitiveCommunicationQuery.qll +++ b/java/ql/lib/semmle/code/java/security/AndroidSensitiveCommunicationQuery.qll @@ -4,6 +4,7 @@ import java import semmle.code.java.dataflow.TaintTracking import semmle.code.java.frameworks.android.Intent import semmle.code.java.security.SensitiveActions +private import semmle.code.java.dataflow.FlowSinks /** * Gets regular expression for matching names of Android variables that indicate the value being held contains sensitive information. @@ -154,7 +155,7 @@ deprecated class SensitiveCommunicationConfig extends TaintTracking::Configurati /** * A class of sensitive communication sink nodes. */ -class SensitiveCommunicationSink extends DataFlow::Node { +class SensitiveCommunicationSink extends ApiSinkNode { SensitiveCommunicationSink() { isSensitiveBroadcastSink(this) or diff --git a/java/ql/lib/semmle/code/java/security/ArbitraryApkInstallation.qll b/java/ql/lib/semmle/code/java/security/ArbitraryApkInstallation.qll index 3aa59286fcd0..d7c5fe94f28a 100644 --- a/java/ql/lib/semmle/code/java/security/ArbitraryApkInstallation.qll +++ b/java/ql/lib/semmle/code/java/security/ArbitraryApkInstallation.qll @@ -4,6 +4,7 @@ import java import semmle.code.java.frameworks.android.Intent import semmle.code.java.dataflow.DataFlow private import semmle.code.java.dataflow.ExternalFlow +private import semmle.code.java.dataflow.FlowSinks private import semmle.code.java.dataflow.FlowSources /** A string literal that represents the MIME type for Android APKs. */ @@ -48,7 +49,7 @@ class SetDataMethod extends Method { } /** A dataflow sink for the URI of an intent. */ -class SetDataSink extends DataFlow::ExprNode { +class SetDataSink extends ApiSinkNode, DataFlow::ExprNode { SetDataSink() { exists(MethodCall ma | this.getExpr() = ma.getQualifier() and @@ -69,7 +70,7 @@ class UriConstructorMethod extends Method { * A dataflow source representing the URIs which an APK not controlled by the * application may come from. Including external storage and web URLs. */ -class ExternalApkSource extends DataFlow::Node { +class ExternalApkSource extends ApiSourceNode { ExternalApkSource() { sourceNode(this, "android-external-storage-dir") or this.asExpr().(MethodCall).getMethod() instanceof UriConstructorMethod or diff --git a/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidDatabaseQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidDatabaseQuery.qll index 5d212ea45f23..b4162f2c6957 100644 --- a/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidDatabaseQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidDatabaseQuery.qll @@ -6,6 +6,8 @@ import semmle.code.java.frameworks.android.ContentProviders import semmle.code.java.frameworks.android.Intent import semmle.code.java.frameworks.android.SQLite import semmle.code.java.security.CleartextStorageQuery +private import semmle.code.java.dataflow.FlowSinks +private import semmle.code.java.dataflow.FlowSources private class LocalDatabaseCleartextStorageSink extends CleartextStorageSink { LocalDatabaseCleartextStorageSink() { localDatabaseInput(_, this.asExpr()) } @@ -99,14 +101,14 @@ private predicate localDatabaseStore(DataFlow::Node database, MethodCall store) /** * A class of local database open method call source nodes. */ -class LocalDatabaseOpenMethodCallSource extends DataFlow::Node { +class LocalDatabaseOpenMethodCallSource extends ApiSourceNode { LocalDatabaseOpenMethodCallSource() { this.asExpr() instanceof LocalDatabaseOpenMethodCall } } /** * A class of local database sink nodes. */ -class LocalDatabaseSink extends DataFlow::Node { +class LocalDatabaseSink extends ApiSinkNode { LocalDatabaseSink() { localDatabaseInput(this, _) or localDatabaseStore(this, _) } } diff --git a/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidFilesystemQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidFilesystemQuery.qll index 90749120fce6..8b1af7b4971f 100644 --- a/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidFilesystemQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidFilesystemQuery.qll @@ -5,9 +5,11 @@ import java import semmle.code.java.dataflow.DataFlow -private import semmle.code.java.dataflow.ExternalFlow import semmle.code.java.security.CleartextStorageQuery import semmle.code.xml.AndroidManifest +private import semmle.code.java.dataflow.ExternalFlow +private import semmle.code.java.dataflow.FlowSinks +private import semmle.code.java.dataflow.FlowSources private class AndroidFilesystemCleartextStorageSink extends CleartextStorageSink { AndroidFilesystemCleartextStorageSink() { @@ -82,14 +84,14 @@ private class CloseFileMethod extends Method { /** * A class of local file open call source nodes. */ -class LocalFileOpenCallSource extends DataFlow::Node { +class LocalFileOpenCallSource extends ApiSourceNode { LocalFileOpenCallSource() { this.asExpr() instanceof LocalFileOpenCall } } /** * A class of local file sink nodes. */ -class LocalFileSink extends DataFlow::Node { +class LocalFileSink extends ApiSinkNode { LocalFileSink() { filesystemInput(this, _) or closesFile(this, _) diff --git a/java/ql/lib/semmle/code/java/security/CleartextStorageCookieQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStorageCookieQuery.qll index 379d52eb5497..c3684646bdd3 100644 --- a/java/ql/lib/semmle/code/java/security/CleartextStorageCookieQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CleartextStorageCookieQuery.qll @@ -4,6 +4,8 @@ import java import semmle.code.java.dataflow.DataFlow deprecated import semmle.code.java.dataflow.DataFlow3 import semmle.code.java.security.CleartextStorageQuery +private import semmle.code.java.dataflow.FlowSinks +private import semmle.code.java.dataflow.FlowSources private class CookieCleartextStorageSink extends CleartextStorageSink { CookieCleartextStorageSink() { this.asExpr() = cookieInput(_) } @@ -40,14 +42,14 @@ private predicate cookieStore(DataFlow::Node cookie, Expr store) { /** * A class of cookie source nodes. */ -class CookieSource extends DataFlow::Node { +class CookieSource extends ApiSourceNode { CookieSource() { this.asExpr() instanceof Cookie } } /** * A class of cookie store sink nodes. */ -class CookieStoreSink extends DataFlow::Node { +class CookieStoreSink extends ApiSinkNode { CookieStoreSink() { cookieStore(this, _) } } diff --git a/java/ql/lib/semmle/code/java/security/CleartextStorageSharedPrefsQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStorageSharedPrefsQuery.qll index c09fb3cc61a6..80dc2fca1f4f 100644 --- a/java/ql/lib/semmle/code/java/security/CleartextStorageSharedPrefsQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CleartextStorageSharedPrefsQuery.qll @@ -4,6 +4,8 @@ import java import semmle.code.java.dataflow.DataFlow import semmle.code.java.frameworks.android.SharedPreferences import semmle.code.java.security.CleartextStorageQuery +private import semmle.code.java.dataflow.FlowSinks +private import semmle.code.java.dataflow.FlowSources private class SharedPrefsCleartextStorageSink extends CleartextStorageSink { SharedPrefsCleartextStorageSink() { @@ -70,7 +72,7 @@ private predicate sharedPreferencesStore(DataFlow::Node editor, MethodCall m) { /** * A shared preferences editor method call source nodes. */ -class SharedPreferencesEditorMethodCallSource extends DataFlow::Node { +class SharedPreferencesEditorMethodCallSource extends ApiSourceNode { SharedPreferencesEditorMethodCallSource() { this.asExpr() instanceof SharedPreferencesEditorMethodCall } @@ -79,7 +81,7 @@ class SharedPreferencesEditorMethodCallSource extends DataFlow::Node { /** * A class of shared preferences sink nodes. */ -class SharedPreferencesSink extends DataFlow::Node { +class SharedPreferencesSink extends ApiSinkNode { SharedPreferencesSink() { sharedPreferencesInput(this, _) or sharedPreferencesStore(this, _) diff --git a/java/ql/lib/semmle/code/java/security/ExternallyControlledFormatStringQuery.qll b/java/ql/lib/semmle/code/java/security/ExternallyControlledFormatStringQuery.qll index 2fc622325dea..8d6fe0426c3c 100644 --- a/java/ql/lib/semmle/code/java/security/ExternallyControlledFormatStringQuery.qll +++ b/java/ql/lib/semmle/code/java/security/ExternallyControlledFormatStringQuery.qll @@ -1,13 +1,14 @@ /** Provides a taint-tracking configuration to reason about externally controlled format string vulnerabilities. */ import java +private import semmle.code.java.dataflow.FlowSinks private import semmle.code.java.dataflow.FlowSources private import semmle.code.java.StringFormat /** * A class of string format sink nodes. */ -class StringFormatSink extends DataFlow::Node { +class StringFormatSink extends ApiSinkNode { StringFormatSink() { this.asExpr() = any(StringFormat formatCall).getFormatArgument() } } diff --git a/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll b/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll index 4cac7715b98a..5c4094de3d32 100644 --- a/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll +++ b/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll @@ -2,6 +2,7 @@ import java private import semmle.code.java.dataflow.ExternalFlow +private import semmle.code.java.dataflow.FlowSources private import semmle.code.java.dataflow.TaintTracking private import semmle.code.java.frameworks.android.Intent private import semmle.code.java.frameworks.android.PendingIntent @@ -27,7 +28,7 @@ class NoState extends PendingIntentState, TNoState { } /** A source for an implicit `PendingIntent` flow. */ -abstract class ImplicitPendingIntentSource extends DataFlow::Node { +abstract class ImplicitPendingIntentSource extends ApiSourceNode { /** * DEPRECATED: Open-ended flow state is not intended to be part of the extension points. * diff --git a/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll b/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll index 92bcac5b50e0..e8bfc97b0fc9 100644 --- a/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll +++ b/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll @@ -4,6 +4,7 @@ import java import semmle.code.java.dataflow.DataFlow import semmle.code.xml.AndroidManifest import semmle.code.java.frameworks.android.Intent +private import semmle.code.java.dataflow.FlowSources /** An `onReceive` method of a `BroadcastReceiver` */ private class OnReceiveMethod extends Method { @@ -16,7 +17,7 @@ private class OnReceiveMethod extends Method { /** * A class of verified intent source nodes. */ -class VerifiedIntentConfigSource extends DataFlow::Node { +class VerifiedIntentConfigSource extends ApiSourceNode { VerifiedIntentConfigSource() { this.asParameter() = any(OnReceiveMethod orm).getIntentParameter() } diff --git a/java/ql/lib/semmle/code/java/security/InsecureBasicAuth.qll b/java/ql/lib/semmle/code/java/security/InsecureBasicAuth.qll index df9b6bdf4a11..b21492406adf 100644 --- a/java/ql/lib/semmle/code/java/security/InsecureBasicAuth.qll +++ b/java/ql/lib/semmle/code/java/security/InsecureBasicAuth.qll @@ -4,6 +4,7 @@ import java import semmle.code.java.dataflow.DataFlow import semmle.code.java.dataflow.TaintTracking import semmle.code.java.security.HttpsUrls +private import semmle.code.java.dataflow.FlowSinks /** * A source that represents HTTP URLs. @@ -20,7 +21,7 @@ private class DefaultInsecureBasicAuthSource extends InsecureBasicAuthSource { * A sink that represents a method that sets Basic Authentication. * Extend this class to add your own Insecure Basic Authentication sinks. */ -abstract class InsecureBasicAuthSink extends DataFlow::Node { } +abstract class InsecureBasicAuthSink extends ApiSinkNode { } /** A default sink representing methods that set an Authorization header. */ private class DefaultInsecureBasicAuthSink extends InsecureBasicAuthSink { diff --git a/java/ql/lib/semmle/code/java/security/InsecureLdapAuth.qll b/java/ql/lib/semmle/code/java/security/InsecureLdapAuth.qll index 9a8cd91b1fcf..52d58afc9e76 100644 --- a/java/ql/lib/semmle/code/java/security/InsecureLdapAuth.qll +++ b/java/ql/lib/semmle/code/java/security/InsecureLdapAuth.qll @@ -2,6 +2,7 @@ import java private import semmle.code.java.dataflow.DataFlow +private import semmle.code.java.dataflow.FlowSinks private import semmle.code.java.frameworks.Networking private import semmle.code.java.frameworks.Jndi @@ -32,7 +33,7 @@ class InsecureLdapUrl extends Expr { /** * A sink representing the construction of a `DirContextEnvironment`. */ -class InsecureLdapUrlSink extends DataFlow::Node { +class InsecureLdapUrlSink extends ApiSinkNode { InsecureLdapUrlSink() { exists(ConstructorCall cc | cc.getConstructedType().getAnAncestor() instanceof TypeDirContext and diff --git a/java/ql/lib/semmle/code/java/security/InsecureTrustManager.qll b/java/ql/lib/semmle/code/java/security/InsecureTrustManager.qll index d82f088cf155..41d8f28573ca 100644 --- a/java/ql/lib/semmle/code/java/security/InsecureTrustManager.qll +++ b/java/ql/lib/semmle/code/java/security/InsecureTrustManager.qll @@ -2,11 +2,12 @@ import java private import semmle.code.java.controlflow.Guards +private import semmle.code.java.dataflow.FlowSinks private import semmle.code.java.security.Encryption private import semmle.code.java.security.SecurityFlag /** The creation of an insecure `TrustManager`. */ -abstract class InsecureTrustManagerSource extends DataFlow::Node { } +abstract class InsecureTrustManagerSource extends ApiSourceNode { } private class DefaultInsecureTrustManagerSource extends InsecureTrustManagerSource { DefaultInsecureTrustManagerSource() { @@ -18,7 +19,7 @@ private class DefaultInsecureTrustManagerSource extends InsecureTrustManagerSour * The use of a `TrustManager` in an SSL context. * Intentionally insecure connections are not considered sinks. */ -abstract class InsecureTrustManagerSink extends DataFlow::Node { +abstract class InsecureTrustManagerSink extends ApiSinkNode { InsecureTrustManagerSink() { not isGuardedByInsecureFlag(this) } } diff --git a/java/ql/lib/semmle/code/java/security/IntentUriPermissionManipulation.qll b/java/ql/lib/semmle/code/java/security/IntentUriPermissionManipulation.qll index 4309af8b3c80..2f9470f2bb9a 100644 --- a/java/ql/lib/semmle/code/java/security/IntentUriPermissionManipulation.qll +++ b/java/ql/lib/semmle/code/java/security/IntentUriPermissionManipulation.qll @@ -6,6 +6,7 @@ import java private import semmle.code.java.controlflow.Guards private import semmle.code.java.dataflow.DataFlow +private import semmle.code.java.dataflow.FlowSinks private import semmle.code.java.dataflow.TaintTracking private import semmle.code.java.frameworks.android.Android private import semmle.code.java.frameworks.android.Intent @@ -14,7 +15,7 @@ private import semmle.code.java.frameworks.android.Intent * A sink for Intent URI permission manipulation vulnerabilities in Android, * that is, method calls that return an Intent as the result of an Activity. */ -abstract class IntentUriPermissionManipulationSink extends DataFlow::Node { } +abstract class IntentUriPermissionManipulationSink extends ApiSinkNode { } /** * A sanitizer that makes sure that an Intent is safe to be returned to another Activity. diff --git a/java/ql/lib/semmle/code/java/security/JWT.qll b/java/ql/lib/semmle/code/java/security/JWT.qll index 183495d85652..c84ebffabdbd 100644 --- a/java/ql/lib/semmle/code/java/security/JWT.qll +++ b/java/ql/lib/semmle/code/java/security/JWT.qll @@ -2,9 +2,11 @@ import java private import semmle.code.java.dataflow.DataFlow +private import semmle.code.java.dataflow.FlowSinks +private import semmle.code.java.dataflow.FlowSources /** A method access that assigns signing keys to a JWT parser. */ -class JwtParserWithInsecureParseSource extends DataFlow::Node { +class JwtParserWithInsecureParseSource extends ApiSourceNode { JwtParserWithInsecureParseSource() { exists(MethodCall ma, Method m | m.getDeclaringType().getAnAncestor() instanceof TypeJwtParser or @@ -24,7 +26,7 @@ class JwtParserWithInsecureParseSource extends DataFlow::Node { * the qualifier of a call to a `parse(token, handler)` method * where the `handler` is considered insecure. */ -class JwtParserWithInsecureParseSink extends DataFlow::Node { +class JwtParserWithInsecureParseSink extends ApiSinkNode { MethodCall insecureParseMa; JwtParserWithInsecureParseSink() { diff --git a/java/ql/lib/semmle/code/java/security/JndiInjection.qll b/java/ql/lib/semmle/code/java/security/JndiInjection.qll index d7282996057d..3df8d6df378e 100644 --- a/java/ql/lib/semmle/code/java/security/JndiInjection.qll +++ b/java/ql/lib/semmle/code/java/security/JndiInjection.qll @@ -3,11 +3,12 @@ import java private import semmle.code.java.dataflow.DataFlow private import semmle.code.java.dataflow.ExternalFlow +private import semmle.code.java.dataflow.FlowSinks private import semmle.code.java.frameworks.Jndi private import semmle.code.java.frameworks.SpringLdap /** A data flow sink for unvalidated user input that is used in JNDI lookup. */ -abstract class JndiInjectionSink extends DataFlow::Node { } +abstract class JndiInjectionSink extends ApiSinkNode { } /** A sanitizer for JNDI injection vulnerabilities. */ abstract class JndiInjectionSanitizer extends DataFlow::Node { } diff --git a/java/ql/lib/semmle/code/java/security/OgnlInjection.qll b/java/ql/lib/semmle/code/java/security/OgnlInjection.qll index d5297702bef4..37f31618fc32 100644 --- a/java/ql/lib/semmle/code/java/security/OgnlInjection.qll +++ b/java/ql/lib/semmle/code/java/security/OgnlInjection.qll @@ -2,6 +2,7 @@ import java private import semmle.code.java.dataflow.DataFlow +private import semmle.code.java.dataflow.FlowSinks private import semmle.code.java.dataflow.ExternalFlow private import semmle.code.java.frameworks.MyBatis @@ -10,7 +11,7 @@ private import semmle.code.java.frameworks.MyBatis * * Extend this class to add your own OGNL injection sinks. */ -abstract class OgnlInjectionSink extends DataFlow::Node { } +abstract class OgnlInjectionSink extends ApiSinkNode { } /** * A unit class for adding additional taint steps. diff --git a/java/ql/lib/semmle/code/java/security/QueryInjection.qll b/java/ql/lib/semmle/code/java/security/QueryInjection.qll index aa92aa16a14c..df316155ba1a 100644 --- a/java/ql/lib/semmle/code/java/security/QueryInjection.qll +++ b/java/ql/lib/semmle/code/java/security/QueryInjection.qll @@ -5,9 +5,10 @@ import semmle.code.java.dataflow.DataFlow import semmle.code.java.frameworks.javaee.Persistence private import semmle.code.java.frameworks.MyBatis private import semmle.code.java.dataflow.ExternalFlow +private import semmle.code.java.dataflow.FlowSinks /** A sink for database query language injection vulnerabilities. */ -abstract class QueryInjectionSink extends DataFlow::Node { } +abstract class QueryInjectionSink extends ApiSinkNode { } /** * A unit class for adding additional taint steps. diff --git a/java/ql/lib/semmle/code/java/security/SensitiveResultReceiverQuery.qll b/java/ql/lib/semmle/code/java/security/SensitiveResultReceiverQuery.qll index 13a4b562a50e..c0179860a01d 100644 --- a/java/ql/lib/semmle/code/java/security/SensitiveResultReceiverQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SensitiveResultReceiverQuery.qll @@ -4,6 +4,7 @@ import java import semmle.code.java.dataflow.TaintTracking import semmle.code.java.dataflow.FlowSources import semmle.code.java.security.SensitiveActions +private import semmle.code.java.dataflow.FlowSinks private class ResultReceiverSendCall extends MethodCall { ResultReceiverSendCall() { @@ -53,7 +54,7 @@ deprecated private class SensitiveResultReceiverConf extends TaintTracking::Conf /** * A class of sensitive result receiver sink nodes. */ -class SensitiveResultReceiverSink extends DataFlow::Node { +class SensitiveResultReceiverSink extends ApiSinkNode { SensitiveResultReceiverSink() { exists(ResultReceiverSendCall call | untrustedResultReceiverSend(_, call) and diff --git a/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll b/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll index 884ab40a3239..f9ff3f240409 100644 --- a/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll @@ -2,6 +2,7 @@ import java private import semmle.code.java.dataflow.ExternalFlow +private import semmle.code.java.dataflow.FlowSinks private import semmle.code.java.dataflow.TaintTracking private import semmle.code.java.security.SensitiveActions private import semmle.code.java.frameworks.android.Layout @@ -54,9 +55,9 @@ private class MaskCall extends MethodCall { } /** - * A class of test field sink nodes. + * A class of text field sink nodes. */ -class TextFieldSink extends DataFlow::Node { +class TextFieldSink extends ApiSinkNode { TextFieldSink() { exists(SetTextCall call | this.asExpr() = call.getStringArgument() and diff --git a/java/ql/lib/semmle/code/java/security/SpelInjection.qll b/java/ql/lib/semmle/code/java/security/SpelInjection.qll index 1aed2049afe4..13eb195eae46 100644 --- a/java/ql/lib/semmle/code/java/security/SpelInjection.qll +++ b/java/ql/lib/semmle/code/java/security/SpelInjection.qll @@ -2,10 +2,11 @@ import java private import semmle.code.java.dataflow.DataFlow +private import semmle.code.java.dataflow.FlowSinks private import semmle.code.java.frameworks.spring.SpringExpression /** A data flow sink for unvalidated user input that is used to construct SpEL expressions. */ -abstract class SpelExpressionEvaluationSink extends DataFlow::ExprNode { } +abstract class SpelExpressionEvaluationSink extends ApiSinkNode, DataFlow::ExprNode { } /** * A unit class for adding additional taint steps. diff --git a/java/ql/lib/semmle/code/java/security/StackTraceExposureQuery.qll b/java/ql/lib/semmle/code/java/security/StackTraceExposureQuery.qll index 2e4b31b7785e..5de0b0098e93 100644 --- a/java/ql/lib/semmle/code/java/security/StackTraceExposureQuery.qll +++ b/java/ql/lib/semmle/code/java/security/StackTraceExposureQuery.qll @@ -2,6 +2,7 @@ import java private import semmle.code.java.dataflow.DataFlow +private import semmle.code.java.dataflow.FlowSources private import semmle.code.java.dataflow.TaintTracking private import semmle.code.java.security.InformationLeak @@ -98,7 +99,7 @@ predicate stringifiedStackFlowsExternally(DataFlow::Node externalExpr, Expr stac /** * A class of get message source nodes. */ -class GetMessageFlowSource extends DataFlow::Node { +class GetMessageFlowSource extends ApiSourceNode { GetMessageFlowSource() { exists(Method method | this.asExpr().(MethodCall).getMethod() = method | method.hasName("getMessage") and diff --git a/java/ql/lib/semmle/code/java/security/TempDirLocalInformationDisclosureQuery.qll b/java/ql/lib/semmle/code/java/security/TempDirLocalInformationDisclosureQuery.qll index 970363fe5439..96db99fe1b4a 100644 --- a/java/ql/lib/semmle/code/java/security/TempDirLocalInformationDisclosureQuery.qll +++ b/java/ql/lib/semmle/code/java/security/TempDirLocalInformationDisclosureQuery.qll @@ -1,6 +1,7 @@ /** Provides classes to reason about local information disclosure in a temporary directory. */ import java +private import semmle.code.java.dataflow.FlowSinks private import semmle.code.java.dataflow.TaintTracking private import semmle.code.java.os.OSCheck private import semmle.code.java.security.TempDirUtils @@ -156,7 +157,7 @@ module TempDirSystemGetPropertyToCreate = /** * A class of method file directory creation sink nodes. */ -class MethodFileDirectoryCreationSink extends DataFlow::Node { +class MethodFileDirectoryCreationSink extends ApiSinkNode { MethodFileDirectoryCreationSink() { exists(MethodCall ma | ma.getMethod() instanceof MethodFileDirectoryCreation | ma.getQualifier() = this.asExpr() diff --git a/java/ql/lib/semmle/code/java/security/UnsafeAndroidAccess.qll b/java/ql/lib/semmle/code/java/security/UnsafeAndroidAccess.qll index 499475cff3ec..afd3af221bed 100644 --- a/java/ql/lib/semmle/code/java/security/UnsafeAndroidAccess.qll +++ b/java/ql/lib/semmle/code/java/security/UnsafeAndroidAccess.qll @@ -4,6 +4,7 @@ import java private import semmle.code.java.dataflow.DataFlow +private import semmle.code.java.dataflow.FlowSinks private import semmle.code.java.frameworks.android.WebView private import semmle.code.java.frameworks.kotlin.Kotlin @@ -12,7 +13,7 @@ private import semmle.code.java.frameworks.kotlin.Kotlin * * Extend this class to add your own Unsafe Resource Fetching sinks. */ -abstract class UrlResourceSink extends DataFlow::Node { +abstract class UrlResourceSink extends ApiSinkNode { /** * Gets a description of this vulnerability. */ diff --git a/java/ql/lib/semmle/code/java/security/UnsafeContentUriResolution.qll b/java/ql/lib/semmle/code/java/security/UnsafeContentUriResolution.qll index 5537add5a2ca..b19d06bbf88c 100644 --- a/java/ql/lib/semmle/code/java/security/UnsafeContentUriResolution.qll +++ b/java/ql/lib/semmle/code/java/security/UnsafeContentUriResolution.qll @@ -1,13 +1,14 @@ /** Provides classes to reason about vulnerabilites related to content URIs. */ import java +private import semmle.code.java.dataflow.FlowSinks private import semmle.code.java.dataflow.TaintTracking private import semmle.code.java.frameworks.android.Android private import semmle.code.java.security.PathSanitizer private import semmle.code.java.security.Sanitizers /** A URI that gets resolved by a `ContentResolver`. */ -abstract class ContentUriResolutionSink extends DataFlow::Node { } +abstract class ContentUriResolutionSink extends ApiSinkNode { } /** A sanitizer for content URIs. */ abstract class ContentUriResolutionSanitizer extends DataFlow::Node { } diff --git a/java/ql/lib/semmle/code/java/security/UnsafeDeserializationQuery.qll b/java/ql/lib/semmle/code/java/security/UnsafeDeserializationQuery.qll index 272c483f7a21..734ad4c89fe6 100644 --- a/java/ql/lib/semmle/code/java/security/UnsafeDeserializationQuery.qll +++ b/java/ql/lib/semmle/code/java/security/UnsafeDeserializationQuery.qll @@ -3,6 +3,7 @@ */ import semmle.code.java.dataflow.FlowSources +private import semmle.code.java.dataflow.FlowSinks private import semmle.code.java.dataflow.TaintTracking2 private import semmle.code.java.dispatch.VirtualDispatch private import semmle.code.java.frameworks.Kryo @@ -235,7 +236,7 @@ predicate unsafeDeserialization(MethodCall ma, Expr sink) { } /** A sink for unsafe deserialization. */ -class UnsafeDeserializationSink extends DataFlow::ExprNode { +class UnsafeDeserializationSink extends ApiSinkNode, DataFlow::ExprNode { UnsafeDeserializationSink() { unsafeDeserialization(_, this.getExpr()) } /** Gets a call that triggers unsafe deserialization. */ diff --git a/java/ql/lib/semmle/code/java/security/UrlRedirect.qll b/java/ql/lib/semmle/code/java/security/UrlRedirect.qll index e806905c1674..02f66e3f0e95 100644 --- a/java/ql/lib/semmle/code/java/security/UrlRedirect.qll +++ b/java/ql/lib/semmle/code/java/security/UrlRedirect.qll @@ -2,14 +2,15 @@ import java import semmle.code.java.dataflow.DataFlow -private import semmle.code.java.dataflow.ExternalFlow import semmle.code.java.frameworks.Servlets import semmle.code.java.frameworks.ApacheHttp +private import semmle.code.java.dataflow.ExternalFlow +private import semmle.code.java.dataflow.FlowSinks private import semmle.code.java.frameworks.JaxWS private import semmle.code.java.security.RequestForgery /** A URL redirection sink. */ -abstract class UrlRedirectSink extends DataFlow::Node { } +abstract class UrlRedirectSink extends ApiSinkNode { } /** A URL redirection sanitizer. */ abstract class UrlRedirectSanitizer extends DataFlow::Node { } diff --git a/java/ql/lib/semmle/code/java/security/WebviewDebuggingEnabledQuery.qll b/java/ql/lib/semmle/code/java/security/WebviewDebuggingEnabledQuery.qll index d2a21be95e0a..c7fd51b1c367 100644 --- a/java/ql/lib/semmle/code/java/security/WebviewDebuggingEnabledQuery.qll +++ b/java/ql/lib/semmle/code/java/security/WebviewDebuggingEnabledQuery.qll @@ -4,6 +4,7 @@ import java import semmle.code.java.dataflow.DataFlow import semmle.code.java.controlflow.Guards import semmle.code.java.security.SecurityTests +private import semmle.code.java.dataflow.FlowSinks /** Holds if `ex` looks like a check that this is a debug build. */ private predicate isDebugCheck(Expr ex) { @@ -47,7 +48,7 @@ deprecated class WebviewDebugEnabledConfig extends DataFlow::Configuration { /** * A class of webview debug sink nodes. */ -class WebviewDebugSink extends DataFlow::Node { +class WebviewDebugSink extends ApiSinkNode { WebviewDebugSink() { exists(MethodCall ma | ma.getMethod().hasQualifiedName("android.webkit", "WebView", "setWebContentsDebuggingEnabled") and diff --git a/java/ql/lib/semmle/code/java/security/XPath.qll b/java/ql/lib/semmle/code/java/security/XPath.qll index 573d6530b330..c2992fdc272a 100644 --- a/java/ql/lib/semmle/code/java/security/XPath.qll +++ b/java/ql/lib/semmle/code/java/security/XPath.qll @@ -3,12 +3,13 @@ import java import semmle.code.java.dataflow.DataFlow private import semmle.code.java.dataflow.ExternalFlow +private import semmle.code.java.dataflow.FlowSinks /** * A sink that represents a method that interprets XPath expressions. * Extend this class to add your own XPath Injection sinks. */ -abstract class XPathInjectionSink extends DataFlow::Node { } +abstract class XPathInjectionSink extends ApiSinkNode { } /** A default sink representing methods susceptible to XPath Injection attacks. */ private class DefaultXPathInjectionSink extends XPathInjectionSink { diff --git a/java/ql/lib/semmle/code/java/security/XSS.qll b/java/ql/lib/semmle/code/java/security/XSS.qll index aa69e5e7865f..daf025141f5f 100644 --- a/java/ql/lib/semmle/code/java/security/XSS.qll +++ b/java/ql/lib/semmle/code/java/security/XSS.qll @@ -10,9 +10,11 @@ private import semmle.code.java.frameworks.hudson.Hudson import semmle.code.java.dataflow.DataFlow import semmle.code.java.dataflow.TaintTracking private import semmle.code.java.dataflow.ExternalFlow +private import semmle.code.java.dataflow.FlowSources +private import semmle.code.java.dataflow.FlowSinks /** A sink that represent a method that outputs data without applying contextual output encoding. */ -abstract class XssSink extends DataFlow::Node { } +abstract class XssSink extends ApiSinkNode { } /** A sanitizer that neutralizes dangerous characters that can be used to perform a XSS attack. */ abstract class XssSanitizer extends DataFlow::Node { } @@ -108,7 +110,7 @@ class XssVulnerableWriterSource extends MethodCall { /** * A class of xss vulnerable writer source nodes. */ -class XssVulnerableWriterSourceNode extends DataFlow::Node { +class XssVulnerableWriterSourceNode extends ApiSourceNode { XssVulnerableWriterSourceNode() { this.asExpr() instanceof XssVulnerableWriterSource } } diff --git a/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll b/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll index f6f3b1bf27c4..0ab889f73725 100644 --- a/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll +++ b/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll @@ -4,6 +4,7 @@ import java import semmle.code.java.dataflow.TaintTracking import semmle.code.java.security.PathSanitizer private import semmle.code.java.dataflow.ExternalFlow +private import semmle.code.java.dataflow.FlowSources private import semmle.code.java.security.PathCreation /** @@ -24,7 +25,7 @@ private class ArchiveEntryNameMethod extends Method { /** * A class of entry name method source nodes. */ -class ArchiveEntryNameMethodSource extends DataFlow::Node { +class ArchiveEntryNameMethodSource extends ApiSourceNode { ArchiveEntryNameMethodSource() { this.asExpr().(MethodCall).getMethod() instanceof ArchiveEntryNameMethod } From 4f46ce1133e9d367d1fb04b89741ff4ed1f5b06f Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Tue, 9 Apr 2024 11:08:56 +0200 Subject: [PATCH 069/238] Python: add test for `Argument[0, self, self:]` for instance methods --- .../model-summaries/InlineTaintTest.ext.yml | 3 +++ .../model-summaries/NormalDataflowTest.ext.yml | 3 +++ .../dataflow/model-summaries/model_summaries.py | 15 +++++++++++++++ 3 files changed, 21 insertions(+) diff --git a/python/ql/test/library-tests/dataflow/model-summaries/InlineTaintTest.ext.yml b/python/ql/test/library-tests/dataflow/model-summaries/InlineTaintTest.ext.yml index 10fbd6df7448..0ed4ca9f172d 100644 --- a/python/ql/test/library-tests/dataflow/model-summaries/InlineTaintTest.ext.yml +++ b/python/ql/test/library-tests/dataflow/model-summaries/InlineTaintTest.ext.yml @@ -18,4 +18,7 @@ extensions: - ["foo", "Member[MS_spread]", "Argument[0]", "ReturnValue.TupleElement[0]", "value"] - ["foo", "Member[MS_spread]", "Argument[1]", "ReturnValue.TupleElement[1]", "value"] - ["foo", "Member[MS_spread_all]", "Argument[0]", "ReturnValue.TupleElement[0,1]", "value"] + - ["foo", "Member[MS_Class].Instance.Member[instance_method]", "Argument[self]", "ReturnValue.TupleElement[0]", "value"] + - ["foo", "Member[MS_Class].Instance.Member[instance_method]", "Argument[0]", "ReturnValue.TupleElement[1]", "value"] + - ["foo", "Member[MS_Class].Instance.Member[explicit_self]", "Argument[self:]", "ReturnValue", "value"] - ["json", "Member[MS_loads]", "Argument[0]", "ReturnValue", "taint"] diff --git a/python/ql/test/library-tests/dataflow/model-summaries/NormalDataflowTest.ext.yml b/python/ql/test/library-tests/dataflow/model-summaries/NormalDataflowTest.ext.yml index 10fbd6df7448..0ed4ca9f172d 100644 --- a/python/ql/test/library-tests/dataflow/model-summaries/NormalDataflowTest.ext.yml +++ b/python/ql/test/library-tests/dataflow/model-summaries/NormalDataflowTest.ext.yml @@ -18,4 +18,7 @@ extensions: - ["foo", "Member[MS_spread]", "Argument[0]", "ReturnValue.TupleElement[0]", "value"] - ["foo", "Member[MS_spread]", "Argument[1]", "ReturnValue.TupleElement[1]", "value"] - ["foo", "Member[MS_spread_all]", "Argument[0]", "ReturnValue.TupleElement[0,1]", "value"] + - ["foo", "Member[MS_Class].Instance.Member[instance_method]", "Argument[self]", "ReturnValue.TupleElement[0]", "value"] + - ["foo", "Member[MS_Class].Instance.Member[instance_method]", "Argument[0]", "ReturnValue.TupleElement[1]", "value"] + - ["foo", "Member[MS_Class].Instance.Member[explicit_self]", "Argument[self:]", "ReturnValue", "value"] - ["json", "Member[MS_loads]", "Argument[0]", "ReturnValue", "taint"] diff --git a/python/ql/test/library-tests/dataflow/model-summaries/model_summaries.py b/python/ql/test/library-tests/dataflow/model-summaries/model_summaries.py index 17f831f6ed12..745a0e64a5b3 100644 --- a/python/ql/test/library-tests/dataflow/model-summaries/model_summaries.py +++ b/python/ql/test/library-tests/dataflow/model-summaries/model_summaries.py @@ -122,6 +122,21 @@ def explicit_identity(x): SINK(a) # $ flow="SOURCE, l:-1 -> a" SINK(b) # $ flow="SOURCE, l:-2 -> b" +from foo import MS_Class + +c = MS_Class() +a, b = c.instance_method(SOURCE) +SINK_F(a) +SINK(b) # $ flow="SOURCE, l:-2 -> b" + +m = c.instance_method +x, y = (SOURCE, NONSOURCE) +SINK(x) # $ flow="SOURCE, l:-1 -> x" +SINK_F(y) + +ms = c.explicit_self +SINK(ms(SOURCE)) # $ MISSING: flow="SOURCE, l:0 -> ms(SOURCE)" + # Modeled flow-summary is not value preserving from json import MS_loads as json_loads From 9f7edf378e07a18a891dae2bd8ba207d8779ce06 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Tue, 23 Apr 2024 11:13:08 +0200 Subject: [PATCH 070/238] Python: fix tests The way to expose the `self` arguemnt is to call an instance method on the class, not on the instance... --- .../dataflow/model-summaries/model_summaries.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/python/ql/test/library-tests/dataflow/model-summaries/model_summaries.py b/python/ql/test/library-tests/dataflow/model-summaries/model_summaries.py index 745a0e64a5b3..295a7ca89c54 100644 --- a/python/ql/test/library-tests/dataflow/model-summaries/model_summaries.py +++ b/python/ql/test/library-tests/dataflow/model-summaries/model_summaries.py @@ -129,13 +129,13 @@ def explicit_identity(x): SINK_F(a) SINK(b) # $ flow="SOURCE, l:-2 -> b" -m = c.instance_method -x, y = (SOURCE, NONSOURCE) -SINK(x) # $ flow="SOURCE, l:-1 -> x" +# call the instance method on the class to expose the self argument +x, y = MS_Class.instance_method(SOURCE, NONSOURCE) +SINK(x) # $ MISSING: flow="SOURCE, l:-1 -> x" SINK_F(y) -ms = c.explicit_self -SINK(ms(SOURCE)) # $ MISSING: flow="SOURCE, l:0 -> ms(SOURCE)" +# call the instance method on the class to expose the self argument +SINK(MS_Class.explicit_self(SOURCE)) # $ MISSING: flow="SOURCE, l:0 -> ms(SOURCE)" # Modeled flow-summary is not value preserving from json import MS_loads as json_loads From 3716b8c6a04f7bf6f5dd06f52620448be401c592 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Tue, 23 Apr 2024 15:05:32 +0200 Subject: [PATCH 071/238] Python: update test to reflect correct behaviour also add comments --- .../dataflow/model-summaries/model_summaries.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/python/ql/test/library-tests/dataflow/model-summaries/model_summaries.py b/python/ql/test/library-tests/dataflow/model-summaries/model_summaries.py index 295a7ca89c54..46b3d6a4db85 100644 --- a/python/ql/test/library-tests/dataflow/model-summaries/model_summaries.py +++ b/python/ql/test/library-tests/dataflow/model-summaries/model_summaries.py @@ -129,13 +129,16 @@ def explicit_identity(x): SINK_F(a) SINK(b) # $ flow="SOURCE, l:-2 -> b" -# call the instance method on the class to expose the self argument +# Call the instance method on the class to expose the self argument x, y = MS_Class.instance_method(SOURCE, NONSOURCE) SINK(x) # $ MISSING: flow="SOURCE, l:-1 -> x" SINK_F(y) -# call the instance method on the class to expose the self argument -SINK(MS_Class.explicit_self(SOURCE)) # $ MISSING: flow="SOURCE, l:0 -> ms(SOURCE)" +# Call the instance method on the class to expose the self argument +# That self argument is not referenced by `Argument[self:]` +SINK_F(MS_Class.explicit_self(SOURCE)) +# Instead, `Argument[self:]` refers to a keyword argument named `self` (which you are allowed to do in Python) +SINK(c.explicit_self(self = SOURCE)) # $ flow="SOURCE -> c.explicit_self(..)" # Modeled flow-summary is not value preserving from json import MS_loads as json_loads From 54cadcfe9be7144c66f00f68640debcaa10fd240 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 26 Apr 2024 13:44:45 +0100 Subject: [PATCH 072/238] C++: Forward to a cached predicate in a cached module instead of caching the predicate in 'Instruction.qll' to include it in the cached stage of the other predicates. --- .../code/cpp/ir/implementation/aliased_ssa/Instruction.qll | 3 +-- .../implementation/aliased_ssa/internal/SSAConstruction.qll | 5 +++++ 2 files changed, 6 insertions(+), 2 deletions(-) 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 189ffce2903e..53a225c2e89f 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 @@ -247,8 +247,7 @@ class Instruction extends Construction::TStageInstruction { * Gets the type of the result produced by this instruction. If the instruction does not produce * a result, its result type will be `IRVoidType`. */ - cached - final IRType getResultIRType() { result = this.getResultLanguageType().getIRType() } + final IRType getResultIRType() { result = Construction::getInstructionResultIRType(this) } /** * Gets the type of the result produced by this instruction. If the 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 209c42726b7d..d2e68c733041 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 @@ -429,6 +429,11 @@ private module Cached { instr = unreachedInstruction(_) and result = Language::getVoidType() } + cached + IRType getInstructionResultIRType(Instruction instr) { + result = instr.getResultLanguageType().getIRType() + } + /** * Holds if `opcode` is the opcode that specifies the operation performed by `instr`. * From dcc4ad2550108d28d04c6abf5ecd50d40ceae66e Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 26 Apr 2024 13:45:15 +0100 Subject: [PATCH 073/238] C++: Sync identical files. --- .../semmle/code/cpp/ir/implementation/raw/Instruction.qll | 3 +-- .../code/cpp/ir/implementation/unaliased_ssa/Instruction.qll | 3 +-- .../unaliased_ssa/internal/SSAConstruction.qll | 5 +++++ 3 files changed, 7 insertions(+), 4 deletions(-) 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 189ffce2903e..53a225c2e89f 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 @@ -247,8 +247,7 @@ class Instruction extends Construction::TStageInstruction { * Gets the type of the result produced by this instruction. If the instruction does not produce * a result, its result type will be `IRVoidType`. */ - cached - final IRType getResultIRType() { result = this.getResultLanguageType().getIRType() } + final IRType getResultIRType() { result = Construction::getInstructionResultIRType(this) } /** * Gets the type of the result produced by this instruction. If the 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 189ffce2903e..53a225c2e89f 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 @@ -247,8 +247,7 @@ class Instruction extends Construction::TStageInstruction { * Gets the type of the result produced by this instruction. If the instruction does not produce * a result, its result type will be `IRVoidType`. */ - cached - final IRType getResultIRType() { result = this.getResultLanguageType().getIRType() } + final IRType getResultIRType() { result = Construction::getInstructionResultIRType(this) } /** * Gets the type of the result produced by this instruction. If the 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 209c42726b7d..d2e68c733041 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 @@ -429,6 +429,11 @@ private module Cached { instr = unreachedInstruction(_) and result = Language::getVoidType() } + cached + IRType getInstructionResultIRType(Instruction instr) { + result = instr.getResultLanguageType().getIRType() + } + /** * Holds if `opcode` is the opcode that specifies the operation performed by `instr`. * From 70e9c48a47e88fa140fdbbaeaaab669100dc6f26 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 26 Apr 2024 13:48:13 +0100 Subject: [PATCH 074/238] C++: Also implement the predicate in the raw stage. --- .../cpp/ir/implementation/raw/internal/IRConstruction.qll | 4 ++++ 1 file changed, 4 insertions(+) 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 96a01954d17f..7bea8178d141 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 @@ -377,6 +377,10 @@ CppType getInstructionResultType(TStageInstruction instr) { result = getVoidType() } +IRType getInstructionResultIRType(Instruction instr) { + result = instr.getResultLanguageType().getIRType() +} + predicate getInstructionOpcode(Opcode opcode, TStageInstruction instr) { getInstructionTranslatedElement(instr).hasInstruction(opcode, getInstructionTag(instr), _) or From 1d45e3a55874b9cd2c9895efbeb2a5e1a3270815 Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Fri, 26 Apr 2024 14:59:31 +0200 Subject: [PATCH 075/238] C#: Store buildless extraction timing information and return in telemetry query --- .../Semmle.Extraction.CSharp.Standalone/Extractor.cs | 1 - .../Semmle.Extraction.CSharp/Extractor/Analyser.cs | 2 ++ .../Semmle.Extraction.CSharp/Extractor/Extractor.cs | 4 +--- .../Extractor/TracingAnalyser.cs | 3 --- csharp/ql/src/Telemetry/ExtractorInformation.ql | 11 ++++++++++- 5 files changed, 13 insertions(+), 8 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Extractor.cs b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Extractor.cs index 63d4ff0e83a8..e578dd4aa31c 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Extractor.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Extractor.cs @@ -40,7 +40,6 @@ private static void AnalyseStandalone( output.Name, syntaxTrees, references, new CSharpCompilationOptions(OutputKind.ConsoleApplication, allowUnsafe: true) ), (compilation, options) => analyser.Initialize(output.FullName, extractionInput.CompilationInfos, compilation, options), - _ => { }, () => { foreach (var type in analyser.MissingNamespaces) diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Analyser.cs b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Analyser.cs index cda4610a217f..2f21716284f0 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Analyser.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Analyser.cs @@ -245,6 +245,8 @@ private void DoAnalyseCompilation() } } + public void LogPerformance(Entities.PerformanceMetrics p) => compilationEntity.PopulatePerformance(p); + #nullable restore warnings /// diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Extractor.cs b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Extractor.cs index 22a55849a026..03369e7b6013 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Extractor.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Extractor.cs @@ -309,7 +309,6 @@ public static ExitCode Analyse(Stopwatch stopwatch, Analyser analyser, CommonOpt Func, IEnumerable> getSyntaxTreeTasks, Func, IEnumerable, CSharpCompilation> getCompilation, Action initializeAnalyser, - Action logPerformance, Action postProcess) { using var references = new BlockingCollection(); @@ -368,7 +367,7 @@ public static ExitCode Analyse(Stopwatch stopwatch, Analyser analyser, CommonOpt PeakWorkingSet = currentProcess.PeakWorkingSet64 }; - logPerformance(performance); + analyser.LogPerformance(performance); analyser.Logger.Log(Severity.Info, " Extraction took {0}", sw.Elapsed); postProcess(); @@ -422,7 +421,6 @@ private static ExitCode AnalyseTracing( ); }, (compilation, options) => analyser.EndInitialize(compilerArguments, options, compilation), - performance => analyser.LogPerformance(performance), () => { }); } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/TracingAnalyser.cs b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/TracingAnalyser.cs index 22db6710f36f..3b73c35f55a4 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/TracingAnalyser.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/TracingAnalyser.cs @@ -175,9 +175,6 @@ private IEnumerable FilteredDiagnostics Where(e => e.Severity >= DiagnosticSeverity.Error && !errorsToIgnore.Contains(e.Id)); } } - - public void LogPerformance(Entities.PerformanceMetrics p) => compilationEntity.PopulatePerformance(p); - #nullable restore warnings } } diff --git a/csharp/ql/src/Telemetry/ExtractorInformation.ql b/csharp/ql/src/Telemetry/ExtractorInformation.ql index 64f90e481706..f466e2c8e8ec 100644 --- a/csharp/ql/src/Telemetry/ExtractorInformation.ql +++ b/csharp/ql/src/Telemetry/ExtractorInformation.ql @@ -201,6 +201,14 @@ predicate analyzerAssemblies(string key, float value) { value = 1.0 } +predicate timingValues(string key, float value) { + exists(Compilation c | + key = "Total elapsed seconds" and value = c.getElapsedSeconds() + or + key = "Extractor elapsed seconds" and value = c.getExtractorElapsedSeconds() + ) +} + from string key, float value where ( @@ -230,7 +238,8 @@ where ExprStatsReport::numberOfOk(key, value) or ExprStatsReport::numberOfNotOk(key, value) or ExprStatsReport::percentageOfOk(key, value) or - analyzerAssemblies(key, value) + analyzerAssemblies(key, value) or + timingValues(key, value) ) and /* Infinity */ value != 1.0 / 0.0 and From 146d84bbf8c0012cb3e496a4deb7470afb61a0dd Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 26 Apr 2024 15:20:33 +0200 Subject: [PATCH 076/238] Go: rework makefile --- go/Makefile | 75 +++++------------------------------------------------ 1 file changed, 7 insertions(+), 68 deletions(-) diff --git a/go/Makefile b/go/Makefile index d0289a093a52..d9ba2c7e2d48 100644 --- a/go/Makefile +++ b/go/Makefile @@ -1,4 +1,4 @@ -all: extractor ql/lib/go.dbscheme +all: gen extractor ifeq ($(OS),Windows_NT) EXE = .exe @@ -14,17 +14,11 @@ CODEQL_PLATFORM = osx64 endif endif -CODEQL_TOOLS = $(addprefix codeql-tools/,autobuild.cmd autobuild.sh baseline-config-empty.json baseline-config-vendor.json configure-baseline.cmd configure-baseline.sh identify-environment.cmd identify-environment.sh index.cmd index.sh pre-finalize.cmd pre-finalize.sh tracing-config.lua) - EXTRACTOR_PACK_OUT = build/codeql-extractor-go -BINARIES = go-extractor go-tokenizer go-autobuilder go-build-runner go-bootstrap go-gen-dbscheme - -.PHONY: tools tools-codeql tools-codeql-full clean autoformat \ - tools-linux64 tools-osx64 tools-win64 check-formatting +.PHONY: extractor gen clean autoformat check-formatting clean: - rm -rf tools/bin tools/linux64 tools/osx64 tools/win64 tools/net tools/opencsv rm -rf $(EXTRACTOR_PACK_OUT) build/stats build/testdb autoformat: @@ -47,66 +41,11 @@ endif qhelp-to-markdown: scripts/qhelp-to-markdown.sh ql/src "$(QHELP_OUT_DIR)" -tools: tools-codeql tools/tokenizer.jar - -.PHONY: $(addsuffix $(EXE),$(addprefix tools/bin/,$(BINARIES))) -$(addsuffix $(EXE),$(addprefix tools/bin/,$(BINARIES))): - go build -C extractor -mod=vendor -o ../$@ ./cli/$(basename $(@F)) - -tools-codeql: tools-$(CODEQL_PLATFORM) - -tools-codeql-full: tools-linux64 tools-osx64 tools-win64 - -tools-linux64: $(addprefix tools/linux64/,$(BINARIES)) - -.PHONY: $(addprefix tools/linux64/,$(BINARIES)) -$(addprefix tools/linux64/,$(BINARIES)): - GOOS=linux GOARCH=amd64 go build -C extractor -mod=vendor -o ../$@ ./cli/$(@F) - -tools-osx64: $(addprefix tools/osx64/,$(BINARIES)) - -.PHONY: $(addprefix tools/osx64/,$(BINARIES)) -$(addprefix tools/osx64/,$(BINARIES)): - GOOS=darwin GOARCH=amd64 go build -C extractor -mod=vendor -o ../$@.amd64 ./cli/$(@F) - GOOS=darwin GOARCH=arm64 go build -C extractor -mod=vendor -o ../$@.arm64 ./cli/$(@F) - lipo -create $@.amd64 $@.arm64 -output $@ - rm $@.amd64 $@.arm64 - -tools-win64: $(addsuffix .exe,$(addprefix tools/win64/,$(BINARIES))) - -.PHONY: $(addsuffix .exe,$(addprefix tools/win64/,$(BINARIES))) -$(addsuffix .exe,$(addprefix tools/win64/,$(BINARIES))): - env GOOS=windows GOARCH=amd64 go build -C extractor -mod=vendor -o ../$@ ./cli/$(basename $(@F)) - -.PHONY: extractor-common extractor extractor-full -extractor-common: codeql-extractor.yml LICENSE ql/lib/go.dbscheme \ - tools/tokenizer.jar $(CODEQL_TOOLS) - rm -rf $(EXTRACTOR_PACK_OUT) - mkdir -p $(EXTRACTOR_PACK_OUT) - cp codeql-extractor.yml LICENSE ql/lib/go.dbscheme ql/lib/go.dbscheme.stats $(EXTRACTOR_PACK_OUT) - mkdir $(EXTRACTOR_PACK_OUT)/tools - cp -r tools/tokenizer.jar $(CODEQL_TOOLS) $(EXTRACTOR_PACK_OUT)/tools - cp -r downgrades $(EXTRACTOR_PACK_OUT) - -extractor: extractor-common tools-codeql - cp -r tools/$(CODEQL_PLATFORM) $(EXTRACTOR_PACK_OUT)/tools - -extractor-full: extractor-common tools-codeql-full - cp -r $(addprefix tools/,linux64 osx64 win64) $(EXTRACTOR_PACK_OUT)/tools - -tools/tokenizer.jar: tools/net/sourceforge/pmd/cpd/GoLanguage.class - jar cf $@ -C tools net - jar uf $@ -C tools opencsv - -tools/net/sourceforge/pmd/cpd/GoLanguage.class: extractor/net/sourceforge/pmd/cpd/GoLanguage.java - javac -cp extractor -d tools $< - rm tools/net/sourceforge/pmd/cpd/AbstractLanguage.class - rm tools/net/sourceforge/pmd/cpd/SourceCode.class - rm tools/net/sourceforge/pmd/cpd/TokenEntry.class - rm tools/net/sourceforge/pmd/cpd/Tokenizer.class +extractor: + bazel run :create-extractor-pack -ql/lib/go.dbscheme: tools/$(CODEQL_PLATFORM)/go-gen-dbscheme$(EXE) - $< $@ +gen: + bazel run :gen build/stats/src.stamp: mkdir -p $(@D)/src @@ -123,7 +62,7 @@ test: all build/testdb/check-upgrade-path codeql test run -j0 ql/test --search-path build/codeql-extractor-go --consistency-queries ql/test/consistency --compilation-cache=$(cache) # use GOOS=linux because GOOS=darwin GOARCH=386 is no longer supported env GOOS=linux GOARCH=386 codeql$(EXE) test run -j0 ql/test/query-tests/Security/CWE-681 --search-path build/codeql-extractor-go --consistency-queries ql/test/consistency --compilation-cache=$(cache) - cd extractor; go test -mod=vendor ./... + cd extractor; bazel test ... bash extractor-smoke-test/test.sh || (echo "Extractor smoke test FAILED"; exit 1) .PHONY: build/testdb/check-upgrade-path From d98ccdfa066544c75c3278c7499e12986cfd11e5 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 26 Apr 2024 16:02:22 +0200 Subject: [PATCH 077/238] Go: update workflow --- .github/workflows/go-tests.yml | 46 ++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/.github/workflows/go-tests.yml b/.github/workflows/go-tests.yml index 6d9cac5dae91..75c34f4f5de2 100644 --- a/.github/workflows/go-tests.yml +++ b/.github/workflows/go-tests.yml @@ -28,13 +28,6 @@ jobs: name: Test Linux (Ubuntu) runs-on: ubuntu-latest-xl steps: - - name: Set up Go ${{ env.GO_VERSION }} - uses: actions/setup-go@v5 - with: - go-version: ${{ env.GO_VERSION }} - cache: false - id: go - - name: Check out code uses: actions/checkout@v4 @@ -46,15 +39,41 @@ jobs: run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;' - name: Build + run: | + bazel run //go:create-extractor-pack + + - name: Cache compilation cache + id: query-cache + uses: ./.github/actions/cache-query-compilation + with: + key: go-qltest + + - name: Test run: | cd go - make + make test cache="${{ steps.query-cache.outputs.cache-dir }}" + + check-code: + name: Check code + runs-on: ubuntu-latest + steps: + - name: Check out code + uses: actions/checkout@v4 - name: Check that all Go code is autoformatted run: | cd go make check-formatting + - name: Check checked-in generated code + run: | + bazel run //go:gen + git add . + git diff --exit-code HEAD || ( + echo "please run bazel run //go:gen" + exit 1 + ) + - name: Compile qhelp files to markdown run: | cd go @@ -65,14 +84,3 @@ jobs: with: name: qhelp-markdown path: go/qhelp-out/**/*.md - - - name: Cache compilation cache - id: query-cache - uses: ./.github/actions/cache-query-compilation - with: - key: go-qltest - - - name: Test - run: | - cd go - make test cache="${{ steps.query-cache.outputs.cache-dir }}" From 3195f0c8288fd00af329ad25a0043e069a376c40 Mon Sep 17 00:00:00 2001 From: Mario Campos Date: Fri, 26 Apr 2024 09:10:40 -0500 Subject: [PATCH 078/238] Use more specific `hasGlobalName()` for stdlib function free(3) Based on the CodeQL documentation's example of strncpy(3) and strlen(3): https://codeql.github.com/docs/codeql-language-guides/hash-consing-and-value-numbering/#example-query --- cpp/ql/src/experimental/Best Practices/GuardedFree.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/src/experimental/Best Practices/GuardedFree.ql b/cpp/ql/src/experimental/Best Practices/GuardedFree.ql index ec8f39c491d7..07d279271592 100644 --- a/cpp/ql/src/experimental/Best Practices/GuardedFree.ql +++ b/cpp/ql/src/experimental/Best Practices/GuardedFree.ql @@ -14,7 +14,7 @@ import cpp class FreeCall extends FunctionCall { - FreeCall() { this.getTarget().hasName("free") } + FreeCall() { this.getTarget().hasGlobalName("free") } } from IfStmt stmt, FreeCall fc, Variable v From 4b0a217420706083dcf7ddc16ea34d5b3ad02848 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 26 Apr 2024 15:22:39 +0100 Subject: [PATCH 079/238] C++: Don't emit destructor calls as part of 'TranslatedResultCopy' as this has already been done in some other 'TranslatedExpr'. --- .../cpp/ir/implementation/raw/internal/TranslatedExpr.qll | 5 +++++ 1 file changed, 5 insertions(+) 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 3f4039ebb346..a43595b08e08 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 @@ -538,6 +538,11 @@ class TranslatedResultCopy extends TranslatedExpr, TTranslatedResultCopy { final override predicate producesExprResult() { any() } private TranslatedCoreExpr getOperand() { result.getExpr() = expr } + + override predicate handlesDestructorsExplicitly() { + // The destructor calls will already have been generated by the translation of `expr`. + any() + } } class TranslatedCommaExpr extends TranslatedNonConstantExpr { From 0f387eeac298cb8c30c11a13ba9f9dcd027220e9 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 26 Apr 2024 16:31:04 +0200 Subject: [PATCH 080/238] Go: add vendor update to `//go:gen` --- go/BUILD.bazel | 9 ++++++--- go/extractor/vendor/modules.txt | 1 + go/gen.py | 7 +++++-- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/go/BUILD.bazel b/go/BUILD.bazel index e769afeea1dd..50e2bc0d447d 100644 --- a/go/BUILD.bazel +++ b/go/BUILD.bazel @@ -1,15 +1,17 @@ load("@bazel_skylib//rules:native_binary.bzl", "native_binary") load("@gazelle//:def.bzl", "gazelle") load("@rules_pkg//pkg:install.bzl", "pkg_install") -load("@rules_pkg//pkg:mappings.bzl", "pkg_filegroup", "pkg_files") +load("@rules_pkg//pkg:mappings.bzl", "pkg_attributes", "pkg_filegroup", "pkg_files") load("//:defs.bzl", "codeql_platform") gazelle( - name = "_gazelle", + name = "gazelle", + extra_args = ["go/extractor"], ) _gen_binaries = [ - ":_gazelle", + "@rules_go//go", + ":gazelle", "//go/extractor/cli/go-gen-dbscheme", ] @@ -62,6 +64,7 @@ pkg_files( "//go/extractor/cli/go-gen-dbscheme", "//go/extractor/cli/go-tokenizer", ], + attributes = pkg_attributes(mode = "0755"), prefix = "tools/" + codeql_platform, visibility = ["//visibility:public"], ) diff --git a/go/extractor/vendor/modules.txt b/go/extractor/vendor/modules.txt index 5687615f62c3..37c4a68d828d 100644 --- a/go/extractor/vendor/modules.txt +++ b/go/extractor/vendor/modules.txt @@ -1,3 +1,4 @@ +## workspace # golang.org/x/mod v0.15.0 ## explicit; go 1.18 golang.org/x/mod/internal/lazyregexp diff --git a/go/gen.py b/go/gen.py index 7b7e9d732376..4b4cac0e46f2 100644 --- a/go/gen.py +++ b/go/gen.py @@ -7,14 +7,17 @@ go_extractor_dir = this.parent / "extractor" go_dbscheme = this.parent / "ql" / "lib" / "go.dbscheme" r = runfiles.Create() -gazelle, go_gen_dbscheme = map(r.Rlocation, sys.argv[1:]) +go, gazelle, go_gen_dbscheme = map(r.Rlocation, sys.argv[1:]) + +print("updating vendor") +subprocess.check_call([go, "-C", go_extractor_dir, "work", "vendor"]) print("clearing generated BUILD files") for build_file in go_extractor_dir.glob("*/**/BUILD.bazel"): build_file.unlink() print("running gazelle") -subprocess.check_call([gazelle, "go/extractor"]) +subprocess.check_call([gazelle]) print("adding header to generated BUILD files") for build_file in go_extractor_dir.glob("*/**/BUILD.bazel"): From 67fb866efa8cc1f38bb8b0f0f5c1362cc19253b8 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Fri, 26 Apr 2024 16:38:39 +0200 Subject: [PATCH 081/238] C++: Update test results --- .../library-tests/ir/ir/PrintAST.expected | 44 ++-- .../library-tests/ir/ir/aliased_ir.expected | 206 +++++++++--------- .../test/library-tests/ir/ir/raw_ir.expected | 148 ++++++------- 3 files changed, 199 insertions(+), 199 deletions(-) diff --git a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected index e0d2da046b2e..28c1398d90bc 100644 --- a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected +++ b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected @@ -19565,12 +19565,6 @@ ir.cpp: # 2216| Type = [PlainCharType] char # 2216| Value = [CharLiteral] 97 # 2216| ValueCategory = prvalue -# 2215| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2215| Type = [VoidType] void -# 2215| ValueCategory = prvalue -# 2215| getQualifier(): [VariableAccess] y -# 2215| Type = [Class] ClassWithDestructor -# 2215| ValueCategory = lvalue # 2215| getImplicitDestructorCall(0): [DestructorCall] call to ~vector # 2215| Type = [VoidType] void # 2215| ValueCategory = prvalue @@ -19580,6 +19574,12 @@ ir.cpp: # 2215| getUpdate().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) # 2215| Type = [ClassTemplateInstantiation,Struct] iterator # 2215| ValueCategory = lvalue +# 2215| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2215| Type = [VoidType] void +# 2215| ValueCategory = prvalue +# 2215| getQualifier(): [VariableAccess] y +# 2215| Type = [Class] ClassWithDestructor +# 2215| ValueCategory = lvalue # 2218| getStmt(6): [RangeBasedForStmt] for(...:...) ... # 2218| getInitialization(): [DeclStmt] declaration # 2218| getDeclarationEntry(0): [VariableDeclarationEntry] definition of ys @@ -19746,12 +19746,6 @@ ir.cpp: # 2233| getQualifier(): [VariableAccess] x # 2233| Type = [Class] ClassWithDestructor # 2233| ValueCategory = lvalue -# 2218| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2218| Type = [VoidType] void -# 2218| ValueCategory = prvalue -# 2218| getQualifier(): [VariableAccess] y -# 2218| Type = [Class] ClassWithDestructor -# 2218| ValueCategory = lvalue # 2218| getImplicitDestructorCall(0): [DestructorCall] call to ~vector # 2218| Type = [VoidType] void # 2218| ValueCategory = prvalue @@ -19761,6 +19755,12 @@ ir.cpp: # 2218| getUpdate().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) # 2218| Type = [ClassTemplateInstantiation,Struct] iterator # 2218| ValueCategory = lvalue +# 2218| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2218| Type = [VoidType] void +# 2218| ValueCategory = prvalue +# 2218| getQualifier(): [VariableAccess] y +# 2218| Type = [Class] ClassWithDestructor +# 2218| ValueCategory = lvalue # 2224| getStmt(7): [RangeBasedForStmt] for(...:...) ... # 2224| getInitialization(): [DeclStmt] declaration # 2224| getDeclarationEntry(0): [VariableDeclarationEntry] definition of ys @@ -20038,12 +20038,6 @@ ir.cpp: # 2232| getQualifier(): [VariableAccess] z1 # 2232| Type = [Class] ClassWithDestructor # 2232| ValueCategory = lvalue -# 2229| getImplicitDestructorCall(2): [DestructorCall] call to ~ClassWithDestructor -# 2229| Type = [VoidType] void -# 2229| ValueCategory = prvalue -# 2229| getQualifier(): [VariableAccess] y -# 2229| Type = [Class] ClassWithDestructor -# 2229| ValueCategory = lvalue # 2229| getImplicitDestructorCall(0): [DestructorCall] call to ~vector # 2229| Type = [VoidType] void # 2229| ValueCategory = prvalue @@ -20053,6 +20047,12 @@ ir.cpp: # 2229| getUpdate().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) # 2229| Type = [ClassTemplateInstantiation,Struct] iterator # 2229| ValueCategory = lvalue +# 2229| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2229| Type = [VoidType] void +# 2229| ValueCategory = prvalue +# 2229| getQualifier(): [VariableAccess] y +# 2229| Type = [Class] ClassWithDestructor +# 2229| ValueCategory = lvalue # 2233| getStmt(9): [ReturnStmt] return ... # 2233| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor # 2233| Type = [VoidType] void @@ -20662,15 +20662,15 @@ ir.cpp: # 2309| getQualifier(): [VariableAccess] s2 # 2309| Type = [Struct] String # 2309| ValueCategory = lvalue -# 2307| getImplicitDestructorCall(1): [DestructorCall] call to ~String +# 2307| getUpdate().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) +# 2307| Type = [ClassTemplateInstantiation,Struct] iterator +# 2307| ValueCategory = lvalue +# 2307| getImplicitDestructorCall(0): [DestructorCall] call to ~String # 2307| Type = [VoidType] void # 2307| ValueCategory = prvalue # 2307| getQualifier(): [VariableAccess] s # 2307| Type = [Struct] String # 2307| ValueCategory = lvalue -# 2307| getUpdate().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) -# 2307| Type = [ClassTemplateInstantiation,Struct] iterator -# 2307| ValueCategory = lvalue # 2311| getStmt(3): [ForStmt] for(...;...;...) ... # 2311| getInitialization(): [DeclStmt] declaration # 2311| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected index 3d3a56e790e9..68e5d36d2062 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected @@ -15372,7 +15372,7 @@ ir.cpp: #-----| True -> Block 2 # 2198| Block 1 -# 2198| m2198_9(unknown) = Phi : from 13:~m2233_5, from 19:~m2233_13, from 23:~m2233_22 +# 2198| m2198_9(unknown) = Phi : from 14:~m2233_5, from 19:~m2233_13, from 23:~m2233_22 # 2198| v2198_10(void) = ReturnVoid : # 2198| v2198_11(void) = AliasedUse : ~m2198_9 # 2198| v2198_12(void) = ExitFunction : @@ -15524,8 +15524,8 @@ ir.cpp: #-----| Goto -> Block 8 # 2215| Block 8 -# 2215| m2215_40(iterator) = Phi : from 7:m2215_32, from 9:m2215_72 -# 2215| m2215_41(unknown) = Phi : from 7:~m2215_39, from 9:~m2215_63 +# 2215| m2215_40(iterator) = Phi : from 7:m2215_32, from 9:m2215_64 +# 2215| m2215_41(unknown) = Phi : from 7:~m2215_39, from 9:~m2215_69 # 2215| r2215_42(glval>) = VariableAddress[(__begin)] : #-----| r0_7(glval>) = Convert : r2215_42 # 2215| r2215_43(glval) = FunctionAddress[operator!=] : @@ -15567,21 +15567,21 @@ ir.cpp: # 2216| v2216_7(void) = ^IndirectReadSideEffect[-1] : &:r2216_1, m2215_58 # 2216| m2216_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2216_1 # 2216| m2216_9(ClassWithDestructor) = Chi : total:m2215_58, partial:m2216_8 -# 2215| r2215_59(glval) = VariableAddress[y] : -# 2215| r2215_60(glval) = FunctionAddress[~ClassWithDestructor] : -# 2215| v2215_61(void) = Call[~ClassWithDestructor] : func:r2215_60, this:r2215_59 -# 2215| m2215_62(unknown) = ^CallSideEffect : ~m2216_6 -# 2215| m2215_63(unknown) = Chi : total:m2216_6, partial:m2215_62 -# 2215| v2215_64(void) = ^IndirectReadSideEffect[-1] : &:r2215_59, m2216_9 -# 2215| m2215_65(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2215_59 -# 2215| m2215_66(ClassWithDestructor) = Chi : total:m2216_9, partial:m2215_65 -# 2215| r2215_67(glval>) = VariableAddress[(__begin)] : -# 2215| r2215_68(glval) = FunctionAddress[operator++] : -# 2215| r2215_69(iterator &) = Call[operator++] : func:r2215_68, this:r2215_67 -# 2215| v2215_70(void) = ^IndirectReadSideEffect[-1] : &:r2215_67, m2215_40 -# 2215| m2215_71(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2215_67 -# 2215| m2215_72(iterator) = Chi : total:m2215_40, partial:m2215_71 -# 2215| r2215_73(glval>) = CopyValue : r2215_69 +# 2215| r2215_59(glval>) = VariableAddress[(__begin)] : +# 2215| r2215_60(glval) = FunctionAddress[operator++] : +# 2215| r2215_61(iterator &) = Call[operator++] : func:r2215_60, this:r2215_59 +# 2215| v2215_62(void) = ^IndirectReadSideEffect[-1] : &:r2215_59, m2215_40 +# 2215| m2215_63(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2215_59 +# 2215| m2215_64(iterator) = Chi : total:m2215_40, partial:m2215_63 +# 2215| r2215_65(glval) = VariableAddress[y] : +# 2215| r2215_66(glval) = FunctionAddress[~ClassWithDestructor] : +# 2215| v2215_67(void) = Call[~ClassWithDestructor] : func:r2215_66, this:r2215_65 +# 2215| m2215_68(unknown) = ^CallSideEffect : ~m2216_6 +# 2215| m2215_69(unknown) = Chi : total:m2216_6, partial:m2215_68 +# 2215| v2215_70(void) = ^IndirectReadSideEffect[-1] : &:r2215_65, m2216_9 +# 2215| m2215_71(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2215_65 +# 2215| m2215_72(ClassWithDestructor) = Chi : total:m2216_9, partial:m2215_71 +# 2215| r2215_73(glval>) = CopyValue : r2215_61 #-----| Goto (back edge) -> Block 8 # 2218| Block 10 @@ -15633,8 +15633,8 @@ ir.cpp: #-----| Goto -> Block 11 # 2218| Block 11 -# 2218| m2218_40(iterator) = Phi : from 10:m2218_32, from 14:m2218_88 -# 2218| m2218_41(unknown) = Phi : from 10:~m2218_39, from 14:~m2218_79 +# 2218| m2218_40(iterator) = Phi : from 10:m2218_32, from 12:m2218_58 +# 2218| m2218_41(unknown) = Phi : from 10:~m2218_39, from 12:~m2218_63 # 2218| r2218_42(glval>) = VariableAddress[(__begin)] : #-----| r0_24(glval>) = Convert : r2218_42 # 2218| r2218_43(glval) = FunctionAddress[operator!=] : @@ -15656,26 +15656,44 @@ ir.cpp: #-----| v0_32(void) = ^IndirectReadSideEffect[-1] : &:r0_24, m2218_40 # 2218| v2218_52(void) = ConditionalBranch : r2218_51 #-----| False -> Block 15 -#-----| True -> Block 12 +#-----| True -> Block 13 # 2218| Block 12 -# 2218| r2218_53(glval) = VariableAddress[y] : -# 2218| r2218_54(glval>) = VariableAddress[(__begin)] : -#-----| r0_33(glval>) = Convert : r2218_54 -# 2218| r2218_55(glval) = FunctionAddress[operator*] : -# 2218| r2218_56(ClassWithDestructor &) = Call[operator*] : func:r2218_55, this:r0_33 +# 2218| r2218_53(glval>) = VariableAddress[(__begin)] : +# 2218| r2218_54(glval) = FunctionAddress[operator++] : +# 2218| r2218_55(iterator &) = Call[operator++] : func:r2218_54, this:r2218_53 +# 2218| v2218_56(void) = ^IndirectReadSideEffect[-1] : &:r2218_53, m2218_40 +# 2218| m2218_57(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2218_53 +# 2218| m2218_58(iterator) = Chi : total:m2218_40, partial:m2218_57 +# 2218| r2218_59(glval) = VariableAddress[y] : +# 2218| r2218_60(glval) = FunctionAddress[~ClassWithDestructor] : +# 2218| v2218_61(void) = Call[~ClassWithDestructor] : func:r2218_60, this:r2218_59 +# 2218| m2218_62(unknown) = ^CallSideEffect : ~m2220_5 +# 2218| m2218_63(unknown) = Chi : total:m2220_5, partial:m2218_62 +# 2218| v2218_64(void) = ^IndirectReadSideEffect[-1] : &:r2218_59, m2220_8 +# 2218| m2218_65(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2218_59 +# 2218| m2218_66(ClassWithDestructor) = Chi : total:m2220_8, partial:m2218_65 +# 2218| r2218_67(glval>) = CopyValue : r2218_55 +#-----| Goto (back edge) -> Block 11 + +# 2218| Block 13 +# 2218| r2218_68(glval) = VariableAddress[y] : +# 2218| r2218_69(glval>) = VariableAddress[(__begin)] : +#-----| r0_33(glval>) = Convert : r2218_69 +# 2218| r2218_70(glval) = FunctionAddress[operator*] : +# 2218| r2218_71(ClassWithDestructor &) = Call[operator*] : func:r2218_70, this:r0_33 #-----| v0_34(void) = ^IndirectReadSideEffect[-1] : &:r0_33, m2218_40 -# 2218| r2218_57(ClassWithDestructor) = Load[?] : &:r2218_56, ~m2218_50 -# 2218| m2218_58(ClassWithDestructor) = Store[y] : &:r2218_53, r2218_57 +# 2218| r2218_72(ClassWithDestructor) = Load[?] : &:r2218_71, ~m2218_50 +# 2218| m2218_73(ClassWithDestructor) = Store[y] : &:r2218_68, r2218_72 # 2219| r2219_1(glval) = VariableAddress[y] : # 2219| r2219_2(glval) = FunctionAddress[set_x] : # 2219| r2219_3(char) = Constant[97] : # 2219| v2219_4(void) = Call[set_x] : func:r2219_2, this:r2219_1, 0:r2219_3 # 2219| m2219_5(unknown) = ^CallSideEffect : ~m2218_50 # 2219| m2219_6(unknown) = Chi : total:m2218_50, partial:m2219_5 -# 2219| v2219_7(void) = ^IndirectReadSideEffect[-1] : &:r2219_1, m2218_58 +# 2219| v2219_7(void) = ^IndirectReadSideEffect[-1] : &:r2219_1, m2218_73 # 2219| m2219_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2219_1 -# 2219| m2219_9(ClassWithDestructor) = Chi : total:m2218_58, partial:m2219_8 +# 2219| m2219_9(ClassWithDestructor) = Chi : total:m2218_73, partial:m2219_8 # 2220| r2220_1(glval) = VariableAddress[y] : # 2220| r2220_2(glval) = FunctionAddress[get_x] : # 2220| r2220_3(char) = Call[get_x] : func:r2220_2, this:r2220_1 @@ -15688,55 +15706,37 @@ ir.cpp: # 2220| r2220_10(int) = Constant[98] : # 2220| r2220_11(bool) = CompareEQ : r2220_9, r2220_10 # 2220| v2220_12(void) = ConditionalBranch : r2220_11 -#-----| False -> Block 14 -#-----| True -> Block 13 +#-----| False -> Block 12 +#-----| True -> Block 14 -# 2221| Block 13 +# 2221| Block 14 # 2221| v2221_1(void) = NoOp : -# 2218| r2218_59(glval) = VariableAddress[y] : -# 2218| r2218_60(glval) = FunctionAddress[~ClassWithDestructor] : -# 2218| v2218_61(void) = Call[~ClassWithDestructor] : func:r2218_60, this:r2218_59 -# 2218| m2218_62(unknown) = ^CallSideEffect : ~m2220_5 -# 2218| m2218_63(unknown) = Chi : total:m2220_5, partial:m2218_62 -# 2218| v2218_64(void) = ^IndirectReadSideEffect[-1] : &:r2218_59, m2220_8 -# 2218| m2218_65(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2218_59 -# 2218| m2218_66(ClassWithDestructor) = Chi : total:m2220_8, partial:m2218_65 -# 2218| r2218_67(glval>) = VariableAddress[ys] : -# 2218| r2218_68(glval) = FunctionAddress[~vector] : -# 2218| v2218_69(void) = Call[~vector] : func:r2218_68, this:r2218_67 -# 2218| m2218_70(unknown) = ^CallSideEffect : ~m2218_63 -# 2218| m2218_71(unknown) = Chi : total:m2218_63, partial:m2218_70 -# 2218| v2218_72(void) = ^IndirectReadSideEffect[-1] : &:r2218_67, ~m2218_71 -# 2218| m2218_73(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2218_67 -# 2218| m2218_74(unknown) = Chi : total:m2218_71, partial:m2218_73 +# 2218| r2218_74(glval) = VariableAddress[y] : +# 2218| r2218_75(glval) = FunctionAddress[~ClassWithDestructor] : +# 2218| v2218_76(void) = Call[~ClassWithDestructor] : func:r2218_75, this:r2218_74 +# 2218| m2218_77(unknown) = ^CallSideEffect : ~m2220_5 +# 2218| m2218_78(unknown) = Chi : total:m2220_5, partial:m2218_77 +# 2218| v2218_79(void) = ^IndirectReadSideEffect[-1] : &:r2218_74, m2220_8 +# 2218| m2218_80(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2218_74 +# 2218| m2218_81(ClassWithDestructor) = Chi : total:m2220_8, partial:m2218_80 +# 2218| r2218_82(glval>) = VariableAddress[ys] : +# 2218| r2218_83(glval) = FunctionAddress[~vector] : +# 2218| v2218_84(void) = Call[~vector] : func:r2218_83, this:r2218_82 +# 2218| m2218_85(unknown) = ^CallSideEffect : ~m2218_78 +# 2218| m2218_86(unknown) = Chi : total:m2218_78, partial:m2218_85 +# 2218| v2218_87(void) = ^IndirectReadSideEffect[-1] : &:r2218_82, ~m2218_86 +# 2218| m2218_88(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2218_82 +# 2218| m2218_89(unknown) = Chi : total:m2218_86, partial:m2218_88 # 2233| r2233_1(glval) = VariableAddress[x] : # 2233| r2233_2(glval) = FunctionAddress[~ClassWithDestructor] : # 2233| v2233_3(void) = Call[~ClassWithDestructor] : func:r2233_2, this:r2233_1 -# 2233| m2233_4(unknown) = ^CallSideEffect : ~m2218_74 -# 2233| m2233_5(unknown) = Chi : total:m2218_74, partial:m2233_4 +# 2233| m2233_4(unknown) = ^CallSideEffect : ~m2218_89 +# 2233| m2233_5(unknown) = Chi : total:m2218_89, partial:m2233_4 # 2233| v2233_6(void) = ^IndirectReadSideEffect[-1] : &:r2233_1, m2214_8 # 2233| m2233_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2233_1 # 2233| m2233_8(ClassWithDestructor) = Chi : total:m2214_8, partial:m2233_7 #-----| Goto -> Block 1 -# 2218| Block 14 -# 2218| r2218_75(glval) = VariableAddress[y] : -# 2218| r2218_76(glval) = FunctionAddress[~ClassWithDestructor] : -# 2218| v2218_77(void) = Call[~ClassWithDestructor] : func:r2218_76, this:r2218_75 -# 2218| m2218_78(unknown) = ^CallSideEffect : ~m2220_5 -# 2218| m2218_79(unknown) = Chi : total:m2220_5, partial:m2218_78 -# 2218| v2218_80(void) = ^IndirectReadSideEffect[-1] : &:r2218_75, m2220_8 -# 2218| m2218_81(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2218_75 -# 2218| m2218_82(ClassWithDestructor) = Chi : total:m2220_8, partial:m2218_81 -# 2218| r2218_83(glval>) = VariableAddress[(__begin)] : -# 2218| r2218_84(glval) = FunctionAddress[operator++] : -# 2218| r2218_85(iterator &) = Call[operator++] : func:r2218_84, this:r2218_83 -# 2218| v2218_86(void) = ^IndirectReadSideEffect[-1] : &:r2218_83, m2218_40 -# 2218| m2218_87(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2218_83 -# 2218| m2218_88(iterator) = Chi : total:m2218_40, partial:m2218_87 -# 2218| r2218_89(glval>) = CopyValue : r2218_85 -#-----| Goto (back edge) -> Block 11 - # 2224| Block 15 # 2224| r2224_1(glval>) = VariableAddress[ys] : # 2224| m2224_2(vector) = Uninitialized[ys] : &:r2224_1 @@ -15895,8 +15895,8 @@ ir.cpp: #-----| Goto -> Block 21 # 2229| Block 21 -# 2229| m2229_40(iterator) = Phi : from 20:m2229_32, from 22:m2229_72 -# 2229| m2229_41(unknown) = Phi : from 20:~m2229_39, from 22:~m2229_63 +# 2229| m2229_40(iterator) = Phi : from 20:m2229_32, from 22:m2229_64 +# 2229| m2229_41(unknown) = Phi : from 20:~m2229_39, from 22:~m2229_69 # 2229| r2229_42(glval>) = VariableAddress[(__begin)] : #-----| r0_58(glval>) = Convert : r2229_42 # 2229| r2229_43(glval) = FunctionAddress[operator!=] : @@ -15961,21 +15961,21 @@ ir.cpp: # 2232| v2232_14(void) = ^IndirectReadSideEffect[-1] : &:r2232_9, m2230_8 # 2232| m2232_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2232_9 # 2232| m2232_16(ClassWithDestructor) = Chi : total:m2230_8, partial:m2232_15 -# 2229| r2229_59(glval) = VariableAddress[y] : -# 2229| r2229_60(glval) = FunctionAddress[~ClassWithDestructor] : -# 2229| v2229_61(void) = Call[~ClassWithDestructor] : func:r2229_60, this:r2229_59 -# 2229| m2229_62(unknown) = ^CallSideEffect : ~m2232_13 -# 2229| m2229_63(unknown) = Chi : total:m2232_13, partial:m2229_62 -# 2229| v2229_64(void) = ^IndirectReadSideEffect[-1] : &:r2229_59, m2229_58 -# 2229| m2229_65(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2229_59 -# 2229| m2229_66(ClassWithDestructor) = Chi : total:m2229_58, partial:m2229_65 -# 2229| r2229_67(glval>) = VariableAddress[(__begin)] : -# 2229| r2229_68(glval) = FunctionAddress[operator++] : -# 2229| r2229_69(iterator &) = Call[operator++] : func:r2229_68, this:r2229_67 -# 2229| v2229_70(void) = ^IndirectReadSideEffect[-1] : &:r2229_67, m2229_40 -# 2229| m2229_71(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2229_67 -# 2229| m2229_72(iterator) = Chi : total:m2229_40, partial:m2229_71 -# 2229| r2229_73(glval>) = CopyValue : r2229_69 +# 2229| r2229_59(glval>) = VariableAddress[(__begin)] : +# 2229| r2229_60(glval) = FunctionAddress[operator++] : +# 2229| r2229_61(iterator &) = Call[operator++] : func:r2229_60, this:r2229_59 +# 2229| v2229_62(void) = ^IndirectReadSideEffect[-1] : &:r2229_59, m2229_40 +# 2229| m2229_63(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2229_59 +# 2229| m2229_64(iterator) = Chi : total:m2229_40, partial:m2229_63 +# 2229| r2229_65(glval) = VariableAddress[y] : +# 2229| r2229_66(glval) = FunctionAddress[~ClassWithDestructor] : +# 2229| v2229_67(void) = Call[~ClassWithDestructor] : func:r2229_66, this:r2229_65 +# 2229| m2229_68(unknown) = ^CallSideEffect : ~m2232_13 +# 2229| m2229_69(unknown) = Chi : total:m2232_13, partial:m2229_68 +# 2229| v2229_70(void) = ^IndirectReadSideEffect[-1] : &:r2229_65, m2229_58 +# 2229| m2229_71(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2229_65 +# 2229| m2229_72(ClassWithDestructor) = Chi : total:m2229_58, partial:m2229_71 +# 2229| r2229_73(glval>) = CopyValue : r2229_61 #-----| Goto (back edge) -> Block 21 # 2233| Block 23 @@ -16684,8 +16684,8 @@ ir.cpp: #-----| Goto -> Block 4 # 2307| Block 4 -# 2307| m2307_47(iterator) = Phi : from 3:m2307_39, from 5:m2307_89 -# 2307| m2307_48(unknown) = Phi : from 3:~m2307_46, from 5:~m2307_83 +# 2307| m2307_47(iterator) = Phi : from 3:m2307_39, from 5:m2307_81 +# 2307| m2307_48(unknown) = Phi : from 3:~m2307_46, from 5:~m2307_89 # 2307| r2307_49(glval>) = VariableAddress[(__begin)] : #-----| r0_7(glval>) = Convert : r2307_49 # 2307| r2307_50(glval) = FunctionAddress[operator!=] : @@ -16745,21 +16745,21 @@ ir.cpp: # 2309| v2309_6(void) = ^IndirectReadSideEffect[-1] : &:r2309_1, ~m2309_5 # 2309| m2309_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2309_1 # 2309| m2309_8(unknown) = Chi : total:m2309_5, partial:m2309_7 -# 2307| r2307_76(glval) = VariableAddress[s] : -# 2307| r2307_77(glval) = FunctionAddress[~String] : -# 2307| v2307_78(void) = Call[~String] : func:r2307_77, this:r2307_76 -# 2307| m2307_79(unknown) = ^CallSideEffect : ~m2309_8 -# 2307| m2307_80(unknown) = Chi : total:m2309_8, partial:m2307_79 -# 2307| v2307_81(void) = ^IndirectReadSideEffect[-1] : &:r2307_76, ~m2307_80 -# 2307| m2307_82(String) = ^IndirectMayWriteSideEffect[-1] : &:r2307_76 -# 2307| m2307_83(unknown) = Chi : total:m2307_80, partial:m2307_82 -# 2307| r2307_84(glval>) = VariableAddress[(__begin)] : -# 2307| r2307_85(glval) = FunctionAddress[operator++] : -# 2307| r2307_86(iterator &) = Call[operator++] : func:r2307_85, this:r2307_84 -# 2307| v2307_87(void) = ^IndirectReadSideEffect[-1] : &:r2307_84, m2307_47 -# 2307| m2307_88(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2307_84 -# 2307| m2307_89(iterator) = Chi : total:m2307_47, partial:m2307_88 -# 2307| r2307_90(glval>) = CopyValue : r2307_86 +# 2307| r2307_76(glval>) = VariableAddress[(__begin)] : +# 2307| r2307_77(glval) = FunctionAddress[operator++] : +# 2307| r2307_78(iterator &) = Call[operator++] : func:r2307_77, this:r2307_76 +# 2307| v2307_79(void) = ^IndirectReadSideEffect[-1] : &:r2307_76, m2307_47 +# 2307| m2307_80(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2307_76 +# 2307| m2307_81(iterator) = Chi : total:m2307_47, partial:m2307_80 +# 2307| r2307_82(glval) = VariableAddress[s] : +# 2307| r2307_83(glval) = FunctionAddress[~String] : +# 2307| v2307_84(void) = Call[~String] : func:r2307_83, this:r2307_82 +# 2307| m2307_85(unknown) = ^CallSideEffect : ~m2309_8 +# 2307| m2307_86(unknown) = Chi : total:m2309_8, partial:m2307_85 +# 2307| v2307_87(void) = ^IndirectReadSideEffect[-1] : &:r2307_82, ~m2307_86 +# 2307| m2307_88(String) = ^IndirectMayWriteSideEffect[-1] : &:r2307_82 +# 2307| m2307_89(unknown) = Chi : total:m2307_86, partial:m2307_88 +# 2307| r2307_90(glval>) = CopyValue : r2307_78 #-----| Goto (back edge) -> Block 4 # 2311| Block 6 diff --git a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected index 6ff42a28cb35..aadcd33f5104 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -14325,18 +14325,18 @@ ir.cpp: # 2216| mu2216_5(unknown) = ^CallSideEffect : ~m? # 2216| v2216_6(void) = ^IndirectReadSideEffect[-1] : &:r2216_1, ~m? # 2216| mu2216_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2216_1 -# 2215| r2215_49(glval) = VariableAddress[y] : -# 2215| r2215_50(glval) = FunctionAddress[~ClassWithDestructor] : -# 2215| v2215_51(void) = Call[~ClassWithDestructor] : func:r2215_50, this:r2215_49 -# 2215| mu2215_52(unknown) = ^CallSideEffect : ~m? -# 2215| v2215_53(void) = ^IndirectReadSideEffect[-1] : &:r2215_49, ~m? -# 2215| mu2215_54(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2215_49 -# 2215| r2215_55(glval>) = VariableAddress[(__begin)] : -# 2215| r2215_56(glval) = FunctionAddress[operator++] : -# 2215| r2215_57(iterator &) = Call[operator++] : func:r2215_56, this:r2215_55 -# 2215| v2215_58(void) = ^IndirectReadSideEffect[-1] : &:r2215_55, ~m? -# 2215| mu2215_59(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2215_55 -# 2215| r2215_60(glval>) = CopyValue : r2215_57 +# 2215| r2215_49(glval>) = VariableAddress[(__begin)] : +# 2215| r2215_50(glval) = FunctionAddress[operator++] : +# 2215| r2215_51(iterator &) = Call[operator++] : func:r2215_50, this:r2215_49 +# 2215| v2215_52(void) = ^IndirectReadSideEffect[-1] : &:r2215_49, ~m? +# 2215| mu2215_53(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2215_49 +# 2215| r2215_54(glval) = VariableAddress[y] : +# 2215| r2215_55(glval) = FunctionAddress[~ClassWithDestructor] : +# 2215| v2215_56(void) = Call[~ClassWithDestructor] : func:r2215_55, this:r2215_54 +# 2215| mu2215_57(unknown) = ^CallSideEffect : ~m? +# 2215| v2215_58(void) = ^IndirectReadSideEffect[-1] : &:r2215_54, ~m? +# 2215| mu2215_59(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2215_54 +# 2215| r2215_60(glval>) = CopyValue : r2215_51 #-----| Goto (back edge) -> Block 11 # 2215| Block 13 @@ -14409,17 +14409,32 @@ ir.cpp: #-----| v0_30(void) = ^IndirectReadSideEffect[-1] : &:r0_23, ~m? # 2218| v2218_42(void) = ConditionalBranch : r2218_41 #-----| False -> Block 20 -#-----| True -> Block 16 +#-----| True -> Block 17 # 2218| Block 16 -# 2218| r2218_43(glval) = VariableAddress[y] : -# 2218| r2218_44(glval>) = VariableAddress[(__begin)] : -#-----| r0_31(glval>) = Convert : r2218_44 -# 2218| r2218_45(glval) = FunctionAddress[operator*] : -# 2218| r2218_46(ClassWithDestructor &) = Call[operator*] : func:r2218_45, this:r0_31 +# 2218| r2218_43(glval>) = VariableAddress[(__begin)] : +# 2218| r2218_44(glval) = FunctionAddress[operator++] : +# 2218| r2218_45(iterator &) = Call[operator++] : func:r2218_44, this:r2218_43 +# 2218| v2218_46(void) = ^IndirectReadSideEffect[-1] : &:r2218_43, ~m? +# 2218| mu2218_47(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2218_43 +# 2218| r2218_48(glval) = VariableAddress[y] : +# 2218| r2218_49(glval) = FunctionAddress[~ClassWithDestructor] : +# 2218| v2218_50(void) = Call[~ClassWithDestructor] : func:r2218_49, this:r2218_48 +# 2218| mu2218_51(unknown) = ^CallSideEffect : ~m? +# 2218| v2218_52(void) = ^IndirectReadSideEffect[-1] : &:r2218_48, ~m? +# 2218| mu2218_53(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2218_48 +# 2218| r2218_54(glval>) = CopyValue : r2218_45 +#-----| Goto (back edge) -> Block 15 + +# 2218| Block 17 +# 2218| r2218_55(glval) = VariableAddress[y] : +# 2218| r2218_56(glval>) = VariableAddress[(__begin)] : +#-----| r0_31(glval>) = Convert : r2218_56 +# 2218| r2218_57(glval) = FunctionAddress[operator*] : +# 2218| r2218_58(ClassWithDestructor &) = Call[operator*] : func:r2218_57, this:r0_31 #-----| v0_32(void) = ^IndirectReadSideEffect[-1] : &:r0_31, ~m? -# 2218| r2218_47(ClassWithDestructor) = Load[?] : &:r2218_46, ~m? -# 2218| mu2218_48(ClassWithDestructor) = Store[y] : &:r2218_43, r2218_47 +# 2218| r2218_59(ClassWithDestructor) = Load[?] : &:r2218_58, ~m? +# 2218| mu2218_60(ClassWithDestructor) = Store[y] : &:r2218_55, r2218_59 # 2219| r2219_1(glval) = VariableAddress[y] : # 2219| r2219_2(glval) = FunctionAddress[set_x] : # 2219| r2219_3(char) = Constant[97] : @@ -14437,23 +14452,23 @@ ir.cpp: # 2220| r2220_8(int) = Constant[98] : # 2220| r2220_9(bool) = CompareEQ : r2220_7, r2220_8 # 2220| v2220_10(void) = ConditionalBranch : r2220_9 -#-----| False -> Block 18 -#-----| True -> Block 17 +#-----| False -> Block 16 +#-----| True -> Block 18 -# 2221| Block 17 +# 2221| Block 18 # 2221| v2221_1(void) = NoOp : -# 2218| r2218_49(glval) = VariableAddress[y] : -# 2218| r2218_50(glval) = FunctionAddress[~ClassWithDestructor] : -# 2218| v2218_51(void) = Call[~ClassWithDestructor] : func:r2218_50, this:r2218_49 -# 2218| mu2218_52(unknown) = ^CallSideEffect : ~m? -# 2218| v2218_53(void) = ^IndirectReadSideEffect[-1] : &:r2218_49, ~m? -# 2218| mu2218_54(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2218_49 -# 2218| r2218_55(glval>) = VariableAddress[ys] : -# 2218| r2218_56(glval) = FunctionAddress[~vector] : -# 2218| v2218_57(void) = Call[~vector] : func:r2218_56, this:r2218_55 -# 2218| mu2218_58(unknown) = ^CallSideEffect : ~m? -# 2218| v2218_59(void) = ^IndirectReadSideEffect[-1] : &:r2218_55, ~m? -# 2218| mu2218_60(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2218_55 +# 2218| r2218_61(glval) = VariableAddress[y] : +# 2218| r2218_62(glval) = FunctionAddress[~ClassWithDestructor] : +# 2218| v2218_63(void) = Call[~ClassWithDestructor] : func:r2218_62, this:r2218_61 +# 2218| mu2218_64(unknown) = ^CallSideEffect : ~m? +# 2218| v2218_65(void) = ^IndirectReadSideEffect[-1] : &:r2218_61, ~m? +# 2218| mu2218_66(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2218_61 +# 2218| r2218_67(glval>) = VariableAddress[ys] : +# 2218| r2218_68(glval) = FunctionAddress[~vector] : +# 2218| v2218_69(void) = Call[~vector] : func:r2218_68, this:r2218_67 +# 2218| mu2218_70(unknown) = ^CallSideEffect : ~m? +# 2218| v2218_71(void) = ^IndirectReadSideEffect[-1] : &:r2218_67, ~m? +# 2218| mu2218_72(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2218_67 # 2233| r2233_1(glval) = VariableAddress[x] : # 2233| r2233_2(glval) = FunctionAddress[~ClassWithDestructor] : # 2233| v2233_3(void) = Call[~ClassWithDestructor] : func:r2233_2, this:r2233_1 @@ -14462,21 +14477,6 @@ ir.cpp: # 2233| mu2233_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2233_1 #-----| Goto -> Block 1 -# 2218| Block 18 -# 2218| r2218_61(glval) = VariableAddress[y] : -# 2218| r2218_62(glval) = FunctionAddress[~ClassWithDestructor] : -# 2218| v2218_63(void) = Call[~ClassWithDestructor] : func:r2218_62, this:r2218_61 -# 2218| mu2218_64(unknown) = ^CallSideEffect : ~m? -# 2218| v2218_65(void) = ^IndirectReadSideEffect[-1] : &:r2218_61, ~m? -# 2218| mu2218_66(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2218_61 -# 2218| r2218_67(glval>) = VariableAddress[(__begin)] : -# 2218| r2218_68(glval) = FunctionAddress[operator++] : -# 2218| r2218_69(iterator &) = Call[operator++] : func:r2218_68, this:r2218_67 -# 2218| v2218_70(void) = ^IndirectReadSideEffect[-1] : &:r2218_67, ~m? -# 2218| mu2218_71(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2218_67 -# 2218| r2218_72(glval>) = CopyValue : r2218_69 -#-----| Goto (back edge) -> Block 15 - # 2218| Block 19 # 2218| r2218_73(glval>) = VariableAddress[ys] : # 2218| r2218_74(glval) = FunctionAddress[~vector] : @@ -14686,18 +14686,18 @@ ir.cpp: # 2232| mu2232_10(unknown) = ^CallSideEffect : ~m? # 2232| v2232_11(void) = ^IndirectReadSideEffect[-1] : &:r2232_7, ~m? # 2232| mu2232_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2232_7 -# 2229| r2229_49(glval) = VariableAddress[y] : -# 2229| r2229_50(glval) = FunctionAddress[~ClassWithDestructor] : -# 2229| v2229_51(void) = Call[~ClassWithDestructor] : func:r2229_50, this:r2229_49 -# 2229| mu2229_52(unknown) = ^CallSideEffect : ~m? -# 2229| v2229_53(void) = ^IndirectReadSideEffect[-1] : &:r2229_49, ~m? -# 2229| mu2229_54(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2229_49 -# 2229| r2229_55(glval>) = VariableAddress[(__begin)] : -# 2229| r2229_56(glval) = FunctionAddress[operator++] : -# 2229| r2229_57(iterator &) = Call[operator++] : func:r2229_56, this:r2229_55 -# 2229| v2229_58(void) = ^IndirectReadSideEffect[-1] : &:r2229_55, ~m? -# 2229| mu2229_59(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2229_55 -# 2229| r2229_60(glval>) = CopyValue : r2229_57 +# 2229| r2229_49(glval>) = VariableAddress[(__begin)] : +# 2229| r2229_50(glval) = FunctionAddress[operator++] : +# 2229| r2229_51(iterator &) = Call[operator++] : func:r2229_50, this:r2229_49 +# 2229| v2229_52(void) = ^IndirectReadSideEffect[-1] : &:r2229_49, ~m? +# 2229| mu2229_53(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2229_49 +# 2229| r2229_54(glval) = VariableAddress[y] : +# 2229| r2229_55(glval) = FunctionAddress[~ClassWithDestructor] : +# 2229| v2229_56(void) = Call[~ClassWithDestructor] : func:r2229_55, this:r2229_54 +# 2229| mu2229_57(unknown) = ^CallSideEffect : ~m? +# 2229| v2229_58(void) = ^IndirectReadSideEffect[-1] : &:r2229_54, ~m? +# 2229| mu2229_59(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2229_54 +# 2229| r2229_60(glval>) = CopyValue : r2229_51 #-----| Goto (back edge) -> Block 27 # 2229| Block 29 @@ -15339,18 +15339,18 @@ ir.cpp: # 2309| mu2309_4(unknown) = ^CallSideEffect : ~m? # 2309| v2309_5(void) = ^IndirectReadSideEffect[-1] : &:r2309_1, ~m? # 2309| mu2309_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2309_1 -# 2307| r2307_60(glval) = VariableAddress[s] : -# 2307| r2307_61(glval) = FunctionAddress[~String] : -# 2307| v2307_62(void) = Call[~String] : func:r2307_61, this:r2307_60 -# 2307| mu2307_63(unknown) = ^CallSideEffect : ~m? -# 2307| v2307_64(void) = ^IndirectReadSideEffect[-1] : &:r2307_60, ~m? -# 2307| mu2307_65(String) = ^IndirectMayWriteSideEffect[-1] : &:r2307_60 -# 2307| r2307_66(glval>) = VariableAddress[(__begin)] : -# 2307| r2307_67(glval) = FunctionAddress[operator++] : -# 2307| r2307_68(iterator &) = Call[operator++] : func:r2307_67, this:r2307_66 -# 2307| v2307_69(void) = ^IndirectReadSideEffect[-1] : &:r2307_66, ~m? -# 2307| mu2307_70(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2307_66 -# 2307| r2307_71(glval>) = CopyValue : r2307_68 +# 2307| r2307_60(glval>) = VariableAddress[(__begin)] : +# 2307| r2307_61(glval) = FunctionAddress[operator++] : +# 2307| r2307_62(iterator &) = Call[operator++] : func:r2307_61, this:r2307_60 +# 2307| v2307_63(void) = ^IndirectReadSideEffect[-1] : &:r2307_60, ~m? +# 2307| mu2307_64(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2307_60 +# 2307| r2307_65(glval) = VariableAddress[s] : +# 2307| r2307_66(glval) = FunctionAddress[~String] : +# 2307| v2307_67(void) = Call[~String] : func:r2307_66, this:r2307_65 +# 2307| mu2307_68(unknown) = ^CallSideEffect : ~m? +# 2307| v2307_69(void) = ^IndirectReadSideEffect[-1] : &:r2307_65, ~m? +# 2307| mu2307_70(String) = ^IndirectMayWriteSideEffect[-1] : &:r2307_65 +# 2307| r2307_71(glval>) = CopyValue : r2307_62 #-----| Goto (back edge) -> Block 4 # 2311| Block 6 From 86d6b8ef21c8a1d82fb23c4530aa31b07de0a305 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 26 Apr 2024 16:39:51 +0200 Subject: [PATCH 082/238] Go: put back go setup --- .github/workflows/go-tests.yml | 47 +++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/.github/workflows/go-tests.yml b/.github/workflows/go-tests.yml index 75c34f4f5de2..5c9204f8405f 100644 --- a/.github/workflows/go-tests.yml +++ b/.github/workflows/go-tests.yml @@ -16,9 +16,6 @@ on: - .github/actions/** - codeql-workspace.yml -env: - GO_VERSION: '~1.22.0' - permissions: contents: read @@ -31,6 +28,21 @@ jobs: - name: Check out code uses: actions/checkout@v4 + - name: Get go version + shell: bash + run: | + ( + echo -n "GO_VERSION=" + bazel run @rules_go//go -- version | sed 's/go version go\(\S*\) .*/\1/' + ) | tee -a "$GITHUB_ENV" + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: ${{ env.GO_VERSION }} + cache: false + id: go + - name: Set up CodeQL CLI uses: ./.github/actions/fetch-codeql @@ -42,24 +54,6 @@ jobs: run: | bazel run //go:create-extractor-pack - - name: Cache compilation cache - id: query-cache - uses: ./.github/actions/cache-query-compilation - with: - key: go-qltest - - - name: Test - run: | - cd go - make test cache="${{ steps.query-cache.outputs.cache-dir }}" - - check-code: - name: Check code - runs-on: ubuntu-latest - steps: - - name: Check out code - uses: actions/checkout@v4 - - name: Check that all Go code is autoformatted run: | cd go @@ -84,3 +78,14 @@ jobs: with: name: qhelp-markdown path: go/qhelp-out/**/*.md + + - name: Cache compilation cache + id: query-cache + uses: ./.github/actions/cache-query-compilation + with: + key: go-qltest + + - name: Test + run: | + cd go + make test cache="${{ steps.query-cache.outputs.cache-dir }}" From d66494dcb0b2b23010794a052a2315f19de10f30 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 26 Apr 2024 17:03:56 +0200 Subject: [PATCH 083/238] Go: update `go-tests-other-os.yml` --- .github/workflows/go-tests-other-os.yml | 58 +++++++------------------ 1 file changed, 15 insertions(+), 43 deletions(-) diff --git a/.github/workflows/go-tests-other-os.yml b/.github/workflows/go-tests-other-os.yml index ded53f868b70..ba3dd0335ad4 100644 --- a/.github/workflows/go-tests-other-os.yml +++ b/.github/workflows/go-tests-other-os.yml @@ -7,64 +7,38 @@ on: - .github/workflows/go-tests-other-os.yml - .github/actions/** - codeql-workspace.yml -env: - GO_VERSION: '~1.22.0' permissions: contents: read jobs: - test-mac: - name: Test MacOS - runs-on: macos-latest + test: + name: Test + strategy: + fail-fast: false + matrix: + os: [macos-latest, windows-latest-xl] + if: matrix.os == 'macos-latest' || github.repository_owner == 'github' + runs-on: ${{ matrix.os }} steps: - - name: Set up Go ${{ env.GO_VERSION }} - uses: actions/setup-go@v5 - with: - go-version: ${{ env.GO_VERSION }} - cache: false - id: go - - name: Check out code uses: actions/checkout@v4 - - name: Set up CodeQL CLI - uses: ./.github/actions/fetch-codeql - - - name: Enable problem matchers in repository + - name: Get go version shell: bash - run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;' - - - name: Build - run: | - cd go - make - - - name: Cache compilation cache - id: query-cache - uses: ./.github/actions/cache-query-compilation - with: - key: go-qltest - - name: Test run: | - cd go - make test cache="${{ steps.query-cache.outputs.cache-dir }}" + ( + echo -n "GO_VERSION=" + bazel run @rules_go//go -- version | sed 's/go version go\(\S*\) .*/\1/' + ) | tee -a "$GITHUB_ENV" - test-win: - if: github.repository_owner == 'github' - name: Test Windows - runs-on: windows-latest-xl - steps: - - name: Set up Go ${{ env.GO_VERSION }} + - name: Set up Go uses: actions/setup-go@v5 with: go-version: ${{ env.GO_VERSION }} cache: false id: go - - name: Check out code - uses: actions/checkout@v4 - - name: Set up CodeQL CLI uses: ./.github/actions/fetch-codeql @@ -74,15 +48,13 @@ jobs: - name: Build run: | - cd go - make + bazel run //go:create-extractor-pack - name: Cache compilation cache id: query-cache uses: ./.github/actions/cache-query-compilation with: key: go-qltest - - name: Test run: | cd go From d6c57de6505a1528448089d98eef0523c171dcf6 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 26 Apr 2024 16:05:29 +0100 Subject: [PATCH 084/238] C++: Convert one of the tests to also test the 'absolute' versions of the GuardCondition predicates. --- .../controlflow/guards/GuardsEnsure.expected | 86 +++++++++++++++++++ .../controlflow/guards/GuardsEnsure.ql | 21 ++++- 2 files changed, 104 insertions(+), 3 deletions(-) diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected b/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected index e5328aefa629..cf5a6d2c73bd 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected @@ -1,3 +1,4 @@ +binary | test.c:7:9:7:13 | ... > ... | test.c:7:9:7:9 | x | < | test.c:7:13:7:13 | 0 | 1 | 10 | 11 | | test.c:7:9:7:13 | ... > ... | test.c:7:9:7:9 | x | >= | test.c:7:13:7:13 | 0 | 1 | 7 | 9 | | test.c:7:9:7:13 | ... > ... | test.c:7:13:7:13 | 0 | < | test.c:7:9:7:9 | x | 0 | 7 | 9 | @@ -154,3 +155,88 @@ | test.cpp:31:7:31:13 | ... == ... | test.cpp:31:12:31:13 | - ... | != | test.cpp:31:7:31:7 | x | 0 | 34 | 34 | | test.cpp:31:7:31:13 | ... == ... | test.cpp:31:12:31:13 | - ... | == | test.cpp:31:7:31:7 | x | 0 | 30 | 30 | | test.cpp:31:7:31:13 | ... == ... | test.cpp:31:12:31:13 | - ... | == | test.cpp:31:7:31:7 | x | 0 | 31 | 32 | +unary +| test.c:7:9:7:13 | ... > ... | test.c:7:9:7:9 | x | < | 1 | 10 | 11 | +| test.c:7:9:7:13 | ... > ... | test.c:7:9:7:9 | x | >= | 1 | 7 | 9 | +| test.c:17:8:17:12 | ... < ... | test.c:17:8:17:8 | x | < | 0 | 17 | 17 | +| test.c:17:8:17:12 | ... < ... | test.c:17:8:17:8 | x | < | 0 | 18 | 18 | +| test.c:17:8:17:21 | ... && ... | test.c:17:8:17:8 | x | < | 0 | 18 | 18 | +| test.c:17:8:17:21 | ... && ... | test.c:17:17:17:17 | y | >= | 2 | 18 | 18 | +| test.c:17:17:17:21 | ... > ... | test.c:17:17:17:17 | y | >= | 2 | 18 | 18 | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 2 | 2 | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 31 | 34 | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 34 | 34 | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 39 | 42 | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 42 | 42 | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 42 | 44 | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 45 | 45 | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 45 | 47 | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 51 | 53 | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 56 | 58 | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 58 | 58 | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 58 | 66 | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 62 | 62 | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | >= | 1 | 26 | 28 | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | < | 10 | 34 | 34 | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 2 | 2 | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 39 | 42 | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 42 | 42 | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 42 | 44 | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 45 | 45 | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 45 | 47 | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 51 | 53 | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 56 | 58 | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 58 | 58 | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 58 | 66 | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 62 | 62 | +| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:16 | j | < | 10 | 42 | 42 | +| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:16 | j | < | 10 | 42 | 44 | +| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:16 | j | < | 10 | 45 | 45 | +| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:16 | j | < | 10 | 45 | 47 | +| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:16 | j | < | 10 | 51 | 53 | +| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:12 | z | < | 1 | 42 | 42 | +| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:12 | z | < | 1 | 51 | 53 | +| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:12 | z | >= | 1 | 45 | 45 | +| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:12 | z | >= | 1 | 45 | 47 | +| test.c:45:16:45:20 | ... > ... | test.c:45:16:45:16 | y | >= | 1 | 45 | 47 | +| test.c:58:9:58:14 | ... == ... | test.c:58:9:58:9 | x | != | 0 | 58 | 58 | +| test.c:58:9:58:14 | ... == ... | test.c:58:9:58:9 | x | != | 0 | 62 | 62 | +| test.c:58:9:58:23 | ... \|\| ... | test.c:58:9:58:9 | x | != | 0 | 62 | 62 | +| test.c:58:9:58:23 | ... \|\| ... | test.c:58:19:58:19 | y | >= | 0 | 62 | 62 | +| test.c:58:19:58:23 | ... < ... | test.c:58:19:58:19 | y | >= | 0 | 62 | 62 | +| test.c:75:9:75:14 | ... == ... | test.c:75:9:75:9 | x | != | 0 | 78 | 79 | +| test.c:75:9:75:14 | ... == ... | test.c:75:9:75:9 | x | == | 0 | 75 | 77 | +| test.c:85:8:85:13 | ... == ... | test.c:85:8:85:8 | x | == | 0 | 85 | 85 | +| test.c:85:8:85:13 | ... == ... | test.c:85:8:85:8 | x | == | 0 | 86 | 86 | +| test.c:85:8:85:23 | ... && ... | test.c:85:8:85:8 | x | == | 0 | 86 | 86 | +| test.c:85:8:85:23 | ... && ... | test.c:85:18:85:18 | y | != | 0 | 86 | 86 | +| test.c:85:18:85:23 | ... != ... | test.c:85:18:85:18 | y | != | 0 | 86 | 86 | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | != | 0 | 94 | 96 | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | 0 | 70 | 70 | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | 0 | 99 | 102 | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | 0 | 102 | 102 | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | 0 | 107 | 109 | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | 0 | 109 | 109 | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | 0 | 109 | 117 | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | 0 | 113 | 113 | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | < | 10 | 102 | 102 | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | >= | 10 | 70 | 70 | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | >= | 10 | 107 | 109 | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | >= | 10 | 109 | 109 | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | >= | 10 | 109 | 117 | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | >= | 10 | 113 | 113 | +| test.c:109:9:109:14 | ... == ... | test.c:109:9:109:9 | x | != | 0 | 109 | 109 | +| test.c:109:9:109:14 | ... == ... | test.c:109:9:109:9 | x | != | 0 | 113 | 113 | +| test.c:109:9:109:23 | ... \|\| ... | test.c:109:9:109:9 | x | != | 0 | 113 | 113 | +| test.c:109:9:109:23 | ... \|\| ... | test.c:109:19:109:19 | y | >= | 0 | 113 | 113 | +| test.c:109:19:109:23 | ... < ... | test.c:109:19:109:19 | y | >= | 0 | 113 | 113 | +| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | -1 | 30 | 30 | +| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | -1 | 34 | 34 | +| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | -1 | 30 | 30 | +| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | -1 | 31 | 32 | +| test.cpp:61:10:61:10 | i | test.cpp:61:10:61:10 | i | == | 0 | 62 | 64 | +| test.cpp:61:10:61:10 | i | test.cpp:61:10:61:10 | i | == | 1 | 65 | 66 | +| test.cpp:74:10:74:10 | i | test.cpp:74:10:74:10 | i | < | 11 | 75 | 77 | +| test.cpp:74:10:74:10 | i | test.cpp:74:10:74:10 | i | < | 21 | 78 | 79 | +| test.cpp:74:10:74:10 | i | test.cpp:74:10:74:10 | i | >= | 0 | 75 | 77 | +| test.cpp:74:10:74:10 | i | test.cpp:74:10:74:10 | i | >= | 11 | 78 | 79 | diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.ql b/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.ql index 94aaade03ed5..59f8a399c6d4 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.ql +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.ql @@ -7,8 +7,9 @@ import cpp import semmle.code.cpp.controlflow.Guards -from GuardCondition guard, Expr left, Expr right, int k, int start, int end, string op -where +query predicate binary( + GuardCondition guard, Expr left, string op, Expr right, int k, int start, int end +) { exists(BasicBlock block | guard.ensuresLt(left, right, k, block, true) and op = "<" or @@ -20,4 +21,18 @@ where | block.hasLocationInfo(_, start, _, end, _) ) -select guard, left, op, right, k, start, end +} + +query predicate unary(GuardCondition guard, Expr left, string op, int k, int start, int end) { + exists(BasicBlock block | + guard.ensuresLt(left, k, block, true) and op = "<" + or + guard.ensuresLt(left, k, block, false) and op = ">=" + or + guard.ensuresEq(left, k, block, true) and op = "==" + or + guard.ensuresEq(left, k, block, false) and op = "!=" + | + block.hasLocationInfo(_, start, _, end, _) + ) +} From 800d7546fa1b4976ccf0058aa103e829c901e782 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Fri, 26 Apr 2024 17:17:23 +0200 Subject: [PATCH 085/238] change all the change-notes to breaking --- cpp/ql/lib/change-notes/2024-04-26-outdated-deprecations.md | 2 +- csharp/ql/lib/change-notes/2024-04-26-outdated-deprecations.md | 2 +- go/ql/lib/change-notes/2024-04-26-outdated-deprecations.md | 2 +- java/ql/lib/change-notes/2024-04-26-outdated-deprecations.md | 2 +- .../ql/lib/change-notes/2024-04-26-outdated-deprecations.md | 2 +- python/ql/lib/change-notes/2024-04-26-outdated-deprecations.md | 2 +- ruby/ql/lib/change-notes/2024-04-26-outdated-deprecations.md | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cpp/ql/lib/change-notes/2024-04-26-outdated-deprecations.md b/cpp/ql/lib/change-notes/2024-04-26-outdated-deprecations.md index 61a02a9613d4..642e3443640a 100644 --- a/cpp/ql/lib/change-notes/2024-04-26-outdated-deprecations.md +++ b/cpp/ql/lib/change-notes/2024-04-26-outdated-deprecations.md @@ -1,4 +1,4 @@ --- -category: minorAnalysis +category: breaking --- * Deleted the deprecated `GlobalValueNumberingImpl.qll` implementation. diff --git a/csharp/ql/lib/change-notes/2024-04-26-outdated-deprecations.md b/csharp/ql/lib/change-notes/2024-04-26-outdated-deprecations.md index 2ac740557260..314bb6e01fe3 100644 --- a/csharp/ql/lib/change-notes/2024-04-26-outdated-deprecations.md +++ b/csharp/ql/lib/change-notes/2024-04-26-outdated-deprecations.md @@ -1,5 +1,5 @@ --- -category: minorAnalysis +category: breaking --- * Deleted the deprecated `getAssemblyName` predicate from the `Operator` class. Use `getFunctionName` instead. * Deleted the deprecated `LShiftOperator`, `RShiftOperator`, `AssignLShiftExpr`, `AssignRShiftExpr`, `LShiftExpr`, and `RShiftExpr` aliases. diff --git a/go/ql/lib/change-notes/2024-04-26-outdated-deprecations.md b/go/ql/lib/change-notes/2024-04-26-outdated-deprecations.md index 6723f78df122..2c7b522b792c 100644 --- a/go/ql/lib/change-notes/2024-04-26-outdated-deprecations.md +++ b/go/ql/lib/change-notes/2024-04-26-outdated-deprecations.md @@ -1,4 +1,4 @@ --- -category: minorAnalysis +category: breaking --- * Deleted the deprecated `CsvRemoteSource` alias. Use `MaDRemoteSource` instead. \ No newline at end of file diff --git a/java/ql/lib/change-notes/2024-04-26-outdated-deprecations.md b/java/ql/lib/change-notes/2024-04-26-outdated-deprecations.md index de3190492d39..fb245f821a82 100644 --- a/java/ql/lib/change-notes/2024-04-26-outdated-deprecations.md +++ b/java/ql/lib/change-notes/2024-04-26-outdated-deprecations.md @@ -1,4 +1,4 @@ --- -category: minorAnalysis +category: breaking --- * Deleted the deprecated `AssignLShiftExpr`, `AssignRShiftExpr`, `AssignURShiftExpr`, `LShiftExpr`, `RShiftExpr`, and `URShiftExpr` aliases. diff --git a/javascript/ql/lib/change-notes/2024-04-26-outdated-deprecations.md b/javascript/ql/lib/change-notes/2024-04-26-outdated-deprecations.md index 36444c07ac77..59a90e91ec86 100644 --- a/javascript/ql/lib/change-notes/2024-04-26-outdated-deprecations.md +++ b/javascript/ql/lib/change-notes/2024-04-26-outdated-deprecations.md @@ -1,5 +1,5 @@ --- -category: minorAnalysis +category: breaking --- * Deleted the deprecated `getInput` predicate from the `CryptographicOperation` class. Use `getAnInput` instead. * Deleted the deprecated `RegExpPatterns` module from `Regexp.qll`. diff --git a/python/ql/lib/change-notes/2024-04-26-outdated-deprecations.md b/python/ql/lib/change-notes/2024-04-26-outdated-deprecations.md index 469060fd5be5..db64f0a98312 100644 --- a/python/ql/lib/change-notes/2024-04-26-outdated-deprecations.md +++ b/python/ql/lib/change-notes/2024-04-26-outdated-deprecations.md @@ -1,5 +1,5 @@ --- -category: minorAnalysis +category: breaking --- * Deleted the deprecated `RegExpPatterns` module from `Regexp.qll`. * Deleted the deprecated `Security/CWE-020/HostnameRegexpShared.qll` file. \ No newline at end of file diff --git a/ruby/ql/lib/change-notes/2024-04-26-outdated-deprecations.md b/ruby/ql/lib/change-notes/2024-04-26-outdated-deprecations.md index 1ad9ef373827..76cc93df2aaa 100644 --- a/ruby/ql/lib/change-notes/2024-04-26-outdated-deprecations.md +++ b/ruby/ql/lib/change-notes/2024-04-26-outdated-deprecations.md @@ -1,5 +1,5 @@ --- -category: minorAnalysis +category: breaking --- * Deleted the deprecated `RegExpPatterns` module from `Regexp.qll`. * Deleted the deprecated `security/cwe-020/HostnameRegexpShared.qll` file. \ No newline at end of file From bf61114284ef8e5a5f5caeced7ed022a909e236a Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 26 Apr 2024 16:06:32 +0100 Subject: [PATCH 086/238] C++: Add a test with pointer comparisons and float comparisons. --- .../controlflow/guards/Guards.expected | 4 +++ .../controlflow/guards/GuardsCompare.expected | 8 ++++++ .../controlflow/guards/GuardsControl.expected | 4 +++ .../controlflow/guards/GuardsEnsure.expected | 4 +++ .../library-tests/controlflow/guards/test.cpp | 28 ++++++++++++++++++- 5 files changed, 47 insertions(+), 1 deletion(-) diff --git a/cpp/ql/test/library-tests/controlflow/guards/Guards.expected b/cpp/ql/test/library-tests/controlflow/guards/Guards.expected index 6eebc960ce3c..08a8a9281bb1 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/Guards.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/Guards.expected @@ -32,3 +32,7 @@ | test.cpp:61:10:61:10 | i | | test.cpp:74:10:74:10 | i | | test.cpp:84:10:84:10 | i | +| test.cpp:93:6:93:6 | c | +| test.cpp:99:6:99:6 | f | +| test.cpp:105:6:105:14 | ... != ... | +| test.cpp:111:6:111:14 | ... != ... | diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected b/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected index b88856d90cf0..381175d886e0 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected @@ -119,6 +119,10 @@ | 102 | j < 10+0 when ... < ... is true | | 102 | j >= 10 when ... < ... is false | | 102 | j >= 10+0 when ... < ... is false | +| 105 | 0.0 != f+0 when ... != ... is true | +| 105 | 0.0 == f+0 when ... != ... is false | +| 105 | f != 0.0+0 when ... != ... is true | +| 105 | f == 0.0+0 when ... != ... is false | | 109 | 0 != x+0 when ... == ... is false | | 109 | 0 != x+0 when ... \|\| ... is false | | 109 | 0 < y+1 when ... < ... is false | @@ -137,3 +141,7 @@ | 109 | y >= 0 when ... \|\| ... is false | | 109 | y >= 0+0 when ... < ... is false | | 109 | y >= 0+0 when ... \|\| ... is false | +| 111 | 0.0 != i+0 when ... != ... is true | +| 111 | 0.0 == i+0 when ... != ... is false | +| 111 | i != 0.0+0 when ... != ... is true | +| 111 | i == 0.0+0 when ... != ... is false | diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected b/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected index fbfaff9acf6b..62d9b0a12294 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected @@ -90,3 +90,7 @@ | test.cpp:61:10:61:10 | i | Case[1] | 65 | 66 | | test.cpp:74:10:74:10 | i | Case[0..10] | 75 | 77 | | test.cpp:74:10:74:10 | i | Case[11..20] | 78 | 79 | +| test.cpp:93:6:93:6 | c | true | 93 | 94 | +| test.cpp:99:6:99:6 | f | true | 99 | 100 | +| test.cpp:105:6:105:14 | ... != ... | true | 105 | 106 | +| test.cpp:111:6:111:14 | ... != ... | true | 111 | 112 | diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected b/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected index cf5a6d2c73bd..70e35880ad66 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected @@ -155,6 +155,10 @@ binary | test.cpp:31:7:31:13 | ... == ... | test.cpp:31:12:31:13 | - ... | != | test.cpp:31:7:31:7 | x | 0 | 34 | 34 | | test.cpp:31:7:31:13 | ... == ... | test.cpp:31:12:31:13 | - ... | == | test.cpp:31:7:31:7 | x | 0 | 30 | 30 | | test.cpp:31:7:31:13 | ... == ... | test.cpp:31:12:31:13 | - ... | == | test.cpp:31:7:31:7 | x | 0 | 31 | 32 | +| test.cpp:105:6:105:14 | ... != ... | test.cpp:105:6:105:6 | f | != | test.cpp:105:11:105:14 | 0.0 | 0 | 105 | 106 | +| test.cpp:105:6:105:14 | ... != ... | test.cpp:105:11:105:14 | 0.0 | != | test.cpp:105:6:105:6 | f | 0 | 105 | 106 | +| test.cpp:111:6:111:14 | ... != ... | test.cpp:111:6:111:6 | i | != | test.cpp:111:11:111:14 | 0.0 | 0 | 111 | 112 | +| test.cpp:111:6:111:14 | ... != ... | test.cpp:111:11:111:14 | 0.0 | != | test.cpp:111:6:111:6 | i | 0 | 111 | 112 | unary | test.c:7:9:7:13 | ... > ... | test.c:7:9:7:9 | x | < | 1 | 10 | 11 | | test.c:7:9:7:13 | ... > ... | test.c:7:9:7:9 | x | >= | 1 | 7 | 9 | diff --git a/cpp/ql/test/library-tests/controlflow/guards/test.cpp b/cpp/ql/test/library-tests/controlflow/guards/test.cpp index 3a60f5f026e7..84d02ca4efa5 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/test.cpp +++ b/cpp/ql/test/library-tests/controlflow/guards/test.cpp @@ -85,4 +85,30 @@ void test_switches_default(int i) { default: use1(i); } -} \ No newline at end of file +} + +void use(...); + +void pointer_comparison(char* c) { + if(c) { + use(c); + } +} + +void implicit_float_comparison(float f) { + if(f) { + use(f); + } +} + +void explicit_float_comparison(float f) { + if(f != 0.0f) { + use(f); + } +} + +void int_float_comparison(int i) { + if(i != 0.0f) { + use(i); + } +} From c10e00d389a211843e5c29dec3ddc673f9c8030e Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 26 Apr 2024 16:18:52 +0100 Subject: [PATCH 087/238] C++: Add a subclass for constant instructions with pointer type. --- .../implementation/aliased_ssa/Instruction.qll | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) 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 189ffce2903e..d8fec6b61340 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 @@ -995,9 +995,8 @@ class ConstantInstruction extends ConstantValueInstruction { */ class IntegerConstantInstruction extends ConstantInstruction { IntegerConstantInstruction() { - exists(IRType resultType | - resultType = this.getResultIRType() and - (resultType instanceof IRIntegerType or resultType instanceof IRBooleanType) + exists(IRType resultType | resultType = this.getResultIRType() | + resultType instanceof IRIntegerType or resultType instanceof IRBooleanType ) } } @@ -1009,6 +1008,17 @@ class FloatConstantInstruction extends ConstantInstruction { FloatConstantInstruction() { this.getResultIRType() instanceof IRFloatingPointType } } +/** + * An instruction whose result is a constant value of a pointer type. + */ +class PointerConstantInstruction extends ConstantInstruction { + PointerConstantInstruction() { + exists(IRType resultType | resultType = this.getResultIRType() | + resultType instanceof IRAddressType or resultType instanceof IRFunctionAddressType + ) + } +} + /** * An instruction whose result is the address of a string literal. */ From e78091e9d02497ae050e804ce588354707bdec95 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 26 Apr 2024 16:19:02 +0100 Subject: [PATCH 088/238] C++: Sync identical files. --- .../cpp/ir/implementation/raw/Instruction.qll | 16 +++++++++++++--- .../implementation/unaliased_ssa/Instruction.qll | 16 +++++++++++++--- 2 files changed, 26 insertions(+), 6 deletions(-) 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 189ffce2903e..d8fec6b61340 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 @@ -995,9 +995,8 @@ class ConstantInstruction extends ConstantValueInstruction { */ class IntegerConstantInstruction extends ConstantInstruction { IntegerConstantInstruction() { - exists(IRType resultType | - resultType = this.getResultIRType() and - (resultType instanceof IRIntegerType or resultType instanceof IRBooleanType) + exists(IRType resultType | resultType = this.getResultIRType() | + resultType instanceof IRIntegerType or resultType instanceof IRBooleanType ) } } @@ -1009,6 +1008,17 @@ class FloatConstantInstruction extends ConstantInstruction { FloatConstantInstruction() { this.getResultIRType() instanceof IRFloatingPointType } } +/** + * An instruction whose result is a constant value of a pointer type. + */ +class PointerConstantInstruction extends ConstantInstruction { + PointerConstantInstruction() { + exists(IRType resultType | resultType = this.getResultIRType() | + resultType instanceof IRAddressType or resultType instanceof IRFunctionAddressType + ) + } +} + /** * An instruction whose result is the address of a string literal. */ 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 189ffce2903e..d8fec6b61340 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 @@ -995,9 +995,8 @@ class ConstantInstruction extends ConstantValueInstruction { */ class IntegerConstantInstruction extends ConstantInstruction { IntegerConstantInstruction() { - exists(IRType resultType | - resultType = this.getResultIRType() and - (resultType instanceof IRIntegerType or resultType instanceof IRBooleanType) + exists(IRType resultType | resultType = this.getResultIRType() | + resultType instanceof IRIntegerType or resultType instanceof IRBooleanType ) } } @@ -1009,6 +1008,17 @@ class FloatConstantInstruction extends ConstantInstruction { FloatConstantInstruction() { this.getResultIRType() instanceof IRFloatingPointType } } +/** + * An instruction whose result is a constant value of a pointer type. + */ +class PointerConstantInstruction extends ConstantInstruction { + PointerConstantInstruction() { + exists(IRType resultType | resultType = this.getResultIRType() | + resultType instanceof IRAddressType or resultType instanceof IRFunctionAddressType + ) + } +} + /** * An instruction whose result is the address of a string literal. */ From b78537dd74e6d49a1790558fc02e4dd3cf106a9d Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 26 Apr 2024 16:19:24 +0100 Subject: [PATCH 089/238] C++: Allow comparisons with pointer types in IRGuards. --- cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll index ee419dd70249..bcd214ec0000 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll @@ -1156,5 +1156,14 @@ private predicate add_eq( ) } +private class IntegerOrPointerConstantInstruction extends ConstantInstruction { + IntegerOrPointerConstantInstruction() { + this instanceof IntegerConstantInstruction or + this instanceof PointerConstantInstruction + } +} + /** The int value of integer constant expression. */ -private int int_value(Instruction i) { result = i.(IntegerConstantInstruction).getValue().toInt() } +private int int_value(Instruction i) { + result = i.(IntegerOrPointerConstantInstruction).getValue().toInt() +} From d18cdee0bc707f0c0a223c905ecc4d0d16aaae90 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 26 Apr 2024 16:19:33 +0100 Subject: [PATCH 090/238] C++: Accept test changes. --- .../test/library-tests/controlflow/guards-ir/tests.expected | 6 ++++++ .../library-tests/controlflow/guards/GuardsCompare.expected | 4 ++++ .../library-tests/controlflow/guards/GuardsEnsure.expected | 2 ++ 3 files changed, 12 insertions(+) diff --git a/cpp/ql/test/library-tests/controlflow/guards-ir/tests.expected b/cpp/ql/test/library-tests/controlflow/guards-ir/tests.expected index cc29559d5d31..943d7028a5d2 100644 --- a/cpp/ql/test/library-tests/controlflow/guards-ir/tests.expected +++ b/cpp/ql/test/library-tests/controlflow/guards-ir/tests.expected @@ -56,6 +56,8 @@ astGuardsCompare | 17 | y < 1+1 when ... > ... is false | | 17 | y >= 1+1 when ... && ... is true | | 17 | y >= 1+1 when ... > ... is true | +| 18 | call to get != 0 when call to get is true | +| 18 | call to get == 0 when call to get is false | | 26 | 0 < x+0 when ... > ... is true | | 26 | 0 >= x+0 when ... > ... is false | | 26 | x < 0+1 when ... > ... is false | @@ -487,6 +489,7 @@ astGuardsEnsure_const | test.c:109:9:109:23 | ... \|\| ... | test.c:109:9:109:9 | x | != | 0 | 113 | 113 | | test.c:175:13:175:32 | ... == ... | test.c:175:13:175:15 | call to foo | != | 0 | 175 | 175 | | test.c:175:13:175:32 | ... == ... | test.c:175:13:175:15 | call to foo | == | 0 | 175 | 175 | +| test.cpp:18:8:18:10 | call to get | test.cpp:18:8:18:10 | call to get | != | 0 | 19 | 19 | | test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | -1 | 30 | 30 | | test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | -1 | 34 | 34 | | test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | -1 | 30 | 30 | @@ -545,6 +548,8 @@ irGuardsCompare | 17 | y < 2 when CompareGT: ... > ... is false | | 17 | y >= 1+1 when CompareGT: ... > ... is true | | 17 | y >= 2 when CompareGT: ... > ... is true | +| 18 | call to get != 0 when CompareNE: (bool)... is true | +| 18 | call to get == 0 when CompareNE: (bool)... is false | | 26 | 0 < x+0 when CompareGT: ... > ... is true | | 26 | 0 >= x+0 when CompareGT: ... > ... is false | | 26 | x < 0+1 when CompareGT: ... > ... is false | @@ -996,6 +1001,7 @@ irGuardsEnsure_const | test.c:109:19:109:23 | CompareLT: ... < ... | test.c:109:19:109:19 | Load: y | >= | 0 | 113 | 113 | | test.c:175:13:175:32 | CompareEQ: ... == ... | test.c:175:13:175:15 | Call: call to foo | != | 0 | 175 | 175 | | test.c:175:13:175:32 | CompareEQ: ... == ... | test.c:175:13:175:15 | Call: call to foo | == | 0 | 175 | 175 | +| test.cpp:18:8:18:12 | CompareNE: (bool)... | test.cpp:18:8:18:10 | Call: call to get | != | 0 | 19 | 19 | | test.cpp:31:7:31:13 | CompareEQ: ... == ... | test.cpp:31:7:31:7 | Load: x | != | -1 | 34 | 34 | | test.cpp:31:7:31:13 | CompareEQ: ... == ... | test.cpp:31:7:31:7 | Load: x | == | -1 | 30 | 30 | | test.cpp:31:7:31:13 | CompareEQ: ... == ... | test.cpp:31:7:31:7 | Load: x | == | -1 | 32 | 32 | diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected b/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected index 381175d886e0..756140604e13 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected @@ -22,6 +22,8 @@ | 17 | y >= 1+1 when ... > ... is true | | 17 | y >= 2 when ... && ... is true | | 17 | y >= 2 when ... > ... is true | +| 18 | call to get != 0 when call to get is true | +| 18 | call to get == 0 when call to get is false | | 26 | 0 < x+0 when ... > ... is true | | 26 | 0 >= x+0 when ... > ... is false | | 26 | x < 0+1 when ... > ... is false | @@ -107,6 +109,8 @@ | 85 | y != 0+0 when ... && ... is true | | 85 | y == 0 when ... != ... is false | | 85 | y == 0+0 when ... != ... is false | +| 93 | c != 0 when c is true | +| 93 | c == 0 when c is false | | 94 | 0 != x+0 when ... != ... is true | | 94 | 0 == x+0 when ... != ... is false | | 94 | x != 0 when ... != ... is true | diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected b/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected index 70e35880ad66..f9eaced1276a 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected @@ -234,6 +234,7 @@ unary | test.c:109:9:109:23 | ... \|\| ... | test.c:109:9:109:9 | x | != | 0 | 113 | 113 | | test.c:109:9:109:23 | ... \|\| ... | test.c:109:19:109:19 | y | >= | 0 | 113 | 113 | | test.c:109:19:109:23 | ... < ... | test.c:109:19:109:19 | y | >= | 0 | 113 | 113 | +| test.cpp:18:8:18:10 | call to get | test.cpp:18:8:18:10 | call to get | != | 0 | 19 | 19 | | test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | -1 | 30 | 30 | | test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | -1 | 34 | 34 | | test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | -1 | 30 | 30 | @@ -244,3 +245,4 @@ unary | test.cpp:74:10:74:10 | i | test.cpp:74:10:74:10 | i | < | 21 | 78 | 79 | | test.cpp:74:10:74:10 | i | test.cpp:74:10:74:10 | i | >= | 0 | 75 | 77 | | test.cpp:74:10:74:10 | i | test.cpp:74:10:74:10 | i | >= | 11 | 78 | 79 | +| test.cpp:93:6:93:6 | c | test.cpp:93:6:93:6 | c | != | 0 | 93 | 94 | From 8b23f6db1022ec518962db98d5b882b244d3e66b Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Sat, 27 Apr 2024 09:53:07 +0100 Subject: [PATCH 091/238] Ruby: Add URI.open example to rb/kernel-open qhelp --- .../queries/security/cwe-078/examples/file_open.rb | 13 ++++++++----- .../security/cwe-078/examples/kernel_open.rb | 7 ++++++- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/ruby/ql/src/queries/security/cwe-078/examples/file_open.rb b/ruby/ql/src/queries/security/cwe-078/examples/file_open.rb index 3ce1f44817f9..1e0c13d6aca3 100644 --- a/ruby/ql/src/queries/security/cwe-078/examples/file_open.rb +++ b/ruby/ql/src/queries/security/cwe-078/examples/file_open.rb @@ -1,6 +1,9 @@ class UsersController < ActionController::Base - def create - filename = params[:filename] - File.open(filename) - end - end \ No newline at end of file + def create + filename = params[:filename] + File.open(filename) + + web_page = params[:web_page] + Net::HTTP.get(URI.parse(web_page)) + end +end diff --git a/ruby/ql/src/queries/security/cwe-078/examples/kernel_open.rb b/ruby/ql/src/queries/security/cwe-078/examples/kernel_open.rb index 84f8bc8db7d4..ce14c11acede 100644 --- a/ruby/ql/src/queries/security/cwe-078/examples/kernel_open.rb +++ b/ruby/ql/src/queries/security/cwe-078/examples/kernel_open.rb @@ -1,6 +1,11 @@ +require "open-uri" + class UsersController < ActionController::Base def create filename = params[:filename] open(filename) # BAD + + web_page = params[:web_page] + URI.open(web_page) # BAD - calls `Kernel.open` internally end -end \ No newline at end of file +end From 044ee9b08a04bc6c1696b56d8e28e1aef6d2eb49 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 26 Apr 2024 17:16:26 +0100 Subject: [PATCH 092/238] C++: Delete old iterator flow using memory edges. --- .../cpp/ir/dataflow/internal/SsaInternals.qll | 34 --- .../dataflow/internal/SsaInternalsCommon.qll | 242 ------------------ 2 files changed, 276 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll index 7eb84aefe3f4..db8fafa13b0e 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll @@ -121,16 +121,6 @@ private newtype TDefOrUseImpl = // a function body. isGlobalDefImpl(v, f, _, indirectionIndex) } or - TIteratorDef( - Operand iteratorDerefAddress, BaseSourceVariableInstruction container, int indirectionIndex - ) { - isIteratorDef(container, iteratorDerefAddress, _, _, indirectionIndex) - } or - TIteratorUse( - Operand iteratorAddress, BaseSourceVariableInstruction container, int indirectionIndex - ) { - isIteratorUse(container, iteratorAddress, _, indirectionIndex) - } or TFinalParameterUse(Parameter p, int indirectionIndex) { underlyingTypeIsModifiableAt(p.getUnderlyingType(), indirectionIndex) and // Only create an SSA read for the final use of a parameter if there's @@ -336,20 +326,6 @@ private class DirectDef extends OperandBasedDef, TDefImpl { override predicate isCertain() { isDef(true, _, address, base, _, ind) } } -private class IteratorDef extends OperandBasedDef, TIteratorDef { - BaseSourceVariableInstruction container; - - IteratorDef() { this = TIteratorDef(address, container, ind) } - - override BaseSourceVariableInstruction getBase() { result = container } - - override int getIndirection() { isIteratorDef(container, address, _, result, ind) } - - override Node0Impl getValue() { isIteratorDef(container, address, result, _, _) } - - override predicate isCertain() { none() } -} - abstract class UseImpl extends DefOrUseImpl { int ind; @@ -418,16 +394,6 @@ private class DirectUse extends OperandBasedUse, TUseImpl { override Node getNode() { nodeHasOperand(result, operand, ind) } } -private class IteratorUse extends OperandBasedUse, TIteratorUse { - IteratorUse() { this = TIteratorUse(operand, base, ind) } - - override int getIndirection() { isIteratorUse(base, operand, result, ind) } - - override predicate isCertain() { none() } - - override Node getNode() { nodeHasOperand(result, operand, ind) } -} - pragma[nomagic] private predicate finalParameterNodeHasParameterAndIndex( FinalParameterNode n, Parameter p, int indirectionIndex diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll index 7e5b4de8122c..0920e5a38657 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll @@ -246,14 +246,6 @@ private module IteratorIndirections { baseType = super.getValueType() } - override predicate isAdditionalDereference(Instruction deref, Operand address) { - exists(CallInstruction call | - operandForFullyConvertedCall(getAUse(deref), call) and - this = call.getStaticCallTarget().getClassAndName("operator*") and - address = call.getThisArgumentOperand() - ) - } - override predicate isAdditionalWrite(Node0Impl value, Operand address, boolean certain) { exists(CallInstruction call | call.getArgumentOperand(0) = value.asOperand() | this = call.getStaticCallTarget().getClassAndName("operator=") and @@ -262,16 +254,6 @@ private module IteratorIndirections { ) } - override predicate isAdditionalTaintStep(Node node1, Node node2) { - exists(CallInstruction call | - // Taint through `operator+=` and `operator-=` on iterators. - call.getStaticCallTarget() instanceof Iterator::IteratorAssignArithmeticOperator and - node2.(IndirectArgumentOutNode).getPreUpdateNode() = node1 and - node1.(IndirectOperand).hasOperandAndIndirectionIndex(call.getArgumentOperand(0), _) and - node1.getType().getUnspecifiedType() = this - ) - } - override predicate isAdditionalConversionFlow(Operand opFrom, Instruction instrTo) { // This is a bit annoying: Consider the following snippet: // ``` @@ -589,230 +571,6 @@ private class BaseCallInstruction extends BaseSourceVariableInstruction, CallIns cached private module Cached { - private import semmle.code.cpp.models.interfaces.Iterator as Interfaces - private import semmle.code.cpp.models.implementations.Iterator as Iterator - private import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs as IO - - /** - * Holds if `next` is a instruction with a memory result that potentially - * updates the memory produced by `prev`. - */ - private predicate memorySucc(Instruction prev, Instruction next) { - prev = next.(ChiInstruction).getTotal() - or - // Phi inputs can be inexact. - prev = next.(PhiInstruction).getAnInputOperand().getAnyDef() - or - prev = next.(CopyInstruction).getSourceValue() - or - exists(ReadSideEffectInstruction read | - next = read.getPrimaryInstruction() and - isAdditionalConversionFlow(_, next) and - prev = read.getSideEffectOperand().getAnyDef() - ) - } - - /** - * Holds if `iteratorDerefAddress` is an address of an iterator dereference (i.e., `*it`) - * that is used for a write operation that writes the value `value`. The `memory` instruction - * represents the memory that the IR's SSA analysis determined was read by the call to `operator*`. - * - * The `numberOfLoads` integer represents the number of dereferences this write corresponds to - * on the underlying container that produced the iterator. - */ - private predicate isChiAfterIteratorDef( - Instruction memory, Operand iteratorDerefAddress, Node0Impl value, int numberOfLoads - ) { - exists( - BaseSourceVariableInstruction iteratorBase, ReadSideEffectInstruction read, - Operand iteratorAddress - | - numberOfLoads >= 0 and - isDef(_, value, iteratorDerefAddress, iteratorBase, numberOfLoads + 2, 0) and - isUse(_, iteratorAddress, iteratorBase, numberOfLoads + 1, 0) and - iteratorBase.getResultType() instanceof Interfaces::Iterator and - isDereference(iteratorAddress.getDef(), read.getArgumentDef().getAUse(), _) and - memory = read.getSideEffectOperand().getAnyDef() - ) - } - - private predicate isSource(Instruction instr, Operand iteratorAddress, int numberOfLoads) { - getAUse(instr) = iteratorAddress and - exists(BaseSourceVariableInstruction iteratorBase | - iteratorBase.getResultType() instanceof Interfaces::Iterator and - not iteratorBase.getResultType() instanceof Cpp::PointerType and - isUse(_, iteratorAddress, iteratorBase, numberOfLoads - 1, 0) - ) - } - - private predicate isSink(Instruction instr, CallInstruction call) { - getAUse(instr).(ArgumentOperand).getCall() = call and - // Only include operations that may modify the object that the iterator points to. - // The following is a non-exhaustive list of things that may modify the value of the - // iterator, but never the value of what the iterator points to. - // The more things we can exclude here, the faster the small dataflow-like analysis - // done by `convertsIntoArgument` will converge. - not exists(Function f | f = call.getStaticCallTarget() | - f instanceof Iterator::IteratorCrementOperator or - f instanceof Iterator::IteratorBinaryArithmeticOperator or - f instanceof Iterator::IteratorAssignArithmeticOperator or - f instanceof Iterator::IteratorCrementMemberOperator or - f instanceof Iterator::IteratorBinaryArithmeticMemberOperator or - f instanceof Iterator::IteratorAssignArithmeticMemberOperator or - f instanceof Iterator::IteratorAssignmentMemberOperator - ) - } - - private predicate convertsIntoArgumentFwd(Instruction instr) { - isSource(instr, _, _) - or - exists(Instruction prev | convertsIntoArgumentFwd(prev) | - conversionFlow(unique( | | getAUse(prev)), instr, false, _) - ) - } - - private predicate convertsIntoArgumentRev(Instruction instr) { - convertsIntoArgumentFwd(instr) and - ( - isSink(instr, _) - or - exists(Instruction next | convertsIntoArgumentRev(next) | - conversionFlow(unique( | | getAUse(instr)), next, false, _) - ) - ) - } - - private predicate convertsIntoArgument( - Operand iteratorAddress, CallInstruction call, int numberOfLoads - ) { - exists(Instruction iteratorAddressDef | - isSource(iteratorAddressDef, iteratorAddress, numberOfLoads) and - isSink(iteratorAddressDef, call) and - convertsIntoArgumentRev(pragma[only_bind_into](iteratorAddressDef)) - ) - } - - private predicate isChiAfterIteratorArgument( - Instruction memory, Operand iteratorAddress, int numberOfLoads - ) { - // Ideally, `iteratorAddress` would be an `ArgumentOperand`, but there might be - // various conversions applied to it before it becomes an argument. - // So we do a small amount of flow to find the call that the iterator is passed to. - exists(CallInstruction call | convertsIntoArgument(iteratorAddress, call, numberOfLoads) | - exists(ReadSideEffectInstruction read | - read.getPrimaryInstruction() = call and - read.getSideEffectOperand().getAnyDef() = memory - ) - or - exists(LoadInstruction load | - iteratorAddress.getDef() = load and - memory = load.getSourceValueOperand().getAnyDef() - ) - ) - } - - /** - * Holds if `iterator` is a `StoreInstruction` that stores the result of some function - * returning an iterator into an address computed started at `containerBase`. - * - * For example, given a declaration like `std::vector::iterator it = v.begin()`, - * the `iterator` will be the `StoreInstruction` generated by the write to `it`, and - * `containerBase` will be the address of `v`. - */ - private predicate isChiAfterBegin( - BaseSourceVariableInstruction containerBase, StoreInstruction iterator - ) { - exists( - CallInstruction getIterator, Iterator::GetIteratorFunction getIteratorFunction, - IO::FunctionInput input, int i - | - getIterator = iterator.getSourceValue() and - getIteratorFunction = getIterator.getStaticCallTarget() and - getIteratorFunction.getsIterator(input, _) and - isDef(_, any(Node0Impl n | n.asInstruction() = iterator), _, _, 1, 0) and - input.isParameterDerefOrQualifierObject(i) and - isUse(_, getIterator.getArgumentOperand(i), containerBase, 0, 0) - ) - } - - /** - * Holds if `iteratorAddress` is an address of an iterator that is used for - * a read operation. The `memory` instruction represents the memory that - * the IR's SSA analysis determined was read by the call to `operator*`. - * - * Finally, the `numberOfLoads` integer represents the number of dereferences - * this read corresponds to on the underlying container that produced the iterator. - */ - private predicate isChiBeforeIteratorUse( - Operand iteratorAddress, Instruction memory, int numberOfLoads - ) { - exists( - BaseSourceVariableInstruction iteratorBase, LoadInstruction load, - ReadSideEffectInstruction read, Operand iteratorDerefAddress - | - numberOfLoads >= 0 and - isUse(_, iteratorAddress, iteratorBase, numberOfLoads + 1, 0) and - isUse(_, iteratorDerefAddress, iteratorBase, numberOfLoads + 2, 0) and - iteratorBase.getResultType() instanceof Interfaces::Iterator and - load.getSourceAddressOperand() = iteratorDerefAddress and - read.getPrimaryInstruction() = load.getSourceAddress() and - memory = read.getSideEffectOperand().getAnyDef() - ) - } - - /** - * Holds if `iteratorDerefAddress` is an address of an iterator dereference (i.e., `*it`) - * that is used for a write operation that writes the value `value` to a container that - * created the iterator. `container` represents the base of the address of the container - * that was used to create the iterator. - */ - cached - predicate isIteratorDef( - BaseSourceVariableInstruction container, Operand iteratorDerefAddress, Node0Impl value, - int numberOfLoads, int indirectionIndex - ) { - exists(Instruction memory, Instruction begin, int upper, int ind | - isChiAfterIteratorDef(memory, iteratorDerefAddress, value, numberOfLoads) and - memorySucc*(begin, memory) and - isChiAfterBegin(container, begin) and - upper = countIndirectionsForCppType(getResultLanguageType(container)) and - ind = numberOfLoads + [1 .. upper] and - indirectionIndex = ind - (numberOfLoads + 1) - ) - } - - /** - * Holds if `iteratorAddress` is an address of an iterator that is used for a - * read operation to read a value from a container that created the iterator. - * `container` represents the base of the address of the container that was used - * to create the iterator. - */ - cached - predicate isIteratorUse( - BaseSourceVariableInstruction container, Operand iteratorAddress, int numberOfLoads, - int indirectionIndex - ) { - // Direct use - exists(Instruction begin, Instruction memory, int upper, int ind | - isChiBeforeIteratorUse(iteratorAddress, memory, numberOfLoads) and - memorySucc*(begin, memory) and - isChiAfterBegin(container, begin) and - upper = countIndirectionsForCppType(getResultLanguageType(container)) and - ind = numberOfLoads + [1 .. upper] and - indirectionIndex = ind - (numberOfLoads + 1) - ) - or - // Use through function output - exists(Instruction memory, Instruction begin, int upper, int ind | - isChiAfterIteratorArgument(memory, iteratorAddress, numberOfLoads) and - memorySucc*(begin, memory) and - isChiAfterBegin(container, begin) and - upper = countIndirectionsForCppType(getResultLanguageType(container)) and - ind = numberOfLoads + [1 .. upper] and - indirectionIndex = ind - (numberOfLoads - 1) - ) - } - /** Holds if `op` is the only use of its defining instruction, and that op is used in a conversation */ private predicate isConversion(Operand op) { exists(Instruction def, Operand use | From 9874d40d29ea8b58ac52f758d89492006d1db572 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 26 Apr 2024 17:17:19 +0100 Subject: [PATCH 093/238] C++: Make 'getAddressOperand' available on 'DefImpl'. --- .../semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll index db8fafa13b0e..7649d3804d4d 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll @@ -256,11 +256,17 @@ abstract class DefImpl extends DefOrUseImpl { override string toString() { result = "Def of " + this.getSourceVariable() } + /** Gets the indirection of this definition. */ abstract int getIndirection(); + /** Holds if this definition is guaranteed to overwrite the entire destination allocation. */ abstract predicate isCertain(); + /** Gets the value stored by this definition (i.e., the "right-hand side", if any. */ abstract Node0Impl getValue(); + + /** Gets the operand representing the destination address of this definition, if any. */ + Operand getAddressOperand() { none() } } /** An initial definition of an `IRVariable`'s address. */ @@ -303,7 +309,7 @@ abstract private class OperandBasedDef extends DefImpl { bindingset[ind] OperandBasedDef() { any() } - Operand getAddressOperand() { result = address } + override Operand getAddressOperand() { result = address } override Cpp::Location getLocation() { result = this.getAddressOperand().getUse().getLocation() } From 50775d0c531fedc4c518aeaa7e6ab7feef9b92da Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Sat, 27 Apr 2024 15:29:12 +0100 Subject: [PATCH 094/238] C++: Get rid of 'UseImpl' in TSsaDefOrUse so that it now only contains definitions. --- .../cpp/ir/dataflow/internal/DataFlowUtil.qll | 6 +- .../cpp/ir/dataflow/internal/SsaInternals.qll | 633 +++++++++--------- 2 files changed, 301 insertions(+), 338 deletions(-) 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 94729c47fcb3..88a984e5dab1 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 @@ -1190,11 +1190,11 @@ class UninitializedNode extends Node { LocalVariable v; UninitializedNode() { - exists(Ssa::Def def | + exists(Ssa::Def def, Ssa::SourceVariable sv | def.getIndirectionIndex() = 0 and def.getValue().asInstruction() instanceof UninitializedInstruction and - Ssa::nodeToDefOrUse(this, def, _) and - v = def.getSourceVariable().getBaseVariable().(Ssa::BaseIRVariable).getIRVariable().getAst() + Ssa::defToNode(this, def, sv, _, _, _) and + v = sv.getBaseVariable().(Ssa::BaseIRVariable).getIRVariable().getAst() ) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll index 7649d3804d4d..7d2dc5d606d0 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll @@ -102,12 +102,20 @@ predicate hasRawIndirectInstruction(Instruction instr, int indirectionIndex) { } cached -private newtype TDefOrUseImpl = +private newtype TDefImpl = TDefAddressImpl(BaseIRVariable v) or - TDefImpl(BaseSourceVariableInstruction base, Operand address, int indirectionIndex) { + TDirectDefImpl(BaseSourceVariableInstruction base, Operand address, int indirectionIndex) { isDef(_, _, address, base, _, indirectionIndex) } or - TUseImpl(BaseSourceVariableInstruction base, Operand operand, int indirectionIndex) { + TGlobalDefImpl(GlobalLikeVariable v, IRFunction f, int indirectionIndex) { + // Represents the initial "definition" of a global variable when entering + // a function body. + isGlobalDefImpl(v, f, _, indirectionIndex) + } + +cached +private newtype TUseImpl = + TDirectUseImpl(BaseSourceVariableInstruction base, Operand operand, int indirectionIndex) { isUse(_, operand, base, _, indirectionIndex) and not isDef(true, _, operand, _, _, _) } or @@ -116,11 +124,6 @@ private newtype TDefOrUseImpl = // the assignment to a global variable isn't ruled out as dead. isGlobalUse(v, f, _, indirectionIndex) } or - TGlobalDefImpl(GlobalLikeVariable v, IRFunction f, int indirectionIndex) { - // Represents the initial "definition" of a global variable when entering - // a function body. - isGlobalDefImpl(v, f, _, indirectionIndex) - } or TFinalParameterUse(Parameter p, int indirectionIndex) { underlyingTypeIsModifiableAt(p.getUnderlyingType(), indirectionIndex) and // Only create an SSA read for the final use of a parameter if there's @@ -167,7 +170,12 @@ private predicate underlyingTypeIsModifiableAt(Type underlying, int indirectionI private Indirection getIndirectionForUnspecifiedType(Type t) { result.getType() = t } -abstract private class DefOrUseImpl extends TDefOrUseImpl { +abstract class DefImpl extends TDefImpl { + int indirectionIndex; + + bindingset[indirectionIndex] + DefImpl() { any() } + /** Gets a textual representation of this element. */ abstract string toString(); @@ -189,6 +197,9 @@ abstract private class DefOrUseImpl extends TDefOrUseImpl { /** Gets the location of this element. */ abstract Cpp::Location getLocation(); + /** Gets the indirection index of this definition. */ + final int getIndirectionIndex() { result = indirectionIndex } + /** * Gets the index (i.e., the number of loads required) of this * definition or use. @@ -197,7 +208,7 @@ abstract private class DefOrUseImpl extends TDefOrUseImpl { * the enclosing basic block. To obtain this index, use * `DefOrUseImpl::hasIndexInBlock/2` or `DefOrUseImpl::hasIndexInBlock/3`. */ - abstract int getIndirectionIndex(); + abstract int getIndirection(); /** * Gets the instruction that computes the base of this definition or use. @@ -215,17 +226,89 @@ abstract private class DefOrUseImpl extends TDefOrUseImpl { /** Gets the variable that is defined or used. */ SourceVariable getSourceVariable() { - exists(BaseSourceVariable v, int ind | - sourceVariableHasBaseAndIndex(result, v, ind) and - defOrUseHasSourceVariable(this, v, ind) + exists(BaseSourceVariable v, int indirection | + sourceVariableHasBaseAndIndex(result, v, indirection) and + defHasSourceVariable(this, v, indirection) ) } + + abstract predicate isCertain(); + + abstract Node0Impl getValue(); + + Operand getAddressOperand() { none() } } -private predicate defOrUseHasSourceVariable(DefOrUseImpl defOrUse, BaseSourceVariable bv, int ind) { - defHasSourceVariable(defOrUse, bv, ind) - or - useHasSourceVariable(defOrUse, bv, ind) +abstract class UseImpl extends TUseImpl { + int indirectionIndex; + + bindingset[indirectionIndex] + UseImpl() { any() } + + /** Gets the node associated with this use. */ + abstract Node getNode(); + + /** Gets a textual representation of this element. */ + abstract string toString(); + + /** Gets the block of this definition or use. */ + final IRBlock getBlock() { this.hasIndexInBlock(result, _) } + + /** Holds if this definition or use has index `index` in block `block`. */ + abstract predicate hasIndexInBlock(IRBlock block, int index); + + /** + * Holds if this definition (or use) has index `index` in block `block`, + * and is a definition (or use) of the variable `sv` + */ + final predicate hasIndexInBlock(IRBlock block, int index, SourceVariable sv) { + this.hasIndexInBlock(block, index) and + sv = this.getSourceVariable() + } + + /** Gets the location of this element. */ + abstract Cpp::Location getLocation(); + + /** + * Gets the index (i.e., the number of loads required) of this + * definition or use. + * + * Note that this is _not_ the definition's (or use's) index in + * the enclosing basic block. To obtain this index, use + * `DefOrUseImpl::hasIndexInBlock/2` or `DefOrUseImpl::hasIndexInBlock/3`. + */ + abstract int getIndirection(); + + /** Gets the indirection index of this use. */ + final int getIndirectionIndex() { result = indirectionIndex } + + /** + * Gets the instruction that computes the base of this definition or use. + * This is always a `VariableAddressInstruction` or an `CallInstruction`. + */ + abstract BaseSourceVariableInstruction getBase(); + + /** + * Gets the base source variable (i.e., the variable without + * any indirection) of this definition or use. + */ + final BaseSourceVariable getBaseSourceVariable() { + this.getBase().getBaseSourceVariable() = result + } + + /** Gets the variable that is defined or used. */ + SourceVariable getSourceVariable() { + exists(BaseSourceVariable v, int indirection | + sourceVariableHasBaseAndIndex(result, v, indirection) and + useHasSourceVariable(this, v, indirection) + ) + } + + /** + * Holds if this use is guaranteed to read the + * associated variable. + */ + abstract predicate isCertain(); } pragma[noinline] @@ -246,38 +329,17 @@ private predicate sourceVariableHasBaseAndIndex(SourceVariable v, BaseSourceVari v.getIndirection() = ind } -abstract class DefImpl extends DefOrUseImpl { - int ind; - - bindingset[ind] - DefImpl() { any() } - - override int getIndirectionIndex() { result = ind } - - override string toString() { result = "Def of " + this.getSourceVariable() } - - /** Gets the indirection of this definition. */ - abstract int getIndirection(); - - /** Holds if this definition is guaranteed to overwrite the entire destination allocation. */ - abstract predicate isCertain(); - - /** Gets the value stored by this definition (i.e., the "right-hand side", if any. */ - abstract Node0Impl getValue(); - - /** Gets the operand representing the destination address of this definition, if any. */ - Operand getAddressOperand() { none() } -} - /** An initial definition of an `IRVariable`'s address. */ private class DefAddressImpl extends DefImpl, TDefAddressImpl { BaseIRVariable v; DefAddressImpl() { this = TDefAddressImpl(v) and - ind = 0 + indirectionIndex = 0 } + override string toString() { result = "Def of &" + v.toString() } + final override int getIndirection() { result = 0 } final override predicate isCertain() { any() } @@ -299,77 +361,45 @@ private class DefAddressImpl extends DefImpl, TDefAddressImpl { final override BaseSourceVariableInstruction getBase() { none() } } -/** - * An SSA definition that has an associated `Operand` representing the address - * that is being written to. - */ -abstract private class OperandBasedDef extends DefImpl { +private class DirectDef extends DefImpl, TDirectDefImpl { Operand address; + BaseSourceVariableInstruction base; - bindingset[ind] - OperandBasedDef() { any() } - - override Operand getAddressOperand() { result = address } + DirectDef() { this = TDirectDefImpl(base, address, indirectionIndex) } override Cpp::Location getLocation() { result = this.getAddressOperand().getUse().getLocation() } final override predicate hasIndexInBlock(IRBlock block, int index) { this.getAddressOperand().getUse() = block.getInstruction(index) } -} -private class DirectDef extends OperandBasedDef, TDefImpl { - BaseSourceVariableInstruction base; + override string toString() { result = "Def of " + this.getSourceVariable() } - DirectDef() { this = TDefImpl(base, address, ind) } + override Operand getAddressOperand() { result = address } override BaseSourceVariableInstruction getBase() { result = base } - override int getIndirection() { isDef(_, _, address, base, result, ind) } + override int getIndirection() { isDef(_, _, address, base, result, indirectionIndex) } override Node0Impl getValue() { isDef(_, result, address, base, _, _) } - override predicate isCertain() { isDef(true, _, address, base, _, ind) } -} - -abstract class UseImpl extends DefOrUseImpl { - int ind; - - bindingset[ind] - UseImpl() { any() } - - /** Gets the node associated with this use. */ - abstract Node getNode(); - - override string toString() { result = "Use of " + this.getSourceVariable() } - - /** Gets the indirection index of this use. */ - final override int getIndirectionIndex() { result = ind } - - /** Gets the number of loads that precedence this use. */ - abstract int getIndirection(); - - /** - * Holds if this use is guaranteed to read the - * associated variable. - */ - abstract predicate isCertain(); + override predicate isCertain() { isDef(true, _, address, base, _, indirectionIndex) } } -abstract private class OperandBasedUse extends UseImpl { +private class DirectUseImpl extends UseImpl, TDirectUseImpl { Operand operand; BaseSourceVariableInstruction base; - bindingset[ind] - OperandBasedUse() { any() } + DirectUseImpl() { this = TDirectUseImpl(base, operand, indirectionIndex) } + + override string toString() { result = "Use of " + this.getSourceVariable() } final override predicate hasIndexInBlock(IRBlock block, int index) { // See the comment in `ssa0`'s `OperandBasedUse` for an explanation of this // predicate's implementation. if base.getAst() = any(Cpp::PostfixCrementOperation c).getOperand() then - exists(Operand op, int indirectionIndex, int indirection | - indirectionIndex = this.getIndirectionIndex() and + exists(Operand op, int indirection | indirection = this.getIndirection() and op = min(Operand cand, int i | @@ -388,16 +418,12 @@ abstract private class OperandBasedUse extends UseImpl { final Operand getOperand() { result = operand } final override Cpp::Location getLocation() { result = operand.getLocation() } -} -private class DirectUse extends OperandBasedUse, TUseImpl { - DirectUse() { this = TUseImpl(base, operand, ind) } + override int getIndirection() { isUse(_, operand, base, result, indirectionIndex) } - override int getIndirection() { isUse(_, operand, base, result, ind) } + override predicate isCertain() { isUse(true, operand, base, _, indirectionIndex) } - override predicate isCertain() { isUse(true, operand, base, _, ind) } - - override Node getNode() { nodeHasOperand(result, operand, ind) } + override Node getNode() { nodeHasOperand(result, operand, indirectionIndex) } } pragma[nomagic] @@ -411,15 +437,17 @@ private predicate finalParameterNodeHasParameterAndIndex( class FinalParameterUse extends UseImpl, TFinalParameterUse { Parameter p; - FinalParameterUse() { this = TFinalParameterUse(p, ind) } + FinalParameterUse() { this = TFinalParameterUse(p, indirectionIndex) } + + override string toString() { result = "Use of " + p.toString() } Parameter getParameter() { result = p } int getArgumentIndex() { result = p.getIndex() } - override Node getNode() { finalParameterNodeHasParameterAndIndex(result, p, ind) } + override Node getNode() { finalParameterNodeHasParameterAndIndex(result, p, indirectionIndex) } - override int getIndirection() { result = ind + 1 } + override int getIndirection() { result = indirectionIndex + 1 } override predicate isCertain() { any() } @@ -516,11 +544,13 @@ class GlobalUse extends UseImpl, TGlobalUse { GlobalLikeVariable global; IRFunction f; - GlobalUse() { this = TGlobalUse(global, f, ind) } + GlobalUse() { this = TGlobalUse(global, f, indirectionIndex) } + + override string toString() { result = "Use of " + global } override FinalGlobalValue getNode() { result.getGlobalUse() = this } - override int getIndirection() { isGlobalUse(global, f, result, ind) } + override int getIndirection() { isGlobalUse(global, f, result, indirectionIndex) } /** Gets the global variable associated with this use. */ GlobalLikeVariable getVariable() { result = global } @@ -570,10 +600,9 @@ class GlobalUse extends UseImpl, TGlobalUse { * * See the QLDoc for `GlobalUse` for how this is used. */ -class GlobalDefImpl extends DefOrUseImpl, TGlobalDefImpl { +class GlobalDefImpl extends DefImpl, TGlobalDefImpl { GlobalLikeVariable global; IRFunction f; - int indirectionIndex; GlobalDefImpl() { this = TGlobalDefImpl(global, f, indirectionIndex) } @@ -583,9 +612,6 @@ class GlobalDefImpl extends DefOrUseImpl, TGlobalDefImpl { /** Gets the `IRFunction` whose body is evaluated after this definition. */ IRFunction getIRFunction() { result = f } - /** Gets the global variable associated with this definition. */ - override int getIndirectionIndex() { result = indirectionIndex } - /** Holds if this definition or use has index `index` in block `block`. */ final override predicate hasIndexInBlock(IRBlock block, int index) { exists(EnterFunctionInstruction enter | @@ -599,7 +625,11 @@ class GlobalDefImpl extends DefOrUseImpl, TGlobalDefImpl { sourceVariableIsGlobal(result, global, f, this.getIndirection()) } - int getIndirection() { result = indirectionIndex } + override int getIndirection() { result = indirectionIndex } + + override Node0Impl getValue() { none() } + + override predicate isCertain() { any() } /** * Gets the type of this definition after specifiers have been deeply @@ -620,60 +650,30 @@ class GlobalDefImpl extends DefOrUseImpl, TGlobalDefImpl { } /** - * Holds if `defOrUse1` is a definition which is first read by `use`, - * or if `defOrUse1` is a use and `use` is a next subsequent use. - * - * In both cases, `use` can either be an explicit use written in the - * source file, or it can be a phi node as computed by the SSA library. + * Holds if there is a definition or access at index `i1` in basic block `bb1` + * and the next subsequent read is at index `i2` in basic block `bb2`. */ -predicate adjacentDefRead(DefOrUse defOrUse1, UseOrPhi use) { - exists(IRBlock bb1, int i1, SourceVariable v | - defOrUse1 - .asDefOrUse() - .hasIndexInBlock(pragma[only_bind_out](bb1), pragma[only_bind_out](i1), - pragma[only_bind_out](v)) - | - exists(IRBlock bb2, int i2, DefinitionExt def | - adjacentDefReadExt(pragma[only_bind_into](def), pragma[only_bind_into](bb1), - pragma[only_bind_into](i1), pragma[only_bind_into](bb2), pragma[only_bind_into](i2)) and - def.getSourceVariable() = v and - use.asDefOrUse().(UseImpl).hasIndexInBlock(bb2, i2, v) - ) - or - exists(PhiNode phi | - lastRefRedefExt(_, bb1, i1, phi) and - use.asPhi() = phi and - phi.getSourceVariable() = pragma[only_bind_into](v) - ) +predicate adjacentDefRead(IRBlock bb1, int i1, SourceVariable sv, IRBlock bb2, int i2) { + adjacentDefReadExt(_, sv, bb1, i1, bb2, i2) + or + exists(PhiNode phi | + lastRefRedefExt(_, sv, bb1, i1, phi) and + phi.definesAt(sv, bb2, i2, _) ) } -/** - * Holds if `globalDef` represents the initial definition of a global variable that - * flows to `useOrPhi`. - */ -private predicate globalDefToUse(GlobalDef globalDef, UseOrPhi useOrPhi) { - exists(IRBlock bb1, int i1, SourceVariable v | - globalDef - .hasIndexInBlock(pragma[only_bind_out](bb1), pragma[only_bind_out](i1), - pragma[only_bind_out](v)) - | - exists(IRBlock bb2, int i2 | - adjacentDefReadExt(_, pragma[only_bind_into](bb1), pragma[only_bind_into](i1), - pragma[only_bind_into](bb2), pragma[only_bind_into](i2)) and - useOrPhi.asDefOrUse().hasIndexInBlock(bb2, i2, v) - ) - or - exists(PhiNode phi | - lastRefRedefExt(_, bb1, i1, phi) and - useOrPhi.asPhi() = phi and - phi.getSourceVariable() = pragma[only_bind_into](v) - ) +predicate useToNode(IRBlock bb, int i, SourceVariable sv, Node nodeTo) { + exists(Phi phi | + phi.asPhi().definesAt(sv, bb, i, _) and + nodeTo = phi.getNode() + ) + or + exists(UseImpl use | + use.hasIndexInBlock(bb, i, sv) and + nodeTo = use.getNode() ) } -private predicate useToNode(UseOrPhi use, Node nodeTo) { use.getNode() = nodeTo } - pragma[noinline] predicate outNodeHasAddressAndIndex( IndirectArgumentOutNode out, Operand address, int indirectionIndex @@ -682,11 +682,19 @@ predicate outNodeHasAddressAndIndex( out.getIndirectionIndex() = indirectionIndex } -private predicate defToNode(Node nodeFrom, Def def, boolean uncertain) { +/** + * INTERNAL: Do not use. + * + * Holds if `node` is the node that corresponds to the definition of `def`. + */ +predicate defToNode(Node node, Def def, SourceVariable sv, IRBlock bb, int i, boolean uncertain) { + def.hasIndexInBlock(bb, i, sv) and ( - nodeHasOperand(nodeFrom, def.getValue().asOperand(), def.getIndirectionIndex()) + nodeHasOperand(node, def.getValue().asOperand(), def.getIndirectionIndex()) + or + nodeHasInstruction(node, def.getValue().asInstruction(), def.getIndirectionIndex()) or - nodeHasInstruction(nodeFrom, def.getValue().asInstruction(), def.getIndirectionIndex()) + node.(InitialGlobalValue).getGlobalDef() = def ) and if def.isCertain() then uncertain = false else uncertain = true } @@ -694,14 +702,16 @@ private predicate defToNode(Node nodeFrom, Def def, boolean uncertain) { /** * INTERNAL: Do not use. * - * Holds if `nodeFrom` is the node that correspond to the definition or use `defOrUse`. + * Holds if `node` is the node that corresponds to the definition or use at + * index `i` in block `bb` of `sv`. + * + * `uncertain` is `true` if this is an uncertain definition. */ -predicate nodeToDefOrUse(Node nodeFrom, SsaDefOrUse defOrUse, boolean uncertain) { - // Node -> Def - defToNode(nodeFrom, defOrUse, uncertain) +predicate nodeToDefOrUse(Node node, SourceVariable sv, IRBlock bb, int i, boolean uncertain) { + defToNode(node, _, sv, bb, i, uncertain) or // Node -> Use - useToNode(defOrUse, nodeFrom) and + useToNode(bb, i, sv, node) and uncertain = false } @@ -710,9 +720,9 @@ predicate nodeToDefOrUse(Node nodeFrom, SsaDefOrUse defOrUse, boolean uncertain) * only holds when there is no use-use relation out of `nTo`. */ private predicate indirectConversionFlowStep(Node nFrom, Node nTo) { - not exists(UseOrPhi defOrUse | - nodeToDefOrUse(nTo, defOrUse, _) and - adjacentDefRead(defOrUse, _) + not exists(SourceVariable sv, IRBlock bb2, int i2 | + nodeToDefOrUse(nTo, sv, bb2, i2, _) and + adjacentDefRead(bb2, i2, sv, _, _) ) and ( exists(Operand op1, Operand op2, int indirectionIndex, Instruction instr | @@ -746,60 +756,38 @@ private predicate indirectConversionFlowStep(Node nFrom, Node nTo) { * So this predicate recurses back along conversions and `PointerArithmeticInstruction`s to find the * first use that has provides use-use flow, and uses that target as the target of the `nodeFrom`. */ -private predicate adjustForPointerArith(PostUpdateNode pun, UseOrPhi use) { - exists(DefOrUse defOrUse, Node adjusted | +private predicate adjustForPointerArith(PostUpdateNode pun, SourceVariable sv, IRBlock bb2, int i2) { + exists(IRBlock bb1, int i1, Node adjusted | indirectConversionFlowStep*(adjusted, pun.getPreUpdateNode()) and - nodeToDefOrUse(adjusted, defOrUse, _) and - adjacentDefRead(defOrUse, use) + nodeToDefOrUse(adjusted, sv, bb1, i1, _) and + adjacentDefRead(bb1, i1, sv, bb2, i2) ) } /** - * Holds if `nodeFrom` flows to `nodeTo` because there is `def-use` or - * `use-use` flow from `defOrUse` to `use`. + * Holds if there should be flow from `nodeFrom` to `nodeTo` because + * `nodeFrom` is a definition or use of `sv` at index `i1` at basic + * block `bb1`. * - * `uncertain` is `true` if the `defOrUse` is an uncertain definition. + * `uncertain` is `true` if the this is an uncertain definition. */ -private predicate localSsaFlow( - SsaDefOrUse defOrUse, Node nodeFrom, UseOrPhi use, Node nodeTo, boolean uncertain +private predicate ssaFlowImpl( + IRBlock bb1, int i1, SourceVariable sv, Node nodeFrom, Node nodeTo, boolean uncertain ) { - nodeToDefOrUse(nodeFrom, defOrUse, uncertain) and - adjacentDefRead(defOrUse, use) and - useToNode(use, nodeTo) and + exists(IRBlock bb2, int i2 | + nodeToDefOrUse(nodeFrom, sv, bb1, i1, uncertain) and + adjacentDefRead(bb1, i1, sv, bb2, i2) and + useToNode(bb2, i2, sv, nodeTo) + ) and nodeFrom != nodeTo } -private predicate ssaFlowImpl(SsaDefOrUse defOrUse, Node nodeFrom, Node nodeTo, boolean uncertain) { - exists(UseOrPhi use | - localSsaFlow(defOrUse, nodeFrom, use, nodeTo, uncertain) - or - // Initial global variable value to a first use - nodeFrom.(InitialGlobalValue).getGlobalDef() = defOrUse and - globalDefToUse(defOrUse, use) and - useToNode(use, nodeTo) and - uncertain = false - ) -} - -/** - * Holds if `def` is the corresponding definition of - * the SSA library's `definition`. - */ -private DefinitionExt ssaDefinition(Def def) { - exists(IRBlock block, int i, SourceVariable sv | - def.hasIndexInBlock(block, i, sv) and - result.definesAt(sv, block, i, _) - ) -} - /** Gets a node that represents the prior definition of `node`. */ -private Node getAPriorDefinition(SsaDefOrUse defOrUse) { - exists(IRBlock bb, int i, SourceVariable sv, DefinitionExt def, DefOrUse defOrUse0 | - lastRefRedefExt(pragma[only_bind_into](def), pragma[only_bind_into](bb), - pragma[only_bind_into](i), ssaDefinition(defOrUse)) and - def.getSourceVariable() = sv and - defOrUse0.hasIndexInBlock(bb, i, sv) and - nodeToDefOrUse(result, defOrUse0, _) +private Node getAPriorDefinition(DefinitionExt next) { + exists(IRBlock bb, int i, SourceVariable sv | + lastRefRedefExt(_, pragma[only_bind_into](sv), pragma[only_bind_into](bb), + pragma[only_bind_into](i), next) and + nodeToDefOrUse(result, sv, bb, i, _) ) } @@ -851,12 +839,16 @@ private predicate modeledFlowBarrier(Node n) { /** Holds if there is def-use or use-use flow from `nodeFrom` to `nodeTo`. */ predicate ssaFlow(Node nodeFrom, Node nodeTo) { - exists(Node nFrom, boolean uncertain, SsaDefOrUse defOrUse | - ssaFlowImpl(defOrUse, nFrom, nodeTo, uncertain) and + exists(Node nFrom, boolean uncertain, IRBlock bb, int i, SourceVariable sv | + ssaFlowImpl(bb, i, sv, nFrom, nodeTo, uncertain) and not modeledFlowBarrier(nFrom) and nodeFrom != nodeTo | - if uncertain = true then nodeFrom = [nFrom, getAPriorDefinition(defOrUse)] else nodeFrom = nFrom + if uncertain = true + then + nodeFrom = + [nFrom, getAPriorDefinition(any(DefinitionExt next | next.definesAt(sv, bb, i, _)))] + else nodeFrom = nFrom ) } @@ -901,15 +893,15 @@ private predicate isArgumentOfCallable(DataFlowCall call, Node n) { * Holds if there is use-use flow from `pun`'s pre-update node to `n`. */ private predicate postUpdateNodeToFirstUse(PostUpdateNode pun, Node n) { - exists(UseOrPhi use | - adjustForPointerArith(pun, use) and - useToNode(use, n) + exists(SourceVariable sv, IRBlock bb2, int i2 | + adjustForPointerArith(pun, sv, bb2, i2) and + useToNode(bb2, i2, sv, n) ) } private predicate stepUntilNotInCall(DataFlowCall call, Node n1, Node n2) { isArgumentOfCallable(call, n1) and - exists(Node mid | localSsaFlow(_, n1, _, mid, _) | + exists(Node mid | ssaFlowImpl(_, _, _, n1, mid, _) | isArgumentOfCallable(call, mid) and stepUntilNotInCall(call, mid, n2) or @@ -956,35 +948,13 @@ predicate postUpdateFlow(PostUpdateNode pun, Node nodeTo) { ) } -/** - * Holds if `use` is a use of `sv` and is a next adjacent use of `phi` in - * index `i1` in basic block `bb1`. - * - * This predicate exists to prevent an early join of `adjacentDefRead` with `definesAt`. - */ -pragma[nomagic] -private predicate fromPhiNodeToUse(PhiNode phi, SourceVariable sv, IRBlock bb1, int i1, UseOrPhi use) { - exists(IRBlock bb2, int i2 | - use.asDefOrUse().hasIndexInBlock(bb2, i2, sv) and - adjacentDefReadExt(pragma[only_bind_into](phi), pragma[only_bind_into](bb1), - pragma[only_bind_into](i1), pragma[only_bind_into](bb2), pragma[only_bind_into](i2)) - ) -} - /** Holds if `nodeTo` receives flow from the phi node `nodeFrom`. */ predicate fromPhiNode(SsaPhiNode nodeFrom, Node nodeTo) { - exists(PhiNode phi, SourceVariable sv, IRBlock bb1, int i1, UseOrPhi use | + exists(PhiNode phi, SourceVariable sv, IRBlock bb1, int i1, IRBlock bb2, int i2 | phi = nodeFrom.getPhiNode() and phi.definesAt(sv, bb1, i1, _) and - useToNode(use, nodeTo) - | - fromPhiNodeToUse(phi, sv, bb1, i1, use) - or - exists(PhiNode phiTo | - phi != phiTo and - lastRefRedefExt(phi, bb1, i1, phiTo) and - nodeTo.(SsaPhiNode).getPhiNode() = phiTo - ) + adjacentDefRead(bb1, i1, sv, bb2, i2) and + useToNode(bb2, i2, sv, nodeTo) ) } @@ -1049,8 +1019,10 @@ module SsaCached { * path between them without any read of `def`. */ cached - predicate adjacentDefReadExt(DefinitionExt def, IRBlock bb1, int i1, IRBlock bb2, int i2) { - SsaImpl::adjacentDefReadExt(def, _, bb1, i1, bb2, i2) + predicate adjacentDefReadExt( + DefinitionExt def, SourceVariable sv, IRBlock bb1, int i1, IRBlock bb2, int i2 + ) { + SsaImpl::adjacentDefReadExt(def, sv, bb1, i1, bb2, i2) } /** @@ -1059,32 +1031,24 @@ module SsaCached { * without passing through another read or write. */ cached - predicate lastRefRedefExt(DefinitionExt def, IRBlock bb, int i, DefinitionExt next) { - SsaImpl::lastRefRedefExt(def, _, bb, i, next) + predicate lastRefRedefExt( + DefinitionExt def, SourceVariable sv, IRBlock bb, int i, DefinitionExt next + ) { + SsaImpl::lastRefRedefExt(def, sv, bb, i, next) } } cached -private newtype TSsaDefOrUse = - TDefOrUse(DefOrUseImpl defOrUse) { - defOrUse instanceof UseImpl - or - // Like in the pruning stage, we only include definition that's live after the - // write as the final definitions computed by SSA. - exists(DefinitionExt def, SourceVariable sv, IRBlock bb, int i | - def.definesAt(sv, bb, i, _) and - defOrUse.(DefImpl).hasIndexInBlock(bb, i, sv) - ) - } or - TPhi(PhiNode phi) or - TGlobalDef(GlobalDefImpl global) +private newtype TSsaDef = + TDef(DefinitionExt def) or + TPhi(PhiNode phi) -abstract private class SsaDefOrUse extends TSsaDefOrUse { +abstract private class SsaDef extends TSsaDef { /** Gets a textual representation of this element. */ string toString() { none() } /** Gets the underlying non-phi definition or use. */ - DefOrUseImpl asDefOrUse() { none() } + DefinitionExt asDef() { none() } /** Gets the underlying phi node. */ PhiNode asPhi() { none() } @@ -1093,52 +1057,94 @@ abstract private class SsaDefOrUse extends TSsaDefOrUse { abstract Location getLocation(); } -class DefOrUse extends TDefOrUse, SsaDefOrUse { - DefOrUseImpl defOrUse; - - DefOrUse() { this = TDefOrUse(defOrUse) } +abstract class Def extends SsaDef, TDef { + DefinitionExt def; - final override DefOrUseImpl asDefOrUse() { result = defOrUse } + Def() { this = TDef(def) } - final override Location getLocation() { result = defOrUse.getLocation() } + final override DefinitionExt asDef() { result = def } - final SourceVariable getSourceVariable() { result = defOrUse.getSourceVariable() } + /** Gets the source variable underlying this SSA definition. */ + final SourceVariable getSourceVariable() { result = def.getSourceVariable() } - override string toString() { result = defOrUse.toString() } + override string toString() { result = def.toString() } /** * Holds if this definition (or use) has index `index` in block `block`, * and is a definition (or use) of the variable `sv`. */ predicate hasIndexInBlock(IRBlock block, int index, SourceVariable sv) { - defOrUse.hasIndexInBlock(block, index, sv) + def.definesAt(sv, block, index, _) } -} -class GlobalDef extends TGlobalDef, SsaDefOrUse { - GlobalDefImpl global; + /** Gets the value written by this definition, if any. */ + Node0Impl getValue() { none() } - GlobalDef() { this = TGlobalDef(global) } + /** + * Holds if this definition is guaranteed to overwrite the entire + * destination's allocation. + */ + abstract predicate isCertain(); - /** Gets the location of this definition. */ - final override Location getLocation() { result = global.getLocation() } + /** Gets the address operand written to by this definition. */ + Operand getAddressOperand() { none() } - /** Gets a textual representation of this definition. */ - override string toString() { result = global.toString() } + /** Gets the address written to by this definition. */ + final Instruction getAddress() { result = this.getAddressOperand().getDef() } + + /** Gets the indirection index of this definition. */ + abstract int getIndirectionIndex(); /** - * Holds if this definition has index `index` in block `block`, and - * is a definition of the variable `sv`. + * Gets the indirection level that this definition is writing to. + * For instance, `x = y` is a definition of `x` at indirection level 1 and + * `*x = y` is a definition of `x` at indirection level 2. + * + * This predicate ensures that joins go from `defOrUse` to the result + * instead of the other way around. */ - predicate hasIndexInBlock(IRBlock block, int index, SourceVariable sv) { - global.hasIndexInBlock(block, index, sv) + abstract int getIndirection(); +} + +private predicate isGlobal(DefinitionExt def, GlobalDefImpl global) { + exists(SourceVariable sv, IRBlock bb, int i | + def.definesAt(sv, bb, i, _) and + global.hasIndexInBlock(bb, i, sv) + ) +} + +private class NonGlobalDef extends Def { + NonGlobalDef() { not isGlobal(def, _) } + + final override Location getLocation() { result = this.getImpl().getLocation() } + + private DefImpl getImpl() { + exists(SourceVariable sv, IRBlock bb, int i | + this.hasIndexInBlock(bb, i, sv) and + result.hasIndexInBlock(bb, i, sv) + ) } - /** Gets the indirection index of this definition. */ - int getIndirection() { result = global.getIndirection() } + override Node0Impl getValue() { result = this.getImpl().getValue() } - /** Gets the indirection index of this definition. */ - int getIndirectionIndex() { result = global.getIndirectionIndex() } + override predicate isCertain() { this.getImpl().isCertain() } + + override Operand getAddressOperand() { result = this.getImpl().getAddressOperand() } + + override int getIndirectionIndex() { result = this.getImpl().getIndirectionIndex() } + + override int getIndirection() { result = this.getImpl().getIndirection() } +} + +class GlobalDef extends Def { + GlobalDefImpl global; + + GlobalDef() { isGlobal(def, global) } + + /** Gets a textual representation of this definition. */ + override string toString() { result = global.toString() } + + final override Location getLocation() { result = global.getLocation() } /** * Gets the type of this definition after specifiers have been deeply stripped @@ -1156,9 +1162,15 @@ class GlobalDef extends TGlobalDef, SsaDefOrUse { /** Gets the global variable associated with this definition. */ GlobalLikeVariable getVariable() { result = global.getVariable() } + + override predicate isCertain() { any() } + + final override int getIndirectionIndex() { result = global.getIndirectionIndex() } + + final override int getIndirection() { result = global.getIndirection() } } -class Phi extends TPhi, SsaDefOrUse { +class Phi extends TPhi, SsaDef { PhiNode phi; Phi() { this = TPhi(phi) } @@ -1172,62 +1184,13 @@ class Phi extends TPhi, SsaDefOrUse { SsaPhiNode getNode() { result.getPhiNode() = phi } } -class UseOrPhi extends SsaDefOrUse { - UseOrPhi() { - this.asDefOrUse() instanceof UseImpl - or - this instanceof Phi - } - - final override Location getLocation() { - result = this.asDefOrUse().getLocation() or result = this.(Phi).getLocation() - } - - final Node getNode() { - result = this.(Phi).getNode() - or - result = this.asDefOrUse().(UseImpl).getNode() - } -} - -class Def extends DefOrUse { - override DefImpl defOrUse; - - Operand getAddressOperand() { result = defOrUse.(OperandBasedDef).getAddressOperand() } - - Instruction getAddress() { result = this.getAddressOperand().getDef() } - - /** - * Gets the indirection index of this definition. - * - * This predicate ensures that joins go from `defOrUse` to the result - * instead of the other way around. - */ - pragma[inline] - int getIndirectionIndex() { - pragma[only_bind_into](result) = pragma[only_bind_out](defOrUse).getIndirectionIndex() - } - - /** - * Gets the indirection level that this definition is writing to. - * For instance, `x = y` is a definition of `x` at indirection level 1 and - * `*x = y` is a definition of `x` at indirection level 2. - * - * This predicate ensures that joins go from `defOrUse` to the result - * instead of the other way around. - */ - pragma[inline] - int getIndirection() { - pragma[only_bind_into](result) = pragma[only_bind_out](defOrUse).getIndirection() - } - - Node0Impl getValue() { result = defOrUse.getValue() } - - predicate isCertain() { defOrUse.isCertain() } -} - private module SsaImpl = SsaImplCommon::Make; +/** + * An static single assignment (SSA) phi node. + * + * This is either a normal phi node or a phi-read node. + */ class PhiNode extends SsaImpl::DefinitionExt { PhiNode() { this instanceof SsaImpl::PhiNode or @@ -1245,6 +1208,6 @@ class PhiNode extends SsaImpl::DefinitionExt { class DefinitionExt = SsaImpl::DefinitionExt; -class UncertainWriteDefinition = SsaImpl::UncertainWriteDefinition; +class Definition = SsaImpl::Definition; import SsaCached From d62e888b86904d9541490388857b3cfa36d67471 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 29 Apr 2024 09:27:12 +0200 Subject: [PATCH 095/238] C#: Code quality improvements. --- .../Assets.cs | 6 +++--- .../DependencyContainer.cs | 10 +++++----- .../NugetPackageRestorer.cs | 13 +++++-------- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/Assets.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/Assets.cs index 511db0871d9a..4082146f5920 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/Assets.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/Assets.cs @@ -17,7 +17,7 @@ internal class Assets private readonly ILogger logger; /// - /// Contains the dependencies found in the parsed asset files. + /// Contains the dependencies found in the parsed assets files. /// public DependencyContainer Dependencies { get; } = new(); @@ -225,7 +225,7 @@ private static bool TryReadAllText(string path, ILogger logger, [NotNullWhen(ret /// /// Add the dependencies from the assets file to the dependencies. /// - /// Path to an asset file. + /// Path to an assets file. public void AddDependencies(string asset) { if (TryReadAllText(asset, logger, out var json)) @@ -237,7 +237,7 @@ public void AddDependencies(string asset) /// /// Add the dependencies from the assets files to the dependencies. /// - /// Collection of paths to asset files. + /// Collection of paths to assets files. public void AddDependenciesRange(IEnumerable assets) => assets.ForEach(AddDependencies); } diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyContainer.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyContainer.cs index 6251fa321243..230731104124 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyContainer.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyContainer.cs @@ -45,7 +45,7 @@ public void Add(string package, string dependency) var p = package.Replace('/', Path.DirectorySeparatorChar); var d = dependency.Replace('/', Path.DirectorySeparatorChar); - // In most cases paths in asset files point to dll's or the empty _._ file. + // In most cases paths in assets files point to dll's or the empty _._ file. // That is, for _._ we don't need to add anything. if (Path.GetFileName(d) == "_._") { @@ -74,11 +74,11 @@ internal static class DependencyContainerExtensions /// /// Flatten a list of containers into a single container. /// - public static DependencyContainer Flatten(this IEnumerable container) => - container.Aggregate(new DependencyContainer(), (acc, c) => + public static DependencyContainer Flatten(this IEnumerable containers, DependencyContainer init) => + containers.Aggregate(init, (acc, container) => { - acc.Paths.UnionWith(c.Paths); - acc.Packages.UnionWith(c.Packages); + acc.Paths.UnionWith(container.Paths); + acc.Packages.UnionWith(container.Packages); return acc; }); } diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs index 371b33dfecaa..307be1244eb5 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; @@ -148,8 +149,7 @@ public HashSet Restore() var projects = fileProvider.Projects.Except(restoredProjects); RestoreProjects(projects, out var containers); - containers.Add(container); - var dependencies = containers.Flatten(); + var dependencies = containers.Flatten(container); var paths = dependencies .Paths @@ -235,11 +235,11 @@ private IEnumerable RestoreSolutions(out DependencyContainer dependencie /// Populates dependencies with the relative paths to the assets files generated by the restore. /// /// A list of paths to project files. - private void RestoreProjects(IEnumerable projects, out List dependencies) + private void RestoreProjects(IEnumerable projects, out ConcurrentBag dependencies) { var successCount = 0; var nugetSourceFailures = 0; - List collectedDependencies = []; + ConcurrentBag collectedDependencies = []; var sync = new object(); var projectGroups = projects.GroupBy(Path.GetDirectoryName); Parallel.ForEach(projectGroups, new ParallelOptions { MaxDegreeOfParallelism = DependencyManager.Threads }, projectGroup => @@ -262,10 +262,7 @@ private void RestoreProjects(IEnumerable projects, out List Date: Mon, 29 Apr 2024 10:29:53 +0200 Subject: [PATCH 096/238] Go: workaround for gazelle on macOS See https://github.com/bazelbuild/bazel-gazelle/issues/1793 for details. --- MODULE.bazel | 6 +++++- go/BUILD.bazel | 13 +++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/MODULE.bazel b/MODULE.bazel index 6daa5a98215b..5fd99f767404 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -56,7 +56,11 @@ node.toolchain( use_repo(node, "nodejs", "nodejs_toolchains") go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk") -go_sdk.download(version = "1.22.2") +go_sdk.download(version = "1.22.2") # default + +# following is needed for gazelle on macOS +# see https://github.com/bazelbuild/bazel-gazelle/issues/1793 +go_sdk.download(version = "1.21.9") register_toolchains( "@nodejs_toolchains//:all", diff --git a/go/BUILD.bazel b/go/BUILD.bazel index 50e2bc0d447d..41113d45f518 100644 --- a/go/BUILD.bazel +++ b/go/BUILD.bazel @@ -1,12 +1,25 @@ load("@bazel_skylib//rules:native_binary.bzl", "native_binary") load("@gazelle//:def.bzl", "gazelle") +load("@rules_go//go:def.bzl", "go_cross_binary") load("@rules_pkg//pkg:install.bzl", "pkg_install") load("@rules_pkg//pkg:mappings.bzl", "pkg_attributes", "pkg_filegroup", "pkg_files") load("//:defs.bzl", "codeql_platform") +# following is needed for running gazelle on macOS +# see https://github.com/bazelbuild/bazel-gazelle/issues/1793 +go_cross_binary( + name = "gazelle-1.21.9", + sdk_version = "1.21.9", + target = "@gazelle//cmd/gazelle", +) + gazelle( name = "gazelle", extra_args = ["go/extractor"], + gazelle = select({ + "@platforms//os:macos": ":gazelle-1.21.9", + "//conditions:default": "@gazelle//cmd/gazelle", + }), ) _gen_binaries = [ From 0dfd3367291da2e84b2dbe95f57d3ae054992bf3 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Mon, 29 Apr 2024 10:34:22 +0200 Subject: [PATCH 097/238] Go: fix `//go:gen` on windows --- go/gen.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/go/gen.py b/go/gen.py index 4b4cac0e46f2..b9394cd15b28 100644 --- a/go/gen.py +++ b/go/gen.py @@ -1,11 +1,17 @@ import sys import pathlib import subprocess +import os from python.runfiles import runfiles -this = pathlib.Path(__file__).resolve() -go_extractor_dir = this.parent / "extractor" -go_dbscheme = this.parent / "ql" / "lib" / "go.dbscheme" +try: + workspace_dir = pathlib.Path(os.environ['BUILD_WORKSPACE_DIRECTORY']) +except KeyError: + print("this should be run with bazel run", file=sys.stderr) + sys.exit(1) + +go_extractor_dir = workspace_dir / "go" / "extractor" +go_dbscheme = workspace_dir / "go" / "ql" / "lib" / "go.dbscheme" r = runfiles.Create() go, gazelle, go_gen_dbscheme = map(r.Rlocation, sys.argv[1:]) From 5f0efc19faeb0059ed69b0e942839d782671b77c Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 26 Apr 2024 18:17:19 +0100 Subject: [PATCH 098/238] C++: Accept test changes. --- .../dataflow/dataflow-tests/test-source-sink.expected | 2 -- cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp | 4 ++-- .../syntax-zoo/dataflow-ir-consistency.expected | 6 ------ 3 files changed, 2 insertions(+), 10 deletions(-) diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected index e03ee68b8a35..e8afa785492f 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected @@ -228,7 +228,6 @@ irFlow | test.cpp:333:17:333:22 | call to source | test.cpp:337:10:337:18 | globalVar | | test.cpp:333:17:333:22 | call to source | test.cpp:339:10:339:18 | globalVar | | test.cpp:333:17:333:22 | call to source | test.cpp:343:10:343:18 | globalVar | -| test.cpp:333:17:333:22 | call to source | test.cpp:349:10:349:18 | globalVar | | test.cpp:347:17:347:22 | call to source | test.cpp:337:10:337:18 | globalVar | | test.cpp:347:17:347:22 | call to source | test.cpp:339:10:339:18 | globalVar | | test.cpp:347:17:347:22 | call to source | test.cpp:343:10:343:18 | globalVar | @@ -260,7 +259,6 @@ irFlow | test.cpp:562:17:562:31 | *call to indirect_source | test.cpp:566:10:566:19 | * ... | | test.cpp:562:17:562:31 | *call to indirect_source | test.cpp:568:10:568:19 | * ... | | test.cpp:562:17:562:31 | *call to indirect_source | test.cpp:572:10:572:19 | * ... | -| test.cpp:562:17:562:31 | *call to indirect_source | test.cpp:578:10:578:19 | * ... | | test.cpp:576:17:576:31 | *call to indirect_source | test.cpp:566:10:566:19 | * ... | | test.cpp:576:17:576:31 | *call to indirect_source | test.cpp:568:10:568:19 | * ... | | test.cpp:576:17:576:31 | *call to indirect_source | test.cpp:572:10:572:19 | * ... | diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp index af9e18034edd..c1c84c71e3bf 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp @@ -346,7 +346,7 @@ namespace FlowThroughGlobals { void taintAndCall() { globalVar = source(); calledAfterTaint(); - sink(globalVar); // $ ast ir=333:17 ir=347:17 + sink(globalVar); // $ ast ir } } @@ -575,7 +575,7 @@ namespace IndirectFlowThroughGlobals { void taintAndCall() { globalInt = indirect_source(); calledAfterTaint(); - sink(*globalInt); // $ ir=562:17 ir=576:17 MISSING: ast=562:17 ast=576:17 + sink(*globalInt); // $ ir MISSING: ast=562:17 ast=576:17 } } diff --git a/cpp/ql/test/library-tests/syntax-zoo/dataflow-ir-consistency.expected b/cpp/ql/test/library-tests/syntax-zoo/dataflow-ir-consistency.expected index 2a8d7ad25bd5..c9fd8e3dbbe8 100644 --- a/cpp/ql/test/library-tests/syntax-zoo/dataflow-ir-consistency.expected +++ b/cpp/ql/test/library-tests/syntax-zoo/dataflow-ir-consistency.expected @@ -4,12 +4,6 @@ uniqueType uniqueNodeLocation missingLocation uniqueNodeToString -| builtin.c:5:5:5:11 | (no string representation) | Node should have one toString but has 0. | -| misc.c:227:7:227:28 | (no string representation) | Node should have one toString but has 0. | -| static_init_templates.cpp:80:18:80:23 | (no string representation) | Node should have one toString but has 0. | -| static_init_templates.cpp:80:18:80:23 | (no string representation) | Node should have one toString but has 0. | -| static_init_templates.cpp:89:18:89:23 | (no string representation) | Node should have one toString but has 0. | -| static_init_templates.cpp:89:18:89:23 | (no string representation) | Node should have one toString but has 0. | parameterCallable localFlowIsLocal readStepIsLocal From ea1b8a3999b9dd27204eb17f66cb41130d3e717b Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 26 Apr 2024 17:57:47 +0100 Subject: [PATCH 099/238] C++: Implement 'getAnUltimateDefinition' on SSA definitions. --- .../cpp/ir/dataflow/internal/SsaInternals.qll | 42 ++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll index 7d2dc5d606d0..17cfe8cbb8b5 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll @@ -1036,6 +1036,16 @@ module SsaCached { ) { SsaImpl::lastRefRedefExt(def, sv, bb, i, next) } + + cached + Definition phiHasInputFromBlock(PhiNode phi, IRBlock bb) { + SsaImpl::phiHasInputFromBlock(phi, result, bb) + } + + cached + predicate ssaDefReachesRead(SourceVariable v, Definition def, IRBlock bb, int i) { + SsaImpl::ssaDefReachesRead(v, def, bb, i) + } } cached @@ -1104,6 +1114,12 @@ abstract class Def extends SsaDef, TDef { * instead of the other way around. */ abstract int getIndirection(); + + /** + * Gets a definition that ultimately defines this SSA definition and is not + * itself a phi node. + */ + Def getAnUltimateDefinition() { result.asDef() = def.getAnUltimateDefinition() } } private predicate isGlobal(DefinitionExt def, GlobalDefImpl global) { @@ -1182,6 +1198,10 @@ class Phi extends TPhi, SsaDef { override string toString() { result = "Phi" } SsaPhiNode getNode() { result.getPhiNode() = phi } + + predicate hasInputFromBlock(Definition inp, IRBlock bb) { inp = phiHasInputFromBlock(phi, bb) } + + final Definition getAnInput() { this.hasInputFromBlock(result, _) } } private module SsaImpl = SsaImplCommon::Make; @@ -1204,9 +1224,29 @@ class PhiNode extends SsaImpl::DefinitionExt { * on reads instead of writes. */ predicate isPhiRead() { this instanceof SsaImpl::PhiReadNode } + + /** Holds if `inp` is an input to this phi node along the edge originating in `bb`. */ + predicate hasInputFromBlock(Definition inp, IRBlock bb) { + inp = SsaCached::phiHasInputFromBlock(this, bb) + } + + /** Gets a definition that is an input to this phi node. */ + final Definition getAnInput() { this.hasInputFromBlock(result, _) } } -class DefinitionExt = SsaImpl::DefinitionExt; +/** An static single assignment (SSA) definition. */ +class DefinitionExt extends SsaImpl::DefinitionExt { + private Definition getAPhiInputOrPriorDefinition() { result = this.(PhiNode).getAnInput() } + + /** + * Gets a definition that ultimately defines this SSA definition and is + * not itself a phi node. + */ + final DefinitionExt getAnUltimateDefinition() { + result = this.getAPhiInputOrPriorDefinition*() and + not result instanceof PhiNode + } +} class Definition = SsaImpl::Definition; From 683fe260349ee5cf0277f47c6fac7e9109d6ad61 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 26 Apr 2024 18:09:47 +0100 Subject: [PATCH 100/238] C++: Add iterator flow based on dataflow SSA. --- .../ir/dataflow/internal/DataFlowPrivate.qll | 308 ++++++++++++++++++ .../cpp/ir/dataflow/internal/SsaInternals.qll | 4 + 2 files changed, 312 insertions(+) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll index e6ad9c86c9bd..bc6ebf2c2958 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll @@ -1665,3 +1665,311 @@ class DataFlowSecondLevelScope extends TDataFlowSecondLevelScope { /** Gets the second-level scope containing the node `n`, if any. */ DataFlowSecondLevelScope getSecondLevelScope(Node n) { result.getANode() = n } + +/** + * Module that defines flow through iterators. + * For example, + * ```cpp + * auto it = v.begin(); + * *it = source(); + * ... + * sink(v[0]); + * ``` + */ +module IteratorFlow { + private import codeql.ssa.Ssa as SsaImpl + private import semmle.code.cpp.models.interfaces.Iterator as Interface + private import semmle.code.cpp.models.implementations.Iterator as Impl + + /** + * A variable of some type that can produce an iterator. + */ + class SourceVariable extends Ssa::SourceVariable { + SourceVariable() { + exists(Interface::GetIteratorFunction gets, Cpp::FunctionInput input, int i | + input.isParameterDerefOrQualifierObject(i) and + gets.getsIterator(input, _) + | + this.getType().stripType() = gets.getParameter(i).getType().stripType() + or + i = -1 and + this.getType().stripType() = gets.getDeclaringType() + ) + } + } + + private module SsaInput implements SsaImpl::InputSig { + import Ssa::InputSigCommon + + class SourceVariable = IteratorFlow::SourceVariable; + + /** A call to function that dereferences an iterator. */ + private class IteratorPointerDereferenceCall extends CallInstruction { + IteratorPointerDereferenceCall() { + this.getStaticCallTarget() instanceof Impl::IteratorPointerDereferenceOperator + } + } + + /** A call to a function that obtains an iterator. */ + private class GetsIteratorCall extends CallInstruction { + GetsIteratorCall() { this.getStaticCallTarget() instanceof Impl::GetIteratorFunction } + } + + /** A call to `operator++` or `operator--` on an iterator. */ + private class IteratorCrementCall extends CallInstruction { + IteratorCrementCall() { this.getStaticCallTarget() instanceof Impl::IteratorCrementOperator } + } + + /** + * Gets an ultimate definition of `def`. + * + * Note: Unlike `def.getAnUltimateDefinition()` this predicate also + * traverses back through iterator increment and decrement operations. + */ + private Ssa::Def getAnUltimateDefinition(Ssa::Def def) { + result = def.getAnUltimateDefinition() + or + exists(IRBlock bb, int i, IteratorCrementCall crementCall, Ssa::SourceVariable sv | + crementCall = def.getValue().asInstruction().(StoreInstruction).getSourceValue() and + sv = def.getSourceVariable() and + bb.getInstruction(i) = crementCall and + Ssa::ssaDefReachesRead(sv, result.asDef(), bb, i) + ) + } + + /** + * Holds if `write` is an instruction that writes to address `address` + */ + private predicate isIteratorWrite(Instruction write, Operand address) { + exists(Ssa::DefImpl writeDef, IRBlock bb, int i | + writeDef.hasIndexInBlock(bb, i, _) and + bb.getInstruction(i) = write and + address = writeDef.getAddressOperand() + ) + } + + /** + * Holds if `writeToDeref` is a write to an iterator that was obtained + * by `beginCall`. That is, the following instruction sequence holds: + * ```cpp + * it = container.begin(); // or a similar iterator-obtaining function call + * ... + * *it = value; + * ``` + */ + private predicate isIteratorStoreInstruction( + GetsIteratorCall beginCall, Instruction writeToDeref + ) { + exists( + StoreInstruction beginStore, IRBlock bbStar, int iStar, Ssa::Def def, + IteratorPointerDereferenceCall starCall, Ssa::Def ultimate, Operand address + | + isIteratorWrite(writeToDeref, address) and + operandForFullyConvertedCall(address, starCall) and + bbStar.getInstruction(iStar) = starCall and + Ssa::ssaDefReachesRead(_, def.asDef(), bbStar, iStar) and + ultimate = getAnUltimateDefinition*(def) and + beginStore = ultimate.getValue().asInstruction() and + operandForFullyConvertedCall(beginStore.getSourceValueOperand(), beginCall) + ) + } + + /** + * Holds if `(bb, i)` contains a write to an iterator that may have been obtained + * by calling `begin` (or related functions) on the variable `v`. + */ + predicate variableWrite(IRBlock bb, int i, SourceVariable v, boolean certain) { + certain = false and + exists(GetsIteratorCall beginCall, Instruction writeToDeref, IRBlock bbQual, int iQual | + isIteratorStoreInstruction(beginCall, writeToDeref) and + bb.getInstruction(i) = writeToDeref and + bbQual.getInstruction(iQual) = beginCall and + Ssa::variableRead(bbQual, iQual, v, _) + ) + } + + /** Holds if `(bb, i)` reads the container variable `v`. */ + predicate variableRead(IRBlock bb, int i, SourceVariable v, boolean certain) { + Ssa::variableRead(bb, i, v, certain) + } + } + + private module IteratorSsa = SsaImpl::Make; + + cached + private newtype TSsaDef = + TDef(IteratorSsa::DefinitionExt def) or + TPhi(PhiNode phi) + + abstract private class SsaDef extends TSsaDef { + /** Gets a textual representation of this element. */ + string toString() { none() } + + /** Gets the underlying non-phi definition or use. */ + IteratorSsa::DefinitionExt asDef() { none() } + + /** Gets the underlying phi node. */ + PhiNode asPhi() { none() } + + /** Gets the location of this element. */ + abstract Location getLocation(); + } + + private class Def extends TDef, SsaDef { + IteratorSsa::DefinitionExt def; + + Def() { this = TDef(def) } + + final override IteratorSsa::DefinitionExt asDef() { result = def } + + final override Location getLocation() { result = this.getImpl().getLocation() } + + /** Gets the variable written to by this definition. */ + final SourceVariable getSourceVariable() { result = def.getSourceVariable() } + + override string toString() { result = def.toString() } + + /** + * Holds if this definition (or use) has index `index` in block `block`, + * and is a definition (or use) of the variable `sv`. + */ + predicate hasIndexInBlock(IRBlock block, int index, SourceVariable sv) { + def.definesAt(sv, block, index, _) + } + + private Ssa::DefImpl getImpl() { + exists(IRBlock bb, int i | + this.hasIndexInBlock(bb, i, _) and + result.hasIndexInBlock(bb, i) + ) + } + + /** Gets the value written by this definition (i.e., the "right-hand side"). */ + Node0Impl getValue() { result = this.getImpl().getValue() } + + /** Gets the indirection index of this definition. */ + int getIndirectionIndex() { result = this.getImpl().getIndirectionIndex() } + } + + private class Phi extends TPhi, SsaDef { + PhiNode phi; + + Phi() { this = TPhi(phi) } + + final override PhiNode asPhi() { result = phi } + + final override Location getLocation() { result = phi.getBasicBlock().getLocation() } + + override string toString() { result = phi.toString() } + + SsaIteratorNode getNode() { result.getIteratorFlowNode() = phi } + } + + private class PhiNode extends IteratorSsa::DefinitionExt { + PhiNode() { + this instanceof IteratorSsa::PhiNode or + this instanceof IteratorSsa::PhiReadNode + } + + SsaIteratorNode getNode() { result.getIteratorFlowNode() = this } + } + + cached + private module IteratorSsaCached { + cached + predicate adjacentDefRead(IRBlock bb1, int i1, SourceVariable sv, IRBlock bb2, int i2) { + IteratorSsa::adjacentDefReadExt(_, sv, bb1, i1, bb2, i2) + or + exists(PhiNode phi | + IteratorSsa::lastRefRedefExt(_, sv, bb1, i1, phi) and + phi.definesAt(sv, bb2, i2, _) + ) + } + + cached + Node getAPriorDefinition(IteratorSsa::DefinitionExt next) { + exists(IRBlock bb, int i, SourceVariable sv, IteratorSsa::DefinitionExt def | + IteratorSsa::lastRefRedefExt(pragma[only_bind_into](def), pragma[only_bind_into](sv), + pragma[only_bind_into](bb), pragma[only_bind_into](i), next) and + nodeToDefOrUse(result, sv, bb, i, _) + ) + } + } + + /** The set of nodes necessary for iterator flow. */ + class IteratorFlowNode instanceof PhiNode { + /** Gets a textual representation of this node. */ + string toString() { result = super.toString() } + + /** Gets the type of this node. */ + DataFlowType getType() { + exists(Ssa::SourceVariable sv | + super.definesAt(sv, _, _, _) and + result = sv.getType() + ) + } + + /** Gets the `Declaration` that contains this block. */ + Declaration getFunction() { result = super.getBasicBlock().getEnclosingFunction() } + + /** Gets the locatino of this node. */ + Location getLocation() { result = super.getBasicBlock().getLocation() } + } + + private import IteratorSsaCached + + private predicate defToNode(Node node, Def def, boolean uncertain) { + ( + nodeHasOperand(node, def.getValue().asOperand(), def.getIndirectionIndex()) + or + nodeHasInstruction(node, def.getValue().asInstruction(), def.getIndirectionIndex()) + ) and + uncertain = false + } + + private predicate nodeToDefOrUse( + Node node, SourceVariable sv, IRBlock bb, int i, boolean uncertain + ) { + exists(Def def | + def.hasIndexInBlock(bb, i, sv) and + defToNode(node, def, uncertain) + ) + or + useToNode(bb, i, sv, node) and + uncertain = false + } + + private predicate useToNode(IRBlock bb, int i, SourceVariable sv, Node nodeTo) { + exists(PhiNode phi | + phi.definesAt(sv, bb, i, _) and + nodeTo = phi.getNode() + ) + or + exists(Ssa::UseImpl use | + use.hasIndexInBlock(bb, i, sv) and + nodeTo = use.getNode() + ) + } + + /** + * Holds if `nodeFrom` flows to `nodeTo` in a single step. + */ + predicate localFlowStep(Node nodeFrom, Node nodeTo) { + exists( + Node nFrom, SourceVariable sv, IRBlock bb1, int i1, IRBlock bb2, int i2, boolean uncertain + | + adjacentDefRead(bb1, i1, sv, bb2, i2) and + nodeToDefOrUse(nFrom, sv, bb1, i1, uncertain) and + useToNode(bb2, i2, sv, nodeTo) + | + if uncertain = true + then + nodeFrom = + [ + nFrom, + getAPriorDefinition(any(IteratorSsa::DefinitionExt next | next.definesAt(sv, bb1, i1, _))) + ] + else nFrom = nodeFrom + ) + } +} diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll index 17cfe8cbb8b5..bedaaee487d3 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll @@ -1046,6 +1046,10 @@ module SsaCached { predicate ssaDefReachesRead(SourceVariable v, Definition def, IRBlock bb, int i) { SsaImpl::ssaDefReachesRead(v, def, bb, i) } + + predicate variableRead = SsaInput::variableRead/4; + + predicate variableWrite = SsaInput::variableWrite/4; } cached From 6e3dddede0dd153ca9dee27d7eb127c79d0c4793 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 26 Apr 2024 18:10:17 +0100 Subject: [PATCH 101/238] C++: Use iterator flow in dataflow. --- .../cpp/ir/dataflow/internal/DataFlowUtil.qll | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) 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 88a984e5dab1..dc591dccbb98 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 @@ -46,6 +46,7 @@ private newtype TIRDataFlowNode = Ssa::isModifiableByCall(operand, indirectionIndex) } or TSsaPhiNode(Ssa::PhiNode phi) or + TSsaIteratorNode(IteratorFlow::IteratorFlowNode n) or TRawIndirectOperand0(Node0Impl node, int indirectionIndex) { Ssa::hasRawIndirectOperand(node.asOperand(), indirectionIndex) } or @@ -653,6 +654,30 @@ class SsaPhiNode extends Node, TSsaPhiNode { predicate isPhiRead() { phi.isPhiRead() } } +/** + * INTERNAL: do not use. + * + * Dataflow nodes necessary for iterator flow + */ +class SsaIteratorNode extends Node, TSsaIteratorNode { + IteratorFlow::IteratorFlowNode node; + + SsaIteratorNode() { this = TSsaIteratorNode(node) } + + /** Gets the phi node associated with this node. */ + IteratorFlow::IteratorFlowNode getIteratorFlowNode() { result = node } + + override Declaration getEnclosingCallable() { result = this.getFunction() } + + override Declaration getFunction() { result = node.getFunction() } + + override DataFlowType getType() { result = node.getType() } + + final override Location getLocationImpl() { result = node.getLocation() } + + override string toStringImpl() { result = node.toString() } +} + /** * INTERNAL: do not use. * @@ -2151,6 +2176,8 @@ private module Cached { // Def-use/Use-use flow Ssa::ssaFlow(nodeFrom, nodeTo) or + IteratorFlow::localFlowStep(nodeFrom, nodeTo) + or // Operand -> Instruction flow simpleInstructionLocalFlowStep(nodeFrom.asOperand(), nodeTo.asInstruction()) or From 141af7cc87352d14aa921f5c05ddacf94c3636d4 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 26 Apr 2024 18:11:44 +0100 Subject: [PATCH 102/238] C++: Subclasses for both 'begin' and 'end'. --- .../cpp/models/implementations/Iterator.qll | 27 +++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Iterator.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Iterator.qll index 8e527c7e6947..89658000c8ac 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Iterator.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Iterator.qll @@ -579,17 +579,34 @@ private class IteratorAssignmentMemberOperatorModel extends IteratorAssignmentMe override predicate parameterEscapesOnlyViaReturn(int index) { index = -1 } } +/** + * A `begin` member function, or a related function, that returns an iterator. + */ +class BeginFunction extends MemberFunction { + BeginFunction() { + this.hasName(["begin", "cbegin", "rbegin", "crbegin", "before_begin", "cbefore_begin"]) and + this.getType().getUnspecifiedType() instanceof Iterator + } +} + +/** + * An `end` member function, or a related function, that returns an iterator. + */ +class EndFunction extends MemberFunction { + EndFunction() { + this.hasName(["end", "cend", "rend", "crend"]) and + this.getType().getUnspecifiedType() instanceof Iterator + } +} + /** * A `begin` or `end` member function, or a related member function, that * returns an iterator. */ class BeginOrEndFunction extends MemberFunction { BeginOrEndFunction() { - this.hasName([ - "begin", "cbegin", "rbegin", "crbegin", "end", "cend", "rend", "crend", "before_begin", - "cbefore_begin" - ]) and - this.getType().getUnspecifiedType() instanceof Iterator + this instanceof BeginFunction or + this instanceof EndFunction } } From d3d2e2188d1090876d617bdd5009926bb537b01a Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 26 Apr 2024 18:15:59 +0100 Subject: [PATCH 103/238] C++: Accept test changes. --- .../test/library-tests/dataflow/taint-tests/taint.expected | 4 ++++ cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected index 0065ae75d21b..76cbdd4bacd8 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected @@ -4,4 +4,8 @@ WARNING: Module DataFlow has been deprecated and may be removed in future (taint WARNING: Module DataFlow has been deprecated and may be removed in future (taint.ql:68,25-33) WARNING: Module TaintTracking has been deprecated and may be removed in future (taint.ql:73,20-33) testFailures +| standalone_iterators.cpp:95:15:95:25 | // $ ast,ir | Missing result:ir= | +| standalone_iterators.cpp:112:11:112:21 | // $ ast,ir | Missing result:ir= | +| standalone_iterators.cpp:116:11:116:21 | // $ ast,ir | Missing result:ir= | +| standalone_iterators.cpp:117:12:117:22 | // $ ast,ir | Missing result:ir= | failures diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp index 179c5eb6b199..c26eef5176ce 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp @@ -389,7 +389,7 @@ void test_vector_output_iterator(int b) { *i9 = source(); taint_vector_output_iterator(i9); - sink(v9); // $ ast=330:10 MISSING: ir SPURIOUS: ast=389:8 + sink(v9); // $ ast=330:10 ir SPURIOUS: ast=389:8 std::vector::iterator i10 = v10.begin(); vector_iterator_assign_wrapper(i10, 10); @@ -440,14 +440,14 @@ void test_vector_inserter(char *source_string) { std::vector out; auto it = std::back_inserter(out); *++it = std::string(source_string); - sink(out); // $ ast MISSING: ir + sink(out); // $ ast,ir } { std::vector out; auto it = std::back_inserter(out); *++it = source(); - sink(out); // $ ast MISSING: ir + sink(out); // $ ast,ir } } From 527409d05fd07ec4aae41afe940f7684a00b972a Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 26 Apr 2024 18:16:49 +0100 Subject: [PATCH 104/238] C++: Fix iterator return types and accept test changes. --- .../dataflow/taint-tests/standalone_iterators.cpp | 4 ++-- cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected | 3 --- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/standalone_iterators.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/standalone_iterators.cpp index 7265cb175426..a39e06988065 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/standalone_iterators.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/standalone_iterators.cpp @@ -66,8 +66,8 @@ class insert_iterator_by_trait { insert_iterator_by_trait operator++(int); insert_iterator_by_trait &operator--(); insert_iterator_by_trait operator--(int); - insert_iterator_by_trait operator*(); - insert_iterator_by_trait operator=(int x); + insert_iterator_by_trait& operator*(); + insert_iterator_by_trait& operator=(int x); }; template<> diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected index 76cbdd4bacd8..2b6ae9bf70e3 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected @@ -4,8 +4,5 @@ WARNING: Module DataFlow has been deprecated and may be removed in future (taint WARNING: Module DataFlow has been deprecated and may be removed in future (taint.ql:68,25-33) WARNING: Module TaintTracking has been deprecated and may be removed in future (taint.ql:73,20-33) testFailures -| standalone_iterators.cpp:95:15:95:25 | // $ ast,ir | Missing result:ir= | | standalone_iterators.cpp:112:11:112:21 | // $ ast,ir | Missing result:ir= | -| standalone_iterators.cpp:116:11:116:21 | // $ ast,ir | Missing result:ir= | -| standalone_iterators.cpp:117:12:117:22 | // $ ast,ir | Missing result:ir= | failures From 401717d739c34d0d9c57b58e81b05da8f68ee3f4 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 26 Apr 2024 18:33:39 +0100 Subject: [PATCH 105/238] C++: Add a missing taint step and accept test changes. --- cpp/ql/lib/semmle/code/cpp/models/implementations/Iterator.qll | 2 +- cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Iterator.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Iterator.qll index 89658000c8ac..a016210de5a0 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Iterator.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Iterator.qll @@ -560,7 +560,7 @@ private class IteratorAssignmentMemberOperatorModel extends IteratorAssignmentMe TaintFunction, SideEffectFunction, AliasFunction { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input.isParameterDeref(0) and + (input.isParameterDeref(0) or input.isParameter(0)) and output.isQualifierObject() } diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected index 2b6ae9bf70e3..0065ae75d21b 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected @@ -4,5 +4,4 @@ WARNING: Module DataFlow has been deprecated and may be removed in future (taint WARNING: Module DataFlow has been deprecated and may be removed in future (taint.ql:68,25-33) WARNING: Module TaintTracking has been deprecated and may be removed in future (taint.ql:73,20-33) testFailures -| standalone_iterators.cpp:112:11:112:21 | // $ ast,ir | Missing result:ir= | failures From 6ec223c5150efbacdb14157f7e5f0815bac7d62a Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Mon, 29 Apr 2024 11:00:21 +0200 Subject: [PATCH 106/238] Go: small cleanup in `Makefile` --- go/Makefile | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/go/Makefile b/go/Makefile index d9ba2c7e2d48..3ebeb69fcaf1 100644 --- a/go/Makefile +++ b/go/Makefile @@ -1,19 +1,5 @@ all: gen extractor -ifeq ($(OS),Windows_NT) -EXE = .exe -CODEQL_PLATFORM = win64 -else -EXE = -UNAME_S := $(shell uname -s) -ifeq ($(UNAME_S),Linux) -CODEQL_PLATFORM = linux64 -endif -ifeq ($(UNAME_S),Darwin) -CODEQL_PLATFORM = osx64 -endif -endif - EXTRACTOR_PACK_OUT = build/codeql-extractor-go .PHONY: extractor gen clean autoformat check-formatting From 2f6dd2ab819c59425a4c636cdb65930d6c6405fb Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Mon, 29 Apr 2024 11:11:23 +0200 Subject: [PATCH 107/238] Go: refactor workflows with shared action --- .github/workflows/go-tests-other-os.yml | 57 +++++------------- .github/workflows/go-tests.yml | 64 +------------------- go/actions/test/action.yml | 80 +++++++++++++++++++++++++ 3 files changed, 97 insertions(+), 104 deletions(-) create mode 100644 go/actions/test/action.yml diff --git a/.github/workflows/go-tests-other-os.yml b/.github/workflows/go-tests-other-os.yml index ba3dd0335ad4..9915b0869db7 100644 --- a/.github/workflows/go-tests-other-os.yml +++ b/.github/workflows/go-tests-other-os.yml @@ -12,50 +12,21 @@ permissions: contents: read jobs: - test: - name: Test - strategy: - fail-fast: false - matrix: - os: [macos-latest, windows-latest-xl] - if: matrix.os == 'macos-latest' || github.repository_owner == 'github' - runs-on: ${{ matrix.os }} + test-mac: + name: Test MacOS + runs-on: macos-latest steps: - name: Check out code uses: actions/checkout@v4 + - name: Run tests + uses: ./go/actions/test - - name: Get go version - shell: bash - run: | - ( - echo -n "GO_VERSION=" - bazel run @rules_go//go -- version | sed 's/go version go\(\S*\) .*/\1/' - ) | tee -a "$GITHUB_ENV" - - - name: Set up Go - uses: actions/setup-go@v5 - with: - go-version: ${{ env.GO_VERSION }} - cache: false - id: go - - - name: Set up CodeQL CLI - uses: ./.github/actions/fetch-codeql - - - name: Enable problem matchers in repository - shell: bash - run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;' - - - name: Build - run: | - bazel run //go:create-extractor-pack - - - name: Cache compilation cache - id: query-cache - uses: ./.github/actions/cache-query-compilation - with: - key: go-qltest - - name: Test - run: | - cd go - make test cache="${{ steps.query-cache.outputs.cache-dir }}" + test-win: + if: github.repository_owner == 'github' + name: Test Windows + runs-on: windows-latest-xl + steps: + - name: Check out code + uses: actions/checkout@v4 + - name: Run tests + uses: ./go/actions/test diff --git a/.github/workflows/go-tests.yml b/.github/workflows/go-tests.yml index 5c9204f8405f..63e2b7c49740 100644 --- a/.github/workflows/go-tests.yml +++ b/.github/workflows/go-tests.yml @@ -27,65 +27,7 @@ jobs: steps: - name: Check out code uses: actions/checkout@v4 - - - name: Get go version - shell: bash - run: | - ( - echo -n "GO_VERSION=" - bazel run @rules_go//go -- version | sed 's/go version go\(\S*\) .*/\1/' - ) | tee -a "$GITHUB_ENV" - - - name: Set up Go - uses: actions/setup-go@v5 + - name: Run tests + uses: ./go/actions/test with: - go-version: ${{ env.GO_VERSION }} - cache: false - id: go - - - name: Set up CodeQL CLI - uses: ./.github/actions/fetch-codeql - - - name: Enable problem matchers in repository - shell: bash - run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;' - - - name: Build - run: | - bazel run //go:create-extractor-pack - - - name: Check that all Go code is autoformatted - run: | - cd go - make check-formatting - - - name: Check checked-in generated code - run: | - bazel run //go:gen - git add . - git diff --exit-code HEAD || ( - echo "please run bazel run //go:gen" - exit 1 - ) - - - name: Compile qhelp files to markdown - run: | - cd go - env QHELP_OUT_DIR=qhelp-out make qhelp-to-markdown - - - name: Upload qhelp markdown - uses: actions/upload-artifact@v3 - with: - name: qhelp-markdown - path: go/qhelp-out/**/*.md - - - name: Cache compilation cache - id: query-cache - uses: ./.github/actions/cache-query-compilation - with: - key: go-qltest - - - name: Test - run: | - cd go - make test cache="${{ steps.query-cache.outputs.cache-dir }}" + run-code-checks: true diff --git a/go/actions/test/action.yml b/go/actions/test/action.yml new file mode 100644 index 000000000000..f9bdee5fe0c0 --- /dev/null +++ b/go/actions/test/action.yml @@ -0,0 +1,80 @@ +name: Test go extractor +description: Run build, QL tests and optionally basic code sanity checks (formatting and generation) +inputs: + run-code-checks: + description: Whether to run formatting, code and qhelp generation checks + required: false + default: false +runs: + using: composite + steps: + - name: Get go version + shell: bash + run: | + ( + echo -n "GO_VERSION=" + bazel run @rules_go//go -- version | sed 's/go version go\(\S*\) .*/\1/' + ) | tee -a "$GITHUB_ENV" + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: ${{ env.GO_VERSION }} + cache: false + id: go + + - name: Set up CodeQL CLI + uses: ./.github/actions/fetch-codeql + + - name: Enable problem matchers in repository + shell: bash + run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;' + + - name: Build + shell: bash + run: | + bazel run //go:create-extractor-pack + + - name: Check that all Go code is autoformatted + if: inputs.run-code-checks == 'true' + shell: bash + run: | + cd go + make check-formatting + + - name: Check checked-in generated code + if: inputs.run-code-checks == 'true' + shell: bash + run: | + bazel run //go:gen + git add . + git diff --exit-code HEAD || ( + echo "please run bazel run //go:gen" + exit 1 + ) + + - name: Compile qhelp files to markdown + if: inputs.run-code-checks == 'true' + shell: bash + run: | + cd go + env QHELP_OUT_DIR=qhelp-out make qhelp-to-markdown + + - name: Upload qhelp markdown + if: inputs.run-code-checks == 'true' + uses: actions/upload-artifact@v3 + with: + name: qhelp-markdown + path: go/qhelp-out/**/*.md + + - name: Cache compilation cache + id: query-cache + uses: ./.github/actions/cache-query-compilation + with: + key: go-qltest + + - name: Test + shell: bash + run: | + cd go + make test cache="${{ steps.query-cache.outputs.cache-dir }}" From f0f6c229f6d10c6f3f770777a5bc23b1bd808439 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Mon, 29 Apr 2024 11:16:30 +0200 Subject: [PATCH 108/238] Go: fix regex in action for macOS --- go/actions/test/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/actions/test/action.yml b/go/actions/test/action.yml index f9bdee5fe0c0..ade22410d957 100644 --- a/go/actions/test/action.yml +++ b/go/actions/test/action.yml @@ -13,7 +13,7 @@ runs: run: | ( echo -n "GO_VERSION=" - bazel run @rules_go//go -- version | sed 's/go version go\(\S*\) .*/\1/' + bazel run @rules_go//go -- version | sed 's/go version go\(.*\) .*/\1/' ) | tee -a "$GITHUB_ENV" - name: Set up Go From 1f78882cdc80011a86dfeb866b08dd46f3004121 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Mon, 29 Apr 2024 11:27:16 +0200 Subject: [PATCH 109/238] Go: make windows checks happy --- go/actions/test/action.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go/actions/test/action.yml b/go/actions/test/action.yml index ade22410d957..a351c4382ac9 100644 --- a/go/actions/test/action.yml +++ b/go/actions/test/action.yml @@ -33,7 +33,7 @@ runs: - name: Build shell: bash run: | - bazel run //go:create-extractor-pack + bazel run go:create-extractor-pack - name: Check that all Go code is autoformatted if: inputs.run-code-checks == 'true' @@ -46,7 +46,7 @@ runs: if: inputs.run-code-checks == 'true' shell: bash run: | - bazel run //go:gen + bazel run go:gen git add . git diff --exit-code HEAD || ( echo "please run bazel run //go:gen" From 179270ffc1203a00e7006c8cebbdd09cdcd8a306 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Mon, 29 Apr 2024 11:07:55 +0100 Subject: [PATCH 110/238] C++: Move 'cpp/iterator-to-expired-container' out of experimental. --- .../Security/CWE/CWE-416/IteratorToExpiredContainer.qhelp | 0 .../Security/CWE/CWE-416/IteratorToExpiredContainer.ql | 0 .../CWE/CWE-416/IteratorToExpiredContainerExtendedLifetime.cpp | 0 .../Security/CWE/CWE-416/IteratorToExpiredContainer.qlref | 1 - .../IteratorToExpiredContainer.expected | 0 .../IteratorToExpiredContainer/IteratorToExpiredContainer.qlref | 1 + .../CWE-416/semmle/tests/IteratorToExpiredContainer}/test.cpp | 0 7 files changed, 1 insertion(+), 1 deletion(-) rename cpp/ql/src/{experimental => }/Security/CWE/CWE-416/IteratorToExpiredContainer.qhelp (100%) rename cpp/ql/src/{experimental => }/Security/CWE/CWE-416/IteratorToExpiredContainer.ql (100%) rename cpp/ql/src/{experimental => }/Security/CWE/CWE-416/IteratorToExpiredContainerExtendedLifetime.cpp (100%) delete mode 100644 cpp/ql/test/experimental/query-tests/Security/CWE/CWE-416/IteratorToExpiredContainer.qlref rename cpp/ql/test/{experimental/query-tests/Security/CWE/CWE-416 => query-tests/Security/CWE/CWE-416/semmle/tests/IteratorToExpiredContainer}/IteratorToExpiredContainer.expected (100%) create mode 100644 cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/IteratorToExpiredContainer/IteratorToExpiredContainer.qlref rename cpp/ql/test/{experimental/query-tests/Security/CWE/CWE-416 => query-tests/Security/CWE/CWE-416/semmle/tests/IteratorToExpiredContainer}/test.cpp (100%) diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-416/IteratorToExpiredContainer.qhelp b/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.qhelp similarity index 100% rename from cpp/ql/src/experimental/Security/CWE/CWE-416/IteratorToExpiredContainer.qhelp rename to cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.qhelp diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-416/IteratorToExpiredContainer.ql b/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.ql similarity index 100% rename from cpp/ql/src/experimental/Security/CWE/CWE-416/IteratorToExpiredContainer.ql rename to cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.ql diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-416/IteratorToExpiredContainerExtendedLifetime.cpp b/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainerExtendedLifetime.cpp similarity index 100% rename from cpp/ql/src/experimental/Security/CWE/CWE-416/IteratorToExpiredContainerExtendedLifetime.cpp rename to cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainerExtendedLifetime.cpp diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-416/IteratorToExpiredContainer.qlref b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-416/IteratorToExpiredContainer.qlref deleted file mode 100644 index 5f86bb26ff09..000000000000 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-416/IteratorToExpiredContainer.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security/CWE/CWE-416/IteratorToExpiredContainer.ql diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-416/IteratorToExpiredContainer.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/IteratorToExpiredContainer/IteratorToExpiredContainer.expected similarity index 100% rename from cpp/ql/test/experimental/query-tests/Security/CWE/CWE-416/IteratorToExpiredContainer.expected rename to cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/IteratorToExpiredContainer/IteratorToExpiredContainer.expected diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/IteratorToExpiredContainer/IteratorToExpiredContainer.qlref b/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/IteratorToExpiredContainer/IteratorToExpiredContainer.qlref new file mode 100644 index 000000000000..fb2d78f87dfe --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/IteratorToExpiredContainer/IteratorToExpiredContainer.qlref @@ -0,0 +1 @@ +Security/CWE/CWE-416/IteratorToExpiredContainer.ql diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-416/test.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/IteratorToExpiredContainer/test.cpp similarity index 100% rename from cpp/ql/test/experimental/query-tests/Security/CWE/CWE-416/test.cpp rename to cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/IteratorToExpiredContainer/test.cpp From f194c70e8aee75f37f99a2ad9fe002c961606728 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Mon, 29 Apr 2024 11:08:08 +0100 Subject: [PATCH 111/238] C++: Set precision to medium. --- cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.ql b/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.ql index a36e54070bbe..5ec585780c12 100644 --- a/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.ql +++ b/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.ql @@ -2,7 +2,7 @@ * @name Iterator to expired container * @description Using an iterator owned by a container whose lifetime has expired may lead to unexpected behavior. * @kind problem - * @precision high + * @precision medium * @id cpp/iterator-to-expired-container * @problem.severity warning * @tags reliability From 5c454bdd8c1d0224771acce38997922d194d6e8f Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Mon, 29 Apr 2024 11:09:42 +0100 Subject: [PATCH 112/238] C++: Compute and add severity. --- cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.ql | 1 + 1 file changed, 1 insertion(+) diff --git a/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.ql b/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.ql index 5ec585780c12..ec8f7cbef91a 100644 --- a/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.ql +++ b/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.ql @@ -5,6 +5,7 @@ * @precision medium * @id cpp/iterator-to-expired-container * @problem.severity warning + * @security-severity 8.8 * @tags reliability * security * external/cwe/cwe-416 From 15bb846a5fb9a00748219475e4a2d436181e5e1a Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Mon, 29 Apr 2024 12:17:47 +0200 Subject: [PATCH 113/238] Go: add workaround for extractor pack windows installer --- go/BUILD.bazel | 23 +++++++++++++++++++++-- go/create_extractor_pack.py | 16 +++++++++++++--- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/go/BUILD.bazel b/go/BUILD.bazel index 41113d45f518..4251ebd228f2 100644 --- a/go/BUILD.bazel +++ b/go/BUILD.bazel @@ -3,6 +3,7 @@ load("@gazelle//:def.bzl", "gazelle") load("@rules_go//go:def.bzl", "go_cross_binary") load("@rules_pkg//pkg:install.bzl", "pkg_install") load("@rules_pkg//pkg:mappings.bzl", "pkg_attributes", "pkg_filegroup", "pkg_files") +load("@rules_pkg//pkg:zip.bzl", "pkg_zip") load("//:defs.bzl", "codeql_platform") # following is needed for running gazelle on macOS @@ -92,15 +93,33 @@ pkg_filegroup( ) pkg_install( - name = "_create_extractor_pack", + name = "_extractor-pack-installer", srcs = [":extractor-pack"], ) +# rules_pkg installer is currently broken on Windows +# see https://github.com/bazelbuild/rules_pkg/issues/387 +# for now, work around it using an archive +pkg_zip( + name = "_extractor-pack-zip", + srcs = [":extractor-pack"], +) + +alias( + name = "_create-extractor-pack-arg", + actual = select({ + "@platforms//os:windows": ":_extractor-pack-zip", + "//conditions:default": ":_extractor-pack-installer", + }), +) + py_binary( name = "create-extractor-pack", srcs = ["create_extractor_pack.py"], + args = ["$(rlocationpath :_create-extractor-pack-arg)"], + data = [":_create-extractor-pack-arg"], main = "create_extractor_pack.py", - deps = [":_create_extractor_pack"], + deps = ["@rules_python//python/runfiles"], ) native_binary( diff --git a/go/create_extractor_pack.py b/go/create_extractor_pack.py index 08665a2d8dc9..a1154a777d85 100644 --- a/go/create_extractor_pack.py +++ b/go/create_extractor_pack.py @@ -2,7 +2,9 @@ import pathlib import shutil import sys -from go._create_extractor_pack_install_script import main +import subprocess +import zipfile +from python.runfiles import runfiles try: workspace_dir = pathlib.Path(os.environ['BUILD_WORKSPACE_DIRECTORY']) @@ -11,6 +13,14 @@ sys.exit(1) dest_dir = workspace_dir / 'go' / 'build' / 'codeql-extractor-go' +installer_or_zip = pathlib.Path(runfiles.Create().Rlocation(sys.argv[1])) + shutil.rmtree(dest_dir, ignore_errors=True) -os.environ['DESTDIR'] = str(dest_dir) -main(sys.argv) + +if installer_or_zip.suffix == '.zip': + dest_dir.mkdir() + with zipfile.ZipFile(installer_or_zip) as pack: + pack.extractall(dest_dir) +else: + os.environ['DESTDIR'] = str(dest_dir) + subprocess.check_call([installer_or_zip]) From 0fa5a1f2748dc81239ce454ead6ba7ed239ad9f9 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Mon, 29 Apr 2024 11:17:53 +0100 Subject: [PATCH 114/238] C++: Add change note. --- .../change-notes/2024-04-29-iterator-to-expired-container.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 cpp/ql/src/change-notes/2024-04-29-iterator-to-expired-container.md diff --git a/cpp/ql/src/change-notes/2024-04-29-iterator-to-expired-container.md b/cpp/ql/src/change-notes/2024-04-29-iterator-to-expired-container.md new file mode 100644 index 000000000000..ce06805a8f37 --- /dev/null +++ b/cpp/ql/src/change-notes/2024-04-29-iterator-to-expired-container.md @@ -0,0 +1,4 @@ +--- +category: newQuery +--- +* Added a new query, `cpp/iterator-to-expired-container`, to detect the creation of iterators owned by a temporary objects that are about to be destroyed. From 51bc8e917e57d1a90e702d95058a455d9b7bf107 Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Mon, 29 Apr 2024 11:17:24 +0100 Subject: [PATCH 115/238] Ruby: Reduce FPs for rb/incomplete-hostname-regexp Arguments in calls to `match[?]` should only be considered regular expression interpretations if the `match` refers to the standard library method, not a method in source code. --- ruby/ql/lib/codeql/ruby/Regexp.qll | 4 +++- .../IncompleteHostnameRegExp.expected | 1 + .../tst-IncompleteHostnameRegExp.rb | 14 ++++++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/ruby/ql/lib/codeql/ruby/Regexp.qll b/ruby/ql/lib/codeql/ruby/Regexp.qll index 1abcee8d2d16..6ca1d40dc632 100644 --- a/ruby/ql/lib/codeql/ruby/Regexp.qll +++ b/ruby/ql/lib/codeql/ruby/Regexp.qll @@ -122,7 +122,9 @@ class StdLibRegExpInterpretation extends RegExpInterpretation::Range { mce.getMethodName() = ["match", "match?"] and this = mce.getArgument(0) and // exclude https://ruby-doc.org/core-2.4.0/Regexp.html#method-i-match - not mce.getReceiver() = RegExpTracking::trackRegexpType() + not mce.getReceiver() = RegExpTracking::trackRegexpType() and + // exclude non-stdlib methods + not exists(mce.getATarget()) ) } } diff --git a/ruby/ql/test/query-tests/security/cwe-020/IncompleteHostnameRegExp/IncompleteHostnameRegExp.expected b/ruby/ql/test/query-tests/security/cwe-020/IncompleteHostnameRegExp/IncompleteHostnameRegExp.expected index 9110e245cd63..097f43c33e70 100644 --- a/ruby/ql/test/query-tests/security/cwe-020/IncompleteHostnameRegExp/IncompleteHostnameRegExp.expected +++ b/ruby/ql/test/query-tests/security/cwe-020/IncompleteHostnameRegExp/IncompleteHostnameRegExp.expected @@ -28,3 +28,4 @@ | tst-IncompleteHostnameRegExp.rb:48:42:48:67 | ^https?://.+.example\\.com/ | This string, which is used as a regular expression $@, has an unescaped '.' before 'example\\.com/', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.rb:48:13:48:69 | ... + ... | here | | tst-IncompleteHostnameRegExp.rb:48:42:48:67 | ^https?://.+.example\\.com/ | This string, which is used as a regular expression $@, has an unrestricted wildcard '.+' which may cause 'example\\.com/' to be matched anywhere in the URL, outside the hostname. | tst-IncompleteHostnameRegExp.rb:48:13:48:69 | ... + ... | here | | tst-IncompleteHostnameRegExp.rb:59:5:59:20 | foo.example\\.com | This regular expression has an unescaped '.' before 'example\\.com', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.rb:59:2:59:32 | /^(foo.example\\.com\|whatever)$/ | here | +| tst-IncompleteHostnameRegExp.rb:81:11:81:34 | ^http://test.example.com | This string, which is used as a regular expression $@, has an unescaped '.' before 'example.com', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.rb:77:22:77:22 | x | here | diff --git a/ruby/ql/test/query-tests/security/cwe-020/IncompleteHostnameRegExp/tst-IncompleteHostnameRegExp.rb b/ruby/ql/test/query-tests/security/cwe-020/IncompleteHostnameRegExp/tst-IncompleteHostnameRegExp.rb index 91770040110a..7041e4dc9c46 100644 --- a/ruby/ql/test/query-tests/security/cwe-020/IncompleteHostnameRegExp/tst-IncompleteHostnameRegExp.rb +++ b/ruby/ql/test/query-tests/security/cwe-020/IncompleteHostnameRegExp/tst-IncompleteHostnameRegExp.rb @@ -65,3 +65,17 @@ def convert1(domain) def convert2(domain) return Regexp.new(domain[:hostname]); end + +class A + def self.match?(x) = true +end + +A.match?("^http://test.example.com") # OK + +class B + def self.match?(x) + some_string.match?(x) + end +end + +B.match?("^http://test.example.com") # NOT OK From e7886d0e572a3b13e073dce8a121ef44dd9e6e26 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Mon, 29 Apr 2024 13:31:48 +0200 Subject: [PATCH 116/238] Bazel: add empty registry override --- .bazelrc | 3 + .bazelrc.internal | 4 + misc/bazel/registry/AUTHORS | 7 + misc/bazel/registry/LICENSE | 202 ++++++++++++++++++++++++ misc/bazel/registry/NOTICE | 3 + misc/bazel/registry/README.md | 3 + misc/bazel/registry/bazel_registry.json | 3 + misc/bazel/registry/fix.py | 55 +++++++ 8 files changed, 280 insertions(+) create mode 100644 .bazelrc.internal create mode 100644 misc/bazel/registry/AUTHORS create mode 100644 misc/bazel/registry/LICENSE create mode 100644 misc/bazel/registry/NOTICE create mode 100644 misc/bazel/registry/README.md create mode 100644 misc/bazel/registry/bazel_registry.json create mode 100755 misc/bazel/registry/fix.py diff --git a/.bazelrc b/.bazelrc index 12232b4bbd68..0a49f682da37 100644 --- a/.bazelrc +++ b/.bazelrc @@ -14,4 +14,7 @@ build:linux --cxxopt=-std=c++20 build:macos --cxxopt=-std=c++20 --cpu=darwin_x86_64 build:windows --cxxopt=/std:c++20 --cxxopt=/Zc:preprocessor +common --registry=file:///%workspace%/misc/bazel/registry +common --registry=https://bcr.bazel.build + try-import %workspace%/local.bazelrc diff --git a/.bazelrc.internal b/.bazelrc.internal new file mode 100644 index 000000000000..cdffa9ccdea6 --- /dev/null +++ b/.bazelrc.internal @@ -0,0 +1,4 @@ +# this file should contain bazel settings required to build things from `semmle-code` + +common --registry=file:///%workspace%/ql/misc/bazel/registry +common --registry=https://bcr.bazel.build diff --git a/misc/bazel/registry/AUTHORS b/misc/bazel/registry/AUTHORS new file mode 100644 index 000000000000..42818b292e7c --- /dev/null +++ b/misc/bazel/registry/AUTHORS @@ -0,0 +1,7 @@ +# This is the list of Bazel's significant contributors. +# +# This does not necessarily list everyone who has contributed code, +# especially since many employees of one corporation may be contributing. +# To see the full list of contributors, see the revision history in +# source control. +Google LLC diff --git a/misc/bazel/registry/LICENSE b/misc/bazel/registry/LICENSE new file mode 100644 index 000000000000..d64569567334 --- /dev/null +++ b/misc/bazel/registry/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/misc/bazel/registry/NOTICE b/misc/bazel/registry/NOTICE new file mode 100644 index 000000000000..95329ae18f60 --- /dev/null +++ b/misc/bazel/registry/NOTICE @@ -0,0 +1,3 @@ +The files in this directory where originally taken from http://github.com/bazelbuild/bazel-central-registry and are +a derivative work thereof, distributed under the Apache 2.0 license, with the following exceptions: +* the `fix.py` file was added under the MIT license as the rest of the `codeql` repository. diff --git a/misc/bazel/registry/README.md b/misc/bazel/registry/README.md new file mode 100644 index 000000000000..5d1723d0eacb --- /dev/null +++ b/misc/bazel/registry/README.md @@ -0,0 +1,3 @@ +Versions to be patched can be taken from https://github.com/bazelbuild/bazel-central-repository. After adding patches +inside `//patches`, and eventually renaming ``, run [`fix.py`](./fix.py) to align all metadata +to the renamed version and added patches. diff --git a/misc/bazel/registry/bazel_registry.json b/misc/bazel/registry/bazel_registry.json new file mode 100644 index 000000000000..ea3f94f7a1e4 --- /dev/null +++ b/misc/bazel/registry/bazel_registry.json @@ -0,0 +1,3 @@ +{ + "mirrors": [] +} diff --git a/misc/bazel/registry/fix.py b/misc/bazel/registry/fix.py new file mode 100755 index 000000000000..a2b947e19e20 --- /dev/null +++ b/misc/bazel/registry/fix.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 + +# Copyright (c) 2024 GitHub, Inc. + +""" +Fix metadata in overridden registry, updating `metadata.json` to list correct versions and `source.json` +to list correct patches with sha256 hashes. +""" + +import pathlib +import json +import base64 +import hashlib +import re + +this_dir = pathlib.Path(__file__).resolve().parent + + +def sha256(file): + with open(file, 'rb') as input: + hash = hashlib.sha256(input.read()).digest() + hash = base64.b64encode(hash).decode() + return f"sha256-{hash}" + + +def patch_file(file, f): + try: + data = file.read_text() + except FileNotFoundError: + data = None + file.write_text(f(data)) + + +def patch_json(file, **kwargs): + def update(data): + data = json.loads(data) if data else {} + data.update(kwargs) + return json.dumps(data, indent=4) + "\n" + + patch_file(file, update) + + +for entry in this_dir.joinpath("modules").iterdir(): + if not entry.is_dir(): + continue + versions = [e for e in entry.iterdir() if e.is_dir()] + + patch_json(entry / "metadata.json", versions=[v.name for v in versions]) + + for version in versions: + patch_json(version / "source.json", patches={ + p.name: sha256(p) for p in version.joinpath("patches").iterdir() + }) + patch_file(version / "MODULE.bazel", + lambda s: re.sub(r'''version\s*=\s*['"].*['"]''', f'version = "{version.name}"', s, 1)) From cb85a756a053b4f7526e3ef7ab88e4c044baa39d Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Mon, 29 Apr 2024 13:42:05 +0200 Subject: [PATCH 117/238] Bazel: patch `apple_support` to avoid registering its toolchain This is done in order to avoid requiring a full Xcode installation, but still being able to use other `apple_support` facilities, like `universal_binary`. --- MODULE.bazel | 2 +- .../1.15.1-codeql.1/MODULE.bazel | 17 ++++++++++++++++ .../1.15.1-codeql.1/patches/module.patch | 20 +++++++++++++++++++ .../apple_support/1.15.1-codeql.1/source.json | 9 +++++++++ .../modules/apple_support/metadata.json | 5 +++++ 5 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 misc/bazel/registry/modules/apple_support/1.15.1-codeql.1/MODULE.bazel create mode 100644 misc/bazel/registry/modules/apple_support/1.15.1-codeql.1/patches/module.patch create mode 100644 misc/bazel/registry/modules/apple_support/1.15.1-codeql.1/source.json create mode 100644 misc/bazel/registry/modules/apple_support/metadata.json diff --git a/MODULE.bazel b/MODULE.bazel index 5fd99f767404..875e61da383a 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -13,7 +13,7 @@ local_path_override( # see https://registry.bazel.build/ for a list of available packages -bazel_dep(name = "apple_support", version = "1.15.1") +bazel_dep(name = "apple_support", version = "1.15.1-codeql.1") bazel_dep(name = "platforms", version = "0.0.9") bazel_dep(name = "rules_go", version = "0.47.0") bazel_dep(name = "rules_pkg", version = "0.10.1") diff --git a/misc/bazel/registry/modules/apple_support/1.15.1-codeql.1/MODULE.bazel b/misc/bazel/registry/modules/apple_support/1.15.1-codeql.1/MODULE.bazel new file mode 100644 index 000000000000..a58d520fee20 --- /dev/null +++ b/misc/bazel/registry/modules/apple_support/1.15.1-codeql.1/MODULE.bazel @@ -0,0 +1,17 @@ +module( + name = "apple_support", + version = "1.15.1-codeql.1", + bazel_compatibility = [">=6.0.0"], + compatibility_level = 1, + repo_name = "build_bazel_apple_support", +) + +bazel_dep(name = "bazel_skylib", version = "1.3.0") +bazel_dep(name = "platforms", version = "0.0.9") + +bazel_dep( + name = "stardoc", + version = "0.6.2", + dev_dependency = True, + repo_name = "io_bazel_stardoc", +) diff --git a/misc/bazel/registry/modules/apple_support/1.15.1-codeql.1/patches/module.patch b/misc/bazel/registry/modules/apple_support/1.15.1-codeql.1/patches/module.patch new file mode 100644 index 000000000000..59fc49ec7b37 --- /dev/null +++ b/misc/bazel/registry/modules/apple_support/1.15.1-codeql.1/patches/module.patch @@ -0,0 +1,20 @@ +diff --git a/MODULE.bazel b/MODULE.bazel +index 6b06c3b..99bc7c6 100644 +--- a/MODULE.bazel ++++ b/MODULE.bazel +@@ -1,6 +1,6 @@ + module( + name = "apple_support", +- version = "0", ++ version = "1.15.1-codeql.1", + bazel_compatibility = [">=6.0.0"], + compatibility_level = 1, + repo_name = "build_bazel_apple_support", +@@ -16,7 +16,3 @@ bazel_dep( + repo_name = "io_bazel_stardoc", + ) + +-apple_cc_configure = use_extension("//crosstool:setup.bzl", "apple_cc_configure_extension") +-use_repo(apple_cc_configure, "local_config_apple_cc", "local_config_apple_cc_toolchains") +- +-register_toolchains("@local_config_apple_cc_toolchains//:all") diff --git a/misc/bazel/registry/modules/apple_support/1.15.1-codeql.1/source.json b/misc/bazel/registry/modules/apple_support/1.15.1-codeql.1/source.json new file mode 100644 index 000000000000..57a1f2137fea --- /dev/null +++ b/misc/bazel/registry/modules/apple_support/1.15.1-codeql.1/source.json @@ -0,0 +1,9 @@ +{ + "integrity": "sha256-xLsrc2fEhDgjAK7nW+WYuS+EeJb7MbvSLzojRq32aoA=", + "strip_prefix": "", + "url": "https://github.com/bazelbuild/apple_support/releases/download/1.15.1/apple_support.1.15.1.tar.gz", + "patches": { + "module.patch": "sha256-K06B2W9t6nKcU8S5u6cWeNIdw/vGWWKAoJdGiI8CSS0=" + }, + "patch_strip": 1 +} diff --git a/misc/bazel/registry/modules/apple_support/metadata.json b/misc/bazel/registry/modules/apple_support/metadata.json new file mode 100644 index 000000000000..8a0e54c9abd9 --- /dev/null +++ b/misc/bazel/registry/modules/apple_support/metadata.json @@ -0,0 +1,5 @@ +{ + "versions": [ + "1.15.1-codeql.1" + ] +} From 94364f724ee4021f6cac5021461c07a2f50c9433 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Mon, 29 Apr 2024 16:46:00 +0100 Subject: [PATCH 118/238] C++: Remove CP between all sinks and all states in 'cpp/iterator-to-expired-container'. --- .../CWE/CWE-416/IteratorToExpiredContainer.ql | 46 +++++++++++++++---- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.ql b/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.ql index ec8f7cbef91a..51dfd3478ac6 100644 --- a/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.ql +++ b/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.ql @@ -70,6 +70,31 @@ predicate destroyedToBeginSink(DataFlow::Node sink, FunctionCall fc) { ) } +/** + * Holds if `node1` is the node corresponding to a qualifier of a destructor + * call and `node2` is a node that is destroyed as a result of `node1` being + * destroyed. + */ +private predicate qualifierToDestroyed(DataFlow::Node node1, DataFlow::Node node2) { + tempToDestructorSink(node1, _) and + node2 = getADestroyedNode(node1) +} + +/** + * A configuration to track flow from a destroyed node to a qualifier of + * a `begin` or `end` function call. + * + * This configuration exists to prevent a cartesian product between all sinks and + * all states in `Config::isSink`. + */ +module Config0 implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { qualifierToDestroyed(_, source) } + + predicate isSink(DataFlow::Node sink) { destroyedToBeginSink(sink, _) } +} + +module Flow0 = DataFlow::Global; + /** * A configuration to track flow from a temporary variable to the qualifier of * a destructor call, and subsequently to a qualifier of a call to `begin` or @@ -79,12 +104,15 @@ module Config implements DataFlow::StateConfigSig { newtype FlowState = additional TempToDestructor() or additional DestroyedToBegin(DataFlow::Node n) { - exists(DataFlow::Node thisOperand | - tempToDestructorSink(thisOperand, _) and - n = getADestroyedNode(thisOperand) - ) + any(Flow0::PathNode pn | pn.isSource()).getNode() = n } + /** + * Holds if `sink` is a qualifier to a call to `begin`, and `mid` is an + * object that is destroyed. + */ + private predicate relevant(DataFlow::Node mid, DataFlow::Node sink) { Flow0::flow(mid, sink) } + predicate isSource(DataFlow::Node source, FlowState state) { source.asInstruction().(VariableAddressInstruction).getIRVariable() instanceof IRTempVariable and state = TempToDestructor() @@ -93,16 +121,16 @@ module Config implements DataFlow::StateConfigSig { predicate isAdditionalFlowStep( DataFlow::Node node1, FlowState state1, DataFlow::Node node2, FlowState state2 ) { - tempToDestructorSink(node1, _) and state1 = TempToDestructor() and state2 = DestroyedToBegin(node2) and - node2 = getADestroyedNode(node1) + qualifierToDestroyed(node1, node2) } predicate isSink(DataFlow::Node sink, FlowState state) { - // Note: This is a non-trivial cartesian product! - // Hopefully, both of these sets are quite small in practice - destroyedToBeginSink(sink, _) and state instanceof DestroyedToBegin + exists(DataFlow::Node mid | + relevant(mid, sink) and + state = DestroyedToBegin(mid) + ) } DataFlow::FlowFeature getAFeature() { From a28f87fff061164c93a75344151b8148f8344a27 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Mon, 29 Apr 2024 13:31:48 +0200 Subject: [PATCH 119/238] Bazel: add empty registry override This will unblock work in parallel on two separate PRs that require patching different modules. --- .bazelrc | 3 + .bazelrc.internal | 4 + misc/bazel/registry/AUTHORS | 7 + misc/bazel/registry/LICENSE | 202 ++++++++++++++++++++++++ misc/bazel/registry/NOTICE | 3 + misc/bazel/registry/README.md | 3 + misc/bazel/registry/bazel_registry.json | 3 + misc/bazel/registry/fix.py | 55 +++++++ 8 files changed, 280 insertions(+) create mode 100644 .bazelrc.internal create mode 100644 misc/bazel/registry/AUTHORS create mode 100644 misc/bazel/registry/LICENSE create mode 100644 misc/bazel/registry/NOTICE create mode 100644 misc/bazel/registry/README.md create mode 100644 misc/bazel/registry/bazel_registry.json create mode 100755 misc/bazel/registry/fix.py diff --git a/.bazelrc b/.bazelrc index 12232b4bbd68..0a49f682da37 100644 --- a/.bazelrc +++ b/.bazelrc @@ -14,4 +14,7 @@ build:linux --cxxopt=-std=c++20 build:macos --cxxopt=-std=c++20 --cpu=darwin_x86_64 build:windows --cxxopt=/std:c++20 --cxxopt=/Zc:preprocessor +common --registry=file:///%workspace%/misc/bazel/registry +common --registry=https://bcr.bazel.build + try-import %workspace%/local.bazelrc diff --git a/.bazelrc.internal b/.bazelrc.internal new file mode 100644 index 000000000000..cdffa9ccdea6 --- /dev/null +++ b/.bazelrc.internal @@ -0,0 +1,4 @@ +# this file should contain bazel settings required to build things from `semmle-code` + +common --registry=file:///%workspace%/ql/misc/bazel/registry +common --registry=https://bcr.bazel.build diff --git a/misc/bazel/registry/AUTHORS b/misc/bazel/registry/AUTHORS new file mode 100644 index 000000000000..42818b292e7c --- /dev/null +++ b/misc/bazel/registry/AUTHORS @@ -0,0 +1,7 @@ +# This is the list of Bazel's significant contributors. +# +# This does not necessarily list everyone who has contributed code, +# especially since many employees of one corporation may be contributing. +# To see the full list of contributors, see the revision history in +# source control. +Google LLC diff --git a/misc/bazel/registry/LICENSE b/misc/bazel/registry/LICENSE new file mode 100644 index 000000000000..d64569567334 --- /dev/null +++ b/misc/bazel/registry/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/misc/bazel/registry/NOTICE b/misc/bazel/registry/NOTICE new file mode 100644 index 000000000000..95329ae18f60 --- /dev/null +++ b/misc/bazel/registry/NOTICE @@ -0,0 +1,3 @@ +The files in this directory where originally taken from http://github.com/bazelbuild/bazel-central-registry and are +a derivative work thereof, distributed under the Apache 2.0 license, with the following exceptions: +* the `fix.py` file was added under the MIT license as the rest of the `codeql` repository. diff --git a/misc/bazel/registry/README.md b/misc/bazel/registry/README.md new file mode 100644 index 000000000000..5d1723d0eacb --- /dev/null +++ b/misc/bazel/registry/README.md @@ -0,0 +1,3 @@ +Versions to be patched can be taken from https://github.com/bazelbuild/bazel-central-repository. After adding patches +inside `//patches`, and eventually renaming ``, run [`fix.py`](./fix.py) to align all metadata +to the renamed version and added patches. diff --git a/misc/bazel/registry/bazel_registry.json b/misc/bazel/registry/bazel_registry.json new file mode 100644 index 000000000000..ea3f94f7a1e4 --- /dev/null +++ b/misc/bazel/registry/bazel_registry.json @@ -0,0 +1,3 @@ +{ + "mirrors": [] +} diff --git a/misc/bazel/registry/fix.py b/misc/bazel/registry/fix.py new file mode 100755 index 000000000000..a2b947e19e20 --- /dev/null +++ b/misc/bazel/registry/fix.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 + +# Copyright (c) 2024 GitHub, Inc. + +""" +Fix metadata in overridden registry, updating `metadata.json` to list correct versions and `source.json` +to list correct patches with sha256 hashes. +""" + +import pathlib +import json +import base64 +import hashlib +import re + +this_dir = pathlib.Path(__file__).resolve().parent + + +def sha256(file): + with open(file, 'rb') as input: + hash = hashlib.sha256(input.read()).digest() + hash = base64.b64encode(hash).decode() + return f"sha256-{hash}" + + +def patch_file(file, f): + try: + data = file.read_text() + except FileNotFoundError: + data = None + file.write_text(f(data)) + + +def patch_json(file, **kwargs): + def update(data): + data = json.loads(data) if data else {} + data.update(kwargs) + return json.dumps(data, indent=4) + "\n" + + patch_file(file, update) + + +for entry in this_dir.joinpath("modules").iterdir(): + if not entry.is_dir(): + continue + versions = [e for e in entry.iterdir() if e.is_dir()] + + patch_json(entry / "metadata.json", versions=[v.name for v in versions]) + + for version in versions: + patch_json(version / "source.json", patches={ + p.name: sha256(p) for p in version.joinpath("patches").iterdir() + }) + patch_file(version / "MODULE.bazel", + lambda s: re.sub(r'''version\s*=\s*['"].*['"]''', f'version = "{version.name}"', s, 1)) From 676bcf39a560d52e5b3c28fe8ff47f4cfbf47a57 Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Fri, 26 Apr 2024 15:33:36 +0100 Subject: [PATCH 120/238] Java: Remove support for deprecated ODASA_BUILD_ERROR_DIR env var --- .../src/main/java/com/semmle/util/process/Env.java | 1 - java/ql/lib/change-notes/2024-04-26-env-vars.md | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 java/ql/lib/change-notes/2024-04-26-env-vars.md diff --git a/java/kotlin-extractor/src/main/java/com/semmle/util/process/Env.java b/java/kotlin-extractor/src/main/java/com/semmle/util/process/Env.java index 0ce3d42c14f0..71a03b0bf45a 100644 --- a/java/kotlin-extractor/src/main/java/com/semmle/util/process/Env.java +++ b/java/kotlin-extractor/src/main/java/com/semmle/util/process/Env.java @@ -276,7 +276,6 @@ public enum Var { */ ODASA_SRC, ODASA_DB, - ODASA_BUILD_ERROR_DIR, TRAP_FOLDER, SOURCE_ARCHIVE, ODASA_OUTPUT, diff --git a/java/ql/lib/change-notes/2024-04-26-env-vars.md b/java/ql/lib/change-notes/2024-04-26-env-vars.md new file mode 100644 index 000000000000..cb2003740ef2 --- /dev/null +++ b/java/ql/lib/change-notes/2024-04-26-env-vars.md @@ -0,0 +1,4 @@ +--- +category: breaking +--- +* The Java extractor no longer supports the `ODASA_BUILD_ERROR_DIR` legacy environment variable. From 5228d94d42ddc9fcece64fc49c3c95e79918f3f1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 30 Apr 2024 10:25:51 +0000 Subject: [PATCH 121/238] Release preparation for version 2.17.2 --- cpp/ql/lib/CHANGELOG.md | 17 +++++++++++++++++ cpp/ql/lib/change-notes/2024-04-05-sound-ir.md | 4 ---- .../lib/change-notes/2024-04-18-param-nodes.md | 4 ---- .../2024-04-26-outdated-deprecations.md | 4 ---- cpp/ql/lib/change-notes/2024-10-04-getc.md | 4 ---- .../change-notes/2024-10-04-models-as-data.md | 4 ---- cpp/ql/lib/change-notes/2024-10-04-zmq.md | 4 ---- cpp/ql/lib/change-notes/released/0.13.0.md | 16 ++++++++++++++++ cpp/ql/lib/codeql-pack.release.yml | 2 +- cpp/ql/lib/qlpack.yml | 2 +- cpp/ql/src/CHANGELOG.md | 8 ++++++++ .../change-notes/2024-04-25-path-injection.md | 4 ---- .../0.9.11.md} | 10 ++++++---- cpp/ql/src/codeql-pack.release.yml | 2 +- cpp/ql/src/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md | 4 ++++ .../lib/change-notes/released/1.7.15.md | 3 +++ .../Solorigate/lib/codeql-pack.release.yml | 2 +- csharp/ql/campaigns/Solorigate/lib/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/src/CHANGELOG.md | 4 ++++ .../src/change-notes/released/1.7.15.md | 3 +++ .../Solorigate/src/codeql-pack.release.yml | 2 +- csharp/ql/campaigns/Solorigate/src/qlpack.yml | 2 +- csharp/ql/lib/CHANGELOG.md | 12 ++++++++++++ ...2024-04-05-dotnet-runtime-property-models.md | 4 ---- .../0.10.0.md} | 13 +++++++++---- csharp/ql/lib/codeql-pack.release.yml | 2 +- csharp/ql/lib/qlpack.yml | 2 +- csharp/ql/src/CHANGELOG.md | 4 ++++ csharp/ql/src/change-notes/released/0.8.15.md | 3 +++ csharp/ql/src/codeql-pack.release.yml | 2 +- csharp/ql/src/qlpack.yml | 2 +- go/ql/consistency-queries/CHANGELOG.md | 4 ++++ .../change-notes/released/0.0.14.md | 3 +++ .../consistency-queries/codeql-pack.release.yml | 2 +- go/ql/consistency-queries/qlpack.yml | 2 +- go/ql/lib/CHANGELOG.md | 11 +++++++++++ .../2024-04-26-outdated-deprecations.md | 4 ---- .../0.8.0.md} | 11 ++++++++--- go/ql/lib/codeql-pack.release.yml | 2 +- go/ql/lib/qlpack.yml | 2 +- go/ql/src/CHANGELOG.md | 7 +++++++ ...-17-incorrect-integer-conversion-barriers.md | 4 ---- .../0.7.15.md} | 8 +++++--- go/ql/src/codeql-pack.release.yml | 2 +- go/ql/src/qlpack.yml | 2 +- java/ql/automodel/src/CHANGELOG.md | 4 ++++ .../src/change-notes/released/0.0.22.md | 3 +++ java/ql/automodel/src/codeql-pack.release.yml | 2 +- java/ql/automodel/src/qlpack.yml | 2 +- java/ql/lib/CHANGELOG.md | 6 ++++++ .../0.10.0.md} | 7 ++++--- java/ql/lib/codeql-pack.release.yml | 2 +- java/ql/lib/qlpack.yml | 2 +- java/ql/src/CHANGELOG.md | 4 ++++ java/ql/src/change-notes/released/0.8.15.md | 3 +++ java/ql/src/codeql-pack.release.yml | 2 +- java/ql/src/qlpack.yml | 2 +- javascript/ql/lib/CHANGELOG.md | 12 ++++++++++++ ...2024-04-02-more-robust-commonjs-detection.md | 4 ---- .../0.9.0.md} | 13 +++++++++---- javascript/ql/lib/codeql-pack.release.yml | 2 +- javascript/ql/lib/qlpack.yml | 2 +- javascript/ql/src/CHANGELOG.md | 9 +++++++++ .../0.8.15.md} | 7 ++++--- javascript/ql/src/codeql-pack.release.yml | 2 +- javascript/ql/src/qlpack.yml | 2 +- misc/suite-helpers/CHANGELOG.md | 4 ++++ .../change-notes/released/0.7.15.md | 3 +++ misc/suite-helpers/codeql-pack.release.yml | 2 +- misc/suite-helpers/qlpack.yml | 2 +- python/ql/lib/CHANGELOG.md | 11 +++++++++++ ...-04-22-renaming-StrConst-to-StringLiteral.md | 5 ----- .../2024-04-26-outdated-deprecations.md | 5 ----- python/ql/lib/change-notes/released/0.12.0.md | 10 ++++++++++ python/ql/lib/codeql-pack.release.yml | 2 +- python/ql/lib/qlpack.yml | 2 +- python/ql/src/CHANGELOG.md | 4 ++++ python/ql/src/change-notes/released/0.9.15.md | 3 +++ python/ql/src/codeql-pack.release.yml | 2 +- python/ql/src/qlpack.yml | 2 +- ruby/ql/lib/CHANGELOG.md | 7 +++++++ .../0.9.0.md} | 9 +++++---- ruby/ql/lib/codeql-pack.release.yml | 2 +- ruby/ql/lib/qlpack.yml | 2 +- ruby/ql/src/CHANGELOG.md | 4 ++++ ruby/ql/src/change-notes/released/0.8.15.md | 3 +++ ruby/ql/src/codeql-pack.release.yml | 2 +- ruby/ql/src/qlpack.yml | 2 +- shared/controlflow/CHANGELOG.md | 4 ++++ .../controlflow/change-notes/released/0.1.15.md | 3 +++ shared/controlflow/codeql-pack.release.yml | 2 +- shared/controlflow/qlpack.yml | 2 +- shared/dataflow/CHANGELOG.md | 6 ++++++ .../0.2.6.md} | 7 ++++--- shared/dataflow/codeql-pack.release.yml | 2 +- shared/dataflow/qlpack.yml | 2 +- shared/mad/CHANGELOG.md | 4 ++++ shared/mad/change-notes/released/0.2.15.md | 3 +++ shared/mad/codeql-pack.release.yml | 2 +- shared/mad/qlpack.yml | 2 +- shared/rangeanalysis/CHANGELOG.md | 4 ++++ .../change-notes/released/0.0.14.md | 3 +++ shared/rangeanalysis/codeql-pack.release.yml | 2 +- shared/rangeanalysis/qlpack.yml | 2 +- shared/regex/CHANGELOG.md | 4 ++++ shared/regex/change-notes/released/0.2.15.md | 3 +++ shared/regex/codeql-pack.release.yml | 2 +- shared/regex/qlpack.yml | 2 +- shared/ssa/CHANGELOG.md | 4 ++++ shared/ssa/change-notes/released/0.2.15.md | 3 +++ shared/ssa/codeql-pack.release.yml | 2 +- shared/ssa/qlpack.yml | 2 +- shared/threat-models/CHANGELOG.md | 4 ++++ .../change-notes/released/0.0.14.md | 3 +++ shared/threat-models/codeql-pack.release.yml | 2 +- shared/threat-models/qlpack.yml | 2 +- shared/tutorial/CHANGELOG.md | 4 ++++ shared/tutorial/change-notes/released/0.2.15.md | 3 +++ shared/tutorial/codeql-pack.release.yml | 2 +- shared/tutorial/qlpack.yml | 2 +- shared/typeflow/CHANGELOG.md | 4 ++++ shared/typeflow/change-notes/released/0.0.2.md | 3 +++ shared/typeflow/codeql-pack.release.yml | 2 +- shared/typeflow/qlpack.yml | 2 +- shared/typetracking/CHANGELOG.md | 4 ++++ .../change-notes/released/0.2.15.md | 3 +++ shared/typetracking/codeql-pack.release.yml | 2 +- shared/typetracking/qlpack.yml | 2 +- shared/typos/CHANGELOG.md | 4 ++++ shared/typos/change-notes/released/0.2.15.md | 3 +++ shared/typos/codeql-pack.release.yml | 2 +- shared/typos/qlpack.yml | 2 +- shared/util/CHANGELOG.md | 4 ++++ shared/util/change-notes/released/0.2.15.md | 3 +++ shared/util/codeql-pack.release.yml | 2 +- shared/util/qlpack.yml | 2 +- shared/xml/CHANGELOG.md | 4 ++++ shared/xml/change-notes/released/0.0.2.md | 3 +++ shared/xml/codeql-pack.release.yml | 2 +- shared/xml/qlpack.yml | 2 +- shared/yaml/CHANGELOG.md | 4 ++++ shared/yaml/change-notes/released/0.2.15.md | 3 +++ shared/yaml/codeql-pack.release.yml | 2 +- shared/yaml/qlpack.yml | 2 +- swift/ql/lib/CHANGELOG.md | 4 ++++ swift/ql/lib/change-notes/released/0.3.15.md | 3 +++ swift/ql/lib/codeql-pack.release.yml | 2 +- swift/ql/lib/qlpack.yml | 2 +- swift/ql/src/CHANGELOG.md | 4 ++++ swift/ql/src/change-notes/released/0.3.15.md | 3 +++ swift/ql/src/codeql-pack.release.yml | 2 +- swift/ql/src/qlpack.yml | 2 +- 153 files changed, 424 insertions(+), 155 deletions(-) delete mode 100644 cpp/ql/lib/change-notes/2024-04-05-sound-ir.md delete mode 100644 cpp/ql/lib/change-notes/2024-04-18-param-nodes.md delete mode 100644 cpp/ql/lib/change-notes/2024-04-26-outdated-deprecations.md delete mode 100644 cpp/ql/lib/change-notes/2024-10-04-getc.md delete mode 100644 cpp/ql/lib/change-notes/2024-10-04-models-as-data.md delete mode 100644 cpp/ql/lib/change-notes/2024-10-04-zmq.md create mode 100644 cpp/ql/lib/change-notes/released/0.13.0.md delete mode 100644 cpp/ql/src/change-notes/2024-04-25-path-injection.md rename cpp/ql/src/change-notes/{2024-04-09-reduce-FP.md => released/0.9.11.md} (60%) create mode 100644 csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.7.15.md create mode 100644 csharp/ql/campaigns/Solorigate/src/change-notes/released/1.7.15.md delete mode 100644 csharp/ql/lib/change-notes/2024-04-05-dotnet-runtime-property-models.md rename csharp/ql/lib/change-notes/{2024-04-26-outdated-deprecations.md => released/0.10.0.md} (64%) create mode 100644 csharp/ql/src/change-notes/released/0.8.15.md create mode 100644 go/ql/consistency-queries/change-notes/released/0.0.14.md delete mode 100644 go/ql/lib/change-notes/2024-04-26-outdated-deprecations.md rename go/ql/lib/change-notes/{2024-04-18-untrustedflowsource-renamed-remoteflowsource.md => released/0.8.0.md} (72%) delete mode 100644 go/ql/src/change-notes/2024-04-17-incorrect-integer-conversion-barriers.md rename go/ql/src/change-notes/{2024-04-24-incomplete-hostname-regexp.md => released/0.7.15.md} (52%) create mode 100644 java/ql/automodel/src/change-notes/released/0.0.22.md rename java/ql/lib/change-notes/{2024-04-26-outdated-deprecations.md => released/0.10.0.md} (81%) create mode 100644 java/ql/src/change-notes/released/0.8.15.md delete mode 100644 javascript/ql/lib/change-notes/2024-04-02-more-robust-commonjs-detection.md rename javascript/ql/lib/change-notes/{2024-04-26-outdated-deprecations.md => released/0.9.0.md} (66%) rename javascript/ql/src/change-notes/{2024-04-17-strict-mode.md => released/0.8.15.md} (89%) create mode 100644 misc/suite-helpers/change-notes/released/0.7.15.md delete mode 100644 python/ql/lib/change-notes/2024-04-22-renaming-StrConst-to-StringLiteral.md delete mode 100644 python/ql/lib/change-notes/2024-04-26-outdated-deprecations.md create mode 100644 python/ql/lib/change-notes/released/0.12.0.md create mode 100644 python/ql/src/change-notes/released/0.9.15.md rename ruby/ql/lib/change-notes/{2024-04-26-outdated-deprecations.md => released/0.9.0.md} (75%) create mode 100644 ruby/ql/src/change-notes/released/0.8.15.md create mode 100644 shared/controlflow/change-notes/released/0.1.15.md rename shared/dataflow/change-notes/{2024-04-19-fieldflowbranchlimit.md => released/0.2.6.md} (94%) create mode 100644 shared/mad/change-notes/released/0.2.15.md create mode 100644 shared/rangeanalysis/change-notes/released/0.0.14.md create mode 100644 shared/regex/change-notes/released/0.2.15.md create mode 100644 shared/ssa/change-notes/released/0.2.15.md create mode 100644 shared/threat-models/change-notes/released/0.0.14.md create mode 100644 shared/tutorial/change-notes/released/0.2.15.md create mode 100644 shared/typeflow/change-notes/released/0.0.2.md create mode 100644 shared/typetracking/change-notes/released/0.2.15.md create mode 100644 shared/typos/change-notes/released/0.2.15.md create mode 100644 shared/util/change-notes/released/0.2.15.md create mode 100644 shared/xml/change-notes/released/0.0.2.md create mode 100644 shared/yaml/change-notes/released/0.2.15.md create mode 100644 swift/ql/lib/change-notes/released/0.3.15.md create mode 100644 swift/ql/src/change-notes/released/0.3.15.md diff --git a/cpp/ql/lib/CHANGELOG.md b/cpp/ql/lib/CHANGELOG.md index e480b46a279d..bcb7d30a2ed9 100644 --- a/cpp/ql/lib/CHANGELOG.md +++ b/cpp/ql/lib/CHANGELOG.md @@ -1,3 +1,20 @@ +## 0.13.0 + +### Breaking Changes + +* Deleted the deprecated `GlobalValueNumberingImpl.qll` implementation. + +### New Features + +* Models-as-Data support has been added for C/C++. This feature allows flow sources, sinks and summaries to be expressed in compact strings as an alternative to modelling each source / sink / summary with explicit QL. See `dataflow/ExternalFlow.qll` for documentation and specification of the model format, and `models/implementations/ZMQ.qll` for a simple example of models. Importing models from `.yml` is not yet supported. + +### Minor Analysis Improvements + +* Source models have been added for the standard library function `getc` (and variations). +* Source, sink and flow models for the ZeroMQ (ZMQ) networking library have been added. +* Parameters of functions without definitions now have `ParameterNode`s. +* The alias analysis used internally by various libraries has been improved to answer alias questions more conservatively. As a result, some queries may report fewer false positives. + ## 0.12.11 No user-facing changes. diff --git a/cpp/ql/lib/change-notes/2024-04-05-sound-ir.md b/cpp/ql/lib/change-notes/2024-04-05-sound-ir.md deleted file mode 100644 index 0bb930934168..000000000000 --- a/cpp/ql/lib/change-notes/2024-04-05-sound-ir.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* The alias analysis used internally by various libraries has been improved to answer alias questions more conservatively. As a result, some queries may report fewer false positives. \ No newline at end of file diff --git a/cpp/ql/lib/change-notes/2024-04-18-param-nodes.md b/cpp/ql/lib/change-notes/2024-04-18-param-nodes.md deleted file mode 100644 index 1911af38d8a0..000000000000 --- a/cpp/ql/lib/change-notes/2024-04-18-param-nodes.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Parameters of functions without definitions now have `ParameterNode`s. diff --git a/cpp/ql/lib/change-notes/2024-04-26-outdated-deprecations.md b/cpp/ql/lib/change-notes/2024-04-26-outdated-deprecations.md deleted file mode 100644 index 642e3443640a..000000000000 --- a/cpp/ql/lib/change-notes/2024-04-26-outdated-deprecations.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: breaking ---- -* Deleted the deprecated `GlobalValueNumberingImpl.qll` implementation. diff --git a/cpp/ql/lib/change-notes/2024-10-04-getc.md b/cpp/ql/lib/change-notes/2024-10-04-getc.md deleted file mode 100644 index 9174b7a11848..000000000000 --- a/cpp/ql/lib/change-notes/2024-10-04-getc.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Source models have been added for the standard library function `getc` (and variations). diff --git a/cpp/ql/lib/change-notes/2024-10-04-models-as-data.md b/cpp/ql/lib/change-notes/2024-10-04-models-as-data.md deleted file mode 100644 index 83e660cdb649..000000000000 --- a/cpp/ql/lib/change-notes/2024-10-04-models-as-data.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: feature ---- -* Models-as-Data support has been added for C/C++. This feature allows flow sources, sinks and summaries to be expressed in compact strings as an alternative to modelling each source / sink / summary with explicit QL. See `dataflow/ExternalFlow.qll` for documentation and specification of the model format, and `models/implementations/ZMQ.qll` for a simple example of models. Importing models from `.yml` is not yet supported. diff --git a/cpp/ql/lib/change-notes/2024-10-04-zmq.md b/cpp/ql/lib/change-notes/2024-10-04-zmq.md deleted file mode 100644 index 2800a4d55b34..000000000000 --- a/cpp/ql/lib/change-notes/2024-10-04-zmq.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Source, sink and flow models for the ZeroMQ (ZMQ) networking library have been added. diff --git a/cpp/ql/lib/change-notes/released/0.13.0.md b/cpp/ql/lib/change-notes/released/0.13.0.md new file mode 100644 index 000000000000..84dc06b699cb --- /dev/null +++ b/cpp/ql/lib/change-notes/released/0.13.0.md @@ -0,0 +1,16 @@ +## 0.13.0 + +### Breaking Changes + +* Deleted the deprecated `GlobalValueNumberingImpl.qll` implementation. + +### New Features + +* Models-as-Data support has been added for C/C++. This feature allows flow sources, sinks and summaries to be expressed in compact strings as an alternative to modelling each source / sink / summary with explicit QL. See `dataflow/ExternalFlow.qll` for documentation and specification of the model format, and `models/implementations/ZMQ.qll` for a simple example of models. Importing models from `.yml` is not yet supported. + +### Minor Analysis Improvements + +* Source models have been added for the standard library function `getc` (and variations). +* Source, sink and flow models for the ZeroMQ (ZMQ) networking library have been added. +* Parameters of functions without definitions now have `ParameterNode`s. +* The alias analysis used internally by various libraries has been improved to answer alias questions more conservatively. As a result, some queries may report fewer false positives. diff --git a/cpp/ql/lib/codeql-pack.release.yml b/cpp/ql/lib/codeql-pack.release.yml index 18a7ef452ef3..5a1b274ee587 100644 --- a/cpp/ql/lib/codeql-pack.release.yml +++ b/cpp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.12.11 +lastReleaseVersion: 0.13.0 diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml index 4691c2b2a9af..f6f48625357b 100644 --- a/cpp/ql/lib/qlpack.yml +++ b/cpp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-all -version: 0.12.12-dev +version: 0.13.0 groups: cpp dbscheme: semmlecode.cpp.dbscheme extractor: cpp diff --git a/cpp/ql/src/CHANGELOG.md b/cpp/ql/src/CHANGELOG.md index ab33b22360c1..52ce33161a75 100644 --- a/cpp/ql/src/CHANGELOG.md +++ b/cpp/ql/src/CHANGELOG.md @@ -1,3 +1,11 @@ +## 0.9.11 + +### Minor Analysis Improvements + +* The "Uncontrolled data used in path expression" query (`cpp/path-injection`) query produces fewer near-duplicate results. +* The "Global variable may be used before initialization" query (`cpp/global-use-before-init`) no longer raises an alert on global variables that are initialized when they are declared. +* The "Inconsistent null check of pointer" query (`cpp/inconsistent-nullness-testing`) query no longer raises an alert when the guarded check is in a macro expansion. + ## 0.9.10 No user-facing changes. diff --git a/cpp/ql/src/change-notes/2024-04-25-path-injection.md b/cpp/ql/src/change-notes/2024-04-25-path-injection.md deleted file mode 100644 index 9989a7dc6221..000000000000 --- a/cpp/ql/src/change-notes/2024-04-25-path-injection.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* The "Uncontrolled data used in path expression" query (`cpp/path-injection`) query produces fewer near-duplicate results. diff --git a/cpp/ql/src/change-notes/2024-04-09-reduce-FP.md b/cpp/ql/src/change-notes/released/0.9.11.md similarity index 60% rename from cpp/ql/src/change-notes/2024-04-09-reduce-FP.md rename to cpp/ql/src/change-notes/released/0.9.11.md index d2d104d59cd8..41ffd2f0d06b 100644 --- a/cpp/ql/src/change-notes/2024-04-09-reduce-FP.md +++ b/cpp/ql/src/change-notes/released/0.9.11.md @@ -1,5 +1,7 @@ ---- -category: minorAnalysis ---- +## 0.9.11 + +### Minor Analysis Improvements + +* The "Uncontrolled data used in path expression" query (`cpp/path-injection`) query produces fewer near-duplicate results. * The "Global variable may be used before initialization" query (`cpp/global-use-before-init`) no longer raises an alert on global variables that are initialized when they are declared. -* The "Inconsistent null check of pointer" query (`cpp/inconsistent-nullness-testing`) query no longer raises an alert when the guarded check is in a macro expansion. \ No newline at end of file +* The "Inconsistent null check of pointer" query (`cpp/inconsistent-nullness-testing`) query no longer raises an alert when the guarded check is in a macro expansion. diff --git a/cpp/ql/src/codeql-pack.release.yml b/cpp/ql/src/codeql-pack.release.yml index d086ed69541d..47eb8b55bab8 100644 --- a/cpp/ql/src/codeql-pack.release.yml +++ b/cpp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.9.10 +lastReleaseVersion: 0.9.11 diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml index 3fe23a7cbbad..7eb3d91c6029 100644 --- a/cpp/ql/src/qlpack.yml +++ b/cpp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-queries -version: 0.9.11-dev +version: 0.9.11 groups: - cpp - queries diff --git a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md index b19677a4af47..a1fa74650477 100644 --- a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.7.15 + +No user-facing changes. + ## 1.7.14 No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.7.15.md b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.7.15.md new file mode 100644 index 000000000000..42dec3d1f07f --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.7.15.md @@ -0,0 +1,3 @@ +## 1.7.15 + +No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml index e2ee0b0d7d4b..07b34a2aaf70 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.7.14 +lastReleaseVersion: 1.7.15 diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml index 1ba514323d65..56aae235d873 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.7.15-dev +version: 1.7.15 groups: - csharp - solorigate diff --git a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md index b19677a4af47..a1fa74650477 100644 --- a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.7.15 + +No user-facing changes. + ## 1.7.14 No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.7.15.md b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.7.15.md new file mode 100644 index 000000000000..42dec3d1f07f --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.7.15.md @@ -0,0 +1,3 @@ +## 1.7.15 + +No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml index e2ee0b0d7d4b..07b34a2aaf70 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.7.14 +lastReleaseVersion: 1.7.15 diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml index d4840e16bda0..ded88f88d0a3 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.7.15-dev +version: 1.7.15 groups: - csharp - solorigate diff --git a/csharp/ql/lib/CHANGELOG.md b/csharp/ql/lib/CHANGELOG.md index 95817811fdef..c136a0828890 100644 --- a/csharp/ql/lib/CHANGELOG.md +++ b/csharp/ql/lib/CHANGELOG.md @@ -1,3 +1,15 @@ +## 0.10.0 + +### Breaking Changes + +* Deleted the deprecated `getAssemblyName` predicate from the `Operator` class. Use `getFunctionName` instead. +* Deleted the deprecated `LShiftOperator`, `RShiftOperator`, `AssignLShiftExpr`, `AssignRShiftExpr`, `LShiftExpr`, and `RShiftExpr` aliases. +* Deleted the deprecated `getCallableDescription` predicate from the `ExternalApiDataNode` class. Use `hasQualifiedName` instead. + +### Minor Analysis Improvements + +* Generated .NET Runtime models for properties with both getters and setters have been removed as this is now handled by the data flow library. + ## 0.9.1 ### Minor Analysis Improvements diff --git a/csharp/ql/lib/change-notes/2024-04-05-dotnet-runtime-property-models.md b/csharp/ql/lib/change-notes/2024-04-05-dotnet-runtime-property-models.md deleted file mode 100644 index f4ae2b3bb5e8..000000000000 --- a/csharp/ql/lib/change-notes/2024-04-05-dotnet-runtime-property-models.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Generated .NET Runtime models for properties with both getters and setters have been removed as this is now handled by the data flow library. diff --git a/csharp/ql/lib/change-notes/2024-04-26-outdated-deprecations.md b/csharp/ql/lib/change-notes/released/0.10.0.md similarity index 64% rename from csharp/ql/lib/change-notes/2024-04-26-outdated-deprecations.md rename to csharp/ql/lib/change-notes/released/0.10.0.md index 314bb6e01fe3..fc6c28cf41bd 100644 --- a/csharp/ql/lib/change-notes/2024-04-26-outdated-deprecations.md +++ b/csharp/ql/lib/change-notes/released/0.10.0.md @@ -1,6 +1,11 @@ ---- -category: breaking ---- +## 0.10.0 + +### Breaking Changes + * Deleted the deprecated `getAssemblyName` predicate from the `Operator` class. Use `getFunctionName` instead. * Deleted the deprecated `LShiftOperator`, `RShiftOperator`, `AssignLShiftExpr`, `AssignRShiftExpr`, `LShiftExpr`, and `RShiftExpr` aliases. -* Deleted the deprecated `getCallableDescription` predicate from the `ExternalApiDataNode` class. Use `hasQualifiedName` instead. \ No newline at end of file +* Deleted the deprecated `getCallableDescription` predicate from the `ExternalApiDataNode` class. Use `hasQualifiedName` instead. + +### Minor Analysis Improvements + +* Generated .NET Runtime models for properties with both getters and setters have been removed as this is now handled by the data flow library. diff --git a/csharp/ql/lib/codeql-pack.release.yml b/csharp/ql/lib/codeql-pack.release.yml index 6789dcd18b70..b21db6232459 100644 --- a/csharp/ql/lib/codeql-pack.release.yml +++ b/csharp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.9.1 +lastReleaseVersion: 0.10.0 diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index 385fba580d08..a5e029d1ea2e 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-all -version: 0.9.2-dev +version: 0.10.0 groups: csharp dbscheme: semmlecode.csharp.dbscheme extractor: csharp diff --git a/csharp/ql/src/CHANGELOG.md b/csharp/ql/src/CHANGELOG.md index 7b89cfb9a385..7954eef127f5 100644 --- a/csharp/ql/src/CHANGELOG.md +++ b/csharp/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.8.15 + +No user-facing changes. + ## 0.8.14 No user-facing changes. diff --git a/csharp/ql/src/change-notes/released/0.8.15.md b/csharp/ql/src/change-notes/released/0.8.15.md new file mode 100644 index 000000000000..18c028b4ff00 --- /dev/null +++ b/csharp/ql/src/change-notes/released/0.8.15.md @@ -0,0 +1,3 @@ +## 0.8.15 + +No user-facing changes. diff --git a/csharp/ql/src/codeql-pack.release.yml b/csharp/ql/src/codeql-pack.release.yml index b36a2e248f34..2e3c183bb7a2 100644 --- a/csharp/ql/src/codeql-pack.release.yml +++ b/csharp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.8.14 +lastReleaseVersion: 0.8.15 diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml index cf2bfcdcd9b8..03a21b8ad75d 100644 --- a/csharp/ql/src/qlpack.yml +++ b/csharp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-queries -version: 0.8.15-dev +version: 0.8.15 groups: - csharp - queries diff --git a/go/ql/consistency-queries/CHANGELOG.md b/go/ql/consistency-queries/CHANGELOG.md index 29ece641a7e3..ad4781e2cbda 100644 --- a/go/ql/consistency-queries/CHANGELOG.md +++ b/go/ql/consistency-queries/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.14 + +No user-facing changes. + ## 0.0.13 No user-facing changes. diff --git a/go/ql/consistency-queries/change-notes/released/0.0.14.md b/go/ql/consistency-queries/change-notes/released/0.0.14.md new file mode 100644 index 000000000000..63b4d50ca454 --- /dev/null +++ b/go/ql/consistency-queries/change-notes/released/0.0.14.md @@ -0,0 +1,3 @@ +## 0.0.14 + +No user-facing changes. diff --git a/go/ql/consistency-queries/codeql-pack.release.yml b/go/ql/consistency-queries/codeql-pack.release.yml index 044e54e4f7e5..ca29e45d0a67 100644 --- a/go/ql/consistency-queries/codeql-pack.release.yml +++ b/go/ql/consistency-queries/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.13 +lastReleaseVersion: 0.0.14 diff --git a/go/ql/consistency-queries/qlpack.yml b/go/ql/consistency-queries/qlpack.yml index 7744027ba9f5..cf6a59361407 100644 --- a/go/ql/consistency-queries/qlpack.yml +++ b/go/ql/consistency-queries/qlpack.yml @@ -1,5 +1,5 @@ name: codeql-go-consistency-queries -version: 0.0.14-dev +version: 0.0.14 groups: - go - queries diff --git a/go/ql/lib/CHANGELOG.md b/go/ql/lib/CHANGELOG.md index fdfa26c8d4c0..de0b40c8648d 100644 --- a/go/ql/lib/CHANGELOG.md +++ b/go/ql/lib/CHANGELOG.md @@ -1,3 +1,14 @@ +## 0.8.0 + +### Breaking Changes + +* Deleted the deprecated `CsvRemoteSource` alias. Use `MaDRemoteSource` instead. + +### Deprecated APIs + +* To make Go consistent with other language libraries, the `UntrustedFlowSource` name has been deprecated throughout. Use `RemoteFlowSource` instead, which replaces it. +* Where modules have classes named `UntrustedFlowAsSource`, these are also deprecated and the `Source` class in the same module or the `RemoteFlowSource` class should be used instead. + ## 0.7.14 ### Minor Analysis Improvements diff --git a/go/ql/lib/change-notes/2024-04-26-outdated-deprecations.md b/go/ql/lib/change-notes/2024-04-26-outdated-deprecations.md deleted file mode 100644 index 2c7b522b792c..000000000000 --- a/go/ql/lib/change-notes/2024-04-26-outdated-deprecations.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: breaking ---- -* Deleted the deprecated `CsvRemoteSource` alias. Use `MaDRemoteSource` instead. \ No newline at end of file diff --git a/go/ql/lib/change-notes/2024-04-18-untrustedflowsource-renamed-remoteflowsource.md b/go/ql/lib/change-notes/released/0.8.0.md similarity index 72% rename from go/ql/lib/change-notes/2024-04-18-untrustedflowsource-renamed-remoteflowsource.md rename to go/ql/lib/change-notes/released/0.8.0.md index cb3edc34d848..829bdac7b08c 100644 --- a/go/ql/lib/change-notes/2024-04-18-untrustedflowsource-renamed-remoteflowsource.md +++ b/go/ql/lib/change-notes/released/0.8.0.md @@ -1,5 +1,10 @@ ---- -category: deprecated ---- +## 0.8.0 + +### Breaking Changes + +* Deleted the deprecated `CsvRemoteSource` alias. Use `MaDRemoteSource` instead. + +### Deprecated APIs + * To make Go consistent with other language libraries, the `UntrustedFlowSource` name has been deprecated throughout. Use `RemoteFlowSource` instead, which replaces it. * Where modules have classes named `UntrustedFlowAsSource`, these are also deprecated and the `Source` class in the same module or the `RemoteFlowSource` class should be used instead. diff --git a/go/ql/lib/codeql-pack.release.yml b/go/ql/lib/codeql-pack.release.yml index 2189dcea5188..37eab3197dcb 100644 --- a/go/ql/lib/codeql-pack.release.yml +++ b/go/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.7.14 +lastReleaseVersion: 0.8.0 diff --git a/go/ql/lib/qlpack.yml b/go/ql/lib/qlpack.yml index 9af680ede6f1..cbd4958f113a 100644 --- a/go/ql/lib/qlpack.yml +++ b/go/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-all -version: 0.7.15-dev +version: 0.8.0 groups: go dbscheme: go.dbscheme extractor: go diff --git a/go/ql/src/CHANGELOG.md b/go/ql/src/CHANGELOG.md index e5c2f9589d77..0364ec221d40 100644 --- a/go/ql/src/CHANGELOG.md +++ b/go/ql/src/CHANGELOG.md @@ -1,3 +1,10 @@ +## 0.7.15 + +### Minor Analysis Improvements + +* The query `go/incomplete-hostname-regexp` now recognizes more sources involving concatenation of string literals and also follows flow through string concatenation. This may lead to more alerts. +* Added some more barriers to flow for `go/incorrect-integer-conversion` to reduce false positives, especially around type switches. + ## 0.7.14 No user-facing changes. diff --git a/go/ql/src/change-notes/2024-04-17-incorrect-integer-conversion-barriers.md b/go/ql/src/change-notes/2024-04-17-incorrect-integer-conversion-barriers.md deleted file mode 100644 index 7453f2bef5c5..000000000000 --- a/go/ql/src/change-notes/2024-04-17-incorrect-integer-conversion-barriers.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Added some more barriers to flow for `go/incorrect-integer-conversion` to reduce false positives, especially around type switches. diff --git a/go/ql/src/change-notes/2024-04-24-incomplete-hostname-regexp.md b/go/ql/src/change-notes/released/0.7.15.md similarity index 52% rename from go/ql/src/change-notes/2024-04-24-incomplete-hostname-regexp.md rename to go/ql/src/change-notes/released/0.7.15.md index 3e7f0d593ec1..5672b61cc772 100644 --- a/go/ql/src/change-notes/2024-04-24-incomplete-hostname-regexp.md +++ b/go/ql/src/change-notes/released/0.7.15.md @@ -1,4 +1,6 @@ ---- -category: minorAnalysis ---- +## 0.7.15 + +### Minor Analysis Improvements + * The query `go/incomplete-hostname-regexp` now recognizes more sources involving concatenation of string literals and also follows flow through string concatenation. This may lead to more alerts. +* Added some more barriers to flow for `go/incorrect-integer-conversion` to reduce false positives, especially around type switches. diff --git a/go/ql/src/codeql-pack.release.yml b/go/ql/src/codeql-pack.release.yml index 2189dcea5188..e56b7f6a7b1d 100644 --- a/go/ql/src/codeql-pack.release.yml +++ b/go/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.7.14 +lastReleaseVersion: 0.7.15 diff --git a/go/ql/src/qlpack.yml b/go/ql/src/qlpack.yml index 63c52f6fb9fe..ae3f681f32fd 100644 --- a/go/ql/src/qlpack.yml +++ b/go/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-queries -version: 0.7.15-dev +version: 0.7.15 groups: - go - queries diff --git a/java/ql/automodel/src/CHANGELOG.md b/java/ql/automodel/src/CHANGELOG.md index 7b0018f30363..d8475687370d 100644 --- a/java/ql/automodel/src/CHANGELOG.md +++ b/java/ql/automodel/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.22 + +No user-facing changes. + ## 0.0.21 No user-facing changes. diff --git a/java/ql/automodel/src/change-notes/released/0.0.22.md b/java/ql/automodel/src/change-notes/released/0.0.22.md new file mode 100644 index 000000000000..002267474382 --- /dev/null +++ b/java/ql/automodel/src/change-notes/released/0.0.22.md @@ -0,0 +1,3 @@ +## 0.0.22 + +No user-facing changes. diff --git a/java/ql/automodel/src/codeql-pack.release.yml b/java/ql/automodel/src/codeql-pack.release.yml index 0c15c351db40..11aaa2243f57 100644 --- a/java/ql/automodel/src/codeql-pack.release.yml +++ b/java/ql/automodel/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.21 +lastReleaseVersion: 0.0.22 diff --git a/java/ql/automodel/src/qlpack.yml b/java/ql/automodel/src/qlpack.yml index 300f0cb5d0b5..8a8b37aef6f7 100644 --- a/java/ql/automodel/src/qlpack.yml +++ b/java/ql/automodel/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-automodel-queries -version: 0.0.22-dev +version: 0.0.22 groups: - java - automodel diff --git a/java/ql/lib/CHANGELOG.md b/java/ql/lib/CHANGELOG.md index 7c86037ae04c..4265865ea374 100644 --- a/java/ql/lib/CHANGELOG.md +++ b/java/ql/lib/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.10.0 + +### Breaking Changes + +* Deleted the deprecated `AssignLShiftExpr`, `AssignRShiftExpr`, `AssignURShiftExpr`, `LShiftExpr`, `RShiftExpr`, and `URShiftExpr` aliases. + ## 0.9.1 ### Minor Analysis Improvements diff --git a/java/ql/lib/change-notes/2024-04-26-outdated-deprecations.md b/java/ql/lib/change-notes/released/0.10.0.md similarity index 81% rename from java/ql/lib/change-notes/2024-04-26-outdated-deprecations.md rename to java/ql/lib/change-notes/released/0.10.0.md index fb245f821a82..e18998c07ec6 100644 --- a/java/ql/lib/change-notes/2024-04-26-outdated-deprecations.md +++ b/java/ql/lib/change-notes/released/0.10.0.md @@ -1,4 +1,5 @@ ---- -category: breaking ---- +## 0.10.0 + +### Breaking Changes + * Deleted the deprecated `AssignLShiftExpr`, `AssignRShiftExpr`, `AssignURShiftExpr`, `LShiftExpr`, `RShiftExpr`, and `URShiftExpr` aliases. diff --git a/java/ql/lib/codeql-pack.release.yml b/java/ql/lib/codeql-pack.release.yml index 6789dcd18b70..b21db6232459 100644 --- a/java/ql/lib/codeql-pack.release.yml +++ b/java/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.9.1 +lastReleaseVersion: 0.10.0 diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index 2a4bad9bc0f7..2f829aaeeb37 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-all -version: 0.9.2-dev +version: 0.10.0 groups: java dbscheme: config/semmlecode.dbscheme extractor: java diff --git a/java/ql/src/CHANGELOG.md b/java/ql/src/CHANGELOG.md index 00af3da16607..a242e40221e1 100644 --- a/java/ql/src/CHANGELOG.md +++ b/java/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.8.15 + +No user-facing changes. + ## 0.8.14 ### Minor Analysis Improvements diff --git a/java/ql/src/change-notes/released/0.8.15.md b/java/ql/src/change-notes/released/0.8.15.md new file mode 100644 index 000000000000..18c028b4ff00 --- /dev/null +++ b/java/ql/src/change-notes/released/0.8.15.md @@ -0,0 +1,3 @@ +## 0.8.15 + +No user-facing changes. diff --git a/java/ql/src/codeql-pack.release.yml b/java/ql/src/codeql-pack.release.yml index b36a2e248f34..2e3c183bb7a2 100644 --- a/java/ql/src/codeql-pack.release.yml +++ b/java/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.8.14 +lastReleaseVersion: 0.8.15 diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml index eb3b350c821d..b2225619f653 100644 --- a/java/ql/src/qlpack.yml +++ b/java/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-queries -version: 0.8.15-dev +version: 0.8.15 groups: - java - queries diff --git a/javascript/ql/lib/CHANGELOG.md b/javascript/ql/lib/CHANGELOG.md index 59c3204488d9..abe221bc6d25 100644 --- a/javascript/ql/lib/CHANGELOG.md +++ b/javascript/ql/lib/CHANGELOG.md @@ -1,3 +1,15 @@ +## 0.9.0 + +### Breaking Changes + +* Deleted the deprecated `getInput` predicate from the `CryptographicOperation` class. Use `getAnInput` instead. +* Deleted the deprecated `RegExpPatterns` module from `Regexp.qll`. +* Deleted the deprecated `semmle/javascript/security/BadTagFilterQuery.qll`, `semmle/javascript/security/OverlyLargeRangeQuery.qll`, `semmle/javascript/security/regexp/RegexpMatching.qll`, and `Security/CWE-020/HostnameRegexpShared.qll` files. + +### Minor Analysis Improvements + +* Improved detection of whether a file uses CommonJS module system. + ## 0.8.14 No user-facing changes. diff --git a/javascript/ql/lib/change-notes/2024-04-02-more-robust-commonjs-detection.md b/javascript/ql/lib/change-notes/2024-04-02-more-robust-commonjs-detection.md deleted file mode 100644 index 45c3879c39cc..000000000000 --- a/javascript/ql/lib/change-notes/2024-04-02-more-robust-commonjs-detection.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Improved detection of whether a file uses CommonJS module system. diff --git a/javascript/ql/lib/change-notes/2024-04-26-outdated-deprecations.md b/javascript/ql/lib/change-notes/released/0.9.0.md similarity index 66% rename from javascript/ql/lib/change-notes/2024-04-26-outdated-deprecations.md rename to javascript/ql/lib/change-notes/released/0.9.0.md index 59a90e91ec86..d76d2e4d1226 100644 --- a/javascript/ql/lib/change-notes/2024-04-26-outdated-deprecations.md +++ b/javascript/ql/lib/change-notes/released/0.9.0.md @@ -1,6 +1,11 @@ ---- -category: breaking ---- +## 0.9.0 + +### Breaking Changes + * Deleted the deprecated `getInput` predicate from the `CryptographicOperation` class. Use `getAnInput` instead. * Deleted the deprecated `RegExpPatterns` module from `Regexp.qll`. -* Deleted the deprecated `semmle/javascript/security/BadTagFilterQuery.qll`, `semmle/javascript/security/OverlyLargeRangeQuery.qll`, `semmle/javascript/security/regexp/RegexpMatching.qll`, and `Security/CWE-020/HostnameRegexpShared.qll` files. \ No newline at end of file +* Deleted the deprecated `semmle/javascript/security/BadTagFilterQuery.qll`, `semmle/javascript/security/OverlyLargeRangeQuery.qll`, `semmle/javascript/security/regexp/RegexpMatching.qll`, and `Security/CWE-020/HostnameRegexpShared.qll` files. + +### Minor Analysis Improvements + +* Improved detection of whether a file uses CommonJS module system. diff --git a/javascript/ql/lib/codeql-pack.release.yml b/javascript/ql/lib/codeql-pack.release.yml index b36a2e248f34..8b9fc185202d 100644 --- a/javascript/ql/lib/codeql-pack.release.yml +++ b/javascript/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.8.14 +lastReleaseVersion: 0.9.0 diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index 700b48d33202..6a1a8db3c216 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-all -version: 0.8.15-dev +version: 0.9.0 groups: javascript dbscheme: semmlecode.javascript.dbscheme extractor: javascript diff --git a/javascript/ql/src/CHANGELOG.md b/javascript/ql/src/CHANGELOG.md index 51c2e97d9eac..7499f8b36698 100644 --- a/javascript/ql/src/CHANGELOG.md +++ b/javascript/ql/src/CHANGELOG.md @@ -1,3 +1,12 @@ +## 0.8.15 + +### Minor Analysis Improvements + +* The JavaScript extractor will on longer report syntax errors related to "strict mode". + Files containing such errors are now being fully analyzed along with other sources files. + This improves our support for source files that technically break the "strict mode" rules, + but where a build steps transforms the code such that it ends up working at runtime. + ## 0.8.14 ### Minor Analysis Improvements diff --git a/javascript/ql/src/change-notes/2024-04-17-strict-mode.md b/javascript/ql/src/change-notes/released/0.8.15.md similarity index 89% rename from javascript/ql/src/change-notes/2024-04-17-strict-mode.md rename to javascript/ql/src/change-notes/released/0.8.15.md index 65dd10d45eb3..43526f8e132a 100644 --- a/javascript/ql/src/change-notes/2024-04-17-strict-mode.md +++ b/javascript/ql/src/change-notes/released/0.8.15.md @@ -1,6 +1,7 @@ ---- -category: minorAnalysis ---- +## 0.8.15 + +### Minor Analysis Improvements + * The JavaScript extractor will on longer report syntax errors related to "strict mode". Files containing such errors are now being fully analyzed along with other sources files. This improves our support for source files that technically break the "strict mode" rules, diff --git a/javascript/ql/src/codeql-pack.release.yml b/javascript/ql/src/codeql-pack.release.yml index b36a2e248f34..2e3c183bb7a2 100644 --- a/javascript/ql/src/codeql-pack.release.yml +++ b/javascript/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.8.14 +lastReleaseVersion: 0.8.15 diff --git a/javascript/ql/src/qlpack.yml b/javascript/ql/src/qlpack.yml index d67a8f387d81..765436be44f8 100644 --- a/javascript/ql/src/qlpack.yml +++ b/javascript/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-queries -version: 0.8.15-dev +version: 0.8.15 groups: - javascript - queries diff --git a/misc/suite-helpers/CHANGELOG.md b/misc/suite-helpers/CHANGELOG.md index ddf1cfabc849..e97a0b0fe5f2 100644 --- a/misc/suite-helpers/CHANGELOG.md +++ b/misc/suite-helpers/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.7.15 + +No user-facing changes. + ## 0.7.14 No user-facing changes. diff --git a/misc/suite-helpers/change-notes/released/0.7.15.md b/misc/suite-helpers/change-notes/released/0.7.15.md new file mode 100644 index 000000000000..8d772280c75e --- /dev/null +++ b/misc/suite-helpers/change-notes/released/0.7.15.md @@ -0,0 +1,3 @@ +## 0.7.15 + +No user-facing changes. diff --git a/misc/suite-helpers/codeql-pack.release.yml b/misc/suite-helpers/codeql-pack.release.yml index 2189dcea5188..e56b7f6a7b1d 100644 --- a/misc/suite-helpers/codeql-pack.release.yml +++ b/misc/suite-helpers/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.7.14 +lastReleaseVersion: 0.7.15 diff --git a/misc/suite-helpers/qlpack.yml b/misc/suite-helpers/qlpack.yml index 4aa5c302aa8a..f711a5b95cc9 100644 --- a/misc/suite-helpers/qlpack.yml +++ b/misc/suite-helpers/qlpack.yml @@ -1,4 +1,4 @@ name: codeql/suite-helpers -version: 0.7.15-dev +version: 0.7.15 groups: shared warnOnImplicitThis: true diff --git a/python/ql/lib/CHANGELOG.md b/python/ql/lib/CHANGELOG.md index c55b68e36846..3ca353c75060 100644 --- a/python/ql/lib/CHANGELOG.md +++ b/python/ql/lib/CHANGELOG.md @@ -1,3 +1,14 @@ +## 0.12.0 + +### Breaking Changes + +* Deleted the deprecated `RegExpPatterns` module from `Regexp.qll`. +* Deleted the deprecated `Security/CWE-020/HostnameRegexpShared.qll` file. + +### Deprecated APIs + +- Renamed the `StrConst` class to `StringLiteral`, for greater consistency with other languages. The `StrConst` and `Str` classes are now deprecated and will be removed in a future release. + ## 0.11.14 ### Minor Analysis Improvements diff --git a/python/ql/lib/change-notes/2024-04-22-renaming-StrConst-to-StringLiteral.md b/python/ql/lib/change-notes/2024-04-22-renaming-StrConst-to-StringLiteral.md deleted file mode 100644 index 958262dda2bf..000000000000 --- a/python/ql/lib/change-notes/2024-04-22-renaming-StrConst-to-StringLiteral.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -category: deprecated ---- - -- Renamed the `StrConst` class to `StringLiteral`, for greater consistency with other languages. The `StrConst` and `Str` classes are now deprecated and will be removed in a future release. diff --git a/python/ql/lib/change-notes/2024-04-26-outdated-deprecations.md b/python/ql/lib/change-notes/2024-04-26-outdated-deprecations.md deleted file mode 100644 index db64f0a98312..000000000000 --- a/python/ql/lib/change-notes/2024-04-26-outdated-deprecations.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -category: breaking ---- -* Deleted the deprecated `RegExpPatterns` module from `Regexp.qll`. -* Deleted the deprecated `Security/CWE-020/HostnameRegexpShared.qll` file. \ No newline at end of file diff --git a/python/ql/lib/change-notes/released/0.12.0.md b/python/ql/lib/change-notes/released/0.12.0.md new file mode 100644 index 000000000000..2f122ac3bcc4 --- /dev/null +++ b/python/ql/lib/change-notes/released/0.12.0.md @@ -0,0 +1,10 @@ +## 0.12.0 + +### Breaking Changes + +* Deleted the deprecated `RegExpPatterns` module from `Regexp.qll`. +* Deleted the deprecated `Security/CWE-020/HostnameRegexpShared.qll` file. + +### Deprecated APIs + +- Renamed the `StrConst` class to `StringLiteral`, for greater consistency with other languages. The `StrConst` and `Str` classes are now deprecated and will be removed in a future release. diff --git a/python/ql/lib/codeql-pack.release.yml b/python/ql/lib/codeql-pack.release.yml index 63d619be9acb..5e2fb32b0597 100644 --- a/python/ql/lib/codeql-pack.release.yml +++ b/python/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.11.14 +lastReleaseVersion: 0.12.0 diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml index c038958349ed..da26320c692d 100644 --- a/python/ql/lib/qlpack.yml +++ b/python/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-all -version: 0.11.15-dev +version: 0.12.0 groups: python dbscheme: semmlecode.python.dbscheme extractor: python diff --git a/python/ql/src/CHANGELOG.md b/python/ql/src/CHANGELOG.md index ef271f0654d0..96a2c3cc7dba 100644 --- a/python/ql/src/CHANGELOG.md +++ b/python/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.9.15 + +No user-facing changes. + ## 0.9.14 No user-facing changes. diff --git a/python/ql/src/change-notes/released/0.9.15.md b/python/ql/src/change-notes/released/0.9.15.md new file mode 100644 index 000000000000..95252948c0d4 --- /dev/null +++ b/python/ql/src/change-notes/released/0.9.15.md @@ -0,0 +1,3 @@ +## 0.9.15 + +No user-facing changes. diff --git a/python/ql/src/codeql-pack.release.yml b/python/ql/src/codeql-pack.release.yml index e4e3bab02833..4896915c2157 100644 --- a/python/ql/src/codeql-pack.release.yml +++ b/python/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.9.14 +lastReleaseVersion: 0.9.15 diff --git a/python/ql/src/qlpack.yml b/python/ql/src/qlpack.yml index ce6edd4ef709..cbb24537e518 100644 --- a/python/ql/src/qlpack.yml +++ b/python/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-queries -version: 0.9.15-dev +version: 0.9.15 groups: - python - queries diff --git a/ruby/ql/lib/CHANGELOG.md b/ruby/ql/lib/CHANGELOG.md index 1c87f55596f2..685e9b24bd5b 100644 --- a/ruby/ql/lib/CHANGELOG.md +++ b/ruby/ql/lib/CHANGELOG.md @@ -1,3 +1,10 @@ +## 0.9.0 + +### Breaking Changes + +* Deleted the deprecated `RegExpPatterns` module from `Regexp.qll`. +* Deleted the deprecated `security/cwe-020/HostnameRegexpShared.qll` file. + ## 0.8.14 No user-facing changes. diff --git a/ruby/ql/lib/change-notes/2024-04-26-outdated-deprecations.md b/ruby/ql/lib/change-notes/released/0.9.0.md similarity index 75% rename from ruby/ql/lib/change-notes/2024-04-26-outdated-deprecations.md rename to ruby/ql/lib/change-notes/released/0.9.0.md index 76cc93df2aaa..534e3ad77234 100644 --- a/ruby/ql/lib/change-notes/2024-04-26-outdated-deprecations.md +++ b/ruby/ql/lib/change-notes/released/0.9.0.md @@ -1,5 +1,6 @@ ---- -category: breaking ---- +## 0.9.0 + +### Breaking Changes + * Deleted the deprecated `RegExpPatterns` module from `Regexp.qll`. -* Deleted the deprecated `security/cwe-020/HostnameRegexpShared.qll` file. \ No newline at end of file +* Deleted the deprecated `security/cwe-020/HostnameRegexpShared.qll` file. diff --git a/ruby/ql/lib/codeql-pack.release.yml b/ruby/ql/lib/codeql-pack.release.yml index b36a2e248f34..8b9fc185202d 100644 --- a/ruby/ql/lib/codeql-pack.release.yml +++ b/ruby/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.8.14 +lastReleaseVersion: 0.9.0 diff --git a/ruby/ql/lib/qlpack.yml b/ruby/ql/lib/qlpack.yml index e14d47178a83..4025867e348e 100644 --- a/ruby/ql/lib/qlpack.yml +++ b/ruby/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-all -version: 0.8.15-dev +version: 0.9.0 groups: ruby extractor: ruby dbscheme: ruby.dbscheme diff --git a/ruby/ql/src/CHANGELOG.md b/ruby/ql/src/CHANGELOG.md index a95ee7ee1ffb..317d8cf367f9 100644 --- a/ruby/ql/src/CHANGELOG.md +++ b/ruby/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.8.15 + +No user-facing changes. + ## 0.8.14 ### New Queries diff --git a/ruby/ql/src/change-notes/released/0.8.15.md b/ruby/ql/src/change-notes/released/0.8.15.md new file mode 100644 index 000000000000..18c028b4ff00 --- /dev/null +++ b/ruby/ql/src/change-notes/released/0.8.15.md @@ -0,0 +1,3 @@ +## 0.8.15 + +No user-facing changes. diff --git a/ruby/ql/src/codeql-pack.release.yml b/ruby/ql/src/codeql-pack.release.yml index b36a2e248f34..2e3c183bb7a2 100644 --- a/ruby/ql/src/codeql-pack.release.yml +++ b/ruby/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.8.14 +lastReleaseVersion: 0.8.15 diff --git a/ruby/ql/src/qlpack.yml b/ruby/ql/src/qlpack.yml index 4ea0c217f092..e0b73d2f8d5f 100644 --- a/ruby/ql/src/qlpack.yml +++ b/ruby/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-queries -version: 0.8.15-dev +version: 0.8.15 groups: - ruby - queries diff --git a/shared/controlflow/CHANGELOG.md b/shared/controlflow/CHANGELOG.md index b2cc0c1080dc..7e1a517c4a95 100644 --- a/shared/controlflow/CHANGELOG.md +++ b/shared/controlflow/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.15 + +No user-facing changes. + ## 0.1.14 No user-facing changes. diff --git a/shared/controlflow/change-notes/released/0.1.15.md b/shared/controlflow/change-notes/released/0.1.15.md new file mode 100644 index 000000000000..ce8f7b7f0149 --- /dev/null +++ b/shared/controlflow/change-notes/released/0.1.15.md @@ -0,0 +1,3 @@ +## 0.1.15 + +No user-facing changes. diff --git a/shared/controlflow/codeql-pack.release.yml b/shared/controlflow/codeql-pack.release.yml index 76f7b27fb4e4..747196347438 100644 --- a/shared/controlflow/codeql-pack.release.yml +++ b/shared/controlflow/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.1.14 +lastReleaseVersion: 0.1.15 diff --git a/shared/controlflow/qlpack.yml b/shared/controlflow/qlpack.yml index f1f79c6d9396..7fceca57d01a 100644 --- a/shared/controlflow/qlpack.yml +++ b/shared/controlflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/controlflow -version: 0.1.15-dev +version: 0.1.15 groups: shared library: true dependencies: diff --git a/shared/dataflow/CHANGELOG.md b/shared/dataflow/CHANGELOG.md index 22bec6239eb4..180ffb852071 100644 --- a/shared/dataflow/CHANGELOG.md +++ b/shared/dataflow/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.2.6 + +### Major Analysis Improvements + +* The data flow library performs heuristic filtering of code paths that have a high degree of control-flow uncertainty for improved performance in cases that are deemed unlikely to yield true positive flow paths. This filtering can be controlled with the `fieldFlowBranchLimit` predicate in configurations. Two bugs have been fixed in relation to this: Some cases of high uncertainty were not being correctly identified. This fix improves performance in certain scenarios. Another group of cases of low uncertainty were also being misidentified, which led to false negatives. Taken together, we generally expect some additional query results with more true positives and fewer false positives. + ## 0.2.5 ### New Features diff --git a/shared/dataflow/change-notes/2024-04-19-fieldflowbranchlimit.md b/shared/dataflow/change-notes/released/0.2.6.md similarity index 94% rename from shared/dataflow/change-notes/2024-04-19-fieldflowbranchlimit.md rename to shared/dataflow/change-notes/released/0.2.6.md index 887d17f28664..d928a91c5b62 100644 --- a/shared/dataflow/change-notes/2024-04-19-fieldflowbranchlimit.md +++ b/shared/dataflow/change-notes/released/0.2.6.md @@ -1,4 +1,5 @@ ---- -category: majorAnalysis ---- +## 0.2.6 + +### Major Analysis Improvements + * The data flow library performs heuristic filtering of code paths that have a high degree of control-flow uncertainty for improved performance in cases that are deemed unlikely to yield true positive flow paths. This filtering can be controlled with the `fieldFlowBranchLimit` predicate in configurations. Two bugs have been fixed in relation to this: Some cases of high uncertainty were not being correctly identified. This fix improves performance in certain scenarios. Another group of cases of low uncertainty were also being misidentified, which led to false negatives. Taken together, we generally expect some additional query results with more true positives and fewer false positives. diff --git a/shared/dataflow/codeql-pack.release.yml b/shared/dataflow/codeql-pack.release.yml index 211454ed3064..248dd0f4594b 100644 --- a/shared/dataflow/codeql-pack.release.yml +++ b/shared/dataflow/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.2.5 +lastReleaseVersion: 0.2.6 diff --git a/shared/dataflow/qlpack.yml b/shared/dataflow/qlpack.yml index 028aadc50917..05692d1b152b 100644 --- a/shared/dataflow/qlpack.yml +++ b/shared/dataflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/dataflow -version: 0.2.6-dev +version: 0.2.6 groups: shared library: true dependencies: diff --git a/shared/mad/CHANGELOG.md b/shared/mad/CHANGELOG.md index 70e6a3e254c6..6f1322a26ffb 100644 --- a/shared/mad/CHANGELOG.md +++ b/shared/mad/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.15 + +No user-facing changes. + ## 0.2.14 No user-facing changes. diff --git a/shared/mad/change-notes/released/0.2.15.md b/shared/mad/change-notes/released/0.2.15.md new file mode 100644 index 000000000000..89e215669cd8 --- /dev/null +++ b/shared/mad/change-notes/released/0.2.15.md @@ -0,0 +1,3 @@ +## 0.2.15 + +No user-facing changes. diff --git a/shared/mad/codeql-pack.release.yml b/shared/mad/codeql-pack.release.yml index c53820a76d54..0f574e080e4c 100644 --- a/shared/mad/codeql-pack.release.yml +++ b/shared/mad/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.2.14 +lastReleaseVersion: 0.2.15 diff --git a/shared/mad/qlpack.yml b/shared/mad/qlpack.yml index 2da72ddffac3..c60b7b1326fe 100644 --- a/shared/mad/qlpack.yml +++ b/shared/mad/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/mad -version: 0.2.15-dev +version: 0.2.15 groups: shared library: true dependencies: diff --git a/shared/rangeanalysis/CHANGELOG.md b/shared/rangeanalysis/CHANGELOG.md index cc3ed2692e73..0c0ae0d04f66 100644 --- a/shared/rangeanalysis/CHANGELOG.md +++ b/shared/rangeanalysis/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.14 + +No user-facing changes. + ## 0.0.13 No user-facing changes. diff --git a/shared/rangeanalysis/change-notes/released/0.0.14.md b/shared/rangeanalysis/change-notes/released/0.0.14.md new file mode 100644 index 000000000000..63b4d50ca454 --- /dev/null +++ b/shared/rangeanalysis/change-notes/released/0.0.14.md @@ -0,0 +1,3 @@ +## 0.0.14 + +No user-facing changes. diff --git a/shared/rangeanalysis/codeql-pack.release.yml b/shared/rangeanalysis/codeql-pack.release.yml index 044e54e4f7e5..ca29e45d0a67 100644 --- a/shared/rangeanalysis/codeql-pack.release.yml +++ b/shared/rangeanalysis/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.13 +lastReleaseVersion: 0.0.14 diff --git a/shared/rangeanalysis/qlpack.yml b/shared/rangeanalysis/qlpack.yml index 11e6ae0c5f84..cd1b6c4d432d 100644 --- a/shared/rangeanalysis/qlpack.yml +++ b/shared/rangeanalysis/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/rangeanalysis -version: 0.0.14-dev +version: 0.0.14 groups: shared library: true dependencies: diff --git a/shared/regex/CHANGELOG.md b/shared/regex/CHANGELOG.md index 23e63b6a8b6d..a974d3bb9a16 100644 --- a/shared/regex/CHANGELOG.md +++ b/shared/regex/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.15 + +No user-facing changes. + ## 0.2.14 No user-facing changes. diff --git a/shared/regex/change-notes/released/0.2.15.md b/shared/regex/change-notes/released/0.2.15.md new file mode 100644 index 000000000000..89e215669cd8 --- /dev/null +++ b/shared/regex/change-notes/released/0.2.15.md @@ -0,0 +1,3 @@ +## 0.2.15 + +No user-facing changes. diff --git a/shared/regex/codeql-pack.release.yml b/shared/regex/codeql-pack.release.yml index c53820a76d54..0f574e080e4c 100644 --- a/shared/regex/codeql-pack.release.yml +++ b/shared/regex/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.2.14 +lastReleaseVersion: 0.2.15 diff --git a/shared/regex/qlpack.yml b/shared/regex/qlpack.yml index 8ca0e7569341..15813ea4760d 100644 --- a/shared/regex/qlpack.yml +++ b/shared/regex/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/regex -version: 0.2.15-dev +version: 0.2.15 groups: shared library: true dependencies: diff --git a/shared/ssa/CHANGELOG.md b/shared/ssa/CHANGELOG.md index 10af5c066847..2126603d56ae 100644 --- a/shared/ssa/CHANGELOG.md +++ b/shared/ssa/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.15 + +No user-facing changes. + ## 0.2.14 No user-facing changes. diff --git a/shared/ssa/change-notes/released/0.2.15.md b/shared/ssa/change-notes/released/0.2.15.md new file mode 100644 index 000000000000..89e215669cd8 --- /dev/null +++ b/shared/ssa/change-notes/released/0.2.15.md @@ -0,0 +1,3 @@ +## 0.2.15 + +No user-facing changes. diff --git a/shared/ssa/codeql-pack.release.yml b/shared/ssa/codeql-pack.release.yml index c53820a76d54..0f574e080e4c 100644 --- a/shared/ssa/codeql-pack.release.yml +++ b/shared/ssa/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.2.14 +lastReleaseVersion: 0.2.15 diff --git a/shared/ssa/qlpack.yml b/shared/ssa/qlpack.yml index 7a7752cabcdb..746d89a8e992 100644 --- a/shared/ssa/qlpack.yml +++ b/shared/ssa/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ssa -version: 0.2.15-dev +version: 0.2.15 groups: shared library: true dependencies: diff --git a/shared/threat-models/CHANGELOG.md b/shared/threat-models/CHANGELOG.md index 29ece641a7e3..ad4781e2cbda 100644 --- a/shared/threat-models/CHANGELOG.md +++ b/shared/threat-models/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.14 + +No user-facing changes. + ## 0.0.13 No user-facing changes. diff --git a/shared/threat-models/change-notes/released/0.0.14.md b/shared/threat-models/change-notes/released/0.0.14.md new file mode 100644 index 000000000000..63b4d50ca454 --- /dev/null +++ b/shared/threat-models/change-notes/released/0.0.14.md @@ -0,0 +1,3 @@ +## 0.0.14 + +No user-facing changes. diff --git a/shared/threat-models/codeql-pack.release.yml b/shared/threat-models/codeql-pack.release.yml index 044e54e4f7e5..ca29e45d0a67 100644 --- a/shared/threat-models/codeql-pack.release.yml +++ b/shared/threat-models/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.13 +lastReleaseVersion: 0.0.14 diff --git a/shared/threat-models/qlpack.yml b/shared/threat-models/qlpack.yml index 4c4a19afafd9..ac44b807cde0 100644 --- a/shared/threat-models/qlpack.yml +++ b/shared/threat-models/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/threat-models -version: 0.0.14-dev +version: 0.0.14 library: true groups: shared dataExtensions: diff --git a/shared/tutorial/CHANGELOG.md b/shared/tutorial/CHANGELOG.md index ed8307d3c525..953f7f46f4ea 100644 --- a/shared/tutorial/CHANGELOG.md +++ b/shared/tutorial/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.15 + +No user-facing changes. + ## 0.2.14 No user-facing changes. diff --git a/shared/tutorial/change-notes/released/0.2.15.md b/shared/tutorial/change-notes/released/0.2.15.md new file mode 100644 index 000000000000..89e215669cd8 --- /dev/null +++ b/shared/tutorial/change-notes/released/0.2.15.md @@ -0,0 +1,3 @@ +## 0.2.15 + +No user-facing changes. diff --git a/shared/tutorial/codeql-pack.release.yml b/shared/tutorial/codeql-pack.release.yml index c53820a76d54..0f574e080e4c 100644 --- a/shared/tutorial/codeql-pack.release.yml +++ b/shared/tutorial/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.2.14 +lastReleaseVersion: 0.2.15 diff --git a/shared/tutorial/qlpack.yml b/shared/tutorial/qlpack.yml index 7b8488aacf13..37dc21a6e3a0 100644 --- a/shared/tutorial/qlpack.yml +++ b/shared/tutorial/qlpack.yml @@ -1,7 +1,7 @@ name: codeql/tutorial description: Library for the CodeQL detective tutorials, helping new users learn to write CodeQL queries. -version: 0.2.15-dev +version: 0.2.15 groups: shared library: true warnOnImplicitThis: true diff --git a/shared/typeflow/CHANGELOG.md b/shared/typeflow/CHANGELOG.md index 01b03981cd49..ac82f761c1d9 100644 --- a/shared/typeflow/CHANGELOG.md +++ b/shared/typeflow/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.2 + +No user-facing changes. + ## 0.0.1 ### New Features diff --git a/shared/typeflow/change-notes/released/0.0.2.md b/shared/typeflow/change-notes/released/0.0.2.md new file mode 100644 index 000000000000..5ab250998ed4 --- /dev/null +++ b/shared/typeflow/change-notes/released/0.0.2.md @@ -0,0 +1,3 @@ +## 0.0.2 + +No user-facing changes. diff --git a/shared/typeflow/codeql-pack.release.yml b/shared/typeflow/codeql-pack.release.yml index c6933410b71c..55dc06fbd76a 100644 --- a/shared/typeflow/codeql-pack.release.yml +++ b/shared/typeflow/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.1 +lastReleaseVersion: 0.0.2 diff --git a/shared/typeflow/qlpack.yml b/shared/typeflow/qlpack.yml index b0a2bf9a7484..10024358df5c 100644 --- a/shared/typeflow/qlpack.yml +++ b/shared/typeflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typeflow -version: 0.0.2-dev +version: 0.0.2 groups: shared library: true dependencies: diff --git a/shared/typetracking/CHANGELOG.md b/shared/typetracking/CHANGELOG.md index c259d339ee6b..57b0a29dd6c4 100644 --- a/shared/typetracking/CHANGELOG.md +++ b/shared/typetracking/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.15 + +No user-facing changes. + ## 0.2.14 No user-facing changes. diff --git a/shared/typetracking/change-notes/released/0.2.15.md b/shared/typetracking/change-notes/released/0.2.15.md new file mode 100644 index 000000000000..89e215669cd8 --- /dev/null +++ b/shared/typetracking/change-notes/released/0.2.15.md @@ -0,0 +1,3 @@ +## 0.2.15 + +No user-facing changes. diff --git a/shared/typetracking/codeql-pack.release.yml b/shared/typetracking/codeql-pack.release.yml index c53820a76d54..0f574e080e4c 100644 --- a/shared/typetracking/codeql-pack.release.yml +++ b/shared/typetracking/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.2.14 +lastReleaseVersion: 0.2.15 diff --git a/shared/typetracking/qlpack.yml b/shared/typetracking/qlpack.yml index 4317864eb39b..ee57425e254a 100644 --- a/shared/typetracking/qlpack.yml +++ b/shared/typetracking/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typetracking -version: 0.2.15-dev +version: 0.2.15 groups: shared library: true dependencies: diff --git a/shared/typos/CHANGELOG.md b/shared/typos/CHANGELOG.md index 8f6f77b20d06..335d25587375 100644 --- a/shared/typos/CHANGELOG.md +++ b/shared/typos/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.15 + +No user-facing changes. + ## 0.2.14 No user-facing changes. diff --git a/shared/typos/change-notes/released/0.2.15.md b/shared/typos/change-notes/released/0.2.15.md new file mode 100644 index 000000000000..89e215669cd8 --- /dev/null +++ b/shared/typos/change-notes/released/0.2.15.md @@ -0,0 +1,3 @@ +## 0.2.15 + +No user-facing changes. diff --git a/shared/typos/codeql-pack.release.yml b/shared/typos/codeql-pack.release.yml index c53820a76d54..0f574e080e4c 100644 --- a/shared/typos/codeql-pack.release.yml +++ b/shared/typos/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.2.14 +lastReleaseVersion: 0.2.15 diff --git a/shared/typos/qlpack.yml b/shared/typos/qlpack.yml index a0d2e5036c9f..cd620389331e 100644 --- a/shared/typos/qlpack.yml +++ b/shared/typos/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typos -version: 0.2.15-dev +version: 0.2.15 groups: shared library: true warnOnImplicitThis: true diff --git a/shared/util/CHANGELOG.md b/shared/util/CHANGELOG.md index b7d7602c5a9a..e583745ef4a8 100644 --- a/shared/util/CHANGELOG.md +++ b/shared/util/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.15 + +No user-facing changes. + ## 0.2.14 No user-facing changes. diff --git a/shared/util/change-notes/released/0.2.15.md b/shared/util/change-notes/released/0.2.15.md new file mode 100644 index 000000000000..89e215669cd8 --- /dev/null +++ b/shared/util/change-notes/released/0.2.15.md @@ -0,0 +1,3 @@ +## 0.2.15 + +No user-facing changes. diff --git a/shared/util/codeql-pack.release.yml b/shared/util/codeql-pack.release.yml index c53820a76d54..0f574e080e4c 100644 --- a/shared/util/codeql-pack.release.yml +++ b/shared/util/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.2.14 +lastReleaseVersion: 0.2.15 diff --git a/shared/util/qlpack.yml b/shared/util/qlpack.yml index 13114a094664..dafa542bf2ca 100644 --- a/shared/util/qlpack.yml +++ b/shared/util/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/util -version: 0.2.15-dev +version: 0.2.15 groups: shared library: true dependencies: null diff --git a/shared/xml/CHANGELOG.md b/shared/xml/CHANGELOG.md index 59b60bad0f37..7668a5ba39d5 100644 --- a/shared/xml/CHANGELOG.md +++ b/shared/xml/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.2 + +No user-facing changes. + ## 0.0.1 No user-facing changes. diff --git a/shared/xml/change-notes/released/0.0.2.md b/shared/xml/change-notes/released/0.0.2.md new file mode 100644 index 000000000000..5ab250998ed4 --- /dev/null +++ b/shared/xml/change-notes/released/0.0.2.md @@ -0,0 +1,3 @@ +## 0.0.2 + +No user-facing changes. diff --git a/shared/xml/codeql-pack.release.yml b/shared/xml/codeql-pack.release.yml index c6933410b71c..55dc06fbd76a 100644 --- a/shared/xml/codeql-pack.release.yml +++ b/shared/xml/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.1 +lastReleaseVersion: 0.0.2 diff --git a/shared/xml/qlpack.yml b/shared/xml/qlpack.yml index aac15f40851b..8c04aa720c78 100644 --- a/shared/xml/qlpack.yml +++ b/shared/xml/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/xml -version: 0.0.2-dev +version: 0.0.2 groups: shared library: true dependencies: diff --git a/shared/yaml/CHANGELOG.md b/shared/yaml/CHANGELOG.md index 379fbd1bee3a..c2982987f8a2 100644 --- a/shared/yaml/CHANGELOG.md +++ b/shared/yaml/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.15 + +No user-facing changes. + ## 0.2.14 No user-facing changes. diff --git a/shared/yaml/change-notes/released/0.2.15.md b/shared/yaml/change-notes/released/0.2.15.md new file mode 100644 index 000000000000..89e215669cd8 --- /dev/null +++ b/shared/yaml/change-notes/released/0.2.15.md @@ -0,0 +1,3 @@ +## 0.2.15 + +No user-facing changes. diff --git a/shared/yaml/codeql-pack.release.yml b/shared/yaml/codeql-pack.release.yml index c53820a76d54..0f574e080e4c 100644 --- a/shared/yaml/codeql-pack.release.yml +++ b/shared/yaml/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.2.14 +lastReleaseVersion: 0.2.15 diff --git a/shared/yaml/qlpack.yml b/shared/yaml/qlpack.yml index b1b9e5e13523..b0428c4d3868 100644 --- a/shared/yaml/qlpack.yml +++ b/shared/yaml/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/yaml -version: 0.2.15-dev +version: 0.2.15 groups: shared library: true warnOnImplicitThis: true diff --git a/swift/ql/lib/CHANGELOG.md b/swift/ql/lib/CHANGELOG.md index 565902398bdb..48bd64147649 100644 --- a/swift/ql/lib/CHANGELOG.md +++ b/swift/ql/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.15 + +No user-facing changes. + ## 0.3.14 No user-facing changes. diff --git a/swift/ql/lib/change-notes/released/0.3.15.md b/swift/ql/lib/change-notes/released/0.3.15.md new file mode 100644 index 000000000000..11fa7599e324 --- /dev/null +++ b/swift/ql/lib/change-notes/released/0.3.15.md @@ -0,0 +1,3 @@ +## 0.3.15 + +No user-facing changes. diff --git a/swift/ql/lib/codeql-pack.release.yml b/swift/ql/lib/codeql-pack.release.yml index 1ff0ab05e829..469af066c19c 100644 --- a/swift/ql/lib/codeql-pack.release.yml +++ b/swift/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.3.14 +lastReleaseVersion: 0.3.15 diff --git a/swift/ql/lib/qlpack.yml b/swift/ql/lib/qlpack.yml index 3c6c268ced85..435d074a0808 100644 --- a/swift/ql/lib/qlpack.yml +++ b/swift/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-all -version: 0.3.15-dev +version: 0.3.15 groups: swift extractor: swift dbscheme: swift.dbscheme diff --git a/swift/ql/src/CHANGELOG.md b/swift/ql/src/CHANGELOG.md index 05ea3aed885b..c780f5cd2860 100644 --- a/swift/ql/src/CHANGELOG.md +++ b/swift/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.15 + +No user-facing changes. + ## 0.3.14 No user-facing changes. diff --git a/swift/ql/src/change-notes/released/0.3.15.md b/swift/ql/src/change-notes/released/0.3.15.md new file mode 100644 index 000000000000..11fa7599e324 --- /dev/null +++ b/swift/ql/src/change-notes/released/0.3.15.md @@ -0,0 +1,3 @@ +## 0.3.15 + +No user-facing changes. diff --git a/swift/ql/src/codeql-pack.release.yml b/swift/ql/src/codeql-pack.release.yml index 1ff0ab05e829..469af066c19c 100644 --- a/swift/ql/src/codeql-pack.release.yml +++ b/swift/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.3.14 +lastReleaseVersion: 0.3.15 diff --git a/swift/ql/src/qlpack.yml b/swift/ql/src/qlpack.yml index 735197aa4270..923eb4adb6c2 100644 --- a/swift/ql/src/qlpack.yml +++ b/swift/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-queries -version: 0.3.15-dev +version: 0.3.15 groups: - swift - queries From 806d42852ca671c8804058045b84c42969bad98d Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 30 Apr 2024 11:33:22 +0100 Subject: [PATCH 122/238] C++: Add test in C file with pointer type guard. --- .../library-tests/controlflow/guards/Guards.expected | 3 +++ .../controlflow/guards/GuardsControl.expected | 3 +++ cpp/ql/test/library-tests/controlflow/guards/test.c | 12 ++++++++++++ 3 files changed, 18 insertions(+) diff --git a/cpp/ql/test/library-tests/controlflow/guards/Guards.expected b/cpp/ql/test/library-tests/controlflow/guards/Guards.expected index 08a8a9281bb1..8ee1b1af7d45 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/Guards.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/Guards.expected @@ -26,6 +26,9 @@ | test.c:137:7:137:7 | 0 | | test.c:146:7:146:8 | ! ... | | test.c:146:8:146:8 | x | +| test.c:152:8:152:8 | p | +| test.c:158:8:158:9 | ! ... | +| test.c:158:9:158:9 | p | | test.cpp:18:8:18:10 | call to get | | test.cpp:31:7:31:13 | ... == ... | | test.cpp:42:13:42:20 | call to getABool | diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected b/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected index 62d9b0a12294..5c024bebc629 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected @@ -79,6 +79,9 @@ | test.c:137:7:137:7 | 0 | false | 142 | 136 | | test.c:146:7:146:8 | ! ... | true | 146 | 147 | | test.c:146:8:146:8 | x | false | 146 | 147 | +| test.c:152:8:152:8 | p | true | 152 | 154 | +| test.c:158:8:158:9 | ! ... | true | 158 | 160 | +| test.c:158:9:158:9 | p | false | 158 | 160 | | test.cpp:18:8:18:10 | call to get | true | 19 | 19 | | test.cpp:31:7:31:13 | ... == ... | false | 30 | 30 | | test.cpp:31:7:31:13 | ... == ... | false | 34 | 34 | diff --git a/cpp/ql/test/library-tests/controlflow/guards/test.c b/cpp/ql/test/library-tests/controlflow/guards/test.c index 186244d4fca2..1d1134d64edc 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/test.c +++ b/cpp/ql/test/library-tests/controlflow/guards/test.c @@ -147,3 +147,15 @@ void test5(int x) { test3(); } } + +void test6(char* p) { + if(p) { + + } +} + +void test7(char* p) { + if(!p) { + + } +} \ No newline at end of file From d736426529dfef17c0e64939ddbc417c47f6f2bd Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 30 Apr 2024 11:45:58 +0100 Subject: [PATCH 123/238] C++: Support guards without implicit boolean conversions. --- .../lib/semmle/code/cpp/controlflow/IRGuards.qll | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll index bcd214ec0000..913cc42a85a7 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll @@ -790,6 +790,22 @@ private predicate simple_comparison_eq(Instruction test, Operand op, int k, Abst exists(switch.getSuccessor(case)) and case.getValue().toInt() = k ) + or + // There's no implicit CompareInstruction in files compiled as C since C + // doesn't have implicit boolean conversions. So instead we check whether + // there's a branch on a value ofpointer or integer type. + exists(ConditionalBranchInstruction branch, IRType type | + not test instanceof CompareInstruction and + (type instanceof IRAddressType or type instanceof IRIntegerType) and + test = branch.getCondition() and + op.getDef() = test + | + k = 1 and + value.(BooleanValue).getValue() = true + or + k = 0 and + value.(BooleanValue).getValue() = false + ) } private predicate complex_eq( From bb6cc92728ce121a22cf524a2ee416af90eee452 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 30 Apr 2024 12:04:35 +0100 Subject: [PATCH 124/238] C++: Support guards without implicit boolean conversions. --- cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll index 913cc42a85a7..eee69488b285 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll @@ -796,13 +796,18 @@ private predicate simple_comparison_eq(Instruction test, Operand op, int k, Abst // there's a branch on a value ofpointer or integer type. exists(ConditionalBranchInstruction branch, IRType type | not test instanceof CompareInstruction and + type = test.getResultIRType() and (type instanceof IRAddressType or type instanceof IRIntegerType) and test = branch.getCondition() and op.getDef() = test | - k = 1 and - value.(BooleanValue).getValue() = true - or + // We'd like to also include a case such as: + // ``` + // k = 1 and + // value.(BooleanValue).getValue() = true + // ``` + // but all we know is that the value is non-zero in the true branch. + // So we can only conclude something in the false branch. k = 0 and value.(BooleanValue).getValue() = false ) From 2939c89f7a4a169303ff7a6fcdbd57dcdf0d47fa Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 30 Apr 2024 12:04:42 +0100 Subject: [PATCH 125/238] C++: Accept test changes. --- .../controlflow/guards-ir/tests.expected | 68 +++++++++++++++++++ .../controlflow/guards/GuardsCompare.expected | 16 +++++ .../controlflow/guards/GuardsEnsure.expected | 13 ++++ 3 files changed, 97 insertions(+) diff --git a/cpp/ql/test/library-tests/controlflow/guards-ir/tests.expected b/cpp/ql/test/library-tests/controlflow/guards-ir/tests.expected index 943d7028a5d2..d50ca1609163 100644 --- a/cpp/ql/test/library-tests/controlflow/guards-ir/tests.expected +++ b/cpp/ql/test/library-tests/controlflow/guards-ir/tests.expected @@ -148,6 +148,24 @@ astGuardsCompare | 109 | y < 0+0 when ... < ... is true | | 109 | y >= 0+0 when ... < ... is false | | 109 | y >= 0+0 when ... \|\| ... is false | +| 126 | 1 != 0 when 1 is true | +| 126 | 1 != 0 when ... && ... is true | +| 126 | 1 == 0 when 1 is false | +| 126 | call to test3_condition != 0 when ... && ... is true | +| 126 | call to test3_condition != 0 when call to test3_condition is true | +| 126 | call to test3_condition == 0 when call to test3_condition is false | +| 131 | b != 0 when b is true | +| 131 | b == 0 when b is false | +| 137 | 0 != 0 when 0 is true | +| 137 | 0 == 0 when 0 is false | +| 146 | ! ... != 0 when ! ... is true | +| 146 | ! ... == 0 when ! ... is false | +| 152 | x != 0 when ... && ... is true | +| 152 | x != 0 when x is true | +| 152 | x == 0 when x is false | +| 152 | y != 0 when ... && ... is true | +| 152 | y != 0 when y is true | +| 152 | y == 0 when y is false | | 156 | ... + ... != x+0 when ... == ... is false | | 156 | ... + ... == x+0 when ... == ... is true | | 156 | x != ... + ...+0 when ... == ... is false | @@ -186,6 +204,8 @@ astGuardsCompare | 175 | call to foo != 0+0 when ... == ... is false | | 175 | call to foo == 0 when ... == ... is true | | 175 | call to foo == 0+0 when ... == ... is true | +| 181 | x != 0 when x is true | +| 181 | x == 0 when x is false | astGuardsControl | test.c:7:9:7:13 | ... > ... | false | 10 | 11 | | test.c:7:9:7:13 | ... > ... | true | 7 | 9 | @@ -487,8 +507,27 @@ astGuardsEnsure_const | test.c:109:9:109:14 | ... == ... | test.c:109:9:109:9 | x | != | 0 | 109 | 109 | | test.c:109:9:109:14 | ... == ... | test.c:109:9:109:9 | x | != | 0 | 113 | 113 | | test.c:109:9:109:23 | ... \|\| ... | test.c:109:9:109:9 | x | != | 0 | 113 | 113 | +| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | != | 0 | 126 | 126 | +| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | != | 0 | 126 | 128 | +| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | != | 0 | 131 | 131 | +| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | != | 0 | 131 | 132 | +| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | != | 0 | 134 | 123 | +| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | != | 0 | 126 | 128 | +| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | != | 0 | 126 | 128 | +| test.c:126:12:126:26 | call to test3_condition | test.c:126:12:126:26 | call to test3_condition | != | 0 | 126 | 128 | +| test.c:131:7:131:7 | b | test.c:131:7:131:7 | b | != | 0 | 131 | 132 | +| test.c:137:7:137:7 | 0 | test.c:137:7:137:7 | 0 | == | 0 | 142 | 136 | +| test.c:146:7:146:8 | ! ... | test.c:146:7:146:8 | ! ... | != | 0 | 146 | 147 | +| test.c:152:10:152:10 | x | test.c:152:10:152:10 | x | != | 0 | 151 | 152 | +| test.c:152:10:152:10 | x | test.c:152:10:152:10 | x | != | 0 | 152 | 152 | +| test.c:152:10:152:15 | ... && ... | test.c:152:10:152:10 | x | != | 0 | 151 | 152 | +| test.c:152:10:152:15 | ... && ... | test.c:152:15:152:15 | y | != | 0 | 151 | 152 | +| test.c:152:15:152:15 | y | test.c:152:15:152:15 | y | != | 0 | 151 | 152 | | test.c:175:13:175:32 | ... == ... | test.c:175:13:175:15 | call to foo | != | 0 | 175 | 175 | | test.c:175:13:175:32 | ... == ... | test.c:175:13:175:15 | call to foo | == | 0 | 175 | 175 | +| test.c:181:9:181:9 | x | test.c:181:9:181:9 | x | != | 0 | 181 | 182 | +| test.c:181:9:181:9 | x | test.c:181:9:181:9 | x | != | 0 | 186 | 180 | +| test.c:181:9:181:9 | x | test.c:181:9:181:9 | x | == | 0 | 183 | 184 | | test.cpp:18:8:18:10 | call to get | test.cpp:18:8:18:10 | call to get | != | 0 | 19 | 19 | | test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | -1 | 30 | 30 | | test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | -1 | 34 | 34 | @@ -640,6 +679,20 @@ irGuardsCompare | 109 | y < 0+0 when CompareLT: ... < ... is true | | 109 | y >= 0 when CompareLT: ... < ... is false | | 109 | y >= 0+0 when CompareLT: ... < ... is false | +| 126 | 1 != 0 when Constant: 1 is true | +| 126 | 1 == 0 when Constant: 1 is false | +| 126 | call to test3_condition != 0 when Call: call to test3_condition is true | +| 126 | call to test3_condition == 0 when Call: call to test3_condition is false | +| 131 | b != 0 when Load: b is true | +| 131 | b == 0 when Load: b is false | +| 137 | 0 != 0 when Constant: 0 is true | +| 137 | 0 == 0 when Constant: 0 is false | +| 146 | ! ... != 0 when LogicalNot: ! ... is true | +| 146 | ! ... == 0 when LogicalNot: ! ... is false | +| 152 | x != 0 when Load: x is true | +| 152 | x == 0 when Load: x is false | +| 152 | y != 0 when Load: y is true | +| 152 | y == 0 when Load: y is false | | 156 | ... + ... != x+0 when CompareEQ: ... == ... is false | | 156 | ... + ... == x+0 when CompareEQ: ... == ... is true | | 156 | x != ... + ...+0 when CompareEQ: ... == ... is false | @@ -678,6 +731,8 @@ irGuardsCompare | 175 | call to foo != 0+0 when CompareEQ: ... == ... is false | | 175 | call to foo == 0 when CompareEQ: ... == ... is true | | 175 | call to foo == 0+0 when CompareEQ: ... == ... is true | +| 181 | x != 0 when Load: x is true | +| 181 | x == 0 when Load: x is false | irGuardsControl | test.c:7:9:7:13 | CompareGT: ... > ... | false | 11 | 11 | | test.c:7:9:7:13 | CompareGT: ... > ... | true | 8 | 8 | @@ -999,8 +1054,21 @@ irGuardsEnsure_const | test.c:109:9:109:14 | CompareEQ: ... == ... | test.c:109:9:109:9 | Load: x | != | 0 | 109 | 109 | | test.c:109:9:109:14 | CompareEQ: ... == ... | test.c:109:9:109:9 | Load: x | != | 0 | 113 | 113 | | test.c:109:19:109:23 | CompareLT: ... < ... | test.c:109:19:109:19 | Load: y | >= | 0 | 113 | 113 | +| test.c:126:7:126:7 | Constant: 1 | test.c:126:7:126:7 | Constant: 1 | != | 0 | 126 | 126 | +| test.c:126:7:126:7 | Constant: 1 | test.c:126:7:126:7 | Constant: 1 | != | 0 | 127 | 127 | +| test.c:126:7:126:7 | Constant: 1 | test.c:126:7:126:7 | Constant: 1 | != | 0 | 131 | 131 | +| test.c:126:7:126:7 | Constant: 1 | test.c:126:7:126:7 | Constant: 1 | != | 0 | 132 | 132 | +| test.c:126:7:126:7 | Constant: 1 | test.c:126:7:126:7 | Constant: 1 | != | 0 | 134 | 134 | +| test.c:126:12:126:26 | Call: call to test3_condition | test.c:126:12:126:26 | Call: call to test3_condition | != | 0 | 127 | 127 | +| test.c:131:7:131:7 | Load: b | test.c:131:7:131:7 | Load: b | != | 0 | 132 | 132 | +| test.c:137:7:137:7 | Constant: 0 | test.c:137:7:137:7 | Constant: 0 | == | 0 | 142 | 142 | +| test.c:146:7:146:8 | LogicalNot: ! ... | test.c:146:7:146:8 | LogicalNot: ! ... | != | 0 | 147 | 147 | +| test.c:152:10:152:10 | Load: x | test.c:152:10:152:10 | Load: x | != | 0 | 152 | 152 | +| test.c:152:15:152:15 | Load: y | test.c:152:15:152:15 | Load: y | != | 0 | 152 | 152 | | test.c:175:13:175:32 | CompareEQ: ... == ... | test.c:175:13:175:15 | Call: call to foo | != | 0 | 175 | 175 | | test.c:175:13:175:32 | CompareEQ: ... == ... | test.c:175:13:175:15 | Call: call to foo | == | 0 | 175 | 175 | +| test.c:181:9:181:9 | Load: x | test.c:181:9:181:9 | Load: x | != | 0 | 182 | 182 | +| test.c:181:9:181:9 | Load: x | test.c:181:9:181:9 | Load: x | == | 0 | 184 | 184 | | test.cpp:18:8:18:12 | CompareNE: (bool)... | test.cpp:18:8:18:10 | Call: call to get | != | 0 | 19 | 19 | | test.cpp:31:7:31:13 | CompareEQ: ... == ... | test.cpp:31:7:31:7 | Load: x | != | -1 | 34 | 34 | | test.cpp:31:7:31:13 | CompareEQ: ... == ... | test.cpp:31:7:31:7 | Load: x | == | -1 | 30 | 30 | diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected b/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected index 756140604e13..bdee2bad3103 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected @@ -149,3 +149,19 @@ | 111 | 0.0 == i+0 when ... != ... is false | | 111 | i != 0.0+0 when ... != ... is true | | 111 | i == 0.0+0 when ... != ... is false | +| 126 | 1 != 0 when 1 is true | +| 126 | 1 != 0 when ... && ... is true | +| 126 | 1 == 0 when 1 is false | +| 126 | call to test3_condition != 0 when ... && ... is true | +| 126 | call to test3_condition != 0 when call to test3_condition is true | +| 126 | call to test3_condition == 0 when call to test3_condition is false | +| 131 | b != 0 when b is true | +| 131 | b == 0 when b is false | +| 137 | 0 != 0 when 0 is true | +| 137 | 0 == 0 when 0 is false | +| 146 | ! ... != 0 when ! ... is true | +| 146 | ! ... == 0 when ! ... is false | +| 152 | p != 0 when p is true | +| 152 | p == 0 when p is false | +| 158 | ! ... != 0 when ! ... is true | +| 158 | ! ... == 0 when ! ... is false | diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected b/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected index f9eaced1276a..4abf0e6fa824 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected @@ -234,6 +234,19 @@ unary | test.c:109:9:109:23 | ... \|\| ... | test.c:109:9:109:9 | x | != | 0 | 113 | 113 | | test.c:109:9:109:23 | ... \|\| ... | test.c:109:19:109:19 | y | >= | 0 | 113 | 113 | | test.c:109:19:109:23 | ... < ... | test.c:109:19:109:19 | y | >= | 0 | 113 | 113 | +| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | != | 0 | 126 | 126 | +| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | != | 0 | 126 | 128 | +| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | != | 0 | 131 | 131 | +| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | != | 0 | 131 | 132 | +| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | != | 0 | 134 | 123 | +| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | != | 0 | 126 | 128 | +| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | != | 0 | 126 | 128 | +| test.c:126:12:126:26 | call to test3_condition | test.c:126:12:126:26 | call to test3_condition | != | 0 | 126 | 128 | +| test.c:131:7:131:7 | b | test.c:131:7:131:7 | b | != | 0 | 131 | 132 | +| test.c:137:7:137:7 | 0 | test.c:137:7:137:7 | 0 | == | 0 | 142 | 136 | +| test.c:146:7:146:8 | ! ... | test.c:146:7:146:8 | ! ... | != | 0 | 146 | 147 | +| test.c:152:8:152:8 | p | test.c:152:8:152:8 | p | != | 0 | 152 | 154 | +| test.c:158:8:158:9 | ! ... | test.c:158:8:158:9 | ! ... | != | 0 | 158 | 160 | | test.cpp:18:8:18:10 | call to get | test.cpp:18:8:18:10 | call to get | != | 0 | 19 | 19 | | test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | -1 | 30 | 30 | | test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | -1 | 34 | 34 | From 99928b82edc3e2b0780ce2b6df39ef1a13db56c0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 30 Apr 2024 12:15:35 +0000 Subject: [PATCH 126/238] Post-release preparation for codeql-cli-2.17.2 --- cpp/ql/lib/qlpack.yml | 2 +- cpp/ql/src/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/lib/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/src/qlpack.yml | 2 +- csharp/ql/lib/qlpack.yml | 2 +- csharp/ql/src/qlpack.yml | 2 +- go/ql/consistency-queries/qlpack.yml | 2 +- go/ql/lib/qlpack.yml | 2 +- go/ql/src/qlpack.yml | 2 +- java/ql/automodel/src/qlpack.yml | 2 +- java/ql/lib/qlpack.yml | 2 +- java/ql/src/qlpack.yml | 2 +- javascript/ql/lib/qlpack.yml | 2 +- javascript/ql/src/qlpack.yml | 2 +- misc/suite-helpers/qlpack.yml | 2 +- python/ql/lib/qlpack.yml | 2 +- python/ql/src/qlpack.yml | 2 +- ruby/ql/lib/qlpack.yml | 2 +- ruby/ql/src/qlpack.yml | 2 +- shared/controlflow/qlpack.yml | 2 +- shared/dataflow/qlpack.yml | 2 +- shared/mad/qlpack.yml | 2 +- shared/rangeanalysis/qlpack.yml | 2 +- shared/regex/qlpack.yml | 2 +- shared/ssa/qlpack.yml | 2 +- shared/threat-models/qlpack.yml | 2 +- shared/tutorial/qlpack.yml | 2 +- shared/typeflow/qlpack.yml | 2 +- shared/typetracking/qlpack.yml | 2 +- shared/typos/qlpack.yml | 2 +- shared/util/qlpack.yml | 2 +- shared/xml/qlpack.yml | 2 +- shared/yaml/qlpack.yml | 2 +- swift/ql/lib/qlpack.yml | 2 +- swift/ql/src/qlpack.yml | 2 +- 35 files changed, 35 insertions(+), 35 deletions(-) diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml index f6f48625357b..b87cf42fb6fb 100644 --- a/cpp/ql/lib/qlpack.yml +++ b/cpp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-all -version: 0.13.0 +version: 0.13.1-dev groups: cpp dbscheme: semmlecode.cpp.dbscheme extractor: cpp diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml index 7eb3d91c6029..e3f87e5a6356 100644 --- a/cpp/ql/src/qlpack.yml +++ b/cpp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-queries -version: 0.9.11 +version: 0.9.12-dev groups: - cpp - queries diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml index 56aae235d873..4129c2ad6fd7 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.7.15 +version: 1.7.16-dev groups: - csharp - solorigate diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml index ded88f88d0a3..033c39775dda 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.7.15 +version: 1.7.16-dev groups: - csharp - solorigate diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index a5e029d1ea2e..13ddf66ad755 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-all -version: 0.10.0 +version: 0.10.1-dev groups: csharp dbscheme: semmlecode.csharp.dbscheme extractor: csharp diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml index 03a21b8ad75d..3e7180240edb 100644 --- a/csharp/ql/src/qlpack.yml +++ b/csharp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-queries -version: 0.8.15 +version: 0.8.16-dev groups: - csharp - queries diff --git a/go/ql/consistency-queries/qlpack.yml b/go/ql/consistency-queries/qlpack.yml index cf6a59361407..f56add92e15b 100644 --- a/go/ql/consistency-queries/qlpack.yml +++ b/go/ql/consistency-queries/qlpack.yml @@ -1,5 +1,5 @@ name: codeql-go-consistency-queries -version: 0.0.14 +version: 0.0.15-dev groups: - go - queries diff --git a/go/ql/lib/qlpack.yml b/go/ql/lib/qlpack.yml index cbd4958f113a..53780e3ecee3 100644 --- a/go/ql/lib/qlpack.yml +++ b/go/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-all -version: 0.8.0 +version: 0.8.1-dev groups: go dbscheme: go.dbscheme extractor: go diff --git a/go/ql/src/qlpack.yml b/go/ql/src/qlpack.yml index ae3f681f32fd..121ba9674729 100644 --- a/go/ql/src/qlpack.yml +++ b/go/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-queries -version: 0.7.15 +version: 0.7.16-dev groups: - go - queries diff --git a/java/ql/automodel/src/qlpack.yml b/java/ql/automodel/src/qlpack.yml index 8a8b37aef6f7..79c6f172bcc2 100644 --- a/java/ql/automodel/src/qlpack.yml +++ b/java/ql/automodel/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-automodel-queries -version: 0.0.22 +version: 0.0.23-dev groups: - java - automodel diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index 2f829aaeeb37..d3bcafad03c9 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-all -version: 0.10.0 +version: 0.10.1-dev groups: java dbscheme: config/semmlecode.dbscheme extractor: java diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml index b2225619f653..1279345f1964 100644 --- a/java/ql/src/qlpack.yml +++ b/java/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-queries -version: 0.8.15 +version: 0.8.16-dev groups: - java - queries diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index 6a1a8db3c216..d0321a60db45 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-all -version: 0.9.0 +version: 0.9.1-dev groups: javascript dbscheme: semmlecode.javascript.dbscheme extractor: javascript diff --git a/javascript/ql/src/qlpack.yml b/javascript/ql/src/qlpack.yml index 765436be44f8..97c6c232c9e2 100644 --- a/javascript/ql/src/qlpack.yml +++ b/javascript/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-queries -version: 0.8.15 +version: 0.8.16-dev groups: - javascript - queries diff --git a/misc/suite-helpers/qlpack.yml b/misc/suite-helpers/qlpack.yml index f711a5b95cc9..1e5655889b82 100644 --- a/misc/suite-helpers/qlpack.yml +++ b/misc/suite-helpers/qlpack.yml @@ -1,4 +1,4 @@ name: codeql/suite-helpers -version: 0.7.15 +version: 0.7.16-dev groups: shared warnOnImplicitThis: true diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml index da26320c692d..a06d9ac3d492 100644 --- a/python/ql/lib/qlpack.yml +++ b/python/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-all -version: 0.12.0 +version: 0.12.1-dev groups: python dbscheme: semmlecode.python.dbscheme extractor: python diff --git a/python/ql/src/qlpack.yml b/python/ql/src/qlpack.yml index cbb24537e518..4d4432b7fc21 100644 --- a/python/ql/src/qlpack.yml +++ b/python/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-queries -version: 0.9.15 +version: 0.9.16-dev groups: - python - queries diff --git a/ruby/ql/lib/qlpack.yml b/ruby/ql/lib/qlpack.yml index 4025867e348e..79ec8fc4fb55 100644 --- a/ruby/ql/lib/qlpack.yml +++ b/ruby/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-all -version: 0.9.0 +version: 0.9.1-dev groups: ruby extractor: ruby dbscheme: ruby.dbscheme diff --git a/ruby/ql/src/qlpack.yml b/ruby/ql/src/qlpack.yml index e0b73d2f8d5f..b2d690177e0a 100644 --- a/ruby/ql/src/qlpack.yml +++ b/ruby/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-queries -version: 0.8.15 +version: 0.8.16-dev groups: - ruby - queries diff --git a/shared/controlflow/qlpack.yml b/shared/controlflow/qlpack.yml index 7fceca57d01a..0cb89d3b4162 100644 --- a/shared/controlflow/qlpack.yml +++ b/shared/controlflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/controlflow -version: 0.1.15 +version: 0.1.16-dev groups: shared library: true dependencies: diff --git a/shared/dataflow/qlpack.yml b/shared/dataflow/qlpack.yml index 05692d1b152b..14e318dced6b 100644 --- a/shared/dataflow/qlpack.yml +++ b/shared/dataflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/dataflow -version: 0.2.6 +version: 0.2.7-dev groups: shared library: true dependencies: diff --git a/shared/mad/qlpack.yml b/shared/mad/qlpack.yml index c60b7b1326fe..82dd88dcb56d 100644 --- a/shared/mad/qlpack.yml +++ b/shared/mad/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/mad -version: 0.2.15 +version: 0.2.16-dev groups: shared library: true dependencies: diff --git a/shared/rangeanalysis/qlpack.yml b/shared/rangeanalysis/qlpack.yml index cd1b6c4d432d..309d8214fc05 100644 --- a/shared/rangeanalysis/qlpack.yml +++ b/shared/rangeanalysis/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/rangeanalysis -version: 0.0.14 +version: 0.0.15-dev groups: shared library: true dependencies: diff --git a/shared/regex/qlpack.yml b/shared/regex/qlpack.yml index 15813ea4760d..bbd72f8b24cc 100644 --- a/shared/regex/qlpack.yml +++ b/shared/regex/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/regex -version: 0.2.15 +version: 0.2.16-dev groups: shared library: true dependencies: diff --git a/shared/ssa/qlpack.yml b/shared/ssa/qlpack.yml index 746d89a8e992..a824d260d607 100644 --- a/shared/ssa/qlpack.yml +++ b/shared/ssa/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ssa -version: 0.2.15 +version: 0.2.16-dev groups: shared library: true dependencies: diff --git a/shared/threat-models/qlpack.yml b/shared/threat-models/qlpack.yml index ac44b807cde0..915ae1b88fd1 100644 --- a/shared/threat-models/qlpack.yml +++ b/shared/threat-models/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/threat-models -version: 0.0.14 +version: 0.0.15-dev library: true groups: shared dataExtensions: diff --git a/shared/tutorial/qlpack.yml b/shared/tutorial/qlpack.yml index 37dc21a6e3a0..4c5c4ed20cdf 100644 --- a/shared/tutorial/qlpack.yml +++ b/shared/tutorial/qlpack.yml @@ -1,7 +1,7 @@ name: codeql/tutorial description: Library for the CodeQL detective tutorials, helping new users learn to write CodeQL queries. -version: 0.2.15 +version: 0.2.16-dev groups: shared library: true warnOnImplicitThis: true diff --git a/shared/typeflow/qlpack.yml b/shared/typeflow/qlpack.yml index 10024358df5c..365c17b83041 100644 --- a/shared/typeflow/qlpack.yml +++ b/shared/typeflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typeflow -version: 0.0.2 +version: 0.0.3-dev groups: shared library: true dependencies: diff --git a/shared/typetracking/qlpack.yml b/shared/typetracking/qlpack.yml index ee57425e254a..5f568fad1c30 100644 --- a/shared/typetracking/qlpack.yml +++ b/shared/typetracking/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typetracking -version: 0.2.15 +version: 0.2.16-dev groups: shared library: true dependencies: diff --git a/shared/typos/qlpack.yml b/shared/typos/qlpack.yml index cd620389331e..a50a2dae34b9 100644 --- a/shared/typos/qlpack.yml +++ b/shared/typos/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typos -version: 0.2.15 +version: 0.2.16-dev groups: shared library: true warnOnImplicitThis: true diff --git a/shared/util/qlpack.yml b/shared/util/qlpack.yml index dafa542bf2ca..602b3353d902 100644 --- a/shared/util/qlpack.yml +++ b/shared/util/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/util -version: 0.2.15 +version: 0.2.16-dev groups: shared library: true dependencies: null diff --git a/shared/xml/qlpack.yml b/shared/xml/qlpack.yml index 8c04aa720c78..f4de1f7ea4f0 100644 --- a/shared/xml/qlpack.yml +++ b/shared/xml/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/xml -version: 0.0.2 +version: 0.0.3-dev groups: shared library: true dependencies: diff --git a/shared/yaml/qlpack.yml b/shared/yaml/qlpack.yml index b0428c4d3868..598b37055db8 100644 --- a/shared/yaml/qlpack.yml +++ b/shared/yaml/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/yaml -version: 0.2.15 +version: 0.2.16-dev groups: shared library: true warnOnImplicitThis: true diff --git a/swift/ql/lib/qlpack.yml b/swift/ql/lib/qlpack.yml index 435d074a0808..0db44bbb5dae 100644 --- a/swift/ql/lib/qlpack.yml +++ b/swift/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-all -version: 0.3.15 +version: 0.3.16-dev groups: swift extractor: swift dbscheme: swift.dbscheme diff --git a/swift/ql/src/qlpack.yml b/swift/ql/src/qlpack.yml index 923eb4adb6c2..759f8ba34d17 100644 --- a/swift/ql/src/qlpack.yml +++ b/swift/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-queries -version: 0.3.15 +version: 0.3.16-dev groups: - swift - queries From 32fe0846302bc5d7d427b0c459e4aa02085ec1b6 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 30 Apr 2024 14:42:30 +0100 Subject: [PATCH 127/238] Update cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com> --- cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll index eee69488b285..83f8dc8b3bc7 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll @@ -793,7 +793,7 @@ private predicate simple_comparison_eq(Instruction test, Operand op, int k, Abst or // There's no implicit CompareInstruction in files compiled as C since C // doesn't have implicit boolean conversions. So instead we check whether - // there's a branch on a value ofpointer or integer type. + // there's a branch on a value of pointer or integer type. exists(ConditionalBranchInstruction branch, IRType type | not test instanceof CompareInstruction and type = test.getResultIRType() and From c32c810ae77576afe2e661d0ada72a360f1ffc2e Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 30 Apr 2024 14:48:21 +0100 Subject: [PATCH 128/238] C++: Add a test with a 'short' type. --- .../library-tests/controlflow/guards/Guards.expected | 3 +++ .../controlflow/guards/GuardsCompare.expected | 4 ++++ .../controlflow/guards/GuardsControl.expected | 3 +++ .../controlflow/guards/GuardsEnsure.expected | 2 ++ cpp/ql/test/library-tests/controlflow/guards/test.c | 12 ++++++++++++ 5 files changed, 24 insertions(+) diff --git a/cpp/ql/test/library-tests/controlflow/guards/Guards.expected b/cpp/ql/test/library-tests/controlflow/guards/Guards.expected index 8ee1b1af7d45..13d6c2b654ff 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/Guards.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/Guards.expected @@ -29,6 +29,9 @@ | test.c:152:8:152:8 | p | | test.c:158:8:158:9 | ! ... | | test.c:158:9:158:9 | p | +| test.c:164:8:164:8 | s | +| test.c:170:8:170:9 | ! ... | +| test.c:170:9:170:9 | s | | test.cpp:18:8:18:10 | call to get | | test.cpp:31:7:31:13 | ... == ... | | test.cpp:42:13:42:20 | call to getABool | diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected b/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected index bdee2bad3103..a2f418b3d7bb 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected @@ -165,3 +165,7 @@ | 152 | p == 0 when p is false | | 158 | ! ... != 0 when ! ... is true | | 158 | ! ... == 0 when ! ... is false | +| 164 | s != 0 when s is true | +| 164 | s == 0 when s is false | +| 170 | ! ... != 0 when ! ... is true | +| 170 | ! ... == 0 when ! ... is false | diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected b/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected index 5c024bebc629..cf36a58a515b 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected @@ -82,6 +82,9 @@ | test.c:152:8:152:8 | p | true | 152 | 154 | | test.c:158:8:158:9 | ! ... | true | 158 | 160 | | test.c:158:9:158:9 | p | false | 158 | 160 | +| test.c:164:8:164:8 | s | true | 164 | 166 | +| test.c:170:8:170:9 | ! ... | true | 170 | 172 | +| test.c:170:9:170:9 | s | false | 170 | 172 | | test.cpp:18:8:18:10 | call to get | true | 19 | 19 | | test.cpp:31:7:31:13 | ... == ... | false | 30 | 30 | | test.cpp:31:7:31:13 | ... == ... | false | 34 | 34 | diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected b/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected index 4abf0e6fa824..45d63f6dd536 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected @@ -247,6 +247,8 @@ unary | test.c:146:7:146:8 | ! ... | test.c:146:7:146:8 | ! ... | != | 0 | 146 | 147 | | test.c:152:8:152:8 | p | test.c:152:8:152:8 | p | != | 0 | 152 | 154 | | test.c:158:8:158:9 | ! ... | test.c:158:8:158:9 | ! ... | != | 0 | 158 | 160 | +| test.c:164:8:164:8 | s | test.c:164:8:164:8 | s | != | 0 | 164 | 166 | +| test.c:170:8:170:9 | ! ... | test.c:170:8:170:9 | ! ... | != | 0 | 170 | 172 | | test.cpp:18:8:18:10 | call to get | test.cpp:18:8:18:10 | call to get | != | 0 | 19 | 19 | | test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | -1 | 30 | 30 | | test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | -1 | 34 | 34 | diff --git a/cpp/ql/test/library-tests/controlflow/guards/test.c b/cpp/ql/test/library-tests/controlflow/guards/test.c index 1d1134d64edc..207e23baa0e3 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/test.c +++ b/cpp/ql/test/library-tests/controlflow/guards/test.c @@ -157,5 +157,17 @@ void test6(char* p) { void test7(char* p) { if(!p) { + } +} + +void test8(short s) { + if(s) { + + } +} + +void test9(short s) { + if(!s) { + } } \ No newline at end of file From c5a87c95d8ff74b7fae5b65752787dfd9b78b8c7 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 30 Apr 2024 15:39:00 +0100 Subject: [PATCH 129/238] C++: Add tests that incorrectly call destructors twice. --- .../library-tests/ir/ir/PrintAST.expected | 133 +++++++++++++++ .../library-tests/ir/ir/aliased_ir.expected | 159 ++++++++++++++++++ cpp/ql/test/library-tests/ir/ir/ir.cpp | 32 ++++ .../test/library-tests/ir/ir/raw_ir.expected | 157 +++++++++++++++++ 4 files changed, 481 insertions(+) diff --git a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected index 28c1398d90bc..0897b3f25c3e 100644 --- a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected +++ b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected @@ -22442,6 +22442,139 @@ ir.cpp: #-----| Type = [Class] ClassWithDestructor #-----| ValueCategory = lvalue # 2499| getStmt(4): [ReturnStmt] return ... +# 2501| [TopLevelFunction] void destruction_in_switch_1(int) +# 2501| : +# 2501| getParameter(0): [Parameter] c +# 2501| Type = [IntType] int +# 2501| getEntryPoint(): [BlockStmt] { ... } +# 2502| getStmt(0): [SwitchStmt] switch (...) ... +# 2502| getExpr(): [VariableAccess] c +# 2502| Type = [IntType] int +# 2502| ValueCategory = prvalue(load) +# 2502| getStmt(): [BlockStmt] { ... } +# 2503| getStmt(0): [SwitchCase] case ...: +# 2503| getExpr(): [Literal] 0 +# 2503| Type = [IntType] int +# 2503| Value = [Literal] 0 +# 2503| ValueCategory = prvalue +# 2503| getStmt(1): [BlockStmt] { ... } +# 2504| getStmt(0): [DeclStmt] declaration +# 2504| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x +# 2504| Type = [Class] ClassWithDestructor +# 2504| getVariable().getInitializer(): [Initializer] initializer for x +# 2504| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2504| Type = [VoidType] void +# 2504| ValueCategory = prvalue +# 2505| getStmt(1): [BreakStmt] break; +# 2506| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2506| Type = [VoidType] void +# 2506| ValueCategory = prvalue +# 2506| getQualifier(): [VariableAccess] x +# 2506| Type = [Class] ClassWithDestructor +# 2506| ValueCategory = lvalue +# 2506| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2506| Type = [VoidType] void +# 2506| ValueCategory = prvalue +# 2506| getQualifier(): [VariableAccess] x +# 2506| Type = [Class] ClassWithDestructor +# 2506| ValueCategory = lvalue +# 2507| getStmt(1): [LabelStmt] label ...: +# 2508| getStmt(2): [ReturnStmt] return ... +# 2510| [TopLevelFunction] void destruction_in_switch_2(int) +# 2510| : +# 2510| getParameter(0): [Parameter] c +# 2510| Type = [IntType] int +# 2510| getEntryPoint(): [BlockStmt] { ... } +# 2511| getStmt(0): [SwitchStmt] switch (...) ... +# 2511| getInitialization(): [DeclStmt] declaration +# 2511| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y +# 2511| Type = [Class] ClassWithDestructor +# 2511| getVariable().getInitializer(): [Initializer] initializer for y +# 2511| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2511| Type = [VoidType] void +# 2511| ValueCategory = prvalue +# 2511| getExpr(): [VariableAccess] c +# 2511| Type = [IntType] int +# 2511| ValueCategory = prvalue(load) +# 2511| getStmt(): [BlockStmt] { ... } +# 2512| getStmt(0): [SwitchCase] case ...: +# 2512| getExpr(): [Literal] 0 +# 2512| Type = [IntType] int +# 2512| Value = [Literal] 0 +# 2512| ValueCategory = prvalue +# 2512| getStmt(1): [BlockStmt] { ... } +# 2513| getStmt(0): [BreakStmt] break; +# 2515| getStmt(2): [SwitchCase] default: +# 2515| getStmt(3): [BlockStmt] { ... } +# 2516| getStmt(0): [BreakStmt] break; +# 2518| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2518| Type = [VoidType] void +# 2518| ValueCategory = prvalue +# 2518| getQualifier(): [VariableAccess] y +# 2518| Type = [Class] ClassWithDestructor +# 2518| ValueCategory = lvalue +# 2518| getStmt(1): [LabelStmt] label ...: +# 2519| getStmt(2): [ReturnStmt] return ... +# 2521| [TopLevelFunction] void destruction_in_switch_3(int) +# 2521| : +# 2521| getParameter(0): [Parameter] c +# 2521| Type = [IntType] int +# 2521| getEntryPoint(): [BlockStmt] { ... } +# 2522| getStmt(0): [SwitchStmt] switch (...) ... +# 2522| getInitialization(): [DeclStmt] declaration +# 2522| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y +# 2522| Type = [Class] ClassWithDestructor +# 2522| getVariable().getInitializer(): [Initializer] initializer for y +# 2522| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2522| Type = [VoidType] void +# 2522| ValueCategory = prvalue +# 2522| getExpr(): [VariableAccess] c +# 2522| Type = [IntType] int +# 2522| ValueCategory = prvalue(load) +# 2522| getStmt(): [BlockStmt] { ... } +# 2523| getStmt(0): [SwitchCase] case ...: +# 2523| getExpr(): [Literal] 0 +# 2523| Type = [IntType] int +# 2523| Value = [Literal] 0 +# 2523| ValueCategory = prvalue +# 2523| getStmt(1): [BlockStmt] { ... } +# 2524| getStmt(0): [DeclStmt] declaration +# 2524| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x +# 2524| Type = [Class] ClassWithDestructor +# 2524| getVariable().getInitializer(): [Initializer] initializer for x +# 2524| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2524| Type = [VoidType] void +# 2524| ValueCategory = prvalue +# 2525| getStmt(1): [BreakStmt] break; +# 2526| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2526| Type = [VoidType] void +# 2526| ValueCategory = prvalue +# 2526| getQualifier(): [VariableAccess] x +# 2526| Type = [Class] ClassWithDestructor +# 2526| ValueCategory = lvalue +# 2530| getImplicitDestructorCall(1): [DestructorCall] call to ~ClassWithDestructor +# 2530| Type = [VoidType] void +# 2530| ValueCategory = prvalue +# 2530| getQualifier(): [VariableAccess] y +# 2530| Type = [Class] ClassWithDestructor +# 2530| ValueCategory = lvalue +# 2526| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2526| Type = [VoidType] void +# 2526| ValueCategory = prvalue +# 2526| getQualifier(): [VariableAccess] x +# 2526| Type = [Class] ClassWithDestructor +# 2526| ValueCategory = lvalue +# 2527| getStmt(2): [SwitchCase] default: +# 2527| getStmt(3): [BlockStmt] { ... } +# 2528| getStmt(0): [BreakStmt] break; +# 2530| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2530| Type = [VoidType] void +# 2530| ValueCategory = prvalue +# 2530| getQualifier(): [VariableAccess] y +# 2530| Type = [Class] ClassWithDestructor +# 2530| ValueCategory = lvalue +# 2530| getStmt(1): [LabelStmt] label ...: +# 2531| getStmt(2): [ReturnStmt] return ... perf-regression.cpp: # 4| [CopyAssignmentOperator] Big& Big::operator=(Big const&) # 4| : diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected index 68e5d36d2062..3ec42290d746 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected @@ -17958,6 +17958,165 @@ ir.cpp: # 2484| v2484_8(void) = AliasedUse : ~m2497_4 # 2484| v2484_9(void) = ExitFunction : +# 2501| void destruction_in_switch_1(int) +# 2501| Block 0 +# 2501| v2501_1(void) = EnterFunction : +# 2501| m2501_2(unknown) = AliasedDefinition : +# 2501| m2501_3(unknown) = InitializeNonLocal : +# 2501| m2501_4(unknown) = Chi : total:m2501_2, partial:m2501_3 +# 2501| r2501_5(glval) = VariableAddress[c] : +# 2501| m2501_6(int) = InitializeParameter[c] : &:r2501_5 +# 2502| r2502_1(glval) = VariableAddress[c] : +# 2502| r2502_2(int) = Load[c] : &:r2502_1, m2501_6 +# 2502| v2502_3(void) = Switch : r2502_2 +#-----| Case[0] -> Block 1 +#-----| Default -> Block 2 + +# 2503| Block 1 +# 2503| v2503_1(void) = NoOp : +# 2504| r2504_1(glval) = VariableAddress[x] : +# 2504| m2504_2(ClassWithDestructor) = Uninitialized[x] : &:r2504_1 +# 2504| r2504_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2504| v2504_4(void) = Call[ClassWithDestructor] : func:r2504_3, this:r2504_1 +# 2504| m2504_5(unknown) = ^CallSideEffect : ~m2501_4 +# 2504| m2504_6(unknown) = Chi : total:m2501_4, partial:m2504_5 +# 2504| m2504_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2504_1 +# 2504| m2504_8(ClassWithDestructor) = Chi : total:m2504_2, partial:m2504_7 +# 2505| v2505_1(void) = NoOp : +# 2506| r2506_1(glval) = VariableAddress[x] : +# 2506| r2506_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2506| v2506_3(void) = Call[~ClassWithDestructor] : func:r2506_2, this:r2506_1 +# 2506| m2506_4(unknown) = ^CallSideEffect : ~m2504_6 +# 2506| m2506_5(unknown) = Chi : total:m2504_6, partial:m2506_4 +# 2506| v2506_6(void) = ^IndirectReadSideEffect[-1] : &:r2506_1, m2504_8 +# 2506| m2506_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2506_1 +# 2506| m2506_8(ClassWithDestructor) = Chi : total:m2504_8, partial:m2506_7 +# 2506| r2506_9(glval) = VariableAddress[x] : +# 2506| r2506_10(glval) = FunctionAddress[~ClassWithDestructor] : +# 2506| v2506_11(void) = Call[~ClassWithDestructor] : func:r2506_10, this:r2506_9 +# 2506| m2506_12(unknown) = ^CallSideEffect : ~m2506_5 +# 2506| m2506_13(unknown) = Chi : total:m2506_5, partial:m2506_12 +# 2506| v2506_14(void) = ^IndirectReadSideEffect[-1] : &:r2506_9, m2506_8 +# 2506| m2506_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2506_9 +# 2506| m2506_16(ClassWithDestructor) = Chi : total:m2506_8, partial:m2506_15 +#-----| Goto -> Block 2 + +# 2507| Block 2 +# 2507| m2507_1(unknown) = Phi : from 0:~m2501_4, from 1:~m2506_13 +# 2507| v2507_2(void) = NoOp : +# 2508| v2508_1(void) = NoOp : +# 2501| v2501_7(void) = ReturnVoid : +# 2501| v2501_8(void) = AliasedUse : ~m2507_1 +# 2501| v2501_9(void) = ExitFunction : + +# 2510| void destruction_in_switch_2(int) +# 2510| Block 0 +# 2510| v2510_1(void) = EnterFunction : +# 2510| m2510_2(unknown) = AliasedDefinition : +# 2510| m2510_3(unknown) = InitializeNonLocal : +# 2510| m2510_4(unknown) = Chi : total:m2510_2, partial:m2510_3 +# 2510| r2510_5(glval) = VariableAddress[c] : +# 2510| m2510_6(int) = InitializeParameter[c] : &:r2510_5 +# 2511| r2511_1(glval) = VariableAddress[y] : +# 2511| m2511_2(ClassWithDestructor) = Uninitialized[y] : &:r2511_1 +# 2511| r2511_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2511| v2511_4(void) = Call[ClassWithDestructor] : func:r2511_3, this:r2511_1 +# 2511| m2511_5(unknown) = ^CallSideEffect : ~m2510_4 +# 2511| m2511_6(unknown) = Chi : total:m2510_4, partial:m2511_5 +# 2511| m2511_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2511_1 +# 2511| m2511_8(ClassWithDestructor) = Chi : total:m2511_2, partial:m2511_7 +# 2511| r2511_9(glval) = VariableAddress[c] : +# 2511| r2511_10(int) = Load[c] : &:r2511_9, m2510_6 +# 2511| v2511_11(void) = Switch : r2511_10 +#-----| Case[0] -> Block 1 +#-----| Default -> Block 2 + +# 2512| Block 1 +# 2512| v2512_1(void) = NoOp : +# 2513| v2513_1(void) = NoOp : +#-----| Goto -> Block 3 + +# 2515| Block 2 +# 2515| v2515_1(void) = NoOp : +# 2516| v2516_1(void) = NoOp : +#-----| Goto -> Block 3 + +# 2518| Block 3 +# 2518| v2518_1(void) = NoOp : +# 2519| v2519_1(void) = NoOp : +# 2510| v2510_7(void) = ReturnVoid : +# 2510| v2510_8(void) = AliasedUse : ~m2511_6 +# 2510| v2510_9(void) = ExitFunction : + +# 2521| void destruction_in_switch_3(int) +# 2521| Block 0 +# 2521| v2521_1(void) = EnterFunction : +# 2521| m2521_2(unknown) = AliasedDefinition : +# 2521| m2521_3(unknown) = InitializeNonLocal : +# 2521| m2521_4(unknown) = Chi : total:m2521_2, partial:m2521_3 +# 2521| r2521_5(glval) = VariableAddress[c] : +# 2521| m2521_6(int) = InitializeParameter[c] : &:r2521_5 +# 2522| r2522_1(glval) = VariableAddress[y] : +# 2522| m2522_2(ClassWithDestructor) = Uninitialized[y] : &:r2522_1 +# 2522| r2522_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2522| v2522_4(void) = Call[ClassWithDestructor] : func:r2522_3, this:r2522_1 +# 2522| m2522_5(unknown) = ^CallSideEffect : ~m2521_4 +# 2522| m2522_6(unknown) = Chi : total:m2521_4, partial:m2522_5 +# 2522| m2522_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2522_1 +# 2522| m2522_8(ClassWithDestructor) = Chi : total:m2522_2, partial:m2522_7 +# 2522| r2522_9(glval) = VariableAddress[c] : +# 2522| r2522_10(int) = Load[c] : &:r2522_9, m2521_6 +# 2522| v2522_11(void) = Switch : r2522_10 +#-----| Case[0] -> Block 1 +#-----| Default -> Block 2 + +# 2523| Block 1 +# 2523| v2523_1(void) = NoOp : +# 2524| r2524_1(glval) = VariableAddress[x] : +# 2524| m2524_2(ClassWithDestructor) = Uninitialized[x] : &:r2524_1 +# 2524| r2524_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2524| v2524_4(void) = Call[ClassWithDestructor] : func:r2524_3, this:r2524_1 +# 2524| m2524_5(unknown) = ^CallSideEffect : ~m2522_6 +# 2524| m2524_6(unknown) = Chi : total:m2522_6, partial:m2524_5 +# 2524| m2524_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2524_1 +# 2524| m2524_8(ClassWithDestructor) = Chi : total:m2524_2, partial:m2524_7 +# 2525| v2525_1(void) = NoOp : +# 2526| r2526_1(glval) = VariableAddress[x] : +# 2526| r2526_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2526| v2526_3(void) = Call[~ClassWithDestructor] : func:r2526_2, this:r2526_1 +# 2526| m2526_4(unknown) = ^CallSideEffect : ~m2524_6 +# 2526| m2526_5(unknown) = Chi : total:m2524_6, partial:m2526_4 +# 2526| v2526_6(void) = ^IndirectReadSideEffect[-1] : &:r2526_1, m2524_8 +# 2526| m2526_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2526_1 +# 2526| m2526_8(ClassWithDestructor) = Chi : total:m2524_8, partial:m2526_7 +# 2530| r2530_1(glval) = VariableAddress[y] : +# 2530| r2530_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2530| v2530_3(void) = Call[~ClassWithDestructor] : func:r2530_2, this:r2530_1 +# 2530| m2530_4(unknown) = ^CallSideEffect : ~m2526_5 +# 2530| m2530_5(unknown) = Chi : total:m2526_5, partial:m2530_4 +# 2530| v2530_6(void) = ^IndirectReadSideEffect[-1] : &:r2530_1, m2522_8 +# 2530| m2530_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2530_1 +# 2530| m2530_8(ClassWithDestructor) = Chi : total:m2522_8, partial:m2530_7 +# 2526| r2526_9(glval) = VariableAddress[x] : +# 2526| r2526_10(glval) = FunctionAddress[~ClassWithDestructor] : +# 2526| v2526_11(void) = Call[~ClassWithDestructor] : func:r2526_10, this:r2526_9 +# 2526| m2526_12(unknown) = ^CallSideEffect : ~m2530_5 +# 2526| m2526_13(unknown) = Chi : total:m2530_5, partial:m2526_12 +# 2526| v2526_14(void) = ^IndirectReadSideEffect[-1] : &:r2526_9, m2526_8 +# 2526| m2526_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2526_9 +# 2526| m2526_16(ClassWithDestructor) = Chi : total:m2526_8, partial:m2526_15 +#-----| Goto -> Block 2 + +# 2527| Block 2 +# 2527| m2527_1(unknown) = Phi : from 0:~m2522_6, from 1:~m2526_13 +# 2527| v2527_2(void) = NoOp : +# 2528| v2528_1(void) = NoOp : +# 2530| v2530_9(void) = NoOp : +# 2531| v2531_1(void) = NoOp : +# 2521| v2521_7(void) = ReturnVoid : +# 2521| v2521_8(void) = AliasedUse : ~m2527_1 +# 2521| v2521_9(void) = ExitFunction : + perf-regression.cpp: # 6| void Big::Big() # 6| Block 0 diff --git a/cpp/ql/test/library-tests/ir/ir/ir.cpp b/cpp/ql/test/library-tests/ir/ir/ir.cpp index c8840fd0b56e..accee358e952 100644 --- a/cpp/ql/test/library-tests/ir/ir/ir.cpp +++ b/cpp/ql/test/library-tests/ir/ir/ir.cpp @@ -2498,4 +2498,36 @@ void destructor_without_block(bool b) ClassWithDestructor g; } +void destruction_in_switch_1(int c) { + switch (c) { + case 0: { + ClassWithDestructor x; + break; + } + } +} + +void destruction_in_switch_2(int c) { + switch (ClassWithDestructor y; c) { + case 0: { + break; + } + default: { + break; + } + } +} + +void destruction_in_switch_3(int c) { + switch (ClassWithDestructor y; c) { + case 0: { + ClassWithDestructor x; + break; + } + default: { + break; + } + } +} + // semmle-extractor-options: -std=c++20 --clang diff --git a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected index aadcd33f5104..0684dcba0b7b 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -16372,6 +16372,163 @@ ir.cpp: # 2484| v2484_7(void) = AliasedUse : ~m? # 2484| v2484_8(void) = ExitFunction : +# 2501| void destruction_in_switch_1(int) +# 2501| Block 0 +# 2501| v2501_1(void) = EnterFunction : +# 2501| mu2501_2(unknown) = AliasedDefinition : +# 2501| mu2501_3(unknown) = InitializeNonLocal : +# 2501| r2501_4(glval) = VariableAddress[c] : +# 2501| mu2501_5(int) = InitializeParameter[c] : &:r2501_4 +# 2502| r2502_1(glval) = VariableAddress[c] : +# 2502| r2502_2(int) = Load[c] : &:r2502_1, ~m? +# 2502| v2502_3(void) = Switch : r2502_2 +#-----| Case[0] -> Block 1 +#-----| Default -> Block 2 + +# 2503| Block 1 +# 2503| v2503_1(void) = NoOp : +# 2504| r2504_1(glval) = VariableAddress[x] : +# 2504| mu2504_2(ClassWithDestructor) = Uninitialized[x] : &:r2504_1 +# 2504| r2504_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2504| v2504_4(void) = Call[ClassWithDestructor] : func:r2504_3, this:r2504_1 +# 2504| mu2504_5(unknown) = ^CallSideEffect : ~m? +# 2504| mu2504_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2504_1 +# 2505| v2505_1(void) = NoOp : +# 2506| r2506_1(glval) = VariableAddress[x] : +# 2506| r2506_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2506| v2506_3(void) = Call[~ClassWithDestructor] : func:r2506_2, this:r2506_1 +# 2506| mu2506_4(unknown) = ^CallSideEffect : ~m? +# 2506| v2506_5(void) = ^IndirectReadSideEffect[-1] : &:r2506_1, ~m? +# 2506| mu2506_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2506_1 +# 2506| r2506_7(glval) = VariableAddress[x] : +# 2506| r2506_8(glval) = FunctionAddress[~ClassWithDestructor] : +# 2506| v2506_9(void) = Call[~ClassWithDestructor] : func:r2506_8, this:r2506_7 +# 2506| mu2506_10(unknown) = ^CallSideEffect : ~m? +# 2506| v2506_11(void) = ^IndirectReadSideEffect[-1] : &:r2506_7, ~m? +# 2506| mu2506_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2506_7 +#-----| Goto -> Block 2 + +# 2507| Block 2 +# 2507| v2507_1(void) = NoOp : +# 2508| v2508_1(void) = NoOp : +# 2501| v2501_6(void) = ReturnVoid : +# 2501| v2501_7(void) = AliasedUse : ~m? +# 2501| v2501_8(void) = ExitFunction : + +# 2510| void destruction_in_switch_2(int) +# 2510| Block 0 +# 2510| v2510_1(void) = EnterFunction : +# 2510| mu2510_2(unknown) = AliasedDefinition : +# 2510| mu2510_3(unknown) = InitializeNonLocal : +# 2510| r2510_4(glval) = VariableAddress[c] : +# 2510| mu2510_5(int) = InitializeParameter[c] : &:r2510_4 +# 2511| r2511_1(glval) = VariableAddress[y] : +# 2511| mu2511_2(ClassWithDestructor) = Uninitialized[y] : &:r2511_1 +# 2511| r2511_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2511| v2511_4(void) = Call[ClassWithDestructor] : func:r2511_3, this:r2511_1 +# 2511| mu2511_5(unknown) = ^CallSideEffect : ~m? +# 2511| mu2511_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2511_1 +# 2511| r2511_7(glval) = VariableAddress[c] : +# 2511| r2511_8(int) = Load[c] : &:r2511_7, ~m? +# 2511| v2511_9(void) = Switch : r2511_8 +#-----| Case[0] -> Block 1 +#-----| Default -> Block 2 + +# 2512| Block 1 +# 2512| v2512_1(void) = NoOp : +# 2513| v2513_1(void) = NoOp : +#-----| Goto -> Block 4 + +# 2515| Block 2 +# 2515| v2515_1(void) = NoOp : +# 2516| v2516_1(void) = NoOp : +#-----| Goto -> Block 4 + +# 2518| Block 3 +# 2518| r2518_1(glval) = VariableAddress[y] : +# 2518| r2518_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2518| v2518_3(void) = Call[~ClassWithDestructor] : func:r2518_2, this:r2518_1 +# 2518| mu2518_4(unknown) = ^CallSideEffect : ~m? +# 2518| v2518_5(void) = ^IndirectReadSideEffect[-1] : &:r2518_1, ~m? +# 2518| mu2518_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2518_1 +#-----| Goto -> Block 4 + +# 2518| Block 4 +# 2518| v2518_7(void) = NoOp : +# 2519| v2519_1(void) = NoOp : +# 2510| v2510_6(void) = ReturnVoid : +# 2510| v2510_7(void) = AliasedUse : ~m? +# 2510| v2510_8(void) = ExitFunction : + +# 2521| void destruction_in_switch_3(int) +# 2521| Block 0 +# 2521| v2521_1(void) = EnterFunction : +# 2521| mu2521_2(unknown) = AliasedDefinition : +# 2521| mu2521_3(unknown) = InitializeNonLocal : +# 2521| r2521_4(glval) = VariableAddress[c] : +# 2521| mu2521_5(int) = InitializeParameter[c] : &:r2521_4 +# 2522| r2522_1(glval) = VariableAddress[y] : +# 2522| mu2522_2(ClassWithDestructor) = Uninitialized[y] : &:r2522_1 +# 2522| r2522_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2522| v2522_4(void) = Call[ClassWithDestructor] : func:r2522_3, this:r2522_1 +# 2522| mu2522_5(unknown) = ^CallSideEffect : ~m? +# 2522| mu2522_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2522_1 +# 2522| r2522_7(glval) = VariableAddress[c] : +# 2522| r2522_8(int) = Load[c] : &:r2522_7, ~m? +# 2522| v2522_9(void) = Switch : r2522_8 +#-----| Case[0] -> Block 1 +#-----| Default -> Block 2 + +# 2523| Block 1 +# 2523| v2523_1(void) = NoOp : +# 2524| r2524_1(glval) = VariableAddress[x] : +# 2524| mu2524_2(ClassWithDestructor) = Uninitialized[x] : &:r2524_1 +# 2524| r2524_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2524| v2524_4(void) = Call[ClassWithDestructor] : func:r2524_3, this:r2524_1 +# 2524| mu2524_5(unknown) = ^CallSideEffect : ~m? +# 2524| mu2524_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2524_1 +# 2525| v2525_1(void) = NoOp : +# 2526| r2526_1(glval) = VariableAddress[x] : +# 2526| r2526_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2526| v2526_3(void) = Call[~ClassWithDestructor] : func:r2526_2, this:r2526_1 +# 2526| mu2526_4(unknown) = ^CallSideEffect : ~m? +# 2526| v2526_5(void) = ^IndirectReadSideEffect[-1] : &:r2526_1, ~m? +# 2526| mu2526_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2526_1 +# 2530| r2530_1(glval) = VariableAddress[y] : +# 2530| r2530_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2530| v2530_3(void) = Call[~ClassWithDestructor] : func:r2530_2, this:r2530_1 +# 2530| mu2530_4(unknown) = ^CallSideEffect : ~m? +# 2530| v2530_5(void) = ^IndirectReadSideEffect[-1] : &:r2530_1, ~m? +# 2530| mu2530_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2530_1 +# 2526| r2526_7(glval) = VariableAddress[x] : +# 2526| r2526_8(glval) = FunctionAddress[~ClassWithDestructor] : +# 2526| v2526_9(void) = Call[~ClassWithDestructor] : func:r2526_8, this:r2526_7 +# 2526| mu2526_10(unknown) = ^CallSideEffect : ~m? +# 2526| v2526_11(void) = ^IndirectReadSideEffect[-1] : &:r2526_7, ~m? +# 2526| mu2526_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2526_7 +#-----| Goto -> Block 2 + +# 2527| Block 2 +# 2527| v2527_1(void) = NoOp : +# 2528| v2528_1(void) = NoOp : +#-----| Goto -> Block 4 + +# 2530| Block 3 +# 2530| r2530_7(glval) = VariableAddress[y] : +# 2530| r2530_8(glval) = FunctionAddress[~ClassWithDestructor] : +# 2530| v2530_9(void) = Call[~ClassWithDestructor] : func:r2530_8, this:r2530_7 +# 2530| mu2530_10(unknown) = ^CallSideEffect : ~m? +# 2530| v2530_11(void) = ^IndirectReadSideEffect[-1] : &:r2530_7, ~m? +# 2530| mu2530_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2530_7 +#-----| Goto -> Block 4 + +# 2530| Block 4 +# 2530| v2530_13(void) = NoOp : +# 2531| v2531_1(void) = NoOp : +# 2521| v2521_6(void) = ReturnVoid : +# 2521| v2521_7(void) = AliasedUse : ~m? +# 2521| v2521_8(void) = ExitFunction : + perf-regression.cpp: # 6| void Big::Big() # 6| Block 0 From a200ced2d611cdbf47199df82fdbfd7a312923e4 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 30 Apr 2024 15:41:25 +0100 Subject: [PATCH 130/238] C++: Fix IR generation for jump statements. --- .../raw/internal/TranslatedStmt.qll | 34 +++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) 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 fab2dacc8a78..d08a01244d78 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 @@ -1276,6 +1276,11 @@ class TranslatedJumpStmt extends TranslatedStmt { override JumpStmt stmt; override Instruction getFirstInstruction(EdgeKind kind) { + // The first instruction is a destructor call, if any. + result = this.getChildInternal(0).getFirstInstruction(kind) + or + // Otherwise, the first (and only) instruction is a `NoOp` + not exists(this.getChildInternal(0)) and result = this.getInstruction(OnlyInstructionTag()) and kind instanceof GotoEdge } @@ -1284,7 +1289,20 @@ class TranslatedJumpStmt extends TranslatedStmt { result = this.getInstruction(OnlyInstructionTag()) } - override TranslatedElement getChildInternal(int id) { none() } + private TranslatedCall getTranslatedImplicitDestructorCall(int id) { + result.getExpr() = stmt.getImplicitDestructorCall(id) + } + + override TranslatedElement getLastChild() { + result = + this.getTranslatedImplicitDestructorCall(max(int id | + exists(stmt.getImplicitDestructorCall(id)) + )) + } + + override TranslatedElement getChildInternal(int id) { + result = this.getTranslatedImplicitDestructorCall(id) + } override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { tag = OnlyInstructionTag() and @@ -1297,7 +1315,19 @@ class TranslatedJumpStmt extends TranslatedStmt { result = getTranslatedStmt(stmt.getTarget()).getFirstInstruction(kind) } - override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) { none() } + final override predicate handlesDestructorsExplicitly() { any() } + + override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) { + exists(int id | child = this.getChildInternal(id) | + // Transition to the next destructor call, if any. + result = this.getChildInternal(id + 1).getFirstInstruction(kind) + or + // And otherwise, exit this element by flowing to the target of the jump. + not exists(this.getChildInternal(id + 1)) and + kind instanceof GotoEdge and + result = this.getInstruction(OnlyInstructionTag()) + ) + } } private EdgeKind getCaseEdge(SwitchCase switchCase) { From cf025e19244c831232254470d2959b739abe2447 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 30 Apr 2024 15:47:53 +0100 Subject: [PATCH 131/238] C++: Accept test changes. --- .../library-tests/ir/ir/aliased_ir.expected | 37 ++++++------------- .../test/library-tests/ir/ir/raw_ir.expected | 30 +++++++++------ 2 files changed, 30 insertions(+), 37 deletions(-) diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected index 3ec42290d746..e1f8430d1607 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected @@ -17982,7 +17982,6 @@ ir.cpp: # 2504| m2504_6(unknown) = Chi : total:m2501_4, partial:m2504_5 # 2504| m2504_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2504_1 # 2504| m2504_8(ClassWithDestructor) = Chi : total:m2504_2, partial:m2504_7 -# 2505| v2505_1(void) = NoOp : # 2506| r2506_1(glval) = VariableAddress[x] : # 2506| r2506_2(glval) = FunctionAddress[~ClassWithDestructor] : # 2506| v2506_3(void) = Call[~ClassWithDestructor] : func:r2506_2, this:r2506_1 @@ -17991,18 +17990,11 @@ ir.cpp: # 2506| v2506_6(void) = ^IndirectReadSideEffect[-1] : &:r2506_1, m2504_8 # 2506| m2506_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2506_1 # 2506| m2506_8(ClassWithDestructor) = Chi : total:m2504_8, partial:m2506_7 -# 2506| r2506_9(glval) = VariableAddress[x] : -# 2506| r2506_10(glval) = FunctionAddress[~ClassWithDestructor] : -# 2506| v2506_11(void) = Call[~ClassWithDestructor] : func:r2506_10, this:r2506_9 -# 2506| m2506_12(unknown) = ^CallSideEffect : ~m2506_5 -# 2506| m2506_13(unknown) = Chi : total:m2506_5, partial:m2506_12 -# 2506| v2506_14(void) = ^IndirectReadSideEffect[-1] : &:r2506_9, m2506_8 -# 2506| m2506_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2506_9 -# 2506| m2506_16(ClassWithDestructor) = Chi : total:m2506_8, partial:m2506_15 +# 2505| v2505_1(void) = NoOp : #-----| Goto -> Block 2 # 2507| Block 2 -# 2507| m2507_1(unknown) = Phi : from 0:~m2501_4, from 1:~m2506_13 +# 2507| m2507_1(unknown) = Phi : from 0:~m2501_4, from 1:~m2506_5 # 2507| v2507_2(void) = NoOp : # 2508| v2508_1(void) = NoOp : # 2501| v2501_7(void) = ReturnVoid : @@ -18080,7 +18072,6 @@ ir.cpp: # 2524| m2524_6(unknown) = Chi : total:m2522_6, partial:m2524_5 # 2524| m2524_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2524_1 # 2524| m2524_8(ClassWithDestructor) = Chi : total:m2524_2, partial:m2524_7 -# 2525| v2525_1(void) = NoOp : # 2526| r2526_1(glval) = VariableAddress[x] : # 2526| r2526_2(glval) = FunctionAddress[~ClassWithDestructor] : # 2526| v2526_3(void) = Call[~ClassWithDestructor] : func:r2526_2, this:r2526_1 @@ -18097,24 +18088,20 @@ ir.cpp: # 2530| v2530_6(void) = ^IndirectReadSideEffect[-1] : &:r2530_1, m2522_8 # 2530| m2530_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2530_1 # 2530| m2530_8(ClassWithDestructor) = Chi : total:m2522_8, partial:m2530_7 -# 2526| r2526_9(glval) = VariableAddress[x] : -# 2526| r2526_10(glval) = FunctionAddress[~ClassWithDestructor] : -# 2526| v2526_11(void) = Call[~ClassWithDestructor] : func:r2526_10, this:r2526_9 -# 2526| m2526_12(unknown) = ^CallSideEffect : ~m2530_5 -# 2526| m2526_13(unknown) = Chi : total:m2530_5, partial:m2526_12 -# 2526| v2526_14(void) = ^IndirectReadSideEffect[-1] : &:r2526_9, m2526_8 -# 2526| m2526_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2526_9 -# 2526| m2526_16(ClassWithDestructor) = Chi : total:m2526_8, partial:m2526_15 -#-----| Goto -> Block 2 +# 2525| v2525_1(void) = NoOp : +#-----| Goto -> Block 3 # 2527| Block 2 -# 2527| m2527_1(unknown) = Phi : from 0:~m2522_6, from 1:~m2526_13 -# 2527| v2527_2(void) = NoOp : -# 2528| v2528_1(void) = NoOp : -# 2530| v2530_9(void) = NoOp : +# 2527| v2527_1(void) = NoOp : +# 2528| v2528_1(void) = NoOp : +#-----| Goto -> Block 3 + +# 2530| Block 3 +# 2530| m2530_9(unknown) = Phi : from 1:~m2530_5, from 2:~m2522_6 +# 2530| v2530_10(void) = NoOp : # 2531| v2531_1(void) = NoOp : # 2521| v2521_7(void) = ReturnVoid : -# 2521| v2521_8(void) = AliasedUse : ~m2527_1 +# 2521| v2521_8(void) = AliasedUse : ~m2530_9 # 2521| v2521_9(void) = ExitFunction : perf-regression.cpp: diff --git a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected index 0684dcba0b7b..d2ccd190ac29 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -16383,7 +16383,7 @@ ir.cpp: # 2502| r2502_2(int) = Load[c] : &:r2502_1, ~m? # 2502| v2502_3(void) = Switch : r2502_2 #-----| Case[0] -> Block 1 -#-----| Default -> Block 2 +#-----| Default -> Block 3 # 2503| Block 1 # 2503| v2503_1(void) = NoOp : @@ -16393,22 +16393,25 @@ ir.cpp: # 2504| v2504_4(void) = Call[ClassWithDestructor] : func:r2504_3, this:r2504_1 # 2504| mu2504_5(unknown) = ^CallSideEffect : ~m? # 2504| mu2504_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2504_1 -# 2505| v2505_1(void) = NoOp : # 2506| r2506_1(glval) = VariableAddress[x] : # 2506| r2506_2(glval) = FunctionAddress[~ClassWithDestructor] : # 2506| v2506_3(void) = Call[~ClassWithDestructor] : func:r2506_2, this:r2506_1 # 2506| mu2506_4(unknown) = ^CallSideEffect : ~m? # 2506| v2506_5(void) = ^IndirectReadSideEffect[-1] : &:r2506_1, ~m? # 2506| mu2506_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2506_1 +# 2505| v2505_1(void) = NoOp : +#-----| Goto -> Block 3 + +# 2506| Block 2 # 2506| r2506_7(glval) = VariableAddress[x] : # 2506| r2506_8(glval) = FunctionAddress[~ClassWithDestructor] : # 2506| v2506_9(void) = Call[~ClassWithDestructor] : func:r2506_8, this:r2506_7 # 2506| mu2506_10(unknown) = ^CallSideEffect : ~m? # 2506| v2506_11(void) = ^IndirectReadSideEffect[-1] : &:r2506_7, ~m? # 2506| mu2506_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2506_7 -#-----| Goto -> Block 2 +#-----| Goto -> Block 3 -# 2507| Block 2 +# 2507| Block 3 # 2507| v2507_1(void) = NoOp : # 2508| v2508_1(void) = NoOp : # 2501| v2501_6(void) = ReturnVoid : @@ -16477,7 +16480,7 @@ ir.cpp: # 2522| r2522_8(int) = Load[c] : &:r2522_7, ~m? # 2522| v2522_9(void) = Switch : r2522_8 #-----| Case[0] -> Block 1 -#-----| Default -> Block 2 +#-----| Default -> Block 3 # 2523| Block 1 # 2523| v2523_1(void) = NoOp : @@ -16487,7 +16490,6 @@ ir.cpp: # 2524| v2524_4(void) = Call[ClassWithDestructor] : func:r2524_3, this:r2524_1 # 2524| mu2524_5(unknown) = ^CallSideEffect : ~m? # 2524| mu2524_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2524_1 -# 2525| v2525_1(void) = NoOp : # 2526| r2526_1(glval) = VariableAddress[x] : # 2526| r2526_2(glval) = FunctionAddress[~ClassWithDestructor] : # 2526| v2526_3(void) = Call[~ClassWithDestructor] : func:r2526_2, this:r2526_1 @@ -16500,29 +16502,33 @@ ir.cpp: # 2530| mu2530_4(unknown) = ^CallSideEffect : ~m? # 2530| v2530_5(void) = ^IndirectReadSideEffect[-1] : &:r2530_1, ~m? # 2530| mu2530_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2530_1 +# 2525| v2525_1(void) = NoOp : +#-----| Goto -> Block 5 + +# 2526| Block 2 # 2526| r2526_7(glval) = VariableAddress[x] : # 2526| r2526_8(glval) = FunctionAddress[~ClassWithDestructor] : # 2526| v2526_9(void) = Call[~ClassWithDestructor] : func:r2526_8, this:r2526_7 # 2526| mu2526_10(unknown) = ^CallSideEffect : ~m? # 2526| v2526_11(void) = ^IndirectReadSideEffect[-1] : &:r2526_7, ~m? # 2526| mu2526_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2526_7 -#-----| Goto -> Block 2 +#-----| Goto -> Block 3 -# 2527| Block 2 +# 2527| Block 3 # 2527| v2527_1(void) = NoOp : # 2528| v2528_1(void) = NoOp : -#-----| Goto -> Block 4 +#-----| Goto -> Block 5 -# 2530| Block 3 +# 2530| Block 4 # 2530| r2530_7(glval) = VariableAddress[y] : # 2530| r2530_8(glval) = FunctionAddress[~ClassWithDestructor] : # 2530| v2530_9(void) = Call[~ClassWithDestructor] : func:r2530_8, this:r2530_7 # 2530| mu2530_10(unknown) = ^CallSideEffect : ~m? # 2530| v2530_11(void) = ^IndirectReadSideEffect[-1] : &:r2530_7, ~m? # 2530| mu2530_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2530_7 -#-----| Goto -> Block 4 +#-----| Goto -> Block 5 -# 2530| Block 4 +# 2530| Block 5 # 2530| v2530_13(void) = NoOp : # 2531| v2531_1(void) = NoOp : # 2521| v2521_6(void) = ReturnVoid : From 61ce7252e659bc346965a28581c6042b2c3f6daa Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 30 Apr 2024 16:12:54 +0100 Subject: [PATCH 132/238] C++: Update the alert message in 'cpp/iterator-to-expired-container'. --- .../CWE/CWE-416/IteratorToExpiredContainer.ql | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.ql b/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.ql index 51dfd3478ac6..139555cfa1d6 100644 --- a/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.ql +++ b/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.ql @@ -62,10 +62,9 @@ DataFlow::Node getADestroyedNode(DataFlow::Node n) { ) } -predicate destroyedToBeginSink(DataFlow::Node sink, FunctionCall fc) { +predicate destroyedToBeginSink(DataFlow::Node sink) { exists(CallInstruction call | call = sink.asOperand().(ThisArgumentOperand).getCall() and - fc = call.getUnconvertedResultExpression() and call.getStaticCallTarget() instanceof BeginOrEndFunction ) } @@ -90,7 +89,7 @@ private predicate qualifierToDestroyed(DataFlow::Node node1, DataFlow::Node node module Config0 implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { qualifierToDestroyed(_, source) } - predicate isSink(DataFlow::Node sink) { destroyedToBeginSink(sink, _) } + predicate isSink(DataFlow::Node sink) { destroyedToBeginSink(sink) } } module Flow0 = DataFlow::Global; @@ -150,9 +149,9 @@ module Config implements DataFlow::StateConfigSig { module Flow = DataFlow::GlobalWithState; -from Flow::PathNode source, Flow::PathNode sink, FunctionCall beginOrEnd, DataFlow::Node mid +from Flow::PathNode source, Flow::PathNode sink, DataFlow::Node mid where Flow::flowPath(source, sink) and - destroyedToBeginSink(sink.getNode(), beginOrEnd) and + destroyedToBeginSink(sink.getNode()) and sink.getState() = Config::DestroyedToBegin(mid) -select mid, "This object is destroyed before $@ is called.", beginOrEnd, beginOrEnd.toString() +select mid, "This object is destroyed at the end of the full-expression." From 3eddd3114f7996f1994c231c1683fa709422c69d Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 30 Apr 2024 16:14:30 +0100 Subject: [PATCH 133/238] C++: Accept test changes. --- .../IteratorToExpiredContainer.expected | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/IteratorToExpiredContainer/IteratorToExpiredContainer.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/IteratorToExpiredContainer/IteratorToExpiredContainer.expected index c29e7953ea64..f47e5d655b96 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/IteratorToExpiredContainer/IteratorToExpiredContainer.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/IteratorToExpiredContainer/IteratorToExpiredContainer.expected @@ -1,11 +1,6 @@ -| test.cpp:680:30:680:30 | call to operator[] | This object is destroyed before $@ is called. | test.cpp:680:17:680:17 | call to begin | call to begin | -| test.cpp:680:30:680:30 | call to operator[] | This object is destroyed before $@ is called. | test.cpp:680:17:680:17 | call to end | call to end | -| test.cpp:683:31:683:32 | call to at | This object is destroyed before $@ is called. | test.cpp:683:17:683:17 | call to begin | call to begin | -| test.cpp:683:31:683:32 | call to at | This object is destroyed before $@ is called. | test.cpp:683:17:683:17 | call to end | call to end | -| test.cpp:689:46:689:58 | pointer to ~vector output argument | This object is destroyed before $@ is called. | test.cpp:689:60:689:62 | call to end | call to end | -| test.cpp:702:27:702:27 | call to operator[] | This object is destroyed before $@ is called. | test.cpp:703:19:703:23 | call to begin | call to begin | -| test.cpp:702:27:702:27 | call to operator[] | This object is destroyed before $@ is called. | test.cpp:703:36:703:38 | call to end | call to end | -| test.cpp:727:23:727:23 | call to operator[] | This object is destroyed before $@ is called. | test.cpp:750:17:750:17 | call to begin | call to begin | -| test.cpp:727:23:727:23 | call to operator[] | This object is destroyed before $@ is called. | test.cpp:750:17:750:17 | call to end | call to end | -| test.cpp:735:23:735:23 | call to operator[] | This object is destroyed before $@ is called. | test.cpp:759:17:759:17 | call to begin | call to begin | -| test.cpp:735:23:735:23 | call to operator[] | This object is destroyed before $@ is called. | test.cpp:759:17:759:17 | call to end | call to end | +| test.cpp:680:30:680:30 | call to operator[] | This object is destroyed at the end of the full-expression. | +| test.cpp:683:31:683:32 | call to at | This object is destroyed at the end of the full-expression. | +| test.cpp:689:46:689:58 | pointer to ~vector output argument | This object is destroyed at the end of the full-expression. | +| test.cpp:702:27:702:27 | call to operator[] | This object is destroyed at the end of the full-expression. | +| test.cpp:727:23:727:23 | call to operator[] | This object is destroyed at the end of the full-expression. | +| test.cpp:735:23:735:23 | call to operator[] | This object is destroyed at the end of the full-expression. | From 708d12624f05ad8891864d499c64ff2ee3039e43 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 30 Apr 2024 16:32:32 +0100 Subject: [PATCH 134/238] C++: Update documentation on 'cpp/iterator-to-expired-container'. --- .../Security/CWE/CWE-416/IteratorToExpiredContainer.qhelp | 6 ++++++ .../IteratorToExpiredContainerExtendedLifetime-fixed.cpp | 6 ++++++ 2 files changed, 12 insertions(+) create mode 100644 cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainerExtendedLifetime-fixed.cpp diff --git a/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.qhelp b/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.qhelp index 19975b174932..176ead87de4c 100644 --- a/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.qhelp +++ b/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.qhelp @@ -30,6 +30,12 @@ This is because the temporary container is not bound to a rvalue reference.

    +

    +To fix lifetime_of_temp_not_extended consider rewriting the code so that the temporary's lifetime is extended. +In fixed_lifetime_of_temp_not_extended the lifetime of the temporary object has been extended by storing it in an rvalue reference. +

    + + diff --git a/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainerExtendedLifetime-fixed.cpp b/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainerExtendedLifetime-fixed.cpp new file mode 100644 index 000000000000..d113b4165ff7 --- /dev/null +++ b/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainerExtendedLifetime-fixed.cpp @@ -0,0 +1,6 @@ +void fixed_lifetime_of_temp_not_extended() { + auto&& v = get_vector(); + for(auto x : log_and_return_argument(v)) { + use(x); // GOOD: The lifetime of the container returned by `get_vector()` has been extended to the lifetime of `v`. + } +} From 07dd6d5c8dd13bb3a4a869add692d6b78a98cb15 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 30 Apr 2024 16:40:23 +0100 Subject: [PATCH 135/238] C++: Align 'break' statements. --- cpp/ql/test/library-tests/ir/ir/ir.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/ql/test/library-tests/ir/ir/ir.cpp b/cpp/ql/test/library-tests/ir/ir/ir.cpp index accee358e952..e6c8b90ea5c8 100644 --- a/cpp/ql/test/library-tests/ir/ir/ir.cpp +++ b/cpp/ql/test/library-tests/ir/ir/ir.cpp @@ -2513,7 +2513,7 @@ void destruction_in_switch_2(int c) { break; } default: { - break; + break; } } } @@ -2525,7 +2525,7 @@ void destruction_in_switch_3(int c) { break; } default: { - break; + break; } } } From 5843326b5cd772e0f3cf6027d6dadbe9136624d8 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 30 Apr 2024 21:12:30 +0200 Subject: [PATCH 136/238] C++: Update IR tests after better handling of init statements in the extractor --- .../library-tests/ir/ir/PrintAST.expected | 30 +++++ .../library-tests/ir/ir/aliased_ir.expected | 127 ++++++++++++------ .../test/library-tests/ir/ir/raw_ir.expected | 122 ++++++++++------- 3 files changed, 190 insertions(+), 89 deletions(-) diff --git a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected index 0897b3f25c3e..cf5125b1ccf2 100644 --- a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected +++ b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected @@ -19411,6 +19411,12 @@ ir.cpp: # 2207| Value = [CharLiteral] 97 # 2207| ValueCategory = prvalue # 2208| getStmt(2): [BreakStmt] break; +# 2212| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2212| Type = [VoidType] void +# 2212| ValueCategory = prvalue +# 2212| getQualifier(): [VariableAccess] x +# 2212| Type = [Class] ClassWithDestructor +# 2212| ValueCategory = lvalue # 2209| getStmt(3): [SwitchCase] default: # 2210| getStmt(4): [ExprStmt] ExprStmt # 2210| getExpr(): [FunctionCall] call to set_x @@ -19424,6 +19430,12 @@ ir.cpp: # 2210| Value = [CharLiteral] 98 # 2210| ValueCategory = prvalue # 2211| getStmt(5): [BreakStmt] break; +# 2212| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2212| Type = [VoidType] void +# 2212| ValueCategory = prvalue +# 2212| getQualifier(): [VariableAccess] x +# 2212| Type = [Class] ClassWithDestructor +# 2212| ValueCategory = lvalue # 2212| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor # 2212| Type = [VoidType] void # 2212| ValueCategory = prvalue @@ -22504,9 +22516,21 @@ ir.cpp: # 2512| ValueCategory = prvalue # 2512| getStmt(1): [BlockStmt] { ... } # 2513| getStmt(0): [BreakStmt] break; +# 2518| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2518| Type = [VoidType] void +# 2518| ValueCategory = prvalue +# 2518| getQualifier(): [VariableAccess] y +# 2518| Type = [Class] ClassWithDestructor +# 2518| ValueCategory = lvalue # 2515| getStmt(2): [SwitchCase] default: # 2515| getStmt(3): [BlockStmt] { ... } # 2516| getStmt(0): [BreakStmt] break; +# 2518| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2518| Type = [VoidType] void +# 2518| ValueCategory = prvalue +# 2518| getQualifier(): [VariableAccess] y +# 2518| Type = [Class] ClassWithDestructor +# 2518| ValueCategory = lvalue # 2518| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor # 2518| Type = [VoidType] void # 2518| ValueCategory = prvalue @@ -22567,6 +22591,12 @@ ir.cpp: # 2527| getStmt(2): [SwitchCase] default: # 2527| getStmt(3): [BlockStmt] { ... } # 2528| getStmt(0): [BreakStmt] break; +# 2530| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2530| Type = [VoidType] void +# 2530| ValueCategory = prvalue +# 2530| getQualifier(): [VariableAccess] y +# 2530| Type = [Class] ClassWithDestructor +# 2530| ValueCategory = lvalue # 2530| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor # 2530| Type = [VoidType] void # 2530| ValueCategory = prvalue diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected index e1f8430d1607..3502252f6011 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected @@ -15438,42 +15438,58 @@ ir.cpp: #-----| Default -> Block 6 # 2206| Block 5 -# 2206| v2206_1(void) = NoOp : -# 2207| r2207_1(glval) = VariableAddress[x] : -# 2207| r2207_2(glval) = FunctionAddress[set_x] : -# 2207| r2207_3(char) = Constant[97] : -# 2207| v2207_4(void) = Call[set_x] : func:r2207_2, this:r2207_1, 0:r2207_3 -# 2207| m2207_5(unknown) = ^CallSideEffect : ~m2205_6 -# 2207| m2207_6(unknown) = Chi : total:m2205_6, partial:m2207_5 -# 2207| v2207_7(void) = ^IndirectReadSideEffect[-1] : &:r2207_1, m2205_8 -# 2207| m2207_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2207_1 -# 2207| m2207_9(ClassWithDestructor) = Chi : total:m2205_8, partial:m2207_8 -# 2208| v2208_1(void) = NoOp : +# 2206| v2206_1(void) = NoOp : +# 2207| r2207_1(glval) = VariableAddress[x] : +# 2207| r2207_2(glval) = FunctionAddress[set_x] : +# 2207| r2207_3(char) = Constant[97] : +# 2207| v2207_4(void) = Call[set_x] : func:r2207_2, this:r2207_1, 0:r2207_3 +# 2207| m2207_5(unknown) = ^CallSideEffect : ~m2205_6 +# 2207| m2207_6(unknown) = Chi : total:m2205_6, partial:m2207_5 +# 2207| v2207_7(void) = ^IndirectReadSideEffect[-1] : &:r2207_1, m2205_8 +# 2207| m2207_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2207_1 +# 2207| m2207_9(ClassWithDestructor) = Chi : total:m2205_8, partial:m2207_8 +# 2212| r2212_1(glval) = VariableAddress[x] : +# 2212| r2212_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2212| v2212_3(void) = Call[~ClassWithDestructor] : func:r2212_2, this:r2212_1 +# 2212| m2212_4(unknown) = ^CallSideEffect : ~m2207_6 +# 2212| m2212_5(unknown) = Chi : total:m2207_6, partial:m2212_4 +# 2212| v2212_6(void) = ^IndirectReadSideEffect[-1] : &:r2212_1, m2207_9 +# 2212| m2212_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2212_1 +# 2212| m2212_8(ClassWithDestructor) = Chi : total:m2207_9, partial:m2212_7 +# 2208| v2208_1(void) = NoOp : #-----| Goto -> Block 7 # 2209| Block 6 -# 2209| v2209_1(void) = NoOp : -# 2210| r2210_1(glval) = VariableAddress[x] : -# 2210| r2210_2(glval) = FunctionAddress[set_x] : -# 2210| r2210_3(char) = Constant[98] : -# 2210| v2210_4(void) = Call[set_x] : func:r2210_2, this:r2210_1, 0:r2210_3 -# 2210| m2210_5(unknown) = ^CallSideEffect : ~m2205_6 -# 2210| m2210_6(unknown) = Chi : total:m2205_6, partial:m2210_5 -# 2210| v2210_7(void) = ^IndirectReadSideEffect[-1] : &:r2210_1, m2205_8 -# 2210| m2210_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2210_1 -# 2210| m2210_9(ClassWithDestructor) = Chi : total:m2205_8, partial:m2210_8 -# 2211| v2211_1(void) = NoOp : +# 2209| v2209_1(void) = NoOp : +# 2210| r2210_1(glval) = VariableAddress[x] : +# 2210| r2210_2(glval) = FunctionAddress[set_x] : +# 2210| r2210_3(char) = Constant[98] : +# 2210| v2210_4(void) = Call[set_x] : func:r2210_2, this:r2210_1, 0:r2210_3 +# 2210| m2210_5(unknown) = ^CallSideEffect : ~m2205_6 +# 2210| m2210_6(unknown) = Chi : total:m2205_6, partial:m2210_5 +# 2210| v2210_7(void) = ^IndirectReadSideEffect[-1] : &:r2210_1, m2205_8 +# 2210| m2210_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2210_1 +# 2210| m2210_9(ClassWithDestructor) = Chi : total:m2205_8, partial:m2210_8 +# 2212| r2212_9(glval) = VariableAddress[x] : +# 2212| r2212_10(glval) = FunctionAddress[~ClassWithDestructor] : +# 2212| v2212_11(void) = Call[~ClassWithDestructor] : func:r2212_10, this:r2212_9 +# 2212| m2212_12(unknown) = ^CallSideEffect : ~m2210_6 +# 2212| m2212_13(unknown) = Chi : total:m2210_6, partial:m2212_12 +# 2212| v2212_14(void) = ^IndirectReadSideEffect[-1] : &:r2212_9, m2210_9 +# 2212| m2212_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2212_9 +# 2212| m2212_16(ClassWithDestructor) = Chi : total:m2210_9, partial:m2212_15 +# 2211| v2211_1(void) = NoOp : #-----| Goto -> Block 7 # 2212| Block 7 -# 2212| m2212_1(unknown) = Phi : from 5:~m2207_6, from 6:~m2210_6 -# 2212| v2212_2(void) = NoOp : +# 2212| m2212_17(unknown) = Phi : from 5:~m2212_5, from 6:~m2212_13 +# 2212| v2212_18(void) = NoOp : # 2214| r2214_1(glval) = VariableAddress[x] : # 2214| m2214_2(ClassWithDestructor) = Uninitialized[x] : &:r2214_1 # 2214| r2214_3(glval) = FunctionAddress[ClassWithDestructor] : # 2214| v2214_4(void) = Call[ClassWithDestructor] : func:r2214_3, this:r2214_1 -# 2214| m2214_5(unknown) = ^CallSideEffect : ~m2212_1 -# 2214| m2214_6(unknown) = Chi : total:m2212_1, partial:m2214_5 +# 2214| m2214_5(unknown) = ^CallSideEffect : ~m2212_17 +# 2214| m2214_6(unknown) = Chi : total:m2212_17, partial:m2214_5 # 2214| m2214_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2214_1 # 2214| m2214_8(ClassWithDestructor) = Chi : total:m2214_2, partial:m2214_7 # 2215| r2215_1(glval>) = VariableAddress[ys] : @@ -18024,21 +18040,38 @@ ir.cpp: #-----| Default -> Block 2 # 2512| Block 1 -# 2512| v2512_1(void) = NoOp : -# 2513| v2513_1(void) = NoOp : +# 2512| v2512_1(void) = NoOp : +# 2518| r2518_1(glval) = VariableAddress[y] : +# 2518| r2518_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2518| v2518_3(void) = Call[~ClassWithDestructor] : func:r2518_2, this:r2518_1 +# 2518| m2518_4(unknown) = ^CallSideEffect : ~m2511_6 +# 2518| m2518_5(unknown) = Chi : total:m2511_6, partial:m2518_4 +# 2518| v2518_6(void) = ^IndirectReadSideEffect[-1] : &:r2518_1, m2511_8 +# 2518| m2518_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2518_1 +# 2518| m2518_8(ClassWithDestructor) = Chi : total:m2511_8, partial:m2518_7 +# 2513| v2513_1(void) = NoOp : #-----| Goto -> Block 3 # 2515| Block 2 -# 2515| v2515_1(void) = NoOp : -# 2516| v2516_1(void) = NoOp : +# 2515| v2515_1(void) = NoOp : +# 2518| r2518_9(glval) = VariableAddress[y] : +# 2518| r2518_10(glval) = FunctionAddress[~ClassWithDestructor] : +# 2518| v2518_11(void) = Call[~ClassWithDestructor] : func:r2518_10, this:r2518_9 +# 2518| m2518_12(unknown) = ^CallSideEffect : ~m2511_6 +# 2518| m2518_13(unknown) = Chi : total:m2511_6, partial:m2518_12 +# 2518| v2518_14(void) = ^IndirectReadSideEffect[-1] : &:r2518_9, m2511_8 +# 2518| m2518_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2518_9 +# 2518| m2518_16(ClassWithDestructor) = Chi : total:m2511_8, partial:m2518_15 +# 2516| v2516_1(void) = NoOp : #-----| Goto -> Block 3 # 2518| Block 3 -# 2518| v2518_1(void) = NoOp : -# 2519| v2519_1(void) = NoOp : -# 2510| v2510_7(void) = ReturnVoid : -# 2510| v2510_8(void) = AliasedUse : ~m2511_6 -# 2510| v2510_9(void) = ExitFunction : +# 2518| m2518_17(unknown) = Phi : from 1:~m2518_5, from 2:~m2518_13 +# 2518| v2518_18(void) = NoOp : +# 2519| v2519_1(void) = NoOp : +# 2510| v2510_7(void) = ReturnVoid : +# 2510| v2510_8(void) = AliasedUse : ~m2518_17 +# 2510| v2510_9(void) = ExitFunction : # 2521| void destruction_in_switch_3(int) # 2521| Block 0 @@ -18092,17 +18125,25 @@ ir.cpp: #-----| Goto -> Block 3 # 2527| Block 2 -# 2527| v2527_1(void) = NoOp : -# 2528| v2528_1(void) = NoOp : +# 2527| v2527_1(void) = NoOp : +# 2530| r2530_9(glval) = VariableAddress[y] : +# 2530| r2530_10(glval) = FunctionAddress[~ClassWithDestructor] : +# 2530| v2530_11(void) = Call[~ClassWithDestructor] : func:r2530_10, this:r2530_9 +# 2530| m2530_12(unknown) = ^CallSideEffect : ~m2522_6 +# 2530| m2530_13(unknown) = Chi : total:m2522_6, partial:m2530_12 +# 2530| v2530_14(void) = ^IndirectReadSideEffect[-1] : &:r2530_9, m2522_8 +# 2530| m2530_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2530_9 +# 2530| m2530_16(ClassWithDestructor) = Chi : total:m2522_8, partial:m2530_15 +# 2528| v2528_1(void) = NoOp : #-----| Goto -> Block 3 # 2530| Block 3 -# 2530| m2530_9(unknown) = Phi : from 1:~m2530_5, from 2:~m2522_6 -# 2530| v2530_10(void) = NoOp : -# 2531| v2531_1(void) = NoOp : -# 2521| v2521_7(void) = ReturnVoid : -# 2521| v2521_8(void) = AliasedUse : ~m2530_9 -# 2521| v2521_9(void) = ExitFunction : +# 2530| m2530_17(unknown) = Phi : from 1:~m2530_5, from 2:~m2530_13 +# 2530| v2530_18(void) = NoOp : +# 2531| v2531_1(void) = NoOp : +# 2521| v2521_7(void) = ReturnVoid : +# 2521| v2521_8(void) = AliasedUse : ~m2530_17 +# 2521| v2521_9(void) = ExitFunction : perf-regression.cpp: # 6| void Big::Big() diff --git a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected index d2ccd190ac29..e454a6ba92eb 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -14207,40 +14207,52 @@ ir.cpp: #-----| Default -> Block 8 # 2206| Block 7 -# 2206| v2206_1(void) = NoOp : -# 2207| r2207_1(glval) = VariableAddress[x] : -# 2207| r2207_2(glval) = FunctionAddress[set_x] : -# 2207| r2207_3(char) = Constant[97] : -# 2207| v2207_4(void) = Call[set_x] : func:r2207_2, this:r2207_1, 0:r2207_3 -# 2207| mu2207_5(unknown) = ^CallSideEffect : ~m? -# 2207| v2207_6(void) = ^IndirectReadSideEffect[-1] : &:r2207_1, ~m? -# 2207| mu2207_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2207_1 -# 2208| v2208_1(void) = NoOp : -#-----| Goto -> Block 10 - -# 2209| Block 8 -# 2209| v2209_1(void) = NoOp : -# 2210| r2210_1(glval) = VariableAddress[x] : -# 2210| r2210_2(glval) = FunctionAddress[set_x] : -# 2210| r2210_3(char) = Constant[98] : -# 2210| v2210_4(void) = Call[set_x] : func:r2210_2, this:r2210_1, 0:r2210_3 -# 2210| mu2210_5(unknown) = ^CallSideEffect : ~m? -# 2210| v2210_6(void) = ^IndirectReadSideEffect[-1] : &:r2210_1, ~m? -# 2210| mu2210_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2210_1 -# 2211| v2211_1(void) = NoOp : -#-----| Goto -> Block 10 - -# 2212| Block 9 +# 2206| v2206_1(void) = NoOp : +# 2207| r2207_1(glval) = VariableAddress[x] : +# 2207| r2207_2(glval) = FunctionAddress[set_x] : +# 2207| r2207_3(char) = Constant[97] : +# 2207| v2207_4(void) = Call[set_x] : func:r2207_2, this:r2207_1, 0:r2207_3 +# 2207| mu2207_5(unknown) = ^CallSideEffect : ~m? +# 2207| v2207_6(void) = ^IndirectReadSideEffect[-1] : &:r2207_1, ~m? +# 2207| mu2207_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2207_1 # 2212| r2212_1(glval) = VariableAddress[x] : # 2212| r2212_2(glval) = FunctionAddress[~ClassWithDestructor] : # 2212| v2212_3(void) = Call[~ClassWithDestructor] : func:r2212_2, this:r2212_1 # 2212| mu2212_4(unknown) = ^CallSideEffect : ~m? # 2212| v2212_5(void) = ^IndirectReadSideEffect[-1] : &:r2212_1, ~m? # 2212| mu2212_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2212_1 +# 2208| v2208_1(void) = NoOp : +#-----| Goto -> Block 10 + +# 2209| Block 8 +# 2209| v2209_1(void) = NoOp : +# 2210| r2210_1(glval) = VariableAddress[x] : +# 2210| r2210_2(glval) = FunctionAddress[set_x] : +# 2210| r2210_3(char) = Constant[98] : +# 2210| v2210_4(void) = Call[set_x] : func:r2210_2, this:r2210_1, 0:r2210_3 +# 2210| mu2210_5(unknown) = ^CallSideEffect : ~m? +# 2210| v2210_6(void) = ^IndirectReadSideEffect[-1] : &:r2210_1, ~m? +# 2210| mu2210_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2210_1 +# 2212| r2212_7(glval) = VariableAddress[x] : +# 2212| r2212_8(glval) = FunctionAddress[~ClassWithDestructor] : +# 2212| v2212_9(void) = Call[~ClassWithDestructor] : func:r2212_8, this:r2212_7 +# 2212| mu2212_10(unknown) = ^CallSideEffect : ~m? +# 2212| v2212_11(void) = ^IndirectReadSideEffect[-1] : &:r2212_7, ~m? +# 2212| mu2212_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2212_7 +# 2211| v2211_1(void) = NoOp : +#-----| Goto -> Block 10 + +# 2212| Block 9 +# 2212| r2212_13(glval) = VariableAddress[x] : +# 2212| r2212_14(glval) = FunctionAddress[~ClassWithDestructor] : +# 2212| v2212_15(void) = Call[~ClassWithDestructor] : func:r2212_14, this:r2212_13 +# 2212| mu2212_16(unknown) = ^CallSideEffect : ~m? +# 2212| v2212_17(void) = ^IndirectReadSideEffect[-1] : &:r2212_13, ~m? +# 2212| mu2212_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2212_13 #-----| Goto -> Block 10 # 2212| Block 10 -# 2212| v2212_7(void) = NoOp : +# 2212| v2212_19(void) = NoOp : # 2214| r2214_1(glval) = VariableAddress[x] : # 2214| mu2214_2(ClassWithDestructor) = Uninitialized[x] : &:r2214_1 # 2214| r2214_3(glval) = FunctionAddress[ClassWithDestructor] : @@ -16438,30 +16450,42 @@ ir.cpp: #-----| Default -> Block 2 # 2512| Block 1 -# 2512| v2512_1(void) = NoOp : -# 2513| v2513_1(void) = NoOp : -#-----| Goto -> Block 4 - -# 2515| Block 2 -# 2515| v2515_1(void) = NoOp : -# 2516| v2516_1(void) = NoOp : -#-----| Goto -> Block 4 - -# 2518| Block 3 +# 2512| v2512_1(void) = NoOp : # 2518| r2518_1(glval) = VariableAddress[y] : # 2518| r2518_2(glval) = FunctionAddress[~ClassWithDestructor] : # 2518| v2518_3(void) = Call[~ClassWithDestructor] : func:r2518_2, this:r2518_1 # 2518| mu2518_4(unknown) = ^CallSideEffect : ~m? # 2518| v2518_5(void) = ^IndirectReadSideEffect[-1] : &:r2518_1, ~m? # 2518| mu2518_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2518_1 +# 2513| v2513_1(void) = NoOp : +#-----| Goto -> Block 4 + +# 2515| Block 2 +# 2515| v2515_1(void) = NoOp : +# 2518| r2518_7(glval) = VariableAddress[y] : +# 2518| r2518_8(glval) = FunctionAddress[~ClassWithDestructor] : +# 2518| v2518_9(void) = Call[~ClassWithDestructor] : func:r2518_8, this:r2518_7 +# 2518| mu2518_10(unknown) = ^CallSideEffect : ~m? +# 2518| v2518_11(void) = ^IndirectReadSideEffect[-1] : &:r2518_7, ~m? +# 2518| mu2518_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2518_7 +# 2516| v2516_1(void) = NoOp : +#-----| Goto -> Block 4 + +# 2518| Block 3 +# 2518| r2518_13(glval) = VariableAddress[y] : +# 2518| r2518_14(glval) = FunctionAddress[~ClassWithDestructor] : +# 2518| v2518_15(void) = Call[~ClassWithDestructor] : func:r2518_14, this:r2518_13 +# 2518| mu2518_16(unknown) = ^CallSideEffect : ~m? +# 2518| v2518_17(void) = ^IndirectReadSideEffect[-1] : &:r2518_13, ~m? +# 2518| mu2518_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2518_13 #-----| Goto -> Block 4 # 2518| Block 4 -# 2518| v2518_7(void) = NoOp : -# 2519| v2519_1(void) = NoOp : -# 2510| v2510_6(void) = ReturnVoid : -# 2510| v2510_7(void) = AliasedUse : ~m? -# 2510| v2510_8(void) = ExitFunction : +# 2518| v2518_19(void) = NoOp : +# 2519| v2519_1(void) = NoOp : +# 2510| v2510_6(void) = ReturnVoid : +# 2510| v2510_7(void) = AliasedUse : ~m? +# 2510| v2510_8(void) = ExitFunction : # 2521| void destruction_in_switch_3(int) # 2521| Block 0 @@ -16515,21 +16539,27 @@ ir.cpp: #-----| Goto -> Block 3 # 2527| Block 3 -# 2527| v2527_1(void) = NoOp : -# 2528| v2528_1(void) = NoOp : -#-----| Goto -> Block 5 - -# 2530| Block 4 +# 2527| v2527_1(void) = NoOp : # 2530| r2530_7(glval) = VariableAddress[y] : # 2530| r2530_8(glval) = FunctionAddress[~ClassWithDestructor] : # 2530| v2530_9(void) = Call[~ClassWithDestructor] : func:r2530_8, this:r2530_7 # 2530| mu2530_10(unknown) = ^CallSideEffect : ~m? # 2530| v2530_11(void) = ^IndirectReadSideEffect[-1] : &:r2530_7, ~m? # 2530| mu2530_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2530_7 +# 2528| v2528_1(void) = NoOp : +#-----| Goto -> Block 5 + +# 2530| Block 4 +# 2530| r2530_13(glval) = VariableAddress[y] : +# 2530| r2530_14(glval) = FunctionAddress[~ClassWithDestructor] : +# 2530| v2530_15(void) = Call[~ClassWithDestructor] : func:r2530_14, this:r2530_13 +# 2530| mu2530_16(unknown) = ^CallSideEffect : ~m? +# 2530| v2530_17(void) = ^IndirectReadSideEffect[-1] : &:r2530_13, ~m? +# 2530| mu2530_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2530_13 #-----| Goto -> Block 5 # 2530| Block 5 -# 2530| v2530_13(void) = NoOp : +# 2530| v2530_19(void) = NoOp : # 2531| v2531_1(void) = NoOp : # 2521| v2521_6(void) = ReturnVoid : # 2521| v2521_7(void) = AliasedUse : ~m? From 3c70a2d7dfe8e5b7a5c3a1360ab53e0a2d955d3e Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Wed, 1 May 2024 12:30:38 +0200 Subject: [PATCH 137/238] C++: Update test results after extractor changes --- .../stackvariables/graphable.expected | 474 +++++++++--------- 1 file changed, 237 insertions(+), 237 deletions(-) diff --git a/cpp/ql/test/successor-tests/stackvariables/stackvariables/graphable.expected b/cpp/ql/test/successor-tests/stackvariables/stackvariables/graphable.expected index c4e250d591f8..e90d571bce4a 100644 --- a/cpp/ql/test/successor-tests/stackvariables/stackvariables/graphable.expected +++ b/cpp/ql/test/successor-tests/stackvariables/stackvariables/graphable.expected @@ -41,99 +41,99 @@ | BoxedInt::~BoxedInt | true | 481 | 483 | | | BoxedInt::~BoxedInt | true | 483 | 222 | | | BoxedInt::~BoxedInt | true | 485 | 474 | | -| NonTrivial::NonTrivial | false | 543 | 543 | NonTrivial | -| NonTrivial::operator= | false | 549 | 549 | operator= | -| NonTrivial::~NonTrivial | false | 557 | 557 | ~NonTrivial | -| NonTrivial::~NonTrivial | false | 563 | 563 | return ... | -| NonTrivial::~NonTrivial | false | 565 | 565 | { ... } | -| NonTrivial::~NonTrivial | true | 563 | 557 | | -| NonTrivial::~NonTrivial | true | 565 | 563 | | +| NonTrivial::NonTrivial | false | 544 | 544 | NonTrivial | +| NonTrivial::operator= | false | 550 | 550 | operator= | +| NonTrivial::~NonTrivial | false | 558 | 558 | ~NonTrivial | +| NonTrivial::~NonTrivial | false | 564 | 564 | return ... | +| NonTrivial::~NonTrivial | false | 566 | 566 | { ... } | +| NonTrivial::~NonTrivial | true | 564 | 558 | | +| NonTrivial::~NonTrivial | true | 566 | 564 | | | __va_list_tag::operator= | false | 66 | 66 | operator= | | __va_list_tag::operator= | false | 72 | 72 | operator= | -| early_return | false | 799 | 799 | early_return | -| early_return | false | 807 | 807 | declaration | -| early_return | false | 812 | 812 | if (...) ... | -| early_return | false | 814 | 814 | x | -| early_return | false | 816 | 816 | (bool)... | -| early_return | false | 820 | 820 | declaration | -| early_return | false | 822 | 822 | return ... | -| early_return | false | 824 | 824 | { ... } | -| early_return | false | 826 | 826 | declaration | -| early_return | false | 831 | 831 | return ... | -| early_return | false | 833 | 833 | { ... } | -| early_return | false | 835 | 835 | inner | -| early_return | false | 837 | 837 | call to inner.~NonTrivial | -| early_return | false | 838 | 838 | before | -| early_return | false | 840 | 840 | call to before.~NonTrivial | -| early_return | false | 841 | 841 | inner | -| early_return | false | 842 | 842 | call to inner.~NonTrivial | -| early_return | false | 843 | 843 | before | -| early_return | false | 844 | 844 | call to before.~NonTrivial | -| early_return | false | 845 | 845 | after | -| early_return | false | 846 | 846 | call to after.~NonTrivial | -| early_return | true | 807 | 812 | | -| early_return | true | 812 | 814 | | -| early_return | true | 814 | 824 | T | -| early_return | true | 814 | 826 | F | -| early_return | true | 820 | 822 | | -| early_return | true | 822 | 841 | | -| early_return | true | 824 | 820 | | -| early_return | true | 826 | 831 | | -| early_return | true | 831 | 845 | | -| early_return | true | 833 | 807 | | -| early_return | true | 835 | 837 | | -| early_return | true | 837 | 826 | | -| early_return | true | 838 | 840 | | -| early_return | true | 840 | 799 | | -| early_return | true | 841 | 842 | | -| early_return | true | 842 | 838 | | -| early_return | true | 843 | 844 | | -| early_return | true | 844 | 799 | | -| early_return | true | 845 | 846 | | -| early_return | true | 846 | 843 | | -| early_throw | false | 749 | 749 | early_throw | -| early_throw | false | 757 | 757 | declaration | -| early_throw | false | 762 | 762 | if (...) ... | -| early_throw | false | 764 | 764 | x | -| early_throw | false | 766 | 766 | (bool)... | -| early_throw | false | 770 | 770 | declaration | -| early_throw | false | 772 | 772 | ExprStmt | -| early_throw | false | 774 | 774 | re-throw exception | -| early_throw | false | 776 | 776 | { ... } | -| early_throw | false | 778 | 778 | declaration | -| early_throw | false | 783 | 783 | return ... | -| early_throw | false | 785 | 785 | { ... } | -| early_throw | false | 787 | 787 | inner | -| early_throw | false | 789 | 789 | call to inner.~NonTrivial | -| early_throw | false | 790 | 790 | before | -| early_throw | false | 792 | 792 | call to before.~NonTrivial | -| early_throw | false | 793 | 793 | inner | -| early_throw | false | 794 | 794 | call to inner.~NonTrivial | -| early_throw | false | 795 | 795 | before | -| early_throw | false | 796 | 796 | call to before.~NonTrivial | -| early_throw | false | 797 | 797 | after | -| early_throw | false | 798 | 798 | call to after.~NonTrivial | -| early_throw | true | 757 | 762 | | -| early_throw | true | 762 | 764 | | -| early_throw | true | 764 | 776 | T | -| early_throw | true | 764 | 778 | F | -| early_throw | true | 770 | 772 | | -| early_throw | true | 772 | 774 | | -| early_throw | true | 774 | 793 | | -| early_throw | true | 776 | 770 | | -| early_throw | true | 778 | 783 | | -| early_throw | true | 783 | 797 | | -| early_throw | true | 785 | 757 | | -| early_throw | true | 787 | 789 | | -| early_throw | true | 789 | 778 | | -| early_throw | true | 790 | 792 | | -| early_throw | true | 792 | 749 | | -| early_throw | true | 793 | 794 | | -| early_throw | true | 794 | 790 | | -| early_throw | true | 795 | 796 | | -| early_throw | true | 796 | 749 | | -| early_throw | true | 797 | 798 | | -| early_throw | true | 798 | 795 | | +| early_return | false | 800 | 800 | early_return | +| early_return | false | 808 | 808 | declaration | +| early_return | false | 813 | 813 | if (...) ... | +| early_return | false | 815 | 815 | x | +| early_return | false | 817 | 817 | (bool)... | +| early_return | false | 821 | 821 | declaration | +| early_return | false | 823 | 823 | return ... | +| early_return | false | 825 | 825 | { ... } | +| early_return | false | 827 | 827 | declaration | +| early_return | false | 832 | 832 | return ... | +| early_return | false | 834 | 834 | { ... } | +| early_return | false | 836 | 836 | before | +| early_return | false | 838 | 838 | call to before.~NonTrivial | +| early_return | false | 839 | 839 | inner | +| early_return | false | 841 | 841 | call to inner.~NonTrivial | +| early_return | false | 842 | 842 | inner | +| early_return | false | 843 | 843 | call to inner.~NonTrivial | +| early_return | false | 844 | 844 | before | +| early_return | false | 845 | 845 | call to before.~NonTrivial | +| early_return | false | 846 | 846 | after | +| early_return | false | 847 | 847 | call to after.~NonTrivial | +| early_return | true | 808 | 813 | | +| early_return | true | 813 | 815 | | +| early_return | true | 815 | 825 | T | +| early_return | true | 815 | 827 | F | +| early_return | true | 821 | 823 | | +| early_return | true | 823 | 839 | | +| early_return | true | 825 | 821 | | +| early_return | true | 827 | 832 | | +| early_return | true | 832 | 846 | | +| early_return | true | 834 | 808 | | +| early_return | true | 836 | 838 | | +| early_return | true | 838 | 800 | | +| early_return | true | 839 | 841 | | +| early_return | true | 841 | 836 | | +| early_return | true | 842 | 843 | | +| early_return | true | 843 | 827 | | +| early_return | true | 844 | 845 | | +| early_return | true | 845 | 800 | | +| early_return | true | 846 | 847 | | +| early_return | true | 847 | 844 | | +| early_throw | false | 750 | 750 | early_throw | +| early_throw | false | 758 | 758 | declaration | +| early_throw | false | 763 | 763 | if (...) ... | +| early_throw | false | 765 | 765 | x | +| early_throw | false | 767 | 767 | (bool)... | +| early_throw | false | 771 | 771 | declaration | +| early_throw | false | 773 | 773 | ExprStmt | +| early_throw | false | 775 | 775 | re-throw exception | +| early_throw | false | 777 | 777 | { ... } | +| early_throw | false | 779 | 779 | declaration | +| early_throw | false | 784 | 784 | return ... | +| early_throw | false | 786 | 786 | { ... } | +| early_throw | false | 788 | 788 | before | +| early_throw | false | 790 | 790 | call to before.~NonTrivial | +| early_throw | false | 791 | 791 | inner | +| early_throw | false | 793 | 793 | call to inner.~NonTrivial | +| early_throw | false | 794 | 794 | inner | +| early_throw | false | 795 | 795 | call to inner.~NonTrivial | +| early_throw | false | 796 | 796 | before | +| early_throw | false | 797 | 797 | call to before.~NonTrivial | +| early_throw | false | 798 | 798 | after | +| early_throw | false | 799 | 799 | call to after.~NonTrivial | +| early_throw | true | 758 | 763 | | +| early_throw | true | 763 | 765 | | +| early_throw | true | 765 | 777 | T | +| early_throw | true | 765 | 779 | F | +| early_throw | true | 771 | 773 | | +| early_throw | true | 773 | 775 | | +| early_throw | true | 775 | 791 | | +| early_throw | true | 777 | 771 | | +| early_throw | true | 779 | 784 | | +| early_throw | true | 784 | 798 | | +| early_throw | true | 786 | 758 | | +| early_throw | true | 788 | 790 | | +| early_throw | true | 790 | 750 | | +| early_throw | true | 791 | 793 | | +| early_throw | true | 793 | 788 | | +| early_throw | true | 794 | 795 | | +| early_throw | true | 795 | 779 | | +| early_throw | true | 796 | 797 | | +| early_throw | true | 797 | 750 | | +| early_throw | true | 798 | 799 | | +| early_throw | true | 799 | 796 | | | for_decl_bind | false | 153 | 153 | for_decl_bind | | for_decl_bind | false | 161 | 161 | for(...;...;...) ... | | for_decl_bind | false | 164 | 164 | call to BoxedInt | @@ -194,108 +194,108 @@ | for_decl_bind | true | 225 | 219 | | | for_decl_bind | true | 226 | 227 | | | for_decl_bind | true | 227 | 182 | | -| for_loop_scope | false | 698 | 698 | for_loop_scope | -| for_loop_scope | false | 706 | 706 | declaration | -| for_loop_scope | false | 711 | 711 | for(...;...;...) ... | -| for_loop_scope | false | 716 | 716 | x | -| for_loop_scope | false | 720 | 720 | 10 | -| for_loop_scope | false | 721 | 721 | ... < ... | -| for_loop_scope | false | 726 | 726 | declaration | -| for_loop_scope | false | 728 | 728 | { ... } | -| for_loop_scope | false | 730 | 730 | declaration | -| for_loop_scope | false | 732 | 732 | x | -| for_loop_scope | false | 734 | 734 | ++ ... | -| for_loop_scope | false | 736 | 736 | return ... | -| for_loop_scope | false | 738 | 738 | { ... } | -| for_loop_scope | false | 740 | 740 | for_scope | -| for_loop_scope | false | 742 | 742 | call to for_scope.~NonTrivial | -| for_loop_scope | false | 743 | 743 | inner_scope | -| for_loop_scope | false | 745 | 745 | call to inner_scope.~NonTrivial | -| for_loop_scope | false | 746 | 746 | outer_scope | -| for_loop_scope | false | 748 | 748 | call to outer_scope.~NonTrivial | -| for_loop_scope | true | 706 | 711 | | -| for_loop_scope | true | 711 | 730 | | -| for_loop_scope | true | 716 | 720 | | -| for_loop_scope | true | 720 | 721 | | -| for_loop_scope | true | 721 | 728 | T | -| for_loop_scope | true | 721 | 740 | F | -| for_loop_scope | true | 726 | 743 | | -| for_loop_scope | true | 728 | 726 | | -| for_loop_scope | true | 730 | 716 | | -| for_loop_scope | true | 732 | 734 | | -| for_loop_scope | true | 734 | 716 | | -| for_loop_scope | true | 736 | 746 | | -| for_loop_scope | true | 738 | 706 | | -| for_loop_scope | true | 740 | 742 | | -| for_loop_scope | true | 742 | 736 | | -| for_loop_scope | true | 743 | 745 | | -| for_loop_scope | true | 745 | 732 | | -| for_loop_scope | true | 746 | 748 | | -| for_loop_scope | true | 748 | 698 | | -| gotos | false | 608 | 608 | gotos | -| gotos | false | 616 | 616 | declaration | -| gotos | false | 621 | 621 | if (...) ... | -| gotos | false | 623 | 623 | x | -| gotos | false | 625 | 625 | (bool)... | -| gotos | false | 626 | 626 | goto ... | -| gotos | false | 628 | 628 | x | -| gotos | false | 630 | 630 | ++ ... | -| gotos | false | 632 | 632 | initializer for y | -| gotos | false | 643 | 643 | declaration | -| gotos | false | 645 | 645 | label ...: | -| gotos | false | 647 | 647 | declaration | -| gotos | false | 649 | 649 | if (...) ... | -| gotos | false | 651 | 651 | y | -| gotos | false | 653 | 653 | (bool)... | -| gotos | false | 654 | 654 | goto ... | -| gotos | false | 656 | 656 | declaration | -| gotos | false | 658 | 658 | { ... } | -| gotos | false | 660 | 660 | label ...: | -| gotos | false | 662 | 662 | ExprStmt | -| gotos | false | 664 | 664 | x | -| gotos | false | 666 | 666 | -- ... | -| gotos | false | 668 | 668 | return ... | -| gotos | false | 670 | 670 | { ... } | -| gotos | false | 672 | 672 | nt2 | -| gotos | false | 674 | 674 | call to nt2.~NonTrivial | -| gotos | false | 675 | 675 | nt3 | -| gotos | false | 676 | 676 | call to nt3.~NonTrivial | -| gotos | false | 677 | 677 | nt2 | -| gotos | false | 678 | 678 | call to nt2.~NonTrivial | -| gotos | false | 679 | 679 | nt1 | -| gotos | false | 681 | 681 | call to nt1.~NonTrivial | -| gotos | true | 616 | 621 | | -| gotos | true | 621 | 623 | | -| gotos | true | 623 | 626 | T | -| gotos | true | 623 | 658 | F | -| gotos | true | 626 | 645 | | -| gotos | true | 628 | 630 | | -| gotos | true | 630 | 645 | | -| gotos | true | 632 | 628 | | -| gotos | true | 643 | 632 | | -| gotos | true | 643 | 645 | | -| gotos | true | 645 | 647 | | -| gotos | true | 647 | 649 | | -| gotos | true | 649 | 651 | | -| gotos | true | 651 | 654 | T | -| gotos | true | 651 | 656 | F | -| gotos | true | 654 | 677 | | -| gotos | true | 656 | 675 | | -| gotos | true | 658 | 643 | | -| gotos | true | 660 | 662 | | -| gotos | true | 662 | 664 | | -| gotos | true | 664 | 666 | | -| gotos | true | 666 | 668 | | -| gotos | true | 668 | 679 | | -| gotos | true | 670 | 616 | | -| gotos | true | 672 | 674 | | -| gotos | true | 674 | 660 | | -| gotos | true | 675 | 676 | | -| gotos | true | 676 | 672 | | -| gotos | true | 677 | 678 | | -| gotos | true | 678 | 660 | | -| gotos | true | 679 | 681 | | -| gotos | true | 681 | 608 | | +| for_loop_scope | false | 699 | 699 | for_loop_scope | +| for_loop_scope | false | 707 | 707 | declaration | +| for_loop_scope | false | 712 | 712 | for(...;...;...) ... | +| for_loop_scope | false | 717 | 717 | x | +| for_loop_scope | false | 721 | 721 | 10 | +| for_loop_scope | false | 722 | 722 | ... < ... | +| for_loop_scope | false | 727 | 727 | declaration | +| for_loop_scope | false | 729 | 729 | { ... } | +| for_loop_scope | false | 731 | 731 | declaration | +| for_loop_scope | false | 733 | 733 | x | +| for_loop_scope | false | 735 | 735 | ++ ... | +| for_loop_scope | false | 737 | 737 | return ... | +| for_loop_scope | false | 739 | 739 | { ... } | +| for_loop_scope | false | 741 | 741 | for_scope | +| for_loop_scope | false | 743 | 743 | call to for_scope.~NonTrivial | +| for_loop_scope | false | 744 | 744 | inner_scope | +| for_loop_scope | false | 746 | 746 | call to inner_scope.~NonTrivial | +| for_loop_scope | false | 747 | 747 | outer_scope | +| for_loop_scope | false | 749 | 749 | call to outer_scope.~NonTrivial | +| for_loop_scope | true | 707 | 712 | | +| for_loop_scope | true | 712 | 731 | | +| for_loop_scope | true | 717 | 721 | | +| for_loop_scope | true | 721 | 722 | | +| for_loop_scope | true | 722 | 729 | T | +| for_loop_scope | true | 722 | 741 | F | +| for_loop_scope | true | 727 | 744 | | +| for_loop_scope | true | 729 | 727 | | +| for_loop_scope | true | 731 | 717 | | +| for_loop_scope | true | 733 | 735 | | +| for_loop_scope | true | 735 | 717 | | +| for_loop_scope | true | 737 | 747 | | +| for_loop_scope | true | 739 | 707 | | +| for_loop_scope | true | 741 | 743 | | +| for_loop_scope | true | 743 | 737 | | +| for_loop_scope | true | 744 | 746 | | +| for_loop_scope | true | 746 | 733 | | +| for_loop_scope | true | 747 | 749 | | +| for_loop_scope | true | 749 | 699 | | +| gotos | false | 609 | 609 | gotos | +| gotos | false | 617 | 617 | declaration | +| gotos | false | 622 | 622 | if (...) ... | +| gotos | false | 624 | 624 | x | +| gotos | false | 626 | 626 | (bool)... | +| gotos | false | 627 | 627 | goto ... | +| gotos | false | 629 | 629 | x | +| gotos | false | 631 | 631 | ++ ... | +| gotos | false | 633 | 633 | initializer for y | +| gotos | false | 644 | 644 | declaration | +| gotos | false | 646 | 646 | label ...: | +| gotos | false | 648 | 648 | declaration | +| gotos | false | 650 | 650 | if (...) ... | +| gotos | false | 652 | 652 | y | +| gotos | false | 654 | 654 | (bool)... | +| gotos | false | 655 | 655 | goto ... | +| gotos | false | 657 | 657 | declaration | +| gotos | false | 659 | 659 | { ... } | +| gotos | false | 661 | 661 | label ...: | +| gotos | false | 663 | 663 | ExprStmt | +| gotos | false | 665 | 665 | x | +| gotos | false | 667 | 667 | -- ... | +| gotos | false | 669 | 669 | return ... | +| gotos | false | 671 | 671 | { ... } | +| gotos | false | 673 | 673 | nt2 | +| gotos | false | 675 | 675 | call to nt2.~NonTrivial | +| gotos | false | 676 | 676 | nt2 | +| gotos | false | 677 | 677 | call to nt2.~NonTrivial | +| gotos | false | 678 | 678 | nt3 | +| gotos | false | 679 | 679 | call to nt3.~NonTrivial | +| gotos | false | 680 | 680 | nt1 | +| gotos | false | 682 | 682 | call to nt1.~NonTrivial | +| gotos | true | 617 | 622 | | +| gotos | true | 622 | 624 | | +| gotos | true | 624 | 627 | T | +| gotos | true | 624 | 659 | F | +| gotos | true | 627 | 646 | | +| gotos | true | 629 | 631 | | +| gotos | true | 631 | 646 | | +| gotos | true | 633 | 629 | | +| gotos | true | 644 | 633 | | +| gotos | true | 644 | 646 | | +| gotos | true | 646 | 648 | | +| gotos | true | 648 | 650 | | +| gotos | true | 650 | 652 | | +| gotos | true | 652 | 655 | T | +| gotos | true | 652 | 657 | F | +| gotos | true | 655 | 673 | | +| gotos | true | 657 | 678 | | +| gotos | true | 659 | 644 | | +| gotos | true | 661 | 663 | | +| gotos | true | 663 | 665 | | +| gotos | true | 665 | 667 | | +| gotos | true | 667 | 669 | | +| gotos | true | 669 | 680 | | +| gotos | true | 671 | 617 | | +| gotos | true | 673 | 675 | | +| gotos | true | 675 | 661 | | +| gotos | true | 676 | 677 | | +| gotos | true | 677 | 661 | | +| gotos | true | 678 | 679 | | +| gotos | true | 679 | 676 | | +| gotos | true | 680 | 682 | | +| gotos | true | 682 | 609 | | | if_decl_bind | false | 375 | 375 | if_decl_bind | | if_decl_bind | false | 383 | 383 | if (...) ... | | if_decl_bind | false | 386 | 386 | call to operator int | @@ -350,45 +350,45 @@ | if_decl_bind | true | 435 | 383 | | | if_decl_bind | true | 437 | 439 | | | if_decl_bind | true | 439 | 424 | | -| never_destructs | false | 682 | 682 | never_destructs | -| never_destructs | false | 687 | 687 | declaration | -| never_destructs | false | 692 | 692 | label ...: | -| never_destructs | false | 694 | 694 | goto ... | -| never_destructs | false | 696 | 696 | { ... } | -| never_destructs | true | 687 | 692 | | -| never_destructs | true | 692 | 694 | | -| never_destructs | true | 694 | 692 | | -| never_destructs | true | 696 | 687 | | +| never_destructs | false | 683 | 683 | never_destructs | +| never_destructs | false | 688 | 688 | declaration | +| never_destructs | false | 693 | 693 | label ...: | +| never_destructs | false | 695 | 695 | goto ... | +| never_destructs | false | 697 | 697 | { ... } | +| never_destructs | true | 688 | 693 | | +| never_destructs | true | 693 | 695 | | +| never_destructs | true | 695 | 693 | | +| never_destructs | true | 697 | 688 | | | operator delete | false | 476 | 476 | operator delete | | operator new | false | 499 | 499 | operator new | -| simple | false | 871 | 871 | simple | -| simple | false | 876 | 876 | declaration | -| simple | false | 881 | 881 | return ... | -| simple | false | 883 | 883 | { ... } | -| simple | false | 885 | 885 | nt | -| simple | false | 887 | 887 | call to nt.~NonTrivial | -| simple | true | 876 | 881 | | -| simple | true | 881 | 885 | | -| simple | true | 883 | 876 | | -| simple | true | 885 | 887 | | -| simple | true | 887 | 871 | | -| simple2 | false | 847 | 847 | simple2 | -| simple2 | false | 852 | 852 | declaration | -| simple2 | false | 857 | 857 | declaration | -| simple2 | false | 862 | 862 | return ... | -| simple2 | false | 864 | 864 | { ... } | -| simple2 | false | 866 | 866 | one | -| simple2 | false | 868 | 868 | call to one.~NonTrivial | -| simple2 | false | 869 | 869 | two | -| simple2 | false | 870 | 870 | call to two.~NonTrivial | -| simple2 | true | 852 | 857 | | -| simple2 | true | 857 | 862 | | -| simple2 | true | 862 | 869 | | -| simple2 | true | 864 | 852 | | -| simple2 | true | 866 | 868 | | -| simple2 | true | 868 | 847 | | -| simple2 | true | 869 | 870 | | -| simple2 | true | 870 | 866 | | +| simple | false | 872 | 872 | simple | +| simple | false | 877 | 877 | declaration | +| simple | false | 882 | 882 | return ... | +| simple | false | 884 | 884 | { ... } | +| simple | false | 886 | 886 | nt | +| simple | false | 888 | 888 | call to nt.~NonTrivial | +| simple | true | 877 | 882 | | +| simple | true | 882 | 886 | | +| simple | true | 884 | 877 | | +| simple | true | 886 | 888 | | +| simple | true | 888 | 872 | | +| simple2 | false | 848 | 848 | simple2 | +| simple2 | false | 853 | 853 | declaration | +| simple2 | false | 858 | 858 | declaration | +| simple2 | false | 863 | 863 | return ... | +| simple2 | false | 865 | 865 | { ... } | +| simple2 | false | 867 | 867 | one | +| simple2 | false | 869 | 869 | call to one.~NonTrivial | +| simple2 | false | 870 | 870 | two | +| simple2 | false | 871 | 871 | call to two.~NonTrivial | +| simple2 | true | 853 | 858 | | +| simple2 | true | 858 | 863 | | +| simple2 | true | 863 | 870 | | +| simple2 | true | 865 | 853 | | +| simple2 | true | 867 | 869 | | +| simple2 | true | 869 | 848 | | +| simple2 | true | 870 | 871 | | +| simple2 | true | 871 | 867 | | | switch_decl_bind | false | 276 | 276 | switch_decl_bind | | switch_decl_bind | false | 284 | 284 | switch (...) ... | | switch_decl_bind | false | 287 | 287 | call to operator int | @@ -444,21 +444,21 @@ | switch_decl_bind | true | 310 | 313 | | | switch_decl_bind | true | 313 | 315 | | | switch_decl_bind | true | 315 | 317 | | -| switch_decl_bind | true | 317 | 371 | | +| switch_decl_bind | true | 317 | 368 | | | switch_decl_bind | true | 319 | 324 | | | switch_decl_bind | true | 324 | 326 | | | switch_decl_bind | true | 326 | 328 | | | switch_decl_bind | true | 328 | 330 | | | switch_decl_bind | true | 330 | 332 | | | switch_decl_bind | true | 332 | 334 | | -| switch_decl_bind | true | 334 | 373 | | +| switch_decl_bind | true | 334 | 371 | | | switch_decl_bind | true | 336 | 338 | | | switch_decl_bind | true | 338 | 340 | | | switch_decl_bind | true | 340 | 342 | | | switch_decl_bind | true | 342 | 344 | | | switch_decl_bind | true | 344 | 348 | | | switch_decl_bind | true | 348 | 349 | | -| switch_decl_bind | true | 349 | 368 | | +| switch_decl_bind | true | 349 | 373 | | | switch_decl_bind | true | 351 | 300 | | | switch_decl_bind | true | 351 | 319 | | | switch_decl_bind | true | 351 | 336 | | @@ -501,10 +501,11 @@ | while_decl_bind | true | 241 | 251 | | | while_decl_bind | true | 243 | 241 | | | while_decl_bind | true | 251 | 259 | T | -| while_decl_bind | true | 251 | 271 | F | +| while_decl_bind | true | 251 | 274 | F | | while_decl_bind | true | 253 | 255 | | | while_decl_bind | true | 255 | 257 | | -| while_decl_bind | true | 257 | 274 | | +| while_decl_bind | true | 257 | 243 | | +| while_decl_bind | true | 257 | 271 | | | while_decl_bind | true | 259 | 253 | | | while_decl_bind | true | 261 | 263 | | | while_decl_bind | true | 263 | 265 | | @@ -512,6 +513,5 @@ | while_decl_bind | true | 267 | 228 | | | while_decl_bind | true | 269 | 236 | | | while_decl_bind | true | 271 | 273 | | -| while_decl_bind | true | 273 | 261 | | | while_decl_bind | true | 274 | 275 | | -| while_decl_bind | true | 275 | 243 | | +| while_decl_bind | true | 275 | 261 | | From 22e843abc665a2303982ab0a3fa6c2dcab3cb79e Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 1 May 2024 11:41:16 +0100 Subject: [PATCH 138/238] Update cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.qhelp Co-authored-by: mc <42146119+mchammer01@users.noreply.github.com> --- .../src/Security/CWE/CWE-416/IteratorToExpiredContainer.qhelp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.qhelp b/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.qhelp index 176ead87de4c..0f3660e0b1ec 100644 --- a/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.qhelp +++ b/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.qhelp @@ -31,7 +31,7 @@ This is because the temporary container is not bound to a rvalue reference.

    -To fix lifetime_of_temp_not_extended consider rewriting the code so that the temporary's lifetime is extended. +To fix lifetime_of_temp_not_extended, consider rewriting the code so that the lifetime of the temporary object is extended. In fixed_lifetime_of_temp_not_extended the lifetime of the temporary object has been extended by storing it in an rvalue reference.

    From 40b6e1624f7f0c1d68baa5b3263e0f023f884e15 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 1 May 2024 11:41:23 +0100 Subject: [PATCH 139/238] Update cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.qhelp Co-authored-by: mc <42146119+mchammer01@users.noreply.github.com> --- .../src/Security/CWE/CWE-416/IteratorToExpiredContainer.qhelp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.qhelp b/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.qhelp index 0f3660e0b1ec..87cc75c5f019 100644 --- a/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.qhelp +++ b/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.qhelp @@ -32,7 +32,7 @@ This is because the temporary container is not bound to a rvalue reference.

    To fix lifetime_of_temp_not_extended, consider rewriting the code so that the lifetime of the temporary object is extended. -In fixed_lifetime_of_temp_not_extended the lifetime of the temporary object has been extended by storing it in an rvalue reference. +In fixed_lifetime_of_temp_not_extended, the lifetime of the temporary object has been extended by storing it in an rvalue reference.

    From 00cbfaf40e052d28aea3021f0ba8023317cfe0d4 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Wed, 1 May 2024 15:00:45 +0100 Subject: [PATCH 140/238] Go: Allow version suffixes --- go/extractor/project/project.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/extractor/project/project.go b/go/extractor/project/project.go index 215d7c6bc4ff..13f6f455ba1d 100644 --- a/go/extractor/project/project.go +++ b/go/extractor/project/project.go @@ -575,7 +575,7 @@ func getModMode(depMode DependencyInstallerMode, baseDir string) ModMode { // Tries to open `go.mod` and read a go directive, returning the version and whether it was found. // The version string is returned in the "1.2.3" format. func tryReadGoDirective(path string) GoVersionInfo { - versionRe := regexp.MustCompile(`(?m)^go[ \t\r]+([0-9]+\.[0-9]+(\.[0-9]+)?)$`) + versionRe := regexp.MustCompile(`(?m)^go[ \t\r]+([0-9]+\.[0-9]+(\.[0-9]+)?)`) goMod, err := os.ReadFile(path) if err != nil { log.Println("Failed to read go.mod to check for missing Go version") From f7fc2e0b0076afb14af30a995ce208d2eaa8e72b Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Wed, 1 May 2024 16:13:39 +0100 Subject: [PATCH 141/238] Ruby: Fix StringSubstitutionCall charpred Some missing parens meant this class targeted way more things than intended. --- ruby/ql/lib/codeql/ruby/frameworks/core/String.qll | 8 +++++--- .../security/cwe-116/IncompleteSanitization/tst.rb | 5 +++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/core/String.qll b/ruby/ql/lib/codeql/ruby/frameworks/core/String.qll index 86246ba80a20..23a902c00195 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/core/String.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/core/String.qll @@ -19,9 +19,11 @@ class StringSubstitutionCall extends DataFlow::CallNode { StringSubstitutionCall() { this.getMethodName() = ["sub", "sub!", "gsub", "gsub!"] and exists(this.getReceiver()) and - this.getNumberOfArguments() = 2 - or - this.getNumberOfArguments() = 1 and exists(this.getBlock()) + ( + this.getNumberOfArguments() = 2 + or + this.getNumberOfArguments() = 1 and exists(this.getBlock()) + ) } /** diff --git a/ruby/ql/test/query-tests/security/cwe-116/IncompleteSanitization/tst.rb b/ruby/ql/test/query-tests/security/cwe-116/IncompleteSanitization/tst.rb index 569e8b5ac09a..f59fdd332aed 100644 --- a/ruby/ql/test/query-tests/security/cwe-116/IncompleteSanitization/tst.rb +++ b/ruby/ql/test/query-tests/security/cwe-116/IncompleteSanitization/tst.rb @@ -268,3 +268,8 @@ def bad_path_sanitizer(p1, p2) p1.sub! "/../", "" # NOT OK p2.sub "/../", "" # NOT OK end + +def each_line_sanitizer(p1) + p1.each_line("\n") do |l| # OK - does no sanitization + end +end From c480431ec0aa5f67fcb472b8a58430f012090795 Mon Sep 17 00:00:00 2001 From: Mario Campos Date: Wed, 1 May 2024 10:59:16 -0500 Subject: [PATCH 142/238] C++: simplify cpp/guarded-free This new form is more declarative by use of the `GuardCondition`. Thanks to the tireless effort of @MathiasVP! --- .../Best Practices/GuardedFree.ql | 33 +++---------------- 1 file changed, 5 insertions(+), 28 deletions(-) diff --git a/cpp/ql/src/experimental/Best Practices/GuardedFree.ql b/cpp/ql/src/experimental/Best Practices/GuardedFree.ql index 07d279271592..1316c38143b0 100644 --- a/cpp/ql/src/experimental/Best Practices/GuardedFree.ql +++ b/cpp/ql/src/experimental/Best Practices/GuardedFree.ql @@ -17,32 +17,9 @@ class FreeCall extends FunctionCall { FreeCall() { this.getTarget().hasGlobalName("free") } } -from IfStmt stmt, FreeCall fc, Variable v +from GuardCondition gc, FreeCall fc, Variable v, BasicBlock bb where - stmt.getThen() = fc.getEnclosingStmt() and - ( - stmt.getCondition() = v.getAnAccess() and - fc.getArgument(0) = v.getAnAccess() - or - exists(PointerDereferenceExpr cond, PointerDereferenceExpr arg | - fc.getArgument(0) = arg and - stmt.getCondition() = cond and - cond.getOperand+() = v.getAnAccess() and - arg.getOperand+() = v.getAnAccess() - ) - or - exists(ArrayExpr cond, ArrayExpr arg | - fc.getArgument(0) = arg and - stmt.getCondition() = cond and - cond.getArrayBase+() = v.getAnAccess() and - arg.getArrayBase+() = v.getAnAccess() - ) - or - exists(NEExpr eq | - fc.getArgument(0) = v.getAnAccess() and - stmt.getCondition() = eq and - eq.getAnOperand() = v.getAnAccess() and - eq.getAnOperand().getValue() = "0" - ) - ) -select stmt, "unnecessary NULL check before call to $@", fc, "free" + gc.ensuresEq(v.getAnAccess(), 0, bb, false) and + fc.getArgument(0) = v.getAnAccess() and + bb = fc.getEnclosingStmt() +select gc, "unnecessary NULL check before call to $@", fc, "free" From 5a7a1dc92eead406994d97320dd888f7f03e7514 Mon Sep 17 00:00:00 2001 From: Mario Campos Date: Wed, 1 May 2024 11:00:19 -0500 Subject: [PATCH 143/238] C++: forgot to import semmle.code.cpp.controlflow.Guards --- cpp/ql/src/experimental/Best Practices/GuardedFree.ql | 1 + 1 file changed, 1 insertion(+) diff --git a/cpp/ql/src/experimental/Best Practices/GuardedFree.ql b/cpp/ql/src/experimental/Best Practices/GuardedFree.ql index 1316c38143b0..2d504d9bc057 100644 --- a/cpp/ql/src/experimental/Best Practices/GuardedFree.ql +++ b/cpp/ql/src/experimental/Best Practices/GuardedFree.ql @@ -12,6 +12,7 @@ */ import cpp +import semmle.code.cpp.controlflow.Guards class FreeCall extends FunctionCall { FreeCall() { this.getTarget().hasGlobalName("free") } From c00d0d302d965c01afc9e5f81fbb607d9783e05c Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Wed, 1 May 2024 17:25:19 +0100 Subject: [PATCH 144/238] Ruby: fix wording in rb/request-without-cert-validation --- .../cwe-295/RequestWithoutValidation.ql | 2 +- .../cwe-295/RequestWithoutValidation.expected | 56 +++++++++---------- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/ruby/ql/src/queries/security/cwe-295/RequestWithoutValidation.ql b/ruby/ql/src/queries/security/cwe-295/RequestWithoutValidation.ql index 783f70426d6b..87c772e1cc13 100644 --- a/ruby/ql/src/queries/security/cwe-295/RequestWithoutValidation.ql +++ b/ruby/ql/src/queries/security/cwe-295/RequestWithoutValidation.ql @@ -29,4 +29,4 @@ where // does NOT hold. if disablingNode.getLocation() = origin.getLocation() then ending = "." else ending = " by $@." select request, "This request may run without certificate validation because $@" + ending, - disablingNode, "the request is disabled", origin, "this value" + disablingNode, "validation is disabled", origin, "this value" diff --git a/ruby/ql/test/query-tests/security/cwe-295/RequestWithoutValidation.expected b/ruby/ql/test/query-tests/security/cwe-295/RequestWithoutValidation.expected index 7b5c32c891a5..4f368a250027 100644 --- a/ruby/ql/test/query-tests/security/cwe-295/RequestWithoutValidation.expected +++ b/ruby/ql/test/query-tests/security/cwe-295/RequestWithoutValidation.expected @@ -1,28 +1,28 @@ -| Excon.rb:6:3:6:34 | call to get | This request may run without certificate validation because $@. | Excon.rb:5:38:5:42 | ... = ... | the request is disabled | Excon.rb:5:38:5:42 | false | this value | -| Excon.rb:12:3:12:34 | call to get | This request may run without certificate validation because $@. | Excon.rb:11:27:11:31 | ... = ... | the request is disabled | Excon.rb:11:27:11:31 | false | this value | -| Excon.rb:18:3:18:34 | call to get | This request may run without certificate validation because $@ by $@. | Excon.rb:17:38:17:60 | ... = ... | the request is disabled | Excon.rb:17:55:17:59 | false | this value | -| Excon.rb:24:3:24:10 | call to get | This request may run without certificate validation because $@. | Excon.rb:23:72:23:76 | false | the request is disabled | Excon.rb:23:72:23:76 | false | this value | -| Excon.rb:30:3:30:62 | call to get | This request may run without certificate validation because $@. | Excon.rb:30:53:30:57 | false | the request is disabled | Excon.rb:30:53:30:57 | false | this value | -| Faraday.rb:5:12:5:30 | call to get | This request may run without certificate validation because $@. | Faraday.rb:4:63:4:67 | false | the request is disabled | Faraday.rb:4:63:4:67 | false | this value | -| Faraday.rb:9:12:9:30 | call to get | This request may run without certificate validation because $@. | Faraday.rb:8:68:8:92 | VERIFY_NONE | the request is disabled | Faraday.rb:8:68:8:92 | VERIFY_NONE | this value | -| Faraday.rb:35:16:35:35 | call to get | This request may run without certificate validation because $@ by $@. | Faraday.rb:34:51:34:53 | arg | the request is disabled | Faraday.rb:38:42:38:46 | false | this value | -| Faraday.rb:44:16:44:35 | call to get | This request may run without certificate validation because $@ by $@. | Faraday.rb:43:56:43:58 | arg | the request is disabled | Faraday.rb:47:47:47:71 | VERIFY_NONE | this value | -| HttpClient.rb:6:1:6:33 | call to get | This request may run without certificate validation because $@. | HttpClient.rb:5:33:5:57 | ... = ... | the request is disabled | HttpClient.rb:5:33:5:57 | VERIFY_NONE | this value | -| Httparty.rb:4:1:4:50 | call to get | This request may run without certificate validation because $@. | Httparty.rb:4:45:4:49 | false | the request is disabled | Httparty.rb:4:45:4:49 | false | this value | -| Httparty.rb:7:1:7:55 | call to get | This request may run without certificate validation because $@. | Httparty.rb:7:50:7:54 | false | the request is disabled | Httparty.rb:7:50:7:54 | false | this value | -| Httparty.rb:10:1:10:59 | call to get | This request may run without certificate validation because $@. | Httparty.rb:10:52:10:56 | false | the request is disabled | Httparty.rb:10:52:10:56 | false | this value | -| Httparty.rb:13:1:13:70 | call to post | This request may run without certificate validation because $@. | Httparty.rb:13:65:13:69 | false | the request is disabled | Httparty.rb:13:65:13:69 | false | this value | -| Httparty.rb:16:1:16:74 | call to post | This request may run without certificate validation because $@. | Httparty.rb:16:67:16:71 | false | the request is disabled | Httparty.rb:16:67:16:71 | false | this value | -| NetHttp.rb:9:12:9:31 | call to request | This request may run without certificate validation because $@. | NetHttp.rb:7:20:7:44 | ... = ... | the request is disabled | NetHttp.rb:7:20:7:44 | VERIFY_NONE | this value | -| OpenURI.rb:4:1:4:78 | call to open | This request may run without certificate validation because $@. | OpenURI.rb:4:53:4:77 | VERIFY_NONE | the request is disabled | OpenURI.rb:4:53:4:77 | VERIFY_NONE | this value | -| OpenURI.rb:7:1:7:82 | call to open | This request may run without certificate validation because $@. | OpenURI.rb:7:55:7:79 | VERIFY_NONE | the request is disabled | OpenURI.rb:7:55:7:79 | VERIFY_NONE | this value | -| OpenURI.rb:11:1:11:43 | call to open | This request may run without certificate validation because $@. | OpenURI.rb:10:30:10:54 | VERIFY_NONE | the request is disabled | OpenURI.rb:10:30:10:54 | VERIFY_NONE | this value | -| OpenURI.rb:14:1:14:81 | call to open | This request may run without certificate validation because $@. | OpenURI.rb:14:56:14:80 | VERIFY_NONE | the request is disabled | OpenURI.rb:14:56:14:80 | VERIFY_NONE | this value | -| OpenURI.rb:17:1:17:85 | call to open | This request may run without certificate validation because $@. | OpenURI.rb:17:58:17:82 | VERIFY_NONE | the request is disabled | OpenURI.rb:17:58:17:82 | VERIFY_NONE | this value | -| OpenURI.rb:21:1:21:46 | call to open | This request may run without certificate validation because $@. | OpenURI.rb:20:30:20:54 | VERIFY_NONE | the request is disabled | OpenURI.rb:20:30:20:54 | VERIFY_NONE | this value | -| RestClient.rb:5:12:5:23 | call to get | This request may run without certificate validation because $@. | RestClient.rb:4:72:4:96 | VERIFY_NONE | the request is disabled | RestClient.rb:4:72:4:96 | VERIFY_NONE | this value | -| RestClient.rb:9:12:9:23 | call to get | This request may run without certificate validation because $@. | RestClient.rb:8:74:8:98 | VERIFY_NONE | the request is disabled | RestClient.rb:8:74:8:98 | VERIFY_NONE | this value | -| RestClient.rb:14:12:14:23 | call to get | This request may run without certificate validation because $@. | RestClient.rb:12:25:12:49 | VERIFY_NONE | the request is disabled | RestClient.rb:12:25:12:49 | VERIFY_NONE | this value | -| RestClient.rb:19:12:19:23 | call to get | This request may run without certificate validation because $@ by $@. | RestClient.rb:18:72:18:76 | value | the request is disabled | RestClient.rb:17:9:17:33 | VERIFY_NONE | this value | -| Typhoeus.rb:4:1:4:62 | call to get | This request may run without certificate validation because $@. | Typhoeus.rb:4:57:4:61 | false | the request is disabled | Typhoeus.rb:4:57:4:61 | false | this value | -| Typhoeus.rb:8:1:8:54 | call to post | This request may run without certificate validation because $@. | Typhoeus.rb:7:53:7:57 | false | the request is disabled | Typhoeus.rb:7:53:7:57 | false | this value | +| Excon.rb:6:3:6:34 | call to get | This request may run without certificate validation because $@. | Excon.rb:5:38:5:42 | ... = ... | validation is disabled | Excon.rb:5:38:5:42 | false | this value | +| Excon.rb:12:3:12:34 | call to get | This request may run without certificate validation because $@. | Excon.rb:11:27:11:31 | ... = ... | validation is disabled | Excon.rb:11:27:11:31 | false | this value | +| Excon.rb:18:3:18:34 | call to get | This request may run without certificate validation because $@ by $@. | Excon.rb:17:38:17:60 | ... = ... | validation is disabled | Excon.rb:17:55:17:59 | false | this value | +| Excon.rb:24:3:24:10 | call to get | This request may run without certificate validation because $@. | Excon.rb:23:72:23:76 | false | validation is disabled | Excon.rb:23:72:23:76 | false | this value | +| Excon.rb:30:3:30:62 | call to get | This request may run without certificate validation because $@. | Excon.rb:30:53:30:57 | false | validation is disabled | Excon.rb:30:53:30:57 | false | this value | +| Faraday.rb:5:12:5:30 | call to get | This request may run without certificate validation because $@. | Faraday.rb:4:63:4:67 | false | validation is disabled | Faraday.rb:4:63:4:67 | false | this value | +| Faraday.rb:9:12:9:30 | call to get | This request may run without certificate validation because $@. | Faraday.rb:8:68:8:92 | VERIFY_NONE | validation is disabled | Faraday.rb:8:68:8:92 | VERIFY_NONE | this value | +| Faraday.rb:35:16:35:35 | call to get | This request may run without certificate validation because $@ by $@. | Faraday.rb:34:51:34:53 | arg | validation is disabled | Faraday.rb:38:42:38:46 | false | this value | +| Faraday.rb:44:16:44:35 | call to get | This request may run without certificate validation because $@ by $@. | Faraday.rb:43:56:43:58 | arg | validation is disabled | Faraday.rb:47:47:47:71 | VERIFY_NONE | this value | +| HttpClient.rb:6:1:6:33 | call to get | This request may run without certificate validation because $@. | HttpClient.rb:5:33:5:57 | ... = ... | validation is disabled | HttpClient.rb:5:33:5:57 | VERIFY_NONE | this value | +| Httparty.rb:4:1:4:50 | call to get | This request may run without certificate validation because $@. | Httparty.rb:4:45:4:49 | false | validation is disabled | Httparty.rb:4:45:4:49 | false | this value | +| Httparty.rb:7:1:7:55 | call to get | This request may run without certificate validation because $@. | Httparty.rb:7:50:7:54 | false | validation is disabled | Httparty.rb:7:50:7:54 | false | this value | +| Httparty.rb:10:1:10:59 | call to get | This request may run without certificate validation because $@. | Httparty.rb:10:52:10:56 | false | validation is disabled | Httparty.rb:10:52:10:56 | false | this value | +| Httparty.rb:13:1:13:70 | call to post | This request may run without certificate validation because $@. | Httparty.rb:13:65:13:69 | false | validation is disabled | Httparty.rb:13:65:13:69 | false | this value | +| Httparty.rb:16:1:16:74 | call to post | This request may run without certificate validation because $@. | Httparty.rb:16:67:16:71 | false | validation is disabled | Httparty.rb:16:67:16:71 | false | this value | +| NetHttp.rb:9:12:9:31 | call to request | This request may run without certificate validation because $@. | NetHttp.rb:7:20:7:44 | ... = ... | validation is disabled | NetHttp.rb:7:20:7:44 | VERIFY_NONE | this value | +| OpenURI.rb:4:1:4:78 | call to open | This request may run without certificate validation because $@. | OpenURI.rb:4:53:4:77 | VERIFY_NONE | validation is disabled | OpenURI.rb:4:53:4:77 | VERIFY_NONE | this value | +| OpenURI.rb:7:1:7:82 | call to open | This request may run without certificate validation because $@. | OpenURI.rb:7:55:7:79 | VERIFY_NONE | validation is disabled | OpenURI.rb:7:55:7:79 | VERIFY_NONE | this value | +| OpenURI.rb:11:1:11:43 | call to open | This request may run without certificate validation because $@. | OpenURI.rb:10:30:10:54 | VERIFY_NONE | validation is disabled | OpenURI.rb:10:30:10:54 | VERIFY_NONE | this value | +| OpenURI.rb:14:1:14:81 | call to open | This request may run without certificate validation because $@. | OpenURI.rb:14:56:14:80 | VERIFY_NONE | validation is disabled | OpenURI.rb:14:56:14:80 | VERIFY_NONE | this value | +| OpenURI.rb:17:1:17:85 | call to open | This request may run without certificate validation because $@. | OpenURI.rb:17:58:17:82 | VERIFY_NONE | validation is disabled | OpenURI.rb:17:58:17:82 | VERIFY_NONE | this value | +| OpenURI.rb:21:1:21:46 | call to open | This request may run without certificate validation because $@. | OpenURI.rb:20:30:20:54 | VERIFY_NONE | validation is disabled | OpenURI.rb:20:30:20:54 | VERIFY_NONE | this value | +| RestClient.rb:5:12:5:23 | call to get | This request may run without certificate validation because $@. | RestClient.rb:4:72:4:96 | VERIFY_NONE | validation is disabled | RestClient.rb:4:72:4:96 | VERIFY_NONE | this value | +| RestClient.rb:9:12:9:23 | call to get | This request may run without certificate validation because $@. | RestClient.rb:8:74:8:98 | VERIFY_NONE | validation is disabled | RestClient.rb:8:74:8:98 | VERIFY_NONE | this value | +| RestClient.rb:14:12:14:23 | call to get | This request may run without certificate validation because $@. | RestClient.rb:12:25:12:49 | VERIFY_NONE | validation is disabled | RestClient.rb:12:25:12:49 | VERIFY_NONE | this value | +| RestClient.rb:19:12:19:23 | call to get | This request may run without certificate validation because $@ by $@. | RestClient.rb:18:72:18:76 | value | validation is disabled | RestClient.rb:17:9:17:33 | VERIFY_NONE | this value | +| Typhoeus.rb:4:1:4:62 | call to get | This request may run without certificate validation because $@. | Typhoeus.rb:4:57:4:61 | false | validation is disabled | Typhoeus.rb:4:57:4:61 | false | this value | +| Typhoeus.rb:8:1:8:54 | call to post | This request may run without certificate validation because $@. | Typhoeus.rb:7:53:7:57 | false | validation is disabled | Typhoeus.rb:7:53:7:57 | false | this value | From 09e59ccf440ab7213f7e2702651c71fef753b6e8 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 1 May 2024 21:39:38 +0100 Subject: [PATCH 145/238] Name files with empty definitions of MaD extensible predicates to erowdmpty.model.yml --- csharp/ql/lib/ext/{default.model.yml => empty.model.yml} | 0 go/ql/lib/ext/{dummy.model.yml => empty.model.yml} | 0 java/ql/lib/ext/{dummy.model.yml => empty.model.yml} | 0 java/ql/lib/ext/experimental/{dummy.model.yml => empty.model.yml} | 0 .../frameworks/data/internal/{model.yml => empty.model.yml} | 0 .../ruby/frameworks/data/internal/{model.yml => empty.model.yml} | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename csharp/ql/lib/ext/{default.model.yml => empty.model.yml} (100%) rename go/ql/lib/ext/{dummy.model.yml => empty.model.yml} (100%) rename java/ql/lib/ext/{dummy.model.yml => empty.model.yml} (100%) rename java/ql/lib/ext/experimental/{dummy.model.yml => empty.model.yml} (100%) rename javascript/ql/lib/semmle/javascript/frameworks/data/internal/{model.yml => empty.model.yml} (100%) rename ruby/ql/lib/codeql/ruby/frameworks/data/internal/{model.yml => empty.model.yml} (100%) diff --git a/csharp/ql/lib/ext/default.model.yml b/csharp/ql/lib/ext/empty.model.yml similarity index 100% rename from csharp/ql/lib/ext/default.model.yml rename to csharp/ql/lib/ext/empty.model.yml diff --git a/go/ql/lib/ext/dummy.model.yml b/go/ql/lib/ext/empty.model.yml similarity index 100% rename from go/ql/lib/ext/dummy.model.yml rename to go/ql/lib/ext/empty.model.yml diff --git a/java/ql/lib/ext/dummy.model.yml b/java/ql/lib/ext/empty.model.yml similarity index 100% rename from java/ql/lib/ext/dummy.model.yml rename to java/ql/lib/ext/empty.model.yml diff --git a/java/ql/lib/ext/experimental/dummy.model.yml b/java/ql/lib/ext/experimental/empty.model.yml similarity index 100% rename from java/ql/lib/ext/experimental/dummy.model.yml rename to java/ql/lib/ext/experimental/empty.model.yml diff --git a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/model.yml b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/empty.model.yml similarity index 100% rename from javascript/ql/lib/semmle/javascript/frameworks/data/internal/model.yml rename to javascript/ql/lib/semmle/javascript/frameworks/data/internal/empty.model.yml diff --git a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/model.yml b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/empty.model.yml similarity index 100% rename from ruby/ql/lib/codeql/ruby/frameworks/data/internal/model.yml rename to ruby/ql/lib/codeql/ruby/frameworks/data/internal/empty.model.yml From 16dcc0969bca2f1f7a7c0906ebe114d5fc942ecc Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 1 May 2024 22:00:01 +0100 Subject: [PATCH 146/238] Standardise comment explaining why extensible predicates must be defined --- csharp/ql/lib/ext/empty.model.yml | 2 ++ go/ql/lib/ext/empty.model.yml | 3 ++- java/ql/lib/ext/empty.model.yml | 5 +++-- java/ql/lib/ext/experimental/empty.model.yml | 4 ++-- .../javascript/frameworks/data/internal/empty.model.yml | 3 ++- .../semmle/python/frameworks/data/internal/empty.model.yml | 3 ++- .../lib/codeql/ruby/frameworks/data/internal/empty.model.yml | 3 ++- 7 files changed, 15 insertions(+), 8 deletions(-) diff --git a/csharp/ql/lib/ext/empty.model.yml b/csharp/ql/lib/ext/empty.model.yml index a041c1f649b1..f71119f47de5 100644 --- a/csharp/ql/lib/ext/empty.model.yml +++ b/csharp/ql/lib/ext/empty.model.yml @@ -1,4 +1,6 @@ extensions: + # Make sure that the extensible model predicates have at least one definition + # to avoid errors about an undefined extensionals. - addsTo: pack: codeql/csharp-all extensible: sourceModel diff --git a/go/ql/lib/ext/empty.model.yml b/go/ql/lib/ext/empty.model.yml index e04298be8ba4..414145a18c58 100644 --- a/go/ql/lib/ext/empty.model.yml +++ b/go/ql/lib/ext/empty.model.yml @@ -1,5 +1,6 @@ extensions: - # Make sure that the extensible model predicates are at least defined as empty. + # Make sure that the extensible model predicates have at least one definition + # to avoid errors about an undefined extensionals. - addsTo: pack: codeql/go-all extensible: sourceModel diff --git a/java/ql/lib/ext/empty.model.yml b/java/ql/lib/ext/empty.model.yml index 0269fe72311f..f36a853ba26b 100644 --- a/java/ql/lib/ext/empty.model.yml +++ b/java/ql/lib/ext/empty.model.yml @@ -1,5 +1,6 @@ extensions: - # Make sure that the extensible model predicates are at least defined as empty. + # Make sure that the extensible model predicates have at least one definition + # to avoid errors about an undefined extensionals. - addsTo: pack: codeql/java-all extensible: sourceModel @@ -15,4 +16,4 @@ extensions: - addsTo: pack: codeql/java-all extensible: neutralModel - data: [] \ No newline at end of file + data: [] diff --git a/java/ql/lib/ext/experimental/empty.model.yml b/java/ql/lib/ext/experimental/empty.model.yml index b43cb611b663..fc44e61db78e 100644 --- a/java/ql/lib/ext/experimental/empty.model.yml +++ b/java/ql/lib/ext/experimental/empty.model.yml @@ -1,6 +1,6 @@ -# Define the extensible prediactes related to experimental queries -# to at least be empty. extensions: + # Make sure that the extensible model predicates have at least one definition + # to avoid errors about an undefined extensionals. - addsTo: pack: codeql/java-all extensible: experimentalSourceModel diff --git a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/empty.model.yml b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/empty.model.yml index 016192a224ae..f6d1436f92ba 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/empty.model.yml +++ b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/empty.model.yml @@ -1,5 +1,6 @@ extensions: - # Contribute empty data sets to avoid errors about an undefined extensionals + # Make sure that the extensible model predicates have at least one definition + # to avoid errors about an undefined extensionals. - addsTo: pack: codeql/javascript-all extensible: sourceModel diff --git a/python/ql/lib/semmle/python/frameworks/data/internal/empty.model.yml b/python/ql/lib/semmle/python/frameworks/data/internal/empty.model.yml index 49a1f01983f2..4fa217f2e9ca 100644 --- a/python/ql/lib/semmle/python/frameworks/data/internal/empty.model.yml +++ b/python/ql/lib/semmle/python/frameworks/data/internal/empty.model.yml @@ -1,5 +1,6 @@ extensions: - # Contribute empty data sets to avoid errors about an undefined extensionals + # Make sure that the extensible model predicates have at least one definition + # to avoid errors about an undefined extensionals. - addsTo: pack: codeql/python-all extensible: sourceModel diff --git a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/empty.model.yml b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/empty.model.yml index 7dd7c7a9c0cb..185d81333159 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/empty.model.yml +++ b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/empty.model.yml @@ -1,5 +1,6 @@ extensions: - # Contribute empty data sets to avoid errors about an undefined extensionals + # Make sure that the extensible model predicates have at least one definition + # to avoid errors about an undefined extensionals. - addsTo: pack: codeql/ruby-all extensible: sourceModel From 677520aa8e8aa815cc743116c3a881064289458f Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Tue, 30 Apr 2024 09:00:14 +0200 Subject: [PATCH 147/238] Bazel: improved lazy lfs files This reintroduces lazy lfs file rules that were removed in https://github.com/github/codeql/pull/16117, now improved. The new rules will make the actual file download go through bazel's download manager, which includes: * caching into the repository cache * sane limiting of concurrent downloads * retries The bulk of the work is done by `git_lfs_probe.py`, which will use the LFS protocol (with authentication via SSH) to output short lived download URLs that can be consumed by `repository_ctx.download`. --- .lfsconfig | 5 ++ misc/bazel/internal/BUILD.bazel | 0 misc/bazel/internal/git_lfs_probe.py | 112 +++++++++++++++++++++++++++ misc/bazel/lfs.bzl | 79 +++++++++++++++++++ 4 files changed, 196 insertions(+) create mode 100644 .lfsconfig create mode 100644 misc/bazel/internal/BUILD.bazel create mode 100755 misc/bazel/internal/git_lfs_probe.py create mode 100644 misc/bazel/lfs.bzl diff --git a/.lfsconfig b/.lfsconfig new file mode 100644 index 000000000000..cb0a8e352e86 --- /dev/null +++ b/.lfsconfig @@ -0,0 +1,5 @@ +[lfs] +# codeql is publicly forked by many users, and we don't want any LFS file polluting their working +# copies. We therefore exclude everything by default. +# For files required by bazel builds, use rules in `misc/bazel/lfs.bzl` to download them on demand. +fetchinclude = /nothing diff --git a/misc/bazel/internal/BUILD.bazel b/misc/bazel/internal/BUILD.bazel new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/misc/bazel/internal/git_lfs_probe.py b/misc/bazel/internal/git_lfs_probe.py new file mode 100755 index 000000000000..3d0ed7679a34 --- /dev/null +++ b/misc/bazel/internal/git_lfs_probe.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python3 + +""" +Probe lfs files. +For each source file provided as output, this will print: +* "local", if the source file is not an LFS pointer +* the sha256 hash, a space character and a transient download link obtained via the LFS protocol otherwise +""" + +import sys +import pathlib +import subprocess +import os +import shutil +import json +import urllib.request +from urllib.parse import urlparse +import re + +sources = [pathlib.Path(arg).resolve() for arg in sys.argv[1:]] +source_dir = pathlib.Path(os.path.commonpath(src.parent for src in sources)) +source_dir = subprocess.check_output(["git", "rev-parse", "--show-toplevel"], cwd=source_dir, text=True).strip() + + +def get_endpoint(): + lfs_env = subprocess.check_output(["git", "lfs", "env"], text=True, cwd=source_dir) + endpoint = ssh_server = ssh_path = None + endpoint_re = re.compile(r'Endpoint(?: \(\S+\))?=(\S+)') + ssh_re = re.compile(r'\s*SSH=(\S*):(.*)') + for line in lfs_env.splitlines(): + m = endpoint_re.match(line) + if m: + if endpoint is None: + endpoint = m[1] + else: + break + m = ssh_re.match(line) + if m: + ssh_server, ssh_path = m.groups() + break + assert endpoint, f"no Endpoint= line found in git lfs env:\n{lfs_env}" + headers = { + "Content-Type": "application/vnd.git-lfs+json", + "Accept": "application/vnd.git-lfs+json", + } + if ssh_server: + ssh_command = shutil.which(os.environ.get("GIT_SSH", os.environ.get("GIT_SSH_COMMAND", "ssh"))) + assert ssh_command, "no ssh command found" + with subprocess.Popen([ssh_command, ssh_server, "git-lfs-authenticate", ssh_path, "download"], + stdout=subprocess.PIPE) as ssh: + resp = json.load(ssh.stdout) + assert ssh.wait() == 0, "ssh command failed" + endpoint = resp.get("href", endpoint) + for k, v in resp.get("header", {}).items(): + headers[k.capitalize()] = v + url = urlparse(endpoint) + # this is how actions/checkout persist credentials + # see https://github.com/actions/checkout/blob/44c2b7a8a4ea60a981eaca3cf939b5f4305c123b/src/git-auth-helper.ts#L56-L63 + auth = subprocess.run(["git", "config", f"http.{url.scheme}://{url.netloc}/.extraheader"], text=True, + stdout=subprocess.PIPE, cwd=source_dir).stdout.strip() + for l in auth.splitlines(): + k, _, v = l.partition(": ") + headers[k.capitalize()] = v + if "GITHUB_TOKEN" in os.environ: + headers["Authorization"] = f"token {os.environ['GITHUB_TOKEN']}" + return endpoint, headers + + +# see https://github.com/git-lfs/git-lfs/blob/310d1b4a7d01e8d9d884447df4635c7a9c7642c2/docs/api/basic-transfers.md +def get_locations(objects): + href, headers = get_endpoint() + indexes = [i for i, o in enumerate(objects) if o] + ret = ["local" for _ in objects] + req = urllib.request.Request( + f"{href}/objects/batch", + headers=headers, + data=json.dumps({ + "operation": "download", + "transfers": ["basic"], + "objects": [o for o in objects if o], + "hash_algo": "sha256", + }).encode("ascii"), + ) + with urllib.request.urlopen(req) as resp: + data = json.load(resp) + assert len(data["objects"]) == len(indexes), data + for i, resp in zip(indexes, data["objects"]): + ret[i] = f'{resp["oid"]} {resp["actions"]["download"]["href"]}' + return ret + + +def get_lfs_object(path): + with open(path, 'rb') as fileobj: + lfs_header = "version https://git-lfs.github.com/spec".encode() + actual_header = fileobj.read(len(lfs_header)) + sha256 = size = None + if lfs_header != actual_header: + return None + for line in fileobj: + line = line.decode('ascii').strip() + if line.startswith("oid sha256:"): + sha256 = line[len("oid sha256:"):] + elif line.startswith("size "): + size = int(line[len("size "):]) + if not (sha256 and line): + raise Exception("malformed pointer file") + return {"oid": sha256, "size": size} + + +objects = [get_lfs_object(src) for src in sources] +for resp in get_locations(objects): + print(resp) diff --git a/misc/bazel/lfs.bzl b/misc/bazel/lfs.bzl new file mode 100644 index 000000000000..0f6f981d861b --- /dev/null +++ b/misc/bazel/lfs.bzl @@ -0,0 +1,79 @@ +def lfs_smudge(repository_ctx, srcs): + for src in srcs: + repository_ctx.watch(src) + script = Label("//misc/bazel/internal:git_lfs_probe.py") + python = repository_ctx.which("python3") or repository_ctx.which("python") + if not python: + fail("Neither python3 nor python executables found") + res = repository_ctx.execute([python, script] + srcs, quiet = True) + if res.return_code != 0: + fail("git LFS probing failed while instantiating @%s:\n%s" % (repository_ctx.name, res.stderr)) + for src, loc in zip(srcs, res.stdout.splitlines()): + if loc == "local": + repository_ctx.symlink(src, src.basename) + else: + sha256, _, url = loc.partition(" ") + repository_ctx.download(url, src.basename, sha256 = sha256) + +def _download_and_extract_lfs(repository_ctx): + attr = repository_ctx.attr + src = repository_ctx.path(attr.src) + if attr.build_file_content and attr.build_file: + fail("You should specify only one among build_file_content and build_file for rule @%s" % repository_ctx.name) + lfs_smudge(repository_ctx, [src]) + repository_ctx.extract(src.basename, stripPrefix = attr.strip_prefix) + repository_ctx.delete(src.basename) + if attr.build_file_content: + repository_ctx.file("BUILD.bazel", attr.build_file_content) + elif attr.build_file: + repository_ctx.symlink(attr.build_file, "BUILD.bazel") + +def _download_lfs(repository_ctx): + attr = repository_ctx.attr + if int(bool(attr.srcs)) + int(bool(attr.dir)) != 1: + fail("Exactly one between `srcs` and `dir` must be defined for @%s" % repository_ctx.name) + if attr.srcs: + srcs = [repository_ctx.path(src) for src in attr.srcs] + else: + dir = repository_ctx.path(attr.dir) + if not dir.is_dir: + fail("`dir` not a directory in @%s" % repository_ctx.name) + srcs = [f for f in dir.readdir() if not f.is_dir] + lfs_smudge(repository_ctx, srcs) + + # with bzlmod the name is qualified with `~` separators, and we want the base name here + name = repository_ctx.name.split("~")[-1] + repository_ctx.file("BUILD.bazel", """ +exports_files({files}) + +filegroup( + name = "{name}", + srcs = {files}, + visibility = ["//visibility:public"], +) +""".format(name = name, files = repr([src.basename for src in srcs]))) + +lfs_archive = repository_rule( + doc = "Export the contents from an on-demand LFS archive. The corresponding path should be added to be ignored " + + "in `.lfsconfig`.", + implementation = _download_and_extract_lfs, + attrs = { + "src": attr.label(mandatory = True, doc = "Local path to the LFS archive to extract."), + "build_file_content": attr.string(doc = "The content for the BUILD file for this repository. " + + "Either build_file or build_file_content can be specified, but not both."), + "build_file": attr.label(doc = "The file to use as the BUILD file for this repository. " + + "Either build_file or build_file_content can be specified, but not both."), + "strip_prefix": attr.string(default = "", doc = "A directory prefix to strip from the extracted files. "), + }, +) + +lfs_files = repository_rule( + doc = "Export LFS files for on-demand download. Exactly one between `srcs` and `dir` must be defined. The " + + "corresponding paths should be added to be ignored in `.lfsconfig`.", + implementation = _download_lfs, + attrs = { + "srcs": attr.label_list(doc = "Local paths to the LFS files to export."), + "dir": attr.label(doc = "Local path to a directory containing LFS files to export. Only the direct contents " + + "of the directory are exported"), + }, +) From 9157dee0db4b2606bec4a0b0c1ec7e6b4067f442 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 2 May 2024 08:53:51 +0200 Subject: [PATCH 148/238] Bazel: integrate `download_and_extract` into `lfs_smudge` --- misc/bazel/lfs.bzl | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/misc/bazel/lfs.bzl b/misc/bazel/lfs.bzl index 0f6f981d861b..1f9c8972923f 100644 --- a/misc/bazel/lfs.bzl +++ b/misc/bazel/lfs.bzl @@ -1,4 +1,4 @@ -def lfs_smudge(repository_ctx, srcs): +def lfs_smudge(repository_ctx, srcs, extract = False, stripPrefix = None): for src in srcs: repository_ctx.watch(src) script = Label("//misc/bazel/internal:git_lfs_probe.py") @@ -10,19 +10,28 @@ def lfs_smudge(repository_ctx, srcs): fail("git LFS probing failed while instantiating @%s:\n%s" % (repository_ctx.name, res.stderr)) for src, loc in zip(srcs, res.stdout.splitlines()): if loc == "local": - repository_ctx.symlink(src, src.basename) + if extract: + repository_ctx.extract(src, stripPrefix = stripPrefix) + else: + repository_ctx.symlink(src, src.basename) else: sha256, _, url = loc.partition(" ") - repository_ctx.download(url, src.basename, sha256 = sha256) + if extract: + # we can't use skylib's `paths.split_extension`, as that only gets the last extension, so `.tar.gz` + # or similar wouldn't work + # it doesn't matter if file is something like some.name.zip and possible_extension == "name.zip", + # download_and_extract will just append ".name.zip" its internal temporary name, so extraction works + possible_extension = ".".join(src.basename.rsplit(".", 2)[-2:]) + repository_ctx.download_and_extract(url, sha256 = sha256, stripPrefix = stripPrefix, type = possible_extension) + else: + repository_ctx.download(url, src.basename, sha256 = sha256) def _download_and_extract_lfs(repository_ctx): attr = repository_ctx.attr src = repository_ctx.path(attr.src) if attr.build_file_content and attr.build_file: fail("You should specify only one among build_file_content and build_file for rule @%s" % repository_ctx.name) - lfs_smudge(repository_ctx, [src]) - repository_ctx.extract(src.basename, stripPrefix = attr.strip_prefix) - repository_ctx.delete(src.basename) + lfs_smudge(repository_ctx, [src], extract = True, stripPrefix = attr.strip_prefix) if attr.build_file_content: repository_ctx.file("BUILD.bazel", attr.build_file_content) elif attr.build_file: From 608791fd7f99166b6f6daba5b27f9abb7c37bac9 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 2 May 2024 09:13:40 +0200 Subject: [PATCH 149/238] Bazel/Go: use native cross compilation for fat binaries --- go/rules.bzl | 40 +++++++++++++++++++++++++++++---- misc/bazel/universal_binary.bzl | 24 -------------------- 2 files changed, 36 insertions(+), 28 deletions(-) delete mode 100644 misc/bazel/universal_binary.bzl diff --git a/go/rules.bzl b/go/rules.bzl index 4ef798001d2a..e26dd57bf449 100644 --- a/go/rules.bzl +++ b/go/rules.bzl @@ -1,5 +1,37 @@ -load("@rules_go//go:def.bzl", "go_binary") -load("//misc/bazel:universal_binary.bzl", "wrap_as_universal_binary") +load("@rules_go//go:def.bzl", "go_binary", "go_cross_binary") -def codeql_go_binary(**kwargs): - wrap_as_universal_binary(go_binary, **kwargs) +def codeql_go_binary(*, name, visibility = None, **kwargs): + def internal(prefix = "internal"): + return "%s/%s" % (prefix, name) + + go_binary( + name = internal(), + visibility = ["//visibility:private"], + **kwargs + ) + macos_targets = ("darwin_arm64", "darwin_amd64") + for target in macos_targets: + go_cross_binary( + name = internal(target), + platform = "@rules_go//go/toolchain:%s" % target, + target = internal(), + target_compatible_with = ["@platforms//os:macos"], + visibility = ["//visibility:private"], + ) + native.genrule( + name = internal("universal"), + outs = [internal("universal_")], + srcs = [internal(t) for t in macos_targets], + target_compatible_with = ["@platforms//os:macos"], + executable = True, + visibility = ["//visibility:private"], + cmd = "lipo -create $(SRCS) -output $@", + ) + native.alias( + name = name, + actual = select({ + "@platforms//os:macos": internal("universal"), + "//conditions:default": internal(), + }), + visibility = visibility, + ) diff --git a/misc/bazel/universal_binary.bzl b/misc/bazel/universal_binary.bzl deleted file mode 100644 index 85881356d0eb..000000000000 --- a/misc/bazel/universal_binary.bzl +++ /dev/null @@ -1,24 +0,0 @@ -load("@apple_support//rules:universal_binary.bzl", _universal_binary = "universal_binary") - -def wrap_as_universal_binary(rule, *, name, visibility = None, **kwargs): - internal_name = "internal/%s" % name - universal_name = "universal/%s" % name - rule( - name = internal_name, - visibility = ["//visibility:private"], - **kwargs - ) - _universal_binary( - name = universal_name, - target_compatible_with = ["@platforms//os:macos"], - binary = internal_name, - visibility = ["//visibility:private"], - ) - native.alias( - name = name, - actual = select({ - "@platforms//os:macos": universal_name, - "//conditions:default": internal_name, - }), - visibility = visibility, - ) From 94212d103ec3cffd91f5efcffa668db36f99b7a7 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 2 May 2024 09:14:15 +0200 Subject: [PATCH 150/238] Bazel/Go: remove `apple_support` This was actually unnecessary, and requried a full Xcode installation that we'd rather avoid. --- MODULE.bazel | 5 ----- go/BUILD.bazel | 13 ------------ .../1.15.1-codeql.1/MODULE.bazel | 17 ---------------- .../1.15.1-codeql.1/patches/module.patch | 20 ------------------- .../apple_support/1.15.1-codeql.1/source.json | 9 --------- .../modules/apple_support/metadata.json | 5 ----- 6 files changed, 69 deletions(-) delete mode 100644 misc/bazel/registry/modules/apple_support/1.15.1-codeql.1/MODULE.bazel delete mode 100644 misc/bazel/registry/modules/apple_support/1.15.1-codeql.1/patches/module.patch delete mode 100644 misc/bazel/registry/modules/apple_support/1.15.1-codeql.1/source.json delete mode 100644 misc/bazel/registry/modules/apple_support/metadata.json diff --git a/MODULE.bazel b/MODULE.bazel index 875e61da383a..d069d320f07a 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -13,7 +13,6 @@ local_path_override( # see https://registry.bazel.build/ for a list of available packages -bazel_dep(name = "apple_support", version = "1.15.1-codeql.1") bazel_dep(name = "platforms", version = "0.0.9") bazel_dep(name = "rules_go", version = "0.47.0") bazel_dep(name = "rules_pkg", version = "0.10.1") @@ -58,10 +57,6 @@ use_repo(node, "nodejs", "nodejs_toolchains") go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk") go_sdk.download(version = "1.22.2") # default -# following is needed for gazelle on macOS -# see https://github.com/bazelbuild/bazel-gazelle/issues/1793 -go_sdk.download(version = "1.21.9") - register_toolchains( "@nodejs_toolchains//:all", ) diff --git a/go/BUILD.bazel b/go/BUILD.bazel index 4251ebd228f2..6c80e7cb258c 100644 --- a/go/BUILD.bazel +++ b/go/BUILD.bazel @@ -1,26 +1,13 @@ load("@bazel_skylib//rules:native_binary.bzl", "native_binary") load("@gazelle//:def.bzl", "gazelle") -load("@rules_go//go:def.bzl", "go_cross_binary") load("@rules_pkg//pkg:install.bzl", "pkg_install") load("@rules_pkg//pkg:mappings.bzl", "pkg_attributes", "pkg_filegroup", "pkg_files") load("@rules_pkg//pkg:zip.bzl", "pkg_zip") load("//:defs.bzl", "codeql_platform") -# following is needed for running gazelle on macOS -# see https://github.com/bazelbuild/bazel-gazelle/issues/1793 -go_cross_binary( - name = "gazelle-1.21.9", - sdk_version = "1.21.9", - target = "@gazelle//cmd/gazelle", -) - gazelle( name = "gazelle", extra_args = ["go/extractor"], - gazelle = select({ - "@platforms//os:macos": ":gazelle-1.21.9", - "//conditions:default": "@gazelle//cmd/gazelle", - }), ) _gen_binaries = [ diff --git a/misc/bazel/registry/modules/apple_support/1.15.1-codeql.1/MODULE.bazel b/misc/bazel/registry/modules/apple_support/1.15.1-codeql.1/MODULE.bazel deleted file mode 100644 index a58d520fee20..000000000000 --- a/misc/bazel/registry/modules/apple_support/1.15.1-codeql.1/MODULE.bazel +++ /dev/null @@ -1,17 +0,0 @@ -module( - name = "apple_support", - version = "1.15.1-codeql.1", - bazel_compatibility = [">=6.0.0"], - compatibility_level = 1, - repo_name = "build_bazel_apple_support", -) - -bazel_dep(name = "bazel_skylib", version = "1.3.0") -bazel_dep(name = "platforms", version = "0.0.9") - -bazel_dep( - name = "stardoc", - version = "0.6.2", - dev_dependency = True, - repo_name = "io_bazel_stardoc", -) diff --git a/misc/bazel/registry/modules/apple_support/1.15.1-codeql.1/patches/module.patch b/misc/bazel/registry/modules/apple_support/1.15.1-codeql.1/patches/module.patch deleted file mode 100644 index 59fc49ec7b37..000000000000 --- a/misc/bazel/registry/modules/apple_support/1.15.1-codeql.1/patches/module.patch +++ /dev/null @@ -1,20 +0,0 @@ -diff --git a/MODULE.bazel b/MODULE.bazel -index 6b06c3b..99bc7c6 100644 ---- a/MODULE.bazel -+++ b/MODULE.bazel -@@ -1,6 +1,6 @@ - module( - name = "apple_support", -- version = "0", -+ version = "1.15.1-codeql.1", - bazel_compatibility = [">=6.0.0"], - compatibility_level = 1, - repo_name = "build_bazel_apple_support", -@@ -16,7 +16,3 @@ bazel_dep( - repo_name = "io_bazel_stardoc", - ) - --apple_cc_configure = use_extension("//crosstool:setup.bzl", "apple_cc_configure_extension") --use_repo(apple_cc_configure, "local_config_apple_cc", "local_config_apple_cc_toolchains") -- --register_toolchains("@local_config_apple_cc_toolchains//:all") diff --git a/misc/bazel/registry/modules/apple_support/1.15.1-codeql.1/source.json b/misc/bazel/registry/modules/apple_support/1.15.1-codeql.1/source.json deleted file mode 100644 index 57a1f2137fea..000000000000 --- a/misc/bazel/registry/modules/apple_support/1.15.1-codeql.1/source.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "integrity": "sha256-xLsrc2fEhDgjAK7nW+WYuS+EeJb7MbvSLzojRq32aoA=", - "strip_prefix": "", - "url": "https://github.com/bazelbuild/apple_support/releases/download/1.15.1/apple_support.1.15.1.tar.gz", - "patches": { - "module.patch": "sha256-K06B2W9t6nKcU8S5u6cWeNIdw/vGWWKAoJdGiI8CSS0=" - }, - "patch_strip": 1 -} diff --git a/misc/bazel/registry/modules/apple_support/metadata.json b/misc/bazel/registry/modules/apple_support/metadata.json deleted file mode 100644 index 8a0e54c9abd9..000000000000 --- a/misc/bazel/registry/modules/apple_support/metadata.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "versions": [ - "1.15.1-codeql.1" - ] -} From 9ce08c586ce09dff2fb33d9dc745aeb1176fcf95 Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Thu, 2 May 2024 10:14:26 +0200 Subject: [PATCH 151/238] C#: Add file path to log messages in assets.json parsing --- .../Assets.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/Assets.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/Assets.cs index 4082146f5920..9308a137e7e3 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/Assets.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/Assets.cs @@ -77,7 +77,7 @@ private record class ReferenceInfo(string? Type, Dictionary? Com /// "json.net" /// } /// - private void AddPackageDependencies(JObject json) + private void AddPackageDependencies(JObject json, string jsonPath) { // If there is more than one framework we need to pick just one. // To ensure stability we pick one based on the lexicographic order of @@ -91,7 +91,7 @@ private void AddPackageDependencies(JObject json) if (references is null) { - logger.LogDebug("No references found in the targets section in the assets file."); + logger.LogDebug($"No references found in the targets section in '{jsonPath}'"); return; } @@ -154,7 +154,7 @@ private void AddPackageDependencies(JObject json) /// "microsoft.netcore.app.ref" /// } /// - private void AddFrameworkDependencies(JObject json) + private void AddFrameworkDependencies(JObject json, string jsonPath) { var frameworks = json @@ -163,7 +163,7 @@ private void AddFrameworkDependencies(JObject json) if (frameworks is null) { - logger.LogDebug("No framework section in assets.json."); + logger.LogDebug($"No framework section in '{jsonPath}'."); return; } @@ -177,7 +177,7 @@ private void AddFrameworkDependencies(JObject json) if (references is null) { - logger.LogDebug("No framework references in assets.json."); + logger.LogDebug($"No framework references in '{jsonPath}'."); return; } @@ -196,8 +196,8 @@ public bool TryParse(string json) try { var obj = JObject.Parse(json); - AddPackageDependencies(obj); - AddFrameworkDependencies(obj); + AddPackageDependencies(obj, json); + AddFrameworkDependencies(obj, json); return true; } catch (Exception e) From c6185b30ba2f9c5881d3418f242717fd50da293c Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Thu, 2 May 2024 10:25:12 +0200 Subject: [PATCH 152/238] C#: Change nuget feed responsiveness checking to be opt-out --- .../NugetPackageRestorer.cs | 5 ++++- .../SourceGenerators/RazorGenerator.cs | 14 +++----------- .../extractor/Semmle.Util/EnvironmentVariables.cs | 13 +++++++++++++ .../test.py | 2 +- 4 files changed, 21 insertions(+), 13 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs index 07fb8d2c89d6..5e556682df21 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs @@ -94,7 +94,10 @@ public static DirectoryInfo[] GetOrderedPackageVersionSubDirectories(string pack public HashSet Restore() { var assemblyLookupLocations = new HashSet(); - var checkNugetFeedResponsiveness = EnvironmentVariables.GetBoolean(EnvironmentVariableNames.CheckNugetFeedResponsiveness); + var checkNugetFeedResponsiveness = EnvironmentVariables.GetBooleanOptOut(EnvironmentVariableNames.CheckNugetFeedResponsiveness); + logger.LogInfo($"Checking NuGet feed responsiveness: {checkNugetFeedResponsiveness}"); + compilationInfoContainer.CompilationInfos.Add(("NuGet feed responsiveness checked", checkNugetFeedResponsiveness ? "1" : "0")); + try { if (checkNugetFeedResponsiveness && !CheckFeeds()) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/SourceGenerators/RazorGenerator.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/SourceGenerators/RazorGenerator.cs index b2670e023e56..3f9a17dc6b30 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/SourceGenerators/RazorGenerator.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/SourceGenerators/RazorGenerator.cs @@ -20,17 +20,9 @@ public RazorGenerator( protected override bool IsEnabled() { - var webViewExtractionOption = Environment.GetEnvironmentVariable(EnvironmentVariableNames.WebViewGeneration); - if (webViewExtractionOption == null || - bool.TryParse(webViewExtractionOption, out var shouldExtractWebViews) && - shouldExtractWebViews) - { - compilationInfoContainer.CompilationInfos.Add(("WebView extraction enabled", "1")); - return true; - } - - compilationInfoContainer.CompilationInfos.Add(("WebView extraction enabled", "0")); - return false; + var webViewExtractionOption = EnvironmentVariables.GetBooleanOptOut(EnvironmentVariableNames.WebViewGeneration); + compilationInfoContainer.CompilationInfos.Add(("WebView extraction enabled", webViewExtractionOption ? "1" : "0")); + return webViewExtractionOption; } protected override ICollection AdditionalFiles => fileProvider.RazorViews; diff --git a/csharp/extractor/Semmle.Util/EnvironmentVariables.cs b/csharp/extractor/Semmle.Util/EnvironmentVariables.cs index c8c272e94ad9..076507d07e0a 100644 --- a/csharp/extractor/Semmle.Util/EnvironmentVariables.cs +++ b/csharp/extractor/Semmle.Util/EnvironmentVariables.cs @@ -29,6 +29,19 @@ public static int GetDefaultNumberOfThreads() return threads; } + public static bool GetBooleanOptOut(string name) + { + var env = Environment.GetEnvironmentVariable(name); + if (env == null || + bool.TryParse(env, out var value) && + value) + { + return true; + } + + return false; + } + public static bool GetBoolean(string name) { var env = Environment.GetEnvironmentVariable(name); diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error_timeout/test.py b/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error_timeout/test.py index 0b290510983e..7345609d4d61 100644 --- a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error_timeout/test.py +++ b/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error_timeout/test.py @@ -2,7 +2,7 @@ from diagnostics_test_utils import * import os -os.environ["CODEQL_EXTRACTOR_CSHARP_BUILDLESS_NUGET_FEEDS_CHECK"] = "true" # Enable NuGet feed check +# os.environ["CODEQL_EXTRACTOR_CSHARP_BUILDLESS_NUGET_FEEDS_CHECK"] = "true" # Nuget feed check is enabled by default os.environ["CODEQL_EXTRACTOR_CSHARP_BUILDLESS_NUGET_FEEDS_CHECK_TIMEOUT"] = "1" # 1ms, the GET request should fail with such short timeout os.environ["CODEQL_EXTRACTOR_CSHARP_BUILDLESS_NUGET_FEEDS_CHECK_LIMIT"] = "1" # Limit the count of checks to 1 os.environ["CODEQL_EXTRACTOR_CSHARP_BUILDLESS_NUGET_FEEDS_CHECK_EXCLUDED"] = "https://abc.de:8000/packages/" # Exclude this feed from check From 83249cd9c2234f6af96fb6bd920af518fd369d15 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 2 May 2024 09:59:48 +0100 Subject: [PATCH 153/238] Fix grammar in comment --- csharp/ql/lib/ext/empty.model.yml | 2 +- go/ql/lib/ext/empty.model.yml | 2 +- java/ql/lib/ext/empty.model.yml | 2 +- java/ql/lib/ext/experimental/empty.model.yml | 2 +- .../semmle/javascript/frameworks/data/internal/empty.model.yml | 2 +- .../lib/semmle/python/frameworks/data/internal/empty.model.yml | 2 +- .../ql/lib/codeql/ruby/frameworks/data/internal/empty.model.yml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/csharp/ql/lib/ext/empty.model.yml b/csharp/ql/lib/ext/empty.model.yml index f71119f47de5..6b38b783cbe2 100644 --- a/csharp/ql/lib/ext/empty.model.yml +++ b/csharp/ql/lib/ext/empty.model.yml @@ -1,6 +1,6 @@ extensions: # Make sure that the extensible model predicates have at least one definition - # to avoid errors about an undefined extensionals. + # to avoid errors about undefined extensionals. - addsTo: pack: codeql/csharp-all extensible: sourceModel diff --git a/go/ql/lib/ext/empty.model.yml b/go/ql/lib/ext/empty.model.yml index 414145a18c58..03279fc65880 100644 --- a/go/ql/lib/ext/empty.model.yml +++ b/go/ql/lib/ext/empty.model.yml @@ -1,6 +1,6 @@ extensions: # Make sure that the extensible model predicates have at least one definition - # to avoid errors about an undefined extensionals. + # to avoid errors about undefined extensionals. - addsTo: pack: codeql/go-all extensible: sourceModel diff --git a/java/ql/lib/ext/empty.model.yml b/java/ql/lib/ext/empty.model.yml index f36a853ba26b..43028e7cc14e 100644 --- a/java/ql/lib/ext/empty.model.yml +++ b/java/ql/lib/ext/empty.model.yml @@ -1,6 +1,6 @@ extensions: # Make sure that the extensible model predicates have at least one definition - # to avoid errors about an undefined extensionals. + # to avoid errors about undefined extensionals. - addsTo: pack: codeql/java-all extensible: sourceModel diff --git a/java/ql/lib/ext/experimental/empty.model.yml b/java/ql/lib/ext/experimental/empty.model.yml index fc44e61db78e..b1ee4d24cdfa 100644 --- a/java/ql/lib/ext/experimental/empty.model.yml +++ b/java/ql/lib/ext/experimental/empty.model.yml @@ -1,6 +1,6 @@ extensions: # Make sure that the extensible model predicates have at least one definition - # to avoid errors about an undefined extensionals. + # to avoid errors about undefined extensionals. - addsTo: pack: codeql/java-all extensible: experimentalSourceModel diff --git a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/empty.model.yml b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/empty.model.yml index f6d1436f92ba..12f83f71e55b 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/empty.model.yml +++ b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/empty.model.yml @@ -1,6 +1,6 @@ extensions: # Make sure that the extensible model predicates have at least one definition - # to avoid errors about an undefined extensionals. + # to avoid errors about undefined extensionals. - addsTo: pack: codeql/javascript-all extensible: sourceModel diff --git a/python/ql/lib/semmle/python/frameworks/data/internal/empty.model.yml b/python/ql/lib/semmle/python/frameworks/data/internal/empty.model.yml index 4fa217f2e9ca..ea9b9fce546b 100644 --- a/python/ql/lib/semmle/python/frameworks/data/internal/empty.model.yml +++ b/python/ql/lib/semmle/python/frameworks/data/internal/empty.model.yml @@ -1,6 +1,6 @@ extensions: # Make sure that the extensible model predicates have at least one definition - # to avoid errors about an undefined extensionals. + # to avoid errors about undefined extensionals. - addsTo: pack: codeql/python-all extensible: sourceModel diff --git a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/empty.model.yml b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/empty.model.yml index 185d81333159..b887eed7c1c5 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/empty.model.yml +++ b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/empty.model.yml @@ -1,6 +1,6 @@ extensions: # Make sure that the extensible model predicates have at least one definition - # to avoid errors about an undefined extensionals. + # to avoid errors about undefined extensionals. - addsTo: pack: codeql/ruby-all extensible: sourceModel From 4a47e11a164a731ae7a5eb1afca102bb854e1071 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Thu, 2 May 2024 10:36:40 +0100 Subject: [PATCH 154/238] C++: Fix QLDoc. --- .../lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll index bedaaee487d3..c347f7084ed5 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll @@ -769,7 +769,8 @@ private predicate adjustForPointerArith(PostUpdateNode pun, SourceVariable sv, I * `nodeFrom` is a definition or use of `sv` at index `i1` at basic * block `bb1`. * - * `uncertain` is `true` if the this is an uncertain definition. + * `uncertain` is `true` if `(bb1, i1)` is a definition, and that definition + * is guaranteed to overwrite the entire allocation. */ private predicate ssaFlowImpl( IRBlock bb1, int i1, SourceVariable sv, Node nodeFrom, Node nodeTo, boolean uncertain From 322fa363596771e7dc22c600f115c1feac72542d Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Thu, 2 May 2024 10:37:49 +0100 Subject: [PATCH 155/238] C++: Fix QLDoc. --- .../lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll | 3 --- 1 file changed, 3 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll index c347f7084ed5..294b35e2751e 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll @@ -1114,9 +1114,6 @@ abstract class Def extends SsaDef, TDef { * Gets the indirection level that this definition is writing to. * For instance, `x = y` is a definition of `x` at indirection level 1 and * `*x = y` is a definition of `x` at indirection level 2. - * - * This predicate ensures that joins go from `defOrUse` to the result - * instead of the other way around. */ abstract int getIndirection(); From 12b9b805e2f40fd72bf30c0c8178c6b04e647891 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 2 May 2024 12:37:47 +0200 Subject: [PATCH 156/238] Go: revert changes to `make` and CI to postpone them in a separate PR --- .github/workflows/go-tests-other-os.yml | 65 ++++++++++++++++-- .github/workflows/go-tests.yml | 51 +++++++++++++- go/Makefile | 89 +++++++++++++++++++++++-- 3 files changed, 191 insertions(+), 14 deletions(-) diff --git a/.github/workflows/go-tests-other-os.yml b/.github/workflows/go-tests-other-os.yml index 9915b0869db7..ded53f868b70 100644 --- a/.github/workflows/go-tests-other-os.yml +++ b/.github/workflows/go-tests-other-os.yml @@ -7,6 +7,8 @@ on: - .github/workflows/go-tests-other-os.yml - .github/actions/** - codeql-workspace.yml +env: + GO_VERSION: '~1.22.0' permissions: contents: read @@ -16,17 +18,72 @@ jobs: name: Test MacOS runs-on: macos-latest steps: + - name: Set up Go ${{ env.GO_VERSION }} + uses: actions/setup-go@v5 + with: + go-version: ${{ env.GO_VERSION }} + cache: false + id: go + - name: Check out code uses: actions/checkout@v4 - - name: Run tests - uses: ./go/actions/test + + - name: Set up CodeQL CLI + uses: ./.github/actions/fetch-codeql + + - name: Enable problem matchers in repository + shell: bash + run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;' + + - name: Build + run: | + cd go + make + + - name: Cache compilation cache + id: query-cache + uses: ./.github/actions/cache-query-compilation + with: + key: go-qltest + - name: Test + run: | + cd go + make test cache="${{ steps.query-cache.outputs.cache-dir }}" test-win: if: github.repository_owner == 'github' name: Test Windows runs-on: windows-latest-xl steps: + - name: Set up Go ${{ env.GO_VERSION }} + uses: actions/setup-go@v5 + with: + go-version: ${{ env.GO_VERSION }} + cache: false + id: go + - name: Check out code uses: actions/checkout@v4 - - name: Run tests - uses: ./go/actions/test + + - name: Set up CodeQL CLI + uses: ./.github/actions/fetch-codeql + + - name: Enable problem matchers in repository + shell: bash + run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;' + + - name: Build + run: | + cd go + make + + - name: Cache compilation cache + id: query-cache + uses: ./.github/actions/cache-query-compilation + with: + key: go-qltest + + - name: Test + run: | + cd go + make test cache="${{ steps.query-cache.outputs.cache-dir }}" diff --git a/.github/workflows/go-tests.yml b/.github/workflows/go-tests.yml index 63e2b7c49740..6d9cac5dae91 100644 --- a/.github/workflows/go-tests.yml +++ b/.github/workflows/go-tests.yml @@ -16,6 +16,9 @@ on: - .github/actions/** - codeql-workspace.yml +env: + GO_VERSION: '~1.22.0' + permissions: contents: read @@ -25,9 +28,51 @@ jobs: name: Test Linux (Ubuntu) runs-on: ubuntu-latest-xl steps: + - name: Set up Go ${{ env.GO_VERSION }} + uses: actions/setup-go@v5 + with: + go-version: ${{ env.GO_VERSION }} + cache: false + id: go + - name: Check out code uses: actions/checkout@v4 - - name: Run tests - uses: ./go/actions/test + + - name: Set up CodeQL CLI + uses: ./.github/actions/fetch-codeql + + - name: Enable problem matchers in repository + shell: bash + run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;' + + - name: Build + run: | + cd go + make + + - name: Check that all Go code is autoformatted + run: | + cd go + make check-formatting + + - name: Compile qhelp files to markdown + run: | + cd go + env QHELP_OUT_DIR=qhelp-out make qhelp-to-markdown + + - name: Upload qhelp markdown + uses: actions/upload-artifact@v3 with: - run-code-checks: true + name: qhelp-markdown + path: go/qhelp-out/**/*.md + + - name: Cache compilation cache + id: query-cache + uses: ./.github/actions/cache-query-compilation + with: + key: go-qltest + + - name: Test + run: | + cd go + make test cache="${{ steps.query-cache.outputs.cache-dir }}" diff --git a/go/Makefile b/go/Makefile index 3ebeb69fcaf1..d0289a093a52 100644 --- a/go/Makefile +++ b/go/Makefile @@ -1,10 +1,30 @@ -all: gen extractor +all: extractor ql/lib/go.dbscheme + +ifeq ($(OS),Windows_NT) +EXE = .exe +CODEQL_PLATFORM = win64 +else +EXE = +UNAME_S := $(shell uname -s) +ifeq ($(UNAME_S),Linux) +CODEQL_PLATFORM = linux64 +endif +ifeq ($(UNAME_S),Darwin) +CODEQL_PLATFORM = osx64 +endif +endif + +CODEQL_TOOLS = $(addprefix codeql-tools/,autobuild.cmd autobuild.sh baseline-config-empty.json baseline-config-vendor.json configure-baseline.cmd configure-baseline.sh identify-environment.cmd identify-environment.sh index.cmd index.sh pre-finalize.cmd pre-finalize.sh tracing-config.lua) EXTRACTOR_PACK_OUT = build/codeql-extractor-go -.PHONY: extractor gen clean autoformat check-formatting +BINARIES = go-extractor go-tokenizer go-autobuilder go-build-runner go-bootstrap go-gen-dbscheme + +.PHONY: tools tools-codeql tools-codeql-full clean autoformat \ + tools-linux64 tools-osx64 tools-win64 check-formatting clean: + rm -rf tools/bin tools/linux64 tools/osx64 tools/win64 tools/net tools/opencsv rm -rf $(EXTRACTOR_PACK_OUT) build/stats build/testdb autoformat: @@ -27,11 +47,66 @@ endif qhelp-to-markdown: scripts/qhelp-to-markdown.sh ql/src "$(QHELP_OUT_DIR)" -extractor: - bazel run :create-extractor-pack +tools: tools-codeql tools/tokenizer.jar + +.PHONY: $(addsuffix $(EXE),$(addprefix tools/bin/,$(BINARIES))) +$(addsuffix $(EXE),$(addprefix tools/bin/,$(BINARIES))): + go build -C extractor -mod=vendor -o ../$@ ./cli/$(basename $(@F)) + +tools-codeql: tools-$(CODEQL_PLATFORM) + +tools-codeql-full: tools-linux64 tools-osx64 tools-win64 + +tools-linux64: $(addprefix tools/linux64/,$(BINARIES)) + +.PHONY: $(addprefix tools/linux64/,$(BINARIES)) +$(addprefix tools/linux64/,$(BINARIES)): + GOOS=linux GOARCH=amd64 go build -C extractor -mod=vendor -o ../$@ ./cli/$(@F) + +tools-osx64: $(addprefix tools/osx64/,$(BINARIES)) + +.PHONY: $(addprefix tools/osx64/,$(BINARIES)) +$(addprefix tools/osx64/,$(BINARIES)): + GOOS=darwin GOARCH=amd64 go build -C extractor -mod=vendor -o ../$@.amd64 ./cli/$(@F) + GOOS=darwin GOARCH=arm64 go build -C extractor -mod=vendor -o ../$@.arm64 ./cli/$(@F) + lipo -create $@.amd64 $@.arm64 -output $@ + rm $@.amd64 $@.arm64 + +tools-win64: $(addsuffix .exe,$(addprefix tools/win64/,$(BINARIES))) + +.PHONY: $(addsuffix .exe,$(addprefix tools/win64/,$(BINARIES))) +$(addsuffix .exe,$(addprefix tools/win64/,$(BINARIES))): + env GOOS=windows GOARCH=amd64 go build -C extractor -mod=vendor -o ../$@ ./cli/$(basename $(@F)) + +.PHONY: extractor-common extractor extractor-full +extractor-common: codeql-extractor.yml LICENSE ql/lib/go.dbscheme \ + tools/tokenizer.jar $(CODEQL_TOOLS) + rm -rf $(EXTRACTOR_PACK_OUT) + mkdir -p $(EXTRACTOR_PACK_OUT) + cp codeql-extractor.yml LICENSE ql/lib/go.dbscheme ql/lib/go.dbscheme.stats $(EXTRACTOR_PACK_OUT) + mkdir $(EXTRACTOR_PACK_OUT)/tools + cp -r tools/tokenizer.jar $(CODEQL_TOOLS) $(EXTRACTOR_PACK_OUT)/tools + cp -r downgrades $(EXTRACTOR_PACK_OUT) + +extractor: extractor-common tools-codeql + cp -r tools/$(CODEQL_PLATFORM) $(EXTRACTOR_PACK_OUT)/tools + +extractor-full: extractor-common tools-codeql-full + cp -r $(addprefix tools/,linux64 osx64 win64) $(EXTRACTOR_PACK_OUT)/tools + +tools/tokenizer.jar: tools/net/sourceforge/pmd/cpd/GoLanguage.class + jar cf $@ -C tools net + jar uf $@ -C tools opencsv + +tools/net/sourceforge/pmd/cpd/GoLanguage.class: extractor/net/sourceforge/pmd/cpd/GoLanguage.java + javac -cp extractor -d tools $< + rm tools/net/sourceforge/pmd/cpd/AbstractLanguage.class + rm tools/net/sourceforge/pmd/cpd/SourceCode.class + rm tools/net/sourceforge/pmd/cpd/TokenEntry.class + rm tools/net/sourceforge/pmd/cpd/Tokenizer.class -gen: - bazel run :gen +ql/lib/go.dbscheme: tools/$(CODEQL_PLATFORM)/go-gen-dbscheme$(EXE) + $< $@ build/stats/src.stamp: mkdir -p $(@D)/src @@ -48,7 +123,7 @@ test: all build/testdb/check-upgrade-path codeql test run -j0 ql/test --search-path build/codeql-extractor-go --consistency-queries ql/test/consistency --compilation-cache=$(cache) # use GOOS=linux because GOOS=darwin GOARCH=386 is no longer supported env GOOS=linux GOARCH=386 codeql$(EXE) test run -j0 ql/test/query-tests/Security/CWE-681 --search-path build/codeql-extractor-go --consistency-queries ql/test/consistency --compilation-cache=$(cache) - cd extractor; bazel test ... + cd extractor; go test -mod=vendor ./... bash extractor-smoke-test/test.sh || (echo "Extractor smoke test FAILED"; exit 1) .PHONY: build/testdb/check-upgrade-path From d909f2bc4f77fc5b73500c39f48dff0733e52410 Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Thu, 2 May 2024 13:32:01 +0200 Subject: [PATCH 157/238] Fix expected test output --- .../all-platforms/standalone_resx/CompilationInfo.expected | 2 ++ .../CompilationInfo.expected | 2 ++ .../CompilationInfo.expected | 1 + 3 files changed, 5 insertions(+) diff --git a/csharp/ql/integration-tests/all-platforms/standalone_resx/CompilationInfo.expected b/csharp/ql/integration-tests/all-platforms/standalone_resx/CompilationInfo.expected index 2f5b2c9ea4eb..1fbab458c34a 100644 --- a/csharp/ql/integration-tests/all-platforms/standalone_resx/CompilationInfo.expected +++ b/csharp/ql/integration-tests/all-platforms/standalone_resx/CompilationInfo.expected @@ -1,5 +1,7 @@ +| All Nuget feeds reachable | 1.0 | | Failed project restore with package source error | 0.0 | | Failed solution restore with package source error | 0.0 | +| NuGet feed responsiveness checked | 1.0 | | Project files on filesystem | 1.0 | | Resource extraction enabled | 1.0 | | Restored .NET framework variants | 1.0 | diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error/CompilationInfo.expected b/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error/CompilationInfo.expected index 9171a445bcd7..81a44b5f8fd2 100644 --- a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error/CompilationInfo.expected +++ b/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error/CompilationInfo.expected @@ -1,6 +1,8 @@ +| All Nuget feeds reachable | 1.0 | | Failed project restore with package source error | 1.0 | | Failed solution restore with package source error | 0.0 | | Fallback nuget restore | 1.0 | +| NuGet feed responsiveness checked | 1.0 | | Project files on filesystem | 1.0 | | Resolved assembly conflicts | 7.0 | | Resource extraction enabled | 0.0 | diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error_timeout/CompilationInfo.expected b/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error_timeout/CompilationInfo.expected index bd676f6f1d7a..026a3d386e3c 100644 --- a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error_timeout/CompilationInfo.expected +++ b/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error_timeout/CompilationInfo.expected @@ -1,6 +1,7 @@ | All Nuget feeds reachable | 0.0 | | Fallback nuget restore | 1.0 | | Inherited Nuget feed count | 1.0 | +| NuGet feed responsiveness checked | 1.0 | | Project files on filesystem | 1.0 | | Resolved assembly conflicts | 7.0 | | Resource extraction enabled | 0.0 | From f5d4b2e6cd51efbebe4fc1b9c741499e7d9d961e Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 2 May 2024 13:25:05 +0200 Subject: [PATCH 158/238] C#: Make `Element.getLocation` (mostly) functional --- .../semmle/code/csharp/ExprOrStmtParent.qll | 41 +++++++++++++++---- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/ExprOrStmtParent.qll b/csharp/ql/lib/semmle/code/csharp/ExprOrStmtParent.qll index 636f8061b2a2..7ae36b31f3eb 100644 --- a/csharp/ql/lib/semmle/code/csharp/ExprOrStmtParent.qll +++ b/csharp/ql/lib/semmle/code/csharp/ExprOrStmtParent.qll @@ -51,8 +51,6 @@ class TopLevelExprParent extends Element, @top_level_expr_parent { final Expr getAChildExpr() { result = this.getChildExpr(_) } } -private predicate hasNoSourceLocation(Element e) { not e.getALocation() instanceof SourceLocation } - /** INTERNAL: Do not use. */ Expr getExpressionBody(Callable c) { result = c.getAChildExpr() and @@ -67,17 +65,46 @@ private ControlFlowElement getBody(Callable c) { result = getStatementBody(c) } +pragma[nomagic] +private Location getASourceLocation(Element e) { + result = e.getALocation().(SourceLocation) and + not exists(e.getALocation().(SourceLocation).getMappedLocation()) + or + result = e.getALocation().(SourceLocation).getMappedLocation() +} + +pragma[nomagic] +private predicate hasNoSourceLocation(Element e) { not exists(getASourceLocation(e)) } + +pragma[nomagic] +private Location getFirstSourceLocation(Element e) { + result = + min(Location l, string filepath, int startline, int startcolumn, int endline, int endcolumn | + l = getASourceLocation(e) and + l.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) + | + l order by filepath, startline, startcolumn, endline, endcolumn + ) +} + cached private module Cached { cached Location bestLocation(Element e) { - result = e.getALocation().(SourceLocation) and - not exists(e.getALocation().(SourceLocation).getMappedLocation()) - or - result = e.getALocation().(SourceLocation).getMappedLocation() + ( + if e.(Modifiable).isPartial() or e instanceof Namespace + then result = getASourceLocation(e) + else result = getFirstSourceLocation(e) + ) or hasNoSourceLocation(e) and - result = min(Location l | l = e.getALocation() | l order by l.getFile().toString()) + result = + min(Location l, string filepath | + l = e.getALocation() and + l.hasLocationInfo(filepath, _, _, _, _) + | + l order by filepath + ) or not exists(e.getALocation()) and result instanceof EmptyLocation From b912918d8b6aa7f3ebd73f2c44a5e2721237acc5 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Thu, 2 May 2024 13:32:52 +0100 Subject: [PATCH 159/238] C++: Fix QLDoc. --- .../lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll index 294b35e2751e..924f68ef8076 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll @@ -770,7 +770,7 @@ private predicate adjustForPointerArith(PostUpdateNode pun, SourceVariable sv, I * block `bb1`. * * `uncertain` is `true` if `(bb1, i1)` is a definition, and that definition - * is guaranteed to overwrite the entire allocation. + * is _not_ guaranteed to overwrite the entire allocation. */ private predicate ssaFlowImpl( IRBlock bb1, int i1, SourceVariable sv, Node nodeFrom, Node nodeTo, boolean uncertain From 8ec4f0b5bdb863bf8499073222e2bdcf8ebabbe4 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 2 May 2024 14:05:12 +0200 Subject: [PATCH 160/238] C#: Update expected test output --- .../controlflow/graph/BasicBlock.expected | 119 --- .../controlflow/graph/Dominance.expected | 458 ---------- .../graph/EnclosingCallable.expected | 400 --------- .../controlflow/graph/NodeGraph.expected | 807 +++++------------- .../controlflow/graph/Nodes.expected | 33 - .../library-tests/csharp7/TupleTypes.expected | 1 - .../exprorstmtparent/Callable.expected | 35 - .../exprorstmtparent/Declaration.expected | 38 - .../exprorstmtparent/Indexer.expected | 2 - .../exprorstmtparent/Parameter.expected | 2 - .../exprorstmtparent/Property.expected | 4 - .../extractor/tagstack/Bodies.expected | 1 - .../extractor/tagstack/Classes.expected | 1 - .../extractor/tagstack/Methods.expected | 1 - .../errorrecovery/ErrorTypes.expected | 2 - .../standalone/errorrecovery/Methods.expected | 1 - 16 files changed, 208 insertions(+), 1697 deletions(-) diff --git a/csharp/ql/test/library-tests/controlflow/graph/BasicBlock.expected b/csharp/ql/test/library-tests/controlflow/graph/BasicBlock.expected index f53a82e3d923..527816c645be 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/BasicBlock.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/BasicBlock.expected @@ -749,191 +749,72 @@ | LoopUnrolling.cs:97:22:97:22 | String x | LoopUnrolling.cs:97:9:100:9 | foreach (... ... in ...) ... | 6 | | MultiImplementationA.cs:4:7:4:8 | call to constructor Object | MultiImplementationA.cs:4:7:4:8 | {...} | 2 | | MultiImplementationA.cs:4:7:4:8 | enter C1 | MultiImplementationA.cs:4:7:4:8 | enter C1 | 1 | -| MultiImplementationA.cs:4:7:4:8 | enter C1 | MultiImplementationB.cs:1:7:1:8 | enter C1 | 1 | | MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | MultiImplementationA.cs:4:7:4:8 | exit C1 | 2 | -| MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | MultiImplementationB.cs:1:7:1:8 | exit C1 | 2 | | MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationA.cs:6:22:6:31 | enter get_P1 | 1 | -| MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | enter get_P1 | 1 | | MultiImplementationA.cs:6:22:6:31 | exit get_P1 | MultiImplementationA.cs:6:22:6:31 | exit get_P1 | 1 | -| MultiImplementationA.cs:6:22:6:31 | exit get_P1 | MultiImplementationB.cs:3:22:3:22 | exit get_P1 | 1 | | MultiImplementationA.cs:6:28:6:31 | null | MultiImplementationA.cs:6:22:6:31 | exit get_P1 (abnormal) | 3 | -| MultiImplementationA.cs:6:28:6:31 | null | MultiImplementationB.cs:3:22:3:22 | exit get_P1 (abnormal) | 3 | | MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationA.cs:7:21:7:23 | enter get_P2 | 1 | -| MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationB.cs:4:21:4:23 | enter get_P2 | 1 | | MultiImplementationA.cs:7:21:7:23 | exit get_P2 | MultiImplementationA.cs:7:21:7:23 | exit get_P2 | 1 | -| MultiImplementationA.cs:7:21:7:23 | exit get_P2 | MultiImplementationB.cs:4:21:4:23 | exit get_P2 | 1 | | MultiImplementationA.cs:7:25:7:39 | {...} | MultiImplementationA.cs:7:21:7:23 | exit get_P2 (abnormal) | 4 | -| MultiImplementationA.cs:7:25:7:39 | {...} | MultiImplementationB.cs:4:21:4:23 | exit get_P2 (abnormal) | 4 | | MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationA.cs:7:41:7:43 | enter set_P2 | 1 | -| MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationB.cs:4:39:4:41 | enter set_P2 | 1 | | MultiImplementationA.cs:7:41:7:43 | exit set_P2 | MultiImplementationA.cs:7:41:7:43 | exit set_P2 | 1 | -| MultiImplementationA.cs:7:41:7:43 | exit set_P2 | MultiImplementationB.cs:4:39:4:41 | exit set_P2 | 1 | | MultiImplementationA.cs:7:45:7:59 | {...} | MultiImplementationA.cs:7:41:7:43 | exit set_P2 (abnormal) | 4 | -| MultiImplementationA.cs:7:45:7:59 | {...} | MultiImplementationB.cs:4:39:4:41 | exit set_P2 (abnormal) | 4 | | MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationA.cs:8:16:8:16 | enter M | 1 | -| MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationB.cs:5:16:5:16 | enter M | 1 | | MultiImplementationA.cs:8:16:8:16 | exit M | MultiImplementationA.cs:8:16:8:16 | exit M | 1 | -| MultiImplementationA.cs:8:16:8:16 | exit M | MultiImplementationB.cs:5:16:5:16 | exit M | 1 | | MultiImplementationA.cs:8:29:8:32 | null | MultiImplementationA.cs:8:16:8:16 | exit M (abnormal) | 3 | -| MultiImplementationA.cs:8:29:8:32 | null | MultiImplementationB.cs:5:16:5:16 | exit M (abnormal) | 3 | | MultiImplementationA.cs:14:31:14:31 | access to parameter i | MultiImplementationA.cs:14:31:14:31 | exit get_Item (normal) | 2 | -| MultiImplementationA.cs:14:31:14:31 | access to parameter i | MultiImplementationB.cs:12:31:12:40 | exit get_Item (normal) | 2 | | MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | enter get_Item | 1 | -| MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationB.cs:12:31:12:40 | enter get_Item | 1 | | MultiImplementationA.cs:14:31:14:31 | exit get_Item | MultiImplementationA.cs:14:31:14:31 | exit get_Item | 1 | -| MultiImplementationA.cs:14:31:14:31 | exit get_Item | MultiImplementationB.cs:12:31:12:40 | exit get_Item | 1 | | MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationA.cs:15:36:15:38 | enter get_Item | 1 | -| MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationB.cs:13:36:13:38 | enter get_Item | 1 | | MultiImplementationA.cs:15:36:15:38 | exit get_Item | MultiImplementationA.cs:15:36:15:38 | exit get_Item | 1 | -| MultiImplementationA.cs:15:36:15:38 | exit get_Item | MultiImplementationB.cs:13:36:13:38 | exit get_Item | 1 | | MultiImplementationA.cs:15:40:15:52 | {...} | MultiImplementationA.cs:15:36:15:38 | exit get_Item (normal) | 4 | -| MultiImplementationA.cs:15:40:15:52 | {...} | MultiImplementationB.cs:13:36:13:38 | exit get_Item (normal) | 4 | | MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationA.cs:15:54:15:56 | enter set_Item | 1 | -| MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationB.cs:13:56:13:58 | enter set_Item | 1 | | MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | MultiImplementationA.cs:15:54:15:56 | exit set_Item | 2 | -| MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | MultiImplementationB.cs:13:56:13:58 | exit set_Item | 2 | | MultiImplementationA.cs:15:58:15:60 | {...} | MultiImplementationA.cs:15:58:15:60 | {...} | 1 | | MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationA.cs:16:17:16:18 | enter M1 | 1 | -| MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationB.cs:14:17:14:18 | enter M1 | 1 | | MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | MultiImplementationA.cs:16:17:16:18 | exit M1 | 2 | -| MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | MultiImplementationB.cs:14:17:14:18 | exit M1 | 2 | | MultiImplementationA.cs:17:5:19:5 | {...} | MultiImplementationA.cs:18:9:18:22 | M2(...) | 2 | | MultiImplementationA.cs:18:9:18:22 | enter M2 | MultiImplementationA.cs:18:9:18:22 | exit M2 | 4 | | MultiImplementationA.cs:20:12:20:13 | call to constructor Object | MultiImplementationA.cs:20:12:20:13 | exit C2 (normal) | 14 | -| MultiImplementationA.cs:20:12:20:13 | call to constructor Object | MultiImplementationB.cs:18:12:18:13 | exit C2 (normal) | 14 | | MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | enter C2 | 1 | -| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | enter C2 | 1 | | MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationA.cs:20:12:20:13 | exit C2 | 1 | -| MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationB.cs:18:12:18:13 | exit C2 | 1 | | MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationA.cs:21:12:21:13 | enter C2 | 1 | -| MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationB.cs:19:12:19:13 | enter C2 | 1 | | MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | MultiImplementationA.cs:21:12:21:13 | exit C2 | 2 | -| MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | MultiImplementationB.cs:19:12:19:13 | exit C2 | 2 | | MultiImplementationA.cs:21:24:21:24 | 0 | MultiImplementationA.cs:21:27:21:29 | {...} | 3 | | MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationA.cs:22:6:22:7 | enter ~C2 | 1 | -| MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationB.cs:20:6:20:7 | enter ~C2 | 1 | | MultiImplementationA.cs:22:6:22:7 | exit ~C2 | MultiImplementationA.cs:22:6:22:7 | exit ~C2 | 1 | -| MultiImplementationA.cs:22:6:22:7 | exit ~C2 | MultiImplementationB.cs:20:6:20:7 | exit ~C2 | 1 | | MultiImplementationA.cs:22:11:22:13 | {...} | MultiImplementationA.cs:22:6:22:7 | exit ~C2 (normal) | 2 | -| MultiImplementationA.cs:22:11:22:13 | {...} | MultiImplementationB.cs:20:6:20:7 | exit ~C2 (normal) | 2 | | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | 1 | -| MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | 1 | | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | 1 | -| MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | 1 | | MultiImplementationA.cs:23:50:23:53 | null | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion (normal) | 2 | -| MultiImplementationA.cs:23:50:23:53 | null | MultiImplementationB.cs:21:28:21:35 | exit implicit conversion (normal) | 2 | | MultiImplementationA.cs:28:7:28:8 | call to constructor Object | MultiImplementationA.cs:28:7:28:8 | {...} | 2 | | MultiImplementationA.cs:28:7:28:8 | enter C3 | MultiImplementationA.cs:28:7:28:8 | enter C3 | 1 | -| MultiImplementationA.cs:28:7:28:8 | enter C3 | MultiImplementationB.cs:25:7:25:8 | enter C3 | 1 | | MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | MultiImplementationA.cs:28:7:28:8 | exit C3 | 2 | -| MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | MultiImplementationB.cs:25:7:25:8 | exit C3 | 2 | | MultiImplementationA.cs:30:21:30:23 | enter get_P3 | MultiImplementationA.cs:30:21:30:23 | exit get_P3 | 5 | -| MultiImplementationA.cs:30:21:30:23 | enter get_P3 | MultiImplementationB.cs:27:21:27:23 | exit get_P3 | 5 | | MultiImplementationA.cs:34:15:34:16 | call to constructor Object | MultiImplementationA.cs:34:15:34:16 | {...} | 2 | | MultiImplementationA.cs:34:15:34:16 | enter C4 | MultiImplementationA.cs:34:15:34:16 | enter C4 | 1 | -| MultiImplementationA.cs:34:15:34:16 | enter C4 | MultiImplementationB.cs:30:15:30:16 | enter C4 | 1 | | MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | MultiImplementationA.cs:34:15:34:16 | exit C4 | 2 | -| MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | MultiImplementationB.cs:30:15:30:16 | exit C4 | 2 | | MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationA.cs:36:9:36:10 | enter M1 | 1 | -| MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationB.cs:32:9:32:10 | enter M1 | 1 | | MultiImplementationA.cs:36:9:36:10 | exit M1 | MultiImplementationA.cs:36:9:36:10 | exit M1 | 1 | -| MultiImplementationA.cs:36:9:36:10 | exit M1 | MultiImplementationB.cs:32:9:32:10 | exit M1 | 1 | | MultiImplementationA.cs:36:14:36:28 | {...} | MultiImplementationA.cs:36:9:36:10 | exit M1 (abnormal) | 4 | -| MultiImplementationA.cs:36:14:36:28 | {...} | MultiImplementationB.cs:32:9:32:10 | exit M1 (abnormal) | 4 | | MultiImplementationA.cs:37:9:37:10 | enter M2 | MultiImplementationA.cs:37:9:37:10 | exit M2 | 6 | | MultiImplementationB.cs:1:7:1:8 | call to constructor Object | MultiImplementationB.cs:1:7:1:8 | {...} | 2 | -| MultiImplementationB.cs:1:7:1:8 | enter C1 | MultiImplementationA.cs:4:7:4:8 | enter C1 | 1 | -| MultiImplementationB.cs:1:7:1:8 | enter C1 | MultiImplementationB.cs:1:7:1:8 | enter C1 | 1 | -| MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | MultiImplementationA.cs:4:7:4:8 | exit C1 | 2 | -| MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | MultiImplementationB.cs:1:7:1:8 | exit C1 | 2 | | MultiImplementationB.cs:3:22:3:22 | 0 | MultiImplementationA.cs:6:22:6:31 | exit get_P1 (normal) | 2 | -| MultiImplementationB.cs:3:22:3:22 | 0 | MultiImplementationB.cs:3:22:3:22 | exit get_P1 (normal) | 2 | -| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationA.cs:6:22:6:31 | enter get_P1 | 1 | -| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | enter get_P1 | 1 | -| MultiImplementationB.cs:3:22:3:22 | exit get_P1 | MultiImplementationA.cs:6:22:6:31 | exit get_P1 | 1 | -| MultiImplementationB.cs:3:22:3:22 | exit get_P1 | MultiImplementationB.cs:3:22:3:22 | exit get_P1 | 1 | -| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationA.cs:7:21:7:23 | enter get_P2 | 1 | -| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationB.cs:4:21:4:23 | enter get_P2 | 1 | -| MultiImplementationB.cs:4:21:4:23 | exit get_P2 | MultiImplementationA.cs:7:21:7:23 | exit get_P2 | 1 | -| MultiImplementationB.cs:4:21:4:23 | exit get_P2 | MultiImplementationB.cs:4:21:4:23 | exit get_P2 | 1 | | MultiImplementationB.cs:4:25:4:37 | {...} | MultiImplementationA.cs:7:21:7:23 | exit get_P2 (normal) | 4 | -| MultiImplementationB.cs:4:25:4:37 | {...} | MultiImplementationB.cs:4:21:4:23 | exit get_P2 (normal) | 4 | -| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationA.cs:7:41:7:43 | enter set_P2 | 1 | -| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationB.cs:4:39:4:41 | enter set_P2 | 1 | -| MultiImplementationB.cs:4:39:4:41 | exit set_P2 | MultiImplementationA.cs:7:41:7:43 | exit set_P2 | 1 | -| MultiImplementationB.cs:4:39:4:41 | exit set_P2 | MultiImplementationB.cs:4:39:4:41 | exit set_P2 | 1 | | MultiImplementationB.cs:4:43:4:45 | {...} | MultiImplementationA.cs:7:41:7:43 | exit set_P2 (normal) | 2 | -| MultiImplementationB.cs:4:43:4:45 | {...} | MultiImplementationB.cs:4:39:4:41 | exit set_P2 (normal) | 2 | -| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationA.cs:8:16:8:16 | enter M | 1 | -| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationB.cs:5:16:5:16 | enter M | 1 | -| MultiImplementationB.cs:5:16:5:16 | exit M | MultiImplementationA.cs:8:16:8:16 | exit M | 1 | -| MultiImplementationB.cs:5:16:5:16 | exit M | MultiImplementationB.cs:5:16:5:16 | exit M | 1 | | MultiImplementationB.cs:5:23:5:23 | 2 | MultiImplementationA.cs:8:16:8:16 | exit M (normal) | 2 | -| MultiImplementationB.cs:5:23:5:23 | 2 | MultiImplementationB.cs:5:16:5:16 | exit M (normal) | 2 | -| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | enter get_Item | 1 | -| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationB.cs:12:31:12:40 | enter get_Item | 1 | -| MultiImplementationB.cs:12:31:12:40 | exit get_Item | MultiImplementationA.cs:14:31:14:31 | exit get_Item | 1 | -| MultiImplementationB.cs:12:31:12:40 | exit get_Item | MultiImplementationB.cs:12:31:12:40 | exit get_Item | 1 | | MultiImplementationB.cs:12:37:12:40 | null | MultiImplementationA.cs:14:31:14:31 | exit get_Item (abnormal) | 3 | -| MultiImplementationB.cs:12:37:12:40 | null | MultiImplementationB.cs:12:31:12:40 | exit get_Item (abnormal) | 3 | -| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationA.cs:15:36:15:38 | enter get_Item | 1 | -| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationB.cs:13:36:13:38 | enter get_Item | 1 | -| MultiImplementationB.cs:13:36:13:38 | exit get_Item | MultiImplementationA.cs:15:36:15:38 | exit get_Item | 1 | -| MultiImplementationB.cs:13:36:13:38 | exit get_Item | MultiImplementationB.cs:13:36:13:38 | exit get_Item | 1 | | MultiImplementationB.cs:13:40:13:54 | {...} | MultiImplementationA.cs:15:36:15:38 | exit get_Item (abnormal) | 4 | -| MultiImplementationB.cs:13:40:13:54 | {...} | MultiImplementationB.cs:13:36:13:38 | exit get_Item (abnormal) | 4 | -| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationA.cs:15:54:15:56 | enter set_Item | 1 | -| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationB.cs:13:56:13:58 | enter set_Item | 1 | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | MultiImplementationA.cs:15:54:15:56 | exit set_Item | 2 | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | MultiImplementationB.cs:13:56:13:58 | exit set_Item | 2 | | MultiImplementationB.cs:13:60:13:62 | {...} | MultiImplementationB.cs:13:60:13:62 | {...} | 1 | -| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationA.cs:16:17:16:18 | enter M1 | 1 | -| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationB.cs:14:17:14:18 | enter M1 | 1 | -| MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | MultiImplementationA.cs:16:17:16:18 | exit M1 | 2 | -| MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | MultiImplementationB.cs:14:17:14:18 | exit M1 | 2 | | MultiImplementationB.cs:15:5:17:5 | {...} | MultiImplementationB.cs:16:9:16:31 | M2(...) | 2 | | MultiImplementationB.cs:16:9:16:31 | enter M2 | MultiImplementationB.cs:16:9:16:31 | exit M2 | 5 | | MultiImplementationB.cs:18:12:18:13 | call to constructor Object | MultiImplementationA.cs:20:12:20:13 | exit C2 (abnormal) | 12 | -| MultiImplementationB.cs:18:12:18:13 | call to constructor Object | MultiImplementationB.cs:18:12:18:13 | exit C2 (abnormal) | 12 | -| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | enter C2 | 1 | -| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | enter C2 | 1 | -| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationA.cs:20:12:20:13 | exit C2 | 1 | -| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationB.cs:18:12:18:13 | exit C2 | 1 | -| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationA.cs:21:12:21:13 | enter C2 | 1 | -| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationB.cs:19:12:19:13 | enter C2 | 1 | -| MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | MultiImplementationA.cs:21:12:21:13 | exit C2 | 2 | -| MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | MultiImplementationB.cs:19:12:19:13 | exit C2 | 2 | | MultiImplementationB.cs:19:24:19:24 | 1 | MultiImplementationB.cs:19:27:19:29 | {...} | 3 | -| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationA.cs:22:6:22:7 | enter ~C2 | 1 | -| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationB.cs:20:6:20:7 | enter ~C2 | 1 | -| MultiImplementationB.cs:20:6:20:7 | exit ~C2 | MultiImplementationA.cs:22:6:22:7 | exit ~C2 | 1 | -| MultiImplementationB.cs:20:6:20:7 | exit ~C2 | MultiImplementationB.cs:20:6:20:7 | exit ~C2 | 1 | | MultiImplementationB.cs:20:11:20:25 | {...} | MultiImplementationA.cs:22:6:22:7 | exit ~C2 (abnormal) | 4 | -| MultiImplementationB.cs:20:11:20:25 | {...} | MultiImplementationB.cs:20:6:20:7 | exit ~C2 (abnormal) | 4 | -| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | 1 | -| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | 1 | -| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | 1 | -| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | 1 | | MultiImplementationB.cs:21:56:21:59 | null | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion (abnormal) | 3 | -| MultiImplementationB.cs:21:56:21:59 | null | MultiImplementationB.cs:21:28:21:35 | exit implicit conversion (abnormal) | 3 | | MultiImplementationB.cs:25:7:25:8 | call to constructor Object | MultiImplementationB.cs:25:7:25:8 | {...} | 2 | -| MultiImplementationB.cs:25:7:25:8 | enter C3 | MultiImplementationA.cs:28:7:28:8 | enter C3 | 1 | -| MultiImplementationB.cs:25:7:25:8 | enter C3 | MultiImplementationB.cs:25:7:25:8 | enter C3 | 1 | -| MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | MultiImplementationA.cs:28:7:28:8 | exit C3 | 2 | -| MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | MultiImplementationB.cs:25:7:25:8 | exit C3 | 2 | -| MultiImplementationB.cs:27:21:27:23 | enter get_P3 | MultiImplementationA.cs:30:21:30:23 | exit get_P3 | 5 | -| MultiImplementationB.cs:27:21:27:23 | enter get_P3 | MultiImplementationB.cs:27:21:27:23 | exit get_P3 | 5 | | MultiImplementationB.cs:30:15:30:16 | call to constructor Object | MultiImplementationB.cs:30:15:30:16 | {...} | 2 | -| MultiImplementationB.cs:30:15:30:16 | enter C4 | MultiImplementationA.cs:34:15:34:16 | enter C4 | 1 | -| MultiImplementationB.cs:30:15:30:16 | enter C4 | MultiImplementationB.cs:30:15:30:16 | enter C4 | 1 | -| MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | MultiImplementationA.cs:34:15:34:16 | exit C4 | 2 | -| MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | MultiImplementationB.cs:30:15:30:16 | exit C4 | 2 | -| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationA.cs:36:9:36:10 | enter M1 | 1 | -| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationB.cs:32:9:32:10 | enter M1 | 1 | -| MultiImplementationB.cs:32:9:32:10 | exit M1 | MultiImplementationA.cs:36:9:36:10 | exit M1 | 1 | -| MultiImplementationB.cs:32:9:32:10 | exit M1 | MultiImplementationB.cs:32:9:32:10 | exit M1 | 1 | | MultiImplementationB.cs:32:17:32:17 | 0 | MultiImplementationA.cs:36:9:36:10 | exit M1 (normal) | 2 | -| MultiImplementationB.cs:32:17:32:17 | 0 | MultiImplementationB.cs:32:9:32:10 | exit M1 (normal) | 2 | | NullCoalescing.cs:1:7:1:20 | enter NullCoalescing | NullCoalescing.cs:1:7:1:20 | exit NullCoalescing | 5 | | NullCoalescing.cs:3:9:3:10 | enter M1 | NullCoalescing.cs:3:23:3:23 | access to parameter i | 2 | | NullCoalescing.cs:3:23:3:28 | ... ?? ... | NullCoalescing.cs:3:9:3:10 | exit M1 | 3 | diff --git a/csharp/ql/test/library-tests/controlflow/graph/Dominance.expected b/csharp/ql/test/library-tests/controlflow/graph/Dominance.expected index 831c014ef0ba..9a1a38b7935a 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/Dominance.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/Dominance.expected @@ -2923,50 +2923,41 @@ dominance | MultiImplementationA.cs:4:7:4:8 | enter C1 | MultiImplementationA.cs:4:7:4:8 | call to constructor Object | | MultiImplementationA.cs:4:7:4:8 | enter C1 | MultiImplementationB.cs:1:7:1:8 | call to constructor Object | | MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | MultiImplementationA.cs:4:7:4:8 | exit C1 | -| MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | MultiImplementationB.cs:1:7:1:8 | exit C1 | | MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationA.cs:6:28:6:31 | null | | MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | 0 | | MultiImplementationA.cs:6:22:6:31 | throw ... | MultiImplementationA.cs:6:22:6:31 | exit get_P1 (abnormal) | -| MultiImplementationA.cs:6:22:6:31 | throw ... | MultiImplementationB.cs:3:22:3:22 | exit get_P1 (abnormal) | | MultiImplementationA.cs:6:28:6:31 | null | MultiImplementationA.cs:6:22:6:31 | throw ... | | MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationA.cs:7:25:7:39 | {...} | | MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationB.cs:4:25:4:37 | {...} | | MultiImplementationA.cs:7:25:7:39 | {...} | MultiImplementationA.cs:7:33:7:36 | null | | MultiImplementationA.cs:7:27:7:37 | throw ...; | MultiImplementationA.cs:7:21:7:23 | exit get_P2 (abnormal) | -| MultiImplementationA.cs:7:27:7:37 | throw ...; | MultiImplementationB.cs:4:21:4:23 | exit get_P2 (abnormal) | | MultiImplementationA.cs:7:33:7:36 | null | MultiImplementationA.cs:7:27:7:37 | throw ...; | | MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationA.cs:7:45:7:59 | {...} | | MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationB.cs:4:43:4:45 | {...} | | MultiImplementationA.cs:7:45:7:59 | {...} | MultiImplementationA.cs:7:53:7:56 | null | | MultiImplementationA.cs:7:47:7:57 | throw ...; | MultiImplementationA.cs:7:41:7:43 | exit set_P2 (abnormal) | -| MultiImplementationA.cs:7:47:7:57 | throw ...; | MultiImplementationB.cs:4:39:4:41 | exit set_P2 (abnormal) | | MultiImplementationA.cs:7:53:7:56 | null | MultiImplementationA.cs:7:47:7:57 | throw ...; | | MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationA.cs:8:29:8:32 | null | | MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationB.cs:5:23:5:23 | 2 | | MultiImplementationA.cs:8:23:8:32 | throw ... | MultiImplementationA.cs:8:16:8:16 | exit M (abnormal) | -| MultiImplementationA.cs:8:23:8:32 | throw ... | MultiImplementationB.cs:5:16:5:16 | exit M (abnormal) | | MultiImplementationA.cs:8:29:8:32 | null | MultiImplementationA.cs:8:23:8:32 | throw ... | | MultiImplementationA.cs:13:16:13:16 | this access | MultiImplementationA.cs:13:20:13:20 | 0 | | MultiImplementationA.cs:13:16:13:20 | ... = ... | MultiImplementationA.cs:24:16:24:16 | this access | | MultiImplementationA.cs:13:20:13:20 | 0 | MultiImplementationA.cs:13:16:13:20 | ... = ... | | MultiImplementationA.cs:14:31:14:31 | access to parameter i | MultiImplementationA.cs:14:31:14:31 | exit get_Item (normal) | -| MultiImplementationA.cs:14:31:14:31 | access to parameter i | MultiImplementationB.cs:12:31:12:40 | exit get_Item (normal) | | MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | access to parameter i | | MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationB.cs:12:37:12:40 | null | | MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationA.cs:15:40:15:52 | {...} | | MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationB.cs:13:40:13:54 | {...} | | MultiImplementationA.cs:15:40:15:52 | {...} | MultiImplementationA.cs:15:49:15:49 | access to parameter s | | MultiImplementationA.cs:15:42:15:50 | return ...; | MultiImplementationA.cs:15:36:15:38 | exit get_Item (normal) | -| MultiImplementationA.cs:15:42:15:50 | return ...; | MultiImplementationB.cs:13:36:13:38 | exit get_Item (normal) | | MultiImplementationA.cs:15:49:15:49 | access to parameter s | MultiImplementationA.cs:15:42:15:50 | return ...; | | MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationA.cs:15:58:15:60 | {...} | | MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationB.cs:13:60:13:62 | {...} | | MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | MultiImplementationA.cs:15:54:15:56 | exit set_Item | -| MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | MultiImplementationB.cs:13:56:13:58 | exit set_Item | | MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationA.cs:17:5:19:5 | {...} | | MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationB.cs:15:5:17:5 | {...} | | MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | MultiImplementationA.cs:16:17:16:18 | exit M1 | -| MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | MultiImplementationB.cs:14:17:14:18 | exit M1 | | MultiImplementationA.cs:17:5:19:5 | {...} | MultiImplementationA.cs:18:9:18:22 | M2(...) | | MultiImplementationA.cs:18:9:18:22 | enter M2 | MultiImplementationA.cs:18:21:18:21 | 0 | | MultiImplementationA.cs:18:9:18:22 | exit M2 (normal) | MultiImplementationA.cs:18:9:18:22 | exit M2 | @@ -2977,23 +2968,19 @@ dominance | MultiImplementationA.cs:20:22:20:31 | {...} | MultiImplementationA.cs:20:24:20:29 | ...; | | MultiImplementationA.cs:20:24:20:24 | this access | MultiImplementationA.cs:20:28:20:28 | access to parameter i | | MultiImplementationA.cs:20:24:20:28 | ... = ... | MultiImplementationA.cs:20:12:20:13 | exit C2 (normal) | -| MultiImplementationA.cs:20:24:20:28 | ... = ... | MultiImplementationB.cs:18:12:18:13 | exit C2 (normal) | | MultiImplementationA.cs:20:24:20:29 | ...; | MultiImplementationA.cs:20:24:20:24 | this access | | MultiImplementationA.cs:20:28:20:28 | access to parameter i | MultiImplementationA.cs:20:24:20:28 | ... = ... | | MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationA.cs:21:24:21:24 | 0 | | MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationB.cs:19:24:19:24 | 1 | | MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | MultiImplementationA.cs:21:12:21:13 | exit C2 | -| MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | MultiImplementationB.cs:19:12:19:13 | exit C2 | | MultiImplementationA.cs:21:19:21:22 | call to constructor C2 | MultiImplementationA.cs:21:27:21:29 | {...} | | MultiImplementationA.cs:21:24:21:24 | 0 | MultiImplementationA.cs:21:19:21:22 | call to constructor C2 | | MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationA.cs:22:11:22:13 | {...} | | MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationB.cs:20:11:20:25 | {...} | | MultiImplementationA.cs:22:11:22:13 | {...} | MultiImplementationA.cs:22:6:22:7 | exit ~C2 (normal) | -| MultiImplementationA.cs:22:11:22:13 | {...} | MultiImplementationB.cs:20:6:20:7 | exit ~C2 (normal) | | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationA.cs:23:50:23:53 | null | | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationB.cs:21:56:21:59 | null | | MultiImplementationA.cs:23:50:23:53 | null | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion (normal) | -| MultiImplementationA.cs:23:50:23:53 | null | MultiImplementationB.cs:21:28:21:35 | exit implicit conversion (normal) | | MultiImplementationA.cs:24:16:24:16 | access to property P | MultiImplementationA.cs:24:32:24:34 | ... = ... | | MultiImplementationA.cs:24:16:24:16 | this access | MultiImplementationA.cs:24:34:24:34 | 0 | | MultiImplementationA.cs:24:32:24:34 | ... = ... | MultiImplementationA.cs:20:22:20:31 | {...} | @@ -3002,23 +2989,18 @@ dominance | MultiImplementationA.cs:28:7:28:8 | enter C3 | MultiImplementationA.cs:28:7:28:8 | call to constructor Object | | MultiImplementationA.cs:28:7:28:8 | enter C3 | MultiImplementationB.cs:25:7:25:8 | call to constructor Object | | MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | MultiImplementationA.cs:28:7:28:8 | exit C3 | -| MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | MultiImplementationB.cs:25:7:25:8 | exit C3 | | MultiImplementationA.cs:30:21:30:23 | enter get_P3 | MultiImplementationA.cs:30:34:30:37 | null | | MultiImplementationA.cs:30:21:30:23 | exit get_P3 (abnormal) | MultiImplementationA.cs:30:21:30:23 | exit get_P3 | -| MultiImplementationA.cs:30:21:30:23 | exit get_P3 (abnormal) | MultiImplementationB.cs:27:21:27:23 | exit get_P3 | | MultiImplementationA.cs:30:28:30:37 | throw ... | MultiImplementationA.cs:30:21:30:23 | exit get_P3 (abnormal) | -| MultiImplementationA.cs:30:28:30:37 | throw ... | MultiImplementationB.cs:27:21:27:23 | exit get_P3 (abnormal) | | MultiImplementationA.cs:30:34:30:37 | null | MultiImplementationA.cs:30:28:30:37 | throw ... | | MultiImplementationA.cs:34:15:34:16 | call to constructor Object | MultiImplementationA.cs:34:15:34:16 | {...} | | MultiImplementationA.cs:34:15:34:16 | enter C4 | MultiImplementationA.cs:34:15:34:16 | call to constructor Object | | MultiImplementationA.cs:34:15:34:16 | enter C4 | MultiImplementationB.cs:30:15:30:16 | call to constructor Object | | MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | MultiImplementationA.cs:34:15:34:16 | exit C4 | -| MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | MultiImplementationB.cs:30:15:30:16 | exit C4 | | MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationA.cs:36:14:36:28 | {...} | | MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationB.cs:32:17:32:17 | 0 | | MultiImplementationA.cs:36:14:36:28 | {...} | MultiImplementationA.cs:36:22:36:25 | null | | MultiImplementationA.cs:36:16:36:26 | throw ...; | MultiImplementationA.cs:36:9:36:10 | exit M1 (abnormal) | -| MultiImplementationA.cs:36:16:36:26 | throw ...; | MultiImplementationB.cs:32:9:32:10 | exit M1 (abnormal) | | MultiImplementationA.cs:36:22:36:25 | null | MultiImplementationA.cs:36:16:36:26 | throw ...; | | MultiImplementationA.cs:37:9:37:10 | enter M2 | MultiImplementationA.cs:37:14:37:28 | {...} | | MultiImplementationA.cs:37:9:37:10 | exit M2 (abnormal) | MultiImplementationA.cs:37:9:37:10 | exit M2 | @@ -3026,100 +3008,43 @@ dominance | MultiImplementationA.cs:37:16:37:26 | throw ...; | MultiImplementationA.cs:37:9:37:10 | exit M2 (abnormal) | | MultiImplementationA.cs:37:22:37:25 | null | MultiImplementationA.cs:37:16:37:26 | throw ...; | | MultiImplementationB.cs:1:7:1:8 | call to constructor Object | MultiImplementationB.cs:1:7:1:8 | {...} | -| MultiImplementationB.cs:1:7:1:8 | enter C1 | MultiImplementationA.cs:4:7:4:8 | call to constructor Object | -| MultiImplementationB.cs:1:7:1:8 | enter C1 | MultiImplementationB.cs:1:7:1:8 | call to constructor Object | -| MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | MultiImplementationA.cs:4:7:4:8 | exit C1 | -| MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | MultiImplementationB.cs:1:7:1:8 | exit C1 | | MultiImplementationB.cs:3:22:3:22 | 0 | MultiImplementationA.cs:6:22:6:31 | exit get_P1 (normal) | -| MultiImplementationB.cs:3:22:3:22 | 0 | MultiImplementationB.cs:3:22:3:22 | exit get_P1 (normal) | -| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationA.cs:6:28:6:31 | null | -| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | 0 | -| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationA.cs:7:25:7:39 | {...} | -| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationB.cs:4:25:4:37 | {...} | | MultiImplementationB.cs:4:25:4:37 | {...} | MultiImplementationB.cs:4:34:4:34 | 1 | | MultiImplementationB.cs:4:27:4:35 | return ...; | MultiImplementationA.cs:7:21:7:23 | exit get_P2 (normal) | -| MultiImplementationB.cs:4:27:4:35 | return ...; | MultiImplementationB.cs:4:21:4:23 | exit get_P2 (normal) | | MultiImplementationB.cs:4:34:4:34 | 1 | MultiImplementationB.cs:4:27:4:35 | return ...; | -| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationA.cs:7:45:7:59 | {...} | -| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationB.cs:4:43:4:45 | {...} | | MultiImplementationB.cs:4:43:4:45 | {...} | MultiImplementationA.cs:7:41:7:43 | exit set_P2 (normal) | -| MultiImplementationB.cs:4:43:4:45 | {...} | MultiImplementationB.cs:4:39:4:41 | exit set_P2 (normal) | -| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationA.cs:8:29:8:32 | null | -| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationB.cs:5:23:5:23 | 2 | | MultiImplementationB.cs:5:23:5:23 | 2 | MultiImplementationA.cs:8:16:8:16 | exit M (normal) | -| MultiImplementationB.cs:5:23:5:23 | 2 | MultiImplementationB.cs:5:16:5:16 | exit M (normal) | | MultiImplementationB.cs:11:16:11:16 | this access | MultiImplementationB.cs:11:20:11:20 | 1 | | MultiImplementationB.cs:11:16:11:20 | ... = ... | MultiImplementationB.cs:22:16:22:16 | this access | | MultiImplementationB.cs:11:20:11:20 | 1 | MultiImplementationB.cs:11:16:11:20 | ... = ... | -| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | access to parameter i | -| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationB.cs:12:37:12:40 | null | | MultiImplementationB.cs:12:31:12:40 | throw ... | MultiImplementationA.cs:14:31:14:31 | exit get_Item (abnormal) | -| MultiImplementationB.cs:12:31:12:40 | throw ... | MultiImplementationB.cs:12:31:12:40 | exit get_Item (abnormal) | | MultiImplementationB.cs:12:37:12:40 | null | MultiImplementationB.cs:12:31:12:40 | throw ... | -| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationA.cs:15:40:15:52 | {...} | -| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationB.cs:13:40:13:54 | {...} | | MultiImplementationB.cs:13:40:13:54 | {...} | MultiImplementationB.cs:13:48:13:51 | null | | MultiImplementationB.cs:13:42:13:52 | throw ...; | MultiImplementationA.cs:15:36:15:38 | exit get_Item (abnormal) | -| MultiImplementationB.cs:13:42:13:52 | throw ...; | MultiImplementationB.cs:13:36:13:38 | exit get_Item (abnormal) | | MultiImplementationB.cs:13:48:13:51 | null | MultiImplementationB.cs:13:42:13:52 | throw ...; | -| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationA.cs:15:58:15:60 | {...} | -| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationB.cs:13:60:13:62 | {...} | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | MultiImplementationA.cs:15:54:15:56 | exit set_Item | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | MultiImplementationB.cs:13:56:13:58 | exit set_Item | -| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationA.cs:17:5:19:5 | {...} | -| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationB.cs:15:5:17:5 | {...} | -| MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | MultiImplementationA.cs:16:17:16:18 | exit M1 | -| MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | MultiImplementationB.cs:14:17:14:18 | exit M1 | | MultiImplementationB.cs:15:5:17:5 | {...} | MultiImplementationB.cs:16:9:16:31 | M2(...) | | MultiImplementationB.cs:16:9:16:31 | enter M2 | MultiImplementationB.cs:16:27:16:30 | null | | MultiImplementationB.cs:16:9:16:31 | exit M2 (abnormal) | MultiImplementationB.cs:16:9:16:31 | exit M2 | | MultiImplementationB.cs:16:21:16:30 | throw ... | MultiImplementationB.cs:16:9:16:31 | exit M2 (abnormal) | | MultiImplementationB.cs:16:27:16:30 | null | MultiImplementationB.cs:16:21:16:30 | throw ... | | MultiImplementationB.cs:18:12:18:13 | call to constructor Object | MultiImplementationB.cs:11:16:11:16 | this access | -| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | call to constructor Object | -| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | call to constructor Object | | MultiImplementationB.cs:18:22:18:36 | {...} | MultiImplementationB.cs:18:30:18:33 | null | | MultiImplementationB.cs:18:24:18:34 | throw ...; | MultiImplementationA.cs:20:12:20:13 | exit C2 (abnormal) | -| MultiImplementationB.cs:18:24:18:34 | throw ...; | MultiImplementationB.cs:18:12:18:13 | exit C2 (abnormal) | | MultiImplementationB.cs:18:30:18:33 | null | MultiImplementationB.cs:18:24:18:34 | throw ...; | -| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationA.cs:21:24:21:24 | 0 | -| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationB.cs:19:24:19:24 | 1 | -| MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | MultiImplementationA.cs:21:12:21:13 | exit C2 | -| MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | MultiImplementationB.cs:19:12:19:13 | exit C2 | | MultiImplementationB.cs:19:19:19:22 | call to constructor C2 | MultiImplementationB.cs:19:27:19:29 | {...} | | MultiImplementationB.cs:19:24:19:24 | 1 | MultiImplementationB.cs:19:19:19:22 | call to constructor C2 | -| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationA.cs:22:11:22:13 | {...} | -| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationB.cs:20:11:20:25 | {...} | | MultiImplementationB.cs:20:11:20:25 | {...} | MultiImplementationB.cs:20:19:20:22 | null | | MultiImplementationB.cs:20:13:20:23 | throw ...; | MultiImplementationA.cs:22:6:22:7 | exit ~C2 (abnormal) | -| MultiImplementationB.cs:20:13:20:23 | throw ...; | MultiImplementationB.cs:20:6:20:7 | exit ~C2 (abnormal) | | MultiImplementationB.cs:20:19:20:22 | null | MultiImplementationB.cs:20:13:20:23 | throw ...; | -| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationA.cs:23:50:23:53 | null | -| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationB.cs:21:56:21:59 | null | | MultiImplementationB.cs:21:50:21:59 | throw ... | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion (abnormal) | -| MultiImplementationB.cs:21:50:21:59 | throw ... | MultiImplementationB.cs:21:28:21:35 | exit implicit conversion (abnormal) | | MultiImplementationB.cs:21:56:21:59 | null | MultiImplementationB.cs:21:50:21:59 | throw ... | | MultiImplementationB.cs:22:16:22:16 | access to property P | MultiImplementationB.cs:22:32:22:34 | ... = ... | | MultiImplementationB.cs:22:16:22:16 | this access | MultiImplementationB.cs:22:34:22:34 | 1 | | MultiImplementationB.cs:22:32:22:34 | ... = ... | MultiImplementationB.cs:18:22:18:36 | {...} | | MultiImplementationB.cs:22:34:22:34 | 1 | MultiImplementationB.cs:22:16:22:16 | access to property P | | MultiImplementationB.cs:25:7:25:8 | call to constructor Object | MultiImplementationB.cs:25:7:25:8 | {...} | -| MultiImplementationB.cs:25:7:25:8 | enter C3 | MultiImplementationA.cs:28:7:28:8 | call to constructor Object | -| MultiImplementationB.cs:25:7:25:8 | enter C3 | MultiImplementationB.cs:25:7:25:8 | call to constructor Object | -| MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | MultiImplementationA.cs:28:7:28:8 | exit C3 | -| MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | MultiImplementationB.cs:25:7:25:8 | exit C3 | -| MultiImplementationB.cs:27:21:27:23 | enter get_P3 | MultiImplementationA.cs:30:34:30:37 | null | -| MultiImplementationB.cs:27:21:27:23 | exit get_P3 (abnormal) | MultiImplementationA.cs:30:21:30:23 | exit get_P3 | -| MultiImplementationB.cs:27:21:27:23 | exit get_P3 (abnormal) | MultiImplementationB.cs:27:21:27:23 | exit get_P3 | | MultiImplementationB.cs:30:15:30:16 | call to constructor Object | MultiImplementationB.cs:30:15:30:16 | {...} | -| MultiImplementationB.cs:30:15:30:16 | enter C4 | MultiImplementationA.cs:34:15:34:16 | call to constructor Object | -| MultiImplementationB.cs:30:15:30:16 | enter C4 | MultiImplementationB.cs:30:15:30:16 | call to constructor Object | -| MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | MultiImplementationA.cs:34:15:34:16 | exit C4 | -| MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | MultiImplementationB.cs:30:15:30:16 | exit C4 | -| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationA.cs:36:14:36:28 | {...} | -| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationB.cs:32:17:32:17 | 0 | | MultiImplementationB.cs:32:17:32:17 | 0 | MultiImplementationA.cs:36:9:36:10 | exit M1 (normal) | -| MultiImplementationB.cs:32:17:32:17 | 0 | MultiImplementationB.cs:32:9:32:10 | exit M1 (normal) | | NullCoalescing.cs:1:7:1:20 | call to constructor Object | NullCoalescing.cs:1:7:1:20 | {...} | | NullCoalescing.cs:1:7:1:20 | enter NullCoalescing | NullCoalescing.cs:1:7:1:20 | call to constructor Object | | NullCoalescing.cs:1:7:1:20 | exit NullCoalescing (normal) | NullCoalescing.cs:1:7:1:20 | exit NullCoalescing | @@ -7205,7 +7130,6 @@ postDominance | LoopUnrolling.cs:99:13:99:33 | ...; | LoopUnrolling.cs:98:9:100:9 | {...} | | LoopUnrolling.cs:99:31:99:31 | access to local variable x | LoopUnrolling.cs:99:13:99:33 | ...; | | MultiImplementationA.cs:4:7:4:8 | exit C1 | MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | -| MultiImplementationA.cs:4:7:4:8 | exit C1 | MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | | MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | MultiImplementationA.cs:4:7:4:8 | {...} | | MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | MultiImplementationB.cs:1:7:1:8 | {...} | | MultiImplementationA.cs:4:7:4:8 | {...} | MultiImplementationA.cs:4:7:4:8 | call to constructor Object | @@ -7227,21 +7151,17 @@ postDominance | MultiImplementationA.cs:13:16:13:20 | ... = ... | MultiImplementationA.cs:13:20:13:20 | 0 | | MultiImplementationA.cs:13:20:13:20 | 0 | MultiImplementationA.cs:13:16:13:16 | this access | | MultiImplementationA.cs:14:31:14:31 | access to parameter i | MultiImplementationA.cs:14:31:14:31 | enter get_Item | -| MultiImplementationA.cs:14:31:14:31 | access to parameter i | MultiImplementationB.cs:12:31:12:40 | enter get_Item | | MultiImplementationA.cs:14:31:14:31 | exit get_Item (abnormal) | MultiImplementationB.cs:12:31:12:40 | throw ... | | MultiImplementationA.cs:14:31:14:31 | exit get_Item (normal) | MultiImplementationA.cs:14:31:14:31 | access to parameter i | | MultiImplementationA.cs:15:36:15:38 | exit get_Item (abnormal) | MultiImplementationB.cs:13:42:13:52 | throw ...; | | MultiImplementationA.cs:15:36:15:38 | exit get_Item (normal) | MultiImplementationA.cs:15:42:15:50 | return ...; | | MultiImplementationA.cs:15:40:15:52 | {...} | MultiImplementationA.cs:15:36:15:38 | enter get_Item | -| MultiImplementationA.cs:15:40:15:52 | {...} | MultiImplementationB.cs:13:36:13:38 | enter get_Item | | MultiImplementationA.cs:15:42:15:50 | return ...; | MultiImplementationA.cs:15:49:15:49 | access to parameter s | | MultiImplementationA.cs:15:49:15:49 | access to parameter s | MultiImplementationA.cs:15:40:15:52 | {...} | | MultiImplementationA.cs:15:54:15:56 | exit set_Item | MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | -| MultiImplementationA.cs:15:54:15:56 | exit set_Item | MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | | MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | MultiImplementationA.cs:15:58:15:60 | {...} | | MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | MultiImplementationB.cs:13:60:13:62 | {...} | | MultiImplementationA.cs:16:17:16:18 | exit M1 | MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | -| MultiImplementationA.cs:16:17:16:18 | exit M1 | MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | | MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | MultiImplementationA.cs:18:9:18:22 | M2(...) | | MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | MultiImplementationB.cs:16:9:16:31 | M2(...) | | MultiImplementationA.cs:18:9:18:22 | M2(...) | MultiImplementationA.cs:17:5:19:5 | {...} | @@ -7249,7 +7169,6 @@ postDominance | MultiImplementationA.cs:18:9:18:22 | exit M2 (normal) | MultiImplementationA.cs:18:21:18:21 | 0 | | MultiImplementationA.cs:18:21:18:21 | 0 | MultiImplementationA.cs:18:9:18:22 | enter M2 | | MultiImplementationA.cs:20:12:20:13 | call to constructor Object | MultiImplementationA.cs:20:12:20:13 | enter C2 | -| MultiImplementationA.cs:20:12:20:13 | call to constructor Object | MultiImplementationB.cs:18:12:18:13 | enter C2 | | MultiImplementationA.cs:20:12:20:13 | exit C2 (abnormal) | MultiImplementationB.cs:18:24:18:34 | throw ...; | | MultiImplementationA.cs:20:12:20:13 | exit C2 (normal) | MultiImplementationA.cs:20:24:20:28 | ... = ... | | MultiImplementationA.cs:20:22:20:31 | {...} | MultiImplementationA.cs:24:32:24:34 | ... = ... | @@ -7258,7 +7177,6 @@ postDominance | MultiImplementationA.cs:20:24:20:29 | ...; | MultiImplementationA.cs:20:22:20:31 | {...} | | MultiImplementationA.cs:20:28:20:28 | access to parameter i | MultiImplementationA.cs:20:24:20:24 | this access | | MultiImplementationA.cs:21:12:21:13 | exit C2 | MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | -| MultiImplementationA.cs:21:12:21:13 | exit C2 | MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | | MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | MultiImplementationA.cs:21:27:21:29 | {...} | | MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | MultiImplementationB.cs:19:27:19:29 | {...} | | MultiImplementationA.cs:21:19:21:22 | call to constructor C2 | MultiImplementationA.cs:21:24:21:24 | 0 | @@ -7266,28 +7184,22 @@ postDominance | MultiImplementationA.cs:22:6:22:7 | exit ~C2 (abnormal) | MultiImplementationB.cs:20:13:20:23 | throw ...; | | MultiImplementationA.cs:22:6:22:7 | exit ~C2 (normal) | MultiImplementationA.cs:22:11:22:13 | {...} | | MultiImplementationA.cs:22:11:22:13 | {...} | MultiImplementationA.cs:22:6:22:7 | enter ~C2 | -| MultiImplementationA.cs:22:11:22:13 | {...} | MultiImplementationB.cs:20:6:20:7 | enter ~C2 | | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion (abnormal) | MultiImplementationB.cs:21:50:21:59 | throw ... | | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion (normal) | MultiImplementationA.cs:23:50:23:53 | null | | MultiImplementationA.cs:23:50:23:53 | null | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | -| MultiImplementationA.cs:23:50:23:53 | null | MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | | MultiImplementationA.cs:24:16:24:16 | access to property P | MultiImplementationA.cs:24:34:24:34 | 0 | | MultiImplementationA.cs:24:16:24:16 | this access | MultiImplementationA.cs:13:16:13:20 | ... = ... | | MultiImplementationA.cs:24:32:24:34 | ... = ... | MultiImplementationA.cs:24:16:24:16 | access to property P | | MultiImplementationA.cs:24:34:24:34 | 0 | MultiImplementationA.cs:24:16:24:16 | this access | | MultiImplementationA.cs:28:7:28:8 | exit C3 | MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | -| MultiImplementationA.cs:28:7:28:8 | exit C3 | MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | | MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | MultiImplementationA.cs:28:7:28:8 | {...} | | MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | MultiImplementationB.cs:25:7:25:8 | {...} | | MultiImplementationA.cs:28:7:28:8 | {...} | MultiImplementationA.cs:28:7:28:8 | call to constructor Object | | MultiImplementationA.cs:30:21:30:23 | exit get_P3 | MultiImplementationA.cs:30:21:30:23 | exit get_P3 (abnormal) | -| MultiImplementationA.cs:30:21:30:23 | exit get_P3 | MultiImplementationB.cs:27:21:27:23 | exit get_P3 (abnormal) | | MultiImplementationA.cs:30:21:30:23 | exit get_P3 (abnormal) | MultiImplementationA.cs:30:28:30:37 | throw ... | | MultiImplementationA.cs:30:28:30:37 | throw ... | MultiImplementationA.cs:30:34:30:37 | null | | MultiImplementationA.cs:30:34:30:37 | null | MultiImplementationA.cs:30:21:30:23 | enter get_P3 | -| MultiImplementationA.cs:30:34:30:37 | null | MultiImplementationB.cs:27:21:27:23 | enter get_P3 | | MultiImplementationA.cs:34:15:34:16 | exit C4 | MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | -| MultiImplementationA.cs:34:15:34:16 | exit C4 | MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | | MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | MultiImplementationA.cs:34:15:34:16 | {...} | | MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | MultiImplementationB.cs:30:15:30:16 | {...} | | MultiImplementationA.cs:34:15:34:16 | {...} | MultiImplementationA.cs:34:15:34:16 | call to constructor Object | @@ -7300,91 +7212,39 @@ postDominance | MultiImplementationA.cs:37:14:37:28 | {...} | MultiImplementationA.cs:37:9:37:10 | enter M2 | | MultiImplementationA.cs:37:16:37:26 | throw ...; | MultiImplementationA.cs:37:22:37:25 | null | | MultiImplementationA.cs:37:22:37:25 | null | MultiImplementationA.cs:37:14:37:28 | {...} | -| MultiImplementationB.cs:1:7:1:8 | exit C1 | MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | -| MultiImplementationB.cs:1:7:1:8 | exit C1 | MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | -| MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | MultiImplementationA.cs:4:7:4:8 | {...} | -| MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | MultiImplementationB.cs:1:7:1:8 | {...} | | MultiImplementationB.cs:1:7:1:8 | {...} | MultiImplementationB.cs:1:7:1:8 | call to constructor Object | | MultiImplementationB.cs:3:22:3:22 | 0 | MultiImplementationA.cs:6:22:6:31 | enter get_P1 | -| MultiImplementationB.cs:3:22:3:22 | 0 | MultiImplementationB.cs:3:22:3:22 | enter get_P1 | -| MultiImplementationB.cs:3:22:3:22 | exit get_P1 (abnormal) | MultiImplementationA.cs:6:22:6:31 | throw ... | -| MultiImplementationB.cs:3:22:3:22 | exit get_P1 (normal) | MultiImplementationB.cs:3:22:3:22 | 0 | -| MultiImplementationB.cs:4:21:4:23 | exit get_P2 (abnormal) | MultiImplementationA.cs:7:27:7:37 | throw ...; | -| MultiImplementationB.cs:4:21:4:23 | exit get_P2 (normal) | MultiImplementationB.cs:4:27:4:35 | return ...; | | MultiImplementationB.cs:4:25:4:37 | {...} | MultiImplementationA.cs:7:21:7:23 | enter get_P2 | -| MultiImplementationB.cs:4:25:4:37 | {...} | MultiImplementationB.cs:4:21:4:23 | enter get_P2 | | MultiImplementationB.cs:4:27:4:35 | return ...; | MultiImplementationB.cs:4:34:4:34 | 1 | | MultiImplementationB.cs:4:34:4:34 | 1 | MultiImplementationB.cs:4:25:4:37 | {...} | -| MultiImplementationB.cs:4:39:4:41 | exit set_P2 (abnormal) | MultiImplementationA.cs:7:47:7:57 | throw ...; | -| MultiImplementationB.cs:4:39:4:41 | exit set_P2 (normal) | MultiImplementationB.cs:4:43:4:45 | {...} | | MultiImplementationB.cs:4:43:4:45 | {...} | MultiImplementationA.cs:7:41:7:43 | enter set_P2 | -| MultiImplementationB.cs:4:43:4:45 | {...} | MultiImplementationB.cs:4:39:4:41 | enter set_P2 | -| MultiImplementationB.cs:5:16:5:16 | exit M (abnormal) | MultiImplementationA.cs:8:23:8:32 | throw ... | -| MultiImplementationB.cs:5:16:5:16 | exit M (normal) | MultiImplementationB.cs:5:23:5:23 | 2 | | MultiImplementationB.cs:5:23:5:23 | 2 | MultiImplementationA.cs:8:16:8:16 | enter M | -| MultiImplementationB.cs:5:23:5:23 | 2 | MultiImplementationB.cs:5:16:5:16 | enter M | | MultiImplementationB.cs:11:16:11:16 | this access | MultiImplementationB.cs:18:12:18:13 | call to constructor Object | | MultiImplementationB.cs:11:16:11:20 | ... = ... | MultiImplementationB.cs:11:20:11:20 | 1 | | MultiImplementationB.cs:11:20:11:20 | 1 | MultiImplementationB.cs:11:16:11:16 | this access | -| MultiImplementationB.cs:12:31:12:40 | exit get_Item (abnormal) | MultiImplementationB.cs:12:31:12:40 | throw ... | -| MultiImplementationB.cs:12:31:12:40 | exit get_Item (normal) | MultiImplementationA.cs:14:31:14:31 | access to parameter i | | MultiImplementationB.cs:12:31:12:40 | throw ... | MultiImplementationB.cs:12:37:12:40 | null | -| MultiImplementationB.cs:13:36:13:38 | exit get_Item (abnormal) | MultiImplementationB.cs:13:42:13:52 | throw ...; | -| MultiImplementationB.cs:13:36:13:38 | exit get_Item (normal) | MultiImplementationA.cs:15:42:15:50 | return ...; | | MultiImplementationB.cs:13:42:13:52 | throw ...; | MultiImplementationB.cs:13:48:13:51 | null | | MultiImplementationB.cs:13:48:13:51 | null | MultiImplementationB.cs:13:40:13:54 | {...} | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item | MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item | MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | MultiImplementationA.cs:15:58:15:60 | {...} | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | MultiImplementationB.cs:13:60:13:62 | {...} | -| MultiImplementationB.cs:14:17:14:18 | exit M1 | MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | -| MultiImplementationB.cs:14:17:14:18 | exit M1 | MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | -| MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | MultiImplementationA.cs:18:9:18:22 | M2(...) | -| MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | MultiImplementationB.cs:16:9:16:31 | M2(...) | | MultiImplementationB.cs:16:9:16:31 | M2(...) | MultiImplementationB.cs:15:5:17:5 | {...} | | MultiImplementationB.cs:16:9:16:31 | exit M2 | MultiImplementationB.cs:16:9:16:31 | exit M2 (abnormal) | | MultiImplementationB.cs:16:9:16:31 | exit M2 (abnormal) | MultiImplementationB.cs:16:21:16:30 | throw ... | | MultiImplementationB.cs:16:21:16:30 | throw ... | MultiImplementationB.cs:16:27:16:30 | null | | MultiImplementationB.cs:16:27:16:30 | null | MultiImplementationB.cs:16:9:16:31 | enter M2 | -| MultiImplementationB.cs:18:12:18:13 | exit C2 (abnormal) | MultiImplementationB.cs:18:24:18:34 | throw ...; | -| MultiImplementationB.cs:18:12:18:13 | exit C2 (normal) | MultiImplementationA.cs:20:24:20:28 | ... = ... | | MultiImplementationB.cs:18:22:18:36 | {...} | MultiImplementationB.cs:22:32:22:34 | ... = ... | | MultiImplementationB.cs:18:24:18:34 | throw ...; | MultiImplementationB.cs:18:30:18:33 | null | | MultiImplementationB.cs:18:30:18:33 | null | MultiImplementationB.cs:18:22:18:36 | {...} | -| MultiImplementationB.cs:19:12:19:13 | exit C2 | MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | -| MultiImplementationB.cs:19:12:19:13 | exit C2 | MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | -| MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | MultiImplementationA.cs:21:27:21:29 | {...} | -| MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | MultiImplementationB.cs:19:27:19:29 | {...} | | MultiImplementationB.cs:19:19:19:22 | call to constructor C2 | MultiImplementationB.cs:19:24:19:24 | 1 | | MultiImplementationB.cs:19:27:19:29 | {...} | MultiImplementationB.cs:19:19:19:22 | call to constructor C2 | -| MultiImplementationB.cs:20:6:20:7 | exit ~C2 (abnormal) | MultiImplementationB.cs:20:13:20:23 | throw ...; | -| MultiImplementationB.cs:20:6:20:7 | exit ~C2 (normal) | MultiImplementationA.cs:22:11:22:13 | {...} | | MultiImplementationB.cs:20:13:20:23 | throw ...; | MultiImplementationB.cs:20:19:20:22 | null | | MultiImplementationB.cs:20:19:20:22 | null | MultiImplementationB.cs:20:11:20:25 | {...} | -| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion (abnormal) | MultiImplementationB.cs:21:50:21:59 | throw ... | -| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion (normal) | MultiImplementationA.cs:23:50:23:53 | null | | MultiImplementationB.cs:21:50:21:59 | throw ... | MultiImplementationB.cs:21:56:21:59 | null | | MultiImplementationB.cs:22:16:22:16 | access to property P | MultiImplementationB.cs:22:34:22:34 | 1 | | MultiImplementationB.cs:22:16:22:16 | this access | MultiImplementationB.cs:11:16:11:20 | ... = ... | | MultiImplementationB.cs:22:32:22:34 | ... = ... | MultiImplementationB.cs:22:16:22:16 | access to property P | | MultiImplementationB.cs:22:34:22:34 | 1 | MultiImplementationB.cs:22:16:22:16 | this access | -| MultiImplementationB.cs:25:7:25:8 | exit C3 | MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | -| MultiImplementationB.cs:25:7:25:8 | exit C3 | MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | -| MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | MultiImplementationA.cs:28:7:28:8 | {...} | -| MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | MultiImplementationB.cs:25:7:25:8 | {...} | | MultiImplementationB.cs:25:7:25:8 | {...} | MultiImplementationB.cs:25:7:25:8 | call to constructor Object | -| MultiImplementationB.cs:27:21:27:23 | exit get_P3 | MultiImplementationA.cs:30:21:30:23 | exit get_P3 (abnormal) | -| MultiImplementationB.cs:27:21:27:23 | exit get_P3 | MultiImplementationB.cs:27:21:27:23 | exit get_P3 (abnormal) | -| MultiImplementationB.cs:27:21:27:23 | exit get_P3 (abnormal) | MultiImplementationA.cs:30:28:30:37 | throw ... | -| MultiImplementationB.cs:30:15:30:16 | exit C4 | MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | -| MultiImplementationB.cs:30:15:30:16 | exit C4 | MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | -| MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | MultiImplementationA.cs:34:15:34:16 | {...} | -| MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | MultiImplementationB.cs:30:15:30:16 | {...} | | MultiImplementationB.cs:30:15:30:16 | {...} | MultiImplementationB.cs:30:15:30:16 | call to constructor Object | -| MultiImplementationB.cs:32:9:32:10 | exit M1 (abnormal) | MultiImplementationA.cs:36:16:36:26 | throw ...; | -| MultiImplementationB.cs:32:9:32:10 | exit M1 (normal) | MultiImplementationB.cs:32:17:32:17 | 0 | | MultiImplementationB.cs:32:17:32:17 | 0 | MultiImplementationA.cs:36:9:36:10 | enter M1 | -| MultiImplementationB.cs:32:17:32:17 | 0 | MultiImplementationB.cs:32:9:32:10 | enter M1 | | NullCoalescing.cs:1:7:1:20 | call to constructor Object | NullCoalescing.cs:1:7:1:20 | enter NullCoalescing | | NullCoalescing.cs:1:7:1:20 | exit NullCoalescing | NullCoalescing.cs:1:7:1:20 | exit NullCoalescing (normal) | | NullCoalescing.cs:1:7:1:20 | exit NullCoalescing (normal) | NullCoalescing.cs:1:7:1:20 | {...} | @@ -11734,81 +11594,54 @@ blockDominance | MultiImplementationA.cs:4:7:4:8 | enter C1 | MultiImplementationA.cs:4:7:4:8 | enter C1 | | MultiImplementationA.cs:4:7:4:8 | enter C1 | MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | | MultiImplementationA.cs:4:7:4:8 | enter C1 | MultiImplementationB.cs:1:7:1:8 | call to constructor Object | -| MultiImplementationA.cs:4:7:4:8 | enter C1 | MultiImplementationB.cs:1:7:1:8 | enter C1 | -| MultiImplementationA.cs:4:7:4:8 | enter C1 | MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | | MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | -| MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | | MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationA.cs:6:22:6:31 | enter get_P1 | | MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationA.cs:6:22:6:31 | exit get_P1 | | MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationA.cs:6:28:6:31 | null | | MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | 0 | -| MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | enter get_P1 | -| MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | exit get_P1 | | MultiImplementationA.cs:6:22:6:31 | exit get_P1 | MultiImplementationA.cs:6:22:6:31 | exit get_P1 | -| MultiImplementationA.cs:6:22:6:31 | exit get_P1 | MultiImplementationB.cs:3:22:3:22 | exit get_P1 | | MultiImplementationA.cs:6:28:6:31 | null | MultiImplementationA.cs:6:28:6:31 | null | | MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationA.cs:7:21:7:23 | enter get_P2 | | MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationA.cs:7:21:7:23 | exit get_P2 | | MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationA.cs:7:25:7:39 | {...} | -| MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationB.cs:4:21:4:23 | enter get_P2 | -| MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationB.cs:4:21:4:23 | exit get_P2 | | MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationB.cs:4:25:4:37 | {...} | | MultiImplementationA.cs:7:21:7:23 | exit get_P2 | MultiImplementationA.cs:7:21:7:23 | exit get_P2 | -| MultiImplementationA.cs:7:21:7:23 | exit get_P2 | MultiImplementationB.cs:4:21:4:23 | exit get_P2 | | MultiImplementationA.cs:7:25:7:39 | {...} | MultiImplementationA.cs:7:25:7:39 | {...} | | MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationA.cs:7:41:7:43 | enter set_P2 | | MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationA.cs:7:41:7:43 | exit set_P2 | | MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationA.cs:7:45:7:59 | {...} | -| MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationB.cs:4:39:4:41 | enter set_P2 | -| MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationB.cs:4:39:4:41 | exit set_P2 | | MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationB.cs:4:43:4:45 | {...} | | MultiImplementationA.cs:7:41:7:43 | exit set_P2 | MultiImplementationA.cs:7:41:7:43 | exit set_P2 | -| MultiImplementationA.cs:7:41:7:43 | exit set_P2 | MultiImplementationB.cs:4:39:4:41 | exit set_P2 | | MultiImplementationA.cs:7:45:7:59 | {...} | MultiImplementationA.cs:7:45:7:59 | {...} | | MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationA.cs:8:16:8:16 | enter M | | MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationA.cs:8:16:8:16 | exit M | | MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationA.cs:8:29:8:32 | null | -| MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationB.cs:5:16:5:16 | enter M | -| MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationB.cs:5:16:5:16 | exit M | | MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationB.cs:5:23:5:23 | 2 | | MultiImplementationA.cs:8:16:8:16 | exit M | MultiImplementationA.cs:8:16:8:16 | exit M | -| MultiImplementationA.cs:8:16:8:16 | exit M | MultiImplementationB.cs:5:16:5:16 | exit M | | MultiImplementationA.cs:8:29:8:32 | null | MultiImplementationA.cs:8:29:8:32 | null | | MultiImplementationA.cs:14:31:14:31 | access to parameter i | MultiImplementationA.cs:14:31:14:31 | access to parameter i | | MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | access to parameter i | | MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | enter get_Item | | MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | exit get_Item | -| MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationB.cs:12:31:12:40 | enter get_Item | -| MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationB.cs:12:31:12:40 | exit get_Item | | MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationB.cs:12:37:12:40 | null | | MultiImplementationA.cs:14:31:14:31 | exit get_Item | MultiImplementationA.cs:14:31:14:31 | exit get_Item | -| MultiImplementationA.cs:14:31:14:31 | exit get_Item | MultiImplementationB.cs:12:31:12:40 | exit get_Item | | MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationA.cs:15:36:15:38 | enter get_Item | | MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationA.cs:15:36:15:38 | exit get_Item | | MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationA.cs:15:40:15:52 | {...} | -| MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationB.cs:13:36:13:38 | enter get_Item | -| MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationB.cs:13:36:13:38 | exit get_Item | | MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationB.cs:13:40:13:54 | {...} | | MultiImplementationA.cs:15:36:15:38 | exit get_Item | MultiImplementationA.cs:15:36:15:38 | exit get_Item | -| MultiImplementationA.cs:15:36:15:38 | exit get_Item | MultiImplementationB.cs:13:36:13:38 | exit get_Item | | MultiImplementationA.cs:15:40:15:52 | {...} | MultiImplementationA.cs:15:40:15:52 | {...} | | MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationA.cs:15:54:15:56 | enter set_Item | | MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | | MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationA.cs:15:58:15:60 | {...} | -| MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationB.cs:13:56:13:58 | enter set_Item | -| MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | | MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationB.cs:13:60:13:62 | {...} | | MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | -| MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | | MultiImplementationA.cs:15:58:15:60 | {...} | MultiImplementationA.cs:15:58:15:60 | {...} | | MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationA.cs:16:17:16:18 | enter M1 | | MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | | MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationA.cs:17:5:19:5 | {...} | -| MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationB.cs:14:17:14:18 | enter M1 | -| MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | | MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationB.cs:15:5:17:5 | {...} | | MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | -| MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | | MultiImplementationA.cs:17:5:19:5 | {...} | MultiImplementationA.cs:17:5:19:5 | {...} | | MultiImplementationA.cs:18:9:18:22 | enter M2 | MultiImplementationA.cs:18:9:18:22 | enter M2 | | MultiImplementationA.cs:20:12:20:13 | call to constructor Object | MultiImplementationA.cs:20:12:20:13 | call to constructor Object | @@ -11816,213 +11649,61 @@ blockDominance | MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | enter C2 | | MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | exit C2 | | MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | call to constructor Object | -| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | enter C2 | -| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | exit C2 | | MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationA.cs:20:12:20:13 | exit C2 | -| MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationB.cs:18:12:18:13 | exit C2 | | MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationA.cs:21:12:21:13 | enter C2 | | MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | | MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationA.cs:21:24:21:24 | 0 | -| MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationB.cs:19:12:19:13 | enter C2 | -| MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | | MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationB.cs:19:24:19:24 | 1 | | MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | -| MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | | MultiImplementationA.cs:21:24:21:24 | 0 | MultiImplementationA.cs:21:24:21:24 | 0 | | MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationA.cs:22:6:22:7 | enter ~C2 | | MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationA.cs:22:6:22:7 | exit ~C2 | | MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationA.cs:22:11:22:13 | {...} | -| MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationB.cs:20:6:20:7 | enter ~C2 | -| MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationB.cs:20:6:20:7 | exit ~C2 | | MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationB.cs:20:11:20:25 | {...} | | MultiImplementationA.cs:22:6:22:7 | exit ~C2 | MultiImplementationA.cs:22:6:22:7 | exit ~C2 | -| MultiImplementationA.cs:22:6:22:7 | exit ~C2 | MultiImplementationB.cs:20:6:20:7 | exit ~C2 | | MultiImplementationA.cs:22:11:22:13 | {...} | MultiImplementationA.cs:22:11:22:13 | {...} | | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationA.cs:23:50:23:53 | null | -| MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | -| MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationB.cs:21:56:21:59 | null | | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | -| MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | | MultiImplementationA.cs:23:50:23:53 | null | MultiImplementationA.cs:23:50:23:53 | null | | MultiImplementationA.cs:28:7:28:8 | call to constructor Object | MultiImplementationA.cs:28:7:28:8 | call to constructor Object | | MultiImplementationA.cs:28:7:28:8 | enter C3 | MultiImplementationA.cs:28:7:28:8 | call to constructor Object | | MultiImplementationA.cs:28:7:28:8 | enter C3 | MultiImplementationA.cs:28:7:28:8 | enter C3 | | MultiImplementationA.cs:28:7:28:8 | enter C3 | MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | | MultiImplementationA.cs:28:7:28:8 | enter C3 | MultiImplementationB.cs:25:7:25:8 | call to constructor Object | -| MultiImplementationA.cs:28:7:28:8 | enter C3 | MultiImplementationB.cs:25:7:25:8 | enter C3 | -| MultiImplementationA.cs:28:7:28:8 | enter C3 | MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | | MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | -| MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | | MultiImplementationA.cs:30:21:30:23 | enter get_P3 | MultiImplementationA.cs:30:21:30:23 | enter get_P3 | -| MultiImplementationA.cs:30:21:30:23 | enter get_P3 | MultiImplementationB.cs:27:21:27:23 | enter get_P3 | | MultiImplementationA.cs:34:15:34:16 | call to constructor Object | MultiImplementationA.cs:34:15:34:16 | call to constructor Object | | MultiImplementationA.cs:34:15:34:16 | enter C4 | MultiImplementationA.cs:34:15:34:16 | call to constructor Object | | MultiImplementationA.cs:34:15:34:16 | enter C4 | MultiImplementationA.cs:34:15:34:16 | enter C4 | | MultiImplementationA.cs:34:15:34:16 | enter C4 | MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | | MultiImplementationA.cs:34:15:34:16 | enter C4 | MultiImplementationB.cs:30:15:30:16 | call to constructor Object | -| MultiImplementationA.cs:34:15:34:16 | enter C4 | MultiImplementationB.cs:30:15:30:16 | enter C4 | -| MultiImplementationA.cs:34:15:34:16 | enter C4 | MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | | MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | -| MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | | MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationA.cs:36:9:36:10 | enter M1 | | MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationA.cs:36:9:36:10 | exit M1 | | MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationA.cs:36:14:36:28 | {...} | -| MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationB.cs:32:9:32:10 | enter M1 | -| MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationB.cs:32:9:32:10 | exit M1 | | MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationB.cs:32:17:32:17 | 0 | | MultiImplementationA.cs:36:9:36:10 | exit M1 | MultiImplementationA.cs:36:9:36:10 | exit M1 | -| MultiImplementationA.cs:36:9:36:10 | exit M1 | MultiImplementationB.cs:32:9:32:10 | exit M1 | | MultiImplementationA.cs:36:14:36:28 | {...} | MultiImplementationA.cs:36:14:36:28 | {...} | | MultiImplementationA.cs:37:9:37:10 | enter M2 | MultiImplementationA.cs:37:9:37:10 | enter M2 | | MultiImplementationB.cs:1:7:1:8 | call to constructor Object | MultiImplementationB.cs:1:7:1:8 | call to constructor Object | -| MultiImplementationB.cs:1:7:1:8 | enter C1 | MultiImplementationA.cs:4:7:4:8 | call to constructor Object | -| MultiImplementationB.cs:1:7:1:8 | enter C1 | MultiImplementationA.cs:4:7:4:8 | enter C1 | -| MultiImplementationB.cs:1:7:1:8 | enter C1 | MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | -| MultiImplementationB.cs:1:7:1:8 | enter C1 | MultiImplementationB.cs:1:7:1:8 | call to constructor Object | -| MultiImplementationB.cs:1:7:1:8 | enter C1 | MultiImplementationB.cs:1:7:1:8 | enter C1 | -| MultiImplementationB.cs:1:7:1:8 | enter C1 | MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | -| MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | -| MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | | MultiImplementationB.cs:3:22:3:22 | 0 | MultiImplementationB.cs:3:22:3:22 | 0 | -| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationA.cs:6:22:6:31 | enter get_P1 | -| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationA.cs:6:22:6:31 | exit get_P1 | -| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationA.cs:6:28:6:31 | null | -| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | 0 | -| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | enter get_P1 | -| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | exit get_P1 | -| MultiImplementationB.cs:3:22:3:22 | exit get_P1 | MultiImplementationA.cs:6:22:6:31 | exit get_P1 | -| MultiImplementationB.cs:3:22:3:22 | exit get_P1 | MultiImplementationB.cs:3:22:3:22 | exit get_P1 | -| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationA.cs:7:21:7:23 | enter get_P2 | -| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationA.cs:7:21:7:23 | exit get_P2 | -| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationA.cs:7:25:7:39 | {...} | -| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationB.cs:4:21:4:23 | enter get_P2 | -| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationB.cs:4:21:4:23 | exit get_P2 | -| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationB.cs:4:25:4:37 | {...} | -| MultiImplementationB.cs:4:21:4:23 | exit get_P2 | MultiImplementationA.cs:7:21:7:23 | exit get_P2 | -| MultiImplementationB.cs:4:21:4:23 | exit get_P2 | MultiImplementationB.cs:4:21:4:23 | exit get_P2 | | MultiImplementationB.cs:4:25:4:37 | {...} | MultiImplementationB.cs:4:25:4:37 | {...} | -| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationA.cs:7:41:7:43 | enter set_P2 | -| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationA.cs:7:41:7:43 | exit set_P2 | -| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationA.cs:7:45:7:59 | {...} | -| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationB.cs:4:39:4:41 | enter set_P2 | -| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationB.cs:4:39:4:41 | exit set_P2 | -| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationB.cs:4:43:4:45 | {...} | -| MultiImplementationB.cs:4:39:4:41 | exit set_P2 | MultiImplementationA.cs:7:41:7:43 | exit set_P2 | -| MultiImplementationB.cs:4:39:4:41 | exit set_P2 | MultiImplementationB.cs:4:39:4:41 | exit set_P2 | | MultiImplementationB.cs:4:43:4:45 | {...} | MultiImplementationB.cs:4:43:4:45 | {...} | -| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationA.cs:8:16:8:16 | enter M | -| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationA.cs:8:16:8:16 | exit M | -| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationA.cs:8:29:8:32 | null | -| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationB.cs:5:16:5:16 | enter M | -| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationB.cs:5:16:5:16 | exit M | -| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationB.cs:5:23:5:23 | 2 | -| MultiImplementationB.cs:5:16:5:16 | exit M | MultiImplementationA.cs:8:16:8:16 | exit M | -| MultiImplementationB.cs:5:16:5:16 | exit M | MultiImplementationB.cs:5:16:5:16 | exit M | | MultiImplementationB.cs:5:23:5:23 | 2 | MultiImplementationB.cs:5:23:5:23 | 2 | -| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | access to parameter i | -| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | enter get_Item | -| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | exit get_Item | -| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationB.cs:12:31:12:40 | enter get_Item | -| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationB.cs:12:31:12:40 | exit get_Item | -| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationB.cs:12:37:12:40 | null | -| MultiImplementationB.cs:12:31:12:40 | exit get_Item | MultiImplementationA.cs:14:31:14:31 | exit get_Item | -| MultiImplementationB.cs:12:31:12:40 | exit get_Item | MultiImplementationB.cs:12:31:12:40 | exit get_Item | | MultiImplementationB.cs:12:37:12:40 | null | MultiImplementationB.cs:12:37:12:40 | null | -| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationA.cs:15:36:15:38 | enter get_Item | -| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationA.cs:15:36:15:38 | exit get_Item | -| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationA.cs:15:40:15:52 | {...} | -| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationB.cs:13:36:13:38 | enter get_Item | -| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationB.cs:13:36:13:38 | exit get_Item | -| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationB.cs:13:40:13:54 | {...} | -| MultiImplementationB.cs:13:36:13:38 | exit get_Item | MultiImplementationA.cs:15:36:15:38 | exit get_Item | -| MultiImplementationB.cs:13:36:13:38 | exit get_Item | MultiImplementationB.cs:13:36:13:38 | exit get_Item | | MultiImplementationB.cs:13:40:13:54 | {...} | MultiImplementationB.cs:13:40:13:54 | {...} | -| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationA.cs:15:54:15:56 | enter set_Item | -| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | -| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationA.cs:15:58:15:60 | {...} | -| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationB.cs:13:56:13:58 | enter set_Item | -| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | -| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationB.cs:13:60:13:62 | {...} | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | | MultiImplementationB.cs:13:60:13:62 | {...} | MultiImplementationB.cs:13:60:13:62 | {...} | -| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationA.cs:16:17:16:18 | enter M1 | -| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | -| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationA.cs:17:5:19:5 | {...} | -| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationB.cs:14:17:14:18 | enter M1 | -| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | -| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationB.cs:15:5:17:5 | {...} | -| MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | -| MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | | MultiImplementationB.cs:15:5:17:5 | {...} | MultiImplementationB.cs:15:5:17:5 | {...} | | MultiImplementationB.cs:16:9:16:31 | enter M2 | MultiImplementationB.cs:16:9:16:31 | enter M2 | | MultiImplementationB.cs:18:12:18:13 | call to constructor Object | MultiImplementationB.cs:18:12:18:13 | call to constructor Object | -| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | call to constructor Object | -| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | enter C2 | -| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | exit C2 | -| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | call to constructor Object | -| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | enter C2 | -| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | exit C2 | -| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationA.cs:20:12:20:13 | exit C2 | -| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationB.cs:18:12:18:13 | exit C2 | -| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationA.cs:21:12:21:13 | enter C2 | -| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | -| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationA.cs:21:24:21:24 | 0 | -| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationB.cs:19:12:19:13 | enter C2 | -| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | -| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationB.cs:19:24:19:24 | 1 | -| MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | -| MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | | MultiImplementationB.cs:19:24:19:24 | 1 | MultiImplementationB.cs:19:24:19:24 | 1 | -| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationA.cs:22:6:22:7 | enter ~C2 | -| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationA.cs:22:6:22:7 | exit ~C2 | -| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationA.cs:22:11:22:13 | {...} | -| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationB.cs:20:6:20:7 | enter ~C2 | -| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationB.cs:20:6:20:7 | exit ~C2 | -| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationB.cs:20:11:20:25 | {...} | -| MultiImplementationB.cs:20:6:20:7 | exit ~C2 | MultiImplementationA.cs:22:6:22:7 | exit ~C2 | -| MultiImplementationB.cs:20:6:20:7 | exit ~C2 | MultiImplementationB.cs:20:6:20:7 | exit ~C2 | | MultiImplementationB.cs:20:11:20:25 | {...} | MultiImplementationB.cs:20:11:20:25 | {...} | -| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | -| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | -| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationA.cs:23:50:23:53 | null | -| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | -| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | -| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationB.cs:21:56:21:59 | null | -| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | -| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | | MultiImplementationB.cs:21:56:21:59 | null | MultiImplementationB.cs:21:56:21:59 | null | | MultiImplementationB.cs:25:7:25:8 | call to constructor Object | MultiImplementationB.cs:25:7:25:8 | call to constructor Object | -| MultiImplementationB.cs:25:7:25:8 | enter C3 | MultiImplementationA.cs:28:7:28:8 | call to constructor Object | -| MultiImplementationB.cs:25:7:25:8 | enter C3 | MultiImplementationA.cs:28:7:28:8 | enter C3 | -| MultiImplementationB.cs:25:7:25:8 | enter C3 | MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | -| MultiImplementationB.cs:25:7:25:8 | enter C3 | MultiImplementationB.cs:25:7:25:8 | call to constructor Object | -| MultiImplementationB.cs:25:7:25:8 | enter C3 | MultiImplementationB.cs:25:7:25:8 | enter C3 | -| MultiImplementationB.cs:25:7:25:8 | enter C3 | MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | -| MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | -| MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | -| MultiImplementationB.cs:27:21:27:23 | enter get_P3 | MultiImplementationA.cs:30:21:30:23 | enter get_P3 | -| MultiImplementationB.cs:27:21:27:23 | enter get_P3 | MultiImplementationB.cs:27:21:27:23 | enter get_P3 | | MultiImplementationB.cs:30:15:30:16 | call to constructor Object | MultiImplementationB.cs:30:15:30:16 | call to constructor Object | -| MultiImplementationB.cs:30:15:30:16 | enter C4 | MultiImplementationA.cs:34:15:34:16 | call to constructor Object | -| MultiImplementationB.cs:30:15:30:16 | enter C4 | MultiImplementationA.cs:34:15:34:16 | enter C4 | -| MultiImplementationB.cs:30:15:30:16 | enter C4 | MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | -| MultiImplementationB.cs:30:15:30:16 | enter C4 | MultiImplementationB.cs:30:15:30:16 | call to constructor Object | -| MultiImplementationB.cs:30:15:30:16 | enter C4 | MultiImplementationB.cs:30:15:30:16 | enter C4 | -| MultiImplementationB.cs:30:15:30:16 | enter C4 | MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | -| MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | -| MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | -| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationA.cs:36:9:36:10 | enter M1 | -| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationA.cs:36:9:36:10 | exit M1 | -| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationA.cs:36:14:36:28 | {...} | -| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationB.cs:32:9:32:10 | enter M1 | -| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationB.cs:32:9:32:10 | exit M1 | -| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationB.cs:32:17:32:17 | 0 | -| MultiImplementationB.cs:32:9:32:10 | exit M1 | MultiImplementationA.cs:36:9:36:10 | exit M1 | -| MultiImplementationB.cs:32:9:32:10 | exit M1 | MultiImplementationB.cs:32:9:32:10 | exit M1 | | MultiImplementationB.cs:32:17:32:17 | 0 | MultiImplementationB.cs:32:17:32:17 | 0 | | NullCoalescing.cs:1:7:1:20 | enter NullCoalescing | NullCoalescing.cs:1:7:1:20 | enter NullCoalescing | | NullCoalescing.cs:3:9:3:10 | enter M1 | NullCoalescing.cs:3:9:3:10 | enter M1 | @@ -15399,238 +15080,99 @@ postBlockDominance | LoopUnrolling.cs:97:22:97:22 | String x | LoopUnrolling.cs:97:22:97:22 | String x | | MultiImplementationA.cs:4:7:4:8 | call to constructor Object | MultiImplementationA.cs:4:7:4:8 | call to constructor Object | | MultiImplementationA.cs:4:7:4:8 | enter C1 | MultiImplementationA.cs:4:7:4:8 | enter C1 | -| MultiImplementationA.cs:4:7:4:8 | enter C1 | MultiImplementationB.cs:1:7:1:8 | enter C1 | | MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | MultiImplementationA.cs:4:7:4:8 | call to constructor Object | | MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | MultiImplementationA.cs:4:7:4:8 | enter C1 | | MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | | MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | MultiImplementationB.cs:1:7:1:8 | call to constructor Object | -| MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | MultiImplementationB.cs:1:7:1:8 | enter C1 | -| MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | | MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationA.cs:6:22:6:31 | enter get_P1 | -| MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | enter get_P1 | | MultiImplementationA.cs:6:22:6:31 | exit get_P1 | MultiImplementationA.cs:6:22:6:31 | exit get_P1 | -| MultiImplementationA.cs:6:22:6:31 | exit get_P1 | MultiImplementationB.cs:3:22:3:22 | exit get_P1 | | MultiImplementationA.cs:6:28:6:31 | null | MultiImplementationA.cs:6:28:6:31 | null | | MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationA.cs:7:21:7:23 | enter get_P2 | -| MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationB.cs:4:21:4:23 | enter get_P2 | | MultiImplementationA.cs:7:21:7:23 | exit get_P2 | MultiImplementationA.cs:7:21:7:23 | exit get_P2 | -| MultiImplementationA.cs:7:21:7:23 | exit get_P2 | MultiImplementationB.cs:4:21:4:23 | exit get_P2 | | MultiImplementationA.cs:7:25:7:39 | {...} | MultiImplementationA.cs:7:25:7:39 | {...} | | MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationA.cs:7:41:7:43 | enter set_P2 | -| MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationB.cs:4:39:4:41 | enter set_P2 | | MultiImplementationA.cs:7:41:7:43 | exit set_P2 | MultiImplementationA.cs:7:41:7:43 | exit set_P2 | -| MultiImplementationA.cs:7:41:7:43 | exit set_P2 | MultiImplementationB.cs:4:39:4:41 | exit set_P2 | | MultiImplementationA.cs:7:45:7:59 | {...} | MultiImplementationA.cs:7:45:7:59 | {...} | | MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationA.cs:8:16:8:16 | enter M | -| MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationB.cs:5:16:5:16 | enter M | | MultiImplementationA.cs:8:16:8:16 | exit M | MultiImplementationA.cs:8:16:8:16 | exit M | -| MultiImplementationA.cs:8:16:8:16 | exit M | MultiImplementationB.cs:5:16:5:16 | exit M | | MultiImplementationA.cs:8:29:8:32 | null | MultiImplementationA.cs:8:29:8:32 | null | | MultiImplementationA.cs:14:31:14:31 | access to parameter i | MultiImplementationA.cs:14:31:14:31 | access to parameter i | | MultiImplementationA.cs:14:31:14:31 | access to parameter i | MultiImplementationA.cs:14:31:14:31 | enter get_Item | -| MultiImplementationA.cs:14:31:14:31 | access to parameter i | MultiImplementationB.cs:12:31:12:40 | enter get_Item | | MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | enter get_Item | -| MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationB.cs:12:31:12:40 | enter get_Item | | MultiImplementationA.cs:14:31:14:31 | exit get_Item | MultiImplementationA.cs:14:31:14:31 | exit get_Item | -| MultiImplementationA.cs:14:31:14:31 | exit get_Item | MultiImplementationB.cs:12:31:12:40 | exit get_Item | | MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationA.cs:15:36:15:38 | enter get_Item | -| MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationB.cs:13:36:13:38 | enter get_Item | | MultiImplementationA.cs:15:36:15:38 | exit get_Item | MultiImplementationA.cs:15:36:15:38 | exit get_Item | -| MultiImplementationA.cs:15:36:15:38 | exit get_Item | MultiImplementationB.cs:13:36:13:38 | exit get_Item | | MultiImplementationA.cs:15:40:15:52 | {...} | MultiImplementationA.cs:15:36:15:38 | enter get_Item | | MultiImplementationA.cs:15:40:15:52 | {...} | MultiImplementationA.cs:15:40:15:52 | {...} | -| MultiImplementationA.cs:15:40:15:52 | {...} | MultiImplementationB.cs:13:36:13:38 | enter get_Item | | MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationA.cs:15:54:15:56 | enter set_Item | -| MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationB.cs:13:56:13:58 | enter set_Item | | MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | MultiImplementationA.cs:15:54:15:56 | enter set_Item | | MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | | MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | MultiImplementationA.cs:15:58:15:60 | {...} | -| MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | MultiImplementationB.cs:13:56:13:58 | enter set_Item | -| MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | | MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | MultiImplementationB.cs:13:60:13:62 | {...} | | MultiImplementationA.cs:15:58:15:60 | {...} | MultiImplementationA.cs:15:58:15:60 | {...} | | MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationA.cs:16:17:16:18 | enter M1 | -| MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationB.cs:14:17:14:18 | enter M1 | | MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | MultiImplementationA.cs:16:17:16:18 | enter M1 | | MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | | MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | MultiImplementationA.cs:17:5:19:5 | {...} | -| MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | MultiImplementationB.cs:14:17:14:18 | enter M1 | -| MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | | MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | MultiImplementationB.cs:15:5:17:5 | {...} | | MultiImplementationA.cs:17:5:19:5 | {...} | MultiImplementationA.cs:17:5:19:5 | {...} | | MultiImplementationA.cs:18:9:18:22 | enter M2 | MultiImplementationA.cs:18:9:18:22 | enter M2 | | MultiImplementationA.cs:20:12:20:13 | call to constructor Object | MultiImplementationA.cs:20:12:20:13 | call to constructor Object | | MultiImplementationA.cs:20:12:20:13 | call to constructor Object | MultiImplementationA.cs:20:12:20:13 | enter C2 | -| MultiImplementationA.cs:20:12:20:13 | call to constructor Object | MultiImplementationB.cs:18:12:18:13 | enter C2 | | MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | enter C2 | -| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | enter C2 | | MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationA.cs:20:12:20:13 | exit C2 | -| MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationB.cs:18:12:18:13 | exit C2 | | MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationA.cs:21:12:21:13 | enter C2 | -| MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationB.cs:19:12:19:13 | enter C2 | | MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | MultiImplementationA.cs:21:12:21:13 | enter C2 | | MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | | MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | MultiImplementationA.cs:21:24:21:24 | 0 | -| MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | MultiImplementationB.cs:19:12:19:13 | enter C2 | -| MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | | MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | MultiImplementationB.cs:19:24:19:24 | 1 | | MultiImplementationA.cs:21:24:21:24 | 0 | MultiImplementationA.cs:21:24:21:24 | 0 | | MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationA.cs:22:6:22:7 | enter ~C2 | -| MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationB.cs:20:6:20:7 | enter ~C2 | | MultiImplementationA.cs:22:6:22:7 | exit ~C2 | MultiImplementationA.cs:22:6:22:7 | exit ~C2 | -| MultiImplementationA.cs:22:6:22:7 | exit ~C2 | MultiImplementationB.cs:20:6:20:7 | exit ~C2 | | MultiImplementationA.cs:22:11:22:13 | {...} | MultiImplementationA.cs:22:6:22:7 | enter ~C2 | | MultiImplementationA.cs:22:11:22:13 | {...} | MultiImplementationA.cs:22:11:22:13 | {...} | -| MultiImplementationA.cs:22:11:22:13 | {...} | MultiImplementationB.cs:20:6:20:7 | enter ~C2 | | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | -| MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | -| MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | | MultiImplementationA.cs:23:50:23:53 | null | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | | MultiImplementationA.cs:23:50:23:53 | null | MultiImplementationA.cs:23:50:23:53 | null | -| MultiImplementationA.cs:23:50:23:53 | null | MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | | MultiImplementationA.cs:28:7:28:8 | call to constructor Object | MultiImplementationA.cs:28:7:28:8 | call to constructor Object | | MultiImplementationA.cs:28:7:28:8 | enter C3 | MultiImplementationA.cs:28:7:28:8 | enter C3 | -| MultiImplementationA.cs:28:7:28:8 | enter C3 | MultiImplementationB.cs:25:7:25:8 | enter C3 | | MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | MultiImplementationA.cs:28:7:28:8 | call to constructor Object | | MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | MultiImplementationA.cs:28:7:28:8 | enter C3 | | MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | | MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | MultiImplementationB.cs:25:7:25:8 | call to constructor Object | -| MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | MultiImplementationB.cs:25:7:25:8 | enter C3 | -| MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | | MultiImplementationA.cs:30:21:30:23 | enter get_P3 | MultiImplementationA.cs:30:21:30:23 | enter get_P3 | -| MultiImplementationA.cs:30:21:30:23 | enter get_P3 | MultiImplementationB.cs:27:21:27:23 | enter get_P3 | | MultiImplementationA.cs:34:15:34:16 | call to constructor Object | MultiImplementationA.cs:34:15:34:16 | call to constructor Object | | MultiImplementationA.cs:34:15:34:16 | enter C4 | MultiImplementationA.cs:34:15:34:16 | enter C4 | -| MultiImplementationA.cs:34:15:34:16 | enter C4 | MultiImplementationB.cs:30:15:30:16 | enter C4 | | MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | MultiImplementationA.cs:34:15:34:16 | call to constructor Object | | MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | MultiImplementationA.cs:34:15:34:16 | enter C4 | | MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | | MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | MultiImplementationB.cs:30:15:30:16 | call to constructor Object | -| MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | MultiImplementationB.cs:30:15:30:16 | enter C4 | -| MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | | MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationA.cs:36:9:36:10 | enter M1 | -| MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationB.cs:32:9:32:10 | enter M1 | | MultiImplementationA.cs:36:9:36:10 | exit M1 | MultiImplementationA.cs:36:9:36:10 | exit M1 | -| MultiImplementationA.cs:36:9:36:10 | exit M1 | MultiImplementationB.cs:32:9:32:10 | exit M1 | | MultiImplementationA.cs:36:14:36:28 | {...} | MultiImplementationA.cs:36:14:36:28 | {...} | | MultiImplementationA.cs:37:9:37:10 | enter M2 | MultiImplementationA.cs:37:9:37:10 | enter M2 | | MultiImplementationB.cs:1:7:1:8 | call to constructor Object | MultiImplementationB.cs:1:7:1:8 | call to constructor Object | -| MultiImplementationB.cs:1:7:1:8 | enter C1 | MultiImplementationA.cs:4:7:4:8 | enter C1 | -| MultiImplementationB.cs:1:7:1:8 | enter C1 | MultiImplementationB.cs:1:7:1:8 | enter C1 | -| MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | MultiImplementationA.cs:4:7:4:8 | call to constructor Object | -| MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | MultiImplementationA.cs:4:7:4:8 | enter C1 | -| MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | -| MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | MultiImplementationB.cs:1:7:1:8 | call to constructor Object | -| MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | MultiImplementationB.cs:1:7:1:8 | enter C1 | -| MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | | MultiImplementationB.cs:3:22:3:22 | 0 | MultiImplementationA.cs:6:22:6:31 | enter get_P1 | | MultiImplementationB.cs:3:22:3:22 | 0 | MultiImplementationB.cs:3:22:3:22 | 0 | -| MultiImplementationB.cs:3:22:3:22 | 0 | MultiImplementationB.cs:3:22:3:22 | enter get_P1 | -| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationA.cs:6:22:6:31 | enter get_P1 | -| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | enter get_P1 | -| MultiImplementationB.cs:3:22:3:22 | exit get_P1 | MultiImplementationA.cs:6:22:6:31 | exit get_P1 | -| MultiImplementationB.cs:3:22:3:22 | exit get_P1 | MultiImplementationB.cs:3:22:3:22 | exit get_P1 | -| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationA.cs:7:21:7:23 | enter get_P2 | -| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationB.cs:4:21:4:23 | enter get_P2 | -| MultiImplementationB.cs:4:21:4:23 | exit get_P2 | MultiImplementationA.cs:7:21:7:23 | exit get_P2 | -| MultiImplementationB.cs:4:21:4:23 | exit get_P2 | MultiImplementationB.cs:4:21:4:23 | exit get_P2 | | MultiImplementationB.cs:4:25:4:37 | {...} | MultiImplementationA.cs:7:21:7:23 | enter get_P2 | -| MultiImplementationB.cs:4:25:4:37 | {...} | MultiImplementationB.cs:4:21:4:23 | enter get_P2 | | MultiImplementationB.cs:4:25:4:37 | {...} | MultiImplementationB.cs:4:25:4:37 | {...} | -| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationA.cs:7:41:7:43 | enter set_P2 | -| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationB.cs:4:39:4:41 | enter set_P2 | -| MultiImplementationB.cs:4:39:4:41 | exit set_P2 | MultiImplementationA.cs:7:41:7:43 | exit set_P2 | -| MultiImplementationB.cs:4:39:4:41 | exit set_P2 | MultiImplementationB.cs:4:39:4:41 | exit set_P2 | | MultiImplementationB.cs:4:43:4:45 | {...} | MultiImplementationA.cs:7:41:7:43 | enter set_P2 | -| MultiImplementationB.cs:4:43:4:45 | {...} | MultiImplementationB.cs:4:39:4:41 | enter set_P2 | | MultiImplementationB.cs:4:43:4:45 | {...} | MultiImplementationB.cs:4:43:4:45 | {...} | -| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationA.cs:8:16:8:16 | enter M | -| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationB.cs:5:16:5:16 | enter M | -| MultiImplementationB.cs:5:16:5:16 | exit M | MultiImplementationA.cs:8:16:8:16 | exit M | -| MultiImplementationB.cs:5:16:5:16 | exit M | MultiImplementationB.cs:5:16:5:16 | exit M | | MultiImplementationB.cs:5:23:5:23 | 2 | MultiImplementationA.cs:8:16:8:16 | enter M | -| MultiImplementationB.cs:5:23:5:23 | 2 | MultiImplementationB.cs:5:16:5:16 | enter M | | MultiImplementationB.cs:5:23:5:23 | 2 | MultiImplementationB.cs:5:23:5:23 | 2 | -| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | enter get_Item | -| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationB.cs:12:31:12:40 | enter get_Item | -| MultiImplementationB.cs:12:31:12:40 | exit get_Item | MultiImplementationA.cs:14:31:14:31 | exit get_Item | -| MultiImplementationB.cs:12:31:12:40 | exit get_Item | MultiImplementationB.cs:12:31:12:40 | exit get_Item | | MultiImplementationB.cs:12:37:12:40 | null | MultiImplementationB.cs:12:37:12:40 | null | -| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationA.cs:15:36:15:38 | enter get_Item | -| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationB.cs:13:36:13:38 | enter get_Item | -| MultiImplementationB.cs:13:36:13:38 | exit get_Item | MultiImplementationA.cs:15:36:15:38 | exit get_Item | -| MultiImplementationB.cs:13:36:13:38 | exit get_Item | MultiImplementationB.cs:13:36:13:38 | exit get_Item | | MultiImplementationB.cs:13:40:13:54 | {...} | MultiImplementationB.cs:13:40:13:54 | {...} | -| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationA.cs:15:54:15:56 | enter set_Item | -| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationB.cs:13:56:13:58 | enter set_Item | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | MultiImplementationA.cs:15:54:15:56 | enter set_Item | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | MultiImplementationA.cs:15:58:15:60 | {...} | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | MultiImplementationB.cs:13:56:13:58 | enter set_Item | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | MultiImplementationB.cs:13:60:13:62 | {...} | | MultiImplementationB.cs:13:60:13:62 | {...} | MultiImplementationB.cs:13:60:13:62 | {...} | -| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationA.cs:16:17:16:18 | enter M1 | -| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationB.cs:14:17:14:18 | enter M1 | -| MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | MultiImplementationA.cs:16:17:16:18 | enter M1 | -| MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | -| MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | MultiImplementationA.cs:17:5:19:5 | {...} | -| MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | MultiImplementationB.cs:14:17:14:18 | enter M1 | -| MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | -| MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | MultiImplementationB.cs:15:5:17:5 | {...} | | MultiImplementationB.cs:15:5:17:5 | {...} | MultiImplementationB.cs:15:5:17:5 | {...} | | MultiImplementationB.cs:16:9:16:31 | enter M2 | MultiImplementationB.cs:16:9:16:31 | enter M2 | | MultiImplementationB.cs:18:12:18:13 | call to constructor Object | MultiImplementationB.cs:18:12:18:13 | call to constructor Object | -| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | enter C2 | -| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | enter C2 | -| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationA.cs:20:12:20:13 | exit C2 | -| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationB.cs:18:12:18:13 | exit C2 | -| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationA.cs:21:12:21:13 | enter C2 | -| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationB.cs:19:12:19:13 | enter C2 | -| MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | MultiImplementationA.cs:21:12:21:13 | enter C2 | -| MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | -| MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | MultiImplementationA.cs:21:24:21:24 | 0 | -| MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | MultiImplementationB.cs:19:12:19:13 | enter C2 | -| MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | -| MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | MultiImplementationB.cs:19:24:19:24 | 1 | | MultiImplementationB.cs:19:24:19:24 | 1 | MultiImplementationB.cs:19:24:19:24 | 1 | -| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationA.cs:22:6:22:7 | enter ~C2 | -| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationB.cs:20:6:20:7 | enter ~C2 | -| MultiImplementationB.cs:20:6:20:7 | exit ~C2 | MultiImplementationA.cs:22:6:22:7 | exit ~C2 | -| MultiImplementationB.cs:20:6:20:7 | exit ~C2 | MultiImplementationB.cs:20:6:20:7 | exit ~C2 | | MultiImplementationB.cs:20:11:20:25 | {...} | MultiImplementationB.cs:20:11:20:25 | {...} | -| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | -| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | -| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | -| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | | MultiImplementationB.cs:21:56:21:59 | null | MultiImplementationB.cs:21:56:21:59 | null | | MultiImplementationB.cs:25:7:25:8 | call to constructor Object | MultiImplementationB.cs:25:7:25:8 | call to constructor Object | -| MultiImplementationB.cs:25:7:25:8 | enter C3 | MultiImplementationA.cs:28:7:28:8 | enter C3 | -| MultiImplementationB.cs:25:7:25:8 | enter C3 | MultiImplementationB.cs:25:7:25:8 | enter C3 | -| MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | MultiImplementationA.cs:28:7:28:8 | call to constructor Object | -| MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | MultiImplementationA.cs:28:7:28:8 | enter C3 | -| MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | -| MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | MultiImplementationB.cs:25:7:25:8 | call to constructor Object | -| MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | MultiImplementationB.cs:25:7:25:8 | enter C3 | -| MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | -| MultiImplementationB.cs:27:21:27:23 | enter get_P3 | MultiImplementationA.cs:30:21:30:23 | enter get_P3 | -| MultiImplementationB.cs:27:21:27:23 | enter get_P3 | MultiImplementationB.cs:27:21:27:23 | enter get_P3 | | MultiImplementationB.cs:30:15:30:16 | call to constructor Object | MultiImplementationB.cs:30:15:30:16 | call to constructor Object | -| MultiImplementationB.cs:30:15:30:16 | enter C4 | MultiImplementationA.cs:34:15:34:16 | enter C4 | -| MultiImplementationB.cs:30:15:30:16 | enter C4 | MultiImplementationB.cs:30:15:30:16 | enter C4 | -| MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | MultiImplementationA.cs:34:15:34:16 | call to constructor Object | -| MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | MultiImplementationA.cs:34:15:34:16 | enter C4 | -| MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | -| MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | MultiImplementationB.cs:30:15:30:16 | call to constructor Object | -| MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | MultiImplementationB.cs:30:15:30:16 | enter C4 | -| MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | -| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationA.cs:36:9:36:10 | enter M1 | -| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationB.cs:32:9:32:10 | enter M1 | -| MultiImplementationB.cs:32:9:32:10 | exit M1 | MultiImplementationA.cs:36:9:36:10 | exit M1 | -| MultiImplementationB.cs:32:9:32:10 | exit M1 | MultiImplementationB.cs:32:9:32:10 | exit M1 | | MultiImplementationB.cs:32:17:32:17 | 0 | MultiImplementationA.cs:36:9:36:10 | enter M1 | -| MultiImplementationB.cs:32:17:32:17 | 0 | MultiImplementationB.cs:32:9:32:10 | enter M1 | | MultiImplementationB.cs:32:17:32:17 | 0 | MultiImplementationB.cs:32:17:32:17 | 0 | | NullCoalescing.cs:1:7:1:20 | enter NullCoalescing | NullCoalescing.cs:1:7:1:20 | enter NullCoalescing | | NullCoalescing.cs:3:9:3:10 | enter M1 | NullCoalescing.cs:3:9:3:10 | enter M1 | diff --git a/csharp/ql/test/library-tests/controlflow/graph/EnclosingCallable.expected b/csharp/ql/test/library-tests/controlflow/graph/EnclosingCallable.expected index fb983a081ae3..9edc62925d86 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/EnclosingCallable.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/EnclosingCallable.expected @@ -3157,223 +3157,116 @@ nodeEnclosing | LoopUnrolling.cs:99:13:99:33 | ...; | LoopUnrolling.cs:94:10:94:12 | M11 | | LoopUnrolling.cs:99:31:99:31 | access to local variable x | LoopUnrolling.cs:94:10:94:12 | M11 | | MultiImplementationA.cs:4:7:4:8 | call to constructor Object | MultiImplementationA.cs:4:7:4:8 | C1 | -| MultiImplementationA.cs:4:7:4:8 | call to constructor Object | MultiImplementationB.cs:1:7:1:8 | C1 | | MultiImplementationA.cs:4:7:4:8 | enter C1 | MultiImplementationA.cs:4:7:4:8 | C1 | -| MultiImplementationA.cs:4:7:4:8 | enter C1 | MultiImplementationB.cs:1:7:1:8 | C1 | | MultiImplementationA.cs:4:7:4:8 | exit C1 | MultiImplementationA.cs:4:7:4:8 | C1 | -| MultiImplementationA.cs:4:7:4:8 | exit C1 | MultiImplementationB.cs:1:7:1:8 | C1 | | MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | MultiImplementationA.cs:4:7:4:8 | C1 | -| MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | MultiImplementationB.cs:1:7:1:8 | C1 | | MultiImplementationA.cs:4:7:4:8 | {...} | MultiImplementationA.cs:4:7:4:8 | C1 | -| MultiImplementationA.cs:4:7:4:8 | {...} | MultiImplementationB.cs:1:7:1:8 | C1 | | MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationA.cs:6:22:6:31 | get_P1 | -| MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | get_P1 | | MultiImplementationA.cs:6:22:6:31 | exit get_P1 | MultiImplementationA.cs:6:22:6:31 | get_P1 | -| MultiImplementationA.cs:6:22:6:31 | exit get_P1 | MultiImplementationB.cs:3:22:3:22 | get_P1 | | MultiImplementationA.cs:6:22:6:31 | exit get_P1 (abnormal) | MultiImplementationA.cs:6:22:6:31 | get_P1 | -| MultiImplementationA.cs:6:22:6:31 | exit get_P1 (abnormal) | MultiImplementationB.cs:3:22:3:22 | get_P1 | | MultiImplementationA.cs:6:22:6:31 | exit get_P1 (normal) | MultiImplementationA.cs:6:22:6:31 | get_P1 | -| MultiImplementationA.cs:6:22:6:31 | exit get_P1 (normal) | MultiImplementationB.cs:3:22:3:22 | get_P1 | | MultiImplementationA.cs:6:22:6:31 | throw ... | MultiImplementationA.cs:6:22:6:31 | get_P1 | -| MultiImplementationA.cs:6:22:6:31 | throw ... | MultiImplementationB.cs:3:22:3:22 | get_P1 | | MultiImplementationA.cs:6:28:6:31 | null | MultiImplementationA.cs:6:22:6:31 | get_P1 | -| MultiImplementationA.cs:6:28:6:31 | null | MultiImplementationB.cs:3:22:3:22 | get_P1 | | MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationA.cs:7:21:7:23 | get_P2 | -| MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationB.cs:4:21:4:23 | get_P2 | | MultiImplementationA.cs:7:21:7:23 | exit get_P2 | MultiImplementationA.cs:7:21:7:23 | get_P2 | -| MultiImplementationA.cs:7:21:7:23 | exit get_P2 | MultiImplementationB.cs:4:21:4:23 | get_P2 | | MultiImplementationA.cs:7:21:7:23 | exit get_P2 (abnormal) | MultiImplementationA.cs:7:21:7:23 | get_P2 | -| MultiImplementationA.cs:7:21:7:23 | exit get_P2 (abnormal) | MultiImplementationB.cs:4:21:4:23 | get_P2 | | MultiImplementationA.cs:7:21:7:23 | exit get_P2 (normal) | MultiImplementationA.cs:7:21:7:23 | get_P2 | -| MultiImplementationA.cs:7:21:7:23 | exit get_P2 (normal) | MultiImplementationB.cs:4:21:4:23 | get_P2 | | MultiImplementationA.cs:7:25:7:39 | {...} | MultiImplementationA.cs:7:21:7:23 | get_P2 | -| MultiImplementationA.cs:7:25:7:39 | {...} | MultiImplementationB.cs:4:21:4:23 | get_P2 | | MultiImplementationA.cs:7:27:7:37 | throw ...; | MultiImplementationA.cs:7:21:7:23 | get_P2 | -| MultiImplementationA.cs:7:27:7:37 | throw ...; | MultiImplementationB.cs:4:21:4:23 | get_P2 | | MultiImplementationA.cs:7:33:7:36 | null | MultiImplementationA.cs:7:21:7:23 | get_P2 | -| MultiImplementationA.cs:7:33:7:36 | null | MultiImplementationB.cs:4:21:4:23 | get_P2 | | MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationA.cs:7:41:7:43 | set_P2 | -| MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationB.cs:4:39:4:41 | set_P2 | | MultiImplementationA.cs:7:41:7:43 | exit set_P2 | MultiImplementationA.cs:7:41:7:43 | set_P2 | -| MultiImplementationA.cs:7:41:7:43 | exit set_P2 | MultiImplementationB.cs:4:39:4:41 | set_P2 | | MultiImplementationA.cs:7:41:7:43 | exit set_P2 (abnormal) | MultiImplementationA.cs:7:41:7:43 | set_P2 | -| MultiImplementationA.cs:7:41:7:43 | exit set_P2 (abnormal) | MultiImplementationB.cs:4:39:4:41 | set_P2 | | MultiImplementationA.cs:7:41:7:43 | exit set_P2 (normal) | MultiImplementationA.cs:7:41:7:43 | set_P2 | -| MultiImplementationA.cs:7:41:7:43 | exit set_P2 (normal) | MultiImplementationB.cs:4:39:4:41 | set_P2 | | MultiImplementationA.cs:7:45:7:59 | {...} | MultiImplementationA.cs:7:41:7:43 | set_P2 | -| MultiImplementationA.cs:7:45:7:59 | {...} | MultiImplementationB.cs:4:39:4:41 | set_P2 | | MultiImplementationA.cs:7:47:7:57 | throw ...; | MultiImplementationA.cs:7:41:7:43 | set_P2 | -| MultiImplementationA.cs:7:47:7:57 | throw ...; | MultiImplementationB.cs:4:39:4:41 | set_P2 | | MultiImplementationA.cs:7:53:7:56 | null | MultiImplementationA.cs:7:41:7:43 | set_P2 | -| MultiImplementationA.cs:7:53:7:56 | null | MultiImplementationB.cs:4:39:4:41 | set_P2 | | MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationA.cs:8:16:8:16 | M | -| MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationB.cs:5:16:5:16 | M | | MultiImplementationA.cs:8:16:8:16 | exit M | MultiImplementationA.cs:8:16:8:16 | M | -| MultiImplementationA.cs:8:16:8:16 | exit M | MultiImplementationB.cs:5:16:5:16 | M | | MultiImplementationA.cs:8:16:8:16 | exit M (abnormal) | MultiImplementationA.cs:8:16:8:16 | M | -| MultiImplementationA.cs:8:16:8:16 | exit M (abnormal) | MultiImplementationB.cs:5:16:5:16 | M | | MultiImplementationA.cs:8:16:8:16 | exit M (normal) | MultiImplementationA.cs:8:16:8:16 | M | -| MultiImplementationA.cs:8:16:8:16 | exit M (normal) | MultiImplementationB.cs:5:16:5:16 | M | | MultiImplementationA.cs:8:23:8:32 | throw ... | MultiImplementationA.cs:8:16:8:16 | M | -| MultiImplementationA.cs:8:23:8:32 | throw ... | MultiImplementationB.cs:5:16:5:16 | M | | MultiImplementationA.cs:8:29:8:32 | null | MultiImplementationA.cs:8:16:8:16 | M | -| MultiImplementationA.cs:8:29:8:32 | null | MultiImplementationB.cs:5:16:5:16 | M | | MultiImplementationA.cs:13:16:13:16 | this access | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationA.cs:13:16:13:16 | this access | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationA.cs:13:16:13:20 | ... = ... | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationA.cs:13:16:13:20 | ... = ... | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationA.cs:13:20:13:20 | 0 | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationA.cs:13:20:13:20 | 0 | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationA.cs:14:31:14:31 | access to parameter i | MultiImplementationA.cs:14:31:14:31 | get_Item | -| MultiImplementationA.cs:14:31:14:31 | access to parameter i | MultiImplementationB.cs:12:31:12:40 | get_Item | | MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | get_Item | -| MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationB.cs:12:31:12:40 | get_Item | | MultiImplementationA.cs:14:31:14:31 | exit get_Item | MultiImplementationA.cs:14:31:14:31 | get_Item | -| MultiImplementationA.cs:14:31:14:31 | exit get_Item | MultiImplementationB.cs:12:31:12:40 | get_Item | | MultiImplementationA.cs:14:31:14:31 | exit get_Item (abnormal) | MultiImplementationA.cs:14:31:14:31 | get_Item | -| MultiImplementationA.cs:14:31:14:31 | exit get_Item (abnormal) | MultiImplementationB.cs:12:31:12:40 | get_Item | | MultiImplementationA.cs:14:31:14:31 | exit get_Item (normal) | MultiImplementationA.cs:14:31:14:31 | get_Item | -| MultiImplementationA.cs:14:31:14:31 | exit get_Item (normal) | MultiImplementationB.cs:12:31:12:40 | get_Item | | MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationA.cs:15:36:15:38 | get_Item | -| MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationB.cs:13:36:13:38 | get_Item | | MultiImplementationA.cs:15:36:15:38 | exit get_Item | MultiImplementationA.cs:15:36:15:38 | get_Item | -| MultiImplementationA.cs:15:36:15:38 | exit get_Item | MultiImplementationB.cs:13:36:13:38 | get_Item | | MultiImplementationA.cs:15:36:15:38 | exit get_Item (abnormal) | MultiImplementationA.cs:15:36:15:38 | get_Item | -| MultiImplementationA.cs:15:36:15:38 | exit get_Item (abnormal) | MultiImplementationB.cs:13:36:13:38 | get_Item | | MultiImplementationA.cs:15:36:15:38 | exit get_Item (normal) | MultiImplementationA.cs:15:36:15:38 | get_Item | -| MultiImplementationA.cs:15:36:15:38 | exit get_Item (normal) | MultiImplementationB.cs:13:36:13:38 | get_Item | | MultiImplementationA.cs:15:40:15:52 | {...} | MultiImplementationA.cs:15:36:15:38 | get_Item | -| MultiImplementationA.cs:15:40:15:52 | {...} | MultiImplementationB.cs:13:36:13:38 | get_Item | | MultiImplementationA.cs:15:42:15:50 | return ...; | MultiImplementationA.cs:15:36:15:38 | get_Item | -| MultiImplementationA.cs:15:42:15:50 | return ...; | MultiImplementationB.cs:13:36:13:38 | get_Item | | MultiImplementationA.cs:15:49:15:49 | access to parameter s | MultiImplementationA.cs:15:36:15:38 | get_Item | -| MultiImplementationA.cs:15:49:15:49 | access to parameter s | MultiImplementationB.cs:13:36:13:38 | get_Item | | MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationA.cs:15:54:15:56 | set_Item | -| MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationB.cs:13:56:13:58 | set_Item | | MultiImplementationA.cs:15:54:15:56 | exit set_Item | MultiImplementationA.cs:15:54:15:56 | set_Item | -| MultiImplementationA.cs:15:54:15:56 | exit set_Item | MultiImplementationB.cs:13:56:13:58 | set_Item | | MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | MultiImplementationA.cs:15:54:15:56 | set_Item | -| MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | MultiImplementationB.cs:13:56:13:58 | set_Item | | MultiImplementationA.cs:15:58:15:60 | {...} | MultiImplementationA.cs:15:54:15:56 | set_Item | -| MultiImplementationA.cs:15:58:15:60 | {...} | MultiImplementationB.cs:13:56:13:58 | set_Item | | MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationA.cs:16:17:16:18 | M1 | -| MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationB.cs:14:17:14:18 | M1 | | MultiImplementationA.cs:16:17:16:18 | exit M1 | MultiImplementationA.cs:16:17:16:18 | M1 | -| MultiImplementationA.cs:16:17:16:18 | exit M1 | MultiImplementationB.cs:14:17:14:18 | M1 | | MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | MultiImplementationA.cs:16:17:16:18 | M1 | -| MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | MultiImplementationB.cs:14:17:14:18 | M1 | | MultiImplementationA.cs:17:5:19:5 | {...} | MultiImplementationA.cs:16:17:16:18 | M1 | -| MultiImplementationA.cs:17:5:19:5 | {...} | MultiImplementationB.cs:14:17:14:18 | M1 | | MultiImplementationA.cs:18:9:18:22 | M2(...) | MultiImplementationA.cs:16:17:16:18 | M1 | -| MultiImplementationA.cs:18:9:18:22 | M2(...) | MultiImplementationB.cs:14:17:14:18 | M1 | | MultiImplementationA.cs:18:9:18:22 | enter M2 | MultiImplementationA.cs:18:9:18:22 | M2 | | MultiImplementationA.cs:18:9:18:22 | exit M2 | MultiImplementationA.cs:18:9:18:22 | M2 | | MultiImplementationA.cs:18:9:18:22 | exit M2 (normal) | MultiImplementationA.cs:18:9:18:22 | M2 | | MultiImplementationA.cs:18:21:18:21 | 0 | MultiImplementationA.cs:18:9:18:22 | M2 | | MultiImplementationA.cs:20:12:20:13 | call to constructor Object | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationA.cs:20:12:20:13 | call to constructor Object | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationA.cs:20:12:20:13 | exit C2 (abnormal) | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationA.cs:20:12:20:13 | exit C2 (abnormal) | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationA.cs:20:12:20:13 | exit C2 (normal) | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationA.cs:20:12:20:13 | exit C2 (normal) | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationA.cs:20:22:20:31 | {...} | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationA.cs:20:22:20:31 | {...} | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationA.cs:20:24:20:24 | this access | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationA.cs:20:24:20:24 | this access | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationA.cs:20:24:20:28 | ... = ... | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationA.cs:20:24:20:28 | ... = ... | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationA.cs:20:24:20:29 | ...; | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationA.cs:20:24:20:29 | ...; | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationA.cs:20:28:20:28 | access to parameter i | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationA.cs:20:28:20:28 | access to parameter i | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationA.cs:21:12:21:13 | C2 | -| MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationB.cs:19:12:19:13 | C2 | | MultiImplementationA.cs:21:12:21:13 | exit C2 | MultiImplementationA.cs:21:12:21:13 | C2 | -| MultiImplementationA.cs:21:12:21:13 | exit C2 | MultiImplementationB.cs:19:12:19:13 | C2 | | MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | MultiImplementationA.cs:21:12:21:13 | C2 | -| MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | MultiImplementationB.cs:19:12:19:13 | C2 | | MultiImplementationA.cs:21:19:21:22 | call to constructor C2 | MultiImplementationA.cs:21:12:21:13 | C2 | -| MultiImplementationA.cs:21:19:21:22 | call to constructor C2 | MultiImplementationB.cs:19:12:19:13 | C2 | | MultiImplementationA.cs:21:24:21:24 | 0 | MultiImplementationA.cs:21:12:21:13 | C2 | -| MultiImplementationA.cs:21:24:21:24 | 0 | MultiImplementationB.cs:19:12:19:13 | C2 | | MultiImplementationA.cs:21:27:21:29 | {...} | MultiImplementationA.cs:21:12:21:13 | C2 | -| MultiImplementationA.cs:21:27:21:29 | {...} | MultiImplementationB.cs:19:12:19:13 | C2 | | MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationA.cs:22:6:22:7 | ~C2 | -| MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationB.cs:20:6:20:7 | ~C2 | | MultiImplementationA.cs:22:6:22:7 | exit ~C2 | MultiImplementationA.cs:22:6:22:7 | ~C2 | -| MultiImplementationA.cs:22:6:22:7 | exit ~C2 | MultiImplementationB.cs:20:6:20:7 | ~C2 | | MultiImplementationA.cs:22:6:22:7 | exit ~C2 (abnormal) | MultiImplementationA.cs:22:6:22:7 | ~C2 | -| MultiImplementationA.cs:22:6:22:7 | exit ~C2 (abnormal) | MultiImplementationB.cs:20:6:20:7 | ~C2 | | MultiImplementationA.cs:22:6:22:7 | exit ~C2 (normal) | MultiImplementationA.cs:22:6:22:7 | ~C2 | -| MultiImplementationA.cs:22:6:22:7 | exit ~C2 (normal) | MultiImplementationB.cs:20:6:20:7 | ~C2 | | MultiImplementationA.cs:22:11:22:13 | {...} | MultiImplementationA.cs:22:6:22:7 | ~C2 | -| MultiImplementationA.cs:22:11:22:13 | {...} | MultiImplementationB.cs:20:6:20:7 | ~C2 | | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationA.cs:23:28:23:35 | implicit conversion | -| MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationB.cs:21:28:21:35 | implicit conversion | | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | MultiImplementationA.cs:23:28:23:35 | implicit conversion | -| MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | MultiImplementationB.cs:21:28:21:35 | implicit conversion | | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion (abnormal) | MultiImplementationA.cs:23:28:23:35 | implicit conversion | -| MultiImplementationA.cs:23:28:23:35 | exit implicit conversion (abnormal) | MultiImplementationB.cs:21:28:21:35 | implicit conversion | | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion (normal) | MultiImplementationA.cs:23:28:23:35 | implicit conversion | -| MultiImplementationA.cs:23:28:23:35 | exit implicit conversion (normal) | MultiImplementationB.cs:21:28:21:35 | implicit conversion | | MultiImplementationA.cs:23:50:23:53 | null | MultiImplementationA.cs:23:28:23:35 | implicit conversion | -| MultiImplementationA.cs:23:50:23:53 | null | MultiImplementationB.cs:21:28:21:35 | implicit conversion | | MultiImplementationA.cs:24:16:24:16 | access to property P | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationA.cs:24:16:24:16 | access to property P | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationA.cs:24:16:24:16 | this access | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationA.cs:24:16:24:16 | this access | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationA.cs:24:32:24:34 | ... = ... | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationA.cs:24:32:24:34 | ... = ... | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationA.cs:24:34:24:34 | 0 | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationA.cs:24:34:24:34 | 0 | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationA.cs:28:7:28:8 | call to constructor Object | MultiImplementationA.cs:28:7:28:8 | C3 | -| MultiImplementationA.cs:28:7:28:8 | call to constructor Object | MultiImplementationB.cs:25:7:25:8 | C3 | | MultiImplementationA.cs:28:7:28:8 | enter C3 | MultiImplementationA.cs:28:7:28:8 | C3 | -| MultiImplementationA.cs:28:7:28:8 | enter C3 | MultiImplementationB.cs:25:7:25:8 | C3 | | MultiImplementationA.cs:28:7:28:8 | exit C3 | MultiImplementationA.cs:28:7:28:8 | C3 | -| MultiImplementationA.cs:28:7:28:8 | exit C3 | MultiImplementationB.cs:25:7:25:8 | C3 | | MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | MultiImplementationA.cs:28:7:28:8 | C3 | -| MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | MultiImplementationB.cs:25:7:25:8 | C3 | | MultiImplementationA.cs:28:7:28:8 | {...} | MultiImplementationA.cs:28:7:28:8 | C3 | -| MultiImplementationA.cs:28:7:28:8 | {...} | MultiImplementationB.cs:25:7:25:8 | C3 | | MultiImplementationA.cs:30:21:30:23 | enter get_P3 | MultiImplementationA.cs:30:21:30:23 | get_P3 | -| MultiImplementationA.cs:30:21:30:23 | enter get_P3 | MultiImplementationB.cs:27:21:27:23 | get_P3 | | MultiImplementationA.cs:30:21:30:23 | exit get_P3 | MultiImplementationA.cs:30:21:30:23 | get_P3 | -| MultiImplementationA.cs:30:21:30:23 | exit get_P3 | MultiImplementationB.cs:27:21:27:23 | get_P3 | | MultiImplementationA.cs:30:21:30:23 | exit get_P3 (abnormal) | MultiImplementationA.cs:30:21:30:23 | get_P3 | -| MultiImplementationA.cs:30:21:30:23 | exit get_P3 (abnormal) | MultiImplementationB.cs:27:21:27:23 | get_P3 | | MultiImplementationA.cs:30:28:30:37 | throw ... | MultiImplementationA.cs:30:21:30:23 | get_P3 | -| MultiImplementationA.cs:30:28:30:37 | throw ... | MultiImplementationB.cs:27:21:27:23 | get_P3 | | MultiImplementationA.cs:30:34:30:37 | null | MultiImplementationA.cs:30:21:30:23 | get_P3 | -| MultiImplementationA.cs:30:34:30:37 | null | MultiImplementationB.cs:27:21:27:23 | get_P3 | | MultiImplementationA.cs:34:15:34:16 | call to constructor Object | MultiImplementationA.cs:34:15:34:16 | C4 | -| MultiImplementationA.cs:34:15:34:16 | call to constructor Object | MultiImplementationB.cs:30:15:30:16 | C4 | | MultiImplementationA.cs:34:15:34:16 | enter C4 | MultiImplementationA.cs:34:15:34:16 | C4 | -| MultiImplementationA.cs:34:15:34:16 | enter C4 | MultiImplementationB.cs:30:15:30:16 | C4 | | MultiImplementationA.cs:34:15:34:16 | exit C4 | MultiImplementationA.cs:34:15:34:16 | C4 | -| MultiImplementationA.cs:34:15:34:16 | exit C4 | MultiImplementationB.cs:30:15:30:16 | C4 | | MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | MultiImplementationA.cs:34:15:34:16 | C4 | -| MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | MultiImplementationB.cs:30:15:30:16 | C4 | | MultiImplementationA.cs:34:15:34:16 | {...} | MultiImplementationA.cs:34:15:34:16 | C4 | -| MultiImplementationA.cs:34:15:34:16 | {...} | MultiImplementationB.cs:30:15:30:16 | C4 | | MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationA.cs:36:9:36:10 | M1 | -| MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationB.cs:32:9:32:10 | M1 | | MultiImplementationA.cs:36:9:36:10 | exit M1 | MultiImplementationA.cs:36:9:36:10 | M1 | -| MultiImplementationA.cs:36:9:36:10 | exit M1 | MultiImplementationB.cs:32:9:32:10 | M1 | | MultiImplementationA.cs:36:9:36:10 | exit M1 (abnormal) | MultiImplementationA.cs:36:9:36:10 | M1 | -| MultiImplementationA.cs:36:9:36:10 | exit M1 (abnormal) | MultiImplementationB.cs:32:9:32:10 | M1 | | MultiImplementationA.cs:36:9:36:10 | exit M1 (normal) | MultiImplementationA.cs:36:9:36:10 | M1 | -| MultiImplementationA.cs:36:9:36:10 | exit M1 (normal) | MultiImplementationB.cs:32:9:32:10 | M1 | | MultiImplementationA.cs:36:14:36:28 | {...} | MultiImplementationA.cs:36:9:36:10 | M1 | -| MultiImplementationA.cs:36:14:36:28 | {...} | MultiImplementationB.cs:32:9:32:10 | M1 | | MultiImplementationA.cs:36:16:36:26 | throw ...; | MultiImplementationA.cs:36:9:36:10 | M1 | -| MultiImplementationA.cs:36:16:36:26 | throw ...; | MultiImplementationB.cs:32:9:32:10 | M1 | | MultiImplementationA.cs:36:22:36:25 | null | MultiImplementationA.cs:36:9:36:10 | M1 | -| MultiImplementationA.cs:36:22:36:25 | null | MultiImplementationB.cs:32:9:32:10 | M1 | | MultiImplementationA.cs:37:9:37:10 | enter M2 | MultiImplementationA.cs:37:9:37:10 | M2 | | MultiImplementationA.cs:37:9:37:10 | exit M2 | MultiImplementationA.cs:37:9:37:10 | M2 | | MultiImplementationA.cs:37:9:37:10 | exit M2 (abnormal) | MultiImplementationA.cs:37:9:37:10 | M2 | @@ -3381,212 +3274,50 @@ nodeEnclosing | MultiImplementationA.cs:37:16:37:26 | throw ...; | MultiImplementationA.cs:37:9:37:10 | M2 | | MultiImplementationA.cs:37:22:37:25 | null | MultiImplementationA.cs:37:9:37:10 | M2 | | MultiImplementationB.cs:1:7:1:8 | call to constructor Object | MultiImplementationA.cs:4:7:4:8 | C1 | -| MultiImplementationB.cs:1:7:1:8 | call to constructor Object | MultiImplementationB.cs:1:7:1:8 | C1 | -| MultiImplementationB.cs:1:7:1:8 | enter C1 | MultiImplementationA.cs:4:7:4:8 | C1 | -| MultiImplementationB.cs:1:7:1:8 | enter C1 | MultiImplementationB.cs:1:7:1:8 | C1 | -| MultiImplementationB.cs:1:7:1:8 | exit C1 | MultiImplementationA.cs:4:7:4:8 | C1 | -| MultiImplementationB.cs:1:7:1:8 | exit C1 | MultiImplementationB.cs:1:7:1:8 | C1 | -| MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | MultiImplementationA.cs:4:7:4:8 | C1 | -| MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | MultiImplementationB.cs:1:7:1:8 | C1 | | MultiImplementationB.cs:1:7:1:8 | {...} | MultiImplementationA.cs:4:7:4:8 | C1 | -| MultiImplementationB.cs:1:7:1:8 | {...} | MultiImplementationB.cs:1:7:1:8 | C1 | | MultiImplementationB.cs:3:22:3:22 | 0 | MultiImplementationA.cs:6:22:6:31 | get_P1 | -| MultiImplementationB.cs:3:22:3:22 | 0 | MultiImplementationB.cs:3:22:3:22 | get_P1 | -| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationA.cs:6:22:6:31 | get_P1 | -| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | get_P1 | -| MultiImplementationB.cs:3:22:3:22 | exit get_P1 | MultiImplementationA.cs:6:22:6:31 | get_P1 | -| MultiImplementationB.cs:3:22:3:22 | exit get_P1 | MultiImplementationB.cs:3:22:3:22 | get_P1 | -| MultiImplementationB.cs:3:22:3:22 | exit get_P1 (abnormal) | MultiImplementationA.cs:6:22:6:31 | get_P1 | -| MultiImplementationB.cs:3:22:3:22 | exit get_P1 (abnormal) | MultiImplementationB.cs:3:22:3:22 | get_P1 | -| MultiImplementationB.cs:3:22:3:22 | exit get_P1 (normal) | MultiImplementationA.cs:6:22:6:31 | get_P1 | -| MultiImplementationB.cs:3:22:3:22 | exit get_P1 (normal) | MultiImplementationB.cs:3:22:3:22 | get_P1 | -| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationA.cs:7:21:7:23 | get_P2 | -| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationB.cs:4:21:4:23 | get_P2 | -| MultiImplementationB.cs:4:21:4:23 | exit get_P2 | MultiImplementationA.cs:7:21:7:23 | get_P2 | -| MultiImplementationB.cs:4:21:4:23 | exit get_P2 | MultiImplementationB.cs:4:21:4:23 | get_P2 | -| MultiImplementationB.cs:4:21:4:23 | exit get_P2 (abnormal) | MultiImplementationA.cs:7:21:7:23 | get_P2 | -| MultiImplementationB.cs:4:21:4:23 | exit get_P2 (abnormal) | MultiImplementationB.cs:4:21:4:23 | get_P2 | -| MultiImplementationB.cs:4:21:4:23 | exit get_P2 (normal) | MultiImplementationA.cs:7:21:7:23 | get_P2 | -| MultiImplementationB.cs:4:21:4:23 | exit get_P2 (normal) | MultiImplementationB.cs:4:21:4:23 | get_P2 | | MultiImplementationB.cs:4:25:4:37 | {...} | MultiImplementationA.cs:7:21:7:23 | get_P2 | -| MultiImplementationB.cs:4:25:4:37 | {...} | MultiImplementationB.cs:4:21:4:23 | get_P2 | | MultiImplementationB.cs:4:27:4:35 | return ...; | MultiImplementationA.cs:7:21:7:23 | get_P2 | -| MultiImplementationB.cs:4:27:4:35 | return ...; | MultiImplementationB.cs:4:21:4:23 | get_P2 | | MultiImplementationB.cs:4:34:4:34 | 1 | MultiImplementationA.cs:7:21:7:23 | get_P2 | -| MultiImplementationB.cs:4:34:4:34 | 1 | MultiImplementationB.cs:4:21:4:23 | get_P2 | -| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationA.cs:7:41:7:43 | set_P2 | -| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationB.cs:4:39:4:41 | set_P2 | -| MultiImplementationB.cs:4:39:4:41 | exit set_P2 | MultiImplementationA.cs:7:41:7:43 | set_P2 | -| MultiImplementationB.cs:4:39:4:41 | exit set_P2 | MultiImplementationB.cs:4:39:4:41 | set_P2 | -| MultiImplementationB.cs:4:39:4:41 | exit set_P2 (abnormal) | MultiImplementationA.cs:7:41:7:43 | set_P2 | -| MultiImplementationB.cs:4:39:4:41 | exit set_P2 (abnormal) | MultiImplementationB.cs:4:39:4:41 | set_P2 | -| MultiImplementationB.cs:4:39:4:41 | exit set_P2 (normal) | MultiImplementationA.cs:7:41:7:43 | set_P2 | -| MultiImplementationB.cs:4:39:4:41 | exit set_P2 (normal) | MultiImplementationB.cs:4:39:4:41 | set_P2 | | MultiImplementationB.cs:4:43:4:45 | {...} | MultiImplementationA.cs:7:41:7:43 | set_P2 | -| MultiImplementationB.cs:4:43:4:45 | {...} | MultiImplementationB.cs:4:39:4:41 | set_P2 | -| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationA.cs:8:16:8:16 | M | -| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationB.cs:5:16:5:16 | M | -| MultiImplementationB.cs:5:16:5:16 | exit M | MultiImplementationA.cs:8:16:8:16 | M | -| MultiImplementationB.cs:5:16:5:16 | exit M | MultiImplementationB.cs:5:16:5:16 | M | -| MultiImplementationB.cs:5:16:5:16 | exit M (abnormal) | MultiImplementationA.cs:8:16:8:16 | M | -| MultiImplementationB.cs:5:16:5:16 | exit M (abnormal) | MultiImplementationB.cs:5:16:5:16 | M | -| MultiImplementationB.cs:5:16:5:16 | exit M (normal) | MultiImplementationA.cs:8:16:8:16 | M | -| MultiImplementationB.cs:5:16:5:16 | exit M (normal) | MultiImplementationB.cs:5:16:5:16 | M | | MultiImplementationB.cs:5:23:5:23 | 2 | MultiImplementationA.cs:8:16:8:16 | M | -| MultiImplementationB.cs:5:23:5:23 | 2 | MultiImplementationB.cs:5:16:5:16 | M | | MultiImplementationB.cs:11:16:11:16 | this access | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationB.cs:11:16:11:16 | this access | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationB.cs:11:16:11:20 | ... = ... | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationB.cs:11:16:11:20 | ... = ... | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationB.cs:11:20:11:20 | 1 | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationB.cs:11:20:11:20 | 1 | MultiImplementationB.cs:18:12:18:13 | C2 | -| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | get_Item | -| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationB.cs:12:31:12:40 | get_Item | -| MultiImplementationB.cs:12:31:12:40 | exit get_Item | MultiImplementationA.cs:14:31:14:31 | get_Item | -| MultiImplementationB.cs:12:31:12:40 | exit get_Item | MultiImplementationB.cs:12:31:12:40 | get_Item | -| MultiImplementationB.cs:12:31:12:40 | exit get_Item (abnormal) | MultiImplementationA.cs:14:31:14:31 | get_Item | -| MultiImplementationB.cs:12:31:12:40 | exit get_Item (abnormal) | MultiImplementationB.cs:12:31:12:40 | get_Item | -| MultiImplementationB.cs:12:31:12:40 | exit get_Item (normal) | MultiImplementationA.cs:14:31:14:31 | get_Item | -| MultiImplementationB.cs:12:31:12:40 | exit get_Item (normal) | MultiImplementationB.cs:12:31:12:40 | get_Item | | MultiImplementationB.cs:12:31:12:40 | throw ... | MultiImplementationA.cs:14:31:14:31 | get_Item | -| MultiImplementationB.cs:12:31:12:40 | throw ... | MultiImplementationB.cs:12:31:12:40 | get_Item | | MultiImplementationB.cs:12:37:12:40 | null | MultiImplementationA.cs:14:31:14:31 | get_Item | -| MultiImplementationB.cs:12:37:12:40 | null | MultiImplementationB.cs:12:31:12:40 | get_Item | -| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationA.cs:15:36:15:38 | get_Item | -| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationB.cs:13:36:13:38 | get_Item | -| MultiImplementationB.cs:13:36:13:38 | exit get_Item | MultiImplementationA.cs:15:36:15:38 | get_Item | -| MultiImplementationB.cs:13:36:13:38 | exit get_Item | MultiImplementationB.cs:13:36:13:38 | get_Item | -| MultiImplementationB.cs:13:36:13:38 | exit get_Item (abnormal) | MultiImplementationA.cs:15:36:15:38 | get_Item | -| MultiImplementationB.cs:13:36:13:38 | exit get_Item (abnormal) | MultiImplementationB.cs:13:36:13:38 | get_Item | -| MultiImplementationB.cs:13:36:13:38 | exit get_Item (normal) | MultiImplementationA.cs:15:36:15:38 | get_Item | -| MultiImplementationB.cs:13:36:13:38 | exit get_Item (normal) | MultiImplementationB.cs:13:36:13:38 | get_Item | | MultiImplementationB.cs:13:40:13:54 | {...} | MultiImplementationA.cs:15:36:15:38 | get_Item | -| MultiImplementationB.cs:13:40:13:54 | {...} | MultiImplementationB.cs:13:36:13:38 | get_Item | | MultiImplementationB.cs:13:42:13:52 | throw ...; | MultiImplementationA.cs:15:36:15:38 | get_Item | -| MultiImplementationB.cs:13:42:13:52 | throw ...; | MultiImplementationB.cs:13:36:13:38 | get_Item | | MultiImplementationB.cs:13:48:13:51 | null | MultiImplementationA.cs:15:36:15:38 | get_Item | -| MultiImplementationB.cs:13:48:13:51 | null | MultiImplementationB.cs:13:36:13:38 | get_Item | -| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationA.cs:15:54:15:56 | set_Item | -| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationB.cs:13:56:13:58 | set_Item | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item | MultiImplementationA.cs:15:54:15:56 | set_Item | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item | MultiImplementationB.cs:13:56:13:58 | set_Item | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | MultiImplementationA.cs:15:54:15:56 | set_Item | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | MultiImplementationB.cs:13:56:13:58 | set_Item | | MultiImplementationB.cs:13:60:13:62 | {...} | MultiImplementationA.cs:15:54:15:56 | set_Item | -| MultiImplementationB.cs:13:60:13:62 | {...} | MultiImplementationB.cs:13:56:13:58 | set_Item | -| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationA.cs:16:17:16:18 | M1 | -| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationB.cs:14:17:14:18 | M1 | -| MultiImplementationB.cs:14:17:14:18 | exit M1 | MultiImplementationA.cs:16:17:16:18 | M1 | -| MultiImplementationB.cs:14:17:14:18 | exit M1 | MultiImplementationB.cs:14:17:14:18 | M1 | -| MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | MultiImplementationA.cs:16:17:16:18 | M1 | -| MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | MultiImplementationB.cs:14:17:14:18 | M1 | | MultiImplementationB.cs:15:5:17:5 | {...} | MultiImplementationA.cs:16:17:16:18 | M1 | -| MultiImplementationB.cs:15:5:17:5 | {...} | MultiImplementationB.cs:14:17:14:18 | M1 | | MultiImplementationB.cs:16:9:16:31 | M2(...) | MultiImplementationA.cs:16:17:16:18 | M1 | -| MultiImplementationB.cs:16:9:16:31 | M2(...) | MultiImplementationB.cs:14:17:14:18 | M1 | | MultiImplementationB.cs:16:9:16:31 | enter M2 | MultiImplementationB.cs:16:9:16:31 | M2 | | MultiImplementationB.cs:16:9:16:31 | exit M2 | MultiImplementationB.cs:16:9:16:31 | M2 | | MultiImplementationB.cs:16:9:16:31 | exit M2 (abnormal) | MultiImplementationB.cs:16:9:16:31 | M2 | | MultiImplementationB.cs:16:21:16:30 | throw ... | MultiImplementationB.cs:16:9:16:31 | M2 | | MultiImplementationB.cs:16:27:16:30 | null | MultiImplementationB.cs:16:9:16:31 | M2 | | MultiImplementationB.cs:18:12:18:13 | call to constructor Object | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationB.cs:18:12:18:13 | call to constructor Object | MultiImplementationB.cs:18:12:18:13 | C2 | -| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | C2 | -| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationB.cs:18:12:18:13 | C2 | -| MultiImplementationB.cs:18:12:18:13 | exit C2 (abnormal) | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationB.cs:18:12:18:13 | exit C2 (abnormal) | MultiImplementationB.cs:18:12:18:13 | C2 | -| MultiImplementationB.cs:18:12:18:13 | exit C2 (normal) | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationB.cs:18:12:18:13 | exit C2 (normal) | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationB.cs:18:22:18:36 | {...} | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationB.cs:18:22:18:36 | {...} | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationB.cs:18:24:18:34 | throw ...; | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationB.cs:18:24:18:34 | throw ...; | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationB.cs:18:30:18:33 | null | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationB.cs:18:30:18:33 | null | MultiImplementationB.cs:18:12:18:13 | C2 | -| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationA.cs:21:12:21:13 | C2 | -| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationB.cs:19:12:19:13 | C2 | -| MultiImplementationB.cs:19:12:19:13 | exit C2 | MultiImplementationA.cs:21:12:21:13 | C2 | -| MultiImplementationB.cs:19:12:19:13 | exit C2 | MultiImplementationB.cs:19:12:19:13 | C2 | -| MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | MultiImplementationA.cs:21:12:21:13 | C2 | -| MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | MultiImplementationB.cs:19:12:19:13 | C2 | | MultiImplementationB.cs:19:19:19:22 | call to constructor C2 | MultiImplementationA.cs:21:12:21:13 | C2 | -| MultiImplementationB.cs:19:19:19:22 | call to constructor C2 | MultiImplementationB.cs:19:12:19:13 | C2 | | MultiImplementationB.cs:19:24:19:24 | 1 | MultiImplementationA.cs:21:12:21:13 | C2 | -| MultiImplementationB.cs:19:24:19:24 | 1 | MultiImplementationB.cs:19:12:19:13 | C2 | | MultiImplementationB.cs:19:27:19:29 | {...} | MultiImplementationA.cs:21:12:21:13 | C2 | -| MultiImplementationB.cs:19:27:19:29 | {...} | MultiImplementationB.cs:19:12:19:13 | C2 | -| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationA.cs:22:6:22:7 | ~C2 | -| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationB.cs:20:6:20:7 | ~C2 | -| MultiImplementationB.cs:20:6:20:7 | exit ~C2 | MultiImplementationA.cs:22:6:22:7 | ~C2 | -| MultiImplementationB.cs:20:6:20:7 | exit ~C2 | MultiImplementationB.cs:20:6:20:7 | ~C2 | -| MultiImplementationB.cs:20:6:20:7 | exit ~C2 (abnormal) | MultiImplementationA.cs:22:6:22:7 | ~C2 | -| MultiImplementationB.cs:20:6:20:7 | exit ~C2 (abnormal) | MultiImplementationB.cs:20:6:20:7 | ~C2 | -| MultiImplementationB.cs:20:6:20:7 | exit ~C2 (normal) | MultiImplementationA.cs:22:6:22:7 | ~C2 | -| MultiImplementationB.cs:20:6:20:7 | exit ~C2 (normal) | MultiImplementationB.cs:20:6:20:7 | ~C2 | | MultiImplementationB.cs:20:11:20:25 | {...} | MultiImplementationA.cs:22:6:22:7 | ~C2 | -| MultiImplementationB.cs:20:11:20:25 | {...} | MultiImplementationB.cs:20:6:20:7 | ~C2 | | MultiImplementationB.cs:20:13:20:23 | throw ...; | MultiImplementationA.cs:22:6:22:7 | ~C2 | -| MultiImplementationB.cs:20:13:20:23 | throw ...; | MultiImplementationB.cs:20:6:20:7 | ~C2 | | MultiImplementationB.cs:20:19:20:22 | null | MultiImplementationA.cs:22:6:22:7 | ~C2 | -| MultiImplementationB.cs:20:19:20:22 | null | MultiImplementationB.cs:20:6:20:7 | ~C2 | -| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationA.cs:23:28:23:35 | implicit conversion | -| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationB.cs:21:28:21:35 | implicit conversion | -| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | MultiImplementationA.cs:23:28:23:35 | implicit conversion | -| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | MultiImplementationB.cs:21:28:21:35 | implicit conversion | -| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion (abnormal) | MultiImplementationA.cs:23:28:23:35 | implicit conversion | -| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion (abnormal) | MultiImplementationB.cs:21:28:21:35 | implicit conversion | -| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion (normal) | MultiImplementationA.cs:23:28:23:35 | implicit conversion | -| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion (normal) | MultiImplementationB.cs:21:28:21:35 | implicit conversion | | MultiImplementationB.cs:21:50:21:59 | throw ... | MultiImplementationA.cs:23:28:23:35 | implicit conversion | -| MultiImplementationB.cs:21:50:21:59 | throw ... | MultiImplementationB.cs:21:28:21:35 | implicit conversion | | MultiImplementationB.cs:21:56:21:59 | null | MultiImplementationA.cs:23:28:23:35 | implicit conversion | -| MultiImplementationB.cs:21:56:21:59 | null | MultiImplementationB.cs:21:28:21:35 | implicit conversion | | MultiImplementationB.cs:22:16:22:16 | access to property P | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationB.cs:22:16:22:16 | access to property P | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationB.cs:22:16:22:16 | this access | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationB.cs:22:16:22:16 | this access | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationB.cs:22:32:22:34 | ... = ... | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationB.cs:22:32:22:34 | ... = ... | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationB.cs:22:34:22:34 | 1 | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationB.cs:22:34:22:34 | 1 | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationB.cs:25:7:25:8 | call to constructor Object | MultiImplementationA.cs:28:7:28:8 | C3 | -| MultiImplementationB.cs:25:7:25:8 | call to constructor Object | MultiImplementationB.cs:25:7:25:8 | C3 | -| MultiImplementationB.cs:25:7:25:8 | enter C3 | MultiImplementationA.cs:28:7:28:8 | C3 | -| MultiImplementationB.cs:25:7:25:8 | enter C3 | MultiImplementationB.cs:25:7:25:8 | C3 | -| MultiImplementationB.cs:25:7:25:8 | exit C3 | MultiImplementationA.cs:28:7:28:8 | C3 | -| MultiImplementationB.cs:25:7:25:8 | exit C3 | MultiImplementationB.cs:25:7:25:8 | C3 | -| MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | MultiImplementationA.cs:28:7:28:8 | C3 | -| MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | MultiImplementationB.cs:25:7:25:8 | C3 | | MultiImplementationB.cs:25:7:25:8 | {...} | MultiImplementationA.cs:28:7:28:8 | C3 | -| MultiImplementationB.cs:25:7:25:8 | {...} | MultiImplementationB.cs:25:7:25:8 | C3 | -| MultiImplementationB.cs:27:21:27:23 | enter get_P3 | MultiImplementationA.cs:30:21:30:23 | get_P3 | -| MultiImplementationB.cs:27:21:27:23 | enter get_P3 | MultiImplementationB.cs:27:21:27:23 | get_P3 | -| MultiImplementationB.cs:27:21:27:23 | exit get_P3 | MultiImplementationA.cs:30:21:30:23 | get_P3 | -| MultiImplementationB.cs:27:21:27:23 | exit get_P3 | MultiImplementationB.cs:27:21:27:23 | get_P3 | -| MultiImplementationB.cs:27:21:27:23 | exit get_P3 (abnormal) | MultiImplementationA.cs:30:21:30:23 | get_P3 | -| MultiImplementationB.cs:27:21:27:23 | exit get_P3 (abnormal) | MultiImplementationB.cs:27:21:27:23 | get_P3 | | MultiImplementationB.cs:30:15:30:16 | call to constructor Object | MultiImplementationA.cs:34:15:34:16 | C4 | -| MultiImplementationB.cs:30:15:30:16 | call to constructor Object | MultiImplementationB.cs:30:15:30:16 | C4 | -| MultiImplementationB.cs:30:15:30:16 | enter C4 | MultiImplementationA.cs:34:15:34:16 | C4 | -| MultiImplementationB.cs:30:15:30:16 | enter C4 | MultiImplementationB.cs:30:15:30:16 | C4 | -| MultiImplementationB.cs:30:15:30:16 | exit C4 | MultiImplementationA.cs:34:15:34:16 | C4 | -| MultiImplementationB.cs:30:15:30:16 | exit C4 | MultiImplementationB.cs:30:15:30:16 | C4 | -| MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | MultiImplementationA.cs:34:15:34:16 | C4 | -| MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | MultiImplementationB.cs:30:15:30:16 | C4 | | MultiImplementationB.cs:30:15:30:16 | {...} | MultiImplementationA.cs:34:15:34:16 | C4 | -| MultiImplementationB.cs:30:15:30:16 | {...} | MultiImplementationB.cs:30:15:30:16 | C4 | -| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationA.cs:36:9:36:10 | M1 | -| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationB.cs:32:9:32:10 | M1 | -| MultiImplementationB.cs:32:9:32:10 | exit M1 | MultiImplementationA.cs:36:9:36:10 | M1 | -| MultiImplementationB.cs:32:9:32:10 | exit M1 | MultiImplementationB.cs:32:9:32:10 | M1 | -| MultiImplementationB.cs:32:9:32:10 | exit M1 (abnormal) | MultiImplementationA.cs:36:9:36:10 | M1 | -| MultiImplementationB.cs:32:9:32:10 | exit M1 (abnormal) | MultiImplementationB.cs:32:9:32:10 | M1 | -| MultiImplementationB.cs:32:9:32:10 | exit M1 (normal) | MultiImplementationA.cs:36:9:36:10 | M1 | -| MultiImplementationB.cs:32:9:32:10 | exit M1 (normal) | MultiImplementationB.cs:32:9:32:10 | M1 | | MultiImplementationB.cs:32:17:32:17 | 0 | MultiImplementationA.cs:36:9:36:10 | M1 | -| MultiImplementationB.cs:32:17:32:17 | 0 | MultiImplementationB.cs:32:9:32:10 | M1 | | NullCoalescing.cs:1:7:1:20 | call to constructor Object | NullCoalescing.cs:1:7:1:20 | NullCoalescing | | NullCoalescing.cs:1:7:1:20 | enter NullCoalescing | NullCoalescing.cs:1:7:1:20 | NullCoalescing | | NullCoalescing.cs:1:7:1:20 | exit NullCoalescing | NullCoalescing.cs:1:7:1:20 | NullCoalescing | @@ -5843,204 +5574,73 @@ blockEnclosing | LoopUnrolling.cs:94:10:94:12 | exit M11 (normal) | LoopUnrolling.cs:94:10:94:12 | M11 | | LoopUnrolling.cs:97:22:97:22 | String x | LoopUnrolling.cs:94:10:94:12 | M11 | | MultiImplementationA.cs:4:7:4:8 | call to constructor Object | MultiImplementationA.cs:4:7:4:8 | C1 | -| MultiImplementationA.cs:4:7:4:8 | call to constructor Object | MultiImplementationB.cs:1:7:1:8 | C1 | | MultiImplementationA.cs:4:7:4:8 | enter C1 | MultiImplementationA.cs:4:7:4:8 | C1 | -| MultiImplementationA.cs:4:7:4:8 | enter C1 | MultiImplementationB.cs:1:7:1:8 | C1 | | MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | MultiImplementationA.cs:4:7:4:8 | C1 | -| MultiImplementationA.cs:4:7:4:8 | exit C1 (normal) | MultiImplementationB.cs:1:7:1:8 | C1 | | MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationA.cs:6:22:6:31 | get_P1 | -| MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | get_P1 | | MultiImplementationA.cs:6:22:6:31 | exit get_P1 | MultiImplementationA.cs:6:22:6:31 | get_P1 | -| MultiImplementationA.cs:6:22:6:31 | exit get_P1 | MultiImplementationB.cs:3:22:3:22 | get_P1 | | MultiImplementationA.cs:6:28:6:31 | null | MultiImplementationA.cs:6:22:6:31 | get_P1 | -| MultiImplementationA.cs:6:28:6:31 | null | MultiImplementationB.cs:3:22:3:22 | get_P1 | | MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationA.cs:7:21:7:23 | get_P2 | -| MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationB.cs:4:21:4:23 | get_P2 | | MultiImplementationA.cs:7:21:7:23 | exit get_P2 | MultiImplementationA.cs:7:21:7:23 | get_P2 | -| MultiImplementationA.cs:7:21:7:23 | exit get_P2 | MultiImplementationB.cs:4:21:4:23 | get_P2 | | MultiImplementationA.cs:7:25:7:39 | {...} | MultiImplementationA.cs:7:21:7:23 | get_P2 | -| MultiImplementationA.cs:7:25:7:39 | {...} | MultiImplementationB.cs:4:21:4:23 | get_P2 | | MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationA.cs:7:41:7:43 | set_P2 | -| MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationB.cs:4:39:4:41 | set_P2 | | MultiImplementationA.cs:7:41:7:43 | exit set_P2 | MultiImplementationA.cs:7:41:7:43 | set_P2 | -| MultiImplementationA.cs:7:41:7:43 | exit set_P2 | MultiImplementationB.cs:4:39:4:41 | set_P2 | | MultiImplementationA.cs:7:45:7:59 | {...} | MultiImplementationA.cs:7:41:7:43 | set_P2 | -| MultiImplementationA.cs:7:45:7:59 | {...} | MultiImplementationB.cs:4:39:4:41 | set_P2 | | MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationA.cs:8:16:8:16 | M | -| MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationB.cs:5:16:5:16 | M | | MultiImplementationA.cs:8:16:8:16 | exit M | MultiImplementationA.cs:8:16:8:16 | M | -| MultiImplementationA.cs:8:16:8:16 | exit M | MultiImplementationB.cs:5:16:5:16 | M | | MultiImplementationA.cs:8:29:8:32 | null | MultiImplementationA.cs:8:16:8:16 | M | -| MultiImplementationA.cs:8:29:8:32 | null | MultiImplementationB.cs:5:16:5:16 | M | | MultiImplementationA.cs:14:31:14:31 | access to parameter i | MultiImplementationA.cs:14:31:14:31 | get_Item | -| MultiImplementationA.cs:14:31:14:31 | access to parameter i | MultiImplementationB.cs:12:31:12:40 | get_Item | | MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | get_Item | -| MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationB.cs:12:31:12:40 | get_Item | | MultiImplementationA.cs:14:31:14:31 | exit get_Item | MultiImplementationA.cs:14:31:14:31 | get_Item | -| MultiImplementationA.cs:14:31:14:31 | exit get_Item | MultiImplementationB.cs:12:31:12:40 | get_Item | | MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationA.cs:15:36:15:38 | get_Item | -| MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationB.cs:13:36:13:38 | get_Item | | MultiImplementationA.cs:15:36:15:38 | exit get_Item | MultiImplementationA.cs:15:36:15:38 | get_Item | -| MultiImplementationA.cs:15:36:15:38 | exit get_Item | MultiImplementationB.cs:13:36:13:38 | get_Item | | MultiImplementationA.cs:15:40:15:52 | {...} | MultiImplementationA.cs:15:36:15:38 | get_Item | -| MultiImplementationA.cs:15:40:15:52 | {...} | MultiImplementationB.cs:13:36:13:38 | get_Item | | MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationA.cs:15:54:15:56 | set_Item | -| MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationB.cs:13:56:13:58 | set_Item | | MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | MultiImplementationA.cs:15:54:15:56 | set_Item | -| MultiImplementationA.cs:15:54:15:56 | exit set_Item (normal) | MultiImplementationB.cs:13:56:13:58 | set_Item | | MultiImplementationA.cs:15:58:15:60 | {...} | MultiImplementationA.cs:15:54:15:56 | set_Item | -| MultiImplementationA.cs:15:58:15:60 | {...} | MultiImplementationB.cs:13:56:13:58 | set_Item | | MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationA.cs:16:17:16:18 | M1 | -| MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationB.cs:14:17:14:18 | M1 | | MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | MultiImplementationA.cs:16:17:16:18 | M1 | -| MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | MultiImplementationB.cs:14:17:14:18 | M1 | | MultiImplementationA.cs:17:5:19:5 | {...} | MultiImplementationA.cs:16:17:16:18 | M1 | -| MultiImplementationA.cs:17:5:19:5 | {...} | MultiImplementationB.cs:14:17:14:18 | M1 | | MultiImplementationA.cs:18:9:18:22 | enter M2 | MultiImplementationA.cs:18:9:18:22 | M2 | | MultiImplementationA.cs:20:12:20:13 | call to constructor Object | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationA.cs:20:12:20:13 | call to constructor Object | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationB.cs:18:12:18:13 | C2 | | MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationA.cs:21:12:21:13 | C2 | -| MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationB.cs:19:12:19:13 | C2 | | MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | MultiImplementationA.cs:21:12:21:13 | C2 | -| MultiImplementationA.cs:21:12:21:13 | exit C2 (normal) | MultiImplementationB.cs:19:12:19:13 | C2 | | MultiImplementationA.cs:21:24:21:24 | 0 | MultiImplementationA.cs:21:12:21:13 | C2 | -| MultiImplementationA.cs:21:24:21:24 | 0 | MultiImplementationB.cs:19:12:19:13 | C2 | | MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationA.cs:22:6:22:7 | ~C2 | -| MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationB.cs:20:6:20:7 | ~C2 | | MultiImplementationA.cs:22:6:22:7 | exit ~C2 | MultiImplementationA.cs:22:6:22:7 | ~C2 | -| MultiImplementationA.cs:22:6:22:7 | exit ~C2 | MultiImplementationB.cs:20:6:20:7 | ~C2 | | MultiImplementationA.cs:22:11:22:13 | {...} | MultiImplementationA.cs:22:6:22:7 | ~C2 | -| MultiImplementationA.cs:22:11:22:13 | {...} | MultiImplementationB.cs:20:6:20:7 | ~C2 | | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationA.cs:23:28:23:35 | implicit conversion | -| MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationB.cs:21:28:21:35 | implicit conversion | | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | MultiImplementationA.cs:23:28:23:35 | implicit conversion | -| MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | MultiImplementationB.cs:21:28:21:35 | implicit conversion | | MultiImplementationA.cs:23:50:23:53 | null | MultiImplementationA.cs:23:28:23:35 | implicit conversion | -| MultiImplementationA.cs:23:50:23:53 | null | MultiImplementationB.cs:21:28:21:35 | implicit conversion | | MultiImplementationA.cs:28:7:28:8 | call to constructor Object | MultiImplementationA.cs:28:7:28:8 | C3 | -| MultiImplementationA.cs:28:7:28:8 | call to constructor Object | MultiImplementationB.cs:25:7:25:8 | C3 | | MultiImplementationA.cs:28:7:28:8 | enter C3 | MultiImplementationA.cs:28:7:28:8 | C3 | -| MultiImplementationA.cs:28:7:28:8 | enter C3 | MultiImplementationB.cs:25:7:25:8 | C3 | | MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | MultiImplementationA.cs:28:7:28:8 | C3 | -| MultiImplementationA.cs:28:7:28:8 | exit C3 (normal) | MultiImplementationB.cs:25:7:25:8 | C3 | | MultiImplementationA.cs:30:21:30:23 | enter get_P3 | MultiImplementationA.cs:30:21:30:23 | get_P3 | -| MultiImplementationA.cs:30:21:30:23 | enter get_P3 | MultiImplementationB.cs:27:21:27:23 | get_P3 | | MultiImplementationA.cs:34:15:34:16 | call to constructor Object | MultiImplementationA.cs:34:15:34:16 | C4 | -| MultiImplementationA.cs:34:15:34:16 | call to constructor Object | MultiImplementationB.cs:30:15:30:16 | C4 | | MultiImplementationA.cs:34:15:34:16 | enter C4 | MultiImplementationA.cs:34:15:34:16 | C4 | -| MultiImplementationA.cs:34:15:34:16 | enter C4 | MultiImplementationB.cs:30:15:30:16 | C4 | | MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | MultiImplementationA.cs:34:15:34:16 | C4 | -| MultiImplementationA.cs:34:15:34:16 | exit C4 (normal) | MultiImplementationB.cs:30:15:30:16 | C4 | | MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationA.cs:36:9:36:10 | M1 | -| MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationB.cs:32:9:32:10 | M1 | | MultiImplementationA.cs:36:9:36:10 | exit M1 | MultiImplementationA.cs:36:9:36:10 | M1 | -| MultiImplementationA.cs:36:9:36:10 | exit M1 | MultiImplementationB.cs:32:9:32:10 | M1 | | MultiImplementationA.cs:36:14:36:28 | {...} | MultiImplementationA.cs:36:9:36:10 | M1 | -| MultiImplementationA.cs:36:14:36:28 | {...} | MultiImplementationB.cs:32:9:32:10 | M1 | | MultiImplementationA.cs:37:9:37:10 | enter M2 | MultiImplementationA.cs:37:9:37:10 | M2 | | MultiImplementationB.cs:1:7:1:8 | call to constructor Object | MultiImplementationA.cs:4:7:4:8 | C1 | -| MultiImplementationB.cs:1:7:1:8 | call to constructor Object | MultiImplementationB.cs:1:7:1:8 | C1 | -| MultiImplementationB.cs:1:7:1:8 | enter C1 | MultiImplementationA.cs:4:7:4:8 | C1 | -| MultiImplementationB.cs:1:7:1:8 | enter C1 | MultiImplementationB.cs:1:7:1:8 | C1 | -| MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | MultiImplementationA.cs:4:7:4:8 | C1 | -| MultiImplementationB.cs:1:7:1:8 | exit C1 (normal) | MultiImplementationB.cs:1:7:1:8 | C1 | | MultiImplementationB.cs:3:22:3:22 | 0 | MultiImplementationA.cs:6:22:6:31 | get_P1 | -| MultiImplementationB.cs:3:22:3:22 | 0 | MultiImplementationB.cs:3:22:3:22 | get_P1 | -| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationA.cs:6:22:6:31 | get_P1 | -| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | get_P1 | -| MultiImplementationB.cs:3:22:3:22 | exit get_P1 | MultiImplementationA.cs:6:22:6:31 | get_P1 | -| MultiImplementationB.cs:3:22:3:22 | exit get_P1 | MultiImplementationB.cs:3:22:3:22 | get_P1 | -| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationA.cs:7:21:7:23 | get_P2 | -| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationB.cs:4:21:4:23 | get_P2 | -| MultiImplementationB.cs:4:21:4:23 | exit get_P2 | MultiImplementationA.cs:7:21:7:23 | get_P2 | -| MultiImplementationB.cs:4:21:4:23 | exit get_P2 | MultiImplementationB.cs:4:21:4:23 | get_P2 | | MultiImplementationB.cs:4:25:4:37 | {...} | MultiImplementationA.cs:7:21:7:23 | get_P2 | -| MultiImplementationB.cs:4:25:4:37 | {...} | MultiImplementationB.cs:4:21:4:23 | get_P2 | -| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationA.cs:7:41:7:43 | set_P2 | -| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationB.cs:4:39:4:41 | set_P2 | -| MultiImplementationB.cs:4:39:4:41 | exit set_P2 | MultiImplementationA.cs:7:41:7:43 | set_P2 | -| MultiImplementationB.cs:4:39:4:41 | exit set_P2 | MultiImplementationB.cs:4:39:4:41 | set_P2 | | MultiImplementationB.cs:4:43:4:45 | {...} | MultiImplementationA.cs:7:41:7:43 | set_P2 | -| MultiImplementationB.cs:4:43:4:45 | {...} | MultiImplementationB.cs:4:39:4:41 | set_P2 | -| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationA.cs:8:16:8:16 | M | -| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationB.cs:5:16:5:16 | M | -| MultiImplementationB.cs:5:16:5:16 | exit M | MultiImplementationA.cs:8:16:8:16 | M | -| MultiImplementationB.cs:5:16:5:16 | exit M | MultiImplementationB.cs:5:16:5:16 | M | | MultiImplementationB.cs:5:23:5:23 | 2 | MultiImplementationA.cs:8:16:8:16 | M | -| MultiImplementationB.cs:5:23:5:23 | 2 | MultiImplementationB.cs:5:16:5:16 | M | -| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | get_Item | -| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationB.cs:12:31:12:40 | get_Item | -| MultiImplementationB.cs:12:31:12:40 | exit get_Item | MultiImplementationA.cs:14:31:14:31 | get_Item | -| MultiImplementationB.cs:12:31:12:40 | exit get_Item | MultiImplementationB.cs:12:31:12:40 | get_Item | | MultiImplementationB.cs:12:37:12:40 | null | MultiImplementationA.cs:14:31:14:31 | get_Item | -| MultiImplementationB.cs:12:37:12:40 | null | MultiImplementationB.cs:12:31:12:40 | get_Item | -| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationA.cs:15:36:15:38 | get_Item | -| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationB.cs:13:36:13:38 | get_Item | -| MultiImplementationB.cs:13:36:13:38 | exit get_Item | MultiImplementationA.cs:15:36:15:38 | get_Item | -| MultiImplementationB.cs:13:36:13:38 | exit get_Item | MultiImplementationB.cs:13:36:13:38 | get_Item | | MultiImplementationB.cs:13:40:13:54 | {...} | MultiImplementationA.cs:15:36:15:38 | get_Item | -| MultiImplementationB.cs:13:40:13:54 | {...} | MultiImplementationB.cs:13:36:13:38 | get_Item | -| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationA.cs:15:54:15:56 | set_Item | -| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationB.cs:13:56:13:58 | set_Item | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | MultiImplementationA.cs:15:54:15:56 | set_Item | -| MultiImplementationB.cs:13:56:13:58 | exit set_Item (normal) | MultiImplementationB.cs:13:56:13:58 | set_Item | | MultiImplementationB.cs:13:60:13:62 | {...} | MultiImplementationA.cs:15:54:15:56 | set_Item | -| MultiImplementationB.cs:13:60:13:62 | {...} | MultiImplementationB.cs:13:56:13:58 | set_Item | -| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationA.cs:16:17:16:18 | M1 | -| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationB.cs:14:17:14:18 | M1 | -| MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | MultiImplementationA.cs:16:17:16:18 | M1 | -| MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | MultiImplementationB.cs:14:17:14:18 | M1 | | MultiImplementationB.cs:15:5:17:5 | {...} | MultiImplementationA.cs:16:17:16:18 | M1 | -| MultiImplementationB.cs:15:5:17:5 | {...} | MultiImplementationB.cs:14:17:14:18 | M1 | | MultiImplementationB.cs:16:9:16:31 | enter M2 | MultiImplementationB.cs:16:9:16:31 | M2 | | MultiImplementationB.cs:18:12:18:13 | call to constructor Object | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationB.cs:18:12:18:13 | call to constructor Object | MultiImplementationB.cs:18:12:18:13 | C2 | -| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | C2 | -| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationA.cs:20:12:20:13 | C2 | -| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationB.cs:18:12:18:13 | C2 | -| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationA.cs:21:12:21:13 | C2 | -| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationB.cs:19:12:19:13 | C2 | -| MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | MultiImplementationA.cs:21:12:21:13 | C2 | -| MultiImplementationB.cs:19:12:19:13 | exit C2 (normal) | MultiImplementationB.cs:19:12:19:13 | C2 | | MultiImplementationB.cs:19:24:19:24 | 1 | MultiImplementationA.cs:21:12:21:13 | C2 | -| MultiImplementationB.cs:19:24:19:24 | 1 | MultiImplementationB.cs:19:12:19:13 | C2 | -| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationA.cs:22:6:22:7 | ~C2 | -| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationB.cs:20:6:20:7 | ~C2 | -| MultiImplementationB.cs:20:6:20:7 | exit ~C2 | MultiImplementationA.cs:22:6:22:7 | ~C2 | -| MultiImplementationB.cs:20:6:20:7 | exit ~C2 | MultiImplementationB.cs:20:6:20:7 | ~C2 | | MultiImplementationB.cs:20:11:20:25 | {...} | MultiImplementationA.cs:22:6:22:7 | ~C2 | -| MultiImplementationB.cs:20:11:20:25 | {...} | MultiImplementationB.cs:20:6:20:7 | ~C2 | -| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationA.cs:23:28:23:35 | implicit conversion | -| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationB.cs:21:28:21:35 | implicit conversion | -| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | MultiImplementationA.cs:23:28:23:35 | implicit conversion | -| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | MultiImplementationB.cs:21:28:21:35 | implicit conversion | | MultiImplementationB.cs:21:56:21:59 | null | MultiImplementationA.cs:23:28:23:35 | implicit conversion | -| MultiImplementationB.cs:21:56:21:59 | null | MultiImplementationB.cs:21:28:21:35 | implicit conversion | | MultiImplementationB.cs:25:7:25:8 | call to constructor Object | MultiImplementationA.cs:28:7:28:8 | C3 | -| MultiImplementationB.cs:25:7:25:8 | call to constructor Object | MultiImplementationB.cs:25:7:25:8 | C3 | -| MultiImplementationB.cs:25:7:25:8 | enter C3 | MultiImplementationA.cs:28:7:28:8 | C3 | -| MultiImplementationB.cs:25:7:25:8 | enter C3 | MultiImplementationB.cs:25:7:25:8 | C3 | -| MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | MultiImplementationA.cs:28:7:28:8 | C3 | -| MultiImplementationB.cs:25:7:25:8 | exit C3 (normal) | MultiImplementationB.cs:25:7:25:8 | C3 | -| MultiImplementationB.cs:27:21:27:23 | enter get_P3 | MultiImplementationA.cs:30:21:30:23 | get_P3 | -| MultiImplementationB.cs:27:21:27:23 | enter get_P3 | MultiImplementationB.cs:27:21:27:23 | get_P3 | | MultiImplementationB.cs:30:15:30:16 | call to constructor Object | MultiImplementationA.cs:34:15:34:16 | C4 | -| MultiImplementationB.cs:30:15:30:16 | call to constructor Object | MultiImplementationB.cs:30:15:30:16 | C4 | -| MultiImplementationB.cs:30:15:30:16 | enter C4 | MultiImplementationA.cs:34:15:34:16 | C4 | -| MultiImplementationB.cs:30:15:30:16 | enter C4 | MultiImplementationB.cs:30:15:30:16 | C4 | -| MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | MultiImplementationA.cs:34:15:34:16 | C4 | -| MultiImplementationB.cs:30:15:30:16 | exit C4 (normal) | MultiImplementationB.cs:30:15:30:16 | C4 | -| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationA.cs:36:9:36:10 | M1 | -| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationB.cs:32:9:32:10 | M1 | -| MultiImplementationB.cs:32:9:32:10 | exit M1 | MultiImplementationA.cs:36:9:36:10 | M1 | -| MultiImplementationB.cs:32:9:32:10 | exit M1 | MultiImplementationB.cs:32:9:32:10 | M1 | | MultiImplementationB.cs:32:17:32:17 | 0 | MultiImplementationA.cs:36:9:36:10 | M1 | -| MultiImplementationB.cs:32:17:32:17 | 0 | MultiImplementationB.cs:32:9:32:10 | M1 | | NullCoalescing.cs:1:7:1:20 | enter NullCoalescing | NullCoalescing.cs:1:7:1:20 | NullCoalescing | | NullCoalescing.cs:3:9:3:10 | enter M1 | NullCoalescing.cs:3:9:3:10 | M1 | | NullCoalescing.cs:3:23:3:28 | ... ?? ... | NullCoalescing.cs:3:9:3:10 | M1 | diff --git a/csharp/ql/test/library-tests/controlflow/graph/NodeGraph.expected b/csharp/ql/test/library-tests/controlflow/graph/NodeGraph.expected index 502acfb87b7f..fd3b8ff38bb4 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/NodeGraph.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/NodeGraph.expected @@ -3541,6 +3541,9 @@ ConditionalAccess.cs: # 7| exit M3 (normal) #-----| -> exit M3 +# 7| access to property Length +#-----| -> exit M3 (normal) + # 7| access to parameter s1 #-----| non-null -> ... ?? ... #-----| null -> access to parameter s2 @@ -3559,9 +3562,6 @@ ConditionalAccess.cs: #-----| non-null -> [non-null] ... ?? ... #-----| null -> [null] ... ?? ... -# 7| access to property Length -#-----| -> exit M3 (normal) - # 9| enter M4 #-----| -> access to parameter s @@ -3574,13 +3574,13 @@ ConditionalAccess.cs: #-----| non-null -> access to property Length #-----| null -> 0 -# 9| ... ?? ... -#-----| -> exit M4 (normal) - # 9| access to property Length #-----| non-null -> ... ?? ... #-----| null -> 0 +# 9| ... ?? ... +#-----| -> exit M4 (normal) + # 9| 0 #-----| -> ... ?? ... @@ -3602,13 +3602,13 @@ ConditionalAccess.cs: #-----| non-null -> access to property Length #-----| null -> 0 +# 13| access to property Length +#-----| -> 0 + # 13| ... > ... #-----| true -> 0 #-----| false -> 1 -# 13| access to property Length -#-----| -> 0 - # 13| (...) ... #-----| -> ... > ... @@ -3674,15 +3674,15 @@ ConditionalAccess.cs: # 24| String s = ... #-----| -> ...; +# 24| call to method ToString +#-----| -> String s = ... + # 24| (...) ... #-----| non-null -> call to method ToString # 24| access to parameter i #-----| -> (...) ... -# 24| call to method ToString -#-----| -> String s = ... - # 25| ... = ... #-----| -> exit M7 (normal) @@ -3739,12 +3739,12 @@ ConditionalAccess.cs: # 35| this access #-----| -> access to property Prop -# 35| ...; -#-----| -> this access - # 35| call to method Out #-----| -> exit M8 (normal) +# 35| ...; +#-----| -> this access + # 41| enter CommaJoinWith #-----| -> access to parameter s1 @@ -8195,13 +8195,13 @@ Foreach.cs: #-----| non-null -> call to method ToArray #-----| null -> call to method Empty -# 20| ... ?? ... -#-----| -> foreach (... ... in ...) ... - # 20| call to method ToArray #-----| non-null -> ... ?? ... #-----| null -> call to method Empty +# 20| ... ?? ... +#-----| -> foreach (... ... in ...) ... + # 20| call to method Empty #-----| -> ... ?? ... @@ -9592,40 +9592,92 @@ MultiImplementationA.cs: # 4| call to constructor Object #-----| -> {...} +# 4| enter C1 +#-----| -> call to constructor Object +#-----| -> call to constructor Object + +# 4| exit C1 + +# 4| exit C1 (normal) +#-----| -> exit C1 + # 4| {...} #-----| -> exit C1 (normal) -#-----| -> exit C1 (normal) + +# 6| enter get_P1 +#-----| -> null +#-----| -> 0 + +# 6| exit get_P1 + +# 6| exit get_P1 (abnormal) +#-----| -> exit get_P1 + +# 6| exit get_P1 (normal) +#-----| -> exit get_P1 # 6| throw ... #-----| exception(NullReferenceException) -> exit get_P1 (abnormal) -#-----| exception(NullReferenceException) -> exit get_P1 (abnormal) # 6| null #-----| -> throw ... +# 7| enter get_P2 +#-----| -> {...} +#-----| -> {...} + +# 7| exit get_P2 + +# 7| exit get_P2 (abnormal) +#-----| -> exit get_P2 + +# 7| exit get_P2 (normal) +#-----| -> exit get_P2 + # 7| {...} #-----| -> null # 7| throw ...; #-----| exception(NullReferenceException) -> exit get_P2 (abnormal) -#-----| exception(NullReferenceException) -> exit get_P2 (abnormal) # 7| null #-----| -> throw ...; +# 7| enter set_P2 +#-----| -> {...} +#-----| -> {...} + +# 7| exit set_P2 + +# 7| exit set_P2 (abnormal) +#-----| -> exit set_P2 + +# 7| exit set_P2 (normal) +#-----| -> exit set_P2 + # 7| {...} #-----| -> null # 7| throw ...; #-----| exception(NullReferenceException) -> exit set_P2 (abnormal) -#-----| exception(NullReferenceException) -> exit set_P2 (abnormal) # 7| null #-----| -> throw ...; +# 8| enter M +#-----| -> null +#-----| -> 2 + +# 8| exit M + +# 8| exit M (abnormal) +#-----| -> exit M + +# 8| exit M (normal) +#-----| -> exit M + # 8| throw ... #-----| exception(NullReferenceException) -> exit M (abnormal) -#-----| exception(NullReferenceException) -> exit M (abnormal) # 8| null #-----| -> throw ... @@ -9641,34 +9693,66 @@ MultiImplementationA.cs: # 14| access to parameter i #-----| -> exit get_Item (normal) -#-----| -> exit get_Item (normal) + +# 14| enter get_Item +#-----| -> access to parameter i +#-----| -> null + +# 14| exit get_Item + +# 14| exit get_Item (abnormal) +#-----| -> exit get_Item + +# 14| exit get_Item (normal) +#-----| -> exit get_Item + +# 15| enter get_Item +#-----| -> {...} +#-----| -> {...} + +# 15| exit get_Item + +# 15| exit get_Item (abnormal) +#-----| -> exit get_Item + +# 15| exit get_Item (normal) +#-----| -> exit get_Item # 15| {...} #-----| -> access to parameter s # 15| return ...; #-----| return -> exit get_Item (normal) -#-----| return -> exit get_Item (normal) # 15| access to parameter s #-----| -> return ...; +# 15| enter set_Item +#-----| -> {...} +#-----| -> {...} + +# 15| exit set_Item + +# 15| exit set_Item (normal) +#-----| -> exit set_Item + # 15| {...} #-----| -> exit set_Item (normal) -#-----| -> exit set_Item (normal) + +# 16| enter M1 +#-----| -> {...} +#-----| -> {...} # 16| exit M1 -MultiImplementationB.cs: -# 14| exit M1 +# 16| exit M1 (normal) +#-----| -> exit M1 -MultiImplementationA.cs: # 17| {...} #-----| -> M2(...) # 18| M2(...) #-----| -> exit M1 (normal) -#-----| -> exit M1 (normal) # 18| enter M2 #-----| -> 0 @@ -9684,6 +9768,18 @@ MultiImplementationA.cs: # 20| call to constructor Object #-----| -> this access +# 20| enter C2 +#-----| -> call to constructor Object +#-----| -> call to constructor Object + +# 20| exit C2 + +# 20| exit C2 (abnormal) +#-----| -> exit C2 + +# 20| exit C2 (normal) +#-----| -> exit C2 + # 20| {...} #-----| -> ...; @@ -9692,7 +9788,6 @@ MultiImplementationA.cs: # 20| ... = ... #-----| -> exit C2 (normal) -#-----| -> exit C2 (normal) # 20| ...; #-----| -> this access @@ -9700,6 +9795,15 @@ MultiImplementationA.cs: # 20| access to parameter i #-----| -> ... = ... +# 21| enter C2 +#-----| -> 0 +#-----| -> 1 + +# 21| exit C2 + +# 21| exit C2 (normal) +#-----| -> exit C2 + # 21| call to constructor C2 #-----| -> {...} @@ -9708,15 +9812,36 @@ MultiImplementationA.cs: # 21| {...} #-----| -> exit C2 (normal) -#-----| -> exit C2 (normal) + +# 22| enter ~C2 +#-----| -> {...} +#-----| -> {...} + +# 22| exit ~C2 + +# 22| exit ~C2 (abnormal) +#-----| -> exit ~C2 + +# 22| exit ~C2 (normal) +#-----| -> exit ~C2 # 22| {...} #-----| -> exit ~C2 (normal) -#-----| -> exit ~C2 (normal) + +# 23| enter implicit conversion +#-----| -> null +#-----| -> null + +# 23| exit implicit conversion + +# 23| exit implicit conversion (abnormal) +#-----| -> exit implicit conversion + +# 23| exit implicit conversion (normal) +#-----| -> exit implicit conversion # 23| null #-----| -> exit implicit conversion (normal) -#-----| -> exit implicit conversion (normal) # 24| access to property P #-----| -> ... = ... @@ -9733,13 +9858,28 @@ MultiImplementationA.cs: # 28| call to constructor Object #-----| -> {...} +# 28| enter C3 +#-----| -> call to constructor Object +#-----| -> call to constructor Object + +# 28| exit C3 + +# 28| exit C3 (normal) +#-----| -> exit C3 + # 28| {...} #-----| -> exit C3 (normal) -#-----| -> exit C3 (normal) + +# 30| enter get_P3 +#-----| -> null + +# 30| exit get_P3 + +# 30| exit get_P3 (abnormal) +#-----| -> exit get_P3 # 30| throw ... #-----| exception(NullReferenceException) -> exit get_P3 (abnormal) -#-----| exception(NullReferenceException) -> exit get_P3 (abnormal) # 30| null #-----| -> throw ... @@ -9747,16 +9887,35 @@ MultiImplementationA.cs: # 34| call to constructor Object #-----| -> {...} +# 34| enter C4 +#-----| -> call to constructor Object +#-----| -> call to constructor Object + +# 34| exit C4 + +# 34| exit C4 (normal) +#-----| -> exit C4 + # 34| {...} #-----| -> exit C4 (normal) -#-----| -> exit C4 (normal) + +# 36| enter M1 +#-----| -> {...} +#-----| -> 0 + +# 36| exit M1 + +# 36| exit M1 (abnormal) +#-----| -> exit M1 + +# 36| exit M1 (normal) +#-----| -> exit M1 # 36| {...} #-----| -> null # 36| throw ...; #-----| exception(NullReferenceException) -> exit M1 (abnormal) -#-----| exception(NullReferenceException) -> exit M1 (abnormal) # 36| null #-----| -> throw ...; @@ -9782,201 +9941,26 @@ MultiImplementationB.cs: # 1| call to constructor Object #-----| -> {...} -MultiImplementationA.cs: -# 4| enter C1 -#-----| -> call to constructor Object -#-----| -> call to constructor Object +# 1| {...} +#-----| -> exit C1 (normal) -MultiImplementationB.cs: -# 1| enter C1 -#-----| -> call to constructor Object -#-----| -> call to constructor Object +# 3| 0 +#-----| -> exit get_P1 (normal) -MultiImplementationA.cs: -# 4| exit C1 +# 4| {...} +#-----| -> 1 -MultiImplementationB.cs: -# 1| exit C1 - -MultiImplementationA.cs: -# 4| exit C1 (normal) -#-----| -> exit C1 -#-----| -> exit C1 - -MultiImplementationB.cs: -# 1| exit C1 (normal) -#-----| -> exit C1 -#-----| -> exit C1 - -# 1| {...} -#-----| -> exit C1 (normal) -#-----| -> exit C1 (normal) - -# 3| 0 -#-----| -> exit get_P1 (normal) -#-----| -> exit get_P1 (normal) - -MultiImplementationA.cs: -# 6| enter get_P1 -#-----| -> null -#-----| -> 0 - -MultiImplementationB.cs: -# 3| enter get_P1 -#-----| -> null -#-----| -> 0 - -MultiImplementationA.cs: -# 6| exit get_P1 - -MultiImplementationB.cs: -# 3| exit get_P1 - -MultiImplementationA.cs: -# 6| exit get_P1 (abnormal) -#-----| -> exit get_P1 -#-----| -> exit get_P1 - -MultiImplementationB.cs: -# 3| exit get_P1 (abnormal) -#-----| -> exit get_P1 -#-----| -> exit get_P1 - -MultiImplementationA.cs: -# 6| exit get_P1 (normal) -#-----| -> exit get_P1 -#-----| -> exit get_P1 - -MultiImplementationB.cs: -# 3| exit get_P1 (normal) -#-----| -> exit get_P1 -#-----| -> exit get_P1 - -MultiImplementationA.cs: -# 7| enter get_P2 -#-----| -> {...} -#-----| -> {...} - -MultiImplementationB.cs: -# 4| enter get_P2 -#-----| -> {...} -#-----| -> {...} - -MultiImplementationA.cs: -# 7| exit get_P2 - -MultiImplementationB.cs: -# 4| exit get_P2 - -MultiImplementationA.cs: -# 7| exit get_P2 (abnormal) -#-----| -> exit get_P2 -#-----| -> exit get_P2 - -MultiImplementationB.cs: -# 4| exit get_P2 (abnormal) -#-----| -> exit get_P2 -#-----| -> exit get_P2 - -MultiImplementationA.cs: -# 7| exit get_P2 (normal) -#-----| -> exit get_P2 -#-----| -> exit get_P2 - -MultiImplementationB.cs: -# 4| exit get_P2 (normal) -#-----| -> exit get_P2 -#-----| -> exit get_P2 - -# 4| {...} -#-----| -> 1 - -# 4| return ...; -#-----| return -> exit get_P2 (normal) -#-----| return -> exit get_P2 (normal) +# 4| return ...; +#-----| return -> exit get_P2 (normal) # 4| 1 #-----| -> return ...; -MultiImplementationA.cs: -# 7| enter set_P2 -#-----| -> {...} -#-----| -> {...} - -MultiImplementationB.cs: -# 4| enter set_P2 -#-----| -> {...} -#-----| -> {...} - -MultiImplementationA.cs: -# 7| exit set_P2 - -MultiImplementationB.cs: -# 4| exit set_P2 - -MultiImplementationA.cs: -# 7| exit set_P2 (abnormal) -#-----| -> exit set_P2 -#-----| -> exit set_P2 - -MultiImplementationB.cs: -# 4| exit set_P2 (abnormal) -#-----| -> exit set_P2 -#-----| -> exit set_P2 - -MultiImplementationA.cs: -# 7| exit set_P2 (normal) -#-----| -> exit set_P2 -#-----| -> exit set_P2 - -MultiImplementationB.cs: -# 4| exit set_P2 (normal) -#-----| -> exit set_P2 -#-----| -> exit set_P2 - # 4| {...} #-----| -> exit set_P2 (normal) -#-----| -> exit set_P2 (normal) - -MultiImplementationA.cs: -# 8| enter M -#-----| -> null -#-----| -> 2 - -MultiImplementationB.cs: -# 5| enter M -#-----| -> null -#-----| -> 2 - -MultiImplementationA.cs: -# 8| exit M - -MultiImplementationB.cs: -# 5| exit M - -MultiImplementationA.cs: -# 8| exit M (abnormal) -#-----| -> exit M -#-----| -> exit M - -MultiImplementationB.cs: -# 5| exit M (abnormal) -#-----| -> exit M -#-----| -> exit M - -MultiImplementationA.cs: -# 8| exit M (normal) -#-----| -> exit M -#-----| -> exit M - -MultiImplementationB.cs: -# 5| exit M (normal) -#-----| -> exit M -#-----| -> exit M # 5| 2 #-----| -> exit M (normal) -#-----| -> exit M (normal) # 11| this access #-----| -> 1 @@ -9987,151 +9971,29 @@ MultiImplementationB.cs: # 11| 1 #-----| -> ... = ... -MultiImplementationA.cs: -# 14| enter get_Item -#-----| -> access to parameter i -#-----| -> null - -MultiImplementationB.cs: -# 12| enter get_Item -#-----| -> access to parameter i -#-----| -> null - -MultiImplementationA.cs: -# 14| exit get_Item - -MultiImplementationB.cs: -# 12| exit get_Item - -MultiImplementationA.cs: -# 14| exit get_Item (abnormal) -#-----| -> exit get_Item -#-----| -> exit get_Item - -MultiImplementationB.cs: -# 12| exit get_Item (abnormal) -#-----| -> exit get_Item -#-----| -> exit get_Item - -MultiImplementationA.cs: -# 14| exit get_Item (normal) -#-----| -> exit get_Item -#-----| -> exit get_Item - -MultiImplementationB.cs: -# 12| exit get_Item (normal) -#-----| -> exit get_Item -#-----| -> exit get_Item - # 12| throw ... #-----| exception(NullReferenceException) -> exit get_Item (abnormal) -#-----| exception(NullReferenceException) -> exit get_Item (abnormal) # 12| null #-----| -> throw ... -MultiImplementationA.cs: -# 15| enter get_Item -#-----| -> {...} -#-----| -> {...} - -MultiImplementationB.cs: -# 13| enter get_Item -#-----| -> {...} -#-----| -> {...} - -MultiImplementationA.cs: -# 15| exit get_Item - -MultiImplementationB.cs: -# 13| exit get_Item - -MultiImplementationA.cs: -# 15| exit get_Item (abnormal) -#-----| -> exit get_Item -#-----| -> exit get_Item - -MultiImplementationB.cs: -# 13| exit get_Item (abnormal) -#-----| -> exit get_Item -#-----| -> exit get_Item - -MultiImplementationA.cs: -# 15| exit get_Item (normal) -#-----| -> exit get_Item -#-----| -> exit get_Item - -MultiImplementationB.cs: -# 13| exit get_Item (normal) -#-----| -> exit get_Item -#-----| -> exit get_Item - # 13| {...} #-----| -> null # 13| throw ...; #-----| exception(NullReferenceException) -> exit get_Item (abnormal) -#-----| exception(NullReferenceException) -> exit get_Item (abnormal) # 13| null #-----| -> throw ...; -MultiImplementationA.cs: -# 15| enter set_Item -#-----| -> {...} -#-----| -> {...} - -MultiImplementationB.cs: -# 13| enter set_Item -#-----| -> {...} -#-----| -> {...} - -MultiImplementationA.cs: -# 15| exit set_Item - -MultiImplementationB.cs: -# 13| exit set_Item - -MultiImplementationA.cs: -# 15| exit set_Item (normal) -#-----| -> exit set_Item -#-----| -> exit set_Item - -MultiImplementationB.cs: -# 13| exit set_Item (normal) -#-----| -> exit set_Item -#-----| -> exit set_Item - # 13| {...} #-----| -> exit set_Item (normal) -#-----| -> exit set_Item (normal) - -MultiImplementationA.cs: -# 16| enter M1 -#-----| -> {...} -#-----| -> {...} - -MultiImplementationB.cs: -# 14| enter M1 -#-----| -> {...} -#-----| -> {...} - -MultiImplementationA.cs: -# 16| exit M1 (normal) -#-----| -> exit M1 -#-----| -> exit M1 - -MultiImplementationB.cs: -# 14| exit M1 (normal) -#-----| -> exit M1 -#-----| -> exit M1 # 15| {...} #-----| -> M2(...) # 16| M2(...) #-----| -> exit M1 (normal) -#-----| -> exit M1 (normal) # 16| enter M2 #-----| -> null @@ -10150,78 +10012,15 @@ MultiImplementationB.cs: # 18| call to constructor Object #-----| -> this access -MultiImplementationA.cs: -# 20| enter C2 -#-----| -> call to constructor Object -#-----| -> call to constructor Object - -MultiImplementationB.cs: -# 18| enter C2 -#-----| -> call to constructor Object -#-----| -> call to constructor Object - -MultiImplementationA.cs: -# 20| exit C2 - -MultiImplementationB.cs: -# 18| exit C2 - -MultiImplementationA.cs: -# 20| exit C2 (abnormal) -#-----| -> exit C2 -#-----| -> exit C2 - -MultiImplementationB.cs: -# 18| exit C2 (abnormal) -#-----| -> exit C2 -#-----| -> exit C2 - -MultiImplementationA.cs: -# 20| exit C2 (normal) -#-----| -> exit C2 -#-----| -> exit C2 - -MultiImplementationB.cs: -# 18| exit C2 (normal) -#-----| -> exit C2 -#-----| -> exit C2 - # 18| {...} #-----| -> null # 18| throw ...; #-----| exception(NullReferenceException) -> exit C2 (abnormal) -#-----| exception(NullReferenceException) -> exit C2 (abnormal) # 18| null #-----| -> throw ...; -MultiImplementationA.cs: -# 21| enter C2 -#-----| -> 0 -#-----| -> 1 - -MultiImplementationB.cs: -# 19| enter C2 -#-----| -> 0 -#-----| -> 1 - -MultiImplementationA.cs: -# 21| exit C2 - -MultiImplementationB.cs: -# 19| exit C2 - -MultiImplementationA.cs: -# 21| exit C2 (normal) -#-----| -> exit C2 -#-----| -> exit C2 - -MultiImplementationB.cs: -# 19| exit C2 (normal) -#-----| -> exit C2 -#-----| -> exit C2 - # 19| call to constructor C2 #-----| -> {...} @@ -10230,93 +10029,18 @@ MultiImplementationB.cs: # 19| {...} #-----| -> exit C2 (normal) -#-----| -> exit C2 (normal) - -MultiImplementationA.cs: -# 22| enter ~C2 -#-----| -> {...} -#-----| -> {...} - -MultiImplementationB.cs: -# 20| enter ~C2 -#-----| -> {...} -#-----| -> {...} - -MultiImplementationA.cs: -# 22| exit ~C2 - -MultiImplementationB.cs: -# 20| exit ~C2 - -MultiImplementationA.cs: -# 22| exit ~C2 (abnormal) -#-----| -> exit ~C2 -#-----| -> exit ~C2 - -MultiImplementationB.cs: -# 20| exit ~C2 (abnormal) -#-----| -> exit ~C2 -#-----| -> exit ~C2 - -MultiImplementationA.cs: -# 22| exit ~C2 (normal) -#-----| -> exit ~C2 -#-----| -> exit ~C2 - -MultiImplementationB.cs: -# 20| exit ~C2 (normal) -#-----| -> exit ~C2 -#-----| -> exit ~C2 # 20| {...} #-----| -> null # 20| throw ...; #-----| exception(NullReferenceException) -> exit ~C2 (abnormal) -#-----| exception(NullReferenceException) -> exit ~C2 (abnormal) # 20| null #-----| -> throw ...; -MultiImplementationA.cs: -# 23| enter implicit conversion -#-----| -> null -#-----| -> null - -MultiImplementationB.cs: -# 21| enter implicit conversion -#-----| -> null -#-----| -> null - -MultiImplementationA.cs: -# 23| exit implicit conversion - -MultiImplementationB.cs: -# 21| exit implicit conversion - -MultiImplementationA.cs: -# 23| exit implicit conversion (abnormal) -#-----| -> exit implicit conversion -#-----| -> exit implicit conversion - -MultiImplementationB.cs: -# 21| exit implicit conversion (abnormal) -#-----| -> exit implicit conversion -#-----| -> exit implicit conversion - -MultiImplementationA.cs: -# 23| exit implicit conversion (normal) -#-----| -> exit implicit conversion -#-----| -> exit implicit conversion - -MultiImplementationB.cs: -# 21| exit implicit conversion (normal) -#-----| -> exit implicit conversion -#-----| -> exit implicit conversion - # 21| throw ... #-----| exception(NullReferenceException) -> exit implicit conversion (abnormal) -#-----| exception(NullReferenceException) -> exit implicit conversion (abnormal) # 21| null #-----| -> throw ... @@ -10336,132 +10060,17 @@ MultiImplementationB.cs: # 25| call to constructor Object #-----| -> {...} -MultiImplementationA.cs: -# 28| enter C3 -#-----| -> call to constructor Object -#-----| -> call to constructor Object - -MultiImplementationB.cs: -# 25| enter C3 -#-----| -> call to constructor Object -#-----| -> call to constructor Object - -MultiImplementationA.cs: -# 28| exit C3 - -MultiImplementationB.cs: -# 25| exit C3 - -MultiImplementationA.cs: -# 28| exit C3 (normal) -#-----| -> exit C3 -#-----| -> exit C3 - -MultiImplementationB.cs: -# 25| exit C3 (normal) -#-----| -> exit C3 -#-----| -> exit C3 - # 25| {...} #-----| -> exit C3 (normal) -#-----| -> exit C3 (normal) - -MultiImplementationA.cs: -# 30| enter get_P3 -#-----| -> null - -MultiImplementationB.cs: -# 27| enter get_P3 -#-----| -> null - -MultiImplementationA.cs: -# 30| exit get_P3 - -MultiImplementationB.cs: -# 27| exit get_P3 - -MultiImplementationA.cs: -# 30| exit get_P3 (abnormal) -#-----| -> exit get_P3 -#-----| -> exit get_P3 - -MultiImplementationB.cs: -# 27| exit get_P3 (abnormal) -#-----| -> exit get_P3 -#-----| -> exit get_P3 # 30| call to constructor Object #-----| -> {...} -MultiImplementationA.cs: -# 34| enter C4 -#-----| -> call to constructor Object -#-----| -> call to constructor Object - -MultiImplementationB.cs: -# 30| enter C4 -#-----| -> call to constructor Object -#-----| -> call to constructor Object - -MultiImplementationA.cs: -# 34| exit C4 - -MultiImplementationB.cs: -# 30| exit C4 - -MultiImplementationA.cs: -# 34| exit C4 (normal) -#-----| -> exit C4 -#-----| -> exit C4 - -MultiImplementationB.cs: -# 30| exit C4 (normal) -#-----| -> exit C4 -#-----| -> exit C4 - # 30| {...} #-----| -> exit C4 (normal) -#-----| -> exit C4 (normal) - -MultiImplementationA.cs: -# 36| enter M1 -#-----| -> {...} -#-----| -> 0 - -MultiImplementationB.cs: -# 32| enter M1 -#-----| -> {...} -#-----| -> 0 - -MultiImplementationA.cs: -# 36| exit M1 - -MultiImplementationB.cs: -# 32| exit M1 - -MultiImplementationA.cs: -# 36| exit M1 (abnormal) -#-----| -> exit M1 -#-----| -> exit M1 - -MultiImplementationB.cs: -# 32| exit M1 (abnormal) -#-----| -> exit M1 -#-----| -> exit M1 - -MultiImplementationA.cs: -# 36| exit M1 (normal) -#-----| -> exit M1 -#-----| -> exit M1 - -MultiImplementationB.cs: -# 32| exit M1 (normal) -#-----| -> exit M1 -#-----| -> exit M1 # 32| 0 #-----| -> exit M1 (normal) -#-----| -> exit M1 (normal) NullCoalescing.cs: # 1| call to constructor Object @@ -12374,6 +11983,9 @@ Switch.cs: # 131| return ...; #-----| return -> exit M12 (normal) +# 131| call to method ToString +#-----| -> return ...; + # 131| access to parameter o #-----| -> String s @@ -12406,9 +12018,6 @@ Switch.cs: # 131| null #-----| null -> [null] ... => ... -# 131| call to method ToString -#-----| -> return ...; - # 134| enter M13 #-----| -> {...} diff --git a/csharp/ql/test/library-tests/controlflow/graph/Nodes.expected b/csharp/ql/test/library-tests/controlflow/graph/Nodes.expected index 0dc443fa6236..72ad97ec2bb9 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/Nodes.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/Nodes.expected @@ -1210,40 +1210,7 @@ entryPoint | MultiImplementationA.cs:36:9:36:10 | M1 | MultiImplementationA.cs:36:14:36:28 | {...} | | MultiImplementationA.cs:36:9:36:10 | M1 | MultiImplementationB.cs:32:17:32:17 | 0 | | MultiImplementationA.cs:37:9:37:10 | M2 | MultiImplementationA.cs:37:14:37:28 | {...} | -| MultiImplementationB.cs:1:7:1:8 | C1 | MultiImplementationA.cs:4:7:4:8 | call to constructor Object | -| MultiImplementationB.cs:1:7:1:8 | C1 | MultiImplementationB.cs:1:7:1:8 | call to constructor Object | -| MultiImplementationB.cs:3:22:3:22 | get_P1 | MultiImplementationA.cs:6:28:6:31 | null | -| MultiImplementationB.cs:3:22:3:22 | get_P1 | MultiImplementationB.cs:3:22:3:22 | 0 | -| MultiImplementationB.cs:4:21:4:23 | get_P2 | MultiImplementationA.cs:7:25:7:39 | {...} | -| MultiImplementationB.cs:4:21:4:23 | get_P2 | MultiImplementationB.cs:4:25:4:37 | {...} | -| MultiImplementationB.cs:4:39:4:41 | set_P2 | MultiImplementationA.cs:7:45:7:59 | {...} | -| MultiImplementationB.cs:4:39:4:41 | set_P2 | MultiImplementationB.cs:4:43:4:45 | {...} | -| MultiImplementationB.cs:5:16:5:16 | M | MultiImplementationA.cs:8:29:8:32 | null | -| MultiImplementationB.cs:5:16:5:16 | M | MultiImplementationB.cs:5:23:5:23 | 2 | -| MultiImplementationB.cs:12:31:12:40 | get_Item | MultiImplementationA.cs:14:31:14:31 | access to parameter i | -| MultiImplementationB.cs:12:31:12:40 | get_Item | MultiImplementationB.cs:12:37:12:40 | null | -| MultiImplementationB.cs:13:36:13:38 | get_Item | MultiImplementationA.cs:15:40:15:52 | {...} | -| MultiImplementationB.cs:13:36:13:38 | get_Item | MultiImplementationB.cs:13:40:13:54 | {...} | -| MultiImplementationB.cs:13:56:13:58 | set_Item | MultiImplementationA.cs:15:58:15:60 | {...} | -| MultiImplementationB.cs:13:56:13:58 | set_Item | MultiImplementationB.cs:13:60:13:62 | {...} | -| MultiImplementationB.cs:14:17:14:18 | M1 | MultiImplementationA.cs:17:5:19:5 | {...} | -| MultiImplementationB.cs:14:17:14:18 | M1 | MultiImplementationB.cs:15:5:17:5 | {...} | | MultiImplementationB.cs:16:9:16:31 | M2 | MultiImplementationB.cs:16:27:16:30 | null | -| MultiImplementationB.cs:18:12:18:13 | C2 | MultiImplementationA.cs:20:12:20:13 | call to constructor Object | -| MultiImplementationB.cs:18:12:18:13 | C2 | MultiImplementationB.cs:18:12:18:13 | call to constructor Object | -| MultiImplementationB.cs:19:12:19:13 | C2 | MultiImplementationA.cs:21:24:21:24 | 0 | -| MultiImplementationB.cs:19:12:19:13 | C2 | MultiImplementationB.cs:19:24:19:24 | 1 | -| MultiImplementationB.cs:20:6:20:7 | ~C2 | MultiImplementationA.cs:22:11:22:13 | {...} | -| MultiImplementationB.cs:20:6:20:7 | ~C2 | MultiImplementationB.cs:20:11:20:25 | {...} | -| MultiImplementationB.cs:21:28:21:35 | implicit conversion | MultiImplementationA.cs:23:50:23:53 | null | -| MultiImplementationB.cs:21:28:21:35 | implicit conversion | MultiImplementationB.cs:21:56:21:59 | null | -| MultiImplementationB.cs:25:7:25:8 | C3 | MultiImplementationA.cs:28:7:28:8 | call to constructor Object | -| MultiImplementationB.cs:25:7:25:8 | C3 | MultiImplementationB.cs:25:7:25:8 | call to constructor Object | -| MultiImplementationB.cs:27:21:27:23 | get_P3 | MultiImplementationA.cs:30:34:30:37 | null | -| MultiImplementationB.cs:30:15:30:16 | C4 | MultiImplementationA.cs:34:15:34:16 | call to constructor Object | -| MultiImplementationB.cs:30:15:30:16 | C4 | MultiImplementationB.cs:30:15:30:16 | call to constructor Object | -| MultiImplementationB.cs:32:9:32:10 | M1 | MultiImplementationA.cs:36:14:36:28 | {...} | -| MultiImplementationB.cs:32:9:32:10 | M1 | MultiImplementationB.cs:32:17:32:17 | 0 | | NullCoalescing.cs:1:7:1:20 | NullCoalescing | NullCoalescing.cs:1:7:1:20 | call to constructor Object | | NullCoalescing.cs:3:9:3:10 | M1 | NullCoalescing.cs:3:23:3:23 | access to parameter i | | NullCoalescing.cs:5:9:5:10 | M2 | NullCoalescing.cs:5:25:5:25 | access to parameter b | diff --git a/csharp/ql/test/library-tests/csharp7/TupleTypes.expected b/csharp/ql/test/library-tests/csharp7/TupleTypes.expected index d958ad60e4d1..9d7f3330151b 100644 --- a/csharp/ql/test/library-tests/csharp7/TupleTypes.expected +++ b/csharp/ql/test/library-tests/csharp7/TupleTypes.expected @@ -7,7 +7,6 @@ | (Int32,String) | (int, string) | ValueTuple | 2 | 0 | CSharp7.cs:95:19:95:19 | Item1 | | (Int32,String) | (int, string) | ValueTuple | 2 | 1 | CSharp7.cs:95:22:95:37 | Item2 | | (String,Int32) | (string, int) | ValueTuple | 2 | 0 | CSharp7.cs:82:17:82:17 | Item1 | -| (String,Int32) | (string, int) | ValueTuple | 2 | 0 | CSharp7.cs:101:19:101:38 | Item1 | | (String,Int32) | (string, int) | ValueTuple | 2 | 1 | CSharp7.cs:82:23:82:23 | Item2 | | (String,String) | (string, string) | ValueTuple | 2 | 0 | CSharp7.cs:87:19:87:27 | Item1 | | (String,String) | (string, string) | ValueTuple | 2 | 1 | CSharp7.cs:87:30:87:33 | Item2 | diff --git a/csharp/ql/test/library-tests/exprorstmtparent/Callable.expected b/csharp/ql/test/library-tests/exprorstmtparent/Callable.expected index 191dd35f9765..2de32e4ee009 100644 --- a/csharp/ql/test/library-tests/exprorstmtparent/Callable.expected +++ b/csharp/ql/test/library-tests/exprorstmtparent/Callable.expected @@ -34,39 +34,4 @@ | A.cs:36:9:36:10 | M1 | B.cs:32:17:32:17 | 0 | | A.cs:37:9:37:10 | M2 | A.cs:37:14:37:28 | {...} | | A.cs:37:9:37:10 | M2 | C.cs:3:17:3:17 | 0 | -| B.cs:1:7:1:8 | C1 | A.cs:4:7:4:8 | {...} | -| B.cs:1:7:1:8 | C1 | B.cs:1:7:1:8 | {...} | -| B.cs:3:22:3:22 | get_P1 | A.cs:6:22:6:31 | throw ... | -| B.cs:3:22:3:22 | get_P1 | B.cs:3:22:3:22 | 0 | -| B.cs:4:21:4:23 | get_P2 | A.cs:7:25:7:39 | {...} | -| B.cs:4:21:4:23 | get_P2 | B.cs:4:25:4:37 | {...} | -| B.cs:4:39:4:41 | set_P2 | A.cs:7:45:7:59 | {...} | -| B.cs:4:39:4:41 | set_P2 | B.cs:4:43:4:45 | {...} | -| B.cs:5:16:5:16 | M | A.cs:8:23:8:32 | throw ... | -| B.cs:5:16:5:16 | M | B.cs:5:23:5:23 | 2 | -| B.cs:12:31:12:40 | get_Item | A.cs:14:31:14:31 | access to parameter i | -| B.cs:12:31:12:40 | get_Item | B.cs:12:31:12:40 | throw ... | -| B.cs:13:36:13:38 | get_Item | A.cs:15:40:15:52 | {...} | -| B.cs:13:36:13:38 | get_Item | B.cs:13:40:13:54 | {...} | -| B.cs:13:56:13:58 | set_Item | A.cs:15:58:15:60 | {...} | -| B.cs:13:56:13:58 | set_Item | B.cs:13:60:13:62 | {...} | -| B.cs:14:17:14:18 | M1 | A.cs:17:5:19:5 | {...} | -| B.cs:14:17:14:18 | M1 | B.cs:15:5:17:5 | {...} | | B.cs:16:9:16:31 | M2 | B.cs:16:21:16:30 | throw ... | -| B.cs:18:12:18:13 | C2 | A.cs:20:22:20:31 | {...} | -| B.cs:18:12:18:13 | C2 | B.cs:18:22:18:36 | {...} | -| B.cs:19:12:19:13 | C2 | A.cs:21:27:21:29 | {...} | -| B.cs:19:12:19:13 | C2 | B.cs:19:27:19:29 | {...} | -| B.cs:20:6:20:7 | ~C2 | A.cs:22:11:22:13 | {...} | -| B.cs:20:6:20:7 | ~C2 | B.cs:20:11:20:25 | {...} | -| B.cs:21:28:21:35 | implicit conversion | A.cs:23:50:23:53 | null | -| B.cs:21:28:21:35 | implicit conversion | B.cs:21:50:21:59 | throw ... | -| B.cs:25:7:25:8 | C3 | A.cs:28:7:28:8 | {...} | -| B.cs:25:7:25:8 | C3 | B.cs:25:7:25:8 | {...} | -| B.cs:27:21:27:23 | get_P3 | A.cs:30:28:30:37 | throw ... | -| B.cs:32:9:32:10 | M1 | A.cs:36:14:36:28 | {...} | -| B.cs:32:9:32:10 | M1 | B.cs:32:17:32:17 | 0 | -| C.cs:1:15:1:16 | C4 | A.cs:34:15:34:16 | {...} | -| C.cs:1:15:1:16 | C4 | C.cs:1:15:1:16 | {...} | -| C.cs:3:9:3:10 | M2 | A.cs:37:14:37:28 | {...} | -| C.cs:3:9:3:10 | M2 | C.cs:3:17:3:17 | 0 | diff --git a/csharp/ql/test/library-tests/exprorstmtparent/Declaration.expected b/csharp/ql/test/library-tests/exprorstmtparent/Declaration.expected index 2bab92ce872b..a1df8e9dd0ff 100644 --- a/csharp/ql/test/library-tests/exprorstmtparent/Declaration.expected +++ b/csharp/ql/test/library-tests/exprorstmtparent/Declaration.expected @@ -38,45 +38,7 @@ | A.cs:34:15:34:16 | C4 | | A.cs:36:9:36:10 | M1 | | A.cs:37:9:37:10 | M2 | -| B.cs:1:7:1:8 | C1 | -| B.cs:3:16:3:17 | P1 | -| B.cs:3:22:3:22 | get_P1 | -| B.cs:4:16:4:17 | P2 | -| B.cs:4:21:4:23 | get_P2 | -| B.cs:4:39:4:41 | set_P2 | -| B.cs:4:39:4:41 | value | -| B.cs:5:16:5:16 | M | -| B.cs:9:7:9:8 | C2 | -| B.cs:11:16:11:16 | F | -| B.cs:12:16:12:19 | Item | -| B.cs:12:25:12:25 | i | -| B.cs:12:25:12:25 | i | -| B.cs:12:31:12:40 | get_Item | -| B.cs:13:19:13:22 | Item | -| B.cs:13:31:13:31 | s | -| B.cs:13:31:13:31 | s | -| B.cs:13:31:13:31 | s | -| B.cs:13:36:13:38 | get_Item | -| B.cs:13:56:13:58 | set_Item | -| B.cs:13:56:13:58 | value | -| B.cs:14:17:14:18 | M1 | -| B.cs:14:24:14:24 | i | | B.cs:16:9:16:31 | M2 | -| B.cs:18:12:18:13 | C2 | -| B.cs:18:19:18:19 | i | -| B.cs:19:12:19:13 | C2 | -| B.cs:20:6:20:7 | ~C2 | -| B.cs:21:28:21:35 | implicit conversion | -| B.cs:21:44:21:44 | i | -| B.cs:22:16:22:16 | P | -| B.cs:22:20:22:22 | get_P | -| B.cs:22:25:22:27 | set_P | -| B.cs:22:25:22:27 | value | -| B.cs:25:7:25:8 | C3 | -| B.cs:27:16:27:17 | P3 | -| B.cs:27:21:27:23 | get_P3 | | B.cs:30:15:30:16 | C4 | -| B.cs:32:9:32:10 | M1 | | C.cs:1:15:1:16 | C4 | -| C.cs:3:9:3:10 | M2 | | file://:0:0:0:0 | | diff --git a/csharp/ql/test/library-tests/exprorstmtparent/Indexer.expected b/csharp/ql/test/library-tests/exprorstmtparent/Indexer.expected index 2421dc75b7a5..260045e6eb9d 100644 --- a/csharp/ql/test/library-tests/exprorstmtparent/Indexer.expected +++ b/csharp/ql/test/library-tests/exprorstmtparent/Indexer.expected @@ -1,4 +1,2 @@ | A.cs:14:16:14:19 | Item | A.cs:14:31:14:31 | access to parameter i | | A.cs:14:16:14:19 | Item | B.cs:12:31:12:40 | throw ... | -| B.cs:12:16:12:19 | Item | A.cs:14:31:14:31 | access to parameter i | -| B.cs:12:16:12:19 | Item | B.cs:12:31:12:40 | throw ... | diff --git a/csharp/ql/test/library-tests/exprorstmtparent/Parameter.expected b/csharp/ql/test/library-tests/exprorstmtparent/Parameter.expected index 405336b42285..952b77bf3af5 100644 --- a/csharp/ql/test/library-tests/exprorstmtparent/Parameter.expected +++ b/csharp/ql/test/library-tests/exprorstmtparent/Parameter.expected @@ -1,4 +1,2 @@ | A.cs:16:24:16:24 | i | A.cs:16:28:16:28 | 0 | | A.cs:16:24:16:24 | i | B.cs:14:28:14:28 | 1 | -| B.cs:14:24:14:24 | i | A.cs:16:28:16:28 | 0 | -| B.cs:14:24:14:24 | i | B.cs:14:28:14:28 | 1 | diff --git a/csharp/ql/test/library-tests/exprorstmtparent/Property.expected b/csharp/ql/test/library-tests/exprorstmtparent/Property.expected index bf3e4797973d..3ffc55cfe3cb 100644 --- a/csharp/ql/test/library-tests/exprorstmtparent/Property.expected +++ b/csharp/ql/test/library-tests/exprorstmtparent/Property.expected @@ -2,7 +2,3 @@ | A.cs:6:16:6:17 | P1 | B.cs:3:22:3:22 | 0 | body | | A.cs:24:16:24:16 | P | A.cs:24:34:24:34 | 0 | initializer | | A.cs:24:16:24:16 | P | B.cs:22:34:22:34 | 1 | initializer | -| B.cs:3:16:3:17 | P1 | A.cs:6:22:6:31 | throw ... | body | -| B.cs:3:16:3:17 | P1 | B.cs:3:22:3:22 | 0 | body | -| B.cs:22:16:22:16 | P | A.cs:24:34:24:34 | 0 | initializer | -| B.cs:22:16:22:16 | P | B.cs:22:34:22:34 | 1 | initializer | diff --git a/csharp/ql/test/library-tests/extractor/tagstack/Bodies.expected b/csharp/ql/test/library-tests/extractor/tagstack/Bodies.expected index 147cd9914254..60c8b99a6d4c 100644 --- a/csharp/ql/test/library-tests/extractor/tagstack/Bodies.expected +++ b/csharp/ql/test/library-tests/extractor/tagstack/Bodies.expected @@ -1,2 +1 @@ | A.cs:5:12:5:13 | M1 | This method has multiple bodies. | -| B.cs:5:12:5:13 | M1 | This method has multiple bodies. | diff --git a/csharp/ql/test/library-tests/extractor/tagstack/Classes.expected b/csharp/ql/test/library-tests/extractor/tagstack/Classes.expected index 33c9f5a6b3d5..3163ed48abe9 100644 --- a/csharp/ql/test/library-tests/extractor/tagstack/Classes.expected +++ b/csharp/ql/test/library-tests/extractor/tagstack/Classes.expected @@ -1,2 +1 @@ | A.cs:3:7:3:7 | C | -| B.cs:3:7:3:7 | C | diff --git a/csharp/ql/test/library-tests/extractor/tagstack/Methods.expected b/csharp/ql/test/library-tests/extractor/tagstack/Methods.expected index 27a65e160d5d..664f3830acb3 100644 --- a/csharp/ql/test/library-tests/extractor/tagstack/Methods.expected +++ b/csharp/ql/test/library-tests/extractor/tagstack/Methods.expected @@ -1,4 +1,3 @@ | A.cs:5:12:5:13 | M1 | | A.cs:6:10:6:11 | M2 | -| B.cs:5:12:5:13 | M1 | | B.cs:6:10:6:11 | M3 | diff --git a/csharp/ql/test/library-tests/standalone/errorrecovery/ErrorTypes.expected b/csharp/ql/test/library-tests/standalone/errorrecovery/ErrorTypes.expected index bd9f2307b756..6de54b87ba87 100644 --- a/csharp/ql/test/library-tests/standalone/errorrecovery/ErrorTypes.expected +++ b/csharp/ql/test/library-tests/standalone/errorrecovery/ErrorTypes.expected @@ -13,10 +13,8 @@ | errors.cs:74:17:74:17 | x | Int32 | | errors.cs:75:17:75:17 | x | Int32 | | errors.cs:82:13:82:13 | F | Int32 | -| errors.cs:89:13:89:13 | F | Int32 | | errors.cs:91:29:91:29 | a | Func | | errors.cs:91:34:91:35 | x1 | Int32 | | errors.cs:91:38:91:39 | x2 | Int32 | -| errors.cs:92:29:92:29 | a | Func | | errors.cs:92:34:92:35 | y1 | Int32 | | errors.cs:92:38:92:39 | y2 | Int32 | diff --git a/csharp/ql/test/library-tests/standalone/errorrecovery/Methods.expected b/csharp/ql/test/library-tests/standalone/errorrecovery/Methods.expected index 54d152d2a8fc..a27ebd477de8 100644 --- a/csharp/ql/test/library-tests/standalone/errorrecovery/Methods.expected +++ b/csharp/ql/test/library-tests/standalone/errorrecovery/Methods.expected @@ -6,6 +6,5 @@ | errors.cs:67:22:67:22 | M | 0 | | errors.cs:72:22:72:22 | M | 0 | | errors.cs:81:18:81:22 | get_P | 0 | -| errors.cs:88:18:88:22 | get_P | 0 | | errors.cs:91:33:91:45 | (...) => ... | 0 | | errors.cs:92:33:92:45 | (...) => ... | 0 | From 9055d9567aa9e850e6c7836aa7086c847192d588 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 2 May 2024 15:08:51 +0200 Subject: [PATCH 161/238] Go: remove unused action (will be re-added later) --- go/actions/test/action.yml | 80 -------------------------------------- 1 file changed, 80 deletions(-) delete mode 100644 go/actions/test/action.yml diff --git a/go/actions/test/action.yml b/go/actions/test/action.yml deleted file mode 100644 index a351c4382ac9..000000000000 --- a/go/actions/test/action.yml +++ /dev/null @@ -1,80 +0,0 @@ -name: Test go extractor -description: Run build, QL tests and optionally basic code sanity checks (formatting and generation) -inputs: - run-code-checks: - description: Whether to run formatting, code and qhelp generation checks - required: false - default: false -runs: - using: composite - steps: - - name: Get go version - shell: bash - run: | - ( - echo -n "GO_VERSION=" - bazel run @rules_go//go -- version | sed 's/go version go\(.*\) .*/\1/' - ) | tee -a "$GITHUB_ENV" - - - name: Set up Go - uses: actions/setup-go@v5 - with: - go-version: ${{ env.GO_VERSION }} - cache: false - id: go - - - name: Set up CodeQL CLI - uses: ./.github/actions/fetch-codeql - - - name: Enable problem matchers in repository - shell: bash - run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;' - - - name: Build - shell: bash - run: | - bazel run go:create-extractor-pack - - - name: Check that all Go code is autoformatted - if: inputs.run-code-checks == 'true' - shell: bash - run: | - cd go - make check-formatting - - - name: Check checked-in generated code - if: inputs.run-code-checks == 'true' - shell: bash - run: | - bazel run go:gen - git add . - git diff --exit-code HEAD || ( - echo "please run bazel run //go:gen" - exit 1 - ) - - - name: Compile qhelp files to markdown - if: inputs.run-code-checks == 'true' - shell: bash - run: | - cd go - env QHELP_OUT_DIR=qhelp-out make qhelp-to-markdown - - - name: Upload qhelp markdown - if: inputs.run-code-checks == 'true' - uses: actions/upload-artifact@v3 - with: - name: qhelp-markdown - path: go/qhelp-out/**/*.md - - - name: Cache compilation cache - id: query-cache - uses: ./.github/actions/cache-query-compilation - with: - key: go-qltest - - - name: Test - shell: bash - run: | - cd go - make test cache="${{ steps.query-cache.outputs.cache-dir }}" From 2cff081f2ba0605cb9bb6e21496badcc07cdb483 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Thu, 2 May 2024 15:13:50 +0200 Subject: [PATCH 162/238] Minor fixes to CI script. I had problems with proper resolution of codeql_repo_dir with old python installation, this fixes it --- misc/scripts/accept-expected-changes-from-ci.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/misc/scripts/accept-expected-changes-from-ci.py b/misc/scripts/accept-expected-changes-from-ci.py index bd7071a6c537..7553a1068496 100755 --- a/misc/scripts/accept-expected-changes-from-ci.py +++ b/misc/scripts/accept-expected-changes-from-ci.py @@ -38,14 +38,13 @@ def _get_codeql_repo_dir() -> Path: - return Path(__file__).parent.parent.parent + return Path(__file__).parent.parent.parent.resolve() CODEQL_REPO_DIR = _get_codeql_repo_dir() - def _get_semmle_code_dir() -> Optional[Path]: - guess = CODEQL_REPO_DIR.parent + guess = CODEQL_REPO_DIR.parent.resolve() try: out = subprocess.check_output( ["git", "remote", "-v"], @@ -413,7 +412,7 @@ def ok_job_name(job_name: str) -> bool: subprocess.check_call(["git", "apply", temp.name], cwd=patch.dir) - if "CONSISTENCY" in patch.filename.parts: + if "CONSISTENCY" in patch.filename.parts and patch.filename.exists(): # delete if empty if os.path.getsize(patch.filename) == 1 and patch.filename.read_text() == "\n": os.remove(patch.filename) From ca2d94b297820ff93ef072419c19de31d6c6dd57 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 2 May 2024 15:15:45 +0200 Subject: [PATCH 163/238] Fix go pattern in `.pre-commit-config.yaml` --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 055cab4ac05e..5a0ccc4938f8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -31,7 +31,7 @@ repos: - id: go-gen name: Check checked in generated files in go - files: go/.* + files: ^go/.* language: system entry: bazel run //go:gen pass_filenames: false From 3239af9973e603b828193161839962b603b5ffb6 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Thu, 2 May 2024 15:19:56 +0200 Subject: [PATCH 164/238] Handle multiple job failure URLs CI has changed how jobs are being run :shrug: --- .../scripts/accept-expected-changes-from-ci.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/misc/scripts/accept-expected-changes-from-ci.py b/misc/scripts/accept-expected-changes-from-ci.py index 7553a1068496..cd59387c6684 100755 --- a/misc/scripts/accept-expected-changes-from-ci.py +++ b/misc/scripts/accept-expected-changes-from-ci.py @@ -280,10 +280,7 @@ def main(pr_number: Optional[int], sha_override: Optional[str] = None, force=Fal for lang_test_failure in lang_test_failures: job_failure_urls.add(lang_test_failure.target_url) - if job_failure_urls: - assert len(job_failure_urls) == 1, f"Multiple job failure URLs: {job_failure_urls}" - job_failure_url = job_failure_urls.pop() - + for job_failure_url in job_failure_urls: # fixup URL. On the status, the target URL is the run, and it's really hard to # change this to link to the full `/runs//jobs/` URL, since # the `` is not available in a context: https://github.com/community/community/discussions/40291 @@ -301,6 +298,11 @@ def main(pr_number: Optional[int], sha_override: Optional[str] = None, force=Fal for job in jobs["jobs"]: api_name: str = job["name"] + + if api_name.lower().startswith(expected_workflow_name.lower()): + lang_test_failure.job_id = job["id"] + break + if " / " not in api_name: continue @@ -310,9 +312,11 @@ def main(pr_number: Optional[int], sha_override: Optional[str] = None, force=Fal if workflow_name == expected_workflow_name and job_name.lower().startswith(lang_test_failure.context.lower()): lang_test_failure.job_id = job["id"] break - else: - LOGGER.error(f"Could not find job for {lang_test_failure.context!r}") - sys.exit(1) + + for lang_test_failure in lang_test_failures: + if lang_test_failure.job_id is None: + LOGGER.error(f"Could not find job for {lang_test_failure.context!r}") + sys.exit(1) # Ruby/Swift/C#/Go use github actions, and not internal CI. These are not reported # from the /statuses API, but from the /check-suites API From 318d954536bfca389d3c00812a84ff81f99ff64c Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 2 May 2024 15:38:47 +0200 Subject: [PATCH 165/238] Go: make `//go:gen` not clear by default, and clean on `--force` --- go/gen.py | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/go/gen.py b/go/gen.py index b9394cd15b28..ebb57b2a685a 100644 --- a/go/gen.py +++ b/go/gen.py @@ -2,8 +2,18 @@ import pathlib import subprocess import os +import argparse +import shutil from python.runfiles import runfiles +def options(): + p = argparse.ArgumentParser(description="Update generated checked in files in the Go pack") + p.add_argument("--force", "-f", action="store_true", help="Regenerate all files from scratch rather than updating them") + p.add_argument("generators", nargs=3) + return p.parse_args() + +opts = options() + try: workspace_dir = pathlib.Path(os.environ['BUILD_WORKSPACE_DIRECTORY']) except KeyError: @@ -13,20 +23,34 @@ go_extractor_dir = workspace_dir / "go" / "extractor" go_dbscheme = workspace_dir / "go" / "ql" / "lib" / "go.dbscheme" r = runfiles.Create() -go, gazelle, go_gen_dbscheme = map(r.Rlocation, sys.argv[1:]) +go, gazelle, go_gen_dbscheme = map(r.Rlocation, opts.generators) + -print("updating vendor") +if opts.force: + print("clearing vendor directory") + shutil.rmtree(go_extractor_dir / "vendor") + +existing_build_files = set(go_extractor_dir.glob("*/**/BUILD.bazel")) + +print("updating vendor directory") subprocess.check_call([go, "-C", go_extractor_dir, "work", "vendor"]) -print("clearing generated BUILD files") -for build_file in go_extractor_dir.glob("*/**/BUILD.bazel"): - build_file.unlink() +if opts.force: + print("clearing generated BUILD files") + for build_file in existing_build_files: + build_file.unlink() print("running gazelle") subprocess.check_call([gazelle]) +build_files_to_update = set(go_extractor_dir.glob("*/**/BUILD.bazel")) +if not opts.force: + build_files_to_update -= existing_build_files + # these are always refreshed + build_files_to_update.update(go_extractor_dir.glob("vendor/**/BUILD.bazel")) + print("adding header to generated BUILD files") -for build_file in go_extractor_dir.glob("*/**/BUILD.bazel"): +for build_file in build_files_to_update: contents = build_file.read_text() build_file.write_text(f"# generated running `bazel run //go/gazelle`, do not edit\n\n{contents}") From ccad70897d65c8074f7e40d6870adce0d1dfddb2 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Thu, 2 May 2024 15:39:07 +0200 Subject: [PATCH 166/238] Add `--dont-wait` option --- misc/scripts/accept-expected-changes-from-ci.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/misc/scripts/accept-expected-changes-from-ci.py b/misc/scripts/accept-expected-changes-from-ci.py index cd59387c6684..a8c86d8f3e45 100755 --- a/misc/scripts/accept-expected-changes-from-ci.py +++ b/misc/scripts/accept-expected-changes-from-ci.py @@ -220,7 +220,7 @@ def get_log_content(status: GithubStatus) -> str: return content -def main(pr_number: Optional[int], sha_override: Optional[str] = None, force=False): +def main(pr_number: Optional[int], sha_override: Optional[str] = None, force=False, wait_for_ci=True): if not pr_number and not sha_override: raise Exception("Must specify either a PR number or a SHA") @@ -273,8 +273,9 @@ def main(pr_number: Optional[int], sha_override: Optional[str] = None, force=Fal if status.state == "failure": lang_test_failures.append(status) elif status.state == "pending": - LOGGER.error(f"Language tests ({status.context}) are still running, please wait for them to finish before running this script again") - sys.exit(1) + if wait_for_ci: + LOGGER.error(f"Language tests ({status.context}) are still running, please wait for them to finish before running this script again (or run with --dont-wait)") + sys.exit(1) job_failure_urls = set() for lang_test_failure in lang_test_failures: @@ -327,9 +328,10 @@ def main(pr_number: Optional[int], sha_override: Optional[str] = None, force=Fal check_failure_urls = [] for check in check_suites["check_suites"]: if check["status"] != "completed": - print(check) - LOGGER.error("At least one check not completed yet!") - sys.exit(1) + if wait_for_ci: + print(check) + LOGGER.error("At least one check not completed yet!") + sys.exit(1) if check["conclusion"] == "failure": check_failure_urls.append(check["check_runs_url"]) @@ -460,6 +462,7 @@ def printHelp(): # parse command line arguments parser = argparse.ArgumentParser() parser.add_argument("--force", action="store_true", help="Apply patches even if the local SHA is different from the GitHub PR SHA") + parser.add_argument("--dont-wait", dest="wait_for_ci", action="store_false", help="Do not wait for all CI jobs to finish") parser.add_argument("posarg", nargs="?", default=None) if DEBUG_LOG_FILE: @@ -494,4 +497,4 @@ def printHelp(): else: pr_number = int(args.posarg) - main(pr_number, override_sha, force=args.force) + main(pr_number, override_sha, force=args.force, wait_for_ci=args.wait_for_ci) From 4ae82ac2150cd2c90cb708f1e810381367fb0fa7 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 2 May 2024 15:40:13 +0200 Subject: [PATCH 167/238] Go: add explanatory comment to `extractor` `BUILD` file --- go/extractor/BUILD.bazel | 1 + 1 file changed, 1 insertion(+) diff --git a/go/extractor/BUILD.bazel b/go/extractor/BUILD.bazel index cb7bc3ac8ef2..32eaa8fda745 100644 --- a/go/extractor/BUILD.bazel +++ b/go/extractor/BUILD.bazel @@ -4,6 +4,7 @@ load("@rules_pkg//pkg:mappings.bzl", "pkg_files") # gazelle:prefix github.com/github/codeql-go/extractor # gazelle:map_kind go_binary codeql_go_binary //go:rules.bzl +# following target is kept up to date by `bazel run //go:gen`, do not edit directly go_library( name = "extractor", srcs = [ From 0bc6934bfc210d7efc2f87966ab13cae710a82a0 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 2 May 2024 15:44:06 +0200 Subject: [PATCH 168/238] Go: rename `pkg_files` to something less confusing --- go/codeql-tools/BUILD.bazel | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/go/codeql-tools/BUILD.bazel b/go/codeql-tools/BUILD.bazel index 4e839b4774b5..8c3946b24ad0 100644 --- a/go/codeql-tools/BUILD.bazel +++ b/go/codeql-tools/BUILD.bazel @@ -1,13 +1,13 @@ load("@rules_pkg//pkg:mappings.bzl", "pkg_attributes", "pkg_filegroup", "pkg_files") pkg_files( - name = "executables", + name = "sh-files", srcs = glob(["*.sh"]), attributes = pkg_attributes(mode = "0755"), ) pkg_files( - name = "non-executables", + name = "non-sh-files", srcs = glob( ["*"], exclude = [ @@ -20,8 +20,8 @@ pkg_files( pkg_filegroup( name = "codeql-tools", srcs = [ - ":executables", - ":non-executables", + ":non-sh-files", + ":sh-files", ], prefix = "tools", visibility = ["//go:__pkg__"], From abcd9165b4b9ded2c2b9c297502df24529f95561 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 2 May 2024 16:08:17 +0200 Subject: [PATCH 169/238] Go: write test go runtime version in a specific file --- .github/workflows/go-tests-other-os.yml | 10 ++++------ .github/workflows/go-tests.yml | 7 ++----- go/ql/test/go.mod | 4 ---- go/test-runtime-version/go.work | 1 + 4 files changed, 7 insertions(+), 15 deletions(-) delete mode 100644 go/ql/test/go.mod create mode 100644 go/test-runtime-version/go.work diff --git a/.github/workflows/go-tests-other-os.yml b/.github/workflows/go-tests-other-os.yml index ded53f868b70..d38fd18f2728 100644 --- a/.github/workflows/go-tests-other-os.yml +++ b/.github/workflows/go-tests-other-os.yml @@ -7,8 +7,6 @@ on: - .github/workflows/go-tests-other-os.yml - .github/actions/** - codeql-workspace.yml -env: - GO_VERSION: '~1.22.0' permissions: contents: read @@ -18,10 +16,10 @@ jobs: name: Test MacOS runs-on: macos-latest steps: - - name: Set up Go ${{ env.GO_VERSION }} + - name: Set up Go uses: actions/setup-go@v5 with: - go-version: ${{ env.GO_VERSION }} + go-version-file: go/test-runtime-version/go.work cache: false id: go @@ -55,10 +53,10 @@ jobs: name: Test Windows runs-on: windows-latest-xl steps: - - name: Set up Go ${{ env.GO_VERSION }} + - name: Set up Go uses: actions/setup-go@v5 with: - go-version: ${{ env.GO_VERSION }} + go-version-file: go/test-runtime-version/go.work cache: false id: go diff --git a/.github/workflows/go-tests.yml b/.github/workflows/go-tests.yml index 6d9cac5dae91..60182bb2c810 100644 --- a/.github/workflows/go-tests.yml +++ b/.github/workflows/go-tests.yml @@ -16,9 +16,6 @@ on: - .github/actions/** - codeql-workspace.yml -env: - GO_VERSION: '~1.22.0' - permissions: contents: read @@ -28,10 +25,10 @@ jobs: name: Test Linux (Ubuntu) runs-on: ubuntu-latest-xl steps: - - name: Set up Go ${{ env.GO_VERSION }} + - name: Set up Go uses: actions/setup-go@v5 with: - go-version: ${{ env.GO_VERSION }} + go-version-file: go/test-runtime-version/go.work cache: false id: go diff --git a/go/ql/test/go.mod b/go/ql/test/go.mod deleted file mode 100644 index 2420613ecee8..000000000000 --- a/go/ql/test/go.mod +++ /dev/null @@ -1,4 +0,0 @@ -module github.com/github/codeql-go/ql/test - -go 1.21 - diff --git a/go/test-runtime-version/go.work b/go/test-runtime-version/go.work new file mode 100644 index 000000000000..233b10082402 --- /dev/null +++ b/go/test-runtime-version/go.work @@ -0,0 +1 @@ +go 1.22 From 1aafc377adf9a809e59e3a66f24235e2671b1822 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 2 May 2024 16:22:24 +0200 Subject: [PATCH 170/238] Revert "Go: write test go runtime version in a specific file" This reverts commit abcd9165b4b9ded2c2b9c297502df24529f95561. --- .github/workflows/go-tests-other-os.yml | 10 ++++++---- .github/workflows/go-tests.yml | 7 +++++-- go/ql/test/go.mod | 4 ++++ go/test-runtime-version/go.work | 1 - 4 files changed, 15 insertions(+), 7 deletions(-) create mode 100644 go/ql/test/go.mod delete mode 100644 go/test-runtime-version/go.work diff --git a/.github/workflows/go-tests-other-os.yml b/.github/workflows/go-tests-other-os.yml index d38fd18f2728..ded53f868b70 100644 --- a/.github/workflows/go-tests-other-os.yml +++ b/.github/workflows/go-tests-other-os.yml @@ -7,6 +7,8 @@ on: - .github/workflows/go-tests-other-os.yml - .github/actions/** - codeql-workspace.yml +env: + GO_VERSION: '~1.22.0' permissions: contents: read @@ -16,10 +18,10 @@ jobs: name: Test MacOS runs-on: macos-latest steps: - - name: Set up Go + - name: Set up Go ${{ env.GO_VERSION }} uses: actions/setup-go@v5 with: - go-version-file: go/test-runtime-version/go.work + go-version: ${{ env.GO_VERSION }} cache: false id: go @@ -53,10 +55,10 @@ jobs: name: Test Windows runs-on: windows-latest-xl steps: - - name: Set up Go + - name: Set up Go ${{ env.GO_VERSION }} uses: actions/setup-go@v5 with: - go-version-file: go/test-runtime-version/go.work + go-version: ${{ env.GO_VERSION }} cache: false id: go diff --git a/.github/workflows/go-tests.yml b/.github/workflows/go-tests.yml index 60182bb2c810..6d9cac5dae91 100644 --- a/.github/workflows/go-tests.yml +++ b/.github/workflows/go-tests.yml @@ -16,6 +16,9 @@ on: - .github/actions/** - codeql-workspace.yml +env: + GO_VERSION: '~1.22.0' + permissions: contents: read @@ -25,10 +28,10 @@ jobs: name: Test Linux (Ubuntu) runs-on: ubuntu-latest-xl steps: - - name: Set up Go + - name: Set up Go ${{ env.GO_VERSION }} uses: actions/setup-go@v5 with: - go-version-file: go/test-runtime-version/go.work + go-version: ${{ env.GO_VERSION }} cache: false id: go diff --git a/go/ql/test/go.mod b/go/ql/test/go.mod new file mode 100644 index 000000000000..2420613ecee8 --- /dev/null +++ b/go/ql/test/go.mod @@ -0,0 +1,4 @@ +module github.com/github/codeql-go/ql/test + +go 1.21 + diff --git a/go/test-runtime-version/go.work b/go/test-runtime-version/go.work deleted file mode 100644 index 233b10082402..000000000000 --- a/go/test-runtime-version/go.work +++ /dev/null @@ -1 +0,0 @@ -go 1.22 From 0693bf9e753ac42358faa8c3d79a1fc291f8cd8c Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 2 May 2024 15:31:28 +0100 Subject: [PATCH 171/238] C++: Improve UseOfStringAfterLifetimeEnds qhelp, references and alert message. --- .../UseOfStringAfterLifetimeEnds.qhelp | 7 +++++ .../CWE-416/UseOfStringAfterLifetimeEnds.ql | 2 +- .../UseOfStringAfterLifetimeEnds.expected | 26 +++++++++---------- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/cpp/ql/src/Security/CWE/CWE-416/UseOfStringAfterLifetimeEnds.qhelp b/cpp/ql/src/Security/CWE/CWE-416/UseOfStringAfterLifetimeEnds.qhelp index e0678c0beff2..18b3ce15d4be 100644 --- a/cpp/ql/src/Security/CWE/CWE-416/UseOfStringAfterLifetimeEnds.qhelp +++ b/cpp/ql/src/Security/CWE/CWE-416/UseOfStringAfterLifetimeEnds.qhelp @@ -8,6 +8,12 @@ When the std::string object is destroyed, the pointer returned by c_str is no longer valid. If the pointer is used after the std::string object is destroyed, then the behavior is undefined.

    + +

    Typically this problem occurs when a std::string is returned by a function call (or overloaded operator) +by value, and the result is not immediately stored in a variable by value (or const reference). The resulting +temporary std::string object is destroyed at the end of the expression statement it is contained in, along +with any memory returned by a call to c_str. +

    @@ -39,6 +45,7 @@ points to valid memory.
  • MEM50-CPP. Do not access freed memory.
  • +
  • Microsoft Learn: Temporary objects.
  • diff --git a/cpp/ql/src/Security/CWE/CWE-416/UseOfStringAfterLifetimeEnds.ql b/cpp/ql/src/Security/CWE/CWE-416/UseOfStringAfterLifetimeEnds.ql index 7d776280f917..e563991762b6 100644 --- a/cpp/ql/src/Security/CWE/CWE-416/UseOfStringAfterLifetimeEnds.ql +++ b/cpp/ql/src/Security/CWE/CWE-416/UseOfStringAfterLifetimeEnds.ql @@ -23,4 +23,4 @@ where (c.getTarget() instanceof StdStringCStr or c.getTarget() instanceof StdStringData) and isTemporary(c.getQualifier().getFullyConverted()) select c, - "The underlying string object is destroyed after the call to '" + c.getTarget() + "' returns." + "The underlying temporary string object is destroyed after the call to '" + c.getTarget() + "' returns." diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/UseOfStringAfterLifetimeEnds/UseOfStringAfterLifetimeEnds.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/UseOfStringAfterLifetimeEnds/UseOfStringAfterLifetimeEnds.expected index e6f64d57c994..1949ae5c3980 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/UseOfStringAfterLifetimeEnds/UseOfStringAfterLifetimeEnds.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/UseOfStringAfterLifetimeEnds/UseOfStringAfterLifetimeEnds.expected @@ -1,13 +1,13 @@ -| test.cpp:165:34:165:38 | call to c_str | The underlying string object is destroyed after the call to 'c_str' returns. | -| test.cpp:166:39:166:43 | call to c_str | The underlying string object is destroyed after the call to 'c_str' returns. | -| test.cpp:167:44:167:48 | call to c_str | The underlying string object is destroyed after the call to 'c_str' returns. | -| test.cpp:169:29:169:33 | call to c_str | The underlying string object is destroyed after the call to 'c_str' returns. | -| test.cpp:178:37:178:41 | call to c_str | The underlying string object is destroyed after the call to 'c_str' returns. | -| test.cpp:181:39:181:43 | call to c_str | The underlying string object is destroyed after the call to 'c_str' returns. | -| test.cpp:183:37:183:41 | call to c_str | The underlying string object is destroyed after the call to 'c_str' returns. | -| test.cpp:187:34:187:37 | call to data | The underlying string object is destroyed after the call to 'data' returns. | -| test.cpp:188:39:188:42 | call to data | The underlying string object is destroyed after the call to 'data' returns. | -| test.cpp:189:44:189:47 | call to data | The underlying string object is destroyed after the call to 'data' returns. | -| test.cpp:191:29:191:32 | call to data | The underlying string object is destroyed after the call to 'data' returns. | -| test.cpp:193:47:193:51 | call to c_str | The underlying string object is destroyed after the call to 'c_str' returns. | -| test.cpp:195:31:195:35 | call to c_str | The underlying string object is destroyed after the call to 'c_str' returns. | +| test.cpp:165:34:165:38 | call to c_str | The underlying temporary string object is destroyed after the call to 'c_str' returns. | +| test.cpp:166:39:166:43 | call to c_str | The underlying temporary string object is destroyed after the call to 'c_str' returns. | +| test.cpp:167:44:167:48 | call to c_str | The underlying temporary string object is destroyed after the call to 'c_str' returns. | +| test.cpp:169:29:169:33 | call to c_str | The underlying temporary string object is destroyed after the call to 'c_str' returns. | +| test.cpp:178:37:178:41 | call to c_str | The underlying temporary string object is destroyed after the call to 'c_str' returns. | +| test.cpp:181:39:181:43 | call to c_str | The underlying temporary string object is destroyed after the call to 'c_str' returns. | +| test.cpp:183:37:183:41 | call to c_str | The underlying temporary string object is destroyed after the call to 'c_str' returns. | +| test.cpp:187:34:187:37 | call to data | The underlying temporary string object is destroyed after the call to 'data' returns. | +| test.cpp:188:39:188:42 | call to data | The underlying temporary string object is destroyed after the call to 'data' returns. | +| test.cpp:189:44:189:47 | call to data | The underlying temporary string object is destroyed after the call to 'data' returns. | +| test.cpp:191:29:191:32 | call to data | The underlying temporary string object is destroyed after the call to 'data' returns. | +| test.cpp:193:47:193:51 | call to c_str | The underlying temporary string object is destroyed after the call to 'c_str' returns. | +| test.cpp:195:31:195:35 | call to c_str | The underlying temporary string object is destroyed after the call to 'c_str' returns. | From b8b36892511c6b926953bdaa738683837aec8f20 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 2 May 2024 15:49:56 +0100 Subject: [PATCH 172/238] C++: Autoformat. --- .../src/Security/CWE/CWE-416/UseOfStringAfterLifetimeEnds.ql | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cpp/ql/src/Security/CWE/CWE-416/UseOfStringAfterLifetimeEnds.ql b/cpp/ql/src/Security/CWE/CWE-416/UseOfStringAfterLifetimeEnds.ql index e563991762b6..982486759082 100644 --- a/cpp/ql/src/Security/CWE/CWE-416/UseOfStringAfterLifetimeEnds.ql +++ b/cpp/ql/src/Security/CWE/CWE-416/UseOfStringAfterLifetimeEnds.ql @@ -23,4 +23,5 @@ where (c.getTarget() instanceof StdStringCStr or c.getTarget() instanceof StdStringData) and isTemporary(c.getQualifier().getFullyConverted()) select c, - "The underlying temporary string object is destroyed after the call to '" + c.getTarget() + "' returns." + "The underlying temporary string object is destroyed after the call to '" + c.getTarget() + + "' returns." From e4cf7df38f48a10529938558fc98e6492f7d4ad5 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 2 May 2024 15:59:22 +0100 Subject: [PATCH 173/238] C++: Edits to the .qhelp based on suggestions. --- .../CWE/CWE-416/UseOfStringAfterLifetimeEnds.qhelp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cpp/ql/src/Security/CWE/CWE-416/UseOfStringAfterLifetimeEnds.qhelp b/cpp/ql/src/Security/CWE/CWE-416/UseOfStringAfterLifetimeEnds.qhelp index 18b3ce15d4be..5ab82834b408 100644 --- a/cpp/ql/src/Security/CWE/CWE-416/UseOfStringAfterLifetimeEnds.qhelp +++ b/cpp/ql/src/Security/CWE/CWE-416/UseOfStringAfterLifetimeEnds.qhelp @@ -10,9 +10,9 @@ longer valid. If the pointer is used after the std::string object i

    Typically this problem occurs when a std::string is returned by a function call (or overloaded operator) -by value, and the result is not immediately stored in a variable by value (or const reference). The resulting -temporary std::string object is destroyed at the end of the expression statement it is contained in, along -with any memory returned by a call to c_str. +by value, and the result is not immediately stored in a variable by value or reference in a way that extends the lifetime of +the temporary object. The resulting temporary std::string object is destroyed at the end of the expression +statement it is contained in, along with any memory returned by a call to c_str.

    @@ -46,6 +46,7 @@ points to valid memory.
  • MEM50-CPP. Do not access freed memory.
  • Microsoft Learn: Temporary objects.
  • +
  • cppreference.com: Lifetime of a temporary.
  • From 76067cb12d88fdd761ac4dbfbd85eada52415977 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 2 May 2024 17:02:48 +0200 Subject: [PATCH 174/238] Go: skip `X:nocoverageredesign` printing by autobuilder built with bazel --- go/extractor/cli/go-autobuilder/go-autobuilder.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/go/extractor/cli/go-autobuilder/go-autobuilder.go b/go/extractor/cli/go-autobuilder/go-autobuilder.go index 08f8477cac7b..8df8b5069189 100644 --- a/go/extractor/cli/go-autobuilder/go-autobuilder.go +++ b/go/extractor/cli/go-autobuilder/go-autobuilder.go @@ -487,7 +487,9 @@ func extract(workspace project.GoWorkspace) bool { // Build the project and run the extractor. func installDependenciesAndBuild() { - log.Printf("Autobuilder was built with %s, environment has %s\n", runtime.Version(), toolchain.GetEnvGoVersion()) + // do not print experiments the autobuilder was built with if any, only the version + version := strings.SplitN(runtime.Version(), " ", 2)[0] + log.Printf("Autobuilder was built with %s, environment has %s\n", version, toolchain.GetEnvGoVersion()) srcdir := getSourceDir() From 00baccbc152af091936983ba111d0f5cc3b46c46 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 2 May 2024 17:08:23 +0200 Subject: [PATCH 175/238] Go: autoformat --- go/extractor/cli/go-autobuilder/go-autobuilder.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go/extractor/cli/go-autobuilder/go-autobuilder.go b/go/extractor/cli/go-autobuilder/go-autobuilder.go index 8df8b5069189..2e9731c989b8 100644 --- a/go/extractor/cli/go-autobuilder/go-autobuilder.go +++ b/go/extractor/cli/go-autobuilder/go-autobuilder.go @@ -487,8 +487,8 @@ func extract(workspace project.GoWorkspace) bool { // Build the project and run the extractor. func installDependenciesAndBuild() { - // do not print experiments the autobuilder was built with if any, only the version - version := strings.SplitN(runtime.Version(), " ", 2)[0] + // do not print experiments the autobuilder was built with if any, only the version + version := strings.SplitN(runtime.Version(), " ", 2)[0] log.Printf("Autobuilder was built with %s, environment has %s\n", version, toolchain.GetEnvGoVersion()) srcdir := getSourceDir() From 355c7d9b41f017ff54d0f8c552cbae12262ca35d Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 1 May 2024 09:29:56 +0100 Subject: [PATCH 176/238] C++: Rename an example file. --- ...ongTypeFormatArguments.cpp => WrongTypeFormatArgumentsBad.cpp} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename cpp/ql/src/Likely Bugs/Format/{WrongTypeFormatArguments.cpp => WrongTypeFormatArgumentsBad.cpp} (100%) diff --git a/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.cpp b/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArgumentsBad.cpp similarity index 100% rename from cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.cpp rename to cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArgumentsBad.cpp From e22159ab5d4e15c6b99ac236303d5b380c1fb06d Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 2 May 2024 14:20:02 +0100 Subject: [PATCH 177/238] C++: Update WrongTypeFormatArguments.qhelp. --- .../Format/WrongTypeFormatArguments.qhelp | 25 +++++++++++-------- .../Format/WrongTypeFormatArgumentsBad.cpp | 2 +- .../Format/WrongTypeFormatArgumentsGood.cpp | 4 +++ 3 files changed, 20 insertions(+), 11 deletions(-) create mode 100644 cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArgumentsGood.cpp diff --git a/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.qhelp b/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.qhelp index 02bfd391a330..6b3393febe10 100644 --- a/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.qhelp +++ b/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.qhelp @@ -4,29 +4,34 @@

    Each call to the printf function or a related function should include -the type and sequence of arguments defined by the format. If the function is passed arguments +the type and sequence of arguments defined by the format. If the function is passed arguments of a different type or in a different sequence then the arguments are reinterpreted to fit the type and sequence expected, resulting in unpredictable behavior.

    -

    Review the format and arguments expected by the highlighted function calls. Update either -the format or the arguments so that the expected type and sequence of arguments are passed to +

    Review the format and arguments expected by the highlighted function calls. Update either +the format or the arguments so that the expected type and sequence of arguments are passed to the function.

    - + - - +

    In the following example, the wrong format specifier is given for an integer format argument:

    + + -
  • CERT C Coding -Standard: FIO30-C. Exclude user input from format strings.
  • -
  • cplusplus.com: C++ Functions.
  • -
  • CRT Alphabetical Function Reference: printf, _printf_l, wprintf, _wprintf_l.
  • +

    The corrected version uses %i as the format specifier for the integer format argument:

    + +
    + +
  • Microsoft Learn: Format specification syntax: printf and wprintf functions.
  • +
  • cplusplus.com:printf
  • +
  • CERT C Coding" +Standard: FIO47-C. Use valid format strings.
  • diff --git a/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArgumentsBad.cpp b/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArgumentsBad.cpp index c3dd09c30719..046233af1b00 100644 --- a/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArgumentsBad.cpp +++ b/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArgumentsBad.cpp @@ -1,4 +1,4 @@ int main() { - printf("%s\n", 42); //printf will treat 42 as a char*, will most likely segfault + printf("%s\n", 42); // BAD: printf will treat 42 as a char*, will most likely segfault return 0; } diff --git a/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArgumentsGood.cpp b/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArgumentsGood.cpp new file mode 100644 index 000000000000..0bd3fb5c4391 --- /dev/null +++ b/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArgumentsGood.cpp @@ -0,0 +1,4 @@ +int main() { + printf("%i\n", 42); // GOOD: printf will treat 42 as an int + return 0; +} From 06d8892e03008533712bcabfbd94daae4d335567 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 2 May 2024 14:22:27 +0100 Subject: [PATCH 178/238] C++: Rename an example file. --- .../{StrncpyFlippedArgs.cpp => StrncpyFlippedArgsBad.cpp} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename cpp/ql/src/Likely Bugs/Memory Management/{StrncpyFlippedArgs.cpp => StrncpyFlippedArgsBad.cpp} (100%) diff --git a/cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgs.cpp b/cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgsBad.cpp similarity index 100% rename from cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgs.cpp rename to cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgsBad.cpp From 315f4391358d5b546a062e47c09c373bcb0ff34d Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 2 May 2024 14:55:53 +0100 Subject: [PATCH 179/238] C++: Add test case for reassignment to UseAfterFree.ql. --- .../Critical/MemoryFreed/MemoryFreed.expected | 2 ++ .../Critical/MemoryFreed/UseAfterFree.expected | 8 ++++++++ .../query-tests/Critical/MemoryFreed/test.cpp | 18 +++++++++++++++++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryFreed.expected b/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryFreed.expected index 46e30cedf3e3..87b5ee6c4abd 100644 --- a/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryFreed.expected +++ b/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryFreed.expected @@ -26,6 +26,8 @@ | test.cpp:128:15:128:16 | v4 | | test.cpp:185:10:185:12 | cpy | | test.cpp:199:10:199:12 | cpy | +| test.cpp:208:7:208:7 | a | +| test.cpp:214:7:214:7 | a | | test_free.cpp:11:10:11:10 | a | | test_free.cpp:14:10:14:10 | a | | test_free.cpp:16:10:16:10 | a | diff --git a/cpp/ql/test/query-tests/Critical/MemoryFreed/UseAfterFree.expected b/cpp/ql/test/query-tests/Critical/MemoryFreed/UseAfterFree.expected index 7625783731a3..9df8e932bfc2 100644 --- a/cpp/ql/test/query-tests/Critical/MemoryFreed/UseAfterFree.expected +++ b/cpp/ql/test/query-tests/Critical/MemoryFreed/UseAfterFree.expected @@ -1,4 +1,6 @@ edges +| test.cpp:208:7:208:7 | pointer to free output argument | test.cpp:209:2:209:2 | a | provenance | | +| test.cpp:214:7:214:7 | pointer to free output argument | test.cpp:215:2:215:2 | a | provenance | | | test_free.cpp:11:10:11:10 | pointer to free output argument | test_free.cpp:12:5:12:5 | a | provenance | | | test_free.cpp:11:10:11:10 | pointer to free output argument | test_free.cpp:13:5:13:6 | * ... | provenance | | | test_free.cpp:42:27:42:27 | pointer to free output argument | test_free.cpp:45:5:45:5 | a | provenance | | @@ -31,6 +33,10 @@ edges | test_free.cpp:322:12:322:12 | pointer to operator delete output argument | test_free.cpp:324:5:324:6 | * ... | provenance | | | test_free.cpp:331:12:331:12 | pointer to operator delete output argument | test_free.cpp:332:5:332:6 | * ... | provenance | | nodes +| test.cpp:208:7:208:7 | pointer to free output argument | semmle.label | pointer to free output argument | +| test.cpp:209:2:209:2 | a | semmle.label | a | +| test.cpp:214:7:214:7 | pointer to free output argument | semmle.label | pointer to free output argument | +| test.cpp:215:2:215:2 | a | semmle.label | a | | test_free.cpp:11:10:11:10 | pointer to free output argument | semmle.label | pointer to free output argument | | test_free.cpp:12:5:12:5 | a | semmle.label | a | | test_free.cpp:13:5:13:6 | * ... | semmle.label | * ... | @@ -82,6 +88,8 @@ nodes | test_free.cpp:332:5:332:6 | * ... | semmle.label | * ... | subpaths #select +| test.cpp:209:2:209:2 | a | test.cpp:208:7:208:7 | pointer to free output argument | test.cpp:209:2:209:2 | a | Memory may have been previously freed by $@. | test.cpp:208:2:208:5 | call to free | call to free | +| test.cpp:215:2:215:2 | a | test.cpp:214:7:214:7 | pointer to free output argument | test.cpp:215:2:215:2 | a | Memory may have been previously freed by $@. | test.cpp:214:2:214:5 | call to free | call to free | | test_free.cpp:12:5:12:5 | a | test_free.cpp:11:10:11:10 | pointer to free output argument | test_free.cpp:12:5:12:5 | a | Memory may have been previously freed by $@. | test_free.cpp:11:5:11:8 | call to free | call to free | | test_free.cpp:13:5:13:6 | * ... | test_free.cpp:11:10:11:10 | pointer to free output argument | test_free.cpp:13:5:13:6 | * ... | Memory may have been previously freed by $@. | test_free.cpp:11:5:11:8 | call to free | call to free | | test_free.cpp:45:5:45:5 | a | test_free.cpp:42:27:42:27 | pointer to free output argument | test_free.cpp:45:5:45:5 | a | Memory may have been previously freed by $@. | test_free.cpp:42:22:42:25 | call to free | call to free | diff --git a/cpp/ql/test/query-tests/Critical/MemoryFreed/test.cpp b/cpp/ql/test/query-tests/Critical/MemoryFreed/test.cpp index 4f05f9d49545..c8d21115f3fe 100644 --- a/cpp/ql/test/query-tests/Critical/MemoryFreed/test.cpp +++ b/cpp/ql/test/query-tests/Critical/MemoryFreed/test.cpp @@ -114,7 +114,7 @@ int main() mc2->method2(); delete mc2; } - + { void *v1 = malloc(100); int *i2 = (int *)malloc(100); @@ -198,3 +198,19 @@ void test_strndupa_dealloc() { char *cpy = strndupa(msg, 4); free(cpy); // BAD [NOT DETECTED] } + +// --- + +void test_reassignment() { + char *a = (char *)malloc(128); + char *b = (char *)malloc(128); + + free(a); + a[0] = 0; // BAD + + a = b; + a[0] = 0; // GOOD + + free(a); + a[0] = 0; // BAD +} From daea674095ee9be1f4bddc360e8bb41f28ba788c Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 2 May 2024 18:02:22 +0200 Subject: [PATCH 180/238] Bazel: cover standard `https` git credentials in `git_lfs_probe.py` --- misc/bazel/internal/git_lfs_probe.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/misc/bazel/internal/git_lfs_probe.py b/misc/bazel/internal/git_lfs_probe.py index 3d0ed7679a34..1e5602ec8620 100755 --- a/misc/bazel/internal/git_lfs_probe.py +++ b/misc/bazel/internal/git_lfs_probe.py @@ -27,6 +27,7 @@ def get_endpoint(): endpoint = ssh_server = ssh_path = None endpoint_re = re.compile(r'Endpoint(?: \(\S+\))?=(\S+)') ssh_re = re.compile(r'\s*SSH=(\S*):(.*)') + credentials_re = re.compile(r'^password=(.*)$', re.M) for line in lfs_env.splitlines(): m = endpoint_re.match(line) if m: @@ -63,6 +64,15 @@ def get_endpoint(): headers[k.capitalize()] = v if "GITHUB_TOKEN" in os.environ: headers["Authorization"] = f"token {os.environ['GITHUB_TOKEN']}" + if "Authorization" not in headers: + credentials = subprocess.run(["git", "credential", "fill"], cwd=source_dir, stdout=subprocess.PIPE, text=True, + input=f"protocol={url.scheme}\nhost={url.netloc}\npath={url.path[1:]}\n", + check=True).stdout + m = credentials_re.search(credentials) + if m: + headers["Authorization"] = f"token {m[1]}" + else: + print(f"WARNING: no auth credentials found for {endpoint}") return endpoint, headers From 8a261b7e7a2ac760daa54dd126f13fcf78290a0a Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 2 May 2024 14:31:26 +0100 Subject: [PATCH 181/238] C++: Update StrncpyFlippedArgs.qhelp. --- .../Memory Management/StrncpyFlippedArgs.qhelp | 9 +++++++-- .../Memory Management/StrncpyFlippedArgsBad.cpp | 11 +++++++++-- .../Memory Management/StrncpyFlippedArgsGood.cpp | 10 ++++++++++ 3 files changed, 26 insertions(+), 4 deletions(-) create mode 100644 cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgsGood.cpp diff --git a/cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgs.qhelp b/cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgs.qhelp index 2e297116710f..9ba2b7c7c8e9 100644 --- a/cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgs.qhelp +++ b/cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgs.qhelp @@ -3,7 +3,7 @@ "qhelp.dtd"> -

    The standard library function strncpy copies a source string to a destination buffer. The third argument defines the maximum number of characters to copy and should be less than +

    The standard library function strncpy copies a source string to a destination buffer. The third argument defines the maximum number of characters to copy and should be less than or equal to the size of the destination buffer. Calls of the form strncpy(dest, src, strlen(src)) or strncpy(dest, src, sizeof(src)) incorrectly set the third argument to the size of the source buffer. Executing a call of this type may cause a buffer overflow. Buffer overflows can lead to anything from a segmentation fault to a security vulnerability.

    @@ -12,9 +12,14 @@ or equal to the size of the destination buffer. Calls of the form strncpy( not the source buffer.

    - +

    In the following examples, the size of the source buffer is incorrectly used as a parameter to strncpy:

    + + +

    The corrected version uses the size of the destination buffer, or a variable containing the size of the destination buffer as the size parameter to strncpy:

    + + diff --git a/cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgsBad.cpp b/cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgsBad.cpp index 07acc91cd5ac..952550b26382 100644 --- a/cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgsBad.cpp +++ b/cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgsBad.cpp @@ -1,2 +1,9 @@ -strncpy(dest, src, sizeof(src)); //wrong: size of dest should be used -strncpy(dest, src, strlen(src)); //wrong: size of dest should be used +char src[256]; +char dest1[128]; + +... + +strncpy(dest1, src, sizeof(src)); // wrong: size of dest should be used + +char *dest2 = (char *)malloc(sz1 + sz2 + sz3); +strncpy(dest2, src, strlen(src)); // wrong: size of dest should be used diff --git a/cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgsGood.cpp b/cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgsGood.cpp new file mode 100644 index 000000000000..22fc4ebd2220 --- /dev/null +++ b/cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgsGood.cpp @@ -0,0 +1,10 @@ +char src[256]; +char dest1[128]; + +... + +strncpy(dest1, src, sizeof(dest1)); // correct + +size_t destSize = sz1 + sz2 + sz3; +char *dest2 = (char *)malloc(destSize); +strncpy(dest2, src, destSize); // correct From 8f682ef4e4fd492169f384da3fc03f44fe3753e6 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 2 May 2024 14:17:11 +0100 Subject: [PATCH 182/238] C++: Improve quality of some qhelp references. --- .../src/Likely Bugs/Format/TooManyFormatArguments.qhelp | 4 +--- .../Format/WrongNumberOfFormatArguments.qhelp | 9 +++------ .../Likely Bugs/Format/WrongTypeFormatArguments.qhelp | 3 +-- 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/cpp/ql/src/Likely Bugs/Format/TooManyFormatArguments.qhelp b/cpp/ql/src/Likely Bugs/Format/TooManyFormatArguments.qhelp index bbd64254d54c..b4df60cbac72 100644 --- a/cpp/ql/src/Likely Bugs/Format/TooManyFormatArguments.qhelp +++ b/cpp/ql/src/Likely Bugs/Format/TooManyFormatArguments.qhelp @@ -22,10 +22,8 @@ function.
    -
  • cplusplus.com: C++ Functions.
  • +
  • CERT C Coding Standard: FIO47-C. Use valid format strings.
  • Microsoft C Runtime Library Reference: printf, wprintf.
  • - -
    diff --git a/cpp/ql/src/Likely Bugs/Format/WrongNumberOfFormatArguments.qhelp b/cpp/ql/src/Likely Bugs/Format/WrongNumberOfFormatArguments.qhelp index 66344e93f22d..bb4687b2d9a7 100644 --- a/cpp/ql/src/Likely Bugs/Format/WrongNumberOfFormatArguments.qhelp +++ b/cpp/ql/src/Likely Bugs/Format/WrongNumberOfFormatArguments.qhelp @@ -19,8 +19,8 @@ contents. -

    Review the format and arguments expected by the highlighted function calls. Update either -the format or the arguments so that the expected number of arguments are passed to the +

    Review the format and arguments expected by the highlighted function calls. Update either +the format or the arguments so that the expected number of arguments are passed to the function.

    @@ -30,11 +30,8 @@ function. -
  • CERT C Coding -Standard: FIO30-C. Exclude user input from format strings.
  • -
  • cplusplus.com: C++ Functions.
  • +
  • CERT C Coding Standard: FIO47-C. Use valid format strings.
  • Microsoft C Runtime Library Reference: printf, wprintf.
  • -
    diff --git a/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.qhelp b/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.qhelp index 6b3393febe10..476d37fb300e 100644 --- a/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.qhelp +++ b/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.qhelp @@ -30,8 +30,7 @@ the function.
  • Microsoft Learn: Format specification syntax: printf and wprintf functions.
  • cplusplus.com:printf
  • -
  • CERT C Coding" -Standard: FIO47-C. Use valid format strings.
  • +
  • CERT C Coding Standard: FIO47-C. Use valid format strings.
  • From f4e4e238ba2da04b4a55cb81218084f7398d3981 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 2 May 2024 16:09:03 +0100 Subject: [PATCH 183/238] C++: Add test cases for IncorrectNotOperatorUsage.ql. --- .../IncorrectNotOperatorUsage.cpp | 5 ++--- .../IncorrectNotOperatorUsage.cpp | 21 ++++++++++++++++++- .../IncorrectNotOperatorUsage.expected | 1 + 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.cpp b/cpp/ql/src/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.cpp index c3640a66ab6f..c345e5a88a99 100644 --- a/cpp/ql/src/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.cpp +++ b/cpp/ql/src/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.cpp @@ -4,17 +4,16 @@ void f_warning(int i) { // The usage of the logical not operator in this case is unlikely to be correct // as the output is being used as an operator for a bit-wise and operation - if (i & !FLAGS) + if (i & !FLAGS) { // code } } - void f_fixed(int i) { if (i & ~FLAGS) // Changing the logical not operator for the bit-wise not operator would fix this logic { // code } -} \ No newline at end of file +} diff --git a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage/IncorrectNotOperatorUsage.cpp b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage/IncorrectNotOperatorUsage.cpp index 90c21ca90f3b..ac3f1ab3ed5c 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage/IncorrectNotOperatorUsage.cpp +++ b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage/IncorrectNotOperatorUsage.cpp @@ -3,7 +3,7 @@ void C6317_positive(int i) { - if (i & !FLAGS) // BUG + if (i & !FLAGS) // BUG { } } @@ -71,3 +71,22 @@ void macroUsage(unsigned int arg1, unsigned int arg2) } } + +void bool_examples(bool a, bool b) +{ + if (a & !b) // dubious (confusing intent, but shouldn't produce a wrong result) + { + } + + if (a & ~b) + { + } + + if (a && ~b) + { + } + + if (a && !b) + { + } +} diff --git a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage/IncorrectNotOperatorUsage.expected b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage/IncorrectNotOperatorUsage.expected index a5bbea858da3..9c6d4154bf5e 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage/IncorrectNotOperatorUsage.expected +++ b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage/IncorrectNotOperatorUsage.expected @@ -14,3 +14,4 @@ | IncorrectNotOperatorUsage.cpp:48:9:48:18 | ... \| ... | Usage of a logical not (!) expression as a bitwise operator. | | IncorrectNotOperatorUsage.cpp:49:9:49:20 | ... \| ... | Usage of a logical not (!) expression as a bitwise operator. | | IncorrectNotOperatorUsage.cpp:70:10:70:34 | ... \| ... | Usage of a logical not (!) expression as a bitwise operator. | +| IncorrectNotOperatorUsage.cpp:77:9:77:14 | ... & ... | Usage of a logical not (!) expression as a bitwise operator. | From 8a04840f933cd6efba82bcba6c3c905344b07abd Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 2 May 2024 16:32:45 +0100 Subject: [PATCH 184/238] C++: Improve qhelp for IncorrectNotOperatorUsage.ql, including mention of an alternative fix. --- .../Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.cpp | 4 ++-- .../Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.qhelp | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.cpp b/cpp/ql/src/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.cpp index c345e5a88a99..29eef7c2b1f5 100644 --- a/cpp/ql/src/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.cpp +++ b/cpp/ql/src/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.cpp @@ -2,7 +2,7 @@ void f_warning(int i) { - // The usage of the logical not operator in this case is unlikely to be correct + // BAD: the usage of the logical not operator in this case is unlikely to be correct // as the output is being used as an operator for a bit-wise and operation if (i & !FLAGS) { @@ -12,7 +12,7 @@ void f_warning(int i) void f_fixed(int i) { - if (i & ~FLAGS) // Changing the logical not operator for the bit-wise not operator would fix this logic + if (i & ~FLAGS) // GOOD: Changing the logical not operator for the bit-wise not operator would fix this logic { // code } diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.qhelp b/cpp/ql/src/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.qhelp index bac09fe9cf17..bd89593d96c7 100644 --- a/cpp/ql/src/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.qhelp +++ b/cpp/ql/src/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.qhelp @@ -16,7 +16,9 @@

    Carefully inspect the flagged expressions. Consider the intent in the code logic, and decide whether it is necessary to change the not operator.

    +

    Here is an example of this issue and how it can be fixed:

    +

    In other cases, particularly when the expressions have bool type, the fix may instead be of the form a && !b

  • From 669fc925e0c562d4f880ad2039811ad4d8932b14 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 2 May 2024 17:24:20 +0100 Subject: [PATCH 185/238] C++: Fix qhelp formatting. --- .../Likely Typos/IncorrectNotOperatorUsage.qhelp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.qhelp b/cpp/ql/src/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.qhelp index bd89593d96c7..251e26d50f75 100644 --- a/cpp/ql/src/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.qhelp +++ b/cpp/ql/src/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.qhelp @@ -16,9 +16,13 @@

    Carefully inspect the flagged expressions. Consider the intent in the code logic, and decide whether it is necessary to change the not operator.

    +

    Here is an example of this issue and how it can be fixed:

    - + + +

    In other cases, particularly when the expressions have bool type, the fix may instead be of the form a && !b

    +
  • From ecbf7aef181553960e87b231c1668655106183c8 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 2 May 2024 17:26:24 +0100 Subject: [PATCH 186/238] C++: Fix qhelp formatting. --- .../Likely Bugs/Memory Management/StrncpyFlippedArgs.qhelp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgs.qhelp b/cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgs.qhelp index 9ba2b7c7c8e9..4ef13551ad29 100644 --- a/cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgs.qhelp +++ b/cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgs.qhelp @@ -13,15 +13,16 @@ not the source buffer.

    +

    In the following examples, the size of the source buffer is incorrectly used as a parameter to strncpy:

    - +

    The corrected version uses the size of the destination buffer, or a variable containing the size of the destination buffer as the size parameter to strncpy:

    - - + +
  • cplusplus.com: strncpy.
  • From 657402b42f06ef5d6278c2a0cce0f6f2272beab7 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 2 May 2024 17:31:09 +0100 Subject: [PATCH 187/238] C++: Fix % character in qhelp. --- cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.qhelp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.qhelp b/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.qhelp index 476d37fb300e..055adeb741f3 100644 --- a/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.qhelp +++ b/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.qhelp @@ -21,7 +21,7 @@ the function. -

    The corrected version uses %i as the format specifier for the integer format argument:

    +

    The corrected version uses %i as the format specifier for the integer format argument:

    From 08e08a2b3ac4dcdf31896ac4f8841a17328dbbfc Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 2 May 2024 17:32:24 +0100 Subject: [PATCH 188/238] C++: Qhelp punctuation. --- .../Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.qhelp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.qhelp b/cpp/ql/src/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.qhelp index 251e26d50f75..a33685bdb6fb 100644 --- a/cpp/ql/src/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.qhelp +++ b/cpp/ql/src/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.qhelp @@ -21,7 +21,7 @@ -

    In other cases, particularly when the expressions have bool type, the fix may instead be of the form a && !b

    +

    In other cases, particularly when the expressions have bool type, the fix may instead be of the form a && !b

    . From 73cc211779611c30afe5879746edb68eaa43baa5 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 2 May 2024 17:36:35 +0100 Subject: [PATCH 189/238] C++: Fix qhelp error. --- .../Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.qhelp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.qhelp b/cpp/ql/src/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.qhelp index a33685bdb6fb..3b5824c314a3 100644 --- a/cpp/ql/src/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.qhelp +++ b/cpp/ql/src/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.qhelp @@ -21,7 +21,7 @@ -

    In other cases, particularly when the expressions have bool type, the fix may instead be of the form a && !b

    . +

    In other cases, particularly when the expressions have bool type, the fix may instead be of the form a && !b.

    From f5431abb1095ecf3ca9a27d4f7c8ad92bfc47995 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 2 May 2024 17:37:52 +0100 Subject: [PATCH 190/238] C++: Fix strncpy reference link (the old link was broken). --- .../src/Likely Bugs/Memory Management/StrncpyFlippedArgs.qhelp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgs.qhelp b/cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgs.qhelp index 4ef13551ad29..201b9057499a 100644 --- a/cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgs.qhelp +++ b/cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgs.qhelp @@ -25,7 +25,7 @@ not the source buffer.

    -
  • cplusplus.com: strncpy.
  • +
  • cplusplus.com: strncpy.
  • I. Gerg. An Overview and Example of the Buffer-Overflow Exploit. IANewsletter vol 7 no 4. 2005.
  • From ecdf62376d9ad93e4e0e2e2f1f66ad94a9248327 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 3 May 2024 09:11:28 +0200 Subject: [PATCH 191/238] Bazel: clean up `git_lfs_probe.py` --- misc/bazel/internal/git_lfs_probe.py | 112 +++++++++++++-------------- 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/misc/bazel/internal/git_lfs_probe.py b/misc/bazel/internal/git_lfs_probe.py index 1e5602ec8620..cde509af7119 100755 --- a/misc/bazel/internal/git_lfs_probe.py +++ b/misc/bazel/internal/git_lfs_probe.py @@ -16,74 +16,78 @@ import urllib.request from urllib.parse import urlparse import re +import base64 +from dataclasses import dataclass + + +@dataclass +class Endpoint: + href: str + headers: dict[str, str] + + def update_headers(self, d: dict[str, str]): + self.headers.update((k.capitalize(), v) for k, v in d.items()) + sources = [pathlib.Path(arg).resolve() for arg in sys.argv[1:]] source_dir = pathlib.Path(os.path.commonpath(src.parent for src in sources)) source_dir = subprocess.check_output(["git", "rev-parse", "--show-toplevel"], cwd=source_dir, text=True).strip() +def get_env(s, sep="="): + ret = {} + for m in re.finditer(fr'(.*?){sep}(.*)', s, re.M): + ret.setdefault(*m.groups()) + return ret + + +def git(*args, **kwargs): + return subprocess.run(("git",) + args, stdout=subprocess.PIPE, text=True, cwd=source_dir, **kwargs).stdout.strip() + + def get_endpoint(): - lfs_env = subprocess.check_output(["git", "lfs", "env"], text=True, cwd=source_dir) - endpoint = ssh_server = ssh_path = None - endpoint_re = re.compile(r'Endpoint(?: \(\S+\))?=(\S+)') - ssh_re = re.compile(r'\s*SSH=(\S*):(.*)') - credentials_re = re.compile(r'^password=(.*)$', re.M) - for line in lfs_env.splitlines(): - m = endpoint_re.match(line) - if m: - if endpoint is None: - endpoint = m[1] - else: - break - m = ssh_re.match(line) - if m: - ssh_server, ssh_path = m.groups() - break - assert endpoint, f"no Endpoint= line found in git lfs env:\n{lfs_env}" - headers = { + lfs_env = get_env(subprocess.check_output(["git", "lfs", "env"], text=True, cwd=source_dir)) + endpoint = next(v for k, v in lfs_env.items() if k.startswith('Endpoint')) + endpoint, _, _ = endpoint.partition(' ') + ssh_endpoint = lfs_env.get(" SSH") + endpoint = Endpoint(endpoint, { "Content-Type": "application/vnd.git-lfs+json", "Accept": "application/vnd.git-lfs+json", - } - if ssh_server: + }) + if ssh_endpoint: + # see https://github.com/git-lfs/git-lfs/blob/main/docs/api/authentication.md + server, _, path = ssh_endpoint.partition(":") ssh_command = shutil.which(os.environ.get("GIT_SSH", os.environ.get("GIT_SSH_COMMAND", "ssh"))) assert ssh_command, "no ssh command found" - with subprocess.Popen([ssh_command, ssh_server, "git-lfs-authenticate", ssh_path, "download"], - stdout=subprocess.PIPE) as ssh: - resp = json.load(ssh.stdout) - assert ssh.wait() == 0, "ssh command failed" - endpoint = resp.get("href", endpoint) - for k, v in resp.get("header", {}).items(): - headers[k.capitalize()] = v - url = urlparse(endpoint) + resp = json.loads(subprocess.check_output([ssh_command, server, "git-lfs-authenticate", path, "download"])) + endpoint.href = resp.get("href", endpoint) + endpoint.update_headers(resp.get("header", {})) + url = urlparse(endpoint.href) # this is how actions/checkout persist credentials # see https://github.com/actions/checkout/blob/44c2b7a8a4ea60a981eaca3cf939b5f4305c123b/src/git-auth-helper.ts#L56-L63 - auth = subprocess.run(["git", "config", f"http.{url.scheme}://{url.netloc}/.extraheader"], text=True, - stdout=subprocess.PIPE, cwd=source_dir).stdout.strip() - for l in auth.splitlines(): - k, _, v = l.partition(": ") - headers[k.capitalize()] = v + auth = git("config", f"http.{url.scheme}://{url.netloc}/.extraheader") + endpoint.update_headers(get_env(auth, sep=": ")) if "GITHUB_TOKEN" in os.environ: - headers["Authorization"] = f"token {os.environ['GITHUB_TOKEN']}" - if "Authorization" not in headers: - credentials = subprocess.run(["git", "credential", "fill"], cwd=source_dir, stdout=subprocess.PIPE, text=True, - input=f"protocol={url.scheme}\nhost={url.netloc}\npath={url.path[1:]}\n", - check=True).stdout - m = credentials_re.search(credentials) - if m: - headers["Authorization"] = f"token {m[1]}" - else: - print(f"WARNING: no auth credentials found for {endpoint}") - return endpoint, headers + endpoint.headers["Authorization"] = f"token {os.environ['GITHUB_TOKEN']}" + if "Authorization" not in endpoint.headers: + # last chance: use git credentials (possibly backed by a credential helper like the one installed by gh) + # see https://git-scm.com/docs/git-credential + credentials = get_env(git("credential", "fill", check=True, + # drop leading / from url.path + input=f"protocol={url.scheme}\nhost={url.netloc}\npath={url.path[1:]}\n")) + auth = base64.b64encode(f'{credentials["username"]}:{credentials["password"]}'.encode()).decode('ascii') + endpoint.headers["Authorization"] = f"Basic {auth}" + return endpoint # see https://github.com/git-lfs/git-lfs/blob/310d1b4a7d01e8d9d884447df4635c7a9c7642c2/docs/api/basic-transfers.md def get_locations(objects): - href, headers = get_endpoint() + endpoint = get_endpoint() indexes = [i for i, o in enumerate(objects) if o] ret = ["local" for _ in objects] req = urllib.request.Request( - f"{href}/objects/batch", - headers=headers, + f"{endpoint.href}/objects/batch", + headers=endpoint.headers, data=json.dumps({ "operation": "download", "transfers": ["basic"], @@ -93,7 +97,7 @@ def get_locations(objects): ) with urllib.request.urlopen(req) as resp: data = json.load(resp) - assert len(data["objects"]) == len(indexes), data + assert len(data["objects"]) == len(indexes), f"received {len(data)} objects, expected {len(indexes)}" for i, resp in zip(indexes, data["objects"]): ret[i] = f'{resp["oid"]} {resp["actions"]["download"]["href"]}' return ret @@ -106,14 +110,10 @@ def get_lfs_object(path): sha256 = size = None if lfs_header != actual_header: return None - for line in fileobj: - line = line.decode('ascii').strip() - if line.startswith("oid sha256:"): - sha256 = line[len("oid sha256:"):] - elif line.startswith("size "): - size = int(line[len("size "):]) - if not (sha256 and line): - raise Exception("malformed pointer file") + data = get_env(fileobj.read().decode('ascii'), sep=' ') + assert data['oid'].startswith('sha256:'), f"unknown oid type: {data['oid']}" + _, _, sha256 = data['oid'].partition(':') + size = int(data['size']) return {"oid": sha256, "size": size} From 8def1c2c137e6bedf306dff0f3769f55ac64f266 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Fri, 3 May 2024 11:09:34 +0200 Subject: [PATCH 192/238] Java: Address review comments and some other code quality improvements. --- .../semmle/code/java/dataflow/FlowSinks.qll | 2 +- .../AndroidSensitiveCommunicationQuery.qll | 4 ++-- .../CleartextStorageAndroidDatabaseQuery.qll | 8 ++++---- ...CleartextStorageAndroidFilesystemQuery.qll | 8 ++++---- .../security/CleartextStorageCookieQuery.qll | 8 ++++---- .../CleartextStorageSharedPrefsQuery.qll | 8 ++++---- .../ExternallyControlledFormatStringQuery.qll | 4 ++-- .../java/security/ImplicitPendingIntents.qll | 2 -- .../ImproperIntentVerificationQuery.qll | 14 +++----------- .../java/security/InsecureRandomnessQuery.qll | 3 ++- java/ql/lib/semmle/code/java/security/JWT.qll | 1 - .../security/SensitiveResultReceiverQuery.qll | 4 ++-- .../code/java/security/SensitiveUiQuery.qll | 4 ++-- .../java/security/StackTraceExposureQuery.qll | 6 ++---- ...TempDirLocalInformationDisclosureQuery.qll | 19 ++++++------------- .../security/WebviewDebuggingEnabledQuery.qll | 4 ++-- java/ql/lib/semmle/code/java/security/XSS.qll | 2 +- .../code/java/security/ZipSlipQuery.qll | 4 ++-- 18 files changed, 43 insertions(+), 62 deletions(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/FlowSinks.qll b/java/ql/lib/semmle/code/java/dataflow/FlowSinks.qll index 3b7fd191779c..72cd96f6745c 100644 --- a/java/ql/lib/semmle/code/java/dataflow/FlowSinks.qll +++ b/java/ql/lib/semmle/code/java/dataflow/FlowSinks.qll @@ -11,7 +11,7 @@ private import semmle.code.java.dataflow.DataFlow abstract class ApiSinkNode extends DataFlow::Node { } /** - * Add all models as data sinks. + * Add all sink models as data sinks. */ private class ApiSinkNodeExternal extends ApiSinkNode { ApiSinkNodeExternal() { sinkNode(this, _) } diff --git a/java/ql/lib/semmle/code/java/security/AndroidSensitiveCommunicationQuery.qll b/java/ql/lib/semmle/code/java/security/AndroidSensitiveCommunicationQuery.qll index 607ced09b2cf..a4f9713ac308 100644 --- a/java/ql/lib/semmle/code/java/security/AndroidSensitiveCommunicationQuery.qll +++ b/java/ql/lib/semmle/code/java/security/AndroidSensitiveCommunicationQuery.qll @@ -153,9 +153,9 @@ deprecated class SensitiveCommunicationConfig extends TaintTracking::Configurati } /** - * A class of sensitive communication sink nodes. + * A sensitive communication sink node. */ -class SensitiveCommunicationSink extends ApiSinkNode { +private class SensitiveCommunicationSink extends ApiSinkNode { SensitiveCommunicationSink() { isSensitiveBroadcastSink(this) or diff --git a/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidDatabaseQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidDatabaseQuery.qll index b4162f2c6957..5ee9248d9eb5 100644 --- a/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidDatabaseQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidDatabaseQuery.qll @@ -99,16 +99,16 @@ private predicate localDatabaseStore(DataFlow::Node database, MethodCall store) } /** - * A class of local database open method call source nodes. + * A local database open method call source node. */ -class LocalDatabaseOpenMethodCallSource extends ApiSourceNode { +private class LocalDatabaseOpenMethodCallSource extends ApiSourceNode { LocalDatabaseOpenMethodCallSource() { this.asExpr() instanceof LocalDatabaseOpenMethodCall } } /** - * A class of local database sink nodes. + * A local database sink node. */ -class LocalDatabaseSink extends ApiSinkNode { +private class LocalDatabaseSink extends ApiSinkNode { LocalDatabaseSink() { localDatabaseInput(this, _) or localDatabaseStore(this, _) } } diff --git a/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidFilesystemQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidFilesystemQuery.qll index 8b1af7b4971f..06fa83813124 100644 --- a/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidFilesystemQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidFilesystemQuery.qll @@ -82,16 +82,16 @@ private class CloseFileMethod extends Method { } /** - * A class of local file open call source nodes. + * A local file open call source node. */ -class LocalFileOpenCallSource extends ApiSourceNode { +private class LocalFileOpenCallSource extends ApiSourceNode { LocalFileOpenCallSource() { this.asExpr() instanceof LocalFileOpenCall } } /** - * A class of local file sink nodes. + * A local file sink node. */ -class LocalFileSink extends ApiSinkNode { +private class LocalFileSink extends ApiSinkNode { LocalFileSink() { filesystemInput(this, _) or closesFile(this, _) diff --git a/java/ql/lib/semmle/code/java/security/CleartextStorageCookieQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStorageCookieQuery.qll index c3684646bdd3..a36a4754584a 100644 --- a/java/ql/lib/semmle/code/java/security/CleartextStorageCookieQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CleartextStorageCookieQuery.qll @@ -40,16 +40,16 @@ private predicate cookieStore(DataFlow::Node cookie, Expr store) { } /** - * A class of cookie source nodes. + * A cookie source node. */ -class CookieSource extends ApiSourceNode { +private class CookieSource extends ApiSourceNode { CookieSource() { this.asExpr() instanceof Cookie } } /** - * A class of cookie store sink nodes. + * A cookie store sink node. */ -class CookieStoreSink extends ApiSinkNode { +private class CookieStoreSink extends ApiSinkNode { CookieStoreSink() { cookieStore(this, _) } } diff --git a/java/ql/lib/semmle/code/java/security/CleartextStorageSharedPrefsQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStorageSharedPrefsQuery.qll index 80dc2fca1f4f..f72d40106e35 100644 --- a/java/ql/lib/semmle/code/java/security/CleartextStorageSharedPrefsQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CleartextStorageSharedPrefsQuery.qll @@ -70,18 +70,18 @@ private predicate sharedPreferencesStore(DataFlow::Node editor, MethodCall m) { } /** - * A shared preferences editor method call source nodes. + * A shared preferences editor method call source node. */ -class SharedPreferencesEditorMethodCallSource extends ApiSourceNode { +private class SharedPreferencesEditorMethodCallSource extends ApiSourceNode { SharedPreferencesEditorMethodCallSource() { this.asExpr() instanceof SharedPreferencesEditorMethodCall } } /** - * A class of shared preferences sink nodes. + * A shared preferences sink node. */ -class SharedPreferencesSink extends ApiSinkNode { +private class SharedPreferencesSink extends ApiSinkNode { SharedPreferencesSink() { sharedPreferencesInput(this, _) or sharedPreferencesStore(this, _) diff --git a/java/ql/lib/semmle/code/java/security/ExternallyControlledFormatStringQuery.qll b/java/ql/lib/semmle/code/java/security/ExternallyControlledFormatStringQuery.qll index 8d6fe0426c3c..606e31a07cb7 100644 --- a/java/ql/lib/semmle/code/java/security/ExternallyControlledFormatStringQuery.qll +++ b/java/ql/lib/semmle/code/java/security/ExternallyControlledFormatStringQuery.qll @@ -6,9 +6,9 @@ private import semmle.code.java.dataflow.FlowSources private import semmle.code.java.StringFormat /** - * A class of string format sink nodes. + * A string format sink node. */ -class StringFormatSink extends ApiSinkNode { +private class StringFormatSink extends ApiSinkNode { StringFormatSink() { this.asExpr() = any(StringFormat formatCall).getFormatArgument() } } diff --git a/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll b/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll index 5c4094de3d32..a5d8f256b036 100644 --- a/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll +++ b/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll @@ -3,8 +3,6 @@ import java private import semmle.code.java.dataflow.ExternalFlow private import semmle.code.java.dataflow.FlowSources -private import semmle.code.java.dataflow.TaintTracking -private import semmle.code.java.frameworks.android.Intent private import semmle.code.java.frameworks.android.PendingIntent private newtype TPendingIntentState = diff --git a/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll b/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll index e8bfc97b0fc9..bca045bc8e42 100644 --- a/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll +++ b/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll @@ -4,7 +4,6 @@ import java import semmle.code.java.dataflow.DataFlow import semmle.code.xml.AndroidManifest import semmle.code.java.frameworks.android.Intent -private import semmle.code.java.dataflow.FlowSources /** An `onReceive` method of a `BroadcastReceiver` */ private class OnReceiveMethod extends Method { @@ -14,18 +13,11 @@ private class OnReceiveMethod extends Method { Parameter getIntentParameter() { result = this.getParameter(1) } } -/** - * A class of verified intent source nodes. - */ -class VerifiedIntentConfigSource extends ApiSourceNode { - VerifiedIntentConfigSource() { - this.asParameter() = any(OnReceiveMethod orm).getIntentParameter() - } -} - /** A configuration to detect whether the `action` of an `Intent` is checked. */ private module VerifiedIntentConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node src) { src instanceof VerifiedIntentConfigSource } + predicate isSource(DataFlow::Node src) { + src.asParameter() = any(OnReceiveMethod orm).getIntentParameter() + } predicate isSink(DataFlow::Node sink) { exists(MethodCall ma | diff --git a/java/ql/lib/semmle/code/java/security/InsecureRandomnessQuery.qll b/java/ql/lib/semmle/code/java/security/InsecureRandomnessQuery.qll index f983876d7b38..423046b6746e 100644 --- a/java/ql/lib/semmle/code/java/security/InsecureRandomnessQuery.qll +++ b/java/ql/lib/semmle/code/java/security/InsecureRandomnessQuery.qll @@ -4,6 +4,7 @@ import java private import semmle.code.java.frameworks.OpenSaml private import semmle.code.java.frameworks.Servlets private import semmle.code.java.dataflow.ExternalFlow +private import semmle.code.java.dataflow.FlowSinks private import semmle.code.java.dataflow.TaintTracking private import semmle.code.java.security.Cookies private import semmle.code.java.security.RandomQuery @@ -49,7 +50,7 @@ abstract class InsecureRandomnessSink extends DataFlow::Node { } /** * A node which sets the value of a cookie. */ -private class CookieSink extends InsecureRandomnessSink { +private class CookieSink extends InsecureRandomnessSink, ApiSinkNode { CookieSink() { this.asExpr() instanceof SetCookieValue } } diff --git a/java/ql/lib/semmle/code/java/security/JWT.qll b/java/ql/lib/semmle/code/java/security/JWT.qll index c84ebffabdbd..5ba47072dc68 100644 --- a/java/ql/lib/semmle/code/java/security/JWT.qll +++ b/java/ql/lib/semmle/code/java/security/JWT.qll @@ -1,7 +1,6 @@ /** Provides classes for working with JSON Web Token (JWT) libraries. */ import java -private import semmle.code.java.dataflow.DataFlow private import semmle.code.java.dataflow.FlowSinks private import semmle.code.java.dataflow.FlowSources diff --git a/java/ql/lib/semmle/code/java/security/SensitiveResultReceiverQuery.qll b/java/ql/lib/semmle/code/java/security/SensitiveResultReceiverQuery.qll index c0179860a01d..8269a42c5c25 100644 --- a/java/ql/lib/semmle/code/java/security/SensitiveResultReceiverQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SensitiveResultReceiverQuery.qll @@ -52,9 +52,9 @@ deprecated private class SensitiveResultReceiverConf extends TaintTracking::Conf } /** - * A class of sensitive result receiver sink nodes. + * A sensitive result receiver sink node. */ -class SensitiveResultReceiverSink extends ApiSinkNode { +private class SensitiveResultReceiverSink extends ApiSinkNode { SensitiveResultReceiverSink() { exists(ResultReceiverSendCall call | untrustedResultReceiverSend(_, call) and diff --git a/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll b/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll index f9ff3f240409..a7e76d0e2e31 100644 --- a/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll @@ -55,9 +55,9 @@ private class MaskCall extends MethodCall { } /** - * A class of text field sink nodes. + * A text field sink node. */ -class TextFieldSink extends ApiSinkNode { +private class TextFieldSink extends ApiSinkNode { TextFieldSink() { exists(SetTextCall call | this.asExpr() = call.getStringArgument() and diff --git a/java/ql/lib/semmle/code/java/security/StackTraceExposureQuery.qll b/java/ql/lib/semmle/code/java/security/StackTraceExposureQuery.qll index 5de0b0098e93..1a2fe31e8794 100644 --- a/java/ql/lib/semmle/code/java/security/StackTraceExposureQuery.qll +++ b/java/ql/lib/semmle/code/java/security/StackTraceExposureQuery.qll @@ -1,9 +1,7 @@ /** Provides predicates to reason about exposure of stack-traces. */ import java -private import semmle.code.java.dataflow.DataFlow private import semmle.code.java.dataflow.FlowSources -private import semmle.code.java.dataflow.TaintTracking private import semmle.code.java.security.InformationLeak /** @@ -97,9 +95,9 @@ predicate stringifiedStackFlowsExternally(DataFlow::Node externalExpr, Expr stac } /** - * A class of get message source nodes. + * A get message source node. */ -class GetMessageFlowSource extends ApiSourceNode { +private class GetMessageFlowSource extends ApiSourceNode { GetMessageFlowSource() { exists(Method method | this.asExpr().(MethodCall).getMethod() = method | method.hasName("getMessage") and diff --git a/java/ql/lib/semmle/code/java/security/TempDirLocalInformationDisclosureQuery.qll b/java/ql/lib/semmle/code/java/security/TempDirLocalInformationDisclosureQuery.qll index 96db99fe1b4a..f1ffcaecc515 100644 --- a/java/ql/lib/semmle/code/java/security/TempDirLocalInformationDisclosureQuery.qll +++ b/java/ql/lib/semmle/code/java/security/TempDirLocalInformationDisclosureQuery.qll @@ -30,7 +30,7 @@ private class MethodFileFileCreation extends MethodFileSystemFileCreation { /** * A dataflow node that creates a file or directory in the file system. */ -abstract private class FileCreationSink extends DataFlow::Node { } +abstract private class FileCreationSink extends ApiSinkNode { } /** * The qualifier of a call to one of `File`'s file-creating or directory-creating methods, @@ -154,17 +154,6 @@ module TempDirSystemGetPropertyToCreateConfig implements DataFlow::ConfigSig { module TempDirSystemGetPropertyToCreate = TaintTracking::Global; -/** - * A class of method file directory creation sink nodes. - */ -class MethodFileDirectoryCreationSink extends ApiSinkNode { - MethodFileDirectoryCreationSink() { - exists(MethodCall ma | ma.getMethod() instanceof MethodFileDirectoryCreation | - ma.getQualifier() = this.asExpr() - ) - } -} - /** * Configuration that tracks calls to to `mkdir` or `mkdirs` that are are directly on the temp directory system property. * Examples: @@ -184,7 +173,11 @@ module TempDirSystemGetPropertyDirectlyToMkdirConfig implements DataFlow::Config ) } - predicate isSink(DataFlow::Node node) { node instanceof MethodFileDirectoryCreationSink } + predicate isSink(DataFlow::Node node) { + exists(MethodCall ma | ma.getMethod() instanceof MethodFileDirectoryCreation | + ma.getQualifier() = node.asExpr() + ) + } predicate isBarrier(DataFlow::Node sanitizer) { isFileConstructorArgument(sanitizer.asExpr(), _, _) diff --git a/java/ql/lib/semmle/code/java/security/WebviewDebuggingEnabledQuery.qll b/java/ql/lib/semmle/code/java/security/WebviewDebuggingEnabledQuery.qll index c7fd51b1c367..f10b0132b5ac 100644 --- a/java/ql/lib/semmle/code/java/security/WebviewDebuggingEnabledQuery.qll +++ b/java/ql/lib/semmle/code/java/security/WebviewDebuggingEnabledQuery.qll @@ -46,9 +46,9 @@ deprecated class WebviewDebugEnabledConfig extends DataFlow::Configuration { } /** - * A class of webview debug sink nodes. + * A webview debug sink node. */ -class WebviewDebugSink extends ApiSinkNode { +private class WebviewDebugSink extends ApiSinkNode { WebviewDebugSink() { exists(MethodCall ma | ma.getMethod().hasQualifiedName("android.webkit", "WebView", "setWebContentsDebuggingEnabled") and diff --git a/java/ql/lib/semmle/code/java/security/XSS.qll b/java/ql/lib/semmle/code/java/security/XSS.qll index daf025141f5f..777e5fae0627 100644 --- a/java/ql/lib/semmle/code/java/security/XSS.qll +++ b/java/ql/lib/semmle/code/java/security/XSS.qll @@ -108,7 +108,7 @@ class XssVulnerableWriterSource extends MethodCall { } /** - * A class of xss vulnerable writer source nodes. + * A xss vulnerable writer source node. */ class XssVulnerableWriterSourceNode extends ApiSourceNode { XssVulnerableWriterSourceNode() { this.asExpr() instanceof XssVulnerableWriterSource } diff --git a/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll b/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll index 0ab889f73725..75e2f7000c55 100644 --- a/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll +++ b/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll @@ -23,9 +23,9 @@ private class ArchiveEntryNameMethod extends Method { } /** - * A class of entry name method source nodes. + * An entry name method source node. */ -class ArchiveEntryNameMethodSource extends ApiSourceNode { +private class ArchiveEntryNameMethodSource extends ApiSourceNode { ArchiveEntryNameMethodSource() { this.asExpr().(MethodCall).getMethod() instanceof ArchiveEntryNameMethod } From c07bf65eb6cf1dc7e29b9c467c8ffd5552d9675a Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Fri, 3 May 2024 11:13:05 +0200 Subject: [PATCH 193/238] Update java/ql/lib/semmle/code/java/dataflow/FlowSources.qll Co-authored-by: Owen Mansel-Chan <62447351+owen-mc@users.noreply.github.com> --- java/ql/lib/semmle/code/java/dataflow/FlowSources.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll b/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll index f28cc9984871..6befe289a17c 100644 --- a/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll +++ b/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll @@ -397,7 +397,7 @@ abstract class ApiSourceNode extends DataFlow::Node { } private class AddSourceNodes extends ApiSourceNode instanceof SourceNode { } /** - * Add all models as data sources. + * Add all source models as data sources. */ private class ApiSourceNodeExternal extends ApiSourceNode { ApiSourceNodeExternal() { sourceNode(this, _) } From 6cbe16e0c2faa539f1e074e4a6a7d20c9dd93cf4 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 3 May 2024 12:00:15 +0200 Subject: [PATCH 194/238] Bazel: add progress reporting --- misc/bazel/lfs.bzl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/misc/bazel/lfs.bzl b/misc/bazel/lfs.bzl index 1f9c8972923f..4ba66c9dbfc6 100644 --- a/misc/bazel/lfs.bzl +++ b/misc/bazel/lfs.bzl @@ -5,14 +5,18 @@ def lfs_smudge(repository_ctx, srcs, extract = False, stripPrefix = None): python = repository_ctx.which("python3") or repository_ctx.which("python") if not python: fail("Neither python3 nor python executables found") + repository_ctx.report_progress("querying LFS url(s) for: %s" % ", ".join([src.basename for src in srcs])) res = repository_ctx.execute([python, script] + srcs, quiet = True) if res.return_code != 0: fail("git LFS probing failed while instantiating @%s:\n%s" % (repository_ctx.name, res.stderr)) + promises = [] for src, loc in zip(srcs, res.stdout.splitlines()): if loc == "local": if extract: + repository_ctx.report_progress("extracting local %s" % src.basename) repository_ctx.extract(src, stripPrefix = stripPrefix) else: + repository_ctx.report_progress("symlinking local %s" % src.basename) repository_ctx.symlink(src, src.basename) else: sha256, _, url = loc.partition(" ") @@ -22,8 +26,10 @@ def lfs_smudge(repository_ctx, srcs, extract = False, stripPrefix = None): # it doesn't matter if file is something like some.name.zip and possible_extension == "name.zip", # download_and_extract will just append ".name.zip" its internal temporary name, so extraction works possible_extension = ".".join(src.basename.rsplit(".", 2)[-2:]) + repository_ctx.report_progress("downloading and extracting remote %s" % src.basename) repository_ctx.download_and_extract(url, sha256 = sha256, stripPrefix = stripPrefix, type = possible_extension) else: + repository_ctx.report_progress("downloading remote %s" % src.basename) repository_ctx.download(url, src.basename, sha256 = sha256) def _download_and_extract_lfs(repository_ctx): From 807e6795a7c85622bd092bd8b359ba9d648f54e8 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 3 May 2024 11:40:56 +0100 Subject: [PATCH 195/238] Apply suggestions from code review Co-authored-by: mc <42146119+mchammer01@users.noreply.github.com> --- .../Security/CWE/CWE-416/UseOfStringAfterLifetimeEnds.qhelp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cpp/ql/src/Security/CWE/CWE-416/UseOfStringAfterLifetimeEnds.qhelp b/cpp/ql/src/Security/CWE/CWE-416/UseOfStringAfterLifetimeEnds.qhelp index 5ab82834b408..3a449b4c38c3 100644 --- a/cpp/ql/src/Security/CWE/CWE-416/UseOfStringAfterLifetimeEnds.qhelp +++ b/cpp/ql/src/Security/CWE/CWE-416/UseOfStringAfterLifetimeEnds.qhelp @@ -9,10 +9,10 @@ When the std::string object is destroyed, the pointer returned by < longer valid. If the pointer is used after the std::string object is destroyed, then the behavior is undefined.

    -

    Typically this problem occurs when a std::string is returned by a function call (or overloaded operator) +

    Typically, this problem occurs when a std::string is returned by a function call (or overloaded operator) by value, and the result is not immediately stored in a variable by value or reference in a way that extends the lifetime of -the temporary object. The resulting temporary std::string object is destroyed at the end of the expression -statement it is contained in, along with any memory returned by a call to c_str. +the temporary object. The resulting temporary std::string object is destroyed at the end of the containing expression +statement, along with any memory returned by a call to c_str.

    From e64a2d6c9c318749567eccfbfa4cf6c5dc026ada Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 29 Apr 2024 13:24:32 +0200 Subject: [PATCH 196/238] C#: Align telemetry implementation with Java. --- .../security/dataflow/CodeInjectionQuery.qll | 3 +- .../dataflow/ConditionalBypassQuery.qll | 5 +- .../ExposureOfPrivateInformationQuery.qll | 3 +- .../dataflow/HardcodedCredentialsQuery.qll | 3 +- .../security/dataflow/LDAPInjectionQuery.qll | 3 +- .../security/dataflow/LogForgingQuery.qll | 3 +- .../dataflow/MissingXMLValidationQuery.qll | 3 +- .../csharp/security/dataflow/ReDoSQuery.qll | 3 +- .../security/dataflow/RegexInjectionQuery.qll | 3 +- .../dataflow/ResourceInjectionQuery.qll | 3 +- .../security/dataflow/SqlInjectionQuery.qll | 3 +- .../security/dataflow/TaintedPathQuery.qll | 3 +- .../dataflow/UnsafeDeserializationQuery.qll | 3 +- .../security/dataflow/UrlRedirectQuery.qll | 3 +- .../dataflow/XMLEntityInjectionQuery.qll | 3 +- .../security/dataflow/XPathInjectionQuery.qll | 3 +- .../csharp/security/dataflow/ZipSlipQuery.qll | 3 +- .../security/dataflow/flowsinks/AllSinks.qll | 84 ------------------- .../security/dataflow/flowsinks/ApiSinks.qll | 35 ++++++++ .../flowsinks/ExternalLocationSink.qll | 3 +- .../security/dataflow/flowsinks/FlowSinks.qll | 23 +++++ .../dataflow/flowsinks/ParallelSink.qll | 3 +- .../security/dataflow/flowsinks/Remote.qll | 3 +- .../dataflow/flowsources/AllSources.qll | 77 ----------------- .../dataflow/flowsources/ApiSources.qll | 14 ++++ .../dataflow/flowsources/FlowSources.qll | 15 ++++ csharp/ql/src/Telemetry/ExternalApi.qll | 8 +- 27 files changed, 132 insertions(+), 186 deletions(-) delete mode 100644 csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/AllSinks.qll create mode 100644 csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/ApiSinks.qll create mode 100644 csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/FlowSinks.qll delete mode 100644 csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/AllSources.qll create mode 100644 csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/ApiSources.qll diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/CodeInjectionQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/CodeInjectionQuery.qll index 1256ae5a7ee4..e33c4e37d282 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/CodeInjectionQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/CodeInjectionQuery.qll @@ -3,6 +3,7 @@ */ import csharp +private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks private import semmle.code.csharp.security.dataflow.flowsources.FlowSources private import semmle.code.csharp.frameworks.system.codedom.Compiler private import semmle.code.csharp.security.Sanitizers @@ -16,7 +17,7 @@ abstract class Source extends DataFlow::Node { } /** * A data flow sink for user input treated as code vulnerabilities. */ -abstract class Sink extends DataFlow::ExprNode { } +abstract class Sink extends ApiSinkExprNode { } /** * A sanitizer for user input treated as code vulnerabilities. diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ConditionalBypassQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ConditionalBypassQuery.qll index a8938ecc6c90..cd7119a36af5 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ConditionalBypassQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ConditionalBypassQuery.qll @@ -6,6 +6,7 @@ import csharp private import semmle.code.csharp.controlflow.Guards private import semmle.code.csharp.controlflow.BasicBlocks +private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks private import semmle.code.csharp.security.dataflow.flowsources.FlowSources private import semmle.code.csharp.frameworks.System private import semmle.code.csharp.frameworks.system.Net @@ -14,12 +15,12 @@ private import semmle.code.csharp.security.SensitiveActions /** * A data flow source for user-controlled bypass of sensitive method. */ -abstract class Source extends DataFlow::Node { } +abstract class Source extends ApiSourceNode { } /** * A data flow sink for user-controlled bypass of sensitive method. */ -abstract class Sink extends DataFlow::ExprNode { +abstract class Sink extends ApiSinkExprNode { /** Gets the 'MethodCall' which is considered sensitive. */ abstract MethodCall getSensitiveMethodCall(); } diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExposureOfPrivateInformationQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExposureOfPrivateInformationQuery.qll index 03db7fadf811..1e5f5ae82567 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExposureOfPrivateInformationQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExposureOfPrivateInformationQuery.qll @@ -3,6 +3,7 @@ */ import csharp +private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks private import semmle.code.csharp.security.dataflow.flowsources.FlowSources private import semmle.code.csharp.security.dataflow.flowsinks.ExternalLocationSink private import semmle.code.csharp.security.PrivateData @@ -15,7 +16,7 @@ abstract class Source extends DataFlow::ExprNode { } /** * A data flow sink for private information flowing unencrypted to an external location. */ -abstract class Sink extends DataFlow::ExprNode { } +abstract class Sink extends ApiSinkExprNode { } /** * A sanitizer for private information flowing unencrypted to an external location. diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/HardcodedCredentialsQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/HardcodedCredentialsQuery.qll index dd6669579e1e..63a0bb50732e 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/HardcodedCredentialsQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/HardcodedCredentialsQuery.qll @@ -9,6 +9,7 @@ private import semmle.code.csharp.frameworks.Moq private import semmle.code.csharp.frameworks.system.web.Security private import semmle.code.csharp.frameworks.system.security.cryptography.X509Certificates private import semmle.code.csharp.frameworks.Test +private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks /** * A data flow source for hard coded credentials. @@ -18,7 +19,7 @@ abstract class Source extends DataFlow::ExprNode { } /** * A data flow sink for hard coded credentials. */ -abstract class Sink extends DataFlow::ExprNode { +abstract class Sink extends ApiSinkExprNode { /** * Gets a description of this sink, including a placeholder for the sink and a placeholder for * the supplementary element. 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 58a34f7604bd..78800f392097 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/LDAPInjectionQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/LDAPInjectionQuery.qll @@ -4,6 +4,7 @@ */ import csharp +private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks private import semmle.code.csharp.security.dataflow.flowsources.FlowSources private import semmle.code.csharp.frameworks.system.DirectoryServices private import semmle.code.csharp.frameworks.system.directoryservices.Protocols @@ -18,7 +19,7 @@ abstract class Source extends DataFlow::Node { } /** * A data flow sink for unvalidated user input that is used to construct LDAP queries. */ -abstract class Sink extends DataFlow::ExprNode { } +abstract class Sink extends ApiSinkExprNode { } /** * A sanitizer for unvalidated user input that is used to construct LDAP queries. diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/LogForgingQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/LogForgingQuery.qll index ed6e69f0709c..f0153fea2d4f 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/LogForgingQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/LogForgingQuery.qll @@ -3,6 +3,7 @@ */ import csharp +private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks private import semmle.code.csharp.security.dataflow.flowsources.FlowSources private import semmle.code.csharp.frameworks.System private import semmle.code.csharp.frameworks.system.text.RegularExpressions @@ -18,7 +19,7 @@ abstract class Source extends DataFlow::Node { } /** * A data flow sink for untrusted user input used in log entries. */ -abstract class Sink extends DataFlow::ExprNode { } +abstract class Sink extends ApiSinkExprNode { } /** * A sanitizer for untrusted user input used in log entries. diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/MissingXMLValidationQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/MissingXMLValidationQuery.qll index 914239bf7d5b..b2934d31edac 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/MissingXMLValidationQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/MissingXMLValidationQuery.qll @@ -4,6 +4,7 @@ */ import csharp +private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks private import semmle.code.csharp.security.dataflow.flowsources.FlowSources private import semmle.code.csharp.frameworks.system.Xml private import semmle.code.csharp.security.Sanitizers @@ -18,7 +19,7 @@ abstract class Source extends DataFlow::Node { } * A data flow sink for untrusted user input processed as XML without validation against a known * schema. */ -abstract class Sink extends DataFlow::ExprNode { +abstract class Sink extends ApiSinkExprNode { /** Gets a string describing the reason why this is a sink. */ abstract string getReason(); } diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ReDoSQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ReDoSQuery.qll index 84d12fca0ccd..bf4fbd993233 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ReDoSQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ReDoSQuery.qll @@ -5,6 +5,7 @@ import csharp private import semmle.code.csharp.dataflow.DataFlow2 +private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks private import semmle.code.csharp.security.dataflow.flowsources.FlowSources private import semmle.code.csharp.frameworks.system.text.RegularExpressions private import semmle.code.csharp.security.Sanitizers @@ -17,7 +18,7 @@ abstract class Source extends DataFlow::Node { } /** * A data flow sink for untrusted user input used in dangerous regular expression operations. */ -abstract class Sink extends DataFlow::ExprNode { } +abstract class Sink extends ApiSinkExprNode { } /** * A sanitizer for untrusted user input used in dangerous regular expression operations. diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/RegexInjectionQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/RegexInjectionQuery.qll index 501ede13f299..1a053c29f24d 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/RegexInjectionQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/RegexInjectionQuery.qll @@ -4,6 +4,7 @@ */ import csharp +private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks private import semmle.code.csharp.security.dataflow.flowsources.FlowSources private import semmle.code.csharp.frameworks.system.text.RegularExpressions private import semmle.code.csharp.security.Sanitizers @@ -16,7 +17,7 @@ abstract class Source extends DataFlow::Node { } /** * A data flow sink for untrusted user input used to construct regular expressions. */ -abstract class Sink extends DataFlow::ExprNode { } +abstract class Sink extends ApiSinkExprNode { } /** * A sanitizer for untrusted user input used to construct regular expressions. diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ResourceInjectionQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ResourceInjectionQuery.qll index a66283de02a7..fb016dcddae6 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ResourceInjectionQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ResourceInjectionQuery.qll @@ -3,6 +3,7 @@ */ import csharp +private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks private import semmle.code.csharp.security.dataflow.flowsources.FlowSources private import semmle.code.csharp.frameworks.system.Data private import semmle.code.csharp.security.Sanitizers @@ -15,7 +16,7 @@ abstract class Source extends DataFlow::Node { } /** * A data flow sink for untrusted user input used in resource descriptors. */ -abstract class Sink extends DataFlow::ExprNode { } +abstract class Sink extends ApiSinkExprNode { } /** * A sanitizer for untrusted user input used in resource descriptors. diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/SqlInjectionQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/SqlInjectionQuery.qll index b7b198bbca0e..6473aa58e1cc 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/SqlInjectionQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/SqlInjectionQuery.qll @@ -3,6 +3,7 @@ */ import csharp +private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks private import semmle.code.csharp.security.dataflow.flowsources.FlowSources private import semmle.code.csharp.frameworks.Sql private import semmle.code.csharp.security.Sanitizers @@ -16,7 +17,7 @@ abstract class Source extends DataFlow::Node { } /** * A sink for SQL injection vulnerabilities. */ -abstract class Sink extends DataFlow::ExprNode { } +abstract class Sink extends ApiSinkExprNode { } /** * A sanitizer for SQL injection vulnerabilities. diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/TaintedPathQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/TaintedPathQuery.qll index bbd32b583533..ca2b13439cee 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/TaintedPathQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/TaintedPathQuery.qll @@ -5,6 +5,7 @@ import csharp private import semmle.code.csharp.controlflow.Guards +private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks private import semmle.code.csharp.security.dataflow.flowsources.FlowSources private import semmle.code.csharp.frameworks.system.IO private import semmle.code.csharp.frameworks.system.Web @@ -18,7 +19,7 @@ abstract class Source extends DataFlow::Node { } /** * A data flow sink for uncontrolled data in path expression vulnerabilities. */ -abstract class Sink extends DataFlow::ExprNode { } +abstract class Sink extends ApiSinkExprNode { } /** * A sanitizer for uncontrolled data in path expression vulnerabilities. diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/UnsafeDeserializationQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/UnsafeDeserializationQuery.qll index 6de1305a11d1..a5341aca42f8 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/UnsafeDeserializationQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/UnsafeDeserializationQuery.qll @@ -6,6 +6,7 @@ import csharp private import semmle.code.csharp.serialization.Deserializers private import semmle.code.csharp.dataflow.TaintTracking2 +private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks private import semmle.code.csharp.security.dataflow.flowsources.FlowSources /** @@ -16,7 +17,7 @@ abstract class Source extends DataFlow::Node { } /** * A data flow sink for unsafe deserialization vulnerabilities. */ -abstract class Sink extends DataFlow::Node { } +abstract class Sink extends ApiSinkNode { } /** * A data flow sink for unsafe deserialization vulnerabilities to an instance method. diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/UrlRedirectQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/UrlRedirectQuery.qll index 9a5ec46cb37a..b21d5846bf56 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/UrlRedirectQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/UrlRedirectQuery.qll @@ -3,6 +3,7 @@ */ import csharp +private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks private import semmle.code.csharp.security.dataflow.flowsources.FlowSources private import semmle.code.csharp.controlflow.Guards private import semmle.code.csharp.frameworks.Format @@ -20,7 +21,7 @@ abstract class Source extends DataFlow::Node { } /** * A data flow sink for unvalidated URL redirect vulnerabilities. */ -abstract class Sink extends DataFlow::ExprNode { } +abstract class Sink extends ApiSinkExprNode { } /** * A sanitizer for unvalidated URL redirect vulnerabilities. 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 7e7fd61fb1c9..0bb842adf79d 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/XMLEntityInjectionQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/XMLEntityInjectionQuery.qll @@ -3,6 +3,7 @@ */ import csharp +private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks private import semmle.code.csharp.security.dataflow.flowsources.FlowSources private import semmle.code.csharp.frameworks.System private import semmle.code.csharp.frameworks.system.text.RegularExpressions @@ -19,7 +20,7 @@ private class ThreatModelSource extends Source instanceof ThreatModelFlowSource /** * A data flow sink for untrusted user input used in XML processing. */ -abstract class Sink extends DataFlow::ExprNode { +abstract class Sink extends ApiSinkExprNode { /** * Gets the reason for the insecurity of this sink. */ diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/XPathInjectionQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/XPathInjectionQuery.qll index 1edddf45f56f..c471a4324251 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/XPathInjectionQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/XPathInjectionQuery.qll @@ -3,6 +3,7 @@ */ import csharp +private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks private import semmle.code.csharp.security.dataflow.flowsources.FlowSources private import semmle.code.csharp.frameworks.system.xml.XPath private import semmle.code.csharp.frameworks.system.Xml @@ -16,7 +17,7 @@ abstract class Source extends DataFlow::Node { } /** * A data flow sink for untrusted user input used in XPath expression. */ -abstract class Sink extends DataFlow::ExprNode { } +abstract class Sink extends ApiSinkExprNode { } /** * A sanitizer for untrusted user input used in XPath expression. diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ZipSlipQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ZipSlipQuery.qll index a83bb8b4f5a4..93e7b601585d 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ZipSlipQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ZipSlipQuery.qll @@ -4,6 +4,7 @@ import csharp private import semmle.code.csharp.controlflow.Guards +private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks /** * A data flow source for unsafe zip extraction. @@ -13,7 +14,7 @@ abstract class Source extends DataFlow::Node { } /** * A data flow sink for unsafe zip extraction. */ -abstract class Sink extends DataFlow::ExprNode { } +abstract class Sink extends ApiSinkExprNode { } /** * A sanitizer for unsafe zip extraction. diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/AllSinks.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/AllSinks.qll deleted file mode 100644 index bf601bdf9b66..000000000000 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/AllSinks.qll +++ /dev/null @@ -1,84 +0,0 @@ -/** Provides classes representing various flow sinks for data flow / taint tracking. */ - -private import semmle.code.csharp.dataflow.internal.ExternalFlow - -/** - * A data flow sink node. - */ -abstract class SinkNode extends DataFlow::Node { } - -/** - * Module that adds all sinks to `SinkNode`, excluding sinks for cryptography based - * queries, and queries where sinks are not succifiently explicit. - */ -private module AllSinks { - private import ParallelSink as ParallelSink - private import Remote as Remote - private import semmle.code.csharp.security.dataflow.CodeInjectionQuery as CodeInjectionQuery - private import semmle.code.csharp.security.dataflow.ConditionalBypassQuery as ConditionalBypassQuery - private import semmle.code.csharp.security.dataflow.ExposureOfPrivateInformationQuery as ExposureOfPrivateInformationQuery - private import semmle.code.csharp.security.dataflow.HardcodedCredentialsQuery as HardcodedCredentialsQuery - private import semmle.code.csharp.security.dataflow.LDAPInjectionQuery as LdapInjectionQuery - private import semmle.code.csharp.security.dataflow.LogForgingQuery as LogForgingQuery - private import semmle.code.csharp.security.dataflow.MissingXMLValidationQuery as MissingXmlValidationQuery - private import semmle.code.csharp.security.dataflow.ReDoSQuery as ReDosQuery - private import semmle.code.csharp.security.dataflow.RegexInjectionQuery as RegexInjectionQuery - private import semmle.code.csharp.security.dataflow.ResourceInjectionQuery as ResourceInjectionQuery - private import semmle.code.csharp.security.dataflow.SqlInjectionQuery as SqlInjectionQuery - private import semmle.code.csharp.security.dataflow.TaintedPathQuery as TaintedPathQuery - private import semmle.code.csharp.security.dataflow.UnsafeDeserializationQuery as UnsafeDeserializationQuery - private import semmle.code.csharp.security.dataflow.UrlRedirectQuery as UrlRedirectQuery - private import semmle.code.csharp.security.dataflow.XMLEntityInjectionQuery as XmlEntityInjectionQuery - private import semmle.code.csharp.security.dataflow.XPathInjectionQuery as XpathInjectionQuery - private import semmle.code.csharp.security.dataflow.XSSSinks as XssSinks - private import semmle.code.csharp.security.dataflow.ZipSlipQuery as ZipSlipQuery - - private class ParallelSink extends SinkNode instanceof ParallelSink::ParallelSink { } - - private class RemoteSinkFlowSinks extends SinkNode instanceof Remote::RemoteFlowSink { } - - private class CodeInjectionSink extends SinkNode instanceof CodeInjectionQuery::Sink { } - - private class ConditionalBypassSink extends SinkNode instanceof ConditionalBypassQuery::Sink { } - - private class ExposureOfPrivateInformationSink extends SinkNode instanceof ExposureOfPrivateInformationQuery::Sink - { } - - private class HardcodedCredentialsSink extends SinkNode instanceof HardcodedCredentialsQuery::Sink - { } - - private class LdapInjectionSink extends SinkNode instanceof LdapInjectionQuery::Sink { } - - private class LogForgingSink extends SinkNode instanceof LogForgingQuery::Sink { } - - private class MissingXmlValidationSink extends SinkNode instanceof MissingXmlValidationQuery::Sink - { } - - private class ReDosSink extends SinkNode instanceof ReDosQuery::Sink { } - - private class RegexInjectionSink extends SinkNode instanceof RegexInjectionQuery::Sink { } - - private class ResourceInjectionSink extends SinkNode instanceof ResourceInjectionQuery::Sink { } - - private class SqlInjectionSink extends SinkNode instanceof SqlInjectionQuery::Sink { } - - private class TaintedPathSink extends SinkNode instanceof TaintedPathQuery::Sink { } - - private class UnsafeDeserializationSink extends SinkNode instanceof UnsafeDeserializationQuery::Sink - { } - - private class UrlRedirectSink extends SinkNode instanceof UrlRedirectQuery::Sink { } - - private class XmlEntityInjectionSink extends SinkNode instanceof XmlEntityInjectionQuery::Sink { } - - private class XpathInjectionSink extends SinkNode instanceof XpathInjectionQuery::Sink { } - - private class XssSink extends SinkNode instanceof XssSinks::Sink { } - - /** - * Add all models as data sinks. - */ - private class SinkNodeExternal extends SinkNode { - SinkNodeExternal() { sinkNode(this, _) } - } -} diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/ApiSinks.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/ApiSinks.qll new file mode 100644 index 000000000000..7a069adb2ed8 --- /dev/null +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/ApiSinks.qll @@ -0,0 +1,35 @@ +/** Provides classes representing various flow sinks for data flow / taint tracking. */ + +private import semmle.code.csharp.dataflow.internal.ExternalFlow +private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks + +/** + * A data flow sink node. + */ +final class SinkNode = ApiSinkNode; + +/** + * Module that adds all API like sinks to `SinkNode`, excluding sinks for cryptography based + * queries, and queries where sinks are not succifiently defined (eg. using broad method name matching). + */ +private module AllApiSinks { + private import ParallelSink + private import Remote + private import semmle.code.csharp.security.dataflow.CodeInjectionQuery as CodeInjectionQuery + private import semmle.code.csharp.security.dataflow.ConditionalBypassQuery as ConditionalBypassQuery + private import semmle.code.csharp.security.dataflow.ExposureOfPrivateInformationQuery as ExposureOfPrivateInformationQuery + private import semmle.code.csharp.security.dataflow.HardcodedCredentialsQuery as HardcodedCredentialsQuery + private import semmle.code.csharp.security.dataflow.LDAPInjectionQuery as LdapInjectionQuery + private import semmle.code.csharp.security.dataflow.LogForgingQuery as LogForgingQuery + private import semmle.code.csharp.security.dataflow.MissingXMLValidationQuery as MissingXmlValidationQuery + private import semmle.code.csharp.security.dataflow.ReDoSQuery as ReDosQuery + private import semmle.code.csharp.security.dataflow.RegexInjectionQuery as RegexInjectionQuery + private import semmle.code.csharp.security.dataflow.ResourceInjectionQuery as ResourceInjectionQuery + private import semmle.code.csharp.security.dataflow.SqlInjectionQuery as SqlInjectionQuery + private import semmle.code.csharp.security.dataflow.TaintedPathQuery as TaintedPathQuery + private import semmle.code.csharp.security.dataflow.UnsafeDeserializationQuery as UnsafeDeserializationQuery + private import semmle.code.csharp.security.dataflow.UrlRedirectQuery as UrlRedirectQuery + private import semmle.code.csharp.security.dataflow.XMLEntityInjectionQuery as XmlEntityInjectionQuery + private import semmle.code.csharp.security.dataflow.XPathInjectionQuery as XpathInjectionQuery + private import semmle.code.csharp.security.dataflow.ZipSlipQuery as ZipSlipQuery +} diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/ExternalLocationSink.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/ExternalLocationSink.qll index abd1ad92733e..3bcfdde669a4 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/ExternalLocationSink.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/ExternalLocationSink.qll @@ -3,6 +3,7 @@ */ import csharp +private import FlowSinks private import Remote private import semmle.code.csharp.commons.Loggers private import semmle.code.csharp.frameworks.system.Web @@ -16,7 +17,7 @@ private import semmle.code.csharp.dataflow.internal.ExternalFlow * which the application may have no access control. For example, files on a local or remote * filesystem (including log files and cookies). */ -abstract class ExternalLocationSink extends DataFlow::ExprNode { } +abstract class ExternalLocationSink extends ApiSinkExprNode { } private class ExternalModelSink extends ExternalLocationSink { ExternalModelSink() { sinkNode(this, "file-content-store") } diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/FlowSinks.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/FlowSinks.qll new file mode 100644 index 000000000000..0c5bf14e65cf --- /dev/null +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/FlowSinks.qll @@ -0,0 +1,23 @@ +/** Provides classes representing various flow sinks for data flow / taint tracking. */ + +private import csharp +private import semmle.code.csharp.dataflow.internal.ExternalFlow + +/** + * A data flow sink node for an API, which should be considered + * supported from a modeling perspective. + */ +abstract class ApiSinkNode extends DataFlow::Node { } + +/** + * A data flow sink expression node for an API, which should be considered + * supported from a modeling perspective. + */ +abstract class ApiSinkExprNode extends ApiSinkNode, DataFlow::ExprNode { } + +/** + * Add all sink models as data sinks. + */ +private class ApiSinkNodeExternal extends ApiSinkNode { + ApiSinkNodeExternal() { sinkNode(this, _) } +} diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/ParallelSink.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/ParallelSink.qll index 5e53c9bd8fd2..1546d72887d5 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/ParallelSink.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/ParallelSink.qll @@ -3,11 +3,12 @@ */ import csharp +private import FlowSinks /** * A data flow sink node for parallel execution. */ -abstract class ParallelSink extends DataFlow::Node { } +abstract class ParallelSink extends ApiSinkNode { } /** * A data flow sink node for lambda parallel sink. diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/Remote.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/Remote.qll index 0770a948b095..b58beb38ca59 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/Remote.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/Remote.qll @@ -5,12 +5,13 @@ import csharp private import Email::Email private import ExternalLocationSink +private import FlowSinks private import Html private import semmle.code.csharp.security.dataflow.XSSSinks as XssSinks private import semmle.code.csharp.frameworks.system.web.UI /** A data flow sink of remote user output. */ -abstract class RemoteFlowSink extends DataFlow::Node { } +abstract class RemoteFlowSink extends ApiSinkNode { } /** * A value written to the `[Inner]Text` property of an object defined in the diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/AllSources.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/AllSources.qll deleted file mode 100644 index 7d05500446a4..000000000000 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/AllSources.qll +++ /dev/null @@ -1,77 +0,0 @@ -/** Provides classes representing various flow sources for data flow / taint tracking. */ - -private import semmle.code.csharp.dataflow.internal.ExternalFlow - -/** - * A data flow source node. - */ -abstract class SourceNode extends DataFlow::Node { } - -/** - * Module that adds all sources to `SourceNode`, excluding source for cryptography based - * queries, and queries where sources are not succifiently explicit or mainly hardcoded constants. - */ -private module AllSources { - private import FlowSources as FlowSources - private import semmle.code.csharp.security.cryptography.HardcodedSymmetricEncryptionKey - private import semmle.code.csharp.security.dataflow.CleartextStorageQuery as CleartextStorageQuery - private import semmle.code.csharp.security.dataflow.CodeInjectionQuery as CodeInjectionQuery - private import semmle.code.csharp.security.dataflow.ConditionalBypassQuery as ConditionalBypassQuery - private import semmle.code.csharp.security.dataflow.ExposureOfPrivateInformationQuery as ExposureOfPrivateInformationQuery - private import semmle.code.csharp.security.dataflow.HardcodedCredentialsQuery as HardcodedCredentialsQuery - private import semmle.code.csharp.security.dataflow.LDAPInjectionQuery as LdapInjectionQuery - private import semmle.code.csharp.security.dataflow.LogForgingQuery as LogForgingQuery - private import semmle.code.csharp.security.dataflow.MissingXMLValidationQuery as MissingXmlValidationQuery - private import semmle.code.csharp.security.dataflow.ReDoSQuery as ReDosQuery - private import semmle.code.csharp.security.dataflow.RegexInjectionQuery as RegexInjectionQuery - private import semmle.code.csharp.security.dataflow.ResourceInjectionQuery as ResourceInjectionQuery - private import semmle.code.csharp.security.dataflow.SqlInjectionQuery as SqlInjectionQuery - private import semmle.code.csharp.security.dataflow.TaintedPathQuery as TaintedPathQuery - private import semmle.code.csharp.security.dataflow.UnsafeDeserializationQuery as UnsafeDeserializationQuery - private import semmle.code.csharp.security.dataflow.UrlRedirectQuery as UrlRedirectQuery - private import semmle.code.csharp.security.dataflow.XMLEntityInjectionQuery as XmlEntityInjectionQuery - private import semmle.code.csharp.security.dataflow.XPathInjectionQuery as XpathInjectionQuery - private import semmle.code.csharp.security.dataflow.ZipSlipQuery as ZipSlipQuery - - private class FlowSourcesSources extends SourceNode instanceof FlowSources::SourceNode { } - - private class CodeInjectionSource extends SourceNode instanceof CodeInjectionQuery::Source { } - - private class ConditionalBypassSource extends SourceNode instanceof ConditionalBypassQuery::Source - { } - - private class LdapInjectionSource extends SourceNode instanceof LdapInjectionQuery::Source { } - - private class LogForgingSource extends SourceNode instanceof LogForgingQuery::Source { } - - private class MissingXmlValidationSource extends SourceNode instanceof MissingXmlValidationQuery::Source - { } - - private class ReDosSource extends SourceNode instanceof ReDosQuery::Source { } - - private class RegexInjectionSource extends SourceNode instanceof RegexInjectionQuery::Source { } - - private class ResourceInjectionSource extends SourceNode instanceof ResourceInjectionQuery::Source - { } - - private class SqlInjectionSource extends SourceNode instanceof SqlInjectionQuery::Source { } - - private class TaintedPathSource extends SourceNode instanceof TaintedPathQuery::Source { } - - private class UnsafeDeserializationSource extends SourceNode instanceof UnsafeDeserializationQuery::Source - { } - - private class UrlRedirectSource extends SourceNode instanceof UrlRedirectQuery::Source { } - - private class XmlEntityInjectionSource extends SourceNode instanceof XmlEntityInjectionQuery::Source - { } - - private class XpathInjectionSource extends SourceNode instanceof XpathInjectionQuery::Source { } - - /** - * Add all models as data sources. - */ - private class SourceNodeExternal extends SourceNode { - SourceNodeExternal() { sourceNode(this, _) } - } -} diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/ApiSources.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/ApiSources.qll new file mode 100644 index 000000000000..01d838f2f94d --- /dev/null +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/ApiSources.qll @@ -0,0 +1,14 @@ +/** Provides classes representing various flow sources for data flow / taint tracking. */ + +private import FlowSources as FlowSources + +final class SourceNode = FlowSources::SourceNode; + +/** + * Module that adds all API like sources to `SourceNode`, excluding some sources for cryptography based + * queries, and queries where sources are not succifiently defined (eg. using broad method name matching). + */ +private module AllApiSources { + private import semmle.code.csharp.security.dataflow.ConditionalBypassQuery as ConditionalBypassQuery + private import semmle.code.csharp.security.dataflow.ZipSlipQuery as ZipSlipQuery +} diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/FlowSources.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/FlowSources.qll index a5ada1cbaf8b..c610b3de4c74 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/FlowSources.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/FlowSources.qll @@ -32,3 +32,18 @@ class ThreatModelFlowSource extends DataFlow::Node { ) } } + +/** + * A data flow source node for an API, which should be considered + * supported from a modeling perspective. + */ +abstract class ApiSourceNode extends DataFlow::Node { } + +private class AddSourceNodes extends ApiSourceNode instanceof SourceNode { } + +/** + * Add all source models as data sources. + */ +private class ApiSourceNodeExternal extends ApiSourceNode { + ApiSourceNodeExternal() { sourceNode(this, _) } +} diff --git a/csharp/ql/src/Telemetry/ExternalApi.qll b/csharp/ql/src/Telemetry/ExternalApi.qll index a710cdf7cfde..270db8b0d19c 100644 --- a/csharp/ql/src/Telemetry/ExternalApi.qll +++ b/csharp/ql/src/Telemetry/ExternalApi.qll @@ -8,8 +8,8 @@ private import semmle.code.csharp.dataflow.internal.DataFlowDispatch as DataFlow private import semmle.code.csharp.dataflow.internal.ExternalFlow private import semmle.code.csharp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl private import semmle.code.csharp.dataflow.internal.TaintTrackingPrivate -private import semmle.code.csharp.security.dataflow.flowsources.AllSources -private import semmle.code.csharp.security.dataflow.flowsinks.AllSinks +private import semmle.code.csharp.security.dataflow.flowsources.ApiSources as ApiSources +private import semmle.code.csharp.security.dataflow.flowsinks.ApiSinks as ApiSinks private import TestLibrary /** Holds if the given callable is not worth supporting. */ @@ -85,11 +85,11 @@ class ExternalApi extends Callable { /** Holds if this API is a known source. */ pragma[nomagic] - predicate isSource() { this.getAnOutput() instanceof SourceNode } + predicate isSource() { this.getAnOutput() instanceof ApiSources::SourceNode } /** Holds if this API is a known sink. */ pragma[nomagic] - predicate isSink() { this.getAnInput() instanceof SinkNode } + predicate isSink() { this.getAnInput() instanceof ApiSinks::SinkNode } /** Holds if this API is a known neutral. */ pragma[nomagic] From 31c427e64c030e0cdaeb26b7c571e05124ba00f0 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 3 May 2024 13:04:42 +0200 Subject: [PATCH 197/238] Bazel/Go: add more explanation in `gen.py` --- go/gen.py | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/go/gen.py b/go/gen.py index ebb57b2a685a..0e9005571ea4 100644 --- a/go/gen.py +++ b/go/gen.py @@ -1,3 +1,12 @@ +""" +Update generated files related to Go in the repo. Using --force will regenerate all files from scratch. + +In particular the script will: +1. update the `vendor` dir with `go work vendor` (using a go toolchain provided by bazel) +2. update `BUILD.bazel` files using gazelle +3. update `ql/lib/go.dbscheme` using a compiled `go-dbschemegen` +""" + import sys import pathlib import subprocess @@ -7,9 +16,9 @@ from python.runfiles import runfiles def options(): - p = argparse.ArgumentParser(description="Update generated checked in files in the Go pack") + p = argparse.ArgumentParser(description="Update generated files related to Go in the repo") p.add_argument("--force", "-f", action="store_true", help="Regenerate all files from scratch rather than updating them") - p.add_argument("generators", nargs=3) + p.add_argument("executables", nargs=3, help="Internally provided executables") return p.parse_args() opts = options() @@ -23,7 +32,7 @@ def options(): go_extractor_dir = workspace_dir / "go" / "extractor" go_dbscheme = workspace_dir / "go" / "ql" / "lib" / "go.dbscheme" r = runfiles.Create() -go, gazelle, go_gen_dbscheme = map(r.Rlocation, opts.generators) +go, gazelle, go_gen_dbscheme = map(r.Rlocation, opts.executables) if opts.force: @@ -43,13 +52,16 @@ def options(): print("running gazelle") subprocess.check_call([gazelle]) +# we want to stamp all newly generated `BUILD.bazel` files with a header build_files_to_update = set(go_extractor_dir.glob("*/**/BUILD.bazel")) +# if --force, all files are new if not opts.force: + # otherwise, subtract the files that existed at the start build_files_to_update -= existing_build_files - # these are always refreshed + # but bring back the `vendor` ones, as the vendor update step always clears them build_files_to_update.update(go_extractor_dir.glob("vendor/**/BUILD.bazel")) -print("adding header to generated BUILD files") +print("adding header to newly generated BUILD files") for build_file in build_files_to_update: contents = build_file.read_text() build_file.write_text(f"# generated running `bazel run //go/gazelle`, do not edit\n\n{contents}") From 8f0b88497a89ed9cce41c659528175427d61bf85 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 3 May 2024 13:07:56 +0200 Subject: [PATCH 198/238] Bazel/Go: be more specific in `go/extractor/BUILD.bazel` comments --- go/extractor/BUILD.bazel | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/go/extractor/BUILD.bazel b/go/extractor/BUILD.bazel index 32eaa8fda745..297ca52c8b80 100644 --- a/go/extractor/BUILD.bazel +++ b/go/extractor/BUILD.bazel @@ -4,7 +4,7 @@ load("@rules_pkg//pkg:mappings.bzl", "pkg_files") # gazelle:prefix github.com/github/codeql-go/extractor # gazelle:map_kind go_binary codeql_go_binary //go:rules.bzl -# following target is kept up to date by `bazel run //go:gen`, do not edit directly +# the immediately following `extractor` target is kept up to date by `bazel run //go:gen`, do not edit directly go_library( name = "extractor", srcs = [ @@ -25,6 +25,7 @@ go_library( ], ) +# notice that these other targets are not generated java_library( name = "tokenizer-deps", srcs = [ From ff85db36e2bb8ce248696a6dd1ec127a798d65db Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Fri, 3 May 2024 13:58:11 +0200 Subject: [PATCH 199/238] exclude credentials as kind `key` from hardcoded-credentials when the key looks like a dummy password --- javascript/ql/src/Security/CWE-798/HardcodedCredentials.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/src/Security/CWE-798/HardcodedCredentials.ql b/javascript/ql/src/Security/CWE-798/HardcodedCredentials.ql index 3cc63e51dcfe..1c13ad78bfa2 100644 --- a/javascript/ql/src/Security/CWE-798/HardcodedCredentials.ql +++ b/javascript/ql/src/Security/CWE-798/HardcodedCredentials.ql @@ -30,7 +30,7 @@ where // exclude dummy passwords and templates not ( sink.getNode().(Sink).(DefaultCredentialsSink).getKind() = - ["password", "credentials", "token"] and + ["password", "credentials", "token", "key"] and PasswordHeuristics::isDummyPassword(val) or sink.getNode().(Sink).getKind() = "authorization header" and From d9e8e0e00aee0f2184e81493fc1c1db25212a45a Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Fri, 3 May 2024 13:58:37 +0200 Subject: [PATCH 200/238] use some more standard values for credentials-kind for NodeJS client credentials --- javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll b/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll index b3d93383ed78..98bb0f615b67 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll @@ -1003,7 +1003,7 @@ module NodeJSLib { exists(ClientRequestLoginCallback callback | this = callback.getACall().getArgument(0)) } - override string getCredentialsKind() { result = "Node.js http(s) client login username" } + override string getCredentialsKind() { result = "user name" } } /** @@ -1014,7 +1014,7 @@ module NodeJSLib { exists(ClientRequestLoginCallback callback | this = callback.getACall().getArgument(1)) } - override string getCredentialsKind() { result = "Node.js http(s) client login password" } + override string getCredentialsKind() { result = "password" } } /** From 3c91333d0b79f52ca57130ee6cdb1a7e447d78a6 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Fri, 3 May 2024 14:09:41 +0200 Subject: [PATCH 201/238] Address review comment --- csharp/ql/lib/semmle/code/csharp/ExprOrStmtParent.qll | 2 +- csharp/ql/lib/semmle/code/csharp/Location.qll | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/ExprOrStmtParent.qll b/csharp/ql/lib/semmle/code/csharp/ExprOrStmtParent.qll index 7ae36b31f3eb..778ee8d610c9 100644 --- a/csharp/ql/lib/semmle/code/csharp/ExprOrStmtParent.qll +++ b/csharp/ql/lib/semmle/code/csharp/ExprOrStmtParent.qll @@ -66,7 +66,7 @@ private ControlFlowElement getBody(Callable c) { } pragma[nomagic] -private Location getASourceLocation(Element e) { +private SourceLocation getASourceLocation(Element e) { result = e.getALocation().(SourceLocation) and not exists(e.getALocation().(SourceLocation).getMappedLocation()) or diff --git a/csharp/ql/lib/semmle/code/csharp/Location.qll b/csharp/ql/lib/semmle/code/csharp/Location.qll index 8b4fabb44e79..319b3890e4e1 100644 --- a/csharp/ql/lib/semmle/code/csharp/Location.qll +++ b/csharp/ql/lib/semmle/code/csharp/Location.qll @@ -63,7 +63,7 @@ class EmptyLocation extends Location { */ class SourceLocation extends Location, @location_default { /** Gets the location that takes into account `#line` directives, if any. */ - Location getMappedLocation() { + SourceLocation getMappedLocation() { locations_mapped(this, result) and not exists(LineDirective l | l.getALocation() = this) } From ba64cf3016dbcba8930cf75df1116bb5f2ab99af Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Fri, 3 May 2024 14:38:37 +0200 Subject: [PATCH 202/238] C++: Correctly handle destructors at the end of range-based for-loops in the IR --- .../raw/internal/TranslatedStmt.qll | 19 ++- .../library-tests/ir/ir/aliased_ir.expected | 64 ++++++--- .../test/library-tests/ir/ir/raw_ir.expected | 136 ++++++++---------- 3 files changed, 128 insertions(+), 91 deletions(-) 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 d08a01244d78..3f77a2b0b45e 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 @@ -1163,6 +1163,8 @@ class TranslatedForStmt extends TranslatedLoop { class TranslatedRangeBasedForStmt extends TranslatedStmt, ConditionContext { override RangeBasedForStmt stmt; + override predicate handlesDestructorsExplicitly() { any() } + override TranslatedElement getChildInternal(int id) { id = 0 and result = this.getInitialization() or @@ -1216,6 +1218,19 @@ class TranslatedRangeBasedForStmt extends TranslatedStmt, ConditionContext { or child = this.getUpdate() and result = this.getCondition().getFirstInstruction(kind) + or + exists(int destructorId | + destructorId >= this.getFirstDestructorCallIndex() and + child = this.getChild(destructorId) and + result = this.getChild(destructorId + 1).getFirstInstruction(kind) + ) + or + exists(int lastDestructorIndex | + lastDestructorIndex = + max(int n | exists(this.getChild(n)) and n >= this.getFirstDestructorCallIndex()) and + child = this.getChild(lastDestructorIndex) and + result = this.getParent().getChildSuccessor(this, kind) + ) } override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { @@ -1231,7 +1246,9 @@ class TranslatedRangeBasedForStmt extends TranslatedStmt, ConditionContext { override Instruction getChildFalseSuccessor(TranslatedCondition child, EdgeKind kind) { child = this.getCondition() and - result = this.getParent().getChildSuccessor(this, kind) + if this.hasAnImplicitDestructorCall() + then result = this.getChild(this.getFirstDestructorCallIndex()).getFirstInstruction(kind) + else result = this.getParent().getChildSuccessor(this, kind) } private TranslatedDeclStmt getRangeVariableDeclStmt() { diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected index 3502252f6011..ae73ecd8f6ff 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected @@ -15600,10 +15600,18 @@ ir.cpp: # 2215| r2215_73(glval>) = CopyValue : r2215_61 #-----| Goto (back edge) -> Block 8 -# 2218| Block 10 +# 2215| Block 10 +# 2215| r2215_74(glval>) = VariableAddress[ys] : +# 2215| r2215_75(glval) = FunctionAddress[~vector] : +# 2215| v2215_76(void) = Call[~vector] : func:r2215_75, this:r2215_74 +# 2215| m2215_77(unknown) = ^CallSideEffect : ~m2215_50 +# 2215| m2215_78(unknown) = Chi : total:m2215_50, partial:m2215_77 +# 2215| v2215_79(void) = ^IndirectReadSideEffect[-1] : &:r2215_74, ~m2215_78 +# 2215| m2215_80(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2215_74 +# 2215| m2215_81(unknown) = Chi : total:m2215_78, partial:m2215_80 # 2218| r2218_1(glval>) = VariableAddress[ys] : # 2218| m2218_2(vector) = Uninitialized[ys] : &:r2218_1 -# 2218| m2218_3(unknown) = Chi : total:m2215_50, partial:m2218_2 +# 2218| m2218_3(unknown) = Chi : total:m2215_81, partial:m2218_2 # 2218| r2218_4(glval) = FunctionAddress[vector] : # 2218| r2218_5(glval) = VariableAddress[#temp2218:45] : # 2218| r2218_6(glval) = VariableAddress[x] : @@ -15753,10 +15761,18 @@ ir.cpp: # 2233| m2233_8(ClassWithDestructor) = Chi : total:m2214_8, partial:m2233_7 #-----| Goto -> Block 1 -# 2224| Block 15 +# 2218| Block 15 +# 2218| r2218_90(glval>) = VariableAddress[ys] : +# 2218| r2218_91(glval) = FunctionAddress[~vector] : +# 2218| v2218_92(void) = Call[~vector] : func:r2218_91, this:r2218_90 +# 2218| m2218_93(unknown) = ^CallSideEffect : ~m2218_50 +# 2218| m2218_94(unknown) = Chi : total:m2218_50, partial:m2218_93 +# 2218| v2218_95(void) = ^IndirectReadSideEffect[-1] : &:r2218_90, ~m2218_94 +# 2218| m2218_96(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2218_90 +# 2218| m2218_97(unknown) = Chi : total:m2218_94, partial:m2218_96 # 2224| r2224_1(glval>) = VariableAddress[ys] : # 2224| m2224_2(vector) = Uninitialized[ys] : &:r2224_1 -# 2224| m2224_3(unknown) = Chi : total:m2218_50, partial:m2224_2 +# 2224| m2224_3(unknown) = Chi : total:m2218_97, partial:m2224_2 # 2224| r2224_4(glval) = FunctionAddress[vector] : # 2224| r2224_5(int) = Constant[1] : # 2224| v2224_6(void) = Call[vector] : func:r2224_4, this:r2224_1, 0:r2224_5 @@ -15862,10 +15878,18 @@ ir.cpp: # 2233| m2233_16(ClassWithDestructor) = Chi : total:m2214_8, partial:m2233_15 #-----| Goto -> Block 1 -# 2229| Block 20 +# 2224| Block 20 +# 2224| r2224_62(glval>) = VariableAddress[ys] : +# 2224| r2224_63(glval) = FunctionAddress[~vector] : +# 2224| v2224_64(void) = Call[~vector] : func:r2224_63, this:r2224_62 +# 2224| m2224_65(unknown) = ^CallSideEffect : ~m2224_38 +# 2224| m2224_66(unknown) = Chi : total:m2224_38, partial:m2224_65 +# 2224| v2224_67(void) = ^IndirectReadSideEffect[-1] : &:r2224_62, ~m2224_66 +# 2224| m2224_68(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2224_62 +# 2224| m2224_69(unknown) = Chi : total:m2224_66, partial:m2224_68 # 2229| r2229_1(glval>) = VariableAddress[ys] : # 2229| m2229_2(vector) = Uninitialized[ys] : &:r2229_1 -# 2229| m2229_3(unknown) = Chi : total:m2224_38, partial:m2229_2 +# 2229| m2229_3(unknown) = Chi : total:m2224_69, partial:m2229_2 # 2229| r2229_4(glval) = FunctionAddress[vector] : # 2229| r2229_5(glval) = VariableAddress[#temp2229:45] : # 2229| r2229_6(glval) = VariableAddress[x] : @@ -15994,16 +16018,24 @@ ir.cpp: # 2229| r2229_73(glval>) = CopyValue : r2229_61 #-----| Goto (back edge) -> Block 21 -# 2233| Block 23 -# 2233| v2233_17(void) = NoOp : -# 2233| r2233_18(glval) = VariableAddress[x] : -# 2233| r2233_19(glval) = FunctionAddress[~ClassWithDestructor] : -# 2233| v2233_20(void) = Call[~ClassWithDestructor] : func:r2233_19, this:r2233_18 -# 2233| m2233_21(unknown) = ^CallSideEffect : ~m2229_50 -# 2233| m2233_22(unknown) = Chi : total:m2229_50, partial:m2233_21 -# 2233| v2233_23(void) = ^IndirectReadSideEffect[-1] : &:r2233_18, m2214_8 -# 2233| m2233_24(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2233_18 -# 2233| m2233_25(ClassWithDestructor) = Chi : total:m2214_8, partial:m2233_24 +# 2229| Block 23 +# 2229| r2229_74(glval>) = VariableAddress[ys] : +# 2229| r2229_75(glval) = FunctionAddress[~vector] : +# 2229| v2229_76(void) = Call[~vector] : func:r2229_75, this:r2229_74 +# 2229| m2229_77(unknown) = ^CallSideEffect : ~m2229_50 +# 2229| m2229_78(unknown) = Chi : total:m2229_50, partial:m2229_77 +# 2229| v2229_79(void) = ^IndirectReadSideEffect[-1] : &:r2229_74, ~m2229_78 +# 2229| m2229_80(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2229_74 +# 2229| m2229_81(unknown) = Chi : total:m2229_78, partial:m2229_80 +# 2233| v2233_17(void) = NoOp : +# 2233| r2233_18(glval) = VariableAddress[x] : +# 2233| r2233_19(glval) = FunctionAddress[~ClassWithDestructor] : +# 2233| v2233_20(void) = Call[~ClassWithDestructor] : func:r2233_19, this:r2233_18 +# 2233| m2233_21(unknown) = ^CallSideEffect : ~m2229_81 +# 2233| m2233_22(unknown) = Chi : total:m2229_81, partial:m2233_21 +# 2233| v2233_23(void) = ^IndirectReadSideEffect[-1] : &:r2233_18, m2214_8 +# 2233| m2233_24(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2233_18 +# 2233| m2233_25(ClassWithDestructor) = Chi : total:m2214_8, partial:m2233_24 #-----| Goto -> Block 1 # 2198| Block 24 diff --git a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected index e454a6ba92eb..71796c4c39e2 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -14318,7 +14318,7 @@ ir.cpp: # 2215| r2215_41(bool) = Call[operator!=] : func:r2215_35, this:r0_7, 0:r0_13 #-----| v0_14(void) = ^IndirectReadSideEffect[-1] : &:r0_7, ~m? # 2215| v2215_42(void) = ConditionalBranch : r2215_41 -#-----| False -> Block 14 +#-----| False -> Block 13 #-----| True -> Block 12 # 2215| Block 12 @@ -14352,15 +14352,12 @@ ir.cpp: #-----| Goto (back edge) -> Block 11 # 2215| Block 13 -# 2215| r2215_61(glval>) = VariableAddress[ys] : -# 2215| r2215_62(glval) = FunctionAddress[~vector] : -# 2215| v2215_63(void) = Call[~vector] : func:r2215_62, this:r2215_61 -# 2215| mu2215_64(unknown) = ^CallSideEffect : ~m? -# 2215| v2215_65(void) = ^IndirectReadSideEffect[-1] : &:r2215_61, ~m? -# 2215| mu2215_66(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2215_61 -#-----| Goto -> Block 14 - -# 2218| Block 14 +# 2215| r2215_61(glval>) = VariableAddress[ys] : +# 2215| r2215_62(glval) = FunctionAddress[~vector] : +# 2215| v2215_63(void) = Call[~vector] : func:r2215_62, this:r2215_61 +# 2215| mu2215_64(unknown) = ^CallSideEffect : ~m? +# 2215| v2215_65(void) = ^IndirectReadSideEffect[-1] : &:r2215_61, ~m? +# 2215| mu2215_66(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2215_61 # 2218| r2218_1(glval>) = VariableAddress[ys] : # 2218| mu2218_2(vector) = Uninitialized[ys] : &:r2218_1 # 2218| r2218_3(glval) = FunctionAddress[vector] : @@ -14400,9 +14397,9 @@ ir.cpp: # 2218| r2218_32(iterator) = Call[end] : func:r2218_31, this:r0_21 #-----| v0_22(void) = ^IndirectReadSideEffect[-1] : &:r0_21, ~m? # 2218| mu2218_33(iterator) = Store[(__end)] : &:r2218_28, r2218_32 -#-----| Goto -> Block 15 +#-----| Goto -> Block 14 -# 2218| Block 15 +# 2218| Block 14 # 2218| r2218_34(glval>) = VariableAddress[(__begin)] : #-----| r0_23(glval>) = Convert : r2218_34 # 2218| r2218_35(glval) = FunctionAddress[operator!=] : @@ -14420,10 +14417,10 @@ ir.cpp: # 2218| r2218_41(bool) = Call[operator!=] : func:r2218_35, this:r0_23, 0:r0_29 #-----| v0_30(void) = ^IndirectReadSideEffect[-1] : &:r0_23, ~m? # 2218| v2218_42(void) = ConditionalBranch : r2218_41 -#-----| False -> Block 20 -#-----| True -> Block 17 +#-----| False -> Block 18 +#-----| True -> Block 16 -# 2218| Block 16 +# 2218| Block 15 # 2218| r2218_43(glval>) = VariableAddress[(__begin)] : # 2218| r2218_44(glval) = FunctionAddress[operator++] : # 2218| r2218_45(iterator &) = Call[operator++] : func:r2218_44, this:r2218_43 @@ -14436,9 +14433,9 @@ ir.cpp: # 2218| v2218_52(void) = ^IndirectReadSideEffect[-1] : &:r2218_48, ~m? # 2218| mu2218_53(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2218_48 # 2218| r2218_54(glval>) = CopyValue : r2218_45 -#-----| Goto (back edge) -> Block 15 +#-----| Goto (back edge) -> Block 14 -# 2218| Block 17 +# 2218| Block 16 # 2218| r2218_55(glval) = VariableAddress[y] : # 2218| r2218_56(glval>) = VariableAddress[(__begin)] : #-----| r0_31(glval>) = Convert : r2218_56 @@ -14464,10 +14461,10 @@ ir.cpp: # 2220| r2220_8(int) = Constant[98] : # 2220| r2220_9(bool) = CompareEQ : r2220_7, r2220_8 # 2220| v2220_10(void) = ConditionalBranch : r2220_9 -#-----| False -> Block 16 -#-----| True -> Block 18 +#-----| False -> Block 15 +#-----| True -> Block 17 -# 2221| Block 18 +# 2221| Block 17 # 2221| v2221_1(void) = NoOp : # 2218| r2218_61(glval) = VariableAddress[y] : # 2218| r2218_62(glval) = FunctionAddress[~ClassWithDestructor] : @@ -14489,16 +14486,13 @@ ir.cpp: # 2233| mu2233_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2233_1 #-----| Goto -> Block 1 -# 2218| Block 19 -# 2218| r2218_73(glval>) = VariableAddress[ys] : -# 2218| r2218_74(glval) = FunctionAddress[~vector] : -# 2218| v2218_75(void) = Call[~vector] : func:r2218_74, this:r2218_73 -# 2218| mu2218_76(unknown) = ^CallSideEffect : ~m? -# 2218| v2218_77(void) = ^IndirectReadSideEffect[-1] : &:r2218_73, ~m? -# 2218| mu2218_78(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2218_73 -#-----| Goto -> Block 20 - -# 2224| Block 20 +# 2218| Block 18 +# 2218| r2218_73(glval>) = VariableAddress[ys] : +# 2218| r2218_74(glval) = FunctionAddress[~vector] : +# 2218| v2218_75(void) = Call[~vector] : func:r2218_74, this:r2218_73 +# 2218| mu2218_76(unknown) = ^CallSideEffect : ~m? +# 2218| v2218_77(void) = ^IndirectReadSideEffect[-1] : &:r2218_73, ~m? +# 2218| mu2218_78(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2218_73 # 2224| r2224_1(glval>) = VariableAddress[ys] : # 2224| mu2224_2(vector) = Uninitialized[ys] : &:r2224_1 # 2224| r2224_3(glval) = FunctionAddress[vector] : @@ -14528,9 +14522,9 @@ ir.cpp: # 2224| r2224_22(iterator) = Call[end] : func:r2224_21, this:r0_37 #-----| v0_38(void) = ^IndirectReadSideEffect[-1] : &:r0_37, ~m? # 2224| mu2224_23(iterator) = Store[(__end)] : &:r2224_18, r2224_22 -#-----| Goto -> Block 21 +#-----| Goto -> Block 19 -# 2224| Block 21 +# 2224| Block 19 # 2224| r2224_24(glval>) = VariableAddress[(__begin)] : #-----| r0_39(glval>) = Convert : r2224_24 # 2224| r2224_25(glval) = FunctionAddress[operator!=] : @@ -14548,19 +14542,19 @@ ir.cpp: # 2224| r2224_31(bool) = Call[operator!=] : func:r2224_25, this:r0_39, 0:r0_45 #-----| v0_46(void) = ^IndirectReadSideEffect[-1] : &:r0_39, ~m? # 2224| v2224_32(void) = ConditionalBranch : r2224_31 -#-----| False -> Block 26 -#-----| True -> Block 23 +#-----| False -> Block 23 +#-----| True -> Block 21 -# 2224| Block 22 +# 2224| Block 20 # 2224| r2224_33(glval>) = VariableAddress[(__begin)] : # 2224| r2224_34(glval) = FunctionAddress[operator++] : # 2224| r2224_35(iterator &) = Call[operator++] : func:r2224_34, this:r2224_33 # 2224| v2224_36(void) = ^IndirectReadSideEffect[-1] : &:r2224_33, ~m? # 2224| mu2224_37(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2224_33 # 2224| r2224_38(glval>) = CopyValue : r2224_35 -#-----| Goto (back edge) -> Block 21 +#-----| Goto (back edge) -> Block 19 -# 2224| Block 23 +# 2224| Block 21 # 2224| r2224_39(glval) = VariableAddress[y] : # 2224| r2224_40(glval>) = VariableAddress[(__begin)] : #-----| r0_47(glval>) = Convert : r2224_40 @@ -14574,10 +14568,10 @@ ir.cpp: # 2225| r2225_3(int) = Constant[1] : # 2225| r2225_4(bool) = CompareEQ : r2225_2, r2225_3 # 2225| v2225_5(void) = ConditionalBranch : r2225_4 -#-----| False -> Block 22 -#-----| True -> Block 24 +#-----| False -> Block 20 +#-----| True -> Block 22 -# 2226| Block 24 +# 2226| Block 22 # 2226| v2226_1(void) = NoOp : # 2224| r2224_45(glval>) = VariableAddress[ys] : # 2224| r2224_46(glval) = FunctionAddress[~vector] : @@ -14593,16 +14587,13 @@ ir.cpp: # 2233| mu2233_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2233_7 #-----| Goto -> Block 1 -# 2224| Block 25 -# 2224| r2224_51(glval>) = VariableAddress[ys] : -# 2224| r2224_52(glval) = FunctionAddress[~vector] : -# 2224| v2224_53(void) = Call[~vector] : func:r2224_52, this:r2224_51 -# 2224| mu2224_54(unknown) = ^CallSideEffect : ~m? -# 2224| v2224_55(void) = ^IndirectReadSideEffect[-1] : &:r2224_51, ~m? -# 2224| mu2224_56(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2224_51 -#-----| Goto -> Block 26 - -# 2229| Block 26 +# 2224| Block 23 +# 2224| r2224_51(glval>) = VariableAddress[ys] : +# 2224| r2224_52(glval) = FunctionAddress[~vector] : +# 2224| v2224_53(void) = Call[~vector] : func:r2224_52, this:r2224_51 +# 2224| mu2224_54(unknown) = ^CallSideEffect : ~m? +# 2224| v2224_55(void) = ^IndirectReadSideEffect[-1] : &:r2224_51, ~m? +# 2224| mu2224_56(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2224_51 # 2229| r2229_1(glval>) = VariableAddress[ys] : # 2229| mu2229_2(vector) = Uninitialized[ys] : &:r2229_1 # 2229| r2229_3(glval) = FunctionAddress[vector] : @@ -14642,9 +14633,9 @@ ir.cpp: # 2229| r2229_32(iterator) = Call[end] : func:r2229_31, this:r0_53 #-----| v0_54(void) = ^IndirectReadSideEffect[-1] : &:r0_53, ~m? # 2229| mu2229_33(iterator) = Store[(__end)] : &:r2229_28, r2229_32 -#-----| Goto -> Block 27 +#-----| Goto -> Block 24 -# 2229| Block 27 +# 2229| Block 24 # 2229| r2229_34(glval>) = VariableAddress[(__begin)] : #-----| r0_55(glval>) = Convert : r2229_34 # 2229| r2229_35(glval) = FunctionAddress[operator!=] : @@ -14662,10 +14653,10 @@ ir.cpp: # 2229| r2229_41(bool) = Call[operator!=] : func:r2229_35, this:r0_55, 0:r0_61 #-----| v0_62(void) = ^IndirectReadSideEffect[-1] : &:r0_55, ~m? # 2229| v2229_42(void) = ConditionalBranch : r2229_41 -#-----| False -> Block 30 -#-----| True -> Block 28 +#-----| False -> Block 26 +#-----| True -> Block 25 -# 2229| Block 28 +# 2229| Block 25 # 2229| r2229_43(glval) = VariableAddress[y] : # 2229| r2229_44(glval>) = VariableAddress[(__begin)] : #-----| r0_63(glval>) = Convert : r2229_44 @@ -14710,25 +14701,22 @@ ir.cpp: # 2229| v2229_58(void) = ^IndirectReadSideEffect[-1] : &:r2229_54, ~m? # 2229| mu2229_59(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2229_54 # 2229| r2229_60(glval>) = CopyValue : r2229_51 -#-----| Goto (back edge) -> Block 27 - -# 2229| Block 29 -# 2229| r2229_61(glval>) = VariableAddress[ys] : -# 2229| r2229_62(glval) = FunctionAddress[~vector] : -# 2229| v2229_63(void) = Call[~vector] : func:r2229_62, this:r2229_61 -# 2229| mu2229_64(unknown) = ^CallSideEffect : ~m? -# 2229| v2229_65(void) = ^IndirectReadSideEffect[-1] : &:r2229_61, ~m? -# 2229| mu2229_66(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2229_61 -#-----| Goto -> Block 30 - -# 2233| Block 30 -# 2233| v2233_13(void) = NoOp : -# 2233| r2233_14(glval) = VariableAddress[x] : -# 2233| r2233_15(glval) = FunctionAddress[~ClassWithDestructor] : -# 2233| v2233_16(void) = Call[~ClassWithDestructor] : func:r2233_15, this:r2233_14 -# 2233| mu2233_17(unknown) = ^CallSideEffect : ~m? -# 2233| v2233_18(void) = ^IndirectReadSideEffect[-1] : &:r2233_14, ~m? -# 2233| mu2233_19(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2233_14 +#-----| Goto (back edge) -> Block 24 + +# 2229| Block 26 +# 2229| r2229_61(glval>) = VariableAddress[ys] : +# 2229| r2229_62(glval) = FunctionAddress[~vector] : +# 2229| v2229_63(void) = Call[~vector] : func:r2229_62, this:r2229_61 +# 2229| mu2229_64(unknown) = ^CallSideEffect : ~m? +# 2229| v2229_65(void) = ^IndirectReadSideEffect[-1] : &:r2229_61, ~m? +# 2229| mu2229_66(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2229_61 +# 2233| v2233_13(void) = NoOp : +# 2233| r2233_14(glval) = VariableAddress[x] : +# 2233| r2233_15(glval) = FunctionAddress[~ClassWithDestructor] : +# 2233| v2233_16(void) = Call[~ClassWithDestructor] : func:r2233_15, this:r2233_14 +# 2233| mu2233_17(unknown) = ^CallSideEffect : ~m? +# 2233| v2233_18(void) = ^IndirectReadSideEffect[-1] : &:r2233_14, ~m? +# 2233| mu2233_19(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2233_14 #-----| Goto -> Block 1 # 2235| void static_variable_with_destructor_1() From e8cb8b4f81656ef22812414788a2146e2d02bf8e Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 3 May 2024 13:50:50 +0100 Subject: [PATCH 203/238] C++: Convert IR variables to an abstract base class and use final alias'ing to ensure that we don't accidentially extend the abstract base class. --- .../implementation/aliased_ssa/IRVariable.qll | 102 ++++++++++-------- 1 file changed, 55 insertions(+), 47 deletions(-) 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 b31c7898ba72..63be372b943f 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 @@ -17,18 +17,11 @@ private import Imports::IRType * The variable may be a user-declared variable (`IRUserVariable`) or a temporary variable generated * by the AST-to-IR translation (`IRTempVariable`). */ -class IRVariable extends TIRVariable { +abstract private class AbstractIRVariable extends TIRVariable { Language::Declaration func; - IRVariable() { - this = TIRUserVariable(_, _, func) or - this = TIRTempVariable(func, _, _, _) or - this = TIRStringLiteral(func, _, _, _) or - this = TIRDynamicInitializationFlag(func, _, _) - } - /** Gets a textual representation of this element. */ - string toString() { none() } + abstract string toString(); /** * Holds if this variable's value cannot be changed within a function. Currently used for string @@ -49,13 +42,13 @@ class IRVariable extends TIRVariable { /** * Gets the type of the variable. */ - Language::LanguageType getLanguageType() { none() } + abstract Language::LanguageType getLanguageType(); /** * 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() } + abstract Language::AST getAst(); /** DEPRECATED: Alias for getAst */ deprecated Language::AST getAST() { result = this.getAst() } @@ -64,7 +57,7 @@ class IRVariable extends TIRVariable { * Gets an identifier string for the variable. This identifier is unique * within the function. */ - string getUniqueId() { none() } + abstract string getUniqueId(); /** * Gets the source location of this variable. @@ -74,18 +67,28 @@ class IRVariable extends TIRVariable { /** * Gets the IR for the function that references this variable. */ - final IRFunction getEnclosingIRFunction() { result.getFunction() = func } + final IRFunction getEnclosingIRFunction() { result.getFunction() = this.getEnclosingFunction() } /** * Gets the function that references this variable. */ final Language::Declaration getEnclosingFunction() { result = func } + + IRBlock getDeclarationBlock() { none() } } +/** + * A variable referenced by the IR for a function. + * + * The variable may be a user-declared variable (`IRUserVariable`) or a temporary variable generated + * by the AST-to-IR translation (`IRTempVariable`). + */ +final class IRVariable = AbstractIRVariable; + /** * A user-declared variable referenced by the IR for a function. */ -class IRUserVariable extends IRVariable, TIRUserVariable { +class IRUserVariable extends AbstractIRVariable, TIRUserVariable { Language::Variable var; Language::LanguageType type; @@ -114,27 +117,30 @@ class IRUserVariable extends IRVariable, TIRUserVariable { * A variable (user-declared or temporary) that is allocated on the stack. This includes all * parameters, non-static local variables, and temporary variables. */ -class IRAutomaticVariable extends IRVariable { - IRAutomaticVariable() { - exists(Language::Variable var | - this = TIRUserVariable(var, _, func) and - Language::isVariableAutomatic(var) - ) - or - this = TIRTempVariable(func, _, _, _) - } -} +abstract private class AbstractIRAutomaticVariable extends AbstractIRVariable { } + +/** + * A variable (user-declared or temporary) that is allocated on the stack. This includes all + * parameters, non-static local variables, and temporary variables. + */ +final class IRAutomaticVariable = AbstractIRAutomaticVariable; /** * A user-declared variable that is allocated on the stack. This includes all parameters and * non-static local variables. */ -class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable { +private class AbstractIRAutomaticUserVariable extends IRUserVariable, AbstractIRAutomaticVariable { override Language::AutomaticVariable var; final override Language::AutomaticVariable getVariable() { result = var } } +/** + * A user-declared variable that is allocated on the stack. This includes all parameters and + * non-static local variables. + */ +final class IRAutomaticUserVariable = AbstractIRAutomaticUserVariable; + /** * A user-declared variable that is not allocated on the stack. This includes all global variables, * namespace-scope variables, static fields, and static local variables. @@ -151,16 +157,10 @@ class IRStaticUserVariable extends IRUserVariable { * A variable that is not user-declared. This includes temporary variables generated as part of IR * construction, as well as string literals. */ -class IRGeneratedVariable extends IRVariable { +abstract private class AbstractIRGeneratedVariable extends AbstractIRVariable { Language::AST ast; Language::LanguageType type; - IRGeneratedVariable() { - this = TIRTempVariable(func, ast, _, type) or - this = TIRStringLiteral(func, ast, type, _) or - this = TIRDynamicInitializationFlag(func, ast, type) - } - final override Language::LanguageType getLanguageType() { result = type } final override Language::AST getAst() { result = ast } @@ -196,12 +196,20 @@ class IRGeneratedVariable extends IRVariable { string getBaseString() { none() } } +/** + * A variable that is not user-declared. This includes temporary variables generated as part of IR + * construction, as well as string literals. + */ +final class IRGeneratedVariable = AbstractIRGeneratedVariable; + /** * A temporary variable introduced by IR construction. The most common examples are the variable * generated to hold the return value of a function, or the variable generated to hold the result of * a condition operator (`a ? b : c`). */ -class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVariable { +class IRTempVariable extends AbstractIRGeneratedVariable, AbstractIRAutomaticVariable, + TIRTempVariable +{ TempVariableTag tag; IRTempVariable() { this = TIRTempVariable(func, ast, tag, type) } @@ -241,7 +249,7 @@ class IRThrowVariable extends IRTempVariable { * A temporary variable generated to hold the contents of all arguments passed to the `...` of a * function that accepts a variable number of arguments. */ -class IREllipsisVariable extends IRTempVariable, IRParameter { +class IREllipsisVariable extends IRTempVariable, AbstractIRParameter { IREllipsisVariable() { tag = EllipsisTempVar() } final override string toString() { result = "#ellipsis" } @@ -252,7 +260,7 @@ class IREllipsisVariable extends IRTempVariable, IRParameter { /** * A temporary variable generated to hold the `this` pointer. */ -class IRThisVariable extends IRTempVariable, IRParameter { +class IRThisVariable extends IRTempVariable, AbstractIRParameter { IRThisVariable() { tag = ThisTempVar() } final override string toString() { result = "#this" } @@ -264,7 +272,7 @@ class IRThisVariable extends IRTempVariable, IRParameter { * A variable generated to represent the contents of a string literal. This variable acts much like * a read-only global variable. */ -class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral { +class IRStringLiteral extends AbstractIRGeneratedVariable, TIRStringLiteral { Language::StringLiteral literal; IRStringLiteral() { this = TIRStringLiteral(func, ast, type, literal) } @@ -288,7 +296,7 @@ class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral { * used to model the runtime initialization of static local variables in C++, as well as static * fields in C#. */ -class IRDynamicInitializationFlag extends IRGeneratedVariable, TIRDynamicInitializationFlag { +class IRDynamicInitializationFlag extends AbstractIRGeneratedVariable, TIRDynamicInitializationFlag { Language::Variable var; IRDynamicInitializationFlag() { @@ -314,24 +322,24 @@ class IRDynamicInitializationFlag extends IRGeneratedVariable, TIRDynamicInitial * An IR variable which acts like a function parameter, including positional parameters and the * temporary variables generated for `this` and ellipsis parameters. */ -class IRParameter extends IRAutomaticVariable { - IRParameter() { - this.(IRAutomaticUserVariable).getVariable() instanceof Language::Parameter - or - this = TIRTempVariable(_, _, ThisTempVar(), _) - or - this = TIRTempVariable(_, _, EllipsisTempVar(), _) - } - +abstract private class AbstractIRParameter extends AbstractIRAutomaticVariable { /** * Gets the zero-based index of this parameter. The `this` parameter has index -1. */ int getIndex() { none() } } +/** + * An IR variable which acts like a function parameter, including positional parameters and the + * temporary variables generated for `this` and ellipsis parameters. + */ +final class IRParameter = AbstractIRParameter; + /** * An IR variable representing a positional parameter. */ -class IRPositionalParameter extends IRParameter, IRAutomaticUserVariable { +class IRPositionalParameter extends AbstractIRParameter, AbstractIRAutomaticUserVariable { + IRPositionalParameter() { this.getVariable() instanceof Language::Parameter } + final override int getIndex() { result = this.getVariable().(Language::Parameter).getIndex() } } From 7ca54a6f94edc5897ec2f0e814e7b3d45de0387e Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 3 May 2024 13:51:04 +0100 Subject: [PATCH 204/238] C++: Sync identical files. --- .../cpp/ir/implementation/raw/IRVariable.qll | 102 ++++++++++-------- .../unaliased_ssa/IRVariable.qll | 102 ++++++++++-------- 2 files changed, 110 insertions(+), 94 deletions(-) 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 b31c7898ba72..63be372b943f 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 @@ -17,18 +17,11 @@ private import Imports::IRType * The variable may be a user-declared variable (`IRUserVariable`) or a temporary variable generated * by the AST-to-IR translation (`IRTempVariable`). */ -class IRVariable extends TIRVariable { +abstract private class AbstractIRVariable extends TIRVariable { Language::Declaration func; - IRVariable() { - this = TIRUserVariable(_, _, func) or - this = TIRTempVariable(func, _, _, _) or - this = TIRStringLiteral(func, _, _, _) or - this = TIRDynamicInitializationFlag(func, _, _) - } - /** Gets a textual representation of this element. */ - string toString() { none() } + abstract string toString(); /** * Holds if this variable's value cannot be changed within a function. Currently used for string @@ -49,13 +42,13 @@ class IRVariable extends TIRVariable { /** * Gets the type of the variable. */ - Language::LanguageType getLanguageType() { none() } + abstract Language::LanguageType getLanguageType(); /** * 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() } + abstract Language::AST getAst(); /** DEPRECATED: Alias for getAst */ deprecated Language::AST getAST() { result = this.getAst() } @@ -64,7 +57,7 @@ class IRVariable extends TIRVariable { * Gets an identifier string for the variable. This identifier is unique * within the function. */ - string getUniqueId() { none() } + abstract string getUniqueId(); /** * Gets the source location of this variable. @@ -74,18 +67,28 @@ class IRVariable extends TIRVariable { /** * Gets the IR for the function that references this variable. */ - final IRFunction getEnclosingIRFunction() { result.getFunction() = func } + final IRFunction getEnclosingIRFunction() { result.getFunction() = this.getEnclosingFunction() } /** * Gets the function that references this variable. */ final Language::Declaration getEnclosingFunction() { result = func } + + IRBlock getDeclarationBlock() { none() } } +/** + * A variable referenced by the IR for a function. + * + * The variable may be a user-declared variable (`IRUserVariable`) or a temporary variable generated + * by the AST-to-IR translation (`IRTempVariable`). + */ +final class IRVariable = AbstractIRVariable; + /** * A user-declared variable referenced by the IR for a function. */ -class IRUserVariable extends IRVariable, TIRUserVariable { +class IRUserVariable extends AbstractIRVariable, TIRUserVariable { Language::Variable var; Language::LanguageType type; @@ -114,27 +117,30 @@ class IRUserVariable extends IRVariable, TIRUserVariable { * A variable (user-declared or temporary) that is allocated on the stack. This includes all * parameters, non-static local variables, and temporary variables. */ -class IRAutomaticVariable extends IRVariable { - IRAutomaticVariable() { - exists(Language::Variable var | - this = TIRUserVariable(var, _, func) and - Language::isVariableAutomatic(var) - ) - or - this = TIRTempVariable(func, _, _, _) - } -} +abstract private class AbstractIRAutomaticVariable extends AbstractIRVariable { } + +/** + * A variable (user-declared or temporary) that is allocated on the stack. This includes all + * parameters, non-static local variables, and temporary variables. + */ +final class IRAutomaticVariable = AbstractIRAutomaticVariable; /** * A user-declared variable that is allocated on the stack. This includes all parameters and * non-static local variables. */ -class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable { +private class AbstractIRAutomaticUserVariable extends IRUserVariable, AbstractIRAutomaticVariable { override Language::AutomaticVariable var; final override Language::AutomaticVariable getVariable() { result = var } } +/** + * A user-declared variable that is allocated on the stack. This includes all parameters and + * non-static local variables. + */ +final class IRAutomaticUserVariable = AbstractIRAutomaticUserVariable; + /** * A user-declared variable that is not allocated on the stack. This includes all global variables, * namespace-scope variables, static fields, and static local variables. @@ -151,16 +157,10 @@ class IRStaticUserVariable extends IRUserVariable { * A variable that is not user-declared. This includes temporary variables generated as part of IR * construction, as well as string literals. */ -class IRGeneratedVariable extends IRVariable { +abstract private class AbstractIRGeneratedVariable extends AbstractIRVariable { Language::AST ast; Language::LanguageType type; - IRGeneratedVariable() { - this = TIRTempVariable(func, ast, _, type) or - this = TIRStringLiteral(func, ast, type, _) or - this = TIRDynamicInitializationFlag(func, ast, type) - } - final override Language::LanguageType getLanguageType() { result = type } final override Language::AST getAst() { result = ast } @@ -196,12 +196,20 @@ class IRGeneratedVariable extends IRVariable { string getBaseString() { none() } } +/** + * A variable that is not user-declared. This includes temporary variables generated as part of IR + * construction, as well as string literals. + */ +final class IRGeneratedVariable = AbstractIRGeneratedVariable; + /** * A temporary variable introduced by IR construction. The most common examples are the variable * generated to hold the return value of a function, or the variable generated to hold the result of * a condition operator (`a ? b : c`). */ -class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVariable { +class IRTempVariable extends AbstractIRGeneratedVariable, AbstractIRAutomaticVariable, + TIRTempVariable +{ TempVariableTag tag; IRTempVariable() { this = TIRTempVariable(func, ast, tag, type) } @@ -241,7 +249,7 @@ class IRThrowVariable extends IRTempVariable { * A temporary variable generated to hold the contents of all arguments passed to the `...` of a * function that accepts a variable number of arguments. */ -class IREllipsisVariable extends IRTempVariable, IRParameter { +class IREllipsisVariable extends IRTempVariable, AbstractIRParameter { IREllipsisVariable() { tag = EllipsisTempVar() } final override string toString() { result = "#ellipsis" } @@ -252,7 +260,7 @@ class IREllipsisVariable extends IRTempVariable, IRParameter { /** * A temporary variable generated to hold the `this` pointer. */ -class IRThisVariable extends IRTempVariable, IRParameter { +class IRThisVariable extends IRTempVariable, AbstractIRParameter { IRThisVariable() { tag = ThisTempVar() } final override string toString() { result = "#this" } @@ -264,7 +272,7 @@ class IRThisVariable extends IRTempVariable, IRParameter { * A variable generated to represent the contents of a string literal. This variable acts much like * a read-only global variable. */ -class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral { +class IRStringLiteral extends AbstractIRGeneratedVariable, TIRStringLiteral { Language::StringLiteral literal; IRStringLiteral() { this = TIRStringLiteral(func, ast, type, literal) } @@ -288,7 +296,7 @@ class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral { * used to model the runtime initialization of static local variables in C++, as well as static * fields in C#. */ -class IRDynamicInitializationFlag extends IRGeneratedVariable, TIRDynamicInitializationFlag { +class IRDynamicInitializationFlag extends AbstractIRGeneratedVariable, TIRDynamicInitializationFlag { Language::Variable var; IRDynamicInitializationFlag() { @@ -314,24 +322,24 @@ class IRDynamicInitializationFlag extends IRGeneratedVariable, TIRDynamicInitial * An IR variable which acts like a function parameter, including positional parameters and the * temporary variables generated for `this` and ellipsis parameters. */ -class IRParameter extends IRAutomaticVariable { - IRParameter() { - this.(IRAutomaticUserVariable).getVariable() instanceof Language::Parameter - or - this = TIRTempVariable(_, _, ThisTempVar(), _) - or - this = TIRTempVariable(_, _, EllipsisTempVar(), _) - } - +abstract private class AbstractIRParameter extends AbstractIRAutomaticVariable { /** * Gets the zero-based index of this parameter. The `this` parameter has index -1. */ int getIndex() { none() } } +/** + * An IR variable which acts like a function parameter, including positional parameters and the + * temporary variables generated for `this` and ellipsis parameters. + */ +final class IRParameter = AbstractIRParameter; + /** * An IR variable representing a positional parameter. */ -class IRPositionalParameter extends IRParameter, IRAutomaticUserVariable { +class IRPositionalParameter extends AbstractIRParameter, AbstractIRAutomaticUserVariable { + IRPositionalParameter() { this.getVariable() instanceof Language::Parameter } + final override int getIndex() { result = this.getVariable().(Language::Parameter).getIndex() } } 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 b31c7898ba72..63be372b943f 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 @@ -17,18 +17,11 @@ private import Imports::IRType * The variable may be a user-declared variable (`IRUserVariable`) or a temporary variable generated * by the AST-to-IR translation (`IRTempVariable`). */ -class IRVariable extends TIRVariable { +abstract private class AbstractIRVariable extends TIRVariable { Language::Declaration func; - IRVariable() { - this = TIRUserVariable(_, _, func) or - this = TIRTempVariable(func, _, _, _) or - this = TIRStringLiteral(func, _, _, _) or - this = TIRDynamicInitializationFlag(func, _, _) - } - /** Gets a textual representation of this element. */ - string toString() { none() } + abstract string toString(); /** * Holds if this variable's value cannot be changed within a function. Currently used for string @@ -49,13 +42,13 @@ class IRVariable extends TIRVariable { /** * Gets the type of the variable. */ - Language::LanguageType getLanguageType() { none() } + abstract Language::LanguageType getLanguageType(); /** * 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() } + abstract Language::AST getAst(); /** DEPRECATED: Alias for getAst */ deprecated Language::AST getAST() { result = this.getAst() } @@ -64,7 +57,7 @@ class IRVariable extends TIRVariable { * Gets an identifier string for the variable. This identifier is unique * within the function. */ - string getUniqueId() { none() } + abstract string getUniqueId(); /** * Gets the source location of this variable. @@ -74,18 +67,28 @@ class IRVariable extends TIRVariable { /** * Gets the IR for the function that references this variable. */ - final IRFunction getEnclosingIRFunction() { result.getFunction() = func } + final IRFunction getEnclosingIRFunction() { result.getFunction() = this.getEnclosingFunction() } /** * Gets the function that references this variable. */ final Language::Declaration getEnclosingFunction() { result = func } + + IRBlock getDeclarationBlock() { none() } } +/** + * A variable referenced by the IR for a function. + * + * The variable may be a user-declared variable (`IRUserVariable`) or a temporary variable generated + * by the AST-to-IR translation (`IRTempVariable`). + */ +final class IRVariable = AbstractIRVariable; + /** * A user-declared variable referenced by the IR for a function. */ -class IRUserVariable extends IRVariable, TIRUserVariable { +class IRUserVariable extends AbstractIRVariable, TIRUserVariable { Language::Variable var; Language::LanguageType type; @@ -114,27 +117,30 @@ class IRUserVariable extends IRVariable, TIRUserVariable { * A variable (user-declared or temporary) that is allocated on the stack. This includes all * parameters, non-static local variables, and temporary variables. */ -class IRAutomaticVariable extends IRVariable { - IRAutomaticVariable() { - exists(Language::Variable var | - this = TIRUserVariable(var, _, func) and - Language::isVariableAutomatic(var) - ) - or - this = TIRTempVariable(func, _, _, _) - } -} +abstract private class AbstractIRAutomaticVariable extends AbstractIRVariable { } + +/** + * A variable (user-declared or temporary) that is allocated on the stack. This includes all + * parameters, non-static local variables, and temporary variables. + */ +final class IRAutomaticVariable = AbstractIRAutomaticVariable; /** * A user-declared variable that is allocated on the stack. This includes all parameters and * non-static local variables. */ -class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable { +private class AbstractIRAutomaticUserVariable extends IRUserVariable, AbstractIRAutomaticVariable { override Language::AutomaticVariable var; final override Language::AutomaticVariable getVariable() { result = var } } +/** + * A user-declared variable that is allocated on the stack. This includes all parameters and + * non-static local variables. + */ +final class IRAutomaticUserVariable = AbstractIRAutomaticUserVariable; + /** * A user-declared variable that is not allocated on the stack. This includes all global variables, * namespace-scope variables, static fields, and static local variables. @@ -151,16 +157,10 @@ class IRStaticUserVariable extends IRUserVariable { * A variable that is not user-declared. This includes temporary variables generated as part of IR * construction, as well as string literals. */ -class IRGeneratedVariable extends IRVariable { +abstract private class AbstractIRGeneratedVariable extends AbstractIRVariable { Language::AST ast; Language::LanguageType type; - IRGeneratedVariable() { - this = TIRTempVariable(func, ast, _, type) or - this = TIRStringLiteral(func, ast, type, _) or - this = TIRDynamicInitializationFlag(func, ast, type) - } - final override Language::LanguageType getLanguageType() { result = type } final override Language::AST getAst() { result = ast } @@ -196,12 +196,20 @@ class IRGeneratedVariable extends IRVariable { string getBaseString() { none() } } +/** + * A variable that is not user-declared. This includes temporary variables generated as part of IR + * construction, as well as string literals. + */ +final class IRGeneratedVariable = AbstractIRGeneratedVariable; + /** * A temporary variable introduced by IR construction. The most common examples are the variable * generated to hold the return value of a function, or the variable generated to hold the result of * a condition operator (`a ? b : c`). */ -class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVariable { +class IRTempVariable extends AbstractIRGeneratedVariable, AbstractIRAutomaticVariable, + TIRTempVariable +{ TempVariableTag tag; IRTempVariable() { this = TIRTempVariable(func, ast, tag, type) } @@ -241,7 +249,7 @@ class IRThrowVariable extends IRTempVariable { * A temporary variable generated to hold the contents of all arguments passed to the `...` of a * function that accepts a variable number of arguments. */ -class IREllipsisVariable extends IRTempVariable, IRParameter { +class IREllipsisVariable extends IRTempVariable, AbstractIRParameter { IREllipsisVariable() { tag = EllipsisTempVar() } final override string toString() { result = "#ellipsis" } @@ -252,7 +260,7 @@ class IREllipsisVariable extends IRTempVariable, IRParameter { /** * A temporary variable generated to hold the `this` pointer. */ -class IRThisVariable extends IRTempVariable, IRParameter { +class IRThisVariable extends IRTempVariable, AbstractIRParameter { IRThisVariable() { tag = ThisTempVar() } final override string toString() { result = "#this" } @@ -264,7 +272,7 @@ class IRThisVariable extends IRTempVariable, IRParameter { * A variable generated to represent the contents of a string literal. This variable acts much like * a read-only global variable. */ -class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral { +class IRStringLiteral extends AbstractIRGeneratedVariable, TIRStringLiteral { Language::StringLiteral literal; IRStringLiteral() { this = TIRStringLiteral(func, ast, type, literal) } @@ -288,7 +296,7 @@ class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral { * used to model the runtime initialization of static local variables in C++, as well as static * fields in C#. */ -class IRDynamicInitializationFlag extends IRGeneratedVariable, TIRDynamicInitializationFlag { +class IRDynamicInitializationFlag extends AbstractIRGeneratedVariable, TIRDynamicInitializationFlag { Language::Variable var; IRDynamicInitializationFlag() { @@ -314,24 +322,24 @@ class IRDynamicInitializationFlag extends IRGeneratedVariable, TIRDynamicInitial * An IR variable which acts like a function parameter, including positional parameters and the * temporary variables generated for `this` and ellipsis parameters. */ -class IRParameter extends IRAutomaticVariable { - IRParameter() { - this.(IRAutomaticUserVariable).getVariable() instanceof Language::Parameter - or - this = TIRTempVariable(_, _, ThisTempVar(), _) - or - this = TIRTempVariable(_, _, EllipsisTempVar(), _) - } - +abstract private class AbstractIRParameter extends AbstractIRAutomaticVariable { /** * Gets the zero-based index of this parameter. The `this` parameter has index -1. */ int getIndex() { none() } } +/** + * An IR variable which acts like a function parameter, including positional parameters and the + * temporary variables generated for `this` and ellipsis parameters. + */ +final class IRParameter = AbstractIRParameter; + /** * An IR variable representing a positional parameter. */ -class IRPositionalParameter extends IRParameter, IRAutomaticUserVariable { +class IRPositionalParameter extends AbstractIRParameter, AbstractIRAutomaticUserVariable { + IRPositionalParameter() { this.getVariable() instanceof Language::Parameter } + final override int getIndex() { result = this.getVariable().(Language::Parameter).getIndex() } } From 2132c7bf967e6975827ce8a35b3511cf8297d3f2 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 3 May 2024 14:52:17 +0200 Subject: [PATCH 205/238] Bazel/Go: make `@codeql//go:gen` runnable from internal repo --- go/BUILD.bazel | 22 +++++++--------------- go/gen.py | 12 +++++++++--- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/go/BUILD.bazel b/go/BUILD.bazel index 6c80e7cb258c..e0da93475a21 100644 --- a/go/BUILD.bazel +++ b/go/BUILD.bazel @@ -1,13 +1,14 @@ load("@bazel_skylib//rules:native_binary.bzl", "native_binary") -load("@gazelle//:def.bzl", "gazelle") load("@rules_pkg//pkg:install.bzl", "pkg_install") load("@rules_pkg//pkg:mappings.bzl", "pkg_attributes", "pkg_filegroup", "pkg_files") load("@rules_pkg//pkg:zip.bzl", "pkg_zip") load("//:defs.bzl", "codeql_platform") -gazelle( +native_binary( name = "gazelle", - extra_args = ["go/extractor"], + src = "@gazelle//cmd/gazelle", + out = "gazelle.exe", + args = ["go/extractor"], ) _gen_binaries = [ @@ -24,9 +25,9 @@ py_binary( deps = ["@rules_python//python/runfiles"], ) -# this is an internal copy of the dbscheme to be used by extractor-pack -# this allows the extractor-pack target to be independent and up-to-date with respect to -# having run //go:gen to update the checked in files +# this is an instance of the dbscheme kept in the bazel build tree +# this allows everything that bazel builds to be up-to-date, +# independently from whether //go:gen was already run to update the checked in files genrule( name = "dbscheme", outs = ["go.dbscheme"], @@ -108,12 +109,3 @@ py_binary( main = "create_extractor_pack.py", deps = ["@rules_python//python/runfiles"], ) - -native_binary( - name = "gen-dbscheme", - src = "//go/extractor/cli/go-gen-dbscheme", - out = "go-gen-dbscheme", - args = [ - "$$BUILD_WORKSPACE_DIRECTORY/go/ql/lib/go.dbscheme", - ], -) diff --git a/go/gen.py b/go/gen.py index 0e9005571ea4..6f8d47d70962 100644 --- a/go/gen.py +++ b/go/gen.py @@ -24,12 +24,18 @@ def options(): opts = options() try: - workspace_dir = pathlib.Path(os.environ['BUILD_WORKSPACE_DIRECTORY']) + workspace_dir = pathlib.Path(os.environ.pop('BUILD_WORKSPACE_DIRECTORY')) except KeyError: print("this should be run with bazel run", file=sys.stderr) sys.exit(1) go_extractor_dir = workspace_dir / "go" / "extractor" + +if not go_extractor_dir.exists(): + # internal repo? + workspace_dir /= "ql" + go_extractor_dir = workspace_dir / "go" / "extractor" + go_dbscheme = workspace_dir / "go" / "ql" / "lib" / "go.dbscheme" r = runfiles.Create() go, gazelle, go_gen_dbscheme = map(r.Rlocation, opts.executables) @@ -49,8 +55,8 @@ def options(): for build_file in existing_build_files: build_file.unlink() -print("running gazelle") -subprocess.check_call([gazelle]) +print("running gazelle", gazelle, go_extractor_dir) +subprocess.check_call([gazelle, "go/extractor"], cwd=workspace_dir) # we want to stamp all newly generated `BUILD.bazel` files with a header build_files_to_update = set(go_extractor_dir.glob("*/**/BUILD.bazel")) From 471303bd7ce7e45182cc586db60344f7bae86858 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 3 May 2024 14:56:17 +0200 Subject: [PATCH 206/238] Bazel/Go: remove unneeded comment --- MODULE.bazel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MODULE.bazel b/MODULE.bazel index d069d320f07a..27479e1978f7 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -55,7 +55,7 @@ node.toolchain( use_repo(node, "nodejs", "nodejs_toolchains") go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk") -go_sdk.download(version = "1.22.2") # default +go_sdk.download(version = "1.22.2") register_toolchains( "@nodejs_toolchains//:all", From d5475c4a899aaddb5d4e401390c3618401e4fce2 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 3 May 2024 14:48:01 +0100 Subject: [PATCH 207/238] C++: Delete predicate that I introduced by mistake. --- .../code/cpp/ir/implementation/aliased_ssa/IRVariable.qll | 2 -- cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRVariable.qll | 2 -- .../code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll | 2 -- 3 files changed, 6 deletions(-) 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 63be372b943f..24135820ab8b 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 @@ -73,8 +73,6 @@ abstract private class AbstractIRVariable extends TIRVariable { * Gets the function that references this variable. */ final Language::Declaration getEnclosingFunction() { result = func } - - IRBlock getDeclarationBlock() { none() } } /** 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 63be372b943f..24135820ab8b 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 @@ -73,8 +73,6 @@ abstract private class AbstractIRVariable extends TIRVariable { * Gets the function that references this variable. */ final Language::Declaration getEnclosingFunction() { result = func } - - IRBlock getDeclarationBlock() { none() } } /** 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 63be372b943f..24135820ab8b 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 @@ -73,8 +73,6 @@ abstract private class AbstractIRVariable extends TIRVariable { * Gets the function that references this variable. */ final Language::Declaration getEnclosingFunction() { result = func } - - IRBlock getDeclarationBlock() { none() } } /** From 17990da205995d0fcd7f052287ba9ecb15616e69 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 3 May 2024 15:58:43 +0200 Subject: [PATCH 208/238] Update go/extractor/BUILD.bazel Co-authored-by: Cornelius Riemenschneider --- go/extractor/BUILD.bazel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/extractor/BUILD.bazel b/go/extractor/BUILD.bazel index 297ca52c8b80..6047eea6860c 100644 --- a/go/extractor/BUILD.bazel +++ b/go/extractor/BUILD.bazel @@ -25,7 +25,7 @@ go_library( ], ) -# notice that these other targets are not generated +# the other targets are not generated java_library( name = "tokenizer-deps", srcs = [ From 7a1b85aa56063210db75f5394c68d38f014b7967 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 3 May 2024 16:04:21 +0100 Subject: [PATCH 209/238] C++: Add FP test. --- .../IteratorToExpiredContainer.expected | 1 + .../semmle/tests/IteratorToExpiredContainer/test.cpp | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/IteratorToExpiredContainer/IteratorToExpiredContainer.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/IteratorToExpiredContainer/IteratorToExpiredContainer.expected index f47e5d655b96..5bb295dc02a2 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/IteratorToExpiredContainer/IteratorToExpiredContainer.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/IteratorToExpiredContainer/IteratorToExpiredContainer.expected @@ -4,3 +4,4 @@ | test.cpp:702:27:702:27 | call to operator[] | This object is destroyed at the end of the full-expression. | | test.cpp:727:23:727:23 | call to operator[] | This object is destroyed at the end of the full-expression. | | test.cpp:735:23:735:23 | call to operator[] | This object is destroyed at the end of the full-expression. | +| test.cpp:803:3:803:3 | pointer to ~vector output argument | This object is destroyed at the end of the full-expression. | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/IteratorToExpiredContainer/test.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/IteratorToExpiredContainer/test.cpp index 85d9c4b57ad9..0dc97ece06d6 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/IteratorToExpiredContainer/test.cpp +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/IteratorToExpiredContainer/test.cpp @@ -792,4 +792,13 @@ void test4() { // function we may end up in the destructor call `chunk.~A()`in `A.foo`. This destructor // call can flow to `begin` through the back-edge and cause a strange FP. auto zero = A().size(); +} + +void test5(int i) +{ + while(i < 10) { + const auto& vvs = returnValue(); + for(const auto& vs : vvs) { } + ++i; + } // GOOD [FALSE POSITIVE] } \ No newline at end of file From 77128de105d35ada1e379a6dea61d3939e6cab6e Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 3 May 2024 17:44:29 +0200 Subject: [PATCH 210/238] Bazel/Go: make installer work from internal repo and on windows It turns out everything that is needed for the installer to work on windows is enabling runfiles. This also requires symlinks to avoid excessive copying of files. --- .bazelrc | 3 +++ go/BUILD.bazel | 24 +++--------------------- go/create_extractor_pack.py | 24 ++++++++++-------------- 3 files changed, 16 insertions(+), 35 deletions(-) mode change 100644 => 100755 go/create_extractor_pack.py diff --git a/.bazelrc b/.bazelrc index 0a49f682da37..36111310779c 100644 --- a/.bazelrc +++ b/.bazelrc @@ -14,6 +14,9 @@ build:linux --cxxopt=-std=c++20 build:macos --cxxopt=-std=c++20 --cpu=darwin_x86_64 build:windows --cxxopt=/std:c++20 --cxxopt=/Zc:preprocessor +# this requires developer mode, but is required to have pack installer functioning +common:windows --windows_enable_symlinks --enable_runfiles + common --registry=file:///%workspace%/misc/bazel/registry common --registry=https://bcr.bazel.build diff --git a/go/BUILD.bazel b/go/BUILD.bazel index e0da93475a21..4fb73a51fb69 100644 --- a/go/BUILD.bazel +++ b/go/BUILD.bazel @@ -1,7 +1,6 @@ load("@bazel_skylib//rules:native_binary.bzl", "native_binary") load("@rules_pkg//pkg:install.bzl", "pkg_install") load("@rules_pkg//pkg:mappings.bzl", "pkg_attributes", "pkg_filegroup", "pkg_files") -load("@rules_pkg//pkg:zip.bzl", "pkg_zip") load("//:defs.bzl", "codeql_platform") native_binary( @@ -81,31 +80,14 @@ pkg_filegroup( ) pkg_install( - name = "_extractor-pack-installer", + name = "_extractor_pack", srcs = [":extractor-pack"], ) -# rules_pkg installer is currently broken on Windows -# see https://github.com/bazelbuild/rules_pkg/issues/387 -# for now, work around it using an archive -pkg_zip( - name = "_extractor-pack-zip", - srcs = [":extractor-pack"], -) - -alias( - name = "_create-extractor-pack-arg", - actual = select({ - "@platforms//os:windows": ":_extractor-pack-zip", - "//conditions:default": ":_extractor-pack-installer", - }), -) - py_binary( name = "create-extractor-pack", srcs = ["create_extractor_pack.py"], - args = ["$(rlocationpath :_create-extractor-pack-arg)"], - data = [":_create-extractor-pack-arg"], + env = {"REPO_NAME": repo_name()}, main = "create_extractor_pack.py", - deps = ["@rules_python//python/runfiles"], + deps = ["_extractor_pack"], ) diff --git a/go/create_extractor_pack.py b/go/create_extractor_pack.py old mode 100644 new mode 100755 index a1154a777d85..4d194ab93e46 --- a/go/create_extractor_pack.py +++ b/go/create_extractor_pack.py @@ -1,26 +1,22 @@ +#!/usr/bin/env python3 import os import pathlib import shutil import sys import subprocess -import zipfile -from python.runfiles import runfiles try: workspace_dir = pathlib.Path(os.environ['BUILD_WORKSPACE_DIRECTORY']) except KeyError: - print("this should be run with bazel run", file=sys.stderr) - sys.exit(1) + res = subprocess.run(["bazel", "run", ":create-extractor-pack"], cwd=pathlib.Path(__file__).parent) + sys.exit(res.returncode) -dest_dir = workspace_dir / 'go' / 'build' / 'codeql-extractor-go' -installer_or_zip = pathlib.Path(runfiles.Create().Rlocation(sys.argv[1])) +from go._extractor_pack_install_script import main -shutil.rmtree(dest_dir, ignore_errors=True) +if os.environ['REPO_NAME'] == 'codeql~': + workspace_dir /= 'ql' -if installer_or_zip.suffix == '.zip': - dest_dir.mkdir() - with zipfile.ZipFile(installer_or_zip) as pack: - pack.extractall(dest_dir) -else: - os.environ['DESTDIR'] = str(dest_dir) - subprocess.check_call([installer_or_zip]) +dest_dir = workspace_dir / 'go' / 'build' / 'codeql-extractor-pack' +shutil.rmtree(dest_dir, ignore_errors=True) +os.environ['DESTDIR'] = str(dest_dir) +main(sys.argv) From b209fc67cbdd9b366239f877f7734e852c0e1071 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Fri, 3 May 2024 19:34:18 +0200 Subject: [PATCH 211/238] test the change to hardcoded-credentials --- .../CWE-798/HardcodedCredentials.expected | 24 +++++++++++-------- .../Security/CWE-798/HardcodedCredentials.js | 8 +++++-- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.expected b/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.expected index 3635090cb433..0a9edfb64f86 100644 --- a/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.expected +++ b/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.expected @@ -153,12 +153,12 @@ nodes | HardcodedCredentials.js:135:41:135:50 | "hgfedcba" | | HardcodedCredentials.js:135:41:135:50 | "hgfedcba" | | HardcodedCredentials.js:135:41:135:50 | "hgfedcba" | -| HardcodedCredentials.js:160:38:160:48 | "change_me" | -| HardcodedCredentials.js:160:38:160:48 | "change_me" | -| HardcodedCredentials.js:160:38:160:48 | "change_me" | -| HardcodedCredentials.js:161:41:161:51 | 'change_me' | -| HardcodedCredentials.js:161:41:161:51 | 'change_me' | -| HardcodedCredentials.js:161:41:161:51 | 'change_me' | +| HardcodedCredentials.js:160:38:160:56 | "oiuneawrgiyubaegr" | +| HardcodedCredentials.js:160:38:160:56 | "oiuneawrgiyubaegr" | +| HardcodedCredentials.js:160:38:160:56 | "oiuneawrgiyubaegr" | +| HardcodedCredentials.js:161:41:161:59 | 'oiuneawrgiyubaegr' | +| HardcodedCredentials.js:161:41:161:59 | 'oiuneawrgiyubaegr' | +| HardcodedCredentials.js:161:41:161:59 | 'oiuneawrgiyubaegr' | | HardcodedCredentials.js:164:35:164:45 | 'change_me' | | HardcodedCredentials.js:164:35:164:45 | 'change_me' | | HardcodedCredentials.js:164:35:164:45 | 'change_me' | @@ -271,6 +271,9 @@ nodes | HardcodedCredentials.js:295:37:295:66 | `Basic ... 000001` | | HardcodedCredentials.js:295:37:295:66 | `Basic ... 000001` | | HardcodedCredentials.js:295:37:295:66 | `Basic ... 000001` | +| HardcodedCredentials.js:299:44:299:52 | 'mytoken' | +| HardcodedCredentials.js:299:44:299:52 | 'mytoken' | +| HardcodedCredentials.js:299:44:299:52 | 'mytoken' | edges | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | | HardcodedCredentials.js:8:19:8:28 | 'hgfedcba' | HardcodedCredentials.js:8:19:8:28 | 'hgfedcba' | @@ -326,8 +329,8 @@ edges | HardcodedCredentials.js:130:44:130:53 | 'hgfedcba' | HardcodedCredentials.js:130:44:130:53 | 'hgfedcba' | | HardcodedCredentials.js:131:52:131:61 | 'hgfedcba' | HardcodedCredentials.js:131:52:131:61 | 'hgfedcba' | | HardcodedCredentials.js:135:41:135:50 | "hgfedcba" | HardcodedCredentials.js:135:41:135:50 | "hgfedcba" | -| HardcodedCredentials.js:160:38:160:48 | "change_me" | HardcodedCredentials.js:160:38:160:48 | "change_me" | -| HardcodedCredentials.js:161:41:161:51 | 'change_me' | HardcodedCredentials.js:161:41:161:51 | 'change_me' | +| HardcodedCredentials.js:160:38:160:56 | "oiuneawrgiyubaegr" | HardcodedCredentials.js:160:38:160:56 | "oiuneawrgiyubaegr" | +| HardcodedCredentials.js:161:41:161:59 | 'oiuneawrgiyubaegr' | HardcodedCredentials.js:161:41:161:59 | 'oiuneawrgiyubaegr' | | HardcodedCredentials.js:164:35:164:45 | 'change_me' | HardcodedCredentials.js:164:35:164:45 | 'change_me' | | HardcodedCredentials.js:171:11:171:25 | USER | HardcodedCredentials.js:173:35:173:38 | USER | | HardcodedCredentials.js:171:18:171:25 | 'sdsdag' | HardcodedCredentials.js:171:11:171:25 | USER | @@ -399,6 +402,7 @@ edges | HardcodedCredentials.js:293:37:293:65 | `Basic ... xxxxxx` | HardcodedCredentials.js:293:37:293:65 | `Basic ... xxxxxx` | | HardcodedCredentials.js:294:37:294:70 | `Basic ... gbbbbb` | HardcodedCredentials.js:294:37:294:70 | `Basic ... gbbbbb` | | HardcodedCredentials.js:295:37:295:66 | `Basic ... 000001` | HardcodedCredentials.js:295:37:295:66 | `Basic ... 000001` | +| HardcodedCredentials.js:299:44:299:52 | 'mytoken' | HardcodedCredentials.js:299:44:299:52 | 'mytoken' | #select | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | The hard-coded value "dbuser" is used as $@. | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | user name | | HardcodedCredentials.js:8:19:8:28 | 'hgfedcba' | HardcodedCredentials.js:8:19:8:28 | 'hgfedcba' | HardcodedCredentials.js:8:19:8:28 | 'hgfedcba' | The hard-coded value "hgfedcba" is used as $@. | HardcodedCredentials.js:8:19:8:28 | 'hgfedcba' | password | @@ -448,8 +452,8 @@ edges | HardcodedCredentials.js:130:44:130:53 | 'hgfedcba' | HardcodedCredentials.js:130:44:130:53 | 'hgfedcba' | HardcodedCredentials.js:130:44:130:53 | 'hgfedcba' | The hard-coded value "hgfedcba" is used as $@. | HardcodedCredentials.js:130:44:130:53 | 'hgfedcba' | key | | HardcodedCredentials.js:131:52:131:61 | 'hgfedcba' | HardcodedCredentials.js:131:52:131:61 | 'hgfedcba' | HardcodedCredentials.js:131:52:131:61 | 'hgfedcba' | The hard-coded value "hgfedcba" is used as $@. | HardcodedCredentials.js:131:52:131:61 | 'hgfedcba' | key | | HardcodedCredentials.js:135:41:135:50 | "hgfedcba" | HardcodedCredentials.js:135:41:135:50 | "hgfedcba" | HardcodedCredentials.js:135:41:135:50 | "hgfedcba" | The hard-coded value "hgfedcba" is used as $@. | HardcodedCredentials.js:135:41:135:50 | "hgfedcba" | key | -| HardcodedCredentials.js:160:38:160:48 | "change_me" | HardcodedCredentials.js:160:38:160:48 | "change_me" | HardcodedCredentials.js:160:38:160:48 | "change_me" | The hard-coded value "change_me" is used as $@. | HardcodedCredentials.js:160:38:160:48 | "change_me" | key | -| HardcodedCredentials.js:161:41:161:51 | 'change_me' | HardcodedCredentials.js:161:41:161:51 | 'change_me' | HardcodedCredentials.js:161:41:161:51 | 'change_me' | The hard-coded value "change_me" is used as $@. | HardcodedCredentials.js:161:41:161:51 | 'change_me' | key | +| HardcodedCredentials.js:160:38:160:56 | "oiuneawrgiyubaegr" | HardcodedCredentials.js:160:38:160:56 | "oiuneawrgiyubaegr" | HardcodedCredentials.js:160:38:160:56 | "oiuneawrgiyubaegr" | The hard-coded value "oiuneawrgiyubaegr" is used as $@. | HardcodedCredentials.js:160:38:160:56 | "oiuneawrgiyubaegr" | key | +| HardcodedCredentials.js:161:41:161:59 | 'oiuneawrgiyubaegr' | HardcodedCredentials.js:161:41:161:59 | 'oiuneawrgiyubaegr' | HardcodedCredentials.js:161:41:161:59 | 'oiuneawrgiyubaegr' | The hard-coded value "oiuneawrgiyubaegr" is used as $@. | HardcodedCredentials.js:161:41:161:59 | 'oiuneawrgiyubaegr' | key | | HardcodedCredentials.js:171:18:171:25 | 'sdsdag' | HardcodedCredentials.js:171:18:171:25 | 'sdsdag' | HardcodedCredentials.js:178:30:178:44 | `Basic ${AUTH}` | The hard-coded value "sdsdag" is used as $@. | HardcodedCredentials.js:178:30:178:44 | `Basic ${AUTH}` | authorization header | | HardcodedCredentials.js:171:18:171:25 | 'sdsdag' | HardcodedCredentials.js:171:18:171:25 | 'sdsdag' | HardcodedCredentials.js:188:30:188:44 | `Basic ${AUTH}` | The hard-coded value "sdsdag" is used as $@. | HardcodedCredentials.js:188:30:188:44 | `Basic ${AUTH}` | authorization header | | HardcodedCredentials.js:171:18:171:25 | 'sdsdag' | HardcodedCredentials.js:171:18:171:25 | 'sdsdag' | HardcodedCredentials.js:195:37:195:51 | `Basic ${AUTH}` | The hard-coded value "sdsdag" is used as $@. | HardcodedCredentials.js:195:37:195:51 | `Basic ${AUTH}` | authorization header | diff --git a/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.js b/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.js index 8482d5106fe4..b033764f2648 100644 --- a/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.js +++ b/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.js @@ -157,8 +157,8 @@ })(); (function(){ - require("cookie-session")({ secret: "change_me" }); // NOT OK - require('crypto').createHmac('sha256', 'change_me'); // NOT OK + require("cookie-session")({ secret: "oiuneawrgiyubaegr" }); // NOT OK + require('crypto').createHmac('sha256', 'oiuneawrgiyubaegr'); // NOT OK var basicAuth = require('express-basic-auth'); basicAuth({users: { [adminName]: 'change_me' }}); // OK @@ -294,3 +294,7 @@ headers.append("Authorization", `Basic sdsdag:aaaiuogrweuibgbbbbb`); // NOT OK headers.append("Authorization", `Basic sdsdag:000000000000001`); // OK }); + +(function () { + require('crypto').createHmac('sha256', 'mytoken'); // OK +})(); \ No newline at end of file From 39a8b49222c3f3765ed348d70d612a2babedb6ed Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Fri, 3 May 2024 19:37:31 +0200 Subject: [PATCH 212/238] add qhelp recommendation that you can use an obvious placeholder value --- .../src/Security/CWE-798/HardcodedCredentials.qhelp | 4 ++++ .../Security/CWE-798/HardcodedCredentials.expected | 13 +++++++++++++ .../Security/CWE-798/HardcodedCredentials.js | 3 +++ 3 files changed, 20 insertions(+) diff --git a/javascript/ql/src/Security/CWE-798/HardcodedCredentials.qhelp b/javascript/ql/src/Security/CWE-798/HardcodedCredentials.qhelp index adcd6fc47159..b2d00e38c284 100644 --- a/javascript/ql/src/Security/CWE-798/HardcodedCredentials.qhelp +++ b/javascript/ql/src/Security/CWE-798/HardcodedCredentials.qhelp @@ -19,6 +19,10 @@ If possible, store configuration files including credential data separately from the source code, in a secure location with restricted access.

    +

    + If the credentials are a placeholder value, make sure the value is obviously a placeholder by + using a name such as "SampleToken" or "MyPassword". +

    diff --git a/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.expected b/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.expected index 0a9edfb64f86..fc41f193149c 100644 --- a/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.expected +++ b/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.expected @@ -274,6 +274,15 @@ nodes | HardcodedCredentials.js:299:44:299:52 | 'mytoken' | | HardcodedCredentials.js:299:44:299:52 | 'mytoken' | | HardcodedCredentials.js:299:44:299:52 | 'mytoken' | +| HardcodedCredentials.js:300:44:300:56 | 'SampleToken' | +| HardcodedCredentials.js:300:44:300:56 | 'SampleToken' | +| HardcodedCredentials.js:300:44:300:56 | 'SampleToken' | +| HardcodedCredentials.js:301:44:301:55 | 'MyPassword' | +| HardcodedCredentials.js:301:44:301:55 | 'MyPassword' | +| HardcodedCredentials.js:301:44:301:55 | 'MyPassword' | +| HardcodedCredentials.js:302:44:302:69 | 'iubfew ... ybgera' | +| HardcodedCredentials.js:302:44:302:69 | 'iubfew ... ybgera' | +| HardcodedCredentials.js:302:44:302:69 | 'iubfew ... ybgera' | edges | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | | HardcodedCredentials.js:8:19:8:28 | 'hgfedcba' | HardcodedCredentials.js:8:19:8:28 | 'hgfedcba' | @@ -403,6 +412,9 @@ edges | HardcodedCredentials.js:294:37:294:70 | `Basic ... gbbbbb` | HardcodedCredentials.js:294:37:294:70 | `Basic ... gbbbbb` | | HardcodedCredentials.js:295:37:295:66 | `Basic ... 000001` | HardcodedCredentials.js:295:37:295:66 | `Basic ... 000001` | | HardcodedCredentials.js:299:44:299:52 | 'mytoken' | HardcodedCredentials.js:299:44:299:52 | 'mytoken' | +| HardcodedCredentials.js:300:44:300:56 | 'SampleToken' | HardcodedCredentials.js:300:44:300:56 | 'SampleToken' | +| HardcodedCredentials.js:301:44:301:55 | 'MyPassword' | HardcodedCredentials.js:301:44:301:55 | 'MyPassword' | +| HardcodedCredentials.js:302:44:302:69 | 'iubfew ... ybgera' | HardcodedCredentials.js:302:44:302:69 | 'iubfew ... ybgera' | #select | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | The hard-coded value "dbuser" is used as $@. | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | user name | | HardcodedCredentials.js:8:19:8:28 | 'hgfedcba' | HardcodedCredentials.js:8:19:8:28 | 'hgfedcba' | HardcodedCredentials.js:8:19:8:28 | 'hgfedcba' | The hard-coded value "hgfedcba" is used as $@. | HardcodedCredentials.js:8:19:8:28 | 'hgfedcba' | password | @@ -468,3 +480,4 @@ edges | HardcodedCredentials.js:245:22:245:44 | "myHard ... ateKey" | HardcodedCredentials.js:245:22:245:44 | "myHard ... ateKey" | HardcodedCredentials.js:246:42:246:51 | privateKey | The hard-coded value "myHardCodedPrivateKey" is used as $@. | HardcodedCredentials.js:246:42:246:51 | privateKey | key | | HardcodedCredentials.js:292:37:292:57 | `Basic ... sdsdag` | HardcodedCredentials.js:292:37:292:57 | `Basic ... sdsdag` | HardcodedCredentials.js:292:37:292:57 | `Basic ... sdsdag` | The hard-coded value "Basic sdsdag:sdsdag" is used as $@. | HardcodedCredentials.js:292:37:292:57 | `Basic ... sdsdag` | authorization header | | HardcodedCredentials.js:294:37:294:70 | `Basic ... gbbbbb` | HardcodedCredentials.js:294:37:294:70 | `Basic ... gbbbbb` | HardcodedCredentials.js:294:37:294:70 | `Basic ... gbbbbb` | The hard-coded value "Basic sdsdag:aaaiuogrweuibgbbbbb" is used as $@. | HardcodedCredentials.js:294:37:294:70 | `Basic ... gbbbbb` | authorization header | +| HardcodedCredentials.js:302:44:302:69 | 'iubfew ... ybgera' | HardcodedCredentials.js:302:44:302:69 | 'iubfew ... ybgera' | HardcodedCredentials.js:302:44:302:69 | 'iubfew ... ybgera' | The hard-coded value "iubfewiaaweiybgaeuybgera" is used as $@. | HardcodedCredentials.js:302:44:302:69 | 'iubfew ... ybgera' | key | diff --git a/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.js b/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.js index b033764f2648..d1543f16dc75 100644 --- a/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.js +++ b/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.js @@ -297,4 +297,7 @@ (function () { require('crypto').createHmac('sha256', 'mytoken'); // OK + require('crypto').createHmac('sha256', 'SampleToken'); // OK + require('crypto').createHmac('sha256', 'MyPassword'); // OK + require('crypto').createHmac('sha256', 'iubfewiaaweiybgaeuybgera'); // NOT OK })(); \ No newline at end of file From 105984f7de7e13b49d8875b0fba6608ec80e3929 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 6 May 2024 10:01:34 +0200 Subject: [PATCH 213/238] Java: Make param module for MaD inline test. --- .../CaptureTypeBasedSummaryModels.ql | 52 +++++++++++++------ 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/java/ql/test/utils/modelgenerator/typebasedflow/CaptureTypeBasedSummaryModels.ql b/java/ql/test/utils/modelgenerator/typebasedflow/CaptureTypeBasedSummaryModels.ql index fe77abaa6df8..88932d3a1eff 100644 --- a/java/ql/test/utils/modelgenerator/typebasedflow/CaptureTypeBasedSummaryModels.ql +++ b/java/ql/test/utils/modelgenerator/typebasedflow/CaptureTypeBasedSummaryModels.ql @@ -1,26 +1,44 @@ import java import utils.modelgenerator.internal.CaptureTypeBasedSummaryModels -private string expects() { - exists(Javadoc doc | - doc.getChild(0).toString().regexpCapture(" *(SPURIOUS-)?MaD=(.*)", 2) = result - ) +signature module InlineMadTestConfigSig { + /** + * Gets a relevant code comment, if any. + */ + string getComment(); + + /** + * Gets an identified summary, if any. + */ + string getCapturedSummary(); } -private string flows() { result = captureFlow(_) } +module InlineMadTest { + private string expects() { + Input::getComment().regexpCapture(" *(SPURIOUS-)?MaD=(.*)", 2) = result + } + + query predicate unexpectedSummary(string msg) { + exists(string flow | + flow = Input::getCapturedSummary() and + not flow = expects() and + msg = "Unexpected summary found: " + flow + ) + } -query predicate unexpectedSummary(string msg) { - exists(string flow | - flow = flows() and - not flow = expects() and - msg = "Unexpected summary found: " + flow - ) + query predicate expectedSummary(string msg) { + exists(string e | + e = expects() and + not e = Input::getCapturedSummary() and + msg = "Expected summary missing: " + e + ) + } } -query predicate expectedSummary(string msg) { - exists(string e | - e = expects() and - not e = flows() and - msg = "Expected summary missing: " + e - ) +module InlineMadTestConfig implements InlineMadTestConfigSig { + string getComment() { result = any(Javadoc doc).getChild(0).toString() } + + string getCapturedSummary() { result = captureFlow(_) } } + +import InlineMadTest From 6815bcaa80027a01665d5783821d4fe4fb3fea85 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 6 May 2024 10:19:39 +0200 Subject: [PATCH 214/238] Java: Move param module into TestUtilities. --- java/ql/test/TestUtilities/InlineMadTest.qll | 33 +++++++++++++++++ .../CaptureTypeBasedSummaryModels.ql | 35 +------------------ 2 files changed, 34 insertions(+), 34 deletions(-) create mode 100644 java/ql/test/TestUtilities/InlineMadTest.qll diff --git a/java/ql/test/TestUtilities/InlineMadTest.qll b/java/ql/test/TestUtilities/InlineMadTest.qll new file mode 100644 index 000000000000..64badab0dcab --- /dev/null +++ b/java/ql/test/TestUtilities/InlineMadTest.qll @@ -0,0 +1,33 @@ +signature module InlineMadTestConfigSig { + /** + * Gets a relevant code comment, if any. + */ + string getComment(); + + /** + * Gets an identified summary, if any. + */ + string getCapturedSummary(); +} + +module InlineMadTest { + private string expects() { + Input::getComment().regexpCapture(" *(SPURIOUS-)?MaD=(.*)", 2) = result + } + + query predicate unexpectedSummary(string msg) { + exists(string flow | + flow = Input::getCapturedSummary() and + not flow = expects() and + msg = "Unexpected summary found: " + flow + ) + } + + query predicate expectedSummary(string msg) { + exists(string e | + e = expects() and + not e = Input::getCapturedSummary() and + msg = "Expected summary missing: " + e + ) + } +} diff --git a/java/ql/test/utils/modelgenerator/typebasedflow/CaptureTypeBasedSummaryModels.ql b/java/ql/test/utils/modelgenerator/typebasedflow/CaptureTypeBasedSummaryModels.ql index 88932d3a1eff..c5c509ac3268 100644 --- a/java/ql/test/utils/modelgenerator/typebasedflow/CaptureTypeBasedSummaryModels.ql +++ b/java/ql/test/utils/modelgenerator/typebasedflow/CaptureTypeBasedSummaryModels.ql @@ -1,40 +1,7 @@ import java +import TestUtilities.InlineMadTest import utils.modelgenerator.internal.CaptureTypeBasedSummaryModels -signature module InlineMadTestConfigSig { - /** - * Gets a relevant code comment, if any. - */ - string getComment(); - - /** - * Gets an identified summary, if any. - */ - string getCapturedSummary(); -} - -module InlineMadTest { - private string expects() { - Input::getComment().regexpCapture(" *(SPURIOUS-)?MaD=(.*)", 2) = result - } - - query predicate unexpectedSummary(string msg) { - exists(string flow | - flow = Input::getCapturedSummary() and - not flow = expects() and - msg = "Unexpected summary found: " + flow - ) - } - - query predicate expectedSummary(string msg) { - exists(string e | - e = expects() and - not e = Input::getCapturedSummary() and - msg = "Expected summary missing: " + e - ) - } -} - module InlineMadTestConfig implements InlineMadTestConfigSig { string getComment() { result = any(Javadoc doc).getChild(0).toString() } From 7cb8a6c52f9219abd305b3e2a7d6e4f3c29f3eac Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 6 May 2024 11:01:23 +0200 Subject: [PATCH 215/238] Java: Inline models as data expected output as comments in the java files and add a test. --- .../dataflow/CaptureModels.expected | 2 + .../modelgenerator/dataflow/CaptureModels.ql | 11 + .../modelgenerator/dataflow/p/Factory.java | 54 ++--- .../modelgenerator/dataflow/p/FinalClass.java | 18 +- .../modelgenerator/dataflow/p/FluentAPI.java | 20 +- .../dataflow/p/ImmutablePojo.java | 47 ++-- .../dataflow/p/InnerClasses.java | 27 +-- .../dataflow/p/InnerHolder.java | 51 ++--- .../modelgenerator/dataflow/p/Joiner.java | 203 +++++++++--------- .../dataflow/p/MultipleImpl2.java | 29 +-- .../dataflow/p/MultipleImpls.java | 55 ++--- .../modelgenerator/dataflow/p/ParamFlow.java | 97 +++++---- .../utils/modelgenerator/dataflow/p/Pojo.java | 142 ++++++------ .../p/PrivateFlowViaPublicInterface.java | 80 +++---- 14 files changed, 441 insertions(+), 395 deletions(-) create mode 100644 java/ql/test/utils/modelgenerator/dataflow/CaptureModels.expected create mode 100644 java/ql/test/utils/modelgenerator/dataflow/CaptureModels.ql diff --git a/java/ql/test/utils/modelgenerator/dataflow/CaptureModels.expected b/java/ql/test/utils/modelgenerator/dataflow/CaptureModels.expected new file mode 100644 index 000000000000..ee55a9c6ba6e --- /dev/null +++ b/java/ql/test/utils/modelgenerator/dataflow/CaptureModels.expected @@ -0,0 +1,2 @@ +unexpectedSummary +expectedSummary diff --git a/java/ql/test/utils/modelgenerator/dataflow/CaptureModels.ql b/java/ql/test/utils/modelgenerator/dataflow/CaptureModels.ql new file mode 100644 index 000000000000..1a2dbd03d7a9 --- /dev/null +++ b/java/ql/test/utils/modelgenerator/dataflow/CaptureModels.ql @@ -0,0 +1,11 @@ +import java +import utils.modelgenerator.internal.CaptureSummaryFlowQuery +import TestUtilities.InlineMadTest + +module InlineMadTestConfig implements InlineMadTestConfigSig { + string getComment() { result = any(Javadoc doc).getChild(0).toString() } + + string getCapturedSummary() { result = captureFlow(_) } +} + +import InlineMadTest diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/Factory.java b/java/ql/test/utils/modelgenerator/dataflow/p/Factory.java index a6e7ce5fff6a..84b55a812c94 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/Factory.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/Factory.java @@ -2,29 +2,31 @@ public final class Factory { - private String value; - - private int intValue; - - public static Factory create(String value, int foo) { - return new Factory(value, foo); - } - - public static Factory create(String value) { - return new Factory(value, 0); - } - - private Factory(String value, int intValue) { - this.value = value; - this.intValue = intValue; - } - - public String getValue() { - return value; - } - - public int getIntValue() { - return intValue; - } - -} \ No newline at end of file + private String value; + + private int intValue; + + // MaD=p;Factory;false;create;(String,int);;Argument[0];ReturnValue;taint;df-generated + public static Factory create(String value, int foo) { + return new Factory(value, foo); + } + + // MaD=p;Factory;false;create;(String);;Argument[0];ReturnValue;taint;df-generated + public static Factory create(String value) { + return new Factory(value, 0); + } + + private Factory(String value, int intValue) { + this.value = value; + this.intValue = intValue; + } + + // MaD=p;Factory;false;getValue;();;Argument[this];ReturnValue;taint;df-generated + public String getValue() { + return value; + } + + public int getIntValue() { + return intValue; + } +} diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/FinalClass.java b/java/ql/test/utils/modelgenerator/dataflow/p/FinalClass.java index 224fc44a0bc4..5073f4352339 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/FinalClass.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/FinalClass.java @@ -2,14 +2,14 @@ public final class FinalClass { - private static final String C = "constant"; + private static final String C = "constant"; - public String returnsInput(String input) { - return input; - } + // MaD=p;FinalClass;false;returnsInput;(String);;Argument[0];ReturnValue;taint;df-generated + public String returnsInput(String input) { + return input; + } - public String returnsConstant() { - return C; - } - -} \ No newline at end of file + public String returnsConstant() { + return C; + } +} diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/FluentAPI.java b/java/ql/test/utils/modelgenerator/dataflow/p/FluentAPI.java index 65887625d27a..2bb2bb97604e 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/FluentAPI.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/FluentAPI.java @@ -2,14 +2,14 @@ public final class FluentAPI { - public FluentAPI returnsThis(String input) { - return this; + // MaD=p;FluentAPI;false;returnsThis;(String);;Argument[this];ReturnValue;value;df-generated + public FluentAPI returnsThis(String input) { + return this; + } + + public class Inner { + public FluentAPI notThis(String input) { + return FluentAPI.this; } - - public class Inner { - public FluentAPI notThis(String input) { - return FluentAPI.this; - } - } - -} \ No newline at end of file + } +} diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/ImmutablePojo.java b/java/ql/test/utils/modelgenerator/dataflow/p/ImmutablePojo.java index 660c1970bd3c..38a9b472f625 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/ImmutablePojo.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/ImmutablePojo.java @@ -2,25 +2,28 @@ public final class ImmutablePojo { - private final String value; - - private final long x; - - public ImmutablePojo(String value, int x) { - this.value = value; - this.x = x; - } - - public String getValue() { - return value; - } - - public long getX() { - return x; - } - - public String or(String defaultValue) { - return value != null ? value : defaultValue; - } - -} \ No newline at end of file + private final String value; + + private final long x; + + // MaD=p;ImmutablePojo;false;ImmutablePojo;(String,int);;Argument[0];Argument[this];taint;df-generated + public ImmutablePojo(String value, int x) { + this.value = value; + this.x = x; + } + + // MaD=p;ImmutablePojo;false;getValue;();;Argument[this];ReturnValue;taint;df-generated + public String getValue() { + return value; + } + + public long getX() { + return x; + } + + // MaD=p;ImmutablePojo;false;or;(String);;Argument[0];ReturnValue;taint;df-generated + // MaD=p;ImmutablePojo;false;or;(String);;Argument[this];ReturnValue;taint;df-generated + public String or(String defaultValue) { + return value != null ? value : defaultValue; + } +} diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/InnerClasses.java b/java/ql/test/utils/modelgenerator/dataflow/p/InnerClasses.java index 936166eddf3f..54f014fec93b 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/InnerClasses.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/InnerClasses.java @@ -1,21 +1,22 @@ package p; public class InnerClasses { - - class IgnoreMe { - public String no(String input) { - return input; - } - } - - public class CaptureMe { - public String yesCm(String input) { - return input; - } + + class IgnoreMe { + public String no(String input) { + return input; } + } - public String yes(String input) { - return input; + public class CaptureMe { + // MaD=p;InnerClasses$CaptureMe;true;yesCm;(String);;Argument[0];ReturnValue;taint;df-generated + public String yesCm(String input) { + return input; } + } + // MaD=p;InnerClasses;true;yes;(String);;Argument[0];ReturnValue;taint;df-generated + public String yes(String input) { + return input; + } } diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/InnerHolder.java b/java/ql/test/utils/modelgenerator/dataflow/p/InnerHolder.java index 5dc07cadd51c..ef8729421918 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/InnerHolder.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/InnerHolder.java @@ -2,36 +2,39 @@ public final class InnerHolder { - private class Context { - private String value; + private class Context { + private String value; - Context(String value) { - this.value = value; - } - - public String getValue() { - return value; - } + Context(String value) { + this.value = value; } - private Context context = null; + public String getValue() { + return value; + } + } - private StringBuilder sb = new StringBuilder(); + private Context context = null; - public void setContext(String value) { - context = new Context(value); - } + private StringBuilder sb = new StringBuilder(); - public void explicitSetContext(String value) { - this.context = new Context(value); - } + // MaD=p;InnerHolder;false;setContext;(String);;Argument[0];Argument[this];taint;df-generated + public void setContext(String value) { + context = new Context(value); + } - public void append(String value) { - sb.append(value); - } + // MaD=p;InnerHolder;false;explicitSetContext;(String);;Argument[0];Argument[this];taint;df-generated + public void explicitSetContext(String value) { + this.context = new Context(value); + } - public String getValue() { - return context.getValue(); - } + // MaD=p;InnerHolder;false;append;(String);;Argument[0];Argument[this];taint;df-generated + public void append(String value) { + sb.append(value); + } -} \ No newline at end of file + // MaD=p;InnerHolder;false;getValue;();;Argument[this];ReturnValue;taint;df-generated + public String getValue() { + return context.getValue(); + } +} diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/Joiner.java b/java/ql/test/utils/modelgenerator/dataflow/p/Joiner.java index d9869815bc52..daa939ebe515 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/Joiner.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/Joiner.java @@ -4,115 +4,122 @@ import java.util.Objects; public final class Joiner { - private final String prefix; - private final String delimiter; - private final String suffix; - private String[] elts; - private int size; - private int len; - private String emptyValue; - public Joiner(CharSequence delimiter) { - this(delimiter, "", ""); - } + private final String prefix; + private final String delimiter; + private final String suffix; + private String[] elts; + private int size; + private int len; + private String emptyValue; - public Joiner(CharSequence delimiter, - CharSequence prefix, - CharSequence suffix) { - Objects.requireNonNull(prefix, "The prefix must not be null"); - Objects.requireNonNull(delimiter, "The delimiter must not be null"); - Objects.requireNonNull(suffix, "The suffix must not be null"); - this.prefix = prefix.toString(); - this.delimiter = delimiter.toString(); - this.suffix = suffix.toString(); - checkAddLength(0, 0); - } + // MaD=p;Joiner;false;Joiner;(CharSequence);;Argument[0];Argument[this];taint;df-generated + public Joiner(CharSequence delimiter) { + this(delimiter, "", ""); + } - public Joiner setEmptyValue(CharSequence emptyValue) { - this.emptyValue = Objects.requireNonNull(emptyValue, - "The empty value must not be null").toString(); - return this; - } + // MaD=p;Joiner;false;Joiner;(CharSequence,CharSequence,CharSequence);;Argument[0];Argument[this];taint;df-generated + // MaD=p;Joiner;false;Joiner;(CharSequence,CharSequence,CharSequence);;Argument[1];Argument[this];taint;df-generated + // MaD=p;Joiner;false;Joiner;(CharSequence,CharSequence,CharSequence);;Argument[2];Argument[this];taint;df-generated + public Joiner(CharSequence delimiter, CharSequence prefix, CharSequence suffix) { + Objects.requireNonNull(prefix, "The prefix must not be null"); + Objects.requireNonNull(delimiter, "The delimiter must not be null"); + Objects.requireNonNull(suffix, "The suffix must not be null"); + this.prefix = prefix.toString(); + this.delimiter = delimiter.toString(); + this.suffix = suffix.toString(); + checkAddLength(0, 0); + } - private static int getChars(String s, char[] chars, int start) { - int len = s.length(); - s.getChars(0, len, chars, start); - return len; - } + // MaD=p;Joiner;false;setEmptyValue;(CharSequence);;Argument[0];Argument[this];taint;df-generated + // MaD=p;Joiner;false;setEmptyValue;(CharSequence);;Argument[this];ReturnValue;value;df-generated + public Joiner setEmptyValue(CharSequence emptyValue) { + this.emptyValue = + Objects.requireNonNull(emptyValue, "The empty value must not be null").toString(); + return this; + } - @Override - public String toString() { - final String[] elts = this.elts; - if (elts == null && emptyValue != null) { - return emptyValue; - } - final int size = this.size; - final int addLen = prefix.length() + suffix.length(); - if (addLen == 0) { - compactElts(); - return size == 0 ? "" : elts[0]; - } - final String delimiter = this.delimiter; - final char[] chars = new char[len + addLen]; - int k = getChars(prefix, chars, 0); - if (size > 0) { - k += getChars(elts[0], chars, k); - for (int i = 1; i < size; i++) { - k += getChars(delimiter, chars, k); - k += getChars(elts[i], chars, k); - } - } - k += getChars(suffix, chars, k); - return new String(chars); - } + private static int getChars(String s, char[] chars, int start) { + int len = s.length(); + s.getChars(0, len, chars, start); + return len; + } - public Joiner add(CharSequence newElement) { - final String elt = String.valueOf(newElement); - if (elts == null) { - elts = new String[8]; - } else { - if (size == elts.length) - elts = Arrays.copyOf(elts, 2 * size); - len = checkAddLength(len, delimiter.length()); - } - len = checkAddLength(len, elt.length()); - elts[size++] = elt; - return this; + @Override + public String toString() { + final String[] elts = this.elts; + if (elts == null && emptyValue != null) { + return emptyValue; + } + final int size = this.size; + final int addLen = prefix.length() + suffix.length(); + if (addLen == 0) { + compactElts(); + return size == 0 ? "" : elts[0]; } + final String delimiter = this.delimiter; + final char[] chars = new char[len + addLen]; + int k = getChars(prefix, chars, 0); + if (size > 0) { + k += getChars(elts[0], chars, k); + for (int i = 1; i < size; i++) { + k += getChars(delimiter, chars, k); + k += getChars(elts[i], chars, k); + } + } + k += getChars(suffix, chars, k); + return new String(chars); + } - private int checkAddLength(int oldLen, int inc) { - long newLen = (long)oldLen + (long)inc; - long tmpLen = newLen + (long)prefix.length() + (long)suffix.length(); - if (tmpLen != (int)tmpLen) { - throw new OutOfMemoryError("Requested array size exceeds VM limit"); - } - return (int)newLen; + // MaD=p;Joiner;false;add;(CharSequence);;Argument[this];ReturnValue;value;df-generated + public Joiner add(CharSequence newElement) { + final String elt = String.valueOf(newElement); + if (elts == null) { + elts = new String[8]; + } else { + if (size == elts.length) elts = Arrays.copyOf(elts, 2 * size); + len = checkAddLength(len, delimiter.length()); } + len = checkAddLength(len, elt.length()); + elts[size++] = elt; + return this; + } - public Joiner merge(Joiner other) { - Objects.requireNonNull(other); - if (other.elts == null) { - return this; - } - other.compactElts(); - return add(other.elts[0]); + private int checkAddLength(int oldLen, int inc) { + long newLen = (long) oldLen + (long) inc; + long tmpLen = newLen + (long) prefix.length() + (long) suffix.length(); + if (tmpLen != (int) tmpLen) { + throw new OutOfMemoryError("Requested array size exceeds VM limit"); } + return (int) newLen; + } - private void compactElts() { - if (size > 1) { - final char[] chars = new char[len]; - int i = 1, k = getChars(elts[0], chars, 0); - do { - k += getChars(delimiter, chars, k); - k += getChars(elts[i], chars, k); - elts[i] = null; - } while (++i < size); - size = 1; - elts[0] = new String(chars); - } + // MaD=p;Joiner;false;merge;(Joiner);;Argument[this];ReturnValue;value;df-generated + public Joiner merge(Joiner other) { + Objects.requireNonNull(other); + if (other.elts == null) { + return this; } + other.compactElts(); + return add(other.elts[0]); + } - public int length() { - return (size == 0 && emptyValue != null) ? emptyValue.length() : - len + prefix.length() + suffix.length(); + private void compactElts() { + if (size > 1) { + final char[] chars = new char[len]; + int i = 1, k = getChars(elts[0], chars, 0); + do { + k += getChars(delimiter, chars, k); + k += getChars(elts[i], chars, k); + elts[i] = null; + } while (++i < size); + size = 1; + elts[0] = new String(chars); } -} \ No newline at end of file + } + + public int length() { + return (size == 0 && emptyValue != null) + ? emptyValue.length() + : len + prefix.length() + suffix.length(); + } +} diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpl2.java b/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpl2.java index 9de2d59b2e4f..7c2e2ed92118 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpl2.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpl2.java @@ -2,22 +2,23 @@ class MultipleImpl2 { - // Multiple implementations of the same interface. - // This is used to test that we only generate a summary model and - // not neutral summary model for `IInterface.m`. - public interface IInterface { - Object m(Object value); - } + // Multiple implementations of the same interface. + // This is used to test that we only generate a summary model and + // not neutral summary model for `IInterface.m`. + public interface IInterface { + // MaD=p;MultipleImpl2$IInterface;true;m;(Object);;Argument[0];ReturnValue;taint;df-generated + Object m(Object value); + } - public class Impl1 implements IInterface { - public Object m(Object value) { - return null; - } + public class Impl1 implements IInterface { + public Object m(Object value) { + return null; } + } - public class Impl2 implements IInterface { - public Object m(Object value) { - return value; - } + public class Impl2 implements IInterface { + public Object m(Object value) { + return value; } + } } diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpls.java b/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpls.java index a6697393dbc1..8cdde304bd55 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpls.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpls.java @@ -4,35 +4,38 @@ public class MultipleImpls { - public static interface Strategy { - String doSomething(String value); + public static interface Strategy { + // MaD=p;MultipleImpls$Strategy;true;doSomething;(String);;Argument[0];Argument[this];taint;df-generated + // MaD=p;MultipleImpls$Strategy;true;doSomething;(String);;Argument[0];ReturnValue;taint;df-generated + String doSomething(String value); + } + + public static class Strat1 implements Strategy { + public String doSomething(String value) { + return value; } + } - public static class Strat1 implements Strategy { - public String doSomething(String value) { - return value; - } + // implements in different library should not count as impl + public static class Strat3 implements Callable { + + @Override + public String call() throws Exception { + return null; + } + } + + public static class Strat2 implements Strategy { + private String foo; + + public String doSomething(String value) { + this.foo = value; + return "none"; } - // implements in different library should not count as impl - public static class Strat3 implements Callable { - - @Override - public String call() throws Exception { - return null; - } - - } - public static class Strat2 implements Strategy { - private String foo; - - public String doSomething(String value) { - this.foo = value; - return "none"; - } - - public String getValue() { - return this.foo; - } + // MaD=p;MultipleImpls$Strat2;true;getValue;();;Argument[this];ReturnValue;taint;df-generated + public String getValue() { + return this.foo; } + } } diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/ParamFlow.java b/java/ql/test/utils/modelgenerator/dataflow/p/ParamFlow.java index 8b58c3773167..7d9dac157c27 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/ParamFlow.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/ParamFlow.java @@ -1,64 +1,71 @@ package p; -import java.util.Iterator; -import java.util.List; import java.io.IOException; import java.io.OutputStream; - +import java.util.Iterator; +import java.util.List; public class ParamFlow { - public String returnsInput(String input) { - return input; - } + // MaD=p;ParamFlow;true;returnsInput;(String);;Argument[0];ReturnValue;taint;df-generated + public String returnsInput(String input) { + return input; + } - public int ignorePrimitiveReturnValue(String input) { - return input.length(); - } + public int ignorePrimitiveReturnValue(String input) { + return input.length(); + } - public String returnMultipleParameters(String one, String two) { - if (System.currentTimeMillis() > 100) { - return two; - } - return one; + // MaD=p;ParamFlow;true;returnMultipleParameters;(String,String);;Argument[0];ReturnValue;taint;df-generated + // MaD=p;ParamFlow;true;returnMultipleParameters;(String,String);;Argument[1];ReturnValue;taint;df-generated + public String returnMultipleParameters(String one, String two) { + if (System.currentTimeMillis() > 100) { + return two; } + return one; + } - public String returnArrayElement(String[] input) { - return input[0]; - } + // MaD=p;ParamFlow;true;returnArrayElement;(String[]);;Argument[0].ArrayElement;ReturnValue;taint;df-generated + public String returnArrayElement(String[] input) { + return input[0]; + } - public String returnVarArgElement(String... input) { - return input[0]; - } + // MaD=p;ParamFlow;true;returnVarArgElement;(String[]);;Argument[0].ArrayElement;ReturnValue;taint;df-generated + public String returnVarArgElement(String... input) { + return input[0]; + } - public String returnCollectionElement(List input) { - return input.get(0); - } + // MaD=p;ParamFlow;true;returnCollectionElement;(List);;Argument[0].Element;ReturnValue;taint;df-generated + public String returnCollectionElement(List input) { + return input.get(0); + } - public String returnIteratorElement(Iterator input) { - return input.next(); - } + // MaD=p;ParamFlow;true;returnIteratorElement;(Iterator);;Argument[0].Element;ReturnValue;taint;df-generated + public String returnIteratorElement(Iterator input) { + return input.next(); + } - public String returnIterableElement(Iterable input) { - return input.iterator().next(); - } + // MaD=p;ParamFlow;true;returnIterableElement;(Iterable);;Argument[0].Element;ReturnValue;taint;df-generated + public String returnIterableElement(Iterable input) { + return input.iterator().next(); + } - public Class mapType(Class input) { - return input; - } + public Class mapType(Class input) { + return input; + } - public void writeChunked(byte[] data, OutputStream output) - throws IOException { - output.write(data, 0, data.length); - } - - public void writeChunked(char[] data, OutputStream output) - throws IOException { - output.write(String.valueOf(data).getBytes(), 0, data.length); - } + // MaD=p;ParamFlow;true;writeChunked;(byte[],OutputStream);;Argument[0];Argument[1];taint;df-generated + public void writeChunked(byte[] data, OutputStream output) throws IOException { + output.write(data, 0, data.length); + } - public void addTo(String data, List target) { - target.add(data); - } + // MaD=p;ParamFlow;true;writeChunked;(char[],OutputStream);;Argument[0];Argument[1];taint;df-generated + public void writeChunked(char[] data, OutputStream output) throws IOException { + output.write(String.valueOf(data).getBytes(), 0, data.length); + } -} \ No newline at end of file + // MaD=p;ParamFlow;true;addTo;(String,List);;Argument[0];Argument[1].Element;taint;df-generated + public void addTo(String data, List target) { + target.add(data); + } +} diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/Pojo.java b/java/ql/test/utils/modelgenerator/dataflow/p/Pojo.java index 40dfa56ae868..15fbda5bc79d 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/Pojo.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/Pojo.java @@ -8,91 +8,97 @@ public final class Pojo { - private class Holder { - private String value; + private class Holder { + private String value; - Holder(String value) { - this.value = value; - } + Holder(String value) { + this.value = value; + } - int length() { - return value.length(); - } + int length() { + return value.length(); } + } - private String value; + private String value; - private int intValue = 2; + private int intValue = 2; - private byte[] byteArray = new byte[] {1, 2, 3} ; - private float[] floatArray = new float[] {1, 2, 3} ; - private char[] charArray = new char[] {'a', 'b', 'c'} ; - private List charList = Arrays.asList('a', 'b', 'c'); - private Byte[] byteObjectArray = new Byte[] { 1, 2, 3 }; + private byte[] byteArray = new byte[] {1, 2, 3}; + private float[] floatArray = new float[] {1, 2, 3}; + private char[] charArray = new char[] {'a', 'b', 'c'}; + private List charList = Arrays.asList('a', 'b', 'c'); + private Byte[] byteObjectArray = new Byte[] {1, 2, 3}; - public String getValue() { - return value; - } + // MaD=p;Pojo;false;getValue;();;Argument[this];ReturnValue;taint;df-generated + public String getValue() { + return value; + } - public void setValue(String value) { - this.value = value; - } + // MaD=p;Pojo;false;setValue;(String);;Argument[0];Argument[this];taint;df-generated + public void setValue(String value) { + this.value = value; + } - public int doNotSetValue(String value) { - Holder h = new Holder(value); - return h.length(); - } + public int doNotSetValue(String value) { + Holder h = new Holder(value); + return h.length(); + } - public int getIntValue() { - return intValue; - } + public int getIntValue() { + return intValue; + } - public Integer getBoxedValue() { - return Integer.valueOf(intValue); - } + public Integer getBoxedValue() { + return Integer.valueOf(intValue); + } - public int[] getPrimitiveArray() { - return new int[] { intValue }; - } + public int[] getPrimitiveArray() { + return new int[] {intValue}; + } - public char[] getCharArray() { - return charArray; - } + // MaD=p;Pojo;false;getCharArray;();;Argument[this];ReturnValue;taint;df-generated + public char[] getCharArray() { + return charArray; + } - public byte[] getByteArray() { - return byteArray; - } - - public float[] getFloatArray() { - return floatArray; - } + // MaD=p;Pojo;false;getByteArray;();;Argument[this];ReturnValue;taint;df-generated + public byte[] getByteArray() { + return byteArray; + } - public Integer[] getBoxedArray() { - return new Integer[] { Integer.valueOf(intValue) }; - } - - public Collection getBoxedCollection() { - return List.of(Integer.valueOf(intValue)); - } + public float[] getFloatArray() { + return floatArray; + } - public List getBoxedChars() { - return charList; - } + public Integer[] getBoxedArray() { + return new Integer[] {Integer.valueOf(intValue)}; + } - public Byte[] getBoxedBytes() { - return byteObjectArray; - } - - public BigInteger getBigInt() { - return BigInteger.valueOf(intValue); - } + public Collection getBoxedCollection() { + return List.of(Integer.valueOf(intValue)); + } - public BigDecimal getBigDecimal() { - return new BigDecimal(value); - } + // MaD=p;Pojo;false;getBoxedChars;();;Argument[this];ReturnValue;taint;df-generated + public List getBoxedChars() { + return charList; + } - public void fillIn(List target) { - target.add(value); - } + // MaD=p;Pojo;false;getBoxedBytes;();;Argument[this];ReturnValue;taint;df-generated + public Byte[] getBoxedBytes() { + return byteObjectArray; + } + + public BigInteger getBigInt() { + return BigInteger.valueOf(intValue); + } + + public BigDecimal getBigDecimal() { + return new BigDecimal(value); + } -} \ No newline at end of file + // MaD=p;Pojo;false;fillIn;(List);;Argument[this];Argument[0].Element;taint;df-generated + public void fillIn(List target) { + target.add(value); + } +} diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/PrivateFlowViaPublicInterface.java b/java/ql/test/utils/modelgenerator/dataflow/p/PrivateFlowViaPublicInterface.java index 59247bfe471b..13a2897f08a9 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/PrivateFlowViaPublicInterface.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/PrivateFlowViaPublicInterface.java @@ -7,55 +7,55 @@ public class PrivateFlowViaPublicInterface { - static class RandomPojo { - public File someFile = new File("someFile"); - } - public static interface SPI { - OutputStream openStream() throws IOException; - - default OutputStream openStreamNone() throws IOException { - return null; - }; - } + static class RandomPojo { + public File someFile = new File("someFile"); + } - private static final class PrivateImplWithSink implements SPI { + public static interface SPI { + // MaD=p;PrivateFlowViaPublicInterface$SPI;true;openStream;();;Argument[this];ReturnValue;taint;df-generated + OutputStream openStream() throws IOException; - private File file; + default OutputStream openStreamNone() throws IOException { + return null; + } + ; + } - public PrivateImplWithSink(File file) { - this.file = file; - } + private static final class PrivateImplWithSink implements SPI { - @Override - public OutputStream openStream() throws IOException { - return new FileOutputStream(file); - } + private File file; + public PrivateImplWithSink(File file) { + this.file = file; } - - private static final class PrivateImplWithRandomField implements SPI { - - public PrivateImplWithRandomField(File file) { - } - - @Override - public OutputStream openStream() throws IOException { - return null; - } - - @Override - public OutputStream openStreamNone() throws IOException { - return new FileOutputStream(new RandomPojo().someFile); - } + @Override + public OutputStream openStream() throws IOException { + return new FileOutputStream(file); } + } - public static SPI createAnSPI(File file) { - return new PrivateImplWithSink(file); + private static final class PrivateImplWithRandomField implements SPI { + + public PrivateImplWithRandomField(File file) {} + + @Override + public OutputStream openStream() throws IOException { + return null; } - - public static SPI createAnSPIWithoutTrackingFile(File file) { - return new PrivateImplWithRandomField(file); + + @Override + public OutputStream openStreamNone() throws IOException { + return new FileOutputStream(new RandomPojo().someFile); } + } + + // MaD=p;PrivateFlowViaPublicInterface;true;createAnSPI;(File);;Argument[0];ReturnValue;taint;df-generated + public static SPI createAnSPI(File file) { + return new PrivateImplWithSink(file); + } -} \ No newline at end of file + public static SPI createAnSPIWithoutTrackingFile(File file) { + return new PrivateImplWithRandomField(file); + } +} From a33393d452d8ec5758deb979ae75fbee2eefe74e Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 6 May 2024 11:02:04 +0200 Subject: [PATCH 216/238] Java: Delete old summary models expected output. --- .../dataflow/CaptureSummaryModels.expected | 47 ------------------- .../dataflow/CaptureSummaryModels.qlref | 1 - 2 files changed, 48 deletions(-) delete mode 100644 java/ql/test/utils/modelgenerator/dataflow/CaptureSummaryModels.expected delete mode 100644 java/ql/test/utils/modelgenerator/dataflow/CaptureSummaryModels.qlref diff --git a/java/ql/test/utils/modelgenerator/dataflow/CaptureSummaryModels.expected b/java/ql/test/utils/modelgenerator/dataflow/CaptureSummaryModels.expected deleted file mode 100644 index 50536e850d9a..000000000000 --- a/java/ql/test/utils/modelgenerator/dataflow/CaptureSummaryModels.expected +++ /dev/null @@ -1,47 +0,0 @@ -| p;Factory;false;create;(String);;Argument[0];ReturnValue;taint;df-generated | -| p;Factory;false;create;(String,int);;Argument[0];ReturnValue;taint;df-generated | -| p;Factory;false;getValue;();;Argument[this];ReturnValue;taint;df-generated | -| p;FinalClass;false;returnsInput;(String);;Argument[0];ReturnValue;taint;df-generated | -| p;FluentAPI;false;returnsThis;(String);;Argument[this];ReturnValue;value;df-generated | -| p;ImmutablePojo;false;ImmutablePojo;(String,int);;Argument[0];Argument[this];taint;df-generated | -| p;ImmutablePojo;false;getValue;();;Argument[this];ReturnValue;taint;df-generated | -| p;ImmutablePojo;false;or;(String);;Argument[0];ReturnValue;taint;df-generated | -| p;ImmutablePojo;false;or;(String);;Argument[this];ReturnValue;taint;df-generated | -| p;InnerClasses$CaptureMe;true;yesCm;(String);;Argument[0];ReturnValue;taint;df-generated | -| p;InnerClasses;true;yes;(String);;Argument[0];ReturnValue;taint;df-generated | -| p;InnerHolder;false;append;(String);;Argument[0];Argument[this];taint;df-generated | -| p;InnerHolder;false;explicitSetContext;(String);;Argument[0];Argument[this];taint;df-generated | -| p;InnerHolder;false;getValue;();;Argument[this];ReturnValue;taint;df-generated | -| p;InnerHolder;false;setContext;(String);;Argument[0];Argument[this];taint;df-generated | -| p;Joiner;false;Joiner;(CharSequence);;Argument[0];Argument[this];taint;df-generated | -| p;Joiner;false;Joiner;(CharSequence,CharSequence,CharSequence);;Argument[0];Argument[this];taint;df-generated | -| p;Joiner;false;Joiner;(CharSequence,CharSequence,CharSequence);;Argument[1];Argument[this];taint;df-generated | -| p;Joiner;false;Joiner;(CharSequence,CharSequence,CharSequence);;Argument[2];Argument[this];taint;df-generated | -| p;Joiner;false;add;(CharSequence);;Argument[this];ReturnValue;value;df-generated | -| p;Joiner;false;merge;(Joiner);;Argument[this];ReturnValue;value;df-generated | -| p;Joiner;false;setEmptyValue;(CharSequence);;Argument[0];Argument[this];taint;df-generated | -| p;Joiner;false;setEmptyValue;(CharSequence);;Argument[this];ReturnValue;value;df-generated | -| p;MultipleImpl2$IInterface;true;m;(Object);;Argument[0];ReturnValue;taint;df-generated | -| p;MultipleImpls$Strat2;true;getValue;();;Argument[this];ReturnValue;taint;df-generated | -| p;MultipleImpls$Strategy;true;doSomething;(String);;Argument[0];Argument[this];taint;df-generated | -| p;MultipleImpls$Strategy;true;doSomething;(String);;Argument[0];ReturnValue;taint;df-generated | -| p;ParamFlow;true;addTo;(String,List);;Argument[0];Argument[1].Element;taint;df-generated | -| p;ParamFlow;true;returnArrayElement;(String[]);;Argument[0].ArrayElement;ReturnValue;taint;df-generated | -| p;ParamFlow;true;returnCollectionElement;(List);;Argument[0].Element;ReturnValue;taint;df-generated | -| p;ParamFlow;true;returnIterableElement;(Iterable);;Argument[0].Element;ReturnValue;taint;df-generated | -| p;ParamFlow;true;returnIteratorElement;(Iterator);;Argument[0].Element;ReturnValue;taint;df-generated | -| p;ParamFlow;true;returnMultipleParameters;(String,String);;Argument[0];ReturnValue;taint;df-generated | -| p;ParamFlow;true;returnMultipleParameters;(String,String);;Argument[1];ReturnValue;taint;df-generated | -| p;ParamFlow;true;returnVarArgElement;(String[]);;Argument[0].ArrayElement;ReturnValue;taint;df-generated | -| p;ParamFlow;true;returnsInput;(String);;Argument[0];ReturnValue;taint;df-generated | -| p;ParamFlow;true;writeChunked;(byte[],OutputStream);;Argument[0];Argument[1];taint;df-generated | -| p;ParamFlow;true;writeChunked;(char[],OutputStream);;Argument[0];Argument[1];taint;df-generated | -| p;Pojo;false;fillIn;(List);;Argument[this];Argument[0].Element;taint;df-generated | -| p;Pojo;false;getBoxedBytes;();;Argument[this];ReturnValue;taint;df-generated | -| p;Pojo;false;getBoxedChars;();;Argument[this];ReturnValue;taint;df-generated | -| p;Pojo;false;getByteArray;();;Argument[this];ReturnValue;taint;df-generated | -| p;Pojo;false;getCharArray;();;Argument[this];ReturnValue;taint;df-generated | -| p;Pojo;false;getValue;();;Argument[this];ReturnValue;taint;df-generated | -| p;Pojo;false;setValue;(String);;Argument[0];Argument[this];taint;df-generated | -| p;PrivateFlowViaPublicInterface$SPI;true;openStream;();;Argument[this];ReturnValue;taint;df-generated | -| p;PrivateFlowViaPublicInterface;true;createAnSPI;(File);;Argument[0];ReturnValue;taint;df-generated | diff --git a/java/ql/test/utils/modelgenerator/dataflow/CaptureSummaryModels.qlref b/java/ql/test/utils/modelgenerator/dataflow/CaptureSummaryModels.qlref deleted file mode 100644 index d751f3823f39..000000000000 --- a/java/ql/test/utils/modelgenerator/dataflow/CaptureSummaryModels.qlref +++ /dev/null @@ -1 +0,0 @@ -utils/modelgenerator/CaptureSummaryModels.ql \ No newline at end of file From 5b184c179adfcc4a5f3accf86cb617ebdf9a7275 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Mon, 6 May 2024 12:47:51 +0200 Subject: [PATCH 217/238] Bazel/Go: add some comments --- go/extractor/BUILD.bazel | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/go/extractor/BUILD.bazel b/go/extractor/BUILD.bazel index 6047eea6860c..7e576927f662 100644 --- a/go/extractor/BUILD.bazel +++ b/go/extractor/BUILD.bazel @@ -25,7 +25,9 @@ go_library( ], ) -# the other targets are not generated +# the other targets are not generated by gazelle + +# this is separate from `tokenizer-jar` below because we don't want these compiled class files in the pack java_library( name = "tokenizer-deps", srcs = [ @@ -36,6 +38,7 @@ java_library( ], ) +# we only need these compiled class files in the pack java_library( name = "tokenizer-jar", srcs = [ @@ -51,7 +54,7 @@ pkg_files( srcs = [":tokenizer-jar"], prefix = "tools", renames = { - ":tokenizer-jar": "tokenizer.jar", + ":tokenizer-jar": "tokenizer.jar", # name is `libtokenizer.jar` by default }, visibility = ["//go:__pkg__"], ) From 51e7f3be1a0b3cd3af06ef939253f3e28676f7d0 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 6 May 2024 13:03:38 +0200 Subject: [PATCH 218/238] Java: Rename MaD to summary. --- java/ql/test/TestUtilities/InlineMadTest.qll | 9 +- .../modelgenerator/dataflow/p/Factory.java | 6 +- .../modelgenerator/dataflow/p/FinalClass.java | 2 +- .../modelgenerator/dataflow/p/FluentAPI.java | 2 +- .../dataflow/p/ImmutablePojo.java | 8 +- .../dataflow/p/InnerClasses.java | 4 +- .../dataflow/p/InnerHolder.java | 8 +- .../modelgenerator/dataflow/p/Joiner.java | 16 +- .../dataflow/p/MultipleImpl2.java | 2 +- .../dataflow/p/MultipleImpls.java | 6 +- .../modelgenerator/dataflow/p/ParamFlow.java | 22 +- .../utils/modelgenerator/dataflow/p/Pojo.java | 14 +- .../p/PrivateFlowViaPublicInterface.java | 4 +- .../typebasedflow/p/MyFunction.java | 10 +- .../typebasedflow/p/Stream.java | 476 +++++++++--------- .../typebasedflow/p/TypeBasedCollection.java | 30 +- .../typebasedflow/p/TypeBasedComplex.java | 142 +++--- .../typebasedflow/p/TypeBasedSimple.java | 72 ++- 18 files changed, 412 insertions(+), 421 deletions(-) diff --git a/java/ql/test/TestUtilities/InlineMadTest.qll b/java/ql/test/TestUtilities/InlineMadTest.qll index 64badab0dcab..3e9aee7eb9e2 100644 --- a/java/ql/test/TestUtilities/InlineMadTest.qll +++ b/java/ql/test/TestUtilities/InlineMadTest.qll @@ -11,21 +11,22 @@ signature module InlineMadTestConfigSig { } module InlineMadTest { - private string expects() { - Input::getComment().regexpCapture(" *(SPURIOUS-)?MaD=(.*)", 2) = result + bindingset[kind] + private string expects(string kind) { + Input::getComment().regexpCapture(" *(SPURIOUS-)?" + kind + "=(.*)", 2) = result } query predicate unexpectedSummary(string msg) { exists(string flow | flow = Input::getCapturedSummary() and - not flow = expects() and + not flow = expects("summary") and msg = "Unexpected summary found: " + flow ) } query predicate expectedSummary(string msg) { exists(string e | - e = expects() and + e = expects("summary") and not e = Input::getCapturedSummary() and msg = "Expected summary missing: " + e ) diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/Factory.java b/java/ql/test/utils/modelgenerator/dataflow/p/Factory.java index 84b55a812c94..57d26429a936 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/Factory.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/Factory.java @@ -6,12 +6,12 @@ public final class Factory { private int intValue; - // MaD=p;Factory;false;create;(String,int);;Argument[0];ReturnValue;taint;df-generated + // summary=p;Factory;false;create;(String,int);;Argument[0];ReturnValue;taint;df-generated public static Factory create(String value, int foo) { return new Factory(value, foo); } - // MaD=p;Factory;false;create;(String);;Argument[0];ReturnValue;taint;df-generated + // summary=p;Factory;false;create;(String);;Argument[0];ReturnValue;taint;df-generated public static Factory create(String value) { return new Factory(value, 0); } @@ -21,7 +21,7 @@ private Factory(String value, int intValue) { this.intValue = intValue; } - // MaD=p;Factory;false;getValue;();;Argument[this];ReturnValue;taint;df-generated + // summary=p;Factory;false;getValue;();;Argument[this];ReturnValue;taint;df-generated public String getValue() { return value; } diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/FinalClass.java b/java/ql/test/utils/modelgenerator/dataflow/p/FinalClass.java index 5073f4352339..82a39533ce14 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/FinalClass.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/FinalClass.java @@ -4,7 +4,7 @@ public final class FinalClass { private static final String C = "constant"; - // MaD=p;FinalClass;false;returnsInput;(String);;Argument[0];ReturnValue;taint;df-generated + // summary=p;FinalClass;false;returnsInput;(String);;Argument[0];ReturnValue;taint;df-generated public String returnsInput(String input) { return input; } diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/FluentAPI.java b/java/ql/test/utils/modelgenerator/dataflow/p/FluentAPI.java index 2bb2bb97604e..38fbb286bb01 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/FluentAPI.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/FluentAPI.java @@ -2,7 +2,7 @@ public final class FluentAPI { - // MaD=p;FluentAPI;false;returnsThis;(String);;Argument[this];ReturnValue;value;df-generated + // summary=p;FluentAPI;false;returnsThis;(String);;Argument[this];ReturnValue;value;df-generated public FluentAPI returnsThis(String input) { return this; } diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/ImmutablePojo.java b/java/ql/test/utils/modelgenerator/dataflow/p/ImmutablePojo.java index 38a9b472f625..1b39856b445b 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/ImmutablePojo.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/ImmutablePojo.java @@ -6,13 +6,13 @@ public final class ImmutablePojo { private final long x; - // MaD=p;ImmutablePojo;false;ImmutablePojo;(String,int);;Argument[0];Argument[this];taint;df-generated + // summary=p;ImmutablePojo;false;ImmutablePojo;(String,int);;Argument[0];Argument[this];taint;df-generated public ImmutablePojo(String value, int x) { this.value = value; this.x = x; } - // MaD=p;ImmutablePojo;false;getValue;();;Argument[this];ReturnValue;taint;df-generated + // summary=p;ImmutablePojo;false;getValue;();;Argument[this];ReturnValue;taint;df-generated public String getValue() { return value; } @@ -21,8 +21,8 @@ public long getX() { return x; } - // MaD=p;ImmutablePojo;false;or;(String);;Argument[0];ReturnValue;taint;df-generated - // MaD=p;ImmutablePojo;false;or;(String);;Argument[this];ReturnValue;taint;df-generated + // summary=p;ImmutablePojo;false;or;(String);;Argument[0];ReturnValue;taint;df-generated + // summary=p;ImmutablePojo;false;or;(String);;Argument[this];ReturnValue;taint;df-generated public String or(String defaultValue) { return value != null ? value : defaultValue; } diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/InnerClasses.java b/java/ql/test/utils/modelgenerator/dataflow/p/InnerClasses.java index 54f014fec93b..5b6a8427a3f5 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/InnerClasses.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/InnerClasses.java @@ -9,13 +9,13 @@ public String no(String input) { } public class CaptureMe { - // MaD=p;InnerClasses$CaptureMe;true;yesCm;(String);;Argument[0];ReturnValue;taint;df-generated + // summary=p;InnerClasses$CaptureMe;true;yesCm;(String);;Argument[0];ReturnValue;taint;df-generated public String yesCm(String input) { return input; } } - // MaD=p;InnerClasses;true;yes;(String);;Argument[0];ReturnValue;taint;df-generated + // summary=p;InnerClasses;true;yes;(String);;Argument[0];ReturnValue;taint;df-generated public String yes(String input) { return input; } diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/InnerHolder.java b/java/ql/test/utils/modelgenerator/dataflow/p/InnerHolder.java index ef8729421918..e09680dad525 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/InnerHolder.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/InnerHolder.java @@ -18,22 +18,22 @@ public String getValue() { private StringBuilder sb = new StringBuilder(); - // MaD=p;InnerHolder;false;setContext;(String);;Argument[0];Argument[this];taint;df-generated + // summary=p;InnerHolder;false;setContext;(String);;Argument[0];Argument[this];taint;df-generated public void setContext(String value) { context = new Context(value); } - // MaD=p;InnerHolder;false;explicitSetContext;(String);;Argument[0];Argument[this];taint;df-generated + // summary=p;InnerHolder;false;explicitSetContext;(String);;Argument[0];Argument[this];taint;df-generated public void explicitSetContext(String value) { this.context = new Context(value); } - // MaD=p;InnerHolder;false;append;(String);;Argument[0];Argument[this];taint;df-generated + // summary=p;InnerHolder;false;append;(String);;Argument[0];Argument[this];taint;df-generated public void append(String value) { sb.append(value); } - // MaD=p;InnerHolder;false;getValue;();;Argument[this];ReturnValue;taint;df-generated + // summary=p;InnerHolder;false;getValue;();;Argument[this];ReturnValue;taint;df-generated public String getValue() { return context.getValue(); } diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/Joiner.java b/java/ql/test/utils/modelgenerator/dataflow/p/Joiner.java index daa939ebe515..60edb0fb71e1 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/Joiner.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/Joiner.java @@ -12,14 +12,14 @@ public final class Joiner { private int len; private String emptyValue; - // MaD=p;Joiner;false;Joiner;(CharSequence);;Argument[0];Argument[this];taint;df-generated + // summary=p;Joiner;false;Joiner;(CharSequence);;Argument[0];Argument[this];taint;df-generated public Joiner(CharSequence delimiter) { this(delimiter, "", ""); } - // MaD=p;Joiner;false;Joiner;(CharSequence,CharSequence,CharSequence);;Argument[0];Argument[this];taint;df-generated - // MaD=p;Joiner;false;Joiner;(CharSequence,CharSequence,CharSequence);;Argument[1];Argument[this];taint;df-generated - // MaD=p;Joiner;false;Joiner;(CharSequence,CharSequence,CharSequence);;Argument[2];Argument[this];taint;df-generated + // summary=p;Joiner;false;Joiner;(CharSequence,CharSequence,CharSequence);;Argument[0];Argument[this];taint;df-generated + // summary=p;Joiner;false;Joiner;(CharSequence,CharSequence,CharSequence);;Argument[1];Argument[this];taint;df-generated + // summary=p;Joiner;false;Joiner;(CharSequence,CharSequence,CharSequence);;Argument[2];Argument[this];taint;df-generated public Joiner(CharSequence delimiter, CharSequence prefix, CharSequence suffix) { Objects.requireNonNull(prefix, "The prefix must not be null"); Objects.requireNonNull(delimiter, "The delimiter must not be null"); @@ -30,8 +30,8 @@ public Joiner(CharSequence delimiter, CharSequence prefix, CharSequence suffix) checkAddLength(0, 0); } - // MaD=p;Joiner;false;setEmptyValue;(CharSequence);;Argument[0];Argument[this];taint;df-generated - // MaD=p;Joiner;false;setEmptyValue;(CharSequence);;Argument[this];ReturnValue;value;df-generated + // summary=p;Joiner;false;setEmptyValue;(CharSequence);;Argument[0];Argument[this];taint;df-generated + // summary=p;Joiner;false;setEmptyValue;(CharSequence);;Argument[this];ReturnValue;value;df-generated public Joiner setEmptyValue(CharSequence emptyValue) { this.emptyValue = Objects.requireNonNull(emptyValue, "The empty value must not be null").toString(); @@ -70,7 +70,7 @@ public String toString() { return new String(chars); } - // MaD=p;Joiner;false;add;(CharSequence);;Argument[this];ReturnValue;value;df-generated + // summary=p;Joiner;false;add;(CharSequence);;Argument[this];ReturnValue;value;df-generated public Joiner add(CharSequence newElement) { final String elt = String.valueOf(newElement); if (elts == null) { @@ -93,7 +93,7 @@ private int checkAddLength(int oldLen, int inc) { return (int) newLen; } - // MaD=p;Joiner;false;merge;(Joiner);;Argument[this];ReturnValue;value;df-generated + // summary=p;Joiner;false;merge;(Joiner);;Argument[this];ReturnValue;value;df-generated public Joiner merge(Joiner other) { Objects.requireNonNull(other); if (other.elts == null) { diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpl2.java b/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpl2.java index 7c2e2ed92118..dc67d0dfe6cc 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpl2.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpl2.java @@ -6,7 +6,7 @@ class MultipleImpl2 { // This is used to test that we only generate a summary model and // not neutral summary model for `IInterface.m`. public interface IInterface { - // MaD=p;MultipleImpl2$IInterface;true;m;(Object);;Argument[0];ReturnValue;taint;df-generated + // summary=p;MultipleImpl2$IInterface;true;m;(Object);;Argument[0];ReturnValue;taint;df-generated Object m(Object value); } diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpls.java b/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpls.java index 8cdde304bd55..8fccdf76ab71 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpls.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpls.java @@ -5,8 +5,8 @@ public class MultipleImpls { public static interface Strategy { - // MaD=p;MultipleImpls$Strategy;true;doSomething;(String);;Argument[0];Argument[this];taint;df-generated - // MaD=p;MultipleImpls$Strategy;true;doSomething;(String);;Argument[0];ReturnValue;taint;df-generated + // summary=p;MultipleImpls$Strategy;true;doSomething;(String);;Argument[0];Argument[this];taint;df-generated + // summary=p;MultipleImpls$Strategy;true;doSomething;(String);;Argument[0];ReturnValue;taint;df-generated String doSomething(String value); } @@ -33,7 +33,7 @@ public String doSomething(String value) { return "none"; } - // MaD=p;MultipleImpls$Strat2;true;getValue;();;Argument[this];ReturnValue;taint;df-generated + // summary=p;MultipleImpls$Strat2;true;getValue;();;Argument[this];ReturnValue;taint;df-generated public String getValue() { return this.foo; } diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/ParamFlow.java b/java/ql/test/utils/modelgenerator/dataflow/p/ParamFlow.java index 7d9dac157c27..5c47e292a6b6 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/ParamFlow.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/ParamFlow.java @@ -7,7 +7,7 @@ public class ParamFlow { - // MaD=p;ParamFlow;true;returnsInput;(String);;Argument[0];ReturnValue;taint;df-generated + // summary=p;ParamFlow;true;returnsInput;(String);;Argument[0];ReturnValue;taint;df-generated public String returnsInput(String input) { return input; } @@ -16,8 +16,8 @@ public int ignorePrimitiveReturnValue(String input) { return input.length(); } - // MaD=p;ParamFlow;true;returnMultipleParameters;(String,String);;Argument[0];ReturnValue;taint;df-generated - // MaD=p;ParamFlow;true;returnMultipleParameters;(String,String);;Argument[1];ReturnValue;taint;df-generated + // summary=p;ParamFlow;true;returnMultipleParameters;(String,String);;Argument[0];ReturnValue;taint;df-generated + // summary=p;ParamFlow;true;returnMultipleParameters;(String,String);;Argument[1];ReturnValue;taint;df-generated public String returnMultipleParameters(String one, String two) { if (System.currentTimeMillis() > 100) { return two; @@ -25,27 +25,27 @@ public String returnMultipleParameters(String one, String two) { return one; } - // MaD=p;ParamFlow;true;returnArrayElement;(String[]);;Argument[0].ArrayElement;ReturnValue;taint;df-generated + // summary=p;ParamFlow;true;returnArrayElement;(String[]);;Argument[0].ArrayElement;ReturnValue;taint;df-generated public String returnArrayElement(String[] input) { return input[0]; } - // MaD=p;ParamFlow;true;returnVarArgElement;(String[]);;Argument[0].ArrayElement;ReturnValue;taint;df-generated + // summary=p;ParamFlow;true;returnVarArgElement;(String[]);;Argument[0].ArrayElement;ReturnValue;taint;df-generated public String returnVarArgElement(String... input) { return input[0]; } - // MaD=p;ParamFlow;true;returnCollectionElement;(List);;Argument[0].Element;ReturnValue;taint;df-generated + // summary=p;ParamFlow;true;returnCollectionElement;(List);;Argument[0].Element;ReturnValue;taint;df-generated public String returnCollectionElement(List input) { return input.get(0); } - // MaD=p;ParamFlow;true;returnIteratorElement;(Iterator);;Argument[0].Element;ReturnValue;taint;df-generated + // summary=p;ParamFlow;true;returnIteratorElement;(Iterator);;Argument[0].Element;ReturnValue;taint;df-generated public String returnIteratorElement(Iterator input) { return input.next(); } - // MaD=p;ParamFlow;true;returnIterableElement;(Iterable);;Argument[0].Element;ReturnValue;taint;df-generated + // summary=p;ParamFlow;true;returnIterableElement;(Iterable);;Argument[0].Element;ReturnValue;taint;df-generated public String returnIterableElement(Iterable input) { return input.iterator().next(); } @@ -54,17 +54,17 @@ public Class mapType(Class input) { return input; } - // MaD=p;ParamFlow;true;writeChunked;(byte[],OutputStream);;Argument[0];Argument[1];taint;df-generated + // summary=p;ParamFlow;true;writeChunked;(byte[],OutputStream);;Argument[0];Argument[1];taint;df-generated public void writeChunked(byte[] data, OutputStream output) throws IOException { output.write(data, 0, data.length); } - // MaD=p;ParamFlow;true;writeChunked;(char[],OutputStream);;Argument[0];Argument[1];taint;df-generated + // summary=p;ParamFlow;true;writeChunked;(char[],OutputStream);;Argument[0];Argument[1];taint;df-generated public void writeChunked(char[] data, OutputStream output) throws IOException { output.write(String.valueOf(data).getBytes(), 0, data.length); } - // MaD=p;ParamFlow;true;addTo;(String,List);;Argument[0];Argument[1].Element;taint;df-generated + // summary=p;ParamFlow;true;addTo;(String,List);;Argument[0];Argument[1].Element;taint;df-generated public void addTo(String data, List target) { target.add(data); } diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/Pojo.java b/java/ql/test/utils/modelgenerator/dataflow/p/Pojo.java index 15fbda5bc79d..524e448ef815 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/Pojo.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/Pojo.java @@ -30,12 +30,12 @@ int length() { private List charList = Arrays.asList('a', 'b', 'c'); private Byte[] byteObjectArray = new Byte[] {1, 2, 3}; - // MaD=p;Pojo;false;getValue;();;Argument[this];ReturnValue;taint;df-generated + // summary=p;Pojo;false;getValue;();;Argument[this];ReturnValue;taint;df-generated public String getValue() { return value; } - // MaD=p;Pojo;false;setValue;(String);;Argument[0];Argument[this];taint;df-generated + // summary=p;Pojo;false;setValue;(String);;Argument[0];Argument[this];taint;df-generated public void setValue(String value) { this.value = value; } @@ -57,12 +57,12 @@ public int[] getPrimitiveArray() { return new int[] {intValue}; } - // MaD=p;Pojo;false;getCharArray;();;Argument[this];ReturnValue;taint;df-generated + // summary=p;Pojo;false;getCharArray;();;Argument[this];ReturnValue;taint;df-generated public char[] getCharArray() { return charArray; } - // MaD=p;Pojo;false;getByteArray;();;Argument[this];ReturnValue;taint;df-generated + // summary=p;Pojo;false;getByteArray;();;Argument[this];ReturnValue;taint;df-generated public byte[] getByteArray() { return byteArray; } @@ -79,12 +79,12 @@ public Collection getBoxedCollection() { return List.of(Integer.valueOf(intValue)); } - // MaD=p;Pojo;false;getBoxedChars;();;Argument[this];ReturnValue;taint;df-generated + // summary=p;Pojo;false;getBoxedChars;();;Argument[this];ReturnValue;taint;df-generated public List getBoxedChars() { return charList; } - // MaD=p;Pojo;false;getBoxedBytes;();;Argument[this];ReturnValue;taint;df-generated + // summary=p;Pojo;false;getBoxedBytes;();;Argument[this];ReturnValue;taint;df-generated public Byte[] getBoxedBytes() { return byteObjectArray; } @@ -97,7 +97,7 @@ public BigDecimal getBigDecimal() { return new BigDecimal(value); } - // MaD=p;Pojo;false;fillIn;(List);;Argument[this];Argument[0].Element;taint;df-generated + // summary=p;Pojo;false;fillIn;(List);;Argument[this];Argument[0].Element;taint;df-generated public void fillIn(List target) { target.add(value); } diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/PrivateFlowViaPublicInterface.java b/java/ql/test/utils/modelgenerator/dataflow/p/PrivateFlowViaPublicInterface.java index 13a2897f08a9..6b5dbca3e114 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/PrivateFlowViaPublicInterface.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/PrivateFlowViaPublicInterface.java @@ -12,7 +12,7 @@ static class RandomPojo { } public static interface SPI { - // MaD=p;PrivateFlowViaPublicInterface$SPI;true;openStream;();;Argument[this];ReturnValue;taint;df-generated + // summary=p;PrivateFlowViaPublicInterface$SPI;true;openStream;();;Argument[this];ReturnValue;taint;df-generated OutputStream openStream() throws IOException; default OutputStream openStreamNone() throws IOException { @@ -50,7 +50,7 @@ public OutputStream openStreamNone() throws IOException { } } - // MaD=p;PrivateFlowViaPublicInterface;true;createAnSPI;(File);;Argument[0];ReturnValue;taint;df-generated + // summary=p;PrivateFlowViaPublicInterface;true;createAnSPI;(File);;Argument[0];ReturnValue;taint;df-generated public static SPI createAnSPI(File file) { return new PrivateImplWithSink(file); } diff --git a/java/ql/test/utils/modelgenerator/typebasedflow/p/MyFunction.java b/java/ql/test/utils/modelgenerator/typebasedflow/p/MyFunction.java index 04683952f83f..e3589bf5f6ca 100644 --- a/java/ql/test/utils/modelgenerator/typebasedflow/p/MyFunction.java +++ b/java/ql/test/utils/modelgenerator/typebasedflow/p/MyFunction.java @@ -3,8 +3,8 @@ @FunctionalInterface public interface MyFunction { - // MaD=p;MyFunction;true;apply;(Object,Object);;Argument[this].SyntheticField[ArgType2];ReturnValue;value;tb-generated - // MaD=p;MyFunction;true;apply;(Object,Object);;Argument[0];Argument[this].SyntheticField[ArgType0];value;tb-generated - // MaD=p;MyFunction;true;apply;(Object,Object);;Argument[1];Argument[this].SyntheticField[ArgType1];value;tb-generated - T3 apply(T1 x, T2 y); -} \ No newline at end of file + // summary=p;MyFunction;true;apply;(Object,Object);;Argument[this].SyntheticField[ArgType2];ReturnValue;value;tb-generated + // summary=p;MyFunction;true;apply;(Object,Object);;Argument[0];Argument[this].SyntheticField[ArgType0];value;tb-generated + // summary=p;MyFunction;true;apply;(Object,Object);;Argument[1];Argument[this].SyntheticField[ArgType1];value;tb-generated + T3 apply(T1 x, T2 y); +} diff --git a/java/ql/test/utils/modelgenerator/typebasedflow/p/Stream.java b/java/ql/test/utils/modelgenerator/typebasedflow/p/Stream.java index 86d25088645c..8e99fc7ca7c3 100644 --- a/java/ql/test/utils/modelgenerator/typebasedflow/p/Stream.java +++ b/java/ql/test/utils/modelgenerator/typebasedflow/p/Stream.java @@ -2,246 +2,244 @@ import java.util.*; import java.util.function.*; -import java.util.stream.LongStream; -import java.util.stream.IntStream; -import java.util.stream.DoubleStream; import java.util.stream.Collector; +import java.util.stream.DoubleStream; +import java.util.stream.IntStream; +import java.util.stream.LongStream; -/** - * This is a stub implementation of the Java Stream API. - */ +/** This is a stub implementation of the Java Stream API. */ public class Stream { - // MaD=p;Stream;true;iterator;();;Argument[this].Element;ReturnValue.Element;value;tb-generated - public Iterator iterator() { - return null; - } - - // MaD=p;Stream;true;allMatch;(Predicate);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated - public boolean allMatch(Predicate predicate) { - return false; - } - - // MaD=p;Stream;true;collect;(Supplier,BiConsumer,BiConsumer);;Argument[this].Element;Argument[1].Parameter[1];value;tb-generated - // MaD=p;Stream;true;collect;(Supplier,BiConsumer,BiConsumer);;Argument[0].ReturnValue;Argument[1].Parameter[0];value;tb-generated - // MaD=p;Stream;true;collect;(Supplier,BiConsumer,BiConsumer);;Argument[0].ReturnValue;Argument[2].Parameter[0];value;tb-generated - // MaD=p;Stream;true;collect;(Supplier,BiConsumer,BiConsumer);;Argument[0].ReturnValue;Argument[2].Parameter[1];value;tb-generated - // MaD=p;Stream;true;collect;(Supplier,BiConsumer,BiConsumer);;Argument[0].ReturnValue;ReturnValue;value;tb-generated - public R collect(Supplier supplier, BiConsumer accumulator, BiConsumer combiner) { - return null; - } - - // Collector is not a functional interface, so this is not supported - public R collect(Collector collector) { - return null; - } - - // MaD=p;Stream;true;concat;(Stream,Stream);;Argument[0].Element;ReturnValue.Element;value;tb-generated - // MaD=p;Stream;true;concat;(Stream,Stream);;Argument[1].Element;ReturnValue.Element;value;tb-generated - public static Stream concat(Stream a, Stream b) { - return null; - } - - // MaD=p;Stream;true;distinct;();;Argument[this].Element;ReturnValue.Element;value;tb-generated - public Stream distinct() { - return null; - } - - public static Stream empty() { - return null; - } - - // MaD=p;Stream;true;filter;(Predicate);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated - // MaD=p;Stream;true;filter;(Predicate);;Argument[this].Element;ReturnValue.Element;value;tb-generated - public Stream filter(Predicate predicate) { - return null; - } - - // MaD=p;Stream;true;findAny;();;Argument[this].Element;ReturnValue.SyntheticField[ArgType0];value;tb-generated - public Optional findAny() { - return null; - } - - // MaD=p;Stream;true;findFirst;();;Argument[this].Element;ReturnValue.SyntheticField[ArgType0];value;tb-generated - public Optional findFirst() { - return null; - } - - // MaD=p;Stream;true;flatMap;(Function);;Argument[0].ReturnValue.Element;ReturnValue.Element;value;tb-generated - // MaD=p;Stream;true;flatMap;(Function);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated - public Stream flatMap(Function> mapper) { - return null; - } - - // MaD=p;Stream;true;flatMapToDouble;(Function);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated - public DoubleStream flatMapToDouble(Function mapper) { - return null; - } - - // MaD=p;Stream;true;flatMapToInt;(Function);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated - public IntStream flatMapToInt(Function mapper) { - return null; - } - - // MaD=p;Stream;true;flatMapToLong;(Function);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated - public LongStream flatMapToLong(Function mapper) { - return null; - } - - // MaD=p;Stream;true;forEach;(Consumer);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated - public void forEach(Consumer action) { - } - - // MaD=p;Stream;true;forEachOrdered;(Consumer);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated - public void forEachOrdered(Consumer action) { - } - - // MaD=p;Stream;true;generate;(Supplier);;Argument[0].ReturnValue;ReturnValue.Element;value;tb-generated - public static Stream generate(Supplier s) { - return null; - } - - // MaD=p;Stream;true;iterate;(Object,UnaryOperator);;Argument[0];Argument[1].Parameter[0];value;tb-generated - // MaD=p;Stream;true;iterate;(Object,UnaryOperator);;Argument[0];ReturnValue.Element;value;tb-generated - // MaD=p;Stream;true;iterate;(Object,UnaryOperator);;Argument[1].ReturnValue;Argument[1].Parameter[0];value;tb-generated - // MaD=p;Stream;true;iterate;(Object,UnaryOperator);;Argument[1].ReturnValue;ReturnValue.Element;value;tb-generated - public static Stream iterate(T seed, UnaryOperator f) { - return null; - } - - // MaD=p;Stream;true;limit;(long);;Argument[this].Element;ReturnValue.Element;value;tb-generated - public Stream limit(long maxSize) { - return null; - } - - // MaD=p;Stream;true;map;(Function);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated - // MaD=p;Stream;true;map;(Function);;Argument[0].ReturnValue;ReturnValue.Element;value;tb-generated - public Stream map(Function mapper) { - return null; - } - - // MaD=p;Stream;true;mapToDouble;(ToDoubleFunction);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated - public DoubleStream mapToDouble(ToDoubleFunction mapper) { - return null; - } - - // MaD=p;Stream;true;mapToInt;(ToIntFunction);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated - public IntStream mapToInt(ToIntFunction mapper) { - return null; - } - - // MaD=p;Stream;true;mapToLong;(ToLongFunction);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated - public LongStream mapToLong(ToLongFunction mapper) { - return null; - } - - // MaD=p;Stream;true;max;(Comparator);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated - // MaD=p;Stream;true;max;(Comparator);;Argument[this].Element;Argument[0].Parameter[1];value;tb-generated - // MaD=p;Stream;true;max;(Comparator);;Argument[this].Element;ReturnValue.SyntheticField[ArgType0];value;tb-generated - public Optional max(Comparator comparator) { - return null; - } - - // MaD=p;Stream;true;min;(Comparator);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated - // MaD=p;Stream;true;min;(Comparator);;Argument[this].Element;Argument[0].Parameter[1];value;tb-generated - // MaD=p;Stream;true;min;(Comparator);;Argument[this].Element;ReturnValue.SyntheticField[ArgType0];value;tb-generated - public Optional min(Comparator comparator) { - return null; - } - - // MaD=p;Stream;true;noneMatch;(Predicate);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated - public boolean noneMatch(Predicate predicate) { - return false; - } - - // MaD=p;Stream;true;of;(Object[]);;Argument[0].ArrayElement;ReturnValue.Element;value;tb-generated - public static Stream of(T... t) { - return null; - } - - // MaD=p;Stream;true;of;(Object);;Argument[0];ReturnValue.Element;value;tb-generated - public static Stream of(T t) { - return null; - } - - // MaD=p;Stream;true;peek;(Consumer);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated - // MaD=p;Stream;true;peek;(Consumer);;Argument[this].Element;ReturnValue.Element;value;tb-generated - public Stream peek(Consumer action) { - return null; - } - - // The generated models are only partially correct. - // MaD=p;Stream;true;reduce;(BinaryOperator);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated - // MaD=p;Stream;true;reduce;(BinaryOperator);;Argument[this].Element;Argument[0].Parameter[1];value;tb-generated - // MaD=p;Stream;true;reduce;(BinaryOperator);;Argument[this].Element;ReturnValue.SyntheticField[ArgType0];value;tb-generated - // MaD=p;Stream;true;reduce;(BinaryOperator);;Argument[0].ReturnValue;Argument[0].Parameter[0];value;tb-generated - // MaD=p;Stream;true;reduce;(BinaryOperator);;Argument[0].ReturnValue;Argument[0].Parameter[1];value;tb-generated - // MaD=p;Stream;true;reduce;(BinaryOperator);;Argument[0].ReturnValue;ReturnValue.SyntheticField[ArgType0];value;tb-generated - // SPURIOUS-MaD=p;Stream;true;reduce;(BinaryOperator);;Argument[0].ReturnValue;Argument[this].Element;value;tb-generated - public Optional reduce(BinaryOperator accumulator) { - return null; - } - - // The generated models are only partially correct. - // MaD=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[this].Element;Argument[1].Parameter[0];value;tb-generated - // MaD=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[this].Element;Argument[1].Parameter[1];value;tb-generated - // MaD=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[0];Argument[1].Parameter[0];value;tb-generated - // MaD=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[0];Argument[1].Parameter[1];value;tb-generated - // MaD=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[0];ReturnValue;value;tb-generated - // MaD=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[1].ReturnValue;Argument[1].Parameter[0];value;tb-generated - // MaD=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[1].ReturnValue;Argument[1].Parameter[1];value;tb-generated - // MaD=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[1].ReturnValue;ReturnValue;value;tb-generated - // SPURIOUS-MaD=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[this].Element;ReturnValue;value;tb-generated - // SPURIOUS-MaD=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[0];Argument[this].Element;value;tb-generated - // SPURIOUS-MaD=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[1].ReturnValue;Argument[this].Element;value;tb-generated - public T reduce(T identity, BinaryOperator accumulator) { - return null; - } - - // MaD=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[this].Element;Argument[1].Parameter[1];value;tb-generated - // MaD=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[0];Argument[1].Parameter[0];value;tb-generated - // MaD=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[0];Argument[2].Parameter[0];value;tb-generated - // MaD=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[0];Argument[2].Parameter[1];value;tb-generated - // MaD=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[0];ReturnValue;value;tb-generated - // MaD=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[1].ReturnValue;Argument[1].Parameter[0];value;tb-generated - // MaD=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[1].ReturnValue;Argument[2].Parameter[0];value;tb-generated - // MaD=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[1].ReturnValue;Argument[2].Parameter[1];value;tb-generated - // MaD=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[1].ReturnValue;ReturnValue;value;tb-generated - // MaD=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[2].ReturnValue;Argument[1].Parameter[0];value;tb-generated - // MaD=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[2].ReturnValue;Argument[2].Parameter[0];value;tb-generated - // MaD=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[2].ReturnValue;Argument[2].Parameter[1];value;tb-generated - // MaD=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[2].ReturnValue;ReturnValue;value;tb-generated - public U reduce(U identity, BiFunction accumulator, BinaryOperator combiner) { - return null; - } - - // MaD=p;Stream;true;skip;(long);;Argument[this].Element;ReturnValue.Element;value;tb-generated - public Stream skip(long n) { - return null; - } - - // MaD=p;Stream;true;sorted;();;Argument[this].Element;ReturnValue.Element;value;tb-generated - public Stream sorted() { - return null; - } - - // MaD=p;Stream;true;sorted;(Comparator);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated - // MaD=p;Stream;true;sorted;(Comparator);;Argument[this].Element;Argument[0].Parameter[1];value;tb-generated - // MaD=p;Stream;true;sorted;(Comparator);;Argument[this].Element;ReturnValue.Element;value;tb-generated - public Stream sorted(Comparator comparator) { - return null; - } - - // Models can never be generated correctly based on the type information - // as it involves downcasting. - public Object[] toArray() { - return null; - } - - // The generated result is only partially correct as there is no mentioning of - // the type T in the method definition. - // MaD=p;Stream;true;toArray;(IntFunction);;Argument[0].ReturnValue.ArrayElement;ReturnValue.ArrayElement;value;tb-generated - public A[] toArray(IntFunction generator) { - return null; - } -} \ No newline at end of file + // summary=p;Stream;true;iterator;();;Argument[this].Element;ReturnValue.Element;value;tb-generated + public Iterator iterator() { + return null; + } + + // summary=p;Stream;true;allMatch;(Predicate);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated + public boolean allMatch(Predicate predicate) { + return false; + } + + // summary=p;Stream;true;collect;(Supplier,BiConsumer,BiConsumer);;Argument[this].Element;Argument[1].Parameter[1];value;tb-generated + // summary=p;Stream;true;collect;(Supplier,BiConsumer,BiConsumer);;Argument[0].ReturnValue;Argument[1].Parameter[0];value;tb-generated + // summary=p;Stream;true;collect;(Supplier,BiConsumer,BiConsumer);;Argument[0].ReturnValue;Argument[2].Parameter[0];value;tb-generated + // summary=p;Stream;true;collect;(Supplier,BiConsumer,BiConsumer);;Argument[0].ReturnValue;Argument[2].Parameter[1];value;tb-generated + // summary=p;Stream;true;collect;(Supplier,BiConsumer,BiConsumer);;Argument[0].ReturnValue;ReturnValue;value;tb-generated + public R collect( + Supplier supplier, BiConsumer accumulator, BiConsumer combiner) { + return null; + } + + // Collector is not a functional interface, so this is not supported + public R collect(Collector collector) { + return null; + } + + // summary=p;Stream;true;concat;(Stream,Stream);;Argument[0].Element;ReturnValue.Element;value;tb-generated + // summary=p;Stream;true;concat;(Stream,Stream);;Argument[1].Element;ReturnValue.Element;value;tb-generated + public static Stream concat(Stream a, Stream b) { + return null; + } + + // summary=p;Stream;true;distinct;();;Argument[this].Element;ReturnValue.Element;value;tb-generated + public Stream distinct() { + return null; + } + + public static Stream empty() { + return null; + } + + // summary=p;Stream;true;filter;(Predicate);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated + // summary=p;Stream;true;filter;(Predicate);;Argument[this].Element;ReturnValue.Element;value;tb-generated + public Stream filter(Predicate predicate) { + return null; + } + + // summary=p;Stream;true;findAny;();;Argument[this].Element;ReturnValue.SyntheticField[ArgType0];value;tb-generated + public Optional findAny() { + return null; + } + + // summary=p;Stream;true;findFirst;();;Argument[this].Element;ReturnValue.SyntheticField[ArgType0];value;tb-generated + public Optional findFirst() { + return null; + } + + // summary=p;Stream;true;flatMap;(Function);;Argument[0].ReturnValue.Element;ReturnValue.Element;value;tb-generated + // summary=p;Stream;true;flatMap;(Function);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated + public Stream flatMap(Function> mapper) { + return null; + } + + // summary=p;Stream;true;flatMapToDouble;(Function);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated + public DoubleStream flatMapToDouble(Function mapper) { + return null; + } + + // summary=p;Stream;true;flatMapToInt;(Function);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated + public IntStream flatMapToInt(Function mapper) { + return null; + } + + // summary=p;Stream;true;flatMapToLong;(Function);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated + public LongStream flatMapToLong(Function mapper) { + return null; + } + + // summary=p;Stream;true;forEach;(Consumer);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated + public void forEach(Consumer action) {} + + // summary=p;Stream;true;forEachOrdered;(Consumer);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated + public void forEachOrdered(Consumer action) {} + + // summary=p;Stream;true;generate;(Supplier);;Argument[0].ReturnValue;ReturnValue.Element;value;tb-generated + public static Stream generate(Supplier s) { + return null; + } + + // summary=p;Stream;true;iterate;(Object,UnaryOperator);;Argument[0];Argument[1].Parameter[0];value;tb-generated + // summary=p;Stream;true;iterate;(Object,UnaryOperator);;Argument[0];ReturnValue.Element;value;tb-generated + // summary=p;Stream;true;iterate;(Object,UnaryOperator);;Argument[1].ReturnValue;Argument[1].Parameter[0];value;tb-generated + // summary=p;Stream;true;iterate;(Object,UnaryOperator);;Argument[1].ReturnValue;ReturnValue.Element;value;tb-generated + public static Stream iterate(T seed, UnaryOperator f) { + return null; + } + + // summary=p;Stream;true;limit;(long);;Argument[this].Element;ReturnValue.Element;value;tb-generated + public Stream limit(long maxSize) { + return null; + } + + // summary=p;Stream;true;map;(Function);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated + // summary=p;Stream;true;map;(Function);;Argument[0].ReturnValue;ReturnValue.Element;value;tb-generated + public Stream map(Function mapper) { + return null; + } + + // summary=p;Stream;true;mapToDouble;(ToDoubleFunction);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated + public DoubleStream mapToDouble(ToDoubleFunction mapper) { + return null; + } + + // summary=p;Stream;true;mapToInt;(ToIntFunction);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated + public IntStream mapToInt(ToIntFunction mapper) { + return null; + } + + // summary=p;Stream;true;mapToLong;(ToLongFunction);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated + public LongStream mapToLong(ToLongFunction mapper) { + return null; + } + + // summary=p;Stream;true;max;(Comparator);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated + // summary=p;Stream;true;max;(Comparator);;Argument[this].Element;Argument[0].Parameter[1];value;tb-generated + // summary=p;Stream;true;max;(Comparator);;Argument[this].Element;ReturnValue.SyntheticField[ArgType0];value;tb-generated + public Optional max(Comparator comparator) { + return null; + } + + // summary=p;Stream;true;min;(Comparator);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated + // summary=p;Stream;true;min;(Comparator);;Argument[this].Element;Argument[0].Parameter[1];value;tb-generated + // summary=p;Stream;true;min;(Comparator);;Argument[this].Element;ReturnValue.SyntheticField[ArgType0];value;tb-generated + public Optional min(Comparator comparator) { + return null; + } + + // summary=p;Stream;true;noneMatch;(Predicate);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated + public boolean noneMatch(Predicate predicate) { + return false; + } + + // summary=p;Stream;true;of;(Object[]);;Argument[0].ArrayElement;ReturnValue.Element;value;tb-generated + public static Stream of(T... t) { + return null; + } + + // summary=p;Stream;true;of;(Object);;Argument[0];ReturnValue.Element;value;tb-generated + public static Stream of(T t) { + return null; + } + + // summary=p;Stream;true;peek;(Consumer);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated + // summary=p;Stream;true;peek;(Consumer);;Argument[this].Element;ReturnValue.Element;value;tb-generated + public Stream peek(Consumer action) { + return null; + } + + // The generated models are only partially correct. + // summary=p;Stream;true;reduce;(BinaryOperator);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated + // summary=p;Stream;true;reduce;(BinaryOperator);;Argument[this].Element;Argument[0].Parameter[1];value;tb-generated + // summary=p;Stream;true;reduce;(BinaryOperator);;Argument[this].Element;ReturnValue.SyntheticField[ArgType0];value;tb-generated + // summary=p;Stream;true;reduce;(BinaryOperator);;Argument[0].ReturnValue;Argument[0].Parameter[0];value;tb-generated + // summary=p;Stream;true;reduce;(BinaryOperator);;Argument[0].ReturnValue;Argument[0].Parameter[1];value;tb-generated + // summary=p;Stream;true;reduce;(BinaryOperator);;Argument[0].ReturnValue;ReturnValue.SyntheticField[ArgType0];value;tb-generated + // SPURIOUS-summary=p;Stream;true;reduce;(BinaryOperator);;Argument[0].ReturnValue;Argument[this].Element;value;tb-generated + public Optional reduce(BinaryOperator accumulator) { + return null; + } + + // The generated models are only partially correct. + // summary=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[this].Element;Argument[1].Parameter[0];value;tb-generated + // summary=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[this].Element;Argument[1].Parameter[1];value;tb-generated + // summary=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[0];Argument[1].Parameter[0];value;tb-generated + // summary=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[0];Argument[1].Parameter[1];value;tb-generated + // summary=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[0];ReturnValue;value;tb-generated + // summary=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[1].ReturnValue;Argument[1].Parameter[0];value;tb-generated + // summary=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[1].ReturnValue;Argument[1].Parameter[1];value;tb-generated + // summary=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[1].ReturnValue;ReturnValue;value;tb-generated + // SPURIOUS-summary=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[this].Element;ReturnValue;value;tb-generated + // SPURIOUS-summary=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[0];Argument[this].Element;value;tb-generated + // SPURIOUS-summary=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[1].ReturnValue;Argument[this].Element;value;tb-generated + public T reduce(T identity, BinaryOperator accumulator) { + return null; + } + + // summary=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[this].Element;Argument[1].Parameter[1];value;tb-generated + // summary=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[0];Argument[1].Parameter[0];value;tb-generated + // summary=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[0];Argument[2].Parameter[0];value;tb-generated + // summary=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[0];Argument[2].Parameter[1];value;tb-generated + // summary=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[0];ReturnValue;value;tb-generated + // summary=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[1].ReturnValue;Argument[1].Parameter[0];value;tb-generated + // summary=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[1].ReturnValue;Argument[2].Parameter[0];value;tb-generated + // summary=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[1].ReturnValue;Argument[2].Parameter[1];value;tb-generated + // summary=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[1].ReturnValue;ReturnValue;value;tb-generated + // summary=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[2].ReturnValue;Argument[1].Parameter[0];value;tb-generated + // summary=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[2].ReturnValue;Argument[2].Parameter[0];value;tb-generated + // summary=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[2].ReturnValue;Argument[2].Parameter[1];value;tb-generated + // summary=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[2].ReturnValue;ReturnValue;value;tb-generated + public U reduce( + U identity, BiFunction accumulator, BinaryOperator combiner) { + return null; + } + + // summary=p;Stream;true;skip;(long);;Argument[this].Element;ReturnValue.Element;value;tb-generated + public Stream skip(long n) { + return null; + } + + // summary=p;Stream;true;sorted;();;Argument[this].Element;ReturnValue.Element;value;tb-generated + public Stream sorted() { + return null; + } + + // summary=p;Stream;true;sorted;(Comparator);;Argument[this].Element;Argument[0].Parameter[0];value;tb-generated + // summary=p;Stream;true;sorted;(Comparator);;Argument[this].Element;Argument[0].Parameter[1];value;tb-generated + // summary=p;Stream;true;sorted;(Comparator);;Argument[this].Element;ReturnValue.Element;value;tb-generated + public Stream sorted(Comparator comparator) { + return null; + } + + // Models can never be generated correctly based on the type information + // as it involves downcasting. + public Object[] toArray() { + return null; + } + + // The generated result is only partially correct as there is no mentioning of + // the type T in the method definition. + // summary=p;Stream;true;toArray;(IntFunction);;Argument[0].ReturnValue.ArrayElement;ReturnValue.ArrayElement;value;tb-generated + public A[] toArray(IntFunction generator) { + return null; + } +} diff --git a/java/ql/test/utils/modelgenerator/typebasedflow/p/TypeBasedCollection.java b/java/ql/test/utils/modelgenerator/typebasedflow/p/TypeBasedCollection.java index b1c95dc415a0..e66189e7dedd 100644 --- a/java/ql/test/utils/modelgenerator/typebasedflow/p/TypeBasedCollection.java +++ b/java/ql/test/utils/modelgenerator/typebasedflow/p/TypeBasedCollection.java @@ -1,25 +1,23 @@ package p; -import java.util.List; import java.util.ArrayList; +import java.util.List; public class TypeBasedCollection extends ArrayList { - // MaD=p;TypeBasedCollection;true;addT;(Object);;Argument[0];Argument[this].Element;value;tb-generated - public void addT(T x) { - } + // summary=p;TypeBasedCollection;true;addT;(Object);;Argument[0];Argument[this].Element;value;tb-generated + public void addT(T x) {} - // MaD=p;TypeBasedCollection;true;addManyT;(List);;Argument[0].Element;Argument[this].Element;value;tb-generated - public void addManyT(List xs) { - } + // summary=p;TypeBasedCollection;true;addManyT;(List);;Argument[0].Element;Argument[this].Element;value;tb-generated + public void addManyT(List xs) {} - // MaD=p;TypeBasedCollection;true;firstT;();;Argument[this].Element;ReturnValue;value;tb-generated - public T firstT() { - return null; - } + // summary=p;TypeBasedCollection;true;firstT;();;Argument[this].Element;ReturnValue;value;tb-generated + public T firstT() { + return null; + } - // MaD=p;TypeBasedCollection;true;getManyT;();;Argument[this].Element;ReturnValue.Element;value;tb-generated - public List getManyT() { - return null; - } -} \ No newline at end of file + // summary=p;TypeBasedCollection;true;getManyT;();;Argument[this].Element;ReturnValue.Element;value;tb-generated + public List getManyT() { + return null; + } +} diff --git a/java/ql/test/utils/modelgenerator/typebasedflow/p/TypeBasedComplex.java b/java/ql/test/utils/modelgenerator/typebasedflow/p/TypeBasedComplex.java index ffca17457a0c..a6e6c2204758 100644 --- a/java/ql/test/utils/modelgenerator/typebasedflow/p/TypeBasedComplex.java +++ b/java/ql/test/utils/modelgenerator/typebasedflow/p/TypeBasedComplex.java @@ -5,87 +5,85 @@ public class TypeBasedComplex { - // MaD=p;TypeBasedComplex;true;addMany;(List);;Argument[0].Element;Argument[this].SyntheticField[ArgType0];value;tb-generated - public void addMany(List xs) { - } + // summary=p;TypeBasedComplex;true;addMany;(List);;Argument[0].Element;Argument[this].SyntheticField[ArgType0];value;tb-generated + public void addMany(List xs) {} - // MaD=p;TypeBasedComplex;true;getMany;();;Argument[this].SyntheticField[ArgType0];ReturnValue.Element;value;tb-generated - public List getMany() { - return null; - } + // summary=p;TypeBasedComplex;true;getMany;();;Argument[this].SyntheticField[ArgType0];ReturnValue.Element;value;tb-generated + public List getMany() { + return null; + } - // MaD=p;TypeBasedComplex;true;apply;(Function);;Argument[this].SyntheticField[ArgType0];Argument[0].Parameter[0];value;tb-generated - public Integer apply(Function f) { - return null; - } + // summary=p;TypeBasedComplex;true;apply;(Function);;Argument[this].SyntheticField[ArgType0];Argument[0].Parameter[0];value;tb-generated + public Integer apply(Function f) { + return null; + } - // A method that doesn't mention `T` in its type signature. - // This is for testing that we don't generate a summary that involves the - // implicit field for `T`. - // MaD=p;TypeBasedComplex;true;apply2;(Object,Function);;Argument[0];Argument[1].Parameter[0];value;tb-generated - // MaD=p;TypeBasedComplex;true;apply2;(Object,Function);;Argument[1].ReturnValue;ReturnValue;value;tb-generated - public T2 apply2(T1 x, Function f) { - return null; - } + // A method that doesn't mention `T` in its type signature. + // This is for testing that we don't generate a summary that involves the + // implicit field for `T`. + // summary=p;TypeBasedComplex;true;apply2;(Object,Function);;Argument[0];Argument[1].Parameter[0];value;tb-generated + // summary=p;TypeBasedComplex;true;apply2;(Object,Function);;Argument[1].ReturnValue;ReturnValue;value;tb-generated + public T2 apply2(T1 x, Function f) { + return null; + } - // MaD=p;TypeBasedComplex;true;flatMap;(Function);;Argument[this].SyntheticField[ArgType0];Argument[0].Parameter[0];value;tb-generated - // MaD=p;TypeBasedComplex;true;flatMap;(Function);;Argument[this].SyntheticField[ArgType0];ReturnValue.SyntheticField[ArgType0];value;tb-generated - // MaD=p;TypeBasedComplex;true;flatMap;(Function);;Argument[0].ReturnValue.Element;Argument[this].SyntheticField[ArgType0];value;tb-generated - // MaD=p;TypeBasedComplex;true;flatMap;(Function);;Argument[0].ReturnValue.Element;Argument[0].Parameter[0];value;tb-generated - // MaD=p;TypeBasedComplex;true;flatMap;(Function);;Argument[0].ReturnValue.Element;ReturnValue.SyntheticField[ArgType0];value;tb-generated - public TypeBasedComplex flatMap(Function> f) { - return null; - } + // summary=p;TypeBasedComplex;true;flatMap;(Function);;Argument[this].SyntheticField[ArgType0];Argument[0].Parameter[0];value;tb-generated + // summary=p;TypeBasedComplex;true;flatMap;(Function);;Argument[this].SyntheticField[ArgType0];ReturnValue.SyntheticField[ArgType0];value;tb-generated + // summary=p;TypeBasedComplex;true;flatMap;(Function);;Argument[0].ReturnValue.Element;Argument[this].SyntheticField[ArgType0];value;tb-generated + // summary=p;TypeBasedComplex;true;flatMap;(Function);;Argument[0].ReturnValue.Element;Argument[0].Parameter[0];value;tb-generated + // summary=p;TypeBasedComplex;true;flatMap;(Function);;Argument[0].ReturnValue.Element;ReturnValue.SyntheticField[ArgType0];value;tb-generated + public TypeBasedComplex flatMap(Function> f) { + return null; + } - // MaD=p;TypeBasedComplex;true;flatMap2;(Function);;Argument[this].SyntheticField[ArgType0];Argument[0].Parameter[0];value;tb-generated - // MaD=p;TypeBasedComplex;true;flatMap2;(Function);;Argument[0].ReturnValue.Element;ReturnValue.SyntheticField[ArgType0];value;tb-generated - public TypeBasedComplex flatMap2(Function> f) { - return null; - } + // summary=p;TypeBasedComplex;true;flatMap2;(Function);;Argument[this].SyntheticField[ArgType0];Argument[0].Parameter[0];value;tb-generated + // summary=p;TypeBasedComplex;true;flatMap2;(Function);;Argument[0].ReturnValue.Element;ReturnValue.SyntheticField[ArgType0];value;tb-generated + public TypeBasedComplex flatMap2(Function> f) { + return null; + } - // MaD=p;TypeBasedComplex;true;map;(Function);;Argument[this].SyntheticField[ArgType0];Argument[0].Parameter[0];value;tb-generated - // MaD=p;TypeBasedComplex;true;map;(Function);;Argument[0].ReturnValue;ReturnValue;value;tb-generated - public S map(Function f) { - return null; - } + // summary=p;TypeBasedComplex;true;map;(Function);;Argument[this].SyntheticField[ArgType0];Argument[0].Parameter[0];value;tb-generated + // summary=p;TypeBasedComplex;true;map;(Function);;Argument[0].ReturnValue;ReturnValue;value;tb-generated + public S map(Function f) { + return null; + } - // MaD=p;TypeBasedComplex;true;mapComplex;(Function);;Argument[this].SyntheticField[ArgType0];Argument[0].Parameter[0];value;tb-generated - // MaD=p;TypeBasedComplex;true;mapComplex;(Function);;Argument[0].ReturnValue;ReturnValue.SyntheticField[ArgType0];value;tb-generated - public TypeBasedComplex mapComplex(Function f) { - return null; - } + // summary=p;TypeBasedComplex;true;mapComplex;(Function);;Argument[this].SyntheticField[ArgType0];Argument[0].Parameter[0];value;tb-generated + // summary=p;TypeBasedComplex;true;mapComplex;(Function);;Argument[0].ReturnValue;ReturnValue.SyntheticField[ArgType0];value;tb-generated + public TypeBasedComplex mapComplex(Function f) { + return null; + } - // MaD=p;TypeBasedComplex;true;returnComplex;(Function);;Argument[this].SyntheticField[ArgType0];Argument[0].Parameter[0];value;tb-generated - // MaD=p;TypeBasedComplex;true;returnComplex;(Function);;Argument[this].SyntheticField[ArgType0];ReturnValue.SyntheticField[ArgType0];value;tb-generated - // MaD=p;TypeBasedComplex;true;returnComplex;(Function);;Argument[0].ReturnValue.SyntheticField[ArgType0];Argument[this].SyntheticField[ArgType0];value;tb-generated - // MaD=p;TypeBasedComplex;true;returnComplex;(Function);;Argument[0].ReturnValue.SyntheticField[ArgType0];Argument[0].Parameter[0];value;tb-generated - // MaD=p;TypeBasedComplex;true;returnComplex;(Function);;Argument[0].ReturnValue.SyntheticField[ArgType0];ReturnValue.SyntheticField[ArgType0];value;tb-generated - public TypeBasedComplex returnComplex(Function> f) { - return null; - } + // summary=p;TypeBasedComplex;true;returnComplex;(Function);;Argument[this].SyntheticField[ArgType0];Argument[0].Parameter[0];value;tb-generated + // summary=p;TypeBasedComplex;true;returnComplex;(Function);;Argument[this].SyntheticField[ArgType0];ReturnValue.SyntheticField[ArgType0];value;tb-generated + // summary=p;TypeBasedComplex;true;returnComplex;(Function);;Argument[0].ReturnValue.SyntheticField[ArgType0];Argument[this].SyntheticField[ArgType0];value;tb-generated + // summary=p;TypeBasedComplex;true;returnComplex;(Function);;Argument[0].ReturnValue.SyntheticField[ArgType0];Argument[0].Parameter[0];value;tb-generated + // summary=p;TypeBasedComplex;true;returnComplex;(Function);;Argument[0].ReturnValue.SyntheticField[ArgType0];ReturnValue.SyntheticField[ArgType0];value;tb-generated + public TypeBasedComplex returnComplex(Function> f) { + return null; + } - // MaD=p;TypeBasedComplex;true;set;(Integer,Function);;Argument[1].ReturnValue;Argument[this].SyntheticField[ArgType0];value;tb-generated - public void set(Integer x, Function f) { - } + // summary=p;TypeBasedComplex;true;set;(Integer,Function);;Argument[1].ReturnValue;Argument[this].SyntheticField[ArgType0];value;tb-generated + public void set(Integer x, Function f) {} - // MaD=p;TypeBasedComplex;true;applyMyFunction;(MyFunction,Integer);;Argument[this].SyntheticField[ArgType0];Argument[0].Parameter[0];value;tb-generated - // MaD=p;TypeBasedComplex;true;applyMyFunction;(MyFunction,Integer);;Argument[0].ReturnValue;Argument[this].SyntheticField[ArgType0];value;tb-generated - // MaD=p;TypeBasedComplex;true;applyMyFunction;(MyFunction,Integer);;Argument[0].ReturnValue;Argument[0].Parameter[0];value;tb-generated - public Integer applyMyFunction(MyFunction f, Integer x) { - return null; - } + // summary=p;TypeBasedComplex;true;applyMyFunction;(MyFunction,Integer);;Argument[this].SyntheticField[ArgType0];Argument[0].Parameter[0];value;tb-generated + // summary=p;TypeBasedComplex;true;applyMyFunction;(MyFunction,Integer);;Argument[0].ReturnValue;Argument[this].SyntheticField[ArgType0];value;tb-generated + // summary=p;TypeBasedComplex;true;applyMyFunction;(MyFunction,Integer);;Argument[0].ReturnValue;Argument[0].Parameter[0];value;tb-generated + public Integer applyMyFunction(MyFunction f, Integer x) { + return null; + } - // MaD=p;TypeBasedComplex;true;applyMyFunctionGeneric;(MyFunction,Object);;Argument[this].SyntheticField[ArgType0];Argument[0].Parameter[0];value;tb-generated - // MaD=p;TypeBasedComplex;true;applyMyFunctionGeneric;(MyFunction,Object);;Argument[0].ReturnValue;ReturnValue;value;tb-generated - // MaD=p;TypeBasedComplex;true;applyMyFunctionGeneric;(MyFunction,Object);;Argument[1];Argument[0].Parameter[1];value;tb-generated - public S2 applyMyFunctionGeneric(MyFunction f, S1 x) { - return null; - } + // summary=p;TypeBasedComplex;true;applyMyFunctionGeneric;(MyFunction,Object);;Argument[this].SyntheticField[ArgType0];Argument[0].Parameter[0];value;tb-generated + // summary=p;TypeBasedComplex;true;applyMyFunctionGeneric;(MyFunction,Object);;Argument[0].ReturnValue;ReturnValue;value;tb-generated + // summary=p;TypeBasedComplex;true;applyMyFunctionGeneric;(MyFunction,Object);;Argument[1];Argument[0].Parameter[1];value;tb-generated + public S2 applyMyFunctionGeneric(MyFunction f, S1 x) { + return null; + } - // MaD=p;TypeBasedComplex;true;applyMyFunctionGeneric;(MyFunction,Object,Object);;Argument[0].ReturnValue;ReturnValue;value;tb-generated - // MaD=p;TypeBasedComplex;true;applyMyFunctionGeneric;(MyFunction,Object,Object);;Argument[1];Argument[0].Parameter[0];value;tb-generated - // MaD=p;TypeBasedComplex;true;applyMyFunctionGeneric;(MyFunction,Object,Object);;Argument[2];Argument[0].Parameter[1];value;tb-generated - public S3 applyMyFunctionGeneric(MyFunction f, S1 x, S2 y) { - return null; - } -} \ No newline at end of file + // summary=p;TypeBasedComplex;true;applyMyFunctionGeneric;(MyFunction,Object,Object);;Argument[0].ReturnValue;ReturnValue;value;tb-generated + // summary=p;TypeBasedComplex;true;applyMyFunctionGeneric;(MyFunction,Object,Object);;Argument[1];Argument[0].Parameter[0];value;tb-generated + // summary=p;TypeBasedComplex;true;applyMyFunctionGeneric;(MyFunction,Object,Object);;Argument[2];Argument[0].Parameter[1];value;tb-generated + public S3 applyMyFunctionGeneric(MyFunction f, S1 x, S2 y) { + return null; + } +} diff --git a/java/ql/test/utils/modelgenerator/typebasedflow/p/TypeBasedSimple.java b/java/ql/test/utils/modelgenerator/typebasedflow/p/TypeBasedSimple.java index 8715bc2feeba..17b710922eb7 100644 --- a/java/ql/test/utils/modelgenerator/typebasedflow/p/TypeBasedSimple.java +++ b/java/ql/test/utils/modelgenerator/typebasedflow/p/TypeBasedSimple.java @@ -2,41 +2,37 @@ public class TypeBasedSimple { - // MaD=p;TypeBasedSimple;true;TypeBasedSimple;(Object);;Argument[0];Argument[this].SyntheticField[ArgType0];value;tb-generated - public TypeBasedSimple(T t) { - } - - // MaD=p;TypeBasedSimple;true;get;();;Argument[this].SyntheticField[ArgType0];ReturnValue;value;tb-generated - public T get() { - return null; - } - - // MaD=p;TypeBasedSimple;true;get;(Object);;Argument[this].SyntheticField[ArgType0];ReturnValue;value;tb-generated - public T get(Object o) { - return null; - } - - // MaD=p;TypeBasedSimple;true;id;(Object);;Argument[this].SyntheticField[ArgType0];ReturnValue;value;tb-generated - // MaD=p;TypeBasedSimple;true;id;(Object);;Argument[0];Argument[this].SyntheticField[ArgType0];value;tb-generated - // MaD=p;TypeBasedSimple;true;id;(Object);;Argument[0];ReturnValue;value;tb-generated - public T id(T x) { - return null; - } - - // MaD=p;TypeBasedSimple;true;id2;(Object);;Argument[0];ReturnValue;value;tb-generated - public S id2(S x) { - return null; - } - - // MaD=p;TypeBasedSimple;true;set;(Object);;Argument[0];Argument[this].SyntheticField[ArgType0];value;tb-generated - public void set(T x) { - } - - // MaD=p;TypeBasedSimple;true;set;(int,Object);;Argument[1];Argument[this].SyntheticField[ArgType0];value;tb-generated - public void set(int x, T y) { - } - - // No summary as S is unrelated to T - public void set2(S x) { - } -} \ No newline at end of file + // summary=p;TypeBasedSimple;true;TypeBasedSimple;(Object);;Argument[0];Argument[this].SyntheticField[ArgType0];value;tb-generated + public TypeBasedSimple(T t) {} + + // summary=p;TypeBasedSimple;true;get;();;Argument[this].SyntheticField[ArgType0];ReturnValue;value;tb-generated + public T get() { + return null; + } + + // summary=p;TypeBasedSimple;true;get;(Object);;Argument[this].SyntheticField[ArgType0];ReturnValue;value;tb-generated + public T get(Object o) { + return null; + } + + // summary=p;TypeBasedSimple;true;id;(Object);;Argument[this].SyntheticField[ArgType0];ReturnValue;value;tb-generated + // summary=p;TypeBasedSimple;true;id;(Object);;Argument[0];Argument[this].SyntheticField[ArgType0];value;tb-generated + // summary=p;TypeBasedSimple;true;id;(Object);;Argument[0];ReturnValue;value;tb-generated + public T id(T x) { + return null; + } + + // summary=p;TypeBasedSimple;true;id2;(Object);;Argument[0];ReturnValue;value;tb-generated + public S id2(S x) { + return null; + } + + // summary=p;TypeBasedSimple;true;set;(Object);;Argument[0];Argument[this].SyntheticField[ArgType0];value;tb-generated + public void set(T x) {} + + // summary=p;TypeBasedSimple;true;set;(int,Object);;Argument[1];Argument[this].SyntheticField[ArgType0];value;tb-generated + public void set(int x, T y) {} + + // No summary as S is unrelated to T + public void set2(S x) {} +} From 95ddd6ec743c8773ee94e5519ad8f97849c1491c Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 6 May 2024 13:34:03 +0200 Subject: [PATCH 219/238] Java: Generalize the inline mad test to allow further re-use. --- java/ql/test/TestUtilities/InlineMadTest.qll | 46 +++++++++++++------ .../dataflow/CaptureModels.expected | 4 +- .../modelgenerator/dataflow/CaptureModels.ql | 4 +- .../CaptureTypeBasedSummaryModels.expected | 4 +- .../CaptureTypeBasedSummaryModels.ql | 4 +- 5 files changed, 39 insertions(+), 23 deletions(-) diff --git a/java/ql/test/TestUtilities/InlineMadTest.qll b/java/ql/test/TestUtilities/InlineMadTest.qll index 3e9aee7eb9e2..a5602036a8cb 100644 --- a/java/ql/test/TestUtilities/InlineMadTest.qll +++ b/java/ql/test/TestUtilities/InlineMadTest.qll @@ -1,34 +1,50 @@ -signature module InlineMadTestConfigSig { +import java + +private signature module InlineMadTestLangSig { /** * Gets a relevant code comment, if any. */ string getComment(); +} + +signature module InlineMadTestConfigSig { + /** + * Gets the kind of the captured model. + */ + string getKind(); /** - * Gets an identified summary, if any. + * Gets a captured model, if any. */ - string getCapturedSummary(); + string getCapturedModel(); } -module InlineMadTest { - bindingset[kind] - private string expects(string kind) { - Input::getComment().regexpCapture(" *(SPURIOUS-)?" + kind + "=(.*)", 2) = result +private module InlineMadTestImpl { + private string expects() { + Lang::getComment().regexpCapture(" *(SPURIOUS-)?" + Input::getKind() + "=(.*)", 2) = result } - query predicate unexpectedSummary(string msg) { + query predicate unexpectedModel(string msg) { exists(string flow | - flow = Input::getCapturedSummary() and - not flow = expects("summary") and - msg = "Unexpected summary found: " + flow + flow = Input::getCapturedModel() and + not flow = expects() and + msg = "Unexpected " + Input::getKind() + " found: " + flow ) } - query predicate expectedSummary(string msg) { + query predicate expectedModel(string msg) { exists(string e | - e = expects("summary") and - not e = Input::getCapturedSummary() and - msg = "Expected summary missing: " + e + e = expects() and + not e = Input::getCapturedModel() and + msg = "Expected " + Input::getKind() + " missing: " + e ) } } + +private module InlineMadTestLang implements InlineMadTestLangSig { + string getComment() { result = any(Javadoc doc).getChild(0).toString() } +} + +module InlineMadTest { + import InlineMadTestImpl +} diff --git a/java/ql/test/utils/modelgenerator/dataflow/CaptureModels.expected b/java/ql/test/utils/modelgenerator/dataflow/CaptureModels.expected index ee55a9c6ba6e..cb6fc390349c 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/CaptureModels.expected +++ b/java/ql/test/utils/modelgenerator/dataflow/CaptureModels.expected @@ -1,2 +1,2 @@ -unexpectedSummary -expectedSummary +unexpectedModel +expectedModel diff --git a/java/ql/test/utils/modelgenerator/dataflow/CaptureModels.ql b/java/ql/test/utils/modelgenerator/dataflow/CaptureModels.ql index 1a2dbd03d7a9..821e8e8f0e71 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/CaptureModels.ql +++ b/java/ql/test/utils/modelgenerator/dataflow/CaptureModels.ql @@ -3,9 +3,9 @@ import utils.modelgenerator.internal.CaptureSummaryFlowQuery import TestUtilities.InlineMadTest module InlineMadTestConfig implements InlineMadTestConfigSig { - string getComment() { result = any(Javadoc doc).getChild(0).toString() } + string getCapturedModel() { result = captureFlow(_) } - string getCapturedSummary() { result = captureFlow(_) } + string getKind() { result = "summary" } } import InlineMadTest diff --git a/java/ql/test/utils/modelgenerator/typebasedflow/CaptureTypeBasedSummaryModels.expected b/java/ql/test/utils/modelgenerator/typebasedflow/CaptureTypeBasedSummaryModels.expected index ee55a9c6ba6e..cb6fc390349c 100644 --- a/java/ql/test/utils/modelgenerator/typebasedflow/CaptureTypeBasedSummaryModels.expected +++ b/java/ql/test/utils/modelgenerator/typebasedflow/CaptureTypeBasedSummaryModels.expected @@ -1,2 +1,2 @@ -unexpectedSummary -expectedSummary +unexpectedModel +expectedModel diff --git a/java/ql/test/utils/modelgenerator/typebasedflow/CaptureTypeBasedSummaryModels.ql b/java/ql/test/utils/modelgenerator/typebasedflow/CaptureTypeBasedSummaryModels.ql index c5c509ac3268..e3b64cca7852 100644 --- a/java/ql/test/utils/modelgenerator/typebasedflow/CaptureTypeBasedSummaryModels.ql +++ b/java/ql/test/utils/modelgenerator/typebasedflow/CaptureTypeBasedSummaryModels.ql @@ -3,9 +3,9 @@ import TestUtilities.InlineMadTest import utils.modelgenerator.internal.CaptureTypeBasedSummaryModels module InlineMadTestConfig implements InlineMadTestConfigSig { - string getComment() { result = any(Javadoc doc).getChild(0).toString() } + string getCapturedModel() { result = captureFlow(_) } - string getCapturedSummary() { result = captureFlow(_) } + string getKind() { result = "summary" } } import InlineMadTest From 73df4fa920bfdef11cd8ecb094092f103bfa4850 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Mon, 6 May 2024 14:55:35 +0200 Subject: [PATCH 220/238] Go: fix Windows installation --- .bazelrc | 3 ++- go/create_extractor_pack.py | 8 ++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.bazelrc b/.bazelrc index 36111310779c..c2b4d3b7f03e 100644 --- a/.bazelrc +++ b/.bazelrc @@ -15,7 +15,8 @@ build:macos --cxxopt=-std=c++20 --cpu=darwin_x86_64 build:windows --cxxopt=/std:c++20 --cxxopt=/Zc:preprocessor # this requires developer mode, but is required to have pack installer functioning -common:windows --windows_enable_symlinks --enable_runfiles +startup --windows_enable_symlinks +common --enable_runfiles common --registry=file:///%workspace%/misc/bazel/registry common --registry=https://bcr.bazel.build diff --git a/go/create_extractor_pack.py b/go/create_extractor_pack.py index 4d194ab93e46..427f0c37c36f 100755 --- a/go/create_extractor_pack.py +++ b/go/create_extractor_pack.py @@ -13,10 +13,14 @@ from go._extractor_pack_install_script import main -if os.environ['REPO_NAME'] == 'codeql~': +build_dir = workspace_dir / 'go' / 'build' + +if not build_dir.exists(): + # we probably are in the internal repo workspace_dir /= 'ql' + build_dir = workspace_dir / 'go' / 'build' -dest_dir = workspace_dir / 'go' / 'build' / 'codeql-extractor-pack' +dest_dir = build_dir / 'codeql-extractor-pack' shutil.rmtree(dest_dir, ignore_errors=True) os.environ['DESTDIR'] = str(dest_dir) main(sys.argv) From 54c9aea251b1e011e853f5c36ba397af3fa302f4 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Mon, 6 May 2024 15:47:02 +0200 Subject: [PATCH 221/238] Bazel: fix lfs lazy rule when all objects are local --- misc/bazel/internal/git_lfs_probe.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/misc/bazel/internal/git_lfs_probe.py b/misc/bazel/internal/git_lfs_probe.py index cde509af7119..f0a4dfd4117a 100755 --- a/misc/bazel/internal/git_lfs_probe.py +++ b/misc/bazel/internal/git_lfs_probe.py @@ -82,18 +82,22 @@ def get_endpoint(): # see https://github.com/git-lfs/git-lfs/blob/310d1b4a7d01e8d9d884447df4635c7a9c7642c2/docs/api/basic-transfers.md def get_locations(objects): + ret = ["local" for _ in objects] endpoint = get_endpoint() indexes = [i for i, o in enumerate(objects) if o] - ret = ["local" for _ in objects] + if not indexes: + # all objects are local, do not send an empty request as that would be an error + return ret + data = { + "operation": "download", + "transfers": ["basic"], + "objects": [objects[i] for i in indexes], + "hash_algo": "sha256", + } req = urllib.request.Request( f"{endpoint.href}/objects/batch", headers=endpoint.headers, - data=json.dumps({ - "operation": "download", - "transfers": ["basic"], - "objects": [o for o in objects if o], - "hash_algo": "sha256", - }).encode("ascii"), + data=json.dumps(data).encode("ascii"), ) with urllib.request.urlopen(req) as resp: data = json.load(resp) From a8549d2e233938c043fdd9632f4d013ce8ec2165 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 6 May 2024 13:56:36 +0200 Subject: [PATCH 222/238] Java: Convert remaining tests to inline flow tests. --- .../dataflow/CaptureNeutralModels.expected | 27 +----------- .../dataflow/CaptureNeutralModels.ql | 11 +++++ .../dataflow/CaptureNeutralModels.qlref | 1 - .../dataflow/CaptureSinkModels.expected | 7 +-- .../dataflow/CaptureSinkModels.ql | 11 +++++ .../dataflow/CaptureSinkModels.qlref | 1 - .../dataflow/CaptureSourceModels.expected | 7 +-- .../dataflow/CaptureSourceModels.ql | 11 +++++ .../dataflow/CaptureSourceModels.qlref | 1 - ...expected => CaptureSummaryModels.expected} | 0 ...ptureModels.ql => CaptureSummaryModels.ql} | 0 .../modelgenerator/dataflow/p/Factory.java | 1 + .../modelgenerator/dataflow/p/FinalClass.java | 1 + .../modelgenerator/dataflow/p/FluentAPI.java | 1 + .../dataflow/p/ImmutablePojo.java | 1 + .../modelgenerator/dataflow/p/Joiner.java | 1 + .../modelgenerator/dataflow/p/ParamFlow.java | 2 + .../utils/modelgenerator/dataflow/p/Pojo.java | 9 ++++ .../p/PrivateFlowViaPublicInterface.java | 3 ++ .../modelgenerator/dataflow/p/Sinks.java | 41 ++++++++++------- .../modelgenerator/dataflow/p/Sources.java | 44 +++++++++++-------- 21 files changed, 108 insertions(+), 73 deletions(-) create mode 100644 java/ql/test/utils/modelgenerator/dataflow/CaptureNeutralModels.ql delete mode 100644 java/ql/test/utils/modelgenerator/dataflow/CaptureNeutralModels.qlref create mode 100644 java/ql/test/utils/modelgenerator/dataflow/CaptureSinkModels.ql delete mode 100644 java/ql/test/utils/modelgenerator/dataflow/CaptureSinkModels.qlref create mode 100644 java/ql/test/utils/modelgenerator/dataflow/CaptureSourceModels.ql delete mode 100644 java/ql/test/utils/modelgenerator/dataflow/CaptureSourceModels.qlref rename java/ql/test/utils/modelgenerator/dataflow/{CaptureModels.expected => CaptureSummaryModels.expected} (100%) rename java/ql/test/utils/modelgenerator/dataflow/{CaptureModels.ql => CaptureSummaryModels.ql} (100%) diff --git a/java/ql/test/utils/modelgenerator/dataflow/CaptureNeutralModels.expected b/java/ql/test/utils/modelgenerator/dataflow/CaptureNeutralModels.expected index df6a7bfc8544..cb6fc390349c 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/CaptureNeutralModels.expected +++ b/java/ql/test/utils/modelgenerator/dataflow/CaptureNeutralModels.expected @@ -1,25 +1,2 @@ -| p;Factory;getIntValue;();summary;df-generated | -| p;FinalClass;returnsConstant;();summary;df-generated | -| p;FluentAPI$Inner;notThis;(String);summary;df-generated | -| p;ImmutablePojo;getX;();summary;df-generated | -| p;Joiner;length;();summary;df-generated | -| p;ParamFlow;ignorePrimitiveReturnValue;(String);summary;df-generated | -| p;ParamFlow;mapType;(Class);summary;df-generated | -| p;Pojo;doNotSetValue;(String);summary;df-generated | -| p;Pojo;getBigDecimal;();summary;df-generated | -| p;Pojo;getBigInt;();summary;df-generated | -| p;Pojo;getBoxedArray;();summary;df-generated | -| p;Pojo;getBoxedCollection;();summary;df-generated | -| p;Pojo;getBoxedValue;();summary;df-generated | -| p;Pojo;getFloatArray;();summary;df-generated | -| p;Pojo;getIntValue;();summary;df-generated | -| p;Pojo;getPrimitiveArray;();summary;df-generated | -| p;PrivateFlowViaPublicInterface$SPI;openStreamNone;();summary;df-generated | -| p;PrivateFlowViaPublicInterface;createAnSPIWithoutTrackingFile;(File);summary;df-generated | -| p;Sinks;copyFileToDirectory;(Path,Path,CopyOption[]);summary;df-generated | -| p;Sinks;propagate;(String);summary;df-generated | -| p;Sinks;readUrl;(URL,Charset);summary;df-generated | -| p;Sources;readUrl;(URL);summary;df-generated | -| p;Sources;socketStream;();summary;df-generated | -| p;Sources;sourceToParameter;(InputStream[],List);summary;df-generated | -| p;Sources;wrappedSocketStream;();summary;df-generated | +unexpectedModel +expectedModel diff --git a/java/ql/test/utils/modelgenerator/dataflow/CaptureNeutralModels.ql b/java/ql/test/utils/modelgenerator/dataflow/CaptureNeutralModels.ql new file mode 100644 index 000000000000..50bc36fe4ebd --- /dev/null +++ b/java/ql/test/utils/modelgenerator/dataflow/CaptureNeutralModels.ql @@ -0,0 +1,11 @@ +import java +import utils.modelgenerator.internal.CaptureSummaryFlowQuery +import TestUtilities.InlineMadTest + +module InlineMadTestConfig implements InlineMadTestConfigSig { + string getCapturedModel() { result = captureNoFlow(_) } + + string getKind() { result = "neutral" } +} + +import InlineMadTest diff --git a/java/ql/test/utils/modelgenerator/dataflow/CaptureNeutralModels.qlref b/java/ql/test/utils/modelgenerator/dataflow/CaptureNeutralModels.qlref deleted file mode 100644 index 851ddc0d2946..000000000000 --- a/java/ql/test/utils/modelgenerator/dataflow/CaptureNeutralModels.qlref +++ /dev/null @@ -1 +0,0 @@ -utils/modelgenerator/CaptureNeutralModels.ql \ No newline at end of file diff --git a/java/ql/test/utils/modelgenerator/dataflow/CaptureSinkModels.expected b/java/ql/test/utils/modelgenerator/dataflow/CaptureSinkModels.expected index 799a1a37dd45..cb6fc390349c 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/CaptureSinkModels.expected +++ b/java/ql/test/utils/modelgenerator/dataflow/CaptureSinkModels.expected @@ -1,5 +1,2 @@ -| p;PrivateFlowViaPublicInterface$SPI;true;openStream;();;Argument[this];path-injection;df-generated | -| p;Sinks;true;copyFileToDirectory;(Path,Path,CopyOption[]);;Argument[0];path-injection;df-generated | -| p;Sinks;true;copyFileToDirectory;(Path,Path,CopyOption[]);;Argument[1];path-injection;df-generated | -| p;Sinks;true;readUrl;(URL,Charset);;Argument[0];request-forgery;df-generated | -| p;Sources;true;readUrl;(URL);;Argument[0];request-forgery;df-generated | +unexpectedModel +expectedModel diff --git a/java/ql/test/utils/modelgenerator/dataflow/CaptureSinkModels.ql b/java/ql/test/utils/modelgenerator/dataflow/CaptureSinkModels.ql new file mode 100644 index 000000000000..2bf1c378f2ac --- /dev/null +++ b/java/ql/test/utils/modelgenerator/dataflow/CaptureSinkModels.ql @@ -0,0 +1,11 @@ +import java +import utils.modelgenerator.internal.CaptureModels +import TestUtilities.InlineMadTest + +module InlineMadTestConfig implements InlineMadTestConfigSig { + string getCapturedModel() { result = captureSink(_) } + + string getKind() { result = "sink" } +} + +import InlineMadTest diff --git a/java/ql/test/utils/modelgenerator/dataflow/CaptureSinkModels.qlref b/java/ql/test/utils/modelgenerator/dataflow/CaptureSinkModels.qlref deleted file mode 100644 index 36d2f144247f..000000000000 --- a/java/ql/test/utils/modelgenerator/dataflow/CaptureSinkModels.qlref +++ /dev/null @@ -1 +0,0 @@ -utils/modelgenerator/CaptureSinkModels.ql \ No newline at end of file diff --git a/java/ql/test/utils/modelgenerator/dataflow/CaptureSourceModels.expected b/java/ql/test/utils/modelgenerator/dataflow/CaptureSourceModels.expected index 0f8d0ff1f32a..cb6fc390349c 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/CaptureSourceModels.expected +++ b/java/ql/test/utils/modelgenerator/dataflow/CaptureSourceModels.expected @@ -1,5 +1,2 @@ -| p;Sources;true;readUrl;(URL);;ReturnValue;remote;df-generated | -| p;Sources;true;socketStream;();;ReturnValue;remote;df-generated | -| p;Sources;true;sourceToParameter;(InputStream[],List);;Argument[0].ArrayElement;remote;df-generated | -| p;Sources;true;sourceToParameter;(InputStream[],List);;Argument[1].Element;remote;df-generated | -| p;Sources;true;wrappedSocketStream;();;ReturnValue;remote;df-generated | +unexpectedModel +expectedModel diff --git a/java/ql/test/utils/modelgenerator/dataflow/CaptureSourceModels.ql b/java/ql/test/utils/modelgenerator/dataflow/CaptureSourceModels.ql new file mode 100644 index 000000000000..e628bd19eb47 --- /dev/null +++ b/java/ql/test/utils/modelgenerator/dataflow/CaptureSourceModels.ql @@ -0,0 +1,11 @@ +import java +import utils.modelgenerator.internal.CaptureModels +import TestUtilities.InlineMadTest + +module InlineMadTestConfig implements InlineMadTestConfigSig { + string getCapturedModel() { result = captureSource(_) } + + string getKind() { result = "source" } +} + +import InlineMadTest diff --git a/java/ql/test/utils/modelgenerator/dataflow/CaptureSourceModels.qlref b/java/ql/test/utils/modelgenerator/dataflow/CaptureSourceModels.qlref deleted file mode 100644 index 6bbb499fc27b..000000000000 --- a/java/ql/test/utils/modelgenerator/dataflow/CaptureSourceModels.qlref +++ /dev/null @@ -1 +0,0 @@ -utils/modelgenerator/CaptureSourceModels.ql \ No newline at end of file diff --git a/java/ql/test/utils/modelgenerator/dataflow/CaptureModels.expected b/java/ql/test/utils/modelgenerator/dataflow/CaptureSummaryModels.expected similarity index 100% rename from java/ql/test/utils/modelgenerator/dataflow/CaptureModels.expected rename to java/ql/test/utils/modelgenerator/dataflow/CaptureSummaryModels.expected diff --git a/java/ql/test/utils/modelgenerator/dataflow/CaptureModels.ql b/java/ql/test/utils/modelgenerator/dataflow/CaptureSummaryModels.ql similarity index 100% rename from java/ql/test/utils/modelgenerator/dataflow/CaptureModels.ql rename to java/ql/test/utils/modelgenerator/dataflow/CaptureSummaryModels.ql diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/Factory.java b/java/ql/test/utils/modelgenerator/dataflow/p/Factory.java index 57d26429a936..1887e0ca73e2 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/Factory.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/Factory.java @@ -26,6 +26,7 @@ public String getValue() { return value; } + // neutral=p;Factory;getIntValue;();summary;df-generated public int getIntValue() { return intValue; } diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/FinalClass.java b/java/ql/test/utils/modelgenerator/dataflow/p/FinalClass.java index 82a39533ce14..2638f818854f 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/FinalClass.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/FinalClass.java @@ -9,6 +9,7 @@ public String returnsInput(String input) { return input; } + // neutral=p;FinalClass;returnsConstant;();summary;df-generated public String returnsConstant() { return C; } diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/FluentAPI.java b/java/ql/test/utils/modelgenerator/dataflow/p/FluentAPI.java index 38fbb286bb01..b7793e30666a 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/FluentAPI.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/FluentAPI.java @@ -8,6 +8,7 @@ public FluentAPI returnsThis(String input) { } public class Inner { + // neutral=p;FluentAPI$Inner;notThis;(String);summary;df-generated public FluentAPI notThis(String input) { return FluentAPI.this; } diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/ImmutablePojo.java b/java/ql/test/utils/modelgenerator/dataflow/p/ImmutablePojo.java index 1b39856b445b..0a2cf2d7dbd3 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/ImmutablePojo.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/ImmutablePojo.java @@ -17,6 +17,7 @@ public String getValue() { return value; } + // neutral=p;ImmutablePojo;getX;();summary;df-generated public long getX() { return x; } diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/Joiner.java b/java/ql/test/utils/modelgenerator/dataflow/p/Joiner.java index 60edb0fb71e1..10fc72c907f2 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/Joiner.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/Joiner.java @@ -117,6 +117,7 @@ private void compactElts() { } } + // neutral=p;Joiner;length;();summary;df-generated public int length() { return (size == 0 && emptyValue != null) ? emptyValue.length() diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/ParamFlow.java b/java/ql/test/utils/modelgenerator/dataflow/p/ParamFlow.java index 5c47e292a6b6..d175ee9c71e6 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/ParamFlow.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/ParamFlow.java @@ -12,6 +12,7 @@ public String returnsInput(String input) { return input; } + // neutral=p;ParamFlow;ignorePrimitiveReturnValue;(String);summary;df-generated public int ignorePrimitiveReturnValue(String input) { return input.length(); } @@ -50,6 +51,7 @@ public String returnIterableElement(Iterable input) { return input.iterator().next(); } + // neutral=p;ParamFlow;mapType;(Class);summary;df-generated public Class mapType(Class input) { return input; } diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/Pojo.java b/java/ql/test/utils/modelgenerator/dataflow/p/Pojo.java index 524e448ef815..9d5de0517e1e 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/Pojo.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/Pojo.java @@ -40,19 +40,23 @@ public void setValue(String value) { this.value = value; } + // neutral=p;Pojo;doNotSetValue;(String);summary;df-generated public int doNotSetValue(String value) { Holder h = new Holder(value); return h.length(); } + // neutral=p;Pojo;getIntValue;();summary;df-generated public int getIntValue() { return intValue; } + // neutral=p;Pojo;getBoxedValue;();summary;df-generated public Integer getBoxedValue() { return Integer.valueOf(intValue); } + // neutral=p;Pojo;getPrimitiveArray;();summary;df-generated public int[] getPrimitiveArray() { return new int[] {intValue}; } @@ -67,14 +71,17 @@ public byte[] getByteArray() { return byteArray; } + // neutral=p;Pojo;getFloatArray;();summary;df-generated public float[] getFloatArray() { return floatArray; } + // neutral=p;Pojo;getBoxedArray;();summary;df-generated public Integer[] getBoxedArray() { return new Integer[] {Integer.valueOf(intValue)}; } + // neutral=p;Pojo;getBoxedCollection;();summary;df-generated public Collection getBoxedCollection() { return List.of(Integer.valueOf(intValue)); } @@ -89,10 +96,12 @@ public Byte[] getBoxedBytes() { return byteObjectArray; } + // neutral=p;Pojo;getBigInt;();summary;df-generated public BigInteger getBigInt() { return BigInteger.valueOf(intValue); } + // neutral=p;Pojo;getBigDecimal;();summary;df-generated public BigDecimal getBigDecimal() { return new BigDecimal(value); } diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/PrivateFlowViaPublicInterface.java b/java/ql/test/utils/modelgenerator/dataflow/p/PrivateFlowViaPublicInterface.java index 6b5dbca3e114..753648872741 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/PrivateFlowViaPublicInterface.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/PrivateFlowViaPublicInterface.java @@ -13,8 +13,10 @@ static class RandomPojo { public static interface SPI { // summary=p;PrivateFlowViaPublicInterface$SPI;true;openStream;();;Argument[this];ReturnValue;taint;df-generated + // sink=p;PrivateFlowViaPublicInterface$SPI;true;openStream;();;Argument[this];path-injection;df-generated OutputStream openStream() throws IOException; + // neutral=p;PrivateFlowViaPublicInterface$SPI;openStreamNone;();summary;df-generated default OutputStream openStreamNone() throws IOException { return null; } @@ -55,6 +57,7 @@ public static SPI createAnSPI(File file) { return new PrivateImplWithSink(file); } + // neutral=p;PrivateFlowViaPublicInterface;createAnSPIWithoutTrackingFile;(File);summary;df-generated public static SPI createAnSPIWithoutTrackingFile(File file) { return new PrivateImplWithRandomField(file); } diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/Sinks.java b/java/ql/test/utils/modelgenerator/dataflow/p/Sinks.java index 260f235920a5..e9868b260730 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/Sinks.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/Sinks.java @@ -3,32 +3,39 @@ import java.io.IOException; import java.io.InputStream; import java.net.URL; -import java.nio.file.CopyOption; import java.nio.charset.Charset; +import java.nio.file.CopyOption; import java.nio.file.Files; import java.nio.file.Path; import java.util.logging.Logger; public class Sinks { - - public Path copyFileToDirectory(final Path sourceFile, final Path targetFile, final CopyOption... copyOptions) throws IOException { - return Files.copy(sourceFile, targetFile, copyOptions); - } - public String readUrl(final URL url, Charset encoding) throws IOException { - try (InputStream in = url.openStream()) { - byte[] bytes = in.readAllBytes(); - return new String(bytes, encoding); - } - } + // sink=p;Sinks;true;copyFileToDirectory;(Path,Path,CopyOption[]);;Argument[0];path-injection;df-generated + // sink=p;Sinks;true;copyFileToDirectory;(Path,Path,CopyOption[]);;Argument[1];path-injection;df-generated + // neutral=p;Sinks;copyFileToDirectory;(Path,Path,CopyOption[]);summary;df-generated + public Path copyFileToDirectory( + final Path sourceFile, final Path targetFile, final CopyOption... copyOptions) + throws IOException { + return Files.copy(sourceFile, targetFile, copyOptions); + } - public static void main(String[] args) throws IOException { - String foo = new Sinks().readUrl(new URL(args[0]), Charset.defaultCharset()); + // sink=p;Sinks;true;readUrl;(URL,Charset);;Argument[0];request-forgery;df-generated + // neutral=p;Sinks;readUrl;(URL,Charset);summary;df-generated + public String readUrl(final URL url, Charset encoding) throws IOException { + try (InputStream in = url.openStream()) { + byte[] bytes = in.readAllBytes(); + return new String(bytes, encoding); } + } - public void propagate(String s) { - Logger logger = Logger.getLogger(Sinks.class.getSimpleName()); - logger.warning(s); - } + public static void main(String[] args) throws IOException { + String foo = new Sinks().readUrl(new URL(args[0]), Charset.defaultCharset()); + } + // neutral=p;Sinks;propagate;(String);summary;df-generated + public void propagate(String s) { + Logger logger = Logger.getLogger(Sinks.class.getSimpleName()); + logger.warning(s); + } } diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/Sources.java b/java/ql/test/utils/modelgenerator/dataflow/p/Sources.java index 7b008ff378f2..436bf16797c7 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/Sources.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/Sources.java @@ -4,29 +4,37 @@ import java.io.InputStream; import java.net.ServerSocket; import java.net.URL; -import java.util.function.Consumer; import java.util.List; - public class Sources { - - public InputStream readUrl(final URL url) throws IOException { - return url.openConnection().getInputStream(); - } - public InputStream socketStream() throws IOException { - ServerSocket socket = new ServerSocket(123); - return socket.accept().getInputStream(); - } + // source=p;Sources;true;readUrl;(URL);;ReturnValue;remote;df-generated + // sink=p;Sources;true;readUrl;(URL);;Argument[0];request-forgery;df-generated + // neutral=p;Sources;readUrl;(URL);summary;df-generated + public InputStream readUrl(final URL url) throws IOException { + return url.openConnection().getInputStream(); + } - public InputStream wrappedSocketStream() throws IOException { - return socketStream(); - } + // source=p;Sources;true;socketStream;();;ReturnValue;remote;df-generated + // neutral=p;Sources;socketStream;();summary;df-generated + public InputStream socketStream() throws IOException { + ServerSocket socket = new ServerSocket(123); + return socket.accept().getInputStream(); + } - public void sourceToParameter(InputStream[] streams, List otherStreams) throws IOException { - ServerSocket socket = new ServerSocket(123); - streams[0] = socket.accept().getInputStream(); - otherStreams.add(socket.accept().getInputStream()); - } + // source=p;Sources;true;wrappedSocketStream;();;ReturnValue;remote;df-generated + // neutral=p;Sources;wrappedSocketStream;();summary;df-generated + public InputStream wrappedSocketStream() throws IOException { + return socketStream(); + } + // source=p;Sources;true;sourceToParameter;(InputStream[],List);;Argument[0].ArrayElement;remote;df-generated + // source=p;Sources;true;sourceToParameter;(InputStream[],List);;Argument[1].Element;remote;df-generated + // neutral=p;Sources;sourceToParameter;(InputStream[],List);summary;df-generated + public void sourceToParameter(InputStream[] streams, List otherStreams) + throws IOException { + ServerSocket socket = new ServerSocket(123); + streams[0] = socket.accept().getInputStream(); + otherStreams.add(socket.accept().getInputStream()); + } } From 92b3eda12d7605283a5616ec6b9e9a2681f221e5 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Mon, 6 May 2024 16:00:05 +0200 Subject: [PATCH 223/238] Bazel: move buildifier out of root `BUILD` See https://github.com/github/codeql/pull/16428 for details as to why this is necessary. --- .github/workflows/buildifier.yml | 2 +- .pre-commit-config.yaml | 2 +- BUILD.bazel | 9 --------- misc/bazel/BUILD.bazel | 9 +++++++++ 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/buildifier.yml b/.github/workflows/buildifier.yml index 82444d0440af..b5d1e2244d5c 100644 --- a/.github/workflows/buildifier.yml +++ b/.github/workflows/buildifier.yml @@ -24,5 +24,5 @@ jobs: extra_args: > buildifier --all-files 2>&1 || ( - echo -e "In order to format all bazel files, please run:\n bazel run //:buildifier"; exit 1 + echo -e "In order to format all bazel files, please run:\n bazel run //misc/bazel:buildifier"; exit 1 ) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7fddd1929d4f..00c34e5df06e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -26,7 +26,7 @@ repos: name: Format bazel files files: \.(bazel|bzl) language: system - entry: bazel run //:buildifier + entry: bazel run //misc/bazel:buildifier pass_filenames: false - id: codeql-format diff --git a/BUILD.bazel b/BUILD.bazel index 3ccdcda5f129..e69de29bb2d1 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -1,9 +0,0 @@ -load("@buildifier_prebuilt//:rules.bzl", "buildifier") - -buildifier( - name = "buildifier", - exclude_patterns = [ - "./.git/*", - ], - lint_mode = "fix", -) diff --git a/misc/bazel/BUILD.bazel b/misc/bazel/BUILD.bazel index e69de29bb2d1..3ccdcda5f129 100644 --- a/misc/bazel/BUILD.bazel +++ b/misc/bazel/BUILD.bazel @@ -0,0 +1,9 @@ +load("@buildifier_prebuilt//:rules.bzl", "buildifier") + +buildifier( + name = "buildifier", + exclude_patterns = [ + "./.git/*", + ], + lint_mode = "fix", +) From b53fa0f7f36db827d831fe13c0628e856d179f44 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 6 May 2024 16:32:28 +0200 Subject: [PATCH 224/238] Java: Ensure that it is the callable for the model origin that carries the comment containing the model. --- java/ql/test/TestUtilities/InlineMadTest.qll | 34 +++++++++++-------- .../dataflow/CaptureNeutralModels.ql | 2 +- .../dataflow/CaptureSinkModels.ql | 2 +- .../dataflow/CaptureSourceModels.ql | 2 +- .../dataflow/CaptureSummaryModels.ql | 2 +- .../dataflow/p/MultipleImpl2.java | 2 +- .../dataflow/p/MultipleImpls.java | 4 +-- .../p/PrivateFlowViaPublicInterface.java | 6 ++-- .../CaptureTypeBasedSummaryModels.ql | 2 +- 9 files changed, 31 insertions(+), 25 deletions(-) diff --git a/java/ql/test/TestUtilities/InlineMadTest.qll b/java/ql/test/TestUtilities/InlineMadTest.qll index a5602036a8cb..31206a6338c4 100644 --- a/java/ql/test/TestUtilities/InlineMadTest.qll +++ b/java/ql/test/TestUtilities/InlineMadTest.qll @@ -2,47 +2,53 @@ import java private signature module InlineMadTestLangSig { /** - * Gets a relevant code comment, if any. + * Gets a relevant code comment for `c`, if any. */ - string getComment(); + string getComment(Callable c); } signature module InlineMadTestConfigSig { /** - * Gets the kind of the captured model. + * Gets the kind of a captured model. */ string getKind(); /** - * Gets a captured model, if any. + * Gets a captured model for `c`, if any. */ - string getCapturedModel(); + string getCapturedModel(Callable c); } private module InlineMadTestImpl { - private string expects() { - Lang::getComment().regexpCapture(" *(SPURIOUS-)?" + Input::getKind() + "=(.*)", 2) = result + private string expects(Callable c) { + Lang::getComment(c).regexpCapture(" *(SPURIOUS-)?" + Input::getKind() + "=(.*)", 2) = result } query predicate unexpectedModel(string msg) { - exists(string flow | - flow = Input::getCapturedModel() and - not flow = expects() and + exists(Callable c, string flow | + flow = Input::getCapturedModel(c) and + not flow = expects(c) and msg = "Unexpected " + Input::getKind() + " found: " + flow ) } query predicate expectedModel(string msg) { - exists(string e | - e = expects() and - not e = Input::getCapturedModel() and + exists(Callable c, string e | + e = expects(c) and + not e = Input::getCapturedModel(c) and msg = "Expected " + Input::getKind() + " missing: " + e ) } } private module InlineMadTestLang implements InlineMadTestLangSig { - string getComment() { result = any(Javadoc doc).getChild(0).toString() } + string getComment(Callable c) { + exists(Javadoc doc | + hasJavadoc(c, doc) and + isNormalComment(doc) and + result = doc.getChild(0).toString() + ) + } } module InlineMadTest { diff --git a/java/ql/test/utils/modelgenerator/dataflow/CaptureNeutralModels.ql b/java/ql/test/utils/modelgenerator/dataflow/CaptureNeutralModels.ql index 50bc36fe4ebd..e68730cc0edd 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/CaptureNeutralModels.ql +++ b/java/ql/test/utils/modelgenerator/dataflow/CaptureNeutralModels.ql @@ -3,7 +3,7 @@ import utils.modelgenerator.internal.CaptureSummaryFlowQuery import TestUtilities.InlineMadTest module InlineMadTestConfig implements InlineMadTestConfigSig { - string getCapturedModel() { result = captureNoFlow(_) } + string getCapturedModel(Callable c) { result = captureNoFlow(c) } string getKind() { result = "neutral" } } diff --git a/java/ql/test/utils/modelgenerator/dataflow/CaptureSinkModels.ql b/java/ql/test/utils/modelgenerator/dataflow/CaptureSinkModels.ql index 2bf1c378f2ac..1acde2ade49d 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/CaptureSinkModels.ql +++ b/java/ql/test/utils/modelgenerator/dataflow/CaptureSinkModels.ql @@ -3,7 +3,7 @@ import utils.modelgenerator.internal.CaptureModels import TestUtilities.InlineMadTest module InlineMadTestConfig implements InlineMadTestConfigSig { - string getCapturedModel() { result = captureSink(_) } + string getCapturedModel(Callable c) { result = captureSink(c) } string getKind() { result = "sink" } } diff --git a/java/ql/test/utils/modelgenerator/dataflow/CaptureSourceModels.ql b/java/ql/test/utils/modelgenerator/dataflow/CaptureSourceModels.ql index e628bd19eb47..7596f4f8cc14 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/CaptureSourceModels.ql +++ b/java/ql/test/utils/modelgenerator/dataflow/CaptureSourceModels.ql @@ -3,7 +3,7 @@ import utils.modelgenerator.internal.CaptureModels import TestUtilities.InlineMadTest module InlineMadTestConfig implements InlineMadTestConfigSig { - string getCapturedModel() { result = captureSource(_) } + string getCapturedModel(Callable c) { result = captureSource(c) } string getKind() { result = "source" } } diff --git a/java/ql/test/utils/modelgenerator/dataflow/CaptureSummaryModels.ql b/java/ql/test/utils/modelgenerator/dataflow/CaptureSummaryModels.ql index 821e8e8f0e71..415ebab13439 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/CaptureSummaryModels.ql +++ b/java/ql/test/utils/modelgenerator/dataflow/CaptureSummaryModels.ql @@ -3,7 +3,7 @@ import utils.modelgenerator.internal.CaptureSummaryFlowQuery import TestUtilities.InlineMadTest module InlineMadTestConfig implements InlineMadTestConfigSig { - string getCapturedModel() { result = captureFlow(_) } + string getCapturedModel(Callable c) { result = captureFlow(c) } string getKind() { result = "summary" } } diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpl2.java b/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpl2.java index dc67d0dfe6cc..3e5d9abd7687 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpl2.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpl2.java @@ -6,7 +6,6 @@ class MultipleImpl2 { // This is used to test that we only generate a summary model and // not neutral summary model for `IInterface.m`. public interface IInterface { - // summary=p;MultipleImpl2$IInterface;true;m;(Object);;Argument[0];ReturnValue;taint;df-generated Object m(Object value); } @@ -17,6 +16,7 @@ public Object m(Object value) { } public class Impl2 implements IInterface { + // summary=p;MultipleImpl2$IInterface;true;m;(Object);;Argument[0];ReturnValue;taint;df-generated public Object m(Object value) { return value; } diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpls.java b/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpls.java index 8fccdf76ab71..d2b4ac133b57 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpls.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpls.java @@ -5,12 +5,11 @@ public class MultipleImpls { public static interface Strategy { - // summary=p;MultipleImpls$Strategy;true;doSomething;(String);;Argument[0];Argument[this];taint;df-generated - // summary=p;MultipleImpls$Strategy;true;doSomething;(String);;Argument[0];ReturnValue;taint;df-generated String doSomething(String value); } public static class Strat1 implements Strategy { + // summary=p;MultipleImpls$Strategy;true;doSomething;(String);;Argument[0];ReturnValue;taint;df-generated public String doSomething(String value) { return value; } @@ -28,6 +27,7 @@ public String call() throws Exception { public static class Strat2 implements Strategy { private String foo; + // summary=p;MultipleImpls$Strategy;true;doSomething;(String);;Argument[0];Argument[this];taint;df-generated public String doSomething(String value) { this.foo = value; return "none"; diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/PrivateFlowViaPublicInterface.java b/java/ql/test/utils/modelgenerator/dataflow/p/PrivateFlowViaPublicInterface.java index 753648872741..25c62172121a 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/PrivateFlowViaPublicInterface.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/PrivateFlowViaPublicInterface.java @@ -12,15 +12,12 @@ static class RandomPojo { } public static interface SPI { - // summary=p;PrivateFlowViaPublicInterface$SPI;true;openStream;();;Argument[this];ReturnValue;taint;df-generated - // sink=p;PrivateFlowViaPublicInterface$SPI;true;openStream;();;Argument[this];path-injection;df-generated OutputStream openStream() throws IOException; // neutral=p;PrivateFlowViaPublicInterface$SPI;openStreamNone;();summary;df-generated default OutputStream openStreamNone() throws IOException { return null; } - ; } private static final class PrivateImplWithSink implements SPI { @@ -31,6 +28,8 @@ public PrivateImplWithSink(File file) { this.file = file; } + // summary=p;PrivateFlowViaPublicInterface$SPI;true;openStream;();;Argument[this];ReturnValue;taint;df-generated + // sink=p;PrivateFlowViaPublicInterface$SPI;true;openStream;();;Argument[this];path-injection;df-generated @Override public OutputStream openStream() throws IOException { return new FileOutputStream(file); @@ -46,6 +45,7 @@ public OutputStream openStream() throws IOException { return null; } + // neutral=p;PrivateFlowViaPublicInterface$SPI;openStreamNone;();summary;df-generated @Override public OutputStream openStreamNone() throws IOException { return new FileOutputStream(new RandomPojo().someFile); diff --git a/java/ql/test/utils/modelgenerator/typebasedflow/CaptureTypeBasedSummaryModels.ql b/java/ql/test/utils/modelgenerator/typebasedflow/CaptureTypeBasedSummaryModels.ql index e3b64cca7852..2bf4e08d2c17 100644 --- a/java/ql/test/utils/modelgenerator/typebasedflow/CaptureTypeBasedSummaryModels.ql +++ b/java/ql/test/utils/modelgenerator/typebasedflow/CaptureTypeBasedSummaryModels.ql @@ -3,7 +3,7 @@ import TestUtilities.InlineMadTest import utils.modelgenerator.internal.CaptureTypeBasedSummaryModels module InlineMadTestConfig implements InlineMadTestConfigSig { - string getCapturedModel() { result = captureFlow(_) } + string getCapturedModel(Callable c) { result = captureFlow(c) } string getKind() { result = "summary" } } From 757cf8d43a2f2389557b4cf9f419e7a282c5e807 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 6 May 2024 14:26:30 +0200 Subject: [PATCH 225/238] C#: Fix a comment typo. --- .../semmle/code/csharp/security/dataflow/flowsinks/ApiSinks.qll | 2 +- .../code/csharp/security/dataflow/flowsources/ApiSources.qll | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/ApiSinks.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/ApiSinks.qll index 7a069adb2ed8..15c64b45ca08 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/ApiSinks.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/ApiSinks.qll @@ -10,7 +10,7 @@ final class SinkNode = ApiSinkNode; /** * Module that adds all API like sinks to `SinkNode`, excluding sinks for cryptography based - * queries, and queries where sinks are not succifiently defined (eg. using broad method name matching). + * queries, and queries where sinks are not sufficiently defined (eg. using broad method name matching). */ private module AllApiSinks { private import ParallelSink diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/ApiSources.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/ApiSources.qll index 01d838f2f94d..2aa451831aaf 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/ApiSources.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/ApiSources.qll @@ -6,7 +6,7 @@ final class SourceNode = FlowSources::SourceNode; /** * Module that adds all API like sources to `SourceNode`, excluding some sources for cryptography based - * queries, and queries where sources are not succifiently defined (eg. using broad method name matching). + * queries, and queries where sources are not sufficiently defined (eg. using broad method name matching). */ private module AllApiSources { private import semmle.code.csharp.security.dataflow.ConditionalBypassQuery as ConditionalBypassQuery From 9b23635d0af2e31c113e2a2c93849838fb60826a Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Mon, 6 May 2024 17:47:55 +0200 Subject: [PATCH 226/238] C++: Add test case that shows that no destructors are attached to unwinds --- .../library-tests/ir/ir/PrintAST.expected | 35 +++++++++++ .../library-tests/ir/ir/aliased_ir.expected | 58 +++++++++++++++++++ cpp/ql/test/library-tests/ir/ir/ir.cpp | 9 +++ .../test/library-tests/ir/ir/raw_ir.expected | 50 ++++++++++++++++ 4 files changed, 152 insertions(+) diff --git a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected index cf5125b1ccf2..811502f047e5 100644 --- a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected +++ b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected @@ -22605,6 +22605,41 @@ ir.cpp: # 2530| ValueCategory = lvalue # 2530| getStmt(1): [LabelStmt] label ...: # 2531| getStmt(2): [ReturnStmt] return ... +# 2533| [TopLevelFunction] void destructor_possibly_not_handled() +# 2533| : +# 2533| getEntryPoint(): [BlockStmt] { ... } +# 2534| getStmt(0): [DeclStmt] declaration +# 2534| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x +# 2534| Type = [Class] ClassWithDestructor +# 2534| getVariable().getInitializer(): [Initializer] initializer for x +# 2534| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2534| Type = [VoidType] void +# 2534| ValueCategory = prvalue +# 2535| getStmt(1): [TryStmt] try { ... } +# 2535| getStmt(): [BlockStmt] { ... } +# 2536| getStmt(0): [ExprStmt] ExprStmt +# 2536| getExpr(): [ThrowExpr] throw ... +# 2536| Type = [IntType] int +# 2536| ValueCategory = prvalue +# 2536| getExpr(): [Literal] 42 +# 2536| Type = [IntType] int +# 2536| Value = [Literal] 42 +# 2536| ValueCategory = prvalue +# 2538| getChild(1): [Handler] +# 2538| getBlock(): [CatchBlock] { ... } +# 2540| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2540| Type = [VoidType] void +# 2540| ValueCategory = prvalue +# 2540| getQualifier(): [VariableAccess] x +# 2540| Type = [Class] ClassWithDestructor +# 2540| ValueCategory = lvalue +# 2540| getStmt(2): [ReturnStmt] return ... +# 2540| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2540| Type = [VoidType] void +# 2540| ValueCategory = prvalue +# 2540| getQualifier(): [VariableAccess] x +# 2540| Type = [Class] ClassWithDestructor +# 2540| ValueCategory = lvalue perf-regression.cpp: # 4| [CopyAssignmentOperator] Big& Big::operator=(Big const&) # 4| : diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected index ae73ecd8f6ff..b8585f346a2f 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected @@ -18177,6 +18177,64 @@ ir.cpp: # 2521| v2521_8(void) = AliasedUse : ~m2530_17 # 2521| v2521_9(void) = ExitFunction : +# 2533| void destructor_possibly_not_handled() +# 2533| Block 0 +# 2533| v2533_1(void) = EnterFunction : +# 2533| m2533_2(unknown) = AliasedDefinition : +# 2533| m2533_3(unknown) = InitializeNonLocal : +# 2533| m2533_4(unknown) = Chi : total:m2533_2, partial:m2533_3 +# 2534| r2534_1(glval) = VariableAddress[x] : +# 2534| m2534_2(ClassWithDestructor) = Uninitialized[x] : &:r2534_1 +# 2534| r2534_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2534| v2534_4(void) = Call[ClassWithDestructor] : func:r2534_3, this:r2534_1 +# 2534| m2534_5(unknown) = ^CallSideEffect : ~m2533_4 +# 2534| m2534_6(unknown) = Chi : total:m2533_4, partial:m2534_5 +# 2534| m2534_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2534_1 +# 2534| m2534_8(ClassWithDestructor) = Chi : total:m2534_2, partial:m2534_7 +# 2536| r2536_1(glval) = VariableAddress[#throw2536:5] : +# 2536| r2536_2(int) = Constant[42] : +# 2536| m2536_3(int) = Store[#throw2536:5] : &:r2536_1, r2536_2 +# 2536| v2536_4(void) = ThrowValue : &:r2536_1, m2536_3 +#-----| Exception -> Block 3 + +# 2533| Block 1 +# 2533| m2533_5(unknown) = Phi : from 2:~m2534_6, from 4:~m2540_14 +# 2533| v2533_6(void) = AliasedUse : ~m2533_5 +# 2533| v2533_7(void) = ExitFunction : + +# 2533| Block 2 +# 2533| v2533_8(void) = Unwind : +#-----| Goto -> Block 1 + +# 2538| Block 3 +# 2538| v2538_1(void) = CatchByType[char] : +#-----| Exception -> Block 2 +#-----| Goto -> Block 4 + +# 2538| Block 4 +# 2538| r2538_2(glval) = VariableAddress[(unnamed parameter 0)] : +# 2538| m2538_3(char) = InitializeParameter[(unnamed parameter 0)] : &:r2538_2 +# 2538| v2538_4(void) = NoOp : +# 2540| r2540_1(glval) = VariableAddress[x] : +# 2540| r2540_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2540| v2540_3(void) = Call[~ClassWithDestructor] : func:r2540_2, this:r2540_1 +# 2540| m2540_4(unknown) = ^CallSideEffect : ~m2534_6 +# 2540| m2540_5(unknown) = Chi : total:m2534_6, partial:m2540_4 +# 2540| v2540_6(void) = ^IndirectReadSideEffect[-1] : &:r2540_1, m2534_8 +# 2540| m2540_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2540_1 +# 2540| m2540_8(ClassWithDestructor) = Chi : total:m2534_8, partial:m2540_7 +# 2540| v2540_9(void) = NoOp : +# 2540| r2540_10(glval) = VariableAddress[x] : +# 2540| r2540_11(glval) = FunctionAddress[~ClassWithDestructor] : +# 2540| v2540_12(void) = Call[~ClassWithDestructor] : func:r2540_11, this:r2540_10 +# 2540| m2540_13(unknown) = ^CallSideEffect : ~m2540_5 +# 2540| m2540_14(unknown) = Chi : total:m2540_5, partial:m2540_13 +# 2540| v2540_15(void) = ^IndirectReadSideEffect[-1] : &:r2540_10, m2540_8 +# 2540| m2540_16(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2540_10 +# 2540| m2540_17(ClassWithDestructor) = Chi : total:m2540_8, partial:m2540_16 +# 2533| v2533_9(void) = ReturnVoid : +#-----| Goto -> Block 1 + perf-regression.cpp: # 6| void Big::Big() # 6| Block 0 diff --git a/cpp/ql/test/library-tests/ir/ir/ir.cpp b/cpp/ql/test/library-tests/ir/ir/ir.cpp index e6c8b90ea5c8..35ea60715ccb 100644 --- a/cpp/ql/test/library-tests/ir/ir/ir.cpp +++ b/cpp/ql/test/library-tests/ir/ir/ir.cpp @@ -2530,4 +2530,13 @@ void destruction_in_switch_3(int c) { } } +void destructor_possibly_not_handled() { + ClassWithDestructor x; + try { + throw 42; + } + catch(char) { + } +} + // semmle-extractor-options: -std=c++20 --clang diff --git a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected index 71796c4c39e2..5693fc26f954 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -16553,6 +16553,56 @@ ir.cpp: # 2521| v2521_7(void) = AliasedUse : ~m? # 2521| v2521_8(void) = ExitFunction : +# 2533| void destructor_possibly_not_handled() +# 2533| Block 0 +# 2533| v2533_1(void) = EnterFunction : +# 2533| mu2533_2(unknown) = AliasedDefinition : +# 2533| mu2533_3(unknown) = InitializeNonLocal : +# 2534| r2534_1(glval) = VariableAddress[x] : +# 2534| mu2534_2(ClassWithDestructor) = Uninitialized[x] : &:r2534_1 +# 2534| r2534_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2534| v2534_4(void) = Call[ClassWithDestructor] : func:r2534_3, this:r2534_1 +# 2534| mu2534_5(unknown) = ^CallSideEffect : ~m? +# 2534| mu2534_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2534_1 +# 2536| r2536_1(glval) = VariableAddress[#throw2536:5] : +# 2536| r2536_2(int) = Constant[42] : +# 2536| mu2536_3(int) = Store[#throw2536:5] : &:r2536_1, r2536_2 +# 2536| v2536_4(void) = ThrowValue : &:r2536_1, ~m? +#-----| Exception -> Block 3 + +# 2533| Block 1 +# 2533| v2533_4(void) = AliasedUse : ~m? +# 2533| v2533_5(void) = ExitFunction : + +# 2533| Block 2 +# 2533| v2533_6(void) = Unwind : +#-----| Goto -> Block 1 + +# 2538| Block 3 +# 2538| v2538_1(void) = CatchByType[char] : +#-----| Exception -> Block 2 +#-----| Goto -> Block 4 + +# 2538| Block 4 +# 2538| r2538_2(glval) = VariableAddress[(unnamed parameter 0)] : +# 2538| mu2538_3(char) = InitializeParameter[(unnamed parameter 0)] : &:r2538_2 +# 2538| v2538_4(void) = NoOp : +# 2540| r2540_1(glval) = VariableAddress[x] : +# 2540| r2540_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2540| v2540_3(void) = Call[~ClassWithDestructor] : func:r2540_2, this:r2540_1 +# 2540| mu2540_4(unknown) = ^CallSideEffect : ~m? +# 2540| v2540_5(void) = ^IndirectReadSideEffect[-1] : &:r2540_1, ~m? +# 2540| mu2540_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2540_1 +# 2540| v2540_7(void) = NoOp : +# 2540| r2540_8(glval) = VariableAddress[x] : +# 2540| r2540_9(glval) = FunctionAddress[~ClassWithDestructor] : +# 2540| v2540_10(void) = Call[~ClassWithDestructor] : func:r2540_9, this:r2540_8 +# 2540| mu2540_11(unknown) = ^CallSideEffect : ~m? +# 2540| v2540_12(void) = ^IndirectReadSideEffect[-1] : &:r2540_8, ~m? +# 2540| mu2540_13(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2540_8 +# 2533| v2533_7(void) = ReturnVoid : +#-----| Goto -> Block 1 + perf-regression.cpp: # 6| void Big::Big() # 6| Block 0 From 07d51a55fdb1d44359c03070004bc4e6c5154fab Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Mon, 6 May 2024 18:49:28 +0100 Subject: [PATCH 227/238] C++: Assign a meaningful definition location to the address of an SSA variable when it's available. --- .../cpp/ir/dataflow/internal/SsaInternals.qll | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll index 924f68ef8076..e1512366c709 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll @@ -9,6 +9,7 @@ private import semmle.code.cpp.models.interfaces.PartialFlow as PartialFlow private import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs as FIO private import semmle.code.cpp.ir.internal.IRCppLanguage private import semmle.code.cpp.ir.dataflow.internal.ModelUtil +private import semmle.code.cpp.ir.implementation.raw.internal.TranslatedInitialization private import DataFlowPrivate import SsaInternalsCommon @@ -329,6 +330,17 @@ private predicate sourceVariableHasBaseAndIndex(SourceVariable v, BaseSourceVari v.getIndirection() = ind } +/** + * Gets the instruction that computes the address that's used to + * initialize `v`. + */ +private Instruction getInitializationTargetAddress(IRVariable v) { + exists(TranslatedVariableInitialization init | + init.getIRVariable() = v and + result = init.getTargetAddress() + ) +} + /** An initial definition of an `IRVariable`'s address. */ private class DefAddressImpl extends DefImpl, TDefAddressImpl { BaseIRVariable v; @@ -347,8 +359,15 @@ private class DefAddressImpl extends DefImpl, TDefAddressImpl { final override Node0Impl getValue() { none() } final override predicate hasIndexInBlock(IRBlock block, int index) { - block = v.getIRVariable().getEnclosingIRFunction().getEntryBlock() and - index = 0 + exists(IRVariable var | var = v.getIRVariable() | + block.getInstruction(index) = getInitializationTargetAddress(var) + or + // If there is no translatated element that does initialization of the + // variable we place the SSA definition at the entry block of the function. + not exists(getInitializationTargetAddress(var)) and + block = var.getEnclosingIRFunction().getEntryBlock() and + index = 0 + ) } override Cpp::Location getLocation() { result = v.getIRVariable().getLocation() } From 53c2d2f1e78cc471c8ae6e8c5f74bc7fc2440811 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Mon, 6 May 2024 18:49:41 +0100 Subject: [PATCH 228/238] C++: Accept test changes. --- .../IteratorToExpiredContainer.expected | 2 -- .../CWE-416/semmle/tests/IteratorToExpiredContainer/test.cpp | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/IteratorToExpiredContainer/IteratorToExpiredContainer.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/IteratorToExpiredContainer/IteratorToExpiredContainer.expected index 5bb295dc02a2..126f1e8f4f76 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/IteratorToExpiredContainer/IteratorToExpiredContainer.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/IteratorToExpiredContainer/IteratorToExpiredContainer.expected @@ -1,7 +1,5 @@ | test.cpp:680:30:680:30 | call to operator[] | This object is destroyed at the end of the full-expression. | | test.cpp:683:31:683:32 | call to at | This object is destroyed at the end of the full-expression. | -| test.cpp:689:46:689:58 | pointer to ~vector output argument | This object is destroyed at the end of the full-expression. | | test.cpp:702:27:702:27 | call to operator[] | This object is destroyed at the end of the full-expression. | | test.cpp:727:23:727:23 | call to operator[] | This object is destroyed at the end of the full-expression. | | test.cpp:735:23:735:23 | call to operator[] | This object is destroyed at the end of the full-expression. | -| test.cpp:803:3:803:3 | pointer to ~vector output argument | This object is destroyed at the end of the full-expression. | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/IteratorToExpiredContainer/test.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/IteratorToExpiredContainer/test.cpp index 0dc97ece06d6..bab492796f3c 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/IteratorToExpiredContainer/test.cpp +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/IteratorToExpiredContainer/test.cpp @@ -686,7 +686,7 @@ void test() { for (auto x : returnRef()[0]) {} // GOOD for (auto x : returnRef().at(0)) {} // GOOD - for(auto it = returnValue().begin(); it != returnValue().end(); ++it) {} // BAD + for(auto it = returnValue().begin(); it != returnValue().end(); ++it) {} // BAD [NOT DETECTED] { auto v = returnValue(); @@ -800,5 +800,5 @@ void test5(int i) const auto& vvs = returnValue(); for(const auto& vs : vvs) { } ++i; - } // GOOD [FALSE POSITIVE] + } // GOOD } \ No newline at end of file From 5fe3ab789095d4033204574dd31348240f63ea45 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 7 May 2024 10:12:15 +0200 Subject: [PATCH 229/238] Java: Prepare for inline test sharing with C#. --- java/ql/test/TestUtilities/InlineMadTest.qll | 71 +++++++++++--------- 1 file changed, 40 insertions(+), 31 deletions(-) diff --git a/java/ql/test/TestUtilities/InlineMadTest.qll b/java/ql/test/TestUtilities/InlineMadTest.qll index 31206a6338c4..a336fa6b3a9a 100644 --- a/java/ql/test/TestUtilities/InlineMadTest.qll +++ b/java/ql/test/TestUtilities/InlineMadTest.qll @@ -1,49 +1,60 @@ -import java +import java as J private signature module InlineMadTestLangSig { + /** + * A base class of callables for modeling. + */ + class Callable; + /** * Gets a relevant code comment for `c`, if any. */ string getComment(Callable c); } -signature module InlineMadTestConfigSig { - /** - * Gets the kind of a captured model. - */ - string getKind(); +private module InlineMadTestImpl { + private class Callable = Lang::Callable; - /** - * Gets a captured model for `c`, if any. - */ - string getCapturedModel(Callable c); -} + signature module InlineMadTestConfigSig { + /** + * Gets the kind of a captured model. + */ + string getKind(); -private module InlineMadTestImpl { - private string expects(Callable c) { - Lang::getComment(c).regexpCapture(" *(SPURIOUS-)?" + Input::getKind() + "=(.*)", 2) = result + /** + * Gets a captured model for `c`, if any. + */ + string getCapturedModel(Callable c); } - query predicate unexpectedModel(string msg) { - exists(Callable c, string flow | - flow = Input::getCapturedModel(c) and - not flow = expects(c) and - msg = "Unexpected " + Input::getKind() + " found: " + flow - ) - } + module InlineMadTest { + private string expects(Callable c) { + Lang::getComment(c).regexpCapture(" *(SPURIOUS-)?" + Input::getKind() + "=(.*)", 2) = result + } - query predicate expectedModel(string msg) { - exists(Callable c, string e | - e = expects(c) and - not e = Input::getCapturedModel(c) and - msg = "Expected " + Input::getKind() + " missing: " + e - ) + query predicate unexpectedModel(string msg) { + exists(Callable c, string flow | + flow = Input::getCapturedModel(c) and + not flow = expects(c) and + msg = "Unexpected " + Input::getKind() + " found: " + flow + ) + } + + query predicate expectedModel(string msg) { + exists(Callable c, string e | + e = expects(c) and + not e = Input::getCapturedModel(c) and + msg = "Expected " + Input::getKind() + " missing: " + e + ) + } } } private module InlineMadTestLang implements InlineMadTestLangSig { + class Callable = J::Callable; + string getComment(Callable c) { - exists(Javadoc doc | + exists(J::Javadoc doc | hasJavadoc(c, doc) and isNormalComment(doc) and result = doc.getChild(0).toString() @@ -51,6 +62,4 @@ private module InlineMadTestLang implements InlineMadTestLangSig { } } -module InlineMadTest { - import InlineMadTestImpl -} +import InlineMadTestImpl From 4eea214cb44fba65e8699c6d1df68a0c6b6e4f80 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Fri, 3 May 2024 16:47:51 +0200 Subject: [PATCH 230/238] C++: Update test results after extractor changes --- .../library-tests/ir/ir/PrintAST.expected | 16 ++++ .../library-tests/ir/ir/aliased_ir.expected | 76 +++++++++++-------- .../test/library-tests/ir/ir/raw_ir.expected | 60 +++++++++------ 3 files changed, 98 insertions(+), 54 deletions(-) diff --git a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected index cf5125b1ccf2..5a462665738b 100644 --- a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected +++ b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected @@ -12159,8 +12159,12 @@ ir.cpp: # 1109| Type = [IntType] int # 1110| [Destructor] void std::vector::~vector() # 1110| : +# 1110| [Destructor] void std::vector::~vector() +# 1110| : # 1110| [Destructor] void std::vector::~vector() # 1110| : +# 1110| [Destructor] void std::vector::~vector() +# 1110| : # 1110| [Destructor] void std::vector::~vector() # 1110| : # 1115| [ConstMemberFunction] std::vector::iterator std::vector::begin() const @@ -20674,6 +20678,12 @@ ir.cpp: # 2309| getQualifier(): [VariableAccess] s2 # 2309| Type = [Struct] String # 2309| ValueCategory = lvalue +#-----| getImplicitDestructorCall(0): [DestructorCall] call to ~vector +#-----| Type = [VoidType] void +#-----| ValueCategory = prvalue +#-----| getQualifier(): [ReuseExpr] reuse of temporary object +#-----| Type = [ClassTemplateInstantiation,Struct] vector +#-----| ValueCategory = xvalue # 2307| getUpdate().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) # 2307| Type = [ClassTemplateInstantiation,Struct] iterator # 2307| ValueCategory = lvalue @@ -22198,6 +22208,12 @@ ir.cpp: # 2431| Conversion = [IntegralConversion] integral conversion # 2431| Type = [IntType] int # 2431| ValueCategory = prvalue +#-----| getImplicitDestructorCall(0): [DestructorCall] call to ~vector +#-----| Type = [VoidType] void +#-----| ValueCategory = prvalue +#-----| getQualifier(): [ReuseExpr] reuse of temporary object +#-----| Type = [ClassTemplateInstantiation,Struct] vector +#-----| ValueCategory = xvalue # 2430| getUpdate().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) # 2430| Type = [ClassTemplateInstantiation,Struct] iterator # 2430| ValueCategory = lvalue diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected index ae73ecd8f6ff..3d9766d78b61 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected @@ -16810,31 +16810,39 @@ ir.cpp: # 2307| r2307_90(glval>) = CopyValue : r2307_78 #-----| Goto (back edge) -> Block 4 -# 2311| Block 6 -# 2311| r2311_1(glval) = VariableAddress[s] : -# 2311| m2311_2(String) = Uninitialized[s] : &:r2311_1 -# 2311| m2311_3(unknown) = Chi : total:m2307_57, partial:m2311_2 -# 2311| r2311_4(glval) = FunctionAddress[String] : -# 2311| r2311_5(glval) = StringConstant["hello"] : -# 2311| r2311_6(char *) = Convert : r2311_5 -# 2311| v2311_7(void) = Call[String] : func:r2311_4, this:r2311_1, 0:r2311_6 -# 2311| m2311_8(unknown) = ^CallSideEffect : ~m2311_3 -# 2311| m2311_9(unknown) = Chi : total:m2311_3, partial:m2311_8 -# 2311| v2311_10(void) = ^BufferReadSideEffect[0] : &:r2311_6, ~m2301_3 -# 2311| m2311_11(String) = ^IndirectMayWriteSideEffect[-1] : &:r2311_1 -# 2311| m2311_12(unknown) = Chi : total:m2311_9, partial:m2311_11 -# 2311| r2311_13(glval) = VariableAddress[s2] : -# 2311| m2311_14(String) = Uninitialized[s2] : &:r2311_13 -# 2311| m2311_15(unknown) = Chi : total:m2311_12, partial:m2311_14 -# 2311| r2311_16(glval) = FunctionAddress[String] : -# 2311| r2311_17(glval) = StringConstant["world"] : -# 2311| r2311_18(char *) = Convert : r2311_17 -# 2311| v2311_19(void) = Call[String] : func:r2311_16, this:r2311_13, 0:r2311_18 -# 2311| m2311_20(unknown) = ^CallSideEffect : ~m2311_15 -# 2311| m2311_21(unknown) = Chi : total:m2311_15, partial:m2311_20 -# 2311| v2311_22(void) = ^BufferReadSideEffect[0] : &:r2311_18, ~m2301_3 -# 2311| m2311_23(String) = ^IndirectMayWriteSideEffect[-1] : &:r2311_13 -# 2311| m2311_24(unknown) = Chi : total:m2311_21, partial:m2311_23 +#-----| Block 6 +#-----| r0_18(glval>) = CopyValue : r2307_2 +#-----| r0_19(glval) = FunctionAddress[~vector] : +#-----| v0_20(void) = Call[~vector] : func:r0_19, this:r0_18 +#-----| m0_21(unknown) = ^CallSideEffect : ~m2307_57 +#-----| m0_22(unknown) = Chi : total:m2307_57, partial:m0_21 +#-----| v0_23(void) = ^IndirectReadSideEffect[-1] : &:r0_18, ~m0_22 +#-----| m0_24(vector) = ^IndirectMayWriteSideEffect[-1] : &:r0_18 +#-----| m0_25(unknown) = Chi : total:m0_22, partial:m0_24 +# 2311| r2311_1(glval) = VariableAddress[s] : +# 2311| m2311_2(String) = Uninitialized[s] : &:r2311_1 +# 2311| m2311_3(unknown) = Chi : total:m0_25, partial:m2311_2 +# 2311| r2311_4(glval) = FunctionAddress[String] : +# 2311| r2311_5(glval) = StringConstant["hello"] : +# 2311| r2311_6(char *) = Convert : r2311_5 +# 2311| v2311_7(void) = Call[String] : func:r2311_4, this:r2311_1, 0:r2311_6 +# 2311| m2311_8(unknown) = ^CallSideEffect : ~m2311_3 +# 2311| m2311_9(unknown) = Chi : total:m2311_3, partial:m2311_8 +# 2311| v2311_10(void) = ^BufferReadSideEffect[0] : &:r2311_6, ~m2301_3 +# 2311| m2311_11(String) = ^IndirectMayWriteSideEffect[-1] : &:r2311_1 +# 2311| m2311_12(unknown) = Chi : total:m2311_9, partial:m2311_11 +# 2311| r2311_13(glval) = VariableAddress[s2] : +# 2311| m2311_14(String) = Uninitialized[s2] : &:r2311_13 +# 2311| m2311_15(unknown) = Chi : total:m2311_12, partial:m2311_14 +# 2311| r2311_16(glval) = FunctionAddress[String] : +# 2311| r2311_17(glval) = StringConstant["world"] : +# 2311| r2311_18(char *) = Convert : r2311_17 +# 2311| v2311_19(void) = Call[String] : func:r2311_16, this:r2311_13, 0:r2311_18 +# 2311| m2311_20(unknown) = ^CallSideEffect : ~m2311_15 +# 2311| m2311_21(unknown) = Chi : total:m2311_15, partial:m2311_20 +# 2311| v2311_22(void) = ^BufferReadSideEffect[0] : &:r2311_18, ~m2301_3 +# 2311| m2311_23(String) = ^IndirectMayWriteSideEffect[-1] : &:r2311_13 +# 2311| m2311_24(unknown) = Chi : total:m2311_21, partial:m2311_23 #-----| Goto -> Block 7 # 2311| Block 7 @@ -17673,11 +17681,19 @@ ir.cpp: # 2430| r2430_78(glval>) = CopyValue : r2430_74 #-----| Goto (back edge) -> Block 10 -# 2432| Block 12 -# 2432| v2432_1(void) = NoOp : -# 2410| v2410_5(void) = ReturnVoid : -# 2410| v2410_6(void) = AliasedUse : ~m2430_61 -# 2410| v2410_7(void) = ExitFunction : +#-----| Block 12 +#-----| r0_18(glval>) = CopyValue : r2430_27 +#-----| r0_19(glval) = FunctionAddress[~vector] : +#-----| v0_20(void) = Call[~vector] : func:r0_19, this:r0_18 +#-----| m0_21(unknown) = ^CallSideEffect : ~m2430_63 +#-----| m0_22(unknown) = Chi : total:m2430_63, partial:m0_21 +#-----| v0_23(void) = ^IndirectReadSideEffect[-1] : &:r0_18, ~m0_22 +#-----| m0_24(vector) = ^IndirectMayWriteSideEffect[-1] : &:r0_18 +#-----| m0_25(unknown) = Chi : total:m0_22, partial:m0_24 +# 2432| v2432_1(void) = NoOp : +# 2410| v2410_5(void) = ReturnVoid : +# 2410| v2410_6(void) = AliasedUse : ~m0_22 +# 2410| v2410_7(void) = ExitFunction : # 2410| Block 13 # 2410| v2410_8(void) = Unreached : diff --git a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected index 71796c4c39e2..b2ea13181a12 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -15353,25 +15353,31 @@ ir.cpp: # 2307| r2307_71(glval>) = CopyValue : r2307_62 #-----| Goto (back edge) -> Block 4 -# 2311| Block 6 -# 2311| r2311_1(glval) = VariableAddress[s] : -# 2311| mu2311_2(String) = Uninitialized[s] : &:r2311_1 -# 2311| r2311_3(glval) = FunctionAddress[String] : -# 2311| r2311_4(glval) = StringConstant["hello"] : -# 2311| r2311_5(char *) = Convert : r2311_4 -# 2311| v2311_6(void) = Call[String] : func:r2311_3, this:r2311_1, 0:r2311_5 -# 2311| mu2311_7(unknown) = ^CallSideEffect : ~m? -# 2311| v2311_8(void) = ^BufferReadSideEffect[0] : &:r2311_5, ~m? -# 2311| mu2311_9(String) = ^IndirectMayWriteSideEffect[-1] : &:r2311_1 -# 2311| r2311_10(glval) = VariableAddress[s2] : -# 2311| mu2311_11(String) = Uninitialized[s2] : &:r2311_10 -# 2311| r2311_12(glval) = FunctionAddress[String] : -# 2311| r2311_13(glval) = StringConstant["world"] : -# 2311| r2311_14(char *) = Convert : r2311_13 -# 2311| v2311_15(void) = Call[String] : func:r2311_12, this:r2311_10, 0:r2311_14 -# 2311| mu2311_16(unknown) = ^CallSideEffect : ~m? -# 2311| v2311_17(void) = ^BufferReadSideEffect[0] : &:r2311_14, ~m? -# 2311| mu2311_18(String) = ^IndirectMayWriteSideEffect[-1] : &:r2311_10 +#-----| Block 6 +#-----| r0_17(glval>) = CopyValue : r2307_2 +#-----| r0_18(glval) = FunctionAddress[~vector] : +#-----| v0_19(void) = Call[~vector] : func:r0_18, this:r0_17 +#-----| mu0_20(unknown) = ^CallSideEffect : ~m? +#-----| v0_21(void) = ^IndirectReadSideEffect[-1] : &:r0_17, ~m? +#-----| mu0_22(vector) = ^IndirectMayWriteSideEffect[-1] : &:r0_17 +# 2311| r2311_1(glval) = VariableAddress[s] : +# 2311| mu2311_2(String) = Uninitialized[s] : &:r2311_1 +# 2311| r2311_3(glval) = FunctionAddress[String] : +# 2311| r2311_4(glval) = StringConstant["hello"] : +# 2311| r2311_5(char *) = Convert : r2311_4 +# 2311| v2311_6(void) = Call[String] : func:r2311_3, this:r2311_1, 0:r2311_5 +# 2311| mu2311_7(unknown) = ^CallSideEffect : ~m? +# 2311| v2311_8(void) = ^BufferReadSideEffect[0] : &:r2311_5, ~m? +# 2311| mu2311_9(String) = ^IndirectMayWriteSideEffect[-1] : &:r2311_1 +# 2311| r2311_10(glval) = VariableAddress[s2] : +# 2311| mu2311_11(String) = Uninitialized[s2] : &:r2311_10 +# 2311| r2311_12(glval) = FunctionAddress[String] : +# 2311| r2311_13(glval) = StringConstant["world"] : +# 2311| r2311_14(char *) = Convert : r2311_13 +# 2311| v2311_15(void) = Call[String] : func:r2311_12, this:r2311_10, 0:r2311_14 +# 2311| mu2311_16(unknown) = ^CallSideEffect : ~m? +# 2311| v2311_17(void) = ^BufferReadSideEffect[0] : &:r2311_14, ~m? +# 2311| mu2311_18(String) = ^IndirectMayWriteSideEffect[-1] : &:r2311_10 #-----| Goto -> Block 7 # 2311| Block 7 @@ -16082,11 +16088,17 @@ ir.cpp: # 2430| r2430_63(glval>) = CopyValue : r2430_60 #-----| Goto (back edge) -> Block 11 -# 2432| Block 13 -# 2432| v2432_1(void) = NoOp : -# 2410| v2410_4(void) = ReturnVoid : -# 2410| v2410_5(void) = AliasedUse : ~m? -# 2410| v2410_6(void) = ExitFunction : +#-----| Block 13 +#-----| r0_17(glval>) = CopyValue : r2430_21 +#-----| r0_18(glval) = FunctionAddress[~vector] : +#-----| v0_19(void) = Call[~vector] : func:r0_18, this:r0_17 +#-----| mu0_20(unknown) = ^CallSideEffect : ~m? +#-----| v0_21(void) = ^IndirectReadSideEffect[-1] : &:r0_17, ~m? +#-----| mu0_22(vector) = ^IndirectMayWriteSideEffect[-1] : &:r0_17 +# 2432| v2432_1(void) = NoOp : +# 2410| v2410_4(void) = ReturnVoid : +# 2410| v2410_5(void) = AliasedUse : ~m? +# 2410| v2410_6(void) = ExitFunction : # 2434| void param_with_destructor_by_value(ClassWithDestructor) # 2434| Block 0 From 9f27eb3eda992d7f74b56bea19f29099eda93184 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Tue, 7 May 2024 12:44:28 +0200 Subject: [PATCH 231/238] Bazel: make `git_lfs_probe.py` compatible with python 3.8 --- misc/bazel/internal/git_lfs_probe.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/misc/bazel/internal/git_lfs_probe.py b/misc/bazel/internal/git_lfs_probe.py index f0a4dfd4117a..018725c82da8 100755 --- a/misc/bazel/internal/git_lfs_probe.py +++ b/misc/bazel/internal/git_lfs_probe.py @@ -18,14 +18,15 @@ import re import base64 from dataclasses import dataclass +from typing import Dict @dataclass class Endpoint: href: str - headers: dict[str, str] + headers: Dict[str, str] - def update_headers(self, d: dict[str, str]): + def update_headers(self, d: Dict[str, str]): self.headers.update((k.capitalize(), v) for k, v in d.items()) From 61fb89721ad4736a66d81575179edf06432a2861 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 7 May 2024 12:19:06 +0100 Subject: [PATCH 232/238] C++: Add 'cpp/uninitialized-local' FP. --- .../semmle/tests/UninitializedLocal.expected | 2 ++ .../CWE/CWE-457/semmle/tests/test.cpp | 23 ++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/tests/UninitializedLocal.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/tests/UninitializedLocal.expected index d27b2c996b33..94d01d0e6c13 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/tests/UninitializedLocal.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/tests/UninitializedLocal.expected @@ -13,6 +13,7 @@ nodes | test.cpp:458:6:458:6 | definition of x | semmle.label | definition of x | | test.cpp:464:6:464:6 | definition of x | semmle.label | definition of x | | test.cpp:471:6:471:6 | definition of x | semmle.label | definition of x | +| test.cpp:557:15:557:15 | definition of r | semmle.label | definition of r | #select | test.cpp:12:6:12:8 | foo | test.cpp:11:6:11:8 | definition of foo | test.cpp:11:6:11:8 | definition of foo | The variable $@ may not be initialized at this access. | test.cpp:11:6:11:8 | foo | foo | | test.cpp:113:6:113:8 | foo | test.cpp:111:6:111:8 | definition of foo | test.cpp:111:6:111:8 | definition of foo | The variable $@ may not be initialized at this access. | test.cpp:111:6:111:8 | foo | foo | @@ -27,3 +28,4 @@ nodes | test.cpp:460:7:460:7 | x | test.cpp:458:6:458:6 | definition of x | test.cpp:458:6:458:6 | definition of x | The variable $@ may not be initialized at this access. | test.cpp:458:6:458:6 | x | x | | test.cpp:467:2:467:2 | x | test.cpp:464:6:464:6 | definition of x | test.cpp:464:6:464:6 | definition of x | The variable $@ may not be initialized at this access. | test.cpp:464:6:464:6 | x | x | | test.cpp:474:7:474:7 | x | test.cpp:471:6:471:6 | definition of x | test.cpp:471:6:471:6 | definition of x | The variable $@ may not be initialized at this access. | test.cpp:471:6:471:6 | x | x | +| test.cpp:567:7:567:7 | r | test.cpp:557:15:557:15 | definition of r | test.cpp:557:15:557:15 | definition of r | The variable $@ may not be initialized at this access. | test.cpp:557:15:557:15 | r | r | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/tests/test.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/tests/test.cpp index e3489cee4cc3..4f56ab1259ab 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/tests/test.cpp +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/tests/test.cpp @@ -1,6 +1,6 @@ // Semmle test cases for rule CWE-457. -void use(int data); +void use(...); void test1() { int foo = 1; @@ -544,4 +544,25 @@ class StaticMethodClass{ int static_method_false_positive(){ StaticMethodClass *t; int i = t->get(); // GOOD: the `get` method is static and this is equivalent to StaticMethodClass::get() +} + +struct LinkedList +{ + LinkedList* next; +}; + +bool getBool(); + +void test45() { + LinkedList *r, *s, **rP = &r; + + while(getBool()) + { + s = new LinkedList; + *rP = s; + rP = &s->next; + } + + *rP = NULL; + use(r); // GOOD [FALSE POSITIVE] } \ No newline at end of file From 8e95395382db40ce700ef582998bff933167be9d Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 7 May 2024 12:55:42 +0100 Subject: [PATCH 233/238] C++: Accept more test changes. --- .../CWE/CWE-457/semmle/tests/LoopConditionsConst.expected | 1 + 1 file changed, 1 insertion(+) diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/tests/LoopConditionsConst.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/tests/LoopConditionsConst.expected index 01dbbaa2e652..07ca32b1718c 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/tests/LoopConditionsConst.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/tests/LoopConditionsConst.expected @@ -22,3 +22,4 @@ | test.cpp:416:2:418:2 | for(...;...;...) ... | test.cpp:416:18:416:23 | ... < ... | 1 | i | { ... } | i | return ... | | test.cpp:424:2:425:2 | for(...;...;...) ... | test.cpp:424:18:424:23 | ... < ... | 1 | i | { ... } | i | return ... | | test.cpp:433:2:434:2 | for(...;...;...) ... | test.cpp:433:18:433:22 | 0 | 0 | | { ... } | 0 | return ... | +| test.cpp:559:3:564:3 | while (...) ... | test.cpp:559:9:559:15 | call to getBool | | call to getBool | { ... } | call to getBool | ExprStmt | From c11fac81fd5dcc9b14ff42adff823f58ce3f2e83 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 7 May 2024 13:55:42 +0100 Subject: [PATCH 234/238] Make summaryThroughStepValue include param outputs This matches summaryThroughStepTaint. --- .../dataflow/codeql/dataflow/internal/FlowSummaryImpl.qll | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/internal/FlowSummaryImpl.qll b/shared/dataflow/codeql/dataflow/internal/FlowSummaryImpl.qll index 89a2a23d53bb..78950806f7d6 100644 --- a/shared/dataflow/codeql/dataflow/internal/FlowSummaryImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/FlowSummaryImpl.qll @@ -1286,10 +1286,8 @@ module Make< * be useful to include in the exposed local data-flow/taint-tracking relations. */ predicate summaryThroughStepValue(ArgNode arg, Node out, SummarizedCallable sc) { - exists(ReturnKind rk, SummaryNode ret, DataFlowCall call | - summaryLocalStep(summaryArgParam(call, arg, sc), ret, true, _) and - summaryReturnNode(ret, pragma[only_bind_into](rk)) and - out = getAnOutNode(call, pragma[only_bind_into](rk)) + exists(SummaryNode ret | + summaryLocalStep(summaryArgParamRetOut(arg, ret, out, sc), ret, true, _) ) } From aab43afd8129d64db21507ea04970a9e38900e62 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 7 May 2024 15:36:48 +0100 Subject: [PATCH 235/238] Swift: accept test changes --- .../ql/test/library-tests/dataflow/dataflow/LocalFlow.expected | 2 ++ 1 file changed, 2 insertions(+) diff --git a/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected b/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected index 5a1e142d9457..4456b1a4ac2d 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected +++ b/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected @@ -794,8 +794,10 @@ | test.swift:680:10:680:11 | &... | test.swift:681:15:681:15 | x | | test.swift:680:11:680:11 | [post] x | test.swift:680:10:680:11 | &... | | test.swift:680:11:680:11 | x | test.swift:680:10:680:11 | &... | +| test.swift:680:11:680:11 | x | test.swift:680:15:680:15 | [post] y | | test.swift:680:14:680:15 | &... | test.swift:682:15:682:15 | y | | test.swift:680:15:680:15 | [post] y | test.swift:680:14:680:15 | &... | +| test.swift:680:15:680:15 | y | test.swift:680:11:680:11 | [post] x | | test.swift:680:15:680:15 | y | test.swift:680:14:680:15 | &... | | test.swift:686:9:686:9 | SSA def(arr1) | test.swift:687:15:687:15 | arr1 | | test.swift:686:9:686:9 | arr1 | test.swift:686:9:686:9 | SSA def(arr1) | From 61580da14d608f4a26a2ed19e25eefcafd3aea4d Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 7 May 2024 21:21:25 +0200 Subject: [PATCH 236/238] C++: Update test results after extractor changes --- .../library-tests/ir/ir/PrintAST.expected | 24 ++--- .../library-tests/ir/ir/aliased_ir.expected | 92 +++++++++---------- .../test/library-tests/ir/ir/raw_ir.expected | 72 +++++++-------- 3 files changed, 94 insertions(+), 94 deletions(-) diff --git a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected index eb1b3eeb2a2f..ea5b9fec8253 100644 --- a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected +++ b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected @@ -20678,12 +20678,12 @@ ir.cpp: # 2309| getQualifier(): [VariableAccess] s2 # 2309| Type = [Struct] String # 2309| ValueCategory = lvalue -#-----| getImplicitDestructorCall(0): [DestructorCall] call to ~vector -#-----| Type = [VoidType] void -#-----| ValueCategory = prvalue -#-----| getQualifier(): [ReuseExpr] reuse of temporary object -#-----| Type = [ClassTemplateInstantiation,Struct] vector -#-----| ValueCategory = xvalue +# 2307| getImplicitDestructorCall(0): [DestructorCall] call to ~vector +# 2307| Type = [VoidType] void +# 2307| ValueCategory = prvalue +# 2307| getQualifier(): [ReuseExpr] reuse of temporary object +# 2307| Type = [ClassTemplateInstantiation,Struct] vector +# 2307| ValueCategory = xvalue # 2307| getUpdate().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) # 2307| Type = [ClassTemplateInstantiation,Struct] iterator # 2307| ValueCategory = lvalue @@ -22208,12 +22208,12 @@ ir.cpp: # 2431| Conversion = [IntegralConversion] integral conversion # 2431| Type = [IntType] int # 2431| ValueCategory = prvalue -#-----| getImplicitDestructorCall(0): [DestructorCall] call to ~vector -#-----| Type = [VoidType] void -#-----| ValueCategory = prvalue -#-----| getQualifier(): [ReuseExpr] reuse of temporary object -#-----| Type = [ClassTemplateInstantiation,Struct] vector -#-----| ValueCategory = xvalue +# 2430| getImplicitDestructorCall(0): [DestructorCall] call to ~vector +# 2430| Type = [VoidType] void +# 2430| ValueCategory = prvalue +# 2430| getQualifier(): [ReuseExpr] reuse of temporary object +# 2430| Type = [ClassTemplateInstantiation,Struct] vector +# 2430| ValueCategory = xvalue # 2430| getUpdate().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) # 2430| Type = [ClassTemplateInstantiation,Struct] iterator # 2430| ValueCategory = lvalue diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected index 862e921dde95..1fe18e4f92a9 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected @@ -16810,39 +16810,39 @@ ir.cpp: # 2307| r2307_90(glval>) = CopyValue : r2307_78 #-----| Goto (back edge) -> Block 4 -#-----| Block 6 -#-----| r0_18(glval>) = CopyValue : r2307_2 -#-----| r0_19(glval) = FunctionAddress[~vector] : -#-----| v0_20(void) = Call[~vector] : func:r0_19, this:r0_18 -#-----| m0_21(unknown) = ^CallSideEffect : ~m2307_57 -#-----| m0_22(unknown) = Chi : total:m2307_57, partial:m0_21 -#-----| v0_23(void) = ^IndirectReadSideEffect[-1] : &:r0_18, ~m0_22 -#-----| m0_24(vector) = ^IndirectMayWriteSideEffect[-1] : &:r0_18 -#-----| m0_25(unknown) = Chi : total:m0_22, partial:m0_24 -# 2311| r2311_1(glval) = VariableAddress[s] : -# 2311| m2311_2(String) = Uninitialized[s] : &:r2311_1 -# 2311| m2311_3(unknown) = Chi : total:m0_25, partial:m2311_2 -# 2311| r2311_4(glval) = FunctionAddress[String] : -# 2311| r2311_5(glval) = StringConstant["hello"] : -# 2311| r2311_6(char *) = Convert : r2311_5 -# 2311| v2311_7(void) = Call[String] : func:r2311_4, this:r2311_1, 0:r2311_6 -# 2311| m2311_8(unknown) = ^CallSideEffect : ~m2311_3 -# 2311| m2311_9(unknown) = Chi : total:m2311_3, partial:m2311_8 -# 2311| v2311_10(void) = ^BufferReadSideEffect[0] : &:r2311_6, ~m2301_3 -# 2311| m2311_11(String) = ^IndirectMayWriteSideEffect[-1] : &:r2311_1 -# 2311| m2311_12(unknown) = Chi : total:m2311_9, partial:m2311_11 -# 2311| r2311_13(glval) = VariableAddress[s2] : -# 2311| m2311_14(String) = Uninitialized[s2] : &:r2311_13 -# 2311| m2311_15(unknown) = Chi : total:m2311_12, partial:m2311_14 -# 2311| r2311_16(glval) = FunctionAddress[String] : -# 2311| r2311_17(glval) = StringConstant["world"] : -# 2311| r2311_18(char *) = Convert : r2311_17 -# 2311| v2311_19(void) = Call[String] : func:r2311_16, this:r2311_13, 0:r2311_18 -# 2311| m2311_20(unknown) = ^CallSideEffect : ~m2311_15 -# 2311| m2311_21(unknown) = Chi : total:m2311_15, partial:m2311_20 -# 2311| v2311_22(void) = ^BufferReadSideEffect[0] : &:r2311_18, ~m2301_3 -# 2311| m2311_23(String) = ^IndirectMayWriteSideEffect[-1] : &:r2311_13 -# 2311| m2311_24(unknown) = Chi : total:m2311_21, partial:m2311_23 +# 2307| Block 6 +# 2307| r2307_91(glval>) = CopyValue : r2307_2 +# 2307| r2307_92(glval) = FunctionAddress[~vector] : +# 2307| v2307_93(void) = Call[~vector] : func:r2307_92, this:r2307_91 +# 2307| m2307_94(unknown) = ^CallSideEffect : ~m2307_57 +# 2307| m2307_95(unknown) = Chi : total:m2307_57, partial:m2307_94 +# 2307| v2307_96(void) = ^IndirectReadSideEffect[-1] : &:r2307_91, ~m2307_95 +# 2307| m2307_97(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2307_91 +# 2307| m2307_98(unknown) = Chi : total:m2307_95, partial:m2307_97 +# 2311| r2311_1(glval) = VariableAddress[s] : +# 2311| m2311_2(String) = Uninitialized[s] : &:r2311_1 +# 2311| m2311_3(unknown) = Chi : total:m2307_98, partial:m2311_2 +# 2311| r2311_4(glval) = FunctionAddress[String] : +# 2311| r2311_5(glval) = StringConstant["hello"] : +# 2311| r2311_6(char *) = Convert : r2311_5 +# 2311| v2311_7(void) = Call[String] : func:r2311_4, this:r2311_1, 0:r2311_6 +# 2311| m2311_8(unknown) = ^CallSideEffect : ~m2311_3 +# 2311| m2311_9(unknown) = Chi : total:m2311_3, partial:m2311_8 +# 2311| v2311_10(void) = ^BufferReadSideEffect[0] : &:r2311_6, ~m2301_3 +# 2311| m2311_11(String) = ^IndirectMayWriteSideEffect[-1] : &:r2311_1 +# 2311| m2311_12(unknown) = Chi : total:m2311_9, partial:m2311_11 +# 2311| r2311_13(glval) = VariableAddress[s2] : +# 2311| m2311_14(String) = Uninitialized[s2] : &:r2311_13 +# 2311| m2311_15(unknown) = Chi : total:m2311_12, partial:m2311_14 +# 2311| r2311_16(glval) = FunctionAddress[String] : +# 2311| r2311_17(glval) = StringConstant["world"] : +# 2311| r2311_18(char *) = Convert : r2311_17 +# 2311| v2311_19(void) = Call[String] : func:r2311_16, this:r2311_13, 0:r2311_18 +# 2311| m2311_20(unknown) = ^CallSideEffect : ~m2311_15 +# 2311| m2311_21(unknown) = Chi : total:m2311_15, partial:m2311_20 +# 2311| v2311_22(void) = ^BufferReadSideEffect[0] : &:r2311_18, ~m2301_3 +# 2311| m2311_23(String) = ^IndirectMayWriteSideEffect[-1] : &:r2311_13 +# 2311| m2311_24(unknown) = Chi : total:m2311_21, partial:m2311_23 #-----| Goto -> Block 7 # 2311| Block 7 @@ -17681,19 +17681,19 @@ ir.cpp: # 2430| r2430_78(glval>) = CopyValue : r2430_74 #-----| Goto (back edge) -> Block 10 -#-----| Block 12 -#-----| r0_18(glval>) = CopyValue : r2430_27 -#-----| r0_19(glval) = FunctionAddress[~vector] : -#-----| v0_20(void) = Call[~vector] : func:r0_19, this:r0_18 -#-----| m0_21(unknown) = ^CallSideEffect : ~m2430_63 -#-----| m0_22(unknown) = Chi : total:m2430_63, partial:m0_21 -#-----| v0_23(void) = ^IndirectReadSideEffect[-1] : &:r0_18, ~m0_22 -#-----| m0_24(vector) = ^IndirectMayWriteSideEffect[-1] : &:r0_18 -#-----| m0_25(unknown) = Chi : total:m0_22, partial:m0_24 -# 2432| v2432_1(void) = NoOp : -# 2410| v2410_5(void) = ReturnVoid : -# 2410| v2410_6(void) = AliasedUse : ~m0_22 -# 2410| v2410_7(void) = ExitFunction : +# 2430| Block 12 +# 2430| r2430_79(glval>) = CopyValue : r2430_27 +# 2430| r2430_80(glval) = FunctionAddress[~vector] : +# 2430| v2430_81(void) = Call[~vector] : func:r2430_80, this:r2430_79 +# 2430| m2430_82(unknown) = ^CallSideEffect : ~m2430_63 +# 2430| m2430_83(unknown) = Chi : total:m2430_63, partial:m2430_82 +# 2430| v2430_84(void) = ^IndirectReadSideEffect[-1] : &:r2430_79, ~m2430_83 +# 2430| m2430_85(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2430_79 +# 2430| m2430_86(unknown) = Chi : total:m2430_83, partial:m2430_85 +# 2432| v2432_1(void) = NoOp : +# 2410| v2410_5(void) = ReturnVoid : +# 2410| v2410_6(void) = AliasedUse : ~m2430_83 +# 2410| v2410_7(void) = ExitFunction : # 2410| Block 13 # 2410| v2410_8(void) = Unreached : diff --git a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected index 498b845dd8d0..404d48758b83 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -15353,31 +15353,31 @@ ir.cpp: # 2307| r2307_71(glval>) = CopyValue : r2307_62 #-----| Goto (back edge) -> Block 4 -#-----| Block 6 -#-----| r0_17(glval>) = CopyValue : r2307_2 -#-----| r0_18(glval) = FunctionAddress[~vector] : -#-----| v0_19(void) = Call[~vector] : func:r0_18, this:r0_17 -#-----| mu0_20(unknown) = ^CallSideEffect : ~m? -#-----| v0_21(void) = ^IndirectReadSideEffect[-1] : &:r0_17, ~m? -#-----| mu0_22(vector) = ^IndirectMayWriteSideEffect[-1] : &:r0_17 -# 2311| r2311_1(glval) = VariableAddress[s] : -# 2311| mu2311_2(String) = Uninitialized[s] : &:r2311_1 -# 2311| r2311_3(glval) = FunctionAddress[String] : -# 2311| r2311_4(glval) = StringConstant["hello"] : -# 2311| r2311_5(char *) = Convert : r2311_4 -# 2311| v2311_6(void) = Call[String] : func:r2311_3, this:r2311_1, 0:r2311_5 -# 2311| mu2311_7(unknown) = ^CallSideEffect : ~m? -# 2311| v2311_8(void) = ^BufferReadSideEffect[0] : &:r2311_5, ~m? -# 2311| mu2311_9(String) = ^IndirectMayWriteSideEffect[-1] : &:r2311_1 -# 2311| r2311_10(glval) = VariableAddress[s2] : -# 2311| mu2311_11(String) = Uninitialized[s2] : &:r2311_10 -# 2311| r2311_12(glval) = FunctionAddress[String] : -# 2311| r2311_13(glval) = StringConstant["world"] : -# 2311| r2311_14(char *) = Convert : r2311_13 -# 2311| v2311_15(void) = Call[String] : func:r2311_12, this:r2311_10, 0:r2311_14 -# 2311| mu2311_16(unknown) = ^CallSideEffect : ~m? -# 2311| v2311_17(void) = ^BufferReadSideEffect[0] : &:r2311_14, ~m? -# 2311| mu2311_18(String) = ^IndirectMayWriteSideEffect[-1] : &:r2311_10 +# 2307| Block 6 +# 2307| r2307_72(glval>) = CopyValue : r2307_2 +# 2307| r2307_73(glval) = FunctionAddress[~vector] : +# 2307| v2307_74(void) = Call[~vector] : func:r2307_73, this:r2307_72 +# 2307| mu2307_75(unknown) = ^CallSideEffect : ~m? +# 2307| v2307_76(void) = ^IndirectReadSideEffect[-1] : &:r2307_72, ~m? +# 2307| mu2307_77(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2307_72 +# 2311| r2311_1(glval) = VariableAddress[s] : +# 2311| mu2311_2(String) = Uninitialized[s] : &:r2311_1 +# 2311| r2311_3(glval) = FunctionAddress[String] : +# 2311| r2311_4(glval) = StringConstant["hello"] : +# 2311| r2311_5(char *) = Convert : r2311_4 +# 2311| v2311_6(void) = Call[String] : func:r2311_3, this:r2311_1, 0:r2311_5 +# 2311| mu2311_7(unknown) = ^CallSideEffect : ~m? +# 2311| v2311_8(void) = ^BufferReadSideEffect[0] : &:r2311_5, ~m? +# 2311| mu2311_9(String) = ^IndirectMayWriteSideEffect[-1] : &:r2311_1 +# 2311| r2311_10(glval) = VariableAddress[s2] : +# 2311| mu2311_11(String) = Uninitialized[s2] : &:r2311_10 +# 2311| r2311_12(glval) = FunctionAddress[String] : +# 2311| r2311_13(glval) = StringConstant["world"] : +# 2311| r2311_14(char *) = Convert : r2311_13 +# 2311| v2311_15(void) = Call[String] : func:r2311_12, this:r2311_10, 0:r2311_14 +# 2311| mu2311_16(unknown) = ^CallSideEffect : ~m? +# 2311| v2311_17(void) = ^BufferReadSideEffect[0] : &:r2311_14, ~m? +# 2311| mu2311_18(String) = ^IndirectMayWriteSideEffect[-1] : &:r2311_10 #-----| Goto -> Block 7 # 2311| Block 7 @@ -16088,17 +16088,17 @@ ir.cpp: # 2430| r2430_63(glval>) = CopyValue : r2430_60 #-----| Goto (back edge) -> Block 11 -#-----| Block 13 -#-----| r0_17(glval>) = CopyValue : r2430_21 -#-----| r0_18(glval) = FunctionAddress[~vector] : -#-----| v0_19(void) = Call[~vector] : func:r0_18, this:r0_17 -#-----| mu0_20(unknown) = ^CallSideEffect : ~m? -#-----| v0_21(void) = ^IndirectReadSideEffect[-1] : &:r0_17, ~m? -#-----| mu0_22(vector) = ^IndirectMayWriteSideEffect[-1] : &:r0_17 -# 2432| v2432_1(void) = NoOp : -# 2410| v2410_4(void) = ReturnVoid : -# 2410| v2410_5(void) = AliasedUse : ~m? -# 2410| v2410_6(void) = ExitFunction : +# 2430| Block 13 +# 2430| r2430_64(glval>) = CopyValue : r2430_21 +# 2430| r2430_65(glval) = FunctionAddress[~vector] : +# 2430| v2430_66(void) = Call[~vector] : func:r2430_65, this:r2430_64 +# 2430| mu2430_67(unknown) = ^CallSideEffect : ~m? +# 2430| v2430_68(void) = ^IndirectReadSideEffect[-1] : &:r2430_64, ~m? +# 2430| mu2430_69(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2430_64 +# 2432| v2432_1(void) = NoOp : +# 2410| v2410_4(void) = ReturnVoid : +# 2410| v2410_5(void) = AliasedUse : ~m? +# 2410| v2410_6(void) = ExitFunction : # 2434| void param_with_destructor_by_value(ClassWithDestructor) # 2434| Block 0 From 2dcb55cc42e1cce375dd336a99df92130dc36fa0 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Wed, 8 May 2024 11:38:50 +0200 Subject: [PATCH 237/238] C++: Add `bool` operator to IR test --- .../library-tests/ir/ir/PrintAST.expected | 6018 +++++++++-------- .../library-tests/ir/ir/aliased_ir.expected | 5158 +++++++------- cpp/ql/test/library-tests/ir/ir/ir.cpp | 15 + .../test/library-tests/ir/ir/raw_ir.expected | 4194 ++++++------ 4 files changed, 7701 insertions(+), 7684 deletions(-) diff --git a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected index ea5b9fec8253..0d6ab9c6a4e5 100644 --- a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected +++ b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected @@ -19311,193 +19311,195 @@ ir.cpp: # 2193| getQualifier(): [ThisExpr] this # 2193| Type = [PointerType] ClassWithDestructor * # 2193| ValueCategory = prvalue(load) -# 2196| [GlobalVariable] bool initialization_with_destructor_bool -# 2196| getInitializer(): [Initializer] initializer for initialization_with_destructor_bool -# 2196| getExpr(): [Literal] 1 -# 2196| Type = [BoolType] bool -# 2196| Value = [Literal] 1 -# 2196| ValueCategory = prvalue -# 2198| [TopLevelFunction] void initialization_with_destructor(bool, char) -# 2198| : -# 2198| getParameter(0): [Parameter] b -# 2198| Type = [BoolType] bool -# 2198| getParameter(1): [Parameter] c -# 2198| Type = [PlainCharType] char -# 2198| getEntryPoint(): [BlockStmt] { ... } -# 2199| getStmt(0): [IfStmt] if (...) ... -# 2199| getInitialization(): [DeclStmt] declaration -# 2199| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x -# 2199| Type = [Class] ClassWithDestructor -# 2199| getVariable().getInitializer(): [Initializer] initializer for x -# 2199| getExpr(): [ConstructorCall] call to ClassWithDestructor -# 2199| Type = [VoidType] void -# 2199| ValueCategory = prvalue -# 2199| getCondition(): [VariableAccess] b -# 2199| Type = [BoolType] bool -# 2199| ValueCategory = prvalue(load) -# 2200| getThen(): [ExprStmt] ExprStmt -# 2200| getExpr(): [FunctionCall] call to set_x -# 2200| Type = [VoidType] void -# 2200| ValueCategory = prvalue -# 2200| getQualifier(): [VariableAccess] x -# 2200| Type = [Class] ClassWithDestructor -# 2200| ValueCategory = lvalue -# 2200| getArgument(0): [CharLiteral] 97 -# 2200| Type = [PlainCharType] char -# 2200| Value = [CharLiteral] 97 -# 2200| ValueCategory = prvalue -# 2200| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2200| Type = [VoidType] void -# 2200| ValueCategory = prvalue -# 2200| getQualifier(): [VariableAccess] x +# 2194| [ConstMemberFunction,ConversionOperator] bool ClassWithDestructor::operator bool() const +# 2194| : +# 2197| [GlobalVariable] bool initialization_with_destructor_bool +# 2197| getInitializer(): [Initializer] initializer for initialization_with_destructor_bool +# 2197| getExpr(): [Literal] 1 +# 2197| Type = [BoolType] bool +# 2197| Value = [Literal] 1 +# 2197| ValueCategory = prvalue +# 2199| [TopLevelFunction] void initialization_with_destructor(bool, char) +# 2199| : +# 2199| getParameter(0): [Parameter] b +# 2199| Type = [BoolType] bool +# 2199| getParameter(1): [Parameter] c +# 2199| Type = [PlainCharType] char +# 2199| getEntryPoint(): [BlockStmt] { ... } +# 2200| getStmt(0): [IfStmt] if (...) ... +# 2200| getInitialization(): [DeclStmt] declaration +# 2200| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x # 2200| Type = [Class] ClassWithDestructor -# 2200| ValueCategory = lvalue -# 2202| getStmt(1): [ConstexprIfStmt] if constexpr (...) ... -# 2202| getInitialization(): [DeclStmt] declaration -# 2202| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x -# 2202| Type = [Class] ClassWithDestructor -# 2202| getVariable().getInitializer(): [Initializer] initializer for x -# 2202| getExpr(): [ConstructorCall] call to ClassWithDestructor -# 2202| Type = [VoidType] void -# 2202| ValueCategory = prvalue -# 2202| getCondition(): [VariableAccess] initialization_with_destructor_bool -# 2202| Type = [BoolType] bool -# 2202| Value = [VariableAccess] 1 -# 2202| ValueCategory = prvalue(load) -# 2203| getThen(): [ExprStmt] ExprStmt -# 2203| getExpr(): [FunctionCall] call to set_x -# 2203| Type = [VoidType] void -# 2203| ValueCategory = prvalue -# 2203| getQualifier(): [VariableAccess] x -# 2203| Type = [Class] ClassWithDestructor -# 2203| ValueCategory = lvalue -# 2203| getArgument(0): [CharLiteral] 97 -# 2203| Type = [PlainCharType] char -# 2203| Value = [CharLiteral] 97 -# 2203| ValueCategory = prvalue -# 2203| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2203| Type = [VoidType] void -# 2203| ValueCategory = prvalue -# 2203| getQualifier(): [VariableAccess] x +# 2200| getVariable().getInitializer(): [Initializer] initializer for x +# 2200| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2200| Type = [VoidType] void +# 2200| ValueCategory = prvalue +# 2200| getCondition(): [VariableAccess] b +# 2200| Type = [BoolType] bool +# 2200| ValueCategory = prvalue(load) +# 2201| getThen(): [ExprStmt] ExprStmt +# 2201| getExpr(): [FunctionCall] call to set_x +# 2201| Type = [VoidType] void +# 2201| ValueCategory = prvalue +# 2201| getQualifier(): [VariableAccess] x +# 2201| Type = [Class] ClassWithDestructor +# 2201| ValueCategory = lvalue +# 2201| getArgument(0): [CharLiteral] 97 +# 2201| Type = [PlainCharType] char +# 2201| Value = [CharLiteral] 97 +# 2201| ValueCategory = prvalue +# 2201| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2201| Type = [VoidType] void +# 2201| ValueCategory = prvalue +# 2201| getQualifier(): [VariableAccess] x +# 2201| Type = [Class] ClassWithDestructor +# 2201| ValueCategory = lvalue +# 2203| getStmt(1): [ConstexprIfStmt] if constexpr (...) ... +# 2203| getInitialization(): [DeclStmt] declaration +# 2203| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x # 2203| Type = [Class] ClassWithDestructor -# 2203| ValueCategory = lvalue -# 2205| getStmt(2): [SwitchStmt] switch (...) ... -# 2205| getInitialization(): [DeclStmt] declaration -# 2205| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x -# 2205| Type = [Class] ClassWithDestructor -# 2205| getVariable().getInitializer(): [Initializer] initializer for x -# 2205| getExpr(): [ConstructorCall] call to ClassWithDestructor -# 2205| Type = [VoidType] void -# 2205| ValueCategory = prvalue -# 2205| getExpr(): [VariableAccess] c -# 2205| Type = [PlainCharType] char -# 2205| ValueCategory = prvalue(load) -# 2205| getStmt(): [BlockStmt] { ... } -# 2206| getStmt(0): [SwitchCase] case ...: -# 2206| getExpr(): [CharLiteral] 97 -# 2206| Type = [PlainCharType] char -# 2206| Value = [CharLiteral] 97 -# 2206| ValueCategory = prvalue -# 2206| getExpr().getFullyConverted(): [CStyleCast] (int)... -# 2206| Conversion = [IntegralConversion] integral conversion -# 2206| Type = [IntType] int -# 2206| Value = [CStyleCast] 97 -# 2206| ValueCategory = prvalue -# 2207| getStmt(1): [ExprStmt] ExprStmt -# 2207| getExpr(): [FunctionCall] call to set_x -# 2207| Type = [VoidType] void +# 2203| getVariable().getInitializer(): [Initializer] initializer for x +# 2203| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2203| Type = [VoidType] void +# 2203| ValueCategory = prvalue +# 2203| getCondition(): [VariableAccess] initialization_with_destructor_bool +# 2203| Type = [BoolType] bool +# 2203| Value = [VariableAccess] 1 +# 2203| ValueCategory = prvalue(load) +# 2204| getThen(): [ExprStmt] ExprStmt +# 2204| getExpr(): [FunctionCall] call to set_x +# 2204| Type = [VoidType] void +# 2204| ValueCategory = prvalue +# 2204| getQualifier(): [VariableAccess] x +# 2204| Type = [Class] ClassWithDestructor +# 2204| ValueCategory = lvalue +# 2204| getArgument(0): [CharLiteral] 97 +# 2204| Type = [PlainCharType] char +# 2204| Value = [CharLiteral] 97 +# 2204| ValueCategory = prvalue +# 2204| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2204| Type = [VoidType] void +# 2204| ValueCategory = prvalue +# 2204| getQualifier(): [VariableAccess] x +# 2204| Type = [Class] ClassWithDestructor +# 2204| ValueCategory = lvalue +# 2206| getStmt(2): [SwitchStmt] switch (...) ... +# 2206| getInitialization(): [DeclStmt] declaration +# 2206| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x +# 2206| Type = [Class] ClassWithDestructor +# 2206| getVariable().getInitializer(): [Initializer] initializer for x +# 2206| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2206| Type = [VoidType] void +# 2206| ValueCategory = prvalue +# 2206| getExpr(): [VariableAccess] c +# 2206| Type = [PlainCharType] char +# 2206| ValueCategory = prvalue(load) +# 2206| getStmt(): [BlockStmt] { ... } +# 2207| getStmt(0): [SwitchCase] case ...: +# 2207| getExpr(): [CharLiteral] 97 +# 2207| Type = [PlainCharType] char +# 2207| Value = [CharLiteral] 97 # 2207| ValueCategory = prvalue -# 2207| getQualifier(): [VariableAccess] x -# 2207| Type = [Class] ClassWithDestructor -# 2207| ValueCategory = lvalue -# 2207| getArgument(0): [CharLiteral] 97 -# 2207| Type = [PlainCharType] char -# 2207| Value = [CharLiteral] 97 -# 2207| ValueCategory = prvalue -# 2208| getStmt(2): [BreakStmt] break; -# 2212| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2212| Type = [VoidType] void -# 2212| ValueCategory = prvalue -# 2212| getQualifier(): [VariableAccess] x -# 2212| Type = [Class] ClassWithDestructor -# 2212| ValueCategory = lvalue -# 2209| getStmt(3): [SwitchCase] default: -# 2210| getStmt(4): [ExprStmt] ExprStmt -# 2210| getExpr(): [FunctionCall] call to set_x -# 2210| Type = [VoidType] void -# 2210| ValueCategory = prvalue -# 2210| getQualifier(): [VariableAccess] x -# 2210| Type = [Class] ClassWithDestructor -# 2210| ValueCategory = lvalue -# 2210| getArgument(0): [CharLiteral] 98 -# 2210| Type = [PlainCharType] char -# 2210| Value = [CharLiteral] 98 -# 2210| ValueCategory = prvalue -# 2211| getStmt(5): [BreakStmt] break; -# 2212| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2212| Type = [VoidType] void -# 2212| ValueCategory = prvalue -# 2212| getQualifier(): [VariableAccess] x -# 2212| Type = [Class] ClassWithDestructor -# 2212| ValueCategory = lvalue -# 2212| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2212| Type = [VoidType] void -# 2212| ValueCategory = prvalue -# 2212| getQualifier(): [VariableAccess] x -# 2212| Type = [Class] ClassWithDestructor -# 2212| ValueCategory = lvalue -# 2205| getExpr().getFullyConverted(): [CStyleCast] (int)... -# 2205| Conversion = [IntegralConversion] integral conversion -# 2205| Type = [IntType] int -# 2205| ValueCategory = prvalue -# 2212| getStmt(3): [LabelStmt] label ...: -# 2214| getStmt(4): [DeclStmt] declaration -# 2214| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x -# 2214| Type = [Class] ClassWithDestructor -# 2214| getVariable().getInitializer(): [Initializer] initializer for x -# 2214| getExpr(): [ConstructorCall] call to ClassWithDestructor -# 2214| Type = [VoidType] void -# 2214| ValueCategory = prvalue -# 2215| getStmt(5): [RangeBasedForStmt] for(...:...) ... -# 2215| getInitialization(): [DeclStmt] declaration -# 2215| getDeclarationEntry(0): [VariableDeclarationEntry] definition of ys -# 2215| Type = [ClassTemplateInstantiation,Struct] vector -# 2215| getVariable().getInitializer(): [Initializer] initializer for ys -# 2215| getExpr(): [ConstructorCall] call to vector -# 2215| Type = [VoidType] void -# 2215| ValueCategory = prvalue -# 2215| getArgument(0): [VariableAccess] x -# 2215| Type = [Class] ClassWithDestructor -# 2215| ValueCategory = prvalue(load) -# 2215| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2215| Type = [VoidType] void -# 2215| ValueCategory = prvalue -# 2215| getQualifier(): [ReuseExpr] reuse of temporary object -# 2215| Type = [Class] ClassWithDestructor -# 2215| ValueCategory = xvalue -# 2215| getArgument(0).getFullyConverted(): [TemporaryObjectExpr] temporary object -# 2215| Type = [Class] ClassWithDestructor -# 2215| ValueCategory = lvalue -# 2215| getChild(1): [DeclStmt] declaration -# 2215| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__range) -# 2215| Type = [LValueReferenceType] vector & +# 2207| getExpr().getFullyConverted(): [CStyleCast] (int)... +# 2207| Conversion = [IntegralConversion] integral conversion +# 2207| Type = [IntType] int +# 2207| Value = [CStyleCast] 97 +# 2207| ValueCategory = prvalue +# 2208| getStmt(1): [ExprStmt] ExprStmt +# 2208| getExpr(): [FunctionCall] call to set_x +# 2208| Type = [VoidType] void +# 2208| ValueCategory = prvalue +# 2208| getQualifier(): [VariableAccess] x +# 2208| Type = [Class] ClassWithDestructor +# 2208| ValueCategory = lvalue +# 2208| getArgument(0): [CharLiteral] 97 +# 2208| Type = [PlainCharType] char +# 2208| Value = [CharLiteral] 97 +# 2208| ValueCategory = prvalue +# 2209| getStmt(2): [BreakStmt] break; +# 2213| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2213| Type = [VoidType] void +# 2213| ValueCategory = prvalue +# 2213| getQualifier(): [VariableAccess] x +# 2213| Type = [Class] ClassWithDestructor +# 2213| ValueCategory = lvalue +# 2210| getStmt(3): [SwitchCase] default: +# 2211| getStmt(4): [ExprStmt] ExprStmt +# 2211| getExpr(): [FunctionCall] call to set_x +# 2211| Type = [VoidType] void +# 2211| ValueCategory = prvalue +# 2211| getQualifier(): [VariableAccess] x +# 2211| Type = [Class] ClassWithDestructor +# 2211| ValueCategory = lvalue +# 2211| getArgument(0): [CharLiteral] 98 +# 2211| Type = [PlainCharType] char +# 2211| Value = [CharLiteral] 98 +# 2211| ValueCategory = prvalue +# 2212| getStmt(5): [BreakStmt] break; +# 2213| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2213| Type = [VoidType] void +# 2213| ValueCategory = prvalue +# 2213| getQualifier(): [VariableAccess] x +# 2213| Type = [Class] ClassWithDestructor +# 2213| ValueCategory = lvalue +# 2213| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2213| Type = [VoidType] void +# 2213| ValueCategory = prvalue +# 2213| getQualifier(): [VariableAccess] x +# 2213| Type = [Class] ClassWithDestructor +# 2213| ValueCategory = lvalue +# 2206| getExpr().getFullyConverted(): [CStyleCast] (int)... +# 2206| Conversion = [IntegralConversion] integral conversion +# 2206| Type = [IntType] int +# 2206| ValueCategory = prvalue +# 2213| getStmt(3): [LabelStmt] label ...: +# 2215| getStmt(4): [DeclStmt] declaration +# 2215| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x +# 2215| Type = [Class] ClassWithDestructor +# 2215| getVariable().getInitializer(): [Initializer] initializer for x +# 2215| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2215| Type = [VoidType] void +# 2215| ValueCategory = prvalue +# 2216| getStmt(5): [RangeBasedForStmt] for(...:...) ... +# 2216| getInitialization(): [DeclStmt] declaration +# 2216| getDeclarationEntry(0): [VariableDeclarationEntry] definition of ys +# 2216| Type = [ClassTemplateInstantiation,Struct] vector +# 2216| getVariable().getInitializer(): [Initializer] initializer for ys +# 2216| getExpr(): [ConstructorCall] call to vector +# 2216| Type = [VoidType] void +# 2216| ValueCategory = prvalue +# 2216| getArgument(0): [VariableAccess] x +# 2216| Type = [Class] ClassWithDestructor +# 2216| ValueCategory = prvalue(load) +# 2216| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2216| Type = [VoidType] void +# 2216| ValueCategory = prvalue +# 2216| getQualifier(): [ReuseExpr] reuse of temporary object +# 2216| Type = [Class] ClassWithDestructor +# 2216| ValueCategory = xvalue +# 2216| getArgument(0).getFullyConverted(): [TemporaryObjectExpr] temporary object +# 2216| Type = [Class] ClassWithDestructor +# 2216| ValueCategory = lvalue +# 2216| getChild(1): [DeclStmt] declaration +# 2216| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__range) +# 2216| Type = [LValueReferenceType] vector & #-----| getVariable().getInitializer(): [Initializer] initializer for (__range) -# 2215| getExpr(): [VariableAccess] ys -# 2215| Type = [ClassTemplateInstantiation,Struct] vector -# 2215| ValueCategory = lvalue -# 2215| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to) -# 2215| Type = [LValueReferenceType] vector & -# 2215| ValueCategory = prvalue -# 2215| getBeginEndDeclaration(): [DeclStmt] declaration -# 2215| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__begin) -# 2215| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2216| getExpr(): [VariableAccess] ys +# 2216| Type = [ClassTemplateInstantiation,Struct] vector +# 2216| ValueCategory = lvalue +# 2216| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to) +# 2216| Type = [LValueReferenceType] vector & +# 2216| ValueCategory = prvalue +# 2216| getBeginEndDeclaration(): [DeclStmt] declaration +# 2216| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__begin) +# 2216| Type = [NestedTypedefType,UsingAliasTypedefType] iterator #-----| getVariable().getInitializer(): [Initializer] initializer for (__begin) -# 2215| getExpr(): [FunctionCall] call to begin -# 2215| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2215| ValueCategory = prvalue -# 2215| getQualifier(): [VariableAccess] (__range) -# 2215| Type = [LValueReferenceType] vector & -# 2215| ValueCategory = prvalue(load) +# 2216| getExpr(): [FunctionCall] call to begin +# 2216| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2216| ValueCategory = prvalue +# 2216| getQualifier(): [VariableAccess] (__range) +# 2216| Type = [LValueReferenceType] vector & +# 2216| ValueCategory = prvalue(load) #-----| getQualifier().getFullyConverted(): [CStyleCast] (const vector)... #-----| Conversion = [GlvalueConversion] glvalue conversion #-----| Type = [SpecifiedType] const vector @@ -19505,15 +19507,15 @@ ir.cpp: #-----| getExpr(): [ReferenceDereferenceExpr] (reference dereference) #-----| Type = [ClassTemplateInstantiation,Struct] vector #-----| ValueCategory = lvalue -# 2215| getDeclarationEntry(1): [VariableDeclarationEntry] declaration of (__end) -# 2215| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2216| getDeclarationEntry(1): [VariableDeclarationEntry] declaration of (__end) +# 2216| Type = [NestedTypedefType,UsingAliasTypedefType] iterator #-----| getVariable().getInitializer(): [Initializer] initializer for (__end) -# 2215| getExpr(): [FunctionCall] call to end -# 2215| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2215| ValueCategory = prvalue -# 2215| getQualifier(): [VariableAccess] (__range) -# 2215| Type = [LValueReferenceType] vector & -# 2215| ValueCategory = prvalue(load) +# 2216| getExpr(): [FunctionCall] call to end +# 2216| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2216| ValueCategory = prvalue +# 2216| getQualifier(): [VariableAccess] (__range) +# 2216| Type = [LValueReferenceType] vector & +# 2216| ValueCategory = prvalue(load) #-----| getQualifier().getFullyConverted(): [CStyleCast] (const vector)... #-----| Conversion = [GlvalueConversion] glvalue conversion #-----| Type = [SpecifiedType] const vector @@ -19521,18 +19523,18 @@ ir.cpp: #-----| getExpr(): [ReferenceDereferenceExpr] (reference dereference) #-----| Type = [ClassTemplateInstantiation,Struct] vector #-----| ValueCategory = lvalue -# 2215| getCondition(): [FunctionCall] call to operator!= -# 2215| Type = [BoolType] bool -# 2215| ValueCategory = prvalue -# 2215| getQualifier(): [VariableAccess] (__begin) -# 2215| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2215| ValueCategory = lvalue -# 2215| getArgument(0): [ConstructorCall] call to iterator -# 2215| Type = [VoidType] void -# 2215| ValueCategory = prvalue -# 2215| getArgument(0): [VariableAccess] (__end) -# 2215| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2215| ValueCategory = lvalue +# 2216| getCondition(): [FunctionCall] call to operator!= +# 2216| Type = [BoolType] bool +# 2216| ValueCategory = prvalue +# 2216| getQualifier(): [VariableAccess] (__begin) +# 2216| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2216| ValueCategory = lvalue +# 2216| getArgument(0): [ConstructorCall] call to iterator +# 2216| Type = [VoidType] void +# 2216| ValueCategory = prvalue +# 2216| getArgument(0): [VariableAccess] (__end) +# 2216| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2216| ValueCategory = lvalue #-----| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to) #-----| Type = [LValueReferenceType] const iterator & #-----| ValueCategory = prvalue @@ -19547,95 +19549,95 @@ ir.cpp: #-----| getArgument(0).getFullyConverted(): [TemporaryObjectExpr] temporary object #-----| Type = [ClassTemplateInstantiation,Struct] iterator #-----| ValueCategory = lvalue -# 2215| getUpdate(): [FunctionCall] call to operator++ -# 2215| Type = [LValueReferenceType] iterator & -# 2215| ValueCategory = prvalue -# 2215| getQualifier(): [VariableAccess] (__begin) -# 2215| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2215| ValueCategory = lvalue -# 2215| getChild(5): [DeclStmt] declaration -# 2215| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y -# 2215| Type = [Class] ClassWithDestructor -# 2215| getVariable().getInitializer(): [Initializer] initializer for y -# 2215| getExpr(): [OverloadedPointerDereferenceExpr] call to operator* -# 2215| Type = [LValueReferenceType] ClassWithDestructor & -# 2215| ValueCategory = prvalue -# 2215| getQualifier(): [VariableAccess] (__begin) -# 2215| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2215| ValueCategory = lvalue +# 2216| getUpdate(): [FunctionCall] call to operator++ +# 2216| Type = [LValueReferenceType] iterator & +# 2216| ValueCategory = prvalue +# 2216| getQualifier(): [VariableAccess] (__begin) +# 2216| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2216| ValueCategory = lvalue +# 2216| getChild(5): [DeclStmt] declaration +# 2216| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y +# 2216| Type = [Class] ClassWithDestructor +# 2216| getVariable().getInitializer(): [Initializer] initializer for y +# 2216| getExpr(): [OverloadedPointerDereferenceExpr] call to operator* +# 2216| Type = [LValueReferenceType] ClassWithDestructor & +# 2216| ValueCategory = prvalue +# 2216| getQualifier(): [VariableAccess] (__begin) +# 2216| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2216| ValueCategory = lvalue #-----| getQualifier().getFullyConverted(): [CStyleCast] (const iterator)... #-----| Conversion = [GlvalueConversion] glvalue conversion #-----| Type = [SpecifiedType] const iterator #-----| ValueCategory = lvalue -# 2215| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) -# 2215| Type = [Class] ClassWithDestructor -# 2215| ValueCategory = prvalue(load) -# 2216| getStmt(): [ExprStmt] ExprStmt -# 2216| getExpr(): [FunctionCall] call to set_x +# 2216| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) +# 2216| Type = [Class] ClassWithDestructor +# 2216| ValueCategory = prvalue(load) +# 2217| getStmt(): [ExprStmt] ExprStmt +# 2217| getExpr(): [FunctionCall] call to set_x +# 2217| Type = [VoidType] void +# 2217| ValueCategory = prvalue +# 2217| getQualifier(): [VariableAccess] y +# 2217| Type = [Class] ClassWithDestructor +# 2217| ValueCategory = lvalue +# 2217| getArgument(0): [CharLiteral] 97 +# 2217| Type = [PlainCharType] char +# 2217| Value = [CharLiteral] 97 +# 2217| ValueCategory = prvalue +# 2216| getImplicitDestructorCall(0): [DestructorCall] call to ~vector +# 2216| Type = [VoidType] void +# 2216| ValueCategory = prvalue +# 2216| getQualifier(): [VariableAccess] ys +# 2216| Type = [ClassTemplateInstantiation,Struct] vector +# 2216| ValueCategory = lvalue +# 2216| getUpdate().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) +# 2216| Type = [ClassTemplateInstantiation,Struct] iterator +# 2216| ValueCategory = lvalue +# 2216| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor # 2216| Type = [VoidType] void # 2216| ValueCategory = prvalue # 2216| getQualifier(): [VariableAccess] y # 2216| Type = [Class] ClassWithDestructor # 2216| ValueCategory = lvalue -# 2216| getArgument(0): [CharLiteral] 97 -# 2216| Type = [PlainCharType] char -# 2216| Value = [CharLiteral] 97 -# 2216| ValueCategory = prvalue -# 2215| getImplicitDestructorCall(0): [DestructorCall] call to ~vector -# 2215| Type = [VoidType] void -# 2215| ValueCategory = prvalue -# 2215| getQualifier(): [VariableAccess] ys -# 2215| Type = [ClassTemplateInstantiation,Struct] vector -# 2215| ValueCategory = lvalue -# 2215| getUpdate().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) -# 2215| Type = [ClassTemplateInstantiation,Struct] iterator -# 2215| ValueCategory = lvalue -# 2215| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2215| Type = [VoidType] void -# 2215| ValueCategory = prvalue -# 2215| getQualifier(): [VariableAccess] y -# 2215| Type = [Class] ClassWithDestructor -# 2215| ValueCategory = lvalue -# 2218| getStmt(6): [RangeBasedForStmt] for(...:...) ... -# 2218| getInitialization(): [DeclStmt] declaration -# 2218| getDeclarationEntry(0): [VariableDeclarationEntry] definition of ys -# 2218| Type = [ClassTemplateInstantiation,Struct] vector -# 2218| getVariable().getInitializer(): [Initializer] initializer for ys -# 2218| getExpr(): [ConstructorCall] call to vector -# 2218| Type = [VoidType] void -# 2218| ValueCategory = prvalue -# 2218| getArgument(0): [VariableAccess] x -# 2218| Type = [Class] ClassWithDestructor -# 2218| ValueCategory = prvalue(load) -# 2218| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2218| Type = [VoidType] void -# 2218| ValueCategory = prvalue -# 2218| getQualifier(): [ReuseExpr] reuse of temporary object -# 2218| Type = [Class] ClassWithDestructor -# 2218| ValueCategory = xvalue -# 2218| getArgument(0).getFullyConverted(): [TemporaryObjectExpr] temporary object -# 2218| Type = [Class] ClassWithDestructor -# 2218| ValueCategory = lvalue -# 2218| getChild(1): [DeclStmt] declaration -# 2218| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__range) -# 2218| Type = [LValueReferenceType] vector & +# 2219| getStmt(6): [RangeBasedForStmt] for(...:...) ... +# 2219| getInitialization(): [DeclStmt] declaration +# 2219| getDeclarationEntry(0): [VariableDeclarationEntry] definition of ys +# 2219| Type = [ClassTemplateInstantiation,Struct] vector +# 2219| getVariable().getInitializer(): [Initializer] initializer for ys +# 2219| getExpr(): [ConstructorCall] call to vector +# 2219| Type = [VoidType] void +# 2219| ValueCategory = prvalue +# 2219| getArgument(0): [VariableAccess] x +# 2219| Type = [Class] ClassWithDestructor +# 2219| ValueCategory = prvalue(load) +# 2219| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2219| Type = [VoidType] void +# 2219| ValueCategory = prvalue +# 2219| getQualifier(): [ReuseExpr] reuse of temporary object +# 2219| Type = [Class] ClassWithDestructor +# 2219| ValueCategory = xvalue +# 2219| getArgument(0).getFullyConverted(): [TemporaryObjectExpr] temporary object +# 2219| Type = [Class] ClassWithDestructor +# 2219| ValueCategory = lvalue +# 2219| getChild(1): [DeclStmt] declaration +# 2219| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__range) +# 2219| Type = [LValueReferenceType] vector & #-----| getVariable().getInitializer(): [Initializer] initializer for (__range) -# 2218| getExpr(): [VariableAccess] ys -# 2218| Type = [ClassTemplateInstantiation,Struct] vector -# 2218| ValueCategory = lvalue -# 2218| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to) -# 2218| Type = [LValueReferenceType] vector & -# 2218| ValueCategory = prvalue -# 2218| getBeginEndDeclaration(): [DeclStmt] declaration -# 2218| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__begin) -# 2218| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2219| getExpr(): [VariableAccess] ys +# 2219| Type = [ClassTemplateInstantiation,Struct] vector +# 2219| ValueCategory = lvalue +# 2219| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to) +# 2219| Type = [LValueReferenceType] vector & +# 2219| ValueCategory = prvalue +# 2219| getBeginEndDeclaration(): [DeclStmt] declaration +# 2219| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__begin) +# 2219| Type = [NestedTypedefType,UsingAliasTypedefType] iterator #-----| getVariable().getInitializer(): [Initializer] initializer for (__begin) -# 2218| getExpr(): [FunctionCall] call to begin -# 2218| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2218| ValueCategory = prvalue -# 2218| getQualifier(): [VariableAccess] (__range) -# 2218| Type = [LValueReferenceType] vector & -# 2218| ValueCategory = prvalue(load) +# 2219| getExpr(): [FunctionCall] call to begin +# 2219| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2219| ValueCategory = prvalue +# 2219| getQualifier(): [VariableAccess] (__range) +# 2219| Type = [LValueReferenceType] vector & +# 2219| ValueCategory = prvalue(load) #-----| getQualifier().getFullyConverted(): [CStyleCast] (const vector)... #-----| Conversion = [GlvalueConversion] glvalue conversion #-----| Type = [SpecifiedType] const vector @@ -19643,15 +19645,15 @@ ir.cpp: #-----| getExpr(): [ReferenceDereferenceExpr] (reference dereference) #-----| Type = [ClassTemplateInstantiation,Struct] vector #-----| ValueCategory = lvalue -# 2218| getDeclarationEntry(1): [VariableDeclarationEntry] declaration of (__end) -# 2218| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2219| getDeclarationEntry(1): [VariableDeclarationEntry] declaration of (__end) +# 2219| Type = [NestedTypedefType,UsingAliasTypedefType] iterator #-----| getVariable().getInitializer(): [Initializer] initializer for (__end) -# 2218| getExpr(): [FunctionCall] call to end -# 2218| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2218| ValueCategory = prvalue -# 2218| getQualifier(): [VariableAccess] (__range) -# 2218| Type = [LValueReferenceType] vector & -# 2218| ValueCategory = prvalue(load) +# 2219| getExpr(): [FunctionCall] call to end +# 2219| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2219| ValueCategory = prvalue +# 2219| getQualifier(): [VariableAccess] (__range) +# 2219| Type = [LValueReferenceType] vector & +# 2219| ValueCategory = prvalue(load) #-----| getQualifier().getFullyConverted(): [CStyleCast] (const vector)... #-----| Conversion = [GlvalueConversion] glvalue conversion #-----| Type = [SpecifiedType] const vector @@ -19659,18 +19661,18 @@ ir.cpp: #-----| getExpr(): [ReferenceDereferenceExpr] (reference dereference) #-----| Type = [ClassTemplateInstantiation,Struct] vector #-----| ValueCategory = lvalue -# 2218| getCondition(): [FunctionCall] call to operator!= -# 2218| Type = [BoolType] bool -# 2218| ValueCategory = prvalue -# 2218| getQualifier(): [VariableAccess] (__begin) -# 2218| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2218| ValueCategory = lvalue -# 2218| getArgument(0): [ConstructorCall] call to iterator -# 2218| Type = [VoidType] void -# 2218| ValueCategory = prvalue -# 2218| getArgument(0): [VariableAccess] (__end) -# 2218| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2218| ValueCategory = lvalue +# 2219| getCondition(): [FunctionCall] call to operator!= +# 2219| Type = [BoolType] bool +# 2219| ValueCategory = prvalue +# 2219| getQualifier(): [VariableAccess] (__begin) +# 2219| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2219| ValueCategory = lvalue +# 2219| getArgument(0): [ConstructorCall] call to iterator +# 2219| Type = [VoidType] void +# 2219| ValueCategory = prvalue +# 2219| getArgument(0): [VariableAccess] (__end) +# 2219| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2219| ValueCategory = lvalue #-----| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to) #-----| Type = [LValueReferenceType] const iterator & #-----| ValueCategory = prvalue @@ -19685,130 +19687,130 @@ ir.cpp: #-----| getArgument(0).getFullyConverted(): [TemporaryObjectExpr] temporary object #-----| Type = [ClassTemplateInstantiation,Struct] iterator #-----| ValueCategory = lvalue -# 2218| getUpdate(): [FunctionCall] call to operator++ -# 2218| Type = [LValueReferenceType] iterator & -# 2218| ValueCategory = prvalue -# 2218| getQualifier(): [VariableAccess] (__begin) -# 2218| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2218| ValueCategory = lvalue -# 2218| getChild(5): [DeclStmt] declaration -# 2218| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y -# 2218| Type = [Class] ClassWithDestructor -# 2218| getVariable().getInitializer(): [Initializer] initializer for y -# 2218| getExpr(): [OverloadedPointerDereferenceExpr] call to operator* -# 2218| Type = [LValueReferenceType] ClassWithDestructor & -# 2218| ValueCategory = prvalue -# 2218| getQualifier(): [VariableAccess] (__begin) -# 2218| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2218| ValueCategory = lvalue +# 2219| getUpdate(): [FunctionCall] call to operator++ +# 2219| Type = [LValueReferenceType] iterator & +# 2219| ValueCategory = prvalue +# 2219| getQualifier(): [VariableAccess] (__begin) +# 2219| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2219| ValueCategory = lvalue +# 2219| getChild(5): [DeclStmt] declaration +# 2219| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y +# 2219| Type = [Class] ClassWithDestructor +# 2219| getVariable().getInitializer(): [Initializer] initializer for y +# 2219| getExpr(): [OverloadedPointerDereferenceExpr] call to operator* +# 2219| Type = [LValueReferenceType] ClassWithDestructor & +# 2219| ValueCategory = prvalue +# 2219| getQualifier(): [VariableAccess] (__begin) +# 2219| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2219| ValueCategory = lvalue #-----| getQualifier().getFullyConverted(): [CStyleCast] (const iterator)... #-----| Conversion = [GlvalueConversion] glvalue conversion #-----| Type = [SpecifiedType] const iterator #-----| ValueCategory = lvalue -# 2218| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) -# 2218| Type = [Class] ClassWithDestructor -# 2218| ValueCategory = prvalue(load) -# 2218| getStmt(): [BlockStmt] { ... } -# 2219| getStmt(0): [ExprStmt] ExprStmt -# 2219| getExpr(): [FunctionCall] call to set_x -# 2219| Type = [VoidType] void -# 2219| ValueCategory = prvalue -# 2219| getQualifier(): [VariableAccess] y +# 2219| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) # 2219| Type = [Class] ClassWithDestructor -# 2219| ValueCategory = lvalue -# 2219| getArgument(0): [CharLiteral] 97 -# 2219| Type = [PlainCharType] char -# 2219| Value = [CharLiteral] 97 -# 2219| ValueCategory = prvalue -# 2220| getStmt(1): [IfStmt] if (...) ... -# 2220| getCondition(): [EQExpr] ... == ... -# 2220| Type = [BoolType] bool +# 2219| ValueCategory = prvalue(load) +# 2219| getStmt(): [BlockStmt] { ... } +# 2220| getStmt(0): [ExprStmt] ExprStmt +# 2220| getExpr(): [FunctionCall] call to set_x +# 2220| Type = [VoidType] void # 2220| ValueCategory = prvalue -# 2220| getLeftOperand(): [FunctionCall] call to get_x +# 2220| getQualifier(): [VariableAccess] y +# 2220| Type = [Class] ClassWithDestructor +# 2220| ValueCategory = lvalue +# 2220| getArgument(0): [CharLiteral] 97 # 2220| Type = [PlainCharType] char +# 2220| Value = [CharLiteral] 97 # 2220| ValueCategory = prvalue -# 2220| getQualifier(): [VariableAccess] y -# 2220| Type = [Class] ClassWithDestructor -# 2220| ValueCategory = lvalue -# 2220| getRightOperand(): [CharLiteral] 98 -# 2220| Type = [PlainCharType] char -# 2220| Value = [CharLiteral] 98 -# 2220| ValueCategory = prvalue -# 2220| getLeftOperand().getFullyConverted(): [CStyleCast] (int)... -# 2220| Conversion = [IntegralConversion] integral conversion -# 2220| Type = [IntType] int -# 2220| ValueCategory = prvalue -# 2220| getRightOperand().getFullyConverted(): [CStyleCast] (int)... -# 2220| Conversion = [IntegralConversion] integral conversion -# 2220| Type = [IntType] int -# 2220| Value = [CStyleCast] 98 -# 2220| ValueCategory = prvalue -# 2221| getThen(): [ReturnStmt] return ... -# 2218| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2218| Type = [VoidType] void -# 2218| ValueCategory = prvalue -# 2218| getQualifier(): [VariableAccess] y -# 2218| Type = [Class] ClassWithDestructor -# 2218| ValueCategory = lvalue -# 2218| getImplicitDestructorCall(1): [DestructorCall] call to ~vector -# 2218| Type = [VoidType] void -# 2218| ValueCategory = prvalue -# 2218| getQualifier(): [VariableAccess] ys -# 2218| Type = [ClassTemplateInstantiation,Struct] vector -# 2218| ValueCategory = lvalue -# 2233| getImplicitDestructorCall(2): [DestructorCall] call to ~ClassWithDestructor -# 2233| Type = [VoidType] void -# 2233| ValueCategory = prvalue -# 2233| getQualifier(): [VariableAccess] x -# 2233| Type = [Class] ClassWithDestructor -# 2233| ValueCategory = lvalue -# 2218| getImplicitDestructorCall(0): [DestructorCall] call to ~vector -# 2218| Type = [VoidType] void -# 2218| ValueCategory = prvalue -# 2218| getQualifier(): [VariableAccess] ys -# 2218| Type = [ClassTemplateInstantiation,Struct] vector -# 2218| ValueCategory = lvalue -# 2218| getUpdate().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) -# 2218| Type = [ClassTemplateInstantiation,Struct] iterator -# 2218| ValueCategory = lvalue -# 2218| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2218| Type = [VoidType] void -# 2218| ValueCategory = prvalue -# 2218| getQualifier(): [VariableAccess] y -# 2218| Type = [Class] ClassWithDestructor -# 2218| ValueCategory = lvalue -# 2224| getStmt(7): [RangeBasedForStmt] for(...:...) ... -# 2224| getInitialization(): [DeclStmt] declaration -# 2224| getDeclarationEntry(0): [VariableDeclarationEntry] definition of ys -# 2224| Type = [ClassTemplateInstantiation,Struct] vector -# 2224| getVariable().getInitializer(): [Initializer] initializer for ys -# 2224| getExpr(): [ConstructorCall] call to vector -# 2224| Type = [VoidType] void -# 2224| ValueCategory = prvalue -# 2224| getArgument(0): [Literal] 1 -# 2224| Type = [IntType] int -# 2224| Value = [Literal] 1 -# 2224| ValueCategory = prvalue -# 2224| getChild(1): [DeclStmt] declaration -# 2224| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__range) -# 2224| Type = [LValueReferenceType] vector & +# 2221| getStmt(1): [IfStmt] if (...) ... +# 2221| getCondition(): [EQExpr] ... == ... +# 2221| Type = [BoolType] bool +# 2221| ValueCategory = prvalue +# 2221| getLeftOperand(): [FunctionCall] call to get_x +# 2221| Type = [PlainCharType] char +# 2221| ValueCategory = prvalue +# 2221| getQualifier(): [VariableAccess] y +# 2221| Type = [Class] ClassWithDestructor +# 2221| ValueCategory = lvalue +# 2221| getRightOperand(): [CharLiteral] 98 +# 2221| Type = [PlainCharType] char +# 2221| Value = [CharLiteral] 98 +# 2221| ValueCategory = prvalue +# 2221| getLeftOperand().getFullyConverted(): [CStyleCast] (int)... +# 2221| Conversion = [IntegralConversion] integral conversion +# 2221| Type = [IntType] int +# 2221| ValueCategory = prvalue +# 2221| getRightOperand().getFullyConverted(): [CStyleCast] (int)... +# 2221| Conversion = [IntegralConversion] integral conversion +# 2221| Type = [IntType] int +# 2221| Value = [CStyleCast] 98 +# 2221| ValueCategory = prvalue +# 2222| getThen(): [ReturnStmt] return ... +# 2219| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2219| Type = [VoidType] void +# 2219| ValueCategory = prvalue +# 2219| getQualifier(): [VariableAccess] y +# 2219| Type = [Class] ClassWithDestructor +# 2219| ValueCategory = lvalue +# 2219| getImplicitDestructorCall(1): [DestructorCall] call to ~vector +# 2219| Type = [VoidType] void +# 2219| ValueCategory = prvalue +# 2219| getQualifier(): [VariableAccess] ys +# 2219| Type = [ClassTemplateInstantiation,Struct] vector +# 2219| ValueCategory = lvalue +# 2234| getImplicitDestructorCall(2): [DestructorCall] call to ~ClassWithDestructor +# 2234| Type = [VoidType] void +# 2234| ValueCategory = prvalue +# 2234| getQualifier(): [VariableAccess] x +# 2234| Type = [Class] ClassWithDestructor +# 2234| ValueCategory = lvalue +# 2219| getImplicitDestructorCall(0): [DestructorCall] call to ~vector +# 2219| Type = [VoidType] void +# 2219| ValueCategory = prvalue +# 2219| getQualifier(): [VariableAccess] ys +# 2219| Type = [ClassTemplateInstantiation,Struct] vector +# 2219| ValueCategory = lvalue +# 2219| getUpdate().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) +# 2219| Type = [ClassTemplateInstantiation,Struct] iterator +# 2219| ValueCategory = lvalue +# 2219| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2219| Type = [VoidType] void +# 2219| ValueCategory = prvalue +# 2219| getQualifier(): [VariableAccess] y +# 2219| Type = [Class] ClassWithDestructor +# 2219| ValueCategory = lvalue +# 2225| getStmt(7): [RangeBasedForStmt] for(...:...) ... +# 2225| getInitialization(): [DeclStmt] declaration +# 2225| getDeclarationEntry(0): [VariableDeclarationEntry] definition of ys +# 2225| Type = [ClassTemplateInstantiation,Struct] vector +# 2225| getVariable().getInitializer(): [Initializer] initializer for ys +# 2225| getExpr(): [ConstructorCall] call to vector +# 2225| Type = [VoidType] void +# 2225| ValueCategory = prvalue +# 2225| getArgument(0): [Literal] 1 +# 2225| Type = [IntType] int +# 2225| Value = [Literal] 1 +# 2225| ValueCategory = prvalue +# 2225| getChild(1): [DeclStmt] declaration +# 2225| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__range) +# 2225| Type = [LValueReferenceType] vector & #-----| getVariable().getInitializer(): [Initializer] initializer for (__range) -# 2224| getExpr(): [VariableAccess] ys -# 2224| Type = [ClassTemplateInstantiation,Struct] vector -# 2224| ValueCategory = lvalue -# 2224| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to) -# 2224| Type = [LValueReferenceType] vector & -# 2224| ValueCategory = prvalue -# 2224| getBeginEndDeclaration(): [DeclStmt] declaration -# 2224| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__begin) -# 2224| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2225| getExpr(): [VariableAccess] ys +# 2225| Type = [ClassTemplateInstantiation,Struct] vector +# 2225| ValueCategory = lvalue +# 2225| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to) +# 2225| Type = [LValueReferenceType] vector & +# 2225| ValueCategory = prvalue +# 2225| getBeginEndDeclaration(): [DeclStmt] declaration +# 2225| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__begin) +# 2225| Type = [NestedTypedefType,UsingAliasTypedefType] iterator #-----| getVariable().getInitializer(): [Initializer] initializer for (__begin) -# 2224| getExpr(): [FunctionCall] call to begin -# 2224| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2224| ValueCategory = prvalue -# 2224| getQualifier(): [VariableAccess] (__range) -# 2224| Type = [LValueReferenceType] vector & -# 2224| ValueCategory = prvalue(load) +# 2225| getExpr(): [FunctionCall] call to begin +# 2225| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2225| ValueCategory = prvalue +# 2225| getQualifier(): [VariableAccess] (__range) +# 2225| Type = [LValueReferenceType] vector & +# 2225| ValueCategory = prvalue(load) #-----| getQualifier().getFullyConverted(): [CStyleCast] (const vector)... #-----| Conversion = [GlvalueConversion] glvalue conversion #-----| Type = [SpecifiedType] const vector @@ -19816,15 +19818,15 @@ ir.cpp: #-----| getExpr(): [ReferenceDereferenceExpr] (reference dereference) #-----| Type = [ClassTemplateInstantiation,Struct] vector #-----| ValueCategory = lvalue -# 2224| getDeclarationEntry(1): [VariableDeclarationEntry] declaration of (__end) -# 2224| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2225| getDeclarationEntry(1): [VariableDeclarationEntry] declaration of (__end) +# 2225| Type = [NestedTypedefType,UsingAliasTypedefType] iterator #-----| getVariable().getInitializer(): [Initializer] initializer for (__end) -# 2224| getExpr(): [FunctionCall] call to end -# 2224| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2224| ValueCategory = prvalue -# 2224| getQualifier(): [VariableAccess] (__range) -# 2224| Type = [LValueReferenceType] vector & -# 2224| ValueCategory = prvalue(load) +# 2225| getExpr(): [FunctionCall] call to end +# 2225| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2225| ValueCategory = prvalue +# 2225| getQualifier(): [VariableAccess] (__range) +# 2225| Type = [LValueReferenceType] vector & +# 2225| ValueCategory = prvalue(load) #-----| getQualifier().getFullyConverted(): [CStyleCast] (const vector)... #-----| Conversion = [GlvalueConversion] glvalue conversion #-----| Type = [SpecifiedType] const vector @@ -19832,18 +19834,18 @@ ir.cpp: #-----| getExpr(): [ReferenceDereferenceExpr] (reference dereference) #-----| Type = [ClassTemplateInstantiation,Struct] vector #-----| ValueCategory = lvalue -# 2224| getCondition(): [FunctionCall] call to operator!= -# 2224| Type = [BoolType] bool -# 2224| ValueCategory = prvalue -# 2224| getQualifier(): [VariableAccess] (__begin) -# 2224| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2224| ValueCategory = lvalue -# 2224| getArgument(0): [ConstructorCall] call to iterator -# 2224| Type = [VoidType] void -# 2224| ValueCategory = prvalue -# 2224| getArgument(0): [VariableAccess] (__end) -# 2224| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2224| ValueCategory = lvalue +# 2225| getCondition(): [FunctionCall] call to operator!= +# 2225| Type = [BoolType] bool +# 2225| ValueCategory = prvalue +# 2225| getQualifier(): [VariableAccess] (__begin) +# 2225| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2225| ValueCategory = lvalue +# 2225| getArgument(0): [ConstructorCall] call to iterator +# 2225| Type = [VoidType] void +# 2225| ValueCategory = prvalue +# 2225| getArgument(0): [VariableAccess] (__end) +# 2225| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2225| ValueCategory = lvalue #-----| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to) #-----| Type = [LValueReferenceType] const iterator & #-----| ValueCategory = prvalue @@ -19858,103 +19860,103 @@ ir.cpp: #-----| getArgument(0).getFullyConverted(): [TemporaryObjectExpr] temporary object #-----| Type = [ClassTemplateInstantiation,Struct] iterator #-----| ValueCategory = lvalue -# 2224| getUpdate(): [FunctionCall] call to operator++ -# 2224| Type = [LValueReferenceType] iterator & -# 2224| ValueCategory = prvalue -# 2224| getQualifier(): [VariableAccess] (__begin) -# 2224| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2224| ValueCategory = lvalue -# 2224| getChild(5): [DeclStmt] declaration -# 2224| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y -# 2224| Type = [IntType] int -# 2224| getVariable().getInitializer(): [Initializer] initializer for y -# 2224| getExpr(): [OverloadedPointerDereferenceExpr] call to operator* -# 2224| Type = [LValueReferenceType] int & -# 2224| ValueCategory = prvalue -# 2224| getQualifier(): [VariableAccess] (__begin) -# 2224| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2224| ValueCategory = lvalue +# 2225| getUpdate(): [FunctionCall] call to operator++ +# 2225| Type = [LValueReferenceType] iterator & +# 2225| ValueCategory = prvalue +# 2225| getQualifier(): [VariableAccess] (__begin) +# 2225| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2225| ValueCategory = lvalue +# 2225| getChild(5): [DeclStmt] declaration +# 2225| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y +# 2225| Type = [IntType] int +# 2225| getVariable().getInitializer(): [Initializer] initializer for y +# 2225| getExpr(): [OverloadedPointerDereferenceExpr] call to operator* +# 2225| Type = [LValueReferenceType] int & +# 2225| ValueCategory = prvalue +# 2225| getQualifier(): [VariableAccess] (__begin) +# 2225| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2225| ValueCategory = lvalue #-----| getQualifier().getFullyConverted(): [CStyleCast] (const iterator)... #-----| Conversion = [GlvalueConversion] glvalue conversion #-----| Type = [SpecifiedType] const iterator #-----| ValueCategory = lvalue -# 2224| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) -# 2224| Type = [IntType] int -# 2224| ValueCategory = prvalue(load) -# 2224| getStmt(): [BlockStmt] { ... } -# 2225| getStmt(0): [IfStmt] if (...) ... -# 2225| getCondition(): [EQExpr] ... == ... -# 2225| Type = [BoolType] bool -# 2225| ValueCategory = prvalue -# 2225| getLeftOperand(): [VariableAccess] y +# 2225| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) # 2225| Type = [IntType] int # 2225| ValueCategory = prvalue(load) -# 2225| getRightOperand(): [Literal] 1 -# 2225| Type = [IntType] int -# 2225| Value = [Literal] 1 +# 2225| getStmt(): [BlockStmt] { ... } +# 2226| getStmt(0): [IfStmt] if (...) ... +# 2226| getCondition(): [EQExpr] ... == ... +# 2226| Type = [BoolType] bool +# 2226| ValueCategory = prvalue +# 2226| getLeftOperand(): [VariableAccess] y +# 2226| Type = [IntType] int +# 2226| ValueCategory = prvalue(load) +# 2226| getRightOperand(): [Literal] 1 +# 2226| Type = [IntType] int +# 2226| Value = [Literal] 1 +# 2226| ValueCategory = prvalue +# 2227| getThen(): [ReturnStmt] return ... +# 2225| getImplicitDestructorCall(0): [DestructorCall] call to ~vector +# 2225| Type = [VoidType] void # 2225| ValueCategory = prvalue -# 2226| getThen(): [ReturnStmt] return ... -# 2224| getImplicitDestructorCall(0): [DestructorCall] call to ~vector -# 2224| Type = [VoidType] void -# 2224| ValueCategory = prvalue -# 2224| getQualifier(): [VariableAccess] ys -# 2224| Type = [ClassTemplateInstantiation,Struct] vector -# 2224| ValueCategory = lvalue -# 2233| getImplicitDestructorCall(1): [DestructorCall] call to ~ClassWithDestructor -# 2233| Type = [VoidType] void -# 2233| ValueCategory = prvalue -# 2233| getQualifier(): [VariableAccess] x -# 2233| Type = [Class] ClassWithDestructor -# 2233| ValueCategory = lvalue -# 2224| getImplicitDestructorCall(0): [DestructorCall] call to ~vector -# 2224| Type = [VoidType] void -# 2224| ValueCategory = prvalue -# 2224| getQualifier(): [VariableAccess] ys -# 2224| Type = [ClassTemplateInstantiation,Struct] vector -# 2224| ValueCategory = lvalue -# 2224| getUpdate().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) -# 2224| Type = [ClassTemplateInstantiation,Struct] iterator -# 2224| ValueCategory = lvalue -# 2229| getStmt(8): [RangeBasedForStmt] for(...:...) ... -# 2229| getInitialization(): [DeclStmt] declaration -# 2229| getDeclarationEntry(0): [VariableDeclarationEntry] definition of ys -# 2229| Type = [ClassTemplateInstantiation,Struct] vector -# 2229| getVariable().getInitializer(): [Initializer] initializer for ys -# 2229| getExpr(): [ConstructorCall] call to vector -# 2229| Type = [VoidType] void -# 2229| ValueCategory = prvalue -# 2229| getArgument(0): [VariableAccess] x -# 2229| Type = [Class] ClassWithDestructor -# 2229| ValueCategory = prvalue(load) -# 2229| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2229| Type = [VoidType] void -# 2229| ValueCategory = prvalue -# 2229| getQualifier(): [ReuseExpr] reuse of temporary object -# 2229| Type = [Class] ClassWithDestructor -# 2229| ValueCategory = xvalue -# 2229| getArgument(0).getFullyConverted(): [TemporaryObjectExpr] temporary object -# 2229| Type = [Class] ClassWithDestructor -# 2229| ValueCategory = lvalue -# 2229| getChild(1): [DeclStmt] declaration -# 2229| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__range) -# 2229| Type = [LValueReferenceType] vector & +# 2225| getQualifier(): [VariableAccess] ys +# 2225| Type = [ClassTemplateInstantiation,Struct] vector +# 2225| ValueCategory = lvalue +# 2234| getImplicitDestructorCall(1): [DestructorCall] call to ~ClassWithDestructor +# 2234| Type = [VoidType] void +# 2234| ValueCategory = prvalue +# 2234| getQualifier(): [VariableAccess] x +# 2234| Type = [Class] ClassWithDestructor +# 2234| ValueCategory = lvalue +# 2225| getImplicitDestructorCall(0): [DestructorCall] call to ~vector +# 2225| Type = [VoidType] void +# 2225| ValueCategory = prvalue +# 2225| getQualifier(): [VariableAccess] ys +# 2225| Type = [ClassTemplateInstantiation,Struct] vector +# 2225| ValueCategory = lvalue +# 2225| getUpdate().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) +# 2225| Type = [ClassTemplateInstantiation,Struct] iterator +# 2225| ValueCategory = lvalue +# 2230| getStmt(8): [RangeBasedForStmt] for(...:...) ... +# 2230| getInitialization(): [DeclStmt] declaration +# 2230| getDeclarationEntry(0): [VariableDeclarationEntry] definition of ys +# 2230| Type = [ClassTemplateInstantiation,Struct] vector +# 2230| getVariable().getInitializer(): [Initializer] initializer for ys +# 2230| getExpr(): [ConstructorCall] call to vector +# 2230| Type = [VoidType] void +# 2230| ValueCategory = prvalue +# 2230| getArgument(0): [VariableAccess] x +# 2230| Type = [Class] ClassWithDestructor +# 2230| ValueCategory = prvalue(load) +# 2230| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2230| Type = [VoidType] void +# 2230| ValueCategory = prvalue +# 2230| getQualifier(): [ReuseExpr] reuse of temporary object +# 2230| Type = [Class] ClassWithDestructor +# 2230| ValueCategory = xvalue +# 2230| getArgument(0).getFullyConverted(): [TemporaryObjectExpr] temporary object +# 2230| Type = [Class] ClassWithDestructor +# 2230| ValueCategory = lvalue +# 2230| getChild(1): [DeclStmt] declaration +# 2230| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__range) +# 2230| Type = [LValueReferenceType] vector & #-----| getVariable().getInitializer(): [Initializer] initializer for (__range) -# 2229| getExpr(): [VariableAccess] ys -# 2229| Type = [ClassTemplateInstantiation,Struct] vector -# 2229| ValueCategory = lvalue -# 2229| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to) -# 2229| Type = [LValueReferenceType] vector & -# 2229| ValueCategory = prvalue -# 2229| getBeginEndDeclaration(): [DeclStmt] declaration -# 2229| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__begin) -# 2229| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2230| getExpr(): [VariableAccess] ys +# 2230| Type = [ClassTemplateInstantiation,Struct] vector +# 2230| ValueCategory = lvalue +# 2230| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to) +# 2230| Type = [LValueReferenceType] vector & +# 2230| ValueCategory = prvalue +# 2230| getBeginEndDeclaration(): [DeclStmt] declaration +# 2230| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__begin) +# 2230| Type = [NestedTypedefType,UsingAliasTypedefType] iterator #-----| getVariable().getInitializer(): [Initializer] initializer for (__begin) -# 2229| getExpr(): [FunctionCall] call to begin -# 2229| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2229| ValueCategory = prvalue -# 2229| getQualifier(): [VariableAccess] (__range) -# 2229| Type = [LValueReferenceType] vector & -# 2229| ValueCategory = prvalue(load) +# 2230| getExpr(): [FunctionCall] call to begin +# 2230| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2230| ValueCategory = prvalue +# 2230| getQualifier(): [VariableAccess] (__range) +# 2230| Type = [LValueReferenceType] vector & +# 2230| ValueCategory = prvalue(load) #-----| getQualifier().getFullyConverted(): [CStyleCast] (const vector)... #-----| Conversion = [GlvalueConversion] glvalue conversion #-----| Type = [SpecifiedType] const vector @@ -19962,15 +19964,15 @@ ir.cpp: #-----| getExpr(): [ReferenceDereferenceExpr] (reference dereference) #-----| Type = [ClassTemplateInstantiation,Struct] vector #-----| ValueCategory = lvalue -# 2229| getDeclarationEntry(1): [VariableDeclarationEntry] declaration of (__end) -# 2229| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2230| getDeclarationEntry(1): [VariableDeclarationEntry] declaration of (__end) +# 2230| Type = [NestedTypedefType,UsingAliasTypedefType] iterator #-----| getVariable().getInitializer(): [Initializer] initializer for (__end) -# 2229| getExpr(): [FunctionCall] call to end -# 2229| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2229| ValueCategory = prvalue -# 2229| getQualifier(): [VariableAccess] (__range) -# 2229| Type = [LValueReferenceType] vector & -# 2229| ValueCategory = prvalue(load) +# 2230| getExpr(): [FunctionCall] call to end +# 2230| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2230| ValueCategory = prvalue +# 2230| getQualifier(): [VariableAccess] (__range) +# 2230| Type = [LValueReferenceType] vector & +# 2230| ValueCategory = prvalue(load) #-----| getQualifier().getFullyConverted(): [CStyleCast] (const vector)... #-----| Conversion = [GlvalueConversion] glvalue conversion #-----| Type = [SpecifiedType] const vector @@ -19978,18 +19980,18 @@ ir.cpp: #-----| getExpr(): [ReferenceDereferenceExpr] (reference dereference) #-----| Type = [ClassTemplateInstantiation,Struct] vector #-----| ValueCategory = lvalue -# 2229| getCondition(): [FunctionCall] call to operator!= -# 2229| Type = [BoolType] bool -# 2229| ValueCategory = prvalue -# 2229| getQualifier(): [VariableAccess] (__begin) -# 2229| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2229| ValueCategory = lvalue -# 2229| getArgument(0): [ConstructorCall] call to iterator -# 2229| Type = [VoidType] void -# 2229| ValueCategory = prvalue -# 2229| getArgument(0): [VariableAccess] (__end) -# 2229| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2229| ValueCategory = lvalue +# 2230| getCondition(): [FunctionCall] call to operator!= +# 2230| Type = [BoolType] bool +# 2230| ValueCategory = prvalue +# 2230| getQualifier(): [VariableAccess] (__begin) +# 2230| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2230| ValueCategory = lvalue +# 2230| getArgument(0): [ConstructorCall] call to iterator +# 2230| Type = [VoidType] void +# 2230| ValueCategory = prvalue +# 2230| getArgument(0): [VariableAccess] (__end) +# 2230| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2230| ValueCategory = lvalue #-----| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to) #-----| Type = [LValueReferenceType] const iterator & #-----| ValueCategory = prvalue @@ -20004,584 +20006,584 @@ ir.cpp: #-----| getArgument(0).getFullyConverted(): [TemporaryObjectExpr] temporary object #-----| Type = [ClassTemplateInstantiation,Struct] iterator #-----| ValueCategory = lvalue -# 2229| getUpdate(): [FunctionCall] call to operator++ -# 2229| Type = [LValueReferenceType] iterator & -# 2229| ValueCategory = prvalue -# 2229| getQualifier(): [VariableAccess] (__begin) -# 2229| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2229| ValueCategory = lvalue -# 2229| getChild(5): [DeclStmt] declaration -# 2229| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y -# 2229| Type = [Class] ClassWithDestructor -# 2229| getVariable().getInitializer(): [Initializer] initializer for y -# 2229| getExpr(): [OverloadedPointerDereferenceExpr] call to operator* -# 2229| Type = [LValueReferenceType] ClassWithDestructor & -# 2229| ValueCategory = prvalue -# 2229| getQualifier(): [VariableAccess] (__begin) -# 2229| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2229| ValueCategory = lvalue +# 2230| getUpdate(): [FunctionCall] call to operator++ +# 2230| Type = [LValueReferenceType] iterator & +# 2230| ValueCategory = prvalue +# 2230| getQualifier(): [VariableAccess] (__begin) +# 2230| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2230| ValueCategory = lvalue +# 2230| getChild(5): [DeclStmt] declaration +# 2230| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y +# 2230| Type = [Class] ClassWithDestructor +# 2230| getVariable().getInitializer(): [Initializer] initializer for y +# 2230| getExpr(): [OverloadedPointerDereferenceExpr] call to operator* +# 2230| Type = [LValueReferenceType] ClassWithDestructor & +# 2230| ValueCategory = prvalue +# 2230| getQualifier(): [VariableAccess] (__begin) +# 2230| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2230| ValueCategory = lvalue #-----| getQualifier().getFullyConverted(): [CStyleCast] (const iterator)... #-----| Conversion = [GlvalueConversion] glvalue conversion #-----| Type = [SpecifiedType] const iterator #-----| ValueCategory = lvalue -# 2229| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) -# 2229| Type = [Class] ClassWithDestructor -# 2229| ValueCategory = prvalue(load) -# 2229| getStmt(): [BlockStmt] { ... } -# 2230| getStmt(0): [DeclStmt] declaration -# 2230| getDeclarationEntry(0): [VariableDeclarationEntry] definition of z1 -# 2230| Type = [Class] ClassWithDestructor -# 2230| getVariable().getInitializer(): [Initializer] initializer for z1 -# 2230| getExpr(): [ConstructorCall] call to ClassWithDestructor -# 2230| Type = [VoidType] void -# 2230| ValueCategory = prvalue -# 2231| getStmt(1): [DeclStmt] declaration -# 2231| getDeclarationEntry(0): [VariableDeclarationEntry] definition of z2 +# 2230| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) +# 2230| Type = [Class] ClassWithDestructor +# 2230| ValueCategory = prvalue(load) +# 2230| getStmt(): [BlockStmt] { ... } +# 2231| getStmt(0): [DeclStmt] declaration +# 2231| getDeclarationEntry(0): [VariableDeclarationEntry] definition of z1 # 2231| Type = [Class] ClassWithDestructor -# 2231| getVariable().getInitializer(): [Initializer] initializer for z2 +# 2231| getVariable().getInitializer(): [Initializer] initializer for z1 # 2231| getExpr(): [ConstructorCall] call to ClassWithDestructor # 2231| Type = [VoidType] void # 2231| ValueCategory = prvalue -# 2232| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2232| Type = [VoidType] void -# 2232| ValueCategory = prvalue -# 2232| getQualifier(): [VariableAccess] z2 -# 2232| Type = [Class] ClassWithDestructor -# 2232| ValueCategory = lvalue -# 2232| getImplicitDestructorCall(1): [DestructorCall] call to ~ClassWithDestructor -# 2232| Type = [VoidType] void -# 2232| ValueCategory = prvalue -# 2232| getQualifier(): [VariableAccess] z1 +# 2232| getStmt(1): [DeclStmt] declaration +# 2232| getDeclarationEntry(0): [VariableDeclarationEntry] definition of z2 # 2232| Type = [Class] ClassWithDestructor -# 2232| ValueCategory = lvalue -# 2229| getImplicitDestructorCall(0): [DestructorCall] call to ~vector -# 2229| Type = [VoidType] void -# 2229| ValueCategory = prvalue -# 2229| getQualifier(): [VariableAccess] ys -# 2229| Type = [ClassTemplateInstantiation,Struct] vector -# 2229| ValueCategory = lvalue -# 2229| getUpdate().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) -# 2229| Type = [ClassTemplateInstantiation,Struct] iterator -# 2229| ValueCategory = lvalue -# 2229| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2229| Type = [VoidType] void -# 2229| ValueCategory = prvalue -# 2229| getQualifier(): [VariableAccess] y -# 2229| Type = [Class] ClassWithDestructor -# 2229| ValueCategory = lvalue -# 2233| getStmt(9): [ReturnStmt] return ... -# 2233| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2233| Type = [VoidType] void -# 2233| ValueCategory = prvalue -# 2233| getQualifier(): [VariableAccess] x -# 2233| Type = [Class] ClassWithDestructor -# 2233| ValueCategory = lvalue -# 2235| [TopLevelFunction] void static_variable_with_destructor_1() -# 2235| : -# 2235| getEntryPoint(): [BlockStmt] { ... } -# 2236| getStmt(0): [DeclStmt] declaration -# 2236| getDeclarationEntry(0): [VariableDeclarationEntry] definition of a -# 2236| Type = [Class] ClassWithDestructor -# 2236| getVariable().getInitializer(): [Initializer] initializer for a -# 2236| getExpr(): [ConstructorCall] call to ClassWithDestructor -# 2236| Type = [VoidType] void -# 2236| ValueCategory = prvalue -# 2237| getStmt(1): [DeclStmt] declaration -# 2237| getDeclarationEntry(0): [VariableDeclarationEntry] definition of b +# 2232| getVariable().getInitializer(): [Initializer] initializer for z2 +# 2232| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2232| Type = [VoidType] void +# 2232| ValueCategory = prvalue +# 2233| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2233| Type = [VoidType] void +# 2233| ValueCategory = prvalue +# 2233| getQualifier(): [VariableAccess] z2 +# 2233| Type = [Class] ClassWithDestructor +# 2233| ValueCategory = lvalue +# 2233| getImplicitDestructorCall(1): [DestructorCall] call to ~ClassWithDestructor +# 2233| Type = [VoidType] void +# 2233| ValueCategory = prvalue +# 2233| getQualifier(): [VariableAccess] z1 +# 2233| Type = [Class] ClassWithDestructor +# 2233| ValueCategory = lvalue +# 2230| getImplicitDestructorCall(0): [DestructorCall] call to ~vector +# 2230| Type = [VoidType] void +# 2230| ValueCategory = prvalue +# 2230| getQualifier(): [VariableAccess] ys +# 2230| Type = [ClassTemplateInstantiation,Struct] vector +# 2230| ValueCategory = lvalue +# 2230| getUpdate().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) +# 2230| Type = [ClassTemplateInstantiation,Struct] iterator +# 2230| ValueCategory = lvalue +# 2230| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2230| Type = [VoidType] void +# 2230| ValueCategory = prvalue +# 2230| getQualifier(): [VariableAccess] y +# 2230| Type = [Class] ClassWithDestructor +# 2230| ValueCategory = lvalue +# 2234| getStmt(9): [ReturnStmt] return ... +# 2234| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2234| Type = [VoidType] void +# 2234| ValueCategory = prvalue +# 2234| getQualifier(): [VariableAccess] x +# 2234| Type = [Class] ClassWithDestructor +# 2234| ValueCategory = lvalue +# 2236| [TopLevelFunction] void static_variable_with_destructor_1() +# 2236| : +# 2236| getEntryPoint(): [BlockStmt] { ... } +# 2237| getStmt(0): [DeclStmt] declaration +# 2237| getDeclarationEntry(0): [VariableDeclarationEntry] definition of a # 2237| Type = [Class] ClassWithDestructor +# 2237| getVariable().getInitializer(): [Initializer] initializer for a +# 2237| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2237| Type = [VoidType] void +# 2237| ValueCategory = prvalue +# 2238| getStmt(1): [DeclStmt] declaration +# 2238| getDeclarationEntry(0): [VariableDeclarationEntry] definition of b +# 2238| Type = [Class] ClassWithDestructor #-----| getVariable().getInitializer(): [Initializer] initializer for b #-----| getExpr(): [ConstructorCall] call to ClassWithDestructor #-----| Type = [VoidType] void #-----| ValueCategory = prvalue -# 2238| getStmt(2): [ReturnStmt] return ... -# 2238| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2238| Type = [VoidType] void -# 2238| ValueCategory = prvalue -# 2238| getQualifier(): [VariableAccess] a -# 2238| Type = [Class] ClassWithDestructor -# 2238| ValueCategory = lvalue -# 2240| [TopLevelFunction] void static_variable_with_destructor_2() -# 2240| : -# 2240| getEntryPoint(): [BlockStmt] { ... } -# 2241| getStmt(0): [DeclStmt] declaration -# 2241| getDeclarationEntry(0): [VariableDeclarationEntry] definition of a -# 2241| Type = [Class] ClassWithDestructor +# 2239| getStmt(2): [ReturnStmt] return ... +# 2239| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2239| Type = [VoidType] void +# 2239| ValueCategory = prvalue +# 2239| getQualifier(): [VariableAccess] a +# 2239| Type = [Class] ClassWithDestructor +# 2239| ValueCategory = lvalue +# 2241| [TopLevelFunction] void static_variable_with_destructor_2() +# 2241| : +# 2241| getEntryPoint(): [BlockStmt] { ... } +# 2242| getStmt(0): [DeclStmt] declaration +# 2242| getDeclarationEntry(0): [VariableDeclarationEntry] definition of a +# 2242| Type = [Class] ClassWithDestructor #-----| getVariable().getInitializer(): [Initializer] initializer for a #-----| getExpr(): [ConstructorCall] call to ClassWithDestructor #-----| Type = [VoidType] void #-----| ValueCategory = prvalue -# 2242| getStmt(1): [DeclStmt] declaration -# 2242| getDeclarationEntry(0): [VariableDeclarationEntry] definition of b -# 2242| Type = [Class] ClassWithDestructor -# 2242| getVariable().getInitializer(): [Initializer] initializer for b -# 2242| getExpr(): [ConstructorCall] call to ClassWithDestructor -# 2242| Type = [VoidType] void -# 2242| ValueCategory = prvalue -# 2243| getStmt(2): [ReturnStmt] return ... -# 2243| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2243| Type = [VoidType] void -# 2243| ValueCategory = prvalue -# 2243| getQualifier(): [VariableAccess] b -# 2243| Type = [Class] ClassWithDestructor -# 2243| ValueCategory = lvalue -# 2245| [TopLevelFunction] void static_variable_with_destructor_3() -# 2245| : -# 2245| getEntryPoint(): [BlockStmt] { ... } -# 2246| getStmt(0): [DeclStmt] declaration -# 2246| getDeclarationEntry(0): [VariableDeclarationEntry] definition of a -# 2246| Type = [Class] ClassWithDestructor -# 2246| getVariable().getInitializer(): [Initializer] initializer for a -# 2246| getExpr(): [ConstructorCall] call to ClassWithDestructor -# 2246| Type = [VoidType] void -# 2246| ValueCategory = prvalue -# 2247| getStmt(1): [DeclStmt] declaration -# 2247| getDeclarationEntry(0): [VariableDeclarationEntry] definition of b +# 2243| getStmt(1): [DeclStmt] declaration +# 2243| getDeclarationEntry(0): [VariableDeclarationEntry] definition of b +# 2243| Type = [Class] ClassWithDestructor +# 2243| getVariable().getInitializer(): [Initializer] initializer for b +# 2243| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2243| Type = [VoidType] void +# 2243| ValueCategory = prvalue +# 2244| getStmt(2): [ReturnStmt] return ... +# 2244| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2244| Type = [VoidType] void +# 2244| ValueCategory = prvalue +# 2244| getQualifier(): [VariableAccess] b +# 2244| Type = [Class] ClassWithDestructor +# 2244| ValueCategory = lvalue +# 2246| [TopLevelFunction] void static_variable_with_destructor_3() +# 2246| : +# 2246| getEntryPoint(): [BlockStmt] { ... } +# 2247| getStmt(0): [DeclStmt] declaration +# 2247| getDeclarationEntry(0): [VariableDeclarationEntry] definition of a # 2247| Type = [Class] ClassWithDestructor -# 2247| getVariable().getInitializer(): [Initializer] initializer for b +# 2247| getVariable().getInitializer(): [Initializer] initializer for a # 2247| getExpr(): [ConstructorCall] call to ClassWithDestructor # 2247| Type = [VoidType] void # 2247| ValueCategory = prvalue -# 2248| getStmt(2): [DeclStmt] declaration -# 2248| getDeclarationEntry(0): [VariableDeclarationEntry] definition of c +# 2248| getStmt(1): [DeclStmt] declaration +# 2248| getDeclarationEntry(0): [VariableDeclarationEntry] definition of b # 2248| Type = [Class] ClassWithDestructor +# 2248| getVariable().getInitializer(): [Initializer] initializer for b +# 2248| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2248| Type = [VoidType] void +# 2248| ValueCategory = prvalue +# 2249| getStmt(2): [DeclStmt] declaration +# 2249| getDeclarationEntry(0): [VariableDeclarationEntry] definition of c +# 2249| Type = [Class] ClassWithDestructor #-----| getVariable().getInitializer(): [Initializer] initializer for c #-----| getExpr(): [ConstructorCall] call to ClassWithDestructor #-----| Type = [VoidType] void #-----| ValueCategory = prvalue -# 2249| getStmt(3): [ReturnStmt] return ... -# 2249| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2249| Type = [VoidType] void -# 2249| ValueCategory = prvalue -# 2249| getQualifier(): [VariableAccess] b -# 2249| Type = [Class] ClassWithDestructor -# 2249| ValueCategory = lvalue -# 2249| getImplicitDestructorCall(1): [DestructorCall] call to ~ClassWithDestructor -# 2249| Type = [VoidType] void -# 2249| ValueCategory = prvalue -# 2249| getQualifier(): [VariableAccess] a -# 2249| Type = [Class] ClassWithDestructor -# 2249| ValueCategory = lvalue -# 2251| [GlobalVariable] ClassWithDestructor global_class_with_destructor -# 2251| getInitializer(): [Initializer] initializer for global_class_with_destructor -# 2251| getExpr(): [ConstructorCall] call to ClassWithDestructor -# 2251| Type = [VoidType] void -# 2251| ValueCategory = prvalue -# 2255| [FunctionTemplateInstantiation,TopLevelFunction] ClassWithDestructor& vacuous_destructor_call::get(ClassWithDestructor&) -# 2255| : -# 2255| getParameter(0): [Parameter] t -# 2255| Type = [LValueReferenceType] ClassWithDestructor & -# 2255| getEntryPoint(): [BlockStmt] { ... } -# 2255| getStmt(0): [ReturnStmt] return ... -# 2255| getExpr(): [VariableAccess] t -# 2255| Type = [LValueReferenceType] ClassWithDestructor & -# 2255| ValueCategory = prvalue(load) -# 2255| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to) -# 2255| Type = [LValueReferenceType] ClassWithDestructor & -# 2255| ValueCategory = prvalue -# 2255| getExpr(): [ReferenceDereferenceExpr] (reference dereference) -# 2255| Type = [Class] ClassWithDestructor -# 2255| ValueCategory = lvalue -# 2255| [TemplateFunction,TopLevelFunction] T& vacuous_destructor_call::get(T&) -# 2255| : -# 2255| getParameter(0): [Parameter] t -# 2255| Type = [LValueReferenceType] T & -# 2255| getEntryPoint(): [BlockStmt] { ... } -# 2255| getStmt(0): [ReturnStmt] return ... -# 2255| getExpr(): [VariableAccess] t -# 2255| Type = [LValueReferenceType] T & -# 2255| ValueCategory = prvalue(load) -# 2255| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) -# 2255| Type = [TemplateParameter] T -# 2255| ValueCategory = lvalue -# 2255| [FunctionTemplateInstantiation,TopLevelFunction] int& vacuous_destructor_call::get(int&) -# 2255| : -# 2255| getParameter(0): [Parameter] t -# 2255| Type = [LValueReferenceType] int & -# 2255| getEntryPoint(): [BlockStmt] { ... } -# 2255| getStmt(0): [ReturnStmt] return ... -# 2255| getExpr(): [VariableAccess] t -# 2255| Type = [LValueReferenceType] int & -# 2255| ValueCategory = prvalue(load) -# 2255| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to) -# 2255| Type = [LValueReferenceType] int & -# 2255| ValueCategory = prvalue -# 2255| getExpr(): [ReferenceDereferenceExpr] (reference dereference) -# 2255| Type = [IntType] int -# 2255| ValueCategory = lvalue -# 2258| [FunctionTemplateInstantiation,TopLevelFunction] void vacuous_destructor_call::call_destructor(ClassWithDestructor&) -# 2258| : -# 2258| getParameter(0): [Parameter] t -# 2258| Type = [LValueReferenceType] ClassWithDestructor & -# 2258| getEntryPoint(): [BlockStmt] { ... } -# 2259| getStmt(0): [ExprStmt] ExprStmt -# 2259| getExpr(): [DestructorCall] call to ~ClassWithDestructor -# 2259| Type = [VoidType] void -# 2259| ValueCategory = prvalue -# 2259| getQualifier(): [FunctionCall] call to get -# 2259| Type = [LValueReferenceType] ClassWithDestructor & -# 2259| ValueCategory = prvalue -# 2259| getArgument(0): [VariableAccess] t -# 2259| Type = [LValueReferenceType] ClassWithDestructor & -# 2259| ValueCategory = prvalue(load) -# 2259| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to) -# 2259| Type = [LValueReferenceType] ClassWithDestructor & -# 2259| ValueCategory = prvalue -# 2259| getExpr(): [ReferenceDereferenceExpr] (reference dereference) -# 2259| Type = [Class] ClassWithDestructor -# 2259| ValueCategory = lvalue -# 2259| getQualifier().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) -# 2259| Type = [Class] ClassWithDestructor -# 2259| ValueCategory = lvalue -# 2260| getStmt(1): [ReturnStmt] return ... -# 2258| [TemplateFunction,TopLevelFunction] void vacuous_destructor_call::call_destructor(T&) -# 2258| : -# 2258| getParameter(0): [Parameter] t -# 2258| Type = [LValueReferenceType] T & -# 2258| getEntryPoint(): [BlockStmt] { ... } -# 2259| getStmt(0): [ExprStmt] ExprStmt -# 2259| getExpr(): [ExprCall] call to expression -# 2259| Type = [UnknownType] unknown -# 2259| ValueCategory = prvalue -# 2259| getExpr(): [Literal] Unknown literal -# 2259| Type = [UnknownType] unknown -# 2259| ValueCategory = prvalue -# 2259| getChild(-1): [ExprCall] call to expression -# 2259| Type = [UnknownType] unknown -# 2259| ValueCategory = prvalue -# 2259| getExpr(): [Literal] Unknown literal -# 2259| Type = [UnknownType] unknown -# 2259| ValueCategory = prvalue -# 2259| getArgument(0): [VariableAccess] t -# 2259| Type = [LValueReferenceType] T & -# 2259| ValueCategory = prvalue(load) -# 2259| getArgument(0).getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) -# 2259| Type = [TemplateParameter] T -# 2259| ValueCategory = lvalue -# 2260| getStmt(1): [ReturnStmt] return ... -# 2258| [FunctionTemplateInstantiation,TopLevelFunction] void vacuous_destructor_call::call_destructor(int&) -# 2258| : -# 2258| getParameter(0): [Parameter] t -# 2258| Type = [LValueReferenceType] int & -# 2258| getEntryPoint(): [BlockStmt] { ... } -# 2259| getStmt(0): [ExprStmt] ExprStmt -# 2259| getExpr(): [VacuousDestructorCall] (vacuous destructor call) -# 2259| Type = [VoidType] void -# 2259| ValueCategory = prvalue -# 2259| getChild(0): [FunctionCall] call to get -# 2259| Type = [LValueReferenceType] int & -# 2259| ValueCategory = prvalue -# 2259| getArgument(0): [VariableAccess] t -# 2259| Type = [LValueReferenceType] int & -# 2259| ValueCategory = prvalue(load) -# 2259| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to) -# 2259| Type = [LValueReferenceType] int & -# 2259| ValueCategory = prvalue -# 2259| getExpr(): [ReferenceDereferenceExpr] (reference dereference) -# 2259| Type = [IntType] int -# 2259| ValueCategory = lvalue -# 2259| getChild(0).getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) -# 2259| Type = [IntType] int -# 2259| ValueCategory = lvalue -# 2260| getStmt(1): [ReturnStmt] return ... -# 2262| [TopLevelFunction] void vacuous_destructor_call::non_vacuous_destructor_call() -# 2262| : -# 2262| getEntryPoint(): [BlockStmt] { ... } -# 2263| getStmt(0): [DeclStmt] declaration -# 2263| getDeclarationEntry(0): [VariableDeclarationEntry] definition of c -# 2263| Type = [Class] ClassWithDestructor -# 2263| getVariable().getInitializer(): [Initializer] initializer for c -# 2263| getExpr(): [ConstructorCall] call to ClassWithDestructor -# 2263| Type = [VoidType] void -# 2263| ValueCategory = prvalue -# 2264| getStmt(1): [ExprStmt] ExprStmt -# 2264| getExpr(): [FunctionCall] call to call_destructor -# 2264| Type = [VoidType] void -# 2264| ValueCategory = prvalue -# 2264| getArgument(0): [VariableAccess] c -# 2264| Type = [Class] ClassWithDestructor -# 2264| ValueCategory = lvalue -# 2264| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to) -# 2264| Type = [LValueReferenceType] ClassWithDestructor & -# 2264| ValueCategory = prvalue -# 2265| getStmt(2): [ReturnStmt] return ... -# 2265| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2250| getStmt(3): [ReturnStmt] return ... +# 2250| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2250| Type = [VoidType] void +# 2250| ValueCategory = prvalue +# 2250| getQualifier(): [VariableAccess] b +# 2250| Type = [Class] ClassWithDestructor +# 2250| ValueCategory = lvalue +# 2250| getImplicitDestructorCall(1): [DestructorCall] call to ~ClassWithDestructor +# 2250| Type = [VoidType] void +# 2250| ValueCategory = prvalue +# 2250| getQualifier(): [VariableAccess] a +# 2250| Type = [Class] ClassWithDestructor +# 2250| ValueCategory = lvalue +# 2252| [GlobalVariable] ClassWithDestructor global_class_with_destructor +# 2252| getInitializer(): [Initializer] initializer for global_class_with_destructor +# 2252| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2252| Type = [VoidType] void +# 2252| ValueCategory = prvalue +# 2256| [FunctionTemplateInstantiation,TopLevelFunction] ClassWithDestructor& vacuous_destructor_call::get(ClassWithDestructor&) +# 2256| : +# 2256| getParameter(0): [Parameter] t +# 2256| Type = [LValueReferenceType] ClassWithDestructor & +# 2256| getEntryPoint(): [BlockStmt] { ... } +# 2256| getStmt(0): [ReturnStmt] return ... +# 2256| getExpr(): [VariableAccess] t +# 2256| Type = [LValueReferenceType] ClassWithDestructor & +# 2256| ValueCategory = prvalue(load) +# 2256| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to) +# 2256| Type = [LValueReferenceType] ClassWithDestructor & +# 2256| ValueCategory = prvalue +# 2256| getExpr(): [ReferenceDereferenceExpr] (reference dereference) +# 2256| Type = [Class] ClassWithDestructor +# 2256| ValueCategory = lvalue +# 2256| [TemplateFunction,TopLevelFunction] T& vacuous_destructor_call::get(T&) +# 2256| : +# 2256| getParameter(0): [Parameter] t +# 2256| Type = [LValueReferenceType] T & +# 2256| getEntryPoint(): [BlockStmt] { ... } +# 2256| getStmt(0): [ReturnStmt] return ... +# 2256| getExpr(): [VariableAccess] t +# 2256| Type = [LValueReferenceType] T & +# 2256| ValueCategory = prvalue(load) +# 2256| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) +# 2256| Type = [TemplateParameter] T +# 2256| ValueCategory = lvalue +# 2256| [FunctionTemplateInstantiation,TopLevelFunction] int& vacuous_destructor_call::get(int&) +# 2256| : +# 2256| getParameter(0): [Parameter] t +# 2256| Type = [LValueReferenceType] int & +# 2256| getEntryPoint(): [BlockStmt] { ... } +# 2256| getStmt(0): [ReturnStmt] return ... +# 2256| getExpr(): [VariableAccess] t +# 2256| Type = [LValueReferenceType] int & +# 2256| ValueCategory = prvalue(load) +# 2256| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to) +# 2256| Type = [LValueReferenceType] int & +# 2256| ValueCategory = prvalue +# 2256| getExpr(): [ReferenceDereferenceExpr] (reference dereference) +# 2256| Type = [IntType] int +# 2256| ValueCategory = lvalue +# 2259| [FunctionTemplateInstantiation,TopLevelFunction] void vacuous_destructor_call::call_destructor(ClassWithDestructor&) +# 2259| : +# 2259| getParameter(0): [Parameter] t +# 2259| Type = [LValueReferenceType] ClassWithDestructor & +# 2259| getEntryPoint(): [BlockStmt] { ... } +# 2260| getStmt(0): [ExprStmt] ExprStmt +# 2260| getExpr(): [DestructorCall] call to ~ClassWithDestructor +# 2260| Type = [VoidType] void +# 2260| ValueCategory = prvalue +# 2260| getQualifier(): [FunctionCall] call to get +# 2260| Type = [LValueReferenceType] ClassWithDestructor & +# 2260| ValueCategory = prvalue +# 2260| getArgument(0): [VariableAccess] t +# 2260| Type = [LValueReferenceType] ClassWithDestructor & +# 2260| ValueCategory = prvalue(load) +# 2260| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to) +# 2260| Type = [LValueReferenceType] ClassWithDestructor & +# 2260| ValueCategory = prvalue +# 2260| getExpr(): [ReferenceDereferenceExpr] (reference dereference) +# 2260| Type = [Class] ClassWithDestructor +# 2260| ValueCategory = lvalue +# 2260| getQualifier().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) +# 2260| Type = [Class] ClassWithDestructor +# 2260| ValueCategory = lvalue +# 2261| getStmt(1): [ReturnStmt] return ... +# 2259| [TemplateFunction,TopLevelFunction] void vacuous_destructor_call::call_destructor(T&) +# 2259| : +# 2259| getParameter(0): [Parameter] t +# 2259| Type = [LValueReferenceType] T & +# 2259| getEntryPoint(): [BlockStmt] { ... } +# 2260| getStmt(0): [ExprStmt] ExprStmt +# 2260| getExpr(): [ExprCall] call to expression +# 2260| Type = [UnknownType] unknown +# 2260| ValueCategory = prvalue +# 2260| getExpr(): [Literal] Unknown literal +# 2260| Type = [UnknownType] unknown +# 2260| ValueCategory = prvalue +# 2260| getChild(-1): [ExprCall] call to expression +# 2260| Type = [UnknownType] unknown +# 2260| ValueCategory = prvalue +# 2260| getExpr(): [Literal] Unknown literal +# 2260| Type = [UnknownType] unknown +# 2260| ValueCategory = prvalue +# 2260| getArgument(0): [VariableAccess] t +# 2260| Type = [LValueReferenceType] T & +# 2260| ValueCategory = prvalue(load) +# 2260| getArgument(0).getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) +# 2260| Type = [TemplateParameter] T +# 2260| ValueCategory = lvalue +# 2261| getStmt(1): [ReturnStmt] return ... +# 2259| [FunctionTemplateInstantiation,TopLevelFunction] void vacuous_destructor_call::call_destructor(int&) +# 2259| : +# 2259| getParameter(0): [Parameter] t +# 2259| Type = [LValueReferenceType] int & +# 2259| getEntryPoint(): [BlockStmt] { ... } +# 2260| getStmt(0): [ExprStmt] ExprStmt +# 2260| getExpr(): [VacuousDestructorCall] (vacuous destructor call) +# 2260| Type = [VoidType] void +# 2260| ValueCategory = prvalue +# 2260| getChild(0): [FunctionCall] call to get +# 2260| Type = [LValueReferenceType] int & +# 2260| ValueCategory = prvalue +# 2260| getArgument(0): [VariableAccess] t +# 2260| Type = [LValueReferenceType] int & +# 2260| ValueCategory = prvalue(load) +# 2260| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to) +# 2260| Type = [LValueReferenceType] int & +# 2260| ValueCategory = prvalue +# 2260| getExpr(): [ReferenceDereferenceExpr] (reference dereference) +# 2260| Type = [IntType] int +# 2260| ValueCategory = lvalue +# 2260| getChild(0).getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) +# 2260| Type = [IntType] int +# 2260| ValueCategory = lvalue +# 2261| getStmt(1): [ReturnStmt] return ... +# 2263| [TopLevelFunction] void vacuous_destructor_call::non_vacuous_destructor_call() +# 2263| : +# 2263| getEntryPoint(): [BlockStmt] { ... } +# 2264| getStmt(0): [DeclStmt] declaration +# 2264| getDeclarationEntry(0): [VariableDeclarationEntry] definition of c +# 2264| Type = [Class] ClassWithDestructor +# 2264| getVariable().getInitializer(): [Initializer] initializer for c +# 2264| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2264| Type = [VoidType] void +# 2264| ValueCategory = prvalue +# 2265| getStmt(1): [ExprStmt] ExprStmt +# 2265| getExpr(): [FunctionCall] call to call_destructor # 2265| Type = [VoidType] void # 2265| ValueCategory = prvalue -# 2265| getQualifier(): [VariableAccess] c +# 2265| getArgument(0): [VariableAccess] c # 2265| Type = [Class] ClassWithDestructor # 2265| ValueCategory = lvalue -# 2267| [TopLevelFunction] void vacuous_destructor_call::vacuous_destructor_call() -# 2267| : -# 2267| getEntryPoint(): [BlockStmt] { ... } -# 2268| getStmt(0): [DeclStmt] declaration -# 2268| getDeclarationEntry(0): [VariableDeclarationEntry] definition of i -# 2268| Type = [IntType] int -# 2269| getStmt(1): [ExprStmt] ExprStmt -# 2269| getExpr(): [FunctionCall] call to call_destructor -# 2269| Type = [VoidType] void -# 2269| ValueCategory = prvalue -# 2269| getArgument(0): [VariableAccess] i -# 2269| Type = [IntType] int -# 2269| ValueCategory = lvalue -# 2269| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to) -# 2269| Type = [LValueReferenceType] int & -# 2269| ValueCategory = prvalue -# 2270| getStmt(2): [ReturnStmt] return ... -# 2273| [TopLevelFunction] void TryCatchDestructors(bool) -# 2273| : -# 2273| getParameter(0): [Parameter] b -# 2273| Type = [BoolType] bool -# 2273| getEntryPoint(): [BlockStmt] { ... } -# 2274| getStmt(0): [TryStmt] try { ... } -# 2274| getStmt(): [BlockStmt] { ... } -# 2275| getStmt(0): [DeclStmt] declaration -# 2275| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s -# 2275| Type = [Struct] String -# 2275| getVariable().getInitializer(): [Initializer] initializer for s -# 2275| getExpr(): [ConstructorCall] call to String -# 2275| Type = [VoidType] void -# 2275| ValueCategory = prvalue -# 2276| getStmt(1): [IfStmt] if (...) ... -# 2276| getCondition(): [VariableAccess] b -# 2276| Type = [BoolType] bool -# 2276| ValueCategory = prvalue(load) -# 2276| getThen(): [BlockStmt] { ... } -# 2277| getStmt(0): [ExprStmt] ExprStmt -# 2277| getExpr(): [ThrowExpr] throw ... -# 2277| Type = [PointerType] const char * -# 2277| ValueCategory = prvalue -# 2277| getExpr(): string literal -# 2277| Type = [ArrayType] const char[15] -# 2277| Value = [StringLiteral] "string literal" -# 2277| ValueCategory = lvalue -# 2280| getImplicitDestructorCall(0): [DestructorCall] call to ~String -# 2280| Type = [VoidType] void -# 2280| ValueCategory = prvalue -# 2280| getQualifier(): [VariableAccess] s -# 2280| Type = [Struct] String -# 2280| ValueCategory = lvalue -# 2277| getExpr().getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion -# 2277| Type = [PointerType] const char * -# 2277| ValueCategory = prvalue -# 2279| getStmt(2): [DeclStmt] declaration -# 2279| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s2 -# 2279| Type = [Struct] String -# 2279| getVariable().getInitializer(): [Initializer] initializer for s2 -# 2279| getExpr(): [ConstructorCall] call to String -# 2279| Type = [VoidType] void -# 2279| ValueCategory = prvalue -# 2280| getImplicitDestructorCall(0): [DestructorCall] call to ~String -# 2280| Type = [VoidType] void -# 2280| ValueCategory = prvalue -# 2280| getQualifier(): [VariableAccess] s2 +# 2265| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to) +# 2265| Type = [LValueReferenceType] ClassWithDestructor & +# 2265| ValueCategory = prvalue +# 2266| getStmt(2): [ReturnStmt] return ... +# 2266| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2266| Type = [VoidType] void +# 2266| ValueCategory = prvalue +# 2266| getQualifier(): [VariableAccess] c +# 2266| Type = [Class] ClassWithDestructor +# 2266| ValueCategory = lvalue +# 2268| [TopLevelFunction] void vacuous_destructor_call::vacuous_destructor_call() +# 2268| : +# 2268| getEntryPoint(): [BlockStmt] { ... } +# 2269| getStmt(0): [DeclStmt] declaration +# 2269| getDeclarationEntry(0): [VariableDeclarationEntry] definition of i +# 2269| Type = [IntType] int +# 2270| getStmt(1): [ExprStmt] ExprStmt +# 2270| getExpr(): [FunctionCall] call to call_destructor +# 2270| Type = [VoidType] void +# 2270| ValueCategory = prvalue +# 2270| getArgument(0): [VariableAccess] i +# 2270| Type = [IntType] int +# 2270| ValueCategory = lvalue +# 2270| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to) +# 2270| Type = [LValueReferenceType] int & +# 2270| ValueCategory = prvalue +# 2271| getStmt(2): [ReturnStmt] return ... +# 2274| [TopLevelFunction] void TryCatchDestructors(bool) +# 2274| : +# 2274| getParameter(0): [Parameter] b +# 2274| Type = [BoolType] bool +# 2274| getEntryPoint(): [BlockStmt] { ... } +# 2275| getStmt(0): [TryStmt] try { ... } +# 2275| getStmt(): [BlockStmt] { ... } +# 2276| getStmt(0): [DeclStmt] declaration +# 2276| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s +# 2276| Type = [Struct] String +# 2276| getVariable().getInitializer(): [Initializer] initializer for s +# 2276| getExpr(): [ConstructorCall] call to String +# 2276| Type = [VoidType] void +# 2276| ValueCategory = prvalue +# 2277| getStmt(1): [IfStmt] if (...) ... +# 2277| getCondition(): [VariableAccess] b +# 2277| Type = [BoolType] bool +# 2277| ValueCategory = prvalue(load) +# 2277| getThen(): [BlockStmt] { ... } +# 2278| getStmt(0): [ExprStmt] ExprStmt +# 2278| getExpr(): [ThrowExpr] throw ... +# 2278| Type = [PointerType] const char * +# 2278| ValueCategory = prvalue +# 2278| getExpr(): string literal +# 2278| Type = [ArrayType] const char[15] +# 2278| Value = [StringLiteral] "string literal" +# 2278| ValueCategory = lvalue +# 2281| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2281| Type = [VoidType] void +# 2281| ValueCategory = prvalue +# 2281| getQualifier(): [VariableAccess] s +# 2281| Type = [Struct] String +# 2281| ValueCategory = lvalue +# 2278| getExpr().getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion +# 2278| Type = [PointerType] const char * +# 2278| ValueCategory = prvalue +# 2280| getStmt(2): [DeclStmt] declaration +# 2280| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s2 # 2280| Type = [Struct] String -# 2280| ValueCategory = lvalue -# 2280| getImplicitDestructorCall(1): [DestructorCall] call to ~String -# 2280| Type = [VoidType] void -# 2280| ValueCategory = prvalue -# 2280| getQualifier(): [VariableAccess] s -# 2280| Type = [Struct] String -# 2280| ValueCategory = lvalue -# 2281| getChild(1): [Handler] -# 2281| getBlock(): [CatchBlock] { ... } -# 2282| getStmt(0): [ExprStmt] ExprStmt -# 2282| getExpr(): [ThrowExpr] throw ... -# 2282| Type = [Struct] String -# 2282| ValueCategory = prvalue -# 2282| getExpr(): [ConstructorCall] call to String -# 2282| Type = [VoidType] void -# 2282| ValueCategory = prvalue -# 2282| getArgument(0): [VariableAccess] s -# 2282| Type = [PointerType] const char * -# 2282| ValueCategory = prvalue(load) -# 2284| getChild(2): [Handler] -# 2284| getBlock(): [CatchBlock] { ... } -# 2286| getChild(3): [Handler] -# 2286| getBlock(): [CatchAnyBlock] { ... } -# 2287| getStmt(0): [ExprStmt] ExprStmt -# 2287| getExpr(): [ReThrowExpr] re-throw exception -# 2287| Type = [VoidType] void -# 2287| ValueCategory = prvalue -# 2289| getStmt(1): [ReturnStmt] return ... -# 2291| [TopLevelFunction] void IfDestructors(bool) -# 2291| : -# 2291| getParameter(0): [Parameter] b -# 2291| Type = [BoolType] bool -# 2291| getEntryPoint(): [BlockStmt] { ... } -# 2292| getStmt(0): [DeclStmt] declaration -# 2292| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s1 -# 2292| Type = [Struct] String -# 2292| getVariable().getInitializer(): [Initializer] initializer for s1 -# 2292| getExpr(): [ConstructorCall] call to String -# 2292| Type = [VoidType] void -# 2292| ValueCategory = prvalue -# 2293| getStmt(1): [IfStmt] if (...) ... -# 2293| getCondition(): [VariableAccess] b -# 2293| Type = [BoolType] bool -# 2293| ValueCategory = prvalue(load) -# 2293| getThen(): [BlockStmt] { ... } -# 2294| getStmt(0): [DeclStmt] declaration -# 2294| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s2 -# 2294| Type = [Struct] String -# 2294| getVariable().getInitializer(): [Initializer] initializer for s2 -# 2294| getExpr(): [ConstructorCall] call to String -# 2294| Type = [VoidType] void -# 2294| ValueCategory = prvalue -# 2295| getImplicitDestructorCall(0): [DestructorCall] call to ~String -# 2295| Type = [VoidType] void -# 2295| ValueCategory = prvalue -# 2295| getQualifier(): [VariableAccess] s2 +# 2280| getVariable().getInitializer(): [Initializer] initializer for s2 +# 2280| getExpr(): [ConstructorCall] call to String +# 2280| Type = [VoidType] void +# 2280| ValueCategory = prvalue +# 2281| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2281| Type = [VoidType] void +# 2281| ValueCategory = prvalue +# 2281| getQualifier(): [VariableAccess] s2 +# 2281| Type = [Struct] String +# 2281| ValueCategory = lvalue +# 2281| getImplicitDestructorCall(1): [DestructorCall] call to ~String +# 2281| Type = [VoidType] void +# 2281| ValueCategory = prvalue +# 2281| getQualifier(): [VariableAccess] s +# 2281| Type = [Struct] String +# 2281| ValueCategory = lvalue +# 2282| getChild(1): [Handler] +# 2282| getBlock(): [CatchBlock] { ... } +# 2283| getStmt(0): [ExprStmt] ExprStmt +# 2283| getExpr(): [ThrowExpr] throw ... +# 2283| Type = [Struct] String +# 2283| ValueCategory = prvalue +# 2283| getExpr(): [ConstructorCall] call to String +# 2283| Type = [VoidType] void +# 2283| ValueCategory = prvalue +# 2283| getArgument(0): [VariableAccess] s +# 2283| Type = [PointerType] const char * +# 2283| ValueCategory = prvalue(load) +# 2285| getChild(2): [Handler] +# 2285| getBlock(): [CatchBlock] { ... } +# 2287| getChild(3): [Handler] +# 2287| getBlock(): [CatchAnyBlock] { ... } +# 2288| getStmt(0): [ExprStmt] ExprStmt +# 2288| getExpr(): [ReThrowExpr] re-throw exception +# 2288| Type = [VoidType] void +# 2288| ValueCategory = prvalue +# 2290| getStmt(1): [ReturnStmt] return ... +# 2292| [TopLevelFunction] void IfDestructors(bool) +# 2292| : +# 2292| getParameter(0): [Parameter] b +# 2292| Type = [BoolType] bool +# 2292| getEntryPoint(): [BlockStmt] { ... } +# 2293| getStmt(0): [DeclStmt] declaration +# 2293| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s1 +# 2293| Type = [Struct] String +# 2293| getVariable().getInitializer(): [Initializer] initializer for s1 +# 2293| getExpr(): [ConstructorCall] call to String +# 2293| Type = [VoidType] void +# 2293| ValueCategory = prvalue +# 2294| getStmt(1): [IfStmt] if (...) ... +# 2294| getCondition(): [VariableAccess] b +# 2294| Type = [BoolType] bool +# 2294| ValueCategory = prvalue(load) +# 2294| getThen(): [BlockStmt] { ... } +# 2295| getStmt(0): [DeclStmt] declaration +# 2295| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s2 # 2295| Type = [Struct] String -# 2295| ValueCategory = lvalue -# 2295| getElse(): [BlockStmt] { ... } -# 2296| getStmt(0): [DeclStmt] declaration -# 2296| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s3 +# 2295| getVariable().getInitializer(): [Initializer] initializer for s2 +# 2295| getExpr(): [ConstructorCall] call to String +# 2295| Type = [VoidType] void +# 2295| ValueCategory = prvalue +# 2296| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2296| Type = [VoidType] void +# 2296| ValueCategory = prvalue +# 2296| getQualifier(): [VariableAccess] s2 # 2296| Type = [Struct] String -# 2296| getVariable().getInitializer(): [Initializer] initializer for s3 -# 2296| getExpr(): [ConstructorCall] call to String -# 2296| Type = [VoidType] void -# 2296| ValueCategory = prvalue -# 2297| getImplicitDestructorCall(0): [DestructorCall] call to ~String -# 2297| Type = [VoidType] void -# 2297| ValueCategory = prvalue -# 2297| getQualifier(): [VariableAccess] s3 +# 2296| ValueCategory = lvalue +# 2296| getElse(): [BlockStmt] { ... } +# 2297| getStmt(0): [DeclStmt] declaration +# 2297| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s3 # 2297| Type = [Struct] String -# 2297| ValueCategory = lvalue -# 2298| getStmt(2): [DeclStmt] declaration -# 2298| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s4 -# 2298| Type = [Struct] String -# 2298| getVariable().getInitializer(): [Initializer] initializer for s4 -# 2298| getExpr(): [ConstructorCall] call to String -# 2298| Type = [VoidType] void -# 2298| ValueCategory = prvalue -# 2299| getStmt(3): [ReturnStmt] return ... -# 2299| getImplicitDestructorCall(0): [DestructorCall] call to ~String -# 2299| Type = [VoidType] void -# 2299| ValueCategory = prvalue -# 2299| getQualifier(): [VariableAccess] s4 -# 2299| Type = [Struct] String -# 2299| ValueCategory = lvalue -# 2299| getImplicitDestructorCall(1): [DestructorCall] call to ~String -# 2299| Type = [VoidType] void -# 2299| ValueCategory = prvalue -# 2299| getQualifier(): [VariableAccess] s1 -# 2299| Type = [Struct] String -# 2299| ValueCategory = lvalue -# 2301| [TopLevelFunction] void ForDestructors() -# 2301| : -# 2301| getEntryPoint(): [BlockStmt] { ... } -# 2302| getStmt(0): [DeclStmt] declaration -# 2302| getDeclarationEntry(0): [VariableDeclarationEntry] definition of c -# 2302| Type = [PlainCharType] char -# 2302| getVariable().getInitializer(): [Initializer] initializer for c -# 2302| getExpr(): [CharLiteral] 97 -# 2302| Type = [PlainCharType] char -# 2302| Value = [CharLiteral] 97 -# 2302| ValueCategory = prvalue -# 2303| getStmt(1): [ForStmt] for(...;...;...) ... -# 2303| getInitialization(): [DeclStmt] declaration -# 2303| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s -# 2303| Type = [Struct] String -# 2303| getVariable().getInitializer(): [Initializer] initializer for s -# 2303| getExpr(): [ConstructorCall] call to String -# 2303| Type = [VoidType] void -# 2303| ValueCategory = prvalue -# 2303| getArgument(0): hello -# 2303| Type = [ArrayType] const char[6] -# 2303| Value = [StringLiteral] "hello" -# 2303| ValueCategory = lvalue -# 2303| getArgument(0).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion -# 2303| Type = [PointerType] const char * -# 2303| ValueCategory = prvalue -# 2303| getCondition(): [NEExpr] ... != ... -# 2303| Type = [BoolType] bool -# 2303| ValueCategory = prvalue -# 2303| getLeftOperand(): [VariableAccess] c -# 2303| Type = [PlainCharType] char -# 2303| ValueCategory = prvalue(load) -# 2303| getRightOperand(): [Literal] 0 -# 2303| Type = [IntType] int -# 2303| Value = [Literal] 0 -# 2303| ValueCategory = prvalue -# 2303| getLeftOperand().getFullyConverted(): [CStyleCast] (int)... -# 2303| Conversion = [IntegralConversion] integral conversion -# 2303| Type = [IntType] int -# 2303| ValueCategory = prvalue -# 2303| getUpdate(): [AssignExpr] ... = ... +# 2297| getVariable().getInitializer(): [Initializer] initializer for s3 +# 2297| getExpr(): [ConstructorCall] call to String +# 2297| Type = [VoidType] void +# 2297| ValueCategory = prvalue +# 2298| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2298| Type = [VoidType] void +# 2298| ValueCategory = prvalue +# 2298| getQualifier(): [VariableAccess] s3 +# 2298| Type = [Struct] String +# 2298| ValueCategory = lvalue +# 2299| getStmt(2): [DeclStmt] declaration +# 2299| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s4 +# 2299| Type = [Struct] String +# 2299| getVariable().getInitializer(): [Initializer] initializer for s4 +# 2299| getExpr(): [ConstructorCall] call to String +# 2299| Type = [VoidType] void +# 2299| ValueCategory = prvalue +# 2300| getStmt(3): [ReturnStmt] return ... +# 2300| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2300| Type = [VoidType] void +# 2300| ValueCategory = prvalue +# 2300| getQualifier(): [VariableAccess] s4 +# 2300| Type = [Struct] String +# 2300| ValueCategory = lvalue +# 2300| getImplicitDestructorCall(1): [DestructorCall] call to ~String +# 2300| Type = [VoidType] void +# 2300| ValueCategory = prvalue +# 2300| getQualifier(): [VariableAccess] s1 +# 2300| Type = [Struct] String +# 2300| ValueCategory = lvalue +# 2302| [TopLevelFunction] void ForDestructors() +# 2302| : +# 2302| getEntryPoint(): [BlockStmt] { ... } +# 2303| getStmt(0): [DeclStmt] declaration +# 2303| getDeclarationEntry(0): [VariableDeclarationEntry] definition of c # 2303| Type = [PlainCharType] char -# 2303| ValueCategory = lvalue -# 2303| getLValue(): [VariableAccess] c -# 2303| Type = [PlainCharType] char -# 2303| ValueCategory = lvalue -# 2303| getRValue(): [FunctionCall] call to pop_back -# 2303| Type = [PlainCharType] char -# 2303| ValueCategory = prvalue -# 2303| getQualifier(): [VariableAccess] s -# 2303| Type = [Struct] String -# 2303| ValueCategory = lvalue -# 2303| getStmt(): [BlockStmt] { ... } -# 2304| getStmt(0): [DeclStmt] declaration -# 2304| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s2 -# 2304| Type = [Struct] String -# 2304| getVariable().getInitializer(): [Initializer] initializer for s2 -# 2304| getExpr(): [ConstructorCall] call to String -# 2304| Type = [VoidType] void +# 2303| getVariable().getInitializer(): [Initializer] initializer for c +# 2303| getExpr(): [CharLiteral] 97 +# 2303| Type = [PlainCharType] char +# 2303| Value = [CharLiteral] 97 +# 2303| ValueCategory = prvalue +# 2304| getStmt(1): [ForStmt] for(...;...;...) ... +# 2304| getInitialization(): [DeclStmt] declaration +# 2304| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s +# 2304| Type = [Struct] String +# 2304| getVariable().getInitializer(): [Initializer] initializer for s +# 2304| getExpr(): [ConstructorCall] call to String +# 2304| Type = [VoidType] void +# 2304| ValueCategory = prvalue +# 2304| getArgument(0): hello +# 2304| Type = [ArrayType] const char[6] +# 2304| Value = [StringLiteral] "hello" +# 2304| ValueCategory = lvalue +# 2304| getArgument(0).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion +# 2304| Type = [PointerType] const char * # 2304| ValueCategory = prvalue -# 2305| getImplicitDestructorCall(0): [DestructorCall] call to ~String -# 2305| Type = [VoidType] void -# 2305| ValueCategory = prvalue -# 2305| getQualifier(): [VariableAccess] s2 +# 2304| getCondition(): [NEExpr] ... != ... +# 2304| Type = [BoolType] bool +# 2304| ValueCategory = prvalue +# 2304| getLeftOperand(): [VariableAccess] c +# 2304| Type = [PlainCharType] char +# 2304| ValueCategory = prvalue(load) +# 2304| getRightOperand(): [Literal] 0 +# 2304| Type = [IntType] int +# 2304| Value = [Literal] 0 +# 2304| ValueCategory = prvalue +# 2304| getLeftOperand().getFullyConverted(): [CStyleCast] (int)... +# 2304| Conversion = [IntegralConversion] integral conversion +# 2304| Type = [IntType] int +# 2304| ValueCategory = prvalue +# 2304| getUpdate(): [AssignExpr] ... = ... +# 2304| Type = [PlainCharType] char +# 2304| ValueCategory = lvalue +# 2304| getLValue(): [VariableAccess] c +# 2304| Type = [PlainCharType] char +# 2304| ValueCategory = lvalue +# 2304| getRValue(): [FunctionCall] call to pop_back +# 2304| Type = [PlainCharType] char +# 2304| ValueCategory = prvalue +# 2304| getQualifier(): [VariableAccess] s +# 2304| Type = [Struct] String +# 2304| ValueCategory = lvalue +# 2304| getStmt(): [BlockStmt] { ... } +# 2305| getStmt(0): [DeclStmt] declaration +# 2305| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s2 # 2305| Type = [Struct] String -# 2305| ValueCategory = lvalue -# 2303| getImplicitDestructorCall(0): [DestructorCall] call to ~String -# 2303| Type = [VoidType] void -# 2303| ValueCategory = prvalue -# 2303| getQualifier(): [VariableAccess] s -# 2303| Type = [Struct] String -# 2303| ValueCategory = lvalue -# 2307| getStmt(2): [RangeBasedForStmt] for(...:...) ... -# 2307| getChild(1): [DeclStmt] declaration -# 2307| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__range) -# 2307| Type = [RValueReferenceType] vector && +# 2305| getVariable().getInitializer(): [Initializer] initializer for s2 +# 2305| getExpr(): [ConstructorCall] call to String +# 2305| Type = [VoidType] void +# 2305| ValueCategory = prvalue +# 2306| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2306| Type = [VoidType] void +# 2306| ValueCategory = prvalue +# 2306| getQualifier(): [VariableAccess] s2 +# 2306| Type = [Struct] String +# 2306| ValueCategory = lvalue +# 2304| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2304| Type = [VoidType] void +# 2304| ValueCategory = prvalue +# 2304| getQualifier(): [VariableAccess] s +# 2304| Type = [Struct] String +# 2304| ValueCategory = lvalue +# 2308| getStmt(2): [RangeBasedForStmt] for(...:...) ... +# 2308| getChild(1): [DeclStmt] declaration +# 2308| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__range) +# 2308| Type = [RValueReferenceType] vector && #-----| getVariable().getInitializer(): [Initializer] initializer for (__range) -# 2307| getExpr(): [ConstructorCall] call to vector -# 2307| Type = [VoidType] void -# 2307| ValueCategory = prvalue -# 2307| getArgument(0): [ConstructorCall] call to String -# 2307| Type = [VoidType] void -# 2307| ValueCategory = prvalue -# 2307| getArgument(0): hello -# 2307| Type = [ArrayType] const char[6] -# 2307| Value = [StringLiteral] "hello" -# 2307| ValueCategory = lvalue -# 2307| getArgument(0).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion -# 2307| Type = [PointerType] const char * -# 2307| ValueCategory = prvalue -# 2307| getArgument(0).getFullyConverted(): [TemporaryObjectExpr] temporary object -# 2307| Type = [Struct] String -# 2307| ValueCategory = lvalue -# 2307| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to) -# 2307| Type = [LValueReferenceType] vector & -# 2307| ValueCategory = prvalue -# 2307| getExpr(): [TemporaryObjectExpr] temporary object -# 2307| Type = [ClassTemplateInstantiation,Struct] vector -# 2307| ValueCategory = xvalue -# 2307| getImplicitDestructorCall(0): [DestructorCall] call to ~String -# 2307| Type = [VoidType] void -# 2307| ValueCategory = prvalue -# 2307| getQualifier(): [ReuseExpr] reuse of temporary object -# 2307| Type = [Struct] String -# 2307| ValueCategory = xvalue -# 2307| getBeginEndDeclaration(): [DeclStmt] declaration -# 2307| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__begin) -# 2307| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2308| getExpr(): [ConstructorCall] call to vector +# 2308| Type = [VoidType] void +# 2308| ValueCategory = prvalue +# 2308| getArgument(0): [ConstructorCall] call to String +# 2308| Type = [VoidType] void +# 2308| ValueCategory = prvalue +# 2308| getArgument(0): hello +# 2308| Type = [ArrayType] const char[6] +# 2308| Value = [StringLiteral] "hello" +# 2308| ValueCategory = lvalue +# 2308| getArgument(0).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion +# 2308| Type = [PointerType] const char * +# 2308| ValueCategory = prvalue +# 2308| getArgument(0).getFullyConverted(): [TemporaryObjectExpr] temporary object +# 2308| Type = [Struct] String +# 2308| ValueCategory = lvalue +# 2308| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to) +# 2308| Type = [LValueReferenceType] vector & +# 2308| ValueCategory = prvalue +# 2308| getExpr(): [TemporaryObjectExpr] temporary object +# 2308| Type = [ClassTemplateInstantiation,Struct] vector +# 2308| ValueCategory = xvalue +# 2308| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2308| Type = [VoidType] void +# 2308| ValueCategory = prvalue +# 2308| getQualifier(): [ReuseExpr] reuse of temporary object +# 2308| Type = [Struct] String +# 2308| ValueCategory = xvalue +# 2308| getBeginEndDeclaration(): [DeclStmt] declaration +# 2308| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__begin) +# 2308| Type = [NestedTypedefType,UsingAliasTypedefType] iterator #-----| getVariable().getInitializer(): [Initializer] initializer for (__begin) -# 2307| getExpr(): [FunctionCall] call to begin -# 2307| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2307| ValueCategory = prvalue -# 2307| getQualifier(): [VariableAccess] (__range) -# 2307| Type = [RValueReferenceType] vector && -# 2307| ValueCategory = prvalue(load) +# 2308| getExpr(): [FunctionCall] call to begin +# 2308| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2308| ValueCategory = prvalue +# 2308| getQualifier(): [VariableAccess] (__range) +# 2308| Type = [RValueReferenceType] vector && +# 2308| ValueCategory = prvalue(load) #-----| getQualifier().getFullyConverted(): [CStyleCast] (const vector)... #-----| Conversion = [GlvalueConversion] glvalue conversion #-----| Type = [SpecifiedType] const vector @@ -20589,15 +20591,15 @@ ir.cpp: #-----| getExpr(): [ReferenceDereferenceExpr] (reference dereference) #-----| Type = [ClassTemplateInstantiation,Struct] vector #-----| ValueCategory = lvalue -# 2307| getDeclarationEntry(1): [VariableDeclarationEntry] declaration of (__end) -# 2307| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2308| getDeclarationEntry(1): [VariableDeclarationEntry] declaration of (__end) +# 2308| Type = [NestedTypedefType,UsingAliasTypedefType] iterator #-----| getVariable().getInitializer(): [Initializer] initializer for (__end) -# 2307| getExpr(): [FunctionCall] call to end -# 2307| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2307| ValueCategory = prvalue -# 2307| getQualifier(): [VariableAccess] (__range) -# 2307| Type = [RValueReferenceType] vector && -# 2307| ValueCategory = prvalue(load) +# 2308| getExpr(): [FunctionCall] call to end +# 2308| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2308| ValueCategory = prvalue +# 2308| getQualifier(): [VariableAccess] (__range) +# 2308| Type = [RValueReferenceType] vector && +# 2308| ValueCategory = prvalue(load) #-----| getQualifier().getFullyConverted(): [CStyleCast] (const vector)... #-----| Conversion = [GlvalueConversion] glvalue conversion #-----| Type = [SpecifiedType] const vector @@ -20605,18 +20607,18 @@ ir.cpp: #-----| getExpr(): [ReferenceDereferenceExpr] (reference dereference) #-----| Type = [ClassTemplateInstantiation,Struct] vector #-----| ValueCategory = lvalue -# 2307| getCondition(): [FunctionCall] call to operator!= -# 2307| Type = [BoolType] bool -# 2307| ValueCategory = prvalue -# 2307| getQualifier(): [VariableAccess] (__begin) -# 2307| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2307| ValueCategory = lvalue -# 2307| getArgument(0): [ConstructorCall] call to iterator -# 2307| Type = [VoidType] void -# 2307| ValueCategory = prvalue -# 2307| getArgument(0): [VariableAccess] (__end) -# 2307| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2307| ValueCategory = lvalue +# 2308| getCondition(): [FunctionCall] call to operator!= +# 2308| Type = [BoolType] bool +# 2308| ValueCategory = prvalue +# 2308| getQualifier(): [VariableAccess] (__begin) +# 2308| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2308| ValueCategory = lvalue +# 2308| getArgument(0): [ConstructorCall] call to iterator +# 2308| Type = [VoidType] void +# 2308| ValueCategory = prvalue +# 2308| getArgument(0): [VariableAccess] (__end) +# 2308| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2308| ValueCategory = lvalue #-----| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to) #-----| Type = [LValueReferenceType] const iterator & #-----| ValueCategory = prvalue @@ -20631,1497 +20633,1497 @@ ir.cpp: #-----| getArgument(0).getFullyConverted(): [TemporaryObjectExpr] temporary object #-----| Type = [ClassTemplateInstantiation,Struct] iterator #-----| ValueCategory = lvalue -# 2307| getUpdate(): [FunctionCall] call to operator++ -# 2307| Type = [LValueReferenceType] iterator & -# 2307| ValueCategory = prvalue -# 2307| getQualifier(): [VariableAccess] (__begin) -# 2307| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2307| ValueCategory = lvalue -# 2307| getChild(5): [DeclStmt] declaration -# 2307| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s -# 2307| Type = [Struct] String -# 2307| getVariable().getInitializer(): [Initializer] initializer for s -# 2307| getExpr(): [ConstructorCall] call to String -# 2307| Type = [VoidType] void -# 2307| ValueCategory = prvalue -# 2307| getArgument(0): [OverloadedPointerDereferenceExpr] call to operator* -# 2307| Type = [LValueReferenceType] String & -# 2307| ValueCategory = prvalue -# 2307| getQualifier(): [VariableAccess] (__begin) -# 2307| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2307| ValueCategory = lvalue +# 2308| getUpdate(): [FunctionCall] call to operator++ +# 2308| Type = [LValueReferenceType] iterator & +# 2308| ValueCategory = prvalue +# 2308| getQualifier(): [VariableAccess] (__begin) +# 2308| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2308| ValueCategory = lvalue +# 2308| getChild(5): [DeclStmt] declaration +# 2308| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s +# 2308| Type = [Struct] String +# 2308| getVariable().getInitializer(): [Initializer] initializer for s +# 2308| getExpr(): [ConstructorCall] call to String +# 2308| Type = [VoidType] void +# 2308| ValueCategory = prvalue +# 2308| getArgument(0): [OverloadedPointerDereferenceExpr] call to operator* +# 2308| Type = [LValueReferenceType] String & +# 2308| ValueCategory = prvalue +# 2308| getQualifier(): [VariableAccess] (__begin) +# 2308| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2308| ValueCategory = lvalue #-----| getQualifier().getFullyConverted(): [CStyleCast] (const iterator)... #-----| Conversion = [GlvalueConversion] glvalue conversion #-----| Type = [SpecifiedType] const iterator #-----| ValueCategory = lvalue -# 2307| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to) -# 2307| Type = [LValueReferenceType] const String & -# 2307| ValueCategory = prvalue -# 2307| getExpr(): [CStyleCast] (const String)... -# 2307| Conversion = [GlvalueConversion] glvalue conversion -# 2307| Type = [SpecifiedType] const String -# 2307| ValueCategory = lvalue -# 2307| getExpr(): [ReferenceDereferenceExpr] (reference dereference) -# 2307| Type = [Struct] String -# 2307| ValueCategory = lvalue -# 2307| getStmt(): [BlockStmt] { ... } -# 2308| getStmt(0): [DeclStmt] declaration -# 2308| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s2 -# 2308| Type = [Struct] String -# 2308| getVariable().getInitializer(): [Initializer] initializer for s2 -# 2308| getExpr(): [ConstructorCall] call to String -# 2308| Type = [VoidType] void +# 2308| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to) +# 2308| Type = [LValueReferenceType] const String & # 2308| ValueCategory = prvalue -# 2309| getImplicitDestructorCall(0): [DestructorCall] call to ~String -# 2309| Type = [VoidType] void -# 2309| ValueCategory = prvalue -# 2309| getQualifier(): [VariableAccess] s2 +# 2308| getExpr(): [CStyleCast] (const String)... +# 2308| Conversion = [GlvalueConversion] glvalue conversion +# 2308| Type = [SpecifiedType] const String +# 2308| ValueCategory = lvalue +# 2308| getExpr(): [ReferenceDereferenceExpr] (reference dereference) +# 2308| Type = [Struct] String +# 2308| ValueCategory = lvalue +# 2308| getStmt(): [BlockStmt] { ... } +# 2309| getStmt(0): [DeclStmt] declaration +# 2309| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s2 # 2309| Type = [Struct] String -# 2309| ValueCategory = lvalue -# 2307| getImplicitDestructorCall(0): [DestructorCall] call to ~vector -# 2307| Type = [VoidType] void -# 2307| ValueCategory = prvalue -# 2307| getQualifier(): [ReuseExpr] reuse of temporary object -# 2307| Type = [ClassTemplateInstantiation,Struct] vector -# 2307| ValueCategory = xvalue -# 2307| getUpdate().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) -# 2307| Type = [ClassTemplateInstantiation,Struct] iterator -# 2307| ValueCategory = lvalue -# 2307| getImplicitDestructorCall(0): [DestructorCall] call to ~String -# 2307| Type = [VoidType] void -# 2307| ValueCategory = prvalue -# 2307| getQualifier(): [VariableAccess] s -# 2307| Type = [Struct] String -# 2307| ValueCategory = lvalue -# 2311| getStmt(3): [ForStmt] for(...;...;...) ... -# 2311| getInitialization(): [DeclStmt] declaration -# 2311| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s -# 2311| Type = [Struct] String -# 2311| getVariable().getInitializer(): [Initializer] initializer for s -# 2311| getExpr(): [ConstructorCall] call to String -# 2311| Type = [VoidType] void -# 2311| ValueCategory = prvalue -# 2311| getArgument(0): hello -# 2311| Type = [ArrayType] const char[6] -# 2311| Value = [StringLiteral] "hello" -# 2311| ValueCategory = lvalue -# 2311| getArgument(0).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion -# 2311| Type = [PointerType] const char * -# 2311| ValueCategory = prvalue -# 2311| getDeclarationEntry(1): [VariableDeclarationEntry] definition of s2 -# 2311| Type = [Struct] String -# 2311| getVariable().getInitializer(): [Initializer] initializer for s2 -# 2311| getExpr(): [ConstructorCall] call to String -# 2311| Type = [VoidType] void -# 2311| ValueCategory = prvalue -# 2311| getArgument(0): world -# 2311| Type = [ArrayType] const char[6] -# 2311| Value = [StringLiteral] "world" -# 2311| ValueCategory = lvalue -# 2311| getArgument(0).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion -# 2311| Type = [PointerType] const char * -# 2311| ValueCategory = prvalue -# 2311| getCondition(): [NEExpr] ... != ... -# 2311| Type = [BoolType] bool -# 2311| ValueCategory = prvalue -# 2311| getLeftOperand(): [VariableAccess] c -# 2311| Type = [PlainCharType] char -# 2311| ValueCategory = prvalue(load) -# 2311| getRightOperand(): [Literal] 0 -# 2311| Type = [IntType] int -# 2311| Value = [Literal] 0 -# 2311| ValueCategory = prvalue -# 2311| getLeftOperand().getFullyConverted(): [CStyleCast] (int)... -# 2311| Conversion = [IntegralConversion] integral conversion -# 2311| Type = [IntType] int -# 2311| ValueCategory = prvalue -# 2311| getUpdate(): [AssignExpr] ... = ... -# 2311| Type = [PlainCharType] char -# 2311| ValueCategory = lvalue -# 2311| getLValue(): [VariableAccess] c -# 2311| Type = [PlainCharType] char -# 2311| ValueCategory = lvalue -# 2311| getRValue(): [FunctionCall] call to pop_back -# 2311| Type = [PlainCharType] char -# 2311| ValueCategory = prvalue -# 2311| getQualifier(): [VariableAccess] s -# 2311| Type = [Struct] String -# 2311| ValueCategory = lvalue -# 2311| getStmt(): [BlockStmt] { ... } -# 2312| getStmt(0): [ExprStmt] ExprStmt -# 2312| getExpr(): [AssignExpr] ... = ... -# 2312| Type = [PlainCharType] char -# 2312| ValueCategory = lvalue -# 2312| getLValue(): [VariableAccess] c -# 2312| Type = [PlainCharType] char -# 2312| ValueCategory = lvalue -# 2312| getRValue(): [Literal] 0 -# 2312| Type = [IntType] int -# 2312| Value = [Literal] 0 +# 2309| getVariable().getInitializer(): [Initializer] initializer for s2 +# 2309| getExpr(): [ConstructorCall] call to String +# 2309| Type = [VoidType] void +# 2309| ValueCategory = prvalue +# 2310| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2310| Type = [VoidType] void +# 2310| ValueCategory = prvalue +# 2310| getQualifier(): [VariableAccess] s2 +# 2310| Type = [Struct] String +# 2310| ValueCategory = lvalue +# 2308| getImplicitDestructorCall(0): [DestructorCall] call to ~vector +# 2308| Type = [VoidType] void +# 2308| ValueCategory = prvalue +# 2308| getQualifier(): [ReuseExpr] reuse of temporary object +# 2308| Type = [ClassTemplateInstantiation,Struct] vector +# 2308| ValueCategory = xvalue +# 2308| getUpdate().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) +# 2308| Type = [ClassTemplateInstantiation,Struct] iterator +# 2308| ValueCategory = lvalue +# 2308| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2308| Type = [VoidType] void +# 2308| ValueCategory = prvalue +# 2308| getQualifier(): [VariableAccess] s +# 2308| Type = [Struct] String +# 2308| ValueCategory = lvalue +# 2312| getStmt(3): [ForStmt] for(...;...;...) ... +# 2312| getInitialization(): [DeclStmt] declaration +# 2312| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s +# 2312| Type = [Struct] String +# 2312| getVariable().getInitializer(): [Initializer] initializer for s +# 2312| getExpr(): [ConstructorCall] call to String +# 2312| Type = [VoidType] void # 2312| ValueCategory = prvalue -# 2312| getRValue().getFullyConverted(): [CStyleCast] (char)... -# 2312| Conversion = [IntegralConversion] integral conversion -# 2312| Type = [PlainCharType] char -# 2312| Value = [CStyleCast] 0 +# 2312| getArgument(0): hello +# 2312| Type = [ArrayType] const char[6] +# 2312| Value = [StringLiteral] "hello" +# 2312| ValueCategory = lvalue +# 2312| getArgument(0).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion +# 2312| Type = [PointerType] const char * +# 2312| ValueCategory = prvalue +# 2312| getDeclarationEntry(1): [VariableDeclarationEntry] definition of s2 +# 2312| Type = [Struct] String +# 2312| getVariable().getInitializer(): [Initializer] initializer for s2 +# 2312| getExpr(): [ConstructorCall] call to String +# 2312| Type = [VoidType] void # 2312| ValueCategory = prvalue -# 2311| getImplicitDestructorCall(0): [DestructorCall] call to ~String -# 2311| Type = [VoidType] void -# 2311| ValueCategory = prvalue -# 2311| getQualifier(): [VariableAccess] s2 -# 2311| Type = [Struct] String -# 2311| ValueCategory = lvalue -# 2311| getImplicitDestructorCall(1): [DestructorCall] call to ~String -# 2311| Type = [VoidType] void -# 2311| ValueCategory = prvalue -# 2311| getQualifier(): [VariableAccess] s -# 2311| Type = [Struct] String -# 2311| ValueCategory = lvalue -# 2314| getStmt(4): [ReturnStmt] return ... -# 2316| [TopLevelFunction] void IfDestructors2(bool) -# 2316| : -# 2316| getParameter(0): [Parameter] b -# 2316| Type = [BoolType] bool -# 2316| getEntryPoint(): [BlockStmt] { ... } -# 2317| getStmt(0): [IfStmt] if (...) ... -# 2317| getInitialization(): [DeclStmt] declaration -# 2317| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s -# 2317| Type = [Struct] String -# 2317| getVariable().getInitializer(): [Initializer] initializer for s -# 2317| getExpr(): [ConstructorCall] call to String -# 2317| Type = [VoidType] void -# 2317| ValueCategory = prvalue -# 2317| getArgument(0): hello -# 2317| Type = [ArrayType] const char[6] -# 2317| Value = [StringLiteral] "hello" -# 2317| ValueCategory = lvalue -# 2317| getArgument(0).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion -# 2317| Type = [PointerType] const char * -# 2317| ValueCategory = prvalue -# 2317| getCondition(): [VariableAccess] b -# 2317| Type = [BoolType] bool -# 2317| ValueCategory = prvalue(load) -# 2317| getThen(): [BlockStmt] { ... } -# 2318| getStmt(0): [DeclStmt] declaration -# 2318| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x -# 2318| Type = [IntType] int -# 2318| getVariable().getInitializer(): [Initializer] initializer for x -# 2318| getExpr(): [Literal] 0 -# 2318| Type = [IntType] int -# 2318| Value = [Literal] 0 +# 2312| getArgument(0): world +# 2312| Type = [ArrayType] const char[6] +# 2312| Value = [StringLiteral] "world" +# 2312| ValueCategory = lvalue +# 2312| getArgument(0).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion +# 2312| Type = [PointerType] const char * +# 2312| ValueCategory = prvalue +# 2312| getCondition(): [NEExpr] ... != ... +# 2312| Type = [BoolType] bool +# 2312| ValueCategory = prvalue +# 2312| getLeftOperand(): [VariableAccess] c +# 2312| Type = [PlainCharType] char +# 2312| ValueCategory = prvalue(load) +# 2312| getRightOperand(): [Literal] 0 +# 2312| Type = [IntType] int +# 2312| Value = [Literal] 0 +# 2312| ValueCategory = prvalue +# 2312| getLeftOperand().getFullyConverted(): [CStyleCast] (int)... +# 2312| Conversion = [IntegralConversion] integral conversion +# 2312| Type = [IntType] int +# 2312| ValueCategory = prvalue +# 2312| getUpdate(): [AssignExpr] ... = ... +# 2312| Type = [PlainCharType] char +# 2312| ValueCategory = lvalue +# 2312| getLValue(): [VariableAccess] c +# 2312| Type = [PlainCharType] char +# 2312| ValueCategory = lvalue +# 2312| getRValue(): [FunctionCall] call to pop_back +# 2312| Type = [PlainCharType] char +# 2312| ValueCategory = prvalue +# 2312| getQualifier(): [VariableAccess] s +# 2312| Type = [Struct] String +# 2312| ValueCategory = lvalue +# 2312| getStmt(): [BlockStmt] { ... } +# 2313| getStmt(0): [ExprStmt] ExprStmt +# 2313| getExpr(): [AssignExpr] ... = ... +# 2313| Type = [PlainCharType] char +# 2313| ValueCategory = lvalue +# 2313| getLValue(): [VariableAccess] c +# 2313| Type = [PlainCharType] char +# 2313| ValueCategory = lvalue +# 2313| getRValue(): [Literal] 0 +# 2313| Type = [IntType] int +# 2313| Value = [Literal] 0 +# 2313| ValueCategory = prvalue +# 2313| getRValue().getFullyConverted(): [CStyleCast] (char)... +# 2313| Conversion = [IntegralConversion] integral conversion +# 2313| Type = [PlainCharType] char +# 2313| Value = [CStyleCast] 0 +# 2313| ValueCategory = prvalue +# 2312| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2312| Type = [VoidType] void +# 2312| ValueCategory = prvalue +# 2312| getQualifier(): [VariableAccess] s2 +# 2312| Type = [Struct] String +# 2312| ValueCategory = lvalue +# 2312| getImplicitDestructorCall(1): [DestructorCall] call to ~String +# 2312| Type = [VoidType] void +# 2312| ValueCategory = prvalue +# 2312| getQualifier(): [VariableAccess] s +# 2312| Type = [Struct] String +# 2312| ValueCategory = lvalue +# 2315| getStmt(4): [ReturnStmt] return ... +# 2317| [TopLevelFunction] void IfDestructors2(bool) +# 2317| : +# 2317| getParameter(0): [Parameter] b +# 2317| Type = [BoolType] bool +# 2317| getEntryPoint(): [BlockStmt] { ... } +# 2318| getStmt(0): [IfStmt] if (...) ... +# 2318| getInitialization(): [DeclStmt] declaration +# 2318| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s +# 2318| Type = [Struct] String +# 2318| getVariable().getInitializer(): [Initializer] initializer for s +# 2318| getExpr(): [ConstructorCall] call to String +# 2318| Type = [VoidType] void +# 2318| ValueCategory = prvalue +# 2318| getArgument(0): hello +# 2318| Type = [ArrayType] const char[6] +# 2318| Value = [StringLiteral] "hello" +# 2318| ValueCategory = lvalue +# 2318| getArgument(0).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion +# 2318| Type = [PointerType] const char * # 2318| ValueCategory = prvalue -# 2319| getElse(): [BlockStmt] { ... } -# 2320| getStmt(0): [DeclStmt] declaration -# 2320| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y -# 2320| Type = [IntType] int -# 2320| getVariable().getInitializer(): [Initializer] initializer for y -# 2320| getExpr(): [Literal] 0 -# 2320| Type = [IntType] int -# 2320| Value = [Literal] 0 -# 2320| ValueCategory = prvalue -# 2321| getImplicitDestructorCall(0): [DestructorCall] call to ~String -# 2321| Type = [VoidType] void -# 2321| ValueCategory = prvalue -# 2321| getQualifier(): [VariableAccess] s -# 2321| Type = [Struct] String -# 2321| ValueCategory = lvalue -# 2322| getStmt(1): [ReturnStmt] return ... -# 2324| [CopyAssignmentOperator] Bool& Bool::operator=(Bool const&) -# 2324| : +# 2318| getCondition(): [VariableAccess] b +# 2318| Type = [BoolType] bool +# 2318| ValueCategory = prvalue(load) +# 2318| getThen(): [BlockStmt] { ... } +# 2319| getStmt(0): [DeclStmt] declaration +# 2319| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x +# 2319| Type = [IntType] int +# 2319| getVariable().getInitializer(): [Initializer] initializer for x +# 2319| getExpr(): [Literal] 0 +# 2319| Type = [IntType] int +# 2319| Value = [Literal] 0 +# 2319| ValueCategory = prvalue +# 2320| getElse(): [BlockStmt] { ... } +# 2321| getStmt(0): [DeclStmt] declaration +# 2321| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y +# 2321| Type = [IntType] int +# 2321| getVariable().getInitializer(): [Initializer] initializer for y +# 2321| getExpr(): [Literal] 0 +# 2321| Type = [IntType] int +# 2321| Value = [Literal] 0 +# 2321| ValueCategory = prvalue +# 2322| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2322| Type = [VoidType] void +# 2322| ValueCategory = prvalue +# 2322| getQualifier(): [VariableAccess] s +# 2322| Type = [Struct] String +# 2322| ValueCategory = lvalue +# 2323| getStmt(1): [ReturnStmt] return ... +# 2325| [CopyAssignmentOperator] Bool& Bool::operator=(Bool const&) +# 2325| : #-----| getParameter(0): [Parameter] (unnamed parameter 0) #-----| Type = [LValueReferenceType] const Bool & -# 2324| [CopyConstructor] void Bool::Bool(Bool const&) -# 2324| : +# 2325| [CopyConstructor] void Bool::Bool(Bool const&) +# 2325| : #-----| getParameter(0): [Parameter] (unnamed parameter 0) #-----| Type = [LValueReferenceType] const Bool & -# 2326| [Constructor] void Bool::Bool(bool) -# 2326| : -# 2326| getParameter(0): [Parameter] b_ -# 2326| Type = [BoolType] bool -# 2327| [ConversionOperator] bool Bool::operator bool() +# 2327| [Constructor] void Bool::Bool(bool) # 2327| : -# 2328| [Destructor] void Bool::~Bool() +# 2327| getParameter(0): [Parameter] b_ +# 2327| Type = [BoolType] bool +# 2328| [ConversionOperator] bool Bool::operator bool() # 2328| : -# 2331| [TopLevelFunction] void IfDestructors3(bool) -# 2331| : -# 2331| getParameter(0): [Parameter] b -# 2331| Type = [BoolType] bool -# 2331| getEntryPoint(): [BlockStmt] { ... } -# 2332| getStmt(0): [IfStmt] if (...) ... -# 2332| getCondition(): [ConditionDeclExpr] (condition decl) -# 2332| Type = [BoolType] bool -# 2332| ValueCategory = prvalue -# 2332| getChild(0): [FunctionCall] call to operator bool -# 2332| Type = [BoolType] bool -# 2332| ValueCategory = prvalue -# 2332| getQualifier(): [VariableAccess] B -# 2332| Type = [Class] Bool -# 2332| ValueCategory = prvalue(load) -# 2332| getInitializingExpr(): [ConstructorCall] call to Bool -# 2332| Type = [VoidType] void -# 2332| ValueCategory = prvalue -# 2332| getArgument(0): [VariableAccess] b -# 2332| Type = [BoolType] bool -# 2332| ValueCategory = prvalue(load) -# 2332| getThen(): [BlockStmt] { ... } -# 2333| getStmt(0): [DeclStmt] declaration -# 2333| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s1 -# 2333| Type = [Struct] String -# 2333| getVariable().getInitializer(): [Initializer] initializer for s1 -# 2333| getExpr(): [ConstructorCall] call to String -# 2333| Type = [VoidType] void -# 2333| ValueCategory = prvalue -# 2334| getImplicitDestructorCall(0): [DestructorCall] call to ~String -# 2334| Type = [VoidType] void -# 2334| ValueCategory = prvalue -# 2334| getQualifier(): [VariableAccess] s1 +# 2329| [Destructor] void Bool::~Bool() +# 2329| : +# 2332| [TopLevelFunction] void IfDestructors3(bool) +# 2332| : +# 2332| getParameter(0): [Parameter] b +# 2332| Type = [BoolType] bool +# 2332| getEntryPoint(): [BlockStmt] { ... } +# 2333| getStmt(0): [IfStmt] if (...) ... +# 2333| getCondition(): [ConditionDeclExpr] (condition decl) +# 2333| Type = [BoolType] bool +# 2333| ValueCategory = prvalue +# 2333| getChild(0): [FunctionCall] call to operator bool +# 2333| Type = [BoolType] bool +# 2333| ValueCategory = prvalue +# 2333| getQualifier(): [VariableAccess] B +# 2333| Type = [Class] Bool +# 2333| ValueCategory = prvalue(load) +# 2333| getInitializingExpr(): [ConstructorCall] call to Bool +# 2333| Type = [VoidType] void +# 2333| ValueCategory = prvalue +# 2333| getArgument(0): [VariableAccess] b +# 2333| Type = [BoolType] bool +# 2333| ValueCategory = prvalue(load) +# 2333| getThen(): [BlockStmt] { ... } +# 2334| getStmt(0): [DeclStmt] declaration +# 2334| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s1 # 2334| Type = [Struct] String -# 2334| ValueCategory = lvalue -# 2334| getElse(): [BlockStmt] { ... } -# 2335| getStmt(0): [DeclStmt] declaration -# 2335| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s2 +# 2334| getVariable().getInitializer(): [Initializer] initializer for s1 +# 2334| getExpr(): [ConstructorCall] call to String +# 2334| Type = [VoidType] void +# 2334| ValueCategory = prvalue +# 2335| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2335| Type = [VoidType] void +# 2335| ValueCategory = prvalue +# 2335| getQualifier(): [VariableAccess] s1 # 2335| Type = [Struct] String -# 2335| getVariable().getInitializer(): [Initializer] initializer for s2 -# 2335| getExpr(): [ConstructorCall] call to String -# 2335| Type = [VoidType] void -# 2335| ValueCategory = prvalue -# 2336| getImplicitDestructorCall(0): [DestructorCall] call to ~String -# 2336| Type = [VoidType] void -# 2336| ValueCategory = prvalue -# 2336| getQualifier(): [VariableAccess] s2 +# 2335| ValueCategory = lvalue +# 2335| getElse(): [BlockStmt] { ... } +# 2336| getStmt(0): [DeclStmt] declaration +# 2336| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s2 # 2336| Type = [Struct] String -# 2336| ValueCategory = lvalue -# 2336| getImplicitDestructorCall(0): [DestructorCall] call to ~Bool -# 2336| Type = [VoidType] void -# 2336| ValueCategory = prvalue -# 2336| getQualifier(): [VariableAccess] B -# 2336| Type = [Class] Bool -# 2336| ValueCategory = lvalue -# 2337| getStmt(1): [ReturnStmt] return ... -# 2339| [TopLevelFunction] void WhileLoopDestructors(bool) -# 2339| : -# 2339| getParameter(0): [Parameter] b -# 2339| Type = [BoolType] bool -# 2339| getEntryPoint(): [BlockStmt] { ... } -# 2340| getStmt(0): [BlockStmt] { ... } -# 2341| getStmt(0): [DeclStmt] declaration -# 2341| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s -# 2341| Type = [Struct] String -# 2341| getVariable().getInitializer(): [Initializer] initializer for s -# 2341| getExpr(): [ConstructorCall] call to String -# 2341| Type = [VoidType] void -# 2341| ValueCategory = prvalue -# 2342| getStmt(1): [WhileStmt] while (...) ... -# 2342| getCondition(): [VariableAccess] b -# 2342| Type = [BoolType] bool -# 2342| ValueCategory = prvalue(load) -# 2342| getStmt(): [BlockStmt] { ... } -# 2343| getStmt(0): [ExprStmt] ExprStmt -# 2343| getExpr(): [AssignExpr] ... = ... -# 2343| Type = [BoolType] bool -# 2343| ValueCategory = lvalue -# 2343| getLValue(): [VariableAccess] b -# 2343| Type = [BoolType] bool -# 2343| ValueCategory = lvalue -# 2343| getRValue(): [Literal] 0 -# 2343| Type = [BoolType] bool -# 2343| Value = [Literal] 0 -# 2343| ValueCategory = prvalue -# 2345| getImplicitDestructorCall(0): [DestructorCall] call to ~String -# 2345| Type = [VoidType] void -# 2345| ValueCategory = prvalue -# 2345| getQualifier(): [VariableAccess] s -# 2345| Type = [Struct] String -# 2345| ValueCategory = lvalue -# 2347| getStmt(1): [BlockStmt] { ... } -# 2348| getStmt(0): [WhileStmt] while (...) ... -# 2348| getCondition(): [ConditionDeclExpr] (condition decl) -# 2348| Type = [BoolType] bool -# 2348| ValueCategory = prvalue -# 2348| getChild(0): [FunctionCall] call to operator bool -# 2348| Type = [BoolType] bool -# 2348| ValueCategory = prvalue -# 2348| getQualifier(): [VariableAccess] B -# 2348| Type = [Class] Bool -# 2348| ValueCategory = prvalue(load) -# 2348| getInitializingExpr(): [ConstructorCall] call to Bool -# 2348| Type = [VoidType] void -# 2348| ValueCategory = prvalue -# 2348| getArgument(0): [VariableAccess] b -# 2348| Type = [BoolType] bool -# 2348| ValueCategory = prvalue(load) -# 2348| getStmt(): [BlockStmt] { ... } -# 2349| getStmt(0): [ExprStmt] ExprStmt -# 2349| getExpr(): [AssignExpr] ... = ... +# 2336| getVariable().getInitializer(): [Initializer] initializer for s2 +# 2336| getExpr(): [ConstructorCall] call to String +# 2336| Type = [VoidType] void +# 2336| ValueCategory = prvalue +# 2337| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2337| Type = [VoidType] void +# 2337| ValueCategory = prvalue +# 2337| getQualifier(): [VariableAccess] s2 +# 2337| Type = [Struct] String +# 2337| ValueCategory = lvalue +# 2337| getImplicitDestructorCall(0): [DestructorCall] call to ~Bool +# 2337| Type = [VoidType] void +# 2337| ValueCategory = prvalue +# 2337| getQualifier(): [VariableAccess] B +# 2337| Type = [Class] Bool +# 2337| ValueCategory = lvalue +# 2338| getStmt(1): [ReturnStmt] return ... +# 2340| [TopLevelFunction] void WhileLoopDestructors(bool) +# 2340| : +# 2340| getParameter(0): [Parameter] b +# 2340| Type = [BoolType] bool +# 2340| getEntryPoint(): [BlockStmt] { ... } +# 2341| getStmt(0): [BlockStmt] { ... } +# 2342| getStmt(0): [DeclStmt] declaration +# 2342| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s +# 2342| Type = [Struct] String +# 2342| getVariable().getInitializer(): [Initializer] initializer for s +# 2342| getExpr(): [ConstructorCall] call to String +# 2342| Type = [VoidType] void +# 2342| ValueCategory = prvalue +# 2343| getStmt(1): [WhileStmt] while (...) ... +# 2343| getCondition(): [VariableAccess] b +# 2343| Type = [BoolType] bool +# 2343| ValueCategory = prvalue(load) +# 2343| getStmt(): [BlockStmt] { ... } +# 2344| getStmt(0): [ExprStmt] ExprStmt +# 2344| getExpr(): [AssignExpr] ... = ... +# 2344| Type = [BoolType] bool +# 2344| ValueCategory = lvalue +# 2344| getLValue(): [VariableAccess] b +# 2344| Type = [BoolType] bool +# 2344| ValueCategory = lvalue +# 2344| getRValue(): [Literal] 0 +# 2344| Type = [BoolType] bool +# 2344| Value = [Literal] 0 +# 2344| ValueCategory = prvalue +# 2346| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2346| Type = [VoidType] void +# 2346| ValueCategory = prvalue +# 2346| getQualifier(): [VariableAccess] s +# 2346| Type = [Struct] String +# 2346| ValueCategory = lvalue +# 2348| getStmt(1): [BlockStmt] { ... } +# 2349| getStmt(0): [WhileStmt] while (...) ... +# 2349| getCondition(): [ConditionDeclExpr] (condition decl) +# 2349| Type = [BoolType] bool +# 2349| ValueCategory = prvalue +# 2349| getChild(0): [FunctionCall] call to operator bool +# 2349| Type = [BoolType] bool +# 2349| ValueCategory = prvalue +# 2349| getQualifier(): [VariableAccess] B +# 2349| Type = [Class] Bool +# 2349| ValueCategory = prvalue(load) +# 2349| getInitializingExpr(): [ConstructorCall] call to Bool +# 2349| Type = [VoidType] void +# 2349| ValueCategory = prvalue +# 2349| getArgument(0): [VariableAccess] b # 2349| Type = [BoolType] bool -# 2349| ValueCategory = lvalue -# 2349| getLValue(): [VariableAccess] b -# 2349| Type = [BoolType] bool -# 2349| ValueCategory = lvalue -# 2349| getRValue(): [Literal] 0 -# 2349| Type = [BoolType] bool -# 2349| Value = [Literal] 0 -# 2349| ValueCategory = prvalue -# 2350| getImplicitDestructorCall(0): [DestructorCall] call to ~Bool -# 2350| Type = [VoidType] void -# 2350| ValueCategory = prvalue -# 2350| getQualifier(): [VariableAccess] B -# 2350| Type = [Class] Bool +# 2349| ValueCategory = prvalue(load) +# 2349| getStmt(): [BlockStmt] { ... } +# 2350| getStmt(0): [ExprStmt] ExprStmt +# 2350| getExpr(): [AssignExpr] ... = ... +# 2350| Type = [BoolType] bool # 2350| ValueCategory = lvalue -# 2350| getImplicitDestructorCall(0): [DestructorCall] call to ~Bool -# 2350| Type = [VoidType] void -# 2350| ValueCategory = prvalue -# 2350| getQualifier(): [VariableAccess] B -# 2350| Type = [Class] Bool -# 2350| ValueCategory = lvalue -# 2352| getStmt(2): [ReturnStmt] return ... -# 2354| [TopLevelFunction] void VoidFunc() -# 2354| : -# 2354| getEntryPoint(): [BlockStmt] { ... } -# 2354| getStmt(0): [ReturnStmt] return ... -# 2356| [TopLevelFunction] void IfReturnDestructors(bool) -# 2356| : -# 2356| getParameter(0): [Parameter] b -# 2356| Type = [BoolType] bool -# 2356| getEntryPoint(): [BlockStmt] { ... } -# 2357| getStmt(0): [DeclStmt] declaration -# 2357| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s -# 2357| Type = [Struct] String -# 2357| getVariable().getInitializer(): [Initializer] initializer for s -# 2357| getExpr(): [ConstructorCall] call to String -# 2357| Type = [VoidType] void -# 2357| ValueCategory = prvalue -# 2358| getStmt(1): [IfStmt] if (...) ... -# 2358| getCondition(): [VariableAccess] b -# 2358| Type = [BoolType] bool -# 2358| ValueCategory = prvalue(load) -# 2358| getThen(): [BlockStmt] { ... } -# 2359| getStmt(0): [ReturnStmt] return ... -# 2365| getImplicitDestructorCall(0): [DestructorCall] call to ~String -# 2365| Type = [VoidType] void -# 2365| ValueCategory = prvalue -# 2365| getQualifier(): [VariableAccess] s -# 2365| Type = [Struct] String -# 2365| ValueCategory = lvalue -# 2361| getStmt(2): [IfStmt] if (...) ... -# 2361| getCondition(): [VariableAccess] b -# 2361| Type = [BoolType] bool -# 2361| ValueCategory = prvalue(load) -# 2361| getThen(): [BlockStmt] { ... } -# 2362| getStmt(0): [ReturnStmt] return ... -# 2362| getExpr(): [FunctionCall] call to VoidFunc -# 2362| Type = [VoidType] void -# 2362| ValueCategory = prvalue -# 2365| getImplicitDestructorCall(0): [DestructorCall] call to ~String -# 2365| Type = [VoidType] void -# 2365| ValueCategory = prvalue -# 2365| getQualifier(): [VariableAccess] s -# 2365| Type = [Struct] String -# 2365| ValueCategory = lvalue -# 2364| getStmt(3): [ExprStmt] ExprStmt -# 2364| getExpr(): [VariableAccess] s -# 2364| Type = [Struct] String -# 2364| ValueCategory = lvalue -# 2365| getStmt(4): [ReturnStmt] return ... -# 2365| getImplicitDestructorCall(0): [DestructorCall] call to ~String -# 2365| Type = [VoidType] void -# 2365| ValueCategory = prvalue -# 2365| getQualifier(): [VariableAccess] s -# 2365| Type = [Struct] String -# 2365| ValueCategory = lvalue -# 2367| [TopLevelFunction] int IfReturnDestructors3(bool) -# 2367| : -# 2367| getParameter(0): [Parameter] b -# 2367| Type = [BoolType] bool -# 2367| getEntryPoint(): [BlockStmt] { ... } -# 2368| getStmt(0): [DeclStmt] declaration -# 2368| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s -# 2368| Type = [Struct] String -# 2368| getVariable().getInitializer(): [Initializer] initializer for s -# 2368| getExpr(): [ConstructorCall] call to String -# 2368| Type = [VoidType] void -# 2368| ValueCategory = prvalue -# 2369| getStmt(1): [IfStmt] if (...) ... -# 2369| getCondition(): [VariableAccess] b -# 2369| Type = [BoolType] bool -# 2369| ValueCategory = prvalue(load) -# 2369| getThen(): [BlockStmt] { ... } -# 2370| getStmt(0): [ReturnStmt] return ... -# 2370| getExpr(): [Literal] 1 -# 2370| Type = [IntType] int -# 2370| Value = [Literal] 1 -# 2370| ValueCategory = prvalue -# 2373| getImplicitDestructorCall(0): [DestructorCall] call to ~String -# 2373| Type = [VoidType] void -# 2373| ValueCategory = prvalue -# 2373| getQualifier(): [VariableAccess] s -# 2373| Type = [Struct] String -# 2373| ValueCategory = lvalue -# 2372| getStmt(2): [ReturnStmt] return ... -# 2372| getExpr(): [Literal] 0 -# 2372| Type = [IntType] int -# 2372| Value = [Literal] 0 -# 2372| ValueCategory = prvalue -# 2373| getImplicitDestructorCall(0): [DestructorCall] call to ~String -# 2373| Type = [VoidType] void +# 2350| getLValue(): [VariableAccess] b +# 2350| Type = [BoolType] bool +# 2350| ValueCategory = lvalue +# 2350| getRValue(): [Literal] 0 +# 2350| Type = [BoolType] bool +# 2350| Value = [Literal] 0 +# 2350| ValueCategory = prvalue +# 2351| getImplicitDestructorCall(0): [DestructorCall] call to ~Bool +# 2351| Type = [VoidType] void +# 2351| ValueCategory = prvalue +# 2351| getQualifier(): [VariableAccess] B +# 2351| Type = [Class] Bool +# 2351| ValueCategory = lvalue +# 2351| getImplicitDestructorCall(0): [DestructorCall] call to ~Bool +# 2351| Type = [VoidType] void +# 2351| ValueCategory = prvalue +# 2351| getQualifier(): [VariableAccess] B +# 2351| Type = [Class] Bool +# 2351| ValueCategory = lvalue +# 2353| getStmt(2): [ReturnStmt] return ... +# 2355| [TopLevelFunction] void VoidFunc() +# 2355| : +# 2355| getEntryPoint(): [BlockStmt] { ... } +# 2355| getStmt(0): [ReturnStmt] return ... +# 2357| [TopLevelFunction] void IfReturnDestructors(bool) +# 2357| : +# 2357| getParameter(0): [Parameter] b +# 2357| Type = [BoolType] bool +# 2357| getEntryPoint(): [BlockStmt] { ... } +# 2358| getStmt(0): [DeclStmt] declaration +# 2358| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s +# 2358| Type = [Struct] String +# 2358| getVariable().getInitializer(): [Initializer] initializer for s +# 2358| getExpr(): [ConstructorCall] call to String +# 2358| Type = [VoidType] void +# 2358| ValueCategory = prvalue +# 2359| getStmt(1): [IfStmt] if (...) ... +# 2359| getCondition(): [VariableAccess] b +# 2359| Type = [BoolType] bool +# 2359| ValueCategory = prvalue(load) +# 2359| getThen(): [BlockStmt] { ... } +# 2360| getStmt(0): [ReturnStmt] return ... +# 2366| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2366| Type = [VoidType] void +# 2366| ValueCategory = prvalue +# 2366| getQualifier(): [VariableAccess] s +# 2366| Type = [Struct] String +# 2366| ValueCategory = lvalue +# 2362| getStmt(2): [IfStmt] if (...) ... +# 2362| getCondition(): [VariableAccess] b +# 2362| Type = [BoolType] bool +# 2362| ValueCategory = prvalue(load) +# 2362| getThen(): [BlockStmt] { ... } +# 2363| getStmt(0): [ReturnStmt] return ... +# 2363| getExpr(): [FunctionCall] call to VoidFunc +# 2363| Type = [VoidType] void +# 2363| ValueCategory = prvalue +# 2366| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2366| Type = [VoidType] void +# 2366| ValueCategory = prvalue +# 2366| getQualifier(): [VariableAccess] s +# 2366| Type = [Struct] String +# 2366| ValueCategory = lvalue +# 2365| getStmt(3): [ExprStmt] ExprStmt +# 2365| getExpr(): [VariableAccess] s +# 2365| Type = [Struct] String +# 2365| ValueCategory = lvalue +# 2366| getStmt(4): [ReturnStmt] return ... +# 2366| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2366| Type = [VoidType] void +# 2366| ValueCategory = prvalue +# 2366| getQualifier(): [VariableAccess] s +# 2366| Type = [Struct] String +# 2366| ValueCategory = lvalue +# 2368| [TopLevelFunction] int IfReturnDestructors3(bool) +# 2368| : +# 2368| getParameter(0): [Parameter] b +# 2368| Type = [BoolType] bool +# 2368| getEntryPoint(): [BlockStmt] { ... } +# 2369| getStmt(0): [DeclStmt] declaration +# 2369| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s +# 2369| Type = [Struct] String +# 2369| getVariable().getInitializer(): [Initializer] initializer for s +# 2369| getExpr(): [ConstructorCall] call to String +# 2369| Type = [VoidType] void +# 2369| ValueCategory = prvalue +# 2370| getStmt(1): [IfStmt] if (...) ... +# 2370| getCondition(): [VariableAccess] b +# 2370| Type = [BoolType] bool +# 2370| ValueCategory = prvalue(load) +# 2370| getThen(): [BlockStmt] { ... } +# 2371| getStmt(0): [ReturnStmt] return ... +# 2371| getExpr(): [Literal] 1 +# 2371| Type = [IntType] int +# 2371| Value = [Literal] 1 +# 2371| ValueCategory = prvalue +# 2374| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2374| Type = [VoidType] void +# 2374| ValueCategory = prvalue +# 2374| getQualifier(): [VariableAccess] s +# 2374| Type = [Struct] String +# 2374| ValueCategory = lvalue +# 2373| getStmt(2): [ReturnStmt] return ... +# 2373| getExpr(): [Literal] 0 +# 2373| Type = [IntType] int +# 2373| Value = [Literal] 0 # 2373| ValueCategory = prvalue -# 2373| getQualifier(): [VariableAccess] s -# 2373| Type = [Struct] String -# 2373| ValueCategory = lvalue -# 2375| [TopLevelFunction] void VoidReturnDestructors() -# 2375| : -# 2375| getEntryPoint(): [BlockStmt] { ... } -# 2376| getStmt(0): [DeclStmt] declaration -# 2376| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s -# 2376| Type = [Struct] String -# 2376| getVariable().getInitializer(): [Initializer] initializer for s -# 2376| getExpr(): [ConstructorCall] call to String -# 2376| Type = [VoidType] void -# 2376| ValueCategory = prvalue -# 2377| getStmt(1): [ReturnStmt] return ... -# 2377| getExpr(): [FunctionCall] call to VoidFunc -# 2377| Type = [VoidType] void -# 2377| ValueCategory = prvalue -# 2378| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2374| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2374| Type = [VoidType] void +# 2374| ValueCategory = prvalue +# 2374| getQualifier(): [VariableAccess] s +# 2374| Type = [Struct] String +# 2374| ValueCategory = lvalue +# 2376| [TopLevelFunction] void VoidReturnDestructors() +# 2376| : +# 2376| getEntryPoint(): [BlockStmt] { ... } +# 2377| getStmt(0): [DeclStmt] declaration +# 2377| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s +# 2377| Type = [Struct] String +# 2377| getVariable().getInitializer(): [Initializer] initializer for s +# 2377| getExpr(): [ConstructorCall] call to String +# 2377| Type = [VoidType] void +# 2377| ValueCategory = prvalue +# 2378| getStmt(1): [ReturnStmt] return ... +# 2378| getExpr(): [FunctionCall] call to VoidFunc # 2378| Type = [VoidType] void # 2378| ValueCategory = prvalue -# 2378| getQualifier(): [VariableAccess] s -# 2378| Type = [Struct] String -# 2378| ValueCategory = lvalue -# 2381| [CopyAssignmentOperator] return_routine_type::HasVoidToIntFunc& return_routine_type::HasVoidToIntFunc::operator=(return_routine_type::HasVoidToIntFunc const&) -# 2381| : +# 2379| getImplicitDestructorCall(0): [DestructorCall] call to ~String +# 2379| Type = [VoidType] void +# 2379| ValueCategory = prvalue +# 2379| getQualifier(): [VariableAccess] s +# 2379| Type = [Struct] String +# 2379| ValueCategory = lvalue +# 2382| [CopyAssignmentOperator] return_routine_type::HasVoidToIntFunc& return_routine_type::HasVoidToIntFunc::operator=(return_routine_type::HasVoidToIntFunc const&) +# 2382| : #-----| getParameter(0): [Parameter] (unnamed parameter 0) #-----| Type = [LValueReferenceType] const HasVoidToIntFunc & -# 2381| [MoveAssignmentOperator] return_routine_type::HasVoidToIntFunc& return_routine_type::HasVoidToIntFunc::operator=(return_routine_type::HasVoidToIntFunc&&) -# 2381| : +# 2382| [MoveAssignmentOperator] return_routine_type::HasVoidToIntFunc& return_routine_type::HasVoidToIntFunc::operator=(return_routine_type::HasVoidToIntFunc&&) +# 2382| : #-----| getParameter(0): [Parameter] (unnamed parameter 0) #-----| Type = [RValueReferenceType] HasVoidToIntFunc && -# 2383| [MemberFunction] void return_routine_type::HasVoidToIntFunc::VoidToInt(int) -# 2383| : -# 2383| getParameter(0): [Parameter] (unnamed parameter 0) -# 2383| Type = [IntType] int -# 2388| [TopLevelFunction] return_routine_type::VoidToIntMemberFunc return_routine_type::GetVoidToIntFunc() -# 2388| : -# 2389| getEntryPoint(): [BlockStmt] { ... } -# 2390| getStmt(0): [ReturnStmt] return ... -# 2390| getExpr(): [FunctionAccess] VoidToInt -# 2390| Type = [RoutineType] ..()(..) -# 2390| ValueCategory = prvalue -# 2395| [TopLevelFunction] int small_operation_should_not_be_constant_folded() -# 2395| : -# 2395| getEntryPoint(): [BlockStmt] { ... } -# 2396| getStmt(0): [ReturnStmt] return ... -# 2396| getExpr(): [BitwiseXorExpr] ... ^ ... -# 2396| Type = [IntType] int -# 2396| Value = [BitwiseXorExpr] 3 -# 2396| ValueCategory = prvalue -# 2396| getLeftOperand(): [Literal] 1 -# 2396| Type = [IntType] int -# 2396| Value = [Literal] 1 -# 2396| ValueCategory = prvalue -# 2396| getRightOperand(): [Literal] 2 -# 2396| Type = [IntType] int -# 2396| Value = [Literal] 2 -# 2396| ValueCategory = prvalue -# 2406| [TopLevelFunction] int large_operation_should_be_constant_folded() -# 2406| : -# 2406| getEntryPoint(): [BlockStmt] { ... } -# 2407| getStmt(0): [ReturnStmt] return ... -# 2407| getExpr(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [BitwiseXorExpr] ... ^ ... -# 2407| Type = [IntType] int -# 2407| Value = [BitwiseXorExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand(): [Literal] 1 -# 2407| Type = [IntType] int -# 2407| Value = [Literal] 1 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2407| getExpr().getFullyConverted(): [ParenthesisExpr] (...) -# 2407| Type = [IntType] int -# 2407| Value = [ParenthesisExpr] 0 -# 2407| ValueCategory = prvalue -# 2410| [TopLevelFunction] void initialization_with_temp_destructor() -# 2410| : -# 2410| getEntryPoint(): [BlockStmt] { ... } -# 2411| getStmt(0): [IfStmt] if (...) ... -# 2411| getCondition(): [ConditionDeclExpr] (condition decl) -# 2411| Type = [BoolType] bool -# 2411| ValueCategory = prvalue -# 2411| getVariableAccess(): [VariableAccess] x -# 2411| Type = [PlainCharType] char -# 2411| ValueCategory = prvalue(load) -# 2411| getInitializingExpr(): [FunctionCall] call to get_x -# 2411| Type = [PlainCharType] char -# 2411| ValueCategory = prvalue -# 2411| getQualifier(): [ConstructorCall] call to ClassWithDestructor -# 2411| Type = [VoidType] void -# 2411| ValueCategory = prvalue -# 2411| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2411| Type = [VoidType] void -# 2411| ValueCategory = prvalue -# 2411| getQualifier(): [ReuseExpr] reuse of temporary object -# 2411| Type = [Class] ClassWithDestructor -# 2411| ValueCategory = xvalue -# 2411| getQualifier().getFullyConverted(): [TemporaryObjectExpr] temporary object -# 2411| Type = [Class] ClassWithDestructor -# 2411| ValueCategory = prvalue(load) -# 2411| getVariableAccess().getFullyConverted(): [CStyleCast] (bool)... -# 2411| Conversion = [BoolConversion] conversion to bool -# 2411| Type = [BoolType] bool -# 2411| ValueCategory = prvalue -# 2412| getThen(): [ExprStmt] ExprStmt -# 2412| getExpr(): [PostfixIncrExpr] ... ++ +# 2384| [MemberFunction] void return_routine_type::HasVoidToIntFunc::VoidToInt(int) +# 2384| : +# 2384| getParameter(0): [Parameter] (unnamed parameter 0) +# 2384| Type = [IntType] int +# 2389| [TopLevelFunction] return_routine_type::VoidToIntMemberFunc return_routine_type::GetVoidToIntFunc() +# 2389| : +# 2390| getEntryPoint(): [BlockStmt] { ... } +# 2391| getStmt(0): [ReturnStmt] return ... +# 2391| getExpr(): [FunctionAccess] VoidToInt +# 2391| Type = [RoutineType] ..()(..) +# 2391| ValueCategory = prvalue +# 2396| [TopLevelFunction] int small_operation_should_not_be_constant_folded() +# 2396| : +# 2396| getEntryPoint(): [BlockStmt] { ... } +# 2397| getStmt(0): [ReturnStmt] return ... +# 2397| getExpr(): [BitwiseXorExpr] ... ^ ... +# 2397| Type = [IntType] int +# 2397| Value = [BitwiseXorExpr] 3 +# 2397| ValueCategory = prvalue +# 2397| getLeftOperand(): [Literal] 1 +# 2397| Type = [IntType] int +# 2397| Value = [Literal] 1 +# 2397| ValueCategory = prvalue +# 2397| getRightOperand(): [Literal] 2 +# 2397| Type = [IntType] int +# 2397| Value = [Literal] 2 +# 2397| ValueCategory = prvalue +# 2407| [TopLevelFunction] int large_operation_should_be_constant_folded() +# 2407| : +# 2407| getEntryPoint(): [BlockStmt] { ... } +# 2408| getStmt(0): [ReturnStmt] return ... +# 2408| getExpr(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [BitwiseXorExpr] ... ^ ... +# 2408| Type = [IntType] int +# 2408| Value = [BitwiseXorExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand(): [Literal] 1 +# 2408| Type = [IntType] int +# 2408| Value = [Literal] 1 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2408| getExpr().getFullyConverted(): [ParenthesisExpr] (...) +# 2408| Type = [IntType] int +# 2408| Value = [ParenthesisExpr] 0 +# 2408| ValueCategory = prvalue +# 2411| [TopLevelFunction] void initialization_with_temp_destructor() +# 2411| : +# 2411| getEntryPoint(): [BlockStmt] { ... } +# 2412| getStmt(0): [IfStmt] if (...) ... +# 2412| getCondition(): [ConditionDeclExpr] (condition decl) +# 2412| Type = [BoolType] bool +# 2412| ValueCategory = prvalue +# 2412| getVariableAccess(): [VariableAccess] x +# 2412| Type = [PlainCharType] char +# 2412| ValueCategory = prvalue(load) +# 2412| getInitializingExpr(): [FunctionCall] call to get_x # 2412| Type = [PlainCharType] char # 2412| ValueCategory = prvalue -# 2412| getOperand(): [VariableAccess] x -# 2412| Type = [PlainCharType] char -# 2412| ValueCategory = lvalue -# 2414| getStmt(1): [IfStmt] if (...) ... -# 2414| getInitialization(): [DeclStmt] declaration -# 2414| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x -# 2414| Type = [PlainCharType] char -# 2414| getVariable().getInitializer(): [Initializer] initializer for x -# 2414| getExpr(): [FunctionCall] call to get_x -# 2414| Type = [PlainCharType] char -# 2414| ValueCategory = prvalue -# 2414| getQualifier(): [ConstructorCall] call to ClassWithDestructor -# 2414| Type = [VoidType] void -# 2414| ValueCategory = prvalue -# 2414| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2414| Type = [VoidType] void -# 2414| ValueCategory = prvalue -# 2414| getQualifier(): [ReuseExpr] reuse of temporary object -# 2414| Type = [Class] ClassWithDestructor -# 2414| ValueCategory = xvalue -# 2414| getQualifier().getFullyConverted(): [TemporaryObjectExpr] temporary object -# 2414| Type = [Class] ClassWithDestructor -# 2414| ValueCategory = prvalue(load) -# 2414| getCondition(): [VariableAccess] x -# 2414| Type = [PlainCharType] char -# 2414| ValueCategory = prvalue(load) -# 2415| getThen(): [ExprStmt] ExprStmt -# 2415| getExpr(): [PostfixIncrExpr] ... ++ +# 2412| getQualifier(): [ConstructorCall] call to ClassWithDestructor +# 2412| Type = [VoidType] void +# 2412| ValueCategory = prvalue +# 2412| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2412| Type = [VoidType] void +# 2412| ValueCategory = prvalue +# 2412| getQualifier(): [ReuseExpr] reuse of temporary object +# 2412| Type = [Class] ClassWithDestructor +# 2412| ValueCategory = xvalue +# 2412| getQualifier().getFullyConverted(): [TemporaryObjectExpr] temporary object +# 2412| Type = [Class] ClassWithDestructor +# 2412| ValueCategory = prvalue(load) +# 2412| getVariableAccess().getFullyConverted(): [CStyleCast] (bool)... +# 2412| Conversion = [BoolConversion] conversion to bool +# 2412| Type = [BoolType] bool +# 2412| ValueCategory = prvalue +# 2413| getThen(): [ExprStmt] ExprStmt +# 2413| getExpr(): [PostfixIncrExpr] ... ++ +# 2413| Type = [PlainCharType] char +# 2413| ValueCategory = prvalue +# 2413| getOperand(): [VariableAccess] x +# 2413| Type = [PlainCharType] char +# 2413| ValueCategory = lvalue +# 2415| getStmt(1): [IfStmt] if (...) ... +# 2415| getInitialization(): [DeclStmt] declaration +# 2415| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x # 2415| Type = [PlainCharType] char -# 2415| ValueCategory = prvalue -# 2415| getOperand(): [VariableAccess] x -# 2415| Type = [PlainCharType] char -# 2415| ValueCategory = lvalue -# 2414| getCondition().getFullyConverted(): [CStyleCast] (bool)... -# 2414| Conversion = [BoolConversion] conversion to bool -# 2414| Type = [BoolType] bool -# 2414| ValueCategory = prvalue -# 2417| getStmt(2): [ConstexprIfStmt] if constexpr (...) ... -# 2417| getInitialization(): [DeclStmt] declaration -# 2417| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x -# 2417| Type = [PlainCharType] char -# 2417| getVariable().getInitializer(): [Initializer] initializer for x -# 2417| getExpr(): [FunctionCall] call to get_x -# 2417| Type = [PlainCharType] char -# 2417| ValueCategory = prvalue -# 2417| getQualifier(): [ConstructorCall] call to ClassWithDestructor -# 2417| Type = [VoidType] void -# 2417| ValueCategory = prvalue -# 2417| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2417| Type = [VoidType] void -# 2417| ValueCategory = prvalue -# 2417| getQualifier(): [ReuseExpr] reuse of temporary object -# 2417| Type = [Class] ClassWithDestructor -# 2417| ValueCategory = xvalue -# 2417| getQualifier().getFullyConverted(): [TemporaryObjectExpr] temporary object -# 2417| Type = [Class] ClassWithDestructor -# 2417| ValueCategory = prvalue(load) -# 2417| getCondition(): [VariableAccess] initialization_with_destructor_bool -# 2417| Type = [BoolType] bool -# 2417| Value = [VariableAccess] 1 -# 2417| ValueCategory = prvalue(load) -# 2418| getThen(): [ExprStmt] ExprStmt -# 2418| getExpr(): [PostfixIncrExpr] ... ++ +# 2415| getVariable().getInitializer(): [Initializer] initializer for x +# 2415| getExpr(): [FunctionCall] call to get_x +# 2415| Type = [PlainCharType] char +# 2415| ValueCategory = prvalue +# 2415| getQualifier(): [ConstructorCall] call to ClassWithDestructor +# 2415| Type = [VoidType] void +# 2415| ValueCategory = prvalue +# 2415| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2415| Type = [VoidType] void +# 2415| ValueCategory = prvalue +# 2415| getQualifier(): [ReuseExpr] reuse of temporary object +# 2415| Type = [Class] ClassWithDestructor +# 2415| ValueCategory = xvalue +# 2415| getQualifier().getFullyConverted(): [TemporaryObjectExpr] temporary object +# 2415| Type = [Class] ClassWithDestructor +# 2415| ValueCategory = prvalue(load) +# 2415| getCondition(): [VariableAccess] x +# 2415| Type = [PlainCharType] char +# 2415| ValueCategory = prvalue(load) +# 2416| getThen(): [ExprStmt] ExprStmt +# 2416| getExpr(): [PostfixIncrExpr] ... ++ +# 2416| Type = [PlainCharType] char +# 2416| ValueCategory = prvalue +# 2416| getOperand(): [VariableAccess] x +# 2416| Type = [PlainCharType] char +# 2416| ValueCategory = lvalue +# 2415| getCondition().getFullyConverted(): [CStyleCast] (bool)... +# 2415| Conversion = [BoolConversion] conversion to bool +# 2415| Type = [BoolType] bool +# 2415| ValueCategory = prvalue +# 2418| getStmt(2): [ConstexprIfStmt] if constexpr (...) ... +# 2418| getInitialization(): [DeclStmt] declaration +# 2418| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x # 2418| Type = [PlainCharType] char -# 2418| ValueCategory = prvalue -# 2418| getOperand(): [VariableAccess] x -# 2418| Type = [PlainCharType] char -# 2418| ValueCategory = lvalue -# 2420| getStmt(3): [SwitchStmt] switch (...) ... -# 2420| getExpr(): [ConditionDeclExpr] (condition decl) -# 2420| Type = [IntType] int -# 2420| ValueCategory = prvalue -# 2420| getVariableAccess(): [VariableAccess] x -# 2420| Type = [PlainCharType] char -# 2420| ValueCategory = prvalue(load) -# 2420| getInitializingExpr(): [FunctionCall] call to get_x -# 2420| Type = [PlainCharType] char -# 2420| ValueCategory = prvalue -# 2420| getQualifier(): [ConstructorCall] call to ClassWithDestructor -# 2420| Type = [VoidType] void -# 2420| ValueCategory = prvalue -# 2420| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2420| Type = [VoidType] void -# 2420| ValueCategory = prvalue -# 2420| getQualifier(): [ReuseExpr] reuse of temporary object -# 2420| Type = [Class] ClassWithDestructor -# 2420| ValueCategory = xvalue -# 2420| getQualifier().getFullyConverted(): [TemporaryObjectExpr] temporary object -# 2420| Type = [Class] ClassWithDestructor -# 2420| ValueCategory = prvalue(load) -# 2420| getVariableAccess().getFullyConverted(): [CStyleCast] (int)... -# 2420| Conversion = [IntegralConversion] integral conversion -# 2420| Type = [IntType] int -# 2420| ValueCategory = prvalue -# 2420| getStmt(): [BlockStmt] { ... } -# 2421| getStmt(0): [SwitchCase] case ...: -# 2421| getExpr(): [CharLiteral] 97 -# 2421| Type = [PlainCharType] char -# 2421| Value = [CharLiteral] 97 +# 2418| getVariable().getInitializer(): [Initializer] initializer for x +# 2418| getExpr(): [FunctionCall] call to get_x +# 2418| Type = [PlainCharType] char +# 2418| ValueCategory = prvalue +# 2418| getQualifier(): [ConstructorCall] call to ClassWithDestructor +# 2418| Type = [VoidType] void +# 2418| ValueCategory = prvalue +# 2418| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2418| Type = [VoidType] void +# 2418| ValueCategory = prvalue +# 2418| getQualifier(): [ReuseExpr] reuse of temporary object +# 2418| Type = [Class] ClassWithDestructor +# 2418| ValueCategory = xvalue +# 2418| getQualifier().getFullyConverted(): [TemporaryObjectExpr] temporary object +# 2418| Type = [Class] ClassWithDestructor +# 2418| ValueCategory = prvalue(load) +# 2418| getCondition(): [VariableAccess] initialization_with_destructor_bool +# 2418| Type = [BoolType] bool +# 2418| Value = [VariableAccess] 1 +# 2418| ValueCategory = prvalue(load) +# 2419| getThen(): [ExprStmt] ExprStmt +# 2419| getExpr(): [PostfixIncrExpr] ... ++ +# 2419| Type = [PlainCharType] char +# 2419| ValueCategory = prvalue +# 2419| getOperand(): [VariableAccess] x +# 2419| Type = [PlainCharType] char +# 2419| ValueCategory = lvalue +# 2421| getStmt(3): [SwitchStmt] switch (...) ... +# 2421| getExpr(): [ConditionDeclExpr] (condition decl) +# 2421| Type = [IntType] int +# 2421| ValueCategory = prvalue +# 2421| getVariableAccess(): [VariableAccess] x +# 2421| Type = [PlainCharType] char +# 2421| ValueCategory = prvalue(load) +# 2421| getInitializingExpr(): [FunctionCall] call to get_x +# 2421| Type = [PlainCharType] char +# 2421| ValueCategory = prvalue +# 2421| getQualifier(): [ConstructorCall] call to ClassWithDestructor +# 2421| Type = [VoidType] void # 2421| ValueCategory = prvalue -# 2421| getExpr().getFullyConverted(): [CStyleCast] (int)... -# 2421| Conversion = [IntegralConversion] integral conversion -# 2421| Type = [IntType] int -# 2421| Value = [CStyleCast] 97 +# 2421| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2421| Type = [VoidType] void # 2421| ValueCategory = prvalue -# 2422| getStmt(1): [ExprStmt] ExprStmt -# 2422| getExpr(): [PostfixIncrExpr] ... ++ +# 2421| getQualifier(): [ReuseExpr] reuse of temporary object +# 2421| Type = [Class] ClassWithDestructor +# 2421| ValueCategory = xvalue +# 2421| getQualifier().getFullyConverted(): [TemporaryObjectExpr] temporary object +# 2421| Type = [Class] ClassWithDestructor +# 2421| ValueCategory = prvalue(load) +# 2421| getVariableAccess().getFullyConverted(): [CStyleCast] (int)... +# 2421| Conversion = [IntegralConversion] integral conversion +# 2421| Type = [IntType] int +# 2421| ValueCategory = prvalue +# 2421| getStmt(): [BlockStmt] { ... } +# 2422| getStmt(0): [SwitchCase] case ...: +# 2422| getExpr(): [CharLiteral] 97 # 2422| Type = [PlainCharType] char +# 2422| Value = [CharLiteral] 97 # 2422| ValueCategory = prvalue -# 2422| getOperand(): [VariableAccess] x -# 2422| Type = [PlainCharType] char -# 2422| ValueCategory = lvalue -# 2425| getStmt(4): [SwitchStmt] switch (...) ... -# 2425| getInitialization(): [DeclStmt] declaration -# 2425| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x -# 2425| Type = [PlainCharType] char -# 2425| getVariable().getInitializer(): [Initializer] initializer for x -# 2425| getExpr(): [FunctionCall] call to get_x -# 2425| Type = [PlainCharType] char -# 2425| ValueCategory = prvalue -# 2425| getQualifier(): [ConstructorCall] call to ClassWithDestructor -# 2425| Type = [VoidType] void -# 2425| ValueCategory = prvalue -# 2425| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2425| Type = [VoidType] void -# 2425| ValueCategory = prvalue -# 2425| getQualifier(): [ReuseExpr] reuse of temporary object -# 2425| Type = [Class] ClassWithDestructor -# 2425| ValueCategory = xvalue -# 2425| getQualifier().getFullyConverted(): [TemporaryObjectExpr] temporary object -# 2425| Type = [Class] ClassWithDestructor -# 2425| ValueCategory = prvalue(load) -# 2425| getExpr(): [VariableAccess] x -# 2425| Type = [PlainCharType] char -# 2425| ValueCategory = prvalue(load) -# 2425| getStmt(): [BlockStmt] { ... } -# 2426| getStmt(0): [SwitchCase] case ...: -# 2426| getExpr(): [CharLiteral] 97 -# 2426| Type = [PlainCharType] char -# 2426| Value = [CharLiteral] 97 -# 2426| ValueCategory = prvalue -# 2426| getExpr().getFullyConverted(): [CStyleCast] (int)... -# 2426| Conversion = [IntegralConversion] integral conversion -# 2426| Type = [IntType] int -# 2426| Value = [CStyleCast] 97 -# 2426| ValueCategory = prvalue -# 2427| getStmt(1): [ExprStmt] ExprStmt -# 2427| getExpr(): [PostfixIncrExpr] ... ++ +# 2422| getExpr().getFullyConverted(): [CStyleCast] (int)... +# 2422| Conversion = [IntegralConversion] integral conversion +# 2422| Type = [IntType] int +# 2422| Value = [CStyleCast] 97 +# 2422| ValueCategory = prvalue +# 2423| getStmt(1): [ExprStmt] ExprStmt +# 2423| getExpr(): [PostfixIncrExpr] ... ++ +# 2423| Type = [PlainCharType] char +# 2423| ValueCategory = prvalue +# 2423| getOperand(): [VariableAccess] x +# 2423| Type = [PlainCharType] char +# 2423| ValueCategory = lvalue +# 2426| getStmt(4): [SwitchStmt] switch (...) ... +# 2426| getInitialization(): [DeclStmt] declaration +# 2426| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x +# 2426| Type = [PlainCharType] char +# 2426| getVariable().getInitializer(): [Initializer] initializer for x +# 2426| getExpr(): [FunctionCall] call to get_x +# 2426| Type = [PlainCharType] char +# 2426| ValueCategory = prvalue +# 2426| getQualifier(): [ConstructorCall] call to ClassWithDestructor +# 2426| Type = [VoidType] void +# 2426| ValueCategory = prvalue +# 2426| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2426| Type = [VoidType] void +# 2426| ValueCategory = prvalue +# 2426| getQualifier(): [ReuseExpr] reuse of temporary object +# 2426| Type = [Class] ClassWithDestructor +# 2426| ValueCategory = xvalue +# 2426| getQualifier().getFullyConverted(): [TemporaryObjectExpr] temporary object +# 2426| Type = [Class] ClassWithDestructor +# 2426| ValueCategory = prvalue(load) +# 2426| getExpr(): [VariableAccess] x +# 2426| Type = [PlainCharType] char +# 2426| ValueCategory = prvalue(load) +# 2426| getStmt(): [BlockStmt] { ... } +# 2427| getStmt(0): [SwitchCase] case ...: +# 2427| getExpr(): [CharLiteral] 97 # 2427| Type = [PlainCharType] char +# 2427| Value = [CharLiteral] 97 +# 2427| ValueCategory = prvalue +# 2427| getExpr().getFullyConverted(): [CStyleCast] (int)... +# 2427| Conversion = [IntegralConversion] integral conversion +# 2427| Type = [IntType] int +# 2427| Value = [CStyleCast] 97 # 2427| ValueCategory = prvalue -# 2427| getOperand(): [VariableAccess] x -# 2427| Type = [PlainCharType] char -# 2427| ValueCategory = lvalue -# 2425| getExpr().getFullyConverted(): [CStyleCast] (int)... -# 2425| Conversion = [IntegralConversion] integral conversion -# 2425| Type = [IntType] int -# 2425| ValueCategory = prvalue -# 2430| getStmt(5): [RangeBasedForStmt] for(...:...) ... -# 2430| getInitialization(): [DeclStmt] declaration -# 2430| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x -# 2430| Type = [PlainCharType] char -# 2430| getVariable().getInitializer(): [Initializer] initializer for x -# 2430| getExpr(): [FunctionCall] call to get_x -# 2430| Type = [PlainCharType] char -# 2430| ValueCategory = prvalue -# 2430| getQualifier(): [ConstructorCall] call to ClassWithDestructor -# 2430| Type = [VoidType] void -# 2430| ValueCategory = prvalue -# 2430| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2430| Type = [VoidType] void -# 2430| ValueCategory = prvalue -# 2430| getQualifier(): [ReuseExpr] reuse of temporary object -# 2430| Type = [Class] ClassWithDestructor -# 2430| ValueCategory = xvalue -# 2430| getQualifier().getFullyConverted(): [TemporaryObjectExpr] temporary object -# 2430| Type = [Class] ClassWithDestructor -# 2430| ValueCategory = prvalue(load) -# 2430| getChild(1): [DeclStmt] declaration -# 2430| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__range) -# 2430| Type = [RValueReferenceType] vector && +# 2428| getStmt(1): [ExprStmt] ExprStmt +# 2428| getExpr(): [PostfixIncrExpr] ... ++ +# 2428| Type = [PlainCharType] char +# 2428| ValueCategory = prvalue +# 2428| getOperand(): [VariableAccess] x +# 2428| Type = [PlainCharType] char +# 2428| ValueCategory = lvalue +# 2426| getExpr().getFullyConverted(): [CStyleCast] (int)... +# 2426| Conversion = [IntegralConversion] integral conversion +# 2426| Type = [IntType] int +# 2426| ValueCategory = prvalue +# 2431| getStmt(5): [RangeBasedForStmt] for(...:...) ... +# 2431| getInitialization(): [DeclStmt] declaration +# 2431| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x +# 2431| Type = [PlainCharType] char +# 2431| getVariable().getInitializer(): [Initializer] initializer for x +# 2431| getExpr(): [FunctionCall] call to get_x +# 2431| Type = [PlainCharType] char +# 2431| ValueCategory = prvalue +# 2431| getQualifier(): [ConstructorCall] call to ClassWithDestructor +# 2431| Type = [VoidType] void +# 2431| ValueCategory = prvalue +# 2431| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2431| Type = [VoidType] void +# 2431| ValueCategory = prvalue +# 2431| getQualifier(): [ReuseExpr] reuse of temporary object +# 2431| Type = [Class] ClassWithDestructor +# 2431| ValueCategory = xvalue +# 2431| getQualifier().getFullyConverted(): [TemporaryObjectExpr] temporary object +# 2431| Type = [Class] ClassWithDestructor +# 2431| ValueCategory = prvalue(load) +# 2431| getChild(1): [DeclStmt] declaration +# 2431| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__range) +# 2431| Type = [RValueReferenceType] vector && #-----| getVariable().getInitializer(): [Initializer] initializer for (__range) -# 2430| getExpr(): [ConstructorCall] call to vector -# 2430| Type = [VoidType] void -# 2430| ValueCategory = prvalue -# 2430| getArgument(0): [VariableAccess] x -# 2430| Type = [PlainCharType] char -# 2430| ValueCategory = prvalue(load) -# 2430| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to) -# 2430| Type = [LValueReferenceType] vector & -# 2430| ValueCategory = prvalue -# 2430| getExpr(): [TemporaryObjectExpr] temporary object -# 2430| Type = [ClassTemplateInstantiation,Struct] vector -# 2430| ValueCategory = xvalue -# 2430| getBeginEndDeclaration(): [DeclStmt] declaration -# 2430| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__begin) -# 2430| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2431| getExpr(): [ConstructorCall] call to vector +# 2431| Type = [VoidType] void +# 2431| ValueCategory = prvalue +# 2431| getArgument(0): [VariableAccess] x +# 2431| Type = [PlainCharType] char +# 2431| ValueCategory = prvalue(load) +# 2431| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to) +# 2431| Type = [LValueReferenceType] vector & +# 2431| ValueCategory = prvalue +# 2431| getExpr(): [TemporaryObjectExpr] temporary object +# 2431| Type = [ClassTemplateInstantiation,Struct] vector +# 2431| ValueCategory = xvalue +# 2431| getBeginEndDeclaration(): [DeclStmt] declaration +# 2431| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__begin) +# 2431| Type = [NestedTypedefType,UsingAliasTypedefType] iterator #-----| getVariable().getInitializer(): [Initializer] initializer for (__begin) -# 2430| getExpr(): [FunctionCall] call to begin -# 2430| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2430| ValueCategory = prvalue -# 2430| getQualifier(): [VariableAccess] (__range) -# 2430| Type = [RValueReferenceType] vector && -# 2430| ValueCategory = prvalue(load) +# 2431| getExpr(): [FunctionCall] call to begin +# 2431| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2431| ValueCategory = prvalue +# 2431| getQualifier(): [VariableAccess] (__range) +# 2431| Type = [RValueReferenceType] vector && +# 2431| ValueCategory = prvalue(load) #-----| getQualifier().getFullyConverted(): [CStyleCast] (const vector)... #-----| Conversion = [GlvalueConversion] glvalue conversion #-----| Type = [SpecifiedType] const vector @@ -22129,15 +22131,15 @@ ir.cpp: #-----| getExpr(): [ReferenceDereferenceExpr] (reference dereference) #-----| Type = [ClassTemplateInstantiation,Struct] vector #-----| ValueCategory = lvalue -# 2430| getDeclarationEntry(1): [VariableDeclarationEntry] declaration of (__end) -# 2430| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2431| getDeclarationEntry(1): [VariableDeclarationEntry] declaration of (__end) +# 2431| Type = [NestedTypedefType,UsingAliasTypedefType] iterator #-----| getVariable().getInitializer(): [Initializer] initializer for (__end) -# 2430| getExpr(): [FunctionCall] call to end -# 2430| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2430| ValueCategory = prvalue -# 2430| getQualifier(): [VariableAccess] (__range) -# 2430| Type = [RValueReferenceType] vector && -# 2430| ValueCategory = prvalue(load) +# 2431| getExpr(): [FunctionCall] call to end +# 2431| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2431| ValueCategory = prvalue +# 2431| getQualifier(): [VariableAccess] (__range) +# 2431| Type = [RValueReferenceType] vector && +# 2431| ValueCategory = prvalue(load) #-----| getQualifier().getFullyConverted(): [CStyleCast] (const vector)... #-----| Conversion = [GlvalueConversion] glvalue conversion #-----| Type = [SpecifiedType] const vector @@ -22145,18 +22147,18 @@ ir.cpp: #-----| getExpr(): [ReferenceDereferenceExpr] (reference dereference) #-----| Type = [ClassTemplateInstantiation,Struct] vector #-----| ValueCategory = lvalue -# 2430| getCondition(): [FunctionCall] call to operator!= -# 2430| Type = [BoolType] bool -# 2430| ValueCategory = prvalue -# 2430| getQualifier(): [VariableAccess] (__begin) -# 2430| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2430| ValueCategory = lvalue -# 2430| getArgument(0): [ConstructorCall] call to iterator -# 2430| Type = [VoidType] void -# 2430| ValueCategory = prvalue -# 2430| getArgument(0): [VariableAccess] (__end) -# 2430| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2430| ValueCategory = lvalue +# 2431| getCondition(): [FunctionCall] call to operator!= +# 2431| Type = [BoolType] bool +# 2431| ValueCategory = prvalue +# 2431| getQualifier(): [VariableAccess] (__begin) +# 2431| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2431| ValueCategory = lvalue +# 2431| getArgument(0): [ConstructorCall] call to iterator +# 2431| Type = [VoidType] void +# 2431| ValueCategory = prvalue +# 2431| getArgument(0): [VariableAccess] (__end) +# 2431| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2431| ValueCategory = lvalue #-----| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to) #-----| Type = [LValueReferenceType] const iterator & #-----| ValueCategory = prvalue @@ -22171,491 +22173,491 @@ ir.cpp: #-----| getArgument(0).getFullyConverted(): [TemporaryObjectExpr] temporary object #-----| Type = [ClassTemplateInstantiation,Struct] iterator #-----| ValueCategory = lvalue -# 2430| getUpdate(): [FunctionCall] call to operator++ -# 2430| Type = [LValueReferenceType] iterator & -# 2430| ValueCategory = prvalue -# 2430| getQualifier(): [VariableAccess] (__begin) -# 2430| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2430| ValueCategory = lvalue -# 2430| getChild(5): [DeclStmt] declaration -# 2430| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y -# 2430| Type = [PlainCharType] char -# 2430| getVariable().getInitializer(): [Initializer] initializer for y -# 2430| getExpr(): [OverloadedPointerDereferenceExpr] call to operator* -# 2430| Type = [LValueReferenceType] char & -# 2430| ValueCategory = prvalue -# 2430| getQualifier(): [VariableAccess] (__begin) -# 2430| Type = [NestedTypedefType,UsingAliasTypedefType] iterator -# 2430| ValueCategory = lvalue +# 2431| getUpdate(): [FunctionCall] call to operator++ +# 2431| Type = [LValueReferenceType] iterator & +# 2431| ValueCategory = prvalue +# 2431| getQualifier(): [VariableAccess] (__begin) +# 2431| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2431| ValueCategory = lvalue +# 2431| getChild(5): [DeclStmt] declaration +# 2431| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y +# 2431| Type = [PlainCharType] char +# 2431| getVariable().getInitializer(): [Initializer] initializer for y +# 2431| getExpr(): [OverloadedPointerDereferenceExpr] call to operator* +# 2431| Type = [LValueReferenceType] char & +# 2431| ValueCategory = prvalue +# 2431| getQualifier(): [VariableAccess] (__begin) +# 2431| Type = [NestedTypedefType,UsingAliasTypedefType] iterator +# 2431| ValueCategory = lvalue #-----| getQualifier().getFullyConverted(): [CStyleCast] (const iterator)... #-----| Conversion = [GlvalueConversion] glvalue conversion #-----| Type = [SpecifiedType] const iterator #-----| ValueCategory = lvalue -# 2430| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) -# 2430| Type = [PlainCharType] char -# 2430| ValueCategory = prvalue(load) -# 2431| getStmt(): [ExprStmt] ExprStmt -# 2431| getExpr(): [AssignAddExpr] ... += ... -# 2431| Type = [PlainCharType] char -# 2431| ValueCategory = lvalue -# 2431| getLValue(): [VariableAccess] y -# 2431| Type = [PlainCharType] char -# 2431| ValueCategory = lvalue -# 2431| getRValue(): [VariableAccess] x -# 2431| Type = [PlainCharType] char -# 2431| ValueCategory = prvalue(load) -# 2431| getRValue().getFullyConverted(): [CStyleCast] (int)... -# 2431| Conversion = [IntegralConversion] integral conversion -# 2431| Type = [IntType] int -# 2431| ValueCategory = prvalue -# 2430| getImplicitDestructorCall(0): [DestructorCall] call to ~vector -# 2430| Type = [VoidType] void -# 2430| ValueCategory = prvalue -# 2430| getQualifier(): [ReuseExpr] reuse of temporary object -# 2430| Type = [ClassTemplateInstantiation,Struct] vector -# 2430| ValueCategory = xvalue -# 2430| getUpdate().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) -# 2430| Type = [ClassTemplateInstantiation,Struct] iterator -# 2430| ValueCategory = lvalue -# 2432| getStmt(6): [ReturnStmt] return ... -# 2434| [TopLevelFunction] void param_with_destructor_by_value(ClassWithDestructor) -# 2434| : -# 2434| getParameter(0): [Parameter] c -# 2434| Type = [Class] ClassWithDestructor -# 2434| getEntryPoint(): [BlockStmt] { ... } -# 2436| getStmt(0): [ReturnStmt] return ... -# 2438| [TopLevelFunction] void param_with_destructor_by_pointer(ClassWithDestructor*) -# 2438| : -# 2438| getParameter(0): [Parameter] c -# 2438| Type = [PointerType] ClassWithDestructor * -# 2438| getEntryPoint(): [BlockStmt] { ... } -# 2440| getStmt(0): [ReturnStmt] return ... -# 2442| [TopLevelFunction] void param_with_destructor_by_ref(ClassWithDestructor&) -# 2442| : -# 2442| getParameter(0): [Parameter] c -# 2442| Type = [LValueReferenceType] ClassWithDestructor & -# 2442| getEntryPoint(): [BlockStmt] { ... } -# 2444| getStmt(0): [ReturnStmt] return ... -# 2446| [TopLevelFunction] void param_with_destructor_by_rref(ClassWithDestructor&&) -# 2446| : -# 2446| getParameter(0): [Parameter] c -# 2446| Type = [RValueReferenceType] ClassWithDestructor && -# 2446| getEntryPoint(): [BlockStmt] { ... } -# 2448| getStmt(0): [ReturnStmt] return ... -# 2450| [TopLevelFunction] void rethrow_with_destruction(int) -# 2450| : -# 2450| getParameter(0): [Parameter] x -# 2450| Type = [IntType] int -# 2450| getEntryPoint(): [BlockStmt] { ... } -# 2451| getStmt(0): [DeclStmt] declaration -# 2451| getDeclarationEntry(0): [VariableDeclarationEntry] definition of c -# 2451| Type = [Class] ClassWithDestructor -# 2451| getVariable().getInitializer(): [Initializer] initializer for c -# 2451| getExpr(): [ConstructorCall] call to ClassWithDestructor -# 2451| Type = [VoidType] void -# 2451| ValueCategory = prvalue -# 2452| getStmt(1): [ExprStmt] ExprStmt -# 2452| getExpr(): [ReThrowExpr] re-throw exception -# 2452| Type = [VoidType] void -# 2452| ValueCategory = prvalue -# 2453| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2453| Type = [VoidType] void -# 2453| ValueCategory = prvalue -# 2453| getQualifier(): [VariableAccess] c -# 2453| Type = [Class] ClassWithDestructor -# 2453| ValueCategory = lvalue -# 2455| [CopyAssignmentOperator] ByValueConstructor& ByValueConstructor::operator=(ByValueConstructor const&) -# 2455| : +# 2431| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) +# 2431| Type = [PlainCharType] char +# 2431| ValueCategory = prvalue(load) +# 2432| getStmt(): [ExprStmt] ExprStmt +# 2432| getExpr(): [AssignAddExpr] ... += ... +# 2432| Type = [PlainCharType] char +# 2432| ValueCategory = lvalue +# 2432| getLValue(): [VariableAccess] y +# 2432| Type = [PlainCharType] char +# 2432| ValueCategory = lvalue +# 2432| getRValue(): [VariableAccess] x +# 2432| Type = [PlainCharType] char +# 2432| ValueCategory = prvalue(load) +# 2432| getRValue().getFullyConverted(): [CStyleCast] (int)... +# 2432| Conversion = [IntegralConversion] integral conversion +# 2432| Type = [IntType] int +# 2432| ValueCategory = prvalue +# 2431| getImplicitDestructorCall(0): [DestructorCall] call to ~vector +# 2431| Type = [VoidType] void +# 2431| ValueCategory = prvalue +# 2431| getQualifier(): [ReuseExpr] reuse of temporary object +# 2431| Type = [ClassTemplateInstantiation,Struct] vector +# 2431| ValueCategory = xvalue +# 2431| getUpdate().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) +# 2431| Type = [ClassTemplateInstantiation,Struct] iterator +# 2431| ValueCategory = lvalue +# 2433| getStmt(6): [ReturnStmt] return ... +# 2435| [TopLevelFunction] void param_with_destructor_by_value(ClassWithDestructor) +# 2435| : +# 2435| getParameter(0): [Parameter] c +# 2435| Type = [Class] ClassWithDestructor +# 2435| getEntryPoint(): [BlockStmt] { ... } +# 2437| getStmt(0): [ReturnStmt] return ... +# 2439| [TopLevelFunction] void param_with_destructor_by_pointer(ClassWithDestructor*) +# 2439| : +# 2439| getParameter(0): [Parameter] c +# 2439| Type = [PointerType] ClassWithDestructor * +# 2439| getEntryPoint(): [BlockStmt] { ... } +# 2441| getStmt(0): [ReturnStmt] return ... +# 2443| [TopLevelFunction] void param_with_destructor_by_ref(ClassWithDestructor&) +# 2443| : +# 2443| getParameter(0): [Parameter] c +# 2443| Type = [LValueReferenceType] ClassWithDestructor & +# 2443| getEntryPoint(): [BlockStmt] { ... } +# 2445| getStmt(0): [ReturnStmt] return ... +# 2447| [TopLevelFunction] void param_with_destructor_by_rref(ClassWithDestructor&&) +# 2447| : +# 2447| getParameter(0): [Parameter] c +# 2447| Type = [RValueReferenceType] ClassWithDestructor && +# 2447| getEntryPoint(): [BlockStmt] { ... } +# 2449| getStmt(0): [ReturnStmt] return ... +# 2451| [TopLevelFunction] void rethrow_with_destruction(int) +# 2451| : +# 2451| getParameter(0): [Parameter] x +# 2451| Type = [IntType] int +# 2451| getEntryPoint(): [BlockStmt] { ... } +# 2452| getStmt(0): [DeclStmt] declaration +# 2452| getDeclarationEntry(0): [VariableDeclarationEntry] definition of c +# 2452| Type = [Class] ClassWithDestructor +# 2452| getVariable().getInitializer(): [Initializer] initializer for c +# 2452| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2452| Type = [VoidType] void +# 2452| ValueCategory = prvalue +# 2453| getStmt(1): [ExprStmt] ExprStmt +# 2453| getExpr(): [ReThrowExpr] re-throw exception +# 2453| Type = [VoidType] void +# 2453| ValueCategory = prvalue +# 2454| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2454| Type = [VoidType] void +# 2454| ValueCategory = prvalue +# 2454| getQualifier(): [VariableAccess] c +# 2454| Type = [Class] ClassWithDestructor +# 2454| ValueCategory = lvalue +# 2456| [CopyAssignmentOperator] ByValueConstructor& ByValueConstructor::operator=(ByValueConstructor const&) +# 2456| : #-----| getParameter(0): [Parameter] (unnamed parameter 0) #-----| Type = [LValueReferenceType] const ByValueConstructor & -# 2455| [MoveAssignmentOperator] ByValueConstructor& ByValueConstructor::operator=(ByValueConstructor&&) -# 2455| : +# 2456| [MoveAssignmentOperator] ByValueConstructor& ByValueConstructor::operator=(ByValueConstructor&&) +# 2456| : #-----| getParameter(0): [Parameter] (unnamed parameter 0) #-----| Type = [RValueReferenceType] ByValueConstructor && -# 2455| [CopyConstructor] void ByValueConstructor::ByValueConstructor(ByValueConstructor const&) -# 2455| : +# 2456| [CopyConstructor] void ByValueConstructor::ByValueConstructor(ByValueConstructor const&) +# 2456| : #-----| getParameter(0): [Parameter] (unnamed parameter 0) #-----| Type = [LValueReferenceType] const ByValueConstructor & -# 2455| [MoveConstructor] void ByValueConstructor::ByValueConstructor(ByValueConstructor&&) -# 2455| : +# 2456| [MoveConstructor] void ByValueConstructor::ByValueConstructor(ByValueConstructor&&) +# 2456| : #-----| getParameter(0): [Parameter] (unnamed parameter 0) #-----| Type = [RValueReferenceType] ByValueConstructor && -# 2456| [Constructor] void ByValueConstructor::ByValueConstructor(ClassWithDestructor) -# 2456| : -# 2456| getParameter(0): [Parameter] (unnamed parameter 0) -# 2456| Type = [Class] ClassWithDestructor -# 2459| [TopLevelFunction] void new_with_destructor(ClassWithDestructor) -# 2459| : -# 2459| getParameter(0): [Parameter] a -# 2459| Type = [Class] ClassWithDestructor -# 2460| getEntryPoint(): [BlockStmt] { ... } -# 2461| getStmt(0): [DeclStmt] declaration -# 2461| getDeclarationEntry(0): [VariableDeclarationEntry] definition of b -# 2461| Type = [PointerType] ByValueConstructor * -# 2461| getVariable().getInitializer(): [Initializer] initializer for b -# 2461| getExpr(): [NewExpr] new -# 2461| Type = [PointerType] ByValueConstructor * -# 2461| ValueCategory = prvalue -# 2461| getInitializer(): [ConstructorCall] call to ByValueConstructor -# 2461| Type = [VoidType] void -# 2461| ValueCategory = prvalue -# 2461| getArgument(0): [VariableAccess] a -# 2461| Type = [Class] ClassWithDestructor -# 2461| ValueCategory = prvalue(load) -# 2461| getArgument(0).getFullyConverted(): [TemporaryObjectExpr] temporary object -# 2461| Type = [Class] ClassWithDestructor -# 2461| ValueCategory = lvalue -# 2461| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2461| Type = [VoidType] void -# 2461| ValueCategory = prvalue -# 2461| getQualifier(): [ReuseExpr] reuse of temporary object -# 2461| Type = [Class] ClassWithDestructor -# 2461| ValueCategory = xvalue -# 2462| getStmt(1): [ReturnStmt] return ... -# 2465| [CopyAssignmentOperator] rvalue_conversion_with_destructor::A& rvalue_conversion_with_destructor::A::operator=(rvalue_conversion_with_destructor::A const&) -# 2465| : +# 2457| [Constructor] void ByValueConstructor::ByValueConstructor(ClassWithDestructor) +# 2457| : +# 2457| getParameter(0): [Parameter] (unnamed parameter 0) +# 2457| Type = [Class] ClassWithDestructor +# 2460| [TopLevelFunction] void new_with_destructor(ClassWithDestructor) +# 2460| : +# 2460| getParameter(0): [Parameter] a +# 2460| Type = [Class] ClassWithDestructor +# 2461| getEntryPoint(): [BlockStmt] { ... } +# 2462| getStmt(0): [DeclStmt] declaration +# 2462| getDeclarationEntry(0): [VariableDeclarationEntry] definition of b +# 2462| Type = [PointerType] ByValueConstructor * +# 2462| getVariable().getInitializer(): [Initializer] initializer for b +# 2462| getExpr(): [NewExpr] new +# 2462| Type = [PointerType] ByValueConstructor * +# 2462| ValueCategory = prvalue +# 2462| getInitializer(): [ConstructorCall] call to ByValueConstructor +# 2462| Type = [VoidType] void +# 2462| ValueCategory = prvalue +# 2462| getArgument(0): [VariableAccess] a +# 2462| Type = [Class] ClassWithDestructor +# 2462| ValueCategory = prvalue(load) +# 2462| getArgument(0).getFullyConverted(): [TemporaryObjectExpr] temporary object +# 2462| Type = [Class] ClassWithDestructor +# 2462| ValueCategory = lvalue +# 2462| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2462| Type = [VoidType] void +# 2462| ValueCategory = prvalue +# 2462| getQualifier(): [ReuseExpr] reuse of temporary object +# 2462| Type = [Class] ClassWithDestructor +# 2462| ValueCategory = xvalue +# 2463| getStmt(1): [ReturnStmt] return ... +# 2466| [CopyAssignmentOperator] rvalue_conversion_with_destructor::A& rvalue_conversion_with_destructor::A::operator=(rvalue_conversion_with_destructor::A const&) +# 2466| : #-----| getParameter(0): [Parameter] (unnamed parameter 0) #-----| Type = [LValueReferenceType] const A & -# 2465| [MoveAssignmentOperator] rvalue_conversion_with_destructor::A& rvalue_conversion_with_destructor::A::operator=(rvalue_conversion_with_destructor::A&&) -# 2465| : +# 2466| [MoveAssignmentOperator] rvalue_conversion_with_destructor::A& rvalue_conversion_with_destructor::A::operator=(rvalue_conversion_with_destructor::A&&) +# 2466| : #-----| getParameter(0): [Parameter] (unnamed parameter 0) #-----| Type = [RValueReferenceType] A && -# 2469| [CopyAssignmentOperator] rvalue_conversion_with_destructor::B& rvalue_conversion_with_destructor::B::operator=(rvalue_conversion_with_destructor::B const&) -# 2469| : +# 2470| [CopyAssignmentOperator] rvalue_conversion_with_destructor::B& rvalue_conversion_with_destructor::B::operator=(rvalue_conversion_with_destructor::B const&) +# 2470| : #-----| getParameter(0): [Parameter] (unnamed parameter 0) #-----| Type = [LValueReferenceType] const B & -# 2469| [Constructor] void rvalue_conversion_with_destructor::B::B() -# 2469| : -# 2471| [Destructor] void rvalue_conversion_with_destructor::B::~B() -# 2471| : -# 2473| [ConstMemberFunction] rvalue_conversion_with_destructor::A* rvalue_conversion_with_destructor::B::operator->() const -# 2473| : -# 2476| [TopLevelFunction] rvalue_conversion_with_destructor::B rvalue_conversion_with_destructor::get() -# 2476| : -# 2478| [TopLevelFunction] void rvalue_conversion_with_destructor::test() -# 2478| : -# 2479| getEntryPoint(): [BlockStmt] { ... } -# 2480| getStmt(0): [DeclStmt] declaration -# 2480| getDeclarationEntry(0): [VariableDeclarationEntry] definition of a -# 2480| Type = [IntType] unsigned int -# 2480| getVariable().getInitializer(): [Initializer] initializer for a -# 2480| getExpr(): [PointerFieldAccess] a -# 2480| Type = [IntType] unsigned int -# 2480| ValueCategory = prvalue(load) -# 2480| getQualifier(): [FunctionCall] call to operator-> -# 2480| Type = [PointerType] A * -# 2480| ValueCategory = prvalue -# 2480| getQualifier(): [FunctionCall] call to get -# 2480| Type = [Struct] B -# 2480| ValueCategory = prvalue -# 2480| getQualifier().getFullyConverted(): [CStyleCast] (const B)... -# 2480| Conversion = [PrvalueAdjustmentConversion] prvalue adjustment conversion -# 2480| Type = [SpecifiedType] const B -# 2480| ValueCategory = prvalue -# 2480| getExpr(): [TemporaryObjectExpr] temporary object -# 2480| Type = [Struct] B -# 2480| ValueCategory = prvalue(load) -# 2480| getImplicitDestructorCall(0): [DestructorCall] call to ~B -# 2480| Type = [VoidType] void -# 2480| ValueCategory = prvalue -# 2480| getQualifier(): [ReuseExpr] reuse of temporary object -# 2480| Type = [Struct] B -# 2480| ValueCategory = xvalue -# 2481| getStmt(1): [ReturnStmt] return ... -# 2484| [TopLevelFunction] void destructor_without_block(bool) -# 2484| : -# 2484| getParameter(0): [Parameter] b -# 2484| Type = [BoolType] bool -# 2485| getEntryPoint(): [BlockStmt] { ... } -# 2486| getStmt(0): [IfStmt] if (...) ... -# 2486| getCondition(): [VariableAccess] b -# 2486| Type = [BoolType] bool -# 2486| ValueCategory = prvalue(load) -# 2487| getThen(): [DeclStmt] declaration -# 2487| getDeclarationEntry(0): [VariableDeclarationEntry] definition of c -# 2487| Type = [Class] ClassWithDestructor -# 2487| getVariable().getInitializer(): [Initializer] initializer for c -# 2487| getExpr(): [ConstructorCall] call to ClassWithDestructor -# 2487| Type = [VoidType] void -# 2487| ValueCategory = prvalue +# 2470| [Constructor] void rvalue_conversion_with_destructor::B::B() +# 2470| : +# 2472| [Destructor] void rvalue_conversion_with_destructor::B::~B() +# 2472| : +# 2474| [ConstMemberFunction] rvalue_conversion_with_destructor::A* rvalue_conversion_with_destructor::B::operator->() const +# 2474| : +# 2477| [TopLevelFunction] rvalue_conversion_with_destructor::B rvalue_conversion_with_destructor::get() +# 2477| : +# 2479| [TopLevelFunction] void rvalue_conversion_with_destructor::test() +# 2479| : +# 2480| getEntryPoint(): [BlockStmt] { ... } +# 2481| getStmt(0): [DeclStmt] declaration +# 2481| getDeclarationEntry(0): [VariableDeclarationEntry] definition of a +# 2481| Type = [IntType] unsigned int +# 2481| getVariable().getInitializer(): [Initializer] initializer for a +# 2481| getExpr(): [PointerFieldAccess] a +# 2481| Type = [IntType] unsigned int +# 2481| ValueCategory = prvalue(load) +# 2481| getQualifier(): [FunctionCall] call to operator-> +# 2481| Type = [PointerType] A * +# 2481| ValueCategory = prvalue +# 2481| getQualifier(): [FunctionCall] call to get +# 2481| Type = [Struct] B +# 2481| ValueCategory = prvalue +# 2481| getQualifier().getFullyConverted(): [CStyleCast] (const B)... +# 2481| Conversion = [PrvalueAdjustmentConversion] prvalue adjustment conversion +# 2481| Type = [SpecifiedType] const B +# 2481| ValueCategory = prvalue +# 2481| getExpr(): [TemporaryObjectExpr] temporary object +# 2481| Type = [Struct] B +# 2481| ValueCategory = prvalue(load) +# 2481| getImplicitDestructorCall(0): [DestructorCall] call to ~B +# 2481| Type = [VoidType] void +# 2481| ValueCategory = prvalue +# 2481| getQualifier(): [ReuseExpr] reuse of temporary object +# 2481| Type = [Struct] B +# 2481| ValueCategory = xvalue +# 2482| getStmt(1): [ReturnStmt] return ... +# 2485| [TopLevelFunction] void destructor_without_block(bool) +# 2485| : +# 2485| getParameter(0): [Parameter] b +# 2485| Type = [BoolType] bool +# 2486| getEntryPoint(): [BlockStmt] { ... } +# 2487| getStmt(0): [IfStmt] if (...) ... +# 2487| getCondition(): [VariableAccess] b +# 2487| Type = [BoolType] bool +# 2487| ValueCategory = prvalue(load) +# 2488| getThen(): [DeclStmt] declaration +# 2488| getDeclarationEntry(0): [VariableDeclarationEntry] definition of c +# 2488| Type = [Class] ClassWithDestructor +# 2488| getVariable().getInitializer(): [Initializer] initializer for c +# 2488| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2488| Type = [VoidType] void +# 2488| ValueCategory = prvalue #-----| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor #-----| Type = [VoidType] void #-----| ValueCategory = prvalue #-----| getQualifier(): [VariableAccess] c #-----| Type = [Class] ClassWithDestructor #-----| ValueCategory = lvalue -# 2489| getStmt(1): [IfStmt] if (...) ... -# 2489| getCondition(): [VariableAccess] b -# 2489| Type = [BoolType] bool -# 2489| ValueCategory = prvalue(load) -# 2490| getThen(): [DeclStmt] declaration -# 2490| getDeclarationEntry(0): [VariableDeclarationEntry] definition of d -# 2490| Type = [Class] ClassWithDestructor -# 2490| getVariable().getInitializer(): [Initializer] initializer for d -# 2490| getExpr(): [ConstructorCall] call to ClassWithDestructor -# 2490| Type = [VoidType] void -# 2490| ValueCategory = prvalue +# 2490| getStmt(1): [IfStmt] if (...) ... +# 2490| getCondition(): [VariableAccess] b +# 2490| Type = [BoolType] bool +# 2490| ValueCategory = prvalue(load) +# 2491| getThen(): [DeclStmt] declaration +# 2491| getDeclarationEntry(0): [VariableDeclarationEntry] definition of d +# 2491| Type = [Class] ClassWithDestructor +# 2491| getVariable().getInitializer(): [Initializer] initializer for d +# 2491| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2491| Type = [VoidType] void +# 2491| ValueCategory = prvalue #-----| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor #-----| Type = [VoidType] void #-----| ValueCategory = prvalue #-----| getQualifier(): [VariableAccess] d #-----| Type = [Class] ClassWithDestructor #-----| ValueCategory = lvalue -# 2492| getElse(): [DeclStmt] declaration -# 2492| getDeclarationEntry(0): [VariableDeclarationEntry] definition of e -# 2492| Type = [Class] ClassWithDestructor -# 2492| getVariable().getInitializer(): [Initializer] initializer for e -# 2492| getExpr(): [ConstructorCall] call to ClassWithDestructor -# 2492| Type = [VoidType] void -# 2492| ValueCategory = prvalue +# 2493| getElse(): [DeclStmt] declaration +# 2493| getDeclarationEntry(0): [VariableDeclarationEntry] definition of e +# 2493| Type = [Class] ClassWithDestructor +# 2493| getVariable().getInitializer(): [Initializer] initializer for e +# 2493| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2493| Type = [VoidType] void +# 2493| ValueCategory = prvalue #-----| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor #-----| Type = [VoidType] void #-----| ValueCategory = prvalue #-----| getQualifier(): [VariableAccess] e #-----| Type = [Class] ClassWithDestructor #-----| ValueCategory = lvalue -# 2494| getStmt(2): [WhileStmt] while (...) ... -# 2494| getCondition(): [VariableAccess] b -# 2494| Type = [BoolType] bool -# 2494| ValueCategory = prvalue(load) -# 2495| getStmt(): [DeclStmt] declaration -# 2495| getDeclarationEntry(0): [VariableDeclarationEntry] definition of f -# 2495| Type = [Class] ClassWithDestructor -# 2495| getVariable().getInitializer(): [Initializer] initializer for f -# 2495| getExpr(): [ConstructorCall] call to ClassWithDestructor -# 2495| Type = [VoidType] void -# 2495| ValueCategory = prvalue +# 2495| getStmt(2): [WhileStmt] while (...) ... +# 2495| getCondition(): [VariableAccess] b +# 2495| Type = [BoolType] bool +# 2495| ValueCategory = prvalue(load) +# 2496| getStmt(): [DeclStmt] declaration +# 2496| getDeclarationEntry(0): [VariableDeclarationEntry] definition of f +# 2496| Type = [Class] ClassWithDestructor +# 2496| getVariable().getInitializer(): [Initializer] initializer for f +# 2496| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2496| Type = [VoidType] void +# 2496| ValueCategory = prvalue #-----| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor #-----| Type = [VoidType] void #-----| ValueCategory = prvalue #-----| getQualifier(): [VariableAccess] f #-----| Type = [Class] ClassWithDestructor #-----| ValueCategory = lvalue -# 2497| getStmt(3): [ForStmt] for(...;...;...) ... -# 2497| getInitialization(): [DeclStmt] declaration -# 2497| getDeclarationEntry(0): [VariableDeclarationEntry] definition of i -# 2497| Type = [IntType] int -# 2497| getVariable().getInitializer(): [Initializer] initializer for i -# 2497| getExpr(): [Literal] 0 -# 2497| Type = [IntType] int -# 2497| Value = [Literal] 0 -# 2497| ValueCategory = prvalue -# 2497| getCondition(): [LTExpr] ... < ... -# 2497| Type = [BoolType] bool -# 2497| ValueCategory = prvalue -# 2497| getLesserOperand(): [VariableAccess] i -# 2497| Type = [IntType] int -# 2497| ValueCategory = prvalue(load) -# 2497| getGreaterOperand(): [Literal] 42 -# 2497| Type = [IntType] int -# 2497| Value = [Literal] 42 -# 2497| ValueCategory = prvalue -# 2497| getUpdate(): [PrefixIncrExpr] ++ ... -# 2497| Type = [IntType] int -# 2497| ValueCategory = lvalue -# 2497| getOperand(): [VariableAccess] i -# 2497| Type = [IntType] int -# 2497| ValueCategory = lvalue -# 2498| getStmt(): [DeclStmt] declaration -# 2498| getDeclarationEntry(0): [VariableDeclarationEntry] definition of g -# 2498| Type = [Class] ClassWithDestructor -# 2498| getVariable().getInitializer(): [Initializer] initializer for g -# 2498| getExpr(): [ConstructorCall] call to ClassWithDestructor -# 2498| Type = [VoidType] void +# 2498| getStmt(3): [ForStmt] for(...;...;...) ... +# 2498| getInitialization(): [DeclStmt] declaration +# 2498| getDeclarationEntry(0): [VariableDeclarationEntry] definition of i +# 2498| Type = [IntType] int +# 2498| getVariable().getInitializer(): [Initializer] initializer for i +# 2498| getExpr(): [Literal] 0 +# 2498| Type = [IntType] int +# 2498| Value = [Literal] 0 # 2498| ValueCategory = prvalue +# 2498| getCondition(): [LTExpr] ... < ... +# 2498| Type = [BoolType] bool +# 2498| ValueCategory = prvalue +# 2498| getLesserOperand(): [VariableAccess] i +# 2498| Type = [IntType] int +# 2498| ValueCategory = prvalue(load) +# 2498| getGreaterOperand(): [Literal] 42 +# 2498| Type = [IntType] int +# 2498| Value = [Literal] 42 +# 2498| ValueCategory = prvalue +# 2498| getUpdate(): [PrefixIncrExpr] ++ ... +# 2498| Type = [IntType] int +# 2498| ValueCategory = lvalue +# 2498| getOperand(): [VariableAccess] i +# 2498| Type = [IntType] int +# 2498| ValueCategory = lvalue +# 2499| getStmt(): [DeclStmt] declaration +# 2499| getDeclarationEntry(0): [VariableDeclarationEntry] definition of g +# 2499| Type = [Class] ClassWithDestructor +# 2499| getVariable().getInitializer(): [Initializer] initializer for g +# 2499| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2499| Type = [VoidType] void +# 2499| ValueCategory = prvalue #-----| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor #-----| Type = [VoidType] void #-----| ValueCategory = prvalue #-----| getQualifier(): [VariableAccess] g #-----| Type = [Class] ClassWithDestructor #-----| ValueCategory = lvalue -# 2499| getStmt(4): [ReturnStmt] return ... -# 2501| [TopLevelFunction] void destruction_in_switch_1(int) -# 2501| : -# 2501| getParameter(0): [Parameter] c -# 2501| Type = [IntType] int -# 2501| getEntryPoint(): [BlockStmt] { ... } -# 2502| getStmt(0): [SwitchStmt] switch (...) ... -# 2502| getExpr(): [VariableAccess] c -# 2502| Type = [IntType] int -# 2502| ValueCategory = prvalue(load) -# 2502| getStmt(): [BlockStmt] { ... } -# 2503| getStmt(0): [SwitchCase] case ...: -# 2503| getExpr(): [Literal] 0 -# 2503| Type = [IntType] int -# 2503| Value = [Literal] 0 -# 2503| ValueCategory = prvalue -# 2503| getStmt(1): [BlockStmt] { ... } -# 2504| getStmt(0): [DeclStmt] declaration -# 2504| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x -# 2504| Type = [Class] ClassWithDestructor -# 2504| getVariable().getInitializer(): [Initializer] initializer for x -# 2504| getExpr(): [ConstructorCall] call to ClassWithDestructor -# 2504| Type = [VoidType] void -# 2504| ValueCategory = prvalue -# 2505| getStmt(1): [BreakStmt] break; -# 2506| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2506| Type = [VoidType] void -# 2506| ValueCategory = prvalue -# 2506| getQualifier(): [VariableAccess] x -# 2506| Type = [Class] ClassWithDestructor -# 2506| ValueCategory = lvalue -# 2506| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2506| Type = [VoidType] void -# 2506| ValueCategory = prvalue -# 2506| getQualifier(): [VariableAccess] x -# 2506| Type = [Class] ClassWithDestructor -# 2506| ValueCategory = lvalue -# 2507| getStmt(1): [LabelStmt] label ...: -# 2508| getStmt(2): [ReturnStmt] return ... -# 2510| [TopLevelFunction] void destruction_in_switch_2(int) -# 2510| : -# 2510| getParameter(0): [Parameter] c -# 2510| Type = [IntType] int -# 2510| getEntryPoint(): [BlockStmt] { ... } -# 2511| getStmt(0): [SwitchStmt] switch (...) ... -# 2511| getInitialization(): [DeclStmt] declaration -# 2511| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y -# 2511| Type = [Class] ClassWithDestructor -# 2511| getVariable().getInitializer(): [Initializer] initializer for y -# 2511| getExpr(): [ConstructorCall] call to ClassWithDestructor -# 2511| Type = [VoidType] void -# 2511| ValueCategory = prvalue -# 2511| getExpr(): [VariableAccess] c -# 2511| Type = [IntType] int -# 2511| ValueCategory = prvalue(load) -# 2511| getStmt(): [BlockStmt] { ... } -# 2512| getStmt(0): [SwitchCase] case ...: -# 2512| getExpr(): [Literal] 0 -# 2512| Type = [IntType] int -# 2512| Value = [Literal] 0 -# 2512| ValueCategory = prvalue -# 2512| getStmt(1): [BlockStmt] { ... } -# 2513| getStmt(0): [BreakStmt] break; -# 2518| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2518| Type = [VoidType] void -# 2518| ValueCategory = prvalue -# 2518| getQualifier(): [VariableAccess] y -# 2518| Type = [Class] ClassWithDestructor -# 2518| ValueCategory = lvalue -# 2515| getStmt(2): [SwitchCase] default: -# 2515| getStmt(3): [BlockStmt] { ... } -# 2516| getStmt(0): [BreakStmt] break; -# 2518| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2518| Type = [VoidType] void -# 2518| ValueCategory = prvalue -# 2518| getQualifier(): [VariableAccess] y -# 2518| Type = [Class] ClassWithDestructor -# 2518| ValueCategory = lvalue -# 2518| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2518| Type = [VoidType] void -# 2518| ValueCategory = prvalue -# 2518| getQualifier(): [VariableAccess] y -# 2518| Type = [Class] ClassWithDestructor -# 2518| ValueCategory = lvalue -# 2518| getStmt(1): [LabelStmt] label ...: -# 2519| getStmt(2): [ReturnStmt] return ... -# 2521| [TopLevelFunction] void destruction_in_switch_3(int) -# 2521| : -# 2521| getParameter(0): [Parameter] c -# 2521| Type = [IntType] int -# 2521| getEntryPoint(): [BlockStmt] { ... } -# 2522| getStmt(0): [SwitchStmt] switch (...) ... -# 2522| getInitialization(): [DeclStmt] declaration -# 2522| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y -# 2522| Type = [Class] ClassWithDestructor -# 2522| getVariable().getInitializer(): [Initializer] initializer for y -# 2522| getExpr(): [ConstructorCall] call to ClassWithDestructor -# 2522| Type = [VoidType] void -# 2522| ValueCategory = prvalue -# 2522| getExpr(): [VariableAccess] c -# 2522| Type = [IntType] int -# 2522| ValueCategory = prvalue(load) -# 2522| getStmt(): [BlockStmt] { ... } -# 2523| getStmt(0): [SwitchCase] case ...: -# 2523| getExpr(): [Literal] 0 -# 2523| Type = [IntType] int -# 2523| Value = [Literal] 0 -# 2523| ValueCategory = prvalue -# 2523| getStmt(1): [BlockStmt] { ... } -# 2524| getStmt(0): [DeclStmt] declaration -# 2524| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x -# 2524| Type = [Class] ClassWithDestructor -# 2524| getVariable().getInitializer(): [Initializer] initializer for x -# 2524| getExpr(): [ConstructorCall] call to ClassWithDestructor -# 2524| Type = [VoidType] void -# 2524| ValueCategory = prvalue -# 2525| getStmt(1): [BreakStmt] break; -# 2526| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2526| Type = [VoidType] void -# 2526| ValueCategory = prvalue -# 2526| getQualifier(): [VariableAccess] x -# 2526| Type = [Class] ClassWithDestructor -# 2526| ValueCategory = lvalue -# 2530| getImplicitDestructorCall(1): [DestructorCall] call to ~ClassWithDestructor -# 2530| Type = [VoidType] void -# 2530| ValueCategory = prvalue -# 2530| getQualifier(): [VariableAccess] y -# 2530| Type = [Class] ClassWithDestructor -# 2530| ValueCategory = lvalue -# 2526| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2526| Type = [VoidType] void -# 2526| ValueCategory = prvalue -# 2526| getQualifier(): [VariableAccess] x -# 2526| Type = [Class] ClassWithDestructor -# 2526| ValueCategory = lvalue -# 2527| getStmt(2): [SwitchCase] default: -# 2527| getStmt(3): [BlockStmt] { ... } -# 2528| getStmt(0): [BreakStmt] break; -# 2530| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2530| Type = [VoidType] void -# 2530| ValueCategory = prvalue -# 2530| getQualifier(): [VariableAccess] y -# 2530| Type = [Class] ClassWithDestructor -# 2530| ValueCategory = lvalue -# 2530| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2530| Type = [VoidType] void -# 2530| ValueCategory = prvalue -# 2530| getQualifier(): [VariableAccess] y -# 2530| Type = [Class] ClassWithDestructor -# 2530| ValueCategory = lvalue -# 2530| getStmt(1): [LabelStmt] label ...: -# 2531| getStmt(2): [ReturnStmt] return ... -# 2533| [TopLevelFunction] void destructor_possibly_not_handled() -# 2533| : -# 2533| getEntryPoint(): [BlockStmt] { ... } -# 2534| getStmt(0): [DeclStmt] declaration -# 2534| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x -# 2534| Type = [Class] ClassWithDestructor -# 2534| getVariable().getInitializer(): [Initializer] initializer for x -# 2534| getExpr(): [ConstructorCall] call to ClassWithDestructor -# 2534| Type = [VoidType] void -# 2534| ValueCategory = prvalue -# 2535| getStmt(1): [TryStmt] try { ... } -# 2535| getStmt(): [BlockStmt] { ... } -# 2536| getStmt(0): [ExprStmt] ExprStmt -# 2536| getExpr(): [ThrowExpr] throw ... -# 2536| Type = [IntType] int -# 2536| ValueCategory = prvalue -# 2536| getExpr(): [Literal] 42 -# 2536| Type = [IntType] int -# 2536| Value = [Literal] 42 -# 2536| ValueCategory = prvalue -# 2538| getChild(1): [Handler] -# 2538| getBlock(): [CatchBlock] { ... } -# 2540| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2540| Type = [VoidType] void -# 2540| ValueCategory = prvalue -# 2540| getQualifier(): [VariableAccess] x -# 2540| Type = [Class] ClassWithDestructor -# 2540| ValueCategory = lvalue -# 2540| getStmt(2): [ReturnStmt] return ... -# 2540| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor -# 2540| Type = [VoidType] void -# 2540| ValueCategory = prvalue -# 2540| getQualifier(): [VariableAccess] x -# 2540| Type = [Class] ClassWithDestructor -# 2540| ValueCategory = lvalue +# 2500| getStmt(4): [ReturnStmt] return ... +# 2502| [TopLevelFunction] void destruction_in_switch_1(int) +# 2502| : +# 2502| getParameter(0): [Parameter] c +# 2502| Type = [IntType] int +# 2502| getEntryPoint(): [BlockStmt] { ... } +# 2503| getStmt(0): [SwitchStmt] switch (...) ... +# 2503| getExpr(): [VariableAccess] c +# 2503| Type = [IntType] int +# 2503| ValueCategory = prvalue(load) +# 2503| getStmt(): [BlockStmt] { ... } +# 2504| getStmt(0): [SwitchCase] case ...: +# 2504| getExpr(): [Literal] 0 +# 2504| Type = [IntType] int +# 2504| Value = [Literal] 0 +# 2504| ValueCategory = prvalue +# 2504| getStmt(1): [BlockStmt] { ... } +# 2505| getStmt(0): [DeclStmt] declaration +# 2505| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x +# 2505| Type = [Class] ClassWithDestructor +# 2505| getVariable().getInitializer(): [Initializer] initializer for x +# 2505| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2505| Type = [VoidType] void +# 2505| ValueCategory = prvalue +# 2506| getStmt(1): [BreakStmt] break; +# 2507| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2507| Type = [VoidType] void +# 2507| ValueCategory = prvalue +# 2507| getQualifier(): [VariableAccess] x +# 2507| Type = [Class] ClassWithDestructor +# 2507| ValueCategory = lvalue +# 2507| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2507| Type = [VoidType] void +# 2507| ValueCategory = prvalue +# 2507| getQualifier(): [VariableAccess] x +# 2507| Type = [Class] ClassWithDestructor +# 2507| ValueCategory = lvalue +# 2508| getStmt(1): [LabelStmt] label ...: +# 2509| getStmt(2): [ReturnStmt] return ... +# 2511| [TopLevelFunction] void destruction_in_switch_2(int) +# 2511| : +# 2511| getParameter(0): [Parameter] c +# 2511| Type = [IntType] int +# 2511| getEntryPoint(): [BlockStmt] { ... } +# 2512| getStmt(0): [SwitchStmt] switch (...) ... +# 2512| getInitialization(): [DeclStmt] declaration +# 2512| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y +# 2512| Type = [Class] ClassWithDestructor +# 2512| getVariable().getInitializer(): [Initializer] initializer for y +# 2512| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2512| Type = [VoidType] void +# 2512| ValueCategory = prvalue +# 2512| getExpr(): [VariableAccess] c +# 2512| Type = [IntType] int +# 2512| ValueCategory = prvalue(load) +# 2512| getStmt(): [BlockStmt] { ... } +# 2513| getStmt(0): [SwitchCase] case ...: +# 2513| getExpr(): [Literal] 0 +# 2513| Type = [IntType] int +# 2513| Value = [Literal] 0 +# 2513| ValueCategory = prvalue +# 2513| getStmt(1): [BlockStmt] { ... } +# 2514| getStmt(0): [BreakStmt] break; +# 2519| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2519| Type = [VoidType] void +# 2519| ValueCategory = prvalue +# 2519| getQualifier(): [VariableAccess] y +# 2519| Type = [Class] ClassWithDestructor +# 2519| ValueCategory = lvalue +# 2516| getStmt(2): [SwitchCase] default: +# 2516| getStmt(3): [BlockStmt] { ... } +# 2517| getStmt(0): [BreakStmt] break; +# 2519| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2519| Type = [VoidType] void +# 2519| ValueCategory = prvalue +# 2519| getQualifier(): [VariableAccess] y +# 2519| Type = [Class] ClassWithDestructor +# 2519| ValueCategory = lvalue +# 2519| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2519| Type = [VoidType] void +# 2519| ValueCategory = prvalue +# 2519| getQualifier(): [VariableAccess] y +# 2519| Type = [Class] ClassWithDestructor +# 2519| ValueCategory = lvalue +# 2519| getStmt(1): [LabelStmt] label ...: +# 2520| getStmt(2): [ReturnStmt] return ... +# 2522| [TopLevelFunction] void destruction_in_switch_3(int) +# 2522| : +# 2522| getParameter(0): [Parameter] c +# 2522| Type = [IntType] int +# 2522| getEntryPoint(): [BlockStmt] { ... } +# 2523| getStmt(0): [SwitchStmt] switch (...) ... +# 2523| getInitialization(): [DeclStmt] declaration +# 2523| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y +# 2523| Type = [Class] ClassWithDestructor +# 2523| getVariable().getInitializer(): [Initializer] initializer for y +# 2523| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2523| Type = [VoidType] void +# 2523| ValueCategory = prvalue +# 2523| getExpr(): [VariableAccess] c +# 2523| Type = [IntType] int +# 2523| ValueCategory = prvalue(load) +# 2523| getStmt(): [BlockStmt] { ... } +# 2524| getStmt(0): [SwitchCase] case ...: +# 2524| getExpr(): [Literal] 0 +# 2524| Type = [IntType] int +# 2524| Value = [Literal] 0 +# 2524| ValueCategory = prvalue +# 2524| getStmt(1): [BlockStmt] { ... } +# 2525| getStmt(0): [DeclStmt] declaration +# 2525| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x +# 2525| Type = [Class] ClassWithDestructor +# 2525| getVariable().getInitializer(): [Initializer] initializer for x +# 2525| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2525| Type = [VoidType] void +# 2525| ValueCategory = prvalue +# 2526| getStmt(1): [BreakStmt] break; +# 2527| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2527| Type = [VoidType] void +# 2527| ValueCategory = prvalue +# 2527| getQualifier(): [VariableAccess] x +# 2527| Type = [Class] ClassWithDestructor +# 2527| ValueCategory = lvalue +# 2531| getImplicitDestructorCall(1): [DestructorCall] call to ~ClassWithDestructor +# 2531| Type = [VoidType] void +# 2531| ValueCategory = prvalue +# 2531| getQualifier(): [VariableAccess] y +# 2531| Type = [Class] ClassWithDestructor +# 2531| ValueCategory = lvalue +# 2527| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2527| Type = [VoidType] void +# 2527| ValueCategory = prvalue +# 2527| getQualifier(): [VariableAccess] x +# 2527| Type = [Class] ClassWithDestructor +# 2527| ValueCategory = lvalue +# 2528| getStmt(2): [SwitchCase] default: +# 2528| getStmt(3): [BlockStmt] { ... } +# 2529| getStmt(0): [BreakStmt] break; +# 2531| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2531| Type = [VoidType] void +# 2531| ValueCategory = prvalue +# 2531| getQualifier(): [VariableAccess] y +# 2531| Type = [Class] ClassWithDestructor +# 2531| ValueCategory = lvalue +# 2531| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2531| Type = [VoidType] void +# 2531| ValueCategory = prvalue +# 2531| getQualifier(): [VariableAccess] y +# 2531| Type = [Class] ClassWithDestructor +# 2531| ValueCategory = lvalue +# 2531| getStmt(1): [LabelStmt] label ...: +# 2532| getStmt(2): [ReturnStmt] return ... +# 2534| [TopLevelFunction] void destructor_possibly_not_handled() +# 2534| : +# 2534| getEntryPoint(): [BlockStmt] { ... } +# 2535| getStmt(0): [DeclStmt] declaration +# 2535| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x +# 2535| Type = [Class] ClassWithDestructor +# 2535| getVariable().getInitializer(): [Initializer] initializer for x +# 2535| getExpr(): [ConstructorCall] call to ClassWithDestructor +# 2535| Type = [VoidType] void +# 2535| ValueCategory = prvalue +# 2536| getStmt(1): [TryStmt] try { ... } +# 2536| getStmt(): [BlockStmt] { ... } +# 2537| getStmt(0): [ExprStmt] ExprStmt +# 2537| getExpr(): [ThrowExpr] throw ... +# 2537| Type = [IntType] int +# 2537| ValueCategory = prvalue +# 2537| getExpr(): [Literal] 42 +# 2537| Type = [IntType] int +# 2537| Value = [Literal] 42 +# 2537| ValueCategory = prvalue +# 2539| getChild(1): [Handler] +# 2539| getBlock(): [CatchBlock] { ... } +# 2541| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2541| Type = [VoidType] void +# 2541| ValueCategory = prvalue +# 2541| getQualifier(): [VariableAccess] x +# 2541| Type = [Class] ClassWithDestructor +# 2541| ValueCategory = lvalue +# 2541| getStmt(2): [ReturnStmt] return ... +# 2541| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2541| Type = [VoidType] void +# 2541| ValueCategory = prvalue +# 2541| getQualifier(): [VariableAccess] x +# 2541| Type = [Class] ClassWithDestructor +# 2541| ValueCategory = lvalue perf-regression.cpp: # 4| [CopyAssignmentOperator] Big& Big::operator=(Big const&) # 4| : diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected index 1fe18e4f92a9..2fc610f6d128 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected @@ -15335,2920 +15335,2920 @@ ir.cpp: # 2193| v2193_19(void) = AliasedUse : m2193_3 # 2193| v2193_20(void) = ExitFunction : -# 2196| bool initialization_with_destructor_bool -# 2196| Block 0 -# 2196| v2196_1(void) = EnterFunction : -# 2196| m2196_2(unknown) = AliasedDefinition : -# 2196| r2196_3(glval) = VariableAddress[initialization_with_destructor_bool] : -# 2196| r2196_4(bool) = Constant[1] : -# 2196| m2196_5(bool) = Store[initialization_with_destructor_bool] : &:r2196_3, r2196_4 -# 2196| m2196_6(unknown) = Chi : total:m2196_2, partial:m2196_5 -# 2196| v2196_7(void) = ReturnVoid : -# 2196| v2196_8(void) = AliasedUse : ~m2196_6 -# 2196| v2196_9(void) = ExitFunction : - -# 2198| void initialization_with_destructor(bool, char) -# 2198| Block 0 -# 2198| v2198_1(void) = EnterFunction : -# 2198| m2198_2(unknown) = AliasedDefinition : -# 2198| m2198_3(unknown) = InitializeNonLocal : -# 2198| m2198_4(unknown) = Chi : total:m2198_2, partial:m2198_3 -# 2198| r2198_5(glval) = VariableAddress[b] : -# 2198| m2198_6(bool) = InitializeParameter[b] : &:r2198_5 -# 2198| r2198_7(glval) = VariableAddress[c] : -# 2198| m2198_8(char) = InitializeParameter[c] : &:r2198_7 -# 2199| r2199_1(glval) = VariableAddress[x] : -# 2199| m2199_2(ClassWithDestructor) = Uninitialized[x] : &:r2199_1 -# 2199| r2199_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2199| v2199_4(void) = Call[ClassWithDestructor] : func:r2199_3, this:r2199_1 -# 2199| m2199_5(unknown) = ^CallSideEffect : ~m2198_4 -# 2199| m2199_6(unknown) = Chi : total:m2198_4, partial:m2199_5 -# 2199| m2199_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2199_1 -# 2199| m2199_8(ClassWithDestructor) = Chi : total:m2199_2, partial:m2199_7 -# 2199| r2199_9(glval) = VariableAddress[b] : -# 2199| r2199_10(bool) = Load[b] : &:r2199_9, m2198_6 -# 2199| v2199_11(void) = ConditionalBranch : r2199_10 +# 2197| bool initialization_with_destructor_bool +# 2197| Block 0 +# 2197| v2197_1(void) = EnterFunction : +# 2197| m2197_2(unknown) = AliasedDefinition : +# 2197| r2197_3(glval) = VariableAddress[initialization_with_destructor_bool] : +# 2197| r2197_4(bool) = Constant[1] : +# 2197| m2197_5(bool) = Store[initialization_with_destructor_bool] : &:r2197_3, r2197_4 +# 2197| m2197_6(unknown) = Chi : total:m2197_2, partial:m2197_5 +# 2197| v2197_7(void) = ReturnVoid : +# 2197| v2197_8(void) = AliasedUse : ~m2197_6 +# 2197| v2197_9(void) = ExitFunction : + +# 2199| void initialization_with_destructor(bool, char) +# 2199| Block 0 +# 2199| v2199_1(void) = EnterFunction : +# 2199| m2199_2(unknown) = AliasedDefinition : +# 2199| m2199_3(unknown) = InitializeNonLocal : +# 2199| m2199_4(unknown) = Chi : total:m2199_2, partial:m2199_3 +# 2199| r2199_5(glval) = VariableAddress[b] : +# 2199| m2199_6(bool) = InitializeParameter[b] : &:r2199_5 +# 2199| r2199_7(glval) = VariableAddress[c] : +# 2199| m2199_8(char) = InitializeParameter[c] : &:r2199_7 +# 2200| r2200_1(glval) = VariableAddress[x] : +# 2200| m2200_2(ClassWithDestructor) = Uninitialized[x] : &:r2200_1 +# 2200| r2200_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2200| v2200_4(void) = Call[ClassWithDestructor] : func:r2200_3, this:r2200_1 +# 2200| m2200_5(unknown) = ^CallSideEffect : ~m2199_4 +# 2200| m2200_6(unknown) = Chi : total:m2199_4, partial:m2200_5 +# 2200| m2200_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2200_1 +# 2200| m2200_8(ClassWithDestructor) = Chi : total:m2200_2, partial:m2200_7 +# 2200| r2200_9(glval) = VariableAddress[b] : +# 2200| r2200_10(bool) = Load[b] : &:r2200_9, m2199_6 +# 2200| v2200_11(void) = ConditionalBranch : r2200_10 #-----| False -> Block 3 #-----| True -> Block 2 -# 2198| Block 1 -# 2198| m2198_9(unknown) = Phi : from 14:~m2233_5, from 19:~m2233_13, from 23:~m2233_22 -# 2198| v2198_10(void) = ReturnVoid : -# 2198| v2198_11(void) = AliasedUse : ~m2198_9 -# 2198| v2198_12(void) = ExitFunction : - -# 2200| Block 2 -# 2200| r2200_1(glval) = VariableAddress[x] : -# 2200| r2200_2(glval) = FunctionAddress[set_x] : -# 2200| r2200_3(char) = Constant[97] : -# 2200| v2200_4(void) = Call[set_x] : func:r2200_2, this:r2200_1, 0:r2200_3 -# 2200| m2200_5(unknown) = ^CallSideEffect : ~m2199_6 -# 2200| m2200_6(unknown) = Chi : total:m2199_6, partial:m2200_5 -# 2200| v2200_7(void) = ^IndirectReadSideEffect[-1] : &:r2200_1, m2199_8 -# 2200| m2200_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2200_1 -# 2200| m2200_9(ClassWithDestructor) = Chi : total:m2199_8, partial:m2200_8 -# 2200| r2200_10(glval) = VariableAddress[x] : -# 2200| r2200_11(glval) = FunctionAddress[~ClassWithDestructor] : -# 2200| v2200_12(void) = Call[~ClassWithDestructor] : func:r2200_11, this:r2200_10 -# 2200| m2200_13(unknown) = ^CallSideEffect : ~m2200_6 -# 2200| m2200_14(unknown) = Chi : total:m2200_6, partial:m2200_13 -# 2200| v2200_15(void) = ^IndirectReadSideEffect[-1] : &:r2200_10, m2200_9 -# 2200| m2200_16(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2200_10 -# 2200| m2200_17(ClassWithDestructor) = Chi : total:m2200_9, partial:m2200_16 +# 2199| Block 1 +# 2199| m2199_9(unknown) = Phi : from 14:~m2234_5, from 19:~m2234_13, from 23:~m2234_22 +# 2199| v2199_10(void) = ReturnVoid : +# 2199| v2199_11(void) = AliasedUse : ~m2199_9 +# 2199| v2199_12(void) = ExitFunction : + +# 2201| Block 2 +# 2201| r2201_1(glval) = VariableAddress[x] : +# 2201| r2201_2(glval) = FunctionAddress[set_x] : +# 2201| r2201_3(char) = Constant[97] : +# 2201| v2201_4(void) = Call[set_x] : func:r2201_2, this:r2201_1, 0:r2201_3 +# 2201| m2201_5(unknown) = ^CallSideEffect : ~m2200_6 +# 2201| m2201_6(unknown) = Chi : total:m2200_6, partial:m2201_5 +# 2201| v2201_7(void) = ^IndirectReadSideEffect[-1] : &:r2201_1, m2200_8 +# 2201| m2201_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2201_1 +# 2201| m2201_9(ClassWithDestructor) = Chi : total:m2200_8, partial:m2201_8 +# 2201| r2201_10(glval) = VariableAddress[x] : +# 2201| r2201_11(glval) = FunctionAddress[~ClassWithDestructor] : +# 2201| v2201_12(void) = Call[~ClassWithDestructor] : func:r2201_11, this:r2201_10 +# 2201| m2201_13(unknown) = ^CallSideEffect : ~m2201_6 +# 2201| m2201_14(unknown) = Chi : total:m2201_6, partial:m2201_13 +# 2201| v2201_15(void) = ^IndirectReadSideEffect[-1] : &:r2201_10, m2201_9 +# 2201| m2201_16(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2201_10 +# 2201| m2201_17(ClassWithDestructor) = Chi : total:m2201_9, partial:m2201_16 #-----| Goto -> Block 3 -# 2202| Block 3 -# 2202| m2202_1(unknown) = Phi : from 0:~m2199_6, from 2:~m2200_14 -# 2202| r2202_2(glval) = VariableAddress[x] : -# 2202| m2202_3(ClassWithDestructor) = Uninitialized[x] : &:r2202_2 -# 2202| r2202_4(glval) = FunctionAddress[ClassWithDestructor] : -# 2202| v2202_5(void) = Call[ClassWithDestructor] : func:r2202_4, this:r2202_2 -# 2202| m2202_6(unknown) = ^CallSideEffect : ~m2202_1 -# 2202| m2202_7(unknown) = Chi : total:m2202_1, partial:m2202_6 -# 2202| m2202_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2202_2 -# 2202| m2202_9(ClassWithDestructor) = Chi : total:m2202_3, partial:m2202_8 -# 2202| r2202_10(bool) = Constant[1] : -# 2202| v2202_11(void) = ConditionalBranch : r2202_10 +# 2203| Block 3 +# 2203| m2203_1(unknown) = Phi : from 0:~m2200_6, from 2:~m2201_14 +# 2203| r2203_2(glval) = VariableAddress[x] : +# 2203| m2203_3(ClassWithDestructor) = Uninitialized[x] : &:r2203_2 +# 2203| r2203_4(glval) = FunctionAddress[ClassWithDestructor] : +# 2203| v2203_5(void) = Call[ClassWithDestructor] : func:r2203_4, this:r2203_2 +# 2203| m2203_6(unknown) = ^CallSideEffect : ~m2203_1 +# 2203| m2203_7(unknown) = Chi : total:m2203_1, partial:m2203_6 +# 2203| m2203_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2203_2 +# 2203| m2203_9(ClassWithDestructor) = Chi : total:m2203_3, partial:m2203_8 +# 2203| r2203_10(bool) = Constant[1] : +# 2203| v2203_11(void) = ConditionalBranch : r2203_10 #-----| False -> Block 24 #-----| True -> Block 4 -# 2203| Block 4 -# 2203| r2203_1(glval) = VariableAddress[x] : -# 2203| r2203_2(glval) = FunctionAddress[set_x] : -# 2203| r2203_3(char) = Constant[97] : -# 2203| v2203_4(void) = Call[set_x] : func:r2203_2, this:r2203_1, 0:r2203_3 -# 2203| m2203_5(unknown) = ^CallSideEffect : ~m2202_7 -# 2203| m2203_6(unknown) = Chi : total:m2202_7, partial:m2203_5 -# 2203| v2203_7(void) = ^IndirectReadSideEffect[-1] : &:r2203_1, m2202_9 -# 2203| m2203_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2203_1 -# 2203| m2203_9(ClassWithDestructor) = Chi : total:m2202_9, partial:m2203_8 -# 2205| r2205_1(glval) = VariableAddress[x] : -# 2205| m2205_2(ClassWithDestructor) = Uninitialized[x] : &:r2205_1 -# 2205| r2205_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2205| v2205_4(void) = Call[ClassWithDestructor] : func:r2205_3, this:r2205_1 -# 2205| m2205_5(unknown) = ^CallSideEffect : ~m2203_6 -# 2205| m2205_6(unknown) = Chi : total:m2203_6, partial:m2205_5 -# 2205| m2205_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2205_1 -# 2205| m2205_8(ClassWithDestructor) = Chi : total:m2205_2, partial:m2205_7 -# 2205| r2205_9(glval) = VariableAddress[c] : -# 2205| r2205_10(char) = Load[c] : &:r2205_9, m2198_8 -# 2205| r2205_11(int) = Convert : r2205_10 -# 2205| v2205_12(void) = Switch : r2205_11 +# 2204| Block 4 +# 2204| r2204_1(glval) = VariableAddress[x] : +# 2204| r2204_2(glval) = FunctionAddress[set_x] : +# 2204| r2204_3(char) = Constant[97] : +# 2204| v2204_4(void) = Call[set_x] : func:r2204_2, this:r2204_1, 0:r2204_3 +# 2204| m2204_5(unknown) = ^CallSideEffect : ~m2203_7 +# 2204| m2204_6(unknown) = Chi : total:m2203_7, partial:m2204_5 +# 2204| v2204_7(void) = ^IndirectReadSideEffect[-1] : &:r2204_1, m2203_9 +# 2204| m2204_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2204_1 +# 2204| m2204_9(ClassWithDestructor) = Chi : total:m2203_9, partial:m2204_8 +# 2206| r2206_1(glval) = VariableAddress[x] : +# 2206| m2206_2(ClassWithDestructor) = Uninitialized[x] : &:r2206_1 +# 2206| r2206_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2206| v2206_4(void) = Call[ClassWithDestructor] : func:r2206_3, this:r2206_1 +# 2206| m2206_5(unknown) = ^CallSideEffect : ~m2204_6 +# 2206| m2206_6(unknown) = Chi : total:m2204_6, partial:m2206_5 +# 2206| m2206_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2206_1 +# 2206| m2206_8(ClassWithDestructor) = Chi : total:m2206_2, partial:m2206_7 +# 2206| r2206_9(glval) = VariableAddress[c] : +# 2206| r2206_10(char) = Load[c] : &:r2206_9, m2199_8 +# 2206| r2206_11(int) = Convert : r2206_10 +# 2206| v2206_12(void) = Switch : r2206_11 #-----| Case[97] -> Block 5 #-----| Default -> Block 6 -# 2206| Block 5 -# 2206| v2206_1(void) = NoOp : -# 2207| r2207_1(glval) = VariableAddress[x] : -# 2207| r2207_2(glval) = FunctionAddress[set_x] : -# 2207| r2207_3(char) = Constant[97] : -# 2207| v2207_4(void) = Call[set_x] : func:r2207_2, this:r2207_1, 0:r2207_3 -# 2207| m2207_5(unknown) = ^CallSideEffect : ~m2205_6 -# 2207| m2207_6(unknown) = Chi : total:m2205_6, partial:m2207_5 -# 2207| v2207_7(void) = ^IndirectReadSideEffect[-1] : &:r2207_1, m2205_8 -# 2207| m2207_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2207_1 -# 2207| m2207_9(ClassWithDestructor) = Chi : total:m2205_8, partial:m2207_8 -# 2212| r2212_1(glval) = VariableAddress[x] : -# 2212| r2212_2(glval) = FunctionAddress[~ClassWithDestructor] : -# 2212| v2212_3(void) = Call[~ClassWithDestructor] : func:r2212_2, this:r2212_1 -# 2212| m2212_4(unknown) = ^CallSideEffect : ~m2207_6 -# 2212| m2212_5(unknown) = Chi : total:m2207_6, partial:m2212_4 -# 2212| v2212_6(void) = ^IndirectReadSideEffect[-1] : &:r2212_1, m2207_9 -# 2212| m2212_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2212_1 -# 2212| m2212_8(ClassWithDestructor) = Chi : total:m2207_9, partial:m2212_7 -# 2208| v2208_1(void) = NoOp : +# 2207| Block 5 +# 2207| v2207_1(void) = NoOp : +# 2208| r2208_1(glval) = VariableAddress[x] : +# 2208| r2208_2(glval) = FunctionAddress[set_x] : +# 2208| r2208_3(char) = Constant[97] : +# 2208| v2208_4(void) = Call[set_x] : func:r2208_2, this:r2208_1, 0:r2208_3 +# 2208| m2208_5(unknown) = ^CallSideEffect : ~m2206_6 +# 2208| m2208_6(unknown) = Chi : total:m2206_6, partial:m2208_5 +# 2208| v2208_7(void) = ^IndirectReadSideEffect[-1] : &:r2208_1, m2206_8 +# 2208| m2208_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2208_1 +# 2208| m2208_9(ClassWithDestructor) = Chi : total:m2206_8, partial:m2208_8 +# 2213| r2213_1(glval) = VariableAddress[x] : +# 2213| r2213_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2213| v2213_3(void) = Call[~ClassWithDestructor] : func:r2213_2, this:r2213_1 +# 2213| m2213_4(unknown) = ^CallSideEffect : ~m2208_6 +# 2213| m2213_5(unknown) = Chi : total:m2208_6, partial:m2213_4 +# 2213| v2213_6(void) = ^IndirectReadSideEffect[-1] : &:r2213_1, m2208_9 +# 2213| m2213_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2213_1 +# 2213| m2213_8(ClassWithDestructor) = Chi : total:m2208_9, partial:m2213_7 +# 2209| v2209_1(void) = NoOp : #-----| Goto -> Block 7 -# 2209| Block 6 -# 2209| v2209_1(void) = NoOp : -# 2210| r2210_1(glval) = VariableAddress[x] : -# 2210| r2210_2(glval) = FunctionAddress[set_x] : -# 2210| r2210_3(char) = Constant[98] : -# 2210| v2210_4(void) = Call[set_x] : func:r2210_2, this:r2210_1, 0:r2210_3 -# 2210| m2210_5(unknown) = ^CallSideEffect : ~m2205_6 -# 2210| m2210_6(unknown) = Chi : total:m2205_6, partial:m2210_5 -# 2210| v2210_7(void) = ^IndirectReadSideEffect[-1] : &:r2210_1, m2205_8 -# 2210| m2210_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2210_1 -# 2210| m2210_9(ClassWithDestructor) = Chi : total:m2205_8, partial:m2210_8 -# 2212| r2212_9(glval) = VariableAddress[x] : -# 2212| r2212_10(glval) = FunctionAddress[~ClassWithDestructor] : -# 2212| v2212_11(void) = Call[~ClassWithDestructor] : func:r2212_10, this:r2212_9 -# 2212| m2212_12(unknown) = ^CallSideEffect : ~m2210_6 -# 2212| m2212_13(unknown) = Chi : total:m2210_6, partial:m2212_12 -# 2212| v2212_14(void) = ^IndirectReadSideEffect[-1] : &:r2212_9, m2210_9 -# 2212| m2212_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2212_9 -# 2212| m2212_16(ClassWithDestructor) = Chi : total:m2210_9, partial:m2212_15 -# 2211| v2211_1(void) = NoOp : +# 2210| Block 6 +# 2210| v2210_1(void) = NoOp : +# 2211| r2211_1(glval) = VariableAddress[x] : +# 2211| r2211_2(glval) = FunctionAddress[set_x] : +# 2211| r2211_3(char) = Constant[98] : +# 2211| v2211_4(void) = Call[set_x] : func:r2211_2, this:r2211_1, 0:r2211_3 +# 2211| m2211_5(unknown) = ^CallSideEffect : ~m2206_6 +# 2211| m2211_6(unknown) = Chi : total:m2206_6, partial:m2211_5 +# 2211| v2211_7(void) = ^IndirectReadSideEffect[-1] : &:r2211_1, m2206_8 +# 2211| m2211_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2211_1 +# 2211| m2211_9(ClassWithDestructor) = Chi : total:m2206_8, partial:m2211_8 +# 2213| r2213_9(glval) = VariableAddress[x] : +# 2213| r2213_10(glval) = FunctionAddress[~ClassWithDestructor] : +# 2213| v2213_11(void) = Call[~ClassWithDestructor] : func:r2213_10, this:r2213_9 +# 2213| m2213_12(unknown) = ^CallSideEffect : ~m2211_6 +# 2213| m2213_13(unknown) = Chi : total:m2211_6, partial:m2213_12 +# 2213| v2213_14(void) = ^IndirectReadSideEffect[-1] : &:r2213_9, m2211_9 +# 2213| m2213_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2213_9 +# 2213| m2213_16(ClassWithDestructor) = Chi : total:m2211_9, partial:m2213_15 +# 2212| v2212_1(void) = NoOp : #-----| Goto -> Block 7 -# 2212| Block 7 -# 2212| m2212_17(unknown) = Phi : from 5:~m2212_5, from 6:~m2212_13 -# 2212| v2212_18(void) = NoOp : -# 2214| r2214_1(glval) = VariableAddress[x] : -# 2214| m2214_2(ClassWithDestructor) = Uninitialized[x] : &:r2214_1 -# 2214| r2214_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2214| v2214_4(void) = Call[ClassWithDestructor] : func:r2214_3, this:r2214_1 -# 2214| m2214_5(unknown) = ^CallSideEffect : ~m2212_17 -# 2214| m2214_6(unknown) = Chi : total:m2212_17, partial:m2214_5 -# 2214| m2214_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2214_1 -# 2214| m2214_8(ClassWithDestructor) = Chi : total:m2214_2, partial:m2214_7 -# 2215| r2215_1(glval>) = VariableAddress[ys] : -# 2215| m2215_2(vector) = Uninitialized[ys] : &:r2215_1 -# 2215| m2215_3(unknown) = Chi : total:m2214_6, partial:m2215_2 -# 2215| r2215_4(glval) = FunctionAddress[vector] : -# 2215| r2215_5(glval) = VariableAddress[#temp2215:45] : -# 2215| r2215_6(glval) = VariableAddress[x] : -# 2215| r2215_7(ClassWithDestructor) = Load[x] : &:r2215_6, m2214_8 -# 2215| m2215_8(ClassWithDestructor) = Store[#temp2215:45] : &:r2215_5, r2215_7 -# 2215| r2215_9(ClassWithDestructor) = Load[#temp2215:45] : &:r2215_5, m2215_8 -# 2215| v2215_10(void) = Call[vector] : func:r2215_4, this:r2215_1, 0:r2215_9 -# 2215| m2215_11(unknown) = ^CallSideEffect : ~m2215_3 -# 2215| m2215_12(unknown) = Chi : total:m2215_3, partial:m2215_11 -# 2215| m2215_13(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2215_1 -# 2215| m2215_14(unknown) = Chi : total:m2215_12, partial:m2215_13 -# 2215| r2215_15(glval) = CopyValue : r2215_5 -# 2215| r2215_16(glval) = FunctionAddress[~ClassWithDestructor] : -# 2215| v2215_17(void) = Call[~ClassWithDestructor] : func:r2215_16, this:r2215_15 -# 2215| m2215_18(unknown) = ^CallSideEffect : ~m2215_14 -# 2215| m2215_19(unknown) = Chi : total:m2215_14, partial:m2215_18 -# 2215| v2215_20(void) = ^IndirectReadSideEffect[-1] : &:r2215_15, m2215_8 -# 2215| m2215_21(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2215_15 -# 2215| m2215_22(ClassWithDestructor) = Chi : total:m2215_8, partial:m2215_21 -# 2215| r2215_23(glval &>) = VariableAddress[(__range)] : -# 2215| r2215_24(glval>) = VariableAddress[ys] : -# 2215| r2215_25(vector &) = CopyValue : r2215_24 -# 2215| m2215_26(vector &) = Store[(__range)] : &:r2215_23, r2215_25 -# 2215| r2215_27(glval>) = VariableAddress[(__begin)] : -# 2215| r2215_28(glval &>) = VariableAddress[(__range)] : -# 2215| r2215_29(vector &) = Load[(__range)] : &:r2215_28, m2215_26 -#-----| r0_1(glval>) = CopyValue : r2215_29 +# 2213| Block 7 +# 2213| m2213_17(unknown) = Phi : from 5:~m2213_5, from 6:~m2213_13 +# 2213| v2213_18(void) = NoOp : +# 2215| r2215_1(glval) = VariableAddress[x] : +# 2215| m2215_2(ClassWithDestructor) = Uninitialized[x] : &:r2215_1 +# 2215| r2215_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2215| v2215_4(void) = Call[ClassWithDestructor] : func:r2215_3, this:r2215_1 +# 2215| m2215_5(unknown) = ^CallSideEffect : ~m2213_17 +# 2215| m2215_6(unknown) = Chi : total:m2213_17, partial:m2215_5 +# 2215| m2215_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2215_1 +# 2215| m2215_8(ClassWithDestructor) = Chi : total:m2215_2, partial:m2215_7 +# 2216| r2216_1(glval>) = VariableAddress[ys] : +# 2216| m2216_2(vector) = Uninitialized[ys] : &:r2216_1 +# 2216| m2216_3(unknown) = Chi : total:m2215_6, partial:m2216_2 +# 2216| r2216_4(glval) = FunctionAddress[vector] : +# 2216| r2216_5(glval) = VariableAddress[#temp2216:45] : +# 2216| r2216_6(glval) = VariableAddress[x] : +# 2216| r2216_7(ClassWithDestructor) = Load[x] : &:r2216_6, m2215_8 +# 2216| m2216_8(ClassWithDestructor) = Store[#temp2216:45] : &:r2216_5, r2216_7 +# 2216| r2216_9(ClassWithDestructor) = Load[#temp2216:45] : &:r2216_5, m2216_8 +# 2216| v2216_10(void) = Call[vector] : func:r2216_4, this:r2216_1, 0:r2216_9 +# 2216| m2216_11(unknown) = ^CallSideEffect : ~m2216_3 +# 2216| m2216_12(unknown) = Chi : total:m2216_3, partial:m2216_11 +# 2216| m2216_13(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2216_1 +# 2216| m2216_14(unknown) = Chi : total:m2216_12, partial:m2216_13 +# 2216| r2216_15(glval) = CopyValue : r2216_5 +# 2216| r2216_16(glval) = FunctionAddress[~ClassWithDestructor] : +# 2216| v2216_17(void) = Call[~ClassWithDestructor] : func:r2216_16, this:r2216_15 +# 2216| m2216_18(unknown) = ^CallSideEffect : ~m2216_14 +# 2216| m2216_19(unknown) = Chi : total:m2216_14, partial:m2216_18 +# 2216| v2216_20(void) = ^IndirectReadSideEffect[-1] : &:r2216_15, m2216_8 +# 2216| m2216_21(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2216_15 +# 2216| m2216_22(ClassWithDestructor) = Chi : total:m2216_8, partial:m2216_21 +# 2216| r2216_23(glval &>) = VariableAddress[(__range)] : +# 2216| r2216_24(glval>) = VariableAddress[ys] : +# 2216| r2216_25(vector &) = CopyValue : r2216_24 +# 2216| m2216_26(vector &) = Store[(__range)] : &:r2216_23, r2216_25 +# 2216| r2216_27(glval>) = VariableAddress[(__begin)] : +# 2216| r2216_28(glval &>) = VariableAddress[(__range)] : +# 2216| r2216_29(vector &) = Load[(__range)] : &:r2216_28, m2216_26 +#-----| r0_1(glval>) = CopyValue : r2216_29 #-----| r0_2(glval>) = Convert : r0_1 -# 2215| r2215_30(glval) = FunctionAddress[begin] : -# 2215| r2215_31(iterator) = Call[begin] : func:r2215_30, this:r0_2 -#-----| v0_3(void) = ^IndirectReadSideEffect[-1] : &:r0_2, ~m2215_19 -# 2215| m2215_32(iterator) = Store[(__begin)] : &:r2215_27, r2215_31 -# 2215| r2215_33(glval>) = VariableAddress[(__end)] : -# 2215| r2215_34(glval &>) = VariableAddress[(__range)] : -# 2215| r2215_35(vector &) = Load[(__range)] : &:r2215_34, m2215_26 -#-----| r0_4(glval>) = CopyValue : r2215_35 +# 2216| r2216_30(glval) = FunctionAddress[begin] : +# 2216| r2216_31(iterator) = Call[begin] : func:r2216_30, this:r0_2 +#-----| v0_3(void) = ^IndirectReadSideEffect[-1] : &:r0_2, ~m2216_19 +# 2216| m2216_32(iterator) = Store[(__begin)] : &:r2216_27, r2216_31 +# 2216| r2216_33(glval>) = VariableAddress[(__end)] : +# 2216| r2216_34(glval &>) = VariableAddress[(__range)] : +# 2216| r2216_35(vector &) = Load[(__range)] : &:r2216_34, m2216_26 +#-----| r0_4(glval>) = CopyValue : r2216_35 #-----| r0_5(glval>) = Convert : r0_4 -# 2215| r2215_36(glval) = FunctionAddress[end] : -# 2215| r2215_37(iterator) = Call[end] : func:r2215_36, this:r0_5 -#-----| v0_6(void) = ^IndirectReadSideEffect[-1] : &:r0_5, ~m2215_19 -# 2215| m2215_38(iterator) = Store[(__end)] : &:r2215_33, r2215_37 -# 2215| m2215_39(unknown) = Chi : total:m2215_19, partial:m2215_38 +# 2216| r2216_36(glval) = FunctionAddress[end] : +# 2216| r2216_37(iterator) = Call[end] : func:r2216_36, this:r0_5 +#-----| v0_6(void) = ^IndirectReadSideEffect[-1] : &:r0_5, ~m2216_19 +# 2216| m2216_38(iterator) = Store[(__end)] : &:r2216_33, r2216_37 +# 2216| m2216_39(unknown) = Chi : total:m2216_19, partial:m2216_38 #-----| Goto -> Block 8 -# 2215| Block 8 -# 2215| m2215_40(iterator) = Phi : from 7:m2215_32, from 9:m2215_64 -# 2215| m2215_41(unknown) = Phi : from 7:~m2215_39, from 9:~m2215_69 -# 2215| r2215_42(glval>) = VariableAddress[(__begin)] : -#-----| r0_7(glval>) = Convert : r2215_42 -# 2215| r2215_43(glval) = FunctionAddress[operator!=] : +# 2216| Block 8 +# 2216| m2216_40(iterator) = Phi : from 7:m2216_32, from 9:m2216_64 +# 2216| m2216_41(unknown) = Phi : from 7:~m2216_39, from 9:~m2216_69 +# 2216| r2216_42(glval>) = VariableAddress[(__begin)] : +#-----| r0_7(glval>) = Convert : r2216_42 +# 2216| r2216_43(glval) = FunctionAddress[operator!=] : #-----| r0_8(glval>) = VariableAddress[#temp0:0] : #-----| m0_9(iterator) = Uninitialized[#temp0:0] : &:r0_8 -#-----| m0_10(unknown) = Chi : total:m2215_41, partial:m0_9 -# 2215| r2215_44(glval) = FunctionAddress[iterator] : -# 2215| r2215_45(glval>) = VariableAddress[(__end)] : -#-----| r0_11(glval>) = Convert : r2215_45 +#-----| m0_10(unknown) = Chi : total:m2216_41, partial:m0_9 +# 2216| r2216_44(glval) = FunctionAddress[iterator] : +# 2216| r2216_45(glval>) = VariableAddress[(__end)] : +#-----| r0_11(glval>) = Convert : r2216_45 #-----| r0_12(iterator &) = CopyValue : r0_11 -# 2215| v2215_46(void) = Call[iterator] : func:r2215_44, this:r0_8, 0:r0_12 -# 2215| m2215_47(unknown) = ^CallSideEffect : ~m0_10 -# 2215| m2215_48(unknown) = Chi : total:m0_10, partial:m2215_47 -#-----| v0_13(void) = ^BufferReadSideEffect[0] : &:r0_12, ~m2215_48 -# 2215| m2215_49(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_8 -# 2215| m2215_50(unknown) = Chi : total:m2215_48, partial:m2215_49 -#-----| r0_14(iterator) = Load[#temp0:0] : &:r0_8, ~m2215_50 -# 2215| r2215_51(bool) = Call[operator!=] : func:r2215_43, this:r0_7, 0:r0_14 -#-----| v0_15(void) = ^IndirectReadSideEffect[-1] : &:r0_7, m2215_40 -# 2215| v2215_52(void) = ConditionalBranch : r2215_51 +# 2216| v2216_46(void) = Call[iterator] : func:r2216_44, this:r0_8, 0:r0_12 +# 2216| m2216_47(unknown) = ^CallSideEffect : ~m0_10 +# 2216| m2216_48(unknown) = Chi : total:m0_10, partial:m2216_47 +#-----| v0_13(void) = ^BufferReadSideEffect[0] : &:r0_12, ~m2216_48 +# 2216| m2216_49(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_8 +# 2216| m2216_50(unknown) = Chi : total:m2216_48, partial:m2216_49 +#-----| r0_14(iterator) = Load[#temp0:0] : &:r0_8, ~m2216_50 +# 2216| r2216_51(bool) = Call[operator!=] : func:r2216_43, this:r0_7, 0:r0_14 +#-----| v0_15(void) = ^IndirectReadSideEffect[-1] : &:r0_7, m2216_40 +# 2216| v2216_52(void) = ConditionalBranch : r2216_51 #-----| False -> Block 10 #-----| True -> Block 9 -# 2215| Block 9 -# 2215| r2215_53(glval) = VariableAddress[y] : -# 2215| r2215_54(glval>) = VariableAddress[(__begin)] : -#-----| r0_16(glval>) = Convert : r2215_54 -# 2215| r2215_55(glval) = FunctionAddress[operator*] : -# 2215| r2215_56(ClassWithDestructor &) = Call[operator*] : func:r2215_55, this:r0_16 -#-----| v0_17(void) = ^IndirectReadSideEffect[-1] : &:r0_16, m2215_40 -# 2215| r2215_57(ClassWithDestructor) = Load[?] : &:r2215_56, ~m2215_50 -# 2215| m2215_58(ClassWithDestructor) = Store[y] : &:r2215_53, r2215_57 -# 2216| r2216_1(glval) = VariableAddress[y] : -# 2216| r2216_2(glval) = FunctionAddress[set_x] : -# 2216| r2216_3(char) = Constant[97] : -# 2216| v2216_4(void) = Call[set_x] : func:r2216_2, this:r2216_1, 0:r2216_3 -# 2216| m2216_5(unknown) = ^CallSideEffect : ~m2215_50 -# 2216| m2216_6(unknown) = Chi : total:m2215_50, partial:m2216_5 -# 2216| v2216_7(void) = ^IndirectReadSideEffect[-1] : &:r2216_1, m2215_58 -# 2216| m2216_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2216_1 -# 2216| m2216_9(ClassWithDestructor) = Chi : total:m2215_58, partial:m2216_8 -# 2215| r2215_59(glval>) = VariableAddress[(__begin)] : -# 2215| r2215_60(glval) = FunctionAddress[operator++] : -# 2215| r2215_61(iterator &) = Call[operator++] : func:r2215_60, this:r2215_59 -# 2215| v2215_62(void) = ^IndirectReadSideEffect[-1] : &:r2215_59, m2215_40 -# 2215| m2215_63(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2215_59 -# 2215| m2215_64(iterator) = Chi : total:m2215_40, partial:m2215_63 -# 2215| r2215_65(glval) = VariableAddress[y] : -# 2215| r2215_66(glval) = FunctionAddress[~ClassWithDestructor] : -# 2215| v2215_67(void) = Call[~ClassWithDestructor] : func:r2215_66, this:r2215_65 -# 2215| m2215_68(unknown) = ^CallSideEffect : ~m2216_6 -# 2215| m2215_69(unknown) = Chi : total:m2216_6, partial:m2215_68 -# 2215| v2215_70(void) = ^IndirectReadSideEffect[-1] : &:r2215_65, m2216_9 -# 2215| m2215_71(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2215_65 -# 2215| m2215_72(ClassWithDestructor) = Chi : total:m2216_9, partial:m2215_71 -# 2215| r2215_73(glval>) = CopyValue : r2215_61 +# 2216| Block 9 +# 2216| r2216_53(glval) = VariableAddress[y] : +# 2216| r2216_54(glval>) = VariableAddress[(__begin)] : +#-----| r0_16(glval>) = Convert : r2216_54 +# 2216| r2216_55(glval) = FunctionAddress[operator*] : +# 2216| r2216_56(ClassWithDestructor &) = Call[operator*] : func:r2216_55, this:r0_16 +#-----| v0_17(void) = ^IndirectReadSideEffect[-1] : &:r0_16, m2216_40 +# 2216| r2216_57(ClassWithDestructor) = Load[?] : &:r2216_56, ~m2216_50 +# 2216| m2216_58(ClassWithDestructor) = Store[y] : &:r2216_53, r2216_57 +# 2217| r2217_1(glval) = VariableAddress[y] : +# 2217| r2217_2(glval) = FunctionAddress[set_x] : +# 2217| r2217_3(char) = Constant[97] : +# 2217| v2217_4(void) = Call[set_x] : func:r2217_2, this:r2217_1, 0:r2217_3 +# 2217| m2217_5(unknown) = ^CallSideEffect : ~m2216_50 +# 2217| m2217_6(unknown) = Chi : total:m2216_50, partial:m2217_5 +# 2217| v2217_7(void) = ^IndirectReadSideEffect[-1] : &:r2217_1, m2216_58 +# 2217| m2217_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2217_1 +# 2217| m2217_9(ClassWithDestructor) = Chi : total:m2216_58, partial:m2217_8 +# 2216| r2216_59(glval>) = VariableAddress[(__begin)] : +# 2216| r2216_60(glval) = FunctionAddress[operator++] : +# 2216| r2216_61(iterator &) = Call[operator++] : func:r2216_60, this:r2216_59 +# 2216| v2216_62(void) = ^IndirectReadSideEffect[-1] : &:r2216_59, m2216_40 +# 2216| m2216_63(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2216_59 +# 2216| m2216_64(iterator) = Chi : total:m2216_40, partial:m2216_63 +# 2216| r2216_65(glval) = VariableAddress[y] : +# 2216| r2216_66(glval) = FunctionAddress[~ClassWithDestructor] : +# 2216| v2216_67(void) = Call[~ClassWithDestructor] : func:r2216_66, this:r2216_65 +# 2216| m2216_68(unknown) = ^CallSideEffect : ~m2217_6 +# 2216| m2216_69(unknown) = Chi : total:m2217_6, partial:m2216_68 +# 2216| v2216_70(void) = ^IndirectReadSideEffect[-1] : &:r2216_65, m2217_9 +# 2216| m2216_71(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2216_65 +# 2216| m2216_72(ClassWithDestructor) = Chi : total:m2217_9, partial:m2216_71 +# 2216| r2216_73(glval>) = CopyValue : r2216_61 #-----| Goto (back edge) -> Block 8 -# 2215| Block 10 -# 2215| r2215_74(glval>) = VariableAddress[ys] : -# 2215| r2215_75(glval) = FunctionAddress[~vector] : -# 2215| v2215_76(void) = Call[~vector] : func:r2215_75, this:r2215_74 -# 2215| m2215_77(unknown) = ^CallSideEffect : ~m2215_50 -# 2215| m2215_78(unknown) = Chi : total:m2215_50, partial:m2215_77 -# 2215| v2215_79(void) = ^IndirectReadSideEffect[-1] : &:r2215_74, ~m2215_78 -# 2215| m2215_80(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2215_74 -# 2215| m2215_81(unknown) = Chi : total:m2215_78, partial:m2215_80 -# 2218| r2218_1(glval>) = VariableAddress[ys] : -# 2218| m2218_2(vector) = Uninitialized[ys] : &:r2218_1 -# 2218| m2218_3(unknown) = Chi : total:m2215_81, partial:m2218_2 -# 2218| r2218_4(glval) = FunctionAddress[vector] : -# 2218| r2218_5(glval) = VariableAddress[#temp2218:45] : -# 2218| r2218_6(glval) = VariableAddress[x] : -# 2218| r2218_7(ClassWithDestructor) = Load[x] : &:r2218_6, m2214_8 -# 2218| m2218_8(ClassWithDestructor) = Store[#temp2218:45] : &:r2218_5, r2218_7 -# 2218| r2218_9(ClassWithDestructor) = Load[#temp2218:45] : &:r2218_5, m2218_8 -# 2218| v2218_10(void) = Call[vector] : func:r2218_4, this:r2218_1, 0:r2218_9 -# 2218| m2218_11(unknown) = ^CallSideEffect : ~m2218_3 -# 2218| m2218_12(unknown) = Chi : total:m2218_3, partial:m2218_11 -# 2218| m2218_13(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2218_1 -# 2218| m2218_14(unknown) = Chi : total:m2218_12, partial:m2218_13 -# 2218| r2218_15(glval) = CopyValue : r2218_5 -# 2218| r2218_16(glval) = FunctionAddress[~ClassWithDestructor] : -# 2218| v2218_17(void) = Call[~ClassWithDestructor] : func:r2218_16, this:r2218_15 -# 2218| m2218_18(unknown) = ^CallSideEffect : ~m2218_14 -# 2218| m2218_19(unknown) = Chi : total:m2218_14, partial:m2218_18 -# 2218| v2218_20(void) = ^IndirectReadSideEffect[-1] : &:r2218_15, m2218_8 -# 2218| m2218_21(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2218_15 -# 2218| m2218_22(ClassWithDestructor) = Chi : total:m2218_8, partial:m2218_21 -# 2218| r2218_23(glval &>) = VariableAddress[(__range)] : -# 2218| r2218_24(glval>) = VariableAddress[ys] : -# 2218| r2218_25(vector &) = CopyValue : r2218_24 -# 2218| m2218_26(vector &) = Store[(__range)] : &:r2218_23, r2218_25 -# 2218| r2218_27(glval>) = VariableAddress[(__begin)] : -# 2218| r2218_28(glval &>) = VariableAddress[(__range)] : -# 2218| r2218_29(vector &) = Load[(__range)] : &:r2218_28, m2218_26 -#-----| r0_18(glval>) = CopyValue : r2218_29 +# 2216| Block 10 +# 2216| r2216_74(glval>) = VariableAddress[ys] : +# 2216| r2216_75(glval) = FunctionAddress[~vector] : +# 2216| v2216_76(void) = Call[~vector] : func:r2216_75, this:r2216_74 +# 2216| m2216_77(unknown) = ^CallSideEffect : ~m2216_50 +# 2216| m2216_78(unknown) = Chi : total:m2216_50, partial:m2216_77 +# 2216| v2216_79(void) = ^IndirectReadSideEffect[-1] : &:r2216_74, ~m2216_78 +# 2216| m2216_80(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2216_74 +# 2216| m2216_81(unknown) = Chi : total:m2216_78, partial:m2216_80 +# 2219| r2219_1(glval>) = VariableAddress[ys] : +# 2219| m2219_2(vector) = Uninitialized[ys] : &:r2219_1 +# 2219| m2219_3(unknown) = Chi : total:m2216_81, partial:m2219_2 +# 2219| r2219_4(glval) = FunctionAddress[vector] : +# 2219| r2219_5(glval) = VariableAddress[#temp2219:45] : +# 2219| r2219_6(glval) = VariableAddress[x] : +# 2219| r2219_7(ClassWithDestructor) = Load[x] : &:r2219_6, m2215_8 +# 2219| m2219_8(ClassWithDestructor) = Store[#temp2219:45] : &:r2219_5, r2219_7 +# 2219| r2219_9(ClassWithDestructor) = Load[#temp2219:45] : &:r2219_5, m2219_8 +# 2219| v2219_10(void) = Call[vector] : func:r2219_4, this:r2219_1, 0:r2219_9 +# 2219| m2219_11(unknown) = ^CallSideEffect : ~m2219_3 +# 2219| m2219_12(unknown) = Chi : total:m2219_3, partial:m2219_11 +# 2219| m2219_13(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2219_1 +# 2219| m2219_14(unknown) = Chi : total:m2219_12, partial:m2219_13 +# 2219| r2219_15(glval) = CopyValue : r2219_5 +# 2219| r2219_16(glval) = FunctionAddress[~ClassWithDestructor] : +# 2219| v2219_17(void) = Call[~ClassWithDestructor] : func:r2219_16, this:r2219_15 +# 2219| m2219_18(unknown) = ^CallSideEffect : ~m2219_14 +# 2219| m2219_19(unknown) = Chi : total:m2219_14, partial:m2219_18 +# 2219| v2219_20(void) = ^IndirectReadSideEffect[-1] : &:r2219_15, m2219_8 +# 2219| m2219_21(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2219_15 +# 2219| m2219_22(ClassWithDestructor) = Chi : total:m2219_8, partial:m2219_21 +# 2219| r2219_23(glval &>) = VariableAddress[(__range)] : +# 2219| r2219_24(glval>) = VariableAddress[ys] : +# 2219| r2219_25(vector &) = CopyValue : r2219_24 +# 2219| m2219_26(vector &) = Store[(__range)] : &:r2219_23, r2219_25 +# 2219| r2219_27(glval>) = VariableAddress[(__begin)] : +# 2219| r2219_28(glval &>) = VariableAddress[(__range)] : +# 2219| r2219_29(vector &) = Load[(__range)] : &:r2219_28, m2219_26 +#-----| r0_18(glval>) = CopyValue : r2219_29 #-----| r0_19(glval>) = Convert : r0_18 -# 2218| r2218_30(glval) = FunctionAddress[begin] : -# 2218| r2218_31(iterator) = Call[begin] : func:r2218_30, this:r0_19 -#-----| v0_20(void) = ^IndirectReadSideEffect[-1] : &:r0_19, ~m2218_19 -# 2218| m2218_32(iterator) = Store[(__begin)] : &:r2218_27, r2218_31 -# 2218| r2218_33(glval>) = VariableAddress[(__end)] : -# 2218| r2218_34(glval &>) = VariableAddress[(__range)] : -# 2218| r2218_35(vector &) = Load[(__range)] : &:r2218_34, m2218_26 -#-----| r0_21(glval>) = CopyValue : r2218_35 +# 2219| r2219_30(glval) = FunctionAddress[begin] : +# 2219| r2219_31(iterator) = Call[begin] : func:r2219_30, this:r0_19 +#-----| v0_20(void) = ^IndirectReadSideEffect[-1] : &:r0_19, ~m2219_19 +# 2219| m2219_32(iterator) = Store[(__begin)] : &:r2219_27, r2219_31 +# 2219| r2219_33(glval>) = VariableAddress[(__end)] : +# 2219| r2219_34(glval &>) = VariableAddress[(__range)] : +# 2219| r2219_35(vector &) = Load[(__range)] : &:r2219_34, m2219_26 +#-----| r0_21(glval>) = CopyValue : r2219_35 #-----| r0_22(glval>) = Convert : r0_21 -# 2218| r2218_36(glval) = FunctionAddress[end] : -# 2218| r2218_37(iterator) = Call[end] : func:r2218_36, this:r0_22 -#-----| v0_23(void) = ^IndirectReadSideEffect[-1] : &:r0_22, ~m2218_19 -# 2218| m2218_38(iterator) = Store[(__end)] : &:r2218_33, r2218_37 -# 2218| m2218_39(unknown) = Chi : total:m2218_19, partial:m2218_38 +# 2219| r2219_36(glval) = FunctionAddress[end] : +# 2219| r2219_37(iterator) = Call[end] : func:r2219_36, this:r0_22 +#-----| v0_23(void) = ^IndirectReadSideEffect[-1] : &:r0_22, ~m2219_19 +# 2219| m2219_38(iterator) = Store[(__end)] : &:r2219_33, r2219_37 +# 2219| m2219_39(unknown) = Chi : total:m2219_19, partial:m2219_38 #-----| Goto -> Block 11 -# 2218| Block 11 -# 2218| m2218_40(iterator) = Phi : from 10:m2218_32, from 12:m2218_58 -# 2218| m2218_41(unknown) = Phi : from 10:~m2218_39, from 12:~m2218_63 -# 2218| r2218_42(glval>) = VariableAddress[(__begin)] : -#-----| r0_24(glval>) = Convert : r2218_42 -# 2218| r2218_43(glval) = FunctionAddress[operator!=] : +# 2219| Block 11 +# 2219| m2219_40(iterator) = Phi : from 10:m2219_32, from 12:m2219_58 +# 2219| m2219_41(unknown) = Phi : from 10:~m2219_39, from 12:~m2219_63 +# 2219| r2219_42(glval>) = VariableAddress[(__begin)] : +#-----| r0_24(glval>) = Convert : r2219_42 +# 2219| r2219_43(glval) = FunctionAddress[operator!=] : #-----| r0_25(glval>) = VariableAddress[#temp0:0] : #-----| m0_26(iterator) = Uninitialized[#temp0:0] : &:r0_25 -#-----| m0_27(unknown) = Chi : total:m2218_41, partial:m0_26 -# 2218| r2218_44(glval) = FunctionAddress[iterator] : -# 2218| r2218_45(glval>) = VariableAddress[(__end)] : -#-----| r0_28(glval>) = Convert : r2218_45 +#-----| m0_27(unknown) = Chi : total:m2219_41, partial:m0_26 +# 2219| r2219_44(glval) = FunctionAddress[iterator] : +# 2219| r2219_45(glval>) = VariableAddress[(__end)] : +#-----| r0_28(glval>) = Convert : r2219_45 #-----| r0_29(iterator &) = CopyValue : r0_28 -# 2218| v2218_46(void) = Call[iterator] : func:r2218_44, this:r0_25, 0:r0_29 -# 2218| m2218_47(unknown) = ^CallSideEffect : ~m0_27 -# 2218| m2218_48(unknown) = Chi : total:m0_27, partial:m2218_47 -#-----| v0_30(void) = ^BufferReadSideEffect[0] : &:r0_29, ~m2218_48 -# 2218| m2218_49(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_25 -# 2218| m2218_50(unknown) = Chi : total:m2218_48, partial:m2218_49 -#-----| r0_31(iterator) = Load[#temp0:0] : &:r0_25, ~m2218_50 -# 2218| r2218_51(bool) = Call[operator!=] : func:r2218_43, this:r0_24, 0:r0_31 -#-----| v0_32(void) = ^IndirectReadSideEffect[-1] : &:r0_24, m2218_40 -# 2218| v2218_52(void) = ConditionalBranch : r2218_51 +# 2219| v2219_46(void) = Call[iterator] : func:r2219_44, this:r0_25, 0:r0_29 +# 2219| m2219_47(unknown) = ^CallSideEffect : ~m0_27 +# 2219| m2219_48(unknown) = Chi : total:m0_27, partial:m2219_47 +#-----| v0_30(void) = ^BufferReadSideEffect[0] : &:r0_29, ~m2219_48 +# 2219| m2219_49(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_25 +# 2219| m2219_50(unknown) = Chi : total:m2219_48, partial:m2219_49 +#-----| r0_31(iterator) = Load[#temp0:0] : &:r0_25, ~m2219_50 +# 2219| r2219_51(bool) = Call[operator!=] : func:r2219_43, this:r0_24, 0:r0_31 +#-----| v0_32(void) = ^IndirectReadSideEffect[-1] : &:r0_24, m2219_40 +# 2219| v2219_52(void) = ConditionalBranch : r2219_51 #-----| False -> Block 15 #-----| True -> Block 13 -# 2218| Block 12 -# 2218| r2218_53(glval>) = VariableAddress[(__begin)] : -# 2218| r2218_54(glval) = FunctionAddress[operator++] : -# 2218| r2218_55(iterator &) = Call[operator++] : func:r2218_54, this:r2218_53 -# 2218| v2218_56(void) = ^IndirectReadSideEffect[-1] : &:r2218_53, m2218_40 -# 2218| m2218_57(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2218_53 -# 2218| m2218_58(iterator) = Chi : total:m2218_40, partial:m2218_57 -# 2218| r2218_59(glval) = VariableAddress[y] : -# 2218| r2218_60(glval) = FunctionAddress[~ClassWithDestructor] : -# 2218| v2218_61(void) = Call[~ClassWithDestructor] : func:r2218_60, this:r2218_59 -# 2218| m2218_62(unknown) = ^CallSideEffect : ~m2220_5 -# 2218| m2218_63(unknown) = Chi : total:m2220_5, partial:m2218_62 -# 2218| v2218_64(void) = ^IndirectReadSideEffect[-1] : &:r2218_59, m2220_8 -# 2218| m2218_65(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2218_59 -# 2218| m2218_66(ClassWithDestructor) = Chi : total:m2220_8, partial:m2218_65 -# 2218| r2218_67(glval>) = CopyValue : r2218_55 +# 2219| Block 12 +# 2219| r2219_53(glval>) = VariableAddress[(__begin)] : +# 2219| r2219_54(glval) = FunctionAddress[operator++] : +# 2219| r2219_55(iterator &) = Call[operator++] : func:r2219_54, this:r2219_53 +# 2219| v2219_56(void) = ^IndirectReadSideEffect[-1] : &:r2219_53, m2219_40 +# 2219| m2219_57(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2219_53 +# 2219| m2219_58(iterator) = Chi : total:m2219_40, partial:m2219_57 +# 2219| r2219_59(glval) = VariableAddress[y] : +# 2219| r2219_60(glval) = FunctionAddress[~ClassWithDestructor] : +# 2219| v2219_61(void) = Call[~ClassWithDestructor] : func:r2219_60, this:r2219_59 +# 2219| m2219_62(unknown) = ^CallSideEffect : ~m2221_5 +# 2219| m2219_63(unknown) = Chi : total:m2221_5, partial:m2219_62 +# 2219| v2219_64(void) = ^IndirectReadSideEffect[-1] : &:r2219_59, m2221_8 +# 2219| m2219_65(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2219_59 +# 2219| m2219_66(ClassWithDestructor) = Chi : total:m2221_8, partial:m2219_65 +# 2219| r2219_67(glval>) = CopyValue : r2219_55 #-----| Goto (back edge) -> Block 11 -# 2218| Block 13 -# 2218| r2218_68(glval) = VariableAddress[y] : -# 2218| r2218_69(glval>) = VariableAddress[(__begin)] : -#-----| r0_33(glval>) = Convert : r2218_69 -# 2218| r2218_70(glval) = FunctionAddress[operator*] : -# 2218| r2218_71(ClassWithDestructor &) = Call[operator*] : func:r2218_70, this:r0_33 -#-----| v0_34(void) = ^IndirectReadSideEffect[-1] : &:r0_33, m2218_40 -# 2218| r2218_72(ClassWithDestructor) = Load[?] : &:r2218_71, ~m2218_50 -# 2218| m2218_73(ClassWithDestructor) = Store[y] : &:r2218_68, r2218_72 -# 2219| r2219_1(glval) = VariableAddress[y] : -# 2219| r2219_2(glval) = FunctionAddress[set_x] : -# 2219| r2219_3(char) = Constant[97] : -# 2219| v2219_4(void) = Call[set_x] : func:r2219_2, this:r2219_1, 0:r2219_3 -# 2219| m2219_5(unknown) = ^CallSideEffect : ~m2218_50 -# 2219| m2219_6(unknown) = Chi : total:m2218_50, partial:m2219_5 -# 2219| v2219_7(void) = ^IndirectReadSideEffect[-1] : &:r2219_1, m2218_73 -# 2219| m2219_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2219_1 -# 2219| m2219_9(ClassWithDestructor) = Chi : total:m2218_73, partial:m2219_8 +# 2219| Block 13 +# 2219| r2219_68(glval) = VariableAddress[y] : +# 2219| r2219_69(glval>) = VariableAddress[(__begin)] : +#-----| r0_33(glval>) = Convert : r2219_69 +# 2219| r2219_70(glval) = FunctionAddress[operator*] : +# 2219| r2219_71(ClassWithDestructor &) = Call[operator*] : func:r2219_70, this:r0_33 +#-----| v0_34(void) = ^IndirectReadSideEffect[-1] : &:r0_33, m2219_40 +# 2219| r2219_72(ClassWithDestructor) = Load[?] : &:r2219_71, ~m2219_50 +# 2219| m2219_73(ClassWithDestructor) = Store[y] : &:r2219_68, r2219_72 # 2220| r2220_1(glval) = VariableAddress[y] : -# 2220| r2220_2(glval) = FunctionAddress[get_x] : -# 2220| r2220_3(char) = Call[get_x] : func:r2220_2, this:r2220_1 -# 2220| m2220_4(unknown) = ^CallSideEffect : ~m2219_6 -# 2220| m2220_5(unknown) = Chi : total:m2219_6, partial:m2220_4 -# 2220| v2220_6(void) = ^IndirectReadSideEffect[-1] : &:r2220_1, m2219_9 -# 2220| m2220_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2220_1 -# 2220| m2220_8(ClassWithDestructor) = Chi : total:m2219_9, partial:m2220_7 -# 2220| r2220_9(int) = Convert : r2220_3 -# 2220| r2220_10(int) = Constant[98] : -# 2220| r2220_11(bool) = CompareEQ : r2220_9, r2220_10 -# 2220| v2220_12(void) = ConditionalBranch : r2220_11 +# 2220| r2220_2(glval) = FunctionAddress[set_x] : +# 2220| r2220_3(char) = Constant[97] : +# 2220| v2220_4(void) = Call[set_x] : func:r2220_2, this:r2220_1, 0:r2220_3 +# 2220| m2220_5(unknown) = ^CallSideEffect : ~m2219_50 +# 2220| m2220_6(unknown) = Chi : total:m2219_50, partial:m2220_5 +# 2220| v2220_7(void) = ^IndirectReadSideEffect[-1] : &:r2220_1, m2219_73 +# 2220| m2220_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2220_1 +# 2220| m2220_9(ClassWithDestructor) = Chi : total:m2219_73, partial:m2220_8 +# 2221| r2221_1(glval) = VariableAddress[y] : +# 2221| r2221_2(glval) = FunctionAddress[get_x] : +# 2221| r2221_3(char) = Call[get_x] : func:r2221_2, this:r2221_1 +# 2221| m2221_4(unknown) = ^CallSideEffect : ~m2220_6 +# 2221| m2221_5(unknown) = Chi : total:m2220_6, partial:m2221_4 +# 2221| v2221_6(void) = ^IndirectReadSideEffect[-1] : &:r2221_1, m2220_9 +# 2221| m2221_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2221_1 +# 2221| m2221_8(ClassWithDestructor) = Chi : total:m2220_9, partial:m2221_7 +# 2221| r2221_9(int) = Convert : r2221_3 +# 2221| r2221_10(int) = Constant[98] : +# 2221| r2221_11(bool) = CompareEQ : r2221_9, r2221_10 +# 2221| v2221_12(void) = ConditionalBranch : r2221_11 #-----| False -> Block 12 #-----| True -> Block 14 -# 2221| Block 14 -# 2221| v2221_1(void) = NoOp : -# 2218| r2218_74(glval) = VariableAddress[y] : -# 2218| r2218_75(glval) = FunctionAddress[~ClassWithDestructor] : -# 2218| v2218_76(void) = Call[~ClassWithDestructor] : func:r2218_75, this:r2218_74 -# 2218| m2218_77(unknown) = ^CallSideEffect : ~m2220_5 -# 2218| m2218_78(unknown) = Chi : total:m2220_5, partial:m2218_77 -# 2218| v2218_79(void) = ^IndirectReadSideEffect[-1] : &:r2218_74, m2220_8 -# 2218| m2218_80(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2218_74 -# 2218| m2218_81(ClassWithDestructor) = Chi : total:m2220_8, partial:m2218_80 -# 2218| r2218_82(glval>) = VariableAddress[ys] : -# 2218| r2218_83(glval) = FunctionAddress[~vector] : -# 2218| v2218_84(void) = Call[~vector] : func:r2218_83, this:r2218_82 -# 2218| m2218_85(unknown) = ^CallSideEffect : ~m2218_78 -# 2218| m2218_86(unknown) = Chi : total:m2218_78, partial:m2218_85 -# 2218| v2218_87(void) = ^IndirectReadSideEffect[-1] : &:r2218_82, ~m2218_86 -# 2218| m2218_88(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2218_82 -# 2218| m2218_89(unknown) = Chi : total:m2218_86, partial:m2218_88 -# 2233| r2233_1(glval) = VariableAddress[x] : -# 2233| r2233_2(glval) = FunctionAddress[~ClassWithDestructor] : -# 2233| v2233_3(void) = Call[~ClassWithDestructor] : func:r2233_2, this:r2233_1 -# 2233| m2233_4(unknown) = ^CallSideEffect : ~m2218_89 -# 2233| m2233_5(unknown) = Chi : total:m2218_89, partial:m2233_4 -# 2233| v2233_6(void) = ^IndirectReadSideEffect[-1] : &:r2233_1, m2214_8 -# 2233| m2233_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2233_1 -# 2233| m2233_8(ClassWithDestructor) = Chi : total:m2214_8, partial:m2233_7 +# 2222| Block 14 +# 2222| v2222_1(void) = NoOp : +# 2219| r2219_74(glval) = VariableAddress[y] : +# 2219| r2219_75(glval) = FunctionAddress[~ClassWithDestructor] : +# 2219| v2219_76(void) = Call[~ClassWithDestructor] : func:r2219_75, this:r2219_74 +# 2219| m2219_77(unknown) = ^CallSideEffect : ~m2221_5 +# 2219| m2219_78(unknown) = Chi : total:m2221_5, partial:m2219_77 +# 2219| v2219_79(void) = ^IndirectReadSideEffect[-1] : &:r2219_74, m2221_8 +# 2219| m2219_80(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2219_74 +# 2219| m2219_81(ClassWithDestructor) = Chi : total:m2221_8, partial:m2219_80 +# 2219| r2219_82(glval>) = VariableAddress[ys] : +# 2219| r2219_83(glval) = FunctionAddress[~vector] : +# 2219| v2219_84(void) = Call[~vector] : func:r2219_83, this:r2219_82 +# 2219| m2219_85(unknown) = ^CallSideEffect : ~m2219_78 +# 2219| m2219_86(unknown) = Chi : total:m2219_78, partial:m2219_85 +# 2219| v2219_87(void) = ^IndirectReadSideEffect[-1] : &:r2219_82, ~m2219_86 +# 2219| m2219_88(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2219_82 +# 2219| m2219_89(unknown) = Chi : total:m2219_86, partial:m2219_88 +# 2234| r2234_1(glval) = VariableAddress[x] : +# 2234| r2234_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2234| v2234_3(void) = Call[~ClassWithDestructor] : func:r2234_2, this:r2234_1 +# 2234| m2234_4(unknown) = ^CallSideEffect : ~m2219_89 +# 2234| m2234_5(unknown) = Chi : total:m2219_89, partial:m2234_4 +# 2234| v2234_6(void) = ^IndirectReadSideEffect[-1] : &:r2234_1, m2215_8 +# 2234| m2234_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2234_1 +# 2234| m2234_8(ClassWithDestructor) = Chi : total:m2215_8, partial:m2234_7 #-----| Goto -> Block 1 -# 2218| Block 15 -# 2218| r2218_90(glval>) = VariableAddress[ys] : -# 2218| r2218_91(glval) = FunctionAddress[~vector] : -# 2218| v2218_92(void) = Call[~vector] : func:r2218_91, this:r2218_90 -# 2218| m2218_93(unknown) = ^CallSideEffect : ~m2218_50 -# 2218| m2218_94(unknown) = Chi : total:m2218_50, partial:m2218_93 -# 2218| v2218_95(void) = ^IndirectReadSideEffect[-1] : &:r2218_90, ~m2218_94 -# 2218| m2218_96(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2218_90 -# 2218| m2218_97(unknown) = Chi : total:m2218_94, partial:m2218_96 -# 2224| r2224_1(glval>) = VariableAddress[ys] : -# 2224| m2224_2(vector) = Uninitialized[ys] : &:r2224_1 -# 2224| m2224_3(unknown) = Chi : total:m2218_97, partial:m2224_2 -# 2224| r2224_4(glval) = FunctionAddress[vector] : -# 2224| r2224_5(int) = Constant[1] : -# 2224| v2224_6(void) = Call[vector] : func:r2224_4, this:r2224_1, 0:r2224_5 -# 2224| m2224_7(unknown) = ^CallSideEffect : ~m2224_3 -# 2224| m2224_8(unknown) = Chi : total:m2224_3, partial:m2224_7 -# 2224| m2224_9(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2224_1 -# 2224| m2224_10(unknown) = Chi : total:m2224_8, partial:m2224_9 -# 2224| r2224_11(glval &>) = VariableAddress[(__range)] : -# 2224| r2224_12(glval>) = VariableAddress[ys] : -# 2224| r2224_13(vector &) = CopyValue : r2224_12 -# 2224| m2224_14(vector &) = Store[(__range)] : &:r2224_11, r2224_13 -# 2224| r2224_15(glval>) = VariableAddress[(__begin)] : -# 2224| r2224_16(glval &>) = VariableAddress[(__range)] : -# 2224| r2224_17(vector &) = Load[(__range)] : &:r2224_16, m2224_14 -#-----| r0_35(glval>) = CopyValue : r2224_17 +# 2219| Block 15 +# 2219| r2219_90(glval>) = VariableAddress[ys] : +# 2219| r2219_91(glval) = FunctionAddress[~vector] : +# 2219| v2219_92(void) = Call[~vector] : func:r2219_91, this:r2219_90 +# 2219| m2219_93(unknown) = ^CallSideEffect : ~m2219_50 +# 2219| m2219_94(unknown) = Chi : total:m2219_50, partial:m2219_93 +# 2219| v2219_95(void) = ^IndirectReadSideEffect[-1] : &:r2219_90, ~m2219_94 +# 2219| m2219_96(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2219_90 +# 2219| m2219_97(unknown) = Chi : total:m2219_94, partial:m2219_96 +# 2225| r2225_1(glval>) = VariableAddress[ys] : +# 2225| m2225_2(vector) = Uninitialized[ys] : &:r2225_1 +# 2225| m2225_3(unknown) = Chi : total:m2219_97, partial:m2225_2 +# 2225| r2225_4(glval) = FunctionAddress[vector] : +# 2225| r2225_5(int) = Constant[1] : +# 2225| v2225_6(void) = Call[vector] : func:r2225_4, this:r2225_1, 0:r2225_5 +# 2225| m2225_7(unknown) = ^CallSideEffect : ~m2225_3 +# 2225| m2225_8(unknown) = Chi : total:m2225_3, partial:m2225_7 +# 2225| m2225_9(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2225_1 +# 2225| m2225_10(unknown) = Chi : total:m2225_8, partial:m2225_9 +# 2225| r2225_11(glval &>) = VariableAddress[(__range)] : +# 2225| r2225_12(glval>) = VariableAddress[ys] : +# 2225| r2225_13(vector &) = CopyValue : r2225_12 +# 2225| m2225_14(vector &) = Store[(__range)] : &:r2225_11, r2225_13 +# 2225| r2225_15(glval>) = VariableAddress[(__begin)] : +# 2225| r2225_16(glval &>) = VariableAddress[(__range)] : +# 2225| r2225_17(vector &) = Load[(__range)] : &:r2225_16, m2225_14 +#-----| r0_35(glval>) = CopyValue : r2225_17 #-----| r0_36(glval>) = Convert : r0_35 -# 2224| r2224_18(glval) = FunctionAddress[begin] : -# 2224| r2224_19(iterator) = Call[begin] : func:r2224_18, this:r0_36 -#-----| v0_37(void) = ^IndirectReadSideEffect[-1] : &:r0_36, ~m2224_10 -# 2224| m2224_20(iterator) = Store[(__begin)] : &:r2224_15, r2224_19 -# 2224| r2224_21(glval>) = VariableAddress[(__end)] : -# 2224| r2224_22(glval &>) = VariableAddress[(__range)] : -# 2224| r2224_23(vector &) = Load[(__range)] : &:r2224_22, m2224_14 -#-----| r0_38(glval>) = CopyValue : r2224_23 +# 2225| r2225_18(glval) = FunctionAddress[begin] : +# 2225| r2225_19(iterator) = Call[begin] : func:r2225_18, this:r0_36 +#-----| v0_37(void) = ^IndirectReadSideEffect[-1] : &:r0_36, ~m2225_10 +# 2225| m2225_20(iterator) = Store[(__begin)] : &:r2225_15, r2225_19 +# 2225| r2225_21(glval>) = VariableAddress[(__end)] : +# 2225| r2225_22(glval &>) = VariableAddress[(__range)] : +# 2225| r2225_23(vector &) = Load[(__range)] : &:r2225_22, m2225_14 +#-----| r0_38(glval>) = CopyValue : r2225_23 #-----| r0_39(glval>) = Convert : r0_38 -# 2224| r2224_24(glval) = FunctionAddress[end] : -# 2224| r2224_25(iterator) = Call[end] : func:r2224_24, this:r0_39 -#-----| v0_40(void) = ^IndirectReadSideEffect[-1] : &:r0_39, ~m2224_10 -# 2224| m2224_26(iterator) = Store[(__end)] : &:r2224_21, r2224_25 -# 2224| m2224_27(unknown) = Chi : total:m2224_10, partial:m2224_26 +# 2225| r2225_24(glval) = FunctionAddress[end] : +# 2225| r2225_25(iterator) = Call[end] : func:r2225_24, this:r0_39 +#-----| v0_40(void) = ^IndirectReadSideEffect[-1] : &:r0_39, ~m2225_10 +# 2225| m2225_26(iterator) = Store[(__end)] : &:r2225_21, r2225_25 +# 2225| m2225_27(unknown) = Chi : total:m2225_10, partial:m2225_26 #-----| Goto -> Block 16 -# 2224| Block 16 -# 2224| m2224_28(iterator) = Phi : from 15:m2224_20, from 17:m2224_46 -# 2224| m2224_29(unknown) = Phi : from 15:~m2224_27, from 17:~m2224_38 -# 2224| r2224_30(glval>) = VariableAddress[(__begin)] : -#-----| r0_41(glval>) = Convert : r2224_30 -# 2224| r2224_31(glval) = FunctionAddress[operator!=] : +# 2225| Block 16 +# 2225| m2225_28(iterator) = Phi : from 15:m2225_20, from 17:m2225_46 +# 2225| m2225_29(unknown) = Phi : from 15:~m2225_27, from 17:~m2225_38 +# 2225| r2225_30(glval>) = VariableAddress[(__begin)] : +#-----| r0_41(glval>) = Convert : r2225_30 +# 2225| r2225_31(glval) = FunctionAddress[operator!=] : #-----| r0_42(glval>) = VariableAddress[#temp0:0] : #-----| m0_43(iterator) = Uninitialized[#temp0:0] : &:r0_42 -#-----| m0_44(unknown) = Chi : total:m2224_29, partial:m0_43 -# 2224| r2224_32(glval) = FunctionAddress[iterator] : -# 2224| r2224_33(glval>) = VariableAddress[(__end)] : -#-----| r0_45(glval>) = Convert : r2224_33 +#-----| m0_44(unknown) = Chi : total:m2225_29, partial:m0_43 +# 2225| r2225_32(glval) = FunctionAddress[iterator] : +# 2225| r2225_33(glval>) = VariableAddress[(__end)] : +#-----| r0_45(glval>) = Convert : r2225_33 #-----| r0_46(iterator &) = CopyValue : r0_45 -# 2224| v2224_34(void) = Call[iterator] : func:r2224_32, this:r0_42, 0:r0_46 -# 2224| m2224_35(unknown) = ^CallSideEffect : ~m0_44 -# 2224| m2224_36(unknown) = Chi : total:m0_44, partial:m2224_35 -#-----| v0_47(void) = ^BufferReadSideEffect[0] : &:r0_46, ~m2224_36 -# 2224| m2224_37(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_42 -# 2224| m2224_38(unknown) = Chi : total:m2224_36, partial:m2224_37 -#-----| r0_48(iterator) = Load[#temp0:0] : &:r0_42, ~m2224_38 -# 2224| r2224_39(bool) = Call[operator!=] : func:r2224_31, this:r0_41, 0:r0_48 -#-----| v0_49(void) = ^IndirectReadSideEffect[-1] : &:r0_41, m2224_28 -# 2224| v2224_40(void) = ConditionalBranch : r2224_39 +# 2225| v2225_34(void) = Call[iterator] : func:r2225_32, this:r0_42, 0:r0_46 +# 2225| m2225_35(unknown) = ^CallSideEffect : ~m0_44 +# 2225| m2225_36(unknown) = Chi : total:m0_44, partial:m2225_35 +#-----| v0_47(void) = ^BufferReadSideEffect[0] : &:r0_46, ~m2225_36 +# 2225| m2225_37(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_42 +# 2225| m2225_38(unknown) = Chi : total:m2225_36, partial:m2225_37 +#-----| r0_48(iterator) = Load[#temp0:0] : &:r0_42, ~m2225_38 +# 2225| r2225_39(bool) = Call[operator!=] : func:r2225_31, this:r0_41, 0:r0_48 +#-----| v0_49(void) = ^IndirectReadSideEffect[-1] : &:r0_41, m2225_28 +# 2225| v2225_40(void) = ConditionalBranch : r2225_39 #-----| False -> Block 20 #-----| True -> Block 18 -# 2224| Block 17 -# 2224| r2224_41(glval>) = VariableAddress[(__begin)] : -# 2224| r2224_42(glval) = FunctionAddress[operator++] : -# 2224| r2224_43(iterator &) = Call[operator++] : func:r2224_42, this:r2224_41 -# 2224| v2224_44(void) = ^IndirectReadSideEffect[-1] : &:r2224_41, m2224_28 -# 2224| m2224_45(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2224_41 -# 2224| m2224_46(iterator) = Chi : total:m2224_28, partial:m2224_45 -# 2224| r2224_47(glval>) = CopyValue : r2224_43 +# 2225| Block 17 +# 2225| r2225_41(glval>) = VariableAddress[(__begin)] : +# 2225| r2225_42(glval) = FunctionAddress[operator++] : +# 2225| r2225_43(iterator &) = Call[operator++] : func:r2225_42, this:r2225_41 +# 2225| v2225_44(void) = ^IndirectReadSideEffect[-1] : &:r2225_41, m2225_28 +# 2225| m2225_45(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2225_41 +# 2225| m2225_46(iterator) = Chi : total:m2225_28, partial:m2225_45 +# 2225| r2225_47(glval>) = CopyValue : r2225_43 #-----| Goto (back edge) -> Block 16 -# 2224| Block 18 -# 2224| r2224_48(glval) = VariableAddress[y] : -# 2224| r2224_49(glval>) = VariableAddress[(__begin)] : -#-----| r0_50(glval>) = Convert : r2224_49 -# 2224| r2224_50(glval) = FunctionAddress[operator*] : -# 2224| r2224_51(int &) = Call[operator*] : func:r2224_50, this:r0_50 -#-----| v0_51(void) = ^IndirectReadSideEffect[-1] : &:r0_50, m2224_28 -# 2224| r2224_52(int) = Load[?] : &:r2224_51, ~m2224_38 -# 2224| m2224_53(int) = Store[y] : &:r2224_48, r2224_52 -# 2225| r2225_1(glval) = VariableAddress[y] : -# 2225| r2225_2(int) = Load[y] : &:r2225_1, m2224_53 -# 2225| r2225_3(int) = Constant[1] : -# 2225| r2225_4(bool) = CompareEQ : r2225_2, r2225_3 -# 2225| v2225_5(void) = ConditionalBranch : r2225_4 +# 2225| Block 18 +# 2225| r2225_48(glval) = VariableAddress[y] : +# 2225| r2225_49(glval>) = VariableAddress[(__begin)] : +#-----| r0_50(glval>) = Convert : r2225_49 +# 2225| r2225_50(glval) = FunctionAddress[operator*] : +# 2225| r2225_51(int &) = Call[operator*] : func:r2225_50, this:r0_50 +#-----| v0_51(void) = ^IndirectReadSideEffect[-1] : &:r0_50, m2225_28 +# 2225| r2225_52(int) = Load[?] : &:r2225_51, ~m2225_38 +# 2225| m2225_53(int) = Store[y] : &:r2225_48, r2225_52 +# 2226| r2226_1(glval) = VariableAddress[y] : +# 2226| r2226_2(int) = Load[y] : &:r2226_1, m2225_53 +# 2226| r2226_3(int) = Constant[1] : +# 2226| r2226_4(bool) = CompareEQ : r2226_2, r2226_3 +# 2226| v2226_5(void) = ConditionalBranch : r2226_4 #-----| False -> Block 17 #-----| True -> Block 19 -# 2226| Block 19 -# 2226| v2226_1(void) = NoOp : -# 2224| r2224_54(glval>) = VariableAddress[ys] : -# 2224| r2224_55(glval) = FunctionAddress[~vector] : -# 2224| v2224_56(void) = Call[~vector] : func:r2224_55, this:r2224_54 -# 2224| m2224_57(unknown) = ^CallSideEffect : ~m2224_38 -# 2224| m2224_58(unknown) = Chi : total:m2224_38, partial:m2224_57 -# 2224| v2224_59(void) = ^IndirectReadSideEffect[-1] : &:r2224_54, ~m2224_58 -# 2224| m2224_60(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2224_54 -# 2224| m2224_61(unknown) = Chi : total:m2224_58, partial:m2224_60 -# 2233| r2233_9(glval) = VariableAddress[x] : -# 2233| r2233_10(glval) = FunctionAddress[~ClassWithDestructor] : -# 2233| v2233_11(void) = Call[~ClassWithDestructor] : func:r2233_10, this:r2233_9 -# 2233| m2233_12(unknown) = ^CallSideEffect : ~m2224_61 -# 2233| m2233_13(unknown) = Chi : total:m2224_61, partial:m2233_12 -# 2233| v2233_14(void) = ^IndirectReadSideEffect[-1] : &:r2233_9, m2214_8 -# 2233| m2233_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2233_9 -# 2233| m2233_16(ClassWithDestructor) = Chi : total:m2214_8, partial:m2233_15 +# 2227| Block 19 +# 2227| v2227_1(void) = NoOp : +# 2225| r2225_54(glval>) = VariableAddress[ys] : +# 2225| r2225_55(glval) = FunctionAddress[~vector] : +# 2225| v2225_56(void) = Call[~vector] : func:r2225_55, this:r2225_54 +# 2225| m2225_57(unknown) = ^CallSideEffect : ~m2225_38 +# 2225| m2225_58(unknown) = Chi : total:m2225_38, partial:m2225_57 +# 2225| v2225_59(void) = ^IndirectReadSideEffect[-1] : &:r2225_54, ~m2225_58 +# 2225| m2225_60(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2225_54 +# 2225| m2225_61(unknown) = Chi : total:m2225_58, partial:m2225_60 +# 2234| r2234_9(glval) = VariableAddress[x] : +# 2234| r2234_10(glval) = FunctionAddress[~ClassWithDestructor] : +# 2234| v2234_11(void) = Call[~ClassWithDestructor] : func:r2234_10, this:r2234_9 +# 2234| m2234_12(unknown) = ^CallSideEffect : ~m2225_61 +# 2234| m2234_13(unknown) = Chi : total:m2225_61, partial:m2234_12 +# 2234| v2234_14(void) = ^IndirectReadSideEffect[-1] : &:r2234_9, m2215_8 +# 2234| m2234_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2234_9 +# 2234| m2234_16(ClassWithDestructor) = Chi : total:m2215_8, partial:m2234_15 #-----| Goto -> Block 1 -# 2224| Block 20 -# 2224| r2224_62(glval>) = VariableAddress[ys] : -# 2224| r2224_63(glval) = FunctionAddress[~vector] : -# 2224| v2224_64(void) = Call[~vector] : func:r2224_63, this:r2224_62 -# 2224| m2224_65(unknown) = ^CallSideEffect : ~m2224_38 -# 2224| m2224_66(unknown) = Chi : total:m2224_38, partial:m2224_65 -# 2224| v2224_67(void) = ^IndirectReadSideEffect[-1] : &:r2224_62, ~m2224_66 -# 2224| m2224_68(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2224_62 -# 2224| m2224_69(unknown) = Chi : total:m2224_66, partial:m2224_68 -# 2229| r2229_1(glval>) = VariableAddress[ys] : -# 2229| m2229_2(vector) = Uninitialized[ys] : &:r2229_1 -# 2229| m2229_3(unknown) = Chi : total:m2224_69, partial:m2229_2 -# 2229| r2229_4(glval) = FunctionAddress[vector] : -# 2229| r2229_5(glval) = VariableAddress[#temp2229:45] : -# 2229| r2229_6(glval) = VariableAddress[x] : -# 2229| r2229_7(ClassWithDestructor) = Load[x] : &:r2229_6, m2214_8 -# 2229| m2229_8(ClassWithDestructor) = Store[#temp2229:45] : &:r2229_5, r2229_7 -# 2229| r2229_9(ClassWithDestructor) = Load[#temp2229:45] : &:r2229_5, m2229_8 -# 2229| v2229_10(void) = Call[vector] : func:r2229_4, this:r2229_1, 0:r2229_9 -# 2229| m2229_11(unknown) = ^CallSideEffect : ~m2229_3 -# 2229| m2229_12(unknown) = Chi : total:m2229_3, partial:m2229_11 -# 2229| m2229_13(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2229_1 -# 2229| m2229_14(unknown) = Chi : total:m2229_12, partial:m2229_13 -# 2229| r2229_15(glval) = CopyValue : r2229_5 -# 2229| r2229_16(glval) = FunctionAddress[~ClassWithDestructor] : -# 2229| v2229_17(void) = Call[~ClassWithDestructor] : func:r2229_16, this:r2229_15 -# 2229| m2229_18(unknown) = ^CallSideEffect : ~m2229_14 -# 2229| m2229_19(unknown) = Chi : total:m2229_14, partial:m2229_18 -# 2229| v2229_20(void) = ^IndirectReadSideEffect[-1] : &:r2229_15, m2229_8 -# 2229| m2229_21(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2229_15 -# 2229| m2229_22(ClassWithDestructor) = Chi : total:m2229_8, partial:m2229_21 -# 2229| r2229_23(glval &>) = VariableAddress[(__range)] : -# 2229| r2229_24(glval>) = VariableAddress[ys] : -# 2229| r2229_25(vector &) = CopyValue : r2229_24 -# 2229| m2229_26(vector &) = Store[(__range)] : &:r2229_23, r2229_25 -# 2229| r2229_27(glval>) = VariableAddress[(__begin)] : -# 2229| r2229_28(glval &>) = VariableAddress[(__range)] : -# 2229| r2229_29(vector &) = Load[(__range)] : &:r2229_28, m2229_26 -#-----| r0_52(glval>) = CopyValue : r2229_29 +# 2225| Block 20 +# 2225| r2225_62(glval>) = VariableAddress[ys] : +# 2225| r2225_63(glval) = FunctionAddress[~vector] : +# 2225| v2225_64(void) = Call[~vector] : func:r2225_63, this:r2225_62 +# 2225| m2225_65(unknown) = ^CallSideEffect : ~m2225_38 +# 2225| m2225_66(unknown) = Chi : total:m2225_38, partial:m2225_65 +# 2225| v2225_67(void) = ^IndirectReadSideEffect[-1] : &:r2225_62, ~m2225_66 +# 2225| m2225_68(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2225_62 +# 2225| m2225_69(unknown) = Chi : total:m2225_66, partial:m2225_68 +# 2230| r2230_1(glval>) = VariableAddress[ys] : +# 2230| m2230_2(vector) = Uninitialized[ys] : &:r2230_1 +# 2230| m2230_3(unknown) = Chi : total:m2225_69, partial:m2230_2 +# 2230| r2230_4(glval) = FunctionAddress[vector] : +# 2230| r2230_5(glval) = VariableAddress[#temp2230:45] : +# 2230| r2230_6(glval) = VariableAddress[x] : +# 2230| r2230_7(ClassWithDestructor) = Load[x] : &:r2230_6, m2215_8 +# 2230| m2230_8(ClassWithDestructor) = Store[#temp2230:45] : &:r2230_5, r2230_7 +# 2230| r2230_9(ClassWithDestructor) = Load[#temp2230:45] : &:r2230_5, m2230_8 +# 2230| v2230_10(void) = Call[vector] : func:r2230_4, this:r2230_1, 0:r2230_9 +# 2230| m2230_11(unknown) = ^CallSideEffect : ~m2230_3 +# 2230| m2230_12(unknown) = Chi : total:m2230_3, partial:m2230_11 +# 2230| m2230_13(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2230_1 +# 2230| m2230_14(unknown) = Chi : total:m2230_12, partial:m2230_13 +# 2230| r2230_15(glval) = CopyValue : r2230_5 +# 2230| r2230_16(glval) = FunctionAddress[~ClassWithDestructor] : +# 2230| v2230_17(void) = Call[~ClassWithDestructor] : func:r2230_16, this:r2230_15 +# 2230| m2230_18(unknown) = ^CallSideEffect : ~m2230_14 +# 2230| m2230_19(unknown) = Chi : total:m2230_14, partial:m2230_18 +# 2230| v2230_20(void) = ^IndirectReadSideEffect[-1] : &:r2230_15, m2230_8 +# 2230| m2230_21(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2230_15 +# 2230| m2230_22(ClassWithDestructor) = Chi : total:m2230_8, partial:m2230_21 +# 2230| r2230_23(glval &>) = VariableAddress[(__range)] : +# 2230| r2230_24(glval>) = VariableAddress[ys] : +# 2230| r2230_25(vector &) = CopyValue : r2230_24 +# 2230| m2230_26(vector &) = Store[(__range)] : &:r2230_23, r2230_25 +# 2230| r2230_27(glval>) = VariableAddress[(__begin)] : +# 2230| r2230_28(glval &>) = VariableAddress[(__range)] : +# 2230| r2230_29(vector &) = Load[(__range)] : &:r2230_28, m2230_26 +#-----| r0_52(glval>) = CopyValue : r2230_29 #-----| r0_53(glval>) = Convert : r0_52 -# 2229| r2229_30(glval) = FunctionAddress[begin] : -# 2229| r2229_31(iterator) = Call[begin] : func:r2229_30, this:r0_53 -#-----| v0_54(void) = ^IndirectReadSideEffect[-1] : &:r0_53, ~m2229_19 -# 2229| m2229_32(iterator) = Store[(__begin)] : &:r2229_27, r2229_31 -# 2229| r2229_33(glval>) = VariableAddress[(__end)] : -# 2229| r2229_34(glval &>) = VariableAddress[(__range)] : -# 2229| r2229_35(vector &) = Load[(__range)] : &:r2229_34, m2229_26 -#-----| r0_55(glval>) = CopyValue : r2229_35 +# 2230| r2230_30(glval) = FunctionAddress[begin] : +# 2230| r2230_31(iterator) = Call[begin] : func:r2230_30, this:r0_53 +#-----| v0_54(void) = ^IndirectReadSideEffect[-1] : &:r0_53, ~m2230_19 +# 2230| m2230_32(iterator) = Store[(__begin)] : &:r2230_27, r2230_31 +# 2230| r2230_33(glval>) = VariableAddress[(__end)] : +# 2230| r2230_34(glval &>) = VariableAddress[(__range)] : +# 2230| r2230_35(vector &) = Load[(__range)] : &:r2230_34, m2230_26 +#-----| r0_55(glval>) = CopyValue : r2230_35 #-----| r0_56(glval>) = Convert : r0_55 -# 2229| r2229_36(glval) = FunctionAddress[end] : -# 2229| r2229_37(iterator) = Call[end] : func:r2229_36, this:r0_56 -#-----| v0_57(void) = ^IndirectReadSideEffect[-1] : &:r0_56, ~m2229_19 -# 2229| m2229_38(iterator) = Store[(__end)] : &:r2229_33, r2229_37 -# 2229| m2229_39(unknown) = Chi : total:m2229_19, partial:m2229_38 +# 2230| r2230_36(glval) = FunctionAddress[end] : +# 2230| r2230_37(iterator) = Call[end] : func:r2230_36, this:r0_56 +#-----| v0_57(void) = ^IndirectReadSideEffect[-1] : &:r0_56, ~m2230_19 +# 2230| m2230_38(iterator) = Store[(__end)] : &:r2230_33, r2230_37 +# 2230| m2230_39(unknown) = Chi : total:m2230_19, partial:m2230_38 #-----| Goto -> Block 21 -# 2229| Block 21 -# 2229| m2229_40(iterator) = Phi : from 20:m2229_32, from 22:m2229_64 -# 2229| m2229_41(unknown) = Phi : from 20:~m2229_39, from 22:~m2229_69 -# 2229| r2229_42(glval>) = VariableAddress[(__begin)] : -#-----| r0_58(glval>) = Convert : r2229_42 -# 2229| r2229_43(glval) = FunctionAddress[operator!=] : +# 2230| Block 21 +# 2230| m2230_40(iterator) = Phi : from 20:m2230_32, from 22:m2230_64 +# 2230| m2230_41(unknown) = Phi : from 20:~m2230_39, from 22:~m2230_69 +# 2230| r2230_42(glval>) = VariableAddress[(__begin)] : +#-----| r0_58(glval>) = Convert : r2230_42 +# 2230| r2230_43(glval) = FunctionAddress[operator!=] : #-----| r0_59(glval>) = VariableAddress[#temp0:0] : #-----| m0_60(iterator) = Uninitialized[#temp0:0] : &:r0_59 -#-----| m0_61(unknown) = Chi : total:m2229_41, partial:m0_60 -# 2229| r2229_44(glval) = FunctionAddress[iterator] : -# 2229| r2229_45(glval>) = VariableAddress[(__end)] : -#-----| r0_62(glval>) = Convert : r2229_45 +#-----| m0_61(unknown) = Chi : total:m2230_41, partial:m0_60 +# 2230| r2230_44(glval) = FunctionAddress[iterator] : +# 2230| r2230_45(glval>) = VariableAddress[(__end)] : +#-----| r0_62(glval>) = Convert : r2230_45 #-----| r0_63(iterator &) = CopyValue : r0_62 -# 2229| v2229_46(void) = Call[iterator] : func:r2229_44, this:r0_59, 0:r0_63 -# 2229| m2229_47(unknown) = ^CallSideEffect : ~m0_61 -# 2229| m2229_48(unknown) = Chi : total:m0_61, partial:m2229_47 -#-----| v0_64(void) = ^BufferReadSideEffect[0] : &:r0_63, ~m2229_48 -# 2229| m2229_49(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_59 -# 2229| m2229_50(unknown) = Chi : total:m2229_48, partial:m2229_49 -#-----| r0_65(iterator) = Load[#temp0:0] : &:r0_59, ~m2229_50 -# 2229| r2229_51(bool) = Call[operator!=] : func:r2229_43, this:r0_58, 0:r0_65 -#-----| v0_66(void) = ^IndirectReadSideEffect[-1] : &:r0_58, m2229_40 -# 2229| v2229_52(void) = ConditionalBranch : r2229_51 +# 2230| v2230_46(void) = Call[iterator] : func:r2230_44, this:r0_59, 0:r0_63 +# 2230| m2230_47(unknown) = ^CallSideEffect : ~m0_61 +# 2230| m2230_48(unknown) = Chi : total:m0_61, partial:m2230_47 +#-----| v0_64(void) = ^BufferReadSideEffect[0] : &:r0_63, ~m2230_48 +# 2230| m2230_49(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_59 +# 2230| m2230_50(unknown) = Chi : total:m2230_48, partial:m2230_49 +#-----| r0_65(iterator) = Load[#temp0:0] : &:r0_59, ~m2230_50 +# 2230| r2230_51(bool) = Call[operator!=] : func:r2230_43, this:r0_58, 0:r0_65 +#-----| v0_66(void) = ^IndirectReadSideEffect[-1] : &:r0_58, m2230_40 +# 2230| v2230_52(void) = ConditionalBranch : r2230_51 #-----| False -> Block 23 #-----| True -> Block 22 -# 2229| Block 22 -# 2229| r2229_53(glval) = VariableAddress[y] : -# 2229| r2229_54(glval>) = VariableAddress[(__begin)] : -#-----| r0_67(glval>) = Convert : r2229_54 -# 2229| r2229_55(glval) = FunctionAddress[operator*] : -# 2229| r2229_56(ClassWithDestructor &) = Call[operator*] : func:r2229_55, this:r0_67 -#-----| v0_68(void) = ^IndirectReadSideEffect[-1] : &:r0_67, m2229_40 -# 2229| r2229_57(ClassWithDestructor) = Load[?] : &:r2229_56, ~m2229_50 -# 2229| m2229_58(ClassWithDestructor) = Store[y] : &:r2229_53, r2229_57 -# 2230| r2230_1(glval) = VariableAddress[z1] : -# 2230| m2230_2(ClassWithDestructor) = Uninitialized[z1] : &:r2230_1 -# 2230| r2230_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2230| v2230_4(void) = Call[ClassWithDestructor] : func:r2230_3, this:r2230_1 -# 2230| m2230_5(unknown) = ^CallSideEffect : ~m2229_50 -# 2230| m2230_6(unknown) = Chi : total:m2229_50, partial:m2230_5 -# 2230| m2230_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2230_1 -# 2230| m2230_8(ClassWithDestructor) = Chi : total:m2230_2, partial:m2230_7 -# 2231| r2231_1(glval) = VariableAddress[z2] : -# 2231| m2231_2(ClassWithDestructor) = Uninitialized[z2] : &:r2231_1 +# 2230| Block 22 +# 2230| r2230_53(glval) = VariableAddress[y] : +# 2230| r2230_54(glval>) = VariableAddress[(__begin)] : +#-----| r0_67(glval>) = Convert : r2230_54 +# 2230| r2230_55(glval) = FunctionAddress[operator*] : +# 2230| r2230_56(ClassWithDestructor &) = Call[operator*] : func:r2230_55, this:r0_67 +#-----| v0_68(void) = ^IndirectReadSideEffect[-1] : &:r0_67, m2230_40 +# 2230| r2230_57(ClassWithDestructor) = Load[?] : &:r2230_56, ~m2230_50 +# 2230| m2230_58(ClassWithDestructor) = Store[y] : &:r2230_53, r2230_57 +# 2231| r2231_1(glval) = VariableAddress[z1] : +# 2231| m2231_2(ClassWithDestructor) = Uninitialized[z1] : &:r2231_1 # 2231| r2231_3(glval) = FunctionAddress[ClassWithDestructor] : # 2231| v2231_4(void) = Call[ClassWithDestructor] : func:r2231_3, this:r2231_1 -# 2231| m2231_5(unknown) = ^CallSideEffect : ~m2230_6 -# 2231| m2231_6(unknown) = Chi : total:m2230_6, partial:m2231_5 +# 2231| m2231_5(unknown) = ^CallSideEffect : ~m2230_50 +# 2231| m2231_6(unknown) = Chi : total:m2230_50, partial:m2231_5 # 2231| m2231_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2231_1 # 2231| m2231_8(ClassWithDestructor) = Chi : total:m2231_2, partial:m2231_7 # 2232| r2232_1(glval) = VariableAddress[z2] : -# 2232| r2232_2(glval) = FunctionAddress[~ClassWithDestructor] : -# 2232| v2232_3(void) = Call[~ClassWithDestructor] : func:r2232_2, this:r2232_1 -# 2232| m2232_4(unknown) = ^CallSideEffect : ~m2231_6 -# 2232| m2232_5(unknown) = Chi : total:m2231_6, partial:m2232_4 -# 2232| v2232_6(void) = ^IndirectReadSideEffect[-1] : &:r2232_1, m2231_8 +# 2232| m2232_2(ClassWithDestructor) = Uninitialized[z2] : &:r2232_1 +# 2232| r2232_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2232| v2232_4(void) = Call[ClassWithDestructor] : func:r2232_3, this:r2232_1 +# 2232| m2232_5(unknown) = ^CallSideEffect : ~m2231_6 +# 2232| m2232_6(unknown) = Chi : total:m2231_6, partial:m2232_5 # 2232| m2232_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2232_1 -# 2232| m2232_8(ClassWithDestructor) = Chi : total:m2231_8, partial:m2232_7 -# 2232| r2232_9(glval) = VariableAddress[z1] : -# 2232| r2232_10(glval) = FunctionAddress[~ClassWithDestructor] : -# 2232| v2232_11(void) = Call[~ClassWithDestructor] : func:r2232_10, this:r2232_9 -# 2232| m2232_12(unknown) = ^CallSideEffect : ~m2232_5 -# 2232| m2232_13(unknown) = Chi : total:m2232_5, partial:m2232_12 -# 2232| v2232_14(void) = ^IndirectReadSideEffect[-1] : &:r2232_9, m2230_8 -# 2232| m2232_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2232_9 -# 2232| m2232_16(ClassWithDestructor) = Chi : total:m2230_8, partial:m2232_15 -# 2229| r2229_59(glval>) = VariableAddress[(__begin)] : -# 2229| r2229_60(glval) = FunctionAddress[operator++] : -# 2229| r2229_61(iterator &) = Call[operator++] : func:r2229_60, this:r2229_59 -# 2229| v2229_62(void) = ^IndirectReadSideEffect[-1] : &:r2229_59, m2229_40 -# 2229| m2229_63(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2229_59 -# 2229| m2229_64(iterator) = Chi : total:m2229_40, partial:m2229_63 -# 2229| r2229_65(glval) = VariableAddress[y] : -# 2229| r2229_66(glval) = FunctionAddress[~ClassWithDestructor] : -# 2229| v2229_67(void) = Call[~ClassWithDestructor] : func:r2229_66, this:r2229_65 -# 2229| m2229_68(unknown) = ^CallSideEffect : ~m2232_13 -# 2229| m2229_69(unknown) = Chi : total:m2232_13, partial:m2229_68 -# 2229| v2229_70(void) = ^IndirectReadSideEffect[-1] : &:r2229_65, m2229_58 -# 2229| m2229_71(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2229_65 -# 2229| m2229_72(ClassWithDestructor) = Chi : total:m2229_58, partial:m2229_71 -# 2229| r2229_73(glval>) = CopyValue : r2229_61 +# 2232| m2232_8(ClassWithDestructor) = Chi : total:m2232_2, partial:m2232_7 +# 2233| r2233_1(glval) = VariableAddress[z2] : +# 2233| r2233_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2233| v2233_3(void) = Call[~ClassWithDestructor] : func:r2233_2, this:r2233_1 +# 2233| m2233_4(unknown) = ^CallSideEffect : ~m2232_6 +# 2233| m2233_5(unknown) = Chi : total:m2232_6, partial:m2233_4 +# 2233| v2233_6(void) = ^IndirectReadSideEffect[-1] : &:r2233_1, m2232_8 +# 2233| m2233_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2233_1 +# 2233| m2233_8(ClassWithDestructor) = Chi : total:m2232_8, partial:m2233_7 +# 2233| r2233_9(glval) = VariableAddress[z1] : +# 2233| r2233_10(glval) = FunctionAddress[~ClassWithDestructor] : +# 2233| v2233_11(void) = Call[~ClassWithDestructor] : func:r2233_10, this:r2233_9 +# 2233| m2233_12(unknown) = ^CallSideEffect : ~m2233_5 +# 2233| m2233_13(unknown) = Chi : total:m2233_5, partial:m2233_12 +# 2233| v2233_14(void) = ^IndirectReadSideEffect[-1] : &:r2233_9, m2231_8 +# 2233| m2233_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2233_9 +# 2233| m2233_16(ClassWithDestructor) = Chi : total:m2231_8, partial:m2233_15 +# 2230| r2230_59(glval>) = VariableAddress[(__begin)] : +# 2230| r2230_60(glval) = FunctionAddress[operator++] : +# 2230| r2230_61(iterator &) = Call[operator++] : func:r2230_60, this:r2230_59 +# 2230| v2230_62(void) = ^IndirectReadSideEffect[-1] : &:r2230_59, m2230_40 +# 2230| m2230_63(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2230_59 +# 2230| m2230_64(iterator) = Chi : total:m2230_40, partial:m2230_63 +# 2230| r2230_65(glval) = VariableAddress[y] : +# 2230| r2230_66(glval) = FunctionAddress[~ClassWithDestructor] : +# 2230| v2230_67(void) = Call[~ClassWithDestructor] : func:r2230_66, this:r2230_65 +# 2230| m2230_68(unknown) = ^CallSideEffect : ~m2233_13 +# 2230| m2230_69(unknown) = Chi : total:m2233_13, partial:m2230_68 +# 2230| v2230_70(void) = ^IndirectReadSideEffect[-1] : &:r2230_65, m2230_58 +# 2230| m2230_71(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2230_65 +# 2230| m2230_72(ClassWithDestructor) = Chi : total:m2230_58, partial:m2230_71 +# 2230| r2230_73(glval>) = CopyValue : r2230_61 #-----| Goto (back edge) -> Block 21 -# 2229| Block 23 -# 2229| r2229_74(glval>) = VariableAddress[ys] : -# 2229| r2229_75(glval) = FunctionAddress[~vector] : -# 2229| v2229_76(void) = Call[~vector] : func:r2229_75, this:r2229_74 -# 2229| m2229_77(unknown) = ^CallSideEffect : ~m2229_50 -# 2229| m2229_78(unknown) = Chi : total:m2229_50, partial:m2229_77 -# 2229| v2229_79(void) = ^IndirectReadSideEffect[-1] : &:r2229_74, ~m2229_78 -# 2229| m2229_80(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2229_74 -# 2229| m2229_81(unknown) = Chi : total:m2229_78, partial:m2229_80 -# 2233| v2233_17(void) = NoOp : -# 2233| r2233_18(glval) = VariableAddress[x] : -# 2233| r2233_19(glval) = FunctionAddress[~ClassWithDestructor] : -# 2233| v2233_20(void) = Call[~ClassWithDestructor] : func:r2233_19, this:r2233_18 -# 2233| m2233_21(unknown) = ^CallSideEffect : ~m2229_81 -# 2233| m2233_22(unknown) = Chi : total:m2229_81, partial:m2233_21 -# 2233| v2233_23(void) = ^IndirectReadSideEffect[-1] : &:r2233_18, m2214_8 -# 2233| m2233_24(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2233_18 -# 2233| m2233_25(ClassWithDestructor) = Chi : total:m2214_8, partial:m2233_24 +# 2230| Block 23 +# 2230| r2230_74(glval>) = VariableAddress[ys] : +# 2230| r2230_75(glval) = FunctionAddress[~vector] : +# 2230| v2230_76(void) = Call[~vector] : func:r2230_75, this:r2230_74 +# 2230| m2230_77(unknown) = ^CallSideEffect : ~m2230_50 +# 2230| m2230_78(unknown) = Chi : total:m2230_50, partial:m2230_77 +# 2230| v2230_79(void) = ^IndirectReadSideEffect[-1] : &:r2230_74, ~m2230_78 +# 2230| m2230_80(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2230_74 +# 2230| m2230_81(unknown) = Chi : total:m2230_78, partial:m2230_80 +# 2234| v2234_17(void) = NoOp : +# 2234| r2234_18(glval) = VariableAddress[x] : +# 2234| r2234_19(glval) = FunctionAddress[~ClassWithDestructor] : +# 2234| v2234_20(void) = Call[~ClassWithDestructor] : func:r2234_19, this:r2234_18 +# 2234| m2234_21(unknown) = ^CallSideEffect : ~m2230_81 +# 2234| m2234_22(unknown) = Chi : total:m2230_81, partial:m2234_21 +# 2234| v2234_23(void) = ^IndirectReadSideEffect[-1] : &:r2234_18, m2215_8 +# 2234| m2234_24(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2234_18 +# 2234| m2234_25(ClassWithDestructor) = Chi : total:m2215_8, partial:m2234_24 #-----| Goto -> Block 1 -# 2198| Block 24 -# 2198| v2198_13(void) = Unreached : - -# 2235| void static_variable_with_destructor_1() -# 2235| Block 0 -# 2235| v2235_1(void) = EnterFunction : -# 2235| m2235_2(unknown) = AliasedDefinition : -# 2235| m2235_3(unknown) = InitializeNonLocal : -# 2235| m2235_4(unknown) = Chi : total:m2235_2, partial:m2235_3 -# 2236| r2236_1(glval) = VariableAddress[a] : -# 2236| m2236_2(ClassWithDestructor) = Uninitialized[a] : &:r2236_1 -# 2236| r2236_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2236| v2236_4(void) = Call[ClassWithDestructor] : func:r2236_3, this:r2236_1 -# 2236| m2236_5(unknown) = ^CallSideEffect : ~m2235_4 -# 2236| m2236_6(unknown) = Chi : total:m2235_4, partial:m2236_5 -# 2236| m2236_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2236_1 -# 2236| m2236_8(ClassWithDestructor) = Chi : total:m2236_2, partial:m2236_7 -# 2237| r2237_1(glval) = VariableAddress[b#init] : -# 2237| r2237_2(bool) = Load[b#init] : &:r2237_1, ~m2236_6 -# 2237| v2237_3(void) = ConditionalBranch : r2237_2 +# 2199| Block 24 +# 2199| v2199_13(void) = Unreached : + +# 2236| void static_variable_with_destructor_1() +# 2236| Block 0 +# 2236| v2236_1(void) = EnterFunction : +# 2236| m2236_2(unknown) = AliasedDefinition : +# 2236| m2236_3(unknown) = InitializeNonLocal : +# 2236| m2236_4(unknown) = Chi : total:m2236_2, partial:m2236_3 +# 2237| r2237_1(glval) = VariableAddress[a] : +# 2237| m2237_2(ClassWithDestructor) = Uninitialized[a] : &:r2237_1 +# 2237| r2237_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2237| v2237_4(void) = Call[ClassWithDestructor] : func:r2237_3, this:r2237_1 +# 2237| m2237_5(unknown) = ^CallSideEffect : ~m2236_4 +# 2237| m2237_6(unknown) = Chi : total:m2236_4, partial:m2237_5 +# 2237| m2237_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2237_1 +# 2237| m2237_8(ClassWithDestructor) = Chi : total:m2237_2, partial:m2237_7 +# 2238| r2238_1(glval) = VariableAddress[b#init] : +# 2238| r2238_2(bool) = Load[b#init] : &:r2238_1, ~m2237_6 +# 2238| v2238_3(void) = ConditionalBranch : r2238_2 #-----| False -> Block 1 #-----| True -> Block 2 -# 2237| Block 1 -# 2237| r2237_4(glval) = VariableAddress[b] : +# 2238| Block 1 +# 2238| r2238_4(glval) = VariableAddress[b] : #-----| r0_1(glval) = FunctionAddress[ClassWithDestructor] : -#-----| v0_2(void) = Call[ClassWithDestructor] : func:r0_1, this:r2237_4 -#-----| m0_3(unknown) = ^CallSideEffect : ~m2236_6 -#-----| m0_4(unknown) = Chi : total:m2236_6, partial:m0_3 -#-----| m0_5(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2237_4 +#-----| v0_2(void) = Call[ClassWithDestructor] : func:r0_1, this:r2238_4 +#-----| m0_3(unknown) = ^CallSideEffect : ~m2237_6 +#-----| m0_4(unknown) = Chi : total:m2237_6, partial:m0_3 +#-----| m0_5(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2238_4 #-----| m0_6(unknown) = Chi : total:m0_4, partial:m0_5 -# 2237| r2237_5(bool) = Constant[1] : -# 2237| m2237_6(bool) = Store[b#init] : &:r2237_1, r2237_5 -# 2237| m2237_7(unknown) = Chi : total:m0_6, partial:m2237_6 +# 2238| r2238_5(bool) = Constant[1] : +# 2238| m2238_6(bool) = Store[b#init] : &:r2238_1, r2238_5 +# 2238| m2238_7(unknown) = Chi : total:m0_6, partial:m2238_6 #-----| Goto -> Block 2 -# 2238| Block 2 -# 2238| m2238_1(unknown) = Phi : from 0:~m2236_6, from 1:~m2237_7 -# 2238| v2238_2(void) = NoOp : -# 2238| r2238_3(glval) = VariableAddress[a] : -# 2238| r2238_4(glval) = FunctionAddress[~ClassWithDestructor] : -# 2238| v2238_5(void) = Call[~ClassWithDestructor] : func:r2238_4, this:r2238_3 -# 2238| m2238_6(unknown) = ^CallSideEffect : ~m2238_1 -# 2238| m2238_7(unknown) = Chi : total:m2238_1, partial:m2238_6 -# 2238| v2238_8(void) = ^IndirectReadSideEffect[-1] : &:r2238_3, m2236_8 -# 2238| m2238_9(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2238_3 -# 2238| m2238_10(ClassWithDestructor) = Chi : total:m2236_8, partial:m2238_9 -# 2235| v2235_5(void) = ReturnVoid : -# 2235| v2235_6(void) = AliasedUse : ~m2238_7 -# 2235| v2235_7(void) = ExitFunction : - -# 2240| void static_variable_with_destructor_2() -# 2240| Block 0 -# 2240| v2240_1(void) = EnterFunction : -# 2240| m2240_2(unknown) = AliasedDefinition : -# 2240| m2240_3(unknown) = InitializeNonLocal : -# 2240| m2240_4(unknown) = Chi : total:m2240_2, partial:m2240_3 -# 2241| r2241_1(glval) = VariableAddress[a#init] : -# 2241| r2241_2(bool) = Load[a#init] : &:r2241_1, ~m2240_3 -# 2241| v2241_3(void) = ConditionalBranch : r2241_2 +# 2239| Block 2 +# 2239| m2239_1(unknown) = Phi : from 0:~m2237_6, from 1:~m2238_7 +# 2239| v2239_2(void) = NoOp : +# 2239| r2239_3(glval) = VariableAddress[a] : +# 2239| r2239_4(glval) = FunctionAddress[~ClassWithDestructor] : +# 2239| v2239_5(void) = Call[~ClassWithDestructor] : func:r2239_4, this:r2239_3 +# 2239| m2239_6(unknown) = ^CallSideEffect : ~m2239_1 +# 2239| m2239_7(unknown) = Chi : total:m2239_1, partial:m2239_6 +# 2239| v2239_8(void) = ^IndirectReadSideEffect[-1] : &:r2239_3, m2237_8 +# 2239| m2239_9(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2239_3 +# 2239| m2239_10(ClassWithDestructor) = Chi : total:m2237_8, partial:m2239_9 +# 2236| v2236_5(void) = ReturnVoid : +# 2236| v2236_6(void) = AliasedUse : ~m2239_7 +# 2236| v2236_7(void) = ExitFunction : + +# 2241| void static_variable_with_destructor_2() +# 2241| Block 0 +# 2241| v2241_1(void) = EnterFunction : +# 2241| m2241_2(unknown) = AliasedDefinition : +# 2241| m2241_3(unknown) = InitializeNonLocal : +# 2241| m2241_4(unknown) = Chi : total:m2241_2, partial:m2241_3 +# 2242| r2242_1(glval) = VariableAddress[a#init] : +# 2242| r2242_2(bool) = Load[a#init] : &:r2242_1, ~m2241_3 +# 2242| v2242_3(void) = ConditionalBranch : r2242_2 #-----| False -> Block 1 #-----| True -> Block 2 -# 2241| Block 1 -# 2241| r2241_4(glval) = VariableAddress[a] : +# 2242| Block 1 +# 2242| r2242_4(glval) = VariableAddress[a] : #-----| r0_1(glval) = FunctionAddress[ClassWithDestructor] : -#-----| v0_2(void) = Call[ClassWithDestructor] : func:r0_1, this:r2241_4 -#-----| m0_3(unknown) = ^CallSideEffect : ~m2240_4 -#-----| m0_4(unknown) = Chi : total:m2240_4, partial:m0_3 -#-----| m0_5(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2241_4 +#-----| v0_2(void) = Call[ClassWithDestructor] : func:r0_1, this:r2242_4 +#-----| m0_3(unknown) = ^CallSideEffect : ~m2241_4 +#-----| m0_4(unknown) = Chi : total:m2241_4, partial:m0_3 +#-----| m0_5(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2242_4 #-----| m0_6(unknown) = Chi : total:m0_4, partial:m0_5 -# 2241| r2241_5(bool) = Constant[1] : -# 2241| m2241_6(bool) = Store[a#init] : &:r2241_1, r2241_5 -# 2241| m2241_7(unknown) = Chi : total:m0_6, partial:m2241_6 +# 2242| r2242_5(bool) = Constant[1] : +# 2242| m2242_6(bool) = Store[a#init] : &:r2242_1, r2242_5 +# 2242| m2242_7(unknown) = Chi : total:m0_6, partial:m2242_6 #-----| Goto -> Block 2 -# 2242| Block 2 -# 2242| m2242_1(unknown) = Phi : from 0:~m2240_4, from 1:~m2241_7 -# 2242| r2242_2(glval) = VariableAddress[b] : -# 2242| m2242_3(ClassWithDestructor) = Uninitialized[b] : &:r2242_2 -# 2242| r2242_4(glval) = FunctionAddress[ClassWithDestructor] : -# 2242| v2242_5(void) = Call[ClassWithDestructor] : func:r2242_4, this:r2242_2 -# 2242| m2242_6(unknown) = ^CallSideEffect : ~m2242_1 -# 2242| m2242_7(unknown) = Chi : total:m2242_1, partial:m2242_6 -# 2242| m2242_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2242_2 -# 2242| m2242_9(ClassWithDestructor) = Chi : total:m2242_3, partial:m2242_8 -# 2243| v2243_1(void) = NoOp : +# 2243| Block 2 +# 2243| m2243_1(unknown) = Phi : from 0:~m2241_4, from 1:~m2242_7 # 2243| r2243_2(glval) = VariableAddress[b] : -# 2243| r2243_3(glval) = FunctionAddress[~ClassWithDestructor] : -# 2243| v2243_4(void) = Call[~ClassWithDestructor] : func:r2243_3, this:r2243_2 -# 2243| m2243_5(unknown) = ^CallSideEffect : ~m2242_7 -# 2243| m2243_6(unknown) = Chi : total:m2242_7, partial:m2243_5 -# 2243| v2243_7(void) = ^IndirectReadSideEffect[-1] : &:r2243_2, m2242_9 +# 2243| m2243_3(ClassWithDestructor) = Uninitialized[b] : &:r2243_2 +# 2243| r2243_4(glval) = FunctionAddress[ClassWithDestructor] : +# 2243| v2243_5(void) = Call[ClassWithDestructor] : func:r2243_4, this:r2243_2 +# 2243| m2243_6(unknown) = ^CallSideEffect : ~m2243_1 +# 2243| m2243_7(unknown) = Chi : total:m2243_1, partial:m2243_6 # 2243| m2243_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2243_2 -# 2243| m2243_9(ClassWithDestructor) = Chi : total:m2242_9, partial:m2243_8 -# 2240| v2240_5(void) = ReturnVoid : -# 2240| v2240_6(void) = AliasedUse : ~m2243_6 -# 2240| v2240_7(void) = ExitFunction : - -# 2245| void static_variable_with_destructor_3() -# 2245| Block 0 -# 2245| v2245_1(void) = EnterFunction : -# 2245| m2245_2(unknown) = AliasedDefinition : -# 2245| m2245_3(unknown) = InitializeNonLocal : -# 2245| m2245_4(unknown) = Chi : total:m2245_2, partial:m2245_3 -# 2246| r2246_1(glval) = VariableAddress[a] : -# 2246| m2246_2(ClassWithDestructor) = Uninitialized[a] : &:r2246_1 -# 2246| r2246_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2246| v2246_4(void) = Call[ClassWithDestructor] : func:r2246_3, this:r2246_1 -# 2246| m2246_5(unknown) = ^CallSideEffect : ~m2245_4 -# 2246| m2246_6(unknown) = Chi : total:m2245_4, partial:m2246_5 -# 2246| m2246_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2246_1 -# 2246| m2246_8(ClassWithDestructor) = Chi : total:m2246_2, partial:m2246_7 -# 2247| r2247_1(glval) = VariableAddress[b] : -# 2247| m2247_2(ClassWithDestructor) = Uninitialized[b] : &:r2247_1 +# 2243| m2243_9(ClassWithDestructor) = Chi : total:m2243_3, partial:m2243_8 +# 2244| v2244_1(void) = NoOp : +# 2244| r2244_2(glval) = VariableAddress[b] : +# 2244| r2244_3(glval) = FunctionAddress[~ClassWithDestructor] : +# 2244| v2244_4(void) = Call[~ClassWithDestructor] : func:r2244_3, this:r2244_2 +# 2244| m2244_5(unknown) = ^CallSideEffect : ~m2243_7 +# 2244| m2244_6(unknown) = Chi : total:m2243_7, partial:m2244_5 +# 2244| v2244_7(void) = ^IndirectReadSideEffect[-1] : &:r2244_2, m2243_9 +# 2244| m2244_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2244_2 +# 2244| m2244_9(ClassWithDestructor) = Chi : total:m2243_9, partial:m2244_8 +# 2241| v2241_5(void) = ReturnVoid : +# 2241| v2241_6(void) = AliasedUse : ~m2244_6 +# 2241| v2241_7(void) = ExitFunction : + +# 2246| void static_variable_with_destructor_3() +# 2246| Block 0 +# 2246| v2246_1(void) = EnterFunction : +# 2246| m2246_2(unknown) = AliasedDefinition : +# 2246| m2246_3(unknown) = InitializeNonLocal : +# 2246| m2246_4(unknown) = Chi : total:m2246_2, partial:m2246_3 +# 2247| r2247_1(glval) = VariableAddress[a] : +# 2247| m2247_2(ClassWithDestructor) = Uninitialized[a] : &:r2247_1 # 2247| r2247_3(glval) = FunctionAddress[ClassWithDestructor] : # 2247| v2247_4(void) = Call[ClassWithDestructor] : func:r2247_3, this:r2247_1 -# 2247| m2247_5(unknown) = ^CallSideEffect : ~m2246_6 -# 2247| m2247_6(unknown) = Chi : total:m2246_6, partial:m2247_5 +# 2247| m2247_5(unknown) = ^CallSideEffect : ~m2246_4 +# 2247| m2247_6(unknown) = Chi : total:m2246_4, partial:m2247_5 # 2247| m2247_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2247_1 # 2247| m2247_8(ClassWithDestructor) = Chi : total:m2247_2, partial:m2247_7 -# 2248| r2248_1(glval) = VariableAddress[c#init] : -# 2248| r2248_2(bool) = Load[c#init] : &:r2248_1, ~m2247_6 -# 2248| v2248_3(void) = ConditionalBranch : r2248_2 +# 2248| r2248_1(glval) = VariableAddress[b] : +# 2248| m2248_2(ClassWithDestructor) = Uninitialized[b] : &:r2248_1 +# 2248| r2248_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2248| v2248_4(void) = Call[ClassWithDestructor] : func:r2248_3, this:r2248_1 +# 2248| m2248_5(unknown) = ^CallSideEffect : ~m2247_6 +# 2248| m2248_6(unknown) = Chi : total:m2247_6, partial:m2248_5 +# 2248| m2248_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2248_1 +# 2248| m2248_8(ClassWithDestructor) = Chi : total:m2248_2, partial:m2248_7 +# 2249| r2249_1(glval) = VariableAddress[c#init] : +# 2249| r2249_2(bool) = Load[c#init] : &:r2249_1, ~m2248_6 +# 2249| v2249_3(void) = ConditionalBranch : r2249_2 #-----| False -> Block 1 #-----| True -> Block 2 -# 2248| Block 1 -# 2248| r2248_4(glval) = VariableAddress[c] : +# 2249| Block 1 +# 2249| r2249_4(glval) = VariableAddress[c] : #-----| r0_1(glval) = FunctionAddress[ClassWithDestructor] : -#-----| v0_2(void) = Call[ClassWithDestructor] : func:r0_1, this:r2248_4 -#-----| m0_3(unknown) = ^CallSideEffect : ~m2247_6 -#-----| m0_4(unknown) = Chi : total:m2247_6, partial:m0_3 -#-----| m0_5(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2248_4 +#-----| v0_2(void) = Call[ClassWithDestructor] : func:r0_1, this:r2249_4 +#-----| m0_3(unknown) = ^CallSideEffect : ~m2248_6 +#-----| m0_4(unknown) = Chi : total:m2248_6, partial:m0_3 +#-----| m0_5(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2249_4 #-----| m0_6(unknown) = Chi : total:m0_4, partial:m0_5 -# 2248| r2248_5(bool) = Constant[1] : -# 2248| m2248_6(bool) = Store[c#init] : &:r2248_1, r2248_5 -# 2248| m2248_7(unknown) = Chi : total:m0_6, partial:m2248_6 +# 2249| r2249_5(bool) = Constant[1] : +# 2249| m2249_6(bool) = Store[c#init] : &:r2249_1, r2249_5 +# 2249| m2249_7(unknown) = Chi : total:m0_6, partial:m2249_6 #-----| Goto -> Block 2 -# 2249| Block 2 -# 2249| m2249_1(unknown) = Phi : from 0:~m2247_6, from 1:~m2248_7 -# 2249| v2249_2(void) = NoOp : -# 2249| r2249_3(glval) = VariableAddress[b] : -# 2249| r2249_4(glval) = FunctionAddress[~ClassWithDestructor] : -# 2249| v2249_5(void) = Call[~ClassWithDestructor] : func:r2249_4, this:r2249_3 -# 2249| m2249_6(unknown) = ^CallSideEffect : ~m2249_1 -# 2249| m2249_7(unknown) = Chi : total:m2249_1, partial:m2249_6 -# 2249| v2249_8(void) = ^IndirectReadSideEffect[-1] : &:r2249_3, m2247_8 -# 2249| m2249_9(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2249_3 -# 2249| m2249_10(ClassWithDestructor) = Chi : total:m2247_8, partial:m2249_9 -# 2249| r2249_11(glval) = VariableAddress[a] : -# 2249| r2249_12(glval) = FunctionAddress[~ClassWithDestructor] : -# 2249| v2249_13(void) = Call[~ClassWithDestructor] : func:r2249_12, this:r2249_11 -# 2249| m2249_14(unknown) = ^CallSideEffect : ~m2249_7 -# 2249| m2249_15(unknown) = Chi : total:m2249_7, partial:m2249_14 -# 2249| v2249_16(void) = ^IndirectReadSideEffect[-1] : &:r2249_11, m2246_8 -# 2249| m2249_17(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2249_11 -# 2249| m2249_18(ClassWithDestructor) = Chi : total:m2246_8, partial:m2249_17 -# 2245| v2245_5(void) = ReturnVoid : -# 2245| v2245_6(void) = AliasedUse : ~m2249_15 -# 2245| v2245_7(void) = ExitFunction : - -# 2251| ClassWithDestructor global_class_with_destructor -# 2251| Block 0 -# 2251| v2251_1(void) = EnterFunction : -# 2251| m2251_2(unknown) = AliasedDefinition : -# 2251| r2251_3(glval) = VariableAddress[global_class_with_destructor] : -# 2251| r2251_4(glval) = FunctionAddress[ClassWithDestructor] : -# 2251| v2251_5(void) = Call[ClassWithDestructor] : func:r2251_4, this:r2251_3 -# 2251| m2251_6(unknown) = ^CallSideEffect : ~m2251_2 -# 2251| m2251_7(unknown) = Chi : total:m2251_2, partial:m2251_6 -# 2251| m2251_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2251_3 -# 2251| m2251_9(unknown) = Chi : total:m2251_7, partial:m2251_8 -# 2251| v2251_10(void) = ReturnVoid : -# 2251| v2251_11(void) = AliasedUse : ~m2251_9 -# 2251| v2251_12(void) = ExitFunction : - -# 2255| ClassWithDestructor& vacuous_destructor_call::get(ClassWithDestructor&) -# 2255| Block 0 -# 2255| v2255_1(void) = EnterFunction : -# 2255| m2255_2(unknown) = AliasedDefinition : -# 2255| m2255_3(unknown) = InitializeNonLocal : -# 2255| m2255_4(unknown) = Chi : total:m2255_2, partial:m2255_3 -# 2255| r2255_5(glval) = VariableAddress[t] : -# 2255| m2255_6(ClassWithDestructor &) = InitializeParameter[t] : &:r2255_5 -# 2255| r2255_7(ClassWithDestructor &) = Load[t] : &:r2255_5, m2255_6 -# 2255| m2255_8(unknown) = InitializeIndirection[t] : &:r2255_7 -# 2255| r2255_9(glval) = VariableAddress[#return] : -# 2255| r2255_10(glval) = VariableAddress[t] : -# 2255| r2255_11(ClassWithDestructor &) = Load[t] : &:r2255_10, m2255_6 -# 2255| r2255_12(glval) = CopyValue : r2255_11 -# 2255| r2255_13(ClassWithDestructor &) = CopyValue : r2255_12 -# 2255| m2255_14(ClassWithDestructor &) = Store[#return] : &:r2255_9, r2255_13 -# 2255| v2255_15(void) = ReturnIndirection[t] : &:r2255_7, m2255_8 -# 2255| r2255_16(glval) = VariableAddress[#return] : -# 2255| v2255_17(void) = ReturnValue : &:r2255_16, m2255_14 -# 2255| v2255_18(void) = AliasedUse : m2255_3 -# 2255| v2255_19(void) = ExitFunction : - -# 2255| int& vacuous_destructor_call::get(int&) -# 2255| Block 0 -# 2255| v2255_1(void) = EnterFunction : -# 2255| m2255_2(unknown) = AliasedDefinition : -# 2255| m2255_3(unknown) = InitializeNonLocal : -# 2255| m2255_4(unknown) = Chi : total:m2255_2, partial:m2255_3 -# 2255| r2255_5(glval) = VariableAddress[t] : -# 2255| m2255_6(int &) = InitializeParameter[t] : &:r2255_5 -# 2255| r2255_7(int &) = Load[t] : &:r2255_5, m2255_6 -# 2255| m2255_8(unknown) = InitializeIndirection[t] : &:r2255_7 -# 2255| r2255_9(glval) = VariableAddress[#return] : -# 2255| r2255_10(glval) = VariableAddress[t] : -# 2255| r2255_11(int &) = Load[t] : &:r2255_10, m2255_6 -# 2255| r2255_12(glval) = CopyValue : r2255_11 -# 2255| r2255_13(int &) = CopyValue : r2255_12 -# 2255| m2255_14(int &) = Store[#return] : &:r2255_9, r2255_13 -# 2255| v2255_15(void) = ReturnIndirection[t] : &:r2255_7, m2255_8 -# 2255| r2255_16(glval) = VariableAddress[#return] : -# 2255| v2255_17(void) = ReturnValue : &:r2255_16, m2255_14 -# 2255| v2255_18(void) = AliasedUse : m2255_3 -# 2255| v2255_19(void) = ExitFunction : - -# 2258| void vacuous_destructor_call::call_destructor(ClassWithDestructor&) -# 2258| Block 0 -# 2258| v2258_1(void) = EnterFunction : -# 2258| m2258_2(unknown) = AliasedDefinition : -# 2258| m2258_3(unknown) = InitializeNonLocal : -# 2258| m2258_4(unknown) = Chi : total:m2258_2, partial:m2258_3 -# 2258| r2258_5(glval) = VariableAddress[t] : -# 2258| m2258_6(ClassWithDestructor &) = InitializeParameter[t] : &:r2258_5 -# 2258| r2258_7(ClassWithDestructor &) = Load[t] : &:r2258_5, m2258_6 -# 2258| m2258_8(unknown) = InitializeIndirection[t] : &:r2258_7 -# 2259| r2259_1(glval) = FunctionAddress[get] : -# 2259| r2259_2(glval) = VariableAddress[t] : -# 2259| r2259_3(ClassWithDestructor &) = Load[t] : &:r2259_2, m2258_6 -# 2259| r2259_4(glval) = CopyValue : r2259_3 -# 2259| r2259_5(ClassWithDestructor &) = CopyValue : r2259_4 -# 2259| r2259_6(ClassWithDestructor &) = Call[get] : func:r2259_1, 0:r2259_5 -# 2259| m2259_7(unknown) = ^CallSideEffect : ~m2258_4 -# 2259| m2259_8(unknown) = Chi : total:m2258_4, partial:m2259_7 -# 2259| v2259_9(void) = ^BufferReadSideEffect[0] : &:r2259_5, ~m2258_8 -# 2259| m2259_10(unknown) = ^BufferMayWriteSideEffect[0] : &:r2259_5 -# 2259| m2259_11(unknown) = Chi : total:m2258_8, partial:m2259_10 -# 2259| r2259_12(glval) = CopyValue : r2259_6 -# 2259| r2259_13(glval) = FunctionAddress[~ClassWithDestructor] : -# 2259| v2259_14(void) = Call[~ClassWithDestructor] : func:r2259_13 -# 2259| m2259_15(unknown) = ^CallSideEffect : ~m2259_8 -# 2259| m2259_16(unknown) = Chi : total:m2259_8, partial:m2259_15 -# 2259| v2259_17(void) = ^IndirectReadSideEffect[-1] : &:r2259_12, ~m2259_11 -# 2259| m2259_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2259_12 -# 2259| m2259_19(unknown) = Chi : total:m2259_11, partial:m2259_18 -# 2260| v2260_1(void) = NoOp : -# 2258| v2258_9(void) = ReturnIndirection[t] : &:r2258_7, m2259_19 -# 2258| v2258_10(void) = ReturnVoid : -# 2258| v2258_11(void) = AliasedUse : ~m2259_16 -# 2258| v2258_12(void) = ExitFunction : - -# 2258| void vacuous_destructor_call::call_destructor(int&) -# 2258| Block 0 -# 2258| v2258_1(void) = EnterFunction : -# 2258| m2258_2(unknown) = AliasedDefinition : -# 2258| m2258_3(unknown) = InitializeNonLocal : -# 2258| m2258_4(unknown) = Chi : total:m2258_2, partial:m2258_3 -# 2258| r2258_5(glval) = VariableAddress[t] : -# 2258| m2258_6(int &) = InitializeParameter[t] : &:r2258_5 -# 2258| r2258_7(int &) = Load[t] : &:r2258_5, m2258_6 -# 2258| m2258_8(unknown) = InitializeIndirection[t] : &:r2258_7 -# 2259| r2259_1(glval) = FunctionAddress[get] : -# 2259| r2259_2(glval) = VariableAddress[t] : -# 2259| r2259_3(int &) = Load[t] : &:r2259_2, m2258_6 -# 2259| r2259_4(glval) = CopyValue : r2259_3 -# 2259| r2259_5(int &) = CopyValue : r2259_4 -# 2259| r2259_6(int &) = Call[get] : func:r2259_1, 0:r2259_5 -# 2259| m2259_7(unknown) = ^CallSideEffect : ~m2258_4 -# 2259| m2259_8(unknown) = Chi : total:m2258_4, partial:m2259_7 -# 2259| v2259_9(void) = ^BufferReadSideEffect[0] : &:r2259_5, ~m2258_8 -# 2259| m2259_10(unknown) = ^BufferMayWriteSideEffect[0] : &:r2259_5 -# 2259| m2259_11(unknown) = Chi : total:m2258_8, partial:m2259_10 -# 2259| r2259_12(glval) = CopyValue : r2259_6 -# 2260| v2260_1(void) = NoOp : -# 2258| v2258_9(void) = ReturnIndirection[t] : &:r2258_7, m2259_11 -# 2258| v2258_10(void) = ReturnVoid : -# 2258| v2258_11(void) = AliasedUse : ~m2259_8 -# 2258| v2258_12(void) = ExitFunction : - -# 2262| void vacuous_destructor_call::non_vacuous_destructor_call() -# 2262| Block 0 -# 2262| v2262_1(void) = EnterFunction : -# 2262| m2262_2(unknown) = AliasedDefinition : -# 2262| m2262_3(unknown) = InitializeNonLocal : -# 2262| m2262_4(unknown) = Chi : total:m2262_2, partial:m2262_3 -# 2263| r2263_1(glval) = VariableAddress[c] : -# 2263| m2263_2(ClassWithDestructor) = Uninitialized[c] : &:r2263_1 -# 2263| r2263_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2263| v2263_4(void) = Call[ClassWithDestructor] : func:r2263_3, this:r2263_1 -# 2263| m2263_5(unknown) = ^CallSideEffect : ~m2262_4 -# 2263| m2263_6(unknown) = Chi : total:m2262_4, partial:m2263_5 -# 2263| m2263_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2263_1 -# 2263| m2263_8(ClassWithDestructor) = Chi : total:m2263_2, partial:m2263_7 -# 2264| r2264_1(glval) = FunctionAddress[call_destructor] : -# 2264| r2264_2(glval) = VariableAddress[c] : -# 2264| r2264_3(ClassWithDestructor &) = CopyValue : r2264_2 -# 2264| v2264_4(void) = Call[call_destructor] : func:r2264_1, 0:r2264_3 -# 2264| m2264_5(unknown) = ^CallSideEffect : ~m2263_6 -# 2264| m2264_6(unknown) = Chi : total:m2263_6, partial:m2264_5 -# 2264| v2264_7(void) = ^BufferReadSideEffect[0] : &:r2264_3, ~m2263_8 -# 2264| m2264_8(unknown) = ^BufferMayWriteSideEffect[0] : &:r2264_3 -# 2264| m2264_9(ClassWithDestructor) = Chi : total:m2263_8, partial:m2264_8 -# 2265| v2265_1(void) = NoOp : +# 2250| Block 2 +# 2250| m2250_1(unknown) = Phi : from 0:~m2248_6, from 1:~m2249_7 +# 2250| v2250_2(void) = NoOp : +# 2250| r2250_3(glval) = VariableAddress[b] : +# 2250| r2250_4(glval) = FunctionAddress[~ClassWithDestructor] : +# 2250| v2250_5(void) = Call[~ClassWithDestructor] : func:r2250_4, this:r2250_3 +# 2250| m2250_6(unknown) = ^CallSideEffect : ~m2250_1 +# 2250| m2250_7(unknown) = Chi : total:m2250_1, partial:m2250_6 +# 2250| v2250_8(void) = ^IndirectReadSideEffect[-1] : &:r2250_3, m2248_8 +# 2250| m2250_9(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2250_3 +# 2250| m2250_10(ClassWithDestructor) = Chi : total:m2248_8, partial:m2250_9 +# 2250| r2250_11(glval) = VariableAddress[a] : +# 2250| r2250_12(glval) = FunctionAddress[~ClassWithDestructor] : +# 2250| v2250_13(void) = Call[~ClassWithDestructor] : func:r2250_12, this:r2250_11 +# 2250| m2250_14(unknown) = ^CallSideEffect : ~m2250_7 +# 2250| m2250_15(unknown) = Chi : total:m2250_7, partial:m2250_14 +# 2250| v2250_16(void) = ^IndirectReadSideEffect[-1] : &:r2250_11, m2247_8 +# 2250| m2250_17(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2250_11 +# 2250| m2250_18(ClassWithDestructor) = Chi : total:m2247_8, partial:m2250_17 +# 2246| v2246_5(void) = ReturnVoid : +# 2246| v2246_6(void) = AliasedUse : ~m2250_15 +# 2246| v2246_7(void) = ExitFunction : + +# 2252| ClassWithDestructor global_class_with_destructor +# 2252| Block 0 +# 2252| v2252_1(void) = EnterFunction : +# 2252| m2252_2(unknown) = AliasedDefinition : +# 2252| r2252_3(glval) = VariableAddress[global_class_with_destructor] : +# 2252| r2252_4(glval) = FunctionAddress[ClassWithDestructor] : +# 2252| v2252_5(void) = Call[ClassWithDestructor] : func:r2252_4, this:r2252_3 +# 2252| m2252_6(unknown) = ^CallSideEffect : ~m2252_2 +# 2252| m2252_7(unknown) = Chi : total:m2252_2, partial:m2252_6 +# 2252| m2252_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2252_3 +# 2252| m2252_9(unknown) = Chi : total:m2252_7, partial:m2252_8 +# 2252| v2252_10(void) = ReturnVoid : +# 2252| v2252_11(void) = AliasedUse : ~m2252_9 +# 2252| v2252_12(void) = ExitFunction : + +# 2256| ClassWithDestructor& vacuous_destructor_call::get(ClassWithDestructor&) +# 2256| Block 0 +# 2256| v2256_1(void) = EnterFunction : +# 2256| m2256_2(unknown) = AliasedDefinition : +# 2256| m2256_3(unknown) = InitializeNonLocal : +# 2256| m2256_4(unknown) = Chi : total:m2256_2, partial:m2256_3 +# 2256| r2256_5(glval) = VariableAddress[t] : +# 2256| m2256_6(ClassWithDestructor &) = InitializeParameter[t] : &:r2256_5 +# 2256| r2256_7(ClassWithDestructor &) = Load[t] : &:r2256_5, m2256_6 +# 2256| m2256_8(unknown) = InitializeIndirection[t] : &:r2256_7 +# 2256| r2256_9(glval) = VariableAddress[#return] : +# 2256| r2256_10(glval) = VariableAddress[t] : +# 2256| r2256_11(ClassWithDestructor &) = Load[t] : &:r2256_10, m2256_6 +# 2256| r2256_12(glval) = CopyValue : r2256_11 +# 2256| r2256_13(ClassWithDestructor &) = CopyValue : r2256_12 +# 2256| m2256_14(ClassWithDestructor &) = Store[#return] : &:r2256_9, r2256_13 +# 2256| v2256_15(void) = ReturnIndirection[t] : &:r2256_7, m2256_8 +# 2256| r2256_16(glval) = VariableAddress[#return] : +# 2256| v2256_17(void) = ReturnValue : &:r2256_16, m2256_14 +# 2256| v2256_18(void) = AliasedUse : m2256_3 +# 2256| v2256_19(void) = ExitFunction : + +# 2256| int& vacuous_destructor_call::get(int&) +# 2256| Block 0 +# 2256| v2256_1(void) = EnterFunction : +# 2256| m2256_2(unknown) = AliasedDefinition : +# 2256| m2256_3(unknown) = InitializeNonLocal : +# 2256| m2256_4(unknown) = Chi : total:m2256_2, partial:m2256_3 +# 2256| r2256_5(glval) = VariableAddress[t] : +# 2256| m2256_6(int &) = InitializeParameter[t] : &:r2256_5 +# 2256| r2256_7(int &) = Load[t] : &:r2256_5, m2256_6 +# 2256| m2256_8(unknown) = InitializeIndirection[t] : &:r2256_7 +# 2256| r2256_9(glval) = VariableAddress[#return] : +# 2256| r2256_10(glval) = VariableAddress[t] : +# 2256| r2256_11(int &) = Load[t] : &:r2256_10, m2256_6 +# 2256| r2256_12(glval) = CopyValue : r2256_11 +# 2256| r2256_13(int &) = CopyValue : r2256_12 +# 2256| m2256_14(int &) = Store[#return] : &:r2256_9, r2256_13 +# 2256| v2256_15(void) = ReturnIndirection[t] : &:r2256_7, m2256_8 +# 2256| r2256_16(glval) = VariableAddress[#return] : +# 2256| v2256_17(void) = ReturnValue : &:r2256_16, m2256_14 +# 2256| v2256_18(void) = AliasedUse : m2256_3 +# 2256| v2256_19(void) = ExitFunction : + +# 2259| void vacuous_destructor_call::call_destructor(ClassWithDestructor&) +# 2259| Block 0 +# 2259| v2259_1(void) = EnterFunction : +# 2259| m2259_2(unknown) = AliasedDefinition : +# 2259| m2259_3(unknown) = InitializeNonLocal : +# 2259| m2259_4(unknown) = Chi : total:m2259_2, partial:m2259_3 +# 2259| r2259_5(glval) = VariableAddress[t] : +# 2259| m2259_6(ClassWithDestructor &) = InitializeParameter[t] : &:r2259_5 +# 2259| r2259_7(ClassWithDestructor &) = Load[t] : &:r2259_5, m2259_6 +# 2259| m2259_8(unknown) = InitializeIndirection[t] : &:r2259_7 +# 2260| r2260_1(glval) = FunctionAddress[get] : +# 2260| r2260_2(glval) = VariableAddress[t] : +# 2260| r2260_3(ClassWithDestructor &) = Load[t] : &:r2260_2, m2259_6 +# 2260| r2260_4(glval) = CopyValue : r2260_3 +# 2260| r2260_5(ClassWithDestructor &) = CopyValue : r2260_4 +# 2260| r2260_6(ClassWithDestructor &) = Call[get] : func:r2260_1, 0:r2260_5 +# 2260| m2260_7(unknown) = ^CallSideEffect : ~m2259_4 +# 2260| m2260_8(unknown) = Chi : total:m2259_4, partial:m2260_7 +# 2260| v2260_9(void) = ^BufferReadSideEffect[0] : &:r2260_5, ~m2259_8 +# 2260| m2260_10(unknown) = ^BufferMayWriteSideEffect[0] : &:r2260_5 +# 2260| m2260_11(unknown) = Chi : total:m2259_8, partial:m2260_10 +# 2260| r2260_12(glval) = CopyValue : r2260_6 +# 2260| r2260_13(glval) = FunctionAddress[~ClassWithDestructor] : +# 2260| v2260_14(void) = Call[~ClassWithDestructor] : func:r2260_13 +# 2260| m2260_15(unknown) = ^CallSideEffect : ~m2260_8 +# 2260| m2260_16(unknown) = Chi : total:m2260_8, partial:m2260_15 +# 2260| v2260_17(void) = ^IndirectReadSideEffect[-1] : &:r2260_12, ~m2260_11 +# 2260| m2260_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2260_12 +# 2260| m2260_19(unknown) = Chi : total:m2260_11, partial:m2260_18 +# 2261| v2261_1(void) = NoOp : +# 2259| v2259_9(void) = ReturnIndirection[t] : &:r2259_7, m2260_19 +# 2259| v2259_10(void) = ReturnVoid : +# 2259| v2259_11(void) = AliasedUse : ~m2260_16 +# 2259| v2259_12(void) = ExitFunction : + +# 2259| void vacuous_destructor_call::call_destructor(int&) +# 2259| Block 0 +# 2259| v2259_1(void) = EnterFunction : +# 2259| m2259_2(unknown) = AliasedDefinition : +# 2259| m2259_3(unknown) = InitializeNonLocal : +# 2259| m2259_4(unknown) = Chi : total:m2259_2, partial:m2259_3 +# 2259| r2259_5(glval) = VariableAddress[t] : +# 2259| m2259_6(int &) = InitializeParameter[t] : &:r2259_5 +# 2259| r2259_7(int &) = Load[t] : &:r2259_5, m2259_6 +# 2259| m2259_8(unknown) = InitializeIndirection[t] : &:r2259_7 +# 2260| r2260_1(glval) = FunctionAddress[get] : +# 2260| r2260_2(glval) = VariableAddress[t] : +# 2260| r2260_3(int &) = Load[t] : &:r2260_2, m2259_6 +# 2260| r2260_4(glval) = CopyValue : r2260_3 +# 2260| r2260_5(int &) = CopyValue : r2260_4 +# 2260| r2260_6(int &) = Call[get] : func:r2260_1, 0:r2260_5 +# 2260| m2260_7(unknown) = ^CallSideEffect : ~m2259_4 +# 2260| m2260_8(unknown) = Chi : total:m2259_4, partial:m2260_7 +# 2260| v2260_9(void) = ^BufferReadSideEffect[0] : &:r2260_5, ~m2259_8 +# 2260| m2260_10(unknown) = ^BufferMayWriteSideEffect[0] : &:r2260_5 +# 2260| m2260_11(unknown) = Chi : total:m2259_8, partial:m2260_10 +# 2260| r2260_12(glval) = CopyValue : r2260_6 +# 2261| v2261_1(void) = NoOp : +# 2259| v2259_9(void) = ReturnIndirection[t] : &:r2259_7, m2260_11 +# 2259| v2259_10(void) = ReturnVoid : +# 2259| v2259_11(void) = AliasedUse : ~m2260_8 +# 2259| v2259_12(void) = ExitFunction : + +# 2263| void vacuous_destructor_call::non_vacuous_destructor_call() +# 2263| Block 0 +# 2263| v2263_1(void) = EnterFunction : +# 2263| m2263_2(unknown) = AliasedDefinition : +# 2263| m2263_3(unknown) = InitializeNonLocal : +# 2263| m2263_4(unknown) = Chi : total:m2263_2, partial:m2263_3 +# 2264| r2264_1(glval) = VariableAddress[c] : +# 2264| m2264_2(ClassWithDestructor) = Uninitialized[c] : &:r2264_1 +# 2264| r2264_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2264| v2264_4(void) = Call[ClassWithDestructor] : func:r2264_3, this:r2264_1 +# 2264| m2264_5(unknown) = ^CallSideEffect : ~m2263_4 +# 2264| m2264_6(unknown) = Chi : total:m2263_4, partial:m2264_5 +# 2264| m2264_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2264_1 +# 2264| m2264_8(ClassWithDestructor) = Chi : total:m2264_2, partial:m2264_7 +# 2265| r2265_1(glval) = FunctionAddress[call_destructor] : # 2265| r2265_2(glval) = VariableAddress[c] : -# 2265| r2265_3(glval) = FunctionAddress[~ClassWithDestructor] : -# 2265| v2265_4(void) = Call[~ClassWithDestructor] : func:r2265_3, this:r2265_2 +# 2265| r2265_3(ClassWithDestructor &) = CopyValue : r2265_2 +# 2265| v2265_4(void) = Call[call_destructor] : func:r2265_1, 0:r2265_3 # 2265| m2265_5(unknown) = ^CallSideEffect : ~m2264_6 # 2265| m2265_6(unknown) = Chi : total:m2264_6, partial:m2265_5 -# 2265| v2265_7(void) = ^IndirectReadSideEffect[-1] : &:r2265_2, m2264_9 -# 2265| m2265_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2265_2 -# 2265| m2265_9(ClassWithDestructor) = Chi : total:m2264_9, partial:m2265_8 -# 2262| v2262_5(void) = ReturnVoid : -# 2262| v2262_6(void) = AliasedUse : ~m2265_6 -# 2262| v2262_7(void) = ExitFunction : - -# 2267| void vacuous_destructor_call::vacuous_destructor_call() -# 2267| Block 0 -# 2267| v2267_1(void) = EnterFunction : -# 2267| m2267_2(unknown) = AliasedDefinition : -# 2267| m2267_3(unknown) = InitializeNonLocal : -# 2267| m2267_4(unknown) = Chi : total:m2267_2, partial:m2267_3 -# 2268| r2268_1(glval) = VariableAddress[i] : -# 2268| m2268_2(int) = Uninitialized[i] : &:r2268_1 -# 2269| r2269_1(glval) = FunctionAddress[call_destructor] : -# 2269| r2269_2(glval) = VariableAddress[i] : -# 2269| r2269_3(int &) = CopyValue : r2269_2 -# 2269| v2269_4(void) = Call[call_destructor] : func:r2269_1, 0:r2269_3 -# 2269| m2269_5(unknown) = ^CallSideEffect : ~m2267_4 -# 2269| m2269_6(unknown) = Chi : total:m2267_4, partial:m2269_5 -# 2269| v2269_7(void) = ^BufferReadSideEffect[0] : &:r2269_3, ~m2268_2 -# 2269| m2269_8(unknown) = ^BufferMayWriteSideEffect[0] : &:r2269_3 -# 2269| m2269_9(int) = Chi : total:m2268_2, partial:m2269_8 -# 2270| v2270_1(void) = NoOp : -# 2267| v2267_5(void) = ReturnVoid : -# 2267| v2267_6(void) = AliasedUse : ~m2269_6 -# 2267| v2267_7(void) = ExitFunction : - -# 2273| void TryCatchDestructors(bool) -# 2273| Block 0 -# 2273| v2273_1(void) = EnterFunction : -# 2273| m2273_2(unknown) = AliasedDefinition : -# 2273| m2273_3(unknown) = InitializeNonLocal : -# 2273| m2273_4(unknown) = Chi : total:m2273_2, partial:m2273_3 -# 2273| r2273_5(glval) = VariableAddress[b] : -# 2273| m2273_6(bool) = InitializeParameter[b] : &:r2273_5 -# 2275| r2275_1(glval) = VariableAddress[s] : -# 2275| m2275_2(String) = Uninitialized[s] : &:r2275_1 -# 2275| m2275_3(unknown) = Chi : total:m2273_4, partial:m2275_2 -# 2275| r2275_4(glval) = FunctionAddress[String] : -# 2275| v2275_5(void) = Call[String] : func:r2275_4, this:r2275_1 -# 2275| m2275_6(unknown) = ^CallSideEffect : ~m2275_3 -# 2275| m2275_7(unknown) = Chi : total:m2275_3, partial:m2275_6 -# 2275| m2275_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2275_1 -# 2275| m2275_9(unknown) = Chi : total:m2275_7, partial:m2275_8 -# 2276| r2276_1(glval) = VariableAddress[b] : -# 2276| r2276_2(bool) = Load[b] : &:r2276_1, m2273_6 -# 2276| v2276_3(void) = ConditionalBranch : r2276_2 +# 2265| v2265_7(void) = ^BufferReadSideEffect[0] : &:r2265_3, ~m2264_8 +# 2265| m2265_8(unknown) = ^BufferMayWriteSideEffect[0] : &:r2265_3 +# 2265| m2265_9(ClassWithDestructor) = Chi : total:m2264_8, partial:m2265_8 +# 2266| v2266_1(void) = NoOp : +# 2266| r2266_2(glval) = VariableAddress[c] : +# 2266| r2266_3(glval) = FunctionAddress[~ClassWithDestructor] : +# 2266| v2266_4(void) = Call[~ClassWithDestructor] : func:r2266_3, this:r2266_2 +# 2266| m2266_5(unknown) = ^CallSideEffect : ~m2265_6 +# 2266| m2266_6(unknown) = Chi : total:m2265_6, partial:m2266_5 +# 2266| v2266_7(void) = ^IndirectReadSideEffect[-1] : &:r2266_2, m2265_9 +# 2266| m2266_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2266_2 +# 2266| m2266_9(ClassWithDestructor) = Chi : total:m2265_9, partial:m2266_8 +# 2263| v2263_5(void) = ReturnVoid : +# 2263| v2263_6(void) = AliasedUse : ~m2266_6 +# 2263| v2263_7(void) = ExitFunction : + +# 2268| void vacuous_destructor_call::vacuous_destructor_call() +# 2268| Block 0 +# 2268| v2268_1(void) = EnterFunction : +# 2268| m2268_2(unknown) = AliasedDefinition : +# 2268| m2268_3(unknown) = InitializeNonLocal : +# 2268| m2268_4(unknown) = Chi : total:m2268_2, partial:m2268_3 +# 2269| r2269_1(glval) = VariableAddress[i] : +# 2269| m2269_2(int) = Uninitialized[i] : &:r2269_1 +# 2270| r2270_1(glval) = FunctionAddress[call_destructor] : +# 2270| r2270_2(glval) = VariableAddress[i] : +# 2270| r2270_3(int &) = CopyValue : r2270_2 +# 2270| v2270_4(void) = Call[call_destructor] : func:r2270_1, 0:r2270_3 +# 2270| m2270_5(unknown) = ^CallSideEffect : ~m2268_4 +# 2270| m2270_6(unknown) = Chi : total:m2268_4, partial:m2270_5 +# 2270| v2270_7(void) = ^BufferReadSideEffect[0] : &:r2270_3, ~m2269_2 +# 2270| m2270_8(unknown) = ^BufferMayWriteSideEffect[0] : &:r2270_3 +# 2270| m2270_9(int) = Chi : total:m2269_2, partial:m2270_8 +# 2271| v2271_1(void) = NoOp : +# 2268| v2268_5(void) = ReturnVoid : +# 2268| v2268_6(void) = AliasedUse : ~m2270_6 +# 2268| v2268_7(void) = ExitFunction : + +# 2274| void TryCatchDestructors(bool) +# 2274| Block 0 +# 2274| v2274_1(void) = EnterFunction : +# 2274| m2274_2(unknown) = AliasedDefinition : +# 2274| m2274_3(unknown) = InitializeNonLocal : +# 2274| m2274_4(unknown) = Chi : total:m2274_2, partial:m2274_3 +# 2274| r2274_5(glval) = VariableAddress[b] : +# 2274| m2274_6(bool) = InitializeParameter[b] : &:r2274_5 +# 2276| r2276_1(glval) = VariableAddress[s] : +# 2276| m2276_2(String) = Uninitialized[s] : &:r2276_1 +# 2276| m2276_3(unknown) = Chi : total:m2274_4, partial:m2276_2 +# 2276| r2276_4(glval) = FunctionAddress[String] : +# 2276| v2276_5(void) = Call[String] : func:r2276_4, this:r2276_1 +# 2276| m2276_6(unknown) = ^CallSideEffect : ~m2276_3 +# 2276| m2276_7(unknown) = Chi : total:m2276_3, partial:m2276_6 +# 2276| m2276_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2276_1 +# 2276| m2276_9(unknown) = Chi : total:m2276_7, partial:m2276_8 +# 2277| r2277_1(glval) = VariableAddress[b] : +# 2277| r2277_2(bool) = Load[b] : &:r2277_1, m2274_6 +# 2277| v2277_3(void) = ConditionalBranch : r2277_2 #-----| False -> Block 4 #-----| True -> Block 3 -# 2273| Block 1 -# 2273| m2273_7(unknown) = Phi : from 2:~m2273_10, from 10:~m2289_1 -# 2273| v2273_8(void) = AliasedUse : ~m2273_7 -# 2273| v2273_9(void) = ExitFunction : +# 2274| Block 1 +# 2274| m2274_7(unknown) = Phi : from 2:~m2274_10, from 10:~m2290_1 +# 2274| v2274_8(void) = AliasedUse : ~m2274_7 +# 2274| v2274_9(void) = ExitFunction : -# 2273| Block 2 -# 2273| m2273_10(unknown) = Phi : from 6:~m2282_12, from 9:~m2280_8 -# 2273| v2273_11(void) = Unwind : +# 2274| Block 2 +# 2274| m2274_10(unknown) = Phi : from 6:~m2283_12, from 9:~m2281_8 +# 2274| v2274_11(void) = Unwind : #-----| Goto -> Block 1 -# 2277| Block 3 -# 2277| r2277_1(glval) = VariableAddress[#throw2277:7] : -# 2277| r2277_2(glval) = StringConstant["string literal"] : -# 2277| r2277_3(char *) = Convert : r2277_2 -# 2277| m2277_4(char *) = Store[#throw2277:7] : &:r2277_1, r2277_3 -# 2277| v2277_5(void) = ThrowValue : &:r2277_1, m2277_4 -# 2280| r2280_1(glval) = VariableAddress[s] : -# 2280| r2280_2(glval) = FunctionAddress[~String] : -# 2280| v2280_3(void) = Call[~String] : func:r2280_2, this:r2280_1 -# 2280| m2280_4(unknown) = ^CallSideEffect : ~m2275_9 -# 2280| m2280_5(unknown) = Chi : total:m2275_9, partial:m2280_4 -# 2280| v2280_6(void) = ^IndirectReadSideEffect[-1] : &:r2280_1, ~m2280_5 -# 2280| m2280_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2280_1 -# 2280| m2280_8(unknown) = Chi : total:m2280_5, partial:m2280_7 +# 2278| Block 3 +# 2278| r2278_1(glval) = VariableAddress[#throw2278:7] : +# 2278| r2278_2(glval) = StringConstant["string literal"] : +# 2278| r2278_3(char *) = Convert : r2278_2 +# 2278| m2278_4(char *) = Store[#throw2278:7] : &:r2278_1, r2278_3 +# 2278| v2278_5(void) = ThrowValue : &:r2278_1, m2278_4 +# 2281| r2281_1(glval) = VariableAddress[s] : +# 2281| r2281_2(glval) = FunctionAddress[~String] : +# 2281| v2281_3(void) = Call[~String] : func:r2281_2, this:r2281_1 +# 2281| m2281_4(unknown) = ^CallSideEffect : ~m2276_9 +# 2281| m2281_5(unknown) = Chi : total:m2276_9, partial:m2281_4 +# 2281| v2281_6(void) = ^IndirectReadSideEffect[-1] : &:r2281_1, ~m2281_5 +# 2281| m2281_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2281_1 +# 2281| m2281_8(unknown) = Chi : total:m2281_5, partial:m2281_7 #-----| Exception -> Block 5 -# 2279| Block 4 -# 2279| r2279_1(glval) = VariableAddress[s2] : -# 2279| m2279_2(String) = Uninitialized[s2] : &:r2279_1 -# 2279| m2279_3(unknown) = Chi : total:m2275_9, partial:m2279_2 -# 2279| r2279_4(glval) = FunctionAddress[String] : -# 2279| v2279_5(void) = Call[String] : func:r2279_4, this:r2279_1 -# 2279| m2279_6(unknown) = ^CallSideEffect : ~m2279_3 -# 2279| m2279_7(unknown) = Chi : total:m2279_3, partial:m2279_6 -# 2279| m2279_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2279_1 -# 2279| m2279_9(unknown) = Chi : total:m2279_7, partial:m2279_8 -# 2280| r2280_9(glval) = VariableAddress[s2] : -# 2280| r2280_10(glval) = FunctionAddress[~String] : -# 2280| v2280_11(void) = Call[~String] : func:r2280_10, this:r2280_9 -# 2280| m2280_12(unknown) = ^CallSideEffect : ~m2279_9 -# 2280| m2280_13(unknown) = Chi : total:m2279_9, partial:m2280_12 -# 2280| v2280_14(void) = ^IndirectReadSideEffect[-1] : &:r2280_9, ~m2280_13 -# 2280| m2280_15(String) = ^IndirectMayWriteSideEffect[-1] : &:r2280_9 -# 2280| m2280_16(unknown) = Chi : total:m2280_13, partial:m2280_15 -# 2280| r2280_17(glval) = VariableAddress[s] : -# 2280| r2280_18(glval) = FunctionAddress[~String] : -# 2280| v2280_19(void) = Call[~String] : func:r2280_18, this:r2280_17 -# 2280| m2280_20(unknown) = ^CallSideEffect : ~m2280_16 -# 2280| m2280_21(unknown) = Chi : total:m2280_16, partial:m2280_20 -# 2280| v2280_22(void) = ^IndirectReadSideEffect[-1] : &:r2280_17, ~m2280_21 -# 2280| m2280_23(String) = ^IndirectMayWriteSideEffect[-1] : &:r2280_17 -# 2280| m2280_24(unknown) = Chi : total:m2280_21, partial:m2280_23 +# 2280| Block 4 +# 2280| r2280_1(glval) = VariableAddress[s2] : +# 2280| m2280_2(String) = Uninitialized[s2] : &:r2280_1 +# 2280| m2280_3(unknown) = Chi : total:m2276_9, partial:m2280_2 +# 2280| r2280_4(glval) = FunctionAddress[String] : +# 2280| v2280_5(void) = Call[String] : func:r2280_4, this:r2280_1 +# 2280| m2280_6(unknown) = ^CallSideEffect : ~m2280_3 +# 2280| m2280_7(unknown) = Chi : total:m2280_3, partial:m2280_6 +# 2280| m2280_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2280_1 +# 2280| m2280_9(unknown) = Chi : total:m2280_7, partial:m2280_8 +# 2281| r2281_9(glval) = VariableAddress[s2] : +# 2281| r2281_10(glval) = FunctionAddress[~String] : +# 2281| v2281_11(void) = Call[~String] : func:r2281_10, this:r2281_9 +# 2281| m2281_12(unknown) = ^CallSideEffect : ~m2280_9 +# 2281| m2281_13(unknown) = Chi : total:m2280_9, partial:m2281_12 +# 2281| v2281_14(void) = ^IndirectReadSideEffect[-1] : &:r2281_9, ~m2281_13 +# 2281| m2281_15(String) = ^IndirectMayWriteSideEffect[-1] : &:r2281_9 +# 2281| m2281_16(unknown) = Chi : total:m2281_13, partial:m2281_15 +# 2281| r2281_17(glval) = VariableAddress[s] : +# 2281| r2281_18(glval) = FunctionAddress[~String] : +# 2281| v2281_19(void) = Call[~String] : func:r2281_18, this:r2281_17 +# 2281| m2281_20(unknown) = ^CallSideEffect : ~m2281_16 +# 2281| m2281_21(unknown) = Chi : total:m2281_16, partial:m2281_20 +# 2281| v2281_22(void) = ^IndirectReadSideEffect[-1] : &:r2281_17, ~m2281_21 +# 2281| m2281_23(String) = ^IndirectMayWriteSideEffect[-1] : &:r2281_17 +# 2281| m2281_24(unknown) = Chi : total:m2281_21, partial:m2281_23 #-----| Goto -> Block 10 -# 2281| Block 5 -# 2281| v2281_1(void) = CatchByType[const char *] : +# 2282| Block 5 +# 2282| v2282_1(void) = CatchByType[const char *] : #-----| Exception -> Block 7 #-----| Goto -> Block 6 -# 2281| Block 6 -# 2281| r2281_2(glval) = VariableAddress[s] : -# 2281| m2281_3(char *) = InitializeParameter[s] : &:r2281_2 -# 2281| r2281_4(char *) = Load[s] : &:r2281_2, m2281_3 -# 2281| m2281_5(unknown) = InitializeIndirection[s] : &:r2281_4 -# 2281| m2281_6(unknown) = Chi : total:m2280_8, partial:m2281_5 -# 2282| r2282_1(glval) = VariableAddress[#throw2282:5] : -# 2282| m2282_2(String) = Uninitialized[#throw2282:5] : &:r2282_1 -# 2282| m2282_3(unknown) = Chi : total:m2281_6, partial:m2282_2 -# 2282| r2282_4(glval) = FunctionAddress[String] : -# 2282| r2282_5(glval) = VariableAddress[s] : -# 2282| r2282_6(char *) = Load[s] : &:r2282_5, m2281_3 -# 2282| v2282_7(void) = Call[String] : func:r2282_4, this:r2282_1, 0:r2282_6 -# 2282| m2282_8(unknown) = ^CallSideEffect : ~m2282_3 -# 2282| m2282_9(unknown) = Chi : total:m2282_3, partial:m2282_8 -# 2282| v2282_10(void) = ^BufferReadSideEffect[0] : &:r2282_6, ~m2282_9 -# 2282| m2282_11(String) = ^IndirectMayWriteSideEffect[-1] : &:r2282_1 -# 2282| m2282_12(unknown) = Chi : total:m2282_9, partial:m2282_11 -# 2282| v2282_13(void) = ThrowValue : &:r2282_1, ~m2282_12 +# 2282| Block 6 +# 2282| r2282_2(glval) = VariableAddress[s] : +# 2282| m2282_3(char *) = InitializeParameter[s] : &:r2282_2 +# 2282| r2282_4(char *) = Load[s] : &:r2282_2, m2282_3 +# 2282| m2282_5(unknown) = InitializeIndirection[s] : &:r2282_4 +# 2282| m2282_6(unknown) = Chi : total:m2281_8, partial:m2282_5 +# 2283| r2283_1(glval) = VariableAddress[#throw2283:5] : +# 2283| m2283_2(String) = Uninitialized[#throw2283:5] : &:r2283_1 +# 2283| m2283_3(unknown) = Chi : total:m2282_6, partial:m2283_2 +# 2283| r2283_4(glval) = FunctionAddress[String] : +# 2283| r2283_5(glval) = VariableAddress[s] : +# 2283| r2283_6(char *) = Load[s] : &:r2283_5, m2282_3 +# 2283| v2283_7(void) = Call[String] : func:r2283_4, this:r2283_1, 0:r2283_6 +# 2283| m2283_8(unknown) = ^CallSideEffect : ~m2283_3 +# 2283| m2283_9(unknown) = Chi : total:m2283_3, partial:m2283_8 +# 2283| v2283_10(void) = ^BufferReadSideEffect[0] : &:r2283_6, ~m2283_9 +# 2283| m2283_11(String) = ^IndirectMayWriteSideEffect[-1] : &:r2283_1 +# 2283| m2283_12(unknown) = Chi : total:m2283_9, partial:m2283_11 +# 2283| v2283_13(void) = ThrowValue : &:r2283_1, ~m2283_12 #-----| Exception -> Block 2 -# 2284| Block 7 -# 2284| v2284_1(void) = CatchByType[const String &] : +# 2285| Block 7 +# 2285| v2285_1(void) = CatchByType[const String &] : #-----| Exception -> Block 9 #-----| Goto -> Block 8 -# 2284| Block 8 -# 2284| r2284_2(glval) = VariableAddress[e] : -# 2284| m2284_3(String &) = InitializeParameter[e] : &:r2284_2 -# 2284| r2284_4(String &) = Load[e] : &:r2284_2, m2284_3 -# 2284| m2284_5(unknown) = InitializeIndirection[e] : &:r2284_4 -# 2284| v2284_6(void) = NoOp : +# 2285| Block 8 +# 2285| r2285_2(glval) = VariableAddress[e] : +# 2285| m2285_3(String &) = InitializeParameter[e] : &:r2285_2 +# 2285| r2285_4(String &) = Load[e] : &:r2285_2, m2285_3 +# 2285| m2285_5(unknown) = InitializeIndirection[e] : &:r2285_4 +# 2285| v2285_6(void) = NoOp : #-----| Goto -> Block 10 -# 2286| Block 9 -# 2286| v2286_1(void) = CatchAny : -# 2287| v2287_1(void) = ReThrow : +# 2287| Block 9 +# 2287| v2287_1(void) = CatchAny : +# 2288| v2288_1(void) = ReThrow : #-----| Exception -> Block 2 -# 2289| Block 10 -# 2289| m2289_1(unknown) = Phi : from 4:~m2280_24, from 8:~m2280_8 -# 2289| v2289_2(void) = NoOp : -# 2273| v2273_12(void) = ReturnVoid : +# 2290| Block 10 +# 2290| m2290_1(unknown) = Phi : from 4:~m2281_24, from 8:~m2281_8 +# 2290| v2290_2(void) = NoOp : +# 2274| v2274_12(void) = ReturnVoid : #-----| Goto -> Block 1 -# 2291| void IfDestructors(bool) -# 2291| Block 0 -# 2291| v2291_1(void) = EnterFunction : -# 2291| m2291_2(unknown) = AliasedDefinition : -# 2291| m2291_3(unknown) = InitializeNonLocal : -# 2291| m2291_4(unknown) = Chi : total:m2291_2, partial:m2291_3 -# 2291| r2291_5(glval) = VariableAddress[b] : -# 2291| m2291_6(bool) = InitializeParameter[b] : &:r2291_5 -# 2292| r2292_1(glval) = VariableAddress[s1] : -# 2292| m2292_2(String) = Uninitialized[s1] : &:r2292_1 -# 2292| m2292_3(unknown) = Chi : total:m2291_4, partial:m2292_2 -# 2292| r2292_4(glval) = FunctionAddress[String] : -# 2292| v2292_5(void) = Call[String] : func:r2292_4, this:r2292_1 -# 2292| m2292_6(unknown) = ^CallSideEffect : ~m2292_3 -# 2292| m2292_7(unknown) = Chi : total:m2292_3, partial:m2292_6 -# 2292| m2292_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2292_1 -# 2292| m2292_9(unknown) = Chi : total:m2292_7, partial:m2292_8 -# 2293| r2293_1(glval) = VariableAddress[b] : -# 2293| r2293_2(bool) = Load[b] : &:r2293_1, m2291_6 -# 2293| v2293_3(void) = ConditionalBranch : r2293_2 +# 2292| void IfDestructors(bool) +# 2292| Block 0 +# 2292| v2292_1(void) = EnterFunction : +# 2292| m2292_2(unknown) = AliasedDefinition : +# 2292| m2292_3(unknown) = InitializeNonLocal : +# 2292| m2292_4(unknown) = Chi : total:m2292_2, partial:m2292_3 +# 2292| r2292_5(glval) = VariableAddress[b] : +# 2292| m2292_6(bool) = InitializeParameter[b] : &:r2292_5 +# 2293| r2293_1(glval) = VariableAddress[s1] : +# 2293| m2293_2(String) = Uninitialized[s1] : &:r2293_1 +# 2293| m2293_3(unknown) = Chi : total:m2292_4, partial:m2293_2 +# 2293| r2293_4(glval) = FunctionAddress[String] : +# 2293| v2293_5(void) = Call[String] : func:r2293_4, this:r2293_1 +# 2293| m2293_6(unknown) = ^CallSideEffect : ~m2293_3 +# 2293| m2293_7(unknown) = Chi : total:m2293_3, partial:m2293_6 +# 2293| m2293_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2293_1 +# 2293| m2293_9(unknown) = Chi : total:m2293_7, partial:m2293_8 +# 2294| r2294_1(glval) = VariableAddress[b] : +# 2294| r2294_2(bool) = Load[b] : &:r2294_1, m2292_6 +# 2294| v2294_3(void) = ConditionalBranch : r2294_2 #-----| False -> Block 2 #-----| True -> Block 1 -# 2294| Block 1 -# 2294| r2294_1(glval) = VariableAddress[s2] : -# 2294| m2294_2(String) = Uninitialized[s2] : &:r2294_1 -# 2294| m2294_3(unknown) = Chi : total:m2292_9, partial:m2294_2 -# 2294| r2294_4(glval) = FunctionAddress[String] : -# 2294| v2294_5(void) = Call[String] : func:r2294_4, this:r2294_1 -# 2294| m2294_6(unknown) = ^CallSideEffect : ~m2294_3 -# 2294| m2294_7(unknown) = Chi : total:m2294_3, partial:m2294_6 -# 2294| m2294_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2294_1 -# 2294| m2294_9(unknown) = Chi : total:m2294_7, partial:m2294_8 +# 2295| Block 1 # 2295| r2295_1(glval) = VariableAddress[s2] : -# 2295| r2295_2(glval) = FunctionAddress[~String] : -# 2295| v2295_3(void) = Call[~String] : func:r2295_2, this:r2295_1 -# 2295| m2295_4(unknown) = ^CallSideEffect : ~m2294_9 -# 2295| m2295_5(unknown) = Chi : total:m2294_9, partial:m2295_4 -# 2295| v2295_6(void) = ^IndirectReadSideEffect[-1] : &:r2295_1, ~m2295_5 -# 2295| m2295_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2295_1 -# 2295| m2295_8(unknown) = Chi : total:m2295_5, partial:m2295_7 +# 2295| m2295_2(String) = Uninitialized[s2] : &:r2295_1 +# 2295| m2295_3(unknown) = Chi : total:m2293_9, partial:m2295_2 +# 2295| r2295_4(glval) = FunctionAddress[String] : +# 2295| v2295_5(void) = Call[String] : func:r2295_4, this:r2295_1 +# 2295| m2295_6(unknown) = ^CallSideEffect : ~m2295_3 +# 2295| m2295_7(unknown) = Chi : total:m2295_3, partial:m2295_6 +# 2295| m2295_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2295_1 +# 2295| m2295_9(unknown) = Chi : total:m2295_7, partial:m2295_8 +# 2296| r2296_1(glval) = VariableAddress[s2] : +# 2296| r2296_2(glval) = FunctionAddress[~String] : +# 2296| v2296_3(void) = Call[~String] : func:r2296_2, this:r2296_1 +# 2296| m2296_4(unknown) = ^CallSideEffect : ~m2295_9 +# 2296| m2296_5(unknown) = Chi : total:m2295_9, partial:m2296_4 +# 2296| v2296_6(void) = ^IndirectReadSideEffect[-1] : &:r2296_1, ~m2296_5 +# 2296| m2296_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2296_1 +# 2296| m2296_8(unknown) = Chi : total:m2296_5, partial:m2296_7 #-----| Goto -> Block 3 -# 2296| Block 2 -# 2296| r2296_1(glval) = VariableAddress[s3] : -# 2296| m2296_2(String) = Uninitialized[s3] : &:r2296_1 -# 2296| m2296_3(unknown) = Chi : total:m2292_9, partial:m2296_2 -# 2296| r2296_4(glval) = FunctionAddress[String] : -# 2296| v2296_5(void) = Call[String] : func:r2296_4, this:r2296_1 -# 2296| m2296_6(unknown) = ^CallSideEffect : ~m2296_3 -# 2296| m2296_7(unknown) = Chi : total:m2296_3, partial:m2296_6 -# 2296| m2296_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2296_1 -# 2296| m2296_9(unknown) = Chi : total:m2296_7, partial:m2296_8 +# 2297| Block 2 # 2297| r2297_1(glval) = VariableAddress[s3] : -# 2297| r2297_2(glval) = FunctionAddress[~String] : -# 2297| v2297_3(void) = Call[~String] : func:r2297_2, this:r2297_1 -# 2297| m2297_4(unknown) = ^CallSideEffect : ~m2296_9 -# 2297| m2297_5(unknown) = Chi : total:m2296_9, partial:m2297_4 -# 2297| v2297_6(void) = ^IndirectReadSideEffect[-1] : &:r2297_1, ~m2297_5 -# 2297| m2297_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2297_1 -# 2297| m2297_8(unknown) = Chi : total:m2297_5, partial:m2297_7 +# 2297| m2297_2(String) = Uninitialized[s3] : &:r2297_1 +# 2297| m2297_3(unknown) = Chi : total:m2293_9, partial:m2297_2 +# 2297| r2297_4(glval) = FunctionAddress[String] : +# 2297| v2297_5(void) = Call[String] : func:r2297_4, this:r2297_1 +# 2297| m2297_6(unknown) = ^CallSideEffect : ~m2297_3 +# 2297| m2297_7(unknown) = Chi : total:m2297_3, partial:m2297_6 +# 2297| m2297_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2297_1 +# 2297| m2297_9(unknown) = Chi : total:m2297_7, partial:m2297_8 +# 2298| r2298_1(glval) = VariableAddress[s3] : +# 2298| r2298_2(glval) = FunctionAddress[~String] : +# 2298| v2298_3(void) = Call[~String] : func:r2298_2, this:r2298_1 +# 2298| m2298_4(unknown) = ^CallSideEffect : ~m2297_9 +# 2298| m2298_5(unknown) = Chi : total:m2297_9, partial:m2298_4 +# 2298| v2298_6(void) = ^IndirectReadSideEffect[-1] : &:r2298_1, ~m2298_5 +# 2298| m2298_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2298_1 +# 2298| m2298_8(unknown) = Chi : total:m2298_5, partial:m2298_7 #-----| Goto -> Block 3 -# 2298| Block 3 -# 2298| m2298_1(unknown) = Phi : from 1:~m2295_8, from 2:~m2297_8 -# 2298| r2298_2(glval) = VariableAddress[s4] : -# 2298| m2298_3(String) = Uninitialized[s4] : &:r2298_2 -# 2298| m2298_4(unknown) = Chi : total:m2298_1, partial:m2298_3 -# 2298| r2298_5(glval) = FunctionAddress[String] : -# 2298| v2298_6(void) = Call[String] : func:r2298_5, this:r2298_2 -# 2298| m2298_7(unknown) = ^CallSideEffect : ~m2298_4 -# 2298| m2298_8(unknown) = Chi : total:m2298_4, partial:m2298_7 -# 2298| m2298_9(String) = ^IndirectMayWriteSideEffect[-1] : &:r2298_2 -# 2298| m2298_10(unknown) = Chi : total:m2298_8, partial:m2298_9 -# 2299| v2299_1(void) = NoOp : +# 2299| Block 3 +# 2299| m2299_1(unknown) = Phi : from 1:~m2296_8, from 2:~m2298_8 # 2299| r2299_2(glval) = VariableAddress[s4] : -# 2299| r2299_3(glval) = FunctionAddress[~String] : -# 2299| v2299_4(void) = Call[~String] : func:r2299_3, this:r2299_2 -# 2299| m2299_5(unknown) = ^CallSideEffect : ~m2298_10 -# 2299| m2299_6(unknown) = Chi : total:m2298_10, partial:m2299_5 -# 2299| v2299_7(void) = ^IndirectReadSideEffect[-1] : &:r2299_2, ~m2299_6 -# 2299| m2299_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2299_2 -# 2299| m2299_9(unknown) = Chi : total:m2299_6, partial:m2299_8 -# 2299| r2299_10(glval) = VariableAddress[s1] : -# 2299| r2299_11(glval) = FunctionAddress[~String] : -# 2299| v2299_12(void) = Call[~String] : func:r2299_11, this:r2299_10 -# 2299| m2299_13(unknown) = ^CallSideEffect : ~m2299_9 -# 2299| m2299_14(unknown) = Chi : total:m2299_9, partial:m2299_13 -# 2299| v2299_15(void) = ^IndirectReadSideEffect[-1] : &:r2299_10, ~m2299_14 -# 2299| m2299_16(String) = ^IndirectMayWriteSideEffect[-1] : &:r2299_10 -# 2299| m2299_17(unknown) = Chi : total:m2299_14, partial:m2299_16 -# 2291| v2291_7(void) = ReturnVoid : -# 2291| v2291_8(void) = AliasedUse : ~m2299_14 -# 2291| v2291_9(void) = ExitFunction : - -# 2301| void ForDestructors() -# 2301| Block 0 -# 2301| v2301_1(void) = EnterFunction : -# 2301| m2301_2(unknown) = AliasedDefinition : -# 2301| m2301_3(unknown) = InitializeNonLocal : -# 2301| m2301_4(unknown) = Chi : total:m2301_2, partial:m2301_3 -# 2302| r2302_1(glval) = VariableAddress[c] : -# 2302| r2302_2(char) = Constant[97] : -# 2302| m2302_3(char) = Store[c] : &:r2302_1, r2302_2 -# 2303| r2303_1(glval) = VariableAddress[s] : -# 2303| m2303_2(String) = Uninitialized[s] : &:r2303_1 -# 2303| m2303_3(unknown) = Chi : total:m2301_4, partial:m2303_2 -# 2303| r2303_4(glval) = FunctionAddress[String] : -# 2303| r2303_5(glval) = StringConstant["hello"] : -# 2303| r2303_6(char *) = Convert : r2303_5 -# 2303| v2303_7(void) = Call[String] : func:r2303_4, this:r2303_1, 0:r2303_6 -# 2303| m2303_8(unknown) = ^CallSideEffect : ~m2303_3 -# 2303| m2303_9(unknown) = Chi : total:m2303_3, partial:m2303_8 -# 2303| v2303_10(void) = ^BufferReadSideEffect[0] : &:r2303_6, ~m2301_3 -# 2303| m2303_11(String) = ^IndirectMayWriteSideEffect[-1] : &:r2303_1 -# 2303| m2303_12(unknown) = Chi : total:m2303_9, partial:m2303_11 +# 2299| m2299_3(String) = Uninitialized[s4] : &:r2299_2 +# 2299| m2299_4(unknown) = Chi : total:m2299_1, partial:m2299_3 +# 2299| r2299_5(glval) = FunctionAddress[String] : +# 2299| v2299_6(void) = Call[String] : func:r2299_5, this:r2299_2 +# 2299| m2299_7(unknown) = ^CallSideEffect : ~m2299_4 +# 2299| m2299_8(unknown) = Chi : total:m2299_4, partial:m2299_7 +# 2299| m2299_9(String) = ^IndirectMayWriteSideEffect[-1] : &:r2299_2 +# 2299| m2299_10(unknown) = Chi : total:m2299_8, partial:m2299_9 +# 2300| v2300_1(void) = NoOp : +# 2300| r2300_2(glval) = VariableAddress[s4] : +# 2300| r2300_3(glval) = FunctionAddress[~String] : +# 2300| v2300_4(void) = Call[~String] : func:r2300_3, this:r2300_2 +# 2300| m2300_5(unknown) = ^CallSideEffect : ~m2299_10 +# 2300| m2300_6(unknown) = Chi : total:m2299_10, partial:m2300_5 +# 2300| v2300_7(void) = ^IndirectReadSideEffect[-1] : &:r2300_2, ~m2300_6 +# 2300| m2300_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2300_2 +# 2300| m2300_9(unknown) = Chi : total:m2300_6, partial:m2300_8 +# 2300| r2300_10(glval) = VariableAddress[s1] : +# 2300| r2300_11(glval) = FunctionAddress[~String] : +# 2300| v2300_12(void) = Call[~String] : func:r2300_11, this:r2300_10 +# 2300| m2300_13(unknown) = ^CallSideEffect : ~m2300_9 +# 2300| m2300_14(unknown) = Chi : total:m2300_9, partial:m2300_13 +# 2300| v2300_15(void) = ^IndirectReadSideEffect[-1] : &:r2300_10, ~m2300_14 +# 2300| m2300_16(String) = ^IndirectMayWriteSideEffect[-1] : &:r2300_10 +# 2300| m2300_17(unknown) = Chi : total:m2300_14, partial:m2300_16 +# 2292| v2292_7(void) = ReturnVoid : +# 2292| v2292_8(void) = AliasedUse : ~m2300_14 +# 2292| v2292_9(void) = ExitFunction : + +# 2302| void ForDestructors() +# 2302| Block 0 +# 2302| v2302_1(void) = EnterFunction : +# 2302| m2302_2(unknown) = AliasedDefinition : +# 2302| m2302_3(unknown) = InitializeNonLocal : +# 2302| m2302_4(unknown) = Chi : total:m2302_2, partial:m2302_3 +# 2303| r2303_1(glval) = VariableAddress[c] : +# 2303| r2303_2(char) = Constant[97] : +# 2303| m2303_3(char) = Store[c] : &:r2303_1, r2303_2 +# 2304| r2304_1(glval) = VariableAddress[s] : +# 2304| m2304_2(String) = Uninitialized[s] : &:r2304_1 +# 2304| m2304_3(unknown) = Chi : total:m2302_4, partial:m2304_2 +# 2304| r2304_4(glval) = FunctionAddress[String] : +# 2304| r2304_5(glval) = StringConstant["hello"] : +# 2304| r2304_6(char *) = Convert : r2304_5 +# 2304| v2304_7(void) = Call[String] : func:r2304_4, this:r2304_1, 0:r2304_6 +# 2304| m2304_8(unknown) = ^CallSideEffect : ~m2304_3 +# 2304| m2304_9(unknown) = Chi : total:m2304_3, partial:m2304_8 +# 2304| v2304_10(void) = ^BufferReadSideEffect[0] : &:r2304_6, ~m2302_3 +# 2304| m2304_11(String) = ^IndirectMayWriteSideEffect[-1] : &:r2304_1 +# 2304| m2304_12(unknown) = Chi : total:m2304_9, partial:m2304_11 #-----| Goto -> Block 1 -# 2303| Block 1 -# 2303| m2303_13(unknown) = Phi : from 0:~m2303_12, from 2:~m2303_28 -# 2303| m2303_14(char) = Phi : from 0:m2302_3, from 2:m2303_30 -# 2303| r2303_15(glval) = VariableAddress[c] : -# 2303| r2303_16(char) = Load[c] : &:r2303_15, m2303_14 -# 2303| r2303_17(int) = Convert : r2303_16 -# 2303| r2303_18(int) = Constant[0] : -# 2303| r2303_19(bool) = CompareNE : r2303_17, r2303_18 -# 2303| v2303_20(void) = ConditionalBranch : r2303_19 +# 2304| Block 1 +# 2304| m2304_13(unknown) = Phi : from 0:~m2304_12, from 2:~m2304_28 +# 2304| m2304_14(char) = Phi : from 0:m2303_3, from 2:m2304_30 +# 2304| r2304_15(glval) = VariableAddress[c] : +# 2304| r2304_16(char) = Load[c] : &:r2304_15, m2304_14 +# 2304| r2304_17(int) = Convert : r2304_16 +# 2304| r2304_18(int) = Constant[0] : +# 2304| r2304_19(bool) = CompareNE : r2304_17, r2304_18 +# 2304| v2304_20(void) = ConditionalBranch : r2304_19 #-----| False -> Block 3 #-----| True -> Block 2 -# 2304| Block 2 -# 2304| r2304_1(glval) = VariableAddress[s2] : -# 2304| m2304_2(String) = Uninitialized[s2] : &:r2304_1 -# 2304| m2304_3(unknown) = Chi : total:m2303_13, partial:m2304_2 -# 2304| r2304_4(glval) = FunctionAddress[String] : -# 2304| v2304_5(void) = Call[String] : func:r2304_4, this:r2304_1 -# 2304| m2304_6(unknown) = ^CallSideEffect : ~m2304_3 -# 2304| m2304_7(unknown) = Chi : total:m2304_3, partial:m2304_6 -# 2304| m2304_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2304_1 -# 2304| m2304_9(unknown) = Chi : total:m2304_7, partial:m2304_8 +# 2305| Block 2 # 2305| r2305_1(glval) = VariableAddress[s2] : -# 2305| r2305_2(glval) = FunctionAddress[~String] : -# 2305| v2305_3(void) = Call[~String] : func:r2305_2, this:r2305_1 -# 2305| m2305_4(unknown) = ^CallSideEffect : ~m2304_9 -# 2305| m2305_5(unknown) = Chi : total:m2304_9, partial:m2305_4 -# 2305| v2305_6(void) = ^IndirectReadSideEffect[-1] : &:r2305_1, ~m2305_5 -# 2305| m2305_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2305_1 -# 2305| m2305_8(unknown) = Chi : total:m2305_5, partial:m2305_7 -# 2303| r2303_21(glval) = VariableAddress[s] : -# 2303| r2303_22(glval) = FunctionAddress[pop_back] : -# 2303| r2303_23(char) = Call[pop_back] : func:r2303_22, this:r2303_21 -# 2303| m2303_24(unknown) = ^CallSideEffect : ~m2305_8 -# 2303| m2303_25(unknown) = Chi : total:m2305_8, partial:m2303_24 -# 2303| v2303_26(void) = ^IndirectReadSideEffect[-1] : &:r2303_21, ~m2303_25 -# 2303| m2303_27(String) = ^IndirectMayWriteSideEffect[-1] : &:r2303_21 -# 2303| m2303_28(unknown) = Chi : total:m2303_25, partial:m2303_27 -# 2303| r2303_29(glval) = VariableAddress[c] : -# 2303| m2303_30(char) = Store[c] : &:r2303_29, r2303_23 +# 2305| m2305_2(String) = Uninitialized[s2] : &:r2305_1 +# 2305| m2305_3(unknown) = Chi : total:m2304_13, partial:m2305_2 +# 2305| r2305_4(glval) = FunctionAddress[String] : +# 2305| v2305_5(void) = Call[String] : func:r2305_4, this:r2305_1 +# 2305| m2305_6(unknown) = ^CallSideEffect : ~m2305_3 +# 2305| m2305_7(unknown) = Chi : total:m2305_3, partial:m2305_6 +# 2305| m2305_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2305_1 +# 2305| m2305_9(unknown) = Chi : total:m2305_7, partial:m2305_8 +# 2306| r2306_1(glval) = VariableAddress[s2] : +# 2306| r2306_2(glval) = FunctionAddress[~String] : +# 2306| v2306_3(void) = Call[~String] : func:r2306_2, this:r2306_1 +# 2306| m2306_4(unknown) = ^CallSideEffect : ~m2305_9 +# 2306| m2306_5(unknown) = Chi : total:m2305_9, partial:m2306_4 +# 2306| v2306_6(void) = ^IndirectReadSideEffect[-1] : &:r2306_1, ~m2306_5 +# 2306| m2306_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2306_1 +# 2306| m2306_8(unknown) = Chi : total:m2306_5, partial:m2306_7 +# 2304| r2304_21(glval) = VariableAddress[s] : +# 2304| r2304_22(glval) = FunctionAddress[pop_back] : +# 2304| r2304_23(char) = Call[pop_back] : func:r2304_22, this:r2304_21 +# 2304| m2304_24(unknown) = ^CallSideEffect : ~m2306_8 +# 2304| m2304_25(unknown) = Chi : total:m2306_8, partial:m2304_24 +# 2304| v2304_26(void) = ^IndirectReadSideEffect[-1] : &:r2304_21, ~m2304_25 +# 2304| m2304_27(String) = ^IndirectMayWriteSideEffect[-1] : &:r2304_21 +# 2304| m2304_28(unknown) = Chi : total:m2304_25, partial:m2304_27 +# 2304| r2304_29(glval) = VariableAddress[c] : +# 2304| m2304_30(char) = Store[c] : &:r2304_29, r2304_23 #-----| Goto (back edge) -> Block 1 -# 2303| Block 3 -# 2303| r2303_31(glval) = VariableAddress[s] : -# 2303| r2303_32(glval) = FunctionAddress[~String] : -# 2303| v2303_33(void) = Call[~String] : func:r2303_32, this:r2303_31 -# 2303| m2303_34(unknown) = ^CallSideEffect : ~m2303_13 -# 2303| m2303_35(unknown) = Chi : total:m2303_13, partial:m2303_34 -# 2303| v2303_36(void) = ^IndirectReadSideEffect[-1] : &:r2303_31, ~m2303_35 -# 2303| m2303_37(String) = ^IndirectMayWriteSideEffect[-1] : &:r2303_31 -# 2303| m2303_38(unknown) = Chi : total:m2303_35, partial:m2303_37 -# 2307| r2307_1(glval &&>) = VariableAddress[(__range)] : -# 2307| r2307_2(glval>) = VariableAddress[#temp2307:20] : -# 2307| m2307_3(vector) = Uninitialized[#temp2307:20] : &:r2307_2 -# 2307| m2307_4(unknown) = Chi : total:m2303_38, partial:m2307_3 -# 2307| r2307_5(glval) = FunctionAddress[vector] : -# 2307| r2307_6(glval) = VariableAddress[#temp2307:40] : -# 2307| m2307_7(String) = Uninitialized[#temp2307:40] : &:r2307_6 -# 2307| m2307_8(unknown) = Chi : total:m2307_4, partial:m2307_7 -# 2307| r2307_9(glval) = FunctionAddress[String] : -# 2307| r2307_10(glval) = StringConstant["hello"] : -# 2307| r2307_11(char *) = Convert : r2307_10 -# 2307| v2307_12(void) = Call[String] : func:r2307_9, this:r2307_6, 0:r2307_11 -# 2307| m2307_13(unknown) = ^CallSideEffect : ~m2307_8 -# 2307| m2307_14(unknown) = Chi : total:m2307_8, partial:m2307_13 -# 2307| v2307_15(void) = ^BufferReadSideEffect[0] : &:r2307_11, ~m2301_3 -# 2307| m2307_16(String) = ^IndirectMayWriteSideEffect[-1] : &:r2307_6 -# 2307| m2307_17(unknown) = Chi : total:m2307_14, partial:m2307_16 -# 2307| r2307_18(String) = Load[#temp2307:40] : &:r2307_6, ~m2307_17 -# 2307| v2307_19(void) = Call[vector] : func:r2307_5, this:r2307_2, 0:r2307_18 -# 2307| m2307_20(unknown) = ^CallSideEffect : ~m2307_17 -# 2307| m2307_21(unknown) = Chi : total:m2307_17, partial:m2307_20 -# 2307| m2307_22(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2307_2 -# 2307| m2307_23(unknown) = Chi : total:m2307_21, partial:m2307_22 -# 2307| r2307_24(glval) = CopyValue : r2307_6 -# 2307| r2307_25(glval) = FunctionAddress[~String] : -# 2307| v2307_26(void) = Call[~String] : func:r2307_25, this:r2307_24 -# 2307| m2307_27(unknown) = ^CallSideEffect : ~m2307_23 -# 2307| m2307_28(unknown) = Chi : total:m2307_23, partial:m2307_27 -# 2307| v2307_29(void) = ^IndirectReadSideEffect[-1] : &:r2307_24, ~m2307_28 -# 2307| m2307_30(String) = ^IndirectMayWriteSideEffect[-1] : &:r2307_24 -# 2307| m2307_31(unknown) = Chi : total:m2307_28, partial:m2307_30 -# 2307| r2307_32(vector &) = CopyValue : r2307_2 -# 2307| m2307_33(vector &&) = Store[(__range)] : &:r2307_1, r2307_32 -# 2307| r2307_34(glval>) = VariableAddress[(__begin)] : -# 2307| r2307_35(glval &&>) = VariableAddress[(__range)] : -# 2307| r2307_36(vector &&) = Load[(__range)] : &:r2307_35, m2307_33 -#-----| r0_1(glval>) = CopyValue : r2307_36 +# 2304| Block 3 +# 2304| r2304_31(glval) = VariableAddress[s] : +# 2304| r2304_32(glval) = FunctionAddress[~String] : +# 2304| v2304_33(void) = Call[~String] : func:r2304_32, this:r2304_31 +# 2304| m2304_34(unknown) = ^CallSideEffect : ~m2304_13 +# 2304| m2304_35(unknown) = Chi : total:m2304_13, partial:m2304_34 +# 2304| v2304_36(void) = ^IndirectReadSideEffect[-1] : &:r2304_31, ~m2304_35 +# 2304| m2304_37(String) = ^IndirectMayWriteSideEffect[-1] : &:r2304_31 +# 2304| m2304_38(unknown) = Chi : total:m2304_35, partial:m2304_37 +# 2308| r2308_1(glval &&>) = VariableAddress[(__range)] : +# 2308| r2308_2(glval>) = VariableAddress[#temp2308:20] : +# 2308| m2308_3(vector) = Uninitialized[#temp2308:20] : &:r2308_2 +# 2308| m2308_4(unknown) = Chi : total:m2304_38, partial:m2308_3 +# 2308| r2308_5(glval) = FunctionAddress[vector] : +# 2308| r2308_6(glval) = VariableAddress[#temp2308:40] : +# 2308| m2308_7(String) = Uninitialized[#temp2308:40] : &:r2308_6 +# 2308| m2308_8(unknown) = Chi : total:m2308_4, partial:m2308_7 +# 2308| r2308_9(glval) = FunctionAddress[String] : +# 2308| r2308_10(glval) = StringConstant["hello"] : +# 2308| r2308_11(char *) = Convert : r2308_10 +# 2308| v2308_12(void) = Call[String] : func:r2308_9, this:r2308_6, 0:r2308_11 +# 2308| m2308_13(unknown) = ^CallSideEffect : ~m2308_8 +# 2308| m2308_14(unknown) = Chi : total:m2308_8, partial:m2308_13 +# 2308| v2308_15(void) = ^BufferReadSideEffect[0] : &:r2308_11, ~m2302_3 +# 2308| m2308_16(String) = ^IndirectMayWriteSideEffect[-1] : &:r2308_6 +# 2308| m2308_17(unknown) = Chi : total:m2308_14, partial:m2308_16 +# 2308| r2308_18(String) = Load[#temp2308:40] : &:r2308_6, ~m2308_17 +# 2308| v2308_19(void) = Call[vector] : func:r2308_5, this:r2308_2, 0:r2308_18 +# 2308| m2308_20(unknown) = ^CallSideEffect : ~m2308_17 +# 2308| m2308_21(unknown) = Chi : total:m2308_17, partial:m2308_20 +# 2308| m2308_22(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2308_2 +# 2308| m2308_23(unknown) = Chi : total:m2308_21, partial:m2308_22 +# 2308| r2308_24(glval) = CopyValue : r2308_6 +# 2308| r2308_25(glval) = FunctionAddress[~String] : +# 2308| v2308_26(void) = Call[~String] : func:r2308_25, this:r2308_24 +# 2308| m2308_27(unknown) = ^CallSideEffect : ~m2308_23 +# 2308| m2308_28(unknown) = Chi : total:m2308_23, partial:m2308_27 +# 2308| v2308_29(void) = ^IndirectReadSideEffect[-1] : &:r2308_24, ~m2308_28 +# 2308| m2308_30(String) = ^IndirectMayWriteSideEffect[-1] : &:r2308_24 +# 2308| m2308_31(unknown) = Chi : total:m2308_28, partial:m2308_30 +# 2308| r2308_32(vector &) = CopyValue : r2308_2 +# 2308| m2308_33(vector &&) = Store[(__range)] : &:r2308_1, r2308_32 +# 2308| r2308_34(glval>) = VariableAddress[(__begin)] : +# 2308| r2308_35(glval &&>) = VariableAddress[(__range)] : +# 2308| r2308_36(vector &&) = Load[(__range)] : &:r2308_35, m2308_33 +#-----| r0_1(glval>) = CopyValue : r2308_36 #-----| r0_2(glval>) = Convert : r0_1 -# 2307| r2307_37(glval) = FunctionAddress[begin] : -# 2307| r2307_38(iterator) = Call[begin] : func:r2307_37, this:r0_2 -#-----| v0_3(void) = ^IndirectReadSideEffect[-1] : &:r0_2, ~m2307_28 -# 2307| m2307_39(iterator) = Store[(__begin)] : &:r2307_34, r2307_38 -# 2307| r2307_40(glval>) = VariableAddress[(__end)] : -# 2307| r2307_41(glval &&>) = VariableAddress[(__range)] : -# 2307| r2307_42(vector &&) = Load[(__range)] : &:r2307_41, m2307_33 -#-----| r0_4(glval>) = CopyValue : r2307_42 +# 2308| r2308_37(glval) = FunctionAddress[begin] : +# 2308| r2308_38(iterator) = Call[begin] : func:r2308_37, this:r0_2 +#-----| v0_3(void) = ^IndirectReadSideEffect[-1] : &:r0_2, ~m2308_28 +# 2308| m2308_39(iterator) = Store[(__begin)] : &:r2308_34, r2308_38 +# 2308| r2308_40(glval>) = VariableAddress[(__end)] : +# 2308| r2308_41(glval &&>) = VariableAddress[(__range)] : +# 2308| r2308_42(vector &&) = Load[(__range)] : &:r2308_41, m2308_33 +#-----| r0_4(glval>) = CopyValue : r2308_42 #-----| r0_5(glval>) = Convert : r0_4 -# 2307| r2307_43(glval) = FunctionAddress[end] : -# 2307| r2307_44(iterator) = Call[end] : func:r2307_43, this:r0_5 -#-----| v0_6(void) = ^IndirectReadSideEffect[-1] : &:r0_5, ~m2307_28 -# 2307| m2307_45(iterator) = Store[(__end)] : &:r2307_40, r2307_44 -# 2307| m2307_46(unknown) = Chi : total:m2307_31, partial:m2307_45 +# 2308| r2308_43(glval) = FunctionAddress[end] : +# 2308| r2308_44(iterator) = Call[end] : func:r2308_43, this:r0_5 +#-----| v0_6(void) = ^IndirectReadSideEffect[-1] : &:r0_5, ~m2308_28 +# 2308| m2308_45(iterator) = Store[(__end)] : &:r2308_40, r2308_44 +# 2308| m2308_46(unknown) = Chi : total:m2308_31, partial:m2308_45 #-----| Goto -> Block 4 -# 2307| Block 4 -# 2307| m2307_47(iterator) = Phi : from 3:m2307_39, from 5:m2307_81 -# 2307| m2307_48(unknown) = Phi : from 3:~m2307_46, from 5:~m2307_89 -# 2307| r2307_49(glval>) = VariableAddress[(__begin)] : -#-----| r0_7(glval>) = Convert : r2307_49 -# 2307| r2307_50(glval) = FunctionAddress[operator!=] : +# 2308| Block 4 +# 2308| m2308_47(iterator) = Phi : from 3:m2308_39, from 5:m2308_81 +# 2308| m2308_48(unknown) = Phi : from 3:~m2308_46, from 5:~m2308_89 +# 2308| r2308_49(glval>) = VariableAddress[(__begin)] : +#-----| r0_7(glval>) = Convert : r2308_49 +# 2308| r2308_50(glval) = FunctionAddress[operator!=] : #-----| r0_8(glval>) = VariableAddress[#temp0:0] : #-----| m0_9(iterator) = Uninitialized[#temp0:0] : &:r0_8 -#-----| m0_10(unknown) = Chi : total:m2307_48, partial:m0_9 -# 2307| r2307_51(glval) = FunctionAddress[iterator] : -# 2307| r2307_52(glval>) = VariableAddress[(__end)] : -#-----| r0_11(glval>) = Convert : r2307_52 +#-----| m0_10(unknown) = Chi : total:m2308_48, partial:m0_9 +# 2308| r2308_51(glval) = FunctionAddress[iterator] : +# 2308| r2308_52(glval>) = VariableAddress[(__end)] : +#-----| r0_11(glval>) = Convert : r2308_52 #-----| r0_12(iterator &) = CopyValue : r0_11 -# 2307| v2307_53(void) = Call[iterator] : func:r2307_51, this:r0_8, 0:r0_12 -# 2307| m2307_54(unknown) = ^CallSideEffect : ~m0_10 -# 2307| m2307_55(unknown) = Chi : total:m0_10, partial:m2307_54 -#-----| v0_13(void) = ^BufferReadSideEffect[0] : &:r0_12, ~m2307_55 -# 2307| m2307_56(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_8 -# 2307| m2307_57(unknown) = Chi : total:m2307_55, partial:m2307_56 -#-----| r0_14(iterator) = Load[#temp0:0] : &:r0_8, ~m2307_57 -# 2307| r2307_58(bool) = Call[operator!=] : func:r2307_50, this:r0_7, 0:r0_14 -#-----| v0_15(void) = ^IndirectReadSideEffect[-1] : &:r0_7, m2307_47 -# 2307| v2307_59(void) = ConditionalBranch : r2307_58 +# 2308| v2308_53(void) = Call[iterator] : func:r2308_51, this:r0_8, 0:r0_12 +# 2308| m2308_54(unknown) = ^CallSideEffect : ~m0_10 +# 2308| m2308_55(unknown) = Chi : total:m0_10, partial:m2308_54 +#-----| v0_13(void) = ^BufferReadSideEffect[0] : &:r0_12, ~m2308_55 +# 2308| m2308_56(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_8 +# 2308| m2308_57(unknown) = Chi : total:m2308_55, partial:m2308_56 +#-----| r0_14(iterator) = Load[#temp0:0] : &:r0_8, ~m2308_57 +# 2308| r2308_58(bool) = Call[operator!=] : func:r2308_50, this:r0_7, 0:r0_14 +#-----| v0_15(void) = ^IndirectReadSideEffect[-1] : &:r0_7, m2308_47 +# 2308| v2308_59(void) = ConditionalBranch : r2308_58 #-----| False -> Block 6 #-----| True -> Block 5 -# 2307| Block 5 -# 2307| r2307_60(glval) = VariableAddress[s] : -# 2307| m2307_61(String) = Uninitialized[s] : &:r2307_60 -# 2307| m2307_62(unknown) = Chi : total:m2307_57, partial:m2307_61 -# 2307| r2307_63(glval) = FunctionAddress[String] : -# 2307| r2307_64(glval>) = VariableAddress[(__begin)] : -#-----| r0_16(glval>) = Convert : r2307_64 -# 2307| r2307_65(glval) = FunctionAddress[operator*] : -# 2307| r2307_66(String &) = Call[operator*] : func:r2307_65, this:r0_16 -#-----| v0_17(void) = ^IndirectReadSideEffect[-1] : &:r0_16, m2307_47 -# 2307| r2307_67(glval) = CopyValue : r2307_66 -# 2307| r2307_68(glval) = Convert : r2307_67 -# 2307| r2307_69(String &) = CopyValue : r2307_68 -# 2307| v2307_70(void) = Call[String] : func:r2307_63, this:r2307_60, 0:r2307_69 -# 2307| m2307_71(unknown) = ^CallSideEffect : ~m2307_62 -# 2307| m2307_72(unknown) = Chi : total:m2307_62, partial:m2307_71 -# 2307| v2307_73(void) = ^BufferReadSideEffect[0] : &:r2307_69, ~m2307_72 -# 2307| m2307_74(String) = ^IndirectMayWriteSideEffect[-1] : &:r2307_60 -# 2307| m2307_75(unknown) = Chi : total:m2307_72, partial:m2307_74 -# 2308| r2308_1(glval) = VariableAddress[s2] : -# 2308| m2308_2(String) = Uninitialized[s2] : &:r2308_1 -# 2308| m2308_3(unknown) = Chi : total:m2307_75, partial:m2308_2 -# 2308| r2308_4(glval) = FunctionAddress[String] : -# 2308| v2308_5(void) = Call[String] : func:r2308_4, this:r2308_1 -# 2308| m2308_6(unknown) = ^CallSideEffect : ~m2308_3 -# 2308| m2308_7(unknown) = Chi : total:m2308_3, partial:m2308_6 -# 2308| m2308_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2308_1 -# 2308| m2308_9(unknown) = Chi : total:m2308_7, partial:m2308_8 +# 2308| Block 5 +# 2308| r2308_60(glval) = VariableAddress[s] : +# 2308| m2308_61(String) = Uninitialized[s] : &:r2308_60 +# 2308| m2308_62(unknown) = Chi : total:m2308_57, partial:m2308_61 +# 2308| r2308_63(glval) = FunctionAddress[String] : +# 2308| r2308_64(glval>) = VariableAddress[(__begin)] : +#-----| r0_16(glval>) = Convert : r2308_64 +# 2308| r2308_65(glval) = FunctionAddress[operator*] : +# 2308| r2308_66(String &) = Call[operator*] : func:r2308_65, this:r0_16 +#-----| v0_17(void) = ^IndirectReadSideEffect[-1] : &:r0_16, m2308_47 +# 2308| r2308_67(glval) = CopyValue : r2308_66 +# 2308| r2308_68(glval) = Convert : r2308_67 +# 2308| r2308_69(String &) = CopyValue : r2308_68 +# 2308| v2308_70(void) = Call[String] : func:r2308_63, this:r2308_60, 0:r2308_69 +# 2308| m2308_71(unknown) = ^CallSideEffect : ~m2308_62 +# 2308| m2308_72(unknown) = Chi : total:m2308_62, partial:m2308_71 +# 2308| v2308_73(void) = ^BufferReadSideEffect[0] : &:r2308_69, ~m2308_72 +# 2308| m2308_74(String) = ^IndirectMayWriteSideEffect[-1] : &:r2308_60 +# 2308| m2308_75(unknown) = Chi : total:m2308_72, partial:m2308_74 # 2309| r2309_1(glval) = VariableAddress[s2] : -# 2309| r2309_2(glval) = FunctionAddress[~String] : -# 2309| v2309_3(void) = Call[~String] : func:r2309_2, this:r2309_1 -# 2309| m2309_4(unknown) = ^CallSideEffect : ~m2308_9 -# 2309| m2309_5(unknown) = Chi : total:m2308_9, partial:m2309_4 -# 2309| v2309_6(void) = ^IndirectReadSideEffect[-1] : &:r2309_1, ~m2309_5 -# 2309| m2309_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2309_1 -# 2309| m2309_8(unknown) = Chi : total:m2309_5, partial:m2309_7 -# 2307| r2307_76(glval>) = VariableAddress[(__begin)] : -# 2307| r2307_77(glval) = FunctionAddress[operator++] : -# 2307| r2307_78(iterator &) = Call[operator++] : func:r2307_77, this:r2307_76 -# 2307| v2307_79(void) = ^IndirectReadSideEffect[-1] : &:r2307_76, m2307_47 -# 2307| m2307_80(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2307_76 -# 2307| m2307_81(iterator) = Chi : total:m2307_47, partial:m2307_80 -# 2307| r2307_82(glval) = VariableAddress[s] : -# 2307| r2307_83(glval) = FunctionAddress[~String] : -# 2307| v2307_84(void) = Call[~String] : func:r2307_83, this:r2307_82 -# 2307| m2307_85(unknown) = ^CallSideEffect : ~m2309_8 -# 2307| m2307_86(unknown) = Chi : total:m2309_8, partial:m2307_85 -# 2307| v2307_87(void) = ^IndirectReadSideEffect[-1] : &:r2307_82, ~m2307_86 -# 2307| m2307_88(String) = ^IndirectMayWriteSideEffect[-1] : &:r2307_82 -# 2307| m2307_89(unknown) = Chi : total:m2307_86, partial:m2307_88 -# 2307| r2307_90(glval>) = CopyValue : r2307_78 +# 2309| m2309_2(String) = Uninitialized[s2] : &:r2309_1 +# 2309| m2309_3(unknown) = Chi : total:m2308_75, partial:m2309_2 +# 2309| r2309_4(glval) = FunctionAddress[String] : +# 2309| v2309_5(void) = Call[String] : func:r2309_4, this:r2309_1 +# 2309| m2309_6(unknown) = ^CallSideEffect : ~m2309_3 +# 2309| m2309_7(unknown) = Chi : total:m2309_3, partial:m2309_6 +# 2309| m2309_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2309_1 +# 2309| m2309_9(unknown) = Chi : total:m2309_7, partial:m2309_8 +# 2310| r2310_1(glval) = VariableAddress[s2] : +# 2310| r2310_2(glval) = FunctionAddress[~String] : +# 2310| v2310_3(void) = Call[~String] : func:r2310_2, this:r2310_1 +# 2310| m2310_4(unknown) = ^CallSideEffect : ~m2309_9 +# 2310| m2310_5(unknown) = Chi : total:m2309_9, partial:m2310_4 +# 2310| v2310_6(void) = ^IndirectReadSideEffect[-1] : &:r2310_1, ~m2310_5 +# 2310| m2310_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2310_1 +# 2310| m2310_8(unknown) = Chi : total:m2310_5, partial:m2310_7 +# 2308| r2308_76(glval>) = VariableAddress[(__begin)] : +# 2308| r2308_77(glval) = FunctionAddress[operator++] : +# 2308| r2308_78(iterator &) = Call[operator++] : func:r2308_77, this:r2308_76 +# 2308| v2308_79(void) = ^IndirectReadSideEffect[-1] : &:r2308_76, m2308_47 +# 2308| m2308_80(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2308_76 +# 2308| m2308_81(iterator) = Chi : total:m2308_47, partial:m2308_80 +# 2308| r2308_82(glval) = VariableAddress[s] : +# 2308| r2308_83(glval) = FunctionAddress[~String] : +# 2308| v2308_84(void) = Call[~String] : func:r2308_83, this:r2308_82 +# 2308| m2308_85(unknown) = ^CallSideEffect : ~m2310_8 +# 2308| m2308_86(unknown) = Chi : total:m2310_8, partial:m2308_85 +# 2308| v2308_87(void) = ^IndirectReadSideEffect[-1] : &:r2308_82, ~m2308_86 +# 2308| m2308_88(String) = ^IndirectMayWriteSideEffect[-1] : &:r2308_82 +# 2308| m2308_89(unknown) = Chi : total:m2308_86, partial:m2308_88 +# 2308| r2308_90(glval>) = CopyValue : r2308_78 #-----| Goto (back edge) -> Block 4 -# 2307| Block 6 -# 2307| r2307_91(glval>) = CopyValue : r2307_2 -# 2307| r2307_92(glval) = FunctionAddress[~vector] : -# 2307| v2307_93(void) = Call[~vector] : func:r2307_92, this:r2307_91 -# 2307| m2307_94(unknown) = ^CallSideEffect : ~m2307_57 -# 2307| m2307_95(unknown) = Chi : total:m2307_57, partial:m2307_94 -# 2307| v2307_96(void) = ^IndirectReadSideEffect[-1] : &:r2307_91, ~m2307_95 -# 2307| m2307_97(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2307_91 -# 2307| m2307_98(unknown) = Chi : total:m2307_95, partial:m2307_97 -# 2311| r2311_1(glval) = VariableAddress[s] : -# 2311| m2311_2(String) = Uninitialized[s] : &:r2311_1 -# 2311| m2311_3(unknown) = Chi : total:m2307_98, partial:m2311_2 -# 2311| r2311_4(glval) = FunctionAddress[String] : -# 2311| r2311_5(glval) = StringConstant["hello"] : -# 2311| r2311_6(char *) = Convert : r2311_5 -# 2311| v2311_7(void) = Call[String] : func:r2311_4, this:r2311_1, 0:r2311_6 -# 2311| m2311_8(unknown) = ^CallSideEffect : ~m2311_3 -# 2311| m2311_9(unknown) = Chi : total:m2311_3, partial:m2311_8 -# 2311| v2311_10(void) = ^BufferReadSideEffect[0] : &:r2311_6, ~m2301_3 -# 2311| m2311_11(String) = ^IndirectMayWriteSideEffect[-1] : &:r2311_1 -# 2311| m2311_12(unknown) = Chi : total:m2311_9, partial:m2311_11 -# 2311| r2311_13(glval) = VariableAddress[s2] : -# 2311| m2311_14(String) = Uninitialized[s2] : &:r2311_13 -# 2311| m2311_15(unknown) = Chi : total:m2311_12, partial:m2311_14 -# 2311| r2311_16(glval) = FunctionAddress[String] : -# 2311| r2311_17(glval) = StringConstant["world"] : -# 2311| r2311_18(char *) = Convert : r2311_17 -# 2311| v2311_19(void) = Call[String] : func:r2311_16, this:r2311_13, 0:r2311_18 -# 2311| m2311_20(unknown) = ^CallSideEffect : ~m2311_15 -# 2311| m2311_21(unknown) = Chi : total:m2311_15, partial:m2311_20 -# 2311| v2311_22(void) = ^BufferReadSideEffect[0] : &:r2311_18, ~m2301_3 -# 2311| m2311_23(String) = ^IndirectMayWriteSideEffect[-1] : &:r2311_13 -# 2311| m2311_24(unknown) = Chi : total:m2311_21, partial:m2311_23 +# 2308| Block 6 +# 2308| r2308_91(glval>) = CopyValue : r2308_2 +# 2308| r2308_92(glval) = FunctionAddress[~vector] : +# 2308| v2308_93(void) = Call[~vector] : func:r2308_92, this:r2308_91 +# 2308| m2308_94(unknown) = ^CallSideEffect : ~m2308_57 +# 2308| m2308_95(unknown) = Chi : total:m2308_57, partial:m2308_94 +# 2308| v2308_96(void) = ^IndirectReadSideEffect[-1] : &:r2308_91, ~m2308_95 +# 2308| m2308_97(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2308_91 +# 2308| m2308_98(unknown) = Chi : total:m2308_95, partial:m2308_97 +# 2312| r2312_1(glval) = VariableAddress[s] : +# 2312| m2312_2(String) = Uninitialized[s] : &:r2312_1 +# 2312| m2312_3(unknown) = Chi : total:m2308_98, partial:m2312_2 +# 2312| r2312_4(glval) = FunctionAddress[String] : +# 2312| r2312_5(glval) = StringConstant["hello"] : +# 2312| r2312_6(char *) = Convert : r2312_5 +# 2312| v2312_7(void) = Call[String] : func:r2312_4, this:r2312_1, 0:r2312_6 +# 2312| m2312_8(unknown) = ^CallSideEffect : ~m2312_3 +# 2312| m2312_9(unknown) = Chi : total:m2312_3, partial:m2312_8 +# 2312| v2312_10(void) = ^BufferReadSideEffect[0] : &:r2312_6, ~m2302_3 +# 2312| m2312_11(String) = ^IndirectMayWriteSideEffect[-1] : &:r2312_1 +# 2312| m2312_12(unknown) = Chi : total:m2312_9, partial:m2312_11 +# 2312| r2312_13(glval) = VariableAddress[s2] : +# 2312| m2312_14(String) = Uninitialized[s2] : &:r2312_13 +# 2312| m2312_15(unknown) = Chi : total:m2312_12, partial:m2312_14 +# 2312| r2312_16(glval) = FunctionAddress[String] : +# 2312| r2312_17(glval) = StringConstant["world"] : +# 2312| r2312_18(char *) = Convert : r2312_17 +# 2312| v2312_19(void) = Call[String] : func:r2312_16, this:r2312_13, 0:r2312_18 +# 2312| m2312_20(unknown) = ^CallSideEffect : ~m2312_15 +# 2312| m2312_21(unknown) = Chi : total:m2312_15, partial:m2312_20 +# 2312| v2312_22(void) = ^BufferReadSideEffect[0] : &:r2312_18, ~m2302_3 +# 2312| m2312_23(String) = ^IndirectMayWriteSideEffect[-1] : &:r2312_13 +# 2312| m2312_24(unknown) = Chi : total:m2312_21, partial:m2312_23 #-----| Goto -> Block 7 -# 2311| Block 7 -# 2311| m2311_25(unknown) = Phi : from 6:~m2311_24, from 8:~m2311_40 -# 2311| m2311_26(char) = Phi : from 6:m2303_14, from 8:m2311_42 -# 2311| r2311_27(glval) = VariableAddress[c] : -# 2311| r2311_28(char) = Load[c] : &:r2311_27, m2311_26 -# 2311| r2311_29(int) = Convert : r2311_28 -# 2311| r2311_30(int) = Constant[0] : -# 2311| r2311_31(bool) = CompareNE : r2311_29, r2311_30 -# 2311| v2311_32(void) = ConditionalBranch : r2311_31 +# 2312| Block 7 +# 2312| m2312_25(unknown) = Phi : from 6:~m2312_24, from 8:~m2312_40 +# 2312| m2312_26(char) = Phi : from 6:m2304_14, from 8:m2312_42 +# 2312| r2312_27(glval) = VariableAddress[c] : +# 2312| r2312_28(char) = Load[c] : &:r2312_27, m2312_26 +# 2312| r2312_29(int) = Convert : r2312_28 +# 2312| r2312_30(int) = Constant[0] : +# 2312| r2312_31(bool) = CompareNE : r2312_29, r2312_30 +# 2312| v2312_32(void) = ConditionalBranch : r2312_31 #-----| False -> Block 9 #-----| True -> Block 8 -# 2312| Block 8 -# 2312| r2312_1(char) = Constant[0] : -# 2312| r2312_2(glval) = VariableAddress[c] : -# 2312| m2312_3(char) = Store[c] : &:r2312_2, r2312_1 -# 2311| r2311_33(glval) = VariableAddress[s] : -# 2311| r2311_34(glval) = FunctionAddress[pop_back] : -# 2311| r2311_35(char) = Call[pop_back] : func:r2311_34, this:r2311_33 -# 2311| m2311_36(unknown) = ^CallSideEffect : ~m2311_25 -# 2311| m2311_37(unknown) = Chi : total:m2311_25, partial:m2311_36 -# 2311| v2311_38(void) = ^IndirectReadSideEffect[-1] : &:r2311_33, ~m2311_37 -# 2311| m2311_39(String) = ^IndirectMayWriteSideEffect[-1] : &:r2311_33 -# 2311| m2311_40(unknown) = Chi : total:m2311_37, partial:m2311_39 -# 2311| r2311_41(glval) = VariableAddress[c] : -# 2311| m2311_42(char) = Store[c] : &:r2311_41, r2311_35 +# 2313| Block 8 +# 2313| r2313_1(char) = Constant[0] : +# 2313| r2313_2(glval) = VariableAddress[c] : +# 2313| m2313_3(char) = Store[c] : &:r2313_2, r2313_1 +# 2312| r2312_33(glval) = VariableAddress[s] : +# 2312| r2312_34(glval) = FunctionAddress[pop_back] : +# 2312| r2312_35(char) = Call[pop_back] : func:r2312_34, this:r2312_33 +# 2312| m2312_36(unknown) = ^CallSideEffect : ~m2312_25 +# 2312| m2312_37(unknown) = Chi : total:m2312_25, partial:m2312_36 +# 2312| v2312_38(void) = ^IndirectReadSideEffect[-1] : &:r2312_33, ~m2312_37 +# 2312| m2312_39(String) = ^IndirectMayWriteSideEffect[-1] : &:r2312_33 +# 2312| m2312_40(unknown) = Chi : total:m2312_37, partial:m2312_39 +# 2312| r2312_41(glval) = VariableAddress[c] : +# 2312| m2312_42(char) = Store[c] : &:r2312_41, r2312_35 #-----| Goto (back edge) -> Block 7 -# 2311| Block 9 -# 2311| r2311_43(glval) = VariableAddress[s2] : -# 2311| r2311_44(glval) = FunctionAddress[~String] : -# 2311| v2311_45(void) = Call[~String] : func:r2311_44, this:r2311_43 -# 2311| m2311_46(unknown) = ^CallSideEffect : ~m2311_25 -# 2311| m2311_47(unknown) = Chi : total:m2311_25, partial:m2311_46 -# 2311| v2311_48(void) = ^IndirectReadSideEffect[-1] : &:r2311_43, ~m2311_47 -# 2311| m2311_49(String) = ^IndirectMayWriteSideEffect[-1] : &:r2311_43 -# 2311| m2311_50(unknown) = Chi : total:m2311_47, partial:m2311_49 -# 2311| r2311_51(glval) = VariableAddress[s] : -# 2311| r2311_52(glval) = FunctionAddress[~String] : -# 2311| v2311_53(void) = Call[~String] : func:r2311_52, this:r2311_51 -# 2311| m2311_54(unknown) = ^CallSideEffect : ~m2311_50 -# 2311| m2311_55(unknown) = Chi : total:m2311_50, partial:m2311_54 -# 2311| v2311_56(void) = ^IndirectReadSideEffect[-1] : &:r2311_51, ~m2311_55 -# 2311| m2311_57(String) = ^IndirectMayWriteSideEffect[-1] : &:r2311_51 -# 2311| m2311_58(unknown) = Chi : total:m2311_55, partial:m2311_57 -# 2314| v2314_1(void) = NoOp : -# 2301| v2301_5(void) = ReturnVoid : -# 2301| v2301_6(void) = AliasedUse : ~m2311_55 -# 2301| v2301_7(void) = ExitFunction : - -# 2316| void IfDestructors2(bool) -# 2316| Block 0 -# 2316| v2316_1(void) = EnterFunction : -# 2316| m2316_2(unknown) = AliasedDefinition : -# 2316| m2316_3(unknown) = InitializeNonLocal : -# 2316| m2316_4(unknown) = Chi : total:m2316_2, partial:m2316_3 -# 2316| r2316_5(glval) = VariableAddress[b] : -# 2316| m2316_6(bool) = InitializeParameter[b] : &:r2316_5 -# 2317| r2317_1(glval) = VariableAddress[s] : -# 2317| m2317_2(String) = Uninitialized[s] : &:r2317_1 -# 2317| m2317_3(unknown) = Chi : total:m2316_4, partial:m2317_2 -# 2317| r2317_4(glval) = FunctionAddress[String] : -# 2317| r2317_5(glval) = StringConstant["hello"] : -# 2317| r2317_6(char *) = Convert : r2317_5 -# 2317| v2317_7(void) = Call[String] : func:r2317_4, this:r2317_1, 0:r2317_6 -# 2317| m2317_8(unknown) = ^CallSideEffect : ~m2317_3 -# 2317| m2317_9(unknown) = Chi : total:m2317_3, partial:m2317_8 -# 2317| v2317_10(void) = ^BufferReadSideEffect[0] : &:r2317_6, ~m2316_3 -# 2317| m2317_11(String) = ^IndirectMayWriteSideEffect[-1] : &:r2317_1 -# 2317| m2317_12(unknown) = Chi : total:m2317_9, partial:m2317_11 -# 2317| r2317_13(glval) = VariableAddress[b] : -# 2317| r2317_14(bool) = Load[b] : &:r2317_13, m2316_6 -# 2317| v2317_15(void) = ConditionalBranch : r2317_14 +# 2312| Block 9 +# 2312| r2312_43(glval) = VariableAddress[s2] : +# 2312| r2312_44(glval) = FunctionAddress[~String] : +# 2312| v2312_45(void) = Call[~String] : func:r2312_44, this:r2312_43 +# 2312| m2312_46(unknown) = ^CallSideEffect : ~m2312_25 +# 2312| m2312_47(unknown) = Chi : total:m2312_25, partial:m2312_46 +# 2312| v2312_48(void) = ^IndirectReadSideEffect[-1] : &:r2312_43, ~m2312_47 +# 2312| m2312_49(String) = ^IndirectMayWriteSideEffect[-1] : &:r2312_43 +# 2312| m2312_50(unknown) = Chi : total:m2312_47, partial:m2312_49 +# 2312| r2312_51(glval) = VariableAddress[s] : +# 2312| r2312_52(glval) = FunctionAddress[~String] : +# 2312| v2312_53(void) = Call[~String] : func:r2312_52, this:r2312_51 +# 2312| m2312_54(unknown) = ^CallSideEffect : ~m2312_50 +# 2312| m2312_55(unknown) = Chi : total:m2312_50, partial:m2312_54 +# 2312| v2312_56(void) = ^IndirectReadSideEffect[-1] : &:r2312_51, ~m2312_55 +# 2312| m2312_57(String) = ^IndirectMayWriteSideEffect[-1] : &:r2312_51 +# 2312| m2312_58(unknown) = Chi : total:m2312_55, partial:m2312_57 +# 2315| v2315_1(void) = NoOp : +# 2302| v2302_5(void) = ReturnVoid : +# 2302| v2302_6(void) = AliasedUse : ~m2312_55 +# 2302| v2302_7(void) = ExitFunction : + +# 2317| void IfDestructors2(bool) +# 2317| Block 0 +# 2317| v2317_1(void) = EnterFunction : +# 2317| m2317_2(unknown) = AliasedDefinition : +# 2317| m2317_3(unknown) = InitializeNonLocal : +# 2317| m2317_4(unknown) = Chi : total:m2317_2, partial:m2317_3 +# 2317| r2317_5(glval) = VariableAddress[b] : +# 2317| m2317_6(bool) = InitializeParameter[b] : &:r2317_5 +# 2318| r2318_1(glval) = VariableAddress[s] : +# 2318| m2318_2(String) = Uninitialized[s] : &:r2318_1 +# 2318| m2318_3(unknown) = Chi : total:m2317_4, partial:m2318_2 +# 2318| r2318_4(glval) = FunctionAddress[String] : +# 2318| r2318_5(glval) = StringConstant["hello"] : +# 2318| r2318_6(char *) = Convert : r2318_5 +# 2318| v2318_7(void) = Call[String] : func:r2318_4, this:r2318_1, 0:r2318_6 +# 2318| m2318_8(unknown) = ^CallSideEffect : ~m2318_3 +# 2318| m2318_9(unknown) = Chi : total:m2318_3, partial:m2318_8 +# 2318| v2318_10(void) = ^BufferReadSideEffect[0] : &:r2318_6, ~m2317_3 +# 2318| m2318_11(String) = ^IndirectMayWriteSideEffect[-1] : &:r2318_1 +# 2318| m2318_12(unknown) = Chi : total:m2318_9, partial:m2318_11 +# 2318| r2318_13(glval) = VariableAddress[b] : +# 2318| r2318_14(bool) = Load[b] : &:r2318_13, m2317_6 +# 2318| v2318_15(void) = ConditionalBranch : r2318_14 #-----| False -> Block 2 #-----| True -> Block 1 -# 2318| Block 1 -# 2318| r2318_1(glval) = VariableAddress[x] : -# 2318| r2318_2(int) = Constant[0] : -# 2318| m2318_3(int) = Store[x] : &:r2318_1, r2318_2 +# 2319| Block 1 +# 2319| r2319_1(glval) = VariableAddress[x] : +# 2319| r2319_2(int) = Constant[0] : +# 2319| m2319_3(int) = Store[x] : &:r2319_1, r2319_2 #-----| Goto -> Block 3 -# 2320| Block 2 -# 2320| r2320_1(glval) = VariableAddress[y] : -# 2320| r2320_2(int) = Constant[0] : -# 2320| m2320_3(int) = Store[y] : &:r2320_1, r2320_2 +# 2321| Block 2 +# 2321| r2321_1(glval) = VariableAddress[y] : +# 2321| r2321_2(int) = Constant[0] : +# 2321| m2321_3(int) = Store[y] : &:r2321_1, r2321_2 #-----| Goto -> Block 3 -# 2321| Block 3 -# 2321| r2321_1(glval) = VariableAddress[s] : -# 2321| r2321_2(glval) = FunctionAddress[~String] : -# 2321| v2321_3(void) = Call[~String] : func:r2321_2, this:r2321_1 -# 2321| m2321_4(unknown) = ^CallSideEffect : ~m2317_12 -# 2321| m2321_5(unknown) = Chi : total:m2317_12, partial:m2321_4 -# 2321| v2321_6(void) = ^IndirectReadSideEffect[-1] : &:r2321_1, ~m2321_5 -# 2321| m2321_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2321_1 -# 2321| m2321_8(unknown) = Chi : total:m2321_5, partial:m2321_7 -# 2322| v2322_1(void) = NoOp : -# 2316| v2316_7(void) = ReturnVoid : -# 2316| v2316_8(void) = AliasedUse : ~m2321_5 -# 2316| v2316_9(void) = ExitFunction : - -# 2331| void IfDestructors3(bool) -# 2331| Block 0 -# 2331| v2331_1(void) = EnterFunction : -# 2331| m2331_2(unknown) = AliasedDefinition : -# 2331| m2331_3(unknown) = InitializeNonLocal : -# 2331| m2331_4(unknown) = Chi : total:m2331_2, partial:m2331_3 -# 2331| r2331_5(glval) = VariableAddress[b] : -# 2331| m2331_6(bool) = InitializeParameter[b] : &:r2331_5 -# 2332| r2332_1(glval) = VariableAddress[B] : -# 2332| m2332_2(Bool) = Uninitialized[B] : &:r2332_1 -# 2332| m2332_3(unknown) = Chi : total:m2331_4, partial:m2332_2 -# 2332| r2332_4(glval) = FunctionAddress[Bool] : +# 2322| Block 3 +# 2322| r2322_1(glval) = VariableAddress[s] : +# 2322| r2322_2(glval) = FunctionAddress[~String] : +# 2322| v2322_3(void) = Call[~String] : func:r2322_2, this:r2322_1 +# 2322| m2322_4(unknown) = ^CallSideEffect : ~m2318_12 +# 2322| m2322_5(unknown) = Chi : total:m2318_12, partial:m2322_4 +# 2322| v2322_6(void) = ^IndirectReadSideEffect[-1] : &:r2322_1, ~m2322_5 +# 2322| m2322_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2322_1 +# 2322| m2322_8(unknown) = Chi : total:m2322_5, partial:m2322_7 +# 2323| v2323_1(void) = NoOp : +# 2317| v2317_7(void) = ReturnVoid : +# 2317| v2317_8(void) = AliasedUse : ~m2322_5 +# 2317| v2317_9(void) = ExitFunction : + +# 2332| void IfDestructors3(bool) +# 2332| Block 0 +# 2332| v2332_1(void) = EnterFunction : +# 2332| m2332_2(unknown) = AliasedDefinition : +# 2332| m2332_3(unknown) = InitializeNonLocal : +# 2332| m2332_4(unknown) = Chi : total:m2332_2, partial:m2332_3 # 2332| r2332_5(glval) = VariableAddress[b] : -# 2332| r2332_6(bool) = Load[b] : &:r2332_5, m2331_6 -# 2332| v2332_7(void) = Call[Bool] : func:r2332_4, this:r2332_1, 0:r2332_6 -# 2332| m2332_8(unknown) = ^CallSideEffect : ~m2332_3 -# 2332| m2332_9(unknown) = Chi : total:m2332_3, partial:m2332_8 -# 2332| m2332_10(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2332_1 -# 2332| m2332_11(unknown) = Chi : total:m2332_9, partial:m2332_10 -# 2332| r2332_12(glval) = VariableAddress[B] : -# 2332| r2332_13(glval) = FunctionAddress[operator bool] : -# 2332| r2332_14(bool) = Call[operator bool] : func:r2332_13, this:r2332_12 -# 2332| m2332_15(unknown) = ^CallSideEffect : ~m2332_11 -# 2332| m2332_16(unknown) = Chi : total:m2332_11, partial:m2332_15 -# 2332| v2332_17(void) = ^IndirectReadSideEffect[-1] : &:r2332_12, ~m2332_16 -# 2332| m2332_18(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2332_12 -# 2332| m2332_19(unknown) = Chi : total:m2332_16, partial:m2332_18 -# 2332| r2332_20(bool) = CopyValue : r2332_14 -# 2332| v2332_21(void) = ConditionalBranch : r2332_20 +# 2332| m2332_6(bool) = InitializeParameter[b] : &:r2332_5 +# 2333| r2333_1(glval) = VariableAddress[B] : +# 2333| m2333_2(Bool) = Uninitialized[B] : &:r2333_1 +# 2333| m2333_3(unknown) = Chi : total:m2332_4, partial:m2333_2 +# 2333| r2333_4(glval) = FunctionAddress[Bool] : +# 2333| r2333_5(glval) = VariableAddress[b] : +# 2333| r2333_6(bool) = Load[b] : &:r2333_5, m2332_6 +# 2333| v2333_7(void) = Call[Bool] : func:r2333_4, this:r2333_1, 0:r2333_6 +# 2333| m2333_8(unknown) = ^CallSideEffect : ~m2333_3 +# 2333| m2333_9(unknown) = Chi : total:m2333_3, partial:m2333_8 +# 2333| m2333_10(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2333_1 +# 2333| m2333_11(unknown) = Chi : total:m2333_9, partial:m2333_10 +# 2333| r2333_12(glval) = VariableAddress[B] : +# 2333| r2333_13(glval) = FunctionAddress[operator bool] : +# 2333| r2333_14(bool) = Call[operator bool] : func:r2333_13, this:r2333_12 +# 2333| m2333_15(unknown) = ^CallSideEffect : ~m2333_11 +# 2333| m2333_16(unknown) = Chi : total:m2333_11, partial:m2333_15 +# 2333| v2333_17(void) = ^IndirectReadSideEffect[-1] : &:r2333_12, ~m2333_16 +# 2333| m2333_18(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2333_12 +# 2333| m2333_19(unknown) = Chi : total:m2333_16, partial:m2333_18 +# 2333| r2333_20(bool) = CopyValue : r2333_14 +# 2333| v2333_21(void) = ConditionalBranch : r2333_20 #-----| False -> Block 2 #-----| True -> Block 1 -# 2333| Block 1 -# 2333| r2333_1(glval) = VariableAddress[s1] : -# 2333| m2333_2(String) = Uninitialized[s1] : &:r2333_1 -# 2333| m2333_3(unknown) = Chi : total:m2332_19, partial:m2333_2 -# 2333| r2333_4(glval) = FunctionAddress[String] : -# 2333| v2333_5(void) = Call[String] : func:r2333_4, this:r2333_1 -# 2333| m2333_6(unknown) = ^CallSideEffect : ~m2333_3 -# 2333| m2333_7(unknown) = Chi : total:m2333_3, partial:m2333_6 -# 2333| m2333_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2333_1 -# 2333| m2333_9(unknown) = Chi : total:m2333_7, partial:m2333_8 +# 2334| Block 1 # 2334| r2334_1(glval) = VariableAddress[s1] : -# 2334| r2334_2(glval) = FunctionAddress[~String] : -# 2334| v2334_3(void) = Call[~String] : func:r2334_2, this:r2334_1 -# 2334| m2334_4(unknown) = ^CallSideEffect : ~m2333_9 -# 2334| m2334_5(unknown) = Chi : total:m2333_9, partial:m2334_4 -# 2334| v2334_6(void) = ^IndirectReadSideEffect[-1] : &:r2334_1, ~m2334_5 -# 2334| m2334_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2334_1 -# 2334| m2334_8(unknown) = Chi : total:m2334_5, partial:m2334_7 +# 2334| m2334_2(String) = Uninitialized[s1] : &:r2334_1 +# 2334| m2334_3(unknown) = Chi : total:m2333_19, partial:m2334_2 +# 2334| r2334_4(glval) = FunctionAddress[String] : +# 2334| v2334_5(void) = Call[String] : func:r2334_4, this:r2334_1 +# 2334| m2334_6(unknown) = ^CallSideEffect : ~m2334_3 +# 2334| m2334_7(unknown) = Chi : total:m2334_3, partial:m2334_6 +# 2334| m2334_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2334_1 +# 2334| m2334_9(unknown) = Chi : total:m2334_7, partial:m2334_8 +# 2335| r2335_1(glval) = VariableAddress[s1] : +# 2335| r2335_2(glval) = FunctionAddress[~String] : +# 2335| v2335_3(void) = Call[~String] : func:r2335_2, this:r2335_1 +# 2335| m2335_4(unknown) = ^CallSideEffect : ~m2334_9 +# 2335| m2335_5(unknown) = Chi : total:m2334_9, partial:m2335_4 +# 2335| v2335_6(void) = ^IndirectReadSideEffect[-1] : &:r2335_1, ~m2335_5 +# 2335| m2335_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2335_1 +# 2335| m2335_8(unknown) = Chi : total:m2335_5, partial:m2335_7 #-----| Goto -> Block 3 -# 2335| Block 2 -# 2335| r2335_1(glval) = VariableAddress[s2] : -# 2335| m2335_2(String) = Uninitialized[s2] : &:r2335_1 -# 2335| m2335_3(unknown) = Chi : total:m2332_19, partial:m2335_2 -# 2335| r2335_4(glval) = FunctionAddress[String] : -# 2335| v2335_5(void) = Call[String] : func:r2335_4, this:r2335_1 -# 2335| m2335_6(unknown) = ^CallSideEffect : ~m2335_3 -# 2335| m2335_7(unknown) = Chi : total:m2335_3, partial:m2335_6 -# 2335| m2335_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2335_1 -# 2335| m2335_9(unknown) = Chi : total:m2335_7, partial:m2335_8 +# 2336| Block 2 # 2336| r2336_1(glval) = VariableAddress[s2] : -# 2336| r2336_2(glval) = FunctionAddress[~String] : -# 2336| v2336_3(void) = Call[~String] : func:r2336_2, this:r2336_1 -# 2336| m2336_4(unknown) = ^CallSideEffect : ~m2335_9 -# 2336| m2336_5(unknown) = Chi : total:m2335_9, partial:m2336_4 -# 2336| v2336_6(void) = ^IndirectReadSideEffect[-1] : &:r2336_1, ~m2336_5 -# 2336| m2336_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2336_1 -# 2336| m2336_8(unknown) = Chi : total:m2336_5, partial:m2336_7 +# 2336| m2336_2(String) = Uninitialized[s2] : &:r2336_1 +# 2336| m2336_3(unknown) = Chi : total:m2333_19, partial:m2336_2 +# 2336| r2336_4(glval) = FunctionAddress[String] : +# 2336| v2336_5(void) = Call[String] : func:r2336_4, this:r2336_1 +# 2336| m2336_6(unknown) = ^CallSideEffect : ~m2336_3 +# 2336| m2336_7(unknown) = Chi : total:m2336_3, partial:m2336_6 +# 2336| m2336_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2336_1 +# 2336| m2336_9(unknown) = Chi : total:m2336_7, partial:m2336_8 +# 2337| r2337_1(glval) = VariableAddress[s2] : +# 2337| r2337_2(glval) = FunctionAddress[~String] : +# 2337| v2337_3(void) = Call[~String] : func:r2337_2, this:r2337_1 +# 2337| m2337_4(unknown) = ^CallSideEffect : ~m2336_9 +# 2337| m2337_5(unknown) = Chi : total:m2336_9, partial:m2337_4 +# 2337| v2337_6(void) = ^IndirectReadSideEffect[-1] : &:r2337_1, ~m2337_5 +# 2337| m2337_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2337_1 +# 2337| m2337_8(unknown) = Chi : total:m2337_5, partial:m2337_7 #-----| Goto -> Block 3 -# 2336| Block 3 -# 2336| m2336_9(unknown) = Phi : from 1:~m2334_8, from 2:~m2336_8 -# 2336| r2336_10(glval) = VariableAddress[B] : -# 2336| r2336_11(glval) = FunctionAddress[~Bool] : -# 2336| v2336_12(void) = Call[~Bool] : func:r2336_11, this:r2336_10 -# 2336| m2336_13(unknown) = ^CallSideEffect : ~m2336_9 -# 2336| m2336_14(unknown) = Chi : total:m2336_9, partial:m2336_13 -# 2336| v2336_15(void) = ^IndirectReadSideEffect[-1] : &:r2336_10, ~m2336_14 -# 2336| m2336_16(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2336_10 -# 2336| m2336_17(unknown) = Chi : total:m2336_14, partial:m2336_16 -# 2337| v2337_1(void) = NoOp : -# 2331| v2331_7(void) = ReturnVoid : -# 2331| v2331_8(void) = AliasedUse : ~m2336_14 -# 2331| v2331_9(void) = ExitFunction : - -# 2339| void WhileLoopDestructors(bool) -# 2339| Block 0 -# 2339| v2339_1(void) = EnterFunction : -# 2339| m2339_2(unknown) = AliasedDefinition : -# 2339| m2339_3(unknown) = InitializeNonLocal : -# 2339| m2339_4(unknown) = Chi : total:m2339_2, partial:m2339_3 -# 2339| r2339_5(glval) = VariableAddress[b] : -# 2339| m2339_6(bool) = InitializeParameter[b] : &:r2339_5 -# 2341| r2341_1(glval) = VariableAddress[s] : -# 2341| m2341_2(String) = Uninitialized[s] : &:r2341_1 -# 2341| m2341_3(unknown) = Chi : total:m2339_4, partial:m2341_2 -# 2341| r2341_4(glval) = FunctionAddress[String] : -# 2341| v2341_5(void) = Call[String] : func:r2341_4, this:r2341_1 -# 2341| m2341_6(unknown) = ^CallSideEffect : ~m2341_3 -# 2341| m2341_7(unknown) = Chi : total:m2341_3, partial:m2341_6 -# 2341| m2341_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2341_1 -# 2341| m2341_9(unknown) = Chi : total:m2341_7, partial:m2341_8 +# 2337| Block 3 +# 2337| m2337_9(unknown) = Phi : from 1:~m2335_8, from 2:~m2337_8 +# 2337| r2337_10(glval) = VariableAddress[B] : +# 2337| r2337_11(glval) = FunctionAddress[~Bool] : +# 2337| v2337_12(void) = Call[~Bool] : func:r2337_11, this:r2337_10 +# 2337| m2337_13(unknown) = ^CallSideEffect : ~m2337_9 +# 2337| m2337_14(unknown) = Chi : total:m2337_9, partial:m2337_13 +# 2337| v2337_15(void) = ^IndirectReadSideEffect[-1] : &:r2337_10, ~m2337_14 +# 2337| m2337_16(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2337_10 +# 2337| m2337_17(unknown) = Chi : total:m2337_14, partial:m2337_16 +# 2338| v2338_1(void) = NoOp : +# 2332| v2332_7(void) = ReturnVoid : +# 2332| v2332_8(void) = AliasedUse : ~m2337_14 +# 2332| v2332_9(void) = ExitFunction : + +# 2340| void WhileLoopDestructors(bool) +# 2340| Block 0 +# 2340| v2340_1(void) = EnterFunction : +# 2340| m2340_2(unknown) = AliasedDefinition : +# 2340| m2340_3(unknown) = InitializeNonLocal : +# 2340| m2340_4(unknown) = Chi : total:m2340_2, partial:m2340_3 +# 2340| r2340_5(glval) = VariableAddress[b] : +# 2340| m2340_6(bool) = InitializeParameter[b] : &:r2340_5 +# 2342| r2342_1(glval) = VariableAddress[s] : +# 2342| m2342_2(String) = Uninitialized[s] : &:r2342_1 +# 2342| m2342_3(unknown) = Chi : total:m2340_4, partial:m2342_2 +# 2342| r2342_4(glval) = FunctionAddress[String] : +# 2342| v2342_5(void) = Call[String] : func:r2342_4, this:r2342_1 +# 2342| m2342_6(unknown) = ^CallSideEffect : ~m2342_3 +# 2342| m2342_7(unknown) = Chi : total:m2342_3, partial:m2342_6 +# 2342| m2342_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2342_1 +# 2342| m2342_9(unknown) = Chi : total:m2342_7, partial:m2342_8 #-----| Goto -> Block 1 -# 2342| Block 1 -# 2342| m2342_1(bool) = Phi : from 0:m2339_6, from 2:m2343_3 -# 2342| r2342_2(glval) = VariableAddress[b] : -# 2342| r2342_3(bool) = Load[b] : &:r2342_2, m2342_1 -# 2342| v2342_4(void) = ConditionalBranch : r2342_3 +# 2343| Block 1 +# 2343| m2343_1(bool) = Phi : from 0:m2340_6, from 2:m2344_3 +# 2343| r2343_2(glval) = VariableAddress[b] : +# 2343| r2343_3(bool) = Load[b] : &:r2343_2, m2343_1 +# 2343| v2343_4(void) = ConditionalBranch : r2343_3 #-----| False -> Block 3 #-----| True -> Block 2 -# 2343| Block 2 -# 2343| r2343_1(bool) = Constant[0] : -# 2343| r2343_2(glval) = VariableAddress[b] : -# 2343| m2343_3(bool) = Store[b] : &:r2343_2, r2343_1 +# 2344| Block 2 +# 2344| r2344_1(bool) = Constant[0] : +# 2344| r2344_2(glval) = VariableAddress[b] : +# 2344| m2344_3(bool) = Store[b] : &:r2344_2, r2344_1 #-----| Goto (back edge) -> Block 1 -# 2345| Block 3 -# 2345| r2345_1(glval) = VariableAddress[s] : -# 2345| r2345_2(glval) = FunctionAddress[~String] : -# 2345| v2345_3(void) = Call[~String] : func:r2345_2, this:r2345_1 -# 2345| m2345_4(unknown) = ^CallSideEffect : ~m2341_9 -# 2345| m2345_5(unknown) = Chi : total:m2341_9, partial:m2345_4 -# 2345| v2345_6(void) = ^IndirectReadSideEffect[-1] : &:r2345_1, ~m2345_5 -# 2345| m2345_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2345_1 -# 2345| m2345_8(unknown) = Chi : total:m2345_5, partial:m2345_7 +# 2346| Block 3 +# 2346| r2346_1(glval) = VariableAddress[s] : +# 2346| r2346_2(glval) = FunctionAddress[~String] : +# 2346| v2346_3(void) = Call[~String] : func:r2346_2, this:r2346_1 +# 2346| m2346_4(unknown) = ^CallSideEffect : ~m2342_9 +# 2346| m2346_5(unknown) = Chi : total:m2342_9, partial:m2346_4 +# 2346| v2346_6(void) = ^IndirectReadSideEffect[-1] : &:r2346_1, ~m2346_5 +# 2346| m2346_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2346_1 +# 2346| m2346_8(unknown) = Chi : total:m2346_5, partial:m2346_7 #-----| Goto -> Block 4 -# 2348| Block 4 -# 2348| m2348_1(unknown) = Phi : from 3:~m2345_8, from 5:~m2350_8 -# 2348| m2348_2(bool) = Phi : from 3:m2342_1, from 5:m2349_3 -# 2348| r2348_3(glval) = VariableAddress[B] : -# 2348| m2348_4(Bool) = Uninitialized[B] : &:r2348_3 -# 2348| m2348_5(unknown) = Chi : total:m2348_1, partial:m2348_4 -# 2348| r2348_6(glval) = FunctionAddress[Bool] : -# 2348| r2348_7(glval) = VariableAddress[b] : -# 2348| r2348_8(bool) = Load[b] : &:r2348_7, m2348_2 -# 2348| v2348_9(void) = Call[Bool] : func:r2348_6, this:r2348_3, 0:r2348_8 -# 2348| m2348_10(unknown) = ^CallSideEffect : ~m2348_5 -# 2348| m2348_11(unknown) = Chi : total:m2348_5, partial:m2348_10 -# 2348| m2348_12(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2348_3 -# 2348| m2348_13(unknown) = Chi : total:m2348_11, partial:m2348_12 -# 2348| r2348_14(glval) = VariableAddress[B] : -# 2348| r2348_15(glval) = FunctionAddress[operator bool] : -# 2348| r2348_16(bool) = Call[operator bool] : func:r2348_15, this:r2348_14 -# 2348| m2348_17(unknown) = ^CallSideEffect : ~m2348_13 -# 2348| m2348_18(unknown) = Chi : total:m2348_13, partial:m2348_17 -# 2348| v2348_19(void) = ^IndirectReadSideEffect[-1] : &:r2348_14, ~m2348_18 -# 2348| m2348_20(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2348_14 -# 2348| m2348_21(unknown) = Chi : total:m2348_18, partial:m2348_20 -# 2348| r2348_22(bool) = CopyValue : r2348_16 -# 2348| v2348_23(void) = ConditionalBranch : r2348_22 +# 2349| Block 4 +# 2349| m2349_1(unknown) = Phi : from 3:~m2346_8, from 5:~m2351_8 +# 2349| m2349_2(bool) = Phi : from 3:m2343_1, from 5:m2350_3 +# 2349| r2349_3(glval) = VariableAddress[B] : +# 2349| m2349_4(Bool) = Uninitialized[B] : &:r2349_3 +# 2349| m2349_5(unknown) = Chi : total:m2349_1, partial:m2349_4 +# 2349| r2349_6(glval) = FunctionAddress[Bool] : +# 2349| r2349_7(glval) = VariableAddress[b] : +# 2349| r2349_8(bool) = Load[b] : &:r2349_7, m2349_2 +# 2349| v2349_9(void) = Call[Bool] : func:r2349_6, this:r2349_3, 0:r2349_8 +# 2349| m2349_10(unknown) = ^CallSideEffect : ~m2349_5 +# 2349| m2349_11(unknown) = Chi : total:m2349_5, partial:m2349_10 +# 2349| m2349_12(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2349_3 +# 2349| m2349_13(unknown) = Chi : total:m2349_11, partial:m2349_12 +# 2349| r2349_14(glval) = VariableAddress[B] : +# 2349| r2349_15(glval) = FunctionAddress[operator bool] : +# 2349| r2349_16(bool) = Call[operator bool] : func:r2349_15, this:r2349_14 +# 2349| m2349_17(unknown) = ^CallSideEffect : ~m2349_13 +# 2349| m2349_18(unknown) = Chi : total:m2349_13, partial:m2349_17 +# 2349| v2349_19(void) = ^IndirectReadSideEffect[-1] : &:r2349_14, ~m2349_18 +# 2349| m2349_20(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2349_14 +# 2349| m2349_21(unknown) = Chi : total:m2349_18, partial:m2349_20 +# 2349| r2349_22(bool) = CopyValue : r2349_16 +# 2349| v2349_23(void) = ConditionalBranch : r2349_22 #-----| False -> Block 6 #-----| True -> Block 5 -# 2349| Block 5 -# 2349| r2349_1(bool) = Constant[0] : -# 2349| r2349_2(glval) = VariableAddress[b] : -# 2349| m2349_3(bool) = Store[b] : &:r2349_2, r2349_1 -# 2350| r2350_1(glval) = VariableAddress[B] : -# 2350| r2350_2(glval) = FunctionAddress[~Bool] : -# 2350| v2350_3(void) = Call[~Bool] : func:r2350_2, this:r2350_1 -# 2350| m2350_4(unknown) = ^CallSideEffect : ~m2348_21 -# 2350| m2350_5(unknown) = Chi : total:m2348_21, partial:m2350_4 -# 2350| v2350_6(void) = ^IndirectReadSideEffect[-1] : &:r2350_1, ~m2350_5 -# 2350| m2350_7(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2350_1 -# 2350| m2350_8(unknown) = Chi : total:m2350_5, partial:m2350_7 +# 2350| Block 5 +# 2350| r2350_1(bool) = Constant[0] : +# 2350| r2350_2(glval) = VariableAddress[b] : +# 2350| m2350_3(bool) = Store[b] : &:r2350_2, r2350_1 +# 2351| r2351_1(glval) = VariableAddress[B] : +# 2351| r2351_2(glval) = FunctionAddress[~Bool] : +# 2351| v2351_3(void) = Call[~Bool] : func:r2351_2, this:r2351_1 +# 2351| m2351_4(unknown) = ^CallSideEffect : ~m2349_21 +# 2351| m2351_5(unknown) = Chi : total:m2349_21, partial:m2351_4 +# 2351| v2351_6(void) = ^IndirectReadSideEffect[-1] : &:r2351_1, ~m2351_5 +# 2351| m2351_7(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2351_1 +# 2351| m2351_8(unknown) = Chi : total:m2351_5, partial:m2351_7 #-----| Goto (back edge) -> Block 4 -# 2350| Block 6 -# 2350| r2350_9(glval) = VariableAddress[B] : -# 2350| r2350_10(glval) = FunctionAddress[~Bool] : -# 2350| v2350_11(void) = Call[~Bool] : func:r2350_10, this:r2350_9 -# 2350| m2350_12(unknown) = ^CallSideEffect : ~m2348_21 -# 2350| m2350_13(unknown) = Chi : total:m2348_21, partial:m2350_12 -# 2350| v2350_14(void) = ^IndirectReadSideEffect[-1] : &:r2350_9, ~m2350_13 -# 2350| m2350_15(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2350_9 -# 2350| m2350_16(unknown) = Chi : total:m2350_13, partial:m2350_15 -# 2352| v2352_1(void) = NoOp : -# 2339| v2339_7(void) = ReturnVoid : -# 2339| v2339_8(void) = AliasedUse : ~m2350_13 -# 2339| v2339_9(void) = ExitFunction : - -# 2354| void VoidFunc() -# 2354| Block 0 -# 2354| v2354_1(void) = EnterFunction : -# 2354| m2354_2(unknown) = AliasedDefinition : -# 2354| m2354_3(unknown) = InitializeNonLocal : -# 2354| m2354_4(unknown) = Chi : total:m2354_2, partial:m2354_3 -# 2354| v2354_5(void) = NoOp : -# 2354| v2354_6(void) = ReturnVoid : -# 2354| v2354_7(void) = AliasedUse : m2354_3 -# 2354| v2354_8(void) = ExitFunction : - -# 2356| void IfReturnDestructors(bool) -# 2356| Block 0 -# 2356| v2356_1(void) = EnterFunction : -# 2356| m2356_2(unknown) = AliasedDefinition : -# 2356| m2356_3(unknown) = InitializeNonLocal : -# 2356| m2356_4(unknown) = Chi : total:m2356_2, partial:m2356_3 -# 2356| r2356_5(glval) = VariableAddress[b] : -# 2356| m2356_6(bool) = InitializeParameter[b] : &:r2356_5 -# 2357| r2357_1(glval) = VariableAddress[s] : -# 2357| m2357_2(String) = Uninitialized[s] : &:r2357_1 -# 2357| m2357_3(unknown) = Chi : total:m2356_4, partial:m2357_2 -# 2357| r2357_4(glval) = FunctionAddress[String] : -# 2357| v2357_5(void) = Call[String] : func:r2357_4, this:r2357_1 -# 2357| m2357_6(unknown) = ^CallSideEffect : ~m2357_3 -# 2357| m2357_7(unknown) = Chi : total:m2357_3, partial:m2357_6 -# 2357| m2357_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2357_1 -# 2357| m2357_9(unknown) = Chi : total:m2357_7, partial:m2357_8 -# 2358| r2358_1(glval) = VariableAddress[b] : -# 2358| r2358_2(bool) = Load[b] : &:r2358_1, m2356_6 -# 2358| v2358_3(void) = ConditionalBranch : r2358_2 +# 2351| Block 6 +# 2351| r2351_9(glval) = VariableAddress[B] : +# 2351| r2351_10(glval) = FunctionAddress[~Bool] : +# 2351| v2351_11(void) = Call[~Bool] : func:r2351_10, this:r2351_9 +# 2351| m2351_12(unknown) = ^CallSideEffect : ~m2349_21 +# 2351| m2351_13(unknown) = Chi : total:m2349_21, partial:m2351_12 +# 2351| v2351_14(void) = ^IndirectReadSideEffect[-1] : &:r2351_9, ~m2351_13 +# 2351| m2351_15(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2351_9 +# 2351| m2351_16(unknown) = Chi : total:m2351_13, partial:m2351_15 +# 2353| v2353_1(void) = NoOp : +# 2340| v2340_7(void) = ReturnVoid : +# 2340| v2340_8(void) = AliasedUse : ~m2351_13 +# 2340| v2340_9(void) = ExitFunction : + +# 2355| void VoidFunc() +# 2355| Block 0 +# 2355| v2355_1(void) = EnterFunction : +# 2355| m2355_2(unknown) = AliasedDefinition : +# 2355| m2355_3(unknown) = InitializeNonLocal : +# 2355| m2355_4(unknown) = Chi : total:m2355_2, partial:m2355_3 +# 2355| v2355_5(void) = NoOp : +# 2355| v2355_6(void) = ReturnVoid : +# 2355| v2355_7(void) = AliasedUse : m2355_3 +# 2355| v2355_8(void) = ExitFunction : + +# 2357| void IfReturnDestructors(bool) +# 2357| Block 0 +# 2357| v2357_1(void) = EnterFunction : +# 2357| m2357_2(unknown) = AliasedDefinition : +# 2357| m2357_3(unknown) = InitializeNonLocal : +# 2357| m2357_4(unknown) = Chi : total:m2357_2, partial:m2357_3 +# 2357| r2357_5(glval) = VariableAddress[b] : +# 2357| m2357_6(bool) = InitializeParameter[b] : &:r2357_5 +# 2358| r2358_1(glval) = VariableAddress[s] : +# 2358| m2358_2(String) = Uninitialized[s] : &:r2358_1 +# 2358| m2358_3(unknown) = Chi : total:m2357_4, partial:m2358_2 +# 2358| r2358_4(glval) = FunctionAddress[String] : +# 2358| v2358_5(void) = Call[String] : func:r2358_4, this:r2358_1 +# 2358| m2358_6(unknown) = ^CallSideEffect : ~m2358_3 +# 2358| m2358_7(unknown) = Chi : total:m2358_3, partial:m2358_6 +# 2358| m2358_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2358_1 +# 2358| m2358_9(unknown) = Chi : total:m2358_7, partial:m2358_8 +# 2359| r2359_1(glval) = VariableAddress[b] : +# 2359| r2359_2(bool) = Load[b] : &:r2359_1, m2357_6 +# 2359| v2359_3(void) = ConditionalBranch : r2359_2 #-----| False -> Block 3 #-----| True -> Block 2 -# 2356| Block 1 -# 2356| m2356_7(unknown) = Phi : from 2:~m2365_8, from 4:~m2365_16, from 5:~m2365_25 -# 2356| v2356_8(void) = ReturnVoid : -# 2356| v2356_9(void) = AliasedUse : ~m2356_7 -# 2356| v2356_10(void) = ExitFunction : - -# 2359| Block 2 -# 2359| v2359_1(void) = NoOp : -# 2365| r2365_1(glval) = VariableAddress[s] : -# 2365| r2365_2(glval) = FunctionAddress[~String] : -# 2365| v2365_3(void) = Call[~String] : func:r2365_2, this:r2365_1 -# 2365| m2365_4(unknown) = ^CallSideEffect : ~m2357_9 -# 2365| m2365_5(unknown) = Chi : total:m2357_9, partial:m2365_4 -# 2365| v2365_6(void) = ^IndirectReadSideEffect[-1] : &:r2365_1, ~m2365_5 -# 2365| m2365_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2365_1 -# 2365| m2365_8(unknown) = Chi : total:m2365_5, partial:m2365_7 +# 2357| Block 1 +# 2357| m2357_7(unknown) = Phi : from 2:~m2366_8, from 4:~m2366_16, from 5:~m2366_25 +# 2357| v2357_8(void) = ReturnVoid : +# 2357| v2357_9(void) = AliasedUse : ~m2357_7 +# 2357| v2357_10(void) = ExitFunction : + +# 2360| Block 2 +# 2360| v2360_1(void) = NoOp : +# 2366| r2366_1(glval) = VariableAddress[s] : +# 2366| r2366_2(glval) = FunctionAddress[~String] : +# 2366| v2366_3(void) = Call[~String] : func:r2366_2, this:r2366_1 +# 2366| m2366_4(unknown) = ^CallSideEffect : ~m2358_9 +# 2366| m2366_5(unknown) = Chi : total:m2358_9, partial:m2366_4 +# 2366| v2366_6(void) = ^IndirectReadSideEffect[-1] : &:r2366_1, ~m2366_5 +# 2366| m2366_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2366_1 +# 2366| m2366_8(unknown) = Chi : total:m2366_5, partial:m2366_7 #-----| Goto -> Block 1 -# 2361| Block 3 -# 2361| r2361_1(glval) = VariableAddress[b] : -# 2361| r2361_2(bool) = Load[b] : &:r2361_1, m2356_6 -# 2361| v2361_3(void) = ConditionalBranch : r2361_2 +# 2362| Block 3 +# 2362| r2362_1(glval) = VariableAddress[b] : +# 2362| r2362_2(bool) = Load[b] : &:r2362_1, m2357_6 +# 2362| v2362_3(void) = ConditionalBranch : r2362_2 #-----| False -> Block 5 #-----| True -> Block 4 -# 2362| Block 4 -# 2362| r2362_1(glval) = FunctionAddress[VoidFunc] : -# 2362| v2362_2(void) = Call[VoidFunc] : func:r2362_1 -# 2362| m2362_3(unknown) = ^CallSideEffect : ~m2357_9 -# 2362| m2362_4(unknown) = Chi : total:m2357_9, partial:m2362_3 -# 2362| v2362_5(void) = NoOp : -# 2365| r2365_9(glval) = VariableAddress[s] : -# 2365| r2365_10(glval) = FunctionAddress[~String] : -# 2365| v2365_11(void) = Call[~String] : func:r2365_10, this:r2365_9 -# 2365| m2365_12(unknown) = ^CallSideEffect : ~m2362_4 -# 2365| m2365_13(unknown) = Chi : total:m2362_4, partial:m2365_12 -# 2365| v2365_14(void) = ^IndirectReadSideEffect[-1] : &:r2365_9, ~m2365_13 -# 2365| m2365_15(String) = ^IndirectMayWriteSideEffect[-1] : &:r2365_9 -# 2365| m2365_16(unknown) = Chi : total:m2365_13, partial:m2365_15 +# 2363| Block 4 +# 2363| r2363_1(glval) = FunctionAddress[VoidFunc] : +# 2363| v2363_2(void) = Call[VoidFunc] : func:r2363_1 +# 2363| m2363_3(unknown) = ^CallSideEffect : ~m2358_9 +# 2363| m2363_4(unknown) = Chi : total:m2358_9, partial:m2363_3 +# 2363| v2363_5(void) = NoOp : +# 2366| r2366_9(glval) = VariableAddress[s] : +# 2366| r2366_10(glval) = FunctionAddress[~String] : +# 2366| v2366_11(void) = Call[~String] : func:r2366_10, this:r2366_9 +# 2366| m2366_12(unknown) = ^CallSideEffect : ~m2363_4 +# 2366| m2366_13(unknown) = Chi : total:m2363_4, partial:m2366_12 +# 2366| v2366_14(void) = ^IndirectReadSideEffect[-1] : &:r2366_9, ~m2366_13 +# 2366| m2366_15(String) = ^IndirectMayWriteSideEffect[-1] : &:r2366_9 +# 2366| m2366_16(unknown) = Chi : total:m2366_13, partial:m2366_15 #-----| Goto -> Block 1 -# 2364| Block 5 -# 2364| r2364_1(glval) = VariableAddress[s] : -# 2365| v2365_17(void) = NoOp : -# 2365| r2365_18(glval) = VariableAddress[s] : -# 2365| r2365_19(glval) = FunctionAddress[~String] : -# 2365| v2365_20(void) = Call[~String] : func:r2365_19, this:r2365_18 -# 2365| m2365_21(unknown) = ^CallSideEffect : ~m2357_9 -# 2365| m2365_22(unknown) = Chi : total:m2357_9, partial:m2365_21 -# 2365| v2365_23(void) = ^IndirectReadSideEffect[-1] : &:r2365_18, ~m2365_22 -# 2365| m2365_24(String) = ^IndirectMayWriteSideEffect[-1] : &:r2365_18 -# 2365| m2365_25(unknown) = Chi : total:m2365_22, partial:m2365_24 +# 2365| Block 5 +# 2365| r2365_1(glval) = VariableAddress[s] : +# 2366| v2366_17(void) = NoOp : +# 2366| r2366_18(glval) = VariableAddress[s] : +# 2366| r2366_19(glval) = FunctionAddress[~String] : +# 2366| v2366_20(void) = Call[~String] : func:r2366_19, this:r2366_18 +# 2366| m2366_21(unknown) = ^CallSideEffect : ~m2358_9 +# 2366| m2366_22(unknown) = Chi : total:m2358_9, partial:m2366_21 +# 2366| v2366_23(void) = ^IndirectReadSideEffect[-1] : &:r2366_18, ~m2366_22 +# 2366| m2366_24(String) = ^IndirectMayWriteSideEffect[-1] : &:r2366_18 +# 2366| m2366_25(unknown) = Chi : total:m2366_22, partial:m2366_24 #-----| Goto -> Block 1 -# 2367| int IfReturnDestructors3(bool) -# 2367| Block 0 -# 2367| v2367_1(void) = EnterFunction : -# 2367| m2367_2(unknown) = AliasedDefinition : -# 2367| m2367_3(unknown) = InitializeNonLocal : -# 2367| m2367_4(unknown) = Chi : total:m2367_2, partial:m2367_3 -# 2367| r2367_5(glval) = VariableAddress[b] : -# 2367| m2367_6(bool) = InitializeParameter[b] : &:r2367_5 -# 2368| r2368_1(glval) = VariableAddress[s] : -# 2368| m2368_2(String) = Uninitialized[s] : &:r2368_1 -# 2368| m2368_3(unknown) = Chi : total:m2367_4, partial:m2368_2 -# 2368| r2368_4(glval) = FunctionAddress[String] : -# 2368| v2368_5(void) = Call[String] : func:r2368_4, this:r2368_1 -# 2368| m2368_6(unknown) = ^CallSideEffect : ~m2368_3 -# 2368| m2368_7(unknown) = Chi : total:m2368_3, partial:m2368_6 -# 2368| m2368_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2368_1 -# 2368| m2368_9(unknown) = Chi : total:m2368_7, partial:m2368_8 -# 2369| r2369_1(glval) = VariableAddress[b] : -# 2369| r2369_2(bool) = Load[b] : &:r2369_1, m2367_6 -# 2369| v2369_3(void) = ConditionalBranch : r2369_2 +# 2368| int IfReturnDestructors3(bool) +# 2368| Block 0 +# 2368| v2368_1(void) = EnterFunction : +# 2368| m2368_2(unknown) = AliasedDefinition : +# 2368| m2368_3(unknown) = InitializeNonLocal : +# 2368| m2368_4(unknown) = Chi : total:m2368_2, partial:m2368_3 +# 2368| r2368_5(glval) = VariableAddress[b] : +# 2368| m2368_6(bool) = InitializeParameter[b] : &:r2368_5 +# 2369| r2369_1(glval) = VariableAddress[s] : +# 2369| m2369_2(String) = Uninitialized[s] : &:r2369_1 +# 2369| m2369_3(unknown) = Chi : total:m2368_4, partial:m2369_2 +# 2369| r2369_4(glval) = FunctionAddress[String] : +# 2369| v2369_5(void) = Call[String] : func:r2369_4, this:r2369_1 +# 2369| m2369_6(unknown) = ^CallSideEffect : ~m2369_3 +# 2369| m2369_7(unknown) = Chi : total:m2369_3, partial:m2369_6 +# 2369| m2369_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2369_1 +# 2369| m2369_9(unknown) = Chi : total:m2369_7, partial:m2369_8 +# 2370| r2370_1(glval) = VariableAddress[b] : +# 2370| r2370_2(bool) = Load[b] : &:r2370_1, m2368_6 +# 2370| v2370_3(void) = ConditionalBranch : r2370_2 #-----| False -> Block 3 #-----| True -> Block 2 -# 2367| Block 1 -# 2367| m2367_7(unknown) = Phi : from 2:~m2373_8, from 3:~m2373_16 -# 2367| m2367_8(int) = Phi : from 2:m2370_3, from 3:m2372_3 -# 2367| r2367_9(glval) = VariableAddress[#return] : -# 2367| v2367_10(void) = ReturnValue : &:r2367_9, m2367_8 -# 2367| v2367_11(void) = AliasedUse : ~m2367_7 -# 2367| v2367_12(void) = ExitFunction : - -# 2370| Block 2 -# 2370| r2370_1(glval) = VariableAddress[#return] : -# 2370| r2370_2(int) = Constant[1] : -# 2370| m2370_3(int) = Store[#return] : &:r2370_1, r2370_2 -# 2373| r2373_1(glval) = VariableAddress[s] : -# 2373| r2373_2(glval) = FunctionAddress[~String] : -# 2373| v2373_3(void) = Call[~String] : func:r2373_2, this:r2373_1 -# 2373| m2373_4(unknown) = ^CallSideEffect : ~m2368_9 -# 2373| m2373_5(unknown) = Chi : total:m2368_9, partial:m2373_4 -# 2373| v2373_6(void) = ^IndirectReadSideEffect[-1] : &:r2373_1, ~m2373_5 -# 2373| m2373_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2373_1 -# 2373| m2373_8(unknown) = Chi : total:m2373_5, partial:m2373_7 +# 2368| Block 1 +# 2368| m2368_7(unknown) = Phi : from 2:~m2374_8, from 3:~m2374_16 +# 2368| m2368_8(int) = Phi : from 2:m2371_3, from 3:m2373_3 +# 2368| r2368_9(glval) = VariableAddress[#return] : +# 2368| v2368_10(void) = ReturnValue : &:r2368_9, m2368_8 +# 2368| v2368_11(void) = AliasedUse : ~m2368_7 +# 2368| v2368_12(void) = ExitFunction : + +# 2371| Block 2 +# 2371| r2371_1(glval) = VariableAddress[#return] : +# 2371| r2371_2(int) = Constant[1] : +# 2371| m2371_3(int) = Store[#return] : &:r2371_1, r2371_2 +# 2374| r2374_1(glval) = VariableAddress[s] : +# 2374| r2374_2(glval) = FunctionAddress[~String] : +# 2374| v2374_3(void) = Call[~String] : func:r2374_2, this:r2374_1 +# 2374| m2374_4(unknown) = ^CallSideEffect : ~m2369_9 +# 2374| m2374_5(unknown) = Chi : total:m2369_9, partial:m2374_4 +# 2374| v2374_6(void) = ^IndirectReadSideEffect[-1] : &:r2374_1, ~m2374_5 +# 2374| m2374_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2374_1 +# 2374| m2374_8(unknown) = Chi : total:m2374_5, partial:m2374_7 #-----| Goto -> Block 1 -# 2372| Block 3 -# 2372| r2372_1(glval) = VariableAddress[#return] : -# 2372| r2372_2(int) = Constant[0] : -# 2372| m2372_3(int) = Store[#return] : &:r2372_1, r2372_2 -# 2373| r2373_9(glval) = VariableAddress[s] : -# 2373| r2373_10(glval) = FunctionAddress[~String] : -# 2373| v2373_11(void) = Call[~String] : func:r2373_10, this:r2373_9 -# 2373| m2373_12(unknown) = ^CallSideEffect : ~m2368_9 -# 2373| m2373_13(unknown) = Chi : total:m2368_9, partial:m2373_12 -# 2373| v2373_14(void) = ^IndirectReadSideEffect[-1] : &:r2373_9, ~m2373_13 -# 2373| m2373_15(String) = ^IndirectMayWriteSideEffect[-1] : &:r2373_9 -# 2373| m2373_16(unknown) = Chi : total:m2373_13, partial:m2373_15 +# 2373| Block 3 +# 2373| r2373_1(glval) = VariableAddress[#return] : +# 2373| r2373_2(int) = Constant[0] : +# 2373| m2373_3(int) = Store[#return] : &:r2373_1, r2373_2 +# 2374| r2374_9(glval) = VariableAddress[s] : +# 2374| r2374_10(glval) = FunctionAddress[~String] : +# 2374| v2374_11(void) = Call[~String] : func:r2374_10, this:r2374_9 +# 2374| m2374_12(unknown) = ^CallSideEffect : ~m2369_9 +# 2374| m2374_13(unknown) = Chi : total:m2369_9, partial:m2374_12 +# 2374| v2374_14(void) = ^IndirectReadSideEffect[-1] : &:r2374_9, ~m2374_13 +# 2374| m2374_15(String) = ^IndirectMayWriteSideEffect[-1] : &:r2374_9 +# 2374| m2374_16(unknown) = Chi : total:m2374_13, partial:m2374_15 #-----| Goto -> Block 1 -# 2375| void VoidReturnDestructors() -# 2375| Block 0 -# 2375| v2375_1(void) = EnterFunction : -# 2375| m2375_2(unknown) = AliasedDefinition : -# 2375| m2375_3(unknown) = InitializeNonLocal : -# 2375| m2375_4(unknown) = Chi : total:m2375_2, partial:m2375_3 -# 2376| r2376_1(glval) = VariableAddress[s] : -# 2376| m2376_2(String) = Uninitialized[s] : &:r2376_1 -# 2376| m2376_3(unknown) = Chi : total:m2375_4, partial:m2376_2 -# 2376| r2376_4(glval) = FunctionAddress[String] : -# 2376| v2376_5(void) = Call[String] : func:r2376_4, this:r2376_1 -# 2376| m2376_6(unknown) = ^CallSideEffect : ~m2376_3 -# 2376| m2376_7(unknown) = Chi : total:m2376_3, partial:m2376_6 -# 2376| m2376_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2376_1 -# 2376| m2376_9(unknown) = Chi : total:m2376_7, partial:m2376_8 -# 2377| r2377_1(glval) = FunctionAddress[VoidFunc] : -# 2377| v2377_2(void) = Call[VoidFunc] : func:r2377_1 -# 2377| m2377_3(unknown) = ^CallSideEffect : ~m2376_9 -# 2377| m2377_4(unknown) = Chi : total:m2376_9, partial:m2377_3 -# 2377| v2377_5(void) = NoOp : -# 2378| r2378_1(glval) = VariableAddress[s] : -# 2378| r2378_2(glval) = FunctionAddress[~String] : -# 2378| v2378_3(void) = Call[~String] : func:r2378_2, this:r2378_1 -# 2378| m2378_4(unknown) = ^CallSideEffect : ~m2377_4 -# 2378| m2378_5(unknown) = Chi : total:m2377_4, partial:m2378_4 -# 2378| v2378_6(void) = ^IndirectReadSideEffect[-1] : &:r2378_1, ~m2378_5 -# 2378| m2378_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2378_1 -# 2378| m2378_8(unknown) = Chi : total:m2378_5, partial:m2378_7 -# 2375| v2375_5(void) = ReturnVoid : -# 2375| v2375_6(void) = AliasedUse : ~m2378_5 -# 2375| v2375_7(void) = ExitFunction : - -# 2388| return_routine_type::VoidToIntMemberFunc return_routine_type::GetVoidToIntFunc() -# 2388| Block 0 -# 2388| v2388_1(void) = EnterFunction : -# 2388| m2388_2(unknown) = AliasedDefinition : -# 2388| m2388_3(unknown) = InitializeNonLocal : -# 2388| m2388_4(unknown) = Chi : total:m2388_2, partial:m2388_3 -# 2390| r2390_1(glval<..:: *>) = VariableAddress[#return] : -# 2390| r2390_2(..()(..)) = FunctionAddress[VoidToInt] : -# 2390| m2390_3(..:: *) = Store[#return] : &:r2390_1, r2390_2 -# 2388| r2388_5(glval<..:: *>) = VariableAddress[#return] : -# 2388| v2388_6(void) = ReturnValue : &:r2388_5, m2390_3 -# 2388| v2388_7(void) = AliasedUse : m2388_3 -# 2388| v2388_8(void) = ExitFunction : - -# 2395| int small_operation_should_not_be_constant_folded() -# 2395| Block 0 -# 2395| v2395_1(void) = EnterFunction : -# 2395| m2395_2(unknown) = AliasedDefinition : -# 2395| m2395_3(unknown) = InitializeNonLocal : -# 2395| m2395_4(unknown) = Chi : total:m2395_2, partial:m2395_3 -# 2396| r2396_1(glval) = VariableAddress[#return] : -# 2396| r2396_2(int) = Constant[1] : -# 2396| r2396_3(int) = Constant[2] : -# 2396| r2396_4(int) = BitXor : r2396_2, r2396_3 -# 2396| m2396_5(int) = Store[#return] : &:r2396_1, r2396_4 -# 2395| r2395_5(glval) = VariableAddress[#return] : -# 2395| v2395_6(void) = ReturnValue : &:r2395_5, m2396_5 -# 2395| v2395_7(void) = AliasedUse : m2395_3 -# 2395| v2395_8(void) = ExitFunction : - -# 2406| int large_operation_should_be_constant_folded() -# 2406| Block 0 -# 2406| v2406_1(void) = EnterFunction : -# 2406| m2406_2(unknown) = AliasedDefinition : -# 2406| m2406_3(unknown) = InitializeNonLocal : -# 2406| m2406_4(unknown) = Chi : total:m2406_2, partial:m2406_3 -# 2407| r2407_1(glval) = VariableAddress[#return] : -# 2407| r2407_2(int) = Constant[0] : -# 2407| m2407_3(int) = Store[#return] : &:r2407_1, r2407_2 -# 2406| r2406_5(glval) = VariableAddress[#return] : -# 2406| v2406_6(void) = ReturnValue : &:r2406_5, m2407_3 -# 2406| v2406_7(void) = AliasedUse : m2406_3 -# 2406| v2406_8(void) = ExitFunction : - -# 2410| void initialization_with_temp_destructor() -# 2410| Block 0 -# 2410| v2410_1(void) = EnterFunction : -# 2410| m2410_2(unknown) = AliasedDefinition : -# 2410| m2410_3(unknown) = InitializeNonLocal : -# 2410| m2410_4(unknown) = Chi : total:m2410_2, partial:m2410_3 -# 2411| r2411_1(glval) = VariableAddress[x] : -# 2411| r2411_2(glval) = VariableAddress[#temp2411:18] : -# 2411| m2411_3(ClassWithDestructor) = Uninitialized[#temp2411:18] : &:r2411_2 -# 2411| r2411_4(glval) = FunctionAddress[ClassWithDestructor] : -# 2411| v2411_5(void) = Call[ClassWithDestructor] : func:r2411_4, this:r2411_2 -# 2411| m2411_6(unknown) = ^CallSideEffect : ~m2410_4 -# 2411| m2411_7(unknown) = Chi : total:m2410_4, partial:m2411_6 -# 2411| m2411_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2411_2 -# 2411| m2411_9(ClassWithDestructor) = Chi : total:m2411_3, partial:m2411_8 -# 2411| r2411_10(glval) = FunctionAddress[get_x] : -# 2411| r2411_11(char) = Call[get_x] : func:r2411_10, this:r2411_2 -# 2411| m2411_12(unknown) = ^CallSideEffect : ~m2411_7 -# 2411| m2411_13(unknown) = Chi : total:m2411_7, partial:m2411_12 -# 2411| v2411_14(void) = ^IndirectReadSideEffect[-1] : &:r2411_2, m2411_9 -# 2411| m2411_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2411_2 -# 2411| m2411_16(ClassWithDestructor) = Chi : total:m2411_9, partial:m2411_15 -# 2411| r2411_17(glval) = CopyValue : r2411_2 -# 2411| r2411_18(glval) = FunctionAddress[~ClassWithDestructor] : -# 2411| v2411_19(void) = Call[~ClassWithDestructor] : func:r2411_18, this:r2411_17 -# 2411| m2411_20(unknown) = ^CallSideEffect : ~m2411_13 -# 2411| m2411_21(unknown) = Chi : total:m2411_13, partial:m2411_20 -# 2411| v2411_22(void) = ^IndirectReadSideEffect[-1] : &:r2411_17, m2411_16 -# 2411| m2411_23(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2411_17 -# 2411| m2411_24(ClassWithDestructor) = Chi : total:m2411_16, partial:m2411_23 -# 2411| m2411_25(char) = Store[x] : &:r2411_1, r2411_11 -# 2411| r2411_26(glval) = VariableAddress[x] : -# 2411| r2411_27(char) = Load[x] : &:r2411_26, m2411_25 -# 2411| r2411_28(char) = Constant[0] : -# 2411| r2411_29(bool) = CompareNE : r2411_27, r2411_28 -# 2411| r2411_30(bool) = CopyValue : r2411_29 -# 2411| v2411_31(void) = ConditionalBranch : r2411_30 +# 2376| void VoidReturnDestructors() +# 2376| Block 0 +# 2376| v2376_1(void) = EnterFunction : +# 2376| m2376_2(unknown) = AliasedDefinition : +# 2376| m2376_3(unknown) = InitializeNonLocal : +# 2376| m2376_4(unknown) = Chi : total:m2376_2, partial:m2376_3 +# 2377| r2377_1(glval) = VariableAddress[s] : +# 2377| m2377_2(String) = Uninitialized[s] : &:r2377_1 +# 2377| m2377_3(unknown) = Chi : total:m2376_4, partial:m2377_2 +# 2377| r2377_4(glval) = FunctionAddress[String] : +# 2377| v2377_5(void) = Call[String] : func:r2377_4, this:r2377_1 +# 2377| m2377_6(unknown) = ^CallSideEffect : ~m2377_3 +# 2377| m2377_7(unknown) = Chi : total:m2377_3, partial:m2377_6 +# 2377| m2377_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r2377_1 +# 2377| m2377_9(unknown) = Chi : total:m2377_7, partial:m2377_8 +# 2378| r2378_1(glval) = FunctionAddress[VoidFunc] : +# 2378| v2378_2(void) = Call[VoidFunc] : func:r2378_1 +# 2378| m2378_3(unknown) = ^CallSideEffect : ~m2377_9 +# 2378| m2378_4(unknown) = Chi : total:m2377_9, partial:m2378_3 +# 2378| v2378_5(void) = NoOp : +# 2379| r2379_1(glval) = VariableAddress[s] : +# 2379| r2379_2(glval) = FunctionAddress[~String] : +# 2379| v2379_3(void) = Call[~String] : func:r2379_2, this:r2379_1 +# 2379| m2379_4(unknown) = ^CallSideEffect : ~m2378_4 +# 2379| m2379_5(unknown) = Chi : total:m2378_4, partial:m2379_4 +# 2379| v2379_6(void) = ^IndirectReadSideEffect[-1] : &:r2379_1, ~m2379_5 +# 2379| m2379_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2379_1 +# 2379| m2379_8(unknown) = Chi : total:m2379_5, partial:m2379_7 +# 2376| v2376_5(void) = ReturnVoid : +# 2376| v2376_6(void) = AliasedUse : ~m2379_5 +# 2376| v2376_7(void) = ExitFunction : + +# 2389| return_routine_type::VoidToIntMemberFunc return_routine_type::GetVoidToIntFunc() +# 2389| Block 0 +# 2389| v2389_1(void) = EnterFunction : +# 2389| m2389_2(unknown) = AliasedDefinition : +# 2389| m2389_3(unknown) = InitializeNonLocal : +# 2389| m2389_4(unknown) = Chi : total:m2389_2, partial:m2389_3 +# 2391| r2391_1(glval<..:: *>) = VariableAddress[#return] : +# 2391| r2391_2(..()(..)) = FunctionAddress[VoidToInt] : +# 2391| m2391_3(..:: *) = Store[#return] : &:r2391_1, r2391_2 +# 2389| r2389_5(glval<..:: *>) = VariableAddress[#return] : +# 2389| v2389_6(void) = ReturnValue : &:r2389_5, m2391_3 +# 2389| v2389_7(void) = AliasedUse : m2389_3 +# 2389| v2389_8(void) = ExitFunction : + +# 2396| int small_operation_should_not_be_constant_folded() +# 2396| Block 0 +# 2396| v2396_1(void) = EnterFunction : +# 2396| m2396_2(unknown) = AliasedDefinition : +# 2396| m2396_3(unknown) = InitializeNonLocal : +# 2396| m2396_4(unknown) = Chi : total:m2396_2, partial:m2396_3 +# 2397| r2397_1(glval) = VariableAddress[#return] : +# 2397| r2397_2(int) = Constant[1] : +# 2397| r2397_3(int) = Constant[2] : +# 2397| r2397_4(int) = BitXor : r2397_2, r2397_3 +# 2397| m2397_5(int) = Store[#return] : &:r2397_1, r2397_4 +# 2396| r2396_5(glval) = VariableAddress[#return] : +# 2396| v2396_6(void) = ReturnValue : &:r2396_5, m2397_5 +# 2396| v2396_7(void) = AliasedUse : m2396_3 +# 2396| v2396_8(void) = ExitFunction : + +# 2407| int large_operation_should_be_constant_folded() +# 2407| Block 0 +# 2407| v2407_1(void) = EnterFunction : +# 2407| m2407_2(unknown) = AliasedDefinition : +# 2407| m2407_3(unknown) = InitializeNonLocal : +# 2407| m2407_4(unknown) = Chi : total:m2407_2, partial:m2407_3 +# 2408| r2408_1(glval) = VariableAddress[#return] : +# 2408| r2408_2(int) = Constant[0] : +# 2408| m2408_3(int) = Store[#return] : &:r2408_1, r2408_2 +# 2407| r2407_5(glval) = VariableAddress[#return] : +# 2407| v2407_6(void) = ReturnValue : &:r2407_5, m2408_3 +# 2407| v2407_7(void) = AliasedUse : m2407_3 +# 2407| v2407_8(void) = ExitFunction : + +# 2411| void initialization_with_temp_destructor() +# 2411| Block 0 +# 2411| v2411_1(void) = EnterFunction : +# 2411| m2411_2(unknown) = AliasedDefinition : +# 2411| m2411_3(unknown) = InitializeNonLocal : +# 2411| m2411_4(unknown) = Chi : total:m2411_2, partial:m2411_3 +# 2412| r2412_1(glval) = VariableAddress[x] : +# 2412| r2412_2(glval) = VariableAddress[#temp2412:18] : +# 2412| m2412_3(ClassWithDestructor) = Uninitialized[#temp2412:18] : &:r2412_2 +# 2412| r2412_4(glval) = FunctionAddress[ClassWithDestructor] : +# 2412| v2412_5(void) = Call[ClassWithDestructor] : func:r2412_4, this:r2412_2 +# 2412| m2412_6(unknown) = ^CallSideEffect : ~m2411_4 +# 2412| m2412_7(unknown) = Chi : total:m2411_4, partial:m2412_6 +# 2412| m2412_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2412_2 +# 2412| m2412_9(ClassWithDestructor) = Chi : total:m2412_3, partial:m2412_8 +# 2412| r2412_10(glval) = FunctionAddress[get_x] : +# 2412| r2412_11(char) = Call[get_x] : func:r2412_10, this:r2412_2 +# 2412| m2412_12(unknown) = ^CallSideEffect : ~m2412_7 +# 2412| m2412_13(unknown) = Chi : total:m2412_7, partial:m2412_12 +# 2412| v2412_14(void) = ^IndirectReadSideEffect[-1] : &:r2412_2, m2412_9 +# 2412| m2412_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2412_2 +# 2412| m2412_16(ClassWithDestructor) = Chi : total:m2412_9, partial:m2412_15 +# 2412| r2412_17(glval) = CopyValue : r2412_2 +# 2412| r2412_18(glval) = FunctionAddress[~ClassWithDestructor] : +# 2412| v2412_19(void) = Call[~ClassWithDestructor] : func:r2412_18, this:r2412_17 +# 2412| m2412_20(unknown) = ^CallSideEffect : ~m2412_13 +# 2412| m2412_21(unknown) = Chi : total:m2412_13, partial:m2412_20 +# 2412| v2412_22(void) = ^IndirectReadSideEffect[-1] : &:r2412_17, m2412_16 +# 2412| m2412_23(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2412_17 +# 2412| m2412_24(ClassWithDestructor) = Chi : total:m2412_16, partial:m2412_23 +# 2412| m2412_25(char) = Store[x] : &:r2412_1, r2412_11 +# 2412| r2412_26(glval) = VariableAddress[x] : +# 2412| r2412_27(char) = Load[x] : &:r2412_26, m2412_25 +# 2412| r2412_28(char) = Constant[0] : +# 2412| r2412_29(bool) = CompareNE : r2412_27, r2412_28 +# 2412| r2412_30(bool) = CopyValue : r2412_29 +# 2412| v2412_31(void) = ConditionalBranch : r2412_30 #-----| False -> Block 2 #-----| True -> Block 1 -# 2412| Block 1 -# 2412| r2412_1(glval) = VariableAddress[x] : -# 2412| r2412_2(char) = Load[x] : &:r2412_1, m2411_25 -# 2412| r2412_3(char) = Constant[1] : -# 2412| r2412_4(char) = Add : r2412_2, r2412_3 -# 2412| m2412_5(char) = Store[x] : &:r2412_1, r2412_4 +# 2413| Block 1 +# 2413| r2413_1(glval) = VariableAddress[x] : +# 2413| r2413_2(char) = Load[x] : &:r2413_1, m2412_25 +# 2413| r2413_3(char) = Constant[1] : +# 2413| r2413_4(char) = Add : r2413_2, r2413_3 +# 2413| m2413_5(char) = Store[x] : &:r2413_1, r2413_4 #-----| Goto -> Block 2 -# 2414| Block 2 -# 2414| r2414_1(glval) = VariableAddress[x] : -# 2414| r2414_2(glval) = VariableAddress[#temp2414:18] : -# 2414| m2414_3(ClassWithDestructor) = Uninitialized[#temp2414:18] : &:r2414_2 -# 2414| r2414_4(glval) = FunctionAddress[ClassWithDestructor] : -# 2414| v2414_5(void) = Call[ClassWithDestructor] : func:r2414_4, this:r2414_2 -# 2414| m2414_6(unknown) = ^CallSideEffect : ~m2411_21 -# 2414| m2414_7(unknown) = Chi : total:m2411_21, partial:m2414_6 -# 2414| m2414_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2414_2 -# 2414| m2414_9(ClassWithDestructor) = Chi : total:m2414_3, partial:m2414_8 -# 2414| r2414_10(glval) = FunctionAddress[get_x] : -# 2414| r2414_11(char) = Call[get_x] : func:r2414_10, this:r2414_2 -# 2414| m2414_12(unknown) = ^CallSideEffect : ~m2414_7 -# 2414| m2414_13(unknown) = Chi : total:m2414_7, partial:m2414_12 -# 2414| v2414_14(void) = ^IndirectReadSideEffect[-1] : &:r2414_2, m2414_9 -# 2414| m2414_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2414_2 -# 2414| m2414_16(ClassWithDestructor) = Chi : total:m2414_9, partial:m2414_15 -# 2414| r2414_17(glval) = CopyValue : r2414_2 -# 2414| r2414_18(glval) = FunctionAddress[~ClassWithDestructor] : -# 2414| v2414_19(void) = Call[~ClassWithDestructor] : func:r2414_18, this:r2414_17 -# 2414| m2414_20(unknown) = ^CallSideEffect : ~m2414_13 -# 2414| m2414_21(unknown) = Chi : total:m2414_13, partial:m2414_20 -# 2414| v2414_22(void) = ^IndirectReadSideEffect[-1] : &:r2414_17, m2414_16 -# 2414| m2414_23(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2414_17 -# 2414| m2414_24(ClassWithDestructor) = Chi : total:m2414_16, partial:m2414_23 -# 2414| m2414_25(char) = Store[x] : &:r2414_1, r2414_11 -# 2414| r2414_26(glval) = VariableAddress[x] : -# 2414| r2414_27(char) = Load[x] : &:r2414_26, m2414_25 -# 2414| r2414_28(char) = Constant[0] : -# 2414| r2414_29(bool) = CompareNE : r2414_27, r2414_28 -# 2414| v2414_30(void) = ConditionalBranch : r2414_29 +# 2415| Block 2 +# 2415| r2415_1(glval) = VariableAddress[x] : +# 2415| r2415_2(glval) = VariableAddress[#temp2415:18] : +# 2415| m2415_3(ClassWithDestructor) = Uninitialized[#temp2415:18] : &:r2415_2 +# 2415| r2415_4(glval) = FunctionAddress[ClassWithDestructor] : +# 2415| v2415_5(void) = Call[ClassWithDestructor] : func:r2415_4, this:r2415_2 +# 2415| m2415_6(unknown) = ^CallSideEffect : ~m2412_21 +# 2415| m2415_7(unknown) = Chi : total:m2412_21, partial:m2415_6 +# 2415| m2415_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2415_2 +# 2415| m2415_9(ClassWithDestructor) = Chi : total:m2415_3, partial:m2415_8 +# 2415| r2415_10(glval) = FunctionAddress[get_x] : +# 2415| r2415_11(char) = Call[get_x] : func:r2415_10, this:r2415_2 +# 2415| m2415_12(unknown) = ^CallSideEffect : ~m2415_7 +# 2415| m2415_13(unknown) = Chi : total:m2415_7, partial:m2415_12 +# 2415| v2415_14(void) = ^IndirectReadSideEffect[-1] : &:r2415_2, m2415_9 +# 2415| m2415_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2415_2 +# 2415| m2415_16(ClassWithDestructor) = Chi : total:m2415_9, partial:m2415_15 +# 2415| r2415_17(glval) = CopyValue : r2415_2 +# 2415| r2415_18(glval) = FunctionAddress[~ClassWithDestructor] : +# 2415| v2415_19(void) = Call[~ClassWithDestructor] : func:r2415_18, this:r2415_17 +# 2415| m2415_20(unknown) = ^CallSideEffect : ~m2415_13 +# 2415| m2415_21(unknown) = Chi : total:m2415_13, partial:m2415_20 +# 2415| v2415_22(void) = ^IndirectReadSideEffect[-1] : &:r2415_17, m2415_16 +# 2415| m2415_23(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2415_17 +# 2415| m2415_24(ClassWithDestructor) = Chi : total:m2415_16, partial:m2415_23 +# 2415| m2415_25(char) = Store[x] : &:r2415_1, r2415_11 +# 2415| r2415_26(glval) = VariableAddress[x] : +# 2415| r2415_27(char) = Load[x] : &:r2415_26, m2415_25 +# 2415| r2415_28(char) = Constant[0] : +# 2415| r2415_29(bool) = CompareNE : r2415_27, r2415_28 +# 2415| v2415_30(void) = ConditionalBranch : r2415_29 #-----| False -> Block 4 #-----| True -> Block 3 -# 2415| Block 3 -# 2415| r2415_1(glval) = VariableAddress[x] : -# 2415| r2415_2(char) = Load[x] : &:r2415_1, m2414_25 -# 2415| r2415_3(char) = Constant[1] : -# 2415| r2415_4(char) = Add : r2415_2, r2415_3 -# 2415| m2415_5(char) = Store[x] : &:r2415_1, r2415_4 +# 2416| Block 3 +# 2416| r2416_1(glval) = VariableAddress[x] : +# 2416| r2416_2(char) = Load[x] : &:r2416_1, m2415_25 +# 2416| r2416_3(char) = Constant[1] : +# 2416| r2416_4(char) = Add : r2416_2, r2416_3 +# 2416| m2416_5(char) = Store[x] : &:r2416_1, r2416_4 #-----| Goto -> Block 4 -# 2417| Block 4 -# 2417| r2417_1(glval) = VariableAddress[x] : -# 2417| r2417_2(glval) = VariableAddress[#temp2417:28] : -# 2417| m2417_3(ClassWithDestructor) = Uninitialized[#temp2417:28] : &:r2417_2 -# 2417| r2417_4(glval) = FunctionAddress[ClassWithDestructor] : -# 2417| v2417_5(void) = Call[ClassWithDestructor] : func:r2417_4, this:r2417_2 -# 2417| m2417_6(unknown) = ^CallSideEffect : ~m2414_21 -# 2417| m2417_7(unknown) = Chi : total:m2414_21, partial:m2417_6 -# 2417| m2417_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2417_2 -# 2417| m2417_9(ClassWithDestructor) = Chi : total:m2417_3, partial:m2417_8 -# 2417| r2417_10(glval) = FunctionAddress[get_x] : -# 2417| r2417_11(char) = Call[get_x] : func:r2417_10, this:r2417_2 -# 2417| m2417_12(unknown) = ^CallSideEffect : ~m2417_7 -# 2417| m2417_13(unknown) = Chi : total:m2417_7, partial:m2417_12 -# 2417| v2417_14(void) = ^IndirectReadSideEffect[-1] : &:r2417_2, m2417_9 -# 2417| m2417_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2417_2 -# 2417| m2417_16(ClassWithDestructor) = Chi : total:m2417_9, partial:m2417_15 -# 2417| r2417_17(glval) = CopyValue : r2417_2 -# 2417| r2417_18(glval) = FunctionAddress[~ClassWithDestructor] : -# 2417| v2417_19(void) = Call[~ClassWithDestructor] : func:r2417_18, this:r2417_17 -# 2417| m2417_20(unknown) = ^CallSideEffect : ~m2417_13 -# 2417| m2417_21(unknown) = Chi : total:m2417_13, partial:m2417_20 -# 2417| v2417_22(void) = ^IndirectReadSideEffect[-1] : &:r2417_17, m2417_16 -# 2417| m2417_23(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2417_17 -# 2417| m2417_24(ClassWithDestructor) = Chi : total:m2417_16, partial:m2417_23 -# 2417| m2417_25(char) = Store[x] : &:r2417_1, r2417_11 -# 2417| r2417_26(bool) = Constant[1] : -# 2417| v2417_27(void) = ConditionalBranch : r2417_26 +# 2418| Block 4 +# 2418| r2418_1(glval) = VariableAddress[x] : +# 2418| r2418_2(glval) = VariableAddress[#temp2418:28] : +# 2418| m2418_3(ClassWithDestructor) = Uninitialized[#temp2418:28] : &:r2418_2 +# 2418| r2418_4(glval) = FunctionAddress[ClassWithDestructor] : +# 2418| v2418_5(void) = Call[ClassWithDestructor] : func:r2418_4, this:r2418_2 +# 2418| m2418_6(unknown) = ^CallSideEffect : ~m2415_21 +# 2418| m2418_7(unknown) = Chi : total:m2415_21, partial:m2418_6 +# 2418| m2418_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2418_2 +# 2418| m2418_9(ClassWithDestructor) = Chi : total:m2418_3, partial:m2418_8 +# 2418| r2418_10(glval) = FunctionAddress[get_x] : +# 2418| r2418_11(char) = Call[get_x] : func:r2418_10, this:r2418_2 +# 2418| m2418_12(unknown) = ^CallSideEffect : ~m2418_7 +# 2418| m2418_13(unknown) = Chi : total:m2418_7, partial:m2418_12 +# 2418| v2418_14(void) = ^IndirectReadSideEffect[-1] : &:r2418_2, m2418_9 +# 2418| m2418_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2418_2 +# 2418| m2418_16(ClassWithDestructor) = Chi : total:m2418_9, partial:m2418_15 +# 2418| r2418_17(glval) = CopyValue : r2418_2 +# 2418| r2418_18(glval) = FunctionAddress[~ClassWithDestructor] : +# 2418| v2418_19(void) = Call[~ClassWithDestructor] : func:r2418_18, this:r2418_17 +# 2418| m2418_20(unknown) = ^CallSideEffect : ~m2418_13 +# 2418| m2418_21(unknown) = Chi : total:m2418_13, partial:m2418_20 +# 2418| v2418_22(void) = ^IndirectReadSideEffect[-1] : &:r2418_17, m2418_16 +# 2418| m2418_23(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2418_17 +# 2418| m2418_24(ClassWithDestructor) = Chi : total:m2418_16, partial:m2418_23 +# 2418| m2418_25(char) = Store[x] : &:r2418_1, r2418_11 +# 2418| r2418_26(bool) = Constant[1] : +# 2418| v2418_27(void) = ConditionalBranch : r2418_26 #-----| False -> Block 13 #-----| True -> Block 5 -# 2418| Block 5 -# 2418| r2418_1(glval) = VariableAddress[x] : -# 2418| r2418_2(char) = Load[x] : &:r2418_1, m2417_25 -# 2418| r2418_3(char) = Constant[1] : -# 2418| r2418_4(char) = Add : r2418_2, r2418_3 -# 2418| m2418_5(char) = Store[x] : &:r2418_1, r2418_4 -# 2420| r2420_1(glval) = VariableAddress[x] : -# 2420| r2420_2(glval) = VariableAddress[#temp2420:21] : -# 2420| m2420_3(ClassWithDestructor) = Uninitialized[#temp2420:21] : &:r2420_2 -# 2420| r2420_4(glval) = FunctionAddress[ClassWithDestructor] : -# 2420| v2420_5(void) = Call[ClassWithDestructor] : func:r2420_4, this:r2420_2 -# 2420| m2420_6(unknown) = ^CallSideEffect : ~m2417_21 -# 2420| m2420_7(unknown) = Chi : total:m2417_21, partial:m2420_6 -# 2420| m2420_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2420_2 -# 2420| m2420_9(ClassWithDestructor) = Chi : total:m2420_3, partial:m2420_8 -# 2420| r2420_10(glval) = FunctionAddress[get_x] : -# 2420| r2420_11(char) = Call[get_x] : func:r2420_10, this:r2420_2 -# 2420| m2420_12(unknown) = ^CallSideEffect : ~m2420_7 -# 2420| m2420_13(unknown) = Chi : total:m2420_7, partial:m2420_12 -# 2420| v2420_14(void) = ^IndirectReadSideEffect[-1] : &:r2420_2, m2420_9 -# 2420| m2420_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2420_2 -# 2420| m2420_16(ClassWithDestructor) = Chi : total:m2420_9, partial:m2420_15 -# 2420| r2420_17(glval) = CopyValue : r2420_2 -# 2420| r2420_18(glval) = FunctionAddress[~ClassWithDestructor] : -# 2420| v2420_19(void) = Call[~ClassWithDestructor] : func:r2420_18, this:r2420_17 -# 2420| m2420_20(unknown) = ^CallSideEffect : ~m2420_13 -# 2420| m2420_21(unknown) = Chi : total:m2420_13, partial:m2420_20 -# 2420| v2420_22(void) = ^IndirectReadSideEffect[-1] : &:r2420_17, m2420_16 -# 2420| m2420_23(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2420_17 -# 2420| m2420_24(ClassWithDestructor) = Chi : total:m2420_16, partial:m2420_23 -# 2420| m2420_25(char) = Store[x] : &:r2420_1, r2420_11 -# 2420| r2420_26(glval) = VariableAddress[x] : -# 2420| r2420_27(char) = Load[x] : &:r2420_26, m2420_25 -# 2420| r2420_28(int) = Convert : r2420_27 -# 2420| r2420_29(int) = CopyValue : r2420_28 -# 2420| v2420_30(void) = Switch : r2420_29 +# 2419| Block 5 +# 2419| r2419_1(glval) = VariableAddress[x] : +# 2419| r2419_2(char) = Load[x] : &:r2419_1, m2418_25 +# 2419| r2419_3(char) = Constant[1] : +# 2419| r2419_4(char) = Add : r2419_2, r2419_3 +# 2419| m2419_5(char) = Store[x] : &:r2419_1, r2419_4 +# 2421| r2421_1(glval) = VariableAddress[x] : +# 2421| r2421_2(glval) = VariableAddress[#temp2421:21] : +# 2421| m2421_3(ClassWithDestructor) = Uninitialized[#temp2421:21] : &:r2421_2 +# 2421| r2421_4(glval) = FunctionAddress[ClassWithDestructor] : +# 2421| v2421_5(void) = Call[ClassWithDestructor] : func:r2421_4, this:r2421_2 +# 2421| m2421_6(unknown) = ^CallSideEffect : ~m2418_21 +# 2421| m2421_7(unknown) = Chi : total:m2418_21, partial:m2421_6 +# 2421| m2421_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2421_2 +# 2421| m2421_9(ClassWithDestructor) = Chi : total:m2421_3, partial:m2421_8 +# 2421| r2421_10(glval) = FunctionAddress[get_x] : +# 2421| r2421_11(char) = Call[get_x] : func:r2421_10, this:r2421_2 +# 2421| m2421_12(unknown) = ^CallSideEffect : ~m2421_7 +# 2421| m2421_13(unknown) = Chi : total:m2421_7, partial:m2421_12 +# 2421| v2421_14(void) = ^IndirectReadSideEffect[-1] : &:r2421_2, m2421_9 +# 2421| m2421_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2421_2 +# 2421| m2421_16(ClassWithDestructor) = Chi : total:m2421_9, partial:m2421_15 +# 2421| r2421_17(glval) = CopyValue : r2421_2 +# 2421| r2421_18(glval) = FunctionAddress[~ClassWithDestructor] : +# 2421| v2421_19(void) = Call[~ClassWithDestructor] : func:r2421_18, this:r2421_17 +# 2421| m2421_20(unknown) = ^CallSideEffect : ~m2421_13 +# 2421| m2421_21(unknown) = Chi : total:m2421_13, partial:m2421_20 +# 2421| v2421_22(void) = ^IndirectReadSideEffect[-1] : &:r2421_17, m2421_16 +# 2421| m2421_23(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2421_17 +# 2421| m2421_24(ClassWithDestructor) = Chi : total:m2421_16, partial:m2421_23 +# 2421| m2421_25(char) = Store[x] : &:r2421_1, r2421_11 +# 2421| r2421_26(glval) = VariableAddress[x] : +# 2421| r2421_27(char) = Load[x] : &:r2421_26, m2421_25 +# 2421| r2421_28(int) = Convert : r2421_27 +# 2421| r2421_29(int) = CopyValue : r2421_28 +# 2421| v2421_30(void) = Switch : r2421_29 #-----| Case[97] -> Block 6 #-----| Default -> Block 7 -# 2421| Block 6 -# 2421| v2421_1(void) = NoOp : -# 2422| r2422_1(glval) = VariableAddress[x] : -# 2422| r2422_2(char) = Load[x] : &:r2422_1, m2420_25 -# 2422| r2422_3(char) = Constant[1] : -# 2422| r2422_4(char) = Add : r2422_2, r2422_3 -# 2422| m2422_5(char) = Store[x] : &:r2422_1, r2422_4 +# 2422| Block 6 +# 2422| v2422_1(void) = NoOp : +# 2423| r2423_1(glval) = VariableAddress[x] : +# 2423| r2423_2(char) = Load[x] : &:r2423_1, m2421_25 +# 2423| r2423_3(char) = Constant[1] : +# 2423| r2423_4(char) = Add : r2423_2, r2423_3 +# 2423| m2423_5(char) = Store[x] : &:r2423_1, r2423_4 #-----| Goto -> Block 7 -# 2425| Block 7 -# 2425| r2425_1(glval) = VariableAddress[x] : -# 2425| r2425_2(glval) = VariableAddress[#temp2425:21] : -# 2425| m2425_3(ClassWithDestructor) = Uninitialized[#temp2425:21] : &:r2425_2 -# 2425| r2425_4(glval) = FunctionAddress[ClassWithDestructor] : -# 2425| v2425_5(void) = Call[ClassWithDestructor] : func:r2425_4, this:r2425_2 -# 2425| m2425_6(unknown) = ^CallSideEffect : ~m2420_21 -# 2425| m2425_7(unknown) = Chi : total:m2420_21, partial:m2425_6 -# 2425| m2425_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2425_2 -# 2425| m2425_9(ClassWithDestructor) = Chi : total:m2425_3, partial:m2425_8 -# 2425| r2425_10(glval) = FunctionAddress[get_x] : -# 2425| r2425_11(char) = Call[get_x] : func:r2425_10, this:r2425_2 -# 2425| m2425_12(unknown) = ^CallSideEffect : ~m2425_7 -# 2425| m2425_13(unknown) = Chi : total:m2425_7, partial:m2425_12 -# 2425| v2425_14(void) = ^IndirectReadSideEffect[-1] : &:r2425_2, m2425_9 -# 2425| m2425_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2425_2 -# 2425| m2425_16(ClassWithDestructor) = Chi : total:m2425_9, partial:m2425_15 -# 2425| r2425_17(glval) = CopyValue : r2425_2 -# 2425| r2425_18(glval) = FunctionAddress[~ClassWithDestructor] : -# 2425| v2425_19(void) = Call[~ClassWithDestructor] : func:r2425_18, this:r2425_17 -# 2425| m2425_20(unknown) = ^CallSideEffect : ~m2425_13 -# 2425| m2425_21(unknown) = Chi : total:m2425_13, partial:m2425_20 -# 2425| v2425_22(void) = ^IndirectReadSideEffect[-1] : &:r2425_17, m2425_16 -# 2425| m2425_23(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2425_17 -# 2425| m2425_24(ClassWithDestructor) = Chi : total:m2425_16, partial:m2425_23 -# 2425| m2425_25(char) = Store[x] : &:r2425_1, r2425_11 -# 2425| r2425_26(glval) = VariableAddress[x] : -# 2425| r2425_27(char) = Load[x] : &:r2425_26, m2425_25 -# 2425| r2425_28(int) = Convert : r2425_27 -# 2425| v2425_29(void) = Switch : r2425_28 +# 2426| Block 7 +# 2426| r2426_1(glval) = VariableAddress[x] : +# 2426| r2426_2(glval) = VariableAddress[#temp2426:21] : +# 2426| m2426_3(ClassWithDestructor) = Uninitialized[#temp2426:21] : &:r2426_2 +# 2426| r2426_4(glval) = FunctionAddress[ClassWithDestructor] : +# 2426| v2426_5(void) = Call[ClassWithDestructor] : func:r2426_4, this:r2426_2 +# 2426| m2426_6(unknown) = ^CallSideEffect : ~m2421_21 +# 2426| m2426_7(unknown) = Chi : total:m2421_21, partial:m2426_6 +# 2426| m2426_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2426_2 +# 2426| m2426_9(ClassWithDestructor) = Chi : total:m2426_3, partial:m2426_8 +# 2426| r2426_10(glval) = FunctionAddress[get_x] : +# 2426| r2426_11(char) = Call[get_x] : func:r2426_10, this:r2426_2 +# 2426| m2426_12(unknown) = ^CallSideEffect : ~m2426_7 +# 2426| m2426_13(unknown) = Chi : total:m2426_7, partial:m2426_12 +# 2426| v2426_14(void) = ^IndirectReadSideEffect[-1] : &:r2426_2, m2426_9 +# 2426| m2426_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2426_2 +# 2426| m2426_16(ClassWithDestructor) = Chi : total:m2426_9, partial:m2426_15 +# 2426| r2426_17(glval) = CopyValue : r2426_2 +# 2426| r2426_18(glval) = FunctionAddress[~ClassWithDestructor] : +# 2426| v2426_19(void) = Call[~ClassWithDestructor] : func:r2426_18, this:r2426_17 +# 2426| m2426_20(unknown) = ^CallSideEffect : ~m2426_13 +# 2426| m2426_21(unknown) = Chi : total:m2426_13, partial:m2426_20 +# 2426| v2426_22(void) = ^IndirectReadSideEffect[-1] : &:r2426_17, m2426_16 +# 2426| m2426_23(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2426_17 +# 2426| m2426_24(ClassWithDestructor) = Chi : total:m2426_16, partial:m2426_23 +# 2426| m2426_25(char) = Store[x] : &:r2426_1, r2426_11 +# 2426| r2426_26(glval) = VariableAddress[x] : +# 2426| r2426_27(char) = Load[x] : &:r2426_26, m2426_25 +# 2426| r2426_28(int) = Convert : r2426_27 +# 2426| v2426_29(void) = Switch : r2426_28 #-----| Case[97] -> Block 8 #-----| Default -> Block 9 -# 2426| Block 8 -# 2426| v2426_1(void) = NoOp : -# 2427| r2427_1(glval) = VariableAddress[x] : -# 2427| r2427_2(char) = Load[x] : &:r2427_1, m2425_25 -# 2427| r2427_3(char) = Constant[1] : -# 2427| r2427_4(char) = Add : r2427_2, r2427_3 -# 2427| m2427_5(char) = Store[x] : &:r2427_1, r2427_4 +# 2427| Block 8 +# 2427| v2427_1(void) = NoOp : +# 2428| r2428_1(glval) = VariableAddress[x] : +# 2428| r2428_2(char) = Load[x] : &:r2428_1, m2426_25 +# 2428| r2428_3(char) = Constant[1] : +# 2428| r2428_4(char) = Add : r2428_2, r2428_3 +# 2428| m2428_5(char) = Store[x] : &:r2428_1, r2428_4 #-----| Goto -> Block 9 -# 2430| Block 9 -# 2430| r2430_1(glval) = VariableAddress[x] : -# 2430| r2430_2(glval) = VariableAddress[#temp2430:18] : -# 2430| m2430_3(ClassWithDestructor) = Uninitialized[#temp2430:18] : &:r2430_2 -# 2430| r2430_4(glval) = FunctionAddress[ClassWithDestructor] : -# 2430| v2430_5(void) = Call[ClassWithDestructor] : func:r2430_4, this:r2430_2 -# 2430| m2430_6(unknown) = ^CallSideEffect : ~m2425_21 -# 2430| m2430_7(unknown) = Chi : total:m2425_21, partial:m2430_6 -# 2430| m2430_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2430_2 -# 2430| m2430_9(ClassWithDestructor) = Chi : total:m2430_3, partial:m2430_8 -# 2430| r2430_10(glval) = FunctionAddress[get_x] : -# 2430| r2430_11(char) = Call[get_x] : func:r2430_10, this:r2430_2 -# 2430| m2430_12(unknown) = ^CallSideEffect : ~m2430_7 -# 2430| m2430_13(unknown) = Chi : total:m2430_7, partial:m2430_12 -# 2430| v2430_14(void) = ^IndirectReadSideEffect[-1] : &:r2430_2, m2430_9 -# 2430| m2430_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2430_2 -# 2430| m2430_16(ClassWithDestructor) = Chi : total:m2430_9, partial:m2430_15 -# 2430| r2430_17(glval) = CopyValue : r2430_2 -# 2430| r2430_18(glval) = FunctionAddress[~ClassWithDestructor] : -# 2430| v2430_19(void) = Call[~ClassWithDestructor] : func:r2430_18, this:r2430_17 -# 2430| m2430_20(unknown) = ^CallSideEffect : ~m2430_13 -# 2430| m2430_21(unknown) = Chi : total:m2430_13, partial:m2430_20 -# 2430| v2430_22(void) = ^IndirectReadSideEffect[-1] : &:r2430_17, m2430_16 -# 2430| m2430_23(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2430_17 -# 2430| m2430_24(ClassWithDestructor) = Chi : total:m2430_16, partial:m2430_23 -# 2430| m2430_25(char) = Store[x] : &:r2430_1, r2430_11 -# 2430| r2430_26(glval &&>) = VariableAddress[(__range)] : -# 2430| r2430_27(glval>) = VariableAddress[#temp2430:58] : -# 2430| m2430_28(vector) = Uninitialized[#temp2430:58] : &:r2430_27 -# 2430| m2430_29(unknown) = Chi : total:m2430_21, partial:m2430_28 -# 2430| r2430_30(glval) = FunctionAddress[vector] : -# 2430| r2430_31(glval) = VariableAddress[x] : -# 2430| r2430_32(char) = Load[x] : &:r2430_31, m2430_25 -# 2430| v2430_33(void) = Call[vector] : func:r2430_30, this:r2430_27, 0:r2430_32 -# 2430| m2430_34(unknown) = ^CallSideEffect : ~m2430_29 -# 2430| m2430_35(unknown) = Chi : total:m2430_29, partial:m2430_34 -# 2430| m2430_36(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2430_27 -# 2430| m2430_37(unknown) = Chi : total:m2430_35, partial:m2430_36 -# 2430| r2430_38(vector &) = CopyValue : r2430_27 -# 2430| m2430_39(vector &&) = Store[(__range)] : &:r2430_26, r2430_38 -# 2430| r2430_40(glval>) = VariableAddress[(__begin)] : -# 2430| r2430_41(glval &&>) = VariableAddress[(__range)] : -# 2430| r2430_42(vector &&) = Load[(__range)] : &:r2430_41, m2430_39 -#-----| r0_1(glval>) = CopyValue : r2430_42 +# 2431| Block 9 +# 2431| r2431_1(glval) = VariableAddress[x] : +# 2431| r2431_2(glval) = VariableAddress[#temp2431:18] : +# 2431| m2431_3(ClassWithDestructor) = Uninitialized[#temp2431:18] : &:r2431_2 +# 2431| r2431_4(glval) = FunctionAddress[ClassWithDestructor] : +# 2431| v2431_5(void) = Call[ClassWithDestructor] : func:r2431_4, this:r2431_2 +# 2431| m2431_6(unknown) = ^CallSideEffect : ~m2426_21 +# 2431| m2431_7(unknown) = Chi : total:m2426_21, partial:m2431_6 +# 2431| m2431_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2431_2 +# 2431| m2431_9(ClassWithDestructor) = Chi : total:m2431_3, partial:m2431_8 +# 2431| r2431_10(glval) = FunctionAddress[get_x] : +# 2431| r2431_11(char) = Call[get_x] : func:r2431_10, this:r2431_2 +# 2431| m2431_12(unknown) = ^CallSideEffect : ~m2431_7 +# 2431| m2431_13(unknown) = Chi : total:m2431_7, partial:m2431_12 +# 2431| v2431_14(void) = ^IndirectReadSideEffect[-1] : &:r2431_2, m2431_9 +# 2431| m2431_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2431_2 +# 2431| m2431_16(ClassWithDestructor) = Chi : total:m2431_9, partial:m2431_15 +# 2431| r2431_17(glval) = CopyValue : r2431_2 +# 2431| r2431_18(glval) = FunctionAddress[~ClassWithDestructor] : +# 2431| v2431_19(void) = Call[~ClassWithDestructor] : func:r2431_18, this:r2431_17 +# 2431| m2431_20(unknown) = ^CallSideEffect : ~m2431_13 +# 2431| m2431_21(unknown) = Chi : total:m2431_13, partial:m2431_20 +# 2431| v2431_22(void) = ^IndirectReadSideEffect[-1] : &:r2431_17, m2431_16 +# 2431| m2431_23(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2431_17 +# 2431| m2431_24(ClassWithDestructor) = Chi : total:m2431_16, partial:m2431_23 +# 2431| m2431_25(char) = Store[x] : &:r2431_1, r2431_11 +# 2431| r2431_26(glval &&>) = VariableAddress[(__range)] : +# 2431| r2431_27(glval>) = VariableAddress[#temp2431:58] : +# 2431| m2431_28(vector) = Uninitialized[#temp2431:58] : &:r2431_27 +# 2431| m2431_29(unknown) = Chi : total:m2431_21, partial:m2431_28 +# 2431| r2431_30(glval) = FunctionAddress[vector] : +# 2431| r2431_31(glval) = VariableAddress[x] : +# 2431| r2431_32(char) = Load[x] : &:r2431_31, m2431_25 +# 2431| v2431_33(void) = Call[vector] : func:r2431_30, this:r2431_27, 0:r2431_32 +# 2431| m2431_34(unknown) = ^CallSideEffect : ~m2431_29 +# 2431| m2431_35(unknown) = Chi : total:m2431_29, partial:m2431_34 +# 2431| m2431_36(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2431_27 +# 2431| m2431_37(unknown) = Chi : total:m2431_35, partial:m2431_36 +# 2431| r2431_38(vector &) = CopyValue : r2431_27 +# 2431| m2431_39(vector &&) = Store[(__range)] : &:r2431_26, r2431_38 +# 2431| r2431_40(glval>) = VariableAddress[(__begin)] : +# 2431| r2431_41(glval &&>) = VariableAddress[(__range)] : +# 2431| r2431_42(vector &&) = Load[(__range)] : &:r2431_41, m2431_39 +#-----| r0_1(glval>) = CopyValue : r2431_42 #-----| r0_2(glval>) = Convert : r0_1 -# 2430| r2430_43(glval) = FunctionAddress[begin] : -# 2430| r2430_44(iterator) = Call[begin] : func:r2430_43, this:r0_2 -#-----| v0_3(void) = ^IndirectReadSideEffect[-1] : &:r0_2, ~m2430_37 -# 2430| m2430_45(iterator) = Store[(__begin)] : &:r2430_40, r2430_44 -# 2430| r2430_46(glval>) = VariableAddress[(__end)] : -# 2430| r2430_47(glval &&>) = VariableAddress[(__range)] : -# 2430| r2430_48(vector &&) = Load[(__range)] : &:r2430_47, m2430_39 -#-----| r0_4(glval>) = CopyValue : r2430_48 +# 2431| r2431_43(glval) = FunctionAddress[begin] : +# 2431| r2431_44(iterator) = Call[begin] : func:r2431_43, this:r0_2 +#-----| v0_3(void) = ^IndirectReadSideEffect[-1] : &:r0_2, ~m2431_37 +# 2431| m2431_45(iterator) = Store[(__begin)] : &:r2431_40, r2431_44 +# 2431| r2431_46(glval>) = VariableAddress[(__end)] : +# 2431| r2431_47(glval &&>) = VariableAddress[(__range)] : +# 2431| r2431_48(vector &&) = Load[(__range)] : &:r2431_47, m2431_39 +#-----| r0_4(glval>) = CopyValue : r2431_48 #-----| r0_5(glval>) = Convert : r0_4 -# 2430| r2430_49(glval) = FunctionAddress[end] : -# 2430| r2430_50(iterator) = Call[end] : func:r2430_49, this:r0_5 -#-----| v0_6(void) = ^IndirectReadSideEffect[-1] : &:r0_5, ~m2430_37 -# 2430| m2430_51(iterator) = Store[(__end)] : &:r2430_46, r2430_50 -# 2430| m2430_52(unknown) = Chi : total:m2430_37, partial:m2430_51 +# 2431| r2431_49(glval) = FunctionAddress[end] : +# 2431| r2431_50(iterator) = Call[end] : func:r2431_49, this:r0_5 +#-----| v0_6(void) = ^IndirectReadSideEffect[-1] : &:r0_5, ~m2431_37 +# 2431| m2431_51(iterator) = Store[(__end)] : &:r2431_46, r2431_50 +# 2431| m2431_52(unknown) = Chi : total:m2431_37, partial:m2431_51 #-----| Goto -> Block 10 -# 2430| Block 10 -# 2430| m2430_53(iterator) = Phi : from 9:m2430_45, from 11:m2430_77 -# 2430| m2430_54(unknown) = Phi : from 9:~m2430_52, from 11:~m2430_63 -# 2430| r2430_55(glval>) = VariableAddress[(__begin)] : -#-----| r0_7(glval>) = Convert : r2430_55 -# 2430| r2430_56(glval) = FunctionAddress[operator!=] : +# 2431| Block 10 +# 2431| m2431_53(iterator) = Phi : from 9:m2431_45, from 11:m2431_77 +# 2431| m2431_54(unknown) = Phi : from 9:~m2431_52, from 11:~m2431_63 +# 2431| r2431_55(glval>) = VariableAddress[(__begin)] : +#-----| r0_7(glval>) = Convert : r2431_55 +# 2431| r2431_56(glval) = FunctionAddress[operator!=] : #-----| r0_8(glval>) = VariableAddress[#temp0:0] : #-----| m0_9(iterator) = Uninitialized[#temp0:0] : &:r0_8 -#-----| m0_10(unknown) = Chi : total:m2430_54, partial:m0_9 -# 2430| r2430_57(glval) = FunctionAddress[iterator] : -# 2430| r2430_58(glval>) = VariableAddress[(__end)] : -#-----| r0_11(glval>) = Convert : r2430_58 +#-----| m0_10(unknown) = Chi : total:m2431_54, partial:m0_9 +# 2431| r2431_57(glval) = FunctionAddress[iterator] : +# 2431| r2431_58(glval>) = VariableAddress[(__end)] : +#-----| r0_11(glval>) = Convert : r2431_58 #-----| r0_12(iterator &) = CopyValue : r0_11 -# 2430| v2430_59(void) = Call[iterator] : func:r2430_57, this:r0_8, 0:r0_12 -# 2430| m2430_60(unknown) = ^CallSideEffect : ~m0_10 -# 2430| m2430_61(unknown) = Chi : total:m0_10, partial:m2430_60 -#-----| v0_13(void) = ^BufferReadSideEffect[0] : &:r0_12, ~m2430_61 -# 2430| m2430_62(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_8 -# 2430| m2430_63(unknown) = Chi : total:m2430_61, partial:m2430_62 -#-----| r0_14(iterator) = Load[#temp0:0] : &:r0_8, ~m2430_63 -# 2430| r2430_64(bool) = Call[operator!=] : func:r2430_56, this:r0_7, 0:r0_14 -#-----| v0_15(void) = ^IndirectReadSideEffect[-1] : &:r0_7, m2430_53 -# 2430| v2430_65(void) = ConditionalBranch : r2430_64 +# 2431| v2431_59(void) = Call[iterator] : func:r2431_57, this:r0_8, 0:r0_12 +# 2431| m2431_60(unknown) = ^CallSideEffect : ~m0_10 +# 2431| m2431_61(unknown) = Chi : total:m0_10, partial:m2431_60 +#-----| v0_13(void) = ^BufferReadSideEffect[0] : &:r0_12, ~m2431_61 +# 2431| m2431_62(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_8 +# 2431| m2431_63(unknown) = Chi : total:m2431_61, partial:m2431_62 +#-----| r0_14(iterator) = Load[#temp0:0] : &:r0_8, ~m2431_63 +# 2431| r2431_64(bool) = Call[operator!=] : func:r2431_56, this:r0_7, 0:r0_14 +#-----| v0_15(void) = ^IndirectReadSideEffect[-1] : &:r0_7, m2431_53 +# 2431| v2431_65(void) = ConditionalBranch : r2431_64 #-----| False -> Block 12 #-----| True -> Block 11 -# 2430| Block 11 -# 2430| r2430_66(glval) = VariableAddress[y] : -# 2430| r2430_67(glval>) = VariableAddress[(__begin)] : -#-----| r0_16(glval>) = Convert : r2430_67 -# 2430| r2430_68(glval) = FunctionAddress[operator*] : -# 2430| r2430_69(char &) = Call[operator*] : func:r2430_68, this:r0_16 -#-----| v0_17(void) = ^IndirectReadSideEffect[-1] : &:r0_16, m2430_53 -# 2430| r2430_70(char) = Load[?] : &:r2430_69, ~m2430_63 -# 2430| m2430_71(char) = Store[y] : &:r2430_66, r2430_70 -# 2431| r2431_1(glval) = VariableAddress[x] : -# 2431| r2431_2(char) = Load[x] : &:r2431_1, m2430_25 -# 2431| r2431_3(int) = Convert : r2431_2 -# 2431| r2431_4(glval) = VariableAddress[y] : -# 2431| r2431_5(char) = Load[y] : &:r2431_4, m2430_71 -# 2431| r2431_6(int) = Convert : r2431_5 -# 2431| r2431_7(int) = Add : r2431_6, r2431_3 -# 2431| r2431_8(char) = Convert : r2431_7 -# 2431| m2431_9(char) = Store[y] : &:r2431_4, r2431_8 -# 2430| r2430_72(glval>) = VariableAddress[(__begin)] : -# 2430| r2430_73(glval) = FunctionAddress[operator++] : -# 2430| r2430_74(iterator &) = Call[operator++] : func:r2430_73, this:r2430_72 -# 2430| v2430_75(void) = ^IndirectReadSideEffect[-1] : &:r2430_72, m2430_53 -# 2430| m2430_76(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2430_72 -# 2430| m2430_77(iterator) = Chi : total:m2430_53, partial:m2430_76 -# 2430| r2430_78(glval>) = CopyValue : r2430_74 +# 2431| Block 11 +# 2431| r2431_66(glval) = VariableAddress[y] : +# 2431| r2431_67(glval>) = VariableAddress[(__begin)] : +#-----| r0_16(glval>) = Convert : r2431_67 +# 2431| r2431_68(glval) = FunctionAddress[operator*] : +# 2431| r2431_69(char &) = Call[operator*] : func:r2431_68, this:r0_16 +#-----| v0_17(void) = ^IndirectReadSideEffect[-1] : &:r0_16, m2431_53 +# 2431| r2431_70(char) = Load[?] : &:r2431_69, ~m2431_63 +# 2431| m2431_71(char) = Store[y] : &:r2431_66, r2431_70 +# 2432| r2432_1(glval) = VariableAddress[x] : +# 2432| r2432_2(char) = Load[x] : &:r2432_1, m2431_25 +# 2432| r2432_3(int) = Convert : r2432_2 +# 2432| r2432_4(glval) = VariableAddress[y] : +# 2432| r2432_5(char) = Load[y] : &:r2432_4, m2431_71 +# 2432| r2432_6(int) = Convert : r2432_5 +# 2432| r2432_7(int) = Add : r2432_6, r2432_3 +# 2432| r2432_8(char) = Convert : r2432_7 +# 2432| m2432_9(char) = Store[y] : &:r2432_4, r2432_8 +# 2431| r2431_72(glval>) = VariableAddress[(__begin)] : +# 2431| r2431_73(glval) = FunctionAddress[operator++] : +# 2431| r2431_74(iterator &) = Call[operator++] : func:r2431_73, this:r2431_72 +# 2431| v2431_75(void) = ^IndirectReadSideEffect[-1] : &:r2431_72, m2431_53 +# 2431| m2431_76(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2431_72 +# 2431| m2431_77(iterator) = Chi : total:m2431_53, partial:m2431_76 +# 2431| r2431_78(glval>) = CopyValue : r2431_74 #-----| Goto (back edge) -> Block 10 -# 2430| Block 12 -# 2430| r2430_79(glval>) = CopyValue : r2430_27 -# 2430| r2430_80(glval) = FunctionAddress[~vector] : -# 2430| v2430_81(void) = Call[~vector] : func:r2430_80, this:r2430_79 -# 2430| m2430_82(unknown) = ^CallSideEffect : ~m2430_63 -# 2430| m2430_83(unknown) = Chi : total:m2430_63, partial:m2430_82 -# 2430| v2430_84(void) = ^IndirectReadSideEffect[-1] : &:r2430_79, ~m2430_83 -# 2430| m2430_85(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2430_79 -# 2430| m2430_86(unknown) = Chi : total:m2430_83, partial:m2430_85 -# 2432| v2432_1(void) = NoOp : -# 2410| v2410_5(void) = ReturnVoid : -# 2410| v2410_6(void) = AliasedUse : ~m2430_83 -# 2410| v2410_7(void) = ExitFunction : - -# 2410| Block 13 -# 2410| v2410_8(void) = Unreached : - -# 2434| void param_with_destructor_by_value(ClassWithDestructor) -# 2434| Block 0 -# 2434| v2434_1(void) = EnterFunction : -# 2434| m2434_2(unknown) = AliasedDefinition : -# 2434| m2434_3(unknown) = InitializeNonLocal : -# 2434| m2434_4(unknown) = Chi : total:m2434_2, partial:m2434_3 -# 2434| r2434_5(glval) = VariableAddress[c] : -# 2434| m2434_6(ClassWithDestructor) = InitializeParameter[c] : &:r2434_5 -# 2436| v2436_1(void) = NoOp : -# 2434| v2434_7(void) = ReturnVoid : -# 2434| v2434_8(void) = AliasedUse : m2434_3 -# 2434| v2434_9(void) = ExitFunction : - -# 2438| void param_with_destructor_by_pointer(ClassWithDestructor*) -# 2438| Block 0 -# 2438| v2438_1(void) = EnterFunction : -# 2438| m2438_2(unknown) = AliasedDefinition : -# 2438| m2438_3(unknown) = InitializeNonLocal : -# 2438| m2438_4(unknown) = Chi : total:m2438_2, partial:m2438_3 -# 2438| r2438_5(glval) = VariableAddress[c] : -# 2438| m2438_6(ClassWithDestructor *) = InitializeParameter[c] : &:r2438_5 -# 2438| r2438_7(ClassWithDestructor *) = Load[c] : &:r2438_5, m2438_6 -# 2438| m2438_8(unknown) = InitializeIndirection[c] : &:r2438_7 -# 2440| v2440_1(void) = NoOp : -# 2438| v2438_9(void) = ReturnIndirection[c] : &:r2438_7, m2438_8 -# 2438| v2438_10(void) = ReturnVoid : -# 2438| v2438_11(void) = AliasedUse : m2438_3 -# 2438| v2438_12(void) = ExitFunction : - -# 2442| void param_with_destructor_by_ref(ClassWithDestructor&) -# 2442| Block 0 -# 2442| v2442_1(void) = EnterFunction : -# 2442| m2442_2(unknown) = AliasedDefinition : -# 2442| m2442_3(unknown) = InitializeNonLocal : -# 2442| m2442_4(unknown) = Chi : total:m2442_2, partial:m2442_3 -# 2442| r2442_5(glval) = VariableAddress[c] : -# 2442| m2442_6(ClassWithDestructor &) = InitializeParameter[c] : &:r2442_5 -# 2442| r2442_7(ClassWithDestructor &) = Load[c] : &:r2442_5, m2442_6 -# 2442| m2442_8(unknown) = InitializeIndirection[c] : &:r2442_7 -# 2444| v2444_1(void) = NoOp : -# 2442| v2442_9(void) = ReturnIndirection[c] : &:r2442_7, m2442_8 -# 2442| v2442_10(void) = ReturnVoid : -# 2442| v2442_11(void) = AliasedUse : m2442_3 -# 2442| v2442_12(void) = ExitFunction : - -# 2446| void param_with_destructor_by_rref(ClassWithDestructor&&) -# 2446| Block 0 -# 2446| v2446_1(void) = EnterFunction : -# 2446| m2446_2(unknown) = AliasedDefinition : -# 2446| m2446_3(unknown) = InitializeNonLocal : -# 2446| m2446_4(unknown) = Chi : total:m2446_2, partial:m2446_3 -# 2446| r2446_5(glval) = VariableAddress[c] : -# 2446| m2446_6(ClassWithDestructor &&) = InitializeParameter[c] : &:r2446_5 -# 2446| r2446_7(ClassWithDestructor &&) = Load[c] : &:r2446_5, m2446_6 -# 2446| m2446_8(unknown) = InitializeIndirection[c] : &:r2446_7 -# 2448| v2448_1(void) = NoOp : -# 2446| v2446_9(void) = ReturnIndirection[c] : &:r2446_7, m2446_8 -# 2446| v2446_10(void) = ReturnVoid : -# 2446| v2446_11(void) = AliasedUse : m2446_3 -# 2446| v2446_12(void) = ExitFunction : - -# 2450| void rethrow_with_destruction(int) -# 2450| Block 0 -# 2450| v2450_1(void) = EnterFunction : -# 2450| m2450_2(unknown) = AliasedDefinition : -# 2450| m2450_3(unknown) = InitializeNonLocal : -# 2450| m2450_4(unknown) = Chi : total:m2450_2, partial:m2450_3 -# 2450| r2450_5(glval) = VariableAddress[x] : -# 2450| m2450_6(int) = InitializeParameter[x] : &:r2450_5 -# 2451| r2451_1(glval) = VariableAddress[c] : -# 2451| m2451_2(ClassWithDestructor) = Uninitialized[c] : &:r2451_1 -# 2451| r2451_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2451| v2451_4(void) = Call[ClassWithDestructor] : func:r2451_3, this:r2451_1 -# 2451| m2451_5(unknown) = ^CallSideEffect : ~m2450_4 -# 2451| m2451_6(unknown) = Chi : total:m2450_4, partial:m2451_5 -# 2451| m2451_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2451_1 -# 2451| m2451_8(ClassWithDestructor) = Chi : total:m2451_2, partial:m2451_7 -# 2452| v2452_1(void) = ReThrow : -# 2453| r2453_1(glval) = VariableAddress[c] : -# 2453| r2453_2(glval) = FunctionAddress[~ClassWithDestructor] : -# 2453| v2453_3(void) = Call[~ClassWithDestructor] : func:r2453_2, this:r2453_1 -# 2453| m2453_4(unknown) = ^CallSideEffect : ~m2451_6 -# 2453| m2453_5(unknown) = Chi : total:m2451_6, partial:m2453_4 -# 2453| v2453_6(void) = ^IndirectReadSideEffect[-1] : &:r2453_1, m2451_8 -# 2453| m2453_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2453_1 -# 2453| m2453_8(ClassWithDestructor) = Chi : total:m2451_8, partial:m2453_7 +# 2431| Block 12 +# 2431| r2431_79(glval>) = CopyValue : r2431_27 +# 2431| r2431_80(glval) = FunctionAddress[~vector] : +# 2431| v2431_81(void) = Call[~vector] : func:r2431_80, this:r2431_79 +# 2431| m2431_82(unknown) = ^CallSideEffect : ~m2431_63 +# 2431| m2431_83(unknown) = Chi : total:m2431_63, partial:m2431_82 +# 2431| v2431_84(void) = ^IndirectReadSideEffect[-1] : &:r2431_79, ~m2431_83 +# 2431| m2431_85(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2431_79 +# 2431| m2431_86(unknown) = Chi : total:m2431_83, partial:m2431_85 +# 2433| v2433_1(void) = NoOp : +# 2411| v2411_5(void) = ReturnVoid : +# 2411| v2411_6(void) = AliasedUse : ~m2431_83 +# 2411| v2411_7(void) = ExitFunction : + +# 2411| Block 13 +# 2411| v2411_8(void) = Unreached : + +# 2435| void param_with_destructor_by_value(ClassWithDestructor) +# 2435| Block 0 +# 2435| v2435_1(void) = EnterFunction : +# 2435| m2435_2(unknown) = AliasedDefinition : +# 2435| m2435_3(unknown) = InitializeNonLocal : +# 2435| m2435_4(unknown) = Chi : total:m2435_2, partial:m2435_3 +# 2435| r2435_5(glval) = VariableAddress[c] : +# 2435| m2435_6(ClassWithDestructor) = InitializeParameter[c] : &:r2435_5 +# 2437| v2437_1(void) = NoOp : +# 2435| v2435_7(void) = ReturnVoid : +# 2435| v2435_8(void) = AliasedUse : m2435_3 +# 2435| v2435_9(void) = ExitFunction : + +# 2439| void param_with_destructor_by_pointer(ClassWithDestructor*) +# 2439| Block 0 +# 2439| v2439_1(void) = EnterFunction : +# 2439| m2439_2(unknown) = AliasedDefinition : +# 2439| m2439_3(unknown) = InitializeNonLocal : +# 2439| m2439_4(unknown) = Chi : total:m2439_2, partial:m2439_3 +# 2439| r2439_5(glval) = VariableAddress[c] : +# 2439| m2439_6(ClassWithDestructor *) = InitializeParameter[c] : &:r2439_5 +# 2439| r2439_7(ClassWithDestructor *) = Load[c] : &:r2439_5, m2439_6 +# 2439| m2439_8(unknown) = InitializeIndirection[c] : &:r2439_7 +# 2441| v2441_1(void) = NoOp : +# 2439| v2439_9(void) = ReturnIndirection[c] : &:r2439_7, m2439_8 +# 2439| v2439_10(void) = ReturnVoid : +# 2439| v2439_11(void) = AliasedUse : m2439_3 +# 2439| v2439_12(void) = ExitFunction : + +# 2443| void param_with_destructor_by_ref(ClassWithDestructor&) +# 2443| Block 0 +# 2443| v2443_1(void) = EnterFunction : +# 2443| m2443_2(unknown) = AliasedDefinition : +# 2443| m2443_3(unknown) = InitializeNonLocal : +# 2443| m2443_4(unknown) = Chi : total:m2443_2, partial:m2443_3 +# 2443| r2443_5(glval) = VariableAddress[c] : +# 2443| m2443_6(ClassWithDestructor &) = InitializeParameter[c] : &:r2443_5 +# 2443| r2443_7(ClassWithDestructor &) = Load[c] : &:r2443_5, m2443_6 +# 2443| m2443_8(unknown) = InitializeIndirection[c] : &:r2443_7 +# 2445| v2445_1(void) = NoOp : +# 2443| v2443_9(void) = ReturnIndirection[c] : &:r2443_7, m2443_8 +# 2443| v2443_10(void) = ReturnVoid : +# 2443| v2443_11(void) = AliasedUse : m2443_3 +# 2443| v2443_12(void) = ExitFunction : + +# 2447| void param_with_destructor_by_rref(ClassWithDestructor&&) +# 2447| Block 0 +# 2447| v2447_1(void) = EnterFunction : +# 2447| m2447_2(unknown) = AliasedDefinition : +# 2447| m2447_3(unknown) = InitializeNonLocal : +# 2447| m2447_4(unknown) = Chi : total:m2447_2, partial:m2447_3 +# 2447| r2447_5(glval) = VariableAddress[c] : +# 2447| m2447_6(ClassWithDestructor &&) = InitializeParameter[c] : &:r2447_5 +# 2447| r2447_7(ClassWithDestructor &&) = Load[c] : &:r2447_5, m2447_6 +# 2447| m2447_8(unknown) = InitializeIndirection[c] : &:r2447_7 +# 2449| v2449_1(void) = NoOp : +# 2447| v2447_9(void) = ReturnIndirection[c] : &:r2447_7, m2447_8 +# 2447| v2447_10(void) = ReturnVoid : +# 2447| v2447_11(void) = AliasedUse : m2447_3 +# 2447| v2447_12(void) = ExitFunction : + +# 2451| void rethrow_with_destruction(int) +# 2451| Block 0 +# 2451| v2451_1(void) = EnterFunction : +# 2451| m2451_2(unknown) = AliasedDefinition : +# 2451| m2451_3(unknown) = InitializeNonLocal : +# 2451| m2451_4(unknown) = Chi : total:m2451_2, partial:m2451_3 +# 2451| r2451_5(glval) = VariableAddress[x] : +# 2451| m2451_6(int) = InitializeParameter[x] : &:r2451_5 +# 2452| r2452_1(glval) = VariableAddress[c] : +# 2452| m2452_2(ClassWithDestructor) = Uninitialized[c] : &:r2452_1 +# 2452| r2452_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2452| v2452_4(void) = Call[ClassWithDestructor] : func:r2452_3, this:r2452_1 +# 2452| m2452_5(unknown) = ^CallSideEffect : ~m2451_4 +# 2452| m2452_6(unknown) = Chi : total:m2451_4, partial:m2452_5 +# 2452| m2452_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2452_1 +# 2452| m2452_8(ClassWithDestructor) = Chi : total:m2452_2, partial:m2452_7 +# 2453| v2453_1(void) = ReThrow : +# 2454| r2454_1(glval) = VariableAddress[c] : +# 2454| r2454_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2454| v2454_3(void) = Call[~ClassWithDestructor] : func:r2454_2, this:r2454_1 +# 2454| m2454_4(unknown) = ^CallSideEffect : ~m2452_6 +# 2454| m2454_5(unknown) = Chi : total:m2452_6, partial:m2454_4 +# 2454| v2454_6(void) = ^IndirectReadSideEffect[-1] : &:r2454_1, m2452_8 +# 2454| m2454_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2454_1 +# 2454| m2454_8(ClassWithDestructor) = Chi : total:m2452_8, partial:m2454_7 #-----| Exception -> Block 1 -# 2450| Block 1 -# 2450| v2450_7(void) = Unwind : -# 2450| v2450_8(void) = AliasedUse : ~m2453_5 -# 2450| v2450_9(void) = ExitFunction : - -# 2459| void new_with_destructor(ClassWithDestructor) -# 2459| Block 0 -# 2459| v2459_1(void) = EnterFunction : -# 2459| m2459_2(unknown) = AliasedDefinition : -# 2459| m2459_3(unknown) = InitializeNonLocal : -# 2459| m2459_4(unknown) = Chi : total:m2459_2, partial:m2459_3 -# 2459| r2459_5(glval) = VariableAddress[a] : -# 2459| m2459_6(ClassWithDestructor) = InitializeParameter[a] : &:r2459_5 -# 2461| r2461_1(glval) = VariableAddress[b] : -# 2461| r2461_2(glval) = FunctionAddress[operator new] : -# 2461| r2461_3(unsigned long) = Constant[1] : -# 2461| r2461_4(void *) = Call[operator new] : func:r2461_2, 0:r2461_3 -# 2461| m2461_5(unknown) = ^CallSideEffect : ~m2459_4 -# 2461| m2461_6(unknown) = Chi : total:m2459_4, partial:m2461_5 -# 2461| m2461_7(unknown) = ^InitializeDynamicAllocation : &:r2461_4 -# 2461| m2461_8(unknown) = Chi : total:m2461_6, partial:m2461_7 -# 2461| r2461_9(ByValueConstructor *) = Convert : r2461_4 -# 2461| r2461_10(glval) = FunctionAddress[ByValueConstructor] : -# 2461| r2461_11(glval) = VariableAddress[#temp2461:52] : -# 2461| r2461_12(glval) = VariableAddress[a] : -# 2461| r2461_13(ClassWithDestructor) = Load[a] : &:r2461_12, m2459_6 -# 2461| m2461_14(ClassWithDestructor) = Store[#temp2461:52] : &:r2461_11, r2461_13 -# 2461| r2461_15(ClassWithDestructor) = Load[#temp2461:52] : &:r2461_11, m2461_14 -# 2461| v2461_16(void) = Call[ByValueConstructor] : func:r2461_10, this:r2461_9, 0:r2461_15 -# 2461| m2461_17(unknown) = ^CallSideEffect : ~m2461_8 -# 2461| m2461_18(unknown) = Chi : total:m2461_8, partial:m2461_17 -# 2461| m2461_19(ByValueConstructor) = ^IndirectMayWriteSideEffect[-1] : &:r2461_9 -# 2461| m2461_20(unknown) = Chi : total:m2461_18, partial:m2461_19 -# 2461| r2461_21(glval) = CopyValue : r2461_11 -# 2461| r2461_22(glval) = FunctionAddress[~ClassWithDestructor] : -# 2461| v2461_23(void) = Call[~ClassWithDestructor] : func:r2461_22, this:r2461_21 -# 2461| m2461_24(unknown) = ^CallSideEffect : ~m2461_20 -# 2461| m2461_25(unknown) = Chi : total:m2461_20, partial:m2461_24 -# 2461| v2461_26(void) = ^IndirectReadSideEffect[-1] : &:r2461_21, m2461_14 -# 2461| m2461_27(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2461_21 -# 2461| m2461_28(ClassWithDestructor) = Chi : total:m2461_14, partial:m2461_27 -# 2461| m2461_29(ByValueConstructor *) = Store[b] : &:r2461_1, r2461_9 -# 2462| v2462_1(void) = NoOp : -# 2459| v2459_7(void) = ReturnVoid : -# 2459| v2459_8(void) = AliasedUse : ~m2461_25 -# 2459| v2459_9(void) = ExitFunction : - -# 2478| void rvalue_conversion_with_destructor::test() -# 2478| Block 0 -# 2478| v2478_1(void) = EnterFunction : -# 2478| m2478_2(unknown) = AliasedDefinition : -# 2478| m2478_3(unknown) = InitializeNonLocal : -# 2478| m2478_4(unknown) = Chi : total:m2478_2, partial:m2478_3 -# 2480| r2480_1(glval) = VariableAddress[a] : -# 2480| r2480_2(glval) = VariableAddress[#temp2480:18] : -# 2480| r2480_3(glval) = FunctionAddress[get] : -# 2480| r2480_4(B) = Call[get] : func:r2480_3 -# 2480| m2480_5(unknown) = ^CallSideEffect : ~m2478_4 -# 2480| m2480_6(unknown) = Chi : total:m2478_4, partial:m2480_5 -# 2480| m2480_7(B) = Store[#temp2480:18] : &:r2480_2, r2480_4 -# 2480| m2480_8(unknown) = Chi : total:m2480_6, partial:m2480_7 -# 2480| r2480_9(glval) = Convert : r2480_2 -# 2480| r2480_10(glval) = FunctionAddress[operator->] : -# 2480| r2480_11(A *) = Call[operator->] : func:r2480_10, this:r2480_9 -# 2480| m2480_12(unknown) = ^CallSideEffect : ~m2480_8 -# 2480| m2480_13(unknown) = Chi : total:m2480_8, partial:m2480_12 -# 2480| v2480_14(void) = ^IndirectReadSideEffect[-1] : &:r2480_9, ~m2480_13 -# 2480| r2480_15(glval) = FieldAddress[a] : r2480_11 -# 2480| r2480_16(glval) = CopyValue : r2480_2 -# 2480| r2480_17(glval) = FunctionAddress[~B] : -# 2480| v2480_18(void) = Call[~B] : func:r2480_17, this:r2480_16 -# 2480| m2480_19(unknown) = ^CallSideEffect : ~m2480_13 -# 2480| m2480_20(unknown) = Chi : total:m2480_13, partial:m2480_19 -# 2480| v2480_21(void) = ^IndirectReadSideEffect[-1] : &:r2480_16, ~m2480_20 -# 2480| m2480_22(B) = ^IndirectMayWriteSideEffect[-1] : &:r2480_16 -# 2480| m2480_23(unknown) = Chi : total:m2480_20, partial:m2480_22 -# 2480| r2480_24(unsigned int) = Load[?] : &:r2480_15, ~m2480_23 -# 2480| m2480_25(unsigned int) = Store[a] : &:r2480_1, r2480_24 -# 2481| v2481_1(void) = NoOp : -# 2478| v2478_5(void) = ReturnVoid : -# 2478| v2478_6(void) = AliasedUse : ~m2480_20 -# 2478| v2478_7(void) = ExitFunction : - -# 2484| void destructor_without_block(bool) -# 2484| Block 0 -# 2484| v2484_1(void) = EnterFunction : -# 2484| m2484_2(unknown) = AliasedDefinition : -# 2484| m2484_3(unknown) = InitializeNonLocal : -# 2484| m2484_4(unknown) = Chi : total:m2484_2, partial:m2484_3 -# 2484| r2484_5(glval) = VariableAddress[b] : -# 2484| m2484_6(bool) = InitializeParameter[b] : &:r2484_5 -# 2486| r2486_1(glval) = VariableAddress[b] : -# 2486| r2486_2(bool) = Load[b] : &:r2486_1, m2484_6 -# 2486| v2486_3(void) = ConditionalBranch : r2486_2 +# 2451| Block 1 +# 2451| v2451_7(void) = Unwind : +# 2451| v2451_8(void) = AliasedUse : ~m2454_5 +# 2451| v2451_9(void) = ExitFunction : + +# 2460| void new_with_destructor(ClassWithDestructor) +# 2460| Block 0 +# 2460| v2460_1(void) = EnterFunction : +# 2460| m2460_2(unknown) = AliasedDefinition : +# 2460| m2460_3(unknown) = InitializeNonLocal : +# 2460| m2460_4(unknown) = Chi : total:m2460_2, partial:m2460_3 +# 2460| r2460_5(glval) = VariableAddress[a] : +# 2460| m2460_6(ClassWithDestructor) = InitializeParameter[a] : &:r2460_5 +# 2462| r2462_1(glval) = VariableAddress[b] : +# 2462| r2462_2(glval) = FunctionAddress[operator new] : +# 2462| r2462_3(unsigned long) = Constant[1] : +# 2462| r2462_4(void *) = Call[operator new] : func:r2462_2, 0:r2462_3 +# 2462| m2462_5(unknown) = ^CallSideEffect : ~m2460_4 +# 2462| m2462_6(unknown) = Chi : total:m2460_4, partial:m2462_5 +# 2462| m2462_7(unknown) = ^InitializeDynamicAllocation : &:r2462_4 +# 2462| m2462_8(unknown) = Chi : total:m2462_6, partial:m2462_7 +# 2462| r2462_9(ByValueConstructor *) = Convert : r2462_4 +# 2462| r2462_10(glval) = FunctionAddress[ByValueConstructor] : +# 2462| r2462_11(glval) = VariableAddress[#temp2462:52] : +# 2462| r2462_12(glval) = VariableAddress[a] : +# 2462| r2462_13(ClassWithDestructor) = Load[a] : &:r2462_12, m2460_6 +# 2462| m2462_14(ClassWithDestructor) = Store[#temp2462:52] : &:r2462_11, r2462_13 +# 2462| r2462_15(ClassWithDestructor) = Load[#temp2462:52] : &:r2462_11, m2462_14 +# 2462| v2462_16(void) = Call[ByValueConstructor] : func:r2462_10, this:r2462_9, 0:r2462_15 +# 2462| m2462_17(unknown) = ^CallSideEffect : ~m2462_8 +# 2462| m2462_18(unknown) = Chi : total:m2462_8, partial:m2462_17 +# 2462| m2462_19(ByValueConstructor) = ^IndirectMayWriteSideEffect[-1] : &:r2462_9 +# 2462| m2462_20(unknown) = Chi : total:m2462_18, partial:m2462_19 +# 2462| r2462_21(glval) = CopyValue : r2462_11 +# 2462| r2462_22(glval) = FunctionAddress[~ClassWithDestructor] : +# 2462| v2462_23(void) = Call[~ClassWithDestructor] : func:r2462_22, this:r2462_21 +# 2462| m2462_24(unknown) = ^CallSideEffect : ~m2462_20 +# 2462| m2462_25(unknown) = Chi : total:m2462_20, partial:m2462_24 +# 2462| v2462_26(void) = ^IndirectReadSideEffect[-1] : &:r2462_21, m2462_14 +# 2462| m2462_27(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2462_21 +# 2462| m2462_28(ClassWithDestructor) = Chi : total:m2462_14, partial:m2462_27 +# 2462| m2462_29(ByValueConstructor *) = Store[b] : &:r2462_1, r2462_9 +# 2463| v2463_1(void) = NoOp : +# 2460| v2460_7(void) = ReturnVoid : +# 2460| v2460_8(void) = AliasedUse : ~m2462_25 +# 2460| v2460_9(void) = ExitFunction : + +# 2479| void rvalue_conversion_with_destructor::test() +# 2479| Block 0 +# 2479| v2479_1(void) = EnterFunction : +# 2479| m2479_2(unknown) = AliasedDefinition : +# 2479| m2479_3(unknown) = InitializeNonLocal : +# 2479| m2479_4(unknown) = Chi : total:m2479_2, partial:m2479_3 +# 2481| r2481_1(glval) = VariableAddress[a] : +# 2481| r2481_2(glval) = VariableAddress[#temp2481:18] : +# 2481| r2481_3(glval) = FunctionAddress[get] : +# 2481| r2481_4(B) = Call[get] : func:r2481_3 +# 2481| m2481_5(unknown) = ^CallSideEffect : ~m2479_4 +# 2481| m2481_6(unknown) = Chi : total:m2479_4, partial:m2481_5 +# 2481| m2481_7(B) = Store[#temp2481:18] : &:r2481_2, r2481_4 +# 2481| m2481_8(unknown) = Chi : total:m2481_6, partial:m2481_7 +# 2481| r2481_9(glval) = Convert : r2481_2 +# 2481| r2481_10(glval) = FunctionAddress[operator->] : +# 2481| r2481_11(A *) = Call[operator->] : func:r2481_10, this:r2481_9 +# 2481| m2481_12(unknown) = ^CallSideEffect : ~m2481_8 +# 2481| m2481_13(unknown) = Chi : total:m2481_8, partial:m2481_12 +# 2481| v2481_14(void) = ^IndirectReadSideEffect[-1] : &:r2481_9, ~m2481_13 +# 2481| r2481_15(glval) = FieldAddress[a] : r2481_11 +# 2481| r2481_16(glval) = CopyValue : r2481_2 +# 2481| r2481_17(glval) = FunctionAddress[~B] : +# 2481| v2481_18(void) = Call[~B] : func:r2481_17, this:r2481_16 +# 2481| m2481_19(unknown) = ^CallSideEffect : ~m2481_13 +# 2481| m2481_20(unknown) = Chi : total:m2481_13, partial:m2481_19 +# 2481| v2481_21(void) = ^IndirectReadSideEffect[-1] : &:r2481_16, ~m2481_20 +# 2481| m2481_22(B) = ^IndirectMayWriteSideEffect[-1] : &:r2481_16 +# 2481| m2481_23(unknown) = Chi : total:m2481_20, partial:m2481_22 +# 2481| r2481_24(unsigned int) = Load[?] : &:r2481_15, ~m2481_23 +# 2481| m2481_25(unsigned int) = Store[a] : &:r2481_1, r2481_24 +# 2482| v2482_1(void) = NoOp : +# 2479| v2479_5(void) = ReturnVoid : +# 2479| v2479_6(void) = AliasedUse : ~m2481_20 +# 2479| v2479_7(void) = ExitFunction : + +# 2485| void destructor_without_block(bool) +# 2485| Block 0 +# 2485| v2485_1(void) = EnterFunction : +# 2485| m2485_2(unknown) = AliasedDefinition : +# 2485| m2485_3(unknown) = InitializeNonLocal : +# 2485| m2485_4(unknown) = Chi : total:m2485_2, partial:m2485_3 +# 2485| r2485_5(glval) = VariableAddress[b] : +# 2485| m2485_6(bool) = InitializeParameter[b] : &:r2485_5 +# 2487| r2487_1(glval) = VariableAddress[b] : +# 2487| r2487_2(bool) = Load[b] : &:r2487_1, m2485_6 +# 2487| v2487_3(void) = ConditionalBranch : r2487_2 #-----| False -> Block 2 #-----| True -> Block 1 -# 2487| Block 1 -# 2487| r2487_1(glval) = VariableAddress[c] : -# 2487| m2487_2(ClassWithDestructor) = Uninitialized[c] : &:r2487_1 -# 2487| r2487_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2487| v2487_4(void) = Call[ClassWithDestructor] : func:r2487_3, this:r2487_1 -# 2487| m2487_5(unknown) = ^CallSideEffect : ~m2484_4 -# 2487| m2487_6(unknown) = Chi : total:m2484_4, partial:m2487_5 -# 2487| m2487_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2487_1 -# 2487| m2487_8(ClassWithDestructor) = Chi : total:m2487_2, partial:m2487_7 +# 2488| Block 1 +# 2488| r2488_1(glval) = VariableAddress[c] : +# 2488| m2488_2(ClassWithDestructor) = Uninitialized[c] : &:r2488_1 +# 2488| r2488_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2488| v2488_4(void) = Call[ClassWithDestructor] : func:r2488_3, this:r2488_1 +# 2488| m2488_5(unknown) = ^CallSideEffect : ~m2485_4 +# 2488| m2488_6(unknown) = Chi : total:m2485_4, partial:m2488_5 +# 2488| m2488_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2488_1 +# 2488| m2488_8(ClassWithDestructor) = Chi : total:m2488_2, partial:m2488_7 #-----| r0_1(glval) = VariableAddress[c] : #-----| r0_2(glval) = FunctionAddress[~ClassWithDestructor] : #-----| v0_3(void) = Call[~ClassWithDestructor] : func:r0_2, this:r0_1 -#-----| m0_4(unknown) = ^CallSideEffect : ~m2487_6 -#-----| m0_5(unknown) = Chi : total:m2487_6, partial:m0_4 -#-----| v0_6(void) = ^IndirectReadSideEffect[-1] : &:r0_1, m2487_8 +#-----| m0_4(unknown) = ^CallSideEffect : ~m2488_6 +#-----| m0_5(unknown) = Chi : total:m2488_6, partial:m0_4 +#-----| v0_6(void) = ^IndirectReadSideEffect[-1] : &:r0_1, m2488_8 #-----| m0_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r0_1 -#-----| m0_8(ClassWithDestructor) = Chi : total:m2487_8, partial:m0_7 +#-----| m0_8(ClassWithDestructor) = Chi : total:m2488_8, partial:m0_7 #-----| Goto -> Block 2 -# 2489| Block 2 -# 2489| m2489_1(unknown) = Phi : from 0:~m2484_4, from 1:~m0_5 -# 2489| r2489_2(glval) = VariableAddress[b] : -# 2489| r2489_3(bool) = Load[b] : &:r2489_2, m2484_6 -# 2489| v2489_4(void) = ConditionalBranch : r2489_3 +# 2490| Block 2 +# 2490| m2490_1(unknown) = Phi : from 0:~m2485_4, from 1:~m0_5 +# 2490| r2490_2(glval) = VariableAddress[b] : +# 2490| r2490_3(bool) = Load[b] : &:r2490_2, m2485_6 +# 2490| v2490_4(void) = ConditionalBranch : r2490_3 #-----| False -> Block 4 #-----| True -> Block 3 -# 2490| Block 3 -# 2490| r2490_1(glval) = VariableAddress[d] : -# 2490| m2490_2(ClassWithDestructor) = Uninitialized[d] : &:r2490_1 -# 2490| r2490_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2490| v2490_4(void) = Call[ClassWithDestructor] : func:r2490_3, this:r2490_1 -# 2490| m2490_5(unknown) = ^CallSideEffect : ~m2489_1 -# 2490| m2490_6(unknown) = Chi : total:m2489_1, partial:m2490_5 -# 2490| m2490_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2490_1 -# 2490| m2490_8(ClassWithDestructor) = Chi : total:m2490_2, partial:m2490_7 +# 2491| Block 3 +# 2491| r2491_1(glval) = VariableAddress[d] : +# 2491| m2491_2(ClassWithDestructor) = Uninitialized[d] : &:r2491_1 +# 2491| r2491_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2491| v2491_4(void) = Call[ClassWithDestructor] : func:r2491_3, this:r2491_1 +# 2491| m2491_5(unknown) = ^CallSideEffect : ~m2490_1 +# 2491| m2491_6(unknown) = Chi : total:m2490_1, partial:m2491_5 +# 2491| m2491_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2491_1 +# 2491| m2491_8(ClassWithDestructor) = Chi : total:m2491_2, partial:m2491_7 #-----| r0_9(glval) = VariableAddress[d] : #-----| r0_10(glval) = FunctionAddress[~ClassWithDestructor] : #-----| v0_11(void) = Call[~ClassWithDestructor] : func:r0_10, this:r0_9 -#-----| m0_12(unknown) = ^CallSideEffect : ~m2490_6 -#-----| m0_13(unknown) = Chi : total:m2490_6, partial:m0_12 -#-----| v0_14(void) = ^IndirectReadSideEffect[-1] : &:r0_9, m2490_8 +#-----| m0_12(unknown) = ^CallSideEffect : ~m2491_6 +#-----| m0_13(unknown) = Chi : total:m2491_6, partial:m0_12 +#-----| v0_14(void) = ^IndirectReadSideEffect[-1] : &:r0_9, m2491_8 #-----| m0_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r0_9 -#-----| m0_16(ClassWithDestructor) = Chi : total:m2490_8, partial:m0_15 +#-----| m0_16(ClassWithDestructor) = Chi : total:m2491_8, partial:m0_15 #-----| Goto -> Block 5 -# 2492| Block 4 -# 2492| r2492_1(glval) = VariableAddress[e] : -# 2492| m2492_2(ClassWithDestructor) = Uninitialized[e] : &:r2492_1 -# 2492| r2492_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2492| v2492_4(void) = Call[ClassWithDestructor] : func:r2492_3, this:r2492_1 -# 2492| m2492_5(unknown) = ^CallSideEffect : ~m2489_1 -# 2492| m2492_6(unknown) = Chi : total:m2489_1, partial:m2492_5 -# 2492| m2492_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2492_1 -# 2492| m2492_8(ClassWithDestructor) = Chi : total:m2492_2, partial:m2492_7 +# 2493| Block 4 +# 2493| r2493_1(glval) = VariableAddress[e] : +# 2493| m2493_2(ClassWithDestructor) = Uninitialized[e] : &:r2493_1 +# 2493| r2493_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2493| v2493_4(void) = Call[ClassWithDestructor] : func:r2493_3, this:r2493_1 +# 2493| m2493_5(unknown) = ^CallSideEffect : ~m2490_1 +# 2493| m2493_6(unknown) = Chi : total:m2490_1, partial:m2493_5 +# 2493| m2493_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2493_1 +# 2493| m2493_8(ClassWithDestructor) = Chi : total:m2493_2, partial:m2493_7 #-----| r0_17(glval) = VariableAddress[e] : #-----| r0_18(glval) = FunctionAddress[~ClassWithDestructor] : #-----| v0_19(void) = Call[~ClassWithDestructor] : func:r0_18, this:r0_17 -#-----| m0_20(unknown) = ^CallSideEffect : ~m2492_6 -#-----| m0_21(unknown) = Chi : total:m2492_6, partial:m0_20 -#-----| v0_22(void) = ^IndirectReadSideEffect[-1] : &:r0_17, m2492_8 +#-----| m0_20(unknown) = ^CallSideEffect : ~m2493_6 +#-----| m0_21(unknown) = Chi : total:m2493_6, partial:m0_20 +#-----| v0_22(void) = ^IndirectReadSideEffect[-1] : &:r0_17, m2493_8 #-----| m0_23(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r0_17 -#-----| m0_24(ClassWithDestructor) = Chi : total:m2492_8, partial:m0_23 +#-----| m0_24(ClassWithDestructor) = Chi : total:m2493_8, partial:m0_23 #-----| Goto -> Block 5 -# 2494| Block 5 -# 2494| m2494_1(unknown) = Phi : from 3:~m0_13, from 4:~m0_21, from 6:~m0_29 -# 2494| r2494_2(glval) = VariableAddress[b] : -# 2494| r2494_3(bool) = Load[b] : &:r2494_2, m2484_6 -# 2494| v2494_4(void) = ConditionalBranch : r2494_3 +# 2495| Block 5 +# 2495| m2495_1(unknown) = Phi : from 3:~m0_13, from 4:~m0_21, from 6:~m0_29 +# 2495| r2495_2(glval) = VariableAddress[b] : +# 2495| r2495_3(bool) = Load[b] : &:r2495_2, m2485_6 +# 2495| v2495_4(void) = ConditionalBranch : r2495_3 #-----| False -> Block 7 #-----| True -> Block 6 -# 2495| Block 6 -# 2495| r2495_1(glval) = VariableAddress[f] : -# 2495| m2495_2(ClassWithDestructor) = Uninitialized[f] : &:r2495_1 -# 2495| r2495_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2495| v2495_4(void) = Call[ClassWithDestructor] : func:r2495_3, this:r2495_1 -# 2495| m2495_5(unknown) = ^CallSideEffect : ~m2494_1 -# 2495| m2495_6(unknown) = Chi : total:m2494_1, partial:m2495_5 -# 2495| m2495_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2495_1 -# 2495| m2495_8(ClassWithDestructor) = Chi : total:m2495_2, partial:m2495_7 +# 2496| Block 6 +# 2496| r2496_1(glval) = VariableAddress[f] : +# 2496| m2496_2(ClassWithDestructor) = Uninitialized[f] : &:r2496_1 +# 2496| r2496_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2496| v2496_4(void) = Call[ClassWithDestructor] : func:r2496_3, this:r2496_1 +# 2496| m2496_5(unknown) = ^CallSideEffect : ~m2495_1 +# 2496| m2496_6(unknown) = Chi : total:m2495_1, partial:m2496_5 +# 2496| m2496_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2496_1 +# 2496| m2496_8(ClassWithDestructor) = Chi : total:m2496_2, partial:m2496_7 #-----| r0_25(glval) = VariableAddress[f] : #-----| r0_26(glval) = FunctionAddress[~ClassWithDestructor] : #-----| v0_27(void) = Call[~ClassWithDestructor] : func:r0_26, this:r0_25 -#-----| m0_28(unknown) = ^CallSideEffect : ~m2495_6 -#-----| m0_29(unknown) = Chi : total:m2495_6, partial:m0_28 -#-----| v0_30(void) = ^IndirectReadSideEffect[-1] : &:r0_25, m2495_8 +#-----| m0_28(unknown) = ^CallSideEffect : ~m2496_6 +#-----| m0_29(unknown) = Chi : total:m2496_6, partial:m0_28 +#-----| v0_30(void) = ^IndirectReadSideEffect[-1] : &:r0_25, m2496_8 #-----| m0_31(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r0_25 -#-----| m0_32(ClassWithDestructor) = Chi : total:m2495_8, partial:m0_31 +#-----| m0_32(ClassWithDestructor) = Chi : total:m2496_8, partial:m0_31 #-----| Goto (back edge) -> Block 5 -# 2497| Block 7 -# 2497| r2497_1(glval) = VariableAddress[i] : -# 2497| r2497_2(int) = Constant[0] : -# 2497| m2497_3(int) = Store[i] : &:r2497_1, r2497_2 +# 2498| Block 7 +# 2498| r2498_1(glval) = VariableAddress[i] : +# 2498| r2498_2(int) = Constant[0] : +# 2498| m2498_3(int) = Store[i] : &:r2498_1, r2498_2 #-----| Goto -> Block 8 -# 2497| Block 8 -# 2497| m2497_4(unknown) = Phi : from 7:~m2494_1, from 9:~m0_37 -# 2497| m2497_5(int) = Phi : from 7:m2497_3, from 9:m2497_15 -# 2497| r2497_6(glval) = VariableAddress[i] : -# 2497| r2497_7(int) = Load[i] : &:r2497_6, m2497_5 -# 2497| r2497_8(int) = Constant[42] : -# 2497| r2497_9(bool) = CompareLT : r2497_7, r2497_8 -# 2497| v2497_10(void) = ConditionalBranch : r2497_9 +# 2498| Block 8 +# 2498| m2498_4(unknown) = Phi : from 7:~m2495_1, from 9:~m0_37 +# 2498| m2498_5(int) = Phi : from 7:m2498_3, from 9:m2498_15 +# 2498| r2498_6(glval) = VariableAddress[i] : +# 2498| r2498_7(int) = Load[i] : &:r2498_6, m2498_5 +# 2498| r2498_8(int) = Constant[42] : +# 2498| r2498_9(bool) = CompareLT : r2498_7, r2498_8 +# 2498| v2498_10(void) = ConditionalBranch : r2498_9 #-----| False -> Block 10 #-----| True -> Block 9 -# 2498| Block 9 -# 2498| r2498_1(glval) = VariableAddress[g] : -# 2498| m2498_2(ClassWithDestructor) = Uninitialized[g] : &:r2498_1 -# 2498| r2498_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2498| v2498_4(void) = Call[ClassWithDestructor] : func:r2498_3, this:r2498_1 -# 2498| m2498_5(unknown) = ^CallSideEffect : ~m2497_4 -# 2498| m2498_6(unknown) = Chi : total:m2497_4, partial:m2498_5 -# 2498| m2498_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2498_1 -# 2498| m2498_8(ClassWithDestructor) = Chi : total:m2498_2, partial:m2498_7 +# 2499| Block 9 +# 2499| r2499_1(glval) = VariableAddress[g] : +# 2499| m2499_2(ClassWithDestructor) = Uninitialized[g] : &:r2499_1 +# 2499| r2499_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2499| v2499_4(void) = Call[ClassWithDestructor] : func:r2499_3, this:r2499_1 +# 2499| m2499_5(unknown) = ^CallSideEffect : ~m2498_4 +# 2499| m2499_6(unknown) = Chi : total:m2498_4, partial:m2499_5 +# 2499| m2499_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2499_1 +# 2499| m2499_8(ClassWithDestructor) = Chi : total:m2499_2, partial:m2499_7 #-----| r0_33(glval) = VariableAddress[g] : #-----| r0_34(glval) = FunctionAddress[~ClassWithDestructor] : #-----| v0_35(void) = Call[~ClassWithDestructor] : func:r0_34, this:r0_33 -#-----| m0_36(unknown) = ^CallSideEffect : ~m2498_6 -#-----| m0_37(unknown) = Chi : total:m2498_6, partial:m0_36 -#-----| v0_38(void) = ^IndirectReadSideEffect[-1] : &:r0_33, m2498_8 +#-----| m0_36(unknown) = ^CallSideEffect : ~m2499_6 +#-----| m0_37(unknown) = Chi : total:m2499_6, partial:m0_36 +#-----| v0_38(void) = ^IndirectReadSideEffect[-1] : &:r0_33, m2499_8 #-----| m0_39(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r0_33 -#-----| m0_40(ClassWithDestructor) = Chi : total:m2498_8, partial:m0_39 -# 2497| r2497_11(glval) = VariableAddress[i] : -# 2497| r2497_12(int) = Load[i] : &:r2497_11, m2497_5 -# 2497| r2497_13(int) = Constant[1] : -# 2497| r2497_14(int) = Add : r2497_12, r2497_13 -# 2497| m2497_15(int) = Store[i] : &:r2497_11, r2497_14 +#-----| m0_40(ClassWithDestructor) = Chi : total:m2499_8, partial:m0_39 +# 2498| r2498_11(glval) = VariableAddress[i] : +# 2498| r2498_12(int) = Load[i] : &:r2498_11, m2498_5 +# 2498| r2498_13(int) = Constant[1] : +# 2498| r2498_14(int) = Add : r2498_12, r2498_13 +# 2498| m2498_15(int) = Store[i] : &:r2498_11, r2498_14 #-----| Goto (back edge) -> Block 8 -# 2499| Block 10 -# 2499| v2499_1(void) = NoOp : -# 2484| v2484_7(void) = ReturnVoid : -# 2484| v2484_8(void) = AliasedUse : ~m2497_4 -# 2484| v2484_9(void) = ExitFunction : - -# 2501| void destruction_in_switch_1(int) -# 2501| Block 0 -# 2501| v2501_1(void) = EnterFunction : -# 2501| m2501_2(unknown) = AliasedDefinition : -# 2501| m2501_3(unknown) = InitializeNonLocal : -# 2501| m2501_4(unknown) = Chi : total:m2501_2, partial:m2501_3 -# 2501| r2501_5(glval) = VariableAddress[c] : -# 2501| m2501_6(int) = InitializeParameter[c] : &:r2501_5 -# 2502| r2502_1(glval) = VariableAddress[c] : -# 2502| r2502_2(int) = Load[c] : &:r2502_1, m2501_6 -# 2502| v2502_3(void) = Switch : r2502_2 +# 2500| Block 10 +# 2500| v2500_1(void) = NoOp : +# 2485| v2485_7(void) = ReturnVoid : +# 2485| v2485_8(void) = AliasedUse : ~m2498_4 +# 2485| v2485_9(void) = ExitFunction : + +# 2502| void destruction_in_switch_1(int) +# 2502| Block 0 +# 2502| v2502_1(void) = EnterFunction : +# 2502| m2502_2(unknown) = AliasedDefinition : +# 2502| m2502_3(unknown) = InitializeNonLocal : +# 2502| m2502_4(unknown) = Chi : total:m2502_2, partial:m2502_3 +# 2502| r2502_5(glval) = VariableAddress[c] : +# 2502| m2502_6(int) = InitializeParameter[c] : &:r2502_5 +# 2503| r2503_1(glval) = VariableAddress[c] : +# 2503| r2503_2(int) = Load[c] : &:r2503_1, m2502_6 +# 2503| v2503_3(void) = Switch : r2503_2 #-----| Case[0] -> Block 1 #-----| Default -> Block 2 -# 2503| Block 1 -# 2503| v2503_1(void) = NoOp : -# 2504| r2504_1(glval) = VariableAddress[x] : -# 2504| m2504_2(ClassWithDestructor) = Uninitialized[x] : &:r2504_1 -# 2504| r2504_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2504| v2504_4(void) = Call[ClassWithDestructor] : func:r2504_3, this:r2504_1 -# 2504| m2504_5(unknown) = ^CallSideEffect : ~m2501_4 -# 2504| m2504_6(unknown) = Chi : total:m2501_4, partial:m2504_5 -# 2504| m2504_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2504_1 -# 2504| m2504_8(ClassWithDestructor) = Chi : total:m2504_2, partial:m2504_7 -# 2506| r2506_1(glval) = VariableAddress[x] : -# 2506| r2506_2(glval) = FunctionAddress[~ClassWithDestructor] : -# 2506| v2506_3(void) = Call[~ClassWithDestructor] : func:r2506_2, this:r2506_1 -# 2506| m2506_4(unknown) = ^CallSideEffect : ~m2504_6 -# 2506| m2506_5(unknown) = Chi : total:m2504_6, partial:m2506_4 -# 2506| v2506_6(void) = ^IndirectReadSideEffect[-1] : &:r2506_1, m2504_8 -# 2506| m2506_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2506_1 -# 2506| m2506_8(ClassWithDestructor) = Chi : total:m2504_8, partial:m2506_7 -# 2505| v2505_1(void) = NoOp : +# 2504| Block 1 +# 2504| v2504_1(void) = NoOp : +# 2505| r2505_1(glval) = VariableAddress[x] : +# 2505| m2505_2(ClassWithDestructor) = Uninitialized[x] : &:r2505_1 +# 2505| r2505_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2505| v2505_4(void) = Call[ClassWithDestructor] : func:r2505_3, this:r2505_1 +# 2505| m2505_5(unknown) = ^CallSideEffect : ~m2502_4 +# 2505| m2505_6(unknown) = Chi : total:m2502_4, partial:m2505_5 +# 2505| m2505_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2505_1 +# 2505| m2505_8(ClassWithDestructor) = Chi : total:m2505_2, partial:m2505_7 +# 2507| r2507_1(glval) = VariableAddress[x] : +# 2507| r2507_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2507| v2507_3(void) = Call[~ClassWithDestructor] : func:r2507_2, this:r2507_1 +# 2507| m2507_4(unknown) = ^CallSideEffect : ~m2505_6 +# 2507| m2507_5(unknown) = Chi : total:m2505_6, partial:m2507_4 +# 2507| v2507_6(void) = ^IndirectReadSideEffect[-1] : &:r2507_1, m2505_8 +# 2507| m2507_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2507_1 +# 2507| m2507_8(ClassWithDestructor) = Chi : total:m2505_8, partial:m2507_7 +# 2506| v2506_1(void) = NoOp : #-----| Goto -> Block 2 -# 2507| Block 2 -# 2507| m2507_1(unknown) = Phi : from 0:~m2501_4, from 1:~m2506_5 -# 2507| v2507_2(void) = NoOp : -# 2508| v2508_1(void) = NoOp : -# 2501| v2501_7(void) = ReturnVoid : -# 2501| v2501_8(void) = AliasedUse : ~m2507_1 -# 2501| v2501_9(void) = ExitFunction : - -# 2510| void destruction_in_switch_2(int) -# 2510| Block 0 -# 2510| v2510_1(void) = EnterFunction : -# 2510| m2510_2(unknown) = AliasedDefinition : -# 2510| m2510_3(unknown) = InitializeNonLocal : -# 2510| m2510_4(unknown) = Chi : total:m2510_2, partial:m2510_3 -# 2510| r2510_5(glval) = VariableAddress[c] : -# 2510| m2510_6(int) = InitializeParameter[c] : &:r2510_5 -# 2511| r2511_1(glval) = VariableAddress[y] : -# 2511| m2511_2(ClassWithDestructor) = Uninitialized[y] : &:r2511_1 -# 2511| r2511_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2511| v2511_4(void) = Call[ClassWithDestructor] : func:r2511_3, this:r2511_1 -# 2511| m2511_5(unknown) = ^CallSideEffect : ~m2510_4 -# 2511| m2511_6(unknown) = Chi : total:m2510_4, partial:m2511_5 -# 2511| m2511_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2511_1 -# 2511| m2511_8(ClassWithDestructor) = Chi : total:m2511_2, partial:m2511_7 -# 2511| r2511_9(glval) = VariableAddress[c] : -# 2511| r2511_10(int) = Load[c] : &:r2511_9, m2510_6 -# 2511| v2511_11(void) = Switch : r2511_10 +# 2508| Block 2 +# 2508| m2508_1(unknown) = Phi : from 0:~m2502_4, from 1:~m2507_5 +# 2508| v2508_2(void) = NoOp : +# 2509| v2509_1(void) = NoOp : +# 2502| v2502_7(void) = ReturnVoid : +# 2502| v2502_8(void) = AliasedUse : ~m2508_1 +# 2502| v2502_9(void) = ExitFunction : + +# 2511| void destruction_in_switch_2(int) +# 2511| Block 0 +# 2511| v2511_1(void) = EnterFunction : +# 2511| m2511_2(unknown) = AliasedDefinition : +# 2511| m2511_3(unknown) = InitializeNonLocal : +# 2511| m2511_4(unknown) = Chi : total:m2511_2, partial:m2511_3 +# 2511| r2511_5(glval) = VariableAddress[c] : +# 2511| m2511_6(int) = InitializeParameter[c] : &:r2511_5 +# 2512| r2512_1(glval) = VariableAddress[y] : +# 2512| m2512_2(ClassWithDestructor) = Uninitialized[y] : &:r2512_1 +# 2512| r2512_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2512| v2512_4(void) = Call[ClassWithDestructor] : func:r2512_3, this:r2512_1 +# 2512| m2512_5(unknown) = ^CallSideEffect : ~m2511_4 +# 2512| m2512_6(unknown) = Chi : total:m2511_4, partial:m2512_5 +# 2512| m2512_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2512_1 +# 2512| m2512_8(ClassWithDestructor) = Chi : total:m2512_2, partial:m2512_7 +# 2512| r2512_9(glval) = VariableAddress[c] : +# 2512| r2512_10(int) = Load[c] : &:r2512_9, m2511_6 +# 2512| v2512_11(void) = Switch : r2512_10 #-----| Case[0] -> Block 1 #-----| Default -> Block 2 -# 2512| Block 1 -# 2512| v2512_1(void) = NoOp : -# 2518| r2518_1(glval) = VariableAddress[y] : -# 2518| r2518_2(glval) = FunctionAddress[~ClassWithDestructor] : -# 2518| v2518_3(void) = Call[~ClassWithDestructor] : func:r2518_2, this:r2518_1 -# 2518| m2518_4(unknown) = ^CallSideEffect : ~m2511_6 -# 2518| m2518_5(unknown) = Chi : total:m2511_6, partial:m2518_4 -# 2518| v2518_6(void) = ^IndirectReadSideEffect[-1] : &:r2518_1, m2511_8 -# 2518| m2518_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2518_1 -# 2518| m2518_8(ClassWithDestructor) = Chi : total:m2511_8, partial:m2518_7 +# 2513| Block 1 # 2513| v2513_1(void) = NoOp : +# 2519| r2519_1(glval) = VariableAddress[y] : +# 2519| r2519_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2519| v2519_3(void) = Call[~ClassWithDestructor] : func:r2519_2, this:r2519_1 +# 2519| m2519_4(unknown) = ^CallSideEffect : ~m2512_6 +# 2519| m2519_5(unknown) = Chi : total:m2512_6, partial:m2519_4 +# 2519| v2519_6(void) = ^IndirectReadSideEffect[-1] : &:r2519_1, m2512_8 +# 2519| m2519_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2519_1 +# 2519| m2519_8(ClassWithDestructor) = Chi : total:m2512_8, partial:m2519_7 +# 2514| v2514_1(void) = NoOp : #-----| Goto -> Block 3 -# 2515| Block 2 -# 2515| v2515_1(void) = NoOp : -# 2518| r2518_9(glval) = VariableAddress[y] : -# 2518| r2518_10(glval) = FunctionAddress[~ClassWithDestructor] : -# 2518| v2518_11(void) = Call[~ClassWithDestructor] : func:r2518_10, this:r2518_9 -# 2518| m2518_12(unknown) = ^CallSideEffect : ~m2511_6 -# 2518| m2518_13(unknown) = Chi : total:m2511_6, partial:m2518_12 -# 2518| v2518_14(void) = ^IndirectReadSideEffect[-1] : &:r2518_9, m2511_8 -# 2518| m2518_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2518_9 -# 2518| m2518_16(ClassWithDestructor) = Chi : total:m2511_8, partial:m2518_15 +# 2516| Block 2 # 2516| v2516_1(void) = NoOp : +# 2519| r2519_9(glval) = VariableAddress[y] : +# 2519| r2519_10(glval) = FunctionAddress[~ClassWithDestructor] : +# 2519| v2519_11(void) = Call[~ClassWithDestructor] : func:r2519_10, this:r2519_9 +# 2519| m2519_12(unknown) = ^CallSideEffect : ~m2512_6 +# 2519| m2519_13(unknown) = Chi : total:m2512_6, partial:m2519_12 +# 2519| v2519_14(void) = ^IndirectReadSideEffect[-1] : &:r2519_9, m2512_8 +# 2519| m2519_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2519_9 +# 2519| m2519_16(ClassWithDestructor) = Chi : total:m2512_8, partial:m2519_15 +# 2517| v2517_1(void) = NoOp : #-----| Goto -> Block 3 -# 2518| Block 3 -# 2518| m2518_17(unknown) = Phi : from 1:~m2518_5, from 2:~m2518_13 -# 2518| v2518_18(void) = NoOp : -# 2519| v2519_1(void) = NoOp : -# 2510| v2510_7(void) = ReturnVoid : -# 2510| v2510_8(void) = AliasedUse : ~m2518_17 -# 2510| v2510_9(void) = ExitFunction : - -# 2521| void destruction_in_switch_3(int) -# 2521| Block 0 -# 2521| v2521_1(void) = EnterFunction : -# 2521| m2521_2(unknown) = AliasedDefinition : -# 2521| m2521_3(unknown) = InitializeNonLocal : -# 2521| m2521_4(unknown) = Chi : total:m2521_2, partial:m2521_3 -# 2521| r2521_5(glval) = VariableAddress[c] : -# 2521| m2521_6(int) = InitializeParameter[c] : &:r2521_5 -# 2522| r2522_1(glval) = VariableAddress[y] : -# 2522| m2522_2(ClassWithDestructor) = Uninitialized[y] : &:r2522_1 -# 2522| r2522_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2522| v2522_4(void) = Call[ClassWithDestructor] : func:r2522_3, this:r2522_1 -# 2522| m2522_5(unknown) = ^CallSideEffect : ~m2521_4 -# 2522| m2522_6(unknown) = Chi : total:m2521_4, partial:m2522_5 -# 2522| m2522_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2522_1 -# 2522| m2522_8(ClassWithDestructor) = Chi : total:m2522_2, partial:m2522_7 -# 2522| r2522_9(glval) = VariableAddress[c] : -# 2522| r2522_10(int) = Load[c] : &:r2522_9, m2521_6 -# 2522| v2522_11(void) = Switch : r2522_10 +# 2519| Block 3 +# 2519| m2519_17(unknown) = Phi : from 1:~m2519_5, from 2:~m2519_13 +# 2519| v2519_18(void) = NoOp : +# 2520| v2520_1(void) = NoOp : +# 2511| v2511_7(void) = ReturnVoid : +# 2511| v2511_8(void) = AliasedUse : ~m2519_17 +# 2511| v2511_9(void) = ExitFunction : + +# 2522| void destruction_in_switch_3(int) +# 2522| Block 0 +# 2522| v2522_1(void) = EnterFunction : +# 2522| m2522_2(unknown) = AliasedDefinition : +# 2522| m2522_3(unknown) = InitializeNonLocal : +# 2522| m2522_4(unknown) = Chi : total:m2522_2, partial:m2522_3 +# 2522| r2522_5(glval) = VariableAddress[c] : +# 2522| m2522_6(int) = InitializeParameter[c] : &:r2522_5 +# 2523| r2523_1(glval) = VariableAddress[y] : +# 2523| m2523_2(ClassWithDestructor) = Uninitialized[y] : &:r2523_1 +# 2523| r2523_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2523| v2523_4(void) = Call[ClassWithDestructor] : func:r2523_3, this:r2523_1 +# 2523| m2523_5(unknown) = ^CallSideEffect : ~m2522_4 +# 2523| m2523_6(unknown) = Chi : total:m2522_4, partial:m2523_5 +# 2523| m2523_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2523_1 +# 2523| m2523_8(ClassWithDestructor) = Chi : total:m2523_2, partial:m2523_7 +# 2523| r2523_9(glval) = VariableAddress[c] : +# 2523| r2523_10(int) = Load[c] : &:r2523_9, m2522_6 +# 2523| v2523_11(void) = Switch : r2523_10 #-----| Case[0] -> Block 1 #-----| Default -> Block 2 -# 2523| Block 1 -# 2523| v2523_1(void) = NoOp : -# 2524| r2524_1(glval) = VariableAddress[x] : -# 2524| m2524_2(ClassWithDestructor) = Uninitialized[x] : &:r2524_1 -# 2524| r2524_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2524| v2524_4(void) = Call[ClassWithDestructor] : func:r2524_3, this:r2524_1 -# 2524| m2524_5(unknown) = ^CallSideEffect : ~m2522_6 -# 2524| m2524_6(unknown) = Chi : total:m2522_6, partial:m2524_5 -# 2524| m2524_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2524_1 -# 2524| m2524_8(ClassWithDestructor) = Chi : total:m2524_2, partial:m2524_7 -# 2526| r2526_1(glval) = VariableAddress[x] : -# 2526| r2526_2(glval) = FunctionAddress[~ClassWithDestructor] : -# 2526| v2526_3(void) = Call[~ClassWithDestructor] : func:r2526_2, this:r2526_1 -# 2526| m2526_4(unknown) = ^CallSideEffect : ~m2524_6 -# 2526| m2526_5(unknown) = Chi : total:m2524_6, partial:m2526_4 -# 2526| v2526_6(void) = ^IndirectReadSideEffect[-1] : &:r2526_1, m2524_8 -# 2526| m2526_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2526_1 -# 2526| m2526_8(ClassWithDestructor) = Chi : total:m2524_8, partial:m2526_7 -# 2530| r2530_1(glval) = VariableAddress[y] : -# 2530| r2530_2(glval) = FunctionAddress[~ClassWithDestructor] : -# 2530| v2530_3(void) = Call[~ClassWithDestructor] : func:r2530_2, this:r2530_1 -# 2530| m2530_4(unknown) = ^CallSideEffect : ~m2526_5 -# 2530| m2530_5(unknown) = Chi : total:m2526_5, partial:m2530_4 -# 2530| v2530_6(void) = ^IndirectReadSideEffect[-1] : &:r2530_1, m2522_8 -# 2530| m2530_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2530_1 -# 2530| m2530_8(ClassWithDestructor) = Chi : total:m2522_8, partial:m2530_7 -# 2525| v2525_1(void) = NoOp : +# 2524| Block 1 +# 2524| v2524_1(void) = NoOp : +# 2525| r2525_1(glval) = VariableAddress[x] : +# 2525| m2525_2(ClassWithDestructor) = Uninitialized[x] : &:r2525_1 +# 2525| r2525_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2525| v2525_4(void) = Call[ClassWithDestructor] : func:r2525_3, this:r2525_1 +# 2525| m2525_5(unknown) = ^CallSideEffect : ~m2523_6 +# 2525| m2525_6(unknown) = Chi : total:m2523_6, partial:m2525_5 +# 2525| m2525_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2525_1 +# 2525| m2525_8(ClassWithDestructor) = Chi : total:m2525_2, partial:m2525_7 +# 2527| r2527_1(glval) = VariableAddress[x] : +# 2527| r2527_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2527| v2527_3(void) = Call[~ClassWithDestructor] : func:r2527_2, this:r2527_1 +# 2527| m2527_4(unknown) = ^CallSideEffect : ~m2525_6 +# 2527| m2527_5(unknown) = Chi : total:m2525_6, partial:m2527_4 +# 2527| v2527_6(void) = ^IndirectReadSideEffect[-1] : &:r2527_1, m2525_8 +# 2527| m2527_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2527_1 +# 2527| m2527_8(ClassWithDestructor) = Chi : total:m2525_8, partial:m2527_7 +# 2531| r2531_1(glval) = VariableAddress[y] : +# 2531| r2531_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2531| v2531_3(void) = Call[~ClassWithDestructor] : func:r2531_2, this:r2531_1 +# 2531| m2531_4(unknown) = ^CallSideEffect : ~m2527_5 +# 2531| m2531_5(unknown) = Chi : total:m2527_5, partial:m2531_4 +# 2531| v2531_6(void) = ^IndirectReadSideEffect[-1] : &:r2531_1, m2523_8 +# 2531| m2531_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2531_1 +# 2531| m2531_8(ClassWithDestructor) = Chi : total:m2523_8, partial:m2531_7 +# 2526| v2526_1(void) = NoOp : #-----| Goto -> Block 3 -# 2527| Block 2 -# 2527| v2527_1(void) = NoOp : -# 2530| r2530_9(glval) = VariableAddress[y] : -# 2530| r2530_10(glval) = FunctionAddress[~ClassWithDestructor] : -# 2530| v2530_11(void) = Call[~ClassWithDestructor] : func:r2530_10, this:r2530_9 -# 2530| m2530_12(unknown) = ^CallSideEffect : ~m2522_6 -# 2530| m2530_13(unknown) = Chi : total:m2522_6, partial:m2530_12 -# 2530| v2530_14(void) = ^IndirectReadSideEffect[-1] : &:r2530_9, m2522_8 -# 2530| m2530_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2530_9 -# 2530| m2530_16(ClassWithDestructor) = Chi : total:m2522_8, partial:m2530_15 +# 2528| Block 2 # 2528| v2528_1(void) = NoOp : +# 2531| r2531_9(glval) = VariableAddress[y] : +# 2531| r2531_10(glval) = FunctionAddress[~ClassWithDestructor] : +# 2531| v2531_11(void) = Call[~ClassWithDestructor] : func:r2531_10, this:r2531_9 +# 2531| m2531_12(unknown) = ^CallSideEffect : ~m2523_6 +# 2531| m2531_13(unknown) = Chi : total:m2523_6, partial:m2531_12 +# 2531| v2531_14(void) = ^IndirectReadSideEffect[-1] : &:r2531_9, m2523_8 +# 2531| m2531_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2531_9 +# 2531| m2531_16(ClassWithDestructor) = Chi : total:m2523_8, partial:m2531_15 +# 2529| v2529_1(void) = NoOp : #-----| Goto -> Block 3 -# 2530| Block 3 -# 2530| m2530_17(unknown) = Phi : from 1:~m2530_5, from 2:~m2530_13 -# 2530| v2530_18(void) = NoOp : -# 2531| v2531_1(void) = NoOp : -# 2521| v2521_7(void) = ReturnVoid : -# 2521| v2521_8(void) = AliasedUse : ~m2530_17 -# 2521| v2521_9(void) = ExitFunction : - -# 2533| void destructor_possibly_not_handled() -# 2533| Block 0 -# 2533| v2533_1(void) = EnterFunction : -# 2533| m2533_2(unknown) = AliasedDefinition : -# 2533| m2533_3(unknown) = InitializeNonLocal : -# 2533| m2533_4(unknown) = Chi : total:m2533_2, partial:m2533_3 -# 2534| r2534_1(glval) = VariableAddress[x] : -# 2534| m2534_2(ClassWithDestructor) = Uninitialized[x] : &:r2534_1 -# 2534| r2534_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2534| v2534_4(void) = Call[ClassWithDestructor] : func:r2534_3, this:r2534_1 -# 2534| m2534_5(unknown) = ^CallSideEffect : ~m2533_4 -# 2534| m2534_6(unknown) = Chi : total:m2533_4, partial:m2534_5 -# 2534| m2534_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2534_1 -# 2534| m2534_8(ClassWithDestructor) = Chi : total:m2534_2, partial:m2534_7 -# 2536| r2536_1(glval) = VariableAddress[#throw2536:5] : -# 2536| r2536_2(int) = Constant[42] : -# 2536| m2536_3(int) = Store[#throw2536:5] : &:r2536_1, r2536_2 -# 2536| v2536_4(void) = ThrowValue : &:r2536_1, m2536_3 +# 2531| Block 3 +# 2531| m2531_17(unknown) = Phi : from 1:~m2531_5, from 2:~m2531_13 +# 2531| v2531_18(void) = NoOp : +# 2532| v2532_1(void) = NoOp : +# 2522| v2522_7(void) = ReturnVoid : +# 2522| v2522_8(void) = AliasedUse : ~m2531_17 +# 2522| v2522_9(void) = ExitFunction : + +# 2534| void destructor_possibly_not_handled() +# 2534| Block 0 +# 2534| v2534_1(void) = EnterFunction : +# 2534| m2534_2(unknown) = AliasedDefinition : +# 2534| m2534_3(unknown) = InitializeNonLocal : +# 2534| m2534_4(unknown) = Chi : total:m2534_2, partial:m2534_3 +# 2535| r2535_1(glval) = VariableAddress[x] : +# 2535| m2535_2(ClassWithDestructor) = Uninitialized[x] : &:r2535_1 +# 2535| r2535_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2535| v2535_4(void) = Call[ClassWithDestructor] : func:r2535_3, this:r2535_1 +# 2535| m2535_5(unknown) = ^CallSideEffect : ~m2534_4 +# 2535| m2535_6(unknown) = Chi : total:m2534_4, partial:m2535_5 +# 2535| m2535_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2535_1 +# 2535| m2535_8(ClassWithDestructor) = Chi : total:m2535_2, partial:m2535_7 +# 2537| r2537_1(glval) = VariableAddress[#throw2537:5] : +# 2537| r2537_2(int) = Constant[42] : +# 2537| m2537_3(int) = Store[#throw2537:5] : &:r2537_1, r2537_2 +# 2537| v2537_4(void) = ThrowValue : &:r2537_1, m2537_3 #-----| Exception -> Block 3 -# 2533| Block 1 -# 2533| m2533_5(unknown) = Phi : from 2:~m2534_6, from 4:~m2540_14 -# 2533| v2533_6(void) = AliasedUse : ~m2533_5 -# 2533| v2533_7(void) = ExitFunction : +# 2534| Block 1 +# 2534| m2534_5(unknown) = Phi : from 2:~m2535_6, from 4:~m2541_14 +# 2534| v2534_6(void) = AliasedUse : ~m2534_5 +# 2534| v2534_7(void) = ExitFunction : -# 2533| Block 2 -# 2533| v2533_8(void) = Unwind : +# 2534| Block 2 +# 2534| v2534_8(void) = Unwind : #-----| Goto -> Block 1 -# 2538| Block 3 -# 2538| v2538_1(void) = CatchByType[char] : +# 2539| Block 3 +# 2539| v2539_1(void) = CatchByType[char] : #-----| Exception -> Block 2 #-----| Goto -> Block 4 -# 2538| Block 4 -# 2538| r2538_2(glval) = VariableAddress[(unnamed parameter 0)] : -# 2538| m2538_3(char) = InitializeParameter[(unnamed parameter 0)] : &:r2538_2 -# 2538| v2538_4(void) = NoOp : -# 2540| r2540_1(glval) = VariableAddress[x] : -# 2540| r2540_2(glval) = FunctionAddress[~ClassWithDestructor] : -# 2540| v2540_3(void) = Call[~ClassWithDestructor] : func:r2540_2, this:r2540_1 -# 2540| m2540_4(unknown) = ^CallSideEffect : ~m2534_6 -# 2540| m2540_5(unknown) = Chi : total:m2534_6, partial:m2540_4 -# 2540| v2540_6(void) = ^IndirectReadSideEffect[-1] : &:r2540_1, m2534_8 -# 2540| m2540_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2540_1 -# 2540| m2540_8(ClassWithDestructor) = Chi : total:m2534_8, partial:m2540_7 -# 2540| v2540_9(void) = NoOp : -# 2540| r2540_10(glval) = VariableAddress[x] : -# 2540| r2540_11(glval) = FunctionAddress[~ClassWithDestructor] : -# 2540| v2540_12(void) = Call[~ClassWithDestructor] : func:r2540_11, this:r2540_10 -# 2540| m2540_13(unknown) = ^CallSideEffect : ~m2540_5 -# 2540| m2540_14(unknown) = Chi : total:m2540_5, partial:m2540_13 -# 2540| v2540_15(void) = ^IndirectReadSideEffect[-1] : &:r2540_10, m2540_8 -# 2540| m2540_16(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2540_10 -# 2540| m2540_17(ClassWithDestructor) = Chi : total:m2540_8, partial:m2540_16 -# 2533| v2533_9(void) = ReturnVoid : +# 2539| Block 4 +# 2539| r2539_2(glval) = VariableAddress[(unnamed parameter 0)] : +# 2539| m2539_3(char) = InitializeParameter[(unnamed parameter 0)] : &:r2539_2 +# 2539| v2539_4(void) = NoOp : +# 2541| r2541_1(glval) = VariableAddress[x] : +# 2541| r2541_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2541| v2541_3(void) = Call[~ClassWithDestructor] : func:r2541_2, this:r2541_1 +# 2541| m2541_4(unknown) = ^CallSideEffect : ~m2535_6 +# 2541| m2541_5(unknown) = Chi : total:m2535_6, partial:m2541_4 +# 2541| v2541_6(void) = ^IndirectReadSideEffect[-1] : &:r2541_1, m2535_8 +# 2541| m2541_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2541_1 +# 2541| m2541_8(ClassWithDestructor) = Chi : total:m2535_8, partial:m2541_7 +# 2541| v2541_9(void) = NoOp : +# 2541| r2541_10(glval) = VariableAddress[x] : +# 2541| r2541_11(glval) = FunctionAddress[~ClassWithDestructor] : +# 2541| v2541_12(void) = Call[~ClassWithDestructor] : func:r2541_11, this:r2541_10 +# 2541| m2541_13(unknown) = ^CallSideEffect : ~m2541_5 +# 2541| m2541_14(unknown) = Chi : total:m2541_5, partial:m2541_13 +# 2541| v2541_15(void) = ^IndirectReadSideEffect[-1] : &:r2541_10, m2541_8 +# 2541| m2541_16(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2541_10 +# 2541| m2541_17(ClassWithDestructor) = Chi : total:m2541_8, partial:m2541_16 +# 2534| v2534_9(void) = ReturnVoid : #-----| Goto -> Block 1 perf-regression.cpp: diff --git a/cpp/ql/test/library-tests/ir/ir/ir.cpp b/cpp/ql/test/library-tests/ir/ir/ir.cpp index 35ea60715ccb..159c7173310f 100644 --- a/cpp/ql/test/library-tests/ir/ir/ir.cpp +++ b/cpp/ql/test/library-tests/ir/ir/ir.cpp @@ -2191,6 +2191,7 @@ class ClassWithDestructor { void set_x(char y) { *x = y; } char get_x() { return *x; } + operator bool() const; }; constexpr bool initialization_with_destructor_bool = true; @@ -2539,4 +2540,18 @@ void destructor_possibly_not_handled() { } } +// ClassWithDestructor getClassWithDestructor(); + +// void this_inconsistency(bool b) { +// if (const ClassWithDestructor& a = getClassWithDestructor()) +// ; +// } + +// constexpr bool initialization_with_destructor_bool = true; + +// void constexpr_inconsistency(bool b) { +// if constexpr (const ClassWithDestructor& a = getClassWithDestructor(); initialization_with_destructor_bool) +// ; +// } + // semmle-extractor-options: -std=c++20 --clang diff --git a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected index 404d48758b83..eabbc4c30647 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -14108,2174 +14108,2174 @@ ir.cpp: # 2193| v2193_18(void) = AliasedUse : ~m? # 2193| v2193_19(void) = ExitFunction : -# 2196| bool initialization_with_destructor_bool -# 2196| Block 0 -# 2196| v2196_1(void) = EnterFunction : -# 2196| mu2196_2(unknown) = AliasedDefinition : -# 2196| r2196_3(glval) = VariableAddress[initialization_with_destructor_bool] : -# 2196| r2196_4(bool) = Constant[1] : -# 2196| mu2196_5(bool) = Store[initialization_with_destructor_bool] : &:r2196_3, r2196_4 -# 2196| v2196_6(void) = ReturnVoid : -# 2196| v2196_7(void) = AliasedUse : ~m? -# 2196| v2196_8(void) = ExitFunction : - -# 2198| void initialization_with_destructor(bool, char) -# 2198| Block 0 -# 2198| v2198_1(void) = EnterFunction : -# 2198| mu2198_2(unknown) = AliasedDefinition : -# 2198| mu2198_3(unknown) = InitializeNonLocal : -# 2198| r2198_4(glval) = VariableAddress[b] : -# 2198| mu2198_5(bool) = InitializeParameter[b] : &:r2198_4 -# 2198| r2198_6(glval) = VariableAddress[c] : -# 2198| mu2198_7(char) = InitializeParameter[c] : &:r2198_6 -# 2199| r2199_1(glval) = VariableAddress[x] : -# 2199| mu2199_2(ClassWithDestructor) = Uninitialized[x] : &:r2199_1 -# 2199| r2199_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2199| v2199_4(void) = Call[ClassWithDestructor] : func:r2199_3, this:r2199_1 -# 2199| mu2199_5(unknown) = ^CallSideEffect : ~m? -# 2199| mu2199_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2199_1 -# 2199| r2199_7(glval) = VariableAddress[b] : -# 2199| r2199_8(bool) = Load[b] : &:r2199_7, ~m? -# 2199| v2199_9(void) = ConditionalBranch : r2199_8 +# 2197| bool initialization_with_destructor_bool +# 2197| Block 0 +# 2197| v2197_1(void) = EnterFunction : +# 2197| mu2197_2(unknown) = AliasedDefinition : +# 2197| r2197_3(glval) = VariableAddress[initialization_with_destructor_bool] : +# 2197| r2197_4(bool) = Constant[1] : +# 2197| mu2197_5(bool) = Store[initialization_with_destructor_bool] : &:r2197_3, r2197_4 +# 2197| v2197_6(void) = ReturnVoid : +# 2197| v2197_7(void) = AliasedUse : ~m? +# 2197| v2197_8(void) = ExitFunction : + +# 2199| void initialization_with_destructor(bool, char) +# 2199| Block 0 +# 2199| v2199_1(void) = EnterFunction : +# 2199| mu2199_2(unknown) = AliasedDefinition : +# 2199| mu2199_3(unknown) = InitializeNonLocal : +# 2199| r2199_4(glval) = VariableAddress[b] : +# 2199| mu2199_5(bool) = InitializeParameter[b] : &:r2199_4 +# 2199| r2199_6(glval) = VariableAddress[c] : +# 2199| mu2199_7(char) = InitializeParameter[c] : &:r2199_6 +# 2200| r2200_1(glval) = VariableAddress[x] : +# 2200| mu2200_2(ClassWithDestructor) = Uninitialized[x] : &:r2200_1 +# 2200| r2200_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2200| v2200_4(void) = Call[ClassWithDestructor] : func:r2200_3, this:r2200_1 +# 2200| mu2200_5(unknown) = ^CallSideEffect : ~m? +# 2200| mu2200_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2200_1 +# 2200| r2200_7(glval) = VariableAddress[b] : +# 2200| r2200_8(bool) = Load[b] : &:r2200_7, ~m? +# 2200| v2200_9(void) = ConditionalBranch : r2200_8 #-----| False -> Block 3 #-----| True -> Block 2 -# 2198| Block 1 -# 2198| v2198_8(void) = ReturnVoid : -# 2198| v2198_9(void) = AliasedUse : ~m? -# 2198| v2198_10(void) = ExitFunction : - -# 2200| Block 2 -# 2200| r2200_1(glval) = VariableAddress[x] : -# 2200| r2200_2(glval) = FunctionAddress[set_x] : -# 2200| r2200_3(char) = Constant[97] : -# 2200| v2200_4(void) = Call[set_x] : func:r2200_2, this:r2200_1, 0:r2200_3 -# 2200| mu2200_5(unknown) = ^CallSideEffect : ~m? -# 2200| v2200_6(void) = ^IndirectReadSideEffect[-1] : &:r2200_1, ~m? -# 2200| mu2200_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2200_1 -# 2200| r2200_8(glval) = VariableAddress[x] : -# 2200| r2200_9(glval) = FunctionAddress[~ClassWithDestructor] : -# 2200| v2200_10(void) = Call[~ClassWithDestructor] : func:r2200_9, this:r2200_8 -# 2200| mu2200_11(unknown) = ^CallSideEffect : ~m? -# 2200| v2200_12(void) = ^IndirectReadSideEffect[-1] : &:r2200_8, ~m? -# 2200| mu2200_13(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2200_8 +# 2199| Block 1 +# 2199| v2199_8(void) = ReturnVoid : +# 2199| v2199_9(void) = AliasedUse : ~m? +# 2199| v2199_10(void) = ExitFunction : + +# 2201| Block 2 +# 2201| r2201_1(glval) = VariableAddress[x] : +# 2201| r2201_2(glval) = FunctionAddress[set_x] : +# 2201| r2201_3(char) = Constant[97] : +# 2201| v2201_4(void) = Call[set_x] : func:r2201_2, this:r2201_1, 0:r2201_3 +# 2201| mu2201_5(unknown) = ^CallSideEffect : ~m? +# 2201| v2201_6(void) = ^IndirectReadSideEffect[-1] : &:r2201_1, ~m? +# 2201| mu2201_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2201_1 +# 2201| r2201_8(glval) = VariableAddress[x] : +# 2201| r2201_9(glval) = FunctionAddress[~ClassWithDestructor] : +# 2201| v2201_10(void) = Call[~ClassWithDestructor] : func:r2201_9, this:r2201_8 +# 2201| mu2201_11(unknown) = ^CallSideEffect : ~m? +# 2201| v2201_12(void) = ^IndirectReadSideEffect[-1] : &:r2201_8, ~m? +# 2201| mu2201_13(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2201_8 #-----| Goto -> Block 3 -# 2202| Block 3 -# 2202| r2202_1(glval) = VariableAddress[x] : -# 2202| mu2202_2(ClassWithDestructor) = Uninitialized[x] : &:r2202_1 -# 2202| r2202_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2202| v2202_4(void) = Call[ClassWithDestructor] : func:r2202_3, this:r2202_1 -# 2202| mu2202_5(unknown) = ^CallSideEffect : ~m? -# 2202| mu2202_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2202_1 -# 2202| r2202_7(bool) = Constant[1] : -# 2202| v2202_8(void) = ConditionalBranch : r2202_7 +# 2203| Block 3 +# 2203| r2203_1(glval) = VariableAddress[x] : +# 2203| mu2203_2(ClassWithDestructor) = Uninitialized[x] : &:r2203_1 +# 2203| r2203_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2203| v2203_4(void) = Call[ClassWithDestructor] : func:r2203_3, this:r2203_1 +# 2203| mu2203_5(unknown) = ^CallSideEffect : ~m? +# 2203| mu2203_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2203_1 +# 2203| r2203_7(bool) = Constant[1] : +# 2203| v2203_8(void) = ConditionalBranch : r2203_7 #-----| False -> Block 6 #-----| True -> Block 4 -# 2203| Block 4 -# 2203| r2203_1(glval) = VariableAddress[x] : -# 2203| r2203_2(glval) = FunctionAddress[set_x] : -# 2203| r2203_3(char) = Constant[97] : -# 2203| v2203_4(void) = Call[set_x] : func:r2203_2, this:r2203_1, 0:r2203_3 -# 2203| mu2203_5(unknown) = ^CallSideEffect : ~m? -# 2203| v2203_6(void) = ^IndirectReadSideEffect[-1] : &:r2203_1, ~m? -# 2203| mu2203_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2203_1 +# 2204| Block 4 +# 2204| r2204_1(glval) = VariableAddress[x] : +# 2204| r2204_2(glval) = FunctionAddress[set_x] : +# 2204| r2204_3(char) = Constant[97] : +# 2204| v2204_4(void) = Call[set_x] : func:r2204_2, this:r2204_1, 0:r2204_3 +# 2204| mu2204_5(unknown) = ^CallSideEffect : ~m? +# 2204| v2204_6(void) = ^IndirectReadSideEffect[-1] : &:r2204_1, ~m? +# 2204| mu2204_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2204_1 #-----| Goto -> Block 6 -# 2203| Block 5 -# 2203| r2203_8(glval) = VariableAddress[x] : -# 2203| r2203_9(glval) = FunctionAddress[~ClassWithDestructor] : -# 2203| v2203_10(void) = Call[~ClassWithDestructor] : func:r2203_9, this:r2203_8 -# 2203| mu2203_11(unknown) = ^CallSideEffect : ~m? -# 2203| v2203_12(void) = ^IndirectReadSideEffect[-1] : &:r2203_8, ~m? -# 2203| mu2203_13(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2203_8 +# 2204| Block 5 +# 2204| r2204_8(glval) = VariableAddress[x] : +# 2204| r2204_9(glval) = FunctionAddress[~ClassWithDestructor] : +# 2204| v2204_10(void) = Call[~ClassWithDestructor] : func:r2204_9, this:r2204_8 +# 2204| mu2204_11(unknown) = ^CallSideEffect : ~m? +# 2204| v2204_12(void) = ^IndirectReadSideEffect[-1] : &:r2204_8, ~m? +# 2204| mu2204_13(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2204_8 #-----| Goto -> Block 6 -# 2205| Block 6 -# 2205| r2205_1(glval) = VariableAddress[x] : -# 2205| mu2205_2(ClassWithDestructor) = Uninitialized[x] : &:r2205_1 -# 2205| r2205_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2205| v2205_4(void) = Call[ClassWithDestructor] : func:r2205_3, this:r2205_1 -# 2205| mu2205_5(unknown) = ^CallSideEffect : ~m? -# 2205| mu2205_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2205_1 -# 2205| r2205_7(glval) = VariableAddress[c] : -# 2205| r2205_8(char) = Load[c] : &:r2205_7, ~m? -# 2205| r2205_9(int) = Convert : r2205_8 -# 2205| v2205_10(void) = Switch : r2205_9 +# 2206| Block 6 +# 2206| r2206_1(glval) = VariableAddress[x] : +# 2206| mu2206_2(ClassWithDestructor) = Uninitialized[x] : &:r2206_1 +# 2206| r2206_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2206| v2206_4(void) = Call[ClassWithDestructor] : func:r2206_3, this:r2206_1 +# 2206| mu2206_5(unknown) = ^CallSideEffect : ~m? +# 2206| mu2206_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2206_1 +# 2206| r2206_7(glval) = VariableAddress[c] : +# 2206| r2206_8(char) = Load[c] : &:r2206_7, ~m? +# 2206| r2206_9(int) = Convert : r2206_8 +# 2206| v2206_10(void) = Switch : r2206_9 #-----| Case[97] -> Block 7 #-----| Default -> Block 8 -# 2206| Block 7 -# 2206| v2206_1(void) = NoOp : -# 2207| r2207_1(glval) = VariableAddress[x] : -# 2207| r2207_2(glval) = FunctionAddress[set_x] : -# 2207| r2207_3(char) = Constant[97] : -# 2207| v2207_4(void) = Call[set_x] : func:r2207_2, this:r2207_1, 0:r2207_3 -# 2207| mu2207_5(unknown) = ^CallSideEffect : ~m? -# 2207| v2207_6(void) = ^IndirectReadSideEffect[-1] : &:r2207_1, ~m? -# 2207| mu2207_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2207_1 -# 2212| r2212_1(glval) = VariableAddress[x] : -# 2212| r2212_2(glval) = FunctionAddress[~ClassWithDestructor] : -# 2212| v2212_3(void) = Call[~ClassWithDestructor] : func:r2212_2, this:r2212_1 -# 2212| mu2212_4(unknown) = ^CallSideEffect : ~m? -# 2212| v2212_5(void) = ^IndirectReadSideEffect[-1] : &:r2212_1, ~m? -# 2212| mu2212_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2212_1 -# 2208| v2208_1(void) = NoOp : +# 2207| Block 7 +# 2207| v2207_1(void) = NoOp : +# 2208| r2208_1(glval) = VariableAddress[x] : +# 2208| r2208_2(glval) = FunctionAddress[set_x] : +# 2208| r2208_3(char) = Constant[97] : +# 2208| v2208_4(void) = Call[set_x] : func:r2208_2, this:r2208_1, 0:r2208_3 +# 2208| mu2208_5(unknown) = ^CallSideEffect : ~m? +# 2208| v2208_6(void) = ^IndirectReadSideEffect[-1] : &:r2208_1, ~m? +# 2208| mu2208_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2208_1 +# 2213| r2213_1(glval) = VariableAddress[x] : +# 2213| r2213_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2213| v2213_3(void) = Call[~ClassWithDestructor] : func:r2213_2, this:r2213_1 +# 2213| mu2213_4(unknown) = ^CallSideEffect : ~m? +# 2213| v2213_5(void) = ^IndirectReadSideEffect[-1] : &:r2213_1, ~m? +# 2213| mu2213_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2213_1 +# 2209| v2209_1(void) = NoOp : #-----| Goto -> Block 10 -# 2209| Block 8 -# 2209| v2209_1(void) = NoOp : -# 2210| r2210_1(glval) = VariableAddress[x] : -# 2210| r2210_2(glval) = FunctionAddress[set_x] : -# 2210| r2210_3(char) = Constant[98] : -# 2210| v2210_4(void) = Call[set_x] : func:r2210_2, this:r2210_1, 0:r2210_3 -# 2210| mu2210_5(unknown) = ^CallSideEffect : ~m? -# 2210| v2210_6(void) = ^IndirectReadSideEffect[-1] : &:r2210_1, ~m? -# 2210| mu2210_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2210_1 -# 2212| r2212_7(glval) = VariableAddress[x] : -# 2212| r2212_8(glval) = FunctionAddress[~ClassWithDestructor] : -# 2212| v2212_9(void) = Call[~ClassWithDestructor] : func:r2212_8, this:r2212_7 -# 2212| mu2212_10(unknown) = ^CallSideEffect : ~m? -# 2212| v2212_11(void) = ^IndirectReadSideEffect[-1] : &:r2212_7, ~m? -# 2212| mu2212_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2212_7 -# 2211| v2211_1(void) = NoOp : +# 2210| Block 8 +# 2210| v2210_1(void) = NoOp : +# 2211| r2211_1(glval) = VariableAddress[x] : +# 2211| r2211_2(glval) = FunctionAddress[set_x] : +# 2211| r2211_3(char) = Constant[98] : +# 2211| v2211_4(void) = Call[set_x] : func:r2211_2, this:r2211_1, 0:r2211_3 +# 2211| mu2211_5(unknown) = ^CallSideEffect : ~m? +# 2211| v2211_6(void) = ^IndirectReadSideEffect[-1] : &:r2211_1, ~m? +# 2211| mu2211_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2211_1 +# 2213| r2213_7(glval) = VariableAddress[x] : +# 2213| r2213_8(glval) = FunctionAddress[~ClassWithDestructor] : +# 2213| v2213_9(void) = Call[~ClassWithDestructor] : func:r2213_8, this:r2213_7 +# 2213| mu2213_10(unknown) = ^CallSideEffect : ~m? +# 2213| v2213_11(void) = ^IndirectReadSideEffect[-1] : &:r2213_7, ~m? +# 2213| mu2213_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2213_7 +# 2212| v2212_1(void) = NoOp : #-----| Goto -> Block 10 -# 2212| Block 9 -# 2212| r2212_13(glval) = VariableAddress[x] : -# 2212| r2212_14(glval) = FunctionAddress[~ClassWithDestructor] : -# 2212| v2212_15(void) = Call[~ClassWithDestructor] : func:r2212_14, this:r2212_13 -# 2212| mu2212_16(unknown) = ^CallSideEffect : ~m? -# 2212| v2212_17(void) = ^IndirectReadSideEffect[-1] : &:r2212_13, ~m? -# 2212| mu2212_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2212_13 +# 2213| Block 9 +# 2213| r2213_13(glval) = VariableAddress[x] : +# 2213| r2213_14(glval) = FunctionAddress[~ClassWithDestructor] : +# 2213| v2213_15(void) = Call[~ClassWithDestructor] : func:r2213_14, this:r2213_13 +# 2213| mu2213_16(unknown) = ^CallSideEffect : ~m? +# 2213| v2213_17(void) = ^IndirectReadSideEffect[-1] : &:r2213_13, ~m? +# 2213| mu2213_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2213_13 #-----| Goto -> Block 10 -# 2212| Block 10 -# 2212| v2212_19(void) = NoOp : -# 2214| r2214_1(glval) = VariableAddress[x] : -# 2214| mu2214_2(ClassWithDestructor) = Uninitialized[x] : &:r2214_1 -# 2214| r2214_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2214| v2214_4(void) = Call[ClassWithDestructor] : func:r2214_3, this:r2214_1 -# 2214| mu2214_5(unknown) = ^CallSideEffect : ~m? -# 2214| mu2214_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2214_1 -# 2215| r2215_1(glval>) = VariableAddress[ys] : -# 2215| mu2215_2(vector) = Uninitialized[ys] : &:r2215_1 -# 2215| r2215_3(glval) = FunctionAddress[vector] : -# 2215| r2215_4(glval) = VariableAddress[#temp2215:45] : -# 2215| r2215_5(glval) = VariableAddress[x] : -# 2215| r2215_6(ClassWithDestructor) = Load[x] : &:r2215_5, ~m? -# 2215| mu2215_7(ClassWithDestructor) = Store[#temp2215:45] : &:r2215_4, r2215_6 -# 2215| r2215_8(ClassWithDestructor) = Load[#temp2215:45] : &:r2215_4, ~m? -# 2215| v2215_9(void) = Call[vector] : func:r2215_3, this:r2215_1, 0:r2215_8 -# 2215| mu2215_10(unknown) = ^CallSideEffect : ~m? -# 2215| mu2215_11(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2215_1 -# 2215| r2215_12(glval) = CopyValue : r2215_4 -# 2215| r2215_13(glval) = FunctionAddress[~ClassWithDestructor] : -# 2215| v2215_14(void) = Call[~ClassWithDestructor] : func:r2215_13, this:r2215_12 -# 2215| mu2215_15(unknown) = ^CallSideEffect : ~m? -# 2215| v2215_16(void) = ^IndirectReadSideEffect[-1] : &:r2215_12, ~m? -# 2215| mu2215_17(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2215_12 -# 2215| r2215_18(glval &>) = VariableAddress[(__range)] : -# 2215| r2215_19(glval>) = VariableAddress[ys] : -# 2215| r2215_20(vector &) = CopyValue : r2215_19 -# 2215| mu2215_21(vector &) = Store[(__range)] : &:r2215_18, r2215_20 -# 2215| r2215_22(glval>) = VariableAddress[(__begin)] : -# 2215| r2215_23(glval &>) = VariableAddress[(__range)] : -# 2215| r2215_24(vector &) = Load[(__range)] : &:r2215_23, ~m? -#-----| r0_1(glval>) = CopyValue : r2215_24 +# 2213| Block 10 +# 2213| v2213_19(void) = NoOp : +# 2215| r2215_1(glval) = VariableAddress[x] : +# 2215| mu2215_2(ClassWithDestructor) = Uninitialized[x] : &:r2215_1 +# 2215| r2215_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2215| v2215_4(void) = Call[ClassWithDestructor] : func:r2215_3, this:r2215_1 +# 2215| mu2215_5(unknown) = ^CallSideEffect : ~m? +# 2215| mu2215_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2215_1 +# 2216| r2216_1(glval>) = VariableAddress[ys] : +# 2216| mu2216_2(vector) = Uninitialized[ys] : &:r2216_1 +# 2216| r2216_3(glval) = FunctionAddress[vector] : +# 2216| r2216_4(glval) = VariableAddress[#temp2216:45] : +# 2216| r2216_5(glval) = VariableAddress[x] : +# 2216| r2216_6(ClassWithDestructor) = Load[x] : &:r2216_5, ~m? +# 2216| mu2216_7(ClassWithDestructor) = Store[#temp2216:45] : &:r2216_4, r2216_6 +# 2216| r2216_8(ClassWithDestructor) = Load[#temp2216:45] : &:r2216_4, ~m? +# 2216| v2216_9(void) = Call[vector] : func:r2216_3, this:r2216_1, 0:r2216_8 +# 2216| mu2216_10(unknown) = ^CallSideEffect : ~m? +# 2216| mu2216_11(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2216_1 +# 2216| r2216_12(glval) = CopyValue : r2216_4 +# 2216| r2216_13(glval) = FunctionAddress[~ClassWithDestructor] : +# 2216| v2216_14(void) = Call[~ClassWithDestructor] : func:r2216_13, this:r2216_12 +# 2216| mu2216_15(unknown) = ^CallSideEffect : ~m? +# 2216| v2216_16(void) = ^IndirectReadSideEffect[-1] : &:r2216_12, ~m? +# 2216| mu2216_17(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2216_12 +# 2216| r2216_18(glval &>) = VariableAddress[(__range)] : +# 2216| r2216_19(glval>) = VariableAddress[ys] : +# 2216| r2216_20(vector &) = CopyValue : r2216_19 +# 2216| mu2216_21(vector &) = Store[(__range)] : &:r2216_18, r2216_20 +# 2216| r2216_22(glval>) = VariableAddress[(__begin)] : +# 2216| r2216_23(glval &>) = VariableAddress[(__range)] : +# 2216| r2216_24(vector &) = Load[(__range)] : &:r2216_23, ~m? +#-----| r0_1(glval>) = CopyValue : r2216_24 #-----| r0_2(glval>) = Convert : r0_1 -# 2215| r2215_25(glval) = FunctionAddress[begin] : -# 2215| r2215_26(iterator) = Call[begin] : func:r2215_25, this:r0_2 +# 2216| r2216_25(glval) = FunctionAddress[begin] : +# 2216| r2216_26(iterator) = Call[begin] : func:r2216_25, this:r0_2 #-----| v0_3(void) = ^IndirectReadSideEffect[-1] : &:r0_2, ~m? -# 2215| mu2215_27(iterator) = Store[(__begin)] : &:r2215_22, r2215_26 -# 2215| r2215_28(glval>) = VariableAddress[(__end)] : -# 2215| r2215_29(glval &>) = VariableAddress[(__range)] : -# 2215| r2215_30(vector &) = Load[(__range)] : &:r2215_29, ~m? -#-----| r0_4(glval>) = CopyValue : r2215_30 +# 2216| mu2216_27(iterator) = Store[(__begin)] : &:r2216_22, r2216_26 +# 2216| r2216_28(glval>) = VariableAddress[(__end)] : +# 2216| r2216_29(glval &>) = VariableAddress[(__range)] : +# 2216| r2216_30(vector &) = Load[(__range)] : &:r2216_29, ~m? +#-----| r0_4(glval>) = CopyValue : r2216_30 #-----| r0_5(glval>) = Convert : r0_4 -# 2215| r2215_31(glval) = FunctionAddress[end] : -# 2215| r2215_32(iterator) = Call[end] : func:r2215_31, this:r0_5 +# 2216| r2216_31(glval) = FunctionAddress[end] : +# 2216| r2216_32(iterator) = Call[end] : func:r2216_31, this:r0_5 #-----| v0_6(void) = ^IndirectReadSideEffect[-1] : &:r0_5, ~m? -# 2215| mu2215_33(iterator) = Store[(__end)] : &:r2215_28, r2215_32 +# 2216| mu2216_33(iterator) = Store[(__end)] : &:r2216_28, r2216_32 #-----| Goto -> Block 11 -# 2215| Block 11 -# 2215| r2215_34(glval>) = VariableAddress[(__begin)] : -#-----| r0_7(glval>) = Convert : r2215_34 -# 2215| r2215_35(glval) = FunctionAddress[operator!=] : +# 2216| Block 11 +# 2216| r2216_34(glval>) = VariableAddress[(__begin)] : +#-----| r0_7(glval>) = Convert : r2216_34 +# 2216| r2216_35(glval) = FunctionAddress[operator!=] : #-----| r0_8(glval>) = VariableAddress[#temp0:0] : #-----| mu0_9(iterator) = Uninitialized[#temp0:0] : &:r0_8 -# 2215| r2215_36(glval) = FunctionAddress[iterator] : -# 2215| r2215_37(glval>) = VariableAddress[(__end)] : -#-----| r0_10(glval>) = Convert : r2215_37 +# 2216| r2216_36(glval) = FunctionAddress[iterator] : +# 2216| r2216_37(glval>) = VariableAddress[(__end)] : +#-----| r0_10(glval>) = Convert : r2216_37 #-----| r0_11(iterator &) = CopyValue : r0_10 -# 2215| v2215_38(void) = Call[iterator] : func:r2215_36, this:r0_8, 0:r0_11 -# 2215| mu2215_39(unknown) = ^CallSideEffect : ~m? +# 2216| v2216_38(void) = Call[iterator] : func:r2216_36, this:r0_8, 0:r0_11 +# 2216| mu2216_39(unknown) = ^CallSideEffect : ~m? #-----| v0_12(void) = ^BufferReadSideEffect[0] : &:r0_11, ~m? -# 2215| mu2215_40(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_8 +# 2216| mu2216_40(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_8 #-----| r0_13(iterator) = Load[#temp0:0] : &:r0_8, ~m? -# 2215| r2215_41(bool) = Call[operator!=] : func:r2215_35, this:r0_7, 0:r0_13 +# 2216| r2216_41(bool) = Call[operator!=] : func:r2216_35, this:r0_7, 0:r0_13 #-----| v0_14(void) = ^IndirectReadSideEffect[-1] : &:r0_7, ~m? -# 2215| v2215_42(void) = ConditionalBranch : r2215_41 +# 2216| v2216_42(void) = ConditionalBranch : r2216_41 #-----| False -> Block 13 #-----| True -> Block 12 -# 2215| Block 12 -# 2215| r2215_43(glval) = VariableAddress[y] : -# 2215| r2215_44(glval>) = VariableAddress[(__begin)] : -#-----| r0_15(glval>) = Convert : r2215_44 -# 2215| r2215_45(glval) = FunctionAddress[operator*] : -# 2215| r2215_46(ClassWithDestructor &) = Call[operator*] : func:r2215_45, this:r0_15 +# 2216| Block 12 +# 2216| r2216_43(glval) = VariableAddress[y] : +# 2216| r2216_44(glval>) = VariableAddress[(__begin)] : +#-----| r0_15(glval>) = Convert : r2216_44 +# 2216| r2216_45(glval) = FunctionAddress[operator*] : +# 2216| r2216_46(ClassWithDestructor &) = Call[operator*] : func:r2216_45, this:r0_15 #-----| v0_16(void) = ^IndirectReadSideEffect[-1] : &:r0_15, ~m? -# 2215| r2215_47(ClassWithDestructor) = Load[?] : &:r2215_46, ~m? -# 2215| mu2215_48(ClassWithDestructor) = Store[y] : &:r2215_43, r2215_47 -# 2216| r2216_1(glval) = VariableAddress[y] : -# 2216| r2216_2(glval) = FunctionAddress[set_x] : -# 2216| r2216_3(char) = Constant[97] : -# 2216| v2216_4(void) = Call[set_x] : func:r2216_2, this:r2216_1, 0:r2216_3 -# 2216| mu2216_5(unknown) = ^CallSideEffect : ~m? -# 2216| v2216_6(void) = ^IndirectReadSideEffect[-1] : &:r2216_1, ~m? -# 2216| mu2216_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2216_1 -# 2215| r2215_49(glval>) = VariableAddress[(__begin)] : -# 2215| r2215_50(glval) = FunctionAddress[operator++] : -# 2215| r2215_51(iterator &) = Call[operator++] : func:r2215_50, this:r2215_49 -# 2215| v2215_52(void) = ^IndirectReadSideEffect[-1] : &:r2215_49, ~m? -# 2215| mu2215_53(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2215_49 -# 2215| r2215_54(glval) = VariableAddress[y] : -# 2215| r2215_55(glval) = FunctionAddress[~ClassWithDestructor] : -# 2215| v2215_56(void) = Call[~ClassWithDestructor] : func:r2215_55, this:r2215_54 -# 2215| mu2215_57(unknown) = ^CallSideEffect : ~m? -# 2215| v2215_58(void) = ^IndirectReadSideEffect[-1] : &:r2215_54, ~m? -# 2215| mu2215_59(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2215_54 -# 2215| r2215_60(glval>) = CopyValue : r2215_51 +# 2216| r2216_47(ClassWithDestructor) = Load[?] : &:r2216_46, ~m? +# 2216| mu2216_48(ClassWithDestructor) = Store[y] : &:r2216_43, r2216_47 +# 2217| r2217_1(glval) = VariableAddress[y] : +# 2217| r2217_2(glval) = FunctionAddress[set_x] : +# 2217| r2217_3(char) = Constant[97] : +# 2217| v2217_4(void) = Call[set_x] : func:r2217_2, this:r2217_1, 0:r2217_3 +# 2217| mu2217_5(unknown) = ^CallSideEffect : ~m? +# 2217| v2217_6(void) = ^IndirectReadSideEffect[-1] : &:r2217_1, ~m? +# 2217| mu2217_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2217_1 +# 2216| r2216_49(glval>) = VariableAddress[(__begin)] : +# 2216| r2216_50(glval) = FunctionAddress[operator++] : +# 2216| r2216_51(iterator &) = Call[operator++] : func:r2216_50, this:r2216_49 +# 2216| v2216_52(void) = ^IndirectReadSideEffect[-1] : &:r2216_49, ~m? +# 2216| mu2216_53(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2216_49 +# 2216| r2216_54(glval) = VariableAddress[y] : +# 2216| r2216_55(glval) = FunctionAddress[~ClassWithDestructor] : +# 2216| v2216_56(void) = Call[~ClassWithDestructor] : func:r2216_55, this:r2216_54 +# 2216| mu2216_57(unknown) = ^CallSideEffect : ~m? +# 2216| v2216_58(void) = ^IndirectReadSideEffect[-1] : &:r2216_54, ~m? +# 2216| mu2216_59(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2216_54 +# 2216| r2216_60(glval>) = CopyValue : r2216_51 #-----| Goto (back edge) -> Block 11 -# 2215| Block 13 -# 2215| r2215_61(glval>) = VariableAddress[ys] : -# 2215| r2215_62(glval) = FunctionAddress[~vector] : -# 2215| v2215_63(void) = Call[~vector] : func:r2215_62, this:r2215_61 -# 2215| mu2215_64(unknown) = ^CallSideEffect : ~m? -# 2215| v2215_65(void) = ^IndirectReadSideEffect[-1] : &:r2215_61, ~m? -# 2215| mu2215_66(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2215_61 -# 2218| r2218_1(glval>) = VariableAddress[ys] : -# 2218| mu2218_2(vector) = Uninitialized[ys] : &:r2218_1 -# 2218| r2218_3(glval) = FunctionAddress[vector] : -# 2218| r2218_4(glval) = VariableAddress[#temp2218:45] : -# 2218| r2218_5(glval) = VariableAddress[x] : -# 2218| r2218_6(ClassWithDestructor) = Load[x] : &:r2218_5, ~m? -# 2218| mu2218_7(ClassWithDestructor) = Store[#temp2218:45] : &:r2218_4, r2218_6 -# 2218| r2218_8(ClassWithDestructor) = Load[#temp2218:45] : &:r2218_4, ~m? -# 2218| v2218_9(void) = Call[vector] : func:r2218_3, this:r2218_1, 0:r2218_8 -# 2218| mu2218_10(unknown) = ^CallSideEffect : ~m? -# 2218| mu2218_11(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2218_1 -# 2218| r2218_12(glval) = CopyValue : r2218_4 -# 2218| r2218_13(glval) = FunctionAddress[~ClassWithDestructor] : -# 2218| v2218_14(void) = Call[~ClassWithDestructor] : func:r2218_13, this:r2218_12 -# 2218| mu2218_15(unknown) = ^CallSideEffect : ~m? -# 2218| v2218_16(void) = ^IndirectReadSideEffect[-1] : &:r2218_12, ~m? -# 2218| mu2218_17(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2218_12 -# 2218| r2218_18(glval &>) = VariableAddress[(__range)] : -# 2218| r2218_19(glval>) = VariableAddress[ys] : -# 2218| r2218_20(vector &) = CopyValue : r2218_19 -# 2218| mu2218_21(vector &) = Store[(__range)] : &:r2218_18, r2218_20 -# 2218| r2218_22(glval>) = VariableAddress[(__begin)] : -# 2218| r2218_23(glval &>) = VariableAddress[(__range)] : -# 2218| r2218_24(vector &) = Load[(__range)] : &:r2218_23, ~m? -#-----| r0_17(glval>) = CopyValue : r2218_24 +# 2216| Block 13 +# 2216| r2216_61(glval>) = VariableAddress[ys] : +# 2216| r2216_62(glval) = FunctionAddress[~vector] : +# 2216| v2216_63(void) = Call[~vector] : func:r2216_62, this:r2216_61 +# 2216| mu2216_64(unknown) = ^CallSideEffect : ~m? +# 2216| v2216_65(void) = ^IndirectReadSideEffect[-1] : &:r2216_61, ~m? +# 2216| mu2216_66(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2216_61 +# 2219| r2219_1(glval>) = VariableAddress[ys] : +# 2219| mu2219_2(vector) = Uninitialized[ys] : &:r2219_1 +# 2219| r2219_3(glval) = FunctionAddress[vector] : +# 2219| r2219_4(glval) = VariableAddress[#temp2219:45] : +# 2219| r2219_5(glval) = VariableAddress[x] : +# 2219| r2219_6(ClassWithDestructor) = Load[x] : &:r2219_5, ~m? +# 2219| mu2219_7(ClassWithDestructor) = Store[#temp2219:45] : &:r2219_4, r2219_6 +# 2219| r2219_8(ClassWithDestructor) = Load[#temp2219:45] : &:r2219_4, ~m? +# 2219| v2219_9(void) = Call[vector] : func:r2219_3, this:r2219_1, 0:r2219_8 +# 2219| mu2219_10(unknown) = ^CallSideEffect : ~m? +# 2219| mu2219_11(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2219_1 +# 2219| r2219_12(glval) = CopyValue : r2219_4 +# 2219| r2219_13(glval) = FunctionAddress[~ClassWithDestructor] : +# 2219| v2219_14(void) = Call[~ClassWithDestructor] : func:r2219_13, this:r2219_12 +# 2219| mu2219_15(unknown) = ^CallSideEffect : ~m? +# 2219| v2219_16(void) = ^IndirectReadSideEffect[-1] : &:r2219_12, ~m? +# 2219| mu2219_17(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2219_12 +# 2219| r2219_18(glval &>) = VariableAddress[(__range)] : +# 2219| r2219_19(glval>) = VariableAddress[ys] : +# 2219| r2219_20(vector &) = CopyValue : r2219_19 +# 2219| mu2219_21(vector &) = Store[(__range)] : &:r2219_18, r2219_20 +# 2219| r2219_22(glval>) = VariableAddress[(__begin)] : +# 2219| r2219_23(glval &>) = VariableAddress[(__range)] : +# 2219| r2219_24(vector &) = Load[(__range)] : &:r2219_23, ~m? +#-----| r0_17(glval>) = CopyValue : r2219_24 #-----| r0_18(glval>) = Convert : r0_17 -# 2218| r2218_25(glval) = FunctionAddress[begin] : -# 2218| r2218_26(iterator) = Call[begin] : func:r2218_25, this:r0_18 +# 2219| r2219_25(glval) = FunctionAddress[begin] : +# 2219| r2219_26(iterator) = Call[begin] : func:r2219_25, this:r0_18 #-----| v0_19(void) = ^IndirectReadSideEffect[-1] : &:r0_18, ~m? -# 2218| mu2218_27(iterator) = Store[(__begin)] : &:r2218_22, r2218_26 -# 2218| r2218_28(glval>) = VariableAddress[(__end)] : -# 2218| r2218_29(glval &>) = VariableAddress[(__range)] : -# 2218| r2218_30(vector &) = Load[(__range)] : &:r2218_29, ~m? -#-----| r0_20(glval>) = CopyValue : r2218_30 +# 2219| mu2219_27(iterator) = Store[(__begin)] : &:r2219_22, r2219_26 +# 2219| r2219_28(glval>) = VariableAddress[(__end)] : +# 2219| r2219_29(glval &>) = VariableAddress[(__range)] : +# 2219| r2219_30(vector &) = Load[(__range)] : &:r2219_29, ~m? +#-----| r0_20(glval>) = CopyValue : r2219_30 #-----| r0_21(glval>) = Convert : r0_20 -# 2218| r2218_31(glval) = FunctionAddress[end] : -# 2218| r2218_32(iterator) = Call[end] : func:r2218_31, this:r0_21 +# 2219| r2219_31(glval) = FunctionAddress[end] : +# 2219| r2219_32(iterator) = Call[end] : func:r2219_31, this:r0_21 #-----| v0_22(void) = ^IndirectReadSideEffect[-1] : &:r0_21, ~m? -# 2218| mu2218_33(iterator) = Store[(__end)] : &:r2218_28, r2218_32 +# 2219| mu2219_33(iterator) = Store[(__end)] : &:r2219_28, r2219_32 #-----| Goto -> Block 14 -# 2218| Block 14 -# 2218| r2218_34(glval>) = VariableAddress[(__begin)] : -#-----| r0_23(glval>) = Convert : r2218_34 -# 2218| r2218_35(glval) = FunctionAddress[operator!=] : +# 2219| Block 14 +# 2219| r2219_34(glval>) = VariableAddress[(__begin)] : +#-----| r0_23(glval>) = Convert : r2219_34 +# 2219| r2219_35(glval) = FunctionAddress[operator!=] : #-----| r0_24(glval>) = VariableAddress[#temp0:0] : #-----| mu0_25(iterator) = Uninitialized[#temp0:0] : &:r0_24 -# 2218| r2218_36(glval) = FunctionAddress[iterator] : -# 2218| r2218_37(glval>) = VariableAddress[(__end)] : -#-----| r0_26(glval>) = Convert : r2218_37 +# 2219| r2219_36(glval) = FunctionAddress[iterator] : +# 2219| r2219_37(glval>) = VariableAddress[(__end)] : +#-----| r0_26(glval>) = Convert : r2219_37 #-----| r0_27(iterator &) = CopyValue : r0_26 -# 2218| v2218_38(void) = Call[iterator] : func:r2218_36, this:r0_24, 0:r0_27 -# 2218| mu2218_39(unknown) = ^CallSideEffect : ~m? +# 2219| v2219_38(void) = Call[iterator] : func:r2219_36, this:r0_24, 0:r0_27 +# 2219| mu2219_39(unknown) = ^CallSideEffect : ~m? #-----| v0_28(void) = ^BufferReadSideEffect[0] : &:r0_27, ~m? -# 2218| mu2218_40(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_24 +# 2219| mu2219_40(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_24 #-----| r0_29(iterator) = Load[#temp0:0] : &:r0_24, ~m? -# 2218| r2218_41(bool) = Call[operator!=] : func:r2218_35, this:r0_23, 0:r0_29 +# 2219| r2219_41(bool) = Call[operator!=] : func:r2219_35, this:r0_23, 0:r0_29 #-----| v0_30(void) = ^IndirectReadSideEffect[-1] : &:r0_23, ~m? -# 2218| v2218_42(void) = ConditionalBranch : r2218_41 +# 2219| v2219_42(void) = ConditionalBranch : r2219_41 #-----| False -> Block 18 #-----| True -> Block 16 -# 2218| Block 15 -# 2218| r2218_43(glval>) = VariableAddress[(__begin)] : -# 2218| r2218_44(glval) = FunctionAddress[operator++] : -# 2218| r2218_45(iterator &) = Call[operator++] : func:r2218_44, this:r2218_43 -# 2218| v2218_46(void) = ^IndirectReadSideEffect[-1] : &:r2218_43, ~m? -# 2218| mu2218_47(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2218_43 -# 2218| r2218_48(glval) = VariableAddress[y] : -# 2218| r2218_49(glval) = FunctionAddress[~ClassWithDestructor] : -# 2218| v2218_50(void) = Call[~ClassWithDestructor] : func:r2218_49, this:r2218_48 -# 2218| mu2218_51(unknown) = ^CallSideEffect : ~m? -# 2218| v2218_52(void) = ^IndirectReadSideEffect[-1] : &:r2218_48, ~m? -# 2218| mu2218_53(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2218_48 -# 2218| r2218_54(glval>) = CopyValue : r2218_45 +# 2219| Block 15 +# 2219| r2219_43(glval>) = VariableAddress[(__begin)] : +# 2219| r2219_44(glval) = FunctionAddress[operator++] : +# 2219| r2219_45(iterator &) = Call[operator++] : func:r2219_44, this:r2219_43 +# 2219| v2219_46(void) = ^IndirectReadSideEffect[-1] : &:r2219_43, ~m? +# 2219| mu2219_47(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2219_43 +# 2219| r2219_48(glval) = VariableAddress[y] : +# 2219| r2219_49(glval) = FunctionAddress[~ClassWithDestructor] : +# 2219| v2219_50(void) = Call[~ClassWithDestructor] : func:r2219_49, this:r2219_48 +# 2219| mu2219_51(unknown) = ^CallSideEffect : ~m? +# 2219| v2219_52(void) = ^IndirectReadSideEffect[-1] : &:r2219_48, ~m? +# 2219| mu2219_53(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2219_48 +# 2219| r2219_54(glval>) = CopyValue : r2219_45 #-----| Goto (back edge) -> Block 14 -# 2218| Block 16 -# 2218| r2218_55(glval) = VariableAddress[y] : -# 2218| r2218_56(glval>) = VariableAddress[(__begin)] : -#-----| r0_31(glval>) = Convert : r2218_56 -# 2218| r2218_57(glval) = FunctionAddress[operator*] : -# 2218| r2218_58(ClassWithDestructor &) = Call[operator*] : func:r2218_57, this:r0_31 +# 2219| Block 16 +# 2219| r2219_55(glval) = VariableAddress[y] : +# 2219| r2219_56(glval>) = VariableAddress[(__begin)] : +#-----| r0_31(glval>) = Convert : r2219_56 +# 2219| r2219_57(glval) = FunctionAddress[operator*] : +# 2219| r2219_58(ClassWithDestructor &) = Call[operator*] : func:r2219_57, this:r0_31 #-----| v0_32(void) = ^IndirectReadSideEffect[-1] : &:r0_31, ~m? -# 2218| r2218_59(ClassWithDestructor) = Load[?] : &:r2218_58, ~m? -# 2218| mu2218_60(ClassWithDestructor) = Store[y] : &:r2218_55, r2218_59 -# 2219| r2219_1(glval) = VariableAddress[y] : -# 2219| r2219_2(glval) = FunctionAddress[set_x] : -# 2219| r2219_3(char) = Constant[97] : -# 2219| v2219_4(void) = Call[set_x] : func:r2219_2, this:r2219_1, 0:r2219_3 -# 2219| mu2219_5(unknown) = ^CallSideEffect : ~m? -# 2219| v2219_6(void) = ^IndirectReadSideEffect[-1] : &:r2219_1, ~m? -# 2219| mu2219_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2219_1 +# 2219| r2219_59(ClassWithDestructor) = Load[?] : &:r2219_58, ~m? +# 2219| mu2219_60(ClassWithDestructor) = Store[y] : &:r2219_55, r2219_59 # 2220| r2220_1(glval) = VariableAddress[y] : -# 2220| r2220_2(glval) = FunctionAddress[get_x] : -# 2220| r2220_3(char) = Call[get_x] : func:r2220_2, this:r2220_1 -# 2220| mu2220_4(unknown) = ^CallSideEffect : ~m? -# 2220| v2220_5(void) = ^IndirectReadSideEffect[-1] : &:r2220_1, ~m? -# 2220| mu2220_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2220_1 -# 2220| r2220_7(int) = Convert : r2220_3 -# 2220| r2220_8(int) = Constant[98] : -# 2220| r2220_9(bool) = CompareEQ : r2220_7, r2220_8 -# 2220| v2220_10(void) = ConditionalBranch : r2220_9 +# 2220| r2220_2(glval) = FunctionAddress[set_x] : +# 2220| r2220_3(char) = Constant[97] : +# 2220| v2220_4(void) = Call[set_x] : func:r2220_2, this:r2220_1, 0:r2220_3 +# 2220| mu2220_5(unknown) = ^CallSideEffect : ~m? +# 2220| v2220_6(void) = ^IndirectReadSideEffect[-1] : &:r2220_1, ~m? +# 2220| mu2220_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2220_1 +# 2221| r2221_1(glval) = VariableAddress[y] : +# 2221| r2221_2(glval) = FunctionAddress[get_x] : +# 2221| r2221_3(char) = Call[get_x] : func:r2221_2, this:r2221_1 +# 2221| mu2221_4(unknown) = ^CallSideEffect : ~m? +# 2221| v2221_5(void) = ^IndirectReadSideEffect[-1] : &:r2221_1, ~m? +# 2221| mu2221_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2221_1 +# 2221| r2221_7(int) = Convert : r2221_3 +# 2221| r2221_8(int) = Constant[98] : +# 2221| r2221_9(bool) = CompareEQ : r2221_7, r2221_8 +# 2221| v2221_10(void) = ConditionalBranch : r2221_9 #-----| False -> Block 15 #-----| True -> Block 17 -# 2221| Block 17 -# 2221| v2221_1(void) = NoOp : -# 2218| r2218_61(glval) = VariableAddress[y] : -# 2218| r2218_62(glval) = FunctionAddress[~ClassWithDestructor] : -# 2218| v2218_63(void) = Call[~ClassWithDestructor] : func:r2218_62, this:r2218_61 -# 2218| mu2218_64(unknown) = ^CallSideEffect : ~m? -# 2218| v2218_65(void) = ^IndirectReadSideEffect[-1] : &:r2218_61, ~m? -# 2218| mu2218_66(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2218_61 -# 2218| r2218_67(glval>) = VariableAddress[ys] : -# 2218| r2218_68(glval) = FunctionAddress[~vector] : -# 2218| v2218_69(void) = Call[~vector] : func:r2218_68, this:r2218_67 -# 2218| mu2218_70(unknown) = ^CallSideEffect : ~m? -# 2218| v2218_71(void) = ^IndirectReadSideEffect[-1] : &:r2218_67, ~m? -# 2218| mu2218_72(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2218_67 -# 2233| r2233_1(glval) = VariableAddress[x] : -# 2233| r2233_2(glval) = FunctionAddress[~ClassWithDestructor] : -# 2233| v2233_3(void) = Call[~ClassWithDestructor] : func:r2233_2, this:r2233_1 -# 2233| mu2233_4(unknown) = ^CallSideEffect : ~m? -# 2233| v2233_5(void) = ^IndirectReadSideEffect[-1] : &:r2233_1, ~m? -# 2233| mu2233_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2233_1 +# 2222| Block 17 +# 2222| v2222_1(void) = NoOp : +# 2219| r2219_61(glval) = VariableAddress[y] : +# 2219| r2219_62(glval) = FunctionAddress[~ClassWithDestructor] : +# 2219| v2219_63(void) = Call[~ClassWithDestructor] : func:r2219_62, this:r2219_61 +# 2219| mu2219_64(unknown) = ^CallSideEffect : ~m? +# 2219| v2219_65(void) = ^IndirectReadSideEffect[-1] : &:r2219_61, ~m? +# 2219| mu2219_66(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2219_61 +# 2219| r2219_67(glval>) = VariableAddress[ys] : +# 2219| r2219_68(glval) = FunctionAddress[~vector] : +# 2219| v2219_69(void) = Call[~vector] : func:r2219_68, this:r2219_67 +# 2219| mu2219_70(unknown) = ^CallSideEffect : ~m? +# 2219| v2219_71(void) = ^IndirectReadSideEffect[-1] : &:r2219_67, ~m? +# 2219| mu2219_72(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2219_67 +# 2234| r2234_1(glval) = VariableAddress[x] : +# 2234| r2234_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2234| v2234_3(void) = Call[~ClassWithDestructor] : func:r2234_2, this:r2234_1 +# 2234| mu2234_4(unknown) = ^CallSideEffect : ~m? +# 2234| v2234_5(void) = ^IndirectReadSideEffect[-1] : &:r2234_1, ~m? +# 2234| mu2234_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2234_1 #-----| Goto -> Block 1 -# 2218| Block 18 -# 2218| r2218_73(glval>) = VariableAddress[ys] : -# 2218| r2218_74(glval) = FunctionAddress[~vector] : -# 2218| v2218_75(void) = Call[~vector] : func:r2218_74, this:r2218_73 -# 2218| mu2218_76(unknown) = ^CallSideEffect : ~m? -# 2218| v2218_77(void) = ^IndirectReadSideEffect[-1] : &:r2218_73, ~m? -# 2218| mu2218_78(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2218_73 -# 2224| r2224_1(glval>) = VariableAddress[ys] : -# 2224| mu2224_2(vector) = Uninitialized[ys] : &:r2224_1 -# 2224| r2224_3(glval) = FunctionAddress[vector] : -# 2224| r2224_4(int) = Constant[1] : -# 2224| v2224_5(void) = Call[vector] : func:r2224_3, this:r2224_1, 0:r2224_4 -# 2224| mu2224_6(unknown) = ^CallSideEffect : ~m? -# 2224| mu2224_7(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2224_1 -# 2224| r2224_8(glval &>) = VariableAddress[(__range)] : -# 2224| r2224_9(glval>) = VariableAddress[ys] : -# 2224| r2224_10(vector &) = CopyValue : r2224_9 -# 2224| mu2224_11(vector &) = Store[(__range)] : &:r2224_8, r2224_10 -# 2224| r2224_12(glval>) = VariableAddress[(__begin)] : -# 2224| r2224_13(glval &>) = VariableAddress[(__range)] : -# 2224| r2224_14(vector &) = Load[(__range)] : &:r2224_13, ~m? -#-----| r0_33(glval>) = CopyValue : r2224_14 +# 2219| Block 18 +# 2219| r2219_73(glval>) = VariableAddress[ys] : +# 2219| r2219_74(glval) = FunctionAddress[~vector] : +# 2219| v2219_75(void) = Call[~vector] : func:r2219_74, this:r2219_73 +# 2219| mu2219_76(unknown) = ^CallSideEffect : ~m? +# 2219| v2219_77(void) = ^IndirectReadSideEffect[-1] : &:r2219_73, ~m? +# 2219| mu2219_78(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2219_73 +# 2225| r2225_1(glval>) = VariableAddress[ys] : +# 2225| mu2225_2(vector) = Uninitialized[ys] : &:r2225_1 +# 2225| r2225_3(glval) = FunctionAddress[vector] : +# 2225| r2225_4(int) = Constant[1] : +# 2225| v2225_5(void) = Call[vector] : func:r2225_3, this:r2225_1, 0:r2225_4 +# 2225| mu2225_6(unknown) = ^CallSideEffect : ~m? +# 2225| mu2225_7(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2225_1 +# 2225| r2225_8(glval &>) = VariableAddress[(__range)] : +# 2225| r2225_9(glval>) = VariableAddress[ys] : +# 2225| r2225_10(vector &) = CopyValue : r2225_9 +# 2225| mu2225_11(vector &) = Store[(__range)] : &:r2225_8, r2225_10 +# 2225| r2225_12(glval>) = VariableAddress[(__begin)] : +# 2225| r2225_13(glval &>) = VariableAddress[(__range)] : +# 2225| r2225_14(vector &) = Load[(__range)] : &:r2225_13, ~m? +#-----| r0_33(glval>) = CopyValue : r2225_14 #-----| r0_34(glval>) = Convert : r0_33 -# 2224| r2224_15(glval) = FunctionAddress[begin] : -# 2224| r2224_16(iterator) = Call[begin] : func:r2224_15, this:r0_34 +# 2225| r2225_15(glval) = FunctionAddress[begin] : +# 2225| r2225_16(iterator) = Call[begin] : func:r2225_15, this:r0_34 #-----| v0_35(void) = ^IndirectReadSideEffect[-1] : &:r0_34, ~m? -# 2224| mu2224_17(iterator) = Store[(__begin)] : &:r2224_12, r2224_16 -# 2224| r2224_18(glval>) = VariableAddress[(__end)] : -# 2224| r2224_19(glval &>) = VariableAddress[(__range)] : -# 2224| r2224_20(vector &) = Load[(__range)] : &:r2224_19, ~m? -#-----| r0_36(glval>) = CopyValue : r2224_20 +# 2225| mu2225_17(iterator) = Store[(__begin)] : &:r2225_12, r2225_16 +# 2225| r2225_18(glval>) = VariableAddress[(__end)] : +# 2225| r2225_19(glval &>) = VariableAddress[(__range)] : +# 2225| r2225_20(vector &) = Load[(__range)] : &:r2225_19, ~m? +#-----| r0_36(glval>) = CopyValue : r2225_20 #-----| r0_37(glval>) = Convert : r0_36 -# 2224| r2224_21(glval) = FunctionAddress[end] : -# 2224| r2224_22(iterator) = Call[end] : func:r2224_21, this:r0_37 +# 2225| r2225_21(glval) = FunctionAddress[end] : +# 2225| r2225_22(iterator) = Call[end] : func:r2225_21, this:r0_37 #-----| v0_38(void) = ^IndirectReadSideEffect[-1] : &:r0_37, ~m? -# 2224| mu2224_23(iterator) = Store[(__end)] : &:r2224_18, r2224_22 +# 2225| mu2225_23(iterator) = Store[(__end)] : &:r2225_18, r2225_22 #-----| Goto -> Block 19 -# 2224| Block 19 -# 2224| r2224_24(glval>) = VariableAddress[(__begin)] : -#-----| r0_39(glval>) = Convert : r2224_24 -# 2224| r2224_25(glval) = FunctionAddress[operator!=] : +# 2225| Block 19 +# 2225| r2225_24(glval>) = VariableAddress[(__begin)] : +#-----| r0_39(glval>) = Convert : r2225_24 +# 2225| r2225_25(glval) = FunctionAddress[operator!=] : #-----| r0_40(glval>) = VariableAddress[#temp0:0] : #-----| mu0_41(iterator) = Uninitialized[#temp0:0] : &:r0_40 -# 2224| r2224_26(glval) = FunctionAddress[iterator] : -# 2224| r2224_27(glval>) = VariableAddress[(__end)] : -#-----| r0_42(glval>) = Convert : r2224_27 +# 2225| r2225_26(glval) = FunctionAddress[iterator] : +# 2225| r2225_27(glval>) = VariableAddress[(__end)] : +#-----| r0_42(glval>) = Convert : r2225_27 #-----| r0_43(iterator &) = CopyValue : r0_42 -# 2224| v2224_28(void) = Call[iterator] : func:r2224_26, this:r0_40, 0:r0_43 -# 2224| mu2224_29(unknown) = ^CallSideEffect : ~m? +# 2225| v2225_28(void) = Call[iterator] : func:r2225_26, this:r0_40, 0:r0_43 +# 2225| mu2225_29(unknown) = ^CallSideEffect : ~m? #-----| v0_44(void) = ^BufferReadSideEffect[0] : &:r0_43, ~m? -# 2224| mu2224_30(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_40 +# 2225| mu2225_30(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_40 #-----| r0_45(iterator) = Load[#temp0:0] : &:r0_40, ~m? -# 2224| r2224_31(bool) = Call[operator!=] : func:r2224_25, this:r0_39, 0:r0_45 +# 2225| r2225_31(bool) = Call[operator!=] : func:r2225_25, this:r0_39, 0:r0_45 #-----| v0_46(void) = ^IndirectReadSideEffect[-1] : &:r0_39, ~m? -# 2224| v2224_32(void) = ConditionalBranch : r2224_31 +# 2225| v2225_32(void) = ConditionalBranch : r2225_31 #-----| False -> Block 23 #-----| True -> Block 21 -# 2224| Block 20 -# 2224| r2224_33(glval>) = VariableAddress[(__begin)] : -# 2224| r2224_34(glval) = FunctionAddress[operator++] : -# 2224| r2224_35(iterator &) = Call[operator++] : func:r2224_34, this:r2224_33 -# 2224| v2224_36(void) = ^IndirectReadSideEffect[-1] : &:r2224_33, ~m? -# 2224| mu2224_37(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2224_33 -# 2224| r2224_38(glval>) = CopyValue : r2224_35 +# 2225| Block 20 +# 2225| r2225_33(glval>) = VariableAddress[(__begin)] : +# 2225| r2225_34(glval) = FunctionAddress[operator++] : +# 2225| r2225_35(iterator &) = Call[operator++] : func:r2225_34, this:r2225_33 +# 2225| v2225_36(void) = ^IndirectReadSideEffect[-1] : &:r2225_33, ~m? +# 2225| mu2225_37(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2225_33 +# 2225| r2225_38(glval>) = CopyValue : r2225_35 #-----| Goto (back edge) -> Block 19 -# 2224| Block 21 -# 2224| r2224_39(glval) = VariableAddress[y] : -# 2224| r2224_40(glval>) = VariableAddress[(__begin)] : -#-----| r0_47(glval>) = Convert : r2224_40 -# 2224| r2224_41(glval) = FunctionAddress[operator*] : -# 2224| r2224_42(int &) = Call[operator*] : func:r2224_41, this:r0_47 +# 2225| Block 21 +# 2225| r2225_39(glval) = VariableAddress[y] : +# 2225| r2225_40(glval>) = VariableAddress[(__begin)] : +#-----| r0_47(glval>) = Convert : r2225_40 +# 2225| r2225_41(glval) = FunctionAddress[operator*] : +# 2225| r2225_42(int &) = Call[operator*] : func:r2225_41, this:r0_47 #-----| v0_48(void) = ^IndirectReadSideEffect[-1] : &:r0_47, ~m? -# 2224| r2224_43(int) = Load[?] : &:r2224_42, ~m? -# 2224| mu2224_44(int) = Store[y] : &:r2224_39, r2224_43 -# 2225| r2225_1(glval) = VariableAddress[y] : -# 2225| r2225_2(int) = Load[y] : &:r2225_1, ~m? -# 2225| r2225_3(int) = Constant[1] : -# 2225| r2225_4(bool) = CompareEQ : r2225_2, r2225_3 -# 2225| v2225_5(void) = ConditionalBranch : r2225_4 +# 2225| r2225_43(int) = Load[?] : &:r2225_42, ~m? +# 2225| mu2225_44(int) = Store[y] : &:r2225_39, r2225_43 +# 2226| r2226_1(glval) = VariableAddress[y] : +# 2226| r2226_2(int) = Load[y] : &:r2226_1, ~m? +# 2226| r2226_3(int) = Constant[1] : +# 2226| r2226_4(bool) = CompareEQ : r2226_2, r2226_3 +# 2226| v2226_5(void) = ConditionalBranch : r2226_4 #-----| False -> Block 20 #-----| True -> Block 22 -# 2226| Block 22 -# 2226| v2226_1(void) = NoOp : -# 2224| r2224_45(glval>) = VariableAddress[ys] : -# 2224| r2224_46(glval) = FunctionAddress[~vector] : -# 2224| v2224_47(void) = Call[~vector] : func:r2224_46, this:r2224_45 -# 2224| mu2224_48(unknown) = ^CallSideEffect : ~m? -# 2224| v2224_49(void) = ^IndirectReadSideEffect[-1] : &:r2224_45, ~m? -# 2224| mu2224_50(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2224_45 -# 2233| r2233_7(glval) = VariableAddress[x] : -# 2233| r2233_8(glval) = FunctionAddress[~ClassWithDestructor] : -# 2233| v2233_9(void) = Call[~ClassWithDestructor] : func:r2233_8, this:r2233_7 -# 2233| mu2233_10(unknown) = ^CallSideEffect : ~m? -# 2233| v2233_11(void) = ^IndirectReadSideEffect[-1] : &:r2233_7, ~m? -# 2233| mu2233_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2233_7 +# 2227| Block 22 +# 2227| v2227_1(void) = NoOp : +# 2225| r2225_45(glval>) = VariableAddress[ys] : +# 2225| r2225_46(glval) = FunctionAddress[~vector] : +# 2225| v2225_47(void) = Call[~vector] : func:r2225_46, this:r2225_45 +# 2225| mu2225_48(unknown) = ^CallSideEffect : ~m? +# 2225| v2225_49(void) = ^IndirectReadSideEffect[-1] : &:r2225_45, ~m? +# 2225| mu2225_50(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2225_45 +# 2234| r2234_7(glval) = VariableAddress[x] : +# 2234| r2234_8(glval) = FunctionAddress[~ClassWithDestructor] : +# 2234| v2234_9(void) = Call[~ClassWithDestructor] : func:r2234_8, this:r2234_7 +# 2234| mu2234_10(unknown) = ^CallSideEffect : ~m? +# 2234| v2234_11(void) = ^IndirectReadSideEffect[-1] : &:r2234_7, ~m? +# 2234| mu2234_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2234_7 #-----| Goto -> Block 1 -# 2224| Block 23 -# 2224| r2224_51(glval>) = VariableAddress[ys] : -# 2224| r2224_52(glval) = FunctionAddress[~vector] : -# 2224| v2224_53(void) = Call[~vector] : func:r2224_52, this:r2224_51 -# 2224| mu2224_54(unknown) = ^CallSideEffect : ~m? -# 2224| v2224_55(void) = ^IndirectReadSideEffect[-1] : &:r2224_51, ~m? -# 2224| mu2224_56(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2224_51 -# 2229| r2229_1(glval>) = VariableAddress[ys] : -# 2229| mu2229_2(vector) = Uninitialized[ys] : &:r2229_1 -# 2229| r2229_3(glval) = FunctionAddress[vector] : -# 2229| r2229_4(glval) = VariableAddress[#temp2229:45] : -# 2229| r2229_5(glval) = VariableAddress[x] : -# 2229| r2229_6(ClassWithDestructor) = Load[x] : &:r2229_5, ~m? -# 2229| mu2229_7(ClassWithDestructor) = Store[#temp2229:45] : &:r2229_4, r2229_6 -# 2229| r2229_8(ClassWithDestructor) = Load[#temp2229:45] : &:r2229_4, ~m? -# 2229| v2229_9(void) = Call[vector] : func:r2229_3, this:r2229_1, 0:r2229_8 -# 2229| mu2229_10(unknown) = ^CallSideEffect : ~m? -# 2229| mu2229_11(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2229_1 -# 2229| r2229_12(glval) = CopyValue : r2229_4 -# 2229| r2229_13(glval) = FunctionAddress[~ClassWithDestructor] : -# 2229| v2229_14(void) = Call[~ClassWithDestructor] : func:r2229_13, this:r2229_12 -# 2229| mu2229_15(unknown) = ^CallSideEffect : ~m? -# 2229| v2229_16(void) = ^IndirectReadSideEffect[-1] : &:r2229_12, ~m? -# 2229| mu2229_17(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2229_12 -# 2229| r2229_18(glval &>) = VariableAddress[(__range)] : -# 2229| r2229_19(glval>) = VariableAddress[ys] : -# 2229| r2229_20(vector &) = CopyValue : r2229_19 -# 2229| mu2229_21(vector &) = Store[(__range)] : &:r2229_18, r2229_20 -# 2229| r2229_22(glval>) = VariableAddress[(__begin)] : -# 2229| r2229_23(glval &>) = VariableAddress[(__range)] : -# 2229| r2229_24(vector &) = Load[(__range)] : &:r2229_23, ~m? -#-----| r0_49(glval>) = CopyValue : r2229_24 +# 2225| Block 23 +# 2225| r2225_51(glval>) = VariableAddress[ys] : +# 2225| r2225_52(glval) = FunctionAddress[~vector] : +# 2225| v2225_53(void) = Call[~vector] : func:r2225_52, this:r2225_51 +# 2225| mu2225_54(unknown) = ^CallSideEffect : ~m? +# 2225| v2225_55(void) = ^IndirectReadSideEffect[-1] : &:r2225_51, ~m? +# 2225| mu2225_56(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2225_51 +# 2230| r2230_1(glval>) = VariableAddress[ys] : +# 2230| mu2230_2(vector) = Uninitialized[ys] : &:r2230_1 +# 2230| r2230_3(glval) = FunctionAddress[vector] : +# 2230| r2230_4(glval) = VariableAddress[#temp2230:45] : +# 2230| r2230_5(glval) = VariableAddress[x] : +# 2230| r2230_6(ClassWithDestructor) = Load[x] : &:r2230_5, ~m? +# 2230| mu2230_7(ClassWithDestructor) = Store[#temp2230:45] : &:r2230_4, r2230_6 +# 2230| r2230_8(ClassWithDestructor) = Load[#temp2230:45] : &:r2230_4, ~m? +# 2230| v2230_9(void) = Call[vector] : func:r2230_3, this:r2230_1, 0:r2230_8 +# 2230| mu2230_10(unknown) = ^CallSideEffect : ~m? +# 2230| mu2230_11(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2230_1 +# 2230| r2230_12(glval) = CopyValue : r2230_4 +# 2230| r2230_13(glval) = FunctionAddress[~ClassWithDestructor] : +# 2230| v2230_14(void) = Call[~ClassWithDestructor] : func:r2230_13, this:r2230_12 +# 2230| mu2230_15(unknown) = ^CallSideEffect : ~m? +# 2230| v2230_16(void) = ^IndirectReadSideEffect[-1] : &:r2230_12, ~m? +# 2230| mu2230_17(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2230_12 +# 2230| r2230_18(glval &>) = VariableAddress[(__range)] : +# 2230| r2230_19(glval>) = VariableAddress[ys] : +# 2230| r2230_20(vector &) = CopyValue : r2230_19 +# 2230| mu2230_21(vector &) = Store[(__range)] : &:r2230_18, r2230_20 +# 2230| r2230_22(glval>) = VariableAddress[(__begin)] : +# 2230| r2230_23(glval &>) = VariableAddress[(__range)] : +# 2230| r2230_24(vector &) = Load[(__range)] : &:r2230_23, ~m? +#-----| r0_49(glval>) = CopyValue : r2230_24 #-----| r0_50(glval>) = Convert : r0_49 -# 2229| r2229_25(glval) = FunctionAddress[begin] : -# 2229| r2229_26(iterator) = Call[begin] : func:r2229_25, this:r0_50 +# 2230| r2230_25(glval) = FunctionAddress[begin] : +# 2230| r2230_26(iterator) = Call[begin] : func:r2230_25, this:r0_50 #-----| v0_51(void) = ^IndirectReadSideEffect[-1] : &:r0_50, ~m? -# 2229| mu2229_27(iterator) = Store[(__begin)] : &:r2229_22, r2229_26 -# 2229| r2229_28(glval>) = VariableAddress[(__end)] : -# 2229| r2229_29(glval &>) = VariableAddress[(__range)] : -# 2229| r2229_30(vector &) = Load[(__range)] : &:r2229_29, ~m? -#-----| r0_52(glval>) = CopyValue : r2229_30 +# 2230| mu2230_27(iterator) = Store[(__begin)] : &:r2230_22, r2230_26 +# 2230| r2230_28(glval>) = VariableAddress[(__end)] : +# 2230| r2230_29(glval &>) = VariableAddress[(__range)] : +# 2230| r2230_30(vector &) = Load[(__range)] : &:r2230_29, ~m? +#-----| r0_52(glval>) = CopyValue : r2230_30 #-----| r0_53(glval>) = Convert : r0_52 -# 2229| r2229_31(glval) = FunctionAddress[end] : -# 2229| r2229_32(iterator) = Call[end] : func:r2229_31, this:r0_53 +# 2230| r2230_31(glval) = FunctionAddress[end] : +# 2230| r2230_32(iterator) = Call[end] : func:r2230_31, this:r0_53 #-----| v0_54(void) = ^IndirectReadSideEffect[-1] : &:r0_53, ~m? -# 2229| mu2229_33(iterator) = Store[(__end)] : &:r2229_28, r2229_32 +# 2230| mu2230_33(iterator) = Store[(__end)] : &:r2230_28, r2230_32 #-----| Goto -> Block 24 -# 2229| Block 24 -# 2229| r2229_34(glval>) = VariableAddress[(__begin)] : -#-----| r0_55(glval>) = Convert : r2229_34 -# 2229| r2229_35(glval) = FunctionAddress[operator!=] : +# 2230| Block 24 +# 2230| r2230_34(glval>) = VariableAddress[(__begin)] : +#-----| r0_55(glval>) = Convert : r2230_34 +# 2230| r2230_35(glval) = FunctionAddress[operator!=] : #-----| r0_56(glval>) = VariableAddress[#temp0:0] : #-----| mu0_57(iterator) = Uninitialized[#temp0:0] : &:r0_56 -# 2229| r2229_36(glval) = FunctionAddress[iterator] : -# 2229| r2229_37(glval>) = VariableAddress[(__end)] : -#-----| r0_58(glval>) = Convert : r2229_37 +# 2230| r2230_36(glval) = FunctionAddress[iterator] : +# 2230| r2230_37(glval>) = VariableAddress[(__end)] : +#-----| r0_58(glval>) = Convert : r2230_37 #-----| r0_59(iterator &) = CopyValue : r0_58 -# 2229| v2229_38(void) = Call[iterator] : func:r2229_36, this:r0_56, 0:r0_59 -# 2229| mu2229_39(unknown) = ^CallSideEffect : ~m? +# 2230| v2230_38(void) = Call[iterator] : func:r2230_36, this:r0_56, 0:r0_59 +# 2230| mu2230_39(unknown) = ^CallSideEffect : ~m? #-----| v0_60(void) = ^BufferReadSideEffect[0] : &:r0_59, ~m? -# 2229| mu2229_40(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_56 +# 2230| mu2230_40(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_56 #-----| r0_61(iterator) = Load[#temp0:0] : &:r0_56, ~m? -# 2229| r2229_41(bool) = Call[operator!=] : func:r2229_35, this:r0_55, 0:r0_61 +# 2230| r2230_41(bool) = Call[operator!=] : func:r2230_35, this:r0_55, 0:r0_61 #-----| v0_62(void) = ^IndirectReadSideEffect[-1] : &:r0_55, ~m? -# 2229| v2229_42(void) = ConditionalBranch : r2229_41 +# 2230| v2230_42(void) = ConditionalBranch : r2230_41 #-----| False -> Block 26 #-----| True -> Block 25 -# 2229| Block 25 -# 2229| r2229_43(glval) = VariableAddress[y] : -# 2229| r2229_44(glval>) = VariableAddress[(__begin)] : -#-----| r0_63(glval>) = Convert : r2229_44 -# 2229| r2229_45(glval) = FunctionAddress[operator*] : -# 2229| r2229_46(ClassWithDestructor &) = Call[operator*] : func:r2229_45, this:r0_63 +# 2230| Block 25 +# 2230| r2230_43(glval) = VariableAddress[y] : +# 2230| r2230_44(glval>) = VariableAddress[(__begin)] : +#-----| r0_63(glval>) = Convert : r2230_44 +# 2230| r2230_45(glval) = FunctionAddress[operator*] : +# 2230| r2230_46(ClassWithDestructor &) = Call[operator*] : func:r2230_45, this:r0_63 #-----| v0_64(void) = ^IndirectReadSideEffect[-1] : &:r0_63, ~m? -# 2229| r2229_47(ClassWithDestructor) = Load[?] : &:r2229_46, ~m? -# 2229| mu2229_48(ClassWithDestructor) = Store[y] : &:r2229_43, r2229_47 -# 2230| r2230_1(glval) = VariableAddress[z1] : -# 2230| mu2230_2(ClassWithDestructor) = Uninitialized[z1] : &:r2230_1 -# 2230| r2230_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2230| v2230_4(void) = Call[ClassWithDestructor] : func:r2230_3, this:r2230_1 -# 2230| mu2230_5(unknown) = ^CallSideEffect : ~m? -# 2230| mu2230_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2230_1 -# 2231| r2231_1(glval) = VariableAddress[z2] : -# 2231| mu2231_2(ClassWithDestructor) = Uninitialized[z2] : &:r2231_1 +# 2230| r2230_47(ClassWithDestructor) = Load[?] : &:r2230_46, ~m? +# 2230| mu2230_48(ClassWithDestructor) = Store[y] : &:r2230_43, r2230_47 +# 2231| r2231_1(glval) = VariableAddress[z1] : +# 2231| mu2231_2(ClassWithDestructor) = Uninitialized[z1] : &:r2231_1 # 2231| r2231_3(glval) = FunctionAddress[ClassWithDestructor] : # 2231| v2231_4(void) = Call[ClassWithDestructor] : func:r2231_3, this:r2231_1 # 2231| mu2231_5(unknown) = ^CallSideEffect : ~m? # 2231| mu2231_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2231_1 # 2232| r2232_1(glval) = VariableAddress[z2] : -# 2232| r2232_2(glval) = FunctionAddress[~ClassWithDestructor] : -# 2232| v2232_3(void) = Call[~ClassWithDestructor] : func:r2232_2, this:r2232_1 -# 2232| mu2232_4(unknown) = ^CallSideEffect : ~m? -# 2232| v2232_5(void) = ^IndirectReadSideEffect[-1] : &:r2232_1, ~m? +# 2232| mu2232_2(ClassWithDestructor) = Uninitialized[z2] : &:r2232_1 +# 2232| r2232_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2232| v2232_4(void) = Call[ClassWithDestructor] : func:r2232_3, this:r2232_1 +# 2232| mu2232_5(unknown) = ^CallSideEffect : ~m? # 2232| mu2232_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2232_1 -# 2232| r2232_7(glval) = VariableAddress[z1] : -# 2232| r2232_8(glval) = FunctionAddress[~ClassWithDestructor] : -# 2232| v2232_9(void) = Call[~ClassWithDestructor] : func:r2232_8, this:r2232_7 -# 2232| mu2232_10(unknown) = ^CallSideEffect : ~m? -# 2232| v2232_11(void) = ^IndirectReadSideEffect[-1] : &:r2232_7, ~m? -# 2232| mu2232_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2232_7 -# 2229| r2229_49(glval>) = VariableAddress[(__begin)] : -# 2229| r2229_50(glval) = FunctionAddress[operator++] : -# 2229| r2229_51(iterator &) = Call[operator++] : func:r2229_50, this:r2229_49 -# 2229| v2229_52(void) = ^IndirectReadSideEffect[-1] : &:r2229_49, ~m? -# 2229| mu2229_53(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2229_49 -# 2229| r2229_54(glval) = VariableAddress[y] : -# 2229| r2229_55(glval) = FunctionAddress[~ClassWithDestructor] : -# 2229| v2229_56(void) = Call[~ClassWithDestructor] : func:r2229_55, this:r2229_54 -# 2229| mu2229_57(unknown) = ^CallSideEffect : ~m? -# 2229| v2229_58(void) = ^IndirectReadSideEffect[-1] : &:r2229_54, ~m? -# 2229| mu2229_59(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2229_54 -# 2229| r2229_60(glval>) = CopyValue : r2229_51 +# 2233| r2233_1(glval) = VariableAddress[z2] : +# 2233| r2233_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2233| v2233_3(void) = Call[~ClassWithDestructor] : func:r2233_2, this:r2233_1 +# 2233| mu2233_4(unknown) = ^CallSideEffect : ~m? +# 2233| v2233_5(void) = ^IndirectReadSideEffect[-1] : &:r2233_1, ~m? +# 2233| mu2233_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2233_1 +# 2233| r2233_7(glval) = VariableAddress[z1] : +# 2233| r2233_8(glval) = FunctionAddress[~ClassWithDestructor] : +# 2233| v2233_9(void) = Call[~ClassWithDestructor] : func:r2233_8, this:r2233_7 +# 2233| mu2233_10(unknown) = ^CallSideEffect : ~m? +# 2233| v2233_11(void) = ^IndirectReadSideEffect[-1] : &:r2233_7, ~m? +# 2233| mu2233_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2233_7 +# 2230| r2230_49(glval>) = VariableAddress[(__begin)] : +# 2230| r2230_50(glval) = FunctionAddress[operator++] : +# 2230| r2230_51(iterator &) = Call[operator++] : func:r2230_50, this:r2230_49 +# 2230| v2230_52(void) = ^IndirectReadSideEffect[-1] : &:r2230_49, ~m? +# 2230| mu2230_53(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2230_49 +# 2230| r2230_54(glval) = VariableAddress[y] : +# 2230| r2230_55(glval) = FunctionAddress[~ClassWithDestructor] : +# 2230| v2230_56(void) = Call[~ClassWithDestructor] : func:r2230_55, this:r2230_54 +# 2230| mu2230_57(unknown) = ^CallSideEffect : ~m? +# 2230| v2230_58(void) = ^IndirectReadSideEffect[-1] : &:r2230_54, ~m? +# 2230| mu2230_59(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2230_54 +# 2230| r2230_60(glval>) = CopyValue : r2230_51 #-----| Goto (back edge) -> Block 24 -# 2229| Block 26 -# 2229| r2229_61(glval>) = VariableAddress[ys] : -# 2229| r2229_62(glval) = FunctionAddress[~vector] : -# 2229| v2229_63(void) = Call[~vector] : func:r2229_62, this:r2229_61 -# 2229| mu2229_64(unknown) = ^CallSideEffect : ~m? -# 2229| v2229_65(void) = ^IndirectReadSideEffect[-1] : &:r2229_61, ~m? -# 2229| mu2229_66(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2229_61 -# 2233| v2233_13(void) = NoOp : -# 2233| r2233_14(glval) = VariableAddress[x] : -# 2233| r2233_15(glval) = FunctionAddress[~ClassWithDestructor] : -# 2233| v2233_16(void) = Call[~ClassWithDestructor] : func:r2233_15, this:r2233_14 -# 2233| mu2233_17(unknown) = ^CallSideEffect : ~m? -# 2233| v2233_18(void) = ^IndirectReadSideEffect[-1] : &:r2233_14, ~m? -# 2233| mu2233_19(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2233_14 +# 2230| Block 26 +# 2230| r2230_61(glval>) = VariableAddress[ys] : +# 2230| r2230_62(glval) = FunctionAddress[~vector] : +# 2230| v2230_63(void) = Call[~vector] : func:r2230_62, this:r2230_61 +# 2230| mu2230_64(unknown) = ^CallSideEffect : ~m? +# 2230| v2230_65(void) = ^IndirectReadSideEffect[-1] : &:r2230_61, ~m? +# 2230| mu2230_66(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2230_61 +# 2234| v2234_13(void) = NoOp : +# 2234| r2234_14(glval) = VariableAddress[x] : +# 2234| r2234_15(glval) = FunctionAddress[~ClassWithDestructor] : +# 2234| v2234_16(void) = Call[~ClassWithDestructor] : func:r2234_15, this:r2234_14 +# 2234| mu2234_17(unknown) = ^CallSideEffect : ~m? +# 2234| v2234_18(void) = ^IndirectReadSideEffect[-1] : &:r2234_14, ~m? +# 2234| mu2234_19(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2234_14 #-----| Goto -> Block 1 -# 2235| void static_variable_with_destructor_1() -# 2235| Block 0 -# 2235| v2235_1(void) = EnterFunction : -# 2235| mu2235_2(unknown) = AliasedDefinition : -# 2235| mu2235_3(unknown) = InitializeNonLocal : -# 2236| r2236_1(glval) = VariableAddress[a] : -# 2236| mu2236_2(ClassWithDestructor) = Uninitialized[a] : &:r2236_1 -# 2236| r2236_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2236| v2236_4(void) = Call[ClassWithDestructor] : func:r2236_3, this:r2236_1 -# 2236| mu2236_5(unknown) = ^CallSideEffect : ~m? -# 2236| mu2236_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2236_1 -# 2237| r2237_1(glval) = VariableAddress[b#init] : -# 2237| r2237_2(bool) = Load[b#init] : &:r2237_1, ~m? -# 2237| v2237_3(void) = ConditionalBranch : r2237_2 +# 2236| void static_variable_with_destructor_1() +# 2236| Block 0 +# 2236| v2236_1(void) = EnterFunction : +# 2236| mu2236_2(unknown) = AliasedDefinition : +# 2236| mu2236_3(unknown) = InitializeNonLocal : +# 2237| r2237_1(glval) = VariableAddress[a] : +# 2237| mu2237_2(ClassWithDestructor) = Uninitialized[a] : &:r2237_1 +# 2237| r2237_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2237| v2237_4(void) = Call[ClassWithDestructor] : func:r2237_3, this:r2237_1 +# 2237| mu2237_5(unknown) = ^CallSideEffect : ~m? +# 2237| mu2237_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2237_1 +# 2238| r2238_1(glval) = VariableAddress[b#init] : +# 2238| r2238_2(bool) = Load[b#init] : &:r2238_1, ~m? +# 2238| v2238_3(void) = ConditionalBranch : r2238_2 #-----| False -> Block 1 #-----| True -> Block 2 -# 2237| Block 1 -# 2237| r2237_4(glval) = VariableAddress[b] : +# 2238| Block 1 +# 2238| r2238_4(glval) = VariableAddress[b] : #-----| r0_1(glval) = FunctionAddress[ClassWithDestructor] : -#-----| v0_2(void) = Call[ClassWithDestructor] : func:r0_1, this:r2237_4 +#-----| v0_2(void) = Call[ClassWithDestructor] : func:r0_1, this:r2238_4 #-----| mu0_3(unknown) = ^CallSideEffect : ~m? -#-----| mu0_4(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2237_4 -# 2237| r2237_5(bool) = Constant[1] : -# 2237| mu2237_6(bool) = Store[b#init] : &:r2237_1, r2237_5 +#-----| mu0_4(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2238_4 +# 2238| r2238_5(bool) = Constant[1] : +# 2238| mu2238_6(bool) = Store[b#init] : &:r2238_1, r2238_5 #-----| Goto -> Block 2 -# 2238| Block 2 -# 2238| v2238_1(void) = NoOp : -# 2238| r2238_2(glval) = VariableAddress[a] : -# 2238| r2238_3(glval) = FunctionAddress[~ClassWithDestructor] : -# 2238| v2238_4(void) = Call[~ClassWithDestructor] : func:r2238_3, this:r2238_2 -# 2238| mu2238_5(unknown) = ^CallSideEffect : ~m? -# 2238| v2238_6(void) = ^IndirectReadSideEffect[-1] : &:r2238_2, ~m? -# 2238| mu2238_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2238_2 -# 2235| v2235_4(void) = ReturnVoid : -# 2235| v2235_5(void) = AliasedUse : ~m? -# 2235| v2235_6(void) = ExitFunction : - -# 2240| void static_variable_with_destructor_2() -# 2240| Block 0 -# 2240| v2240_1(void) = EnterFunction : -# 2240| mu2240_2(unknown) = AliasedDefinition : -# 2240| mu2240_3(unknown) = InitializeNonLocal : -# 2241| r2241_1(glval) = VariableAddress[a#init] : -# 2241| r2241_2(bool) = Load[a#init] : &:r2241_1, ~m? -# 2241| v2241_3(void) = ConditionalBranch : r2241_2 +# 2239| Block 2 +# 2239| v2239_1(void) = NoOp : +# 2239| r2239_2(glval) = VariableAddress[a] : +# 2239| r2239_3(glval) = FunctionAddress[~ClassWithDestructor] : +# 2239| v2239_4(void) = Call[~ClassWithDestructor] : func:r2239_3, this:r2239_2 +# 2239| mu2239_5(unknown) = ^CallSideEffect : ~m? +# 2239| v2239_6(void) = ^IndirectReadSideEffect[-1] : &:r2239_2, ~m? +# 2239| mu2239_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2239_2 +# 2236| v2236_4(void) = ReturnVoid : +# 2236| v2236_5(void) = AliasedUse : ~m? +# 2236| v2236_6(void) = ExitFunction : + +# 2241| void static_variable_with_destructor_2() +# 2241| Block 0 +# 2241| v2241_1(void) = EnterFunction : +# 2241| mu2241_2(unknown) = AliasedDefinition : +# 2241| mu2241_3(unknown) = InitializeNonLocal : +# 2242| r2242_1(glval) = VariableAddress[a#init] : +# 2242| r2242_2(bool) = Load[a#init] : &:r2242_1, ~m? +# 2242| v2242_3(void) = ConditionalBranch : r2242_2 #-----| False -> Block 1 #-----| True -> Block 2 -# 2241| Block 1 -# 2241| r2241_4(glval) = VariableAddress[a] : +# 2242| Block 1 +# 2242| r2242_4(glval) = VariableAddress[a] : #-----| r0_1(glval) = FunctionAddress[ClassWithDestructor] : -#-----| v0_2(void) = Call[ClassWithDestructor] : func:r0_1, this:r2241_4 +#-----| v0_2(void) = Call[ClassWithDestructor] : func:r0_1, this:r2242_4 #-----| mu0_3(unknown) = ^CallSideEffect : ~m? -#-----| mu0_4(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2241_4 -# 2241| r2241_5(bool) = Constant[1] : -# 2241| mu2241_6(bool) = Store[a#init] : &:r2241_1, r2241_5 +#-----| mu0_4(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2242_4 +# 2242| r2242_5(bool) = Constant[1] : +# 2242| mu2242_6(bool) = Store[a#init] : &:r2242_1, r2242_5 #-----| Goto -> Block 2 -# 2242| Block 2 -# 2242| r2242_1(glval) = VariableAddress[b] : -# 2242| mu2242_2(ClassWithDestructor) = Uninitialized[b] : &:r2242_1 -# 2242| r2242_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2242| v2242_4(void) = Call[ClassWithDestructor] : func:r2242_3, this:r2242_1 -# 2242| mu2242_5(unknown) = ^CallSideEffect : ~m? -# 2242| mu2242_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2242_1 -# 2243| v2243_1(void) = NoOp : -# 2243| r2243_2(glval) = VariableAddress[b] : -# 2243| r2243_3(glval) = FunctionAddress[~ClassWithDestructor] : -# 2243| v2243_4(void) = Call[~ClassWithDestructor] : func:r2243_3, this:r2243_2 +# 2243| Block 2 +# 2243| r2243_1(glval) = VariableAddress[b] : +# 2243| mu2243_2(ClassWithDestructor) = Uninitialized[b] : &:r2243_1 +# 2243| r2243_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2243| v2243_4(void) = Call[ClassWithDestructor] : func:r2243_3, this:r2243_1 # 2243| mu2243_5(unknown) = ^CallSideEffect : ~m? -# 2243| v2243_6(void) = ^IndirectReadSideEffect[-1] : &:r2243_2, ~m? -# 2243| mu2243_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2243_2 -# 2240| v2240_4(void) = ReturnVoid : -# 2240| v2240_5(void) = AliasedUse : ~m? -# 2240| v2240_6(void) = ExitFunction : - -# 2245| void static_variable_with_destructor_3() -# 2245| Block 0 -# 2245| v2245_1(void) = EnterFunction : -# 2245| mu2245_2(unknown) = AliasedDefinition : -# 2245| mu2245_3(unknown) = InitializeNonLocal : -# 2246| r2246_1(glval) = VariableAddress[a] : -# 2246| mu2246_2(ClassWithDestructor) = Uninitialized[a] : &:r2246_1 -# 2246| r2246_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2246| v2246_4(void) = Call[ClassWithDestructor] : func:r2246_3, this:r2246_1 -# 2246| mu2246_5(unknown) = ^CallSideEffect : ~m? -# 2246| mu2246_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2246_1 -# 2247| r2247_1(glval) = VariableAddress[b] : -# 2247| mu2247_2(ClassWithDestructor) = Uninitialized[b] : &:r2247_1 +# 2243| mu2243_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2243_1 +# 2244| v2244_1(void) = NoOp : +# 2244| r2244_2(glval) = VariableAddress[b] : +# 2244| r2244_3(glval) = FunctionAddress[~ClassWithDestructor] : +# 2244| v2244_4(void) = Call[~ClassWithDestructor] : func:r2244_3, this:r2244_2 +# 2244| mu2244_5(unknown) = ^CallSideEffect : ~m? +# 2244| v2244_6(void) = ^IndirectReadSideEffect[-1] : &:r2244_2, ~m? +# 2244| mu2244_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2244_2 +# 2241| v2241_4(void) = ReturnVoid : +# 2241| v2241_5(void) = AliasedUse : ~m? +# 2241| v2241_6(void) = ExitFunction : + +# 2246| void static_variable_with_destructor_3() +# 2246| Block 0 +# 2246| v2246_1(void) = EnterFunction : +# 2246| mu2246_2(unknown) = AliasedDefinition : +# 2246| mu2246_3(unknown) = InitializeNonLocal : +# 2247| r2247_1(glval) = VariableAddress[a] : +# 2247| mu2247_2(ClassWithDestructor) = Uninitialized[a] : &:r2247_1 # 2247| r2247_3(glval) = FunctionAddress[ClassWithDestructor] : # 2247| v2247_4(void) = Call[ClassWithDestructor] : func:r2247_3, this:r2247_1 # 2247| mu2247_5(unknown) = ^CallSideEffect : ~m? # 2247| mu2247_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2247_1 -# 2248| r2248_1(glval) = VariableAddress[c#init] : -# 2248| r2248_2(bool) = Load[c#init] : &:r2248_1, ~m? -# 2248| v2248_3(void) = ConditionalBranch : r2248_2 +# 2248| r2248_1(glval) = VariableAddress[b] : +# 2248| mu2248_2(ClassWithDestructor) = Uninitialized[b] : &:r2248_1 +# 2248| r2248_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2248| v2248_4(void) = Call[ClassWithDestructor] : func:r2248_3, this:r2248_1 +# 2248| mu2248_5(unknown) = ^CallSideEffect : ~m? +# 2248| mu2248_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2248_1 +# 2249| r2249_1(glval) = VariableAddress[c#init] : +# 2249| r2249_2(bool) = Load[c#init] : &:r2249_1, ~m? +# 2249| v2249_3(void) = ConditionalBranch : r2249_2 #-----| False -> Block 1 #-----| True -> Block 2 -# 2248| Block 1 -# 2248| r2248_4(glval) = VariableAddress[c] : +# 2249| Block 1 +# 2249| r2249_4(glval) = VariableAddress[c] : #-----| r0_1(glval) = FunctionAddress[ClassWithDestructor] : -#-----| v0_2(void) = Call[ClassWithDestructor] : func:r0_1, this:r2248_4 +#-----| v0_2(void) = Call[ClassWithDestructor] : func:r0_1, this:r2249_4 #-----| mu0_3(unknown) = ^CallSideEffect : ~m? -#-----| mu0_4(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2248_4 -# 2248| r2248_5(bool) = Constant[1] : -# 2248| mu2248_6(bool) = Store[c#init] : &:r2248_1, r2248_5 +#-----| mu0_4(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2249_4 +# 2249| r2249_5(bool) = Constant[1] : +# 2249| mu2249_6(bool) = Store[c#init] : &:r2249_1, r2249_5 #-----| Goto -> Block 2 -# 2249| Block 2 -# 2249| v2249_1(void) = NoOp : -# 2249| r2249_2(glval) = VariableAddress[b] : -# 2249| r2249_3(glval) = FunctionAddress[~ClassWithDestructor] : -# 2249| v2249_4(void) = Call[~ClassWithDestructor] : func:r2249_3, this:r2249_2 -# 2249| mu2249_5(unknown) = ^CallSideEffect : ~m? -# 2249| v2249_6(void) = ^IndirectReadSideEffect[-1] : &:r2249_2, ~m? -# 2249| mu2249_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2249_2 -# 2249| r2249_8(glval) = VariableAddress[a] : -# 2249| r2249_9(glval) = FunctionAddress[~ClassWithDestructor] : -# 2249| v2249_10(void) = Call[~ClassWithDestructor] : func:r2249_9, this:r2249_8 -# 2249| mu2249_11(unknown) = ^CallSideEffect : ~m? -# 2249| v2249_12(void) = ^IndirectReadSideEffect[-1] : &:r2249_8, ~m? -# 2249| mu2249_13(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2249_8 -# 2245| v2245_4(void) = ReturnVoid : -# 2245| v2245_5(void) = AliasedUse : ~m? -# 2245| v2245_6(void) = ExitFunction : - -# 2251| ClassWithDestructor global_class_with_destructor -# 2251| Block 0 -# 2251| v2251_1(void) = EnterFunction : -# 2251| mu2251_2(unknown) = AliasedDefinition : -# 2251| r2251_3(glval) = VariableAddress[global_class_with_destructor] : -# 2251| r2251_4(glval) = FunctionAddress[ClassWithDestructor] : -# 2251| v2251_5(void) = Call[ClassWithDestructor] : func:r2251_4, this:r2251_3 -# 2251| mu2251_6(unknown) = ^CallSideEffect : ~m? -# 2251| mu2251_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2251_3 -# 2251| v2251_8(void) = ReturnVoid : -# 2251| v2251_9(void) = AliasedUse : ~m? -# 2251| v2251_10(void) = ExitFunction : - -# 2255| ClassWithDestructor& vacuous_destructor_call::get(ClassWithDestructor&) -# 2255| Block 0 -# 2255| v2255_1(void) = EnterFunction : -# 2255| mu2255_2(unknown) = AliasedDefinition : -# 2255| mu2255_3(unknown) = InitializeNonLocal : -# 2255| r2255_4(glval) = VariableAddress[t] : -# 2255| mu2255_5(ClassWithDestructor &) = InitializeParameter[t] : &:r2255_4 -# 2255| r2255_6(ClassWithDestructor &) = Load[t] : &:r2255_4, ~m? -# 2255| mu2255_7(unknown) = InitializeIndirection[t] : &:r2255_6 -# 2255| r2255_8(glval) = VariableAddress[#return] : -# 2255| r2255_9(glval) = VariableAddress[t] : -# 2255| r2255_10(ClassWithDestructor &) = Load[t] : &:r2255_9, ~m? -# 2255| r2255_11(glval) = CopyValue : r2255_10 -# 2255| r2255_12(ClassWithDestructor &) = CopyValue : r2255_11 -# 2255| mu2255_13(ClassWithDestructor &) = Store[#return] : &:r2255_8, r2255_12 -# 2255| v2255_14(void) = ReturnIndirection[t] : &:r2255_6, ~m? -# 2255| r2255_15(glval) = VariableAddress[#return] : -# 2255| v2255_16(void) = ReturnValue : &:r2255_15, ~m? -# 2255| v2255_17(void) = AliasedUse : ~m? -# 2255| v2255_18(void) = ExitFunction : - -# 2255| int& vacuous_destructor_call::get(int&) -# 2255| Block 0 -# 2255| v2255_1(void) = EnterFunction : -# 2255| mu2255_2(unknown) = AliasedDefinition : -# 2255| mu2255_3(unknown) = InitializeNonLocal : -# 2255| r2255_4(glval) = VariableAddress[t] : -# 2255| mu2255_5(int &) = InitializeParameter[t] : &:r2255_4 -# 2255| r2255_6(int &) = Load[t] : &:r2255_4, ~m? -# 2255| mu2255_7(unknown) = InitializeIndirection[t] : &:r2255_6 -# 2255| r2255_8(glval) = VariableAddress[#return] : -# 2255| r2255_9(glval) = VariableAddress[t] : -# 2255| r2255_10(int &) = Load[t] : &:r2255_9, ~m? -# 2255| r2255_11(glval) = CopyValue : r2255_10 -# 2255| r2255_12(int &) = CopyValue : r2255_11 -# 2255| mu2255_13(int &) = Store[#return] : &:r2255_8, r2255_12 -# 2255| v2255_14(void) = ReturnIndirection[t] : &:r2255_6, ~m? -# 2255| r2255_15(glval) = VariableAddress[#return] : -# 2255| v2255_16(void) = ReturnValue : &:r2255_15, ~m? -# 2255| v2255_17(void) = AliasedUse : ~m? -# 2255| v2255_18(void) = ExitFunction : - -# 2258| void vacuous_destructor_call::call_destructor(ClassWithDestructor&) -# 2258| Block 0 -# 2258| v2258_1(void) = EnterFunction : -# 2258| mu2258_2(unknown) = AliasedDefinition : -# 2258| mu2258_3(unknown) = InitializeNonLocal : -# 2258| r2258_4(glval) = VariableAddress[t] : -# 2258| mu2258_5(ClassWithDestructor &) = InitializeParameter[t] : &:r2258_4 -# 2258| r2258_6(ClassWithDestructor &) = Load[t] : &:r2258_4, ~m? -# 2258| mu2258_7(unknown) = InitializeIndirection[t] : &:r2258_6 -# 2259| r2259_1(glval) = FunctionAddress[get] : -# 2259| r2259_2(glval) = VariableAddress[t] : -# 2259| r2259_3(ClassWithDestructor &) = Load[t] : &:r2259_2, ~m? -# 2259| r2259_4(glval) = CopyValue : r2259_3 -# 2259| r2259_5(ClassWithDestructor &) = CopyValue : r2259_4 -# 2259| r2259_6(ClassWithDestructor &) = Call[get] : func:r2259_1, 0:r2259_5 -# 2259| mu2259_7(unknown) = ^CallSideEffect : ~m? -# 2259| v2259_8(void) = ^BufferReadSideEffect[0] : &:r2259_5, ~m? -# 2259| mu2259_9(unknown) = ^BufferMayWriteSideEffect[0] : &:r2259_5 -# 2259| r2259_10(glval) = CopyValue : r2259_6 -# 2259| r2259_11(glval) = FunctionAddress[~ClassWithDestructor] : -# 2259| v2259_12(void) = Call[~ClassWithDestructor] : func:r2259_11 -# 2259| mu2259_13(unknown) = ^CallSideEffect : ~m? -# 2259| v2259_14(void) = ^IndirectReadSideEffect[-1] : &:r2259_10, ~m? -# 2259| mu2259_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2259_10 -# 2260| v2260_1(void) = NoOp : -# 2258| v2258_8(void) = ReturnIndirection[t] : &:r2258_6, ~m? -# 2258| v2258_9(void) = ReturnVoid : -# 2258| v2258_10(void) = AliasedUse : ~m? -# 2258| v2258_11(void) = ExitFunction : - -# 2258| void vacuous_destructor_call::call_destructor(int&) -# 2258| Block 0 -# 2258| v2258_1(void) = EnterFunction : -# 2258| mu2258_2(unknown) = AliasedDefinition : -# 2258| mu2258_3(unknown) = InitializeNonLocal : -# 2258| r2258_4(glval) = VariableAddress[t] : -# 2258| mu2258_5(int &) = InitializeParameter[t] : &:r2258_4 -# 2258| r2258_6(int &) = Load[t] : &:r2258_4, ~m? -# 2258| mu2258_7(unknown) = InitializeIndirection[t] : &:r2258_6 -# 2259| r2259_1(glval) = FunctionAddress[get] : -# 2259| r2259_2(glval) = VariableAddress[t] : -# 2259| r2259_3(int &) = Load[t] : &:r2259_2, ~m? -# 2259| r2259_4(glval) = CopyValue : r2259_3 -# 2259| r2259_5(int &) = CopyValue : r2259_4 -# 2259| r2259_6(int &) = Call[get] : func:r2259_1, 0:r2259_5 -# 2259| mu2259_7(unknown) = ^CallSideEffect : ~m? -# 2259| v2259_8(void) = ^BufferReadSideEffect[0] : &:r2259_5, ~m? -# 2259| mu2259_9(unknown) = ^BufferMayWriteSideEffect[0] : &:r2259_5 -# 2259| r2259_10(glval) = CopyValue : r2259_6 -# 2260| v2260_1(void) = NoOp : -# 2258| v2258_8(void) = ReturnIndirection[t] : &:r2258_6, ~m? -# 2258| v2258_9(void) = ReturnVoid : -# 2258| v2258_10(void) = AliasedUse : ~m? -# 2258| v2258_11(void) = ExitFunction : - -# 2262| void vacuous_destructor_call::non_vacuous_destructor_call() -# 2262| Block 0 -# 2262| v2262_1(void) = EnterFunction : -# 2262| mu2262_2(unknown) = AliasedDefinition : -# 2262| mu2262_3(unknown) = InitializeNonLocal : -# 2263| r2263_1(glval) = VariableAddress[c] : -# 2263| mu2263_2(ClassWithDestructor) = Uninitialized[c] : &:r2263_1 -# 2263| r2263_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2263| v2263_4(void) = Call[ClassWithDestructor] : func:r2263_3, this:r2263_1 -# 2263| mu2263_5(unknown) = ^CallSideEffect : ~m? -# 2263| mu2263_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2263_1 -# 2264| r2264_1(glval) = FunctionAddress[call_destructor] : -# 2264| r2264_2(glval) = VariableAddress[c] : -# 2264| r2264_3(ClassWithDestructor &) = CopyValue : r2264_2 -# 2264| v2264_4(void) = Call[call_destructor] : func:r2264_1, 0:r2264_3 +# 2250| Block 2 +# 2250| v2250_1(void) = NoOp : +# 2250| r2250_2(glval) = VariableAddress[b] : +# 2250| r2250_3(glval) = FunctionAddress[~ClassWithDestructor] : +# 2250| v2250_4(void) = Call[~ClassWithDestructor] : func:r2250_3, this:r2250_2 +# 2250| mu2250_5(unknown) = ^CallSideEffect : ~m? +# 2250| v2250_6(void) = ^IndirectReadSideEffect[-1] : &:r2250_2, ~m? +# 2250| mu2250_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2250_2 +# 2250| r2250_8(glval) = VariableAddress[a] : +# 2250| r2250_9(glval) = FunctionAddress[~ClassWithDestructor] : +# 2250| v2250_10(void) = Call[~ClassWithDestructor] : func:r2250_9, this:r2250_8 +# 2250| mu2250_11(unknown) = ^CallSideEffect : ~m? +# 2250| v2250_12(void) = ^IndirectReadSideEffect[-1] : &:r2250_8, ~m? +# 2250| mu2250_13(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2250_8 +# 2246| v2246_4(void) = ReturnVoid : +# 2246| v2246_5(void) = AliasedUse : ~m? +# 2246| v2246_6(void) = ExitFunction : + +# 2252| ClassWithDestructor global_class_with_destructor +# 2252| Block 0 +# 2252| v2252_1(void) = EnterFunction : +# 2252| mu2252_2(unknown) = AliasedDefinition : +# 2252| r2252_3(glval) = VariableAddress[global_class_with_destructor] : +# 2252| r2252_4(glval) = FunctionAddress[ClassWithDestructor] : +# 2252| v2252_5(void) = Call[ClassWithDestructor] : func:r2252_4, this:r2252_3 +# 2252| mu2252_6(unknown) = ^CallSideEffect : ~m? +# 2252| mu2252_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2252_3 +# 2252| v2252_8(void) = ReturnVoid : +# 2252| v2252_9(void) = AliasedUse : ~m? +# 2252| v2252_10(void) = ExitFunction : + +# 2256| ClassWithDestructor& vacuous_destructor_call::get(ClassWithDestructor&) +# 2256| Block 0 +# 2256| v2256_1(void) = EnterFunction : +# 2256| mu2256_2(unknown) = AliasedDefinition : +# 2256| mu2256_3(unknown) = InitializeNonLocal : +# 2256| r2256_4(glval) = VariableAddress[t] : +# 2256| mu2256_5(ClassWithDestructor &) = InitializeParameter[t] : &:r2256_4 +# 2256| r2256_6(ClassWithDestructor &) = Load[t] : &:r2256_4, ~m? +# 2256| mu2256_7(unknown) = InitializeIndirection[t] : &:r2256_6 +# 2256| r2256_8(glval) = VariableAddress[#return] : +# 2256| r2256_9(glval) = VariableAddress[t] : +# 2256| r2256_10(ClassWithDestructor &) = Load[t] : &:r2256_9, ~m? +# 2256| r2256_11(glval) = CopyValue : r2256_10 +# 2256| r2256_12(ClassWithDestructor &) = CopyValue : r2256_11 +# 2256| mu2256_13(ClassWithDestructor &) = Store[#return] : &:r2256_8, r2256_12 +# 2256| v2256_14(void) = ReturnIndirection[t] : &:r2256_6, ~m? +# 2256| r2256_15(glval) = VariableAddress[#return] : +# 2256| v2256_16(void) = ReturnValue : &:r2256_15, ~m? +# 2256| v2256_17(void) = AliasedUse : ~m? +# 2256| v2256_18(void) = ExitFunction : + +# 2256| int& vacuous_destructor_call::get(int&) +# 2256| Block 0 +# 2256| v2256_1(void) = EnterFunction : +# 2256| mu2256_2(unknown) = AliasedDefinition : +# 2256| mu2256_3(unknown) = InitializeNonLocal : +# 2256| r2256_4(glval) = VariableAddress[t] : +# 2256| mu2256_5(int &) = InitializeParameter[t] : &:r2256_4 +# 2256| r2256_6(int &) = Load[t] : &:r2256_4, ~m? +# 2256| mu2256_7(unknown) = InitializeIndirection[t] : &:r2256_6 +# 2256| r2256_8(glval) = VariableAddress[#return] : +# 2256| r2256_9(glval) = VariableAddress[t] : +# 2256| r2256_10(int &) = Load[t] : &:r2256_9, ~m? +# 2256| r2256_11(glval) = CopyValue : r2256_10 +# 2256| r2256_12(int &) = CopyValue : r2256_11 +# 2256| mu2256_13(int &) = Store[#return] : &:r2256_8, r2256_12 +# 2256| v2256_14(void) = ReturnIndirection[t] : &:r2256_6, ~m? +# 2256| r2256_15(glval) = VariableAddress[#return] : +# 2256| v2256_16(void) = ReturnValue : &:r2256_15, ~m? +# 2256| v2256_17(void) = AliasedUse : ~m? +# 2256| v2256_18(void) = ExitFunction : + +# 2259| void vacuous_destructor_call::call_destructor(ClassWithDestructor&) +# 2259| Block 0 +# 2259| v2259_1(void) = EnterFunction : +# 2259| mu2259_2(unknown) = AliasedDefinition : +# 2259| mu2259_3(unknown) = InitializeNonLocal : +# 2259| r2259_4(glval) = VariableAddress[t] : +# 2259| mu2259_5(ClassWithDestructor &) = InitializeParameter[t] : &:r2259_4 +# 2259| r2259_6(ClassWithDestructor &) = Load[t] : &:r2259_4, ~m? +# 2259| mu2259_7(unknown) = InitializeIndirection[t] : &:r2259_6 +# 2260| r2260_1(glval) = FunctionAddress[get] : +# 2260| r2260_2(glval) = VariableAddress[t] : +# 2260| r2260_3(ClassWithDestructor &) = Load[t] : &:r2260_2, ~m? +# 2260| r2260_4(glval) = CopyValue : r2260_3 +# 2260| r2260_5(ClassWithDestructor &) = CopyValue : r2260_4 +# 2260| r2260_6(ClassWithDestructor &) = Call[get] : func:r2260_1, 0:r2260_5 +# 2260| mu2260_7(unknown) = ^CallSideEffect : ~m? +# 2260| v2260_8(void) = ^BufferReadSideEffect[0] : &:r2260_5, ~m? +# 2260| mu2260_9(unknown) = ^BufferMayWriteSideEffect[0] : &:r2260_5 +# 2260| r2260_10(glval) = CopyValue : r2260_6 +# 2260| r2260_11(glval) = FunctionAddress[~ClassWithDestructor] : +# 2260| v2260_12(void) = Call[~ClassWithDestructor] : func:r2260_11 +# 2260| mu2260_13(unknown) = ^CallSideEffect : ~m? +# 2260| v2260_14(void) = ^IndirectReadSideEffect[-1] : &:r2260_10, ~m? +# 2260| mu2260_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2260_10 +# 2261| v2261_1(void) = NoOp : +# 2259| v2259_8(void) = ReturnIndirection[t] : &:r2259_6, ~m? +# 2259| v2259_9(void) = ReturnVoid : +# 2259| v2259_10(void) = AliasedUse : ~m? +# 2259| v2259_11(void) = ExitFunction : + +# 2259| void vacuous_destructor_call::call_destructor(int&) +# 2259| Block 0 +# 2259| v2259_1(void) = EnterFunction : +# 2259| mu2259_2(unknown) = AliasedDefinition : +# 2259| mu2259_3(unknown) = InitializeNonLocal : +# 2259| r2259_4(glval) = VariableAddress[t] : +# 2259| mu2259_5(int &) = InitializeParameter[t] : &:r2259_4 +# 2259| r2259_6(int &) = Load[t] : &:r2259_4, ~m? +# 2259| mu2259_7(unknown) = InitializeIndirection[t] : &:r2259_6 +# 2260| r2260_1(glval) = FunctionAddress[get] : +# 2260| r2260_2(glval) = VariableAddress[t] : +# 2260| r2260_3(int &) = Load[t] : &:r2260_2, ~m? +# 2260| r2260_4(glval) = CopyValue : r2260_3 +# 2260| r2260_5(int &) = CopyValue : r2260_4 +# 2260| r2260_6(int &) = Call[get] : func:r2260_1, 0:r2260_5 +# 2260| mu2260_7(unknown) = ^CallSideEffect : ~m? +# 2260| v2260_8(void) = ^BufferReadSideEffect[0] : &:r2260_5, ~m? +# 2260| mu2260_9(unknown) = ^BufferMayWriteSideEffect[0] : &:r2260_5 +# 2260| r2260_10(glval) = CopyValue : r2260_6 +# 2261| v2261_1(void) = NoOp : +# 2259| v2259_8(void) = ReturnIndirection[t] : &:r2259_6, ~m? +# 2259| v2259_9(void) = ReturnVoid : +# 2259| v2259_10(void) = AliasedUse : ~m? +# 2259| v2259_11(void) = ExitFunction : + +# 2263| void vacuous_destructor_call::non_vacuous_destructor_call() +# 2263| Block 0 +# 2263| v2263_1(void) = EnterFunction : +# 2263| mu2263_2(unknown) = AliasedDefinition : +# 2263| mu2263_3(unknown) = InitializeNonLocal : +# 2264| r2264_1(glval) = VariableAddress[c] : +# 2264| mu2264_2(ClassWithDestructor) = Uninitialized[c] : &:r2264_1 +# 2264| r2264_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2264| v2264_4(void) = Call[ClassWithDestructor] : func:r2264_3, this:r2264_1 # 2264| mu2264_5(unknown) = ^CallSideEffect : ~m? -# 2264| v2264_6(void) = ^BufferReadSideEffect[0] : &:r2264_3, ~m? -# 2264| mu2264_7(unknown) = ^BufferMayWriteSideEffect[0] : &:r2264_3 -# 2265| v2265_1(void) = NoOp : +# 2264| mu2264_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2264_1 +# 2265| r2265_1(glval) = FunctionAddress[call_destructor] : # 2265| r2265_2(glval) = VariableAddress[c] : -# 2265| r2265_3(glval) = FunctionAddress[~ClassWithDestructor] : -# 2265| v2265_4(void) = Call[~ClassWithDestructor] : func:r2265_3, this:r2265_2 +# 2265| r2265_3(ClassWithDestructor &) = CopyValue : r2265_2 +# 2265| v2265_4(void) = Call[call_destructor] : func:r2265_1, 0:r2265_3 # 2265| mu2265_5(unknown) = ^CallSideEffect : ~m? -# 2265| v2265_6(void) = ^IndirectReadSideEffect[-1] : &:r2265_2, ~m? -# 2265| mu2265_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2265_2 -# 2262| v2262_4(void) = ReturnVoid : -# 2262| v2262_5(void) = AliasedUse : ~m? -# 2262| v2262_6(void) = ExitFunction : - -# 2267| void vacuous_destructor_call::vacuous_destructor_call() -# 2267| Block 0 -# 2267| v2267_1(void) = EnterFunction : -# 2267| mu2267_2(unknown) = AliasedDefinition : -# 2267| mu2267_3(unknown) = InitializeNonLocal : -# 2268| r2268_1(glval) = VariableAddress[i] : -# 2268| mu2268_2(int) = Uninitialized[i] : &:r2268_1 -# 2269| r2269_1(glval) = FunctionAddress[call_destructor] : -# 2269| r2269_2(glval) = VariableAddress[i] : -# 2269| r2269_3(int &) = CopyValue : r2269_2 -# 2269| v2269_4(void) = Call[call_destructor] : func:r2269_1, 0:r2269_3 -# 2269| mu2269_5(unknown) = ^CallSideEffect : ~m? -# 2269| v2269_6(void) = ^BufferReadSideEffect[0] : &:r2269_3, ~m? -# 2269| mu2269_7(unknown) = ^BufferMayWriteSideEffect[0] : &:r2269_3 -# 2270| v2270_1(void) = NoOp : -# 2267| v2267_4(void) = ReturnVoid : -# 2267| v2267_5(void) = AliasedUse : ~m? -# 2267| v2267_6(void) = ExitFunction : - -# 2273| void TryCatchDestructors(bool) -# 2273| Block 0 -# 2273| v2273_1(void) = EnterFunction : -# 2273| mu2273_2(unknown) = AliasedDefinition : -# 2273| mu2273_3(unknown) = InitializeNonLocal : -# 2273| r2273_4(glval) = VariableAddress[b] : -# 2273| mu2273_5(bool) = InitializeParameter[b] : &:r2273_4 -# 2275| r2275_1(glval) = VariableAddress[s] : -# 2275| mu2275_2(String) = Uninitialized[s] : &:r2275_1 -# 2275| r2275_3(glval) = FunctionAddress[String] : -# 2275| v2275_4(void) = Call[String] : func:r2275_3, this:r2275_1 -# 2275| mu2275_5(unknown) = ^CallSideEffect : ~m? -# 2275| mu2275_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2275_1 -# 2276| r2276_1(glval) = VariableAddress[b] : -# 2276| r2276_2(bool) = Load[b] : &:r2276_1, ~m? -# 2276| v2276_3(void) = ConditionalBranch : r2276_2 +# 2265| v2265_6(void) = ^BufferReadSideEffect[0] : &:r2265_3, ~m? +# 2265| mu2265_7(unknown) = ^BufferMayWriteSideEffect[0] : &:r2265_3 +# 2266| v2266_1(void) = NoOp : +# 2266| r2266_2(glval) = VariableAddress[c] : +# 2266| r2266_3(glval) = FunctionAddress[~ClassWithDestructor] : +# 2266| v2266_4(void) = Call[~ClassWithDestructor] : func:r2266_3, this:r2266_2 +# 2266| mu2266_5(unknown) = ^CallSideEffect : ~m? +# 2266| v2266_6(void) = ^IndirectReadSideEffect[-1] : &:r2266_2, ~m? +# 2266| mu2266_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2266_2 +# 2263| v2263_4(void) = ReturnVoid : +# 2263| v2263_5(void) = AliasedUse : ~m? +# 2263| v2263_6(void) = ExitFunction : + +# 2268| void vacuous_destructor_call::vacuous_destructor_call() +# 2268| Block 0 +# 2268| v2268_1(void) = EnterFunction : +# 2268| mu2268_2(unknown) = AliasedDefinition : +# 2268| mu2268_3(unknown) = InitializeNonLocal : +# 2269| r2269_1(glval) = VariableAddress[i] : +# 2269| mu2269_2(int) = Uninitialized[i] : &:r2269_1 +# 2270| r2270_1(glval) = FunctionAddress[call_destructor] : +# 2270| r2270_2(glval) = VariableAddress[i] : +# 2270| r2270_3(int &) = CopyValue : r2270_2 +# 2270| v2270_4(void) = Call[call_destructor] : func:r2270_1, 0:r2270_3 +# 2270| mu2270_5(unknown) = ^CallSideEffect : ~m? +# 2270| v2270_6(void) = ^BufferReadSideEffect[0] : &:r2270_3, ~m? +# 2270| mu2270_7(unknown) = ^BufferMayWriteSideEffect[0] : &:r2270_3 +# 2271| v2271_1(void) = NoOp : +# 2268| v2268_4(void) = ReturnVoid : +# 2268| v2268_5(void) = AliasedUse : ~m? +# 2268| v2268_6(void) = ExitFunction : + +# 2274| void TryCatchDestructors(bool) +# 2274| Block 0 +# 2274| v2274_1(void) = EnterFunction : +# 2274| mu2274_2(unknown) = AliasedDefinition : +# 2274| mu2274_3(unknown) = InitializeNonLocal : +# 2274| r2274_4(glval) = VariableAddress[b] : +# 2274| mu2274_5(bool) = InitializeParameter[b] : &:r2274_4 +# 2276| r2276_1(glval) = VariableAddress[s] : +# 2276| mu2276_2(String) = Uninitialized[s] : &:r2276_1 +# 2276| r2276_3(glval) = FunctionAddress[String] : +# 2276| v2276_4(void) = Call[String] : func:r2276_3, this:r2276_1 +# 2276| mu2276_5(unknown) = ^CallSideEffect : ~m? +# 2276| mu2276_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2276_1 +# 2277| r2277_1(glval) = VariableAddress[b] : +# 2277| r2277_2(bool) = Load[b] : &:r2277_1, ~m? +# 2277| v2277_3(void) = ConditionalBranch : r2277_2 #-----| False -> Block 4 #-----| True -> Block 3 -# 2273| Block 1 -# 2273| v2273_6(void) = AliasedUse : ~m? -# 2273| v2273_7(void) = ExitFunction : +# 2274| Block 1 +# 2274| v2274_6(void) = AliasedUse : ~m? +# 2274| v2274_7(void) = ExitFunction : -# 2273| Block 2 -# 2273| v2273_8(void) = Unwind : +# 2274| Block 2 +# 2274| v2274_8(void) = Unwind : #-----| Goto -> Block 1 -# 2277| Block 3 -# 2277| r2277_1(glval) = VariableAddress[#throw2277:7] : -# 2277| r2277_2(glval) = StringConstant["string literal"] : -# 2277| r2277_3(char *) = Convert : r2277_2 -# 2277| mu2277_4(char *) = Store[#throw2277:7] : &:r2277_1, r2277_3 -# 2277| v2277_5(void) = ThrowValue : &:r2277_1, ~m? -# 2280| r2280_1(glval) = VariableAddress[s] : -# 2280| r2280_2(glval) = FunctionAddress[~String] : -# 2280| v2280_3(void) = Call[~String] : func:r2280_2, this:r2280_1 -# 2280| mu2280_4(unknown) = ^CallSideEffect : ~m? -# 2280| v2280_5(void) = ^IndirectReadSideEffect[-1] : &:r2280_1, ~m? -# 2280| mu2280_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2280_1 +# 2278| Block 3 +# 2278| r2278_1(glval) = VariableAddress[#throw2278:7] : +# 2278| r2278_2(glval) = StringConstant["string literal"] : +# 2278| r2278_3(char *) = Convert : r2278_2 +# 2278| mu2278_4(char *) = Store[#throw2278:7] : &:r2278_1, r2278_3 +# 2278| v2278_5(void) = ThrowValue : &:r2278_1, ~m? +# 2281| r2281_1(glval) = VariableAddress[s] : +# 2281| r2281_2(glval) = FunctionAddress[~String] : +# 2281| v2281_3(void) = Call[~String] : func:r2281_2, this:r2281_1 +# 2281| mu2281_4(unknown) = ^CallSideEffect : ~m? +# 2281| v2281_5(void) = ^IndirectReadSideEffect[-1] : &:r2281_1, ~m? +# 2281| mu2281_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2281_1 #-----| Exception -> Block 5 -# 2279| Block 4 -# 2279| r2279_1(glval) = VariableAddress[s2] : -# 2279| mu2279_2(String) = Uninitialized[s2] : &:r2279_1 -# 2279| r2279_3(glval) = FunctionAddress[String] : -# 2279| v2279_4(void) = Call[String] : func:r2279_3, this:r2279_1 -# 2279| mu2279_5(unknown) = ^CallSideEffect : ~m? -# 2279| mu2279_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2279_1 -# 2280| r2280_7(glval) = VariableAddress[s2] : -# 2280| r2280_8(glval) = FunctionAddress[~String] : -# 2280| v2280_9(void) = Call[~String] : func:r2280_8, this:r2280_7 -# 2280| mu2280_10(unknown) = ^CallSideEffect : ~m? -# 2280| v2280_11(void) = ^IndirectReadSideEffect[-1] : &:r2280_7, ~m? -# 2280| mu2280_12(String) = ^IndirectMayWriteSideEffect[-1] : &:r2280_7 -# 2280| r2280_13(glval) = VariableAddress[s] : -# 2280| r2280_14(glval) = FunctionAddress[~String] : -# 2280| v2280_15(void) = Call[~String] : func:r2280_14, this:r2280_13 -# 2280| mu2280_16(unknown) = ^CallSideEffect : ~m? -# 2280| v2280_17(void) = ^IndirectReadSideEffect[-1] : &:r2280_13, ~m? -# 2280| mu2280_18(String) = ^IndirectMayWriteSideEffect[-1] : &:r2280_13 +# 2280| Block 4 +# 2280| r2280_1(glval) = VariableAddress[s2] : +# 2280| mu2280_2(String) = Uninitialized[s2] : &:r2280_1 +# 2280| r2280_3(glval) = FunctionAddress[String] : +# 2280| v2280_4(void) = Call[String] : func:r2280_3, this:r2280_1 +# 2280| mu2280_5(unknown) = ^CallSideEffect : ~m? +# 2280| mu2280_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2280_1 +# 2281| r2281_7(glval) = VariableAddress[s2] : +# 2281| r2281_8(glval) = FunctionAddress[~String] : +# 2281| v2281_9(void) = Call[~String] : func:r2281_8, this:r2281_7 +# 2281| mu2281_10(unknown) = ^CallSideEffect : ~m? +# 2281| v2281_11(void) = ^IndirectReadSideEffect[-1] : &:r2281_7, ~m? +# 2281| mu2281_12(String) = ^IndirectMayWriteSideEffect[-1] : &:r2281_7 +# 2281| r2281_13(glval) = VariableAddress[s] : +# 2281| r2281_14(glval) = FunctionAddress[~String] : +# 2281| v2281_15(void) = Call[~String] : func:r2281_14, this:r2281_13 +# 2281| mu2281_16(unknown) = ^CallSideEffect : ~m? +# 2281| v2281_17(void) = ^IndirectReadSideEffect[-1] : &:r2281_13, ~m? +# 2281| mu2281_18(String) = ^IndirectMayWriteSideEffect[-1] : &:r2281_13 #-----| Goto -> Block 10 -# 2281| Block 5 -# 2281| v2281_1(void) = CatchByType[const char *] : +# 2282| Block 5 +# 2282| v2282_1(void) = CatchByType[const char *] : #-----| Exception -> Block 7 #-----| Goto -> Block 6 -# 2281| Block 6 -# 2281| r2281_2(glval) = VariableAddress[s] : -# 2281| mu2281_3(char *) = InitializeParameter[s] : &:r2281_2 -# 2281| r2281_4(char *) = Load[s] : &:r2281_2, ~m? -# 2281| mu2281_5(unknown) = InitializeIndirection[s] : &:r2281_4 -# 2282| r2282_1(glval) = VariableAddress[#throw2282:5] : -# 2282| mu2282_2(String) = Uninitialized[#throw2282:5] : &:r2282_1 -# 2282| r2282_3(glval) = FunctionAddress[String] : -# 2282| r2282_4(glval) = VariableAddress[s] : -# 2282| r2282_5(char *) = Load[s] : &:r2282_4, ~m? -# 2282| v2282_6(void) = Call[String] : func:r2282_3, this:r2282_1, 0:r2282_5 -# 2282| mu2282_7(unknown) = ^CallSideEffect : ~m? -# 2282| v2282_8(void) = ^BufferReadSideEffect[0] : &:r2282_5, ~m? -# 2282| mu2282_9(String) = ^IndirectMayWriteSideEffect[-1] : &:r2282_1 -# 2282| v2282_10(void) = ThrowValue : &:r2282_1, ~m? +# 2282| Block 6 +# 2282| r2282_2(glval) = VariableAddress[s] : +# 2282| mu2282_3(char *) = InitializeParameter[s] : &:r2282_2 +# 2282| r2282_4(char *) = Load[s] : &:r2282_2, ~m? +# 2282| mu2282_5(unknown) = InitializeIndirection[s] : &:r2282_4 +# 2283| r2283_1(glval) = VariableAddress[#throw2283:5] : +# 2283| mu2283_2(String) = Uninitialized[#throw2283:5] : &:r2283_1 +# 2283| r2283_3(glval) = FunctionAddress[String] : +# 2283| r2283_4(glval) = VariableAddress[s] : +# 2283| r2283_5(char *) = Load[s] : &:r2283_4, ~m? +# 2283| v2283_6(void) = Call[String] : func:r2283_3, this:r2283_1, 0:r2283_5 +# 2283| mu2283_7(unknown) = ^CallSideEffect : ~m? +# 2283| v2283_8(void) = ^BufferReadSideEffect[0] : &:r2283_5, ~m? +# 2283| mu2283_9(String) = ^IndirectMayWriteSideEffect[-1] : &:r2283_1 +# 2283| v2283_10(void) = ThrowValue : &:r2283_1, ~m? #-----| Exception -> Block 2 -# 2284| Block 7 -# 2284| v2284_1(void) = CatchByType[const String &] : +# 2285| Block 7 +# 2285| v2285_1(void) = CatchByType[const String &] : #-----| Exception -> Block 9 #-----| Goto -> Block 8 -# 2284| Block 8 -# 2284| r2284_2(glval) = VariableAddress[e] : -# 2284| mu2284_3(String &) = InitializeParameter[e] : &:r2284_2 -# 2284| r2284_4(String &) = Load[e] : &:r2284_2, ~m? -# 2284| mu2284_5(unknown) = InitializeIndirection[e] : &:r2284_4 -# 2284| v2284_6(void) = NoOp : +# 2285| Block 8 +# 2285| r2285_2(glval) = VariableAddress[e] : +# 2285| mu2285_3(String &) = InitializeParameter[e] : &:r2285_2 +# 2285| r2285_4(String &) = Load[e] : &:r2285_2, ~m? +# 2285| mu2285_5(unknown) = InitializeIndirection[e] : &:r2285_4 +# 2285| v2285_6(void) = NoOp : #-----| Goto -> Block 10 -# 2286| Block 9 -# 2286| v2286_1(void) = CatchAny : -# 2287| v2287_1(void) = ReThrow : +# 2287| Block 9 +# 2287| v2287_1(void) = CatchAny : +# 2288| v2288_1(void) = ReThrow : #-----| Exception -> Block 2 -# 2289| Block 10 -# 2289| v2289_1(void) = NoOp : -# 2273| v2273_9(void) = ReturnVoid : +# 2290| Block 10 +# 2290| v2290_1(void) = NoOp : +# 2274| v2274_9(void) = ReturnVoid : #-----| Goto -> Block 1 -# 2291| void IfDestructors(bool) -# 2291| Block 0 -# 2291| v2291_1(void) = EnterFunction : -# 2291| mu2291_2(unknown) = AliasedDefinition : -# 2291| mu2291_3(unknown) = InitializeNonLocal : -# 2291| r2291_4(glval) = VariableAddress[b] : -# 2291| mu2291_5(bool) = InitializeParameter[b] : &:r2291_4 -# 2292| r2292_1(glval) = VariableAddress[s1] : -# 2292| mu2292_2(String) = Uninitialized[s1] : &:r2292_1 -# 2292| r2292_3(glval) = FunctionAddress[String] : -# 2292| v2292_4(void) = Call[String] : func:r2292_3, this:r2292_1 -# 2292| mu2292_5(unknown) = ^CallSideEffect : ~m? -# 2292| mu2292_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2292_1 -# 2293| r2293_1(glval) = VariableAddress[b] : -# 2293| r2293_2(bool) = Load[b] : &:r2293_1, ~m? -# 2293| v2293_3(void) = ConditionalBranch : r2293_2 +# 2292| void IfDestructors(bool) +# 2292| Block 0 +# 2292| v2292_1(void) = EnterFunction : +# 2292| mu2292_2(unknown) = AliasedDefinition : +# 2292| mu2292_3(unknown) = InitializeNonLocal : +# 2292| r2292_4(glval) = VariableAddress[b] : +# 2292| mu2292_5(bool) = InitializeParameter[b] : &:r2292_4 +# 2293| r2293_1(glval) = VariableAddress[s1] : +# 2293| mu2293_2(String) = Uninitialized[s1] : &:r2293_1 +# 2293| r2293_3(glval) = FunctionAddress[String] : +# 2293| v2293_4(void) = Call[String] : func:r2293_3, this:r2293_1 +# 2293| mu2293_5(unknown) = ^CallSideEffect : ~m? +# 2293| mu2293_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2293_1 +# 2294| r2294_1(glval) = VariableAddress[b] : +# 2294| r2294_2(bool) = Load[b] : &:r2294_1, ~m? +# 2294| v2294_3(void) = ConditionalBranch : r2294_2 #-----| False -> Block 2 #-----| True -> Block 1 -# 2294| Block 1 -# 2294| r2294_1(glval) = VariableAddress[s2] : -# 2294| mu2294_2(String) = Uninitialized[s2] : &:r2294_1 -# 2294| r2294_3(glval) = FunctionAddress[String] : -# 2294| v2294_4(void) = Call[String] : func:r2294_3, this:r2294_1 -# 2294| mu2294_5(unknown) = ^CallSideEffect : ~m? -# 2294| mu2294_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2294_1 +# 2295| Block 1 # 2295| r2295_1(glval) = VariableAddress[s2] : -# 2295| r2295_2(glval) = FunctionAddress[~String] : -# 2295| v2295_3(void) = Call[~String] : func:r2295_2, this:r2295_1 -# 2295| mu2295_4(unknown) = ^CallSideEffect : ~m? -# 2295| v2295_5(void) = ^IndirectReadSideEffect[-1] : &:r2295_1, ~m? +# 2295| mu2295_2(String) = Uninitialized[s2] : &:r2295_1 +# 2295| r2295_3(glval) = FunctionAddress[String] : +# 2295| v2295_4(void) = Call[String] : func:r2295_3, this:r2295_1 +# 2295| mu2295_5(unknown) = ^CallSideEffect : ~m? # 2295| mu2295_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2295_1 +# 2296| r2296_1(glval) = VariableAddress[s2] : +# 2296| r2296_2(glval) = FunctionAddress[~String] : +# 2296| v2296_3(void) = Call[~String] : func:r2296_2, this:r2296_1 +# 2296| mu2296_4(unknown) = ^CallSideEffect : ~m? +# 2296| v2296_5(void) = ^IndirectReadSideEffect[-1] : &:r2296_1, ~m? +# 2296| mu2296_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2296_1 #-----| Goto -> Block 3 -# 2296| Block 2 -# 2296| r2296_1(glval) = VariableAddress[s3] : -# 2296| mu2296_2(String) = Uninitialized[s3] : &:r2296_1 -# 2296| r2296_3(glval) = FunctionAddress[String] : -# 2296| v2296_4(void) = Call[String] : func:r2296_3, this:r2296_1 -# 2296| mu2296_5(unknown) = ^CallSideEffect : ~m? -# 2296| mu2296_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2296_1 +# 2297| Block 2 # 2297| r2297_1(glval) = VariableAddress[s3] : -# 2297| r2297_2(glval) = FunctionAddress[~String] : -# 2297| v2297_3(void) = Call[~String] : func:r2297_2, this:r2297_1 -# 2297| mu2297_4(unknown) = ^CallSideEffect : ~m? -# 2297| v2297_5(void) = ^IndirectReadSideEffect[-1] : &:r2297_1, ~m? +# 2297| mu2297_2(String) = Uninitialized[s3] : &:r2297_1 +# 2297| r2297_3(glval) = FunctionAddress[String] : +# 2297| v2297_4(void) = Call[String] : func:r2297_3, this:r2297_1 +# 2297| mu2297_5(unknown) = ^CallSideEffect : ~m? # 2297| mu2297_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2297_1 +# 2298| r2298_1(glval) = VariableAddress[s3] : +# 2298| r2298_2(glval) = FunctionAddress[~String] : +# 2298| v2298_3(void) = Call[~String] : func:r2298_2, this:r2298_1 +# 2298| mu2298_4(unknown) = ^CallSideEffect : ~m? +# 2298| v2298_5(void) = ^IndirectReadSideEffect[-1] : &:r2298_1, ~m? +# 2298| mu2298_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2298_1 #-----| Goto -> Block 3 -# 2298| Block 3 -# 2298| r2298_1(glval) = VariableAddress[s4] : -# 2298| mu2298_2(String) = Uninitialized[s4] : &:r2298_1 -# 2298| r2298_3(glval) = FunctionAddress[String] : -# 2298| v2298_4(void) = Call[String] : func:r2298_3, this:r2298_1 -# 2298| mu2298_5(unknown) = ^CallSideEffect : ~m? -# 2298| mu2298_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2298_1 -# 2299| v2299_1(void) = NoOp : -# 2299| r2299_2(glval) = VariableAddress[s4] : -# 2299| r2299_3(glval) = FunctionAddress[~String] : -# 2299| v2299_4(void) = Call[~String] : func:r2299_3, this:r2299_2 +# 2299| Block 3 +# 2299| r2299_1(glval) = VariableAddress[s4] : +# 2299| mu2299_2(String) = Uninitialized[s4] : &:r2299_1 +# 2299| r2299_3(glval) = FunctionAddress[String] : +# 2299| v2299_4(void) = Call[String] : func:r2299_3, this:r2299_1 # 2299| mu2299_5(unknown) = ^CallSideEffect : ~m? -# 2299| v2299_6(void) = ^IndirectReadSideEffect[-1] : &:r2299_2, ~m? -# 2299| mu2299_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2299_2 -# 2299| r2299_8(glval) = VariableAddress[s1] : -# 2299| r2299_9(glval) = FunctionAddress[~String] : -# 2299| v2299_10(void) = Call[~String] : func:r2299_9, this:r2299_8 -# 2299| mu2299_11(unknown) = ^CallSideEffect : ~m? -# 2299| v2299_12(void) = ^IndirectReadSideEffect[-1] : &:r2299_8, ~m? -# 2299| mu2299_13(String) = ^IndirectMayWriteSideEffect[-1] : &:r2299_8 -# 2291| v2291_6(void) = ReturnVoid : -# 2291| v2291_7(void) = AliasedUse : ~m? -# 2291| v2291_8(void) = ExitFunction : - -# 2301| void ForDestructors() -# 2301| Block 0 -# 2301| v2301_1(void) = EnterFunction : -# 2301| mu2301_2(unknown) = AliasedDefinition : -# 2301| mu2301_3(unknown) = InitializeNonLocal : -# 2302| r2302_1(glval) = VariableAddress[c] : -# 2302| r2302_2(char) = Constant[97] : -# 2302| mu2302_3(char) = Store[c] : &:r2302_1, r2302_2 -# 2303| r2303_1(glval) = VariableAddress[s] : -# 2303| mu2303_2(String) = Uninitialized[s] : &:r2303_1 -# 2303| r2303_3(glval) = FunctionAddress[String] : -# 2303| r2303_4(glval) = StringConstant["hello"] : -# 2303| r2303_5(char *) = Convert : r2303_4 -# 2303| v2303_6(void) = Call[String] : func:r2303_3, this:r2303_1, 0:r2303_5 -# 2303| mu2303_7(unknown) = ^CallSideEffect : ~m? -# 2303| v2303_8(void) = ^BufferReadSideEffect[0] : &:r2303_5, ~m? -# 2303| mu2303_9(String) = ^IndirectMayWriteSideEffect[-1] : &:r2303_1 +# 2299| mu2299_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2299_1 +# 2300| v2300_1(void) = NoOp : +# 2300| r2300_2(glval) = VariableAddress[s4] : +# 2300| r2300_3(glval) = FunctionAddress[~String] : +# 2300| v2300_4(void) = Call[~String] : func:r2300_3, this:r2300_2 +# 2300| mu2300_5(unknown) = ^CallSideEffect : ~m? +# 2300| v2300_6(void) = ^IndirectReadSideEffect[-1] : &:r2300_2, ~m? +# 2300| mu2300_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2300_2 +# 2300| r2300_8(glval) = VariableAddress[s1] : +# 2300| r2300_9(glval) = FunctionAddress[~String] : +# 2300| v2300_10(void) = Call[~String] : func:r2300_9, this:r2300_8 +# 2300| mu2300_11(unknown) = ^CallSideEffect : ~m? +# 2300| v2300_12(void) = ^IndirectReadSideEffect[-1] : &:r2300_8, ~m? +# 2300| mu2300_13(String) = ^IndirectMayWriteSideEffect[-1] : &:r2300_8 +# 2292| v2292_6(void) = ReturnVoid : +# 2292| v2292_7(void) = AliasedUse : ~m? +# 2292| v2292_8(void) = ExitFunction : + +# 2302| void ForDestructors() +# 2302| Block 0 +# 2302| v2302_1(void) = EnterFunction : +# 2302| mu2302_2(unknown) = AliasedDefinition : +# 2302| mu2302_3(unknown) = InitializeNonLocal : +# 2303| r2303_1(glval) = VariableAddress[c] : +# 2303| r2303_2(char) = Constant[97] : +# 2303| mu2303_3(char) = Store[c] : &:r2303_1, r2303_2 +# 2304| r2304_1(glval) = VariableAddress[s] : +# 2304| mu2304_2(String) = Uninitialized[s] : &:r2304_1 +# 2304| r2304_3(glval) = FunctionAddress[String] : +# 2304| r2304_4(glval) = StringConstant["hello"] : +# 2304| r2304_5(char *) = Convert : r2304_4 +# 2304| v2304_6(void) = Call[String] : func:r2304_3, this:r2304_1, 0:r2304_5 +# 2304| mu2304_7(unknown) = ^CallSideEffect : ~m? +# 2304| v2304_8(void) = ^BufferReadSideEffect[0] : &:r2304_5, ~m? +# 2304| mu2304_9(String) = ^IndirectMayWriteSideEffect[-1] : &:r2304_1 #-----| Goto -> Block 1 -# 2303| Block 1 -# 2303| r2303_10(glval) = VariableAddress[c] : -# 2303| r2303_11(char) = Load[c] : &:r2303_10, ~m? -# 2303| r2303_12(int) = Convert : r2303_11 -# 2303| r2303_13(int) = Constant[0] : -# 2303| r2303_14(bool) = CompareNE : r2303_12, r2303_13 -# 2303| v2303_15(void) = ConditionalBranch : r2303_14 +# 2304| Block 1 +# 2304| r2304_10(glval) = VariableAddress[c] : +# 2304| r2304_11(char) = Load[c] : &:r2304_10, ~m? +# 2304| r2304_12(int) = Convert : r2304_11 +# 2304| r2304_13(int) = Constant[0] : +# 2304| r2304_14(bool) = CompareNE : r2304_12, r2304_13 +# 2304| v2304_15(void) = ConditionalBranch : r2304_14 #-----| False -> Block 3 #-----| True -> Block 2 -# 2304| Block 2 -# 2304| r2304_1(glval) = VariableAddress[s2] : -# 2304| mu2304_2(String) = Uninitialized[s2] : &:r2304_1 -# 2304| r2304_3(glval) = FunctionAddress[String] : -# 2304| v2304_4(void) = Call[String] : func:r2304_3, this:r2304_1 -# 2304| mu2304_5(unknown) = ^CallSideEffect : ~m? -# 2304| mu2304_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2304_1 +# 2305| Block 2 # 2305| r2305_1(glval) = VariableAddress[s2] : -# 2305| r2305_2(glval) = FunctionAddress[~String] : -# 2305| v2305_3(void) = Call[~String] : func:r2305_2, this:r2305_1 -# 2305| mu2305_4(unknown) = ^CallSideEffect : ~m? -# 2305| v2305_5(void) = ^IndirectReadSideEffect[-1] : &:r2305_1, ~m? +# 2305| mu2305_2(String) = Uninitialized[s2] : &:r2305_1 +# 2305| r2305_3(glval) = FunctionAddress[String] : +# 2305| v2305_4(void) = Call[String] : func:r2305_3, this:r2305_1 +# 2305| mu2305_5(unknown) = ^CallSideEffect : ~m? # 2305| mu2305_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2305_1 -# 2303| r2303_16(glval) = VariableAddress[s] : -# 2303| r2303_17(glval) = FunctionAddress[pop_back] : -# 2303| r2303_18(char) = Call[pop_back] : func:r2303_17, this:r2303_16 -# 2303| mu2303_19(unknown) = ^CallSideEffect : ~m? -# 2303| v2303_20(void) = ^IndirectReadSideEffect[-1] : &:r2303_16, ~m? -# 2303| mu2303_21(String) = ^IndirectMayWriteSideEffect[-1] : &:r2303_16 -# 2303| r2303_22(glval) = VariableAddress[c] : -# 2303| mu2303_23(char) = Store[c] : &:r2303_22, r2303_18 +# 2306| r2306_1(glval) = VariableAddress[s2] : +# 2306| r2306_2(glval) = FunctionAddress[~String] : +# 2306| v2306_3(void) = Call[~String] : func:r2306_2, this:r2306_1 +# 2306| mu2306_4(unknown) = ^CallSideEffect : ~m? +# 2306| v2306_5(void) = ^IndirectReadSideEffect[-1] : &:r2306_1, ~m? +# 2306| mu2306_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2306_1 +# 2304| r2304_16(glval) = VariableAddress[s] : +# 2304| r2304_17(glval) = FunctionAddress[pop_back] : +# 2304| r2304_18(char) = Call[pop_back] : func:r2304_17, this:r2304_16 +# 2304| mu2304_19(unknown) = ^CallSideEffect : ~m? +# 2304| v2304_20(void) = ^IndirectReadSideEffect[-1] : &:r2304_16, ~m? +# 2304| mu2304_21(String) = ^IndirectMayWriteSideEffect[-1] : &:r2304_16 +# 2304| r2304_22(glval) = VariableAddress[c] : +# 2304| mu2304_23(char) = Store[c] : &:r2304_22, r2304_18 #-----| Goto (back edge) -> Block 1 -# 2303| Block 3 -# 2303| r2303_24(glval) = VariableAddress[s] : -# 2303| r2303_25(glval) = FunctionAddress[~String] : -# 2303| v2303_26(void) = Call[~String] : func:r2303_25, this:r2303_24 -# 2303| mu2303_27(unknown) = ^CallSideEffect : ~m? -# 2303| v2303_28(void) = ^IndirectReadSideEffect[-1] : &:r2303_24, ~m? -# 2303| mu2303_29(String) = ^IndirectMayWriteSideEffect[-1] : &:r2303_24 -# 2307| r2307_1(glval &&>) = VariableAddress[(__range)] : -# 2307| r2307_2(glval>) = VariableAddress[#temp2307:20] : -# 2307| mu2307_3(vector) = Uninitialized[#temp2307:20] : &:r2307_2 -# 2307| r2307_4(glval) = FunctionAddress[vector] : -# 2307| r2307_5(glval) = VariableAddress[#temp2307:40] : -# 2307| mu2307_6(String) = Uninitialized[#temp2307:40] : &:r2307_5 -# 2307| r2307_7(glval) = FunctionAddress[String] : -# 2307| r2307_8(glval) = StringConstant["hello"] : -# 2307| r2307_9(char *) = Convert : r2307_8 -# 2307| v2307_10(void) = Call[String] : func:r2307_7, this:r2307_5, 0:r2307_9 -# 2307| mu2307_11(unknown) = ^CallSideEffect : ~m? -# 2307| v2307_12(void) = ^BufferReadSideEffect[0] : &:r2307_9, ~m? -# 2307| mu2307_13(String) = ^IndirectMayWriteSideEffect[-1] : &:r2307_5 -# 2307| r2307_14(String) = Load[#temp2307:40] : &:r2307_5, ~m? -# 2307| v2307_15(void) = Call[vector] : func:r2307_4, this:r2307_2, 0:r2307_14 -# 2307| mu2307_16(unknown) = ^CallSideEffect : ~m? -# 2307| mu2307_17(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2307_2 -# 2307| r2307_18(glval) = CopyValue : r2307_5 -# 2307| r2307_19(glval) = FunctionAddress[~String] : -# 2307| v2307_20(void) = Call[~String] : func:r2307_19, this:r2307_18 -# 2307| mu2307_21(unknown) = ^CallSideEffect : ~m? -# 2307| v2307_22(void) = ^IndirectReadSideEffect[-1] : &:r2307_18, ~m? -# 2307| mu2307_23(String) = ^IndirectMayWriteSideEffect[-1] : &:r2307_18 -# 2307| r2307_24(vector &) = CopyValue : r2307_2 -# 2307| mu2307_25(vector &&) = Store[(__range)] : &:r2307_1, r2307_24 -# 2307| r2307_26(glval>) = VariableAddress[(__begin)] : -# 2307| r2307_27(glval &&>) = VariableAddress[(__range)] : -# 2307| r2307_28(vector &&) = Load[(__range)] : &:r2307_27, ~m? -#-----| r0_1(glval>) = CopyValue : r2307_28 +# 2304| Block 3 +# 2304| r2304_24(glval) = VariableAddress[s] : +# 2304| r2304_25(glval) = FunctionAddress[~String] : +# 2304| v2304_26(void) = Call[~String] : func:r2304_25, this:r2304_24 +# 2304| mu2304_27(unknown) = ^CallSideEffect : ~m? +# 2304| v2304_28(void) = ^IndirectReadSideEffect[-1] : &:r2304_24, ~m? +# 2304| mu2304_29(String) = ^IndirectMayWriteSideEffect[-1] : &:r2304_24 +# 2308| r2308_1(glval &&>) = VariableAddress[(__range)] : +# 2308| r2308_2(glval>) = VariableAddress[#temp2308:20] : +# 2308| mu2308_3(vector) = Uninitialized[#temp2308:20] : &:r2308_2 +# 2308| r2308_4(glval) = FunctionAddress[vector] : +# 2308| r2308_5(glval) = VariableAddress[#temp2308:40] : +# 2308| mu2308_6(String) = Uninitialized[#temp2308:40] : &:r2308_5 +# 2308| r2308_7(glval) = FunctionAddress[String] : +# 2308| r2308_8(glval) = StringConstant["hello"] : +# 2308| r2308_9(char *) = Convert : r2308_8 +# 2308| v2308_10(void) = Call[String] : func:r2308_7, this:r2308_5, 0:r2308_9 +# 2308| mu2308_11(unknown) = ^CallSideEffect : ~m? +# 2308| v2308_12(void) = ^BufferReadSideEffect[0] : &:r2308_9, ~m? +# 2308| mu2308_13(String) = ^IndirectMayWriteSideEffect[-1] : &:r2308_5 +# 2308| r2308_14(String) = Load[#temp2308:40] : &:r2308_5, ~m? +# 2308| v2308_15(void) = Call[vector] : func:r2308_4, this:r2308_2, 0:r2308_14 +# 2308| mu2308_16(unknown) = ^CallSideEffect : ~m? +# 2308| mu2308_17(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2308_2 +# 2308| r2308_18(glval) = CopyValue : r2308_5 +# 2308| r2308_19(glval) = FunctionAddress[~String] : +# 2308| v2308_20(void) = Call[~String] : func:r2308_19, this:r2308_18 +# 2308| mu2308_21(unknown) = ^CallSideEffect : ~m? +# 2308| v2308_22(void) = ^IndirectReadSideEffect[-1] : &:r2308_18, ~m? +# 2308| mu2308_23(String) = ^IndirectMayWriteSideEffect[-1] : &:r2308_18 +# 2308| r2308_24(vector &) = CopyValue : r2308_2 +# 2308| mu2308_25(vector &&) = Store[(__range)] : &:r2308_1, r2308_24 +# 2308| r2308_26(glval>) = VariableAddress[(__begin)] : +# 2308| r2308_27(glval &&>) = VariableAddress[(__range)] : +# 2308| r2308_28(vector &&) = Load[(__range)] : &:r2308_27, ~m? +#-----| r0_1(glval>) = CopyValue : r2308_28 #-----| r0_2(glval>) = Convert : r0_1 -# 2307| r2307_29(glval) = FunctionAddress[begin] : -# 2307| r2307_30(iterator) = Call[begin] : func:r2307_29, this:r0_2 +# 2308| r2308_29(glval) = FunctionAddress[begin] : +# 2308| r2308_30(iterator) = Call[begin] : func:r2308_29, this:r0_2 #-----| v0_3(void) = ^IndirectReadSideEffect[-1] : &:r0_2, ~m? -# 2307| mu2307_31(iterator) = Store[(__begin)] : &:r2307_26, r2307_30 -# 2307| r2307_32(glval>) = VariableAddress[(__end)] : -# 2307| r2307_33(glval &&>) = VariableAddress[(__range)] : -# 2307| r2307_34(vector &&) = Load[(__range)] : &:r2307_33, ~m? -#-----| r0_4(glval>) = CopyValue : r2307_34 +# 2308| mu2308_31(iterator) = Store[(__begin)] : &:r2308_26, r2308_30 +# 2308| r2308_32(glval>) = VariableAddress[(__end)] : +# 2308| r2308_33(glval &&>) = VariableAddress[(__range)] : +# 2308| r2308_34(vector &&) = Load[(__range)] : &:r2308_33, ~m? +#-----| r0_4(glval>) = CopyValue : r2308_34 #-----| r0_5(glval>) = Convert : r0_4 -# 2307| r2307_35(glval) = FunctionAddress[end] : -# 2307| r2307_36(iterator) = Call[end] : func:r2307_35, this:r0_5 +# 2308| r2308_35(glval) = FunctionAddress[end] : +# 2308| r2308_36(iterator) = Call[end] : func:r2308_35, this:r0_5 #-----| v0_6(void) = ^IndirectReadSideEffect[-1] : &:r0_5, ~m? -# 2307| mu2307_37(iterator) = Store[(__end)] : &:r2307_32, r2307_36 +# 2308| mu2308_37(iterator) = Store[(__end)] : &:r2308_32, r2308_36 #-----| Goto -> Block 4 -# 2307| Block 4 -# 2307| r2307_38(glval>) = VariableAddress[(__begin)] : -#-----| r0_7(glval>) = Convert : r2307_38 -# 2307| r2307_39(glval) = FunctionAddress[operator!=] : +# 2308| Block 4 +# 2308| r2308_38(glval>) = VariableAddress[(__begin)] : +#-----| r0_7(glval>) = Convert : r2308_38 +# 2308| r2308_39(glval) = FunctionAddress[operator!=] : #-----| r0_8(glval>) = VariableAddress[#temp0:0] : #-----| mu0_9(iterator) = Uninitialized[#temp0:0] : &:r0_8 -# 2307| r2307_40(glval) = FunctionAddress[iterator] : -# 2307| r2307_41(glval>) = VariableAddress[(__end)] : -#-----| r0_10(glval>) = Convert : r2307_41 +# 2308| r2308_40(glval) = FunctionAddress[iterator] : +# 2308| r2308_41(glval>) = VariableAddress[(__end)] : +#-----| r0_10(glval>) = Convert : r2308_41 #-----| r0_11(iterator &) = CopyValue : r0_10 -# 2307| v2307_42(void) = Call[iterator] : func:r2307_40, this:r0_8, 0:r0_11 -# 2307| mu2307_43(unknown) = ^CallSideEffect : ~m? +# 2308| v2308_42(void) = Call[iterator] : func:r2308_40, this:r0_8, 0:r0_11 +# 2308| mu2308_43(unknown) = ^CallSideEffect : ~m? #-----| v0_12(void) = ^BufferReadSideEffect[0] : &:r0_11, ~m? -# 2307| mu2307_44(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_8 +# 2308| mu2308_44(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_8 #-----| r0_13(iterator) = Load[#temp0:0] : &:r0_8, ~m? -# 2307| r2307_45(bool) = Call[operator!=] : func:r2307_39, this:r0_7, 0:r0_13 +# 2308| r2308_45(bool) = Call[operator!=] : func:r2308_39, this:r0_7, 0:r0_13 #-----| v0_14(void) = ^IndirectReadSideEffect[-1] : &:r0_7, ~m? -# 2307| v2307_46(void) = ConditionalBranch : r2307_45 +# 2308| v2308_46(void) = ConditionalBranch : r2308_45 #-----| False -> Block 6 #-----| True -> Block 5 -# 2307| Block 5 -# 2307| r2307_47(glval) = VariableAddress[s] : -# 2307| mu2307_48(String) = Uninitialized[s] : &:r2307_47 -# 2307| r2307_49(glval) = FunctionAddress[String] : -# 2307| r2307_50(glval>) = VariableAddress[(__begin)] : -#-----| r0_15(glval>) = Convert : r2307_50 -# 2307| r2307_51(glval) = FunctionAddress[operator*] : -# 2307| r2307_52(String &) = Call[operator*] : func:r2307_51, this:r0_15 +# 2308| Block 5 +# 2308| r2308_47(glval) = VariableAddress[s] : +# 2308| mu2308_48(String) = Uninitialized[s] : &:r2308_47 +# 2308| r2308_49(glval) = FunctionAddress[String] : +# 2308| r2308_50(glval>) = VariableAddress[(__begin)] : +#-----| r0_15(glval>) = Convert : r2308_50 +# 2308| r2308_51(glval) = FunctionAddress[operator*] : +# 2308| r2308_52(String &) = Call[operator*] : func:r2308_51, this:r0_15 #-----| v0_16(void) = ^IndirectReadSideEffect[-1] : &:r0_15, ~m? -# 2307| r2307_53(glval) = CopyValue : r2307_52 -# 2307| r2307_54(glval) = Convert : r2307_53 -# 2307| r2307_55(String &) = CopyValue : r2307_54 -# 2307| v2307_56(void) = Call[String] : func:r2307_49, this:r2307_47, 0:r2307_55 -# 2307| mu2307_57(unknown) = ^CallSideEffect : ~m? -# 2307| v2307_58(void) = ^BufferReadSideEffect[0] : &:r2307_55, ~m? -# 2307| mu2307_59(String) = ^IndirectMayWriteSideEffect[-1] : &:r2307_47 -# 2308| r2308_1(glval) = VariableAddress[s2] : -# 2308| mu2308_2(String) = Uninitialized[s2] : &:r2308_1 -# 2308| r2308_3(glval) = FunctionAddress[String] : -# 2308| v2308_4(void) = Call[String] : func:r2308_3, this:r2308_1 -# 2308| mu2308_5(unknown) = ^CallSideEffect : ~m? -# 2308| mu2308_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2308_1 +# 2308| r2308_53(glval) = CopyValue : r2308_52 +# 2308| r2308_54(glval) = Convert : r2308_53 +# 2308| r2308_55(String &) = CopyValue : r2308_54 +# 2308| v2308_56(void) = Call[String] : func:r2308_49, this:r2308_47, 0:r2308_55 +# 2308| mu2308_57(unknown) = ^CallSideEffect : ~m? +# 2308| v2308_58(void) = ^BufferReadSideEffect[0] : &:r2308_55, ~m? +# 2308| mu2308_59(String) = ^IndirectMayWriteSideEffect[-1] : &:r2308_47 # 2309| r2309_1(glval) = VariableAddress[s2] : -# 2309| r2309_2(glval) = FunctionAddress[~String] : -# 2309| v2309_3(void) = Call[~String] : func:r2309_2, this:r2309_1 -# 2309| mu2309_4(unknown) = ^CallSideEffect : ~m? -# 2309| v2309_5(void) = ^IndirectReadSideEffect[-1] : &:r2309_1, ~m? +# 2309| mu2309_2(String) = Uninitialized[s2] : &:r2309_1 +# 2309| r2309_3(glval) = FunctionAddress[String] : +# 2309| v2309_4(void) = Call[String] : func:r2309_3, this:r2309_1 +# 2309| mu2309_5(unknown) = ^CallSideEffect : ~m? # 2309| mu2309_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2309_1 -# 2307| r2307_60(glval>) = VariableAddress[(__begin)] : -# 2307| r2307_61(glval) = FunctionAddress[operator++] : -# 2307| r2307_62(iterator &) = Call[operator++] : func:r2307_61, this:r2307_60 -# 2307| v2307_63(void) = ^IndirectReadSideEffect[-1] : &:r2307_60, ~m? -# 2307| mu2307_64(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2307_60 -# 2307| r2307_65(glval) = VariableAddress[s] : -# 2307| r2307_66(glval) = FunctionAddress[~String] : -# 2307| v2307_67(void) = Call[~String] : func:r2307_66, this:r2307_65 -# 2307| mu2307_68(unknown) = ^CallSideEffect : ~m? -# 2307| v2307_69(void) = ^IndirectReadSideEffect[-1] : &:r2307_65, ~m? -# 2307| mu2307_70(String) = ^IndirectMayWriteSideEffect[-1] : &:r2307_65 -# 2307| r2307_71(glval>) = CopyValue : r2307_62 +# 2310| r2310_1(glval) = VariableAddress[s2] : +# 2310| r2310_2(glval) = FunctionAddress[~String] : +# 2310| v2310_3(void) = Call[~String] : func:r2310_2, this:r2310_1 +# 2310| mu2310_4(unknown) = ^CallSideEffect : ~m? +# 2310| v2310_5(void) = ^IndirectReadSideEffect[-1] : &:r2310_1, ~m? +# 2310| mu2310_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2310_1 +# 2308| r2308_60(glval>) = VariableAddress[(__begin)] : +# 2308| r2308_61(glval) = FunctionAddress[operator++] : +# 2308| r2308_62(iterator &) = Call[operator++] : func:r2308_61, this:r2308_60 +# 2308| v2308_63(void) = ^IndirectReadSideEffect[-1] : &:r2308_60, ~m? +# 2308| mu2308_64(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2308_60 +# 2308| r2308_65(glval) = VariableAddress[s] : +# 2308| r2308_66(glval) = FunctionAddress[~String] : +# 2308| v2308_67(void) = Call[~String] : func:r2308_66, this:r2308_65 +# 2308| mu2308_68(unknown) = ^CallSideEffect : ~m? +# 2308| v2308_69(void) = ^IndirectReadSideEffect[-1] : &:r2308_65, ~m? +# 2308| mu2308_70(String) = ^IndirectMayWriteSideEffect[-1] : &:r2308_65 +# 2308| r2308_71(glval>) = CopyValue : r2308_62 #-----| Goto (back edge) -> Block 4 -# 2307| Block 6 -# 2307| r2307_72(glval>) = CopyValue : r2307_2 -# 2307| r2307_73(glval) = FunctionAddress[~vector] : -# 2307| v2307_74(void) = Call[~vector] : func:r2307_73, this:r2307_72 -# 2307| mu2307_75(unknown) = ^CallSideEffect : ~m? -# 2307| v2307_76(void) = ^IndirectReadSideEffect[-1] : &:r2307_72, ~m? -# 2307| mu2307_77(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2307_72 -# 2311| r2311_1(glval) = VariableAddress[s] : -# 2311| mu2311_2(String) = Uninitialized[s] : &:r2311_1 -# 2311| r2311_3(glval) = FunctionAddress[String] : -# 2311| r2311_4(glval) = StringConstant["hello"] : -# 2311| r2311_5(char *) = Convert : r2311_4 -# 2311| v2311_6(void) = Call[String] : func:r2311_3, this:r2311_1, 0:r2311_5 -# 2311| mu2311_7(unknown) = ^CallSideEffect : ~m? -# 2311| v2311_8(void) = ^BufferReadSideEffect[0] : &:r2311_5, ~m? -# 2311| mu2311_9(String) = ^IndirectMayWriteSideEffect[-1] : &:r2311_1 -# 2311| r2311_10(glval) = VariableAddress[s2] : -# 2311| mu2311_11(String) = Uninitialized[s2] : &:r2311_10 -# 2311| r2311_12(glval) = FunctionAddress[String] : -# 2311| r2311_13(glval) = StringConstant["world"] : -# 2311| r2311_14(char *) = Convert : r2311_13 -# 2311| v2311_15(void) = Call[String] : func:r2311_12, this:r2311_10, 0:r2311_14 -# 2311| mu2311_16(unknown) = ^CallSideEffect : ~m? -# 2311| v2311_17(void) = ^BufferReadSideEffect[0] : &:r2311_14, ~m? -# 2311| mu2311_18(String) = ^IndirectMayWriteSideEffect[-1] : &:r2311_10 +# 2308| Block 6 +# 2308| r2308_72(glval>) = CopyValue : r2308_2 +# 2308| r2308_73(glval) = FunctionAddress[~vector] : +# 2308| v2308_74(void) = Call[~vector] : func:r2308_73, this:r2308_72 +# 2308| mu2308_75(unknown) = ^CallSideEffect : ~m? +# 2308| v2308_76(void) = ^IndirectReadSideEffect[-1] : &:r2308_72, ~m? +# 2308| mu2308_77(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2308_72 +# 2312| r2312_1(glval) = VariableAddress[s] : +# 2312| mu2312_2(String) = Uninitialized[s] : &:r2312_1 +# 2312| r2312_3(glval) = FunctionAddress[String] : +# 2312| r2312_4(glval) = StringConstant["hello"] : +# 2312| r2312_5(char *) = Convert : r2312_4 +# 2312| v2312_6(void) = Call[String] : func:r2312_3, this:r2312_1, 0:r2312_5 +# 2312| mu2312_7(unknown) = ^CallSideEffect : ~m? +# 2312| v2312_8(void) = ^BufferReadSideEffect[0] : &:r2312_5, ~m? +# 2312| mu2312_9(String) = ^IndirectMayWriteSideEffect[-1] : &:r2312_1 +# 2312| r2312_10(glval) = VariableAddress[s2] : +# 2312| mu2312_11(String) = Uninitialized[s2] : &:r2312_10 +# 2312| r2312_12(glval) = FunctionAddress[String] : +# 2312| r2312_13(glval) = StringConstant["world"] : +# 2312| r2312_14(char *) = Convert : r2312_13 +# 2312| v2312_15(void) = Call[String] : func:r2312_12, this:r2312_10, 0:r2312_14 +# 2312| mu2312_16(unknown) = ^CallSideEffect : ~m? +# 2312| v2312_17(void) = ^BufferReadSideEffect[0] : &:r2312_14, ~m? +# 2312| mu2312_18(String) = ^IndirectMayWriteSideEffect[-1] : &:r2312_10 #-----| Goto -> Block 7 -# 2311| Block 7 -# 2311| r2311_19(glval) = VariableAddress[c] : -# 2311| r2311_20(char) = Load[c] : &:r2311_19, ~m? -# 2311| r2311_21(int) = Convert : r2311_20 -# 2311| r2311_22(int) = Constant[0] : -# 2311| r2311_23(bool) = CompareNE : r2311_21, r2311_22 -# 2311| v2311_24(void) = ConditionalBranch : r2311_23 +# 2312| Block 7 +# 2312| r2312_19(glval) = VariableAddress[c] : +# 2312| r2312_20(char) = Load[c] : &:r2312_19, ~m? +# 2312| r2312_21(int) = Convert : r2312_20 +# 2312| r2312_22(int) = Constant[0] : +# 2312| r2312_23(bool) = CompareNE : r2312_21, r2312_22 +# 2312| v2312_24(void) = ConditionalBranch : r2312_23 #-----| False -> Block 9 #-----| True -> Block 8 -# 2312| Block 8 -# 2312| r2312_1(char) = Constant[0] : -# 2312| r2312_2(glval) = VariableAddress[c] : -# 2312| mu2312_3(char) = Store[c] : &:r2312_2, r2312_1 -# 2311| r2311_25(glval) = VariableAddress[s] : -# 2311| r2311_26(glval) = FunctionAddress[pop_back] : -# 2311| r2311_27(char) = Call[pop_back] : func:r2311_26, this:r2311_25 -# 2311| mu2311_28(unknown) = ^CallSideEffect : ~m? -# 2311| v2311_29(void) = ^IndirectReadSideEffect[-1] : &:r2311_25, ~m? -# 2311| mu2311_30(String) = ^IndirectMayWriteSideEffect[-1] : &:r2311_25 -# 2311| r2311_31(glval) = VariableAddress[c] : -# 2311| mu2311_32(char) = Store[c] : &:r2311_31, r2311_27 +# 2313| Block 8 +# 2313| r2313_1(char) = Constant[0] : +# 2313| r2313_2(glval) = VariableAddress[c] : +# 2313| mu2313_3(char) = Store[c] : &:r2313_2, r2313_1 +# 2312| r2312_25(glval) = VariableAddress[s] : +# 2312| r2312_26(glval) = FunctionAddress[pop_back] : +# 2312| r2312_27(char) = Call[pop_back] : func:r2312_26, this:r2312_25 +# 2312| mu2312_28(unknown) = ^CallSideEffect : ~m? +# 2312| v2312_29(void) = ^IndirectReadSideEffect[-1] : &:r2312_25, ~m? +# 2312| mu2312_30(String) = ^IndirectMayWriteSideEffect[-1] : &:r2312_25 +# 2312| r2312_31(glval) = VariableAddress[c] : +# 2312| mu2312_32(char) = Store[c] : &:r2312_31, r2312_27 #-----| Goto (back edge) -> Block 7 -# 2311| Block 9 -# 2311| r2311_33(glval) = VariableAddress[s2] : -# 2311| r2311_34(glval) = FunctionAddress[~String] : -# 2311| v2311_35(void) = Call[~String] : func:r2311_34, this:r2311_33 -# 2311| mu2311_36(unknown) = ^CallSideEffect : ~m? -# 2311| v2311_37(void) = ^IndirectReadSideEffect[-1] : &:r2311_33, ~m? -# 2311| mu2311_38(String) = ^IndirectMayWriteSideEffect[-1] : &:r2311_33 -# 2311| r2311_39(glval) = VariableAddress[s] : -# 2311| r2311_40(glval) = FunctionAddress[~String] : -# 2311| v2311_41(void) = Call[~String] : func:r2311_40, this:r2311_39 -# 2311| mu2311_42(unknown) = ^CallSideEffect : ~m? -# 2311| v2311_43(void) = ^IndirectReadSideEffect[-1] : &:r2311_39, ~m? -# 2311| mu2311_44(String) = ^IndirectMayWriteSideEffect[-1] : &:r2311_39 -# 2314| v2314_1(void) = NoOp : -# 2301| v2301_4(void) = ReturnVoid : -# 2301| v2301_5(void) = AliasedUse : ~m? -# 2301| v2301_6(void) = ExitFunction : - -# 2316| void IfDestructors2(bool) -# 2316| Block 0 -# 2316| v2316_1(void) = EnterFunction : -# 2316| mu2316_2(unknown) = AliasedDefinition : -# 2316| mu2316_3(unknown) = InitializeNonLocal : -# 2316| r2316_4(glval) = VariableAddress[b] : -# 2316| mu2316_5(bool) = InitializeParameter[b] : &:r2316_4 -# 2317| r2317_1(glval) = VariableAddress[s] : -# 2317| mu2317_2(String) = Uninitialized[s] : &:r2317_1 -# 2317| r2317_3(glval) = FunctionAddress[String] : -# 2317| r2317_4(glval) = StringConstant["hello"] : -# 2317| r2317_5(char *) = Convert : r2317_4 -# 2317| v2317_6(void) = Call[String] : func:r2317_3, this:r2317_1, 0:r2317_5 -# 2317| mu2317_7(unknown) = ^CallSideEffect : ~m? -# 2317| v2317_8(void) = ^BufferReadSideEffect[0] : &:r2317_5, ~m? -# 2317| mu2317_9(String) = ^IndirectMayWriteSideEffect[-1] : &:r2317_1 -# 2317| r2317_10(glval) = VariableAddress[b] : -# 2317| r2317_11(bool) = Load[b] : &:r2317_10, ~m? -# 2317| v2317_12(void) = ConditionalBranch : r2317_11 +# 2312| Block 9 +# 2312| r2312_33(glval) = VariableAddress[s2] : +# 2312| r2312_34(glval) = FunctionAddress[~String] : +# 2312| v2312_35(void) = Call[~String] : func:r2312_34, this:r2312_33 +# 2312| mu2312_36(unknown) = ^CallSideEffect : ~m? +# 2312| v2312_37(void) = ^IndirectReadSideEffect[-1] : &:r2312_33, ~m? +# 2312| mu2312_38(String) = ^IndirectMayWriteSideEffect[-1] : &:r2312_33 +# 2312| r2312_39(glval) = VariableAddress[s] : +# 2312| r2312_40(glval) = FunctionAddress[~String] : +# 2312| v2312_41(void) = Call[~String] : func:r2312_40, this:r2312_39 +# 2312| mu2312_42(unknown) = ^CallSideEffect : ~m? +# 2312| v2312_43(void) = ^IndirectReadSideEffect[-1] : &:r2312_39, ~m? +# 2312| mu2312_44(String) = ^IndirectMayWriteSideEffect[-1] : &:r2312_39 +# 2315| v2315_1(void) = NoOp : +# 2302| v2302_4(void) = ReturnVoid : +# 2302| v2302_5(void) = AliasedUse : ~m? +# 2302| v2302_6(void) = ExitFunction : + +# 2317| void IfDestructors2(bool) +# 2317| Block 0 +# 2317| v2317_1(void) = EnterFunction : +# 2317| mu2317_2(unknown) = AliasedDefinition : +# 2317| mu2317_3(unknown) = InitializeNonLocal : +# 2317| r2317_4(glval) = VariableAddress[b] : +# 2317| mu2317_5(bool) = InitializeParameter[b] : &:r2317_4 +# 2318| r2318_1(glval) = VariableAddress[s] : +# 2318| mu2318_2(String) = Uninitialized[s] : &:r2318_1 +# 2318| r2318_3(glval) = FunctionAddress[String] : +# 2318| r2318_4(glval) = StringConstant["hello"] : +# 2318| r2318_5(char *) = Convert : r2318_4 +# 2318| v2318_6(void) = Call[String] : func:r2318_3, this:r2318_1, 0:r2318_5 +# 2318| mu2318_7(unknown) = ^CallSideEffect : ~m? +# 2318| v2318_8(void) = ^BufferReadSideEffect[0] : &:r2318_5, ~m? +# 2318| mu2318_9(String) = ^IndirectMayWriteSideEffect[-1] : &:r2318_1 +# 2318| r2318_10(glval) = VariableAddress[b] : +# 2318| r2318_11(bool) = Load[b] : &:r2318_10, ~m? +# 2318| v2318_12(void) = ConditionalBranch : r2318_11 #-----| False -> Block 2 #-----| True -> Block 1 -# 2318| Block 1 -# 2318| r2318_1(glval) = VariableAddress[x] : -# 2318| r2318_2(int) = Constant[0] : -# 2318| mu2318_3(int) = Store[x] : &:r2318_1, r2318_2 +# 2319| Block 1 +# 2319| r2319_1(glval) = VariableAddress[x] : +# 2319| r2319_2(int) = Constant[0] : +# 2319| mu2319_3(int) = Store[x] : &:r2319_1, r2319_2 #-----| Goto -> Block 3 -# 2320| Block 2 -# 2320| r2320_1(glval) = VariableAddress[y] : -# 2320| r2320_2(int) = Constant[0] : -# 2320| mu2320_3(int) = Store[y] : &:r2320_1, r2320_2 +# 2321| Block 2 +# 2321| r2321_1(glval) = VariableAddress[y] : +# 2321| r2321_2(int) = Constant[0] : +# 2321| mu2321_3(int) = Store[y] : &:r2321_1, r2321_2 #-----| Goto -> Block 3 -# 2321| Block 3 -# 2321| r2321_1(glval) = VariableAddress[s] : -# 2321| r2321_2(glval) = FunctionAddress[~String] : -# 2321| v2321_3(void) = Call[~String] : func:r2321_2, this:r2321_1 -# 2321| mu2321_4(unknown) = ^CallSideEffect : ~m? -# 2321| v2321_5(void) = ^IndirectReadSideEffect[-1] : &:r2321_1, ~m? -# 2321| mu2321_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2321_1 -# 2322| v2322_1(void) = NoOp : -# 2316| v2316_6(void) = ReturnVoid : -# 2316| v2316_7(void) = AliasedUse : ~m? -# 2316| v2316_8(void) = ExitFunction : - -# 2331| void IfDestructors3(bool) -# 2331| Block 0 -# 2331| v2331_1(void) = EnterFunction : -# 2331| mu2331_2(unknown) = AliasedDefinition : -# 2331| mu2331_3(unknown) = InitializeNonLocal : -# 2331| r2331_4(glval) = VariableAddress[b] : -# 2331| mu2331_5(bool) = InitializeParameter[b] : &:r2331_4 -# 2332| r2332_1(glval) = VariableAddress[B] : -# 2332| mu2332_2(Bool) = Uninitialized[B] : &:r2332_1 -# 2332| r2332_3(glval) = FunctionAddress[Bool] : +# 2322| Block 3 +# 2322| r2322_1(glval) = VariableAddress[s] : +# 2322| r2322_2(glval) = FunctionAddress[~String] : +# 2322| v2322_3(void) = Call[~String] : func:r2322_2, this:r2322_1 +# 2322| mu2322_4(unknown) = ^CallSideEffect : ~m? +# 2322| v2322_5(void) = ^IndirectReadSideEffect[-1] : &:r2322_1, ~m? +# 2322| mu2322_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2322_1 +# 2323| v2323_1(void) = NoOp : +# 2317| v2317_6(void) = ReturnVoid : +# 2317| v2317_7(void) = AliasedUse : ~m? +# 2317| v2317_8(void) = ExitFunction : + +# 2332| void IfDestructors3(bool) +# 2332| Block 0 +# 2332| v2332_1(void) = EnterFunction : +# 2332| mu2332_2(unknown) = AliasedDefinition : +# 2332| mu2332_3(unknown) = InitializeNonLocal : # 2332| r2332_4(glval) = VariableAddress[b] : -# 2332| r2332_5(bool) = Load[b] : &:r2332_4, ~m? -# 2332| v2332_6(void) = Call[Bool] : func:r2332_3, this:r2332_1, 0:r2332_5 -# 2332| mu2332_7(unknown) = ^CallSideEffect : ~m? -# 2332| mu2332_8(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2332_1 -# 2332| r2332_9(glval) = VariableAddress[B] : -# 2332| r2332_10(glval) = FunctionAddress[operator bool] : -# 2332| r2332_11(bool) = Call[operator bool] : func:r2332_10, this:r2332_9 -# 2332| mu2332_12(unknown) = ^CallSideEffect : ~m? -# 2332| v2332_13(void) = ^IndirectReadSideEffect[-1] : &:r2332_9, ~m? -# 2332| mu2332_14(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2332_9 -# 2332| r2332_15(bool) = CopyValue : r2332_11 -# 2332| v2332_16(void) = ConditionalBranch : r2332_15 +# 2332| mu2332_5(bool) = InitializeParameter[b] : &:r2332_4 +# 2333| r2333_1(glval) = VariableAddress[B] : +# 2333| mu2333_2(Bool) = Uninitialized[B] : &:r2333_1 +# 2333| r2333_3(glval) = FunctionAddress[Bool] : +# 2333| r2333_4(glval) = VariableAddress[b] : +# 2333| r2333_5(bool) = Load[b] : &:r2333_4, ~m? +# 2333| v2333_6(void) = Call[Bool] : func:r2333_3, this:r2333_1, 0:r2333_5 +# 2333| mu2333_7(unknown) = ^CallSideEffect : ~m? +# 2333| mu2333_8(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2333_1 +# 2333| r2333_9(glval) = VariableAddress[B] : +# 2333| r2333_10(glval) = FunctionAddress[operator bool] : +# 2333| r2333_11(bool) = Call[operator bool] : func:r2333_10, this:r2333_9 +# 2333| mu2333_12(unknown) = ^CallSideEffect : ~m? +# 2333| v2333_13(void) = ^IndirectReadSideEffect[-1] : &:r2333_9, ~m? +# 2333| mu2333_14(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2333_9 +# 2333| r2333_15(bool) = CopyValue : r2333_11 +# 2333| v2333_16(void) = ConditionalBranch : r2333_15 #-----| False -> Block 2 #-----| True -> Block 1 -# 2333| Block 1 -# 2333| r2333_1(glval) = VariableAddress[s1] : -# 2333| mu2333_2(String) = Uninitialized[s1] : &:r2333_1 -# 2333| r2333_3(glval) = FunctionAddress[String] : -# 2333| v2333_4(void) = Call[String] : func:r2333_3, this:r2333_1 -# 2333| mu2333_5(unknown) = ^CallSideEffect : ~m? -# 2333| mu2333_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2333_1 +# 2334| Block 1 # 2334| r2334_1(glval) = VariableAddress[s1] : -# 2334| r2334_2(glval) = FunctionAddress[~String] : -# 2334| v2334_3(void) = Call[~String] : func:r2334_2, this:r2334_1 -# 2334| mu2334_4(unknown) = ^CallSideEffect : ~m? -# 2334| v2334_5(void) = ^IndirectReadSideEffect[-1] : &:r2334_1, ~m? +# 2334| mu2334_2(String) = Uninitialized[s1] : &:r2334_1 +# 2334| r2334_3(glval) = FunctionAddress[String] : +# 2334| v2334_4(void) = Call[String] : func:r2334_3, this:r2334_1 +# 2334| mu2334_5(unknown) = ^CallSideEffect : ~m? # 2334| mu2334_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2334_1 +# 2335| r2335_1(glval) = VariableAddress[s1] : +# 2335| r2335_2(glval) = FunctionAddress[~String] : +# 2335| v2335_3(void) = Call[~String] : func:r2335_2, this:r2335_1 +# 2335| mu2335_4(unknown) = ^CallSideEffect : ~m? +# 2335| v2335_5(void) = ^IndirectReadSideEffect[-1] : &:r2335_1, ~m? +# 2335| mu2335_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2335_1 #-----| Goto -> Block 3 -# 2335| Block 2 -# 2335| r2335_1(glval) = VariableAddress[s2] : -# 2335| mu2335_2(String) = Uninitialized[s2] : &:r2335_1 -# 2335| r2335_3(glval) = FunctionAddress[String] : -# 2335| v2335_4(void) = Call[String] : func:r2335_3, this:r2335_1 -# 2335| mu2335_5(unknown) = ^CallSideEffect : ~m? -# 2335| mu2335_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2335_1 +# 2336| Block 2 # 2336| r2336_1(glval) = VariableAddress[s2] : -# 2336| r2336_2(glval) = FunctionAddress[~String] : -# 2336| v2336_3(void) = Call[~String] : func:r2336_2, this:r2336_1 -# 2336| mu2336_4(unknown) = ^CallSideEffect : ~m? -# 2336| v2336_5(void) = ^IndirectReadSideEffect[-1] : &:r2336_1, ~m? +# 2336| mu2336_2(String) = Uninitialized[s2] : &:r2336_1 +# 2336| r2336_3(glval) = FunctionAddress[String] : +# 2336| v2336_4(void) = Call[String] : func:r2336_3, this:r2336_1 +# 2336| mu2336_5(unknown) = ^CallSideEffect : ~m? # 2336| mu2336_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2336_1 +# 2337| r2337_1(glval) = VariableAddress[s2] : +# 2337| r2337_2(glval) = FunctionAddress[~String] : +# 2337| v2337_3(void) = Call[~String] : func:r2337_2, this:r2337_1 +# 2337| mu2337_4(unknown) = ^CallSideEffect : ~m? +# 2337| v2337_5(void) = ^IndirectReadSideEffect[-1] : &:r2337_1, ~m? +# 2337| mu2337_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2337_1 #-----| Goto -> Block 3 -# 2336| Block 3 -# 2336| r2336_7(glval) = VariableAddress[B] : -# 2336| r2336_8(glval) = FunctionAddress[~Bool] : -# 2336| v2336_9(void) = Call[~Bool] : func:r2336_8, this:r2336_7 -# 2336| mu2336_10(unknown) = ^CallSideEffect : ~m? -# 2336| v2336_11(void) = ^IndirectReadSideEffect[-1] : &:r2336_7, ~m? -# 2336| mu2336_12(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2336_7 -# 2337| v2337_1(void) = NoOp : -# 2331| v2331_6(void) = ReturnVoid : -# 2331| v2331_7(void) = AliasedUse : ~m? -# 2331| v2331_8(void) = ExitFunction : - -# 2339| void WhileLoopDestructors(bool) -# 2339| Block 0 -# 2339| v2339_1(void) = EnterFunction : -# 2339| mu2339_2(unknown) = AliasedDefinition : -# 2339| mu2339_3(unknown) = InitializeNonLocal : -# 2339| r2339_4(glval) = VariableAddress[b] : -# 2339| mu2339_5(bool) = InitializeParameter[b] : &:r2339_4 -# 2341| r2341_1(glval) = VariableAddress[s] : -# 2341| mu2341_2(String) = Uninitialized[s] : &:r2341_1 -# 2341| r2341_3(glval) = FunctionAddress[String] : -# 2341| v2341_4(void) = Call[String] : func:r2341_3, this:r2341_1 -# 2341| mu2341_5(unknown) = ^CallSideEffect : ~m? -# 2341| mu2341_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2341_1 +# 2337| Block 3 +# 2337| r2337_7(glval) = VariableAddress[B] : +# 2337| r2337_8(glval) = FunctionAddress[~Bool] : +# 2337| v2337_9(void) = Call[~Bool] : func:r2337_8, this:r2337_7 +# 2337| mu2337_10(unknown) = ^CallSideEffect : ~m? +# 2337| v2337_11(void) = ^IndirectReadSideEffect[-1] : &:r2337_7, ~m? +# 2337| mu2337_12(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2337_7 +# 2338| v2338_1(void) = NoOp : +# 2332| v2332_6(void) = ReturnVoid : +# 2332| v2332_7(void) = AliasedUse : ~m? +# 2332| v2332_8(void) = ExitFunction : + +# 2340| void WhileLoopDestructors(bool) +# 2340| Block 0 +# 2340| v2340_1(void) = EnterFunction : +# 2340| mu2340_2(unknown) = AliasedDefinition : +# 2340| mu2340_3(unknown) = InitializeNonLocal : +# 2340| r2340_4(glval) = VariableAddress[b] : +# 2340| mu2340_5(bool) = InitializeParameter[b] : &:r2340_4 +# 2342| r2342_1(glval) = VariableAddress[s] : +# 2342| mu2342_2(String) = Uninitialized[s] : &:r2342_1 +# 2342| r2342_3(glval) = FunctionAddress[String] : +# 2342| v2342_4(void) = Call[String] : func:r2342_3, this:r2342_1 +# 2342| mu2342_5(unknown) = ^CallSideEffect : ~m? +# 2342| mu2342_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2342_1 #-----| Goto -> Block 1 -# 2342| Block 1 -# 2342| r2342_1(glval) = VariableAddress[b] : -# 2342| r2342_2(bool) = Load[b] : &:r2342_1, ~m? -# 2342| v2342_3(void) = ConditionalBranch : r2342_2 +# 2343| Block 1 +# 2343| r2343_1(glval) = VariableAddress[b] : +# 2343| r2343_2(bool) = Load[b] : &:r2343_1, ~m? +# 2343| v2343_3(void) = ConditionalBranch : r2343_2 #-----| False -> Block 3 #-----| True -> Block 2 -# 2343| Block 2 -# 2343| r2343_1(bool) = Constant[0] : -# 2343| r2343_2(glval) = VariableAddress[b] : -# 2343| mu2343_3(bool) = Store[b] : &:r2343_2, r2343_1 +# 2344| Block 2 +# 2344| r2344_1(bool) = Constant[0] : +# 2344| r2344_2(glval) = VariableAddress[b] : +# 2344| mu2344_3(bool) = Store[b] : &:r2344_2, r2344_1 #-----| Goto (back edge) -> Block 1 -# 2345| Block 3 -# 2345| r2345_1(glval) = VariableAddress[s] : -# 2345| r2345_2(glval) = FunctionAddress[~String] : -# 2345| v2345_3(void) = Call[~String] : func:r2345_2, this:r2345_1 -# 2345| mu2345_4(unknown) = ^CallSideEffect : ~m? -# 2345| v2345_5(void) = ^IndirectReadSideEffect[-1] : &:r2345_1, ~m? -# 2345| mu2345_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2345_1 +# 2346| Block 3 +# 2346| r2346_1(glval) = VariableAddress[s] : +# 2346| r2346_2(glval) = FunctionAddress[~String] : +# 2346| v2346_3(void) = Call[~String] : func:r2346_2, this:r2346_1 +# 2346| mu2346_4(unknown) = ^CallSideEffect : ~m? +# 2346| v2346_5(void) = ^IndirectReadSideEffect[-1] : &:r2346_1, ~m? +# 2346| mu2346_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2346_1 #-----| Goto -> Block 4 -# 2348| Block 4 -# 2348| r2348_1(glval) = VariableAddress[B] : -# 2348| mu2348_2(Bool) = Uninitialized[B] : &:r2348_1 -# 2348| r2348_3(glval) = FunctionAddress[Bool] : -# 2348| r2348_4(glval) = VariableAddress[b] : -# 2348| r2348_5(bool) = Load[b] : &:r2348_4, ~m? -# 2348| v2348_6(void) = Call[Bool] : func:r2348_3, this:r2348_1, 0:r2348_5 -# 2348| mu2348_7(unknown) = ^CallSideEffect : ~m? -# 2348| mu2348_8(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2348_1 -# 2348| r2348_9(glval) = VariableAddress[B] : -# 2348| r2348_10(glval) = FunctionAddress[operator bool] : -# 2348| r2348_11(bool) = Call[operator bool] : func:r2348_10, this:r2348_9 -# 2348| mu2348_12(unknown) = ^CallSideEffect : ~m? -# 2348| v2348_13(void) = ^IndirectReadSideEffect[-1] : &:r2348_9, ~m? -# 2348| mu2348_14(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2348_9 -# 2348| r2348_15(bool) = CopyValue : r2348_11 -# 2348| v2348_16(void) = ConditionalBranch : r2348_15 +# 2349| Block 4 +# 2349| r2349_1(glval) = VariableAddress[B] : +# 2349| mu2349_2(Bool) = Uninitialized[B] : &:r2349_1 +# 2349| r2349_3(glval) = FunctionAddress[Bool] : +# 2349| r2349_4(glval) = VariableAddress[b] : +# 2349| r2349_5(bool) = Load[b] : &:r2349_4, ~m? +# 2349| v2349_6(void) = Call[Bool] : func:r2349_3, this:r2349_1, 0:r2349_5 +# 2349| mu2349_7(unknown) = ^CallSideEffect : ~m? +# 2349| mu2349_8(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2349_1 +# 2349| r2349_9(glval) = VariableAddress[B] : +# 2349| r2349_10(glval) = FunctionAddress[operator bool] : +# 2349| r2349_11(bool) = Call[operator bool] : func:r2349_10, this:r2349_9 +# 2349| mu2349_12(unknown) = ^CallSideEffect : ~m? +# 2349| v2349_13(void) = ^IndirectReadSideEffect[-1] : &:r2349_9, ~m? +# 2349| mu2349_14(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2349_9 +# 2349| r2349_15(bool) = CopyValue : r2349_11 +# 2349| v2349_16(void) = ConditionalBranch : r2349_15 #-----| False -> Block 6 #-----| True -> Block 5 -# 2349| Block 5 -# 2349| r2349_1(bool) = Constant[0] : -# 2349| r2349_2(glval) = VariableAddress[b] : -# 2349| mu2349_3(bool) = Store[b] : &:r2349_2, r2349_1 -# 2350| r2350_1(glval) = VariableAddress[B] : -# 2350| r2350_2(glval) = FunctionAddress[~Bool] : -# 2350| v2350_3(void) = Call[~Bool] : func:r2350_2, this:r2350_1 -# 2350| mu2350_4(unknown) = ^CallSideEffect : ~m? -# 2350| v2350_5(void) = ^IndirectReadSideEffect[-1] : &:r2350_1, ~m? -# 2350| mu2350_6(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2350_1 +# 2350| Block 5 +# 2350| r2350_1(bool) = Constant[0] : +# 2350| r2350_2(glval) = VariableAddress[b] : +# 2350| mu2350_3(bool) = Store[b] : &:r2350_2, r2350_1 +# 2351| r2351_1(glval) = VariableAddress[B] : +# 2351| r2351_2(glval) = FunctionAddress[~Bool] : +# 2351| v2351_3(void) = Call[~Bool] : func:r2351_2, this:r2351_1 +# 2351| mu2351_4(unknown) = ^CallSideEffect : ~m? +# 2351| v2351_5(void) = ^IndirectReadSideEffect[-1] : &:r2351_1, ~m? +# 2351| mu2351_6(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2351_1 #-----| Goto (back edge) -> Block 4 -# 2350| Block 6 -# 2350| r2350_7(glval) = VariableAddress[B] : -# 2350| r2350_8(glval) = FunctionAddress[~Bool] : -# 2350| v2350_9(void) = Call[~Bool] : func:r2350_8, this:r2350_7 -# 2350| mu2350_10(unknown) = ^CallSideEffect : ~m? -# 2350| v2350_11(void) = ^IndirectReadSideEffect[-1] : &:r2350_7, ~m? -# 2350| mu2350_12(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2350_7 -# 2352| v2352_1(void) = NoOp : -# 2339| v2339_6(void) = ReturnVoid : -# 2339| v2339_7(void) = AliasedUse : ~m? -# 2339| v2339_8(void) = ExitFunction : - -# 2354| void VoidFunc() -# 2354| Block 0 -# 2354| v2354_1(void) = EnterFunction : -# 2354| mu2354_2(unknown) = AliasedDefinition : -# 2354| mu2354_3(unknown) = InitializeNonLocal : -# 2354| v2354_4(void) = NoOp : -# 2354| v2354_5(void) = ReturnVoid : -# 2354| v2354_6(void) = AliasedUse : ~m? -# 2354| v2354_7(void) = ExitFunction : - -# 2356| void IfReturnDestructors(bool) -# 2356| Block 0 -# 2356| v2356_1(void) = EnterFunction : -# 2356| mu2356_2(unknown) = AliasedDefinition : -# 2356| mu2356_3(unknown) = InitializeNonLocal : -# 2356| r2356_4(glval) = VariableAddress[b] : -# 2356| mu2356_5(bool) = InitializeParameter[b] : &:r2356_4 -# 2357| r2357_1(glval) = VariableAddress[s] : -# 2357| mu2357_2(String) = Uninitialized[s] : &:r2357_1 -# 2357| r2357_3(glval) = FunctionAddress[String] : -# 2357| v2357_4(void) = Call[String] : func:r2357_3, this:r2357_1 -# 2357| mu2357_5(unknown) = ^CallSideEffect : ~m? -# 2357| mu2357_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2357_1 -# 2358| r2358_1(glval) = VariableAddress[b] : -# 2358| r2358_2(bool) = Load[b] : &:r2358_1, ~m? -# 2358| v2358_3(void) = ConditionalBranch : r2358_2 +# 2351| Block 6 +# 2351| r2351_7(glval) = VariableAddress[B] : +# 2351| r2351_8(glval) = FunctionAddress[~Bool] : +# 2351| v2351_9(void) = Call[~Bool] : func:r2351_8, this:r2351_7 +# 2351| mu2351_10(unknown) = ^CallSideEffect : ~m? +# 2351| v2351_11(void) = ^IndirectReadSideEffect[-1] : &:r2351_7, ~m? +# 2351| mu2351_12(Bool) = ^IndirectMayWriteSideEffect[-1] : &:r2351_7 +# 2353| v2353_1(void) = NoOp : +# 2340| v2340_6(void) = ReturnVoid : +# 2340| v2340_7(void) = AliasedUse : ~m? +# 2340| v2340_8(void) = ExitFunction : + +# 2355| void VoidFunc() +# 2355| Block 0 +# 2355| v2355_1(void) = EnterFunction : +# 2355| mu2355_2(unknown) = AliasedDefinition : +# 2355| mu2355_3(unknown) = InitializeNonLocal : +# 2355| v2355_4(void) = NoOp : +# 2355| v2355_5(void) = ReturnVoid : +# 2355| v2355_6(void) = AliasedUse : ~m? +# 2355| v2355_7(void) = ExitFunction : + +# 2357| void IfReturnDestructors(bool) +# 2357| Block 0 +# 2357| v2357_1(void) = EnterFunction : +# 2357| mu2357_2(unknown) = AliasedDefinition : +# 2357| mu2357_3(unknown) = InitializeNonLocal : +# 2357| r2357_4(glval) = VariableAddress[b] : +# 2357| mu2357_5(bool) = InitializeParameter[b] : &:r2357_4 +# 2358| r2358_1(glval) = VariableAddress[s] : +# 2358| mu2358_2(String) = Uninitialized[s] : &:r2358_1 +# 2358| r2358_3(glval) = FunctionAddress[String] : +# 2358| v2358_4(void) = Call[String] : func:r2358_3, this:r2358_1 +# 2358| mu2358_5(unknown) = ^CallSideEffect : ~m? +# 2358| mu2358_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2358_1 +# 2359| r2359_1(glval) = VariableAddress[b] : +# 2359| r2359_2(bool) = Load[b] : &:r2359_1, ~m? +# 2359| v2359_3(void) = ConditionalBranch : r2359_2 #-----| False -> Block 3 #-----| True -> Block 2 -# 2356| Block 1 -# 2356| v2356_6(void) = ReturnVoid : -# 2356| v2356_7(void) = AliasedUse : ~m? -# 2356| v2356_8(void) = ExitFunction : - -# 2359| Block 2 -# 2359| v2359_1(void) = NoOp : -# 2365| r2365_1(glval) = VariableAddress[s] : -# 2365| r2365_2(glval) = FunctionAddress[~String] : -# 2365| v2365_3(void) = Call[~String] : func:r2365_2, this:r2365_1 -# 2365| mu2365_4(unknown) = ^CallSideEffect : ~m? -# 2365| v2365_5(void) = ^IndirectReadSideEffect[-1] : &:r2365_1, ~m? -# 2365| mu2365_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2365_1 +# 2357| Block 1 +# 2357| v2357_6(void) = ReturnVoid : +# 2357| v2357_7(void) = AliasedUse : ~m? +# 2357| v2357_8(void) = ExitFunction : + +# 2360| Block 2 +# 2360| v2360_1(void) = NoOp : +# 2366| r2366_1(glval) = VariableAddress[s] : +# 2366| r2366_2(glval) = FunctionAddress[~String] : +# 2366| v2366_3(void) = Call[~String] : func:r2366_2, this:r2366_1 +# 2366| mu2366_4(unknown) = ^CallSideEffect : ~m? +# 2366| v2366_5(void) = ^IndirectReadSideEffect[-1] : &:r2366_1, ~m? +# 2366| mu2366_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2366_1 #-----| Goto -> Block 1 -# 2361| Block 3 -# 2361| r2361_1(glval) = VariableAddress[b] : -# 2361| r2361_2(bool) = Load[b] : &:r2361_1, ~m? -# 2361| v2361_3(void) = ConditionalBranch : r2361_2 +# 2362| Block 3 +# 2362| r2362_1(glval) = VariableAddress[b] : +# 2362| r2362_2(bool) = Load[b] : &:r2362_1, ~m? +# 2362| v2362_3(void) = ConditionalBranch : r2362_2 #-----| False -> Block 5 #-----| True -> Block 4 -# 2362| Block 4 -# 2362| r2362_1(glval) = FunctionAddress[VoidFunc] : -# 2362| v2362_2(void) = Call[VoidFunc] : func:r2362_1 -# 2362| mu2362_3(unknown) = ^CallSideEffect : ~m? -# 2362| v2362_4(void) = NoOp : -# 2365| r2365_7(glval) = VariableAddress[s] : -# 2365| r2365_8(glval) = FunctionAddress[~String] : -# 2365| v2365_9(void) = Call[~String] : func:r2365_8, this:r2365_7 -# 2365| mu2365_10(unknown) = ^CallSideEffect : ~m? -# 2365| v2365_11(void) = ^IndirectReadSideEffect[-1] : &:r2365_7, ~m? -# 2365| mu2365_12(String) = ^IndirectMayWriteSideEffect[-1] : &:r2365_7 +# 2363| Block 4 +# 2363| r2363_1(glval) = FunctionAddress[VoidFunc] : +# 2363| v2363_2(void) = Call[VoidFunc] : func:r2363_1 +# 2363| mu2363_3(unknown) = ^CallSideEffect : ~m? +# 2363| v2363_4(void) = NoOp : +# 2366| r2366_7(glval) = VariableAddress[s] : +# 2366| r2366_8(glval) = FunctionAddress[~String] : +# 2366| v2366_9(void) = Call[~String] : func:r2366_8, this:r2366_7 +# 2366| mu2366_10(unknown) = ^CallSideEffect : ~m? +# 2366| v2366_11(void) = ^IndirectReadSideEffect[-1] : &:r2366_7, ~m? +# 2366| mu2366_12(String) = ^IndirectMayWriteSideEffect[-1] : &:r2366_7 #-----| Goto -> Block 1 -# 2364| Block 5 -# 2364| r2364_1(glval) = VariableAddress[s] : -# 2365| v2365_13(void) = NoOp : -# 2365| r2365_14(glval) = VariableAddress[s] : -# 2365| r2365_15(glval) = FunctionAddress[~String] : -# 2365| v2365_16(void) = Call[~String] : func:r2365_15, this:r2365_14 -# 2365| mu2365_17(unknown) = ^CallSideEffect : ~m? -# 2365| v2365_18(void) = ^IndirectReadSideEffect[-1] : &:r2365_14, ~m? -# 2365| mu2365_19(String) = ^IndirectMayWriteSideEffect[-1] : &:r2365_14 +# 2365| Block 5 +# 2365| r2365_1(glval) = VariableAddress[s] : +# 2366| v2366_13(void) = NoOp : +# 2366| r2366_14(glval) = VariableAddress[s] : +# 2366| r2366_15(glval) = FunctionAddress[~String] : +# 2366| v2366_16(void) = Call[~String] : func:r2366_15, this:r2366_14 +# 2366| mu2366_17(unknown) = ^CallSideEffect : ~m? +# 2366| v2366_18(void) = ^IndirectReadSideEffect[-1] : &:r2366_14, ~m? +# 2366| mu2366_19(String) = ^IndirectMayWriteSideEffect[-1] : &:r2366_14 #-----| Goto -> Block 1 -# 2367| int IfReturnDestructors3(bool) -# 2367| Block 0 -# 2367| v2367_1(void) = EnterFunction : -# 2367| mu2367_2(unknown) = AliasedDefinition : -# 2367| mu2367_3(unknown) = InitializeNonLocal : -# 2367| r2367_4(glval) = VariableAddress[b] : -# 2367| mu2367_5(bool) = InitializeParameter[b] : &:r2367_4 -# 2368| r2368_1(glval) = VariableAddress[s] : -# 2368| mu2368_2(String) = Uninitialized[s] : &:r2368_1 -# 2368| r2368_3(glval) = FunctionAddress[String] : -# 2368| v2368_4(void) = Call[String] : func:r2368_3, this:r2368_1 -# 2368| mu2368_5(unknown) = ^CallSideEffect : ~m? -# 2368| mu2368_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2368_1 -# 2369| r2369_1(glval) = VariableAddress[b] : -# 2369| r2369_2(bool) = Load[b] : &:r2369_1, ~m? -# 2369| v2369_3(void) = ConditionalBranch : r2369_2 +# 2368| int IfReturnDestructors3(bool) +# 2368| Block 0 +# 2368| v2368_1(void) = EnterFunction : +# 2368| mu2368_2(unknown) = AliasedDefinition : +# 2368| mu2368_3(unknown) = InitializeNonLocal : +# 2368| r2368_4(glval) = VariableAddress[b] : +# 2368| mu2368_5(bool) = InitializeParameter[b] : &:r2368_4 +# 2369| r2369_1(glval) = VariableAddress[s] : +# 2369| mu2369_2(String) = Uninitialized[s] : &:r2369_1 +# 2369| r2369_3(glval) = FunctionAddress[String] : +# 2369| v2369_4(void) = Call[String] : func:r2369_3, this:r2369_1 +# 2369| mu2369_5(unknown) = ^CallSideEffect : ~m? +# 2369| mu2369_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2369_1 +# 2370| r2370_1(glval) = VariableAddress[b] : +# 2370| r2370_2(bool) = Load[b] : &:r2370_1, ~m? +# 2370| v2370_3(void) = ConditionalBranch : r2370_2 #-----| False -> Block 3 #-----| True -> Block 2 -# 2367| Block 1 -# 2367| r2367_6(glval) = VariableAddress[#return] : -# 2367| v2367_7(void) = ReturnValue : &:r2367_6, ~m? -# 2367| v2367_8(void) = AliasedUse : ~m? -# 2367| v2367_9(void) = ExitFunction : - -# 2370| Block 2 -# 2370| r2370_1(glval) = VariableAddress[#return] : -# 2370| r2370_2(int) = Constant[1] : -# 2370| mu2370_3(int) = Store[#return] : &:r2370_1, r2370_2 -# 2373| r2373_1(glval) = VariableAddress[s] : -# 2373| r2373_2(glval) = FunctionAddress[~String] : -# 2373| v2373_3(void) = Call[~String] : func:r2373_2, this:r2373_1 -# 2373| mu2373_4(unknown) = ^CallSideEffect : ~m? -# 2373| v2373_5(void) = ^IndirectReadSideEffect[-1] : &:r2373_1, ~m? -# 2373| mu2373_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2373_1 +# 2368| Block 1 +# 2368| r2368_6(glval) = VariableAddress[#return] : +# 2368| v2368_7(void) = ReturnValue : &:r2368_6, ~m? +# 2368| v2368_8(void) = AliasedUse : ~m? +# 2368| v2368_9(void) = ExitFunction : + +# 2371| Block 2 +# 2371| r2371_1(glval) = VariableAddress[#return] : +# 2371| r2371_2(int) = Constant[1] : +# 2371| mu2371_3(int) = Store[#return] : &:r2371_1, r2371_2 +# 2374| r2374_1(glval) = VariableAddress[s] : +# 2374| r2374_2(glval) = FunctionAddress[~String] : +# 2374| v2374_3(void) = Call[~String] : func:r2374_2, this:r2374_1 +# 2374| mu2374_4(unknown) = ^CallSideEffect : ~m? +# 2374| v2374_5(void) = ^IndirectReadSideEffect[-1] : &:r2374_1, ~m? +# 2374| mu2374_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2374_1 #-----| Goto -> Block 1 -# 2372| Block 3 -# 2372| r2372_1(glval) = VariableAddress[#return] : -# 2372| r2372_2(int) = Constant[0] : -# 2372| mu2372_3(int) = Store[#return] : &:r2372_1, r2372_2 -# 2373| r2373_7(glval) = VariableAddress[s] : -# 2373| r2373_8(glval) = FunctionAddress[~String] : -# 2373| v2373_9(void) = Call[~String] : func:r2373_8, this:r2373_7 -# 2373| mu2373_10(unknown) = ^CallSideEffect : ~m? -# 2373| v2373_11(void) = ^IndirectReadSideEffect[-1] : &:r2373_7, ~m? -# 2373| mu2373_12(String) = ^IndirectMayWriteSideEffect[-1] : &:r2373_7 +# 2373| Block 3 +# 2373| r2373_1(glval) = VariableAddress[#return] : +# 2373| r2373_2(int) = Constant[0] : +# 2373| mu2373_3(int) = Store[#return] : &:r2373_1, r2373_2 +# 2374| r2374_7(glval) = VariableAddress[s] : +# 2374| r2374_8(glval) = FunctionAddress[~String] : +# 2374| v2374_9(void) = Call[~String] : func:r2374_8, this:r2374_7 +# 2374| mu2374_10(unknown) = ^CallSideEffect : ~m? +# 2374| v2374_11(void) = ^IndirectReadSideEffect[-1] : &:r2374_7, ~m? +# 2374| mu2374_12(String) = ^IndirectMayWriteSideEffect[-1] : &:r2374_7 #-----| Goto -> Block 1 -# 2375| void VoidReturnDestructors() -# 2375| Block 0 -# 2375| v2375_1(void) = EnterFunction : -# 2375| mu2375_2(unknown) = AliasedDefinition : -# 2375| mu2375_3(unknown) = InitializeNonLocal : -# 2376| r2376_1(glval) = VariableAddress[s] : -# 2376| mu2376_2(String) = Uninitialized[s] : &:r2376_1 -# 2376| r2376_3(glval) = FunctionAddress[String] : -# 2376| v2376_4(void) = Call[String] : func:r2376_3, this:r2376_1 -# 2376| mu2376_5(unknown) = ^CallSideEffect : ~m? -# 2376| mu2376_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2376_1 -# 2377| r2377_1(glval) = FunctionAddress[VoidFunc] : -# 2377| v2377_2(void) = Call[VoidFunc] : func:r2377_1 -# 2377| mu2377_3(unknown) = ^CallSideEffect : ~m? -# 2377| v2377_4(void) = NoOp : -# 2378| r2378_1(glval) = VariableAddress[s] : -# 2378| r2378_2(glval) = FunctionAddress[~String] : -# 2378| v2378_3(void) = Call[~String] : func:r2378_2, this:r2378_1 -# 2378| mu2378_4(unknown) = ^CallSideEffect : ~m? -# 2378| v2378_5(void) = ^IndirectReadSideEffect[-1] : &:r2378_1, ~m? -# 2378| mu2378_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2378_1 -# 2375| v2375_4(void) = ReturnVoid : -# 2375| v2375_5(void) = AliasedUse : ~m? -# 2375| v2375_6(void) = ExitFunction : - -# 2388| return_routine_type::VoidToIntMemberFunc return_routine_type::GetVoidToIntFunc() -# 2388| Block 0 -# 2388| v2388_1(void) = EnterFunction : -# 2388| mu2388_2(unknown) = AliasedDefinition : -# 2388| mu2388_3(unknown) = InitializeNonLocal : -# 2390| r2390_1(glval<..:: *>) = VariableAddress[#return] : -# 2390| r2390_2(..()(..)) = FunctionAddress[VoidToInt] : -# 2390| mu2390_3(..:: *) = Store[#return] : &:r2390_1, r2390_2 -# 2388| r2388_4(glval<..:: *>) = VariableAddress[#return] : -# 2388| v2388_5(void) = ReturnValue : &:r2388_4, ~m? -# 2388| v2388_6(void) = AliasedUse : ~m? -# 2388| v2388_7(void) = ExitFunction : - -# 2395| int small_operation_should_not_be_constant_folded() -# 2395| Block 0 -# 2395| v2395_1(void) = EnterFunction : -# 2395| mu2395_2(unknown) = AliasedDefinition : -# 2395| mu2395_3(unknown) = InitializeNonLocal : -# 2396| r2396_1(glval) = VariableAddress[#return] : -# 2396| r2396_2(int) = Constant[1] : -# 2396| r2396_3(int) = Constant[2] : -# 2396| r2396_4(int) = BitXor : r2396_2, r2396_3 -# 2396| mu2396_5(int) = Store[#return] : &:r2396_1, r2396_4 -# 2395| r2395_4(glval) = VariableAddress[#return] : -# 2395| v2395_5(void) = ReturnValue : &:r2395_4, ~m? -# 2395| v2395_6(void) = AliasedUse : ~m? -# 2395| v2395_7(void) = ExitFunction : - -# 2406| int large_operation_should_be_constant_folded() -# 2406| Block 0 -# 2406| v2406_1(void) = EnterFunction : -# 2406| mu2406_2(unknown) = AliasedDefinition : -# 2406| mu2406_3(unknown) = InitializeNonLocal : -# 2407| r2407_1(glval) = VariableAddress[#return] : -# 2407| r2407_2(int) = Constant[0] : -# 2407| mu2407_3(int) = Store[#return] : &:r2407_1, r2407_2 -# 2406| r2406_4(glval) = VariableAddress[#return] : -# 2406| v2406_5(void) = ReturnValue : &:r2406_4, ~m? -# 2406| v2406_6(void) = AliasedUse : ~m? -# 2406| v2406_7(void) = ExitFunction : - -# 2410| void initialization_with_temp_destructor() -# 2410| Block 0 -# 2410| v2410_1(void) = EnterFunction : -# 2410| mu2410_2(unknown) = AliasedDefinition : -# 2410| mu2410_3(unknown) = InitializeNonLocal : -# 2411| r2411_1(glval) = VariableAddress[x] : -# 2411| r2411_2(glval) = VariableAddress[#temp2411:18] : -# 2411| mu2411_3(ClassWithDestructor) = Uninitialized[#temp2411:18] : &:r2411_2 -# 2411| r2411_4(glval) = FunctionAddress[ClassWithDestructor] : -# 2411| v2411_5(void) = Call[ClassWithDestructor] : func:r2411_4, this:r2411_2 -# 2411| mu2411_6(unknown) = ^CallSideEffect : ~m? -# 2411| mu2411_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2411_2 -# 2411| r2411_8(glval) = FunctionAddress[get_x] : -# 2411| r2411_9(char) = Call[get_x] : func:r2411_8, this:r2411_2 -# 2411| mu2411_10(unknown) = ^CallSideEffect : ~m? -# 2411| v2411_11(void) = ^IndirectReadSideEffect[-1] : &:r2411_2, ~m? -# 2411| mu2411_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2411_2 -# 2411| r2411_13(glval) = CopyValue : r2411_2 -# 2411| r2411_14(glval) = FunctionAddress[~ClassWithDestructor] : -# 2411| v2411_15(void) = Call[~ClassWithDestructor] : func:r2411_14, this:r2411_13 -# 2411| mu2411_16(unknown) = ^CallSideEffect : ~m? -# 2411| v2411_17(void) = ^IndirectReadSideEffect[-1] : &:r2411_13, ~m? -# 2411| mu2411_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2411_13 -# 2411| mu2411_19(char) = Store[x] : &:r2411_1, r2411_9 -# 2411| r2411_20(glval) = VariableAddress[x] : -# 2411| r2411_21(char) = Load[x] : &:r2411_20, ~m? -# 2411| r2411_22(char) = Constant[0] : -# 2411| r2411_23(bool) = CompareNE : r2411_21, r2411_22 -# 2411| r2411_24(bool) = CopyValue : r2411_23 -# 2411| v2411_25(void) = ConditionalBranch : r2411_24 +# 2376| void VoidReturnDestructors() +# 2376| Block 0 +# 2376| v2376_1(void) = EnterFunction : +# 2376| mu2376_2(unknown) = AliasedDefinition : +# 2376| mu2376_3(unknown) = InitializeNonLocal : +# 2377| r2377_1(glval) = VariableAddress[s] : +# 2377| mu2377_2(String) = Uninitialized[s] : &:r2377_1 +# 2377| r2377_3(glval) = FunctionAddress[String] : +# 2377| v2377_4(void) = Call[String] : func:r2377_3, this:r2377_1 +# 2377| mu2377_5(unknown) = ^CallSideEffect : ~m? +# 2377| mu2377_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2377_1 +# 2378| r2378_1(glval) = FunctionAddress[VoidFunc] : +# 2378| v2378_2(void) = Call[VoidFunc] : func:r2378_1 +# 2378| mu2378_3(unknown) = ^CallSideEffect : ~m? +# 2378| v2378_4(void) = NoOp : +# 2379| r2379_1(glval) = VariableAddress[s] : +# 2379| r2379_2(glval) = FunctionAddress[~String] : +# 2379| v2379_3(void) = Call[~String] : func:r2379_2, this:r2379_1 +# 2379| mu2379_4(unknown) = ^CallSideEffect : ~m? +# 2379| v2379_5(void) = ^IndirectReadSideEffect[-1] : &:r2379_1, ~m? +# 2379| mu2379_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2379_1 +# 2376| v2376_4(void) = ReturnVoid : +# 2376| v2376_5(void) = AliasedUse : ~m? +# 2376| v2376_6(void) = ExitFunction : + +# 2389| return_routine_type::VoidToIntMemberFunc return_routine_type::GetVoidToIntFunc() +# 2389| Block 0 +# 2389| v2389_1(void) = EnterFunction : +# 2389| mu2389_2(unknown) = AliasedDefinition : +# 2389| mu2389_3(unknown) = InitializeNonLocal : +# 2391| r2391_1(glval<..:: *>) = VariableAddress[#return] : +# 2391| r2391_2(..()(..)) = FunctionAddress[VoidToInt] : +# 2391| mu2391_3(..:: *) = Store[#return] : &:r2391_1, r2391_2 +# 2389| r2389_4(glval<..:: *>) = VariableAddress[#return] : +# 2389| v2389_5(void) = ReturnValue : &:r2389_4, ~m? +# 2389| v2389_6(void) = AliasedUse : ~m? +# 2389| v2389_7(void) = ExitFunction : + +# 2396| int small_operation_should_not_be_constant_folded() +# 2396| Block 0 +# 2396| v2396_1(void) = EnterFunction : +# 2396| mu2396_2(unknown) = AliasedDefinition : +# 2396| mu2396_3(unknown) = InitializeNonLocal : +# 2397| r2397_1(glval) = VariableAddress[#return] : +# 2397| r2397_2(int) = Constant[1] : +# 2397| r2397_3(int) = Constant[2] : +# 2397| r2397_4(int) = BitXor : r2397_2, r2397_3 +# 2397| mu2397_5(int) = Store[#return] : &:r2397_1, r2397_4 +# 2396| r2396_4(glval) = VariableAddress[#return] : +# 2396| v2396_5(void) = ReturnValue : &:r2396_4, ~m? +# 2396| v2396_6(void) = AliasedUse : ~m? +# 2396| v2396_7(void) = ExitFunction : + +# 2407| int large_operation_should_be_constant_folded() +# 2407| Block 0 +# 2407| v2407_1(void) = EnterFunction : +# 2407| mu2407_2(unknown) = AliasedDefinition : +# 2407| mu2407_3(unknown) = InitializeNonLocal : +# 2408| r2408_1(glval) = VariableAddress[#return] : +# 2408| r2408_2(int) = Constant[0] : +# 2408| mu2408_3(int) = Store[#return] : &:r2408_1, r2408_2 +# 2407| r2407_4(glval) = VariableAddress[#return] : +# 2407| v2407_5(void) = ReturnValue : &:r2407_4, ~m? +# 2407| v2407_6(void) = AliasedUse : ~m? +# 2407| v2407_7(void) = ExitFunction : + +# 2411| void initialization_with_temp_destructor() +# 2411| Block 0 +# 2411| v2411_1(void) = EnterFunction : +# 2411| mu2411_2(unknown) = AliasedDefinition : +# 2411| mu2411_3(unknown) = InitializeNonLocal : +# 2412| r2412_1(glval) = VariableAddress[x] : +# 2412| r2412_2(glval) = VariableAddress[#temp2412:18] : +# 2412| mu2412_3(ClassWithDestructor) = Uninitialized[#temp2412:18] : &:r2412_2 +# 2412| r2412_4(glval) = FunctionAddress[ClassWithDestructor] : +# 2412| v2412_5(void) = Call[ClassWithDestructor] : func:r2412_4, this:r2412_2 +# 2412| mu2412_6(unknown) = ^CallSideEffect : ~m? +# 2412| mu2412_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2412_2 +# 2412| r2412_8(glval) = FunctionAddress[get_x] : +# 2412| r2412_9(char) = Call[get_x] : func:r2412_8, this:r2412_2 +# 2412| mu2412_10(unknown) = ^CallSideEffect : ~m? +# 2412| v2412_11(void) = ^IndirectReadSideEffect[-1] : &:r2412_2, ~m? +# 2412| mu2412_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2412_2 +# 2412| r2412_13(glval) = CopyValue : r2412_2 +# 2412| r2412_14(glval) = FunctionAddress[~ClassWithDestructor] : +# 2412| v2412_15(void) = Call[~ClassWithDestructor] : func:r2412_14, this:r2412_13 +# 2412| mu2412_16(unknown) = ^CallSideEffect : ~m? +# 2412| v2412_17(void) = ^IndirectReadSideEffect[-1] : &:r2412_13, ~m? +# 2412| mu2412_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2412_13 +# 2412| mu2412_19(char) = Store[x] : &:r2412_1, r2412_9 +# 2412| r2412_20(glval) = VariableAddress[x] : +# 2412| r2412_21(char) = Load[x] : &:r2412_20, ~m? +# 2412| r2412_22(char) = Constant[0] : +# 2412| r2412_23(bool) = CompareNE : r2412_21, r2412_22 +# 2412| r2412_24(bool) = CopyValue : r2412_23 +# 2412| v2412_25(void) = ConditionalBranch : r2412_24 #-----| False -> Block 2 #-----| True -> Block 1 -# 2412| Block 1 -# 2412| r2412_1(glval) = VariableAddress[x] : -# 2412| r2412_2(char) = Load[x] : &:r2412_1, ~m? -# 2412| r2412_3(char) = Constant[1] : -# 2412| r2412_4(char) = Add : r2412_2, r2412_3 -# 2412| mu2412_5(char) = Store[x] : &:r2412_1, r2412_4 +# 2413| Block 1 +# 2413| r2413_1(glval) = VariableAddress[x] : +# 2413| r2413_2(char) = Load[x] : &:r2413_1, ~m? +# 2413| r2413_3(char) = Constant[1] : +# 2413| r2413_4(char) = Add : r2413_2, r2413_3 +# 2413| mu2413_5(char) = Store[x] : &:r2413_1, r2413_4 #-----| Goto -> Block 2 -# 2414| Block 2 -# 2414| r2414_1(glval) = VariableAddress[x] : -# 2414| r2414_2(glval) = VariableAddress[#temp2414:18] : -# 2414| mu2414_3(ClassWithDestructor) = Uninitialized[#temp2414:18] : &:r2414_2 -# 2414| r2414_4(glval) = FunctionAddress[ClassWithDestructor] : -# 2414| v2414_5(void) = Call[ClassWithDestructor] : func:r2414_4, this:r2414_2 -# 2414| mu2414_6(unknown) = ^CallSideEffect : ~m? -# 2414| mu2414_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2414_2 -# 2414| r2414_8(glval) = FunctionAddress[get_x] : -# 2414| r2414_9(char) = Call[get_x] : func:r2414_8, this:r2414_2 -# 2414| mu2414_10(unknown) = ^CallSideEffect : ~m? -# 2414| v2414_11(void) = ^IndirectReadSideEffect[-1] : &:r2414_2, ~m? -# 2414| mu2414_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2414_2 -# 2414| r2414_13(glval) = CopyValue : r2414_2 -# 2414| r2414_14(glval) = FunctionAddress[~ClassWithDestructor] : -# 2414| v2414_15(void) = Call[~ClassWithDestructor] : func:r2414_14, this:r2414_13 -# 2414| mu2414_16(unknown) = ^CallSideEffect : ~m? -# 2414| v2414_17(void) = ^IndirectReadSideEffect[-1] : &:r2414_13, ~m? -# 2414| mu2414_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2414_13 -# 2414| mu2414_19(char) = Store[x] : &:r2414_1, r2414_9 -# 2414| r2414_20(glval) = VariableAddress[x] : -# 2414| r2414_21(char) = Load[x] : &:r2414_20, ~m? -# 2414| r2414_22(char) = Constant[0] : -# 2414| r2414_23(bool) = CompareNE : r2414_21, r2414_22 -# 2414| v2414_24(void) = ConditionalBranch : r2414_23 +# 2415| Block 2 +# 2415| r2415_1(glval) = VariableAddress[x] : +# 2415| r2415_2(glval) = VariableAddress[#temp2415:18] : +# 2415| mu2415_3(ClassWithDestructor) = Uninitialized[#temp2415:18] : &:r2415_2 +# 2415| r2415_4(glval) = FunctionAddress[ClassWithDestructor] : +# 2415| v2415_5(void) = Call[ClassWithDestructor] : func:r2415_4, this:r2415_2 +# 2415| mu2415_6(unknown) = ^CallSideEffect : ~m? +# 2415| mu2415_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2415_2 +# 2415| r2415_8(glval) = FunctionAddress[get_x] : +# 2415| r2415_9(char) = Call[get_x] : func:r2415_8, this:r2415_2 +# 2415| mu2415_10(unknown) = ^CallSideEffect : ~m? +# 2415| v2415_11(void) = ^IndirectReadSideEffect[-1] : &:r2415_2, ~m? +# 2415| mu2415_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2415_2 +# 2415| r2415_13(glval) = CopyValue : r2415_2 +# 2415| r2415_14(glval) = FunctionAddress[~ClassWithDestructor] : +# 2415| v2415_15(void) = Call[~ClassWithDestructor] : func:r2415_14, this:r2415_13 +# 2415| mu2415_16(unknown) = ^CallSideEffect : ~m? +# 2415| v2415_17(void) = ^IndirectReadSideEffect[-1] : &:r2415_13, ~m? +# 2415| mu2415_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2415_13 +# 2415| mu2415_19(char) = Store[x] : &:r2415_1, r2415_9 +# 2415| r2415_20(glval) = VariableAddress[x] : +# 2415| r2415_21(char) = Load[x] : &:r2415_20, ~m? +# 2415| r2415_22(char) = Constant[0] : +# 2415| r2415_23(bool) = CompareNE : r2415_21, r2415_22 +# 2415| v2415_24(void) = ConditionalBranch : r2415_23 #-----| False -> Block 4 #-----| True -> Block 3 -# 2415| Block 3 -# 2415| r2415_1(glval) = VariableAddress[x] : -# 2415| r2415_2(char) = Load[x] : &:r2415_1, ~m? -# 2415| r2415_3(char) = Constant[1] : -# 2415| r2415_4(char) = Add : r2415_2, r2415_3 -# 2415| mu2415_5(char) = Store[x] : &:r2415_1, r2415_4 +# 2416| Block 3 +# 2416| r2416_1(glval) = VariableAddress[x] : +# 2416| r2416_2(char) = Load[x] : &:r2416_1, ~m? +# 2416| r2416_3(char) = Constant[1] : +# 2416| r2416_4(char) = Add : r2416_2, r2416_3 +# 2416| mu2416_5(char) = Store[x] : &:r2416_1, r2416_4 #-----| Goto -> Block 4 -# 2417| Block 4 -# 2417| r2417_1(glval) = VariableAddress[x] : -# 2417| r2417_2(glval) = VariableAddress[#temp2417:28] : -# 2417| mu2417_3(ClassWithDestructor) = Uninitialized[#temp2417:28] : &:r2417_2 -# 2417| r2417_4(glval) = FunctionAddress[ClassWithDestructor] : -# 2417| v2417_5(void) = Call[ClassWithDestructor] : func:r2417_4, this:r2417_2 -# 2417| mu2417_6(unknown) = ^CallSideEffect : ~m? -# 2417| mu2417_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2417_2 -# 2417| r2417_8(glval) = FunctionAddress[get_x] : -# 2417| r2417_9(char) = Call[get_x] : func:r2417_8, this:r2417_2 -# 2417| mu2417_10(unknown) = ^CallSideEffect : ~m? -# 2417| v2417_11(void) = ^IndirectReadSideEffect[-1] : &:r2417_2, ~m? -# 2417| mu2417_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2417_2 -# 2417| r2417_13(glval) = CopyValue : r2417_2 -# 2417| r2417_14(glval) = FunctionAddress[~ClassWithDestructor] : -# 2417| v2417_15(void) = Call[~ClassWithDestructor] : func:r2417_14, this:r2417_13 -# 2417| mu2417_16(unknown) = ^CallSideEffect : ~m? -# 2417| v2417_17(void) = ^IndirectReadSideEffect[-1] : &:r2417_13, ~m? -# 2417| mu2417_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2417_13 -# 2417| mu2417_19(char) = Store[x] : &:r2417_1, r2417_9 -# 2417| r2417_20(bool) = Constant[1] : -# 2417| v2417_21(void) = ConditionalBranch : r2417_20 +# 2418| Block 4 +# 2418| r2418_1(glval) = VariableAddress[x] : +# 2418| r2418_2(glval) = VariableAddress[#temp2418:28] : +# 2418| mu2418_3(ClassWithDestructor) = Uninitialized[#temp2418:28] : &:r2418_2 +# 2418| r2418_4(glval) = FunctionAddress[ClassWithDestructor] : +# 2418| v2418_5(void) = Call[ClassWithDestructor] : func:r2418_4, this:r2418_2 +# 2418| mu2418_6(unknown) = ^CallSideEffect : ~m? +# 2418| mu2418_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2418_2 +# 2418| r2418_8(glval) = FunctionAddress[get_x] : +# 2418| r2418_9(char) = Call[get_x] : func:r2418_8, this:r2418_2 +# 2418| mu2418_10(unknown) = ^CallSideEffect : ~m? +# 2418| v2418_11(void) = ^IndirectReadSideEffect[-1] : &:r2418_2, ~m? +# 2418| mu2418_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2418_2 +# 2418| r2418_13(glval) = CopyValue : r2418_2 +# 2418| r2418_14(glval) = FunctionAddress[~ClassWithDestructor] : +# 2418| v2418_15(void) = Call[~ClassWithDestructor] : func:r2418_14, this:r2418_13 +# 2418| mu2418_16(unknown) = ^CallSideEffect : ~m? +# 2418| v2418_17(void) = ^IndirectReadSideEffect[-1] : &:r2418_13, ~m? +# 2418| mu2418_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2418_13 +# 2418| mu2418_19(char) = Store[x] : &:r2418_1, r2418_9 +# 2418| r2418_20(bool) = Constant[1] : +# 2418| v2418_21(void) = ConditionalBranch : r2418_20 #-----| False -> Block 6 #-----| True -> Block 5 -# 2418| Block 5 -# 2418| r2418_1(glval) = VariableAddress[x] : -# 2418| r2418_2(char) = Load[x] : &:r2418_1, ~m? -# 2418| r2418_3(char) = Constant[1] : -# 2418| r2418_4(char) = Add : r2418_2, r2418_3 -# 2418| mu2418_5(char) = Store[x] : &:r2418_1, r2418_4 +# 2419| Block 5 +# 2419| r2419_1(glval) = VariableAddress[x] : +# 2419| r2419_2(char) = Load[x] : &:r2419_1, ~m? +# 2419| r2419_3(char) = Constant[1] : +# 2419| r2419_4(char) = Add : r2419_2, r2419_3 +# 2419| mu2419_5(char) = Store[x] : &:r2419_1, r2419_4 #-----| Goto -> Block 6 -# 2420| Block 6 -# 2420| r2420_1(glval) = VariableAddress[x] : -# 2420| r2420_2(glval) = VariableAddress[#temp2420:21] : -# 2420| mu2420_3(ClassWithDestructor) = Uninitialized[#temp2420:21] : &:r2420_2 -# 2420| r2420_4(glval) = FunctionAddress[ClassWithDestructor] : -# 2420| v2420_5(void) = Call[ClassWithDestructor] : func:r2420_4, this:r2420_2 -# 2420| mu2420_6(unknown) = ^CallSideEffect : ~m? -# 2420| mu2420_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2420_2 -# 2420| r2420_8(glval) = FunctionAddress[get_x] : -# 2420| r2420_9(char) = Call[get_x] : func:r2420_8, this:r2420_2 -# 2420| mu2420_10(unknown) = ^CallSideEffect : ~m? -# 2420| v2420_11(void) = ^IndirectReadSideEffect[-1] : &:r2420_2, ~m? -# 2420| mu2420_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2420_2 -# 2420| r2420_13(glval) = CopyValue : r2420_2 -# 2420| r2420_14(glval) = FunctionAddress[~ClassWithDestructor] : -# 2420| v2420_15(void) = Call[~ClassWithDestructor] : func:r2420_14, this:r2420_13 -# 2420| mu2420_16(unknown) = ^CallSideEffect : ~m? -# 2420| v2420_17(void) = ^IndirectReadSideEffect[-1] : &:r2420_13, ~m? -# 2420| mu2420_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2420_13 -# 2420| mu2420_19(char) = Store[x] : &:r2420_1, r2420_9 -# 2420| r2420_20(glval) = VariableAddress[x] : -# 2420| r2420_21(char) = Load[x] : &:r2420_20, ~m? -# 2420| r2420_22(int) = Convert : r2420_21 -# 2420| r2420_23(int) = CopyValue : r2420_22 -# 2420| v2420_24(void) = Switch : r2420_23 +# 2421| Block 6 +# 2421| r2421_1(glval) = VariableAddress[x] : +# 2421| r2421_2(glval) = VariableAddress[#temp2421:21] : +# 2421| mu2421_3(ClassWithDestructor) = Uninitialized[#temp2421:21] : &:r2421_2 +# 2421| r2421_4(glval) = FunctionAddress[ClassWithDestructor] : +# 2421| v2421_5(void) = Call[ClassWithDestructor] : func:r2421_4, this:r2421_2 +# 2421| mu2421_6(unknown) = ^CallSideEffect : ~m? +# 2421| mu2421_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2421_2 +# 2421| r2421_8(glval) = FunctionAddress[get_x] : +# 2421| r2421_9(char) = Call[get_x] : func:r2421_8, this:r2421_2 +# 2421| mu2421_10(unknown) = ^CallSideEffect : ~m? +# 2421| v2421_11(void) = ^IndirectReadSideEffect[-1] : &:r2421_2, ~m? +# 2421| mu2421_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2421_2 +# 2421| r2421_13(glval) = CopyValue : r2421_2 +# 2421| r2421_14(glval) = FunctionAddress[~ClassWithDestructor] : +# 2421| v2421_15(void) = Call[~ClassWithDestructor] : func:r2421_14, this:r2421_13 +# 2421| mu2421_16(unknown) = ^CallSideEffect : ~m? +# 2421| v2421_17(void) = ^IndirectReadSideEffect[-1] : &:r2421_13, ~m? +# 2421| mu2421_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2421_13 +# 2421| mu2421_19(char) = Store[x] : &:r2421_1, r2421_9 +# 2421| r2421_20(glval) = VariableAddress[x] : +# 2421| r2421_21(char) = Load[x] : &:r2421_20, ~m? +# 2421| r2421_22(int) = Convert : r2421_21 +# 2421| r2421_23(int) = CopyValue : r2421_22 +# 2421| v2421_24(void) = Switch : r2421_23 #-----| Case[97] -> Block 7 #-----| Default -> Block 8 -# 2421| Block 7 -# 2421| v2421_1(void) = NoOp : -# 2422| r2422_1(glval) = VariableAddress[x] : -# 2422| r2422_2(char) = Load[x] : &:r2422_1, ~m? -# 2422| r2422_3(char) = Constant[1] : -# 2422| r2422_4(char) = Add : r2422_2, r2422_3 -# 2422| mu2422_5(char) = Store[x] : &:r2422_1, r2422_4 +# 2422| Block 7 +# 2422| v2422_1(void) = NoOp : +# 2423| r2423_1(glval) = VariableAddress[x] : +# 2423| r2423_2(char) = Load[x] : &:r2423_1, ~m? +# 2423| r2423_3(char) = Constant[1] : +# 2423| r2423_4(char) = Add : r2423_2, r2423_3 +# 2423| mu2423_5(char) = Store[x] : &:r2423_1, r2423_4 #-----| Goto -> Block 8 -# 2425| Block 8 -# 2425| r2425_1(glval) = VariableAddress[x] : -# 2425| r2425_2(glval) = VariableAddress[#temp2425:21] : -# 2425| mu2425_3(ClassWithDestructor) = Uninitialized[#temp2425:21] : &:r2425_2 -# 2425| r2425_4(glval) = FunctionAddress[ClassWithDestructor] : -# 2425| v2425_5(void) = Call[ClassWithDestructor] : func:r2425_4, this:r2425_2 -# 2425| mu2425_6(unknown) = ^CallSideEffect : ~m? -# 2425| mu2425_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2425_2 -# 2425| r2425_8(glval) = FunctionAddress[get_x] : -# 2425| r2425_9(char) = Call[get_x] : func:r2425_8, this:r2425_2 -# 2425| mu2425_10(unknown) = ^CallSideEffect : ~m? -# 2425| v2425_11(void) = ^IndirectReadSideEffect[-1] : &:r2425_2, ~m? -# 2425| mu2425_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2425_2 -# 2425| r2425_13(glval) = CopyValue : r2425_2 -# 2425| r2425_14(glval) = FunctionAddress[~ClassWithDestructor] : -# 2425| v2425_15(void) = Call[~ClassWithDestructor] : func:r2425_14, this:r2425_13 -# 2425| mu2425_16(unknown) = ^CallSideEffect : ~m? -# 2425| v2425_17(void) = ^IndirectReadSideEffect[-1] : &:r2425_13, ~m? -# 2425| mu2425_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2425_13 -# 2425| mu2425_19(char) = Store[x] : &:r2425_1, r2425_9 -# 2425| r2425_20(glval) = VariableAddress[x] : -# 2425| r2425_21(char) = Load[x] : &:r2425_20, ~m? -# 2425| r2425_22(int) = Convert : r2425_21 -# 2425| v2425_23(void) = Switch : r2425_22 +# 2426| Block 8 +# 2426| r2426_1(glval) = VariableAddress[x] : +# 2426| r2426_2(glval) = VariableAddress[#temp2426:21] : +# 2426| mu2426_3(ClassWithDestructor) = Uninitialized[#temp2426:21] : &:r2426_2 +# 2426| r2426_4(glval) = FunctionAddress[ClassWithDestructor] : +# 2426| v2426_5(void) = Call[ClassWithDestructor] : func:r2426_4, this:r2426_2 +# 2426| mu2426_6(unknown) = ^CallSideEffect : ~m? +# 2426| mu2426_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2426_2 +# 2426| r2426_8(glval) = FunctionAddress[get_x] : +# 2426| r2426_9(char) = Call[get_x] : func:r2426_8, this:r2426_2 +# 2426| mu2426_10(unknown) = ^CallSideEffect : ~m? +# 2426| v2426_11(void) = ^IndirectReadSideEffect[-1] : &:r2426_2, ~m? +# 2426| mu2426_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2426_2 +# 2426| r2426_13(glval) = CopyValue : r2426_2 +# 2426| r2426_14(glval) = FunctionAddress[~ClassWithDestructor] : +# 2426| v2426_15(void) = Call[~ClassWithDestructor] : func:r2426_14, this:r2426_13 +# 2426| mu2426_16(unknown) = ^CallSideEffect : ~m? +# 2426| v2426_17(void) = ^IndirectReadSideEffect[-1] : &:r2426_13, ~m? +# 2426| mu2426_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2426_13 +# 2426| mu2426_19(char) = Store[x] : &:r2426_1, r2426_9 +# 2426| r2426_20(glval) = VariableAddress[x] : +# 2426| r2426_21(char) = Load[x] : &:r2426_20, ~m? +# 2426| r2426_22(int) = Convert : r2426_21 +# 2426| v2426_23(void) = Switch : r2426_22 #-----| Case[97] -> Block 9 #-----| Default -> Block 10 -# 2426| Block 9 -# 2426| v2426_1(void) = NoOp : -# 2427| r2427_1(glval) = VariableAddress[x] : -# 2427| r2427_2(char) = Load[x] : &:r2427_1, ~m? -# 2427| r2427_3(char) = Constant[1] : -# 2427| r2427_4(char) = Add : r2427_2, r2427_3 -# 2427| mu2427_5(char) = Store[x] : &:r2427_1, r2427_4 +# 2427| Block 9 +# 2427| v2427_1(void) = NoOp : +# 2428| r2428_1(glval) = VariableAddress[x] : +# 2428| r2428_2(char) = Load[x] : &:r2428_1, ~m? +# 2428| r2428_3(char) = Constant[1] : +# 2428| r2428_4(char) = Add : r2428_2, r2428_3 +# 2428| mu2428_5(char) = Store[x] : &:r2428_1, r2428_4 #-----| Goto -> Block 10 -# 2430| Block 10 -# 2430| r2430_1(glval) = VariableAddress[x] : -# 2430| r2430_2(glval) = VariableAddress[#temp2430:18] : -# 2430| mu2430_3(ClassWithDestructor) = Uninitialized[#temp2430:18] : &:r2430_2 -# 2430| r2430_4(glval) = FunctionAddress[ClassWithDestructor] : -# 2430| v2430_5(void) = Call[ClassWithDestructor] : func:r2430_4, this:r2430_2 -# 2430| mu2430_6(unknown) = ^CallSideEffect : ~m? -# 2430| mu2430_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2430_2 -# 2430| r2430_8(glval) = FunctionAddress[get_x] : -# 2430| r2430_9(char) = Call[get_x] : func:r2430_8, this:r2430_2 -# 2430| mu2430_10(unknown) = ^CallSideEffect : ~m? -# 2430| v2430_11(void) = ^IndirectReadSideEffect[-1] : &:r2430_2, ~m? -# 2430| mu2430_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2430_2 -# 2430| r2430_13(glval) = CopyValue : r2430_2 -# 2430| r2430_14(glval) = FunctionAddress[~ClassWithDestructor] : -# 2430| v2430_15(void) = Call[~ClassWithDestructor] : func:r2430_14, this:r2430_13 -# 2430| mu2430_16(unknown) = ^CallSideEffect : ~m? -# 2430| v2430_17(void) = ^IndirectReadSideEffect[-1] : &:r2430_13, ~m? -# 2430| mu2430_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2430_13 -# 2430| mu2430_19(char) = Store[x] : &:r2430_1, r2430_9 -# 2430| r2430_20(glval &&>) = VariableAddress[(__range)] : -# 2430| r2430_21(glval>) = VariableAddress[#temp2430:58] : -# 2430| mu2430_22(vector) = Uninitialized[#temp2430:58] : &:r2430_21 -# 2430| r2430_23(glval) = FunctionAddress[vector] : -# 2430| r2430_24(glval) = VariableAddress[x] : -# 2430| r2430_25(char) = Load[x] : &:r2430_24, ~m? -# 2430| v2430_26(void) = Call[vector] : func:r2430_23, this:r2430_21, 0:r2430_25 -# 2430| mu2430_27(unknown) = ^CallSideEffect : ~m? -# 2430| mu2430_28(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2430_21 -# 2430| r2430_29(vector &) = CopyValue : r2430_21 -# 2430| mu2430_30(vector &&) = Store[(__range)] : &:r2430_20, r2430_29 -# 2430| r2430_31(glval>) = VariableAddress[(__begin)] : -# 2430| r2430_32(glval &&>) = VariableAddress[(__range)] : -# 2430| r2430_33(vector &&) = Load[(__range)] : &:r2430_32, ~m? -#-----| r0_1(glval>) = CopyValue : r2430_33 +# 2431| Block 10 +# 2431| r2431_1(glval) = VariableAddress[x] : +# 2431| r2431_2(glval) = VariableAddress[#temp2431:18] : +# 2431| mu2431_3(ClassWithDestructor) = Uninitialized[#temp2431:18] : &:r2431_2 +# 2431| r2431_4(glval) = FunctionAddress[ClassWithDestructor] : +# 2431| v2431_5(void) = Call[ClassWithDestructor] : func:r2431_4, this:r2431_2 +# 2431| mu2431_6(unknown) = ^CallSideEffect : ~m? +# 2431| mu2431_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2431_2 +# 2431| r2431_8(glval) = FunctionAddress[get_x] : +# 2431| r2431_9(char) = Call[get_x] : func:r2431_8, this:r2431_2 +# 2431| mu2431_10(unknown) = ^CallSideEffect : ~m? +# 2431| v2431_11(void) = ^IndirectReadSideEffect[-1] : &:r2431_2, ~m? +# 2431| mu2431_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2431_2 +# 2431| r2431_13(glval) = CopyValue : r2431_2 +# 2431| r2431_14(glval) = FunctionAddress[~ClassWithDestructor] : +# 2431| v2431_15(void) = Call[~ClassWithDestructor] : func:r2431_14, this:r2431_13 +# 2431| mu2431_16(unknown) = ^CallSideEffect : ~m? +# 2431| v2431_17(void) = ^IndirectReadSideEffect[-1] : &:r2431_13, ~m? +# 2431| mu2431_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2431_13 +# 2431| mu2431_19(char) = Store[x] : &:r2431_1, r2431_9 +# 2431| r2431_20(glval &&>) = VariableAddress[(__range)] : +# 2431| r2431_21(glval>) = VariableAddress[#temp2431:58] : +# 2431| mu2431_22(vector) = Uninitialized[#temp2431:58] : &:r2431_21 +# 2431| r2431_23(glval) = FunctionAddress[vector] : +# 2431| r2431_24(glval) = VariableAddress[x] : +# 2431| r2431_25(char) = Load[x] : &:r2431_24, ~m? +# 2431| v2431_26(void) = Call[vector] : func:r2431_23, this:r2431_21, 0:r2431_25 +# 2431| mu2431_27(unknown) = ^CallSideEffect : ~m? +# 2431| mu2431_28(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2431_21 +# 2431| r2431_29(vector &) = CopyValue : r2431_21 +# 2431| mu2431_30(vector &&) = Store[(__range)] : &:r2431_20, r2431_29 +# 2431| r2431_31(glval>) = VariableAddress[(__begin)] : +# 2431| r2431_32(glval &&>) = VariableAddress[(__range)] : +# 2431| r2431_33(vector &&) = Load[(__range)] : &:r2431_32, ~m? +#-----| r0_1(glval>) = CopyValue : r2431_33 #-----| r0_2(glval>) = Convert : r0_1 -# 2430| r2430_34(glval) = FunctionAddress[begin] : -# 2430| r2430_35(iterator) = Call[begin] : func:r2430_34, this:r0_2 +# 2431| r2431_34(glval) = FunctionAddress[begin] : +# 2431| r2431_35(iterator) = Call[begin] : func:r2431_34, this:r0_2 #-----| v0_3(void) = ^IndirectReadSideEffect[-1] : &:r0_2, ~m? -# 2430| mu2430_36(iterator) = Store[(__begin)] : &:r2430_31, r2430_35 -# 2430| r2430_37(glval>) = VariableAddress[(__end)] : -# 2430| r2430_38(glval &&>) = VariableAddress[(__range)] : -# 2430| r2430_39(vector &&) = Load[(__range)] : &:r2430_38, ~m? -#-----| r0_4(glval>) = CopyValue : r2430_39 +# 2431| mu2431_36(iterator) = Store[(__begin)] : &:r2431_31, r2431_35 +# 2431| r2431_37(glval>) = VariableAddress[(__end)] : +# 2431| r2431_38(glval &&>) = VariableAddress[(__range)] : +# 2431| r2431_39(vector &&) = Load[(__range)] : &:r2431_38, ~m? +#-----| r0_4(glval>) = CopyValue : r2431_39 #-----| r0_5(glval>) = Convert : r0_4 -# 2430| r2430_40(glval) = FunctionAddress[end] : -# 2430| r2430_41(iterator) = Call[end] : func:r2430_40, this:r0_5 +# 2431| r2431_40(glval) = FunctionAddress[end] : +# 2431| r2431_41(iterator) = Call[end] : func:r2431_40, this:r0_5 #-----| v0_6(void) = ^IndirectReadSideEffect[-1] : &:r0_5, ~m? -# 2430| mu2430_42(iterator) = Store[(__end)] : &:r2430_37, r2430_41 +# 2431| mu2431_42(iterator) = Store[(__end)] : &:r2431_37, r2431_41 #-----| Goto -> Block 11 -# 2430| Block 11 -# 2430| r2430_43(glval>) = VariableAddress[(__begin)] : -#-----| r0_7(glval>) = Convert : r2430_43 -# 2430| r2430_44(glval) = FunctionAddress[operator!=] : +# 2431| Block 11 +# 2431| r2431_43(glval>) = VariableAddress[(__begin)] : +#-----| r0_7(glval>) = Convert : r2431_43 +# 2431| r2431_44(glval) = FunctionAddress[operator!=] : #-----| r0_8(glval>) = VariableAddress[#temp0:0] : #-----| mu0_9(iterator) = Uninitialized[#temp0:0] : &:r0_8 -# 2430| r2430_45(glval) = FunctionAddress[iterator] : -# 2430| r2430_46(glval>) = VariableAddress[(__end)] : -#-----| r0_10(glval>) = Convert : r2430_46 +# 2431| r2431_45(glval) = FunctionAddress[iterator] : +# 2431| r2431_46(glval>) = VariableAddress[(__end)] : +#-----| r0_10(glval>) = Convert : r2431_46 #-----| r0_11(iterator &) = CopyValue : r0_10 -# 2430| v2430_47(void) = Call[iterator] : func:r2430_45, this:r0_8, 0:r0_11 -# 2430| mu2430_48(unknown) = ^CallSideEffect : ~m? +# 2431| v2431_47(void) = Call[iterator] : func:r2431_45, this:r0_8, 0:r0_11 +# 2431| mu2431_48(unknown) = ^CallSideEffect : ~m? #-----| v0_12(void) = ^BufferReadSideEffect[0] : &:r0_11, ~m? -# 2430| mu2430_49(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_8 +# 2431| mu2431_49(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r0_8 #-----| r0_13(iterator) = Load[#temp0:0] : &:r0_8, ~m? -# 2430| r2430_50(bool) = Call[operator!=] : func:r2430_44, this:r0_7, 0:r0_13 +# 2431| r2431_50(bool) = Call[operator!=] : func:r2431_44, this:r0_7, 0:r0_13 #-----| v0_14(void) = ^IndirectReadSideEffect[-1] : &:r0_7, ~m? -# 2430| v2430_51(void) = ConditionalBranch : r2430_50 +# 2431| v2431_51(void) = ConditionalBranch : r2431_50 #-----| False -> Block 13 #-----| True -> Block 12 -# 2430| Block 12 -# 2430| r2430_52(glval) = VariableAddress[y] : -# 2430| r2430_53(glval>) = VariableAddress[(__begin)] : -#-----| r0_15(glval>) = Convert : r2430_53 -# 2430| r2430_54(glval) = FunctionAddress[operator*] : -# 2430| r2430_55(char &) = Call[operator*] : func:r2430_54, this:r0_15 +# 2431| Block 12 +# 2431| r2431_52(glval) = VariableAddress[y] : +# 2431| r2431_53(glval>) = VariableAddress[(__begin)] : +#-----| r0_15(glval>) = Convert : r2431_53 +# 2431| r2431_54(glval) = FunctionAddress[operator*] : +# 2431| r2431_55(char &) = Call[operator*] : func:r2431_54, this:r0_15 #-----| v0_16(void) = ^IndirectReadSideEffect[-1] : &:r0_15, ~m? -# 2430| r2430_56(char) = Load[?] : &:r2430_55, ~m? -# 2430| mu2430_57(char) = Store[y] : &:r2430_52, r2430_56 -# 2431| r2431_1(glval) = VariableAddress[x] : -# 2431| r2431_2(char) = Load[x] : &:r2431_1, ~m? -# 2431| r2431_3(int) = Convert : r2431_2 -# 2431| r2431_4(glval) = VariableAddress[y] : -# 2431| r2431_5(char) = Load[y] : &:r2431_4, ~m? -# 2431| r2431_6(int) = Convert : r2431_5 -# 2431| r2431_7(int) = Add : r2431_6, r2431_3 -# 2431| r2431_8(char) = Convert : r2431_7 -# 2431| mu2431_9(char) = Store[y] : &:r2431_4, r2431_8 -# 2430| r2430_58(glval>) = VariableAddress[(__begin)] : -# 2430| r2430_59(glval) = FunctionAddress[operator++] : -# 2430| r2430_60(iterator &) = Call[operator++] : func:r2430_59, this:r2430_58 -# 2430| v2430_61(void) = ^IndirectReadSideEffect[-1] : &:r2430_58, ~m? -# 2430| mu2430_62(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2430_58 -# 2430| r2430_63(glval>) = CopyValue : r2430_60 +# 2431| r2431_56(char) = Load[?] : &:r2431_55, ~m? +# 2431| mu2431_57(char) = Store[y] : &:r2431_52, r2431_56 +# 2432| r2432_1(glval) = VariableAddress[x] : +# 2432| r2432_2(char) = Load[x] : &:r2432_1, ~m? +# 2432| r2432_3(int) = Convert : r2432_2 +# 2432| r2432_4(glval) = VariableAddress[y] : +# 2432| r2432_5(char) = Load[y] : &:r2432_4, ~m? +# 2432| r2432_6(int) = Convert : r2432_5 +# 2432| r2432_7(int) = Add : r2432_6, r2432_3 +# 2432| r2432_8(char) = Convert : r2432_7 +# 2432| mu2432_9(char) = Store[y] : &:r2432_4, r2432_8 +# 2431| r2431_58(glval>) = VariableAddress[(__begin)] : +# 2431| r2431_59(glval) = FunctionAddress[operator++] : +# 2431| r2431_60(iterator &) = Call[operator++] : func:r2431_59, this:r2431_58 +# 2431| v2431_61(void) = ^IndirectReadSideEffect[-1] : &:r2431_58, ~m? +# 2431| mu2431_62(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2431_58 +# 2431| r2431_63(glval>) = CopyValue : r2431_60 #-----| Goto (back edge) -> Block 11 -# 2430| Block 13 -# 2430| r2430_64(glval>) = CopyValue : r2430_21 -# 2430| r2430_65(glval) = FunctionAddress[~vector] : -# 2430| v2430_66(void) = Call[~vector] : func:r2430_65, this:r2430_64 -# 2430| mu2430_67(unknown) = ^CallSideEffect : ~m? -# 2430| v2430_68(void) = ^IndirectReadSideEffect[-1] : &:r2430_64, ~m? -# 2430| mu2430_69(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2430_64 -# 2432| v2432_1(void) = NoOp : -# 2410| v2410_4(void) = ReturnVoid : -# 2410| v2410_5(void) = AliasedUse : ~m? -# 2410| v2410_6(void) = ExitFunction : - -# 2434| void param_with_destructor_by_value(ClassWithDestructor) -# 2434| Block 0 -# 2434| v2434_1(void) = EnterFunction : -# 2434| mu2434_2(unknown) = AliasedDefinition : -# 2434| mu2434_3(unknown) = InitializeNonLocal : -# 2434| r2434_4(glval) = VariableAddress[c] : -# 2434| mu2434_5(ClassWithDestructor) = InitializeParameter[c] : &:r2434_4 -# 2436| v2436_1(void) = NoOp : -# 2434| v2434_6(void) = ReturnVoid : -# 2434| v2434_7(void) = AliasedUse : ~m? -# 2434| v2434_8(void) = ExitFunction : - -# 2438| void param_with_destructor_by_pointer(ClassWithDestructor*) -# 2438| Block 0 -# 2438| v2438_1(void) = EnterFunction : -# 2438| mu2438_2(unknown) = AliasedDefinition : -# 2438| mu2438_3(unknown) = InitializeNonLocal : -# 2438| r2438_4(glval) = VariableAddress[c] : -# 2438| mu2438_5(ClassWithDestructor *) = InitializeParameter[c] : &:r2438_4 -# 2438| r2438_6(ClassWithDestructor *) = Load[c] : &:r2438_4, ~m? -# 2438| mu2438_7(unknown) = InitializeIndirection[c] : &:r2438_6 -# 2440| v2440_1(void) = NoOp : -# 2438| v2438_8(void) = ReturnIndirection[c] : &:r2438_6, ~m? -# 2438| v2438_9(void) = ReturnVoid : -# 2438| v2438_10(void) = AliasedUse : ~m? -# 2438| v2438_11(void) = ExitFunction : - -# 2442| void param_with_destructor_by_ref(ClassWithDestructor&) -# 2442| Block 0 -# 2442| v2442_1(void) = EnterFunction : -# 2442| mu2442_2(unknown) = AliasedDefinition : -# 2442| mu2442_3(unknown) = InitializeNonLocal : -# 2442| r2442_4(glval) = VariableAddress[c] : -# 2442| mu2442_5(ClassWithDestructor &) = InitializeParameter[c] : &:r2442_4 -# 2442| r2442_6(ClassWithDestructor &) = Load[c] : &:r2442_4, ~m? -# 2442| mu2442_7(unknown) = InitializeIndirection[c] : &:r2442_6 -# 2444| v2444_1(void) = NoOp : -# 2442| v2442_8(void) = ReturnIndirection[c] : &:r2442_6, ~m? -# 2442| v2442_9(void) = ReturnVoid : -# 2442| v2442_10(void) = AliasedUse : ~m? -# 2442| v2442_11(void) = ExitFunction : - -# 2446| void param_with_destructor_by_rref(ClassWithDestructor&&) -# 2446| Block 0 -# 2446| v2446_1(void) = EnterFunction : -# 2446| mu2446_2(unknown) = AliasedDefinition : -# 2446| mu2446_3(unknown) = InitializeNonLocal : -# 2446| r2446_4(glval) = VariableAddress[c] : -# 2446| mu2446_5(ClassWithDestructor &&) = InitializeParameter[c] : &:r2446_4 -# 2446| r2446_6(ClassWithDestructor &&) = Load[c] : &:r2446_4, ~m? -# 2446| mu2446_7(unknown) = InitializeIndirection[c] : &:r2446_6 -# 2448| v2448_1(void) = NoOp : -# 2446| v2446_8(void) = ReturnIndirection[c] : &:r2446_6, ~m? -# 2446| v2446_9(void) = ReturnVoid : -# 2446| v2446_10(void) = AliasedUse : ~m? -# 2446| v2446_11(void) = ExitFunction : - -# 2450| void rethrow_with_destruction(int) -# 2450| Block 0 -# 2450| v2450_1(void) = EnterFunction : -# 2450| mu2450_2(unknown) = AliasedDefinition : -# 2450| mu2450_3(unknown) = InitializeNonLocal : -# 2450| r2450_4(glval) = VariableAddress[x] : -# 2450| mu2450_5(int) = InitializeParameter[x] : &:r2450_4 -# 2451| r2451_1(glval) = VariableAddress[c] : -# 2451| mu2451_2(ClassWithDestructor) = Uninitialized[c] : &:r2451_1 -# 2451| r2451_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2451| v2451_4(void) = Call[ClassWithDestructor] : func:r2451_3, this:r2451_1 -# 2451| mu2451_5(unknown) = ^CallSideEffect : ~m? -# 2451| mu2451_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2451_1 -# 2452| v2452_1(void) = ReThrow : -# 2453| r2453_1(glval) = VariableAddress[c] : -# 2453| r2453_2(glval) = FunctionAddress[~ClassWithDestructor] : -# 2453| v2453_3(void) = Call[~ClassWithDestructor] : func:r2453_2, this:r2453_1 -# 2453| mu2453_4(unknown) = ^CallSideEffect : ~m? -# 2453| v2453_5(void) = ^IndirectReadSideEffect[-1] : &:r2453_1, ~m? -# 2453| mu2453_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2453_1 +# 2431| Block 13 +# 2431| r2431_64(glval>) = CopyValue : r2431_21 +# 2431| r2431_65(glval) = FunctionAddress[~vector] : +# 2431| v2431_66(void) = Call[~vector] : func:r2431_65, this:r2431_64 +# 2431| mu2431_67(unknown) = ^CallSideEffect : ~m? +# 2431| v2431_68(void) = ^IndirectReadSideEffect[-1] : &:r2431_64, ~m? +# 2431| mu2431_69(vector) = ^IndirectMayWriteSideEffect[-1] : &:r2431_64 +# 2433| v2433_1(void) = NoOp : +# 2411| v2411_4(void) = ReturnVoid : +# 2411| v2411_5(void) = AliasedUse : ~m? +# 2411| v2411_6(void) = ExitFunction : + +# 2435| void param_with_destructor_by_value(ClassWithDestructor) +# 2435| Block 0 +# 2435| v2435_1(void) = EnterFunction : +# 2435| mu2435_2(unknown) = AliasedDefinition : +# 2435| mu2435_3(unknown) = InitializeNonLocal : +# 2435| r2435_4(glval) = VariableAddress[c] : +# 2435| mu2435_5(ClassWithDestructor) = InitializeParameter[c] : &:r2435_4 +# 2437| v2437_1(void) = NoOp : +# 2435| v2435_6(void) = ReturnVoid : +# 2435| v2435_7(void) = AliasedUse : ~m? +# 2435| v2435_8(void) = ExitFunction : + +# 2439| void param_with_destructor_by_pointer(ClassWithDestructor*) +# 2439| Block 0 +# 2439| v2439_1(void) = EnterFunction : +# 2439| mu2439_2(unknown) = AliasedDefinition : +# 2439| mu2439_3(unknown) = InitializeNonLocal : +# 2439| r2439_4(glval) = VariableAddress[c] : +# 2439| mu2439_5(ClassWithDestructor *) = InitializeParameter[c] : &:r2439_4 +# 2439| r2439_6(ClassWithDestructor *) = Load[c] : &:r2439_4, ~m? +# 2439| mu2439_7(unknown) = InitializeIndirection[c] : &:r2439_6 +# 2441| v2441_1(void) = NoOp : +# 2439| v2439_8(void) = ReturnIndirection[c] : &:r2439_6, ~m? +# 2439| v2439_9(void) = ReturnVoid : +# 2439| v2439_10(void) = AliasedUse : ~m? +# 2439| v2439_11(void) = ExitFunction : + +# 2443| void param_with_destructor_by_ref(ClassWithDestructor&) +# 2443| Block 0 +# 2443| v2443_1(void) = EnterFunction : +# 2443| mu2443_2(unknown) = AliasedDefinition : +# 2443| mu2443_3(unknown) = InitializeNonLocal : +# 2443| r2443_4(glval) = VariableAddress[c] : +# 2443| mu2443_5(ClassWithDestructor &) = InitializeParameter[c] : &:r2443_4 +# 2443| r2443_6(ClassWithDestructor &) = Load[c] : &:r2443_4, ~m? +# 2443| mu2443_7(unknown) = InitializeIndirection[c] : &:r2443_6 +# 2445| v2445_1(void) = NoOp : +# 2443| v2443_8(void) = ReturnIndirection[c] : &:r2443_6, ~m? +# 2443| v2443_9(void) = ReturnVoid : +# 2443| v2443_10(void) = AliasedUse : ~m? +# 2443| v2443_11(void) = ExitFunction : + +# 2447| void param_with_destructor_by_rref(ClassWithDestructor&&) +# 2447| Block 0 +# 2447| v2447_1(void) = EnterFunction : +# 2447| mu2447_2(unknown) = AliasedDefinition : +# 2447| mu2447_3(unknown) = InitializeNonLocal : +# 2447| r2447_4(glval) = VariableAddress[c] : +# 2447| mu2447_5(ClassWithDestructor &&) = InitializeParameter[c] : &:r2447_4 +# 2447| r2447_6(ClassWithDestructor &&) = Load[c] : &:r2447_4, ~m? +# 2447| mu2447_7(unknown) = InitializeIndirection[c] : &:r2447_6 +# 2449| v2449_1(void) = NoOp : +# 2447| v2447_8(void) = ReturnIndirection[c] : &:r2447_6, ~m? +# 2447| v2447_9(void) = ReturnVoid : +# 2447| v2447_10(void) = AliasedUse : ~m? +# 2447| v2447_11(void) = ExitFunction : + +# 2451| void rethrow_with_destruction(int) +# 2451| Block 0 +# 2451| v2451_1(void) = EnterFunction : +# 2451| mu2451_2(unknown) = AliasedDefinition : +# 2451| mu2451_3(unknown) = InitializeNonLocal : +# 2451| r2451_4(glval) = VariableAddress[x] : +# 2451| mu2451_5(int) = InitializeParameter[x] : &:r2451_4 +# 2452| r2452_1(glval) = VariableAddress[c] : +# 2452| mu2452_2(ClassWithDestructor) = Uninitialized[c] : &:r2452_1 +# 2452| r2452_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2452| v2452_4(void) = Call[ClassWithDestructor] : func:r2452_3, this:r2452_1 +# 2452| mu2452_5(unknown) = ^CallSideEffect : ~m? +# 2452| mu2452_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2452_1 +# 2453| v2453_1(void) = ReThrow : +# 2454| r2454_1(glval) = VariableAddress[c] : +# 2454| r2454_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2454| v2454_3(void) = Call[~ClassWithDestructor] : func:r2454_2, this:r2454_1 +# 2454| mu2454_4(unknown) = ^CallSideEffect : ~m? +# 2454| v2454_5(void) = ^IndirectReadSideEffect[-1] : &:r2454_1, ~m? +# 2454| mu2454_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2454_1 #-----| Exception -> Block 3 -# 2450| Block 1 -# 2450| v2450_6(void) = AliasedUse : ~m? -# 2450| v2450_7(void) = ExitFunction : +# 2451| Block 1 +# 2451| v2451_6(void) = AliasedUse : ~m? +# 2451| v2451_7(void) = ExitFunction : -# 2450| Block 2 -# 2450| v2450_8(void) = ReturnVoid : +# 2451| Block 2 +# 2451| v2451_8(void) = ReturnVoid : #-----| Goto -> Block 1 -# 2450| Block 3 -# 2450| v2450_9(void) = Unwind : +# 2451| Block 3 +# 2451| v2451_9(void) = Unwind : #-----| Goto -> Block 1 -# 2459| void new_with_destructor(ClassWithDestructor) -# 2459| Block 0 -# 2459| v2459_1(void) = EnterFunction : -# 2459| mu2459_2(unknown) = AliasedDefinition : -# 2459| mu2459_3(unknown) = InitializeNonLocal : -# 2459| r2459_4(glval) = VariableAddress[a] : -# 2459| mu2459_5(ClassWithDestructor) = InitializeParameter[a] : &:r2459_4 -# 2461| r2461_1(glval) = VariableAddress[b] : -# 2461| r2461_2(glval) = FunctionAddress[operator new] : -# 2461| r2461_3(unsigned long) = Constant[1] : -# 2461| r2461_4(void *) = Call[operator new] : func:r2461_2, 0:r2461_3 -# 2461| mu2461_5(unknown) = ^CallSideEffect : ~m? -# 2461| mu2461_6(unknown) = ^InitializeDynamicAllocation : &:r2461_4 -# 2461| r2461_7(ByValueConstructor *) = Convert : r2461_4 -# 2461| r2461_8(glval) = FunctionAddress[ByValueConstructor] : -# 2461| r2461_9(glval) = VariableAddress[#temp2461:52] : -# 2461| r2461_10(glval) = VariableAddress[a] : -# 2461| r2461_11(ClassWithDestructor) = Load[a] : &:r2461_10, ~m? -# 2461| mu2461_12(ClassWithDestructor) = Store[#temp2461:52] : &:r2461_9, r2461_11 -# 2461| r2461_13(ClassWithDestructor) = Load[#temp2461:52] : &:r2461_9, ~m? -# 2461| v2461_14(void) = Call[ByValueConstructor] : func:r2461_8, this:r2461_7, 0:r2461_13 -# 2461| mu2461_15(unknown) = ^CallSideEffect : ~m? -# 2461| mu2461_16(ByValueConstructor) = ^IndirectMayWriteSideEffect[-1] : &:r2461_7 -# 2461| r2461_17(glval) = CopyValue : r2461_9 -# 2461| r2461_18(glval) = FunctionAddress[~ClassWithDestructor] : -# 2461| v2461_19(void) = Call[~ClassWithDestructor] : func:r2461_18, this:r2461_17 -# 2461| mu2461_20(unknown) = ^CallSideEffect : ~m? -# 2461| v2461_21(void) = ^IndirectReadSideEffect[-1] : &:r2461_17, ~m? -# 2461| mu2461_22(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2461_17 -# 2461| mu2461_23(ByValueConstructor *) = Store[b] : &:r2461_1, r2461_7 -# 2462| v2462_1(void) = NoOp : -# 2459| v2459_6(void) = ReturnVoid : -# 2459| v2459_7(void) = AliasedUse : ~m? -# 2459| v2459_8(void) = ExitFunction : - -# 2478| void rvalue_conversion_with_destructor::test() -# 2478| Block 0 -# 2478| v2478_1(void) = EnterFunction : -# 2478| mu2478_2(unknown) = AliasedDefinition : -# 2478| mu2478_3(unknown) = InitializeNonLocal : -# 2480| r2480_1(glval) = VariableAddress[a] : -# 2480| r2480_2(glval) = VariableAddress[#temp2480:18] : -# 2480| r2480_3(glval) = FunctionAddress[get] : -# 2480| r2480_4(B) = Call[get] : func:r2480_3 -# 2480| mu2480_5(unknown) = ^CallSideEffect : ~m? -# 2480| mu2480_6(B) = Store[#temp2480:18] : &:r2480_2, r2480_4 -# 2480| r2480_7(glval) = Convert : r2480_2 -# 2480| r2480_8(glval) = FunctionAddress[operator->] : -# 2480| r2480_9(A *) = Call[operator->] : func:r2480_8, this:r2480_7 -# 2480| mu2480_10(unknown) = ^CallSideEffect : ~m? -# 2480| v2480_11(void) = ^IndirectReadSideEffect[-1] : &:r2480_7, ~m? -# 2480| r2480_12(glval) = FieldAddress[a] : r2480_9 -# 2480| r2480_13(glval) = CopyValue : r2480_2 -# 2480| r2480_14(glval) = FunctionAddress[~B] : -# 2480| v2480_15(void) = Call[~B] : func:r2480_14, this:r2480_13 -# 2480| mu2480_16(unknown) = ^CallSideEffect : ~m? -# 2480| v2480_17(void) = ^IndirectReadSideEffect[-1] : &:r2480_13, ~m? -# 2480| mu2480_18(B) = ^IndirectMayWriteSideEffect[-1] : &:r2480_13 -# 2480| r2480_19(unsigned int) = Load[?] : &:r2480_12, ~m? -# 2480| mu2480_20(unsigned int) = Store[a] : &:r2480_1, r2480_19 -# 2481| v2481_1(void) = NoOp : -# 2478| v2478_4(void) = ReturnVoid : -# 2478| v2478_5(void) = AliasedUse : ~m? -# 2478| v2478_6(void) = ExitFunction : - -# 2484| void destructor_without_block(bool) -# 2484| Block 0 -# 2484| v2484_1(void) = EnterFunction : -# 2484| mu2484_2(unknown) = AliasedDefinition : -# 2484| mu2484_3(unknown) = InitializeNonLocal : -# 2484| r2484_4(glval) = VariableAddress[b] : -# 2484| mu2484_5(bool) = InitializeParameter[b] : &:r2484_4 -# 2486| r2486_1(glval) = VariableAddress[b] : -# 2486| r2486_2(bool) = Load[b] : &:r2486_1, ~m? -# 2486| v2486_3(void) = ConditionalBranch : r2486_2 +# 2460| void new_with_destructor(ClassWithDestructor) +# 2460| Block 0 +# 2460| v2460_1(void) = EnterFunction : +# 2460| mu2460_2(unknown) = AliasedDefinition : +# 2460| mu2460_3(unknown) = InitializeNonLocal : +# 2460| r2460_4(glval) = VariableAddress[a] : +# 2460| mu2460_5(ClassWithDestructor) = InitializeParameter[a] : &:r2460_4 +# 2462| r2462_1(glval) = VariableAddress[b] : +# 2462| r2462_2(glval) = FunctionAddress[operator new] : +# 2462| r2462_3(unsigned long) = Constant[1] : +# 2462| r2462_4(void *) = Call[operator new] : func:r2462_2, 0:r2462_3 +# 2462| mu2462_5(unknown) = ^CallSideEffect : ~m? +# 2462| mu2462_6(unknown) = ^InitializeDynamicAllocation : &:r2462_4 +# 2462| r2462_7(ByValueConstructor *) = Convert : r2462_4 +# 2462| r2462_8(glval) = FunctionAddress[ByValueConstructor] : +# 2462| r2462_9(glval) = VariableAddress[#temp2462:52] : +# 2462| r2462_10(glval) = VariableAddress[a] : +# 2462| r2462_11(ClassWithDestructor) = Load[a] : &:r2462_10, ~m? +# 2462| mu2462_12(ClassWithDestructor) = Store[#temp2462:52] : &:r2462_9, r2462_11 +# 2462| r2462_13(ClassWithDestructor) = Load[#temp2462:52] : &:r2462_9, ~m? +# 2462| v2462_14(void) = Call[ByValueConstructor] : func:r2462_8, this:r2462_7, 0:r2462_13 +# 2462| mu2462_15(unknown) = ^CallSideEffect : ~m? +# 2462| mu2462_16(ByValueConstructor) = ^IndirectMayWriteSideEffect[-1] : &:r2462_7 +# 2462| r2462_17(glval) = CopyValue : r2462_9 +# 2462| r2462_18(glval) = FunctionAddress[~ClassWithDestructor] : +# 2462| v2462_19(void) = Call[~ClassWithDestructor] : func:r2462_18, this:r2462_17 +# 2462| mu2462_20(unknown) = ^CallSideEffect : ~m? +# 2462| v2462_21(void) = ^IndirectReadSideEffect[-1] : &:r2462_17, ~m? +# 2462| mu2462_22(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2462_17 +# 2462| mu2462_23(ByValueConstructor *) = Store[b] : &:r2462_1, r2462_7 +# 2463| v2463_1(void) = NoOp : +# 2460| v2460_6(void) = ReturnVoid : +# 2460| v2460_7(void) = AliasedUse : ~m? +# 2460| v2460_8(void) = ExitFunction : + +# 2479| void rvalue_conversion_with_destructor::test() +# 2479| Block 0 +# 2479| v2479_1(void) = EnterFunction : +# 2479| mu2479_2(unknown) = AliasedDefinition : +# 2479| mu2479_3(unknown) = InitializeNonLocal : +# 2481| r2481_1(glval) = VariableAddress[a] : +# 2481| r2481_2(glval) = VariableAddress[#temp2481:18] : +# 2481| r2481_3(glval) = FunctionAddress[get] : +# 2481| r2481_4(B) = Call[get] : func:r2481_3 +# 2481| mu2481_5(unknown) = ^CallSideEffect : ~m? +# 2481| mu2481_6(B) = Store[#temp2481:18] : &:r2481_2, r2481_4 +# 2481| r2481_7(glval) = Convert : r2481_2 +# 2481| r2481_8(glval) = FunctionAddress[operator->] : +# 2481| r2481_9(A *) = Call[operator->] : func:r2481_8, this:r2481_7 +# 2481| mu2481_10(unknown) = ^CallSideEffect : ~m? +# 2481| v2481_11(void) = ^IndirectReadSideEffect[-1] : &:r2481_7, ~m? +# 2481| r2481_12(glval) = FieldAddress[a] : r2481_9 +# 2481| r2481_13(glval) = CopyValue : r2481_2 +# 2481| r2481_14(glval) = FunctionAddress[~B] : +# 2481| v2481_15(void) = Call[~B] : func:r2481_14, this:r2481_13 +# 2481| mu2481_16(unknown) = ^CallSideEffect : ~m? +# 2481| v2481_17(void) = ^IndirectReadSideEffect[-1] : &:r2481_13, ~m? +# 2481| mu2481_18(B) = ^IndirectMayWriteSideEffect[-1] : &:r2481_13 +# 2481| r2481_19(unsigned int) = Load[?] : &:r2481_12, ~m? +# 2481| mu2481_20(unsigned int) = Store[a] : &:r2481_1, r2481_19 +# 2482| v2482_1(void) = NoOp : +# 2479| v2479_4(void) = ReturnVoid : +# 2479| v2479_5(void) = AliasedUse : ~m? +# 2479| v2479_6(void) = ExitFunction : + +# 2485| void destructor_without_block(bool) +# 2485| Block 0 +# 2485| v2485_1(void) = EnterFunction : +# 2485| mu2485_2(unknown) = AliasedDefinition : +# 2485| mu2485_3(unknown) = InitializeNonLocal : +# 2485| r2485_4(glval) = VariableAddress[b] : +# 2485| mu2485_5(bool) = InitializeParameter[b] : &:r2485_4 +# 2487| r2487_1(glval) = VariableAddress[b] : +# 2487| r2487_2(bool) = Load[b] : &:r2487_1, ~m? +# 2487| v2487_3(void) = ConditionalBranch : r2487_2 #-----| False -> Block 2 #-----| True -> Block 1 -# 2487| Block 1 -# 2487| r2487_1(glval) = VariableAddress[c] : -# 2487| mu2487_2(ClassWithDestructor) = Uninitialized[c] : &:r2487_1 -# 2487| r2487_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2487| v2487_4(void) = Call[ClassWithDestructor] : func:r2487_3, this:r2487_1 -# 2487| mu2487_5(unknown) = ^CallSideEffect : ~m? -# 2487| mu2487_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2487_1 +# 2488| Block 1 +# 2488| r2488_1(glval) = VariableAddress[c] : +# 2488| mu2488_2(ClassWithDestructor) = Uninitialized[c] : &:r2488_1 +# 2488| r2488_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2488| v2488_4(void) = Call[ClassWithDestructor] : func:r2488_3, this:r2488_1 +# 2488| mu2488_5(unknown) = ^CallSideEffect : ~m? +# 2488| mu2488_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2488_1 #-----| r0_1(glval) = VariableAddress[c] : #-----| r0_2(glval) = FunctionAddress[~ClassWithDestructor] : #-----| v0_3(void) = Call[~ClassWithDestructor] : func:r0_2, this:r0_1 @@ -16284,20 +16284,20 @@ ir.cpp: #-----| mu0_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r0_1 #-----| Goto -> Block 2 -# 2489| Block 2 -# 2489| r2489_1(glval) = VariableAddress[b] : -# 2489| r2489_2(bool) = Load[b] : &:r2489_1, ~m? -# 2489| v2489_3(void) = ConditionalBranch : r2489_2 +# 2490| Block 2 +# 2490| r2490_1(glval) = VariableAddress[b] : +# 2490| r2490_2(bool) = Load[b] : &:r2490_1, ~m? +# 2490| v2490_3(void) = ConditionalBranch : r2490_2 #-----| False -> Block 4 #-----| True -> Block 3 -# 2490| Block 3 -# 2490| r2490_1(glval) = VariableAddress[d] : -# 2490| mu2490_2(ClassWithDestructor) = Uninitialized[d] : &:r2490_1 -# 2490| r2490_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2490| v2490_4(void) = Call[ClassWithDestructor] : func:r2490_3, this:r2490_1 -# 2490| mu2490_5(unknown) = ^CallSideEffect : ~m? -# 2490| mu2490_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2490_1 +# 2491| Block 3 +# 2491| r2491_1(glval) = VariableAddress[d] : +# 2491| mu2491_2(ClassWithDestructor) = Uninitialized[d] : &:r2491_1 +# 2491| r2491_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2491| v2491_4(void) = Call[ClassWithDestructor] : func:r2491_3, this:r2491_1 +# 2491| mu2491_5(unknown) = ^CallSideEffect : ~m? +# 2491| mu2491_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2491_1 #-----| r0_7(glval) = VariableAddress[d] : #-----| r0_8(glval) = FunctionAddress[~ClassWithDestructor] : #-----| v0_9(void) = Call[~ClassWithDestructor] : func:r0_8, this:r0_7 @@ -16306,13 +16306,13 @@ ir.cpp: #-----| mu0_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r0_7 #-----| Goto -> Block 5 -# 2492| Block 4 -# 2492| r2492_1(glval) = VariableAddress[e] : -# 2492| mu2492_2(ClassWithDestructor) = Uninitialized[e] : &:r2492_1 -# 2492| r2492_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2492| v2492_4(void) = Call[ClassWithDestructor] : func:r2492_3, this:r2492_1 -# 2492| mu2492_5(unknown) = ^CallSideEffect : ~m? -# 2492| mu2492_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2492_1 +# 2493| Block 4 +# 2493| r2493_1(glval) = VariableAddress[e] : +# 2493| mu2493_2(ClassWithDestructor) = Uninitialized[e] : &:r2493_1 +# 2493| r2493_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2493| v2493_4(void) = Call[ClassWithDestructor] : func:r2493_3, this:r2493_1 +# 2493| mu2493_5(unknown) = ^CallSideEffect : ~m? +# 2493| mu2493_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2493_1 #-----| r0_13(glval) = VariableAddress[e] : #-----| r0_14(glval) = FunctionAddress[~ClassWithDestructor] : #-----| v0_15(void) = Call[~ClassWithDestructor] : func:r0_14, this:r0_13 @@ -16321,20 +16321,20 @@ ir.cpp: #-----| mu0_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r0_13 #-----| Goto -> Block 5 -# 2494| Block 5 -# 2494| r2494_1(glval) = VariableAddress[b] : -# 2494| r2494_2(bool) = Load[b] : &:r2494_1, ~m? -# 2494| v2494_3(void) = ConditionalBranch : r2494_2 +# 2495| Block 5 +# 2495| r2495_1(glval) = VariableAddress[b] : +# 2495| r2495_2(bool) = Load[b] : &:r2495_1, ~m? +# 2495| v2495_3(void) = ConditionalBranch : r2495_2 #-----| False -> Block 7 #-----| True -> Block 6 -# 2495| Block 6 -# 2495| r2495_1(glval) = VariableAddress[f] : -# 2495| mu2495_2(ClassWithDestructor) = Uninitialized[f] : &:r2495_1 -# 2495| r2495_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2495| v2495_4(void) = Call[ClassWithDestructor] : func:r2495_3, this:r2495_1 -# 2495| mu2495_5(unknown) = ^CallSideEffect : ~m? -# 2495| mu2495_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2495_1 +# 2496| Block 6 +# 2496| r2496_1(glval) = VariableAddress[f] : +# 2496| mu2496_2(ClassWithDestructor) = Uninitialized[f] : &:r2496_1 +# 2496| r2496_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2496| v2496_4(void) = Call[ClassWithDestructor] : func:r2496_3, this:r2496_1 +# 2496| mu2496_5(unknown) = ^CallSideEffect : ~m? +# 2496| mu2496_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2496_1 #-----| r0_19(glval) = VariableAddress[f] : #-----| r0_20(glval) = FunctionAddress[~ClassWithDestructor] : #-----| v0_21(void) = Call[~ClassWithDestructor] : func:r0_20, this:r0_19 @@ -16343,276 +16343,276 @@ ir.cpp: #-----| mu0_24(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r0_19 #-----| Goto (back edge) -> Block 5 -# 2497| Block 7 -# 2497| r2497_1(glval) = VariableAddress[i] : -# 2497| r2497_2(int) = Constant[0] : -# 2497| mu2497_3(int) = Store[i] : &:r2497_1, r2497_2 +# 2498| Block 7 +# 2498| r2498_1(glval) = VariableAddress[i] : +# 2498| r2498_2(int) = Constant[0] : +# 2498| mu2498_3(int) = Store[i] : &:r2498_1, r2498_2 #-----| Goto -> Block 8 -# 2497| Block 8 -# 2497| r2497_4(glval) = VariableAddress[i] : -# 2497| r2497_5(int) = Load[i] : &:r2497_4, ~m? -# 2497| r2497_6(int) = Constant[42] : -# 2497| r2497_7(bool) = CompareLT : r2497_5, r2497_6 -# 2497| v2497_8(void) = ConditionalBranch : r2497_7 +# 2498| Block 8 +# 2498| r2498_4(glval) = VariableAddress[i] : +# 2498| r2498_5(int) = Load[i] : &:r2498_4, ~m? +# 2498| r2498_6(int) = Constant[42] : +# 2498| r2498_7(bool) = CompareLT : r2498_5, r2498_6 +# 2498| v2498_8(void) = ConditionalBranch : r2498_7 #-----| False -> Block 10 #-----| True -> Block 9 -# 2498| Block 9 -# 2498| r2498_1(glval) = VariableAddress[g] : -# 2498| mu2498_2(ClassWithDestructor) = Uninitialized[g] : &:r2498_1 -# 2498| r2498_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2498| v2498_4(void) = Call[ClassWithDestructor] : func:r2498_3, this:r2498_1 -# 2498| mu2498_5(unknown) = ^CallSideEffect : ~m? -# 2498| mu2498_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2498_1 +# 2499| Block 9 +# 2499| r2499_1(glval) = VariableAddress[g] : +# 2499| mu2499_2(ClassWithDestructor) = Uninitialized[g] : &:r2499_1 +# 2499| r2499_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2499| v2499_4(void) = Call[ClassWithDestructor] : func:r2499_3, this:r2499_1 +# 2499| mu2499_5(unknown) = ^CallSideEffect : ~m? +# 2499| mu2499_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2499_1 #-----| r0_25(glval) = VariableAddress[g] : #-----| r0_26(glval) = FunctionAddress[~ClassWithDestructor] : #-----| v0_27(void) = Call[~ClassWithDestructor] : func:r0_26, this:r0_25 #-----| mu0_28(unknown) = ^CallSideEffect : ~m? #-----| v0_29(void) = ^IndirectReadSideEffect[-1] : &:r0_25, ~m? #-----| mu0_30(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r0_25 -# 2497| r2497_9(glval) = VariableAddress[i] : -# 2497| r2497_10(int) = Load[i] : &:r2497_9, ~m? -# 2497| r2497_11(int) = Constant[1] : -# 2497| r2497_12(int) = Add : r2497_10, r2497_11 -# 2497| mu2497_13(int) = Store[i] : &:r2497_9, r2497_12 +# 2498| r2498_9(glval) = VariableAddress[i] : +# 2498| r2498_10(int) = Load[i] : &:r2498_9, ~m? +# 2498| r2498_11(int) = Constant[1] : +# 2498| r2498_12(int) = Add : r2498_10, r2498_11 +# 2498| mu2498_13(int) = Store[i] : &:r2498_9, r2498_12 #-----| Goto (back edge) -> Block 8 -# 2499| Block 10 -# 2499| v2499_1(void) = NoOp : -# 2484| v2484_6(void) = ReturnVoid : -# 2484| v2484_7(void) = AliasedUse : ~m? -# 2484| v2484_8(void) = ExitFunction : - -# 2501| void destruction_in_switch_1(int) -# 2501| Block 0 -# 2501| v2501_1(void) = EnterFunction : -# 2501| mu2501_2(unknown) = AliasedDefinition : -# 2501| mu2501_3(unknown) = InitializeNonLocal : -# 2501| r2501_4(glval) = VariableAddress[c] : -# 2501| mu2501_5(int) = InitializeParameter[c] : &:r2501_4 -# 2502| r2502_1(glval) = VariableAddress[c] : -# 2502| r2502_2(int) = Load[c] : &:r2502_1, ~m? -# 2502| v2502_3(void) = Switch : r2502_2 +# 2500| Block 10 +# 2500| v2500_1(void) = NoOp : +# 2485| v2485_6(void) = ReturnVoid : +# 2485| v2485_7(void) = AliasedUse : ~m? +# 2485| v2485_8(void) = ExitFunction : + +# 2502| void destruction_in_switch_1(int) +# 2502| Block 0 +# 2502| v2502_1(void) = EnterFunction : +# 2502| mu2502_2(unknown) = AliasedDefinition : +# 2502| mu2502_3(unknown) = InitializeNonLocal : +# 2502| r2502_4(glval) = VariableAddress[c] : +# 2502| mu2502_5(int) = InitializeParameter[c] : &:r2502_4 +# 2503| r2503_1(glval) = VariableAddress[c] : +# 2503| r2503_2(int) = Load[c] : &:r2503_1, ~m? +# 2503| v2503_3(void) = Switch : r2503_2 #-----| Case[0] -> Block 1 #-----| Default -> Block 3 -# 2503| Block 1 -# 2503| v2503_1(void) = NoOp : -# 2504| r2504_1(glval) = VariableAddress[x] : -# 2504| mu2504_2(ClassWithDestructor) = Uninitialized[x] : &:r2504_1 -# 2504| r2504_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2504| v2504_4(void) = Call[ClassWithDestructor] : func:r2504_3, this:r2504_1 -# 2504| mu2504_5(unknown) = ^CallSideEffect : ~m? -# 2504| mu2504_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2504_1 -# 2506| r2506_1(glval) = VariableAddress[x] : -# 2506| r2506_2(glval) = FunctionAddress[~ClassWithDestructor] : -# 2506| v2506_3(void) = Call[~ClassWithDestructor] : func:r2506_2, this:r2506_1 -# 2506| mu2506_4(unknown) = ^CallSideEffect : ~m? -# 2506| v2506_5(void) = ^IndirectReadSideEffect[-1] : &:r2506_1, ~m? -# 2506| mu2506_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2506_1 -# 2505| v2505_1(void) = NoOp : +# 2504| Block 1 +# 2504| v2504_1(void) = NoOp : +# 2505| r2505_1(glval) = VariableAddress[x] : +# 2505| mu2505_2(ClassWithDestructor) = Uninitialized[x] : &:r2505_1 +# 2505| r2505_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2505| v2505_4(void) = Call[ClassWithDestructor] : func:r2505_3, this:r2505_1 +# 2505| mu2505_5(unknown) = ^CallSideEffect : ~m? +# 2505| mu2505_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2505_1 +# 2507| r2507_1(glval) = VariableAddress[x] : +# 2507| r2507_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2507| v2507_3(void) = Call[~ClassWithDestructor] : func:r2507_2, this:r2507_1 +# 2507| mu2507_4(unknown) = ^CallSideEffect : ~m? +# 2507| v2507_5(void) = ^IndirectReadSideEffect[-1] : &:r2507_1, ~m? +# 2507| mu2507_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2507_1 +# 2506| v2506_1(void) = NoOp : #-----| Goto -> Block 3 -# 2506| Block 2 -# 2506| r2506_7(glval) = VariableAddress[x] : -# 2506| r2506_8(glval) = FunctionAddress[~ClassWithDestructor] : -# 2506| v2506_9(void) = Call[~ClassWithDestructor] : func:r2506_8, this:r2506_7 -# 2506| mu2506_10(unknown) = ^CallSideEffect : ~m? -# 2506| v2506_11(void) = ^IndirectReadSideEffect[-1] : &:r2506_7, ~m? -# 2506| mu2506_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2506_7 +# 2507| Block 2 +# 2507| r2507_7(glval) = VariableAddress[x] : +# 2507| r2507_8(glval) = FunctionAddress[~ClassWithDestructor] : +# 2507| v2507_9(void) = Call[~ClassWithDestructor] : func:r2507_8, this:r2507_7 +# 2507| mu2507_10(unknown) = ^CallSideEffect : ~m? +# 2507| v2507_11(void) = ^IndirectReadSideEffect[-1] : &:r2507_7, ~m? +# 2507| mu2507_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2507_7 #-----| Goto -> Block 3 -# 2507| Block 3 -# 2507| v2507_1(void) = NoOp : +# 2508| Block 3 # 2508| v2508_1(void) = NoOp : -# 2501| v2501_6(void) = ReturnVoid : -# 2501| v2501_7(void) = AliasedUse : ~m? -# 2501| v2501_8(void) = ExitFunction : - -# 2510| void destruction_in_switch_2(int) -# 2510| Block 0 -# 2510| v2510_1(void) = EnterFunction : -# 2510| mu2510_2(unknown) = AliasedDefinition : -# 2510| mu2510_3(unknown) = InitializeNonLocal : -# 2510| r2510_4(glval) = VariableAddress[c] : -# 2510| mu2510_5(int) = InitializeParameter[c] : &:r2510_4 -# 2511| r2511_1(glval) = VariableAddress[y] : -# 2511| mu2511_2(ClassWithDestructor) = Uninitialized[y] : &:r2511_1 -# 2511| r2511_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2511| v2511_4(void) = Call[ClassWithDestructor] : func:r2511_3, this:r2511_1 -# 2511| mu2511_5(unknown) = ^CallSideEffect : ~m? -# 2511| mu2511_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2511_1 -# 2511| r2511_7(glval) = VariableAddress[c] : -# 2511| r2511_8(int) = Load[c] : &:r2511_7, ~m? -# 2511| v2511_9(void) = Switch : r2511_8 +# 2509| v2509_1(void) = NoOp : +# 2502| v2502_6(void) = ReturnVoid : +# 2502| v2502_7(void) = AliasedUse : ~m? +# 2502| v2502_8(void) = ExitFunction : + +# 2511| void destruction_in_switch_2(int) +# 2511| Block 0 +# 2511| v2511_1(void) = EnterFunction : +# 2511| mu2511_2(unknown) = AliasedDefinition : +# 2511| mu2511_3(unknown) = InitializeNonLocal : +# 2511| r2511_4(glval) = VariableAddress[c] : +# 2511| mu2511_5(int) = InitializeParameter[c] : &:r2511_4 +# 2512| r2512_1(glval) = VariableAddress[y] : +# 2512| mu2512_2(ClassWithDestructor) = Uninitialized[y] : &:r2512_1 +# 2512| r2512_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2512| v2512_4(void) = Call[ClassWithDestructor] : func:r2512_3, this:r2512_1 +# 2512| mu2512_5(unknown) = ^CallSideEffect : ~m? +# 2512| mu2512_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2512_1 +# 2512| r2512_7(glval) = VariableAddress[c] : +# 2512| r2512_8(int) = Load[c] : &:r2512_7, ~m? +# 2512| v2512_9(void) = Switch : r2512_8 #-----| Case[0] -> Block 1 #-----| Default -> Block 2 -# 2512| Block 1 -# 2512| v2512_1(void) = NoOp : -# 2518| r2518_1(glval) = VariableAddress[y] : -# 2518| r2518_2(glval) = FunctionAddress[~ClassWithDestructor] : -# 2518| v2518_3(void) = Call[~ClassWithDestructor] : func:r2518_2, this:r2518_1 -# 2518| mu2518_4(unknown) = ^CallSideEffect : ~m? -# 2518| v2518_5(void) = ^IndirectReadSideEffect[-1] : &:r2518_1, ~m? -# 2518| mu2518_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2518_1 +# 2513| Block 1 # 2513| v2513_1(void) = NoOp : +# 2519| r2519_1(glval) = VariableAddress[y] : +# 2519| r2519_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2519| v2519_3(void) = Call[~ClassWithDestructor] : func:r2519_2, this:r2519_1 +# 2519| mu2519_4(unknown) = ^CallSideEffect : ~m? +# 2519| v2519_5(void) = ^IndirectReadSideEffect[-1] : &:r2519_1, ~m? +# 2519| mu2519_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2519_1 +# 2514| v2514_1(void) = NoOp : #-----| Goto -> Block 4 -# 2515| Block 2 -# 2515| v2515_1(void) = NoOp : -# 2518| r2518_7(glval) = VariableAddress[y] : -# 2518| r2518_8(glval) = FunctionAddress[~ClassWithDestructor] : -# 2518| v2518_9(void) = Call[~ClassWithDestructor] : func:r2518_8, this:r2518_7 -# 2518| mu2518_10(unknown) = ^CallSideEffect : ~m? -# 2518| v2518_11(void) = ^IndirectReadSideEffect[-1] : &:r2518_7, ~m? -# 2518| mu2518_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2518_7 +# 2516| Block 2 # 2516| v2516_1(void) = NoOp : +# 2519| r2519_7(glval) = VariableAddress[y] : +# 2519| r2519_8(glval) = FunctionAddress[~ClassWithDestructor] : +# 2519| v2519_9(void) = Call[~ClassWithDestructor] : func:r2519_8, this:r2519_7 +# 2519| mu2519_10(unknown) = ^CallSideEffect : ~m? +# 2519| v2519_11(void) = ^IndirectReadSideEffect[-1] : &:r2519_7, ~m? +# 2519| mu2519_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2519_7 +# 2517| v2517_1(void) = NoOp : #-----| Goto -> Block 4 -# 2518| Block 3 -# 2518| r2518_13(glval) = VariableAddress[y] : -# 2518| r2518_14(glval) = FunctionAddress[~ClassWithDestructor] : -# 2518| v2518_15(void) = Call[~ClassWithDestructor] : func:r2518_14, this:r2518_13 -# 2518| mu2518_16(unknown) = ^CallSideEffect : ~m? -# 2518| v2518_17(void) = ^IndirectReadSideEffect[-1] : &:r2518_13, ~m? -# 2518| mu2518_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2518_13 +# 2519| Block 3 +# 2519| r2519_13(glval) = VariableAddress[y] : +# 2519| r2519_14(glval) = FunctionAddress[~ClassWithDestructor] : +# 2519| v2519_15(void) = Call[~ClassWithDestructor] : func:r2519_14, this:r2519_13 +# 2519| mu2519_16(unknown) = ^CallSideEffect : ~m? +# 2519| v2519_17(void) = ^IndirectReadSideEffect[-1] : &:r2519_13, ~m? +# 2519| mu2519_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2519_13 #-----| Goto -> Block 4 -# 2518| Block 4 -# 2518| v2518_19(void) = NoOp : -# 2519| v2519_1(void) = NoOp : -# 2510| v2510_6(void) = ReturnVoid : -# 2510| v2510_7(void) = AliasedUse : ~m? -# 2510| v2510_8(void) = ExitFunction : - -# 2521| void destruction_in_switch_3(int) -# 2521| Block 0 -# 2521| v2521_1(void) = EnterFunction : -# 2521| mu2521_2(unknown) = AliasedDefinition : -# 2521| mu2521_3(unknown) = InitializeNonLocal : -# 2521| r2521_4(glval) = VariableAddress[c] : -# 2521| mu2521_5(int) = InitializeParameter[c] : &:r2521_4 -# 2522| r2522_1(glval) = VariableAddress[y] : -# 2522| mu2522_2(ClassWithDestructor) = Uninitialized[y] : &:r2522_1 -# 2522| r2522_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2522| v2522_4(void) = Call[ClassWithDestructor] : func:r2522_3, this:r2522_1 -# 2522| mu2522_5(unknown) = ^CallSideEffect : ~m? -# 2522| mu2522_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2522_1 -# 2522| r2522_7(glval) = VariableAddress[c] : -# 2522| r2522_8(int) = Load[c] : &:r2522_7, ~m? -# 2522| v2522_9(void) = Switch : r2522_8 +# 2519| Block 4 +# 2519| v2519_19(void) = NoOp : +# 2520| v2520_1(void) = NoOp : +# 2511| v2511_6(void) = ReturnVoid : +# 2511| v2511_7(void) = AliasedUse : ~m? +# 2511| v2511_8(void) = ExitFunction : + +# 2522| void destruction_in_switch_3(int) +# 2522| Block 0 +# 2522| v2522_1(void) = EnterFunction : +# 2522| mu2522_2(unknown) = AliasedDefinition : +# 2522| mu2522_3(unknown) = InitializeNonLocal : +# 2522| r2522_4(glval) = VariableAddress[c] : +# 2522| mu2522_5(int) = InitializeParameter[c] : &:r2522_4 +# 2523| r2523_1(glval) = VariableAddress[y] : +# 2523| mu2523_2(ClassWithDestructor) = Uninitialized[y] : &:r2523_1 +# 2523| r2523_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2523| v2523_4(void) = Call[ClassWithDestructor] : func:r2523_3, this:r2523_1 +# 2523| mu2523_5(unknown) = ^CallSideEffect : ~m? +# 2523| mu2523_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2523_1 +# 2523| r2523_7(glval) = VariableAddress[c] : +# 2523| r2523_8(int) = Load[c] : &:r2523_7, ~m? +# 2523| v2523_9(void) = Switch : r2523_8 #-----| Case[0] -> Block 1 #-----| Default -> Block 3 -# 2523| Block 1 -# 2523| v2523_1(void) = NoOp : -# 2524| r2524_1(glval) = VariableAddress[x] : -# 2524| mu2524_2(ClassWithDestructor) = Uninitialized[x] : &:r2524_1 -# 2524| r2524_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2524| v2524_4(void) = Call[ClassWithDestructor] : func:r2524_3, this:r2524_1 -# 2524| mu2524_5(unknown) = ^CallSideEffect : ~m? -# 2524| mu2524_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2524_1 -# 2526| r2526_1(glval) = VariableAddress[x] : -# 2526| r2526_2(glval) = FunctionAddress[~ClassWithDestructor] : -# 2526| v2526_3(void) = Call[~ClassWithDestructor] : func:r2526_2, this:r2526_1 -# 2526| mu2526_4(unknown) = ^CallSideEffect : ~m? -# 2526| v2526_5(void) = ^IndirectReadSideEffect[-1] : &:r2526_1, ~m? -# 2526| mu2526_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2526_1 -# 2530| r2530_1(glval) = VariableAddress[y] : -# 2530| r2530_2(glval) = FunctionAddress[~ClassWithDestructor] : -# 2530| v2530_3(void) = Call[~ClassWithDestructor] : func:r2530_2, this:r2530_1 -# 2530| mu2530_4(unknown) = ^CallSideEffect : ~m? -# 2530| v2530_5(void) = ^IndirectReadSideEffect[-1] : &:r2530_1, ~m? -# 2530| mu2530_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2530_1 -# 2525| v2525_1(void) = NoOp : +# 2524| Block 1 +# 2524| v2524_1(void) = NoOp : +# 2525| r2525_1(glval) = VariableAddress[x] : +# 2525| mu2525_2(ClassWithDestructor) = Uninitialized[x] : &:r2525_1 +# 2525| r2525_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2525| v2525_4(void) = Call[ClassWithDestructor] : func:r2525_3, this:r2525_1 +# 2525| mu2525_5(unknown) = ^CallSideEffect : ~m? +# 2525| mu2525_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2525_1 +# 2527| r2527_1(glval) = VariableAddress[x] : +# 2527| r2527_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2527| v2527_3(void) = Call[~ClassWithDestructor] : func:r2527_2, this:r2527_1 +# 2527| mu2527_4(unknown) = ^CallSideEffect : ~m? +# 2527| v2527_5(void) = ^IndirectReadSideEffect[-1] : &:r2527_1, ~m? +# 2527| mu2527_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2527_1 +# 2531| r2531_1(glval) = VariableAddress[y] : +# 2531| r2531_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2531| v2531_3(void) = Call[~ClassWithDestructor] : func:r2531_2, this:r2531_1 +# 2531| mu2531_4(unknown) = ^CallSideEffect : ~m? +# 2531| v2531_5(void) = ^IndirectReadSideEffect[-1] : &:r2531_1, ~m? +# 2531| mu2531_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2531_1 +# 2526| v2526_1(void) = NoOp : #-----| Goto -> Block 5 -# 2526| Block 2 -# 2526| r2526_7(glval) = VariableAddress[x] : -# 2526| r2526_8(glval) = FunctionAddress[~ClassWithDestructor] : -# 2526| v2526_9(void) = Call[~ClassWithDestructor] : func:r2526_8, this:r2526_7 -# 2526| mu2526_10(unknown) = ^CallSideEffect : ~m? -# 2526| v2526_11(void) = ^IndirectReadSideEffect[-1] : &:r2526_7, ~m? -# 2526| mu2526_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2526_7 +# 2527| Block 2 +# 2527| r2527_7(glval) = VariableAddress[x] : +# 2527| r2527_8(glval) = FunctionAddress[~ClassWithDestructor] : +# 2527| v2527_9(void) = Call[~ClassWithDestructor] : func:r2527_8, this:r2527_7 +# 2527| mu2527_10(unknown) = ^CallSideEffect : ~m? +# 2527| v2527_11(void) = ^IndirectReadSideEffect[-1] : &:r2527_7, ~m? +# 2527| mu2527_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2527_7 #-----| Goto -> Block 3 -# 2527| Block 3 -# 2527| v2527_1(void) = NoOp : -# 2530| r2530_7(glval) = VariableAddress[y] : -# 2530| r2530_8(glval) = FunctionAddress[~ClassWithDestructor] : -# 2530| v2530_9(void) = Call[~ClassWithDestructor] : func:r2530_8, this:r2530_7 -# 2530| mu2530_10(unknown) = ^CallSideEffect : ~m? -# 2530| v2530_11(void) = ^IndirectReadSideEffect[-1] : &:r2530_7, ~m? -# 2530| mu2530_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2530_7 +# 2528| Block 3 # 2528| v2528_1(void) = NoOp : +# 2531| r2531_7(glval) = VariableAddress[y] : +# 2531| r2531_8(glval) = FunctionAddress[~ClassWithDestructor] : +# 2531| v2531_9(void) = Call[~ClassWithDestructor] : func:r2531_8, this:r2531_7 +# 2531| mu2531_10(unknown) = ^CallSideEffect : ~m? +# 2531| v2531_11(void) = ^IndirectReadSideEffect[-1] : &:r2531_7, ~m? +# 2531| mu2531_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2531_7 +# 2529| v2529_1(void) = NoOp : #-----| Goto -> Block 5 -# 2530| Block 4 -# 2530| r2530_13(glval) = VariableAddress[y] : -# 2530| r2530_14(glval) = FunctionAddress[~ClassWithDestructor] : -# 2530| v2530_15(void) = Call[~ClassWithDestructor] : func:r2530_14, this:r2530_13 -# 2530| mu2530_16(unknown) = ^CallSideEffect : ~m? -# 2530| v2530_17(void) = ^IndirectReadSideEffect[-1] : &:r2530_13, ~m? -# 2530| mu2530_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2530_13 +# 2531| Block 4 +# 2531| r2531_13(glval) = VariableAddress[y] : +# 2531| r2531_14(glval) = FunctionAddress[~ClassWithDestructor] : +# 2531| v2531_15(void) = Call[~ClassWithDestructor] : func:r2531_14, this:r2531_13 +# 2531| mu2531_16(unknown) = ^CallSideEffect : ~m? +# 2531| v2531_17(void) = ^IndirectReadSideEffect[-1] : &:r2531_13, ~m? +# 2531| mu2531_18(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2531_13 #-----| Goto -> Block 5 -# 2530| Block 5 -# 2530| v2530_19(void) = NoOp : -# 2531| v2531_1(void) = NoOp : -# 2521| v2521_6(void) = ReturnVoid : -# 2521| v2521_7(void) = AliasedUse : ~m? -# 2521| v2521_8(void) = ExitFunction : - -# 2533| void destructor_possibly_not_handled() -# 2533| Block 0 -# 2533| v2533_1(void) = EnterFunction : -# 2533| mu2533_2(unknown) = AliasedDefinition : -# 2533| mu2533_3(unknown) = InitializeNonLocal : -# 2534| r2534_1(glval) = VariableAddress[x] : -# 2534| mu2534_2(ClassWithDestructor) = Uninitialized[x] : &:r2534_1 -# 2534| r2534_3(glval) = FunctionAddress[ClassWithDestructor] : -# 2534| v2534_4(void) = Call[ClassWithDestructor] : func:r2534_3, this:r2534_1 -# 2534| mu2534_5(unknown) = ^CallSideEffect : ~m? -# 2534| mu2534_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2534_1 -# 2536| r2536_1(glval) = VariableAddress[#throw2536:5] : -# 2536| r2536_2(int) = Constant[42] : -# 2536| mu2536_3(int) = Store[#throw2536:5] : &:r2536_1, r2536_2 -# 2536| v2536_4(void) = ThrowValue : &:r2536_1, ~m? +# 2531| Block 5 +# 2531| v2531_19(void) = NoOp : +# 2532| v2532_1(void) = NoOp : +# 2522| v2522_6(void) = ReturnVoid : +# 2522| v2522_7(void) = AliasedUse : ~m? +# 2522| v2522_8(void) = ExitFunction : + +# 2534| void destructor_possibly_not_handled() +# 2534| Block 0 +# 2534| v2534_1(void) = EnterFunction : +# 2534| mu2534_2(unknown) = AliasedDefinition : +# 2534| mu2534_3(unknown) = InitializeNonLocal : +# 2535| r2535_1(glval) = VariableAddress[x] : +# 2535| mu2535_2(ClassWithDestructor) = Uninitialized[x] : &:r2535_1 +# 2535| r2535_3(glval) = FunctionAddress[ClassWithDestructor] : +# 2535| v2535_4(void) = Call[ClassWithDestructor] : func:r2535_3, this:r2535_1 +# 2535| mu2535_5(unknown) = ^CallSideEffect : ~m? +# 2535| mu2535_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2535_1 +# 2537| r2537_1(glval) = VariableAddress[#throw2537:5] : +# 2537| r2537_2(int) = Constant[42] : +# 2537| mu2537_3(int) = Store[#throw2537:5] : &:r2537_1, r2537_2 +# 2537| v2537_4(void) = ThrowValue : &:r2537_1, ~m? #-----| Exception -> Block 3 -# 2533| Block 1 -# 2533| v2533_4(void) = AliasedUse : ~m? -# 2533| v2533_5(void) = ExitFunction : +# 2534| Block 1 +# 2534| v2534_4(void) = AliasedUse : ~m? +# 2534| v2534_5(void) = ExitFunction : -# 2533| Block 2 -# 2533| v2533_6(void) = Unwind : +# 2534| Block 2 +# 2534| v2534_6(void) = Unwind : #-----| Goto -> Block 1 -# 2538| Block 3 -# 2538| v2538_1(void) = CatchByType[char] : +# 2539| Block 3 +# 2539| v2539_1(void) = CatchByType[char] : #-----| Exception -> Block 2 #-----| Goto -> Block 4 -# 2538| Block 4 -# 2538| r2538_2(glval) = VariableAddress[(unnamed parameter 0)] : -# 2538| mu2538_3(char) = InitializeParameter[(unnamed parameter 0)] : &:r2538_2 -# 2538| v2538_4(void) = NoOp : -# 2540| r2540_1(glval) = VariableAddress[x] : -# 2540| r2540_2(glval) = FunctionAddress[~ClassWithDestructor] : -# 2540| v2540_3(void) = Call[~ClassWithDestructor] : func:r2540_2, this:r2540_1 -# 2540| mu2540_4(unknown) = ^CallSideEffect : ~m? -# 2540| v2540_5(void) = ^IndirectReadSideEffect[-1] : &:r2540_1, ~m? -# 2540| mu2540_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2540_1 -# 2540| v2540_7(void) = NoOp : -# 2540| r2540_8(glval) = VariableAddress[x] : -# 2540| r2540_9(glval) = FunctionAddress[~ClassWithDestructor] : -# 2540| v2540_10(void) = Call[~ClassWithDestructor] : func:r2540_9, this:r2540_8 -# 2540| mu2540_11(unknown) = ^CallSideEffect : ~m? -# 2540| v2540_12(void) = ^IndirectReadSideEffect[-1] : &:r2540_8, ~m? -# 2540| mu2540_13(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2540_8 -# 2533| v2533_7(void) = ReturnVoid : +# 2539| Block 4 +# 2539| r2539_2(glval) = VariableAddress[(unnamed parameter 0)] : +# 2539| mu2539_3(char) = InitializeParameter[(unnamed parameter 0)] : &:r2539_2 +# 2539| v2539_4(void) = NoOp : +# 2541| r2541_1(glval) = VariableAddress[x] : +# 2541| r2541_2(glval) = FunctionAddress[~ClassWithDestructor] : +# 2541| v2541_3(void) = Call[~ClassWithDestructor] : func:r2541_2, this:r2541_1 +# 2541| mu2541_4(unknown) = ^CallSideEffect : ~m? +# 2541| v2541_5(void) = ^IndirectReadSideEffect[-1] : &:r2541_1, ~m? +# 2541| mu2541_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2541_1 +# 2541| v2541_7(void) = NoOp : +# 2541| r2541_8(glval) = VariableAddress[x] : +# 2541| r2541_9(glval) = FunctionAddress[~ClassWithDestructor] : +# 2541| v2541_10(void) = Call[~ClassWithDestructor] : func:r2541_9, this:r2541_8 +# 2541| mu2541_11(unknown) = ^CallSideEffect : ~m? +# 2541| v2541_12(void) = ^IndirectReadSideEffect[-1] : &:r2541_8, ~m? +# 2541| mu2541_13(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2541_8 +# 2534| v2534_7(void) = ReturnVoid : #-----| Goto -> Block 1 perf-regression.cpp: From 6575927630efc7e18f1a1eaeb68447a1053cbea0 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Wed, 8 May 2024 11:43:58 +0200 Subject: [PATCH 238/238] C++: Add IR tests demonstrating some inconsistencies that may occur --- .../library-tests/ir/ir/PrintAST.expected | 76 +++++++++++++++++ .../library-tests/ir/ir/aliased_ir.expected | 84 +++++++++++++++++++ .../ir/ir/aliased_ssa_consistency.expected | 1 + .../aliased_ssa_consistency_unsound.expected | 1 + cpp/ql/test/library-tests/ir/ir/ir.cpp | 20 ++--- .../ir/ir/raw_consistency.expected | 2 + .../test/library-tests/ir/ir/raw_ir.expected | 84 +++++++++++++++++++ .../ir/ir/unaliased_ssa_consistency.expected | 1 + ...unaliased_ssa_consistency_unsound.expected | 1 + 9 files changed, 259 insertions(+), 11 deletions(-) diff --git a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected index 0d6ab9c6a4e5..d7b240c8949a 100644 --- a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected +++ b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected @@ -22658,6 +22658,82 @@ ir.cpp: # 2541| getQualifier(): [VariableAccess] x # 2541| Type = [Class] ClassWithDestructor # 2541| ValueCategory = lvalue +# 2543| [TopLevelFunction] ClassWithDestructor getClassWithDestructor() +# 2543| : +# 2545| [TopLevelFunction] void this_inconsistency(bool) +# 2545| : +# 2545| getParameter(0): [Parameter] b +# 2545| Type = [BoolType] bool +# 2545| getEntryPoint(): [BlockStmt] { ... } +# 2546| getStmt(0): [IfStmt] if (...) ... +# 2546| getCondition(): [ConditionDeclExpr] (condition decl) +# 2546| Type = [BoolType] bool +# 2546| ValueCategory = prvalue +# 2546| getChild(0): [FunctionCall] call to operator bool +# 2546| Type = [BoolType] bool +# 2546| ValueCategory = prvalue +# 2546| getQualifier(): [VariableAccess] a +# 2546| Type = [LValueReferenceType] const ClassWithDestructor & +# 2546| ValueCategory = prvalue(load) +# 2546| getQualifier().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) +# 2546| Type = [SpecifiedType] const ClassWithDestructor +# 2546| ValueCategory = prvalue(load) +# 2546| getInitializingExpr(): [FunctionCall] call to getClassWithDestructor +# 2546| Type = [Class] ClassWithDestructor +# 2546| ValueCategory = prvalue +# 2546| getInitializingExpr().getFullyConverted(): [ReferenceToExpr] (reference to) +# 2546| Type = [LValueReferenceType] const ClassWithDestructor & +# 2546| ValueCategory = prvalue +# 2546| getExpr(): [CStyleCast] (const ClassWithDestructor)... +# 2546| Conversion = [GlvalueConversion] glvalue conversion +# 2546| Type = [SpecifiedType] const ClassWithDestructor +# 2546| ValueCategory = lvalue +# 2546| getExpr(): [TemporaryObjectExpr] temporary object +# 2546| Type = [Class] ClassWithDestructor +# 2546| ValueCategory = lvalue +# 2547| getThen(): [EmptyStmt] ; +# 2547| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2547| Type = [VoidType] void +# 2547| ValueCategory = prvalue +# 2547| getQualifier(): [ReuseExpr] reuse of temporary object +# 2547| Type = [Class] ClassWithDestructor +# 2547| ValueCategory = xvalue +# 2548| getStmt(1): [ReturnStmt] return ... +# 2550| [TopLevelFunction] void constexpr_inconsistency(bool) +# 2550| : +# 2550| getParameter(0): [Parameter] b +# 2550| Type = [BoolType] bool +# 2550| getEntryPoint(): [BlockStmt] { ... } +# 2551| getStmt(0): [ConstexprIfStmt] if constexpr (...) ... +# 2551| getInitialization(): [DeclStmt] declaration +# 2551| getDeclarationEntry(0): [VariableDeclarationEntry] definition of a +# 2551| Type = [LValueReferenceType] const ClassWithDestructor & +# 2551| getVariable().getInitializer(): [Initializer] initializer for a +# 2551| getExpr(): [FunctionCall] call to getClassWithDestructor +# 2551| Type = [Class] ClassWithDestructor +# 2551| ValueCategory = prvalue +# 2551| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to) +# 2551| Type = [LValueReferenceType] const ClassWithDestructor & +# 2551| ValueCategory = prvalue +# 2551| getExpr(): [CStyleCast] (const ClassWithDestructor)... +# 2551| Conversion = [GlvalueConversion] glvalue conversion +# 2551| Type = [SpecifiedType] const ClassWithDestructor +# 2551| ValueCategory = lvalue +# 2551| getExpr(): [TemporaryObjectExpr] temporary object +# 2551| Type = [Class] ClassWithDestructor +# 2551| ValueCategory = lvalue +# 2551| getCondition(): [VariableAccess] initialization_with_destructor_bool +# 2551| Type = [BoolType] bool +# 2551| Value = [VariableAccess] 1 +# 2551| ValueCategory = prvalue(load) +# 2552| getThen(): [EmptyStmt] ; +# 2552| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2552| Type = [VoidType] void +# 2552| ValueCategory = prvalue +# 2552| getQualifier(): [ReuseExpr] reuse of temporary object +# 2552| Type = [Class] ClassWithDestructor +# 2552| ValueCategory = xvalue +# 2553| getStmt(1): [ReturnStmt] return ... perf-regression.cpp: # 4| [CopyAssignmentOperator] Big& Big::operator=(Big const&) # 4| : diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected index 2fc610f6d128..eef600513eba 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected @@ -18251,6 +18251,90 @@ ir.cpp: # 2534| v2534_9(void) = ReturnVoid : #-----| Goto -> Block 1 +# 2545| void this_inconsistency(bool) +# 2545| Block 0 +# 2545| v2545_1(void) = EnterFunction : +# 2545| m2545_2(unknown) = AliasedDefinition : +# 2545| m2545_3(unknown) = InitializeNonLocal : +# 2545| m2545_4(unknown) = Chi : total:m2545_2, partial:m2545_3 +# 2545| r2545_5(glval) = VariableAddress[b] : +# 2545| m2545_6(bool) = InitializeParameter[b] : &:r2545_5 +# 2546| r2546_1(glval) = VariableAddress[a] : +# 2546| r2546_2(glval) = VariableAddress[#temp2546:38] : +# 2546| r2546_3(glval) = FunctionAddress[getClassWithDestructor] : +# 2546| r2546_4(ClassWithDestructor) = Call[getClassWithDestructor] : func:r2546_3 +# 2546| m2546_5(unknown) = ^CallSideEffect : ~m2545_4 +# 2546| m2546_6(unknown) = Chi : total:m2545_4, partial:m2546_5 +# 2546| m2546_7(ClassWithDestructor) = Store[#temp2546:38] : &:r2546_2, r2546_4 +# 2546| m2546_8(unknown) = Chi : total:m2546_6, partial:m2546_7 +# 2546| r2546_9(glval) = Convert : r2546_2 +# 2546| r2546_10(ClassWithDestructor &) = CopyValue : r2546_9 +# 2546| m2546_11(ClassWithDestructor &) = Store[a] : &:r2546_1, r2546_10 +# 2546| r2546_12(glval) = VariableAddress[a] : +# 2546| r2546_13(ClassWithDestructor &) = Load[a] : &:r2546_12, m2546_11 +# 2546| r2546_14(ClassWithDestructor) = CopyValue : r2546_13 +# 2546| r2546_15(glval) = FunctionAddress[operator bool] : +# 2546| r2546_16(bool) = Call[operator bool] : func:r2546_15, this:r2546_14 +# 2546| m2546_17(unknown) = ^CallSideEffect : ~m2546_8 +# 2546| m2546_18(unknown) = Chi : total:m2546_8, partial:m2546_17 +# 2546| v2546_19(void) = ^IndirectReadSideEffect[-1] : &:r2546_14, ~m2546_18 +# 2546| r2546_20(bool) = CopyValue : r2546_16 +# 2546| v2546_21(void) = ConditionalBranch : r2546_20 +#-----| False -> Block 2 +#-----| True -> Block 1 + +# 2547| Block 1 +# 2547| v2547_1(void) = NoOp : +# 2547| r2547_2(glval) = CopyValue : r2546_2 +# 2547| r2547_3(glval) = FunctionAddress[~ClassWithDestructor] : +# 2547| v2547_4(void) = Call[~ClassWithDestructor] : func:r2547_3, this:r2547_2 +# 2547| m2547_5(unknown) = ^CallSideEffect : ~m2546_18 +# 2547| m2547_6(unknown) = Chi : total:m2546_18, partial:m2547_5 +# 2547| v2547_7(void) = ^IndirectReadSideEffect[-1] : &:r2547_2, ~m2547_6 +# 2547| m2547_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2547_2 +# 2547| m2547_9(unknown) = Chi : total:m2547_6, partial:m2547_8 +#-----| Goto -> Block 2 + +# 2548| Block 2 +# 2548| m2548_1(unknown) = Phi : from 0:~m2546_18, from 1:~m2547_9 +# 2548| v2548_2(void) = NoOp : +# 2545| v2545_7(void) = ReturnVoid : +# 2545| v2545_8(void) = AliasedUse : ~m2548_1 +# 2545| v2545_9(void) = ExitFunction : + +# 2550| void constexpr_inconsistency(bool) +# 2550| Block 0 +# 2550| v2550_1(void) = EnterFunction : +# 2550| m2550_2(unknown) = AliasedDefinition : +# 2550| m2550_3(unknown) = InitializeNonLocal : +# 2550| m2550_4(unknown) = Chi : total:m2550_2, partial:m2550_3 +# 2550| r2550_5(glval) = VariableAddress[b] : +# 2550| m2550_6(bool) = InitializeParameter[b] : &:r2550_5 +# 2551| r2551_1(glval) = VariableAddress[a] : +# 2551| r2551_2(glval) = VariableAddress[#temp2551:48] : +# 2551| r2551_3(glval) = FunctionAddress[getClassWithDestructor] : +# 2551| r2551_4(ClassWithDestructor) = Call[getClassWithDestructor] : func:r2551_3 +# 2551| m2551_5(unknown) = ^CallSideEffect : ~m2550_4 +# 2551| m2551_6(unknown) = Chi : total:m2550_4, partial:m2551_5 +# 2551| m2551_7(ClassWithDestructor) = Store[#temp2551:48] : &:r2551_2, r2551_4 +# 2551| r2551_8(glval) = Convert : r2551_2 +# 2551| r2551_9(ClassWithDestructor &) = CopyValue : r2551_8 +# 2551| m2551_10(ClassWithDestructor &) = Store[a] : &:r2551_1, r2551_9 +# 2551| r2551_11(bool) = Constant[1] : +# 2551| v2551_12(void) = ConditionalBranch : r2551_11 +#-----| False -> Block 2 +#-----| True -> Block 1 + +# 2552| Block 1 +# 2552| v2552_1(void) = NoOp : +# 2553| v2553_1(void) = NoOp : +# 2550| v2550_7(void) = ReturnVoid : +# 2550| v2550_8(void) = AliasedUse : ~m2551_6 +# 2550| v2550_9(void) = ExitFunction : + +# 2550| Block 2 +# 2550| v2550_10(void) = Unreached : + perf-regression.cpp: # 6| void Big::Big() # 6| Block 0 diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency.expected index 8f472b49f273..5a0234a4cc42 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency.expected @@ -27,6 +27,7 @@ invalidOverlap nonUniqueEnclosingIRFunction fieldAddressOnNonPointer thisArgumentIsNonPointer +| ir.cpp:2546:34:2546:34 | Call: call to operator bool | Call instruction 'Call: call to operator bool' has a `this` argument operand that is not an address, in function '$@'. | ir.cpp:2545:6:2545:23 | void this_inconsistency(bool) | void this_inconsistency(bool) | nonUniqueIRVariable | coroutines.cpp:87:20:87:20 | VariableAddress: (unnamed local variable) | Variable address instruction 'VariableAddress: (unnamed local variable)' has no associated variable, in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() | | coroutines.cpp:87:20:87:20 | VariableAddress: (unnamed local variable) | Variable address instruction 'VariableAddress: (unnamed local variable)' has no associated variable, in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() | diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency_unsound.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency_unsound.expected index 8f472b49f273..5a0234a4cc42 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency_unsound.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency_unsound.expected @@ -27,6 +27,7 @@ invalidOverlap nonUniqueEnclosingIRFunction fieldAddressOnNonPointer thisArgumentIsNonPointer +| ir.cpp:2546:34:2546:34 | Call: call to operator bool | Call instruction 'Call: call to operator bool' has a `this` argument operand that is not an address, in function '$@'. | ir.cpp:2545:6:2545:23 | void this_inconsistency(bool) | void this_inconsistency(bool) | nonUniqueIRVariable | coroutines.cpp:87:20:87:20 | VariableAddress: (unnamed local variable) | Variable address instruction 'VariableAddress: (unnamed local variable)' has no associated variable, in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() | | coroutines.cpp:87:20:87:20 | VariableAddress: (unnamed local variable) | Variable address instruction 'VariableAddress: (unnamed local variable)' has no associated variable, in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() | diff --git a/cpp/ql/test/library-tests/ir/ir/ir.cpp b/cpp/ql/test/library-tests/ir/ir/ir.cpp index 159c7173310f..3c6b1cdbbf01 100644 --- a/cpp/ql/test/library-tests/ir/ir/ir.cpp +++ b/cpp/ql/test/library-tests/ir/ir/ir.cpp @@ -2540,18 +2540,16 @@ void destructor_possibly_not_handled() { } } -// ClassWithDestructor getClassWithDestructor(); +ClassWithDestructor getClassWithDestructor(); -// void this_inconsistency(bool b) { -// if (const ClassWithDestructor& a = getClassWithDestructor()) -// ; -// } - -// constexpr bool initialization_with_destructor_bool = true; +void this_inconsistency(bool b) { + if (const ClassWithDestructor& a = getClassWithDestructor()) + ; +} -// void constexpr_inconsistency(bool b) { -// if constexpr (const ClassWithDestructor& a = getClassWithDestructor(); initialization_with_destructor_bool) -// ; -// } +void constexpr_inconsistency(bool b) { + if constexpr (const ClassWithDestructor& a = getClassWithDestructor(); initialization_with_destructor_bool) + ; +} // semmle-extractor-options: -std=c++20 --clang diff --git a/cpp/ql/test/library-tests/ir/ir/raw_consistency.expected b/cpp/ql/test/library-tests/ir/ir/raw_consistency.expected index 11dd363ebc52..926444e16747 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_consistency.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_consistency.expected @@ -21,6 +21,7 @@ lostReachability backEdgeCountMismatch useNotDominatedByDefinition | ir.cpp:1535:8:1535:8 | Unary | Operand 'Unary' is not dominated by its definition in function '$@'. | ir.cpp:1535:8:1535:8 | void StructuredBindingDataMemberStruct::StructuredBindingDataMemberStruct() | void StructuredBindingDataMemberStruct::StructuredBindingDataMemberStruct() | +| ir.cpp:2551:48:2551:71 | Unary | Operand 'Unary' is not dominated by its definition in function '$@'. | ir.cpp:2550:6:2550:28 | void constexpr_inconsistency(bool) | void constexpr_inconsistency(bool) | | try_except.c:13:13:13:13 | Left | Operand 'Left' is not dominated by its definition in function '$@'. | try_except.c:6:6:6:6 | void f() | void f() | | try_except.c:13:13:13:13 | Left | Operand 'Left' is not dominated by its definition in function '$@'. | try_except.c:6:6:6:6 | void f() | void f() | | try_except.c:39:15:39:15 | Left | Operand 'Left' is not dominated by its definition in function '$@'. | try_except.c:32:6:32:6 | void h(int) | void h(int) | @@ -36,6 +37,7 @@ invalidOverlap nonUniqueEnclosingIRFunction fieldAddressOnNonPointer thisArgumentIsNonPointer +| ir.cpp:2546:34:2546:34 | Call: call to operator bool | Call instruction 'Call: call to operator bool' has a `this` argument operand that is not an address, in function '$@'. | ir.cpp:2545:6:2545:23 | void this_inconsistency(bool) | void this_inconsistency(bool) | nonUniqueIRVariable | coroutines.cpp:87:20:87:20 | VariableAddress: (unnamed local variable) | Variable address instruction 'VariableAddress: (unnamed local variable)' has no associated variable, in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() | | coroutines.cpp:87:20:87:20 | VariableAddress: (unnamed local variable) | Variable address instruction 'VariableAddress: (unnamed local variable)' has no associated variable, in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() | diff --git a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected index eabbc4c30647..434da18f6beb 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -16615,6 +16615,90 @@ ir.cpp: # 2534| v2534_7(void) = ReturnVoid : #-----| Goto -> Block 1 +# 2545| void this_inconsistency(bool) +# 2545| Block 0 +# 2545| v2545_1(void) = EnterFunction : +# 2545| mu2545_2(unknown) = AliasedDefinition : +# 2545| mu2545_3(unknown) = InitializeNonLocal : +# 2545| r2545_4(glval) = VariableAddress[b] : +# 2545| mu2545_5(bool) = InitializeParameter[b] : &:r2545_4 +# 2546| r2546_1(glval) = VariableAddress[a] : +# 2546| r2546_2(glval) = VariableAddress[#temp2546:38] : +# 2546| r2546_3(glval) = FunctionAddress[getClassWithDestructor] : +# 2546| r2546_4(ClassWithDestructor) = Call[getClassWithDestructor] : func:r2546_3 +# 2546| mu2546_5(unknown) = ^CallSideEffect : ~m? +# 2546| mu2546_6(ClassWithDestructor) = Store[#temp2546:38] : &:r2546_2, r2546_4 +# 2546| r2546_7(glval) = Convert : r2546_2 +# 2546| r2546_8(ClassWithDestructor &) = CopyValue : r2546_7 +# 2546| mu2546_9(ClassWithDestructor &) = Store[a] : &:r2546_1, r2546_8 +# 2546| r2546_10(glval) = VariableAddress[a] : +# 2546| r2546_11(ClassWithDestructor &) = Load[a] : &:r2546_10, ~m? +# 2546| r2546_12(ClassWithDestructor) = CopyValue : r2546_11 +# 2546| r2546_13(glval) = FunctionAddress[operator bool] : +# 2546| r2546_14(bool) = Call[operator bool] : func:r2546_13, this:r2546_12 +# 2546| mu2546_15(unknown) = ^CallSideEffect : ~m? +# 2546| v2546_16(void) = ^IndirectReadSideEffect[-1] : &:r2546_12, ~m? +# 2546| r2546_17(bool) = CopyValue : r2546_14 +# 2546| v2546_18(void) = ConditionalBranch : r2546_17 +#-----| False -> Block 2 +#-----| True -> Block 1 + +# 2547| Block 1 +# 2547| v2547_1(void) = NoOp : +# 2547| r2547_2(glval) = CopyValue : r2546_2 +# 2547| r2547_3(glval) = FunctionAddress[~ClassWithDestructor] : +# 2547| v2547_4(void) = Call[~ClassWithDestructor] : func:r2547_3, this:r2547_2 +# 2547| mu2547_5(unknown) = ^CallSideEffect : ~m? +# 2547| v2547_6(void) = ^IndirectReadSideEffect[-1] : &:r2547_2, ~m? +# 2547| mu2547_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2547_2 +#-----| Goto -> Block 2 + +# 2548| Block 2 +# 2548| v2548_1(void) = NoOp : +# 2545| v2545_6(void) = ReturnVoid : +# 2545| v2545_7(void) = AliasedUse : ~m? +# 2545| v2545_8(void) = ExitFunction : + +# 2550| void constexpr_inconsistency(bool) +# 2550| Block 0 +# 2550| v2550_1(void) = EnterFunction : +# 2550| mu2550_2(unknown) = AliasedDefinition : +# 2550| mu2550_3(unknown) = InitializeNonLocal : +# 2550| r2550_4(glval) = VariableAddress[b] : +# 2550| mu2550_5(bool) = InitializeParameter[b] : &:r2550_4 +# 2551| r2551_1(glval) = VariableAddress[a] : +# 2551| r2551_2(glval) = VariableAddress[#temp2551:48] : +# 2551| r2551_3(glval) = FunctionAddress[getClassWithDestructor] : +# 2551| r2551_4(ClassWithDestructor) = Call[getClassWithDestructor] : func:r2551_3 +# 2551| mu2551_5(unknown) = ^CallSideEffect : ~m? +# 2551| mu2551_6(ClassWithDestructor) = Store[#temp2551:48] : &:r2551_2, r2551_4 +# 2551| r2551_7(glval) = Convert : r2551_2 +# 2551| r2551_8(ClassWithDestructor &) = CopyValue : r2551_7 +# 2551| mu2551_9(ClassWithDestructor &) = Store[a] : &:r2551_1, r2551_8 +# 2551| r2551_10(bool) = Constant[1] : +# 2551| v2551_11(void) = ConditionalBranch : r2551_10 +#-----| False -> Block 3 +#-----| True -> Block 1 + +# 2552| Block 1 +# 2552| v2552_1(void) = NoOp : +#-----| Goto -> Block 3 + +# 2552| Block 2 +# 2552| r2552_2(glval) = CopyValue : r2551_2 +# 2552| r2552_3(glval) = FunctionAddress[~ClassWithDestructor] : +# 2552| v2552_4(void) = Call[~ClassWithDestructor] : func:r2552_3, this:r2552_2 +# 2552| mu2552_5(unknown) = ^CallSideEffect : ~m? +# 2552| v2552_6(void) = ^IndirectReadSideEffect[-1] : &:r2552_2, ~m? +# 2552| mu2552_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2552_2 +#-----| Goto -> Block 3 + +# 2553| Block 3 +# 2553| v2553_1(void) = NoOp : +# 2550| v2550_6(void) = ReturnVoid : +# 2550| v2550_7(void) = AliasedUse : ~m? +# 2550| v2550_8(void) = ExitFunction : + perf-regression.cpp: # 6| void Big::Big() # 6| Block 0 diff --git a/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_consistency.expected b/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_consistency.expected index 8f472b49f273..5a0234a4cc42 100644 --- a/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_consistency.expected +++ b/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_consistency.expected @@ -27,6 +27,7 @@ invalidOverlap nonUniqueEnclosingIRFunction fieldAddressOnNonPointer thisArgumentIsNonPointer +| ir.cpp:2546:34:2546:34 | Call: call to operator bool | Call instruction 'Call: call to operator bool' has a `this` argument operand that is not an address, in function '$@'. | ir.cpp:2545:6:2545:23 | void this_inconsistency(bool) | void this_inconsistency(bool) | nonUniqueIRVariable | coroutines.cpp:87:20:87:20 | VariableAddress: (unnamed local variable) | Variable address instruction 'VariableAddress: (unnamed local variable)' has no associated variable, in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() | | coroutines.cpp:87:20:87:20 | VariableAddress: (unnamed local variable) | Variable address instruction 'VariableAddress: (unnamed local variable)' has no associated variable, in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() | diff --git a/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_consistency_unsound.expected b/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_consistency_unsound.expected index 8f472b49f273..5a0234a4cc42 100644 --- a/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_consistency_unsound.expected +++ b/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_consistency_unsound.expected @@ -27,6 +27,7 @@ invalidOverlap nonUniqueEnclosingIRFunction fieldAddressOnNonPointer thisArgumentIsNonPointer +| ir.cpp:2546:34:2546:34 | Call: call to operator bool | Call instruction 'Call: call to operator bool' has a `this` argument operand that is not an address, in function '$@'. | ir.cpp:2545:6:2545:23 | void this_inconsistency(bool) | void this_inconsistency(bool) | nonUniqueIRVariable | coroutines.cpp:87:20:87:20 | VariableAddress: (unnamed local variable) | Variable address instruction 'VariableAddress: (unnamed local variable)' has no associated variable, in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() | | coroutines.cpp:87:20:87:20 | VariableAddress: (unnamed local variable) | Variable address instruction 'VariableAddress: (unnamed local variable)' has no associated variable, in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() |