diff --git a/cpp/ql/src/semmle/code/cpp/exprs/Expr.qll b/cpp/ql/src/semmle/code/cpp/exprs/Expr.qll index 168e6f29fe8d..e36a1602ec8d 100644 --- a/cpp/ql/src/semmle/code/cpp/exprs/Expr.qll +++ b/cpp/ql/src/semmle/code/cpp/exprs/Expr.qll @@ -581,24 +581,13 @@ class ReferenceDereferenceExpr extends Conversion, @ref_indirect { } /** - * A C++ `new` (non-array) expression. + * A C++ `new` or `new[]` expression. */ -class NewExpr extends Expr, @new_expr { - override string toString() { result = "new" } - +class NewOrNewArrayExpr extends Expr, @any_new_expr { override int getPrecedence() { result = 15 } /** - * Gets the type that is being allocated. - * - * For example, for `new int` the result is `int`. - */ - Type getAllocatedType() { - new_allocated_type(underlyingElement(this), unresolveElement(result)) - } - - /** - * Gets the `operator new` that allocates storage. + * Gets the `operator new` or `operator new[]` that allocates storage. */ Function getAllocator() { expr_allocator(underlyingElement(this), unresolveElement(result), _) @@ -612,6 +601,21 @@ class NewExpr extends Expr, @new_expr { expr_allocator(underlyingElement(this), _, 1) } + /** + * Gets the alignment argument passed to the allocation function, if any. + */ + Expr getAlignmentArgument() { + hasAlignedAllocation() and + ( + // If we have an allocator call, the alignment is the second argument to + // that call. + result = getAllocatorCall().getArgument(1) or + // Otherwise, the alignment winds up as child number 3 of the `new` + // itself. + result = getChild(3) + ) + } + /** * Gets the call to a non-default `operator new` that allocates storage, if any. * @@ -652,6 +656,30 @@ class NewExpr extends Expr, @new_expr { ) } + /** + * Gets the type that is being allocated. + * + * For example, for `new int` the result is `int`. + * For `new int[5]` the result is `int[5]`. + */ + abstract Type getAllocatedType(); +} + +/** + * A C++ `new` (non-array) expression. + */ +class NewExpr extends NewOrNewArrayExpr, @new_expr { + override string toString() { result = "new" } + + /** + * Gets the type that is being allocated. + * + * For example, for `new int` the result is `int`. + */ + override Type getAllocatedType() { + new_allocated_type(underlyingElement(this), unresolveElement(result)) + } + /** * Gets the call or expression that initializes the allocated object, if any. * @@ -664,17 +692,15 @@ class NewExpr extends Expr, @new_expr { /** * A C++ `new[]` (array) expression. */ -class NewArrayExpr extends Expr, @new_array_expr { +class NewArrayExpr extends NewOrNewArrayExpr, @new_array_expr { override string toString() { result = "new[]" } - override int getPrecedence() { result = 15 } - /** * Gets the type that is being allocated. * * For example, for `new int[5]` the result is `int[5]`. */ - Type getAllocatedType() { + override Type getAllocatedType() { new_array_allocated_type(underlyingElement(this), unresolveElement(result)) } @@ -685,56 +711,6 @@ class NewArrayExpr extends Expr, @new_array_expr { result = getType().getUnderlyingType().(PointerType).getBaseType() } - /** - * Gets the `operator new[]` that allocates storage. - */ - Function getAllocator() { - expr_allocator(underlyingElement(this), unresolveElement(result), _) - } - - /** - * Holds if the allocation function is the version that expects an alignment - * argument of type `std::align_val_t`. - */ - predicate hasAlignedAllocation() { - expr_allocator(underlyingElement(this), _, 1) - } - - /** - * Gets the call to a non-default `operator new[]` that allocates storage for the array, if any. - * - * If the default `operator new[]` is used, then there will be no call. - */ - FunctionCall getAllocatorCall() { result = this.getChild(0) } - - /** - * Gets the `operator delete` that deallocates storage if the initialization - * throws an exception, if any. - */ - Function getDeallocator() { - expr_deallocator(underlyingElement(this), unresolveElement(result), _) - } - - /** - * Holds if the deallocation function expects a size argument. - */ - predicate hasSizedDeallocation() { - exists(int form | - expr_deallocator(underlyingElement(this), _, form) and - form.bitAnd(1) != 0 // Bit zero is the "size" bit - ) - } - - /** - * Holds if the deallocation function expects an alignment argument. - */ - predicate hasAlignedDeallocation() { - exists(int form | - expr_deallocator(underlyingElement(this), _, form) and - form.bitAnd(2) != 0 // Bit one is the "alignment" bit - ) - } - /** * Gets the call or expression that initializes the first element of the array, if any. * diff --git a/cpp/ql/src/semmle/code/cpp/ir/internal/Instruction.qll b/cpp/ql/src/semmle/code/cpp/ir/internal/Instruction.qll index 7f01c8356b79..5106d7487df8 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/internal/Instruction.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/internal/Instruction.qll @@ -195,8 +195,11 @@ class Instruction extends Construction::TInstruction { private string getResultTypeString() { exists(string valcat | valcat = getValueCategoryString(resultType.toString()) and - if resultType instanceof UnknownType and exists(getResultSize()) then + if (resultType instanceof UnknownType and + not isGLValue() and + exists(getResultSize())) then ( result = valcat + "[" + getResultSize().toString() + "]" + ) else result = valcat ) diff --git a/cpp/ql/src/semmle/code/cpp/ir/internal/InstructionTag.qll b/cpp/ql/src/semmle/code/cpp/ir/internal/InstructionTag.qll index 76a62308a386..7961df3c0e26 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/internal/InstructionTag.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/internal/InstructionTag.qll @@ -43,6 +43,9 @@ newtype TInstructionTag = SwitchBranchTag() or CallTargetTag() or CallTag() or + AllocationSizeTag() or + AllocationElementSizeTag() or + AllocationExtentConvertTag() or ValueConditionConditionalBranchTag() or ConditionValueTrueTempAddressTag() or ConditionValueTrueConstantTag() or @@ -88,11 +91,15 @@ string getInstructionTagId(TInstructionTag tag) { tag = OnlyInstructionTag() and result = "Only" or // Single instruction (not including implicit Load) tag = InitializerVariableAddressTag() and result = "InitVarAddr" or tag = InitializerStoreTag() and result = "InitStore" or + tag = ZeroPadStringConstantTag() and result = "ZeroPadConst" or + tag = ZeroPadStringElementIndexTag() and result = "ZeroPadElemIndex" or + tag = ZeroPadStringElementAddressTag() and result = "ZeroPadElemAddr" or + tag = ZeroPadStringStoreTag() and result = "ZeroPadStore" or tag = AssignOperationLoadTag() and result = "AssignOpLoad" or tag = AssignOperationConvertLeftTag() and result = "AssignOpConvLeft" or tag = AssignOperationOpTag() and result = "AssignOpOp" or tag = AssignOperationConvertResultTag() and result = "AssignOpConvRes" or - tag = AssignmentStoreTag() and result = "AssigStore" or + tag = AssignmentStoreTag() and result = "AssignStore" or tag = CrementLoadTag() and result = "CrementLoad" or tag = CrementConstantTag() and result = "CrementConst" or tag = CrementOpTag() and result = "CrementOp" or @@ -106,6 +113,9 @@ string getInstructionTagId(TInstructionTag tag) { tag = SwitchBranchTag() and result = "SwitchBranch" or tag = CallTargetTag() and result = "CallTarget" or tag = CallTag() and result = "Call" or + tag = AllocationSizeTag() and result = "AllocSize" or + tag = AllocationElementSizeTag() and result = "AllocElemSize" or + tag = AllocationExtentConvertTag() and result = "AllocExtConv" or tag = ValueConditionConditionalBranchTag() and result = "ValCondCondBranch" or tag = ConditionValueTrueTempAddressTag() and result = "CondValTrueTempAddr" or tag = ConditionValueTrueConstantTag() and result = "CondValTrueConst" or diff --git a/cpp/ql/src/semmle/code/cpp/ir/internal/TranslatedElement.qll b/cpp/ql/src/semmle/code/cpp/ir/internal/TranslatedElement.qll index 4e2cfc5dfd3c..c4639f13fb1c 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/internal/TranslatedElement.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/internal/TranslatedElement.qll @@ -47,12 +47,12 @@ private Element getRealParent(Expr expr) { } /** - * Holds if `expr` should be ignored for the purposes of code generation due to - * some property of `expr` itself. Unlike `ignoreExpr()`, this predicate does - * not ignore an expression solely because it is a descendant of an ignored - * element. + * Holds if `expr` and all of its descendants should be ignored for the purposes + * of IR generation due to some property of `expr` itself. Unlike + * `ignoreExpr()`, this predicate does not ignore an expression solely because + * it is a descendant of an ignored element. */ -private predicate ignoreExprLocal(Expr expr) { +private predicate ignoreExprAndDescendants(Expr expr) { // Ignore parentless expressions not exists(getRealParent(expr)) or // Ignore the constants in SwitchCase, since their values are embedded in the @@ -65,23 +65,32 @@ private predicate ignoreExprLocal(Expr expr) { // node as its qualifier, but that `FieldAccess` does not have a child of its own. // We'll ignore that `FieldAccess`, and supply the receiver as part of the calling // context, much like we do with constructor calls. - expr.getParent().(DestructorCall).getParent() instanceof DestructorFieldDestruction + expr.getParent().(DestructorCall).getParent() instanceof DestructorFieldDestruction or + exists(NewArrayExpr newExpr | + // REVIEW: Ignore initializers for `NewArrayExpr` until we determine how to + // represent them. + newExpr.getInitializer().getFullyConverted() = expr + ) } /** - * Holds if `expr` should be ignored for the purposes of IR generation. + * Holds if `expr` (not including its descendants) should be ignored for the + * purposes of IR generation. */ -private predicate ignoreExpr(Expr expr) { - ignoreExprLocal(expr) or - // Ignore all descendants of ignored elements as well. - ignoreElement(getRealParent(expr)) +private predicate ignoreExprOnly(Expr expr) { + exists(NewOrNewArrayExpr newExpr | + // Ignore the allocator call, because we always synthesize it. Don't ignore + // its arguments, though, because we use them as part of the synthesis. + newExpr.getAllocatorCall() = expr + ) } /** - * Holds if `element` should be ignored for the purposes of IR generation. + * Holds if `expr` should be ignored for the purposes of IR generation. */ -private predicate ignoreElement(Element element) { - ignoreExpr(element.(Expr)) +private predicate ignoreExpr(Expr expr) { + ignoreExprOnly(expr) or + ignoreExprAndDescendants(getRealParent*(expr)) } /** @@ -155,7 +164,7 @@ predicate ignoreLoad(Expr expr) { newtype TTranslatedElement = // An expression that is not being consumed as a condition - TTranslatedNonLoadExpr(Expr expr) { + TTranslatedValueExpr(Expr expr) { not ignoreExpr(expr) and not isNativeCondition(expr) and not isFlexibleCondition(expr) @@ -216,6 +225,9 @@ newtype TTranslatedElement = exists(ConstructorFieldInit fieldInit | fieldInit.getExpr().getFullyConverted() = expr ) or + exists(NewExpr newExpr | + newExpr.getInitializer().getFullyConverted() = expr + ) or exists(ThrowExpr throw | throw.getExpr().getFullyConverted() = expr ) @@ -298,6 +310,14 @@ newtype TTranslatedElement = exists(DeclStmt declStmt | declStmt.getADeclarationEntry() = entry ) + } or + // An allocator call in a `new` or `new[]` expression + TTranslatedAllocatorCall(NewOrNewArrayExpr newExpr) { + not ignoreExpr(newExpr) + } or + // An allocation size for a `new` or `new[]` expression + TTranslatedAllocationSize(NewOrNewArrayExpr newExpr) { + not ignoreExpr(newExpr) } /** diff --git a/cpp/ql/src/semmle/code/cpp/ir/internal/TranslatedExpr.qll b/cpp/ql/src/semmle/code/cpp/ir/internal/TranslatedExpr.qll index cf21665a28d6..2bc563f22bbb 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/internal/TranslatedExpr.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/internal/TranslatedExpr.qll @@ -16,18 +16,44 @@ TranslatedExpr getTranslatedExpr(Expr expr) { result.producesExprResult() } +/** + * The IR translation of some part of an expression. + * A single `Expr` may consist of multiple `TranslatedExpr` objects. Every + * `Expr` has a single `TranslatedCoreExpr`, which produces the result of the + * expression before any implicit lvalue-to-rvalue conversion. Any expression + * with an lvalue-to-rvalue conversion will also have a `TranslatedLoad` to + * perform that conversion on the original result. A few expressions have + * additional `TranslatedExpr` objects that compute intermediate values, such + * as the `TranslatedAllocatorCall` and `TranslatedAllocationSize` within the + * translation of a `NewExpr`. + */ abstract class TranslatedExpr extends TranslatedElement { Expr expr; - override final string toString() { - result = expr.toString() - } + /** + * Gets the instruction that produces the result of the expression. + */ + abstract Instruction getResult(); - override final Locatable getAST() { - result = expr + /** + * Holds if this `TranslatedExpr` produces the final result of the original + * expression from the AST. + * + * For example, in `y = x;`, the TranslatedLoad for the VariableAccess `x` + * produces the result of that VariableAccess expression, but the + * TranslatedVariableAccess for `x` does not. The TranslatedVariableAccess + * for `y` does produce its result, however, because there is no load on `y`. + */ + abstract predicate producesExprResult(); + + /** + * Gets the type of the result produced by this expression. + */ + final Type getResultType() { + result = expr.getType().getUnspecifiedType() } - final Expr getExpr() { + override final Locatable getAST() { result = expr } @@ -35,28 +61,33 @@ abstract class TranslatedExpr extends TranslatedElement { result = expr.getEnclosingFunction() } + /** + * Gets the expression from which this `TranslatedExpr` is generated. + */ + final Expr getExpr() { + result = expr + } + + /** + * Gets the `TranslatedFunction` containing this expression. + */ final TranslatedFunction getEnclosingFunction() { result = getTranslatedFunction(expr.getEnclosingFunction()) } +} - final Type getResultType() { - result = expr.getType().getUnspecifiedType() +/** + * 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`. + */ +abstract class TranslatedCoreExpr extends TranslatedExpr { + override final string toString() { + result = expr.toString() } - abstract Instruction getResult(); - - /** - * Holds if this `TranslatedExpr` produces the final result of the original - * expression from the AST. - * - * For example, in `y = x;`, the TranslatedLoad for the VariableAccess `x` - * produces the result of that VariableAccess expression, but the - * TranslatedVariableAccess for `x` does not. The TranslatedVariableAccess - * for `y` does produce its result, however, because there is no load on `y`. - */ - final predicate producesExprResult() { - // A load always produces the result of the expression. - this instanceof TranslatedLoad or + override final predicate producesExprResult() { // If there's no load, then this is the only TranslatedExpr for this // expression. not expr.hasLValueToRValueConversion() or @@ -86,7 +117,7 @@ abstract class TranslatedExpr extends TranslatedElement { } } -class TranslatedConditionValue extends TranslatedExpr, ConditionContext, +class TranslatedConditionValue extends TranslatedCoreExpr, ConditionContext, TTranslatedConditionValue { TranslatedConditionValue() { this = TTranslatedConditionValue(expr) @@ -262,11 +293,19 @@ class TranslatedConditionValue extends TranslatedExpr, ConditionContext, } } +/** + * IR translation of an implicit lvalue-to-rvalue conversion on the result of + * an expression. + */ class TranslatedLoad extends TranslatedExpr, TTranslatedLoad { TranslatedLoad() { this = TTranslatedLoad(expr) } + override string toString() { + result = "Load of " + expr.toString() + } + override Instruction getFirstInstruction() { result = getOperand().getFirstInstruction() } @@ -279,8 +318,11 @@ class TranslatedLoad extends TranslatedExpr, TTranslatedLoad { Type resultType, boolean isGLValue) { tag = LoadTag() and opcode instanceof Opcode::Load and - resultType = getResultType() and - isGLValue = isResultGLValue() + resultType = expr.getType().getUnspecifiedType() and + if expr.isGLValueCategory() then + isGLValue = true + else + isGLValue = false } override Instruction getInstructionSuccessor(InstructionTag tag, @@ -313,8 +355,13 @@ class TranslatedLoad extends TranslatedExpr, TTranslatedLoad { ) } - private TranslatedExpr getOperand() { - result.getExpr() = expr and not result instanceof TranslatedLoad + override final predicate producesExprResult() { + // A load always produces the result of the expression. + any() + } + + private TranslatedCoreExpr getOperand() { + result.getExpr() = expr } } @@ -906,21 +953,24 @@ class TranslatedFunctionAccess extends TranslatedNonConstantExpr { } } -abstract class TranslatedNonLoadExpr extends TranslatedExpr, - TTranslatedNonLoadExpr { - TranslatedNonLoadExpr() { - this = TTranslatedNonLoadExpr(expr) - } -} - -abstract class TranslatedNonConstantExpr extends TranslatedNonLoadExpr { +/** + * IR translation of an expression whose value is not known at compile time. + */ +abstract class TranslatedNonConstantExpr extends TranslatedCoreExpr { TranslatedNonConstantExpr() { + this = TTranslatedValueExpr(expr) and not expr.isConstant() } } -abstract class TranslatedConstantExpr extends TranslatedNonLoadExpr { +/** + * IR translation of an expression with a compile-time constant value. This + * includes not only literals, but also "integral constant expressions" (e.g. + * `1 + 2`). + */ +abstract class TranslatedConstantExpr extends TranslatedCoreExpr { TranslatedConstantExpr() { + this = TTranslatedValueExpr(expr) and expr.isConstant() } @@ -998,7 +1048,15 @@ class TranslatedStringLiteral extends TranslatedConstantExpr { } } -abstract class TranslatedValueExpr extends TranslatedNonConstantExpr { +/** + * IR translation of an expression that performs a single operation on its + * operands and returns the result. + */ +abstract class TranslatedSingleInstructionExpr extends + TranslatedNonConstantExpr { + /** + * Gets the `Opcode` of the operation to be performed. + */ abstract Opcode getOpcode(); override final predicate hasInstruction(Opcode opcode, InstructionTag tag, @@ -1014,7 +1072,7 @@ abstract class TranslatedValueExpr extends TranslatedNonConstantExpr { } } -class TranslatedUnaryExpr extends TranslatedValueExpr { +class TranslatedUnaryExpr extends TranslatedSingleInstructionExpr { TranslatedUnaryExpr() { expr instanceof NotExpr or expr instanceof ComplementExpr or @@ -1299,7 +1357,10 @@ private Opcode comparisonOpcode(ComparisonOperation expr) { expr instanceof GEExpr and result instanceof Opcode::CompareGE } -class TranslatedBinaryOperation extends TranslatedValueExpr { +/** + * IR translation of a simple binary operation. + */ +class TranslatedBinaryOperation extends TranslatedSingleInstructionExpr { TranslatedBinaryOperation() { expr instanceof BinaryArithmeticOperation or expr instanceof BinaryBitwiseOperation or @@ -1707,26 +1768,11 @@ class TranslatedAssignOperation extends TranslatedAssignment { } /** - * Represents the IR translation of a call to a function. + * The IR translation of a call to a function. The call may be from an actual + * call in the source code, or could be a call that is part of the translation + * of a higher-level constructor (e.g. the allocator call in a `NewExpr`). */ -abstract class TranslatedCall extends TranslatedNonConstantExpr { - Call call; - - TranslatedCall() { - expr = call - } - - override final Instruction getFirstInstruction() { - if exists(getQualifier()) then - result = getQualifier().getFirstInstruction() - else - result = getFirstCallTargetInstruction() - } - - override final Instruction getResult() { - result = getInstruction(CallTag()) - } - +abstract class TranslatedCall extends TranslatedExpr { override final TranslatedElement getChild(int id) { // We choose the child's id in the order of evaluation. // The qualifier is evaluated before the call target, because the value of @@ -1737,6 +1783,21 @@ abstract class TranslatedCall extends TranslatedNonConstantExpr { result = getArgument(id) } + override final Instruction getFirstInstruction() { + if exists(getQualifier()) then + result = getQualifier().getFirstInstruction() + else + result = getFirstCallTargetInstruction() + } + + override predicate hasInstruction(Opcode opcode, InstructionTag tag, + Type resultType, boolean isGLValue) { + tag = CallTag() and + opcode instanceof Opcode::Invoke and + resultType = getCallResultType() and + isGLValue = false + } + override Instruction getChildSuccessor(TranslatedElement child) { ( child = getQualifier() and @@ -1755,14 +1816,6 @@ abstract class TranslatedCall extends TranslatedNonConstantExpr { ) } - override predicate hasInstruction(Opcode opcode, InstructionTag tag, - Type resultType, boolean isGLValue) { - tag = CallTag() and - opcode instanceof Opcode::Invoke and - resultType = call.getType().getUnspecifiedType() and - isGLValue = false - } - override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { kind instanceof GotoEdge and @@ -1789,12 +1842,14 @@ abstract class TranslatedCall extends TranslatedNonConstantExpr { ) } + override final Instruction getResult() { + result = getInstruction(CallTag()) + } + /** - * Holds if the call has any arguments, not counting the `this` argument. + * Gets the result type of the call. */ - final predicate hasArguments() { - exists(call.getArgument(0)) - } + abstract Type getCallResultType(); /** * Holds if the call has a `this` argument. @@ -1834,9 +1889,7 @@ abstract class TranslatedCall extends TranslatedNonConstantExpr { * Gets the `TranslatedExpr` for the qualifier of the call (i.e. the value * that is passed as the `this` argument. */ - final TranslatedExpr getQualifier() { - result = getTranslatedExpr(call.getQualifier().getFullyConverted()) - } + abstract TranslatedExpr getQualifier(); /** * Gets the instruction whose result value is the `this` argument of the call. @@ -1852,9 +1905,7 @@ abstract class TranslatedCall extends TranslatedNonConstantExpr { * Gets the argument with the specified `index`. Does not include the `this` * argument. */ - final TranslatedExpr getArgument(int index) { - result = getTranslatedExpr(call.getArgument(index).getFullyConverted()) - } + abstract TranslatedExpr getArgument(int index); /** * If there are any arguments, gets the first instruction of the first @@ -1866,33 +1917,182 @@ abstract class TranslatedCall extends TranslatedNonConstantExpr { else result = getInstruction(CallTag()) } + + /** + * Holds if the call has any arguments, not counting the `this` argument. + */ + abstract predicate hasArguments(); } /** - * Represents the IR translation of a call through a function pointer. + * The IR translation of the allocation size argument passed to `operator new` + * in a `new` expression. + * + * We have to synthesize this because not all `NewExpr` nodes have an allocator + * call, and even the ones that do pass an `ErrorExpr` as the argument. */ -class TranslatedExprCall extends TranslatedCall { - ExprCall exprCall; +abstract class TranslatedAllocationSize extends TranslatedExpr, + TTranslatedAllocationSize { + NewOrNewArrayExpr newExpr; + + TranslatedAllocationSize() { + this = TTranslatedAllocationSize(newExpr) and + expr = newExpr + } - TranslatedExprCall() { - expr = exprCall + override final string toString() { + result = "Allocation size for " + newExpr.toString() } - override TranslatedExpr getCallTarget() { - result = getTranslatedExpr(exprCall.getExpr().getFullyConverted()) + override final predicate producesExprResult() { + none() + } + + override final Instruction getResult() { + result = getInstruction(AllocationSizeTag()) } } +TranslatedAllocationSize getTranslatedAllocationSize(NewOrNewArrayExpr newExpr) { + result.getAST() = newExpr +} + /** - * Represents the IR translation of a direct function call. + * The IR translation of a constant allocation size. + * + * The allocation size for a `new` expression is always a constant. The + * allocation size for a `new[]` expression is a constant if the array extent + * is a compile-time constant. */ -class TranslatedFunctionCall extends TranslatedCall { - FunctionCall funcCall; +class TranslatedConstantAllocationSize extends TranslatedAllocationSize { + TranslatedConstantAllocationSize() { + not exists(newExpr.(NewArrayExpr).getExtent()) + } - TranslatedFunctionCall() { - expr = funcCall + override final Instruction getFirstInstruction() { + result = getInstruction(AllocationSizeTag()) + } + + override final predicate hasInstruction(Opcode opcode, InstructionTag tag, + Type resultType, boolean isGLValue) { + tag = AllocationSizeTag() and + opcode instanceof Opcode::Constant and + resultType = newExpr.getAllocator().getParameter(0).getType().getUnspecifiedType() and + isGLValue = false + } + + override final Instruction getInstructionSuccessor(InstructionTag tag, + EdgeKind kind) { + tag = AllocationSizeTag() and + kind instanceof GotoEdge and + result = getParent().getChildSuccessor(this) } + override final TranslatedElement getChild(int id) { + none() + } + + override final Instruction getChildSuccessor(TranslatedElement child) { + none() + } + + override final string getInstructionConstantValue(InstructionTag tag) { + tag = AllocationSizeTag() and + result = newExpr.getAllocatedType().getSize().toString() + } +} + +/** + * The IR translation of a non-constant allocation size. + * + * This class is used for the allocation size of a `new[]` expression where the + * array extent is not known at compile time. It performs the multiplication of + * the extent by the element size. + */ +class TranslatedNonConstantAllocationSize extends TranslatedAllocationSize { + NewArrayExpr newArrayExpr; + + TranslatedNonConstantAllocationSize() { + newArrayExpr = newExpr and + exists(newArrayExpr.getExtent()) + } + + override final Instruction getFirstInstruction() { + result = getExtent().getFirstInstruction() + } + + override final predicate hasInstruction(Opcode opcode, InstructionTag tag, + Type resultType, boolean isGLValue) { + isGLValue = false and + resultType = newExpr.getAllocator().getParameter(0).getType().getUnspecifiedType() and + ( + // Convert the extent to `size_t`, because the AST doesn't do this already. + tag = AllocationExtentConvertTag() and opcode instanceof Opcode::Convert or + tag = AllocationElementSizeTag() and opcode instanceof Opcode::Constant or + tag = AllocationSizeTag() and opcode instanceof Opcode::Mul // REVIEW: Overflow? + ) + } + + override final Instruction getInstructionSuccessor(InstructionTag tag, + EdgeKind kind) { + kind instanceof GotoEdge and + ( + ( + tag = AllocationExtentConvertTag() and + result = getInstruction(AllocationElementSizeTag()) + ) or + ( + tag = AllocationElementSizeTag() and + result = getInstruction(AllocationSizeTag()) + ) or + ( + tag = AllocationSizeTag() and + result = getParent().getChildSuccessor(this) + ) + ) + } + + override final TranslatedElement getChild(int id) { + id = 0 and result = getExtent() + } + + override final Instruction getChildSuccessor(TranslatedElement child) { + child = getExtent() and + result = getInstruction(AllocationExtentConvertTag()) + } + + override final string getInstructionConstantValue(InstructionTag tag) { + tag = AllocationElementSizeTag() and + result = newArrayExpr.getAllocatedElementType().getSize().toString() + } + + override final Instruction getInstructionOperand(InstructionTag tag, + OperandTag operandTag) { + ( + tag = AllocationSizeTag() and + ( + operandTag instanceof LeftOperand and result = getInstruction(AllocationExtentConvertTag()) or + operandTag instanceof RightOperand and result = getInstruction(AllocationElementSizeTag()) + ) + ) or + ( + tag = AllocationExtentConvertTag() and + operandTag instanceof UnaryOperand and + result = getExtent().getResult() + ) + } + + private TranslatedExpr getExtent() { + result = getTranslatedExpr(newArrayExpr.getExtent().getFullyConverted()) + } +} + +/** + * IR translation of a direct call to a specific function. Used for both + * explicit calls (`TranslatedFunctionCall`) and implicit calls + * (`TranslatedAllocatorCall`). + */ +abstract class TranslatedDirectCall extends TranslatedCall { override final Instruction getFirstCallTargetInstruction() { result = getInstruction(CallTargetTag()) } @@ -1902,25 +2102,140 @@ class TranslatedFunctionCall extends TranslatedCall { } override predicate hasInstruction(Opcode opcode, InstructionTag tag, - Type resultType, boolean isGLValue) { - super.hasInstruction(opcode, tag, resultType, isGLValue) or + Type resultType, boolean isGLValue) { + TranslatedCall.super.hasInstruction(opcode, tag, resultType, isGLValue) or ( tag = CallTargetTag() and opcode instanceof Opcode::FunctionAddress and - resultType instanceof BoolType and //HACK - isGLValue = false + // The database does not contain a `FunctionType` for a function unless + // its address was taken, so we'll just use glval instead of + // glval. + resultType instanceof UnknownType and + isGLValue = true ) } override Instruction getInstructionSuccessor(InstructionTag tag, - EdgeKind kind) { - result = super.getInstructionSuccessor(tag, kind) or + EdgeKind kind) { + result = TranslatedCall.super.getInstructionSuccessor(tag, kind) or ( tag = CallTargetTag() and kind instanceof GotoEdge and result = getFirstArgumentOrCallInstruction() ) } +} + +/** + * The IR translation of a call to `operator new` as part of a `new` or `new[]` + * expression. + */ +class TranslatedAllocatorCall extends TTranslatedAllocatorCall, + TranslatedDirectCall { + NewOrNewArrayExpr newExpr; + + TranslatedAllocatorCall() { + this = TTranslatedAllocatorCall(newExpr) and + expr = newExpr + } + + override final string toString() { + result = "Allocator call for " + newExpr.toString() + } + + override final predicate producesExprResult() { + none() + } + + override Function getInstructionFunction(InstructionTag tag) { + tag = CallTargetTag() and result = newExpr.getAllocator() + } + + override final Type getCallResultType() { + result = newExpr.getAllocator().getType().getUnspecifiedType() + } + + override final TranslatedExpr getQualifier() { + none() + } + + override final predicate hasArguments() { + // All allocator calls have at least one argument. + any() + } + + override final TranslatedExpr getArgument(int index) { + // If the allocator is the default operator new(void*), there will be no + // allocator call in the AST. Otherwise, there will be an allocator call + // that includes all arguments to the allocator, including the size, + // alignment (if any), and placement args. However, the size argument is + // an error node, so we need to provide the correct size argument in any + // case. + if index = 0 then + result = getTranslatedAllocationSize(newExpr) + else if(index = 1 and newExpr.hasAlignedAllocation()) then + result = getTranslatedExpr(newExpr.getAlignmentArgument()) + else + result = getTranslatedExpr(newExpr.getAllocatorCall().getArgument(index)) + } +} + +TranslatedAllocatorCall getTranslatedAllocatorCall(NewOrNewArrayExpr newExpr) { + result.getAST() = newExpr +} + +/** + * The IR translation of a call to a function. + */ +abstract class TranslatedCallExpr extends TranslatedNonConstantExpr, + TranslatedCall { + Call call; + + TranslatedCallExpr() { + expr = call + } + + override final Type getCallResultType() { + result = getResultType() + } + + override final predicate hasArguments() { + exists(call.getArgument(0)) + } + + override final TranslatedExpr getQualifier() { + result = getTranslatedExpr(call.getQualifier().getFullyConverted()) + } + + override final TranslatedExpr getArgument(int index) { + result = getTranslatedExpr(call.getArgument(index).getFullyConverted()) + } +} + +/** + * Represents the IR translation of a call through a function pointer. + */ +class TranslatedExprCall extends TranslatedCallExpr { + ExprCall exprCall; + + TranslatedExprCall() { + expr = exprCall + } + + override TranslatedExpr getCallTarget() { + result = getTranslatedExpr(exprCall.getExpr().getFullyConverted()) + } +} + +/** + * Represents the IR translation of a direct function call. + */ +class TranslatedFunctionCall extends TranslatedCallExpr, TranslatedDirectCall { + FunctionCall funcCall; + + TranslatedFunctionCall() { + expr = funcCall + } override Function getInstructionFunction(InstructionTag tag) { tag = CallTargetTag() and result = funcCall.getTarget() @@ -2498,3 +2813,103 @@ class TranslatedVarArgCopy extends TranslatedBuiltInOperation { result instanceof Opcode::VarArgCopy } } + +/** + * The IR translation of a `new` or `new[]` expression. + */ +abstract class TranslatedNewOrNewArrayExpr extends TranslatedNonConstantExpr, + InitializationContext { + NewOrNewArrayExpr newExpr; + + TranslatedNewOrNewArrayExpr() { + expr = newExpr + } + + override final TranslatedElement getChild(int id) { + id = 0 and result = getAllocatorCall() or + id = 1 and result = getInitialization() + } + + override final predicate hasInstruction(Opcode opcode, InstructionTag tag, + Type resultType, boolean isGLValue) { + tag = OnlyInstructionTag() and + opcode instanceof Opcode::Convert and + resultType = getResultType() and + isGLValue = false + } + + override final Instruction getFirstInstruction() { + result = getAllocatorCall().getFirstInstruction() + } + + override final Instruction getResult() { + result = getInstruction(OnlyInstructionTag()) + } + + override final Instruction getInstructionSuccessor(InstructionTag tag, + EdgeKind kind) { + kind instanceof GotoEdge and + tag = OnlyInstructionTag() and + if exists(getInitialization()) then + result = getInitialization().getFirstInstruction() + else + result = getParent().getChildSuccessor(this) + } + + override final Instruction getChildSuccessor(TranslatedElement child) { + child = getAllocatorCall() and result = getInstruction(OnlyInstructionTag()) or + child = getInitialization() and result = getParent().getChildSuccessor(this) + } + + override final Instruction getInstructionOperand(InstructionTag tag, + OperandTag operandTag) { + tag = OnlyInstructionTag() and + operandTag instanceof UnaryOperand and + result = getAllocatorCall().getResult() + } + + override final Instruction getTargetAddress() { + result = getInstruction(OnlyInstructionTag()) + } + + private TranslatedAllocatorCall getAllocatorCall() { + result = getTranslatedAllocatorCall(newExpr) + } + + abstract TranslatedInitialization getInitialization(); +} + +/** + * The IR translation of a `new` expression. + */ +class TranslatedNewExpr extends TranslatedNewOrNewArrayExpr { + TranslatedNewExpr() { + newExpr instanceof NewExpr + } + + override final Type getTargetType() { + result = newExpr.getAllocatedType().getUnspecifiedType() + } + + override final TranslatedInitialization getInitialization() { + result = getTranslatedInitialization(newExpr.(NewExpr).getInitializer()) + } +} + +/** + * The IR translation of a `new[]` expression. + */ +class TranslatedNewArrayExpr extends TranslatedNewOrNewArrayExpr { + TranslatedNewArrayExpr() { + newExpr instanceof NewArrayExpr + } + + override final Type getTargetType() { + result = newExpr.getAllocatedType().getUnspecifiedType() + } + + override final TranslatedInitialization getInitialization() { + // REVIEW: Figure out how we want to model array initialization in the IR. + none() + } +} diff --git a/cpp/ql/src/semmle/code/cpp/ssa/internal/aliased_ssa/Instruction.qll b/cpp/ql/src/semmle/code/cpp/ssa/internal/aliased_ssa/Instruction.qll index 7f01c8356b79..5106d7487df8 100644 --- a/cpp/ql/src/semmle/code/cpp/ssa/internal/aliased_ssa/Instruction.qll +++ b/cpp/ql/src/semmle/code/cpp/ssa/internal/aliased_ssa/Instruction.qll @@ -195,8 +195,11 @@ class Instruction extends Construction::TInstruction { private string getResultTypeString() { exists(string valcat | valcat = getValueCategoryString(resultType.toString()) and - if resultType instanceof UnknownType and exists(getResultSize()) then + if (resultType instanceof UnknownType and + not isGLValue() and + exists(getResultSize())) then ( result = valcat + "[" + getResultSize().toString() + "]" + ) else result = valcat ) diff --git a/cpp/ql/src/semmle/code/cpp/ssa/internal/ssa/Instruction.qll b/cpp/ql/src/semmle/code/cpp/ssa/internal/ssa/Instruction.qll index 7f01c8356b79..5106d7487df8 100644 --- a/cpp/ql/src/semmle/code/cpp/ssa/internal/ssa/Instruction.qll +++ b/cpp/ql/src/semmle/code/cpp/ssa/internal/ssa/Instruction.qll @@ -195,8 +195,11 @@ class Instruction extends Construction::TInstruction { private string getResultTypeString() { exists(string valcat | valcat = getValueCategoryString(resultType.toString()) and - if resultType instanceof UnknownType and exists(getResultSize()) then + if (resultType instanceof UnknownType and + not isGLValue() and + exists(getResultSize())) then ( result = valcat + "[" + getResultSize().toString() + "]" + ) else result = valcat ) diff --git a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected index eefffaf9f623..e2b377471c59 100644 --- a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected +++ b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected @@ -2,6 +2,38 @@ #-----| params: #-----| __va_list_tag::operator=() -> __va_list_tag & #-----| params: +#-----| operator new(unsigned long) -> void * +#-----| params: +#-----| 0: p#0 +#-----| Type = unsigned long +#-----| operator delete(void *, unsigned long) -> void +#-----| params: +#-----| 0: p#0 +#-----| Type = void * +#-----| 1: p#1 +#-----| Type = unsigned long +#-----| operator new(unsigned long, align_val_t) -> void * +#-----| params: +#-----| 0: p#0 +#-----| Type = unsigned long +#-----| 1: p#1 +#-----| Type = align_val_t +#-----| operator new[](unsigned long) -> void * +#-----| params: +#-----| 0: p#0 +#-----| Type = unsigned long +#-----| operator delete[](void *, unsigned long) -> void +#-----| params: +#-----| 0: p#0 +#-----| Type = void * +#-----| 1: p#1 +#-----| Type = unsigned long +#-----| operator new[](unsigned long, align_val_t) -> void * +#-----| params: +#-----| 0: p#0 +#-----| Type = unsigned long +#-----| 1: p#1 +#-----| Type = align_val_t ir.cpp: # 1| Constants() -> void # 1| params: @@ -5957,3 +5989,317 @@ ir.cpp: # 906| Type = int # 906| ValueCategory = prvalue(load) # 907| 2: return ... +# 915| operator new(size_t, float) -> void * +# 915| params: +# 915| 0: p#0 +# 915| Type = size_t +# 915| 1: p#1 +# 915| Type = float +# 916| operator new[](size_t, float) -> void * +# 916| params: +# 916| 0: p#0 +# 916| Type = size_t +# 916| 1: p#1 +# 916| Type = float +# 917| operator new(size_t, align_val_t, float) -> void * +# 917| params: +# 917| 0: p#0 +# 917| Type = size_t +# 917| 1: p#1 +# 917| Type = align_val_t +# 917| 2: p#2 +# 917| Type = float +# 918| operator new[](size_t, align_val_t, float) -> void * +# 918| params: +# 918| 0: p#0 +# 918| Type = size_t +# 918| 1: p#1 +# 918| Type = align_val_t +# 918| 2: p#2 +# 918| Type = float +# 919| operator delete(void *, float) -> void +# 919| params: +# 919| 0: p#0 +# 919| Type = void * +# 919| 1: p#1 +# 919| Type = float +# 920| operator delete[](void *, float) -> void +# 920| params: +# 920| 0: p#0 +# 920| Type = void * +# 920| 1: p#1 +# 920| Type = float +# 921| operator delete(void *, align_val_t, float) -> void +# 921| params: +# 921| 0: p#0 +# 921| Type = void * +# 921| 1: p#1 +# 921| Type = align_val_t +# 921| 2: p#2 +# 921| Type = float +# 922| operator delete[](void *, align_val_t, float) -> void +# 922| params: +# 922| 0: p#0 +# 922| Type = void * +# 922| 1: p#1 +# 922| Type = align_val_t +# 922| 2: p#2 +# 922| Type = float +# 924| SizedDealloc::operator=(SizedDealloc &&) -> SizedDealloc & +# 924| params: +#-----| 0: p#0 +#-----| Type = SizedDealloc && +# 924| SizedDealloc::operator=(const SizedDealloc &) -> SizedDealloc & +# 924| params: +#-----| 0: p#0 +#-----| Type = const SizedDealloc & +# 926| SizedDealloc::operator new(size_t) -> void * +# 926| params: +# 926| 0: p#0 +# 926| Type = size_t +# 927| SizedDealloc::operator new[](size_t) -> void * +# 927| params: +# 927| 0: p#0 +# 927| Type = size_t +# 928| SizedDealloc::operator delete(void *, size_t) -> void +# 928| params: +# 928| 0: p#0 +# 928| Type = void * +# 928| 1: p#1 +# 928| Type = size_t +# 929| SizedDealloc::operator delete[](void *, size_t) -> void +# 929| params: +# 929| 0: p#0 +# 929| Type = void * +# 929| 1: p#1 +# 929| Type = size_t +# 932| Overaligned::operator=(Overaligned &&) -> Overaligned & +# 932| params: +#-----| 0: p#0 +#-----| Type = Overaligned && +# 932| Overaligned::operator=(const Overaligned &) -> Overaligned & +# 932| params: +#-----| 0: p#0 +#-----| Type = const Overaligned & +# 936| DefaultCtorWithDefaultParam::DefaultCtorWithDefaultParam(DefaultCtorWithDefaultParam &&) -> void +# 936| params: +#-----| 0: p#0 +#-----| Type = DefaultCtorWithDefaultParam && +# 936| DefaultCtorWithDefaultParam::DefaultCtorWithDefaultParam(const DefaultCtorWithDefaultParam &) -> void +# 936| params: +#-----| 0: p#0 +#-----| Type = const DefaultCtorWithDefaultParam & +# 936| DefaultCtorWithDefaultParam::operator=(DefaultCtorWithDefaultParam &&) -> DefaultCtorWithDefaultParam & +# 936| params: +#-----| 0: p#0 +#-----| Type = DefaultCtorWithDefaultParam && +# 936| DefaultCtorWithDefaultParam::operator=(const DefaultCtorWithDefaultParam &) -> DefaultCtorWithDefaultParam & +# 936| params: +#-----| 0: p#0 +#-----| Type = const DefaultCtorWithDefaultParam & +# 937| DefaultCtorWithDefaultParam::DefaultCtorWithDefaultParam(double) -> void +# 937| params: +# 937| 0: d +# 937| Type = double +# 940| OperatorNew() -> void +# 940| params: +# 940| body: { ... } +# 941| 0: ExprStmt +# 941| 0: new +# 941| Type = int * +# 941| ValueCategory = prvalue +# 942| 1: ExprStmt +# 942| 0: new +# 942| Type = int * +# 942| ValueCategory = prvalue +# 942| 0: call to operator new +# 942| Type = void * +# 942| ValueCategory = prvalue +# 942| 0: +# 942| Type = unsigned long +# 942| ValueCategory = prvalue +# 942| 1: 1.0 +# 942| Type = float +# 942| Value = 1.0 +# 942| ValueCategory = prvalue +# 943| 2: ExprStmt +# 943| 0: new +# 943| Type = int * +# 943| ValueCategory = prvalue +# 943| 1: 0 +# 943| Type = int +# 943| Value = 0 +# 943| ValueCategory = prvalue +# 944| 3: ExprStmt +# 944| 0: new +# 944| Type = String * +# 944| ValueCategory = prvalue +# 944| 1: call to String +# 944| Type = void +# 944| ValueCategory = prvalue +# 945| 4: ExprStmt +# 945| 0: new +# 945| Type = String * +# 945| ValueCategory = prvalue +# 945| 0: call to operator new +# 945| Type = void * +# 945| ValueCategory = prvalue +# 945| 0: +# 945| Type = unsigned long +# 945| ValueCategory = prvalue +# 945| 1: 1.0 +# 945| Type = float +# 945| Value = 1.0 +# 945| ValueCategory = prvalue +# 945| 1: call to String +# 945| Type = void +# 945| ValueCategory = prvalue +# 945| 0: array to pointer conversion +# 945| Type = const char * +# 945| ValueCategory = prvalue +# 945| expr: hello +# 945| Type = const char[6] +# 945| Value = "hello" +# 945| ValueCategory = lvalue +# 946| 5: ExprStmt +# 946| 0: new +# 946| Type = Overaligned * +# 946| ValueCategory = prvalue +# 946| 3: 128 +# 946| Type = align_val_t +# 946| Value = 128 +# 946| ValueCategory = prvalue +# 947| 6: ExprStmt +# 947| 0: new +# 947| Type = Overaligned * +# 947| ValueCategory = prvalue +# 947| 0: call to operator new +# 947| Type = void * +# 947| ValueCategory = prvalue +# 947| 0: +# 947| Type = unsigned long +# 947| ValueCategory = prvalue +# 947| 1: 128 +# 947| Type = align_val_t +# 947| Value = 128 +# 947| ValueCategory = prvalue +# 947| 2: 1.0 +# 947| Type = float +# 947| Value = 1.0 +# 947| ValueCategory = prvalue +# 947| 1: 0 +# 947| Type = Overaligned +# 947| Value = 0 +# 947| ValueCategory = prvalue +# 948| 7: return ... +# 950| OperatorNewArray(int) -> void +# 950| params: +# 950| 0: n +# 950| Type = int +# 950| body: { ... } +# 951| 0: ExprStmt +# 951| 0: new[] +# 951| Type = int * +# 951| ValueCategory = prvalue +# 952| 1: ExprStmt +# 952| 0: new[] +# 952| Type = int * +# 952| ValueCategory = prvalue +# 952| 2: n +# 952| Type = int +# 952| ValueCategory = prvalue(load) +# 953| 2: ExprStmt +# 953| 0: new[] +# 953| Type = int * +# 953| ValueCategory = prvalue +# 953| 0: call to operator new[] +# 953| Type = void * +# 953| ValueCategory = prvalue +# 953| 0: +# 953| Type = unsigned long +# 953| ValueCategory = prvalue +# 953| 1: 1.0 +# 953| Type = float +# 953| Value = 1.0 +# 953| ValueCategory = prvalue +# 953| 2: n +# 953| Type = int +# 953| ValueCategory = prvalue(load) +# 954| 3: ExprStmt +# 954| 0: new[] +# 954| Type = String * +# 954| ValueCategory = prvalue +# 954| 1: {...} +# 954| Type = String[] +# 954| ValueCategory = prvalue +# 954| 0: call to String +# 954| Type = void +# 954| ValueCategory = prvalue +# 954| 2: n +# 954| Type = int +# 954| ValueCategory = prvalue(load) +# 955| 4: ExprStmt +# 955| 0: new[] +# 955| Type = Overaligned * +# 955| ValueCategory = prvalue +# 955| 2: n +# 955| Type = int +# 955| ValueCategory = prvalue(load) +# 955| 3: 128 +# 955| Type = align_val_t +# 955| Value = 128 +# 955| ValueCategory = prvalue +# 956| 5: ExprStmt +# 956| 0: new[] +# 956| Type = Overaligned * +# 956| ValueCategory = prvalue +# 956| 0: call to operator new[] +# 956| Type = void * +# 956| ValueCategory = prvalue +# 956| 0: +# 956| Type = unsigned long +# 956| ValueCategory = prvalue +# 956| 1: 128 +# 956| Type = align_val_t +# 956| Value = 128 +# 956| ValueCategory = prvalue +# 956| 2: 1.0 +# 956| Type = float +# 956| Value = 1.0 +# 956| ValueCategory = prvalue +# 957| 6: ExprStmt +# 957| 0: new[] +# 957| Type = DefaultCtorWithDefaultParam * +# 957| ValueCategory = prvalue +# 957| 1: {...} +# 957| Type = DefaultCtorWithDefaultParam[] +# 957| ValueCategory = prvalue +# 957| 0: call to DefaultCtorWithDefaultParam +# 957| Type = void +# 957| ValueCategory = prvalue +# 957| 2: n +# 957| Type = int +# 957| ValueCategory = prvalue(load) +# 958| 7: ExprStmt +# 958| 0: new[] +# 958| Type = int * +# 958| ValueCategory = prvalue +# 958| 1: {...} +# 958| Type = int[3] +# 958| ValueCategory = prvalue +# 958| 0: 0 +# 958| Type = int +# 958| Value = 0 +# 958| ValueCategory = prvalue +# 958| 1: 1 +# 958| Type = int +# 958| Value = 1 +# 958| ValueCategory = prvalue +# 958| 2: 2 +# 958| Type = int +# 958| Value = 2 +# 958| ValueCategory = prvalue +# 958| 2: n +# 958| Type = int +# 958| ValueCategory = prvalue(load) +# 959| 8: return ... diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_ir.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_ir.expected index 8f10a593dd38..0efec7a814a6 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_ir.expected @@ -1556,58 +1556,58 @@ ir.cpp: # 372| Call() -> void # 372| Block 0 -# 372| v0_0(void) = EnterFunction : -# 372| mu0_1(unknown) = UnmodeledDefinition : -# 373| r0_2(bool) = FunctionAddress[VoidFunc] : -# 373| v0_3(void) = Invoke : r0_2 -# 374| v0_4(void) = NoOp : -# 372| v0_5(void) = ReturnVoid : -# 372| v0_6(void) = UnmodeledUse : mu* -# 372| v0_7(void) = ExitFunction : +# 372| v0_0(void) = EnterFunction : +# 372| mu0_1(unknown) = UnmodeledDefinition : +# 373| r0_2(glval) = FunctionAddress[VoidFunc] : +# 373| v0_3(void) = Invoke : r0_2 +# 374| v0_4(void) = NoOp : +# 372| v0_5(void) = ReturnVoid : +# 372| v0_6(void) = UnmodeledUse : mu* +# 372| v0_7(void) = ExitFunction : # 376| CallAdd(int, int) -> int # 376| Block 0 -# 376| v0_0(void) = EnterFunction : -# 376| mu0_1(unknown) = UnmodeledDefinition : -# 376| r0_2(glval) = VariableAddress[x] : -# 376| m0_3(int) = InitializeParameter[x] : r0_2 -# 376| r0_4(glval) = VariableAddress[y] : -# 376| m0_5(int) = InitializeParameter[y] : r0_4 -# 377| r0_6(glval) = VariableAddress[#return] : -# 377| r0_7(bool) = FunctionAddress[Add] : -# 377| r0_8(glval) = VariableAddress[x] : -# 377| r0_9(int) = Load : r0_8, m0_3 -# 377| r0_10(glval) = VariableAddress[y] : -# 377| r0_11(int) = Load : r0_10, m0_5 -# 377| r0_12(int) = Invoke : r0_7, r0_9, r0_11 -# 377| m0_13(int) = Store : r0_6, r0_12 -# 376| r0_14(glval) = VariableAddress[#return] : -# 376| v0_15(void) = ReturnValue : r0_14, m0_13 -# 376| v0_16(void) = UnmodeledUse : mu* -# 376| v0_17(void) = ExitFunction : +# 376| v0_0(void) = EnterFunction : +# 376| mu0_1(unknown) = UnmodeledDefinition : +# 376| r0_2(glval) = VariableAddress[x] : +# 376| m0_3(int) = InitializeParameter[x] : r0_2 +# 376| r0_4(glval) = VariableAddress[y] : +# 376| m0_5(int) = InitializeParameter[y] : r0_4 +# 377| r0_6(glval) = VariableAddress[#return] : +# 377| r0_7(glval) = FunctionAddress[Add] : +# 377| r0_8(glval) = VariableAddress[x] : +# 377| r0_9(int) = Load : r0_8, m0_3 +# 377| r0_10(glval) = VariableAddress[y] : +# 377| r0_11(int) = Load : r0_10, m0_5 +# 377| r0_12(int) = Invoke : r0_7, r0_9, r0_11 +# 377| m0_13(int) = Store : r0_6, r0_12 +# 376| r0_14(glval) = VariableAddress[#return] : +# 376| v0_15(void) = ReturnValue : r0_14, m0_13 +# 376| v0_16(void) = UnmodeledUse : mu* +# 376| v0_17(void) = ExitFunction : # 380| Comma(int, int) -> int # 380| Block 0 -# 380| v0_0(void) = EnterFunction : -# 380| mu0_1(unknown) = UnmodeledDefinition : -# 380| r0_2(glval) = VariableAddress[x] : -# 380| m0_3(int) = InitializeParameter[x] : r0_2 -# 380| r0_4(glval) = VariableAddress[y] : -# 380| m0_5(int) = InitializeParameter[y] : r0_4 -# 381| r0_6(glval) = VariableAddress[#return] : -# 381| r0_7(bool) = FunctionAddress[VoidFunc] : -# 381| v0_8(void) = Invoke : r0_7 -# 381| r0_9(bool) = FunctionAddress[CallAdd] : -# 381| r0_10(glval) = VariableAddress[x] : -# 381| r0_11(int) = Load : r0_10, m0_3 -# 381| r0_12(glval) = VariableAddress[y] : -# 381| r0_13(int) = Load : r0_12, m0_5 -# 381| r0_14(int) = Invoke : r0_9, r0_11, r0_13 -# 381| m0_15(int) = Store : r0_6, r0_14 -# 380| r0_16(glval) = VariableAddress[#return] : -# 380| v0_17(void) = ReturnValue : r0_16, m0_15 -# 380| v0_18(void) = UnmodeledUse : mu* -# 380| v0_19(void) = ExitFunction : +# 380| v0_0(void) = EnterFunction : +# 380| mu0_1(unknown) = UnmodeledDefinition : +# 380| r0_2(glval) = VariableAddress[x] : +# 380| m0_3(int) = InitializeParameter[x] : r0_2 +# 380| r0_4(glval) = VariableAddress[y] : +# 380| m0_5(int) = InitializeParameter[y] : r0_4 +# 381| r0_6(glval) = VariableAddress[#return] : +# 381| r0_7(glval) = FunctionAddress[VoidFunc] : +# 381| v0_8(void) = Invoke : r0_7 +# 381| r0_9(glval) = FunctionAddress[CallAdd] : +# 381| r0_10(glval) = VariableAddress[x] : +# 381| r0_11(int) = Load : r0_10, m0_3 +# 381| r0_12(glval) = VariableAddress[y] : +# 381| r0_13(int) = Load : r0_12, m0_5 +# 381| r0_14(int) = Invoke : r0_9, r0_11, r0_13 +# 381| m0_15(int) = Store : r0_6, r0_14 +# 380| r0_16(glval) = VariableAddress[#return] : +# 380| v0_17(void) = ReturnValue : r0_16, m0_15 +# 380| v0_18(void) = UnmodeledUse : mu* +# 380| v0_19(void) = ExitFunction : # 384| Switch(int) -> void # 384| Block 0 @@ -2113,13 +2113,13 @@ ir.cpp: # 492| v1_3(void) = ExitFunction : # 493| Block 2 -# 493| r2_0(bool) = FunctionAddress[VoidFunc] : -# 493| v2_1(void) = Invoke : r2_0 +# 493| r2_0(glval) = FunctionAddress[VoidFunc] : +# 493| v2_1(void) = Invoke : r2_0 #-----| Goto -> Block 1 # 493| Block 3 -# 493| r3_0(bool) = FunctionAddress[VoidFunc] : -# 493| v3_1(void) = Invoke : r3_0 +# 493| r3_0(glval) = FunctionAddress[VoidFunc] : +# 493| v3_1(void) = Invoke : r3_0 #-----| Goto -> Block 1 # 496| Nullptr() -> void @@ -2519,7 +2519,7 @@ ir.cpp: # 584| Block 0 # 584| v0_0(void) = EnterFunction : # 584| mu0_1(unknown) = UnmodeledDefinition : -# 585| r0_2(bool) = FunctionAddress[VarArgFunction] : +# 585| r0_2(glval) = FunctionAddress[VarArgFunction] : # 585| r0_3(glval) = StringConstant["%d %s"] : # 585| r0_4(char *) = Convert : r0_3 # 585| r0_5(int) = Constant[1] : @@ -2557,19 +2557,19 @@ ir.cpp: # 615| v0_0(void) = EnterFunction : # 615| mu0_1(unknown) = UnmodeledDefinition : # 616| r0_2(glval) = VariableAddress[s1] : -# 616| r0_3(bool) = FunctionAddress[String] : +# 616| r0_3(glval) = FunctionAddress[String] : # 616| v0_4(void) = Invoke : r0_3, this:r0_2 # 617| r0_5(glval) = VariableAddress[s2] : -# 617| r0_6(bool) = FunctionAddress[String] : +# 617| r0_6(glval) = FunctionAddress[String] : # 617| r0_7(glval) = StringConstant["hello"] : # 617| r0_8(char *) = Convert : r0_7 # 617| v0_9(void) = Invoke : r0_6, this:r0_5, r0_8 # 618| r0_10(glval) = VariableAddress[s3] : -# 618| r0_11(bool) = FunctionAddress[ReturnObject] : +# 618| r0_11(glval) = FunctionAddress[ReturnObject] : # 618| r0_12(String) = Invoke : r0_11 # 618| m0_13(String) = Store : r0_10, r0_12 # 619| r0_14(glval) = VariableAddress[s4] : -# 619| r0_15(bool) = FunctionAddress[String] : +# 619| r0_15(glval) = FunctionAddress[String] : # 619| r0_16(glval) = StringConstant["test"] : # 619| r0_17(char *) = Convert : r0_16 # 619| v0_18(void) = Invoke : r0_15, this:r0_14, r0_17 @@ -2591,16 +2591,16 @@ ir.cpp: # 623| r0_8(glval) = VariableAddress[r] : # 623| r0_9(String &) = Load : r0_8, m0_3 # 623| r0_10(glval) = Convert : r0_9 -# 623| r0_11(bool) = FunctionAddress[c_str] : +# 623| r0_11(glval) = FunctionAddress[c_str] : # 623| r0_12(char *) = Invoke : r0_11, this:r0_10 # 624| r0_13(glval) = VariableAddress[p] : # 624| r0_14(String *) = Load : r0_13, m0_5 # 624| r0_15(String *) = Convert : r0_14 -# 624| r0_16(bool) = FunctionAddress[c_str] : +# 624| r0_16(glval) = FunctionAddress[c_str] : # 624| r0_17(char *) = Invoke : r0_16, this:r0_15 # 625| r0_18(glval) = VariableAddress[s] : # 625| r0_19(glval) = Convert : r0_18 -# 625| r0_20(bool) = FunctionAddress[c_str] : +# 625| r0_20(glval) = FunctionAddress[c_str] : # 625| r0_21(char *) = Invoke : r0_20, this:r0_19 # 626| v0_22(void) = NoOp : # 622| v0_23(void) = ReturnVoid : @@ -2695,25 +2695,25 @@ ir.cpp: # 652| C::MethodCalls() -> void # 652| Block 0 -# 652| v0_0(void) = EnterFunction : -# 652| mu0_1(unknown) = UnmodeledDefinition : -# 652| r0_2(glval) = InitializeThis : -# 653| r0_3(C *) = CopyValue : r0_2 -# 653| r0_4(bool) = FunctionAddress[InstanceMemberFunction] : -# 653| r0_5(int) = Constant[0] : -# 653| r0_6(int) = Invoke : r0_4, this:r0_3, r0_5 -# 654| r0_7(C *) = CopyValue : r0_2 -# 654| r0_8(bool) = FunctionAddress[InstanceMemberFunction] : -# 654| r0_9(int) = Constant[1] : -# 654| r0_10(int) = Invoke : r0_8, this:r0_7, r0_9 -#-----| r0_11(C *) = CopyValue : r0_2 -# 655| r0_12(bool) = FunctionAddress[InstanceMemberFunction] : -# 655| r0_13(int) = Constant[2] : -# 655| r0_14(int) = Invoke : r0_12, this:r0_11, r0_13 -# 656| v0_15(void) = NoOp : -# 652| v0_16(void) = ReturnVoid : -# 652| v0_17(void) = UnmodeledUse : mu* -# 652| v0_18(void) = ExitFunction : +# 652| v0_0(void) = EnterFunction : +# 652| mu0_1(unknown) = UnmodeledDefinition : +# 652| r0_2(glval) = InitializeThis : +# 653| r0_3(C *) = CopyValue : r0_2 +# 653| r0_4(glval) = FunctionAddress[InstanceMemberFunction] : +# 653| r0_5(int) = Constant[0] : +# 653| r0_6(int) = Invoke : r0_4, this:r0_3, r0_5 +# 654| r0_7(C *) = CopyValue : r0_2 +# 654| r0_8(glval) = FunctionAddress[InstanceMemberFunction] : +# 654| r0_9(int) = Constant[1] : +# 654| r0_10(int) = Invoke : r0_8, this:r0_7, r0_9 +#-----| r0_11(C *) = CopyValue : r0_2 +# 655| r0_12(glval) = FunctionAddress[InstanceMemberFunction] : +# 655| r0_13(int) = Constant[2] : +# 655| r0_14(int) = Invoke : r0_12, this:r0_11, r0_13 +# 656| v0_15(void) = NoOp : +# 652| v0_16(void) = ReturnVoid : +# 652| v0_17(void) = UnmodeledUse : mu* +# 652| v0_18(void) = ExitFunction : # 658| C::C() -> void # 658| Block 0 @@ -2724,7 +2724,7 @@ ir.cpp: # 659| r0_4(int) = Constant[1] : # 659| mu0_5(int) = Store : r0_3, r0_4 # 663| r0_6(glval) = FieldAddress[m_b] : r0_2 -# 663| r0_7(bool) = FunctionAddress[String] : +# 663| r0_7(glval) = FunctionAddress[String] : # 663| v0_8(void) = Invoke : r0_7, this:r0_6 # 660| r0_9(glval) = FieldAddress[m_c] : r0_2 # 660| r0_10(char) = Constant[3] : @@ -2733,7 +2733,7 @@ ir.cpp: # 661| r0_13(void *) = Constant[0] : # 661| mu0_14(void *) = Store : r0_12, r0_13 # 662| r0_15(glval) = FieldAddress[m_f] : r0_2 -# 662| r0_16(bool) = FunctionAddress[String] : +# 662| r0_16(glval) = FunctionAddress[String] : # 662| r0_17(glval) = StringConstant["test"] : # 662| r0_18(char *) = Convert : r0_17 # 662| v0_19(void) = Invoke : r0_16, this:r0_15, r0_18 @@ -2784,7 +2784,7 @@ ir.cpp: # 687| r0_9(int &) = Load : r0_8, m0_6 # 687| m0_10(int &) = Store : r0_7, r0_9 # 688| r0_11(glval) = VariableAddress[r3] : -# 688| r0_12(bool) = FunctionAddress[ReturnReference] : +# 688| r0_12(glval) = FunctionAddress[ReturnReference] : # 688| r0_13(String &) = Invoke : r0_12 # 688| r0_14(glval) = Convert : r0_13 # 688| m0_15(String &) = Store : r0_11, r0_14 @@ -2879,24 +2879,24 @@ ir.cpp: # 708| CallMin(int, int) -> int # 708| Block 0 -# 708| v0_0(void) = EnterFunction : -# 708| mu0_1(unknown) = UnmodeledDefinition : -# 708| r0_2(glval) = VariableAddress[x] : -# 708| m0_3(int) = InitializeParameter[x] : r0_2 -# 708| r0_4(glval) = VariableAddress[y] : -# 708| m0_5(int) = InitializeParameter[y] : r0_4 -# 709| r0_6(glval) = VariableAddress[#return] : -# 709| r0_7(bool) = FunctionAddress[min] : -# 709| r0_8(glval) = VariableAddress[x] : -# 709| r0_9(int) = Load : r0_8, m0_3 -# 709| r0_10(glval) = VariableAddress[y] : -# 709| r0_11(int) = Load : r0_10, m0_5 -# 709| r0_12(int) = Invoke : r0_7, r0_9, r0_11 -# 709| m0_13(int) = Store : r0_6, r0_12 -# 708| r0_14(glval) = VariableAddress[#return] : -# 708| v0_15(void) = ReturnValue : r0_14, m0_13 -# 708| v0_16(void) = UnmodeledUse : mu* -# 708| v0_17(void) = ExitFunction : +# 708| v0_0(void) = EnterFunction : +# 708| mu0_1(unknown) = UnmodeledDefinition : +# 708| r0_2(glval) = VariableAddress[x] : +# 708| m0_3(int) = InitializeParameter[x] : r0_2 +# 708| r0_4(glval) = VariableAddress[y] : +# 708| m0_5(int) = InitializeParameter[y] : r0_4 +# 709| r0_6(glval) = VariableAddress[#return] : +# 709| r0_7(glval) = FunctionAddress[min] : +# 709| r0_8(glval) = VariableAddress[x] : +# 709| r0_9(int) = Load : r0_8, m0_3 +# 709| r0_10(glval) = VariableAddress[y] : +# 709| r0_11(int) = Load : r0_10, m0_5 +# 709| r0_12(int) = Invoke : r0_7, r0_9, r0_11 +# 709| m0_13(int) = Store : r0_6, r0_12 +# 708| r0_14(glval) = VariableAddress[#return] : +# 708| v0_15(void) = ReturnValue : r0_14, m0_13 +# 708| v0_16(void) = UnmodeledUse : mu* +# 708| v0_17(void) = ExitFunction : # 715| Outer::Func(void *, char) -> long # 715| Block 0 @@ -2916,19 +2916,19 @@ ir.cpp: # 720| CallNestedTemplateFunc() -> double # 720| Block 0 -# 720| v0_0(void) = EnterFunction : -# 720| mu0_1(unknown) = UnmodeledDefinition : -# 721| r0_2(glval) = VariableAddress[#return] : -# 721| r0_3(bool) = FunctionAddress[Func] : -# 721| r0_4(void *) = Constant[0] : -# 721| r0_5(char) = Constant[111] : -# 721| r0_6(long) = Invoke : r0_3, r0_4, r0_5 -# 721| r0_7(double) = Convert : r0_6 -# 721| m0_8(double) = Store : r0_2, r0_7 -# 720| r0_9(glval) = VariableAddress[#return] : -# 720| v0_10(void) = ReturnValue : r0_9, m0_8 -# 720| v0_11(void) = UnmodeledUse : mu* -# 720| v0_12(void) = ExitFunction : +# 720| v0_0(void) = EnterFunction : +# 720| mu0_1(unknown) = UnmodeledDefinition : +# 721| r0_2(glval) = VariableAddress[#return] : +# 721| r0_3(glval) = FunctionAddress[Func] : +# 721| r0_4(void *) = Constant[0] : +# 721| r0_5(char) = Constant[111] : +# 721| r0_6(long) = Invoke : r0_3, r0_4, r0_5 +# 721| r0_7(double) = Convert : r0_6 +# 721| m0_8(double) = Store : r0_2, r0_7 +# 720| r0_9(glval) = VariableAddress[#return] : +# 720| v0_10(void) = ReturnValue : r0_9, m0_8 +# 720| v0_11(void) = UnmodeledUse : mu* +# 720| v0_12(void) = ExitFunction : # 724| TryCatch(bool) -> void # 724| Block 0 @@ -2989,7 +2989,7 @@ ir.cpp: # 731| Block 7 # 731| r7_0(glval) = VariableAddress[#throw731:19] : -# 731| r7_1(bool) = FunctionAddress[String] : +# 731| r7_1(glval) = FunctionAddress[String] : # 731| r7_2(glval) = StringConstant["String object"] : # 731| r7_3(char *) = Convert : r7_2 # 731| v7_4(void) = Invoke : r7_1, this:r7_0, r7_3 @@ -3008,14 +3008,14 @@ ir.cpp: #-----| Goto -> Block 10 # 735| Block 10 -# 735| r10_0(glval) = VariableAddress[s] : -# 735| m10_1(char *) = InitializeParameter[s] : r10_0 -# 736| r10_2(glval) = VariableAddress[#throw736:5] : -# 736| r10_3(bool) = FunctionAddress[String] : -# 736| r10_4(glval) = VariableAddress[s] : -# 736| r10_5(char *) = Load : r10_4, m10_1 -# 736| v10_6(void) = Invoke : r10_3, this:r10_2, r10_5 -# 736| v10_7(void) = ThrowValue : r10_2, mu0_1 +# 735| r10_0(glval) = VariableAddress[s] : +# 735| m10_1(char *) = InitializeParameter[s] : r10_0 +# 736| r10_2(glval) = VariableAddress[#throw736:5] : +# 736| r10_3(glval) = FunctionAddress[String] : +# 736| r10_4(glval) = VariableAddress[s] : +# 736| r10_5(char *) = Load : r10_4, m10_1 +# 736| v10_6(void) = Invoke : r10_3, this:r10_2, r10_5 +# 736| v10_7(void) = ThrowValue : r10_2, mu0_1 #-----| Exception -> Block 2 # 738| Block 11 @@ -3041,18 +3041,18 @@ ir.cpp: # 745| Base::Base(const Base &) -> void # 745| Block 0 -# 745| v0_0(void) = EnterFunction : -# 745| mu0_1(unknown) = UnmodeledDefinition : -# 745| r0_2(glval) = InitializeThis : -#-----| r0_3(glval) = VariableAddress[p#0] : -#-----| m0_4(Base &) = InitializeParameter[p#0] : r0_3 -# 745| r0_5(glval) = FieldAddress[base_s] : r0_2 -# 745| r0_6(bool) = FunctionAddress[String] : -# 745| v0_7(void) = Invoke : r0_6, this:r0_5 -# 745| v0_8(void) = NoOp : -# 745| v0_9(void) = ReturnVoid : -# 745| v0_10(void) = UnmodeledUse : mu* -# 745| v0_11(void) = ExitFunction : +# 745| v0_0(void) = EnterFunction : +# 745| mu0_1(unknown) = UnmodeledDefinition : +# 745| r0_2(glval) = InitializeThis : +#-----| r0_3(glval) = VariableAddress[p#0] : +#-----| m0_4(Base &) = InitializeParameter[p#0] : r0_3 +# 745| r0_5(glval) = FieldAddress[base_s] : r0_2 +# 745| r0_6(glval) = FunctionAddress[String] : +# 745| v0_7(void) = Invoke : r0_6, this:r0_5 +# 745| v0_8(void) = NoOp : +# 745| v0_9(void) = ReturnVoid : +# 745| v0_10(void) = UnmodeledUse : mu* +# 745| v0_11(void) = ExitFunction : # 745| Base::operator=(const Base &) -> Base & # 745| Block 0 @@ -3063,7 +3063,7 @@ ir.cpp: #-----| m0_4(Base &) = InitializeParameter[p#0] : r0_3 #-----| r0_5(Base *) = CopyValue : r0_2 #-----| r0_6(glval) = FieldAddress[base_s] : r0_5 -# 745| r0_7(bool) = FunctionAddress[operator=] : +# 745| r0_7(glval) = FunctionAddress[operator=] : #-----| r0_8(glval) = VariableAddress[p#0] : #-----| r0_9(Base &) = Load : r0_8, m0_4 #-----| r0_10(glval) = FieldAddress[base_s] : r0_9 @@ -3078,29 +3078,29 @@ ir.cpp: # 748| Base::Base() -> void # 748| Block 0 -# 748| v0_0(void) = EnterFunction : -# 748| mu0_1(unknown) = UnmodeledDefinition : -# 748| r0_2(glval) = InitializeThis : -# 748| r0_3(glval) = FieldAddress[base_s] : r0_2 -# 748| r0_4(bool) = FunctionAddress[String] : -# 748| v0_5(void) = Invoke : r0_4, this:r0_3 -# 749| v0_6(void) = NoOp : -# 748| v0_7(void) = ReturnVoid : -# 748| v0_8(void) = UnmodeledUse : mu* -# 748| v0_9(void) = ExitFunction : +# 748| v0_0(void) = EnterFunction : +# 748| mu0_1(unknown) = UnmodeledDefinition : +# 748| r0_2(glval) = InitializeThis : +# 748| r0_3(glval) = FieldAddress[base_s] : r0_2 +# 748| r0_4(glval) = FunctionAddress[String] : +# 748| v0_5(void) = Invoke : r0_4, this:r0_3 +# 749| v0_6(void) = NoOp : +# 748| v0_7(void) = ReturnVoid : +# 748| v0_8(void) = UnmodeledUse : mu* +# 748| v0_9(void) = ExitFunction : # 750| Base::~Base() -> void # 750| Block 0 -# 750| v0_0(void) = EnterFunction : -# 750| mu0_1(unknown) = UnmodeledDefinition : -# 750| r0_2(glval) = InitializeThis : -# 751| v0_3(void) = NoOp : -# 751| r0_4(glval) = FieldAddress[base_s] : r0_2 -# 751| r0_5(bool) = FunctionAddress[~String] : -# 751| v0_6(void) = Invoke : r0_5, this:r0_4 -# 750| v0_7(void) = ReturnVoid : -# 750| v0_8(void) = UnmodeledUse : mu* -# 750| v0_9(void) = ExitFunction : +# 750| v0_0(void) = EnterFunction : +# 750| mu0_1(unknown) = UnmodeledDefinition : +# 750| r0_2(glval) = InitializeThis : +# 751| v0_3(void) = NoOp : +# 751| r0_4(glval) = FieldAddress[base_s] : r0_2 +# 751| r0_5(glval) = FunctionAddress[~String] : +# 751| v0_6(void) = Invoke : r0_5, this:r0_4 +# 750| v0_7(void) = ReturnVoid : +# 750| v0_8(void) = UnmodeledUse : mu* +# 750| v0_9(void) = ExitFunction : # 754| Middle::operator=(const Middle &) -> Middle & # 754| Block 0 @@ -3111,14 +3111,14 @@ ir.cpp: #-----| m0_4(Middle &) = InitializeParameter[p#0] : r0_3 #-----| r0_5(Middle *) = CopyValue : r0_2 #-----| r0_6(Base *) = ConvertToBase[Middle : Base] : r0_5 -# 754| r0_7(bool) = FunctionAddress[operator=] : +# 754| r0_7(glval) = FunctionAddress[operator=] : #-----| r0_8(glval) = VariableAddress[p#0] : #-----| r0_9(Middle &) = Load : r0_8, m0_4 #-----| r0_10(Base *) = ConvertToBase[Middle : Base] : r0_9 # 754| r0_11(Base &) = Invoke : r0_7, this:r0_6, r0_10 #-----| r0_12(Middle *) = CopyValue : r0_2 #-----| r0_13(glval) = FieldAddress[middle_s] : r0_12 -# 754| r0_14(bool) = FunctionAddress[operator=] : +# 754| r0_14(glval) = FunctionAddress[operator=] : #-----| r0_15(glval) = VariableAddress[p#0] : #-----| r0_16(Middle &) = Load : r0_15, m0_4 #-----| r0_17(glval) = FieldAddress[middle_s] : r0_16 @@ -3133,35 +3133,35 @@ ir.cpp: # 757| Middle::Middle() -> void # 757| Block 0 -# 757| v0_0(void) = EnterFunction : -# 757| mu0_1(unknown) = UnmodeledDefinition : -# 757| r0_2(glval) = InitializeThis : -# 757| r0_3(glval) = ConvertToBase[Middle : Base] : r0_2 -# 757| r0_4(bool) = FunctionAddress[Base] : -# 757| v0_5(void) = Invoke : r0_4, this:r0_3 -# 757| r0_6(glval) = FieldAddress[middle_s] : r0_2 -# 757| r0_7(bool) = FunctionAddress[String] : -# 757| v0_8(void) = Invoke : r0_7, this:r0_6 -# 758| v0_9(void) = NoOp : -# 757| v0_10(void) = ReturnVoid : -# 757| v0_11(void) = UnmodeledUse : mu* -# 757| v0_12(void) = ExitFunction : +# 757| v0_0(void) = EnterFunction : +# 757| mu0_1(unknown) = UnmodeledDefinition : +# 757| r0_2(glval) = InitializeThis : +# 757| r0_3(glval) = ConvertToBase[Middle : Base] : r0_2 +# 757| r0_4(glval) = FunctionAddress[Base] : +# 757| v0_5(void) = Invoke : r0_4, this:r0_3 +# 757| r0_6(glval) = FieldAddress[middle_s] : r0_2 +# 757| r0_7(glval) = FunctionAddress[String] : +# 757| v0_8(void) = Invoke : r0_7, this:r0_6 +# 758| v0_9(void) = NoOp : +# 757| v0_10(void) = ReturnVoid : +# 757| v0_11(void) = UnmodeledUse : mu* +# 757| v0_12(void) = ExitFunction : # 759| Middle::~Middle() -> void # 759| Block 0 -# 759| v0_0(void) = EnterFunction : -# 759| mu0_1(unknown) = UnmodeledDefinition : -# 759| r0_2(glval) = InitializeThis : -# 760| v0_3(void) = NoOp : -# 760| r0_4(glval) = FieldAddress[middle_s] : r0_2 -# 760| r0_5(bool) = FunctionAddress[~String] : -# 760| v0_6(void) = Invoke : r0_5, this:r0_4 -# 760| r0_7(glval) = ConvertToBase[Middle : Base] : r0_2 -# 760| r0_8(bool) = FunctionAddress[~Base] : -# 760| v0_9(void) = Invoke : r0_8, this:r0_7 -# 759| v0_10(void) = ReturnVoid : -# 759| v0_11(void) = UnmodeledUse : mu* -# 759| v0_12(void) = ExitFunction : +# 759| v0_0(void) = EnterFunction : +# 759| mu0_1(unknown) = UnmodeledDefinition : +# 759| r0_2(glval) = InitializeThis : +# 760| v0_3(void) = NoOp : +# 760| r0_4(glval) = FieldAddress[middle_s] : r0_2 +# 760| r0_5(glval) = FunctionAddress[~String] : +# 760| v0_6(void) = Invoke : r0_5, this:r0_4 +# 760| r0_7(glval) = ConvertToBase[Middle : Base] : r0_2 +# 760| r0_8(glval) = FunctionAddress[~Base] : +# 760| v0_9(void) = Invoke : r0_8, this:r0_7 +# 759| v0_10(void) = ReturnVoid : +# 759| v0_11(void) = UnmodeledUse : mu* +# 759| v0_12(void) = ExitFunction : # 763| Derived::operator=(const Derived &) -> Derived & # 763| Block 0 @@ -3172,14 +3172,14 @@ ir.cpp: #-----| m0_4(Derived &) = InitializeParameter[p#0] : r0_3 #-----| r0_5(Derived *) = CopyValue : r0_2 #-----| r0_6(Middle *) = ConvertToBase[Derived : Middle] : r0_5 -# 763| r0_7(bool) = FunctionAddress[operator=] : +# 763| r0_7(glval) = FunctionAddress[operator=] : #-----| r0_8(glval) = VariableAddress[p#0] : #-----| r0_9(Derived &) = Load : r0_8, m0_4 #-----| r0_10(Middle *) = ConvertToBase[Derived : Middle] : r0_9 # 763| r0_11(Middle &) = Invoke : r0_7, this:r0_6, r0_10 #-----| r0_12(Derived *) = CopyValue : r0_2 #-----| r0_13(glval) = FieldAddress[derived_s] : r0_12 -# 763| r0_14(bool) = FunctionAddress[operator=] : +# 763| r0_14(glval) = FunctionAddress[operator=] : #-----| r0_15(glval) = VariableAddress[p#0] : #-----| r0_16(Derived &) = Load : r0_15, m0_4 #-----| r0_17(glval) = FieldAddress[derived_s] : r0_16 @@ -3198,10 +3198,10 @@ ir.cpp: # 766| mu0_1(unknown) = UnmodeledDefinition : # 766| r0_2(glval) = InitializeThis : # 766| r0_3(glval) = ConvertToBase[Derived : Middle] : r0_2 -# 766| r0_4(bool) = FunctionAddress[Middle] : +# 766| r0_4(glval) = FunctionAddress[Middle] : # 766| v0_5(void) = Invoke : r0_4, this:r0_3 # 766| r0_6(glval) = FieldAddress[derived_s] : r0_2 -# 766| r0_7(bool) = FunctionAddress[String] : +# 766| r0_7(glval) = FunctionAddress[String] : # 766| v0_8(void) = Invoke : r0_7, this:r0_6 # 767| v0_9(void) = NoOp : # 766| v0_10(void) = ReturnVoid : @@ -3215,10 +3215,10 @@ ir.cpp: # 768| r0_2(glval) = InitializeThis : # 769| v0_3(void) = NoOp : # 769| r0_4(glval) = FieldAddress[derived_s] : r0_2 -# 769| r0_5(bool) = FunctionAddress[~String] : +# 769| r0_5(glval) = FunctionAddress[~String] : # 769| v0_6(void) = Invoke : r0_5, this:r0_4 # 769| r0_7(glval) = ConvertToBase[Derived : Middle] : r0_2 -# 769| r0_8(bool) = FunctionAddress[~Middle] : +# 769| r0_8(glval) = FunctionAddress[~Middle] : # 769| v0_9(void) = Invoke : r0_8, this:r0_7 # 768| v0_10(void) = ReturnVoid : # 768| v0_11(void) = UnmodeledUse : mu* @@ -3230,10 +3230,10 @@ ir.cpp: # 775| mu0_1(unknown) = UnmodeledDefinition : # 775| r0_2(glval) = InitializeThis : # 775| r0_3(glval) = ConvertToBase[MiddleVB1 : Base] : r0_2 -# 775| r0_4(bool) = FunctionAddress[Base] : +# 775| r0_4(glval) = FunctionAddress[Base] : # 775| v0_5(void) = Invoke : r0_4, this:r0_3 # 775| r0_6(glval) = FieldAddress[middlevb1_s] : r0_2 -# 775| r0_7(bool) = FunctionAddress[String] : +# 775| r0_7(glval) = FunctionAddress[String] : # 775| v0_8(void) = Invoke : r0_7, this:r0_6 # 776| v0_9(void) = NoOp : # 775| v0_10(void) = ReturnVoid : @@ -3247,10 +3247,10 @@ ir.cpp: # 777| r0_2(glval) = InitializeThis : # 778| v0_3(void) = NoOp : # 778| r0_4(glval) = FieldAddress[middlevb1_s] : r0_2 -# 778| r0_5(bool) = FunctionAddress[~String] : +# 778| r0_5(glval) = FunctionAddress[~String] : # 778| v0_6(void) = Invoke : r0_5, this:r0_4 # 778| r0_7(glval) = ConvertToBase[MiddleVB1 : Base] : r0_2 -# 778| r0_8(bool) = FunctionAddress[~Base] : +# 778| r0_8(glval) = FunctionAddress[~Base] : # 778| v0_9(void) = Invoke : r0_8, this:r0_7 # 777| v0_10(void) = ReturnVoid : # 777| v0_11(void) = UnmodeledUse : mu* @@ -3262,10 +3262,10 @@ ir.cpp: # 784| mu0_1(unknown) = UnmodeledDefinition : # 784| r0_2(glval) = InitializeThis : # 784| r0_3(glval) = ConvertToBase[MiddleVB2 : Base] : r0_2 -# 784| r0_4(bool) = FunctionAddress[Base] : +# 784| r0_4(glval) = FunctionAddress[Base] : # 784| v0_5(void) = Invoke : r0_4, this:r0_3 # 784| r0_6(glval) = FieldAddress[middlevb2_s] : r0_2 -# 784| r0_7(bool) = FunctionAddress[String] : +# 784| r0_7(glval) = FunctionAddress[String] : # 784| v0_8(void) = Invoke : r0_7, this:r0_6 # 785| v0_9(void) = NoOp : # 784| v0_10(void) = ReturnVoid : @@ -3279,10 +3279,10 @@ ir.cpp: # 786| r0_2(glval) = InitializeThis : # 787| v0_3(void) = NoOp : # 787| r0_4(glval) = FieldAddress[middlevb2_s] : r0_2 -# 787| r0_5(bool) = FunctionAddress[~String] : +# 787| r0_5(glval) = FunctionAddress[~String] : # 787| v0_6(void) = Invoke : r0_5, this:r0_4 # 787| r0_7(glval) = ConvertToBase[MiddleVB2 : Base] : r0_2 -# 787| r0_8(bool) = FunctionAddress[~Base] : +# 787| r0_8(glval) = FunctionAddress[~Base] : # 787| v0_9(void) = Invoke : r0_8, this:r0_7 # 786| v0_10(void) = ReturnVoid : # 786| v0_11(void) = UnmodeledUse : mu* @@ -3294,16 +3294,16 @@ ir.cpp: # 793| mu0_1(unknown) = UnmodeledDefinition : # 793| r0_2(glval) = InitializeThis : # 793| r0_3(glval) = ConvertToBase[DerivedVB : Base] : r0_2 -# 793| r0_4(bool) = FunctionAddress[Base] : +# 793| r0_4(glval) = FunctionAddress[Base] : # 793| v0_5(void) = Invoke : r0_4, this:r0_3 # 793| r0_6(glval) = ConvertToBase[DerivedVB : MiddleVB1] : r0_2 -# 793| r0_7(bool) = FunctionAddress[MiddleVB1] : +# 793| r0_7(glval) = FunctionAddress[MiddleVB1] : # 793| v0_8(void) = Invoke : r0_7, this:r0_6 # 793| r0_9(glval) = ConvertToBase[DerivedVB : MiddleVB2] : r0_2 -# 793| r0_10(bool) = FunctionAddress[MiddleVB2] : +# 793| r0_10(glval) = FunctionAddress[MiddleVB2] : # 793| v0_11(void) = Invoke : r0_10, this:r0_9 # 793| r0_12(glval) = FieldAddress[derivedvb_s] : r0_2 -# 793| r0_13(bool) = FunctionAddress[String] : +# 793| r0_13(glval) = FunctionAddress[String] : # 793| v0_14(void) = Invoke : r0_13, this:r0_12 # 794| v0_15(void) = NoOp : # 793| v0_16(void) = ReturnVoid : @@ -3317,16 +3317,16 @@ ir.cpp: # 795| r0_2(glval) = InitializeThis : # 796| v0_3(void) = NoOp : # 796| r0_4(glval) = FieldAddress[derivedvb_s] : r0_2 -# 796| r0_5(bool) = FunctionAddress[~String] : +# 796| r0_5(glval) = FunctionAddress[~String] : # 796| v0_6(void) = Invoke : r0_5, this:r0_4 # 796| r0_7(glval) = ConvertToBase[DerivedVB : MiddleVB2] : r0_2 -# 796| r0_8(bool) = FunctionAddress[~MiddleVB2] : +# 796| r0_8(glval) = FunctionAddress[~MiddleVB2] : # 796| v0_9(void) = Invoke : r0_8, this:r0_7 # 796| r0_10(glval) = ConvertToBase[DerivedVB : MiddleVB1] : r0_2 -# 796| r0_11(bool) = FunctionAddress[~MiddleVB1] : +# 796| r0_11(glval) = FunctionAddress[~MiddleVB1] : # 796| v0_12(void) = Invoke : r0_11, this:r0_10 # 796| r0_13(glval) = ConvertToBase[DerivedVB : Base] : r0_2 -# 796| r0_14(bool) = FunctionAddress[~Base] : +# 796| r0_14(glval) = FunctionAddress[~Base] : # 796| v0_15(void) = Invoke : r0_14, this:r0_13 # 795| v0_16(void) = ReturnVoid : # 795| v0_17(void) = UnmodeledUse : mu* @@ -3337,13 +3337,13 @@ ir.cpp: # 799| v0_0(void) = EnterFunction : # 799| mu0_1(unknown) = UnmodeledDefinition : # 800| r0_2(glval) = VariableAddress[b] : -# 800| r0_3(bool) = FunctionAddress[Base] : +# 800| r0_3(glval) = FunctionAddress[Base] : # 800| v0_4(void) = Invoke : r0_3, this:r0_2 # 801| r0_5(glval) = VariableAddress[m] : -# 801| r0_6(bool) = FunctionAddress[Middle] : +# 801| r0_6(glval) = FunctionAddress[Middle] : # 801| v0_7(void) = Invoke : r0_6, this:r0_5 # 802| r0_8(glval) = VariableAddress[d] : -# 802| r0_9(bool) = FunctionAddress[Derived] : +# 802| r0_9(glval) = FunctionAddress[Derived] : # 802| v0_10(void) = Invoke : r0_9, this:r0_8 # 804| r0_11(glval) = VariableAddress[pb] : # 804| r0_12(glval) = VariableAddress[b] : @@ -3355,21 +3355,21 @@ ir.cpp: # 806| r0_18(glval) = VariableAddress[d] : # 806| m0_19(Derived *) = Store : r0_17, r0_18 # 808| r0_20(glval) = VariableAddress[b] : -# 808| r0_21(bool) = FunctionAddress[operator=] : +# 808| r0_21(glval) = FunctionAddress[operator=] : # 808| r0_22(glval) = VariableAddress[m] : # 808| r0_23(glval) = ConvertToBase[Middle : Base] : r0_22 # 808| r0_24(Base &) = Invoke : r0_21, this:r0_20, r0_23 # 809| r0_25(glval) = VariableAddress[b] : -# 809| r0_26(bool) = FunctionAddress[operator=] : -# 809| r0_27(bool) = FunctionAddress[Base] : +# 809| r0_26(glval) = FunctionAddress[operator=] : +# 809| r0_27(glval) = FunctionAddress[Base] : # 809| r0_28(glval) = VariableAddress[m] : # 809| r0_29(glval) = ConvertToBase[Middle : Base] : r0_28 # 809| v0_30(void) = Invoke : r0_27, r0_29 # 809| r0_31(Base) = Convert : v0_30 # 809| r0_32(Base &) = Invoke : r0_26, this:r0_25, r0_31 # 810| r0_33(glval) = VariableAddress[b] : -# 810| r0_34(bool) = FunctionAddress[operator=] : -# 810| r0_35(bool) = FunctionAddress[Base] : +# 810| r0_34(glval) = FunctionAddress[operator=] : +# 810| r0_35(glval) = FunctionAddress[Base] : # 810| r0_36(glval) = VariableAddress[m] : # 810| r0_37(glval) = ConvertToBase[Middle : Base] : r0_36 # 810| v0_38(void) = Invoke : r0_35, r0_37 @@ -3396,13 +3396,13 @@ ir.cpp: # 814| r0_59(glval) = VariableAddress[pb] : # 814| m0_60(Base *) = Store : r0_59, r0_58 # 816| r0_61(glval) = VariableAddress[m] : -# 816| r0_62(bool) = FunctionAddress[operator=] : +# 816| r0_62(glval) = FunctionAddress[operator=] : # 816| r0_63(glval) = VariableAddress[b] : # 816| r0_64(glval) = ConvertToDerived[Middle : Base] : r0_63 # 816| r0_65(glval) = Convert : r0_64 # 816| r0_66(Middle &) = Invoke : r0_62, this:r0_61, r0_65 # 817| r0_67(glval) = VariableAddress[m] : -# 817| r0_68(bool) = FunctionAddress[operator=] : +# 817| r0_68(glval) = FunctionAddress[operator=] : # 817| r0_69(glval) = VariableAddress[b] : # 817| r0_70(glval) = ConvertToDerived[Middle : Base] : r0_69 # 817| r0_71(glval) = Convert : r0_70 @@ -3423,14 +3423,14 @@ ir.cpp: # 820| r0_86(glval) = VariableAddress[pm] : # 820| m0_87(Middle *) = Store : r0_86, r0_85 # 822| r0_88(glval) = VariableAddress[b] : -# 822| r0_89(bool) = FunctionAddress[operator=] : +# 822| r0_89(glval) = FunctionAddress[operator=] : # 822| r0_90(glval) = VariableAddress[d] : # 822| r0_91(glval) = ConvertToBase[Derived : Middle] : r0_90 # 822| r0_92(glval) = ConvertToBase[Middle : Base] : r0_91 # 822| r0_93(Base &) = Invoke : r0_89, this:r0_88, r0_92 # 823| r0_94(glval) = VariableAddress[b] : -# 823| r0_95(bool) = FunctionAddress[operator=] : -# 823| r0_96(bool) = FunctionAddress[Base] : +# 823| r0_95(glval) = FunctionAddress[operator=] : +# 823| r0_96(glval) = FunctionAddress[Base] : # 823| r0_97(glval) = VariableAddress[d] : # 823| r0_98(glval) = ConvertToBase[Derived : Middle] : r0_97 # 823| r0_99(glval) = ConvertToBase[Middle : Base] : r0_98 @@ -3438,8 +3438,8 @@ ir.cpp: # 823| r0_101(Base) = Convert : v0_100 # 823| r0_102(Base &) = Invoke : r0_95, this:r0_94, r0_101 # 824| r0_103(glval) = VariableAddress[b] : -# 824| r0_104(bool) = FunctionAddress[operator=] : -# 824| r0_105(bool) = FunctionAddress[Base] : +# 824| r0_104(glval) = FunctionAddress[operator=] : +# 824| r0_105(glval) = FunctionAddress[Base] : # 824| r0_106(glval) = VariableAddress[d] : # 824| r0_107(glval) = ConvertToBase[Derived : Middle] : r0_106 # 824| r0_108(glval) = ConvertToBase[Middle : Base] : r0_107 @@ -3470,14 +3470,14 @@ ir.cpp: # 828| r0_133(glval) = VariableAddress[pb] : # 828| m0_134(Base *) = Store : r0_133, r0_132 # 830| r0_135(glval) = VariableAddress[d] : -# 830| r0_136(bool) = FunctionAddress[operator=] : +# 830| r0_136(glval) = FunctionAddress[operator=] : # 830| r0_137(glval) = VariableAddress[b] : # 830| r0_138(glval) = ConvertToDerived[Middle : Base] : r0_137 # 830| r0_139(glval) = ConvertToDerived[Derived : Middle] : r0_138 # 830| r0_140(glval) = Convert : r0_139 # 830| r0_141(Derived &) = Invoke : r0_136, this:r0_135, r0_140 # 831| r0_142(glval) = VariableAddress[d] : -# 831| r0_143(bool) = FunctionAddress[operator=] : +# 831| r0_143(glval) = FunctionAddress[operator=] : # 831| r0_144(glval) = VariableAddress[b] : # 831| r0_145(glval) = ConvertToDerived[Middle : Base] : r0_144 # 831| r0_146(glval) = ConvertToDerived[Derived : Middle] : r0_145 @@ -3537,7 +3537,7 @@ ir.cpp: # 846| mu0_1(unknown) = UnmodeledDefinition : # 846| r0_2(glval) = InitializeThis : # 846| r0_3(glval) = ConvertToBase[PolymorphicDerived : PolymorphicBase] : r0_2 -# 846| r0_4(bool) = FunctionAddress[PolymorphicBase] : +# 846| r0_4(glval) = FunctionAddress[PolymorphicBase] : # 846| v0_5(void) = Invoke : r0_4, this:r0_3 # 846| v0_6(void) = NoOp : # 846| v0_7(void) = ReturnVoid : @@ -3551,7 +3551,7 @@ ir.cpp: # 846| r0_2(glval) = InitializeThis : #-----| v0_3(void) = NoOp : # 846| r0_4(glval) = ConvertToBase[PolymorphicDerived : PolymorphicBase] : r0_2 -# 846| r0_5(bool) = FunctionAddress[~PolymorphicBase] : +# 846| r0_5(glval) = FunctionAddress[~PolymorphicBase] : # 846| v0_6(void) = Invoke : r0_5, this:r0_4 # 846| v0_7(void) = ReturnVoid : # 846| v0_8(void) = UnmodeledUse : mu* @@ -3562,10 +3562,10 @@ ir.cpp: # 849| v0_0(void) = EnterFunction : # 849| mu0_1(unknown) = UnmodeledDefinition : # 850| r0_2(glval) = VariableAddress[b] : -#-----| r0_3(bool) = FunctionAddress[PolymorphicBase] : +#-----| r0_3(glval) = FunctionAddress[PolymorphicBase] : #-----| v0_4(void) = Invoke : r0_3, this:r0_2 # 851| r0_5(glval) = VariableAddress[d] : -# 851| r0_6(bool) = FunctionAddress[PolymorphicDerived] : +# 851| r0_6(glval) = FunctionAddress[PolymorphicDerived] : # 851| v0_7(void) = Invoke : r0_6, this:r0_5 # 853| r0_8(glval) = VariableAddress[pb] : # 853| r0_9(glval) = VariableAddress[b] : @@ -3611,7 +3611,7 @@ ir.cpp: # 867| v0_0(void) = EnterFunction : # 867| mu0_1(unknown) = UnmodeledDefinition : # 867| r0_2(glval) = InitializeThis : -# 868| r0_3(bool) = FunctionAddress[String] : +# 868| r0_3(glval) = FunctionAddress[String] : # 868| r0_4(glval) = StringConstant[""] : # 868| r0_5(char *) = Convert : r0_4 # 868| v0_6(void) = Invoke : r0_3, this:r0_2, r0_5 @@ -3783,3 +3783,126 @@ ir.cpp: # 906| r3_2(glval) = VariableAddress[#temp906:11] : # 906| m3_3(int) = Store : r3_2, r3_1 #-----| Goto -> Block 1 + +# 940| OperatorNew() -> void +# 940| Block 0 +# 940| v0_0(void) = EnterFunction : +# 940| mu0_1(unknown) = UnmodeledDefinition : +# 941| r0_2(glval) = FunctionAddress[operator new] : +# 941| r0_3(unsigned long) = Constant[4] : +# 941| r0_4(void *) = Invoke : r0_2, r0_3 +# 941| r0_5(int *) = Convert : r0_4 +# 942| r0_6(glval) = FunctionAddress[operator new] : +# 942| r0_7(unsigned long) = Constant[4] : +# 942| r0_8(float) = Constant[1.0] : +# 942| r0_9(void *) = Invoke : r0_6, r0_7, r0_8 +# 942| r0_10(int *) = Convert : r0_9 +# 943| r0_11(glval) = FunctionAddress[operator new] : +# 943| r0_12(unsigned long) = Constant[4] : +# 943| r0_13(void *) = Invoke : r0_11, r0_12 +# 943| r0_14(int *) = Convert : r0_13 +# 943| r0_15(int) = Constant[0] : +# 943| mu0_16(int) = Store : r0_14, r0_15 +# 944| r0_17(glval) = FunctionAddress[operator new] : +# 944| r0_18(unsigned long) = Constant[8] : +# 944| r0_19(void *) = Invoke : r0_17, r0_18 +# 944| r0_20(String *) = Convert : r0_19 +# 944| r0_21(glval) = FunctionAddress[String] : +# 944| v0_22(void) = Invoke : r0_21, this:r0_20 +# 945| r0_23(glval) = FunctionAddress[operator new] : +# 945| r0_24(unsigned long) = Constant[8] : +# 945| r0_25(float) = Constant[1.0] : +# 945| r0_26(void *) = Invoke : r0_23, r0_24, r0_25 +# 945| r0_27(String *) = Convert : r0_26 +# 945| r0_28(glval) = FunctionAddress[String] : +# 945| r0_29(glval) = StringConstant["hello"] : +# 945| r0_30(char *) = Convert : r0_29 +# 945| v0_31(void) = Invoke : r0_28, this:r0_27, r0_30 +# 946| r0_32(glval) = FunctionAddress[operator new] : +# 946| r0_33(unsigned long) = Constant[256] : +# 946| r0_34(align_val_t) = Constant[128] : +# 946| r0_35(void *) = Invoke : r0_32, r0_33, r0_34 +# 946| r0_36(Overaligned *) = Convert : r0_35 +# 947| r0_37(glval) = FunctionAddress[operator new] : +# 947| r0_38(unsigned long) = Constant[256] : +# 947| r0_39(align_val_t) = Constant[128] : +# 947| r0_40(float) = Constant[1.0] : +# 947| r0_41(void *) = Invoke : r0_37, r0_38, r0_39, r0_40 +# 947| r0_42(Overaligned *) = Convert : r0_41 +# 947| r0_43(Overaligned) = Constant[0] : +# 947| mu0_44(Overaligned) = Store : r0_42, r0_43 +# 948| v0_45(void) = NoOp : +# 940| v0_46(void) = ReturnVoid : +# 940| v0_47(void) = UnmodeledUse : mu* +# 940| v0_48(void) = ExitFunction : + +# 950| OperatorNewArray(int) -> void +# 950| Block 0 +# 950| v0_0(void) = EnterFunction : +# 950| mu0_1(unknown) = UnmodeledDefinition : +# 950| r0_2(glval) = VariableAddress[n] : +# 950| m0_3(int) = InitializeParameter[n] : r0_2 +# 951| r0_4(glval) = FunctionAddress[operator new[]] : +# 951| r0_5(unsigned long) = Constant[40] : +# 951| r0_6(void *) = Invoke : r0_4, r0_5 +# 951| r0_7(int *) = Convert : r0_6 +# 952| r0_8(glval) = FunctionAddress[operator new[]] : +# 952| r0_9(glval) = VariableAddress[n] : +# 952| r0_10(int) = Load : r0_9, m0_3 +# 952| r0_11(unsigned long) = Convert : r0_10 +# 952| r0_12(unsigned long) = Constant[4] : +# 952| r0_13(unsigned long) = Mul : r0_11, r0_12 +# 952| r0_14(void *) = Invoke : r0_8, r0_13 +# 952| r0_15(int *) = Convert : r0_14 +# 953| r0_16(glval) = FunctionAddress[operator new[]] : +# 953| r0_17(glval) = VariableAddress[n] : +# 953| r0_18(int) = Load : r0_17, m0_3 +# 953| r0_19(unsigned long) = Convert : r0_18 +# 953| r0_20(unsigned long) = Constant[4] : +# 953| r0_21(unsigned long) = Mul : r0_19, r0_20 +# 953| r0_22(float) = Constant[1.0] : +# 953| r0_23(void *) = Invoke : r0_16, r0_21, r0_22 +# 953| r0_24(int *) = Convert : r0_23 +# 954| r0_25(glval) = FunctionAddress[operator new[]] : +# 954| r0_26(glval) = VariableAddress[n] : +# 954| r0_27(int) = Load : r0_26, m0_3 +# 954| r0_28(unsigned long) = Convert : r0_27 +# 954| r0_29(unsigned long) = Constant[8] : +# 954| r0_30(unsigned long) = Mul : r0_28, r0_29 +# 954| r0_31(void *) = Invoke : r0_25, r0_30 +# 954| r0_32(String *) = Convert : r0_31 +# 955| r0_33(glval) = FunctionAddress[operator new[]] : +# 955| r0_34(glval) = VariableAddress[n] : +# 955| r0_35(int) = Load : r0_34, m0_3 +# 955| r0_36(unsigned long) = Convert : r0_35 +# 955| r0_37(unsigned long) = Constant[256] : +# 955| r0_38(unsigned long) = Mul : r0_36, r0_37 +# 955| r0_39(align_val_t) = Constant[128] : +# 955| r0_40(void *) = Invoke : r0_33, r0_38, r0_39 +# 955| r0_41(Overaligned *) = Convert : r0_40 +# 956| r0_42(glval) = FunctionAddress[operator new[]] : +# 956| r0_43(unsigned long) = Constant[2560] : +# 956| r0_44(align_val_t) = Constant[128] : +# 956| r0_45(float) = Constant[1.0] : +# 956| r0_46(void *) = Invoke : r0_42, r0_43, r0_44, r0_45 +# 956| r0_47(Overaligned *) = Convert : r0_46 +# 957| r0_48(glval) = FunctionAddress[operator new[]] : +# 957| r0_49(glval) = VariableAddress[n] : +# 957| r0_50(int) = Load : r0_49, m0_3 +# 957| r0_51(unsigned long) = Convert : r0_50 +# 957| r0_52(unsigned long) = Constant[1] : +# 957| r0_53(unsigned long) = Mul : r0_51, r0_52 +# 957| r0_54(void *) = Invoke : r0_48, r0_53 +# 957| r0_55(DefaultCtorWithDefaultParam *) = Convert : r0_54 +# 958| r0_56(glval) = FunctionAddress[operator new[]] : +# 958| r0_57(glval) = VariableAddress[n] : +# 958| r0_58(int) = Load : r0_57, m0_3 +# 958| r0_59(unsigned long) = Convert : r0_58 +# 958| r0_60(unsigned long) = Constant[4] : +# 958| r0_61(unsigned long) = Mul : r0_59, r0_60 +# 958| r0_62(void *) = Invoke : r0_56, r0_61 +# 958| r0_63(int *) = Convert : r0_62 +# 959| v0_64(void) = NoOp : +# 950| v0_65(void) = ReturnVoid : +# 950| v0_66(void) = UnmodeledUse : mu* +# 950| v0_67(void) = ExitFunction : diff --git a/cpp/ql/test/library-tests/ir/ir/ir.cpp b/cpp/ql/test/library-tests/ir/ir/ir.cpp index fe0efe1248b9..05682c61db2c 100644 --- a/cpp/ql/test/library-tests/ir/ir/ir.cpp +++ b/cpp/ql/test/library-tests/ir/ir/ir.cpp @@ -905,3 +905,75 @@ void ConstantConditions(int x) { bool a = true && true; int b = (true) ? x : x; } + +typedef unsigned long size_t; + +namespace std { + enum class align_val_t : size_t {}; +} + +void* operator new(size_t, float); +void* operator new[](size_t, float); +void* operator new(size_t, std::align_val_t, float); +void* operator new[](size_t, std::align_val_t, float); +void operator delete(void*, float); +void operator delete[](void*, float); +void operator delete(void*, std::align_val_t, float); +void operator delete[](void*, std::align_val_t, float); + +struct SizedDealloc { + char a[32]; + void* operator new(size_t); + void* operator new[](size_t); + void operator delete(void*, size_t); + void operator delete[](void*, size_t); +}; + +struct alignas(128) Overaligned { + char a[256]; +}; + +struct DefaultCtorWithDefaultParam { + DefaultCtorWithDefaultParam(double d = 1.0); +}; + +void OperatorNew() { + new int; // No constructor + new(1.0f) int; // Placement new, no constructor + new int(); // Zero-init + new String(); // Constructor + new(1.0f) String("hello"); // Placement new, constructor with args + new Overaligned; // Aligned new + new(1.0f) Overaligned(); // Placement aligned new with zero-init +} + +void OperatorNewArray(int n) { + new int[10]; // Constant size + new int[n]; // No constructor + new(1.0f) int[n]; // Placement new, no constructor + new String[n]; // Constructor + new Overaligned[n]; // Aligned new + new(1.0f) Overaligned[10]; // Aligned placement new + new DefaultCtorWithDefaultParam[n]; + new int[n] { 0, 1, 2 }; +} + +#if 0 +void OperatorDelete() { + delete static_cast(nullptr); // No destructor + delete static_cast(nullptr); // Non-virtual destructor, with size. + delete static_cast(nullptr); // No destructor, with size. + delete static_cast(nullptr); // No destructor, with size and alignment. + delete static_cast(nullptr); // Virtual destructor +} + +void OperatorDeleteArray() { + delete[] static_cast(nullptr); // No destructor + delete[] static_cast(nullptr); // Non-virtual destructor, with size. + delete[] static_cast(nullptr); // No destructor, with size. + delete[] static_cast(nullptr); // No destructor, with size and alignment. + delete[] static_cast(nullptr); // Virtual destructor +} +#endif + +// semmle-extractor-options: -std=c++17 diff --git a/cpp/ql/test/library-tests/ir/ir/ir.expected b/cpp/ql/test/library-tests/ir/ir/ir.expected index c31267273a7b..5ed119f70b7d 100644 --- a/cpp/ql/test/library-tests/ir/ir/ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/ir.expected @@ -1544,58 +1544,58 @@ ir.cpp: # 372| Call() -> void # 372| Block 0 -# 372| v0_0(void) = EnterFunction : -# 372| mu0_1(unknown) = UnmodeledDefinition : -# 373| r0_2(bool) = FunctionAddress[VoidFunc] : -# 373| v0_3(void) = Invoke : r0_2 -# 374| v0_4(void) = NoOp : -# 372| v0_5(void) = ReturnVoid : -# 372| v0_6(void) = UnmodeledUse : mu* -# 372| v0_7(void) = ExitFunction : +# 372| v0_0(void) = EnterFunction : +# 372| mu0_1(unknown) = UnmodeledDefinition : +# 373| r0_2(glval) = FunctionAddress[VoidFunc] : +# 373| v0_3(void) = Invoke : r0_2 +# 374| v0_4(void) = NoOp : +# 372| v0_5(void) = ReturnVoid : +# 372| v0_6(void) = UnmodeledUse : mu* +# 372| v0_7(void) = ExitFunction : # 376| CallAdd(int, int) -> int # 376| Block 0 -# 376| v0_0(void) = EnterFunction : -# 376| mu0_1(unknown) = UnmodeledDefinition : -# 376| r0_2(glval) = VariableAddress[x] : -# 376| mu0_3(int) = InitializeParameter[x] : r0_2 -# 376| r0_4(glval) = VariableAddress[y] : -# 376| mu0_5(int) = InitializeParameter[y] : r0_4 -# 377| r0_6(glval) = VariableAddress[#return] : -# 377| r0_7(bool) = FunctionAddress[Add] : -# 377| r0_8(glval) = VariableAddress[x] : -# 377| r0_9(int) = Load : r0_8, mu0_1 -# 377| r0_10(glval) = VariableAddress[y] : -# 377| r0_11(int) = Load : r0_10, mu0_1 -# 377| r0_12(int) = Invoke : r0_7, r0_9, r0_11 -# 377| mu0_13(int) = Store : r0_6, r0_12 -# 376| r0_14(glval) = VariableAddress[#return] : -# 376| v0_15(void) = ReturnValue : r0_14, mu0_1 -# 376| v0_16(void) = UnmodeledUse : mu* -# 376| v0_17(void) = ExitFunction : +# 376| v0_0(void) = EnterFunction : +# 376| mu0_1(unknown) = UnmodeledDefinition : +# 376| r0_2(glval) = VariableAddress[x] : +# 376| mu0_3(int) = InitializeParameter[x] : r0_2 +# 376| r0_4(glval) = VariableAddress[y] : +# 376| mu0_5(int) = InitializeParameter[y] : r0_4 +# 377| r0_6(glval) = VariableAddress[#return] : +# 377| r0_7(glval) = FunctionAddress[Add] : +# 377| r0_8(glval) = VariableAddress[x] : +# 377| r0_9(int) = Load : r0_8, mu0_1 +# 377| r0_10(glval) = VariableAddress[y] : +# 377| r0_11(int) = Load : r0_10, mu0_1 +# 377| r0_12(int) = Invoke : r0_7, r0_9, r0_11 +# 377| mu0_13(int) = Store : r0_6, r0_12 +# 376| r0_14(glval) = VariableAddress[#return] : +# 376| v0_15(void) = ReturnValue : r0_14, mu0_1 +# 376| v0_16(void) = UnmodeledUse : mu* +# 376| v0_17(void) = ExitFunction : # 380| Comma(int, int) -> int # 380| Block 0 -# 380| v0_0(void) = EnterFunction : -# 380| mu0_1(unknown) = UnmodeledDefinition : -# 380| r0_2(glval) = VariableAddress[x] : -# 380| mu0_3(int) = InitializeParameter[x] : r0_2 -# 380| r0_4(glval) = VariableAddress[y] : -# 380| mu0_5(int) = InitializeParameter[y] : r0_4 -# 381| r0_6(glval) = VariableAddress[#return] : -# 381| r0_7(bool) = FunctionAddress[VoidFunc] : -# 381| v0_8(void) = Invoke : r0_7 -# 381| r0_9(bool) = FunctionAddress[CallAdd] : -# 381| r0_10(glval) = VariableAddress[x] : -# 381| r0_11(int) = Load : r0_10, mu0_1 -# 381| r0_12(glval) = VariableAddress[y] : -# 381| r0_13(int) = Load : r0_12, mu0_1 -# 381| r0_14(int) = Invoke : r0_9, r0_11, r0_13 -# 381| mu0_15(int) = Store : r0_6, r0_14 -# 380| r0_16(glval) = VariableAddress[#return] : -# 380| v0_17(void) = ReturnValue : r0_16, mu0_1 -# 380| v0_18(void) = UnmodeledUse : mu* -# 380| v0_19(void) = ExitFunction : +# 380| v0_0(void) = EnterFunction : +# 380| mu0_1(unknown) = UnmodeledDefinition : +# 380| r0_2(glval) = VariableAddress[x] : +# 380| mu0_3(int) = InitializeParameter[x] : r0_2 +# 380| r0_4(glval) = VariableAddress[y] : +# 380| mu0_5(int) = InitializeParameter[y] : r0_4 +# 381| r0_6(glval) = VariableAddress[#return] : +# 381| r0_7(glval) = FunctionAddress[VoidFunc] : +# 381| v0_8(void) = Invoke : r0_7 +# 381| r0_9(glval) = FunctionAddress[CallAdd] : +# 381| r0_10(glval) = VariableAddress[x] : +# 381| r0_11(int) = Load : r0_10, mu0_1 +# 381| r0_12(glval) = VariableAddress[y] : +# 381| r0_13(int) = Load : r0_12, mu0_1 +# 381| r0_14(int) = Invoke : r0_9, r0_11, r0_13 +# 381| mu0_15(int) = Store : r0_6, r0_14 +# 380| r0_16(glval) = VariableAddress[#return] : +# 380| v0_17(void) = ReturnValue : r0_16, mu0_1 +# 380| v0_18(void) = UnmodeledUse : mu* +# 380| v0_19(void) = ExitFunction : # 384| Switch(int) -> void # 384| Block 0 @@ -2096,13 +2096,13 @@ ir.cpp: # 492| v1_3(void) = ExitFunction : # 493| Block 2 -# 493| r2_0(bool) = FunctionAddress[VoidFunc] : -# 493| v2_1(void) = Invoke : r2_0 +# 493| r2_0(glval) = FunctionAddress[VoidFunc] : +# 493| v2_1(void) = Invoke : r2_0 #-----| Goto -> Block 1 # 493| Block 3 -# 493| r3_0(bool) = FunctionAddress[VoidFunc] : -# 493| v3_1(void) = Invoke : r3_0 +# 493| r3_0(glval) = FunctionAddress[VoidFunc] : +# 493| v3_1(void) = Invoke : r3_0 #-----| Goto -> Block 1 # 496| Nullptr() -> void @@ -2500,7 +2500,7 @@ ir.cpp: # 584| Block 0 # 584| v0_0(void) = EnterFunction : # 584| mu0_1(unknown) = UnmodeledDefinition : -# 585| r0_2(bool) = FunctionAddress[VarArgFunction] : +# 585| r0_2(glval) = FunctionAddress[VarArgFunction] : # 585| r0_3(glval) = StringConstant["%d %s"] : # 585| r0_4(char *) = Convert : r0_3 # 585| r0_5(int) = Constant[1] : @@ -2538,19 +2538,19 @@ ir.cpp: # 615| v0_0(void) = EnterFunction : # 615| mu0_1(unknown) = UnmodeledDefinition : # 616| r0_2(glval) = VariableAddress[s1] : -# 616| r0_3(bool) = FunctionAddress[String] : +# 616| r0_3(glval) = FunctionAddress[String] : # 616| v0_4(void) = Invoke : r0_3, this:r0_2 # 617| r0_5(glval) = VariableAddress[s2] : -# 617| r0_6(bool) = FunctionAddress[String] : +# 617| r0_6(glval) = FunctionAddress[String] : # 617| r0_7(glval) = StringConstant["hello"] : # 617| r0_8(char *) = Convert : r0_7 # 617| v0_9(void) = Invoke : r0_6, this:r0_5, r0_8 # 618| r0_10(glval) = VariableAddress[s3] : -# 618| r0_11(bool) = FunctionAddress[ReturnObject] : +# 618| r0_11(glval) = FunctionAddress[ReturnObject] : # 618| r0_12(String) = Invoke : r0_11 # 618| mu0_13(String) = Store : r0_10, r0_12 # 619| r0_14(glval) = VariableAddress[s4] : -# 619| r0_15(bool) = FunctionAddress[String] : +# 619| r0_15(glval) = FunctionAddress[String] : # 619| r0_16(glval) = StringConstant["test"] : # 619| r0_17(char *) = Convert : r0_16 # 619| v0_18(void) = Invoke : r0_15, this:r0_14, r0_17 @@ -2572,16 +2572,16 @@ ir.cpp: # 623| r0_8(glval) = VariableAddress[r] : # 623| r0_9(String &) = Load : r0_8, mu0_1 # 623| r0_10(glval) = Convert : r0_9 -# 623| r0_11(bool) = FunctionAddress[c_str] : +# 623| r0_11(glval) = FunctionAddress[c_str] : # 623| r0_12(char *) = Invoke : r0_11, this:r0_10 # 624| r0_13(glval) = VariableAddress[p] : # 624| r0_14(String *) = Load : r0_13, mu0_1 # 624| r0_15(String *) = Convert : r0_14 -# 624| r0_16(bool) = FunctionAddress[c_str] : +# 624| r0_16(glval) = FunctionAddress[c_str] : # 624| r0_17(char *) = Invoke : r0_16, this:r0_15 # 625| r0_18(glval) = VariableAddress[s] : # 625| r0_19(glval) = Convert : r0_18 -# 625| r0_20(bool) = FunctionAddress[c_str] : +# 625| r0_20(glval) = FunctionAddress[c_str] : # 625| r0_21(char *) = Invoke : r0_20, this:r0_19 # 626| v0_22(void) = NoOp : # 622| v0_23(void) = ReturnVoid : @@ -2676,25 +2676,25 @@ ir.cpp: # 652| C::MethodCalls() -> void # 652| Block 0 -# 652| v0_0(void) = EnterFunction : -# 652| mu0_1(unknown) = UnmodeledDefinition : -# 652| r0_2(glval) = InitializeThis : -# 653| r0_3(C *) = CopyValue : r0_2 -# 653| r0_4(bool) = FunctionAddress[InstanceMemberFunction] : -# 653| r0_5(int) = Constant[0] : -# 653| r0_6(int) = Invoke : r0_4, this:r0_3, r0_5 -# 654| r0_7(C *) = CopyValue : r0_2 -# 654| r0_8(bool) = FunctionAddress[InstanceMemberFunction] : -# 654| r0_9(int) = Constant[1] : -# 654| r0_10(int) = Invoke : r0_8, this:r0_7, r0_9 -#-----| r0_11(C *) = CopyValue : r0_2 -# 655| r0_12(bool) = FunctionAddress[InstanceMemberFunction] : -# 655| r0_13(int) = Constant[2] : -# 655| r0_14(int) = Invoke : r0_12, this:r0_11, r0_13 -# 656| v0_15(void) = NoOp : -# 652| v0_16(void) = ReturnVoid : -# 652| v0_17(void) = UnmodeledUse : mu* -# 652| v0_18(void) = ExitFunction : +# 652| v0_0(void) = EnterFunction : +# 652| mu0_1(unknown) = UnmodeledDefinition : +# 652| r0_2(glval) = InitializeThis : +# 653| r0_3(C *) = CopyValue : r0_2 +# 653| r0_4(glval) = FunctionAddress[InstanceMemberFunction] : +# 653| r0_5(int) = Constant[0] : +# 653| r0_6(int) = Invoke : r0_4, this:r0_3, r0_5 +# 654| r0_7(C *) = CopyValue : r0_2 +# 654| r0_8(glval) = FunctionAddress[InstanceMemberFunction] : +# 654| r0_9(int) = Constant[1] : +# 654| r0_10(int) = Invoke : r0_8, this:r0_7, r0_9 +#-----| r0_11(C *) = CopyValue : r0_2 +# 655| r0_12(glval) = FunctionAddress[InstanceMemberFunction] : +# 655| r0_13(int) = Constant[2] : +# 655| r0_14(int) = Invoke : r0_12, this:r0_11, r0_13 +# 656| v0_15(void) = NoOp : +# 652| v0_16(void) = ReturnVoid : +# 652| v0_17(void) = UnmodeledUse : mu* +# 652| v0_18(void) = ExitFunction : # 658| C::C() -> void # 658| Block 0 @@ -2705,7 +2705,7 @@ ir.cpp: # 659| r0_4(int) = Constant[1] : # 659| mu0_5(int) = Store : r0_3, r0_4 # 663| r0_6(glval) = FieldAddress[m_b] : r0_2 -# 663| r0_7(bool) = FunctionAddress[String] : +# 663| r0_7(glval) = FunctionAddress[String] : # 663| v0_8(void) = Invoke : r0_7, this:r0_6 # 660| r0_9(glval) = FieldAddress[m_c] : r0_2 # 660| r0_10(char) = Constant[3] : @@ -2714,7 +2714,7 @@ ir.cpp: # 661| r0_13(void *) = Constant[0] : # 661| mu0_14(void *) = Store : r0_12, r0_13 # 662| r0_15(glval) = FieldAddress[m_f] : r0_2 -# 662| r0_16(bool) = FunctionAddress[String] : +# 662| r0_16(glval) = FunctionAddress[String] : # 662| r0_17(glval) = StringConstant["test"] : # 662| r0_18(char *) = Convert : r0_17 # 662| v0_19(void) = Invoke : r0_16, this:r0_15, r0_18 @@ -2765,7 +2765,7 @@ ir.cpp: # 687| r0_9(int &) = Load : r0_8, mu0_1 # 687| mu0_10(int &) = Store : r0_7, r0_9 # 688| r0_11(glval) = VariableAddress[r3] : -# 688| r0_12(bool) = FunctionAddress[ReturnReference] : +# 688| r0_12(glval) = FunctionAddress[ReturnReference] : # 688| r0_13(String &) = Invoke : r0_12 # 688| r0_14(glval) = Convert : r0_13 # 688| mu0_15(String &) = Store : r0_11, r0_14 @@ -2859,24 +2859,24 @@ ir.cpp: # 708| CallMin(int, int) -> int # 708| Block 0 -# 708| v0_0(void) = EnterFunction : -# 708| mu0_1(unknown) = UnmodeledDefinition : -# 708| r0_2(glval) = VariableAddress[x] : -# 708| mu0_3(int) = InitializeParameter[x] : r0_2 -# 708| r0_4(glval) = VariableAddress[y] : -# 708| mu0_5(int) = InitializeParameter[y] : r0_4 -# 709| r0_6(glval) = VariableAddress[#return] : -# 709| r0_7(bool) = FunctionAddress[min] : -# 709| r0_8(glval) = VariableAddress[x] : -# 709| r0_9(int) = Load : r0_8, mu0_1 -# 709| r0_10(glval) = VariableAddress[y] : -# 709| r0_11(int) = Load : r0_10, mu0_1 -# 709| r0_12(int) = Invoke : r0_7, r0_9, r0_11 -# 709| mu0_13(int) = Store : r0_6, r0_12 -# 708| r0_14(glval) = VariableAddress[#return] : -# 708| v0_15(void) = ReturnValue : r0_14, mu0_1 -# 708| v0_16(void) = UnmodeledUse : mu* -# 708| v0_17(void) = ExitFunction : +# 708| v0_0(void) = EnterFunction : +# 708| mu0_1(unknown) = UnmodeledDefinition : +# 708| r0_2(glval) = VariableAddress[x] : +# 708| mu0_3(int) = InitializeParameter[x] : r0_2 +# 708| r0_4(glval) = VariableAddress[y] : +# 708| mu0_5(int) = InitializeParameter[y] : r0_4 +# 709| r0_6(glval) = VariableAddress[#return] : +# 709| r0_7(glval) = FunctionAddress[min] : +# 709| r0_8(glval) = VariableAddress[x] : +# 709| r0_9(int) = Load : r0_8, mu0_1 +# 709| r0_10(glval) = VariableAddress[y] : +# 709| r0_11(int) = Load : r0_10, mu0_1 +# 709| r0_12(int) = Invoke : r0_7, r0_9, r0_11 +# 709| mu0_13(int) = Store : r0_6, r0_12 +# 708| r0_14(glval) = VariableAddress[#return] : +# 708| v0_15(void) = ReturnValue : r0_14, mu0_1 +# 708| v0_16(void) = UnmodeledUse : mu* +# 708| v0_17(void) = ExitFunction : # 715| Outer::Func(void *, char) -> long # 715| Block 0 @@ -2896,19 +2896,19 @@ ir.cpp: # 720| CallNestedTemplateFunc() -> double # 720| Block 0 -# 720| v0_0(void) = EnterFunction : -# 720| mu0_1(unknown) = UnmodeledDefinition : -# 721| r0_2(glval) = VariableAddress[#return] : -# 721| r0_3(bool) = FunctionAddress[Func] : -# 721| r0_4(void *) = Constant[0] : -# 721| r0_5(char) = Constant[111] : -# 721| r0_6(long) = Invoke : r0_3, r0_4, r0_5 -# 721| r0_7(double) = Convert : r0_6 -# 721| mu0_8(double) = Store : r0_2, r0_7 -# 720| r0_9(glval) = VariableAddress[#return] : -# 720| v0_10(void) = ReturnValue : r0_9, mu0_1 -# 720| v0_11(void) = UnmodeledUse : mu* -# 720| v0_12(void) = ExitFunction : +# 720| v0_0(void) = EnterFunction : +# 720| mu0_1(unknown) = UnmodeledDefinition : +# 721| r0_2(glval) = VariableAddress[#return] : +# 721| r0_3(glval) = FunctionAddress[Func] : +# 721| r0_4(void *) = Constant[0] : +# 721| r0_5(char) = Constant[111] : +# 721| r0_6(long) = Invoke : r0_3, r0_4, r0_5 +# 721| r0_7(double) = Convert : r0_6 +# 721| mu0_8(double) = Store : r0_2, r0_7 +# 720| r0_9(glval) = VariableAddress[#return] : +# 720| v0_10(void) = ReturnValue : r0_9, mu0_1 +# 720| v0_11(void) = UnmodeledUse : mu* +# 720| v0_12(void) = ExitFunction : # 724| TryCatch(bool) -> void # 724| Block 0 @@ -2969,7 +2969,7 @@ ir.cpp: # 731| Block 7 # 731| r7_0(glval) = VariableAddress[#throw731:19] : -# 731| r7_1(bool) = FunctionAddress[String] : +# 731| r7_1(glval) = FunctionAddress[String] : # 731| r7_2(glval) = StringConstant["String object"] : # 731| r7_3(char *) = Convert : r7_2 # 731| v7_4(void) = Invoke : r7_1, this:r7_0, r7_3 @@ -2988,14 +2988,14 @@ ir.cpp: #-----| Goto -> Block 10 # 735| Block 10 -# 735| r10_0(glval) = VariableAddress[s] : -# 735| mu10_1(char *) = InitializeParameter[s] : r10_0 -# 736| r10_2(glval) = VariableAddress[#throw736:5] : -# 736| r10_3(bool) = FunctionAddress[String] : -# 736| r10_4(glval) = VariableAddress[s] : -# 736| r10_5(char *) = Load : r10_4, mu0_1 -# 736| v10_6(void) = Invoke : r10_3, this:r10_2, r10_5 -# 736| v10_7(void) = ThrowValue : r10_2, mu0_1 +# 735| r10_0(glval) = VariableAddress[s] : +# 735| mu10_1(char *) = InitializeParameter[s] : r10_0 +# 736| r10_2(glval) = VariableAddress[#throw736:5] : +# 736| r10_3(glval) = FunctionAddress[String] : +# 736| r10_4(glval) = VariableAddress[s] : +# 736| r10_5(char *) = Load : r10_4, mu0_1 +# 736| v10_6(void) = Invoke : r10_3, this:r10_2, r10_5 +# 736| v10_7(void) = ThrowValue : r10_2, mu0_1 #-----| Exception -> Block 2 # 738| Block 11 @@ -3021,18 +3021,18 @@ ir.cpp: # 745| Base::Base(const Base &) -> void # 745| Block 0 -# 745| v0_0(void) = EnterFunction : -# 745| mu0_1(unknown) = UnmodeledDefinition : -# 745| r0_2(glval) = InitializeThis : -#-----| r0_3(glval) = VariableAddress[p#0] : -#-----| mu0_4(Base &) = InitializeParameter[p#0] : r0_3 -# 745| r0_5(glval) = FieldAddress[base_s] : r0_2 -# 745| r0_6(bool) = FunctionAddress[String] : -# 745| v0_7(void) = Invoke : r0_6, this:r0_5 -# 745| v0_8(void) = NoOp : -# 745| v0_9(void) = ReturnVoid : -# 745| v0_10(void) = UnmodeledUse : mu* -# 745| v0_11(void) = ExitFunction : +# 745| v0_0(void) = EnterFunction : +# 745| mu0_1(unknown) = UnmodeledDefinition : +# 745| r0_2(glval) = InitializeThis : +#-----| r0_3(glval) = VariableAddress[p#0] : +#-----| mu0_4(Base &) = InitializeParameter[p#0] : r0_3 +# 745| r0_5(glval) = FieldAddress[base_s] : r0_2 +# 745| r0_6(glval) = FunctionAddress[String] : +# 745| v0_7(void) = Invoke : r0_6, this:r0_5 +# 745| v0_8(void) = NoOp : +# 745| v0_9(void) = ReturnVoid : +# 745| v0_10(void) = UnmodeledUse : mu* +# 745| v0_11(void) = ExitFunction : # 745| Base::operator=(const Base &) -> Base & # 745| Block 0 @@ -3043,7 +3043,7 @@ ir.cpp: #-----| mu0_4(Base &) = InitializeParameter[p#0] : r0_3 #-----| r0_5(Base *) = CopyValue : r0_2 #-----| r0_6(glval) = FieldAddress[base_s] : r0_5 -# 745| r0_7(bool) = FunctionAddress[operator=] : +# 745| r0_7(glval) = FunctionAddress[operator=] : #-----| r0_8(glval) = VariableAddress[p#0] : #-----| r0_9(Base &) = Load : r0_8, mu0_1 #-----| r0_10(glval) = FieldAddress[base_s] : r0_9 @@ -3058,29 +3058,29 @@ ir.cpp: # 748| Base::Base() -> void # 748| Block 0 -# 748| v0_0(void) = EnterFunction : -# 748| mu0_1(unknown) = UnmodeledDefinition : -# 748| r0_2(glval) = InitializeThis : -# 748| r0_3(glval) = FieldAddress[base_s] : r0_2 -# 748| r0_4(bool) = FunctionAddress[String] : -# 748| v0_5(void) = Invoke : r0_4, this:r0_3 -# 749| v0_6(void) = NoOp : -# 748| v0_7(void) = ReturnVoid : -# 748| v0_8(void) = UnmodeledUse : mu* -# 748| v0_9(void) = ExitFunction : +# 748| v0_0(void) = EnterFunction : +# 748| mu0_1(unknown) = UnmodeledDefinition : +# 748| r0_2(glval) = InitializeThis : +# 748| r0_3(glval) = FieldAddress[base_s] : r0_2 +# 748| r0_4(glval) = FunctionAddress[String] : +# 748| v0_5(void) = Invoke : r0_4, this:r0_3 +# 749| v0_6(void) = NoOp : +# 748| v0_7(void) = ReturnVoid : +# 748| v0_8(void) = UnmodeledUse : mu* +# 748| v0_9(void) = ExitFunction : # 750| Base::~Base() -> void # 750| Block 0 -# 750| v0_0(void) = EnterFunction : -# 750| mu0_1(unknown) = UnmodeledDefinition : -# 750| r0_2(glval) = InitializeThis : -# 751| v0_3(void) = NoOp : -# 751| r0_4(glval) = FieldAddress[base_s] : r0_2 -# 751| r0_5(bool) = FunctionAddress[~String] : -# 751| v0_6(void) = Invoke : r0_5, this:r0_4 -# 750| v0_7(void) = ReturnVoid : -# 750| v0_8(void) = UnmodeledUse : mu* -# 750| v0_9(void) = ExitFunction : +# 750| v0_0(void) = EnterFunction : +# 750| mu0_1(unknown) = UnmodeledDefinition : +# 750| r0_2(glval) = InitializeThis : +# 751| v0_3(void) = NoOp : +# 751| r0_4(glval) = FieldAddress[base_s] : r0_2 +# 751| r0_5(glval) = FunctionAddress[~String] : +# 751| v0_6(void) = Invoke : r0_5, this:r0_4 +# 750| v0_7(void) = ReturnVoid : +# 750| v0_8(void) = UnmodeledUse : mu* +# 750| v0_9(void) = ExitFunction : # 754| Middle::operator=(const Middle &) -> Middle & # 754| Block 0 @@ -3091,14 +3091,14 @@ ir.cpp: #-----| mu0_4(Middle &) = InitializeParameter[p#0] : r0_3 #-----| r0_5(Middle *) = CopyValue : r0_2 #-----| r0_6(Base *) = ConvertToBase[Middle : Base] : r0_5 -# 754| r0_7(bool) = FunctionAddress[operator=] : +# 754| r0_7(glval) = FunctionAddress[operator=] : #-----| r0_8(glval) = VariableAddress[p#0] : #-----| r0_9(Middle &) = Load : r0_8, mu0_1 #-----| r0_10(Base *) = ConvertToBase[Middle : Base] : r0_9 # 754| r0_11(Base &) = Invoke : r0_7, this:r0_6, r0_10 #-----| r0_12(Middle *) = CopyValue : r0_2 #-----| r0_13(glval) = FieldAddress[middle_s] : r0_12 -# 754| r0_14(bool) = FunctionAddress[operator=] : +# 754| r0_14(glval) = FunctionAddress[operator=] : #-----| r0_15(glval) = VariableAddress[p#0] : #-----| r0_16(Middle &) = Load : r0_15, mu0_1 #-----| r0_17(glval) = FieldAddress[middle_s] : r0_16 @@ -3113,35 +3113,35 @@ ir.cpp: # 757| Middle::Middle() -> void # 757| Block 0 -# 757| v0_0(void) = EnterFunction : -# 757| mu0_1(unknown) = UnmodeledDefinition : -# 757| r0_2(glval) = InitializeThis : -# 757| r0_3(glval) = ConvertToBase[Middle : Base] : r0_2 -# 757| r0_4(bool) = FunctionAddress[Base] : -# 757| v0_5(void) = Invoke : r0_4, this:r0_3 -# 757| r0_6(glval) = FieldAddress[middle_s] : r0_2 -# 757| r0_7(bool) = FunctionAddress[String] : -# 757| v0_8(void) = Invoke : r0_7, this:r0_6 -# 758| v0_9(void) = NoOp : -# 757| v0_10(void) = ReturnVoid : -# 757| v0_11(void) = UnmodeledUse : mu* -# 757| v0_12(void) = ExitFunction : +# 757| v0_0(void) = EnterFunction : +# 757| mu0_1(unknown) = UnmodeledDefinition : +# 757| r0_2(glval) = InitializeThis : +# 757| r0_3(glval) = ConvertToBase[Middle : Base] : r0_2 +# 757| r0_4(glval) = FunctionAddress[Base] : +# 757| v0_5(void) = Invoke : r0_4, this:r0_3 +# 757| r0_6(glval) = FieldAddress[middle_s] : r0_2 +# 757| r0_7(glval) = FunctionAddress[String] : +# 757| v0_8(void) = Invoke : r0_7, this:r0_6 +# 758| v0_9(void) = NoOp : +# 757| v0_10(void) = ReturnVoid : +# 757| v0_11(void) = UnmodeledUse : mu* +# 757| v0_12(void) = ExitFunction : # 759| Middle::~Middle() -> void # 759| Block 0 -# 759| v0_0(void) = EnterFunction : -# 759| mu0_1(unknown) = UnmodeledDefinition : -# 759| r0_2(glval) = InitializeThis : -# 760| v0_3(void) = NoOp : -# 760| r0_4(glval) = FieldAddress[middle_s] : r0_2 -# 760| r0_5(bool) = FunctionAddress[~String] : -# 760| v0_6(void) = Invoke : r0_5, this:r0_4 -# 760| r0_7(glval) = ConvertToBase[Middle : Base] : r0_2 -# 760| r0_8(bool) = FunctionAddress[~Base] : -# 760| v0_9(void) = Invoke : r0_8, this:r0_7 -# 759| v0_10(void) = ReturnVoid : -# 759| v0_11(void) = UnmodeledUse : mu* -# 759| v0_12(void) = ExitFunction : +# 759| v0_0(void) = EnterFunction : +# 759| mu0_1(unknown) = UnmodeledDefinition : +# 759| r0_2(glval) = InitializeThis : +# 760| v0_3(void) = NoOp : +# 760| r0_4(glval) = FieldAddress[middle_s] : r0_2 +# 760| r0_5(glval) = FunctionAddress[~String] : +# 760| v0_6(void) = Invoke : r0_5, this:r0_4 +# 760| r0_7(glval) = ConvertToBase[Middle : Base] : r0_2 +# 760| r0_8(glval) = FunctionAddress[~Base] : +# 760| v0_9(void) = Invoke : r0_8, this:r0_7 +# 759| v0_10(void) = ReturnVoid : +# 759| v0_11(void) = UnmodeledUse : mu* +# 759| v0_12(void) = ExitFunction : # 763| Derived::operator=(const Derived &) -> Derived & # 763| Block 0 @@ -3152,14 +3152,14 @@ ir.cpp: #-----| mu0_4(Derived &) = InitializeParameter[p#0] : r0_3 #-----| r0_5(Derived *) = CopyValue : r0_2 #-----| r0_6(Middle *) = ConvertToBase[Derived : Middle] : r0_5 -# 763| r0_7(bool) = FunctionAddress[operator=] : +# 763| r0_7(glval) = FunctionAddress[operator=] : #-----| r0_8(glval) = VariableAddress[p#0] : #-----| r0_9(Derived &) = Load : r0_8, mu0_1 #-----| r0_10(Middle *) = ConvertToBase[Derived : Middle] : r0_9 # 763| r0_11(Middle &) = Invoke : r0_7, this:r0_6, r0_10 #-----| r0_12(Derived *) = CopyValue : r0_2 #-----| r0_13(glval) = FieldAddress[derived_s] : r0_12 -# 763| r0_14(bool) = FunctionAddress[operator=] : +# 763| r0_14(glval) = FunctionAddress[operator=] : #-----| r0_15(glval) = VariableAddress[p#0] : #-----| r0_16(Derived &) = Load : r0_15, mu0_1 #-----| r0_17(glval) = FieldAddress[derived_s] : r0_16 @@ -3178,10 +3178,10 @@ ir.cpp: # 766| mu0_1(unknown) = UnmodeledDefinition : # 766| r0_2(glval) = InitializeThis : # 766| r0_3(glval) = ConvertToBase[Derived : Middle] : r0_2 -# 766| r0_4(bool) = FunctionAddress[Middle] : +# 766| r0_4(glval) = FunctionAddress[Middle] : # 766| v0_5(void) = Invoke : r0_4, this:r0_3 # 766| r0_6(glval) = FieldAddress[derived_s] : r0_2 -# 766| r0_7(bool) = FunctionAddress[String] : +# 766| r0_7(glval) = FunctionAddress[String] : # 766| v0_8(void) = Invoke : r0_7, this:r0_6 # 767| v0_9(void) = NoOp : # 766| v0_10(void) = ReturnVoid : @@ -3195,10 +3195,10 @@ ir.cpp: # 768| r0_2(glval) = InitializeThis : # 769| v0_3(void) = NoOp : # 769| r0_4(glval) = FieldAddress[derived_s] : r0_2 -# 769| r0_5(bool) = FunctionAddress[~String] : +# 769| r0_5(glval) = FunctionAddress[~String] : # 769| v0_6(void) = Invoke : r0_5, this:r0_4 # 769| r0_7(glval) = ConvertToBase[Derived : Middle] : r0_2 -# 769| r0_8(bool) = FunctionAddress[~Middle] : +# 769| r0_8(glval) = FunctionAddress[~Middle] : # 769| v0_9(void) = Invoke : r0_8, this:r0_7 # 768| v0_10(void) = ReturnVoid : # 768| v0_11(void) = UnmodeledUse : mu* @@ -3210,10 +3210,10 @@ ir.cpp: # 775| mu0_1(unknown) = UnmodeledDefinition : # 775| r0_2(glval) = InitializeThis : # 775| r0_3(glval) = ConvertToBase[MiddleVB1 : Base] : r0_2 -# 775| r0_4(bool) = FunctionAddress[Base] : +# 775| r0_4(glval) = FunctionAddress[Base] : # 775| v0_5(void) = Invoke : r0_4, this:r0_3 # 775| r0_6(glval) = FieldAddress[middlevb1_s] : r0_2 -# 775| r0_7(bool) = FunctionAddress[String] : +# 775| r0_7(glval) = FunctionAddress[String] : # 775| v0_8(void) = Invoke : r0_7, this:r0_6 # 776| v0_9(void) = NoOp : # 775| v0_10(void) = ReturnVoid : @@ -3227,10 +3227,10 @@ ir.cpp: # 777| r0_2(glval) = InitializeThis : # 778| v0_3(void) = NoOp : # 778| r0_4(glval) = FieldAddress[middlevb1_s] : r0_2 -# 778| r0_5(bool) = FunctionAddress[~String] : +# 778| r0_5(glval) = FunctionAddress[~String] : # 778| v0_6(void) = Invoke : r0_5, this:r0_4 # 778| r0_7(glval) = ConvertToBase[MiddleVB1 : Base] : r0_2 -# 778| r0_8(bool) = FunctionAddress[~Base] : +# 778| r0_8(glval) = FunctionAddress[~Base] : # 778| v0_9(void) = Invoke : r0_8, this:r0_7 # 777| v0_10(void) = ReturnVoid : # 777| v0_11(void) = UnmodeledUse : mu* @@ -3242,10 +3242,10 @@ ir.cpp: # 784| mu0_1(unknown) = UnmodeledDefinition : # 784| r0_2(glval) = InitializeThis : # 784| r0_3(glval) = ConvertToBase[MiddleVB2 : Base] : r0_2 -# 784| r0_4(bool) = FunctionAddress[Base] : +# 784| r0_4(glval) = FunctionAddress[Base] : # 784| v0_5(void) = Invoke : r0_4, this:r0_3 # 784| r0_6(glval) = FieldAddress[middlevb2_s] : r0_2 -# 784| r0_7(bool) = FunctionAddress[String] : +# 784| r0_7(glval) = FunctionAddress[String] : # 784| v0_8(void) = Invoke : r0_7, this:r0_6 # 785| v0_9(void) = NoOp : # 784| v0_10(void) = ReturnVoid : @@ -3259,10 +3259,10 @@ ir.cpp: # 786| r0_2(glval) = InitializeThis : # 787| v0_3(void) = NoOp : # 787| r0_4(glval) = FieldAddress[middlevb2_s] : r0_2 -# 787| r0_5(bool) = FunctionAddress[~String] : +# 787| r0_5(glval) = FunctionAddress[~String] : # 787| v0_6(void) = Invoke : r0_5, this:r0_4 # 787| r0_7(glval) = ConvertToBase[MiddleVB2 : Base] : r0_2 -# 787| r0_8(bool) = FunctionAddress[~Base] : +# 787| r0_8(glval) = FunctionAddress[~Base] : # 787| v0_9(void) = Invoke : r0_8, this:r0_7 # 786| v0_10(void) = ReturnVoid : # 786| v0_11(void) = UnmodeledUse : mu* @@ -3274,16 +3274,16 @@ ir.cpp: # 793| mu0_1(unknown) = UnmodeledDefinition : # 793| r0_2(glval) = InitializeThis : # 793| r0_3(glval) = ConvertToBase[DerivedVB : Base] : r0_2 -# 793| r0_4(bool) = FunctionAddress[Base] : +# 793| r0_4(glval) = FunctionAddress[Base] : # 793| v0_5(void) = Invoke : r0_4, this:r0_3 # 793| r0_6(glval) = ConvertToBase[DerivedVB : MiddleVB1] : r0_2 -# 793| r0_7(bool) = FunctionAddress[MiddleVB1] : +# 793| r0_7(glval) = FunctionAddress[MiddleVB1] : # 793| v0_8(void) = Invoke : r0_7, this:r0_6 # 793| r0_9(glval) = ConvertToBase[DerivedVB : MiddleVB2] : r0_2 -# 793| r0_10(bool) = FunctionAddress[MiddleVB2] : +# 793| r0_10(glval) = FunctionAddress[MiddleVB2] : # 793| v0_11(void) = Invoke : r0_10, this:r0_9 # 793| r0_12(glval) = FieldAddress[derivedvb_s] : r0_2 -# 793| r0_13(bool) = FunctionAddress[String] : +# 793| r0_13(glval) = FunctionAddress[String] : # 793| v0_14(void) = Invoke : r0_13, this:r0_12 # 794| v0_15(void) = NoOp : # 793| v0_16(void) = ReturnVoid : @@ -3297,16 +3297,16 @@ ir.cpp: # 795| r0_2(glval) = InitializeThis : # 796| v0_3(void) = NoOp : # 796| r0_4(glval) = FieldAddress[derivedvb_s] : r0_2 -# 796| r0_5(bool) = FunctionAddress[~String] : +# 796| r0_5(glval) = FunctionAddress[~String] : # 796| v0_6(void) = Invoke : r0_5, this:r0_4 # 796| r0_7(glval) = ConvertToBase[DerivedVB : MiddleVB2] : r0_2 -# 796| r0_8(bool) = FunctionAddress[~MiddleVB2] : +# 796| r0_8(glval) = FunctionAddress[~MiddleVB2] : # 796| v0_9(void) = Invoke : r0_8, this:r0_7 # 796| r0_10(glval) = ConvertToBase[DerivedVB : MiddleVB1] : r0_2 -# 796| r0_11(bool) = FunctionAddress[~MiddleVB1] : +# 796| r0_11(glval) = FunctionAddress[~MiddleVB1] : # 796| v0_12(void) = Invoke : r0_11, this:r0_10 # 796| r0_13(glval) = ConvertToBase[DerivedVB : Base] : r0_2 -# 796| r0_14(bool) = FunctionAddress[~Base] : +# 796| r0_14(glval) = FunctionAddress[~Base] : # 796| v0_15(void) = Invoke : r0_14, this:r0_13 # 795| v0_16(void) = ReturnVoid : # 795| v0_17(void) = UnmodeledUse : mu* @@ -3317,13 +3317,13 @@ ir.cpp: # 799| v0_0(void) = EnterFunction : # 799| mu0_1(unknown) = UnmodeledDefinition : # 800| r0_2(glval) = VariableAddress[b] : -# 800| r0_3(bool) = FunctionAddress[Base] : +# 800| r0_3(glval) = FunctionAddress[Base] : # 800| v0_4(void) = Invoke : r0_3, this:r0_2 # 801| r0_5(glval) = VariableAddress[m] : -# 801| r0_6(bool) = FunctionAddress[Middle] : +# 801| r0_6(glval) = FunctionAddress[Middle] : # 801| v0_7(void) = Invoke : r0_6, this:r0_5 # 802| r0_8(glval) = VariableAddress[d] : -# 802| r0_9(bool) = FunctionAddress[Derived] : +# 802| r0_9(glval) = FunctionAddress[Derived] : # 802| v0_10(void) = Invoke : r0_9, this:r0_8 # 804| r0_11(glval) = VariableAddress[pb] : # 804| r0_12(glval) = VariableAddress[b] : @@ -3335,21 +3335,21 @@ ir.cpp: # 806| r0_18(glval) = VariableAddress[d] : # 806| mu0_19(Derived *) = Store : r0_17, r0_18 # 808| r0_20(glval) = VariableAddress[b] : -# 808| r0_21(bool) = FunctionAddress[operator=] : +# 808| r0_21(glval) = FunctionAddress[operator=] : # 808| r0_22(glval) = VariableAddress[m] : # 808| r0_23(glval) = ConvertToBase[Middle : Base] : r0_22 # 808| r0_24(Base &) = Invoke : r0_21, this:r0_20, r0_23 # 809| r0_25(glval) = VariableAddress[b] : -# 809| r0_26(bool) = FunctionAddress[operator=] : -# 809| r0_27(bool) = FunctionAddress[Base] : +# 809| r0_26(glval) = FunctionAddress[operator=] : +# 809| r0_27(glval) = FunctionAddress[Base] : # 809| r0_28(glval) = VariableAddress[m] : # 809| r0_29(glval) = ConvertToBase[Middle : Base] : r0_28 # 809| v0_30(void) = Invoke : r0_27, r0_29 # 809| r0_31(Base) = Convert : v0_30 # 809| r0_32(Base &) = Invoke : r0_26, this:r0_25, r0_31 # 810| r0_33(glval) = VariableAddress[b] : -# 810| r0_34(bool) = FunctionAddress[operator=] : -# 810| r0_35(bool) = FunctionAddress[Base] : +# 810| r0_34(glval) = FunctionAddress[operator=] : +# 810| r0_35(glval) = FunctionAddress[Base] : # 810| r0_36(glval) = VariableAddress[m] : # 810| r0_37(glval) = ConvertToBase[Middle : Base] : r0_36 # 810| v0_38(void) = Invoke : r0_35, r0_37 @@ -3376,13 +3376,13 @@ ir.cpp: # 814| r0_59(glval) = VariableAddress[pb] : # 814| mu0_60(Base *) = Store : r0_59, r0_58 # 816| r0_61(glval) = VariableAddress[m] : -# 816| r0_62(bool) = FunctionAddress[operator=] : +# 816| r0_62(glval) = FunctionAddress[operator=] : # 816| r0_63(glval) = VariableAddress[b] : # 816| r0_64(glval) = ConvertToDerived[Middle : Base] : r0_63 # 816| r0_65(glval) = Convert : r0_64 # 816| r0_66(Middle &) = Invoke : r0_62, this:r0_61, r0_65 # 817| r0_67(glval) = VariableAddress[m] : -# 817| r0_68(bool) = FunctionAddress[operator=] : +# 817| r0_68(glval) = FunctionAddress[operator=] : # 817| r0_69(glval) = VariableAddress[b] : # 817| r0_70(glval) = ConvertToDerived[Middle : Base] : r0_69 # 817| r0_71(glval) = Convert : r0_70 @@ -3403,14 +3403,14 @@ ir.cpp: # 820| r0_86(glval) = VariableAddress[pm] : # 820| mu0_87(Middle *) = Store : r0_86, r0_85 # 822| r0_88(glval) = VariableAddress[b] : -# 822| r0_89(bool) = FunctionAddress[operator=] : +# 822| r0_89(glval) = FunctionAddress[operator=] : # 822| r0_90(glval) = VariableAddress[d] : # 822| r0_91(glval) = ConvertToBase[Derived : Middle] : r0_90 # 822| r0_92(glval) = ConvertToBase[Middle : Base] : r0_91 # 822| r0_93(Base &) = Invoke : r0_89, this:r0_88, r0_92 # 823| r0_94(glval) = VariableAddress[b] : -# 823| r0_95(bool) = FunctionAddress[operator=] : -# 823| r0_96(bool) = FunctionAddress[Base] : +# 823| r0_95(glval) = FunctionAddress[operator=] : +# 823| r0_96(glval) = FunctionAddress[Base] : # 823| r0_97(glval) = VariableAddress[d] : # 823| r0_98(glval) = ConvertToBase[Derived : Middle] : r0_97 # 823| r0_99(glval) = ConvertToBase[Middle : Base] : r0_98 @@ -3418,8 +3418,8 @@ ir.cpp: # 823| r0_101(Base) = Convert : v0_100 # 823| r0_102(Base &) = Invoke : r0_95, this:r0_94, r0_101 # 824| r0_103(glval) = VariableAddress[b] : -# 824| r0_104(bool) = FunctionAddress[operator=] : -# 824| r0_105(bool) = FunctionAddress[Base] : +# 824| r0_104(glval) = FunctionAddress[operator=] : +# 824| r0_105(glval) = FunctionAddress[Base] : # 824| r0_106(glval) = VariableAddress[d] : # 824| r0_107(glval) = ConvertToBase[Derived : Middle] : r0_106 # 824| r0_108(glval) = ConvertToBase[Middle : Base] : r0_107 @@ -3450,14 +3450,14 @@ ir.cpp: # 828| r0_133(glval) = VariableAddress[pb] : # 828| mu0_134(Base *) = Store : r0_133, r0_132 # 830| r0_135(glval) = VariableAddress[d] : -# 830| r0_136(bool) = FunctionAddress[operator=] : +# 830| r0_136(glval) = FunctionAddress[operator=] : # 830| r0_137(glval) = VariableAddress[b] : # 830| r0_138(glval) = ConvertToDerived[Middle : Base] : r0_137 # 830| r0_139(glval) = ConvertToDerived[Derived : Middle] : r0_138 # 830| r0_140(glval) = Convert : r0_139 # 830| r0_141(Derived &) = Invoke : r0_136, this:r0_135, r0_140 # 831| r0_142(glval) = VariableAddress[d] : -# 831| r0_143(bool) = FunctionAddress[operator=] : +# 831| r0_143(glval) = FunctionAddress[operator=] : # 831| r0_144(glval) = VariableAddress[b] : # 831| r0_145(glval) = ConvertToDerived[Middle : Base] : r0_144 # 831| r0_146(glval) = ConvertToDerived[Derived : Middle] : r0_145 @@ -3517,7 +3517,7 @@ ir.cpp: # 846| mu0_1(unknown) = UnmodeledDefinition : # 846| r0_2(glval) = InitializeThis : # 846| r0_3(glval) = ConvertToBase[PolymorphicDerived : PolymorphicBase] : r0_2 -# 846| r0_4(bool) = FunctionAddress[PolymorphicBase] : +# 846| r0_4(glval) = FunctionAddress[PolymorphicBase] : # 846| v0_5(void) = Invoke : r0_4, this:r0_3 # 846| v0_6(void) = NoOp : # 846| v0_7(void) = ReturnVoid : @@ -3531,7 +3531,7 @@ ir.cpp: # 846| r0_2(glval) = InitializeThis : #-----| v0_3(void) = NoOp : # 846| r0_4(glval) = ConvertToBase[PolymorphicDerived : PolymorphicBase] : r0_2 -# 846| r0_5(bool) = FunctionAddress[~PolymorphicBase] : +# 846| r0_5(glval) = FunctionAddress[~PolymorphicBase] : # 846| v0_6(void) = Invoke : r0_5, this:r0_4 # 846| v0_7(void) = ReturnVoid : # 846| v0_8(void) = UnmodeledUse : mu* @@ -3542,10 +3542,10 @@ ir.cpp: # 849| v0_0(void) = EnterFunction : # 849| mu0_1(unknown) = UnmodeledDefinition : # 850| r0_2(glval) = VariableAddress[b] : -#-----| r0_3(bool) = FunctionAddress[PolymorphicBase] : +#-----| r0_3(glval) = FunctionAddress[PolymorphicBase] : #-----| v0_4(void) = Invoke : r0_3, this:r0_2 # 851| r0_5(glval) = VariableAddress[d] : -# 851| r0_6(bool) = FunctionAddress[PolymorphicDerived] : +# 851| r0_6(glval) = FunctionAddress[PolymorphicDerived] : # 851| v0_7(void) = Invoke : r0_6, this:r0_5 # 853| r0_8(glval) = VariableAddress[pb] : # 853| r0_9(glval) = VariableAddress[b] : @@ -3591,7 +3591,7 @@ ir.cpp: # 867| v0_0(void) = EnterFunction : # 867| mu0_1(unknown) = UnmodeledDefinition : # 867| r0_2(glval) = InitializeThis : -# 868| r0_3(bool) = FunctionAddress[String] : +# 868| r0_3(glval) = FunctionAddress[String] : # 868| r0_4(glval) = StringConstant[""] : # 868| r0_5(char *) = Convert : r0_4 # 868| v0_6(void) = Invoke : r0_3, this:r0_2, r0_5 @@ -3762,3 +3762,126 @@ ir.cpp: # 906| r3_2(glval) = VariableAddress[#temp906:11] : # 906| mu3_3(int) = Store : r3_2, r3_1 #-----| Goto -> Block 1 + +# 940| OperatorNew() -> void +# 940| Block 0 +# 940| v0_0(void) = EnterFunction : +# 940| mu0_1(unknown) = UnmodeledDefinition : +# 941| r0_2(glval) = FunctionAddress[operator new] : +# 941| r0_3(unsigned long) = Constant[4] : +# 941| r0_4(void *) = Invoke : r0_2, r0_3 +# 941| r0_5(int *) = Convert : r0_4 +# 942| r0_6(glval) = FunctionAddress[operator new] : +# 942| r0_7(unsigned long) = Constant[4] : +# 942| r0_8(float) = Constant[1.0] : +# 942| r0_9(void *) = Invoke : r0_6, r0_7, r0_8 +# 942| r0_10(int *) = Convert : r0_9 +# 943| r0_11(glval) = FunctionAddress[operator new] : +# 943| r0_12(unsigned long) = Constant[4] : +# 943| r0_13(void *) = Invoke : r0_11, r0_12 +# 943| r0_14(int *) = Convert : r0_13 +# 943| r0_15(int) = Constant[0] : +# 943| mu0_16(int) = Store : r0_14, r0_15 +# 944| r0_17(glval) = FunctionAddress[operator new] : +# 944| r0_18(unsigned long) = Constant[8] : +# 944| r0_19(void *) = Invoke : r0_17, r0_18 +# 944| r0_20(String *) = Convert : r0_19 +# 944| r0_21(glval) = FunctionAddress[String] : +# 944| v0_22(void) = Invoke : r0_21, this:r0_20 +# 945| r0_23(glval) = FunctionAddress[operator new] : +# 945| r0_24(unsigned long) = Constant[8] : +# 945| r0_25(float) = Constant[1.0] : +# 945| r0_26(void *) = Invoke : r0_23, r0_24, r0_25 +# 945| r0_27(String *) = Convert : r0_26 +# 945| r0_28(glval) = FunctionAddress[String] : +# 945| r0_29(glval) = StringConstant["hello"] : +# 945| r0_30(char *) = Convert : r0_29 +# 945| v0_31(void) = Invoke : r0_28, this:r0_27, r0_30 +# 946| r0_32(glval) = FunctionAddress[operator new] : +# 946| r0_33(unsigned long) = Constant[256] : +# 946| r0_34(align_val_t) = Constant[128] : +# 946| r0_35(void *) = Invoke : r0_32, r0_33, r0_34 +# 946| r0_36(Overaligned *) = Convert : r0_35 +# 947| r0_37(glval) = FunctionAddress[operator new] : +# 947| r0_38(unsigned long) = Constant[256] : +# 947| r0_39(align_val_t) = Constant[128] : +# 947| r0_40(float) = Constant[1.0] : +# 947| r0_41(void *) = Invoke : r0_37, r0_38, r0_39, r0_40 +# 947| r0_42(Overaligned *) = Convert : r0_41 +# 947| r0_43(Overaligned) = Constant[0] : +# 947| mu0_44(Overaligned) = Store : r0_42, r0_43 +# 948| v0_45(void) = NoOp : +# 940| v0_46(void) = ReturnVoid : +# 940| v0_47(void) = UnmodeledUse : mu* +# 940| v0_48(void) = ExitFunction : + +# 950| OperatorNewArray(int) -> void +# 950| Block 0 +# 950| v0_0(void) = EnterFunction : +# 950| mu0_1(unknown) = UnmodeledDefinition : +# 950| r0_2(glval) = VariableAddress[n] : +# 950| mu0_3(int) = InitializeParameter[n] : r0_2 +# 951| r0_4(glval) = FunctionAddress[operator new[]] : +# 951| r0_5(unsigned long) = Constant[40] : +# 951| r0_6(void *) = Invoke : r0_4, r0_5 +# 951| r0_7(int *) = Convert : r0_6 +# 952| r0_8(glval) = FunctionAddress[operator new[]] : +# 952| r0_9(glval) = VariableAddress[n] : +# 952| r0_10(int) = Load : r0_9, mu0_1 +# 952| r0_11(unsigned long) = Convert : r0_10 +# 952| r0_12(unsigned long) = Constant[4] : +# 952| r0_13(unsigned long) = Mul : r0_11, r0_12 +# 952| r0_14(void *) = Invoke : r0_8, r0_13 +# 952| r0_15(int *) = Convert : r0_14 +# 953| r0_16(glval) = FunctionAddress[operator new[]] : +# 953| r0_17(glval) = VariableAddress[n] : +# 953| r0_18(int) = Load : r0_17, mu0_1 +# 953| r0_19(unsigned long) = Convert : r0_18 +# 953| r0_20(unsigned long) = Constant[4] : +# 953| r0_21(unsigned long) = Mul : r0_19, r0_20 +# 953| r0_22(float) = Constant[1.0] : +# 953| r0_23(void *) = Invoke : r0_16, r0_21, r0_22 +# 953| r0_24(int *) = Convert : r0_23 +# 954| r0_25(glval) = FunctionAddress[operator new[]] : +# 954| r0_26(glval) = VariableAddress[n] : +# 954| r0_27(int) = Load : r0_26, mu0_1 +# 954| r0_28(unsigned long) = Convert : r0_27 +# 954| r0_29(unsigned long) = Constant[8] : +# 954| r0_30(unsigned long) = Mul : r0_28, r0_29 +# 954| r0_31(void *) = Invoke : r0_25, r0_30 +# 954| r0_32(String *) = Convert : r0_31 +# 955| r0_33(glval) = FunctionAddress[operator new[]] : +# 955| r0_34(glval) = VariableAddress[n] : +# 955| r0_35(int) = Load : r0_34, mu0_1 +# 955| r0_36(unsigned long) = Convert : r0_35 +# 955| r0_37(unsigned long) = Constant[256] : +# 955| r0_38(unsigned long) = Mul : r0_36, r0_37 +# 955| r0_39(align_val_t) = Constant[128] : +# 955| r0_40(void *) = Invoke : r0_33, r0_38, r0_39 +# 955| r0_41(Overaligned *) = Convert : r0_40 +# 956| r0_42(glval) = FunctionAddress[operator new[]] : +# 956| r0_43(unsigned long) = Constant[2560] : +# 956| r0_44(align_val_t) = Constant[128] : +# 956| r0_45(float) = Constant[1.0] : +# 956| r0_46(void *) = Invoke : r0_42, r0_43, r0_44, r0_45 +# 956| r0_47(Overaligned *) = Convert : r0_46 +# 957| r0_48(glval) = FunctionAddress[operator new[]] : +# 957| r0_49(glval) = VariableAddress[n] : +# 957| r0_50(int) = Load : r0_49, mu0_1 +# 957| r0_51(unsigned long) = Convert : r0_50 +# 957| r0_52(unsigned long) = Constant[1] : +# 957| r0_53(unsigned long) = Mul : r0_51, r0_52 +# 957| r0_54(void *) = Invoke : r0_48, r0_53 +# 957| r0_55(DefaultCtorWithDefaultParam *) = Convert : r0_54 +# 958| r0_56(glval) = FunctionAddress[operator new[]] : +# 958| r0_57(glval) = VariableAddress[n] : +# 958| r0_58(int) = Load : r0_57, mu0_1 +# 958| r0_59(unsigned long) = Convert : r0_58 +# 958| r0_60(unsigned long) = Constant[4] : +# 958| r0_61(unsigned long) = Mul : r0_59, r0_60 +# 958| r0_62(void *) = Invoke : r0_56, r0_61 +# 958| r0_63(int *) = Convert : r0_62 +# 959| v0_64(void) = NoOp : +# 950| v0_65(void) = ReturnVoid : +# 950| v0_66(void) = UnmodeledUse : mu* +# 950| v0_67(void) = ExitFunction : diff --git a/cpp/ql/test/library-tests/ir/ir/ssa_block_count.expected b/cpp/ql/test/library-tests/ir/ir/ssa_block_count.expected index f3b1d0697b6d..4bd31c2a64f0 100644 --- a/cpp/ql/test/library-tests/ir/ir/ssa_block_count.expected +++ b/cpp/ql/test/library-tests/ir/ir/ssa_block_count.expected @@ -70,6 +70,8 @@ | IR: MiddleVB2 | 1 | | IR: NestedInitList | 1 | | IR: Nullptr | 1 | +| IR: OperatorNew | 1 | +| IR: OperatorNewArray | 1 | | IR: Parameters | 1 | | IR: PointerCompare | 1 | | IR: PointerCrement | 1 | diff --git a/cpp/ql/test/library-tests/ir/ir/ssa_ir.expected b/cpp/ql/test/library-tests/ir/ir/ssa_ir.expected index 1ee0e3c30e97..c168845702b1 100644 --- a/cpp/ql/test/library-tests/ir/ir/ssa_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/ssa_ir.expected @@ -1556,58 +1556,58 @@ ir.cpp: # 372| Call() -> void # 372| Block 0 -# 372| v0_0(void) = EnterFunction : -# 372| mu0_1(unknown) = UnmodeledDefinition : -# 373| r0_2(bool) = FunctionAddress[VoidFunc] : -# 373| v0_3(void) = Invoke : r0_2 -# 374| v0_4(void) = NoOp : -# 372| v0_5(void) = ReturnVoid : -# 372| v0_6(void) = UnmodeledUse : mu* -# 372| v0_7(void) = ExitFunction : +# 372| v0_0(void) = EnterFunction : +# 372| mu0_1(unknown) = UnmodeledDefinition : +# 373| r0_2(glval) = FunctionAddress[VoidFunc] : +# 373| v0_3(void) = Invoke : r0_2 +# 374| v0_4(void) = NoOp : +# 372| v0_5(void) = ReturnVoid : +# 372| v0_6(void) = UnmodeledUse : mu* +# 372| v0_7(void) = ExitFunction : # 376| CallAdd(int, int) -> int # 376| Block 0 -# 376| v0_0(void) = EnterFunction : -# 376| mu0_1(unknown) = UnmodeledDefinition : -# 376| r0_2(glval) = VariableAddress[x] : -# 376| m0_3(int) = InitializeParameter[x] : r0_2 -# 376| r0_4(glval) = VariableAddress[y] : -# 376| m0_5(int) = InitializeParameter[y] : r0_4 -# 377| r0_6(glval) = VariableAddress[#return] : -# 377| r0_7(bool) = FunctionAddress[Add] : -# 377| r0_8(glval) = VariableAddress[x] : -# 377| r0_9(int) = Load : r0_8, m0_3 -# 377| r0_10(glval) = VariableAddress[y] : -# 377| r0_11(int) = Load : r0_10, m0_5 -# 377| r0_12(int) = Invoke : r0_7, r0_9, r0_11 -# 377| m0_13(int) = Store : r0_6, r0_12 -# 376| r0_14(glval) = VariableAddress[#return] : -# 376| v0_15(void) = ReturnValue : r0_14, m0_13 -# 376| v0_16(void) = UnmodeledUse : mu* -# 376| v0_17(void) = ExitFunction : +# 376| v0_0(void) = EnterFunction : +# 376| mu0_1(unknown) = UnmodeledDefinition : +# 376| r0_2(glval) = VariableAddress[x] : +# 376| m0_3(int) = InitializeParameter[x] : r0_2 +# 376| r0_4(glval) = VariableAddress[y] : +# 376| m0_5(int) = InitializeParameter[y] : r0_4 +# 377| r0_6(glval) = VariableAddress[#return] : +# 377| r0_7(glval) = FunctionAddress[Add] : +# 377| r0_8(glval) = VariableAddress[x] : +# 377| r0_9(int) = Load : r0_8, m0_3 +# 377| r0_10(glval) = VariableAddress[y] : +# 377| r0_11(int) = Load : r0_10, m0_5 +# 377| r0_12(int) = Invoke : r0_7, r0_9, r0_11 +# 377| m0_13(int) = Store : r0_6, r0_12 +# 376| r0_14(glval) = VariableAddress[#return] : +# 376| v0_15(void) = ReturnValue : r0_14, m0_13 +# 376| v0_16(void) = UnmodeledUse : mu* +# 376| v0_17(void) = ExitFunction : # 380| Comma(int, int) -> int # 380| Block 0 -# 380| v0_0(void) = EnterFunction : -# 380| mu0_1(unknown) = UnmodeledDefinition : -# 380| r0_2(glval) = VariableAddress[x] : -# 380| m0_3(int) = InitializeParameter[x] : r0_2 -# 380| r0_4(glval) = VariableAddress[y] : -# 380| m0_5(int) = InitializeParameter[y] : r0_4 -# 381| r0_6(glval) = VariableAddress[#return] : -# 381| r0_7(bool) = FunctionAddress[VoidFunc] : -# 381| v0_8(void) = Invoke : r0_7 -# 381| r0_9(bool) = FunctionAddress[CallAdd] : -# 381| r0_10(glval) = VariableAddress[x] : -# 381| r0_11(int) = Load : r0_10, m0_3 -# 381| r0_12(glval) = VariableAddress[y] : -# 381| r0_13(int) = Load : r0_12, m0_5 -# 381| r0_14(int) = Invoke : r0_9, r0_11, r0_13 -# 381| m0_15(int) = Store : r0_6, r0_14 -# 380| r0_16(glval) = VariableAddress[#return] : -# 380| v0_17(void) = ReturnValue : r0_16, m0_15 -# 380| v0_18(void) = UnmodeledUse : mu* -# 380| v0_19(void) = ExitFunction : +# 380| v0_0(void) = EnterFunction : +# 380| mu0_1(unknown) = UnmodeledDefinition : +# 380| r0_2(glval) = VariableAddress[x] : +# 380| m0_3(int) = InitializeParameter[x] : r0_2 +# 380| r0_4(glval) = VariableAddress[y] : +# 380| m0_5(int) = InitializeParameter[y] : r0_4 +# 381| r0_6(glval) = VariableAddress[#return] : +# 381| r0_7(glval) = FunctionAddress[VoidFunc] : +# 381| v0_8(void) = Invoke : r0_7 +# 381| r0_9(glval) = FunctionAddress[CallAdd] : +# 381| r0_10(glval) = VariableAddress[x] : +# 381| r0_11(int) = Load : r0_10, m0_3 +# 381| r0_12(glval) = VariableAddress[y] : +# 381| r0_13(int) = Load : r0_12, m0_5 +# 381| r0_14(int) = Invoke : r0_9, r0_11, r0_13 +# 381| m0_15(int) = Store : r0_6, r0_14 +# 380| r0_16(glval) = VariableAddress[#return] : +# 380| v0_17(void) = ReturnValue : r0_16, m0_15 +# 380| v0_18(void) = UnmodeledUse : mu* +# 380| v0_19(void) = ExitFunction : # 384| Switch(int) -> void # 384| Block 0 @@ -2113,13 +2113,13 @@ ir.cpp: # 492| v1_3(void) = ExitFunction : # 493| Block 2 -# 493| r2_0(bool) = FunctionAddress[VoidFunc] : -# 493| v2_1(void) = Invoke : r2_0 +# 493| r2_0(glval) = FunctionAddress[VoidFunc] : +# 493| v2_1(void) = Invoke : r2_0 #-----| Goto -> Block 1 # 493| Block 3 -# 493| r3_0(bool) = FunctionAddress[VoidFunc] : -# 493| v3_1(void) = Invoke : r3_0 +# 493| r3_0(glval) = FunctionAddress[VoidFunc] : +# 493| v3_1(void) = Invoke : r3_0 #-----| Goto -> Block 1 # 496| Nullptr() -> void @@ -2519,7 +2519,7 @@ ir.cpp: # 584| Block 0 # 584| v0_0(void) = EnterFunction : # 584| mu0_1(unknown) = UnmodeledDefinition : -# 585| r0_2(bool) = FunctionAddress[VarArgFunction] : +# 585| r0_2(glval) = FunctionAddress[VarArgFunction] : # 585| r0_3(glval) = StringConstant["%d %s"] : # 585| r0_4(char *) = Convert : r0_3 # 585| r0_5(int) = Constant[1] : @@ -2557,19 +2557,19 @@ ir.cpp: # 615| v0_0(void) = EnterFunction : # 615| mu0_1(unknown) = UnmodeledDefinition : # 616| r0_2(glval) = VariableAddress[s1] : -# 616| r0_3(bool) = FunctionAddress[String] : +# 616| r0_3(glval) = FunctionAddress[String] : # 616| v0_4(void) = Invoke : r0_3, this:r0_2 # 617| r0_5(glval) = VariableAddress[s2] : -# 617| r0_6(bool) = FunctionAddress[String] : +# 617| r0_6(glval) = FunctionAddress[String] : # 617| r0_7(glval) = StringConstant["hello"] : # 617| r0_8(char *) = Convert : r0_7 # 617| v0_9(void) = Invoke : r0_6, this:r0_5, r0_8 # 618| r0_10(glval) = VariableAddress[s3] : -# 618| r0_11(bool) = FunctionAddress[ReturnObject] : +# 618| r0_11(glval) = FunctionAddress[ReturnObject] : # 618| r0_12(String) = Invoke : r0_11 # 618| m0_13(String) = Store : r0_10, r0_12 # 619| r0_14(glval) = VariableAddress[s4] : -# 619| r0_15(bool) = FunctionAddress[String] : +# 619| r0_15(glval) = FunctionAddress[String] : # 619| r0_16(glval) = StringConstant["test"] : # 619| r0_17(char *) = Convert : r0_16 # 619| v0_18(void) = Invoke : r0_15, this:r0_14, r0_17 @@ -2591,16 +2591,16 @@ ir.cpp: # 623| r0_8(glval) = VariableAddress[r] : # 623| r0_9(String &) = Load : r0_8, m0_3 # 623| r0_10(glval) = Convert : r0_9 -# 623| r0_11(bool) = FunctionAddress[c_str] : +# 623| r0_11(glval) = FunctionAddress[c_str] : # 623| r0_12(char *) = Invoke : r0_11, this:r0_10 # 624| r0_13(glval) = VariableAddress[p] : # 624| r0_14(String *) = Load : r0_13, m0_5 # 624| r0_15(String *) = Convert : r0_14 -# 624| r0_16(bool) = FunctionAddress[c_str] : +# 624| r0_16(glval) = FunctionAddress[c_str] : # 624| r0_17(char *) = Invoke : r0_16, this:r0_15 # 625| r0_18(glval) = VariableAddress[s] : # 625| r0_19(glval) = Convert : r0_18 -# 625| r0_20(bool) = FunctionAddress[c_str] : +# 625| r0_20(glval) = FunctionAddress[c_str] : # 625| r0_21(char *) = Invoke : r0_20, this:r0_19 # 626| v0_22(void) = NoOp : # 622| v0_23(void) = ReturnVoid : @@ -2695,25 +2695,25 @@ ir.cpp: # 652| C::MethodCalls() -> void # 652| Block 0 -# 652| v0_0(void) = EnterFunction : -# 652| mu0_1(unknown) = UnmodeledDefinition : -# 652| r0_2(glval) = InitializeThis : -# 653| r0_3(C *) = CopyValue : r0_2 -# 653| r0_4(bool) = FunctionAddress[InstanceMemberFunction] : -# 653| r0_5(int) = Constant[0] : -# 653| r0_6(int) = Invoke : r0_4, this:r0_3, r0_5 -# 654| r0_7(C *) = CopyValue : r0_2 -# 654| r0_8(bool) = FunctionAddress[InstanceMemberFunction] : -# 654| r0_9(int) = Constant[1] : -# 654| r0_10(int) = Invoke : r0_8, this:r0_7, r0_9 -#-----| r0_11(C *) = CopyValue : r0_2 -# 655| r0_12(bool) = FunctionAddress[InstanceMemberFunction] : -# 655| r0_13(int) = Constant[2] : -# 655| r0_14(int) = Invoke : r0_12, this:r0_11, r0_13 -# 656| v0_15(void) = NoOp : -# 652| v0_16(void) = ReturnVoid : -# 652| v0_17(void) = UnmodeledUse : mu* -# 652| v0_18(void) = ExitFunction : +# 652| v0_0(void) = EnterFunction : +# 652| mu0_1(unknown) = UnmodeledDefinition : +# 652| r0_2(glval) = InitializeThis : +# 653| r0_3(C *) = CopyValue : r0_2 +# 653| r0_4(glval) = FunctionAddress[InstanceMemberFunction] : +# 653| r0_5(int) = Constant[0] : +# 653| r0_6(int) = Invoke : r0_4, this:r0_3, r0_5 +# 654| r0_7(C *) = CopyValue : r0_2 +# 654| r0_8(glval) = FunctionAddress[InstanceMemberFunction] : +# 654| r0_9(int) = Constant[1] : +# 654| r0_10(int) = Invoke : r0_8, this:r0_7, r0_9 +#-----| r0_11(C *) = CopyValue : r0_2 +# 655| r0_12(glval) = FunctionAddress[InstanceMemberFunction] : +# 655| r0_13(int) = Constant[2] : +# 655| r0_14(int) = Invoke : r0_12, this:r0_11, r0_13 +# 656| v0_15(void) = NoOp : +# 652| v0_16(void) = ReturnVoid : +# 652| v0_17(void) = UnmodeledUse : mu* +# 652| v0_18(void) = ExitFunction : # 658| C::C() -> void # 658| Block 0 @@ -2724,7 +2724,7 @@ ir.cpp: # 659| r0_4(int) = Constant[1] : # 659| mu0_5(int) = Store : r0_3, r0_4 # 663| r0_6(glval) = FieldAddress[m_b] : r0_2 -# 663| r0_7(bool) = FunctionAddress[String] : +# 663| r0_7(glval) = FunctionAddress[String] : # 663| v0_8(void) = Invoke : r0_7, this:r0_6 # 660| r0_9(glval) = FieldAddress[m_c] : r0_2 # 660| r0_10(char) = Constant[3] : @@ -2733,7 +2733,7 @@ ir.cpp: # 661| r0_13(void *) = Constant[0] : # 661| mu0_14(void *) = Store : r0_12, r0_13 # 662| r0_15(glval) = FieldAddress[m_f] : r0_2 -# 662| r0_16(bool) = FunctionAddress[String] : +# 662| r0_16(glval) = FunctionAddress[String] : # 662| r0_17(glval) = StringConstant["test"] : # 662| r0_18(char *) = Convert : r0_17 # 662| v0_19(void) = Invoke : r0_16, this:r0_15, r0_18 @@ -2784,7 +2784,7 @@ ir.cpp: # 687| r0_9(int &) = Load : r0_8, m0_6 # 687| m0_10(int &) = Store : r0_7, r0_9 # 688| r0_11(glval) = VariableAddress[r3] : -# 688| r0_12(bool) = FunctionAddress[ReturnReference] : +# 688| r0_12(glval) = FunctionAddress[ReturnReference] : # 688| r0_13(String &) = Invoke : r0_12 # 688| r0_14(glval) = Convert : r0_13 # 688| m0_15(String &) = Store : r0_11, r0_14 @@ -2879,24 +2879,24 @@ ir.cpp: # 708| CallMin(int, int) -> int # 708| Block 0 -# 708| v0_0(void) = EnterFunction : -# 708| mu0_1(unknown) = UnmodeledDefinition : -# 708| r0_2(glval) = VariableAddress[x] : -# 708| m0_3(int) = InitializeParameter[x] : r0_2 -# 708| r0_4(glval) = VariableAddress[y] : -# 708| m0_5(int) = InitializeParameter[y] : r0_4 -# 709| r0_6(glval) = VariableAddress[#return] : -# 709| r0_7(bool) = FunctionAddress[min] : -# 709| r0_8(glval) = VariableAddress[x] : -# 709| r0_9(int) = Load : r0_8, m0_3 -# 709| r0_10(glval) = VariableAddress[y] : -# 709| r0_11(int) = Load : r0_10, m0_5 -# 709| r0_12(int) = Invoke : r0_7, r0_9, r0_11 -# 709| m0_13(int) = Store : r0_6, r0_12 -# 708| r0_14(glval) = VariableAddress[#return] : -# 708| v0_15(void) = ReturnValue : r0_14, m0_13 -# 708| v0_16(void) = UnmodeledUse : mu* -# 708| v0_17(void) = ExitFunction : +# 708| v0_0(void) = EnterFunction : +# 708| mu0_1(unknown) = UnmodeledDefinition : +# 708| r0_2(glval) = VariableAddress[x] : +# 708| m0_3(int) = InitializeParameter[x] : r0_2 +# 708| r0_4(glval) = VariableAddress[y] : +# 708| m0_5(int) = InitializeParameter[y] : r0_4 +# 709| r0_6(glval) = VariableAddress[#return] : +# 709| r0_7(glval) = FunctionAddress[min] : +# 709| r0_8(glval) = VariableAddress[x] : +# 709| r0_9(int) = Load : r0_8, m0_3 +# 709| r0_10(glval) = VariableAddress[y] : +# 709| r0_11(int) = Load : r0_10, m0_5 +# 709| r0_12(int) = Invoke : r0_7, r0_9, r0_11 +# 709| m0_13(int) = Store : r0_6, r0_12 +# 708| r0_14(glval) = VariableAddress[#return] : +# 708| v0_15(void) = ReturnValue : r0_14, m0_13 +# 708| v0_16(void) = UnmodeledUse : mu* +# 708| v0_17(void) = ExitFunction : # 715| Outer::Func(void *, char) -> long # 715| Block 0 @@ -2916,19 +2916,19 @@ ir.cpp: # 720| CallNestedTemplateFunc() -> double # 720| Block 0 -# 720| v0_0(void) = EnterFunction : -# 720| mu0_1(unknown) = UnmodeledDefinition : -# 721| r0_2(glval) = VariableAddress[#return] : -# 721| r0_3(bool) = FunctionAddress[Func] : -# 721| r0_4(void *) = Constant[0] : -# 721| r0_5(char) = Constant[111] : -# 721| r0_6(long) = Invoke : r0_3, r0_4, r0_5 -# 721| r0_7(double) = Convert : r0_6 -# 721| m0_8(double) = Store : r0_2, r0_7 -# 720| r0_9(glval) = VariableAddress[#return] : -# 720| v0_10(void) = ReturnValue : r0_9, m0_8 -# 720| v0_11(void) = UnmodeledUse : mu* -# 720| v0_12(void) = ExitFunction : +# 720| v0_0(void) = EnterFunction : +# 720| mu0_1(unknown) = UnmodeledDefinition : +# 721| r0_2(glval) = VariableAddress[#return] : +# 721| r0_3(glval) = FunctionAddress[Func] : +# 721| r0_4(void *) = Constant[0] : +# 721| r0_5(char) = Constant[111] : +# 721| r0_6(long) = Invoke : r0_3, r0_4, r0_5 +# 721| r0_7(double) = Convert : r0_6 +# 721| m0_8(double) = Store : r0_2, r0_7 +# 720| r0_9(glval) = VariableAddress[#return] : +# 720| v0_10(void) = ReturnValue : r0_9, m0_8 +# 720| v0_11(void) = UnmodeledUse : mu* +# 720| v0_12(void) = ExitFunction : # 724| TryCatch(bool) -> void # 724| Block 0 @@ -2989,7 +2989,7 @@ ir.cpp: # 731| Block 7 # 731| r7_0(glval) = VariableAddress[#throw731:19] : -# 731| r7_1(bool) = FunctionAddress[String] : +# 731| r7_1(glval) = FunctionAddress[String] : # 731| r7_2(glval) = StringConstant["String object"] : # 731| r7_3(char *) = Convert : r7_2 # 731| v7_4(void) = Invoke : r7_1, this:r7_0, r7_3 @@ -3008,14 +3008,14 @@ ir.cpp: #-----| Goto -> Block 10 # 735| Block 10 -# 735| r10_0(glval) = VariableAddress[s] : -# 735| m10_1(char *) = InitializeParameter[s] : r10_0 -# 736| r10_2(glval) = VariableAddress[#throw736:5] : -# 736| r10_3(bool) = FunctionAddress[String] : -# 736| r10_4(glval) = VariableAddress[s] : -# 736| r10_5(char *) = Load : r10_4, m10_1 -# 736| v10_6(void) = Invoke : r10_3, this:r10_2, r10_5 -# 736| v10_7(void) = ThrowValue : r10_2, mu0_1 +# 735| r10_0(glval) = VariableAddress[s] : +# 735| m10_1(char *) = InitializeParameter[s] : r10_0 +# 736| r10_2(glval) = VariableAddress[#throw736:5] : +# 736| r10_3(glval) = FunctionAddress[String] : +# 736| r10_4(glval) = VariableAddress[s] : +# 736| r10_5(char *) = Load : r10_4, m10_1 +# 736| v10_6(void) = Invoke : r10_3, this:r10_2, r10_5 +# 736| v10_7(void) = ThrowValue : r10_2, mu0_1 #-----| Exception -> Block 2 # 738| Block 11 @@ -3041,18 +3041,18 @@ ir.cpp: # 745| Base::Base(const Base &) -> void # 745| Block 0 -# 745| v0_0(void) = EnterFunction : -# 745| mu0_1(unknown) = UnmodeledDefinition : -# 745| r0_2(glval) = InitializeThis : -#-----| r0_3(glval) = VariableAddress[p#0] : -#-----| m0_4(Base &) = InitializeParameter[p#0] : r0_3 -# 745| r0_5(glval) = FieldAddress[base_s] : r0_2 -# 745| r0_6(bool) = FunctionAddress[String] : -# 745| v0_7(void) = Invoke : r0_6, this:r0_5 -# 745| v0_8(void) = NoOp : -# 745| v0_9(void) = ReturnVoid : -# 745| v0_10(void) = UnmodeledUse : mu* -# 745| v0_11(void) = ExitFunction : +# 745| v0_0(void) = EnterFunction : +# 745| mu0_1(unknown) = UnmodeledDefinition : +# 745| r0_2(glval) = InitializeThis : +#-----| r0_3(glval) = VariableAddress[p#0] : +#-----| m0_4(Base &) = InitializeParameter[p#0] : r0_3 +# 745| r0_5(glval) = FieldAddress[base_s] : r0_2 +# 745| r0_6(glval) = FunctionAddress[String] : +# 745| v0_7(void) = Invoke : r0_6, this:r0_5 +# 745| v0_8(void) = NoOp : +# 745| v0_9(void) = ReturnVoid : +# 745| v0_10(void) = UnmodeledUse : mu* +# 745| v0_11(void) = ExitFunction : # 745| Base::operator=(const Base &) -> Base & # 745| Block 0 @@ -3063,7 +3063,7 @@ ir.cpp: #-----| m0_4(Base &) = InitializeParameter[p#0] : r0_3 #-----| r0_5(Base *) = CopyValue : r0_2 #-----| r0_6(glval) = FieldAddress[base_s] : r0_5 -# 745| r0_7(bool) = FunctionAddress[operator=] : +# 745| r0_7(glval) = FunctionAddress[operator=] : #-----| r0_8(glval) = VariableAddress[p#0] : #-----| r0_9(Base &) = Load : r0_8, m0_4 #-----| r0_10(glval) = FieldAddress[base_s] : r0_9 @@ -3078,29 +3078,29 @@ ir.cpp: # 748| Base::Base() -> void # 748| Block 0 -# 748| v0_0(void) = EnterFunction : -# 748| mu0_1(unknown) = UnmodeledDefinition : -# 748| r0_2(glval) = InitializeThis : -# 748| r0_3(glval) = FieldAddress[base_s] : r0_2 -# 748| r0_4(bool) = FunctionAddress[String] : -# 748| v0_5(void) = Invoke : r0_4, this:r0_3 -# 749| v0_6(void) = NoOp : -# 748| v0_7(void) = ReturnVoid : -# 748| v0_8(void) = UnmodeledUse : mu* -# 748| v0_9(void) = ExitFunction : +# 748| v0_0(void) = EnterFunction : +# 748| mu0_1(unknown) = UnmodeledDefinition : +# 748| r0_2(glval) = InitializeThis : +# 748| r0_3(glval) = FieldAddress[base_s] : r0_2 +# 748| r0_4(glval) = FunctionAddress[String] : +# 748| v0_5(void) = Invoke : r0_4, this:r0_3 +# 749| v0_6(void) = NoOp : +# 748| v0_7(void) = ReturnVoid : +# 748| v0_8(void) = UnmodeledUse : mu* +# 748| v0_9(void) = ExitFunction : # 750| Base::~Base() -> void # 750| Block 0 -# 750| v0_0(void) = EnterFunction : -# 750| mu0_1(unknown) = UnmodeledDefinition : -# 750| r0_2(glval) = InitializeThis : -# 751| v0_3(void) = NoOp : -# 751| r0_4(glval) = FieldAddress[base_s] : r0_2 -# 751| r0_5(bool) = FunctionAddress[~String] : -# 751| v0_6(void) = Invoke : r0_5, this:r0_4 -# 750| v0_7(void) = ReturnVoid : -# 750| v0_8(void) = UnmodeledUse : mu* -# 750| v0_9(void) = ExitFunction : +# 750| v0_0(void) = EnterFunction : +# 750| mu0_1(unknown) = UnmodeledDefinition : +# 750| r0_2(glval) = InitializeThis : +# 751| v0_3(void) = NoOp : +# 751| r0_4(glval) = FieldAddress[base_s] : r0_2 +# 751| r0_5(glval) = FunctionAddress[~String] : +# 751| v0_6(void) = Invoke : r0_5, this:r0_4 +# 750| v0_7(void) = ReturnVoid : +# 750| v0_8(void) = UnmodeledUse : mu* +# 750| v0_9(void) = ExitFunction : # 754| Middle::operator=(const Middle &) -> Middle & # 754| Block 0 @@ -3111,14 +3111,14 @@ ir.cpp: #-----| m0_4(Middle &) = InitializeParameter[p#0] : r0_3 #-----| r0_5(Middle *) = CopyValue : r0_2 #-----| r0_6(Base *) = ConvertToBase[Middle : Base] : r0_5 -# 754| r0_7(bool) = FunctionAddress[operator=] : +# 754| r0_7(glval) = FunctionAddress[operator=] : #-----| r0_8(glval) = VariableAddress[p#0] : #-----| r0_9(Middle &) = Load : r0_8, m0_4 #-----| r0_10(Base *) = ConvertToBase[Middle : Base] : r0_9 # 754| r0_11(Base &) = Invoke : r0_7, this:r0_6, r0_10 #-----| r0_12(Middle *) = CopyValue : r0_2 #-----| r0_13(glval) = FieldAddress[middle_s] : r0_12 -# 754| r0_14(bool) = FunctionAddress[operator=] : +# 754| r0_14(glval) = FunctionAddress[operator=] : #-----| r0_15(glval) = VariableAddress[p#0] : #-----| r0_16(Middle &) = Load : r0_15, m0_4 #-----| r0_17(glval) = FieldAddress[middle_s] : r0_16 @@ -3133,35 +3133,35 @@ ir.cpp: # 757| Middle::Middle() -> void # 757| Block 0 -# 757| v0_0(void) = EnterFunction : -# 757| mu0_1(unknown) = UnmodeledDefinition : -# 757| r0_2(glval) = InitializeThis : -# 757| r0_3(glval) = ConvertToBase[Middle : Base] : r0_2 -# 757| r0_4(bool) = FunctionAddress[Base] : -# 757| v0_5(void) = Invoke : r0_4, this:r0_3 -# 757| r0_6(glval) = FieldAddress[middle_s] : r0_2 -# 757| r0_7(bool) = FunctionAddress[String] : -# 757| v0_8(void) = Invoke : r0_7, this:r0_6 -# 758| v0_9(void) = NoOp : -# 757| v0_10(void) = ReturnVoid : -# 757| v0_11(void) = UnmodeledUse : mu* -# 757| v0_12(void) = ExitFunction : +# 757| v0_0(void) = EnterFunction : +# 757| mu0_1(unknown) = UnmodeledDefinition : +# 757| r0_2(glval) = InitializeThis : +# 757| r0_3(glval) = ConvertToBase[Middle : Base] : r0_2 +# 757| r0_4(glval) = FunctionAddress[Base] : +# 757| v0_5(void) = Invoke : r0_4, this:r0_3 +# 757| r0_6(glval) = FieldAddress[middle_s] : r0_2 +# 757| r0_7(glval) = FunctionAddress[String] : +# 757| v0_8(void) = Invoke : r0_7, this:r0_6 +# 758| v0_9(void) = NoOp : +# 757| v0_10(void) = ReturnVoid : +# 757| v0_11(void) = UnmodeledUse : mu* +# 757| v0_12(void) = ExitFunction : # 759| Middle::~Middle() -> void # 759| Block 0 -# 759| v0_0(void) = EnterFunction : -# 759| mu0_1(unknown) = UnmodeledDefinition : -# 759| r0_2(glval) = InitializeThis : -# 760| v0_3(void) = NoOp : -# 760| r0_4(glval) = FieldAddress[middle_s] : r0_2 -# 760| r0_5(bool) = FunctionAddress[~String] : -# 760| v0_6(void) = Invoke : r0_5, this:r0_4 -# 760| r0_7(glval) = ConvertToBase[Middle : Base] : r0_2 -# 760| r0_8(bool) = FunctionAddress[~Base] : -# 760| v0_9(void) = Invoke : r0_8, this:r0_7 -# 759| v0_10(void) = ReturnVoid : -# 759| v0_11(void) = UnmodeledUse : mu* -# 759| v0_12(void) = ExitFunction : +# 759| v0_0(void) = EnterFunction : +# 759| mu0_1(unknown) = UnmodeledDefinition : +# 759| r0_2(glval) = InitializeThis : +# 760| v0_3(void) = NoOp : +# 760| r0_4(glval) = FieldAddress[middle_s] : r0_2 +# 760| r0_5(glval) = FunctionAddress[~String] : +# 760| v0_6(void) = Invoke : r0_5, this:r0_4 +# 760| r0_7(glval) = ConvertToBase[Middle : Base] : r0_2 +# 760| r0_8(glval) = FunctionAddress[~Base] : +# 760| v0_9(void) = Invoke : r0_8, this:r0_7 +# 759| v0_10(void) = ReturnVoid : +# 759| v0_11(void) = UnmodeledUse : mu* +# 759| v0_12(void) = ExitFunction : # 763| Derived::operator=(const Derived &) -> Derived & # 763| Block 0 @@ -3172,14 +3172,14 @@ ir.cpp: #-----| m0_4(Derived &) = InitializeParameter[p#0] : r0_3 #-----| r0_5(Derived *) = CopyValue : r0_2 #-----| r0_6(Middle *) = ConvertToBase[Derived : Middle] : r0_5 -# 763| r0_7(bool) = FunctionAddress[operator=] : +# 763| r0_7(glval) = FunctionAddress[operator=] : #-----| r0_8(glval) = VariableAddress[p#0] : #-----| r0_9(Derived &) = Load : r0_8, m0_4 #-----| r0_10(Middle *) = ConvertToBase[Derived : Middle] : r0_9 # 763| r0_11(Middle &) = Invoke : r0_7, this:r0_6, r0_10 #-----| r0_12(Derived *) = CopyValue : r0_2 #-----| r0_13(glval) = FieldAddress[derived_s] : r0_12 -# 763| r0_14(bool) = FunctionAddress[operator=] : +# 763| r0_14(glval) = FunctionAddress[operator=] : #-----| r0_15(glval) = VariableAddress[p#0] : #-----| r0_16(Derived &) = Load : r0_15, m0_4 #-----| r0_17(glval) = FieldAddress[derived_s] : r0_16 @@ -3198,10 +3198,10 @@ ir.cpp: # 766| mu0_1(unknown) = UnmodeledDefinition : # 766| r0_2(glval) = InitializeThis : # 766| r0_3(glval) = ConvertToBase[Derived : Middle] : r0_2 -# 766| r0_4(bool) = FunctionAddress[Middle] : +# 766| r0_4(glval) = FunctionAddress[Middle] : # 766| v0_5(void) = Invoke : r0_4, this:r0_3 # 766| r0_6(glval) = FieldAddress[derived_s] : r0_2 -# 766| r0_7(bool) = FunctionAddress[String] : +# 766| r0_7(glval) = FunctionAddress[String] : # 766| v0_8(void) = Invoke : r0_7, this:r0_6 # 767| v0_9(void) = NoOp : # 766| v0_10(void) = ReturnVoid : @@ -3215,10 +3215,10 @@ ir.cpp: # 768| r0_2(glval) = InitializeThis : # 769| v0_3(void) = NoOp : # 769| r0_4(glval) = FieldAddress[derived_s] : r0_2 -# 769| r0_5(bool) = FunctionAddress[~String] : +# 769| r0_5(glval) = FunctionAddress[~String] : # 769| v0_6(void) = Invoke : r0_5, this:r0_4 # 769| r0_7(glval) = ConvertToBase[Derived : Middle] : r0_2 -# 769| r0_8(bool) = FunctionAddress[~Middle] : +# 769| r0_8(glval) = FunctionAddress[~Middle] : # 769| v0_9(void) = Invoke : r0_8, this:r0_7 # 768| v0_10(void) = ReturnVoid : # 768| v0_11(void) = UnmodeledUse : mu* @@ -3230,10 +3230,10 @@ ir.cpp: # 775| mu0_1(unknown) = UnmodeledDefinition : # 775| r0_2(glval) = InitializeThis : # 775| r0_3(glval) = ConvertToBase[MiddleVB1 : Base] : r0_2 -# 775| r0_4(bool) = FunctionAddress[Base] : +# 775| r0_4(glval) = FunctionAddress[Base] : # 775| v0_5(void) = Invoke : r0_4, this:r0_3 # 775| r0_6(glval) = FieldAddress[middlevb1_s] : r0_2 -# 775| r0_7(bool) = FunctionAddress[String] : +# 775| r0_7(glval) = FunctionAddress[String] : # 775| v0_8(void) = Invoke : r0_7, this:r0_6 # 776| v0_9(void) = NoOp : # 775| v0_10(void) = ReturnVoid : @@ -3247,10 +3247,10 @@ ir.cpp: # 777| r0_2(glval) = InitializeThis : # 778| v0_3(void) = NoOp : # 778| r0_4(glval) = FieldAddress[middlevb1_s] : r0_2 -# 778| r0_5(bool) = FunctionAddress[~String] : +# 778| r0_5(glval) = FunctionAddress[~String] : # 778| v0_6(void) = Invoke : r0_5, this:r0_4 # 778| r0_7(glval) = ConvertToBase[MiddleVB1 : Base] : r0_2 -# 778| r0_8(bool) = FunctionAddress[~Base] : +# 778| r0_8(glval) = FunctionAddress[~Base] : # 778| v0_9(void) = Invoke : r0_8, this:r0_7 # 777| v0_10(void) = ReturnVoid : # 777| v0_11(void) = UnmodeledUse : mu* @@ -3262,10 +3262,10 @@ ir.cpp: # 784| mu0_1(unknown) = UnmodeledDefinition : # 784| r0_2(glval) = InitializeThis : # 784| r0_3(glval) = ConvertToBase[MiddleVB2 : Base] : r0_2 -# 784| r0_4(bool) = FunctionAddress[Base] : +# 784| r0_4(glval) = FunctionAddress[Base] : # 784| v0_5(void) = Invoke : r0_4, this:r0_3 # 784| r0_6(glval) = FieldAddress[middlevb2_s] : r0_2 -# 784| r0_7(bool) = FunctionAddress[String] : +# 784| r0_7(glval) = FunctionAddress[String] : # 784| v0_8(void) = Invoke : r0_7, this:r0_6 # 785| v0_9(void) = NoOp : # 784| v0_10(void) = ReturnVoid : @@ -3279,10 +3279,10 @@ ir.cpp: # 786| r0_2(glval) = InitializeThis : # 787| v0_3(void) = NoOp : # 787| r0_4(glval) = FieldAddress[middlevb2_s] : r0_2 -# 787| r0_5(bool) = FunctionAddress[~String] : +# 787| r0_5(glval) = FunctionAddress[~String] : # 787| v0_6(void) = Invoke : r0_5, this:r0_4 # 787| r0_7(glval) = ConvertToBase[MiddleVB2 : Base] : r0_2 -# 787| r0_8(bool) = FunctionAddress[~Base] : +# 787| r0_8(glval) = FunctionAddress[~Base] : # 787| v0_9(void) = Invoke : r0_8, this:r0_7 # 786| v0_10(void) = ReturnVoid : # 786| v0_11(void) = UnmodeledUse : mu* @@ -3294,16 +3294,16 @@ ir.cpp: # 793| mu0_1(unknown) = UnmodeledDefinition : # 793| r0_2(glval) = InitializeThis : # 793| r0_3(glval) = ConvertToBase[DerivedVB : Base] : r0_2 -# 793| r0_4(bool) = FunctionAddress[Base] : +# 793| r0_4(glval) = FunctionAddress[Base] : # 793| v0_5(void) = Invoke : r0_4, this:r0_3 # 793| r0_6(glval) = ConvertToBase[DerivedVB : MiddleVB1] : r0_2 -# 793| r0_7(bool) = FunctionAddress[MiddleVB1] : +# 793| r0_7(glval) = FunctionAddress[MiddleVB1] : # 793| v0_8(void) = Invoke : r0_7, this:r0_6 # 793| r0_9(glval) = ConvertToBase[DerivedVB : MiddleVB2] : r0_2 -# 793| r0_10(bool) = FunctionAddress[MiddleVB2] : +# 793| r0_10(glval) = FunctionAddress[MiddleVB2] : # 793| v0_11(void) = Invoke : r0_10, this:r0_9 # 793| r0_12(glval) = FieldAddress[derivedvb_s] : r0_2 -# 793| r0_13(bool) = FunctionAddress[String] : +# 793| r0_13(glval) = FunctionAddress[String] : # 793| v0_14(void) = Invoke : r0_13, this:r0_12 # 794| v0_15(void) = NoOp : # 793| v0_16(void) = ReturnVoid : @@ -3317,16 +3317,16 @@ ir.cpp: # 795| r0_2(glval) = InitializeThis : # 796| v0_3(void) = NoOp : # 796| r0_4(glval) = FieldAddress[derivedvb_s] : r0_2 -# 796| r0_5(bool) = FunctionAddress[~String] : +# 796| r0_5(glval) = FunctionAddress[~String] : # 796| v0_6(void) = Invoke : r0_5, this:r0_4 # 796| r0_7(glval) = ConvertToBase[DerivedVB : MiddleVB2] : r0_2 -# 796| r0_8(bool) = FunctionAddress[~MiddleVB2] : +# 796| r0_8(glval) = FunctionAddress[~MiddleVB2] : # 796| v0_9(void) = Invoke : r0_8, this:r0_7 # 796| r0_10(glval) = ConvertToBase[DerivedVB : MiddleVB1] : r0_2 -# 796| r0_11(bool) = FunctionAddress[~MiddleVB1] : +# 796| r0_11(glval) = FunctionAddress[~MiddleVB1] : # 796| v0_12(void) = Invoke : r0_11, this:r0_10 # 796| r0_13(glval) = ConvertToBase[DerivedVB : Base] : r0_2 -# 796| r0_14(bool) = FunctionAddress[~Base] : +# 796| r0_14(glval) = FunctionAddress[~Base] : # 796| v0_15(void) = Invoke : r0_14, this:r0_13 # 795| v0_16(void) = ReturnVoid : # 795| v0_17(void) = UnmodeledUse : mu* @@ -3337,13 +3337,13 @@ ir.cpp: # 799| v0_0(void) = EnterFunction : # 799| mu0_1(unknown) = UnmodeledDefinition : # 800| r0_2(glval) = VariableAddress[b] : -# 800| r0_3(bool) = FunctionAddress[Base] : +# 800| r0_3(glval) = FunctionAddress[Base] : # 800| v0_4(void) = Invoke : r0_3, this:r0_2 # 801| r0_5(glval) = VariableAddress[m] : -# 801| r0_6(bool) = FunctionAddress[Middle] : +# 801| r0_6(glval) = FunctionAddress[Middle] : # 801| v0_7(void) = Invoke : r0_6, this:r0_5 # 802| r0_8(glval) = VariableAddress[d] : -# 802| r0_9(bool) = FunctionAddress[Derived] : +# 802| r0_9(glval) = FunctionAddress[Derived] : # 802| v0_10(void) = Invoke : r0_9, this:r0_8 # 804| r0_11(glval) = VariableAddress[pb] : # 804| r0_12(glval) = VariableAddress[b] : @@ -3355,21 +3355,21 @@ ir.cpp: # 806| r0_18(glval) = VariableAddress[d] : # 806| m0_19(Derived *) = Store : r0_17, r0_18 # 808| r0_20(glval) = VariableAddress[b] : -# 808| r0_21(bool) = FunctionAddress[operator=] : +# 808| r0_21(glval) = FunctionAddress[operator=] : # 808| r0_22(glval) = VariableAddress[m] : # 808| r0_23(glval) = ConvertToBase[Middle : Base] : r0_22 # 808| r0_24(Base &) = Invoke : r0_21, this:r0_20, r0_23 # 809| r0_25(glval) = VariableAddress[b] : -# 809| r0_26(bool) = FunctionAddress[operator=] : -# 809| r0_27(bool) = FunctionAddress[Base] : +# 809| r0_26(glval) = FunctionAddress[operator=] : +# 809| r0_27(glval) = FunctionAddress[Base] : # 809| r0_28(glval) = VariableAddress[m] : # 809| r0_29(glval) = ConvertToBase[Middle : Base] : r0_28 # 809| v0_30(void) = Invoke : r0_27, r0_29 # 809| r0_31(Base) = Convert : v0_30 # 809| r0_32(Base &) = Invoke : r0_26, this:r0_25, r0_31 # 810| r0_33(glval) = VariableAddress[b] : -# 810| r0_34(bool) = FunctionAddress[operator=] : -# 810| r0_35(bool) = FunctionAddress[Base] : +# 810| r0_34(glval) = FunctionAddress[operator=] : +# 810| r0_35(glval) = FunctionAddress[Base] : # 810| r0_36(glval) = VariableAddress[m] : # 810| r0_37(glval) = ConvertToBase[Middle : Base] : r0_36 # 810| v0_38(void) = Invoke : r0_35, r0_37 @@ -3396,13 +3396,13 @@ ir.cpp: # 814| r0_59(glval) = VariableAddress[pb] : # 814| m0_60(Base *) = Store : r0_59, r0_58 # 816| r0_61(glval) = VariableAddress[m] : -# 816| r0_62(bool) = FunctionAddress[operator=] : +# 816| r0_62(glval) = FunctionAddress[operator=] : # 816| r0_63(glval) = VariableAddress[b] : # 816| r0_64(glval) = ConvertToDerived[Middle : Base] : r0_63 # 816| r0_65(glval) = Convert : r0_64 # 816| r0_66(Middle &) = Invoke : r0_62, this:r0_61, r0_65 # 817| r0_67(glval) = VariableAddress[m] : -# 817| r0_68(bool) = FunctionAddress[operator=] : +# 817| r0_68(glval) = FunctionAddress[operator=] : # 817| r0_69(glval) = VariableAddress[b] : # 817| r0_70(glval) = ConvertToDerived[Middle : Base] : r0_69 # 817| r0_71(glval) = Convert : r0_70 @@ -3423,14 +3423,14 @@ ir.cpp: # 820| r0_86(glval) = VariableAddress[pm] : # 820| m0_87(Middle *) = Store : r0_86, r0_85 # 822| r0_88(glval) = VariableAddress[b] : -# 822| r0_89(bool) = FunctionAddress[operator=] : +# 822| r0_89(glval) = FunctionAddress[operator=] : # 822| r0_90(glval) = VariableAddress[d] : # 822| r0_91(glval) = ConvertToBase[Derived : Middle] : r0_90 # 822| r0_92(glval) = ConvertToBase[Middle : Base] : r0_91 # 822| r0_93(Base &) = Invoke : r0_89, this:r0_88, r0_92 # 823| r0_94(glval) = VariableAddress[b] : -# 823| r0_95(bool) = FunctionAddress[operator=] : -# 823| r0_96(bool) = FunctionAddress[Base] : +# 823| r0_95(glval) = FunctionAddress[operator=] : +# 823| r0_96(glval) = FunctionAddress[Base] : # 823| r0_97(glval) = VariableAddress[d] : # 823| r0_98(glval) = ConvertToBase[Derived : Middle] : r0_97 # 823| r0_99(glval) = ConvertToBase[Middle : Base] : r0_98 @@ -3438,8 +3438,8 @@ ir.cpp: # 823| r0_101(Base) = Convert : v0_100 # 823| r0_102(Base &) = Invoke : r0_95, this:r0_94, r0_101 # 824| r0_103(glval) = VariableAddress[b] : -# 824| r0_104(bool) = FunctionAddress[operator=] : -# 824| r0_105(bool) = FunctionAddress[Base] : +# 824| r0_104(glval) = FunctionAddress[operator=] : +# 824| r0_105(glval) = FunctionAddress[Base] : # 824| r0_106(glval) = VariableAddress[d] : # 824| r0_107(glval) = ConvertToBase[Derived : Middle] : r0_106 # 824| r0_108(glval) = ConvertToBase[Middle : Base] : r0_107 @@ -3470,14 +3470,14 @@ ir.cpp: # 828| r0_133(glval) = VariableAddress[pb] : # 828| m0_134(Base *) = Store : r0_133, r0_132 # 830| r0_135(glval) = VariableAddress[d] : -# 830| r0_136(bool) = FunctionAddress[operator=] : +# 830| r0_136(glval) = FunctionAddress[operator=] : # 830| r0_137(glval) = VariableAddress[b] : # 830| r0_138(glval) = ConvertToDerived[Middle : Base] : r0_137 # 830| r0_139(glval) = ConvertToDerived[Derived : Middle] : r0_138 # 830| r0_140(glval) = Convert : r0_139 # 830| r0_141(Derived &) = Invoke : r0_136, this:r0_135, r0_140 # 831| r0_142(glval) = VariableAddress[d] : -# 831| r0_143(bool) = FunctionAddress[operator=] : +# 831| r0_143(glval) = FunctionAddress[operator=] : # 831| r0_144(glval) = VariableAddress[b] : # 831| r0_145(glval) = ConvertToDerived[Middle : Base] : r0_144 # 831| r0_146(glval) = ConvertToDerived[Derived : Middle] : r0_145 @@ -3537,7 +3537,7 @@ ir.cpp: # 846| mu0_1(unknown) = UnmodeledDefinition : # 846| r0_2(glval) = InitializeThis : # 846| r0_3(glval) = ConvertToBase[PolymorphicDerived : PolymorphicBase] : r0_2 -# 846| r0_4(bool) = FunctionAddress[PolymorphicBase] : +# 846| r0_4(glval) = FunctionAddress[PolymorphicBase] : # 846| v0_5(void) = Invoke : r0_4, this:r0_3 # 846| v0_6(void) = NoOp : # 846| v0_7(void) = ReturnVoid : @@ -3551,7 +3551,7 @@ ir.cpp: # 846| r0_2(glval) = InitializeThis : #-----| v0_3(void) = NoOp : # 846| r0_4(glval) = ConvertToBase[PolymorphicDerived : PolymorphicBase] : r0_2 -# 846| r0_5(bool) = FunctionAddress[~PolymorphicBase] : +# 846| r0_5(glval) = FunctionAddress[~PolymorphicBase] : # 846| v0_6(void) = Invoke : r0_5, this:r0_4 # 846| v0_7(void) = ReturnVoid : # 846| v0_8(void) = UnmodeledUse : mu* @@ -3562,10 +3562,10 @@ ir.cpp: # 849| v0_0(void) = EnterFunction : # 849| mu0_1(unknown) = UnmodeledDefinition : # 850| r0_2(glval) = VariableAddress[b] : -#-----| r0_3(bool) = FunctionAddress[PolymorphicBase] : +#-----| r0_3(glval) = FunctionAddress[PolymorphicBase] : #-----| v0_4(void) = Invoke : r0_3, this:r0_2 # 851| r0_5(glval) = VariableAddress[d] : -# 851| r0_6(bool) = FunctionAddress[PolymorphicDerived] : +# 851| r0_6(glval) = FunctionAddress[PolymorphicDerived] : # 851| v0_7(void) = Invoke : r0_6, this:r0_5 # 853| r0_8(glval) = VariableAddress[pb] : # 853| r0_9(glval) = VariableAddress[b] : @@ -3611,7 +3611,7 @@ ir.cpp: # 867| v0_0(void) = EnterFunction : # 867| mu0_1(unknown) = UnmodeledDefinition : # 867| r0_2(glval) = InitializeThis : -# 868| r0_3(bool) = FunctionAddress[String] : +# 868| r0_3(glval) = FunctionAddress[String] : # 868| r0_4(glval) = StringConstant[""] : # 868| r0_5(char *) = Convert : r0_4 # 868| v0_6(void) = Invoke : r0_3, this:r0_2, r0_5 @@ -3783,3 +3783,126 @@ ir.cpp: # 906| r3_2(glval) = VariableAddress[#temp906:11] : # 906| m3_3(int) = Store : r3_2, r3_1 #-----| Goto -> Block 1 + +# 940| OperatorNew() -> void +# 940| Block 0 +# 940| v0_0(void) = EnterFunction : +# 940| mu0_1(unknown) = UnmodeledDefinition : +# 941| r0_2(glval) = FunctionAddress[operator new] : +# 941| r0_3(unsigned long) = Constant[4] : +# 941| r0_4(void *) = Invoke : r0_2, r0_3 +# 941| r0_5(int *) = Convert : r0_4 +# 942| r0_6(glval) = FunctionAddress[operator new] : +# 942| r0_7(unsigned long) = Constant[4] : +# 942| r0_8(float) = Constant[1.0] : +# 942| r0_9(void *) = Invoke : r0_6, r0_7, r0_8 +# 942| r0_10(int *) = Convert : r0_9 +# 943| r0_11(glval) = FunctionAddress[operator new] : +# 943| r0_12(unsigned long) = Constant[4] : +# 943| r0_13(void *) = Invoke : r0_11, r0_12 +# 943| r0_14(int *) = Convert : r0_13 +# 943| r0_15(int) = Constant[0] : +# 943| mu0_16(int) = Store : r0_14, r0_15 +# 944| r0_17(glval) = FunctionAddress[operator new] : +# 944| r0_18(unsigned long) = Constant[8] : +# 944| r0_19(void *) = Invoke : r0_17, r0_18 +# 944| r0_20(String *) = Convert : r0_19 +# 944| r0_21(glval) = FunctionAddress[String] : +# 944| v0_22(void) = Invoke : r0_21, this:r0_20 +# 945| r0_23(glval) = FunctionAddress[operator new] : +# 945| r0_24(unsigned long) = Constant[8] : +# 945| r0_25(float) = Constant[1.0] : +# 945| r0_26(void *) = Invoke : r0_23, r0_24, r0_25 +# 945| r0_27(String *) = Convert : r0_26 +# 945| r0_28(glval) = FunctionAddress[String] : +# 945| r0_29(glval) = StringConstant["hello"] : +# 945| r0_30(char *) = Convert : r0_29 +# 945| v0_31(void) = Invoke : r0_28, this:r0_27, r0_30 +# 946| r0_32(glval) = FunctionAddress[operator new] : +# 946| r0_33(unsigned long) = Constant[256] : +# 946| r0_34(align_val_t) = Constant[128] : +# 946| r0_35(void *) = Invoke : r0_32, r0_33, r0_34 +# 946| r0_36(Overaligned *) = Convert : r0_35 +# 947| r0_37(glval) = FunctionAddress[operator new] : +# 947| r0_38(unsigned long) = Constant[256] : +# 947| r0_39(align_val_t) = Constant[128] : +# 947| r0_40(float) = Constant[1.0] : +# 947| r0_41(void *) = Invoke : r0_37, r0_38, r0_39, r0_40 +# 947| r0_42(Overaligned *) = Convert : r0_41 +# 947| r0_43(Overaligned) = Constant[0] : +# 947| mu0_44(Overaligned) = Store : r0_42, r0_43 +# 948| v0_45(void) = NoOp : +# 940| v0_46(void) = ReturnVoid : +# 940| v0_47(void) = UnmodeledUse : mu* +# 940| v0_48(void) = ExitFunction : + +# 950| OperatorNewArray(int) -> void +# 950| Block 0 +# 950| v0_0(void) = EnterFunction : +# 950| mu0_1(unknown) = UnmodeledDefinition : +# 950| r0_2(glval) = VariableAddress[n] : +# 950| m0_3(int) = InitializeParameter[n] : r0_2 +# 951| r0_4(glval) = FunctionAddress[operator new[]] : +# 951| r0_5(unsigned long) = Constant[40] : +# 951| r0_6(void *) = Invoke : r0_4, r0_5 +# 951| r0_7(int *) = Convert : r0_6 +# 952| r0_8(glval) = FunctionAddress[operator new[]] : +# 952| r0_9(glval) = VariableAddress[n] : +# 952| r0_10(int) = Load : r0_9, m0_3 +# 952| r0_11(unsigned long) = Convert : r0_10 +# 952| r0_12(unsigned long) = Constant[4] : +# 952| r0_13(unsigned long) = Mul : r0_11, r0_12 +# 952| r0_14(void *) = Invoke : r0_8, r0_13 +# 952| r0_15(int *) = Convert : r0_14 +# 953| r0_16(glval) = FunctionAddress[operator new[]] : +# 953| r0_17(glval) = VariableAddress[n] : +# 953| r0_18(int) = Load : r0_17, m0_3 +# 953| r0_19(unsigned long) = Convert : r0_18 +# 953| r0_20(unsigned long) = Constant[4] : +# 953| r0_21(unsigned long) = Mul : r0_19, r0_20 +# 953| r0_22(float) = Constant[1.0] : +# 953| r0_23(void *) = Invoke : r0_16, r0_21, r0_22 +# 953| r0_24(int *) = Convert : r0_23 +# 954| r0_25(glval) = FunctionAddress[operator new[]] : +# 954| r0_26(glval) = VariableAddress[n] : +# 954| r0_27(int) = Load : r0_26, m0_3 +# 954| r0_28(unsigned long) = Convert : r0_27 +# 954| r0_29(unsigned long) = Constant[8] : +# 954| r0_30(unsigned long) = Mul : r0_28, r0_29 +# 954| r0_31(void *) = Invoke : r0_25, r0_30 +# 954| r0_32(String *) = Convert : r0_31 +# 955| r0_33(glval) = FunctionAddress[operator new[]] : +# 955| r0_34(glval) = VariableAddress[n] : +# 955| r0_35(int) = Load : r0_34, m0_3 +# 955| r0_36(unsigned long) = Convert : r0_35 +# 955| r0_37(unsigned long) = Constant[256] : +# 955| r0_38(unsigned long) = Mul : r0_36, r0_37 +# 955| r0_39(align_val_t) = Constant[128] : +# 955| r0_40(void *) = Invoke : r0_33, r0_38, r0_39 +# 955| r0_41(Overaligned *) = Convert : r0_40 +# 956| r0_42(glval) = FunctionAddress[operator new[]] : +# 956| r0_43(unsigned long) = Constant[2560] : +# 956| r0_44(align_val_t) = Constant[128] : +# 956| r0_45(float) = Constant[1.0] : +# 956| r0_46(void *) = Invoke : r0_42, r0_43, r0_44, r0_45 +# 956| r0_47(Overaligned *) = Convert : r0_46 +# 957| r0_48(glval) = FunctionAddress[operator new[]] : +# 957| r0_49(glval) = VariableAddress[n] : +# 957| r0_50(int) = Load : r0_49, m0_3 +# 957| r0_51(unsigned long) = Convert : r0_50 +# 957| r0_52(unsigned long) = Constant[1] : +# 957| r0_53(unsigned long) = Mul : r0_51, r0_52 +# 957| r0_54(void *) = Invoke : r0_48, r0_53 +# 957| r0_55(DefaultCtorWithDefaultParam *) = Convert : r0_54 +# 958| r0_56(glval) = FunctionAddress[operator new[]] : +# 958| r0_57(glval) = VariableAddress[n] : +# 958| r0_58(int) = Load : r0_57, m0_3 +# 958| r0_59(unsigned long) = Convert : r0_58 +# 958| r0_60(unsigned long) = Constant[4] : +# 958| r0_61(unsigned long) = Mul : r0_59, r0_60 +# 958| r0_62(void *) = Invoke : r0_56, r0_61 +# 958| r0_63(int *) = Convert : r0_62 +# 959| v0_64(void) = NoOp : +# 950| v0_65(void) = ReturnVoid : +# 950| v0_66(void) = UnmodeledUse : mu* +# 950| v0_67(void) = ExitFunction :