Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

C++: Fix conflation in barrier guards #21171

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
MathiasVP wants to merge 6 commits into github:main
base: main
Choose a base branch
Loading
from MathiasVP:fix-conflation-in-guards

Conversation

@MathiasVP
Copy link
Contributor

@MathiasVP MathiasVP commented Jan 15, 2026
edited
Loading

While working on MaD support for barriers/barrier guards for C/C++ I discovered a bug related to indirect barrier guards. This PR fixes that bug at the cost of:

  • Exposing a predicate that was private in the shared Guards library, and
  • Losing a small bit of smartness in barrier guards related to stuff like:
    if(x == y && clean(x)) {
     sink(y); // okay because `clean` is a barrier and `x == y`
    }

The problem is that (as @aschackmull also discovered when we were porting C++ to the shared SSA library's dataflow integration layer) we cannot relate an SsaDefinition to an Instruction without an indirection index. So on something like:

void foo(int* p) {
 if (validate_indirection(p)) {
 sink(*p);
 }
}

When guardChecksInstr says that p is a barrier guard with indirection 1 guardChecksDef finds the associated Ssa definition for p (and not its indirection, *p, since guardReadsSsaVar doesn't have access to the indirection index) and places a barrier on &p, p, and *p instead of just *p like it was intended.

I can imagine better fixes for this. In particular:

  • Thread an additional language-supplied data column through the guards library and make it available for getARead.
  • C/C++ instantiates the shared Guards library with AstNode = (Instruction, int) instead of AstNode = Instruction like we do currently. This should be totally doable (albeit with another breaking change to the barrier guards library for C/C++ 😭)

@aschackmull do you have any thoughts on this?

In the first commit I switch dataflow to use Type instead of DataFlowType. This may look scary, but DataFlowType is just Type with an empty toString (see here). This was necessary to create the testcase I wanted.

@MathiasVP MathiasVP changed the title (削除) Fix conflation in guards (削除ここまで) (追記) C++: Fix conflation in barrier guards (追記ここまで) Jan 15, 2026
Copy link
Contributor

The fix as-is looks reasonable, I think. I don't think the two alternatives you list sound very appealing.

MathiasVP reacted with thumbs up emoji

@MathiasVP MathiasVP marked this pull request as ready for review January 16, 2026 12:20
@MathiasVP MathiasVP requested a review from a team as a code owner January 16, 2026 12:20
Copilot AI review requested due to automatic review settings January 16, 2026 12:20
@MathiasVP MathiasVP requested a review from a team as a code owner January 16, 2026 12:20
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 fixes a bug in C++ barrier guards related to indirect barrier guards. The issue was that guardChecksDef couldn't properly handle indirection indices when relating an SsaDefinition to an Instruction, leading to barriers being incorrectly placed at all indirection levels (e.g., &p, p, and *p) instead of just the intended level (e.g., only *p).

Changes:

  • Exposed the guardChecks predicate in the shared Guards library by changing it from private to public
  • Reimplemented guardChecksWithWrappers in C++ to call guardChecks directly and manually match instructions to SSA definitions with proper indirection handling
  • Changed the return type of Node.getType() and related methods from DataFlowType to Type throughout the C++ dataflow library
  • Updated model generator to use Cpp::Type instead of DataFlowPrivate::DataFlowType
  • Updated test expectations to display type information for barrier nodes

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
shared/controlflow/codeql/controlflow/Guards.qll Exposed guardChecks predicate by removing private modifier
cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImpl.qll Reimplemented guardChecksWithWrappers to properly handle indirection indices by calling guardChecks directly
cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll Changed Node.getType() and related methods to return Type instead of DataFlowType
cpp/ql/src/utils/modelgenerator/internal/CaptureModels.qll Updated to use Cpp::Type instead of DataFlowPrivate::DataFlowType
cpp/ql/src/Security/CWE/CWE-120/UnboundedWrite.ql Added indirect barrier nodes to the barrier predicate
cpp/ql/test/library-tests/dataflow/ir-barrier-guards/test.ql Updated test to display type information for both direct and indirect barrier nodes
cpp/ql/test/library-tests/dataflow/ir-barrier-guards/test.cpp Added new test case and updated expected results with type information
Comments suppressed due to low confidence (1)

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImpl.qll:56

  • The return type DataFlowType should be changed to Type to be consistent with the changes made throughout the dataflow library.
 DataFlowType getType() {

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

Copy link
Contributor Author

DCA looks fine. Initially we lost some barriers on cpp/unbounded-write. I've verified that the nodes were previously marked as barriers because of the pointer/pointee conflation in the BarrierGuard that we're fixing in this PR. This resulted in some new results that wasn't in line with what the query intended to catch.

I've fixed the query in 6da7890 by putting a similar barrier on the indirections. This results in a few more suppressed results which looks like the correct behavior to me.

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

Reviewers

Copilot code review Copilot Copilot left review comments

At least 1 approving review is required to merge this pull request.

Assignees

No one assigned

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

AltStyle によって変換されたページ (->オリジナル) /