@@ -187,7 +187,7 @@ Variable getEnclosingVariable(Expr e) {
187
187
}
188
188
189
189
/**
190
- * The IR translation of the "core" part of an expression. This is the part of
190
+ * The IR translation of the "core" part of an expression. This is the part of
191
191
* the expression that produces the result value of the expression, before any
192
192
* lvalue-to-rvalue conversion on the result. Every expression has a single
193
193
* `TranslatedCoreExpr`.
@@ -4094,6 +4094,155 @@ class TranslatedStmtExpr extends TranslatedNonConstantExpr {
4094
4094
TranslatedStmt getStmt ( ) { result = getTranslatedStmt ( expr .getStmt ( ) ) }
4095
4095
}
4096
4096
4097
+ private VlaDeclStmt getVlaDeclStmt ( Expr expr , int pointerDerefCount ) {
4098
+ expr .( VariableAccess ) .getTarget ( ) = result .getVariable ( ) and
4099
+ pointerDerefCount = 0
4100
+ or
4101
+ not expr .( PointerDereferenceExpr ) .getOperand ( ) instanceof AddressOfExpr and
4102
+ result = getVlaDeclStmt ( expr .( PointerDereferenceExpr ) .getOperand ( ) , pointerDerefCount - 1 )
4103
+ or
4104
+ // Skip sequences of the form `*&...`
4105
+ result =
4106
+ getVlaDeclStmt ( expr .( PointerDereferenceExpr ) .getOperand ( ) .( AddressOfExpr ) .getOperand ( ) ,
4107
+ pointerDerefCount )
4108
+ or
4109
+ result = getVlaDeclStmt ( expr .( ArrayExpr ) .getArrayBase ( ) , pointerDerefCount - 1 )
4110
+ }
4111
+
4112
+ /**
4113
+ * The IR translation of `SizeofExprOperator` when its result is non-constant, i.e.,
4114
+ * when the operand expression refers to a variable length array.
4115
+ */
4116
+ class TranslatedSizeofExpr extends TranslatedNonConstantExpr {
4117
+ override SizeofExprOperator expr ;
4118
+ VlaDeclStmt vlaDeclStmt ;
4119
+ int vlaDimensions ;
4120
+ int pointerDerefCount ;
4121
+
4122
+ TranslatedSizeofExpr ( ) {
4123
+ vlaDeclStmt = getVlaDeclStmt ( expr .getExprOperand ( ) , pointerDerefCount ) and
4124
+ vlaDimensions = vlaDeclStmt .getTransitiveNumberOfVlaDimensionStmts ( ) and
4125
+ pointerDerefCount < vlaDimensions
4126
+ }
4127
+
4128
+ final override Instruction getFirstInstruction ( EdgeKind kind ) {
4129
+ result = this .getInstruction ( SizeofVlaBaseSizeTag ( ) ) and
4130
+ kind instanceof GotoEdge
4131
+ }
4132
+
4133
+ override Instruction getALastInstructionInternal ( ) {
4134
+ result = this .getInstruction ( SizeofVlaDimensionTag ( vlaDimensions - 1 ) )
4135
+ }
4136
+
4137
+ final override TranslatedElement getChildInternal ( int id ) { none ( ) }
4138
+
4139
+ final override predicate hasInstruction ( Opcode opcode , InstructionTag tag , CppType resultType ) {
4140
+ opcode instanceof Opcode:: Constant and
4141
+ tag = SizeofVlaBaseSizeTag ( ) and
4142
+ resultType = this .getResultType ( )
4143
+ or
4144
+ exists ( int n , Type dimType |
4145
+ pointerDerefCount <= n and
4146
+ n < vlaDimensions and
4147
+ dimType = this .getDimensionExpr ( n ) .getUnderlyingType ( ) and
4148
+ tag = SizeofVlaConversionTag ( n )
4149
+ |
4150
+ (
4151
+ expr .getUnderlyingType ( ) = dimType and
4152
+ opcode instanceof Opcode:: CopyValue
4153
+ or
4154
+ not expr .getUnderlyingType ( ) = dimType and
4155
+ opcode instanceof Opcode:: Convert
4156
+ )
4157
+ ) and
4158
+ resultType = this .getResultType ( )
4159
+ or
4160
+ opcode instanceof Opcode:: Mul and
4161
+ exists ( int n | pointerDerefCount <= n and n < vlaDimensions | tag = SizeofVlaDimensionTag ( n ) ) and
4162
+ resultType = this .getResultType ( )
4163
+ }
4164
+
4165
+ final override Instruction getInstructionSuccessorInternal ( InstructionTag tag , EdgeKind kind ) {
4166
+ tag = SizeofVlaBaseSizeTag ( ) and
4167
+ result = this .getInstruction ( SizeofVlaConversionTag ( pointerDerefCount ) ) and
4168
+ kind instanceof GotoEdge
4169
+ or
4170
+ exists ( int n | pointerDerefCount <= n and n < vlaDimensions |
4171
+ tag = SizeofVlaConversionTag ( n ) and
4172
+ result = this .getInstruction ( SizeofVlaDimensionTag ( n ) )
4173
+ ) and
4174
+ kind instanceof GotoEdge
4175
+ or
4176
+ exists ( int n | pointerDerefCount <= n and n < vlaDimensions - 1 |
4177
+ tag = SizeofVlaDimensionTag ( n ) and
4178
+ result = this .getInstruction ( SizeofVlaConversionTag ( n + 1 ) )
4179
+ ) and
4180
+ kind instanceof GotoEdge
4181
+ or
4182
+ tag = SizeofVlaDimensionTag ( vlaDimensions - 1 ) and
4183
+ result = this .getParent ( ) .getChildSuccessor ( this , kind )
4184
+ }
4185
+
4186
+ override string getInstructionConstantValue ( InstructionTag tag ) {
4187
+ tag = SizeofVlaBaseSizeTag ( ) and
4188
+ result = this .getBaseType ( vlaDeclStmt ) .getSize ( ) .toString ( )
4189
+ }
4190
+
4191
+ private Type getBaseType ( VlaDeclStmt v ) {
4192
+ not exists ( v .getParentVlaDecl ( ) ) and
4193
+ (
4194
+ result =
4195
+ this .getBaseType ( v .getVariable ( ) .getUnderlyingType ( ) , v .getNumberOfVlaDimensionStmts ( ) )
4196
+ or
4197
+ result = this .getBaseType ( v .getType ( ) .getUnderlyingType ( ) , v .getNumberOfVlaDimensionStmts ( ) )
4198
+ )
4199
+ or
4200
+ result = this .getBaseType ( v .getParentVlaDecl ( ) )
4201
+ }
4202
+
4203
+ private Type getBaseType ( Type type , int n ) {
4204
+ n = 0 and
4205
+ result = type
4206
+ or
4207
+ result = this .getBaseType ( type .( DerivedType ) .getBaseType ( ) , n - 1 )
4208
+ }
4209
+
4210
+ override Instruction getInstructionRegisterOperand ( InstructionTag tag , OperandTag operandTag ) {
4211
+ exists ( int n | pointerDerefCount <= n and n < vlaDimensions |
4212
+ tag = SizeofVlaConversionTag ( n ) and
4213
+ (
4214
+ operandTag instanceof UnaryOperandTag and
4215
+ result = getTranslatedExpr ( this .getDimensionExpr ( n ) ) .getResult ( )
4216
+ )
4217
+ )
4218
+ or
4219
+ exists ( int n | pointerDerefCount <= n and n < vlaDimensions |
4220
+ tag = SizeofVlaDimensionTag ( n ) and
4221
+ (
4222
+ operandTag instanceof LeftOperandTag and
4223
+ (
4224
+ n - 1 >= pointerDerefCount and
4225
+ result = this .getInstruction ( SizeofVlaDimensionTag ( n - 1 ) )
4226
+ or
4227
+ n - 1 < pointerDerefCount and
4228
+ result = this .getInstruction ( SizeofVlaBaseSizeTag ( ) )
4229
+ )
4230
+ or
4231
+ operandTag instanceof RightOperandTag and
4232
+ result = this .getInstruction ( SizeofVlaConversionTag ( n ) )
4233
+ )
4234
+ )
4235
+ }
4236
+
4237
+ private Expr getDimensionExpr ( int n ) {
4238
+ result = vlaDeclStmt .getTransitiveVlaDimensionStmt ( n ) .getDimensionExpr ( ) .getFullyConverted ( )
4239
+ }
4240
+
4241
+ final override Instruction getResult ( ) {
4242
+ result = this .getInstruction ( SizeofVlaDimensionTag ( vlaDimensions - 1 ) )
4243
+ }
4244
+ }
4245
+
4097
4246
class TranslatedErrorExpr extends TranslatedSingleInstructionExpr {
4098
4247
override ErrorExpr expr ;
4099
4248
0 commit comments