@@ -187,7 +187,7 @@ Variable getEnclosingVariable(Expr e) {
187187}
188188
189189/**
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
191191 * the expression that produces the result value of the expression, before any
192192 * lvalue-to-rvalue conversion on the result. Every expression has a single
193193 * `TranslatedCoreExpr`.
@@ -4094,6 +4094,155 @@ class TranslatedStmtExpr extends TranslatedNonConstantExpr {
40944094 TranslatedStmt getStmt ( ) { result = getTranslatedStmt ( expr .getStmt ( ) ) }
40954095}
40964096
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+
40974246class TranslatedErrorExpr extends TranslatedSingleInstructionExpr {
40984247 override ErrorExpr expr ;
40994248
0 commit comments