Files
codeql/swift/tools/tracing-config.lua
Jeroen Ketema 3cabcfef75 Swift: Skip -scan-dependencies compiler calls
These do not produce any useful data and just crash our frontend.
2025-12-10 10:11:41 +01:00

160 lines
7.0 KiB
Lua

function RegisterExtractorPack(id)
local extractorDirectory = GetPlatformToolsDirectory()
local relativeSwiftExtractor = extractorDirectory .. 'extractor'
local swiftExtractor = AbsolutifyExtractorPath(id, relativeSwiftExtractor)
local resourceDirectory = AbsolutifyExtractorPath(id, 'resource-dir' .. PathSep .. PlatformDirectory)
function indexOf(array, value)
for i, v in ipairs(array) do
if v == value then
return i
end
end
return nil
end
function startswith(text, prefix)
return string.find(text, prefix, 1, true) == 1
end
-- removes unsupported CLI arg including the following how_many args
function strip_unsupported_arg(args, arg, how_many)
local index = indexOf(args, arg)
if index then
table.remove(args, index)
while (how_many > 0)
do
table.remove(args, index)
how_many = how_many - 1
end
end
end
-- removes unsupported -Xcc flag, e.g, calling strip_unsupported_xcc_arg('-foo', 2) against
-- swift -Xcc -foo -Xcc -bar main.swift
-- will only leave 'swift main.swift' removing both -Xcc -foo, and also -Xcc -bar
-- removes unsupported CLI arg passed to clang via -Xcc together with the following how_many args
function strip_unsupported_clang_arg(args, arg, how_many)
local index = indexOf(args, arg)
if index and index > 0 and args[index - 1] == '-Xcc' then
index = index - 1 -- start from -Xcc
how_many = 2 * (how_many + 1) -- need to remove initial -Xcc <arg> as well as following -Xcc prefixed flags
while (how_many > 0)
do
table.remove(args, index)
how_many = how_many - 1
end
end
end
function strip_unsupported_args(args)
strip_unsupported_arg(args, '-emit-localized-strings', 0)
strip_unsupported_arg(args, '-emit-localized-strings-path', 1)
strip_unsupported_arg(args, '-stack-check', 0)
strip_unsupported_arg(args, '-experimental-skip-non-inlinable-function-bodies-without-types', 0)
strip_unsupported_clang_arg(args, '-ivfsstatcache', 1)
strip_unsupported_clang_arg(args, '-fno-odr-hash-protocols', 0)
strip_unsupported_clang_arg(args, '-clang-vendor-feature=+disableNonDependentMemberExprInCurrentInstantiation', 0)
strip_unsupported_clang_arg(args, '-clang-vendor-feature=+enableAggressiveVLAFolding', 0)
strip_unsupported_clang_arg(args, '-clang-vendor-feature=+revert09abecef7bbf', 0)
strip_unsupported_clang_arg(args, '-clang-vendor-feature=+thisNoAlignAttr', 0)
strip_unsupported_clang_arg(args, '-clang-vendor-feature=+thisNoNullAttr', 0)
strip_unsupported_clang_arg(args, '-clang-vendor-feature=+disableAtImportPrivateFrameworkInImplementationError', 0)
-- The four args below are removed to workaround version mismatches due to recent versions
-- of Xcode defaulting to explicit modules:
strip_unsupported_arg(args, '-disable-implicit-swift-modules', 0)
strip_unsupported_clang_arg(args, '-fno-implicit-modules', 0)
strip_unsupported_clang_arg(args, '-fno-implicit-module-maps', 0)
strip_unsupported_arg(args, '-explicit-swift-module-map-file', 1)
end
-- xcodebuild does not always specify the -resource-dir in which case the compiler falls back
-- to a resource-dir based on its path. We want to know what is the original resource-dir in
-- all cases so that we can patch it with out own. When we see a -resource-dir preceded by
-- -Xcc this will be a resource-dir that is passed to clang. We can still obtain the swift
-- resource-dir in this case by skipping over the -Xcc that follows it and stripping off the
-- clang suffix from the path.
function find_original_resource_dir(compilerPath, args)
local found = indexOf(args, '-resource-dir')
if found and args[found + 1] then
if args[found - 1] ~= '-Xcc' then
return args[found + 1]
elseif args[found + 1] == '-Xcc' and args[found + 2] then
local clang_index = string.find(args[found + 2], "/clang$")
if clang_index and clang_index - 1 > 0 then
return string.sub(args[found + 2], 1, clang_index - 1)
end
end
end
-- derive -resource-dir based on the compilerPath
-- e.g.: /usr/bin/swift-frontend -> /usr/bin/../lib/swift
local second_last_slash_index = string.find(compilerPath, "/[^/]*/[^/]*$")
local usr_dir = string.sub(compilerPath, 1, second_last_slash_index)
return usr_dir .. 'lib/swift'
end
-- replace or add our own resource directory
function replace_resource_dir(compilerPath, args)
local originalResourceDir = find_original_resource_dir(compilerPath, args)
for index, value in ipairs(args) do
if startswith(value, originalResourceDir) then
args[index] = resourceDirectory .. string.sub(value, #originalResourceDir + 1, -1)
end
end
if not indexOf(args, '-resource-dir') then
table.insert(args, '-resource-dir')
table.insert(args, resourceDirectory)
end
end
function SwiftMatcher(compilerName, compilerPath, compilerArguments, lang)
-- Only match binaries names `swift-frontend`
if compilerName ~= 'swift-frontend' then
return nil
end
-- Skip the invocation in case it's not called in `-frontend` mode
if compilerArguments.argv[1] ~= '-frontend' then
return nil
end
-- Drop the `-frontend` argument
table.remove(compilerArguments.argv, 1)
-- Skip "info" queries in case there is nothing to extract
if compilerArguments.argv[1] == '-print-target-info' then
return nil
end
if compilerArguments.argv[1] == '-emit-supported-features' then
return nil
end
if compilerArguments.argv[1] == '-scan-dependencies' then
return nil
end
strip_unsupported_args(compilerArguments.argv)
replace_resource_dir(compilerPath, compilerArguments.argv)
return {
trace = true,
replace = false,
order = ORDER_AFTER,
invocation = { path = swiftExtractor, arguments = compilerArguments }
}
end
return {
SwiftMatcher,
CreatePatternMatcher({ '^lsregister$' }, MatchCompilerName, nil,
{ trace = false }),
CreatePatternMatcher({ '^codesign$' }, MatchCompilerName, nil,
{ trace = false }),
CreatePatternMatcher({ '^sandbox%-exec$' }, MatchCompilerName, nil,
{ trace = false }),
}
end
-- Return a list of minimum supported versions of the configuration file format
-- return one entry per supported major version.
function GetCompatibleVersions()
return { '1.0.0' }
end