From dee4ddbb5ba533586c3ac51da067196f4442a6cc Mon Sep 17 00:00:00 2001
From: Tom Hvitved
Date: Thu, 7 Nov 2019 14:14:36 +0100
Subject: [PATCH 01/44] C#: Only set `UseSharedCompilation=false` in
autobuilder when needed
Since we are now able to trace shared compilation builds on Linux and macOS
(starting from .NET Core 3), and always were able to on Windows, there is
no need to set `UseSharedCompilation=false` in those cases. This may have a
positive performance impact, as shared compilation is generally faster then
non-shared compilation.
---
.../Semmle.Autobuild.Tests/BuildScripts.cs | 47 ++++++++++-----
.../Semmle.Autobuild/Autobuilder.cs | 13 +++-
.../Semmle.Autobuild/BuildActions.cs | 8 +--
.../Semmle.Autobuild/BuildScript.cs | 34 ++++++-----
.../Semmle.Autobuild/CommandBuilder.cs | 7 ++-
.../Semmle.Autobuild/DotNetRule.cs | 59 ++++++++++++++++---
6 files changed, 118 insertions(+), 50 deletions(-)
diff --git a/csharp/autobuilder/Semmle.Autobuild.Tests/BuildScripts.cs b/csharp/autobuilder/Semmle.Autobuild.Tests/BuildScripts.cs
index 20d19a3525c..8037cf98065 100644
--- a/csharp/autobuilder/Semmle.Autobuild.Tests/BuildScripts.cs
+++ b/csharp/autobuilder/Semmle.Autobuild.Tests/BuildScripts.cs
@@ -185,7 +185,7 @@ namespace Semmle.Extraction.Tests
// Records the arguments passed to StartCallback.
IList StartCallbackIn = new List();
- void StartCallback(string s)
+ void StartCallback(string s, bool silent)
{
StartCallbackIn.Add(s);
}
@@ -194,7 +194,7 @@ namespace Semmle.Extraction.Tests
IList EndCallbackIn = new List();
IList EndCallbackReturn = new List();
- void EndCallback(int ret, string s)
+ void EndCallback(int ret, string s, bool silent)
{
EndCallbackReturn.Add(ret);
EndCallbackIn.Add(s);
@@ -203,7 +203,7 @@ namespace Semmle.Extraction.Tests
[Fact]
public void TestBuildCommand()
{
- var cmd = BuildScript.Create("abc", "def ghi", null, null);
+ var cmd = BuildScript.Create("abc", "def ghi", false, null, null);
Actions.RunProcess["abc def ghi"] = 1;
cmd.Run(Actions, StartCallback, EndCallback);
@@ -216,7 +216,7 @@ namespace Semmle.Extraction.Tests
[Fact]
public void TestAnd1()
{
- var cmd = BuildScript.Create("abc", "def ghi", null, null) & BuildScript.Create("odasa", null, null, null);
+ var cmd = BuildScript.Create("abc", "def ghi", false, null, null) & BuildScript.Create("odasa", null, false, null, null);
Actions.RunProcess["abc def ghi"] = 1;
cmd.Run(Actions, StartCallback, EndCallback);
@@ -230,7 +230,7 @@ namespace Semmle.Extraction.Tests
[Fact]
public void TestAnd2()
{
- var cmd = BuildScript.Create("odasa", null, null, null) & BuildScript.Create("abc", "def ghi", null, null);
+ var cmd = BuildScript.Create("odasa", null, false, null, null) & BuildScript.Create("abc", "def ghi", false, null, null);
Actions.RunProcess["abc def ghi"] = 1;
Actions.RunProcess["odasa "] = 0;
@@ -250,7 +250,7 @@ namespace Semmle.Extraction.Tests
[Fact]
public void TestOr1()
{
- var cmd = BuildScript.Create("odasa", null, null, null) | BuildScript.Create("abc", "def ghi", null, null);
+ var cmd = BuildScript.Create("odasa", null, false, null, null) | BuildScript.Create("abc", "def ghi", false, null, null);
Actions.RunProcess["abc def ghi"] = 1;
Actions.RunProcess["odasa "] = 0;
@@ -266,7 +266,7 @@ namespace Semmle.Extraction.Tests
[Fact]
public void TestOr2()
{
- var cmd = BuildScript.Create("abc", "def ghi", null, null) | BuildScript.Create("odasa", null, null, null);
+ var cmd = BuildScript.Create("abc", "def ghi", false, null, null) | BuildScript.Create("odasa", null, false, null, null);
Actions.RunProcess["abc def ghi"] = 1;
Actions.RunProcess["odasa "] = 0;
@@ -375,7 +375,7 @@ namespace Semmle.Extraction.Tests
Actions.RunProcess["cmd.exe /C dotnet --info"] = 0;
Actions.RunProcess["cmd.exe /C dotnet clean test.csproj"] = 0;
Actions.RunProcess["cmd.exe /C dotnet restore test.csproj"] = 0;
- Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --auto dotnet build --no-incremental /p:UseSharedCompilation=false test.csproj"] = 0;
+ Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --auto dotnet build --no-incremental test.csproj"] = 0;
Actions.RunProcess[@"cmd.exe /C C:\codeql\tools\java\bin\java -jar C:\codeql\csharp\tools\extractor-asp.jar ."] = 0;
Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --xml --extensions config csproj props xml"] = 0;
Actions.FileExists["csharp.log"] = true;
@@ -404,6 +404,9 @@ namespace Semmle.Extraction.Tests
Actions.RunProcess["dotnet --info"] = 0;
Actions.RunProcess["dotnet clean test.csproj"] = 0;
Actions.RunProcess["dotnet restore test.csproj"] = 0;
+ Actions.RunProcess["dotnet --list-runtimes"] = 0;
+ Actions.RunProcessOut["dotnet --list-runtimes"] = @"Microsoft.AspNetCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
+Microsoft.NETCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]";
Actions.RunProcess[@"C:\odasa/tools/odasa index --auto dotnet build --no-incremental /p:UseSharedCompilation=false test.csproj"] = 0;
Actions.RunProcess[@"C:\codeql\tools\java/bin/java -jar C:\codeql\csharp/tools/extractor-asp.jar ."] = 0;
Actions.RunProcess[@"C:\odasa/tools/odasa index --xml --extensions config csproj props xml"] = 0;
@@ -424,7 +427,7 @@ namespace Semmle.Extraction.Tests
Actions.LoadXml["test.csproj"] = xml;
var autobuilder = CreateAutoBuilder("csharp", false);
- TestAutobuilderScript(autobuilder, 0, 6);
+ TestAutobuilderScript(autobuilder, 0, 7);
}
[Fact]
@@ -748,7 +751,7 @@ namespace Semmle.Extraction.Tests
TestAutobuilderScript(autobuilder, 0, 6);
}
- [Fact]
+ [Fact]
public void TestWindowCSharpMsBuildMultipleSolutions()
{
Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\csharp\nuget\nuget.exe restore test1.csproj"] = 0;
@@ -874,6 +877,9 @@ namespace Semmle.Extraction.Tests
Actions.RunProcess["dotnet --info"] = 0;
Actions.RunProcess["dotnet clean test.csproj"] = 0;
Actions.RunProcess["dotnet restore test.csproj"] = 0;
+ Actions.RunProcess["dotnet --list-runtimes"] = 0;
+ Actions.RunProcessOut["dotnet --list-runtimes"] = @"Microsoft.AspNetCore.App 2.1.3 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
+Microsoft.NETCore.App 2.1.3 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]";
Actions.RunProcess[@"C:\odasa/tools/odasa index --auto dotnet build --no-incremental /p:UseSharedCompilation=false --no-restore test.csproj"] = 0;
Actions.RunProcess[@"C:\codeql\tools\java/bin/java -jar C:\codeql\csharp/tools/extractor-asp.jar ."] = 0;
Actions.RunProcess[@"C:\odasa/tools/odasa index --xml --extensions config csproj props xml"] = 0;
@@ -894,7 +900,7 @@ namespace Semmle.Extraction.Tests
Actions.LoadXml["test.csproj"] = xml;
var autobuilder = CreateAutoBuilder("csharp", false, dotnetArguments: "--no-restore"); // nugetRestore=false does not work for now.
- TestAutobuilderScript(autobuilder, 0, 6);
+ TestAutobuilderScript(autobuilder, 0, 7);
}
[Fact]
@@ -909,7 +915,10 @@ namespace Semmle.Extraction.Tests
Actions.RunProcess[@"C:\Project/.dotnet/dotnet --info"] = 0;
Actions.RunProcess[@"C:\Project/.dotnet/dotnet clean test.csproj"] = 0;
Actions.RunProcess[@"C:\Project/.dotnet/dotnet restore test.csproj"] = 0;
- Actions.RunProcess[@"C:\odasa/tools/odasa index --auto C:\Project/.dotnet/dotnet build --no-incremental /p:UseSharedCompilation=false test.csproj"] = 0;
+ Actions.RunProcess[@"C:\Project/.dotnet/dotnet --list-runtimes"] = 0;
+ Actions.RunProcessOut[@"C:\Project/.dotnet/dotnet --list-runtimes"] = @"Microsoft.AspNetCore.App 3.0.0 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
+Microsoft.NETCore.App 3.0.0 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]";
+ Actions.RunProcess[@"C:\odasa/tools/odasa index --auto C:\Project/.dotnet/dotnet build --no-incremental test.csproj"] = 0;
Actions.RunProcess[@"C:\codeql\tools\java/bin/java -jar C:\codeql\csharp/tools/extractor-asp.jar ."] = 0;
Actions.RunProcess[@"C:\odasa/tools/odasa index --xml --extensions config csproj props xml"] = 0;
Actions.FileExists["csharp.log"] = true;
@@ -930,14 +939,15 @@ namespace Semmle.Extraction.Tests
Actions.LoadXml["test.csproj"] = xml;
var autobuilder = CreateAutoBuilder("csharp", false, dotnetVersion: "2.1.3");
- TestAutobuilderScript(autobuilder, 0, 11);
+ TestAutobuilderScript(autobuilder, 0, 12);
}
[Fact]
public void TestDotnetVersionAlreadyInstalled()
{
Actions.RunProcess["dotnet --list-sdks"] = 0;
- Actions.RunProcessOut["dotnet --list-sdks"] = "2.1.3 [C:\\Program Files\\dotnet\\sdks]\n2.1.4 [C:\\Program Files\\dotnet\\sdks]";
+ Actions.RunProcessOut["dotnet --list-sdks"] = @"2.1.3 [C:\Program Files\dotnet\sdks]
+2.1.4 [C:\Program Files\dotnet\sdks]";
Actions.RunProcess[@"curl -L -sO https://dot.net/v1/dotnet-install.sh"] = 0;
Actions.RunProcess[@"chmod u+x dotnet-install.sh"] = 0;
Actions.RunProcess[@"./dotnet-install.sh --channel release --version 2.1.3 --install-dir C:\Project/.dotnet"] = 0;
@@ -945,6 +955,11 @@ namespace Semmle.Extraction.Tests
Actions.RunProcess[@"C:\Project/.dotnet/dotnet --info"] = 0;
Actions.RunProcess[@"C:\Project/.dotnet/dotnet clean test.csproj"] = 0;
Actions.RunProcess[@"C:\Project/.dotnet/dotnet restore test.csproj"] = 0;
+ Actions.RunProcess[@"C:\Project/.dotnet/dotnet --list-runtimes"] = 0;
+ Actions.RunProcessOut[@"C:\Project/.dotnet/dotnet --list-runtimes"] = @"Microsoft.AspNetCore.App 2.1.3 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
+Microsoft.AspNetCore.App 2.1.4 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
+Microsoft.NETCore.App 2.1.3 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
+Microsoft.NETCore.App 2.1.4 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]";
Actions.RunProcess[@"C:\odasa/tools/odasa index --auto C:\Project/.dotnet/dotnet build --no-incremental /p:UseSharedCompilation=false test.csproj"] = 0;
Actions.RunProcess[@"C:\codeql\tools\java/bin/java -jar C:\codeql\csharp/tools/extractor-asp.jar ."] = 0;
Actions.RunProcess[@"C:\odasa/tools/odasa index --xml --extensions config csproj props xml"] = 0;
@@ -966,7 +981,7 @@ namespace Semmle.Extraction.Tests
Actions.LoadXml["test.csproj"] = xml;
var autobuilder = CreateAutoBuilder("csharp", false, dotnetVersion: "2.1.3");
- TestAutobuilderScript(autobuilder, 0, 11);
+ TestAutobuilderScript(autobuilder, 0, 12);
}
[Fact]
@@ -979,7 +994,7 @@ namespace Semmle.Extraction.Tests
Actions.RunProcess[@"cmd.exe /C C:\Project\.dotnet\dotnet --info"] = 0;
Actions.RunProcess[@"cmd.exe /C C:\Project\.dotnet\dotnet clean test.csproj"] = 0;
Actions.RunProcess[@"cmd.exe /C C:\Project\.dotnet\dotnet restore test.csproj"] = 0;
- Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --auto C:\Project\.dotnet\dotnet build --no-incremental /p:UseSharedCompilation=false test.csproj"] = 0;
+ Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --auto C:\Project\.dotnet\dotnet build --no-incremental test.csproj"] = 0;
Actions.RunProcess[@"cmd.exe /C C:\codeql\tools\java\bin\java -jar C:\codeql\csharp\tools\extractor-asp.jar ."] = 0;
Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --xml --extensions config csproj props xml"] = 0;
Actions.FileExists["csharp.log"] = true;
diff --git a/csharp/autobuilder/Semmle.Autobuild/Autobuilder.cs b/csharp/autobuilder/Semmle.Autobuild/Autobuilder.cs
index 001934f489d..71653f0a93b 100644
--- a/csharp/autobuilder/Semmle.Autobuild/Autobuilder.cs
+++ b/csharp/autobuilder/Semmle.Autobuild/Autobuilder.cs
@@ -214,8 +214,17 @@ namespace Semmle.Autobuild
if (Options.IgnoreErrors)
script |= BuildScript.Success;
- void startCallback(string s) => Log(Severity.Info, $"\nRunning {s}");
- void exitCallback(int ret, string msg) => Log(Severity.Info, $"Exit code {ret}{(string.IsNullOrEmpty(msg) ? "" : $": {msg}")}");
+ void startCallback(string s, bool silent)
+ {
+ if (!silent) Log(Severity.Info, $"\nRunning {s}");
+ }
+
+ void exitCallback(int ret, string msg, bool silent)
+ {
+ if (!silent)
+ Log(Severity.Info, $"Exit code {ret}{(string.IsNullOrEmpty(msg) ? "" : $": {msg}")}");
+ }
+
return script.Run(Actions, startCallback, exitCallback);
}
diff --git a/csharp/autobuilder/Semmle.Autobuild/BuildActions.cs b/csharp/autobuilder/Semmle.Autobuild/BuildActions.cs
index edf4fc752c1..837f6e3f69e 100644
--- a/csharp/autobuilder/Semmle.Autobuild/BuildActions.cs
+++ b/csharp/autobuilder/Semmle.Autobuild/BuildActions.cs
@@ -141,12 +141,8 @@ namespace Semmle.Autobuild
pi.WorkingDirectory = workingDirectory;
// Environment variables can only be used when not redirecting stdout
- if (!redirectStandardOutput)
- {
- pi.Environment["UseSharedCompilation"] = "false";
- if (environment != null)
- environment.ForEach(kvp => pi.Environment[kvp.Key] = kvp.Value);
- }
+ if (!redirectStandardOutput && environment != null)
+ environment.ForEach(kvp => pi.Environment[kvp.Key] = kvp.Value);
return pi;
}
diff --git a/csharp/autobuilder/Semmle.Autobuild/BuildScript.cs b/csharp/autobuilder/Semmle.Autobuild/BuildScript.cs
index a41011e159f..93ea941d58b 100644
--- a/csharp/autobuilder/Semmle.Autobuild/BuildScript.cs
+++ b/csharp/autobuilder/Semmle.Autobuild/BuildScript.cs
@@ -25,7 +25,7 @@ namespace Semmle.Autobuild
/// an exit message.
///
/// The exit code from this build script.
- public abstract int Run(IBuildActions actions, Action startCallback, Action exitCallBack);
+ public abstract int Run(IBuildActions actions, Action startCallback, Action exitCallBack);
///
/// Run this build command.
@@ -44,33 +44,36 @@ namespace Semmle.Autobuild
///
/// Contents of standard out.
/// The exit code from this build script.
- public abstract int Run(IBuildActions actions, Action startCallback, Action exitCallBack, out IList stdout);
+ public abstract int Run(IBuildActions actions, Action startCallback, Action exitCallBack, out IList stdout);
class BuildCommand : BuildScript
{
readonly string exe, arguments, workingDirectory;
readonly IDictionary environment;
+ readonly bool silent;
///
/// Create a simple build command.
///
/// The executable to run.
/// The arguments to the executable, or null.
+ /// Whether this command should run silently.
/// The working directory (null for current directory).
/// Additional environment variables.
- public BuildCommand(string exe, string argumentsOpt, string workingDirectory = null, IDictionary environment = null)
+ public BuildCommand(string exe, string argumentsOpt, bool silent, string workingDirectory = null, IDictionary environment = null)
{
this.exe = exe;
this.arguments = argumentsOpt ?? "";
+ this.silent = silent;
this.workingDirectory = workingDirectory;
this.environment = environment;
}
public override string ToString() => exe + " " + arguments;
- public override int Run(IBuildActions actions, Action startCallback, Action exitCallBack)
+ public override int Run(IBuildActions actions, Action startCallback, Action exitCallBack)
{
- startCallback(this.ToString());
+ startCallback(this.ToString(), silent);
var ret = 1;
var retMessage = "";
try
@@ -83,13 +86,13 @@ namespace Semmle.Autobuild
retMessage = ex.Message;
}
- exitCallBack(ret, retMessage);
+ exitCallBack(ret, retMessage, silent);
return ret;
}
- public override int Run(IBuildActions actions, Action startCallback, Action exitCallBack, out IList stdout)
+ public override int Run(IBuildActions actions, Action startCallback, Action exitCallBack, out IList stdout)
{
- startCallback(this.ToString());
+ startCallback(this.ToString(), silent);
var ret = 1;
var retMessage = "";
try
@@ -102,7 +105,7 @@ namespace Semmle.Autobuild
retMessage = ex.Message;
stdout = new string[0];
}
- exitCallBack(ret, retMessage);
+ exitCallBack(ret, retMessage, silent);
return ret;
}
@@ -116,9 +119,9 @@ namespace Semmle.Autobuild
this.func = func;
}
- public override int Run(IBuildActions actions, Action startCallback, Action exitCallBack) => func(actions);
+ public override int Run(IBuildActions actions, Action startCallback, Action exitCallBack) => func(actions);
- public override int Run(IBuildActions actions, Action startCallback, Action exitCallBack, out IList stdout)
+ public override int Run(IBuildActions actions, Action startCallback, Action exitCallBack, out IList stdout)
{
stdout = new string[0];
return func(actions);
@@ -142,7 +145,7 @@ namespace Semmle.Autobuild
this.s2b = s2;
}
- public override int Run(IBuildActions actions, Action startCallback, Action exitCallBack)
+ public override int Run(IBuildActions actions, Action startCallback, Action exitCallBack)
{
int ret1;
if (s2a != null)
@@ -155,7 +158,7 @@ namespace Semmle.Autobuild
return s2b(ret1).Run(actions, startCallback, exitCallBack);
}
- public override int Run(IBuildActions actions, Action startCallback, Action exitCallBack, out IList stdout)
+ public override int Run(IBuildActions actions, Action startCallback, Action exitCallBack, out IList stdout)
{
var ret1 = s1.Run(actions, startCallback, exitCallBack, out var stdout1);
var ret2 = (s2a != null ? s2a(stdout1, ret1) : s2b(ret1)).Run(actions, startCallback, exitCallBack, out var stdout2);
@@ -171,10 +174,11 @@ namespace Semmle.Autobuild
/// Creates a simple build script that runs the specified exe.
///
/// The arguments to the executable, or null.
+ /// Whether the executable should run silently.
/// The working directory (null for current directory).
/// Additional environment variables.
- public static BuildScript Create(string exe, string argumentsOpt, string workingDirectory, IDictionary environment) =>
- new BuildCommand(exe, argumentsOpt, workingDirectory, environment);
+ public static BuildScript Create(string exe, string argumentsOpt, bool silent, string workingDirectory, IDictionary environment) =>
+ new BuildCommand(exe, argumentsOpt, silent, workingDirectory, environment);
///
/// Creates a simple build script that runs the specified function.
diff --git a/csharp/autobuilder/Semmle.Autobuild/CommandBuilder.cs b/csharp/autobuilder/Semmle.Autobuild/CommandBuilder.cs
index 273cc52b036..7b95e495697 100644
--- a/csharp/autobuilder/Semmle.Autobuild/CommandBuilder.cs
+++ b/csharp/autobuilder/Semmle.Autobuild/CommandBuilder.cs
@@ -17,13 +17,15 @@ namespace Semmle.Autobuild
readonly EscapeMode escapingMode;
readonly string workingDirectory;
readonly IDictionary environment;
+ readonly bool silent;
///
/// Initializes a new instance of the class.
///
/// The working directory (null for current directory).
/// Additional environment variables.
- public CommandBuilder(IBuildActions actions, string workingDirectory = null, IDictionary environment = null)
+ /// Whether this command should be run silently.
+ public CommandBuilder(IBuildActions actions, string workingDirectory = null, IDictionary environment = null, bool silent = false)
{
arguments = new StringBuilder();
if (actions.IsWindows())
@@ -40,6 +42,7 @@ namespace Semmle.Autobuild
firstCommand = true;
this.workingDirectory = workingDirectory;
this.environment = environment;
+ this.silent = silent;
}
void OdasaIndex(string odasa)
@@ -190,6 +193,6 @@ namespace Semmle.Autobuild
///
/// Returns a build script that contains just this command.
///
- public BuildScript Script => BuildScript.Create(executable, arguments.ToString(), workingDirectory, environment);
+ public BuildScript Script => BuildScript.Create(executable, arguments.ToString(), silent, workingDirectory, environment);
}
}
diff --git a/csharp/autobuilder/Semmle.Autobuild/DotNetRule.cs b/csharp/autobuilder/Semmle.Autobuild/DotNetRule.cs
index 789d68db30a..d44f32e4b56 100644
--- a/csharp/autobuilder/Semmle.Autobuild/DotNetRule.cs
+++ b/csharp/autobuilder/Semmle.Autobuild/DotNetRule.cs
@@ -5,6 +5,7 @@ using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using System.IO;
using Semmle.Util;
+using System.Text.RegularExpressions;
namespace Semmle.Autobuild
{
@@ -47,9 +48,7 @@ namespace Semmle.Autobuild
restoreCommand.QuoteArgument(projectOrSolution.FullPath);
var restore = restoreCommand.Script;
- var buildCommand = GetBuildCommand(builder, dotNet);
- buildCommand.QuoteArgument(projectOrSolution.FullPath);
- var build = buildCommand.Script;
+ var build = GetBuildScript(builder, dotNet, projectOrSolution.FullPath);
ret &= clean & BuildScript.Try(restore) & build;
}
@@ -225,7 +224,7 @@ Invoke-Command -ScriptBlock $ScriptBlock";
static BuildScript GetInstalledSdksScript(IBuildActions actions)
{
- var listSdks = new CommandBuilder(actions).
+ var listSdks = new CommandBuilder(actions, silent: true).
RunCommand("dotnet").
Argument("--list-sdks");
return listSdks.Script;
@@ -258,14 +257,56 @@ Invoke-Command -ScriptBlock $ScriptBlock";
return restore;
}
- CommandBuilder GetBuildCommand(Autobuilder builder, (string DotNetPath, IDictionary Environment)? arg)
+ static BuildScript GetInstalledRuntimesScript(IBuildActions actions, (string DotNetPath, IDictionary Environment)? arg)
+ {
+ var listSdks = new CommandBuilder(actions, environment: arg?.Environment, silent: true).
+ RunCommand(DotNetCommand(actions, arg?.DotNetPath)).
+ Argument("--list-runtimes");
+ return listSdks.Script;
+ }
+
+ ///
+ /// Gets the `dotnet build` script.
+ ///
+ /// The CLR tracer only works on .NET Core >= 3 on Linux and macOS (see
+ /// https://github.com/dotnet/coreclr/issues/19622), so in case we are
+ /// running on an older .NET Core, we disable shared compilation (and
+ /// hence the need for CLR tracing), by adding a
+ /// `/p:UseSharedCompilation=false` argument.
+ ///
+ BuildScript GetBuildScript(Autobuilder builder, (string DotNetPath, IDictionary Environment)? arg, string projOrSln)
{
var build = new CommandBuilder(builder.Actions, null, arg?.Environment);
- return builder.MaybeIndex(build, DotNetCommand(builder.Actions, arg?.DotNetPath)).
+ var script = builder.MaybeIndex(build, DotNetCommand(builder.Actions, arg?.DotNetPath)).
Argument("build").
- Argument("--no-incremental").
- Argument("/p:UseSharedCompilation=false").
- Argument(builder.Options.DotNetArguments);
+ Argument("--no-incremental");
+
+ if (builder.Actions.IsWindows())
+ return script.Argument(builder.Options.DotNetArguments).
+ QuoteArgument(projOrSln).
+ Script;
+
+ return BuildScript.Bind(GetInstalledRuntimesScript(builder.Actions, arg), (runtimes, runtimesRet) =>
+ {
+ var compatibleClr = false;
+ if (runtimesRet == 0)
+ {
+ var regex = new Regex(@"Microsoft\.NETCore\.App (\d)");
+ compatibleClr = runtimes.
+ Select(runtime => regex.Match(runtime)).
+ Where(m => m.Success).
+ Any(m => int.TryParse(m.Groups[1].Value, out var version) && version >= 3);
+ }
+
+ return compatibleClr ?
+ script.Argument(builder.Options.DotNetArguments).
+ QuoteArgument(projOrSln).
+ Script :
+ script.Argument("/p:UseSharedCompilation=false").
+ Argument(builder.Options.DotNetArguments).
+ QuoteArgument(projOrSln).
+ Script;
+ });
}
}
}
From a9f08671cabdf4f951e99bc705744079677ef0c6 Mon Sep 17 00:00:00 2001
From: Tom Hvitved
Date: Thu, 14 Nov 2019 11:00:19 +0100
Subject: [PATCH 02/44] C#: Address review comments
---
csharp/autobuilder/Semmle.Autobuild/Autobuilder.cs | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/csharp/autobuilder/Semmle.Autobuild/Autobuilder.cs b/csharp/autobuilder/Semmle.Autobuild/Autobuilder.cs
index 71653f0a93b..73e6fcd181f 100644
--- a/csharp/autobuilder/Semmle.Autobuild/Autobuilder.cs
+++ b/csharp/autobuilder/Semmle.Autobuild/Autobuilder.cs
@@ -216,13 +216,12 @@ namespace Semmle.Autobuild
void startCallback(string s, bool silent)
{
- if (!silent) Log(Severity.Info, $"\nRunning {s}");
+ Log(silent ? Severity.Debug : Severity.Info, $"\nRunning {s}");
}
void exitCallback(int ret, string msg, bool silent)
{
- if (!silent)
- Log(Severity.Info, $"Exit code {ret}{(string.IsNullOrEmpty(msg) ? "" : $": {msg}")}");
+ Log(silent ? Severity.Debug : Severity.Info, $"Exit code {ret}{(string.IsNullOrEmpty(msg) ? "" : $": {msg}")}");
}
return script.Run(Actions, startCallback, exitCallback);
From 56c12adab7e5effa7b519988ea5b8376cd3a79b5 Mon Sep 17 00:00:00 2001
From: Paulino Calderon
Date: Sat, 16 Nov 2019 14:21:39 -0500
Subject: [PATCH 03/44] Adds check for insecure MaxLengthRequest values
---
.../CWE-016/ASPNetMaxRequestLength.qhelp | 55 +++++++++++++++++++
.../CWE-016/ASPNetMaxRequestLength.ql | 18 ++++++
.../Web.config.ASPNetMaxRequestLength.bad | 6 ++
.../Web.config.ASPNetMaxRequestLength.good | 6 ++
4 files changed, 85 insertions(+)
create mode 100644 csharp/ql/src/Security Features/CWE-016/ASPNetMaxRequestLength.qhelp
create mode 100644 csharp/ql/src/Security Features/CWE-016/ASPNetMaxRequestLength.ql
create mode 100644 csharp/ql/src/Security Features/CWE-016/Web.config.ASPNetMaxRequestLength.bad
create mode 100644 csharp/ql/src/Security Features/CWE-016/Web.config.ASPNetMaxRequestLength.good
diff --git a/csharp/ql/src/Security Features/CWE-016/ASPNetMaxRequestLength.qhelp b/csharp/ql/src/Security Features/CWE-016/ASPNetMaxRequestLength.qhelp
new file mode 100644
index 00000000000..c8860bfc3c0
--- /dev/null
+++ b/csharp/ql/src/Security Features/CWE-016/ASPNetMaxRequestLength.qhelp
@@ -0,0 +1,55 @@
+
+
+
+
+
+ The
+ maxRequestLength
+ attribute sets the limit for the input stream buffering
+ threshold in KB. Attackers can use large requests to cause denial-of-service
+ attacks.
+
+
+
+
+
+ The recommended value is 4096 KB but you should try setting it as small
+ as possible according
+ to business requirements.
+
+
+
+
+
+
+ The following example shows the
+ maxRequestLength
+ attribute set to a high value
+ (255 MB) in a
+ Web.config
+ file for ASP.NET:
+
+
+
+
+
+ Unless such a high value is strictly needed, it is better to set the
+ recommended value (4096 KB):
+
+
+
+
+
+
+
+
+
+ .NET API:
+ MaxRequestLength limit to prevent denial of service attacks
+ .
+
+
+
\ No newline at end of file
diff --git a/csharp/ql/src/Security Features/CWE-016/ASPNetMaxRequestLength.ql b/csharp/ql/src/Security Features/CWE-016/ASPNetMaxRequestLength.ql
new file mode 100644
index 00000000000..1ee5e20967c
--- /dev/null
+++ b/csharp/ql/src/Security Features/CWE-016/ASPNetMaxRequestLength.ql
@@ -0,0 +1,18 @@
+/**
+ * @name Large maxRequestLength value
+ * @description Setting a large 'maxRequestLength' value may render a webpage vulnerable to
+ * denial-of-service attacks.
+ * @kind problem
+ * @problem.severity warning
+ */
+
+import csharp
+import semmle.code.asp.WebConfig
+
+from SystemWebXMLElement web, XMLAttribute maxReqLength
+where
+ maxReqLength = web
+ .getAChild(any(string s | s.toLowerCase() = "httpruntime"))
+ .getAttribute(any(string s | s.toLowerCase() = "maxrequestlength")) and
+ maxReqLength.getValue().toInt() > 4096
+select maxReqLength, "Large 'maxRequestLength' value (" + maxReqLength.getValue() + " KB)."
diff --git a/csharp/ql/src/Security Features/CWE-016/Web.config.ASPNetMaxRequestLength.bad b/csharp/ql/src/Security Features/CWE-016/Web.config.ASPNetMaxRequestLength.bad
new file mode 100644
index 00000000000..266d77385c1
--- /dev/null
+++ b/csharp/ql/src/Security Features/CWE-016/Web.config.ASPNetMaxRequestLength.bad
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/csharp/ql/src/Security Features/CWE-016/Web.config.ASPNetMaxRequestLength.good b/csharp/ql/src/Security Features/CWE-016/Web.config.ASPNetMaxRequestLength.good
new file mode 100644
index 00000000000..8ba76b53dae
--- /dev/null
+++ b/csharp/ql/src/Security Features/CWE-016/Web.config.ASPNetMaxRequestLength.good
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
From 96a02aba3f825f5fb54628ce2eb39054412979a5 Mon Sep 17 00:00:00 2001
From: Paulino Calderon
Date: Tue, 19 Nov 2019 12:39:10 -0500
Subject: [PATCH 04/44] Adds quotes on name and additional info tags
---
.../src/Security Features/CWE-016/ASPNetMaxRequestLength.ql | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/csharp/ql/src/Security Features/CWE-016/ASPNetMaxRequestLength.ql b/csharp/ql/src/Security Features/CWE-016/ASPNetMaxRequestLength.ql
index 1ee5e20967c..dbf1a527f2c 100644
--- a/csharp/ql/src/Security Features/CWE-016/ASPNetMaxRequestLength.ql
+++ b/csharp/ql/src/Security Features/CWE-016/ASPNetMaxRequestLength.ql
@@ -1,9 +1,13 @@
/**
- * @name Large maxRequestLength value
+ * @name Large 'maxRequestLength' value
* @description Setting a large 'maxRequestLength' value may render a webpage vulnerable to
* denial-of-service attacks.
* @kind problem
* @problem.severity warning
+ * @id cs/web/large-max-request-length
+ * @tags security
+ * frameworks/asp.net
+ * external/cwe/cwe-16
*/
import csharp
From 85eda8c978b5fcb6f9d789943d8599bedfe19185 Mon Sep 17 00:00:00 2001
From: Paulino Calderon
Date: Tue, 19 Nov 2019 13:04:19 -0500
Subject: [PATCH 05/44] Brings security tests from other PRs
---
.../Security Features/CWE-016/ASPNetMaxRequestLength.cs | 5 +++++
.../CWE-016/ASPNetMaxRequestLength.expected | 1 +
.../Security Features/CWE-016/ASPNetMaxRequestLength.qlref | 1 +
.../test/query-tests/Security Features/CWE-016/Web.config | 6 ++++++
.../query-tests/Security Features/CWE-016/bad/Web.config | 6 ++++++
5 files changed, 19 insertions(+)
create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-016/ASPNetMaxRequestLength.cs
create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-016/ASPNetMaxRequestLength.expected
create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-016/ASPNetMaxRequestLength.qlref
create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-016/Web.config
create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-016/bad/Web.config
diff --git a/csharp/ql/test/query-tests/Security Features/CWE-016/ASPNetMaxRequestLength.cs b/csharp/ql/test/query-tests/Security Features/CWE-016/ASPNetMaxRequestLength.cs
new file mode 100644
index 00000000000..a3e588b5c5b
--- /dev/null
+++ b/csharp/ql/test/query-tests/Security Features/CWE-016/ASPNetMaxRequestLength.cs
@@ -0,0 +1,5 @@
+// Dummy class for extraction purposes
+public class ASPNetMaxRequestLengthDummyClass
+{
+
+}
\ No newline at end of file
diff --git a/csharp/ql/test/query-tests/Security Features/CWE-016/ASPNetMaxRequestLength.expected b/csharp/ql/test/query-tests/Security Features/CWE-016/ASPNetMaxRequestLength.expected
new file mode 100644
index 00000000000..83252520dea
--- /dev/null
+++ b/csharp/ql/test/query-tests/Security Features/CWE-016/ASPNetMaxRequestLength.expected
@@ -0,0 +1 @@
+| bad/Web.config:4:5:4:46 | maxRequestLength=262144 | Large 'maxRequestLength' value (262144). |
\ No newline at end of file
diff --git a/csharp/ql/test/query-tests/Security Features/CWE-016/ASPNetMaxRequestLength.qlref b/csharp/ql/test/query-tests/Security Features/CWE-016/ASPNetMaxRequestLength.qlref
new file mode 100644
index 00000000000..7469d5d2e98
--- /dev/null
+++ b/csharp/ql/test/query-tests/Security Features/CWE-016/ASPNetMaxRequestLength.qlref
@@ -0,0 +1 @@
+Security Features/CWE-016/ASPNetMaxRequestLength.ql
\ No newline at end of file
diff --git a/csharp/ql/test/query-tests/Security Features/CWE-016/Web.config b/csharp/ql/test/query-tests/Security Features/CWE-016/Web.config
new file mode 100644
index 00000000000..8ba76b53dae
--- /dev/null
+++ b/csharp/ql/test/query-tests/Security Features/CWE-016/Web.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/csharp/ql/test/query-tests/Security Features/CWE-016/bad/Web.config b/csharp/ql/test/query-tests/Security Features/CWE-016/bad/Web.config
new file mode 100644
index 00000000000..ea52bd2505b
--- /dev/null
+++ b/csharp/ql/test/query-tests/Security Features/CWE-016/bad/Web.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
From 63884c1a86f8de9173681514d6f5cb420843045e Mon Sep 17 00:00:00 2001
From: Paulino Calderon
Date: Tue, 19 Nov 2019 13:06:55 -0500
Subject: [PATCH 06/44] Mixed spaces and tabs
---
.../CWE-016/ASPNetMaxRequestLength.qhelp | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/csharp/ql/src/Security Features/CWE-016/ASPNetMaxRequestLength.qhelp b/csharp/ql/src/Security Features/CWE-016/ASPNetMaxRequestLength.qhelp
index c8860bfc3c0..d180aacacbc 100644
--- a/csharp/ql/src/Security Features/CWE-016/ASPNetMaxRequestLength.qhelp
+++ b/csharp/ql/src/Security Features/CWE-016/ASPNetMaxRequestLength.qhelp
@@ -8,14 +8,16 @@
The
maxRequestLength
attribute sets the limit for the input stream buffering
- threshold in KB. Attackers can use large requests to cause denial-of-service
+ threshold in
+ KB. Attackers can use large requests to cause denial-of-service
attacks.
- The recommended value is 4096 KB but you should try setting it as small
+ The recommended value is 4096 KB but you should try setting it as
+ small
as possible according
to business requirements.
@@ -35,7 +37,8 @@
- Unless such a high value is strictly needed, it is better to set the
+ Unless such a high value is strictly needed, it is better to set
+ the
recommended value (4096 KB):
From d0b4653e329773353c10b0c2981cb182695e138b Mon Sep 17 00:00:00 2001
From: Tom Hvitved
Date: Wed, 20 Nov 2019 11:21:24 +0100
Subject: [PATCH 07/44] C#: Introduce `DataFlowErasedType`
---
.../csharp/dataflow/internal/DataFlowImpl.qll | 66 ++++++++++---------
.../dataflow/internal/DataFlowImplCommon.qll | 46 +++++++------
.../dataflow/internal/DataFlowPrivate.qll | 4 +-
3 files changed, 64 insertions(+), 52 deletions(-)
diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll
index 7ecb474f632..6f74f6f024a 100644
--- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll
+++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll
@@ -460,11 +460,11 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
*/
pragma[nomagic]
private predicate simpleParameterFlow(
- ParameterNode p, Node node, DataFlowType t, Configuration config
+ ParameterNode p, Node node, DataFlowErasedType t, Configuration config
) {
throughFlowNodeCand(node, config) and
p = node and
- t = getErasedRepr(node.getType()) and
+ t = getErasedNodeType(node) and
exists(ReturnNode ret, ReturnKind kind |
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
kind = ret.getKind() and
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localFlowStep(mid, node, config) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, _, config) and
additionalLocalFlowStep(mid, node, config) and
- t = getErasedRepr(node.getType())
+ t = getErasedNodeType(node)
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localStoreReadStep(mid, node) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
// value flow through a callable
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
exists(Node arg |
simpleParameterFlow(p, arg, t, config) and
argumentValueFlowsThrough(arg, node, _) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
// flow through a callable
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
pragma[noinline]
private predicate simpleArgumentFlowsThrough0(
- DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
+ DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
) {
nodeCand1(arg, unbind(config)) and
not outBarrier(arg, config) and
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
* additional step from the configuration.
*/
private predicate simpleArgumentFlowsThrough(
- ArgumentNode arg, Node out, DataFlowType t, Configuration config
+ ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
nodeCand1(out, unbind(config)) and
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
}
private newtype TAccessPathFront =
- TFrontNil(DataFlowType t) or
+ TFrontNil(DataFlowErasedType t) or
TFrontHead(Content f)
/**
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
*/
private class AccessPathFront extends TAccessPathFront {
string toString() {
- exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
+ exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
or
exists(Content f | this = TFrontHead(f) | result = f.toString())
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TFrontNil(result)
or
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
*/
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
flowCandFwd0(node, fromArg, apf, config) and
- if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
+ if node instanceof CastingNode
+ then compatibleTypes(getErasedNodeType(node), apf.getType())
+ else any()
}
/**
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
- private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
+ private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1067,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
+ exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
flowCandFwd(mid, fromArg, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
apf = TFrontNil(t)
@@ -1220,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
}
private newtype TAccessPath =
- TNil(DataFlowType t) or
- TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
+ TNil(DataFlowErasedType t) or
+ TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
/**
@@ -1248,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
this = TConsCons(_, _, result)
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TNil(result)
or
result = this.getHead().getContainerType()
@@ -1264,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
private class AccessPathNil extends AccessPath, TNil {
override string toString() {
- exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
+ exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
}
override predicate pop(Content head, AccessPath tail) { none() }
@@ -1278,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
private class AccessPathConsNil extends AccessPathCons, TConsNil {
override string toString() {
- exists(Content f, DataFlowType t | this = TConsNil(f, t) |
+ exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
// The `concat` becomes "" if `ppReprType` has no result.
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
)
@@ -1289,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
}
override predicate pop(Content head, AccessPath tail) {
- exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
+ exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
}
}
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
- private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
+ private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -1409,7 +1411,7 @@ private predicate flowFwd0(
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathNil nil, DataFlowType t |
+ exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
flowFwd(mid, fromArg, _, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
ap = TNil(t) and
@@ -2018,7 +2020,7 @@ private module FlowExploration {
}
private newtype TPartialAccessPath =
- TPartialNil(DataFlowType t) or
+ TPartialNil(DataFlowErasedType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
@@ -2039,7 +2041,7 @@ private module FlowExploration {
this = TPartialCons(_, result)
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
@@ -2050,11 +2052,11 @@ private module FlowExploration {
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
- exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
+ exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
@@ -2076,7 +2078,7 @@ private module FlowExploration {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2091,7 +2093,9 @@ private module FlowExploration {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
not fullBarrier(node, config) and
- if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
+ if node instanceof CastingNode
+ then compatibleTypes(getErasedNodeType(node), ap.getType())
+ else any()
)
}
@@ -2194,7 +2198,7 @@ private module FlowExploration {
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof PartialAccessPathNil and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
)
or
@@ -2206,7 +2210,7 @@ private module FlowExploration {
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof PartialAccessPathNil and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and
diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll
index 8b9c8f5abd3..f0b5cb2b347 100644
--- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll
+++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll
@@ -57,14 +57,14 @@ private module ImplCommon {
exists(Node mid |
parameterValueFlowCand(p, mid) and
step(mid, node) and
- compatibleTypes(p.getType(), node.getType())
+ compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
)
or
// flow through a callable
exists(Node arg |
parameterValueFlowCand(p, arg) and
argumentValueFlowsThroughCand(arg, node) and
- compatibleTypes(p.getType(), node.getType())
+ compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
)
}
@@ -95,7 +95,7 @@ private module ImplCommon {
argumentValueFlowsThroughCand0(call, arg, kind)
|
out = getAnOutNode(call, kind) and
- compatibleTypes(arg.getType(), out.getType())
+ compatibleTypes(getErasedNodeType(arg), getErasedNodeType(out))
)
}
@@ -183,7 +183,7 @@ private module ImplCommon {
exists(Node mid |
parameterValueFlow(p, mid, cc) and
step(mid, node) and
- compatibleTypes(p.getType(), node.getType()) and
+ compatibleTypes(getErasedNodeType(p), getErasedNodeType(node)) and
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall())
)
or
@@ -191,7 +191,7 @@ private module ImplCommon {
exists(Node arg |
parameterValueFlow(p, arg, cc) and
argumentValueFlowsThrough(arg, node, cc) and
- compatibleTypes(p.getType(), node.getType()) and
+ compatibleTypes(getErasedNodeType(p), getErasedNodeType(node)) and
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall())
)
}
@@ -226,7 +226,7 @@ private module ImplCommon {
|
out = getAnOutNode(call, kind) and
not isUnreachableInCall(out, cc.(CallContextSpecificCall).getCall()) and
- compatibleTypes(arg.getType(), out.getType())
+ compatibleTypes(getErasedNodeType(arg), getErasedNodeType(out))
)
}
}
@@ -260,7 +260,7 @@ private module ImplCommon {
exists(Node mid |
parameterValueFlowNoCtx(p, mid) and
localValueStep(mid, node) and
- compatibleTypes(p.getType(), node.getType())
+ compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
)
}
@@ -296,8 +296,8 @@ private module ImplCommon {
setterCall(call, i1, i2, f) and
node1.(ArgumentNode).argumentOf(call, i1) and
node2.getPreUpdateNode().(ArgumentNode).argumentOf(call, i2) and
- compatibleTypes(node1.getTypeBound(), f.getType()) and
- compatibleTypes(node2.getTypeBound(), f.getContainerType())
+ compatibleTypes(getErasedNodeTypeBound(node1), f.getType()) and
+ compatibleTypes(getErasedNodeTypeBound(node2), f.getContainerType())
)
}
@@ -333,8 +333,8 @@ private module ImplCommon {
exists(DataFlowCall call, ReturnKind kind |
storeReturn0(call, kind, node1, f) and
node2 = getAnOutNode(call, kind) and
- compatibleTypes(node1.getTypeBound(), f.getType()) and
- compatibleTypes(node2.getTypeBound(), f.getContainerType())
+ compatibleTypes(getErasedNodeTypeBound(node1), f.getType()) and
+ compatibleTypes(getErasedNodeTypeBound(node2), f.getContainerType())
)
}
@@ -365,8 +365,8 @@ private module ImplCommon {
exists(DataFlowCall call, ReturnKind kind |
read0(call, kind, node1, f) and
node2 = getAnOutNode(call, kind) and
- compatibleTypes(node1.getTypeBound(), f.getContainerType()) and
- compatibleTypes(node2.getTypeBound(), f.getType())
+ compatibleTypes(getErasedNodeTypeBound(node1), f.getContainerType()) and
+ compatibleTypes(getErasedNodeTypeBound(node2), f.getType())
)
}
@@ -384,7 +384,7 @@ private module ImplCommon {
store(node1, f, mid1) and
localValueStep*(mid1, mid2) and
read(mid2, f, node2) and
- compatibleTypes(node1.getTypeBound(), node2.getTypeBound())
+ compatibleTypes(getErasedNodeTypeBound(node1), getErasedNodeTypeBound(node2))
)
}
@@ -405,14 +405,14 @@ private module ImplCommon {
exists(Node mid |
parameterValueFlowCand(p, mid) and
step(mid, node) and
- compatibleTypes(p.getType(), node.getType())
+ compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
)
or
// flow through a callable
exists(Node arg |
parameterValueFlowCand(p, arg) and
argumentValueFlowsThroughCand(arg, node) and
- compatibleTypes(p.getType(), node.getType())
+ compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
)
}
@@ -443,7 +443,7 @@ private module ImplCommon {
argumentValueFlowsThroughCand0(call, arg, kind)
|
out = getAnOutNode(call, kind) and
- compatibleTypes(arg.getType(), out.getType())
+ compatibleTypes(getErasedNodeType(arg), getErasedNodeType(out))
)
}
@@ -531,7 +531,7 @@ private module ImplCommon {
exists(Node mid |
parameterValueFlow(p, mid, cc) and
step(mid, node) and
- compatibleTypes(p.getType(), node.getType()) and
+ compatibleTypes(getErasedNodeType(p), getErasedNodeType(node)) and
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall())
)
or
@@ -539,7 +539,7 @@ private module ImplCommon {
exists(Node arg |
parameterValueFlow(p, arg, cc) and
argumentValueFlowsThrough(arg, node, cc) and
- compatibleTypes(p.getType(), node.getType()) and
+ compatibleTypes(getErasedNodeType(p), getErasedNodeType(node)) and
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall())
)
}
@@ -574,7 +574,7 @@ private module ImplCommon {
|
out = getAnOutNode(call, kind) and
not isUnreachableInCall(out, cc.(CallContextSpecificCall).getCall()) and
- compatibleTypes(arg.getType(), out.getType())
+ compatibleTypes(getErasedNodeType(arg), getErasedNodeType(out))
)
}
}
@@ -860,4 +860,10 @@ private module ImplCommon {
or
result = viableCallable(call) and cc instanceof CallContextReturn
}
+
+ pragma[noinline]
+ DataFlowErasedType getErasedNodeType(Node n) { result = getErasedRepr(n.getType()) }
+
+ pragma[noinline]
+ DataFlowErasedType getErasedNodeTypeBound(Node n) { result = getErasedRepr(n.getTypeBound()) }
}
diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll
index d30ed00a0c4..7f8730c7ee9 100644
--- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll
+++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll
@@ -1307,7 +1307,7 @@ private predicate suppressUnusedType(DotNet::Type t) { any() }
* Type-based pruning is disabled for now, so this is a stub implementation.
*/
bindingset[t]
-DotNet::Type getErasedRepr(DotNet::Type t) {
+DataFlowErasedType getErasedRepr(DataFlowType t) {
// stub implementation
suppressUnusedType(t) and result instanceof ObjectType
}
@@ -1378,6 +1378,8 @@ class DataFlowExpr = DotNet::Expr;
class DataFlowType = DotNet::Type;
+class DataFlowErasedType = DotNet::Type;
+
class DataFlowLocation = Location;
/** Holds if `e` is an expression that always has the same Boolean value `val`. */
From 6c0dbcfca2f03cf8627390de2da17180a10c8c82 Mon Sep 17 00:00:00 2001
From: Tom Hvitved
Date: Wed, 20 Nov 2019 14:02:15 +0100
Subject: [PATCH 08/44] Java/C++: Add `DataFlowErasedType` aliases
---
.../src/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll | 2 ++
.../semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll | 2 ++
.../src/semmle/code/java/dataflow/internal/DataFlowPrivate.qll | 2 ++
3 files changed, 6 insertions(+)
diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll
index ab95d38ed0f..9f58391d7c1 100644
--- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll
+++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll
@@ -282,6 +282,8 @@ class DataFlowExpr = Expr;
class DataFlowType = Type;
+class DataFlowErasedType = Type;
+
class DataFlowLocation = Location;
/** A function call relevant for data flow. */
diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll
index f6306759771..0ce14e90e6c 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll
@@ -191,6 +191,8 @@ class DataFlowExpr = Expr;
class DataFlowType = Type;
+class DataFlowErasedType = Type;
+
class DataFlowLocation = Location;
/** A function call relevant for data flow. */
diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowPrivate.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowPrivate.qll
index 5255e06af5c..698baf84912 100644
--- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowPrivate.qll
+++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowPrivate.qll
@@ -279,6 +279,8 @@ class DataFlowExpr = Expr;
class DataFlowType = RefType;
+class DataFlowErasedType = RefType;
+
class DataFlowLocation = Location;
class DataFlowCall extends Call {
From acc7d5298d1af1e10e6b43d83d8d1249e719be11 Mon Sep 17 00:00:00 2001
From: Tom Hvitved
Date: Wed, 20 Nov 2019 14:02:42 +0100
Subject: [PATCH 09/44] Data flow: Sync files
---
.../cpp/dataflow/internal/DataFlowImpl.qll | 66 ++++++++++---------
.../cpp/dataflow/internal/DataFlowImpl2.qll | 66 ++++++++++---------
.../cpp/dataflow/internal/DataFlowImpl3.qll | 66 ++++++++++---------
.../cpp/dataflow/internal/DataFlowImpl4.qll | 66 ++++++++++---------
.../dataflow/internal/DataFlowImplCommon.qll | 46 +++++++------
.../dataflow/internal/DataFlowImplLocal.qll | 66 ++++++++++---------
.../cpp/ir/dataflow/internal/DataFlowImpl.qll | 66 ++++++++++---------
.../ir/dataflow/internal/DataFlowImpl2.qll | 66 ++++++++++---------
.../ir/dataflow/internal/DataFlowImpl3.qll | 66 ++++++++++---------
.../ir/dataflow/internal/DataFlowImpl4.qll | 66 ++++++++++---------
.../dataflow/internal/DataFlowImplCommon.qll | 46 +++++++------
.../dataflow/internal/DataFlowImpl2.qll | 66 ++++++++++---------
.../dataflow/internal/DataFlowImpl3.qll | 66 ++++++++++---------
.../dataflow/internal/DataFlowImpl4.qll | 66 ++++++++++---------
.../dataflow/internal/DataFlowImpl5.qll | 66 ++++++++++---------
.../java/dataflow/internal/DataFlowImpl.qll | 66 ++++++++++---------
.../java/dataflow/internal/DataFlowImpl2.qll | 66 ++++++++++---------
.../java/dataflow/internal/DataFlowImpl3.qll | 66 ++++++++++---------
.../java/dataflow/internal/DataFlowImpl4.qll | 66 ++++++++++---------
.../java/dataflow/internal/DataFlowImpl5.qll | 66 ++++++++++---------
.../dataflow/internal/DataFlowImplCommon.qll | 46 +++++++------
21 files changed, 708 insertions(+), 618 deletions(-)
diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll
index 7ecb474f632..6f74f6f024a 100644
--- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll
+++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll
@@ -460,11 +460,11 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
*/
pragma[nomagic]
private predicate simpleParameterFlow(
- ParameterNode p, Node node, DataFlowType t, Configuration config
+ ParameterNode p, Node node, DataFlowErasedType t, Configuration config
) {
throughFlowNodeCand(node, config) and
p = node and
- t = getErasedRepr(node.getType()) and
+ t = getErasedNodeType(node) and
exists(ReturnNode ret, ReturnKind kind |
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
kind = ret.getKind() and
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localFlowStep(mid, node, config) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, _, config) and
additionalLocalFlowStep(mid, node, config) and
- t = getErasedRepr(node.getType())
+ t = getErasedNodeType(node)
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localStoreReadStep(mid, node) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
// value flow through a callable
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
exists(Node arg |
simpleParameterFlow(p, arg, t, config) and
argumentValueFlowsThrough(arg, node, _) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
// flow through a callable
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
pragma[noinline]
private predicate simpleArgumentFlowsThrough0(
- DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
+ DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
) {
nodeCand1(arg, unbind(config)) and
not outBarrier(arg, config) and
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
* additional step from the configuration.
*/
private predicate simpleArgumentFlowsThrough(
- ArgumentNode arg, Node out, DataFlowType t, Configuration config
+ ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
nodeCand1(out, unbind(config)) and
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
}
private newtype TAccessPathFront =
- TFrontNil(DataFlowType t) or
+ TFrontNil(DataFlowErasedType t) or
TFrontHead(Content f)
/**
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
*/
private class AccessPathFront extends TAccessPathFront {
string toString() {
- exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
+ exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
or
exists(Content f | this = TFrontHead(f) | result = f.toString())
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TFrontNil(result)
or
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
*/
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
flowCandFwd0(node, fromArg, apf, config) and
- if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
+ if node instanceof CastingNode
+ then compatibleTypes(getErasedNodeType(node), apf.getType())
+ else any()
}
/**
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
- private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
+ private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1067,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
+ exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
flowCandFwd(mid, fromArg, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
apf = TFrontNil(t)
@@ -1220,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
}
private newtype TAccessPath =
- TNil(DataFlowType t) or
- TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
+ TNil(DataFlowErasedType t) or
+ TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
/**
@@ -1248,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
this = TConsCons(_, _, result)
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TNil(result)
or
result = this.getHead().getContainerType()
@@ -1264,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
private class AccessPathNil extends AccessPath, TNil {
override string toString() {
- exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
+ exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
}
override predicate pop(Content head, AccessPath tail) { none() }
@@ -1278,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
private class AccessPathConsNil extends AccessPathCons, TConsNil {
override string toString() {
- exists(Content f, DataFlowType t | this = TConsNil(f, t) |
+ exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
// The `concat` becomes "" if `ppReprType` has no result.
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
)
@@ -1289,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
}
override predicate pop(Content head, AccessPath tail) {
- exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
+ exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
}
}
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
- private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
+ private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -1409,7 +1411,7 @@ private predicate flowFwd0(
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathNil nil, DataFlowType t |
+ exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
flowFwd(mid, fromArg, _, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
ap = TNil(t) and
@@ -2018,7 +2020,7 @@ private module FlowExploration {
}
private newtype TPartialAccessPath =
- TPartialNil(DataFlowType t) or
+ TPartialNil(DataFlowErasedType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
@@ -2039,7 +2041,7 @@ private module FlowExploration {
this = TPartialCons(_, result)
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
@@ -2050,11 +2052,11 @@ private module FlowExploration {
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
- exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
+ exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
@@ -2076,7 +2078,7 @@ private module FlowExploration {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2091,7 +2093,9 @@ private module FlowExploration {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
not fullBarrier(node, config) and
- if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
+ if node instanceof CastingNode
+ then compatibleTypes(getErasedNodeType(node), ap.getType())
+ else any()
)
}
@@ -2194,7 +2198,7 @@ private module FlowExploration {
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof PartialAccessPathNil and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
)
or
@@ -2206,7 +2210,7 @@ private module FlowExploration {
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof PartialAccessPathNil and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and
diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll
index 7ecb474f632..6f74f6f024a 100644
--- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll
+++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll
@@ -460,11 +460,11 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
*/
pragma[nomagic]
private predicate simpleParameterFlow(
- ParameterNode p, Node node, DataFlowType t, Configuration config
+ ParameterNode p, Node node, DataFlowErasedType t, Configuration config
) {
throughFlowNodeCand(node, config) and
p = node and
- t = getErasedRepr(node.getType()) and
+ t = getErasedNodeType(node) and
exists(ReturnNode ret, ReturnKind kind |
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
kind = ret.getKind() and
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localFlowStep(mid, node, config) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, _, config) and
additionalLocalFlowStep(mid, node, config) and
- t = getErasedRepr(node.getType())
+ t = getErasedNodeType(node)
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localStoreReadStep(mid, node) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
// value flow through a callable
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
exists(Node arg |
simpleParameterFlow(p, arg, t, config) and
argumentValueFlowsThrough(arg, node, _) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
// flow through a callable
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
pragma[noinline]
private predicate simpleArgumentFlowsThrough0(
- DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
+ DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
) {
nodeCand1(arg, unbind(config)) and
not outBarrier(arg, config) and
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
* additional step from the configuration.
*/
private predicate simpleArgumentFlowsThrough(
- ArgumentNode arg, Node out, DataFlowType t, Configuration config
+ ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
nodeCand1(out, unbind(config)) and
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
}
private newtype TAccessPathFront =
- TFrontNil(DataFlowType t) or
+ TFrontNil(DataFlowErasedType t) or
TFrontHead(Content f)
/**
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
*/
private class AccessPathFront extends TAccessPathFront {
string toString() {
- exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
+ exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
or
exists(Content f | this = TFrontHead(f) | result = f.toString())
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TFrontNil(result)
or
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
*/
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
flowCandFwd0(node, fromArg, apf, config) and
- if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
+ if node instanceof CastingNode
+ then compatibleTypes(getErasedNodeType(node), apf.getType())
+ else any()
}
/**
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
- private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
+ private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1067,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
+ exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
flowCandFwd(mid, fromArg, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
apf = TFrontNil(t)
@@ -1220,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
}
private newtype TAccessPath =
- TNil(DataFlowType t) or
- TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
+ TNil(DataFlowErasedType t) or
+ TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
/**
@@ -1248,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
this = TConsCons(_, _, result)
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TNil(result)
or
result = this.getHead().getContainerType()
@@ -1264,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
private class AccessPathNil extends AccessPath, TNil {
override string toString() {
- exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
+ exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
}
override predicate pop(Content head, AccessPath tail) { none() }
@@ -1278,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
private class AccessPathConsNil extends AccessPathCons, TConsNil {
override string toString() {
- exists(Content f, DataFlowType t | this = TConsNil(f, t) |
+ exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
// The `concat` becomes "" if `ppReprType` has no result.
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
)
@@ -1289,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
}
override predicate pop(Content head, AccessPath tail) {
- exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
+ exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
}
}
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
- private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
+ private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -1409,7 +1411,7 @@ private predicate flowFwd0(
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathNil nil, DataFlowType t |
+ exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
flowFwd(mid, fromArg, _, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
ap = TNil(t) and
@@ -2018,7 +2020,7 @@ private module FlowExploration {
}
private newtype TPartialAccessPath =
- TPartialNil(DataFlowType t) or
+ TPartialNil(DataFlowErasedType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
@@ -2039,7 +2041,7 @@ private module FlowExploration {
this = TPartialCons(_, result)
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
@@ -2050,11 +2052,11 @@ private module FlowExploration {
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
- exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
+ exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
@@ -2076,7 +2078,7 @@ private module FlowExploration {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2091,7 +2093,9 @@ private module FlowExploration {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
not fullBarrier(node, config) and
- if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
+ if node instanceof CastingNode
+ then compatibleTypes(getErasedNodeType(node), ap.getType())
+ else any()
)
}
@@ -2194,7 +2198,7 @@ private module FlowExploration {
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof PartialAccessPathNil and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
)
or
@@ -2206,7 +2210,7 @@ private module FlowExploration {
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof PartialAccessPathNil and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and
diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll
index 7ecb474f632..6f74f6f024a 100644
--- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll
+++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll
@@ -460,11 +460,11 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
*/
pragma[nomagic]
private predicate simpleParameterFlow(
- ParameterNode p, Node node, DataFlowType t, Configuration config
+ ParameterNode p, Node node, DataFlowErasedType t, Configuration config
) {
throughFlowNodeCand(node, config) and
p = node and
- t = getErasedRepr(node.getType()) and
+ t = getErasedNodeType(node) and
exists(ReturnNode ret, ReturnKind kind |
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
kind = ret.getKind() and
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localFlowStep(mid, node, config) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, _, config) and
additionalLocalFlowStep(mid, node, config) and
- t = getErasedRepr(node.getType())
+ t = getErasedNodeType(node)
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localStoreReadStep(mid, node) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
// value flow through a callable
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
exists(Node arg |
simpleParameterFlow(p, arg, t, config) and
argumentValueFlowsThrough(arg, node, _) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
// flow through a callable
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
pragma[noinline]
private predicate simpleArgumentFlowsThrough0(
- DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
+ DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
) {
nodeCand1(arg, unbind(config)) and
not outBarrier(arg, config) and
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
* additional step from the configuration.
*/
private predicate simpleArgumentFlowsThrough(
- ArgumentNode arg, Node out, DataFlowType t, Configuration config
+ ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
nodeCand1(out, unbind(config)) and
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
}
private newtype TAccessPathFront =
- TFrontNil(DataFlowType t) or
+ TFrontNil(DataFlowErasedType t) or
TFrontHead(Content f)
/**
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
*/
private class AccessPathFront extends TAccessPathFront {
string toString() {
- exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
+ exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
or
exists(Content f | this = TFrontHead(f) | result = f.toString())
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TFrontNil(result)
or
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
*/
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
flowCandFwd0(node, fromArg, apf, config) and
- if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
+ if node instanceof CastingNode
+ then compatibleTypes(getErasedNodeType(node), apf.getType())
+ else any()
}
/**
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
- private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
+ private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1067,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
+ exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
flowCandFwd(mid, fromArg, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
apf = TFrontNil(t)
@@ -1220,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
}
private newtype TAccessPath =
- TNil(DataFlowType t) or
- TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
+ TNil(DataFlowErasedType t) or
+ TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
/**
@@ -1248,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
this = TConsCons(_, _, result)
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TNil(result)
or
result = this.getHead().getContainerType()
@@ -1264,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
private class AccessPathNil extends AccessPath, TNil {
override string toString() {
- exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
+ exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
}
override predicate pop(Content head, AccessPath tail) { none() }
@@ -1278,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
private class AccessPathConsNil extends AccessPathCons, TConsNil {
override string toString() {
- exists(Content f, DataFlowType t | this = TConsNil(f, t) |
+ exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
// The `concat` becomes "" if `ppReprType` has no result.
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
)
@@ -1289,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
}
override predicate pop(Content head, AccessPath tail) {
- exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
+ exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
}
}
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
- private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
+ private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -1409,7 +1411,7 @@ private predicate flowFwd0(
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathNil nil, DataFlowType t |
+ exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
flowFwd(mid, fromArg, _, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
ap = TNil(t) and
@@ -2018,7 +2020,7 @@ private module FlowExploration {
}
private newtype TPartialAccessPath =
- TPartialNil(DataFlowType t) or
+ TPartialNil(DataFlowErasedType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
@@ -2039,7 +2041,7 @@ private module FlowExploration {
this = TPartialCons(_, result)
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
@@ -2050,11 +2052,11 @@ private module FlowExploration {
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
- exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
+ exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
@@ -2076,7 +2078,7 @@ private module FlowExploration {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2091,7 +2093,9 @@ private module FlowExploration {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
not fullBarrier(node, config) and
- if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
+ if node instanceof CastingNode
+ then compatibleTypes(getErasedNodeType(node), ap.getType())
+ else any()
)
}
@@ -2194,7 +2198,7 @@ private module FlowExploration {
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof PartialAccessPathNil and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
)
or
@@ -2206,7 +2210,7 @@ private module FlowExploration {
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof PartialAccessPathNil and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and
diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll
index 7ecb474f632..6f74f6f024a 100644
--- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll
+++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll
@@ -460,11 +460,11 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
*/
pragma[nomagic]
private predicate simpleParameterFlow(
- ParameterNode p, Node node, DataFlowType t, Configuration config
+ ParameterNode p, Node node, DataFlowErasedType t, Configuration config
) {
throughFlowNodeCand(node, config) and
p = node and
- t = getErasedRepr(node.getType()) and
+ t = getErasedNodeType(node) and
exists(ReturnNode ret, ReturnKind kind |
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
kind = ret.getKind() and
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localFlowStep(mid, node, config) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, _, config) and
additionalLocalFlowStep(mid, node, config) and
- t = getErasedRepr(node.getType())
+ t = getErasedNodeType(node)
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localStoreReadStep(mid, node) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
// value flow through a callable
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
exists(Node arg |
simpleParameterFlow(p, arg, t, config) and
argumentValueFlowsThrough(arg, node, _) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
// flow through a callable
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
pragma[noinline]
private predicate simpleArgumentFlowsThrough0(
- DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
+ DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
) {
nodeCand1(arg, unbind(config)) and
not outBarrier(arg, config) and
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
* additional step from the configuration.
*/
private predicate simpleArgumentFlowsThrough(
- ArgumentNode arg, Node out, DataFlowType t, Configuration config
+ ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
nodeCand1(out, unbind(config)) and
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
}
private newtype TAccessPathFront =
- TFrontNil(DataFlowType t) or
+ TFrontNil(DataFlowErasedType t) or
TFrontHead(Content f)
/**
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
*/
private class AccessPathFront extends TAccessPathFront {
string toString() {
- exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
+ exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
or
exists(Content f | this = TFrontHead(f) | result = f.toString())
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TFrontNil(result)
or
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
*/
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
flowCandFwd0(node, fromArg, apf, config) and
- if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
+ if node instanceof CastingNode
+ then compatibleTypes(getErasedNodeType(node), apf.getType())
+ else any()
}
/**
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
- private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
+ private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1067,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
+ exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
flowCandFwd(mid, fromArg, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
apf = TFrontNil(t)
@@ -1220,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
}
private newtype TAccessPath =
- TNil(DataFlowType t) or
- TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
+ TNil(DataFlowErasedType t) or
+ TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
/**
@@ -1248,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
this = TConsCons(_, _, result)
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TNil(result)
or
result = this.getHead().getContainerType()
@@ -1264,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
private class AccessPathNil extends AccessPath, TNil {
override string toString() {
- exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
+ exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
}
override predicate pop(Content head, AccessPath tail) { none() }
@@ -1278,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
private class AccessPathConsNil extends AccessPathCons, TConsNil {
override string toString() {
- exists(Content f, DataFlowType t | this = TConsNil(f, t) |
+ exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
// The `concat` becomes "" if `ppReprType` has no result.
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
)
@@ -1289,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
}
override predicate pop(Content head, AccessPath tail) {
- exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
+ exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
}
}
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
- private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
+ private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -1409,7 +1411,7 @@ private predicate flowFwd0(
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathNil nil, DataFlowType t |
+ exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
flowFwd(mid, fromArg, _, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
ap = TNil(t) and
@@ -2018,7 +2020,7 @@ private module FlowExploration {
}
private newtype TPartialAccessPath =
- TPartialNil(DataFlowType t) or
+ TPartialNil(DataFlowErasedType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
@@ -2039,7 +2041,7 @@ private module FlowExploration {
this = TPartialCons(_, result)
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
@@ -2050,11 +2052,11 @@ private module FlowExploration {
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
- exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
+ exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
@@ -2076,7 +2078,7 @@ private module FlowExploration {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2091,7 +2093,9 @@ private module FlowExploration {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
not fullBarrier(node, config) and
- if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
+ if node instanceof CastingNode
+ then compatibleTypes(getErasedNodeType(node), ap.getType())
+ else any()
)
}
@@ -2194,7 +2198,7 @@ private module FlowExploration {
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof PartialAccessPathNil and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
)
or
@@ -2206,7 +2210,7 @@ private module FlowExploration {
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof PartialAccessPathNil and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and
diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll
index 8b9c8f5abd3..f0b5cb2b347 100644
--- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll
+++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll
@@ -57,14 +57,14 @@ private module ImplCommon {
exists(Node mid |
parameterValueFlowCand(p, mid) and
step(mid, node) and
- compatibleTypes(p.getType(), node.getType())
+ compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
)
or
// flow through a callable
exists(Node arg |
parameterValueFlowCand(p, arg) and
argumentValueFlowsThroughCand(arg, node) and
- compatibleTypes(p.getType(), node.getType())
+ compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
)
}
@@ -95,7 +95,7 @@ private module ImplCommon {
argumentValueFlowsThroughCand0(call, arg, kind)
|
out = getAnOutNode(call, kind) and
- compatibleTypes(arg.getType(), out.getType())
+ compatibleTypes(getErasedNodeType(arg), getErasedNodeType(out))
)
}
@@ -183,7 +183,7 @@ private module ImplCommon {
exists(Node mid |
parameterValueFlow(p, mid, cc) and
step(mid, node) and
- compatibleTypes(p.getType(), node.getType()) and
+ compatibleTypes(getErasedNodeType(p), getErasedNodeType(node)) and
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall())
)
or
@@ -191,7 +191,7 @@ private module ImplCommon {
exists(Node arg |
parameterValueFlow(p, arg, cc) and
argumentValueFlowsThrough(arg, node, cc) and
- compatibleTypes(p.getType(), node.getType()) and
+ compatibleTypes(getErasedNodeType(p), getErasedNodeType(node)) and
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall())
)
}
@@ -226,7 +226,7 @@ private module ImplCommon {
|
out = getAnOutNode(call, kind) and
not isUnreachableInCall(out, cc.(CallContextSpecificCall).getCall()) and
- compatibleTypes(arg.getType(), out.getType())
+ compatibleTypes(getErasedNodeType(arg), getErasedNodeType(out))
)
}
}
@@ -260,7 +260,7 @@ private module ImplCommon {
exists(Node mid |
parameterValueFlowNoCtx(p, mid) and
localValueStep(mid, node) and
- compatibleTypes(p.getType(), node.getType())
+ compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
)
}
@@ -296,8 +296,8 @@ private module ImplCommon {
setterCall(call, i1, i2, f) and
node1.(ArgumentNode).argumentOf(call, i1) and
node2.getPreUpdateNode().(ArgumentNode).argumentOf(call, i2) and
- compatibleTypes(node1.getTypeBound(), f.getType()) and
- compatibleTypes(node2.getTypeBound(), f.getContainerType())
+ compatibleTypes(getErasedNodeTypeBound(node1), f.getType()) and
+ compatibleTypes(getErasedNodeTypeBound(node2), f.getContainerType())
)
}
@@ -333,8 +333,8 @@ private module ImplCommon {
exists(DataFlowCall call, ReturnKind kind |
storeReturn0(call, kind, node1, f) and
node2 = getAnOutNode(call, kind) and
- compatibleTypes(node1.getTypeBound(), f.getType()) and
- compatibleTypes(node2.getTypeBound(), f.getContainerType())
+ compatibleTypes(getErasedNodeTypeBound(node1), f.getType()) and
+ compatibleTypes(getErasedNodeTypeBound(node2), f.getContainerType())
)
}
@@ -365,8 +365,8 @@ private module ImplCommon {
exists(DataFlowCall call, ReturnKind kind |
read0(call, kind, node1, f) and
node2 = getAnOutNode(call, kind) and
- compatibleTypes(node1.getTypeBound(), f.getContainerType()) and
- compatibleTypes(node2.getTypeBound(), f.getType())
+ compatibleTypes(getErasedNodeTypeBound(node1), f.getContainerType()) and
+ compatibleTypes(getErasedNodeTypeBound(node2), f.getType())
)
}
@@ -384,7 +384,7 @@ private module ImplCommon {
store(node1, f, mid1) and
localValueStep*(mid1, mid2) and
read(mid2, f, node2) and
- compatibleTypes(node1.getTypeBound(), node2.getTypeBound())
+ compatibleTypes(getErasedNodeTypeBound(node1), getErasedNodeTypeBound(node2))
)
}
@@ -405,14 +405,14 @@ private module ImplCommon {
exists(Node mid |
parameterValueFlowCand(p, mid) and
step(mid, node) and
- compatibleTypes(p.getType(), node.getType())
+ compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
)
or
// flow through a callable
exists(Node arg |
parameterValueFlowCand(p, arg) and
argumentValueFlowsThroughCand(arg, node) and
- compatibleTypes(p.getType(), node.getType())
+ compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
)
}
@@ -443,7 +443,7 @@ private module ImplCommon {
argumentValueFlowsThroughCand0(call, arg, kind)
|
out = getAnOutNode(call, kind) and
- compatibleTypes(arg.getType(), out.getType())
+ compatibleTypes(getErasedNodeType(arg), getErasedNodeType(out))
)
}
@@ -531,7 +531,7 @@ private module ImplCommon {
exists(Node mid |
parameterValueFlow(p, mid, cc) and
step(mid, node) and
- compatibleTypes(p.getType(), node.getType()) and
+ compatibleTypes(getErasedNodeType(p), getErasedNodeType(node)) and
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall())
)
or
@@ -539,7 +539,7 @@ private module ImplCommon {
exists(Node arg |
parameterValueFlow(p, arg, cc) and
argumentValueFlowsThrough(arg, node, cc) and
- compatibleTypes(p.getType(), node.getType()) and
+ compatibleTypes(getErasedNodeType(p), getErasedNodeType(node)) and
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall())
)
}
@@ -574,7 +574,7 @@ private module ImplCommon {
|
out = getAnOutNode(call, kind) and
not isUnreachableInCall(out, cc.(CallContextSpecificCall).getCall()) and
- compatibleTypes(arg.getType(), out.getType())
+ compatibleTypes(getErasedNodeType(arg), getErasedNodeType(out))
)
}
}
@@ -860,4 +860,10 @@ private module ImplCommon {
or
result = viableCallable(call) and cc instanceof CallContextReturn
}
+
+ pragma[noinline]
+ DataFlowErasedType getErasedNodeType(Node n) { result = getErasedRepr(n.getType()) }
+
+ pragma[noinline]
+ DataFlowErasedType getErasedNodeTypeBound(Node n) { result = getErasedRepr(n.getTypeBound()) }
}
diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll
index 7ecb474f632..6f74f6f024a 100644
--- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll
+++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll
@@ -460,11 +460,11 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
*/
pragma[nomagic]
private predicate simpleParameterFlow(
- ParameterNode p, Node node, DataFlowType t, Configuration config
+ ParameterNode p, Node node, DataFlowErasedType t, Configuration config
) {
throughFlowNodeCand(node, config) and
p = node and
- t = getErasedRepr(node.getType()) and
+ t = getErasedNodeType(node) and
exists(ReturnNode ret, ReturnKind kind |
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
kind = ret.getKind() and
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localFlowStep(mid, node, config) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, _, config) and
additionalLocalFlowStep(mid, node, config) and
- t = getErasedRepr(node.getType())
+ t = getErasedNodeType(node)
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localStoreReadStep(mid, node) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
// value flow through a callable
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
exists(Node arg |
simpleParameterFlow(p, arg, t, config) and
argumentValueFlowsThrough(arg, node, _) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
// flow through a callable
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
pragma[noinline]
private predicate simpleArgumentFlowsThrough0(
- DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
+ DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
) {
nodeCand1(arg, unbind(config)) and
not outBarrier(arg, config) and
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
* additional step from the configuration.
*/
private predicate simpleArgumentFlowsThrough(
- ArgumentNode arg, Node out, DataFlowType t, Configuration config
+ ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
nodeCand1(out, unbind(config)) and
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
}
private newtype TAccessPathFront =
- TFrontNil(DataFlowType t) or
+ TFrontNil(DataFlowErasedType t) or
TFrontHead(Content f)
/**
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
*/
private class AccessPathFront extends TAccessPathFront {
string toString() {
- exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
+ exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
or
exists(Content f | this = TFrontHead(f) | result = f.toString())
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TFrontNil(result)
or
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
*/
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
flowCandFwd0(node, fromArg, apf, config) and
- if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
+ if node instanceof CastingNode
+ then compatibleTypes(getErasedNodeType(node), apf.getType())
+ else any()
}
/**
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
- private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
+ private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1067,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
+ exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
flowCandFwd(mid, fromArg, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
apf = TFrontNil(t)
@@ -1220,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
}
private newtype TAccessPath =
- TNil(DataFlowType t) or
- TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
+ TNil(DataFlowErasedType t) or
+ TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
/**
@@ -1248,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
this = TConsCons(_, _, result)
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TNil(result)
or
result = this.getHead().getContainerType()
@@ -1264,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
private class AccessPathNil extends AccessPath, TNil {
override string toString() {
- exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
+ exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
}
override predicate pop(Content head, AccessPath tail) { none() }
@@ -1278,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
private class AccessPathConsNil extends AccessPathCons, TConsNil {
override string toString() {
- exists(Content f, DataFlowType t | this = TConsNil(f, t) |
+ exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
// The `concat` becomes "" if `ppReprType` has no result.
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
)
@@ -1289,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
}
override predicate pop(Content head, AccessPath tail) {
- exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
+ exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
}
}
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
- private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
+ private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -1409,7 +1411,7 @@ private predicate flowFwd0(
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathNil nil, DataFlowType t |
+ exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
flowFwd(mid, fromArg, _, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
ap = TNil(t) and
@@ -2018,7 +2020,7 @@ private module FlowExploration {
}
private newtype TPartialAccessPath =
- TPartialNil(DataFlowType t) or
+ TPartialNil(DataFlowErasedType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
@@ -2039,7 +2041,7 @@ private module FlowExploration {
this = TPartialCons(_, result)
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
@@ -2050,11 +2052,11 @@ private module FlowExploration {
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
- exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
+ exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
@@ -2076,7 +2078,7 @@ private module FlowExploration {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2091,7 +2093,9 @@ private module FlowExploration {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
not fullBarrier(node, config) and
- if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
+ if node instanceof CastingNode
+ then compatibleTypes(getErasedNodeType(node), ap.getType())
+ else any()
)
}
@@ -2194,7 +2198,7 @@ private module FlowExploration {
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof PartialAccessPathNil and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
)
or
@@ -2206,7 +2210,7 @@ private module FlowExploration {
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof PartialAccessPathNil and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and
diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll
index 7ecb474f632..6f74f6f024a 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll
@@ -460,11 +460,11 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
*/
pragma[nomagic]
private predicate simpleParameterFlow(
- ParameterNode p, Node node, DataFlowType t, Configuration config
+ ParameterNode p, Node node, DataFlowErasedType t, Configuration config
) {
throughFlowNodeCand(node, config) and
p = node and
- t = getErasedRepr(node.getType()) and
+ t = getErasedNodeType(node) and
exists(ReturnNode ret, ReturnKind kind |
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
kind = ret.getKind() and
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localFlowStep(mid, node, config) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, _, config) and
additionalLocalFlowStep(mid, node, config) and
- t = getErasedRepr(node.getType())
+ t = getErasedNodeType(node)
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localStoreReadStep(mid, node) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
// value flow through a callable
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
exists(Node arg |
simpleParameterFlow(p, arg, t, config) and
argumentValueFlowsThrough(arg, node, _) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
// flow through a callable
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
pragma[noinline]
private predicate simpleArgumentFlowsThrough0(
- DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
+ DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
) {
nodeCand1(arg, unbind(config)) and
not outBarrier(arg, config) and
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
* additional step from the configuration.
*/
private predicate simpleArgumentFlowsThrough(
- ArgumentNode arg, Node out, DataFlowType t, Configuration config
+ ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
nodeCand1(out, unbind(config)) and
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
}
private newtype TAccessPathFront =
- TFrontNil(DataFlowType t) or
+ TFrontNil(DataFlowErasedType t) or
TFrontHead(Content f)
/**
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
*/
private class AccessPathFront extends TAccessPathFront {
string toString() {
- exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
+ exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
or
exists(Content f | this = TFrontHead(f) | result = f.toString())
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TFrontNil(result)
or
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
*/
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
flowCandFwd0(node, fromArg, apf, config) and
- if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
+ if node instanceof CastingNode
+ then compatibleTypes(getErasedNodeType(node), apf.getType())
+ else any()
}
/**
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
- private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
+ private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1067,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
+ exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
flowCandFwd(mid, fromArg, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
apf = TFrontNil(t)
@@ -1220,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
}
private newtype TAccessPath =
- TNil(DataFlowType t) or
- TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
+ TNil(DataFlowErasedType t) or
+ TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
/**
@@ -1248,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
this = TConsCons(_, _, result)
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TNil(result)
or
result = this.getHead().getContainerType()
@@ -1264,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
private class AccessPathNil extends AccessPath, TNil {
override string toString() {
- exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
+ exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
}
override predicate pop(Content head, AccessPath tail) { none() }
@@ -1278,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
private class AccessPathConsNil extends AccessPathCons, TConsNil {
override string toString() {
- exists(Content f, DataFlowType t | this = TConsNil(f, t) |
+ exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
// The `concat` becomes "" if `ppReprType` has no result.
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
)
@@ -1289,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
}
override predicate pop(Content head, AccessPath tail) {
- exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
+ exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
}
}
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
- private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
+ private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -1409,7 +1411,7 @@ private predicate flowFwd0(
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathNil nil, DataFlowType t |
+ exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
flowFwd(mid, fromArg, _, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
ap = TNil(t) and
@@ -2018,7 +2020,7 @@ private module FlowExploration {
}
private newtype TPartialAccessPath =
- TPartialNil(DataFlowType t) or
+ TPartialNil(DataFlowErasedType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
@@ -2039,7 +2041,7 @@ private module FlowExploration {
this = TPartialCons(_, result)
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
@@ -2050,11 +2052,11 @@ private module FlowExploration {
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
- exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
+ exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
@@ -2076,7 +2078,7 @@ private module FlowExploration {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2091,7 +2093,9 @@ private module FlowExploration {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
not fullBarrier(node, config) and
- if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
+ if node instanceof CastingNode
+ then compatibleTypes(getErasedNodeType(node), ap.getType())
+ else any()
)
}
@@ -2194,7 +2198,7 @@ private module FlowExploration {
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof PartialAccessPathNil and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
)
or
@@ -2206,7 +2210,7 @@ private module FlowExploration {
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof PartialAccessPathNil and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and
diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll
index 7ecb474f632..6f74f6f024a 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll
@@ -460,11 +460,11 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
*/
pragma[nomagic]
private predicate simpleParameterFlow(
- ParameterNode p, Node node, DataFlowType t, Configuration config
+ ParameterNode p, Node node, DataFlowErasedType t, Configuration config
) {
throughFlowNodeCand(node, config) and
p = node and
- t = getErasedRepr(node.getType()) and
+ t = getErasedNodeType(node) and
exists(ReturnNode ret, ReturnKind kind |
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
kind = ret.getKind() and
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localFlowStep(mid, node, config) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, _, config) and
additionalLocalFlowStep(mid, node, config) and
- t = getErasedRepr(node.getType())
+ t = getErasedNodeType(node)
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localStoreReadStep(mid, node) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
// value flow through a callable
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
exists(Node arg |
simpleParameterFlow(p, arg, t, config) and
argumentValueFlowsThrough(arg, node, _) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
// flow through a callable
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
pragma[noinline]
private predicate simpleArgumentFlowsThrough0(
- DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
+ DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
) {
nodeCand1(arg, unbind(config)) and
not outBarrier(arg, config) and
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
* additional step from the configuration.
*/
private predicate simpleArgumentFlowsThrough(
- ArgumentNode arg, Node out, DataFlowType t, Configuration config
+ ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
nodeCand1(out, unbind(config)) and
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
}
private newtype TAccessPathFront =
- TFrontNil(DataFlowType t) or
+ TFrontNil(DataFlowErasedType t) or
TFrontHead(Content f)
/**
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
*/
private class AccessPathFront extends TAccessPathFront {
string toString() {
- exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
+ exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
or
exists(Content f | this = TFrontHead(f) | result = f.toString())
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TFrontNil(result)
or
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
*/
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
flowCandFwd0(node, fromArg, apf, config) and
- if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
+ if node instanceof CastingNode
+ then compatibleTypes(getErasedNodeType(node), apf.getType())
+ else any()
}
/**
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
- private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
+ private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1067,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
+ exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
flowCandFwd(mid, fromArg, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
apf = TFrontNil(t)
@@ -1220,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
}
private newtype TAccessPath =
- TNil(DataFlowType t) or
- TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
+ TNil(DataFlowErasedType t) or
+ TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
/**
@@ -1248,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
this = TConsCons(_, _, result)
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TNil(result)
or
result = this.getHead().getContainerType()
@@ -1264,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
private class AccessPathNil extends AccessPath, TNil {
override string toString() {
- exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
+ exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
}
override predicate pop(Content head, AccessPath tail) { none() }
@@ -1278,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
private class AccessPathConsNil extends AccessPathCons, TConsNil {
override string toString() {
- exists(Content f, DataFlowType t | this = TConsNil(f, t) |
+ exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
// The `concat` becomes "" if `ppReprType` has no result.
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
)
@@ -1289,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
}
override predicate pop(Content head, AccessPath tail) {
- exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
+ exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
}
}
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
- private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
+ private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -1409,7 +1411,7 @@ private predicate flowFwd0(
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathNil nil, DataFlowType t |
+ exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
flowFwd(mid, fromArg, _, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
ap = TNil(t) and
@@ -2018,7 +2020,7 @@ private module FlowExploration {
}
private newtype TPartialAccessPath =
- TPartialNil(DataFlowType t) or
+ TPartialNil(DataFlowErasedType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
@@ -2039,7 +2041,7 @@ private module FlowExploration {
this = TPartialCons(_, result)
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
@@ -2050,11 +2052,11 @@ private module FlowExploration {
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
- exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
+ exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
@@ -2076,7 +2078,7 @@ private module FlowExploration {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2091,7 +2093,9 @@ private module FlowExploration {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
not fullBarrier(node, config) and
- if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
+ if node instanceof CastingNode
+ then compatibleTypes(getErasedNodeType(node), ap.getType())
+ else any()
)
}
@@ -2194,7 +2198,7 @@ private module FlowExploration {
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof PartialAccessPathNil and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
)
or
@@ -2206,7 +2210,7 @@ private module FlowExploration {
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof PartialAccessPathNil and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and
diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll
index 7ecb474f632..6f74f6f024a 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll
@@ -460,11 +460,11 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
*/
pragma[nomagic]
private predicate simpleParameterFlow(
- ParameterNode p, Node node, DataFlowType t, Configuration config
+ ParameterNode p, Node node, DataFlowErasedType t, Configuration config
) {
throughFlowNodeCand(node, config) and
p = node and
- t = getErasedRepr(node.getType()) and
+ t = getErasedNodeType(node) and
exists(ReturnNode ret, ReturnKind kind |
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
kind = ret.getKind() and
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localFlowStep(mid, node, config) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, _, config) and
additionalLocalFlowStep(mid, node, config) and
- t = getErasedRepr(node.getType())
+ t = getErasedNodeType(node)
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localStoreReadStep(mid, node) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
// value flow through a callable
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
exists(Node arg |
simpleParameterFlow(p, arg, t, config) and
argumentValueFlowsThrough(arg, node, _) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
// flow through a callable
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
pragma[noinline]
private predicate simpleArgumentFlowsThrough0(
- DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
+ DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
) {
nodeCand1(arg, unbind(config)) and
not outBarrier(arg, config) and
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
* additional step from the configuration.
*/
private predicate simpleArgumentFlowsThrough(
- ArgumentNode arg, Node out, DataFlowType t, Configuration config
+ ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
nodeCand1(out, unbind(config)) and
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
}
private newtype TAccessPathFront =
- TFrontNil(DataFlowType t) or
+ TFrontNil(DataFlowErasedType t) or
TFrontHead(Content f)
/**
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
*/
private class AccessPathFront extends TAccessPathFront {
string toString() {
- exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
+ exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
or
exists(Content f | this = TFrontHead(f) | result = f.toString())
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TFrontNil(result)
or
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
*/
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
flowCandFwd0(node, fromArg, apf, config) and
- if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
+ if node instanceof CastingNode
+ then compatibleTypes(getErasedNodeType(node), apf.getType())
+ else any()
}
/**
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
- private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
+ private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1067,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
+ exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
flowCandFwd(mid, fromArg, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
apf = TFrontNil(t)
@@ -1220,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
}
private newtype TAccessPath =
- TNil(DataFlowType t) or
- TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
+ TNil(DataFlowErasedType t) or
+ TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
/**
@@ -1248,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
this = TConsCons(_, _, result)
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TNil(result)
or
result = this.getHead().getContainerType()
@@ -1264,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
private class AccessPathNil extends AccessPath, TNil {
override string toString() {
- exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
+ exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
}
override predicate pop(Content head, AccessPath tail) { none() }
@@ -1278,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
private class AccessPathConsNil extends AccessPathCons, TConsNil {
override string toString() {
- exists(Content f, DataFlowType t | this = TConsNil(f, t) |
+ exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
// The `concat` becomes "" if `ppReprType` has no result.
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
)
@@ -1289,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
}
override predicate pop(Content head, AccessPath tail) {
- exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
+ exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
}
}
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
- private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
+ private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -1409,7 +1411,7 @@ private predicate flowFwd0(
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathNil nil, DataFlowType t |
+ exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
flowFwd(mid, fromArg, _, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
ap = TNil(t) and
@@ -2018,7 +2020,7 @@ private module FlowExploration {
}
private newtype TPartialAccessPath =
- TPartialNil(DataFlowType t) or
+ TPartialNil(DataFlowErasedType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
@@ -2039,7 +2041,7 @@ private module FlowExploration {
this = TPartialCons(_, result)
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
@@ -2050,11 +2052,11 @@ private module FlowExploration {
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
- exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
+ exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
@@ -2076,7 +2078,7 @@ private module FlowExploration {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2091,7 +2093,9 @@ private module FlowExploration {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
not fullBarrier(node, config) and
- if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
+ if node instanceof CastingNode
+ then compatibleTypes(getErasedNodeType(node), ap.getType())
+ else any()
)
}
@@ -2194,7 +2198,7 @@ private module FlowExploration {
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof PartialAccessPathNil and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
)
or
@@ -2206,7 +2210,7 @@ private module FlowExploration {
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof PartialAccessPathNil and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and
diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll
index 7ecb474f632..6f74f6f024a 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll
@@ -460,11 +460,11 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
*/
pragma[nomagic]
private predicate simpleParameterFlow(
- ParameterNode p, Node node, DataFlowType t, Configuration config
+ ParameterNode p, Node node, DataFlowErasedType t, Configuration config
) {
throughFlowNodeCand(node, config) and
p = node and
- t = getErasedRepr(node.getType()) and
+ t = getErasedNodeType(node) and
exists(ReturnNode ret, ReturnKind kind |
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
kind = ret.getKind() and
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localFlowStep(mid, node, config) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, _, config) and
additionalLocalFlowStep(mid, node, config) and
- t = getErasedRepr(node.getType())
+ t = getErasedNodeType(node)
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localStoreReadStep(mid, node) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
// value flow through a callable
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
exists(Node arg |
simpleParameterFlow(p, arg, t, config) and
argumentValueFlowsThrough(arg, node, _) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
// flow through a callable
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
pragma[noinline]
private predicate simpleArgumentFlowsThrough0(
- DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
+ DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
) {
nodeCand1(arg, unbind(config)) and
not outBarrier(arg, config) and
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
* additional step from the configuration.
*/
private predicate simpleArgumentFlowsThrough(
- ArgumentNode arg, Node out, DataFlowType t, Configuration config
+ ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
nodeCand1(out, unbind(config)) and
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
}
private newtype TAccessPathFront =
- TFrontNil(DataFlowType t) or
+ TFrontNil(DataFlowErasedType t) or
TFrontHead(Content f)
/**
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
*/
private class AccessPathFront extends TAccessPathFront {
string toString() {
- exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
+ exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
or
exists(Content f | this = TFrontHead(f) | result = f.toString())
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TFrontNil(result)
or
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
*/
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
flowCandFwd0(node, fromArg, apf, config) and
- if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
+ if node instanceof CastingNode
+ then compatibleTypes(getErasedNodeType(node), apf.getType())
+ else any()
}
/**
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
- private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
+ private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1067,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
+ exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
flowCandFwd(mid, fromArg, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
apf = TFrontNil(t)
@@ -1220,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
}
private newtype TAccessPath =
- TNil(DataFlowType t) or
- TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
+ TNil(DataFlowErasedType t) or
+ TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
/**
@@ -1248,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
this = TConsCons(_, _, result)
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TNil(result)
or
result = this.getHead().getContainerType()
@@ -1264,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
private class AccessPathNil extends AccessPath, TNil {
override string toString() {
- exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
+ exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
}
override predicate pop(Content head, AccessPath tail) { none() }
@@ -1278,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
private class AccessPathConsNil extends AccessPathCons, TConsNil {
override string toString() {
- exists(Content f, DataFlowType t | this = TConsNil(f, t) |
+ exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
// The `concat` becomes "" if `ppReprType` has no result.
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
)
@@ -1289,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
}
override predicate pop(Content head, AccessPath tail) {
- exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
+ exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
}
}
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
- private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
+ private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -1409,7 +1411,7 @@ private predicate flowFwd0(
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathNil nil, DataFlowType t |
+ exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
flowFwd(mid, fromArg, _, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
ap = TNil(t) and
@@ -2018,7 +2020,7 @@ private module FlowExploration {
}
private newtype TPartialAccessPath =
- TPartialNil(DataFlowType t) or
+ TPartialNil(DataFlowErasedType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
@@ -2039,7 +2041,7 @@ private module FlowExploration {
this = TPartialCons(_, result)
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
@@ -2050,11 +2052,11 @@ private module FlowExploration {
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
- exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
+ exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
@@ -2076,7 +2078,7 @@ private module FlowExploration {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2091,7 +2093,9 @@ private module FlowExploration {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
not fullBarrier(node, config) and
- if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
+ if node instanceof CastingNode
+ then compatibleTypes(getErasedNodeType(node), ap.getType())
+ else any()
)
}
@@ -2194,7 +2198,7 @@ private module FlowExploration {
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof PartialAccessPathNil and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
)
or
@@ -2206,7 +2210,7 @@ private module FlowExploration {
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof PartialAccessPathNil and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and
diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll
index 8b9c8f5abd3..f0b5cb2b347 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll
@@ -57,14 +57,14 @@ private module ImplCommon {
exists(Node mid |
parameterValueFlowCand(p, mid) and
step(mid, node) and
- compatibleTypes(p.getType(), node.getType())
+ compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
)
or
// flow through a callable
exists(Node arg |
parameterValueFlowCand(p, arg) and
argumentValueFlowsThroughCand(arg, node) and
- compatibleTypes(p.getType(), node.getType())
+ compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
)
}
@@ -95,7 +95,7 @@ private module ImplCommon {
argumentValueFlowsThroughCand0(call, arg, kind)
|
out = getAnOutNode(call, kind) and
- compatibleTypes(arg.getType(), out.getType())
+ compatibleTypes(getErasedNodeType(arg), getErasedNodeType(out))
)
}
@@ -183,7 +183,7 @@ private module ImplCommon {
exists(Node mid |
parameterValueFlow(p, mid, cc) and
step(mid, node) and
- compatibleTypes(p.getType(), node.getType()) and
+ compatibleTypes(getErasedNodeType(p), getErasedNodeType(node)) and
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall())
)
or
@@ -191,7 +191,7 @@ private module ImplCommon {
exists(Node arg |
parameterValueFlow(p, arg, cc) and
argumentValueFlowsThrough(arg, node, cc) and
- compatibleTypes(p.getType(), node.getType()) and
+ compatibleTypes(getErasedNodeType(p), getErasedNodeType(node)) and
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall())
)
}
@@ -226,7 +226,7 @@ private module ImplCommon {
|
out = getAnOutNode(call, kind) and
not isUnreachableInCall(out, cc.(CallContextSpecificCall).getCall()) and
- compatibleTypes(arg.getType(), out.getType())
+ compatibleTypes(getErasedNodeType(arg), getErasedNodeType(out))
)
}
}
@@ -260,7 +260,7 @@ private module ImplCommon {
exists(Node mid |
parameterValueFlowNoCtx(p, mid) and
localValueStep(mid, node) and
- compatibleTypes(p.getType(), node.getType())
+ compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
)
}
@@ -296,8 +296,8 @@ private module ImplCommon {
setterCall(call, i1, i2, f) and
node1.(ArgumentNode).argumentOf(call, i1) and
node2.getPreUpdateNode().(ArgumentNode).argumentOf(call, i2) and
- compatibleTypes(node1.getTypeBound(), f.getType()) and
- compatibleTypes(node2.getTypeBound(), f.getContainerType())
+ compatibleTypes(getErasedNodeTypeBound(node1), f.getType()) and
+ compatibleTypes(getErasedNodeTypeBound(node2), f.getContainerType())
)
}
@@ -333,8 +333,8 @@ private module ImplCommon {
exists(DataFlowCall call, ReturnKind kind |
storeReturn0(call, kind, node1, f) and
node2 = getAnOutNode(call, kind) and
- compatibleTypes(node1.getTypeBound(), f.getType()) and
- compatibleTypes(node2.getTypeBound(), f.getContainerType())
+ compatibleTypes(getErasedNodeTypeBound(node1), f.getType()) and
+ compatibleTypes(getErasedNodeTypeBound(node2), f.getContainerType())
)
}
@@ -365,8 +365,8 @@ private module ImplCommon {
exists(DataFlowCall call, ReturnKind kind |
read0(call, kind, node1, f) and
node2 = getAnOutNode(call, kind) and
- compatibleTypes(node1.getTypeBound(), f.getContainerType()) and
- compatibleTypes(node2.getTypeBound(), f.getType())
+ compatibleTypes(getErasedNodeTypeBound(node1), f.getContainerType()) and
+ compatibleTypes(getErasedNodeTypeBound(node2), f.getType())
)
}
@@ -384,7 +384,7 @@ private module ImplCommon {
store(node1, f, mid1) and
localValueStep*(mid1, mid2) and
read(mid2, f, node2) and
- compatibleTypes(node1.getTypeBound(), node2.getTypeBound())
+ compatibleTypes(getErasedNodeTypeBound(node1), getErasedNodeTypeBound(node2))
)
}
@@ -405,14 +405,14 @@ private module ImplCommon {
exists(Node mid |
parameterValueFlowCand(p, mid) and
step(mid, node) and
- compatibleTypes(p.getType(), node.getType())
+ compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
)
or
// flow through a callable
exists(Node arg |
parameterValueFlowCand(p, arg) and
argumentValueFlowsThroughCand(arg, node) and
- compatibleTypes(p.getType(), node.getType())
+ compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
)
}
@@ -443,7 +443,7 @@ private module ImplCommon {
argumentValueFlowsThroughCand0(call, arg, kind)
|
out = getAnOutNode(call, kind) and
- compatibleTypes(arg.getType(), out.getType())
+ compatibleTypes(getErasedNodeType(arg), getErasedNodeType(out))
)
}
@@ -531,7 +531,7 @@ private module ImplCommon {
exists(Node mid |
parameterValueFlow(p, mid, cc) and
step(mid, node) and
- compatibleTypes(p.getType(), node.getType()) and
+ compatibleTypes(getErasedNodeType(p), getErasedNodeType(node)) and
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall())
)
or
@@ -539,7 +539,7 @@ private module ImplCommon {
exists(Node arg |
parameterValueFlow(p, arg, cc) and
argumentValueFlowsThrough(arg, node, cc) and
- compatibleTypes(p.getType(), node.getType()) and
+ compatibleTypes(getErasedNodeType(p), getErasedNodeType(node)) and
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall())
)
}
@@ -574,7 +574,7 @@ private module ImplCommon {
|
out = getAnOutNode(call, kind) and
not isUnreachableInCall(out, cc.(CallContextSpecificCall).getCall()) and
- compatibleTypes(arg.getType(), out.getType())
+ compatibleTypes(getErasedNodeType(arg), getErasedNodeType(out))
)
}
}
@@ -860,4 +860,10 @@ private module ImplCommon {
or
result = viableCallable(call) and cc instanceof CallContextReturn
}
+
+ pragma[noinline]
+ DataFlowErasedType getErasedNodeType(Node n) { result = getErasedRepr(n.getType()) }
+
+ pragma[noinline]
+ DataFlowErasedType getErasedNodeTypeBound(Node n) { result = getErasedRepr(n.getTypeBound()) }
}
diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll
index 7ecb474f632..6f74f6f024a 100644
--- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll
+++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll
@@ -460,11 +460,11 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
*/
pragma[nomagic]
private predicate simpleParameterFlow(
- ParameterNode p, Node node, DataFlowType t, Configuration config
+ ParameterNode p, Node node, DataFlowErasedType t, Configuration config
) {
throughFlowNodeCand(node, config) and
p = node and
- t = getErasedRepr(node.getType()) and
+ t = getErasedNodeType(node) and
exists(ReturnNode ret, ReturnKind kind |
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
kind = ret.getKind() and
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localFlowStep(mid, node, config) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, _, config) and
additionalLocalFlowStep(mid, node, config) and
- t = getErasedRepr(node.getType())
+ t = getErasedNodeType(node)
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localStoreReadStep(mid, node) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
// value flow through a callable
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
exists(Node arg |
simpleParameterFlow(p, arg, t, config) and
argumentValueFlowsThrough(arg, node, _) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
// flow through a callable
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
pragma[noinline]
private predicate simpleArgumentFlowsThrough0(
- DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
+ DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
) {
nodeCand1(arg, unbind(config)) and
not outBarrier(arg, config) and
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
* additional step from the configuration.
*/
private predicate simpleArgumentFlowsThrough(
- ArgumentNode arg, Node out, DataFlowType t, Configuration config
+ ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
nodeCand1(out, unbind(config)) and
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
}
private newtype TAccessPathFront =
- TFrontNil(DataFlowType t) or
+ TFrontNil(DataFlowErasedType t) or
TFrontHead(Content f)
/**
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
*/
private class AccessPathFront extends TAccessPathFront {
string toString() {
- exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
+ exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
or
exists(Content f | this = TFrontHead(f) | result = f.toString())
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TFrontNil(result)
or
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
*/
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
flowCandFwd0(node, fromArg, apf, config) and
- if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
+ if node instanceof CastingNode
+ then compatibleTypes(getErasedNodeType(node), apf.getType())
+ else any()
}
/**
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
- private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
+ private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1067,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
+ exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
flowCandFwd(mid, fromArg, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
apf = TFrontNil(t)
@@ -1220,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
}
private newtype TAccessPath =
- TNil(DataFlowType t) or
- TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
+ TNil(DataFlowErasedType t) or
+ TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
/**
@@ -1248,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
this = TConsCons(_, _, result)
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TNil(result)
or
result = this.getHead().getContainerType()
@@ -1264,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
private class AccessPathNil extends AccessPath, TNil {
override string toString() {
- exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
+ exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
}
override predicate pop(Content head, AccessPath tail) { none() }
@@ -1278,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
private class AccessPathConsNil extends AccessPathCons, TConsNil {
override string toString() {
- exists(Content f, DataFlowType t | this = TConsNil(f, t) |
+ exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
// The `concat` becomes "" if `ppReprType` has no result.
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
)
@@ -1289,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
}
override predicate pop(Content head, AccessPath tail) {
- exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
+ exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
}
}
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
- private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
+ private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -1409,7 +1411,7 @@ private predicate flowFwd0(
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathNil nil, DataFlowType t |
+ exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
flowFwd(mid, fromArg, _, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
ap = TNil(t) and
@@ -2018,7 +2020,7 @@ private module FlowExploration {
}
private newtype TPartialAccessPath =
- TPartialNil(DataFlowType t) or
+ TPartialNil(DataFlowErasedType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
@@ -2039,7 +2041,7 @@ private module FlowExploration {
this = TPartialCons(_, result)
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
@@ -2050,11 +2052,11 @@ private module FlowExploration {
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
- exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
+ exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
@@ -2076,7 +2078,7 @@ private module FlowExploration {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2091,7 +2093,9 @@ private module FlowExploration {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
not fullBarrier(node, config) and
- if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
+ if node instanceof CastingNode
+ then compatibleTypes(getErasedNodeType(node), ap.getType())
+ else any()
)
}
@@ -2194,7 +2198,7 @@ private module FlowExploration {
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof PartialAccessPathNil and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
)
or
@@ -2206,7 +2210,7 @@ private module FlowExploration {
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof PartialAccessPathNil and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and
diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll
index 7ecb474f632..6f74f6f024a 100644
--- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll
+++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll
@@ -460,11 +460,11 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
*/
pragma[nomagic]
private predicate simpleParameterFlow(
- ParameterNode p, Node node, DataFlowType t, Configuration config
+ ParameterNode p, Node node, DataFlowErasedType t, Configuration config
) {
throughFlowNodeCand(node, config) and
p = node and
- t = getErasedRepr(node.getType()) and
+ t = getErasedNodeType(node) and
exists(ReturnNode ret, ReturnKind kind |
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
kind = ret.getKind() and
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localFlowStep(mid, node, config) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, _, config) and
additionalLocalFlowStep(mid, node, config) and
- t = getErasedRepr(node.getType())
+ t = getErasedNodeType(node)
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localStoreReadStep(mid, node) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
// value flow through a callable
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
exists(Node arg |
simpleParameterFlow(p, arg, t, config) and
argumentValueFlowsThrough(arg, node, _) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
// flow through a callable
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
pragma[noinline]
private predicate simpleArgumentFlowsThrough0(
- DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
+ DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
) {
nodeCand1(arg, unbind(config)) and
not outBarrier(arg, config) and
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
* additional step from the configuration.
*/
private predicate simpleArgumentFlowsThrough(
- ArgumentNode arg, Node out, DataFlowType t, Configuration config
+ ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
nodeCand1(out, unbind(config)) and
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
}
private newtype TAccessPathFront =
- TFrontNil(DataFlowType t) or
+ TFrontNil(DataFlowErasedType t) or
TFrontHead(Content f)
/**
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
*/
private class AccessPathFront extends TAccessPathFront {
string toString() {
- exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
+ exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
or
exists(Content f | this = TFrontHead(f) | result = f.toString())
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TFrontNil(result)
or
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
*/
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
flowCandFwd0(node, fromArg, apf, config) and
- if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
+ if node instanceof CastingNode
+ then compatibleTypes(getErasedNodeType(node), apf.getType())
+ else any()
}
/**
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
- private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
+ private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1067,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
+ exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
flowCandFwd(mid, fromArg, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
apf = TFrontNil(t)
@@ -1220,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
}
private newtype TAccessPath =
- TNil(DataFlowType t) or
- TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
+ TNil(DataFlowErasedType t) or
+ TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
/**
@@ -1248,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
this = TConsCons(_, _, result)
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TNil(result)
or
result = this.getHead().getContainerType()
@@ -1264,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
private class AccessPathNil extends AccessPath, TNil {
override string toString() {
- exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
+ exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
}
override predicate pop(Content head, AccessPath tail) { none() }
@@ -1278,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
private class AccessPathConsNil extends AccessPathCons, TConsNil {
override string toString() {
- exists(Content f, DataFlowType t | this = TConsNil(f, t) |
+ exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
// The `concat` becomes "" if `ppReprType` has no result.
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
)
@@ -1289,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
}
override predicate pop(Content head, AccessPath tail) {
- exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
+ exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
}
}
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
- private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
+ private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -1409,7 +1411,7 @@ private predicate flowFwd0(
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathNil nil, DataFlowType t |
+ exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
flowFwd(mid, fromArg, _, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
ap = TNil(t) and
@@ -2018,7 +2020,7 @@ private module FlowExploration {
}
private newtype TPartialAccessPath =
- TPartialNil(DataFlowType t) or
+ TPartialNil(DataFlowErasedType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
@@ -2039,7 +2041,7 @@ private module FlowExploration {
this = TPartialCons(_, result)
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
@@ -2050,11 +2052,11 @@ private module FlowExploration {
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
- exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
+ exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
@@ -2076,7 +2078,7 @@ private module FlowExploration {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2091,7 +2093,9 @@ private module FlowExploration {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
not fullBarrier(node, config) and
- if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
+ if node instanceof CastingNode
+ then compatibleTypes(getErasedNodeType(node), ap.getType())
+ else any()
)
}
@@ -2194,7 +2198,7 @@ private module FlowExploration {
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof PartialAccessPathNil and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
)
or
@@ -2206,7 +2210,7 @@ private module FlowExploration {
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof PartialAccessPathNil and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and
diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll
index 7ecb474f632..6f74f6f024a 100644
--- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll
+++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll
@@ -460,11 +460,11 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
*/
pragma[nomagic]
private predicate simpleParameterFlow(
- ParameterNode p, Node node, DataFlowType t, Configuration config
+ ParameterNode p, Node node, DataFlowErasedType t, Configuration config
) {
throughFlowNodeCand(node, config) and
p = node and
- t = getErasedRepr(node.getType()) and
+ t = getErasedNodeType(node) and
exists(ReturnNode ret, ReturnKind kind |
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
kind = ret.getKind() and
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localFlowStep(mid, node, config) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, _, config) and
additionalLocalFlowStep(mid, node, config) and
- t = getErasedRepr(node.getType())
+ t = getErasedNodeType(node)
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localStoreReadStep(mid, node) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
// value flow through a callable
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
exists(Node arg |
simpleParameterFlow(p, arg, t, config) and
argumentValueFlowsThrough(arg, node, _) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
// flow through a callable
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
pragma[noinline]
private predicate simpleArgumentFlowsThrough0(
- DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
+ DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
) {
nodeCand1(arg, unbind(config)) and
not outBarrier(arg, config) and
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
* additional step from the configuration.
*/
private predicate simpleArgumentFlowsThrough(
- ArgumentNode arg, Node out, DataFlowType t, Configuration config
+ ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
nodeCand1(out, unbind(config)) and
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
}
private newtype TAccessPathFront =
- TFrontNil(DataFlowType t) or
+ TFrontNil(DataFlowErasedType t) or
TFrontHead(Content f)
/**
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
*/
private class AccessPathFront extends TAccessPathFront {
string toString() {
- exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
+ exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
or
exists(Content f | this = TFrontHead(f) | result = f.toString())
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TFrontNil(result)
or
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
*/
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
flowCandFwd0(node, fromArg, apf, config) and
- if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
+ if node instanceof CastingNode
+ then compatibleTypes(getErasedNodeType(node), apf.getType())
+ else any()
}
/**
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
- private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
+ private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1067,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
+ exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
flowCandFwd(mid, fromArg, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
apf = TFrontNil(t)
@@ -1220,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
}
private newtype TAccessPath =
- TNil(DataFlowType t) or
- TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
+ TNil(DataFlowErasedType t) or
+ TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
/**
@@ -1248,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
this = TConsCons(_, _, result)
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TNil(result)
or
result = this.getHead().getContainerType()
@@ -1264,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
private class AccessPathNil extends AccessPath, TNil {
override string toString() {
- exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
+ exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
}
override predicate pop(Content head, AccessPath tail) { none() }
@@ -1278,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
private class AccessPathConsNil extends AccessPathCons, TConsNil {
override string toString() {
- exists(Content f, DataFlowType t | this = TConsNil(f, t) |
+ exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
// The `concat` becomes "" if `ppReprType` has no result.
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
)
@@ -1289,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
}
override predicate pop(Content head, AccessPath tail) {
- exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
+ exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
}
}
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
- private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
+ private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -1409,7 +1411,7 @@ private predicate flowFwd0(
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathNil nil, DataFlowType t |
+ exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
flowFwd(mid, fromArg, _, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
ap = TNil(t) and
@@ -2018,7 +2020,7 @@ private module FlowExploration {
}
private newtype TPartialAccessPath =
- TPartialNil(DataFlowType t) or
+ TPartialNil(DataFlowErasedType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
@@ -2039,7 +2041,7 @@ private module FlowExploration {
this = TPartialCons(_, result)
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
@@ -2050,11 +2052,11 @@ private module FlowExploration {
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
- exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
+ exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
@@ -2076,7 +2078,7 @@ private module FlowExploration {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2091,7 +2093,9 @@ private module FlowExploration {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
not fullBarrier(node, config) and
- if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
+ if node instanceof CastingNode
+ then compatibleTypes(getErasedNodeType(node), ap.getType())
+ else any()
)
}
@@ -2194,7 +2198,7 @@ private module FlowExploration {
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof PartialAccessPathNil and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
)
or
@@ -2206,7 +2210,7 @@ private module FlowExploration {
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof PartialAccessPathNil and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and
diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll
index 7ecb474f632..6f74f6f024a 100644
--- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll
+++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll
@@ -460,11 +460,11 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
*/
pragma[nomagic]
private predicate simpleParameterFlow(
- ParameterNode p, Node node, DataFlowType t, Configuration config
+ ParameterNode p, Node node, DataFlowErasedType t, Configuration config
) {
throughFlowNodeCand(node, config) and
p = node and
- t = getErasedRepr(node.getType()) and
+ t = getErasedNodeType(node) and
exists(ReturnNode ret, ReturnKind kind |
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
kind = ret.getKind() and
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localFlowStep(mid, node, config) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, _, config) and
additionalLocalFlowStep(mid, node, config) and
- t = getErasedRepr(node.getType())
+ t = getErasedNodeType(node)
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localStoreReadStep(mid, node) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
// value flow through a callable
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
exists(Node arg |
simpleParameterFlow(p, arg, t, config) and
argumentValueFlowsThrough(arg, node, _) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
// flow through a callable
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
pragma[noinline]
private predicate simpleArgumentFlowsThrough0(
- DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
+ DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
) {
nodeCand1(arg, unbind(config)) and
not outBarrier(arg, config) and
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
* additional step from the configuration.
*/
private predicate simpleArgumentFlowsThrough(
- ArgumentNode arg, Node out, DataFlowType t, Configuration config
+ ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
nodeCand1(out, unbind(config)) and
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
}
private newtype TAccessPathFront =
- TFrontNil(DataFlowType t) or
+ TFrontNil(DataFlowErasedType t) or
TFrontHead(Content f)
/**
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
*/
private class AccessPathFront extends TAccessPathFront {
string toString() {
- exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
+ exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
or
exists(Content f | this = TFrontHead(f) | result = f.toString())
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TFrontNil(result)
or
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
*/
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
flowCandFwd0(node, fromArg, apf, config) and
- if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
+ if node instanceof CastingNode
+ then compatibleTypes(getErasedNodeType(node), apf.getType())
+ else any()
}
/**
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
- private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
+ private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1067,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
+ exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
flowCandFwd(mid, fromArg, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
apf = TFrontNil(t)
@@ -1220,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
}
private newtype TAccessPath =
- TNil(DataFlowType t) or
- TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
+ TNil(DataFlowErasedType t) or
+ TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
/**
@@ -1248,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
this = TConsCons(_, _, result)
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TNil(result)
or
result = this.getHead().getContainerType()
@@ -1264,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
private class AccessPathNil extends AccessPath, TNil {
override string toString() {
- exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
+ exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
}
override predicate pop(Content head, AccessPath tail) { none() }
@@ -1278,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
private class AccessPathConsNil extends AccessPathCons, TConsNil {
override string toString() {
- exists(Content f, DataFlowType t | this = TConsNil(f, t) |
+ exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
// The `concat` becomes "" if `ppReprType` has no result.
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
)
@@ -1289,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
}
override predicate pop(Content head, AccessPath tail) {
- exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
+ exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
}
}
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
- private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
+ private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -1409,7 +1411,7 @@ private predicate flowFwd0(
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathNil nil, DataFlowType t |
+ exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
flowFwd(mid, fromArg, _, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
ap = TNil(t) and
@@ -2018,7 +2020,7 @@ private module FlowExploration {
}
private newtype TPartialAccessPath =
- TPartialNil(DataFlowType t) or
+ TPartialNil(DataFlowErasedType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
@@ -2039,7 +2041,7 @@ private module FlowExploration {
this = TPartialCons(_, result)
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
@@ -2050,11 +2052,11 @@ private module FlowExploration {
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
- exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
+ exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
@@ -2076,7 +2078,7 @@ private module FlowExploration {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2091,7 +2093,9 @@ private module FlowExploration {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
not fullBarrier(node, config) and
- if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
+ if node instanceof CastingNode
+ then compatibleTypes(getErasedNodeType(node), ap.getType())
+ else any()
)
}
@@ -2194,7 +2198,7 @@ private module FlowExploration {
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof PartialAccessPathNil and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
)
or
@@ -2206,7 +2210,7 @@ private module FlowExploration {
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof PartialAccessPathNil and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and
diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll
index 7ecb474f632..6f74f6f024a 100644
--- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll
+++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll
@@ -460,11 +460,11 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
*/
pragma[nomagic]
private predicate simpleParameterFlow(
- ParameterNode p, Node node, DataFlowType t, Configuration config
+ ParameterNode p, Node node, DataFlowErasedType t, Configuration config
) {
throughFlowNodeCand(node, config) and
p = node and
- t = getErasedRepr(node.getType()) and
+ t = getErasedNodeType(node) and
exists(ReturnNode ret, ReturnKind kind |
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
kind = ret.getKind() and
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localFlowStep(mid, node, config) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, _, config) and
additionalLocalFlowStep(mid, node, config) and
- t = getErasedRepr(node.getType())
+ t = getErasedNodeType(node)
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localStoreReadStep(mid, node) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
// value flow through a callable
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
exists(Node arg |
simpleParameterFlow(p, arg, t, config) and
argumentValueFlowsThrough(arg, node, _) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
// flow through a callable
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
pragma[noinline]
private predicate simpleArgumentFlowsThrough0(
- DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
+ DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
) {
nodeCand1(arg, unbind(config)) and
not outBarrier(arg, config) and
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
* additional step from the configuration.
*/
private predicate simpleArgumentFlowsThrough(
- ArgumentNode arg, Node out, DataFlowType t, Configuration config
+ ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
nodeCand1(out, unbind(config)) and
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
}
private newtype TAccessPathFront =
- TFrontNil(DataFlowType t) or
+ TFrontNil(DataFlowErasedType t) or
TFrontHead(Content f)
/**
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
*/
private class AccessPathFront extends TAccessPathFront {
string toString() {
- exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
+ exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
or
exists(Content f | this = TFrontHead(f) | result = f.toString())
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TFrontNil(result)
or
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
*/
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
flowCandFwd0(node, fromArg, apf, config) and
- if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
+ if node instanceof CastingNode
+ then compatibleTypes(getErasedNodeType(node), apf.getType())
+ else any()
}
/**
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
- private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
+ private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1067,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
+ exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
flowCandFwd(mid, fromArg, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
apf = TFrontNil(t)
@@ -1220,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
}
private newtype TAccessPath =
- TNil(DataFlowType t) or
- TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
+ TNil(DataFlowErasedType t) or
+ TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
/**
@@ -1248,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
this = TConsCons(_, _, result)
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TNil(result)
or
result = this.getHead().getContainerType()
@@ -1264,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
private class AccessPathNil extends AccessPath, TNil {
override string toString() {
- exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
+ exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
}
override predicate pop(Content head, AccessPath tail) { none() }
@@ -1278,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
private class AccessPathConsNil extends AccessPathCons, TConsNil {
override string toString() {
- exists(Content f, DataFlowType t | this = TConsNil(f, t) |
+ exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
// The `concat` becomes "" if `ppReprType` has no result.
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
)
@@ -1289,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
}
override predicate pop(Content head, AccessPath tail) {
- exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
+ exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
}
}
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
- private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
+ private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -1409,7 +1411,7 @@ private predicate flowFwd0(
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathNil nil, DataFlowType t |
+ exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
flowFwd(mid, fromArg, _, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
ap = TNil(t) and
@@ -2018,7 +2020,7 @@ private module FlowExploration {
}
private newtype TPartialAccessPath =
- TPartialNil(DataFlowType t) or
+ TPartialNil(DataFlowErasedType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
@@ -2039,7 +2041,7 @@ private module FlowExploration {
this = TPartialCons(_, result)
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
@@ -2050,11 +2052,11 @@ private module FlowExploration {
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
- exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
+ exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
@@ -2076,7 +2078,7 @@ private module FlowExploration {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2091,7 +2093,9 @@ private module FlowExploration {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
not fullBarrier(node, config) and
- if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
+ if node instanceof CastingNode
+ then compatibleTypes(getErasedNodeType(node), ap.getType())
+ else any()
)
}
@@ -2194,7 +2198,7 @@ private module FlowExploration {
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof PartialAccessPathNil and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
)
or
@@ -2206,7 +2210,7 @@ private module FlowExploration {
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof PartialAccessPathNil and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and
diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll
index 7ecb474f632..6f74f6f024a 100644
--- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll
+++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll
@@ -460,11 +460,11 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
*/
pragma[nomagic]
private predicate simpleParameterFlow(
- ParameterNode p, Node node, DataFlowType t, Configuration config
+ ParameterNode p, Node node, DataFlowErasedType t, Configuration config
) {
throughFlowNodeCand(node, config) and
p = node and
- t = getErasedRepr(node.getType()) and
+ t = getErasedNodeType(node) and
exists(ReturnNode ret, ReturnKind kind |
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
kind = ret.getKind() and
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localFlowStep(mid, node, config) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, _, config) and
additionalLocalFlowStep(mid, node, config) and
- t = getErasedRepr(node.getType())
+ t = getErasedNodeType(node)
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localStoreReadStep(mid, node) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
// value flow through a callable
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
exists(Node arg |
simpleParameterFlow(p, arg, t, config) and
argumentValueFlowsThrough(arg, node, _) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
// flow through a callable
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
pragma[noinline]
private predicate simpleArgumentFlowsThrough0(
- DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
+ DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
) {
nodeCand1(arg, unbind(config)) and
not outBarrier(arg, config) and
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
* additional step from the configuration.
*/
private predicate simpleArgumentFlowsThrough(
- ArgumentNode arg, Node out, DataFlowType t, Configuration config
+ ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
nodeCand1(out, unbind(config)) and
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
}
private newtype TAccessPathFront =
- TFrontNil(DataFlowType t) or
+ TFrontNil(DataFlowErasedType t) or
TFrontHead(Content f)
/**
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
*/
private class AccessPathFront extends TAccessPathFront {
string toString() {
- exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
+ exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
or
exists(Content f | this = TFrontHead(f) | result = f.toString())
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TFrontNil(result)
or
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
*/
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
flowCandFwd0(node, fromArg, apf, config) and
- if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
+ if node instanceof CastingNode
+ then compatibleTypes(getErasedNodeType(node), apf.getType())
+ else any()
}
/**
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
- private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
+ private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1067,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
+ exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
flowCandFwd(mid, fromArg, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
apf = TFrontNil(t)
@@ -1220,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
}
private newtype TAccessPath =
- TNil(DataFlowType t) or
- TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
+ TNil(DataFlowErasedType t) or
+ TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
/**
@@ -1248,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
this = TConsCons(_, _, result)
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TNil(result)
or
result = this.getHead().getContainerType()
@@ -1264,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
private class AccessPathNil extends AccessPath, TNil {
override string toString() {
- exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
+ exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
}
override predicate pop(Content head, AccessPath tail) { none() }
@@ -1278,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
private class AccessPathConsNil extends AccessPathCons, TConsNil {
override string toString() {
- exists(Content f, DataFlowType t | this = TConsNil(f, t) |
+ exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
// The `concat` becomes "" if `ppReprType` has no result.
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
)
@@ -1289,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
}
override predicate pop(Content head, AccessPath tail) {
- exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
+ exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
}
}
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
- private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
+ private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -1409,7 +1411,7 @@ private predicate flowFwd0(
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathNil nil, DataFlowType t |
+ exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
flowFwd(mid, fromArg, _, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
ap = TNil(t) and
@@ -2018,7 +2020,7 @@ private module FlowExploration {
}
private newtype TPartialAccessPath =
- TPartialNil(DataFlowType t) or
+ TPartialNil(DataFlowErasedType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
@@ -2039,7 +2041,7 @@ private module FlowExploration {
this = TPartialCons(_, result)
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
@@ -2050,11 +2052,11 @@ private module FlowExploration {
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
- exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
+ exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
@@ -2076,7 +2078,7 @@ private module FlowExploration {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2091,7 +2093,9 @@ private module FlowExploration {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
not fullBarrier(node, config) and
- if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
+ if node instanceof CastingNode
+ then compatibleTypes(getErasedNodeType(node), ap.getType())
+ else any()
)
}
@@ -2194,7 +2198,7 @@ private module FlowExploration {
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof PartialAccessPathNil and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
)
or
@@ -2206,7 +2210,7 @@ private module FlowExploration {
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof PartialAccessPathNil and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and
diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl3.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl3.qll
index 7ecb474f632..6f74f6f024a 100644
--- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl3.qll
+++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl3.qll
@@ -460,11 +460,11 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
*/
pragma[nomagic]
private predicate simpleParameterFlow(
- ParameterNode p, Node node, DataFlowType t, Configuration config
+ ParameterNode p, Node node, DataFlowErasedType t, Configuration config
) {
throughFlowNodeCand(node, config) and
p = node and
- t = getErasedRepr(node.getType()) and
+ t = getErasedNodeType(node) and
exists(ReturnNode ret, ReturnKind kind |
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
kind = ret.getKind() and
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localFlowStep(mid, node, config) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, _, config) and
additionalLocalFlowStep(mid, node, config) and
- t = getErasedRepr(node.getType())
+ t = getErasedNodeType(node)
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localStoreReadStep(mid, node) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
// value flow through a callable
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
exists(Node arg |
simpleParameterFlow(p, arg, t, config) and
argumentValueFlowsThrough(arg, node, _) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
// flow through a callable
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
pragma[noinline]
private predicate simpleArgumentFlowsThrough0(
- DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
+ DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
) {
nodeCand1(arg, unbind(config)) and
not outBarrier(arg, config) and
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
* additional step from the configuration.
*/
private predicate simpleArgumentFlowsThrough(
- ArgumentNode arg, Node out, DataFlowType t, Configuration config
+ ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
nodeCand1(out, unbind(config)) and
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
}
private newtype TAccessPathFront =
- TFrontNil(DataFlowType t) or
+ TFrontNil(DataFlowErasedType t) or
TFrontHead(Content f)
/**
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
*/
private class AccessPathFront extends TAccessPathFront {
string toString() {
- exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
+ exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
or
exists(Content f | this = TFrontHead(f) | result = f.toString())
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TFrontNil(result)
or
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
*/
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
flowCandFwd0(node, fromArg, apf, config) and
- if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
+ if node instanceof CastingNode
+ then compatibleTypes(getErasedNodeType(node), apf.getType())
+ else any()
}
/**
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
- private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
+ private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1067,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
+ exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
flowCandFwd(mid, fromArg, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
apf = TFrontNil(t)
@@ -1220,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
}
private newtype TAccessPath =
- TNil(DataFlowType t) or
- TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
+ TNil(DataFlowErasedType t) or
+ TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
/**
@@ -1248,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
this = TConsCons(_, _, result)
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TNil(result)
or
result = this.getHead().getContainerType()
@@ -1264,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
private class AccessPathNil extends AccessPath, TNil {
override string toString() {
- exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
+ exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
}
override predicate pop(Content head, AccessPath tail) { none() }
@@ -1278,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
private class AccessPathConsNil extends AccessPathCons, TConsNil {
override string toString() {
- exists(Content f, DataFlowType t | this = TConsNil(f, t) |
+ exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
// The `concat` becomes "" if `ppReprType` has no result.
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
)
@@ -1289,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
}
override predicate pop(Content head, AccessPath tail) {
- exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
+ exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
}
}
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
- private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
+ private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -1409,7 +1411,7 @@ private predicate flowFwd0(
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathNil nil, DataFlowType t |
+ exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
flowFwd(mid, fromArg, _, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
ap = TNil(t) and
@@ -2018,7 +2020,7 @@ private module FlowExploration {
}
private newtype TPartialAccessPath =
- TPartialNil(DataFlowType t) or
+ TPartialNil(DataFlowErasedType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
@@ -2039,7 +2041,7 @@ private module FlowExploration {
this = TPartialCons(_, result)
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
@@ -2050,11 +2052,11 @@ private module FlowExploration {
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
- exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
+ exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
@@ -2076,7 +2078,7 @@ private module FlowExploration {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2091,7 +2093,9 @@ private module FlowExploration {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
not fullBarrier(node, config) and
- if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
+ if node instanceof CastingNode
+ then compatibleTypes(getErasedNodeType(node), ap.getType())
+ else any()
)
}
@@ -2194,7 +2198,7 @@ private module FlowExploration {
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof PartialAccessPathNil and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
)
or
@@ -2206,7 +2210,7 @@ private module FlowExploration {
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof PartialAccessPathNil and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and
diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl4.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl4.qll
index 7ecb474f632..6f74f6f024a 100644
--- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl4.qll
+++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl4.qll
@@ -460,11 +460,11 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
*/
pragma[nomagic]
private predicate simpleParameterFlow(
- ParameterNode p, Node node, DataFlowType t, Configuration config
+ ParameterNode p, Node node, DataFlowErasedType t, Configuration config
) {
throughFlowNodeCand(node, config) and
p = node and
- t = getErasedRepr(node.getType()) and
+ t = getErasedNodeType(node) and
exists(ReturnNode ret, ReturnKind kind |
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
kind = ret.getKind() and
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localFlowStep(mid, node, config) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, _, config) and
additionalLocalFlowStep(mid, node, config) and
- t = getErasedRepr(node.getType())
+ t = getErasedNodeType(node)
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localStoreReadStep(mid, node) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
// value flow through a callable
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
exists(Node arg |
simpleParameterFlow(p, arg, t, config) and
argumentValueFlowsThrough(arg, node, _) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
// flow through a callable
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
pragma[noinline]
private predicate simpleArgumentFlowsThrough0(
- DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
+ DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
) {
nodeCand1(arg, unbind(config)) and
not outBarrier(arg, config) and
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
* additional step from the configuration.
*/
private predicate simpleArgumentFlowsThrough(
- ArgumentNode arg, Node out, DataFlowType t, Configuration config
+ ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
nodeCand1(out, unbind(config)) and
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
}
private newtype TAccessPathFront =
- TFrontNil(DataFlowType t) or
+ TFrontNil(DataFlowErasedType t) or
TFrontHead(Content f)
/**
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
*/
private class AccessPathFront extends TAccessPathFront {
string toString() {
- exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
+ exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
or
exists(Content f | this = TFrontHead(f) | result = f.toString())
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TFrontNil(result)
or
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
*/
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
flowCandFwd0(node, fromArg, apf, config) and
- if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
+ if node instanceof CastingNode
+ then compatibleTypes(getErasedNodeType(node), apf.getType())
+ else any()
}
/**
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
- private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
+ private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1067,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
+ exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
flowCandFwd(mid, fromArg, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
apf = TFrontNil(t)
@@ -1220,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
}
private newtype TAccessPath =
- TNil(DataFlowType t) or
- TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
+ TNil(DataFlowErasedType t) or
+ TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
/**
@@ -1248,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
this = TConsCons(_, _, result)
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TNil(result)
or
result = this.getHead().getContainerType()
@@ -1264,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
private class AccessPathNil extends AccessPath, TNil {
override string toString() {
- exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
+ exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
}
override predicate pop(Content head, AccessPath tail) { none() }
@@ -1278,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
private class AccessPathConsNil extends AccessPathCons, TConsNil {
override string toString() {
- exists(Content f, DataFlowType t | this = TConsNil(f, t) |
+ exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
// The `concat` becomes "" if `ppReprType` has no result.
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
)
@@ -1289,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
}
override predicate pop(Content head, AccessPath tail) {
- exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
+ exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
}
}
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
- private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
+ private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -1409,7 +1411,7 @@ private predicate flowFwd0(
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathNil nil, DataFlowType t |
+ exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
flowFwd(mid, fromArg, _, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
ap = TNil(t) and
@@ -2018,7 +2020,7 @@ private module FlowExploration {
}
private newtype TPartialAccessPath =
- TPartialNil(DataFlowType t) or
+ TPartialNil(DataFlowErasedType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
@@ -2039,7 +2041,7 @@ private module FlowExploration {
this = TPartialCons(_, result)
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
@@ -2050,11 +2052,11 @@ private module FlowExploration {
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
- exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
+ exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
@@ -2076,7 +2078,7 @@ private module FlowExploration {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2091,7 +2093,9 @@ private module FlowExploration {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
not fullBarrier(node, config) and
- if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
+ if node instanceof CastingNode
+ then compatibleTypes(getErasedNodeType(node), ap.getType())
+ else any()
)
}
@@ -2194,7 +2198,7 @@ private module FlowExploration {
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof PartialAccessPathNil and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
)
or
@@ -2206,7 +2210,7 @@ private module FlowExploration {
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof PartialAccessPathNil and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and
diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl5.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl5.qll
index 7ecb474f632..6f74f6f024a 100644
--- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl5.qll
+++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl5.qll
@@ -460,11 +460,11 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
*/
pragma[nomagic]
private predicate simpleParameterFlow(
- ParameterNode p, Node node, DataFlowType t, Configuration config
+ ParameterNode p, Node node, DataFlowErasedType t, Configuration config
) {
throughFlowNodeCand(node, config) and
p = node and
- t = getErasedRepr(node.getType()) and
+ t = getErasedNodeType(node) and
exists(ReturnNode ret, ReturnKind kind |
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
kind = ret.getKind() and
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localFlowStep(mid, node, config) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, _, config) and
additionalLocalFlowStep(mid, node, config) and
- t = getErasedRepr(node.getType())
+ t = getErasedNodeType(node)
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localStoreReadStep(mid, node) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
// value flow through a callable
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
exists(Node arg |
simpleParameterFlow(p, arg, t, config) and
argumentValueFlowsThrough(arg, node, _) and
- compatibleTypes(t, node.getType())
+ compatibleTypes(t, getErasedNodeType(node))
)
or
// flow through a callable
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
pragma[noinline]
private predicate simpleArgumentFlowsThrough0(
- DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
+ DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
) {
nodeCand1(arg, unbind(config)) and
not outBarrier(arg, config) and
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
* additional step from the configuration.
*/
private predicate simpleArgumentFlowsThrough(
- ArgumentNode arg, Node out, DataFlowType t, Configuration config
+ ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
nodeCand1(out, unbind(config)) and
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
}
private newtype TAccessPathFront =
- TFrontNil(DataFlowType t) or
+ TFrontNil(DataFlowErasedType t) or
TFrontHead(Content f)
/**
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
*/
private class AccessPathFront extends TAccessPathFront {
string toString() {
- exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
+ exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
or
exists(Content f | this = TFrontHead(f) | result = f.toString())
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TFrontNil(result)
or
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
*/
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
flowCandFwd0(node, fromArg, apf, config) and
- if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
+ if node instanceof CastingNode
+ then compatibleTypes(getErasedNodeType(node), apf.getType())
+ else any()
}
/**
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
- private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
+ private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1067,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
+ exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
flowCandFwd(mid, fromArg, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
apf = TFrontNil(t)
@@ -1220,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
}
private newtype TAccessPath =
- TNil(DataFlowType t) or
- TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
+ TNil(DataFlowErasedType t) or
+ TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
/**
@@ -1248,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
this = TConsCons(_, _, result)
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TNil(result)
or
result = this.getHead().getContainerType()
@@ -1264,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
private class AccessPathNil extends AccessPath, TNil {
override string toString() {
- exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
+ exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
}
override predicate pop(Content head, AccessPath tail) { none() }
@@ -1278,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
private class AccessPathConsNil extends AccessPathCons, TConsNil {
override string toString() {
- exists(Content f, DataFlowType t | this = TConsNil(f, t) |
+ exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
// The `concat` becomes "" if `ppReprType` has no result.
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
)
@@ -1289,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
}
override predicate pop(Content head, AccessPath tail) {
- exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
+ exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
}
}
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
- private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
+ private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -1409,7 +1411,7 @@ private predicate flowFwd0(
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathNil nil, DataFlowType t |
+ exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
flowFwd(mid, fromArg, _, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
ap = TNil(t) and
@@ -2018,7 +2020,7 @@ private module FlowExploration {
}
private newtype TPartialAccessPath =
- TPartialNil(DataFlowType t) or
+ TPartialNil(DataFlowErasedType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
@@ -2039,7 +2041,7 @@ private module FlowExploration {
this = TPartialCons(_, result)
}
- DataFlowType getType() {
+ DataFlowErasedType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
@@ -2050,11 +2052,11 @@ private module FlowExploration {
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
- exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
+ exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
@@ -2076,7 +2078,7 @@ private module FlowExploration {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2091,7 +2093,9 @@ private module FlowExploration {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
not fullBarrier(node, config) and
- if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
+ if node instanceof CastingNode
+ then compatibleTypes(getErasedNodeType(node), ap.getType())
+ else any()
)
}
@@ -2194,7 +2198,7 @@ private module FlowExploration {
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof PartialAccessPathNil and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
)
or
@@ -2206,7 +2210,7 @@ private module FlowExploration {
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof PartialAccessPathNil and
- ap = TPartialNil(getErasedRepr(node.getType())) and
+ ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and
diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll
index 8b9c8f5abd3..f0b5cb2b347 100644
--- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll
+++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll
@@ -57,14 +57,14 @@ private module ImplCommon {
exists(Node mid |
parameterValueFlowCand(p, mid) and
step(mid, node) and
- compatibleTypes(p.getType(), node.getType())
+ compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
)
or
// flow through a callable
exists(Node arg |
parameterValueFlowCand(p, arg) and
argumentValueFlowsThroughCand(arg, node) and
- compatibleTypes(p.getType(), node.getType())
+ compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
)
}
@@ -95,7 +95,7 @@ private module ImplCommon {
argumentValueFlowsThroughCand0(call, arg, kind)
|
out = getAnOutNode(call, kind) and
- compatibleTypes(arg.getType(), out.getType())
+ compatibleTypes(getErasedNodeType(arg), getErasedNodeType(out))
)
}
@@ -183,7 +183,7 @@ private module ImplCommon {
exists(Node mid |
parameterValueFlow(p, mid, cc) and
step(mid, node) and
- compatibleTypes(p.getType(), node.getType()) and
+ compatibleTypes(getErasedNodeType(p), getErasedNodeType(node)) and
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall())
)
or
@@ -191,7 +191,7 @@ private module ImplCommon {
exists(Node arg |
parameterValueFlow(p, arg, cc) and
argumentValueFlowsThrough(arg, node, cc) and
- compatibleTypes(p.getType(), node.getType()) and
+ compatibleTypes(getErasedNodeType(p), getErasedNodeType(node)) and
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall())
)
}
@@ -226,7 +226,7 @@ private module ImplCommon {
|
out = getAnOutNode(call, kind) and
not isUnreachableInCall(out, cc.(CallContextSpecificCall).getCall()) and
- compatibleTypes(arg.getType(), out.getType())
+ compatibleTypes(getErasedNodeType(arg), getErasedNodeType(out))
)
}
}
@@ -260,7 +260,7 @@ private module ImplCommon {
exists(Node mid |
parameterValueFlowNoCtx(p, mid) and
localValueStep(mid, node) and
- compatibleTypes(p.getType(), node.getType())
+ compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
)
}
@@ -296,8 +296,8 @@ private module ImplCommon {
setterCall(call, i1, i2, f) and
node1.(ArgumentNode).argumentOf(call, i1) and
node2.getPreUpdateNode().(ArgumentNode).argumentOf(call, i2) and
- compatibleTypes(node1.getTypeBound(), f.getType()) and
- compatibleTypes(node2.getTypeBound(), f.getContainerType())
+ compatibleTypes(getErasedNodeTypeBound(node1), f.getType()) and
+ compatibleTypes(getErasedNodeTypeBound(node2), f.getContainerType())
)
}
@@ -333,8 +333,8 @@ private module ImplCommon {
exists(DataFlowCall call, ReturnKind kind |
storeReturn0(call, kind, node1, f) and
node2 = getAnOutNode(call, kind) and
- compatibleTypes(node1.getTypeBound(), f.getType()) and
- compatibleTypes(node2.getTypeBound(), f.getContainerType())
+ compatibleTypes(getErasedNodeTypeBound(node1), f.getType()) and
+ compatibleTypes(getErasedNodeTypeBound(node2), f.getContainerType())
)
}
@@ -365,8 +365,8 @@ private module ImplCommon {
exists(DataFlowCall call, ReturnKind kind |
read0(call, kind, node1, f) and
node2 = getAnOutNode(call, kind) and
- compatibleTypes(node1.getTypeBound(), f.getContainerType()) and
- compatibleTypes(node2.getTypeBound(), f.getType())
+ compatibleTypes(getErasedNodeTypeBound(node1), f.getContainerType()) and
+ compatibleTypes(getErasedNodeTypeBound(node2), f.getType())
)
}
@@ -384,7 +384,7 @@ private module ImplCommon {
store(node1, f, mid1) and
localValueStep*(mid1, mid2) and
read(mid2, f, node2) and
- compatibleTypes(node1.getTypeBound(), node2.getTypeBound())
+ compatibleTypes(getErasedNodeTypeBound(node1), getErasedNodeTypeBound(node2))
)
}
@@ -405,14 +405,14 @@ private module ImplCommon {
exists(Node mid |
parameterValueFlowCand(p, mid) and
step(mid, node) and
- compatibleTypes(p.getType(), node.getType())
+ compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
)
or
// flow through a callable
exists(Node arg |
parameterValueFlowCand(p, arg) and
argumentValueFlowsThroughCand(arg, node) and
- compatibleTypes(p.getType(), node.getType())
+ compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
)
}
@@ -443,7 +443,7 @@ private module ImplCommon {
argumentValueFlowsThroughCand0(call, arg, kind)
|
out = getAnOutNode(call, kind) and
- compatibleTypes(arg.getType(), out.getType())
+ compatibleTypes(getErasedNodeType(arg), getErasedNodeType(out))
)
}
@@ -531,7 +531,7 @@ private module ImplCommon {
exists(Node mid |
parameterValueFlow(p, mid, cc) and
step(mid, node) and
- compatibleTypes(p.getType(), node.getType()) and
+ compatibleTypes(getErasedNodeType(p), getErasedNodeType(node)) and
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall())
)
or
@@ -539,7 +539,7 @@ private module ImplCommon {
exists(Node arg |
parameterValueFlow(p, arg, cc) and
argumentValueFlowsThrough(arg, node, cc) and
- compatibleTypes(p.getType(), node.getType()) and
+ compatibleTypes(getErasedNodeType(p), getErasedNodeType(node)) and
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall())
)
}
@@ -574,7 +574,7 @@ private module ImplCommon {
|
out = getAnOutNode(call, kind) and
not isUnreachableInCall(out, cc.(CallContextSpecificCall).getCall()) and
- compatibleTypes(arg.getType(), out.getType())
+ compatibleTypes(getErasedNodeType(arg), getErasedNodeType(out))
)
}
}
@@ -860,4 +860,10 @@ private module ImplCommon {
or
result = viableCallable(call) and cc instanceof CallContextReturn
}
+
+ pragma[noinline]
+ DataFlowErasedType getErasedNodeType(Node n) { result = getErasedRepr(n.getType()) }
+
+ pragma[noinline]
+ DataFlowErasedType getErasedNodeTypeBound(Node n) { result = getErasedRepr(n.getTypeBound()) }
}
From 3c9fe91581f8d9ed585a1a0e54d8722480a21c5d Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Tue, 19 Nov 2019 10:54:04 +0000
Subject: [PATCH 10/44] CPP: Add proof of zero-termination to tests.
---
.../NoSpaceForZeroTerminator.expected | 8 ++++----
.../CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test.c | 9 +++++++++
.../CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test.cpp | 9 +++++++++
3 files changed, 22 insertions(+), 4 deletions(-)
diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/NoSpaceForZeroTerminator.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/NoSpaceForZeroTerminator.expected
index a33f824484b..f2f201053d9 100644
--- a/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/NoSpaceForZeroTerminator.expected
+++ b/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/NoSpaceForZeroTerminator.expected
@@ -1,4 +1,4 @@
-| test.c:15:20:15:25 | call to malloc | This allocation does not include space to null-terminate the string. |
-| test.c:29:20:29:25 | call to malloc | This allocation does not include space to null-terminate the string. |
-| test.c:44:20:44:25 | call to malloc | This allocation does not include space to null-terminate the string. |
-| test.cpp:18:35:18:40 | call to malloc | This allocation does not include space to null-terminate the string. |
+| test.c:16:20:16:25 | call to malloc | This allocation does not include space to null-terminate the string. |
+| test.c:32:20:32:25 | call to malloc | This allocation does not include space to null-terminate the string. |
+| test.c:49:20:49:25 | call to malloc | This allocation does not include space to null-terminate the string. |
+| test.cpp:24:35:24:40 | call to malloc | This allocation does not include space to null-terminate the string. |
diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test.c b/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test.c
index a6d054874d0..2f06af7d42d 100644
--- a/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test.c
+++ b/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test.c
@@ -7,18 +7,21 @@
typedef unsigned long size_t;
void *malloc(size_t size);
void free(void *ptr);
+char *strcpy(char *s1, const char *s2);
//// Test code /////
void bad0(char *str) {
// BAD -- Not allocating space for '\0' terminator
char *buffer = malloc(strlen(str));
+ strcpy(buffer, str);
free(buffer);
}
void good0(char *str) {
// GOOD -- Allocating extra byte for terminator
char *buffer = malloc(strlen(str)+1);
+ strcpy(buffer, str);
free(buffer);
}
@@ -27,6 +30,7 @@ void bad1(char *str) {
int len = strlen(str);
// BAD -- Not allocating space for '\0' terminator
char *buffer = malloc(len);
+ strcpy(buffer, str);
free(buffer);
}
@@ -34,6 +38,7 @@ void good1(char *str) {
int len = strlen(str);
// GOOD -- Allocating extra byte for terminator
char *buffer = malloc(len+1);
+ strcpy(buffer, str);
free(buffer);
}
@@ -42,6 +47,7 @@ void bad2(char *str) {
int len = strlen(str);
// BAD -- Not allocating space for '\0' terminator
char *buffer = malloc(len);
+ strcpy(buffer, str);
free(buffer);
}
@@ -49,18 +55,21 @@ void good2(char *str) {
int len = strlen(str)+1;
// GOOD -- Allocating extra byte for terminator
char *buffer = malloc(len);
+ strcpy(buffer, str);
free(buffer);
}
void bad3(char *str) {
// BAD -- Not allocating space for '\0' terminator [NOT DETECTED]
char *buffer = malloc(strlen(str) * sizeof(char));
+ strcpy(buffer, str);
free(buffer);
}
void good3(char *str) {
// GOOD -- Allocating extra byte for terminator
char *buffer = malloc((strlen(str) + 1) * sizeof(char));
+ strcpy(buffer, str);
free(buffer);
}
diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test.cpp
index 53488c0f229..e240d391224 100644
--- a/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test.cpp
+++ b/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test.cpp
@@ -10,23 +10,32 @@ typedef unsigned long size_t;
void *malloc(size_t size);
void free(void *ptr);
size_t wcslen(const wchar_t *s);
+wchar_t* wcscpy(wchar_t* s1, const wchar_t* s2);
+
+
+
+
+
//// Test code /////
void bad1(wchar_t *wstr) {
// BAD -- Not allocating space for '\0' terminator
wchar_t *wbuffer = (wchar_t *)malloc(wcslen(wstr));
+ wcscpy(wbuffer, wstr);
free(wbuffer);
}
void bad2(wchar_t *wstr) {
// BAD -- Not allocating space for '\0' terminator [NOT DETECTED]
wchar_t *wbuffer = (wchar_t *)malloc(wcslen(wstr) * sizeof(wchar_t));
+ wcscpy(wbuffer, wstr);
free(wbuffer);
}
void good1(wchar_t *wstr) {
// GOOD -- Allocating extra character for terminator
wchar_t *wbuffer = (wchar_t *)malloc((wcslen(wstr) + 1) * sizeof(wchar_t));
+ wcscpy(wbuffer, wstr);
free(wbuffer);
}
From 57c7a87af918bb53dcd3fd6eaa57bef2a8e3431d Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Tue, 19 Nov 2019 11:36:12 +0000
Subject: [PATCH 11/44] CPP: Add tests with different proof of
zero-termination.
---
.../NoSpaceForZeroTerminator.expected | 7 ++
.../semmle/NoSpaceForZeroTerminator/test.cpp | 71 +++++++++++++++++--
2 files changed, 73 insertions(+), 5 deletions(-)
diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/NoSpaceForZeroTerminator.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/NoSpaceForZeroTerminator.expected
index f2f201053d9..7deb5de7541 100644
--- a/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/NoSpaceForZeroTerminator.expected
+++ b/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/NoSpaceForZeroTerminator.expected
@@ -2,3 +2,10 @@
| test.c:32:20:32:25 | call to malloc | This allocation does not include space to null-terminate the string. |
| test.c:49:20:49:25 | call to malloc | This allocation does not include space to null-terminate the string. |
| test.cpp:24:35:24:40 | call to malloc | This allocation does not include space to null-terminate the string. |
+| test.cpp:45:28:45:33 | call to malloc | This allocation does not include space to null-terminate the string. |
+| test.cpp:55:28:55:33 | call to malloc | This allocation does not include space to null-terminate the string. |
+| test.cpp:63:28:63:33 | call to malloc | This allocation does not include space to null-terminate the string. |
+| test.cpp:71:28:71:33 | call to malloc | This allocation does not include space to null-terminate the string. |
+| test.cpp:79:28:79:33 | call to malloc | This allocation does not include space to null-terminate the string. |
+| test.cpp:89:35:89:40 | call to malloc | This allocation does not include space to null-terminate the string. |
+| test.cpp:99:28:99:33 | call to malloc | This allocation does not include space to null-terminate the string. |
diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test.cpp
index e240d391224..13196226d8d 100644
--- a/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test.cpp
+++ b/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test.cpp
@@ -11,11 +11,11 @@ void *malloc(size_t size);
void free(void *ptr);
size_t wcslen(const wchar_t *s);
wchar_t* wcscpy(wchar_t* s1, const wchar_t* s2);
-
-
-
-
-
+int sprintf(char *s, const char *format, ...);
+int wprintf(const wchar_t *format, ...);
+char *strcat(char *s1, const char *s2);
+size_t strlen(const char *s);
+int strcmp(const char *s1, const char *s2);
//// Test code /////
@@ -39,3 +39,64 @@ void good1(wchar_t *wstr) {
wcscpy(wbuffer, wstr);
free(wbuffer);
}
+
+void bad3(char *str) {
+ // BAD -- zero-termination proved by sprintf (as destination)
+ char *buffer = (char *)malloc(strlen(str));
+ sprintf(buffer, "%s", str);
+ free(buffer);
+}
+
+void decode(char *dest, char *src);
+void wdecode(wchar_t *dest, wchar_t *src);
+
+void bad4(char *str) {
+ // BAD -- zero-termination proved by wprintf (as parameter)
+ char *buffer = (char *)malloc(strlen(str));
+ decode(buffer, str);
+ wprintf(L"%s", buffer);
+ free(buffer);
+}
+
+void bad5(char *str) {
+ // BAD -- zero-termination proved by strcat (as destination)
+ char *buffer = (char *)malloc(strlen(str));
+ buffer[0] = 0;
+ strcat(buffer, str);
+ free(buffer);
+}
+
+void bad6(char *str, char *dest) {
+ // BAD -- zero-termination proved by strcat (as source)
+ char *buffer = (char *)malloc(strlen(str));
+ decode(buffer, str);
+ strcat(dest, buffer);
+ free(buffer);
+}
+
+void bad7(char *str, char *str2) {
+ // BAD -- zero-termination proved by strcmp
+ char *buffer = (char *)malloc(strlen(str));
+ decode(buffer, str);
+ if (strcmp(buffer, str2) == 0) {
+ // ...
+ }
+ free(buffer);
+}
+
+void bad8(wchar_t *str) {
+ // BAD -- zero-termination proved by wcslen
+ wchar_t *wbuffer = (wchar_t *)malloc(wcslen(str));
+ wdecode(wbuffer, str);
+ if (wcslen(wbuffer) == 0) {
+ // ...
+ }
+ free(wbuffer);
+}
+
+void good2(char *str, char *dest) {
+ // GOOD -- zero-termination not proven [FALSE POSITIVE]
+ char *buffer = (char *)malloc(strlen(str));
+ decode(buffer, str);
+ free(buffer);
+}
From 6fc9cc595244dbd9cc711816019966f4ac6e3f8d Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Tue, 19 Nov 2019 14:30:35 +0000
Subject: [PATCH 12/44] CPP: Add a test case using 'new'.
---
.../CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test.cpp | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test.cpp
index 13196226d8d..30083e7811a 100644
--- a/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test.cpp
+++ b/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test.cpp
@@ -100,3 +100,10 @@ void good2(char *str, char *dest) {
decode(buffer, str);
free(buffer);
}
+
+void bad9(wchar_t *wstr) {
+ // BAD -- using new [NOT DETECTED]
+ wchar_t *wbuffer = new wchar_t[wcslen(wstr)];
+ wcscpy(wbuffer, wstr);
+ delete wbuffer;
+}
From fbd9d9bdab4c849e689dcecad7edcf78d950a430 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Tue, 19 Nov 2019 15:43:19 +0000
Subject: [PATCH 13/44] CPP: Add a test case involving the std::string
constructor.
---
.../NoSpaceForZeroTerminator.expected | 1 +
.../semmle/NoSpaceForZeroTerminator/test2.cpp | 38 +++++++++++++++++++
2 files changed, 39 insertions(+)
create mode 100644 cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test2.cpp
diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/NoSpaceForZeroTerminator.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/NoSpaceForZeroTerminator.expected
index 7deb5de7541..4f8991dc564 100644
--- a/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/NoSpaceForZeroTerminator.expected
+++ b/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/NoSpaceForZeroTerminator.expected
@@ -1,3 +1,4 @@
+| test2.cpp:35:28:35:33 | call to malloc | This allocation does not include space to null-terminate the string. |
| test.c:16:20:16:25 | call to malloc | This allocation does not include space to null-terminate the string. |
| test.c:32:20:32:25 | call to malloc | This allocation does not include space to null-terminate the string. |
| test.c:49:20:49:25 | call to malloc | This allocation does not include space to null-terminate the string. |
diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test2.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test2.cpp
new file mode 100644
index 00000000000..e0cf225b96f
--- /dev/null
+++ b/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test2.cpp
@@ -0,0 +1,38 @@
+
+///// Library functions //////
+
+typedef unsigned long size_t;
+
+void *malloc(size_t size);
+void free(void *ptr);
+size_t strlen(const char *s);
+
+namespace std
+{
+ template struct char_traits;
+
+ template class allocator {
+ public:
+ allocator() throw();
+ };
+
+ template, class Allocator = allocator >
+ class basic_string {
+ public:
+ explicit basic_string(const Allocator& a = Allocator());
+ basic_string(const charT* s, const Allocator& a = Allocator());
+
+ const charT* c_str() const;
+ };
+
+ typedef basic_string string;
+}
+
+//// Test code /////
+
+void bad1(char *str) {
+ // BAD -- Not allocating space for '\0' terminator
+ char *buffer = (char *)malloc(strlen(str));
+ std::string str2(buffer);
+ free(buffer);
+}
From e6ea705ff29d3cf4add63725f1ead3f7909d90d1 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Tue, 19 Nov 2019 14:49:28 +0000
Subject: [PATCH 14/44] CPP: Switch from a blacklist to whitelist approach for
determining null termination.
---
.../CWE/CWE-131/NoSpaceForZeroTerminator.ql | 18 +++++++++++++-----
.../NoSpaceForZeroTerminator.expected | 6 ------
.../semmle/NoSpaceForZeroTerminator/test.cpp | 10 +++++-----
.../semmle/NoSpaceForZeroTerminator/test2.cpp | 2 +-
4 files changed, 19 insertions(+), 17 deletions(-)
diff --git a/cpp/ql/src/Security/CWE/CWE-131/NoSpaceForZeroTerminator.ql b/cpp/ql/src/Security/CWE/CWE-131/NoSpaceForZeroTerminator.ql
index ff17daca05c..6f4b8d3f392 100644
--- a/cpp/ql/src/Security/CWE/CWE-131/NoSpaceForZeroTerminator.ql
+++ b/cpp/ql/src/Security/CWE/CWE-131/NoSpaceForZeroTerminator.ql
@@ -16,7 +16,7 @@
import cpp
import semmle.code.cpp.dataflow.DataFlow
-import semmle.code.cpp.models.implementations.Memcpy
+import semmle.code.cpp.models.interfaces.ArrayFunction
class MallocCall extends FunctionCall {
MallocCall() { this.getTarget().hasGlobalOrStdName("malloc") }
@@ -33,11 +33,19 @@ class MallocCall extends FunctionCall {
}
predicate terminationProblem(MallocCall malloc, string msg) {
+ // malloc(strlen(...))
malloc.getAllocatedSize() instanceof StrlenCall and
- not exists(FunctionCall fc, MemcpyFunction memcpy, int ix |
- DataFlow::localExprFlow(malloc, fc.getArgument(ix)) and
- fc.getTarget() = memcpy and
- memcpy.hasArrayOutput(ix)
+ // flows into a null-terminated string function
+ exists(ArrayFunction af, FunctionCall fc, int arg |
+ DataFlow::localExprFlow(malloc, fc.getArgument(arg)) and
+ fc.getTarget() = af and
+ (
+ // null terminated string
+ af.hasArrayWithNullTerminator(arg)
+ or
+ // likely a null terminated string (such as `strcpy`, `strcat`)
+ af.hasArrayWithUnknownSize(arg)
+ )
) and
msg = "This allocation does not include space to null-terminate the string."
}
diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/NoSpaceForZeroTerminator.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/NoSpaceForZeroTerminator.expected
index 4f8991dc564..972b06af73c 100644
--- a/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/NoSpaceForZeroTerminator.expected
+++ b/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/NoSpaceForZeroTerminator.expected
@@ -1,12 +1,6 @@
-| test2.cpp:35:28:35:33 | call to malloc | This allocation does not include space to null-terminate the string. |
| test.c:16:20:16:25 | call to malloc | This allocation does not include space to null-terminate the string. |
| test.c:32:20:32:25 | call to malloc | This allocation does not include space to null-terminate the string. |
| test.c:49:20:49:25 | call to malloc | This allocation does not include space to null-terminate the string. |
| test.cpp:24:35:24:40 | call to malloc | This allocation does not include space to null-terminate the string. |
-| test.cpp:45:28:45:33 | call to malloc | This allocation does not include space to null-terminate the string. |
-| test.cpp:55:28:55:33 | call to malloc | This allocation does not include space to null-terminate the string. |
| test.cpp:63:28:63:33 | call to malloc | This allocation does not include space to null-terminate the string. |
| test.cpp:71:28:71:33 | call to malloc | This allocation does not include space to null-terminate the string. |
-| test.cpp:79:28:79:33 | call to malloc | This allocation does not include space to null-terminate the string. |
-| test.cpp:89:35:89:40 | call to malloc | This allocation does not include space to null-terminate the string. |
-| test.cpp:99:28:99:33 | call to malloc | This allocation does not include space to null-terminate the string. |
diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test.cpp
index 30083e7811a..23c446b2a84 100644
--- a/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test.cpp
+++ b/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test.cpp
@@ -41,7 +41,7 @@ void good1(wchar_t *wstr) {
}
void bad3(char *str) {
- // BAD -- zero-termination proved by sprintf (as destination)
+ // BAD -- zero-termination proved by sprintf (as destination) [NOT DETECTED]
char *buffer = (char *)malloc(strlen(str));
sprintf(buffer, "%s", str);
free(buffer);
@@ -51,7 +51,7 @@ void decode(char *dest, char *src);
void wdecode(wchar_t *dest, wchar_t *src);
void bad4(char *str) {
- // BAD -- zero-termination proved by wprintf (as parameter)
+ // BAD -- zero-termination proved by wprintf (as parameter) [NOT DETECTED]
char *buffer = (char *)malloc(strlen(str));
decode(buffer, str);
wprintf(L"%s", buffer);
@@ -75,7 +75,7 @@ void bad6(char *str, char *dest) {
}
void bad7(char *str, char *str2) {
- // BAD -- zero-termination proved by strcmp
+ // BAD -- zero-termination proved by strcmp [NOT DETECTED]
char *buffer = (char *)malloc(strlen(str));
decode(buffer, str);
if (strcmp(buffer, str2) == 0) {
@@ -85,7 +85,7 @@ void bad7(char *str, char *str2) {
}
void bad8(wchar_t *str) {
- // BAD -- zero-termination proved by wcslen
+ // BAD -- zero-termination proved by wcslen [NOT DETECTED]
wchar_t *wbuffer = (wchar_t *)malloc(wcslen(str));
wdecode(wbuffer, str);
if (wcslen(wbuffer) == 0) {
@@ -95,7 +95,7 @@ void bad8(wchar_t *str) {
}
void good2(char *str, char *dest) {
- // GOOD -- zero-termination not proven [FALSE POSITIVE]
+ // GOOD -- zero-termination not proven
char *buffer = (char *)malloc(strlen(str));
decode(buffer, str);
free(buffer);
diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test2.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test2.cpp
index e0cf225b96f..5fad5db1142 100644
--- a/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test2.cpp
+++ b/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test2.cpp
@@ -31,7 +31,7 @@ namespace std
//// Test code /////
void bad1(char *str) {
- // BAD -- Not allocating space for '\0' terminator
+ // BAD -- Not allocating space for '\0' terminator [NOT DETECTED]
char *buffer = (char *)malloc(strlen(str));
std::string str2(buffer);
free(buffer);
From 2212c47db24992de02c641b6e98d8e6d53359319 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Tue, 19 Nov 2019 17:54:04 +0000
Subject: [PATCH 15/44] CPP: Use dataflow more consistently.
---
.../Security/CWE/CWE-131/NoSpaceForZeroTerminator.ql | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/cpp/ql/src/Security/CWE/CWE-131/NoSpaceForZeroTerminator.ql b/cpp/ql/src/Security/CWE/CWE-131/NoSpaceForZeroTerminator.ql
index 6f4b8d3f392..ef983af4cb2 100644
--- a/cpp/ql/src/Security/CWE/CWE-131/NoSpaceForZeroTerminator.ql
+++ b/cpp/ql/src/Security/CWE/CWE-131/NoSpaceForZeroTerminator.ql
@@ -22,19 +22,15 @@ class MallocCall extends FunctionCall {
MallocCall() { this.getTarget().hasGlobalOrStdName("malloc") }
Expr getAllocatedSize() {
- if this.getArgument(0) instanceof VariableAccess
- then
- exists(LocalScopeVariable v, ControlFlowNode def |
- definitionUsePair(v, def, this.getArgument(0)) and
- exprDefinition(v, def, result)
- )
- else result = this.getArgument(0)
+ result = this.getArgument(0)
}
}
predicate terminationProblem(MallocCall malloc, string msg) {
// malloc(strlen(...))
- malloc.getAllocatedSize() instanceof StrlenCall and
+ exists(StrlenCall strlen |
+ DataFlow::localExprFlow(strlen, malloc.getAllocatedSize())
+ ) and
// flows into a null-terminated string function
exists(ArrayFunction af, FunctionCall fc, int arg |
DataFlow::localExprFlow(malloc, fc.getArgument(arg)) and
From 5c855fc92591a1dde1dc53b4aa5841f190eae33c Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Wed, 20 Nov 2019 14:35:45 +0000
Subject: [PATCH 16/44] CPP: Change note.
---
change-notes/1.24/analysis-cpp.md | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
create mode 100644 change-notes/1.24/analysis-cpp.md
diff --git a/change-notes/1.24/analysis-cpp.md b/change-notes/1.24/analysis-cpp.md
new file mode 100644
index 00000000000..2e7fdd422af
--- /dev/null
+++ b/change-notes/1.24/analysis-cpp.md
@@ -0,0 +1,20 @@
+# Improvements to C/C++ analysis
+
+The following changes in version 1.24 affect C/C++ analysis in all applications.
+
+## General improvements
+
+## New queries
+
+| **Query** | **Tags** | **Purpose** |
+|-----------------------------|-----------|--------------------------------------------------------------------|
+
+## Changes to existing queries
+
+| **Query** | **Expected impact** | **Change** |
+|----------------------------|------------------------|------------------------------------------------------------------|
+| No space for zero terminator (`cpp/no-space-for-terminator`) | Fewer false positive results | This query has been modified to be more conservative when identifying which pointers point to null-terminated strings. This approach produces fewer, more accurate results. |
+
+## Changes to libraries
+
+*
From d8aae1c1264d4f36d5dfe9a98f1f2b93a4268265 Mon Sep 17 00:00:00 2001
From: Cornelius Riemenschneider
Date: Thu, 21 Nov 2019 18:33:48 +0100
Subject: [PATCH 17/44] Add tests to track nullness by instanceof checks.
---
java/ql/test/query-tests/Nullness/B.java | 20 +++++++++++++++++++
.../query-tests/Nullness/NullMaybe.expected | 2 ++
2 files changed, 22 insertions(+)
diff --git a/java/ql/test/query-tests/Nullness/B.java b/java/ql/test/query-tests/Nullness/B.java
index c0d9171041b..4db5a2f50b5 100644
--- a/java/ql/test/query-tests/Nullness/B.java
+++ b/java/ql/test/query-tests/Nullness/B.java
@@ -324,4 +324,24 @@ public class B {
if (x != null) y.hashCode(); // OK
if (y != null) x.hashCode(); // OK
}
+
+ public void corrConds3(Object y) {
+ Object x = null;
+ if(y instanceof String) {
+ x = new Object();
+ }
+ if(y instanceof String) {
+ x.hashCode(); // OK
+ }
+ }
+
+ public void corrConds4(Object y) {
+ Object x = null;
+ if(!(y instanceof String)) {
+ x = new Object();
+ }
+ if(!(y instanceof String)) {
+ x.hashCode(); // OK
+ }
+ }
}
diff --git a/java/ql/test/query-tests/Nullness/NullMaybe.expected b/java/ql/test/query-tests/Nullness/NullMaybe.expected
index 5d50a47b9d8..03e24ef04bc 100644
--- a/java/ql/test/query-tests/Nullness/NullMaybe.expected
+++ b/java/ql/test/query-tests/Nullness/NullMaybe.expected
@@ -17,6 +17,8 @@
| B.java:190:7:190:7 | o | Variable $@ may be null here because of $@ assignment. | B.java:178:5:178:20 | Object o | o | B.java:186:5:186:12 | ...=... | this |
| B.java:279:7:279:7 | a | Variable $@ may be null here because of $@ assignment. | B.java:276:5:276:19 | int[] a | a | B.java:276:11:276:18 | a | this |
| B.java:292:7:292:7 | b | Variable $@ may be null here because of $@ assignment. | B.java:287:5:287:44 | int[] b | b | B.java:287:11:287:43 | b | this |
+| B.java:334:7:334:7 | x | Variable $@ may be null here because of $@ assignment. | B.java:329:5:329:20 | Object x | x | B.java:329:12:329:19 | x | this |
+| B.java:344:7:344:7 | x | Variable $@ may be null here because of $@ assignment. | B.java:339:5:339:20 | Object x | x | B.java:339:12:339:19 | x | this |
| C.java:9:44:9:45 | a2 | Variable $@ may be null here as suggested by $@ null guard. | C.java:6:5:6:23 | long[][] a2 | a2 | C.java:7:34:7:54 | ... != ... | this |
| C.java:9:44:9:45 | a2 | Variable $@ may be null here because of $@ assignment. | C.java:6:5:6:23 | long[][] a2 | a2 | C.java:6:14:6:22 | a2 | this |
| C.java:10:17:10:18 | a3 | Variable $@ may be null here as suggested by $@ null guard. | C.java:8:5:8:21 | long[] a3 | a3 | C.java:9:38:9:58 | ... != ... | this |
From 3e5324e77211d62e162eb90ab2ca3244bd001cee Mon Sep 17 00:00:00 2001
From: Cornelius Riemenschneider
Date: Thu, 21 Nov 2019 18:37:44 +0100
Subject: [PATCH 18/44] More precise Nullness tracking by taking correlated
instanceof expressions into account.
Fixes #2238.
---
java/ql/src/semmle/code/java/dataflow/NullGuards.qll | 6 ++++++
java/ql/src/semmle/code/java/dataflow/Nullness.qll | 7 +++++++
java/ql/test/query-tests/Nullness/NullMaybe.expected | 2 --
3 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/java/ql/src/semmle/code/java/dataflow/NullGuards.qll b/java/ql/src/semmle/code/java/dataflow/NullGuards.qll
index 43425f2f908..dd24697c70a 100644
--- a/java/ql/src/semmle/code/java/dataflow/NullGuards.qll
+++ b/java/ql/src/semmle/code/java/dataflow/NullGuards.qll
@@ -24,6 +24,12 @@ Expr enumConstEquality(Expr e, boolean polarity, EnumConstant c) {
)
}
+/** Gets an instanceof expression of `v` with type `type` */
+InstanceOfExpr instanceofExpr(SsaVariable v, Expr type) {
+ result.getTypeName() = type and
+ result.getExpr() = v.getAUse()
+}
+
/** Gets an expression that is provably not `null`. */
Expr clearlyNotNullExpr(Expr reason) {
result instanceof ClassInstanceExpr and reason = result
diff --git a/java/ql/src/semmle/code/java/dataflow/Nullness.qll b/java/ql/src/semmle/code/java/dataflow/Nullness.qll
index d7da85832ae..7fda19e2045 100644
--- a/java/ql/src/semmle/code/java/dataflow/Nullness.qll
+++ b/java/ql/src/semmle/code/java/dataflow/Nullness.qll
@@ -515,6 +515,13 @@ private predicate correlatedConditions(
cond2.getCondition() = enumConstEquality(v.getAUse(), pol2, c) and
inverted = pol1.booleanXor(pol2)
)
+ or
+ exists(SsaVariable v, Expr t1, Expr t2 |
+ cond1.getCondition() = instanceofExpr(v, t1) and
+ cond2.getCondition() = instanceofExpr(v, t2) and
+ t1.getType() = t2.getType() and
+ inverted = false
+ )
)
}
diff --git a/java/ql/test/query-tests/Nullness/NullMaybe.expected b/java/ql/test/query-tests/Nullness/NullMaybe.expected
index 03e24ef04bc..5d50a47b9d8 100644
--- a/java/ql/test/query-tests/Nullness/NullMaybe.expected
+++ b/java/ql/test/query-tests/Nullness/NullMaybe.expected
@@ -17,8 +17,6 @@
| B.java:190:7:190:7 | o | Variable $@ may be null here because of $@ assignment. | B.java:178:5:178:20 | Object o | o | B.java:186:5:186:12 | ...=... | this |
| B.java:279:7:279:7 | a | Variable $@ may be null here because of $@ assignment. | B.java:276:5:276:19 | int[] a | a | B.java:276:11:276:18 | a | this |
| B.java:292:7:292:7 | b | Variable $@ may be null here because of $@ assignment. | B.java:287:5:287:44 | int[] b | b | B.java:287:11:287:43 | b | this |
-| B.java:334:7:334:7 | x | Variable $@ may be null here because of $@ assignment. | B.java:329:5:329:20 | Object x | x | B.java:329:12:329:19 | x | this |
-| B.java:344:7:344:7 | x | Variable $@ may be null here because of $@ assignment. | B.java:339:5:339:20 | Object x | x | B.java:339:12:339:19 | x | this |
| C.java:9:44:9:45 | a2 | Variable $@ may be null here as suggested by $@ null guard. | C.java:6:5:6:23 | long[][] a2 | a2 | C.java:7:34:7:54 | ... != ... | this |
| C.java:9:44:9:45 | a2 | Variable $@ may be null here because of $@ assignment. | C.java:6:5:6:23 | long[][] a2 | a2 | C.java:6:14:6:22 | a2 | this |
| C.java:10:17:10:18 | a3 | Variable $@ may be null here as suggested by $@ null guard. | C.java:8:5:8:21 | long[] a3 | a3 | C.java:9:38:9:58 | ... != ... | this |
From 92f32a12d886affa5eb20fc10c27b9511cc7ab6f Mon Sep 17 00:00:00 2001
From: Cornelius Riemenschneider
Date: Thu, 21 Nov 2019 19:23:39 +0100
Subject: [PATCH 19/44] Add tests for nullness tracking by comparing variables.
---
java/ql/test/query-tests/Nullness/B.java | 27 +++++++++++++++++++
.../query-tests/Nullness/NullMaybe.expected | 3 +++
2 files changed, 30 insertions(+)
diff --git a/java/ql/test/query-tests/Nullness/B.java b/java/ql/test/query-tests/Nullness/B.java
index 4db5a2f50b5..193d61e497f 100644
--- a/java/ql/test/query-tests/Nullness/B.java
+++ b/java/ql/test/query-tests/Nullness/B.java
@@ -344,4 +344,31 @@ public class B {
x.hashCode(); // OK
}
}
+
+ public void corrConds5(Object y, Object z) {
+ Object x = null;
+ if(y == z) {
+ x = new Object();
+ }
+ if(y == z) {
+ x.hashCode(); // OK
+ }
+
+ Object x2 = null;
+ if(y != z) {
+ x2 = new Object();
+ }
+ if(y != z) {
+ x2.hashCode(); // OK
+ }
+
+ Object x3 = null;
+ if(y != z) {
+ x3 = new Object();
+ }
+ if(!(y == z)) {
+ x3.hashCode(); // OK
+ }
+ }
+
}
diff --git a/java/ql/test/query-tests/Nullness/NullMaybe.expected b/java/ql/test/query-tests/Nullness/NullMaybe.expected
index 5d50a47b9d8..340fab9ca58 100644
--- a/java/ql/test/query-tests/Nullness/NullMaybe.expected
+++ b/java/ql/test/query-tests/Nullness/NullMaybe.expected
@@ -17,6 +17,9 @@
| B.java:190:7:190:7 | o | Variable $@ may be null here because of $@ assignment. | B.java:178:5:178:20 | Object o | o | B.java:186:5:186:12 | ...=... | this |
| B.java:279:7:279:7 | a | Variable $@ may be null here because of $@ assignment. | B.java:276:5:276:19 | int[] a | a | B.java:276:11:276:18 | a | this |
| B.java:292:7:292:7 | b | Variable $@ may be null here because of $@ assignment. | B.java:287:5:287:44 | int[] b | b | B.java:287:11:287:43 | b | this |
+| B.java:354:7:354:7 | x | Variable $@ may be null here because of $@ assignment. | B.java:349:5:349:20 | Object x | x | B.java:349:12:349:19 | x | this |
+| B.java:362:7:362:8 | x2 | Variable $@ may be null here because of $@ assignment. | B.java:357:5:357:21 | Object x2 | x2 | B.java:357:12:357:20 | x2 | this |
+| B.java:370:7:370:8 | x3 | Variable $@ may be null here because of $@ assignment. | B.java:365:5:365:21 | Object x3 | x3 | B.java:365:12:365:20 | x3 | this |
| C.java:9:44:9:45 | a2 | Variable $@ may be null here as suggested by $@ null guard. | C.java:6:5:6:23 | long[][] a2 | a2 | C.java:7:34:7:54 | ... != ... | this |
| C.java:9:44:9:45 | a2 | Variable $@ may be null here because of $@ assignment. | C.java:6:5:6:23 | long[][] a2 | a2 | C.java:6:14:6:22 | a2 | this |
| C.java:10:17:10:18 | a3 | Variable $@ may be null here as suggested by $@ null guard. | C.java:8:5:8:21 | long[] a3 | a3 | C.java:9:38:9:58 | ... != ... | this |
From 5d4b6c3a8ce7667bf780f1aa51e06e3bea2ab5db Mon Sep 17 00:00:00 2001
From: Cornelius Riemenschneider
Date: Thu, 21 Nov 2019 19:24:40 +0100
Subject: [PATCH 20/44] Nullness: Track correlated conditions of equality tests
of variables.
---
.../semmle/code/java/dataflow/NullGuards.qll | 21 +++++++++++++++++++
.../semmle/code/java/dataflow/Nullness.qll | 6 ++++++
.../query-tests/Nullness/NullMaybe.expected | 3 ---
3 files changed, 27 insertions(+), 3 deletions(-)
diff --git a/java/ql/src/semmle/code/java/dataflow/NullGuards.qll b/java/ql/src/semmle/code/java/dataflow/NullGuards.qll
index dd24697c70a..f337d32cc8e 100644
--- a/java/ql/src/semmle/code/java/dataflow/NullGuards.qll
+++ b/java/ql/src/semmle/code/java/dataflow/NullGuards.qll
@@ -30,6 +30,27 @@ InstanceOfExpr instanceofExpr(SsaVariable v, Expr type) {
result.getExpr() = v.getAUse()
}
+/**
+ * Gets an expression of the form `v1` == `v2` or `v1` != `v2`.
+ * The predicate is symmetric in `v1` and `v2`.
+ */
+BinaryExpr varComparisonExpr(SsaVariable v1, SsaVariable v2, boolean isEqualExpr) {
+ (
+ result.getLeftOperand() = v1.getAUse() and
+ result.getRightOperand() = v2.getAUse()
+ or
+ result.getLeftOperand() = v2.getAUse() and
+ result.getRightOperand() = v1.getAUse()
+ ) and
+ (
+ result instanceof EQExpr and
+ isEqualExpr = true
+ or
+ result instanceof NEExpr and
+ isEqualExpr = false
+ )
+}
+
/** Gets an expression that is provably not `null`. */
Expr clearlyNotNullExpr(Expr reason) {
result instanceof ClassInstanceExpr and reason = result
diff --git a/java/ql/src/semmle/code/java/dataflow/Nullness.qll b/java/ql/src/semmle/code/java/dataflow/Nullness.qll
index 7fda19e2045..03d2dfac626 100644
--- a/java/ql/src/semmle/code/java/dataflow/Nullness.qll
+++ b/java/ql/src/semmle/code/java/dataflow/Nullness.qll
@@ -522,6 +522,12 @@ private predicate correlatedConditions(
t1.getType() = t2.getType() and
inverted = false
)
+ or
+ exists(SsaVariable v1, SsaVariable v2, boolean branch1, boolean branch2 |
+ cond1.getCondition() = varComparisonExpr(v1, v2, branch1) and
+ cond2.getCondition() = varComparisonExpr(v1, v2, branch2) and
+ inverted = branch1.booleanXor(branch2)
+ )
)
}
diff --git a/java/ql/test/query-tests/Nullness/NullMaybe.expected b/java/ql/test/query-tests/Nullness/NullMaybe.expected
index 340fab9ca58..5d50a47b9d8 100644
--- a/java/ql/test/query-tests/Nullness/NullMaybe.expected
+++ b/java/ql/test/query-tests/Nullness/NullMaybe.expected
@@ -17,9 +17,6 @@
| B.java:190:7:190:7 | o | Variable $@ may be null here because of $@ assignment. | B.java:178:5:178:20 | Object o | o | B.java:186:5:186:12 | ...=... | this |
| B.java:279:7:279:7 | a | Variable $@ may be null here because of $@ assignment. | B.java:276:5:276:19 | int[] a | a | B.java:276:11:276:18 | a | this |
| B.java:292:7:292:7 | b | Variable $@ may be null here because of $@ assignment. | B.java:287:5:287:44 | int[] b | b | B.java:287:11:287:43 | b | this |
-| B.java:354:7:354:7 | x | Variable $@ may be null here because of $@ assignment. | B.java:349:5:349:20 | Object x | x | B.java:349:12:349:19 | x | this |
-| B.java:362:7:362:8 | x2 | Variable $@ may be null here because of $@ assignment. | B.java:357:5:357:21 | Object x2 | x2 | B.java:357:12:357:20 | x2 | this |
-| B.java:370:7:370:8 | x3 | Variable $@ may be null here because of $@ assignment. | B.java:365:5:365:21 | Object x3 | x3 | B.java:365:12:365:20 | x3 | this |
| C.java:9:44:9:45 | a2 | Variable $@ may be null here as suggested by $@ null guard. | C.java:6:5:6:23 | long[][] a2 | a2 | C.java:7:34:7:54 | ... != ... | this |
| C.java:9:44:9:45 | a2 | Variable $@ may be null here because of $@ assignment. | C.java:6:5:6:23 | long[][] a2 | a2 | C.java:6:14:6:22 | a2 | this |
| C.java:10:17:10:18 | a3 | Variable $@ may be null here as suggested by $@ null guard. | C.java:8:5:8:21 | long[] a3 | a3 | C.java:9:38:9:58 | ... != ... | this |
From 0e7a08201f0ed4625ca01dc4a68f80f72797237e Mon Sep 17 00:00:00 2001
From: Cornelius Riemenschneider
Date: Fri, 22 Nov 2019 12:19:06 +0100
Subject: [PATCH 21/44] Address review by Anders.
---
.../semmle/code/java/dataflow/NullGuards.qll | 25 ++++++-------------
.../semmle/code/java/dataflow/Nullness.qll | 11 ++++----
2 files changed, 12 insertions(+), 24 deletions(-)
diff --git a/java/ql/src/semmle/code/java/dataflow/NullGuards.qll b/java/ql/src/semmle/code/java/dataflow/NullGuards.qll
index f337d32cc8e..1ca4720ce18 100644
--- a/java/ql/src/semmle/code/java/dataflow/NullGuards.qll
+++ b/java/ql/src/semmle/code/java/dataflow/NullGuards.qll
@@ -25,30 +25,19 @@ Expr enumConstEquality(Expr e, boolean polarity, EnumConstant c) {
}
/** Gets an instanceof expression of `v` with type `type` */
-InstanceOfExpr instanceofExpr(SsaVariable v, Expr type) {
- result.getTypeName() = type and
+InstanceOfExpr instanceofExpr(SsaVariable v, Type type) {
+ result.getTypeName().getType() = type and
result.getExpr() = v.getAUse()
}
/**
- * Gets an expression of the form `v1` == `v2` or `v1` != `v2`.
+ * Gets an expression of the form `v1 == v2` or `v1 != v2`.
* The predicate is symmetric in `v1` and `v2`.
*/
-BinaryExpr varComparisonExpr(SsaVariable v1, SsaVariable v2, boolean isEqualExpr) {
- (
- result.getLeftOperand() = v1.getAUse() and
- result.getRightOperand() = v2.getAUse()
- or
- result.getLeftOperand() = v2.getAUse() and
- result.getRightOperand() = v1.getAUse()
- ) and
- (
- result instanceof EQExpr and
- isEqualExpr = true
- or
- result instanceof NEExpr and
- isEqualExpr = false
- )
+EqualityTest varEqualityTestExpr(SsaVariable v1, SsaVariable v2, boolean isEqualExpr) {
+ result.hasOperands(v1.getAUse(), v2.getAUse()) and
+ result instanceof EqualityTest and
+ isEqualExpr = result.polarity()
}
/** Gets an expression that is provably not `null`. */
diff --git a/java/ql/src/semmle/code/java/dataflow/Nullness.qll b/java/ql/src/semmle/code/java/dataflow/Nullness.qll
index 03d2dfac626..f6d92b78da7 100644
--- a/java/ql/src/semmle/code/java/dataflow/Nullness.qll
+++ b/java/ql/src/semmle/code/java/dataflow/Nullness.qll
@@ -516,16 +516,15 @@ private predicate correlatedConditions(
inverted = pol1.booleanXor(pol2)
)
or
- exists(SsaVariable v, Expr t1, Expr t2 |
- cond1.getCondition() = instanceofExpr(v, t1) and
- cond2.getCondition() = instanceofExpr(v, t2) and
- t1.getType() = t2.getType() and
+ exists(SsaVariable v, Type type |
+ cond1.getCondition() = instanceofExpr(v, type) and
+ cond2.getCondition() = instanceofExpr(v, type) and
inverted = false
)
or
exists(SsaVariable v1, SsaVariable v2, boolean branch1, boolean branch2 |
- cond1.getCondition() = varComparisonExpr(v1, v2, branch1) and
- cond2.getCondition() = varComparisonExpr(v1, v2, branch2) and
+ cond1.getCondition() = varEqualityTestExpr(v1, v2, branch1) and
+ cond2.getCondition() = varEqualityTestExpr(v1, v2, branch2) and
inverted = branch1.booleanXor(branch2)
)
)
From 7d825af9a3e3126f8463b876dc90c853d142f0b7 Mon Sep 17 00:00:00 2001
From: Erik Krogh Kristensen
Date: Thu, 21 Nov 2019 17:08:13 +0100
Subject: [PATCH 22/44] Added an XSS sink for Handlebars.SafeString
---
javascript/ql/src/javascript.qll | 1 +
.../javascript/frameworks/Handlebars.qll | 29 +++++++++++++++++++
.../javascript/security/dataflow/Xss.qll | 2 ++
.../query-tests/Security/CWE-079/Xss.expected | 5 ++++
.../test/query-tests/Security/CWE-079/tst.js | 4 +++
5 files changed, 41 insertions(+)
create mode 100644 javascript/ql/src/semmle/javascript/frameworks/Handlebars.qll
diff --git a/javascript/ql/src/javascript.qll b/javascript/ql/src/javascript.qll
index 9a183afffe5..08b305c159b 100644
--- a/javascript/ql/src/javascript.qll
+++ b/javascript/ql/src/javascript.qll
@@ -76,6 +76,7 @@ import semmle.javascript.frameworks.Electron
import semmle.javascript.frameworks.Files
import semmle.javascript.frameworks.Firebase
import semmle.javascript.frameworks.jQuery
+import semmle.javascript.frameworks.Handlebars
import semmle.javascript.frameworks.LodashUnderscore
import semmle.javascript.frameworks.Logging
import semmle.javascript.frameworks.HttpFrameworks
diff --git a/javascript/ql/src/semmle/javascript/frameworks/Handlebars.qll b/javascript/ql/src/semmle/javascript/frameworks/Handlebars.qll
new file mode 100644
index 00000000000..6879d4b7699
--- /dev/null
+++ b/javascript/ql/src/semmle/javascript/frameworks/Handlebars.qll
@@ -0,0 +1,29 @@
+/**
+ * Provides classes for working with Handlebars code.
+ */
+
+import javascript
+
+module Handlebars {
+ /**
+ * A reference to the Handlebars library.
+ */
+ class Handlebars extends DataFlow::SourceNode {
+ Handlebars() {
+ this.accessesGlobal("handlebars")
+ or
+ this.accessesGlobal("Handlebars")
+ or
+ this = DataFlow::moduleImport("handlebars")
+ or
+ this.hasUnderlyingType("Handlebars")
+ }
+ }
+
+ /**
+ * A new instantiation of a Handlebars.SafeString.
+ */
+ class SafeString extends DataFlow::NewNode {
+ SafeString() { this = any(Handlebars h).getAConstructorInvocation("SafeString") }
+ }
+}
diff --git a/javascript/ql/src/semmle/javascript/security/dataflow/Xss.qll b/javascript/ql/src/semmle/javascript/security/dataflow/Xss.qll
index 52c4a9b9332..76c4a29f971 100644
--- a/javascript/ql/src/semmle/javascript/security/dataflow/Xss.qll
+++ b/javascript/ql/src/semmle/javascript/security/dataflow/Xss.qll
@@ -95,6 +95,8 @@ module DomBasedXss {
mcn.getMethodName() = m and
this = mcn.getArgument(1)
)
+ or
+ this = any(Handlebars::SafeString s).getAnArgument()
}
}
diff --git a/javascript/ql/test/query-tests/Security/CWE-079/Xss.expected b/javascript/ql/test/query-tests/Security/CWE-079/Xss.expected
index f29d3e5de0f..2e986a06dea 100644
--- a/javascript/ql/test/query-tests/Security/CWE-079/Xss.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-079/Xss.expected
@@ -315,6 +315,9 @@ nodes
| tst.js:285:59:285:65 | tainted |
| tst.js:285:59:285:65 | tainted |
| tst.js:285:59:285:65 | tainted |
+| tst.js:297:35:297:42 | location |
+| tst.js:297:35:297:42 | location |
+| tst.js:297:35:297:42 | location |
| v-html.vue:2:8:2:23 | v-html=tainted |
| v-html.vue:2:8:2:23 | v-html=tainted |
| v-html.vue:6:42:6:58 | document.location |
@@ -604,6 +607,7 @@ edges
| tst.js:282:19:282:29 | window.name | tst.js:282:9:282:29 | tainted |
| tst.js:282:19:282:29 | window.name | tst.js:282:9:282:29 | tainted |
| tst.js:285:59:285:65 | tainted | tst.js:285:59:285:65 | tainted |
+| tst.js:297:35:297:42 | location | tst.js:297:35:297:42 | location |
| v-html.vue:6:42:6:58 | document.location | v-html.vue:2:8:2:23 | v-html=tainted |
| v-html.vue:6:42:6:58 | document.location | v-html.vue:2:8:2:23 | v-html=tainted |
| v-html.vue:6:42:6:58 | document.location | v-html.vue:2:8:2:23 | v-html=tainted |
@@ -693,6 +697,7 @@ edges
| tst.js:285:59:285:65 | tainted | tst.js:282:9:282:29 | tainted | tst.js:285:59:285:65 | tainted | Cross-site scripting vulnerability due to $@. | tst.js:282:9:282:29 | tainted | user-provided value |
| tst.js:285:59:285:65 | tainted | tst.js:282:19:282:29 | window.name | tst.js:285:59:285:65 | tainted | Cross-site scripting vulnerability due to $@. | tst.js:282:19:282:29 | window.name | user-provided value |
| tst.js:285:59:285:65 | tainted | tst.js:285:59:285:65 | tainted | tst.js:285:59:285:65 | tainted | Cross-site scripting vulnerability due to $@. | tst.js:285:59:285:65 | tainted | user-provided value |
+| tst.js:297:35:297:42 | location | tst.js:297:35:297:42 | location | tst.js:297:35:297:42 | location | Cross-site scripting vulnerability due to $@. | tst.js:297:35:297:42 | location | user-provided value |
| v-html.vue:2:8:2:23 | v-html=tainted | v-html.vue:6:42:6:58 | document.location | v-html.vue:2:8:2:23 | v-html=tainted | Cross-site scripting vulnerability due to $@. | v-html.vue:6:42:6:58 | document.location | user-provided value |
| winjs.js:3:43:3:49 | tainted | winjs.js:2:17:2:33 | document.location | winjs.js:3:43:3:49 | tainted | Cross-site scripting vulnerability due to $@. | winjs.js:2:17:2:33 | document.location | user-provided value |
| winjs.js:4:43:4:49 | tainted | winjs.js:2:17:2:33 | document.location | winjs.js:4:43:4:49 | tainted | Cross-site scripting vulnerability due to $@. | winjs.js:2:17:2:33 | document.location | user-provided value |
diff --git a/javascript/ql/test/query-tests/Security/CWE-079/tst.js b/javascript/ql/test/query-tests/Security/CWE-079/tst.js
index 53840d61240..780d56e90e1 100644
--- a/javascript/ql/test/query-tests/Security/CWE-079/tst.js
+++ b/javascript/ql/test/query-tests/Security/CWE-079/tst.js
@@ -292,3 +292,7 @@ function flowThroughPropertyNames() {
for (var p in obj)
$(p); // OK
}
+
+function handlebarsSafeString() {
+ return new Handlebars.SafeString(location); // NOT OK!
+}
From 9fc20cd9b0bc6999ca18bf97fee81fce4ab94102 Mon Sep 17 00:00:00 2001
From: Erik Krogh Kristensen
Date: Fri, 22 Nov 2019 15:58:00 +0100
Subject: [PATCH 23/44] add change note
---
change-notes/1.24/analysis-javascript.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/change-notes/1.24/analysis-javascript.md b/change-notes/1.24/analysis-javascript.md
index 53400f537ce..fbe7fd00899 100644
--- a/change-notes/1.24/analysis-javascript.md
+++ b/change-notes/1.24/analysis-javascript.md
@@ -4,6 +4,7 @@
* Support for the following frameworks and libraries has been improved:
- [react](https://www.npmjs.com/package/react)
+ - [Handlebars](https://www.npmjs.com/package/handlebars)
## New queries
From bbe6a1aa76756c2541ccb1e6e5c15fbc71224489 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Fri, 22 Nov 2019 15:01:04 +0000
Subject: [PATCH 24/44] CPP: Additional test case.
---
.../semmle/NoSpaceForZeroTerminator/test2.cpp | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test2.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test2.cpp
index 5fad5db1142..ec71fa5fa57 100644
--- a/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test2.cpp
+++ b/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test2.cpp
@@ -14,13 +14,16 @@ namespace std
template class allocator {
public:
allocator() throw();
+ typedef size_t size_type;
};
template, class Allocator = allocator >
class basic_string {
public:
+ typedef typename Allocator::size_type size_type;
explicit basic_string(const Allocator& a = Allocator());
basic_string(const charT* s, const Allocator& a = Allocator());
+ basic_string(const charT* s, size_type n, const Allocator& a = Allocator());
const charT* c_str() const;
};
@@ -36,3 +39,12 @@ void bad1(char *str) {
std::string str2(buffer);
free(buffer);
}
+
+void good1(char *str) {
+ // GOOD --- copy does not overrun due to size limit
+ char *buffer = (char *)malloc(strlen(str));
+ std::string str2(buffer, strlen(str));
+ free(buffer);
+}
+
+
From d6cbc674b6f372592248d063c00f1479975245e1 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Fri, 22 Nov 2019 15:02:40 +0000
Subject: [PATCH 25/44] CPP: Autoformat.
---
.../src/Security/CWE/CWE-131/NoSpaceForZeroTerminator.ql | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/cpp/ql/src/Security/CWE/CWE-131/NoSpaceForZeroTerminator.ql b/cpp/ql/src/Security/CWE/CWE-131/NoSpaceForZeroTerminator.ql
index ef983af4cb2..5ed0f1bd679 100644
--- a/cpp/ql/src/Security/CWE/CWE-131/NoSpaceForZeroTerminator.ql
+++ b/cpp/ql/src/Security/CWE/CWE-131/NoSpaceForZeroTerminator.ql
@@ -21,16 +21,12 @@ import semmle.code.cpp.models.interfaces.ArrayFunction
class MallocCall extends FunctionCall {
MallocCall() { this.getTarget().hasGlobalOrStdName("malloc") }
- Expr getAllocatedSize() {
- result = this.getArgument(0)
- }
+ Expr getAllocatedSize() { result = this.getArgument(0) }
}
predicate terminationProblem(MallocCall malloc, string msg) {
// malloc(strlen(...))
- exists(StrlenCall strlen |
- DataFlow::localExprFlow(strlen, malloc.getAllocatedSize())
- ) and
+ exists(StrlenCall strlen | DataFlow::localExprFlow(strlen, malloc.getAllocatedSize())) and
// flows into a null-terminated string function
exists(ArrayFunction af, FunctionCall fc, int arg |
DataFlow::localExprFlow(malloc, fc.getArgument(arg)) and
From 12daa76b7052962a26825b0ad402e5337f5f0a34 Mon Sep 17 00:00:00 2001
From: Dave Bartolomeo
Date: Wed, 14 Aug 2019 13:48:34 -0700
Subject: [PATCH 26/44] C++: Make `duplicateOperand` query report function name
---
.../aliased_ssa/Instruction.qll | 20 +++++++++++++------
.../cpp/ir/implementation/raw/Instruction.qll | 20 +++++++++++++------
.../unaliased_ssa/Instruction.qll | 20 +++++++++++++------
.../ir/implementation/raw/Instruction.qll | 20 +++++++++++++------
.../unaliased_ssa/Instruction.qll | 20 +++++++++++++------
5 files changed, 70 insertions(+), 30 deletions(-)
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll
index e3c78f476e9..bfd04a279e0 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll
@@ -94,12 +94,20 @@ module InstructionSanity {
/**
* Holds if instruction `instr` has multiple operands with tag `tag`.
*/
- query predicate duplicateOperand(Instruction instr, OperandTag tag) {
- strictcount(NonPhiOperand operand |
- operand = instr.getAnOperand() and
- operand.getOperandTag() = tag
- ) > 1 and
- not tag instanceof UnmodeledUseOperandTag
+ query predicate duplicateOperand(Instruction instr, string message, IRFunction func,
+ string funcText) {
+ exists(OperandTag tag, int operandCount |
+ operandCount = strictcount(NonPhiOperand operand |
+ operand = instr.getAnOperand() and
+ operand.getOperandTag() = tag
+ ) and
+ operandCount > 1 and
+ not tag instanceof UnmodeledUseOperandTag and
+ message = "Instruction has " + operandCount + " operands with tag '" + tag.toString() + "'" +
+ " in function '$@'." and
+ func = instr.getEnclosingIRFunction() and
+ funcText = Language::getIdentityString(func.getFunction())
+ )
}
/**
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll
index e3c78f476e9..bfd04a279e0 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll
@@ -94,12 +94,20 @@ module InstructionSanity {
/**
* Holds if instruction `instr` has multiple operands with tag `tag`.
*/
- query predicate duplicateOperand(Instruction instr, OperandTag tag) {
- strictcount(NonPhiOperand operand |
- operand = instr.getAnOperand() and
- operand.getOperandTag() = tag
- ) > 1 and
- not tag instanceof UnmodeledUseOperandTag
+ query predicate duplicateOperand(Instruction instr, string message, IRFunction func,
+ string funcText) {
+ exists(OperandTag tag, int operandCount |
+ operandCount = strictcount(NonPhiOperand operand |
+ operand = instr.getAnOperand() and
+ operand.getOperandTag() = tag
+ ) and
+ operandCount > 1 and
+ not tag instanceof UnmodeledUseOperandTag and
+ message = "Instruction has " + operandCount + " operands with tag '" + tag.toString() + "'" +
+ " in function '$@'." and
+ func = instr.getEnclosingIRFunction() and
+ funcText = Language::getIdentityString(func.getFunction())
+ )
}
/**
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll
index e3c78f476e9..bfd04a279e0 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll
@@ -94,12 +94,20 @@ module InstructionSanity {
/**
* Holds if instruction `instr` has multiple operands with tag `tag`.
*/
- query predicate duplicateOperand(Instruction instr, OperandTag tag) {
- strictcount(NonPhiOperand operand |
- operand = instr.getAnOperand() and
- operand.getOperandTag() = tag
- ) > 1 and
- not tag instanceof UnmodeledUseOperandTag
+ query predicate duplicateOperand(Instruction instr, string message, IRFunction func,
+ string funcText) {
+ exists(OperandTag tag, int operandCount |
+ operandCount = strictcount(NonPhiOperand operand |
+ operand = instr.getAnOperand() and
+ operand.getOperandTag() = tag
+ ) and
+ operandCount > 1 and
+ not tag instanceof UnmodeledUseOperandTag and
+ message = "Instruction has " + operandCount + " operands with tag '" + tag.toString() + "'" +
+ " in function '$@'." and
+ func = instr.getEnclosingIRFunction() and
+ funcText = Language::getIdentityString(func.getFunction())
+ )
}
/**
diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Instruction.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Instruction.qll
index e3c78f476e9..bfd04a279e0 100644
--- a/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Instruction.qll
+++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Instruction.qll
@@ -94,12 +94,20 @@ module InstructionSanity {
/**
* Holds if instruction `instr` has multiple operands with tag `tag`.
*/
- query predicate duplicateOperand(Instruction instr, OperandTag tag) {
- strictcount(NonPhiOperand operand |
- operand = instr.getAnOperand() and
- operand.getOperandTag() = tag
- ) > 1 and
- not tag instanceof UnmodeledUseOperandTag
+ query predicate duplicateOperand(Instruction instr, string message, IRFunction func,
+ string funcText) {
+ exists(OperandTag tag, int operandCount |
+ operandCount = strictcount(NonPhiOperand operand |
+ operand = instr.getAnOperand() and
+ operand.getOperandTag() = tag
+ ) and
+ operandCount > 1 and
+ not tag instanceof UnmodeledUseOperandTag and
+ message = "Instruction has " + operandCount + " operands with tag '" + tag.toString() + "'" +
+ " in function '$@'." and
+ func = instr.getEnclosingIRFunction() and
+ funcText = Language::getIdentityString(func.getFunction())
+ )
}
/**
diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Instruction.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Instruction.qll
index e3c78f476e9..bfd04a279e0 100644
--- a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Instruction.qll
+++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Instruction.qll
@@ -94,12 +94,20 @@ module InstructionSanity {
/**
* Holds if instruction `instr` has multiple operands with tag `tag`.
*/
- query predicate duplicateOperand(Instruction instr, OperandTag tag) {
- strictcount(NonPhiOperand operand |
- operand = instr.getAnOperand() and
- operand.getOperandTag() = tag
- ) > 1 and
- not tag instanceof UnmodeledUseOperandTag
+ query predicate duplicateOperand(Instruction instr, string message, IRFunction func,
+ string funcText) {
+ exists(OperandTag tag, int operandCount |
+ operandCount = strictcount(NonPhiOperand operand |
+ operand = instr.getAnOperand() and
+ operand.getOperandTag() = tag
+ ) and
+ operandCount > 1 and
+ not tag instanceof UnmodeledUseOperandTag and
+ message = "Instruction has " + operandCount + " operands with tag '" + tag.toString() + "'" +
+ " in function '$@'." and
+ func = instr.getEnclosingIRFunction() and
+ funcText = Language::getIdentityString(func.getFunction())
+ )
}
/**
From bc48c25690f98945ad6470c69877650809d6e63c Mon Sep 17 00:00:00 2001
From: Dave Bartolomeo
Date: Fri, 22 Nov 2019 12:13:39 -0700
Subject: [PATCH 27/44] C++/C#: Make `IRVariable` and its derived classes
non-abstract
---
.../implementation/aliased_ssa/IRVariable.qll | 63 ++++++++++++++++---
.../cpp/ir/implementation/raw/IRVariable.qll | 63 ++++++++++++++++---
.../unaliased_ssa/IRVariable.qll | 63 ++++++++++++++++---
.../ir/implementation/raw/IRVariable.qll | 63 ++++++++++++++++---
.../unaliased_ssa/IRVariable.qll | 63 ++++++++++++++++---
5 files changed, 270 insertions(+), 45 deletions(-)
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll
index e10e266b2ab..349ff7cd6bd 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll
@@ -17,10 +17,16 @@ IRUserVariable getIRUserVariable(Language::Function func, Language::Variable var
* be a user-declared variable (`IRUserVariable`) or a temporary variable
* generated by the AST-to-IR translation (`IRTempVariable`).
*/
-abstract class IRVariable extends TIRVariable {
+class IRVariable extends TIRVariable {
Language::Function func;
- abstract string toString();
+ IRVariable() {
+ this = TIRUserVariable(_, _, func) or
+ this = TIRTempVariable(func, _, _, _) or
+ this = TIRStringLiteral(func, _, _, _)
+ }
+
+ string toString() { none() }
/**
* Holds if this variable's value cannot be changed within a function. Currently used for string
@@ -41,19 +47,19 @@ abstract class IRVariable extends TIRVariable {
/**
* Gets the type of the variable.
*/
- abstract Language::LanguageType getLanguageType();
+ Language::LanguageType getLanguageType() { none() }
/**
* Gets the AST node that declared this variable, or that introduced this
* variable as part of the AST-to-IR translation.
*/
- abstract Language::AST getAST();
+ Language::AST getAST() { none() }
/**
* Gets an identifier string for the variable. This identifier is unique
* within the function.
*/
- abstract string getUniqueId();
+ string getUniqueId() { none() }
/**
* Gets the source location of this variable.
@@ -101,16 +107,31 @@ class IRUserVariable extends IRVariable, TIRUserVariable {
* stack. This includes all parameters, non-static local variables, and
* temporary variables.
*/
-abstract class IRAutomaticVariable extends IRVariable { }
+class IRAutomaticVariable extends IRVariable {
+ IRAutomaticVariable() {
+ exists(Language::Variable var |
+ this = TIRUserVariable(var, _, func) and
+ Language::isVariableAutomatic(var)
+ ) or
+ this = TIRTempVariable(func, _, _, _)
+ }
+}
+/**
+ * Represents a user-declared variable that is allocated on the stack. This
+ * includes all parameters and non-static local variables.
+ */
class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable {
override Language::AutomaticVariable var;
- IRAutomaticUserVariable() { Language::isVariableAutomatic(var) }
-
final override Language::AutomaticVariable getVariable() { result = var }
}
+/**
+ * Represents a user-declared variable that is not allocated on the stack. This
+ * includes all global variables, namespace-scope variables, static fields, and
+ * static local variables.
+ */
class IRStaticUserVariable extends IRUserVariable {
override Language::StaticVariable var;
@@ -119,10 +140,19 @@ class IRStaticUserVariable extends IRUserVariable {
final override Language::StaticVariable getVariable() { result = var }
}
-abstract class IRGeneratedVariable extends IRVariable {
+/**
+ * Represents a variable that is not user-declared. This includes temporary
+ * variables generated as part of IR construction, as well as string literals.
+ */
+class IRGeneratedVariable extends IRVariable {
Language::AST ast;
Language::LanguageType type;
+ IRGeneratedVariable() {
+ this = TIRTempVariable(func, ast, _, type) or
+ this = TIRStringLiteral(func, ast, type, _)
+ }
+
final override Language::LanguageType getLanguageType() { result = type }
final override Language::AST getAST() { result = ast }
@@ -144,6 +174,11 @@ IRTempVariable getIRTempVariable(Language::AST ast, TempVariableTag tag) {
result.getTag() = tag
}
+/**
+ * Represents a temporary variable introduced by IR construction. The most common examples are the
+ * variable generated to hold the return value of afunction, or the variable generated to hold the
+ * result of a condition operator (`a ? b : c`).
+ */
class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVariable {
TempVariableTag tag;
@@ -158,18 +193,28 @@ class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVa
override string getBaseString() { result = "#temp" }
}
+/**
+ * The temporary variable generated to hold the return value of a function.
+ */
class IRReturnVariable extends IRTempVariable {
IRReturnVariable() { tag = ReturnValueTempVar() }
final override string toString() { result = "#return" }
}
+/**
+ * The temporary variable generated to hold the exception thrown by a `ThrowValue` instruction.
+ */
class IRThrowVariable extends IRTempVariable {
IRThrowVariable() { tag = ThrowTempVar() }
override string getBaseString() { result = "#throw" }
}
+/**
+ * The variable generated to represent the contents of a string literal. This variable acts much
+ * like a read-only global variable.
+ */
class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral {
Language::StringLiteral literal;
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRVariable.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRVariable.qll
index e10e266b2ab..349ff7cd6bd 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRVariable.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRVariable.qll
@@ -17,10 +17,16 @@ IRUserVariable getIRUserVariable(Language::Function func, Language::Variable var
* be a user-declared variable (`IRUserVariable`) or a temporary variable
* generated by the AST-to-IR translation (`IRTempVariable`).
*/
-abstract class IRVariable extends TIRVariable {
+class IRVariable extends TIRVariable {
Language::Function func;
- abstract string toString();
+ IRVariable() {
+ this = TIRUserVariable(_, _, func) or
+ this = TIRTempVariable(func, _, _, _) or
+ this = TIRStringLiteral(func, _, _, _)
+ }
+
+ string toString() { none() }
/**
* Holds if this variable's value cannot be changed within a function. Currently used for string
@@ -41,19 +47,19 @@ abstract class IRVariable extends TIRVariable {
/**
* Gets the type of the variable.
*/
- abstract Language::LanguageType getLanguageType();
+ Language::LanguageType getLanguageType() { none() }
/**
* Gets the AST node that declared this variable, or that introduced this
* variable as part of the AST-to-IR translation.
*/
- abstract Language::AST getAST();
+ Language::AST getAST() { none() }
/**
* Gets an identifier string for the variable. This identifier is unique
* within the function.
*/
- abstract string getUniqueId();
+ string getUniqueId() { none() }
/**
* Gets the source location of this variable.
@@ -101,16 +107,31 @@ class IRUserVariable extends IRVariable, TIRUserVariable {
* stack. This includes all parameters, non-static local variables, and
* temporary variables.
*/
-abstract class IRAutomaticVariable extends IRVariable { }
+class IRAutomaticVariable extends IRVariable {
+ IRAutomaticVariable() {
+ exists(Language::Variable var |
+ this = TIRUserVariable(var, _, func) and
+ Language::isVariableAutomatic(var)
+ ) or
+ this = TIRTempVariable(func, _, _, _)
+ }
+}
+/**
+ * Represents a user-declared variable that is allocated on the stack. This
+ * includes all parameters and non-static local variables.
+ */
class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable {
override Language::AutomaticVariable var;
- IRAutomaticUserVariable() { Language::isVariableAutomatic(var) }
-
final override Language::AutomaticVariable getVariable() { result = var }
}
+/**
+ * Represents a user-declared variable that is not allocated on the stack. This
+ * includes all global variables, namespace-scope variables, static fields, and
+ * static local variables.
+ */
class IRStaticUserVariable extends IRUserVariable {
override Language::StaticVariable var;
@@ -119,10 +140,19 @@ class IRStaticUserVariable extends IRUserVariable {
final override Language::StaticVariable getVariable() { result = var }
}
-abstract class IRGeneratedVariable extends IRVariable {
+/**
+ * Represents a variable that is not user-declared. This includes temporary
+ * variables generated as part of IR construction, as well as string literals.
+ */
+class IRGeneratedVariable extends IRVariable {
Language::AST ast;
Language::LanguageType type;
+ IRGeneratedVariable() {
+ this = TIRTempVariable(func, ast, _, type) or
+ this = TIRStringLiteral(func, ast, type, _)
+ }
+
final override Language::LanguageType getLanguageType() { result = type }
final override Language::AST getAST() { result = ast }
@@ -144,6 +174,11 @@ IRTempVariable getIRTempVariable(Language::AST ast, TempVariableTag tag) {
result.getTag() = tag
}
+/**
+ * Represents a temporary variable introduced by IR construction. The most common examples are the
+ * variable generated to hold the return value of afunction, or the variable generated to hold the
+ * result of a condition operator (`a ? b : c`).
+ */
class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVariable {
TempVariableTag tag;
@@ -158,18 +193,28 @@ class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVa
override string getBaseString() { result = "#temp" }
}
+/**
+ * The temporary variable generated to hold the return value of a function.
+ */
class IRReturnVariable extends IRTempVariable {
IRReturnVariable() { tag = ReturnValueTempVar() }
final override string toString() { result = "#return" }
}
+/**
+ * The temporary variable generated to hold the exception thrown by a `ThrowValue` instruction.
+ */
class IRThrowVariable extends IRTempVariable {
IRThrowVariable() { tag = ThrowTempVar() }
override string getBaseString() { result = "#throw" }
}
+/**
+ * The variable generated to represent the contents of a string literal. This variable acts much
+ * like a read-only global variable.
+ */
class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral {
Language::StringLiteral literal;
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll
index e10e266b2ab..349ff7cd6bd 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll
@@ -17,10 +17,16 @@ IRUserVariable getIRUserVariable(Language::Function func, Language::Variable var
* be a user-declared variable (`IRUserVariable`) or a temporary variable
* generated by the AST-to-IR translation (`IRTempVariable`).
*/
-abstract class IRVariable extends TIRVariable {
+class IRVariable extends TIRVariable {
Language::Function func;
- abstract string toString();
+ IRVariable() {
+ this = TIRUserVariable(_, _, func) or
+ this = TIRTempVariable(func, _, _, _) or
+ this = TIRStringLiteral(func, _, _, _)
+ }
+
+ string toString() { none() }
/**
* Holds if this variable's value cannot be changed within a function. Currently used for string
@@ -41,19 +47,19 @@ abstract class IRVariable extends TIRVariable {
/**
* Gets the type of the variable.
*/
- abstract Language::LanguageType getLanguageType();
+ Language::LanguageType getLanguageType() { none() }
/**
* Gets the AST node that declared this variable, or that introduced this
* variable as part of the AST-to-IR translation.
*/
- abstract Language::AST getAST();
+ Language::AST getAST() { none() }
/**
* Gets an identifier string for the variable. This identifier is unique
* within the function.
*/
- abstract string getUniqueId();
+ string getUniqueId() { none() }
/**
* Gets the source location of this variable.
@@ -101,16 +107,31 @@ class IRUserVariable extends IRVariable, TIRUserVariable {
* stack. This includes all parameters, non-static local variables, and
* temporary variables.
*/
-abstract class IRAutomaticVariable extends IRVariable { }
+class IRAutomaticVariable extends IRVariable {
+ IRAutomaticVariable() {
+ exists(Language::Variable var |
+ this = TIRUserVariable(var, _, func) and
+ Language::isVariableAutomatic(var)
+ ) or
+ this = TIRTempVariable(func, _, _, _)
+ }
+}
+/**
+ * Represents a user-declared variable that is allocated on the stack. This
+ * includes all parameters and non-static local variables.
+ */
class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable {
override Language::AutomaticVariable var;
- IRAutomaticUserVariable() { Language::isVariableAutomatic(var) }
-
final override Language::AutomaticVariable getVariable() { result = var }
}
+/**
+ * Represents a user-declared variable that is not allocated on the stack. This
+ * includes all global variables, namespace-scope variables, static fields, and
+ * static local variables.
+ */
class IRStaticUserVariable extends IRUserVariable {
override Language::StaticVariable var;
@@ -119,10 +140,19 @@ class IRStaticUserVariable extends IRUserVariable {
final override Language::StaticVariable getVariable() { result = var }
}
-abstract class IRGeneratedVariable extends IRVariable {
+/**
+ * Represents a variable that is not user-declared. This includes temporary
+ * variables generated as part of IR construction, as well as string literals.
+ */
+class IRGeneratedVariable extends IRVariable {
Language::AST ast;
Language::LanguageType type;
+ IRGeneratedVariable() {
+ this = TIRTempVariable(func, ast, _, type) or
+ this = TIRStringLiteral(func, ast, type, _)
+ }
+
final override Language::LanguageType getLanguageType() { result = type }
final override Language::AST getAST() { result = ast }
@@ -144,6 +174,11 @@ IRTempVariable getIRTempVariable(Language::AST ast, TempVariableTag tag) {
result.getTag() = tag
}
+/**
+ * Represents a temporary variable introduced by IR construction. The most common examples are the
+ * variable generated to hold the return value of afunction, or the variable generated to hold the
+ * result of a condition operator (`a ? b : c`).
+ */
class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVariable {
TempVariableTag tag;
@@ -158,18 +193,28 @@ class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVa
override string getBaseString() { result = "#temp" }
}
+/**
+ * The temporary variable generated to hold the return value of a function.
+ */
class IRReturnVariable extends IRTempVariable {
IRReturnVariable() { tag = ReturnValueTempVar() }
final override string toString() { result = "#return" }
}
+/**
+ * The temporary variable generated to hold the exception thrown by a `ThrowValue` instruction.
+ */
class IRThrowVariable extends IRTempVariable {
IRThrowVariable() { tag = ThrowTempVar() }
override string getBaseString() { result = "#throw" }
}
+/**
+ * The variable generated to represent the contents of a string literal. This variable acts much
+ * like a read-only global variable.
+ */
class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral {
Language::StringLiteral literal;
diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/IRVariable.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/IRVariable.qll
index e10e266b2ab..349ff7cd6bd 100644
--- a/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/IRVariable.qll
+++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/IRVariable.qll
@@ -17,10 +17,16 @@ IRUserVariable getIRUserVariable(Language::Function func, Language::Variable var
* be a user-declared variable (`IRUserVariable`) or a temporary variable
* generated by the AST-to-IR translation (`IRTempVariable`).
*/
-abstract class IRVariable extends TIRVariable {
+class IRVariable extends TIRVariable {
Language::Function func;
- abstract string toString();
+ IRVariable() {
+ this = TIRUserVariable(_, _, func) or
+ this = TIRTempVariable(func, _, _, _) or
+ this = TIRStringLiteral(func, _, _, _)
+ }
+
+ string toString() { none() }
/**
* Holds if this variable's value cannot be changed within a function. Currently used for string
@@ -41,19 +47,19 @@ abstract class IRVariable extends TIRVariable {
/**
* Gets the type of the variable.
*/
- abstract Language::LanguageType getLanguageType();
+ Language::LanguageType getLanguageType() { none() }
/**
* Gets the AST node that declared this variable, or that introduced this
* variable as part of the AST-to-IR translation.
*/
- abstract Language::AST getAST();
+ Language::AST getAST() { none() }
/**
* Gets an identifier string for the variable. This identifier is unique
* within the function.
*/
- abstract string getUniqueId();
+ string getUniqueId() { none() }
/**
* Gets the source location of this variable.
@@ -101,16 +107,31 @@ class IRUserVariable extends IRVariable, TIRUserVariable {
* stack. This includes all parameters, non-static local variables, and
* temporary variables.
*/
-abstract class IRAutomaticVariable extends IRVariable { }
+class IRAutomaticVariable extends IRVariable {
+ IRAutomaticVariable() {
+ exists(Language::Variable var |
+ this = TIRUserVariable(var, _, func) and
+ Language::isVariableAutomatic(var)
+ ) or
+ this = TIRTempVariable(func, _, _, _)
+ }
+}
+/**
+ * Represents a user-declared variable that is allocated on the stack. This
+ * includes all parameters and non-static local variables.
+ */
class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable {
override Language::AutomaticVariable var;
- IRAutomaticUserVariable() { Language::isVariableAutomatic(var) }
-
final override Language::AutomaticVariable getVariable() { result = var }
}
+/**
+ * Represents a user-declared variable that is not allocated on the stack. This
+ * includes all global variables, namespace-scope variables, static fields, and
+ * static local variables.
+ */
class IRStaticUserVariable extends IRUserVariable {
override Language::StaticVariable var;
@@ -119,10 +140,19 @@ class IRStaticUserVariable extends IRUserVariable {
final override Language::StaticVariable getVariable() { result = var }
}
-abstract class IRGeneratedVariable extends IRVariable {
+/**
+ * Represents a variable that is not user-declared. This includes temporary
+ * variables generated as part of IR construction, as well as string literals.
+ */
+class IRGeneratedVariable extends IRVariable {
Language::AST ast;
Language::LanguageType type;
+ IRGeneratedVariable() {
+ this = TIRTempVariable(func, ast, _, type) or
+ this = TIRStringLiteral(func, ast, type, _)
+ }
+
final override Language::LanguageType getLanguageType() { result = type }
final override Language::AST getAST() { result = ast }
@@ -144,6 +174,11 @@ IRTempVariable getIRTempVariable(Language::AST ast, TempVariableTag tag) {
result.getTag() = tag
}
+/**
+ * Represents a temporary variable introduced by IR construction. The most common examples are the
+ * variable generated to hold the return value of afunction, or the variable generated to hold the
+ * result of a condition operator (`a ? b : c`).
+ */
class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVariable {
TempVariableTag tag;
@@ -158,18 +193,28 @@ class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVa
override string getBaseString() { result = "#temp" }
}
+/**
+ * The temporary variable generated to hold the return value of a function.
+ */
class IRReturnVariable extends IRTempVariable {
IRReturnVariable() { tag = ReturnValueTempVar() }
final override string toString() { result = "#return" }
}
+/**
+ * The temporary variable generated to hold the exception thrown by a `ThrowValue` instruction.
+ */
class IRThrowVariable extends IRTempVariable {
IRThrowVariable() { tag = ThrowTempVar() }
override string getBaseString() { result = "#throw" }
}
+/**
+ * The variable generated to represent the contents of a string literal. This variable acts much
+ * like a read-only global variable.
+ */
class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral {
Language::StringLiteral literal;
diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/IRVariable.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/IRVariable.qll
index e10e266b2ab..349ff7cd6bd 100644
--- a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/IRVariable.qll
+++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/IRVariable.qll
@@ -17,10 +17,16 @@ IRUserVariable getIRUserVariable(Language::Function func, Language::Variable var
* be a user-declared variable (`IRUserVariable`) or a temporary variable
* generated by the AST-to-IR translation (`IRTempVariable`).
*/
-abstract class IRVariable extends TIRVariable {
+class IRVariable extends TIRVariable {
Language::Function func;
- abstract string toString();
+ IRVariable() {
+ this = TIRUserVariable(_, _, func) or
+ this = TIRTempVariable(func, _, _, _) or
+ this = TIRStringLiteral(func, _, _, _)
+ }
+
+ string toString() { none() }
/**
* Holds if this variable's value cannot be changed within a function. Currently used for string
@@ -41,19 +47,19 @@ abstract class IRVariable extends TIRVariable {
/**
* Gets the type of the variable.
*/
- abstract Language::LanguageType getLanguageType();
+ Language::LanguageType getLanguageType() { none() }
/**
* Gets the AST node that declared this variable, or that introduced this
* variable as part of the AST-to-IR translation.
*/
- abstract Language::AST getAST();
+ Language::AST getAST() { none() }
/**
* Gets an identifier string for the variable. This identifier is unique
* within the function.
*/
- abstract string getUniqueId();
+ string getUniqueId() { none() }
/**
* Gets the source location of this variable.
@@ -101,16 +107,31 @@ class IRUserVariable extends IRVariable, TIRUserVariable {
* stack. This includes all parameters, non-static local variables, and
* temporary variables.
*/
-abstract class IRAutomaticVariable extends IRVariable { }
+class IRAutomaticVariable extends IRVariable {
+ IRAutomaticVariable() {
+ exists(Language::Variable var |
+ this = TIRUserVariable(var, _, func) and
+ Language::isVariableAutomatic(var)
+ ) or
+ this = TIRTempVariable(func, _, _, _)
+ }
+}
+/**
+ * Represents a user-declared variable that is allocated on the stack. This
+ * includes all parameters and non-static local variables.
+ */
class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable {
override Language::AutomaticVariable var;
- IRAutomaticUserVariable() { Language::isVariableAutomatic(var) }
-
final override Language::AutomaticVariable getVariable() { result = var }
}
+/**
+ * Represents a user-declared variable that is not allocated on the stack. This
+ * includes all global variables, namespace-scope variables, static fields, and
+ * static local variables.
+ */
class IRStaticUserVariable extends IRUserVariable {
override Language::StaticVariable var;
@@ -119,10 +140,19 @@ class IRStaticUserVariable extends IRUserVariable {
final override Language::StaticVariable getVariable() { result = var }
}
-abstract class IRGeneratedVariable extends IRVariable {
+/**
+ * Represents a variable that is not user-declared. This includes temporary
+ * variables generated as part of IR construction, as well as string literals.
+ */
+class IRGeneratedVariable extends IRVariable {
Language::AST ast;
Language::LanguageType type;
+ IRGeneratedVariable() {
+ this = TIRTempVariable(func, ast, _, type) or
+ this = TIRStringLiteral(func, ast, type, _)
+ }
+
final override Language::LanguageType getLanguageType() { result = type }
final override Language::AST getAST() { result = ast }
@@ -144,6 +174,11 @@ IRTempVariable getIRTempVariable(Language::AST ast, TempVariableTag tag) {
result.getTag() = tag
}
+/**
+ * Represents a temporary variable introduced by IR construction. The most common examples are the
+ * variable generated to hold the return value of afunction, or the variable generated to hold the
+ * result of a condition operator (`a ? b : c`).
+ */
class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVariable {
TempVariableTag tag;
@@ -158,18 +193,28 @@ class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVa
override string getBaseString() { result = "#temp" }
}
+/**
+ * The temporary variable generated to hold the return value of a function.
+ */
class IRReturnVariable extends IRTempVariable {
IRReturnVariable() { tag = ReturnValueTempVar() }
final override string toString() { result = "#return" }
}
+/**
+ * The temporary variable generated to hold the exception thrown by a `ThrowValue` instruction.
+ */
class IRThrowVariable extends IRTempVariable {
IRThrowVariable() { tag = ThrowTempVar() }
override string getBaseString() { result = "#throw" }
}
+/**
+ * The variable generated to represent the contents of a string literal. This variable acts much
+ * like a read-only global variable.
+ */
class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral {
Language::StringLiteral literal;
From 51ff262cbc6fee9fab7a7186416649bb5b15e4ee Mon Sep 17 00:00:00 2001
From: Dave Bartolomeo
Date: Wed, 14 Aug 2019 13:53:48 -0700
Subject: [PATCH 28/44] C++/C#: Add IR SSA sanity tests
---
config/identical-files.json | 5 +++++
.../aliased_ssa/internal/SSAConstruction.qll | 13 +++++++++++++
.../aliased_ssa/internal/SSASanity.ql | 8 ++++++++
.../aliased_ssa/internal/SSASanity.qll | 2 ++
.../unaliased_ssa/internal/SSAConstruction.qll | 13 +++++++++++++
.../unaliased_ssa/internal/SSASanity.ql | 8 ++++++++
.../unaliased_ssa/internal/SSASanity.qll | 2 ++
.../ir/ssa/aliased_ssa_ssa_sanity.expected | 0
.../ir/ssa/aliased_ssa_ssa_sanity.qlref | 1 +
.../ir/ssa/unaliased_ssa_ssa_sanity.expected | 0
.../ir/ssa/unaliased_ssa_ssa_sanity.qlref | 1 +
.../unaliased_ssa/internal/SSAConstruction.qll | 13 +++++++++++++
.../unaliased_ssa/internal/SSASanity.ql | 8 ++++++++
.../unaliased_ssa/internal/SSASanity.qll | 2 ++
.../ir/ir/unaliased_ssa_ssa_sanity.expected | 0
.../ir/ir/unaliased_ssa_ssa_sanity.qlref | 1 +
16 files changed, 77 insertions(+)
create mode 100644 cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSASanity.ql
create mode 100644 cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSASanity.qll
create mode 100644 cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSASanity.ql
create mode 100644 cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSASanity.qll
create mode 100644 cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ssa_sanity.expected
create mode 100644 cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ssa_sanity.qlref
create mode 100644 cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ssa_sanity.expected
create mode 100644 cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ssa_sanity.qlref
create mode 100644 csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSASanity.ql
create mode 100644 csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSASanity.qll
create mode 100644 csharp/ql/test/library-tests/ir/ir/unaliased_ssa_ssa_sanity.expected
create mode 100644 csharp/ql/test/library-tests/ir/ir/unaliased_ssa_ssa_sanity.qlref
diff --git a/config/identical-files.json b/config/identical-files.json
index 4fdac5c7fea..29601d19510 100644
--- a/config/identical-files.json
+++ b/config/identical-files.json
@@ -143,6 +143,11 @@
"cpp/ql/src/semmle/code/cpp/ir/implementation/Opcode.qll",
"csharp/ql/src/semmle/code/csharp/ir/implementation/Opcode.qll"
],
+ "IR SSASanity": [
+ "cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSASanity.qll",
+ "cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSASanity.qll",
+ "csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSASanity.qll"
+ ],
"C++ IR InstructionImports": [
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/InstructionImports.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/InstructionImports.qll",
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll
index a789edc7590..ebb111efc03 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll
@@ -865,3 +865,16 @@ private module CachedForDebugging {
result.getTag() = var.getTag()
}
}
+
+module SSASanity {
+ query predicate multipleOperandMemoryLocations(OldIR::MemoryOperand operand, string message,
+ OldIR::IRFunction func, string funcText) {
+ exists(int locationCount |
+ locationCount = strictcount(Alias::getOperandMemoryLocation(operand)) and
+ locationCount > 1 and
+ func = operand.getEnclosingIRFunction() and
+ funcText = Language::getIdentityString(func.getFunction()) and
+ message = "Operand has " + locationCount.toString() + " memory accesses in function '$@'."
+ )
+ }
+}
\ No newline at end of file
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSASanity.ql b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSASanity.ql
new file mode 100644
index 00000000000..50368cdc6d9
--- /dev/null
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSASanity.ql
@@ -0,0 +1,8 @@
+/**
+ * @name Aliased SSA Sanity Check
+ * @description Performs sanity checks on the SSA construction. This query should have no results.
+ * @kind table
+ * @id cpp/aliased-ssa-sanity-check
+ */
+
+import SSASanity
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSASanity.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSASanity.qll
new file mode 100644
index 00000000000..95e8443b2a3
--- /dev/null
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSASanity.qll
@@ -0,0 +1,2 @@
+private import SSAConstruction as SSA
+import SSA::SSASanity
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll
index a789edc7590..ebb111efc03 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll
@@ -865,3 +865,16 @@ private module CachedForDebugging {
result.getTag() = var.getTag()
}
}
+
+module SSASanity {
+ query predicate multipleOperandMemoryLocations(OldIR::MemoryOperand operand, string message,
+ OldIR::IRFunction func, string funcText) {
+ exists(int locationCount |
+ locationCount = strictcount(Alias::getOperandMemoryLocation(operand)) and
+ locationCount > 1 and
+ func = operand.getEnclosingIRFunction() and
+ funcText = Language::getIdentityString(func.getFunction()) and
+ message = "Operand has " + locationCount.toString() + " memory accesses in function '$@'."
+ )
+ }
+}
\ No newline at end of file
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSASanity.ql b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSASanity.ql
new file mode 100644
index 00000000000..b67f6f281be
--- /dev/null
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSASanity.ql
@@ -0,0 +1,8 @@
+/**
+ * @name Unaliased SSA Sanity Check
+ * @description Performs sanity checks on the SSA construction. This query should have no results.
+ * @kind table
+ * @id cpp/unaliased-ssa-sanity-check
+ */
+
+import SSASanity
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSASanity.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSASanity.qll
new file mode 100644
index 00000000000..95e8443b2a3
--- /dev/null
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSASanity.qll
@@ -0,0 +1,2 @@
+private import SSAConstruction as SSA
+import SSA::SSASanity
diff --git a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ssa_sanity.expected b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ssa_sanity.expected
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ssa_sanity.qlref b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ssa_sanity.qlref
new file mode 100644
index 00000000000..8e348011785
--- /dev/null
+++ b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ssa_sanity.qlref
@@ -0,0 +1 @@
+semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSASanity.ql
\ No newline at end of file
diff --git a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ssa_sanity.expected b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ssa_sanity.expected
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ssa_sanity.qlref b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ssa_sanity.qlref
new file mode 100644
index 00000000000..18bf9212dbf
--- /dev/null
+++ b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ssa_sanity.qlref
@@ -0,0 +1 @@
+semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSASanity.ql
\ No newline at end of file
diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll
index a789edc7590..ebb111efc03 100644
--- a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll
+++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll
@@ -865,3 +865,16 @@ private module CachedForDebugging {
result.getTag() = var.getTag()
}
}
+
+module SSASanity {
+ query predicate multipleOperandMemoryLocations(OldIR::MemoryOperand operand, string message,
+ OldIR::IRFunction func, string funcText) {
+ exists(int locationCount |
+ locationCount = strictcount(Alias::getOperandMemoryLocation(operand)) and
+ locationCount > 1 and
+ func = operand.getEnclosingIRFunction() and
+ funcText = Language::getIdentityString(func.getFunction()) and
+ message = "Operand has " + locationCount.toString() + " memory accesses in function '$@'."
+ )
+ }
+}
\ No newline at end of file
diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSASanity.ql b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSASanity.ql
new file mode 100644
index 00000000000..11d7add514b
--- /dev/null
+++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSASanity.ql
@@ -0,0 +1,8 @@
+/**
+ * @name Unaliased SSA Sanity Check
+ * @description Performs sanity checks on the SSA construction. This query should have no results.
+ * @kind table
+ * @id csharp/unaliased-ssa-sanity-check
+ */
+
+import SSASanity
diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSASanity.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSASanity.qll
new file mode 100644
index 00000000000..95e8443b2a3
--- /dev/null
+++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSASanity.qll
@@ -0,0 +1,2 @@
+private import SSAConstruction as SSA
+import SSA::SSASanity
diff --git a/csharp/ql/test/library-tests/ir/ir/unaliased_ssa_ssa_sanity.expected b/csharp/ql/test/library-tests/ir/ir/unaliased_ssa_ssa_sanity.expected
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/csharp/ql/test/library-tests/ir/ir/unaliased_ssa_ssa_sanity.qlref b/csharp/ql/test/library-tests/ir/ir/unaliased_ssa_ssa_sanity.qlref
new file mode 100644
index 00000000000..1b7d4a7996a
--- /dev/null
+++ b/csharp/ql/test/library-tests/ir/ir/unaliased_ssa_ssa_sanity.qlref
@@ -0,0 +1 @@
+semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSASanity.ql
\ No newline at end of file
From df218357590cf1a1a9646b63481dead245f5e5dc Mon Sep 17 00:00:00 2001
From: Dave Bartolomeo
Date: Wed, 14 Aug 2019 13:54:52 -0700
Subject: [PATCH 29/44] C++/C#: Refactor some integer constant code
Make `bitsToBytesAndBits` omit the leftover bits if zero.
---
.../code/cpp/ir/internal/IntegerConstant.qll | 33 +++++++++++++++++++
.../code/cpp/ir/internal/IntegerInterval.qll | 2 +-
.../csharp/ir/internal/IntegerConstant.qll | 33 +++++++++++++++++++
.../csharp/ir/internal/IntegerInterval.qll | 2 +-
4 files changed, 68 insertions(+), 2 deletions(-)
diff --git a/cpp/ql/src/semmle/code/cpp/ir/internal/IntegerConstant.qll b/cpp/ql/src/semmle/code/cpp/ir/internal/IntegerConstant.qll
index 55546ba380f..0d845303c28 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/internal/IntegerConstant.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/internal/IntegerConstant.qll
@@ -192,3 +192,36 @@ predicate isGT(IntValue a, IntValue b) { hasValue(a) and hasValue(b) and a > b }
*/
bindingset[a, b]
predicate isGE(IntValue a, IntValue b) { hasValue(a) and hasValue(b) and a >= b }
+
+/**
+ * Converts the bit count in `bits` to a byte count and a bit count in the form
+ * "bytes:bits". If `bits` represents an integer number of bytes, the ":bits" section is omitted.
+ * If `bits` does not have a known value, the result is "?".
+ */
+bindingset[bits]
+string bitsToBytesAndBits(IntValue bits) {
+ exists(int bytes, int leftoverBits |
+ hasValue(bits) and
+ bytes = bits / 8 and
+ leftoverBits = bits % 8 and
+ if leftoverBits = 0 then
+ result = bytes.toString()
+ else
+ result = bytes + ":" + leftoverBits
+ ) or
+ not hasValue(bits) and result = "?"
+}
+
+/**
+ * Gets a printable string for a bit offset with possibly unknown value.
+ */
+bindingset[bitOffset]
+string getBitOffsetString(IntValue bitOffset) {
+ if hasValue(bitOffset) then
+ if bitOffset >= 0 then
+ result = "+" + bitsToBytesAndBits(bitOffset)
+ else
+ result = "-" + bitsToBytesAndBits(neg(bitOffset))
+ else
+ result = "+?"
+}
diff --git a/cpp/ql/src/semmle/code/cpp/ir/internal/IntegerInterval.qll b/cpp/ql/src/semmle/code/cpp/ir/internal/IntegerInterval.qll
index bc09f9c2243..cd12b9b627a 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/internal/IntegerInterval.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/internal/IntegerInterval.qll
@@ -30,5 +30,5 @@ Overlap getOverlap(IntValue defStart, IntValue defEnd, IntValue useStart, IntVal
bindingset[start, end]
string getIntervalString(IntValue start, IntValue end) {
// We represent an interval has half-open, so print it as "[start..end)".
- result = "[" + intValueToString(start) + ".." + intValueToString(end) + ")"
+ result = "[" + bitsToBytesAndBits(start) + ".." + bitsToBytesAndBits(end) + ")"
}
diff --git a/csharp/ql/src/semmle/code/csharp/ir/internal/IntegerConstant.qll b/csharp/ql/src/semmle/code/csharp/ir/internal/IntegerConstant.qll
index 55546ba380f..0d845303c28 100644
--- a/csharp/ql/src/semmle/code/csharp/ir/internal/IntegerConstant.qll
+++ b/csharp/ql/src/semmle/code/csharp/ir/internal/IntegerConstant.qll
@@ -192,3 +192,36 @@ predicate isGT(IntValue a, IntValue b) { hasValue(a) and hasValue(b) and a > b }
*/
bindingset[a, b]
predicate isGE(IntValue a, IntValue b) { hasValue(a) and hasValue(b) and a >= b }
+
+/**
+ * Converts the bit count in `bits` to a byte count and a bit count in the form
+ * "bytes:bits". If `bits` represents an integer number of bytes, the ":bits" section is omitted.
+ * If `bits` does not have a known value, the result is "?".
+ */
+bindingset[bits]
+string bitsToBytesAndBits(IntValue bits) {
+ exists(int bytes, int leftoverBits |
+ hasValue(bits) and
+ bytes = bits / 8 and
+ leftoverBits = bits % 8 and
+ if leftoverBits = 0 then
+ result = bytes.toString()
+ else
+ result = bytes + ":" + leftoverBits
+ ) or
+ not hasValue(bits) and result = "?"
+}
+
+/**
+ * Gets a printable string for a bit offset with possibly unknown value.
+ */
+bindingset[bitOffset]
+string getBitOffsetString(IntValue bitOffset) {
+ if hasValue(bitOffset) then
+ if bitOffset >= 0 then
+ result = "+" + bitsToBytesAndBits(bitOffset)
+ else
+ result = "-" + bitsToBytesAndBits(neg(bitOffset))
+ else
+ result = "+?"
+}
diff --git a/csharp/ql/src/semmle/code/csharp/ir/internal/IntegerInterval.qll b/csharp/ql/src/semmle/code/csharp/ir/internal/IntegerInterval.qll
index bc09f9c2243..cd12b9b627a 100644
--- a/csharp/ql/src/semmle/code/csharp/ir/internal/IntegerInterval.qll
+++ b/csharp/ql/src/semmle/code/csharp/ir/internal/IntegerInterval.qll
@@ -30,5 +30,5 @@ Overlap getOverlap(IntValue defStart, IntValue defEnd, IntValue useStart, IntVal
bindingset[start, end]
string getIntervalString(IntValue start, IntValue end) {
// We represent an interval has half-open, so print it as "[start..end)".
- result = "[" + intValueToString(start) + ".." + intValueToString(end) + ")"
+ result = "[" + bitsToBytesAndBits(start) + ".." + bitsToBytesAndBits(end) + ")"
}
From bd78f689752fc34801641f293358316dec285d64 Mon Sep 17 00:00:00 2001
From: Dave Bartolomeo
Date: Fri, 22 Nov 2019 16:08:49 -0700
Subject: [PATCH 30/44] C++/C#: Fix formatting
---
.../ir/implementation/aliased_ssa/IRVariable.qll | 3 ++-
.../ir/implementation/aliased_ssa/Instruction.qll | 13 +++++++------
.../aliased_ssa/internal/SSAConstruction.qll | 7 ++++---
.../aliased_ssa/internal/SSASanity.ql | 2 +-
.../code/cpp/ir/implementation/raw/IRVariable.qll | 3 ++-
.../code/cpp/ir/implementation/raw/Instruction.qll | 13 +++++++------
.../ir/implementation/unaliased_ssa/IRVariable.qll | 3 ++-
.../ir/implementation/unaliased_ssa/Instruction.qll | 13 +++++++------
.../unaliased_ssa/internal/SSAConstruction.qll | 7 ++++---
.../csharp/ir/implementation/raw/IRVariable.qll | 3 ++-
.../csharp/ir/implementation/raw/Instruction.qll | 13 +++++++------
.../ir/implementation/unaliased_ssa/IRVariable.qll | 3 ++-
.../ir/implementation/unaliased_ssa/Instruction.qll | 13 +++++++------
.../unaliased_ssa/internal/SSAConstruction.qll | 7 ++++---
14 files changed, 58 insertions(+), 45 deletions(-)
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll
index 349ff7cd6bd..1092acc0003 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll
@@ -112,7 +112,8 @@ class IRAutomaticVariable extends IRVariable {
exists(Language::Variable var |
this = TIRUserVariable(var, _, func) and
Language::isVariableAutomatic(var)
- ) or
+ )
+ or
this = TIRTempVariable(func, _, _, _)
}
}
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll
index bfd04a279e0..8819826d5c3 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll
@@ -94,17 +94,18 @@ module InstructionSanity {
/**
* Holds if instruction `instr` has multiple operands with tag `tag`.
*/
- query predicate duplicateOperand(Instruction instr, string message, IRFunction func,
- string funcText) {
+ query predicate duplicateOperand(
+ Instruction instr, string message, IRFunction func, string funcText
+ ) {
exists(OperandTag tag, int operandCount |
operandCount = strictcount(NonPhiOperand operand |
- operand = instr.getAnOperand() and
- operand.getOperandTag() = tag
- ) and
+ operand = instr.getAnOperand() and
+ operand.getOperandTag() = tag
+ ) and
operandCount > 1 and
not tag instanceof UnmodeledUseOperandTag and
message = "Instruction has " + operandCount + " operands with tag '" + tag.toString() + "'" +
- " in function '$@'." and
+ " in function '$@'." and
func = instr.getEnclosingIRFunction() and
funcText = Language::getIdentityString(func.getFunction())
)
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll
index ebb111efc03..96b4c28db82 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll
@@ -867,8 +867,9 @@ private module CachedForDebugging {
}
module SSASanity {
- query predicate multipleOperandMemoryLocations(OldIR::MemoryOperand operand, string message,
- OldIR::IRFunction func, string funcText) {
+ query predicate multipleOperandMemoryLocations(
+ OldIR::MemoryOperand operand, string message, OldIR::IRFunction func, string funcText
+ ) {
exists(int locationCount |
locationCount = strictcount(Alias::getOperandMemoryLocation(operand)) and
locationCount > 1 and
@@ -877,4 +878,4 @@ module SSASanity {
message = "Operand has " + locationCount.toString() + " memory accesses in function '$@'."
)
}
-}
\ No newline at end of file
+}
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSASanity.ql b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSASanity.ql
index 50368cdc6d9..3bd709a93dc 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSASanity.ql
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSASanity.ql
@@ -1,6 +1,6 @@
/**
* @name Aliased SSA Sanity Check
- * @description Performs sanity checks on the SSA construction. This query should have no results.
+ * @description Performs sanity checks on the SSA construction. This query should have no results.
* @kind table
* @id cpp/aliased-ssa-sanity-check
*/
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRVariable.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRVariable.qll
index 349ff7cd6bd..1092acc0003 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRVariable.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRVariable.qll
@@ -112,7 +112,8 @@ class IRAutomaticVariable extends IRVariable {
exists(Language::Variable var |
this = TIRUserVariable(var, _, func) and
Language::isVariableAutomatic(var)
- ) or
+ )
+ or
this = TIRTempVariable(func, _, _, _)
}
}
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll
index bfd04a279e0..8819826d5c3 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll
@@ -94,17 +94,18 @@ module InstructionSanity {
/**
* Holds if instruction `instr` has multiple operands with tag `tag`.
*/
- query predicate duplicateOperand(Instruction instr, string message, IRFunction func,
- string funcText) {
+ query predicate duplicateOperand(
+ Instruction instr, string message, IRFunction func, string funcText
+ ) {
exists(OperandTag tag, int operandCount |
operandCount = strictcount(NonPhiOperand operand |
- operand = instr.getAnOperand() and
- operand.getOperandTag() = tag
- ) and
+ operand = instr.getAnOperand() and
+ operand.getOperandTag() = tag
+ ) and
operandCount > 1 and
not tag instanceof UnmodeledUseOperandTag and
message = "Instruction has " + operandCount + " operands with tag '" + tag.toString() + "'" +
- " in function '$@'." and
+ " in function '$@'." and
func = instr.getEnclosingIRFunction() and
funcText = Language::getIdentityString(func.getFunction())
)
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll
index 349ff7cd6bd..1092acc0003 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll
@@ -112,7 +112,8 @@ class IRAutomaticVariable extends IRVariable {
exists(Language::Variable var |
this = TIRUserVariable(var, _, func) and
Language::isVariableAutomatic(var)
- ) or
+ )
+ or
this = TIRTempVariable(func, _, _, _)
}
}
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll
index bfd04a279e0..8819826d5c3 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll
@@ -94,17 +94,18 @@ module InstructionSanity {
/**
* Holds if instruction `instr` has multiple operands with tag `tag`.
*/
- query predicate duplicateOperand(Instruction instr, string message, IRFunction func,
- string funcText) {
+ query predicate duplicateOperand(
+ Instruction instr, string message, IRFunction func, string funcText
+ ) {
exists(OperandTag tag, int operandCount |
operandCount = strictcount(NonPhiOperand operand |
- operand = instr.getAnOperand() and
- operand.getOperandTag() = tag
- ) and
+ operand = instr.getAnOperand() and
+ operand.getOperandTag() = tag
+ ) and
operandCount > 1 and
not tag instanceof UnmodeledUseOperandTag and
message = "Instruction has " + operandCount + " operands with tag '" + tag.toString() + "'" +
- " in function '$@'." and
+ " in function '$@'." and
func = instr.getEnclosingIRFunction() and
funcText = Language::getIdentityString(func.getFunction())
)
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll
index ebb111efc03..96b4c28db82 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll
@@ -867,8 +867,9 @@ private module CachedForDebugging {
}
module SSASanity {
- query predicate multipleOperandMemoryLocations(OldIR::MemoryOperand operand, string message,
- OldIR::IRFunction func, string funcText) {
+ query predicate multipleOperandMemoryLocations(
+ OldIR::MemoryOperand operand, string message, OldIR::IRFunction func, string funcText
+ ) {
exists(int locationCount |
locationCount = strictcount(Alias::getOperandMemoryLocation(operand)) and
locationCount > 1 and
@@ -877,4 +878,4 @@ module SSASanity {
message = "Operand has " + locationCount.toString() + " memory accesses in function '$@'."
)
}
-}
\ No newline at end of file
+}
diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/IRVariable.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/IRVariable.qll
index 349ff7cd6bd..1092acc0003 100644
--- a/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/IRVariable.qll
+++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/IRVariable.qll
@@ -112,7 +112,8 @@ class IRAutomaticVariable extends IRVariable {
exists(Language::Variable var |
this = TIRUserVariable(var, _, func) and
Language::isVariableAutomatic(var)
- ) or
+ )
+ or
this = TIRTempVariable(func, _, _, _)
}
}
diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Instruction.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Instruction.qll
index bfd04a279e0..8819826d5c3 100644
--- a/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Instruction.qll
+++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Instruction.qll
@@ -94,17 +94,18 @@ module InstructionSanity {
/**
* Holds if instruction `instr` has multiple operands with tag `tag`.
*/
- query predicate duplicateOperand(Instruction instr, string message, IRFunction func,
- string funcText) {
+ query predicate duplicateOperand(
+ Instruction instr, string message, IRFunction func, string funcText
+ ) {
exists(OperandTag tag, int operandCount |
operandCount = strictcount(NonPhiOperand operand |
- operand = instr.getAnOperand() and
- operand.getOperandTag() = tag
- ) and
+ operand = instr.getAnOperand() and
+ operand.getOperandTag() = tag
+ ) and
operandCount > 1 and
not tag instanceof UnmodeledUseOperandTag and
message = "Instruction has " + operandCount + " operands with tag '" + tag.toString() + "'" +
- " in function '$@'." and
+ " in function '$@'." and
func = instr.getEnclosingIRFunction() and
funcText = Language::getIdentityString(func.getFunction())
)
diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/IRVariable.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/IRVariable.qll
index 349ff7cd6bd..1092acc0003 100644
--- a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/IRVariable.qll
+++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/IRVariable.qll
@@ -112,7 +112,8 @@ class IRAutomaticVariable extends IRVariable {
exists(Language::Variable var |
this = TIRUserVariable(var, _, func) and
Language::isVariableAutomatic(var)
- ) or
+ )
+ or
this = TIRTempVariable(func, _, _, _)
}
}
diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Instruction.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Instruction.qll
index bfd04a279e0..8819826d5c3 100644
--- a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Instruction.qll
+++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Instruction.qll
@@ -94,17 +94,18 @@ module InstructionSanity {
/**
* Holds if instruction `instr` has multiple operands with tag `tag`.
*/
- query predicate duplicateOperand(Instruction instr, string message, IRFunction func,
- string funcText) {
+ query predicate duplicateOperand(
+ Instruction instr, string message, IRFunction func, string funcText
+ ) {
exists(OperandTag tag, int operandCount |
operandCount = strictcount(NonPhiOperand operand |
- operand = instr.getAnOperand() and
- operand.getOperandTag() = tag
- ) and
+ operand = instr.getAnOperand() and
+ operand.getOperandTag() = tag
+ ) and
operandCount > 1 and
not tag instanceof UnmodeledUseOperandTag and
message = "Instruction has " + operandCount + " operands with tag '" + tag.toString() + "'" +
- " in function '$@'." and
+ " in function '$@'." and
func = instr.getEnclosingIRFunction() and
funcText = Language::getIdentityString(func.getFunction())
)
diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll
index ebb111efc03..96b4c28db82 100644
--- a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll
+++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll
@@ -867,8 +867,9 @@ private module CachedForDebugging {
}
module SSASanity {
- query predicate multipleOperandMemoryLocations(OldIR::MemoryOperand operand, string message,
- OldIR::IRFunction func, string funcText) {
+ query predicate multipleOperandMemoryLocations(
+ OldIR::MemoryOperand operand, string message, OldIR::IRFunction func, string funcText
+ ) {
exists(int locationCount |
locationCount = strictcount(Alias::getOperandMemoryLocation(operand)) and
locationCount > 1 and
@@ -877,4 +878,4 @@ module SSASanity {
message = "Operand has " + locationCount.toString() + " memory accesses in function '$@'."
)
}
-}
\ No newline at end of file
+}
From eda47bfc5175a8dfb28cf7b5b44562366e5b024f Mon Sep 17 00:00:00 2001
From: Dave Bartolomeo
Date: Wed, 14 Aug 2019 13:59:41 -0700
Subject: [PATCH 31/44] C++: Add SSA sanity tests to IR tests
---
cpp/ql/test/library-tests/ir/ir/aliased_ssa_ssa_sanity.expected | 0
cpp/ql/test/library-tests/ir/ir/aliased_ssa_ssa_sanity.qlref | 1 +
.../test/library-tests/ir/ir/unaliased_ssa_ssa_sanity.expected | 0
cpp/ql/test/library-tests/ir/ir/unaliased_ssa_ssa_sanity.qlref | 1 +
4 files changed, 2 insertions(+)
create mode 100644 cpp/ql/test/library-tests/ir/ir/aliased_ssa_ssa_sanity.expected
create mode 100644 cpp/ql/test/library-tests/ir/ir/aliased_ssa_ssa_sanity.qlref
create mode 100644 cpp/ql/test/library-tests/ir/ir/unaliased_ssa_ssa_sanity.expected
create mode 100644 cpp/ql/test/library-tests/ir/ir/unaliased_ssa_ssa_sanity.qlref
diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_ssa_sanity.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_ssa_sanity.expected
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_ssa_sanity.qlref b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_ssa_sanity.qlref
new file mode 100644
index 00000000000..8e348011785
--- /dev/null
+++ b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_ssa_sanity.qlref
@@ -0,0 +1 @@
+semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSASanity.ql
\ No newline at end of file
diff --git a/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_ssa_sanity.expected b/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_ssa_sanity.expected
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_ssa_sanity.qlref b/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_ssa_sanity.qlref
new file mode 100644
index 00000000000..18bf9212dbf
--- /dev/null
+++ b/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_ssa_sanity.qlref
@@ -0,0 +1 @@
+semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSASanity.ql
\ No newline at end of file
From a26efdf4c1069f0f0e87b2e701db10b500d8ec09 Mon Sep 17 00:00:00 2001
From: Tom Hvitved
Date: Mon, 25 Nov 2019 10:47:34 +0100
Subject: [PATCH 32/44] Java/C++/C#: Rename `DataFlowErasedType` back to
`DataFlowType`
---
.../cpp/dataflow/internal/DataFlowImpl.qll | 42 +++++++++----------
.../cpp/dataflow/internal/DataFlowImpl2.qll | 42 +++++++++----------
.../cpp/dataflow/internal/DataFlowImpl3.qll | 42 +++++++++----------
.../cpp/dataflow/internal/DataFlowImpl4.qll | 42 +++++++++----------
.../dataflow/internal/DataFlowImplCommon.qll | 4 +-
.../dataflow/internal/DataFlowImplLocal.qll | 42 +++++++++----------
.../cpp/dataflow/internal/DataFlowPrivate.qll | 2 -
.../cpp/ir/dataflow/internal/DataFlowImpl.qll | 42 +++++++++----------
.../ir/dataflow/internal/DataFlowImpl2.qll | 42 +++++++++----------
.../ir/dataflow/internal/DataFlowImpl3.qll | 42 +++++++++----------
.../ir/dataflow/internal/DataFlowImpl4.qll | 42 +++++++++----------
.../dataflow/internal/DataFlowImplCommon.qll | 4 +-
.../ir/dataflow/internal/DataFlowPrivate.qll | 2 -
.../csharp/dataflow/internal/DataFlowImpl.qll | 42 +++++++++----------
.../dataflow/internal/DataFlowImpl2.qll | 42 +++++++++----------
.../dataflow/internal/DataFlowImpl3.qll | 42 +++++++++----------
.../dataflow/internal/DataFlowImpl4.qll | 42 +++++++++----------
.../dataflow/internal/DataFlowImpl5.qll | 42 +++++++++----------
.../dataflow/internal/DataFlowImplCommon.qll | 4 +-
.../dataflow/internal/DataFlowPrivate.qll | 4 +-
.../java/dataflow/internal/DataFlowImpl.qll | 42 +++++++++----------
.../java/dataflow/internal/DataFlowImpl2.qll | 42 +++++++++----------
.../java/dataflow/internal/DataFlowImpl3.qll | 42 +++++++++----------
.../java/dataflow/internal/DataFlowImpl4.qll | 42 +++++++++----------
.../java/dataflow/internal/DataFlowImpl5.qll | 42 +++++++++----------
.../dataflow/internal/DataFlowImplCommon.qll | 4 +-
.../dataflow/internal/DataFlowPrivate.qll | 2 -
27 files changed, 408 insertions(+), 416 deletions(-)
diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll
index 6f74f6f024a..9519a74265f 100644
--- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll
+++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll
@@ -460,7 +460,7 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
*/
pragma[nomagic]
private predicate simpleParameterFlow(
- ParameterNode p, Node node, DataFlowErasedType t, Configuration config
+ ParameterNode p, Node node, DataFlowType t, Configuration config
) {
throughFlowNodeCand(node, config) and
p = node and
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
pragma[noinline]
private predicate simpleArgumentFlowsThrough0(
- DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
+ DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
) {
nodeCand1(arg, unbind(config)) and
not outBarrier(arg, config) and
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
* additional step from the configuration.
*/
private predicate simpleArgumentFlowsThrough(
- ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
+ ArgumentNode arg, Node out, DataFlowType t, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
nodeCand1(out, unbind(config)) and
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
}
private newtype TAccessPathFront =
- TFrontNil(DataFlowErasedType t) or
+ TFrontNil(DataFlowType t) or
TFrontHead(Content f)
/**
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
*/
private class AccessPathFront extends TAccessPathFront {
string toString() {
- exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
+ exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
or
exists(Content f | this = TFrontHead(f) | result = f.toString())
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TFrontNil(result)
or
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
@@ -1012,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
- private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
+ private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1069,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
+ exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
flowCandFwd(mid, fromArg, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
apf = TFrontNil(t)
@@ -1222,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
}
private newtype TAccessPath =
- TNil(DataFlowErasedType t) or
- TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
+ TNil(DataFlowType t) or
+ TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
/**
@@ -1250,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
this = TConsCons(_, _, result)
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TNil(result)
or
result = this.getHead().getContainerType()
@@ -1266,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
private class AccessPathNil extends AccessPath, TNil {
override string toString() {
- exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
+ exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
}
override predicate pop(Content head, AccessPath tail) { none() }
@@ -1280,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
private class AccessPathConsNil extends AccessPathCons, TConsNil {
override string toString() {
- exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
+ exists(Content f, DataFlowType t | this = TConsNil(f, t) |
// The `concat` becomes "" if `ppReprType` has no result.
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
)
@@ -1291,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
}
override predicate pop(Content head, AccessPath tail) {
- exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
+ exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
}
}
@@ -1339,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
- private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
+ private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -1411,7 +1411,7 @@ private predicate flowFwd0(
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
+ exists(Node mid, AccessPathNil nil, DataFlowType t |
flowFwd(mid, fromArg, _, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
ap = TNil(t) and
@@ -2020,7 +2020,7 @@ private module FlowExploration {
}
private newtype TPartialAccessPath =
- TPartialNil(DataFlowErasedType t) or
+ TPartialNil(DataFlowType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
@@ -2041,7 +2041,7 @@ private module FlowExploration {
this = TPartialCons(_, result)
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
@@ -2052,11 +2052,11 @@ private module FlowExploration {
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
- exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
+ exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll
index 6f74f6f024a..9519a74265f 100644
--- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll
+++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll
@@ -460,7 +460,7 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
*/
pragma[nomagic]
private predicate simpleParameterFlow(
- ParameterNode p, Node node, DataFlowErasedType t, Configuration config
+ ParameterNode p, Node node, DataFlowType t, Configuration config
) {
throughFlowNodeCand(node, config) and
p = node and
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
pragma[noinline]
private predicate simpleArgumentFlowsThrough0(
- DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
+ DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
) {
nodeCand1(arg, unbind(config)) and
not outBarrier(arg, config) and
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
* additional step from the configuration.
*/
private predicate simpleArgumentFlowsThrough(
- ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
+ ArgumentNode arg, Node out, DataFlowType t, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
nodeCand1(out, unbind(config)) and
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
}
private newtype TAccessPathFront =
- TFrontNil(DataFlowErasedType t) or
+ TFrontNil(DataFlowType t) or
TFrontHead(Content f)
/**
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
*/
private class AccessPathFront extends TAccessPathFront {
string toString() {
- exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
+ exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
or
exists(Content f | this = TFrontHead(f) | result = f.toString())
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TFrontNil(result)
or
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
@@ -1012,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
- private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
+ private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1069,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
+ exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
flowCandFwd(mid, fromArg, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
apf = TFrontNil(t)
@@ -1222,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
}
private newtype TAccessPath =
- TNil(DataFlowErasedType t) or
- TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
+ TNil(DataFlowType t) or
+ TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
/**
@@ -1250,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
this = TConsCons(_, _, result)
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TNil(result)
or
result = this.getHead().getContainerType()
@@ -1266,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
private class AccessPathNil extends AccessPath, TNil {
override string toString() {
- exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
+ exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
}
override predicate pop(Content head, AccessPath tail) { none() }
@@ -1280,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
private class AccessPathConsNil extends AccessPathCons, TConsNil {
override string toString() {
- exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
+ exists(Content f, DataFlowType t | this = TConsNil(f, t) |
// The `concat` becomes "" if `ppReprType` has no result.
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
)
@@ -1291,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
}
override predicate pop(Content head, AccessPath tail) {
- exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
+ exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
}
}
@@ -1339,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
- private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
+ private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -1411,7 +1411,7 @@ private predicate flowFwd0(
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
+ exists(Node mid, AccessPathNil nil, DataFlowType t |
flowFwd(mid, fromArg, _, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
ap = TNil(t) and
@@ -2020,7 +2020,7 @@ private module FlowExploration {
}
private newtype TPartialAccessPath =
- TPartialNil(DataFlowErasedType t) or
+ TPartialNil(DataFlowType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
@@ -2041,7 +2041,7 @@ private module FlowExploration {
this = TPartialCons(_, result)
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
@@ -2052,11 +2052,11 @@ private module FlowExploration {
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
- exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
+ exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll
index 6f74f6f024a..9519a74265f 100644
--- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll
+++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll
@@ -460,7 +460,7 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
*/
pragma[nomagic]
private predicate simpleParameterFlow(
- ParameterNode p, Node node, DataFlowErasedType t, Configuration config
+ ParameterNode p, Node node, DataFlowType t, Configuration config
) {
throughFlowNodeCand(node, config) and
p = node and
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
pragma[noinline]
private predicate simpleArgumentFlowsThrough0(
- DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
+ DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
) {
nodeCand1(arg, unbind(config)) and
not outBarrier(arg, config) and
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
* additional step from the configuration.
*/
private predicate simpleArgumentFlowsThrough(
- ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
+ ArgumentNode arg, Node out, DataFlowType t, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
nodeCand1(out, unbind(config)) and
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
}
private newtype TAccessPathFront =
- TFrontNil(DataFlowErasedType t) or
+ TFrontNil(DataFlowType t) or
TFrontHead(Content f)
/**
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
*/
private class AccessPathFront extends TAccessPathFront {
string toString() {
- exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
+ exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
or
exists(Content f | this = TFrontHead(f) | result = f.toString())
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TFrontNil(result)
or
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
@@ -1012,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
- private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
+ private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1069,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
+ exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
flowCandFwd(mid, fromArg, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
apf = TFrontNil(t)
@@ -1222,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
}
private newtype TAccessPath =
- TNil(DataFlowErasedType t) or
- TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
+ TNil(DataFlowType t) or
+ TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
/**
@@ -1250,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
this = TConsCons(_, _, result)
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TNil(result)
or
result = this.getHead().getContainerType()
@@ -1266,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
private class AccessPathNil extends AccessPath, TNil {
override string toString() {
- exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
+ exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
}
override predicate pop(Content head, AccessPath tail) { none() }
@@ -1280,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
private class AccessPathConsNil extends AccessPathCons, TConsNil {
override string toString() {
- exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
+ exists(Content f, DataFlowType t | this = TConsNil(f, t) |
// The `concat` becomes "" if `ppReprType` has no result.
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
)
@@ -1291,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
}
override predicate pop(Content head, AccessPath tail) {
- exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
+ exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
}
}
@@ -1339,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
- private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
+ private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -1411,7 +1411,7 @@ private predicate flowFwd0(
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
+ exists(Node mid, AccessPathNil nil, DataFlowType t |
flowFwd(mid, fromArg, _, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
ap = TNil(t) and
@@ -2020,7 +2020,7 @@ private module FlowExploration {
}
private newtype TPartialAccessPath =
- TPartialNil(DataFlowErasedType t) or
+ TPartialNil(DataFlowType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
@@ -2041,7 +2041,7 @@ private module FlowExploration {
this = TPartialCons(_, result)
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
@@ -2052,11 +2052,11 @@ private module FlowExploration {
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
- exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
+ exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll
index 6f74f6f024a..9519a74265f 100644
--- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll
+++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll
@@ -460,7 +460,7 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
*/
pragma[nomagic]
private predicate simpleParameterFlow(
- ParameterNode p, Node node, DataFlowErasedType t, Configuration config
+ ParameterNode p, Node node, DataFlowType t, Configuration config
) {
throughFlowNodeCand(node, config) and
p = node and
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
pragma[noinline]
private predicate simpleArgumentFlowsThrough0(
- DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
+ DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
) {
nodeCand1(arg, unbind(config)) and
not outBarrier(arg, config) and
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
* additional step from the configuration.
*/
private predicate simpleArgumentFlowsThrough(
- ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
+ ArgumentNode arg, Node out, DataFlowType t, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
nodeCand1(out, unbind(config)) and
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
}
private newtype TAccessPathFront =
- TFrontNil(DataFlowErasedType t) or
+ TFrontNil(DataFlowType t) or
TFrontHead(Content f)
/**
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
*/
private class AccessPathFront extends TAccessPathFront {
string toString() {
- exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
+ exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
or
exists(Content f | this = TFrontHead(f) | result = f.toString())
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TFrontNil(result)
or
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
@@ -1012,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
- private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
+ private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1069,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
+ exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
flowCandFwd(mid, fromArg, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
apf = TFrontNil(t)
@@ -1222,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
}
private newtype TAccessPath =
- TNil(DataFlowErasedType t) or
- TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
+ TNil(DataFlowType t) or
+ TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
/**
@@ -1250,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
this = TConsCons(_, _, result)
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TNil(result)
or
result = this.getHead().getContainerType()
@@ -1266,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
private class AccessPathNil extends AccessPath, TNil {
override string toString() {
- exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
+ exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
}
override predicate pop(Content head, AccessPath tail) { none() }
@@ -1280,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
private class AccessPathConsNil extends AccessPathCons, TConsNil {
override string toString() {
- exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
+ exists(Content f, DataFlowType t | this = TConsNil(f, t) |
// The `concat` becomes "" if `ppReprType` has no result.
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
)
@@ -1291,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
}
override predicate pop(Content head, AccessPath tail) {
- exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
+ exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
}
}
@@ -1339,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
- private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
+ private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -1411,7 +1411,7 @@ private predicate flowFwd0(
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
+ exists(Node mid, AccessPathNil nil, DataFlowType t |
flowFwd(mid, fromArg, _, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
ap = TNil(t) and
@@ -2020,7 +2020,7 @@ private module FlowExploration {
}
private newtype TPartialAccessPath =
- TPartialNil(DataFlowErasedType t) or
+ TPartialNil(DataFlowType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
@@ -2041,7 +2041,7 @@ private module FlowExploration {
this = TPartialCons(_, result)
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
@@ -2052,11 +2052,11 @@ private module FlowExploration {
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
- exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
+ exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll
index f0b5cb2b347..91f5aeacc9d 100644
--- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll
+++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll
@@ -862,8 +862,8 @@ private module ImplCommon {
}
pragma[noinline]
- DataFlowErasedType getErasedNodeType(Node n) { result = getErasedRepr(n.getType()) }
+ DataFlowType getErasedNodeType(Node n) { result = getErasedRepr(n.getType()) }
pragma[noinline]
- DataFlowErasedType getErasedNodeTypeBound(Node n) { result = getErasedRepr(n.getTypeBound()) }
+ DataFlowType getErasedNodeTypeBound(Node n) { result = getErasedRepr(n.getTypeBound()) }
}
diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll
index 6f74f6f024a..9519a74265f 100644
--- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll
+++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll
@@ -460,7 +460,7 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
*/
pragma[nomagic]
private predicate simpleParameterFlow(
- ParameterNode p, Node node, DataFlowErasedType t, Configuration config
+ ParameterNode p, Node node, DataFlowType t, Configuration config
) {
throughFlowNodeCand(node, config) and
p = node and
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
pragma[noinline]
private predicate simpleArgumentFlowsThrough0(
- DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
+ DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
) {
nodeCand1(arg, unbind(config)) and
not outBarrier(arg, config) and
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
* additional step from the configuration.
*/
private predicate simpleArgumentFlowsThrough(
- ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
+ ArgumentNode arg, Node out, DataFlowType t, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
nodeCand1(out, unbind(config)) and
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
}
private newtype TAccessPathFront =
- TFrontNil(DataFlowErasedType t) or
+ TFrontNil(DataFlowType t) or
TFrontHead(Content f)
/**
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
*/
private class AccessPathFront extends TAccessPathFront {
string toString() {
- exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
+ exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
or
exists(Content f | this = TFrontHead(f) | result = f.toString())
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TFrontNil(result)
or
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
@@ -1012,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
- private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
+ private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1069,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
+ exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
flowCandFwd(mid, fromArg, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
apf = TFrontNil(t)
@@ -1222,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
}
private newtype TAccessPath =
- TNil(DataFlowErasedType t) or
- TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
+ TNil(DataFlowType t) or
+ TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
/**
@@ -1250,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
this = TConsCons(_, _, result)
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TNil(result)
or
result = this.getHead().getContainerType()
@@ -1266,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
private class AccessPathNil extends AccessPath, TNil {
override string toString() {
- exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
+ exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
}
override predicate pop(Content head, AccessPath tail) { none() }
@@ -1280,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
private class AccessPathConsNil extends AccessPathCons, TConsNil {
override string toString() {
- exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
+ exists(Content f, DataFlowType t | this = TConsNil(f, t) |
// The `concat` becomes "" if `ppReprType` has no result.
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
)
@@ -1291,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
}
override predicate pop(Content head, AccessPath tail) {
- exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
+ exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
}
}
@@ -1339,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
- private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
+ private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -1411,7 +1411,7 @@ private predicate flowFwd0(
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
+ exists(Node mid, AccessPathNil nil, DataFlowType t |
flowFwd(mid, fromArg, _, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
ap = TNil(t) and
@@ -2020,7 +2020,7 @@ private module FlowExploration {
}
private newtype TPartialAccessPath =
- TPartialNil(DataFlowErasedType t) or
+ TPartialNil(DataFlowType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
@@ -2041,7 +2041,7 @@ private module FlowExploration {
this = TPartialCons(_, result)
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
@@ -2052,11 +2052,11 @@ private module FlowExploration {
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
- exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
+ exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll
index 9f58391d7c1..ab95d38ed0f 100644
--- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll
+++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll
@@ -282,8 +282,6 @@ class DataFlowExpr = Expr;
class DataFlowType = Type;
-class DataFlowErasedType = Type;
-
class DataFlowLocation = Location;
/** A function call relevant for data flow. */
diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll
index 6f74f6f024a..9519a74265f 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll
@@ -460,7 +460,7 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
*/
pragma[nomagic]
private predicate simpleParameterFlow(
- ParameterNode p, Node node, DataFlowErasedType t, Configuration config
+ ParameterNode p, Node node, DataFlowType t, Configuration config
) {
throughFlowNodeCand(node, config) and
p = node and
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
pragma[noinline]
private predicate simpleArgumentFlowsThrough0(
- DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
+ DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
) {
nodeCand1(arg, unbind(config)) and
not outBarrier(arg, config) and
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
* additional step from the configuration.
*/
private predicate simpleArgumentFlowsThrough(
- ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
+ ArgumentNode arg, Node out, DataFlowType t, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
nodeCand1(out, unbind(config)) and
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
}
private newtype TAccessPathFront =
- TFrontNil(DataFlowErasedType t) or
+ TFrontNil(DataFlowType t) or
TFrontHead(Content f)
/**
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
*/
private class AccessPathFront extends TAccessPathFront {
string toString() {
- exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
+ exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
or
exists(Content f | this = TFrontHead(f) | result = f.toString())
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TFrontNil(result)
or
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
@@ -1012,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
- private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
+ private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1069,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
+ exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
flowCandFwd(mid, fromArg, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
apf = TFrontNil(t)
@@ -1222,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
}
private newtype TAccessPath =
- TNil(DataFlowErasedType t) or
- TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
+ TNil(DataFlowType t) or
+ TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
/**
@@ -1250,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
this = TConsCons(_, _, result)
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TNil(result)
or
result = this.getHead().getContainerType()
@@ -1266,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
private class AccessPathNil extends AccessPath, TNil {
override string toString() {
- exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
+ exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
}
override predicate pop(Content head, AccessPath tail) { none() }
@@ -1280,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
private class AccessPathConsNil extends AccessPathCons, TConsNil {
override string toString() {
- exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
+ exists(Content f, DataFlowType t | this = TConsNil(f, t) |
// The `concat` becomes "" if `ppReprType` has no result.
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
)
@@ -1291,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
}
override predicate pop(Content head, AccessPath tail) {
- exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
+ exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
}
}
@@ -1339,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
- private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
+ private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -1411,7 +1411,7 @@ private predicate flowFwd0(
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
+ exists(Node mid, AccessPathNil nil, DataFlowType t |
flowFwd(mid, fromArg, _, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
ap = TNil(t) and
@@ -2020,7 +2020,7 @@ private module FlowExploration {
}
private newtype TPartialAccessPath =
- TPartialNil(DataFlowErasedType t) or
+ TPartialNil(DataFlowType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
@@ -2041,7 +2041,7 @@ private module FlowExploration {
this = TPartialCons(_, result)
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
@@ -2052,11 +2052,11 @@ private module FlowExploration {
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
- exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
+ exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll
index 6f74f6f024a..9519a74265f 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll
@@ -460,7 +460,7 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
*/
pragma[nomagic]
private predicate simpleParameterFlow(
- ParameterNode p, Node node, DataFlowErasedType t, Configuration config
+ ParameterNode p, Node node, DataFlowType t, Configuration config
) {
throughFlowNodeCand(node, config) and
p = node and
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
pragma[noinline]
private predicate simpleArgumentFlowsThrough0(
- DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
+ DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
) {
nodeCand1(arg, unbind(config)) and
not outBarrier(arg, config) and
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
* additional step from the configuration.
*/
private predicate simpleArgumentFlowsThrough(
- ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
+ ArgumentNode arg, Node out, DataFlowType t, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
nodeCand1(out, unbind(config)) and
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
}
private newtype TAccessPathFront =
- TFrontNil(DataFlowErasedType t) or
+ TFrontNil(DataFlowType t) or
TFrontHead(Content f)
/**
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
*/
private class AccessPathFront extends TAccessPathFront {
string toString() {
- exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
+ exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
or
exists(Content f | this = TFrontHead(f) | result = f.toString())
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TFrontNil(result)
or
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
@@ -1012,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
- private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
+ private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1069,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
+ exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
flowCandFwd(mid, fromArg, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
apf = TFrontNil(t)
@@ -1222,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
}
private newtype TAccessPath =
- TNil(DataFlowErasedType t) or
- TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
+ TNil(DataFlowType t) or
+ TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
/**
@@ -1250,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
this = TConsCons(_, _, result)
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TNil(result)
or
result = this.getHead().getContainerType()
@@ -1266,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
private class AccessPathNil extends AccessPath, TNil {
override string toString() {
- exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
+ exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
}
override predicate pop(Content head, AccessPath tail) { none() }
@@ -1280,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
private class AccessPathConsNil extends AccessPathCons, TConsNil {
override string toString() {
- exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
+ exists(Content f, DataFlowType t | this = TConsNil(f, t) |
// The `concat` becomes "" if `ppReprType` has no result.
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
)
@@ -1291,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
}
override predicate pop(Content head, AccessPath tail) {
- exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
+ exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
}
}
@@ -1339,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
- private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
+ private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -1411,7 +1411,7 @@ private predicate flowFwd0(
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
+ exists(Node mid, AccessPathNil nil, DataFlowType t |
flowFwd(mid, fromArg, _, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
ap = TNil(t) and
@@ -2020,7 +2020,7 @@ private module FlowExploration {
}
private newtype TPartialAccessPath =
- TPartialNil(DataFlowErasedType t) or
+ TPartialNil(DataFlowType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
@@ -2041,7 +2041,7 @@ private module FlowExploration {
this = TPartialCons(_, result)
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
@@ -2052,11 +2052,11 @@ private module FlowExploration {
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
- exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
+ exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll
index 6f74f6f024a..9519a74265f 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll
@@ -460,7 +460,7 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
*/
pragma[nomagic]
private predicate simpleParameterFlow(
- ParameterNode p, Node node, DataFlowErasedType t, Configuration config
+ ParameterNode p, Node node, DataFlowType t, Configuration config
) {
throughFlowNodeCand(node, config) and
p = node and
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
pragma[noinline]
private predicate simpleArgumentFlowsThrough0(
- DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
+ DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
) {
nodeCand1(arg, unbind(config)) and
not outBarrier(arg, config) and
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
* additional step from the configuration.
*/
private predicate simpleArgumentFlowsThrough(
- ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
+ ArgumentNode arg, Node out, DataFlowType t, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
nodeCand1(out, unbind(config)) and
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
}
private newtype TAccessPathFront =
- TFrontNil(DataFlowErasedType t) or
+ TFrontNil(DataFlowType t) or
TFrontHead(Content f)
/**
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
*/
private class AccessPathFront extends TAccessPathFront {
string toString() {
- exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
+ exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
or
exists(Content f | this = TFrontHead(f) | result = f.toString())
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TFrontNil(result)
or
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
@@ -1012,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
- private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
+ private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1069,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
+ exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
flowCandFwd(mid, fromArg, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
apf = TFrontNil(t)
@@ -1222,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
}
private newtype TAccessPath =
- TNil(DataFlowErasedType t) or
- TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
+ TNil(DataFlowType t) or
+ TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
/**
@@ -1250,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
this = TConsCons(_, _, result)
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TNil(result)
or
result = this.getHead().getContainerType()
@@ -1266,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
private class AccessPathNil extends AccessPath, TNil {
override string toString() {
- exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
+ exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
}
override predicate pop(Content head, AccessPath tail) { none() }
@@ -1280,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
private class AccessPathConsNil extends AccessPathCons, TConsNil {
override string toString() {
- exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
+ exists(Content f, DataFlowType t | this = TConsNil(f, t) |
// The `concat` becomes "" if `ppReprType` has no result.
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
)
@@ -1291,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
}
override predicate pop(Content head, AccessPath tail) {
- exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
+ exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
}
}
@@ -1339,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
- private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
+ private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -1411,7 +1411,7 @@ private predicate flowFwd0(
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
+ exists(Node mid, AccessPathNil nil, DataFlowType t |
flowFwd(mid, fromArg, _, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
ap = TNil(t) and
@@ -2020,7 +2020,7 @@ private module FlowExploration {
}
private newtype TPartialAccessPath =
- TPartialNil(DataFlowErasedType t) or
+ TPartialNil(DataFlowType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
@@ -2041,7 +2041,7 @@ private module FlowExploration {
this = TPartialCons(_, result)
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
@@ -2052,11 +2052,11 @@ private module FlowExploration {
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
- exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
+ exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll
index 6f74f6f024a..9519a74265f 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll
@@ -460,7 +460,7 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
*/
pragma[nomagic]
private predicate simpleParameterFlow(
- ParameterNode p, Node node, DataFlowErasedType t, Configuration config
+ ParameterNode p, Node node, DataFlowType t, Configuration config
) {
throughFlowNodeCand(node, config) and
p = node and
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
pragma[noinline]
private predicate simpleArgumentFlowsThrough0(
- DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
+ DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
) {
nodeCand1(arg, unbind(config)) and
not outBarrier(arg, config) and
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
* additional step from the configuration.
*/
private predicate simpleArgumentFlowsThrough(
- ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
+ ArgumentNode arg, Node out, DataFlowType t, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
nodeCand1(out, unbind(config)) and
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
}
private newtype TAccessPathFront =
- TFrontNil(DataFlowErasedType t) or
+ TFrontNil(DataFlowType t) or
TFrontHead(Content f)
/**
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
*/
private class AccessPathFront extends TAccessPathFront {
string toString() {
- exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
+ exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
or
exists(Content f | this = TFrontHead(f) | result = f.toString())
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TFrontNil(result)
or
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
@@ -1012,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
- private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
+ private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1069,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
+ exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
flowCandFwd(mid, fromArg, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
apf = TFrontNil(t)
@@ -1222,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
}
private newtype TAccessPath =
- TNil(DataFlowErasedType t) or
- TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
+ TNil(DataFlowType t) or
+ TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
/**
@@ -1250,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
this = TConsCons(_, _, result)
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TNil(result)
or
result = this.getHead().getContainerType()
@@ -1266,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
private class AccessPathNil extends AccessPath, TNil {
override string toString() {
- exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
+ exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
}
override predicate pop(Content head, AccessPath tail) { none() }
@@ -1280,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
private class AccessPathConsNil extends AccessPathCons, TConsNil {
override string toString() {
- exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
+ exists(Content f, DataFlowType t | this = TConsNil(f, t) |
// The `concat` becomes "" if `ppReprType` has no result.
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
)
@@ -1291,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
}
override predicate pop(Content head, AccessPath tail) {
- exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
+ exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
}
}
@@ -1339,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
- private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
+ private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -1411,7 +1411,7 @@ private predicate flowFwd0(
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
+ exists(Node mid, AccessPathNil nil, DataFlowType t |
flowFwd(mid, fromArg, _, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
ap = TNil(t) and
@@ -2020,7 +2020,7 @@ private module FlowExploration {
}
private newtype TPartialAccessPath =
- TPartialNil(DataFlowErasedType t) or
+ TPartialNil(DataFlowType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
@@ -2041,7 +2041,7 @@ private module FlowExploration {
this = TPartialCons(_, result)
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
@@ -2052,11 +2052,11 @@ private module FlowExploration {
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
- exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
+ exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll
index f0b5cb2b347..91f5aeacc9d 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll
@@ -862,8 +862,8 @@ private module ImplCommon {
}
pragma[noinline]
- DataFlowErasedType getErasedNodeType(Node n) { result = getErasedRepr(n.getType()) }
+ DataFlowType getErasedNodeType(Node n) { result = getErasedRepr(n.getType()) }
pragma[noinline]
- DataFlowErasedType getErasedNodeTypeBound(Node n) { result = getErasedRepr(n.getTypeBound()) }
+ DataFlowType getErasedNodeTypeBound(Node n) { result = getErasedRepr(n.getTypeBound()) }
}
diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll
index 0ce14e90e6c..f6306759771 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll
@@ -191,8 +191,6 @@ class DataFlowExpr = Expr;
class DataFlowType = Type;
-class DataFlowErasedType = Type;
-
class DataFlowLocation = Location;
/** A function call relevant for data flow. */
diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll
index 6f74f6f024a..9519a74265f 100644
--- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll
+++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll
@@ -460,7 +460,7 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
*/
pragma[nomagic]
private predicate simpleParameterFlow(
- ParameterNode p, Node node, DataFlowErasedType t, Configuration config
+ ParameterNode p, Node node, DataFlowType t, Configuration config
) {
throughFlowNodeCand(node, config) and
p = node and
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
pragma[noinline]
private predicate simpleArgumentFlowsThrough0(
- DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
+ DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
) {
nodeCand1(arg, unbind(config)) and
not outBarrier(arg, config) and
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
* additional step from the configuration.
*/
private predicate simpleArgumentFlowsThrough(
- ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
+ ArgumentNode arg, Node out, DataFlowType t, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
nodeCand1(out, unbind(config)) and
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
}
private newtype TAccessPathFront =
- TFrontNil(DataFlowErasedType t) or
+ TFrontNil(DataFlowType t) or
TFrontHead(Content f)
/**
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
*/
private class AccessPathFront extends TAccessPathFront {
string toString() {
- exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
+ exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
or
exists(Content f | this = TFrontHead(f) | result = f.toString())
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TFrontNil(result)
or
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
@@ -1012,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
- private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
+ private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1069,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
+ exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
flowCandFwd(mid, fromArg, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
apf = TFrontNil(t)
@@ -1222,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
}
private newtype TAccessPath =
- TNil(DataFlowErasedType t) or
- TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
+ TNil(DataFlowType t) or
+ TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
/**
@@ -1250,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
this = TConsCons(_, _, result)
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TNil(result)
or
result = this.getHead().getContainerType()
@@ -1266,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
private class AccessPathNil extends AccessPath, TNil {
override string toString() {
- exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
+ exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
}
override predicate pop(Content head, AccessPath tail) { none() }
@@ -1280,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
private class AccessPathConsNil extends AccessPathCons, TConsNil {
override string toString() {
- exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
+ exists(Content f, DataFlowType t | this = TConsNil(f, t) |
// The `concat` becomes "" if `ppReprType` has no result.
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
)
@@ -1291,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
}
override predicate pop(Content head, AccessPath tail) {
- exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
+ exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
}
}
@@ -1339,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
- private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
+ private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -1411,7 +1411,7 @@ private predicate flowFwd0(
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
+ exists(Node mid, AccessPathNil nil, DataFlowType t |
flowFwd(mid, fromArg, _, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
ap = TNil(t) and
@@ -2020,7 +2020,7 @@ private module FlowExploration {
}
private newtype TPartialAccessPath =
- TPartialNil(DataFlowErasedType t) or
+ TPartialNil(DataFlowType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
@@ -2041,7 +2041,7 @@ private module FlowExploration {
this = TPartialCons(_, result)
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
@@ -2052,11 +2052,11 @@ private module FlowExploration {
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
- exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
+ exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll
index 6f74f6f024a..9519a74265f 100644
--- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll
+++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll
@@ -460,7 +460,7 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
*/
pragma[nomagic]
private predicate simpleParameterFlow(
- ParameterNode p, Node node, DataFlowErasedType t, Configuration config
+ ParameterNode p, Node node, DataFlowType t, Configuration config
) {
throughFlowNodeCand(node, config) and
p = node and
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
pragma[noinline]
private predicate simpleArgumentFlowsThrough0(
- DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
+ DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
) {
nodeCand1(arg, unbind(config)) and
not outBarrier(arg, config) and
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
* additional step from the configuration.
*/
private predicate simpleArgumentFlowsThrough(
- ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
+ ArgumentNode arg, Node out, DataFlowType t, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
nodeCand1(out, unbind(config)) and
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
}
private newtype TAccessPathFront =
- TFrontNil(DataFlowErasedType t) or
+ TFrontNil(DataFlowType t) or
TFrontHead(Content f)
/**
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
*/
private class AccessPathFront extends TAccessPathFront {
string toString() {
- exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
+ exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
or
exists(Content f | this = TFrontHead(f) | result = f.toString())
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TFrontNil(result)
or
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
@@ -1012,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
- private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
+ private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1069,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
+ exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
flowCandFwd(mid, fromArg, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
apf = TFrontNil(t)
@@ -1222,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
}
private newtype TAccessPath =
- TNil(DataFlowErasedType t) or
- TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
+ TNil(DataFlowType t) or
+ TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
/**
@@ -1250,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
this = TConsCons(_, _, result)
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TNil(result)
or
result = this.getHead().getContainerType()
@@ -1266,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
private class AccessPathNil extends AccessPath, TNil {
override string toString() {
- exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
+ exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
}
override predicate pop(Content head, AccessPath tail) { none() }
@@ -1280,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
private class AccessPathConsNil extends AccessPathCons, TConsNil {
override string toString() {
- exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
+ exists(Content f, DataFlowType t | this = TConsNil(f, t) |
// The `concat` becomes "" if `ppReprType` has no result.
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
)
@@ -1291,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
}
override predicate pop(Content head, AccessPath tail) {
- exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
+ exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
}
}
@@ -1339,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
- private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
+ private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -1411,7 +1411,7 @@ private predicate flowFwd0(
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
+ exists(Node mid, AccessPathNil nil, DataFlowType t |
flowFwd(mid, fromArg, _, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
ap = TNil(t) and
@@ -2020,7 +2020,7 @@ private module FlowExploration {
}
private newtype TPartialAccessPath =
- TPartialNil(DataFlowErasedType t) or
+ TPartialNil(DataFlowType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
@@ -2041,7 +2041,7 @@ private module FlowExploration {
this = TPartialCons(_, result)
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
@@ -2052,11 +2052,11 @@ private module FlowExploration {
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
- exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
+ exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll
index 6f74f6f024a..9519a74265f 100644
--- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll
+++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll
@@ -460,7 +460,7 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
*/
pragma[nomagic]
private predicate simpleParameterFlow(
- ParameterNode p, Node node, DataFlowErasedType t, Configuration config
+ ParameterNode p, Node node, DataFlowType t, Configuration config
) {
throughFlowNodeCand(node, config) and
p = node and
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
pragma[noinline]
private predicate simpleArgumentFlowsThrough0(
- DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
+ DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
) {
nodeCand1(arg, unbind(config)) and
not outBarrier(arg, config) and
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
* additional step from the configuration.
*/
private predicate simpleArgumentFlowsThrough(
- ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
+ ArgumentNode arg, Node out, DataFlowType t, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
nodeCand1(out, unbind(config)) and
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
}
private newtype TAccessPathFront =
- TFrontNil(DataFlowErasedType t) or
+ TFrontNil(DataFlowType t) or
TFrontHead(Content f)
/**
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
*/
private class AccessPathFront extends TAccessPathFront {
string toString() {
- exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
+ exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
or
exists(Content f | this = TFrontHead(f) | result = f.toString())
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TFrontNil(result)
or
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
@@ -1012,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
- private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
+ private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1069,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
+ exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
flowCandFwd(mid, fromArg, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
apf = TFrontNil(t)
@@ -1222,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
}
private newtype TAccessPath =
- TNil(DataFlowErasedType t) or
- TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
+ TNil(DataFlowType t) or
+ TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
/**
@@ -1250,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
this = TConsCons(_, _, result)
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TNil(result)
or
result = this.getHead().getContainerType()
@@ -1266,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
private class AccessPathNil extends AccessPath, TNil {
override string toString() {
- exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
+ exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
}
override predicate pop(Content head, AccessPath tail) { none() }
@@ -1280,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
private class AccessPathConsNil extends AccessPathCons, TConsNil {
override string toString() {
- exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
+ exists(Content f, DataFlowType t | this = TConsNil(f, t) |
// The `concat` becomes "" if `ppReprType` has no result.
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
)
@@ -1291,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
}
override predicate pop(Content head, AccessPath tail) {
- exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
+ exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
}
}
@@ -1339,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
- private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
+ private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -1411,7 +1411,7 @@ private predicate flowFwd0(
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
+ exists(Node mid, AccessPathNil nil, DataFlowType t |
flowFwd(mid, fromArg, _, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
ap = TNil(t) and
@@ -2020,7 +2020,7 @@ private module FlowExploration {
}
private newtype TPartialAccessPath =
- TPartialNil(DataFlowErasedType t) or
+ TPartialNil(DataFlowType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
@@ -2041,7 +2041,7 @@ private module FlowExploration {
this = TPartialCons(_, result)
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
@@ -2052,11 +2052,11 @@ private module FlowExploration {
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
- exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
+ exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll
index 6f74f6f024a..9519a74265f 100644
--- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll
+++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll
@@ -460,7 +460,7 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
*/
pragma[nomagic]
private predicate simpleParameterFlow(
- ParameterNode p, Node node, DataFlowErasedType t, Configuration config
+ ParameterNode p, Node node, DataFlowType t, Configuration config
) {
throughFlowNodeCand(node, config) and
p = node and
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
pragma[noinline]
private predicate simpleArgumentFlowsThrough0(
- DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
+ DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
) {
nodeCand1(arg, unbind(config)) and
not outBarrier(arg, config) and
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
* additional step from the configuration.
*/
private predicate simpleArgumentFlowsThrough(
- ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
+ ArgumentNode arg, Node out, DataFlowType t, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
nodeCand1(out, unbind(config)) and
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
}
private newtype TAccessPathFront =
- TFrontNil(DataFlowErasedType t) or
+ TFrontNil(DataFlowType t) or
TFrontHead(Content f)
/**
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
*/
private class AccessPathFront extends TAccessPathFront {
string toString() {
- exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
+ exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
or
exists(Content f | this = TFrontHead(f) | result = f.toString())
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TFrontNil(result)
or
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
@@ -1012,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
- private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
+ private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1069,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
+ exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
flowCandFwd(mid, fromArg, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
apf = TFrontNil(t)
@@ -1222,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
}
private newtype TAccessPath =
- TNil(DataFlowErasedType t) or
- TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
+ TNil(DataFlowType t) or
+ TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
/**
@@ -1250,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
this = TConsCons(_, _, result)
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TNil(result)
or
result = this.getHead().getContainerType()
@@ -1266,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
private class AccessPathNil extends AccessPath, TNil {
override string toString() {
- exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
+ exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
}
override predicate pop(Content head, AccessPath tail) { none() }
@@ -1280,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
private class AccessPathConsNil extends AccessPathCons, TConsNil {
override string toString() {
- exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
+ exists(Content f, DataFlowType t | this = TConsNil(f, t) |
// The `concat` becomes "" if `ppReprType` has no result.
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
)
@@ -1291,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
}
override predicate pop(Content head, AccessPath tail) {
- exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
+ exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
}
}
@@ -1339,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
- private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
+ private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -1411,7 +1411,7 @@ private predicate flowFwd0(
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
+ exists(Node mid, AccessPathNil nil, DataFlowType t |
flowFwd(mid, fromArg, _, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
ap = TNil(t) and
@@ -2020,7 +2020,7 @@ private module FlowExploration {
}
private newtype TPartialAccessPath =
- TPartialNil(DataFlowErasedType t) or
+ TPartialNil(DataFlowType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
@@ -2041,7 +2041,7 @@ private module FlowExploration {
this = TPartialCons(_, result)
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
@@ -2052,11 +2052,11 @@ private module FlowExploration {
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
- exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
+ exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll
index 6f74f6f024a..9519a74265f 100644
--- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll
+++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll
@@ -460,7 +460,7 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
*/
pragma[nomagic]
private predicate simpleParameterFlow(
- ParameterNode p, Node node, DataFlowErasedType t, Configuration config
+ ParameterNode p, Node node, DataFlowType t, Configuration config
) {
throughFlowNodeCand(node, config) and
p = node and
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
pragma[noinline]
private predicate simpleArgumentFlowsThrough0(
- DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
+ DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
) {
nodeCand1(arg, unbind(config)) and
not outBarrier(arg, config) and
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
* additional step from the configuration.
*/
private predicate simpleArgumentFlowsThrough(
- ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
+ ArgumentNode arg, Node out, DataFlowType t, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
nodeCand1(out, unbind(config)) and
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
}
private newtype TAccessPathFront =
- TFrontNil(DataFlowErasedType t) or
+ TFrontNil(DataFlowType t) or
TFrontHead(Content f)
/**
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
*/
private class AccessPathFront extends TAccessPathFront {
string toString() {
- exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
+ exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
or
exists(Content f | this = TFrontHead(f) | result = f.toString())
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TFrontNil(result)
or
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
@@ -1012,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
- private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
+ private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1069,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
+ exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
flowCandFwd(mid, fromArg, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
apf = TFrontNil(t)
@@ -1222,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
}
private newtype TAccessPath =
- TNil(DataFlowErasedType t) or
- TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
+ TNil(DataFlowType t) or
+ TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
/**
@@ -1250,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
this = TConsCons(_, _, result)
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TNil(result)
or
result = this.getHead().getContainerType()
@@ -1266,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
private class AccessPathNil extends AccessPath, TNil {
override string toString() {
- exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
+ exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
}
override predicate pop(Content head, AccessPath tail) { none() }
@@ -1280,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
private class AccessPathConsNil extends AccessPathCons, TConsNil {
override string toString() {
- exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
+ exists(Content f, DataFlowType t | this = TConsNil(f, t) |
// The `concat` becomes "" if `ppReprType` has no result.
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
)
@@ -1291,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
}
override predicate pop(Content head, AccessPath tail) {
- exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
+ exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
}
}
@@ -1339,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
- private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
+ private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -1411,7 +1411,7 @@ private predicate flowFwd0(
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
+ exists(Node mid, AccessPathNil nil, DataFlowType t |
flowFwd(mid, fromArg, _, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
ap = TNil(t) and
@@ -2020,7 +2020,7 @@ private module FlowExploration {
}
private newtype TPartialAccessPath =
- TPartialNil(DataFlowErasedType t) or
+ TPartialNil(DataFlowType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
@@ -2041,7 +2041,7 @@ private module FlowExploration {
this = TPartialCons(_, result)
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
@@ -2052,11 +2052,11 @@ private module FlowExploration {
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
- exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
+ exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll
index f0b5cb2b347..91f5aeacc9d 100644
--- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll
+++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll
@@ -862,8 +862,8 @@ private module ImplCommon {
}
pragma[noinline]
- DataFlowErasedType getErasedNodeType(Node n) { result = getErasedRepr(n.getType()) }
+ DataFlowType getErasedNodeType(Node n) { result = getErasedRepr(n.getType()) }
pragma[noinline]
- DataFlowErasedType getErasedNodeTypeBound(Node n) { result = getErasedRepr(n.getTypeBound()) }
+ DataFlowType getErasedNodeTypeBound(Node n) { result = getErasedRepr(n.getTypeBound()) }
}
diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll
index 7f8730c7ee9..9df3803fa3d 100644
--- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll
+++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll
@@ -1307,7 +1307,7 @@ private predicate suppressUnusedType(DotNet::Type t) { any() }
* Type-based pruning is disabled for now, so this is a stub implementation.
*/
bindingset[t]
-DataFlowErasedType getErasedRepr(DataFlowType t) {
+DataFlowType getErasedRepr(DotNet::Type t) {
// stub implementation
suppressUnusedType(t) and result instanceof ObjectType
}
@@ -1378,8 +1378,6 @@ class DataFlowExpr = DotNet::Expr;
class DataFlowType = DotNet::Type;
-class DataFlowErasedType = DotNet::Type;
-
class DataFlowLocation = Location;
/** Holds if `e` is an expression that always has the same Boolean value `val`. */
diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll
index 6f74f6f024a..9519a74265f 100644
--- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll
+++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll
@@ -460,7 +460,7 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
*/
pragma[nomagic]
private predicate simpleParameterFlow(
- ParameterNode p, Node node, DataFlowErasedType t, Configuration config
+ ParameterNode p, Node node, DataFlowType t, Configuration config
) {
throughFlowNodeCand(node, config) and
p = node and
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
pragma[noinline]
private predicate simpleArgumentFlowsThrough0(
- DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
+ DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
) {
nodeCand1(arg, unbind(config)) and
not outBarrier(arg, config) and
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
* additional step from the configuration.
*/
private predicate simpleArgumentFlowsThrough(
- ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
+ ArgumentNode arg, Node out, DataFlowType t, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
nodeCand1(out, unbind(config)) and
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
}
private newtype TAccessPathFront =
- TFrontNil(DataFlowErasedType t) or
+ TFrontNil(DataFlowType t) or
TFrontHead(Content f)
/**
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
*/
private class AccessPathFront extends TAccessPathFront {
string toString() {
- exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
+ exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
or
exists(Content f | this = TFrontHead(f) | result = f.toString())
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TFrontNil(result)
or
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
@@ -1012,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
- private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
+ private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1069,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
+ exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
flowCandFwd(mid, fromArg, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
apf = TFrontNil(t)
@@ -1222,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
}
private newtype TAccessPath =
- TNil(DataFlowErasedType t) or
- TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
+ TNil(DataFlowType t) or
+ TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
/**
@@ -1250,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
this = TConsCons(_, _, result)
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TNil(result)
or
result = this.getHead().getContainerType()
@@ -1266,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
private class AccessPathNil extends AccessPath, TNil {
override string toString() {
- exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
+ exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
}
override predicate pop(Content head, AccessPath tail) { none() }
@@ -1280,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
private class AccessPathConsNil extends AccessPathCons, TConsNil {
override string toString() {
- exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
+ exists(Content f, DataFlowType t | this = TConsNil(f, t) |
// The `concat` becomes "" if `ppReprType` has no result.
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
)
@@ -1291,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
}
override predicate pop(Content head, AccessPath tail) {
- exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
+ exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
}
}
@@ -1339,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
- private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
+ private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -1411,7 +1411,7 @@ private predicate flowFwd0(
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
+ exists(Node mid, AccessPathNil nil, DataFlowType t |
flowFwd(mid, fromArg, _, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
ap = TNil(t) and
@@ -2020,7 +2020,7 @@ private module FlowExploration {
}
private newtype TPartialAccessPath =
- TPartialNil(DataFlowErasedType t) or
+ TPartialNil(DataFlowType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
@@ -2041,7 +2041,7 @@ private module FlowExploration {
this = TPartialCons(_, result)
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
@@ -2052,11 +2052,11 @@ private module FlowExploration {
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
- exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
+ exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll
index 6f74f6f024a..9519a74265f 100644
--- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll
+++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll
@@ -460,7 +460,7 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
*/
pragma[nomagic]
private predicate simpleParameterFlow(
- ParameterNode p, Node node, DataFlowErasedType t, Configuration config
+ ParameterNode p, Node node, DataFlowType t, Configuration config
) {
throughFlowNodeCand(node, config) and
p = node and
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
pragma[noinline]
private predicate simpleArgumentFlowsThrough0(
- DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
+ DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
) {
nodeCand1(arg, unbind(config)) and
not outBarrier(arg, config) and
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
* additional step from the configuration.
*/
private predicate simpleArgumentFlowsThrough(
- ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
+ ArgumentNode arg, Node out, DataFlowType t, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
nodeCand1(out, unbind(config)) and
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
}
private newtype TAccessPathFront =
- TFrontNil(DataFlowErasedType t) or
+ TFrontNil(DataFlowType t) or
TFrontHead(Content f)
/**
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
*/
private class AccessPathFront extends TAccessPathFront {
string toString() {
- exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
+ exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
or
exists(Content f | this = TFrontHead(f) | result = f.toString())
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TFrontNil(result)
or
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
@@ -1012,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
- private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
+ private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1069,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
+ exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
flowCandFwd(mid, fromArg, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
apf = TFrontNil(t)
@@ -1222,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
}
private newtype TAccessPath =
- TNil(DataFlowErasedType t) or
- TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
+ TNil(DataFlowType t) or
+ TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
/**
@@ -1250,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
this = TConsCons(_, _, result)
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TNil(result)
or
result = this.getHead().getContainerType()
@@ -1266,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
private class AccessPathNil extends AccessPath, TNil {
override string toString() {
- exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
+ exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
}
override predicate pop(Content head, AccessPath tail) { none() }
@@ -1280,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
private class AccessPathConsNil extends AccessPathCons, TConsNil {
override string toString() {
- exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
+ exists(Content f, DataFlowType t | this = TConsNil(f, t) |
// The `concat` becomes "" if `ppReprType` has no result.
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
)
@@ -1291,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
}
override predicate pop(Content head, AccessPath tail) {
- exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
+ exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
}
}
@@ -1339,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
- private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
+ private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -1411,7 +1411,7 @@ private predicate flowFwd0(
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
+ exists(Node mid, AccessPathNil nil, DataFlowType t |
flowFwd(mid, fromArg, _, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
ap = TNil(t) and
@@ -2020,7 +2020,7 @@ private module FlowExploration {
}
private newtype TPartialAccessPath =
- TPartialNil(DataFlowErasedType t) or
+ TPartialNil(DataFlowType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
@@ -2041,7 +2041,7 @@ private module FlowExploration {
this = TPartialCons(_, result)
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
@@ -2052,11 +2052,11 @@ private module FlowExploration {
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
- exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
+ exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl3.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl3.qll
index 6f74f6f024a..9519a74265f 100644
--- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl3.qll
+++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl3.qll
@@ -460,7 +460,7 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
*/
pragma[nomagic]
private predicate simpleParameterFlow(
- ParameterNode p, Node node, DataFlowErasedType t, Configuration config
+ ParameterNode p, Node node, DataFlowType t, Configuration config
) {
throughFlowNodeCand(node, config) and
p = node and
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
pragma[noinline]
private predicate simpleArgumentFlowsThrough0(
- DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
+ DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
) {
nodeCand1(arg, unbind(config)) and
not outBarrier(arg, config) and
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
* additional step from the configuration.
*/
private predicate simpleArgumentFlowsThrough(
- ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
+ ArgumentNode arg, Node out, DataFlowType t, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
nodeCand1(out, unbind(config)) and
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
}
private newtype TAccessPathFront =
- TFrontNil(DataFlowErasedType t) or
+ TFrontNil(DataFlowType t) or
TFrontHead(Content f)
/**
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
*/
private class AccessPathFront extends TAccessPathFront {
string toString() {
- exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
+ exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
or
exists(Content f | this = TFrontHead(f) | result = f.toString())
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TFrontNil(result)
or
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
@@ -1012,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
- private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
+ private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1069,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
+ exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
flowCandFwd(mid, fromArg, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
apf = TFrontNil(t)
@@ -1222,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
}
private newtype TAccessPath =
- TNil(DataFlowErasedType t) or
- TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
+ TNil(DataFlowType t) or
+ TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
/**
@@ -1250,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
this = TConsCons(_, _, result)
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TNil(result)
or
result = this.getHead().getContainerType()
@@ -1266,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
private class AccessPathNil extends AccessPath, TNil {
override string toString() {
- exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
+ exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
}
override predicate pop(Content head, AccessPath tail) { none() }
@@ -1280,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
private class AccessPathConsNil extends AccessPathCons, TConsNil {
override string toString() {
- exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
+ exists(Content f, DataFlowType t | this = TConsNil(f, t) |
// The `concat` becomes "" if `ppReprType` has no result.
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
)
@@ -1291,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
}
override predicate pop(Content head, AccessPath tail) {
- exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
+ exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
}
}
@@ -1339,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
- private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
+ private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -1411,7 +1411,7 @@ private predicate flowFwd0(
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
+ exists(Node mid, AccessPathNil nil, DataFlowType t |
flowFwd(mid, fromArg, _, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
ap = TNil(t) and
@@ -2020,7 +2020,7 @@ private module FlowExploration {
}
private newtype TPartialAccessPath =
- TPartialNil(DataFlowErasedType t) or
+ TPartialNil(DataFlowType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
@@ -2041,7 +2041,7 @@ private module FlowExploration {
this = TPartialCons(_, result)
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
@@ -2052,11 +2052,11 @@ private module FlowExploration {
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
- exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
+ exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl4.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl4.qll
index 6f74f6f024a..9519a74265f 100644
--- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl4.qll
+++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl4.qll
@@ -460,7 +460,7 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
*/
pragma[nomagic]
private predicate simpleParameterFlow(
- ParameterNode p, Node node, DataFlowErasedType t, Configuration config
+ ParameterNode p, Node node, DataFlowType t, Configuration config
) {
throughFlowNodeCand(node, config) and
p = node and
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
pragma[noinline]
private predicate simpleArgumentFlowsThrough0(
- DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
+ DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
) {
nodeCand1(arg, unbind(config)) and
not outBarrier(arg, config) and
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
* additional step from the configuration.
*/
private predicate simpleArgumentFlowsThrough(
- ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
+ ArgumentNode arg, Node out, DataFlowType t, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
nodeCand1(out, unbind(config)) and
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
}
private newtype TAccessPathFront =
- TFrontNil(DataFlowErasedType t) or
+ TFrontNil(DataFlowType t) or
TFrontHead(Content f)
/**
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
*/
private class AccessPathFront extends TAccessPathFront {
string toString() {
- exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
+ exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
or
exists(Content f | this = TFrontHead(f) | result = f.toString())
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TFrontNil(result)
or
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
@@ -1012,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
- private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
+ private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1069,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
+ exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
flowCandFwd(mid, fromArg, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
apf = TFrontNil(t)
@@ -1222,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
}
private newtype TAccessPath =
- TNil(DataFlowErasedType t) or
- TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
+ TNil(DataFlowType t) or
+ TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
/**
@@ -1250,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
this = TConsCons(_, _, result)
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TNil(result)
or
result = this.getHead().getContainerType()
@@ -1266,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
private class AccessPathNil extends AccessPath, TNil {
override string toString() {
- exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
+ exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
}
override predicate pop(Content head, AccessPath tail) { none() }
@@ -1280,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
private class AccessPathConsNil extends AccessPathCons, TConsNil {
override string toString() {
- exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
+ exists(Content f, DataFlowType t | this = TConsNil(f, t) |
// The `concat` becomes "" if `ppReprType` has no result.
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
)
@@ -1291,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
}
override predicate pop(Content head, AccessPath tail) {
- exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
+ exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
}
}
@@ -1339,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
- private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
+ private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -1411,7 +1411,7 @@ private predicate flowFwd0(
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
+ exists(Node mid, AccessPathNil nil, DataFlowType t |
flowFwd(mid, fromArg, _, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
ap = TNil(t) and
@@ -2020,7 +2020,7 @@ private module FlowExploration {
}
private newtype TPartialAccessPath =
- TPartialNil(DataFlowErasedType t) or
+ TPartialNil(DataFlowType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
@@ -2041,7 +2041,7 @@ private module FlowExploration {
this = TPartialCons(_, result)
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
@@ -2052,11 +2052,11 @@ private module FlowExploration {
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
- exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
+ exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl5.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl5.qll
index 6f74f6f024a..9519a74265f 100644
--- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl5.qll
+++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl5.qll
@@ -460,7 +460,7 @@ private predicate throughFlowNodeCand(Node node, Configuration config) {
*/
pragma[nomagic]
private predicate simpleParameterFlow(
- ParameterNode p, Node node, DataFlowErasedType t, Configuration config
+ ParameterNode p, Node node, DataFlowType t, Configuration config
) {
throughFlowNodeCand(node, config) and
p = node and
@@ -510,7 +510,7 @@ private predicate simpleParameterFlow(
pragma[noinline]
private predicate simpleArgumentFlowsThrough0(
- DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowErasedType t, Configuration config
+ DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
) {
nodeCand1(arg, unbind(config)) and
not outBarrier(arg, config) and
@@ -529,7 +529,7 @@ private predicate simpleArgumentFlowsThrough0(
* additional step from the configuration.
*/
private predicate simpleArgumentFlowsThrough(
- ArgumentNode arg, Node out, DataFlowErasedType t, Configuration config
+ ArgumentNode arg, Node out, DataFlowType t, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
nodeCand1(out, unbind(config)) and
@@ -948,7 +948,7 @@ private predicate localFlowBigStep(
}
private newtype TAccessPathFront =
- TFrontNil(DataFlowErasedType t) or
+ TFrontNil(DataFlowType t) or
TFrontHead(Content f)
/**
@@ -956,12 +956,12 @@ private newtype TAccessPathFront =
*/
private class AccessPathFront extends TAccessPathFront {
string toString() {
- exists(DataFlowErasedType t | this = TFrontNil(t) | result = ppReprType(t))
+ exists(DataFlowType t | this = TFrontNil(t) | result = ppReprType(t))
or
exists(Content f | this = TFrontHead(f) | result = f.toString())
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TFrontNil(result)
or
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
@@ -1012,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
- private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
+ private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1069,7 +1069,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathFrontNil nil, DataFlowErasedType t |
+ exists(Node mid, AccessPathFrontNil nil, DataFlowType t |
flowCandFwd(mid, fromArg, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
apf = TFrontNil(t)
@@ -1222,8 +1222,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
}
private newtype TAccessPath =
- TNil(DataFlowErasedType t) or
- TConsNil(Content f, DataFlowErasedType t) { consCand(f, TFrontNil(t), _) } or
+ TNil(DataFlowType t) or
+ TConsNil(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
/**
@@ -1250,7 +1250,7 @@ abstract private class AccessPath extends TAccessPath {
this = TConsCons(_, _, result)
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TNil(result)
or
result = this.getHead().getContainerType()
@@ -1266,11 +1266,11 @@ abstract private class AccessPath extends TAccessPath {
private class AccessPathNil extends AccessPath, TNil {
override string toString() {
- exists(DataFlowErasedType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowErasedType t | this = TNil(t) | result = TFrontNil(t))
+ exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
}
override predicate pop(Content head, AccessPath tail) { none() }
@@ -1280,7 +1280,7 @@ abstract private class AccessPathCons extends AccessPath { }
private class AccessPathConsNil extends AccessPathCons, TConsNil {
override string toString() {
- exists(Content f, DataFlowErasedType t | this = TConsNil(f, t) |
+ exists(Content f, DataFlowType t | this = TConsNil(f, t) |
// The `concat` becomes "" if `ppReprType` has no result.
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
)
@@ -1291,7 +1291,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
}
override predicate pop(Content head, AccessPath tail) {
- exists(DataFlowErasedType t | this = TConsNil(head, t) and tail = TNil(t))
+ exists(DataFlowType t | this = TConsNil(head, t) and tail = TNil(t))
}
}
@@ -1339,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
- private DataFlowErasedType getErasedReprType() { result = getErasedNodeType(this) }
+ private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -1411,7 +1411,7 @@ private predicate flowFwd0(
argumentValueFlowsThrough(mid, node, _)
)
or
- exists(Node mid, AccessPathNil nil, DataFlowErasedType t |
+ exists(Node mid, AccessPathNil nil, DataFlowType t |
flowFwd(mid, fromArg, _, nil, config) and
simpleArgumentFlowsThrough(mid, node, t, config) and
ap = TNil(t) and
@@ -2020,7 +2020,7 @@ private module FlowExploration {
}
private newtype TPartialAccessPath =
- TPartialNil(DataFlowErasedType t) or
+ TPartialNil(DataFlowType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
@@ -2041,7 +2041,7 @@ private module FlowExploration {
this = TPartialCons(_, result)
}
- DataFlowErasedType getType() {
+ DataFlowType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
@@ -2052,11 +2052,11 @@ private module FlowExploration {
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
- exists(DataFlowErasedType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
+ exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
}
override AccessPathFront getFront() {
- exists(DataFlowErasedType t | this = TPartialNil(t) | result = TFrontNil(t))
+ exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll
index f0b5cb2b347..91f5aeacc9d 100644
--- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll
+++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll
@@ -862,8 +862,8 @@ private module ImplCommon {
}
pragma[noinline]
- DataFlowErasedType getErasedNodeType(Node n) { result = getErasedRepr(n.getType()) }
+ DataFlowType getErasedNodeType(Node n) { result = getErasedRepr(n.getType()) }
pragma[noinline]
- DataFlowErasedType getErasedNodeTypeBound(Node n) { result = getErasedRepr(n.getTypeBound()) }
+ DataFlowType getErasedNodeTypeBound(Node n) { result = getErasedRepr(n.getTypeBound()) }
}
diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowPrivate.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowPrivate.qll
index 698baf84912..5255e06af5c 100644
--- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowPrivate.qll
+++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowPrivate.qll
@@ -279,8 +279,6 @@ class DataFlowExpr = Expr;
class DataFlowType = RefType;
-class DataFlowErasedType = RefType;
-
class DataFlowLocation = Location;
class DataFlowCall extends Call {
From 4efc71b7a2bc8e8ce41d81b3a2c9854e5ab07de2 Mon Sep 17 00:00:00 2001
From: Erik Krogh Kristensen
Date: Mon, 25 Nov 2019 11:48:16 +0100
Subject: [PATCH 33/44] remove FP in use-of-returnless-function FP related to
calls to super()
---
.../ql/src/Statements/UseOfReturnlessFunction.ql | 3 ++-
.../Statements/UseOfReturnlessFunction/tst.js | 14 +++++++++++++-
2 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/javascript/ql/src/Statements/UseOfReturnlessFunction.ql b/javascript/ql/src/Statements/UseOfReturnlessFunction.ql
index db889527ce2..5b431c33489 100644
--- a/javascript/ql/src/Statements/UseOfReturnlessFunction.ql
+++ b/javascript/ql/src/Statements/UseOfReturnlessFunction.ql
@@ -222,6 +222,7 @@ where
not lastStatementHasNoEffect(func) and
// anonymous one-shot closure. Those are used in weird ways and we ignore them.
not oneshotClosure(call) and
- not hasNonVoidReturnType(func)
+ not hasNonVoidReturnType(func) and
+ not call.getEnclosingExpr() instanceof SuperCall
select
call, msg, func, name
diff --git a/javascript/ql/test/query-tests/Statements/UseOfReturnlessFunction/tst.js b/javascript/ql/test/query-tests/Statements/UseOfReturnlessFunction/tst.js
index ee69b7e53cf..abdc41143f0 100644
--- a/javascript/ql/test/query-tests/Statements/UseOfReturnlessFunction/tst.js
+++ b/javascript/ql/test/query-tests/Statements/UseOfReturnlessFunction/tst.js
@@ -92,4 +92,16 @@
+function() {
console.log("FOO");
-}.call(this);
\ No newline at end of file
+}.call(this);
+
+class Foo {
+ constructor() {
+ console.log("FOO");
+ }
+}
+
+class Bar extends Foo {
+ constructor() {
+ console.log(super()); // OK.
+ }
+}
\ No newline at end of file
From 71fd5379c9812af53ca3540f598a4db3cf298292 Mon Sep 17 00:00:00 2001
From: Tom Hvitved
Date: Mon, 25 Nov 2019 13:40:44 +0100
Subject: [PATCH 34/44] C#: Remove tabs from qhelp file
---
.../CWE-016/ASPNetMaxRequestLength.qhelp | 75 ++++++++-----------
1 file changed, 32 insertions(+), 43 deletions(-)
diff --git a/csharp/ql/src/Security Features/CWE-016/ASPNetMaxRequestLength.qhelp b/csharp/ql/src/Security Features/CWE-016/ASPNetMaxRequestLength.qhelp
index d180aacacbc..2d9454c16d5 100644
--- a/csharp/ql/src/Security Features/CWE-016/ASPNetMaxRequestLength.qhelp
+++ b/csharp/ql/src/Security Features/CWE-016/ASPNetMaxRequestLength.qhelp
@@ -3,56 +3,45 @@
"qhelp.dtd">
-
-
- The
- maxRequestLength
- attribute sets the limit for the input stream buffering
- threshold in
- KB. Attackers can use large requests to cause denial-of-service
- attacks.
-
-
-
+
+
+ The maxRequestLength attribute sets the limit for the input
+ stream buffering threshold in KB. Attackers can use large requests to cause
+ denial-of-service attacks.
+
+
+
-
- The recommended value is 4096 KB but you should try setting it as
- small
- as possible according
- to business requirements.
-
+
+ The recommended value is 4096 KB but you should try setting it as
+ small as possible according to business requirements.
+
-
-
+
+
-
- The following example shows the
- maxRequestLength
- attribute set to a high value
- (255 MB) in a
- Web.config
- file for ASP.NET:
-
+
+ The following example shows the maxRequestLength
+ attribute set to a high value (255 MB) in a Web.config
+ file for ASP.NET:
+
-
+
-
- Unless such a high value is strictly needed, it is better to set
- the
- recommended value (4096 KB):
-
+
+ Unless such a high value is strictly needed, it is better to set
+ the recommended value (4096 KB):
+
-
+
-
+
-
+
-
- .NET API:
- MaxRequestLength limit to prevent denial of service attacks
- .
-
-
+
+ MSDN:
+ HttpRuntimeSection.MaxRequestLength Property.
+
+
\ No newline at end of file
From 795959ef8d72039ab89fa0912e7d1731d1997602 Mon Sep 17 00:00:00 2001
From: Tom Hvitved
Date: Mon, 25 Nov 2019 13:41:12 +0100
Subject: [PATCH 35/44] C#: Update expected test output
---
.../Security Features/CWE-016/ASPNetMaxRequestLength.expected | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/csharp/ql/test/query-tests/Security Features/CWE-016/ASPNetMaxRequestLength.expected b/csharp/ql/test/query-tests/Security Features/CWE-016/ASPNetMaxRequestLength.expected
index 83252520dea..1feab65d0ee 100644
--- a/csharp/ql/test/query-tests/Security Features/CWE-016/ASPNetMaxRequestLength.expected
+++ b/csharp/ql/test/query-tests/Security Features/CWE-016/ASPNetMaxRequestLength.expected
@@ -1 +1 @@
-| bad/Web.config:4:5:4:46 | maxRequestLength=262144 | Large 'maxRequestLength' value (262144). |
\ No newline at end of file
+| bad/Web.config:4:5:4:46 | maxRequestLength=262144 | Large 'maxRequestLength' value (262144 KB). |
From 3368169df84e321d652e0b491a105c43551d9928 Mon Sep 17 00:00:00 2001
From: Cornelius Riemenschneider
Date: Mon, 25 Nov 2019 14:54:50 +0100
Subject: [PATCH 36/44] Address review.
---
java/ql/src/semmle/code/java/dataflow/NullGuards.qll | 1 -
1 file changed, 1 deletion(-)
diff --git a/java/ql/src/semmle/code/java/dataflow/NullGuards.qll b/java/ql/src/semmle/code/java/dataflow/NullGuards.qll
index 1ca4720ce18..7069699eb5d 100644
--- a/java/ql/src/semmle/code/java/dataflow/NullGuards.qll
+++ b/java/ql/src/semmle/code/java/dataflow/NullGuards.qll
@@ -36,7 +36,6 @@ InstanceOfExpr instanceofExpr(SsaVariable v, Type type) {
*/
EqualityTest varEqualityTestExpr(SsaVariable v1, SsaVariable v2, boolean isEqualExpr) {
result.hasOperands(v1.getAUse(), v2.getAUse()) and
- result instanceof EqualityTest and
isEqualExpr = result.polarity()
}
From 07e18c88a8f1dcb6a3b55bbbbad7ccb207c307f1 Mon Sep 17 00:00:00 2001
From: Tom Hvitved
Date: Mon, 25 Nov 2019 16:51:09 +0100
Subject: [PATCH 37/44] C#: Address review comments
---
.../Semmle.Autobuild.Tests/BuildScripts.cs | 40 +++--
.../Semmle.Autobuild/BuildCommandAutoRule.cs | 4 +-
.../Semmle.Autobuild/BuildCommandRule.cs | 4 +-
.../Semmle.Autobuild/DotNetRule.cs | 141 ++++++++++--------
4 files changed, 107 insertions(+), 82 deletions(-)
diff --git a/csharp/autobuilder/Semmle.Autobuild.Tests/BuildScripts.cs b/csharp/autobuilder/Semmle.Autobuild.Tests/BuildScripts.cs
index 8037cf98065..a2e59cf7ac3 100644
--- a/csharp/autobuilder/Semmle.Autobuild.Tests/BuildScripts.cs
+++ b/csharp/autobuilder/Semmle.Autobuild.Tests/BuildScripts.cs
@@ -401,12 +401,12 @@ namespace Semmle.Extraction.Tests
[Fact]
public void TestLinuxCSharpAutoBuilder()
{
- Actions.RunProcess["dotnet --info"] = 0;
- Actions.RunProcess["dotnet clean test.csproj"] = 0;
- Actions.RunProcess["dotnet restore test.csproj"] = 0;
Actions.RunProcess["dotnet --list-runtimes"] = 0;
Actions.RunProcessOut["dotnet --list-runtimes"] = @"Microsoft.AspNetCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]";
+ Actions.RunProcess["dotnet --info"] = 0;
+ Actions.RunProcess["dotnet clean test.csproj"] = 0;
+ Actions.RunProcess["dotnet restore test.csproj"] = 0;
Actions.RunProcess[@"C:\odasa/tools/odasa index --auto dotnet build --no-incremental /p:UseSharedCompilation=false test.csproj"] = 0;
Actions.RunProcess[@"C:\codeql\tools\java/bin/java -jar C:\codeql\csharp/tools/extractor-asp.jar ."] = 0;
Actions.RunProcess[@"C:\odasa/tools/odasa index --xml --extensions config csproj props xml"] = 0;
@@ -601,6 +601,8 @@ Microsoft.NETCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
[Fact]
public void TestLinuxBuildCommand()
{
+ Actions.RunProcess["dotnet --list-runtimes"] = 1;
+ Actions.RunProcessOut["dotnet --list-runtimes"] = "";
Actions.RunProcess[@"C:\odasa/tools/odasa index --auto ""./build.sh --skip-tests"""] = 0;
Actions.RunProcess[@"C:\codeql\tools\java/bin/java -jar C:\codeql\csharp/tools/extractor-asp.jar ."] = 0;
Actions.RunProcess[@"C:\odasa/tools/odasa index --xml --extensions config csproj props xml"] = 0;
@@ -613,7 +615,7 @@ Microsoft.NETCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
SkipVsWhere();
var autobuilder = CreateAutoBuilder("csharp", false, buildCommand: "./build.sh --skip-tests");
- TestAutobuilderScript(autobuilder, 0, 3);
+ TestAutobuilderScript(autobuilder, 0, 4);
}
[Fact]
@@ -624,6 +626,8 @@ Microsoft.NETCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
Actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = "";
Actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_SOURCE_ARCHIVE_DIR"] = "";
Actions.RunProcess["/bin/chmod u+x build/build.sh"] = 0;
+ Actions.RunProcess["dotnet --list-runtimes"] = 1;
+ Actions.RunProcessOut["dotnet --list-runtimes"] = "";
Actions.RunProcess[@"C:\odasa/tools/odasa index --auto build/build.sh"] = 0;
Actions.RunProcessWorkingDirectory[@"C:\odasa/tools/odasa index --auto build/build.sh"] = "build";
Actions.RunProcess[@"C:\codeql\tools\java/bin/java -jar C:\codeql\csharp/tools/extractor-asp.jar ."] = 0;
@@ -631,7 +635,7 @@ Microsoft.NETCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
Actions.FileExists["csharp.log"] = true;
var autobuilder = CreateAutoBuilder("csharp", false);
- TestAutobuilderScript(autobuilder, 0, 4);
+ TestAutobuilderScript(autobuilder, 0, 5);
}
[Fact]
@@ -643,12 +647,14 @@ Microsoft.NETCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
Actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_SOURCE_ARCHIVE_DIR"] = "";
Actions.RunProcess["/bin/chmod u+x build.sh"] = 0;
+ Actions.RunProcess["dotnet --list-runtimes"] = 1;
+ Actions.RunProcessOut["dotnet --list-runtimes"] = "";
Actions.RunProcess[@"C:\odasa/tools/odasa index --auto build.sh"] = 0;
Actions.RunProcessWorkingDirectory[@"C:\odasa/tools/odasa index --auto build.sh"] = "";
Actions.FileExists["csharp.log"] = false;
var autobuilder = CreateAutoBuilder("csharp", false);
- TestAutobuilderScript(autobuilder, 1, 2);
+ TestAutobuilderScript(autobuilder, 1, 3);
}
[Fact]
@@ -660,12 +666,14 @@ Microsoft.NETCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
Actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_SOURCE_ARCHIVE_DIR"] = "";
Actions.RunProcess["/bin/chmod u+x build.sh"] = 0;
+ Actions.RunProcess["dotnet --list-runtimes"] = 1;
+ Actions.RunProcessOut["dotnet --list-runtimes"] = "";
Actions.RunProcess[@"C:\odasa/tools/odasa index --auto build.sh"] = 5;
Actions.RunProcessWorkingDirectory[@"C:\odasa/tools/odasa index --auto build.sh"] = "";
Actions.FileExists["csharp.log"] = true;
var autobuilder = CreateAutoBuilder("csharp", false);
- TestAutobuilderScript(autobuilder, 1, 2);
+ TestAutobuilderScript(autobuilder, 1, 3);
}
[Fact]
@@ -874,12 +882,12 @@ Microsoft.NETCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
[Fact]
public void TestSkipNugetDotnet()
{
- Actions.RunProcess["dotnet --info"] = 0;
- Actions.RunProcess["dotnet clean test.csproj"] = 0;
- Actions.RunProcess["dotnet restore test.csproj"] = 0;
Actions.RunProcess["dotnet --list-runtimes"] = 0;
Actions.RunProcessOut["dotnet --list-runtimes"] = @"Microsoft.AspNetCore.App 2.1.3 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.1.3 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]";
+ Actions.RunProcess["dotnet --info"] = 0;
+ Actions.RunProcess["dotnet clean test.csproj"] = 0;
+ Actions.RunProcess["dotnet restore test.csproj"] = 0;
Actions.RunProcess[@"C:\odasa/tools/odasa index --auto dotnet build --no-incremental /p:UseSharedCompilation=false --no-restore test.csproj"] = 0;
Actions.RunProcess[@"C:\codeql\tools\java/bin/java -jar C:\codeql\csharp/tools/extractor-asp.jar ."] = 0;
Actions.RunProcess[@"C:\odasa/tools/odasa index --xml --extensions config csproj props xml"] = 0;
@@ -912,12 +920,12 @@ Microsoft.NETCore.App 2.1.3 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
Actions.RunProcess[@"chmod u+x dotnet-install.sh"] = 0;
Actions.RunProcess[@"./dotnet-install.sh --channel release --version 2.1.3 --install-dir C:\Project/.dotnet"] = 0;
Actions.RunProcess[@"rm dotnet-install.sh"] = 0;
- Actions.RunProcess[@"C:\Project/.dotnet/dotnet --info"] = 0;
- Actions.RunProcess[@"C:\Project/.dotnet/dotnet clean test.csproj"] = 0;
- Actions.RunProcess[@"C:\Project/.dotnet/dotnet restore test.csproj"] = 0;
Actions.RunProcess[@"C:\Project/.dotnet/dotnet --list-runtimes"] = 0;
Actions.RunProcessOut[@"C:\Project/.dotnet/dotnet --list-runtimes"] = @"Microsoft.AspNetCore.App 3.0.0 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 3.0.0 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]";
+ Actions.RunProcess[@"C:\Project/.dotnet/dotnet --info"] = 0;
+ Actions.RunProcess[@"C:\Project/.dotnet/dotnet clean test.csproj"] = 0;
+ Actions.RunProcess[@"C:\Project/.dotnet/dotnet restore test.csproj"] = 0;
Actions.RunProcess[@"C:\odasa/tools/odasa index --auto C:\Project/.dotnet/dotnet build --no-incremental test.csproj"] = 0;
Actions.RunProcess[@"C:\codeql\tools\java/bin/java -jar C:\codeql\csharp/tools/extractor-asp.jar ."] = 0;
Actions.RunProcess[@"C:\odasa/tools/odasa index --xml --extensions config csproj props xml"] = 0;
@@ -952,14 +960,14 @@ Microsoft.NETCore.App 3.0.0 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
Actions.RunProcess[@"chmod u+x dotnet-install.sh"] = 0;
Actions.RunProcess[@"./dotnet-install.sh --channel release --version 2.1.3 --install-dir C:\Project/.dotnet"] = 0;
Actions.RunProcess[@"rm dotnet-install.sh"] = 0;
- Actions.RunProcess[@"C:\Project/.dotnet/dotnet --info"] = 0;
- Actions.RunProcess[@"C:\Project/.dotnet/dotnet clean test.csproj"] = 0;
- Actions.RunProcess[@"C:\Project/.dotnet/dotnet restore test.csproj"] = 0;
Actions.RunProcess[@"C:\Project/.dotnet/dotnet --list-runtimes"] = 0;
Actions.RunProcessOut[@"C:\Project/.dotnet/dotnet --list-runtimes"] = @"Microsoft.AspNetCore.App 2.1.3 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.4 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.1.3 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.4 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]";
+ Actions.RunProcess[@"C:\Project/.dotnet/dotnet --info"] = 0;
+ Actions.RunProcess[@"C:\Project/.dotnet/dotnet clean test.csproj"] = 0;
+ Actions.RunProcess[@"C:\Project/.dotnet/dotnet restore test.csproj"] = 0;
Actions.RunProcess[@"C:\odasa/tools/odasa index --auto C:\Project/.dotnet/dotnet build --no-incremental /p:UseSharedCompilation=false test.csproj"] = 0;
Actions.RunProcess[@"C:\codeql\tools\java/bin/java -jar C:\codeql\csharp/tools/extractor-asp.jar ."] = 0;
Actions.RunProcess[@"C:\odasa/tools/odasa index --xml --extensions config csproj props xml"] = 0;
diff --git a/csharp/autobuilder/Semmle.Autobuild/BuildCommandAutoRule.cs b/csharp/autobuilder/Semmle.Autobuild/BuildCommandAutoRule.cs
index 09c41ccf74c..e7e2c9255dd 100644
--- a/csharp/autobuilder/Semmle.Autobuild/BuildCommandAutoRule.cs
+++ b/csharp/autobuilder/Semmle.Autobuild/BuildCommandAutoRule.cs
@@ -43,9 +43,9 @@ namespace Semmle.Autobuild
var dir = Path.GetDirectoryName(scriptPath);
// A specific .NET Core version may be required
- return chmodScript & DotNetRule.WithDotNet(builder, dotNet =>
+ return chmodScript & DotNetRule.WithDotNet(builder, environment =>
{
- var command = new CommandBuilder(builder.Actions, dir, dotNet?.Environment);
+ var command = new CommandBuilder(builder.Actions, dir, environment);
// A specific Visual Studio version may be required
var vsTools = MsBuildRule.GetVcVarsBatFile(builder);
diff --git a/csharp/autobuilder/Semmle.Autobuild/BuildCommandRule.cs b/csharp/autobuilder/Semmle.Autobuild/BuildCommandRule.cs
index 2e582b707f2..fe91503ec8f 100644
--- a/csharp/autobuilder/Semmle.Autobuild/BuildCommandRule.cs
+++ b/csharp/autobuilder/Semmle.Autobuild/BuildCommandRule.cs
@@ -11,9 +11,9 @@
return BuildScript.Failure;
// Custom build commands may require a specific .NET Core version
- return DotNetRule.WithDotNet(builder, dotNet =>
+ return DotNetRule.WithDotNet(builder, environment =>
{
- var command = new CommandBuilder(builder.Actions, null, dotNet?.Environment);
+ var command = new CommandBuilder(builder.Actions, null, environment);
// Custom build commands may require a specific Visual Studio version
var vsTools = MsBuildRule.GetVcVarsBatFile(builder);
diff --git a/csharp/autobuilder/Semmle.Autobuild/DotNetRule.cs b/csharp/autobuilder/Semmle.Autobuild/DotNetRule.cs
index d44f32e4b56..c9b33cef8d1 100644
--- a/csharp/autobuilder/Semmle.Autobuild/DotNetRule.cs
+++ b/csharp/autobuilder/Semmle.Autobuild/DotNetRule.cs
@@ -35,20 +35,20 @@ namespace Semmle.Autobuild
builder.Log(Severity.Info, "Attempting to build using .NET Core");
}
- return WithDotNet(builder, dotNet =>
+ return WithDotNet(builder, (dotNetPath, environment, compatibleClr) =>
{
- var ret = GetInfoCommand(builder.Actions, dotNet);
+ var ret = GetInfoCommand(builder.Actions, dotNetPath, environment);
foreach (var projectOrSolution in builder.ProjectsOrSolutionsToBuild)
{
- var cleanCommand = GetCleanCommand(builder.Actions, dotNet);
+ var cleanCommand = GetCleanCommand(builder.Actions, dotNetPath, environment);
cleanCommand.QuoteArgument(projectOrSolution.FullPath);
var clean = cleanCommand.Script;
- var restoreCommand = GetRestoreCommand(builder.Actions, dotNet);
+ var restoreCommand = GetRestoreCommand(builder.Actions, dotNetPath, environment);
restoreCommand.QuoteArgument(projectOrSolution.FullPath);
var restore = restoreCommand.Script;
- var build = GetBuildScript(builder, dotNet, projectOrSolution.FullPath);
+ var build = GetBuildScript(builder, dotNetPath, environment, compatibleClr, projectOrSolution.FullPath);
ret &= clean & BuildScript.Try(restore) & build;
}
@@ -56,38 +56,73 @@ namespace Semmle.Autobuild
});
}
- ///
- /// Returns a script that attempts to download relevant version(s) of the
- /// .NET Core SDK, followed by running the script generated by .
- ///
- /// The first element DotNetPath of the argument to
- /// is the path where .NET Core was installed, and the second element Environment
- /// is any additional required environment variables. The tuple argument is null
- /// when the installation failed.
- ///
- public static BuildScript WithDotNet(Autobuilder builder, Func<(string DotNetPath, IDictionary Environment)?, BuildScript> f)
+ static BuildScript WithDotNet(Autobuilder builder, Func, bool, BuildScript> f)
{
var installDir = builder.Actions.PathCombine(builder.Options.RootDirectory, ".dotnet");
var installScript = DownloadDotNet(builder, installDir);
return BuildScript.Bind(installScript, installed =>
+ {
+ Dictionary env;
+ if (installed == 0)
{
- if (installed == 0)
- {
- // The installation succeeded, so use the newly installed .NET Core
- var path = builder.Actions.GetEnvironmentVariable("PATH");
- var delim = builder.Actions.IsWindows() ? ";" : ":";
- var env = new Dictionary{
+ // The installation succeeded, so use the newly installed .NET Core
+ var path = builder.Actions.GetEnvironmentVariable("PATH");
+ var delim = builder.Actions.IsWindows() ? ";" : ":";
+ env = new Dictionary{
{ "DOTNET_MULTILEVEL_LOOKUP", "false" }, // prevent look up of other .NET Core SDKs
{ "DOTNET_SKIP_FIRST_TIME_EXPERIENCE", "true" },
{ "PATH", installDir + delim + path }
};
- return f((installDir, env));
+ }
+ else
+ {
+ installDir = null;
+ env = null;
+ }
+
+ // The CLR tracer is always compatible on Windows
+ if (builder.Actions.IsWindows())
+ return f(installDir, env, true);
+
+ // The CLR tracer is only compatible on .NET Core >= 3 on Linux and macOS (see
+ // https://github.com/dotnet/coreclr/issues/19622)
+ return BuildScript.Bind(GetInstalledRuntimesScript(builder.Actions, installDir, env), (runtimes, runtimesRet) =>
+ {
+ var compatibleClr = false;
+ if (runtimesRet == 0)
+ {
+ var minimumVersion = new Version(3, 0);
+ var regex = new Regex(@"Microsoft\.NETCore\.App (\d\.\d\.\d)");
+ compatibleClr = runtimes.
+ Select(runtime => regex.Match(runtime)).
+ Where(m => m.Success).
+ Select(m => m.Groups[1].Value).
+ Any(m => Version.TryParse(m, out var v) && v >= minimumVersion);
}
- return f(null);
+ if (!compatibleClr)
+ {
+ if (env == null)
+ env = new Dictionary();
+ env.Add("UseSharedCompilation", "false");
+ }
+
+ return f(installDir, env, compatibleClr);
});
+ });
}
+ ///
+ /// Returns a script that attempts to download relevant version(s) of the
+ /// .NET Core SDK, followed by running the script generated by .
+ ///
+ /// The argument to is any additional required environment
+ /// variables needed by the installed .NET Core (null when no variables
+ /// are needed).
+ ///
+ public static BuildScript WithDotNet(Autobuilder builder, Func, BuildScript> f)
+ => WithDotNet(builder, (_1, env, _2) => f(env));
+
///
/// Returns a script for downloading relevant versions of the
/// .NET Core SDK. The SDK(s) will be installed at installDir
@@ -233,34 +268,34 @@ Invoke-Command -ScriptBlock $ScriptBlock";
static string DotNetCommand(IBuildActions actions, string dotNetPath) =>
dotNetPath != null ? actions.PathCombine(dotNetPath, "dotnet") : "dotnet";
- BuildScript GetInfoCommand(IBuildActions actions, (string DotNetPath, IDictionary Environment)? arg)
+ BuildScript GetInfoCommand(IBuildActions actions, string dotNetPath, IDictionary environment)
{
- var info = new CommandBuilder(actions, null, arg?.Environment).
- RunCommand(DotNetCommand(actions, arg?.DotNetPath)).
+ var info = new CommandBuilder(actions, null, environment).
+ RunCommand(DotNetCommand(actions, dotNetPath)).
Argument("--info");
return info.Script;
}
- CommandBuilder GetCleanCommand(IBuildActions actions, (string DotNetPath, IDictionary Environment)? arg)
+ CommandBuilder GetCleanCommand(IBuildActions actions, string dotNetPath, IDictionary environment)
{
- var clean = new CommandBuilder(actions, null, arg?.Environment).
- RunCommand(DotNetCommand(actions, arg?.DotNetPath)).
+ var clean = new CommandBuilder(actions, null, environment).
+ RunCommand(DotNetCommand(actions, dotNetPath)).
Argument("clean");
return clean;
}
- CommandBuilder GetRestoreCommand(IBuildActions actions, (string DotNetPath, IDictionary Environment)? arg)
+ CommandBuilder GetRestoreCommand(IBuildActions actions, string dotNetPath, IDictionary environment)
{
- var restore = new CommandBuilder(actions, null, arg?.Environment).
- RunCommand(DotNetCommand(actions, arg?.DotNetPath)).
+ var restore = new CommandBuilder(actions, null, environment).
+ RunCommand(DotNetCommand(actions, dotNetPath)).
Argument("restore");
return restore;
}
- static BuildScript GetInstalledRuntimesScript(IBuildActions actions, (string DotNetPath, IDictionary Environment)? arg)
+ static BuildScript GetInstalledRuntimesScript(IBuildActions actions, string dotNetPath, IDictionary environment)
{
- var listSdks = new CommandBuilder(actions, environment: arg?.Environment, silent: true).
- RunCommand(DotNetCommand(actions, arg?.DotNetPath)).
+ var listSdks = new CommandBuilder(actions, environment: environment, silent: true).
+ RunCommand(DotNetCommand(actions, dotNetPath)).
Argument("--list-runtimes");
return listSdks.Script;
}
@@ -274,39 +309,21 @@ Invoke-Command -ScriptBlock $ScriptBlock";
/// hence the need for CLR tracing), by adding a
/// `/p:UseSharedCompilation=false` argument.
///
- BuildScript GetBuildScript(Autobuilder builder, (string DotNetPath, IDictionary Environment)? arg, string projOrSln)
+ BuildScript GetBuildScript(Autobuilder builder, string dotNetPath, IDictionary environment, bool compatibleClr, string projOrSln)
{
- var build = new CommandBuilder(builder.Actions, null, arg?.Environment);
- var script = builder.MaybeIndex(build, DotNetCommand(builder.Actions, arg?.DotNetPath)).
+ var build = new CommandBuilder(builder.Actions, null, environment);
+ var script = builder.MaybeIndex(build, DotNetCommand(builder.Actions, dotNetPath)).
Argument("build").
Argument("--no-incremental");
- if (builder.Actions.IsWindows())
- return script.Argument(builder.Options.DotNetArguments).
+ return compatibleClr ?
+ script.Argument(builder.Options.DotNetArguments).
+ QuoteArgument(projOrSln).
+ Script :
+ script.Argument("/p:UseSharedCompilation=false").
+ Argument(builder.Options.DotNetArguments).
QuoteArgument(projOrSln).
Script;
-
- return BuildScript.Bind(GetInstalledRuntimesScript(builder.Actions, arg), (runtimes, runtimesRet) =>
- {
- var compatibleClr = false;
- if (runtimesRet == 0)
- {
- var regex = new Regex(@"Microsoft\.NETCore\.App (\d)");
- compatibleClr = runtimes.
- Select(runtime => regex.Match(runtime)).
- Where(m => m.Success).
- Any(m => int.TryParse(m.Groups[1].Value, out var version) && version >= 3);
- }
-
- return compatibleClr ?
- script.Argument(builder.Options.DotNetArguments).
- QuoteArgument(projOrSln).
- Script :
- script.Argument("/p:UseSharedCompilation=false").
- Argument(builder.Options.DotNetArguments).
- QuoteArgument(projOrSln).
- Script;
- });
}
}
}
From 37f162106a29b7c747b76b859848c4c6bee99613 Mon Sep 17 00:00:00 2001
From: Cornelius Riemenschneider
Date: Mon, 25 Nov 2019 17:04:38 +0100
Subject: [PATCH 38/44] Fix formatting of file.
---
java/ql/src/semmle/code/java/dataflow/Nullness.qll | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/java/ql/src/semmle/code/java/dataflow/Nullness.qll b/java/ql/src/semmle/code/java/dataflow/Nullness.qll
index f6d92b78da7..c3faeaf0ff2 100644
--- a/java/ql/src/semmle/code/java/dataflow/Nullness.qll
+++ b/java/ql/src/semmle/code/java/dataflow/Nullness.qll
@@ -522,7 +522,7 @@ private predicate correlatedConditions(
inverted = false
)
or
- exists(SsaVariable v1, SsaVariable v2, boolean branch1, boolean branch2 |
+ exists(SsaVariable v1, SsaVariable v2, boolean branch1, boolean branch2 |
cond1.getCondition() = varEqualityTestExpr(v1, v2, branch1) and
cond2.getCondition() = varEqualityTestExpr(v1, v2, branch2) and
inverted = branch1.booleanXor(branch2)
From 521fbb125e7466fb65d312f7c93ab4314ac2c6c7 Mon Sep 17 00:00:00 2001
From: Dave Bartolomeo
Date: Mon, 25 Nov 2019 11:12:23 -0700
Subject: [PATCH 39/44] C++/C#: Fix formatting
---
.../cpp/ir/implementation/unaliased_ssa/internal/SSASanity.ql | 2 +-
.../ir/implementation/unaliased_ssa/internal/SSASanity.ql | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSASanity.ql b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSASanity.ql
index b67f6f281be..1b5ee80b603 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSASanity.ql
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSASanity.ql
@@ -1,6 +1,6 @@
/**
* @name Unaliased SSA Sanity Check
- * @description Performs sanity checks on the SSA construction. This query should have no results.
+ * @description Performs sanity checks on the SSA construction. This query should have no results.
* @kind table
* @id cpp/unaliased-ssa-sanity-check
*/
diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSASanity.ql b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSASanity.ql
index 11d7add514b..43f303dd024 100644
--- a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSASanity.ql
+++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSASanity.ql
@@ -1,6 +1,6 @@
/**
* @name Unaliased SSA Sanity Check
- * @description Performs sanity checks on the SSA construction. This query should have no results.
+ * @description Performs sanity checks on the SSA construction. This query should have no results.
* @kind table
* @id csharp/unaliased-ssa-sanity-check
*/
From 44c1c5a7abb24641e18413d8ab98c067edd807e4 Mon Sep 17 00:00:00 2001
From: Dave Bartolomeo
Date: Mon, 25 Nov 2019 11:13:02 -0700
Subject: [PATCH 40/44] C++: Update `points_to.ql` test to use new bit offset
format
---
.../aliased_ssa/internal/AliasAnalysis.qll | 26 +--
.../unaliased_ssa/internal/AliasAnalysis.qll | 26 +--
.../ir/escape/points_to.expected | 172 +++++++++---------
.../test/library-tests/ir/escape/points_to.ql | 9 +-
4 files changed, 101 insertions(+), 132 deletions(-)
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasAnalysis.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasAnalysis.qll
index 6ecfd1470bb..bc67acc1be2 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasAnalysis.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasAnalysis.qll
@@ -6,26 +6,6 @@ private import semmle.code.cpp.models.interfaces.Alias
private class IntValue = Ints::IntValue;
-/**
- * Converts the bit count in `bits` to a byte count and a bit count in the form
- * bytes:bits.
- */
-bindingset[bits]
-string bitsToBytesAndBits(int bits) { result = (bits / 8).toString() + ":" + (bits % 8).toString() }
-
-/**
- * Gets a printable string for a bit offset with possibly unknown value.
- */
-bindingset[bitOffset]
-string getBitOffsetString(IntValue bitOffset) {
- if Ints::hasValue(bitOffset)
- then
- if bitOffset >= 0
- then result = "+" + bitsToBytesAndBits(bitOffset)
- else result = "-" + bitsToBytesAndBits(Ints::neg(bitOffset))
- else result = "+?"
-}
-
/**
* Gets the offset of field `field` in bits.
*/
@@ -137,7 +117,11 @@ private predicate operandIsPropagated(Operand operand, IntValue bitOffset) {
or
// Adding an integer to or subtracting an integer from a pointer propagates
// the address with an offset.
- bitOffset = getPointerBitOffset(instr.(PointerOffsetInstruction))
+ exists(PointerOffsetInstruction ptrOffset |
+ ptrOffset = instr and
+ operand = ptrOffset.getLeftOperand() and
+ bitOffset = getPointerBitOffset(ptrOffset)
+ )
or
// Computing a field address from a pointer propagates the address plus the
// offset of the field.
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/AliasAnalysis.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/AliasAnalysis.qll
index 6ecfd1470bb..bc67acc1be2 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/AliasAnalysis.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/AliasAnalysis.qll
@@ -6,26 +6,6 @@ private import semmle.code.cpp.models.interfaces.Alias
private class IntValue = Ints::IntValue;
-/**
- * Converts the bit count in `bits` to a byte count and a bit count in the form
- * bytes:bits.
- */
-bindingset[bits]
-string bitsToBytesAndBits(int bits) { result = (bits / 8).toString() + ":" + (bits % 8).toString() }
-
-/**
- * Gets a printable string for a bit offset with possibly unknown value.
- */
-bindingset[bitOffset]
-string getBitOffsetString(IntValue bitOffset) {
- if Ints::hasValue(bitOffset)
- then
- if bitOffset >= 0
- then result = "+" + bitsToBytesAndBits(bitOffset)
- else result = "-" + bitsToBytesAndBits(Ints::neg(bitOffset))
- else result = "+?"
-}
-
/**
* Gets the offset of field `field` in bits.
*/
@@ -137,7 +117,11 @@ private predicate operandIsPropagated(Operand operand, IntValue bitOffset) {
or
// Adding an integer to or subtracting an integer from a pointer propagates
// the address with an offset.
- bitOffset = getPointerBitOffset(instr.(PointerOffsetInstruction))
+ exists(PointerOffsetInstruction ptrOffset |
+ ptrOffset = instr and
+ operand = ptrOffset.getLeftOperand() and
+ bitOffset = getPointerBitOffset(ptrOffset)
+ )
or
// Computing a field address from a pointer propagates the address plus the
// offset of the field.
diff --git a/cpp/ql/test/library-tests/ir/escape/points_to.expected b/cpp/ql/test/library-tests/ir/escape/points_to.expected
index ac518b5dd79..6447bd81a5f 100644
--- a/cpp/ql/test/library-tests/ir/escape/points_to.expected
+++ b/cpp/ql/test/library-tests/ir/escape/points_to.expected
@@ -1,86 +1,86 @@
-| escape.cpp:111:18:111:21 | CopyValue | no_+0:0 | no_+0:0 |
-| escape.cpp:115:19:115:28 | PointerAdd[4] | no_+0:0 | no_+0:0 |
-| escape.cpp:115:20:115:23 | CopyValue | no_+0:0 | no_+0:0 |
-| escape.cpp:116:19:116:28 | PointerSub[4] | no_+0:0 | no_+0:0 |
-| escape.cpp:116:20:116:23 | CopyValue | no_+0:0 | no_+0:0 |
-| escape.cpp:117:19:117:26 | PointerAdd[4] | no_+0:0 | no_+0:0 |
-| escape.cpp:117:23:117:26 | CopyValue | no_+0:0 | no_+0:0 |
-| escape.cpp:118:9:118:12 | CopyValue | no_+0:0 | no_+0:0 |
-| escape.cpp:120:12:120:15 | CopyValue | no_+0:0 | no_+0:0 |
-| escape.cpp:123:14:123:17 | CopyValue | no_+0:0 | no_+0:0 |
-| escape.cpp:124:15:124:18 | CopyValue | no_+0:0 | no_+0:0 |
-| escape.cpp:127:9:127:12 | CopyValue | no_+0:0 | no_+0:0 |
-| escape.cpp:129:12:129:15 | CopyValue | no_+0:0 | no_+0:0 |
-| escape.cpp:134:5:134:18 | Convert | no_Array+0:0 | no_Array+0:0 |
-| escape.cpp:134:11:134:18 | Convert | no_Array+0:0 | no_Array+0:0 |
-| escape.cpp:135:5:135:12 | Convert | no_Array+0:0 | no_Array+0:0 |
-| escape.cpp:135:5:135:15 | PointerAdd[4] | no_Array+20:0 | no_Array+20:0 |
-| escape.cpp:136:5:136:15 | PointerAdd[4] | no_Array+20:0 | no_Array+20:0 |
-| escape.cpp:136:7:136:14 | Convert | no_Array+0:0 | no_Array+0:0 |
-| escape.cpp:137:17:137:24 | Convert | no_Array+0:0 | no_Array+0:0 |
-| escape.cpp:137:17:137:27 | PointerAdd[4] | no_Array+20:0 | no_Array+20:0 |
-| escape.cpp:138:17:138:27 | PointerAdd[4] | no_Array+20:0 | no_Array+20:0 |
-| escape.cpp:138:19:138:26 | Convert | no_Array+0:0 | no_Array+0:0 |
-| escape.cpp:140:21:140:32 | FieldAddress[x] | no_Point+0:0 | no_Point+0:0 |
-| escape.cpp:140:21:140:32 | FieldAddress[y] | no_Point+4:0 | no_Point+4:0 |
-| escape.cpp:140:21:140:32 | FieldAddress[z] | no_Point+8:0 | no_Point+8:0 |
-| escape.cpp:141:27:141:27 | FieldAddress[x] | no_Point+0:0 | no_Point+0:0 |
-| escape.cpp:142:14:142:14 | FieldAddress[y] | no_Point+4:0 | no_Point+4:0 |
-| escape.cpp:143:19:143:27 | CopyValue | no_Point+0:0 | no_Point+0:0 |
-| escape.cpp:143:31:143:31 | FieldAddress[y] | no_Point+4:0 | no_Point+4:0 |
-| escape.cpp:144:6:144:14 | CopyValue | no_Point+0:0 | no_Point+0:0 |
-| escape.cpp:144:18:144:18 | FieldAddress[y] | no_Point+4:0 | no_Point+4:0 |
-| escape.cpp:145:20:145:30 | CopyValue | no_Point+8:0 | no_Point+8:0 |
-| escape.cpp:145:30:145:30 | FieldAddress[z] | no_Point+8:0 | no_Point+8:0 |
-| escape.cpp:146:5:146:18 | CopyValue | no_Point+8:0 | no_Point+8:0 |
-| escape.cpp:146:7:146:17 | CopyValue | no_Point+8:0 | no_Point+8:0 |
-| escape.cpp:146:17:146:17 | FieldAddress[z] | no_Point+8:0 | no_Point+8:0 |
-| escape.cpp:149:5:149:14 | ConvertToNonVirtualBase[Derived : Intermediate1] | no_Derived+0:0 | no_Derived+0:0 |
-| escape.cpp:149:5:149:14 | ConvertToNonVirtualBase[Intermediate1 : Base] | no_Derived+0:0 | no_Derived+0:0 |
-| escape.cpp:149:16:149:16 | FieldAddress[b] | no_Derived+0:0 | no_Derived+0:0 |
-| escape.cpp:150:18:150:27 | ConvertToNonVirtualBase[Derived : Intermediate1] | no_Derived+0:0 | no_Derived+0:0 |
-| escape.cpp:150:18:150:27 | ConvertToNonVirtualBase[Intermediate1 : Base] | no_Derived+0:0 | no_Derived+0:0 |
-| escape.cpp:150:29:150:29 | FieldAddress[b] | no_Derived+0:0 | no_Derived+0:0 |
-| escape.cpp:151:5:151:14 | ConvertToNonVirtualBase[Derived : Intermediate2] | no_Derived+12:0 | no_Derived+12:0 |
-| escape.cpp:151:16:151:17 | FieldAddress[i2] | no_Derived+16:0 | no_Derived+16:0 |
-| escape.cpp:152:19:152:28 | ConvertToNonVirtualBase[Derived : Intermediate2] | no_Derived+12:0 | no_Derived+12:0 |
-| escape.cpp:152:30:152:31 | FieldAddress[i2] | no_Derived+16:0 | no_Derived+16:0 |
-| escape.cpp:155:17:155:30 | CopyValue | no_ssa_addrOf+0:0 | no_ssa_addrOf+0:0 |
-| escape.cpp:155:17:155:30 | Store | no_ssa_addrOf+0:0 | no_ssa_addrOf+0:0 |
-| escape.cpp:158:17:158:28 | CopyValue | no_ssa_refTo+0:0 | no_ssa_refTo+0:0 |
-| escape.cpp:158:17:158:28 | Store | no_ssa_refTo+0:0 | no_ssa_refTo+0:0 |
-| escape.cpp:161:19:161:42 | Convert | no_ssa_refToArrayElement+0:0 | no_ssa_refToArrayElement+0:0 |
-| escape.cpp:161:19:161:45 | CopyValue | no_ssa_refToArrayElement+20:0 | no_ssa_refToArrayElement+20:0 |
-| escape.cpp:161:19:161:45 | PointerAdd[4] | no_ssa_refToArrayElement+20:0 | no_ssa_refToArrayElement+20:0 |
-| escape.cpp:161:19:161:45 | Store | no_ssa_refToArrayElement+20:0 | no_ssa_refToArrayElement+20:0 |
-| escape.cpp:164:24:164:40 | CopyValue | no_ssa_refToArray+0:0 | no_ssa_refToArray+0:0 |
-| escape.cpp:164:24:164:40 | Store | no_ssa_refToArray+0:0 | no_ssa_refToArray+0:0 |
-| escape.cpp:167:19:167:28 | CopyValue | passByPtr+0:0 | passByPtr+0:0 |
-| escape.cpp:170:21:170:29 | CopyValue | passByRef+0:0 | passByRef+0:0 |
-| escape.cpp:173:22:173:38 | CopyValue | no_ssa_passByPtr+0:0 | no_ssa_passByPtr+0:0 |
-| escape.cpp:176:24:176:39 | CopyValue | no_ssa_passByRef+0:0 | no_ssa_passByRef+0:0 |
-| escape.cpp:179:22:179:42 | CopyValue | no_ssa_passByPtr_ret+0:0 | no_ssa_passByPtr_ret+0:0 |
-| escape.cpp:182:24:182:43 | CopyValue | no_ssa_passByRef_ret+0:0 | no_ssa_passByRef_ret+0:0 |
-| escape.cpp:185:30:185:40 | CopyValue | passByPtr2+0:0 | passByPtr2+0:0 |
-| escape.cpp:188:32:188:41 | CopyValue | passByRef2+0:0 | passByRef2+0:0 |
-| escape.cpp:191:30:191:42 | Call | none | passByPtr3+0:0 |
-| escape.cpp:191:44:191:54 | CopyValue | passByPtr3+0:0 | passByPtr3+0:0 |
-| escape.cpp:194:32:194:46 | Call | none | passByRef3+0:0 |
-| escape.cpp:194:32:194:59 | CopyValue | none | passByRef3+0:0 |
-| escape.cpp:194:48:194:57 | CopyValue | passByRef3+0:0 | passByRef3+0:0 |
-| escape.cpp:199:17:199:34 | CopyValue | no_ssa_passByPtr4+0:0 | no_ssa_passByPtr4+0:0 |
-| escape.cpp:199:37:199:54 | CopyValue | no_ssa_passByPtr5+0:0 | no_ssa_passByPtr5+0:0 |
-| escape.cpp:202:5:202:19 | Call | none | passByRef6+0:0 |
-| escape.cpp:202:5:202:32 | CopyValue | none | passByRef6+0:0 |
-| escape.cpp:202:21:202:30 | CopyValue | passByRef6+0:0 | passByRef6+0:0 |
-| escape.cpp:205:5:205:19 | Call | none | no_ssa_passByRef7+0:0 |
-| escape.cpp:205:5:205:39 | CopyValue | none | no_ssa_passByRef7+0:0 |
-| escape.cpp:205:21:205:37 | CopyValue | no_ssa_passByRef7+0:0 | no_ssa_passByRef7+0:0 |
-| escape.cpp:209:14:209:25 | Call | none | no_ssa_c+0:0 |
-| escape.cpp:217:14:217:16 | CopyValue | c2+0:0 | c2+0:0 |
-| escape.cpp:221:8:221:19 | Call | none | c3+0:0 |
-| escape.cpp:225:17:225:28 | Call | none | c4+0:0 |
-| escape.cpp:247:2:247:27 | Store | condEscape1+0:0 | condEscape1+0:0 |
-| escape.cpp:247:16:247:27 | CopyValue | condEscape1+0:0 | condEscape1+0:0 |
-| escape.cpp:249:9:249:34 | Store | condEscape2+0:0 | condEscape2+0:0 |
-| escape.cpp:249:23:249:34 | CopyValue | condEscape2+0:0 | condEscape2+0:0 |
+| escape.cpp:111:18:111:21 | CopyValue | no_+0 | no_+0 |
+| escape.cpp:115:19:115:28 | PointerAdd[4] | no_+0 | no_+0 |
+| escape.cpp:115:20:115:23 | CopyValue | no_+0 | no_+0 |
+| escape.cpp:116:19:116:28 | PointerSub[4] | no_+0 | no_+0 |
+| escape.cpp:116:20:116:23 | CopyValue | no_+0 | no_+0 |
+| escape.cpp:117:19:117:26 | PointerAdd[4] | no_+0 | no_+0 |
+| escape.cpp:117:23:117:26 | CopyValue | no_+0 | no_+0 |
+| escape.cpp:118:9:118:12 | CopyValue | no_+0 | no_+0 |
+| escape.cpp:120:12:120:15 | CopyValue | no_+0 | no_+0 |
+| escape.cpp:123:14:123:17 | CopyValue | no_+0 | no_+0 |
+| escape.cpp:124:15:124:18 | CopyValue | no_+0 | no_+0 |
+| escape.cpp:127:9:127:12 | CopyValue | no_+0 | no_+0 |
+| escape.cpp:129:12:129:15 | CopyValue | no_+0 | no_+0 |
+| escape.cpp:134:5:134:18 | Convert | no_Array+0 | no_Array+0 |
+| escape.cpp:134:11:134:18 | Convert | no_Array+0 | no_Array+0 |
+| escape.cpp:135:5:135:12 | Convert | no_Array+0 | no_Array+0 |
+| escape.cpp:135:5:135:15 | PointerAdd[4] | no_Array+20 | no_Array+20 |
+| escape.cpp:136:5:136:15 | PointerAdd[4] | no_Array+20 | no_Array+20 |
+| escape.cpp:136:7:136:14 | Convert | no_Array+0 | no_Array+0 |
+| escape.cpp:137:17:137:24 | Convert | no_Array+0 | no_Array+0 |
+| escape.cpp:137:17:137:27 | PointerAdd[4] | no_Array+20 | no_Array+20 |
+| escape.cpp:138:17:138:27 | PointerAdd[4] | no_Array+20 | no_Array+20 |
+| escape.cpp:138:19:138:26 | Convert | no_Array+0 | no_Array+0 |
+| escape.cpp:140:21:140:32 | FieldAddress[x] | no_Point+0 | no_Point+0 |
+| escape.cpp:140:21:140:32 | FieldAddress[y] | no_Point+4 | no_Point+4 |
+| escape.cpp:140:21:140:32 | FieldAddress[z] | no_Point+8 | no_Point+8 |
+| escape.cpp:141:27:141:27 | FieldAddress[x] | no_Point+0 | no_Point+0 |
+| escape.cpp:142:14:142:14 | FieldAddress[y] | no_Point+4 | no_Point+4 |
+| escape.cpp:143:19:143:27 | CopyValue | no_Point+0 | no_Point+0 |
+| escape.cpp:143:31:143:31 | FieldAddress[y] | no_Point+4 | no_Point+4 |
+| escape.cpp:144:6:144:14 | CopyValue | no_Point+0 | no_Point+0 |
+| escape.cpp:144:18:144:18 | FieldAddress[y] | no_Point+4 | no_Point+4 |
+| escape.cpp:145:20:145:30 | CopyValue | no_Point+8 | no_Point+8 |
+| escape.cpp:145:30:145:30 | FieldAddress[z] | no_Point+8 | no_Point+8 |
+| escape.cpp:146:5:146:18 | CopyValue | no_Point+8 | no_Point+8 |
+| escape.cpp:146:7:146:17 | CopyValue | no_Point+8 | no_Point+8 |
+| escape.cpp:146:17:146:17 | FieldAddress[z] | no_Point+8 | no_Point+8 |
+| escape.cpp:149:5:149:14 | ConvertToNonVirtualBase[Derived : Intermediate1] | no_Derived+0 | no_Derived+0 |
+| escape.cpp:149:5:149:14 | ConvertToNonVirtualBase[Intermediate1 : Base] | no_Derived+0 | no_Derived+0 |
+| escape.cpp:149:16:149:16 | FieldAddress[b] | no_Derived+0 | no_Derived+0 |
+| escape.cpp:150:18:150:27 | ConvertToNonVirtualBase[Derived : Intermediate1] | no_Derived+0 | no_Derived+0 |
+| escape.cpp:150:18:150:27 | ConvertToNonVirtualBase[Intermediate1 : Base] | no_Derived+0 | no_Derived+0 |
+| escape.cpp:150:29:150:29 | FieldAddress[b] | no_Derived+0 | no_Derived+0 |
+| escape.cpp:151:5:151:14 | ConvertToNonVirtualBase[Derived : Intermediate2] | no_Derived+12 | no_Derived+12 |
+| escape.cpp:151:16:151:17 | FieldAddress[i2] | no_Derived+16 | no_Derived+16 |
+| escape.cpp:152:19:152:28 | ConvertToNonVirtualBase[Derived : Intermediate2] | no_Derived+12 | no_Derived+12 |
+| escape.cpp:152:30:152:31 | FieldAddress[i2] | no_Derived+16 | no_Derived+16 |
+| escape.cpp:155:17:155:30 | CopyValue | no_ssa_addrOf+0 | no_ssa_addrOf+0 |
+| escape.cpp:155:17:155:30 | Store | no_ssa_addrOf+0 | no_ssa_addrOf+0 |
+| escape.cpp:158:17:158:28 | CopyValue | no_ssa_refTo+0 | no_ssa_refTo+0 |
+| escape.cpp:158:17:158:28 | Store | no_ssa_refTo+0 | no_ssa_refTo+0 |
+| escape.cpp:161:19:161:42 | Convert | no_ssa_refToArrayElement+0 | no_ssa_refToArrayElement+0 |
+| escape.cpp:161:19:161:45 | CopyValue | no_ssa_refToArrayElement+20 | no_ssa_refToArrayElement+20 |
+| escape.cpp:161:19:161:45 | PointerAdd[4] | no_ssa_refToArrayElement+20 | no_ssa_refToArrayElement+20 |
+| escape.cpp:161:19:161:45 | Store | no_ssa_refToArrayElement+20 | no_ssa_refToArrayElement+20 |
+| escape.cpp:164:24:164:40 | CopyValue | no_ssa_refToArray+0 | no_ssa_refToArray+0 |
+| escape.cpp:164:24:164:40 | Store | no_ssa_refToArray+0 | no_ssa_refToArray+0 |
+| escape.cpp:167:19:167:28 | CopyValue | passByPtr+0 | passByPtr+0 |
+| escape.cpp:170:21:170:29 | CopyValue | passByRef+0 | passByRef+0 |
+| escape.cpp:173:22:173:38 | CopyValue | no_ssa_passByPtr+0 | no_ssa_passByPtr+0 |
+| escape.cpp:176:24:176:39 | CopyValue | no_ssa_passByRef+0 | no_ssa_passByRef+0 |
+| escape.cpp:179:22:179:42 | CopyValue | no_ssa_passByPtr_ret+0 | no_ssa_passByPtr_ret+0 |
+| escape.cpp:182:24:182:43 | CopyValue | no_ssa_passByRef_ret+0 | no_ssa_passByRef_ret+0 |
+| escape.cpp:185:30:185:40 | CopyValue | passByPtr2+0 | passByPtr2+0 |
+| escape.cpp:188:32:188:41 | CopyValue | passByRef2+0 | passByRef2+0 |
+| escape.cpp:191:30:191:42 | Call | none | passByPtr3+0 |
+| escape.cpp:191:44:191:54 | CopyValue | passByPtr3+0 | passByPtr3+0 |
+| escape.cpp:194:32:194:46 | Call | none | passByRef3+0 |
+| escape.cpp:194:32:194:59 | CopyValue | none | passByRef3+0 |
+| escape.cpp:194:48:194:57 | CopyValue | passByRef3+0 | passByRef3+0 |
+| escape.cpp:199:17:199:34 | CopyValue | no_ssa_passByPtr4+0 | no_ssa_passByPtr4+0 |
+| escape.cpp:199:37:199:54 | CopyValue | no_ssa_passByPtr5+0 | no_ssa_passByPtr5+0 |
+| escape.cpp:202:5:202:19 | Call | none | passByRef6+0 |
+| escape.cpp:202:5:202:32 | CopyValue | none | passByRef6+0 |
+| escape.cpp:202:21:202:30 | CopyValue | passByRef6+0 | passByRef6+0 |
+| escape.cpp:205:5:205:19 | Call | none | no_ssa_passByRef7+0 |
+| escape.cpp:205:5:205:39 | CopyValue | none | no_ssa_passByRef7+0 |
+| escape.cpp:205:21:205:37 | CopyValue | no_ssa_passByRef7+0 | no_ssa_passByRef7+0 |
+| escape.cpp:209:14:209:25 | Call | none | no_ssa_c+0 |
+| escape.cpp:217:14:217:16 | CopyValue | c2+0 | c2+0 |
+| escape.cpp:221:8:221:19 | Call | none | c3+0 |
+| escape.cpp:225:17:225:28 | Call | none | c4+0 |
+| escape.cpp:247:2:247:27 | Store | condEscape1+0 | condEscape1+0 |
+| escape.cpp:247:16:247:27 | CopyValue | condEscape1+0 | condEscape1+0 |
+| escape.cpp:249:9:249:34 | Store | condEscape2+0 | condEscape2+0 |
+| escape.cpp:249:23:249:34 | CopyValue | condEscape2+0 | condEscape2+0 |
diff --git a/cpp/ql/test/library-tests/ir/escape/points_to.ql b/cpp/ql/test/library-tests/ir/escape/points_to.ql
index 04dbf0e0060..7c265974b10 100644
--- a/cpp/ql/test/library-tests/ir/escape/points_to.ql
+++ b/cpp/ql/test/library-tests/ir/escape/points_to.ql
@@ -4,6 +4,7 @@ import semmle.code.cpp.ir.implementation.raw.IR as Raw
import semmle.code.cpp.ir.implementation.aliased_ssa.internal.AliasAnalysis as UnAA
import semmle.code.cpp.ir.implementation.unaliased_ssa.IR as Un
import semmle.code.cpp.ir.implementation.unaliased_ssa.internal.SSAConstruction
+import semmle.code.cpp.ir.internal.IntegerConstant
from Raw::Instruction rawInstr, Un::Instruction unInstr, string rawPointsTo, string unPointsTo
where
@@ -12,21 +13,21 @@ where
(
exists(Variable var, int rawBitOffset, int unBitOffset |
RawAA::resultPointsTo(rawInstr, Raw::getIRUserVariable(_, var), rawBitOffset) and
- rawPointsTo = var.toString() + RawAA::getBitOffsetString(rawBitOffset) and
+ rawPointsTo = var.toString() + getBitOffsetString(rawBitOffset) and
UnAA::resultPointsTo(unInstr, Un::getIRUserVariable(_, var), unBitOffset) and
- unPointsTo = var.toString() + UnAA::getBitOffsetString(unBitOffset)
+ unPointsTo = var.toString() + getBitOffsetString(unBitOffset)
)
or
exists(Variable var, int unBitOffset |
not RawAA::resultPointsTo(rawInstr, Raw::getIRUserVariable(_, var), _) and
rawPointsTo = "none" and
UnAA::resultPointsTo(unInstr, Un::getIRUserVariable(_, var), unBitOffset) and
- unPointsTo = var.toString() + UnAA::getBitOffsetString(unBitOffset)
+ unPointsTo = var.toString() + getBitOffsetString(unBitOffset)
)
or
exists(Variable var, int rawBitOffset |
RawAA::resultPointsTo(rawInstr, Raw::getIRUserVariable(_, var), rawBitOffset) and
- rawPointsTo = var.toString() + RawAA::getBitOffsetString(rawBitOffset) and
+ rawPointsTo = var.toString() + getBitOffsetString(rawBitOffset) and
not UnAA::resultPointsTo(unInstr, Un::getIRUserVariable(_, var), _) and
unPointsTo = "none"
)
From 7d48220a76c393ecc27b67c0cf1639b252918935 Mon Sep 17 00:00:00 2001
From: Dave Bartolomeo
Date: Mon, 25 Nov 2019 11:26:45 -0700
Subject: [PATCH 41/44] C++/C#: Make QLDoc conform to style guide
---
.../implementation/aliased_ssa/IRVariable.qll | 40 +++++++++----------
.../cpp/ir/implementation/raw/IRVariable.qll | 40 +++++++++----------
.../unaliased_ssa/IRVariable.qll | 40 +++++++++----------
.../ir/implementation/raw/IRVariable.qll | 40 +++++++++----------
.../unaliased_ssa/IRVariable.qll | 40 +++++++++----------
5 files changed, 95 insertions(+), 105 deletions(-)
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll
index 1092acc0003..f9efad42fb0 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll
@@ -13,9 +13,9 @@ IRUserVariable getIRUserVariable(Language::Function func, Language::Variable var
}
/**
- * Represents a variable referenced by the IR for a function. The variable may
- * be a user-declared variable (`IRUserVariable`) or a temporary variable
- * generated by the AST-to-IR translation (`IRTempVariable`).
+ * A variable referenced by the IR for a function. The variable may be a user-declared variable
+ * (`IRUserVariable`) or a temporary variable generated by the AST-to-IR translation
+ * (`IRTempVariable`).
*/
class IRVariable extends TIRVariable {
Language::Function func;
@@ -78,7 +78,7 @@ class IRVariable extends TIRVariable {
}
/**
- * Represents a user-declared variable referenced by the IR for a function.
+ * A user-declared variable referenced by the IR for a function.
*/
class IRUserVariable extends IRVariable, TIRUserVariable {
Language::Variable var;
@@ -103,9 +103,8 @@ class IRUserVariable extends IRVariable, TIRUserVariable {
}
/**
- * Represents a variable (user-declared or temporary) that is allocated on the
- * stack. This includes all parameters, non-static local variables, and
- * temporary variables.
+ * A variable (user-declared or temporary) that is allocated on the stack. This includes all
+ * parameters, non-static local variables, and temporary variables.
*/
class IRAutomaticVariable extends IRVariable {
IRAutomaticVariable() {
@@ -119,8 +118,8 @@ class IRAutomaticVariable extends IRVariable {
}
/**
- * Represents a user-declared variable that is allocated on the stack. This
- * includes all parameters and non-static local variables.
+ * A user-declared variable that is allocated on the stack. This includes all parameters and
+ * non-static local variables.
*/
class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable {
override Language::AutomaticVariable var;
@@ -129,9 +128,8 @@ class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable {
}
/**
- * Represents a user-declared variable that is not allocated on the stack. This
- * includes all global variables, namespace-scope variables, static fields, and
- * static local variables.
+ * A user-declared variable that is not allocated on the stack. This includes all global variables,
+ * namespace-scope variables, static fields, and static local variables.
*/
class IRStaticUserVariable extends IRUserVariable {
override Language::StaticVariable var;
@@ -142,8 +140,8 @@ class IRStaticUserVariable extends IRUserVariable {
}
/**
- * Represents a variable that is not user-declared. This includes temporary
- * variables generated as part of IR construction, as well as string literals.
+ * A variable that is not user-declared. This includes temporary variables generated as part of IR
+ * construction, as well as string literals.
*/
class IRGeneratedVariable extends IRVariable {
Language::AST ast;
@@ -176,9 +174,9 @@ IRTempVariable getIRTempVariable(Language::AST ast, TempVariableTag tag) {
}
/**
- * Represents a temporary variable introduced by IR construction. The most common examples are the
- * variable generated to hold the return value of afunction, or the variable generated to hold the
- * result of a condition operator (`a ? b : c`).
+ * A temporary variable introduced by IR construction. The most common examples are the variable
+ * generated to hold the return value of afunction, or the variable generated to hold the result of
+ * a condition operator (`a ? b : c`).
*/
class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVariable {
TempVariableTag tag;
@@ -195,7 +193,7 @@ class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVa
}
/**
- * The temporary variable generated to hold the return value of a function.
+ * A temporary variable generated to hold the return value of a function.
*/
class IRReturnVariable extends IRTempVariable {
IRReturnVariable() { tag = ReturnValueTempVar() }
@@ -204,7 +202,7 @@ class IRReturnVariable extends IRTempVariable {
}
/**
- * The temporary variable generated to hold the exception thrown by a `ThrowValue` instruction.
+ * A temporary variable generated to hold the exception thrown by a `ThrowValue` instruction.
*/
class IRThrowVariable extends IRTempVariable {
IRThrowVariable() { tag = ThrowTempVar() }
@@ -213,8 +211,8 @@ class IRThrowVariable extends IRTempVariable {
}
/**
- * The variable generated to represent the contents of a string literal. This variable acts much
- * like a read-only global variable.
+ * A variable generated to represent the contents of a string literal. This variable acts much like
+ * a read-only global variable.
*/
class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral {
Language::StringLiteral literal;
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRVariable.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRVariable.qll
index 1092acc0003..f9efad42fb0 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRVariable.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRVariable.qll
@@ -13,9 +13,9 @@ IRUserVariable getIRUserVariable(Language::Function func, Language::Variable var
}
/**
- * Represents a variable referenced by the IR for a function. The variable may
- * be a user-declared variable (`IRUserVariable`) or a temporary variable
- * generated by the AST-to-IR translation (`IRTempVariable`).
+ * A variable referenced by the IR for a function. The variable may be a user-declared variable
+ * (`IRUserVariable`) or a temporary variable generated by the AST-to-IR translation
+ * (`IRTempVariable`).
*/
class IRVariable extends TIRVariable {
Language::Function func;
@@ -78,7 +78,7 @@ class IRVariable extends TIRVariable {
}
/**
- * Represents a user-declared variable referenced by the IR for a function.
+ * A user-declared variable referenced by the IR for a function.
*/
class IRUserVariable extends IRVariable, TIRUserVariable {
Language::Variable var;
@@ -103,9 +103,8 @@ class IRUserVariable extends IRVariable, TIRUserVariable {
}
/**
- * Represents a variable (user-declared or temporary) that is allocated on the
- * stack. This includes all parameters, non-static local variables, and
- * temporary variables.
+ * A variable (user-declared or temporary) that is allocated on the stack. This includes all
+ * parameters, non-static local variables, and temporary variables.
*/
class IRAutomaticVariable extends IRVariable {
IRAutomaticVariable() {
@@ -119,8 +118,8 @@ class IRAutomaticVariable extends IRVariable {
}
/**
- * Represents a user-declared variable that is allocated on the stack. This
- * includes all parameters and non-static local variables.
+ * A user-declared variable that is allocated on the stack. This includes all parameters and
+ * non-static local variables.
*/
class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable {
override Language::AutomaticVariable var;
@@ -129,9 +128,8 @@ class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable {
}
/**
- * Represents a user-declared variable that is not allocated on the stack. This
- * includes all global variables, namespace-scope variables, static fields, and
- * static local variables.
+ * A user-declared variable that is not allocated on the stack. This includes all global variables,
+ * namespace-scope variables, static fields, and static local variables.
*/
class IRStaticUserVariable extends IRUserVariable {
override Language::StaticVariable var;
@@ -142,8 +140,8 @@ class IRStaticUserVariable extends IRUserVariable {
}
/**
- * Represents a variable that is not user-declared. This includes temporary
- * variables generated as part of IR construction, as well as string literals.
+ * A variable that is not user-declared. This includes temporary variables generated as part of IR
+ * construction, as well as string literals.
*/
class IRGeneratedVariable extends IRVariable {
Language::AST ast;
@@ -176,9 +174,9 @@ IRTempVariable getIRTempVariable(Language::AST ast, TempVariableTag tag) {
}
/**
- * Represents a temporary variable introduced by IR construction. The most common examples are the
- * variable generated to hold the return value of afunction, or the variable generated to hold the
- * result of a condition operator (`a ? b : c`).
+ * A temporary variable introduced by IR construction. The most common examples are the variable
+ * generated to hold the return value of afunction, or the variable generated to hold the result of
+ * a condition operator (`a ? b : c`).
*/
class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVariable {
TempVariableTag tag;
@@ -195,7 +193,7 @@ class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVa
}
/**
- * The temporary variable generated to hold the return value of a function.
+ * A temporary variable generated to hold the return value of a function.
*/
class IRReturnVariable extends IRTempVariable {
IRReturnVariable() { tag = ReturnValueTempVar() }
@@ -204,7 +202,7 @@ class IRReturnVariable extends IRTempVariable {
}
/**
- * The temporary variable generated to hold the exception thrown by a `ThrowValue` instruction.
+ * A temporary variable generated to hold the exception thrown by a `ThrowValue` instruction.
*/
class IRThrowVariable extends IRTempVariable {
IRThrowVariable() { tag = ThrowTempVar() }
@@ -213,8 +211,8 @@ class IRThrowVariable extends IRTempVariable {
}
/**
- * The variable generated to represent the contents of a string literal. This variable acts much
- * like a read-only global variable.
+ * A variable generated to represent the contents of a string literal. This variable acts much like
+ * a read-only global variable.
*/
class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral {
Language::StringLiteral literal;
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll
index 1092acc0003..f9efad42fb0 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll
@@ -13,9 +13,9 @@ IRUserVariable getIRUserVariable(Language::Function func, Language::Variable var
}
/**
- * Represents a variable referenced by the IR for a function. The variable may
- * be a user-declared variable (`IRUserVariable`) or a temporary variable
- * generated by the AST-to-IR translation (`IRTempVariable`).
+ * A variable referenced by the IR for a function. The variable may be a user-declared variable
+ * (`IRUserVariable`) or a temporary variable generated by the AST-to-IR translation
+ * (`IRTempVariable`).
*/
class IRVariable extends TIRVariable {
Language::Function func;
@@ -78,7 +78,7 @@ class IRVariable extends TIRVariable {
}
/**
- * Represents a user-declared variable referenced by the IR for a function.
+ * A user-declared variable referenced by the IR for a function.
*/
class IRUserVariable extends IRVariable, TIRUserVariable {
Language::Variable var;
@@ -103,9 +103,8 @@ class IRUserVariable extends IRVariable, TIRUserVariable {
}
/**
- * Represents a variable (user-declared or temporary) that is allocated on the
- * stack. This includes all parameters, non-static local variables, and
- * temporary variables.
+ * A variable (user-declared or temporary) that is allocated on the stack. This includes all
+ * parameters, non-static local variables, and temporary variables.
*/
class IRAutomaticVariable extends IRVariable {
IRAutomaticVariable() {
@@ -119,8 +118,8 @@ class IRAutomaticVariable extends IRVariable {
}
/**
- * Represents a user-declared variable that is allocated on the stack. This
- * includes all parameters and non-static local variables.
+ * A user-declared variable that is allocated on the stack. This includes all parameters and
+ * non-static local variables.
*/
class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable {
override Language::AutomaticVariable var;
@@ -129,9 +128,8 @@ class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable {
}
/**
- * Represents a user-declared variable that is not allocated on the stack. This
- * includes all global variables, namespace-scope variables, static fields, and
- * static local variables.
+ * A user-declared variable that is not allocated on the stack. This includes all global variables,
+ * namespace-scope variables, static fields, and static local variables.
*/
class IRStaticUserVariable extends IRUserVariable {
override Language::StaticVariable var;
@@ -142,8 +140,8 @@ class IRStaticUserVariable extends IRUserVariable {
}
/**
- * Represents a variable that is not user-declared. This includes temporary
- * variables generated as part of IR construction, as well as string literals.
+ * A variable that is not user-declared. This includes temporary variables generated as part of IR
+ * construction, as well as string literals.
*/
class IRGeneratedVariable extends IRVariable {
Language::AST ast;
@@ -176,9 +174,9 @@ IRTempVariable getIRTempVariable(Language::AST ast, TempVariableTag tag) {
}
/**
- * Represents a temporary variable introduced by IR construction. The most common examples are the
- * variable generated to hold the return value of afunction, or the variable generated to hold the
- * result of a condition operator (`a ? b : c`).
+ * A temporary variable introduced by IR construction. The most common examples are the variable
+ * generated to hold the return value of afunction, or the variable generated to hold the result of
+ * a condition operator (`a ? b : c`).
*/
class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVariable {
TempVariableTag tag;
@@ -195,7 +193,7 @@ class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVa
}
/**
- * The temporary variable generated to hold the return value of a function.
+ * A temporary variable generated to hold the return value of a function.
*/
class IRReturnVariable extends IRTempVariable {
IRReturnVariable() { tag = ReturnValueTempVar() }
@@ -204,7 +202,7 @@ class IRReturnVariable extends IRTempVariable {
}
/**
- * The temporary variable generated to hold the exception thrown by a `ThrowValue` instruction.
+ * A temporary variable generated to hold the exception thrown by a `ThrowValue` instruction.
*/
class IRThrowVariable extends IRTempVariable {
IRThrowVariable() { tag = ThrowTempVar() }
@@ -213,8 +211,8 @@ class IRThrowVariable extends IRTempVariable {
}
/**
- * The variable generated to represent the contents of a string literal. This variable acts much
- * like a read-only global variable.
+ * A variable generated to represent the contents of a string literal. This variable acts much like
+ * a read-only global variable.
*/
class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral {
Language::StringLiteral literal;
diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/IRVariable.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/IRVariable.qll
index 1092acc0003..f9efad42fb0 100644
--- a/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/IRVariable.qll
+++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/IRVariable.qll
@@ -13,9 +13,9 @@ IRUserVariable getIRUserVariable(Language::Function func, Language::Variable var
}
/**
- * Represents a variable referenced by the IR for a function. The variable may
- * be a user-declared variable (`IRUserVariable`) or a temporary variable
- * generated by the AST-to-IR translation (`IRTempVariable`).
+ * A variable referenced by the IR for a function. The variable may be a user-declared variable
+ * (`IRUserVariable`) or a temporary variable generated by the AST-to-IR translation
+ * (`IRTempVariable`).
*/
class IRVariable extends TIRVariable {
Language::Function func;
@@ -78,7 +78,7 @@ class IRVariable extends TIRVariable {
}
/**
- * Represents a user-declared variable referenced by the IR for a function.
+ * A user-declared variable referenced by the IR for a function.
*/
class IRUserVariable extends IRVariable, TIRUserVariable {
Language::Variable var;
@@ -103,9 +103,8 @@ class IRUserVariable extends IRVariable, TIRUserVariable {
}
/**
- * Represents a variable (user-declared or temporary) that is allocated on the
- * stack. This includes all parameters, non-static local variables, and
- * temporary variables.
+ * A variable (user-declared or temporary) that is allocated on the stack. This includes all
+ * parameters, non-static local variables, and temporary variables.
*/
class IRAutomaticVariable extends IRVariable {
IRAutomaticVariable() {
@@ -119,8 +118,8 @@ class IRAutomaticVariable extends IRVariable {
}
/**
- * Represents a user-declared variable that is allocated on the stack. This
- * includes all parameters and non-static local variables.
+ * A user-declared variable that is allocated on the stack. This includes all parameters and
+ * non-static local variables.
*/
class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable {
override Language::AutomaticVariable var;
@@ -129,9 +128,8 @@ class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable {
}
/**
- * Represents a user-declared variable that is not allocated on the stack. This
- * includes all global variables, namespace-scope variables, static fields, and
- * static local variables.
+ * A user-declared variable that is not allocated on the stack. This includes all global variables,
+ * namespace-scope variables, static fields, and static local variables.
*/
class IRStaticUserVariable extends IRUserVariable {
override Language::StaticVariable var;
@@ -142,8 +140,8 @@ class IRStaticUserVariable extends IRUserVariable {
}
/**
- * Represents a variable that is not user-declared. This includes temporary
- * variables generated as part of IR construction, as well as string literals.
+ * A variable that is not user-declared. This includes temporary variables generated as part of IR
+ * construction, as well as string literals.
*/
class IRGeneratedVariable extends IRVariable {
Language::AST ast;
@@ -176,9 +174,9 @@ IRTempVariable getIRTempVariable(Language::AST ast, TempVariableTag tag) {
}
/**
- * Represents a temporary variable introduced by IR construction. The most common examples are the
- * variable generated to hold the return value of afunction, or the variable generated to hold the
- * result of a condition operator (`a ? b : c`).
+ * A temporary variable introduced by IR construction. The most common examples are the variable
+ * generated to hold the return value of afunction, or the variable generated to hold the result of
+ * a condition operator (`a ? b : c`).
*/
class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVariable {
TempVariableTag tag;
@@ -195,7 +193,7 @@ class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVa
}
/**
- * The temporary variable generated to hold the return value of a function.
+ * A temporary variable generated to hold the return value of a function.
*/
class IRReturnVariable extends IRTempVariable {
IRReturnVariable() { tag = ReturnValueTempVar() }
@@ -204,7 +202,7 @@ class IRReturnVariable extends IRTempVariable {
}
/**
- * The temporary variable generated to hold the exception thrown by a `ThrowValue` instruction.
+ * A temporary variable generated to hold the exception thrown by a `ThrowValue` instruction.
*/
class IRThrowVariable extends IRTempVariable {
IRThrowVariable() { tag = ThrowTempVar() }
@@ -213,8 +211,8 @@ class IRThrowVariable extends IRTempVariable {
}
/**
- * The variable generated to represent the contents of a string literal. This variable acts much
- * like a read-only global variable.
+ * A variable generated to represent the contents of a string literal. This variable acts much like
+ * a read-only global variable.
*/
class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral {
Language::StringLiteral literal;
diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/IRVariable.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/IRVariable.qll
index 1092acc0003..f9efad42fb0 100644
--- a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/IRVariable.qll
+++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/IRVariable.qll
@@ -13,9 +13,9 @@ IRUserVariable getIRUserVariable(Language::Function func, Language::Variable var
}
/**
- * Represents a variable referenced by the IR for a function. The variable may
- * be a user-declared variable (`IRUserVariable`) or a temporary variable
- * generated by the AST-to-IR translation (`IRTempVariable`).
+ * A variable referenced by the IR for a function. The variable may be a user-declared variable
+ * (`IRUserVariable`) or a temporary variable generated by the AST-to-IR translation
+ * (`IRTempVariable`).
*/
class IRVariable extends TIRVariable {
Language::Function func;
@@ -78,7 +78,7 @@ class IRVariable extends TIRVariable {
}
/**
- * Represents a user-declared variable referenced by the IR for a function.
+ * A user-declared variable referenced by the IR for a function.
*/
class IRUserVariable extends IRVariable, TIRUserVariable {
Language::Variable var;
@@ -103,9 +103,8 @@ class IRUserVariable extends IRVariable, TIRUserVariable {
}
/**
- * Represents a variable (user-declared or temporary) that is allocated on the
- * stack. This includes all parameters, non-static local variables, and
- * temporary variables.
+ * A variable (user-declared or temporary) that is allocated on the stack. This includes all
+ * parameters, non-static local variables, and temporary variables.
*/
class IRAutomaticVariable extends IRVariable {
IRAutomaticVariable() {
@@ -119,8 +118,8 @@ class IRAutomaticVariable extends IRVariable {
}
/**
- * Represents a user-declared variable that is allocated on the stack. This
- * includes all parameters and non-static local variables.
+ * A user-declared variable that is allocated on the stack. This includes all parameters and
+ * non-static local variables.
*/
class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable {
override Language::AutomaticVariable var;
@@ -129,9 +128,8 @@ class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable {
}
/**
- * Represents a user-declared variable that is not allocated on the stack. This
- * includes all global variables, namespace-scope variables, static fields, and
- * static local variables.
+ * A user-declared variable that is not allocated on the stack. This includes all global variables,
+ * namespace-scope variables, static fields, and static local variables.
*/
class IRStaticUserVariable extends IRUserVariable {
override Language::StaticVariable var;
@@ -142,8 +140,8 @@ class IRStaticUserVariable extends IRUserVariable {
}
/**
- * Represents a variable that is not user-declared. This includes temporary
- * variables generated as part of IR construction, as well as string literals.
+ * A variable that is not user-declared. This includes temporary variables generated as part of IR
+ * construction, as well as string literals.
*/
class IRGeneratedVariable extends IRVariable {
Language::AST ast;
@@ -176,9 +174,9 @@ IRTempVariable getIRTempVariable(Language::AST ast, TempVariableTag tag) {
}
/**
- * Represents a temporary variable introduced by IR construction. The most common examples are the
- * variable generated to hold the return value of afunction, or the variable generated to hold the
- * result of a condition operator (`a ? b : c`).
+ * A temporary variable introduced by IR construction. The most common examples are the variable
+ * generated to hold the return value of afunction, or the variable generated to hold the result of
+ * a condition operator (`a ? b : c`).
*/
class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVariable {
TempVariableTag tag;
@@ -195,7 +193,7 @@ class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVa
}
/**
- * The temporary variable generated to hold the return value of a function.
+ * A temporary variable generated to hold the return value of a function.
*/
class IRReturnVariable extends IRTempVariable {
IRReturnVariable() { tag = ReturnValueTempVar() }
@@ -204,7 +202,7 @@ class IRReturnVariable extends IRTempVariable {
}
/**
- * The temporary variable generated to hold the exception thrown by a `ThrowValue` instruction.
+ * A temporary variable generated to hold the exception thrown by a `ThrowValue` instruction.
*/
class IRThrowVariable extends IRTempVariable {
IRThrowVariable() { tag = ThrowTempVar() }
@@ -213,8 +211,8 @@ class IRThrowVariable extends IRTempVariable {
}
/**
- * The variable generated to represent the contents of a string literal. This variable acts much
- * like a read-only global variable.
+ * A variable generated to represent the contents of a string literal. This variable acts much like
+ * a read-only global variable.
*/
class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral {
Language::StringLiteral literal;
From deb6a6e5c69ee7ea54b97561554ed4c0cee471fe Mon Sep 17 00:00:00 2001
From: Anders Schack-Mulligen
Date: Tue, 26 Nov 2019 17:20:01 +0100
Subject: [PATCH 42/44] Java: Improve performance by normalizing import order
to reduce cache invalidation.
---
java/ql/src/Security/CWE/CWE-078/ExecTainted.ql | 2 +-
java/ql/src/Security/CWE/CWE-078/ExecUnescaped.ql | 2 +-
java/ql/src/Security/CWE/CWE-089/SqlTainted.ql | 2 +-
java/ql/src/Security/CWE/CWE-089/SqlUnescaped.ql | 1 +
4 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/java/ql/src/Security/CWE/CWE-078/ExecTainted.ql b/java/ql/src/Security/CWE/CWE-078/ExecTainted.ql
index 8774de339b6..353df33afed 100644
--- a/java/ql/src/Security/CWE/CWE-078/ExecTainted.ql
+++ b/java/ql/src/Security/CWE/CWE-078/ExecTainted.ql
@@ -11,7 +11,7 @@
* external/cwe/cwe-088
*/
-import semmle.code.java.Expr
+import java
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.security.ExternalProcess
import ExecCommon
diff --git a/java/ql/src/Security/CWE/CWE-078/ExecUnescaped.ql b/java/ql/src/Security/CWE/CWE-078/ExecUnescaped.ql
index e80afa7f6eb..a0fa793872f 100644
--- a/java/ql/src/Security/CWE/CWE-078/ExecUnescaped.ql
+++ b/java/ql/src/Security/CWE/CWE-078/ExecUnescaped.ql
@@ -11,7 +11,7 @@
* external/cwe/cwe-088
*/
-import semmle.code.java.Expr
+import java
import semmle.code.java.security.ExternalProcess
import ExecCommon
diff --git a/java/ql/src/Security/CWE/CWE-089/SqlTainted.ql b/java/ql/src/Security/CWE/CWE-089/SqlTainted.ql
index 5b79c56a83c..5750829d7d6 100644
--- a/java/ql/src/Security/CWE/CWE-089/SqlTainted.ql
+++ b/java/ql/src/Security/CWE/CWE-089/SqlTainted.ql
@@ -10,7 +10,7 @@
* external/cwe/cwe-089
*/
-import semmle.code.java.Expr
+import java
import semmle.code.java.dataflow.FlowSources
import SqlInjectionLib
import DataFlow::PathGraph
diff --git a/java/ql/src/Security/CWE/CWE-089/SqlUnescaped.ql b/java/ql/src/Security/CWE/CWE-089/SqlUnescaped.ql
index 83eaa50ea2c..e721cb7fba6 100644
--- a/java/ql/src/Security/CWE/CWE-089/SqlUnescaped.ql
+++ b/java/ql/src/Security/CWE/CWE-089/SqlUnescaped.ql
@@ -10,6 +10,7 @@
* external/cwe/cwe-089
*/
+import java
import semmle.code.java.security.SqlUnescapedLib
import SqlInjectionLib
From 4e1ee7a998b52b2654f2e9d3901155050b2fd577 Mon Sep 17 00:00:00 2001
From: Dave Bartolomeo
Date: Tue, 26 Nov 2019 10:48:24 -0700
Subject: [PATCH 43/44] C++/C#: Fix formatting
---
.../code/cpp/ir/internal/IntegerConstant.qll | 21 ++++++++-----------
.../csharp/ir/internal/IntegerConstant.qll | 21 ++++++++-----------
2 files changed, 18 insertions(+), 24 deletions(-)
diff --git a/cpp/ql/src/semmle/code/cpp/ir/internal/IntegerConstant.qll b/cpp/ql/src/semmle/code/cpp/ir/internal/IntegerConstant.qll
index 0d845303c28..6034ebc5674 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/internal/IntegerConstant.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/internal/IntegerConstant.qll
@@ -204,11 +204,9 @@ string bitsToBytesAndBits(IntValue bits) {
hasValue(bits) and
bytes = bits / 8 and
leftoverBits = bits % 8 and
- if leftoverBits = 0 then
- result = bytes.toString()
- else
- result = bytes + ":" + leftoverBits
- ) or
+ if leftoverBits = 0 then result = bytes.toString() else result = bytes + ":" + leftoverBits
+ )
+ or
not hasValue(bits) and result = "?"
}
@@ -217,11 +215,10 @@ string bitsToBytesAndBits(IntValue bits) {
*/
bindingset[bitOffset]
string getBitOffsetString(IntValue bitOffset) {
- if hasValue(bitOffset) then
- if bitOffset >= 0 then
- result = "+" + bitsToBytesAndBits(bitOffset)
- else
- result = "-" + bitsToBytesAndBits(neg(bitOffset))
- else
- result = "+?"
+ if hasValue(bitOffset)
+ then
+ if bitOffset >= 0
+ then result = "+" + bitsToBytesAndBits(bitOffset)
+ else result = "-" + bitsToBytesAndBits(neg(bitOffset))
+ else result = "+?"
}
diff --git a/csharp/ql/src/semmle/code/csharp/ir/internal/IntegerConstant.qll b/csharp/ql/src/semmle/code/csharp/ir/internal/IntegerConstant.qll
index 0d845303c28..6034ebc5674 100644
--- a/csharp/ql/src/semmle/code/csharp/ir/internal/IntegerConstant.qll
+++ b/csharp/ql/src/semmle/code/csharp/ir/internal/IntegerConstant.qll
@@ -204,11 +204,9 @@ string bitsToBytesAndBits(IntValue bits) {
hasValue(bits) and
bytes = bits / 8 and
leftoverBits = bits % 8 and
- if leftoverBits = 0 then
- result = bytes.toString()
- else
- result = bytes + ":" + leftoverBits
- ) or
+ if leftoverBits = 0 then result = bytes.toString() else result = bytes + ":" + leftoverBits
+ )
+ or
not hasValue(bits) and result = "?"
}
@@ -217,11 +215,10 @@ string bitsToBytesAndBits(IntValue bits) {
*/
bindingset[bitOffset]
string getBitOffsetString(IntValue bitOffset) {
- if hasValue(bitOffset) then
- if bitOffset >= 0 then
- result = "+" + bitsToBytesAndBits(bitOffset)
- else
- result = "-" + bitsToBytesAndBits(neg(bitOffset))
- else
- result = "+?"
+ if hasValue(bitOffset)
+ then
+ if bitOffset >= 0
+ then result = "+" + bitsToBytesAndBits(bitOffset)
+ else result = "-" + bitsToBytesAndBits(neg(bitOffset))
+ else result = "+?"
}
From 2eea94c3dc7c4c93b4e9b61b384063c9416a8246 Mon Sep 17 00:00:00 2001
From: yo-h <55373593+yo-h@users.noreply.github.com>
Date: Tue, 26 Nov 2019 14:11:54 -0500
Subject: [PATCH 44/44] Documentation: fix invalid `@precision` value
---
docs/query-metadata-style-guide.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/query-metadata-style-guide.md b/docs/query-metadata-style-guide.md
index d5f5606002c..70cb083cb1a 100644
--- a/docs/query-metadata-style-guide.md
+++ b/docs/query-metadata-style-guide.md
@@ -113,7 +113,7 @@ Alert queries (`@kind problem` or `path-problem`) support two further properties
* `low `
* `medium `
* `high `
- * `very high`
+ * `very-high`
* `@problem.severity`–defines the level of severity of the alert:
* `error`–an issue that is likely to cause incorrect program behavior, for example a crash or vulnerability.
* `warning`–an issue that indicates a potential problem in the code, or makes the code fragile if another (unrelated) part of code is changed.