From 5dd0addfc2953fb64e7495b10a2470dd400c09cc Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Fri, 19 Jan 2024 15:44:28 +0000 Subject: [PATCH 01/50] Add sensitive text flow query --- .../code/java/security/SensitiveUiQuery.qll | 35 +++++++++++++++++++ .../CWE/CWE-200/AndroidSensitiveTextField.ql | 20 +++++++++++ 2 files changed, 55 insertions(+) create mode 100644 java/ql/src/Security/CWE/CWE-200/AndroidSensitiveTextField.ql diff --git a/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll b/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll index eb49adfa10d..f4c8df6dc73 100644 --- a/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll @@ -20,3 +20,38 @@ private module NotificationTrackingConfig implements DataFlow::ConfigSig { /** Taint tracking flow for sensitive data flowing to system notifications. */ module NotificationTracking = TaintTracking::Global; + +/** A call to a method that sets the text of a `TextView`. */ +private class SetTextCall extends MethodCall { + SetTextCall() { + this.getMethod() + .getAnOverride*() + .hasQualifiedName("android.widget", "TextView", ["append", "setText", "setHint"]) and + ( + this.getMethod() + .getParameter(0) + .getType() + .(RefType) + .hasQualifiedName("java.lang", "CharSequence") + or + this.getMethod().getParameter(0).getType().(Array).getElementType() instanceof CharacterType + ) + } + + /** Gets the string argument of this call. */ + Expr getStringArgument() { result = this.getArgument(0) } +} + +/** 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.asExpr() = any(SetTextCall s).getStringArgument() } + + predicate isBarrier(DataFlow::Node node) { + node.getType() instanceof PrimitiveType or node.getType() instanceof BoxedType + } +} + +/** Taint tracking flow for sensitive data flowing to text fields. */ +module TextFieldTracking = TaintTracking::Global; diff --git a/java/ql/src/Security/CWE/CWE-200/AndroidSensitiveTextField.ql b/java/ql/src/Security/CWE/CWE-200/AndroidSensitiveTextField.ql new file mode 100644 index 00000000000..6711a037bcb --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-200/AndroidSensitiveTextField.ql @@ -0,0 +1,20 @@ +/** + * @name Exposure of sensitive information to UI text fields. + * @id java/android/sensitive-text + * @kind path-problem + * @description Sensitive information ... TODO + * @problem.severity warning + * @precision medium + * @security-severity 6.5 + * @tags security + * external/cwe/cwe-200 + */ + +import java +import java +import semmle.code.java.security.SensitiveUiQuery +import TextFieldTracking::PathGraph + +from TextFieldTracking::PathNode source, TextFieldTracking::PathNode sink +where NotificationTracking::flowPath(source, sink) +select sink, source, sink, "This $@ is exposed in a text view.", source, "sensitive information" From 1b13597d72657881f4b5808f83a88713f1103bf0 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Fri, 19 Jan 2024 17:45:39 +0000 Subject: [PATCH 02/50] Implement checks for calls that may safely mask information --- .../code/java/frameworks/android/Layout.qll | 69 +++++++++++++++++++ .../security/SensitiveKeyboardCacheQuery.qll | 66 +----------------- .../code/java/security/SensitiveUiQuery.qll | 25 ++++++- 3 files changed, 94 insertions(+), 66 deletions(-) create mode 100644 java/ql/lib/semmle/code/java/frameworks/android/Layout.qll diff --git a/java/ql/lib/semmle/code/java/frameworks/android/Layout.qll b/java/ql/lib/semmle/code/java/frameworks/android/Layout.qll new file mode 100644 index 00000000000..b1489b4cebb --- /dev/null +++ b/java/ql/lib/semmle/code/java/frameworks/android/Layout.qll @@ -0,0 +1,69 @@ +/** Provides classes and predicates for working with Android layouts and UI elements. */ + +import java +import semmle.code.xml.AndroidManifest +private import semmle.code.java.dataflow.DataFlow + +/** An Android Layout XML file. */ +class AndroidLayoutXmlFile extends XmlFile { + AndroidLayoutXmlFile() { this.getRelativePath().matches("%/res/layout/%.xml") } +} + +/** A component declared in an Android layout file. */ +class AndroidLayoutXmlElement extends XmlElement { + AndroidXmlAttribute id; + + AndroidLayoutXmlElement() { + this.getFile() instanceof AndroidLayoutXmlFile and + id = this.getAttribute("id") + } + + /** Gets the ID of this component. */ + string getId() { result = id.getValue() } + + /** Gets the class of this component. */ + Class getClass() { + this.getName() = "view" and + this.getAttribute("class").getValue() = result.getQualifiedName() + or + this.getName() = result.getQualifiedName() + or + result.hasQualifiedName(["android.widget", "android.view"], this.getName()) + } +} + +/** An XML element that represents an editable text field. */ +class AndroidEditableXmlElement extends AndroidLayoutXmlElement { + AndroidEditableXmlElement() { + this.getClass().getASourceSupertype*().hasQualifiedName("android.widget", "EditText") + } + + /** Gets the input type of this field, if any. */ + string getInputType() { result = this.getAttribute("inputType").(AndroidXmlAttribute).getValue() } +} + +/** A `findViewById` or `requireViewById` method on `Activity` or `View`. */ +private class FindViewMethod extends Method { + FindViewMethod() { + this.hasQualifiedName("android.view", "View", ["findViewById", "requireViewById"]) + or + exists(Method m | + m.hasQualifiedName("android.app", "Activity", ["findViewById", "requireViewById"]) and + this = m.getAnOverride*() + ) + } +} + +/** Gets a use of the view that has the given id. (i.e. from a call to a method like `findViewById`) */ +MethodCall getAUseOfViewWithId(string id) { + exists(string name, NestedClass r_id, Field id_field | + id = "@+id/" + name and + result.getMethod() instanceof FindViewMethod and + r_id.getEnclosingType().hasName("R") and + r_id.hasName("id") and + id_field.getDeclaringType() = r_id and + id_field.hasName(name) + | + DataFlow::localExprFlow(id_field.getAnAccess(), result.getArgument(0)) + ) +} diff --git a/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll b/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll index 498a746a30a..610fb4d6b4d 100644 --- a/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll @@ -3,71 +3,7 @@ import java import semmle.code.java.dataflow.DataFlow import semmle.code.java.security.SensitiveActions -import semmle.code.xml.AndroidManifest - -/** An Android Layout XML file. */ -private class AndroidLayoutXmlFile extends XmlFile { - AndroidLayoutXmlFile() { this.getRelativePath().matches("%/res/layout/%.xml") } -} - -/** A component declared in an Android layout file. */ -class AndroidLayoutXmlElement extends XmlElement { - AndroidXmlAttribute id; - - AndroidLayoutXmlElement() { - this.getFile() instanceof AndroidLayoutXmlFile and - id = this.getAttribute("id") - } - - /** Gets the ID of this component. */ - string getId() { result = id.getValue() } - - /** Gets the class of this component. */ - Class getClass() { - this.getName() = "view" and - this.getAttribute("class").getValue() = result.getQualifiedName() - or - this.getName() = result.getQualifiedName() - or - result.hasQualifiedName(["android.widget", "android.view"], this.getName()) - } -} - -/** An XML element that represents an editable text field. */ -class AndroidEditableXmlElement extends AndroidLayoutXmlElement { - AndroidEditableXmlElement() { - this.getClass().getASourceSupertype*().hasQualifiedName("android.widget", "EditText") - } - - /** Gets the input type of this field, if any. */ - string getInputType() { result = this.getAttribute("inputType").(AndroidXmlAttribute).getValue() } -} - -/** A `findViewById` or `requireViewById` method on `Activity` or `View`. */ -private class FindViewMethod extends Method { - FindViewMethod() { - this.hasQualifiedName("android.view", "View", ["findViewById", "requireViewById"]) - or - exists(Method m | - m.hasQualifiedName("android.app", "Activity", ["findViewById", "requireViewById"]) and - this = m.getAnOverride*() - ) - } -} - -/** Gets a use of the view that has the given id. */ -private MethodCall getAUseOfViewWithId(string id) { - exists(string name, NestedClass r_id, Field id_field | - id = "@+id/" + name and - result.getMethod() instanceof FindViewMethod and - r_id.getEnclosingType().hasName("R") and - r_id.hasName("id") and - id_field.getDeclaringType() = r_id and - id_field.hasName(name) - | - DataFlow::localExprFlow(id_field.getAnAccess(), result.getArgument(0)) - ) -} +import semmle.code.java.frameworks.android.Layout /** Gets the argument of a use of `setInputType` called on the view with the given id. */ private Argument setInputTypeForId(string id) { diff --git a/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll b/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll index f4c8df6dc73..75d84148373 100644 --- a/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll @@ -4,6 +4,7 @@ import java private import semmle.code.java.dataflow.ExternalFlow private import semmle.code.java.dataflow.TaintTracking private import semmle.code.java.security.SensitiveActions +private import semmle.code.java.frameworks.android.Layout /** A configuration for tracking sensitive information to system notifications. */ private module NotificationTrackingConfig implements DataFlow::ConfigSig { @@ -42,16 +43,38 @@ private class SetTextCall extends MethodCall { Expr getStringArgument() { result = this.getArgument(0) } } +/** A call to a method indicating that the contents of a UI element are safely masked. */ +private class MaskCall extends MethodCall { + MaskCall() { + this.getMethod().hasQualifiedName("android.widget", "TextView", "setInputType") + or + this.getMethod().hasQualifiedName("android.widget", "view", "setVisibility") + } +} + /** 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.asExpr() = any(SetTextCall s).getStringArgument() } + predicate isSink(DataFlow::Node sink) { + exists(SetTextCall call | + sink.asExpr() = call.getStringArgument() and + not isMasked(call) + ) + } predicate isBarrier(DataFlow::Node node) { node.getType() instanceof PrimitiveType or node.getType() instanceof BoxedType } } +/** Holds if the qualifier of `call` is also called with a method that may mask the information displayed. */ +private predicate isMasked(SetTextCall call) { + exists(string id | + DataFlow::localExprFlow(getAUseOfViewWithId(id), call.getQualifier()) and + DataFlow::localExprFlow(getAUseOfViewWithId(id), any(MaskCall mcall).getQualifier()) + ) +} + /** Taint tracking flow for sensitive data flowing to text fields. */ module TextFieldTracking = TaintTracking::Global; From 8582093e651605831270d0c93e5410a7bc7f0cde Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Mon, 22 Jan 2024 14:52:53 +0000 Subject: [PATCH 03/50] Implement checks for parent views being hidden --- .../code/java/security/SensitiveUiQuery.qll | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll b/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll index 75d84148373..7b45f9efef2 100644 --- a/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll @@ -59,7 +59,7 @@ private module TextFieldTrackingConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { exists(SetTextCall call | sink.asExpr() = call.getStringArgument() and - not isMasked(call) + not setTextCallIsMasked(call) ) } @@ -68,13 +68,18 @@ private module TextFieldTrackingConfig implements DataFlow::ConfigSig { } } +/** Holds if the given may be masked. */ +private predicate viewIsMasked(AndroidLayoutXmlElement view) { + DataFlow::localExprFlow(getAUseOfViewWithId(view.getId()), any(MaskCall mcall).getQualifier()) +} + /** Holds if the qualifier of `call` is also called with a method that may mask the information displayed. */ -private predicate isMasked(SetTextCall call) { - exists(string id | - DataFlow::localExprFlow(getAUseOfViewWithId(id), call.getQualifier()) and - DataFlow::localExprFlow(getAUseOfViewWithId(id), any(MaskCall mcall).getQualifier()) +private predicate setTextCallIsMasked(SetTextCall call) { + exists(AndroidLayoutXmlElement view | + DataFlow::localExprFlow(getAUseOfViewWithId(view.getId()), call.getQualifier()) and + viewIsMasked(view.getParent*()) ) } /** Taint tracking flow for sensitive data flowing to text fields. */ -module TextFieldTracking = TaintTracking::Global; +module TextFieldTracking = TaintTracking::Global; From 6081f180899462701e36fcbecc8cc26412c3ea89 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Tue, 23 Jan 2024 09:38:48 +0000 Subject: [PATCH 04/50] Add unit tests + make some fixes --- .../code/java/security/SensitiveUiQuery.qll | 6 +- .../CWE/CWE-200/AndroidSensitiveTextField.ql | 2 +- .../SensitiveTextView/AndroidManifest.xml | 5 ++ .../semmle/tests/SensitiveTextView/R.java | 15 ++++ .../semmle/tests/SensitiveTextView/Test.java | 31 +++++++++ .../semmle/tests/SensitiveTextView/options | 1 + .../SensitiveTextView/res/layout/Test.xml | 23 +++++++ .../tests/SensitiveTextView/test.expected | 2 + .../semmle/tests/SensitiveTextView/test.ql | 19 ++++++ .../android/widget/LinearLayout.java | 68 +++++++++++++++++++ 10 files changed, 169 insertions(+), 3 deletions(-) create mode 100644 java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/AndroidManifest.xml create mode 100644 java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/R.java create mode 100644 java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/Test.java create mode 100644 java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/options create mode 100644 java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/res/layout/Test.xml create mode 100644 java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/test.expected create mode 100644 java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/test.ql create mode 100644 java/ql/test/stubs/google-android-9.0.0/android/widget/LinearLayout.java diff --git a/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll b/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll index 7b45f9efef2..b9add152cfc 100644 --- a/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll @@ -46,9 +46,9 @@ private class SetTextCall extends MethodCall { /** A call to a method indicating that the contents of a UI element are safely masked. */ private class MaskCall extends MethodCall { MaskCall() { - this.getMethod().hasQualifiedName("android.widget", "TextView", "setInputType") + this.getMethod().getAnOverride*().hasQualifiedName("android.widget", "TextView", "setInputType") or - this.getMethod().hasQualifiedName("android.widget", "view", "setVisibility") + this.getMethod().getAnOverride*().hasQualifiedName("android.view", "View", "setVisibility") } } @@ -66,6 +66,8 @@ private module TextFieldTrackingConfig implements DataFlow::ConfigSig { predicate isBarrier(DataFlow::Node node) { node.getType() instanceof PrimitiveType or node.getType() instanceof BoxedType } + + predicate isBarrierIn(DataFlow::Node node) { isSource(node) } } /** Holds if the given may be masked. */ diff --git a/java/ql/src/Security/CWE/CWE-200/AndroidSensitiveTextField.ql b/java/ql/src/Security/CWE/CWE-200/AndroidSensitiveTextField.ql index 6711a037bcb..99f15125ead 100644 --- a/java/ql/src/Security/CWE/CWE-200/AndroidSensitiveTextField.ql +++ b/java/ql/src/Security/CWE/CWE-200/AndroidSensitiveTextField.ql @@ -16,5 +16,5 @@ import semmle.code.java.security.SensitiveUiQuery import TextFieldTracking::PathGraph from TextFieldTracking::PathNode source, TextFieldTracking::PathNode sink -where NotificationTracking::flowPath(source, sink) +where TextFieldTracking::flowPath(source, sink) select sink, source, sink, "This $@ is exposed in a text view.", source, "sensitive information" diff --git a/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/AndroidManifest.xml b/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/AndroidManifest.xml new file mode 100644 index 00000000000..54b933452c8 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/AndroidManifest.xml @@ -0,0 +1,5 @@ + + + \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/R.java b/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/R.java new file mode 100644 index 00000000000..19d727c1c8a --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/R.java @@ -0,0 +1,15 @@ +package com.example.test; + +public final class R { + public static final class id { + public static final int test1 = 1; + public static final int test2 = 2; + public static final int test3 = 3; + public static final int test4 = 4; + public static final int test5 = 5; + } + + public static final class string { + public static final int password_prompt = 0; + } +} \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/Test.java b/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/Test.java new file mode 100644 index 00000000000..46ff773eb32 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/Test.java @@ -0,0 +1,31 @@ +package com.example.test; + +import android.app.Activity; +import android.widget.EditText; +import android.widget.TextView; +import android.widget.LinearLayout; +import android.view.View; +import android.text.InputType; + +class Test extends Activity { + void test(String password) { + EditText test1 = findViewById(R.id.test1); + test1.setText(password); // $sensitive-text + test1.setHint(password); // $sensitive-text + test1.append(password); // $sensitive-text + test1.setText(R.string.password_prompt); + + TextView test2 = findViewById(R.id.test2); + test2.setVisibility(View.INVISIBLE); + test2.setText(password); + + EditText test3 = findViewById(R.id.test3); + test3.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); + test3.setText(password); + + LinearLayout test4 = findViewById(R.id.test4); + TextView test5 = findViewById(R.id.test5); + test4.setVisibility(View.INVISIBLE); + test5.setText(password); + } +} \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/options b/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/options new file mode 100644 index 00000000000..cce20967940 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/options @@ -0,0 +1 @@ +//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../../stubs/google-android-9.0.0 diff --git a/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/res/layout/Test.xml b/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/res/layout/Test.xml new file mode 100644 index 00000000000..badf8019c3b --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/res/layout/Test.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/test.expected b/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/test.expected new file mode 100644 index 00000000000..8ec8033d086 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/test.expected @@ -0,0 +1,2 @@ +testFailures +failures diff --git a/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/test.ql b/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/test.ql new file mode 100644 index 00000000000..49ccd889b85 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/test.ql @@ -0,0 +1,19 @@ +import java +import TestUtilities.InlineExpectationsTest +import semmle.code.java.dataflow.DataFlow +import semmle.code.java.security.SensitiveUiQuery + +module SensitiveTextTest implements TestSig { + string getARelevantTag() { result = "sensitive-text" } + + predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "sensitive-text" and + exists(DataFlow::Node sink | TextFieldTracking::flowTo(sink) | + sink.getLocation() = location and + element = sink.toString() and + value = "" + ) + } +} + +import MakeTest diff --git a/java/ql/test/stubs/google-android-9.0.0/android/widget/LinearLayout.java b/java/ql/test/stubs/google-android-9.0.0/android/widget/LinearLayout.java new file mode 100644 index 00000000000..c9bbe6c217a --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/android/widget/LinearLayout.java @@ -0,0 +1,68 @@ +// Generated automatically from android.widget.LinearLayout for testing purposes + +package android.widget; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.view.ViewGroup; + +public class LinearLayout extends ViewGroup +{ + protected LinearLayout() {} + protected LinearLayout.LayoutParams generateDefaultLayoutParams(){ return null; } + protected LinearLayout.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p0){ return null; } + protected boolean checkLayoutParams(ViewGroup.LayoutParams p0){ return false; } + protected void onDraw(Canvas p0){} + protected void onLayout(boolean p0, int p1, int p2, int p3, int p4){} + protected void onMeasure(int p0, int p1){} + public CharSequence getAccessibilityClassName(){ return null; } + public Drawable getDividerDrawable(){ return null; } + public LinearLayout(Context p0){} + public LinearLayout(Context p0, AttributeSet p1){} + public LinearLayout(Context p0, AttributeSet p1, int p2){} + public LinearLayout(Context p0, AttributeSet p1, int p2, int p3){} + public LinearLayout.LayoutParams generateLayoutParams(AttributeSet p0){ return null; } + public boolean isBaselineAligned(){ return false; } + public boolean isMeasureWithLargestChildEnabled(){ return false; } + public boolean shouldDelayChildPressedState(){ return false; } + public float getWeightSum(){ return 0; } + public int getBaseline(){ return 0; } + public int getBaselineAlignedChildIndex(){ return 0; } + public int getDividerPadding(){ return 0; } + public int getGravity(){ return 0; } + public int getOrientation(){ return 0; } + public int getShowDividers(){ return 0; } + public static int HORIZONTAL = 0; + public static int SHOW_DIVIDER_BEGINNING = 0; + public static int SHOW_DIVIDER_END = 0; + public static int SHOW_DIVIDER_MIDDLE = 0; + public static int SHOW_DIVIDER_NONE = 0; + public static int VERTICAL = 0; + public void onRtlPropertiesChanged(int p0){} + public void setBaselineAligned(boolean p0){} + public void setBaselineAlignedChildIndex(int p0){} + public void setDividerDrawable(Drawable p0){} + public void setDividerPadding(int p0){} + public void setGravity(int p0){} + public void setHorizontalGravity(int p0){} + public void setMeasureWithLargestChildEnabled(boolean p0){} + public void setOrientation(int p0){} + public void setShowDividers(int p0){} + public void setVerticalGravity(int p0){} + public void setWeightSum(float p0){} + static public class LayoutParams extends ViewGroup.MarginLayoutParams + { + protected LayoutParams() {} + public LayoutParams(Context p0, AttributeSet p1){} + public LayoutParams(LinearLayout.LayoutParams p0){} + public LayoutParams(ViewGroup.LayoutParams p0){} + public LayoutParams(ViewGroup.MarginLayoutParams p0){} + public LayoutParams(int p0, int p1){} + public LayoutParams(int p0, int p1, float p2){} + public String debug(String p0){ return null; } + public float weight = 0; + public int gravity = 0; + } +} From aa7805093389718f8a06a0f96b8011606cc96042 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Wed, 24 Jan 2024 13:31:06 +0000 Subject: [PATCH 05/50] Implement checks for elements hidden by their xml attributes --- .../code/java/frameworks/android/Layout.qll | 11 ++---- .../code/java/security/SensitiveUiQuery.qll | 8 +++++ .../semmle/tests/SensitiveTextView/R.java | 7 ++++ .../semmle/tests/SensitiveTextView/Test.java | 35 ++++++++++++++++++- .../SensitiveTextView/res/layout/Test.xml | 30 ++++++++++++++++ 5 files changed, 82 insertions(+), 9 deletions(-) diff --git a/java/ql/lib/semmle/code/java/frameworks/android/Layout.qll b/java/ql/lib/semmle/code/java/frameworks/android/Layout.qll index b1489b4cebb..3d09ff82367 100644 --- a/java/ql/lib/semmle/code/java/frameworks/android/Layout.qll +++ b/java/ql/lib/semmle/code/java/frameworks/android/Layout.qll @@ -11,15 +11,10 @@ class AndroidLayoutXmlFile extends XmlFile { /** A component declared in an Android layout file. */ class AndroidLayoutXmlElement extends XmlElement { - AndroidXmlAttribute id; + AndroidLayoutXmlElement() { this.getFile() instanceof AndroidLayoutXmlFile } - AndroidLayoutXmlElement() { - this.getFile() instanceof AndroidLayoutXmlFile and - id = this.getAttribute("id") - } - - /** Gets the ID of this component. */ - string getId() { result = id.getValue() } + /** Gets the ID of this component, if any. */ + string getId() { result = this.getAttribute("id").getValue() } /** Gets the class of this component. */ Class getClass() { diff --git a/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll b/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll index b9add152cfc..59dac4fcb56 100644 --- a/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll @@ -73,6 +73,14 @@ private module TextFieldTrackingConfig implements DataFlow::ConfigSig { /** Holds if the given may be masked. */ private predicate viewIsMasked(AndroidLayoutXmlElement view) { DataFlow::localExprFlow(getAUseOfViewWithId(view.getId()), any(MaskCall mcall).getQualifier()) + or + view.getAttribute("inputType") + .(AndroidXmlAttribute) + .getValue() + .regexpMatch("(?i).*(text|number)(web)?password.*") + or + view.getAttribute("visibility").(AndroidXmlAttribute).getValue().toLowerCase() = + ["invisible", "gone"] } /** Holds if the qualifier of `call` is also called with a method that may mask the information displayed. */ diff --git a/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/R.java b/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/R.java index 19d727c1c8a..fba7620e53d 100644 --- a/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/R.java +++ b/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/R.java @@ -7,6 +7,13 @@ public final class R { public static final int test3 = 3; public static final int test4 = 4; public static final int test5 = 5; + public static final int test6 = 6; + public static final int test7 = 7; + public static final int test8 = 8; + public static final int test9 = 9; + public static final int test10 = 10; + public static final int test11 = 11; + public static final int test12 = 12; } public static final class string { diff --git a/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/Test.java b/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/Test.java index 46ff773eb32..530a2c77a75 100644 --- a/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/Test.java +++ b/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/Test.java @@ -10,22 +10,55 @@ import android.text.InputType; class Test extends Activity { void test(String password) { EditText test1 = findViewById(R.id.test1); + // BAD: Exposing sensitive data to text view test1.setText(password); // $sensitive-text test1.setHint(password); // $sensitive-text test1.append(password); // $sensitive-text - test1.setText(R.string.password_prompt); + // GOOD: resource constant is not sensitive info + test1.setText(R.string.password_prompt); + // GOOD: Visibility is dynamically set TextView test2 = findViewById(R.id.test2); test2.setVisibility(View.INVISIBLE); test2.setText(password); + // GOOD: Input type is dynamically set EditText test3 = findViewById(R.id.test3); test3.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); test3.setText(password); + // GOOD: Visibility of parent is dynamically set LinearLayout test4 = findViewById(R.id.test4); TextView test5 = findViewById(R.id.test5); test4.setVisibility(View.INVISIBLE); test5.setText(password); + + // GOOD: Input type set to textPassword in XML + EditText test6 = findViewById(R.id.test6); + test6.setText(password); + + // GOOD: Input type set to textWebPassword in XML + EditText test7 = findViewById(R.id.test7); + test7.setText(password); + + // GOOD: Input type set to numberPassword in XML + EditText test8 = findViewById(R.id.test8); + test8.setText(password); + + // BAD: Input type set to textVisiblePassword in XML, which is not hidden + EditText test9 = findViewById(R.id.test9); + test9.setText(password); // $sensitive-text + + // GOOD: Visibility set to invisible in XML + EditText test10 = findViewById(R.id.test10); + test10.setText(password); + + // GOOD: Visibility set to gone in XML + EditText test11 = findViewById(R.id.test11); + test11.setText(password); + + // GOOD: Visibility of parent set to invisible in XML + EditText test12 = findViewById(R.id.test12); + test12.setText(password); } } \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/res/layout/Test.xml b/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/res/layout/Test.xml index badf8019c3b..105d3209e5a 100644 --- a/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/res/layout/Test.xml +++ b/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/res/layout/Test.xml @@ -20,4 +20,34 @@ android:id="@+id/test5"/> + + + + + + + + + + + + + + + + \ No newline at end of file From 8d201626e1b76ce7ebcafb2897ede4a7bea54ad6 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Wed, 24 Jan 2024 14:10:28 +0000 Subject: [PATCH 06/50] Add documentation --- .../CWE/CWE-200/AndroidSensitiveTextBad.java | 2 + .../CWE-200/AndroidSensitiveTextField.qhelp | 38 +++++++++++++++++++ .../CWE/CWE-200/AndroidSensitiveTextField.ql | 4 +- .../CWE/CWE-200/AndroidSensitiveTextGood.java | 10 +++++ 4 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 java/ql/src/Security/CWE/CWE-200/AndroidSensitiveTextBad.java create mode 100644 java/ql/src/Security/CWE/CWE-200/AndroidSensitiveTextField.qhelp create mode 100644 java/ql/src/Security/CWE/CWE-200/AndroidSensitiveTextGood.java diff --git a/java/ql/src/Security/CWE/CWE-200/AndroidSensitiveTextBad.java b/java/ql/src/Security/CWE/CWE-200/AndroidSensitiveTextBad.java new file mode 100644 index 00000000000..d94e667b3db --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-200/AndroidSensitiveTextBad.java @@ -0,0 +1,2 @@ +TextView pwView = getViewById(R.id.pw_text); +pwView.setText("Your password is: " + password); \ No newline at end of file diff --git a/java/ql/src/Security/CWE/CWE-200/AndroidSensitiveTextField.qhelp b/java/ql/src/Security/CWE/CWE-200/AndroidSensitiveTextField.qhelp new file mode 100644 index 00000000000..dc4f30a1dce --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-200/AndroidSensitiveTextField.qhelp @@ -0,0 +1,38 @@ + + + +

+ Sensitive information such as passwords should not be displayed in UI components unless explicitly required, to mitigate shoulder-surfing attacks. +

+
+ + +

+ For editable text fields containing sensitive information, the inputType should be set to textPassword or similar to ensure it is properly masked. + Otherwise, sensitive data that is required to be displayed should be hidden by default, and only revealed based on an explicit user action. +

+
+ + +

+ In the following (bad) case, sensitive information password is exposed to the TextView. +

+ + + +

+ In the following (good) case, the user must press a button to reveal sensitive information. +

+ + +
+ + +
  • + OWASP Mobile Application Security: Android Data Storage - UI Components +
  • +
    + +
    diff --git a/java/ql/src/Security/CWE/CWE-200/AndroidSensitiveTextField.ql b/java/ql/src/Security/CWE/CWE-200/AndroidSensitiveTextField.ql index 99f15125ead..0311192740c 100644 --- a/java/ql/src/Security/CWE/CWE-200/AndroidSensitiveTextField.ql +++ b/java/ql/src/Security/CWE/CWE-200/AndroidSensitiveTextField.ql @@ -1,8 +1,8 @@ /** - * @name Exposure of sensitive information to UI text fields. + * @name Exposure of sensitive information to UI text views. * @id java/android/sensitive-text * @kind path-problem - * @description Sensitive information ... TODO + * @description Sensitive information displayed in UI text views should be properly masked. * @problem.severity warning * @precision medium * @security-severity 6.5 diff --git a/java/ql/src/Security/CWE/CWE-200/AndroidSensitiveTextGood.java b/java/ql/src/Security/CWE/CWE-200/AndroidSensitiveTextGood.java new file mode 100644 index 00000000000..507fdae731c --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-200/AndroidSensitiveTextGood.java @@ -0,0 +1,10 @@ +TextView pwView = findViewById(R.id.pw_text); +pwView.setVisibility(View.INVISIBLE); +pwView.setText("Your password is: " + password); + +Button showButton = findViewById(R.id.show_pw_button); +showButton.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + pwView.setVisibility(View.VISIBLE); + } +}); From 94075ef14846cd235ea244851907dbbe2f85ec06 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Mon, 29 Jan 2024 15:37:44 +0000 Subject: [PATCH 07/50] Fix FPs - consider flow through fields when determining whether a view is masked, and find more instances of findViewById. --- .../code/java/frameworks/android/Layout.qll | 13 +++++---- .../code/java/security/SensitiveUiQuery.qll | 29 ++++++++++++++++--- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/java/ql/lib/semmle/code/java/frameworks/android/Layout.qll b/java/ql/lib/semmle/code/java/frameworks/android/Layout.qll index 3d09ff82367..8993c8cd87d 100644 --- a/java/ql/lib/semmle/code/java/frameworks/android/Layout.qll +++ b/java/ql/lib/semmle/code/java/frameworks/android/Layout.qll @@ -40,11 +40,12 @@ class AndroidEditableXmlElement extends AndroidLayoutXmlElement { /** A `findViewById` or `requireViewById` method on `Activity` or `View`. */ private class FindViewMethod extends Method { FindViewMethod() { - this.hasQualifiedName("android.view", "View", ["findViewById", "requireViewById"]) - or - exists(Method m | - m.hasQualifiedName("android.app", "Activity", ["findViewById", "requireViewById"]) and - this = m.getAnOverride*() + exists(Method m | this.getAnOverride*() = m | + m.hasQualifiedName("android.app", "Activity", ["findViewById", "requireViewById"]) + or + m.hasQualifiedName("android.view", "View", ["findViewById", "requireViewById"]) + or + m.hasQualifiedName("android.app", "Dialog", ["findViewById", "requireViewById"]) ) } } @@ -52,7 +53,7 @@ private class FindViewMethod extends Method { /** Gets a use of the view that has the given id. (i.e. from a call to a method like `findViewById`) */ MethodCall getAUseOfViewWithId(string id) { exists(string name, NestedClass r_id, Field id_field | - id = "@+id/" + name and + id = ["@+id/", "@id/"] + name and result.getMethod() instanceof FindViewMethod and r_id.getEnclosingType().hasName("R") and r_id.hasName("id") and diff --git a/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll b/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll index 59dac4fcb56..ccbf622f557 100644 --- a/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll @@ -70,9 +70,30 @@ private module TextFieldTrackingConfig implements DataFlow::ConfigSig { predicate isBarrierIn(DataFlow::Node node) { isSource(node) } } -/** Holds if the given may be masked. */ +/** A local flow step that also flows through access to fields containing `View`s */ +private predicate localViewFieldFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + DataFlow::localFlowStep(node1, node2) + or + exists(Field f | + f.getType().(Class).getASupertype*().hasQualifiedName("android.view", "View") and + node1.asExpr() = f.getAnAccess().(FieldWrite).getASource() and + node2.asExpr() = f.getAnAccess().(FieldRead) + ) +} + +/** Holds if data can flow from `node1` to `node2` with local flow steps as well as flow through fields containing `View`s */ +private predicate localViewFieldFlow(DataFlow::Node node1, DataFlow::Node node2) { + localViewFieldFlowStep*(node1, node2) +} + +/** Holds if data can flow from `e1` to `e2` with local flow steps as well as flow through fields containing `View`s */ +private predicate localViewFieldExprFlow(Expr e1, Expr e2) { + localViewFieldFlow(DataFlow::exprNode(e1), DataFlow::exprNode(e2)) +} + +/** Holds if the given view may be properly masked. */ private predicate viewIsMasked(AndroidLayoutXmlElement view) { - DataFlow::localExprFlow(getAUseOfViewWithId(view.getId()), any(MaskCall mcall).getQualifier()) + localViewFieldExprFlow(getAUseOfViewWithId(view.getId()), any(MaskCall mcall).getQualifier()) or view.getAttribute("inputType") .(AndroidXmlAttribute) @@ -83,10 +104,10 @@ private predicate viewIsMasked(AndroidLayoutXmlElement view) { ["invisible", "gone"] } -/** Holds if the qualifier of `call` is also called with a method that may mask the information displayed. */ +/** Holds if the qualifier of `call` may be properly masked. */ private predicate setTextCallIsMasked(SetTextCall call) { exists(AndroidLayoutXmlElement view | - DataFlow::localExprFlow(getAUseOfViewWithId(view.getId()), call.getQualifier()) and + localViewFieldExprFlow(getAUseOfViewWithId(view.getId()), call.getQualifier()) and viewIsMasked(view.getParent*()) ) } From 3abd67064ddd97f737577f349a1217fb22a8ed07 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Mon, 29 Jan 2024 16:33:07 +0000 Subject: [PATCH 08/50] Add change note --- .../2024-01-29-android-sensitive-text-field-query.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 java/ql/src/change-notes/2024-01-29-android-sensitive-text-field-query.md diff --git a/java/ql/src/change-notes/2024-01-29-android-sensitive-text-field-query.md b/java/ql/src/change-notes/2024-01-29-android-sensitive-text-field-query.md new file mode 100644 index 00000000000..5e5156944a7 --- /dev/null +++ b/java/ql/src/change-notes/2024-01-29-android-sensitive-text-field-query.md @@ -0,0 +1,4 @@ +--- +category: newQuery +--- +* Added a new query `java/android/sensitive-text` to detect instances of sensitive data being exposed through text fields without being properly masked. \ No newline at end of file From 460ffc89b2100cbfca008086ec5430aae1ec5e6a Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Mon, 29 Jan 2024 22:43:28 +0000 Subject: [PATCH 09/50] Add additional test cases --- .../CWE-200/semmle/tests/SensitiveTextView/R.java | 2 ++ .../semmle/tests/SensitiveTextView/Test.java | 13 +++++++++++++ .../tests/SensitiveTextView/res/layout/Test.xml | 8 ++++++++ 3 files changed, 23 insertions(+) diff --git a/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/R.java b/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/R.java index fba7620e53d..68c91af13ce 100644 --- a/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/R.java +++ b/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/R.java @@ -14,6 +14,8 @@ public final class R { public static final int test10 = 10; public static final int test11 = 11; public static final int test12 = 12; + public static final int test13 = 13; + public static final int test14 = 14; } public static final class string { diff --git a/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/Test.java b/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/Test.java index 530a2c77a75..9b6ab9da35b 100644 --- a/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/Test.java +++ b/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/Test.java @@ -60,5 +60,18 @@ class Test extends Activity { // GOOD: Visibility of parent set to invisible in XML EditText test12 = findViewById(R.id.test12); test12.setText(password); + + // GOOD: Input type set to textPassword in XML + EditText test13 = findViewById(R.id.test13); + test13.setText(password); + + test14 = findViewById(R.id.test14); + } + + EditText test14; + + void test2(String password) { + // GOOD: Input type set to textPassword in XML + test14.setText(password); } } \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/res/layout/Test.xml b/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/res/layout/Test.xml index 105d3209e5a..989ad6369f0 100644 --- a/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/res/layout/Test.xml +++ b/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/res/layout/Test.xml @@ -50,4 +50,12 @@ android:id="@+id/test12"/> + + + + \ No newline at end of file From eb5e0123d6c55d19e94a9ead5c82fb34f1838577 Mon Sep 17 00:00:00 2001 From: James Ockers Date: Tue, 30 Jan 2024 13:16:18 -0800 Subject: [PATCH 10/50] exclude certification from maybeCertificate() regexes --- .../javascript/security/internal/SensitiveDataHeuristics.qll | 2 +- .../semmle/python/security/internal/SensitiveDataHeuristics.qll | 2 +- .../codeql/ruby/security/internal/SensitiveDataHeuristics.qll | 2 +- .../codeql/swift/security/internal/SensitiveDataHeuristics.qll | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/internal/SensitiveDataHeuristics.qll b/javascript/ql/lib/semmle/javascript/security/internal/SensitiveDataHeuristics.qll index 7bc61ee2aee..833c00fd528 100644 --- a/javascript/ql/lib/semmle/javascript/security/internal/SensitiveDataHeuristics.qll +++ b/javascript/ql/lib/semmle/javascript/security/internal/SensitiveDataHeuristics.qll @@ -75,7 +75,7 @@ module HeuristicNames { * Gets a regular expression that identifies strings that may indicate the presence of * a certificate. */ - string maybeCertificate() { result = "(?is).*(cert)(?!.*(format|name)).*" } + string maybeCertificate() { result = "(?is).*(cert)(?!.*(format|name|ification)).*" } /** * Gets a regular expression that identifies strings that may indicate the presence diff --git a/python/ql/lib/semmle/python/security/internal/SensitiveDataHeuristics.qll b/python/ql/lib/semmle/python/security/internal/SensitiveDataHeuristics.qll index 7bc61ee2aee..833c00fd528 100644 --- a/python/ql/lib/semmle/python/security/internal/SensitiveDataHeuristics.qll +++ b/python/ql/lib/semmle/python/security/internal/SensitiveDataHeuristics.qll @@ -75,7 +75,7 @@ module HeuristicNames { * Gets a regular expression that identifies strings that may indicate the presence of * a certificate. */ - string maybeCertificate() { result = "(?is).*(cert)(?!.*(format|name)).*" } + string maybeCertificate() { result = "(?is).*(cert)(?!.*(format|name|ification)).*" } /** * Gets a regular expression that identifies strings that may indicate the presence diff --git a/ruby/ql/lib/codeql/ruby/security/internal/SensitiveDataHeuristics.qll b/ruby/ql/lib/codeql/ruby/security/internal/SensitiveDataHeuristics.qll index 7bc61ee2aee..833c00fd528 100644 --- a/ruby/ql/lib/codeql/ruby/security/internal/SensitiveDataHeuristics.qll +++ b/ruby/ql/lib/codeql/ruby/security/internal/SensitiveDataHeuristics.qll @@ -75,7 +75,7 @@ module HeuristicNames { * Gets a regular expression that identifies strings that may indicate the presence of * a certificate. */ - string maybeCertificate() { result = "(?is).*(cert)(?!.*(format|name)).*" } + string maybeCertificate() { result = "(?is).*(cert)(?!.*(format|name|ification)).*" } /** * Gets a regular expression that identifies strings that may indicate the presence diff --git a/swift/ql/lib/codeql/swift/security/internal/SensitiveDataHeuristics.qll b/swift/ql/lib/codeql/swift/security/internal/SensitiveDataHeuristics.qll index 7bc61ee2aee..833c00fd528 100644 --- a/swift/ql/lib/codeql/swift/security/internal/SensitiveDataHeuristics.qll +++ b/swift/ql/lib/codeql/swift/security/internal/SensitiveDataHeuristics.qll @@ -75,7 +75,7 @@ module HeuristicNames { * Gets a regular expression that identifies strings that may indicate the presence of * a certificate. */ - string maybeCertificate() { result = "(?is).*(cert)(?!.*(format|name)).*" } + string maybeCertificate() { result = "(?is).*(cert)(?!.*(format|name|ification)).*" } /** * Gets a regular expression that identifies strings that may indicate the presence From 0ae1268f589fce014a464f7c38b5cce60a02292e Mon Sep 17 00:00:00 2001 From: James Ockers Date: Tue, 30 Jan 2024 13:31:35 -0800 Subject: [PATCH 11/50] Add change-note --- change-notes/2024-01-30.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 change-notes/2024-01-30.md diff --git a/change-notes/2024-01-30.md b/change-notes/2024-01-30.md new file mode 100644 index 00000000000..8ccded69047 --- /dev/null +++ b/change-notes/2024-01-30.md @@ -0,0 +1,7 @@ +# Improvements to SensitiveDataHeuristics + +The following change adds "certification" to the excluded strings for maybeCertificate() regex matching. + +## General improvements + +The string "certification" isn't a certificate, and should be excluded from the maybeCertificate() regex. From 0f1e21aa0920ebfe2909e1ded85856c9b51192c4 Mon Sep 17 00:00:00 2001 From: James Ockers Date: Tue, 30 Jan 2024 17:28:34 -0800 Subject: [PATCH 12/50] Adding per-language change-notes --- change-notes/2024-01-30.md | 7 ------- .../2024-01-30-certification_not_certificate.md | 4 ++++ .../2024-01-30-certification_not_certificate.md | 4 ++++ .../2024-01-30-certification_not_certificate.md | 4 ++++ .../2024-01-30-certification_not_certificate.md | 4 ++++ 5 files changed, 16 insertions(+), 7 deletions(-) delete mode 100644 change-notes/2024-01-30.md create mode 100644 javascript/ql/lib/change-notes/2024-01-30-certification_not_certificate.md create mode 100644 python/ql/lib/change-notes/2024-01-30-certification_not_certificate.md create mode 100644 ruby/ql/lib/change-notes/2024-01-30-certification_not_certificate.md create mode 100644 swift/ql/lib/change-notes/2024-01-30-certification_not_certificate.md diff --git a/change-notes/2024-01-30.md b/change-notes/2024-01-30.md deleted file mode 100644 index 8ccded69047..00000000000 --- a/change-notes/2024-01-30.md +++ /dev/null @@ -1,7 +0,0 @@ -# Improvements to SensitiveDataHeuristics - -The following change adds "certification" to the excluded strings for maybeCertificate() regex matching. - -## General improvements - -The string "certification" isn't a certificate, and should be excluded from the maybeCertificate() regex. diff --git a/javascript/ql/lib/change-notes/2024-01-30-certification_not_certificate.md b/javascript/ql/lib/change-notes/2024-01-30-certification_not_certificate.md new file mode 100644 index 00000000000..fa0e0026dbe --- /dev/null +++ b/javascript/ql/lib/change-notes/2024-01-30-certification_not_certificate.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The string "certification" isn't a certificate, and should be excluded from the maybeCertificate() regex. diff --git a/python/ql/lib/change-notes/2024-01-30-certification_not_certificate.md b/python/ql/lib/change-notes/2024-01-30-certification_not_certificate.md new file mode 100644 index 00000000000..fa0e0026dbe --- /dev/null +++ b/python/ql/lib/change-notes/2024-01-30-certification_not_certificate.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The string "certification" isn't a certificate, and should be excluded from the maybeCertificate() regex. diff --git a/ruby/ql/lib/change-notes/2024-01-30-certification_not_certificate.md b/ruby/ql/lib/change-notes/2024-01-30-certification_not_certificate.md new file mode 100644 index 00000000000..fa0e0026dbe --- /dev/null +++ b/ruby/ql/lib/change-notes/2024-01-30-certification_not_certificate.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The string "certification" isn't a certificate, and should be excluded from the maybeCertificate() regex. diff --git a/swift/ql/lib/change-notes/2024-01-30-certification_not_certificate.md b/swift/ql/lib/change-notes/2024-01-30-certification_not_certificate.md new file mode 100644 index 00000000000..fa0e0026dbe --- /dev/null +++ b/swift/ql/lib/change-notes/2024-01-30-certification_not_certificate.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The string "certification" isn't a certificate, and should be excluded from the maybeCertificate() regex. From 9130603334dff72a4150193e1a0cd80e8e41d7ba Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Wed, 31 Jan 2024 11:31:25 +0000 Subject: [PATCH 13/50] Address reviews - use SimpleTypeSanitizer and alter qldoc style --- java/ql/lib/semmle/code/java/frameworks/android/Layout.qll | 2 +- java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/java/ql/lib/semmle/code/java/frameworks/android/Layout.qll b/java/ql/lib/semmle/code/java/frameworks/android/Layout.qll index 8993c8cd87d..d7f0b0e2e6c 100644 --- a/java/ql/lib/semmle/code/java/frameworks/android/Layout.qll +++ b/java/ql/lib/semmle/code/java/frameworks/android/Layout.qll @@ -50,7 +50,7 @@ private class FindViewMethod extends Method { } } -/** Gets a use of the view that has the given id. (i.e. from a call to a method like `findViewById`) */ +/** Gets a use of the view that has the given id. (that is, from a call to a method like `findViewById`) */ MethodCall getAUseOfViewWithId(string id) { exists(string name, NestedClass r_id, Field id_field | id = ["@+id/", "@id/"] + name and diff --git a/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll b/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll index ccbf622f557..38a5aeb93cf 100644 --- a/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SensitiveUiQuery.qll @@ -5,6 +5,7 @@ private import semmle.code.java.dataflow.ExternalFlow private import semmle.code.java.dataflow.TaintTracking private import semmle.code.java.security.SensitiveActions private import semmle.code.java.frameworks.android.Layout +private import semmle.code.java.security.Sanitizers /** A configuration for tracking sensitive information to system notifications. */ private module NotificationTrackingConfig implements DataFlow::ConfigSig { @@ -63,9 +64,7 @@ private module TextFieldTrackingConfig implements DataFlow::ConfigSig { ) } - predicate isBarrier(DataFlow::Node node) { - node.getType() instanceof PrimitiveType or node.getType() instanceof BoxedType - } + predicate isBarrier(DataFlow::Node node) { node instanceof SimpleTypeSanitizer } predicate isBarrierIn(DataFlow::Node node) { isSource(node) } } From 8853acb4dd1c7edb66e47a3ba7c41667f69d36c0 Mon Sep 17 00:00:00 2001 From: Koen Vlaswinkel Date: Thu, 1 Feb 2024 16:20:00 +0100 Subject: [PATCH 14/50] Ruby: Add query for access paths in model editor --- .../modeleditor/FrameworkModeAccessPaths.ql | 81 +++++++++++++++++++ .../FrameworkModeAccessPaths.expected | 58 +++++++++++++ .../FrameworkModeAccessPaths.qlref | 1 + 3 files changed, 140 insertions(+) create mode 100644 ruby/ql/src/utils/modeleditor/FrameworkModeAccessPaths.ql create mode 100644 ruby/ql/test/query-tests/utils/modeleditor/FrameworkModeAccessPaths.expected create mode 100644 ruby/ql/test/query-tests/utils/modeleditor/FrameworkModeAccessPaths.qlref diff --git a/ruby/ql/src/utils/modeleditor/FrameworkModeAccessPaths.ql b/ruby/ql/src/utils/modeleditor/FrameworkModeAccessPaths.ql new file mode 100644 index 00000000000..5438f282f65 --- /dev/null +++ b/ruby/ql/src/utils/modeleditor/FrameworkModeAccessPaths.ql @@ -0,0 +1,81 @@ +/** + * @name Fetch a subset of valid access paths of input and output parameters of a method (framework mode). + * @description A list of access paths for input and output parameters of a method. Excludes test and generated code. + * @kind table + * @id ruby/utils/modeleditor/framework-mode-access-paths + * @tags modeleditor access-paths framework-mode + */ + +private import ruby +private import codeql.ruby.ApiGraphs +private import queries.modeling.internal.Util as Util + +predicate simpleParameters(string type, string path, string value, string details) { + exists(DataFlow::MethodNode methodNode, DataFlow::ParameterNode paramNode | + methodNode.getLocation().getFile() instanceof Util::RelevantFile and + ( + // Check that this parameter belongs to this method + // Block parameter explicitly excluded because it's already included + // as part of the blockArguments predicate + paramNode = Util::getAnyParameter(methodNode) and + paramNode != methodNode.getBlockParameter() + ) + | + Util::pathToMethod(methodNode, type, path) and + value = Util::getArgumentPath(paramNode) and + details = paramNode.toString() + ) +} + +predicate blockArguments(string type, string path, string value, string details) { + exists(DataFlow::MethodNode methodNode, DataFlow::CallNode callNode | + methodNode.getLocation().getFile() instanceof Util::RelevantFile and + callNode = methodNode.getABlockCall() + | + ( + exists(DataFlow::ExprNode argNode, int i | argNode = callNode.getPositionalArgument(i) | + value = "Argument[block].Parameter[" + i + "]" and + details = argNode.toString() + ) + or + exists(DataFlow::ExprNode argNode, string keyword | + argNode = callNode.getKeywordArgument(keyword) + | + value = "Argument[block].Parameter[" + keyword + ":]" and + details = ":" + keyword + ) + or + value = "Argument[block]" and details = callNode.toString() + ) and + Util::pathToMethod(methodNode, type, path) + ) +} + +predicate returnValue(string type, string path, string value, string details) { + exists(DataFlow::MethodNode methodNode, DataFlow::Node returnNode | + methodNode.getLocation().getFile() instanceof Util::RelevantFile and + returnNode = methodNode.getAReturnNode() + | + Util::pathToMethod(methodNode, type, path) and + value = "ReturnValue" and + details = returnNode.toString() + ) +} + +predicate inputSuggestions(string type, string path, string value, string details, string defType) { + simpleParameters(type, path, value, details) and defType = "parameter" + or + blockArguments(type, path, value, details) and defType = "parameter" +} + +predicate outputSuggestions(string type, string path, string value, string details, string defType) { + simpleParameters(type, path, value, details) and defType = "parameter" + or + blockArguments(type, path, value, details) and defType = "parameter" + or + returnValue(type, path, value, details) and defType = "return" +} + +query predicate input = inputSuggestions/5; + +query predicate output = outputSuggestions/5; diff --git a/ruby/ql/test/query-tests/utils/modeleditor/FrameworkModeAccessPaths.expected b/ruby/ql/test/query-tests/utils/modeleditor/FrameworkModeAccessPaths.expected new file mode 100644 index 00000000000..c9cc80ad987 --- /dev/null +++ b/ruby/ql/test/query-tests/utils/modeleditor/FrameworkModeAccessPaths.expected @@ -0,0 +1,58 @@ +input +| A | Method[bar] | Argument[0] | x | parameter | +| A | Method[bar] | Argument[self] | self in bar | parameter | +| A | Method[foo] | Argument[0] | x | parameter | +| A | Method[foo] | Argument[1] | y | parameter | +| A | Method[foo] | Argument[2] | key1 | parameter | +| A | Method[foo] | Argument[key1:] | key1 | parameter | +| A | Method[foo] | Argument[self] | self in foo | parameter | +| A! | Method[new] | Argument[0] | x | parameter | +| A! | Method[new] | Argument[1] | y | parameter | +| A! | Method[new] | Argument[self] | self in initialize | parameter | +| A! | Method[self_foo] | Argument[0] | x | parameter | +| A! | Method[self_foo] | Argument[1] | y | parameter | +| A! | Method[self_foo] | Argument[self] | self in self_foo | parameter | +| A::ANested | Method[foo] | Argument[0] | x | parameter | +| A::ANested | Method[foo] | Argument[1] | y | parameter | +| A::ANested | Method[foo] | Argument[self] | self in foo | parameter | +| B | Method[foo] | Argument[0] | x | parameter | +| B | Method[foo] | Argument[1] | y | parameter | +| B | Method[foo] | Argument[self] | self in foo | parameter | +| M1 | Method[foo] | Argument[0] | x | parameter | +| M1 | Method[foo] | Argument[1] | y | parameter | +| M1 | Method[foo] | Argument[self] | self in foo | parameter | +| M1! | Method[self_foo] | Argument[0] | x | parameter | +| M1! | Method[self_foo] | Argument[1] | y | parameter | +| M1! | Method[self_foo] | Argument[self] | self in self_foo | parameter | +| OtherLib::A | Method[foo] | Argument[0] | x | parameter | +| OtherLib::A | Method[foo] | Argument[1] | y | parameter | +| OtherLib::A | Method[foo] | Argument[self] | self in foo | parameter | +output +| A | Method[bar] | Argument[0] | x | parameter | +| A | Method[bar] | Argument[self] | self in bar | parameter | +| A | Method[foo] | Argument[0] | x | parameter | +| A | Method[foo] | Argument[1] | y | parameter | +| A | Method[foo] | Argument[2] | key1 | parameter | +| A | Method[foo] | Argument[key1:] | key1 | parameter | +| A | Method[foo] | Argument[self] | self in foo | parameter | +| A! | Method[new] | Argument[0] | x | parameter | +| A! | Method[new] | Argument[1] | y | parameter | +| A! | Method[new] | Argument[self] | self in initialize | parameter | +| A! | Method[self_foo] | Argument[0] | x | parameter | +| A! | Method[self_foo] | Argument[1] | y | parameter | +| A! | Method[self_foo] | Argument[self] | self in self_foo | parameter | +| A::ANested | Method[foo] | Argument[0] | x | parameter | +| A::ANested | Method[foo] | Argument[1] | y | parameter | +| A::ANested | Method[foo] | Argument[self] | self in foo | parameter | +| B | Method[foo] | Argument[0] | x | parameter | +| B | Method[foo] | Argument[1] | y | parameter | +| B | Method[foo] | Argument[self] | self in foo | parameter | +| M1 | Method[foo] | Argument[0] | x | parameter | +| M1 | Method[foo] | Argument[1] | y | parameter | +| M1 | Method[foo] | Argument[self] | self in foo | parameter | +| M1! | Method[self_foo] | Argument[0] | x | parameter | +| M1! | Method[self_foo] | Argument[1] | y | parameter | +| M1! | Method[self_foo] | Argument[self] | self in self_foo | parameter | +| OtherLib::A | Method[foo] | Argument[0] | x | parameter | +| OtherLib::A | Method[foo] | Argument[1] | y | parameter | +| OtherLib::A | Method[foo] | Argument[self] | self in foo | parameter | diff --git a/ruby/ql/test/query-tests/utils/modeleditor/FrameworkModeAccessPaths.qlref b/ruby/ql/test/query-tests/utils/modeleditor/FrameworkModeAccessPaths.qlref new file mode 100644 index 00000000000..8407cd817f1 --- /dev/null +++ b/ruby/ql/test/query-tests/utils/modeleditor/FrameworkModeAccessPaths.qlref @@ -0,0 +1 @@ +utils/modeleditor/FrameworkModeAccessPaths.ql From ac1ebf27a79efd674ee7f0b81b98e5dba0bf5d80 Mon Sep 17 00:00:00 2001 From: Koen Vlaswinkel Date: Fri, 2 Feb 2024 11:23:37 +0100 Subject: [PATCH 15/50] Ruby: Rename suggestion predicates --- ruby/ql/src/utils/modeleditor/FrameworkModeAccessPaths.ql | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ruby/ql/src/utils/modeleditor/FrameworkModeAccessPaths.ql b/ruby/ql/src/utils/modeleditor/FrameworkModeAccessPaths.ql index 5438f282f65..faa07f96879 100644 --- a/ruby/ql/src/utils/modeleditor/FrameworkModeAccessPaths.ql +++ b/ruby/ql/src/utils/modeleditor/FrameworkModeAccessPaths.ql @@ -62,13 +62,13 @@ predicate returnValue(string type, string path, string value, string details) { ) } -predicate inputSuggestions(string type, string path, string value, string details, string defType) { +predicate inputAccessPaths(string type, string path, string value, string details, string defType) { simpleParameters(type, path, value, details) and defType = "parameter" or blockArguments(type, path, value, details) and defType = "parameter" } -predicate outputSuggestions(string type, string path, string value, string details, string defType) { +predicate outputAccessPaths(string type, string path, string value, string details, string defType) { simpleParameters(type, path, value, details) and defType = "parameter" or blockArguments(type, path, value, details) and defType = "parameter" @@ -76,6 +76,6 @@ predicate outputSuggestions(string type, string path, string value, string detai returnValue(type, path, value, details) and defType = "return" } -query predicate input = inputSuggestions/5; +query predicate input = inputAccessPaths/5; -query predicate output = outputSuggestions/5; +query predicate output = outputAccessPaths/5; From f83d2a7d551c3b1b5cd430a5d53eff86725df12c Mon Sep 17 00:00:00 2001 From: Koen Vlaswinkel Date: Fri, 2 Feb 2024 14:18:09 +0100 Subject: [PATCH 16/50] Ruby: Avoid using toString where possible --- .../modeleditor/FrameworkModeAccessPaths.ql | 46 ++++++++++++++-- .../FrameworkModeAccessPaths.expected | 55 +++++++++++-------- .../FrameworkModeEndpoints.expected | 12 ++-- .../utils/modeleditor/lib/mylib.rb | 3 + 4 files changed, 84 insertions(+), 32 deletions(-) diff --git a/ruby/ql/src/utils/modeleditor/FrameworkModeAccessPaths.ql b/ruby/ql/src/utils/modeleditor/FrameworkModeAccessPaths.ql index faa07f96879..e265d813969 100644 --- a/ruby/ql/src/utils/modeleditor/FrameworkModeAccessPaths.ql +++ b/ruby/ql/src/utils/modeleditor/FrameworkModeAccessPaths.ql @@ -7,9 +7,38 @@ */ private import ruby +private import codeql.ruby.AST private import codeql.ruby.ApiGraphs private import queries.modeling.internal.Util as Util +string parameterDetails(DataFlow::ParameterNode paramNode) { + exists(DataFlow::MethodNode methodNode | methodNode.getParameter(_) = paramNode | + result = paramNode.getName() + ) + or + exists(DataFlow::MethodNode methodNode, string name | + methodNode.getKeywordParameter(name) = paramNode + | + result = name + ":" + ) + or + exists(DataFlow::MethodNode methodNode | methodNode.getBlockParameter() = paramNode | + result = "&" + paramNode.getName() + or + not exists(paramNode.getName()) and result = "&" + ) + or + exists(DataFlow::MethodNode methodNode | methodNode.getSelfParameter() = paramNode | + result = "self" + ) + or + exists(DataFlow::MethodNode methodNode | methodNode.getHashSplatParameter() = paramNode | + result = "**" + paramNode.getName() + or + not exists(paramNode.getName()) and result = "**" + ) +} + predicate simpleParameters(string type, string path, string value, string details) { exists(DataFlow::MethodNode methodNode, DataFlow::ParameterNode paramNode | methodNode.getLocation().getFile() instanceof Util::RelevantFile and @@ -23,7 +52,7 @@ predicate simpleParameters(string type, string path, string value, string detail | Util::pathToMethod(methodNode, type, path) and value = Util::getArgumentPath(paramNode) and - details = paramNode.toString() + details = parameterDetails(paramNode) ) } @@ -33,9 +62,11 @@ predicate blockArguments(string type, string path, string value, string details) callNode = methodNode.getABlockCall() | ( - exists(DataFlow::ExprNode argNode, int i | argNode = callNode.getPositionalArgument(i) | + exists(DataFlow::VariableAccessNode argNode, int i | + argNode = callNode.getPositionalArgument(i) + | value = "Argument[block].Parameter[" + i + "]" and - details = argNode.toString() + details = argNode.asVariableAccessAstNode().getVariable().getName() ) or exists(DataFlow::ExprNode argNode, string keyword | @@ -45,7 +76,14 @@ predicate blockArguments(string type, string path, string value, string details) details = ":" + keyword ) or - value = "Argument[block]" and details = callNode.toString() + value = "Argument[block]" and + ( + details = callNode.getMethodName() + or + not exists(callNode.getMethodName()) and + callNode.getExprNode().getExpr() instanceof YieldCall and + details = "yield ..." + ) ) and Util::pathToMethod(methodNode, type, path) ) diff --git a/ruby/ql/test/query-tests/utils/modeleditor/FrameworkModeAccessPaths.expected b/ruby/ql/test/query-tests/utils/modeleditor/FrameworkModeAccessPaths.expected index c9cc80ad987..c215eb84bdc 100644 --- a/ruby/ql/test/query-tests/utils/modeleditor/FrameworkModeAccessPaths.expected +++ b/ruby/ql/test/query-tests/utils/modeleditor/FrameworkModeAccessPaths.expected @@ -1,58 +1,69 @@ input | A | Method[bar] | Argument[0] | x | parameter | -| A | Method[bar] | Argument[self] | self in bar | parameter | +| A | Method[bar] | Argument[self] | self | parameter | | A | Method[foo] | Argument[0] | x | parameter | | A | Method[foo] | Argument[1] | y | parameter | -| A | Method[foo] | Argument[2] | key1 | parameter | -| A | Method[foo] | Argument[key1:] | key1 | parameter | -| A | Method[foo] | Argument[self] | self in foo | parameter | +| A | Method[foo] | Argument[2] | key1: | parameter | +| A | Method[foo] | Argument[block] | call | parameter | +| A | Method[foo] | Argument[block] | yield ... | parameter | +| A | Method[foo] | Argument[block].Parameter[0] | x | parameter | +| A | Method[foo] | Argument[block].Parameter[1] | y | parameter | +| A | Method[foo] | Argument[block].Parameter[key2:] | :key2 | parameter | +| A | Method[foo] | Argument[key1:] | key1: | parameter | +| A | Method[foo] | Argument[self] | self | parameter | | A! | Method[new] | Argument[0] | x | parameter | | A! | Method[new] | Argument[1] | y | parameter | -| A! | Method[new] | Argument[self] | self in initialize | parameter | +| A! | Method[new] | Argument[self] | self | parameter | | A! | Method[self_foo] | Argument[0] | x | parameter | | A! | Method[self_foo] | Argument[1] | y | parameter | -| A! | Method[self_foo] | Argument[self] | self in self_foo | parameter | +| A! | Method[self_foo] | Argument[self] | self | parameter | | A::ANested | Method[foo] | Argument[0] | x | parameter | | A::ANested | Method[foo] | Argument[1] | y | parameter | -| A::ANested | Method[foo] | Argument[self] | self in foo | parameter | +| A::ANested | Method[foo] | Argument[self] | self | parameter | | B | Method[foo] | Argument[0] | x | parameter | | B | Method[foo] | Argument[1] | y | parameter | -| B | Method[foo] | Argument[self] | self in foo | parameter | +| B | Method[foo] | Argument[self] | self | parameter | | M1 | Method[foo] | Argument[0] | x | parameter | | M1 | Method[foo] | Argument[1] | y | parameter | -| M1 | Method[foo] | Argument[self] | self in foo | parameter | +| M1 | Method[foo] | Argument[self] | self | parameter | | M1! | Method[self_foo] | Argument[0] | x | parameter | | M1! | Method[self_foo] | Argument[1] | y | parameter | -| M1! | Method[self_foo] | Argument[self] | self in self_foo | parameter | +| M1! | Method[self_foo] | Argument[self] | self | parameter | | OtherLib::A | Method[foo] | Argument[0] | x | parameter | | OtherLib::A | Method[foo] | Argument[1] | y | parameter | -| OtherLib::A | Method[foo] | Argument[self] | self in foo | parameter | +| OtherLib::A | Method[foo] | Argument[self] | self | parameter | output | A | Method[bar] | Argument[0] | x | parameter | -| A | Method[bar] | Argument[self] | self in bar | parameter | +| A | Method[bar] | Argument[self] | self | parameter | | A | Method[foo] | Argument[0] | x | parameter | | A | Method[foo] | Argument[1] | y | parameter | -| A | Method[foo] | Argument[2] | key1 | parameter | -| A | Method[foo] | Argument[key1:] | key1 | parameter | -| A | Method[foo] | Argument[self] | self in foo | parameter | +| A | Method[foo] | Argument[2] | key1: | parameter | +| A | Method[foo] | Argument[block] | call | parameter | +| A | Method[foo] | Argument[block] | yield ... | parameter | +| A | Method[foo] | Argument[block].Parameter[0] | x | parameter | +| A | Method[foo] | Argument[block].Parameter[1] | y | parameter | +| A | Method[foo] | Argument[block].Parameter[key2:] | :key2 | parameter | +| A | Method[foo] | Argument[key1:] | key1: | parameter | +| A | Method[foo] | Argument[self] | self | parameter | +| A | Method[foo] | ReturnValue | yield ... | return | | A! | Method[new] | Argument[0] | x | parameter | | A! | Method[new] | Argument[1] | y | parameter | -| A! | Method[new] | Argument[self] | self in initialize | parameter | +| A! | Method[new] | Argument[self] | self | parameter | | A! | Method[self_foo] | Argument[0] | x | parameter | | A! | Method[self_foo] | Argument[1] | y | parameter | -| A! | Method[self_foo] | Argument[self] | self in self_foo | parameter | +| A! | Method[self_foo] | Argument[self] | self | parameter | | A::ANested | Method[foo] | Argument[0] | x | parameter | | A::ANested | Method[foo] | Argument[1] | y | parameter | -| A::ANested | Method[foo] | Argument[self] | self in foo | parameter | +| A::ANested | Method[foo] | Argument[self] | self | parameter | | B | Method[foo] | Argument[0] | x | parameter | | B | Method[foo] | Argument[1] | y | parameter | -| B | Method[foo] | Argument[self] | self in foo | parameter | +| B | Method[foo] | Argument[self] | self | parameter | | M1 | Method[foo] | Argument[0] | x | parameter | | M1 | Method[foo] | Argument[1] | y | parameter | -| M1 | Method[foo] | Argument[self] | self in foo | parameter | +| M1 | Method[foo] | Argument[self] | self | parameter | | M1! | Method[self_foo] | Argument[0] | x | parameter | | M1! | Method[self_foo] | Argument[1] | y | parameter | -| M1! | Method[self_foo] | Argument[self] | self in self_foo | parameter | +| M1! | Method[self_foo] | Argument[self] | self | parameter | | OtherLib::A | Method[foo] | Argument[0] | x | parameter | | OtherLib::A | Method[foo] | Argument[1] | y | parameter | -| OtherLib::A | Method[foo] | Argument[self] | self in foo | parameter | +| OtherLib::A | Method[foo] | Argument[self] | self | parameter | diff --git a/ruby/ql/test/query-tests/utils/modeleditor/FrameworkModeEndpoints.expected b/ruby/ql/test/query-tests/utils/modeleditor/FrameworkModeEndpoints.expected index fdfd9173720..a42da32525d 100644 --- a/ruby/ql/test/query-tests/utils/modeleditor/FrameworkModeEndpoints.expected +++ b/ruby/ql/test/query-tests/utils/modeleditor/FrameworkModeEndpoints.expected @@ -1,13 +1,13 @@ | lib/module.rb:1:1:7:3 | M1 | mylib | M1 | | | false | module.rb | | | lib/module.rb:2:3:3:5 | foo | mylib | M1 | foo | (x,y) | false | module.rb | | | lib/module.rb:5:3:6:5 | self_foo | mylib | M1! | self_foo | (x,y) | false | module.rb | | -| lib/mylib.rb:3:1:30:3 | A | mylib | A | | | false | mylib.rb | | +| lib/mylib.rb:3:1:33:3 | A | mylib | A | | | false | mylib.rb | | | lib/mylib.rb:4:3:5:5 | initialize | mylib | A! | new | (x,y) | false | mylib.rb | | -| lib/mylib.rb:7:3:8:5 | foo | mylib | A | foo | (x,y,key1:) | false | mylib.rb | | -| lib/mylib.rb:10:3:11:5 | bar | mylib | A | bar | (x) | false | mylib.rb | | -| lib/mylib.rb:13:3:14:5 | self_foo | mylib | A! | self_foo | (x,y) | false | mylib.rb | | -| lib/mylib.rb:21:3:29:5 | ANested | mylib | A::ANested | | | false | mylib.rb | | -| lib/mylib.rb:22:5:23:7 | foo | mylib | A::ANested | foo | (x,y) | false | mylib.rb | | +| lib/mylib.rb:7:3:11:5 | foo | mylib | A | foo | (x,y,key1:) | false | mylib.rb | | +| lib/mylib.rb:13:3:14:5 | bar | mylib | A | bar | (x) | false | mylib.rb | | +| lib/mylib.rb:16:3:17:5 | self_foo | mylib | A! | self_foo | (x,y) | false | mylib.rb | | +| lib/mylib.rb:24:3:32:5 | ANested | mylib | A::ANested | | | false | mylib.rb | | +| lib/mylib.rb:25:5:26:7 | foo | mylib | A::ANested | foo | (x,y) | false | mylib.rb | | | lib/other.rb:3:1:8:3 | B | mylib | B | | | false | other.rb | | | lib/other.rb:6:3:7:5 | foo | mylib | B | foo | (x,y) | false | other.rb | | | lib/other.rb:10:1:12:3 | C | mylib | C | | | false | other.rb | | diff --git a/ruby/ql/test/query-tests/utils/modeleditor/lib/mylib.rb b/ruby/ql/test/query-tests/utils/modeleditor/lib/mylib.rb index 699c814dbf7..66c0d35ac23 100644 --- a/ruby/ql/test/query-tests/utils/modeleditor/lib/mylib.rb +++ b/ruby/ql/test/query-tests/utils/modeleditor/lib/mylib.rb @@ -5,6 +5,9 @@ class A end def foo(x, y, key1:, **kwargs, &block) + block.call(x, y, key2: key1) + + yield x, y, key2: key1 end def bar(x, *args) From 6ff22622ca7ff626a023d84a209d06eb754b9188 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 29 Jan 2024 15:54:24 +0100 Subject: [PATCH 17/50] C#: Add summaries for Span and ReadOnlySpan. --- csharp/ql/lib/ext/System.model.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/csharp/ql/lib/ext/System.model.yml b/csharp/ql/lib/ext/System.model.yml index c8ed5d7fa6a..e8bfe9c03ae 100644 --- a/csharp/ql/lib/ext/System.model.yml +++ b/csharp/ql/lib/ext/System.model.yml @@ -380,6 +380,28 @@ extensions: - ["System", "Nullable", False, "Nullable", "(T)", "", "Argument[0]", "Argument[this].Property[System.Nullable`1.Value]", "value", "manual"] - ["System", "Nullable", False, "get_HasValue", "()", "", "Argument[this].Property[System.Nullable`1.Value]", "ReturnValue", "taint", "manual"] - ["System", "Nullable", False, "get_Value", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["System", "ReadOnlySpan", False, "CopyTo", "(System.Span)", "", "Argument[this].Element", "Argument[0].Element", "value", "manual"] + - ["System", "ReadOnlySpan", False, "get_Item", "(System.Int32)", "", "Argument[this].Element", "ReturnValue", "value", "manual"] + - ["System", "ReadOnlySpan", False, "GetPinnableReference", "()", "", "Argument[this].Element", "ReturnValue", "value", "manual"] + - ["System", "ReadOnlySpan", False, "Slice", "(System.Int32)", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] + - ["System", "ReadOnlySpan", False, "Slice", "(System.Int32,System.Int32)", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] + - ["System", "ReadOnlySpan", False, "ReadOnlySpan", "(T)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] + - ["System", "ReadOnlySpan", False, "ReadOnlySpan", "(T[])", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"] + - ["System", "ReadOnlySpan", False, "ReadOnlySpan", "(T[],System.Int32,System.Int32)", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"] + - ["System", "ReadOnlySpan", False, "ToArray", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] + - ["System", "ReadOnlySpan", False, "TryCopyTo", "(System.Span)", "", "Argument[this].Element", "Argument[0].Element", "value", "manual"] + - ["System", "Span", False, "Clear", "()", "", "Argument[this].WithoutElement", "Argument[this]", "value", "manual"] + - ["System", "Span", False, "CopyTo", "(System.Span)", "", "Argument[this].Element", "Argument[0].Element", "value", "manual"] + - ["System", "Span", False, "Fill", "(T)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] + - ["System", "Span", False, "get_Item", "(System.Int32)", "", "Argument[this].Element", "ReturnValue", "value", "manual"] + - ["System", "Span", False, "GetPinnableReference", "()", "", "Argument[this].Element", "ReturnValue", "value", "manual"] + - ["System", "Span", False, "Slice", "(System.Int32)", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] + - ["System", "Span", False, "Slice", "(System.Int32,System.Int32)", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] + - ["System", "Span", False, "Span", "(T)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] + - ["System", "Span", False, "Span", "(T[])", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"] + - ["System", "Span", False, "Span", "(T[],System.Int32,System.Int32)", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"] + - ["System", "Span", False, "ToArray", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] + - ["System", "Span", False, "TryCopyTo", "(System.Span)", "", "Argument[this].Element", "Argument[0].Element", "value", "manual"] - ["System", "String", False, "Clone", "()", "", "Argument[this]", "ReturnValue", "value", "manual"] - ["System", "String", False, "Concat", "(System.Collections.Generic.IEnumerable)", "", "Argument[0].Element", "ReturnValue", "taint", "manual"] - ["System", "String", False, "Concat", "(System.Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] From 7f5d2e1f44f3f6940362520a57ae6f338f44033d Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 29 Jan 2024 16:27:05 +0100 Subject: [PATCH 18/50] C#: Update flowsummaries expected output. --- .../dataflow/library/FlowSummaries.expected | 22 +++++++++++++++++++ .../library/FlowSummariesFiltered.expected | 22 +++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected b/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected index f2f8dac0139..3c9ebb33a48 100644 --- a/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected +++ b/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected @@ -17785,7 +17785,17 @@ summary | System;ReadOnlyMemory;false;Slice;(System.Int32);;Argument[this];ReturnValue;taint;df-generated | | System;ReadOnlyMemory;false;Slice;(System.Int32,System.Int32);;Argument[this];ReturnValue;taint;df-generated | | System;ReadOnlyMemory;false;ToString;();;Argument[this];ReturnValue;taint;df-generated | +| System;ReadOnlySpan;false;CopyTo;(System.Span);;Argument[this].Element;Argument[0].Element;value;manual | | System;ReadOnlySpan;false;GetEnumerator;();;Argument[this];ReturnValue;taint;df-generated | +| System;ReadOnlySpan;false;GetPinnableReference;();;Argument[this].Element;ReturnValue;value;manual | +| System;ReadOnlySpan;false;ReadOnlySpan;(T);;Argument[0];Argument[this].Element;value;manual | +| System;ReadOnlySpan;false;ReadOnlySpan;(T[]);;Argument[0].Element;Argument[this].Element;value;manual | +| System;ReadOnlySpan;false;ReadOnlySpan;(T[],System.Int32,System.Int32);;Argument[0].Element;Argument[this].Element;value;manual | +| System;ReadOnlySpan;false;Slice;(System.Int32);;Argument[this].Element;ReturnValue.Element;value;manual | +| System;ReadOnlySpan;false;Slice;(System.Int32,System.Int32);;Argument[this].Element;ReturnValue.Element;value;manual | +| System;ReadOnlySpan;false;ToArray;();;Argument[this].Element;ReturnValue.Element;value;manual | +| System;ReadOnlySpan;false;TryCopyTo;(System.Span);;Argument[this].Element;Argument[0].Element;value;manual | +| System;ReadOnlySpan;false;get_Item;(System.Int32);;Argument[this].Element;ReturnValue;value;manual | | System;ResolveEventHandler;false;BeginInvoke;(System.Object,System.ResolveEventArgs,System.AsyncCallback,System.Object);;Argument[2];Argument[2].Parameter[delegate-self];value;hq-generated | | System;RuntimeFieldHandle;false;FromIntPtr;(System.IntPtr);;Argument[0];ReturnValue;taint;df-generated | | System;RuntimeFieldHandle;false;ToIntPtr;(System.RuntimeFieldHandle);;Argument[0];ReturnValue;taint;df-generated | @@ -17833,7 +17843,19 @@ summary | System;Single;false;ToString;(System.IFormatProvider);;Argument[0];ReturnValue;taint;df-generated | | System;Single;false;ToString;(System.String,System.IFormatProvider);;Argument[1];ReturnValue;taint;df-generated | | System;Single;false;ToType;(System.Type,System.IFormatProvider);;Argument[1];ReturnValue;taint;df-generated | +| System;Span;false;Clear;();;Argument[this].WithoutElement;Argument[this];value;manual | +| System;Span;false;CopyTo;(System.Span);;Argument[this].Element;Argument[0].Element;value;manual | +| System;Span;false;Fill;(T);;Argument[0];Argument[this].Element;value;manual | | System;Span;false;GetEnumerator;();;Argument[this];ReturnValue;taint;df-generated | +| System;Span;false;GetPinnableReference;();;Argument[this].Element;ReturnValue;value;manual | +| System;Span;false;Slice;(System.Int32);;Argument[this].Element;ReturnValue.Element;value;manual | +| System;Span;false;Slice;(System.Int32,System.Int32);;Argument[this].Element;ReturnValue.Element;value;manual | +| System;Span;false;Span;(T);;Argument[0];Argument[this].Element;value;manual | +| System;Span;false;Span;(T[]);;Argument[0].Element;Argument[this].Element;value;manual | +| System;Span;false;Span;(T[],System.Int32,System.Int32);;Argument[0].Element;Argument[this].Element;value;manual | +| System;Span;false;ToArray;();;Argument[this].Element;ReturnValue.Element;value;manual | +| System;Span;false;TryCopyTo;(System.Span);;Argument[this].Element;Argument[0].Element;value;manual | +| System;Span;false;get_Item;(System.Int32);;Argument[this].Element;ReturnValue;value;manual | | System;String;false;Clone;();;Argument[this];ReturnValue;value;manual | | System;String;false;Concat;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;manual | | System;String;false;Concat;(System.Object);;Argument[0];ReturnValue;taint;manual | diff --git a/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected b/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected index c513e544b7a..1c3104b1bc9 100644 --- a/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected +++ b/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected @@ -15338,7 +15338,17 @@ summary | System;ReadOnlyMemory;false;Slice;(System.Int32);;Argument[this];ReturnValue;taint;df-generated | | System;ReadOnlyMemory;false;Slice;(System.Int32,System.Int32);;Argument[this];ReturnValue;taint;df-generated | | System;ReadOnlyMemory;false;ToString;();;Argument[this];ReturnValue;taint;df-generated | +| System;ReadOnlySpan;false;CopyTo;(System.Span);;Argument[this].Element;Argument[0].Element;value;manual | | System;ReadOnlySpan;false;GetEnumerator;();;Argument[this];ReturnValue;taint;df-generated | +| System;ReadOnlySpan;false;GetPinnableReference;();;Argument[this].Element;ReturnValue;value;manual | +| System;ReadOnlySpan;false;ReadOnlySpan;(T);;Argument[0];Argument[this].Element;value;manual | +| System;ReadOnlySpan;false;ReadOnlySpan;(T[]);;Argument[0].Element;Argument[this].Element;value;manual | +| System;ReadOnlySpan;false;ReadOnlySpan;(T[],System.Int32,System.Int32);;Argument[0].Element;Argument[this].Element;value;manual | +| System;ReadOnlySpan;false;Slice;(System.Int32);;Argument[this].Element;ReturnValue.Element;value;manual | +| System;ReadOnlySpan;false;Slice;(System.Int32,System.Int32);;Argument[this].Element;ReturnValue.Element;value;manual | +| System;ReadOnlySpan;false;ToArray;();;Argument[this].Element;ReturnValue.Element;value;manual | +| System;ReadOnlySpan;false;TryCopyTo;(System.Span);;Argument[this].Element;Argument[0].Element;value;manual | +| System;ReadOnlySpan;false;get_Item;(System.Int32);;Argument[this].Element;ReturnValue;value;manual | | System;ResolveEventHandler;false;BeginInvoke;(System.Object,System.ResolveEventArgs,System.AsyncCallback,System.Object);;Argument[2];Argument[2].Parameter[delegate-self];value;hq-generated | | System;RuntimeFieldHandle;false;FromIntPtr;(System.IntPtr);;Argument[0];ReturnValue;taint;df-generated | | System;RuntimeFieldHandle;false;ToIntPtr;(System.RuntimeFieldHandle);;Argument[0];ReturnValue;taint;df-generated | @@ -15354,7 +15364,19 @@ summary | System;Single;false;ToString;(System.IFormatProvider);;Argument[0];ReturnValue;taint;df-generated | | System;Single;false;ToString;(System.String,System.IFormatProvider);;Argument[1];ReturnValue;taint;df-generated | | System;Single;false;ToType;(System.Type,System.IFormatProvider);;Argument[1];ReturnValue;taint;df-generated | +| System;Span;false;Clear;();;Argument[this].WithoutElement;Argument[this];value;manual | +| System;Span;false;CopyTo;(System.Span);;Argument[this].Element;Argument[0].Element;value;manual | +| System;Span;false;Fill;(T);;Argument[0];Argument[this].Element;value;manual | | System;Span;false;GetEnumerator;();;Argument[this];ReturnValue;taint;df-generated | +| System;Span;false;GetPinnableReference;();;Argument[this].Element;ReturnValue;value;manual | +| System;Span;false;Slice;(System.Int32);;Argument[this].Element;ReturnValue.Element;value;manual | +| System;Span;false;Slice;(System.Int32,System.Int32);;Argument[this].Element;ReturnValue.Element;value;manual | +| System;Span;false;Span;(T);;Argument[0];Argument[this].Element;value;manual | +| System;Span;false;Span;(T[]);;Argument[0].Element;Argument[this].Element;value;manual | +| System;Span;false;Span;(T[],System.Int32,System.Int32);;Argument[0].Element;Argument[this].Element;value;manual | +| System;Span;false;ToArray;();;Argument[this].Element;ReturnValue.Element;value;manual | +| System;Span;false;TryCopyTo;(System.Span);;Argument[this].Element;Argument[0].Element;value;manual | +| System;Span;false;get_Item;(System.Int32);;Argument[this].Element;ReturnValue;value;manual | | System;String;false;Clone;();;Argument[this];ReturnValue;value;manual | | System;String;false;Concat;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;manual | | System;String;false;Concat;(System.Object);;Argument[0];ReturnValue;taint;manual | From 91d844316a6dca724bc71bcd8c958dd5f0b66e6f Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 30 Jan 2024 12:48:43 +0100 Subject: [PATCH 19/50] C#: Add some tests with expected output. --- .../dataflow/collections/CollectionFlow.cs | 36 +++++++++++ .../collections/CollectionFlow.expected | 64 +++++++++++++++++++ 2 files changed, 100 insertions(+) diff --git a/csharp/ql/test/library-tests/dataflow/collections/CollectionFlow.cs b/csharp/ql/test/library-tests/dataflow/collections/CollectionFlow.cs index 95ab917468c..bee481a8cc9 100644 --- a/csharp/ql/test/library-tests/dataflow/collections/CollectionFlow.cs +++ b/csharp/ql/test/library-tests/dataflow/collections/CollectionFlow.cs @@ -481,4 +481,40 @@ public class CollectionFlow IntegerCollection ic1 = [.. ic0]; Sink(ic1.Payload); // No flow } + + public void SpanConstructorFlow() + { + var a = new A(); + Span span = new Span(ref a); + Sink(span[0]); // flow + } + + public void SpanToArrayFlow() + { + var a = new A(); + Span span = new Span(ref a); + var arr = span.ToArray(); + Sink(arr[0]); // flow + } + + public void SpanFillFlow(Span target) + { + var a = new A(); + target.Fill(a); + Sink(target[0]); // flow + } + + public void SpanCopyToFlow(Span target) + { + var source = new Span(new[] { new A() }); + source.CopyTo(target); + Sink(target[0]); // flow + } + + public void ReadOnlySpanConstructorFlow() + { + var a = new A(); + ReadOnlySpan span = new ReadOnlySpan(new[] { a }); + Sink(span[0]); // flow + } } diff --git a/csharp/ql/test/library-tests/dataflow/collections/CollectionFlow.expected b/csharp/ql/test/library-tests/dataflow/collections/CollectionFlow.expected index eca1796dbdc..4ecd3771cbf 100644 --- a/csharp/ql/test/library-tests/dataflow/collections/CollectionFlow.expected +++ b/csharp/ql/test/library-tests/dataflow/collections/CollectionFlow.expected @@ -246,6 +246,33 @@ edges | CollectionFlow.cs:448:21:448:21 | access to local variable a : A | CollectionFlow.cs:448:20:448:22 | [...] : A[] [element] : A | | CollectionFlow.cs:449:22:449:28 | .. access to local variable temp : A[] [element] : A | CollectionFlow.cs:450:14:450:18 | access to local variable array : A[] [element] : A | | CollectionFlow.cs:450:14:450:18 | access to local variable array : A[] [element] : A | CollectionFlow.cs:450:14:450:21 | access to array element | +| CollectionFlow.cs:487:17:487:23 | object creation of type A : A | CollectionFlow.cs:488:40:488:40 | access to local variable a : A | +| CollectionFlow.cs:488:24:488:41 | object creation of type Span : Span [element] : A | CollectionFlow.cs:489:14:489:17 | access to local variable span : Span [element] : A | +| CollectionFlow.cs:488:40:488:40 | access to local variable a : A | CollectionFlow.cs:488:24:488:41 | object creation of type Span : Span [element] : A | +| CollectionFlow.cs:489:14:489:17 | access to local variable span : Span [element] : A | CollectionFlow.cs:489:14:489:20 | access to indexer | +| CollectionFlow.cs:494:17:494:23 | object creation of type A : A | CollectionFlow.cs:495:40:495:40 | access to local variable a : A | +| CollectionFlow.cs:495:24:495:41 | object creation of type Span : Span [element] : A | CollectionFlow.cs:496:19:496:22 | access to local variable span : Span [element] : A | +| CollectionFlow.cs:495:40:495:40 | access to local variable a : A | CollectionFlow.cs:495:24:495:41 | object creation of type Span : Span [element] : A | +| CollectionFlow.cs:496:19:496:22 | access to local variable span : Span [element] : A | CollectionFlow.cs:496:19:496:32 | call to method ToArray : T[] [element] : A | +| CollectionFlow.cs:496:19:496:32 | call to method ToArray : T[] [element] : A | CollectionFlow.cs:497:14:497:16 | access to local variable arr : T[] [element] : A | +| CollectionFlow.cs:497:14:497:16 | access to local variable arr : T[] [element] : A | CollectionFlow.cs:497:14:497:19 | access to array element | +| CollectionFlow.cs:502:17:502:23 | object creation of type A : A | CollectionFlow.cs:503:21:503:21 | access to local variable a : A | +| CollectionFlow.cs:503:9:503:14 | [post] access to parameter target : Span [element] : A | CollectionFlow.cs:504:14:504:19 | access to parameter target : Span [element] : A | +| CollectionFlow.cs:503:21:503:21 | access to local variable a : A | CollectionFlow.cs:503:9:503:14 | [post] access to parameter target : Span [element] : A | +| CollectionFlow.cs:504:14:504:19 | access to parameter target : Span [element] : A | CollectionFlow.cs:504:14:504:22 | access to indexer | +| CollectionFlow.cs:509:22:509:51 | object creation of type Span : Span [element] : A | CollectionFlow.cs:510:9:510:14 | access to local variable source : Span [element] : A | +| CollectionFlow.cs:509:34:509:50 | array creation of type A[] : null [element] : A | CollectionFlow.cs:509:22:509:51 | object creation of type Span : Span [element] : A | +| CollectionFlow.cs:509:40:509:50 | { ..., ... } : null [element] : A | CollectionFlow.cs:509:34:509:50 | array creation of type A[] : null [element] : A | +| CollectionFlow.cs:509:42:509:48 | object creation of type A : A | CollectionFlow.cs:509:40:509:50 | { ..., ... } : null [element] : A | +| CollectionFlow.cs:510:9:510:14 | access to local variable source : Span [element] : A | CollectionFlow.cs:510:23:510:28 | [post] access to parameter target : Span [element] : A | +| CollectionFlow.cs:510:23:510:28 | [post] access to parameter target : Span [element] : A | CollectionFlow.cs:511:14:511:19 | access to parameter target : Span [element] : A | +| CollectionFlow.cs:511:14:511:19 | access to parameter target : Span [element] : A | CollectionFlow.cs:511:14:511:22 | access to indexer | +| CollectionFlow.cs:516:17:516:23 | object creation of type A : A | CollectionFlow.cs:517:60:517:60 | access to local variable a : A | +| CollectionFlow.cs:517:32:517:63 | object creation of type ReadOnlySpan : ReadOnlySpan [element] : A | CollectionFlow.cs:518:14:518:17 | access to local variable span : ReadOnlySpan [element] : A | +| CollectionFlow.cs:517:52:517:62 | array creation of type A[] : null [element] : A | CollectionFlow.cs:517:32:517:63 | object creation of type ReadOnlySpan : ReadOnlySpan [element] : A | +| CollectionFlow.cs:517:58:517:62 | { ..., ... } : null [element] : A | CollectionFlow.cs:517:52:517:62 | array creation of type A[] : null [element] : A | +| CollectionFlow.cs:517:60:517:60 | access to local variable a : A | CollectionFlow.cs:517:58:517:62 | { ..., ... } : null [element] : A | +| CollectionFlow.cs:518:14:518:17 | access to local variable span : ReadOnlySpan [element] : A | CollectionFlow.cs:518:14:518:20 | access to indexer | nodes | CollectionFlow.cs:14:40:14:41 | ts : A[] [element] : A | semmle.label | ts : A[] [element] : A | | CollectionFlow.cs:14:40:14:41 | ts : null [element] : A | semmle.label | ts : null [element] : A | @@ -497,6 +524,38 @@ nodes | CollectionFlow.cs:449:22:449:28 | .. access to local variable temp : A[] [element] : A | semmle.label | .. access to local variable temp : A[] [element] : A | | CollectionFlow.cs:450:14:450:18 | access to local variable array : A[] [element] : A | semmle.label | access to local variable array : A[] [element] : A | | CollectionFlow.cs:450:14:450:21 | access to array element | semmle.label | access to array element | +| CollectionFlow.cs:487:17:487:23 | object creation of type A : A | semmle.label | object creation of type A : A | +| CollectionFlow.cs:488:24:488:41 | object creation of type Span : Span [element] : A | semmle.label | object creation of type Span : Span [element] : A | +| CollectionFlow.cs:488:40:488:40 | access to local variable a : A | semmle.label | access to local variable a : A | +| CollectionFlow.cs:489:14:489:17 | access to local variable span : Span [element] : A | semmle.label | access to local variable span : Span [element] : A | +| CollectionFlow.cs:489:14:489:20 | access to indexer | semmle.label | access to indexer | +| CollectionFlow.cs:494:17:494:23 | object creation of type A : A | semmle.label | object creation of type A : A | +| CollectionFlow.cs:495:24:495:41 | object creation of type Span : Span [element] : A | semmle.label | object creation of type Span : Span [element] : A | +| CollectionFlow.cs:495:40:495:40 | access to local variable a : A | semmle.label | access to local variable a : A | +| CollectionFlow.cs:496:19:496:22 | access to local variable span : Span [element] : A | semmle.label | access to local variable span : Span [element] : A | +| CollectionFlow.cs:496:19:496:32 | call to method ToArray : T[] [element] : A | semmle.label | call to method ToArray : T[] [element] : A | +| CollectionFlow.cs:497:14:497:16 | access to local variable arr : T[] [element] : A | semmle.label | access to local variable arr : T[] [element] : A | +| CollectionFlow.cs:497:14:497:19 | access to array element | semmle.label | access to array element | +| CollectionFlow.cs:502:17:502:23 | object creation of type A : A | semmle.label | object creation of type A : A | +| CollectionFlow.cs:503:9:503:14 | [post] access to parameter target : Span [element] : A | semmle.label | [post] access to parameter target : Span [element] : A | +| CollectionFlow.cs:503:21:503:21 | access to local variable a : A | semmle.label | access to local variable a : A | +| CollectionFlow.cs:504:14:504:19 | access to parameter target : Span [element] : A | semmle.label | access to parameter target : Span [element] : A | +| CollectionFlow.cs:504:14:504:22 | access to indexer | semmle.label | access to indexer | +| CollectionFlow.cs:509:22:509:51 | object creation of type Span : Span [element] : A | semmle.label | object creation of type Span : Span [element] : A | +| CollectionFlow.cs:509:34:509:50 | array creation of type A[] : null [element] : A | semmle.label | array creation of type A[] : null [element] : A | +| CollectionFlow.cs:509:40:509:50 | { ..., ... } : null [element] : A | semmle.label | { ..., ... } : null [element] : A | +| CollectionFlow.cs:509:42:509:48 | object creation of type A : A | semmle.label | object creation of type A : A | +| CollectionFlow.cs:510:9:510:14 | access to local variable source : Span [element] : A | semmle.label | access to local variable source : Span [element] : A | +| CollectionFlow.cs:510:23:510:28 | [post] access to parameter target : Span [element] : A | semmle.label | [post] access to parameter target : Span [element] : A | +| CollectionFlow.cs:511:14:511:19 | access to parameter target : Span [element] : A | semmle.label | access to parameter target : Span [element] : A | +| CollectionFlow.cs:511:14:511:22 | access to indexer | semmle.label | access to indexer | +| CollectionFlow.cs:516:17:516:23 | object creation of type A : A | semmle.label | object creation of type A : A | +| CollectionFlow.cs:517:32:517:63 | object creation of type ReadOnlySpan : ReadOnlySpan [element] : A | semmle.label | object creation of type ReadOnlySpan : ReadOnlySpan [element] : A | +| CollectionFlow.cs:517:52:517:62 | array creation of type A[] : null [element] : A | semmle.label | array creation of type A[] : null [element] : A | +| CollectionFlow.cs:517:58:517:62 | { ..., ... } : null [element] : A | semmle.label | { ..., ... } : null [element] : A | +| CollectionFlow.cs:517:60:517:60 | access to local variable a : A | semmle.label | access to local variable a : A | +| CollectionFlow.cs:518:14:518:17 | access to local variable span : ReadOnlySpan [element] : A | semmle.label | access to local variable span : ReadOnlySpan [element] : A | +| CollectionFlow.cs:518:14:518:20 | access to indexer | semmle.label | access to indexer | subpaths | CollectionFlow.cs:44:20:44:22 | access to local variable as : null [element] : A | CollectionFlow.cs:22:34:22:35 | ts : null [element] : A | CollectionFlow.cs:22:41:22:45 | access to array element : A | CollectionFlow.cs:44:14:44:23 | call to method First | | CollectionFlow.cs:62:20:62:23 | access to field As : A[] [element] : A | CollectionFlow.cs:22:34:22:35 | ts : A[] [element] : A | CollectionFlow.cs:22:41:22:45 | access to array element : A | CollectionFlow.cs:62:14:62:24 | call to method First | @@ -581,3 +640,8 @@ subpaths | CollectionFlow.cs:427:17:427:23 | object creation of type A : A | CollectionFlow.cs:427:17:427:23 | object creation of type A : A | CollectionFlow.cs:429:14:429:21 | access to array element | $@ | CollectionFlow.cs:429:14:429:21 | access to array element | access to array element | | CollectionFlow.cs:434:17:434:23 | object creation of type A : A | CollectionFlow.cs:434:17:434:23 | object creation of type A : A | CollectionFlow.cs:436:14:436:17 | access to indexer | $@ | CollectionFlow.cs:436:14:436:17 | access to indexer | access to indexer | | CollectionFlow.cs:447:17:447:23 | object creation of type A : A | CollectionFlow.cs:447:17:447:23 | object creation of type A : A | CollectionFlow.cs:450:14:450:21 | access to array element | $@ | CollectionFlow.cs:450:14:450:21 | access to array element | access to array element | +| CollectionFlow.cs:487:17:487:23 | object creation of type A : A | CollectionFlow.cs:487:17:487:23 | object creation of type A : A | CollectionFlow.cs:489:14:489:20 | access to indexer | $@ | CollectionFlow.cs:489:14:489:20 | access to indexer | access to indexer | +| CollectionFlow.cs:494:17:494:23 | object creation of type A : A | CollectionFlow.cs:494:17:494:23 | object creation of type A : A | CollectionFlow.cs:497:14:497:19 | access to array element | $@ | CollectionFlow.cs:497:14:497:19 | access to array element | access to array element | +| CollectionFlow.cs:502:17:502:23 | object creation of type A : A | CollectionFlow.cs:502:17:502:23 | object creation of type A : A | CollectionFlow.cs:504:14:504:22 | access to indexer | $@ | CollectionFlow.cs:504:14:504:22 | access to indexer | access to indexer | +| CollectionFlow.cs:509:42:509:48 | object creation of type A : A | CollectionFlow.cs:509:42:509:48 | object creation of type A : A | CollectionFlow.cs:511:14:511:22 | access to indexer | $@ | CollectionFlow.cs:511:14:511:22 | access to indexer | access to indexer | +| CollectionFlow.cs:516:17:516:23 | object creation of type A : A | CollectionFlow.cs:516:17:516:23 | object creation of type A : A | CollectionFlow.cs:518:14:518:20 | access to indexer | $@ | CollectionFlow.cs:518:14:518:20 | access to indexer | access to indexer | From f6e3027321abb5bfb864594e752ea9d299163174 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Fri, 2 Feb 2024 10:10:30 +0100 Subject: [PATCH 20/50] C#: Add summaries for Span and ReadOnlySpan extension methods. --- csharp/ql/lib/ext/System.Collections.Immutable.model.yml | 2 ++ csharp/ql/lib/ext/System.model.yml | 3 +++ 2 files changed, 5 insertions(+) diff --git a/csharp/ql/lib/ext/System.Collections.Immutable.model.yml b/csharp/ql/lib/ext/System.Collections.Immutable.model.yml index e121e6976a6..6244f979c5c 100644 --- a/csharp/ql/lib/ext/System.Collections.Immutable.model.yml +++ b/csharp/ql/lib/ext/System.Collections.Immutable.model.yml @@ -12,6 +12,8 @@ extensions: - ["System.Collections.Immutable", "IImmutableSet", True, "Add", "(T)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] - ["System.Collections.Immutable", "IImmutableSet", True, "Clear", "()", "", "Argument[this].WithoutElement", "ReturnValue", "value", "manual"] - ["System.Collections.Immutable", "IImmutableStack", True, "Clear", "()", "", "Argument[this].WithoutElement", "ReturnValue", "value", "manual"] + - ["System.Collections.Immutable", "ImmutableArray", False, "ToImmutableArray", "(System.Span)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["System.Collections.Immutable", "ImmutableArray", False, "ToImmutableArray", "(System.ReadOnlySpan)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - ["System.Collections.Immutable", "ImmutableArray+Builder", False, "AddRange", "(System.Collections.Generic.IEnumerable)", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"] - ["System.Collections.Immutable", "ImmutableArray+Builder", False, "AddRange", "(System.Collections.Immutable.ImmutableArray)", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"] - ["System.Collections.Immutable", "ImmutableArray+Builder", False, "AddRange", "(System.Collections.Immutable.ImmutableArray+Builder)", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"] diff --git a/csharp/ql/lib/ext/System.model.yml b/csharp/ql/lib/ext/System.model.yml index e8bfe9c03ae..36ce30e0ecb 100644 --- a/csharp/ql/lib/ext/System.model.yml +++ b/csharp/ql/lib/ext/System.model.yml @@ -374,6 +374,9 @@ extensions: - ["System", "Lazy", False, "Lazy", "(System.Func,System.Boolean)", "", "Argument[0].ReturnValue", "Argument[this].Property[System.Lazy`1.Value]", "value", "manual"] - ["System", "Lazy", False, "Lazy", "(System.Func,System.Threading.LazyThreadSafetyMode)", "", "Argument[0].ReturnValue", "Argument[this].Property[System.Lazy`1.Value]", "value", "manual"] - ["System", "Lazy", False, "get_Value", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["System", "MemoryExtensions", False, "Replace", "(System.Span,T,T)", "", "Argument[2]", "Argument[0].Element", "value", "manual"] + - ["System", "MemoryExtensions", False, "Replace", "(System.ReadOnlySpan,System.Span,T,T)", "", "Argument[0].Element", "Argument[1].Element", "value", "manual"] + - ["System", "MemoryExtensions", False, "Replace", "(System.ReadOnlySpan,System.Span,T,T)", "", "Argument[3]", "Argument[1].Element", "value", "manual"] - ["System", "Nullable", False, "GetValueOrDefault", "()", "", "Argument[this].Property[System.Nullable`1.Value]", "ReturnValue", "value", "manual"] - ["System", "Nullable", False, "GetValueOrDefault", "(T)", "", "Argument[0]", "ReturnValue", "value", "manual"] - ["System", "Nullable", False, "GetValueOrDefault", "(T)", "", "Argument[this].Property[System.Nullable`1.Value]", "ReturnValue", "value", "manual"] From 4acce3276a3f6432b108aafd8f7a587752715b53 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Fri, 2 Feb 2024 10:10:56 +0100 Subject: [PATCH 21/50] C#: Update FlowSummaries expected output test. --- .../library-tests/dataflow/library/FlowSummaries.expected | 5 +++++ .../dataflow/library/FlowSummariesFiltered.expected | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected b/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected index 3c9ebb33a48..e31b2fb370e 100644 --- a/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected +++ b/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected @@ -5137,6 +5137,8 @@ summary | System.Collections.Immutable;ImmutableArray;false;CreateRange;(System.Collections.Immutable.ImmutableArray,System.Int32,System.Int32,System.Func,TArg);;Argument[3];Argument[3].Parameter[delegate-self];value;hq-generated | | System.Collections.Immutable;ImmutableArray;false;CreateRange;(System.Collections.Immutable.ImmutableArray,System.Func);;Argument[1];Argument[1].Parameter[delegate-self];value;hq-generated | | System.Collections.Immutable;ImmutableArray;false;CreateRange;(System.Collections.Immutable.ImmutableArray,System.Int32,System.Int32,System.Func);;Argument[3];Argument[3].Parameter[delegate-self];value;hq-generated | +| System.Collections.Immutable;ImmutableArray;false;ToImmutableArray;(System.ReadOnlySpan);;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Collections.Immutable;ImmutableArray;false;ToImmutableArray;(System.Span);;Argument[0].Element;ReturnValue.Element;value;manual | | System.Collections.Immutable;ImmutableArray;false;ToImmutableArray;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;df-generated | | System.Collections.Immutable;ImmutableArray+Builder;false;Add;(T);;Argument[0];Argument[this].Element;value;manual | | System.Collections.Immutable;ImmutableArray+Builder;false;AddRange;(System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[this].Element;value;manual | @@ -17709,6 +17711,9 @@ summary | System;MemoryExtensions;false;AsMemory;(T[],System.Range);;Argument[0].Element;ReturnValue;taint;df-generated | | System;MemoryExtensions;false;EnumerateLines;(System.ReadOnlySpan);;Argument[0];ReturnValue;taint;df-generated | | System;MemoryExtensions;false;EnumerateRunes;(System.ReadOnlySpan);;Argument[0];ReturnValue;taint;df-generated | +| System;MemoryExtensions;false;Replace;(System.ReadOnlySpan,System.Span,T,T);;Argument[0].Element;Argument[1].Element;value;manual | +| System;MemoryExtensions;false;Replace;(System.ReadOnlySpan,System.Span,T,T);;Argument[3];Argument[1].Element;value;manual | +| System;MemoryExtensions;false;Replace;(System.Span,T,T);;Argument[2];Argument[0].Element;value;manual | | System;MemoryExtensions;false;Sort;(System.Span,System.Comparison);;Argument[1];Argument[1].Parameter[delegate-self];value;hq-generated | | System;MemoryExtensions;false;Sort;(System.Span,System.Span,System.Comparison);;Argument[2];Argument[2].Parameter[delegate-self];value;hq-generated | | System;MemoryExtensions;false;Trim;(System.Memory);;Argument[0];ReturnValue;taint;df-generated | diff --git a/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected b/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected index 1c3104b1bc9..f418f5f74e0 100644 --- a/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected +++ b/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected @@ -4425,6 +4425,8 @@ summary | System.Collections.Immutable;ImmutableArray;false;CreateRange;(System.Collections.Immutable.ImmutableArray,System.Int32,System.Int32,System.Func,TArg);;Argument[3];Argument[3].Parameter[delegate-self];value;hq-generated | | System.Collections.Immutable;ImmutableArray;false;CreateRange;(System.Collections.Immutable.ImmutableArray,System.Func);;Argument[1];Argument[1].Parameter[delegate-self];value;hq-generated | | System.Collections.Immutable;ImmutableArray;false;CreateRange;(System.Collections.Immutable.ImmutableArray,System.Int32,System.Int32,System.Func);;Argument[3];Argument[3].Parameter[delegate-self];value;hq-generated | +| System.Collections.Immutable;ImmutableArray;false;ToImmutableArray;(System.ReadOnlySpan);;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Collections.Immutable;ImmutableArray;false;ToImmutableArray;(System.Span);;Argument[0].Element;ReturnValue.Element;value;manual | | System.Collections.Immutable;ImmutableArray;false;ToImmutableArray;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;df-generated | | System.Collections.Immutable;ImmutableArray+Builder;false;AddRange;(System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[this].Element;value;manual | | System.Collections.Immutable;ImmutableArray+Builder;false;AddRange;(System.Collections.Immutable.ImmutableArray);;Argument[0].Element;Argument[this].Element;value;manual | @@ -15265,6 +15267,9 @@ summary | System;MemoryExtensions;false;AsMemory;(T[],System.Range);;Argument[0].Element;ReturnValue;taint;df-generated | | System;MemoryExtensions;false;EnumerateLines;(System.ReadOnlySpan);;Argument[0];ReturnValue;taint;df-generated | | System;MemoryExtensions;false;EnumerateRunes;(System.ReadOnlySpan);;Argument[0];ReturnValue;taint;df-generated | +| System;MemoryExtensions;false;Replace;(System.ReadOnlySpan,System.Span,T,T);;Argument[0].Element;Argument[1].Element;value;manual | +| System;MemoryExtensions;false;Replace;(System.ReadOnlySpan,System.Span,T,T);;Argument[3];Argument[1].Element;value;manual | +| System;MemoryExtensions;false;Replace;(System.Span,T,T);;Argument[2];Argument[0].Element;value;manual | | System;MemoryExtensions;false;Sort;(System.Span,System.Comparison);;Argument[1];Argument[1].Parameter[delegate-self];value;hq-generated | | System;MemoryExtensions;false;Sort;(System.Span,System.Span,System.Comparison);;Argument[2];Argument[2].Parameter[delegate-self];value;hq-generated | | System;MemoryExtensions;false;Trim;(System.Memory);;Argument[0];ReturnValue;taint;df-generated | From 38781928102de439869a03e48379632e16b053c5 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Fri, 2 Feb 2024 17:21:23 +0000 Subject: [PATCH 22/50] Apply suggestions from documentation review Co-authored-by: Ben Ahmady <32935794+subatoi@users.noreply.github.com> --- .../src/Security/CWE/CWE-200/AndroidSensitiveTextField.qhelp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/ql/src/Security/CWE/CWE-200/AndroidSensitiveTextField.qhelp b/java/ql/src/Security/CWE/CWE-200/AndroidSensitiveTextField.qhelp index dc4f30a1dce..8658a8abfd0 100644 --- a/java/ql/src/Security/CWE/CWE-200/AndroidSensitiveTextField.qhelp +++ b/java/ql/src/Security/CWE/CWE-200/AndroidSensitiveTextField.qhelp @@ -11,13 +11,13 @@

    For editable text fields containing sensitive information, the inputType should be set to textPassword or similar to ensure it is properly masked. - Otherwise, sensitive data that is required to be displayed should be hidden by default, and only revealed based on an explicit user action. + Otherwise, sensitive data that must be displayed should be hidden by default, and only revealed based on an explicit user action.

    - In the following (bad) case, sensitive information password is exposed to the TextView. + In the following (bad) case, sensitive information in password is exposed to the TextView.

    From 9f7f9fcc6e811b58ad3bb69324215d28f82093d7 Mon Sep 17 00:00:00 2001 From: James Ockers Date: Fri, 2 Feb 2024 11:38:17 -0800 Subject: [PATCH 23/50] Updating change-notes to reflect what will be the visible change to end users --- .../change-notes/2024-01-30-certification_not_certificate.md | 2 +- .../change-notes/2024-01-30-certification_not_certificate.md | 2 +- .../change-notes/2024-01-30-certification_not_certificate.md | 2 +- .../change-notes/2024-01-30-certification_not_certificate.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/javascript/ql/lib/change-notes/2024-01-30-certification_not_certificate.md b/javascript/ql/lib/change-notes/2024-01-30-certification_not_certificate.md index fa0e0026dbe..bfd7ab63dab 100644 --- a/javascript/ql/lib/change-notes/2024-01-30-certification_not_certificate.md +++ b/javascript/ql/lib/change-notes/2024-01-30-certification_not_certificate.md @@ -1,4 +1,4 @@ --- category: minorAnalysis --- -* The string "certification" isn't a certificate, and should be excluded from the maybeCertificate() regex. +* The name "certification" is no longer seen as possibly being a certificate, and will therefore no longer be flagged in queries like "clear-text-logging" which look for sensitive data. diff --git a/python/ql/lib/change-notes/2024-01-30-certification_not_certificate.md b/python/ql/lib/change-notes/2024-01-30-certification_not_certificate.md index fa0e0026dbe..bfd7ab63dab 100644 --- a/python/ql/lib/change-notes/2024-01-30-certification_not_certificate.md +++ b/python/ql/lib/change-notes/2024-01-30-certification_not_certificate.md @@ -1,4 +1,4 @@ --- category: minorAnalysis --- -* The string "certification" isn't a certificate, and should be excluded from the maybeCertificate() regex. +* The name "certification" is no longer seen as possibly being a certificate, and will therefore no longer be flagged in queries like "clear-text-logging" which look for sensitive data. diff --git a/ruby/ql/lib/change-notes/2024-01-30-certification_not_certificate.md b/ruby/ql/lib/change-notes/2024-01-30-certification_not_certificate.md index fa0e0026dbe..bfd7ab63dab 100644 --- a/ruby/ql/lib/change-notes/2024-01-30-certification_not_certificate.md +++ b/ruby/ql/lib/change-notes/2024-01-30-certification_not_certificate.md @@ -1,4 +1,4 @@ --- category: minorAnalysis --- -* The string "certification" isn't a certificate, and should be excluded from the maybeCertificate() regex. +* The name "certification" is no longer seen as possibly being a certificate, and will therefore no longer be flagged in queries like "clear-text-logging" which look for sensitive data. diff --git a/swift/ql/lib/change-notes/2024-01-30-certification_not_certificate.md b/swift/ql/lib/change-notes/2024-01-30-certification_not_certificate.md index fa0e0026dbe..bfd7ab63dab 100644 --- a/swift/ql/lib/change-notes/2024-01-30-certification_not_certificate.md +++ b/swift/ql/lib/change-notes/2024-01-30-certification_not_certificate.md @@ -1,4 +1,4 @@ --- category: minorAnalysis --- -* The string "certification" isn't a certificate, and should be excluded from the maybeCertificate() regex. +* The name "certification" is no longer seen as possibly being a certificate, and will therefore no longer be flagged in queries like "clear-text-logging" which look for sensitive data. From ee5df7bf585fbb0019d7dfa514aac9b777c61468 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 00:16:44 +0000 Subject: [PATCH 24/50] Add changed framework coverage reports --- java/documentation/library-coverage/coverage.csv | 2 +- java/documentation/library-coverage/coverage.rst | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/java/documentation/library-coverage/coverage.csv b/java/documentation/library-coverage/coverage.csv index 520d175aa5e..05fc3c67ada 100644 --- a/java/documentation/library-coverage/coverage.csv +++ b/java/documentation/library-coverage/coverage.csv @@ -77,7 +77,7 @@ jakarta.xml.bind.attachment,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,, java.awt,1,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,3 java.beans,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, java.io,50,1,46,,,,,,,,,22,,,,,,,,,,,,,,,28,,,,,,,,,,,,,,,,,,,,,1,,44,2 -java.lang,33,3,103,,13,,,,,,1,,,,,,,,,,,,8,,,,6,,,4,,,1,,,,,,,,,,,,,,3,,,60,43 +java.lang,33,3,101,,13,,,,,,1,,,,,,,,,,,,8,,,,6,,,4,,,1,,,,,,,,,,,,,,3,,,58,43 java.net,21,3,23,,,,1,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,19,,,,,,,,,,,,,3,23, java.nio,49,,36,,,,,,,,,5,,,,,,,,,,,,,,,43,,,,,,,,,1,,,,,,,,,,,,,,36, java.security,21,,,,,11,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, diff --git a/java/documentation/library-coverage/coverage.rst b/java/documentation/library-coverage/coverage.rst index 185704348b1..78130e9d9c2 100644 --- a/java/documentation/library-coverage/coverage.rst +++ b/java/documentation/library-coverage/coverage.rst @@ -18,10 +18,10 @@ Java framework & library support `Google Guava `_,``com.google.common.*``,,730,43,9,,,,, JBoss Logging,``org.jboss.logging``,,,324,,,,,, `JSON-java `_,``org.json``,,236,,,,,,, - Java Standard Library,``java.*``,10,733,237,79,,9,,,24 + Java Standard Library,``java.*``,10,731,237,79,,9,,,24 Java extensions,"``javax.*``, ``jakarta.*``",67,688,80,5,4,2,1,1,4 Kotlin Standard Library,``kotlin*``,,1849,16,14,,,,,2 `Spring `_,``org.springframework.*``,38,481,118,5,,28,14,,35 Others,"``actions.osgi``, ``antlr``, ``ch.ethz.ssh2``, ``cn.hutool.core.codec``, ``com.alibaba.druid.sql``, ``com.alibaba.fastjson2``, ``com.amazonaws.auth``, ``com.auth0.jwt.algorithms``, ``com.azure.identity``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.google.gson``, ``com.hubspot.jinjava``, ``com.jcraft.jsch``, ``com.microsoft.sqlserver.jdbc``, ``com.mitchellbosecke.pebble``, ``com.mongodb``, ``com.opensymphony.xwork2``, ``com.rabbitmq.client``, ``com.sshtools.j2ssh.authentication``, ``com.sun.crypto.provider``, ``com.sun.jndi.ldap``, ``com.sun.net.httpserver``, ``com.sun.net.ssl``, ``com.sun.rowset``, ``com.sun.security.auth.module``, ``com.sun.security.ntlm``, ``com.sun.security.sasl.digest``, ``com.thoughtworks.xstream``, ``com.trilead.ssh2``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``freemarker.cache``, ``freemarker.template``, ``groovy.lang``, ``groovy.text``, ``groovy.util``, ``hudson``, ``io.jsonwebtoken``, ``io.netty.bootstrap``, ``io.netty.buffer``, ``io.netty.channel``, ``io.netty.handler.codec``, ``io.netty.handler.ssl``, ``io.netty.handler.stream``, ``io.netty.resolver``, ``io.netty.util``, ``javafx.scene.web``, ``jenkins``, ``jodd.json``, ``liquibase.database.jvm``, ``liquibase.statement.core``, ``net.schmizz.sshj``, ``net.sf.json``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.acegisecurity``, ``org.antlr.runtime``, ``org.apache.commons.codec``, ``org.apache.commons.compress.archivers.tar``, ``org.apache.commons.exec``, ``org.apache.commons.httpclient.util``, ``org.apache.commons.jelly``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.lang``, ``org.apache.commons.logging``, ``org.apache.commons.net``, ``org.apache.commons.ognl``, ``org.apache.cxf.catalog``, ``org.apache.cxf.common.classloader``, ``org.apache.cxf.common.jaxb``, ``org.apache.cxf.common.logging``, ``org.apache.cxf.configuration.jsse``, ``org.apache.cxf.helpers``, ``org.apache.cxf.resource``, ``org.apache.cxf.staxutils``, ``org.apache.cxf.tools.corba.utils``, ``org.apache.cxf.tools.util``, ``org.apache.cxf.transform``, ``org.apache.directory.ldap.client.api``, ``org.apache.hadoop.fs``, ``org.apache.hadoop.hive.metastore``, ``org.apache.hadoop.hive.ql.exec``, ``org.apache.hadoop.hive.ql.metadata``, ``org.apache.hc.client5.http.async.methods``, ``org.apache.hc.client5.http.classic.methods``, ``org.apache.hc.client5.http.fluent``, ``org.apache.hive.hcatalog.templeton``, ``org.apache.ibatis.jdbc``, ``org.apache.ibatis.mapping``, ``org.apache.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.apache.shiro.mgt``, ``org.apache.sshd.client.session``, ``org.apache.struts.beanvalidation.validation.interceptor``, ``org.apache.struts2``, ``org.apache.tools.ant``, ``org.apache.tools.zip``, ``org.apache.velocity.app``, ``org.apache.velocity.runtime``, ``org.codehaus.cargo.container.installer``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.eclipse.jetty.client``, ``org.fusesource.leveldbjni``, ``org.geogebra.web.full.main``, ``org.gradle.api.file``, ``org.hibernate``, ``org.influxdb``, ``org.jdbi.v3.core``, ``org.jenkins.ui.icon``, ``org.jenkins.ui.symbol``, ``org.jooq``, ``org.keycloak.models.map.storage``, ``org.kohsuke.stapler``, ``org.mvel2``, ``org.openjdk.jmh.runner.options``, ``org.owasp.esapi``, ``org.pac4j.jwt.config.encryption``, ``org.pac4j.jwt.config.signature``, ``org.scijava.log``, ``org.slf4j``, ``org.thymeleaf``, ``org.xml.sax``, ``org.xmlpull.v1``, ``org.yaml.snakeyaml``, ``play.libs.ws``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``, ``retrofit2``, ``sun.jvmstat.perfdata.monitor.protocol.local``, ``sun.jvmstat.perfdata.monitor.protocol.rmi``, ``sun.misc``, ``sun.net.ftp``, ``sun.net.www.protocol.http``, ``sun.security.acl``, ``sun.security.jgss.krb5``, ``sun.security.krb5``, ``sun.security.pkcs``, ``sun.security.pkcs11``, ``sun.security.provider``, ``sun.security.ssl``, ``sun.security.x509``, ``sun.tools.jconsole``",131,10516,889,121,6,22,18,,208 - Totals,,308,18947,2551,331,16,128,33,1,407 + Totals,,308,18945,2551,331,16,128,33,1,407 From c2c7826936b5af7475a9c8dfb7675d6d36986554 Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Mon, 5 Feb 2024 13:09:04 +0100 Subject: [PATCH 25/50] C#: Extract dependency restore telemetry data --- .../DependencyManager.cs | 70 +++++++++++++++++-- .../NugetPackages.cs | 17 ++++- .../Extractor.cs | 19 +++-- .../Program.cs | 3 + .../Extractor/Analyser.cs | 5 +- .../Extractor/StandaloneAnalyser.cs | 4 +- .../Semmle.Extraction.CSharp/Tuples.cs | 3 + .../Semmle.Extraction/Extractor/Extractor.cs | 6 +- .../Extractor/StandaloneExtractor.cs | 3 +- .../Extractor/TracingExtractor.cs | 3 +- .../code/csharp/commons/Compilation.qll | 5 ++ csharp/ql/lib/semmlecode.csharp.dbscheme | 6 ++ .../ql/src/Telemetry/ExtractorInformation.ql | 13 ++++ 13 files changed, 133 insertions(+), 24 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs index 9a29a8c3cda..44925dc1d68 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs @@ -133,6 +133,17 @@ namespace Semmle.Extraction.CSharp.DependencyFetching logger.LogInfo($"{conflictedReferences,align} resolved assembly conflicts"); logger.LogInfo($"{dotnetFrameworkVersionVariantCount,align} restored .NET framework variants"); logger.LogInfo($"Build analysis completed in {DateTime.Now - startTime}"); + + CompilationInfos.AddRange([ + ("Source files on filesystem", nonGeneratedSources.Count.ToString()), + ("Source files generated", generatedSources.Count.ToString()), + ("Solution files on filesystem", allSolutions.Count.ToString()), + ("Project files on filesystem", allProjects.Count.ToString()), + ("Resolved references", usedReferences.Keys.Count.ToString()), + ("Unresolved references", unresolvedReferences.Count.ToString()), + ("Resolved assembly conflicts", conflictedReferences.ToString()), + ("Restored .NET framework variants", dotnetFrameworkVersionVariantCount.ToString()), + ]); } private HashSet AddFrameworkDlls(HashSet dllPaths) @@ -146,12 +157,18 @@ namespace Semmle.Extraction.CSharp.DependencyFetching return frameworkLocations; } - private void RestoreNugetPackages(List allNonBinaryFiles, IEnumerable allProjects, IEnumerable allSolutions, HashSet dllPaths) + private void RestoreNugetPackages(List allNonBinaryFiles, List allProjects, List allSolutions, HashSet dllPaths) { try { var nuget = new NugetPackages(sourceDir.FullName, legacyPackageDirectory, logger); - nuget.InstallPackages(); + var count = nuget.InstallPackages(); + + if (nuget.PackageCount > 0) + { + CompilationInfos.Add(("packages.config files", nuget.PackageCount.ToString())); + CompilationInfos.Add(("Successfully restored packages.config files", count.ToString())); + } var nugetPackageDlls = legacyPackageDirectory.DirInfo.GetFiles("*.dll", new EnumerationOptions { RecurseSubdirectories = true }); var nugetPackageDllPaths = nugetPackageDlls.Select(f => f.FullName).ToHashSet(); @@ -629,6 +646,11 @@ namespace Semmle.Extraction.CSharp.DependencyFetching /// public IEnumerable UnresolvedReferences => unresolvedReferences.Select(r => r.Key); + /// + /// List of `(key, value)` tuples, that are stored in the DB for telemetry purposes. + /// + public List<(string, string)> CompilationInfos { get; } = new List<(string, string)>(); + /// /// Record that a particular reference couldn't be resolved. /// Note that this records at most one project file per missing reference. @@ -697,17 +719,24 @@ namespace Semmle.Extraction.CSharp.DependencyFetching /// Returns a list of projects that are up to date with respect to restore. /// /// A list of paths to solution files. - private IEnumerable RestoreSolutions(IEnumerable solutions, out IEnumerable assets) + private IEnumerable RestoreSolutions(List solutions, out IEnumerable assets) { + var successCount = 0; var assetFiles = new List(); var projects = solutions.SelectMany(solution => { logger.LogInfo($"Restoring solution {solution}..."); var res = dotnet.Restore(new(solution, packageDirectory.DirInfo.FullName, ForceDotnetRefAssemblyFetching: true)); + if (res.Success) + { + successCount++; + } assetFiles.AddRange(res.AssetsFilePaths); return res.RestoredProjects; - }); + }).ToList(); assets = assetFiles; + CompilationInfos.Add(("Successfully restored solution files", successCount.ToString())); + CompilationInfos.Add(("Restored projects through solution files", projects.Count.ToString())); return projects; } @@ -719,14 +748,24 @@ namespace Semmle.Extraction.CSharp.DependencyFetching /// A list of paths to project files. private void RestoreProjects(IEnumerable projects, out IEnumerable assets) { + var successCount = 0; var assetFiles = new List(); + var sync = new object(); Parallel.ForEach(projects, new ParallelOptions { MaxDegreeOfParallelism = options.Threads }, project => { logger.LogInfo($"Restoring project {project}..."); var res = dotnet.Restore(new(project, packageDirectory.DirInfo.FullName, ForceDotnetRefAssemblyFetching: true)); - assetFiles.AddRange(res.AssetsFilePaths); + lock (sync) + { + if (res.Success) + { + successCount++; + } + assetFiles.AddRange(res.AssetsFilePaths); + } }); assets = assetFiles; + CompilationInfos.Add(("Successfully restored project files", successCount.ToString())); } private void DownloadMissingPackages(List allFiles, ISet dllPaths) @@ -767,6 +806,11 @@ namespace Semmle.Extraction.CSharp.DependencyFetching logger.LogInfo($"Using nuget.config file {nugetConfig}."); } + CompilationInfos.Add(("Fallback nuget restore", notYetDownloadedPackages.Count.ToString())); + + var successCount = 0; + var sync = new object(); + Parallel.ForEach(notYetDownloadedPackages, new ParallelOptions { MaxDegreeOfParallelism = options.Threads }, package => { logger.LogInfo($"Restoring package {package}..."); @@ -798,9 +842,25 @@ namespace Semmle.Extraction.CSharp.DependencyFetching { logger.LogInfo($"Failed to restore nuget package {package}"); } + else + { + lock (sync) + { + successCount++; + } + } + } + else + { + lock (sync) + { + successCount++; + } } }); + CompilationInfos.Add(("Successfully ran fallback nuget restore", successCount.ToString())); + dllPaths.Add(missingPackageDirectory.DirInfo.FullName); } diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackages.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackages.cs index 52e5ccc4ff5..89970a221a1 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackages.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackages.cs @@ -22,6 +22,8 @@ namespace Semmle.Extraction.CSharp.DependencyFetching /// private readonly FileInfo[] packageFiles; + public int PackageCount => packageFiles.Length; + /// /// The computed packages directory. /// This will be in the Temp location @@ -105,7 +107,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching /// Restore all files in a specified package. /// /// The package file. - private void RestoreNugetPackage(string package) + private bool RestoreNugetPackage(string package) { logger.LogInfo($"Restoring file {package}..."); @@ -141,22 +143,31 @@ namespace Semmle.Extraction.CSharp.DependencyFetching if (exitCode != 0) { logger.LogError($"Command {pi.FileName} {pi.Arguments} failed with exit code {exitCode}"); + return false; } else { logger.LogInfo($"Restored file {package}"); + return true; } } /// /// Download the packages to the temp folder. /// - public void InstallPackages() + public int InstallPackages() { + var success = 0; foreach (var package in packageFiles) { - RestoreNugetPackage(package.FullName); + var result = RestoreNugetPackage(package.FullName); + if (result) + { + success++; + } } + + return success; } } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Extractor.cs b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Extractor.cs index 6e2f913873a..829591818d5 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Extractor.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Extractor.cs @@ -24,8 +24,7 @@ namespace Semmle.Extraction.CSharp.Standalone private static void AnalyseStandalone( StandaloneAnalyser analyser, - IEnumerable sources, - IEnumerable referencePaths, + ExtractionInput extractionInput, CommonOptions options, IProgressMonitor progressMonitor, Stopwatch stopwatch) @@ -35,12 +34,12 @@ namespace Semmle.Extraction.CSharp.Standalone try { CSharp.Extractor.Analyse(stopwatch, analyser, options, - references => GetResolvedReferencesStandalone(referencePaths, references), - (analyser, syntaxTrees) => CSharp.Extractor.ReadSyntaxTrees(sources, analyser, null, null, syntaxTrees), + references => GetResolvedReferencesStandalone(extractionInput.References, references), + (analyser, syntaxTrees) => CSharp.Extractor.ReadSyntaxTrees(extractionInput.Sources, analyser, null, null, syntaxTrees), (syntaxTrees, references) => CSharpCompilation.Create( output.Name, syntaxTrees, references, new CSharpCompilationOptions(OutputKind.ConsoleApplication, allowUnsafe: true) ), - (compilation, options) => analyser.Initialize(output.FullName, compilation, options), + (compilation, options) => analyser.Initialize(output.FullName, extractionInput.CompilationInfos, compilation, options), _ => { }, () => { @@ -73,8 +72,7 @@ namespace Semmle.Extraction.CSharp.Standalone } private static void ExtractStandalone( - IEnumerable sources, - IEnumerable referencePaths, + ExtractionInput extractionInput, IProgressMonitor pm, ILogger logger, CommonOptions options) @@ -88,7 +86,7 @@ namespace Semmle.Extraction.CSharp.Standalone using var analyser = new StandaloneAnalyser(pm, logger, false, pathTransformer); try { - AnalyseStandalone(analyser, sources, referencePaths, options, pm, stopwatch); + AnalyseStandalone(analyser, extractionInput, options, pm, stopwatch); } catch (Exception ex) // lgtm[cs/catch-of-all-exceptions] { @@ -131,6 +129,8 @@ namespace Semmle.Extraction.CSharp.Standalone } } + public record ExtractionInput(IEnumerable Sources, IEnumerable References, IEnumerable<(string, string)> CompilationInfos); + public static ExitCode Run(Options options) { var stopwatch = new Stopwatch(); @@ -152,8 +152,7 @@ namespace Semmle.Extraction.CSharp.Standalone logger.Log(Severity.Info, ""); logger.Log(Severity.Info, "Extracting..."); ExtractStandalone( - a.Extraction.Sources, - a.References, + new ExtractionInput(a.Extraction.Sources, a.References, a.CompilationInfos), new ExtractionProgress(logger), fileLogger, options); diff --git a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Program.cs b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Program.cs index 5b9d40ba8a7..8437896c807 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Program.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Program.cs @@ -30,6 +30,7 @@ namespace Semmle.Extraction.CSharp.Standalone References = dependencyManager.ReferenceFiles; Extraction = new Extraction(options.SrcDir); Extraction.Sources.AddRange(dependencyManager.AllSourceFiles); + CompilationInfos = dependencyManager.CompilationInfos; } public IEnumerable References { get; } @@ -39,6 +40,8 @@ namespace Semmle.Extraction.CSharp.Standalone /// public Extraction Extraction { get; } + public IEnumerable<(string, string)> CompilationInfos { get; } + private readonly DependencyManager dependencyManager; public void Dispose() diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Analyser.cs b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Analyser.cs index d242ee5c9ef..51a63cef5f5 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Analyser.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Analyser.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; +using Semmle.Util; using Semmle.Util.Logging; using Semmle.Extraction.CSharp.Populators; @@ -20,7 +21,7 @@ namespace Semmle.Extraction.CSharp protected CSharpCompilation? compilation; protected CommonOptions? options; private protected Entities.Compilation? compilationEntity; - private IDisposable? compilationTrapFile; + private TrapWriter? compilationTrapFile; private readonly object progressMutex = new object(); @@ -240,6 +241,8 @@ namespace Semmle.Extraction.CSharp var cx = new Context(extractor, compilation.Clone(), trapWriter, new AssemblyScope(assembly, assemblyPath), addAssemblyTrapPrefix); compilationEntity = Entities.Compilation.Create(cx); + + extractor.CompilationInfos?.ForEach(ci => trapWriter.Writer.compilation_info(compilationEntity, ci.key, ci.value)); } catch (Exception ex) // lgtm[cs/catch-of-all-exceptions] { diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/StandaloneAnalyser.cs b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/StandaloneAnalyser.cs index 3ae7b8a1d0e..d559d091214 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/StandaloneAnalyser.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/StandaloneAnalyser.cs @@ -13,10 +13,10 @@ namespace Semmle.Extraction.CSharp { } - public void Initialize(string outputPath, CSharpCompilation compilationIn, CommonOptions options) + public void Initialize(string outputPath, IEnumerable<(string, string)> compilationInfos, CSharpCompilation compilationIn, CommonOptions options) { compilation = compilationIn; - extractor = new StandaloneExtractor(outputPath, Logger, PathTransformer, options); + extractor = new StandaloneExtractor(outputPath, compilationInfos, Logger, PathTransformer, options); this.options = options; LogExtractorInfo(Extraction.Extractor.Version); SetReferencePaths(); diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Tuples.cs b/csharp/extractor/Semmle.Extraction.CSharp/Tuples.cs index 4b89e1077f0..6f61119eb77 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Tuples.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Tuples.cs @@ -71,6 +71,9 @@ namespace Semmle.Extraction.CSharp internal static void compilation_expanded_args(this TextWriter trapFile, Compilation compilation, int index, string arg) => trapFile.WriteTuple("compilation_expanded_args", compilation, index, arg); + internal static void compilation_info(this TextWriter trapFile, Compilation compilation, string infoKey, string infoValue) => + trapFile.WriteTuple("compilation_info", compilation, infoKey, infoValue); + internal static void compilation_compiling_files(this TextWriter trapFile, Compilation compilation, int index, Extraction.Entities.File file) => trapFile.WriteTuple("compilation_compiling_files", compilation, index, file); diff --git a/csharp/extractor/Semmle.Extraction/Extractor/Extractor.cs b/csharp/extractor/Semmle.Extraction/Extractor/Extractor.cs index e4284f97cfd..362b7910c56 100644 --- a/csharp/extractor/Semmle.Extraction/Extractor/Extractor.cs +++ b/csharp/extractor/Semmle.Extraction/Extractor/Extractor.cs @@ -1,6 +1,8 @@ using System.Collections.Generic; using Semmle.Util.Logging; +using CompilationInfo = (string key, string value); + namespace Semmle.Extraction { /// @@ -10,17 +12,19 @@ namespace Semmle.Extraction { public abstract ExtractorMode Mode { get; } public string OutputPath { get; } + public IEnumerable CompilationInfos { get; } /// /// Creates a new extractor instance for one compilation unit. /// /// The object used for logging. /// The object used for path transformations. - protected Extractor(string outputPath, ILogger logger, PathTransformer pathTransformer) + protected Extractor(string outputPath, IEnumerable compilationInfos, ILogger logger, PathTransformer pathTransformer) { OutputPath = outputPath; Logger = logger; PathTransformer = pathTransformer; + CompilationInfos = compilationInfos; } // Limit the number of error messages in the log file diff --git a/csharp/extractor/Semmle.Extraction/Extractor/StandaloneExtractor.cs b/csharp/extractor/Semmle.Extraction/Extractor/StandaloneExtractor.cs index d9f8725a1e2..67079a73214 100644 --- a/csharp/extractor/Semmle.Extraction/Extractor/StandaloneExtractor.cs +++ b/csharp/extractor/Semmle.Extraction/Extractor/StandaloneExtractor.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using Semmle.Util.Logging; namespace Semmle.Extraction @@ -11,7 +12,7 @@ namespace Semmle.Extraction /// /// The object used for logging. /// The object used for path transformations. - public StandaloneExtractor(string outputPath, ILogger logger, PathTransformer pathTransformer, CommonOptions options) : base(outputPath, logger, pathTransformer) + public StandaloneExtractor(string outputPath, IEnumerable<(string, string)> compilationInfos, ILogger logger, PathTransformer pathTransformer, CommonOptions options) : base(outputPath, compilationInfos, logger, pathTransformer) { Mode = ExtractorMode.Standalone; if (options.QlTest) diff --git a/csharp/extractor/Semmle.Extraction/Extractor/TracingExtractor.cs b/csharp/extractor/Semmle.Extraction/Extractor/TracingExtractor.cs index dadda4c8488..4d54aef6d5b 100644 --- a/csharp/extractor/Semmle.Extraction/Extractor/TracingExtractor.cs +++ b/csharp/extractor/Semmle.Extraction/Extractor/TracingExtractor.cs @@ -1,3 +1,4 @@ +using System.Linq; using Semmle.Util.Logging; namespace Semmle.Extraction @@ -12,7 +13,7 @@ namespace Semmle.Extraction /// The name of the output DLL/EXE, or null if not specified (standalone extraction). /// The object used for logging. /// The object used for path transformations. - public TracingExtractor(string outputPath, ILogger logger, PathTransformer pathTransformer, CommonOptions options) : base(outputPath, logger, pathTransformer) + public TracingExtractor(string outputPath, ILogger logger, PathTransformer pathTransformer, CommonOptions options) : base(outputPath, Enumerable.Empty<(string, string)>(), logger, pathTransformer) { Mode = ExtractorMode.None; if (options.QlTest) diff --git a/csharp/ql/lib/semmle/code/csharp/commons/Compilation.qll b/csharp/ql/lib/semmle/code/csharp/commons/Compilation.qll index df53084c835..c72a40e9ae0 100644 --- a/csharp/ql/lib/semmle/code/csharp/commons/Compilation.qll +++ b/csharp/ql/lib/semmle/code/csharp/commons/Compilation.qll @@ -83,4 +83,9 @@ class Compilation extends @compilation { /** Gets the elapsed seconds for the entire extractor process. */ float getElapsedSeconds() { compilation_finished(this, _, result) } + + /** + * Gets the piece of compilation information with the given key, if any. + */ + string getInfo(string key) { compilation_info(this, key, result) } } diff --git a/csharp/ql/lib/semmlecode.csharp.dbscheme b/csharp/ql/lib/semmlecode.csharp.dbscheme index f145a9a7275..c9ee11bd1ee 100644 --- a/csharp/ql/lib/semmlecode.csharp.dbscheme +++ b/csharp/ql/lib/semmlecode.csharp.dbscheme @@ -24,6 +24,12 @@ compilations( string cwd : string ref ); +compilation_info( + int id : @compilation ref, + string info_key: string ref, + string info_value: string ref +) + /** * The arguments that were passed to the extractor for a compiler * invocation. If `id` is for the compiler invocation diff --git a/csharp/ql/src/Telemetry/ExtractorInformation.ql b/csharp/ql/src/Telemetry/ExtractorInformation.ql index 13eff511ee8..6d015b3e659 100644 --- a/csharp/ql/src/Telemetry/ExtractorInformation.ql +++ b/csharp/ql/src/Telemetry/ExtractorInformation.ql @@ -9,6 +9,18 @@ import csharp import semmle.code.csharp.commons.Diagnostics +predicate compilationInfo(string key, float value) { + exists(Compilation c, string infoKey, string infoValue | infoValue = c.getInfo(infoKey) | + exists(infoValue.toFloat()) and + key = infoKey and + value = infoValue.toFloat() + or + not exists(infoValue.toFloat()) and + key = infoKey + ": " + infoValue and + value = 1 + ) +} + predicate fileCount(string key, int value) { key = "Number of files" and value = strictcount(File f) @@ -177,6 +189,7 @@ predicate analyzerAssemblies(string key, float value) { from string key, float value where ( + compilationInfo(key, value) or fileCount(key, value) or fileCountByExtension(key, value) or totalNumberOfLines(key, value) or From 5d08dc748dc709fd3f6ffeea4fe8b4594585d290 Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Mon, 5 Feb 2024 13:45:31 +0100 Subject: [PATCH 26/50] Add DB upgrade downgrade script --- .../old.dbscheme | 2100 +++++++++++++++++ .../semmlecode.csharp.dbscheme | 2094 ++++++++++++++++ .../upgrade.properties | 3 + .../old.dbscheme | 2094 ++++++++++++++++ .../semmlecode.csharp.dbscheme | 2100 +++++++++++++++++ .../upgrade.properties | 2 + 6 files changed, 8393 insertions(+) create mode 100644 csharp/downgrades/c9ee11bd1ee96e925a35cedff000be924634447f/old.dbscheme create mode 100644 csharp/downgrades/c9ee11bd1ee96e925a35cedff000be924634447f/semmlecode.csharp.dbscheme create mode 100644 csharp/downgrades/c9ee11bd1ee96e925a35cedff000be924634447f/upgrade.properties create mode 100644 csharp/ql/lib/upgrades/f145a9a7275c8f457b392b2ebc9f8e07960a0ed2/old.dbscheme create mode 100644 csharp/ql/lib/upgrades/f145a9a7275c8f457b392b2ebc9f8e07960a0ed2/semmlecode.csharp.dbscheme create mode 100644 csharp/ql/lib/upgrades/f145a9a7275c8f457b392b2ebc9f8e07960a0ed2/upgrade.properties diff --git a/csharp/downgrades/c9ee11bd1ee96e925a35cedff000be924634447f/old.dbscheme b/csharp/downgrades/c9ee11bd1ee96e925a35cedff000be924634447f/old.dbscheme new file mode 100644 index 00000000000..c9ee11bd1ee --- /dev/null +++ b/csharp/downgrades/c9ee11bd1ee96e925a35cedff000be924634447f/old.dbscheme @@ -0,0 +1,2100 @@ +/* This is a dummy line to alter the dbscheme, so we can make a database upgrade + * without actually changing any of the dbscheme predicates. It contains a date + * to allow for such updates in the future as well. + * + * 2021-07-14 + * + * DO NOT remove this comment carelessly, since it can revert the dbscheme back to a + * previously seen state (matching a previously seen SHA), which would make the upgrade + * mechanism not work properly. + */ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * csc f1.cs f2.cs f3.cs + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + unique int id : @compilation, + string cwd : string ref +); + +compilation_info( + int id : @compilation ref, + string info_key: string ref, + string info_value: string ref +) + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | --compiler + * 1 | *path to compiler* + * 2 | f1.cs + * 3 | f2.cs + * 4 | f3.cs + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The expanded arguments that were passed to the extractor for a + * compiler invocation. This is similar to `compilation_args`, but + * for a `@someFile.rsp` argument, it includes the arguments from that + * file, rather than just taking the argument literally. + */ +#keyset[id, num] +compilation_expanded_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.cs + * 1 | f2.cs + * 2 | f3.cs + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The references used by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs /r:ref1.dll /r:ref2.dll /r:ref3.dll + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | ref1.dll + * 1 | ref2.dll + * 2 | ref3.dll + */ +#keyset[id, num] +compilation_referencing_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location ref +); + +extractor_messages( + unique int id: @extractor_message, + int severity: int ref, + string origin : string ref, + string text : string ref, + string entity : string ref, + int location: @location ref, + string stack_trace : string ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +compilation_assembly( + unique int id : @compilation ref, + int assembly: @assembly ref +) + +// Populated by the CSV extractor +externalData( + int id: @externalDataElement, + string path: string ref, + int column: int ref, + string value: string ref); + +sourceLocationPrefix( + string prefix: string ref); + +/* + * C# dbscheme + */ + +/** ELEMENTS **/ + +@element = @declaration | @stmt | @expr | @modifier | @attribute | @namespace_declaration + | @using_directive | @type_parameter_constraints | @externalDataElement + | @xmllocatable | @asp_element | @namespace | @preprocessor_directive; + +@declaration = @callable | @generic | @assignable | @namespace; + +@named_element = @namespace | @declaration; + +@declaration_with_accessors = @property | @indexer | @event; + +@assignable = @variable | @assignable_with_accessors | @event; + +@assignable_with_accessors = @property | @indexer; + +@attributable = @assembly | @field | @parameter | @operator | @method | @constructor + | @destructor | @callable_accessor | @value_or_ref_type | @declaration_with_accessors + | @local_function | @lambda_expr; + +/** LOCATIONS, ASEMMBLIES, MODULES, FILES and FOLDERS **/ + +@location = @location_default | @assembly; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +locations_mapped( + unique int id: @location_default ref, + int mapped_to: @location_default ref); + +@sourceline = @file | @callable | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref); + +assemblies( + unique int id: @assembly, + int file: @file ref, + string fullname: string ref, + string name: string ref, + string version: string ref); + +files( + unique int id: @file, + string name: string ref); + +folders( + unique int id: @folder, + string name: string ref); + +@container = @folder | @file ; + +containerparent( + int parent: @container ref, + unique int child: @container ref); + +file_extraction_mode( + unique int file: @file ref, + int mode: int ref + /* 0 = normal, 1 = standalone extractor */ + ); + +/** NAMESPACES **/ + +@type_container = @namespace | @type; + +namespaces( + unique int id: @namespace, + string name: string ref); + +namespace_declarations( + unique int id: @namespace_declaration, + int namespace_id: @namespace ref); + +namespace_declaration_location( + unique int id: @namespace_declaration ref, + int loc: @location ref); + +parent_namespace( + unique int child_id: @type_container ref, + int namespace_id: @namespace ref); + +@declaration_or_directive = @namespace_declaration | @type | @using_directive; + +parent_namespace_declaration( + int child_id: @declaration_or_directive ref, // cannot be unique because of partial classes + int namespace_id: @namespace_declaration ref); + +@using_directive = @using_namespace_directive | @using_static_directive; + +using_global( + unique int id: @using_directive ref +); + +using_namespace_directives( + unique int id: @using_namespace_directive, + int namespace_id: @namespace ref); + +using_static_directives( + unique int id: @using_static_directive, + int type_id: @type_or_ref ref); + +using_directive_location( + unique int id: @using_directive ref, + int loc: @location ref); + +@preprocessor_directive = @pragma_warning | @pragma_checksum | @directive_define | @directive_undefine | @directive_warning + | @directive_error | @directive_nullable | @directive_line | @directive_region | @directive_endregion | @directive_if + | @directive_elif | @directive_else | @directive_endif; + +@conditional_directive = @directive_if | @directive_elif; +@branch_directive = @directive_if | @directive_elif | @directive_else; + +directive_ifs( + unique int id: @directive_if, + int branchTaken: int ref, /* 0: false, 1: true */ + int conditionValue: int ref); /* 0: false, 1: true */ + +directive_elifs( + unique int id: @directive_elif, + int branchTaken: int ref, /* 0: false, 1: true */ + int conditionValue: int ref, /* 0: false, 1: true */ + int parent: @directive_if ref, + int index: int ref); + +directive_elses( + unique int id: @directive_else, + int branchTaken: int ref, /* 0: false, 1: true */ + int parent: @directive_if ref, + int index: int ref); + +#keyset[id, start] +directive_endifs( + unique int id: @directive_endif, + unique int start: @directive_if ref); + +directive_define_symbols( + unique int id: @define_symbol_expr ref, + string name: string ref); + +directive_regions( + unique int id: @directive_region, + string name: string ref); + +#keyset[id, start] +directive_endregions( + unique int id: @directive_endregion, + unique int start: @directive_region ref); + +directive_lines( + unique int id: @directive_line, + int kind: int ref); /* 0: default, 1: hidden, 2: numeric, 3: span */ + +directive_line_value( + unique int id: @directive_line ref, + int line: int ref); + +directive_line_file( + unique int id: @directive_line ref, + int file: @file ref); + +directive_line_offset( + unique int id: @directive_line ref, + int offset: int ref); + +directive_line_span( + unique int id: @directive_line ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +directive_nullables( + unique int id: @directive_nullable, + int setting: int ref, /* 0: disable, 1: enable, 2: restore */ + int target: int ref); /* 0: none, 1: annotations, 2: warnings */ + +directive_warnings( + unique int id: @directive_warning, + string message: string ref); + +directive_errors( + unique int id: @directive_error, + string message: string ref); + +directive_undefines( + unique int id: @directive_undefine, + string name: string ref); + +directive_defines( + unique int id: @directive_define, + string name: string ref); + +pragma_checksums( + unique int id: @pragma_checksum, + int file: @file ref, + string guid: string ref, + string bytes: string ref); + +pragma_warnings( + unique int id: @pragma_warning, + int kind: int ref /* 0 = disable, 1 = restore */); + +#keyset[id, index] +pragma_warning_error_codes( + int id: @pragma_warning ref, + string errorCode: string ref, + int index: int ref); + +preprocessor_directive_location( + unique int id: @preprocessor_directive ref, + int loc: @location ref); + +preprocessor_directive_compilation( + unique int id: @preprocessor_directive ref, + int compilation: @compilation ref); + +preprocessor_directive_active( + unique int id: @preprocessor_directive ref, + int active: int ref); /* 0: false, 1: true */ + +/** TYPES **/ + +types( + unique int id: @type, + int kind: int ref, + string name: string ref); + +case @type.kind of + 1 = @bool_type +| 2 = @char_type +| 3 = @decimal_type +| 4 = @sbyte_type +| 5 = @short_type +| 6 = @int_type +| 7 = @long_type +| 8 = @byte_type +| 9 = @ushort_type +| 10 = @uint_type +| 11 = @ulong_type +| 12 = @float_type +| 13 = @double_type +| 14 = @enum_type +| 15 = @struct_type +| 17 = @class_type +| 19 = @interface_type +| 20 = @delegate_type +| 21 = @null_type +| 22 = @type_parameter +| 23 = @pointer_type +| 24 = @nullable_type +| 25 = @array_type +| 26 = @void_type +| 27 = @int_ptr_type +| 28 = @uint_ptr_type +| 29 = @dynamic_type +| 30 = @arglist_type +| 31 = @unknown_type +| 32 = @tuple_type +| 33 = @function_pointer_type +| 34 = @inline_array_type + ; + +@simple_type = @bool_type | @char_type | @integral_type | @floating_point_type | @decimal_type; +@integral_type = @signed_integral_type | @unsigned_integral_type; +@signed_integral_type = @sbyte_type | @short_type | @int_type | @long_type; +@unsigned_integral_type = @byte_type | @ushort_type | @uint_type | @ulong_type; +@floating_point_type = @float_type | @double_type; +@value_type = @simple_type | @enum_type | @struct_type | @nullable_type | @int_ptr_type + | @uint_ptr_type | @tuple_type | @void_type | @inline_array_type; +@ref_type = @class_type | @interface_type | @array_type | @delegate_type | @null_type + | @dynamic_type; +@value_or_ref_type = @value_type | @ref_type; + +typerefs( + unique int id: @typeref, + string name: string ref); + +typeref_type( + int id: @typeref ref, + unique int typeId: @type ref); + +@type_or_ref = @type | @typeref; + +array_element_type( + unique int array: @array_type ref, + int dimension: int ref, + int rank: int ref, + int element: @type_or_ref ref); + +nullable_underlying_type( + unique int nullable: @nullable_type ref, + int underlying: @type_or_ref ref); + +pointer_referent_type( + unique int pointer: @pointer_type ref, + int referent: @type_or_ref ref); + +enum_underlying_type( + unique int enum_id: @enum_type ref, + int underlying_type_id: @type_or_ref ref); + +delegate_return_type( + unique int delegate_id: @delegate_type ref, + int return_type_id: @type_or_ref ref); + +function_pointer_return_type( + unique int function_pointer_id: @function_pointer_type ref, + int return_type_id: @type_or_ref ref); + +extend( + int sub: @type ref, + int super: @type_or_ref ref); + +anonymous_types( + unique int id: @type ref); + +@interface_or_ref = @interface_type | @typeref; + +implement( + int sub: @type ref, + int super: @type_or_ref ref); + +type_location( + int id: @type ref, + int loc: @location ref); + +tuple_underlying_type( + unique int tuple: @tuple_type ref, + int struct: @type_or_ref ref); + +#keyset[tuple, index] +tuple_element( + int tuple: @tuple_type ref, + int index: int ref, + unique int field: @field ref); + +attributes( + unique int id: @attribute, + int kind: int ref, + int type_id: @type_or_ref ref, + int target: @attributable ref); + +case @attribute.kind of + 0 = @attribute_default +| 1 = @attribute_return +| 2 = @attribute_assembly +| 3 = @attribute_module +; + +attribute_location( + int id: @attribute ref, + int loc: @location ref); + +@type_mention_parent = @element | @type_mention; + +type_mention( + unique int id: @type_mention, + int type_id: @type_or_ref ref, + int parent: @type_mention_parent ref); + +type_mention_location( + unique int id: @type_mention ref, + int loc: @location ref); + +@has_type_annotation = @assignable | @type_parameter | @callable | @expr | @delegate_type | @generic | @function_pointer_type; + +/** + * A direct annotation on an entity, for example `string? x;`. + * + * Annotations: + * 2 = reftype is not annotated "!" + * 3 = reftype is annotated "?" + * 4 = readonly ref type / in parameter + * 5 = ref type parameter, return or local variable + * 6 = out parameter + * + * Note that the annotation depends on the element it annotates. + * @assignable: The annotation is on the type of the assignable, for example the variable type. + * @type_parameter: The annotation is on the reftype constraint + * @callable: The annotation is on the return type + * @array_type: The annotation is on the element type + */ +type_annotation(int id: @has_type_annotation ref, int annotation: int ref); + +nullability(unique int nullability: @nullability, int kind: int ref); + +case @nullability.kind of + 0 = @oblivious +| 1 = @not_annotated +| 2 = @annotated +; + +#keyset[parent, index] +nullability_parent(int nullability: @nullability ref, int index: int ref, int parent: @nullability ref) + +type_nullability(int id: @has_type_annotation ref, int nullability: @nullability ref); + +/** + * The nullable flow state of an expression, as determined by Roslyn. + * 0 = none (default, not populated) + * 1 = not null + * 2 = maybe null + */ +expr_flowstate(unique int id: @expr ref, int state: int ref); + +/** GENERICS **/ + +@generic = @type | @method | @local_function; + +type_parameters( + unique int id: @type_parameter ref, + int index: int ref, + int generic_id: @generic ref, + int variance: int ref /* none = 0, out = 1, in = 2 */); + +#keyset[constructed_id, index] +type_arguments( + int id: @type_or_ref ref, + int index: int ref, + int constructed_id: @generic_or_ref ref); + +@generic_or_ref = @generic | @typeref; + +constructed_generic( + unique int constructed: @generic ref, + int generic: @generic_or_ref ref); + +type_parameter_constraints( + unique int id: @type_parameter_constraints, + int param_id: @type_parameter ref); + +type_parameter_constraints_location( + int id: @type_parameter_constraints ref, + int loc: @location ref); + +general_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int kind: int ref /* class = 1, struct = 2, new = 3 */); + +specific_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref); + +specific_type_parameter_nullability( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref, + int nullability: @nullability ref); + +/** FUNCTION POINTERS */ + +function_pointer_calling_conventions( + int id: @function_pointer_type ref, + int kind: int ref); + +#keyset[id, index] +has_unmanaged_calling_conventions( + int id: @function_pointer_type ref, + int index: int ref, + int conv_id: @type_or_ref ref); + +/** MODIFIERS */ + +@modifiable = @modifiable_direct | @event_accessor; + +@modifiable_direct = @member | @accessor | @local_function | @anonymous_function_expr; + +modifiers( + unique int id: @modifier, + string name: string ref); + +has_modifiers( + int id: @modifiable_direct ref, + int mod_id: @modifier ref); + +compiler_generated(unique int id: @modifiable ref); + +/** MEMBERS **/ + +@member = @method | @constructor | @destructor | @field | @property | @event | @operator | @indexer | @type; + +@named_exprorstmt = @goto_stmt | @labeled_stmt | @expr; + +@virtualizable = @method | @property | @indexer | @event | @operator; + +exprorstmt_name( + unique int parent_id: @named_exprorstmt ref, + string name: string ref); + +nested_types( + unique int id: @type ref, + int declaring_type_id: @type ref, + int unbound_id: @type ref); + +properties( + unique int id: @property, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @property ref); + +property_location( + int id: @property ref, + int loc: @location ref); + +indexers( + unique int id: @indexer, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @indexer ref); + +indexer_location( + int id: @indexer ref, + int loc: @location ref); + +accessors( + unique int id: @accessor, + int kind: int ref, + string name: string ref, + int declaring_member_id: @member ref, + int unbound_id: @accessor ref); + +case @accessor.kind of + 1 = @getter +| 2 = @setter + ; + +init_only_accessors( + unique int id: @accessor ref); + +accessor_location( + int id: @accessor ref, + int loc: @location ref); + +events( + unique int id: @event, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @event ref); + +event_location( + int id: @event ref, + int loc: @location ref); + +event_accessors( + unique int id: @event_accessor, + int kind: int ref, + string name: string ref, + int declaring_event_id: @event ref, + int unbound_id: @event_accessor ref); + +case @event_accessor.kind of + 1 = @add_event_accessor +| 2 = @remove_event_accessor + ; + +event_accessor_location( + int id: @event_accessor ref, + int loc: @location ref); + +operators( + unique int id: @operator, + string name: string ref, + string symbol: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @operator ref); + +operator_location( + int id: @operator ref, + int loc: @location ref); + +constant_value( + int id: @variable ref, + string value: string ref); + +/** CALLABLES **/ + +@callable = @method | @constructor | @destructor | @operator | @callable_accessor | @anonymous_function_expr | @local_function; + +@callable_accessor = @accessor | @event_accessor; + +methods( + unique int id: @method, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @method ref); + +method_location( + int id: @method ref, + int loc: @location ref); + +constructors( + unique int id: @constructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @constructor ref); + +constructor_location( + int id: @constructor ref, + int loc: @location ref); + +destructors( + unique int id: @destructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @destructor ref); + +destructor_location( + int id: @destructor ref, + int loc: @location ref); + +overrides( + int id: @callable ref, + int base_id: @callable ref); + +explicitly_implements( + int id: @member ref, + int interface_id: @interface_or_ref ref); + +local_functions( + unique int id: @local_function, + string name: string ref, + int return_type: @type ref, + int unbound_id: @local_function ref); + +local_function_stmts( + unique int fn: @local_function_stmt ref, + int stmt: @local_function ref); + +/** VARIABLES **/ + +@variable = @local_scope_variable | @field; + +@local_scope_variable = @local_variable | @parameter; + +fields( + unique int id: @field, + int kind: int ref, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @field ref); + +case @field.kind of + 1 = @addressable_field +| 2 = @constant + ; + +field_location( + int id: @field ref, + int loc: @location ref); + +localvars( + unique int id: @local_variable, + int kind: int ref, + string name: string ref, + int implicitly_typed: int ref /* 0 = no, 1 = yes */, + int type_id: @type_or_ref ref, + int parent_id: @local_var_decl_expr ref); + +case @local_variable.kind of + 1 = @addressable_local_variable +| 2 = @local_constant +| 3 = @local_variable_ref + ; + +localvar_location( + unique int id: @local_variable ref, + int loc: @location ref); + +@parameterizable = @callable | @delegate_type | @indexer | @function_pointer_type; + +#keyset[name, parent_id] +#keyset[index, parent_id] +params( + unique int id: @parameter, + string name: string ref, + int type_id: @type_or_ref ref, + int index: int ref, + int mode: int ref, /* value = 0, ref = 1, out = 2, array = 3, this = 4 */ + int parent_id: @parameterizable ref, + int unbound_id: @parameter ref); + +param_location( + int id: @parameter ref, + int loc: @location ref); + +@has_scoped_annotation = @local_scope_variable + +scoped_annotation( + int id: @has_scoped_annotation ref, + int kind: int ref // scoped ref = 1, scoped value = 2 + ); + +/** STATEMENTS **/ + +@exprorstmt_parent = @control_flow_element | @top_level_exprorstmt_parent; + +statements( + unique int id: @stmt, + int kind: int ref); + +#keyset[index, parent] +stmt_parent( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_stmt_parent = @callable; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +stmt_parent_top_level( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @top_level_stmt_parent ref); + +case @stmt.kind of + 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @switch_stmt +| 5 = @while_stmt +| 6 = @do_stmt +| 7 = @for_stmt +| 8 = @foreach_stmt +| 9 = @break_stmt +| 10 = @continue_stmt +| 11 = @goto_stmt +| 12 = @goto_case_stmt +| 13 = @goto_default_stmt +| 14 = @throw_stmt +| 15 = @return_stmt +| 16 = @yield_stmt +| 17 = @try_stmt +| 18 = @checked_stmt +| 19 = @unchecked_stmt +| 20 = @lock_stmt +| 21 = @using_block_stmt +| 22 = @var_decl_stmt +| 23 = @const_decl_stmt +| 24 = @empty_stmt +| 25 = @unsafe_stmt +| 26 = @fixed_stmt +| 27 = @label_stmt +| 28 = @catch +| 29 = @case_stmt +| 30 = @local_function_stmt +| 31 = @using_decl_stmt + ; + +@using_stmt = @using_block_stmt | @using_decl_stmt; + +@labeled_stmt = @label_stmt | @case; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @using_decl_stmt; + +@cond_stmt = @if_stmt | @switch_stmt; + +@loop_stmt = @while_stmt | @do_stmt | @for_stmt | @foreach_stmt; + +@jump_stmt = @break_stmt | @goto_any_stmt | @continue_stmt | @throw_stmt | @return_stmt + | @yield_stmt; + +@goto_any_stmt = @goto_default_stmt | @goto_case_stmt | @goto_stmt; + + +stmt_location( + unique int id: @stmt ref, + int loc: @location ref); + +catch_type( + unique int catch_id: @catch ref, + int type_id: @type_or_ref ref, + int kind: int ref /* explicit = 1, implicit = 2 */); + +foreach_stmt_info( + unique int id: @foreach_stmt ref, + int kind: int ref /* non-async = 1, async = 2 */); + +@foreach_symbol = @method | @property | @type_or_ref; + +#keyset[id, kind] +foreach_stmt_desugar( + int id: @foreach_stmt ref, + int symbol: @foreach_symbol ref, + int kind: int ref /* GetEnumeratorMethod = 1, CurrentProperty = 2, MoveNextMethod = 3, DisposeMethod = 4, ElementType = 5 */); + +/** EXPRESSIONS **/ + +expressions( + unique int id: @expr, + int kind: int ref, + int type_id: @type_or_ref ref); + +#keyset[index, parent] +expr_parent( + unique int expr: @expr ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_expr_parent = @attribute | @field | @property | @indexer | @parameter | @directive_if | @directive_elif; + +@top_level_exprorstmt_parent = @top_level_expr_parent | @top_level_stmt_parent; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +expr_parent_top_level( + unique int expr: @expr ref, + int index: int ref, + int parent: @top_level_exprorstmt_parent ref); + +case @expr.kind of +/* literal */ + 1 = @bool_literal_expr +| 2 = @char_literal_expr +| 3 = @decimal_literal_expr +| 4 = @int_literal_expr +| 5 = @long_literal_expr +| 6 = @uint_literal_expr +| 7 = @ulong_literal_expr +| 8 = @float_literal_expr +| 9 = @double_literal_expr +| 10 = @utf16_string_literal_expr +| 11 = @null_literal_expr +/* primary & unary */ +| 12 = @this_access_expr +| 13 = @base_access_expr +| 14 = @local_variable_access_expr +| 15 = @parameter_access_expr +| 16 = @field_access_expr +| 17 = @property_access_expr +| 18 = @method_access_expr +| 19 = @event_access_expr +| 20 = @indexer_access_expr +| 21 = @array_access_expr +| 22 = @type_access_expr +| 23 = @typeof_expr +| 24 = @method_invocation_expr +| 25 = @delegate_invocation_expr +| 26 = @operator_invocation_expr +| 27 = @cast_expr +| 28 = @object_creation_expr +| 29 = @explicit_delegate_creation_expr +| 30 = @implicit_delegate_creation_expr +| 31 = @array_creation_expr +| 32 = @default_expr +| 33 = @plus_expr +| 34 = @minus_expr +| 35 = @bit_not_expr +| 36 = @log_not_expr +| 37 = @post_incr_expr +| 38 = @post_decr_expr +| 39 = @pre_incr_expr +| 40 = @pre_decr_expr +/* multiplicative */ +| 41 = @mul_expr +| 42 = @div_expr +| 43 = @rem_expr +/* additive */ +| 44 = @add_expr +| 45 = @sub_expr +/* shift */ +| 46 = @lshift_expr +| 47 = @rshift_expr +/* relational */ +| 48 = @lt_expr +| 49 = @gt_expr +| 50 = @le_expr +| 51 = @ge_expr +/* equality */ +| 52 = @eq_expr +| 53 = @ne_expr +/* logical */ +| 54 = @bit_and_expr +| 55 = @bit_xor_expr +| 56 = @bit_or_expr +| 57 = @log_and_expr +| 58 = @log_or_expr +/* type testing */ +| 59 = @is_expr +| 60 = @as_expr +/* null coalescing */ +| 61 = @null_coalescing_expr +/* conditional */ +| 62 = @conditional_expr +/* assignment */ +| 63 = @simple_assign_expr +| 64 = @assign_add_expr +| 65 = @assign_sub_expr +| 66 = @assign_mul_expr +| 67 = @assign_div_expr +| 68 = @assign_rem_expr +| 69 = @assign_and_expr +| 70 = @assign_xor_expr +| 71 = @assign_or_expr +| 72 = @assign_lshift_expr +| 73 = @assign_rshift_expr +/* more */ +| 74 = @object_init_expr +| 75 = @collection_init_expr +| 76 = @array_init_expr +| 77 = @checked_expr +| 78 = @unchecked_expr +| 79 = @constructor_init_expr +| 80 = @add_event_expr +| 81 = @remove_event_expr +| 82 = @par_expr +| 83 = @local_var_decl_expr +| 84 = @lambda_expr +| 85 = @anonymous_method_expr +| 86 = @namespace_expr +/* dynamic */ +| 92 = @dynamic_element_access_expr +| 93 = @dynamic_member_access_expr +/* unsafe */ +| 100 = @pointer_indirection_expr +| 101 = @address_of_expr +| 102 = @sizeof_expr +/* async */ +| 103 = @await_expr +/* C# 6.0 */ +| 104 = @nameof_expr +| 105 = @interpolated_string_expr +| 106 = @unknown_expr +/* C# 7.0 */ +| 107 = @throw_expr +| 108 = @tuple_expr +| 109 = @local_function_invocation_expr +| 110 = @ref_expr +| 111 = @discard_expr +/* C# 8.0 */ +| 112 = @range_expr +| 113 = @index_expr +| 114 = @switch_expr +| 115 = @recursive_pattern_expr +| 116 = @property_pattern_expr +| 117 = @positional_pattern_expr +| 118 = @switch_case_expr +| 119 = @assign_coalesce_expr +| 120 = @suppress_nullable_warning_expr +| 121 = @namespace_access_expr +/* C# 9.0 */ +| 122 = @lt_pattern_expr +| 123 = @gt_pattern_expr +| 124 = @le_pattern_expr +| 125 = @ge_pattern_expr +| 126 = @not_pattern_expr +| 127 = @and_pattern_expr +| 128 = @or_pattern_expr +| 129 = @function_pointer_invocation_expr +| 130 = @with_expr +/* C# 11.0 */ +| 131 = @list_pattern_expr +| 132 = @slice_pattern_expr +| 133 = @urshift_expr +| 134 = @assign_urshift_expr +| 135 = @utf8_string_literal_expr +/* C# 12.0 */ +| 136 = @collection_expr +| 137 = @spread_element_expr +/* Preprocessor */ +| 999 = @define_symbol_expr +; + +@switch = @switch_stmt | @switch_expr; +@case = @case_stmt | @switch_case_expr; +@pattern_match = @case | @is_expr; +@unary_pattern_expr = @not_pattern_expr; +@relational_pattern_expr = @gt_pattern_expr | @lt_pattern_expr | @ge_pattern_expr | @le_pattern_expr; +@binary_pattern_expr = @and_pattern_expr | @or_pattern_expr; + +@integer_literal_expr = @int_literal_expr | @long_literal_expr | @uint_literal_expr | @ulong_literal_expr; +@real_literal_expr = @float_literal_expr | @double_literal_expr | @decimal_literal_expr; +@string_literal_expr = @utf16_string_literal_expr | @utf8_string_literal_expr; +@literal_expr = @bool_literal_expr | @char_literal_expr | @integer_literal_expr | @real_literal_expr + | @string_literal_expr | @null_literal_expr; + +@assign_expr = @simple_assign_expr | @assign_op_expr | @local_var_decl_expr; +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr | @assign_event_expr | @assign_coalesce_expr; +@assign_event_expr = @add_event_expr | @remove_event_expr; + +@assign_arith_expr = @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr + | @assign_rem_expr +@assign_bitwise_expr = @assign_and_expr | @assign_or_expr | @assign_xor_expr + | @assign_lshift_expr | @assign_rshift_expr | @assign_urshift_expr; + +@member_access_expr = @field_access_expr | @property_access_expr | @indexer_access_expr | @event_access_expr + | @method_access_expr | @type_access_expr | @dynamic_member_access_expr; +@access_expr = @member_access_expr | @this_access_expr | @base_access_expr | @assignable_access_expr | @namespace_access_expr; +@element_access_expr = @indexer_access_expr | @array_access_expr | @dynamic_element_access_expr; + +@local_variable_access = @local_variable_access_expr | @local_var_decl_expr; +@local_scope_variable_access_expr = @parameter_access_expr | @local_variable_access; +@variable_access_expr = @local_scope_variable_access_expr | @field_access_expr; + +@assignable_access_expr = @variable_access_expr | @property_access_expr | @element_access_expr + | @event_access_expr | @dynamic_member_access_expr; + +@objectorcollection_init_expr = @object_init_expr | @collection_init_expr; + +@delegate_creation_expr = @explicit_delegate_creation_expr | @implicit_delegate_creation_expr; + +@bin_arith_op_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr; +@incr_op_expr = @pre_incr_expr | @post_incr_expr; +@decr_op_expr = @pre_decr_expr | @post_decr_expr; +@mut_op_expr = @incr_op_expr | @decr_op_expr; +@un_arith_op_expr = @plus_expr | @minus_expr | @mut_op_expr; +@arith_op_expr = @bin_arith_op_expr | @un_arith_op_expr; + +@ternary_log_op_expr = @conditional_expr; +@bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr; +@un_log_op_expr = @log_not_expr; +@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr; + +@bin_bit_op_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr + | @rshift_expr | @urshift_expr; +@un_bit_op_expr = @bit_not_expr; +@bit_expr = @un_bit_op_expr | @bin_bit_op_expr; + +@equality_op_expr = @eq_expr | @ne_expr; +@rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr; +@comp_expr = @equality_op_expr | @rel_op_expr; + +@op_expr = @assign_expr | @un_op | @bin_op | @ternary_op; + +@ternary_op = @ternary_log_op_expr; +@bin_op = @bin_arith_op_expr | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr; +@un_op = @un_arith_op_expr | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr + | @pointer_indirection_expr | @address_of_expr; + +@anonymous_function_expr = @lambda_expr | @anonymous_method_expr; + +@call = @method_invocation_expr | @constructor_init_expr | @operator_invocation_expr + | @delegate_invocation_expr | @object_creation_expr | @call_access_expr + | @local_function_invocation_expr | @function_pointer_invocation_expr; + +@call_access_expr = @property_access_expr | @event_access_expr | @indexer_access_expr; + +@late_bindable_expr = @dynamic_element_access_expr | @dynamic_member_access_expr + | @object_creation_expr | @method_invocation_expr | @operator_invocation_expr; + +@throw_element = @throw_expr | @throw_stmt; + +@implicitly_typeable_object_creation_expr = @object_creation_expr | @explicit_delegate_creation_expr; + +implicitly_typed_array_creation( + unique int id: @array_creation_expr ref); + +explicitly_sized_array_creation( + unique int id: @array_creation_expr ref); + +stackalloc_array_creation( + unique int id: @array_creation_expr ref); + +implicitly_typed_object_creation( + unique int id: @implicitly_typeable_object_creation_expr ref); + +mutator_invocation_mode( + unique int id: @operator_invocation_expr ref, + int mode: int ref /* prefix = 1, postfix = 2*/); + +expr_compiler_generated( + unique int id: @expr ref); + +expr_value( + unique int id: @expr ref, + string value: string ref); + +expr_call( + unique int caller_id: @expr ref, + int target_id: @callable ref); + +expr_access( + unique int accesser_id: @access_expr ref, + int target_id: @accessible ref); + +@accessible = @method | @assignable | @local_function | @namespace; + +expr_location( + unique int id: @expr ref, + int loc: @location ref); + +dynamic_member_name( + unique int id: @late_bindable_expr ref, + string name: string ref); + +@qualifiable_expr = @member_access_expr + | @method_invocation_expr + | @element_access_expr; + +conditional_access( + unique int id: @qualifiable_expr ref); + +expr_argument( + unique int id: @expr ref, + int mode: int ref); + /* mode is the same as params: value = 0, ref = 1, out = 2 */ + +expr_argument_name( + unique int id: @expr ref, + string name: string ref); + +lambda_expr_return_type( + unique int id: @lambda_expr ref, + int type_id: @type_or_ref ref); + +/** CONTROL/DATA FLOW **/ + +@control_flow_element = @stmt | @expr; + +/* XML Files */ + +xmlEncoding ( + unique int id: @file ref, + string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* Comments */ + +commentline( + unique int id: @commentline, + int kind: int ref, + string text: string ref, + string rawtext: string ref); + +case @commentline.kind of + 0 = @singlelinecomment +| 1 = @xmldoccomment +| 2 = @multilinecomment; + +commentline_location( + unique int id: @commentline ref, + int loc: @location ref); + +commentblock( + unique int id : @commentblock); + +commentblock_location( + unique int id: @commentblock ref, + int loc: @location ref); + +commentblock_binding( + int id: @commentblock ref, + int entity: @element ref, + int bindtype: int ref); /* 0: Parent, 1: Best, 2: Before, 3: After */ + +commentblock_child( + int id: @commentblock ref, + int commentline: @commentline ref, + int index: int ref); + +/* ASP.NET */ + +case @asp_element.kind of + 0=@asp_close_tag +| 1=@asp_code +| 2=@asp_comment +| 3=@asp_data_binding +| 4=@asp_directive +| 5=@asp_open_tag +| 6=@asp_quoted_string +| 7=@asp_text +| 8=@asp_xml_directive; + +@asp_attribute = @asp_code | @asp_data_binding | @asp_quoted_string; + +asp_elements( + unique int id: @asp_element, + int kind: int ref, + int loc: @location ref); + +asp_comment_server(unique int comment: @asp_comment ref); +asp_code_inline(unique int code: @asp_code ref); +asp_directive_attribute( + int directive: @asp_directive ref, + int index: int ref, + string name: string ref, + int value: @asp_quoted_string ref); +asp_directive_name( + unique int directive: @asp_directive ref, + string name: string ref); +asp_element_body( + unique int element: @asp_element ref, + string body: string ref); +asp_tag_attribute( + int tag: @asp_open_tag ref, + int index: int ref, + string name: string ref, + int attribute: @asp_attribute ref); +asp_tag_name( + unique int tag: @asp_open_tag ref, + string name: string ref); +asp_tag_isempty(int tag: @asp_open_tag ref); + +/* Common Intermediate Language - CIL */ + +case @cil_instruction.opcode of + 0 = @cil_nop +| 1 = @cil_break +| 2 = @cil_ldarg_0 +| 3 = @cil_ldarg_1 +| 4 = @cil_ldarg_2 +| 5 = @cil_ldarg_3 +| 6 = @cil_ldloc_0 +| 7 = @cil_ldloc_1 +| 8 = @cil_ldloc_2 +| 9 = @cil_ldloc_3 +| 10 = @cil_stloc_0 +| 11 = @cil_stloc_1 +| 12 = @cil_stloc_2 +| 13 = @cil_stloc_3 +| 14 = @cil_ldarg_s +| 15 = @cil_ldarga_s +| 16 = @cil_starg_s +| 17 = @cil_ldloc_s +| 18 = @cil_ldloca_s +| 19 = @cil_stloc_s +| 20 = @cil_ldnull +| 21 = @cil_ldc_i4_m1 +| 22 = @cil_ldc_i4_0 +| 23 = @cil_ldc_i4_1 +| 24 = @cil_ldc_i4_2 +| 25 = @cil_ldc_i4_3 +| 26 = @cil_ldc_i4_4 +| 27 = @cil_ldc_i4_5 +| 28 = @cil_ldc_i4_6 +| 29 = @cil_ldc_i4_7 +| 30 = @cil_ldc_i4_8 +| 31 = @cil_ldc_i4_s +| 32 = @cil_ldc_i4 +| 33 = @cil_ldc_i8 +| 34 = @cil_ldc_r4 +| 35 = @cil_ldc_r8 +| 37 = @cil_dup +| 38 = @cil_pop +| 39 = @cil_jmp +| 40 = @cil_call +| 41 = @cil_calli +| 42 = @cil_ret +| 43 = @cil_br_s +| 44 = @cil_brfalse_s +| 45 = @cil_brtrue_s +| 46 = @cil_beq_s +| 47 = @cil_bge_s +| 48 = @cil_bgt_s +| 49 = @cil_ble_s +| 50 = @cil_blt_s +| 51 = @cil_bne_un_s +| 52 = @cil_bge_un_s +| 53 = @cil_bgt_un_s +| 54 = @cil_ble_un_s +| 55 = @cil_blt_un_s +| 56 = @cil_br +| 57 = @cil_brfalse +| 58 = @cil_brtrue +| 59 = @cil_beq +| 60 = @cil_bge +| 61 = @cil_bgt +| 62 = @cil_ble +| 63 = @cil_blt +| 64 = @cil_bne_un +| 65 = @cil_bge_un +| 66 = @cil_bgt_un +| 67 = @cil_ble_un +| 68 = @cil_blt_un +| 69 = @cil_switch +| 70 = @cil_ldind_i1 +| 71 = @cil_ldind_u1 +| 72 = @cil_ldind_i2 +| 73 = @cil_ldind_u2 +| 74 = @cil_ldind_i4 +| 75 = @cil_ldind_u4 +| 76 = @cil_ldind_i8 +| 77 = @cil_ldind_i +| 78 = @cil_ldind_r4 +| 79 = @cil_ldind_r8 +| 80 = @cil_ldind_ref +| 81 = @cil_stind_ref +| 82 = @cil_stind_i1 +| 83 = @cil_stind_i2 +| 84 = @cil_stind_i4 +| 85 = @cil_stind_i8 +| 86 = @cil_stind_r4 +| 87 = @cil_stind_r8 +| 88 = @cil_add +| 89 = @cil_sub +| 90 = @cil_mul +| 91 = @cil_div +| 92 = @cil_div_un +| 93 = @cil_rem +| 94 = @cil_rem_un +| 95 = @cil_and +| 96 = @cil_or +| 97 = @cil_xor +| 98 = @cil_shl +| 99 = @cil_shr +| 100 = @cil_shr_un +| 101 = @cil_neg +| 102 = @cil_not +| 103 = @cil_conv_i1 +| 104 = @cil_conv_i2 +| 105 = @cil_conv_i4 +| 106 = @cil_conv_i8 +| 107 = @cil_conv_r4 +| 108 = @cil_conv_r8 +| 109 = @cil_conv_u4 +| 110 = @cil_conv_u8 +| 111 = @cil_callvirt +| 112 = @cil_cpobj +| 113 = @cil_ldobj +| 114 = @cil_ldstr +| 115 = @cil_newobj +| 116 = @cil_castclass +| 117 = @cil_isinst +| 118 = @cil_conv_r_un +| 121 = @cil_unbox +| 122 = @cil_throw +| 123 = @cil_ldfld +| 124 = @cil_ldflda +| 125 = @cil_stfld +| 126 = @cil_ldsfld +| 127 = @cil_ldsflda +| 128 = @cil_stsfld +| 129 = @cil_stobj +| 130 = @cil_conv_ovf_i1_un +| 131 = @cil_conv_ovf_i2_un +| 132 = @cil_conv_ovf_i4_un +| 133 = @cil_conv_ovf_i8_un +| 134 = @cil_conv_ovf_u1_un +| 135 = @cil_conv_ovf_u2_un +| 136 = @cil_conv_ovf_u4_un +| 137 = @cil_conv_ovf_u8_un +| 138 = @cil_conv_ovf_i_un +| 139 = @cil_conv_ovf_u_un +| 140 = @cil_box +| 141 = @cil_newarr +| 142 = @cil_ldlen +| 143 = @cil_ldelema +| 144 = @cil_ldelem_i1 +| 145 = @cil_ldelem_u1 +| 146 = @cil_ldelem_i2 +| 147 = @cil_ldelem_u2 +| 148 = @cil_ldelem_i4 +| 149 = @cil_ldelem_u4 +| 150 = @cil_ldelem_i8 +| 151 = @cil_ldelem_i +| 152 = @cil_ldelem_r4 +| 153 = @cil_ldelem_r8 +| 154 = @cil_ldelem_ref +| 155 = @cil_stelem_i +| 156 = @cil_stelem_i1 +| 157 = @cil_stelem_i2 +| 158 = @cil_stelem_i4 +| 159 = @cil_stelem_i8 +| 160 = @cil_stelem_r4 +| 161 = @cil_stelem_r8 +| 162 = @cil_stelem_ref +| 163 = @cil_ldelem +| 164 = @cil_stelem +| 165 = @cil_unbox_any +| 179 = @cil_conv_ovf_i1 +| 180 = @cil_conv_ovf_u1 +| 181 = @cil_conv_ovf_i2 +| 182 = @cil_conv_ovf_u2 +| 183 = @cil_conv_ovf_i4 +| 184 = @cil_conv_ovf_u4 +| 185 = @cil_conv_ovf_i8 +| 186 = @cil_conv_ovf_u8 +| 194 = @cil_refanyval +| 195 = @cil_ckinfinite +| 198 = @cil_mkrefany +| 208 = @cil_ldtoken +| 209 = @cil_conv_u2 +| 210 = @cil_conv_u1 +| 211 = @cil_conv_i +| 212 = @cil_conv_ovf_i +| 213 = @cil_conv_ovf_u +| 214 = @cil_add_ovf +| 215 = @cil_add_ovf_un +| 216 = @cil_mul_ovf +| 217 = @cil_mul_ovf_un +| 218 = @cil_sub_ovf +| 219 = @cil_sub_ovf_un +| 220 = @cil_endfinally +| 221 = @cil_leave +| 222 = @cil_leave_s +| 223 = @cil_stind_i +| 224 = @cil_conv_u +| 65024 = @cil_arglist +| 65025 = @cil_ceq +| 65026 = @cil_cgt +| 65027 = @cil_cgt_un +| 65028 = @cil_clt +| 65029 = @cil_clt_un +| 65030 = @cil_ldftn +| 65031 = @cil_ldvirtftn +| 65033 = @cil_ldarg +| 65034 = @cil_ldarga +| 65035 = @cil_starg +| 65036 = @cil_ldloc +| 65037 = @cil_ldloca +| 65038 = @cil_stloc +| 65039 = @cil_localloc +| 65041 = @cil_endfilter +| 65042 = @cil_unaligned +| 65043 = @cil_volatile +| 65044 = @cil_tail +| 65045 = @cil_initobj +| 65046 = @cil_constrained +| 65047 = @cil_cpblk +| 65048 = @cil_initblk +| 65050 = @cil_rethrow +| 65052 = @cil_sizeof +| 65053 = @cil_refanytype +| 65054 = @cil_readonly +; + +// CIL ignored instructions + +@cil_ignore = @cil_nop | @cil_break | @cil_volatile | @cil_unaligned; + +// CIL local/parameter/field access + +@cil_ldarg_any = @cil_ldarg_0 | @cil_ldarg_1 | @cil_ldarg_2 | @cil_ldarg_3 | @cil_ldarg_s | @cil_ldarga_s | @cil_ldarg | @cil_ldarga; +@cil_starg_any = @cil_starg | @cil_starg_s; + +@cil_ldloc_any = @cil_ldloc_0 | @cil_ldloc_1 | @cil_ldloc_2 | @cil_ldloc_3 | @cil_ldloc_s | @cil_ldloca_s | @cil_ldloc | @cil_ldloca; +@cil_stloc_any = @cil_stloc_0 | @cil_stloc_1 | @cil_stloc_2 | @cil_stloc_3 | @cil_stloc_s | @cil_stloc; + +@cil_ldfld_any = @cil_ldfld | @cil_ldsfld | @cil_ldsflda | @cil_ldflda; +@cil_stfld_any = @cil_stfld | @cil_stsfld; + +@cil_local_access = @cil_stloc_any | @cil_ldloc_any; +@cil_arg_access = @cil_starg_any | @cil_ldarg_any; +@cil_read_access = @cil_ldloc_any | @cil_ldarg_any | @cil_ldfld_any; +@cil_write_access = @cil_stloc_any | @cil_starg_any | @cil_stfld_any; + +@cil_stack_access = @cil_local_access | @cil_arg_access; +@cil_field_access = @cil_ldfld_any | @cil_stfld_any; + +@cil_access = @cil_read_access | @cil_write_access; + +// CIL constant/literal instructions + +@cil_ldc_i = @cil_ldc_i4_any | @cil_ldc_i8; + +@cil_ldc_i4_any = @cil_ldc_i4_m1 | @cil_ldc_i4_0 | @cil_ldc_i4_1 | @cil_ldc_i4_2 | @cil_ldc_i4_3 | + @cil_ldc_i4_4 | @cil_ldc_i4_5 | @cil_ldc_i4_6 | @cil_ldc_i4_7 | @cil_ldc_i4_8 | @cil_ldc_i4_s | @cil_ldc_i4; + +@cil_ldc_r = @cil_ldc_r4 | @cil_ldc_r8; + +@cil_literal = @cil_ldnull | @cil_ldc_i | @cil_ldc_r | @cil_ldstr; + +// Control flow + +@cil_conditional_jump = @cil_binary_jump | @cil_unary_jump; +@cil_binary_jump = @cil_beq_s | @cil_bge_s | @cil_bgt_s | @cil_ble_s | @cil_blt_s | + @cil_bne_un_s | @cil_bge_un_s | @cil_bgt_un_s | @cil_ble_un_s | @cil_blt_un_s | + @cil_beq | @cil_bge | @cil_bgt | @cil_ble | @cil_blt | + @cil_bne_un | @cil_bge_un | @cil_bgt_un | @cil_ble_un | @cil_blt_un; +@cil_unary_jump = @cil_brfalse_s | @cil_brtrue_s | @cil_brfalse | @cil_brtrue | @cil_switch; +@cil_unconditional_jump = @cil_br | @cil_br_s | @cil_leave_any; +@cil_leave_any = @cil_leave | @cil_leave_s; +@cil_jump = @cil_unconditional_jump | @cil_conditional_jump; + +// CIL call instructions + +@cil_call_any = @cil_jmp | @cil_call | @cil_calli | @cil_tail | @cil_callvirt | @cil_newobj; + +// CIL expression instructions + +@cil_expr = @cil_literal | @cil_binary_expr | @cil_unary_expr | @cil_call_any | @cil_read_access | + @cil_newarr | @cil_ldtoken | @cil_sizeof | + @cil_ldftn | @cil_ldvirtftn | @cil_localloc | @cil_mkrefany | @cil_refanytype | @cil_arglist | @cil_dup; + +@cil_unary_expr = + @cil_conversion_operation | @cil_unary_arithmetic_operation | @cil_unary_bitwise_operation| + @cil_ldlen | @cil_isinst | @cil_box | @cil_ldobj | @cil_castclass | @cil_unbox_any | + @cil_ldind | @cil_unbox; + +@cil_conversion_operation = + @cil_conv_i1 | @cil_conv_i2 | @cil_conv_i4 | @cil_conv_i8 | + @cil_conv_u1 | @cil_conv_u2 | @cil_conv_u4 | @cil_conv_u8 | + @cil_conv_ovf_i | @cil_conv_ovf_i_un | @cil_conv_ovf_i1 | @cil_conv_ovf_i1_un | + @cil_conv_ovf_i2 | @cil_conv_ovf_i2_un | @cil_conv_ovf_i4 | @cil_conv_ovf_i4_un | + @cil_conv_ovf_i8 | @cil_conv_ovf_i8_un | @cil_conv_ovf_u | @cil_conv_ovf_u_un | + @cil_conv_ovf_u1 | @cil_conv_ovf_u1_un | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_ovf_u4 | @cil_conv_ovf_u4_un | @cil_conv_ovf_u8 | @cil_conv_ovf_u8_un | + @cil_conv_r4 | @cil_conv_r8 | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_i | @cil_conv_u | @cil_conv_r_un; + +@cil_ldind = @cil_ldind_i | @cil_ldind_i1 | @cil_ldind_i2 | @cil_ldind_i4 | @cil_ldind_i8 | + @cil_ldind_r4 | @cil_ldind_r8 | @cil_ldind_ref | @cil_ldind_u1 | @cil_ldind_u2 | @cil_ldind_u4; + +@cil_stind = @cil_stind_i | @cil_stind_i1 | @cil_stind_i2 | @cil_stind_i4 | @cil_stind_i8 | + @cil_stind_r4 | @cil_stind_r8 | @cil_stind_ref; + +@cil_bitwise_operation = @cil_binary_bitwise_operation | @cil_unary_bitwise_operation; + +@cil_binary_bitwise_operation = @cil_and | @cil_or | @cil_xor | @cil_shr | @cil_shr | @cil_shr_un | @cil_shl; + +@cil_binary_arithmetic_operation = @cil_add | @cil_sub | @cil_mul | @cil_div | @cil_div_un | + @cil_rem | @cil_rem_un | @cil_add_ovf | @cil_add_ovf_un | @cil_mul_ovf | @cil_mul_ovf_un | + @cil_sub_ovf | @cil_sub_ovf_un; + +@cil_unary_bitwise_operation = @cil_not; + +@cil_binary_expr = @cil_binary_arithmetic_operation | @cil_binary_bitwise_operation | @cil_read_array | @cil_comparison_operation; + +@cil_unary_arithmetic_operation = @cil_neg; + +@cil_comparison_operation = @cil_cgt_un | @cil_ceq | @cil_cgt | @cil_clt | @cil_clt_un; + +// Elements that retrieve an address of something +@cil_read_ref = @cil_ldloca_s | @cil_ldarga_s | @cil_ldflda | @cil_ldsflda | @cil_ldelema; + +// CIL array instructions + +@cil_read_array = + @cil_ldelem | @cil_ldelema | @cil_ldelem_i1 | @cil_ldelem_ref | @cil_ldelem_i | + @cil_ldelem_i1 | @cil_ldelem_i2 | @cil_ldelem_i4 | @cil_ldelem_i8 | @cil_ldelem_r4 | + @cil_ldelem_r8 | @cil_ldelem_u1 | @cil_ldelem_u2 | @cil_ldelem_u4; + +@cil_write_array = @cil_stelem | @cil_stelem_ref | + @cil_stelem_i | @cil_stelem_i1 | @cil_stelem_i2 | @cil_stelem_i4 | @cil_stelem_i8 | + @cil_stelem_r4 | @cil_stelem_r8; + +@cil_throw_any = @cil_throw | @cil_rethrow; + +#keyset[impl, index] +cil_instruction( + unique int id: @cil_instruction, + int opcode: int ref, + int index: int ref, + int impl: @cil_method_implementation ref); + +cil_jump( + unique int instruction: @cil_jump ref, + int target: @cil_instruction ref); + +cil_access( + unique int instruction: @cil_instruction ref, + int target: @cil_accessible ref); + +cil_value( + unique int instruction: @cil_literal ref, + string value: string ref); + +#keyset[instruction, index] +cil_switch( + int instruction: @cil_switch ref, + int index: int ref, + int target: @cil_instruction ref); + +cil_instruction_location( + unique int id: @cil_instruction ref, + int loc: @location ref); + +cil_type_location( + int id: @cil_type ref, + int loc: @location ref); + +cil_method_location( + int id: @cil_method ref, + int loc: @location ref); + +@cil_namespace = @namespace; + +@cil_type_container = @cil_type | @cil_namespace | @cil_method; + +case @cil_type.kind of + 0 = @cil_valueorreftype +| 1 = @cil_typeparameter +| 2 = @cil_array_type +| 3 = @cil_pointer_type +| 4 = @cil_function_pointer_type +; + +cil_type( + unique int id: @cil_type, + string name: string ref, + int kind: int ref, + int parent: @cil_type_container ref, + int sourceDecl: @cil_type ref); + +cil_pointer_type( + unique int id: @cil_pointer_type ref, + int pointee: @cil_type ref); + +cil_array_type( + unique int id: @cil_array_type ref, + int element_type: @cil_type ref, + int rank: int ref); + +cil_function_pointer_return_type( + unique int id: @cil_function_pointer_type ref, + int return_type: @cil_type ref); + +cil_method( + unique int id: @cil_method, + string name: string ref, + int parent: @cil_type ref, + int return_type: @cil_type ref); + +cil_method_source_declaration( + unique int method: @cil_method ref, + int source: @cil_method ref); + +cil_method_implementation( + unique int id: @cil_method_implementation, + int method: @cil_method ref, + int location: @assembly ref); + +cil_implements( + int id: @cil_method ref, + int decl: @cil_method ref); + +#keyset[parent, name] +cil_field( + unique int id: @cil_field, + int parent: @cil_type ref, + string name: string ref, + int field_type: @cil_type ref); + +@cil_element = @cil_instruction | @cil_declaration | @cil_handler | @cil_attribute | @cil_namespace; +@cil_named_element = @cil_declaration | @cil_namespace; +@cil_declaration = @cil_variable | @cil_method | @cil_type | @cil_member; +@cil_accessible = @cil_declaration; +@cil_variable = @cil_field | @cil_stack_variable; +@cil_stack_variable = @cil_local_variable | @cil_parameter; +@cil_member = @cil_method | @cil_type | @cil_field | @cil_property | @cil_event; +@cil_custom_modifier_receiver = @cil_method | @cil_property | @cil_parameter | @cil_field | @cil_function_pointer_type; +@cil_parameterizable = @cil_method | @cil_function_pointer_type; +@cil_has_type_annotation = @cil_stack_variable | @cil_property | @cil_field | @cil_method | @cil_function_pointer_type; + +#keyset[parameterizable, index] +cil_parameter( + unique int id: @cil_parameter, + int parameterizable: @cil_parameterizable ref, + int index: int ref, + int param_type: @cil_type ref); + +cil_parameter_in(unique int id: @cil_parameter ref); +cil_parameter_out(unique int id: @cil_parameter ref); + +cil_setter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +#keyset[id, modifier] +cil_custom_modifiers( + int id: @cil_custom_modifier_receiver ref, + int modifier: @cil_type ref, + int kind: int ref); // modreq: 1, modopt: 0 + +cil_type_annotation( + int id: @cil_has_type_annotation ref, + int annotation: int ref); + +cil_getter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_adder(unique int event: @cil_event ref, + int method: @cil_method ref); + +cil_remover(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_raiser(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_property( + unique int id: @cil_property, + int parent: @cil_type ref, + string name: string ref, + int property_type: @cil_type ref); + +#keyset[parent, name] +cil_event(unique int id: @cil_event, + int parent: @cil_type ref, + string name: string ref, + int event_type: @cil_type ref); + +#keyset[impl, index] +cil_local_variable( + unique int id: @cil_local_variable, + int impl: @cil_method_implementation ref, + int index: int ref, + int var_type: @cil_type ref); + +cil_function_pointer_calling_conventions( + int id: @cil_function_pointer_type ref, + int kind: int ref); + +// CIL handlers (exception handlers etc). + +case @cil_handler.kind of + 0 = @cil_catch_handler +| 1 = @cil_filter_handler +| 2 = @cil_finally_handler +| 4 = @cil_fault_handler +; + +#keyset[impl, index] +cil_handler( + unique int id: @cil_handler, + int impl: @cil_method_implementation ref, + int index: int ref, + int kind: int ref, + int try_start: @cil_instruction ref, + int try_end: @cil_instruction ref, + int handler_start: @cil_instruction ref); + +cil_handler_filter( + unique int id: @cil_handler ref, + int filter_start: @cil_instruction ref); + +cil_handler_type( + unique int id: @cil_handler ref, + int catch_type: @cil_type ref); + +@cil_controlflow_node = @cil_entry_point | @cil_instruction; + +@cil_entry_point = @cil_method_implementation | @cil_handler; + +@cil_dataflow_node = @cil_instruction | @cil_variable | @cil_method; + +cil_method_stack_size( + unique int method: @cil_method_implementation ref, + int size: int ref); + +// CIL modifiers + +cil_public(int id: @cil_member ref); +cil_private(int id: @cil_member ref); +cil_protected(int id: @cil_member ref); +cil_internal(int id: @cil_member ref); +cil_static(int id: @cil_member ref); +cil_sealed(int id: @cil_member ref); +cil_virtual(int id: @cil_method ref); +cil_abstract(int id: @cil_member ref); +cil_class(int id: @cil_type ref); +cil_interface(int id: @cil_type ref); +cil_security(int id: @cil_member ref); +cil_requiresecobject(int id: @cil_method ref); +cil_specialname(int id: @cil_method ref); +cil_newslot(int id: @cil_method ref); + +cil_base_class(unique int id: @cil_type ref, int base: @cil_type ref); +cil_base_interface(int id: @cil_type ref, int base: @cil_type ref); +cil_enum_underlying_type(unique int id: @cil_type ref, int underlying: @cil_type ref); + +#keyset[unbound, index] +cil_type_parameter( + int unbound: @cil_member ref, + int index: int ref, + int param: @cil_typeparameter ref); + +#keyset[bound, index] +cil_type_argument( + int bound: @cil_member ref, + int index: int ref, + int t: @cil_type ref); + +// CIL type parameter constraints + +cil_typeparam_covariant(int tp: @cil_typeparameter ref); +cil_typeparam_contravariant(int tp: @cil_typeparameter ref); +cil_typeparam_class(int tp: @cil_typeparameter ref); +cil_typeparam_struct(int tp: @cil_typeparameter ref); +cil_typeparam_new(int tp: @cil_typeparameter ref); +cil_typeparam_constraint(int tp: @cil_typeparameter ref, int supertype: @cil_type ref); + +// CIL attributes + +cil_attribute( + unique int attributeid: @cil_attribute, + int element: @cil_declaration ref, + int constructor: @cil_method ref); + +#keyset[attribute_id, param] +cil_attribute_named_argument( + int attribute_id: @cil_attribute ref, + string param: string ref, + string value: string ref); + +#keyset[attribute_id, index] +cil_attribute_positional_argument( + int attribute_id: @cil_attribute ref, + int index: int ref, + string value: string ref); + + +// Common .Net data model covering both C# and CIL + +// Common elements +@dotnet_element = @element | @cil_element; +@dotnet_named_element = @named_element | @cil_named_element; +@dotnet_callable = @callable | @cil_method; +@dotnet_variable = @variable | @cil_variable; +@dotnet_field = @field | @cil_field; +@dotnet_parameter = @parameter | @cil_parameter; +@dotnet_declaration = @declaration | @cil_declaration; +@dotnet_member = @member | @cil_member; +@dotnet_event = @event | @cil_event; +@dotnet_property = @property | @cil_property | @indexer; +@dotnet_parameterizable = @parameterizable | @cil_parameterizable; + +// Common types +@dotnet_type = @type | @cil_type; +@dotnet_call = @call | @cil_call_any; +@dotnet_throw = @throw_element | @cil_throw_any; +@dotnet_valueorreftype = @cil_valueorreftype | @value_or_ref_type | @cil_array_type | @void_type; +@dotnet_typeparameter = @type_parameter | @cil_typeparameter; +@dotnet_array_type = @array_type | @cil_array_type; +@dotnet_pointer_type = @pointer_type | @cil_pointer_type; +@dotnet_type_parameter = @type_parameter | @cil_typeparameter; +@dotnet_generic = @dotnet_valueorreftype | @dotnet_callable; + +// Attributes +@dotnet_attribute = @attribute | @cil_attribute; + +// Expressions +@dotnet_expr = @expr | @cil_expr; + +// Literals +@dotnet_literal = @literal_expr | @cil_literal; +@dotnet_string_literal = @string_literal_expr | @cil_ldstr; +@dotnet_int_literal = @integer_literal_expr | @cil_ldc_i; +@dotnet_float_literal = @float_literal_expr | @cil_ldc_r; +@dotnet_null_literal = @null_literal_expr | @cil_ldnull; + +@metadata_entity = @cil_method | @cil_type | @cil_field | @cil_property | @field | @property | + @callable | @value_or_ref_type | @void_type; + +metadata_handle(int entity : @metadata_entity ref, int location: @assembly ref, int handle: int ref) diff --git a/csharp/downgrades/c9ee11bd1ee96e925a35cedff000be924634447f/semmlecode.csharp.dbscheme b/csharp/downgrades/c9ee11bd1ee96e925a35cedff000be924634447f/semmlecode.csharp.dbscheme new file mode 100644 index 00000000000..f145a9a7275 --- /dev/null +++ b/csharp/downgrades/c9ee11bd1ee96e925a35cedff000be924634447f/semmlecode.csharp.dbscheme @@ -0,0 +1,2094 @@ +/* This is a dummy line to alter the dbscheme, so we can make a database upgrade + * without actually changing any of the dbscheme predicates. It contains a date + * to allow for such updates in the future as well. + * + * 2021-07-14 + * + * DO NOT remove this comment carelessly, since it can revert the dbscheme back to a + * previously seen state (matching a previously seen SHA), which would make the upgrade + * mechanism not work properly. + */ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * csc f1.cs f2.cs f3.cs + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | --compiler + * 1 | *path to compiler* + * 2 | f1.cs + * 3 | f2.cs + * 4 | f3.cs + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The expanded arguments that were passed to the extractor for a + * compiler invocation. This is similar to `compilation_args`, but + * for a `@someFile.rsp` argument, it includes the arguments from that + * file, rather than just taking the argument literally. + */ +#keyset[id, num] +compilation_expanded_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.cs + * 1 | f2.cs + * 2 | f3.cs + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The references used by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs /r:ref1.dll /r:ref2.dll /r:ref3.dll + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | ref1.dll + * 1 | ref2.dll + * 2 | ref3.dll + */ +#keyset[id, num] +compilation_referencing_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location ref +); + +extractor_messages( + unique int id: @extractor_message, + int severity: int ref, + string origin : string ref, + string text : string ref, + string entity : string ref, + int location: @location ref, + string stack_trace : string ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +compilation_assembly( + unique int id : @compilation ref, + int assembly: @assembly ref +) + +// Populated by the CSV extractor +externalData( + int id: @externalDataElement, + string path: string ref, + int column: int ref, + string value: string ref); + +sourceLocationPrefix( + string prefix: string ref); + +/* + * C# dbscheme + */ + +/** ELEMENTS **/ + +@element = @declaration | @stmt | @expr | @modifier | @attribute | @namespace_declaration + | @using_directive | @type_parameter_constraints | @externalDataElement + | @xmllocatable | @asp_element | @namespace | @preprocessor_directive; + +@declaration = @callable | @generic | @assignable | @namespace; + +@named_element = @namespace | @declaration; + +@declaration_with_accessors = @property | @indexer | @event; + +@assignable = @variable | @assignable_with_accessors | @event; + +@assignable_with_accessors = @property | @indexer; + +@attributable = @assembly | @field | @parameter | @operator | @method | @constructor + | @destructor | @callable_accessor | @value_or_ref_type | @declaration_with_accessors + | @local_function | @lambda_expr; + +/** LOCATIONS, ASEMMBLIES, MODULES, FILES and FOLDERS **/ + +@location = @location_default | @assembly; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +locations_mapped( + unique int id: @location_default ref, + int mapped_to: @location_default ref); + +@sourceline = @file | @callable | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref); + +assemblies( + unique int id: @assembly, + int file: @file ref, + string fullname: string ref, + string name: string ref, + string version: string ref); + +files( + unique int id: @file, + string name: string ref); + +folders( + unique int id: @folder, + string name: string ref); + +@container = @folder | @file ; + +containerparent( + int parent: @container ref, + unique int child: @container ref); + +file_extraction_mode( + unique int file: @file ref, + int mode: int ref + /* 0 = normal, 1 = standalone extractor */ + ); + +/** NAMESPACES **/ + +@type_container = @namespace | @type; + +namespaces( + unique int id: @namespace, + string name: string ref); + +namespace_declarations( + unique int id: @namespace_declaration, + int namespace_id: @namespace ref); + +namespace_declaration_location( + unique int id: @namespace_declaration ref, + int loc: @location ref); + +parent_namespace( + unique int child_id: @type_container ref, + int namespace_id: @namespace ref); + +@declaration_or_directive = @namespace_declaration | @type | @using_directive; + +parent_namespace_declaration( + int child_id: @declaration_or_directive ref, // cannot be unique because of partial classes + int namespace_id: @namespace_declaration ref); + +@using_directive = @using_namespace_directive | @using_static_directive; + +using_global( + unique int id: @using_directive ref +); + +using_namespace_directives( + unique int id: @using_namespace_directive, + int namespace_id: @namespace ref); + +using_static_directives( + unique int id: @using_static_directive, + int type_id: @type_or_ref ref); + +using_directive_location( + unique int id: @using_directive ref, + int loc: @location ref); + +@preprocessor_directive = @pragma_warning | @pragma_checksum | @directive_define | @directive_undefine | @directive_warning + | @directive_error | @directive_nullable | @directive_line | @directive_region | @directive_endregion | @directive_if + | @directive_elif | @directive_else | @directive_endif; + +@conditional_directive = @directive_if | @directive_elif; +@branch_directive = @directive_if | @directive_elif | @directive_else; + +directive_ifs( + unique int id: @directive_if, + int branchTaken: int ref, /* 0: false, 1: true */ + int conditionValue: int ref); /* 0: false, 1: true */ + +directive_elifs( + unique int id: @directive_elif, + int branchTaken: int ref, /* 0: false, 1: true */ + int conditionValue: int ref, /* 0: false, 1: true */ + int parent: @directive_if ref, + int index: int ref); + +directive_elses( + unique int id: @directive_else, + int branchTaken: int ref, /* 0: false, 1: true */ + int parent: @directive_if ref, + int index: int ref); + +#keyset[id, start] +directive_endifs( + unique int id: @directive_endif, + unique int start: @directive_if ref); + +directive_define_symbols( + unique int id: @define_symbol_expr ref, + string name: string ref); + +directive_regions( + unique int id: @directive_region, + string name: string ref); + +#keyset[id, start] +directive_endregions( + unique int id: @directive_endregion, + unique int start: @directive_region ref); + +directive_lines( + unique int id: @directive_line, + int kind: int ref); /* 0: default, 1: hidden, 2: numeric, 3: span */ + +directive_line_value( + unique int id: @directive_line ref, + int line: int ref); + +directive_line_file( + unique int id: @directive_line ref, + int file: @file ref); + +directive_line_offset( + unique int id: @directive_line ref, + int offset: int ref); + +directive_line_span( + unique int id: @directive_line ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +directive_nullables( + unique int id: @directive_nullable, + int setting: int ref, /* 0: disable, 1: enable, 2: restore */ + int target: int ref); /* 0: none, 1: annotations, 2: warnings */ + +directive_warnings( + unique int id: @directive_warning, + string message: string ref); + +directive_errors( + unique int id: @directive_error, + string message: string ref); + +directive_undefines( + unique int id: @directive_undefine, + string name: string ref); + +directive_defines( + unique int id: @directive_define, + string name: string ref); + +pragma_checksums( + unique int id: @pragma_checksum, + int file: @file ref, + string guid: string ref, + string bytes: string ref); + +pragma_warnings( + unique int id: @pragma_warning, + int kind: int ref /* 0 = disable, 1 = restore */); + +#keyset[id, index] +pragma_warning_error_codes( + int id: @pragma_warning ref, + string errorCode: string ref, + int index: int ref); + +preprocessor_directive_location( + unique int id: @preprocessor_directive ref, + int loc: @location ref); + +preprocessor_directive_compilation( + unique int id: @preprocessor_directive ref, + int compilation: @compilation ref); + +preprocessor_directive_active( + unique int id: @preprocessor_directive ref, + int active: int ref); /* 0: false, 1: true */ + +/** TYPES **/ + +types( + unique int id: @type, + int kind: int ref, + string name: string ref); + +case @type.kind of + 1 = @bool_type +| 2 = @char_type +| 3 = @decimal_type +| 4 = @sbyte_type +| 5 = @short_type +| 6 = @int_type +| 7 = @long_type +| 8 = @byte_type +| 9 = @ushort_type +| 10 = @uint_type +| 11 = @ulong_type +| 12 = @float_type +| 13 = @double_type +| 14 = @enum_type +| 15 = @struct_type +| 17 = @class_type +| 19 = @interface_type +| 20 = @delegate_type +| 21 = @null_type +| 22 = @type_parameter +| 23 = @pointer_type +| 24 = @nullable_type +| 25 = @array_type +| 26 = @void_type +| 27 = @int_ptr_type +| 28 = @uint_ptr_type +| 29 = @dynamic_type +| 30 = @arglist_type +| 31 = @unknown_type +| 32 = @tuple_type +| 33 = @function_pointer_type +| 34 = @inline_array_type + ; + +@simple_type = @bool_type | @char_type | @integral_type | @floating_point_type | @decimal_type; +@integral_type = @signed_integral_type | @unsigned_integral_type; +@signed_integral_type = @sbyte_type | @short_type | @int_type | @long_type; +@unsigned_integral_type = @byte_type | @ushort_type | @uint_type | @ulong_type; +@floating_point_type = @float_type | @double_type; +@value_type = @simple_type | @enum_type | @struct_type | @nullable_type | @int_ptr_type + | @uint_ptr_type | @tuple_type | @void_type | @inline_array_type; +@ref_type = @class_type | @interface_type | @array_type | @delegate_type | @null_type + | @dynamic_type; +@value_or_ref_type = @value_type | @ref_type; + +typerefs( + unique int id: @typeref, + string name: string ref); + +typeref_type( + int id: @typeref ref, + unique int typeId: @type ref); + +@type_or_ref = @type | @typeref; + +array_element_type( + unique int array: @array_type ref, + int dimension: int ref, + int rank: int ref, + int element: @type_or_ref ref); + +nullable_underlying_type( + unique int nullable: @nullable_type ref, + int underlying: @type_or_ref ref); + +pointer_referent_type( + unique int pointer: @pointer_type ref, + int referent: @type_or_ref ref); + +enum_underlying_type( + unique int enum_id: @enum_type ref, + int underlying_type_id: @type_or_ref ref); + +delegate_return_type( + unique int delegate_id: @delegate_type ref, + int return_type_id: @type_or_ref ref); + +function_pointer_return_type( + unique int function_pointer_id: @function_pointer_type ref, + int return_type_id: @type_or_ref ref); + +extend( + int sub: @type ref, + int super: @type_or_ref ref); + +anonymous_types( + unique int id: @type ref); + +@interface_or_ref = @interface_type | @typeref; + +implement( + int sub: @type ref, + int super: @type_or_ref ref); + +type_location( + int id: @type ref, + int loc: @location ref); + +tuple_underlying_type( + unique int tuple: @tuple_type ref, + int struct: @type_or_ref ref); + +#keyset[tuple, index] +tuple_element( + int tuple: @tuple_type ref, + int index: int ref, + unique int field: @field ref); + +attributes( + unique int id: @attribute, + int kind: int ref, + int type_id: @type_or_ref ref, + int target: @attributable ref); + +case @attribute.kind of + 0 = @attribute_default +| 1 = @attribute_return +| 2 = @attribute_assembly +| 3 = @attribute_module +; + +attribute_location( + int id: @attribute ref, + int loc: @location ref); + +@type_mention_parent = @element | @type_mention; + +type_mention( + unique int id: @type_mention, + int type_id: @type_or_ref ref, + int parent: @type_mention_parent ref); + +type_mention_location( + unique int id: @type_mention ref, + int loc: @location ref); + +@has_type_annotation = @assignable | @type_parameter | @callable | @expr | @delegate_type | @generic | @function_pointer_type; + +/** + * A direct annotation on an entity, for example `string? x;`. + * + * Annotations: + * 2 = reftype is not annotated "!" + * 3 = reftype is annotated "?" + * 4 = readonly ref type / in parameter + * 5 = ref type parameter, return or local variable + * 6 = out parameter + * + * Note that the annotation depends on the element it annotates. + * @assignable: The annotation is on the type of the assignable, for example the variable type. + * @type_parameter: The annotation is on the reftype constraint + * @callable: The annotation is on the return type + * @array_type: The annotation is on the element type + */ +type_annotation(int id: @has_type_annotation ref, int annotation: int ref); + +nullability(unique int nullability: @nullability, int kind: int ref); + +case @nullability.kind of + 0 = @oblivious +| 1 = @not_annotated +| 2 = @annotated +; + +#keyset[parent, index] +nullability_parent(int nullability: @nullability ref, int index: int ref, int parent: @nullability ref) + +type_nullability(int id: @has_type_annotation ref, int nullability: @nullability ref); + +/** + * The nullable flow state of an expression, as determined by Roslyn. + * 0 = none (default, not populated) + * 1 = not null + * 2 = maybe null + */ +expr_flowstate(unique int id: @expr ref, int state: int ref); + +/** GENERICS **/ + +@generic = @type | @method | @local_function; + +type_parameters( + unique int id: @type_parameter ref, + int index: int ref, + int generic_id: @generic ref, + int variance: int ref /* none = 0, out = 1, in = 2 */); + +#keyset[constructed_id, index] +type_arguments( + int id: @type_or_ref ref, + int index: int ref, + int constructed_id: @generic_or_ref ref); + +@generic_or_ref = @generic | @typeref; + +constructed_generic( + unique int constructed: @generic ref, + int generic: @generic_or_ref ref); + +type_parameter_constraints( + unique int id: @type_parameter_constraints, + int param_id: @type_parameter ref); + +type_parameter_constraints_location( + int id: @type_parameter_constraints ref, + int loc: @location ref); + +general_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int kind: int ref /* class = 1, struct = 2, new = 3 */); + +specific_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref); + +specific_type_parameter_nullability( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref, + int nullability: @nullability ref); + +/** FUNCTION POINTERS */ + +function_pointer_calling_conventions( + int id: @function_pointer_type ref, + int kind: int ref); + +#keyset[id, index] +has_unmanaged_calling_conventions( + int id: @function_pointer_type ref, + int index: int ref, + int conv_id: @type_or_ref ref); + +/** MODIFIERS */ + +@modifiable = @modifiable_direct | @event_accessor; + +@modifiable_direct = @member | @accessor | @local_function | @anonymous_function_expr; + +modifiers( + unique int id: @modifier, + string name: string ref); + +has_modifiers( + int id: @modifiable_direct ref, + int mod_id: @modifier ref); + +compiler_generated(unique int id: @modifiable ref); + +/** MEMBERS **/ + +@member = @method | @constructor | @destructor | @field | @property | @event | @operator | @indexer | @type; + +@named_exprorstmt = @goto_stmt | @labeled_stmt | @expr; + +@virtualizable = @method | @property | @indexer | @event | @operator; + +exprorstmt_name( + unique int parent_id: @named_exprorstmt ref, + string name: string ref); + +nested_types( + unique int id: @type ref, + int declaring_type_id: @type ref, + int unbound_id: @type ref); + +properties( + unique int id: @property, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @property ref); + +property_location( + int id: @property ref, + int loc: @location ref); + +indexers( + unique int id: @indexer, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @indexer ref); + +indexer_location( + int id: @indexer ref, + int loc: @location ref); + +accessors( + unique int id: @accessor, + int kind: int ref, + string name: string ref, + int declaring_member_id: @member ref, + int unbound_id: @accessor ref); + +case @accessor.kind of + 1 = @getter +| 2 = @setter + ; + +init_only_accessors( + unique int id: @accessor ref); + +accessor_location( + int id: @accessor ref, + int loc: @location ref); + +events( + unique int id: @event, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @event ref); + +event_location( + int id: @event ref, + int loc: @location ref); + +event_accessors( + unique int id: @event_accessor, + int kind: int ref, + string name: string ref, + int declaring_event_id: @event ref, + int unbound_id: @event_accessor ref); + +case @event_accessor.kind of + 1 = @add_event_accessor +| 2 = @remove_event_accessor + ; + +event_accessor_location( + int id: @event_accessor ref, + int loc: @location ref); + +operators( + unique int id: @operator, + string name: string ref, + string symbol: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @operator ref); + +operator_location( + int id: @operator ref, + int loc: @location ref); + +constant_value( + int id: @variable ref, + string value: string ref); + +/** CALLABLES **/ + +@callable = @method | @constructor | @destructor | @operator | @callable_accessor | @anonymous_function_expr | @local_function; + +@callable_accessor = @accessor | @event_accessor; + +methods( + unique int id: @method, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @method ref); + +method_location( + int id: @method ref, + int loc: @location ref); + +constructors( + unique int id: @constructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @constructor ref); + +constructor_location( + int id: @constructor ref, + int loc: @location ref); + +destructors( + unique int id: @destructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @destructor ref); + +destructor_location( + int id: @destructor ref, + int loc: @location ref); + +overrides( + int id: @callable ref, + int base_id: @callable ref); + +explicitly_implements( + int id: @member ref, + int interface_id: @interface_or_ref ref); + +local_functions( + unique int id: @local_function, + string name: string ref, + int return_type: @type ref, + int unbound_id: @local_function ref); + +local_function_stmts( + unique int fn: @local_function_stmt ref, + int stmt: @local_function ref); + +/** VARIABLES **/ + +@variable = @local_scope_variable | @field; + +@local_scope_variable = @local_variable | @parameter; + +fields( + unique int id: @field, + int kind: int ref, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @field ref); + +case @field.kind of + 1 = @addressable_field +| 2 = @constant + ; + +field_location( + int id: @field ref, + int loc: @location ref); + +localvars( + unique int id: @local_variable, + int kind: int ref, + string name: string ref, + int implicitly_typed: int ref /* 0 = no, 1 = yes */, + int type_id: @type_or_ref ref, + int parent_id: @local_var_decl_expr ref); + +case @local_variable.kind of + 1 = @addressable_local_variable +| 2 = @local_constant +| 3 = @local_variable_ref + ; + +localvar_location( + unique int id: @local_variable ref, + int loc: @location ref); + +@parameterizable = @callable | @delegate_type | @indexer | @function_pointer_type; + +#keyset[name, parent_id] +#keyset[index, parent_id] +params( + unique int id: @parameter, + string name: string ref, + int type_id: @type_or_ref ref, + int index: int ref, + int mode: int ref, /* value = 0, ref = 1, out = 2, array = 3, this = 4 */ + int parent_id: @parameterizable ref, + int unbound_id: @parameter ref); + +param_location( + int id: @parameter ref, + int loc: @location ref); + +@has_scoped_annotation = @local_scope_variable + +scoped_annotation( + int id: @has_scoped_annotation ref, + int kind: int ref // scoped ref = 1, scoped value = 2 + ); + +/** STATEMENTS **/ + +@exprorstmt_parent = @control_flow_element | @top_level_exprorstmt_parent; + +statements( + unique int id: @stmt, + int kind: int ref); + +#keyset[index, parent] +stmt_parent( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_stmt_parent = @callable; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +stmt_parent_top_level( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @top_level_stmt_parent ref); + +case @stmt.kind of + 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @switch_stmt +| 5 = @while_stmt +| 6 = @do_stmt +| 7 = @for_stmt +| 8 = @foreach_stmt +| 9 = @break_stmt +| 10 = @continue_stmt +| 11 = @goto_stmt +| 12 = @goto_case_stmt +| 13 = @goto_default_stmt +| 14 = @throw_stmt +| 15 = @return_stmt +| 16 = @yield_stmt +| 17 = @try_stmt +| 18 = @checked_stmt +| 19 = @unchecked_stmt +| 20 = @lock_stmt +| 21 = @using_block_stmt +| 22 = @var_decl_stmt +| 23 = @const_decl_stmt +| 24 = @empty_stmt +| 25 = @unsafe_stmt +| 26 = @fixed_stmt +| 27 = @label_stmt +| 28 = @catch +| 29 = @case_stmt +| 30 = @local_function_stmt +| 31 = @using_decl_stmt + ; + +@using_stmt = @using_block_stmt | @using_decl_stmt; + +@labeled_stmt = @label_stmt | @case; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @using_decl_stmt; + +@cond_stmt = @if_stmt | @switch_stmt; + +@loop_stmt = @while_stmt | @do_stmt | @for_stmt | @foreach_stmt; + +@jump_stmt = @break_stmt | @goto_any_stmt | @continue_stmt | @throw_stmt | @return_stmt + | @yield_stmt; + +@goto_any_stmt = @goto_default_stmt | @goto_case_stmt | @goto_stmt; + + +stmt_location( + unique int id: @stmt ref, + int loc: @location ref); + +catch_type( + unique int catch_id: @catch ref, + int type_id: @type_or_ref ref, + int kind: int ref /* explicit = 1, implicit = 2 */); + +foreach_stmt_info( + unique int id: @foreach_stmt ref, + int kind: int ref /* non-async = 1, async = 2 */); + +@foreach_symbol = @method | @property | @type_or_ref; + +#keyset[id, kind] +foreach_stmt_desugar( + int id: @foreach_stmt ref, + int symbol: @foreach_symbol ref, + int kind: int ref /* GetEnumeratorMethod = 1, CurrentProperty = 2, MoveNextMethod = 3, DisposeMethod = 4, ElementType = 5 */); + +/** EXPRESSIONS **/ + +expressions( + unique int id: @expr, + int kind: int ref, + int type_id: @type_or_ref ref); + +#keyset[index, parent] +expr_parent( + unique int expr: @expr ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_expr_parent = @attribute | @field | @property | @indexer | @parameter | @directive_if | @directive_elif; + +@top_level_exprorstmt_parent = @top_level_expr_parent | @top_level_stmt_parent; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +expr_parent_top_level( + unique int expr: @expr ref, + int index: int ref, + int parent: @top_level_exprorstmt_parent ref); + +case @expr.kind of +/* literal */ + 1 = @bool_literal_expr +| 2 = @char_literal_expr +| 3 = @decimal_literal_expr +| 4 = @int_literal_expr +| 5 = @long_literal_expr +| 6 = @uint_literal_expr +| 7 = @ulong_literal_expr +| 8 = @float_literal_expr +| 9 = @double_literal_expr +| 10 = @utf16_string_literal_expr +| 11 = @null_literal_expr +/* primary & unary */ +| 12 = @this_access_expr +| 13 = @base_access_expr +| 14 = @local_variable_access_expr +| 15 = @parameter_access_expr +| 16 = @field_access_expr +| 17 = @property_access_expr +| 18 = @method_access_expr +| 19 = @event_access_expr +| 20 = @indexer_access_expr +| 21 = @array_access_expr +| 22 = @type_access_expr +| 23 = @typeof_expr +| 24 = @method_invocation_expr +| 25 = @delegate_invocation_expr +| 26 = @operator_invocation_expr +| 27 = @cast_expr +| 28 = @object_creation_expr +| 29 = @explicit_delegate_creation_expr +| 30 = @implicit_delegate_creation_expr +| 31 = @array_creation_expr +| 32 = @default_expr +| 33 = @plus_expr +| 34 = @minus_expr +| 35 = @bit_not_expr +| 36 = @log_not_expr +| 37 = @post_incr_expr +| 38 = @post_decr_expr +| 39 = @pre_incr_expr +| 40 = @pre_decr_expr +/* multiplicative */ +| 41 = @mul_expr +| 42 = @div_expr +| 43 = @rem_expr +/* additive */ +| 44 = @add_expr +| 45 = @sub_expr +/* shift */ +| 46 = @lshift_expr +| 47 = @rshift_expr +/* relational */ +| 48 = @lt_expr +| 49 = @gt_expr +| 50 = @le_expr +| 51 = @ge_expr +/* equality */ +| 52 = @eq_expr +| 53 = @ne_expr +/* logical */ +| 54 = @bit_and_expr +| 55 = @bit_xor_expr +| 56 = @bit_or_expr +| 57 = @log_and_expr +| 58 = @log_or_expr +/* type testing */ +| 59 = @is_expr +| 60 = @as_expr +/* null coalescing */ +| 61 = @null_coalescing_expr +/* conditional */ +| 62 = @conditional_expr +/* assignment */ +| 63 = @simple_assign_expr +| 64 = @assign_add_expr +| 65 = @assign_sub_expr +| 66 = @assign_mul_expr +| 67 = @assign_div_expr +| 68 = @assign_rem_expr +| 69 = @assign_and_expr +| 70 = @assign_xor_expr +| 71 = @assign_or_expr +| 72 = @assign_lshift_expr +| 73 = @assign_rshift_expr +/* more */ +| 74 = @object_init_expr +| 75 = @collection_init_expr +| 76 = @array_init_expr +| 77 = @checked_expr +| 78 = @unchecked_expr +| 79 = @constructor_init_expr +| 80 = @add_event_expr +| 81 = @remove_event_expr +| 82 = @par_expr +| 83 = @local_var_decl_expr +| 84 = @lambda_expr +| 85 = @anonymous_method_expr +| 86 = @namespace_expr +/* dynamic */ +| 92 = @dynamic_element_access_expr +| 93 = @dynamic_member_access_expr +/* unsafe */ +| 100 = @pointer_indirection_expr +| 101 = @address_of_expr +| 102 = @sizeof_expr +/* async */ +| 103 = @await_expr +/* C# 6.0 */ +| 104 = @nameof_expr +| 105 = @interpolated_string_expr +| 106 = @unknown_expr +/* C# 7.0 */ +| 107 = @throw_expr +| 108 = @tuple_expr +| 109 = @local_function_invocation_expr +| 110 = @ref_expr +| 111 = @discard_expr +/* C# 8.0 */ +| 112 = @range_expr +| 113 = @index_expr +| 114 = @switch_expr +| 115 = @recursive_pattern_expr +| 116 = @property_pattern_expr +| 117 = @positional_pattern_expr +| 118 = @switch_case_expr +| 119 = @assign_coalesce_expr +| 120 = @suppress_nullable_warning_expr +| 121 = @namespace_access_expr +/* C# 9.0 */ +| 122 = @lt_pattern_expr +| 123 = @gt_pattern_expr +| 124 = @le_pattern_expr +| 125 = @ge_pattern_expr +| 126 = @not_pattern_expr +| 127 = @and_pattern_expr +| 128 = @or_pattern_expr +| 129 = @function_pointer_invocation_expr +| 130 = @with_expr +/* C# 11.0 */ +| 131 = @list_pattern_expr +| 132 = @slice_pattern_expr +| 133 = @urshift_expr +| 134 = @assign_urshift_expr +| 135 = @utf8_string_literal_expr +/* C# 12.0 */ +| 136 = @collection_expr +| 137 = @spread_element_expr +/* Preprocessor */ +| 999 = @define_symbol_expr +; + +@switch = @switch_stmt | @switch_expr; +@case = @case_stmt | @switch_case_expr; +@pattern_match = @case | @is_expr; +@unary_pattern_expr = @not_pattern_expr; +@relational_pattern_expr = @gt_pattern_expr | @lt_pattern_expr | @ge_pattern_expr | @le_pattern_expr; +@binary_pattern_expr = @and_pattern_expr | @or_pattern_expr; + +@integer_literal_expr = @int_literal_expr | @long_literal_expr | @uint_literal_expr | @ulong_literal_expr; +@real_literal_expr = @float_literal_expr | @double_literal_expr | @decimal_literal_expr; +@string_literal_expr = @utf16_string_literal_expr | @utf8_string_literal_expr; +@literal_expr = @bool_literal_expr | @char_literal_expr | @integer_literal_expr | @real_literal_expr + | @string_literal_expr | @null_literal_expr; + +@assign_expr = @simple_assign_expr | @assign_op_expr | @local_var_decl_expr; +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr | @assign_event_expr | @assign_coalesce_expr; +@assign_event_expr = @add_event_expr | @remove_event_expr; + +@assign_arith_expr = @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr + | @assign_rem_expr +@assign_bitwise_expr = @assign_and_expr | @assign_or_expr | @assign_xor_expr + | @assign_lshift_expr | @assign_rshift_expr | @assign_urshift_expr; + +@member_access_expr = @field_access_expr | @property_access_expr | @indexer_access_expr | @event_access_expr + | @method_access_expr | @type_access_expr | @dynamic_member_access_expr; +@access_expr = @member_access_expr | @this_access_expr | @base_access_expr | @assignable_access_expr | @namespace_access_expr; +@element_access_expr = @indexer_access_expr | @array_access_expr | @dynamic_element_access_expr; + +@local_variable_access = @local_variable_access_expr | @local_var_decl_expr; +@local_scope_variable_access_expr = @parameter_access_expr | @local_variable_access; +@variable_access_expr = @local_scope_variable_access_expr | @field_access_expr; + +@assignable_access_expr = @variable_access_expr | @property_access_expr | @element_access_expr + | @event_access_expr | @dynamic_member_access_expr; + +@objectorcollection_init_expr = @object_init_expr | @collection_init_expr; + +@delegate_creation_expr = @explicit_delegate_creation_expr | @implicit_delegate_creation_expr; + +@bin_arith_op_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr; +@incr_op_expr = @pre_incr_expr | @post_incr_expr; +@decr_op_expr = @pre_decr_expr | @post_decr_expr; +@mut_op_expr = @incr_op_expr | @decr_op_expr; +@un_arith_op_expr = @plus_expr | @minus_expr | @mut_op_expr; +@arith_op_expr = @bin_arith_op_expr | @un_arith_op_expr; + +@ternary_log_op_expr = @conditional_expr; +@bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr; +@un_log_op_expr = @log_not_expr; +@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr; + +@bin_bit_op_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr + | @rshift_expr | @urshift_expr; +@un_bit_op_expr = @bit_not_expr; +@bit_expr = @un_bit_op_expr | @bin_bit_op_expr; + +@equality_op_expr = @eq_expr | @ne_expr; +@rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr; +@comp_expr = @equality_op_expr | @rel_op_expr; + +@op_expr = @assign_expr | @un_op | @bin_op | @ternary_op; + +@ternary_op = @ternary_log_op_expr; +@bin_op = @bin_arith_op_expr | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr; +@un_op = @un_arith_op_expr | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr + | @pointer_indirection_expr | @address_of_expr; + +@anonymous_function_expr = @lambda_expr | @anonymous_method_expr; + +@call = @method_invocation_expr | @constructor_init_expr | @operator_invocation_expr + | @delegate_invocation_expr | @object_creation_expr | @call_access_expr + | @local_function_invocation_expr | @function_pointer_invocation_expr; + +@call_access_expr = @property_access_expr | @event_access_expr | @indexer_access_expr; + +@late_bindable_expr = @dynamic_element_access_expr | @dynamic_member_access_expr + | @object_creation_expr | @method_invocation_expr | @operator_invocation_expr; + +@throw_element = @throw_expr | @throw_stmt; + +@implicitly_typeable_object_creation_expr = @object_creation_expr | @explicit_delegate_creation_expr; + +implicitly_typed_array_creation( + unique int id: @array_creation_expr ref); + +explicitly_sized_array_creation( + unique int id: @array_creation_expr ref); + +stackalloc_array_creation( + unique int id: @array_creation_expr ref); + +implicitly_typed_object_creation( + unique int id: @implicitly_typeable_object_creation_expr ref); + +mutator_invocation_mode( + unique int id: @operator_invocation_expr ref, + int mode: int ref /* prefix = 1, postfix = 2*/); + +expr_compiler_generated( + unique int id: @expr ref); + +expr_value( + unique int id: @expr ref, + string value: string ref); + +expr_call( + unique int caller_id: @expr ref, + int target_id: @callable ref); + +expr_access( + unique int accesser_id: @access_expr ref, + int target_id: @accessible ref); + +@accessible = @method | @assignable | @local_function | @namespace; + +expr_location( + unique int id: @expr ref, + int loc: @location ref); + +dynamic_member_name( + unique int id: @late_bindable_expr ref, + string name: string ref); + +@qualifiable_expr = @member_access_expr + | @method_invocation_expr + | @element_access_expr; + +conditional_access( + unique int id: @qualifiable_expr ref); + +expr_argument( + unique int id: @expr ref, + int mode: int ref); + /* mode is the same as params: value = 0, ref = 1, out = 2 */ + +expr_argument_name( + unique int id: @expr ref, + string name: string ref); + +lambda_expr_return_type( + unique int id: @lambda_expr ref, + int type_id: @type_or_ref ref); + +/** CONTROL/DATA FLOW **/ + +@control_flow_element = @stmt | @expr; + +/* XML Files */ + +xmlEncoding ( + unique int id: @file ref, + string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* Comments */ + +commentline( + unique int id: @commentline, + int kind: int ref, + string text: string ref, + string rawtext: string ref); + +case @commentline.kind of + 0 = @singlelinecomment +| 1 = @xmldoccomment +| 2 = @multilinecomment; + +commentline_location( + unique int id: @commentline ref, + int loc: @location ref); + +commentblock( + unique int id : @commentblock); + +commentblock_location( + unique int id: @commentblock ref, + int loc: @location ref); + +commentblock_binding( + int id: @commentblock ref, + int entity: @element ref, + int bindtype: int ref); /* 0: Parent, 1: Best, 2: Before, 3: After */ + +commentblock_child( + int id: @commentblock ref, + int commentline: @commentline ref, + int index: int ref); + +/* ASP.NET */ + +case @asp_element.kind of + 0=@asp_close_tag +| 1=@asp_code +| 2=@asp_comment +| 3=@asp_data_binding +| 4=@asp_directive +| 5=@asp_open_tag +| 6=@asp_quoted_string +| 7=@asp_text +| 8=@asp_xml_directive; + +@asp_attribute = @asp_code | @asp_data_binding | @asp_quoted_string; + +asp_elements( + unique int id: @asp_element, + int kind: int ref, + int loc: @location ref); + +asp_comment_server(unique int comment: @asp_comment ref); +asp_code_inline(unique int code: @asp_code ref); +asp_directive_attribute( + int directive: @asp_directive ref, + int index: int ref, + string name: string ref, + int value: @asp_quoted_string ref); +asp_directive_name( + unique int directive: @asp_directive ref, + string name: string ref); +asp_element_body( + unique int element: @asp_element ref, + string body: string ref); +asp_tag_attribute( + int tag: @asp_open_tag ref, + int index: int ref, + string name: string ref, + int attribute: @asp_attribute ref); +asp_tag_name( + unique int tag: @asp_open_tag ref, + string name: string ref); +asp_tag_isempty(int tag: @asp_open_tag ref); + +/* Common Intermediate Language - CIL */ + +case @cil_instruction.opcode of + 0 = @cil_nop +| 1 = @cil_break +| 2 = @cil_ldarg_0 +| 3 = @cil_ldarg_1 +| 4 = @cil_ldarg_2 +| 5 = @cil_ldarg_3 +| 6 = @cil_ldloc_0 +| 7 = @cil_ldloc_1 +| 8 = @cil_ldloc_2 +| 9 = @cil_ldloc_3 +| 10 = @cil_stloc_0 +| 11 = @cil_stloc_1 +| 12 = @cil_stloc_2 +| 13 = @cil_stloc_3 +| 14 = @cil_ldarg_s +| 15 = @cil_ldarga_s +| 16 = @cil_starg_s +| 17 = @cil_ldloc_s +| 18 = @cil_ldloca_s +| 19 = @cil_stloc_s +| 20 = @cil_ldnull +| 21 = @cil_ldc_i4_m1 +| 22 = @cil_ldc_i4_0 +| 23 = @cil_ldc_i4_1 +| 24 = @cil_ldc_i4_2 +| 25 = @cil_ldc_i4_3 +| 26 = @cil_ldc_i4_4 +| 27 = @cil_ldc_i4_5 +| 28 = @cil_ldc_i4_6 +| 29 = @cil_ldc_i4_7 +| 30 = @cil_ldc_i4_8 +| 31 = @cil_ldc_i4_s +| 32 = @cil_ldc_i4 +| 33 = @cil_ldc_i8 +| 34 = @cil_ldc_r4 +| 35 = @cil_ldc_r8 +| 37 = @cil_dup +| 38 = @cil_pop +| 39 = @cil_jmp +| 40 = @cil_call +| 41 = @cil_calli +| 42 = @cil_ret +| 43 = @cil_br_s +| 44 = @cil_brfalse_s +| 45 = @cil_brtrue_s +| 46 = @cil_beq_s +| 47 = @cil_bge_s +| 48 = @cil_bgt_s +| 49 = @cil_ble_s +| 50 = @cil_blt_s +| 51 = @cil_bne_un_s +| 52 = @cil_bge_un_s +| 53 = @cil_bgt_un_s +| 54 = @cil_ble_un_s +| 55 = @cil_blt_un_s +| 56 = @cil_br +| 57 = @cil_brfalse +| 58 = @cil_brtrue +| 59 = @cil_beq +| 60 = @cil_bge +| 61 = @cil_bgt +| 62 = @cil_ble +| 63 = @cil_blt +| 64 = @cil_bne_un +| 65 = @cil_bge_un +| 66 = @cil_bgt_un +| 67 = @cil_ble_un +| 68 = @cil_blt_un +| 69 = @cil_switch +| 70 = @cil_ldind_i1 +| 71 = @cil_ldind_u1 +| 72 = @cil_ldind_i2 +| 73 = @cil_ldind_u2 +| 74 = @cil_ldind_i4 +| 75 = @cil_ldind_u4 +| 76 = @cil_ldind_i8 +| 77 = @cil_ldind_i +| 78 = @cil_ldind_r4 +| 79 = @cil_ldind_r8 +| 80 = @cil_ldind_ref +| 81 = @cil_stind_ref +| 82 = @cil_stind_i1 +| 83 = @cil_stind_i2 +| 84 = @cil_stind_i4 +| 85 = @cil_stind_i8 +| 86 = @cil_stind_r4 +| 87 = @cil_stind_r8 +| 88 = @cil_add +| 89 = @cil_sub +| 90 = @cil_mul +| 91 = @cil_div +| 92 = @cil_div_un +| 93 = @cil_rem +| 94 = @cil_rem_un +| 95 = @cil_and +| 96 = @cil_or +| 97 = @cil_xor +| 98 = @cil_shl +| 99 = @cil_shr +| 100 = @cil_shr_un +| 101 = @cil_neg +| 102 = @cil_not +| 103 = @cil_conv_i1 +| 104 = @cil_conv_i2 +| 105 = @cil_conv_i4 +| 106 = @cil_conv_i8 +| 107 = @cil_conv_r4 +| 108 = @cil_conv_r8 +| 109 = @cil_conv_u4 +| 110 = @cil_conv_u8 +| 111 = @cil_callvirt +| 112 = @cil_cpobj +| 113 = @cil_ldobj +| 114 = @cil_ldstr +| 115 = @cil_newobj +| 116 = @cil_castclass +| 117 = @cil_isinst +| 118 = @cil_conv_r_un +| 121 = @cil_unbox +| 122 = @cil_throw +| 123 = @cil_ldfld +| 124 = @cil_ldflda +| 125 = @cil_stfld +| 126 = @cil_ldsfld +| 127 = @cil_ldsflda +| 128 = @cil_stsfld +| 129 = @cil_stobj +| 130 = @cil_conv_ovf_i1_un +| 131 = @cil_conv_ovf_i2_un +| 132 = @cil_conv_ovf_i4_un +| 133 = @cil_conv_ovf_i8_un +| 134 = @cil_conv_ovf_u1_un +| 135 = @cil_conv_ovf_u2_un +| 136 = @cil_conv_ovf_u4_un +| 137 = @cil_conv_ovf_u8_un +| 138 = @cil_conv_ovf_i_un +| 139 = @cil_conv_ovf_u_un +| 140 = @cil_box +| 141 = @cil_newarr +| 142 = @cil_ldlen +| 143 = @cil_ldelema +| 144 = @cil_ldelem_i1 +| 145 = @cil_ldelem_u1 +| 146 = @cil_ldelem_i2 +| 147 = @cil_ldelem_u2 +| 148 = @cil_ldelem_i4 +| 149 = @cil_ldelem_u4 +| 150 = @cil_ldelem_i8 +| 151 = @cil_ldelem_i +| 152 = @cil_ldelem_r4 +| 153 = @cil_ldelem_r8 +| 154 = @cil_ldelem_ref +| 155 = @cil_stelem_i +| 156 = @cil_stelem_i1 +| 157 = @cil_stelem_i2 +| 158 = @cil_stelem_i4 +| 159 = @cil_stelem_i8 +| 160 = @cil_stelem_r4 +| 161 = @cil_stelem_r8 +| 162 = @cil_stelem_ref +| 163 = @cil_ldelem +| 164 = @cil_stelem +| 165 = @cil_unbox_any +| 179 = @cil_conv_ovf_i1 +| 180 = @cil_conv_ovf_u1 +| 181 = @cil_conv_ovf_i2 +| 182 = @cil_conv_ovf_u2 +| 183 = @cil_conv_ovf_i4 +| 184 = @cil_conv_ovf_u4 +| 185 = @cil_conv_ovf_i8 +| 186 = @cil_conv_ovf_u8 +| 194 = @cil_refanyval +| 195 = @cil_ckinfinite +| 198 = @cil_mkrefany +| 208 = @cil_ldtoken +| 209 = @cil_conv_u2 +| 210 = @cil_conv_u1 +| 211 = @cil_conv_i +| 212 = @cil_conv_ovf_i +| 213 = @cil_conv_ovf_u +| 214 = @cil_add_ovf +| 215 = @cil_add_ovf_un +| 216 = @cil_mul_ovf +| 217 = @cil_mul_ovf_un +| 218 = @cil_sub_ovf +| 219 = @cil_sub_ovf_un +| 220 = @cil_endfinally +| 221 = @cil_leave +| 222 = @cil_leave_s +| 223 = @cil_stind_i +| 224 = @cil_conv_u +| 65024 = @cil_arglist +| 65025 = @cil_ceq +| 65026 = @cil_cgt +| 65027 = @cil_cgt_un +| 65028 = @cil_clt +| 65029 = @cil_clt_un +| 65030 = @cil_ldftn +| 65031 = @cil_ldvirtftn +| 65033 = @cil_ldarg +| 65034 = @cil_ldarga +| 65035 = @cil_starg +| 65036 = @cil_ldloc +| 65037 = @cil_ldloca +| 65038 = @cil_stloc +| 65039 = @cil_localloc +| 65041 = @cil_endfilter +| 65042 = @cil_unaligned +| 65043 = @cil_volatile +| 65044 = @cil_tail +| 65045 = @cil_initobj +| 65046 = @cil_constrained +| 65047 = @cil_cpblk +| 65048 = @cil_initblk +| 65050 = @cil_rethrow +| 65052 = @cil_sizeof +| 65053 = @cil_refanytype +| 65054 = @cil_readonly +; + +// CIL ignored instructions + +@cil_ignore = @cil_nop | @cil_break | @cil_volatile | @cil_unaligned; + +// CIL local/parameter/field access + +@cil_ldarg_any = @cil_ldarg_0 | @cil_ldarg_1 | @cil_ldarg_2 | @cil_ldarg_3 | @cil_ldarg_s | @cil_ldarga_s | @cil_ldarg | @cil_ldarga; +@cil_starg_any = @cil_starg | @cil_starg_s; + +@cil_ldloc_any = @cil_ldloc_0 | @cil_ldloc_1 | @cil_ldloc_2 | @cil_ldloc_3 | @cil_ldloc_s | @cil_ldloca_s | @cil_ldloc | @cil_ldloca; +@cil_stloc_any = @cil_stloc_0 | @cil_stloc_1 | @cil_stloc_2 | @cil_stloc_3 | @cil_stloc_s | @cil_stloc; + +@cil_ldfld_any = @cil_ldfld | @cil_ldsfld | @cil_ldsflda | @cil_ldflda; +@cil_stfld_any = @cil_stfld | @cil_stsfld; + +@cil_local_access = @cil_stloc_any | @cil_ldloc_any; +@cil_arg_access = @cil_starg_any | @cil_ldarg_any; +@cil_read_access = @cil_ldloc_any | @cil_ldarg_any | @cil_ldfld_any; +@cil_write_access = @cil_stloc_any | @cil_starg_any | @cil_stfld_any; + +@cil_stack_access = @cil_local_access | @cil_arg_access; +@cil_field_access = @cil_ldfld_any | @cil_stfld_any; + +@cil_access = @cil_read_access | @cil_write_access; + +// CIL constant/literal instructions + +@cil_ldc_i = @cil_ldc_i4_any | @cil_ldc_i8; + +@cil_ldc_i4_any = @cil_ldc_i4_m1 | @cil_ldc_i4_0 | @cil_ldc_i4_1 | @cil_ldc_i4_2 | @cil_ldc_i4_3 | + @cil_ldc_i4_4 | @cil_ldc_i4_5 | @cil_ldc_i4_6 | @cil_ldc_i4_7 | @cil_ldc_i4_8 | @cil_ldc_i4_s | @cil_ldc_i4; + +@cil_ldc_r = @cil_ldc_r4 | @cil_ldc_r8; + +@cil_literal = @cil_ldnull | @cil_ldc_i | @cil_ldc_r | @cil_ldstr; + +// Control flow + +@cil_conditional_jump = @cil_binary_jump | @cil_unary_jump; +@cil_binary_jump = @cil_beq_s | @cil_bge_s | @cil_bgt_s | @cil_ble_s | @cil_blt_s | + @cil_bne_un_s | @cil_bge_un_s | @cil_bgt_un_s | @cil_ble_un_s | @cil_blt_un_s | + @cil_beq | @cil_bge | @cil_bgt | @cil_ble | @cil_blt | + @cil_bne_un | @cil_bge_un | @cil_bgt_un | @cil_ble_un | @cil_blt_un; +@cil_unary_jump = @cil_brfalse_s | @cil_brtrue_s | @cil_brfalse | @cil_brtrue | @cil_switch; +@cil_unconditional_jump = @cil_br | @cil_br_s | @cil_leave_any; +@cil_leave_any = @cil_leave | @cil_leave_s; +@cil_jump = @cil_unconditional_jump | @cil_conditional_jump; + +// CIL call instructions + +@cil_call_any = @cil_jmp | @cil_call | @cil_calli | @cil_tail | @cil_callvirt | @cil_newobj; + +// CIL expression instructions + +@cil_expr = @cil_literal | @cil_binary_expr | @cil_unary_expr | @cil_call_any | @cil_read_access | + @cil_newarr | @cil_ldtoken | @cil_sizeof | + @cil_ldftn | @cil_ldvirtftn | @cil_localloc | @cil_mkrefany | @cil_refanytype | @cil_arglist | @cil_dup; + +@cil_unary_expr = + @cil_conversion_operation | @cil_unary_arithmetic_operation | @cil_unary_bitwise_operation| + @cil_ldlen | @cil_isinst | @cil_box | @cil_ldobj | @cil_castclass | @cil_unbox_any | + @cil_ldind | @cil_unbox; + +@cil_conversion_operation = + @cil_conv_i1 | @cil_conv_i2 | @cil_conv_i4 | @cil_conv_i8 | + @cil_conv_u1 | @cil_conv_u2 | @cil_conv_u4 | @cil_conv_u8 | + @cil_conv_ovf_i | @cil_conv_ovf_i_un | @cil_conv_ovf_i1 | @cil_conv_ovf_i1_un | + @cil_conv_ovf_i2 | @cil_conv_ovf_i2_un | @cil_conv_ovf_i4 | @cil_conv_ovf_i4_un | + @cil_conv_ovf_i8 | @cil_conv_ovf_i8_un | @cil_conv_ovf_u | @cil_conv_ovf_u_un | + @cil_conv_ovf_u1 | @cil_conv_ovf_u1_un | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_ovf_u4 | @cil_conv_ovf_u4_un | @cil_conv_ovf_u8 | @cil_conv_ovf_u8_un | + @cil_conv_r4 | @cil_conv_r8 | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_i | @cil_conv_u | @cil_conv_r_un; + +@cil_ldind = @cil_ldind_i | @cil_ldind_i1 | @cil_ldind_i2 | @cil_ldind_i4 | @cil_ldind_i8 | + @cil_ldind_r4 | @cil_ldind_r8 | @cil_ldind_ref | @cil_ldind_u1 | @cil_ldind_u2 | @cil_ldind_u4; + +@cil_stind = @cil_stind_i | @cil_stind_i1 | @cil_stind_i2 | @cil_stind_i4 | @cil_stind_i8 | + @cil_stind_r4 | @cil_stind_r8 | @cil_stind_ref; + +@cil_bitwise_operation = @cil_binary_bitwise_operation | @cil_unary_bitwise_operation; + +@cil_binary_bitwise_operation = @cil_and | @cil_or | @cil_xor | @cil_shr | @cil_shr | @cil_shr_un | @cil_shl; + +@cil_binary_arithmetic_operation = @cil_add | @cil_sub | @cil_mul | @cil_div | @cil_div_un | + @cil_rem | @cil_rem_un | @cil_add_ovf | @cil_add_ovf_un | @cil_mul_ovf | @cil_mul_ovf_un | + @cil_sub_ovf | @cil_sub_ovf_un; + +@cil_unary_bitwise_operation = @cil_not; + +@cil_binary_expr = @cil_binary_arithmetic_operation | @cil_binary_bitwise_operation | @cil_read_array | @cil_comparison_operation; + +@cil_unary_arithmetic_operation = @cil_neg; + +@cil_comparison_operation = @cil_cgt_un | @cil_ceq | @cil_cgt | @cil_clt | @cil_clt_un; + +// Elements that retrieve an address of something +@cil_read_ref = @cil_ldloca_s | @cil_ldarga_s | @cil_ldflda | @cil_ldsflda | @cil_ldelema; + +// CIL array instructions + +@cil_read_array = + @cil_ldelem | @cil_ldelema | @cil_ldelem_i1 | @cil_ldelem_ref | @cil_ldelem_i | + @cil_ldelem_i1 | @cil_ldelem_i2 | @cil_ldelem_i4 | @cil_ldelem_i8 | @cil_ldelem_r4 | + @cil_ldelem_r8 | @cil_ldelem_u1 | @cil_ldelem_u2 | @cil_ldelem_u4; + +@cil_write_array = @cil_stelem | @cil_stelem_ref | + @cil_stelem_i | @cil_stelem_i1 | @cil_stelem_i2 | @cil_stelem_i4 | @cil_stelem_i8 | + @cil_stelem_r4 | @cil_stelem_r8; + +@cil_throw_any = @cil_throw | @cil_rethrow; + +#keyset[impl, index] +cil_instruction( + unique int id: @cil_instruction, + int opcode: int ref, + int index: int ref, + int impl: @cil_method_implementation ref); + +cil_jump( + unique int instruction: @cil_jump ref, + int target: @cil_instruction ref); + +cil_access( + unique int instruction: @cil_instruction ref, + int target: @cil_accessible ref); + +cil_value( + unique int instruction: @cil_literal ref, + string value: string ref); + +#keyset[instruction, index] +cil_switch( + int instruction: @cil_switch ref, + int index: int ref, + int target: @cil_instruction ref); + +cil_instruction_location( + unique int id: @cil_instruction ref, + int loc: @location ref); + +cil_type_location( + int id: @cil_type ref, + int loc: @location ref); + +cil_method_location( + int id: @cil_method ref, + int loc: @location ref); + +@cil_namespace = @namespace; + +@cil_type_container = @cil_type | @cil_namespace | @cil_method; + +case @cil_type.kind of + 0 = @cil_valueorreftype +| 1 = @cil_typeparameter +| 2 = @cil_array_type +| 3 = @cil_pointer_type +| 4 = @cil_function_pointer_type +; + +cil_type( + unique int id: @cil_type, + string name: string ref, + int kind: int ref, + int parent: @cil_type_container ref, + int sourceDecl: @cil_type ref); + +cil_pointer_type( + unique int id: @cil_pointer_type ref, + int pointee: @cil_type ref); + +cil_array_type( + unique int id: @cil_array_type ref, + int element_type: @cil_type ref, + int rank: int ref); + +cil_function_pointer_return_type( + unique int id: @cil_function_pointer_type ref, + int return_type: @cil_type ref); + +cil_method( + unique int id: @cil_method, + string name: string ref, + int parent: @cil_type ref, + int return_type: @cil_type ref); + +cil_method_source_declaration( + unique int method: @cil_method ref, + int source: @cil_method ref); + +cil_method_implementation( + unique int id: @cil_method_implementation, + int method: @cil_method ref, + int location: @assembly ref); + +cil_implements( + int id: @cil_method ref, + int decl: @cil_method ref); + +#keyset[parent, name] +cil_field( + unique int id: @cil_field, + int parent: @cil_type ref, + string name: string ref, + int field_type: @cil_type ref); + +@cil_element = @cil_instruction | @cil_declaration | @cil_handler | @cil_attribute | @cil_namespace; +@cil_named_element = @cil_declaration | @cil_namespace; +@cil_declaration = @cil_variable | @cil_method | @cil_type | @cil_member; +@cil_accessible = @cil_declaration; +@cil_variable = @cil_field | @cil_stack_variable; +@cil_stack_variable = @cil_local_variable | @cil_parameter; +@cil_member = @cil_method | @cil_type | @cil_field | @cil_property | @cil_event; +@cil_custom_modifier_receiver = @cil_method | @cil_property | @cil_parameter | @cil_field | @cil_function_pointer_type; +@cil_parameterizable = @cil_method | @cil_function_pointer_type; +@cil_has_type_annotation = @cil_stack_variable | @cil_property | @cil_field | @cil_method | @cil_function_pointer_type; + +#keyset[parameterizable, index] +cil_parameter( + unique int id: @cil_parameter, + int parameterizable: @cil_parameterizable ref, + int index: int ref, + int param_type: @cil_type ref); + +cil_parameter_in(unique int id: @cil_parameter ref); +cil_parameter_out(unique int id: @cil_parameter ref); + +cil_setter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +#keyset[id, modifier] +cil_custom_modifiers( + int id: @cil_custom_modifier_receiver ref, + int modifier: @cil_type ref, + int kind: int ref); // modreq: 1, modopt: 0 + +cil_type_annotation( + int id: @cil_has_type_annotation ref, + int annotation: int ref); + +cil_getter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_adder(unique int event: @cil_event ref, + int method: @cil_method ref); + +cil_remover(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_raiser(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_property( + unique int id: @cil_property, + int parent: @cil_type ref, + string name: string ref, + int property_type: @cil_type ref); + +#keyset[parent, name] +cil_event(unique int id: @cil_event, + int parent: @cil_type ref, + string name: string ref, + int event_type: @cil_type ref); + +#keyset[impl, index] +cil_local_variable( + unique int id: @cil_local_variable, + int impl: @cil_method_implementation ref, + int index: int ref, + int var_type: @cil_type ref); + +cil_function_pointer_calling_conventions( + int id: @cil_function_pointer_type ref, + int kind: int ref); + +// CIL handlers (exception handlers etc). + +case @cil_handler.kind of + 0 = @cil_catch_handler +| 1 = @cil_filter_handler +| 2 = @cil_finally_handler +| 4 = @cil_fault_handler +; + +#keyset[impl, index] +cil_handler( + unique int id: @cil_handler, + int impl: @cil_method_implementation ref, + int index: int ref, + int kind: int ref, + int try_start: @cil_instruction ref, + int try_end: @cil_instruction ref, + int handler_start: @cil_instruction ref); + +cil_handler_filter( + unique int id: @cil_handler ref, + int filter_start: @cil_instruction ref); + +cil_handler_type( + unique int id: @cil_handler ref, + int catch_type: @cil_type ref); + +@cil_controlflow_node = @cil_entry_point | @cil_instruction; + +@cil_entry_point = @cil_method_implementation | @cil_handler; + +@cil_dataflow_node = @cil_instruction | @cil_variable | @cil_method; + +cil_method_stack_size( + unique int method: @cil_method_implementation ref, + int size: int ref); + +// CIL modifiers + +cil_public(int id: @cil_member ref); +cil_private(int id: @cil_member ref); +cil_protected(int id: @cil_member ref); +cil_internal(int id: @cil_member ref); +cil_static(int id: @cil_member ref); +cil_sealed(int id: @cil_member ref); +cil_virtual(int id: @cil_method ref); +cil_abstract(int id: @cil_member ref); +cil_class(int id: @cil_type ref); +cil_interface(int id: @cil_type ref); +cil_security(int id: @cil_member ref); +cil_requiresecobject(int id: @cil_method ref); +cil_specialname(int id: @cil_method ref); +cil_newslot(int id: @cil_method ref); + +cil_base_class(unique int id: @cil_type ref, int base: @cil_type ref); +cil_base_interface(int id: @cil_type ref, int base: @cil_type ref); +cil_enum_underlying_type(unique int id: @cil_type ref, int underlying: @cil_type ref); + +#keyset[unbound, index] +cil_type_parameter( + int unbound: @cil_member ref, + int index: int ref, + int param: @cil_typeparameter ref); + +#keyset[bound, index] +cil_type_argument( + int bound: @cil_member ref, + int index: int ref, + int t: @cil_type ref); + +// CIL type parameter constraints + +cil_typeparam_covariant(int tp: @cil_typeparameter ref); +cil_typeparam_contravariant(int tp: @cil_typeparameter ref); +cil_typeparam_class(int tp: @cil_typeparameter ref); +cil_typeparam_struct(int tp: @cil_typeparameter ref); +cil_typeparam_new(int tp: @cil_typeparameter ref); +cil_typeparam_constraint(int tp: @cil_typeparameter ref, int supertype: @cil_type ref); + +// CIL attributes + +cil_attribute( + unique int attributeid: @cil_attribute, + int element: @cil_declaration ref, + int constructor: @cil_method ref); + +#keyset[attribute_id, param] +cil_attribute_named_argument( + int attribute_id: @cil_attribute ref, + string param: string ref, + string value: string ref); + +#keyset[attribute_id, index] +cil_attribute_positional_argument( + int attribute_id: @cil_attribute ref, + int index: int ref, + string value: string ref); + + +// Common .Net data model covering both C# and CIL + +// Common elements +@dotnet_element = @element | @cil_element; +@dotnet_named_element = @named_element | @cil_named_element; +@dotnet_callable = @callable | @cil_method; +@dotnet_variable = @variable | @cil_variable; +@dotnet_field = @field | @cil_field; +@dotnet_parameter = @parameter | @cil_parameter; +@dotnet_declaration = @declaration | @cil_declaration; +@dotnet_member = @member | @cil_member; +@dotnet_event = @event | @cil_event; +@dotnet_property = @property | @cil_property | @indexer; +@dotnet_parameterizable = @parameterizable | @cil_parameterizable; + +// Common types +@dotnet_type = @type | @cil_type; +@dotnet_call = @call | @cil_call_any; +@dotnet_throw = @throw_element | @cil_throw_any; +@dotnet_valueorreftype = @cil_valueorreftype | @value_or_ref_type | @cil_array_type | @void_type; +@dotnet_typeparameter = @type_parameter | @cil_typeparameter; +@dotnet_array_type = @array_type | @cil_array_type; +@dotnet_pointer_type = @pointer_type | @cil_pointer_type; +@dotnet_type_parameter = @type_parameter | @cil_typeparameter; +@dotnet_generic = @dotnet_valueorreftype | @dotnet_callable; + +// Attributes +@dotnet_attribute = @attribute | @cil_attribute; + +// Expressions +@dotnet_expr = @expr | @cil_expr; + +// Literals +@dotnet_literal = @literal_expr | @cil_literal; +@dotnet_string_literal = @string_literal_expr | @cil_ldstr; +@dotnet_int_literal = @integer_literal_expr | @cil_ldc_i; +@dotnet_float_literal = @float_literal_expr | @cil_ldc_r; +@dotnet_null_literal = @null_literal_expr | @cil_ldnull; + +@metadata_entity = @cil_method | @cil_type | @cil_field | @cil_property | @field | @property | + @callable | @value_or_ref_type | @void_type; + +metadata_handle(int entity : @metadata_entity ref, int location: @assembly ref, int handle: int ref) diff --git a/csharp/downgrades/c9ee11bd1ee96e925a35cedff000be924634447f/upgrade.properties b/csharp/downgrades/c9ee11bd1ee96e925a35cedff000be924634447f/upgrade.properties new file mode 100644 index 00000000000..580afc7c736 --- /dev/null +++ b/csharp/downgrades/c9ee11bd1ee96e925a35cedff000be924634447f/upgrade.properties @@ -0,0 +1,3 @@ +description: Remove `compilation_info`. +compatibility: backwards +compilation_info.rel: delete diff --git a/csharp/ql/lib/upgrades/f145a9a7275c8f457b392b2ebc9f8e07960a0ed2/old.dbscheme b/csharp/ql/lib/upgrades/f145a9a7275c8f457b392b2ebc9f8e07960a0ed2/old.dbscheme new file mode 100644 index 00000000000..f145a9a7275 --- /dev/null +++ b/csharp/ql/lib/upgrades/f145a9a7275c8f457b392b2ebc9f8e07960a0ed2/old.dbscheme @@ -0,0 +1,2094 @@ +/* This is a dummy line to alter the dbscheme, so we can make a database upgrade + * without actually changing any of the dbscheme predicates. It contains a date + * to allow for such updates in the future as well. + * + * 2021-07-14 + * + * DO NOT remove this comment carelessly, since it can revert the dbscheme back to a + * previously seen state (matching a previously seen SHA), which would make the upgrade + * mechanism not work properly. + */ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * csc f1.cs f2.cs f3.cs + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | --compiler + * 1 | *path to compiler* + * 2 | f1.cs + * 3 | f2.cs + * 4 | f3.cs + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The expanded arguments that were passed to the extractor for a + * compiler invocation. This is similar to `compilation_args`, but + * for a `@someFile.rsp` argument, it includes the arguments from that + * file, rather than just taking the argument literally. + */ +#keyset[id, num] +compilation_expanded_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.cs + * 1 | f2.cs + * 2 | f3.cs + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The references used by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs /r:ref1.dll /r:ref2.dll /r:ref3.dll + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | ref1.dll + * 1 | ref2.dll + * 2 | ref3.dll + */ +#keyset[id, num] +compilation_referencing_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location ref +); + +extractor_messages( + unique int id: @extractor_message, + int severity: int ref, + string origin : string ref, + string text : string ref, + string entity : string ref, + int location: @location ref, + string stack_trace : string ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +compilation_assembly( + unique int id : @compilation ref, + int assembly: @assembly ref +) + +// Populated by the CSV extractor +externalData( + int id: @externalDataElement, + string path: string ref, + int column: int ref, + string value: string ref); + +sourceLocationPrefix( + string prefix: string ref); + +/* + * C# dbscheme + */ + +/** ELEMENTS **/ + +@element = @declaration | @stmt | @expr | @modifier | @attribute | @namespace_declaration + | @using_directive | @type_parameter_constraints | @externalDataElement + | @xmllocatable | @asp_element | @namespace | @preprocessor_directive; + +@declaration = @callable | @generic | @assignable | @namespace; + +@named_element = @namespace | @declaration; + +@declaration_with_accessors = @property | @indexer | @event; + +@assignable = @variable | @assignable_with_accessors | @event; + +@assignable_with_accessors = @property | @indexer; + +@attributable = @assembly | @field | @parameter | @operator | @method | @constructor + | @destructor | @callable_accessor | @value_or_ref_type | @declaration_with_accessors + | @local_function | @lambda_expr; + +/** LOCATIONS, ASEMMBLIES, MODULES, FILES and FOLDERS **/ + +@location = @location_default | @assembly; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +locations_mapped( + unique int id: @location_default ref, + int mapped_to: @location_default ref); + +@sourceline = @file | @callable | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref); + +assemblies( + unique int id: @assembly, + int file: @file ref, + string fullname: string ref, + string name: string ref, + string version: string ref); + +files( + unique int id: @file, + string name: string ref); + +folders( + unique int id: @folder, + string name: string ref); + +@container = @folder | @file ; + +containerparent( + int parent: @container ref, + unique int child: @container ref); + +file_extraction_mode( + unique int file: @file ref, + int mode: int ref + /* 0 = normal, 1 = standalone extractor */ + ); + +/** NAMESPACES **/ + +@type_container = @namespace | @type; + +namespaces( + unique int id: @namespace, + string name: string ref); + +namespace_declarations( + unique int id: @namespace_declaration, + int namespace_id: @namespace ref); + +namespace_declaration_location( + unique int id: @namespace_declaration ref, + int loc: @location ref); + +parent_namespace( + unique int child_id: @type_container ref, + int namespace_id: @namespace ref); + +@declaration_or_directive = @namespace_declaration | @type | @using_directive; + +parent_namespace_declaration( + int child_id: @declaration_or_directive ref, // cannot be unique because of partial classes + int namespace_id: @namespace_declaration ref); + +@using_directive = @using_namespace_directive | @using_static_directive; + +using_global( + unique int id: @using_directive ref +); + +using_namespace_directives( + unique int id: @using_namespace_directive, + int namespace_id: @namespace ref); + +using_static_directives( + unique int id: @using_static_directive, + int type_id: @type_or_ref ref); + +using_directive_location( + unique int id: @using_directive ref, + int loc: @location ref); + +@preprocessor_directive = @pragma_warning | @pragma_checksum | @directive_define | @directive_undefine | @directive_warning + | @directive_error | @directive_nullable | @directive_line | @directive_region | @directive_endregion | @directive_if + | @directive_elif | @directive_else | @directive_endif; + +@conditional_directive = @directive_if | @directive_elif; +@branch_directive = @directive_if | @directive_elif | @directive_else; + +directive_ifs( + unique int id: @directive_if, + int branchTaken: int ref, /* 0: false, 1: true */ + int conditionValue: int ref); /* 0: false, 1: true */ + +directive_elifs( + unique int id: @directive_elif, + int branchTaken: int ref, /* 0: false, 1: true */ + int conditionValue: int ref, /* 0: false, 1: true */ + int parent: @directive_if ref, + int index: int ref); + +directive_elses( + unique int id: @directive_else, + int branchTaken: int ref, /* 0: false, 1: true */ + int parent: @directive_if ref, + int index: int ref); + +#keyset[id, start] +directive_endifs( + unique int id: @directive_endif, + unique int start: @directive_if ref); + +directive_define_symbols( + unique int id: @define_symbol_expr ref, + string name: string ref); + +directive_regions( + unique int id: @directive_region, + string name: string ref); + +#keyset[id, start] +directive_endregions( + unique int id: @directive_endregion, + unique int start: @directive_region ref); + +directive_lines( + unique int id: @directive_line, + int kind: int ref); /* 0: default, 1: hidden, 2: numeric, 3: span */ + +directive_line_value( + unique int id: @directive_line ref, + int line: int ref); + +directive_line_file( + unique int id: @directive_line ref, + int file: @file ref); + +directive_line_offset( + unique int id: @directive_line ref, + int offset: int ref); + +directive_line_span( + unique int id: @directive_line ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +directive_nullables( + unique int id: @directive_nullable, + int setting: int ref, /* 0: disable, 1: enable, 2: restore */ + int target: int ref); /* 0: none, 1: annotations, 2: warnings */ + +directive_warnings( + unique int id: @directive_warning, + string message: string ref); + +directive_errors( + unique int id: @directive_error, + string message: string ref); + +directive_undefines( + unique int id: @directive_undefine, + string name: string ref); + +directive_defines( + unique int id: @directive_define, + string name: string ref); + +pragma_checksums( + unique int id: @pragma_checksum, + int file: @file ref, + string guid: string ref, + string bytes: string ref); + +pragma_warnings( + unique int id: @pragma_warning, + int kind: int ref /* 0 = disable, 1 = restore */); + +#keyset[id, index] +pragma_warning_error_codes( + int id: @pragma_warning ref, + string errorCode: string ref, + int index: int ref); + +preprocessor_directive_location( + unique int id: @preprocessor_directive ref, + int loc: @location ref); + +preprocessor_directive_compilation( + unique int id: @preprocessor_directive ref, + int compilation: @compilation ref); + +preprocessor_directive_active( + unique int id: @preprocessor_directive ref, + int active: int ref); /* 0: false, 1: true */ + +/** TYPES **/ + +types( + unique int id: @type, + int kind: int ref, + string name: string ref); + +case @type.kind of + 1 = @bool_type +| 2 = @char_type +| 3 = @decimal_type +| 4 = @sbyte_type +| 5 = @short_type +| 6 = @int_type +| 7 = @long_type +| 8 = @byte_type +| 9 = @ushort_type +| 10 = @uint_type +| 11 = @ulong_type +| 12 = @float_type +| 13 = @double_type +| 14 = @enum_type +| 15 = @struct_type +| 17 = @class_type +| 19 = @interface_type +| 20 = @delegate_type +| 21 = @null_type +| 22 = @type_parameter +| 23 = @pointer_type +| 24 = @nullable_type +| 25 = @array_type +| 26 = @void_type +| 27 = @int_ptr_type +| 28 = @uint_ptr_type +| 29 = @dynamic_type +| 30 = @arglist_type +| 31 = @unknown_type +| 32 = @tuple_type +| 33 = @function_pointer_type +| 34 = @inline_array_type + ; + +@simple_type = @bool_type | @char_type | @integral_type | @floating_point_type | @decimal_type; +@integral_type = @signed_integral_type | @unsigned_integral_type; +@signed_integral_type = @sbyte_type | @short_type | @int_type | @long_type; +@unsigned_integral_type = @byte_type | @ushort_type | @uint_type | @ulong_type; +@floating_point_type = @float_type | @double_type; +@value_type = @simple_type | @enum_type | @struct_type | @nullable_type | @int_ptr_type + | @uint_ptr_type | @tuple_type | @void_type | @inline_array_type; +@ref_type = @class_type | @interface_type | @array_type | @delegate_type | @null_type + | @dynamic_type; +@value_or_ref_type = @value_type | @ref_type; + +typerefs( + unique int id: @typeref, + string name: string ref); + +typeref_type( + int id: @typeref ref, + unique int typeId: @type ref); + +@type_or_ref = @type | @typeref; + +array_element_type( + unique int array: @array_type ref, + int dimension: int ref, + int rank: int ref, + int element: @type_or_ref ref); + +nullable_underlying_type( + unique int nullable: @nullable_type ref, + int underlying: @type_or_ref ref); + +pointer_referent_type( + unique int pointer: @pointer_type ref, + int referent: @type_or_ref ref); + +enum_underlying_type( + unique int enum_id: @enum_type ref, + int underlying_type_id: @type_or_ref ref); + +delegate_return_type( + unique int delegate_id: @delegate_type ref, + int return_type_id: @type_or_ref ref); + +function_pointer_return_type( + unique int function_pointer_id: @function_pointer_type ref, + int return_type_id: @type_or_ref ref); + +extend( + int sub: @type ref, + int super: @type_or_ref ref); + +anonymous_types( + unique int id: @type ref); + +@interface_or_ref = @interface_type | @typeref; + +implement( + int sub: @type ref, + int super: @type_or_ref ref); + +type_location( + int id: @type ref, + int loc: @location ref); + +tuple_underlying_type( + unique int tuple: @tuple_type ref, + int struct: @type_or_ref ref); + +#keyset[tuple, index] +tuple_element( + int tuple: @tuple_type ref, + int index: int ref, + unique int field: @field ref); + +attributes( + unique int id: @attribute, + int kind: int ref, + int type_id: @type_or_ref ref, + int target: @attributable ref); + +case @attribute.kind of + 0 = @attribute_default +| 1 = @attribute_return +| 2 = @attribute_assembly +| 3 = @attribute_module +; + +attribute_location( + int id: @attribute ref, + int loc: @location ref); + +@type_mention_parent = @element | @type_mention; + +type_mention( + unique int id: @type_mention, + int type_id: @type_or_ref ref, + int parent: @type_mention_parent ref); + +type_mention_location( + unique int id: @type_mention ref, + int loc: @location ref); + +@has_type_annotation = @assignable | @type_parameter | @callable | @expr | @delegate_type | @generic | @function_pointer_type; + +/** + * A direct annotation on an entity, for example `string? x;`. + * + * Annotations: + * 2 = reftype is not annotated "!" + * 3 = reftype is annotated "?" + * 4 = readonly ref type / in parameter + * 5 = ref type parameter, return or local variable + * 6 = out parameter + * + * Note that the annotation depends on the element it annotates. + * @assignable: The annotation is on the type of the assignable, for example the variable type. + * @type_parameter: The annotation is on the reftype constraint + * @callable: The annotation is on the return type + * @array_type: The annotation is on the element type + */ +type_annotation(int id: @has_type_annotation ref, int annotation: int ref); + +nullability(unique int nullability: @nullability, int kind: int ref); + +case @nullability.kind of + 0 = @oblivious +| 1 = @not_annotated +| 2 = @annotated +; + +#keyset[parent, index] +nullability_parent(int nullability: @nullability ref, int index: int ref, int parent: @nullability ref) + +type_nullability(int id: @has_type_annotation ref, int nullability: @nullability ref); + +/** + * The nullable flow state of an expression, as determined by Roslyn. + * 0 = none (default, not populated) + * 1 = not null + * 2 = maybe null + */ +expr_flowstate(unique int id: @expr ref, int state: int ref); + +/** GENERICS **/ + +@generic = @type | @method | @local_function; + +type_parameters( + unique int id: @type_parameter ref, + int index: int ref, + int generic_id: @generic ref, + int variance: int ref /* none = 0, out = 1, in = 2 */); + +#keyset[constructed_id, index] +type_arguments( + int id: @type_or_ref ref, + int index: int ref, + int constructed_id: @generic_or_ref ref); + +@generic_or_ref = @generic | @typeref; + +constructed_generic( + unique int constructed: @generic ref, + int generic: @generic_or_ref ref); + +type_parameter_constraints( + unique int id: @type_parameter_constraints, + int param_id: @type_parameter ref); + +type_parameter_constraints_location( + int id: @type_parameter_constraints ref, + int loc: @location ref); + +general_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int kind: int ref /* class = 1, struct = 2, new = 3 */); + +specific_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref); + +specific_type_parameter_nullability( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref, + int nullability: @nullability ref); + +/** FUNCTION POINTERS */ + +function_pointer_calling_conventions( + int id: @function_pointer_type ref, + int kind: int ref); + +#keyset[id, index] +has_unmanaged_calling_conventions( + int id: @function_pointer_type ref, + int index: int ref, + int conv_id: @type_or_ref ref); + +/** MODIFIERS */ + +@modifiable = @modifiable_direct | @event_accessor; + +@modifiable_direct = @member | @accessor | @local_function | @anonymous_function_expr; + +modifiers( + unique int id: @modifier, + string name: string ref); + +has_modifiers( + int id: @modifiable_direct ref, + int mod_id: @modifier ref); + +compiler_generated(unique int id: @modifiable ref); + +/** MEMBERS **/ + +@member = @method | @constructor | @destructor | @field | @property | @event | @operator | @indexer | @type; + +@named_exprorstmt = @goto_stmt | @labeled_stmt | @expr; + +@virtualizable = @method | @property | @indexer | @event | @operator; + +exprorstmt_name( + unique int parent_id: @named_exprorstmt ref, + string name: string ref); + +nested_types( + unique int id: @type ref, + int declaring_type_id: @type ref, + int unbound_id: @type ref); + +properties( + unique int id: @property, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @property ref); + +property_location( + int id: @property ref, + int loc: @location ref); + +indexers( + unique int id: @indexer, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @indexer ref); + +indexer_location( + int id: @indexer ref, + int loc: @location ref); + +accessors( + unique int id: @accessor, + int kind: int ref, + string name: string ref, + int declaring_member_id: @member ref, + int unbound_id: @accessor ref); + +case @accessor.kind of + 1 = @getter +| 2 = @setter + ; + +init_only_accessors( + unique int id: @accessor ref); + +accessor_location( + int id: @accessor ref, + int loc: @location ref); + +events( + unique int id: @event, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @event ref); + +event_location( + int id: @event ref, + int loc: @location ref); + +event_accessors( + unique int id: @event_accessor, + int kind: int ref, + string name: string ref, + int declaring_event_id: @event ref, + int unbound_id: @event_accessor ref); + +case @event_accessor.kind of + 1 = @add_event_accessor +| 2 = @remove_event_accessor + ; + +event_accessor_location( + int id: @event_accessor ref, + int loc: @location ref); + +operators( + unique int id: @operator, + string name: string ref, + string symbol: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @operator ref); + +operator_location( + int id: @operator ref, + int loc: @location ref); + +constant_value( + int id: @variable ref, + string value: string ref); + +/** CALLABLES **/ + +@callable = @method | @constructor | @destructor | @operator | @callable_accessor | @anonymous_function_expr | @local_function; + +@callable_accessor = @accessor | @event_accessor; + +methods( + unique int id: @method, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @method ref); + +method_location( + int id: @method ref, + int loc: @location ref); + +constructors( + unique int id: @constructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @constructor ref); + +constructor_location( + int id: @constructor ref, + int loc: @location ref); + +destructors( + unique int id: @destructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @destructor ref); + +destructor_location( + int id: @destructor ref, + int loc: @location ref); + +overrides( + int id: @callable ref, + int base_id: @callable ref); + +explicitly_implements( + int id: @member ref, + int interface_id: @interface_or_ref ref); + +local_functions( + unique int id: @local_function, + string name: string ref, + int return_type: @type ref, + int unbound_id: @local_function ref); + +local_function_stmts( + unique int fn: @local_function_stmt ref, + int stmt: @local_function ref); + +/** VARIABLES **/ + +@variable = @local_scope_variable | @field; + +@local_scope_variable = @local_variable | @parameter; + +fields( + unique int id: @field, + int kind: int ref, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @field ref); + +case @field.kind of + 1 = @addressable_field +| 2 = @constant + ; + +field_location( + int id: @field ref, + int loc: @location ref); + +localvars( + unique int id: @local_variable, + int kind: int ref, + string name: string ref, + int implicitly_typed: int ref /* 0 = no, 1 = yes */, + int type_id: @type_or_ref ref, + int parent_id: @local_var_decl_expr ref); + +case @local_variable.kind of + 1 = @addressable_local_variable +| 2 = @local_constant +| 3 = @local_variable_ref + ; + +localvar_location( + unique int id: @local_variable ref, + int loc: @location ref); + +@parameterizable = @callable | @delegate_type | @indexer | @function_pointer_type; + +#keyset[name, parent_id] +#keyset[index, parent_id] +params( + unique int id: @parameter, + string name: string ref, + int type_id: @type_or_ref ref, + int index: int ref, + int mode: int ref, /* value = 0, ref = 1, out = 2, array = 3, this = 4 */ + int parent_id: @parameterizable ref, + int unbound_id: @parameter ref); + +param_location( + int id: @parameter ref, + int loc: @location ref); + +@has_scoped_annotation = @local_scope_variable + +scoped_annotation( + int id: @has_scoped_annotation ref, + int kind: int ref // scoped ref = 1, scoped value = 2 + ); + +/** STATEMENTS **/ + +@exprorstmt_parent = @control_flow_element | @top_level_exprorstmt_parent; + +statements( + unique int id: @stmt, + int kind: int ref); + +#keyset[index, parent] +stmt_parent( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_stmt_parent = @callable; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +stmt_parent_top_level( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @top_level_stmt_parent ref); + +case @stmt.kind of + 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @switch_stmt +| 5 = @while_stmt +| 6 = @do_stmt +| 7 = @for_stmt +| 8 = @foreach_stmt +| 9 = @break_stmt +| 10 = @continue_stmt +| 11 = @goto_stmt +| 12 = @goto_case_stmt +| 13 = @goto_default_stmt +| 14 = @throw_stmt +| 15 = @return_stmt +| 16 = @yield_stmt +| 17 = @try_stmt +| 18 = @checked_stmt +| 19 = @unchecked_stmt +| 20 = @lock_stmt +| 21 = @using_block_stmt +| 22 = @var_decl_stmt +| 23 = @const_decl_stmt +| 24 = @empty_stmt +| 25 = @unsafe_stmt +| 26 = @fixed_stmt +| 27 = @label_stmt +| 28 = @catch +| 29 = @case_stmt +| 30 = @local_function_stmt +| 31 = @using_decl_stmt + ; + +@using_stmt = @using_block_stmt | @using_decl_stmt; + +@labeled_stmt = @label_stmt | @case; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @using_decl_stmt; + +@cond_stmt = @if_stmt | @switch_stmt; + +@loop_stmt = @while_stmt | @do_stmt | @for_stmt | @foreach_stmt; + +@jump_stmt = @break_stmt | @goto_any_stmt | @continue_stmt | @throw_stmt | @return_stmt + | @yield_stmt; + +@goto_any_stmt = @goto_default_stmt | @goto_case_stmt | @goto_stmt; + + +stmt_location( + unique int id: @stmt ref, + int loc: @location ref); + +catch_type( + unique int catch_id: @catch ref, + int type_id: @type_or_ref ref, + int kind: int ref /* explicit = 1, implicit = 2 */); + +foreach_stmt_info( + unique int id: @foreach_stmt ref, + int kind: int ref /* non-async = 1, async = 2 */); + +@foreach_symbol = @method | @property | @type_or_ref; + +#keyset[id, kind] +foreach_stmt_desugar( + int id: @foreach_stmt ref, + int symbol: @foreach_symbol ref, + int kind: int ref /* GetEnumeratorMethod = 1, CurrentProperty = 2, MoveNextMethod = 3, DisposeMethod = 4, ElementType = 5 */); + +/** EXPRESSIONS **/ + +expressions( + unique int id: @expr, + int kind: int ref, + int type_id: @type_or_ref ref); + +#keyset[index, parent] +expr_parent( + unique int expr: @expr ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_expr_parent = @attribute | @field | @property | @indexer | @parameter | @directive_if | @directive_elif; + +@top_level_exprorstmt_parent = @top_level_expr_parent | @top_level_stmt_parent; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +expr_parent_top_level( + unique int expr: @expr ref, + int index: int ref, + int parent: @top_level_exprorstmt_parent ref); + +case @expr.kind of +/* literal */ + 1 = @bool_literal_expr +| 2 = @char_literal_expr +| 3 = @decimal_literal_expr +| 4 = @int_literal_expr +| 5 = @long_literal_expr +| 6 = @uint_literal_expr +| 7 = @ulong_literal_expr +| 8 = @float_literal_expr +| 9 = @double_literal_expr +| 10 = @utf16_string_literal_expr +| 11 = @null_literal_expr +/* primary & unary */ +| 12 = @this_access_expr +| 13 = @base_access_expr +| 14 = @local_variable_access_expr +| 15 = @parameter_access_expr +| 16 = @field_access_expr +| 17 = @property_access_expr +| 18 = @method_access_expr +| 19 = @event_access_expr +| 20 = @indexer_access_expr +| 21 = @array_access_expr +| 22 = @type_access_expr +| 23 = @typeof_expr +| 24 = @method_invocation_expr +| 25 = @delegate_invocation_expr +| 26 = @operator_invocation_expr +| 27 = @cast_expr +| 28 = @object_creation_expr +| 29 = @explicit_delegate_creation_expr +| 30 = @implicit_delegate_creation_expr +| 31 = @array_creation_expr +| 32 = @default_expr +| 33 = @plus_expr +| 34 = @minus_expr +| 35 = @bit_not_expr +| 36 = @log_not_expr +| 37 = @post_incr_expr +| 38 = @post_decr_expr +| 39 = @pre_incr_expr +| 40 = @pre_decr_expr +/* multiplicative */ +| 41 = @mul_expr +| 42 = @div_expr +| 43 = @rem_expr +/* additive */ +| 44 = @add_expr +| 45 = @sub_expr +/* shift */ +| 46 = @lshift_expr +| 47 = @rshift_expr +/* relational */ +| 48 = @lt_expr +| 49 = @gt_expr +| 50 = @le_expr +| 51 = @ge_expr +/* equality */ +| 52 = @eq_expr +| 53 = @ne_expr +/* logical */ +| 54 = @bit_and_expr +| 55 = @bit_xor_expr +| 56 = @bit_or_expr +| 57 = @log_and_expr +| 58 = @log_or_expr +/* type testing */ +| 59 = @is_expr +| 60 = @as_expr +/* null coalescing */ +| 61 = @null_coalescing_expr +/* conditional */ +| 62 = @conditional_expr +/* assignment */ +| 63 = @simple_assign_expr +| 64 = @assign_add_expr +| 65 = @assign_sub_expr +| 66 = @assign_mul_expr +| 67 = @assign_div_expr +| 68 = @assign_rem_expr +| 69 = @assign_and_expr +| 70 = @assign_xor_expr +| 71 = @assign_or_expr +| 72 = @assign_lshift_expr +| 73 = @assign_rshift_expr +/* more */ +| 74 = @object_init_expr +| 75 = @collection_init_expr +| 76 = @array_init_expr +| 77 = @checked_expr +| 78 = @unchecked_expr +| 79 = @constructor_init_expr +| 80 = @add_event_expr +| 81 = @remove_event_expr +| 82 = @par_expr +| 83 = @local_var_decl_expr +| 84 = @lambda_expr +| 85 = @anonymous_method_expr +| 86 = @namespace_expr +/* dynamic */ +| 92 = @dynamic_element_access_expr +| 93 = @dynamic_member_access_expr +/* unsafe */ +| 100 = @pointer_indirection_expr +| 101 = @address_of_expr +| 102 = @sizeof_expr +/* async */ +| 103 = @await_expr +/* C# 6.0 */ +| 104 = @nameof_expr +| 105 = @interpolated_string_expr +| 106 = @unknown_expr +/* C# 7.0 */ +| 107 = @throw_expr +| 108 = @tuple_expr +| 109 = @local_function_invocation_expr +| 110 = @ref_expr +| 111 = @discard_expr +/* C# 8.0 */ +| 112 = @range_expr +| 113 = @index_expr +| 114 = @switch_expr +| 115 = @recursive_pattern_expr +| 116 = @property_pattern_expr +| 117 = @positional_pattern_expr +| 118 = @switch_case_expr +| 119 = @assign_coalesce_expr +| 120 = @suppress_nullable_warning_expr +| 121 = @namespace_access_expr +/* C# 9.0 */ +| 122 = @lt_pattern_expr +| 123 = @gt_pattern_expr +| 124 = @le_pattern_expr +| 125 = @ge_pattern_expr +| 126 = @not_pattern_expr +| 127 = @and_pattern_expr +| 128 = @or_pattern_expr +| 129 = @function_pointer_invocation_expr +| 130 = @with_expr +/* C# 11.0 */ +| 131 = @list_pattern_expr +| 132 = @slice_pattern_expr +| 133 = @urshift_expr +| 134 = @assign_urshift_expr +| 135 = @utf8_string_literal_expr +/* C# 12.0 */ +| 136 = @collection_expr +| 137 = @spread_element_expr +/* Preprocessor */ +| 999 = @define_symbol_expr +; + +@switch = @switch_stmt | @switch_expr; +@case = @case_stmt | @switch_case_expr; +@pattern_match = @case | @is_expr; +@unary_pattern_expr = @not_pattern_expr; +@relational_pattern_expr = @gt_pattern_expr | @lt_pattern_expr | @ge_pattern_expr | @le_pattern_expr; +@binary_pattern_expr = @and_pattern_expr | @or_pattern_expr; + +@integer_literal_expr = @int_literal_expr | @long_literal_expr | @uint_literal_expr | @ulong_literal_expr; +@real_literal_expr = @float_literal_expr | @double_literal_expr | @decimal_literal_expr; +@string_literal_expr = @utf16_string_literal_expr | @utf8_string_literal_expr; +@literal_expr = @bool_literal_expr | @char_literal_expr | @integer_literal_expr | @real_literal_expr + | @string_literal_expr | @null_literal_expr; + +@assign_expr = @simple_assign_expr | @assign_op_expr | @local_var_decl_expr; +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr | @assign_event_expr | @assign_coalesce_expr; +@assign_event_expr = @add_event_expr | @remove_event_expr; + +@assign_arith_expr = @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr + | @assign_rem_expr +@assign_bitwise_expr = @assign_and_expr | @assign_or_expr | @assign_xor_expr + | @assign_lshift_expr | @assign_rshift_expr | @assign_urshift_expr; + +@member_access_expr = @field_access_expr | @property_access_expr | @indexer_access_expr | @event_access_expr + | @method_access_expr | @type_access_expr | @dynamic_member_access_expr; +@access_expr = @member_access_expr | @this_access_expr | @base_access_expr | @assignable_access_expr | @namespace_access_expr; +@element_access_expr = @indexer_access_expr | @array_access_expr | @dynamic_element_access_expr; + +@local_variable_access = @local_variable_access_expr | @local_var_decl_expr; +@local_scope_variable_access_expr = @parameter_access_expr | @local_variable_access; +@variable_access_expr = @local_scope_variable_access_expr | @field_access_expr; + +@assignable_access_expr = @variable_access_expr | @property_access_expr | @element_access_expr + | @event_access_expr | @dynamic_member_access_expr; + +@objectorcollection_init_expr = @object_init_expr | @collection_init_expr; + +@delegate_creation_expr = @explicit_delegate_creation_expr | @implicit_delegate_creation_expr; + +@bin_arith_op_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr; +@incr_op_expr = @pre_incr_expr | @post_incr_expr; +@decr_op_expr = @pre_decr_expr | @post_decr_expr; +@mut_op_expr = @incr_op_expr | @decr_op_expr; +@un_arith_op_expr = @plus_expr | @minus_expr | @mut_op_expr; +@arith_op_expr = @bin_arith_op_expr | @un_arith_op_expr; + +@ternary_log_op_expr = @conditional_expr; +@bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr; +@un_log_op_expr = @log_not_expr; +@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr; + +@bin_bit_op_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr + | @rshift_expr | @urshift_expr; +@un_bit_op_expr = @bit_not_expr; +@bit_expr = @un_bit_op_expr | @bin_bit_op_expr; + +@equality_op_expr = @eq_expr | @ne_expr; +@rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr; +@comp_expr = @equality_op_expr | @rel_op_expr; + +@op_expr = @assign_expr | @un_op | @bin_op | @ternary_op; + +@ternary_op = @ternary_log_op_expr; +@bin_op = @bin_arith_op_expr | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr; +@un_op = @un_arith_op_expr | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr + | @pointer_indirection_expr | @address_of_expr; + +@anonymous_function_expr = @lambda_expr | @anonymous_method_expr; + +@call = @method_invocation_expr | @constructor_init_expr | @operator_invocation_expr + | @delegate_invocation_expr | @object_creation_expr | @call_access_expr + | @local_function_invocation_expr | @function_pointer_invocation_expr; + +@call_access_expr = @property_access_expr | @event_access_expr | @indexer_access_expr; + +@late_bindable_expr = @dynamic_element_access_expr | @dynamic_member_access_expr + | @object_creation_expr | @method_invocation_expr | @operator_invocation_expr; + +@throw_element = @throw_expr | @throw_stmt; + +@implicitly_typeable_object_creation_expr = @object_creation_expr | @explicit_delegate_creation_expr; + +implicitly_typed_array_creation( + unique int id: @array_creation_expr ref); + +explicitly_sized_array_creation( + unique int id: @array_creation_expr ref); + +stackalloc_array_creation( + unique int id: @array_creation_expr ref); + +implicitly_typed_object_creation( + unique int id: @implicitly_typeable_object_creation_expr ref); + +mutator_invocation_mode( + unique int id: @operator_invocation_expr ref, + int mode: int ref /* prefix = 1, postfix = 2*/); + +expr_compiler_generated( + unique int id: @expr ref); + +expr_value( + unique int id: @expr ref, + string value: string ref); + +expr_call( + unique int caller_id: @expr ref, + int target_id: @callable ref); + +expr_access( + unique int accesser_id: @access_expr ref, + int target_id: @accessible ref); + +@accessible = @method | @assignable | @local_function | @namespace; + +expr_location( + unique int id: @expr ref, + int loc: @location ref); + +dynamic_member_name( + unique int id: @late_bindable_expr ref, + string name: string ref); + +@qualifiable_expr = @member_access_expr + | @method_invocation_expr + | @element_access_expr; + +conditional_access( + unique int id: @qualifiable_expr ref); + +expr_argument( + unique int id: @expr ref, + int mode: int ref); + /* mode is the same as params: value = 0, ref = 1, out = 2 */ + +expr_argument_name( + unique int id: @expr ref, + string name: string ref); + +lambda_expr_return_type( + unique int id: @lambda_expr ref, + int type_id: @type_or_ref ref); + +/** CONTROL/DATA FLOW **/ + +@control_flow_element = @stmt | @expr; + +/* XML Files */ + +xmlEncoding ( + unique int id: @file ref, + string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* Comments */ + +commentline( + unique int id: @commentline, + int kind: int ref, + string text: string ref, + string rawtext: string ref); + +case @commentline.kind of + 0 = @singlelinecomment +| 1 = @xmldoccomment +| 2 = @multilinecomment; + +commentline_location( + unique int id: @commentline ref, + int loc: @location ref); + +commentblock( + unique int id : @commentblock); + +commentblock_location( + unique int id: @commentblock ref, + int loc: @location ref); + +commentblock_binding( + int id: @commentblock ref, + int entity: @element ref, + int bindtype: int ref); /* 0: Parent, 1: Best, 2: Before, 3: After */ + +commentblock_child( + int id: @commentblock ref, + int commentline: @commentline ref, + int index: int ref); + +/* ASP.NET */ + +case @asp_element.kind of + 0=@asp_close_tag +| 1=@asp_code +| 2=@asp_comment +| 3=@asp_data_binding +| 4=@asp_directive +| 5=@asp_open_tag +| 6=@asp_quoted_string +| 7=@asp_text +| 8=@asp_xml_directive; + +@asp_attribute = @asp_code | @asp_data_binding | @asp_quoted_string; + +asp_elements( + unique int id: @asp_element, + int kind: int ref, + int loc: @location ref); + +asp_comment_server(unique int comment: @asp_comment ref); +asp_code_inline(unique int code: @asp_code ref); +asp_directive_attribute( + int directive: @asp_directive ref, + int index: int ref, + string name: string ref, + int value: @asp_quoted_string ref); +asp_directive_name( + unique int directive: @asp_directive ref, + string name: string ref); +asp_element_body( + unique int element: @asp_element ref, + string body: string ref); +asp_tag_attribute( + int tag: @asp_open_tag ref, + int index: int ref, + string name: string ref, + int attribute: @asp_attribute ref); +asp_tag_name( + unique int tag: @asp_open_tag ref, + string name: string ref); +asp_tag_isempty(int tag: @asp_open_tag ref); + +/* Common Intermediate Language - CIL */ + +case @cil_instruction.opcode of + 0 = @cil_nop +| 1 = @cil_break +| 2 = @cil_ldarg_0 +| 3 = @cil_ldarg_1 +| 4 = @cil_ldarg_2 +| 5 = @cil_ldarg_3 +| 6 = @cil_ldloc_0 +| 7 = @cil_ldloc_1 +| 8 = @cil_ldloc_2 +| 9 = @cil_ldloc_3 +| 10 = @cil_stloc_0 +| 11 = @cil_stloc_1 +| 12 = @cil_stloc_2 +| 13 = @cil_stloc_3 +| 14 = @cil_ldarg_s +| 15 = @cil_ldarga_s +| 16 = @cil_starg_s +| 17 = @cil_ldloc_s +| 18 = @cil_ldloca_s +| 19 = @cil_stloc_s +| 20 = @cil_ldnull +| 21 = @cil_ldc_i4_m1 +| 22 = @cil_ldc_i4_0 +| 23 = @cil_ldc_i4_1 +| 24 = @cil_ldc_i4_2 +| 25 = @cil_ldc_i4_3 +| 26 = @cil_ldc_i4_4 +| 27 = @cil_ldc_i4_5 +| 28 = @cil_ldc_i4_6 +| 29 = @cil_ldc_i4_7 +| 30 = @cil_ldc_i4_8 +| 31 = @cil_ldc_i4_s +| 32 = @cil_ldc_i4 +| 33 = @cil_ldc_i8 +| 34 = @cil_ldc_r4 +| 35 = @cil_ldc_r8 +| 37 = @cil_dup +| 38 = @cil_pop +| 39 = @cil_jmp +| 40 = @cil_call +| 41 = @cil_calli +| 42 = @cil_ret +| 43 = @cil_br_s +| 44 = @cil_brfalse_s +| 45 = @cil_brtrue_s +| 46 = @cil_beq_s +| 47 = @cil_bge_s +| 48 = @cil_bgt_s +| 49 = @cil_ble_s +| 50 = @cil_blt_s +| 51 = @cil_bne_un_s +| 52 = @cil_bge_un_s +| 53 = @cil_bgt_un_s +| 54 = @cil_ble_un_s +| 55 = @cil_blt_un_s +| 56 = @cil_br +| 57 = @cil_brfalse +| 58 = @cil_brtrue +| 59 = @cil_beq +| 60 = @cil_bge +| 61 = @cil_bgt +| 62 = @cil_ble +| 63 = @cil_blt +| 64 = @cil_bne_un +| 65 = @cil_bge_un +| 66 = @cil_bgt_un +| 67 = @cil_ble_un +| 68 = @cil_blt_un +| 69 = @cil_switch +| 70 = @cil_ldind_i1 +| 71 = @cil_ldind_u1 +| 72 = @cil_ldind_i2 +| 73 = @cil_ldind_u2 +| 74 = @cil_ldind_i4 +| 75 = @cil_ldind_u4 +| 76 = @cil_ldind_i8 +| 77 = @cil_ldind_i +| 78 = @cil_ldind_r4 +| 79 = @cil_ldind_r8 +| 80 = @cil_ldind_ref +| 81 = @cil_stind_ref +| 82 = @cil_stind_i1 +| 83 = @cil_stind_i2 +| 84 = @cil_stind_i4 +| 85 = @cil_stind_i8 +| 86 = @cil_stind_r4 +| 87 = @cil_stind_r8 +| 88 = @cil_add +| 89 = @cil_sub +| 90 = @cil_mul +| 91 = @cil_div +| 92 = @cil_div_un +| 93 = @cil_rem +| 94 = @cil_rem_un +| 95 = @cil_and +| 96 = @cil_or +| 97 = @cil_xor +| 98 = @cil_shl +| 99 = @cil_shr +| 100 = @cil_shr_un +| 101 = @cil_neg +| 102 = @cil_not +| 103 = @cil_conv_i1 +| 104 = @cil_conv_i2 +| 105 = @cil_conv_i4 +| 106 = @cil_conv_i8 +| 107 = @cil_conv_r4 +| 108 = @cil_conv_r8 +| 109 = @cil_conv_u4 +| 110 = @cil_conv_u8 +| 111 = @cil_callvirt +| 112 = @cil_cpobj +| 113 = @cil_ldobj +| 114 = @cil_ldstr +| 115 = @cil_newobj +| 116 = @cil_castclass +| 117 = @cil_isinst +| 118 = @cil_conv_r_un +| 121 = @cil_unbox +| 122 = @cil_throw +| 123 = @cil_ldfld +| 124 = @cil_ldflda +| 125 = @cil_stfld +| 126 = @cil_ldsfld +| 127 = @cil_ldsflda +| 128 = @cil_stsfld +| 129 = @cil_stobj +| 130 = @cil_conv_ovf_i1_un +| 131 = @cil_conv_ovf_i2_un +| 132 = @cil_conv_ovf_i4_un +| 133 = @cil_conv_ovf_i8_un +| 134 = @cil_conv_ovf_u1_un +| 135 = @cil_conv_ovf_u2_un +| 136 = @cil_conv_ovf_u4_un +| 137 = @cil_conv_ovf_u8_un +| 138 = @cil_conv_ovf_i_un +| 139 = @cil_conv_ovf_u_un +| 140 = @cil_box +| 141 = @cil_newarr +| 142 = @cil_ldlen +| 143 = @cil_ldelema +| 144 = @cil_ldelem_i1 +| 145 = @cil_ldelem_u1 +| 146 = @cil_ldelem_i2 +| 147 = @cil_ldelem_u2 +| 148 = @cil_ldelem_i4 +| 149 = @cil_ldelem_u4 +| 150 = @cil_ldelem_i8 +| 151 = @cil_ldelem_i +| 152 = @cil_ldelem_r4 +| 153 = @cil_ldelem_r8 +| 154 = @cil_ldelem_ref +| 155 = @cil_stelem_i +| 156 = @cil_stelem_i1 +| 157 = @cil_stelem_i2 +| 158 = @cil_stelem_i4 +| 159 = @cil_stelem_i8 +| 160 = @cil_stelem_r4 +| 161 = @cil_stelem_r8 +| 162 = @cil_stelem_ref +| 163 = @cil_ldelem +| 164 = @cil_stelem +| 165 = @cil_unbox_any +| 179 = @cil_conv_ovf_i1 +| 180 = @cil_conv_ovf_u1 +| 181 = @cil_conv_ovf_i2 +| 182 = @cil_conv_ovf_u2 +| 183 = @cil_conv_ovf_i4 +| 184 = @cil_conv_ovf_u4 +| 185 = @cil_conv_ovf_i8 +| 186 = @cil_conv_ovf_u8 +| 194 = @cil_refanyval +| 195 = @cil_ckinfinite +| 198 = @cil_mkrefany +| 208 = @cil_ldtoken +| 209 = @cil_conv_u2 +| 210 = @cil_conv_u1 +| 211 = @cil_conv_i +| 212 = @cil_conv_ovf_i +| 213 = @cil_conv_ovf_u +| 214 = @cil_add_ovf +| 215 = @cil_add_ovf_un +| 216 = @cil_mul_ovf +| 217 = @cil_mul_ovf_un +| 218 = @cil_sub_ovf +| 219 = @cil_sub_ovf_un +| 220 = @cil_endfinally +| 221 = @cil_leave +| 222 = @cil_leave_s +| 223 = @cil_stind_i +| 224 = @cil_conv_u +| 65024 = @cil_arglist +| 65025 = @cil_ceq +| 65026 = @cil_cgt +| 65027 = @cil_cgt_un +| 65028 = @cil_clt +| 65029 = @cil_clt_un +| 65030 = @cil_ldftn +| 65031 = @cil_ldvirtftn +| 65033 = @cil_ldarg +| 65034 = @cil_ldarga +| 65035 = @cil_starg +| 65036 = @cil_ldloc +| 65037 = @cil_ldloca +| 65038 = @cil_stloc +| 65039 = @cil_localloc +| 65041 = @cil_endfilter +| 65042 = @cil_unaligned +| 65043 = @cil_volatile +| 65044 = @cil_tail +| 65045 = @cil_initobj +| 65046 = @cil_constrained +| 65047 = @cil_cpblk +| 65048 = @cil_initblk +| 65050 = @cil_rethrow +| 65052 = @cil_sizeof +| 65053 = @cil_refanytype +| 65054 = @cil_readonly +; + +// CIL ignored instructions + +@cil_ignore = @cil_nop | @cil_break | @cil_volatile | @cil_unaligned; + +// CIL local/parameter/field access + +@cil_ldarg_any = @cil_ldarg_0 | @cil_ldarg_1 | @cil_ldarg_2 | @cil_ldarg_3 | @cil_ldarg_s | @cil_ldarga_s | @cil_ldarg | @cil_ldarga; +@cil_starg_any = @cil_starg | @cil_starg_s; + +@cil_ldloc_any = @cil_ldloc_0 | @cil_ldloc_1 | @cil_ldloc_2 | @cil_ldloc_3 | @cil_ldloc_s | @cil_ldloca_s | @cil_ldloc | @cil_ldloca; +@cil_stloc_any = @cil_stloc_0 | @cil_stloc_1 | @cil_stloc_2 | @cil_stloc_3 | @cil_stloc_s | @cil_stloc; + +@cil_ldfld_any = @cil_ldfld | @cil_ldsfld | @cil_ldsflda | @cil_ldflda; +@cil_stfld_any = @cil_stfld | @cil_stsfld; + +@cil_local_access = @cil_stloc_any | @cil_ldloc_any; +@cil_arg_access = @cil_starg_any | @cil_ldarg_any; +@cil_read_access = @cil_ldloc_any | @cil_ldarg_any | @cil_ldfld_any; +@cil_write_access = @cil_stloc_any | @cil_starg_any | @cil_stfld_any; + +@cil_stack_access = @cil_local_access | @cil_arg_access; +@cil_field_access = @cil_ldfld_any | @cil_stfld_any; + +@cil_access = @cil_read_access | @cil_write_access; + +// CIL constant/literal instructions + +@cil_ldc_i = @cil_ldc_i4_any | @cil_ldc_i8; + +@cil_ldc_i4_any = @cil_ldc_i4_m1 | @cil_ldc_i4_0 | @cil_ldc_i4_1 | @cil_ldc_i4_2 | @cil_ldc_i4_3 | + @cil_ldc_i4_4 | @cil_ldc_i4_5 | @cil_ldc_i4_6 | @cil_ldc_i4_7 | @cil_ldc_i4_8 | @cil_ldc_i4_s | @cil_ldc_i4; + +@cil_ldc_r = @cil_ldc_r4 | @cil_ldc_r8; + +@cil_literal = @cil_ldnull | @cil_ldc_i | @cil_ldc_r | @cil_ldstr; + +// Control flow + +@cil_conditional_jump = @cil_binary_jump | @cil_unary_jump; +@cil_binary_jump = @cil_beq_s | @cil_bge_s | @cil_bgt_s | @cil_ble_s | @cil_blt_s | + @cil_bne_un_s | @cil_bge_un_s | @cil_bgt_un_s | @cil_ble_un_s | @cil_blt_un_s | + @cil_beq | @cil_bge | @cil_bgt | @cil_ble | @cil_blt | + @cil_bne_un | @cil_bge_un | @cil_bgt_un | @cil_ble_un | @cil_blt_un; +@cil_unary_jump = @cil_brfalse_s | @cil_brtrue_s | @cil_brfalse | @cil_brtrue | @cil_switch; +@cil_unconditional_jump = @cil_br | @cil_br_s | @cil_leave_any; +@cil_leave_any = @cil_leave | @cil_leave_s; +@cil_jump = @cil_unconditional_jump | @cil_conditional_jump; + +// CIL call instructions + +@cil_call_any = @cil_jmp | @cil_call | @cil_calli | @cil_tail | @cil_callvirt | @cil_newobj; + +// CIL expression instructions + +@cil_expr = @cil_literal | @cil_binary_expr | @cil_unary_expr | @cil_call_any | @cil_read_access | + @cil_newarr | @cil_ldtoken | @cil_sizeof | + @cil_ldftn | @cil_ldvirtftn | @cil_localloc | @cil_mkrefany | @cil_refanytype | @cil_arglist | @cil_dup; + +@cil_unary_expr = + @cil_conversion_operation | @cil_unary_arithmetic_operation | @cil_unary_bitwise_operation| + @cil_ldlen | @cil_isinst | @cil_box | @cil_ldobj | @cil_castclass | @cil_unbox_any | + @cil_ldind | @cil_unbox; + +@cil_conversion_operation = + @cil_conv_i1 | @cil_conv_i2 | @cil_conv_i4 | @cil_conv_i8 | + @cil_conv_u1 | @cil_conv_u2 | @cil_conv_u4 | @cil_conv_u8 | + @cil_conv_ovf_i | @cil_conv_ovf_i_un | @cil_conv_ovf_i1 | @cil_conv_ovf_i1_un | + @cil_conv_ovf_i2 | @cil_conv_ovf_i2_un | @cil_conv_ovf_i4 | @cil_conv_ovf_i4_un | + @cil_conv_ovf_i8 | @cil_conv_ovf_i8_un | @cil_conv_ovf_u | @cil_conv_ovf_u_un | + @cil_conv_ovf_u1 | @cil_conv_ovf_u1_un | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_ovf_u4 | @cil_conv_ovf_u4_un | @cil_conv_ovf_u8 | @cil_conv_ovf_u8_un | + @cil_conv_r4 | @cil_conv_r8 | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_i | @cil_conv_u | @cil_conv_r_un; + +@cil_ldind = @cil_ldind_i | @cil_ldind_i1 | @cil_ldind_i2 | @cil_ldind_i4 | @cil_ldind_i8 | + @cil_ldind_r4 | @cil_ldind_r8 | @cil_ldind_ref | @cil_ldind_u1 | @cil_ldind_u2 | @cil_ldind_u4; + +@cil_stind = @cil_stind_i | @cil_stind_i1 | @cil_stind_i2 | @cil_stind_i4 | @cil_stind_i8 | + @cil_stind_r4 | @cil_stind_r8 | @cil_stind_ref; + +@cil_bitwise_operation = @cil_binary_bitwise_operation | @cil_unary_bitwise_operation; + +@cil_binary_bitwise_operation = @cil_and | @cil_or | @cil_xor | @cil_shr | @cil_shr | @cil_shr_un | @cil_shl; + +@cil_binary_arithmetic_operation = @cil_add | @cil_sub | @cil_mul | @cil_div | @cil_div_un | + @cil_rem | @cil_rem_un | @cil_add_ovf | @cil_add_ovf_un | @cil_mul_ovf | @cil_mul_ovf_un | + @cil_sub_ovf | @cil_sub_ovf_un; + +@cil_unary_bitwise_operation = @cil_not; + +@cil_binary_expr = @cil_binary_arithmetic_operation | @cil_binary_bitwise_operation | @cil_read_array | @cil_comparison_operation; + +@cil_unary_arithmetic_operation = @cil_neg; + +@cil_comparison_operation = @cil_cgt_un | @cil_ceq | @cil_cgt | @cil_clt | @cil_clt_un; + +// Elements that retrieve an address of something +@cil_read_ref = @cil_ldloca_s | @cil_ldarga_s | @cil_ldflda | @cil_ldsflda | @cil_ldelema; + +// CIL array instructions + +@cil_read_array = + @cil_ldelem | @cil_ldelema | @cil_ldelem_i1 | @cil_ldelem_ref | @cil_ldelem_i | + @cil_ldelem_i1 | @cil_ldelem_i2 | @cil_ldelem_i4 | @cil_ldelem_i8 | @cil_ldelem_r4 | + @cil_ldelem_r8 | @cil_ldelem_u1 | @cil_ldelem_u2 | @cil_ldelem_u4; + +@cil_write_array = @cil_stelem | @cil_stelem_ref | + @cil_stelem_i | @cil_stelem_i1 | @cil_stelem_i2 | @cil_stelem_i4 | @cil_stelem_i8 | + @cil_stelem_r4 | @cil_stelem_r8; + +@cil_throw_any = @cil_throw | @cil_rethrow; + +#keyset[impl, index] +cil_instruction( + unique int id: @cil_instruction, + int opcode: int ref, + int index: int ref, + int impl: @cil_method_implementation ref); + +cil_jump( + unique int instruction: @cil_jump ref, + int target: @cil_instruction ref); + +cil_access( + unique int instruction: @cil_instruction ref, + int target: @cil_accessible ref); + +cil_value( + unique int instruction: @cil_literal ref, + string value: string ref); + +#keyset[instruction, index] +cil_switch( + int instruction: @cil_switch ref, + int index: int ref, + int target: @cil_instruction ref); + +cil_instruction_location( + unique int id: @cil_instruction ref, + int loc: @location ref); + +cil_type_location( + int id: @cil_type ref, + int loc: @location ref); + +cil_method_location( + int id: @cil_method ref, + int loc: @location ref); + +@cil_namespace = @namespace; + +@cil_type_container = @cil_type | @cil_namespace | @cil_method; + +case @cil_type.kind of + 0 = @cil_valueorreftype +| 1 = @cil_typeparameter +| 2 = @cil_array_type +| 3 = @cil_pointer_type +| 4 = @cil_function_pointer_type +; + +cil_type( + unique int id: @cil_type, + string name: string ref, + int kind: int ref, + int parent: @cil_type_container ref, + int sourceDecl: @cil_type ref); + +cil_pointer_type( + unique int id: @cil_pointer_type ref, + int pointee: @cil_type ref); + +cil_array_type( + unique int id: @cil_array_type ref, + int element_type: @cil_type ref, + int rank: int ref); + +cil_function_pointer_return_type( + unique int id: @cil_function_pointer_type ref, + int return_type: @cil_type ref); + +cil_method( + unique int id: @cil_method, + string name: string ref, + int parent: @cil_type ref, + int return_type: @cil_type ref); + +cil_method_source_declaration( + unique int method: @cil_method ref, + int source: @cil_method ref); + +cil_method_implementation( + unique int id: @cil_method_implementation, + int method: @cil_method ref, + int location: @assembly ref); + +cil_implements( + int id: @cil_method ref, + int decl: @cil_method ref); + +#keyset[parent, name] +cil_field( + unique int id: @cil_field, + int parent: @cil_type ref, + string name: string ref, + int field_type: @cil_type ref); + +@cil_element = @cil_instruction | @cil_declaration | @cil_handler | @cil_attribute | @cil_namespace; +@cil_named_element = @cil_declaration | @cil_namespace; +@cil_declaration = @cil_variable | @cil_method | @cil_type | @cil_member; +@cil_accessible = @cil_declaration; +@cil_variable = @cil_field | @cil_stack_variable; +@cil_stack_variable = @cil_local_variable | @cil_parameter; +@cil_member = @cil_method | @cil_type | @cil_field | @cil_property | @cil_event; +@cil_custom_modifier_receiver = @cil_method | @cil_property | @cil_parameter | @cil_field | @cil_function_pointer_type; +@cil_parameterizable = @cil_method | @cil_function_pointer_type; +@cil_has_type_annotation = @cil_stack_variable | @cil_property | @cil_field | @cil_method | @cil_function_pointer_type; + +#keyset[parameterizable, index] +cil_parameter( + unique int id: @cil_parameter, + int parameterizable: @cil_parameterizable ref, + int index: int ref, + int param_type: @cil_type ref); + +cil_parameter_in(unique int id: @cil_parameter ref); +cil_parameter_out(unique int id: @cil_parameter ref); + +cil_setter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +#keyset[id, modifier] +cil_custom_modifiers( + int id: @cil_custom_modifier_receiver ref, + int modifier: @cil_type ref, + int kind: int ref); // modreq: 1, modopt: 0 + +cil_type_annotation( + int id: @cil_has_type_annotation ref, + int annotation: int ref); + +cil_getter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_adder(unique int event: @cil_event ref, + int method: @cil_method ref); + +cil_remover(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_raiser(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_property( + unique int id: @cil_property, + int parent: @cil_type ref, + string name: string ref, + int property_type: @cil_type ref); + +#keyset[parent, name] +cil_event(unique int id: @cil_event, + int parent: @cil_type ref, + string name: string ref, + int event_type: @cil_type ref); + +#keyset[impl, index] +cil_local_variable( + unique int id: @cil_local_variable, + int impl: @cil_method_implementation ref, + int index: int ref, + int var_type: @cil_type ref); + +cil_function_pointer_calling_conventions( + int id: @cil_function_pointer_type ref, + int kind: int ref); + +// CIL handlers (exception handlers etc). + +case @cil_handler.kind of + 0 = @cil_catch_handler +| 1 = @cil_filter_handler +| 2 = @cil_finally_handler +| 4 = @cil_fault_handler +; + +#keyset[impl, index] +cil_handler( + unique int id: @cil_handler, + int impl: @cil_method_implementation ref, + int index: int ref, + int kind: int ref, + int try_start: @cil_instruction ref, + int try_end: @cil_instruction ref, + int handler_start: @cil_instruction ref); + +cil_handler_filter( + unique int id: @cil_handler ref, + int filter_start: @cil_instruction ref); + +cil_handler_type( + unique int id: @cil_handler ref, + int catch_type: @cil_type ref); + +@cil_controlflow_node = @cil_entry_point | @cil_instruction; + +@cil_entry_point = @cil_method_implementation | @cil_handler; + +@cil_dataflow_node = @cil_instruction | @cil_variable | @cil_method; + +cil_method_stack_size( + unique int method: @cil_method_implementation ref, + int size: int ref); + +// CIL modifiers + +cil_public(int id: @cil_member ref); +cil_private(int id: @cil_member ref); +cil_protected(int id: @cil_member ref); +cil_internal(int id: @cil_member ref); +cil_static(int id: @cil_member ref); +cil_sealed(int id: @cil_member ref); +cil_virtual(int id: @cil_method ref); +cil_abstract(int id: @cil_member ref); +cil_class(int id: @cil_type ref); +cil_interface(int id: @cil_type ref); +cil_security(int id: @cil_member ref); +cil_requiresecobject(int id: @cil_method ref); +cil_specialname(int id: @cil_method ref); +cil_newslot(int id: @cil_method ref); + +cil_base_class(unique int id: @cil_type ref, int base: @cil_type ref); +cil_base_interface(int id: @cil_type ref, int base: @cil_type ref); +cil_enum_underlying_type(unique int id: @cil_type ref, int underlying: @cil_type ref); + +#keyset[unbound, index] +cil_type_parameter( + int unbound: @cil_member ref, + int index: int ref, + int param: @cil_typeparameter ref); + +#keyset[bound, index] +cil_type_argument( + int bound: @cil_member ref, + int index: int ref, + int t: @cil_type ref); + +// CIL type parameter constraints + +cil_typeparam_covariant(int tp: @cil_typeparameter ref); +cil_typeparam_contravariant(int tp: @cil_typeparameter ref); +cil_typeparam_class(int tp: @cil_typeparameter ref); +cil_typeparam_struct(int tp: @cil_typeparameter ref); +cil_typeparam_new(int tp: @cil_typeparameter ref); +cil_typeparam_constraint(int tp: @cil_typeparameter ref, int supertype: @cil_type ref); + +// CIL attributes + +cil_attribute( + unique int attributeid: @cil_attribute, + int element: @cil_declaration ref, + int constructor: @cil_method ref); + +#keyset[attribute_id, param] +cil_attribute_named_argument( + int attribute_id: @cil_attribute ref, + string param: string ref, + string value: string ref); + +#keyset[attribute_id, index] +cil_attribute_positional_argument( + int attribute_id: @cil_attribute ref, + int index: int ref, + string value: string ref); + + +// Common .Net data model covering both C# and CIL + +// Common elements +@dotnet_element = @element | @cil_element; +@dotnet_named_element = @named_element | @cil_named_element; +@dotnet_callable = @callable | @cil_method; +@dotnet_variable = @variable | @cil_variable; +@dotnet_field = @field | @cil_field; +@dotnet_parameter = @parameter | @cil_parameter; +@dotnet_declaration = @declaration | @cil_declaration; +@dotnet_member = @member | @cil_member; +@dotnet_event = @event | @cil_event; +@dotnet_property = @property | @cil_property | @indexer; +@dotnet_parameterizable = @parameterizable | @cil_parameterizable; + +// Common types +@dotnet_type = @type | @cil_type; +@dotnet_call = @call | @cil_call_any; +@dotnet_throw = @throw_element | @cil_throw_any; +@dotnet_valueorreftype = @cil_valueorreftype | @value_or_ref_type | @cil_array_type | @void_type; +@dotnet_typeparameter = @type_parameter | @cil_typeparameter; +@dotnet_array_type = @array_type | @cil_array_type; +@dotnet_pointer_type = @pointer_type | @cil_pointer_type; +@dotnet_type_parameter = @type_parameter | @cil_typeparameter; +@dotnet_generic = @dotnet_valueorreftype | @dotnet_callable; + +// Attributes +@dotnet_attribute = @attribute | @cil_attribute; + +// Expressions +@dotnet_expr = @expr | @cil_expr; + +// Literals +@dotnet_literal = @literal_expr | @cil_literal; +@dotnet_string_literal = @string_literal_expr | @cil_ldstr; +@dotnet_int_literal = @integer_literal_expr | @cil_ldc_i; +@dotnet_float_literal = @float_literal_expr | @cil_ldc_r; +@dotnet_null_literal = @null_literal_expr | @cil_ldnull; + +@metadata_entity = @cil_method | @cil_type | @cil_field | @cil_property | @field | @property | + @callable | @value_or_ref_type | @void_type; + +metadata_handle(int entity : @metadata_entity ref, int location: @assembly ref, int handle: int ref) diff --git a/csharp/ql/lib/upgrades/f145a9a7275c8f457b392b2ebc9f8e07960a0ed2/semmlecode.csharp.dbscheme b/csharp/ql/lib/upgrades/f145a9a7275c8f457b392b2ebc9f8e07960a0ed2/semmlecode.csharp.dbscheme new file mode 100644 index 00000000000..c9ee11bd1ee --- /dev/null +++ b/csharp/ql/lib/upgrades/f145a9a7275c8f457b392b2ebc9f8e07960a0ed2/semmlecode.csharp.dbscheme @@ -0,0 +1,2100 @@ +/* This is a dummy line to alter the dbscheme, so we can make a database upgrade + * without actually changing any of the dbscheme predicates. It contains a date + * to allow for such updates in the future as well. + * + * 2021-07-14 + * + * DO NOT remove this comment carelessly, since it can revert the dbscheme back to a + * previously seen state (matching a previously seen SHA), which would make the upgrade + * mechanism not work properly. + */ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * csc f1.cs f2.cs f3.cs + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + unique int id : @compilation, + string cwd : string ref +); + +compilation_info( + int id : @compilation ref, + string info_key: string ref, + string info_value: string ref +) + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | --compiler + * 1 | *path to compiler* + * 2 | f1.cs + * 3 | f2.cs + * 4 | f3.cs + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The expanded arguments that were passed to the extractor for a + * compiler invocation. This is similar to `compilation_args`, but + * for a `@someFile.rsp` argument, it includes the arguments from that + * file, rather than just taking the argument literally. + */ +#keyset[id, num] +compilation_expanded_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.cs + * 1 | f2.cs + * 2 | f3.cs + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The references used by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs /r:ref1.dll /r:ref2.dll /r:ref3.dll + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | ref1.dll + * 1 | ref2.dll + * 2 | ref3.dll + */ +#keyset[id, num] +compilation_referencing_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location ref +); + +extractor_messages( + unique int id: @extractor_message, + int severity: int ref, + string origin : string ref, + string text : string ref, + string entity : string ref, + int location: @location ref, + string stack_trace : string ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +compilation_assembly( + unique int id : @compilation ref, + int assembly: @assembly ref +) + +// Populated by the CSV extractor +externalData( + int id: @externalDataElement, + string path: string ref, + int column: int ref, + string value: string ref); + +sourceLocationPrefix( + string prefix: string ref); + +/* + * C# dbscheme + */ + +/** ELEMENTS **/ + +@element = @declaration | @stmt | @expr | @modifier | @attribute | @namespace_declaration + | @using_directive | @type_parameter_constraints | @externalDataElement + | @xmllocatable | @asp_element | @namespace | @preprocessor_directive; + +@declaration = @callable | @generic | @assignable | @namespace; + +@named_element = @namespace | @declaration; + +@declaration_with_accessors = @property | @indexer | @event; + +@assignable = @variable | @assignable_with_accessors | @event; + +@assignable_with_accessors = @property | @indexer; + +@attributable = @assembly | @field | @parameter | @operator | @method | @constructor + | @destructor | @callable_accessor | @value_or_ref_type | @declaration_with_accessors + | @local_function | @lambda_expr; + +/** LOCATIONS, ASEMMBLIES, MODULES, FILES and FOLDERS **/ + +@location = @location_default | @assembly; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +locations_mapped( + unique int id: @location_default ref, + int mapped_to: @location_default ref); + +@sourceline = @file | @callable | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref); + +assemblies( + unique int id: @assembly, + int file: @file ref, + string fullname: string ref, + string name: string ref, + string version: string ref); + +files( + unique int id: @file, + string name: string ref); + +folders( + unique int id: @folder, + string name: string ref); + +@container = @folder | @file ; + +containerparent( + int parent: @container ref, + unique int child: @container ref); + +file_extraction_mode( + unique int file: @file ref, + int mode: int ref + /* 0 = normal, 1 = standalone extractor */ + ); + +/** NAMESPACES **/ + +@type_container = @namespace | @type; + +namespaces( + unique int id: @namespace, + string name: string ref); + +namespace_declarations( + unique int id: @namespace_declaration, + int namespace_id: @namespace ref); + +namespace_declaration_location( + unique int id: @namespace_declaration ref, + int loc: @location ref); + +parent_namespace( + unique int child_id: @type_container ref, + int namespace_id: @namespace ref); + +@declaration_or_directive = @namespace_declaration | @type | @using_directive; + +parent_namespace_declaration( + int child_id: @declaration_or_directive ref, // cannot be unique because of partial classes + int namespace_id: @namespace_declaration ref); + +@using_directive = @using_namespace_directive | @using_static_directive; + +using_global( + unique int id: @using_directive ref +); + +using_namespace_directives( + unique int id: @using_namespace_directive, + int namespace_id: @namespace ref); + +using_static_directives( + unique int id: @using_static_directive, + int type_id: @type_or_ref ref); + +using_directive_location( + unique int id: @using_directive ref, + int loc: @location ref); + +@preprocessor_directive = @pragma_warning | @pragma_checksum | @directive_define | @directive_undefine | @directive_warning + | @directive_error | @directive_nullable | @directive_line | @directive_region | @directive_endregion | @directive_if + | @directive_elif | @directive_else | @directive_endif; + +@conditional_directive = @directive_if | @directive_elif; +@branch_directive = @directive_if | @directive_elif | @directive_else; + +directive_ifs( + unique int id: @directive_if, + int branchTaken: int ref, /* 0: false, 1: true */ + int conditionValue: int ref); /* 0: false, 1: true */ + +directive_elifs( + unique int id: @directive_elif, + int branchTaken: int ref, /* 0: false, 1: true */ + int conditionValue: int ref, /* 0: false, 1: true */ + int parent: @directive_if ref, + int index: int ref); + +directive_elses( + unique int id: @directive_else, + int branchTaken: int ref, /* 0: false, 1: true */ + int parent: @directive_if ref, + int index: int ref); + +#keyset[id, start] +directive_endifs( + unique int id: @directive_endif, + unique int start: @directive_if ref); + +directive_define_symbols( + unique int id: @define_symbol_expr ref, + string name: string ref); + +directive_regions( + unique int id: @directive_region, + string name: string ref); + +#keyset[id, start] +directive_endregions( + unique int id: @directive_endregion, + unique int start: @directive_region ref); + +directive_lines( + unique int id: @directive_line, + int kind: int ref); /* 0: default, 1: hidden, 2: numeric, 3: span */ + +directive_line_value( + unique int id: @directive_line ref, + int line: int ref); + +directive_line_file( + unique int id: @directive_line ref, + int file: @file ref); + +directive_line_offset( + unique int id: @directive_line ref, + int offset: int ref); + +directive_line_span( + unique int id: @directive_line ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +directive_nullables( + unique int id: @directive_nullable, + int setting: int ref, /* 0: disable, 1: enable, 2: restore */ + int target: int ref); /* 0: none, 1: annotations, 2: warnings */ + +directive_warnings( + unique int id: @directive_warning, + string message: string ref); + +directive_errors( + unique int id: @directive_error, + string message: string ref); + +directive_undefines( + unique int id: @directive_undefine, + string name: string ref); + +directive_defines( + unique int id: @directive_define, + string name: string ref); + +pragma_checksums( + unique int id: @pragma_checksum, + int file: @file ref, + string guid: string ref, + string bytes: string ref); + +pragma_warnings( + unique int id: @pragma_warning, + int kind: int ref /* 0 = disable, 1 = restore */); + +#keyset[id, index] +pragma_warning_error_codes( + int id: @pragma_warning ref, + string errorCode: string ref, + int index: int ref); + +preprocessor_directive_location( + unique int id: @preprocessor_directive ref, + int loc: @location ref); + +preprocessor_directive_compilation( + unique int id: @preprocessor_directive ref, + int compilation: @compilation ref); + +preprocessor_directive_active( + unique int id: @preprocessor_directive ref, + int active: int ref); /* 0: false, 1: true */ + +/** TYPES **/ + +types( + unique int id: @type, + int kind: int ref, + string name: string ref); + +case @type.kind of + 1 = @bool_type +| 2 = @char_type +| 3 = @decimal_type +| 4 = @sbyte_type +| 5 = @short_type +| 6 = @int_type +| 7 = @long_type +| 8 = @byte_type +| 9 = @ushort_type +| 10 = @uint_type +| 11 = @ulong_type +| 12 = @float_type +| 13 = @double_type +| 14 = @enum_type +| 15 = @struct_type +| 17 = @class_type +| 19 = @interface_type +| 20 = @delegate_type +| 21 = @null_type +| 22 = @type_parameter +| 23 = @pointer_type +| 24 = @nullable_type +| 25 = @array_type +| 26 = @void_type +| 27 = @int_ptr_type +| 28 = @uint_ptr_type +| 29 = @dynamic_type +| 30 = @arglist_type +| 31 = @unknown_type +| 32 = @tuple_type +| 33 = @function_pointer_type +| 34 = @inline_array_type + ; + +@simple_type = @bool_type | @char_type | @integral_type | @floating_point_type | @decimal_type; +@integral_type = @signed_integral_type | @unsigned_integral_type; +@signed_integral_type = @sbyte_type | @short_type | @int_type | @long_type; +@unsigned_integral_type = @byte_type | @ushort_type | @uint_type | @ulong_type; +@floating_point_type = @float_type | @double_type; +@value_type = @simple_type | @enum_type | @struct_type | @nullable_type | @int_ptr_type + | @uint_ptr_type | @tuple_type | @void_type | @inline_array_type; +@ref_type = @class_type | @interface_type | @array_type | @delegate_type | @null_type + | @dynamic_type; +@value_or_ref_type = @value_type | @ref_type; + +typerefs( + unique int id: @typeref, + string name: string ref); + +typeref_type( + int id: @typeref ref, + unique int typeId: @type ref); + +@type_or_ref = @type | @typeref; + +array_element_type( + unique int array: @array_type ref, + int dimension: int ref, + int rank: int ref, + int element: @type_or_ref ref); + +nullable_underlying_type( + unique int nullable: @nullable_type ref, + int underlying: @type_or_ref ref); + +pointer_referent_type( + unique int pointer: @pointer_type ref, + int referent: @type_or_ref ref); + +enum_underlying_type( + unique int enum_id: @enum_type ref, + int underlying_type_id: @type_or_ref ref); + +delegate_return_type( + unique int delegate_id: @delegate_type ref, + int return_type_id: @type_or_ref ref); + +function_pointer_return_type( + unique int function_pointer_id: @function_pointer_type ref, + int return_type_id: @type_or_ref ref); + +extend( + int sub: @type ref, + int super: @type_or_ref ref); + +anonymous_types( + unique int id: @type ref); + +@interface_or_ref = @interface_type | @typeref; + +implement( + int sub: @type ref, + int super: @type_or_ref ref); + +type_location( + int id: @type ref, + int loc: @location ref); + +tuple_underlying_type( + unique int tuple: @tuple_type ref, + int struct: @type_or_ref ref); + +#keyset[tuple, index] +tuple_element( + int tuple: @tuple_type ref, + int index: int ref, + unique int field: @field ref); + +attributes( + unique int id: @attribute, + int kind: int ref, + int type_id: @type_or_ref ref, + int target: @attributable ref); + +case @attribute.kind of + 0 = @attribute_default +| 1 = @attribute_return +| 2 = @attribute_assembly +| 3 = @attribute_module +; + +attribute_location( + int id: @attribute ref, + int loc: @location ref); + +@type_mention_parent = @element | @type_mention; + +type_mention( + unique int id: @type_mention, + int type_id: @type_or_ref ref, + int parent: @type_mention_parent ref); + +type_mention_location( + unique int id: @type_mention ref, + int loc: @location ref); + +@has_type_annotation = @assignable | @type_parameter | @callable | @expr | @delegate_type | @generic | @function_pointer_type; + +/** + * A direct annotation on an entity, for example `string? x;`. + * + * Annotations: + * 2 = reftype is not annotated "!" + * 3 = reftype is annotated "?" + * 4 = readonly ref type / in parameter + * 5 = ref type parameter, return or local variable + * 6 = out parameter + * + * Note that the annotation depends on the element it annotates. + * @assignable: The annotation is on the type of the assignable, for example the variable type. + * @type_parameter: The annotation is on the reftype constraint + * @callable: The annotation is on the return type + * @array_type: The annotation is on the element type + */ +type_annotation(int id: @has_type_annotation ref, int annotation: int ref); + +nullability(unique int nullability: @nullability, int kind: int ref); + +case @nullability.kind of + 0 = @oblivious +| 1 = @not_annotated +| 2 = @annotated +; + +#keyset[parent, index] +nullability_parent(int nullability: @nullability ref, int index: int ref, int parent: @nullability ref) + +type_nullability(int id: @has_type_annotation ref, int nullability: @nullability ref); + +/** + * The nullable flow state of an expression, as determined by Roslyn. + * 0 = none (default, not populated) + * 1 = not null + * 2 = maybe null + */ +expr_flowstate(unique int id: @expr ref, int state: int ref); + +/** GENERICS **/ + +@generic = @type | @method | @local_function; + +type_parameters( + unique int id: @type_parameter ref, + int index: int ref, + int generic_id: @generic ref, + int variance: int ref /* none = 0, out = 1, in = 2 */); + +#keyset[constructed_id, index] +type_arguments( + int id: @type_or_ref ref, + int index: int ref, + int constructed_id: @generic_or_ref ref); + +@generic_or_ref = @generic | @typeref; + +constructed_generic( + unique int constructed: @generic ref, + int generic: @generic_or_ref ref); + +type_parameter_constraints( + unique int id: @type_parameter_constraints, + int param_id: @type_parameter ref); + +type_parameter_constraints_location( + int id: @type_parameter_constraints ref, + int loc: @location ref); + +general_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int kind: int ref /* class = 1, struct = 2, new = 3 */); + +specific_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref); + +specific_type_parameter_nullability( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref, + int nullability: @nullability ref); + +/** FUNCTION POINTERS */ + +function_pointer_calling_conventions( + int id: @function_pointer_type ref, + int kind: int ref); + +#keyset[id, index] +has_unmanaged_calling_conventions( + int id: @function_pointer_type ref, + int index: int ref, + int conv_id: @type_or_ref ref); + +/** MODIFIERS */ + +@modifiable = @modifiable_direct | @event_accessor; + +@modifiable_direct = @member | @accessor | @local_function | @anonymous_function_expr; + +modifiers( + unique int id: @modifier, + string name: string ref); + +has_modifiers( + int id: @modifiable_direct ref, + int mod_id: @modifier ref); + +compiler_generated(unique int id: @modifiable ref); + +/** MEMBERS **/ + +@member = @method | @constructor | @destructor | @field | @property | @event | @operator | @indexer | @type; + +@named_exprorstmt = @goto_stmt | @labeled_stmt | @expr; + +@virtualizable = @method | @property | @indexer | @event | @operator; + +exprorstmt_name( + unique int parent_id: @named_exprorstmt ref, + string name: string ref); + +nested_types( + unique int id: @type ref, + int declaring_type_id: @type ref, + int unbound_id: @type ref); + +properties( + unique int id: @property, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @property ref); + +property_location( + int id: @property ref, + int loc: @location ref); + +indexers( + unique int id: @indexer, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @indexer ref); + +indexer_location( + int id: @indexer ref, + int loc: @location ref); + +accessors( + unique int id: @accessor, + int kind: int ref, + string name: string ref, + int declaring_member_id: @member ref, + int unbound_id: @accessor ref); + +case @accessor.kind of + 1 = @getter +| 2 = @setter + ; + +init_only_accessors( + unique int id: @accessor ref); + +accessor_location( + int id: @accessor ref, + int loc: @location ref); + +events( + unique int id: @event, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @event ref); + +event_location( + int id: @event ref, + int loc: @location ref); + +event_accessors( + unique int id: @event_accessor, + int kind: int ref, + string name: string ref, + int declaring_event_id: @event ref, + int unbound_id: @event_accessor ref); + +case @event_accessor.kind of + 1 = @add_event_accessor +| 2 = @remove_event_accessor + ; + +event_accessor_location( + int id: @event_accessor ref, + int loc: @location ref); + +operators( + unique int id: @operator, + string name: string ref, + string symbol: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @operator ref); + +operator_location( + int id: @operator ref, + int loc: @location ref); + +constant_value( + int id: @variable ref, + string value: string ref); + +/** CALLABLES **/ + +@callable = @method | @constructor | @destructor | @operator | @callable_accessor | @anonymous_function_expr | @local_function; + +@callable_accessor = @accessor | @event_accessor; + +methods( + unique int id: @method, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @method ref); + +method_location( + int id: @method ref, + int loc: @location ref); + +constructors( + unique int id: @constructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @constructor ref); + +constructor_location( + int id: @constructor ref, + int loc: @location ref); + +destructors( + unique int id: @destructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @destructor ref); + +destructor_location( + int id: @destructor ref, + int loc: @location ref); + +overrides( + int id: @callable ref, + int base_id: @callable ref); + +explicitly_implements( + int id: @member ref, + int interface_id: @interface_or_ref ref); + +local_functions( + unique int id: @local_function, + string name: string ref, + int return_type: @type ref, + int unbound_id: @local_function ref); + +local_function_stmts( + unique int fn: @local_function_stmt ref, + int stmt: @local_function ref); + +/** VARIABLES **/ + +@variable = @local_scope_variable | @field; + +@local_scope_variable = @local_variable | @parameter; + +fields( + unique int id: @field, + int kind: int ref, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @field ref); + +case @field.kind of + 1 = @addressable_field +| 2 = @constant + ; + +field_location( + int id: @field ref, + int loc: @location ref); + +localvars( + unique int id: @local_variable, + int kind: int ref, + string name: string ref, + int implicitly_typed: int ref /* 0 = no, 1 = yes */, + int type_id: @type_or_ref ref, + int parent_id: @local_var_decl_expr ref); + +case @local_variable.kind of + 1 = @addressable_local_variable +| 2 = @local_constant +| 3 = @local_variable_ref + ; + +localvar_location( + unique int id: @local_variable ref, + int loc: @location ref); + +@parameterizable = @callable | @delegate_type | @indexer | @function_pointer_type; + +#keyset[name, parent_id] +#keyset[index, parent_id] +params( + unique int id: @parameter, + string name: string ref, + int type_id: @type_or_ref ref, + int index: int ref, + int mode: int ref, /* value = 0, ref = 1, out = 2, array = 3, this = 4 */ + int parent_id: @parameterizable ref, + int unbound_id: @parameter ref); + +param_location( + int id: @parameter ref, + int loc: @location ref); + +@has_scoped_annotation = @local_scope_variable + +scoped_annotation( + int id: @has_scoped_annotation ref, + int kind: int ref // scoped ref = 1, scoped value = 2 + ); + +/** STATEMENTS **/ + +@exprorstmt_parent = @control_flow_element | @top_level_exprorstmt_parent; + +statements( + unique int id: @stmt, + int kind: int ref); + +#keyset[index, parent] +stmt_parent( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_stmt_parent = @callable; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +stmt_parent_top_level( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @top_level_stmt_parent ref); + +case @stmt.kind of + 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @switch_stmt +| 5 = @while_stmt +| 6 = @do_stmt +| 7 = @for_stmt +| 8 = @foreach_stmt +| 9 = @break_stmt +| 10 = @continue_stmt +| 11 = @goto_stmt +| 12 = @goto_case_stmt +| 13 = @goto_default_stmt +| 14 = @throw_stmt +| 15 = @return_stmt +| 16 = @yield_stmt +| 17 = @try_stmt +| 18 = @checked_stmt +| 19 = @unchecked_stmt +| 20 = @lock_stmt +| 21 = @using_block_stmt +| 22 = @var_decl_stmt +| 23 = @const_decl_stmt +| 24 = @empty_stmt +| 25 = @unsafe_stmt +| 26 = @fixed_stmt +| 27 = @label_stmt +| 28 = @catch +| 29 = @case_stmt +| 30 = @local_function_stmt +| 31 = @using_decl_stmt + ; + +@using_stmt = @using_block_stmt | @using_decl_stmt; + +@labeled_stmt = @label_stmt | @case; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @using_decl_stmt; + +@cond_stmt = @if_stmt | @switch_stmt; + +@loop_stmt = @while_stmt | @do_stmt | @for_stmt | @foreach_stmt; + +@jump_stmt = @break_stmt | @goto_any_stmt | @continue_stmt | @throw_stmt | @return_stmt + | @yield_stmt; + +@goto_any_stmt = @goto_default_stmt | @goto_case_stmt | @goto_stmt; + + +stmt_location( + unique int id: @stmt ref, + int loc: @location ref); + +catch_type( + unique int catch_id: @catch ref, + int type_id: @type_or_ref ref, + int kind: int ref /* explicit = 1, implicit = 2 */); + +foreach_stmt_info( + unique int id: @foreach_stmt ref, + int kind: int ref /* non-async = 1, async = 2 */); + +@foreach_symbol = @method | @property | @type_or_ref; + +#keyset[id, kind] +foreach_stmt_desugar( + int id: @foreach_stmt ref, + int symbol: @foreach_symbol ref, + int kind: int ref /* GetEnumeratorMethod = 1, CurrentProperty = 2, MoveNextMethod = 3, DisposeMethod = 4, ElementType = 5 */); + +/** EXPRESSIONS **/ + +expressions( + unique int id: @expr, + int kind: int ref, + int type_id: @type_or_ref ref); + +#keyset[index, parent] +expr_parent( + unique int expr: @expr ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_expr_parent = @attribute | @field | @property | @indexer | @parameter | @directive_if | @directive_elif; + +@top_level_exprorstmt_parent = @top_level_expr_parent | @top_level_stmt_parent; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +expr_parent_top_level( + unique int expr: @expr ref, + int index: int ref, + int parent: @top_level_exprorstmt_parent ref); + +case @expr.kind of +/* literal */ + 1 = @bool_literal_expr +| 2 = @char_literal_expr +| 3 = @decimal_literal_expr +| 4 = @int_literal_expr +| 5 = @long_literal_expr +| 6 = @uint_literal_expr +| 7 = @ulong_literal_expr +| 8 = @float_literal_expr +| 9 = @double_literal_expr +| 10 = @utf16_string_literal_expr +| 11 = @null_literal_expr +/* primary & unary */ +| 12 = @this_access_expr +| 13 = @base_access_expr +| 14 = @local_variable_access_expr +| 15 = @parameter_access_expr +| 16 = @field_access_expr +| 17 = @property_access_expr +| 18 = @method_access_expr +| 19 = @event_access_expr +| 20 = @indexer_access_expr +| 21 = @array_access_expr +| 22 = @type_access_expr +| 23 = @typeof_expr +| 24 = @method_invocation_expr +| 25 = @delegate_invocation_expr +| 26 = @operator_invocation_expr +| 27 = @cast_expr +| 28 = @object_creation_expr +| 29 = @explicit_delegate_creation_expr +| 30 = @implicit_delegate_creation_expr +| 31 = @array_creation_expr +| 32 = @default_expr +| 33 = @plus_expr +| 34 = @minus_expr +| 35 = @bit_not_expr +| 36 = @log_not_expr +| 37 = @post_incr_expr +| 38 = @post_decr_expr +| 39 = @pre_incr_expr +| 40 = @pre_decr_expr +/* multiplicative */ +| 41 = @mul_expr +| 42 = @div_expr +| 43 = @rem_expr +/* additive */ +| 44 = @add_expr +| 45 = @sub_expr +/* shift */ +| 46 = @lshift_expr +| 47 = @rshift_expr +/* relational */ +| 48 = @lt_expr +| 49 = @gt_expr +| 50 = @le_expr +| 51 = @ge_expr +/* equality */ +| 52 = @eq_expr +| 53 = @ne_expr +/* logical */ +| 54 = @bit_and_expr +| 55 = @bit_xor_expr +| 56 = @bit_or_expr +| 57 = @log_and_expr +| 58 = @log_or_expr +/* type testing */ +| 59 = @is_expr +| 60 = @as_expr +/* null coalescing */ +| 61 = @null_coalescing_expr +/* conditional */ +| 62 = @conditional_expr +/* assignment */ +| 63 = @simple_assign_expr +| 64 = @assign_add_expr +| 65 = @assign_sub_expr +| 66 = @assign_mul_expr +| 67 = @assign_div_expr +| 68 = @assign_rem_expr +| 69 = @assign_and_expr +| 70 = @assign_xor_expr +| 71 = @assign_or_expr +| 72 = @assign_lshift_expr +| 73 = @assign_rshift_expr +/* more */ +| 74 = @object_init_expr +| 75 = @collection_init_expr +| 76 = @array_init_expr +| 77 = @checked_expr +| 78 = @unchecked_expr +| 79 = @constructor_init_expr +| 80 = @add_event_expr +| 81 = @remove_event_expr +| 82 = @par_expr +| 83 = @local_var_decl_expr +| 84 = @lambda_expr +| 85 = @anonymous_method_expr +| 86 = @namespace_expr +/* dynamic */ +| 92 = @dynamic_element_access_expr +| 93 = @dynamic_member_access_expr +/* unsafe */ +| 100 = @pointer_indirection_expr +| 101 = @address_of_expr +| 102 = @sizeof_expr +/* async */ +| 103 = @await_expr +/* C# 6.0 */ +| 104 = @nameof_expr +| 105 = @interpolated_string_expr +| 106 = @unknown_expr +/* C# 7.0 */ +| 107 = @throw_expr +| 108 = @tuple_expr +| 109 = @local_function_invocation_expr +| 110 = @ref_expr +| 111 = @discard_expr +/* C# 8.0 */ +| 112 = @range_expr +| 113 = @index_expr +| 114 = @switch_expr +| 115 = @recursive_pattern_expr +| 116 = @property_pattern_expr +| 117 = @positional_pattern_expr +| 118 = @switch_case_expr +| 119 = @assign_coalesce_expr +| 120 = @suppress_nullable_warning_expr +| 121 = @namespace_access_expr +/* C# 9.0 */ +| 122 = @lt_pattern_expr +| 123 = @gt_pattern_expr +| 124 = @le_pattern_expr +| 125 = @ge_pattern_expr +| 126 = @not_pattern_expr +| 127 = @and_pattern_expr +| 128 = @or_pattern_expr +| 129 = @function_pointer_invocation_expr +| 130 = @with_expr +/* C# 11.0 */ +| 131 = @list_pattern_expr +| 132 = @slice_pattern_expr +| 133 = @urshift_expr +| 134 = @assign_urshift_expr +| 135 = @utf8_string_literal_expr +/* C# 12.0 */ +| 136 = @collection_expr +| 137 = @spread_element_expr +/* Preprocessor */ +| 999 = @define_symbol_expr +; + +@switch = @switch_stmt | @switch_expr; +@case = @case_stmt | @switch_case_expr; +@pattern_match = @case | @is_expr; +@unary_pattern_expr = @not_pattern_expr; +@relational_pattern_expr = @gt_pattern_expr | @lt_pattern_expr | @ge_pattern_expr | @le_pattern_expr; +@binary_pattern_expr = @and_pattern_expr | @or_pattern_expr; + +@integer_literal_expr = @int_literal_expr | @long_literal_expr | @uint_literal_expr | @ulong_literal_expr; +@real_literal_expr = @float_literal_expr | @double_literal_expr | @decimal_literal_expr; +@string_literal_expr = @utf16_string_literal_expr | @utf8_string_literal_expr; +@literal_expr = @bool_literal_expr | @char_literal_expr | @integer_literal_expr | @real_literal_expr + | @string_literal_expr | @null_literal_expr; + +@assign_expr = @simple_assign_expr | @assign_op_expr | @local_var_decl_expr; +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr | @assign_event_expr | @assign_coalesce_expr; +@assign_event_expr = @add_event_expr | @remove_event_expr; + +@assign_arith_expr = @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr + | @assign_rem_expr +@assign_bitwise_expr = @assign_and_expr | @assign_or_expr | @assign_xor_expr + | @assign_lshift_expr | @assign_rshift_expr | @assign_urshift_expr; + +@member_access_expr = @field_access_expr | @property_access_expr | @indexer_access_expr | @event_access_expr + | @method_access_expr | @type_access_expr | @dynamic_member_access_expr; +@access_expr = @member_access_expr | @this_access_expr | @base_access_expr | @assignable_access_expr | @namespace_access_expr; +@element_access_expr = @indexer_access_expr | @array_access_expr | @dynamic_element_access_expr; + +@local_variable_access = @local_variable_access_expr | @local_var_decl_expr; +@local_scope_variable_access_expr = @parameter_access_expr | @local_variable_access; +@variable_access_expr = @local_scope_variable_access_expr | @field_access_expr; + +@assignable_access_expr = @variable_access_expr | @property_access_expr | @element_access_expr + | @event_access_expr | @dynamic_member_access_expr; + +@objectorcollection_init_expr = @object_init_expr | @collection_init_expr; + +@delegate_creation_expr = @explicit_delegate_creation_expr | @implicit_delegate_creation_expr; + +@bin_arith_op_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr; +@incr_op_expr = @pre_incr_expr | @post_incr_expr; +@decr_op_expr = @pre_decr_expr | @post_decr_expr; +@mut_op_expr = @incr_op_expr | @decr_op_expr; +@un_arith_op_expr = @plus_expr | @minus_expr | @mut_op_expr; +@arith_op_expr = @bin_arith_op_expr | @un_arith_op_expr; + +@ternary_log_op_expr = @conditional_expr; +@bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr; +@un_log_op_expr = @log_not_expr; +@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr; + +@bin_bit_op_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr + | @rshift_expr | @urshift_expr; +@un_bit_op_expr = @bit_not_expr; +@bit_expr = @un_bit_op_expr | @bin_bit_op_expr; + +@equality_op_expr = @eq_expr | @ne_expr; +@rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr; +@comp_expr = @equality_op_expr | @rel_op_expr; + +@op_expr = @assign_expr | @un_op | @bin_op | @ternary_op; + +@ternary_op = @ternary_log_op_expr; +@bin_op = @bin_arith_op_expr | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr; +@un_op = @un_arith_op_expr | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr + | @pointer_indirection_expr | @address_of_expr; + +@anonymous_function_expr = @lambda_expr | @anonymous_method_expr; + +@call = @method_invocation_expr | @constructor_init_expr | @operator_invocation_expr + | @delegate_invocation_expr | @object_creation_expr | @call_access_expr + | @local_function_invocation_expr | @function_pointer_invocation_expr; + +@call_access_expr = @property_access_expr | @event_access_expr | @indexer_access_expr; + +@late_bindable_expr = @dynamic_element_access_expr | @dynamic_member_access_expr + | @object_creation_expr | @method_invocation_expr | @operator_invocation_expr; + +@throw_element = @throw_expr | @throw_stmt; + +@implicitly_typeable_object_creation_expr = @object_creation_expr | @explicit_delegate_creation_expr; + +implicitly_typed_array_creation( + unique int id: @array_creation_expr ref); + +explicitly_sized_array_creation( + unique int id: @array_creation_expr ref); + +stackalloc_array_creation( + unique int id: @array_creation_expr ref); + +implicitly_typed_object_creation( + unique int id: @implicitly_typeable_object_creation_expr ref); + +mutator_invocation_mode( + unique int id: @operator_invocation_expr ref, + int mode: int ref /* prefix = 1, postfix = 2*/); + +expr_compiler_generated( + unique int id: @expr ref); + +expr_value( + unique int id: @expr ref, + string value: string ref); + +expr_call( + unique int caller_id: @expr ref, + int target_id: @callable ref); + +expr_access( + unique int accesser_id: @access_expr ref, + int target_id: @accessible ref); + +@accessible = @method | @assignable | @local_function | @namespace; + +expr_location( + unique int id: @expr ref, + int loc: @location ref); + +dynamic_member_name( + unique int id: @late_bindable_expr ref, + string name: string ref); + +@qualifiable_expr = @member_access_expr + | @method_invocation_expr + | @element_access_expr; + +conditional_access( + unique int id: @qualifiable_expr ref); + +expr_argument( + unique int id: @expr ref, + int mode: int ref); + /* mode is the same as params: value = 0, ref = 1, out = 2 */ + +expr_argument_name( + unique int id: @expr ref, + string name: string ref); + +lambda_expr_return_type( + unique int id: @lambda_expr ref, + int type_id: @type_or_ref ref); + +/** CONTROL/DATA FLOW **/ + +@control_flow_element = @stmt | @expr; + +/* XML Files */ + +xmlEncoding ( + unique int id: @file ref, + string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* Comments */ + +commentline( + unique int id: @commentline, + int kind: int ref, + string text: string ref, + string rawtext: string ref); + +case @commentline.kind of + 0 = @singlelinecomment +| 1 = @xmldoccomment +| 2 = @multilinecomment; + +commentline_location( + unique int id: @commentline ref, + int loc: @location ref); + +commentblock( + unique int id : @commentblock); + +commentblock_location( + unique int id: @commentblock ref, + int loc: @location ref); + +commentblock_binding( + int id: @commentblock ref, + int entity: @element ref, + int bindtype: int ref); /* 0: Parent, 1: Best, 2: Before, 3: After */ + +commentblock_child( + int id: @commentblock ref, + int commentline: @commentline ref, + int index: int ref); + +/* ASP.NET */ + +case @asp_element.kind of + 0=@asp_close_tag +| 1=@asp_code +| 2=@asp_comment +| 3=@asp_data_binding +| 4=@asp_directive +| 5=@asp_open_tag +| 6=@asp_quoted_string +| 7=@asp_text +| 8=@asp_xml_directive; + +@asp_attribute = @asp_code | @asp_data_binding | @asp_quoted_string; + +asp_elements( + unique int id: @asp_element, + int kind: int ref, + int loc: @location ref); + +asp_comment_server(unique int comment: @asp_comment ref); +asp_code_inline(unique int code: @asp_code ref); +asp_directive_attribute( + int directive: @asp_directive ref, + int index: int ref, + string name: string ref, + int value: @asp_quoted_string ref); +asp_directive_name( + unique int directive: @asp_directive ref, + string name: string ref); +asp_element_body( + unique int element: @asp_element ref, + string body: string ref); +asp_tag_attribute( + int tag: @asp_open_tag ref, + int index: int ref, + string name: string ref, + int attribute: @asp_attribute ref); +asp_tag_name( + unique int tag: @asp_open_tag ref, + string name: string ref); +asp_tag_isempty(int tag: @asp_open_tag ref); + +/* Common Intermediate Language - CIL */ + +case @cil_instruction.opcode of + 0 = @cil_nop +| 1 = @cil_break +| 2 = @cil_ldarg_0 +| 3 = @cil_ldarg_1 +| 4 = @cil_ldarg_2 +| 5 = @cil_ldarg_3 +| 6 = @cil_ldloc_0 +| 7 = @cil_ldloc_1 +| 8 = @cil_ldloc_2 +| 9 = @cil_ldloc_3 +| 10 = @cil_stloc_0 +| 11 = @cil_stloc_1 +| 12 = @cil_stloc_2 +| 13 = @cil_stloc_3 +| 14 = @cil_ldarg_s +| 15 = @cil_ldarga_s +| 16 = @cil_starg_s +| 17 = @cil_ldloc_s +| 18 = @cil_ldloca_s +| 19 = @cil_stloc_s +| 20 = @cil_ldnull +| 21 = @cil_ldc_i4_m1 +| 22 = @cil_ldc_i4_0 +| 23 = @cil_ldc_i4_1 +| 24 = @cil_ldc_i4_2 +| 25 = @cil_ldc_i4_3 +| 26 = @cil_ldc_i4_4 +| 27 = @cil_ldc_i4_5 +| 28 = @cil_ldc_i4_6 +| 29 = @cil_ldc_i4_7 +| 30 = @cil_ldc_i4_8 +| 31 = @cil_ldc_i4_s +| 32 = @cil_ldc_i4 +| 33 = @cil_ldc_i8 +| 34 = @cil_ldc_r4 +| 35 = @cil_ldc_r8 +| 37 = @cil_dup +| 38 = @cil_pop +| 39 = @cil_jmp +| 40 = @cil_call +| 41 = @cil_calli +| 42 = @cil_ret +| 43 = @cil_br_s +| 44 = @cil_brfalse_s +| 45 = @cil_brtrue_s +| 46 = @cil_beq_s +| 47 = @cil_bge_s +| 48 = @cil_bgt_s +| 49 = @cil_ble_s +| 50 = @cil_blt_s +| 51 = @cil_bne_un_s +| 52 = @cil_bge_un_s +| 53 = @cil_bgt_un_s +| 54 = @cil_ble_un_s +| 55 = @cil_blt_un_s +| 56 = @cil_br +| 57 = @cil_brfalse +| 58 = @cil_brtrue +| 59 = @cil_beq +| 60 = @cil_bge +| 61 = @cil_bgt +| 62 = @cil_ble +| 63 = @cil_blt +| 64 = @cil_bne_un +| 65 = @cil_bge_un +| 66 = @cil_bgt_un +| 67 = @cil_ble_un +| 68 = @cil_blt_un +| 69 = @cil_switch +| 70 = @cil_ldind_i1 +| 71 = @cil_ldind_u1 +| 72 = @cil_ldind_i2 +| 73 = @cil_ldind_u2 +| 74 = @cil_ldind_i4 +| 75 = @cil_ldind_u4 +| 76 = @cil_ldind_i8 +| 77 = @cil_ldind_i +| 78 = @cil_ldind_r4 +| 79 = @cil_ldind_r8 +| 80 = @cil_ldind_ref +| 81 = @cil_stind_ref +| 82 = @cil_stind_i1 +| 83 = @cil_stind_i2 +| 84 = @cil_stind_i4 +| 85 = @cil_stind_i8 +| 86 = @cil_stind_r4 +| 87 = @cil_stind_r8 +| 88 = @cil_add +| 89 = @cil_sub +| 90 = @cil_mul +| 91 = @cil_div +| 92 = @cil_div_un +| 93 = @cil_rem +| 94 = @cil_rem_un +| 95 = @cil_and +| 96 = @cil_or +| 97 = @cil_xor +| 98 = @cil_shl +| 99 = @cil_shr +| 100 = @cil_shr_un +| 101 = @cil_neg +| 102 = @cil_not +| 103 = @cil_conv_i1 +| 104 = @cil_conv_i2 +| 105 = @cil_conv_i4 +| 106 = @cil_conv_i8 +| 107 = @cil_conv_r4 +| 108 = @cil_conv_r8 +| 109 = @cil_conv_u4 +| 110 = @cil_conv_u8 +| 111 = @cil_callvirt +| 112 = @cil_cpobj +| 113 = @cil_ldobj +| 114 = @cil_ldstr +| 115 = @cil_newobj +| 116 = @cil_castclass +| 117 = @cil_isinst +| 118 = @cil_conv_r_un +| 121 = @cil_unbox +| 122 = @cil_throw +| 123 = @cil_ldfld +| 124 = @cil_ldflda +| 125 = @cil_stfld +| 126 = @cil_ldsfld +| 127 = @cil_ldsflda +| 128 = @cil_stsfld +| 129 = @cil_stobj +| 130 = @cil_conv_ovf_i1_un +| 131 = @cil_conv_ovf_i2_un +| 132 = @cil_conv_ovf_i4_un +| 133 = @cil_conv_ovf_i8_un +| 134 = @cil_conv_ovf_u1_un +| 135 = @cil_conv_ovf_u2_un +| 136 = @cil_conv_ovf_u4_un +| 137 = @cil_conv_ovf_u8_un +| 138 = @cil_conv_ovf_i_un +| 139 = @cil_conv_ovf_u_un +| 140 = @cil_box +| 141 = @cil_newarr +| 142 = @cil_ldlen +| 143 = @cil_ldelema +| 144 = @cil_ldelem_i1 +| 145 = @cil_ldelem_u1 +| 146 = @cil_ldelem_i2 +| 147 = @cil_ldelem_u2 +| 148 = @cil_ldelem_i4 +| 149 = @cil_ldelem_u4 +| 150 = @cil_ldelem_i8 +| 151 = @cil_ldelem_i +| 152 = @cil_ldelem_r4 +| 153 = @cil_ldelem_r8 +| 154 = @cil_ldelem_ref +| 155 = @cil_stelem_i +| 156 = @cil_stelem_i1 +| 157 = @cil_stelem_i2 +| 158 = @cil_stelem_i4 +| 159 = @cil_stelem_i8 +| 160 = @cil_stelem_r4 +| 161 = @cil_stelem_r8 +| 162 = @cil_stelem_ref +| 163 = @cil_ldelem +| 164 = @cil_stelem +| 165 = @cil_unbox_any +| 179 = @cil_conv_ovf_i1 +| 180 = @cil_conv_ovf_u1 +| 181 = @cil_conv_ovf_i2 +| 182 = @cil_conv_ovf_u2 +| 183 = @cil_conv_ovf_i4 +| 184 = @cil_conv_ovf_u4 +| 185 = @cil_conv_ovf_i8 +| 186 = @cil_conv_ovf_u8 +| 194 = @cil_refanyval +| 195 = @cil_ckinfinite +| 198 = @cil_mkrefany +| 208 = @cil_ldtoken +| 209 = @cil_conv_u2 +| 210 = @cil_conv_u1 +| 211 = @cil_conv_i +| 212 = @cil_conv_ovf_i +| 213 = @cil_conv_ovf_u +| 214 = @cil_add_ovf +| 215 = @cil_add_ovf_un +| 216 = @cil_mul_ovf +| 217 = @cil_mul_ovf_un +| 218 = @cil_sub_ovf +| 219 = @cil_sub_ovf_un +| 220 = @cil_endfinally +| 221 = @cil_leave +| 222 = @cil_leave_s +| 223 = @cil_stind_i +| 224 = @cil_conv_u +| 65024 = @cil_arglist +| 65025 = @cil_ceq +| 65026 = @cil_cgt +| 65027 = @cil_cgt_un +| 65028 = @cil_clt +| 65029 = @cil_clt_un +| 65030 = @cil_ldftn +| 65031 = @cil_ldvirtftn +| 65033 = @cil_ldarg +| 65034 = @cil_ldarga +| 65035 = @cil_starg +| 65036 = @cil_ldloc +| 65037 = @cil_ldloca +| 65038 = @cil_stloc +| 65039 = @cil_localloc +| 65041 = @cil_endfilter +| 65042 = @cil_unaligned +| 65043 = @cil_volatile +| 65044 = @cil_tail +| 65045 = @cil_initobj +| 65046 = @cil_constrained +| 65047 = @cil_cpblk +| 65048 = @cil_initblk +| 65050 = @cil_rethrow +| 65052 = @cil_sizeof +| 65053 = @cil_refanytype +| 65054 = @cil_readonly +; + +// CIL ignored instructions + +@cil_ignore = @cil_nop | @cil_break | @cil_volatile | @cil_unaligned; + +// CIL local/parameter/field access + +@cil_ldarg_any = @cil_ldarg_0 | @cil_ldarg_1 | @cil_ldarg_2 | @cil_ldarg_3 | @cil_ldarg_s | @cil_ldarga_s | @cil_ldarg | @cil_ldarga; +@cil_starg_any = @cil_starg | @cil_starg_s; + +@cil_ldloc_any = @cil_ldloc_0 | @cil_ldloc_1 | @cil_ldloc_2 | @cil_ldloc_3 | @cil_ldloc_s | @cil_ldloca_s | @cil_ldloc | @cil_ldloca; +@cil_stloc_any = @cil_stloc_0 | @cil_stloc_1 | @cil_stloc_2 | @cil_stloc_3 | @cil_stloc_s | @cil_stloc; + +@cil_ldfld_any = @cil_ldfld | @cil_ldsfld | @cil_ldsflda | @cil_ldflda; +@cil_stfld_any = @cil_stfld | @cil_stsfld; + +@cil_local_access = @cil_stloc_any | @cil_ldloc_any; +@cil_arg_access = @cil_starg_any | @cil_ldarg_any; +@cil_read_access = @cil_ldloc_any | @cil_ldarg_any | @cil_ldfld_any; +@cil_write_access = @cil_stloc_any | @cil_starg_any | @cil_stfld_any; + +@cil_stack_access = @cil_local_access | @cil_arg_access; +@cil_field_access = @cil_ldfld_any | @cil_stfld_any; + +@cil_access = @cil_read_access | @cil_write_access; + +// CIL constant/literal instructions + +@cil_ldc_i = @cil_ldc_i4_any | @cil_ldc_i8; + +@cil_ldc_i4_any = @cil_ldc_i4_m1 | @cil_ldc_i4_0 | @cil_ldc_i4_1 | @cil_ldc_i4_2 | @cil_ldc_i4_3 | + @cil_ldc_i4_4 | @cil_ldc_i4_5 | @cil_ldc_i4_6 | @cil_ldc_i4_7 | @cil_ldc_i4_8 | @cil_ldc_i4_s | @cil_ldc_i4; + +@cil_ldc_r = @cil_ldc_r4 | @cil_ldc_r8; + +@cil_literal = @cil_ldnull | @cil_ldc_i | @cil_ldc_r | @cil_ldstr; + +// Control flow + +@cil_conditional_jump = @cil_binary_jump | @cil_unary_jump; +@cil_binary_jump = @cil_beq_s | @cil_bge_s | @cil_bgt_s | @cil_ble_s | @cil_blt_s | + @cil_bne_un_s | @cil_bge_un_s | @cil_bgt_un_s | @cil_ble_un_s | @cil_blt_un_s | + @cil_beq | @cil_bge | @cil_bgt | @cil_ble | @cil_blt | + @cil_bne_un | @cil_bge_un | @cil_bgt_un | @cil_ble_un | @cil_blt_un; +@cil_unary_jump = @cil_brfalse_s | @cil_brtrue_s | @cil_brfalse | @cil_brtrue | @cil_switch; +@cil_unconditional_jump = @cil_br | @cil_br_s | @cil_leave_any; +@cil_leave_any = @cil_leave | @cil_leave_s; +@cil_jump = @cil_unconditional_jump | @cil_conditional_jump; + +// CIL call instructions + +@cil_call_any = @cil_jmp | @cil_call | @cil_calli | @cil_tail | @cil_callvirt | @cil_newobj; + +// CIL expression instructions + +@cil_expr = @cil_literal | @cil_binary_expr | @cil_unary_expr | @cil_call_any | @cil_read_access | + @cil_newarr | @cil_ldtoken | @cil_sizeof | + @cil_ldftn | @cil_ldvirtftn | @cil_localloc | @cil_mkrefany | @cil_refanytype | @cil_arglist | @cil_dup; + +@cil_unary_expr = + @cil_conversion_operation | @cil_unary_arithmetic_operation | @cil_unary_bitwise_operation| + @cil_ldlen | @cil_isinst | @cil_box | @cil_ldobj | @cil_castclass | @cil_unbox_any | + @cil_ldind | @cil_unbox; + +@cil_conversion_operation = + @cil_conv_i1 | @cil_conv_i2 | @cil_conv_i4 | @cil_conv_i8 | + @cil_conv_u1 | @cil_conv_u2 | @cil_conv_u4 | @cil_conv_u8 | + @cil_conv_ovf_i | @cil_conv_ovf_i_un | @cil_conv_ovf_i1 | @cil_conv_ovf_i1_un | + @cil_conv_ovf_i2 | @cil_conv_ovf_i2_un | @cil_conv_ovf_i4 | @cil_conv_ovf_i4_un | + @cil_conv_ovf_i8 | @cil_conv_ovf_i8_un | @cil_conv_ovf_u | @cil_conv_ovf_u_un | + @cil_conv_ovf_u1 | @cil_conv_ovf_u1_un | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_ovf_u4 | @cil_conv_ovf_u4_un | @cil_conv_ovf_u8 | @cil_conv_ovf_u8_un | + @cil_conv_r4 | @cil_conv_r8 | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_i | @cil_conv_u | @cil_conv_r_un; + +@cil_ldind = @cil_ldind_i | @cil_ldind_i1 | @cil_ldind_i2 | @cil_ldind_i4 | @cil_ldind_i8 | + @cil_ldind_r4 | @cil_ldind_r8 | @cil_ldind_ref | @cil_ldind_u1 | @cil_ldind_u2 | @cil_ldind_u4; + +@cil_stind = @cil_stind_i | @cil_stind_i1 | @cil_stind_i2 | @cil_stind_i4 | @cil_stind_i8 | + @cil_stind_r4 | @cil_stind_r8 | @cil_stind_ref; + +@cil_bitwise_operation = @cil_binary_bitwise_operation | @cil_unary_bitwise_operation; + +@cil_binary_bitwise_operation = @cil_and | @cil_or | @cil_xor | @cil_shr | @cil_shr | @cil_shr_un | @cil_shl; + +@cil_binary_arithmetic_operation = @cil_add | @cil_sub | @cil_mul | @cil_div | @cil_div_un | + @cil_rem | @cil_rem_un | @cil_add_ovf | @cil_add_ovf_un | @cil_mul_ovf | @cil_mul_ovf_un | + @cil_sub_ovf | @cil_sub_ovf_un; + +@cil_unary_bitwise_operation = @cil_not; + +@cil_binary_expr = @cil_binary_arithmetic_operation | @cil_binary_bitwise_operation | @cil_read_array | @cil_comparison_operation; + +@cil_unary_arithmetic_operation = @cil_neg; + +@cil_comparison_operation = @cil_cgt_un | @cil_ceq | @cil_cgt | @cil_clt | @cil_clt_un; + +// Elements that retrieve an address of something +@cil_read_ref = @cil_ldloca_s | @cil_ldarga_s | @cil_ldflda | @cil_ldsflda | @cil_ldelema; + +// CIL array instructions + +@cil_read_array = + @cil_ldelem | @cil_ldelema | @cil_ldelem_i1 | @cil_ldelem_ref | @cil_ldelem_i | + @cil_ldelem_i1 | @cil_ldelem_i2 | @cil_ldelem_i4 | @cil_ldelem_i8 | @cil_ldelem_r4 | + @cil_ldelem_r8 | @cil_ldelem_u1 | @cil_ldelem_u2 | @cil_ldelem_u4; + +@cil_write_array = @cil_stelem | @cil_stelem_ref | + @cil_stelem_i | @cil_stelem_i1 | @cil_stelem_i2 | @cil_stelem_i4 | @cil_stelem_i8 | + @cil_stelem_r4 | @cil_stelem_r8; + +@cil_throw_any = @cil_throw | @cil_rethrow; + +#keyset[impl, index] +cil_instruction( + unique int id: @cil_instruction, + int opcode: int ref, + int index: int ref, + int impl: @cil_method_implementation ref); + +cil_jump( + unique int instruction: @cil_jump ref, + int target: @cil_instruction ref); + +cil_access( + unique int instruction: @cil_instruction ref, + int target: @cil_accessible ref); + +cil_value( + unique int instruction: @cil_literal ref, + string value: string ref); + +#keyset[instruction, index] +cil_switch( + int instruction: @cil_switch ref, + int index: int ref, + int target: @cil_instruction ref); + +cil_instruction_location( + unique int id: @cil_instruction ref, + int loc: @location ref); + +cil_type_location( + int id: @cil_type ref, + int loc: @location ref); + +cil_method_location( + int id: @cil_method ref, + int loc: @location ref); + +@cil_namespace = @namespace; + +@cil_type_container = @cil_type | @cil_namespace | @cil_method; + +case @cil_type.kind of + 0 = @cil_valueorreftype +| 1 = @cil_typeparameter +| 2 = @cil_array_type +| 3 = @cil_pointer_type +| 4 = @cil_function_pointer_type +; + +cil_type( + unique int id: @cil_type, + string name: string ref, + int kind: int ref, + int parent: @cil_type_container ref, + int sourceDecl: @cil_type ref); + +cil_pointer_type( + unique int id: @cil_pointer_type ref, + int pointee: @cil_type ref); + +cil_array_type( + unique int id: @cil_array_type ref, + int element_type: @cil_type ref, + int rank: int ref); + +cil_function_pointer_return_type( + unique int id: @cil_function_pointer_type ref, + int return_type: @cil_type ref); + +cil_method( + unique int id: @cil_method, + string name: string ref, + int parent: @cil_type ref, + int return_type: @cil_type ref); + +cil_method_source_declaration( + unique int method: @cil_method ref, + int source: @cil_method ref); + +cil_method_implementation( + unique int id: @cil_method_implementation, + int method: @cil_method ref, + int location: @assembly ref); + +cil_implements( + int id: @cil_method ref, + int decl: @cil_method ref); + +#keyset[parent, name] +cil_field( + unique int id: @cil_field, + int parent: @cil_type ref, + string name: string ref, + int field_type: @cil_type ref); + +@cil_element = @cil_instruction | @cil_declaration | @cil_handler | @cil_attribute | @cil_namespace; +@cil_named_element = @cil_declaration | @cil_namespace; +@cil_declaration = @cil_variable | @cil_method | @cil_type | @cil_member; +@cil_accessible = @cil_declaration; +@cil_variable = @cil_field | @cil_stack_variable; +@cil_stack_variable = @cil_local_variable | @cil_parameter; +@cil_member = @cil_method | @cil_type | @cil_field | @cil_property | @cil_event; +@cil_custom_modifier_receiver = @cil_method | @cil_property | @cil_parameter | @cil_field | @cil_function_pointer_type; +@cil_parameterizable = @cil_method | @cil_function_pointer_type; +@cil_has_type_annotation = @cil_stack_variable | @cil_property | @cil_field | @cil_method | @cil_function_pointer_type; + +#keyset[parameterizable, index] +cil_parameter( + unique int id: @cil_parameter, + int parameterizable: @cil_parameterizable ref, + int index: int ref, + int param_type: @cil_type ref); + +cil_parameter_in(unique int id: @cil_parameter ref); +cil_parameter_out(unique int id: @cil_parameter ref); + +cil_setter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +#keyset[id, modifier] +cil_custom_modifiers( + int id: @cil_custom_modifier_receiver ref, + int modifier: @cil_type ref, + int kind: int ref); // modreq: 1, modopt: 0 + +cil_type_annotation( + int id: @cil_has_type_annotation ref, + int annotation: int ref); + +cil_getter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_adder(unique int event: @cil_event ref, + int method: @cil_method ref); + +cil_remover(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_raiser(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_property( + unique int id: @cil_property, + int parent: @cil_type ref, + string name: string ref, + int property_type: @cil_type ref); + +#keyset[parent, name] +cil_event(unique int id: @cil_event, + int parent: @cil_type ref, + string name: string ref, + int event_type: @cil_type ref); + +#keyset[impl, index] +cil_local_variable( + unique int id: @cil_local_variable, + int impl: @cil_method_implementation ref, + int index: int ref, + int var_type: @cil_type ref); + +cil_function_pointer_calling_conventions( + int id: @cil_function_pointer_type ref, + int kind: int ref); + +// CIL handlers (exception handlers etc). + +case @cil_handler.kind of + 0 = @cil_catch_handler +| 1 = @cil_filter_handler +| 2 = @cil_finally_handler +| 4 = @cil_fault_handler +; + +#keyset[impl, index] +cil_handler( + unique int id: @cil_handler, + int impl: @cil_method_implementation ref, + int index: int ref, + int kind: int ref, + int try_start: @cil_instruction ref, + int try_end: @cil_instruction ref, + int handler_start: @cil_instruction ref); + +cil_handler_filter( + unique int id: @cil_handler ref, + int filter_start: @cil_instruction ref); + +cil_handler_type( + unique int id: @cil_handler ref, + int catch_type: @cil_type ref); + +@cil_controlflow_node = @cil_entry_point | @cil_instruction; + +@cil_entry_point = @cil_method_implementation | @cil_handler; + +@cil_dataflow_node = @cil_instruction | @cil_variable | @cil_method; + +cil_method_stack_size( + unique int method: @cil_method_implementation ref, + int size: int ref); + +// CIL modifiers + +cil_public(int id: @cil_member ref); +cil_private(int id: @cil_member ref); +cil_protected(int id: @cil_member ref); +cil_internal(int id: @cil_member ref); +cil_static(int id: @cil_member ref); +cil_sealed(int id: @cil_member ref); +cil_virtual(int id: @cil_method ref); +cil_abstract(int id: @cil_member ref); +cil_class(int id: @cil_type ref); +cil_interface(int id: @cil_type ref); +cil_security(int id: @cil_member ref); +cil_requiresecobject(int id: @cil_method ref); +cil_specialname(int id: @cil_method ref); +cil_newslot(int id: @cil_method ref); + +cil_base_class(unique int id: @cil_type ref, int base: @cil_type ref); +cil_base_interface(int id: @cil_type ref, int base: @cil_type ref); +cil_enum_underlying_type(unique int id: @cil_type ref, int underlying: @cil_type ref); + +#keyset[unbound, index] +cil_type_parameter( + int unbound: @cil_member ref, + int index: int ref, + int param: @cil_typeparameter ref); + +#keyset[bound, index] +cil_type_argument( + int bound: @cil_member ref, + int index: int ref, + int t: @cil_type ref); + +// CIL type parameter constraints + +cil_typeparam_covariant(int tp: @cil_typeparameter ref); +cil_typeparam_contravariant(int tp: @cil_typeparameter ref); +cil_typeparam_class(int tp: @cil_typeparameter ref); +cil_typeparam_struct(int tp: @cil_typeparameter ref); +cil_typeparam_new(int tp: @cil_typeparameter ref); +cil_typeparam_constraint(int tp: @cil_typeparameter ref, int supertype: @cil_type ref); + +// CIL attributes + +cil_attribute( + unique int attributeid: @cil_attribute, + int element: @cil_declaration ref, + int constructor: @cil_method ref); + +#keyset[attribute_id, param] +cil_attribute_named_argument( + int attribute_id: @cil_attribute ref, + string param: string ref, + string value: string ref); + +#keyset[attribute_id, index] +cil_attribute_positional_argument( + int attribute_id: @cil_attribute ref, + int index: int ref, + string value: string ref); + + +// Common .Net data model covering both C# and CIL + +// Common elements +@dotnet_element = @element | @cil_element; +@dotnet_named_element = @named_element | @cil_named_element; +@dotnet_callable = @callable | @cil_method; +@dotnet_variable = @variable | @cil_variable; +@dotnet_field = @field | @cil_field; +@dotnet_parameter = @parameter | @cil_parameter; +@dotnet_declaration = @declaration | @cil_declaration; +@dotnet_member = @member | @cil_member; +@dotnet_event = @event | @cil_event; +@dotnet_property = @property | @cil_property | @indexer; +@dotnet_parameterizable = @parameterizable | @cil_parameterizable; + +// Common types +@dotnet_type = @type | @cil_type; +@dotnet_call = @call | @cil_call_any; +@dotnet_throw = @throw_element | @cil_throw_any; +@dotnet_valueorreftype = @cil_valueorreftype | @value_or_ref_type | @cil_array_type | @void_type; +@dotnet_typeparameter = @type_parameter | @cil_typeparameter; +@dotnet_array_type = @array_type | @cil_array_type; +@dotnet_pointer_type = @pointer_type | @cil_pointer_type; +@dotnet_type_parameter = @type_parameter | @cil_typeparameter; +@dotnet_generic = @dotnet_valueorreftype | @dotnet_callable; + +// Attributes +@dotnet_attribute = @attribute | @cil_attribute; + +// Expressions +@dotnet_expr = @expr | @cil_expr; + +// Literals +@dotnet_literal = @literal_expr | @cil_literal; +@dotnet_string_literal = @string_literal_expr | @cil_ldstr; +@dotnet_int_literal = @integer_literal_expr | @cil_ldc_i; +@dotnet_float_literal = @float_literal_expr | @cil_ldc_r; +@dotnet_null_literal = @null_literal_expr | @cil_ldnull; + +@metadata_entity = @cil_method | @cil_type | @cil_field | @cil_property | @field | @property | + @callable | @value_or_ref_type | @void_type; + +metadata_handle(int entity : @metadata_entity ref, int location: @assembly ref, int handle: int ref) diff --git a/csharp/ql/lib/upgrades/f145a9a7275c8f457b392b2ebc9f8e07960a0ed2/upgrade.properties b/csharp/ql/lib/upgrades/f145a9a7275c8f457b392b2ebc9f8e07960a0ed2/upgrade.properties new file mode 100644 index 00000000000..9f1b4c72a66 --- /dev/null +++ b/csharp/ql/lib/upgrades/f145a9a7275c8f457b392b2ebc9f8e07960a0ed2/upgrade.properties @@ -0,0 +1,2 @@ +description: Add `compilation_info`. +compatibility: backwards From 397d814c8b83f9b8a3d46f9f260129dde3d3ed65 Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Mon, 5 Feb 2024 13:48:28 +0100 Subject: [PATCH 27/50] Add change note --- csharp/ql/lib/change-notes/2024-02-05-compilation-info.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 csharp/ql/lib/change-notes/2024-02-05-compilation-info.md diff --git a/csharp/ql/lib/change-notes/2024-02-05-compilation-info.md b/csharp/ql/lib/change-notes/2024-02-05-compilation-info.md new file mode 100644 index 00000000000..5a6a3e58fc2 --- /dev/null +++ b/csharp/ql/lib/change-notes/2024-02-05-compilation-info.md @@ -0,0 +1,6 @@ +--- +category: minorAnalysis +--- +* Added a new database relation to store key-value pairs corresponding to compilations. The new relation is used in +buildless mode to surface information related to dependency fetching. + From 24a7a7644d2bae55f7c2bdf329f1c0c2c73482a5 Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Mon, 5 Feb 2024 13:50:20 +0100 Subject: [PATCH 28/50] Remove superfluous conjunct to improve code quality --- csharp/ql/src/Telemetry/ExtractorInformation.ql | 1 - 1 file changed, 1 deletion(-) diff --git a/csharp/ql/src/Telemetry/ExtractorInformation.ql b/csharp/ql/src/Telemetry/ExtractorInformation.ql index 6d015b3e659..d09e1c9d5d3 100644 --- a/csharp/ql/src/Telemetry/ExtractorInformation.ql +++ b/csharp/ql/src/Telemetry/ExtractorInformation.ql @@ -11,7 +11,6 @@ import semmle.code.csharp.commons.Diagnostics predicate compilationInfo(string key, float value) { exists(Compilation c, string infoKey, string infoValue | infoValue = c.getInfo(infoKey) | - exists(infoValue.toFloat()) and key = infoKey and value = infoValue.toFloat() or From 809da54229919d43dcc1499e3c75a19298b6b3de Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Mon, 5 Feb 2024 14:21:13 +0100 Subject: [PATCH 29/50] Revert unneeded changes and simplify code --- .../DependencyManager.cs | 20 +++------ .../NugetPackages.cs | 14 +----- .../Extractor.cs | 9 ++-- .../Program.cs | 45 ------------------- .../Extractor/Analyser.cs | 2 +- 5 files changed, 13 insertions(+), 77 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs index 44925dc1d68..13f8cc4e2a5 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs @@ -157,7 +157,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching return frameworkLocations; } - private void RestoreNugetPackages(List allNonBinaryFiles, List allProjects, List allSolutions, HashSet dllPaths) + private void RestoreNugetPackages(List allNonBinaryFiles, IEnumerable allProjects, IEnumerable allSolutions, HashSet dllPaths) { try { @@ -719,7 +719,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching /// Returns a list of projects that are up to date with respect to restore. /// /// A list of paths to solution files. - private IEnumerable RestoreSolutions(List solutions, out IEnumerable assets) + private IEnumerable RestoreSolutions(IEnumerable solutions, out IEnumerable assets) { var successCount = 0; var assetFiles = new List(); @@ -841,21 +841,13 @@ namespace Semmle.Extraction.CSharp.DependencyFetching if (!res.Success) { logger.LogInfo($"Failed to restore nuget package {package}"); - } - else - { - lock (sync) - { - successCount++; - } + return; } } - else + + lock (sync) { - lock (sync) - { - successCount++; - } + successCount++; } }); diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackages.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackages.cs index 89970a221a1..db0f20bc8cb 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackages.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackages.cs @@ -107,7 +107,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching /// Restore all files in a specified package. /// /// The package file. - private bool RestoreNugetPackage(string package) + private bool TryRestoreNugetPackage(string package) { logger.LogInfo($"Restoring file {package}..."); @@ -157,17 +157,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching /// public int InstallPackages() { - var success = 0; - foreach (var package in packageFiles) - { - var result = RestoreNugetPackage(package.FullName); - if (result) - { - success++; - } - } - - return success; + return packageFiles.Count(package => TryRestoreNugetPackage(package.FullName)); } } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Extractor.cs b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Extractor.cs index 829591818d5..115a8d418b6 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Extractor.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Extractor.cs @@ -5,6 +5,7 @@ using System.Diagnostics; using System.Linq; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; +using Semmle.Extraction.CSharp.DependencyFetching; using Semmle.Util; using Semmle.Util.Logging; @@ -12,7 +13,6 @@ namespace Semmle.Extraction.CSharp.Standalone { public static class Extractor { - private static IEnumerable GetResolvedReferencesStandalone(IEnumerable referencePaths, BlockingCollection references) { return referencePaths.Select(path => () => @@ -138,10 +138,9 @@ namespace Semmle.Extraction.CSharp.Standalone using var logger = new ConsoleLogger(options.Verbosity, logThreadId: true); logger.Log(Severity.Info, "Extracting C# in buildless mode"); - using var a = new Analysis(logger, options); - var sourceFileCount = a.Extraction.Sources.Count; + using var dependencyManager = new DependencyManager(options.SrcDir, options.Dependencies, logger); - if (sourceFileCount == 0) + if (!dependencyManager.AllSourceFiles.Any()) { logger.Log(Severity.Error, "No source files found"); return ExitCode.Errors; @@ -152,7 +151,7 @@ namespace Semmle.Extraction.CSharp.Standalone logger.Log(Severity.Info, ""); logger.Log(Severity.Info, "Extracting..."); ExtractStandalone( - new ExtractionInput(a.Extraction.Sources, a.References, a.CompilationInfos), + new ExtractionInput(dependencyManager.AllSourceFiles, dependencyManager.ReferenceFiles, dependencyManager.CompilationInfos), new ExtractionProgress(logger), fileLogger, options); diff --git a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Program.cs b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Program.cs index 8437896c807..fc13b774f4f 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Program.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Program.cs @@ -5,51 +5,6 @@ using Semmle.Extraction.CSharp.DependencyFetching; namespace Semmle.Extraction.CSharp.Standalone { - /// - /// One independent run of the extractor. - /// - internal class Extraction - { - public Extraction(string directory) - { - Directory = directory; - } - - public string Directory { get; } - public List Sources { get; } = new List(); - }; - - /// - /// Searches for source/references and creates separate extractions. - /// - internal sealed class Analysis : IDisposable - { - public Analysis(ILogger logger, Options options) - { - dependencyManager = new DependencyManager(options.SrcDir, options.Dependencies, logger); - References = dependencyManager.ReferenceFiles; - Extraction = new Extraction(options.SrcDir); - Extraction.Sources.AddRange(dependencyManager.AllSourceFiles); - CompilationInfos = dependencyManager.CompilationInfos; - } - - public IEnumerable References { get; } - - /// - /// The extraction configuration. - /// - public Extraction Extraction { get; } - - public IEnumerable<(string, string)> CompilationInfos { get; } - - private readonly DependencyManager dependencyManager; - - public void Dispose() - { - dependencyManager.Dispose(); - } - }; - public class Program { public static int Main(string[] args) diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Analyser.cs b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Analyser.cs index 51a63cef5f5..c3ed0217559 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Analyser.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Analyser.cs @@ -21,7 +21,7 @@ namespace Semmle.Extraction.CSharp protected CSharpCompilation? compilation; protected CommonOptions? options; private protected Entities.Compilation? compilationEntity; - private TrapWriter? compilationTrapFile; + private IDisposable? compilationTrapFile; private readonly object progressMutex = new object(); From 49dbad96f9162b267524717eb811d1ff6a116772 Mon Sep 17 00:00:00 2001 From: Koen Vlaswinkel Date: Mon, 5 Feb 2024 16:33:01 +0100 Subject: [PATCH 30/50] Switch from details string to DataFlow::Node --- .../modeleditor/FrameworkModeAccessPaths.ql | 58 ++------ .../FrameworkModeAccessPaths.expected | 140 +++++++++--------- 2 files changed, 87 insertions(+), 111 deletions(-) diff --git a/ruby/ql/src/utils/modeleditor/FrameworkModeAccessPaths.ql b/ruby/ql/src/utils/modeleditor/FrameworkModeAccessPaths.ql index e265d813969..a47f8e1cbb4 100644 --- a/ruby/ql/src/utils/modeleditor/FrameworkModeAccessPaths.ql +++ b/ruby/ql/src/utils/modeleditor/FrameworkModeAccessPaths.ql @@ -11,35 +11,7 @@ private import codeql.ruby.AST private import codeql.ruby.ApiGraphs private import queries.modeling.internal.Util as Util -string parameterDetails(DataFlow::ParameterNode paramNode) { - exists(DataFlow::MethodNode methodNode | methodNode.getParameter(_) = paramNode | - result = paramNode.getName() - ) - or - exists(DataFlow::MethodNode methodNode, string name | - methodNode.getKeywordParameter(name) = paramNode - | - result = name + ":" - ) - or - exists(DataFlow::MethodNode methodNode | methodNode.getBlockParameter() = paramNode | - result = "&" + paramNode.getName() - or - not exists(paramNode.getName()) and result = "&" - ) - or - exists(DataFlow::MethodNode methodNode | methodNode.getSelfParameter() = paramNode | - result = "self" - ) - or - exists(DataFlow::MethodNode methodNode | methodNode.getHashSplatParameter() = paramNode | - result = "**" + paramNode.getName() - or - not exists(paramNode.getName()) and result = "**" - ) -} - -predicate simpleParameters(string type, string path, string value, string details) { +predicate simpleParameters(string type, string path, string value, DataFlow::Node details) { exists(DataFlow::MethodNode methodNode, DataFlow::ParameterNode paramNode | methodNode.getLocation().getFile() instanceof Util::RelevantFile and ( @@ -52,11 +24,11 @@ predicate simpleParameters(string type, string path, string value, string detail | Util::pathToMethod(methodNode, type, path) and value = Util::getArgumentPath(paramNode) and - details = parameterDetails(paramNode) + details = paramNode ) } -predicate blockArguments(string type, string path, string value, string details) { +predicate blockArguments(string type, string path, string value, DataFlow::Node details) { exists(DataFlow::MethodNode methodNode, DataFlow::CallNode callNode | methodNode.getLocation().getFile() instanceof Util::RelevantFile and callNode = methodNode.getABlockCall() @@ -66,47 +38,45 @@ predicate blockArguments(string type, string path, string value, string details) argNode = callNode.getPositionalArgument(i) | value = "Argument[block].Parameter[" + i + "]" and - details = argNode.asVariableAccessAstNode().getVariable().getName() + details = argNode ) or exists(DataFlow::ExprNode argNode, string keyword | argNode = callNode.getKeywordArgument(keyword) | value = "Argument[block].Parameter[" + keyword + ":]" and - details = ":" + keyword + details = argNode ) or value = "Argument[block]" and - ( - details = callNode.getMethodName() - or - not exists(callNode.getMethodName()) and - callNode.getExprNode().getExpr() instanceof YieldCall and - details = "yield ..." - ) + details = callNode ) and Util::pathToMethod(methodNode, type, path) ) } -predicate returnValue(string type, string path, string value, string details) { +predicate returnValue(string type, string path, string value, DataFlow::Node details) { exists(DataFlow::MethodNode methodNode, DataFlow::Node returnNode | methodNode.getLocation().getFile() instanceof Util::RelevantFile and returnNode = methodNode.getAReturnNode() | Util::pathToMethod(methodNode, type, path) and value = "ReturnValue" and - details = returnNode.toString() + details = returnNode ) } -predicate inputAccessPaths(string type, string path, string value, string details, string defType) { +predicate inputAccessPaths( + string type, string path, string value, DataFlow::Node details, string defType +) { simpleParameters(type, path, value, details) and defType = "parameter" or blockArguments(type, path, value, details) and defType = "parameter" } -predicate outputAccessPaths(string type, string path, string value, string details, string defType) { +predicate outputAccessPaths( + string type, string path, string value, DataFlow::Node details, string defType +) { simpleParameters(type, path, value, details) and defType = "parameter" or blockArguments(type, path, value, details) and defType = "parameter" diff --git a/ruby/ql/test/query-tests/utils/modeleditor/FrameworkModeAccessPaths.expected b/ruby/ql/test/query-tests/utils/modeleditor/FrameworkModeAccessPaths.expected index c215eb84bdc..6951f1a2322 100644 --- a/ruby/ql/test/query-tests/utils/modeleditor/FrameworkModeAccessPaths.expected +++ b/ruby/ql/test/query-tests/utils/modeleditor/FrameworkModeAccessPaths.expected @@ -1,69 +1,75 @@ input -| A | Method[bar] | Argument[0] | x | parameter | -| A | Method[bar] | Argument[self] | self | parameter | -| A | Method[foo] | Argument[0] | x | parameter | -| A | Method[foo] | Argument[1] | y | parameter | -| A | Method[foo] | Argument[2] | key1: | parameter | -| A | Method[foo] | Argument[block] | call | parameter | -| A | Method[foo] | Argument[block] | yield ... | parameter | -| A | Method[foo] | Argument[block].Parameter[0] | x | parameter | -| A | Method[foo] | Argument[block].Parameter[1] | y | parameter | -| A | Method[foo] | Argument[block].Parameter[key2:] | :key2 | parameter | -| A | Method[foo] | Argument[key1:] | key1: | parameter | -| A | Method[foo] | Argument[self] | self | parameter | -| A! | Method[new] | Argument[0] | x | parameter | -| A! | Method[new] | Argument[1] | y | parameter | -| A! | Method[new] | Argument[self] | self | parameter | -| A! | Method[self_foo] | Argument[0] | x | parameter | -| A! | Method[self_foo] | Argument[1] | y | parameter | -| A! | Method[self_foo] | Argument[self] | self | parameter | -| A::ANested | Method[foo] | Argument[0] | x | parameter | -| A::ANested | Method[foo] | Argument[1] | y | parameter | -| A::ANested | Method[foo] | Argument[self] | self | parameter | -| B | Method[foo] | Argument[0] | x | parameter | -| B | Method[foo] | Argument[1] | y | parameter | -| B | Method[foo] | Argument[self] | self | parameter | -| M1 | Method[foo] | Argument[0] | x | parameter | -| M1 | Method[foo] | Argument[1] | y | parameter | -| M1 | Method[foo] | Argument[self] | self | parameter | -| M1! | Method[self_foo] | Argument[0] | x | parameter | -| M1! | Method[self_foo] | Argument[1] | y | parameter | -| M1! | Method[self_foo] | Argument[self] | self | parameter | -| OtherLib::A | Method[foo] | Argument[0] | x | parameter | -| OtherLib::A | Method[foo] | Argument[1] | y | parameter | -| OtherLib::A | Method[foo] | Argument[self] | self | parameter | +| A | Method[bar] | Argument[0] | lib/mylib.rb:13:11:13:11 | x | parameter | +| A | Method[bar] | Argument[self] | lib/mylib.rb:13:3:14:5 | self in bar | parameter | +| A | Method[foo] | Argument[0] | lib/mylib.rb:7:11:7:11 | x | parameter | +| A | Method[foo] | Argument[1] | lib/mylib.rb:7:14:7:14 | y | parameter | +| A | Method[foo] | Argument[2] | lib/mylib.rb:7:17:7:20 | key1 | parameter | +| A | Method[foo] | Argument[block] | lib/mylib.rb:8:5:8:32 | call to call | parameter | +| A | Method[foo] | Argument[block] | lib/mylib.rb:10:5:10:26 | yield ... | parameter | +| A | Method[foo] | Argument[block].Parameter[0] | lib/mylib.rb:8:16:8:16 | x | parameter | +| A | Method[foo] | Argument[block].Parameter[0] | lib/mylib.rb:10:11:10:11 | x | parameter | +| A | Method[foo] | Argument[block].Parameter[1] | lib/mylib.rb:8:19:8:19 | y | parameter | +| A | Method[foo] | Argument[block].Parameter[1] | lib/mylib.rb:10:14:10:14 | y | parameter | +| A | Method[foo] | Argument[block].Parameter[key2:] | lib/mylib.rb:8:28:8:31 | key1 | parameter | +| A | Method[foo] | Argument[block].Parameter[key2:] | lib/mylib.rb:10:23:10:26 | key1 | parameter | +| A | Method[foo] | Argument[key1:] | lib/mylib.rb:7:17:7:20 | key1 | parameter | +| A | Method[foo] | Argument[self] | lib/mylib.rb:7:3:11:5 | self in foo | parameter | +| A! | Method[new] | Argument[0] | lib/mylib.rb:4:18:4:18 | x | parameter | +| A! | Method[new] | Argument[1] | lib/mylib.rb:4:21:4:21 | y | parameter | +| A! | Method[new] | Argument[self] | lib/mylib.rb:4:3:5:5 | self in initialize | parameter | +| A! | Method[self_foo] | Argument[0] | lib/mylib.rb:16:21:16:21 | x | parameter | +| A! | Method[self_foo] | Argument[1] | lib/mylib.rb:16:24:16:24 | y | parameter | +| A! | Method[self_foo] | Argument[self] | lib/mylib.rb:16:3:17:5 | self in self_foo | parameter | +| A::ANested | Method[foo] | Argument[0] | lib/mylib.rb:25:13:25:13 | x | parameter | +| A::ANested | Method[foo] | Argument[1] | lib/mylib.rb:25:16:25:16 | y | parameter | +| A::ANested | Method[foo] | Argument[self] | lib/mylib.rb:25:5:26:7 | self in foo | parameter | +| B | Method[foo] | Argument[0] | lib/other.rb:6:11:6:11 | x | parameter | +| B | Method[foo] | Argument[1] | lib/other.rb:6:14:6:14 | y | parameter | +| B | Method[foo] | Argument[self] | lib/other.rb:6:3:7:5 | self in foo | parameter | +| M1 | Method[foo] | Argument[0] | lib/module.rb:2:11:2:11 | x | parameter | +| M1 | Method[foo] | Argument[1] | lib/module.rb:2:14:2:14 | y | parameter | +| M1 | Method[foo] | Argument[self] | lib/module.rb:2:3:3:5 | self in foo | parameter | +| M1! | Method[self_foo] | Argument[0] | lib/module.rb:5:21:5:21 | x | parameter | +| M1! | Method[self_foo] | Argument[1] | lib/module.rb:5:24:5:24 | y | parameter | +| M1! | Method[self_foo] | Argument[self] | lib/module.rb:5:3:6:5 | self in self_foo | parameter | +| OtherLib::A | Method[foo] | Argument[0] | other_lib/lib/other_gem.rb:3:17:3:17 | x | parameter | +| OtherLib::A | Method[foo] | Argument[1] | other_lib/lib/other_gem.rb:3:20:3:20 | y | parameter | +| OtherLib::A | Method[foo] | Argument[self] | other_lib/lib/other_gem.rb:3:9:4:11 | self in foo | parameter | output -| A | Method[bar] | Argument[0] | x | parameter | -| A | Method[bar] | Argument[self] | self | parameter | -| A | Method[foo] | Argument[0] | x | parameter | -| A | Method[foo] | Argument[1] | y | parameter | -| A | Method[foo] | Argument[2] | key1: | parameter | -| A | Method[foo] | Argument[block] | call | parameter | -| A | Method[foo] | Argument[block] | yield ... | parameter | -| A | Method[foo] | Argument[block].Parameter[0] | x | parameter | -| A | Method[foo] | Argument[block].Parameter[1] | y | parameter | -| A | Method[foo] | Argument[block].Parameter[key2:] | :key2 | parameter | -| A | Method[foo] | Argument[key1:] | key1: | parameter | -| A | Method[foo] | Argument[self] | self | parameter | -| A | Method[foo] | ReturnValue | yield ... | return | -| A! | Method[new] | Argument[0] | x | parameter | -| A! | Method[new] | Argument[1] | y | parameter | -| A! | Method[new] | Argument[self] | self | parameter | -| A! | Method[self_foo] | Argument[0] | x | parameter | -| A! | Method[self_foo] | Argument[1] | y | parameter | -| A! | Method[self_foo] | Argument[self] | self | parameter | -| A::ANested | Method[foo] | Argument[0] | x | parameter | -| A::ANested | Method[foo] | Argument[1] | y | parameter | -| A::ANested | Method[foo] | Argument[self] | self | parameter | -| B | Method[foo] | Argument[0] | x | parameter | -| B | Method[foo] | Argument[1] | y | parameter | -| B | Method[foo] | Argument[self] | self | parameter | -| M1 | Method[foo] | Argument[0] | x | parameter | -| M1 | Method[foo] | Argument[1] | y | parameter | -| M1 | Method[foo] | Argument[self] | self | parameter | -| M1! | Method[self_foo] | Argument[0] | x | parameter | -| M1! | Method[self_foo] | Argument[1] | y | parameter | -| M1! | Method[self_foo] | Argument[self] | self | parameter | -| OtherLib::A | Method[foo] | Argument[0] | x | parameter | -| OtherLib::A | Method[foo] | Argument[1] | y | parameter | -| OtherLib::A | Method[foo] | Argument[self] | self | parameter | +| A | Method[bar] | Argument[0] | lib/mylib.rb:13:11:13:11 | x | parameter | +| A | Method[bar] | Argument[self] | lib/mylib.rb:13:3:14:5 | self in bar | parameter | +| A | Method[foo] | Argument[0] | lib/mylib.rb:7:11:7:11 | x | parameter | +| A | Method[foo] | Argument[1] | lib/mylib.rb:7:14:7:14 | y | parameter | +| A | Method[foo] | Argument[2] | lib/mylib.rb:7:17:7:20 | key1 | parameter | +| A | Method[foo] | Argument[block] | lib/mylib.rb:8:5:8:32 | call to call | parameter | +| A | Method[foo] | Argument[block] | lib/mylib.rb:10:5:10:26 | yield ... | parameter | +| A | Method[foo] | Argument[block].Parameter[0] | lib/mylib.rb:8:16:8:16 | x | parameter | +| A | Method[foo] | Argument[block].Parameter[0] | lib/mylib.rb:10:11:10:11 | x | parameter | +| A | Method[foo] | Argument[block].Parameter[1] | lib/mylib.rb:8:19:8:19 | y | parameter | +| A | Method[foo] | Argument[block].Parameter[1] | lib/mylib.rb:10:14:10:14 | y | parameter | +| A | Method[foo] | Argument[block].Parameter[key2:] | lib/mylib.rb:8:28:8:31 | key1 | parameter | +| A | Method[foo] | Argument[block].Parameter[key2:] | lib/mylib.rb:10:23:10:26 | key1 | parameter | +| A | Method[foo] | Argument[key1:] | lib/mylib.rb:7:17:7:20 | key1 | parameter | +| A | Method[foo] | Argument[self] | lib/mylib.rb:7:3:11:5 | self in foo | parameter | +| A | Method[foo] | ReturnValue | lib/mylib.rb:10:5:10:26 | yield ... | return | +| A! | Method[new] | Argument[0] | lib/mylib.rb:4:18:4:18 | x | parameter | +| A! | Method[new] | Argument[1] | lib/mylib.rb:4:21:4:21 | y | parameter | +| A! | Method[new] | Argument[self] | lib/mylib.rb:4:3:5:5 | self in initialize | parameter | +| A! | Method[self_foo] | Argument[0] | lib/mylib.rb:16:21:16:21 | x | parameter | +| A! | Method[self_foo] | Argument[1] | lib/mylib.rb:16:24:16:24 | y | parameter | +| A! | Method[self_foo] | Argument[self] | lib/mylib.rb:16:3:17:5 | self in self_foo | parameter | +| A::ANested | Method[foo] | Argument[0] | lib/mylib.rb:25:13:25:13 | x | parameter | +| A::ANested | Method[foo] | Argument[1] | lib/mylib.rb:25:16:25:16 | y | parameter | +| A::ANested | Method[foo] | Argument[self] | lib/mylib.rb:25:5:26:7 | self in foo | parameter | +| B | Method[foo] | Argument[0] | lib/other.rb:6:11:6:11 | x | parameter | +| B | Method[foo] | Argument[1] | lib/other.rb:6:14:6:14 | y | parameter | +| B | Method[foo] | Argument[self] | lib/other.rb:6:3:7:5 | self in foo | parameter | +| M1 | Method[foo] | Argument[0] | lib/module.rb:2:11:2:11 | x | parameter | +| M1 | Method[foo] | Argument[1] | lib/module.rb:2:14:2:14 | y | parameter | +| M1 | Method[foo] | Argument[self] | lib/module.rb:2:3:3:5 | self in foo | parameter | +| M1! | Method[self_foo] | Argument[0] | lib/module.rb:5:21:5:21 | x | parameter | +| M1! | Method[self_foo] | Argument[1] | lib/module.rb:5:24:5:24 | y | parameter | +| M1! | Method[self_foo] | Argument[self] | lib/module.rb:5:3:6:5 | self in self_foo | parameter | +| OtherLib::A | Method[foo] | Argument[0] | other_lib/lib/other_gem.rb:3:17:3:17 | x | parameter | +| OtherLib::A | Method[foo] | Argument[1] | other_lib/lib/other_gem.rb:3:20:3:20 | y | parameter | +| OtherLib::A | Method[foo] | Argument[self] | other_lib/lib/other_gem.rb:3:9:4:11 | self in foo | parameter | From 6a098120e3738038e8ebc97c5996e4b28d358121 Mon Sep 17 00:00:00 2001 From: Koen Vlaswinkel Date: Mon, 5 Feb 2024 16:33:29 +0100 Subject: [PATCH 31/50] Rename details to node --- .../modeleditor/FrameworkModeAccessPaths.ql | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/ruby/ql/src/utils/modeleditor/FrameworkModeAccessPaths.ql b/ruby/ql/src/utils/modeleditor/FrameworkModeAccessPaths.ql index a47f8e1cbb4..d992f1c46f8 100644 --- a/ruby/ql/src/utils/modeleditor/FrameworkModeAccessPaths.ql +++ b/ruby/ql/src/utils/modeleditor/FrameworkModeAccessPaths.ql @@ -11,7 +11,7 @@ private import codeql.ruby.AST private import codeql.ruby.ApiGraphs private import queries.modeling.internal.Util as Util -predicate simpleParameters(string type, string path, string value, DataFlow::Node details) { +predicate simpleParameters(string type, string path, string value, DataFlow::Node node) { exists(DataFlow::MethodNode methodNode, DataFlow::ParameterNode paramNode | methodNode.getLocation().getFile() instanceof Util::RelevantFile and ( @@ -24,11 +24,11 @@ predicate simpleParameters(string type, string path, string value, DataFlow::Nod | Util::pathToMethod(methodNode, type, path) and value = Util::getArgumentPath(paramNode) and - details = paramNode + node = paramNode ) } -predicate blockArguments(string type, string path, string value, DataFlow::Node details) { +predicate blockArguments(string type, string path, string value, DataFlow::Node node) { exists(DataFlow::MethodNode methodNode, DataFlow::CallNode callNode | methodNode.getLocation().getFile() instanceof Util::RelevantFile and callNode = methodNode.getABlockCall() @@ -38,50 +38,50 @@ predicate blockArguments(string type, string path, string value, DataFlow::Node argNode = callNode.getPositionalArgument(i) | value = "Argument[block].Parameter[" + i + "]" and - details = argNode + node = argNode ) or exists(DataFlow::ExprNode argNode, string keyword | argNode = callNode.getKeywordArgument(keyword) | value = "Argument[block].Parameter[" + keyword + ":]" and - details = argNode + node = argNode ) or value = "Argument[block]" and - details = callNode + node = callNode ) and Util::pathToMethod(methodNode, type, path) ) } -predicate returnValue(string type, string path, string value, DataFlow::Node details) { +predicate returnValue(string type, string path, string value, DataFlow::Node node) { exists(DataFlow::MethodNode methodNode, DataFlow::Node returnNode | methodNode.getLocation().getFile() instanceof Util::RelevantFile and returnNode = methodNode.getAReturnNode() | Util::pathToMethod(methodNode, type, path) and value = "ReturnValue" and - details = returnNode + node = returnNode ) } predicate inputAccessPaths( - string type, string path, string value, DataFlow::Node details, string defType + string type, string path, string value, DataFlow::Node node, string defType ) { - simpleParameters(type, path, value, details) and defType = "parameter" + simpleParameters(type, path, value, node) and defType = "parameter" or - blockArguments(type, path, value, details) and defType = "parameter" + blockArguments(type, path, value, node) and defType = "parameter" } predicate outputAccessPaths( - string type, string path, string value, DataFlow::Node details, string defType + string type, string path, string value, DataFlow::Node node, string defType ) { - simpleParameters(type, path, value, details) and defType = "parameter" + simpleParameters(type, path, value, node) and defType = "parameter" or - blockArguments(type, path, value, details) and defType = "parameter" + blockArguments(type, path, value, node) and defType = "parameter" or - returnValue(type, path, value, details) and defType = "return" + returnValue(type, path, value, node) and defType = "return" } query predicate input = inputAccessPaths/5; From e4a4e3af393efb6501ac81d49d68fd1ffab5dfa1 Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Tue, 6 Feb 2024 08:18:27 +0100 Subject: [PATCH 32/50] Update DB stats --- .../ql/lib/semmlecode.csharp.dbscheme.stats | 4225 +++++++++-------- 1 file changed, 2145 insertions(+), 2080 deletions(-) diff --git a/csharp/ql/lib/semmlecode.csharp.dbscheme.stats b/csharp/ql/lib/semmlecode.csharp.dbscheme.stats index acbf07eb460..e217f9cea60 100644 --- a/csharp/ql/lib/semmlecode.csharp.dbscheme.stats +++ b/csharp/ql/lib/semmlecode.csharp.dbscheme.stats @@ -6,7 +6,7 @@ @diagnostic - 138225 + 138224 @extractor_message @@ -22,15 +22,15 @@ @file - 92269 + 92261 @folder - 34266 + 34263 @namespace - 206511 + 206514 @namespace_declaration @@ -41,12 +41,12 @@ 1202 - @using_namespace_directive - 286857 + @directive_if + 20769 - @directive_if - 20770 + @using_namespace_directive + 286854 @directive_elif @@ -61,20 +61,20 @@ 20338 - @directive_endregion - 38815 + @directive_region + 38812 - @directive_region - 38815 + @directive_endregion + 38812 @directive_line - 539554 + 539550 @directive_nullable - 467929 + 467925 @directive_warning @@ -88,21 +88,21 @@ @directive_undefine 68 - - @directive_define - 83 - @pragma_checksum 9570 + + @directive_define + 83 + @pragma_warning 57623 @typeref - 4008630 + 4008699 @bool_type @@ -158,23 +158,23 @@ @enum_type - 163756 + 163759 @struct_type - 716360 + 716372 @class_type - 4319642 + 4319716 @interface_type - 2787029 + 2787078 @delegate_type - 834337 + 834351 @null_type @@ -182,7 +182,7 @@ @type_parameter - 897766 + 897781 @pointer_type @@ -194,7 +194,7 @@ @array_type - 95570 + 95572 @void_type @@ -234,15 +234,15 @@ @attribute_default - 13884494 + 13884733 @attribute_return - 338129 + 338135 @attribute_assembly - 42997 + 42996 @attribute_module @@ -262,15 +262,15 @@ @type_mention - 3321290 - - - @location_default - 154018663 + 3322420 @type_parameter_constraints - 897766 + 897781 + + + @location_default + 154005847 @modifier @@ -278,43 +278,43 @@ @property - 5910461 + 5910563 @indexer - 103348 - - - @event - 60799 + 103350 @getter - 6006793 + 6006897 @setter - 895136 + 895152 + + + @event + 60800 @add_event_accessor - 60799 + 60800 @remove_event_accessor - 60799 + 60800 @operator - 146896 + 146898 @method - 17405743 + 17406043 @constructor - 5023369 + 5023456 @destructor @@ -326,15 +326,15 @@ @addressable_field - 9983265 + 9983437 @constant - 3003952 + 3004004 @addressable_local_variable - 617261 + 617257 @local_constant @@ -346,19 +346,19 @@ @parameter - 31463252 + 31463795 @block_stmt - 797354 + 797317 @expr_stmt - 866011 + 866006 @if_stmt - 371649 + 371632 @switch_stmt @@ -366,7 +366,7 @@ @while_stmt - 23332 + 23333 @do_stmt @@ -374,19 +374,19 @@ @for_stmt - 22829 + 22828 @foreach_stmt - 32476 + 32474 @break_stmt - 115989 + 115991 @continue_stmt - 10335 + 10334 @goto_stmt @@ -402,19 +402,19 @@ @throw_stmt - 175591 + 175588 @return_stmt - 374232 + 374214 @yield_stmt - 7199 + 7198 @try_stmt - 21813 + 21811 @checked_stmt @@ -430,11 +430,11 @@ @using_block_stmt - 9207 + 9206 @var_decl_stmt - 557026 + 557023 @const_decl_stmt @@ -458,11 +458,11 @@ @catch - 30235 + 30233 @case_stmt - 130469 + 130471 @local_function_stmt @@ -470,35 +470,31 @@ @using_decl_stmt - 13938 - - - @xmldtd - 72 + 13937 @bool_literal_expr - 517976 + 517984 @char_literal_expr - 75980 + 75977 @decimal_literal_expr - 185556 + 185559 @int_literal_expr - 4872986 + 4873070 @long_literal_expr - 10294 + 10293 @uint_literal_expr - 10266 + 10265 @ulong_literal_expr @@ -506,7 +502,7 @@ @float_literal_expr - 129367 + 129369 @double_literal_expr @@ -514,35 +510,35 @@ @utf16_string_literal_expr - 1936294 + 1936327 @null_literal_expr - 249869 + 249861 @this_access_expr - 1139948 + 1139940 @base_access_expr - 57395 + 57393 @local_variable_access_expr - 1800146 + 1800136 @parameter_access_expr - 1043216 + 1043167 @field_access_expr - 1360597 + 1361171 @property_access_expr - 1468662 + 1468688 @method_access_expr @@ -554,39 +550,39 @@ @indexer_access_expr - 73965 + 73964 @array_access_expr - 95246 + 95237 @type_access_expr - 1319846 + 1319868 @typeof_expr - 733314 + 733326 @method_invocation_expr - 1292967 + 1292925 @delegate_invocation_expr - 14028 + 14027 @operator_invocation_expr - 53468 + 53469 @cast_expr - 666675 + 666635 @object_creation_expr - 233005 + 232984 @explicit_delegate_creation_expr @@ -598,11 +594,11 @@ @array_creation_expr - 842373 + 842441 @default_expr - 475086 + 475094 @plus_expr @@ -610,7 +606,7 @@ @minus_expr - 83951 + 83947 @bit_not_expr @@ -618,11 +614,11 @@ @log_not_expr - 69873 + 69874 @post_incr_expr - 34721 + 34720 @post_decr_expr @@ -638,7 +634,7 @@ @mul_expr - 13675 + 13674 @div_expr @@ -650,15 +646,15 @@ @add_expr - 89979 + 89975 @sub_expr - 32232 + 32231 @lshift_expr - 20398 + 20397 @rshift_expr @@ -666,11 +662,11 @@ @lt_expr - 42477 + 42475 @gt_expr - 26006 + 26005 @le_expr @@ -682,15 +678,15 @@ @eq_expr - 167785 + 167777 @ne_expr - 126217 + 126219 @bit_and_expr - 19734 + 19733 @bit_xor_expr @@ -698,23 +694,23 @@ @bit_or_expr - 37842 + 37840 @log_and_expr - 64043 + 64040 @log_or_expr - 40881 + 40879 @is_expr - 27102 + 27099 @as_expr - 25540 + 25539 @null_coalescing_expr @@ -722,15 +718,15 @@ @conditional_expr - 25478 + 25477 @simple_assign_expr - 1445790 + 1445815 @assign_add_expr - 10986 + 10985 @assign_sub_expr @@ -770,15 +766,15 @@ @object_init_expr - 192700 + 192703 @collection_init_expr - 17878 + 17877 @array_init_expr - 836437 + 836505 @checked_expr @@ -786,11 +782,11 @@ @unchecked_expr - 2774 + 2773 @constructor_init_expr - 48761 + 48759 @add_event_expr @@ -802,11 +798,11 @@ @local_var_decl_expr - 619056 + 619052 @lambda_expr - 246845 + 246837 @anonymous_method_expr @@ -814,7 +810,7 @@ @pointer_indirection_expr - 8988 + 8987 @address_of_expr @@ -826,15 +822,15 @@ @await_expr - 111126 + 111125 @nameof_expr - 60900 + 60898 @interpolated_string_expr - 45840 + 45841 @unknown_expr @@ -842,7 +838,7 @@ @throw_expr - 6054 + 6053 @tuple_expr @@ -854,7 +850,7 @@ @ref_expr - 3050 + 3049 @discard_expr @@ -886,7 +882,7 @@ @switch_case_expr - 13129 + 13128 @assign_coalesce_expr @@ -914,7 +910,7 @@ @not_pattern_expr - 4716 + 4720 @and_pattern_expr @@ -922,7 +918,7 @@ @or_pattern_expr - 3133 + 3131 @function_pointer_invocation_expr @@ -958,7 +954,7 @@ @define_symbol_expr - 40316 + 40315 @par_expr @@ -984,13 +980,17 @@ @spread_element_expr 15 + + @xmldtd + 72 + @xmlelement - 67061685 + 67055539 @xmlattribute - 45633086 + 45628904 @xmlnamespace @@ -1002,27 +1002,27 @@ @xmlcharacters - 50185384 + 50180784 @singlelinecomment - 835561 + 835522 @xmldoccomment - 1480701 + 1480593 @multilinecomment - 102857 + 102852 @commentblock - 452781 + 452748 @asp_close_tag - 24358 + 24357 @asp_code @@ -1042,15 +1042,15 @@ @asp_open_tag - 33602 + 33601 @asp_quoted_string - 58511 + 58509 @asp_text - 60439 + 60436 @asp_xml_directive @@ -1957,11 +1957,11 @@ 0 - @cil_field + @cil_parameter 0 - @cil_parameter + @cil_field 0 @@ -2056,6 +2056,86 @@ + + compilation_info + 0 + + + id + 0 + + + info_key + 0 + + + info_value + 0 + + + + + id + info_key + + + 12 + + + + + + id + info_value + + + 12 + + + + + + info_key + id + + + 12 + + + + + + info_key + info_value + + + 12 + + + + + + info_value + id + + + 12 + + + + + + info_value + info_key + + + 12 + + + + + + compilation_args 17990 @@ -2354,7 +2434,7 @@ compilation_expanded_args - 593387 + 593382 id @@ -2684,7 +2764,7 @@
    1 2 - 59242 + 59241 2 @@ -2710,7 +2790,7 @@ 1 2 - 59323 + 59322 2 @@ -2730,7 +2810,7 @@ compilation_compiling_files - 49166 + 49163 id @@ -2742,7 +2822,7 @@ file - 33857 + 33855 @@ -2939,57 +3019,62 @@ 1 2 - 23 + 14 2 3 - 897 + 905 3 5 - 140 + 144 5 6 - 729 + 725 6 7 - 84 + 83 7 8 - 326 + 328 8 10 - 281 + 202 10 - 14 - 314 + 13 + 281 - 14 - 21 - 294 + 13 + 19 + 274 - 21 - 67 + 19 + 35 + 267 + + + 35 + 140 263 - 67 - 348 - 157 + 140 + 343 + 21 @@ -3005,7 +3090,7 @@ 1 2 - 21716 + 21715 2 @@ -3031,17 +3116,17 @@ 1 2 - 23811 + 23185 2 3 - 9329 + 9805 3 32 - 716 + 864 @@ -3051,7 +3136,7 @@ compilation_referencing_files - 466141 + 466138 id @@ -3290,57 +3375,57 @@ 1 5 - 343 + 370 5 6 - 499 + 613 6 7 - 890 + 755 7 - 22 + 23 + 370 + + + 23 + 29 377 - - 22 - 29 - 384 - 29 - 36 - 357 - - - 36 - 48 + 33 337 - 48 - 64 + 33 + 46 350 - 64 - 67 - 276 + 46 + 63 + 343 - 67 - 70 + 63 + 69 + 350 + + + 69 + 73 411 - 70 - 80 - 263 + 73 + 83 + 209 @@ -3422,62 +3507,62 @@ 2 5 - 330 + 323 5 6 - 242 + 296 6 7 - 620 + 593 7 - 8 - 310 + 9 + 418 - 8 - 14 - 384 - - - 14 - 23 + 9 + 19 370 - 23 - 30 - 404 + 19 + 26 + 418 - 30 - 37 - 391 + 26 + 33 + 411 - 37 - 66 + 33 + 40 + 384 + + + 40 + 69 + 370 + + + 69 + 71 + 343 + + + 71 + 74 377 - 66 - 70 - 391 - - - 70 - 72 - 310 - - - 72 - 78 - 323 + 74 + 82 + 148 @@ -3487,7 +3572,7 @@ compilation_time - 11250 + 11249 id @@ -3503,7 +3588,7 @@ seconds - 6581 + 6580 @@ -3549,12 +3634,12 @@ 6 7 - 7 + 12 7 8 - 1599 + 1594 @@ -3648,34 +3733,34 @@ 12 - 282 - 283 + 280 + 281 2 - 297 - 298 + 290 + 291 2 - 368 - 369 + 372 + 373 2 - 370 - 371 + 382 + 383 2 - 638 - 639 - 2 + 639 + 640 + 5 640 641 - 5 + 2 @@ -3691,17 +3776,17 @@ 1 2 - 5593 + 5545 2 6 - 524 + 589 6 17 - 463 + 446 @@ -3717,7 +3802,7 @@ 1 2 - 6581 + 6580 @@ -3733,17 +3818,17 @@ 1 2 - 5686 + 5648 2 3 - 428 + 468 3 5 - 466 + 463 @@ -3753,11 +3838,11 @@ diagnostic_for - 138225 + 138224 diagnostic - 138225 + 138224 compilation @@ -3783,7 +3868,7 @@ 1 2 - 138225 + 138224 @@ -3799,7 +3884,7 @@ 1 2 - 138225 + 138224 @@ -3815,7 +3900,7 @@ 1 2 - 138225 + 138224 @@ -4099,11 +4184,11 @@ diagnostics - 138225 + 138224 id - 138225 + 138224 severity @@ -4123,7 +4208,7 @@ location - 138225 + 138224 @@ -4137,7 +4222,7 @@ 1 2 - 138225 + 138224 @@ -4153,7 +4238,7 @@ 1 2 - 138225 + 138224 @@ -4169,7 +4254,7 @@ 1 2 - 138225 + 138224 @@ -4185,7 +4270,7 @@ 1 2 - 138225 + 138224 @@ -4201,7 +4286,7 @@ 1 2 - 138225 + 138224 @@ -4597,7 +4682,7 @@ 1 2 - 138225 + 138224 @@ -4613,7 +4698,7 @@ 1 2 - 138225 + 138224 @@ -4629,7 +4714,7 @@ 1 2 - 138225 + 138224 @@ -4645,7 +4730,7 @@ 1 2 - 138225 + 138224 @@ -4661,7 +4746,7 @@ 1 2 - 138225 + 138224 @@ -4699,7 +4784,7 @@ stack_trace - 295 + 282 @@ -4912,8 +4997,8 @@ 1 - 294 - 295 + 281 + 282 1 @@ -5008,8 +5093,8 @@ 12 - 295 - 296 + 282 + 283 1 @@ -5141,16 +5226,11 @@ 1 2 - 21 - - - 2 - 3 - 36 + 57 3 - 207 + 193 5 @@ -5292,17 +5372,17 @@ 1 2 - 4034 + 4028 2 3 - 491 + 518 3 - 8 - 124 + 12 + 103 @@ -5413,12 +5493,12 @@ 1 2 - 7220 + 7254 2 4 - 413 + 379 @@ -5434,47 +5514,47 @@ 1 2 - 98 + 79 2 3 - 43 + 44 3 4 - 26 + 24 4 6 - 27 + 26 6 - 11 + 9 23 - 11 - 24 - 23 + 9 + 16 + 22 - 24 - 42 + 16 + 34 24 - 45 - 199 - 23 + 35 + 80 + 22 - 229 - 2173 - 8 + 85 + 2137 + 18 @@ -5490,7 +5570,7 @@ 1 2 - 295 + 282 @@ -5506,7 +5586,7 @@ 1 2 - 295 + 282 @@ -5522,11 +5602,11 @@ 1 2 - 292 + 279 2 - 55 + 37 3 @@ -5543,42 +5623,47 @@ 1 2 - 112 + 95 2 3 - 53 + 47 3 4 - 25 + 28 4 - 6 + 5 + 15 + + + 5 + 7 26 - 6 - 13 - 23 + 7 + 17 + 24 - 13 - 29 - 23 + 18 + 37 + 24 - 29 - 97 - 23 + 37 + 609 + 22 - 158 - 778 - 10 + 809 + 810 + 1 @@ -5594,47 +5679,47 @@ 1 2 - 102 + 85 2 3 - 48 + 47 3 4 - 24 + 23 4 5 - 15 + 16 5 7 - 24 - - - 7 - 18 - 24 - - - 18 - 37 26 - 38 - 178 + 7 + 14 + 22 + + + 14 + 30 23 - 192 - 1141 - 9 + 31 + 62 + 22 + + + 63 + 1135 + 18 @@ -5652,11 +5737,11 @@ cpu_seconds - 1123 + 1110 elapsed_seconds - 1602 + 1607 @@ -5702,22 +5787,22 @@ 1 2 - 784 + 772 2 3 - 235 + 220 3 - 5 - 95 + 4 + 87 - 5 - 6 - 7 + 4 + 7 + 30 @@ -5733,22 +5818,22 @@ 1 2 - 784 + 772 2 3 - 235 + 220 3 - 5 - 95 + 4 + 87 - 5 - 6 - 7 + 4 + 7 + 30 @@ -5764,12 +5849,7 @@ 1 2 - 1597 - - - 2 - 3 - 5 + 1607 @@ -5785,12 +5865,7 @@ 1 2 - 1597 - - - 2 - 3 - 5 + 1607 @@ -6003,31 +6078,31 @@ locations_default - 154018663 + 154005847 id - 154018663 + 154005847 file - 85470 + 85462 beginLine - 373111 + 373077 beginColumn - 11199 + 11198 endLine - 387784 + 387748 endColumn - 15840 + 15839 @@ -6041,7 +6116,7 @@ 1 2 - 154018663 + 154005847 @@ -6057,7 +6132,7 @@ 1 2 - 154018663 + 154005847 @@ -6073,7 +6148,7 @@ 1 2 - 154018663 + 154005847 @@ -6089,7 +6164,7 @@ 1 2 - 154018663 + 154005847 @@ -6105,7 +6180,7 @@ 1 2 - 154018663 + 154005847 @@ -6126,22 +6201,22 @@ 14 29 - 6446 + 6445 29 56 - 6476 + 6478 56 99 - 6543 + 6540 99 147 - 6551 + 6550 147 @@ -6156,32 +6231,32 @@ 383 562 - 6486 + 6478 562 - 889 - 6413 + 887 + 6410 - 889 + 887 1560 - 6691 + 6701 1561 2241 - 6659 + 6658 2243 4570 - 6624 + 6623 4570 25909 - 6421 + 6420 26296 @@ -6202,22 +6277,22 @@ 1 9 - 7100 + 7099 9 17 - 7002 + 6999 17 27 - 6799 + 6801 27 44 - 6664 + 6663 44 @@ -6227,12 +6302,12 @@ 65 101 - 6458 + 6455 101 151 - 6997 + 6999 151 @@ -6242,12 +6317,12 @@ 229 401 - 6541 + 6538 401 674 - 6413 + 6415 674 @@ -6257,7 +6332,7 @@ 1032 2141 - 6426 + 6425 2149 @@ -6283,7 +6358,7 @@ 6 10 - 6907 + 6906 10 @@ -6293,17 +6368,17 @@ 18 27 - 7579 + 7578 27 38 - 6844 + 6846 38 51 - 6631 + 6628 51 @@ -6313,7 +6388,7 @@ 64 82 - 6699 + 6698 82 @@ -6323,17 +6398,17 @@ 106 126 - 7544 + 7543 126 167 - 6433 + 6435 167 229 - 6503 + 6500 229 @@ -6354,17 +6429,17 @@ 1 9 - 6955 + 6954 9 18 - 6599 + 6596 18 27 - 6701 + 6703 27 @@ -6374,47 +6449,47 @@ 43 72 - 6521 + 6523 72 112 - 6536 + 6530 112 190 - 7235 + 7237 190 285 - 6899 + 6901 285 - 483 - 6413 + 484 + 6593 - 483 - 830 - 6559 + 484 + 841 + 6410 - 830 - 1376 - 6428 + 841 + 1381 + 7237 - 1378 - 2594 - 6488 + 1381 + 2762 + 6433 - 2594 + 2765 135652 - 5523 + 4733 @@ -6430,12 +6505,12 @@ 1 12 - 7045 + 7044 12 23 - 6832 + 6831 23 @@ -6445,12 +6520,12 @@ 37 51 - 6488 + 6490 51 66 - 6536 + 6533 66 @@ -6460,12 +6535,12 @@ 86 107 - 6556 + 6555 107 131 - 6634 + 6633 131 @@ -6475,22 +6550,22 @@ 153 183 - 7047 + 7049 183 226 - 7123 + 7117 226 304 - 6418 + 6423 304 4355 - 4603 + 4600 @@ -6511,67 +6586,67 @@ 2 3 - 30302 + 30300 3 6 - 29575 + 29573 6 7 - 18315 + 18313 7 9 - 33662 + 33659 9 11 - 28221 + 28219 11 15 - 28337 + 28334 15 21 - 29583 + 29580 21 29 - 28560 + 28557 29 47 - 28700 + 28698 47 84 - 28144 + 28141 84 146 - 28166 + 28164 146 946 - 27993 + 27991 946 - 61760 - 27690 + 61765 + 27687 @@ -6587,67 +6662,67 @@ 1 2 - 39449 + 39445 2 3 - 14324 + 14322 3 4 - 51910 + 51905 4 5 - 40206 + 40202 5 6 - 18776 + 18775 6 7 - 17656 + 17654 7 8 - 20020 + 20018 8 11 - 32037 + 32034 11 20 - 29199 + 29196 20 35 - 29472 + 29470 35 59 - 28078 + 28076 59 366 - 28028 + 28026 366 32788 - 23949 + 23947 @@ -6663,62 +6738,62 @@ 1 2 - 22675 + 22673 2 3 - 54623 + 54618 3 4 - 40512 + 40508 4 5 - 27920 + 27918 5 7 - 32210 + 32207 7 9 - 24089 + 24087 9 12 - 28184 + 28181 12 17 - 31498 + 31495 17 26 - 29134 + 29131 26 43 - 28893 + 28891 43 89 - 28352 + 28349 89 2349 - 25015 + 25012 @@ -6734,47 +6809,47 @@ 1 2 - 58517 + 58511 2 3 - 97605 + 97596 3 4 - 60741 + 60735 4 5 - 32341 + 32338 5 6 - 21888 + 21886 6 8 - 33208 + 33205 8 11 - 30320 + 30317 11 16 - 28221 + 28219 16 1412 - 10267 + 10266 @@ -6790,72 +6865,72 @@ 1 2 - 6654 + 6653 2 3 - 38529 + 38525 3 4 - 21547 + 21545 4 5 - 20664 + 20663 5 6 - 27171 + 27168 6 8 - 31894 + 31892 8 11 - 29791 + 29788 11 15 - 28347 + 28344 15 22 - 31313 + 31310 22 33 - 28342 + 28339 33 53 - 28036 + 28033 53 80 - 28700 + 28698 80 146 - 28271 + 28269 146 4143 - 23846 + 23844 @@ -6910,7 +6985,7 @@ 130043 - 9382463 + 9382473 152 @@ -6927,7 +7002,7 @@ 1 2 - 6496 + 6495 2 @@ -6951,7 +7026,7 @@ 404 - 6302 + 6301 842 @@ -7111,72 +7186,72 @@ 1 2 - 26331 + 26328 2 4 - 28660 + 28657 4 6 - 29382 + 29379 6 7 - 14574 + 14573 7 8 - 21562 + 21560 8 10 - 32504 + 32501 10 14 - 31972 + 31969 14 20 - 29588 + 29585 20 28 - 29498 + 29495 28 45 - 29420 + 29417 45 83 - 29723 + 29720 83 147 - 29116 + 29114 147 987 - 29101 + 29099 987 60323 - 26346 + 26343 @@ -7192,7 +7267,7 @@ 1 2 - 44634 + 44630 2 @@ -7202,57 +7277,57 @@ 3 4 - 39394 + 39390 4 5 - 56862 + 56857 5 7 - 31375 + 31373 7 8 - 17255 + 17253 8 9 - 23846 + 23844 9 13 - 31917 + 31914 13 26 - 29836 + 29833 26 45 - 29711 + 29708 45 78 - 29104 + 29101 78 500 - 29124 + 29121 500 32902 - 22134 + 22132 @@ -7268,47 +7343,47 @@ 1 2 - 86415 + 86407 2 3 - 84936 + 84928 3 4 - 60991 + 60986 4 5 - 31817 + 31814 5 6 - 21344 + 21342 6 8 - 33288 + 33285 8 11 - 30380 + 30377 11 17 - 30789 + 30786 17 72 - 7820 + 7819 @@ -7324,62 +7399,62 @@ 1 2 - 31280 + 31277 2 3 - 44220 + 44216 3 4 - 46033 + 46029 4 5 - 28274 + 28271 5 7 - 35901 + 35898 7 9 - 25601 + 25599 9 12 - 30418 + 30415 12 17 - 33569 + 33566 17 26 - 29864 + 29861 26 44 - 30195 + 30192 44 93 - 29086 + 29084 93 2350 - 23337 + 23335 @@ -7395,72 +7470,72 @@ 1 2 - 33542 + 33539 2 3 - 26053 + 26050 3 4 - 10909 + 10908 4 5 - 37245 + 37242 5 6 - 21221 + 21219 6 8 - 34332 + 34328 8 11 - 28312 + 28309 11 16 - 33379 + 33376 16 24 - 31982 + 31979 24 38 - 30368 + 30365 38 62 - 29808 + 29806 62 102 - 29254 + 29252 102 183 - 29159 + 29156 183 4143 - 12215 + 12214 @@ -7476,12 +7551,12 @@ 1 2 - 10477 + 10476 2 17 - 1216 + 1215 17 @@ -7517,7 +7592,7 @@ 1 2 - 10663 + 10662 2 @@ -7536,13 +7611,13 @@ 337 - 11710 - 1188 + 11711 + 1190 - 11710 - 28030 - 373 + 11721 + 28029 + 371 @@ -7558,7 +7633,7 @@ 1 2 - 10645 + 10644 2 @@ -7573,17 +7648,17 @@ 20 227 - 1190 - - - 228 - 25708 1188 - 26375 + 227 + 25452 + 1188 + + + 25707 121783 - 225 + 228 @@ -7599,12 +7674,12 @@ 1 2 - 11172 + 11171 2 6 - 1414 + 1413 6 @@ -7614,12 +7689,12 @@ 19 123 - 1198 + 1193 123 429 - 817 + 822 @@ -7635,7 +7710,7 @@ 1 2 - 10635 + 10634 2 @@ -7670,15 +7745,15 @@ locations_mapped - 997818 + 997878 id - 997818 + 997878 mapped_to - 757706 + 757768 @@ -7692,7 +7767,7 @@ 1 2 - 997818 + 997878 @@ -7708,12 +7783,12 @@ 1 2 - 683525 + 683587 2 4 - 58534 + 58533 4 @@ -7728,19 +7803,19 @@ numlines - 67413091 + 67406913 element_id - 67412921 + 67406743 num_lines - 8226 + 8225 num_code - 8128 + 8127 num_comment @@ -7758,7 +7833,7 @@ 1 2 - 67412788 + 67406610 2 @@ -7779,7 +7854,7 @@ 1 2 - 67412790 + 67406612 2 @@ -7800,7 +7875,7 @@ 1 2 - 67412908 + 67406730 2 @@ -7846,7 +7921,7 @@ 9 12 - 712 + 711 12 @@ -7918,7 +7993,7 @@ 1 2 - 6120 + 6119 2 @@ -7928,7 +8003,7 @@ 3 7 - 702 + 701 7 @@ -8015,7 +8090,7 @@ 1 2 - 6318 + 6317 2 @@ -8046,7 +8121,7 @@ 1 2 - 6308 + 6307 2 @@ -8475,7 +8550,7 @@ 1 2 - 13266 + 13267 2 @@ -8496,7 +8571,7 @@ 1 2 - 13266 + 13267 2 @@ -8717,15 +8792,15 @@ files - 92269 + 92261 id - 92269 + 92261 name - 92269 + 92261 @@ -8739,7 +8814,7 @@ 1 2 - 92269 + 92261 @@ -8755,7 +8830,7 @@ 1 2 - 92269 + 92261 @@ -8765,15 +8840,15 @@ folders - 34266 + 34263 id - 34266 + 34263 name - 34266 + 34263 @@ -8787,7 +8862,7 @@ 1 2 - 34266 + 34263 @@ -8803,7 +8878,7 @@ 1 2 - 34266 + 34263 @@ -8813,15 +8888,15 @@ containerparent - 126531 + 126520 parent - 34266 + 34263 child - 126531 + 126520 @@ -8835,12 +8910,12 @@ 1 2 - 20885 + 20883 2 3 - 4736 + 4735 3 @@ -8850,17 +8925,17 @@ 4 7 - 3109 + 3108 7 17 - 2600 + 2599 17 546 - 1211 + 1210 @@ -8876,7 +8951,7 @@ 1 2 - 126531 + 126520 @@ -8886,11 +8961,11 @@ file_extraction_mode - 57603 + 57602 file - 57603 + 57602 mode @@ -8908,7 +8983,7 @@ 1 2 - 57603 + 57602 @@ -8934,15 +9009,15 @@ namespaces - 206511 + 206514 id - 206511 + 206514 name - 67588 + 67590 @@ -8956,7 +9031,7 @@ 1 2 - 206511 + 206514 @@ -8972,7 +9047,7 @@ 1 2 - 40635 + 40636 2 @@ -9138,15 +9213,15 @@ parent_namespace - 8107543 + 8107683 child_id - 8107543 + 8107683 namespace_id - 204927 + 204930 @@ -9160,7 +9235,7 @@ 1 2 - 8107543 + 8107683 @@ -9176,22 +9251,22 @@ 1 2 - 43207 + 43208 2 3 - 28475 + 28476 3 4 - 19319 + 19320 4 5 - 13949 + 13950 5 @@ -9211,7 +9286,7 @@ 11 16 - 15595 + 15596 16 @@ -9236,11 +9311,11 @@ parent_namespace_declaration - 185725 + 185724 child_id - 184424 + 184422 namespace_id @@ -9258,7 +9333,7 @@ 1 2 - 184120 + 184119 2 @@ -9309,22 +9384,22 @@ using_global - 9372 + 9371 id - 9372 + 9371 using_namespace_directives - 286857 + 286854 id - 286857 + 286854 namespace_id @@ -9342,7 +9417,7 @@ 1 2 - 286857 + 286854 @@ -9501,15 +9576,15 @@ using_directive_location - 286958 + 286956 id - 286958 + 286956 loc - 286890 + 286888 @@ -9523,7 +9598,7 @@ 1 2 - 286958 + 286956 @@ -9539,7 +9614,7 @@ 1 2 - 286823 + 286821 2 @@ -9554,11 +9629,11 @@ directive_ifs - 20770 + 20769 id - 20770 + 20769 branchTaken @@ -9580,7 +9655,7 @@ 1 2 - 20770 + 20769 @@ -9596,7 +9671,7 @@ 1 2 - 20770 + 20769 @@ -9706,7 +9781,7 @@ parent - 178 + 177 index @@ -10422,7 +10497,7 @@ start - 20770 + 20769 @@ -10452,7 +10527,7 @@ 1 2 - 20770 + 20769 @@ -10462,11 +10537,11 @@ directive_define_symbols - 40316 + 40315 id - 40316 + 40315 name @@ -10484,7 +10559,7 @@ 1 2 - 40316 + 40315 @@ -10565,15 +10640,15 @@ directive_regions - 38815 + 38812 id - 38815 + 38812 name - 18813 + 18812 @@ -10587,7 +10662,7 @@ 1 2 - 38815 + 38812 @@ -10603,7 +10678,7 @@ 1 2 - 15530 + 15529 2 @@ -10628,15 +10703,15 @@ directive_endregions - 38815 + 38812 id - 38815 + 38812 start - 38815 + 38812 @@ -10650,7 +10725,7 @@ 1 2 - 38815 + 38812 @@ -10666,7 +10741,7 @@ 1 2 - 38815 + 38812 @@ -10676,11 +10751,11 @@ directive_lines - 539554 + 539550 id - 539554 + 539550 kind @@ -10698,7 +10773,7 @@ 1 2 - 539554 + 539550 @@ -10739,11 +10814,11 @@ directive_line_value - 119550 + 119549 id - 119550 + 119549 line @@ -10761,7 +10836,7 @@ 1 2 - 119550 + 119549 @@ -10837,11 +10912,11 @@ directive_line_file - 175157 + 175155 id - 175157 + 175155 file @@ -10859,7 +10934,7 @@ 1 2 - 175157 + 175155 @@ -10935,11 +11010,11 @@ directive_line_offset - 55607 + 55606 id - 55607 + 55606 offset @@ -10957,7 +11032,7 @@ 1 2 - 55607 + 55606 @@ -11023,11 +11098,11 @@ directive_line_span - 55607 + 55606 id - 55607 + 55606 startLine @@ -11057,7 +11132,7 @@ 1 2 - 55607 + 55606 @@ -11073,7 +11148,7 @@ 1 2 - 55607 + 55606 @@ -11089,7 +11164,7 @@ 1 2 - 55607 + 55606 @@ -11105,7 +11180,7 @@ 1 2 - 55607 + 55606 @@ -12111,11 +12186,11 @@ directive_nullables - 467929 + 467925 id - 467929 + 467925 setting @@ -12137,7 +12212,7 @@ 1 2 - 467929 + 467925 @@ -12153,7 +12228,7 @@ 1 2 - 467929 + 467925 @@ -12743,7 +12818,7 @@ pragma_warning_error_codes - 57637 + 57636 id @@ -12769,7 +12844,7 @@ 1 2 - 57610 + 57609 2 @@ -12790,7 +12865,7 @@ 1 2 - 57610 + 57609 2 @@ -12914,15 +12989,15 @@ preprocessor_directive_location - 1075331 + 1075323 id - 1075331 + 1075323 loc - 1075331 + 1075323 @@ -12936,7 +13011,7 @@ 1 2 - 1075331 + 1075323 @@ -12952,7 +13027,7 @@ 1 2 - 1075331 + 1075323 @@ -12962,11 +13037,11 @@ preprocessor_directive_compilation - 1075331 + 1075323 id - 1075331 + 1075323 compilation @@ -12984,7 +13059,7 @@ 1 2 - 1075331 + 1075323 @@ -13070,11 +13145,11 @@ preprocessor_directive_active - 1075331 + 1075323 id - 1075331 + 1075323 active @@ -13092,7 +13167,7 @@ 1 2 - 1075331 + 1075323 @@ -13123,11 +13198,11 @@ types - 9818809 + 9818978 id - 9818809 + 9818978 kind @@ -13135,7 +13210,7 @@ name - 2815649 + 2815698 @@ -13149,7 +13224,7 @@ 1 2 - 9818809 + 9818978 @@ -13165,7 +13240,7 @@ 1 2 - 9818809 + 9818978 @@ -13268,17 +13343,17 @@ 1 2 - 2509678 + 2509722 2 4 - 213897 + 213901 4 26166 - 92073 + 92074 @@ -13294,12 +13369,12 @@ 1 2 - 2793613 + 2793662 2 7 - 22035 + 22036 @@ -13309,15 +13384,15 @@ typerefs - 4008630 + 4008699 id - 4008630 + 4008699 name - 2703433 + 2703480 @@ -13331,7 +13406,7 @@ 1 2 - 4008630 + 4008699 @@ -13347,12 +13422,12 @@ 1 2 - 2495770 + 2495813 2 17 - 202807 + 202811 17 @@ -13367,15 +13442,15 @@ typeref_type - 3978097 + 3978165 id - 3978097 + 3978165 typeId - 3978097 + 3978165 @@ -13389,7 +13464,7 @@ 1 2 - 3978097 + 3978165 @@ -13405,7 +13480,7 @@ 1 2 - 3978097 + 3978165 @@ -13415,11 +13490,11 @@ array_element_type - 95570 + 95572 array - 95570 + 95572 dimension @@ -13431,7 +13506,7 @@ element - 95262 + 95263 @@ -13445,7 +13520,7 @@ 1 2 - 95570 + 95572 @@ -13461,7 +13536,7 @@ 1 2 - 95570 + 95572 @@ -13477,7 +13552,7 @@ 1 2 - 95570 + 95572 @@ -13639,7 +13714,7 @@ 1 2 - 94994 + 94996 2 @@ -13660,7 +13735,7 @@ 1 2 - 95262 + 95263 @@ -13676,7 +13751,7 @@ 1 2 - 94994 + 94996 2 @@ -13787,11 +13862,11 @@ enum_underlying_type - 163756 + 163759 enum_id - 163756 + 163759 underlying_type_id @@ -13809,7 +13884,7 @@ 1 2 - 163756 + 163759 @@ -13870,15 +13945,15 @@ delegate_return_type - 834337 + 834351 delegate_id - 834337 + 834351 return_type_id - 303790 + 303795 @@ -13892,7 +13967,7 @@ 1 2 - 834337 + 834351 @@ -13908,12 +13983,12 @@ 1 2 - 269759 + 269763 2 4 - 24463 + 24464 4 @@ -13996,15 +14071,15 @@ extend - 3329675 + 3329732 sub - 3329078 + 3329136 super - 487957 + 487965 @@ -14018,7 +14093,7 @@ 1 2 - 3328482 + 3328539 2 @@ -14039,22 +14114,22 @@ 1 2 - 330578 + 330584 2 3 - 75736 + 75737 3 5 - 43783 + 43784 5 97 - 36602 + 36603 97 @@ -14080,15 +14155,15 @@ implement - 11230275 + 11230469 sub - 3882135 + 3882202 super - 2387792 + 2387833 @@ -14102,32 +14177,32 @@ 1 2 - 1315813 + 1315836 2 3 - 1049078 + 1049097 3 4 - 724754 + 724767 4 6 - 297638 + 297643 6 9 - 320620 + 320626 9 31 - 174229 + 174232 @@ -14143,27 +14218,27 @@ 1 2 - 1138518 + 1138538 2 3 - 715557 + 715570 3 5 - 204988 + 204992 5 6 - 182006 + 182009 6 109829 - 146720 + 146722 @@ -14173,11 +14248,11 @@ type_location - 5294918 + 5295009 id - 5063017 + 5063104 loc @@ -14195,12 +14270,12 @@ 1 2 - 4974730 + 4974816 2 551 - 88287 + 88288 @@ -14216,7 +14291,7 @@ 1 2 - 2324 + 2325 2 @@ -14329,11 +14404,11 @@ tuple_element - 115837 + 115839 tuple - 47178 + 47179 index @@ -14341,7 +14416,7 @@ field - 115837 + 115839 @@ -14649,7 +14724,7 @@ 1 2 - 115837 + 115839 @@ -14665,7 +14740,7 @@ 1 2 - 115837 + 115839 @@ -14675,11 +14750,11 @@ attributes - 14223261 + 14223506 id - 14223261 + 14223506 kind @@ -14691,7 +14766,7 @@ target - 12263944 + 12264155 @@ -14705,7 +14780,7 @@ 1 2 - 14223261 + 14223506 @@ -14721,7 +14796,7 @@ 1 2 - 14223261 + 14223506 @@ -14737,7 +14812,7 @@ 1 2 - 14223261 + 14223506 @@ -15004,17 +15079,17 @@ 1 2 - 11192109 + 11192302 2 4 - 963404 + 963421 4 4012 - 108430 + 108432 @@ -15030,12 +15105,12 @@ 1 2 - 12146728 + 12146937 2 3 - 117215 + 117217 @@ -15051,12 +15126,12 @@ 1 2 - 11399937 + 11400133 2 29 - 864006 + 864021 @@ -15066,11 +15141,11 @@ attribute_location - 14224002 + 14224247 id - 14223261 + 14223506 loc @@ -15088,7 +15163,7 @@ 1 2 - 14222541 + 14222786 2 @@ -15179,19 +15254,19 @@ type_mention - 3321290 + 3322420 id - 3321290 + 3322420 type_id - 93833 + 93831 parent - 2593907 + 2594238 @@ -15205,7 +15280,7 @@ 1 2 - 3321290 + 3322420 @@ -15221,7 +15296,7 @@ 1 2 - 3321290 + 3322420 @@ -15242,52 +15317,52 @@ 2 3 - 18104 + 18106 3 4 - 10214 + 10207 4 5 - 7731 + 7735 5 6 - 4996 + 4991 6 7 - 6410 + 6347 7 10 - 7565 + 7628 10 16 - 7147 + 7154 16 36 - 7084 + 7080 36 - 1554 + 1547 7038 - 1562 - 103797 - 238 + 1553 + 103831 + 240 @@ -15303,7 +15378,7 @@ 1 2 - 29401 + 29400 2 @@ -15313,12 +15388,12 @@ 3 4 - 7880 + 7878 4 5 - 6972 + 6975 5 @@ -15328,17 +15403,17 @@ 6 8 - 7353 + 7304 8 13 - 7518 + 7530 13 30 - 7045 + 7082 30 @@ -15347,7 +15422,7 @@ 949 - 77995 + 78000 275 @@ -15364,17 +15439,17 @@ 1 2 - 2213046 + 2213261 2 3 - 271676 + 271774 3 851 - 109183 + 109202 @@ -15390,12 +15465,12 @@ 1 2 - 2538060 + 2538267 2 40 - 55846 + 55971 @@ -15405,15 +15480,15 @@ type_mention_location - 3321290 + 3322420 id - 3321290 + 3322420 loc - 2857143 + 2857079 @@ -15427,7 +15502,7 @@ 1 2 - 3321290 + 3322420 @@ -15443,12 +15518,12 @@ 1 2 - 2673133 + 2673027 2 213 - 184009 + 184052 @@ -15458,11 +15533,11 @@ type_annotation - 924250 + 924266 id - 924250 + 924266 annotation @@ -15480,7 +15555,7 @@ 1 2 - 924250 + 924266 @@ -15574,7 +15649,7 @@ nullability_parent - 83203 + 83204 nullability @@ -15855,7 +15930,7 @@ 7 14 - 1920 + 1921 14 @@ -15870,11 +15945,11 @@ type_nullability - 40400690 + 40401386 id - 40392995 + 40393691 nullability @@ -15892,7 +15967,7 @@ 1 2 - 40385793 + 40386490 2 @@ -15968,11 +16043,11 @@ expr_flowstate - 6546823 + 6545248 id - 6546823 + 6545248 state @@ -15990,7 +16065,7 @@ 1 2 - 6546823 + 6545248 @@ -16004,13 +16079,13 @@ 12 - 238162 - 238163 + 238130 + 238131 2 - 2567260 - 2567261 + 2566670 + 2566671 2 @@ -16021,11 +16096,11 @@ type_parameters - 897766 + 897781 id - 897766 + 897781 index @@ -16033,7 +16108,7 @@ generic_id - 486432 + 486441 variance @@ -16051,7 +16126,7 @@ 1 2 - 897766 + 897781 @@ -16067,7 +16142,7 @@ 1 2 - 897766 + 897781 @@ -16083,7 +16158,7 @@ 1 2 - 897766 + 897781 @@ -16297,17 +16372,17 @@ 1 2 - 356465 + 356471 2 3 - 75219 + 75220 3 9 - 38239 + 38240 9 @@ -16328,17 +16403,17 @@ 1 2 - 356465 + 356471 2 3 - 75219 + 75220 3 9 - 38239 + 38240 9 @@ -16359,7 +16434,7 @@ 1 2 - 485232 + 485240 2 @@ -16452,11 +16527,11 @@ type_arguments - 6159213 + 6159319 id - 1600674 + 1600702 index @@ -16464,7 +16539,7 @@ constructed_id - 4581294 + 4581373 @@ -16478,12 +16553,12 @@ 1 2 - 1361387 + 1361410 2 3 - 218979 + 218983 3 @@ -16504,37 +16579,37 @@ 1 2 - 707019 + 707031 2 3 - 283071 + 283075 3 4 - 199371 + 199375 4 5 - 99480 + 99481 5 7 - 121824 + 121826 7 11 - 126474 + 126476 11 10327 - 63432 + 63433 @@ -16712,17 +16787,17 @@ 1 2 - 3249206 + 3249262 2 3 - 1220160 + 1220181 3 22 - 111928 + 111930 @@ -16738,17 +16813,17 @@ 1 2 - 3213261 + 3213317 2 3 - 1223987 + 1224008 3 22 - 144045 + 144048 @@ -16758,15 +16833,15 @@ constructed_generic - 4581294 + 4581373 constructed - 4581294 + 4581373 generic - 89830 + 89832 @@ -16780,7 +16855,7 @@ 1 2 - 4581294 + 4581373 @@ -16846,15 +16921,15 @@ type_parameter_constraints - 897766 + 897781 id - 897766 + 897781 param_id - 897766 + 897781 @@ -16868,7 +16943,7 @@ 1 2 - 897766 + 897781 @@ -16884,7 +16959,7 @@ 1 2 - 897766 + 897781 @@ -16930,11 +17005,11 @@ general_type_parameter_constraints - 345681 + 345670 id - 344379 + 344368 kind @@ -16952,7 +17027,7 @@ 1 2 - 343078 + 343067 2 @@ -17003,15 +17078,15 @@ specific_type_parameter_constraints - 250871 + 250875 id - 244698 + 244702 base_id - 45347 + 45348 @@ -17025,7 +17100,7 @@ 1 2 - 240110 + 240114 2 @@ -17076,11 +17151,11 @@ specific_type_parameter_nullability - 44236 + 44237 id - 43989 + 43990 base_id @@ -17102,7 +17177,7 @@ 1 2 - 43742 + 43743 2 @@ -17123,7 +17198,7 @@ 1 2 - 43989 + 43990 @@ -17468,11 +17543,11 @@ has_modifiers - 86999480 + 87000980 id - 57380757 + 57381746 mod_id @@ -17490,17 +17565,17 @@ 1 2 - 29261602 + 29262107 2 3 - 26624852 + 26625311 3 5 - 1494301 + 1494327 @@ -17601,11 +17676,11 @@ compiler_generated - 479150 + 479159 id - 479150 + 479159 @@ -17710,19 +17785,19 @@ nested_types - 1913887 + 1913920 id - 1913887 + 1913920 declaring_type_id - 774464 + 774477 unbound_id - 1613719 + 1613746 @@ -17736,7 +17811,7 @@ 1 2 - 1913887 + 1913920 @@ -17752,7 +17827,7 @@ 1 2 - 1913887 + 1913920 @@ -17768,27 +17843,27 @@ 1 2 - 455139 + 455147 2 3 - 135877 + 135879 3 4 - 62321 + 62322 4 6 - 58083 + 58084 6 22 - 58165 + 58166 22 @@ -17809,27 +17884,27 @@ 1 2 - 456662 + 456670 2 3 - 136247 + 136250 3 4 - 61951 + 61952 4 6 - 58042 + 58043 6 24 - 58289 + 58290 24 @@ -17850,12 +17925,12 @@ 1 2 - 1556417 + 1556444 2 691 - 57301 + 57302 @@ -17871,12 +17946,12 @@ 1 2 - 1565861 + 1565888 2 691 - 47857 + 47858 @@ -17886,27 +17961,27 @@ properties - 5910461 + 5910563 id - 5910461 + 5910563 name - 1742991 + 1743021 declaring_type_id - 1511276 + 1511302 type_id - 597519 + 597529 unbound_id - 5336459 + 5336551 @@ -17920,7 +17995,7 @@ 1 2 - 5910461 + 5910563 @@ -17936,7 +18011,7 @@ 1 2 - 5910461 + 5910563 @@ -17952,7 +18027,7 @@ 1 2 - 5910461 + 5910563 @@ -17968,7 +18043,7 @@ 1 2 - 5910461 + 5910563 @@ -17984,22 +18059,22 @@ 1 2 - 1266289 + 1266311 2 3 - 219638 + 219642 3 6 - 146638 + 146640 6 9450 - 110426 + 110428 @@ -18015,22 +18090,22 @@ 1 2 - 1267276 + 1267298 2 3 - 219165 + 219168 3 6 - 146905 + 146908 6 5564 - 109644 + 109646 @@ -18046,12 +18121,12 @@ 1 2 - 1585099 + 1585126 2 6 - 137852 + 137854 6 @@ -18072,22 +18147,22 @@ 1 2 - 1273223 + 1273245 2 3 - 224370 + 224374 3 6 - 144621 + 144624 6 8011 - 100776 + 100778 @@ -18103,37 +18178,37 @@ 1 2 - 549785 + 549794 2 3 - 348705 + 348711 3 4 - 196244 + 196247 4 5 - 130466 + 130468 5 7 - 125363 + 125365 7 14 - 113965 + 113966 14 3362 - 46746 + 46747 @@ -18149,37 +18224,37 @@ 1 2 - 630048 + 630059 2 3 - 270293 + 270298 3 4 - 196656 + 196659 4 5 - 132626 + 132628 5 7 - 125198 + 125201 7 15 - 117359 + 117361 15 3362 - 39092 + 39093 @@ -18195,32 +18270,32 @@ 1 2 - 636488 + 636499 2 3 - 426026 + 426033 3 4 - 180895 + 180898 4 5 - 100282 + 100284 5 9 - 124252 + 124254 9 56 - 43330 + 43331 @@ -18236,37 +18311,37 @@ 1 2 - 549785 + 549794 2 3 - 348705 + 348711 3 4 - 196244 + 196247 4 5 - 130466 + 130468 5 7 - 125363 + 125365 7 14 - 113965 + 113966 14 3362 - 46746 + 46747 @@ -18282,27 +18357,27 @@ 1 2 - 329611 + 329617 2 3 - 122709 + 122711 3 4 - 38804 + 38805 4 7 - 51540 + 51541 7 36 - 44956 + 44957 36 @@ -18323,17 +18398,17 @@ 1 2 - 477422 + 477430 2 3 - 66539 + 66540 3 11 - 44976 + 44977 11 @@ -18354,12 +18429,12 @@ 1 2 - 345660 + 345666 2 3 - 117894 + 117896 3 @@ -18369,12 +18444,12 @@ 4 7 - 46890 + 46891 7 66 - 44832 + 44833 66 @@ -18395,17 +18470,17 @@ 1 2 - 331340 + 331345 2 3 - 125075 + 125077 3 4 - 38804 + 38805 4 @@ -18415,12 +18490,12 @@ 7 45 - 44976 + 44977 45 72507 - 6830 + 6831 @@ -18436,12 +18511,12 @@ 1 2 - 5254406 + 5254497 2 1890 - 82053 + 82054 @@ -18457,7 +18532,7 @@ 1 2 - 5336459 + 5336551 @@ -18473,12 +18548,12 @@ 1 2 - 5254406 + 5254497 2 1890 - 82053 + 82054 @@ -18494,7 +18569,7 @@ 1 2 - 5319300 + 5319391 2 @@ -18509,11 +18584,11 @@ property_location - 6046297 + 6046401 id - 5910461 + 5910563 loc @@ -18531,12 +18606,12 @@ 1 2 - 5818182 + 5818282 2 34 - 92278 + 92280 @@ -18622,11 +18697,11 @@ indexers - 103348 + 103350 id - 103348 + 103350 name @@ -18634,7 +18709,7 @@ declaring_type_id - 92628 + 92630 type_id @@ -18656,7 +18731,7 @@ 1 2 - 103348 + 103350 @@ -18672,7 +18747,7 @@ 1 2 - 103348 + 103350 @@ -18688,7 +18763,7 @@ 1 2 - 103348 + 103350 @@ -18704,7 +18779,7 @@ 1 2 - 103348 + 103350 @@ -18879,7 +18954,7 @@ 1 2 - 83575 + 83577 2 @@ -18905,7 +18980,7 @@ 1 2 - 92566 + 92568 2 @@ -18926,7 +19001,7 @@ 1 2 - 87649 + 87651 2 @@ -18947,7 +19022,7 @@ 1 2 - 83575 + 83577 2 @@ -18978,7 +19053,7 @@ 2 3 - 6295 + 6296 3 @@ -19009,7 +19084,7 @@ 1 2 - 21747 + 21748 2 @@ -19160,7 +19235,7 @@ 1 2 - 29895 + 29896 2 @@ -19175,11 +19250,11 @@ indexer_location - 104747 + 104749 id - 103348 + 103350 loc @@ -19197,7 +19272,7 @@ 1 2 - 101949 + 101950 2 @@ -19268,11 +19343,11 @@ accessors - 6901930 + 6902049 id - 6901930 + 6902049 kind @@ -19280,15 +19355,15 @@ name - 2155562 + 2155599 declaring_member_id - 6013027 + 6013131 unbound_id - 6177257 + 6177364 @@ -19302,7 +19377,7 @@ 1 2 - 6901930 + 6902049 @@ -19318,7 +19393,7 @@ 1 2 - 6901930 + 6902049 @@ -19334,7 +19409,7 @@ 1 2 - 6901930 + 6902049 @@ -19350,7 +19425,7 @@ 1 2 - 6901930 + 6902049 @@ -19450,22 +19525,22 @@ 1 2 - 1548043 + 1548070 2 3 - 284449 + 284454 3 6 - 187253 + 187256 6 3848 - 135815 + 135818 @@ -19481,7 +19556,7 @@ 1 2 - 2155397 + 2155434 2 @@ -19502,22 +19577,22 @@ 1 2 - 1548043 + 1548070 2 3 - 284449 + 284454 3 6 - 187253 + 187256 6 3848 - 135815 + 135818 @@ -19533,22 +19608,22 @@ 1 2 - 1560512 + 1560539 2 3 - 291383 + 291388 3 6 - 181080 + 181083 6 3822 - 122585 + 122588 @@ -19564,12 +19639,12 @@ 1 2 - 5124125 + 5124213 2 3 - 888902 + 888917 @@ -19585,12 +19660,12 @@ 1 2 - 5124125 + 5124213 2 3 - 888902 + 888917 @@ -19606,12 +19681,12 @@ 1 2 - 5125051 + 5125139 2 3 - 887976 + 887991 @@ -19627,12 +19702,12 @@ 1 2 - 5124125 + 5124213 2 3 - 888902 + 888917 @@ -19648,12 +19723,12 @@ 1 2 - 6082118 + 6082223 2 1890 - 95138 + 95140 @@ -19669,7 +19744,7 @@ 1 2 - 6177257 + 6177364 @@ -19685,7 +19760,7 @@ 1 2 - 6177257 + 6177364 @@ -19701,12 +19776,12 @@ 1 2 - 6082118 + 6082223 2 1890 - 95138 + 95140 @@ -19727,11 +19802,11 @@ accessor_location - 7067127 + 7067248 id - 6901930 + 6902049 loc @@ -19749,12 +19824,12 @@ 1 2 - 6784549 + 6784666 2 34 - 117380 + 117382 @@ -19840,11 +19915,11 @@ events - 60799 + 60800 id - 60799 + 60800 name @@ -19852,7 +19927,7 @@ declaring_type_id - 25224 + 25225 type_id @@ -19860,7 +19935,7 @@ unbound_id - 54029 + 54030 @@ -19874,7 +19949,7 @@ 1 2 - 60799 + 60800 @@ -19890,7 +19965,7 @@ 1 2 - 60799 + 60800 @@ -19906,7 +19981,7 @@ 1 2 - 60799 + 60800 @@ -19922,7 +19997,7 @@ 1 2 - 60799 + 60800 @@ -20041,7 +20116,7 @@ 2 3 - 5472 + 5473 3 @@ -20216,7 +20291,7 @@ 1 2 - 7797 + 7798 2 @@ -20350,7 +20425,7 @@ 1 2 - 52219 + 52220 2 @@ -20371,7 +20446,7 @@ 1 2 - 54029 + 54030 @@ -20387,7 +20462,7 @@ 1 2 - 52219 + 52220 2 @@ -20408,7 +20483,7 @@ 1 2 - 53700 + 53701 2 @@ -20423,7 +20498,7 @@ event_location - 73181 + 73180 id @@ -20496,11 +20571,11 @@ event_accessors - 121598 + 121600 id - 121598 + 121600 kind @@ -20512,11 +20587,11 @@ declaring_event_id - 60799 + 60800 unbound_id - 108059 + 108061 @@ -20530,7 +20605,7 @@ 1 2 - 121598 + 121600 @@ -20546,7 +20621,7 @@ 1 2 - 121598 + 121600 @@ -20562,7 +20637,7 @@ 1 2 - 121598 + 121600 @@ -20578,7 +20653,7 @@ 1 2 - 121598 + 121600 @@ -20746,7 +20821,7 @@ 1 2 - 31232 + 31233 2 @@ -20782,7 +20857,7 @@ 2 3 - 60799 + 60800 @@ -20798,7 +20873,7 @@ 2 3 - 60799 + 60800 @@ -20814,7 +20889,7 @@ 2 3 - 60799 + 60800 @@ -20830,7 +20905,7 @@ 2 3 - 60799 + 60800 @@ -20846,7 +20921,7 @@ 1 2 - 104438 + 104440 2 @@ -20867,7 +20942,7 @@ 1 2 - 108059 + 108061 @@ -20883,7 +20958,7 @@ 1 2 - 108059 + 108061 @@ -20899,7 +20974,7 @@ 1 2 - 104438 + 104440 2 @@ -20914,7 +20989,7 @@ event_accessor_location - 146362 + 146361 id @@ -20987,11 +21062,11 @@ operators - 146896 + 146898 id - 146896 + 146898 name @@ -21007,11 +21082,11 @@ type_id - 22451 + 22452 unbound_id - 119041 + 119043 @@ -21025,7 +21100,7 @@ 1 2 - 146896 + 146898 @@ -21041,7 +21116,7 @@ 1 2 - 146896 + 146898 @@ -21057,7 +21132,7 @@ 1 2 - 146896 + 146898 @@ -21073,7 +21148,7 @@ 1 2 - 146896 + 146898 @@ -21089,7 +21164,7 @@ 1 2 - 146896 + 146898 @@ -21828,7 +21903,7 @@ 1 2 - 22451 + 22452 2 @@ -21956,7 +22031,7 @@ 1 2 - 16988 + 16989 2 @@ -21987,12 +22062,12 @@ 1 2 - 16988 + 16989 2 4 - 1920 + 1921 4 @@ -22018,7 +22093,7 @@ 1 2 - 19089 + 19090 2 @@ -22090,7 +22165,7 @@ 1 2 - 116100 + 116102 2 @@ -22111,7 +22186,7 @@ 1 2 - 119041 + 119043 @@ -22127,7 +22202,7 @@ 1 2 - 119041 + 119043 @@ -22143,7 +22218,7 @@ 1 2 - 116100 + 116102 2 @@ -22164,7 +22239,7 @@ 1 2 - 116280 + 116282 2 @@ -22179,15 +22254,15 @@ operator_location - 238354 + 238350 id - 94950 + 94949 loc - 10923 + 10928 @@ -22206,7 +22281,7 @@ 2 3 - 76788 + 76786 3 @@ -22237,7 +22312,7 @@ 2 5 - 865 + 870 5 @@ -22257,15 +22332,15 @@ constant_value - 3005248 + 3005300 id - 3003952 + 3004004 value - 955297 + 955314 @@ -22279,7 +22354,7 @@ 1 2 - 3003067 + 3003119 2 @@ -22300,17 +22375,17 @@ 1 2 - 763559 + 763572 2 3 - 102052 + 102053 3 9 - 73061 + 73063 9 @@ -22325,27 +22400,27 @@ methods - 17405743 + 17406043 id - 17405743 + 17406043 name - 4654192 + 4654272 declaring_type_id - 3635132 + 3635194 type_id - 1167652 + 1167672 unbound_id - 14310664 + 14310911 @@ -22359,7 +22434,7 @@ 1 2 - 17405743 + 17406043 @@ -22375,7 +22450,7 @@ 1 2 - 17405743 + 17406043 @@ -22391,7 +22466,7 @@ 1 2 - 17405743 + 17406043 @@ -22407,7 +22482,7 @@ 1 2 - 17405743 + 17406043 @@ -22423,22 +22498,22 @@ 1 2 - 3332494 + 3332551 2 3 - 557171 + 557181 3 5 - 372860 + 372866 5 30 - 349548 + 349554 30 @@ -22459,22 +22534,22 @@ 1 2 - 3459380 + 3459439 2 3 - 498224 + 498232 3 6 - 416438 + 416445 6 15129 - 280149 + 280154 @@ -22490,17 +22565,17 @@ 1 2 - 4249666 + 4249739 2 7 - 349404 + 349410 7 3080 - 55120 + 55121 @@ -22516,22 +22591,22 @@ 1 2 - 3392573 + 3392631 2 3 - 574042 + 574052 3 5 - 366770 + 366776 5 14243 - 320805 + 320811 @@ -22547,42 +22622,42 @@ 1 2 - 1267606 + 1267628 2 3 - 821992 + 822006 3 4 - 350083 + 350089 4 5 - 236921 + 236925 5 6 - 207210 + 207214 6 9 - 321093 + 321099 9 17 - 281054 + 281059 17 1325 - 149168 + 149171 @@ -22598,37 +22673,37 @@ 1 2 - 1315648 + 1315671 2 3 - 850756 + 850771 3 4 - 360659 + 360665 4 5 - 283215 + 283219 5 6 - 241180 + 241184 6 10 - 303851 + 303857 10 89 - 272680 + 272685 89 @@ -22649,32 +22724,32 @@ 1 2 - 1738053 + 1738083 2 3 - 858636 + 858651 3 4 - 372881 + 372887 4 5 - 307555 + 307560 5 10 - 283667 + 283672 10 272 - 74337 + 74338 @@ -22690,42 +22765,42 @@ 1 2 - 1267606 + 1267628 2 3 - 821992 + 822006 3 4 - 350083 + 350089 4 5 - 236921 + 236925 5 6 - 207210 + 207214 6 9 - 321093 + 321099 9 17 - 281054 + 281059 17 1325 - 149168 + 149171 @@ -22741,32 +22816,32 @@ 1 2 - 670786 + 670798 2 3 - 190216 + 190219 3 4 - 84048 + 84050 4 7 - 103121 + 103123 7 25 - 87999 + 88000 25 239280 - 31479 + 31480 @@ -22782,22 +22857,22 @@ 1 2 - 817877 + 817891 2 3 - 156699 + 156702 3 5 - 96826 + 96827 5 33 - 87649 + 87651 33 @@ -22818,27 +22893,27 @@ 1 2 - 762386 + 762399 2 3 - 184413 + 184417 3 4 - 74275 + 74277 4 9 - 91682 + 91683 9 76756 - 54894 + 54895 @@ -22854,27 +22929,27 @@ 1 2 - 673872 + 673884 2 3 - 191738 + 191741 3 4 - 84522 + 84523 4 7 - 102895 + 102897 7 27 - 87958 + 87959 27 @@ -22895,12 +22970,12 @@ 1 2 - 13875626 + 13875865 2 4984 - 435038 + 435045 @@ -22916,7 +22991,7 @@ 1 2 - 14310664 + 14310911 @@ -22932,12 +23007,12 @@ 1 2 - 13875626 + 13875865 2 4984 - 435038 + 435045 @@ -22953,12 +23028,12 @@ 1 2 - 14180568 + 14180813 2 1923 - 130095 + 130098 @@ -22968,15 +23043,15 @@ method_location - 17716426 + 17716731 id - 17405743 + 17406043 loc - 9011 + 9012 @@ -22990,12 +23065,12 @@ 1 2 - 17203367 + 17203664 2 34 - 202375 + 202379 @@ -23086,23 +23161,23 @@ constructors - 5023369 + 5023456 id - 5023369 + 5023456 name - 2237718 + 2237756 declaring_type_id - 3721855 + 3721919 unbound_id - 4648822 + 4648902 @@ -23116,7 +23191,7 @@ 1 2 - 5023369 + 5023456 @@ -23132,7 +23207,7 @@ 1 2 - 5023369 + 5023456 @@ -23148,7 +23223,7 @@ 1 2 - 5023369 + 5023456 @@ -23164,22 +23239,22 @@ 1 2 - 1580572 + 1580599 2 3 - 438762 + 438769 3 7 - 180010 + 180013 7 29898 - 38372 + 38373 @@ -23195,17 +23270,17 @@ 1 2 - 2032626 + 2032661 2 5 - 178159 + 178162 5 14950 - 26932 + 26933 @@ -23221,17 +23296,17 @@ 1 2 - 1604933 + 1604961 2 3 - 440243 + 440251 3 8 - 171142 + 171145 8 @@ -23252,17 +23327,17 @@ 1 2 - 2716107 + 2716154 2 3 - 861455 + 861470 3 55 - 144292 + 144295 @@ -23278,7 +23353,7 @@ 1 2 - 3721855 + 3721919 @@ -23294,17 +23369,17 @@ 1 2 - 2716107 + 2716154 2 3 - 861455 + 861470 3 55 - 144292 + 144295 @@ -23320,12 +23395,12 @@ 1 2 - 4603166 + 4603245 2 1890 - 45655 + 45656 @@ -23341,7 +23416,7 @@ 1 2 - 4648822 + 4648902 @@ -23357,12 +23432,12 @@ 1 2 - 4603166 + 4603245 2 1890 - 45655 + 45656 @@ -23372,11 +23447,11 @@ constructor_location - 5171571 + 5171660 id - 5023369 + 5023456 loc @@ -23394,12 +23469,12 @@ 1 2 - 4954587 + 4954672 2 306 - 68782 + 68783 @@ -23726,7 +23801,7 @@ destructor_location - 4649 + 4650 id @@ -23804,15 +23879,15 @@ overrides - 3995009 + 3995078 id - 3990298 + 3990366 base_id - 1238286 + 1238308 @@ -23826,7 +23901,7 @@ 1 2 - 3985586 + 3985655 2 @@ -23847,22 +23922,22 @@ 1 2 - 835942 + 835956 2 3 - 192252 + 192256 3 5 - 107957 + 107958 5 28 - 93451 + 93453 28 @@ -23877,15 +23952,15 @@ explicitly_implements - 1640816 + 1640844 id - 1640425 + 1640453 interface_id - 107525 + 107526 @@ -23899,7 +23974,7 @@ 1 2 - 1640034 + 1640062 2 @@ -23920,7 +23995,7 @@ 1 2 - 54894 + 54895 2 @@ -23930,7 +24005,7 @@ 3 4 - 6830 + 6831 4 @@ -24314,11 +24389,11 @@ fields - 12987217 + 12987441 id - 12987217 + 12987441 kind @@ -24326,19 +24401,19 @@ name - 5002321 + 5002407 declaring_type_id - 2950909 + 2950960 type_id - 2616421 + 2616467 unbound_id - 12547385 + 12547601 @@ -24352,7 +24427,7 @@ 1 2 - 12987217 + 12987441 @@ -24368,7 +24443,7 @@ 1 2 - 12987217 + 12987441 @@ -24384,7 +24459,7 @@ 1 2 - 12987217 + 12987441 @@ -24400,7 +24475,7 @@ 1 2 - 12987217 + 12987441 @@ -24416,7 +24491,7 @@ 1 2 - 12987217 + 12987441 @@ -24537,22 +24612,22 @@ 1 2 - 3909664 + 3909731 2 3 - 577849 + 577859 3 8 - 381666 + 381673 8 15557 - 133140 + 133143 @@ -24568,12 +24643,12 @@ 1 2 - 4889508 + 4889592 2 3 - 112812 + 112814 @@ -24589,22 +24664,22 @@ 1 2 - 3910713 + 3910781 2 3 - 578384 + 578394 3 8 - 381543 + 381549 8 15557 - 131680 + 131682 @@ -24620,17 +24695,17 @@ 1 2 - 4380503 + 4380578 2 3 - 372613 + 372619 3 15557 - 249204 + 249208 @@ -24646,22 +24721,22 @@ 1 2 - 3938119 + 3938187 2 3 - 578219 + 578229 3 9 - 380699 + 380706 9 15557 - 105282 + 105284 @@ -24677,42 +24752,42 @@ 1 2 - 806643 + 806657 2 3 - 748292 + 748305 3 4 - 411623 + 411630 4 5 - 257948 + 257953 5 6 - 174290 + 174293 6 8 - 222930 + 222934 8 14 - 227107 + 227110 14 6823 - 102072 + 102074 @@ -24728,12 +24803,12 @@ 1 2 - 2817871 + 2817920 2 3 - 133038 + 133040 @@ -24749,42 +24824,42 @@ 1 2 - 806828 + 806842 2 3 - 748272 + 748285 3 4 - 411603 + 411610 4 5 - 257990 + 257994 5 6 - 174270 + 174273 6 8 - 223053 + 223057 8 14 - 226963 + 226966 14 6823 - 101928 + 101930 @@ -24800,32 +24875,32 @@ 1 2 - 1103849 + 1103868 2 3 - 812404 + 812418 3 4 - 381234 + 381241 4 5 - 207972 + 207975 5 7 - 225872 + 225876 7 612 - 219576 + 219580 @@ -24841,42 +24916,42 @@ 1 2 - 806643 + 806657 2 3 - 748292 + 748305 3 4 - 411623 + 411630 4 5 - 257948 + 257953 5 6 - 174290 + 174293 6 8 - 222930 + 222934 8 14 - 227107 + 227110 14 6823 - 102072 + 102074 @@ -24892,27 +24967,27 @@ 1 2 - 1788812 + 1788843 2 3 - 320661 + 320667 3 5 - 237517 + 237522 5 15 - 200565 + 200568 15 68300 - 68864 + 68865 @@ -24928,12 +25003,12 @@ 1 2 - 2540561 + 2540605 2 3 - 75860 + 75861 @@ -24949,22 +25024,22 @@ 1 2 - 1915616 + 1915649 2 3 - 308892 + 308898 3 5 - 202108 + 202111 5 37646 - 189804 + 189807 @@ -24980,22 +25055,22 @@ 1 2 - 1970531 + 1970564 2 3 - 313110 + 313115 3 6 - 205503 + 205506 6 23118 - 127277 + 127279 @@ -25011,27 +25086,27 @@ 1 2 - 1793729 + 1793760 2 3 - 322328 + 322333 3 5 - 235789 + 235793 5 15 - 197417 + 197420 15 67097 - 67156 + 67158 @@ -25047,12 +25122,12 @@ 1 2 - 12474961 + 12475176 2 1890 - 72424 + 72425 @@ -25068,7 +25143,7 @@ 1 2 - 12547385 + 12547601 @@ -25084,7 +25159,7 @@ 1 2 - 12547385 + 12547601 @@ -25100,12 +25175,12 @@ 1 2 - 12474961 + 12475176 2 1890 - 72424 + 72425 @@ -25121,7 +25196,7 @@ 1 2 - 12524835 + 12525051 2 @@ -25136,11 +25211,11 @@ field_location - 13100668 + 13100894 id - 12871956 + 12872178 loc @@ -25158,12 +25233,12 @@ 1 2 - 12723404 + 12723624 2 283 - 148551 + 148554 @@ -25249,11 +25324,11 @@ localvars - 618980 + 618977 id - 618980 + 618977 kind @@ -25269,11 +25344,11 @@ type_id - 31963 + 31962 parent_id - 618980 + 618977 @@ -25287,7 +25362,7 @@ 1 2 - 618980 + 618977 @@ -25303,7 +25378,7 @@ 1 2 - 618980 + 618977 @@ -25319,7 +25394,7 @@ 1 2 - 618980 + 618977 @@ -25335,7 +25410,7 @@ 1 2 - 618980 + 618977 @@ -25351,7 +25426,7 @@ 1 2 - 618980 + 618977 @@ -25508,7 +25583,7 @@ 1 2 - 112983 + 112982 2 @@ -25529,7 +25604,7 @@ 1 2 - 98443 + 98442 2 @@ -25550,7 +25625,7 @@ 1 2 - 97836 + 97835 2 @@ -25825,7 +25900,7 @@ 1 2 - 23340 + 23339 2 @@ -25892,7 +25967,7 @@ 1 2 - 618980 + 618977 @@ -25908,7 +25983,7 @@ 1 2 - 618980 + 618977 @@ -25924,7 +25999,7 @@ 1 2 - 618980 + 618977 @@ -25940,7 +26015,7 @@ 1 2 - 618980 + 618977 @@ -25956,7 +26031,7 @@ 1 2 - 618980 + 618977 @@ -25966,15 +26041,15 @@ localvar_location - 618980 + 618977 id - 618980 + 618977 loc - 618980 + 618977 @@ -25988,7 +26063,7 @@ 1 2 - 618980 + 618977 @@ -26004,7 +26079,7 @@ 1 2 - 618980 + 618977 @@ -26014,19 +26089,19 @@ params - 31463252 + 31463795 id - 31463252 + 31463795 name - 1755563 + 1755593 type_id - 2360118 + 2360159 index @@ -26038,11 +26113,11 @@ parent_id - 17473887 + 17474189 unbound_id - 25163121 + 25163555 @@ -26056,7 +26131,7 @@ 1 2 - 31463252 + 31463795 @@ -26072,7 +26147,7 @@ 1 2 - 31463252 + 31463795 @@ -26088,7 +26163,7 @@ 1 2 - 31463252 + 31463795 @@ -26104,7 +26179,7 @@ 1 2 - 31463252 + 31463795 @@ -26120,7 +26195,7 @@ 1 2 - 31463252 + 31463795 @@ -26136,7 +26211,7 @@ 1 2 - 31463252 + 31463795 @@ -26152,37 +26227,37 @@ 1 2 - 778558 + 778572 2 3 - 321772 + 321778 3 4 - 144354 + 144356 4 6 - 159209 + 159212 6 10 - 135095 + 135097 10 26 - 133264 + 133266 26 82408 - 83308 + 83309 @@ -26198,22 +26273,22 @@ 1 2 - 1424367 + 1424391 2 3 - 172665 + 172668 3 12 - 132523 + 132525 12 15932 - 26006 + 26007 @@ -26229,22 +26304,22 @@ 1 2 - 1213596 + 1213617 2 3 - 297576 + 297581 3 4 - 115940 + 115942 4 23 - 128449 + 128452 @@ -26260,17 +26335,17 @@ 1 2 - 1598123 + 1598150 2 3 - 132050 + 132052 3 7 - 25389 + 25390 @@ -26286,37 +26361,37 @@ 1 2 - 778558 + 778572 2 3 - 321772 + 321778 3 4 - 144354 + 144356 4 6 - 159209 + 159212 6 10 - 135095 + 135097 10 26 - 133264 + 133266 26 82408 - 83308 + 83309 @@ -26332,37 +26407,37 @@ 1 2 - 795491 + 795505 2 3 - 328089 + 328094 3 4 - 155505 + 155508 4 5 - 102854 + 102856 5 8 - 139189 + 139192 8 19 - 135630 + 135632 19 69269 - 98801 + 98802 @@ -26378,37 +26453,37 @@ 1 2 - 1148620 + 1148640 2 3 - 332903 + 332909 3 4 - 201141 + 201144 4 5 - 155999 + 156002 5 8 - 185031 + 185034 8 18 - 178529 + 178532 18 107768 - 157892 + 157895 @@ -26424,22 +26499,22 @@ 1 2 - 1573083 + 1573110 2 3 - 396130 + 396137 3 4 - 179517 + 179520 4 12 - 180895 + 180898 12 @@ -26460,22 +26535,22 @@ 1 2 - 1703529 + 1703558 2 3 - 413989 + 413997 3 5 - 179496 + 179499 5 70 - 63103 + 63104 @@ -26491,12 +26566,12 @@ 1 2 - 2211834 + 2211872 2 6 - 148284 + 148286 @@ -26512,37 +26587,37 @@ 1 2 - 1179750 + 1179771 2 3 - 314571 + 314576 3 4 - 201017 + 201021 4 5 - 156617 + 156619 5 8 - 183076 + 183079 8 19 - 178817 + 178820 19 87339 - 146267 + 146270 @@ -26558,37 +26633,37 @@ 1 2 - 1156747 + 1156767 2 3 - 333706 + 333711 3 4 - 213465 + 213469 4 5 - 154621 + 154623 5 8 - 193775 + 193778 8 19 - 180504 + 180507 19 100456 - 127297 + 127299 @@ -27201,27 +27276,27 @@ 1 2 - 9861646 + 9861816 2 3 - 4448647 + 4448724 3 4 - 1719824 + 1719854 4 8 - 1312151 + 1312173 8 70 - 131618 + 131620 @@ -27237,27 +27312,27 @@ 1 2 - 9861625 + 9861795 2 3 - 4448647 + 4448724 3 4 - 1719824 + 1719854 4 8 - 1312171 + 1312194 8 70 - 131618 + 131620 @@ -27273,22 +27348,22 @@ 1 2 - 10469864 + 10470044 2 3 - 4359784 + 4359859 3 4 - 1575840 + 1575867 4 43 - 1068398 + 1068417 @@ -27304,27 +27379,27 @@ 1 2 - 9861646 + 9861816 2 3 - 4448647 + 4448724 3 4 - 1719824 + 1719854 4 8 - 1312151 + 1312173 8 70 - 131618 + 131620 @@ -27340,12 +27415,12 @@ 1 2 - 16675165 + 16675453 2 5 - 798722 + 798735 @@ -27361,27 +27436,27 @@ 1 2 - 9861646 + 9861816 2 3 - 4448647 + 4448724 3 4 - 1719824 + 1719854 4 8 - 1312151 + 1312173 8 70 - 131618 + 131620 @@ -27397,12 +27472,12 @@ 1 2 - 24343803 + 24344223 2 21044 - 819317 + 819331 @@ -27418,7 +27493,7 @@ 1 2 - 25163059 + 25163493 2 @@ -27439,12 +27514,12 @@ 1 2 - 24923710 + 24924140 2 11733 - 239410 + 239415 @@ -27460,7 +27535,7 @@ 1 2 - 25163121 + 25163555 @@ -27476,7 +27551,7 @@ 1 2 - 25163100 + 25163534 2 @@ -27497,12 +27572,12 @@ 1 2 - 24343803 + 24344223 2 21044 - 819317 + 819331 @@ -27512,11 +27587,11 @@ param_location - 32043550 + 32044103 id - 31455722 + 31456264 loc @@ -27534,12 +27609,12 @@ 1 2 - 31081257 + 31081793 2 283 - 374465 + 374471 @@ -27625,11 +27700,11 @@ scoped_annotation - 382468 + 382475 id - 382468 + 382475 kind @@ -27647,7 +27722,7 @@ 1 2 - 382468 + 382475 @@ -27673,11 +27748,11 @@ statements - 3047866 + 3047725 id - 3047866 + 3047725 kind @@ -27695,7 +27770,7 @@ 1 2 - 3047866 + 3047725 @@ -27791,19 +27866,19 @@ stmt_parent - 2600530 + 2600410 stmt - 2600530 + 2600410 index - 6149 + 6148 parent - 1245075 + 1245017 @@ -27817,7 +27892,7 @@ 1 2 - 2600530 + 2600410 @@ -27833,7 +27908,7 @@ 1 2 - 2600530 + 2600410 @@ -27961,27 +28036,27 @@ 1 2 - 802507 + 802470 2 3 - 236422 + 236411 3 4 - 77805 + 77802 4 9 - 99413 + 99408 9 3407 - 28926 + 28925 @@ -27997,27 +28072,27 @@ 1 2 - 802507 + 802470 2 3 - 236422 + 236411 3 4 - 77805 + 77802 4 9 - 99413 + 99408 9 3407 - 28926 + 28925 @@ -28027,11 +28102,11 @@ stmt_parent_top_level - 447336 + 447315 stmt - 447336 + 447315 index @@ -28039,7 +28114,7 @@ parent - 422479 + 422460 @@ -28053,7 +28128,7 @@ 1 2 - 447336 + 447315 @@ -28069,7 +28144,7 @@ 1 2 - 447336 + 447315 @@ -28117,12 +28192,12 @@ 1 2 - 399538 + 399519 2 5 - 22941 + 22940 @@ -28138,7 +28213,7 @@ 1 2 - 422479 + 422460 @@ -28148,15 +28223,15 @@ stmt_location - 3047859 + 3047718 id - 3047859 + 3047718 loc - 2947337 + 2947201 @@ -28170,7 +28245,7 @@ 1 2 - 3047859 + 3047718 @@ -28186,12 +28261,12 @@ 1 2 - 2852235 + 2852104 2 5 - 95101 + 95097 @@ -28201,11 +28276,11 @@ catch_type - 30235 + 30233 catch_id - 30235 + 30233 type_id @@ -28227,7 +28302,7 @@ 1 2 - 30235 + 30233 @@ -28243,7 +28318,7 @@ 1 2 - 30235 + 30233 @@ -28372,11 +28447,11 @@ foreach_stmt_info - 32431 + 32428 id - 32431 + 32428 kind @@ -28394,7 +28469,7 @@ 1 2 - 32431 + 32428 @@ -28420,15 +28495,15 @@ foreach_stmt_desugar - 162122 + 162110 id - 32431 + 32428 symbol - 19968 + 19966 kind @@ -28451,7 +28526,7 @@ 5 6 - 32397 + 32394 @@ -28472,7 +28547,7 @@ 5 6 - 32397 + 32394 @@ -28534,7 +28609,7 @@ 1 2 - 19968 + 19966 @@ -28601,19 +28676,19 @@ expressions - 12065066 + 12065274 id - 12065066 + 12065274 kind - 176 + 282 type_id - 110007 + 95429 @@ -28627,7 +28702,7 @@ 1 2 - 12065066 + 12065274 @@ -28643,7 +28718,7 @@ 1 2 - 12065066 + 12065274 @@ -28657,69 +28732,64 @@ 12 - 5 - 84 - 14 + 1 + 37 + 25 - 95 - 270 - 14 + 47 + 133 + 23 - 341 - 797 - 14 + 134 + 544 + 23 - 819 - 1281 - 14 + 570 + 985 + 23 - 1537 - 2495 - 14 + 1041 + 1502 + 23 - 2609 - 4357 - 14 + 1512 + 1811 + 23 - 4453 - 6679 - 14 + 1901 + 3636 + 23 - 7465 - 13714 - 14 + 4438 + 6455 + 23 - 14409 - 23536 - 14 + 7058 + 14022 + 23 - 27017 - 46515 - 14 + 14452 + 28402 + 23 - 49854 - 183862 - 14 + 32648 + 169673 + 23 - 313497 - 578005 - 14 - - - 745202 - 753853 - 3 + 172052 + 1144418 + 23 @@ -28735,57 +28805,52 @@ 1 2 - 45 + 91 2 - 5 - 16 + 7 + 25 - 5 - 9 - 10 + 8 + 12 + 23 - 9 - 14 - 16 + 12 + 27 + 23 - 16 - 46 - 14 + 29 + 102 + 23 - 46 - 116 - 14 + 162 + 320 + 23 - 131 - 397 - 14 + 320 + 863 + 23 - 513 - 1251 - 14 + 915 + 4194 + 23 - 1355 - 8712 - 14 + 4905 + 13903 + 23 - 11608 - 19250 - 14 - - - 25103 - 25104 - 1 + 16571 + 16572 + 2 @@ -28801,57 +28866,57 @@ 1 2 - 25224 + 19361 2 3 - 10899 + 13919 3 4 - 7688 + 5455 4 5 - 6125 + 8090 5 7 - 8804 + 7637 7 11 - 10105 + 8729 11 17 - 8699 + 7698 17 - 28 - 8457 + 30 + 7273 - 28 - 50 - 8437 + 30 + 60 + 7182 - 50 - 121 - 8266 + 60 + 238 + 7161 - 121 - 1192575 - 7298 + 238 + 919701 + 2916 @@ -28867,42 +28932,42 @@ 1 2 - 43908 + 34716 2 3 - 14177 + 21172 3 4 - 15581 + 11492 4 5 - 9412 + 6989 5 6 - 7149 + 5465 6 8 - 9488 + 6872 8 13 - 9035 + 7208 13 - 54 - 1256 + 60 + 1512 @@ -28912,19 +28977,19 @@ expr_parent - 11682392 + 11682627 expr - 11682392 + 11682627 index - 40692 + 40690 parent - 7822739 + 7823161 @@ -28938,7 +29003,7 @@ 1 2 - 11682392 + 11682627 @@ -28954,7 +29019,7 @@ 1 2 - 11682392 + 11682627 @@ -28975,7 +29040,7 @@ 4 5 - 21178 + 21177 5 @@ -28990,7 +29055,7 @@ 10 11 - 5956 + 5955 11 @@ -28999,7 +29064,7 @@ 66 - 3205894 + 3205889 882 @@ -29021,7 +29086,7 @@ 4 5 - 21178 + 21177 5 @@ -29036,7 +29101,7 @@ 10 11 - 5956 + 5955 11 @@ -29045,7 +29110,7 @@ 66 - 3205894 + 3205889 882 @@ -29062,17 +29127,17 @@ 1 2 - 5080347 + 5080905 2 3 - 2351800 + 2351683 3 22534 - 390591 + 390573 @@ -29088,17 +29153,17 @@ 1 2 - 5080347 + 5080905 2 3 - 2351800 + 2351683 3 22534 - 390591 + 390573 @@ -29108,11 +29173,11 @@ expr_parent_top_level - 6487240 + 6487352 expr - 6487240 + 6487352 index @@ -29120,7 +29185,7 @@ parent - 4784143 + 4784226 @@ -29134,7 +29199,7 @@ 1 2 - 6487240 + 6487352 @@ -29150,7 +29215,7 @@ 1 2 - 6487240 + 6487352 @@ -29328,17 +29393,17 @@ 1 2 - 4124138 + 4124209 2 3 - 343479 + 343485 3 15 - 316526 + 316531 @@ -29354,17 +29419,17 @@ 1 2 - 4127780 + 4127851 2 3 - 340845 + 340851 3 15 - 315517 + 315523 @@ -29407,11 +29472,11 @@ implicitly_typed_object_creation - 14529 + 14530 id - 14529 + 14530 @@ -29471,26 +29536,26 @@ expr_compiler_generated - 12064345 + 12064553 id - 12064345 + 12064553 expr_value - 8310207 + 8310351 id - 8310207 + 8310351 value - 718788 + 718800 @@ -29504,7 +29569,7 @@ 1 2 - 8310207 + 8310351 @@ -29520,17 +29585,17 @@ 1 2 - 505569 + 505578 2 3 - 110652 + 110654 3 4 - 55367 + 55368 4 @@ -29545,15 +29610,15 @@ expr_call - 1966214 + 1966123 caller_id - 1966214 + 1966123 target_id - 257183 + 257171 @@ -29567,7 +29632,7 @@ 1 2 - 1966214 + 1966123 @@ -29583,22 +29648,22 @@ 1 2 - 137524 + 137518 2 3 - 51110 + 51107 3 4 - 19301 + 19300 4 6 - 19324 + 19323 6 @@ -29618,15 +29683,15 @@ expr_access - 4483718 + 4484304 accesser_id - 4483718 + 4484304 target_id - 1084843 + 1084863 @@ -29640,7 +29705,7 @@ 1 2 - 4483718 + 4484304 @@ -29656,32 +29721,32 @@ 1 2 - 362211 + 361965 2 3 - 236534 + 236660 3 4 - 166823 + 166914 4 5 - 102369 + 102379 5 7 - 99561 + 99569 7 15 - 84344 + 84375 15 @@ -29696,15 +29761,15 @@ expr_location - 12065066 + 12065274 id - 12065066 + 12065274 loc - 10110422 + 7880074 @@ -29718,7 +29783,7 @@ 1 2 - 12065066 + 12065274 @@ -29734,17 +29799,17 @@ 1 2 - 8365713 + 6971739 2 3 - 1650623 + 852056 3 - 9205 - 94085 + 163205 + 56279 @@ -29853,11 +29918,11 @@ expr_argument - 1774404 + 1774394 id - 1774404 + 1774394 mode @@ -29875,7 +29940,7 @@ 1 2 - 1774404 + 1774394 @@ -29911,11 +29976,11 @@ expr_argument_name - 840180 + 840195 id - 840180 + 840195 name @@ -29933,7 +29998,7 @@ 1 2 - 840180 + 840195 @@ -30082,11 +30147,11 @@ xmlEncoding - 51268 + 51263 id - 51268 + 51263 encoding @@ -30104,7 +30169,7 @@ 1 2 - 51268 + 51263 @@ -30598,27 +30663,27 @@ xmlElements - 67061685 + 67055539 id - 67061685 + 67055539 name - 5082 + 5081 parentid - 27351687 + 27349180 idx - 78615 + 78608 fileid - 51263 + 51258 @@ -30632,7 +30697,7 @@ 1 2 - 67061685 + 67055539 @@ -30648,7 +30713,7 @@ 1 2 - 67061685 + 67055539 @@ -30664,7 +30729,7 @@ 1 2 - 67061685 + 67055539 @@ -30680,7 +30745,7 @@ 1 2 - 67061685 + 67055539 @@ -30865,27 +30930,27 @@ 1 2 - 16075227 + 16073753 2 3 - 5276599 + 5276115 3 4 - 2405163 + 2404943 4 6 - 2305179 + 2304967 6 31356 - 1289517 + 1289399 @@ -30901,22 +30966,22 @@ 1 2 - 19033145 + 19031401 2 3 - 4597119 + 4596698 3 4 - 2298956 + 2298745 4 121 - 1422465 + 1422335 @@ -30932,27 +30997,27 @@ 1 2 - 16075227 + 16073753 2 3 - 5276599 + 5276115 3 4 - 2405163 + 2404943 4 6 - 2305179 + 2304967 6 31356 - 1289517 + 1289399 @@ -30968,7 +31033,7 @@ 1 2 - 27351687 + 27349180 @@ -30984,22 +31049,22 @@ 1 2 - 35502 + 35499 2 4 - 7000 + 6999 4 11 - 4864 + 4863 12 15 - 3317 + 3316 15 @@ -31019,7 +31084,7 @@ 64 506 - 5902 + 5901 506 @@ -31040,7 +31105,7 @@ 1 2 - 77672 + 77665 2 @@ -31061,22 +31126,22 @@ 1 2 - 35502 + 35499 2 4 - 7000 + 6999 4 11 - 4864 + 4863 12 15 - 3317 + 3316 15 @@ -31096,7 +31161,7 @@ 64 506 - 5902 + 5901 506 @@ -31117,22 +31182,22 @@ 1 2 - 35502 + 35499 2 4 - 7000 + 6999 4 11 - 4864 + 4863 12 15 - 3317 + 3316 15 @@ -31152,7 +31217,7 @@ 64 506 - 5902 + 5901 506 @@ -31173,7 +31238,7 @@ 1 15 - 4345 + 4344 15 @@ -31188,42 +31253,42 @@ 103 172 - 4380 + 4379 173 236 - 4049 + 4048 237 351 - 4563 + 4562 351 564 - 3886 + 3885 564 804 - 3851 + 3850 806 996 - 4222 + 4221 997 1436 - 4330 + 4329 1441 2336 - 3861 + 3860 2342 @@ -31269,12 +31334,12 @@ 13 14 - 5982 + 5981 14 15 - 7168 + 7167 15 @@ -31315,17 +31380,17 @@ 1 6 - 4167 + 4166 6 19 - 3974 + 3973 19 48 - 3856 + 3855 48 @@ -31340,7 +31405,7 @@ 94 142 - 3851 + 3850 142 @@ -31350,7 +31415,7 @@ 209 314 - 4375 + 4374 314 @@ -31365,17 +31430,17 @@ 592 903 - 3846 + 3845 904 1647 - 3906 + 3905 1647 45210 - 3530 + 3529 @@ -31416,7 +31481,7 @@ 48 67 - 3861 + 3860 67 @@ -31426,12 +31491,12 @@ 96 152 - 3984 + 3983 152 199 - 3851 + 3850 199 @@ -31461,15 +31526,15 @@ xmlAttrs - 45633086 + 45628904 id - 45633086 + 45628904 elementid - 45273709 + 45269560 name @@ -31477,7 +31542,7 @@ value - 1023366 + 1023272 idx @@ -31485,7 +31550,7 @@ fileid - 50827 + 50822 @@ -31499,7 +31564,7 @@ 1 2 - 45633086 + 45628904 @@ -31515,7 +31580,7 @@ 1 2 - 45633086 + 45628904 @@ -31531,7 +31596,7 @@ 1 2 - 45633086 + 45628904 @@ -31547,7 +31612,7 @@ 1 2 - 45633086 + 45628904 @@ -31563,7 +31628,7 @@ 1 2 - 45633086 + 45628904 @@ -31579,12 +31644,12 @@ 1 2 - 45082031 + 45077900 2 14 - 191678 + 191660 @@ -31600,12 +31665,12 @@ 1 2 - 45082031 + 45077900 2 14 - 191678 + 191660 @@ -31621,12 +31686,12 @@ 1 2 - 45082239 + 45078108 2 13 - 191469 + 191452 @@ -31642,12 +31707,12 @@ 1 2 - 45082031 + 45077900 2 14 - 191678 + 191660 @@ -31663,7 +31728,7 @@ 1 2 - 45273709 + 45269560 @@ -31826,7 +31891,7 @@ 2 3 - 173 + 172 3 @@ -31959,52 +32024,52 @@ 1 2 - 172793 + 172777 2 3 - 292861 + 292834 3 4 - 91964 + 91955 4 5 - 61906 + 61901 5 6 - 46745 + 46741 6 8 - 84367 + 84359 8 13 - 89343 + 89335 13 37 - 77116 + 77108 37 165 - 77301 + 77294 165 509314 - 28966 + 28963 @@ -32020,52 +32085,52 @@ 1 2 - 172808 + 172792 2 3 - 292871 + 292844 3 4 - 91959 + 91950 4 5 - 61914 + 61908 5 6 - 46755 + 46751 6 8 - 84374 + 84366 8 13 - 89323 + 89315 13 37 - 77090 + 77083 37 165 - 77301 + 77294 165 509314 - 28966 + 28963 @@ -32081,12 +32146,12 @@ 1 2 - 914089 + 914005 2 3 - 108654 + 108644 3 @@ -32107,7 +32172,7 @@ 1 2 - 1021525 + 1021432 2 @@ -32128,47 +32193,47 @@ 1 2 - 186372 + 186355 2 3 - 344114 + 344083 3 4 - 95278 + 95269 4 5 - 44927 + 44923 5 6 - 51602 + 51597 6 8 - 77928 + 77921 8 15 - 82381 + 82373 15 68 - 77993 + 77986 68 10155 - 62766 + 62761 @@ -32554,7 +32619,7 @@ 1 12 - 3989 + 3988 12 @@ -32584,7 +32649,7 @@ 228 406 - 3806 + 3805 407 @@ -32609,7 +32674,7 @@ 1605 3016 - 3846 + 3845 3021 @@ -32630,17 +32695,17 @@ 1 10 - 3851 + 3850 10 30 - 3916 + 3915 30 61 - 3836 + 3835 61 @@ -32650,22 +32715,22 @@ 105 146 - 4084 + 4083 146 221 - 3821 + 3820 222 343 - 3821 + 3820 343 446 - 3816 + 3815 446 @@ -32680,7 +32745,7 @@ 789 1329 - 4385 + 4384 1334 @@ -32706,22 +32771,22 @@ 1 2 - 3124 + 3123 2 3 - 19561 + 19559 3 4 - 13087 + 13086 4 5 - 6160 + 6159 5 @@ -32757,7 +32822,7 @@ 10 27 - 4079 + 4078 27 @@ -32767,12 +32832,12 @@ 43 61 - 4267 + 4266 61 79 - 4355 + 4354 79 @@ -32782,7 +32847,7 @@ 116 180 - 3896 + 3895 181 @@ -32807,7 +32872,7 @@ 601 1116 - 3866 + 3865 1117 @@ -32828,7 +32893,7 @@ 1 2 - 43059 + 43055 2 @@ -32838,7 +32903,7 @@ 3 5 - 4420 + 4419 5 @@ -33249,11 +33314,11 @@ xmlHasNs - 357552 + 357558 elementId - 357552 + 357558 nsId @@ -33275,7 +33340,7 @@ 1 2 - 357552 + 357558 @@ -33291,7 +33356,7 @@ 1 2 - 357552 + 357558 @@ -33684,7 +33749,7 @@ 1 2 - 5211 + 5210 2 @@ -33715,7 +33780,7 @@ 1 2 - 5582 + 5581 2 @@ -33766,19 +33831,19 @@ xmlChars - 50185384 + 50180784 id - 50185384 + 50180784 text - 1818383 + 1818216 parentid - 31637371 + 31634472 idx @@ -33790,7 +33855,7 @@ fileid - 49072 + 49067 @@ -33804,7 +33869,7 @@ 1 2 - 50185384 + 50180784 @@ -33820,7 +33885,7 @@ 1 2 - 50185384 + 50180784 @@ -33836,7 +33901,7 @@ 1 2 - 50185384 + 50180784 @@ -33852,7 +33917,7 @@ 1 2 - 50185384 + 50180784 @@ -33868,7 +33933,7 @@ 1 2 - 50185384 + 50180784 @@ -33884,62 +33949,62 @@ 1 2 - 190103 + 190086 2 3 - 423627 + 423589 3 4 - 100448 + 100439 4 5 - 177339 + 177322 5 6 - 53810 + 53806 6 8 - 152883 + 152869 8 10 - 147492 + 147478 10 12 - 103316 + 103307 12 15 - 93307 + 93299 15 21 - 150877 + 150863 21 67 - 136906 + 136894 67 1003068 - 88268 + 88260 @@ -33955,62 +34020,62 @@ 1 2 - 190238 + 190221 2 3 - 423657 + 423619 3 4 - 100471 + 100462 4 5 - 177379 + 177362 5 6 - 53821 + 53816 6 8 - 152860 + 152846 8 10 - 147507 + 147494 10 12 - 103334 + 103325 12 15 - 93380 + 93372 15 21 - 151010 + 150996 21 67 - 136678 + 136666 67 1000575 - 88042 + 88034 @@ -34026,12 +34091,12 @@ 1 2 - 1784617 + 1784454 2 33 - 33765 + 33762 @@ -34047,7 +34112,7 @@ 1 2 - 1818380 + 1818213 2 @@ -34068,57 +34133,57 @@ 1 2 - 256834 + 256810 2 3 - 492795 + 492750 3 4 - 134153 + 134141 4 5 - 137260 + 137247 5 6 - 63556 + 63550 6 8 - 148901 + 148887 8 10 - 138669 + 138656 10 12 - 119814 + 119803 12 15 - 79134 + 79127 15 20 - 138228 + 138215 20 15105 - 109033 + 109023 @@ -34134,22 +34199,22 @@ 1 2 - 19074302 + 19072554 2 3 - 9103155 + 9102321 3 5 - 2902380 + 2902114 5 61 - 557533 + 557482 @@ -34165,22 +34230,22 @@ 1 2 - 19076544 + 19074795 2 3 - 9111876 + 9111041 3 4 - 2305525 + 2305313 4 47 - 1143426 + 1143321 @@ -34196,22 +34261,22 @@ 1 2 - 19074302 + 19072554 2 3 - 9103155 + 9102321 3 5 - 2902380 + 2902114 5 61 - 557533 + 557482 @@ -34227,7 +34292,7 @@ 1 2 - 31636775 + 31633875 2 @@ -34248,7 +34313,7 @@ 1 2 - 31637371 + 31634472 @@ -34649,7 +34714,7 @@ 9 38 - 4084 + 4083 38 @@ -34684,7 +34749,7 @@ 578 710 - 3896 + 3895 712 @@ -34730,7 +34795,7 @@ 27 53 - 3703 + 3702 53 @@ -34745,7 +34810,7 @@ 95 144 - 4390 + 4389 145 @@ -34755,7 +34820,7 @@ 208 310 - 4425 + 4424 311 @@ -34765,7 +34830,7 @@ 417 564 - 3718 + 3717 564 @@ -34796,7 +34861,7 @@ 1 9 - 3801 + 3800 9 @@ -34806,17 +34871,17 @@ 31 56 - 3826 + 3825 56 84 - 3856 + 3855 84 111 - 3891 + 3890 111 @@ -34846,17 +34911,17 @@ 700 1079 - 3698 + 3697 1083 1973 - 3733 + 3732 1984 61987 - 2773 + 2772 @@ -34877,32 +34942,32 @@ 2 3 - 2417 + 2416 3 4 - 5814 + 5813 4 5 - 10698 + 10697 5 6 - 7973 + 7972 6 7 - 5265 + 5264 7 9 - 3906 + 3905 9 @@ -34928,7 +34993,7 @@ 1 2 - 48844 + 48839 2 @@ -34943,15 +35008,15 @@ xmllocations - 162941664 + 162926731 xmlElement - 162936973 + 162922041 location - 142841448 + 142828357 @@ -34965,7 +35030,7 @@ 1 2 - 162936925 + 162921993 2 @@ -34986,17 +35051,17 @@ 1 2 - 123085053 + 123073773 2 3 - 19575384 + 19573590 3 15 - 181009 + 180993 @@ -35006,11 +35071,11 @@ commentline - 1860877 + 1860741 id - 1860877 + 1860741 kind @@ -35018,11 +35083,11 @@ text - 694980 + 694930 rawtext - 701319 + 701268 @@ -35036,7 +35101,7 @@ 1 2 - 1860877 + 1860741 @@ -35052,7 +35117,7 @@ 1 2 - 1860877 + 1860741 @@ -35068,7 +35133,7 @@ 1 2 - 1860877 + 1860741 @@ -35162,17 +35227,17 @@ 1 2 - 581306 + 581264 2 3 - 64409 + 64405 3 21238 - 49263 + 49260 @@ -35188,7 +35253,7 @@ 1 2 - 692739 + 692688 2 @@ -35209,7 +35274,7 @@ 1 2 - 690769 + 690719 2 @@ -35230,17 +35295,17 @@ 1 2 - 588189 + 588146 2 3 - 63719 + 63714 3 21237 - 49411 + 49407 @@ -35256,7 +35321,7 @@ 1 2 - 701319 + 701268 @@ -35272,7 +35337,7 @@ 1 2 - 701319 + 701268 @@ -35282,15 +35347,15 @@ commentline_location - 1860877 + 1860741 id - 1860877 + 1860741 loc - 1860877 + 1860741 @@ -35304,7 +35369,7 @@ 1 2 - 1860877 + 1860741 @@ -35320,7 +35385,7 @@ 1 2 - 1860877 + 1860741 @@ -35330,26 +35395,26 @@ commentblock - 452781 + 452748 id - 452781 + 452748 commentblock_location - 452781 + 452748 id - 452781 + 452748 loc - 452781 + 452748 @@ -35363,7 +35428,7 @@ 1 2 - 452781 + 452748 @@ -35379,7 +35444,7 @@ 1 2 - 452781 + 452748 @@ -35389,15 +35454,15 @@ commentblock_binding - 1636303 + 1636184 id - 452781 + 452748 entity - 706277 + 706226 bindtype @@ -35415,17 +35480,17 @@ 1 2 - 28774 + 28772 2 3 - 104425 + 104417 3 4 - 319581 + 319558 @@ -35441,17 +35506,17 @@ 1 3 - 29091 + 29089 3 4 - 104108 + 104100 4 5 - 319581 + 319558 @@ -35467,17 +35532,17 @@ 1 2 - 498310 + 498273 2 3 - 169548 + 169535 3 526 - 38419 + 38416 @@ -35493,22 +35558,22 @@ 1 2 - 267419 + 267400 2 3 - 275954 + 275934 3 4 - 151323 + 151312 4 5 - 11580 + 11579 @@ -35580,15 +35645,15 @@ commentblock_child - 2294166 + 2293999 id - 452781 + 452748 commentline - 1860118 + 1859983 index @@ -35606,37 +35671,37 @@ 1 2 - 140807 + 140797 2 3 - 43751 + 43747 3 4 - 103836 + 103829 4 5 - 35306 + 35303 5 6 - 58466 + 58462 6 10 - 39528 + 39525 10 323 - 31084 + 31081 @@ -35657,37 +35722,37 @@ 2 3 - 137332 + 137322 3 4 - 49739 + 49735 4 5 - 98663 + 98656 5 6 - 34095 + 34092 6 7 - 58217 + 58213 7 11 - 39257 + 39254 11 324 - 30846 + 30844 @@ -35703,7 +35768,7 @@ 1 2 - 1860118 + 1859983 @@ -35719,12 +35784,12 @@ 1 2 - 1426071 + 1425967 2 3 - 434047 + 434015 @@ -35836,11 +35901,11 @@ asp_elements - 184021 + 184013 id - 184021 + 184013 kind @@ -35848,7 +35913,7 @@ loc - 184021 + 184013 @@ -35862,7 +35927,7 @@ 1 2 - 184021 + 184013 @@ -35878,7 +35943,7 @@ 1 2 - 184021 + 184013 @@ -36006,7 +36071,7 @@ 1 2 - 184021 + 184013 @@ -36022,7 +36087,7 @@ 1 2 - 184021 + 184013 @@ -36623,11 +36688,11 @@ asp_element_body - 147088 + 147082 element - 147088 + 147082 body @@ -36645,7 +36710,7 @@ 1 2 - 147088 + 147082 @@ -36661,7 +36726,7 @@ 1 2 - 8192 + 8191 2 @@ -36696,11 +36761,11 @@ asp_tag_attribute - 49276 + 49274 tag - 20205 + 20204 index @@ -36712,7 +36777,7 @@ attribute - 49276 + 49274 @@ -36726,7 +36791,7 @@ 1 2 - 5725 + 5724 2 @@ -36767,7 +36832,7 @@ 1 2 - 5725 + 5724 2 @@ -36808,7 +36873,7 @@ 1 2 - 5725 + 5724 2 @@ -37320,7 +37385,7 @@ 1 2 - 49276 + 49274 @@ -37336,7 +37401,7 @@ 1 2 - 49276 + 49274 @@ -37352,7 +37417,7 @@ 1 2 - 49276 + 49274 @@ -37362,11 +37427,11 @@ asp_tag_name - 33602 + 33601 tag - 33602 + 33601 name @@ -37384,7 +37449,7 @@ 1 2 - 33602 + 33601 @@ -41302,11 +41367,11 @@ metadata_handle - 47747658 + 47748481 entity - 46752588 + 46753394 location @@ -41314,7 +41379,7 @@ handle - 2013738 + 2013773 @@ -41328,12 +41393,12 @@ 1 2 - 46104557 + 46105352 2 551 - 648030 + 648041 @@ -41349,12 +41414,12 @@ 1 2 - 46139288 + 46140083 2 124 - 613300 + 613310 @@ -41512,67 +41577,67 @@ 1 2 - 285396 + 285400 2 3 - 118203 + 118205 3 5 - 172521 + 172524 5 7 - 143572 + 143574 7 9 - 149436 + 149438 9 11 - 99130 + 99132 11 14 - 182253 + 182256 14 19 - 159476 + 159479 19 25 - 178632 + 178635 25 35 - 152625 + 152628 35 48 - 152584 + 152586 48 120 - 151740 + 151743 120 401 - 68165 + 68166 @@ -41588,67 +41653,67 @@ 1 2 - 285375 + 285380 2 3 - 118203 + 118205 3 5 - 172521 + 172524 5 7 - 143572 + 143574 7 9 - 149436 + 149438 9 11 - 99130 + 99132 11 14 - 182253 + 182256 14 19 - 159476 + 159479 19 25 - 178632 + 178635 25 35 - 152625 + 152628 35 48 - 152584 + 152586 48 120 - 151720 + 151722 120 551 - 68206 + 68207 From b41758fb391383cf9af714b36675277ec11d5259 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 6 Feb 2024 11:24:02 +0100 Subject: [PATCH 33/50] C#: Update summaries for Enumerable.DefaultIfEmpty to target elements in the return value. --- csharp/ql/lib/ext/System.Linq.model.yml | 6 +++--- .../library-tests/dataflow/library/FlowSummaries.expected | 6 +++--- .../dataflow/library/FlowSummariesFiltered.expected | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/csharp/ql/lib/ext/System.Linq.model.yml b/csharp/ql/lib/ext/System.Linq.model.yml index 0cfbfa7593c..530fd6c2eeb 100644 --- a/csharp/ql/lib/ext/System.Linq.model.yml +++ b/csharp/ql/lib/ext/System.Linq.model.yml @@ -29,9 +29,9 @@ extensions: - ["System.Linq", "Enumerable", False, "Concat", "(System.Collections.Generic.IEnumerable,System.Collections.Generic.IEnumerable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - ["System.Linq", "Enumerable", False, "Concat", "(System.Collections.Generic.IEnumerable,System.Collections.Generic.IEnumerable)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] - ["System.Linq", "Enumerable", False, "Count", "(System.Collections.Generic.IEnumerable,System.Func)", "", "Argument[0].Element", "Argument[1].Parameter[0]", "value", "manual"] - - ["System.Linq", "Enumerable", False, "DefaultIfEmpty", "(System.Collections.Generic.IEnumerable)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] - - ["System.Linq", "Enumerable", False, "DefaultIfEmpty", "(System.Collections.Generic.IEnumerable,TSource)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] - - ["System.Linq", "Enumerable", False, "DefaultIfEmpty", "(System.Collections.Generic.IEnumerable,TSource)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["System.Linq", "Enumerable", False, "DefaultIfEmpty", "(System.Collections.Generic.IEnumerable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["System.Linq", "Enumerable", False, "DefaultIfEmpty", "(System.Collections.Generic.IEnumerable,TSource)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["System.Linq", "Enumerable", False, "DefaultIfEmpty", "(System.Collections.Generic.IEnumerable,TSource)", "", "Argument[1]", "ReturnValue.Element", "value", "manual"] - ["System.Linq", "Enumerable", False, "Distinct", "(System.Collections.Generic.IEnumerable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - ["System.Linq", "Enumerable", False, "Distinct", "(System.Collections.Generic.IEnumerable,System.Collections.Generic.IEqualityComparer)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - ["System.Linq", "Enumerable", False, "ElementAt", "(System.Collections.Generic.IEnumerable,System.Int32)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] diff --git a/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected b/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected index e31b2fb370e..3c1af9087db 100644 --- a/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected +++ b/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected @@ -9805,9 +9805,9 @@ summary | System.Linq;Enumerable;false;Concat;(System.Collections.Generic.IEnumerable,System.Collections.Generic.IEnumerable);;Argument[1].Element;ReturnValue.Element;value;manual | | System.Linq;Enumerable;false;Count;(System.Collections.Generic.IEnumerable,System.Func);;Argument[0].Element;Argument[1].Parameter[0];value;manual | | System.Linq;Enumerable;false;Count;(System.Collections.Generic.IEnumerable,System.Func);;Argument[1];Argument[1].Parameter[delegate-self];value;manual | -| System.Linq;Enumerable;false;DefaultIfEmpty;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;value;manual | -| System.Linq;Enumerable;false;DefaultIfEmpty;(System.Collections.Generic.IEnumerable,TSource);;Argument[0].Element;ReturnValue;value;manual | -| System.Linq;Enumerable;false;DefaultIfEmpty;(System.Collections.Generic.IEnumerable,TSource);;Argument[1];ReturnValue;value;manual | +| System.Linq;Enumerable;false;DefaultIfEmpty;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Linq;Enumerable;false;DefaultIfEmpty;(System.Collections.Generic.IEnumerable,TSource);;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Linq;Enumerable;false;DefaultIfEmpty;(System.Collections.Generic.IEnumerable,TSource);;Argument[1];ReturnValue.Element;value;manual | | System.Linq;Enumerable;false;Distinct;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue.Element;value;manual | | System.Linq;Enumerable;false;Distinct;(System.Collections.Generic.IEnumerable,System.Collections.Generic.IEqualityComparer);;Argument[0].Element;ReturnValue.Element;value;manual | | System.Linq;Enumerable;false;DistinctBy;(System.Collections.Generic.IEnumerable,System.Func);;Argument[1];Argument[1].Parameter[delegate-self];value;hq-generated | diff --git a/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected b/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected index f418f5f74e0..52d557b8d4f 100644 --- a/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected +++ b/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected @@ -8183,9 +8183,9 @@ summary | System.Linq;Enumerable;false;Concat;(System.Collections.Generic.IEnumerable,System.Collections.Generic.IEnumerable);;Argument[1].Element;ReturnValue.Element;value;manual | | System.Linq;Enumerable;false;Count;(System.Collections.Generic.IEnumerable,System.Func);;Argument[0].Element;Argument[1].Parameter[0];value;manual | | System.Linq;Enumerable;false;Count;(System.Collections.Generic.IEnumerable,System.Func);;Argument[1];Argument[1].Parameter[delegate-self];value;manual | -| System.Linq;Enumerable;false;DefaultIfEmpty;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;value;manual | -| System.Linq;Enumerable;false;DefaultIfEmpty;(System.Collections.Generic.IEnumerable,TSource);;Argument[0].Element;ReturnValue;value;manual | -| System.Linq;Enumerable;false;DefaultIfEmpty;(System.Collections.Generic.IEnumerable,TSource);;Argument[1];ReturnValue;value;manual | +| System.Linq;Enumerable;false;DefaultIfEmpty;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Linq;Enumerable;false;DefaultIfEmpty;(System.Collections.Generic.IEnumerable,TSource);;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Linq;Enumerable;false;DefaultIfEmpty;(System.Collections.Generic.IEnumerable,TSource);;Argument[1];ReturnValue.Element;value;manual | | System.Linq;Enumerable;false;Distinct;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue.Element;value;manual | | System.Linq;Enumerable;false;Distinct;(System.Collections.Generic.IEnumerable,System.Collections.Generic.IEqualityComparer);;Argument[0].Element;ReturnValue.Element;value;manual | | System.Linq;Enumerable;false;DistinctBy;(System.Collections.Generic.IEnumerable,System.Func);;Argument[1];Argument[1].Parameter[delegate-self];value;hq-generated | From 681c37d5fc1ed6e0d3007339c085e22842c2021f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tam=C3=A1s=20Vajk?= Date: Tue, 6 Feb 2024 13:49:08 +0100 Subject: [PATCH 34/50] Code quality improvement Co-authored-by: Michael Nebel --- csharp/extractor/Semmle.Extraction.CSharp/Extractor/Analyser.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Analyser.cs b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Analyser.cs index c3ed0217559..2f56bbfa3cc 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Analyser.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Analyser.cs @@ -242,7 +242,7 @@ namespace Semmle.Extraction.CSharp compilationEntity = Entities.Compilation.Create(cx); - extractor.CompilationInfos?.ForEach(ci => trapWriter.Writer.compilation_info(compilationEntity, ci.key, ci.value)); + extractor.CompilationInfos.ForEach(ci => trapWriter.Writer.compilation_info(compilationEntity, ci.key, ci.value)); } catch (Exception ex) // lgtm[cs/catch-of-all-exceptions] { From 31b0da763935422c8cb178be5e0b0125f17100f7 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 6 Feb 2024 13:49:24 +0100 Subject: [PATCH 35/50] C#: Update models for Except and DefaultIfEmpty. --- csharp/ql/lib/ext/System.Linq.model.yml | 28 ++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/csharp/ql/lib/ext/System.Linq.model.yml b/csharp/ql/lib/ext/System.Linq.model.yml index 530fd6c2eeb..89c0016d277 100644 --- a/csharp/ql/lib/ext/System.Linq.model.yml +++ b/csharp/ql/lib/ext/System.Linq.model.yml @@ -36,8 +36,8 @@ extensions: - ["System.Linq", "Enumerable", False, "Distinct", "(System.Collections.Generic.IEnumerable,System.Collections.Generic.IEqualityComparer)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - ["System.Linq", "Enumerable", False, "ElementAt", "(System.Collections.Generic.IEnumerable,System.Int32)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] - ["System.Linq", "Enumerable", False, "ElementAtOrDefault", "(System.Collections.Generic.IEnumerable,System.Int32)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] - - ["System.Linq", "Enumerable", False, "Except", "(System.Collections.Generic.IEnumerable,System.Collections.Generic.IEnumerable)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] - - ["System.Linq", "Enumerable", False, "Except", "(System.Collections.Generic.IEnumerable,System.Collections.Generic.IEnumerable,System.Collections.Generic.IEqualityComparer)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["System.Linq", "Enumerable", False, "Except", "(System.Collections.Generic.IEnumerable,System.Collections.Generic.IEnumerable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["System.Linq", "Enumerable", False, "Except", "(System.Collections.Generic.IEnumerable,System.Collections.Generic.IEnumerable,System.Collections.Generic.IEqualityComparer)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - ["System.Linq", "Enumerable", False, "First", "(System.Collections.Generic.IEnumerable)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] - ["System.Linq", "Enumerable", False, "First", "(System.Collections.Generic.IEnumerable,System.Func)", "", "Argument[0].Element", "Argument[1].Parameter[0]", "value", "manual"] - ["System.Linq", "Enumerable", False, "First", "(System.Collections.Generic.IEnumerable,System.Func)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] @@ -250,17 +250,17 @@ extensions: - ["System.Linq", "ParallelEnumerable", False, "Concat", "(System.Linq.ParallelQuery,System.Linq.ParallelQuery)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - ["System.Linq", "ParallelEnumerable", False, "Concat", "(System.Linq.ParallelQuery,System.Linq.ParallelQuery)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] - ["System.Linq", "ParallelEnumerable", False, "Count", "(System.Linq.ParallelQuery,System.Func)", "", "Argument[0].Element", "Argument[1].Parameter[0]", "value", "manual"] - - ["System.Linq", "ParallelEnumerable", False, "DefaultIfEmpty", "(System.Linq.ParallelQuery)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] - - ["System.Linq", "ParallelEnumerable", False, "DefaultIfEmpty", "(System.Linq.ParallelQuery,TSource)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] - - ["System.Linq", "ParallelEnumerable", False, "DefaultIfEmpty", "(System.Linq.ParallelQuery,TSource)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["System.Linq", "ParallelEnumerable", False, "DefaultIfEmpty", "(System.Linq.ParallelQuery)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["System.Linq", "ParallelEnumerable", False, "DefaultIfEmpty", "(System.Linq.ParallelQuery,TSource)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["System.Linq", "ParallelEnumerable", False, "DefaultIfEmpty", "(System.Linq.ParallelQuery,TSource)", "", "Argument[1]", "ReturnValue.Element", "value", "manual"] - ["System.Linq", "ParallelEnumerable", False, "Distinct", "(System.Linq.ParallelQuery)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - ["System.Linq", "ParallelEnumerable", False, "Distinct", "(System.Linq.ParallelQuery,System.Collections.Generic.IEqualityComparer)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - ["System.Linq", "ParallelEnumerable", False, "ElementAt", "(System.Linq.ParallelQuery,System.Int32)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] - ["System.Linq", "ParallelEnumerable", False, "ElementAtOrDefault", "(System.Linq.ParallelQuery,System.Int32)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] - - ["System.Linq", "ParallelEnumerable", False, "Except", "(System.Linq.ParallelQuery,System.Collections.Generic.IEnumerable)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] - - ["System.Linq", "ParallelEnumerable", False, "Except", "(System.Linq.ParallelQuery,System.Collections.Generic.IEnumerable,System.Collections.Generic.IEqualityComparer)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] - - ["System.Linq", "ParallelEnumerable", False, "Except", "(System.Linq.ParallelQuery,System.Linq.ParallelQuery)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] - - ["System.Linq", "ParallelEnumerable", False, "Except", "(System.Linq.ParallelQuery,System.Linq.ParallelQuery,System.Collections.Generic.IEqualityComparer)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["System.Linq", "ParallelEnumerable", False, "Except", "(System.Linq.ParallelQuery,System.Collections.Generic.IEnumerable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["System.Linq", "ParallelEnumerable", False, "Except", "(System.Linq.ParallelQuery,System.Collections.Generic.IEnumerable,System.Collections.Generic.IEqualityComparer)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["System.Linq", "ParallelEnumerable", False, "Except", "(System.Linq.ParallelQuery,System.Linq.ParallelQuery)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["System.Linq", "ParallelEnumerable", False, "Except", "(System.Linq.ParallelQuery,System.Linq.ParallelQuery,System.Collections.Generic.IEqualityComparer)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - ["System.Linq", "ParallelEnumerable", False, "First", "(System.Linq.ParallelQuery)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] - ["System.Linq", "ParallelEnumerable", False, "First", "(System.Linq.ParallelQuery,System.Func)", "", "Argument[0].Element", "Argument[1].Parameter[0]", "value", "manual"] - ["System.Linq", "ParallelEnumerable", False, "First", "(System.Linq.ParallelQuery,System.Func)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] @@ -496,15 +496,15 @@ extensions: - ["System.Linq", "Queryable", False, "Concat", "(System.Linq.IQueryable,System.Collections.Generic.IEnumerable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - ["System.Linq", "Queryable", False, "Concat", "(System.Linq.IQueryable,System.Collections.Generic.IEnumerable)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] - ["System.Linq", "Queryable", False, "Count", "(System.Linq.IQueryable,System.Linq.Expressions.Expression>)", "", "Argument[0].Element", "Argument[1].Parameter[0]", "value", "manual"] - - ["System.Linq", "Queryable", False, "DefaultIfEmpty", "(System.Linq.IQueryable)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] - - ["System.Linq", "Queryable", False, "DefaultIfEmpty", "(System.Linq.IQueryable,TSource)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] - - ["System.Linq", "Queryable", False, "DefaultIfEmpty", "(System.Linq.IQueryable,TSource)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["System.Linq", "Queryable", False, "DefaultIfEmpty", "(System.Linq.IQueryable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["System.Linq", "Queryable", False, "DefaultIfEmpty", "(System.Linq.IQueryable,TSource)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["System.Linq", "Queryable", False, "DefaultIfEmpty", "(System.Linq.IQueryable,TSource)", "", "Argument[1]", "ReturnValue.Element", "value", "manual"] - ["System.Linq", "Queryable", False, "Distinct", "(System.Linq.IQueryable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - ["System.Linq", "Queryable", False, "Distinct", "(System.Linq.IQueryable,System.Collections.Generic.IEqualityComparer)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - ["System.Linq", "Queryable", False, "ElementAt", "(System.Linq.IQueryable,System.Int32)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] - ["System.Linq", "Queryable", False, "ElementAtOrDefault", "(System.Linq.IQueryable,System.Int32)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] - - ["System.Linq", "Queryable", False, "Except", "(System.Linq.IQueryable,System.Collections.Generic.IEnumerable)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] - - ["System.Linq", "Queryable", False, "Except", "(System.Linq.IQueryable,System.Collections.Generic.IEnumerable,System.Collections.Generic.IEqualityComparer)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["System.Linq", "Queryable", False, "Except", "(System.Linq.IQueryable,System.Collections.Generic.IEnumerable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["System.Linq", "Queryable", False, "Except", "(System.Linq.IQueryable,System.Collections.Generic.IEnumerable,System.Collections.Generic.IEqualityComparer)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - ["System.Linq", "Queryable", False, "First", "(System.Linq.IQueryable)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] - ["System.Linq", "Queryable", False, "First", "(System.Linq.IQueryable,System.Linq.Expressions.Expression>)", "", "Argument[0].Element", "Argument[1].Parameter[0]", "value", "manual"] - ["System.Linq", "Queryable", False, "First", "(System.Linq.IQueryable,System.Linq.Expressions.Expression>)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] From 2e4786c2abc1e5634ec84aa105569c39596c182b Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 6 Feb 2024 14:06:07 +0100 Subject: [PATCH 36/50] C#: Update flow summaries expected output test. --- .../dataflow/library/FlowSummaries.expected | 28 +++++++++---------- .../library/FlowSummariesFiltered.expected | 28 +++++++++---------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected b/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected index 3c1af9087db..9c4e141a490 100644 --- a/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected +++ b/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected @@ -9816,8 +9816,8 @@ summary | System.Linq;Enumerable;false;ElementAt;(System.Collections.Generic.IEnumerable,System.Int32);;Argument[0].Element;ReturnValue;value;manual | | System.Linq;Enumerable;false;ElementAtOrDefault;(System.Collections.Generic.IEnumerable,System.Index);;Argument[0].Element;ReturnValue;taint;df-generated | | System.Linq;Enumerable;false;ElementAtOrDefault;(System.Collections.Generic.IEnumerable,System.Int32);;Argument[0].Element;ReturnValue;value;manual | -| System.Linq;Enumerable;false;Except;(System.Collections.Generic.IEnumerable,System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;value;manual | -| System.Linq;Enumerable;false;Except;(System.Collections.Generic.IEnumerable,System.Collections.Generic.IEnumerable,System.Collections.Generic.IEqualityComparer);;Argument[0].Element;ReturnValue;value;manual | +| System.Linq;Enumerable;false;Except;(System.Collections.Generic.IEnumerable,System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Linq;Enumerable;false;Except;(System.Collections.Generic.IEnumerable,System.Collections.Generic.IEnumerable,System.Collections.Generic.IEqualityComparer);;Argument[0].Element;ReturnValue.Element;value;manual | | System.Linq;Enumerable;false;ExceptBy;(System.Collections.Generic.IEnumerable,System.Collections.Generic.IEnumerable,System.Func);;Argument[2];Argument[2].Parameter[delegate-self];value;hq-generated | | System.Linq;Enumerable;false;ExceptBy;(System.Collections.Generic.IEnumerable,System.Collections.Generic.IEnumerable,System.Func,System.Collections.Generic.IEqualityComparer);;Argument[2];Argument[2].Parameter[delegate-self];value;hq-generated | | System.Linq;Enumerable;false;First;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;value;manual | @@ -10240,17 +10240,17 @@ summary | System.Linq;ParallelEnumerable;false;Concat;(System.Linq.ParallelQuery,System.Linq.ParallelQuery);;Argument[1].Element;ReturnValue.Element;value;manual | | System.Linq;ParallelEnumerable;false;Count;(System.Linq.ParallelQuery,System.Func);;Argument[0].Element;Argument[1].Parameter[0];value;manual | | System.Linq;ParallelEnumerable;false;Count;(System.Linq.ParallelQuery,System.Func);;Argument[1];Argument[1].Parameter[delegate-self];value;manual | -| System.Linq;ParallelEnumerable;false;DefaultIfEmpty;(System.Linq.ParallelQuery);;Argument[0].Element;ReturnValue;value;manual | -| System.Linq;ParallelEnumerable;false;DefaultIfEmpty;(System.Linq.ParallelQuery,TSource);;Argument[0].Element;ReturnValue;value;manual | -| System.Linq;ParallelEnumerable;false;DefaultIfEmpty;(System.Linq.ParallelQuery,TSource);;Argument[1];ReturnValue;value;manual | +| System.Linq;ParallelEnumerable;false;DefaultIfEmpty;(System.Linq.ParallelQuery);;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Linq;ParallelEnumerable;false;DefaultIfEmpty;(System.Linq.ParallelQuery,TSource);;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Linq;ParallelEnumerable;false;DefaultIfEmpty;(System.Linq.ParallelQuery,TSource);;Argument[1];ReturnValue.Element;value;manual | | System.Linq;ParallelEnumerable;false;Distinct;(System.Linq.ParallelQuery);;Argument[0].Element;ReturnValue.Element;value;manual | | System.Linq;ParallelEnumerable;false;Distinct;(System.Linq.ParallelQuery,System.Collections.Generic.IEqualityComparer);;Argument[0].Element;ReturnValue.Element;value;manual | | System.Linq;ParallelEnumerable;false;ElementAt;(System.Linq.ParallelQuery,System.Int32);;Argument[0].Element;ReturnValue;value;manual | | System.Linq;ParallelEnumerable;false;ElementAtOrDefault;(System.Linq.ParallelQuery,System.Int32);;Argument[0].Element;ReturnValue;value;manual | -| System.Linq;ParallelEnumerable;false;Except;(System.Linq.ParallelQuery,System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;value;manual | -| System.Linq;ParallelEnumerable;false;Except;(System.Linq.ParallelQuery,System.Collections.Generic.IEnumerable,System.Collections.Generic.IEqualityComparer);;Argument[0].Element;ReturnValue;value;manual | -| System.Linq;ParallelEnumerable;false;Except;(System.Linq.ParallelQuery,System.Linq.ParallelQuery);;Argument[0].Element;ReturnValue;value;manual | -| System.Linq;ParallelEnumerable;false;Except;(System.Linq.ParallelQuery,System.Linq.ParallelQuery,System.Collections.Generic.IEqualityComparer);;Argument[0].Element;ReturnValue;value;manual | +| System.Linq;ParallelEnumerable;false;Except;(System.Linq.ParallelQuery,System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Linq;ParallelEnumerable;false;Except;(System.Linq.ParallelQuery,System.Collections.Generic.IEnumerable,System.Collections.Generic.IEqualityComparer);;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Linq;ParallelEnumerable;false;Except;(System.Linq.ParallelQuery,System.Linq.ParallelQuery);;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Linq;ParallelEnumerable;false;Except;(System.Linq.ParallelQuery,System.Linq.ParallelQuery,System.Collections.Generic.IEqualityComparer);;Argument[0].Element;ReturnValue.Element;value;manual | | System.Linq;ParallelEnumerable;false;First;(System.Linq.ParallelQuery);;Argument[0].Element;ReturnValue;value;manual | | System.Linq;ParallelEnumerable;false;First;(System.Linq.ParallelQuery,System.Func);;Argument[0].Element;Argument[1].Parameter[0];value;manual | | System.Linq;ParallelEnumerable;false;First;(System.Linq.ParallelQuery,System.Func);;Argument[0].Element;ReturnValue;value;manual | @@ -10626,17 +10626,17 @@ summary | System.Linq;Queryable;false;Concat;(System.Linq.IQueryable,System.Collections.Generic.IEnumerable);;Argument[1].Element;ReturnValue.Element;value;manual | | System.Linq;Queryable;false;Count;(System.Linq.IQueryable,System.Linq.Expressions.Expression>);;Argument[0].Element;Argument[1].Parameter[0];value;manual | | System.Linq;Queryable;false;Count;(System.Linq.IQueryable,System.Linq.Expressions.Expression>);;Argument[1];Argument[1].Parameter[delegate-self];value;manual | -| System.Linq;Queryable;false;DefaultIfEmpty;(System.Linq.IQueryable);;Argument[0].Element;ReturnValue;value;manual | -| System.Linq;Queryable;false;DefaultIfEmpty;(System.Linq.IQueryable,TSource);;Argument[0].Element;ReturnValue;value;manual | -| System.Linq;Queryable;false;DefaultIfEmpty;(System.Linq.IQueryable,TSource);;Argument[1];ReturnValue;value;manual | +| System.Linq;Queryable;false;DefaultIfEmpty;(System.Linq.IQueryable);;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Linq;Queryable;false;DefaultIfEmpty;(System.Linq.IQueryable,TSource);;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Linq;Queryable;false;DefaultIfEmpty;(System.Linq.IQueryable,TSource);;Argument[1];ReturnValue.Element;value;manual | | System.Linq;Queryable;false;Distinct;(System.Linq.IQueryable);;Argument[0].Element;ReturnValue.Element;value;manual | | System.Linq;Queryable;false;Distinct;(System.Linq.IQueryable,System.Collections.Generic.IEqualityComparer);;Argument[0].Element;ReturnValue.Element;value;manual | | System.Linq;Queryable;false;DistinctBy;(System.Linq.IQueryable,System.Linq.Expressions.Expression>);;Argument[1];Argument[1].Parameter[delegate-self];value;hq-generated | | System.Linq;Queryable;false;DistinctBy;(System.Linq.IQueryable,System.Linq.Expressions.Expression>,System.Collections.Generic.IEqualityComparer);;Argument[1];Argument[1].Parameter[delegate-self];value;hq-generated | | System.Linq;Queryable;false;ElementAt;(System.Linq.IQueryable,System.Int32);;Argument[0].Element;ReturnValue;value;manual | | System.Linq;Queryable;false;ElementAtOrDefault;(System.Linq.IQueryable,System.Int32);;Argument[0].Element;ReturnValue;value;manual | -| System.Linq;Queryable;false;Except;(System.Linq.IQueryable,System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;value;manual | -| System.Linq;Queryable;false;Except;(System.Linq.IQueryable,System.Collections.Generic.IEnumerable,System.Collections.Generic.IEqualityComparer);;Argument[0].Element;ReturnValue;value;manual | +| System.Linq;Queryable;false;Except;(System.Linq.IQueryable,System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Linq;Queryable;false;Except;(System.Linq.IQueryable,System.Collections.Generic.IEnumerable,System.Collections.Generic.IEqualityComparer);;Argument[0].Element;ReturnValue.Element;value;manual | | System.Linq;Queryable;false;ExceptBy;(System.Linq.IQueryable,System.Collections.Generic.IEnumerable,System.Linq.Expressions.Expression>);;Argument[2];Argument[2].Parameter[delegate-self];value;hq-generated | | System.Linq;Queryable;false;ExceptBy;(System.Linq.IQueryable,System.Collections.Generic.IEnumerable,System.Linq.Expressions.Expression>,System.Collections.Generic.IEqualityComparer);;Argument[2];Argument[2].Parameter[delegate-self];value;hq-generated | | System.Linq;Queryable;false;First;(System.Linq.IQueryable);;Argument[0].Element;ReturnValue;value;manual | diff --git a/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected b/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected index 52d557b8d4f..12c531e1837 100644 --- a/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected +++ b/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected @@ -8194,8 +8194,8 @@ summary | System.Linq;Enumerable;false;ElementAt;(System.Collections.Generic.IEnumerable,System.Int32);;Argument[0].Element;ReturnValue;value;manual | | System.Linq;Enumerable;false;ElementAtOrDefault;(System.Collections.Generic.IEnumerable,System.Index);;Argument[0].Element;ReturnValue;taint;df-generated | | System.Linq;Enumerable;false;ElementAtOrDefault;(System.Collections.Generic.IEnumerable,System.Int32);;Argument[0].Element;ReturnValue;value;manual | -| System.Linq;Enumerable;false;Except;(System.Collections.Generic.IEnumerable,System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;value;manual | -| System.Linq;Enumerable;false;Except;(System.Collections.Generic.IEnumerable,System.Collections.Generic.IEnumerable,System.Collections.Generic.IEqualityComparer);;Argument[0].Element;ReturnValue;value;manual | +| System.Linq;Enumerable;false;Except;(System.Collections.Generic.IEnumerable,System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Linq;Enumerable;false;Except;(System.Collections.Generic.IEnumerable,System.Collections.Generic.IEnumerable,System.Collections.Generic.IEqualityComparer);;Argument[0].Element;ReturnValue.Element;value;manual | | System.Linq;Enumerable;false;ExceptBy;(System.Collections.Generic.IEnumerable,System.Collections.Generic.IEnumerable,System.Func);;Argument[2];Argument[2].Parameter[delegate-self];value;hq-generated | | System.Linq;Enumerable;false;ExceptBy;(System.Collections.Generic.IEnumerable,System.Collections.Generic.IEnumerable,System.Func,System.Collections.Generic.IEqualityComparer);;Argument[2];Argument[2].Parameter[delegate-self];value;hq-generated | | System.Linq;Enumerable;false;First;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;value;manual | @@ -8615,17 +8615,17 @@ summary | System.Linq;ParallelEnumerable;false;Concat;(System.Linq.ParallelQuery,System.Linq.ParallelQuery);;Argument[1].Element;ReturnValue.Element;value;manual | | System.Linq;ParallelEnumerable;false;Count;(System.Linq.ParallelQuery,System.Func);;Argument[0].Element;Argument[1].Parameter[0];value;manual | | System.Linq;ParallelEnumerable;false;Count;(System.Linq.ParallelQuery,System.Func);;Argument[1];Argument[1].Parameter[delegate-self];value;manual | -| System.Linq;ParallelEnumerable;false;DefaultIfEmpty;(System.Linq.ParallelQuery);;Argument[0].Element;ReturnValue;value;manual | -| System.Linq;ParallelEnumerable;false;DefaultIfEmpty;(System.Linq.ParallelQuery,TSource);;Argument[0].Element;ReturnValue;value;manual | -| System.Linq;ParallelEnumerable;false;DefaultIfEmpty;(System.Linq.ParallelQuery,TSource);;Argument[1];ReturnValue;value;manual | +| System.Linq;ParallelEnumerable;false;DefaultIfEmpty;(System.Linq.ParallelQuery);;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Linq;ParallelEnumerable;false;DefaultIfEmpty;(System.Linq.ParallelQuery,TSource);;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Linq;ParallelEnumerable;false;DefaultIfEmpty;(System.Linq.ParallelQuery,TSource);;Argument[1];ReturnValue.Element;value;manual | | System.Linq;ParallelEnumerable;false;Distinct;(System.Linq.ParallelQuery);;Argument[0].Element;ReturnValue.Element;value;manual | | System.Linq;ParallelEnumerable;false;Distinct;(System.Linq.ParallelQuery,System.Collections.Generic.IEqualityComparer);;Argument[0].Element;ReturnValue.Element;value;manual | | System.Linq;ParallelEnumerable;false;ElementAt;(System.Linq.ParallelQuery,System.Int32);;Argument[0].Element;ReturnValue;value;manual | | System.Linq;ParallelEnumerable;false;ElementAtOrDefault;(System.Linq.ParallelQuery,System.Int32);;Argument[0].Element;ReturnValue;value;manual | -| System.Linq;ParallelEnumerable;false;Except;(System.Linq.ParallelQuery,System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;value;manual | -| System.Linq;ParallelEnumerable;false;Except;(System.Linq.ParallelQuery,System.Collections.Generic.IEnumerable,System.Collections.Generic.IEqualityComparer);;Argument[0].Element;ReturnValue;value;manual | -| System.Linq;ParallelEnumerable;false;Except;(System.Linq.ParallelQuery,System.Linq.ParallelQuery);;Argument[0].Element;ReturnValue;value;manual | -| System.Linq;ParallelEnumerable;false;Except;(System.Linq.ParallelQuery,System.Linq.ParallelQuery,System.Collections.Generic.IEqualityComparer);;Argument[0].Element;ReturnValue;value;manual | +| System.Linq;ParallelEnumerable;false;Except;(System.Linq.ParallelQuery,System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Linq;ParallelEnumerable;false;Except;(System.Linq.ParallelQuery,System.Collections.Generic.IEnumerable,System.Collections.Generic.IEqualityComparer);;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Linq;ParallelEnumerable;false;Except;(System.Linq.ParallelQuery,System.Linq.ParallelQuery);;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Linq;ParallelEnumerable;false;Except;(System.Linq.ParallelQuery,System.Linq.ParallelQuery,System.Collections.Generic.IEqualityComparer);;Argument[0].Element;ReturnValue.Element;value;manual | | System.Linq;ParallelEnumerable;false;First;(System.Linq.ParallelQuery);;Argument[0].Element;ReturnValue;value;manual | | System.Linq;ParallelEnumerable;false;First;(System.Linq.ParallelQuery,System.Func);;Argument[0].Element;Argument[1].Parameter[0];value;manual | | System.Linq;ParallelEnumerable;false;First;(System.Linq.ParallelQuery,System.Func);;Argument[0].Element;ReturnValue;value;manual | @@ -8999,17 +8999,17 @@ summary | System.Linq;Queryable;false;Concat;(System.Linq.IQueryable,System.Collections.Generic.IEnumerable);;Argument[1].Element;ReturnValue.Element;value;manual | | System.Linq;Queryable;false;Count;(System.Linq.IQueryable,System.Linq.Expressions.Expression>);;Argument[0].Element;Argument[1].Parameter[0];value;manual | | System.Linq;Queryable;false;Count;(System.Linq.IQueryable,System.Linq.Expressions.Expression>);;Argument[1];Argument[1].Parameter[delegate-self];value;manual | -| System.Linq;Queryable;false;DefaultIfEmpty;(System.Linq.IQueryable);;Argument[0].Element;ReturnValue;value;manual | -| System.Linq;Queryable;false;DefaultIfEmpty;(System.Linq.IQueryable,TSource);;Argument[0].Element;ReturnValue;value;manual | -| System.Linq;Queryable;false;DefaultIfEmpty;(System.Linq.IQueryable,TSource);;Argument[1];ReturnValue;value;manual | +| System.Linq;Queryable;false;DefaultIfEmpty;(System.Linq.IQueryable);;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Linq;Queryable;false;DefaultIfEmpty;(System.Linq.IQueryable,TSource);;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Linq;Queryable;false;DefaultIfEmpty;(System.Linq.IQueryable,TSource);;Argument[1];ReturnValue.Element;value;manual | | System.Linq;Queryable;false;Distinct;(System.Linq.IQueryable);;Argument[0].Element;ReturnValue.Element;value;manual | | System.Linq;Queryable;false;Distinct;(System.Linq.IQueryable,System.Collections.Generic.IEqualityComparer);;Argument[0].Element;ReturnValue.Element;value;manual | | System.Linq;Queryable;false;DistinctBy;(System.Linq.IQueryable,System.Linq.Expressions.Expression>);;Argument[1];Argument[1].Parameter[delegate-self];value;hq-generated | | System.Linq;Queryable;false;DistinctBy;(System.Linq.IQueryable,System.Linq.Expressions.Expression>,System.Collections.Generic.IEqualityComparer);;Argument[1];Argument[1].Parameter[delegate-self];value;hq-generated | | System.Linq;Queryable;false;ElementAt;(System.Linq.IQueryable,System.Int32);;Argument[0].Element;ReturnValue;value;manual | | System.Linq;Queryable;false;ElementAtOrDefault;(System.Linq.IQueryable,System.Int32);;Argument[0].Element;ReturnValue;value;manual | -| System.Linq;Queryable;false;Except;(System.Linq.IQueryable,System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;value;manual | -| System.Linq;Queryable;false;Except;(System.Linq.IQueryable,System.Collections.Generic.IEnumerable,System.Collections.Generic.IEqualityComparer);;Argument[0].Element;ReturnValue;value;manual | +| System.Linq;Queryable;false;Except;(System.Linq.IQueryable,System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Linq;Queryable;false;Except;(System.Linq.IQueryable,System.Collections.Generic.IEnumerable,System.Collections.Generic.IEqualityComparer);;Argument[0].Element;ReturnValue.Element;value;manual | | System.Linq;Queryable;false;ExceptBy;(System.Linq.IQueryable,System.Collections.Generic.IEnumerable,System.Linq.Expressions.Expression>);;Argument[2];Argument[2].Parameter[delegate-self];value;hq-generated | | System.Linq;Queryable;false;ExceptBy;(System.Linq.IQueryable,System.Collections.Generic.IEnumerable,System.Linq.Expressions.Expression>,System.Collections.Generic.IEqualityComparer);;Argument[2];Argument[2].Parameter[delegate-self];value;hq-generated | | System.Linq;Queryable;false;First;(System.Linq.IQueryable);;Argument[0].Element;ReturnValue;value;manual | From 879d882fa48d15ca5b323603dcb201effe656b5c Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Tue, 6 Feb 2024 15:17:30 +0100 Subject: [PATCH 37/50] Java: fix typo in JndiInjection.qhelp --- java/ql/src/Security/CWE/CWE-074/JndiInjection.qhelp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/src/Security/CWE/CWE-074/JndiInjection.qhelp b/java/ql/src/Security/CWE/CWE-074/JndiInjection.qhelp index b3d1da82fa5..6e3739fafdf 100644 --- a/java/ql/src/Security/CWE/CWE-074/JndiInjection.qhelp +++ b/java/ql/src/Security/CWE/CWE-074/JndiInjection.qhelp @@ -13,7 +13,7 @@ code execution.

    The general recommendation is to avoid passing untrusted data to the InitialContext.lookup method. If the name being used to look up the object must be provided by the user, make -sure that it's not in the form of an absolute URL or that it's the URL pointing to a trused server. +sure that it's not in the form of an absolute URL or that it's the URL pointing to a trusted server.

    From e539aca337c1170ff0250c7e1c2a8c2ef6635671 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 6 Feb 2024 16:05:32 +0000 Subject: [PATCH 38/50] C++: Add an interface for blocking flow out of functions that reach a certain argument. --- .../cpp/ir/dataflow/internal/SsaInternals.qll | 25 +++++++++++++++++- .../cpp/models/interfaces/FlowOutBarrier.qll | 26 +++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 cpp/ql/lib/semmle/code/cpp/models/interfaces/FlowOutBarrier.qll 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 996385f2bfa..3e7cfbe9e11 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 @@ -2,8 +2,11 @@ private import codeql.ssa.Ssa as SsaImplCommon private import semmle.code.cpp.ir.IR private import DataFlowUtil private import DataFlowImplCommon as DataFlowImplCommon +private import semmle.code.cpp.ir.dataflow.internal.ModelUtil private import semmle.code.cpp.models.interfaces.Allocation as Alloc private import semmle.code.cpp.models.interfaces.DataFlow as DataFlow +private import semmle.code.cpp.models.interfaces.FlowOutBarrier as FOB +private import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs as FIO private import semmle.code.cpp.ir.internal.IRCppLanguage private import DataFlowPrivate private import ssa0.SsaInternals as SsaInternals0 @@ -784,10 +787,30 @@ private Node getAPriorDefinition(SsaDefOrUse defOrUse) { ) } +/** + * Holds if there should not be use-use flow out of `n` (or a conversion that + * flows to `n`). + */ +private predicate modeledFlowBarrier(Node n) { + exists(FIO::FunctionInput input, CallInstruction call | + call.getStaticCallTarget().(FOB::FlowOutBarrierFunction).isFlowOutBarrier(input) and + n = callInput(call, input) + ) + or + exists(Operand operand, Instruction instr, Node n0, int indirectionIndex | + modeledFlowBarrier(n0) and + nodeHasInstruction(n0, instr, indirectionIndex) and + conversionFlow(operand, instr, false, _) and + nodeHasOperand(n, operand, indirectionIndex) + ) +} + /** 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 nodeFrom != nodeTo + ssaFlowImpl(defOrUse, nFrom, nodeTo, uncertain) and + not modeledFlowBarrier(nFrom) and + nodeFrom != nodeTo | if uncertain = true then nodeFrom = [nFrom, getAPriorDefinition(defOrUse)] else nodeFrom = nFrom ) diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/FlowOutBarrier.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/FlowOutBarrier.qll new file mode 100644 index 00000000000..d25e4381dcc --- /dev/null +++ b/cpp/ql/lib/semmle/code/cpp/models/interfaces/FlowOutBarrier.qll @@ -0,0 +1,26 @@ +/** + * Provides an abstract class for blocking flow out of functions. To use this + * QL library, create a QL class extending `FlowOutBarrierFunction` with a + * characteristic predicate that selects the function or set of functions you + * are modeling. Within that class, override the predicates provided by + * `FlowOutBarrierFunction` to match the flow within that function. + */ + +import semmle.code.cpp.Function +import FunctionInputsAndOutputs + +/** + * A library function for which flow should not continue after reaching one + * of its inputs. + * + * For example, since `std::swap(a, b)` swaps the values pointed to by `a` + * and `b` there should not be use-use flow out of `a` or `b`. + */ +abstract class FlowOutBarrierFunction extends Function { + /** + * Holds if use-use flow should not continue onwards after reaching + * the argument, qualifier, or buffer represented by `input`. + */ + pragma[nomagic] + abstract predicate isFlowOutBarrier(FunctionInput input); +} From 359b6e14c67cf21a2ad5e10b01307e712f2e980c Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 6 Feb 2024 16:05:48 +0000 Subject: [PATCH 39/50] C++: Block flow out of 'swap'. --- .../semmle/code/cpp/models/implementations/Swap.qll | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Swap.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Swap.qll index 446e659fac5..325fd6f58b2 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Swap.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Swap.qll @@ -1,6 +1,7 @@ import semmle.code.cpp.models.interfaces.DataFlow import semmle.code.cpp.models.interfaces.Taint import semmle.code.cpp.models.interfaces.Alias +import semmle.code.cpp.models.interfaces.FlowOutBarrier /** * The standard function `swap`. A use of `swap` looks like this: @@ -8,7 +9,7 @@ import semmle.code.cpp.models.interfaces.Alias * std::swap(obj1, obj2) * ``` */ -private class Swap extends DataFlowFunction { +private class Swap extends DataFlowFunction, FlowOutBarrierFunction { Swap() { this.hasQualifiedName(["std", "bsl"], "swap") } override predicate hasDataFlow(FunctionInput input, FunctionOutput output) { @@ -18,6 +19,8 @@ private class Swap extends DataFlowFunction { input.isParameterDeref(1) and output.isParameterDeref(0) } + + override predicate isFlowOutBarrier(FunctionInput input) { input.isParameterDeref(1) } } /** @@ -26,7 +29,9 @@ private class Swap extends DataFlowFunction { * obj1.swap(obj2) * ``` */ -private class MemberSwap extends TaintFunction, MemberFunction, AliasFunction { +private class MemberSwap extends TaintFunction, MemberFunction, AliasFunction, + FlowOutBarrierFunction +{ MemberSwap() { this.hasName("swap") and this.getNumberOfParameters() = 1 and @@ -47,4 +52,8 @@ private class MemberSwap extends TaintFunction, MemberFunction, AliasFunction { override predicate parameterEscapesOnlyViaReturn(int index) { index = 0 } override predicate parameterIsAlwaysReturned(int index) { index = 0 } + + override predicate isFlowOutBarrier(FunctionInput input) { + input.isQualifierObject() or input.isParameterDeref(0) + } } From 21b9b3b87f61adfca5a3a5a6b44b4a1262856601 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 6 Feb 2024 16:05:54 +0000 Subject: [PATCH 40/50] C++: Accept test changes. --- .../library-tests/dataflow/taint-tests/map.cpp | 16 ++++++++-------- .../library-tests/dataflow/taint-tests/set.cpp | 8 ++++---- .../dataflow/taint-tests/string.cpp | 4 ++-- .../dataflow/taint-tests/stringstream.cpp | 4 ++-- .../dataflow/taint-tests/vector.cpp | 4 ++-- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp index 8eeb80a0f83..555f39779bf 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp @@ -71,11 +71,11 @@ void test_pair() sink(i.second); // $ MISSING: ast,ir sink(i); // $ ast,ir sink(j.first); - sink(j.second); // $ SPURIOUS: ast,ir - sink(j); // $ SPURIOUS: ast,ir + sink(j.second); // $ SPURIOUS: ast + sink(j); // $ SPURIOUS: ast sink(k.first); - sink(k.second); // $ SPURIOUS: ast,ir - sink(k); // $ SPURIOUS: ast,ir + sink(k.second); // $ SPURIOUS: ast + sink(k); // $ SPURIOUS: ast sink(l.first); sink(l.second); // $ MISSING: ast,ir sink(l); // $ ast,ir @@ -196,10 +196,10 @@ void test_map() sink(m18); // $ ast,ir m15.swap(m16); m17.swap(m18); - sink(m15); // $ SPURIOUS: ast,ir + sink(m15); // $ SPURIOUS: ast sink(m16); // $ ast,ir sink(m17); // $ ast,ir - sink(m18); // $ SPURIOUS: ast,ir + sink(m18); // $ SPURIOUS: ast // merge std::map m19, m20, m21, m22; @@ -345,10 +345,10 @@ void test_unordered_map() sink(m18); // $ ast,ir m15.swap(m16); m17.swap(m18); - sink(m15); // $ SPURIOUS: ast,ir + sink(m15); // $ SPURIOUS: ast sink(m16); // $ ast,ir sink(m17); // $ ast,ir - sink(m18); // $ SPURIOUS: ast,ir + sink(m18); // $ SPURIOUS: ast // merge std::unordered_map m19, m20, m21, m22; diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/set.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/set.cpp index c6c19d90089..7c906fb72d2 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/set.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/set.cpp @@ -81,10 +81,10 @@ void test_set() sink(s15); // $ ast,ir s12.swap(s13); s14.swap(s15); - sink(s12); // $ SPURIOUS: ast,ir + sink(s12); // $ SPURIOUS: ast sink(s13); // $ ast,ir sink(s14); // $ ast,ir - sink(s15); // $ SPURIOUS: ast,ir + sink(s15); // $ SPURIOUS: ast // merge std::set s16, s17, s18, s19; @@ -193,10 +193,10 @@ void test_unordered_set() sink(s15); // $ ast,ir s12.swap(s13); s14.swap(s15); - sink(s12); // $ SPURIOUS: ast,ir + sink(s12); // $ SPURIOUS: ast sink(s13); // $ ast,ir sink(s14); // $ ast,ir - sink(s15); // $ SPURIOUS: ast,ir + sink(s15); // $ SPURIOUS: ast // merge std::unordered_set s16, s17, s18, s19; diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/string.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/string.cpp index e2b99945724..4f2c4afd6b0 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/string.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/string.cpp @@ -280,9 +280,9 @@ void test_string_swap() { s4.swap(s3); sink(s1); // $ ast,ir - sink(s2); // $ SPURIOUS: ast,ir + sink(s2); // $ SPURIOUS: ast sink(s3); // $ ast,ir - sink(s4); // $ SPURIOUS: ast,ir + sink(s4); // $ SPURIOUS: ast } void test_string_clear() { diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/stringstream.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/stringstream.cpp index a84b3606f92..57310dfef6f 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/stringstream.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/stringstream.cpp @@ -118,9 +118,9 @@ void test_stringstream_swap() ss4.swap(ss3); sink(ss1); // $ ast,ir - sink(ss2); // $ SPURIOUS: ast,ir + sink(ss2); // $ SPURIOUS: ast sink(ss3); // $ ast,ir - sink(ss4); // $ SPURIOUS: ast,ir + sink(ss4); // $ SPURIOUS: ast } void test_stringstream_in() 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 a26ac8f0513..14834e2a5e9 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp @@ -114,10 +114,10 @@ void test_vector_swap() { v1.swap(v2); v3.swap(v4); - sink(v1); // $ SPURIOUS: ast,ir + sink(v1); // $ SPURIOUS: ast sink(v2); // $ ast,ir sink(v3); // $ ast,ir - sink(v4); // $ SPURIOUS: ast,ir + sink(v4); // $ SPURIOUS: ast } void test_vector_clear() { From f7fe84adb44417b55241b4369096347415d7cd41 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 6 Feb 2024 16:23:59 +0000 Subject: [PATCH 41/50] C++: Add change note. --- .../lib/change-notes/2024-02-06-flow-out-barrier-function.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 cpp/ql/lib/change-notes/2024-02-06-flow-out-barrier-function.md diff --git a/cpp/ql/lib/change-notes/2024-02-06-flow-out-barrier-function.md b/cpp/ql/lib/change-notes/2024-02-06-flow-out-barrier-function.md new file mode 100644 index 00000000000..70accc67d4c --- /dev/null +++ b/cpp/ql/lib/change-notes/2024-02-06-flow-out-barrier-function.md @@ -0,0 +1,4 @@ +--- +category: feature +--- +* Added an abstract class `FlowOutBarrierFunction` that can be used to block flow out of a function. \ No newline at end of file From 79489114154e7234a41ea3c51a7304d82c3f737f Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 6 Feb 2024 17:38:22 +0000 Subject: [PATCH 42/50] C++: Delete dead code. --- .../ir/implementation/aliased_ssa/Instruction.qll | 7 ------- .../aliased_ssa/internal/SSAConstruction.qll | 14 -------------- .../code/cpp/ir/implementation/raw/Instruction.qll | 7 ------- .../implementation/raw/internal/IRConstruction.qll | 6 ------ .../implementation/unaliased_ssa/Instruction.qll | 7 ------- .../unaliased_ssa/internal/SSAConstruction.qll | 14 -------------- 6 files changed, 55 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 bf07e73d5fe..189ffce2903 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 @@ -2125,13 +2125,6 @@ class ChiInstruction extends Instruction { */ final Instruction getPartial() { result = this.getPartialOperand().getDef() } - /** - * Gets the bit range `[startBit, endBit)` updated by the partial operand of this `ChiInstruction`, relative to the start address of the total operand. - */ - final predicate getUpdatedInterval(int startBit, int endBit) { - Construction::getIntervalUpdatedByChi(this, startBit, endBit) - } - /** * Holds if the `ChiPartialOperand` totally, but not exactly, overlaps with the `ChiTotalOperand`. * This means that the `ChiPartialOperand` will not override the entire memory associated with 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 04522e4fe18..209c42726b7 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 @@ -233,20 +233,6 @@ private module Cached { ) } - /** - * Holds if the partial operand of this `ChiInstruction` updates the bit range - * `[startBitOffset, endBitOffset)` of the total operand. - */ - cached - predicate getIntervalUpdatedByChi(ChiInstruction chi, int startBitOffset, int endBitOffset) { - exists(Alias::MemoryLocation location, OldInstruction oldInstruction | - oldInstruction = getOldInstruction(chi.getPartial()) and - location = Alias::getResultMemoryLocation(oldInstruction) and - startBitOffset = Alias::getStartBitOffset(location) and - endBitOffset = Alias::getEndBitOffset(location) - ) - } - /** * Holds if `operand` totally overlaps with its definition and consumes the bit range * `[startBitOffset, endBitOffset)`. 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 bf07e73d5fe..189ffce2903 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 @@ -2125,13 +2125,6 @@ class ChiInstruction extends Instruction { */ final Instruction getPartial() { result = this.getPartialOperand().getDef() } - /** - * Gets the bit range `[startBit, endBit)` updated by the partial operand of this `ChiInstruction`, relative to the start address of the total operand. - */ - final predicate getUpdatedInterval(int startBit, int endBit) { - Construction::getIntervalUpdatedByChi(this, startBit, endBit) - } - /** * Holds if the `ChiPartialOperand` totally, but not exactly, overlaps with the `ChiTotalOperand`. * This means that the `ChiPartialOperand` will not override the entire memory associated with the 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 7e4c3e7934c..07764ef7aa4 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 @@ -202,12 +202,6 @@ Instruction getMemoryOperandDefinition( none() } -/** - * Holds if the partial operand of this `ChiInstruction` updates the bit range - * `[startBitOffset, endBitOffset)` of the total operand. - */ -predicate getIntervalUpdatedByChi(ChiInstruction chi, int startBit, int endBit) { none() } - /** * Holds if the operand totally overlaps with its definition and consumes the * bit range `[startBitOffset, endBitOffset)`. 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 bf07e73d5fe..189ffce2903 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 @@ -2125,13 +2125,6 @@ class ChiInstruction extends Instruction { */ final Instruction getPartial() { result = this.getPartialOperand().getDef() } - /** - * Gets the bit range `[startBit, endBit)` updated by the partial operand of this `ChiInstruction`, relative to the start address of the total operand. - */ - final predicate getUpdatedInterval(int startBit, int endBit) { - Construction::getIntervalUpdatedByChi(this, startBit, endBit) - } - /** * Holds if the `ChiPartialOperand` totally, but not exactly, overlaps with the `ChiTotalOperand`. * This means that the `ChiPartialOperand` will not override the entire memory associated with 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 04522e4fe18..209c42726b7 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 @@ -233,20 +233,6 @@ private module Cached { ) } - /** - * Holds if the partial operand of this `ChiInstruction` updates the bit range - * `[startBitOffset, endBitOffset)` of the total operand. - */ - cached - predicate getIntervalUpdatedByChi(ChiInstruction chi, int startBitOffset, int endBitOffset) { - exists(Alias::MemoryLocation location, OldInstruction oldInstruction | - oldInstruction = getOldInstruction(chi.getPartial()) and - location = Alias::getResultMemoryLocation(oldInstruction) and - startBitOffset = Alias::getStartBitOffset(location) and - endBitOffset = Alias::getEndBitOffset(location) - ) - } - /** * Holds if `operand` totally overlaps with its definition and consumes the bit range * `[startBitOffset, endBitOffset)`. From b68824a337864d544fe9377fa6567dccb313cab4 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 6 Feb 2024 17:41:11 +0000 Subject: [PATCH 43/50] C#: Sync identical files. --- .../ir/implementation/raw/Instruction.qll | 7 ------- .../implementation/raw/internal/IRConstruction.qll | 7 ------- .../implementation/unaliased_ssa/Instruction.qll | 7 ------- .../unaliased_ssa/internal/SSAConstruction.qll | 14 -------------- 4 files changed, 35 deletions(-) diff --git a/csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll b/csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll index bf07e73d5fe..189ffce2903 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll @@ -2125,13 +2125,6 @@ class ChiInstruction extends Instruction { */ final Instruction getPartial() { result = this.getPartialOperand().getDef() } - /** - * Gets the bit range `[startBit, endBit)` updated by the partial operand of this `ChiInstruction`, relative to the start address of the total operand. - */ - final predicate getUpdatedInterval(int startBit, int endBit) { - Construction::getIntervalUpdatedByChi(this, startBit, endBit) - } - /** * Holds if the `ChiPartialOperand` totally, but not exactly, overlaps with the `ChiTotalOperand`. * This means that the `ChiPartialOperand` will not override the entire memory associated with the diff --git a/csharp/ql/src/experimental/ir/implementation/raw/internal/IRConstruction.qll b/csharp/ql/src/experimental/ir/implementation/raw/internal/IRConstruction.qll index 8297fedb28e..5811f2ff946 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/internal/IRConstruction.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/internal/IRConstruction.qll @@ -216,13 +216,6 @@ private module Cached { result = getMemoryOperandDefinition(instr, _, _) } - /** - * Holds if the partial operand of this `ChiInstruction` updates the bit range - * `[startBitOffset, endBitOffset)` of the total operand. - */ - cached - predicate getIntervalUpdatedByChi(ChiInstruction chi, int startBit, int endBit) { none() } - /** * Holds if the operand totally overlaps with its definition and consumes the * bit range `[startBitOffset, endBitOffset)`. diff --git a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Instruction.qll b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Instruction.qll index bf07e73d5fe..189ffce2903 100644 --- a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Instruction.qll +++ b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Instruction.qll @@ -2125,13 +2125,6 @@ class ChiInstruction extends Instruction { */ final Instruction getPartial() { result = this.getPartialOperand().getDef() } - /** - * Gets the bit range `[startBit, endBit)` updated by the partial operand of this `ChiInstruction`, relative to the start address of the total operand. - */ - final predicate getUpdatedInterval(int startBit, int endBit) { - Construction::getIntervalUpdatedByChi(this, startBit, endBit) - } - /** * Holds if the `ChiPartialOperand` totally, but not exactly, overlaps with the `ChiTotalOperand`. * This means that the `ChiPartialOperand` will not override the entire memory associated with the diff --git a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll index 04522e4fe18..209c42726b7 100644 --- a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll +++ b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll @@ -233,20 +233,6 @@ private module Cached { ) } - /** - * Holds if the partial operand of this `ChiInstruction` updates the bit range - * `[startBitOffset, endBitOffset)` of the total operand. - */ - cached - predicate getIntervalUpdatedByChi(ChiInstruction chi, int startBitOffset, int endBitOffset) { - exists(Alias::MemoryLocation location, OldInstruction oldInstruction | - oldInstruction = getOldInstruction(chi.getPartial()) and - location = Alias::getResultMemoryLocation(oldInstruction) and - startBitOffset = Alias::getStartBitOffset(location) and - endBitOffset = Alias::getEndBitOffset(location) - ) - } - /** * Holds if `operand` totally overlaps with its definition and consumes the bit range * `[startBitOffset, endBitOffset)`. From e71f0fc1ba546980234768bb73c93d0ab8fa46b9 Mon Sep 17 00:00:00 2001 From: Henry Mercer Date: Tue, 6 Feb 2024 19:51:13 +0000 Subject: [PATCH 44/50] Add supported build modes to extractor metadata --- csharp/codeql-extractor.yml | 3 +++ go/codeql-extractor.yml | 3 +++ ql/codeql-extractor.yml | 2 ++ ruby/codeql-extractor.yml | 2 ++ swift/codeql-extractor.yml | 3 +++ 5 files changed, 13 insertions(+) diff --git a/csharp/codeql-extractor.yml b/csharp/codeql-extractor.yml index 1990b2080e7..0f65d9bc2e5 100644 --- a/csharp/codeql-extractor.yml +++ b/csharp/codeql-extractor.yml @@ -6,6 +6,9 @@ version: 1.22.1 column_kind: "utf16" extra_env_vars: DOTNET_GENERATE_ASPNET_CERTIFICATE: "false" +build_modes: + - autobuild + - manual github_api_languages: - C# scc_languages: diff --git a/go/codeql-extractor.yml b/go/codeql-extractor.yml index ccb1c721060..20cfe987ef3 100644 --- a/go/codeql-extractor.yml +++ b/go/codeql-extractor.yml @@ -6,6 +6,9 @@ pull_request_triggers: - "**/glide.yaml" - "**/Gopkg.toml" column_kind: "utf8" +build_modes: + - autobuild + - manual github_api_languages: - Go scc_languages: diff --git a/ql/codeql-extractor.yml b/ql/codeql-extractor.yml index fb5027f8f5b..516845588fe 100644 --- a/ql/codeql-extractor.yml +++ b/ql/codeql-extractor.yml @@ -3,6 +3,8 @@ display_name: "QL" version: 0.0.1 column_kind: "utf8" legacy_qltest_extraction: true +build_modes: + - none github_api_languages: - CodeQL scc_languages: diff --git a/ruby/codeql-extractor.yml b/ruby/codeql-extractor.yml index 1c9cfbdf052..9b949a1a4ab 100644 --- a/ruby/codeql-extractor.yml +++ b/ruby/codeql-extractor.yml @@ -3,6 +3,8 @@ display_name: "Ruby" version: 0.1.0 column_kind: "utf8" legacy_qltest_extraction: true +build_modes: + - none github_api_languages: - Ruby scc_languages: diff --git a/swift/codeql-extractor.yml b/swift/codeql-extractor.yml index 0439f0ea3e0..c7c0bdca75a 100644 --- a/swift/codeql-extractor.yml +++ b/swift/codeql-extractor.yml @@ -3,6 +3,9 @@ display_name: "Swift" version: 0.1.0 column_kind: "utf8" legacy_qltest_extraction: true +build_modes: + - autobuild + - manual github_api_languages: - Swift scc_languages: From 565426940cd912a9a217ba81bdd880be45f3f3cf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Feb 2024 03:32:07 +0000 Subject: [PATCH 45/50] Bump the extractor-dependencies group in /go/extractor with 1 update Bumps the extractor-dependencies group in /go/extractor with 1 update: [golang.org/x/mod](https://github.com/golang/mod). Updates `golang.org/x/mod` from 0.14.0 to 0.15.0 - [Commits](https://github.com/golang/mod/compare/v0.14.0...v0.15.0) --- updated-dependencies: - dependency-name: golang.org/x/mod dependency-type: direct:production update-type: version-update:semver-minor dependency-group: extractor-dependencies ... Signed-off-by: dependabot[bot] --- go/extractor/go.mod | 2 +- go/extractor/go.sum | 4 ++-- go/extractor/vendor/modules.txt | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/go/extractor/go.mod b/go/extractor/go.mod index 74928220e83..d4a00dcd158 100644 --- a/go/extractor/go.mod +++ b/go/extractor/go.mod @@ -3,6 +3,6 @@ module github.com/github/codeql-go/extractor go 1.21 require ( - golang.org/x/mod v0.14.0 + golang.org/x/mod v0.15.0 golang.org/x/tools v0.17.0 ) diff --git a/go/extractor/go.sum b/go/extractor/go.sum index 84d5fdb7e0b..f3a7decbd45 100644 --- a/go/extractor/go.sum +++ b/go/extractor/go.sum @@ -1,5 +1,5 @@ -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= +golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= diff --git a/go/extractor/vendor/modules.txt b/go/extractor/vendor/modules.txt index c967e6f41d5..fa3a89a509d 100644 --- a/go/extractor/vendor/modules.txt +++ b/go/extractor/vendor/modules.txt @@ -1,4 +1,4 @@ -# golang.org/x/mod v0.14.0 +# golang.org/x/mod v0.15.0 ## explicit; go 1.18 golang.org/x/mod/internal/lazyregexp golang.org/x/mod/modfile From 4b046ad67060d1467585276238fdcc3da2dfd5dd Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 7 Feb 2024 10:31:18 +0000 Subject: [PATCH 46/50] C++: Also clear the 0'th argument of 'swap'. --- cpp/ql/lib/semmle/code/cpp/models/implementations/Swap.qll | 2 +- cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Swap.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Swap.qll index 325fd6f58b2..cb757800d65 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Swap.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Swap.qll @@ -20,7 +20,7 @@ private class Swap extends DataFlowFunction, FlowOutBarrierFunction { output.isParameterDeref(0) } - override predicate isFlowOutBarrier(FunctionInput input) { input.isParameterDeref(1) } + override predicate isFlowOutBarrier(FunctionInput input) { input.isParameterDeref([0, 1]) } } /** diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp index eeefa6dd427..1ca4957b529 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp @@ -212,7 +212,7 @@ void test_swap() { std::swap(x, y); - sink(x); // $ SPURIOUS: ast,ir + sink(x); // $ SPURIOUS: ast sink(y); // $ ast,ir } From d0b0440427974b3d9ee2226d7b79824205d4619d Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 7 Feb 2024 11:38:02 +0000 Subject: [PATCH 47/50] C++: Add a testcase with failing IR generation. --- .../library-tests/ir/ir/PrintAST.expected | 25 ++++++++++++++ .../library-tests/ir/ir/aliased_ir.expected | 10 ++++++ .../ir/ir/aliased_ssa_consistency.expected | 9 ++--- .../aliased_ssa_consistency_unsound.expected | 9 ++--- cpp/ql/test/library-tests/ir/ir/ir.cpp | 8 +++++ .../ir/ir/operand_locations.expected | 4 +++ .../ir/ir/raw_consistency.expected | 3 ++ .../test/library-tests/ir/ir/raw_ir.expected | 33 +++++++++++++++++++ .../ir/ir/unaliased_ssa_consistency.expected | 9 ++--- ...unaliased_ssa_consistency_unsound.expected | 9 ++--- 10 files changed, 103 insertions(+), 16 deletions(-) diff --git a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected index c14fbc66926..41fb6a467b0 100644 --- a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected +++ b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected @@ -16132,6 +16132,31 @@ ir.cpp: # 2112| getExpr(): [VariableAccess] end # 2112| Type = [CharPointerType] char * # 2112| ValueCategory = prvalue(load) +# 2115| [CopyAssignmentOperator] HasOperatorBool& HasOperatorBool::operator=(HasOperatorBool const&) +# 2115| : +#-----| getParameter(0): [Parameter] (unnamed parameter 0) +#-----| Type = [LValueReferenceType] const HasOperatorBool & +# 2115| [MoveAssignmentOperator] HasOperatorBool& HasOperatorBool::operator=(HasOperatorBool&&) +# 2115| : +#-----| getParameter(0): [Parameter] (unnamed parameter 0) +#-----| Type = [RValueReferenceType] HasOperatorBool && +# 2116| [ConversionOperator] bool HasOperatorBool::operator bool() +# 2116| : +# 2119| [TopLevelFunction] void call_as_child_of_ConditionDeclExpr() +# 2119| : +# 2119| getEntryPoint(): [BlockStmt] { ... } +# 2120| getStmt(0): [IfStmt] if (...) ... +# 2120| getCondition(): [ConditionDeclExpr] (condition decl) +# 2120| Type = [BoolType] bool +# 2120| ValueCategory = prvalue +# 2120| getChild(0): [FunctionCall] call to operator bool +# 2120| Type = [BoolType] bool +# 2120| ValueCategory = prvalue +# 2120| getQualifier(): [VariableAccess] b +# 2120| Type = [Struct] HasOperatorBool +# 2120| ValueCategory = prvalue(load) +# 2120| getThen(): [BlockStmt] { ... } +# 2121| 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 3949bb9f0f6..cd1c7455c8e 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected @@ -12441,6 +12441,16 @@ ir.cpp: # 2109| v2109_12(void) = AliasedUse : m2109_3 # 2109| v2109_13(void) = ExitFunction : +# 2119| void call_as_child_of_ConditionDeclExpr() +# 2119| Block 0 +# 2119| v2119_1(void) = EnterFunction : +# 2119| m2119_2(unknown) = AliasedDefinition : +# 2119| m2119_3(unknown) = InitializeNonLocal : +# 2119| m2119_4(unknown) = Chi : total:m2119_2, partial:m2119_3 +# 2120| r2120_1(glval) = VariableAddress[b] : +# 2120| r2120_2(HasOperatorBool) = Constant[0] : +# 2120| m2120_3(HasOperatorBool) = Store[b] : &:r2120_1, r2120_2 + 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 79887fffc1f..d4467596ca9 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 @@ -6,13 +6,18 @@ missingOperandType duplicateChiOperand sideEffectWithoutPrimary instructionWithoutSuccessor +| ir.cpp:2120:25:2120:42 | Store: 0 | Instruction 'Store: 0' has no successors in function '$@'. | ir.cpp:2119:6:2119:39 | void call_as_child_of_ConditionDeclExpr() | void call_as_child_of_ConditionDeclExpr() | ambiguousSuccessors unexplainedLoop unnecessaryPhiInstruction memoryOperandDefinitionIsUnmodeled operandAcrossFunctions instructionWithoutUniqueBlock +missingCanonicalLanguageType +multipleCanonicalLanguageTypes containsLoopOfForwardEdges +missingIRType +multipleIRTypes lostReachability backEdgeCountMismatch useNotDominatedByDefinition @@ -24,8 +29,4 @@ nonUniqueEnclosingIRFunction fieldAddressOnNonPointer thisArgumentIsNonPointer nonUniqueIRVariable -missingCanonicalLanguageType -multipleCanonicalLanguageTypes -missingIRType -multipleIRTypes missingCppType 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 79887fffc1f..d4467596ca9 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 @@ -6,13 +6,18 @@ missingOperandType duplicateChiOperand sideEffectWithoutPrimary instructionWithoutSuccessor +| ir.cpp:2120:25:2120:42 | Store: 0 | Instruction 'Store: 0' has no successors in function '$@'. | ir.cpp:2119:6:2119:39 | void call_as_child_of_ConditionDeclExpr() | void call_as_child_of_ConditionDeclExpr() | ambiguousSuccessors unexplainedLoop unnecessaryPhiInstruction memoryOperandDefinitionIsUnmodeled operandAcrossFunctions instructionWithoutUniqueBlock +missingCanonicalLanguageType +multipleCanonicalLanguageTypes containsLoopOfForwardEdges +missingIRType +multipleIRTypes lostReachability backEdgeCountMismatch useNotDominatedByDefinition @@ -24,8 +29,4 @@ nonUniqueEnclosingIRFunction fieldAddressOnNonPointer thisArgumentIsNonPointer nonUniqueIRVariable -missingCanonicalLanguageType -multipleCanonicalLanguageTypes -missingIRType -multipleIRTypes missingCppType diff --git a/cpp/ql/test/library-tests/ir/ir/ir.cpp b/cpp/ql/test/library-tests/ir/ir/ir.cpp index adaae6b7e59..ce03076f0c3 100644 --- a/cpp/ql/test/library-tests/ir/ir/ir.cpp +++ b/cpp/ql/test/library-tests/ir/ir/ir.cpp @@ -2112,4 +2112,12 @@ char* test_strtod(char *s) { return end; } +struct HasOperatorBool { + operator bool(); +}; + +void call_as_child_of_ConditionDeclExpr() { + if(HasOperatorBool b = HasOperatorBool()) {} +} + // semmle-extractor-options: -std=c++17 --clang diff --git a/cpp/ql/test/library-tests/ir/ir/operand_locations.expected b/cpp/ql/test/library-tests/ir/ir/operand_locations.expected index 1a3da84e78f..7748a5aae38 100644 --- a/cpp/ql/test/library-tests/ir/ir/operand_locations.expected +++ b/cpp/ql/test/library-tests/ir/ir/operand_locations.expected @@ -10070,6 +10070,10 @@ | ir.cpp:2112:10:2112:12 | Address | &:r2112_2 | | ir.cpp:2112:10:2112:12 | Load | m2111_11 | | ir.cpp:2112:10:2112:12 | StoreValue | r2112_3 | +| ir.cpp:2119:6:2119:39 | ChiPartial | partial:m2119_3 | +| ir.cpp:2119:6:2119:39 | ChiTotal | total:m2119_2 | +| ir.cpp:2120:6:2120:42 | Address | &:r2120_1 | +| ir.cpp:2120:25:2120:42 | StoreValue | r2120_2 | | perf-regression.cpp:6:3:6:5 | Address | &:r6_5 | | perf-regression.cpp:6:3:6:5 | Address | &:r6_5 | | perf-regression.cpp:6:3:6:5 | Address | &:r6_7 | 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 d2a11541fd1..0c7c83bd5dc 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_consistency.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_consistency.expected @@ -1,4 +1,5 @@ missingOperand +| ir.cpp:2120:6:2120:42 | CopyValue: (condition decl) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | ir.cpp:2119:6:2119:39 | void call_as_child_of_ConditionDeclExpr() | void call_as_child_of_ConditionDeclExpr() | unexpectedOperand duplicateOperand missingPhiOperand @@ -6,6 +7,8 @@ missingOperandType duplicateChiOperand sideEffectWithoutPrimary instructionWithoutSuccessor +| ir.cpp:2120:22:2120:22 | IndirectMayWriteSideEffect: b | Instruction 'IndirectMayWriteSideEffect: b' has no successors in function '$@'. | ir.cpp:2119:6:2119:39 | void call_as_child_of_ConditionDeclExpr() | void call_as_child_of_ConditionDeclExpr() | +| ir.cpp:2120:25:2120:42 | Store: 0 | Instruction 'Store: 0' has no successors in function '$@'. | ir.cpp:2119:6:2119:39 | void call_as_child_of_ConditionDeclExpr() | void call_as_child_of_ConditionDeclExpr() | ambiguousSuccessors unexplainedLoop unnecessaryPhiInstruction 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 af98e5f6419..a67cbbb0e14 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -11647,6 +11647,39 @@ ir.cpp: # 2109| v2109_11(void) = AliasedUse : ~m? # 2109| v2109_12(void) = ExitFunction : +# 2119| void call_as_child_of_ConditionDeclExpr() +# 2119| Block 0 +# 2119| v2119_1(void) = EnterFunction : +# 2119| mu2119_2(unknown) = AliasedDefinition : +# 2119| mu2119_3(unknown) = InitializeNonLocal : +# 2120| r2120_1(glval) = VariableAddress[b] : +# 2120| r2120_2(HasOperatorBool) = Constant[0] : +# 2120| mu2120_3(HasOperatorBool) = Store[b] : &:r2120_1, r2120_2 + +# 2120| (no string representation) +# 2120| CopyValue: (condition decl) +# 2120| ConditionalBranch: (condition decl) +#-----| False -> Block 3 +#-----| True -> Block 2 + +# 2120| Block 1 +# 2120| r2120_4(glval) = VariableAddress[b] : +# 2120| r2120_5(glval) = FunctionAddress[operator bool] : +# 2120| r2120_6(bool) = Call[operator bool] : func:r2120_5, this:r2120_4 +# 2120| mu2120_7(unknown) = ^CallSideEffect : ~m? +# 2120| v2120_8(void) = ^IndirectReadSideEffect[-1] : &:r2120_4, ~m? +# 2120| mu2120_9(HasOperatorBool) = ^IndirectMayWriteSideEffect[-1] : &:r2120_4 + +# 2120| Block 2 +# 2120| v2120_10(void) = NoOp : +#-----| Goto -> Block 3 + +# 2121| Block 3 +# 2121| v2121_1(void) = NoOp : +# 2119| v2119_4(void) = ReturnVoid : +# 2119| v2119_5(void) = AliasedUse : ~m? +# 2119| v2119_6(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 79887fffc1f..d4467596ca9 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 @@ -6,13 +6,18 @@ missingOperandType duplicateChiOperand sideEffectWithoutPrimary instructionWithoutSuccessor +| ir.cpp:2120:25:2120:42 | Store: 0 | Instruction 'Store: 0' has no successors in function '$@'. | ir.cpp:2119:6:2119:39 | void call_as_child_of_ConditionDeclExpr() | void call_as_child_of_ConditionDeclExpr() | ambiguousSuccessors unexplainedLoop unnecessaryPhiInstruction memoryOperandDefinitionIsUnmodeled operandAcrossFunctions instructionWithoutUniqueBlock +missingCanonicalLanguageType +multipleCanonicalLanguageTypes containsLoopOfForwardEdges +missingIRType +multipleIRTypes lostReachability backEdgeCountMismatch useNotDominatedByDefinition @@ -24,8 +29,4 @@ nonUniqueEnclosingIRFunction fieldAddressOnNonPointer thisArgumentIsNonPointer nonUniqueIRVariable -missingCanonicalLanguageType -multipleCanonicalLanguageTypes -missingIRType -multipleIRTypes missingCppType 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 79887fffc1f..d4467596ca9 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 @@ -6,13 +6,18 @@ missingOperandType duplicateChiOperand sideEffectWithoutPrimary instructionWithoutSuccessor +| ir.cpp:2120:25:2120:42 | Store: 0 | Instruction 'Store: 0' has no successors in function '$@'. | ir.cpp:2119:6:2119:39 | void call_as_child_of_ConditionDeclExpr() | void call_as_child_of_ConditionDeclExpr() | ambiguousSuccessors unexplainedLoop unnecessaryPhiInstruction memoryOperandDefinitionIsUnmodeled operandAcrossFunctions instructionWithoutUniqueBlock +missingCanonicalLanguageType +multipleCanonicalLanguageTypes containsLoopOfForwardEdges +missingIRType +multipleIRTypes lostReachability backEdgeCountMismatch useNotDominatedByDefinition @@ -24,8 +29,4 @@ nonUniqueEnclosingIRFunction fieldAddressOnNonPointer thisArgumentIsNonPointer nonUniqueIRVariable -missingCanonicalLanguageType -multipleCanonicalLanguageTypes -missingIRType -multipleIRTypes missingCppType From edc7903c69280dbe2110f2f62b115dbaa1edb00a Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 7 Feb 2024 11:45:13 +0000 Subject: [PATCH 48/50] C++: Add a predicate for getting the 0'th child of a 'ConditionDeclExpr' without casting it to a 'VariableAccess' and use it in IR generation. --- cpp/ql/lib/semmle/code/cpp/exprs/Assignment.qll | 10 ++++++++-- .../ir/implementation/raw/internal/TranslatedExpr.qll | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/Assignment.qll b/cpp/ql/lib/semmle/code/cpp/exprs/Assignment.qll index f30c9ec8d67..56ec87b23f2 100644 --- a/cpp/ql/lib/semmle/code/cpp/exprs/Assignment.qll +++ b/cpp/ql/lib/semmle/code/cpp/exprs/Assignment.qll @@ -244,9 +244,15 @@ class ConditionDeclExpr extends Expr, @condition_decl { /** * Gets the compiler-generated variable access that conceptually occurs after - * the initialization of the declared variable. + * the initialization of the declared variable, if any. */ - VariableAccess getVariableAccess() { result = this.getChild(0) } + VariableAccess getVariableAccess() { result = this.getExpr() } + + /** + * Gets the expression that is evaluated after the initialization of the declared + * variable. + */ + Expr getExpr() { result = this.getChild(0) } /** * Gets the expression that initializes the declared variable. This predicate 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 1e4b52283fc..4bf21a43f63 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 @@ -3173,7 +3173,7 @@ class TranslatedConditionDeclExpr extends TranslatedNonConstantExpr { private TranslatedConditionDecl getDecl() { result = getTranslatedConditionDecl(expr) } private TranslatedExpr getConditionExpr() { - result = getTranslatedExpr(expr.getVariableAccess().getFullyConverted()) + result = getTranslatedExpr(expr.getExpr().getFullyConverted()) } } From fe5eca41345cae8128da7ba0468e4ee8ecdcff22 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 7 Feb 2024 11:45:40 +0000 Subject: [PATCH 49/50] C++: Accept test changes. --- .../library-tests/ir/ir/aliased_ir.expected | 36 +++++++++++++++---- .../ir/ir/aliased_ssa_consistency.expected | 1 - .../aliased_ssa_consistency_unsound.expected | 1 - .../ir/ir/operand_locations.expected | 13 +++++++ .../ir/ir/raw_consistency.expected | 3 -- .../test/library-tests/ir/ir/raw_ir.expected | 32 ++++++++--------- .../ir/ir/unaliased_ssa_consistency.expected | 1 - ...unaliased_ssa_consistency_unsound.expected | 1 - 8 files changed, 56 insertions(+), 32 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 cd1c7455c8e..f21ffad9dbb 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected @@ -12443,13 +12443,35 @@ ir.cpp: # 2119| void call_as_child_of_ConditionDeclExpr() # 2119| Block 0 -# 2119| v2119_1(void) = EnterFunction : -# 2119| m2119_2(unknown) = AliasedDefinition : -# 2119| m2119_3(unknown) = InitializeNonLocal : -# 2119| m2119_4(unknown) = Chi : total:m2119_2, partial:m2119_3 -# 2120| r2120_1(glval) = VariableAddress[b] : -# 2120| r2120_2(HasOperatorBool) = Constant[0] : -# 2120| m2120_3(HasOperatorBool) = Store[b] : &:r2120_1, r2120_2 +# 2119| v2119_1(void) = EnterFunction : +# 2119| m2119_2(unknown) = AliasedDefinition : +# 2119| m2119_3(unknown) = InitializeNonLocal : +# 2119| m2119_4(unknown) = Chi : total:m2119_2, partial:m2119_3 +# 2120| r2120_1(glval) = VariableAddress[b] : +# 2120| r2120_2(HasOperatorBool) = Constant[0] : +# 2120| m2120_3(HasOperatorBool) = Store[b] : &:r2120_1, r2120_2 +# 2120| r2120_4(glval) = VariableAddress[b] : +# 2120| r2120_5(glval) = FunctionAddress[operator bool] : +# 2120| r2120_6(bool) = Call[operator bool] : func:r2120_5, this:r2120_4 +# 2120| m2120_7(unknown) = ^CallSideEffect : ~m2119_4 +# 2120| m2120_8(unknown) = Chi : total:m2119_4, partial:m2120_7 +# 2120| v2120_9(void) = ^IndirectReadSideEffect[-1] : &:r2120_4, m2120_3 +# 2120| m2120_10(HasOperatorBool) = ^IndirectMayWriteSideEffect[-1] : &:r2120_4 +# 2120| m2120_11(HasOperatorBool) = Chi : total:m2120_3, partial:m2120_10 +# 2120| r2120_12(bool) = CopyValue : r2120_6 +# 2120| v2120_13(void) = ConditionalBranch : r2120_12 +#-----| False -> Block 2 +#-----| True -> Block 1 + +# 2120| Block 1 +# 2120| v2120_14(void) = NoOp : +#-----| Goto -> Block 2 + +# 2121| Block 2 +# 2121| v2121_1(void) = NoOp : +# 2119| v2119_5(void) = ReturnVoid : +# 2119| v2119_6(void) = AliasedUse : ~m2120_8 +# 2119| v2119_7(void) = ExitFunction : perf-regression.cpp: # 6| void Big::Big() 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 d4467596ca9..b93c7d2649f 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 @@ -6,7 +6,6 @@ missingOperandType duplicateChiOperand sideEffectWithoutPrimary instructionWithoutSuccessor -| ir.cpp:2120:25:2120:42 | Store: 0 | Instruction 'Store: 0' has no successors in function '$@'. | ir.cpp:2119:6:2119:39 | void call_as_child_of_ConditionDeclExpr() | void call_as_child_of_ConditionDeclExpr() | ambiguousSuccessors unexplainedLoop unnecessaryPhiInstruction 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 d4467596ca9..b93c7d2649f 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 @@ -6,7 +6,6 @@ missingOperandType duplicateChiOperand sideEffectWithoutPrimary instructionWithoutSuccessor -| ir.cpp:2120:25:2120:42 | Store: 0 | Instruction 'Store: 0' has no successors in function '$@'. | ir.cpp:2119:6:2119:39 | void call_as_child_of_ConditionDeclExpr() | void call_as_child_of_ConditionDeclExpr() | ambiguousSuccessors unexplainedLoop unnecessaryPhiInstruction diff --git a/cpp/ql/test/library-tests/ir/ir/operand_locations.expected b/cpp/ql/test/library-tests/ir/ir/operand_locations.expected index 7748a5aae38..2af9a3488e0 100644 --- a/cpp/ql/test/library-tests/ir/ir/operand_locations.expected +++ b/cpp/ql/test/library-tests/ir/ir/operand_locations.expected @@ -10072,7 +10072,20 @@ | ir.cpp:2112:10:2112:12 | StoreValue | r2112_3 | | ir.cpp:2119:6:2119:39 | ChiPartial | partial:m2119_3 | | ir.cpp:2119:6:2119:39 | ChiTotal | total:m2119_2 | +| ir.cpp:2119:6:2119:39 | SideEffect | ~m2120_8 | | ir.cpp:2120:6:2120:42 | Address | &:r2120_1 | +| ir.cpp:2120:6:2120:42 | Condition | r2120_12 | +| ir.cpp:2120:22:2120:22 | Address | &:r2120_4 | +| ir.cpp:2120:22:2120:22 | Address | &:r2120_4 | +| ir.cpp:2120:22:2120:22 | Arg(this) | this:r2120_4 | +| ir.cpp:2120:22:2120:22 | CallTarget | func:r2120_5 | +| ir.cpp:2120:22:2120:22 | ChiPartial | partial:m2120_7 | +| ir.cpp:2120:22:2120:22 | ChiPartial | partial:m2120_10 | +| ir.cpp:2120:22:2120:22 | ChiTotal | total:m2119_4 | +| ir.cpp:2120:22:2120:22 | ChiTotal | total:m2120_3 | +| ir.cpp:2120:22:2120:22 | SideEffect | m2120_3 | +| ir.cpp:2120:22:2120:22 | SideEffect | ~m2119_4 | +| ir.cpp:2120:22:2120:22 | Unary | r2120_6 | | ir.cpp:2120:25:2120:42 | StoreValue | r2120_2 | | perf-regression.cpp:6:3:6:5 | Address | &:r6_5 | | perf-regression.cpp:6:3:6:5 | Address | &:r6_5 | 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 0c7c83bd5dc..d2a11541fd1 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_consistency.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_consistency.expected @@ -1,5 +1,4 @@ missingOperand -| ir.cpp:2120:6:2120:42 | CopyValue: (condition decl) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | ir.cpp:2119:6:2119:39 | void call_as_child_of_ConditionDeclExpr() | void call_as_child_of_ConditionDeclExpr() | unexpectedOperand duplicateOperand missingPhiOperand @@ -7,8 +6,6 @@ missingOperandType duplicateChiOperand sideEffectWithoutPrimary instructionWithoutSuccessor -| ir.cpp:2120:22:2120:22 | IndirectMayWriteSideEffect: b | Instruction 'IndirectMayWriteSideEffect: b' has no successors in function '$@'. | ir.cpp:2119:6:2119:39 | void call_as_child_of_ConditionDeclExpr() | void call_as_child_of_ConditionDeclExpr() | -| ir.cpp:2120:25:2120:42 | Store: 0 | Instruction 'Store: 0' has no successors in function '$@'. | ir.cpp:2119:6:2119:39 | void call_as_child_of_ConditionDeclExpr() | void call_as_child_of_ConditionDeclExpr() | ambiguousSuccessors unexplainedLoop unnecessaryPhiInstruction 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 a67cbbb0e14..53361dd907a 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -11649,32 +11649,28 @@ ir.cpp: # 2119| void call_as_child_of_ConditionDeclExpr() # 2119| Block 0 -# 2119| v2119_1(void) = EnterFunction : -# 2119| mu2119_2(unknown) = AliasedDefinition : -# 2119| mu2119_3(unknown) = InitializeNonLocal : -# 2120| r2120_1(glval) = VariableAddress[b] : -# 2120| r2120_2(HasOperatorBool) = Constant[0] : -# 2120| mu2120_3(HasOperatorBool) = Store[b] : &:r2120_1, r2120_2 - -# 2120| (no string representation) -# 2120| CopyValue: (condition decl) -# 2120| ConditionalBranch: (condition decl) -#-----| False -> Block 3 -#-----| True -> Block 2 - -# 2120| Block 1 +# 2119| v2119_1(void) = EnterFunction : +# 2119| mu2119_2(unknown) = AliasedDefinition : +# 2119| mu2119_3(unknown) = InitializeNonLocal : +# 2120| r2120_1(glval) = VariableAddress[b] : +# 2120| r2120_2(HasOperatorBool) = Constant[0] : +# 2120| mu2120_3(HasOperatorBool) = Store[b] : &:r2120_1, r2120_2 # 2120| r2120_4(glval) = VariableAddress[b] : # 2120| r2120_5(glval) = FunctionAddress[operator bool] : # 2120| r2120_6(bool) = Call[operator bool] : func:r2120_5, this:r2120_4 # 2120| mu2120_7(unknown) = ^CallSideEffect : ~m? # 2120| v2120_8(void) = ^IndirectReadSideEffect[-1] : &:r2120_4, ~m? # 2120| mu2120_9(HasOperatorBool) = ^IndirectMayWriteSideEffect[-1] : &:r2120_4 +# 2120| r2120_10(bool) = CopyValue : r2120_6 +# 2120| v2120_11(void) = ConditionalBranch : r2120_10 +#-----| False -> Block 2 +#-----| True -> Block 1 -# 2120| Block 2 -# 2120| v2120_10(void) = NoOp : -#-----| Goto -> Block 3 +# 2120| Block 1 +# 2120| v2120_12(void) = NoOp : +#-----| Goto -> Block 2 -# 2121| Block 3 +# 2121| Block 2 # 2121| v2121_1(void) = NoOp : # 2119| v2119_4(void) = ReturnVoid : # 2119| v2119_5(void) = AliasedUse : ~m? 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 d4467596ca9..b93c7d2649f 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 @@ -6,7 +6,6 @@ missingOperandType duplicateChiOperand sideEffectWithoutPrimary instructionWithoutSuccessor -| ir.cpp:2120:25:2120:42 | Store: 0 | Instruction 'Store: 0' has no successors in function '$@'. | ir.cpp:2119:6:2119:39 | void call_as_child_of_ConditionDeclExpr() | void call_as_child_of_ConditionDeclExpr() | ambiguousSuccessors unexplainedLoop unnecessaryPhiInstruction 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 d4467596ca9..b93c7d2649f 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 @@ -6,7 +6,6 @@ missingOperandType duplicateChiOperand sideEffectWithoutPrimary instructionWithoutSuccessor -| ir.cpp:2120:25:2120:42 | Store: 0 | Instruction 'Store: 0' has no successors in function '$@'. | ir.cpp:2119:6:2119:39 | void call_as_child_of_ConditionDeclExpr() | void call_as_child_of_ConditionDeclExpr() | ambiguousSuccessors unexplainedLoop unnecessaryPhiInstruction From df181f2dc4b1b974368492177a202be853703f61 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 7 Feb 2024 14:50:18 +0000 Subject: [PATCH 50/50] C++: Accept more test changes. --- .../syntax-zoo/aliased_ssa_consistency.expected | 12 ++++-------- .../syntax-zoo/raw_consistency.expected | 12 ------------ .../syntax-zoo/unaliased_ssa_consistency.expected | 12 ++++-------- 3 files changed, 8 insertions(+), 28 deletions(-) diff --git a/cpp/ql/test/library-tests/syntax-zoo/aliased_ssa_consistency.expected b/cpp/ql/test/library-tests/syntax-zoo/aliased_ssa_consistency.expected index d94b3df0bb3..c2e0783d70f 100644 --- a/cpp/ql/test/library-tests/syntax-zoo/aliased_ssa_consistency.expected +++ b/cpp/ql/test/library-tests/syntax-zoo/aliased_ssa_consistency.expected @@ -8,10 +8,6 @@ duplicateChiOperand sideEffectWithoutPrimary instructionWithoutSuccessor | VacuousDestructorCall.cpp:2:29:2:29 | InitializeIndirection: y | Instruction 'InitializeIndirection: y' has no successors in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | void CallDestructor(int, int*) | void CallDestructor(int, int*) | -| condition_decls.cpp:16:19:16:20 | Chi: call to BoxedInt | Instruction 'Chi: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:15:6:15:17 | void if_decl_bind(int) | void if_decl_bind(int) | -| condition_decls.cpp:26:23:26:24 | Chi: call to BoxedInt | Instruction 'Chi: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:25:6:25:21 | void switch_decl_bind(int) | void switch_decl_bind(int) | -| condition_decls.cpp:41:22:41:23 | Chi: call to BoxedInt | Instruction 'Chi: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:40:6:40:20 | void while_decl_bind(int) | void while_decl_bind(int) | -| condition_decls.cpp:48:52:48:53 | Chi: call to BoxedInt | Instruction 'Chi: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:47:6:47:18 | void for_decl_bind(int) | void for_decl_bind(int) | | ms_try_mix.cpp:35:13:35:19 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:29:6:29:19 | void ms_finally_mix(int) | void ms_finally_mix(int) | | ms_try_mix.cpp:53:5:53:11 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:49:6:49:28 | void ms_empty_finally_at_end() | void ms_empty_finally_at_end() | | stmt_expr.cpp:27:5:27:15 | Store: ... = ... | Instruction 'Store: ... = ...' has no successors in function '$@'. | stmt_expr.cpp:21:13:21:13 | void stmtexpr::g(int) | void stmtexpr::g(int) | @@ -21,7 +17,11 @@ unnecessaryPhiInstruction memoryOperandDefinitionIsUnmodeled operandAcrossFunctions instructionWithoutUniqueBlock +missingCanonicalLanguageType +multipleCanonicalLanguageTypes containsLoopOfForwardEdges +missingIRType +multipleIRTypes lostReachability backEdgeCountMismatch useNotDominatedByDefinition @@ -36,8 +36,4 @@ thisArgumentIsNonPointer | pointer_to_member.cpp:23:5:23:54 | Call: call to expression | Call instruction 'Call: call to expression' has a `this` argument operand that is not an address, in function '$@'. | pointer_to_member.cpp:14:5:14:9 | int usePM(int PM::*) | int usePM(int PM::*) | | pointer_to_member.cpp:24:5:24:49 | Call: call to expression | Call instruction 'Call: call to expression' has a `this` argument operand that is not an address, in function '$@'. | pointer_to_member.cpp:14:5:14:9 | int usePM(int PM::*) | int usePM(int PM::*) | nonUniqueIRVariable -missingCanonicalLanguageType -multipleCanonicalLanguageTypes -missingIRType -multipleIRTypes missingCppType diff --git a/cpp/ql/test/library-tests/syntax-zoo/raw_consistency.expected b/cpp/ql/test/library-tests/syntax-zoo/raw_consistency.expected index bee483d992b..caff6369ad9 100644 --- a/cpp/ql/test/library-tests/syntax-zoo/raw_consistency.expected +++ b/cpp/ql/test/library-tests/syntax-zoo/raw_consistency.expected @@ -1,8 +1,4 @@ missingOperand -| condition_decls.cpp:16:6:16:20 | CopyValue: (condition decl) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | condition_decls.cpp:15:6:15:17 | void if_decl_bind(int) | void if_decl_bind(int) | -| condition_decls.cpp:26:10:26:24 | CopyValue: (condition decl) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | condition_decls.cpp:25:6:25:21 | void switch_decl_bind(int) | void switch_decl_bind(int) | -| condition_decls.cpp:41:9:41:23 | CopyValue: (condition decl) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | condition_decls.cpp:40:6:40:20 | void while_decl_bind(int) | void while_decl_bind(int) | -| condition_decls.cpp:48:39:48:53 | CopyValue: (condition decl) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | condition_decls.cpp:47:6:47:18 | void for_decl_bind(int) | void for_decl_bind(int) | | misc.c:125:5:125:11 | CopyValue: (statement expression) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | misc.c:97:6:97:10 | void misc3() | void misc3() | | try_catch.cpp:23:5:23:18 | CopyValue: (statement expression) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | try_catch.cpp:19:6:19:23 | void throw_from_nonstmt(int) | void throw_from_nonstmt(int) | unexpectedOperand @@ -15,14 +11,6 @@ instructionWithoutSuccessor | VacuousDestructorCall.cpp:2:29:2:29 | InitializeIndirection: y | Instruction 'InitializeIndirection: y' has no successors in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | void CallDestructor(int, int*) | void CallDestructor(int, int*) | | VacuousDestructorCall.cpp:3:3:3:3 | VariableAddress: x | Instruction 'VariableAddress: x' has no successors in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | void CallDestructor(int, int*) | void CallDestructor(int, int*) | | VacuousDestructorCall.cpp:4:3:4:3 | Load: y | Instruction 'Load: y' has no successors in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | void CallDestructor(int, int*) | void CallDestructor(int, int*) | -| condition_decls.cpp:16:19:16:20 | IndirectMayWriteSideEffect: call to BoxedInt | Instruction 'IndirectMayWriteSideEffect: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:15:6:15:17 | void if_decl_bind(int) | void if_decl_bind(int) | -| condition_decls.cpp:26:19:26:20 | IndirectMayWriteSideEffect: bi | Instruction 'IndirectMayWriteSideEffect: bi' has no successors in function '$@'. | condition_decls.cpp:25:6:25:21 | void switch_decl_bind(int) | void switch_decl_bind(int) | -| condition_decls.cpp:26:23:26:24 | IndirectMayWriteSideEffect: call to BoxedInt | Instruction 'IndirectMayWriteSideEffect: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:25:6:25:21 | void switch_decl_bind(int) | void switch_decl_bind(int) | -| condition_decls.cpp:41:22:41:23 | IndirectMayWriteSideEffect: call to BoxedInt | Instruction 'IndirectMayWriteSideEffect: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:40:6:40:20 | void while_decl_bind(int) | void while_decl_bind(int) | -| condition_decls.cpp:48:52:48:53 | IndirectMayWriteSideEffect: call to BoxedInt | Instruction 'IndirectMayWriteSideEffect: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:47:6:47:18 | void for_decl_bind(int) | void for_decl_bind(int) | -| file://:0:0:0:0 | CompareNE: (bool)... | Instruction 'CompareNE: (bool)...' has no successors in function '$@'. | condition_decls.cpp:15:6:15:17 | void if_decl_bind(int) | void if_decl_bind(int) | -| file://:0:0:0:0 | CompareNE: (bool)... | Instruction 'CompareNE: (bool)...' has no successors in function '$@'. | condition_decls.cpp:40:6:40:20 | void while_decl_bind(int) | void while_decl_bind(int) | -| file://:0:0:0:0 | CompareNE: (bool)... | Instruction 'CompareNE: (bool)...' has no successors in function '$@'. | condition_decls.cpp:47:6:47:18 | void for_decl_bind(int) | void for_decl_bind(int) | | ms_try_mix.cpp:35:13:35:19 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:29:6:29:19 | void ms_finally_mix(int) | void ms_finally_mix(int) | | ms_try_mix.cpp:53:5:53:11 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:49:6:49:28 | void ms_empty_finally_at_end() | void ms_empty_finally_at_end() | | stmt_expr.cpp:27:5:27:15 | Store: ... = ... | Instruction 'Store: ... = ...' has no successors in function '$@'. | stmt_expr.cpp:21:13:21:13 | void stmtexpr::g(int) | void stmtexpr::g(int) | diff --git a/cpp/ql/test/library-tests/syntax-zoo/unaliased_ssa_consistency.expected b/cpp/ql/test/library-tests/syntax-zoo/unaliased_ssa_consistency.expected index 6706c66c0a2..c2e0783d70f 100644 --- a/cpp/ql/test/library-tests/syntax-zoo/unaliased_ssa_consistency.expected +++ b/cpp/ql/test/library-tests/syntax-zoo/unaliased_ssa_consistency.expected @@ -8,10 +8,6 @@ duplicateChiOperand sideEffectWithoutPrimary instructionWithoutSuccessor | VacuousDestructorCall.cpp:2:29:2:29 | InitializeIndirection: y | Instruction 'InitializeIndirection: y' has no successors in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | void CallDestructor(int, int*) | void CallDestructor(int, int*) | -| condition_decls.cpp:16:19:16:20 | IndirectMayWriteSideEffect: call to BoxedInt | Instruction 'IndirectMayWriteSideEffect: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:15:6:15:17 | void if_decl_bind(int) | void if_decl_bind(int) | -| condition_decls.cpp:26:23:26:24 | IndirectMayWriteSideEffect: call to BoxedInt | Instruction 'IndirectMayWriteSideEffect: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:25:6:25:21 | void switch_decl_bind(int) | void switch_decl_bind(int) | -| condition_decls.cpp:41:22:41:23 | IndirectMayWriteSideEffect: call to BoxedInt | Instruction 'IndirectMayWriteSideEffect: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:40:6:40:20 | void while_decl_bind(int) | void while_decl_bind(int) | -| condition_decls.cpp:48:52:48:53 | IndirectMayWriteSideEffect: call to BoxedInt | Instruction 'IndirectMayWriteSideEffect: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:47:6:47:18 | void for_decl_bind(int) | void for_decl_bind(int) | | ms_try_mix.cpp:35:13:35:19 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:29:6:29:19 | void ms_finally_mix(int) | void ms_finally_mix(int) | | ms_try_mix.cpp:53:5:53:11 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:49:6:49:28 | void ms_empty_finally_at_end() | void ms_empty_finally_at_end() | | stmt_expr.cpp:27:5:27:15 | Store: ... = ... | Instruction 'Store: ... = ...' has no successors in function '$@'. | stmt_expr.cpp:21:13:21:13 | void stmtexpr::g(int) | void stmtexpr::g(int) | @@ -21,7 +17,11 @@ unnecessaryPhiInstruction memoryOperandDefinitionIsUnmodeled operandAcrossFunctions instructionWithoutUniqueBlock +missingCanonicalLanguageType +multipleCanonicalLanguageTypes containsLoopOfForwardEdges +missingIRType +multipleIRTypes lostReachability backEdgeCountMismatch useNotDominatedByDefinition @@ -36,8 +36,4 @@ thisArgumentIsNonPointer | pointer_to_member.cpp:23:5:23:54 | Call: call to expression | Call instruction 'Call: call to expression' has a `this` argument operand that is not an address, in function '$@'. | pointer_to_member.cpp:14:5:14:9 | int usePM(int PM::*) | int usePM(int PM::*) | | pointer_to_member.cpp:24:5:24:49 | Call: call to expression | Call instruction 'Call: call to expression' has a `this` argument operand that is not an address, in function '$@'. | pointer_to_member.cpp:14:5:14:9 | int usePM(int PM::*) | int usePM(int PM::*) | nonUniqueIRVariable -missingCanonicalLanguageType -multipleCanonicalLanguageTypes -missingIRType -multipleIRTypes missingCppType