mirror of
https://github.com/github/codeql.git
synced 2026-04-23 07:45:17 +02:00
Merge pull request #16688 from MathiasVP/flow-through-builtin-bit-cast
C++: Fix IR generation for builtins and add flow through `__builtin_bit_cast`
This commit is contained in:
@@ -114,6 +114,13 @@ predicate conversionFlow(
|
||||
instrTo.(CheckedConvertOrNullInstruction).getUnaryOperand() = opFrom
|
||||
or
|
||||
instrTo.(InheritanceConversionInstruction).getUnaryOperand() = opFrom
|
||||
or
|
||||
exists(BuiltInInstruction builtIn |
|
||||
builtIn = instrTo and
|
||||
// __builtin_bit_cast
|
||||
builtIn.getBuiltInOperation() instanceof BuiltInBitCast and
|
||||
opFrom = builtIn.getAnOperand()
|
||||
)
|
||||
)
|
||||
or
|
||||
additional = true and
|
||||
|
||||
@@ -3208,9 +3208,20 @@ class TranslatedBuiltInOperation extends TranslatedNonConstantExpr {
|
||||
|
||||
final override Instruction getResult() { result = this.getInstruction(OnlyInstructionTag()) }
|
||||
|
||||
/**
|
||||
* Gets the rnk'th (0-indexed) child for which a `TranslatedElement` exists.
|
||||
*
|
||||
* We use this predicate to filter out `TypeName` expressions that sometimes
|
||||
* occur in builtin operations since the IR doesn't have an instruction to
|
||||
* represent a reference to a type.
|
||||
*/
|
||||
private TranslatedElement getRankedChild(int rnk) {
|
||||
result = rank[rnk + 1](int id, TranslatedElement te | te = this.getChild(id) | te order by id)
|
||||
}
|
||||
|
||||
final override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
if exists(this.getChild(0))
|
||||
then result = this.getChild(0).getFirstInstruction(kind)
|
||||
if exists(this.getRankedChild(0))
|
||||
then result = this.getRankedChild(0).getFirstInstruction(kind)
|
||||
else (
|
||||
kind instanceof GotoEdge and result = this.getInstruction(OnlyInstructionTag())
|
||||
)
|
||||
@@ -3230,11 +3241,11 @@ class TranslatedBuiltInOperation extends TranslatedNonConstantExpr {
|
||||
}
|
||||
|
||||
final override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
exists(int id | child = this.getChild(id) |
|
||||
result = this.getChild(id + 1).getFirstInstruction(kind)
|
||||
exists(int id | child = this.getRankedChild(id) |
|
||||
result = this.getRankedChild(id + 1).getFirstInstruction(kind)
|
||||
or
|
||||
kind instanceof GotoEdge and
|
||||
not exists(this.getChild(id + 1)) and
|
||||
not exists(this.getRankedChild(id + 1)) and
|
||||
result = this.getInstruction(OnlyInstructionTag())
|
||||
)
|
||||
}
|
||||
@@ -3249,7 +3260,7 @@ class TranslatedBuiltInOperation extends TranslatedNonConstantExpr {
|
||||
tag = OnlyInstructionTag() and
|
||||
exists(int index |
|
||||
operandTag = positionalArgumentOperand(index) and
|
||||
result = this.getChild(index).(TranslatedExpr).getResult()
|
||||
result = this.getRankedChild(index).(TranslatedExpr).getResult()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -52,3 +52,9 @@ void following_pointers( // $ ast-def=sourceStruct1_ptr ir-def=*cleanArray1 ir-d
|
||||
sink(stackArray); // $ ast,ir
|
||||
indirect_sink(stackArray); // $ ast ir=50:25 ir=50:35 ir=51:19
|
||||
}
|
||||
|
||||
void test_bitcast() {
|
||||
unsigned long x = source();
|
||||
double d = __builtin_bit_cast(double, x);
|
||||
sink(d); // $ ir MISSING: ast
|
||||
}
|
||||
@@ -153,6 +153,7 @@ irFlow
|
||||
| clang.cpp:50:25:50:30 | call to source | clang.cpp:53:17:53:26 | *stackArray |
|
||||
| clang.cpp:50:35:50:40 | call to source | clang.cpp:53:17:53:26 | *stackArray |
|
||||
| clang.cpp:51:19:51:24 | call to source | clang.cpp:53:17:53:26 | *stackArray |
|
||||
| clang.cpp:57:21:57:28 | call to source | clang.cpp:59:8:59:8 | d |
|
||||
| dispatch.cpp:9:37:9:42 | call to source | dispatch.cpp:35:16:35:25 | call to notSource1 |
|
||||
| dispatch.cpp:9:37:9:42 | call to source | dispatch.cpp:43:15:43:24 | call to notSource1 |
|
||||
| dispatch.cpp:10:37:10:42 | call to source | dispatch.cpp:36:16:36:25 | call to notSource2 |
|
||||
|
||||
@@ -22734,6 +22734,25 @@ ir.cpp:
|
||||
# 2552| Type = [Class] ClassWithDestructor
|
||||
# 2552| ValueCategory = xvalue
|
||||
# 2553| getStmt(1): [ReturnStmt] return ...
|
||||
# 2555| [TopLevelFunction] void builtin_bitcast(unsigned long)
|
||||
# 2555| <params>:
|
||||
# 2555| getParameter(0): [Parameter] ul
|
||||
# 2555| Type = [LongType] unsigned long
|
||||
# 2555| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 2556| getStmt(0): [DeclStmt] declaration
|
||||
# 2556| getDeclarationEntry(0): [VariableDeclarationEntry] definition of d
|
||||
# 2556| Type = [DoubleType] double
|
||||
# 2556| getVariable().getInitializer(): [Initializer] initializer for d
|
||||
# 2556| getExpr(): [BuiltInBitCast] __builtin_bit_cast
|
||||
# 2556| Type = [DoubleType] double
|
||||
# 2556| ValueCategory = prvalue
|
||||
# 2556| getChild(0): [TypeName] double
|
||||
# 2556| Type = [DoubleType] double
|
||||
# 2556| ValueCategory = prvalue
|
||||
# 2556| getChild(1): [VariableAccess] ul
|
||||
# 2556| Type = [LongType] unsigned long
|
||||
# 2556| ValueCategory = prvalue(load)
|
||||
# 2557| getStmt(1): [ReturnStmt] return ...
|
||||
perf-regression.cpp:
|
||||
# 4| [CopyAssignmentOperator] Big& Big::operator=(Big const&)
|
||||
# 4| <params>:
|
||||
|
||||
@@ -18351,6 +18351,24 @@ ir.cpp:
|
||||
# 2550| Block 2
|
||||
# 2550| v2550_10(void) = Unreached :
|
||||
|
||||
# 2555| void builtin_bitcast(unsigned long)
|
||||
# 2555| Block 0
|
||||
# 2555| v2555_1(void) = EnterFunction :
|
||||
# 2555| m2555_2(unknown) = AliasedDefinition :
|
||||
# 2555| m2555_3(unknown) = InitializeNonLocal :
|
||||
# 2555| m2555_4(unknown) = Chi : total:m2555_2, partial:m2555_3
|
||||
# 2555| r2555_5(glval<unsigned long>) = VariableAddress[ul] :
|
||||
# 2555| m2555_6(unsigned long) = InitializeParameter[ul] : &:r2555_5
|
||||
# 2556| r2556_1(glval<double>) = VariableAddress[d] :
|
||||
# 2556| r2556_2(glval<unsigned long>) = VariableAddress[ul] :
|
||||
# 2556| r2556_3(unsigned long) = Load[ul] : &:r2556_2, m2555_6
|
||||
# 2556| r2556_4(double) = BuiltIn[__builtin_bit_cast] : 0:r2556_3
|
||||
# 2556| m2556_5(double) = Store[d] : &:r2556_1, r2556_4
|
||||
# 2557| v2557_1(void) = NoOp :
|
||||
# 2555| v2555_7(void) = ReturnVoid :
|
||||
# 2555| v2555_8(void) = AliasedUse : m2555_3
|
||||
# 2555| v2555_9(void) = ExitFunction :
|
||||
|
||||
perf-regression.cpp:
|
||||
# 6| void Big::Big()
|
||||
# 6| Block 0
|
||||
|
||||
@@ -2552,4 +2552,8 @@ void constexpr_inconsistency(bool b) {
|
||||
;
|
||||
}
|
||||
|
||||
void builtin_bitcast(unsigned long ul) {
|
||||
double d = __builtin_bit_cast(double, ul);
|
||||
}
|
||||
|
||||
// semmle-extractor-options: -std=c++20 --clang
|
||||
|
||||
@@ -16693,6 +16693,23 @@ ir.cpp:
|
||||
# 2550| v2550_7(void) = AliasedUse : ~m?
|
||||
# 2550| v2550_8(void) = ExitFunction :
|
||||
|
||||
# 2555| void builtin_bitcast(unsigned long)
|
||||
# 2555| Block 0
|
||||
# 2555| v2555_1(void) = EnterFunction :
|
||||
# 2555| mu2555_2(unknown) = AliasedDefinition :
|
||||
# 2555| mu2555_3(unknown) = InitializeNonLocal :
|
||||
# 2555| r2555_4(glval<unsigned long>) = VariableAddress[ul] :
|
||||
# 2555| mu2555_5(unsigned long) = InitializeParameter[ul] : &:r2555_4
|
||||
# 2556| r2556_1(glval<double>) = VariableAddress[d] :
|
||||
# 2556| r2556_2(glval<unsigned long>) = VariableAddress[ul] :
|
||||
# 2556| r2556_3(unsigned long) = Load[ul] : &:r2556_2, ~m?
|
||||
# 2556| r2556_4(double) = BuiltIn[__builtin_bit_cast] : 0:r2556_3
|
||||
# 2556| mu2556_5(double) = Store[d] : &:r2556_1, r2556_4
|
||||
# 2557| v2557_1(void) = NoOp :
|
||||
# 2555| v2555_6(void) = ReturnVoid :
|
||||
# 2555| v2555_7(void) = AliasedUse : ~m?
|
||||
# 2555| v2555_8(void) = ExitFunction :
|
||||
|
||||
perf-regression.cpp:
|
||||
# 6| void Big::Big()
|
||||
# 6| Block 0
|
||||
|
||||
Reference in New Issue
Block a user