Skip to content

Conversation

@MathiasVP
Copy link
Contributor

@MathiasVP MathiasVP commented Jan 9, 2026

In C/C++, assertions are often done via a macro defined like:

#ifdef NDEBUG
#define assert(condition) ((void)0)
#else
#define assert(condition) /* implementation defined */
#endif

where /* implementation defined */ represents the actual operation that implements the assertion in a debug build.

However, in a release build (i.e., when NDEBUG is defined) then no check is performed. This is great for performance, but it means the CodeQL database has no way of observing these conditions. And these conditions often help us remove FPs (i.e., a null check or an index validation prior to a dereference).

This PR adds support for identifying (a small subset of) assertions by generating IR corresponding to the check which would have been performed had assertions been enabled (the rationale being basically the same as what Schack wrote for Java here).

This PR only covers a small subset of assertions since we only have the assertion as text since this is a macro argument. So we have to parse that macro argument in QL 😭. Because of this, I've limited this PR to only genearte IR for an assertion of the form E op E where E is an integer constant, or a local variable, and op is =, !=, <, >, <=, or >=. (Locally, I have a follow-up PR to add support for negations, disjunctions, and conjunctions.)

As I didn't feel like implementing all of C++'s conversion rules the generated IR will also not be totally conversion-correct. For example, in an expression like x < y where x is int and y is unsigned int there would normally be a signed-to-unsigned conversion on x but currently we simply generate a comparison between types of different types. I don't imagine this will be a problem in practice, though.

Commit-by-commit review recommended.

The three new alerts look genuine. They arise because we now realize that there's a suspicious looking assertion here which ought to have been fhSize < dstCapacity.

@github-actions github-actions bot added the C++ label Jan 9, 2026
@MathiasVP MathiasVP force-pushed the ir-support-for-assertions branch 3 times, most recently from 0cf33ff to 20c0239 Compare January 12, 2026 12:00
@MathiasVP MathiasVP marked this pull request as ready for review January 12, 2026 19:30
@MathiasVP MathiasVP requested a review from a team as a code owner January 12, 2026 19:30
Copilot AI review requested due to automatic review settings January 12, 2026 19:30
@MathiasVP MathiasVP added the no-change-note-required This PR does not need a change note label Jan 12, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds support for generating IR for assertions in C++ release builds where they would normally be compiled out. The implementation parses macro arguments from assertion macros (like assert and __analysis_assume) to synthesize the conditional checks that would have been present in debug builds, helping CodeQL remove false positives by understanding assertion constraints.

Changes:

  • Adds new TranslatedAssertion.qll module that parses assertion macro arguments and generates synthetic IR for simple comparisons
  • Updates TranslatedStmt.qll and TranslatedElement.qll to exclude assertion statements from normal translation
  • Adds new instruction tags and test coverage for assertion IR generation

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedAssertion.qll New module implementing assertion parsing and IR generation for simple comparison assertions
cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll Excludes assertion statements from normal translation to avoid duplication
cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll Integrates assertion translation into the element translation framework
cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/InstructionTag.qll Adds four new instruction tags for assertion IR generation
cpp/ql/lib/semmle/code/cpp/stmts/Stmt.qll Adds override for getEnclosingFunction() in StmtParent base class
cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll Adds override keyword to getEnclosingFunction()
cpp/ql/lib/semmle/code/cpp/Element.qll Adds new isAffectedByMacro(MacroInvocation) predicate
cpp/ql/test/library-tests/ir/ir/ir.cpp Adds test cases for assertion IR generation including templates and shadowed variables
cpp/ql/test/library-tests/ir/ir/raw_ir.expected Expected IR output for assertion tests
cpp/ql/test/library-tests/ir/ir/aliased_ir.expected Expected aliased IR output for assertion tests
cpp/ql/test/library-tests/ir/ir/PrintAST.expected Expected AST output for assertion tests
Comments suppressed due to low confidence (1)

cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll:330

  • The comment has a typo: "synthedsize" should be "synthesize".
    // we synthedsize the check that would have occurred.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@MathiasVP MathiasVP force-pushed the ir-support-for-assertions branch from 4370bc6 to 4f4baee Compare January 12, 2026 21:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C++ no-change-note-required This PR does not need a change note

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant