Skip to content

A program that checks builds when a C++ compiler calls a self-assignment, a self-comparison or an unsigned comparison with zero pointless - #187

Open
SamMausberg wants to merge 2 commits into
mainfrom
c13/accepted-builds
Open

SamMausberg wants to merge 2 commits into
mainfrom
c13/accepted-builds

Conversation

@SamMausberg

Copy link
Copy Markdown
Owner

Summary

A program that checks now builds when a C++ compiler calls part of it pointless. The default build makes every C++ warning an error, and before this change it refused

fn negative[T:integer](x:T) -> bool = x < 0;

fn main() -> i32 {
  let mut seen:u64 = 0;
  seen = seen;
  let ok = seen == 0;
  if ok != ok { return 1; }
  let mut w:u8 = 5;
  while w < 0 { w += 1; }
  let b:i64 = -3;
  if negative(seen) || !negative(b) { return 3; }
  if w >= 0 { return 0; }
  return 2;
}

which cairn check accepts: clang++ on seen = seen (-Wself-assign), both compilers on ok != ok (-Wtautological-compare), and g++ on w < 0, w >= 0 and the u64 instance of negative (-Wtype-limits). cairn run said it was "a fault of the CAIRN compiler, never of the program", which was right.

Motivation

Part of #36. The typed fuzzer I am building for #36 found this in its first batch: 23 of the first 96 programs it built under the default flags, seed 2, failed this way, and every one cut down to one of three statements, a self-assignment, a self-comparison or an unsigned comparison with zero. The generic negative is the form an agent is likely to meet: a bound of integer covers signed and unsigned types, each instance is its own C++ function, and g++ judges the unsigned one on its own.

Each of the three means in C++ what it means in CAIRN: a self-assignment does nothing, an integer compared with itself is equal, and an unsigned value is never below zero. The warnings are advice about the source, and CAIRN's source already has one meaning for them, so the build stops treating them as errors, as it already does for a local that is never read (-Wno-unused-variable). The alternative was to refuse these forms in the checker, which would be a language change that refuses correct programs, or to have the emitter rewrite them, which would hide what the program says. nvcc's own front end refuses the unsigned comparison with zero too (#186), in device code and in the host code of a device program, so it is suppressed there beside 177 and 550.

Changes

  • projects (projects/toolchain.py): WARNINGS adds -Wno-self-assign, -Wno-tautological-compare and -Wno-type-limits; DEVICE_WARNINGS suppresses 186. GCC ignores -Wno-self-assign, which it does not know.
  • tests (tests/soundness/test_fuzz_findings.py, new): the program above built as cairn build builds it and run under clang++ and g++, and the same forms in a device lane and beside it compiled by nvcc for sm_120. The file is where the fuzzer's regression programs will go. The Makefile's DEVICE_TESTS names the nvcc test, so the device job compiles it.

Behaviour and compatibility

Every host build, sanitized build, freestanding image, nvcc host pass and incremental unit gets the three flags, and every device build suppresses one more nvcc diagnostic. A program that built before builds the same, since a flag that turns a warning off changes no code. Programs with these forms, refused by the native build until now, build. No diagnostic code, emitted C++ or CUDA changes.

Testing

make lint                                                   # clean
python -m pytest -q tests -n 4                              # 6226 passed, 7 failed, 58 skipped
python -m pytest -q -n 4 tests/tooling/test_workflow.py tests/soundness/test_fuzz_findings.py tests/soundness/test_endless.py   # 31 passed

Six of the seven failures are the g++ ThreadSanitizer tests main fails on this machine (GCC 11's libtsan on this aarch64 kernel). The seventh was test_workflow.py asking for the new nvcc test in the Makefile's DEVICE_TESTS, which it now is; the second command ran after that. Without the change the three new tests fail: clang++ on -Wself-assign and -Wtautological-compare, g++ on -Wtautological-compare and -Wtype-limits, and nvcc 13.0 on #186 twice. Clang 14 and GCC 11.4 are what this machine has; the floor README names is Clang 13 and GCC 11, and each of the three flags is older than both. Nothing ran on a device: the nvcc test compiles only.

Evidence and claims

The native-built claim now holds for accepted programs with these three forms, which it did not. No other claim changes.

Performance

none: the flags silence diagnostics and change no generated code.

Checklist

  • The title is one plain sentence saying what is now true; it becomes the squash commit's subject
  • Every behaviour added has a test, and every new refusal a rejection test naming its code (no refusal is added)
  • The documentation is updated in the file that owns the subject, and its examples compile (no document states the flags)
  • Generated files are current (make editors, make docs): nothing they generate from changed
  • A language change carries everything AGENTS.md lists: not a language change
  • No emojis, no attribution trailers, nothing unrelated to the change

@SamMausberg
SamMausberg enabled auto-merge (squash) September 28, 2026 19:36
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-28T19:39:42.277865Z bdd07c3 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant