mirror of
https://github.com/github/codeql.git
synced 2026-04-30 11:15:13 +02:00
C++: Handle pointer decay and inferred array sizes
For function parameters that are subject to "pointer decay", the database contains the type as originally declared (e.g. `T[]` instead of `T*`). The IR needs the actual type. Similarly, for variable declared as an array of unknown size, the actual size needs to be inferred from the initializer (e.g. `char a[] = "blah";` needs to have the type `char[5]`). I've opened a ticket to have the extractor emit the actual type alongside the declared type, but for now, this workaround is enough to unblock progress for typical code.
This commit is contained in:
@@ -6591,3 +6591,39 @@ ir.cpp:
|
||||
# 983| ValueCategory = prvalue(load)
|
||||
# 983| 1: { ... }
|
||||
# 985| 3: return ...
|
||||
# 987| int PointerDecay(int[], int(float))
|
||||
# 987| params:
|
||||
# 987| 0: a
|
||||
# 987| Type = int[]
|
||||
# 987| 1: fn
|
||||
# 987| Type = ..()(..)
|
||||
# 987| body: { ... }
|
||||
# 988| 0: return ...
|
||||
# 988| 0: ... + ...
|
||||
# 988| Type = int
|
||||
# 988| ValueCategory = prvalue
|
||||
# 988| 0: access to array
|
||||
# 988| Type = int
|
||||
# 988| ValueCategory = prvalue(load)
|
||||
# 988| 0: a
|
||||
# 988| Type = int *
|
||||
# 988| ValueCategory = prvalue(load)
|
||||
# 988| 1: 0
|
||||
# 988| Type = int
|
||||
# 988| Value = 0
|
||||
# 988| ValueCategory = prvalue
|
||||
# 988| 1: call to expression
|
||||
# 988| Type = int
|
||||
# 988| ValueCategory = prvalue
|
||||
# 988| 0: fn
|
||||
# 988| Type = ..(*)(..)
|
||||
# 988| ValueCategory = prvalue(load)
|
||||
# 988| 1: (float)...
|
||||
# 988| Conversion = floating point conversion
|
||||
# 988| Type = float
|
||||
# 988| Value = 1.0
|
||||
# 988| ValueCategory = prvalue
|
||||
# 988| expr: 1.0
|
||||
# 988| Type = double
|
||||
# 988| Value = 1.0
|
||||
# 988| ValueCategory = prvalue
|
||||
|
||||
@@ -984,6 +984,10 @@ void WhileStmtWithDeclaration(int x, int y) {
|
||||
}
|
||||
}
|
||||
|
||||
int PointerDecay(int a[], int fn(float)) {
|
||||
return a[0] + fn(1.0);
|
||||
}
|
||||
|
||||
#if 0
|
||||
void OperatorDelete() {
|
||||
delete static_cast<int*>(nullptr); // No destructor
|
||||
|
||||
@@ -2579,7 +2579,7 @@ ir.cpp:
|
||||
# 573| r0_12(glval<char[4]>) = StringConstant["foo"] :
|
||||
# 573| r0_13(char[4]) = Load : r0_12, mu0_2
|
||||
# 573| mu0_14(char[4]) = Store : r0_11, r0_13
|
||||
# 574| r0_15(glval<char[]>) = VariableAddress[a_infer] :
|
||||
# 574| r0_15(glval<char[5]>) = VariableAddress[a_infer] :
|
||||
# 574| r0_16(glval<char[5]>) = StringConstant["blah"] :
|
||||
# 574| r0_17(char[5]) = Load : r0_16, mu0_2
|
||||
# 574| mu0_18(char[5]) = Store : r0_15, r0_17
|
||||
@@ -4339,3 +4339,30 @@ ir.cpp:
|
||||
# 979| v7_9(void) = ConditionalBranch : r7_8
|
||||
#-----| False -> Block 2
|
||||
#-----| True -> Block 1
|
||||
|
||||
# 987| int PointerDecay(int[], int(float))
|
||||
# 987| Block 0
|
||||
# 987| v0_0(void) = EnterFunction :
|
||||
# 987| mu0_1(unknown) = AliasedDefinition :
|
||||
# 987| mu0_2(unknown) = UnmodeledDefinition :
|
||||
# 987| r0_3(glval<int *>) = VariableAddress[a] :
|
||||
# 987| mu0_4(int *) = InitializeParameter[a] : r0_3
|
||||
# 987| r0_5(glval<..(*)(..)>) = VariableAddress[fn] :
|
||||
# 987| mu0_6(..(*)(..)) = InitializeParameter[fn] : r0_5
|
||||
# 988| r0_7(glval<int>) = VariableAddress[#return] :
|
||||
# 988| r0_8(glval<int *>) = VariableAddress[a] :
|
||||
# 988| r0_9(int *) = Load : r0_8, mu0_2
|
||||
# 988| r0_10(int) = Constant[0] :
|
||||
# 988| r0_11(int *) = PointerAdd[4] : r0_9, r0_10
|
||||
# 988| r0_12(int) = Load : r0_11, mu0_2
|
||||
# 988| r0_13(glval<..(*)(..)>) = VariableAddress[fn] :
|
||||
# 988| r0_14(..(*)(..)) = Load : r0_13, mu0_2
|
||||
# 988| r0_15(float) = Constant[1.0] :
|
||||
# 988| r0_16(int) = Call : r0_14, r0_15
|
||||
# 988| mu0_17(unknown) = ^CallSideEffect : mu0_2
|
||||
# 988| r0_18(int) = Add : r0_12, r0_16
|
||||
# 988| mu0_19(int) = Store : r0_7, r0_18
|
||||
# 987| r0_20(glval<int>) = VariableAddress[#return] :
|
||||
# 987| v0_21(void) = ReturnValue : r0_20, mu0_2
|
||||
# 987| v0_22(void) = UnmodeledUse : mu*
|
||||
# 987| v0_23(void) = ExitFunction :
|
||||
|
||||
Reference in New Issue
Block a user