C++ extractor crashes with coordinates_of_template_param_symbol assertion on a dependent default non-type template parameter used through a libc++ alias over a pack
まだ誰も着手していません。
評価
- 難易度
- 5/5
- 見積もり時間
- 1週間以上
- 初心者へのやさしさ
- 20/100
調査の方向性
The crash occurs in the C++ extractor's templates.c at line 3973. Start by examining the provided standalone reproduction files (repro_standalone.cc, repro_standalone_compile.sh) to understand the triggering condition: a libc++ alias template applied to a pack feeding a member template with a default non-type argument. Look at the extractor source code around coordinates_of_template_param_symbol. Running the extractor on the minimal test case with debugging enabled will help trace the assertion failure. The fix likely involves handling dependent default non-type template parameters in the presence of libc++ alias templates and pack expansions.
索引モデルが issue の本文から書いたものです。
説明
2.27.1 version has not resolved this issue; the problem still persists:
https://github.com/github/codeql/issues/22506#issue-5343398793.
For the main branch of Chromium, the current CodeQL still loses many things, such as the most basic OnceCallback
and RepeatingCallback classes implemented under the [src/base/functional/](https://source.chromium.org/chromium/
chromium/src/+/main:base/functional/) directory.
CodeQL C++ extractor aborts in coordinates_of_template_param_symbol on Chromium code
Summary
The CodeQL 2.27.1 C++ extractor (extractor version 1.22.1) aborts with an
internal assertion while extracting Chromium translation units:
Warning[extractor-c++]: In construct_text_message: "<file>", line N:
internal error: assertion failed at: "templates.c", line 3973
in coordinates_of_template_param_symbol
Warning[extractor-c++]: In main: Extractor exiting with code 4
The extractor exits with code 4 and the affected translation unit contributes
almost nothing to the database, while codeql database create still exits with
status 0 and reports Successfully created database, so the failure is silent
unless the extractor log is inspected.
The crash reproduces without any Chromium code: a seven-line file that uses
libc++ is enough (Reproduction A). It also reproduces on real Chromium code, both
on a one-line #include and on a real Chromium translation unit compiled with
its own GN build command (Reproduction B).
Environment
- CodeQL CLI 2.27.1, C++ extractor 1.22.1
- Linux x64
- clang 24 (
third_party/llvm-build/Release+Asserts/bin/clang++,
llvmorg-24-init-7747-g62397f8b-29) - libc++ from Chromium's
third_party/libc++andthird_party/libc++abi - Chromium commit
89c312d38e954(2026-09-22), build directoryout/release - Language mode
-std=c++23
Reproduction A - standalone, no Chromium code
repro_standalone.cc:
#include <type_traits>
template <typename...> struct Pack;
template <typename... Args>
struct Outer {
template <typename T, bool v = (sizeof(T) > 0)>
struct Check {};
using Result = Pack<Check<std::decay_t<Args>>...>;
};
The file is compiled against libc++ only; the Linux sysroot is used for the C
library headers. Compile command (also in repro_standalone_compile.sh):
clang++ -std=c++23 -nostdinc++ \
-isystem <chromium>/src/third_party/libc++/src/include \
-isystem <chromium>/src/third_party/libc++abi/src/include \
-isystem <chromium>/src/buildtools/third_party/libc++ \
--sysroot=<chromium>/src/build/linux/debian_bullseye_amd64-sysroot \
-fno-exceptions -fno-rtti \
-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_EXTENSIVE \
-c repro_standalone.cc -o repro_standalone.o
Database creation:
codeql database create repro-standalone-db --language=cpp --source-root=. \
--command="sh repro_standalone_compile.sh"
Observed output:
Warning[extractor-c++]: In construct_text_message: "repro_standalone.cc", line 5:
internal error: assertion failed at: "templates.c", line 3973
in coordinates_of_template_param_symbol
template <typename T, bool v = (sizeof(T) > 0)>
^
Warning[extractor-c++]: In main: Extractor exiting with code 4
Expected: database creation succeeds.
Actual: the extractor aborts with exit code 4. The full log is attached as
logs/standalone_extractor.log.
libc++ is required for this reproduction - the same file compiled against
libstdc++ does not crash.
Reproduction B - real Chromium code
repro_chromium_compile.sh contains the compile command that GN uses for
obj/base/base/concurrent_closures.o in out/release, with the Clang module
flags removed (-DUSE_LIBCXX_MODULES, -fmodules,
-fno-implicit-module-maps, -fno-implicit-modules,
-fmodules-local-submodule-visibility, -fmodules-disable-diagnostic-validation,
-fmodule-file-home-is-cwd, -fmodules-cache-path=...,
-fmodule-map-file=..., -fmodule-file=..., -fmodule-name=...), i.e. the
configuration that results from use_clang_modules = false. All other flags are
unchanged and the object file is written to /tmp.
B1 - real Chromium translation unit
base/functional/concurrent_closures.cc is an ordinary Chromium source file of
the //base:base target. Compiling it with the command above aborts the
extractor:
Warning[extractor-c++]: In construct_text_message:
"../../base/functional/bind_internal.h", line 1227:
internal error: assertion failed at: "templates.c", line 3973
in coordinates_of_template_param_symbol
(IsRawRef<T> && IsRefCountedType<base::RemoveRawRefT<T>>) ||
^
Warning[extractor-c++]: In main: Extractor exiting with code 4
Log: logs/chromium_real_tu_extractor.log.
The database creation still reports success, but the translation unit is lost:
this run imports 1.40 KiB of relations, whereas a control run of the same
pipeline on a small standalone file that does not trigger the assertion
(variant 4 below) imports 410.64 KiB. In other words, the affected
translation unit contributes essentially no entities.
B2 - include-only minimisation
repro_chromium.cc is a single line:
#include "base/functional/bind.h"
Compiled with the same command (only the -c argument is changed:
sh repro_chromium_compile.sh repro_chromium.cc), it produces the same
assertion at the same location. Log:
logs/chromium_include_only_extractor.log.
Chromium code involved
base/functional/bind_internal.h:1227:
template <typename... BoundArgs>
struct ValidateBindStateTypeCommonChecks {
private:
template <typename T,
bool v =
(IsRawRef<T> && IsRefCountedType<base::RemoveRawRefT<T>>) ||
(IsPointerOrRawPtr<T> && IsRefCountedType<base::RemovePointerT<T>>)>
struct RefCountedTypeNotPassedByRawPointer { ... };
public:
using CommonCheckResult = std::conjunction<
RefCountedTypeNotPassedByRawPointer<std::decay_t<BoundArgs>>...,
ValidateStorageTraits<BoundArgs>...>;
};
Minimization
The standalone reproduction was minimized by changing one thing at a time and
re-running codeql database create. Each variant below was extracted on its
own:
- Reproducer as shown above (control) - extractor crashes, exit code 4.
std::remove_cv_t<Args>in place ofstd::decay_t<Args>- extractor
crashes, exit code 4.typename std::decay<Args>::typein place of thestd::decay_t<Args>
alias - no crash.- Single type parameter (
template <typename Arg>) in place of the pack
Args...- no crash. - Pack-expansion use of the member template removed
(using Result = Pack<>;) - no crash. - Non-type parameter and its default argument removed
(template <typename T> struct Check {};) - no crash. - libstdc++ in place of libc++ - no crash.
Variants 1 and 2 together show that the failure is not specific to decay_t:
any libc++ alias template applied to the pack triggers it, while the non-alias
form (variant 3) does not.
The final reproducer contains no concepts, no std::conjunction, no
static_assert, no lambda and no Chromium header, so none of these is required
for the crash.
Trigger description:
A class template with a parameter pack
Args...contains a member class
templatetemplate <typename T, bool v = <expression depending on T>>, and the
member template is used asPack<Check<std::decay_t<Args>>...>- i.e. a libc++
_talias template applied to the pack feeds the member template whose default
non-type argument references its own template parameter. The extractor aborts
while resolving the coordinates of the template parameter symbol
(templates.c:3973,coordinates_of_template_param_symbol).
Additional observation
In a database created from a full Chromium build with the default modularized
configuration, entities from module-imported headers never reach the database:
base::OnceCallback, base::RepeatingCallback and base::BindOnce have no
results, and practically no classes from base/ are present. This is the symptom
that led us to the crash above. We can supply a separate minimal reproduction for
it if it is useful.
Attachments and how to use them
README.md- the same instructions in one file, inside the attached package.repro_standalone.cc,repro_standalone_compile.sh- standalone
reproduction (Reproduction A). Compile with
SRC=<chromium>/src sh repro_standalone_compile.sh, or let CodeQL drive it
withcodeql database create repro-standalone-db --language=cpp --source-root=. --command="sh repro_standalone_compile.sh". The script only
needs a libc++ and a Linux sysroot, no Chromium code.repro_chromium.cc,repro_chromium_compile.sh- Chromium reproduction
(Reproduction B). The script must run with<chromium>/src/out/releaseas the
working directory and the absolute paths inside it adapted to the checkout.sh repro_chromium_compile.shcompiles the real translation unit
base/functional/concurrent_closures.cc(B1).sh repro_chromium_compile.sh repro_chromium.cccompiles the include-only
file instead (B2).- Under CodeQL:
codeql database create repro-chromium-db --language=cpp --source-root=<chromium>/src --command="sh repro_chromium_compile.sh".
logs/standalone_extractor.log- extractor log for A, showing the assertion.logs/chromium_real_tu_extractor.log- extractor log for the real translation
unit (B1).logs/chromium_include_only_extractor.log- extractor log for the include-only
file (B2).
- 主要言語
- CodeQL
- スター
- 10.1k
- フォーク
- 2.1k
- 平均マージ
- 2日 17時間
- マージ済み PR(30日)
- 145
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
github/codeql のほかの issue
-
agentic-workflows
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
-
false-positive javascript
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100
-
C#: cs/simplifiable-boolean-expression false positive on Nullable<bool> compared with a literal オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
-
false-positive
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
JakeChampion/lang#10213 ·
-
bug language-server
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
purefunctor/purescript-iris#552 ·
-
enhancement good first issue needs testing
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
bradcypert/plum#58 ·