Skip to content

Commit 04641a3

Browse files
author
Robert Marsh
committed
Merge branch 'main' into rdmarsh/cpp/use-taint-configuration-dtt
2 parents c2e44fa + b9b6a35 commit 04641a3

49 files changed

Lines changed: 3944 additions & 3245 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRBlock.qll

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,46 @@ class IRBlock extends IRBlockBase {
163163
not strictlyDominates(result)
164164
}
165165

166+
/**
167+
* Holds if this block immediately post-dominates `block`.
168+
*
169+
* Block `A` immediate post-dominates block `B` if block `A` strictly post-dominates block `B` and
170+
* block `B` is a direct successor of block `A`.
171+
*/
172+
final predicate immediatelyPostDominates(IRBlock block) {
173+
blockImmediatelyPostDominates(this, block)
174+
}
175+
176+
/**
177+
* Holds if this block strictly post-dominates `block`.
178+
*
179+
* Block `A` strictly post-dominates block `B` if block `A` post-dominates block `B` and blocks `A`
180+
* and `B` are not the same block.
181+
*/
182+
final predicate strictlyPostDominates(IRBlock block) {
183+
blockImmediatelyPostDominates+(this, block)
184+
}
185+
186+
/**
187+
* Holds if this block is a post-dominator of `block`.
188+
*
189+
* Block `A` post-dominates block `B` if any control flow path from `B` to the exit block of the
190+
* function must pass through block `A`. A block always post-dominates itself.
191+
*/
192+
final predicate postDominates(IRBlock block) { strictlyPostDominates(block) or this = block }
193+
194+
/**
195+
* Gets a block on the post-dominance frontier of this block.
196+
*
197+
* The post-dominance frontier of block `A` is the set of blocks `B` such that block `A` does not
198+
* post-dominate block `B`, but block `A` does post-dominate an immediate successor of block `B`.
199+
*/
200+
pragma[noinline]
201+
final IRBlock postPominanceFrontier() {
202+
postDominates(result.getASuccessor()) and
203+
not strictlyPostDominates(result)
204+
}
205+
166206
/**
167207
* Holds if this block is reachable from the entry block of its function.
168208
*/
@@ -280,3 +320,12 @@ private module Cached {
280320
}
281321

282322
private Instruction getFirstInstruction(TIRBlock block) { block = MkIRBlock(result) }
323+
324+
private predicate blockFunctionExit(IRBlock exit) {
325+
exit.getLastInstruction() instanceof ExitFunctionInstruction
326+
}
327+
328+
private predicate blockPredecessor(IRBlock src, IRBlock pred) { src.getAPredecessor() = pred }
329+
330+
private predicate blockImmediatelyPostDominates(IRBlock postDominator, IRBlock block) =
331+
idominance(blockFunctionExit/1, blockPredecessor/2)(_, postDominator, block)

cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRBlock.qll

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,46 @@ class IRBlock extends IRBlockBase {
163163
not strictlyDominates(result)
164164
}
165165

166+
/**
167+
* Holds if this block immediately post-dominates `block`.
168+
*
169+
* Block `A` immediate post-dominates block `B` if block `A` strictly post-dominates block `B` and
170+
* block `B` is a direct successor of block `A`.
171+
*/
172+
final predicate immediatelyPostDominates(IRBlock block) {
173+
blockImmediatelyPostDominates(this, block)
174+
}
175+
176+
/**
177+
* Holds if this block strictly post-dominates `block`.
178+
*
179+
* Block `A` strictly post-dominates block `B` if block `A` post-dominates block `B` and blocks `A`
180+
* and `B` are not the same block.
181+
*/
182+
final predicate strictlyPostDominates(IRBlock block) {
183+
blockImmediatelyPostDominates+(this, block)
184+
}
185+
186+
/**
187+
* Holds if this block is a post-dominator of `block`.
188+
*
189+
* Block `A` post-dominates block `B` if any control flow path from `B` to the exit block of the
190+
* function must pass through block `A`. A block always post-dominates itself.
191+
*/
192+
final predicate postDominates(IRBlock block) { strictlyPostDominates(block) or this = block }
193+
194+
/**
195+
* Gets a block on the post-dominance frontier of this block.
196+
*
197+
* The post-dominance frontier of block `A` is the set of blocks `B` such that block `A` does not
198+
* post-dominate block `B`, but block `A` does post-dominate an immediate successor of block `B`.
199+
*/
200+
pragma[noinline]
201+
final IRBlock postPominanceFrontier() {
202+
postDominates(result.getASuccessor()) and
203+
not strictlyPostDominates(result)
204+
}
205+
166206
/**
167207
* Holds if this block is reachable from the entry block of its function.
168208
*/
@@ -280,3 +320,12 @@ private module Cached {
280320
}
281321

282322
private Instruction getFirstInstruction(TIRBlock block) { block = MkIRBlock(result) }
323+
324+
private predicate blockFunctionExit(IRBlock exit) {
325+
exit.getLastInstruction() instanceof ExitFunctionInstruction
326+
}
327+
328+
private predicate blockPredecessor(IRBlock src, IRBlock pred) { src.getAPredecessor() = pred }
329+
330+
private predicate blockImmediatelyPostDominates(IRBlock postDominator, IRBlock block) =
331+
idominance(blockFunctionExit/1, blockPredecessor/2)(_, postDominator, block)

cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRBlock.qll

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,46 @@ class IRBlock extends IRBlockBase {
163163
not strictlyDominates(result)
164164
}
165165

166+
/**
167+
* Holds if this block immediately post-dominates `block`.
168+
*
169+
* Block `A` immediate post-dominates block `B` if block `A` strictly post-dominates block `B` and
170+
* block `B` is a direct successor of block `A`.
171+
*/
172+
final predicate immediatelyPostDominates(IRBlock block) {
173+
blockImmediatelyPostDominates(this, block)
174+
}
175+
176+
/**
177+
* Holds if this block strictly post-dominates `block`.
178+
*
179+
* Block `A` strictly post-dominates block `B` if block `A` post-dominates block `B` and blocks `A`
180+
* and `B` are not the same block.
181+
*/
182+
final predicate strictlyPostDominates(IRBlock block) {
183+
blockImmediatelyPostDominates+(this, block)
184+
}
185+
186+
/**
187+
* Holds if this block is a post-dominator of `block`.
188+
*
189+
* Block `A` post-dominates block `B` if any control flow path from `B` to the exit block of the
190+
* function must pass through block `A`. A block always post-dominates itself.
191+
*/
192+
final predicate postDominates(IRBlock block) { strictlyPostDominates(block) or this = block }
193+
194+
/**
195+
* Gets a block on the post-dominance frontier of this block.
196+
*
197+
* The post-dominance frontier of block `A` is the set of blocks `B` such that block `A` does not
198+
* post-dominate block `B`, but block `A` does post-dominate an immediate successor of block `B`.
199+
*/
200+
pragma[noinline]
201+
final IRBlock postPominanceFrontier() {
202+
postDominates(result.getASuccessor()) and
203+
not strictlyPostDominates(result)
204+
}
205+
166206
/**
167207
* Holds if this block is reachable from the entry block of its function.
168208
*/
@@ -280,3 +320,12 @@ private module Cached {
280320
}
281321

282322
private Instruction getFirstInstruction(TIRBlock block) { block = MkIRBlock(result) }
323+
324+
private predicate blockFunctionExit(IRBlock exit) {
325+
exit.getLastInstruction() instanceof ExitFunctionInstruction
326+
}
327+
328+
private predicate blockPredecessor(IRBlock src, IRBlock pred) { src.getAPredecessor() = pred }
329+
330+
private predicate blockImmediatelyPostDominates(IRBlock postDominator, IRBlock block) =
331+
idominance(blockFunctionExit/1, blockPredecessor/2)(_, postDominator, block)

csharp/extractor/Semmle.Extraction.CSharp/Semmle.Extraction.CSharp.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
</ItemGroup>
2121

2222
<ItemGroup>
23-
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.7.0" />
23+
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.8.0" />
2424
</ItemGroup>
2525

2626
</Project>

csharp/extractor/Semmle.Extraction/Semmle.Extraction.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
</PropertyGroup>
1616

1717
<ItemGroup>
18-
<PackageReference Include="Microsoft.CodeAnalysis" Version="3.7.0" />
18+
<PackageReference Include="Microsoft.CodeAnalysis" Version="3.8.0" />
1919
<PackageReference Include="GitInfo" Version="2.0.20">
2020
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
2121
<PrivateAssets>all</PrivateAssets>

csharp/ql/src/Bad Practices/Control-Flow/ConstantCondition.ql

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,23 @@ class ConstantBooleanCondition extends ConstantCondition {
3535

3636
override predicate isWhiteListed() {
3737
// E.g. `x ?? false`
38-
this.(BoolLiteral) = any(NullCoalescingExpr nce).getRightOperand()
38+
this.(BoolLiteral) = any(NullCoalescingExpr nce).getRightOperand() or
39+
// No need to flag logical operations when the operands are constant
40+
isConstantCondition(this.(LogicalNotExpr).getOperand(), _) or
41+
this =
42+
any(LogicalAndExpr lae |
43+
isConstantCondition(lae.getAnOperand(), false)
44+
or
45+
isConstantCondition(lae.getLeftOperand(), true) and
46+
isConstantCondition(lae.getRightOperand(), true)
47+
) or
48+
this =
49+
any(LogicalOrExpr loe |
50+
isConstantCondition(loe.getAnOperand(), true)
51+
or
52+
isConstantCondition(loe.getLeftOperand(), false) and
53+
isConstantCondition(loe.getRightOperand(), false)
54+
)
3955
}
4056
}
4157

@@ -51,7 +67,8 @@ class ConstantIfCondition extends ConstantBooleanCondition {
5167
or
5268
// It is a common pattern to use a local constant/constant field to control
5369
// whether code parts must be executed or not
54-
this instanceof AssignableRead
70+
this instanceof AssignableRead and
71+
not this instanceof ParameterRead
5572
}
5673
}
5774

