Compare commits

..

3 Commits

Author SHA1 Message Date
Anders Fugmann
0f83586757 Kotlin 2.4.0: Address peer review
* Update documentation to only claim support for 2.4.0x
* Python test code; remove newlines between imports.
* Sync comments between kotlin 1.8 and 1.9
* Update code comments to attach where actually relevant,
  and improve comments on IrMemberAccessExpression<*>.extensionReceiverParameterIndex()
2026-06-19 13:45:28 +02:00
Anders Fugmann
1b785a8ff6 Kotlin: mark kotlin1 integration tests
Mark the integration tests that require a Kotlin 1.x language version
with @pytest.mark.kotlin1 so CI can run them on a pinned pre-2.4
compiler (Kotlin 2.4 no longer accepts -language-version 1.9).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-16 16:24:43 +02:00
Anders Fugmann
e10743bd08 Kotlin: add extractor support for 2.4.0
Add the Kotlin 2.4.0 compiler plugin variant (component registrar,
IR compatibility shims, and version-specific utilities), bundle the
2.4.0 compiler dependencies, and update the build wiring, supported
version metadata and the too-new diagnostic bound.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-16 16:24:42 +02:00
648 changed files with 5379 additions and 40422 deletions

View File

@@ -2,7 +2,7 @@
* @github/code-scanning-alert-coverage
# CodeQL language libraries
/actions/ @github/code-scanning-alert-coverage
/actions/ @github/codeql-dynamic
/cpp/ @github/codeql-c-analysis
/csharp/ @github/codeql-csharp
/csharp/autobuilder/Semmle.Autobuild.Cpp @github/codeql-c-extractor @github/code-scanning-language-coverage

View File

@@ -248,6 +248,7 @@ use_repo(
"kotlin-compiler-2.2.20-Beta2",
"kotlin-compiler-2.3.0",
"kotlin-compiler-2.3.20",
"kotlin-compiler-2.4.0",
"kotlin-compiler-embeddable-1.8.0",
"kotlin-compiler-embeddable-1.9.0-Beta",
"kotlin-compiler-embeddable-1.9.20-Beta",
@@ -259,6 +260,7 @@ use_repo(
"kotlin-compiler-embeddable-2.2.20-Beta2",
"kotlin-compiler-embeddable-2.3.0",
"kotlin-compiler-embeddable-2.3.20",
"kotlin-compiler-embeddable-2.4.0",
"kotlin-stdlib-1.8.0",
"kotlin-stdlib-1.9.0-Beta",
"kotlin-stdlib-1.9.20-Beta",
@@ -270,6 +272,7 @@ use_repo(
"kotlin-stdlib-2.2.20-Beta2",
"kotlin-stdlib-2.3.0",
"kotlin-stdlib-2.3.20",
"kotlin-stdlib-2.4.0",
)
go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk")

View File

@@ -2,7 +2,7 @@
### Minor Analysis Improvements
* The GitHub Actions analysis now recognizes more Bash regex checks that restrict a value to alphanumeric characters, including regexes like `^[0-9a-zA-Z]{40}([0-9a-zA-Z]{24})?$` which check for a SHA-1 or SHA-256 hash. This may reduce false positive results where command output is validated with grouped or optional alphanumeric patterns before being used.
* The GitHub Actions analysis now recognizes more Bash regex checks that restrict a value to alphanumeric characters, include regexes like `^[0-9a-zA-Z]{40}([0-9a-zA-Z]{24})?$` which check for a sha1 or sha256 hash. This may reduce false positive results where command output is validated with grouped or optional alphanumeric patterns before being used.
## 0.4.36

View File

@@ -2,4 +2,4 @@
### Minor Analysis Improvements
* The GitHub Actions analysis now recognizes more Bash regex checks that restrict a value to alphanumeric characters, including regexes like `^[0-9a-zA-Z]{40}([0-9a-zA-Z]{24})?$` which check for a SHA-1 or SHA-256 hash. This may reduce false positive results where command output is validated with grouped or optional alphanumeric patterns before being used.
* The GitHub Actions analysis now recognizes more Bash regex checks that restrict a value to alphanumeric characters, include regexes like `^[0-9a-zA-Z]{40}([0-9a-zA-Z]{24})?$` which check for a sha1 or sha256 hash. This may reduce false positive results where command output is validated with grouped or optional alphanumeric patterns before being used.

View File

@@ -1920,5 +1920,3 @@ private YamlMappingLikeNode resolveMatrixAccessPath(
else result = resolveMatrixAccessPath(newRoot, rest)
)
}
class Comment = YamlComment;

View File

@@ -52,12 +52,6 @@ private module YamlSig implements LibYaml::InputSig {
class ParseErrorBase extends LocatableBase, @yaml_error {
string getMessage() { yaml_errors(this, result) }
}
class CommentBase extends LocatableBase, @yaml_comment {
string getText() { yaml_comments(this, result, _) }
override string toString() { yaml_comments(this, _, result) }
}
}
import LibYaml::Make<YamlSig>

View File

@@ -15,7 +15,7 @@
### Bug Fixes
* Adjusted (minor) help file descriptions for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`, `actions/untrusted-checkout/medium`. Clarified wording on a minor point, added one more listed resource and added one more recommendation for things to check.
* Adjusted (minor) help file descriptions for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`, `actions/untrusted-checkout/medium`. Clarified wording on in minor point, added one more listed resource and added one more recommendation for things to check.
## 0.6.28

View File

@@ -1,8 +1,8 @@
/**
* @name Checkout of untrusted code in a non-privileged context
* @description Checking out and running the build script from a fork executes untrusted code. Even in a
* non-privileged workflow, this can be abused, for example to compromise self-hosted runners
* or to poison caches and artifacts that are later consumed by privileged workflows.
* @name Checkout of untrusted code in a trusted context
* @description Privileged workflows have read/write access to the base repository and access to secrets.
* By explicitly checking out and running the build script from a fork the untrusted code is running in an environment
* that is able to push to the base repository and to access secrets.
* @kind problem
* @problem.severity warning
* @precision medium
@@ -20,4 +20,4 @@ from PRHeadCheckoutStep checkout
where
// the checkout occurs in a non-privileged context
inNonPrivilegedContext(checkout)
select checkout, "Potential unsafe checkout of untrusted pull request on non-privileged workflow."
select checkout, "Potential unsafe checkout of untrusted pull request on privileged workflow."

View File

@@ -1,4 +0,0 @@
---
category: queryMetadata
---
* The name, description, and alert message of `actions/untrusted-checkout/medium` have been corrected to describe a non-privileged context.

View File

@@ -15,4 +15,4 @@
### Bug Fixes
* Adjusted (minor) help file descriptions for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`, `actions/untrusted-checkout/medium`. Clarified wording on a minor point, added one more listed resource and added one more recommendation for things to check.
* Adjusted (minor) help file descriptions for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`, `actions/untrusted-checkout/medium`. Clarified wording on in minor point, added one more listed resource and added one more recommendation for things to check.

View File

@@ -1,10 +1,10 @@
| .github/workflows/artifactpoisoning81.yml:11:9:14:6 | Uses Step | Potential unsafe checkout of untrusted pull request on non-privileged workflow. |
| .github/workflows/dependabot2.yml:33:9:38:6 | Uses Step | Potential unsafe checkout of untrusted pull request on non-privileged workflow. |
| .github/workflows/mend.yml:22:9:29:6 | Uses Step | Potential unsafe checkout of untrusted pull request on non-privileged workflow. |
| .github/workflows/poc3.yml:18:7:25:4 | Uses Step | Potential unsafe checkout of untrusted pull request on non-privileged workflow. |
| .github/workflows/poc.yml:30:9:36:6 | Uses Step | Potential unsafe checkout of untrusted pull request on non-privileged workflow. |
| .github/workflows/priv_pull_request_checkout.yml:14:9:20:6 | Uses Step | Potential unsafe checkout of untrusted pull request on non-privileged workflow. |
| .github/workflows/test3.yml:28:9:33:6 | Uses Step | Potential unsafe checkout of untrusted pull request on non-privileged workflow. |
| .github/workflows/test4.yml:18:7:25:4 | Uses Step | Potential unsafe checkout of untrusted pull request on non-privileged workflow. |
| .github/workflows/test8.yml:20:9:26:6 | Uses Step | Potential unsafe checkout of untrusted pull request on non-privileged workflow. |
| .github/workflows/test9.yml:11:9:16:6 | Uses Step | Potential unsafe checkout of untrusted pull request on non-privileged workflow. |
| .github/workflows/artifactpoisoning81.yml:11:9:14:6 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
| .github/workflows/dependabot2.yml:33:9:38:6 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
| .github/workflows/mend.yml:22:9:29:6 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
| .github/workflows/poc3.yml:18:7:25:4 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
| .github/workflows/poc.yml:30:9:36:6 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
| .github/workflows/priv_pull_request_checkout.yml:14:9:20:6 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
| .github/workflows/test3.yml:28:9:33:6 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
| .github/workflows/test4.yml:18:7:25:4 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
| .github/workflows/test8.yml:20:9:26:6 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
| .github/workflows/test9.yml:11:9:16:6 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |

View File

@@ -135,7 +135,7 @@ namespace Semmle.Autobuild.CSharp.Tests
if (!EnumerateFiles.TryGetValue(dir, out var str))
throw new ArgumentException("Missing EnumerateFiles " + dir);
return str.Split("\n").Select(p => PathJoin(dir, p));
return str.Split("\n").Select(p => PathCombine(dir, p));
}
public IDictionary<string, string> EnumerateDirectories { get; } = new Dictionary<string, string>();
@@ -147,7 +147,7 @@ namespace Semmle.Autobuild.CSharp.Tests
return string.IsNullOrEmpty(str)
? Enumerable.Empty<string>()
: str.Split("\n").Select(p => PathJoin(dir, p));
: str.Split("\n").Select(p => PathCombine(dir, p));
}
public bool IsWindows { get; set; }
@@ -170,7 +170,7 @@ namespace Semmle.Autobuild.CSharp.Tests
bool IBuildActions.IsMonoInstalled() => IsMonoInstalled;
public string PathJoin(params string[] parts)
public string PathCombine(params string[] parts)
{
return string.Join(IsWindows ? '\\' : '/', parts.Where(p => !string.IsNullOrWhiteSpace(p)));
}

View File

@@ -109,7 +109,7 @@ namespace Semmle.Autobuild.CSharp
=> WithDotNet(builder, ensureDotNetAvailable: false, (_, env) => f(env));
private static string DotNetCommand(IBuildActions actions, string? dotNetPath) =>
dotNetPath is not null ? actions.PathJoin(dotNetPath, "dotnet") : "dotnet";
dotNetPath is not null ? actions.PathCombine(dotNetPath, "dotnet") : "dotnet";
private static CommandBuilder GetCleanCommand(IBuildActions actions, string? dotNetPath, IDictionary<string, string>? environment)
{

View File

@@ -158,7 +158,7 @@ namespace Semmle.Autobuild.Cpp.Tests
bool IBuildActions.IsMonoInstalled() => IsMonoInstalled;
string IBuildActions.PathJoin(params string[] parts)
string IBuildActions.PathCombine(params string[] parts)
{
return string.Join(IsWindows ? '\\' : '/', parts.Where(p => !string.IsNullOrWhiteSpace(p)));
}

View File

@@ -108,7 +108,7 @@ namespace Semmle.Autobuild.Shared
/// </summary>
/// <param name="path">The relative path.</param>
/// <returns>True iff the path was found.</returns>
public bool HasRelativePath(string path) => HasPath(Actions.PathJoin(RootDirectory, path));
public bool HasRelativePath(string path) => HasPath(Actions.PathCombine(RootDirectory, path));
/// <summary>
/// List of project/solution files to build.

View File

@@ -32,7 +32,7 @@ namespace Semmle.Autobuild.Shared
yield break;
// Attempt to use vswhere to find installations of Visual Studio
var vswhere = actions.PathJoin(programFilesx86, "Microsoft Visual Studio", "Installer", "vswhere.exe");
var vswhere = actions.PathCombine(programFilesx86, "Microsoft Visual Studio", "Installer", "vswhere.exe");
if (actions.FileExists(vswhere))
{
@@ -51,14 +51,14 @@ namespace Semmle.Autobuild.Shared
if (majorVersion < 15)
{
// Visual Studio 2015 and below
yield return new VcVarsBatFile(actions.PathJoin(vsInstallation.InstallationPath, @"VC\vcvarsall.bat"), majorVersion);
yield return new VcVarsBatFile(actions.PathCombine(vsInstallation.InstallationPath, @"VC\vcvarsall.bat"), majorVersion);
}
else
{
// Visual Studio 2017 and above
yield return new VcVarsBatFile(actions.PathJoin(vsInstallation.InstallationPath, @"VC\Auxiliary\Build\vcvars32.bat"), majorVersion);
yield return new VcVarsBatFile(actions.PathJoin(vsInstallation.InstallationPath, @"VC\Auxiliary\Build\vcvars64.bat"), majorVersion);
yield return new VcVarsBatFile(actions.PathJoin(vsInstallation.InstallationPath, @"Common7\Tools\VsDevCmd.bat"), majorVersion);
yield return new VcVarsBatFile(actions.PathCombine(vsInstallation.InstallationPath, @"VC\Auxiliary\Build\vcvars32.bat"), majorVersion);
yield return new VcVarsBatFile(actions.PathCombine(vsInstallation.InstallationPath, @"VC\Auxiliary\Build\vcvars64.bat"), majorVersion);
yield return new VcVarsBatFile(actions.PathCombine(vsInstallation.InstallationPath, @"Common7\Tools\VsDevCmd.bat"), majorVersion);
}
}
// else: Skip installation without a version
@@ -68,10 +68,10 @@ namespace Semmle.Autobuild.Shared
}
// vswhere not installed or didn't run correctly - return legacy Visual Studio versions
yield return new VcVarsBatFile(actions.PathJoin(programFilesx86, @"Microsoft Visual Studio 14.0\VC\vcvarsall.bat"), 14);
yield return new VcVarsBatFile(actions.PathJoin(programFilesx86, @"Microsoft Visual Studio 12.0\VC\vcvarsall.bat"), 12);
yield return new VcVarsBatFile(actions.PathJoin(programFilesx86, @"Microsoft Visual Studio 11.0\VC\vcvarsall.bat"), 11);
yield return new VcVarsBatFile(actions.PathJoin(programFilesx86, @"Microsoft Visual Studio 10.0\VC\vcvarsall.bat"), 10);
yield return new VcVarsBatFile(actions.PathCombine(programFilesx86, @"Microsoft Visual Studio 14.0\VC\vcvarsall.bat"), 14);
yield return new VcVarsBatFile(actions.PathCombine(programFilesx86, @"Microsoft Visual Studio 12.0\VC\vcvarsall.bat"), 12);
yield return new VcVarsBatFile(actions.PathCombine(programFilesx86, @"Microsoft Visual Studio 11.0\VC\vcvarsall.bat"), 11);
yield return new VcVarsBatFile(actions.PathCombine(programFilesx86, @"Microsoft Visual Studio 10.0\VC\vcvarsall.bat"), 10);
}
/// <summary>

View File

@@ -60,7 +60,7 @@ namespace Semmle.Autobuild.Shared
// Use `nuget.exe` from source code repo, if present, otherwise first attempt with global
// `nuget` command, and if that fails, attempt to download `nuget.exe` from nuget.org
var nuget = builder.GetFilename("nuget.exe").Select(t => t.Item1).FirstOrDefault() ?? "nuget";
var nugetDownloadPath = builder.Actions.PathJoin(FileUtils.GetTemporaryWorkingDirectory(builder.Actions.GetEnvironmentVariable, builder.Options.Language.UpperCaseName, out _), ".nuget", "nuget.exe");
var nugetDownloadPath = builder.Actions.PathCombine(FileUtils.GetTemporaryWorkingDirectory(builder.Actions.GetEnvironmentVariable, builder.Options.Language.UpperCaseName, out _), ".nuget", "nuget.exe");
var nugetDownloaded = false;
var ret = BuildScript.Success;

View File

@@ -107,9 +107,8 @@ namespace Semmle.Autobuild.Shared
continue;
}
var includePath = builder.Actions.PathJoin(include.Value.Split('\\', StringSplitOptions.RemoveEmptyEntries));
var path = Path.IsPathRooted(includePath) ? includePath : builder.Actions.PathJoin(DirectoryName, includePath);
ret.Add(new Project<TAutobuildOptions>(builder, path));
var includePath = builder.Actions.PathCombine(include.Value.Split('\\', StringSplitOptions.RemoveEmptyEntries));
ret.Add(new Project<TAutobuildOptions>(builder, builder.Actions.PathCombine(DirectoryName, includePath)));
}
return ret;
});

View File

@@ -79,7 +79,7 @@ namespace Semmle.Autobuild.Shared
includedProjects = solution.ProjectsInOrder
.Where(p => p.ProjectType == SolutionProjectType.KnownToBeMSBuildFormat)
.Select(p => builder.Actions.PathJoin(DirectoryName, builder.Actions.PathJoin(p.RelativePath.Split('\\', StringSplitOptions.RemoveEmptyEntries))))
.Select(p => builder.Actions.PathCombine(DirectoryName, builder.Actions.PathCombine(p.RelativePath.Split('\\', StringSplitOptions.RemoveEmptyEntries))))
.Select(p => new Project<TAutobuildOptions>(builder, p))
.ToArray();
}

View File

@@ -50,7 +50,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
return;
}
var path = Path.Join(p, ParseFilePath(d));
var path = Path.Combine(p, ParseFilePath(d));
Paths.Add(path);
Packages.Add(GetPackageName(p));
}

View File

@@ -75,7 +75,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
}
}
this.diagnosticsWriter = new DiagnosticsStream(Path.Join(
this.diagnosticsWriter = new DiagnosticsStream(Path.Combine(
diagDirEnv ?? "",
$"dependency-manager-{DateTime.UtcNow:yyyyMMddHHmm}-{Environment.ProcessId}.jsonc"));
this.sourceDir = new DirectoryInfo(srcDir);
@@ -327,7 +327,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
private void RemoveNugetPackageReference(string packagePrefix, ISet<AssemblyLookupLocation> dllLocations)
{
var packageFolder = nugetPackageRestorer.PackageDirectory.DirInfo.FullName.ToLowerInvariant();
var packagePathPrefix = Path.Join(packageFolder, packagePrefix.ToLowerInvariant());
var packagePathPrefix = Path.Combine(packageFolder, packagePrefix.ToLowerInvariant());
var toRemove = dllLocations.Where(s => s.Path.StartsWith(packagePathPrefix, StringComparison.InvariantCultureIgnoreCase));
foreach (var path in toRemove)
{

View File

@@ -31,7 +31,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
}
}
private DotNet(ILogger logger, string? dotNetPath, TemporaryDirectory tempWorkingDirectory, DependabotProxy? dependabotProxy) : this(new DotNetCliInvoker(logger, Path.Join(dotNetPath ?? string.Empty, "dotnet"), dependabotProxy), logger, dotNetPath is null, tempWorkingDirectory) { }
private DotNet(ILogger logger, string? dotNetPath, TemporaryDirectory tempWorkingDirectory, DependabotProxy? dependabotProxy) : this(new DotNetCliInvoker(logger, Path.Combine(dotNetPath ?? string.Empty, "dotnet"), dependabotProxy), logger, dotNetPath is null, tempWorkingDirectory) { }
internal static IDotNet Make(IDotNetCliInvoker dotnetCliInvoker, ILogger logger, bool runDotnetInfo) => new DotNet(dotnetCliInvoker, logger, runDotnetInfo);
@@ -73,7 +73,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
var path = ".empty";
if (tempWorkingDirectory != null)
{
path = Path.Join(tempWorkingDirectory.ToString(), "emptyFakeDotnetRoot");
path = Path.Combine(tempWorkingDirectory.ToString(), "emptyFakeDotnetRoot");
Directory.CreateDirectory(path);
}
@@ -303,7 +303,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
}
else
{
var dotnetInstallPath = actions.PathJoin(tempWorkingDirectory, ".dotnet", "dotnet-install.sh");
var dotnetInstallPath = actions.PathCombine(tempWorkingDirectory, ".dotnet", "dotnet-install.sh");
var downloadDotNetInstallSh = BuildScript.DownloadFile(
"https://dot.net/v1/dotnet-install.sh",
dotnetInstallPath,
@@ -339,7 +339,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
};
}
var dotnetInfo = InfoScript(actions, actions.PathJoin(path, "dotnet"), MinimalEnvironment.ToDictionary(), logger);
var dotnetInfo = InfoScript(actions, actions.PathCombine(path, "dotnet"), MinimalEnvironment.ToDictionary(), logger);
Func<string, BuildScript> getInstallAndVerify = version =>
// run `dotnet --info` after install, to check that it executes successfully
@@ -384,7 +384,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
/// </summary>
public static BuildScript WithDotNet(IBuildActions actions, ILogger logger, IEnumerable<string> files, string tempWorkingDirectory, bool shouldCleanUp, bool ensureDotNetAvailable, string? version, Func<string?, BuildScript> f)
{
var installDir = actions.PathJoin(tempWorkingDirectory, ".dotnet");
var installDir = actions.PathCombine(tempWorkingDirectory, ".dotnet");
var installScript = DownloadDotNet(actions, logger, files, tempWorkingDirectory, shouldCleanUp, installDir, version, ensureDotNetAvailable);
return BuildScript.Bind(installScript, installed =>
{

View File

@@ -12,7 +12,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
private string FullVersion =>
version.ToString();
public string FullPath => Path.Join(dir, FullVersion);
public string FullPath => Path.Combine(dir, FullVersion);
/**
* The full path to the reference assemblies for this runtime.
@@ -33,7 +33,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
{
directories[^2] = "packs";
directories[^1] = $"{directories[^1]}.Ref";
return Path.Join(string.Join(Path.DirectorySeparatorChar, directories), FullVersion, "ref");
return Path.Combine(string.Join(Path.DirectorySeparatorChar, directories), FullVersion, "ref");
}
return null;
}

View File

@@ -0,0 +1,304 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using Semmle.Util;
namespace Semmle.Extraction.CSharp.DependencyFetching
{
/// <summary>
/// Manage the downloading of NuGet packages with nuget.exe.
/// Locates packages in a source tree and downloads all of the
/// referenced assemblies to a temp folder.
/// </summary>
internal class NugetExeWrapper : IDisposable
{
private readonly string? nugetExe;
private readonly Semmle.Util.Logging.ILogger logger;
public int PackageCount => fileProvider.PackagesConfigs.Count;
private readonly string? backupNugetConfig;
private readonly string? nugetConfigPath;
private readonly FileProvider fileProvider;
/// <summary>
/// The packages directory.
/// This will be in the user-specified or computed Temp location
/// so as to not trample the source tree.
/// </summary>
private readonly DependencyDirectory packageDirectory;
/// <summary>
/// Create the package manager for a specified source tree.
/// </summary>
public NugetExeWrapper(FileProvider fileProvider, DependencyDirectory packageDirectory, Semmle.Util.Logging.ILogger logger, Func<bool> useDefaultFeed)
{
this.fileProvider = fileProvider;
this.packageDirectory = packageDirectory;
this.logger = logger;
if (fileProvider.PackagesConfigs.Count > 0)
{
logger.LogInfo($"Found packages.config files, trying to use nuget.exe for package restore");
nugetExe = ResolveNugetExe();
if (HasNoPackageSource() && useDefaultFeed())
{
// We only modify or add a top level nuget.config file
nugetConfigPath = Path.Combine(fileProvider.SourceDir.FullName, "nuget.config");
try
{
if (File.Exists(nugetConfigPath))
{
var tempFolderPath = FileUtils.GetTemporaryWorkingDirectory(out _);
do
{
backupNugetConfig = Path.Combine(tempFolderPath, Path.GetRandomFileName());
}
while (File.Exists(backupNugetConfig));
File.Copy(nugetConfigPath, backupNugetConfig, true);
}
else
{
File.WriteAllText(nugetConfigPath,
"""
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
</packageSources>
</configuration>
""");
}
AddDefaultPackageSource(nugetConfigPath);
}
catch (Exception e)
{
logger.LogError($"Failed to add default package source to {nugetConfigPath}: {e}");
}
}
}
}
/// <summary>
/// Tries to find the location of `nuget.exe`. It looks for
/// - the environment variable specifying a location,
/// - files in the repository,
/// - tries to resolve nuget from the PATH, or
/// - downloads it if it is not found.
/// </summary>
private string ResolveNugetExe()
{
var envVarPath = Environment.GetEnvironmentVariable(EnvironmentVariableNames.NugetExePath);
if (!string.IsNullOrEmpty(envVarPath))
{
logger.LogInfo($"Using nuget.exe from environment variable: '{envVarPath}'");
return envVarPath;
}
try
{
return DownloadNugetExe(fileProvider.SourceDir.FullName);
}
catch (Exception exc)
{
logger.LogInfo($"Download of nuget.exe failed: {exc.Message}");
}
var nugetExesInRepo = fileProvider.NugetExes;
if (nugetExesInRepo.Count > 1)
{
logger.LogInfo($"Found multiple nuget.exe files in the repository: {string.Join(", ", nugetExesInRepo.OrderBy(s => s))}");
}
if (nugetExesInRepo.Count > 0)
{
var path = nugetExesInRepo.First();
logger.LogInfo($"Using nuget.exe from path '{path}'");
return path;
}
var executableName = Win32.IsWindows() ? "nuget.exe" : "nuget";
var nugetPath = FileUtils.FindProgramOnPath(executableName);
if (nugetPath is not null)
{
nugetPath = Path.Combine(nugetPath, executableName);
logger.LogInfo($"Using nuget.exe from PATH: {nugetPath}");
return nugetPath;
}
throw new Exception("Could not find or download nuget.exe.");
}
private string DownloadNugetExe(string sourceDir)
{
var directory = Path.Combine(sourceDir, ".nuget");
var nuget = Path.Combine(directory, "nuget.exe");
// Nuget.exe already exists in the .nuget directory.
if (File.Exists(nuget))
{
logger.LogInfo($"Found nuget.exe at {nuget}");
return nuget;
}
Directory.CreateDirectory(directory);
logger.LogInfo("Attempting to download nuget.exe");
FileUtils.DownloadFile(FileUtils.NugetExeUrl, nuget, logger);
logger.LogInfo($"Downloaded nuget.exe to {nuget}");
return nuget;
}
private bool RunWithMono => !Win32.IsWindows() && !string.IsNullOrEmpty(Path.GetExtension(nugetExe));
/// <summary>
/// Restore all packages in the specified packages.config file.
/// </summary>
/// <param name="packagesConfig">The packages.config file.</param>
private bool TryRestoreNugetPackage(string packagesConfig)
{
logger.LogInfo($"Restoring file \"{packagesConfig}\"...");
/* Use nuget.exe to install a package.
* Note that there is a clutch of NuGet assemblies which could be used to
* invoke this directly, which would arguably be nicer. However they are
* really unwieldy and this solution works for now.
*/
string exe, args;
if (RunWithMono)
{
exe = "mono";
args = $"\"{nugetExe}\" install -OutputDirectory \"{packageDirectory}\" \"{packagesConfig}\"";
}
else
{
exe = nugetExe!;
args = $"install -OutputDirectory \"{packageDirectory}\" \"{packagesConfig}\"";
}
var pi = new ProcessStartInfo(exe, args)
{
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false
};
var threadId = Environment.CurrentManagedThreadId;
void onOut(string s) => logger.LogDebug(s, threadId);
void onError(string s) => logger.LogError(s, threadId);
var exitCode = pi.ReadOutput(out _, onOut, onError);
if (exitCode != 0)
{
logger.LogError($"Command {pi.FileName} {pi.Arguments} failed with exit code {exitCode}");
return false;
}
else
{
logger.LogInfo($"Restored file \"{packagesConfig}\"");
return true;
}
}
/// <summary>
/// Download the packages to the temp folder.
/// </summary>
public int InstallPackages()
{
return fileProvider.PackagesConfigs.Count(TryRestoreNugetPackage);
}
private bool HasNoPackageSource()
{
if (Win32.IsWindows())
{
return false;
}
try
{
logger.LogInfo("Checking if default package source is available...");
RunMonoNugetCommand("sources list -ForceEnglishOutput", out var stdout);
if (stdout.All(line => line != "No sources found."))
{
return false;
}
return true;
}
catch (Exception e)
{
logger.LogWarning($"Failed to check if default package source is added: {e}");
return false;
}
}
private void RunMonoNugetCommand(string command, out IList<string> stdout)
{
string exe, args;
if (RunWithMono)
{
exe = "mono";
args = $"\"{nugetExe}\" {command}";
}
else
{
exe = nugetExe!;
args = command;
}
var pi = new ProcessStartInfo(exe, args)
{
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false
};
var threadId = Environment.CurrentManagedThreadId;
void onOut(string s) => logger.LogDebug(s, threadId);
void onError(string s) => logger.LogError(s, threadId);
pi.ReadOutput(out stdout, onOut, onError);
}
private void AddDefaultPackageSource(string nugetConfig)
{
logger.LogInfo("Adding default package source...");
RunMonoNugetCommand($"sources add -Name DefaultNugetOrg -Source {NugetPackageRestorer.PublicNugetOrgFeed} -ConfigFile \"{nugetConfig}\"", out _);
}
public void Dispose()
{
if (nugetConfigPath is null)
{
return;
}
try
{
if (backupNugetConfig is null)
{
logger.LogInfo("Removing nuget.config file");
File.Delete(nugetConfigPath);
return;
}
logger.LogInfo("Reverting nuget.config file content");
// The content of the original nuget.config file is reverted without changing the file's attributes or casing:
using (var backup = File.OpenRead(backupNugetConfig))
using (var current = File.OpenWrite(nugetConfigPath))
{
current.SetLength(0); // Truncate file
backup.CopyTo(current); // Restore original content
}
logger.LogInfo("Deleting backup nuget.config file");
File.Delete(backupNugetConfig);
}
catch (Exception exc)
{
logger.LogError($"Failed to restore original nuget.config file: {exc}");
}
}
}
}

View File

