Skip to content
Draft
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
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,12 @@ newtype TInstructionTag =
exists(Stmt s | exists(s.getImplicitDestructorCall(index)))
} or
CoAwaitBranchTag() or
BoolToIntConversionTag()
BoolToIntConversionTag() or
SizeofVlaDimensionTag(int index) {
index = -1
or
exists(VlaDeclStmt v | exists(v.getVlaDimensionStmt(index)))
}

class InstructionTag extends TInstructionTag {
final string toString() { result = getInstructionTagId(this) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,16 @@ private predicate ignoreExprAndDescendants(Expr expr) {
// or
ignoreExprAndDescendants(getRealParent(expr)) // recursive case
or
// va_start doesn't evaluate its argument, so we don't need to translate it.
// va_start does not evaluate its argument, so we do not need to translate it.
exists(BuiltInVarArgsStart vaStartExpr |
vaStartExpr.getLastNamedParameter().getFullyConverted() = expr
)
or
// sizeof does not evaluate its argument, so we do not need to translate it.
exists(SizeofExprOperator sizeofExpr | sizeofExpr.getExprOperand().getFullyConverted() = expr)
or
// The children of C11 _Generic expressions are just surface syntax.
exists(C11GenericExpr generic | generic.getAChild() = expr)
exists(C11GenericExpr generic | generic.getAChild().getFullyConverted() = expr)
or
// Do not translate implicit destructor calls for unnamed temporary variables that are
// conditionally constructed (until we have a mechanism for calling these only when the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ Variable getEnclosingVariable(Expr e) {
}

/**
* The IR translation of the "core" part of an expression. This is the part of
* The IR translation of the "core" part of an expression. This is the part of
* the expression that produces the result value of the expression, before any
* lvalue-to-rvalue conversion on the result. Every expression has a single
* `TranslatedCoreExpr`.
Expand Down Expand Up @@ -4094,6 +4094,103 @@ class TranslatedStmtExpr extends TranslatedNonConstantExpr {
TranslatedStmt getStmt() { result = getTranslatedStmt(expr.getStmt()) }
}

private VlaDeclStmt getVlaDeclStmt(Expr expr, int pointerDerefCount) {
expr.(VariableAccess).getTarget() = result.getVariable() and
pointerDerefCount = 0
or
result = getVlaDeclStmt(expr.(PointerDereferenceExpr).getOperand(), pointerDerefCount - 1)
}

class TranslatedSizeofExpr extends TranslatedNonConstantExpr {
override SizeofExprOperator expr;
VlaDeclStmt vlaDeclStmt;
int pointerDerefCount;

TranslatedSizeofExpr() {
vlaDeclStmt = getVlaDeclStmt(expr.getExprOperand(), pointerDerefCount) and
pointerDerefCount < vlaDeclStmt.getNumberOfVlaDimensionStmts()
}

final override Instruction getFirstInstruction(EdgeKind kind) {
result = this.getInstruction(SizeofVlaDimensionTag(-1)) and
kind instanceof GotoEdge
}

override Instruction getALastInstructionInternal() {
result =
this.getInstruction(SizeofVlaDimensionTag(vlaDeclStmt.getNumberOfVlaDimensionStmts() - 1))
}

final override TranslatedElement getChildInternal(int id) { none() }

final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
opcode instanceof Opcode::Constant and
tag = SizeofVlaDimensionTag(-1) and
resultType = this.getResultType()
or
opcode instanceof Opcode::Mul and
exists(int n | pointerDerefCount <= n and n < vlaDeclStmt.getNumberOfVlaDimensionStmts() |
tag = SizeofVlaDimensionTag(n)
) and
resultType = this.getResultType()
}

final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
tag = SizeofVlaDimensionTag(-1) and
result = this.getInstruction(SizeofVlaDimensionTag(pointerDerefCount)) and
kind instanceof GotoEdge
or
exists(int n | pointerDerefCount <= n and n < vlaDeclStmt.getNumberOfVlaDimensionStmts() - 1 |
tag = SizeofVlaDimensionTag(n) and
result = this.getInstruction(SizeofVlaDimensionTag(n + 1))
) and
kind instanceof GotoEdge
or
tag = SizeofVlaDimensionTag(vlaDeclStmt.getNumberOfVlaDimensionStmts() - 1) and
result = this.getParent().getChildSuccessor(this, kind)
}

override string getInstructionConstantValue(InstructionTag tag) {
tag = SizeofVlaDimensionTag(-1) and
result =
this.getBaseSize(vlaDeclStmt.getVariable().getType(),
vlaDeclStmt.getNumberOfVlaDimensionStmts() - 1).toString()
}

private int getBaseSize(DerivedType type, int n) {
n = 0 and
result = type.getBaseType().getSize()
or
n = [1 .. vlaDeclStmt.getNumberOfVlaDimensionStmts() - 1] and
result = this.getBaseSize(type.getBaseType(), n - 1)
}

override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
exists(int n | pointerDerefCount <= n and n < vlaDeclStmt.getNumberOfVlaDimensionStmts() |
tag = SizeofVlaDimensionTag(n) and
(
operandTag instanceof LeftOperandTag and
(
n - 1 >= pointerDerefCount and
result = this.getInstruction(SizeofVlaDimensionTag(n - 1))
or
n - 1 < pointerDerefCount and
result = this.getInstruction(SizeofVlaDimensionTag(-1))
)
or
operandTag instanceof RightOperandTag and
result =
getTranslatedExpr(vlaDeclStmt.getVlaDimensionStmt(n).getDimensionExpr()).getResult()
)
)
}

final override Instruction getResult() {
result =
this.getInstruction(SizeofVlaDimensionTag(vlaDeclStmt.getNumberOfVlaDimensionStmts() - 1))
}
}

class TranslatedErrorExpr extends TranslatedSingleInstructionExpr {
override ErrorExpr expr;

Expand Down
180 changes: 180 additions & 0 deletions cpp/ql/test/library-tests/ir/ir/PrintAST.expected
Original file line number Diff line number Diff line change
Expand Up @@ -24581,6 +24581,186 @@ ir.cpp:
# 2776| Value = [CStyleCast] 42
# 2776| ValueCategory = prvalue
# 2777| getStmt(2): [ReturnStmt] return ...
# 2779| [TopLevelFunction] void vla_sizeof_test(int, size_t, char)
# 2779| <params>:
# 2779| getParameter(0): [Parameter] len1
# 2779| Type = [IntType] int
# 2779| getParameter(1): [Parameter] len2
# 2779| Type = [CTypedefType,Size_t] size_t
# 2779| getParameter(2): [Parameter] len3
# 2779| Type = [PlainCharType] char
# 2780| getEntryPoint(): [BlockStmt] { ... }
# 2781| getStmt(0): [DeclStmt] declaration
# 2781| getDeclarationEntry(0): [VariableDeclarationEntry] definition of tmp1
# 2781| Type = [ArrayType] char[]
# 2781| getStmt(1): [VlaDimensionStmt] VLA dimension size
# 2781| getDimensionExpr(): [VariableAccess] len1
# 2781| Type = [IntType] int
# 2781| ValueCategory = prvalue(load)
# 2781| getStmt(2): [VlaDeclStmt] VLA declaration
# 2782| getStmt(3): [DeclStmt] declaration
# 2782| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x
# 2782| Type = [CTypedefType,Size_t] size_t
# 2782| getVariable().getInitializer(): [Initializer] initializer for x
# 2782| getExpr(): [SizeofExprOperator] sizeof(<expr>)
# 2782| Type = [LongType] unsigned long
# 2782| ValueCategory = prvalue
# 2782| getExprOperand(): [VariableAccess] tmp1
# 2782| Type = [ArrayType] char[]
# 2782| ValueCategory = lvalue
# 2782| getExprOperand().getFullyConverted(): [ParenthesisExpr] (...)
# 2782| Type = [ArrayType] char[]
# 2782| ValueCategory = lvalue
# 2783| getStmt(4): [DeclStmt] declaration
# 2783| getDeclarationEntry(0): [VariableDeclarationEntry] definition of tmp2
# 2783| Type = [ArrayType] int[][]
# 2783| getStmt(5): [VlaDimensionStmt] VLA dimension size
# 2783| getDimensionExpr(): [VariableAccess] len1
# 2783| Type = [IntType] int
# 2783| ValueCategory = prvalue(load)
# 2783| getStmt(6): [VlaDimensionStmt] VLA dimension size
# 2783| getDimensionExpr(): [VariableAccess] len2
# 2783| Type = [CTypedefType,Size_t] size_t
# 2783| ValueCategory = prvalue(load)
# 2783| getStmt(7): [VlaDeclStmt] VLA declaration
# 2784| getStmt(8): [DeclStmt] declaration
# 2784| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y
# 2784| Type = [CTypedefType,Size_t] size_t
# 2784| getVariable().getInitializer(): [Initializer] initializer for y
# 2784| getExpr(): [SizeofExprOperator] sizeof(<expr>)
# 2784| Type = [LongType] unsigned long
# 2784| ValueCategory = prvalue
# 2784| getExprOperand(): [VariableAccess] tmp2
# 2784| Type = [ArrayType] int[][]
# 2784| ValueCategory = lvalue
# 2784| getExprOperand().getFullyConverted(): [ParenthesisExpr] (...)
# 2784| Type = [ArrayType] int[][]
# 2784| ValueCategory = lvalue
# 2785| getStmt(9): [DeclStmt] declaration
# 2785| getDeclarationEntry(0): [VariableDeclarationEntry] definition of z
# 2785| Type = [CTypedefType,Size_t] size_t
# 2785| getVariable().getInitializer(): [Initializer] initializer for z
# 2785| getExpr(): [SizeofExprOperator] sizeof(<expr>)
# 2785| Type = [LongType] unsigned long
# 2785| ValueCategory = prvalue
# 2785| getExprOperand(): [PointerDereferenceExpr] * ...
# 2785| Type = [ArrayType] int[]
# 2785| ValueCategory = lvalue
# 2785| getOperand(): [VariableAccess] tmp2
# 2785| Type = [ArrayType] int[][]
# 2785| ValueCategory = lvalue
# 2785| getOperand().getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion
# 2785| Type = [PointerType] int(*)[]
# 2785| ValueCategory = prvalue
# 2785| getExprOperand().getFullyConverted(): [ParenthesisExpr] (...)
# 2785| Type = [ArrayType] int[]
# 2785| ValueCategory = lvalue
# 2786| getStmt(10): [DeclStmt] declaration
# 2786| getDeclarationEntry(0): [VariableDeclarationEntry] definition of tmp3
# 2786| Type = [ArrayType] int[][][]
# 2786| getStmt(11): [VlaDimensionStmt] VLA dimension size
# 2786| getDimensionExpr(): [VariableAccess] len1
# 2786| Type = [IntType] int
# 2786| ValueCategory = prvalue(load)
# 2786| getStmt(12): [VlaDimensionStmt] VLA dimension size
# 2786| getDimensionExpr(): [VariableAccess] len2
# 2786| Type = [CTypedefType,Size_t] size_t
# 2786| ValueCategory = prvalue(load)
# 2786| getStmt(13): [VlaDimensionStmt] VLA dimension size
# 2786| getDimensionExpr(): [VariableAccess] len3
# 2786| Type = [PlainCharType] char
# 2786| ValueCategory = prvalue(load)
# 2786| getStmt(14): [VlaDeclStmt] VLA declaration
# 2787| getStmt(15): [DeclStmt] declaration
# 2787| getDeclarationEntry(0): [VariableDeclarationEntry] definition of w
# 2787| Type = [CTypedefType,Size_t] size_t
# 2787| getVariable().getInitializer(): [Initializer] initializer for w
# 2787| getExpr(): [SizeofExprOperator] sizeof(<expr>)
# 2787| Type = [LongType] unsigned long
# 2787| ValueCategory = prvalue
# 2787| getExprOperand(): [VariableAccess] tmp3
# 2787| Type = [ArrayType] int[][][]
# 2787| ValueCategory = lvalue
# 2787| getExprOperand().getFullyConverted(): [ParenthesisExpr] (...)
# 2787| Type = [ArrayType] int[][][]
# 2787| ValueCategory = lvalue
# 2788| getStmt(16): [DeclStmt] declaration
# 2788| getDeclarationEntry(0): [VariableDeclarationEntry] definition of v
# 2788| Type = [CTypedefType,Size_t] size_t
# 2788| getVariable().getInitializer(): [Initializer] initializer for v
# 2788| getExpr(): [SizeofExprOperator] sizeof(<expr>)
# 2788| Type = [LongType] unsigned long
# 2788| ValueCategory = prvalue
# 2788| getExprOperand(): [PointerDereferenceExpr] * ...
# 2788| Type = [ArrayType] int[][]
# 2788| ValueCategory = lvalue
# 2788| getOperand(): [VariableAccess] tmp3
# 2788| Type = [ArrayType] int[][][]
# 2788| ValueCategory = lvalue
# 2788| getOperand().getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion
# 2788| Type = [PointerType] int(*)[][]
# 2788| ValueCategory = prvalue
# 2788| getExprOperand().getFullyConverted(): [ParenthesisExpr] (...)
# 2788| Type = [ArrayType] int[][]
# 2788| ValueCategory = lvalue
# 2789| getStmt(17): [DeclStmt] declaration
# 2789| getDeclarationEntry(0): [VariableDeclarationEntry] definition of u
# 2789| Type = [CTypedefType,Size_t] size_t
# 2789| getVariable().getInitializer(): [Initializer] initializer for u
# 2789| getExpr(): [SizeofExprOperator] sizeof(<expr>)
# 2789| Type = [LongType] unsigned long
# 2789| ValueCategory = prvalue
# 2789| getExprOperand(): [PointerDereferenceExpr] * ...
# 2789| Type = [ArrayType] int[]
# 2789| ValueCategory = lvalue
# 2789| getOperand(): [PointerDereferenceExpr] * ...
# 2789| Type = [ArrayType] int[][]
# 2789| ValueCategory = lvalue
# 2789| getOperand(): [VariableAccess] tmp3
# 2789| Type = [ArrayType] int[][][]
# 2789| ValueCategory = lvalue
# 2789| getOperand().getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion
# 2789| Type = [PointerType] int(*)[][]
# 2789| ValueCategory = prvalue
# 2789| getOperand().getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion
# 2789| Type = [PointerType] int(*)[]
# 2789| ValueCategory = prvalue
# 2789| getExprOperand().getFullyConverted(): [ParenthesisExpr] (...)
# 2789| Type = [ArrayType] int[]
# 2789| ValueCategory = lvalue
# 2790| getStmt(18): [DeclStmt] declaration
# 2790| getDeclarationEntry(0): [VariableDeclarationEntry] definition of t
# 2790| Type = [CTypedefType,Size_t] size_t
# 2790| getVariable().getInitializer(): [Initializer] initializer for t
# 2790| getExpr(): [SizeofExprOperator] sizeof(<expr>)
# 2790| Type = [LongType] unsigned long
# 2790| Value = [SizeofExprOperator] 4
# 2790| ValueCategory = prvalue
# 2790| getExprOperand(): [PointerDereferenceExpr] * ...
# 2790| Type = [IntType] int
# 2790| ValueCategory = lvalue
# 2790| getOperand(): [PointerDereferenceExpr] * ...
# 2790| Type = [ArrayType] int[]
# 2790| ValueCategory = lvalue
# 2790| getOperand(): [PointerDereferenceExpr] * ...
# 2790| Type = [ArrayType] int[][]
# 2790| ValueCategory = lvalue
# 2790| getOperand(): [VariableAccess] tmp3
# 2790| Type = [ArrayType] int[][][]
# 2790| ValueCategory = lvalue
# 2790| getOperand().getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion
# 2790| Type = [PointerType] int(*)[][]
# 2790| ValueCategory = prvalue
# 2790| getOperand().getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion
# 2790| Type = [PointerType] int(*)[]
# 2790| ValueCategory = prvalue
# 2790| getOperand().getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion
# 2790| Type = [IntPointerType] int *
# 2790| ValueCategory = prvalue
# 2790| getExprOperand().getFullyConverted(): [ParenthesisExpr] (...)
# 2790| Type = [IntType] int
# 2790| ValueCategory = lvalue
# 2791| getStmt(19): [ReturnStmt] return ...
ir23.cpp:
# 1| [TopLevelFunction] bool consteval_1()
# 1| <params>:
Expand Down
Loading