csharp/ql/src/experimental/ir/implementation/raw/IRBlock.qll

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,46 @@ class IRBlock extends IRBlockBase {
163163
not strictlyDominates(result)
164164
}
165165

166+
/**
167+
* Holds if this block immediately post-dominates `block`.
168+
*
169+
* Block `A` immediate post-dominates block `B` if block `A` strictly post-dominates block `B` and
170+
* block `B` is a direct successor of block `A`.
171+
*/
172+
final predicate immediatelyPostDominates(IRBlock block) {
173+
blockImmediatelyPostDominates(this, block)
174+
}
175+
176+
/**
177+
* Holds if this block strictly post-dominates `block`.
178+
*
179+
* Block `A` strictly post-dominates block `B` if block `A` post-dominates block `B` and blocks `A`
180+
* and `B` are not the same block.
181+
*/
182+
final predicate strictlyPostDominates(IRBlock block) {
183+
blockImmediatelyPostDominates+(this, block)
184+
}
185+
186+
/**
187+
* Holds if this block is a post-dominator of `block`.
188+
*
189+
* Block `A` post-dominates block `B` if any control flow path from `B` to the exit block of the
190+
* function must pass through block `A`. A block always post-dominates itself.
191+
*/
192+
final predicate postDominates(IRBlock block) { strictlyPostDominates(block) or this = block }
193+
194+
/**
195+
* Gets a block on the post-dominance frontier of this block.
196+
*
197+
* The post-dominance frontier of block `A` is the set of blocks `B` such that block `A` does not
198+
* post-dominate block `B`, but block `A` does post-dominate an immediate successor of block `B`.
199+
*/
200+
pragma[noinline]
201+
final IRBlock postPominanceFrontier() {
202+
postDominates(result.getASuccessor()) and
203+
not strictlyPostDominates(result)
204+
}
205+
166206
/**
167207
* Holds if this block is reachable from the entry block of its function.
168208
*/
@@ -280,3 +320,12 @@ private module Cached {
280320
}
281321

282322
private Instruction getFirstInstruction(TIRBlock block) { block = MkIRBlock(result) }
323+
324+
private predicate blockFunctionExit(IRBlock exit) {
325+
exit.getLastInstruction() instanceof ExitFunctionInstruction
326+
}
327+
328+
private predicate blockPredecessor(IRBlock src, IRBlock pred) { src.getAPredecessor() = pred }
329+
330+
private predicate blockImmediatelyPostDominates(IRBlock postDominator, IRBlock block) =
331+
idominance(blockFunctionExit/1, blockPredecessor/2)(_, postDominator, block)

csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IRBlock.qll

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,46 @@ class IRBlock extends IRBlockBase {
163163
not strictlyDominates(result)
164164
}
165165

166+
/**
167+
* Holds if this block immediately post-dominates `block`.
168+
*
169+
* Block `A` immediate post-dominates block `B` if block `A` strictly post-dominates block `B` and
170+
* block `B` is a direct successor of block `A`.
171+
*/
172+
final predicate immediatelyPostDominates(IRBlock block) {
173+
blockImmediatelyPostDominates(this, block)
174+
}
175+
176+
/**
177+
* Holds if this block strictly post-dominates `block`.
178+
*
179+
* Block `A` strictly post-dominates block `B` if block `A` post-dominates block `B` and blocks `A`
180+
* and `B` are not the same block.
181+
*/
182+
final predicate strictlyPostDominates(IRBlock block) {
183+
blockImmediatelyPostDominates+(this, block)
184+
}
185+
186+
/**
187+
* Holds if this block is a post-dominator of `block`.
188+
*
189+
* Block `A` post-dominates block `B` if any control flow path from `B` to the exit block of the
190+
* function must pass through block `A`. A block always post-dominates itself.
191+
*/
192+
final predicate postDominates(IRBlock block) { strictlyPostDominates(block) or this = block }
193+
194+
/**
195+
* Gets a block on the post-dominance frontier of this block.
196+
*
197+
* The post-dominance frontier of block `A` is the set of blocks `B` such that block `A` does not
198+
* post-dominate block `B`, but block `A` does post-dominate an immediate successor of block `B`.
199+
*/
200+
pragma[noinline]
201+
final IRBlock postPominanceFrontier() {
202+
postDominates(result.getASuccessor()) and
203+
not strictlyPostDominates(result)
204+
}
205+
166206
/**
167207
* Holds if this block is reachable from the entry block of its function.
168208
*/
@@ -280,3 +320,12 @@ private module Cached {
280320
}
281321

282322
private Instruction getFirstInstruction(TIRBlock block) { block = MkIRBlock(result) }
323+
324+
private predicate blockFunctionExit(IRBlock exit) {
325+
exit.getLastInstruction() instanceof ExitFunctionInstruction
326+
}
327+
328+
private predicate blockPredecessor(IRBlock src, IRBlock pred) { src.getAPredecessor() = pred }
329+
330+
private predicate blockImmediatelyPostDominates(IRBlock postDominator, IRBlock block) =
331+
idominance(blockFunctionExit/1, blockPredecessor/2)(_, postDominator, block)

0 commit comments

Comments
 (0)