From 07c08f83a62de43819cfffc96d703f64a38dbac5 Mon Sep 17 00:00:00 2001 From: Dave Bartolomeo Date: Wed, 8 Aug 2018 16:18:30 -0700 Subject: [PATCH 1/4] Create common base class for `NewExpr` and `NewArrayExpr` --- cpp/ql/src/semmle/code/cpp/exprs/Expr.qll | 112 +++++++++------------- 1 file changed, 44 insertions(+), 68 deletions(-) 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. * From b9a8293610004da4f5285be4abe7c3d716a2cfca Mon Sep 17 00:00:00 2001 From: Dave Bartolomeo Date: Thu, 9 Aug 2018 10:38:33 -0700 Subject: [PATCH 2/4] C++: IR translation for `NewExpr` and `NewArrayExpr` These expressions are a little trickier than most because they include an implicit call to an allocator function. The database tells us which function to call, but we have to synthesize the allocation size and alignment arguments ourselves. The alignment argument, if it exists, is always a constant, but the size argument requires multiplication by the element count for most `NewArrayExpr`s. I introduced the new `TranslatedAllocationSize` class to handle this. --- .../code/cpp/ir/internal/InstructionTag.qll | 12 +- .../cpp/ir/internal/TranslatedElement.qll | 48 +- .../code/cpp/ir/internal/TranslatedExpr.qll | 489 ++++++++++++++++-- .../library-tests/ir/ir/PrintAST.expected | 346 +++++++++++++ .../ir/ir/aliased_ssa_ir.expected | 123 +++++ cpp/ql/test/library-tests/ir/ir/ir.cpp | 72 +++ cpp/ql/test/library-tests/ir/ir/ir.expected | 123 +++++ .../ir/ir/ssa_block_count.expected | 2 + .../test/library-tests/ir/ir/ssa_ir.expected | 123 +++++ 9 files changed, 1273 insertions(+), 65 deletions(-) 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..0ec1d2a7136c 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)) } /** @@ -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..ab40b3655042 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/internal/TranslatedExpr.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/internal/TranslatedExpr.qll @@ -16,35 +16,59 @@ TranslatedExpr getTranslatedExpr(Expr expr) { result.producesExprResult() } -abstract class TranslatedExpr extends TranslatedElement { - Expr expr; +/** + * The IR translation of an expression that was either directly present in the + * AST as an `Expr` (`TranslatedExpr`) or was synthesized from something other + * than an `Expr` . + */ +abstract class TranslatedOrSynthesizedExpr extends TranslatedElement { + /** + * Gets the instruction that produces the result of the expression. + */ + abstract Instruction getResult(); +} - override final string toString() { - result = expr.toString() - } +/** + * The IR translation of some part of an expression. This could be the + * expression itself (`TranslatedExpr`), or some other construct synthesized + * from an `Expr` (e.g. `TranslatedAllocatorCall`). + */ +abstract class TranslatedFromExpr extends TranslatedElement { + Expr expr; override final Locatable getAST() { result = expr } - final Expr getExpr() { - result = expr - } - override final Function getFunction() { result = expr.getEnclosingFunction() } + /** + * Gets the `TranslatedFunction` containing this expression. + */ final TranslatedFunction getEnclosingFunction() { result = getTranslatedFunction(expr.getEnclosingFunction()) } +} + +/** + * The IR translation of an expression. + */ +abstract class TranslatedExpr extends TranslatedOrSynthesizedExpr, + TranslatedFromExpr { + override final string toString() { + result = expr.toString() + } + + final Expr getExpr() { + result = expr + } final Type getResultType() { result = expr.getType().getUnspecifiedType() } - abstract Instruction getResult(); - /** * Holds if this `TranslatedExpr` produces the final result of the original * expression from the AST. @@ -1707,26 +1731,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 TranslatedOrSynthesizedExpr { 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 +1746,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 +1779,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 +1805,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 +1852,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 +1868,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 TranslatedOrSynthesizedExpr getArgument(int index); /** * If there are any arguments, gets the first instruction of the first @@ -1866,12 +1880,287 @@ abstract class TranslatedCall extends TranslatedNonConstantExpr { else result = getInstruction(CallTag()) } + + /** + * Holds if the call has any arguments, not counting the `this` argument. + */ + abstract predicate hasArguments(); +} + +/** + * 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. + */ +abstract class TranslatedAllocationSize extends TranslatedOrSynthesizedExpr, + TranslatedFromExpr, TTranslatedAllocationSize { + NewOrNewArrayExpr newExpr; + + TranslatedAllocationSize() { + this = TTranslatedAllocationSize(newExpr) and + expr = newExpr + } + + override final string toString() { + result = "Allocation size for " + newExpr.toString() + } + + override final Instruction getResult() { + result = getInstruction(AllocationSizeTag()) + } +} + +TranslatedAllocationSize getTranslatedAllocationSize(NewOrNewArrayExpr newExpr) { + result.getAST() = newExpr +} + +/** + * 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 TranslatedConstantAllocationSize extends TranslatedAllocationSize { + TranslatedConstantAllocationSize() { + not exists(newExpr.(NewArrayExpr).getExtent()) + } + + 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()) + } +} + +/** + * The IR translation of a call to `operator new` as part of a `new` or `new[]` + * expression. + */ +class TranslatedAllocatorCall extends TTranslatedAllocatorCall, TranslatedCall, + TranslatedFromExpr { + NewOrNewArrayExpr newExpr; + + TranslatedAllocatorCall() { + this = TTranslatedAllocatorCall(newExpr) and + expr = newExpr + } + + override final string toString() { + result = "Allocator call for " + newExpr.toString() + } + + override final Instruction getFirstCallTargetInstruction() { + result = getInstruction(CallTargetTag()) + } + + override final Instruction getCallTargetResult() { + result = getInstruction(CallTargetTag()) + } + + override predicate hasInstruction(Opcode opcode, InstructionTag tag, + 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 + ) + } + + override Instruction getInstructionSuccessor(InstructionTag tag, + EdgeKind kind) { + result = TranslatedCall.super.getInstructionSuccessor(tag, kind) or + ( + tag = CallTargetTag() and + kind instanceof GotoEdge and + result = getFirstArgumentOrCallInstruction() + ) + } + + 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 TranslatedOrSynthesizedExpr 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 TranslatedOrSynthesizedExpr getArgument(int index) { + result = getTranslatedExpr(call.getArgument(index).getFullyConverted()) + } } /** * Represents the IR translation of a call through a function pointer. */ -class TranslatedExprCall extends TranslatedCall { +class TranslatedExprCall extends TranslatedCallExpr { ExprCall exprCall; TranslatedExprCall() { @@ -1886,7 +2175,7 @@ class TranslatedExprCall extends TranslatedCall { /** * Represents the IR translation of a direct function call. */ -class TranslatedFunctionCall extends TranslatedCall { +class TranslatedFunctionCall extends TranslatedCallExpr { FunctionCall funcCall; TranslatedFunctionCall() { @@ -2498,3 +2787,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/test/library-tests/ir/ir/PrintAST.expected b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected index eefffaf9f623..88a516c1faef 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, 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 +#-----| 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 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..1793f32b64f3 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 @@ -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(bool) = 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(bool) = 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(bool) = 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(bool) = 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(bool) = FunctionAddress[String] : +# 944| v0_22(void) = Invoke : r0_21, this:r0_20 +# 945| r0_23(bool) = 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(bool) = 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(bool) = 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(bool) = 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(bool) = 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(bool) = 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(bool) = 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(bool) = 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(bool) = 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(bool) = 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(bool) = 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(bool) = 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..0ab9191784cd 100644 --- a/cpp/ql/test/library-tests/ir/ir/ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/ir.expected @@ -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(bool) = 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(bool) = 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(bool) = 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(bool) = 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(bool) = FunctionAddress[String] : +# 944| v0_22(void) = Invoke : r0_21, this:r0_20 +# 945| r0_23(bool) = 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(bool) = 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(bool) = 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(bool) = 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(bool) = 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(bool) = 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(bool) = 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(bool) = 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(bool) = 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(bool) = 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(bool) = 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(bool) = 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..f87fed120dfe 100644 --- a/cpp/ql/test/library-tests/ir/ir/ssa_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/ssa_ir.expected @@ -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(bool) = 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(bool) = 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(bool) = 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(bool) = 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(bool) = FunctionAddress[String] : +# 944| v0_22(void) = Invoke : r0_21, this:r0_20 +# 945| r0_23(bool) = 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(bool) = 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(bool) = 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(bool) = 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(bool) = 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(bool) = 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(bool) = 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(bool) = 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(bool) = 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(bool) = 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(bool) = 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(bool) = 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 : From bba7f16790dbd4f911b2fa278d4e2ece241078ce Mon Sep 17 00:00:00 2001 From: Dave Bartolomeo Date: Wed, 22 Aug 2018 17:13:03 -0700 Subject: [PATCH 3/4] C++: Simplify `TranslatedExpr` hierarchy a bit I introduced some unnecessary base classes in the `TranslatedExpr` hierarchy with a previous commit. This commit refactors the hierarchy a bit to align with the following high-level description: `TranslatedExpr` represents a translated piece of an `Expr`. Each `Expr` has exactly one `TranslatedCoreExpr`, which produces the result of that `Expr` ignoring any lvalue-to-rvalue conversion on its result. If an lvalue-to-rvalue converison is present, there is an additional `TranslatedLoad` for that `Expr` to do the conversion. For higher-level `Expr`s like `NewExpr`, there can also be additional `TranslatedExpr`s to represent the sub-operations within the overall `Expr`, such as the allocator call. --- .../cpp/ir/internal/TranslatedElement.qll | 2 +- .../code/cpp/ir/internal/TranslatedExpr.qll | 165 +++++++++++------- .../library-tests/ir/ir/PrintAST.expected | 20 +-- 3 files changed, 116 insertions(+), 71 deletions(-) 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 0ec1d2a7136c..c4639f13fb1c 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/internal/TranslatedElement.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/internal/TranslatedElement.qll @@ -164,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) 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 ab40b3655042..3570c2d9168a 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/internal/TranslatedExpr.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/internal/TranslatedExpr.qll @@ -17,24 +17,41 @@ TranslatedExpr getTranslatedExpr(Expr expr) { } /** - * The IR translation of an expression that was either directly present in the - * AST as an `Expr` (`TranslatedExpr`) or was synthesized from something other - * than an `Expr` . + * 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 TranslatedOrSynthesizedExpr extends TranslatedElement { +abstract class TranslatedExpr extends TranslatedElement { + Expr expr; + /** * Gets the instruction that produces the result of the expression. */ abstract Instruction getResult(); -} -/** - * The IR translation of some part of an expression. This could be the - * expression itself (`TranslatedExpr`), or some other construct synthesized - * from an `Expr` (e.g. `TranslatedAllocatorCall`). - */ -abstract class TranslatedFromExpr extends TranslatedElement { - Expr 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() + } override final Locatable getAST() { result = expr @@ -44,6 +61,13 @@ abstract class TranslatedFromExpr 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. */ @@ -53,34 +77,17 @@ abstract class TranslatedFromExpr extends TranslatedElement { } /** - * The IR translation of an expression. + * 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 TranslatedExpr extends TranslatedOrSynthesizedExpr, - TranslatedFromExpr { +abstract class TranslatedCoreExpr extends TranslatedExpr { override final string toString() { result = expr.toString() } - final Expr getExpr() { - result = expr - } - - final Type getResultType() { - result = expr.getType().getUnspecifiedType() - } - - /** - * 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 @@ -110,7 +117,7 @@ abstract class TranslatedExpr extends TranslatedOrSynthesizedExpr, } } -class TranslatedConditionValue extends TranslatedExpr, ConditionContext, +class TranslatedConditionValue extends TranslatedCoreExpr, ConditionContext, TTranslatedConditionValue { TranslatedConditionValue() { this = TTranslatedConditionValue(expr) @@ -286,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() } @@ -303,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, @@ -337,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 } } @@ -930,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() } @@ -1022,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, @@ -1038,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 @@ -1323,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 @@ -1735,7 +1772,7 @@ class TranslatedAssignOperation extends TranslatedAssignment { * 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 TranslatedOrSynthesizedExpr { +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 @@ -1868,7 +1905,7 @@ abstract class TranslatedCall extends TranslatedOrSynthesizedExpr { * Gets the argument with the specified `index`. Does not include the `this` * argument. */ - abstract TranslatedOrSynthesizedExpr getArgument(int index); + abstract TranslatedExpr getArgument(int index); /** * If there are any arguments, gets the first instruction of the first @@ -1894,8 +1931,8 @@ abstract class TranslatedCall extends TranslatedOrSynthesizedExpr { * 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. */ -abstract class TranslatedAllocationSize extends TranslatedOrSynthesizedExpr, - TranslatedFromExpr, TTranslatedAllocationSize { +abstract class TranslatedAllocationSize extends TranslatedExpr, + TTranslatedAllocationSize { NewOrNewArrayExpr newExpr; TranslatedAllocationSize() { @@ -1907,6 +1944,10 @@ abstract class TranslatedAllocationSize extends TranslatedOrSynthesizedExpr, result = "Allocation size for " + newExpr.toString() } + override final predicate producesExprResult() { + none() + } + override final Instruction getResult() { result = getInstruction(AllocationSizeTag()) } @@ -2050,8 +2091,8 @@ class TranslatedNonConstantAllocationSize extends TranslatedAllocationSize { * The IR translation of a call to `operator new` as part of a `new` or `new[]` * expression. */ -class TranslatedAllocatorCall extends TTranslatedAllocatorCall, TranslatedCall, - TranslatedFromExpr { +class TranslatedAllocatorCall extends TTranslatedAllocatorCall, + TranslatedCall { NewOrNewArrayExpr newExpr; TranslatedAllocatorCall() { @@ -2063,6 +2104,10 @@ class TranslatedAllocatorCall extends TTranslatedAllocatorCall, TranslatedCall, result = "Allocator call for " + newExpr.toString() } + override final predicate producesExprResult() { + none() + } + override final Instruction getFirstCallTargetInstruction() { result = getInstruction(CallTargetTag()) } @@ -2109,7 +2154,7 @@ class TranslatedAllocatorCall extends TTranslatedAllocatorCall, TranslatedCall, any() } - override final TranslatedOrSynthesizedExpr getArgument(int index) { + 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, @@ -2152,7 +2197,7 @@ abstract class TranslatedCallExpr extends TranslatedNonConstantExpr, result = getTranslatedExpr(call.getQualifier().getFullyConverted()) } - override final TranslatedOrSynthesizedExpr getArgument(int index) { + override final TranslatedExpr getArgument(int index) { result = getTranslatedExpr(call.getArgument(index).getFullyConverted()) } } diff --git a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected index 88a516c1faef..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,16 @@ #-----| 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 @@ -24,16 +34,6 @@ #-----| 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 ir.cpp: # 1| Constants() -> void # 1| params: From 72e72357c222924ab7f01a3ceec245bd19cb4375 Mon Sep 17 00:00:00 2001 From: Dave Bartolomeo Date: Thu, 23 Aug 2018 09:43:58 -0700 Subject: [PATCH 4/4] C++: Use `glval` as type of call target Also shared some code between `TranslatedFunctionCall` and `TranslatedAllocatorCall`, and fixed dumps of glval to not print the size. --- .../code/cpp/ir/internal/Instruction.qll | 5 +- .../code/cpp/ir/internal/TranslatedExpr.qll | 83 ++- .../ssa/internal/aliased_ssa/Instruction.qll | 5 +- .../code/cpp/ssa/internal/ssa/Instruction.qll | 5 +- .../ir/ir/aliased_ssa_ir.expected | 484 +++++++++--------- cpp/ql/test/library-tests/ir/ir/ir.expected | 484 +++++++++--------- .../test/library-tests/ir/ir/ssa_ir.expected | 484 +++++++++--------- 7 files changed, 770 insertions(+), 780 deletions(-) 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/TranslatedExpr.qll b/cpp/ql/src/semmle/code/cpp/ir/internal/TranslatedExpr.qll index 3570c2d9168a..2bc563f22bbb 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/internal/TranslatedExpr.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/internal/TranslatedExpr.qll @@ -2088,26 +2088,11 @@ class TranslatedNonConstantAllocationSize extends TranslatedAllocationSize { } /** - * The IR translation of a call to `operator new` as part of a `new` or `new[]` - * expression. + * IR translation of a direct call to a specific function. Used for both + * explicit calls (`TranslatedFunctionCall`) and implicit calls + * (`TranslatedAllocatorCall`). */ -class TranslatedAllocatorCall extends TTranslatedAllocatorCall, - TranslatedCall { - NewOrNewArrayExpr newExpr; - - TranslatedAllocatorCall() { - this = TTranslatedAllocatorCall(newExpr) and - expr = newExpr - } - - override final string toString() { - result = "Allocator call for " + newExpr.toString() - } - - override final predicate producesExprResult() { - none() - } - +abstract class TranslatedDirectCall extends TranslatedCall { override final Instruction getFirstCallTargetInstruction() { result = getInstruction(CallTargetTag()) } @@ -2122,8 +2107,11 @@ class TranslatedAllocatorCall extends TTranslatedAllocatorCall, ( 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 ) } @@ -2136,6 +2124,28 @@ class TranslatedAllocatorCall extends TTranslatedAllocatorCall, 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() @@ -2220,42 +2230,13 @@ class TranslatedExprCall extends TranslatedCallExpr { /** * Represents the IR translation of a direct function call. */ -class TranslatedFunctionCall extends TranslatedCallExpr { +class TranslatedFunctionCall extends TranslatedCallExpr, TranslatedDirectCall { FunctionCall funcCall; TranslatedFunctionCall() { expr = funcCall } - override final Instruction getFirstCallTargetInstruction() { - result = getInstruction(CallTargetTag()) - } - - override final Instruction getCallTargetResult() { - result = getInstruction(CallTargetTag()) - } - - override predicate hasInstruction(Opcode opcode, InstructionTag tag, - Type resultType, boolean isGLValue) { - super.hasInstruction(opcode, tag, resultType, isGLValue) or - ( - tag = CallTargetTag() and - opcode instanceof Opcode::FunctionAddress and - resultType instanceof BoolType and //HACK - isGLValue = false - ) - } - - override Instruction getInstructionSuccessor(InstructionTag tag, - EdgeKind kind) { - result = super.getInstructionSuccessor(tag, kind) or - ( - tag = CallTargetTag() and - kind instanceof GotoEdge and - result = getFirstArgumentOrCallInstruction() - ) - } - override Function getInstructionFunction(InstructionTag tag) { tag = CallTargetTag() and result = funcCall.getTarget() } 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/aliased_ssa_ir.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_ir.expected index 1793f32b64f3..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 @@ -3788,42 +3788,42 @@ ir.cpp: # 940| Block 0 # 940| v0_0(void) = EnterFunction : # 940| mu0_1(unknown) = UnmodeledDefinition : -# 941| r0_2(bool) = FunctionAddress[operator new] : +# 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(bool) = FunctionAddress[operator new] : +# 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(bool) = FunctionAddress[operator new] : +# 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(bool) = FunctionAddress[operator new] : +# 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(bool) = FunctionAddress[String] : +# 944| r0_21(glval) = FunctionAddress[String] : # 944| v0_22(void) = Invoke : r0_21, this:r0_20 -# 945| r0_23(bool) = FunctionAddress[operator new] : +# 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(bool) = FunctionAddress[String] : +# 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(bool) = FunctionAddress[operator new] : +# 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(bool) = FunctionAddress[operator new] : +# 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] : @@ -3842,11 +3842,11 @@ ir.cpp: # 950| mu0_1(unknown) = UnmodeledDefinition : # 950| r0_2(glval) = VariableAddress[n] : # 950| m0_3(int) = InitializeParameter[n] : r0_2 -# 951| r0_4(bool) = FunctionAddress[operator new[]] : +# 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(bool) = FunctionAddress[operator new[]] : +# 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 @@ -3854,7 +3854,7 @@ ir.cpp: # 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(bool) = FunctionAddress[operator new[]] : +# 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 @@ -3863,7 +3863,7 @@ ir.cpp: # 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(bool) = FunctionAddress[operator new[]] : +# 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 @@ -3871,7 +3871,7 @@ ir.cpp: # 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(bool) = FunctionAddress[operator new[]] : +# 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 @@ -3880,13 +3880,13 @@ ir.cpp: # 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(bool) = FunctionAddress[operator new[]] : +# 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(bool) = FunctionAddress[operator new[]] : +# 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 @@ -3894,7 +3894,7 @@ ir.cpp: # 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(bool) = FunctionAddress[operator new[]] : +# 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 diff --git a/cpp/ql/test/library-tests/ir/ir/ir.expected b/cpp/ql/test/library-tests/ir/ir/ir.expected index 0ab9191784cd..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 @@ -3767,42 +3767,42 @@ ir.cpp: # 940| Block 0 # 940| v0_0(void) = EnterFunction : # 940| mu0_1(unknown) = UnmodeledDefinition : -# 941| r0_2(bool) = FunctionAddress[operator new] : +# 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(bool) = FunctionAddress[operator new] : +# 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(bool) = FunctionAddress[operator new] : +# 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(bool) = FunctionAddress[operator new] : +# 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(bool) = FunctionAddress[String] : +# 944| r0_21(glval) = FunctionAddress[String] : # 944| v0_22(void) = Invoke : r0_21, this:r0_20 -# 945| r0_23(bool) = FunctionAddress[operator new] : +# 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(bool) = FunctionAddress[String] : +# 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(bool) = FunctionAddress[operator new] : +# 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(bool) = FunctionAddress[operator new] : +# 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] : @@ -3821,11 +3821,11 @@ ir.cpp: # 950| mu0_1(unknown) = UnmodeledDefinition : # 950| r0_2(glval) = VariableAddress[n] : # 950| mu0_3(int) = InitializeParameter[n] : r0_2 -# 951| r0_4(bool) = FunctionAddress[operator new[]] : +# 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(bool) = FunctionAddress[operator new[]] : +# 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 @@ -3833,7 +3833,7 @@ ir.cpp: # 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(bool) = FunctionAddress[operator new[]] : +# 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 @@ -3842,7 +3842,7 @@ ir.cpp: # 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(bool) = FunctionAddress[operator new[]] : +# 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 @@ -3850,7 +3850,7 @@ ir.cpp: # 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(bool) = FunctionAddress[operator new[]] : +# 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 @@ -3859,13 +3859,13 @@ ir.cpp: # 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(bool) = FunctionAddress[operator new[]] : +# 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(bool) = FunctionAddress[operator new[]] : +# 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 @@ -3873,7 +3873,7 @@ ir.cpp: # 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(bool) = FunctionAddress[operator new[]] : +# 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 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 f87fed120dfe..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 @@ -3788,42 +3788,42 @@ ir.cpp: # 940| Block 0 # 940| v0_0(void) = EnterFunction : # 940| mu0_1(unknown) = UnmodeledDefinition : -# 941| r0_2(bool) = FunctionAddress[operator new] : +# 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(bool) = FunctionAddress[operator new] : +# 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(bool) = FunctionAddress[operator new] : +# 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(bool) = FunctionAddress[operator new] : +# 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(bool) = FunctionAddress[String] : +# 944| r0_21(glval) = FunctionAddress[String] : # 944| v0_22(void) = Invoke : r0_21, this:r0_20 -# 945| r0_23(bool) = FunctionAddress[operator new] : +# 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(bool) = FunctionAddress[String] : +# 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(bool) = FunctionAddress[operator new] : +# 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(bool) = FunctionAddress[operator new] : +# 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] : @@ -3842,11 +3842,11 @@ ir.cpp: # 950| mu0_1(unknown) = UnmodeledDefinition : # 950| r0_2(glval) = VariableAddress[n] : # 950| m0_3(int) = InitializeParameter[n] : r0_2 -# 951| r0_4(bool) = FunctionAddress[operator new[]] : +# 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(bool) = FunctionAddress[operator new[]] : +# 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 @@ -3854,7 +3854,7 @@ ir.cpp: # 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(bool) = FunctionAddress[operator new[]] : +# 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 @@ -3863,7 +3863,7 @@ ir.cpp: # 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(bool) = FunctionAddress[operator new[]] : +# 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 @@ -3871,7 +3871,7 @@ ir.cpp: # 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(bool) = FunctionAddress[operator new[]] : +# 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 @@ -3880,13 +3880,13 @@ ir.cpp: # 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(bool) = FunctionAddress[operator new[]] : +# 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(bool) = FunctionAddress[operator new[]] : +# 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 @@ -3894,7 +3894,7 @@ ir.cpp: # 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(bool) = FunctionAddress[operator new[]] : +# 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