Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions cpp/ql/lib/change-notes/2026-08-21-compiler-generated.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Initializers of compiler-generated variables are now recognized as compiler-generated. A new predicate `isCompilerGenerated` on `Initializer` has been added to reflect this.
11 changes: 11 additions & 0 deletions cpp/ql/lib/semmle/code/cpp/Initializer.qll
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,15 @@ class Initializer extends ControlFlowNode, @initialiser {

/** Holds if the initializer used the C++ braced initializer notation. */
predicate isBraced() { braced_initialisers(underlyingElement(this)) }

/** Holds if this initializer is generated by the compiler. */
predicate isCompilerGenerated() {
exists(Variable v |
v = this.getDeclaration() and
// We require the variable to be an orphan to not mark the initializer
// from a desugared ranged for loop as compiler generated.
orphaned_variables(unresolveElement(v), _) and
v.isCompilerGenerated()
)
Comment on lines +59 to +66

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is really an edge case, but I wonder whether there are some initializers related to coroutines that should be marked as compiler generated? However, we can always deal with those when the need arises (no immediate need here).

}
}
3 changes: 2 additions & 1 deletion cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ class Expr extends StmtParent, @expr {
/** Holds if this is an auxiliary expression generated by the compiler. */
predicate isCompilerGenerated() {
compgenerated(underlyingElement(this)) or
this.getParent().(ConstructorFieldInit).isCompilerGenerated()
this.getParent().(ConstructorFieldInit).isCompilerGenerated() or
this.getParent().(Initializer).isCompilerGenerated()
Comment thread
MathiasVP marked this conversation as resolved.
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,31 @@
| cpp.cpp:15:5:15:12 | call to ~MyClass | Expr |
| cpp.cpp:15:12:15:12 | reuse of m | Expr |
| cpp.cpp:16:1:16:1 | return ... | Stmt |
| cpp.cpp:19:26:19:44 | __PRETTY_FUNCTION__ | Variable |
| cpp.cpp:19:26:19:44 | array to pointer conversion | Expr |
| cpp.cpp:19:26:19:44 | initializer for __PRETTY_FUNCTION__ | Initializer |
| cpp.cpp:19:26:19:44 | void uses_pretty_function() | Expr |
| cpp.cpp:20:1:20:1 | return ... | Stmt |
| cpp.cpp:23:29:23:32 | args | Variable |
| cpp.cpp:23:37:23:37 | return ... | Stmt |
| cpp.cpp:23:37:23:37 | return ... | Stmt |
| cpp.cpp:27:1:27:1 | return ... | Stmt |
| cpp.cpp:31:5:31:5 | (__begin) | Variable |
| cpp.cpp:31:5:31:5 | (__end) | Variable |
| cpp.cpp:31:5:31:5 | (__range) | Variable |
| cpp.cpp:31:5:33:5 | declaration | Stmt |
| cpp.cpp:31:5:33:5 | declaration | Stmt |
| cpp.cpp:31:5:33:5 | declaration | Stmt |
| cpp.cpp:31:17:31:18 | (reference to) | Expr |
| cpp.cpp:34:1:34:1 | return ... | Stmt |
| file://:0:0:0:0 | (__begin) | Expr |
| file://:0:0:0:0 | (__begin) | Expr |
| file://:0:0:0:0 | (__begin) | Expr |
| file://:0:0:0:0 | (__end) | Expr |
| file://:0:0:0:0 | (reference dereference) | Expr |
| file://:0:0:0:0 | (reference dereference) | Expr |
| file://:0:0:0:0 | * ... | Expr |
| file://:0:0:0:0 | array to pointer conversion | Expr |
| file://:0:0:0:0 | array to pointer conversion | Expr |
| file://:0:0:0:0 | operator delete | Function |
| file://:0:0:0:0 | operator new | Function |
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@ where
e.(Variable).isCompilerGenerated() and type = "Variable"
or
e.(Stmt).isCompilerGenerated() and type = "Stmt"
or
e.(Initializer).isCompilerGenerated() and type = "Initializer"
select e, type
17 changes: 17 additions & 0 deletions cpp/ql/test/library-tests/compiler_generated/cpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,20 @@ void g1(void) {
delete m;
}

void uses_pretty_function() {
const char* pretty = __PRETTY_FUNCTION__;
}

template <typename... Args>
void parameter_pack(Args... args) { }

void test_parameter_pack() {
parameter_pack();
}

void ranged_for() {
int vs[] = {1, 2, 3};
for(int i : vs) {

}
}
Comment thread
jketema marked this conversation as resolved.
Loading