@@ -161,13 +161,13 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
reachableFeeds.UnionWith(reachableInheritedFeeds);
}
using (var packagesConfigRestore = PackagesConfigRestoreFactory.Create(fileProvider, legacyPackageDirectory, logger, IsDefaultFeedReachable))
using (var nuget = new NugetExeWrapper(fileProvider, legacyPackageDirectory, logger, IsDefaultFeedReachable))
{
var count = packagesConfigRestore.InstallPackages();
var count = nuget.InstallPackages();
if (packagesConfigRestore.PackageCount > 0)
if (nuget.PackageCount > 0)
{
compilationInfoContainer.CompilationInfos.Add(("packages.config files", packagesConfigRestore.PackageCount.ToString()));
compilationInfoContainer.CompilationInfos.Add(("packages.config files", nuget.PackageCount.ToString()));
compilationInfoContainer.CompilationInfos.Add(("Successfully restored packages.config files", count.ToString()));
}
}
@@ -209,7 +209,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
var paths = dependencies
.Paths
.Select(d => Path.Join(PackageDirectory.DirInfo.FullName, d))
.Select(d => Path.Combine(PackageDirectory.DirInfo.FullName, d))
.ToList();
assemblyLookupLocations.UnionWith(paths.Select(p => new AssemblyLookupLocation(p)));
@@ -527,7 +527,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
var sb = new StringBuilder();
fallbackNugetFeeds.ForEach((feed, index) => sb.AppendLine($"<add key=\"feed{index}\" value=\"{feed}\" />"));
var nugetConfigPath = Path.Join(folderPath, "nuget.config");
var nugetConfigPath = Path.Combine(folderPath, "nuget.config");
logger.LogInfo($"Creating fallback nuget.config file {nugetConfigPath}.");
File.WriteAllText(nugetConfigPath,
$"""
@@ -1052,7 +1052,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
/// </summary>
private static string ComputeTempDirectoryPath(string subfolderName)
{
return Path.Join(FileUtils.GetTemporaryWorkingDirectory(out _), subfolderName);
return Path.Combine(FileUtils.GetTemporaryWorkingDirectory(out _), subfolderName);
}
/// <summary>
@@ -1060,7 +1060,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
/// </summary>
private static string ComputeTempDirectoryPath(string srcDir, string subfolderName)
{
return Path.Join(FileUtils.GetTemporaryWorkingDirectory(out _), FileUtils.ComputeHash(srcDir), subfolderName);
return Path.Combine(FileUtils.GetTemporaryWorkingDirectory(out _), FileUtils.ComputeHash(srcDir), subfolderName);
}
}
}

View File

@@ -1,368 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using Semmle.Util;
namespace Semmle.Extraction.CSharp.DependencyFetching
{
internal interface IPackagesConfigRestore : IDisposable
{
/// <summary>
/// The number of packages.config files found in the source tree.
/// </summary>
int PackageCount { get; }
/// <summary>
/// Download the packages to the temp folder.
/// </summary>
int InstallPackages();
}
/// <summary>
/// Factory for creating a package manager to restore NuGet packages referenced in packages.config files.
/// If the environment doesn't support using nuget.exe to restore packages from packages.config files, a no-op implementation is returned.
/// It is worth noting that for macOS and Linux, nuget.exe is used with mono. However, mono is being deprecated and the last GitHub images
/// to contain mono are:
/// - Ubuntu 22.04
/// - macOS 14
///
/// If the packages from the packages.config files are not restored with the packages.config restore functionality below, there is a subsequent
/// step that still may succeed in restoring the packages without the help of nuget.exe (by attempting to restore using dotnet).
/// </summary>
internal class PackagesConfigRestoreFactory
{
public static IPackagesConfigRestore Create(FileProvider fileProvider, DependencyDirectory packageDirectory, Semmle.Util.Logging.ILogger logger, Func<bool> useDefaultFeed)
{
if (SystemBuildActions.Instance.IsWindows() || SystemBuildActions.Instance.IsMonoInstalled())
{
return new NugetExeWrapper(fileProvider, packageDirectory, logger, useDefaultFeed);
}
return new NoOpPackagesConfig(fileProvider, logger);
}
/// <summary>
/// Manage the downloading of NuGet packages with nuget.exe.
/// Locates packages in a source tree and downloads all of the
/// referenced assemblies to a temp folder.
/// </summary>
private class NugetExeWrapper : IPackagesConfigRestore
{
private readonly string? nugetExe;
private readonly Semmle.Util.Logging.ILogger logger;
public int PackageCount => fileProvider.PackagesConfigs.Count;
private readonly string? backupNugetConfig;
private readonly string? nugetConfigPath;
private readonly FileProvider fileProvider;
/// <summary>
/// The packages directory.
/// This will be in the user-specified or computed Temp location
/// so as to not trample the source tree.
/// </summary>
private readonly DependencyDirectory packageDirectory;
private bool IsWindows => SystemBuildActions.Instance.IsWindows();
/// <summary>
/// Create the package manager for a specified source tree.
/// </summary>
public NugetExeWrapper(FileProvider fileProvider, DependencyDirectory packageDirectory, Semmle.Util.Logging.ILogger logger, Func<bool> useDefaultFeed)
{
this.fileProvider = fileProvider;
this.packageDirectory = packageDirectory;
this.logger = logger;
if (fileProvider.PackagesConfigs.Count > 0)
{
logger.LogInfo($"Found packages.config files, trying to use nuget.exe for package restore");
nugetExe = ResolveNugetExe();
if (!HasPackageSource() && useDefaultFeed())
{
// We only modify or add a top level nuget.config file
nugetConfigPath = Path.Join(fileProvider.SourceDir.FullName, "nuget.config");
try
{
if (File.Exists(nugetConfigPath))
{
var tempFolderPath = FileUtils.GetTemporaryWorkingDirectory(out _);
do
{
backupNugetConfig = Path.Join(tempFolderPath, Path.GetRandomFileName());
}
while (File.Exists(backupNugetConfig));
File.Copy(nugetConfigPath, backupNugetConfig, true);
}
else
{
File.WriteAllText(nugetConfigPath,
"""
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
</packageSources>
</configuration>
""");
}
AddDefaultPackageSource(nugetConfigPath);
}
catch (Exception e)
{
logger.LogError($"Failed to add default package source to {nugetConfigPath}: {e}");
}
}
}
}
/// <summary>
/// Tries to find the location of `nuget.exe`. It looks for
/// - the environment variable specifying a location,
/// - files in the repository,
/// - tries to resolve nuget from the PATH, or
/// - downloads it if it is not found.
/// </summary>
private string ResolveNugetExe()
{
var envVarPath = Environment.GetEnvironmentVariable(EnvironmentVariableNames.NugetExePath);
if (!string.IsNullOrEmpty(envVarPath))
{
logger.LogInfo($"Using nuget.exe from environment variable: '{envVarPath}'");
return envVarPath;
}
try
{
return DownloadNugetExe(fileProvider.SourceDir.FullName);
}
catch (Exception exc)
{
logger.LogInfo($"Download of nuget.exe failed: {exc.Message}");
}
var nugetExesInRepo = fileProvider.NugetExes;
if (nugetExesInRepo.Count > 1)
{
logger.LogInfo($"Found multiple nuget.exe files in the repository: {string.Join(", ", nugetExesInRepo.OrderBy(s => s))}");
}
if (nugetExesInRepo.Count > 0)
{
var path = nugetExesInRepo.First();
logger.LogInfo($"Using nuget.exe from path '{path}'");
return path;
}
var executableName = IsWindows ? "nuget.exe" : "nuget";
var nugetPath = FileUtils.FindProgramOnPath(executableName);
if (nugetPath is not null)
{
nugetPath = Path.Join(nugetPath, executableName);
logger.LogInfo($"Using nuget.exe from PATH: {nugetPath}");
return nugetPath;
}
throw new Exception("Could not find or download nuget.exe.");
}
private string DownloadNugetExe(string sourceDir)
{
var directory = Path.Join(sourceDir, ".nuget");
var nuget = Path.Join(directory, "nuget.exe");
// Nuget.exe already exists in the .nuget directory.
if (File.Exists(nuget))
{
logger.LogInfo($"Found nuget.exe at {nuget}");
return nuget;
}
Directory.CreateDirectory(directory);
logger.LogInfo("Attempting to download nuget.exe");
FileUtils.DownloadFile(FileUtils.NugetExeUrl, nuget, logger);
logger.LogInfo($"Downloaded nuget.exe to {nuget}");
return nuget;
}
private bool RunWithMono => !IsWindows && !string.IsNullOrEmpty(Path.GetExtension(nugetExe));
/// <summary>
/// Restore all packages in the specified packages.config file.
/// </summary>
/// <param name="packagesConfig">The packages.config file.</param>
private bool TryRestoreNugetPackage(string packagesConfig)
{
logger.LogInfo($"Restoring file \"{packagesConfig}\"...");
/* Use nuget.exe to install a package.
* Note that there is a clutch of NuGet assemblies which could be used to
* invoke this directly, which would arguably be nicer. However they are
* really unwieldy and this solution works for now.
*/
string exe, args;
if (RunWithMono)
{
exe = "mono";
args = $"\"{nugetExe}\" install -OutputDirectory \"{packageDirectory}\" \"{packagesConfig}\"";
}
else
{
exe = nugetExe!;
args = $"install -OutputDirectory \"{packageDirectory}\" \"{packagesConfig}\"";
}
var pi = new ProcessStartInfo(exe, args)
{
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false
};
var threadId = Environment.CurrentManagedThreadId;
void onOut(string s) => logger.LogDebug(s, threadId);
void onError(string s) => logger.LogError(s, threadId);
var exitCode = pi.ReadOutput(out _, onOut, onError);
if (exitCode != 0)
{
logger.LogError($"Command {pi.FileName} {pi.Arguments} failed with exit code {exitCode}");
return false;
}
else
{
logger.LogInfo($"Restored file \"{packagesConfig}\"");
return true;
}
}
/// <summary>
/// Download the packages to the temp folder.
/// </summary>
public int InstallPackages()
{
return fileProvider.PackagesConfigs.Count(TryRestoreNugetPackage);
}
private bool HasPackageSource()
{
if (IsWindows)
{
return true;
}
try
{
logger.LogInfo("Checking if default package source is available...");
RunMonoNugetCommand("sources list -ForceEnglishOutput", out var stdout);
if (stdout.All(line => line != "No sources found."))
{
return true;
}
return false;
}
catch (Exception e)
{
logger.LogWarning($"Failed to check if default package source is added: {e}");
return true;
}
}
private void RunMonoNugetCommand(string command, out IList<string> stdout)
{
string exe, args;
if (RunWithMono)
{
exe = "mono";
args = $"\"{nugetExe}\" {command}";
}
else
{
exe = nugetExe!;
args = command;
}
var pi = new ProcessStartInfo(exe, args)
{
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false
};
var threadId = Environment.CurrentManagedThreadId;
void onOut(string s) => logger.LogDebug(s, threadId);
void onError(string s) => logger.LogError(s, threadId);
pi.ReadOutput(out stdout, onOut, onError);
}
private void AddDefaultPackageSource(string nugetConfig)
{
logger.LogInfo("Adding default package source...");
RunMonoNugetCommand($"sources add -Name DefaultNugetOrg -Source {NugetPackageRestorer.PublicNugetOrgFeed} -ConfigFile \"{nugetConfig}\"", out _);
}
public void Dispose()
{
if (nugetConfigPath is null)
{
return;
}
try
{
if (backupNugetConfig is null)
{
logger.LogInfo("Removing nuget.config file");
File.Delete(nugetConfigPath);
return;
}
logger.LogInfo("Reverting nuget.config file content");
// The content of the original nuget.config file is reverted without changing the file's attributes or casing:
using (var backup = File.OpenRead(backupNugetConfig))
using (var current = File.OpenWrite(nugetConfigPath))
{
current.SetLength(0); // Truncate file
backup.CopyTo(current); // Restore original content
}
logger.LogInfo("Deleting backup nuget.config file");
File.Delete(backupNugetConfig);
}
catch (Exception exc)
{
logger.LogError($"Failed to restore original nuget.config file: {exc}");
}
}
}
private class NoOpPackagesConfig : IPackagesConfigRestore
{
private readonly Semmle.Util.Logging.ILogger logger;
private readonly FileProvider fileProvider;
public NoOpPackagesConfig(FileProvider fileProvider, Semmle.Util.Logging.ILogger logger)
{
this.fileProvider = fileProvider;
this.logger = logger;
}
public int PackageCount => fileProvider.PackagesConfigs.Count;
public int InstallPackages()
{
if (PackageCount > 0)
{
logger.LogInfo("Found packages.config files, but nuget.exe cannot be used to restore packages on this platform. Skipping restore of packages.config files.");
}
return 0;
}
public void Dispose() { }
}
}
}

View File

@@ -79,7 +79,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
var monoPath = FileUtils.FindProgramOnPath(Win32.IsWindows() ? "mono.exe" : "mono");
string[] monoDirs = monoPath is not null
? [Path.GetFullPath(Path.Join(monoPath, "..", "lib", "mono")), monoPath]
? [Path.GetFullPath(Path.Combine(monoPath, "..", "lib", "mono")), monoPath]
: ["/usr/lib/mono", "/usr/local/mono", "/usr/local/bin/mono", @"C:\Program Files\Mono\lib\mono"];
var monoDir = monoDirs.FirstOrDefault(Directory.Exists);

View File

@@ -63,7 +63,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
return null;
}
var path = Path.Join(version.FullPath, "Roslyn", "bincore", "csc.dll");
var path = Path.Combine(version.FullPath, "Roslyn", "bincore", "csc.dll");
logger.LogDebug($"Source generator CSC: '{path}'");
if (!File.Exists(path))
{

View File

@@ -41,10 +41,10 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
.Replace('\\', '/'); // Ensure we're generating the same hash regardless of the OS
var name = FileUtils.ComputeHash($"{relativePathToCsProj}\n{this.GetType().Name}");
using var tempDir = new TemporaryDirectory(Path.Join(FileUtils.GetTemporaryWorkingDirectory(out _), "source-generator"), "source generator temporary", logger);
var analyzerConfigPath = Path.Join(tempDir.DirInfo.FullName, $"{name}.txt");
var dllPath = Path.Join(tempDir.DirInfo.FullName, $"{name}.dll");
var cscArgsPath = Path.Join(tempDir.DirInfo.FullName, $"{name}.rsp");
var outputFolder = Path.Join(targetDir, name);
var analyzerConfigPath = Path.Combine(tempDir.DirInfo.FullName, $"{name}.txt");
var dllPath = Path.Combine(tempDir.DirInfo.FullName, $"{name}.dll");
var cscArgsPath = Path.Combine(tempDir.DirInfo.FullName, $"{name}.rsp");
var outputFolder = Path.Combine(targetDir, name);
Directory.CreateDirectory(outputFolder);
logger.LogInfo("Producing analyzer config content.");
GenerateAnalyzerConfig(additionalFiles, csprojFile, analyzerConfigPath);

View File

@@ -21,7 +21,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
throw new Exception("No SDK path available.");
}
SourceGeneratorFolder = Path.Join(sdkPath, "Sdks", "Microsoft.NET.Sdk.Razor", "source-generators");
SourceGeneratorFolder = Path.Combine(sdkPath, "Sdks", "Microsoft.NET.Sdk.Razor", "source-generators");
this.logger.LogInfo($"Razor source generator folder: {SourceGeneratorFolder}");
if (!Directory.Exists(SourceGeneratorFolder))
{

View File

@@ -50,7 +50,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
if (usings.Count > 0)
{
var tempDir = GetTemporaryWorkingDirectory("implicitUsings");
var path = Path.Join(tempDir, "GlobalUsings.g.cs");
var path = Path.Combine(tempDir, "GlobalUsings.g.cs");
using (var writer = new StreamWriter(path))
{
writer.WriteLine("// <auto-generated/>");

View File

@@ -32,7 +32,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
var nugetFolder = nugetPackageRestorer.TryRestore("Microsoft.CodeAnalysis.ResxSourceGenerator");
if (nugetFolder is not null)
{
sourceGeneratorFolder = System.IO.Path.Join(nugetFolder, "analyzers", "dotnet", "cs");
sourceGeneratorFolder = System.IO.Path.Combine(nugetFolder, "analyzers", "dotnet", "cs");
}
}
catch (Exception e)

View File

@@ -35,7 +35,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
/// </summary>
protected string GetTemporaryWorkingDirectory(string subfolder)
{
var temp = Path.Join(tempWorkingDirectory.ToString(), subfolder);
var temp = Path.Combine(tempWorkingDirectory.ToString(), subfolder);
Directory.CreateDirectory(temp);
return temp;

View File

@@ -23,9 +23,7 @@ namespace Semmle.Extraction.CSharp.Entities.Statements
}
else if (isSpecificCatchClause) // A catch clause of the form 'catch(Ex) { ... }'
{
var type = Type.Create(Context, Context.GetType(Stmt.Declaration!.Type));
trapFile.catch_type(this, type.TypeRef, true);
TypeMention.Create(Context, Stmt.Declaration!.Type, this, type);
trapFile.catch_type(this, Type.Create(Context, Context.GetType(Stmt.Declaration!.Type)).TypeRef, true);
}
else // A catch clause of the form 'catch { ... }'
{

View File

@@ -67,7 +67,7 @@ namespace Semmle.Extraction.CSharp
return;
}
var mscorlibExists = File.Exists(Path.Join(compilerDir, "mscorlib.dll"));
var mscorlibExists = File.Exists(Path.Combine(compilerDir, "mscorlib.dll"));
if (specifiedFramework is null && mscorlibExists)
{
@@ -107,7 +107,7 @@ namespace Semmle.Extraction.CSharp
/// <summary>
/// The file csc.rsp.
/// </summary>
private string CscRsp => Path.Join(FrameworkPath, csc_rsp);
private string CscRsp => Path.Combine(FrameworkPath, csc_rsp);
/// <summary>
/// Should we skip extraction?

View File

@@ -680,7 +680,7 @@ namespace Semmle.Extraction.CSharp
{
try
{
var fullPath = Path.GetFullPath(Path.Join(Path.GetDirectoryName(mappedFromPath)!, mappedToPath));
var fullPath = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(mappedFromPath)!, mappedToPath));
ExtractionContext.Logger.LogDebug($"Found relative path in line mapping: '{mappedToPath}', interpreting it as '{fullPath}'");
mappedToPath = fullPath;

View File

@@ -159,11 +159,7 @@ namespace Semmle.Extraction.CSharp
return null;
}
var normalized = Path.DirectorySeparatorChar == '/' ? file.Replace("\\", "/") : file;
var path = projDir is not null && !Path.IsPathRooted(normalized)
? Path.Join(projDir.FullName, normalized)
: normalized;
return Path.GetFullPath(path);
return Path.GetFullPath(Path.Combine(projDir?.FullName ?? string.Empty, Path.DirectorySeparatorChar == '/' ? file.Replace("\\", "/") : file));
}
private readonly string[] references;

View File

@@ -210,7 +210,7 @@ namespace Semmle.Extraction.CSharp
TracingAnalyser.GetOutputName(compilation, args),
compilation,
generatedSyntaxTrees,
Path.Join(compilationIdentifierPath, diagnosticName),
Path.Combine(compilationIdentifierPath, diagnosticName),
options),
() => { });
@@ -377,7 +377,7 @@ namespace Semmle.Extraction.CSharp
else
{
var composed = referencePaths.Value
.Select(path => Path.Join(path, clref.Reference))
.Select(path => Path.Combine(path, clref.Reference))
.Where(path => File.Exists(path))
.Select(path => analyser.PathCache.GetCanonicalPath(path))
.FirstOrDefault();
@@ -559,13 +559,13 @@ namespace Semmle.Extraction.CSharp
/// Gets the path to the `csharp.log` file written to by the C# extractor.
/// </summary>
public static string GetCSharpLogPath() =>
Path.Join(GetCSharpLogDirectory(), "csharp.log");
Path.Combine(GetCSharpLogDirectory(), "csharp.log");
/// <summary>
/// Gets the path to a `csharp.{hash}.txt` file written to by the C# extractor.
/// </summary>
public static string GetCSharpArgsLogPath(string hash) =>
Path.Join(GetCSharpLogDirectory(), $"csharp.{hash}.txt");
Path.Combine(GetCSharpLogDirectory(), $"csharp.{hash}.txt");
/// <summary>
/// Gets a list of all `csharp.{hash}.txt` files currently written to the log directory.

View File

@@ -131,7 +131,7 @@ namespace Semmle.Extraction.CSharp
return Path.ChangeExtension(entryPointFilename, ".exe");
}
return Path.Join(commandLineArguments.OutputDirectory, commandLineArguments.OutputFileName);
return Path.Combine(commandLineArguments.OutputDirectory, commandLineArguments.OutputFileName);
}
private int LogDiagnostics()

View File

@@ -61,7 +61,7 @@ namespace Semmle.Extraction.CSharp
* Although GetRandomFileName() is cryptographically secure,
* there's a tiny chance the file could already exists.
*/
tmpFile = Path.Join(tempPath, Path.GetRandomFileName());
tmpFile = Path.Combine(tempPath, Path.GetRandomFileName());
}
while (File.Exists(tmpFile));

View File

@@ -82,13 +82,13 @@ namespace SemmleTests.Semmle.Util
[Fact]
public void CanonicalPathMissingFile()
{
Assert.Equal(Path.Join(Directory.GetCurrentDirectory(), "NOSUCHFILE"), cache.GetCanonicalPath("NOSUCHFILE"));
Assert.Equal(Path.Combine(Directory.GetCurrentDirectory(), "NOSUCHFILE"), cache.GetCanonicalPath("NOSUCHFILE"));
}
[Fact]
public void CanonicalPathMissingAbsolutePath()
{
Assert.Equal(Path.Join(root, "no", "such", "file"), cache.GetCanonicalPath(Path.Join(root, "no", "such", "file")));
Assert.Equal(Path.Combine(root, "no", "such", "file"), cache.GetCanonicalPath(Path.Combine(root, "no", "such", "file")));
if (Win32.IsWindows())
Assert.Equal(@"C:\Windows\no\such\file", cache.GetCanonicalPath(@"C:\windOws\no\such\file"));
@@ -97,7 +97,7 @@ namespace SemmleTests.Semmle.Util
[Fact]
public void CanonicalPathMissingRelativePath()
{
Assert.Equal(Path.Join(Directory.GetCurrentDirectory(), "NO", "SUCH"), cache.GetCanonicalPath(Path.Join("NO", "SUCH")));
Assert.Equal(Path.Combine(Directory.GetCurrentDirectory(), "NO", "SUCH"), cache.GetCanonicalPath(Path.Combine("NO", "SUCH")));
}
[Fact]
@@ -125,7 +125,7 @@ namespace SemmleTests.Semmle.Util
public void CanonicalPathDots()
{
var abcPath = Path.GetFullPath("abc");
Assert.Equal(abcPath, cache.GetCanonicalPath(Path.Join("foo", ".", "..", "abc")));
Assert.Equal(abcPath, cache.GetCanonicalPath(Path.Combine("foo", ".", "..", "abc")));
}
[Fact]

View File

@@ -14,20 +14,20 @@ namespace SemmleTests.Semmle.Util
public sealed class LongPaths
{
private static readonly string tmpDir = Environment.GetEnvironmentVariable("TEST_TMPDIR") ?? Path.GetTempPath();
private static readonly string longPathDir = Path.Join(tmpDir, "aaaaaaaaaaaaaaaaaaaaaaaaaaaa", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
private static readonly string longPathDir = Path.Combine(tmpDir, "aaaaaaaaaaaaaaaaaaaaaaaaaaaa", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
"ccccccccccccccccccccccccccccccc", "ddddddddddddddddddddddddddddddddddddd", "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", "fffffffffffffffffffffffffffffffff",
"ggggggggggggggggggggggggggggggggggg", "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
private static string MakeLongPath()
{
var uniquePostfix = Guid.NewGuid().ToString("N");
return Path.Join(longPathDir, $"iiiiiiiiiiiiiiii{uniquePostfix}.txt");
return Path.Combine(longPathDir, $"iiiiiiiiiiiiiiii{uniquePostfix}.txt");
}
private static string MakeShortPath()
{
var uniquePostfix = Guid.NewGuid().ToString("N");
return Path.Join(tmpDir, $"test{uniquePostfix}.txt");
return Path.Combine(tmpDir, $"test{uniquePostfix}.txt");
}
public LongPaths()
@@ -62,7 +62,7 @@ namespace SemmleTests.Semmle.Util
[Fact]
public void ParentDirectory()
{
Assert.Equal("abc", Path.GetDirectoryName(Path.Join("abc", "def")));
Assert.Equal("abc", Path.GetDirectoryName(Path.Combine("abc", "def")));
Assert.Equal(Win32.IsWindows() ? "\\" : "/", Path.GetDirectoryName($@"{Path.DirectorySeparatorChar}def"));
Assert.Equal("", Path.GetDirectoryName(@"def"));

View File

@@ -137,11 +137,11 @@ namespace Semmle.Util
bool IsMonoInstalled();
/// <summary>
/// Joins path segments, Path.Join().
/// Combine path segments, Path.Combine().
/// </summary>
/// <param name="parts">The parts of the path.</param>
/// <returns>The combined path.</returns>
string PathJoin(params string[] parts);
string PathCombine(params string[] parts);
/// <summary>
/// Gets the full path for <paramref name="path"/>, Path.GetFullPath().
@@ -293,7 +293,7 @@ namespace Semmle.Util
}
}
string IBuildActions.PathJoin(params string[] parts) => Path.Join(parts);
string IBuildActions.PathCombine(params string[] parts) => Path.Combine(parts);
void IBuildActions.WriteAllText(string filename, string contents) => File.WriteAllText(filename, contents);

View File

@@ -43,7 +43,7 @@ namespace Semmle.Util
var parent = Directory.GetParent(path);
return parent is not null ?
Path.Join(cache.GetCanonicalPath(parent.FullName), Path.GetFileName(path)) :
Path.Combine(cache.GetCanonicalPath(parent.FullName), Path.GetFileName(path)) :
path.ToUpperInvariant();
}
}
@@ -138,12 +138,12 @@ namespace Semmle.Util
var entries = Directory.GetFileSystemEntries(parentPath, name);
return entries.Length == 1
? entries[0]
: Path.Join(parentPath, name);
: Path.Combine(parentPath, name);
}
catch // lgtm[cs/catch-of-all-exceptions]
{
// IO error or security error querying directory.
return Path.Join(parentPath, name);
return Path.Combine(parentPath, name);
}
}
}

View File

@@ -82,7 +82,7 @@ namespace Semmle.Util
{
exes = new[] { prog };
}
var candidates = paths?.Where(path => exes.Any(exe0 => File.Exists(Path.Join(path, exe0))));
var candidates = paths?.Where(path => exes.Any(exe0 => File.Exists(Path.Combine(path, exe0))));
return candidates?.FirstOrDefault();
}
@@ -179,7 +179,7 @@ namespace Semmle.Util
{
innerpath = ConvertPathToSafeRelativePath(innerpath);
nested = Path.Join(outerpath, innerpath);
nested = Path.Combine(outerpath, innerpath);
}
try
{
@@ -203,7 +203,7 @@ namespace Semmle.Util
{
var tempPath = Path.GetTempPath();
var name = Guid.NewGuid().ToString("N").ToUpper();
var tempFolder = Path.Join(tempPath, "GitHub", name);
var tempFolder = Path.Combine(tempPath, "GitHub", name);
Directory.CreateDirectory(tempFolder);
return tempFolder;
});
@@ -231,7 +231,7 @@ namespace Semmle.Util
string outputPath;
do
{
outputPath = Path.Join(tempFolder, Path.GetRandomFileName() + extension);
outputPath = Path.Combine(tempFolder, Path.GetRandomFileName() + extension);
}
while (File.Exists(outputPath));

View File

@@ -121,13 +121,6 @@ private module Cached {
result = getAChildExpr(parent)
or
result = parent.getAChildStmt()
or
result =
any(TypeMention tm |
tm.getTarget() = parent
or
tm.getParent+().getTarget() = parent
)
}
private predicate parent(ControlFlowElement child, ExprOrStmtParent parent) {

View File

@@ -6,7 +6,6 @@ import Generics
import Location
import Namespace
import Property
import semmle.code.csharp.controlflow.ControlFlowElement
private import Conversion
private import semmle.code.csharp.metrics.Coupling
private import TypeRef
@@ -1287,7 +1286,7 @@ class TupleType extends ValueType, @tuple_type {
* A type mention, that is, any mention of a type in a source code file.
* For example, `int` is mentioned in `int M() { return 1; }`.
*/
class TypeMention extends ControlFlowElement, @type_mention {
class TypeMention extends @type_mention {
Type type;
@type_mention_parent parent;
@@ -1320,13 +1319,13 @@ class TypeMention extends ControlFlowElement, @type_mention {
* }
* ```
*/
override TypeMention getParent() { result = parent }
TypeMention getParent() { result = parent }
/** Gets a textual representation of this type mention. */
override string toString() { result = type.toString() }
string toString() { result = type.toString() }
/** Gets the location of this type mention. */
override Location getALocation() { type_mention_location(this, result) }
Location getLocation() { type_mention_location(this, result) }
}
/**

View File

@@ -20,7 +20,7 @@ class ControlFlowElementOrCallable extends ExprOrStmtParent, TControlFlowElement
*/
class ControlFlowElement extends ControlFlowElementOrCallable, @control_flow_element {
/** Gets the enclosing callable of this element, if any. */
Callable getEnclosingCallable() { enclosingCallable(this, result) }
Callable getEnclosingCallable() { none() }
/** Gets the assembly that this element was compiled into. */
Assembly getAssembly() {

View File

@@ -145,8 +145,6 @@ module Ast implements AstSig<Location> {
final private class ParameterFinal = CS::Parameter;
class Parameter extends ParameterFinal {
AstNode getPattern() { result = this }
Expr getDefaultValue() {
// Avoid combinatorial explosions for callables with multiple bodies
result = unique( | | super.getDefaultValue())

View File

@@ -219,7 +219,7 @@ overlayChangedFiles(
/** ELEMENTS **/
@element = @declaration | @stmt | @expr | @modifier | @attribute | @namespace_declaration
| @using_directive | @type_parameter_constraints | @type_mention | @externalDataElement
| @using_directive | @type_parameter_constraints | @externalDataElement
| @xmllocatable | @asp_element | @namespace | @preprocessor_directive;
@declaration = @callable | @generic | @assignable | @namespace;
@@ -1369,7 +1369,7 @@ compiler_generated(unique int id: @element ref);
/** CONTROL/DATA FLOW **/
@control_flow_element = @stmt | @expr | @parameter | @type_mention;
@control_flow_element = @stmt | @expr | @parameter;
/* XML Files */

View File

@@ -101,7 +101,6 @@ csharp6.cs:
# 32| 0: [IntLiteral] 2
# 32| 0: [IntLiteral] 1
# 34| 1: [SpecificCatchClause] catch (...) {...}
# 34| 0: [TypeMention] IndexOutOfRangeException
# 35| 1: [BlockStmt] {...}
# 34| 2: [EQExpr] ... == ...
# 34| 0: [PropertyCall] access to property Value

View File

@@ -194,16 +194,3 @@ class C3<T> : C2<C4<T>> { }
class C4<T> : C2<C3<T>> { }
class C5 : C4<C5> { }
class CatchTypeMentions
{
void F()
{
try
{
}
catch (Exception)
{
}
}
}

View File

@@ -100,5 +100,3 @@
| Program.cs:194:21:194:21 | T |
| Program.cs:196:12:196:17 | C4<C5> |
| Program.cs:196:15:196:16 | C5 |
| Program.cs:200:5:200:8 | Void |
| Program.cs:205:16:205:24 | Exception |

View File

@@ -21,7 +21,7 @@
Java,"Java 7 to 26 [6]_","javac (OpenJDK and Oracle JDK),
Eclipse compiler for Java (ECJ) [7]_",``.java``
Kotlin,"Kotlin 1.8.0 to 2.3.2\ *x*","kotlinc",``.kt``
Kotlin,"Kotlin 1.8.0 to 2.4.0\ *x*","kotlinc",``.kt``
JavaScript,ECMAScript 2022 or lower,Not applicable,"``.js``, ``.jsx``, ``.mjs``, ``.es``, ``.es6``, ``.htm``, ``.html``, ``.xhtm``, ``.xhtml``, ``.vue``, ``.hbs``, ``.ejs``, ``.njk``, ``.json``, ``.yaml``, ``.yml``, ``.raml``, ``.xml`` [8]_"
Python [9]_,"2.7, 3.5, 3.6, 3.7, 3.8, 3.9, 3.10, 3.11, 3.12, 3.13",Not applicable,``.py``
Ruby [10]_,"up to 3.3",Not applicable,"``.rb``, ``.erb``, ``.gemspec``, ``Gemfile``"

View File

@@ -123,7 +123,7 @@ k8s.io/api/core,,,10,,,,,,,,,,,,,,,,,,,,,,,10,
k8s.io/apimachinery/pkg/runtime,,,47,,,,,,,,,,,,,,,,,,,,,,,47,
k8s.io/klog,90,,,,,,90,,,,,,,,,,,,,,,,,,,,
launchpad.net/xmlpath,2,,,,,,,,,,,,,,,,,,2,,,,,,,,
log,40,,3,,,,40,,,,,,,,,,,,,,,,,,,3,
log,20,,3,,,,20,,,,,,,,,,,,,,,,,,,3,
math/big,,,1,,,,,,,,,,,,,,,,,,,,,,,1,
mime,,,14,,,,,,,,,,,,,,,,,,,,,,,14,
net,2,16,100,,,,,,1,,,,,,,,1,,,,,,,16,,100,
1 package sink source summary sink:command-injection sink:credentials-key sink:jwt sink:log-injection sink:nosql-injection sink:path-injection sink:regex-use[0] sink:regex-use[1] sink:regex-use[c] sink:request-forgery sink:request-forgery[TCP Addr + Port] sink:sql-injection sink:url-redirection sink:url-redirection[0] sink:url-redirection[receiver] sink:xpath-injection source:commandargs source:database source:environment source:file source:remote source:stdin summary:taint summary:value
123 k8s.io/apimachinery/pkg/runtime 47 47
124 k8s.io/klog 90 90
125 launchpad.net/xmlpath 2 2
126 log 40 20 3 40 20 3
127 math/big 1 1
128 mime 14 14
129 net 2 16 100 1 1 16 100

View File

@@ -32,7 +32,7 @@ Go framework & library support
`Revel <http://revel.github.io/>`_,"``github.com/revel/revel*``, ``github.com/robfig/revel*``",46,20,4
`SendGrid <https://github.com/sendgrid/sendgrid-go>`_,``github.com/sendgrid/sendgrid-go*``,,1,
`Squirrel <https://github.com/Masterminds/squirrel>`_,"``github.com/Masterminds/squirrel*``, ``github.com/lann/squirrel*``, ``gopkg.in/Masterminds/squirrel``",81,,96
`Standard library <https://pkg.go.dev/std>`_,"````, ``archive/*``, ``bufio``, ``bytes``, ``cmp``, ``compress/*``, ``container/*``, ``context``, ``crypto``, ``crypto/*``, ``database/*``, ``debug/*``, ``embed``, ``encoding``, ``encoding/*``, ``errors``, ``expvar``, ``flag``, ``fmt``, ``go/*``, ``hash``, ``hash/*``, ``html``, ``html/*``, ``image``, ``image/*``, ``index/*``, ``io``, ``io/*``, ``log``, ``log/*``, ``maps``, ``math``, ``math/*``, ``mime``, ``mime/*``, ``net``, ``net/*``, ``os``, ``os/*``, ``path``, ``path/*``, ``plugin``, ``reflect``, ``reflect/*``, ``regexp``, ``regexp/*``, ``slices``, ``sort``, ``strconv``, ``strings``, ``sync``, ``sync/*``, ``syscall``, ``syscall/*``, ``testing``, ``testing/*``, ``text/*``, ``time``, ``time/*``, ``unicode``, ``unicode/*``, ``unsafe``, ``weak``",52,612,124
`Standard library <https://pkg.go.dev/std>`_,"````, ``archive/*``, ``bufio``, ``bytes``, ``cmp``, ``compress/*``, ``container/*``, ``context``, ``crypto``, ``crypto/*``, ``database/*``, ``debug/*``, ``embed``, ``encoding``, ``encoding/*``, ``errors``, ``expvar``, ``flag``, ``fmt``, ``go/*``, ``hash``, ``hash/*``, ``html``, ``html/*``, ``image``, ``image/*``, ``index/*``, ``io``, ``io/*``, ``log``, ``log/*``, ``maps``, ``math``, ``math/*``, ``mime``, ``mime/*``, ``net``, ``net/*``, ``os``, ``os/*``, ``path``, ``path/*``, ``plugin``, ``reflect``, ``reflect/*``, ``regexp``, ``regexp/*``, ``slices``, ``sort``, ``strconv``, ``strings``, ``sync``, ``sync/*``, ``syscall``, ``syscall/*``, ``testing``, ``testing/*``, ``text/*``, ``time``, ``time/*``, ``unicode``, ``unicode/*``, ``unsafe``, ``weak``",52,612,104
`XORM <https://xorm.io>`_,"``github.com/go-xorm/xorm*``, ``xorm.io/xorm*``",,,68
`XPath <https://github.com/antchfx/xpath>`_,``github.com/antchfx/xpath*``,,,4
`appleboy/gin-jwt <https://github.com/appleboy/gin-jwt>`_,``github.com/appleboy/gin-jwt*``,,,1
@@ -74,5 +74,5 @@ Go framework & library support
`xpathparser <https://github.com/santhosh-tekuri/xpathparser>`_,``github.com/santhosh-tekuri/xpathparser*``,,,2
`yaml <https://gopkg.in/yaml.v3>`_,``gopkg.in/yaml*``,,9,
`zap <https://go.uber.org/zap>`_,``go.uber.org/zap*``,,11,33
Totals,,688,1072,1577
Totals,,688,1072,1557

View File

@@ -1,4 +0,0 @@
---
category: deprecated
---
* `FuncTypeExpr.getResultDecl()` has been deprecated. Use `FuncTypeExpr.getResultDecl(int i)` instead.

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* `DataFlow::ResultNode`s are no longer created for returned expressions in functions with named result parameters. In this case there are already result nodes corresponding to `IR::ReadResultInstruction`s at the end of the function body.

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* `FuncTypeExpr.getNumResult()` now gets the number of result parameters. It previously got the number of result declarations, which is different when one result declaration declares more than one variable, as in `x, y int`. All uses of it expected the number of result parameters. Its QLDoc has been updated.

View File

@@ -1,8 +0,0 @@
---
category: minorAnalysis
---
* Added models for the `log/slog` package (Go 1.21+). Its logging functions and
`*slog.Logger` methods (`Debug`/`Info`/`Warn`/`Error`, their `Context`
variants, and `Log`/`LogAttrs`) are now recognized as logging sinks, so the
`go/log-injection` and `go/clear-text-logging` queries cover code that logs
through `slog`.

View File

@@ -1,29 +0,0 @@
extensions:
- addsTo:
pack: codeql/go-all
extensible: sinkModel
data:
# Package-level convenience functions (msg string, args ...any).
- ["log/slog", "", False, "Debug", "", "", "Argument[0..1]", "log-injection", "manual"]
- ["log/slog", "", False, "Info", "", "", "Argument[0..1]", "log-injection", "manual"]
- ["log/slog", "", False, "Warn", "", "", "Argument[0..1]", "log-injection", "manual"]
- ["log/slog", "", False, "Error", "", "", "Argument[0..1]", "log-injection", "manual"]
# Context variants (ctx, msg string, args ...any).
- ["log/slog", "", False, "DebugContext", "", "", "Argument[1..2]", "log-injection", "manual"]
- ["log/slog", "", False, "InfoContext", "", "", "Argument[1..2]", "log-injection", "manual"]
- ["log/slog", "", False, "WarnContext", "", "", "Argument[1..2]", "log-injection", "manual"]
- ["log/slog", "", False, "ErrorContext", "", "", "Argument[1..2]", "log-injection", "manual"]
# Log/LogAttrs (ctx, level, msg string, args/attrs ...).
- ["log/slog", "", False, "Log", "", "", "Argument[2..3]", "log-injection", "manual"]
- ["log/slog", "", False, "LogAttrs", "", "", "Argument[2..3]", "log-injection", "manual"]
# Methods on *slog.Logger.
- ["log/slog", "Logger", True, "Debug", "", "", "Argument[0..1]", "log-injection", "manual"]
- ["log/slog", "Logger", True, "Info", "", "", "Argument[0..1]", "log-injection", "manual"]
- ["log/slog", "Logger", True, "Warn", "", "", "Argument[0..1]", "log-injection", "manual"]
- ["log/slog", "Logger", True, "Error", "", "", "Argument[0..1]", "log-injection", "manual"]
- ["log/slog", "Logger", True, "DebugContext", "", "", "Argument[1..2]", "log-injection", "manual"]
- ["log/slog", "Logger", True, "InfoContext", "", "", "Argument[1..2]", "log-injection", "manual"]
- ["log/slog", "Logger", True, "WarnContext", "", "", "Argument[1..2]", "log-injection", "manual"]
- ["log/slog", "Logger", True, "ErrorContext", "", "", "Argument[1..2]", "log-injection", "manual"]
- ["log/slog", "Logger", True, "Log", "", "", "Argument[2..3]", "log-injection", "manual"]
- ["log/slog", "Logger", True, "LogAttrs", "", "", "Argument[2..3]", "log-injection", "manual"]

View File

@@ -10,7 +10,6 @@ dependencies:
codeql/controlflow: ${workspace}
codeql/dataflow: ${workspace}
codeql/mad: ${workspace}
codeql/ssa: ${workspace}
codeql/threat-models: ${workspace}
codeql/tutorial: ${workspace}
codeql/util: ${workspace}

View File

@@ -1049,29 +1049,17 @@ class FuncTypeExpr extends @functypeexpr, TypeExpr, ScopeNode, FieldParent {
*/
int getNumParameter() { result = count(this.getAParameterDecl().getANameExpr()) }
/**
* Gets the `i`th result declaration of this function type (0-based).
*
* Note: `x, y int` is a single `ResultVariableDecl`.
*/
/** Gets the `i`th result of this function type (0-based). */
ResultVariableDecl getResultDecl(int i) { result = this.getField(-(i + 1)) }
/**
* Gets a result declaration of this function type.
*
* Note: `x, y int` is a single `ResultVariableDecl`.
*/
/** Gets a result of this function type. */
ResultVariableDecl getAResultDecl() { result = this.getResultDecl(_) }
/** Gets the number of result parameters of this function type. */
int getNumResult() { result = count(this.getAResultDecl().getANameExpr()) }
/** Gets the number of results of this function type. */
int getNumResult() { result = count(this.getAResultDecl()) }
/**
* DEPRECATED: Use `getResultDecl(int i)` instead.
*/
deprecated ResultVariableDecl getResultDecl() {
this.getNumResult() = 1 and result = this.getAResultDecl()
}
/** Gets the result of this function type, if there is only one. */
ResultVariableDecl getResultDecl() { this.getNumResult() = 1 and result = this.getAResultDecl() }
override string toString() { result = "function type" }

View File

@@ -42,11 +42,11 @@ private module Input implements BB::InputSig<Location> {
predicate nodeIsPostDominanceExit(Node node) { node instanceof ExitNode }
}
module Cfg = BB::Make<Location, Input>;
private module BbImpl = BB::Make<Location, Input>;
class BasicBlock = Cfg::BasicBlock;
class BasicBlock = BbImpl::BasicBlock;
class EntryBasicBlock = Cfg::EntryBasicBlock;
class EntryBasicBlock = BbImpl::EntryBasicBlock;
cached
private predicate reachableBB(BasicBlock bb) {

View File

@@ -63,7 +63,10 @@ private predicate unresolvedIdentifier(Ident id, string name) {
/**
* An SSA variable.
*/
class SsaVariable extends Definition {
class SsaVariable extends TSsaDefinition {
/** Gets the source variable corresponding to this SSA variable. */
SsaSourceVariable getSourceVariable() { result = this.(SsaDefinition).getSourceVariable() }
/** Gets the (unique) definition of this SSA variable. */
SsaDefinition getDefinition() { result = this }
@@ -71,17 +74,22 @@ class SsaVariable extends Definition {
Type getType() { result = this.getSourceVariable().getType() }
/** Gets a use in basic block `bb` that refers to this SSA variable. */
IR::Instruction getAUseIn(BasicBlock bb) {
IR::Instruction getAUseIn(ReachableBasicBlock bb) {
exists(int i, SsaSourceVariable v | v = this.getSourceVariable() |
result = bb.getNode(i) and
ssaDefReachesRead(v, this, bb, i) and
useAt(bb, i, v)
this = getDefinition(bb, i, v)
)
}
/** Gets a use that refers to this SSA variable. */
IR::Instruction getAUse() { result = this.getAUseIn(_) }
/** Gets a textual representation of this element. */
string toString() { result = this.getDefinition().prettyPrintRef() }
/** Gets the location of this SSA variable. */
Location getLocation() { result = this.getDefinition().getLocation() }
/**
* DEPRECATED: Use `getLocation()` instead.
*
@@ -101,20 +109,50 @@ class SsaVariable extends Definition {
/**
* An SSA definition.
*/
class SsaDefinition extends Definition {
class SsaDefinition extends TSsaDefinition {
/** Gets the SSA variable defined by this definition. */
SsaVariable getVariable() { result = this }
/** Gets the innermost function or file to which this SSA definition belongs. */
ControlFlow::Root getRoot() { result = this.getBasicBlock().getScope() }
/** Gets the source variable defined by this definition. */
abstract SsaSourceVariable getSourceVariable();
/**
* Gets the basic block to which this definition belongs.
*/
abstract ReachableBasicBlock getBasicBlock();
/**
* INTERNAL: Use `getBasicBlock()` and `getSourceVariable()` instead.
*
* Holds if this is a definition of source variable `v` at index `idx` in basic block `bb`.
*
* Phi nodes are considered to be at index `-1`, all other definitions at the index of
* the control flow node they correspond to.
*/
abstract predicate definesAt(ReachableBasicBlock bb, int idx, SsaSourceVariable v);
/**
* INTERNAL: Use `toString()` instead.
*
* Gets a pretty-printed representation of this SSA definition.
*/
abstract string prettyPrintDef();
/**
* INTERNAL: Do not use.
*
* Gets a short string identifying the kind of this SSA definition,
* used in reference formatting (e.g., `"def"`, `"capture"`, `"phi"`).
* Gets a pretty-printed representation of a reference to this SSA definition.
*/
string getKind() { none() }
abstract string prettyPrintRef();
/** Gets the innermost function or file to which this SSA definition belongs. */
ControlFlow::Root getRoot() { result = this.getBasicBlock().getScope() }
/** Gets a textual representation of this element. */
string toString() { result = this.prettyPrintDef() }
/** Gets the source location for this element. */
abstract Location getLocation();
/**
* DEPRECATED: Use `getLocation()` instead.
@@ -142,23 +180,32 @@ class SsaDefinition extends Definition {
/**
* An SSA definition that corresponds to an explicit assignment or other variable definition.
*/
class SsaExplicitDefinition extends SsaDefinition, WriteDefinition {
SsaExplicitDefinition() {
exists(BasicBlock bb, int i, SsaSourceVariable v |
this.definesAt(v, bb, i) and
defAt(bb, i, v)
)
}
class SsaExplicitDefinition extends SsaDefinition, TExplicitDef {
/** Gets the instruction where the definition happens. */
IR::Instruction getInstruction() {
exists(BasicBlock bb, int i | this.definesAt(_, bb, i) | result = bb.getNode(i))
exists(BasicBlock bb, int i | this = TExplicitDef(bb, i, _) | result = bb.getNode(i))
}
/** Gets the right-hand side of the definition. */
IR::Instruction getRhs() { this.getInstruction().writes(_, result) }
override string getKind() { result = "def" }
override predicate definesAt(ReachableBasicBlock bb, int i, SsaSourceVariable v) {
this = TExplicitDef(bb, i, v)
}
override ReachableBasicBlock getBasicBlock() { this.definesAt(result, _, _) }
override SsaSourceVariable getSourceVariable() { this = TExplicitDef(_, _, result) }
override string prettyPrintRef() {
exists(Location loc | loc = this.getLocation() |
result = "def@" + loc.getStartLine() + ":" + loc.getStartColumn()
)
}
override string prettyPrintDef() { result = "definition of " + this.getSourceVariable() }
override Location getLocation() { result = this.getInstruction().getLocation() }
}
/** Provides a helper predicate for working with explicit SSA definitions. */
@@ -172,7 +219,22 @@ module SsaExplicitDefinition {
/**
* An SSA definition that does not correspond to an explicit variable definition.
*/
abstract class SsaImplicitDefinition extends SsaDefinition { }
abstract class SsaImplicitDefinition extends SsaDefinition {
/**
* INTERNAL: Do not use.
*
* Gets the definition kind to include in `prettyPrintRef`.
*/
abstract string getKind();
override string prettyPrintRef() {
exists(Location loc | loc = this.getLocation() |
result = this.getKind() + "@" + loc.getStartLine() + ":" + loc.getStartColumn()
)
}
override Location getLocation() { result = this.getBasicBlock().getLocation() }
}
/**
* An SSA definition representing the capturing of an SSA-convertible variable
@@ -181,8 +243,24 @@ abstract class SsaImplicitDefinition extends SsaDefinition { }
* Capturing definitions appear at the beginning of such functions, as well as
* at any function call that may affect the value of the variable.
*/
class SsaVariableCapture extends SsaImplicitDefinition, UncertainWriteDefinition {
class SsaVariableCapture extends SsaImplicitDefinition, TCapture {
override predicate definesAt(ReachableBasicBlock bb, int i, SsaSourceVariable v) {
this = TCapture(bb, i, v)
}
override ReachableBasicBlock getBasicBlock() { this.definesAt(result, _, _) }
override SsaSourceVariable getSourceVariable() { this.definesAt(_, _, result) }
override string getKind() { result = "capture" }
override string prettyPrintDef() { result = "capture variable " + this.getSourceVariable() }
override Location getLocation() {
exists(ReachableBasicBlock bb, int i | this.definesAt(bb, i, _) |
result = bb.getNode(i).getLocation()
)
}
}
/**
@@ -194,6 +272,12 @@ abstract class SsaPseudoDefinition extends SsaImplicitDefinition {
* Gets an input of this pseudo-definition.
*/
abstract SsaVariable getAnInput();
/**
* Gets a textual representation of the inputs of this pseudo-definition
* in lexicographical order.
*/
string ppInputs() { result = concat(this.getAnInput().getDefinition().prettyPrintRef(), ", ") }
}
/**
@@ -201,10 +285,26 @@ abstract class SsaPseudoDefinition extends SsaImplicitDefinition {
* in the flow graph where otherwise two or more definitions for the variable
* would be visible.
*/
class SsaPhiNode extends SsaPseudoDefinition, PhiNode {
override SsaVariable getAnInput() { phiHasInputFromBlock(this, result, _) }
class SsaPhiNode extends SsaPseudoDefinition, TPhi {
override SsaVariable getAnInput() {
result = getDefReachingEndOf(this.getBasicBlock().getAPredecessor(_), this.getSourceVariable())
}
override predicate definesAt(ReachableBasicBlock bb, int i, SsaSourceVariable v) {
bb = this.getBasicBlock() and v = this.getSourceVariable() and i = -1
}
override ReachableBasicBlock getBasicBlock() { this = TPhi(result, _) }
override SsaSourceVariable getSourceVariable() { this = TPhi(_, result) }
override string getKind() { result = "phi" }
override string prettyPrintDef() {
result = this.getSourceVariable() + " = phi(" + this.ppInputs() + ")"
}
override Location getLocation() { result = this.getBasicBlock().getLocation() }
}
/**

View File

@@ -7,25 +7,76 @@ overlay[local]
module;
import go
private import codeql.ssa.Ssa as SsaImplCommon
private import semmle.go.controlflow.BasicBlocks as BasicBlocks
private class BasicBlock = BasicBlocks::BasicBlock;
cached
private module Internal {
/** Holds if the `i`th node of `bb` defines `v`. */
cached
predicate defAt(BasicBlock bb, int i, SsaSourceVariable v) {
predicate defAt(ReachableBasicBlock bb, int i, SsaSourceVariable v) {
bb.getNode(i).(IR::Instruction).writes(v, _)
}
/** Holds if the `i`th node of `bb` reads `v`. */
cached
predicate useAt(BasicBlock bb, int i, SsaSourceVariable v) {
predicate useAt(ReachableBasicBlock bb, int i, SsaSourceVariable v) {
bb.getNode(i).(IR::Instruction).reads(v)
}
/**
* A data type representing SSA definitions.
*
* We distinguish three kinds of SSA definitions:
*
* 1. Variable definitions, including declarations, assignments and increments/decrements.
* 2. Pseudo-definitions for captured variables at the beginning of the capturing function
* as well as after calls.
* 3. Phi nodes.
*
* SSA definitions are only introduced where necessary. In particular,
* unreachable code has no SSA definitions associated with it, and neither
* have dead assignments (that is, assignments whose value is never read).
*/
cached
newtype TSsaDefinition =
/**
* An SSA definition that corresponds to an explicit assignment or other variable definition.
*/
TExplicitDef(ReachableBasicBlock bb, int i, SsaSourceVariable v) {
defAt(bb, i, v) and
(liveAfterDef(bb, i, v) or v.isCaptured())
} or
/**
* An SSA definition representing the capturing of an SSA-convertible variable
* in the closure of a nested function.
*
* Capturing definitions appear at the beginning of such functions, as well as
* at any function call that may affect the value of the variable.
*/
TCapture(ReachableBasicBlock bb, int i, SsaSourceVariable v) {
mayCapture(bb, i, v) and
liveAfterDef(bb, i, v)
} or
/**
* An SSA phi node, that is, a pseudo-definition for a variable at a point
* in the flow graph where otherwise two or more definitions for the variable
* would be visible.
*/
TPhi(ReachableJoinBlock bb, SsaSourceVariable v) {
liveAtEntry(bb, v) and
inDefDominanceFrontier(bb, v)
}
/**
* Holds if `bb` is in the dominance frontier of a block containing a definition of `v`.
*/
pragma[noinline]
private predicate inDefDominanceFrontier(ReachableJoinBlock bb, SsaSourceVariable v) {
exists(ReachableBasicBlock defbb, SsaDefinition def |
def.definesAt(defbb, _, v) and
defbb.inDominanceFrontier(bb)
)
}
/**
* Holds if `v` is a captured variable which is declared in `declFun` and read in `useFun`.
*/
@@ -36,7 +87,7 @@ private module Internal {
}
/** Holds if the `i`th node of `bb` in function `f` is an entry node. */
private predicate entryNode(FuncDef f, BasicBlock bb, int i) {
private predicate entryNode(FuncDef f, ReachableBasicBlock bb, int i) {
f = bb.getScope() and
bb.getNode(i).isEntryNode()
}
@@ -44,17 +95,17 @@ private module Internal {
/**
* Holds if the `i`th node of `bb` in function `f` is a function call.
*/
private predicate callNode(FuncDef f, BasicBlock bb, int i) {
private predicate callNode(FuncDef f, ReachableBasicBlock bb, int i) {
f = bb.getScope() and
bb.getNode(i).(IR::EvalInstruction).getExpr() instanceof CallExpr
}
/**
* Holds if the `i`th node of basic block `bb` may induce a pseudo-definition for
* modeling updates to captured variable `v`.
* modeling updates to captured variable `v`. Whether the definition is actually
* introduced depends on whether `v` is live at this point in the program.
*/
cached
predicate mayUpdateCapturedVariable(BasicBlock bb, int i, SsaSourceVariable v) {
private predicate mayCapture(ReachableBasicBlock bb, int i, SsaSourceVariable v) {
exists(FuncDef capturingContainer, FuncDef declContainer |
// capture initial value of variable declared in enclosing scope
readsCapturedVar(capturingContainer, v, declContainer) and
@@ -68,134 +119,347 @@ private module Internal {
)
}
/** A classification of variable references into reads and writes. */
private newtype RefKind =
ReadRef() or
WriteRef()
/**
* Holds if the `i`th node of basic block `bb` is a reference to `v`, either a read
* (when `tp` is `ReadRef()`) or a direct or indirect write (when `tp` is `WriteRef()`).
*/
private predicate ref(ReachableBasicBlock bb, int i, SsaSourceVariable v, RefKind tp) {
useAt(bb, i, v) and tp = ReadRef()
or
(mayCapture(bb, i, v) or defAt(bb, i, v)) and
tp = WriteRef()
}
/**
* Gets the (1-based) rank of the reference to `v` at the `i`th node of basic block `bb`,
* which has the given reference kind `tp`.
*/
private int refRank(ReachableBasicBlock bb, int i, SsaSourceVariable v, RefKind tp) {
i = rank[result](int j | ref(bb, j, v, _)) and
ref(bb, i, v, tp)
}
/**
* Gets the maximum rank among all references to `v` in basic block `bb`.
*/
private int maxRefRank(ReachableBasicBlock bb, SsaSourceVariable v) {
result = max(refRank(bb, _, v, _))
}
/**
* Holds if variable `v` is live after the `i`th node of basic block `bb`, where
* `i` is the index of a node that may assign or capture `v`.
*
* For the purposes of this predicate, function calls are considered as writes of captured variables.
*/
private predicate liveAfterDef(ReachableBasicBlock bb, int i, SsaSourceVariable v) {
exists(int r | r = refRank(bb, i, v, WriteRef()) |
// the next reference to `v` inside `bb` is a read
r + 1 = refRank(bb, _, v, ReadRef())
or
// this is the last reference to `v` inside `bb`, but `v` is live at entry
// to a successor basic block of `bb`
r = maxRefRank(bb, v) and
liveAtSuccEntry(bb, v)
)
}
/**
* Holds if variable `v` is live at the beginning of basic block `bb`.
*
* For the purposes of this predicate, function calls are considered as writes of captured variables.
*/
private predicate liveAtEntry(ReachableBasicBlock bb, SsaSourceVariable v) {
// the first reference to `v` inside `bb` is a read
refRank(bb, _, v, ReadRef()) = 1
or
// there is no reference to `v` inside `bb`, but `v` is live at entry
// to a successor basic block of `bb`
not exists(refRank(bb, _, v, _)) and
liveAtSuccEntry(bb, v)
}
/**
* Holds if `v` is live at the beginning of any successor of basic block `bb`.
*/
private predicate liveAtSuccEntry(ReachableBasicBlock bb, SsaSourceVariable v) {
liveAtEntry(bb.getASuccessor(_), v)
}
/**
* Holds if `v` is assigned outside its declaring function.
*/
cached
predicate assignedThroughClosure(SsaSourceVariable v) {
private predicate assignedThroughClosure(SsaSourceVariable v) {
any(IR::Instruction def | def.writes(v, _)).getRoot() != v.getDeclaringFunction()
}
/** SSA input. */
cached
module SsaInput implements SsaImplCommon::InputSig<Location, BasicBlock> {
class SourceVariable = SsaSourceVariable;
/**
* Holds if the `i`th node of `bb` is a use or an SSA definition of variable `v`, with
* `k` indicating whether it is the former or the latter.
*
* Note this includes phi nodes, whereas `ref` above only includes explicit writes and captures.
*/
private predicate ssaRef(ReachableBasicBlock bb, int i, SsaSourceVariable v, RefKind k) {
useAt(bb, i, v) and k = ReadRef()
or
any(SsaDefinition def).definesAt(bb, i, v) and k = WriteRef()
}
/**
* Holds if the `i`th node of basic block `bb` is a (potential) write to source
* variable `v`. The Boolean `certain` indicates whether the write is certain.
*
* Certain writes are explicit definitions; uncertain writes are captures.
*/
cached
predicate variableWrite(BasicBlock bb, int i, SourceVariable v, boolean certain) {
defAt(bb, i, v) and certain = true
/**
* Gets the (1-based) rank of the `i`th node of `bb` among all SSA definitions
* and uses of `v` in `bb`, with `k` indicating whether it is a definition or a use.
*
* For example, if `bb` is a basic block with a phi node for `v` (considered
* to be at index -1), uses `v` at node 2 and defines it at node 5, we have:
*
* ```
* ssaRefRank(bb, -1, v, WriteRef()) = 1 // phi node
* ssaRefRank(bb, 2, v, ReadRef()) = 2 // use at node 2
* ssaRefRank(bb, 5, v, WriteRef()) = 3 // definition at node 5
* ```
*/
private int ssaRefRank(ReachableBasicBlock bb, int i, SsaSourceVariable v, RefKind k) {
i = rank[result](int j | ssaRef(bb, j, v, _)) and
ssaRef(bb, i, v, k)
}
/**
* Gets the minimum rank of a read in `bb` such that all references to `v` between that
* read and the read at index `i` are reads (and not writes).
*/
private int rewindReads(ReachableBasicBlock bb, int i, SsaSourceVariable v) {
exists(int r | r = ssaRefRank(bb, i, v, ReadRef()) |
exists(int j, RefKind k | r - 1 = ssaRefRank(bb, j, v, k) |
k = ReadRef() and result = rewindReads(bb, j, v)
or
k = WriteRef() and result = r
)
or
mayUpdateCapturedVariable(bb, i, v) and certain = false
r = 1 and result = r
)
}
/**
* Gets the SSA definition of `v` in `bb` that reaches the read of `v` at node `i`, if any.
*/
private SsaDefinition getLocalDefinition(ReachableBasicBlock bb, int i, SsaSourceVariable v) {
exists(int r | r = rewindReads(bb, i, v) |
exists(int j | result.definesAt(bb, j, v) and ssaRefRank(bb, j, v, _) = r - 1)
)
}
/**
* Gets an SSA definition of `v` that reaches the end of the immediate dominator of `bb`.
*/
pragma[noinline]
private SsaDefinition getDefReachingEndOfImmediateDominator(
ReachableBasicBlock bb, SsaSourceVariable v
) {
result = getDefReachingEndOf(bb.getImmediateDominator(), v)
}
/**
* Gets an SSA definition of `v` that reaches the end of basic block `bb`.
*/
cached
SsaDefinition getDefReachingEndOf(ReachableBasicBlock bb, SsaSourceVariable v) {
exists(int lastRef | lastRef = max(int i | ssaRef(bb, i, v, _)) |
result = getLocalDefinition(bb, lastRef, v)
or
result.definesAt(bb, lastRef, v) and
liveAtSuccEntry(bb, v)
)
or
// In SSA form, the (unique) reaching definition of a use is the closest
// definition that dominates the use. If two definitions dominate a node
// then one must dominate the other, so we can find the reaching definition
// by following the idominance relation backwards.
result = getDefReachingEndOfImmediateDominator(bb, v) and
not exists(SsaDefinition ssa | ssa.definesAt(bb, _, v)) and
liveAtSuccEntry(bb, v)
}
/**
* Gets the unique SSA definition of `v` whose value reaches the `i`th node of `bb`,
* which is a use of `v`.
*/
cached
SsaDefinition getDefinition(ReachableBasicBlock bb, int i, SsaSourceVariable v) {
result = getLocalDefinition(bb, i, v)
or
rewindReads(bb, i, v) = 1 and result = getDefReachingEndOf(bb.getImmediateDominator(), v)
}
private module AdjacentUsesImpl {
/** Holds if `v` is defined or used in `b`. */
private predicate varOccursInBlock(SsaSourceVariable v, ReachableBasicBlock b) {
ssaRef(b, _, v, _)
}
/** Holds if `v` occurs in `b` or one of `b`'s transitive successors. */
private predicate blockPrecedesVar(SsaSourceVariable v, ReachableBasicBlock b) {
varOccursInBlock(v, b)
or
exists(getDefReachingEndOf(b, v))
}
/**
* Holds if the `i`th node of basic block `bb` reads source variable `v`.
* Holds if `v` occurs in `b1` and `b2` is one of `b1`'s successors.
*
* We add a synthetic uncertain read at the exit node of every function
* that references a captured variable `v`. This ensures that definitions
* of captured variables are included in the SSA graph even when the
* variable is not locally read in that function scope (but may be read
* by another function sharing the same closure).
* Factored out of `varBlockReaches` to force join order compared to the larger
* set `blockPrecedesVar(v, b2)`.
*/
cached
predicate variableRead(BasicBlock bb, int i, SourceVariable v, boolean certain) {
useAt(bb, i, v) and certain = true
pragma[noinline]
private predicate varBlockReachesBaseCand(
SsaSourceVariable v, ReachableBasicBlock b1, ReachableBasicBlock b2
) {
varOccursInBlock(v, b1) and
b2 = b1.getASuccessor(_)
}
/**
* Holds if `b2` is a transitive successor of `b1` and `v` occurs in `b1` and
* in `b2` or one of its transitive successors but not in any block on the path
* between `b1` and `b2`. Unlike `varBlockReaches` this may include blocks `b2`
* where `v` is dead.
*
* Factored out of `varBlockReaches` to force join order compared to the larger
* set `blockPrecedesVar(v, b2)`.
*/
pragma[noinline]
private predicate varBlockReachesRecCand(
SsaSourceVariable v, ReachableBasicBlock b1, ReachableBasicBlock mid, ReachableBasicBlock b2
) {
varBlockReaches(v, b1, mid) and
not varOccursInBlock(v, mid) and
b2 = mid.getASuccessor(_)
}
/**
* Holds if `b2` is a transitive successor of `b1` and `v` occurs in `b1` and
* in `b2` or one of its transitive successors but not in any block on the path
* between `b1` and `b2`.
*/
private predicate varBlockReaches(
SsaSourceVariable v, ReachableBasicBlock b1, ReachableBasicBlock b2
) {
varBlockReachesBaseCand(v, b1, b2) and
blockPrecedesVar(v, b2)
or
v.isCaptured() and
exists(FuncDef f |
f = bb.getScope() and
bb.getLastNode().isExitNode() and
i = bb.length() - 1 and
certain = false
|
// The declaring function: captures may be read after calls to closures
f = v.getDeclaringFunction()
or
// Any function that writes `v`: the write may be observed by the
// declaring function or another closure sharing the same variable
any(IR::Instruction def | def.writes(v, _)).getRoot() = f
varBlockReachesRecCand(v, b1, _, b2) and
blockPrecedesVar(v, b2)
}
/**
* Holds if `b2` is a transitive successor of `b1` and `v` occurs in `b1` and
* `b2` but not in any block on the path between `b1` and `b2`.
*/
private predicate varBlockStep(
SsaSourceVariable v, ReachableBasicBlock b1, ReachableBasicBlock b2
) {
varBlockReaches(v, b1, b2) and
varOccursInBlock(v, b2)
}
/**
* Gets the maximum rank among all SSA references to `v` in basic block `bb`.
*/
private int maxSsaRefRank(ReachableBasicBlock bb, SsaSourceVariable v) {
result = max(ssaRefRank(bb, _, v, _))
}
/**
* Holds if `v` occurs at index `i1` in `b1` and at index `i2` in `b2` and
* there is a path between them without any occurrence of `v`.
*/
pragma[nomagic]
predicate adjacentVarRefs(
SsaSourceVariable v, ReachableBasicBlock b1, int i1, ReachableBasicBlock b2, int i2
) {
exists(int rankix |
b1 = b2 and
ssaRefRank(b1, i1, v, _) = rankix and
ssaRefRank(b2, i2, v, _) = rankix + 1
)
or
maxSsaRefRank(b1, v) = ssaRefRank(b1, i1, v, _) and
varBlockStep(v, b1, b2) and
ssaRefRank(b2, i2, v, _) = 1
}
predicate variableUse(SsaSourceVariable v, IR::Instruction use, ReachableBasicBlock bb, int i) {
bb.getNode(i) = use and
exists(SsaVariable sv |
sv.getSourceVariable() = v and
use = sv.getAUse()
)
}
}
private import AdjacentUsesImpl
/**
* Holds if the value defined at `def` can reach `use` without passing through
* any other uses, but possibly through phi nodes.
*/
cached
predicate firstUse(SsaDefinition def, IR::Instruction use) {
exists(SsaSourceVariable v, ReachableBasicBlock b1, int i1, ReachableBasicBlock b2, int i2 |
adjacentVarRefs(v, b1, i1, b2, i2) and
def.definesAt(b1, i1, v) and
variableUse(v, use, b2, i2)
)
or
exists(
SsaSourceVariable v, SsaPhiNode redef, ReachableBasicBlock b1, int i1, ReachableBasicBlock b2,
int i2
|
adjacentVarRefs(v, b1, i1, b2, i2) and
def.definesAt(b1, i1, v) and
redef.definesAt(b2, i2, v) and
firstUse(redef, use)
)
}
/**
* Holds if `use1` and `use2` form an adjacent use-use-pair of the same SSA
* variable, that is, the value read in `use1` can reach `use2` without passing
* through any other use or any SSA definition of the variable.
*/
cached
predicate adjacentUseUseSameVar(IR::Instruction use1, IR::Instruction use2) {
exists(SsaSourceVariable v, ReachableBasicBlock b1, int i1, ReachableBasicBlock b2, int i2 |
adjacentVarRefs(v, b1, i1, b2, i2) and
variableUse(v, use1, b1, i1) and
variableUse(v, use2, b2, i2)
)
}
/**
* Holds if `use1` and `use2` form an adjacent use-use-pair of the same
* `SsaSourceVariable`, that is, the value read in `use1` can reach `use2`
* without passing through any other use or any SSA definition of the variable
* except for phi nodes and uncertain implicit updates.
*/
cached
predicate adjacentUseUse(IR::Instruction use1, IR::Instruction use2) {
adjacentUseUseSameVar(use1, use2)
or
exists(
SsaSourceVariable v, SsaPhiNode def, ReachableBasicBlock b1, int i1, ReachableBasicBlock b2,
int i2
|
adjacentVarRefs(v, b1, i1, b2, i2) and
variableUse(v, use1, b1, i1) and
def.definesAt(b2, i2, v) and
firstUse(def, use2)
)
}
}
import Internal
import SsaImplCommon::Make<Location, BasicBlocks::Cfg, SsaInput> as Impl
final class Definition = Impl::Definition;
final class WriteDefinition = Impl::WriteDefinition;
final class UncertainWriteDefinition = Impl::UncertainWriteDefinition;
final class PhiNode = Impl::PhiNode;
module Consistency = Impl::Consistency;
/**
* NB: This predicate should be cached.
*
* Holds if the SSA definition of `v` at `def` reaches a read at index `i` in
* basic block `bb`.
*/
cached
predicate ssaDefReachesRead(SsaSourceVariable v, Definition def, BasicBlock bb, int i) {
Impl::ssaDefReachesRead(v, def, bb, i)
}
/**
* NB: This predicate should be cached.
*
* Holds if the SSA definition of `v` at `def` reaches the end of basic block `bb`.
*/
cached
predicate ssaDefReachesEndOfBlock(BasicBlock bb, Definition def, SsaSourceVariable v) {
Impl::ssaDefReachesEndOfBlock(bb, def, v)
}
/**
* NB: This predicate should be cached.
*
* Holds if `inp` is an input to the phi node `phi` along the edge originating in `bb`.
*/
cached
predicate phiHasInputFromBlock(PhiNode phi, Definition inp, BasicBlock bb) {
Impl::phiHasInputFromBlock(phi, inp, bb)
}
/**
* NB: This predicate should be cached.
*
* Holds if `def` reaches the first use `use` without going through any other use,
* but possibly through phi nodes.
*/
cached
predicate firstUse(Definition def, IR::Instruction use) {
exists(BasicBlock bb, int i |
Impl::firstUse(def, bb, i, _) and
use = bb.getNode(i)
)
}
/**
* NB: This predicate should be cached.
*
* Holds if `use1` and `use2` form an adjacent use-use-pair of the same SSA
* variable, that is, the value read in `use1` can reach `use2` without passing
* through any other use or any SSA definition of the variable except for phi nodes
* and uncertain implicit updates.
*/
cached
predicate adjacentUseUse(IR::Instruction use1, IR::Instruction use2) {
exists(BasicBlock bb1, int i1, BasicBlock bb2, int i2 |
Impl::adjacentUseUse(bb1, i1, bb2, i2, _, _) and
use1 = bb1.getNode(i1) and
use2 = bb2.getNode(i2)
)
}

View File

@@ -923,20 +923,15 @@ module Public {
/**
* A node whose value is returned as a result from a function.
*
* If the function declares named result variables, this is a node representing
* the current value of one of those variables at function exit. Otherwise, this
* is a node corresponding to an expression in a return statement.
* This can either be a node corresponding to an expression in a return statement,
* or a node representing the current value of a named result variable at the exit
* of the function.
*/
class ResultNode extends InstructionNode {
int i;
ResultNode() {
exists(FuncDef fd |
// If the function has named result variables, then the
// `IR::ReadResultInstruction` nodes at the end of the function are
// the correct result nodes. Otherwise, the returned expressions are
// the result nodes.
not exists(fd.getAResultVar()) and
exists(IR::ReturnInstruction ret | ret.getRoot() = fd | insn = ret.getResult(i))
or
insn.(IR::ReadResultInstruction).reads(fd.getResultVar(i))

View File

@@ -55,7 +55,7 @@ class SyncFileFun extends Method {
/**
* Holds if a `call` to a function is "unhandled". That is, it is either
* deferred or used as an expression statement, so that its result is discarded.
* deferred or its result is not assigned to anything.
*
* TODO: maybe we should check that something is actually done with the result
*/
@@ -77,6 +77,7 @@ predicate isWritableFileHandle(DataFlow::Node source, DataFlow::CallNode call) {
// get the flags expression used for opening the file
call.getArgument(1) = flags and
// extract individual flags from the argument
// flag = flag.getAChild*() and
flag = getConstants(flags.asExpr()) and
// check for one which signals that the handle will be writable
// note that we are underestimating here, since the flags may be
@@ -86,18 +87,27 @@ predicate isWritableFileHandle(DataFlow::Node source, DataFlow::CallNode call) {
}
/**
* Holds if `postDominator` post-dominates `node` in the control-flow graph. That is,
* every path from `node` to the exit of the enclosing function passes through
* `postDominator`.
* Holds if `os.File.Close` is called on `sink`.
*/
pragma[inline]
predicate postDominatesNode(ControlFlow::Node postDominator, ControlFlow::Node node) {
exists(ReachableBasicBlock pdbb, ReachableBasicBlock nbb, int i, int j |
postDominator = pdbb.getNode(i) and node = nbb.getNode(j)
|
pdbb.strictlyPostDominates(nbb)
or
pdbb = nbb and i >= j
predicate isCloseSink(DataFlow::Node sink, DataFlow::CallNode closeCall) {
// find calls to the os.File.Close function
closeCall = any(CloseFileFun f).getACall() and
// that are unhandled
unhandledCall(closeCall) and
// where the function is called on the sink
closeCall.getReceiver() = sink and
// and check that it is not dominated by a call to `os.File.Sync`.
// TODO: fix this logic when `closeCall` is in a defer statement.
not exists(IR::Instruction syncInstr, DataFlow::Node syncReceiver, DataFlow::CallNode syncCall |
// match the instruction corresponding to an `os.File.Sync` call with the predecessor
syncCall.asInstruction() = syncInstr and
// check that the call to `os.File.Sync` is handled
isHandledSync(syncReceiver, syncCall) and
// find a predecessor to `closeCall` in the control flow graph which dominates the call to
// `os.File.Close`
syncInstr.dominatesNode(closeCall.asInstruction()) and
// check that `os.File.Sync` is called on the same object as `os.File.Close`
exists(DataFlow::SsaNode ssa | ssa.getAUse() = sink and ssa.getAUse() = syncReceiver)
)
}
@@ -117,39 +127,7 @@ predicate isHandledSync(DataFlow::Node sink, DataFlow::CallNode syncCall) {
module UnhandledFileCloseConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { isWritableFileHandle(source, _) }
predicate isSink(DataFlow::Node sink) {
exists(DataFlow::CallNode closeCall |
// `closeCall` is an unhandled call to `os.File.Close` on `sink`
closeCall = any(CloseFileFun f).getACall() and
unhandledCall(closeCall) and
closeCall.getReceiver() = sink
|
// `closeCall` is not guaranteed to be preceded during
// execution by a handled call to `os.File.Sync` on the same file handle.
not exists(DataFlow::Node syncReceiver, DataFlow::CallNode syncCall |
// check that the call to `os.File.Sync` is handled
isHandledSync(syncReceiver, syncCall) and
// check that `os.File.Sync` is called on the same object as `os.File.Close`
exists(DataFlow::SsaNode ssa | ssa.getAUse() = sink and ssa.getAUse() = syncReceiver)
|
if exists(DeferStmt defer | defer.getCall() = closeCall.asExpr())
then
// When the call to `os.File.Close` is deferred it runs when the enclosing function
// returns, but the receiver of the deferred call is evaluated where the `defer`
// statement appears. It is therefore enough for the handled call to `os.File.Sync`
// to post-dominate that point, since that guarantees `os.File.Sync` runs before the
// deferred `os.File.Close` on every path on which the `os.File.Close` is registered.
// We cannot reuse the domination check below because the control-flow graph splices
// the deferred call in at the function exit, where it may be reachable along paths
// that do not pass through the call to `os.File.Sync`.
postDominatesNode(syncCall.asInstruction(), sink.asInstruction())
else
// Otherwise the call to `os.File.Close` is executed where it appears, so we require
// the handled call to `os.File.Sync` to dominate it.
syncCall.asInstruction().dominatesNode(closeCall.asInstruction())
)
)
}
predicate isSink(DataFlow::Node sink) { isCloseSink(sink, _) }
predicate observeDiffInformedIncrementalMode() { any() }
@@ -170,12 +148,14 @@ import UnhandledFileCloseFlow::PathGraph
from
UnhandledFileCloseFlow::PathNode source, DataFlow::CallNode openCall,
UnhandledFileCloseFlow::PathNode sink
UnhandledFileCloseFlow::PathNode sink, DataFlow::CallNode closeCall
where
// find data flow from an `os.OpenFile` call to an `os.File.Close` call
// where the handle is writable
UnhandledFileCloseFlow::flowPath(source, sink) and
isWritableFileHandle(source.getNode(), openCall)
isWritableFileHandle(source.getNode(), openCall) and
// get the `CallNode` corresponding to the sink
isCloseSink(sink.getNode(), closeCall)
select sink, source, sink,
"File handle may be writable as a result of data flow from a $@ and closing it may result in data loss upon failure, which is not handled explicitly.",
openCall, openCall.toString()

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* The query `go/unhandled-writable-file-close` ("Writable file handle closed without error handling") now produces fewer false positives. A deferred call to `Close` that is preceded on every execution path by a handled call to `Sync` on the same file handle is no longer flagged.

View File

@@ -2,7 +2,7 @@
| file://:0:0:0:0 | [summary param] -1 in Clone |
| file://:0:0:0:0 | [summary param] -1 in Write |
| file://:0:0:0:0 | [summary param] -1 in WriteProxy |
| main.go:18:12:18:14 | SSA def(req) |
| main.go:18:12:18:14 | argument corresponding to req |
| main.go:18:12:18:14 | definition of req |
| main.go:20:5:20:7 | req |
| main.go:20:5:20:7 | req [postupdate] |

View File

@@ -47,27 +47,27 @@
| test.go:621:25:621:31 | tarRead | test.go:93:5:93:16 | selection of Body | test.go:621:25:621:31 | tarRead | This decompression is $@. | test.go:93:5:93:16 | selection of Body | decompressing compressed data without managing output size |
| test.go:629:2:629:8 | tarRead | test.go:93:5:93:16 | selection of Body | test.go:629:2:629:8 | tarRead | This decompression is $@. | test.go:93:5:93:16 | selection of Body | decompressing compressed data without managing output size |
edges
| test.go:59:16:59:44 | call to FormValue | test.go:128:20:128:27 | SSA def(filename) | provenance | Src:MaD:2 |
| test.go:60:15:60:26 | selection of Body | test.go:158:19:158:22 | SSA def(file) | provenance | Src:MaD:1 |
| test.go:61:24:61:35 | selection of Body | test.go:169:28:169:31 | SSA def(file) | provenance | Src:MaD:1 |
| test.go:62:13:62:24 | selection of Body | test.go:181:17:181:20 | SSA def(file) | provenance | Src:MaD:1 |
| test.go:64:8:64:19 | selection of Body | test.go:208:12:208:15 | SSA def(file) | provenance | Src:MaD:1 |
| test.go:66:8:66:19 | selection of Body | test.go:233:12:233:15 | SSA def(file) | provenance | Src:MaD:1 |
| test.go:68:17:68:28 | selection of Body | test.go:258:21:258:24 | SSA def(file) | provenance | Src:MaD:1 |
| test.go:70:13:70:24 | selection of Body | test.go:283:17:283:20 | SSA def(file) | provenance | Src:MaD:1 |
| test.go:72:16:72:27 | selection of Body | test.go:308:20:308:23 | SSA def(file) | provenance | Src:MaD:1 |
| test.go:74:7:74:18 | selection of Body | test.go:333:11:333:14 | SSA def(file) | provenance | Src:MaD:1 |
| test.go:76:9:76:20 | selection of Body | test.go:358:13:358:16 | SSA def(file) | provenance | Src:MaD:1 |
| test.go:78:18:78:29 | selection of Body | test.go:384:22:384:25 | SSA def(file) | provenance | Src:MaD:1 |
| test.go:80:5:80:16 | selection of Body | test.go:412:9:412:12 | SSA def(file) | provenance | Src:MaD:1 |
| test.go:82:7:82:18 | selection of Body | test.go:447:11:447:14 | SSA def(file) | provenance | Src:MaD:1 |
| test.go:84:15:84:26 | selection of Body | test.go:440:19:440:21 | SSA def(src) | provenance | Src:MaD:1 |
| test.go:85:16:85:27 | selection of Body | test.go:472:20:472:23 | SSA def(file) | provenance | Src:MaD:1 |
| test.go:87:16:87:27 | selection of Body | test.go:499:20:499:23 | SSA def(file) | provenance | Src:MaD:1 |
| test.go:89:17:89:28 | selection of Body | test.go:526:21:526:24 | SSA def(file) | provenance | Src:MaD:1 |
| test.go:91:15:91:26 | selection of Body | test.go:555:19:555:22 | SSA def(file) | provenance | Src:MaD:1 |
| test.go:93:5:93:16 | selection of Body | test.go:580:9:580:12 | SSA def(file) | provenance | Src:MaD:1 |
| test.go:128:20:128:27 | SSA def(filename) | test.go:130:33:130:40 | filename | provenance | |
| test.go:59:16:59:44 | call to FormValue | test.go:128:20:128:27 | definition of filename | provenance | Src:MaD:2 |
| test.go:60:15:60:26 | selection of Body | test.go:158:19:158:22 | definition of file | provenance | Src:MaD:1 |
| test.go:61:24:61:35 | selection of Body | test.go:169:28:169:31 | definition of file | provenance | Src:MaD:1 |
| test.go:62:13:62:24 | selection of Body | test.go:181:17:181:20 | definition of file | provenance | Src:MaD:1 |
| test.go:64:8:64:19 | selection of Body | test.go:208:12:208:15 | definition of file | provenance | Src:MaD:1 |
| test.go:66:8:66:19 | selection of Body | test.go:233:12:233:15 | definition of file | provenance | Src:MaD:1 |
| test.go:68:17:68:28 | selection of Body | test.go:258:21:258:24 | definition of file | provenance | Src:MaD:1 |
| test.go:70:13:70:24 | selection of Body | test.go:283:17:283:20 | definition of file | provenance | Src:MaD:1 |
| test.go:72:16:72:27 | selection of Body | test.go:308:20:308:23 | definition of file | provenance | Src:MaD:1 |
| test.go:74:7:74:18 | selection of Body | test.go:333:11:333:14 | definition of file | provenance | Src:MaD:1 |
| test.go:76:9:76:20 | selection of Body | test.go:358:13:358:16 | definition of file | provenance | Src:MaD:1 |
| test.go:78:18:78:29 | selection of Body | test.go:384:22:384:25 | definition of file | provenance | Src:MaD:1 |
| test.go:80:5:80:16 | selection of Body | test.go:412:9:412:12 | definition of file | provenance | Src:MaD:1 |
| test.go:82:7:82:18 | selection of Body | test.go:447:11:447:14 | definition of file | provenance | Src:MaD:1 |
| test.go:84:15:84:26 | selection of Body | test.go:440:19:440:21 | definition of src | provenance | Src:MaD:1 |
| test.go:85:16:85:27 | selection of Body | test.go:472:20:472:23 | definition of file | provenance | Src:MaD:1 |
| test.go:87:16:87:27 | selection of Body | test.go:499:20:499:23 | definition of file | provenance | Src:MaD:1 |
| test.go:89:17:89:28 | selection of Body | test.go:526:21:526:24 | definition of file | provenance | Src:MaD:1 |
| test.go:91:15:91:26 | selection of Body | test.go:555:19:555:22 | definition of file | provenance | Src:MaD:1 |
| test.go:93:5:93:16 | selection of Body | test.go:580:9:580:12 | definition of file | provenance | Src:MaD:1 |
| test.go:128:20:128:27 | definition of filename | test.go:130:33:130:40 | filename | provenance | |
| test.go:130:2:130:41 | ... := ...[0] | test.go:132:12:132:12 | f | provenance | |
| test.go:130:33:130:40 | filename | test.go:130:2:130:41 | ... := ...[0] | provenance | Config |
| test.go:130:33:130:40 | filename | test.go:143:51:143:58 | filename | provenance | |
@@ -77,7 +77,7 @@ edges
| test.go:143:51:143:58 | filename | test.go:143:2:143:59 | ... := ...[0] | provenance | Config |
| test.go:145:12:145:12 | f | test.go:145:12:145:19 | call to Open | provenance | Config |
| test.go:145:12:145:19 | call to Open | test.go:147:37:147:38 | rc | provenance | |
| test.go:158:19:158:22 | SSA def(file) | test.go:159:25:159:28 | file | provenance | |
| test.go:158:19:158:22 | definition of file | test.go:159:25:159:28 | file | provenance | |
| test.go:159:2:159:29 | ... := ...[0] | test.go:160:48:160:52 | file1 | provenance | |
| test.go:159:25:159:28 | file | test.go:159:2:159:29 | ... := ...[0] | provenance | MaD:6 |
| test.go:160:2:160:69 | ... := ...[0] | test.go:163:26:163:29 | file | provenance | |
@@ -85,7 +85,7 @@ edges
| test.go:160:48:160:52 | file1 | test.go:160:32:160:53 | call to NewReader | provenance | MaD:5 |
| test.go:163:3:163:36 | ... := ...[0] | test.go:164:36:164:51 | fileReaderCloser | provenance | |
| test.go:163:26:163:29 | file | test.go:163:3:163:36 | ... := ...[0] | provenance | MaD:4 |
| test.go:169:28:169:31 | SSA def(file) | test.go:170:25:170:28 | file | provenance | |
| test.go:169:28:169:31 | definition of file | test.go:170:25:170:28 | file | provenance | |
| test.go:170:2:170:29 | ... := ...[0] | test.go:171:57:171:61 | file2 | provenance | |
| test.go:170:25:170:28 | file | test.go:170:2:170:29 | ... := ...[0] | provenance | MaD:6 |
| test.go:171:2:171:78 | ... := ...[0] | test.go:175:26:175:29 | file | provenance | |
@@ -93,64 +93,64 @@ edges
| test.go:171:57:171:61 | file2 | test.go:171:41:171:62 | call to NewReader | provenance | MaD:5 |
| test.go:175:26:175:29 | file | test.go:175:26:175:36 | call to Open | provenance | Config |
| test.go:175:26:175:36 | call to Open | test.go:176:36:176:51 | fileReaderCloser | provenance | |
| test.go:181:17:181:20 | SSA def(file) | test.go:184:41:184:44 | file | provenance | |
| test.go:181:17:181:20 | definition of file | test.go:184:41:184:44 | file | provenance | |
| test.go:184:2:184:73 | ... := ...[0] | test.go:186:2:186:12 | bzip2Reader | provenance | |
| test.go:184:2:184:73 | ... := ...[0] | test.go:187:26:187:36 | bzip2Reader | provenance | |
| test.go:184:41:184:44 | file | test.go:184:2:184:73 | ... := ...[0] | provenance | Config |
| test.go:187:12:187:37 | call to NewReader | test.go:189:18:189:24 | tarRead | provenance | |
| test.go:187:26:187:36 | bzip2Reader | test.go:187:12:187:37 | call to NewReader | provenance | MaD:3 |
| test.go:189:18:189:24 | tarRead | test.go:611:22:611:28 | SSA def(tarRead) | provenance | |
| test.go:208:12:208:15 | SSA def(file) | test.go:211:33:211:36 | file | provenance | |
| test.go:189:18:189:24 | tarRead | test.go:611:22:611:28 | definition of tarRead | provenance | |
| test.go:208:12:208:15 | definition of file | test.go:211:33:211:36 | file | provenance | |
| test.go:211:17:211:37 | call to NewReader | test.go:213:2:213:12 | bzip2Reader | provenance | |
| test.go:211:17:211:37 | call to NewReader | test.go:214:26:214:36 | bzip2Reader | provenance | |
| test.go:211:33:211:36 | file | test.go:211:17:211:37 | call to NewReader | provenance | Config |
| test.go:214:12:214:37 | call to NewReader | test.go:216:18:216:24 | tarRead | provenance | |
| test.go:214:26:214:36 | bzip2Reader | test.go:214:12:214:37 | call to NewReader | provenance | MaD:3 |
| test.go:216:18:216:24 | tarRead | test.go:611:22:611:28 | SSA def(tarRead) | provenance | |
| test.go:233:12:233:15 | SSA def(file) | test.go:236:33:236:36 | file | provenance | |
| test.go:216:18:216:24 | tarRead | test.go:611:22:611:28 | definition of tarRead | provenance | |
| test.go:233:12:233:15 | definition of file | test.go:236:33:236:36 | file | provenance | |
| test.go:236:17:236:37 | call to NewReader | test.go:238:2:238:12 | flateReader | provenance | |
| test.go:236:17:236:37 | call to NewReader | test.go:239:26:239:36 | flateReader | provenance | |
| test.go:236:33:236:36 | file | test.go:236:17:236:37 | call to NewReader | provenance | Config |
| test.go:239:12:239:37 | call to NewReader | test.go:241:18:241:24 | tarRead | provenance | |
| test.go:239:26:239:36 | flateReader | test.go:239:12:239:37 | call to NewReader | provenance | MaD:3 |
| test.go:241:18:241:24 | tarRead | test.go:611:22:611:28 | SSA def(tarRead) | provenance | |
| test.go:258:21:258:24 | SSA def(file) | test.go:261:42:261:45 | file | provenance | |
| test.go:241:18:241:24 | tarRead | test.go:611:22:611:28 | definition of tarRead | provenance | |
| test.go:258:21:258:24 | definition of file | test.go:261:42:261:45 | file | provenance | |
| test.go:261:17:261:46 | call to NewReader | test.go:263:2:263:12 | flateReader | provenance | |
| test.go:261:17:261:46 | call to NewReader | test.go:264:26:264:36 | flateReader | provenance | |
| test.go:261:42:261:45 | file | test.go:261:17:261:46 | call to NewReader | provenance | Config |
| test.go:264:12:264:37 | call to NewReader | test.go:266:18:266:24 | tarRead | provenance | |
| test.go:264:26:264:36 | flateReader | test.go:264:12:264:37 | call to NewReader | provenance | MaD:3 |
| test.go:266:18:266:24 | tarRead | test.go:611:22:611:28 | SSA def(tarRead) | provenance | |
| test.go:283:17:283:20 | SSA def(file) | test.go:286:41:286:44 | file | provenance | |
| test.go:266:18:266:24 | tarRead | test.go:611:22:611:28 | definition of tarRead | provenance | |
| test.go:283:17:283:20 | definition of file | test.go:286:41:286:44 | file | provenance | |
| test.go:286:2:286:73 | ... := ...[0] | test.go:288:2:288:12 | flateReader | provenance | |
| test.go:286:2:286:73 | ... := ...[0] | test.go:289:26:289:36 | flateReader | provenance | |
| test.go:286:41:286:44 | file | test.go:286:2:286:73 | ... := ...[0] | provenance | Config |
| test.go:289:12:289:37 | call to NewReader | test.go:291:18:291:24 | tarRead | provenance | |
| test.go:289:26:289:36 | flateReader | test.go:289:12:289:37 | call to NewReader | provenance | MaD:3 |
| test.go:291:18:291:24 | tarRead | test.go:611:22:611:28 | SSA def(tarRead) | provenance | |
| test.go:308:20:308:23 | SSA def(file) | test.go:311:43:311:46 | file | provenance | |
| test.go:291:18:291:24 | tarRead | test.go:611:22:611:28 | definition of tarRead | provenance | |
| test.go:308:20:308:23 | definition of file | test.go:311:43:311:46 | file | provenance | |
| test.go:311:2:311:47 | ... := ...[0] | test.go:313:2:313:11 | zlibReader | provenance | |
| test.go:311:2:311:47 | ... := ...[0] | test.go:314:26:314:35 | zlibReader | provenance | |
| test.go:311:43:311:46 | file | test.go:311:2:311:47 | ... := ...[0] | provenance | Config |
| test.go:314:12:314:36 | call to NewReader | test.go:316:18:316:24 | tarRead | provenance | |
| test.go:314:26:314:35 | zlibReader | test.go:314:12:314:36 | call to NewReader | provenance | MaD:3 |
| test.go:316:18:316:24 | tarRead | test.go:611:22:611:28 | SSA def(tarRead) | provenance | |
| test.go:333:11:333:14 | SSA def(file) | test.go:336:34:336:37 | file | provenance | |
| test.go:316:18:316:24 | tarRead | test.go:611:22:611:28 | definition of tarRead | provenance | |
| test.go:333:11:333:14 | definition of file | test.go:336:34:336:37 | file | provenance | |
| test.go:336:2:336:38 | ... := ...[0] | test.go:338:2:338:11 | zlibReader | provenance | |
| test.go:336:2:336:38 | ... := ...[0] | test.go:339:26:339:35 | zlibReader | provenance | |
| test.go:336:34:336:37 | file | test.go:336:2:336:38 | ... := ...[0] | provenance | Config |
| test.go:339:12:339:36 | call to NewReader | test.go:341:18:341:24 | tarRead | provenance | |
| test.go:339:26:339:35 | zlibReader | test.go:339:12:339:36 | call to NewReader | provenance | MaD:3 |
| test.go:341:18:341:24 | tarRead | test.go:611:22:611:28 | SSA def(tarRead) | provenance | |
| test.go:358:13:358:16 | SSA def(file) | test.go:361:35:361:38 | file | provenance | |
| test.go:341:18:341:24 | tarRead | test.go:611:22:611:28 | definition of tarRead | provenance | |
| test.go:358:13:358:16 | definition of file | test.go:361:35:361:38 | file | provenance | |
| test.go:361:18:361:39 | call to NewReader | test.go:363:2:363:13 | snappyReader | provenance | |
| test.go:361:18:361:39 | call to NewReader | test.go:364:2:364:13 | snappyReader | provenance | |
| test.go:361:18:361:39 | call to NewReader | test.go:365:26:365:37 | snappyReader | provenance | |
| test.go:361:35:361:38 | file | test.go:361:18:361:39 | call to NewReader | provenance | Config |
| test.go:365:12:365:38 | call to NewReader | test.go:367:18:367:24 | tarRead | provenance | |
| test.go:365:26:365:37 | snappyReader | test.go:365:12:365:38 | call to NewReader | provenance | MaD:3 |
| test.go:367:18:367:24 | tarRead | test.go:611:22:611:28 | SSA def(tarRead) | provenance | |
| test.go:384:22:384:25 | SSA def(file) | test.go:387:44:387:47 | file | provenance | |
| test.go:367:18:367:24 | tarRead | test.go:611:22:611:28 | definition of tarRead | provenance | |
| test.go:384:22:384:25 | definition of file | test.go:387:44:387:47 | file | provenance | |
| test.go:387:18:387:48 | call to NewReader | test.go:389:2:389:13 | snappyReader | provenance | |
| test.go:387:18:387:48 | call to NewReader | test.go:391:2:391:13 | snappyReader | provenance | |
| test.go:387:18:387:48 | call to NewReader | test.go:392:2:392:13 | snappyReader | provenance | |
@@ -158,8 +158,8 @@ edges
| test.go:387:44:387:47 | file | test.go:387:18:387:48 | call to NewReader | provenance | Config |
| test.go:393:12:393:38 | call to NewReader | test.go:395:18:395:24 | tarRead | provenance | |
| test.go:393:26:393:37 | snappyReader | test.go:393:12:393:38 | call to NewReader | provenance | MaD:3 |
| test.go:395:18:395:24 | tarRead | test.go:611:22:611:28 | SSA def(tarRead) | provenance | |
| test.go:412:9:412:12 | SSA def(file) | test.go:415:27:415:30 | file | provenance | |
| test.go:395:18:395:24 | tarRead | test.go:611:22:611:28 | definition of tarRead | provenance | |
| test.go:412:9:412:12 | definition of file | test.go:415:27:415:30 | file | provenance | |
| test.go:415:14:415:31 | call to NewReader | test.go:417:2:417:9 | s2Reader | provenance | |
| test.go:415:14:415:31 | call to NewReader | test.go:418:2:418:9 | s2Reader | provenance | |
| test.go:415:14:415:31 | call to NewReader | test.go:420:2:420:9 | s2Reader | provenance | |
@@ -167,35 +167,35 @@ edges
| test.go:415:27:415:30 | file | test.go:415:14:415:31 | call to NewReader | provenance | Config |
| test.go:421:12:421:34 | call to NewReader | test.go:423:18:423:24 | tarRead | provenance | |
| test.go:421:26:421:33 | s2Reader | test.go:421:12:421:34 | call to NewReader | provenance | MaD:3 |
| test.go:423:18:423:24 | tarRead | test.go:611:22:611:28 | SSA def(tarRead) | provenance | |
| test.go:440:19:440:21 | SSA def(src) | test.go:441:34:441:36 | src | provenance | |
| test.go:423:18:423:24 | tarRead | test.go:611:22:611:28 | definition of tarRead | provenance | |
| test.go:440:19:440:21 | definition of src | test.go:441:34:441:36 | src | provenance | |
| test.go:441:2:441:37 | ... := ...[0] | test.go:444:12:444:32 | type conversion | provenance | |
| test.go:441:34:441:36 | src | test.go:441:2:441:37 | ... := ...[0] | provenance | Config |
| test.go:444:12:444:32 | type conversion | test.go:445:23:445:28 | newSrc | provenance | |
| test.go:447:11:447:14 | SSA def(file) | test.go:450:34:450:37 | file | provenance | |
| test.go:447:11:447:14 | definition of file | test.go:450:34:450:37 | file | provenance | |
| test.go:450:2:450:38 | ... := ...[0] | test.go:452:2:452:11 | gzipReader | provenance | |
| test.go:450:2:450:38 | ... := ...[0] | test.go:453:26:453:35 | gzipReader | provenance | |
| test.go:450:34:450:37 | file | test.go:450:2:450:38 | ... := ...[0] | provenance | Config |
| test.go:453:12:453:36 | call to NewReader | test.go:455:18:455:24 | tarRead | provenance | |
| test.go:453:26:453:35 | gzipReader | test.go:453:12:453:36 | call to NewReader | provenance | MaD:3 |
| test.go:455:18:455:24 | tarRead | test.go:611:22:611:28 | SSA def(tarRead) | provenance | |
| test.go:472:20:472:23 | SSA def(file) | test.go:475:43:475:46 | file | provenance | |
| test.go:455:18:455:24 | tarRead | test.go:611:22:611:28 | definition of tarRead | provenance | |
| test.go:472:20:472:23 | definition of file | test.go:475:43:475:46 | file | provenance | |
| test.go:475:2:475:47 | ... := ...[0] | test.go:477:2:477:11 | gzipReader | provenance | |
| test.go:475:2:475:47 | ... := ...[0] | test.go:479:2:479:11 | gzipReader | provenance | |
| test.go:475:2:475:47 | ... := ...[0] | test.go:480:26:480:35 | gzipReader | provenance | |
| test.go:475:43:475:46 | file | test.go:475:2:475:47 | ... := ...[0] | provenance | Config |
| test.go:480:12:480:36 | call to NewReader | test.go:482:18:482:24 | tarRead | provenance | |
| test.go:480:26:480:35 | gzipReader | test.go:480:12:480:36 | call to NewReader | provenance | MaD:3 |
| test.go:482:18:482:24 | tarRead | test.go:611:22:611:28 | SSA def(tarRead) | provenance | |
| test.go:499:20:499:23 | SSA def(file) | test.go:502:45:502:48 | file | provenance | |
| test.go:482:18:482:24 | tarRead | test.go:611:22:611:28 | definition of tarRead | provenance | |
| test.go:499:20:499:23 | definition of file | test.go:502:45:502:48 | file | provenance | |
| test.go:502:2:502:49 | ... := ...[0] | test.go:504:2:504:12 | pgzipReader | provenance | |
| test.go:502:2:502:49 | ... := ...[0] | test.go:506:2:506:12 | pgzipReader | provenance | |
| test.go:502:2:502:49 | ... := ...[0] | test.go:507:26:507:36 | pgzipReader | provenance | |
| test.go:502:45:502:48 | file | test.go:502:2:502:49 | ... := ...[0] | provenance | Config |
| test.go:507:12:507:37 | call to NewReader | test.go:509:18:509:24 | tarRead | provenance | |
| test.go:507:26:507:36 | pgzipReader | test.go:507:12:507:37 | call to NewReader | provenance | MaD:3 |
| test.go:509:18:509:24 | tarRead | test.go:611:22:611:28 | SSA def(tarRead) | provenance | |
| test.go:526:21:526:24 | SSA def(file) | test.go:529:43:529:46 | file | provenance | |
| test.go:509:18:509:24 | tarRead | test.go:611:22:611:28 | definition of tarRead | provenance | |
| test.go:526:21:526:24 | definition of file | test.go:529:43:529:46 | file | provenance | |
| test.go:529:2:529:47 | ... := ...[0] | test.go:531:2:531:11 | zstdReader | provenance | |
| test.go:529:2:529:47 | ... := ...[0] | test.go:533:2:533:11 | zstdReader | provenance | |
| test.go:529:2:529:47 | ... := ...[0] | test.go:535:2:535:11 | zstdReader | provenance | |
@@ -203,33 +203,33 @@ edges
| test.go:529:43:529:46 | file | test.go:529:2:529:47 | ... := ...[0] | provenance | Config |
| test.go:536:12:536:36 | call to NewReader | test.go:538:18:538:24 | tarRead | provenance | |
| test.go:536:26:536:35 | zstdReader | test.go:536:12:536:36 | call to NewReader | provenance | MaD:3 |
| test.go:538:18:538:24 | tarRead | test.go:611:22:611:28 | SSA def(tarRead) | provenance | |
| test.go:555:19:555:22 | SSA def(file) | test.go:558:38:558:41 | file | provenance | |
| test.go:538:18:538:24 | tarRead | test.go:611:22:611:28 | definition of tarRead | provenance | |
| test.go:555:19:555:22 | definition of file | test.go:558:38:558:41 | file | provenance | |
| test.go:558:16:558:42 | call to NewReader | test.go:560:2:560:11 | zstdReader | provenance | |
| test.go:558:16:558:42 | call to NewReader | test.go:561:26:561:35 | zstdReader | provenance | |
| test.go:558:38:558:41 | file | test.go:558:16:558:42 | call to NewReader | provenance | Config |
| test.go:561:12:561:36 | call to NewReader | test.go:563:18:563:24 | tarRead | provenance | |
| test.go:561:26:561:35 | zstdReader | test.go:561:12:561:36 | call to NewReader | provenance | MaD:3 |
| test.go:563:18:563:24 | tarRead | test.go:611:22:611:28 | SSA def(tarRead) | provenance | |
| test.go:580:9:580:12 | SSA def(file) | test.go:583:30:583:33 | file | provenance | |
| test.go:563:18:563:24 | tarRead | test.go:611:22:611:28 | definition of tarRead | provenance | |
| test.go:580:9:580:12 | definition of file | test.go:583:30:583:33 | file | provenance | |
| test.go:583:2:583:34 | ... := ...[0] | test.go:585:2:585:9 | xzReader | provenance | |
| test.go:583:2:583:34 | ... := ...[0] | test.go:586:26:586:33 | xzReader | provenance | |
| test.go:583:30:583:33 | file | test.go:583:2:583:34 | ... := ...[0] | provenance | Config |
| test.go:586:12:586:34 | call to NewReader | test.go:589:18:589:24 | tarRead | provenance | |
| test.go:586:12:586:34 | call to NewReader | test.go:590:19:590:25 | tarRead | provenance | |
| test.go:586:26:586:33 | xzReader | test.go:586:12:586:34 | call to NewReader | provenance | MaD:3 |
| test.go:589:18:589:24 | tarRead | test.go:611:22:611:28 | SSA def(tarRead) | provenance | |
| test.go:590:19:590:25 | tarRead | test.go:627:23:627:29 | SSA def(tarRead) | provenance | |
| test.go:611:22:611:28 | SSA def(tarRead) | test.go:621:25:621:31 | tarRead | provenance | |
| test.go:611:22:611:28 | SSA def(tarRead) | test.go:621:25:621:31 | tarRead | provenance | |
| test.go:611:22:611:28 | SSA def(tarRead) | test.go:621:25:621:31 | tarRead | provenance | |
| test.go:611:22:611:28 | SSA def(tarRead) | test.go:621:25:621:31 | tarRead | provenance | |
| test.go:611:22:611:28 | SSA def(tarRead) | test.go:621:25:621:31 | tarRead | provenance | |
| test.go:611:22:611:28 | SSA def(tarRead) | test.go:621:25:621:31 | tarRead | provenance | |
| test.go:611:22:611:28 | SSA def(tarRead) | test.go:621:25:621:31 | tarRead | provenance | |
| test.go:611:22:611:28 | SSA def(tarRead) | test.go:621:25:621:31 | tarRead | provenance | |
| test.go:611:22:611:28 | SSA def(tarRead) | test.go:621:25:621:31 | tarRead | provenance | |
| test.go:627:23:627:29 | SSA def(tarRead) | test.go:629:2:629:8 | tarRead | provenance | |
| test.go:589:18:589:24 | tarRead | test.go:611:22:611:28 | definition of tarRead | provenance | |
| test.go:590:19:590:25 | tarRead | test.go:627:23:627:29 | definition of tarRead | provenance | |
| test.go:611:22:611:28 | definition of tarRead | test.go:621:25:621:31 | tarRead | provenance | |
| test.go:611:22:611:28 | definition of tarRead | test.go:621:25:621:31 | tarRead | provenance | |
| test.go:611:22:611:28 | definition of tarRead | test.go:621:25:621:31 | tarRead | provenance | |
| test.go:611:22:611:28 | definition of tarRead | test.go:621:25:621:31 | tarRead | provenance | |
| test.go:611:22:611:28 | definition of tarRead | test.go:621:25:621:31 | tarRead | provenance | |
| test.go:611:22:611:28 | definition of tarRead | test.go:621:25:621:31 | tarRead | provenance | |
| test.go:611:22:611:28 | definition of tarRead | test.go:621:25:621:31 | tarRead | provenance | |
| test.go:611:22:611:28 | definition of tarRead | test.go:621:25:621:31 | tarRead | provenance | |
| test.go:611:22:611:28 | definition of tarRead | test.go:621:25:621:31 | tarRead | provenance | |
| test.go:627:23:627:29 | definition of tarRead | test.go:629:2:629:8 | tarRead | provenance | |
models
| 1 | Source: net/http; Request; true; Body; ; ; ; remote; manual |
| 2 | Source: net/http; Request; true; FormValue; ; ; ReturnValue; remote; manual |
@@ -258,7 +258,7 @@ nodes
| test.go:89:17:89:28 | selection of Body | semmle.label | selection of Body |
| test.go:91:15:91:26 | selection of Body | semmle.label | selection of Body |
| test.go:93:5:93:16 | selection of Body | semmle.label | selection of Body |
| test.go:128:20:128:27 | SSA def(filename) | semmle.label | SSA def(filename) |
| test.go:128:20:128:27 | definition of filename | semmle.label | definition of filename |
| test.go:130:2:130:41 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:130:33:130:40 | filename | semmle.label | filename |
| test.go:132:3:132:19 | ... := ...[0] | semmle.label | ... := ...[0] |
@@ -269,7 +269,7 @@ nodes
| test.go:145:12:145:12 | f | semmle.label | f |
| test.go:145:12:145:19 | call to Open | semmle.label | call to Open |
| test.go:147:37:147:38 | rc | semmle.label | rc |
| test.go:158:19:158:22 | SSA def(file) | semmle.label | SSA def(file) |
| test.go:158:19:158:22 | definition of file | semmle.label | definition of file |
| test.go:159:2:159:29 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:159:25:159:28 | file | semmle.label | file |
| test.go:160:2:160:69 | ... := ...[0] | semmle.label | ... := ...[0] |
@@ -278,7 +278,7 @@ nodes
| test.go:163:3:163:36 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:163:26:163:29 | file | semmle.label | file |
| test.go:164:36:164:51 | fileReaderCloser | semmle.label | fileReaderCloser |
| test.go:169:28:169:31 | SSA def(file) | semmle.label | SSA def(file) |
| test.go:169:28:169:31 | definition of file | semmle.label | definition of file |
| test.go:170:2:170:29 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:170:25:170:28 | file | semmle.label | file |
| test.go:171:2:171:78 | ... := ...[0] | semmle.label | ... := ...[0] |
@@ -287,56 +287,56 @@ nodes
| test.go:175:26:175:29 | file | semmle.label | file |
| test.go:175:26:175:36 | call to Open | semmle.label | call to Open |
| test.go:176:36:176:51 | fileReaderCloser | semmle.label | fileReaderCloser |
| test.go:181:17:181:20 | SSA def(file) | semmle.label | SSA def(file) |
| test.go:181:17:181:20 | definition of file | semmle.label | definition of file |
| test.go:184:2:184:73 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:184:41:184:44 | file | semmle.label | file |
| test.go:186:2:186:12 | bzip2Reader | semmle.label | bzip2Reader |
| test.go:187:12:187:37 | call to NewReader | semmle.label | call to NewReader |
| test.go:187:26:187:36 | bzip2Reader | semmle.label | bzip2Reader |
| test.go:189:18:189:24 | tarRead | semmle.label | tarRead |
| test.go:208:12:208:15 | SSA def(file) | semmle.label | SSA def(file) |
| test.go:208:12:208:15 | definition of file | semmle.label | definition of file |
| test.go:211:17:211:37 | call to NewReader | semmle.label | call to NewReader |
| test.go:211:33:211:36 | file | semmle.label | file |
| test.go:213:2:213:12 | bzip2Reader | semmle.label | bzip2Reader |
| test.go:214:12:214:37 | call to NewReader | semmle.label | call to NewReader |
| test.go:214:26:214:36 | bzip2Reader | semmle.label | bzip2Reader |
| test.go:216:18:216:24 | tarRead | semmle.label | tarRead |
| test.go:233:12:233:15 | SSA def(file) | semmle.label | SSA def(file) |
| test.go:233:12:233:15 | definition of file | semmle.label | definition of file |
| test.go:236:17:236:37 | call to NewReader | semmle.label | call to NewReader |
| test.go:236:33:236:36 | file | semmle.label | file |
| test.go:238:2:238:12 | flateReader | semmle.label | flateReader |
| test.go:239:12:239:37 | call to NewReader | semmle.label | call to NewReader |
| test.go:239:26:239:36 | flateReader | semmle.label | flateReader |
| test.go:241:18:241:24 | tarRead | semmle.label | tarRead |
| test.go:258:21:258:24 | SSA def(file) | semmle.label | SSA def(file) |
| test.go:258:21:258:24 | definition of file | semmle.label | definition of file |
| test.go:261:17:261:46 | call to NewReader | semmle.label | call to NewReader |
| test.go:261:42:261:45 | file | semmle.label | file |
| test.go:263:2:263:12 | flateReader | semmle.label | flateReader |
| test.go:264:12:264:37 | call to NewReader | semmle.label | call to NewReader |
| test.go:264:26:264:36 | flateReader | semmle.label | flateReader |
| test.go:266:18:266:24 | tarRead | semmle.label | tarRead |
| test.go:283:17:283:20 | SSA def(file) | semmle.label | SSA def(file) |
| test.go:283:17:283:20 | definition of file | semmle.label | definition of file |
| test.go:286:2:286:73 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:286:41:286:44 | file | semmle.label | file |
| test.go:288:2:288:12 | flateReader | semmle.label | flateReader |
| test.go:289:12:289:37 | call to NewReader | semmle.label | call to NewReader |
| test.go:289:26:289:36 | flateReader | semmle.label | flateReader |
| test.go:291:18:291:24 | tarRead | semmle.label | tarRead |
| test.go:308:20:308:23 | SSA def(file) | semmle.label | SSA def(file) |
| test.go:308:20:308:23 | definition of file | semmle.label | definition of file |
| test.go:311:2:311:47 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:311:43:311:46 | file | semmle.label | file |
| test.go:313:2:313:11 | zlibReader | semmle.label | zlibReader |
| test.go:314:12:314:36 | call to NewReader | semmle.label | call to NewReader |
| test.go:314:26:314:35 | zlibReader | semmle.label | zlibReader |
| test.go:316:18:316:24 | tarRead | semmle.label | tarRead |
| test.go:333:11:333:14 | SSA def(file) | semmle.label | SSA def(file) |
| test.go:333:11:333:14 | definition of file | semmle.label | definition of file |
| test.go:336:2:336:38 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:336:34:336:37 | file | semmle.label | file |
| test.go:338:2:338:11 | zlibReader | semmle.label | zlibReader |
| test.go:339:12:339:36 | call to NewReader | semmle.label | call to NewReader |
| test.go:339:26:339:35 | zlibReader | semmle.label | zlibReader |
| test.go:341:18:341:24 | tarRead | semmle.label | tarRead |
| test.go:358:13:358:16 | SSA def(file) | semmle.label | SSA def(file) |
| test.go:358:13:358:16 | definition of file | semmle.label | definition of file |
| test.go:361:18:361:39 | call to NewReader | semmle.label | call to NewReader |
| test.go:361:35:361:38 | file | semmle.label | file |
| test.go:363:2:363:13 | snappyReader | semmle.label | snappyReader |
@@ -344,7 +344,7 @@ nodes
| test.go:365:12:365:38 | call to NewReader | semmle.label | call to NewReader |
| test.go:365:26:365:37 | snappyReader | semmle.label | snappyReader |
| test.go:367:18:367:24 | tarRead | semmle.label | tarRead |
| test.go:384:22:384:25 | SSA def(file) | semmle.label | SSA def(file) |
| test.go:384:22:384:25 | definition of file | semmle.label | definition of file |
| test.go:387:18:387:48 | call to NewReader | semmle.label | call to NewReader |
| test.go:387:44:387:47 | file | semmle.label | file |
| test.go:389:2:389:13 | snappyReader | semmle.label | snappyReader |
@@ -353,7 +353,7 @@ nodes
| test.go:393:12:393:38 | call to NewReader | semmle.label | call to NewReader |
| test.go:393:26:393:37 | snappyReader | semmle.label | snappyReader |
| test.go:395:18:395:24 | tarRead | semmle.label | tarRead |
| test.go:412:9:412:12 | SSA def(file) | semmle.label | SSA def(file) |
| test.go:412:9:412:12 | definition of file | semmle.label | definition of file |
| test.go:415:14:415:31 | call to NewReader | semmle.label | call to NewReader |
| test.go:415:27:415:30 | file | semmle.label | file |
| test.go:417:2:417:9 | s2Reader | semmle.label | s2Reader |
@@ -362,19 +362,19 @@ nodes
| test.go:421:12:421:34 | call to NewReader | semmle.label | call to NewReader |
| test.go:421:26:421:33 | s2Reader | semmle.label | s2Reader |
| test.go:423:18:423:24 | tarRead | semmle.label | tarRead |
| test.go:440:19:440:21 | SSA def(src) | semmle.label | SSA def(src) |
| test.go:440:19:440:21 | definition of src | semmle.label | definition of src |
| test.go:441:2:441:37 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:441:34:441:36 | src | semmle.label | src |
| test.go:444:12:444:32 | type conversion | semmle.label | type conversion |
| test.go:445:23:445:28 | newSrc | semmle.label | newSrc |
| test.go:447:11:447:14 | SSA def(file) | semmle.label | SSA def(file) |
| test.go:447:11:447:14 | definition of file | semmle.label | definition of file |
| test.go:450:2:450:38 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:450:34:450:37 | file | semmle.label | file |
| test.go:452:2:452:11 | gzipReader | semmle.label | gzipReader |
| test.go:453:12:453:36 | call to NewReader | semmle.label | call to NewReader |
| test.go:453:26:453:35 | gzipReader | semmle.label | gzipReader |
| test.go:455:18:455:24 | tarRead | semmle.label | tarRead |
| test.go:472:20:472:23 | SSA def(file) | semmle.label | SSA def(file) |
| test.go:472:20:472:23 | definition of file | semmle.label | definition of file |
| test.go:475:2:475:47 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:475:43:475:46 | file | semmle.label | file |
| test.go:477:2:477:11 | gzipReader | semmle.label | gzipReader |
@@ -382,7 +382,7 @@ nodes
| test.go:480:12:480:36 | call to NewReader | semmle.label | call to NewReader |
| test.go:480:26:480:35 | gzipReader | semmle.label | gzipReader |
| test.go:482:18:482:24 | tarRead | semmle.label | tarRead |
| test.go:499:20:499:23 | SSA def(file) | semmle.label | SSA def(file) |
| test.go:499:20:499:23 | definition of file | semmle.label | definition of file |
| test.go:502:2:502:49 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:502:45:502:48 | file | semmle.label | file |
| test.go:504:2:504:12 | pgzipReader | semmle.label | pgzipReader |
@@ -390,7 +390,7 @@ nodes
| test.go:507:12:507:37 | call to NewReader | semmle.label | call to NewReader |
| test.go:507:26:507:36 | pgzipReader | semmle.label | pgzipReader |
| test.go:509:18:509:24 | tarRead | semmle.label | tarRead |
| test.go:526:21:526:24 | SSA def(file) | semmle.label | SSA def(file) |
| test.go:526:21:526:24 | definition of file | semmle.label | definition of file |
| test.go:529:2:529:47 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:529:43:529:46 | file | semmle.label | file |
| test.go:531:2:531:11 | zstdReader | semmle.label | zstdReader |
@@ -399,14 +399,14 @@ nodes
| test.go:536:12:536:36 | call to NewReader | semmle.label | call to NewReader |
| test.go:536:26:536:35 | zstdReader | semmle.label | zstdReader |
| test.go:538:18:538:24 | tarRead | semmle.label | tarRead |
| test.go:555:19:555:22 | SSA def(file) | semmle.label | SSA def(file) |
| test.go:555:19:555:22 | definition of file | semmle.label | definition of file |
| test.go:558:16:558:42 | call to NewReader | semmle.label | call to NewReader |
| test.go:558:38:558:41 | file | semmle.label | file |
| test.go:560:2:560:11 | zstdReader | semmle.label | zstdReader |
| test.go:561:12:561:36 | call to NewReader | semmle.label | call to NewReader |
| test.go:561:26:561:35 | zstdReader | semmle.label | zstdReader |
| test.go:563:18:563:24 | tarRead | semmle.label | tarRead |
| test.go:580:9:580:12 | SSA def(file) | semmle.label | SSA def(file) |
| test.go:580:9:580:12 | definition of file | semmle.label | definition of file |
| test.go:583:2:583:34 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:583:30:583:33 | file | semmle.label | file |
| test.go:585:2:585:9 | xzReader | semmle.label | xzReader |
@@ -414,15 +414,15 @@ nodes
| test.go:586:26:586:33 | xzReader | semmle.label | xzReader |
| test.go:589:18:589:24 | tarRead | semmle.label | tarRead |
| test.go:590:19:590:25 | tarRead | semmle.label | tarRead |
| test.go:611:22:611:28 | SSA def(tarRead) | semmle.label | SSA def(tarRead) |
| test.go:611:22:611:28 | SSA def(tarRead) | semmle.label | SSA def(tarRead) |
| test.go:611:22:611:28 | SSA def(tarRead) | semmle.label | SSA def(tarRead) |
| test.go:611:22:611:28 | SSA def(tarRead) | semmle.label | SSA def(tarRead) |
| test.go:611:22:611:28 | SSA def(tarRead) | semmle.label | SSA def(tarRead) |
| test.go:611:22:611:28 | SSA def(tarRead) | semmle.label | SSA def(tarRead) |
| test.go:611:22:611:28 | SSA def(tarRead) | semmle.label | SSA def(tarRead) |
| test.go:611:22:611:28 | SSA def(tarRead) | semmle.label | SSA def(tarRead) |
| test.go:611:22:611:28 | SSA def(tarRead) | semmle.label | SSA def(tarRead) |
| test.go:611:22:611:28 | definition of tarRead | semmle.label | definition of tarRead |
| test.go:611:22:611:28 | definition of tarRead | semmle.label | definition of tarRead |
| test.go:611:22:611:28 | definition of tarRead | semmle.label | definition of tarRead |
| test.go:611:22:611:28 | definition of tarRead | semmle.label | definition of tarRead |
| test.go:611:22:611:28 | definition of tarRead | semmle.label | definition of tarRead |
| test.go:611:22:611:28 | definition of tarRead | semmle.label | definition of tarRead |
| test.go:611:22:611:28 | definition of tarRead | semmle.label | definition of tarRead |
| test.go:611:22:611:28 | definition of tarRead | semmle.label | definition of tarRead |
| test.go:611:22:611:28 | definition of tarRead | semmle.label | definition of tarRead |
| test.go:621:25:621:31 | tarRead | semmle.label | tarRead |
| test.go:621:25:621:31 | tarRead | semmle.label | tarRead |
| test.go:621:25:621:31 | tarRead | semmle.label | tarRead |
@@ -432,6 +432,6 @@ nodes
| test.go:621:25:621:31 | tarRead | semmle.label | tarRead |
| test.go:621:25:621:31 | tarRead | semmle.label | tarRead |
| test.go:621:25:621:31 | tarRead | semmle.label | tarRead |
| test.go:627:23:627:29 | SSA def(tarRead) | semmle.label | SSA def(tarRead) |
| test.go:627:23:627:29 | definition of tarRead | semmle.label | definition of tarRead |
| test.go:629:2:629:8 | tarRead | semmle.label | tarRead |
subpaths

View File

@@ -22,8 +22,8 @@ edges
| WrongUsageOfUnsafe.go:166:33:166:57 | type conversion | WrongUsageOfUnsafe.go:166:16:166:58 | type conversion | provenance | |
| WrongUsageOfUnsafe.go:189:31:189:55 | type conversion | WrongUsageOfUnsafe.go:189:16:189:56 | type conversion | provenance | |
| WrongUsageOfUnsafe.go:211:31:211:60 | type conversion | WrongUsageOfUnsafe.go:211:16:211:61 | type conversion | provenance | |
| WrongUsageOfUnsafe.go:227:31:227:55 | type conversion | WrongUsageOfUnsafe.go:236:21:236:23 | SSA def(req) | provenance | |
| WrongUsageOfUnsafe.go:236:21:236:23 | SSA def(req) | WrongUsageOfUnsafe.go:243:9:243:27 | type conversion | provenance | |
| WrongUsageOfUnsafe.go:227:31:227:55 | type conversion | WrongUsageOfUnsafe.go:236:21:236:23 | definition of req | provenance | |
| WrongUsageOfUnsafe.go:236:21:236:23 | definition of req | WrongUsageOfUnsafe.go:243:9:243:27 | type conversion | provenance | |
| WrongUsageOfUnsafe.go:256:28:256:52 | type conversion | WrongUsageOfUnsafe.go:256:16:256:53 | type conversion | provenance | |
| WrongUsageOfUnsafe.go:274:25:274:49 | type conversion | WrongUsageOfUnsafe.go:274:16:274:50 | type conversion | provenance | |
| WrongUsageOfUnsafe.go:292:23:292:47 | type conversion | WrongUsageOfUnsafe.go:292:16:292:48 | type conversion | provenance | |
@@ -51,7 +51,7 @@ nodes
| WrongUsageOfUnsafe.go:211:16:211:61 | type conversion | semmle.label | type conversion |
| WrongUsageOfUnsafe.go:211:31:211:60 | type conversion | semmle.label | type conversion |
| WrongUsageOfUnsafe.go:227:31:227:55 | type conversion | semmle.label | type conversion |
| WrongUsageOfUnsafe.go:236:21:236:23 | SSA def(req) | semmle.label | SSA def(req) |
| WrongUsageOfUnsafe.go:236:21:236:23 | definition of req | semmle.label | definition of req |
| WrongUsageOfUnsafe.go:243:9:243:27 | type conversion | semmle.label | type conversion |
| WrongUsageOfUnsafe.go:256:16:256:53 | type conversion | semmle.label | type conversion |
| WrongUsageOfUnsafe.go:256:28:256:52 | type conversion | semmle.label | type conversion |

View File

@@ -1,6 +1,6 @@
module codeql-go-tests/concepts/loggercall
go 1.21
go 1.15
require (
github.com/golang/glog v1.2.5

View File

@@ -2,12 +2,10 @@ package main
const fmt = "formatted %s string"
const text = "test"
const key = "key"
var v []byte
func main() {
glogTest(len(v))
stdlib()
slogTest()
}

View File

@@ -1,40 +0,0 @@
package main
import (
"context"
"log/slog"
)
func slogTest() {
ctx := context.Background()
var logger *slog.Logger
var attr slog.Attr
// Methods on *slog.Logger: Debug/Info/Warn/Error(msg string, args ...any).
logger.Debug(text) // $ logger=text
logger.Info(text) // $ logger=text
logger.Warn(text) // $ logger=text
logger.Error(text) // $ logger=text
logger.Info(text, key, v) // $ logger=text logger=key logger=v
// Context variants: (ctx, msg string, args ...any).
logger.DebugContext(ctx, text) // $ logger=text
logger.InfoContext(ctx, text) // $ logger=text
logger.WarnContext(ctx, text) // $ logger=text
logger.ErrorContext(ctx, text) // $ logger=text
logger.InfoContext(ctx, text, key, v) // $ logger=text logger=key logger=v
// Log/LogAttrs: (ctx, level, msg string, args/attrs ...).
logger.Log(ctx, slog.LevelInfo, text, key, v) // $ logger=text logger=key logger=v
logger.LogAttrs(ctx, slog.LevelInfo, text, attr) // $ logger=text logger=attr
// Package-level convenience functions.
slog.Debug(text) // $ logger=text
slog.Info(text) // $ logger=text
slog.Warn(text) // $ logger=text
slog.Error(text) // $ logger=text
slog.Info(text, key, v) // $ logger=text logger=key logger=v
slog.InfoContext(ctx, text, key, v) // $ logger=text logger=key logger=v
slog.Log(ctx, slog.LevelInfo, text, key, v) // $ logger=text logger=key logger=v
slog.LogAttrs(ctx, slog.LevelInfo, text, attr) // $ logger=text logger=attr
}

View File

@@ -3,7 +3,7 @@
| stdlib.go:13:21:13:24 | "ab" | ab | stdlib.go:13:21:13:24 | "ab" |
| stdlib.go:15:26:15:39 | "[so]me\|regex" | [so]me\|regex | stdlib.go:15:2:15:40 | ... := ...[0] |
| stdlib.go:15:26:15:39 | "[so]me\|regex" | [so]me\|regex | stdlib.go:15:26:15:39 | "[so]me\|regex" |
| stdlib.go:16:30:16:37 | "posix?" | posix? | stdlib.go:16:2:16:3 | SSA def(re) |
| stdlib.go:16:30:16:37 | "posix?" | posix? | stdlib.go:16:2:16:3 | definition of re |
| stdlib.go:16:30:16:37 | "posix?" | posix? | stdlib.go:16:2:16:38 | ... = ...[0] |
| stdlib.go:16:30:16:37 | "posix?" | posix? | stdlib.go:16:30:16:37 | "posix?" |
| stdlib.go:16:30:16:37 | "posix?" | posix? | stdlib.go:17:2:17:3 | re |

View File

@@ -735,153 +735,129 @@
| main.go:48:11:48:12 | 42 | main.go:48:2:48:7 | assignment to result |
| main.go:49:2:49:7 | return statement | main.go:47:13:47:18 | implicit read of result |
| main.go:52:1:54:1 | entry | main.go:52:14:52:19 | zero value for result |
| main.go:52:1:54:1 | function declaration | main.go:56:6:56:9 | skip |
| main.go:52:1:54:1 | function declaration | main.go:56:6:56:10 | skip |
| main.go:52:6:52:9 | skip | main.go:52:1:54:1 | function declaration |
| main.go:52:14:52:19 | implicit read of result | main.go:52:1:54:1 | exit |
| main.go:52:14:52:19 | initialization of result | main.go:53:2:53:7 | return statement |
| main.go:52:14:52:19 | zero value for result | main.go:52:14:52:19 | initialization of result |
| main.go:53:2:53:7 | return statement | main.go:52:14:52:19 | implicit read of result |
| main.go:56:1:64:1 | entry | main.go:56:11:56:18 | argument corresponding to selector |
| main.go:56:1:64:1 | function declaration | main.go:66:6:66:10 | skip |
| main.go:56:6:56:9 | skip | main.go:56:1:64:1 | function declaration |
| main.go:56:11:56:18 | argument corresponding to selector | main.go:56:11:56:18 | initialization of selector |
| main.go:56:11:56:18 | initialization of selector | main.go:56:26:56:31 | zero value for result |
| main.go:56:26:56:31 | implicit read of result | main.go:56:1:64:1 | exit |
| main.go:56:26:56:31 | initialization of result | main.go:57:2:57:7 | skip |
| main.go:56:26:56:31 | zero value for result | main.go:56:26:56:31 | initialization of result |
| main.go:57:2:57:7 | assignment to result | main.go:58:5:58:12 | selector |
| main.go:57:2:57:7 | skip | main.go:57:11:57:11 | 0 |
| main.go:57:11:57:11 | 0 | main.go:57:2:57:7 | assignment to result |
| main.go:58:5:58:12 | selector | main.go:58:17:58:17 | 1 |
| main.go:58:5:58:17 | ...==... | main.go:58:5:58:17 | ...==... is false |
| main.go:58:5:58:17 | ...==... | main.go:58:5:58:17 | ...==... is true |
| main.go:58:5:58:17 | ...==... is false | main.go:61:3:61:8 | skip |
| main.go:58:5:58:17 | ...==... is true | main.go:59:10:59:10 | 1 |
| main.go:58:17:58:17 | 1 | main.go:58:5:58:17 | ...==... |
| main.go:59:3:59:10 | return statement | main.go:56:26:56:31 | implicit read of result |
| main.go:59:10:59:10 | 1 | main.go:59:10:59:10 | implicit write of result |
| main.go:59:10:59:10 | implicit write of result | main.go:59:3:59:10 | return statement |
| main.go:61:3:61:8 | assignment to result | main.go:63:2:63:7 | return statement |
| main.go:61:3:61:8 | skip | main.go:61:12:61:12 | 2 |
| main.go:61:12:61:12 | 2 | main.go:61:3:61:8 | assignment to result |
| main.go:63:2:63:7 | return statement | main.go:56:26:56:31 | implicit read of result |
| main.go:66:1:90:1 | entry | main.go:67:6:67:6 | skip |
| main.go:66:1:90:1 | function declaration | main.go:92:6:92:13 | skip |
| main.go:66:6:66:10 | skip | main.go:66:1:90:1 | function declaration |
| main.go:67:6:67:6 | assignment to x | main.go:68:6:68:9 | cond |
| main.go:67:6:67:6 | skip | main.go:67:6:67:6 | zero value for x |
| main.go:67:6:67:6 | zero value for x | main.go:67:6:67:6 | assignment to x |
| main.go:68:6:68:9 | cond | main.go:68:6:68:11 | call to cond |
| main.go:68:6:68:11 | call to cond | main.go:66:1:90:1 | exit |
| main.go:68:6:68:11 | call to cond | main.go:68:6:68:11 | call to cond is false |
| main.go:68:6:68:11 | call to cond | main.go:68:6:68:11 | call to cond is true |
| main.go:68:6:68:11 | call to cond is false | main.go:71:2:71:10 | selection of Print |
| main.go:68:6:68:11 | call to cond is true | main.go:69:3:69:3 | skip |
| main.go:69:3:69:3 | assignment to x | main.go:68:6:68:9 | cond |
| main.go:69:3:69:3 | skip | main.go:69:7:69:7 | 2 |
| main.go:69:7:69:7 | 2 | main.go:69:3:69:3 | assignment to x |
| main.go:71:2:71:10 | selection of Print | main.go:71:12:71:12 | x |
| main.go:71:2:71:13 | call to Print | main.go:66:1:90:1 | exit |
| main.go:71:2:71:13 | call to Print | main.go:73:2:73:2 | skip |
| main.go:71:12:71:12 | x | main.go:71:2:71:13 | call to Print |
| main.go:73:2:73:2 | assignment to y | main.go:74:6:74:6 | skip |
| main.go:73:2:73:2 | skip | main.go:73:7:73:7 | 1 |
| main.go:73:7:73:7 | 1 | main.go:73:2:73:2 | assignment to y |
| main.go:74:6:74:6 | assignment to i | main.go:75:6:75:9 | cond |
| main.go:74:6:74:6 | skip | main.go:74:11:74:11 | 0 |
| main.go:74:11:74:11 | 0 | main.go:74:6:74:6 | assignment to i |
| main.go:74:16:74:16 | i | main.go:74:16:74:18 | 1 |
| main.go:74:16:74:18 | 1 | main.go:74:16:74:18 | rhs of increment statement |
| main.go:74:16:74:18 | increment statement | main.go:75:6:75:9 | cond |
| main.go:74:16:74:18 | rhs of increment statement | main.go:74:16:74:18 | increment statement |
| main.go:56:1:80:1 | entry | main.go:57:6:57:6 | skip |
| main.go:56:1:80:1 | function declaration | main.go:82:6:82:13 | skip |
| main.go:56:6:56:10 | skip | main.go:56:1:80:1 | function declaration |
| main.go:57:6:57:6 | assignment to x | main.go:58:6:58:9 | cond |
| main.go:57:6:57:6 | skip | main.go:57:6:57:6 | zero value for x |
| main.go:57:6:57:6 | zero value for x | main.go:57:6:57:6 | assignment to x |
| main.go:58:6:58:9 | cond | main.go:58:6:58:11 | call to cond |
| main.go:58:6:58:11 | call to cond | main.go:56:1:80:1 | exit |
| main.go:58:6:58:11 | call to cond | main.go:58:6:58:11 | call to cond is false |
| main.go:58:6:58:11 | call to cond | main.go:58:6:58:11 | call to cond is true |
| main.go:58:6:58:11 | call to cond is false | main.go:61:2:61:10 | selection of Print |
| main.go:58:6:58:11 | call to cond is true | main.go:59:3:59:3 | skip |
| main.go:59:3:59:3 | assignment to x | main.go:58:6:58:9 | cond |
| main.go:59:3:59:3 | skip | main.go:59:7:59:7 | 2 |
| main.go:59:7:59:7 | 2 | main.go:59:3:59:3 | assignment to x |
| main.go:61:2:61:10 | selection of Print | main.go:61:12:61:12 | x |
| main.go:61:2:61:13 | call to Print | main.go:56:1:80:1 | exit |
| main.go:61:2:61:13 | call to Print | main.go:63:2:63:2 | skip |
| main.go:61:12:61:12 | x | main.go:61:2:61:13 | call to Print |
| main.go:63:2:63:2 | assignment to y | main.go:64:6:64:6 | skip |
| main.go:63:2:63:2 | skip | main.go:63:7:63:7 | 1 |
| main.go:63:7:63:7 | 1 | main.go:63:2:63:2 | assignment to y |
| main.go:64:6:64:6 | assignment to i | main.go:65:6:65:9 | cond |
| main.go:64:6:64:6 | skip | main.go:64:11:64:11 | 0 |
| main.go:64:11:64:11 | 0 | main.go:64:6:64:6 | assignment to i |
| main.go:64:16:64:16 | i | main.go:64:16:64:18 | 1 |
| main.go:64:16:64:18 | 1 | main.go:64:16:64:18 | rhs of increment statement |
| main.go:64:16:64:18 | increment statement | main.go:65:6:65:9 | cond |
| main.go:64:16:64:18 | rhs of increment statement | main.go:64:16:64:18 | increment statement |
| main.go:65:6:65:9 | cond | main.go:65:6:65:11 | call to cond |
| main.go:65:6:65:11 | call to cond | main.go:56:1:80:1 | exit |
| main.go:65:6:65:11 | call to cond | main.go:65:6:65:11 | call to cond is false |
| main.go:65:6:65:11 | call to cond | main.go:65:6:65:11 | call to cond is true |
| main.go:65:6:65:11 | call to cond is false | main.go:68:3:68:3 | skip |
| main.go:65:6:65:11 | call to cond is true | main.go:66:4:66:8 | skip |
| main.go:66:4:66:8 | skip | main.go:70:2:70:10 | selection of Print |
| main.go:68:3:68:3 | assignment to y | main.go:64:16:64:16 | i |
| main.go:68:3:68:3 | skip | main.go:68:7:68:7 | 2 |
| main.go:68:7:68:7 | 2 | main.go:68:3:68:3 | assignment to y |
| main.go:70:2:70:10 | selection of Print | main.go:70:12:70:12 | y |
| main.go:70:2:70:13 | call to Print | main.go:56:1:80:1 | exit |
| main.go:70:2:70:13 | call to Print | main.go:72:2:72:2 | skip |
| main.go:70:12:70:12 | y | main.go:70:2:70:13 | call to Print |
| main.go:72:2:72:2 | assignment to z | main.go:73:6:73:6 | skip |
| main.go:72:2:72:2 | skip | main.go:72:7:72:7 | 1 |
| main.go:72:7:72:7 | 1 | main.go:72:2:72:2 | assignment to z |
| main.go:73:6:73:6 | assignment to i | main.go:74:3:74:3 | skip |
| main.go:73:6:73:6 | skip | main.go:73:11:73:11 | 0 |
| main.go:73:11:73:11 | 0 | main.go:73:6:73:6 | assignment to i |
| main.go:73:16:73:16 | i | main.go:73:16:73:18 | 1 |
| main.go:73:16:73:18 | 1 | main.go:73:16:73:18 | rhs of increment statement |
| main.go:73:16:73:18 | increment statement | main.go:74:3:74:3 | skip |
| main.go:73:16:73:18 | rhs of increment statement | main.go:73:16:73:18 | increment statement |
| main.go:74:3:74:3 | assignment to z | main.go:75:6:75:9 | cond |
| main.go:74:3:74:3 | skip | main.go:74:7:74:7 | 2 |
| main.go:74:7:74:7 | 2 | main.go:74:3:74:3 | assignment to z |
| main.go:75:6:75:9 | cond | main.go:75:6:75:11 | call to cond |
| main.go:75:6:75:11 | call to cond | main.go:66:1:90:1 | exit |
| main.go:75:6:75:11 | call to cond | main.go:56:1:80:1 | exit |
| main.go:75:6:75:11 | call to cond | main.go:75:6:75:11 | call to cond is false |
| main.go:75:6:75:11 | call to cond | main.go:75:6:75:11 | call to cond is true |
| main.go:75:6:75:11 | call to cond is false | main.go:78:3:78:3 | skip |
| main.go:75:6:75:11 | call to cond is false | main.go:73:16:73:16 | i |
| main.go:75:6:75:11 | call to cond is true | main.go:76:4:76:8 | skip |
| main.go:76:4:76:8 | skip | main.go:80:2:80:10 | selection of Print |
| main.go:78:3:78:3 | assignment to y | main.go:74:16:74:16 | i |
| main.go:78:3:78:3 | skip | main.go:78:7:78:7 | 2 |
| main.go:78:7:78:7 | 2 | main.go:78:3:78:3 | assignment to y |
| main.go:80:2:80:10 | selection of Print | main.go:80:12:80:12 | y |
| main.go:80:2:80:13 | call to Print | main.go:66:1:90:1 | exit |
| main.go:80:2:80:13 | call to Print | main.go:82:2:82:2 | skip |
| main.go:80:12:80:12 | y | main.go:80:2:80:13 | call to Print |
| main.go:82:2:82:2 | assignment to z | main.go:83:6:83:6 | skip |
| main.go:82:2:82:2 | skip | main.go:82:7:82:7 | 1 |
| main.go:82:7:82:7 | 1 | main.go:82:2:82:2 | assignment to z |
| main.go:83:6:83:6 | assignment to i | main.go:84:3:84:3 | skip |
| main.go:83:6:83:6 | skip | main.go:83:11:83:11 | 0 |
| main.go:83:11:83:11 | 0 | main.go:83:6:83:6 | assignment to i |
| main.go:83:16:83:16 | i | main.go:83:16:83:18 | 1 |
| main.go:83:16:83:18 | 1 | main.go:83:16:83:18 | rhs of increment statement |
| main.go:83:16:83:18 | increment statement | main.go:84:3:84:3 | skip |
| main.go:83:16:83:18 | rhs of increment statement | main.go:83:16:83:18 | increment statement |
| main.go:84:3:84:3 | assignment to z | main.go:85:6:85:9 | cond |
| main.go:84:3:84:3 | skip | main.go:84:7:84:7 | 2 |
| main.go:84:7:84:7 | 2 | main.go:84:3:84:3 | assignment to z |
| main.go:85:6:85:9 | cond | main.go:85:6:85:11 | call to cond |
| main.go:85:6:85:11 | call to cond | main.go:66:1:90:1 | exit |
| main.go:85:6:85:11 | call to cond | main.go:85:6:85:11 | call to cond is false |
| main.go:85:6:85:11 | call to cond | main.go:85:6:85:11 | call to cond is true |
| main.go:85:6:85:11 | call to cond is false | main.go:83:16:83:16 | i |
| main.go:85:6:85:11 | call to cond is true | main.go:86:4:86:8 | skip |
| main.go:86:4:86:8 | skip | main.go:89:2:89:10 | selection of Print |
| main.go:89:2:89:10 | selection of Print | main.go:89:12:89:12 | z |
| main.go:89:2:89:13 | call to Print | main.go:66:1:90:1 | exit |
| main.go:89:12:89:12 | z | main.go:89:2:89:13 | call to Print |
| main.go:92:1:96:1 | entry | main.go:92:18:92:18 | zero value for a |
| main.go:92:1:96:1 | function declaration | main.go:98:6:98:23 | skip |
| main.go:92:6:92:13 | skip | main.go:92:1:96:1 | function declaration |
| main.go:92:18:92:18 | implicit read of a | main.go:92:25:92:25 | implicit read of b |
| main.go:92:18:92:18 | initialization of a | main.go:92:25:92:25 | zero value for b |
| main.go:92:18:92:18 | zero value for a | main.go:92:18:92:18 | initialization of a |
| main.go:92:25:92:25 | implicit read of b | main.go:92:1:96:1 | exit |
| main.go:92:25:92:25 | initialization of b | main.go:93:2:93:2 | skip |
| main.go:92:25:92:25 | zero value for b | main.go:92:25:92:25 | initialization of b |
| main.go:93:2:93:2 | assignment to x | main.go:94:2:94:2 | skip |
| main.go:93:2:93:2 | skip | main.go:93:7:93:8 | 23 |
| main.go:93:7:93:8 | 23 | main.go:93:2:93:2 | assignment to x |
| main.go:94:2:94:2 | assignment to x | main.go:94:5:94:5 | assignment to a |
| main.go:94:2:94:2 | skip | main.go:94:5:94:5 | skip |
| main.go:94:5:94:5 | assignment to a | main.go:95:2:95:7 | return statement |
| main.go:94:5:94:5 | skip | main.go:94:9:94:9 | x |
| main.go:94:9:94:9 | x | main.go:94:11:94:12 | 19 |
| main.go:94:9:94:12 | ...+... | main.go:94:15:94:15 | x |
| main.go:94:11:94:12 | 19 | main.go:94:9:94:12 | ...+... |
| main.go:94:15:94:15 | x | main.go:94:2:94:2 | assignment to x |
| main.go:95:2:95:7 | return statement | main.go:92:18:92:18 | implicit read of a |
| main.go:98:1:106:1 | entry | main.go:98:25:98:25 | argument corresponding to x |
| main.go:98:1:106:1 | function declaration | main.go:0:0:0:0 | exit |
| main.go:98:6:98:23 | skip | main.go:98:1:106:1 | function declaration |
| main.go:98:25:98:25 | argument corresponding to x | main.go:98:25:98:25 | initialization of x |
| main.go:98:25:98:25 | initialization of x | main.go:99:2:99:2 | skip |
| main.go:99:2:99:2 | assignment to a | main.go:99:5:99:5 | assignment to b |
| main.go:99:2:99:2 | skip | main.go:99:5:99:5 | skip |
| main.go:99:5:99:5 | assignment to b | main.go:100:5:100:8 | cond |
| main.go:99:5:99:5 | skip | main.go:99:10:99:10 | x |
| main.go:99:10:99:10 | x | main.go:99:13:99:13 | 0 |
| main.go:99:13:99:13 | 0 | main.go:99:2:99:2 | assignment to a |
| main.go:100:5:100:8 | cond | main.go:100:5:100:10 | call to cond |
| main.go:100:5:100:10 | call to cond | main.go:98:1:106:1 | exit |
| main.go:100:5:100:10 | call to cond | main.go:100:5:100:10 | call to cond is false |
| main.go:100:5:100:10 | call to cond | main.go:100:5:100:10 | call to cond is true |
| main.go:100:5:100:10 | call to cond is false | main.go:103:3:103:3 | skip |
| main.go:100:5:100:10 | call to cond is true | main.go:101:3:101:3 | skip |
| main.go:101:3:101:3 | assignment to a | main.go:105:9:105:9 | a |
| main.go:101:3:101:3 | skip | main.go:101:6:101:6 | skip |
| main.go:101:6:101:6 | skip | main.go:101:10:101:10 | b |
| main.go:101:10:101:10 | b | main.go:101:13:101:13 | a |
| main.go:101:13:101:13 | a | main.go:101:3:101:3 | assignment to a |
| main.go:103:3:103:3 | skip | main.go:103:6:103:6 | skip |
| main.go:103:6:103:6 | assignment to b | main.go:105:9:105:9 | a |
| main.go:103:6:103:6 | skip | main.go:103:10:103:10 | b |
| main.go:103:10:103:10 | b | main.go:103:13:103:13 | a |
| main.go:103:13:103:13 | a | main.go:103:6:103:6 | assignment to b |
| main.go:105:2:105:12 | return statement | main.go:98:1:106:1 | exit |
| main.go:105:9:105:9 | a | main.go:105:12:105:12 | b |
| main.go:105:12:105:12 | b | main.go:105:2:105:12 | return statement |
| main.go:76:4:76:8 | skip | main.go:79:2:79:10 | selection of Print |
| main.go:79:2:79:10 | selection of Print | main.go:79:12:79:12 | z |
| main.go:79:2:79:13 | call to Print | main.go:56:1:80:1 | exit |
| main.go:79:12:79:12 | z | main.go:79:2:79:13 | call to Print |
| main.go:82:1:86:1 | entry | main.go:82:18:82:18 | zero value for a |
| main.go:82:1:86:1 | function declaration | main.go:88:6:88:23 | skip |
| main.go:82:6:82:13 | skip | main.go:82:1:86:1 | function declaration |
| main.go:82:18:82:18 | implicit read of a | main.go:82:25:82:25 | implicit read of b |
| main.go:82:18:82:18 | initialization of a | main.go:82:25:82:25 | zero value for b |
| main.go:82:18:82:18 | zero value for a | main.go:82:18:82:18 | initialization of a |
| main.go:82:25:82:25 | implicit read of b | main.go:82:1:86:1 | exit |
| main.go:82:25:82:25 | initialization of b | main.go:83:2:83:2 | skip |
| main.go:82:25:82:25 | zero value for b | main.go:82:25:82:25 | initialization of b |
| main.go:83:2:83:2 | assignment to x | main.go:84:2:84:2 | skip |
| main.go:83:2:83:2 | skip | main.go:83:7:83:8 | 23 |
| main.go:83:7:83:8 | 23 | main.go:83:2:83:2 | assignment to x |
| main.go:84:2:84:2 | assignment to x | main.go:84:5:84:5 | assignment to a |
| main.go:84:2:84:2 | skip | main.go:84:5:84:5 | skip |
| main.go:84:5:84:5 | assignment to a | main.go:85:2:85:7 | return statement |
| main.go:84:5:84:5 | skip | main.go:84:9:84:9 | x |
| main.go:84:9:84:9 | x | main.go:84:11:84:12 | 19 |
| main.go:84:9:84:12 | ...+... | main.go:84:15:84:15 | x |
| main.go:84:11:84:12 | 19 | main.go:84:9:84:12 | ...+... |
| main.go:84:15:84:15 | x | main.go:84:2:84:2 | assignment to x |
| main.go:85:2:85:7 | return statement | main.go:82:18:82:18 | implicit read of a |
| main.go:88:1:96:1 | entry | main.go:88:25:88:25 | argument corresponding to x |
| main.go:88:1:96:1 | function declaration | main.go:0:0:0:0 | exit |
| main.go:88:6:88:23 | skip | main.go:88:1:96:1 | function declaration |
| main.go:88:25:88:25 | argument corresponding to x | main.go:88:25:88:25 | initialization of x |
| main.go:88:25:88:25 | initialization of x | main.go:89:2:89:2 | skip |
| main.go:89:2:89:2 | assignment to a | main.go:89:5:89:5 | assignment to b |
| main.go:89:2:89:2 | skip | main.go:89:5:89:5 | skip |
| main.go:89:5:89:5 | assignment to b | main.go:90:5:90:8 | cond |
| main.go:89:5:89:5 | skip | main.go:89:10:89:10 | x |
| main.go:89:10:89:10 | x | main.go:89:13:89:13 | 0 |
| main.go:89:13:89:13 | 0 | main.go:89:2:89:2 | assignment to a |
| main.go:90:5:90:8 | cond | main.go:90:5:90:10 | call to cond |
| main.go:90:5:90:10 | call to cond | main.go:88:1:96:1 | exit |
| main.go:90:5:90:10 | call to cond | main.go:90:5:90:10 | call to cond is false |
| main.go:90:5:90:10 | call to cond | main.go:90:5:90:10 | call to cond is true |
| main.go:90:5:90:10 | call to cond is false | main.go:93:3:93:3 | skip |
| main.go:90:5:90:10 | call to cond is true | main.go:91:3:91:3 | skip |
| main.go:91:3:91:3 | assignment to a | main.go:95:9:95:9 | a |
| main.go:91:3:91:3 | skip | main.go:91:6:91:6 | skip |
| main.go:91:6:91:6 | skip | main.go:91:10:91:10 | b |
| main.go:91:10:91:10 | b | main.go:91:13:91:13 | a |
| main.go:91:13:91:13 | a | main.go:91:3:91:3 | assignment to a |
| main.go:93:3:93:3 | skip | main.go:93:6:93:6 | skip |
| main.go:93:6:93:6 | assignment to b | main.go:95:9:95:9 | a |
| main.go:93:6:93:6 | skip | main.go:93:10:93:10 | b |
| main.go:93:10:93:10 | b | main.go:93:13:93:13 | a |
| main.go:93:13:93:13 | a | main.go:93:6:93:6 | assignment to b |
| main.go:95:2:95:12 | return statement | main.go:88:1:96:1 | exit |
| main.go:95:9:95:9 | a | main.go:95:12:95:12 | b |
| main.go:95:12:95:12 | b | main.go:95:2:95:12 | return statement |
| noretfunctions.go:0:0:0:0 | entry | noretfunctions.go:3:1:6:1 | skip |
| noretfunctions.go:3:1:6:1 | skip | noretfunctions.go:8:6:8:12 | skip |
| noretfunctions.go:8:1:10:1 | entry | noretfunctions.go:9:2:9:8 | selection of Exit |

View File

@@ -53,16 +53,6 @@ func baz2() (result int) {
return
}
func baz3(selector int) (result int) {
result = 0
if selector == 1 {
return 1
} else {
result = 2
}
return
}
func loops() {
var x int
for cond() {

View File

@@ -22,4 +22,4 @@ invalidModelRow
| test.go:187:24:187:31 | call to Src1 | qltest |
| test.go:191:24:191:31 | call to Src1 | qltest |
| test.go:201:10:201:28 | selection of SourceVariable | qltest |
| test.go:208:15:208:17 | SSA def(src) | qltest |
| test.go:208:15:208:17 | definition of src | qltest |

View File

@@ -22,4 +22,4 @@ invalidModelRow
| test.go:187:24:187:31 | call to Src1 | qltest |
| test.go:191:24:191:31 | call to Src1 | qltest |
| test.go:209:10:209:28 | selection of SourceVariable | qltest |
| test.go:216:15:216:17 | SSA def(src) | qltest |
| test.go:216:15:216:17 | definition of src | qltest |

View File

@@ -1,169 +1,169 @@
| main.go:3:12:3:12 | SSA def(x) | main.go:5:5:5:5 | x |
| main.go:3:12:3:12 | argument corresponding to x | main.go:3:12:3:12 | SSA def(x) |
| main.go:3:19:3:20 | SSA def(fn) | main.go:10:24:10:25 | fn |
| main.go:3:19:3:20 | argument corresponding to fn | main.go:3:19:3:20 | SSA def(fn) |
| main.go:3:12:3:12 | argument corresponding to x | main.go:3:12:3:12 | definition of x |
| main.go:3:12:3:12 | definition of x | main.go:5:5:5:5 | x |
| main.go:3:19:3:20 | argument corresponding to fn | main.go:3:19:3:20 | definition of fn |
| main.go:3:19:3:20 | definition of fn | main.go:10:24:10:25 | fn |
| main.go:5:5:5:5 | x | main.go:6:7:6:7 | x |
| main.go:5:5:5:5 | x | main.go:8:8:8:8 | x |
| main.go:6:3:6:3 | SSA def(y) | main.go:10:12:10:12 | y |
| main.go:6:7:6:7 | x | main.go:6:3:6:3 | SSA def(y) |
| main.go:6:3:6:3 | definition of y | main.go:10:12:10:12 | y |
| main.go:6:7:6:7 | x | main.go:6:3:6:3 | definition of y |
| main.go:6:7:6:7 | x | main.go:10:7:10:7 | x |
| main.go:8:3:8:3 | SSA def(y) | main.go:10:12:10:12 | y |
| main.go:8:7:8:8 | -... | main.go:8:3:8:3 | SSA def(y) |
| main.go:8:3:8:3 | definition of y | main.go:10:12:10:12 | y |
| main.go:8:7:8:8 | -... | main.go:8:3:8:3 | definition of y |
| main.go:8:8:8:8 | x | main.go:10:7:10:7 | x |
| main.go:10:2:10:2 | SSA def(z) | main.go:11:14:11:14 | z |
| main.go:10:2:10:2 | definition of z | main.go:11:14:11:14 | z |
| main.go:10:7:10:7 | x | main.go:10:22:10:22 | x |
| main.go:10:7:10:12 | ...<=... | main.go:10:7:10:27 | ...&&... |
| main.go:10:7:10:27 | ...&&... | main.go:10:2:10:2 | SSA def(z) |
| main.go:10:7:10:27 | ...&&... | main.go:10:2:10:2 | definition of z |
| main.go:10:12:10:12 | y | main.go:10:17:10:17 | y |
| main.go:10:17:10:27 | ...>=... | main.go:10:7:10:27 | ...&&... |
| main.go:11:14:11:14 | z | main.go:11:9:11:15 | type conversion |
| main.go:15:9:15:9 | 0 | main.go:15:2:15:4 | SSA def(acc) |
| main.go:16:9:19:2 | SSA def(acc) | main.go:17:3:17:5 | acc |
| main.go:17:3:17:7 | SSA def(acc) | main.go:18:10:18:12 | acc |
| main.go:17:3:17:7 | rhs of increment statement | main.go:17:3:17:7 | SSA def(acc) |
| main.go:22:12:22:12 | SSA def(b) | main.go:23:5:23:5 | b |
| main.go:22:12:22:12 | argument corresponding to b | main.go:22:12:22:12 | SSA def(b) |
| main.go:22:20:22:20 | SSA def(x) | main.go:24:10:24:10 | x |
| main.go:22:20:22:20 | SSA def(x) | main.go:26:11:26:11 | x |
| main.go:22:20:22:20 | argument corresponding to x | main.go:22:20:22:20 | SSA def(x) |
| main.go:15:9:15:9 | 0 | main.go:15:2:15:4 | definition of acc |
| main.go:16:9:19:2 | capture variable acc | main.go:17:3:17:5 | acc |
| main.go:17:3:17:7 | definition of acc | main.go:18:10:18:12 | acc |
| main.go:17:3:17:7 | rhs of increment statement | main.go:17:3:17:7 | definition of acc |
| main.go:22:12:22:12 | argument corresponding to b | main.go:22:12:22:12 | definition of b |
| main.go:22:12:22:12 | definition of b | main.go:23:5:23:5 | b |
| main.go:22:20:22:20 | argument corresponding to x | main.go:22:20:22:20 | definition of x |
| main.go:22:20:22:20 | definition of x | main.go:24:10:24:10 | x |
| main.go:22:20:22:20 | definition of x | main.go:26:11:26:11 | x |
| main.go:24:10:24:10 | x | main.go:24:10:24:19 | type assertion |
| main.go:26:2:26:2 | SSA def(n) | main.go:27:11:27:11 | n |
| main.go:26:2:26:17 | ... := ...[0] | main.go:26:2:26:2 | SSA def(n) |
| main.go:26:2:26:17 | ... := ...[1] | main.go:26:5:26:6 | SSA def(ok) |
| main.go:26:5:26:6 | SSA def(ok) | main.go:27:5:27:6 | ok |
| main.go:26:2:26:2 | definition of n | main.go:27:11:27:11 | n |
| main.go:26:2:26:17 | ... := ...[0] | main.go:26:2:26:2 | definition of n |
| main.go:26:2:26:17 | ... := ...[1] | main.go:26:5:26:6 | definition of ok |
| main.go:26:5:26:6 | definition of ok | main.go:27:5:27:6 | ok |
| main.go:26:11:26:11 | x | main.go:26:2:26:17 | ... := ...[0] |
| main.go:38:2:38:2 | SSA def(s) | main.go:39:15:39:15 | s |
| main.go:38:7:38:20 | slice literal | main.go:38:2:38:2 | SSA def(s) |
| main.go:38:7:38:20 | slice literal [postupdate] | main.go:38:2:38:2 | SSA def(s) |
| main.go:39:2:39:3 | SSA def(s1) | main.go:40:18:40:19 | s1 |
| main.go:39:8:39:25 | call to append | main.go:39:2:39:3 | SSA def(s1) |
| main.go:38:2:38:2 | definition of s | main.go:39:15:39:15 | s |
| main.go:38:7:38:20 | slice literal | main.go:38:2:38:2 | definition of s |
| main.go:38:7:38:20 | slice literal [postupdate] | main.go:38:2:38:2 | definition of s |
| main.go:39:2:39:3 | definition of s1 | main.go:40:18:40:19 | s1 |
| main.go:39:8:39:25 | call to append | main.go:39:2:39:3 | definition of s1 |
| main.go:39:15:39:15 | s | main.go:40:15:40:15 | s |
| main.go:39:15:39:15 | s [postupdate] | main.go:40:15:40:15 | s |
| main.go:40:2:40:3 | SSA def(s2) | main.go:43:9:43:10 | s2 |
| main.go:40:8:40:23 | call to append | main.go:40:2:40:3 | SSA def(s2) |
| main.go:40:2:40:3 | definition of s2 | main.go:43:9:43:10 | s2 |
| main.go:40:8:40:23 | call to append | main.go:40:2:40:3 | definition of s2 |
| main.go:40:15:40:15 | s | main.go:42:7:42:7 | s |
| main.go:40:15:40:15 | s [postupdate] | main.go:42:7:42:7 | s |
| main.go:41:2:41:3 | SSA def(s4) | main.go:42:10:42:11 | s4 |
| main.go:41:8:41:21 | call to make | main.go:41:2:41:3 | SSA def(s4) |
| main.go:46:13:46:14 | SSA def(xs) | main.go:47:20:47:21 | xs |
| main.go:46:13:46:14 | argument corresponding to xs | main.go:46:13:46:14 | SSA def(xs) |
| main.go:46:24:46:27 | SSA def(keys) | main.go:46:24:46:27 | implicit read of keys |
| main.go:46:24:46:27 | SSA def(keys) | main.go:49:3:49:6 | keys |
| main.go:46:24:46:27 | zero value for keys | main.go:46:24:46:27 | SSA def(keys) |
| main.go:46:34:46:37 | SSA def(vals) | main.go:46:34:46:37 | implicit read of vals |
| main.go:46:34:46:37 | SSA def(vals) | main.go:48:3:48:6 | vals |
| main.go:46:34:46:37 | zero value for vals | main.go:46:34:46:37 | SSA def(vals) |
| main.go:47:2:50:2 | range statement[0] | main.go:47:6:47:6 | SSA def(k) |
| main.go:47:2:50:2 | range statement[1] | main.go:47:9:47:9 | SSA def(v) |
| main.go:47:6:47:6 | SSA def(k) | main.go:49:11:49:11 | k |
| main.go:47:9:47:9 | SSA def(v) | main.go:48:11:48:11 | v |
| main.go:48:3:48:6 | SSA def(vals) | main.go:46:34:46:37 | implicit read of vals |
| main.go:48:3:48:6 | SSA def(vals) | main.go:48:3:48:6 | vals |
| main.go:48:3:48:11 | ... += ... | main.go:48:3:48:6 | SSA def(vals) |
| main.go:49:3:49:6 | SSA def(keys) | main.go:46:24:46:27 | implicit read of keys |
| main.go:49:3:49:6 | SSA def(keys) | main.go:49:3:49:6 | keys |
| main.go:49:3:49:11 | ... += ... | main.go:49:3:49:6 | SSA def(keys) |
| main.go:55:6:55:7 | SSA def(ch) | main.go:56:2:56:3 | ch |
| main.go:55:6:55:7 | zero value for ch | main.go:55:6:55:7 | SSA def(ch) |
| main.go:41:2:41:3 | definition of s4 | main.go:42:10:42:11 | s4 |
| main.go:41:8:41:21 | call to make | main.go:41:2:41:3 | definition of s4 |
| main.go:46:13:46:14 | argument corresponding to xs | main.go:46:13:46:14 | definition of xs |
| main.go:46:13:46:14 | definition of xs | main.go:47:20:47:21 | xs |
| main.go:46:24:46:27 | definition of keys | main.go:46:24:46:27 | implicit read of keys |
| main.go:46:24:46:27 | definition of keys | main.go:49:3:49:6 | keys |
| main.go:46:24:46:27 | zero value for keys | main.go:46:24:46:27 | definition of keys |
| main.go:46:34:46:37 | definition of vals | main.go:46:34:46:37 | implicit read of vals |
| main.go:46:34:46:37 | definition of vals | main.go:48:3:48:6 | vals |
| main.go:46:34:46:37 | zero value for vals | main.go:46:34:46:37 | definition of vals |
| main.go:47:2:50:2 | range statement[0] | main.go:47:6:47:6 | definition of k |
| main.go:47:2:50:2 | range statement[1] | main.go:47:9:47:9 | definition of v |
| main.go:47:6:47:6 | definition of k | main.go:49:11:49:11 | k |
| main.go:47:9:47:9 | definition of v | main.go:48:11:48:11 | v |
| main.go:48:3:48:6 | definition of vals | main.go:46:34:46:37 | implicit read of vals |
| main.go:48:3:48:6 | definition of vals | main.go:48:3:48:6 | vals |
| main.go:48:3:48:11 | ... += ... | main.go:48:3:48:6 | definition of vals |
| main.go:49:3:49:6 | definition of keys | main.go:46:24:46:27 | implicit read of keys |
| main.go:49:3:49:6 | definition of keys | main.go:49:3:49:6 | keys |
| main.go:49:3:49:11 | ... += ... | main.go:49:3:49:6 | definition of keys |
| main.go:55:6:55:7 | definition of ch | main.go:56:2:56:3 | ch |
| main.go:55:6:55:7 | zero value for ch | main.go:55:6:55:7 | definition of ch |
| main.go:56:2:56:3 | ch | main.go:57:4:57:5 | ch |
| main.go:56:2:56:3 | ch [postupdate] | main.go:57:4:57:5 | ch |
| main.go:61:2:61:2 | SSA def(x) | main.go:64:11:64:11 | x |
| main.go:61:7:61:7 | 1 | main.go:61:2:61:2 | SSA def(x) |
| main.go:62:2:62:2 | SSA def(y) | main.go:64:14:64:14 | y |
| main.go:62:7:62:7 | 2 | main.go:62:2:62:2 | SSA def(y) |
| main.go:63:2:63:2 | SSA def(z) | main.go:64:17:64:17 | z |
| main.go:63:7:63:7 | 3 | main.go:63:2:63:2 | SSA def(z) |
| main.go:64:2:64:2 | SSA def(a) | main.go:66:9:66:9 | a |
| main.go:64:7:64:18 | call to min | main.go:64:2:64:2 | SSA def(a) |
| main.go:61:2:61:2 | definition of x | main.go:64:11:64:11 | x |
| main.go:61:7:61:7 | 1 | main.go:61:2:61:2 | definition of x |
| main.go:62:2:62:2 | definition of y | main.go:64:14:64:14 | y |
| main.go:62:7:62:7 | 2 | main.go:62:2:62:2 | definition of y |
| main.go:63:2:63:2 | definition of z | main.go:64:17:64:17 | z |
| main.go:63:7:63:7 | 3 | main.go:63:2:63:2 | definition of z |
| main.go:64:2:64:2 | definition of a | main.go:66:9:66:9 | a |
| main.go:64:7:64:18 | call to min | main.go:64:2:64:2 | definition of a |
| main.go:64:11:64:11 | x | main.go:64:7:64:18 | call to min |
| main.go:64:11:64:11 | x | main.go:65:11:65:11 | x |
| main.go:64:14:64:14 | y | main.go:64:7:64:18 | call to min |
| main.go:64:14:64:14 | y | main.go:65:14:65:14 | y |
| main.go:64:17:64:17 | z | main.go:64:7:64:18 | call to min |
| main.go:64:17:64:17 | z | main.go:65:17:65:17 | z |
| main.go:65:2:65:2 | SSA def(b) | main.go:66:12:66:12 | b |
| main.go:65:7:65:18 | call to max | main.go:65:2:65:2 | SSA def(b) |
| main.go:65:2:65:2 | definition of b | main.go:66:12:66:12 | b |
| main.go:65:7:65:18 | call to max | main.go:65:2:65:2 | definition of b |
| main.go:65:11:65:11 | x | main.go:65:7:65:18 | call to max |
| main.go:65:14:65:14 | y | main.go:65:7:65:18 | call to max |
| main.go:65:17:65:17 | z | main.go:65:7:65:18 | call to max |
| strings.go:8:12:8:12 | SSA def(s) | strings.go:9:24:9:24 | s |
| strings.go:8:12:8:12 | argument corresponding to s | strings.go:8:12:8:12 | SSA def(s) |
| strings.go:9:2:9:3 | SSA def(s2) | strings.go:11:20:11:21 | s2 |
| strings.go:9:8:9:38 | call to Replace | strings.go:9:2:9:3 | SSA def(s2) |
| strings.go:8:12:8:12 | argument corresponding to s | strings.go:8:12:8:12 | definition of s |
| strings.go:8:12:8:12 | definition of s | strings.go:9:24:9:24 | s |
| strings.go:9:2:9:3 | definition of s2 | strings.go:11:20:11:21 | s2 |
| strings.go:9:8:9:38 | call to Replace | strings.go:9:2:9:3 | definition of s2 |
| strings.go:9:24:9:24 | s | strings.go:10:27:10:27 | s |
| strings.go:10:2:10:3 | SSA def(s3) | strings.go:11:24:11:25 | s3 |
| strings.go:10:8:10:42 | call to ReplaceAll | strings.go:10:2:10:3 | SSA def(s3) |
| strings.go:10:2:10:3 | definition of s3 | strings.go:11:24:11:25 | s3 |
| strings.go:10:8:10:42 | call to ReplaceAll | strings.go:10:2:10:3 | definition of s3 |
| strings.go:11:20:11:21 | s2 | strings.go:11:48:11:49 | s2 |
| strings.go:11:24:11:25 | s3 | strings.go:11:67:11:68 | s3 |
| url.go:8:12:8:12 | SSA def(b) | url.go:11:5:11:5 | b |
| url.go:8:12:8:12 | argument corresponding to b | url.go:8:12:8:12 | SSA def(b) |
| url.go:8:20:8:20 | SSA def(s) | url.go:12:46:12:46 | s |
| url.go:8:20:8:20 | SSA def(s) | url.go:14:48:14:48 | s |
| url.go:8:20:8:20 | argument corresponding to s | url.go:8:20:8:20 | SSA def(s) |
| url.go:12:3:12:5 | SSA def(res) | url.go:19:9:19:11 | res |
| url.go:12:3:12:48 | ... = ...[0] | url.go:12:3:12:5 | SSA def(res) |
| url.go:12:3:12:48 | ... = ...[1] | url.go:12:8:12:10 | SSA def(err) |
| url.go:12:8:12:10 | SSA def(err) | url.go:16:5:16:7 | err |
| url.go:14:3:14:5 | SSA def(res) | url.go:19:9:19:11 | res |
| url.go:14:3:14:50 | ... = ...[0] | url.go:14:3:14:5 | SSA def(res) |
| url.go:14:3:14:50 | ... = ...[1] | url.go:14:8:14:10 | SSA def(err) |
| url.go:14:8:14:10 | SSA def(err) | url.go:16:5:16:7 | err |
| url.go:22:12:22:12 | SSA def(i) | url.go:24:5:24:5 | i |
| url.go:22:12:22:12 | argument corresponding to i | url.go:22:12:22:12 | SSA def(i) |
| url.go:22:19:22:19 | SSA def(s) | url.go:23:20:23:20 | s |
| url.go:22:19:22:19 | argument corresponding to s | url.go:22:19:22:19 | SSA def(s) |
| url.go:23:2:23:2 | SSA def(u) | url.go:25:10:25:10 | u |
| url.go:23:2:23:21 | ... := ...[0] | url.go:23:2:23:2 | SSA def(u) |
| url.go:8:12:8:12 | argument corresponding to b | url.go:8:12:8:12 | definition of b |
| url.go:8:12:8:12 | definition of b | url.go:11:5:11:5 | b |
| url.go:8:20:8:20 | argument corresponding to s | url.go:8:20:8:20 | definition of s |
| url.go:8:20:8:20 | definition of s | url.go:12:46:12:46 | s |
| url.go:8:20:8:20 | definition of s | url.go:14:48:14:48 | s |
| url.go:12:3:12:5 | definition of res | url.go:19:9:19:11 | res |
| url.go:12:3:12:48 | ... = ...[0] | url.go:12:3:12:5 | definition of res |
| url.go:12:3:12:48 | ... = ...[1] | url.go:12:8:12:10 | definition of err |
| url.go:12:8:12:10 | definition of err | url.go:16:5:16:7 | err |
| url.go:14:3:14:5 | definition of res | url.go:19:9:19:11 | res |
| url.go:14:3:14:50 | ... = ...[0] | url.go:14:3:14:5 | definition of res |
| url.go:14:3:14:50 | ... = ...[1] | url.go:14:8:14:10 | definition of err |
| url.go:14:8:14:10 | definition of err | url.go:16:5:16:7 | err |
| url.go:22:12:22:12 | argument corresponding to i | url.go:22:12:22:12 | definition of i |
| url.go:22:12:22:12 | definition of i | url.go:24:5:24:5 | i |
| url.go:22:19:22:19 | argument corresponding to s | url.go:22:19:22:19 | definition of s |
| url.go:22:19:22:19 | definition of s | url.go:23:20:23:20 | s |
| url.go:23:2:23:2 | definition of u | url.go:25:10:25:10 | u |
| url.go:23:2:23:21 | ... := ...[0] | url.go:23:2:23:2 | definition of u |
| url.go:23:20:23:20 | s | url.go:27:29:27:29 | s |
| url.go:27:2:27:2 | SSA def(u) | url.go:28:14:28:14 | u |
| url.go:27:2:27:30 | ... = ...[0] | url.go:27:2:27:2 | SSA def(u) |
| url.go:27:2:27:2 | definition of u | url.go:28:14:28:14 | u |
| url.go:27:2:27:30 | ... = ...[0] | url.go:27:2:27:2 | definition of u |
| url.go:28:14:28:14 | u | url.go:29:14:29:14 | u |
| url.go:28:14:28:14 | u [postupdate] | url.go:29:14:29:14 | u |
| url.go:29:14:29:14 | u | url.go:30:11:30:11 | u |
| url.go:29:14:29:14 | u [postupdate] | url.go:30:11:30:11 | u |
| url.go:30:2:30:3 | SSA def(bs) | url.go:31:14:31:15 | bs |
| url.go:30:2:30:27 | ... := ...[0] | url.go:30:2:30:3 | SSA def(bs) |
| url.go:30:2:30:3 | definition of bs | url.go:31:14:31:15 | bs |
| url.go:30:2:30:27 | ... := ...[0] | url.go:30:2:30:3 | definition of bs |
| url.go:30:11:30:11 | u | url.go:32:9:32:9 | u |
| url.go:30:11:30:11 | u [postupdate] | url.go:32:9:32:9 | u |
| url.go:32:2:32:2 | SSA def(u) | url.go:33:14:33:14 | u |
| url.go:32:2:32:23 | ... = ...[0] | url.go:32:2:32:2 | SSA def(u) |
| url.go:32:2:32:2 | definition of u | url.go:33:14:33:14 | u |
| url.go:32:2:32:23 | ... = ...[0] | url.go:32:2:32:2 | definition of u |
| url.go:33:14:33:14 | u | url.go:34:14:34:14 | u |
| url.go:33:14:33:14 | u [postupdate] | url.go:34:14:34:14 | u |
| url.go:34:14:34:14 | u | url.go:35:14:35:14 | u |
| url.go:34:14:34:14 | u [postupdate] | url.go:35:14:35:14 | u |
| url.go:35:14:35:14 | u | url.go:36:6:36:6 | u |
| url.go:35:14:35:14 | u [postupdate] | url.go:36:6:36:6 | u |
| url.go:36:2:36:2 | SSA def(u) | url.go:37:9:37:9 | u |
| url.go:36:2:36:2 | definition of u | url.go:37:9:37:9 | u |
| url.go:36:6:36:6 | u | url.go:36:25:36:25 | u |
| url.go:36:6:36:6 | u [postupdate] | url.go:36:25:36:25 | u |
| url.go:36:6:36:26 | call to ResolveReference | url.go:36:2:36:2 | SSA def(u) |
| url.go:42:2:42:3 | SSA def(ui) | url.go:43:11:43:12 | ui |
| url.go:42:7:42:38 | call to UserPassword | url.go:42:2:42:3 | SSA def(ui) |
| url.go:43:2:43:3 | SSA def(pw) | url.go:44:14:44:15 | pw |
| url.go:43:2:43:23 | ... := ...[0] | url.go:43:2:43:3 | SSA def(pw) |
| url.go:36:6:36:26 | call to ResolveReference | url.go:36:2:36:2 | definition of u |
| url.go:42:2:42:3 | definition of ui | url.go:43:11:43:12 | ui |
| url.go:42:7:42:38 | call to UserPassword | url.go:42:2:42:3 | definition of ui |
| url.go:43:2:43:3 | definition of pw | url.go:44:14:44:15 | pw |
| url.go:43:2:43:23 | ... := ...[0] | url.go:43:2:43:3 | definition of pw |
| url.go:43:11:43:12 | ui | url.go:45:14:45:15 | ui |
| url.go:43:11:43:12 | ui [postupdate] | url.go:45:14:45:15 | ui |
| url.go:45:14:45:15 | ui | url.go:46:9:46:10 | ui |
| url.go:45:14:45:15 | ui [postupdate] | url.go:46:9:46:10 | ui |
| url.go:49:12:49:12 | SSA def(q) | url.go:50:25:50:25 | q |
| url.go:49:12:49:12 | argument corresponding to q | url.go:49:12:49:12 | SSA def(q) |
| url.go:50:2:50:2 | SSA def(v) | url.go:51:14:51:14 | v |
| url.go:50:2:50:26 | ... := ...[0] | url.go:50:2:50:2 | SSA def(v) |
| url.go:49:12:49:12 | argument corresponding to q | url.go:49:12:49:12 | definition of q |
| url.go:49:12:49:12 | definition of q | url.go:50:25:50:25 | q |
| url.go:50:2:50:2 | definition of v | url.go:51:14:51:14 | v |
| url.go:50:2:50:26 | ... := ...[0] | url.go:50:2:50:2 | definition of v |
| url.go:51:14:51:14 | v | url.go:52:14:52:14 | v |
| url.go:51:14:51:14 | v [postupdate] | url.go:52:14:52:14 | v |
| url.go:52:14:52:14 | v | url.go:53:9:53:9 | v |
| url.go:52:14:52:14 | v [postupdate] | url.go:53:9:53:9 | v |
| url.go:56:12:56:12 | SSA def(q) | url.go:57:29:57:29 | q |
| url.go:56:12:56:12 | argument corresponding to q | url.go:56:12:56:12 | SSA def(q) |
| url.go:57:2:57:8 | SSA def(joined1) | url.go:58:38:58:44 | joined1 |
| url.go:57:2:57:39 | ... := ...[0] | url.go:57:2:57:8 | SSA def(joined1) |
| url.go:58:2:58:8 | SSA def(joined2) | url.go:59:24:59:30 | joined2 |
| url.go:58:2:58:45 | ... := ...[0] | url.go:58:2:58:8 | SSA def(joined2) |
| url.go:59:2:59:6 | SSA def(asUrl) | url.go:60:15:60:19 | asUrl |
| url.go:59:2:59:31 | ... := ...[0] | url.go:59:2:59:6 | SSA def(asUrl) |
| url.go:60:2:60:10 | SSA def(joinedUrl) | url.go:61:9:61:17 | joinedUrl |
| url.go:60:15:60:37 | call to JoinPath | url.go:60:2:60:10 | SSA def(joinedUrl) |
| url.go:64:13:64:13 | SSA def(q) | url.go:66:27:66:27 | q |
| url.go:64:13:64:13 | argument corresponding to q | url.go:64:13:64:13 | SSA def(q) |
| url.go:65:2:65:9 | SSA def(cleanUrl) | url.go:66:9:66:16 | cleanUrl |
| url.go:65:2:65:48 | ... := ...[0] | url.go:65:2:65:9 | SSA def(cleanUrl) |
| url.go:56:12:56:12 | argument corresponding to q | url.go:56:12:56:12 | definition of q |
| url.go:56:12:56:12 | definition of q | url.go:57:29:57:29 | q |
| url.go:57:2:57:8 | definition of joined1 | url.go:58:38:58:44 | joined1 |
| url.go:57:2:57:39 | ... := ...[0] | url.go:57:2:57:8 | definition of joined1 |
| url.go:58:2:58:8 | definition of joined2 | url.go:59:24:59:30 | joined2 |
| url.go:58:2:58:45 | ... := ...[0] | url.go:58:2:58:8 | definition of joined2 |
| url.go:59:2:59:6 | definition of asUrl | url.go:60:15:60:19 | asUrl |
| url.go:59:2:59:31 | ... := ...[0] | url.go:59:2:59:6 | definition of asUrl |
| url.go:60:2:60:10 | definition of joinedUrl | url.go:61:9:61:17 | joinedUrl |
| url.go:60:15:60:37 | call to JoinPath | url.go:60:2:60:10 | definition of joinedUrl |
| url.go:64:13:64:13 | argument corresponding to q | url.go:64:13:64:13 | definition of q |
| url.go:64:13:64:13 | definition of q | url.go:66:27:66:27 | q |
| url.go:65:2:65:9 | definition of cleanUrl | url.go:66:9:66:16 | cleanUrl |
| url.go:65:2:65:48 | ... := ...[0] | url.go:65:2:65:9 | definition of cleanUrl |

View File

@@ -25,15 +25,15 @@
| result | main.go:53:2:53:22 | call to op2 | main.go:53:2:53:22 | call to op2 |
| result | main.go:53:14:53:21 | call to bump | main.go:53:14:53:21 | call to bump |
| result | tst2.go:10:9:10:26 | call to NewEncoder | tst2.go:10:9:10:26 | call to NewEncoder |
| result | tst2.go:10:9:10:39 | call to Encode | tst2.go:10:2:10:4 | SSA def(err) |
| result | tst.go:9:17:9:33 | call to new | tst.go:9:2:9:12 | SSA def(bytesBuffer) |
| result | tst2.go:10:9:10:39 | call to Encode | tst2.go:10:2:10:4 | definition of err |
| result | tst.go:9:17:9:33 | call to new | tst.go:9:2:9:12 | definition of bytesBuffer |
| result 0 | main.go:51:2:51:14 | call to op | main.go:51:2:51:14 | call to op |
| result 0 | main.go:53:2:53:22 | call to op2 | main.go:53:2:53:22 | call to op2 |
| result 0 | main.go:53:14:53:21 | call to bump | main.go:53:14:53:21 | call to bump |
| result 0 | main.go:54:10:54:15 | call to test | main.go:54:2:54:2 | SSA def(x) |
| result 0 | main.go:56:9:56:15 | call to test2 | main.go:56:2:56:2 | SSA def(x) |
| result 0 | main.go:54:10:54:15 | call to test | main.go:54:2:54:2 | definition of x |
| result 0 | main.go:56:9:56:15 | call to test2 | main.go:56:2:56:2 | definition of x |
| result 0 | tst2.go:10:9:10:26 | call to NewEncoder | tst2.go:10:9:10:26 | call to NewEncoder |
| result 0 | tst2.go:10:9:10:39 | call to Encode | tst2.go:10:2:10:4 | SSA def(err) |
| result 0 | tst.go:9:17:9:33 | call to new | tst.go:9:2:9:12 | SSA def(bytesBuffer) |
| result 1 | main.go:54:10:54:15 | call to test | main.go:54:5:54:5 | SSA def(y) |
| result 1 | main.go:56:9:56:15 | call to test2 | main.go:56:5:56:5 | SSA def(y) |
| result 0 | tst2.go:10:9:10:39 | call to Encode | tst2.go:10:2:10:4 | definition of err |
| result 0 | tst.go:9:17:9:33 | call to new | tst.go:9:2:9:12 | definition of bytesBuffer |
| result 1 | main.go:54:10:54:15 | call to test | main.go:54:5:54:5 | definition of y |
| result 1 | main.go:56:9:56:15 | call to test2 | main.go:56:5:56:5 | definition of y |

View File

@@ -1,14 +1,14 @@
| parameter 0 | main.go:5:1:11:1 | function declaration | main.go:5:9:5:10 | SSA def(op) |
| parameter 0 | main.go:13:1:20:1 | function declaration | main.go:13:10:13:11 | SSA def(op) |
| parameter 0 | main.go:40:1:48:1 | function declaration | main.go:40:12:40:12 | SSA def(b) |
| parameter 0 | reset.go:8:1:16:1 | function declaration | reset.go:8:27:8:27 | SSA def(r) |
| parameter 0 | tst2.go:8:1:12:1 | function declaration | tst2.go:8:12:8:15 | SSA def(data) |
| parameter 0 | tst.go:8:1:11:1 | function declaration | tst.go:8:12:8:17 | SSA def(reader) |
| parameter 0 | main.go:5:1:11:1 | function declaration | main.go:5:9:5:10 | definition of op |
| parameter 0 | main.go:13:1:20:1 | function declaration | main.go:13:10:13:11 | definition of op |
| parameter 0 | main.go:40:1:48:1 | function declaration | main.go:40:12:40:12 | definition of b |
| parameter 0 | reset.go:8:1:16:1 | function declaration | reset.go:8:27:8:27 | definition of r |
| parameter 0 | tst2.go:8:1:12:1 | function declaration | tst2.go:8:12:8:15 | definition of data |
| parameter 0 | tst.go:8:1:11:1 | function declaration | tst.go:8:12:8:17 | definition of reader |
| parameter 0 | tst.go:13:1:13:25 | function declaration | tst.go:13:12:13:13 | initialization of xs |
| parameter 0 | tst.go:15:1:19:1 | function declaration | tst.go:15:12:15:12 | SSA def(x) |
| parameter 1 | main.go:5:1:11:1 | function declaration | main.go:5:20:5:20 | SSA def(x) |
| parameter 1 | main.go:13:1:20:1 | function declaration | main.go:13:21:13:21 | SSA def(x) |
| parameter 1 | tst.go:15:1:19:1 | function declaration | tst.go:15:15:15:15 | SSA def(y) |
| parameter 2 | main.go:5:1:11:1 | function declaration | main.go:5:27:5:27 | SSA def(y) |
| parameter 2 | main.go:13:1:20:1 | function declaration | main.go:13:28:13:28 | SSA def(y) |
| receiver | main.go:26:1:29:1 | function declaration | main.go:26:7:26:7 | SSA def(c) |
| parameter 0 | tst.go:15:1:19:1 | function declaration | tst.go:15:12:15:12 | definition of x |
| parameter 1 | main.go:5:1:11:1 | function declaration | main.go:5:20:5:20 | definition of x |
| parameter 1 | main.go:13:1:20:1 | function declaration | main.go:13:21:13:21 | definition of x |
| parameter 1 | tst.go:15:1:19:1 | function declaration | tst.go:15:15:15:15 | definition of y |
| parameter 2 | main.go:5:1:11:1 | function declaration | main.go:5:27:5:27 | definition of y |
| parameter 2 | main.go:13:1:20:1 | function declaration | main.go:13:28:13:28 | definition of y |
| receiver | main.go:26:1:29:1 | function declaration | main.go:26:7:26:7 | definition of c |

View File

@@ -1,18 +1,18 @@
| main.go:6:2:6:5 | 1 | main.go:14:7:14:7 | 1 |
| main.go:10:2:10:2 | SSA def(x) | main.go:10:7:10:7 | 0 |
| main.go:10:2:10:2 | definition of x | main.go:10:7:10:7 | 0 |
| main.go:10:7:10:7 | 0 | main.go:10:7:10:7 | 0 |
| main.go:11:6:11:6 | SSA def(y) | main.go:10:7:10:7 | 0 |
| main.go:11:6:11:6 | definition of y | main.go:10:7:10:7 | 0 |
| main.go:11:6:11:6 | zero value for y | main.go:10:7:10:7 | 0 |
| main.go:12:2:12:18 | call to Println | main.go:12:2:12:18 | call to Println |
| main.go:12:14:12:14 | x | main.go:10:7:10:7 | 0 |
| main.go:12:17:12:17 | y | main.go:10:7:10:7 | 0 |
| main.go:14:2:14:2 | SSA def(z) | main.go:14:7:14:7 | 1 |
| main.go:14:2:14:2 | definition of z | main.go:14:7:14:7 | 1 |
| main.go:14:7:14:7 | 1 | main.go:14:7:14:7 | 1 |
| main.go:15:2:15:9 | call to bump | main.go:15:2:15:9 | call to bump |
| main.go:16:2:16:21 | call to Println | main.go:16:2:16:21 | call to Println |
| main.go:16:14:16:14 | x | main.go:10:7:10:7 | 0 |
| main.go:16:17:16:17 | y | main.go:10:7:10:7 | 0 |
| main.go:18:2:18:3 | SSA def(ss) | main.go:18:8:18:24 | call to make |
| main.go:18:2:18:3 | definition of ss | main.go:18:8:18:24 | call to make |
| main.go:18:8:18:24 | call to make | main.go:18:8:18:24 | call to make |
| main.go:18:23:18:23 | 3 | main.go:18:23:18:23 | 3 |
| main.go:19:5:19:5 | 2 | main.go:19:5:19:5 | 2 |
@@ -20,20 +20,22 @@
| main.go:20:2:20:16 | call to Println | main.go:20:2:20:16 | call to Println |
| main.go:23:14:23:16 | implicit read of res | main.go:24:8:24:8 | 4 |
| main.go:23:14:23:16 | zero value for res | main.go:10:7:10:7 | 0 |
| main.go:24:2:24:4 | SSA def(res) | main.go:24:8:24:8 | 4 |
| main.go:24:2:24:4 | definition of res | main.go:24:8:24:8 | 4 |
| main.go:24:8:24:8 | 4 | main.go:24:8:24:8 | 4 |
| main.go:28:15:28:17 | implicit read of res | main.go:30:9:30:9 | 6 |
| main.go:28:15:28:17 | zero value for res | main.go:10:7:10:7 | 0 |
| main.go:29:8:29:8 | 5 | main.go:29:8:29:8 | 5 |
| main.go:30:9:30:9 | 6 | main.go:30:9:30:9 | 6 |
| main.go:30:9:30:9 | SSA def(res) | main.go:30:9:30:9 | 6 |
| main.go:30:9:30:9 | definition of res | main.go:30:9:30:9 | 6 |
| main.go:33:15:33:17 | definition of res | main.go:10:7:10:7 | 0 |
| main.go:33:15:33:17 | zero value for res | main.go:10:7:10:7 | 0 |
| main.go:34:2:34:4 | definition of res | main.go:34:8:34:8 | 7 |
| main.go:34:8:34:8 | 7 | main.go:34:8:34:8 | 7 |
| main.go:35:8:37:4 | function call | main.go:35:8:37:4 | function call |
| main.go:36:3:36:5 | SSA def(res) | main.go:36:9:36:9 | 8 |
| main.go:36:3:36:5 | definition of res | main.go:36:9:36:9 | 8 |
| main.go:36:9:36:9 | 8 | main.go:36:9:36:9 | 8 |
| main.go:38:9:38:9 | 9 | main.go:38:9:38:9 | 9 |
| main.go:38:9:38:9 | SSA def(res) | main.go:38:9:38:9 | 9 |
| main.go:38:9:38:9 | definition of res | main.go:38:9:38:9 | 9 |
| regressions.go:5:11:5:31 | call to Sizeof | regressions.go:5:11:5:31 | call to Sizeof |
| regressions.go:7:11:7:15 | false | regressions.go:7:11:7:15 | false |
| regressions.go:9:11:9:12 | !... | regressions.go:11:11:11:14 | true |

View File

@@ -2,5 +2,3 @@
| main.go:7:19:7:23 | ...+... | + | main.go:7:19:7:19 | y | main.go:7:23:7:23 | z |
| main.go:10:14:10:18 | ...+... | + | main.go:10:14:10:14 | x | main.go:10:18:10:18 | y |
| main.go:17:2:17:13 | ... += ... | + | main.go:17:2:17:6 | index expression | main.go:17:11:17:13 | "!" |
| resultParameters.go:4:5:4:17 | ...==... | == | resultParameters.go:4:5:4:12 | selector | resultParameters.go:4:17:4:17 | 0 |
| resultParameters.go:23:5:23:17 | ...==... | == | resultParameters.go:23:5:23:12 | selector | resultParameters.go:23:17:23:17 | 1 |

View File

@@ -1,8 +0,0 @@
| main.go:21:9:21:10 | 23 | Result node with index 0 |
| main.go:21:13:21:14 | 42 | Result node with index 1 |
| resultParameters.go:5:10:5:10 | 0 | Result node with index 0 |
| resultParameters.go:9:10:9:10 | 1 | Result node with index 0 |
| resultParameters.go:11:10:11:10 | 2 | Result node with index 0 |
| resultParameters.go:13:9:13:9 | 3 | Result node with index 0 |
| resultParameters.go:16:26:16:26 | implicit read of r | Result node with index 0 |
| resultParameters.go:21:38:21:38 | implicit read of r | Result node with index 0 |

View File

@@ -1,9 +0,0 @@
/**
* @kind problem
* @id result-node
*/
import go
from DataFlow::ResultNode r
select r, "Result node with index " + r.getIndex()

View File

@@ -1,2 +0,0 @@
query: ResultNode.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -18,5 +18,5 @@ func f() {
}
func test() (int, int) {
return 23, 42 // $ Alert[result-node]
return 23, 42
}

View File

@@ -1,27 +0,0 @@
package main
func multipleReturns(selector int) int {
if selector == 0 {
return 0 // $ Alert[result-node]
}
switch selector {
case 1:
return 1 // $ Alert[result-node]
case 2:
return 2 // $ Alert[result-node]
}
return 3 // $ Alert[result-node]
}
func resultParameter1() (r int) { // $ Alert[result-node] // implicit reads of result parameters are located at the result parameter declaration
r = 0
return
}
func resultParameter2(selector int) (r int) { // $ Alert[result-node] // implicit reads of result parameters are located at the result parameter declaration
r = 0
if selector == 1 {
return 1
}
return
}

View File

@@ -1,132 +1,132 @@
| main.go:22:2:22:6 | SSA def(outer) | main.go:25:7:25:11 | outer |
| main.go:22:11:24:2 | struct literal | main.go:22:2:22:6 | SSA def(outer) |
| main.go:22:11:24:2 | struct literal [postupdate] | main.go:22:2:22:6 | SSA def(outer) |
| main.go:22:2:22:6 | definition of outer | main.go:25:7:25:11 | outer |
| main.go:22:11:24:2 | struct literal | main.go:22:2:22:6 | definition of outer |
| main.go:22:11:24:2 | struct literal [postupdate] | main.go:22:2:22:6 | definition of outer |
| main.go:25:7:25:11 | outer | main.go:26:7:26:11 | outer |
| main.go:26:7:26:11 | outer | main.go:27:7:27:11 | outer |
| main.go:27:7:27:11 | outer | main.go:28:7:28:11 | outer |
| main.go:30:2:30:7 | SSA def(outerp) | main.go:33:7:33:12 | outerp |
| main.go:30:12:32:2 | &... | main.go:30:2:30:7 | SSA def(outerp) |
| main.go:30:12:32:2 | &... [postupdate] | main.go:30:2:30:7 | SSA def(outerp) |
| main.go:30:2:30:7 | definition of outerp | main.go:33:7:33:12 | outerp |
| main.go:30:12:32:2 | &... | main.go:30:2:30:7 | definition of outerp |
| main.go:30:12:32:2 | &... [postupdate] | main.go:30:2:30:7 | definition of outerp |
| main.go:33:7:33:12 | outerp | main.go:34:7:34:12 | outerp |
| main.go:33:7:33:12 | outerp [postupdate] | main.go:34:7:34:12 | outerp |
| main.go:34:7:34:12 | outerp | main.go:35:7:35:12 | outerp |
| main.go:34:7:34:12 | outerp [postupdate] | main.go:35:7:35:12 | outerp |
| main.go:35:7:35:12 | outerp | main.go:36:7:36:12 | outerp |
| main.go:35:7:35:12 | outerp [postupdate] | main.go:36:7:36:12 | outerp |
| main.go:40:2:40:6 | SSA def(outer) | main.go:41:7:41:11 | outer |
| main.go:40:11:40:40 | struct literal | main.go:40:2:40:6 | SSA def(outer) |
| main.go:40:11:40:40 | struct literal [postupdate] | main.go:40:2:40:6 | SSA def(outer) |
| main.go:40:2:40:6 | definition of outer | main.go:41:7:41:11 | outer |
| main.go:40:11:40:40 | struct literal | main.go:40:2:40:6 | definition of outer |
| main.go:40:11:40:40 | struct literal [postupdate] | main.go:40:2:40:6 | definition of outer |
| main.go:41:7:41:11 | outer | main.go:42:7:42:11 | outer |
| main.go:42:7:42:11 | outer | main.go:43:7:43:11 | outer |
| main.go:43:7:43:11 | outer | main.go:44:7:44:11 | outer |
| main.go:46:2:46:7 | SSA def(outerp) | main.go:47:7:47:12 | outerp |
| main.go:46:12:46:42 | &... | main.go:46:2:46:7 | SSA def(outerp) |
| main.go:46:12:46:42 | &... [postupdate] | main.go:46:2:46:7 | SSA def(outerp) |
| main.go:46:2:46:7 | definition of outerp | main.go:47:7:47:12 | outerp |
| main.go:46:12:46:42 | &... | main.go:46:2:46:7 | definition of outerp |
| main.go:46:12:46:42 | &... [postupdate] | main.go:46:2:46:7 | definition of outerp |
| main.go:47:7:47:12 | outerp | main.go:48:7:48:12 | outerp |
| main.go:47:7:47:12 | outerp [postupdate] | main.go:48:7:48:12 | outerp |
| main.go:48:7:48:12 | outerp | main.go:49:7:49:12 | outerp |
| main.go:48:7:48:12 | outerp [postupdate] | main.go:49:7:49:12 | outerp |
| main.go:49:7:49:12 | outerp | main.go:50:7:50:12 | outerp |
| main.go:49:7:49:12 | outerp [postupdate] | main.go:50:7:50:12 | outerp |
| main.go:54:2:54:6 | SSA def(inner) | main.go:55:19:55:23 | inner |
| main.go:54:11:54:25 | struct literal | main.go:54:2:54:6 | SSA def(inner) |
| main.go:54:11:54:25 | struct literal [postupdate] | main.go:54:2:54:6 | SSA def(inner) |
| main.go:55:2:55:7 | SSA def(middle) | main.go:56:17:56:22 | middle |
| main.go:55:12:55:24 | struct literal | main.go:55:2:55:7 | SSA def(middle) |
| main.go:55:12:55:24 | struct literal [postupdate] | main.go:55:2:55:7 | SSA def(middle) |
| main.go:56:2:56:6 | SSA def(outer) | main.go:57:7:57:11 | outer |
| main.go:56:11:56:23 | struct literal | main.go:56:2:56:6 | SSA def(outer) |
| main.go:56:11:56:23 | struct literal [postupdate] | main.go:56:2:56:6 | SSA def(outer) |
| main.go:54:2:54:6 | definition of inner | main.go:55:19:55:23 | inner |
| main.go:54:11:54:25 | struct literal | main.go:54:2:54:6 | definition of inner |
| main.go:54:11:54:25 | struct literal [postupdate] | main.go:54:2:54:6 | definition of inner |
| main.go:55:2:55:7 | definition of middle | main.go:56:17:56:22 | middle |
| main.go:55:12:55:24 | struct literal | main.go:55:2:55:7 | definition of middle |
| main.go:55:12:55:24 | struct literal [postupdate] | main.go:55:2:55:7 | definition of middle |
| main.go:56:2:56:6 | definition of outer | main.go:57:7:57:11 | outer |
| main.go:56:11:56:23 | struct literal | main.go:56:2:56:6 | definition of outer |
| main.go:56:11:56:23 | struct literal [postupdate] | main.go:56:2:56:6 | definition of outer |
| main.go:57:7:57:11 | outer | main.go:58:7:58:11 | outer |
| main.go:58:7:58:11 | outer | main.go:59:7:59:11 | outer |
| main.go:59:7:59:11 | outer | main.go:60:7:60:11 | outer |
| main.go:62:2:62:7 | SSA def(innerp) | main.go:63:20:63:25 | innerp |
| main.go:62:12:62:26 | struct literal | main.go:62:2:62:7 | SSA def(innerp) |
| main.go:62:12:62:26 | struct literal [postupdate] | main.go:62:2:62:7 | SSA def(innerp) |
| main.go:63:2:63:8 | SSA def(middlep) | main.go:64:18:64:24 | middlep |
| main.go:63:13:63:26 | struct literal | main.go:63:2:63:8 | SSA def(middlep) |
| main.go:63:13:63:26 | struct literal [postupdate] | main.go:63:2:63:8 | SSA def(middlep) |
| main.go:64:2:64:7 | SSA def(outerp) | main.go:65:7:65:12 | outerp |
| main.go:64:12:64:25 | struct literal | main.go:64:2:64:7 | SSA def(outerp) |
| main.go:64:12:64:25 | struct literal [postupdate] | main.go:64:2:64:7 | SSA def(outerp) |
| main.go:62:2:62:7 | definition of innerp | main.go:63:20:63:25 | innerp |
| main.go:62:12:62:26 | struct literal | main.go:62:2:62:7 | definition of innerp |
| main.go:62:12:62:26 | struct literal [postupdate] | main.go:62:2:62:7 | definition of innerp |
| main.go:63:2:63:8 | definition of middlep | main.go:64:18:64:24 | middlep |
| main.go:63:13:63:26 | struct literal | main.go:63:2:63:8 | definition of middlep |
| main.go:63:13:63:26 | struct literal [postupdate] | main.go:63:2:63:8 | definition of middlep |
| main.go:64:2:64:7 | definition of outerp | main.go:65:7:65:12 | outerp |
| main.go:64:12:64:25 | struct literal | main.go:64:2:64:7 | definition of outerp |
| main.go:64:12:64:25 | struct literal [postupdate] | main.go:64:2:64:7 | definition of outerp |
| main.go:65:7:65:12 | outerp | main.go:66:7:66:12 | outerp |
| main.go:66:7:66:12 | outerp | main.go:67:7:67:12 | outerp |
| main.go:67:7:67:12 | outerp | main.go:68:7:68:12 | outerp |
| main.go:72:2:72:6 | SSA def(inner) | main.go:73:26:73:30 | inner |
| main.go:72:11:72:25 | struct literal | main.go:72:2:72:6 | SSA def(inner) |
| main.go:72:11:72:25 | struct literal [postupdate] | main.go:72:2:72:6 | SSA def(inner) |
| main.go:73:2:73:7 | SSA def(middle) | main.go:74:25:74:30 | middle |
| main.go:73:12:73:31 | struct literal | main.go:73:2:73:7 | SSA def(middle) |
| main.go:73:12:73:31 | struct literal [postupdate] | main.go:73:2:73:7 | SSA def(middle) |
| main.go:74:2:74:6 | SSA def(outer) | main.go:75:7:75:11 | outer |
| main.go:74:11:74:31 | struct literal | main.go:74:2:74:6 | SSA def(outer) |
| main.go:74:11:74:31 | struct literal [postupdate] | main.go:74:2:74:6 | SSA def(outer) |
| main.go:72:2:72:6 | definition of inner | main.go:73:26:73:30 | inner |
| main.go:72:11:72:25 | struct literal | main.go:72:2:72:6 | definition of inner |
| main.go:72:11:72:25 | struct literal [postupdate] | main.go:72:2:72:6 | definition of inner |
| main.go:73:2:73:7 | definition of middle | main.go:74:25:74:30 | middle |
| main.go:73:12:73:31 | struct literal | main.go:73:2:73:7 | definition of middle |
| main.go:73:12:73:31 | struct literal [postupdate] | main.go:73:2:73:7 | definition of middle |
| main.go:74:2:74:6 | definition of outer | main.go:75:7:75:11 | outer |
| main.go:74:11:74:31 | struct literal | main.go:74:2:74:6 | definition of outer |
| main.go:74:11:74:31 | struct literal [postupdate] | main.go:74:2:74:6 | definition of outer |
| main.go:75:7:75:11 | outer | main.go:76:7:76:11 | outer |
| main.go:76:7:76:11 | outer | main.go:77:7:77:11 | outer |
| main.go:77:7:77:11 | outer | main.go:78:7:78:11 | outer |
| main.go:80:2:80:7 | SSA def(innerp) | main.go:81:27:81:32 | innerp |
| main.go:80:12:80:26 | struct literal | main.go:80:2:80:7 | SSA def(innerp) |
| main.go:80:12:80:26 | struct literal [postupdate] | main.go:80:2:80:7 | SSA def(innerp) |
| main.go:81:2:81:8 | SSA def(middlep) | main.go:82:26:82:32 | middlep |
| main.go:81:13:81:33 | struct literal | main.go:81:2:81:8 | SSA def(middlep) |
| main.go:81:13:81:33 | struct literal [postupdate] | main.go:81:2:81:8 | SSA def(middlep) |
| main.go:82:2:82:7 | SSA def(outerp) | main.go:83:7:83:12 | outerp |
| main.go:82:12:82:33 | struct literal | main.go:82:2:82:7 | SSA def(outerp) |
| main.go:82:12:82:33 | struct literal [postupdate] | main.go:82:2:82:7 | SSA def(outerp) |
| main.go:80:2:80:7 | definition of innerp | main.go:81:27:81:32 | innerp |
| main.go:80:12:80:26 | struct literal | main.go:80:2:80:7 | definition of innerp |
| main.go:80:12:80:26 | struct literal [postupdate] | main.go:80:2:80:7 | definition of innerp |
| main.go:81:2:81:8 | definition of middlep | main.go:82:26:82:32 | middlep |
| main.go:81:13:81:33 | struct literal | main.go:81:2:81:8 | definition of middlep |
| main.go:81:13:81:33 | struct literal [postupdate] | main.go:81:2:81:8 | definition of middlep |
| main.go:82:2:82:7 | definition of outerp | main.go:83:7:83:12 | outerp |
| main.go:82:12:82:33 | struct literal | main.go:82:2:82:7 | definition of outerp |
| main.go:82:12:82:33 | struct literal [postupdate] | main.go:82:2:82:7 | definition of outerp |
| main.go:83:7:83:12 | outerp | main.go:84:7:84:12 | outerp |
| main.go:84:7:84:12 | outerp | main.go:85:7:85:12 | outerp |
| main.go:85:7:85:12 | outerp | main.go:86:7:86:12 | outerp |
| main.go:90:6:90:10 | SSA def(outer) | main.go:91:2:91:6 | outer |
| main.go:90:6:90:10 | zero value for outer | main.go:90:6:90:10 | SSA def(outer) |
| main.go:90:6:90:10 | definition of outer | main.go:91:2:91:6 | outer |
| main.go:90:6:90:10 | zero value for outer | main.go:90:6:90:10 | definition of outer |
| main.go:91:2:91:6 | outer | main.go:92:7:92:11 | outer |
| main.go:91:2:91:6 | outer [postupdate] | main.go:92:7:92:11 | outer |
| main.go:92:7:92:11 | outer | main.go:93:7:93:11 | outer |
| main.go:93:7:93:11 | outer | main.go:94:7:94:11 | outer |
| main.go:94:7:94:11 | outer | main.go:95:7:95:11 | outer |
| main.go:97:6:97:11 | SSA def(outerp) | main.go:98:2:98:7 | outerp |
| main.go:97:6:97:11 | zero value for outerp | main.go:97:6:97:11 | SSA def(outerp) |
| main.go:97:6:97:11 | definition of outerp | main.go:98:2:98:7 | outerp |
| main.go:97:6:97:11 | zero value for outerp | main.go:97:6:97:11 | definition of outerp |
| main.go:98:2:98:7 | outerp | main.go:99:7:99:12 | outerp |
| main.go:98:2:98:7 | outerp [postupdate] | main.go:99:7:99:12 | outerp |
| main.go:99:7:99:12 | outerp | main.go:100:7:100:12 | outerp |
| main.go:100:7:100:12 | outerp | main.go:101:7:101:12 | outerp |
| main.go:101:7:101:12 | outerp | main.go:102:7:102:12 | outerp |
| main.go:106:6:106:10 | SSA def(outer) | main.go:107:2:107:6 | outer |
| main.go:106:6:106:10 | zero value for outer | main.go:106:6:106:10 | SSA def(outer) |
| main.go:106:6:106:10 | definition of outer | main.go:107:2:107:6 | outer |
| main.go:106:6:106:10 | zero value for outer | main.go:106:6:106:10 | definition of outer |
| main.go:107:2:107:6 | outer | main.go:108:7:108:11 | outer |
| main.go:107:2:107:6 | outer [postupdate] | main.go:108:7:108:11 | outer |
| main.go:108:7:108:11 | outer | main.go:109:7:109:11 | outer |
| main.go:109:7:109:11 | outer | main.go:110:7:110:11 | outer |
| main.go:110:7:110:11 | outer | main.go:111:7:111:11 | outer |
| main.go:113:6:113:11 | SSA def(outerp) | main.go:114:2:114:7 | outerp |
| main.go:113:6:113:11 | zero value for outerp | main.go:113:6:113:11 | SSA def(outerp) |
| main.go:113:6:113:11 | definition of outerp | main.go:114:2:114:7 | outerp |
| main.go:113:6:113:11 | zero value for outerp | main.go:113:6:113:11 | definition of outerp |
| main.go:114:2:114:7 | outerp | main.go:115:7:115:12 | outerp |
| main.go:114:2:114:7 | outerp [postupdate] | main.go:115:7:115:12 | outerp |
| main.go:115:7:115:12 | outerp | main.go:116:7:116:12 | outerp |
| main.go:116:7:116:12 | outerp | main.go:117:7:117:12 | outerp |
| main.go:117:7:117:12 | outerp | main.go:118:7:118:12 | outerp |
| main.go:122:6:122:10 | SSA def(outer) | main.go:123:2:123:6 | outer |
| main.go:122:6:122:10 | zero value for outer | main.go:122:6:122:10 | SSA def(outer) |
| main.go:122:6:122:10 | definition of outer | main.go:123:2:123:6 | outer |
| main.go:122:6:122:10 | zero value for outer | main.go:122:6:122:10 | definition of outer |
| main.go:123:2:123:6 | outer | main.go:124:7:124:11 | outer |
| main.go:123:2:123:6 | outer [postupdate] | main.go:124:7:124:11 | outer |
| main.go:124:7:124:11 | outer | main.go:125:7:125:11 | outer |
| main.go:125:7:125:11 | outer | main.go:126:7:126:11 | outer |
| main.go:126:7:126:11 | outer | main.go:127:7:127:11 | outer |
| main.go:129:6:129:11 | SSA def(outerp) | main.go:130:2:130:7 | outerp |
| main.go:129:6:129:11 | zero value for outerp | main.go:129:6:129:11 | SSA def(outerp) |
| main.go:129:6:129:11 | definition of outerp | main.go:130:2:130:7 | outerp |
| main.go:129:6:129:11 | zero value for outerp | main.go:129:6:129:11 | definition of outerp |
| main.go:130:2:130:7 | outerp | main.go:131:7:131:12 | outerp |
| main.go:130:2:130:7 | outerp [postupdate] | main.go:131:7:131:12 | outerp |
| main.go:131:7:131:12 | outerp | main.go:132:7:132:12 | outerp |
| main.go:132:7:132:12 | outerp | main.go:133:7:133:12 | outerp |
| main.go:133:7:133:12 | outerp | main.go:134:7:134:12 | outerp |
| main.go:138:6:138:10 | SSA def(outer) | main.go:139:2:139:6 | outer |
| main.go:138:6:138:10 | zero value for outer | main.go:138:6:138:10 | SSA def(outer) |
| main.go:138:6:138:10 | definition of outer | main.go:139:2:139:6 | outer |
| main.go:138:6:138:10 | zero value for outer | main.go:138:6:138:10 | definition of outer |
| main.go:139:2:139:6 | outer | main.go:140:7:140:11 | outer |
| main.go:139:2:139:6 | outer [postupdate] | main.go:140:7:140:11 | outer |
| main.go:140:7:140:11 | outer | main.go:141:7:141:11 | outer |
| main.go:141:7:141:11 | outer | main.go:142:7:142:11 | outer |
| main.go:142:7:142:11 | outer | main.go:143:7:143:11 | outer |
| main.go:145:6:145:11 | SSA def(outerp) | main.go:146:2:146:7 | outerp |
| main.go:145:6:145:11 | zero value for outerp | main.go:145:6:145:11 | SSA def(outerp) |
| main.go:145:6:145:11 | definition of outerp | main.go:146:2:146:7 | outerp |
| main.go:145:6:145:11 | zero value for outerp | main.go:145:6:145:11 | definition of outerp |
| main.go:146:2:146:7 | outerp | main.go:147:7:147:12 | outerp |
| main.go:146:2:146:7 | outerp [postupdate] | main.go:147:7:147:12 | outerp |
| main.go:147:7:147:12 | outerp | main.go:148:7:148:12 | outerp |

View File

@@ -1,5 +1,3 @@
reverseRead
| main.go:97:2:97:8 | wrapper | Origin of readStep is missing a PostUpdateNode. |
| main.go:105:2:105:8 | wrapper | Origin of readStep is missing a PostUpdateNode. |
| main.go:114:2:114:8 | wrapper | Origin of readStep is missing a PostUpdateNode. |
| main.go:135:2:135:2 | p | Origin of readStep is missing a PostUpdateNode. |
| main.go:117:2:117:2 | p | Origin of readStep is missing a PostUpdateNode. |

View File

@@ -1,42 +1,34 @@
| main.go:15:12:15:12 | x | main.go:13:6:13:6 | SSA def(x) | main.go:13:6:13:6 | x |
| main.go:15:15:15:15 | y | main.go:14:2:14:2 | SSA def(y) | main.go:14:2:14:2 | y |
| main.go:17:3:17:3 | y | main.go:14:2:14:2 | SSA def(y) | main.go:14:2:14:2 | y |
| main.go:19:12:19:12 | x | main.go:13:6:13:6 | SSA def(x) | main.go:13:6:13:6 | x |
| main.go:19:15:19:15 | y | main.go:19:2:19:10 | SSA phi(y) | main.go:14:2:14:2 | y |
| main.go:21:7:21:7 | y | main.go:19:2:19:10 | SSA phi(y) | main.go:14:2:14:2 | y |
| main.go:23:12:23:12 | x | main.go:23:2:23:10 | SSA phi(x) | main.go:13:6:13:6 | x |
| main.go:23:15:23:15 | y | main.go:19:2:19:10 | SSA phi(y) | main.go:14:2:14:2 | y |
| main.go:27:10:27:10 | x | main.go:26:10:26:10 | SSA def(x) | main.go:26:10:26:10 | x |
| main.go:29:10:29:10 | b | main.go:27:5:27:5 | SSA def(b) | main.go:27:5:27:5 | b |
| main.go:29:13:29:13 | a | main.go:27:2:27:2 | SSA def(a) | main.go:27:2:27:2 | a |
| main.go:31:9:31:9 | a | main.go:31:9:31:9 | SSA phi(a) | main.go:27:2:27:2 | a |
| main.go:31:12:31:12 | b | main.go:31:9:31:9 | SSA phi(b) | main.go:27:5:27:5 | b |
| main.go:35:3:35:3 | x | main.go:34:11:34:11 | SSA def(x) | main.go:34:11:34:11 | x |
| main.go:40:10:40:10 | x | main.go:39:2:39:2 | SSA def(x) | main.go:39:2:39:2 | x |
| main.go:42:8:42:10 | ptr | main.go:40:2:40:4 | SSA def(ptr) | main.go:40:2:40:4 | ptr |
| main.go:44:12:44:12 | x | main.go:39:2:39:2 | SSA def(x) | main.go:39:2:39:2 | x |
| main.go:47:13:47:18 | implicit read of result | main.go:48:2:48:7 | SSA def(result) | main.go:47:13:47:18 | result |
| main.go:52:14:52:19 | implicit read of result | main.go:52:14:52:19 | SSA def(result) | main.go:52:14:52:19 | result |
| main.go:61:12:61:12 | x | main.go:58:6:58:9 | SSA phi(x) | main.go:57:6:57:6 | x |
| main.go:64:16:64:16 | i | main.go:65:6:65:9 | SSA phi(i) | main.go:64:6:64:6 | i |
| main.go:70:12:70:12 | y | main.go:65:6:65:9 | SSA phi(y) | main.go:63:2:63:2 | y |
| main.go:73:16:73:16 | i | main.go:74:3:74:3 | SSA phi(i) | main.go:73:6:73:6 | i |
| main.go:79:12:79:12 | z | main.go:74:3:74:3 | SSA def(z) | main.go:72:2:72:2 | z |
| main.go:82:18:82:18 | implicit read of a | main.go:84:5:84:5 | SSA def(a) | main.go:82:18:82:18 | a |
| main.go:82:25:82:25 | implicit read of b | main.go:82:25:82:25 | SSA def(b) | main.go:82:25:82:25 | b |
| main.go:84:9:84:9 | x | main.go:83:2:83:2 | SSA def(x) | main.go:83:2:83:2 | x |
| main.go:84:15:84:15 | x | main.go:83:2:83:2 | SSA def(x) | main.go:83:2:83:2 | x |
| main.go:97:2:97:8 | wrapper | main.go:95:22:95:28 | SSA def(wrapper) | main.go:95:22:95:28 | wrapper |
| main.go:100:9:100:9 | x | main.go:97:2:99:3 | SSA def(x) | main.go:96:2:96:2 | x |
| main.go:105:2:105:8 | wrapper | main.go:103:20:103:26 | SSA def(wrapper) | main.go:103:20:103:26 | wrapper |
| main.go:106:8:106:8 | x | main.go:105:16:108:2 | SSA def(x) | main.go:104:2:104:2 | x |
| main.go:107:7:107:7 | y | main.go:106:3:106:3 | SSA def(y) | main.go:106:3:106:3 | y |
| main.go:109:9:109:9 | x | main.go:104:2:104:2 | SSA def(x) | main.go:104:2:104:2 | x |
| main.go:114:2:114:8 | wrapper | main.go:112:29:112:35 | SSA def(wrapper) | main.go:112:29:112:35 | wrapper |
| main.go:115:8:115:8 | x | main.go:114:16:117:2 | SSA def(x) | main.go:113:2:113:2 | x |
| main.go:116:7:116:7 | y | main.go:115:3:115:3 | SSA def(y) | main.go:115:3:115:3 | y |
| main.go:118:9:118:9 | x | main.go:114:2:117:3 | SSA def(x) | main.go:113:2:113:2 | x |
| main.go:135:2:135:2 | p | main.go:135:2:135:2 | SSA phi(p) | main.go:128:6:128:6 | p |
| main.go:137:12:137:12 | p | main.go:135:2:135:2 | SSA phi(p) | main.go:128:6:128:6 | p |
| main.go:137:17:137:17 | p | main.go:135:2:135:2 | SSA phi(p) | main.go:128:6:128:6 | p |
| main.go:137:24:137:24 | p | main.go:135:2:135:2 | SSA phi(p) | main.go:128:6:128:6 | p |
| main.go:15:12:15:12 | x | main.go:13:6:13:6 | definition of x | main.go:13:6:13:6 | x |
| main.go:15:15:15:15 | y | main.go:14:2:14:2 | definition of y | main.go:14:2:14:2 | y |
| main.go:17:3:17:3 | y | main.go:14:2:14:2 | definition of y | main.go:14:2:14:2 | y |
| main.go:19:12:19:12 | x | main.go:13:6:13:6 | definition of x | main.go:13:6:13:6 | x |
| main.go:19:15:19:15 | y | main.go:19:2:19:10 | y = phi(def@14:2, def@17:3) | main.go:14:2:14:2 | y |
| main.go:21:7:21:7 | y | main.go:19:2:19:10 | y = phi(def@14:2, def@17:3) | main.go:14:2:14:2 | y |
| main.go:23:12:23:12 | x | main.go:23:2:23:10 | x = phi(def@13:6, def@21:3) | main.go:13:6:13:6 | x |
| main.go:23:15:23:15 | y | main.go:19:2:19:10 | y = phi(def@14:2, def@17:3) | main.go:14:2:14:2 | y |
| main.go:27:10:27:10 | x | main.go:26:10:26:10 | definition of x | main.go:26:10:26:10 | x |
| main.go:29:10:29:10 | b | main.go:27:5:27:5 | definition of b | main.go:27:5:27:5 | b |
| main.go:29:13:29:13 | a | main.go:27:2:27:2 | definition of a | main.go:27:2:27:2 | a |
| main.go:31:9:31:9 | a | main.go:31:9:31:9 | a = phi(def@27:2, def@29:3) | main.go:27:2:27:2 | a |
| main.go:31:12:31:12 | b | main.go:31:9:31:9 | b = phi(def@27:5, def@29:6) | main.go:27:5:27:5 | b |
| main.go:35:3:35:3 | x | main.go:34:11:34:11 | definition of x | main.go:34:11:34:11 | x |
| main.go:40:10:40:10 | x | main.go:39:2:39:2 | definition of x | main.go:39:2:39:2 | x |
| main.go:42:8:42:10 | ptr | main.go:40:2:40:4 | definition of ptr | main.go:40:2:40:4 | ptr |
| main.go:44:12:44:12 | x | main.go:39:2:39:2 | definition of x | main.go:39:2:39:2 | x |
| main.go:47:13:47:18 | implicit read of result | main.go:48:2:48:7 | definition of result | main.go:47:13:47:18 | result |
| main.go:52:14:52:19 | implicit read of result | main.go:52:14:52:19 | definition of result | main.go:52:14:52:19 | result |
| main.go:61:12:61:12 | x | main.go:58:6:58:9 | x = phi(def@57:6, def@59:3) | main.go:57:6:57:6 | x |
| main.go:64:16:64:16 | i | main.go:65:6:65:9 | i = phi(def@64:16, def@64:6) | main.go:64:6:64:6 | i |
| main.go:70:12:70:12 | y | main.go:65:6:65:9 | y = phi(def@63:2, def@68:3) | main.go:63:2:63:2 | y |
| main.go:73:16:73:16 | i | main.go:74:3:74:3 | i = phi(def@73:16, def@73:6) | main.go:73:6:73:6 | i |
| main.go:79:12:79:12 | z | main.go:74:3:74:3 | definition of z | main.go:72:2:72:2 | z |
| main.go:82:18:82:18 | implicit read of a | main.go:84:5:84:5 | definition of a | main.go:82:18:82:18 | a |
| main.go:82:25:82:25 | implicit read of b | main.go:82:25:82:25 | definition of b | main.go:82:25:82:25 | b |
| main.go:84:9:84:9 | x | main.go:83:2:83:2 | definition of x | main.go:83:2:83:2 | x |
| main.go:84:15:84:15 | x | main.go:83:2:83:2 | definition of x | main.go:83:2:83:2 | x |
| main.go:97:2:97:8 | wrapper | main.go:95:22:95:28 | definition of wrapper | main.go:95:22:95:28 | wrapper |
| main.go:100:9:100:9 | x | main.go:97:2:99:3 | capture variable x | main.go:96:2:96:2 | x |
| main.go:117:2:117:2 | p | main.go:117:2:117:2 | p = phi(def@112:3, def@114:3) | main.go:110:6:110:6 | p |
| main.go:119:12:119:12 | p | main.go:117:2:117:2 | p = phi(def@112:3, def@114:3) | main.go:110:6:110:6 | p |
| main.go:119:17:119:17 | p | main.go:117:2:117:2 | p = phi(def@112:3, def@114:3) | main.go:110:6:110:6 | p |
| main.go:119:24:119:24 | p | main.go:117:2:117:2 | p = phi(def@112:3, def@114:3) | main.go:110:6:110:6 | p |

View File

@@ -1,51 +1,41 @@
| main.go:13:6:13:6 | SSA def(x) |
| main.go:14:2:14:2 | SSA def(y) |
| main.go:17:3:17:3 | SSA def(y) |
| main.go:19:2:19:10 | SSA phi(y) |
| main.go:21:3:21:3 | SSA def(x) |
| main.go:23:2:23:10 | SSA phi(x) |
| main.go:26:10:26:10 | SSA def(x) |
| main.go:27:2:27:2 | SSA def(a) |
| main.go:27:5:27:5 | SSA def(b) |
| main.go:29:3:29:3 | SSA def(a) |
| main.go:29:6:29:6 | SSA def(b) |
| main.go:31:9:31:9 | SSA phi(a) |
| main.go:31:9:31:9 | SSA phi(b) |
| main.go:34:11:34:11 | SSA def(x) |
| main.go:39:2:39:2 | SSA def(x) |
| main.go:40:2:40:4 | SSA def(ptr) |
| main.go:48:2:48:7 | SSA def(result) |
| main.go:52:14:52:19 | SSA def(result) |
| main.go:57:6:57:6 | SSA def(x) |
| main.go:58:6:58:9 | SSA phi(x) |
| main.go:59:3:59:3 | SSA def(x) |
| main.go:63:2:63:2 | SSA def(y) |
| main.go:64:6:64:6 | SSA def(i) |
| main.go:64:16:64:18 | SSA def(i) |
| main.go:65:6:65:9 | SSA phi(i) |
| main.go:65:6:65:9 | SSA phi(y) |
| main.go:68:3:68:3 | SSA def(y) |
| main.go:73:6:73:6 | SSA def(i) |
| main.go:73:16:73:18 | SSA def(i) |
| main.go:74:3:74:3 | SSA def(z) |
| main.go:74:3:74:3 | SSA phi(i) |
| main.go:82:25:82:25 | SSA def(b) |
| main.go:83:2:83:2 | SSA def(x) |
| main.go:84:5:84:5 | SSA def(a) |
| main.go:95:22:95:28 | SSA def(wrapper) |
| main.go:96:2:96:2 | SSA def(x) |
| main.go:97:2:99:3 | SSA def(x) |
| main.go:98:3:98:3 | SSA def(x) |
| main.go:103:20:103:26 | SSA def(wrapper) |
| main.go:104:2:104:2 | SSA def(x) |
| main.go:105:16:108:2 | SSA def(x) |
| main.go:106:3:106:3 | SSA def(y) |
| main.go:112:29:112:35 | SSA def(wrapper) |
| main.go:113:2:113:2 | SSA def(x) |
| main.go:114:2:117:3 | SSA def(x) |
| main.go:114:16:117:2 | SSA def(x) |
| main.go:115:3:115:3 | SSA def(y) |
| main.go:116:3:116:3 | SSA def(x) |
| main.go:130:3:130:3 | SSA def(p) |
| main.go:132:3:132:3 | SSA def(p) |
| main.go:135:2:135:2 | SSA phi(p) |
| main.go:13:6:13:6 | definition of x |
| main.go:14:2:14:2 | definition of y |
| main.go:17:3:17:3 | definition of y |
| main.go:19:2:19:10 | y = phi(def@14:2, def@17:3) |
| main.go:21:3:21:3 | definition of x |
| main.go:23:2:23:10 | x = phi(def@13:6, def@21:3) |
| main.go:26:10:26:10 | definition of x |
| main.go:27:2:27:2 | definition of a |
| main.go:27:5:27:5 | definition of b |
| main.go:29:3:29:3 | definition of a |
| main.go:29:6:29:6 | definition of b |
| main.go:31:9:31:9 | a = phi(def@27:2, def@29:3) |
| main.go:31:9:31:9 | b = phi(def@27:5, def@29:6) |
| main.go:34:11:34:11 | definition of x |
| main.go:39:2:39:2 | definition of x |
| main.go:40:2:40:4 | definition of ptr |
| main.go:48:2:48:7 | definition of result |
| main.go:52:14:52:19 | definition of result |
| main.go:57:6:57:6 | definition of x |
| main.go:58:6:58:9 | x = phi(def@57:6, def@59:3) |
| main.go:59:3:59:3 | definition of x |
| main.go:63:2:63:2 | definition of y |
| main.go:64:6:64:6 | definition of i |
| main.go:64:16:64:18 | definition of i |
| main.go:65:6:65:9 | i = phi(def@64:16, def@64:6) |
| main.go:65:6:65:9 | y = phi(def@63:2, def@68:3) |
| main.go:68:3:68:3 | definition of y |
| main.go:73:6:73:6 | definition of i |
| main.go:73:16:73:18 | definition of i |
| main.go:74:3:74:3 | definition of z |
| main.go:74:3:74:3 | i = phi(def@73:16, def@73:6) |
| main.go:82:25:82:25 | definition of b |
| main.go:83:2:83:2 | definition of x |
| main.go:84:5:84:5 | definition of a |
| main.go:95:22:95:28 | definition of wrapper |
| main.go:96:2:96:2 | definition of x |
| main.go:97:2:99:3 | capture variable x |
| main.go:98:3:98:3 | definition of x |
| main.go:112:3:112:3 | definition of p |
| main.go:114:3:114:3 | definition of p |
| main.go:117:2:117:2 | p = phi(def@112:3, def@114:3) |

View File

@@ -1,58 +1,46 @@
| main.go:13:6:13:6 | (SSA def(x)) | x |
| main.go:14:2:14:2 | (SSA def(y)) | y |
| main.go:17:3:17:3 | (SSA def(y)) | y |
| main.go:19:2:19:10 | (SSA phi(y)) | y |
| main.go:21:3:21:3 | (SSA def(x)) | x |
| main.go:23:2:23:10 | (SSA phi(x)) | x |
| main.go:26:10:26:10 | (SSA def(x)) | x |
| main.go:27:2:27:2 | (SSA def(a)) | a |
| main.go:27:5:27:5 | (SSA def(b)) | b |
| main.go:29:3:29:3 | (SSA def(a)) | a |
| main.go:29:6:29:6 | (SSA def(b)) | b |
| main.go:31:9:31:9 | (SSA phi(a)) | a |
| main.go:31:9:31:9 | (SSA phi(b)) | b |
| main.go:34:11:34:11 | (SSA def(x)) | x |
| main.go:39:2:39:2 | (SSA def(x)) | x |
| main.go:40:2:40:4 | (SSA def(ptr)) | ptr |
| main.go:48:2:48:7 | (SSA def(result)) | result |
| main.go:52:14:52:19 | (SSA def(result)) | result |
| main.go:57:6:57:6 | (SSA def(x)) | x |
| main.go:58:6:58:9 | (SSA phi(x)) | x |
| main.go:59:3:59:3 | (SSA def(x)) | x |
| main.go:63:2:63:2 | (SSA def(y)) | y |
| main.go:64:6:64:6 | (SSA def(i)) | i |
| main.go:64:16:64:18 | (SSA def(i)) | i |
| main.go:65:6:65:9 | (SSA phi(i)) | i |
| main.go:65:6:65:9 | (SSA phi(y)) | y |
| main.go:68:3:68:3 | (SSA def(y)) | y |
| main.go:73:6:73:6 | (SSA def(i)) | i |
| main.go:73:16:73:18 | (SSA def(i)) | i |
| main.go:74:3:74:3 | (SSA def(z)) | z |
| main.go:74:3:74:3 | (SSA phi(i)) | i |
| main.go:82:25:82:25 | (SSA def(b)) | b |
| main.go:83:2:83:2 | (SSA def(x)) | x |
| main.go:84:5:84:5 | (SSA def(a)) | a |
| main.go:95:22:95:28 | (SSA def(wrapper)) | wrapper |
| main.go:95:22:95:28 | (SSA def(wrapper)).s | wrapper.s |
| main.go:96:2:96:2 | (SSA def(x)) | x |
| main.go:97:2:99:3 | (SSA def(x)) | x |
| main.go:98:3:98:3 | (SSA def(x)) | x |
| main.go:103:20:103:26 | (SSA def(wrapper)) | wrapper |
| main.go:103:20:103:26 | (SSA def(wrapper)).s | wrapper.s |
| main.go:104:2:104:2 | (SSA def(x)) | x |
| main.go:105:16:108:2 | (SSA def(x)) | x |
| main.go:106:3:106:3 | (SSA def(y)) | y |
| main.go:112:29:112:35 | (SSA def(wrapper)) | wrapper |
| main.go:112:29:112:35 | (SSA def(wrapper)).s | wrapper.s |
| main.go:113:2:113:2 | (SSA def(x)) | x |
| main.go:114:2:117:3 | (SSA def(x)) | x |
| main.go:114:16:117:2 | (SSA def(x)) | x |
| main.go:115:3:115:3 | (SSA def(y)) | y |
| main.go:116:3:116:3 | (SSA def(x)) | x |
| main.go:130:3:130:3 | (SSA def(p)) | p |
| main.go:132:3:132:3 | (SSA def(p)) | p |
| main.go:135:2:135:2 | (SSA phi(p)) | p |
| main.go:135:2:135:2 | (SSA phi(p)).a | p.a |
| main.go:135:2:135:2 | (SSA phi(p)).b | p.b |
| main.go:135:2:135:2 | (SSA phi(p)).b.a | p.b.a |
| main.go:135:2:135:2 | (SSA phi(p)).c | p.c |
| main.go:13:6:13:6 | (def@13:6) | x |
| main.go:14:2:14:2 | (def@14:2) | y |
| main.go:17:3:17:3 | (def@17:3) | y |
| main.go:19:2:19:10 | (phi@19:2) | y |
| main.go:21:3:21:3 | (def@21:3) | x |
| main.go:23:2:23:10 | (phi@23:2) | x |
| main.go:26:10:26:10 | (def@26:10) | x |
| main.go:27:2:27:2 | (def@27:2) | a |
| main.go:27:5:27:5 | (def@27:5) | b |
| main.go:29:3:29:3 | (def@29:3) | a |
| main.go:29:6:29:6 | (def@29:6) | b |
| main.go:31:9:31:9 | (phi@31:9) | a |
| main.go:31:9:31:9 | (phi@31:9) | b |
| main.go:34:11:34:11 | (def@34:11) | x |
| main.go:39:2:39:2 | (def@39:2) | x |
| main.go:40:2:40:4 | (def@40:2) | ptr |
| main.go:48:2:48:7 | (def@48:2) | result |
| main.go:52:14:52:19 | (def@52:14) | result |
| main.go:57:6:57:6 | (def@57:6) | x |
| main.go:58:6:58:9 | (phi@58:6) | x |
| main.go:59:3:59:3 | (def@59:3) | x |
| main.go:63:2:63:2 | (def@63:2) | y |
| main.go:64:6:64:6 | (def@64:6) | i |
| main.go:64:16:64:18 | (def@64:16) | i |
| main.go:65:6:65:9 | (phi@65:6) | i |
| main.go:65:6:65:9 | (phi@65:6) | y |
| main.go:68:3:68:3 | (def@68:3) | y |
| main.go:73:6:73:6 | (def@73:6) | i |
| main.go:73:16:73:18 | (def@73:16) | i |
| main.go:74:3:74:3 | (def@74:3) | z |
| main.go:74:3:74:3 | (phi@74:3) | i |
| main.go:82:25:82:25 | (def@82:25) | b |
| main.go:83:2:83:2 | (def@83:2) | x |
| main.go:84:5:84:5 | (def@84:5) | a |
| main.go:95:22:95:28 | (def@95:22) | wrapper |
| main.go:95:22:95:28 | (def@95:22).s | wrapper.s |
| main.go:96:2:96:2 | (def@96:2) | x |
| main.go:97:2:99:3 | (capture@97:2) | x |
| main.go:98:3:98:3 | (def@98:3) | x |
| main.go:112:3:112:3 | (def@112:3) | p |
| main.go:114:3:114:3 | (def@114:3) | p |
| main.go:117:2:117:2 | (phi@117:2) | p |
| main.go:117:2:117:2 | (phi@117:2).a | p.a |
| main.go:117:2:117:2 | (phi@117:2).b | p.b |
| main.go:117:2:117:2 | (phi@117:2).b.a | p.b.a |
| main.go:117:2:117:2 | (phi@117:2).c | p.c |

View File

@@ -32,23 +32,16 @@
| main.go:95:22:95:28 | initialization of wrapper | main.go:95:22:95:28 | wrapper | main.go:95:22:95:28 | argument corresponding to wrapper |
| main.go:96:2:96:2 | assignment to x | main.go:96:2:96:2 | x | main.go:96:7:96:7 | 0 |
| main.go:98:3:98:3 | assignment to x | main.go:96:2:96:2 | x | main.go:98:7:98:7 | 1 |
| main.go:103:20:103:26 | initialization of wrapper | main.go:103:20:103:26 | wrapper | main.go:103:20:103:26 | argument corresponding to wrapper |
| main.go:104:2:104:2 | assignment to x | main.go:104:2:104:2 | x | main.go:104:7:104:7 | 0 |
| main.go:106:3:106:3 | assignment to y | main.go:106:3:106:3 | y | main.go:106:8:106:8 | x |
| main.go:112:29:112:35 | initialization of wrapper | main.go:112:29:112:35 | wrapper | main.go:112:29:112:35 | argument corresponding to wrapper |
| main.go:113:2:113:2 | assignment to x | main.go:113:2:113:2 | x | main.go:113:7:113:7 | 0 |
| main.go:115:3:115:3 | assignment to y | main.go:115:3:115:3 | y | main.go:115:8:115:12 | ...+... |
| main.go:116:3:116:3 | assignment to x | main.go:113:2:113:2 | x | main.go:116:7:116:7 | y |
| main.go:128:6:128:6 | assignment to p | main.go:128:6:128:6 | p | main.go:128:6:128:6 | zero value for p |
| main.go:130:3:130:3 | assignment to p | main.go:128:6:128:6 | p | main.go:130:7:130:24 | struct literal |
| main.go:130:9:130:9 | init of 2 | main.go:122:2:122:2 | a | main.go:130:9:130:9 | 2 |
| main.go:130:12:130:18 | init of struct literal | main.go:123:2:123:2 | b | main.go:130:12:130:18 | struct literal |
| main.go:130:14:130:14 | init of 1 | main.go:89:2:89:2 | a | main.go:130:14:130:14 | 1 |
| main.go:130:17:130:17 | init of 5 | main.go:90:2:90:2 | b | main.go:130:17:130:17 | 5 |
| main.go:130:21:130:23 | init of 'n' | main.go:124:2:124:2 | c | main.go:130:21:130:23 | 'n' |
| main.go:132:3:132:3 | assignment to p | main.go:128:6:128:6 | p | main.go:132:7:132:24 | struct literal |
| main.go:132:9:132:9 | init of 3 | main.go:122:2:122:2 | a | main.go:132:9:132:9 | 3 |
| main.go:132:12:132:18 | init of struct literal | main.go:123:2:123:2 | b | main.go:132:12:132:18 | struct literal |
| main.go:132:14:132:14 | init of 4 | main.go:89:2:89:2 | a | main.go:132:14:132:14 | 4 |
| main.go:132:17:132:17 | init of 5 | main.go:90:2:90:2 | b | main.go:132:17:132:17 | 5 |
| main.go:132:21:132:23 | init of '2' | main.go:124:2:124:2 | c | main.go:132:21:132:23 | '2' |
| main.go:110:6:110:6 | assignment to p | main.go:110:6:110:6 | p | main.go:110:6:110:6 | zero value for p |
| main.go:112:3:112:3 | assignment to p | main.go:110:6:110:6 | p | main.go:112:7:112:24 | struct literal |
| main.go:112:9:112:9 | init of 2 | main.go:104:2:104:2 | a | main.go:112:9:112:9 | 2 |
| main.go:112:12:112:18 | init of struct literal | main.go:105:2:105:2 | b | main.go:112:12:112:18 | struct literal |
| main.go:112:14:112:14 | init of 1 | main.go:89:2:89:2 | a | main.go:112:14:112:14 | 1 |
| main.go:112:17:112:17 | init of 5 | main.go:90:2:90:2 | b | main.go:112:17:112:17 | 5 |
| main.go:112:21:112:23 | init of 'n' | main.go:106:2:106:2 | c | main.go:112:21:112:23 | 'n' |
| main.go:114:3:114:3 | assignment to p | main.go:110:6:110:6 | p | main.go:114:7:114:24 | struct literal |
| main.go:114:9:114:9 | init of 3 | main.go:104:2:104:2 | a | main.go:114:9:114:9 | 3 |
| main.go:114:12:114:18 | init of struct literal | main.go:105:2:105:2 | b | main.go:114:12:114:18 | struct literal |
| main.go:114:14:114:14 | init of 4 | main.go:89:2:89:2 | a | main.go:114:14:114:14 | 4 |
| main.go:114:17:114:17 | init of 5 | main.go:90:2:90:2 | b | main.go:114:17:114:17 | 5 |
| main.go:114:21:114:23 | init of '2' | main.go:106:2:106:2 | c | main.go:114:21:114:23 | '2' |

View File

@@ -28,29 +28,13 @@
| main.go:84:15:84:15 | x | main.go:83:2:83:2 | x |
| main.go:97:2:97:8 | wrapper | main.go:95:22:95:28 | wrapper |
| main.go:97:2:97:10 | selection of s | main.go:95:38:95:38 | s |
| main.go:97:2:97:10 | selection of s | main.go:103:36:103:36 | s |
| main.go:97:2:97:10 | selection of s | main.go:112:45:112:45 | s |
| main.go:100:9:100:9 | x | main.go:96:2:96:2 | x |
| main.go:105:2:105:8 | wrapper | main.go:103:20:103:26 | wrapper |
| main.go:105:2:105:10 | selection of s | main.go:95:38:95:38 | s |
| main.go:105:2:105:10 | selection of s | main.go:103:36:103:36 | s |
| main.go:105:2:105:10 | selection of s | main.go:112:45:112:45 | s |
| main.go:106:8:106:8 | x | main.go:104:2:104:2 | x |
| main.go:107:7:107:7 | y | main.go:106:3:106:3 | y |
| main.go:109:9:109:9 | x | main.go:104:2:104:2 | x |
| main.go:114:2:114:8 | wrapper | main.go:112:29:112:35 | wrapper |
| main.go:114:2:114:10 | selection of s | main.go:95:38:95:38 | s |
| main.go:114:2:114:10 | selection of s | main.go:103:36:103:36 | s |
| main.go:114:2:114:10 | selection of s | main.go:112:45:112:45 | s |
| main.go:115:8:115:8 | x | main.go:113:2:113:2 | x |
| main.go:116:7:116:7 | y | main.go:115:3:115:3 | y |
| main.go:118:9:118:9 | x | main.go:113:2:113:2 | x |
| main.go:135:2:135:2 | p | main.go:128:6:128:6 | p |
| main.go:135:2:135:4 | selection of b | main.go:123:2:123:2 | b |
| main.go:137:12:137:12 | p | main.go:128:6:128:6 | p |
| main.go:137:12:137:14 | selection of a | main.go:122:2:122:2 | a |
| main.go:137:17:137:17 | p | main.go:128:6:128:6 | p |
| main.go:137:17:137:19 | selection of b | main.go:123:2:123:2 | b |
| main.go:137:17:137:21 | selection of a | main.go:89:2:89:2 | a |
| main.go:137:24:137:24 | p | main.go:128:6:128:6 | p |
| main.go:137:24:137:26 | selection of c | main.go:124:2:124:2 | c |
| main.go:117:2:117:2 | p | main.go:110:6:110:6 | p |
| main.go:117:2:117:4 | selection of b | main.go:105:2:105:2 | b |
| main.go:119:12:119:12 | p | main.go:110:6:110:6 | p |
| main.go:119:12:119:14 | selection of a | main.go:104:2:104:2 | a |
| main.go:119:17:119:17 | p | main.go:110:6:110:6 | p |
| main.go:119:17:119:19 | selection of b | main.go:105:2:105:2 | b |
| main.go:119:17:119:21 | selection of a | main.go:89:2:89:2 | a |
| main.go:119:24:119:24 | p | main.go:110:6:110:6 | p |
| main.go:119:24:119:26 | selection of c | main.go:106:2:106:2 | c |

View File

@@ -100,24 +100,6 @@ func updateInClosure(wrapper struct{ s }) int {
return x
}
func readInClosure(wrapper struct{ s }) int {
x := 0
wrapper.s.foo(func() {
y := x
_ = y
})
return x
}
func readAndUpdateInClosure(wrapper struct{ s }) int {
x := 0
wrapper.s.foo(func() {
y := x + 1
x = y
})
return x
}
type t struct {
a int
b s

View File

@@ -1,73 +1,73 @@
#select
| test.go:154:14:154:21 | password | test.go:153:17:153:24 | SSA def(password) | test.go:154:14:154:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:155:17:155:24 | password | test.go:153:17:153:24 | SSA def(password) | test.go:155:17:155:24 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:156:14:156:21 | password | test.go:153:17:153:24 | SSA def(password) | test.go:156:14:156:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:157:18:157:25 | password | test.go:153:17:153:24 | SSA def(password) | test.go:157:18:157:25 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:158:14:158:21 | password | test.go:153:17:153:24 | SSA def(password) | test.go:158:14:158:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:159:13:159:20 | password | test.go:153:17:153:24 | SSA def(password) | test.go:159:13:159:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:160:22:160:29 | password | test.go:153:17:153:24 | SSA def(password) | test.go:160:22:160:29 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:161:15:161:22 | password | test.go:153:17:153:24 | SSA def(password) | test.go:161:15:161:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:162:14:162:21 | password | test.go:153:17:153:24 | SSA def(password) | test.go:162:14:162:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:163:13:163:20 | password | test.go:153:17:153:24 | SSA def(password) | test.go:163:13:163:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:164:16:164:23 | password | test.go:153:17:153:24 | SSA def(password) | test.go:164:16:164:23 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:165:13:165:20 | password | test.go:153:17:153:24 | SSA def(password) | test.go:165:13:165:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:166:16:166:23 | password | test.go:153:17:153:24 | SSA def(password) | test.go:166:16:166:23 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:167:13:167:20 | password | test.go:153:17:153:24 | SSA def(password) | test.go:167:13:167:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:168:17:168:24 | password | test.go:153:17:153:24 | SSA def(password) | test.go:168:17:168:24 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:169:13:169:20 | password | test.go:153:17:153:24 | SSA def(password) | test.go:169:13:169:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:170:12:170:19 | password | test.go:153:17:153:24 | SSA def(password) | test.go:170:12:170:19 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:171:21:171:28 | password | test.go:153:17:153:24 | SSA def(password) | test.go:171:21:171:28 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:172:14:172:21 | password | test.go:153:17:153:24 | SSA def(password) | test.go:172:14:172:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:173:13:173:20 | password | test.go:153:17:153:24 | SSA def(password) | test.go:173:13:173:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:174:12:174:19 | password | test.go:153:17:153:24 | SSA def(password) | test.go:174:12:174:19 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:175:15:175:22 | password | test.go:153:17:153:24 | SSA def(password) | test.go:175:15:175:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:176:15:176:22 | password | test.go:153:17:153:24 | SSA def(password) | test.go:176:15:176:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:177:18:177:25 | password | test.go:153:17:153:24 | SSA def(password) | test.go:177:18:177:25 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:178:15:178:22 | password | test.go:153:17:153:24 | SSA def(password) | test.go:178:15:178:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:179:19:179:26 | password | test.go:153:17:153:24 | SSA def(password) | test.go:179:19:179:26 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:180:15:180:22 | password | test.go:153:17:153:24 | SSA def(password) | test.go:180:15:180:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:181:14:181:21 | password | test.go:153:17:153:24 | SSA def(password) | test.go:181:14:181:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:182:23:182:30 | password | test.go:153:17:153:24 | SSA def(password) | test.go:182:23:182:30 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:183:16:183:23 | password | test.go:153:17:153:24 | SSA def(password) | test.go:183:16:183:23 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:184:15:184:22 | password | test.go:153:17:153:24 | SSA def(password) | test.go:184:15:184:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:185:14:185:21 | password | test.go:153:17:153:24 | SSA def(password) | test.go:185:14:185:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:186:17:186:24 | password | test.go:153:17:153:24 | SSA def(password) | test.go:186:17:186:24 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:187:16:187:23 | password | test.go:153:17:153:24 | SSA def(password) | test.go:187:16:187:23 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:154:14:154:21 | password | test.go:153:17:153:24 | definition of password | test.go:154:14:154:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:155:17:155:24 | password | test.go:153:17:153:24 | definition of password | test.go:155:17:155:24 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:156:14:156:21 | password | test.go:153:17:153:24 | definition of password | test.go:156:14:156:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:157:18:157:25 | password | test.go:153:17:153:24 | definition of password | test.go:157:18:157:25 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:158:14:158:21 | password | test.go:153:17:153:24 | definition of password | test.go:158:14:158:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:159:13:159:20 | password | test.go:153:17:153:24 | definition of password | test.go:159:13:159:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:160:22:160:29 | password | test.go:153:17:153:24 | definition of password | test.go:160:22:160:29 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:161:15:161:22 | password | test.go:153:17:153:24 | definition of password | test.go:161:15:161:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:162:14:162:21 | password | test.go:153:17:153:24 | definition of password | test.go:162:14:162:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:163:13:163:20 | password | test.go:153:17:153:24 | definition of password | test.go:163:13:163:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:164:16:164:23 | password | test.go:153:17:153:24 | definition of password | test.go:164:16:164:23 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:165:13:165:20 | password | test.go:153:17:153:24 | definition of password | test.go:165:13:165:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:166:16:166:23 | password | test.go:153:17:153:24 | definition of password | test.go:166:16:166:23 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:167:13:167:20 | password | test.go:153:17:153:24 | definition of password | test.go:167:13:167:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:168:17:168:24 | password | test.go:153:17:153:24 | definition of password | test.go:168:17:168:24 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:169:13:169:20 | password | test.go:153:17:153:24 | definition of password | test.go:169:13:169:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:170:12:170:19 | password | test.go:153:17:153:24 | definition of password | test.go:170:12:170:19 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:171:21:171:28 | password | test.go:153:17:153:24 | definition of password | test.go:171:21:171:28 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:172:14:172:21 | password | test.go:153:17:153:24 | definition of password | test.go:172:14:172:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:173:13:173:20 | password | test.go:153:17:153:24 | definition of password | test.go:173:13:173:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:174:12:174:19 | password | test.go:153:17:153:24 | definition of password | test.go:174:12:174:19 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:175:15:175:22 | password | test.go:153:17:153:24 | definition of password | test.go:175:15:175:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:176:15:176:22 | password | test.go:153:17:153:24 | definition of password | test.go:176:15:176:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:177:18:177:25 | password | test.go:153:17:153:24 | definition of password | test.go:177:18:177:25 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:178:15:178:22 | password | test.go:153:17:153:24 | definition of password | test.go:178:15:178:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:179:19:179:26 | password | test.go:153:17:153:24 | definition of password | test.go:179:19:179:26 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:180:15:180:22 | password | test.go:153:17:153:24 | definition of password | test.go:180:15:180:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:181:14:181:21 | password | test.go:153:17:153:24 | definition of password | test.go:181:14:181:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:182:23:182:30 | password | test.go:153:17:153:24 | definition of password | test.go:182:23:182:30 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:183:16:183:23 | password | test.go:153:17:153:24 | definition of password | test.go:183:16:183:23 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:184:15:184:22 | password | test.go:153:17:153:24 | definition of password | test.go:184:15:184:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:185:14:185:21 | password | test.go:153:17:153:24 | definition of password | test.go:185:14:185:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:186:17:186:24 | password | test.go:153:17:153:24 | definition of password | test.go:186:17:186:24 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:187:16:187:23 | password | test.go:153:17:153:24 | definition of password | test.go:187:16:187:23 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
edges
| test.go:153:17:153:24 | SSA def(password) | test.go:154:14:154:21 | password | provenance | |
| test.go:153:17:153:24 | SSA def(password) | test.go:155:17:155:24 | password | provenance | |
| test.go:153:17:153:24 | SSA def(password) | test.go:156:14:156:21 | password | provenance | |
| test.go:153:17:153:24 | SSA def(password) | test.go:157:18:157:25 | password | provenance | |
| test.go:153:17:153:24 | SSA def(password) | test.go:158:14:158:21 | password | provenance | |
| test.go:153:17:153:24 | SSA def(password) | test.go:159:13:159:20 | password | provenance | |
| test.go:153:17:153:24 | SSA def(password) | test.go:160:22:160:29 | password | provenance | |
| test.go:153:17:153:24 | SSA def(password) | test.go:161:15:161:22 | password | provenance | |
| test.go:153:17:153:24 | SSA def(password) | test.go:162:14:162:21 | password | provenance | |
| test.go:153:17:153:24 | SSA def(password) | test.go:163:13:163:20 | password | provenance | |
| test.go:153:17:153:24 | SSA def(password) | test.go:164:16:164:23 | password | provenance | |
| test.go:153:17:153:24 | SSA def(password) | test.go:165:13:165:20 | password | provenance | Sink:MaD:1 |
| test.go:153:17:153:24 | SSA def(password) | test.go:166:16:166:23 | password | provenance | Sink:MaD:2 |
| test.go:153:17:153:24 | SSA def(password) | test.go:167:13:167:20 | password | provenance | Sink:MaD:3 |
| test.go:153:17:153:24 | SSA def(password) | test.go:168:17:168:24 | password | provenance | Sink:MaD:4 |
| test.go:153:17:153:24 | SSA def(password) | test.go:169:13:169:20 | password | provenance | Sink:MaD:5 |
| test.go:153:17:153:24 | SSA def(password) | test.go:170:12:170:19 | password | provenance | Sink:MaD:6 |
| test.go:153:17:153:24 | SSA def(password) | test.go:171:21:171:28 | password | provenance | Sink:MaD:7 |
| test.go:153:17:153:24 | SSA def(password) | test.go:172:14:172:21 | password | provenance | Sink:MaD:8 |
| test.go:153:17:153:24 | SSA def(password) | test.go:173:13:173:20 | password | provenance | Sink:MaD:9 |
| test.go:153:17:153:24 | SSA def(password) | test.go:174:12:174:19 | password | provenance | Sink:MaD:10 |
| test.go:153:17:153:24 | SSA def(password) | test.go:175:15:175:22 | password | provenance | Sink:MaD:11 |
| test.go:153:17:153:24 | SSA def(password) | test.go:176:15:176:22 | password | provenance | Sink:MaD:12 |
| test.go:153:17:153:24 | SSA def(password) | test.go:177:18:177:25 | password | provenance | Sink:MaD:13 |
| test.go:153:17:153:24 | SSA def(password) | test.go:178:15:178:22 | password | provenance | Sink:MaD:14 |
| test.go:153:17:153:24 | SSA def(password) | test.go:179:19:179:26 | password | provenance | Sink:MaD:15 |
| test.go:153:17:153:24 | SSA def(password) | test.go:180:15:180:22 | password | provenance | Sink:MaD:16 |
| test.go:153:17:153:24 | SSA def(password) | test.go:181:14:181:21 | password | provenance | Sink:MaD:17 |
| test.go:153:17:153:24 | SSA def(password) | test.go:182:23:182:30 | password | provenance | Sink:MaD:18 |
| test.go:153:17:153:24 | SSA def(password) | test.go:183:16:183:23 | password | provenance | Sink:MaD:19 |
| test.go:153:17:153:24 | SSA def(password) | test.go:184:15:184:22 | password | provenance | Sink:MaD:20 |
| test.go:153:17:153:24 | SSA def(password) | test.go:185:14:185:21 | password | provenance | Sink:MaD:21 |
| test.go:153:17:153:24 | SSA def(password) | test.go:186:17:186:24 | password | provenance | Sink:MaD:22 |
| test.go:153:17:153:24 | SSA def(password) | test.go:187:16:187:23 | password | provenance | |
| test.go:153:17:153:24 | definition of password | test.go:154:14:154:21 | password | provenance | |
| test.go:153:17:153:24 | definition of password | test.go:155:17:155:24 | password | provenance | |
| test.go:153:17:153:24 | definition of password | test.go:156:14:156:21 | password | provenance | |
| test.go:153:17:153:24 | definition of password | test.go:157:18:157:25 | password | provenance | |
| test.go:153:17:153:24 | definition of password | test.go:158:14:158:21 | password | provenance | |
| test.go:153:17:153:24 | definition of password | test.go:159:13:159:20 | password | provenance | |
| test.go:153:17:153:24 | definition of password | test.go:160:22:160:29 | password | provenance | |
| test.go:153:17:153:24 | definition of password | test.go:161:15:161:22 | password | provenance | |
| test.go:153:17:153:24 | definition of password | test.go:162:14:162:21 | password | provenance | |
| test.go:153:17:153:24 | definition of password | test.go:163:13:163:20 | password | provenance | |
| test.go:153:17:153:24 | definition of password | test.go:164:16:164:23 | password | provenance | |
| test.go:153:17:153:24 | definition of password | test.go:165:13:165:20 | password | provenance | Sink:MaD:1 |
| test.go:153:17:153:24 | definition of password | test.go:166:16:166:23 | password | provenance | Sink:MaD:2 |
| test.go:153:17:153:24 | definition of password | test.go:167:13:167:20 | password | provenance | Sink:MaD:3 |
| test.go:153:17:153:24 | definition of password | test.go:168:17:168:24 | password | provenance | Sink:MaD:4 |
| test.go:153:17:153:24 | definition of password | test.go:169:13:169:20 | password | provenance | Sink:MaD:5 |
| test.go:153:17:153:24 | definition of password | test.go:170:12:170:19 | password | provenance | Sink:MaD:6 |
| test.go:153:17:153:24 | definition of password | test.go:171:21:171:28 | password | provenance | Sink:MaD:7 |
| test.go:153:17:153:24 | definition of password | test.go:172:14:172:21 | password | provenance | Sink:MaD:8 |
| test.go:153:17:153:24 | definition of password | test.go:173:13:173:20 | password | provenance | Sink:MaD:9 |
| test.go:153:17:153:24 | definition of password | test.go:174:12:174:19 | password | provenance | Sink:MaD:10 |
| test.go:153:17:153:24 | definition of password | test.go:175:15:175:22 | password | provenance | Sink:MaD:11 |
| test.go:153:17:153:24 | definition of password | test.go:176:15:176:22 | password | provenance | Sink:MaD:12 |
| test.go:153:17:153:24 | definition of password | test.go:177:18:177:25 | password | provenance | Sink:MaD:13 |
| test.go:153:17:153:24 | definition of password | test.go:178:15:178:22 | password | provenance | Sink:MaD:14 |
| test.go:153:17:153:24 | definition of password | test.go:179:19:179:26 | password | provenance | Sink:MaD:15 |
| test.go:153:17:153:24 | definition of password | test.go:180:15:180:22 | password | provenance | Sink:MaD:16 |
| test.go:153:17:153:24 | definition of password | test.go:181:14:181:21 | password | provenance | Sink:MaD:17 |
| test.go:153:17:153:24 | definition of password | test.go:182:23:182:30 | password | provenance | Sink:MaD:18 |
| test.go:153:17:153:24 | definition of password | test.go:183:16:183:23 | password | provenance | Sink:MaD:19 |
| test.go:153:17:153:24 | definition of password | test.go:184:15:184:22 | password | provenance | Sink:MaD:20 |
| test.go:153:17:153:24 | definition of password | test.go:185:14:185:21 | password | provenance | Sink:MaD:21 |
| test.go:153:17:153:24 | definition of password | test.go:186:17:186:24 | password | provenance | Sink:MaD:22 |
| test.go:153:17:153:24 | definition of password | test.go:187:16:187:23 | password | provenance | |
models
| 1 | Sink: group:beego-logs; ; false; Alert; ; ; Argument[0..1]; log-injection; manual |
| 2 | Sink: group:beego-logs; ; false; Critical; ; ; Argument[0..1]; log-injection; manual |
@@ -92,7 +92,7 @@ models
| 21 | Sink: group:beego-logs; BeeLogger; true; Warn; ; ; Argument[0..1]; log-injection; manual |
| 22 | Sink: group:beego-logs; BeeLogger; true; Warning; ; ; Argument[0..1]; log-injection; manual |
nodes
| test.go:153:17:153:24 | SSA def(password) | semmle.label | SSA def(password) |
| test.go:153:17:153:24 | definition of password | semmle.label | definition of password |
| test.go:154:14:154:21 | password | semmle.label | password |
| test.go:155:17:155:24 | password | semmle.label | password |
| test.go:156:14:156:21 | password | semmle.label | password |

View File

@@ -12,12 +12,12 @@ type MyService interface {
}
func makeEndpointLit(svc MyService) endpoint.Endpoint {
return func(_ context.Context, request interface{}) (interface{}, error) { // $ source="SSA def(request)"
return func(_ context.Context, request interface{}) (interface{}, error) { // $ source="definition of request"
return request, nil
}
}
func endpointfn(_ context.Context, request interface{}) (interface{}, error) { // $ source="SSA def(request)"
func endpointfn(_ context.Context, request interface{}) (interface{}, error) { // $ source="definition of request"
return request, nil
}

Some files were not shown because too many files have changed in this diff Show More