mirror of
https://github.com/DeusData/codebase-memory-mcp.git
synced 2026-11-04 10:48:20 +00:00
The test only covered a whitelisted finding. The defect in #2442 is the other direction: on main clang-tidy reported findings that carry the ,-warnings-as-errors suffix, the old FINDING_RE matched none of them, and the gate reported clean. Pin that direction too: a second fixture function with no whitelist entry, a suffixed finding inside it, and the gate must exit 1 and report the finding under its plain check name ([clang-analyzer-core.NullDereference], the whitelist key form) as an entry missing for unlisted(). With the suffix group of FINDING_RE reverted, this case exits 0 with "memory gate clean" and the test fails, naming all three assertions. A parser that accepts the line but keeps the suffix inside the check name fails it as well. The negative assertion is a maintainer decision (R1). Refs #2442 Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
106 lines
4.2 KiB
Bash
Executable File
106 lines
4.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Regression contract for clang-tidy's `,-warnings-as-errors` diagnostic suffix
|
|
# (#2442). With WarningsAsErrors enabled, clang-tidy prints an analyzer check as
|
|
# [clang-analyzer-<check>,-warnings-as-errors]; a gate that only accepts
|
|
# [<check>] drops every such line and reports a clean gate. Both directions are
|
|
# pinned, and every assertion is reported, so a regression names what broke:
|
|
# 1. a suffixed finding WITH an argued whitelist entry is counted under its
|
|
# plain check name and suppressed (exit 0, "1 argued false positive");
|
|
# 2. a suffixed finding WITHOUT an entry fails the gate (exit 1) and is
|
|
# reported under its plain check name. This is the negative assertion: a
|
|
# parser that drops the suffixed line reports clean (exit 0) here.
|
|
# Reverting the suffix group in FINDING_RE (scripts/lint-mem-gate.py) turns
|
|
# both red.
|
|
#
|
|
# The gate runs from inside the fixture directory with RELATIVE paths. On the
|
|
# Windows leg python3 is a native MSYS2 build: MSYS converts path ARGUMENTS for
|
|
# it, but never the diagnostic text on stdin, so an absolute /c/... path in a
|
|
# finding would not resolve there, and a C:/... one would not parse (the file
|
|
# field ends at the first colon).
|
|
set -euo pipefail
|
|
|
|
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
GATE="$ROOT/scripts/lint-mem-gate.py"
|
|
FIX="$(mktemp -d "${TMPDIR:-/tmp}/lint-mem-gate.XXXXXX")"
|
|
trap 'rm -rf "$FIX"' EXIT
|
|
|
|
failures=0
|
|
fail() {
|
|
echo "FAIL: $*" >&2
|
|
failures=$((failures + 1))
|
|
}
|
|
|
|
show() {
|
|
sed 's/^/ | /' "$1" >&2
|
|
}
|
|
|
|
# A subshell, so the test's own shell never sits inside $FIX (Windows cannot
|
|
# remove a directory that is a process's working directory).
|
|
run_gate() {
|
|
(cd "$FIX" && LINT_MEM_WHITELIST=whitelist.txt python3 "$GATE" "$@")
|
|
}
|
|
|
|
cat > "$FIX/sample.c" <<'EOF'
|
|
int sample(int *value) {
|
|
return *value;
|
|
}
|
|
|
|
int unlisted(int *value) {
|
|
return *value;
|
|
}
|
|
EOF
|
|
|
|
# A native Windows python3 writes CRLF; strip it before the hash is reused.
|
|
HASH="$(run_gate --hash sample.c sample | tr -d '\r' | awk '/^segment-sha256:/ {print $2}')"
|
|
if [[ ! "$HASH" =~ ^[0-9a-f]{64}$ ]]; then
|
|
echo "FAIL: lint-mem-gate.py --hash sample.c sample printed no segment hash (got '$HASH')" >&2
|
|
exit 1
|
|
fi
|
|
|
|
cat > "$FIX/whitelist.txt" <<EOF
|
|
## sample.c :: sample :: clang-analyzer-core.NullDereference
|
|
segment-sha256: $HASH
|
|
why: |
|
|
The test deliberately models a diagnostic that is suppressed by the fixture whitelist.
|
|
This text is long enough to exercise the gate's normal argument validation path.
|
|
tried: |
|
|
The fixture is intentionally minimal and only verifies diagnostic parsing.
|
|
EOF
|
|
|
|
SUFFIX='[clang-analyzer-core.NullDereference,-warnings-as-errors]'
|
|
|
|
# 1. Whitelisted: counted under the plain check name, then suppressed.
|
|
rc=0
|
|
printf '%s\n' "sample.c:2:12: warning: possible null dereference $SUFFIX" \
|
|
| run_gate > /dev/null 2> "$FIX/whitelisted.err" || rc=$?
|
|
if [ "$rc" -ne 0 ]; then
|
|
fail "a whitelisted suffixed finding left the gate at exit $rc, expected 0"
|
|
show "$FIX/whitelisted.err"
|
|
fi
|
|
if ! grep -q 'memory gate clean (1 argued false positive' "$FIX/whitelisted.err"; then
|
|
fail "a whitelisted suffixed finding was not counted as 1 argued false positive"
|
|
show "$FIX/whitelisted.err"
|
|
fi
|
|
|
|
# 2. Not whitelisted: the gate must fail and name the finding.
|
|
rc=0
|
|
printf '%s\n' "sample.c:6:12: warning: possible null dereference $SUFFIX" \
|
|
| run_gate > /dev/null 2> "$FIX/unlisted.err" || rc=$?
|
|
if [ "$rc" -ne 1 ]; then
|
|
fail "an unwhitelisted suffixed finding left the gate at exit $rc, expected 1" \
|
|
"(exit 0 = the suffixed line was parsed as no finding, #2442)"
|
|
show "$FIX/unlisted.err"
|
|
fi
|
|
if ! grep -qF 'sample.c:6: possible null dereference [clang-analyzer-core.NullDereference]' "$FIX/unlisted.err" ||
|
|
! grep -qF 'no whitelist entry for unlisted()' "$FIX/unlisted.err" ||
|
|
! grep -qF '1 finding(s) unaccounted for' "$FIX/unlisted.err"; then
|
|
fail "the gate did not report the unwhitelisted suffixed finding under its plain check name"
|
|
show "$FIX/unlisted.err"
|
|
fi
|
|
|
|
if [ "$failures" -ne 0 ]; then
|
|
echo "lint-mem-gate warning suffix contract: $failures assertion(s) failed" >&2
|
|
exit 1
|
|
fi
|
|
echo 'lint-mem-gate warning suffix contract passed (whitelisted + unwhitelisted suffixed findings)'
|