Fix IR for member accesses on prvalues

This fixes the IR generation for member accesses where the qualifier is a prvalue that is _not_ the load of a `TemporaryObjectExpr`. We synthesize a temporary variable during IR generation instead. It fits into the IR construction code at the same spot as `TranslatedLoad`, since it's basically the opposite of `TranslatedLoad` (prvalue->glvalue instead of vice versa). Note that array prvalues require special treatment.

This fixes some consistency errors in the `syntax-zoo`. It introduces three new ones in `dataflow-ir-consistency.expected`, but those are along the same lines as tons of existing failures.
This commit is contained in:
Dave Bartolomeo
2020-10-21 13:32:15 -04:00
parent 98e0ae4865
commit ee18db7b36
14 changed files with 329 additions and 56 deletions

View File

@@ -227,6 +227,49 @@ private predicate usedAsCondition(Expr expr) {
)
}
/**
* Holds if `expr` is the result of a field access whose qualifier was a prvalue and whose result is
* a prvalue. These accesses are not marked as having loads, but we do need a load in the IR.
*/
private predicate isPRValueFieldAccessWithImplicitLoad(Expr expr) {
expr instanceof ValueFieldAccess and
expr.isPRValueCategory() and
// No need to do a load if we're replacing the result with a constant anyway.
not isIRConstant(expr) and
// Model an array prvalue as the address of the array, just like an array glvalue.
not expr.getUnspecifiedType() instanceof ArrayType
}
/**
* Holds if `expr` is a prvalue of class type that is used directly as the qualifier for a member
* access, or is used after undergoing a prvalue adjustment conversion.
*/
private predicate isClassPRValueForMemberAccessQualifier(Expr expr) {
exists(Expr qualifier |
exists(FieldAccess access | qualifier = access.getQualifier().getFullyConverted())
or
exists(Call call | qualifier = call.getQualifier().getFullyConverted())
|
// The qualifier is a prvalue of class type.
qualifier.getUnspecifiedType() instanceof Class and
qualifier.isPRValueCategory() and
(
expr = qualifier and not expr instanceof PrvalueAdjustmentConversion
or
// If the qualifier is a prvalue adjustment conversion, the actual object with be provided by
// the operand of that conversion. For example:
// ```c++
// std::string("s").c_str();
// ```
// The object for the qualifier is a prvalue(load) of type `std::string`, but the actual
// fully-converted qualifier of the call to `c_str()` is a prvalue adjustment conversion that
// converts the type to `const std::string` to match the type of the `this` pointer of the
// member function.
expr = qualifier.(PrvalueAdjustmentConversion).getExpr()
)
)
}
/**
* Holds if `expr` has an lvalue-to-rvalue conversion that should be ignored
* when generating IR. This occurs for conversion from an lvalue of function type
@@ -249,30 +292,9 @@ predicate ignoreLoad(Expr expr) {
or
// The extractor represents the qualifier of a field access or member function call as a load of
// the temporary object if the original qualifier was a prvalue. For IR purposes, we always want
// to use the address of the temporary object as the base of a field access or the `this`
// to use the address of the temporary object as the qualifier of a field access or the `this`
// argument to a member function call.
exists(Expr qualifier |
exists(FieldAccess access | qualifier = access.getQualifier().getFullyConverted())
or
exists(Call call | qualifier = call.getQualifier().getFullyConverted())
|
// The qualifier has a class type.
qualifier.getUnspecifiedType() instanceof Class and
(
expr = qualifier
or
// If the qualifier is a prvalue adjustment conversion, the load will be on the operand of
// that conversion. For example:
// ```c++
// std::string("s").c_str();
// ```
// The temporary object for the qualifier is a prvalue(load) of type `std::string`, but the
// actual fully converted qualifier of the call to `c_str()` is a prvalue adjustment
// conversion that converts the type to `const std::string` to match the type of the `this`
// pointer of the member function.
expr = qualifier.(PrvalueAdjustmentConversion).getExpr()
)
)
isClassPRValueForMemberAccessQualifier(expr)
)
}
@@ -308,6 +330,8 @@ predicate hasTranslatedLoad(Expr expr) {
expr.hasLValueToRValueConversion()
or
needsLoadForParentExpr(expr)
or
isPRValueFieldAccessWithImplicitLoad(expr)
) and
not ignoreExpr(expr) and
not isNativeCondition(expr) and
@@ -315,6 +339,16 @@ predicate hasTranslatedLoad(Expr expr) {
not ignoreLoad(expr)
}
/**
* Holds if `expr` should have a `TranslatedSyntheticTemporaryObject` on it.
*/
predicate hasTranslatedSyntheticTemporaryObject(Expr expr) {
not ignoreExpr(expr) and
isClassPRValueForMemberAccessQualifier(expr) and
// If it's a load, we'll just ignore the load in `ignoreLoad()`.
not expr.hasLValueToRValueConversion()
}
/**
* Holds if the specified `DeclarationEntry` needs an IR translation. An IR translation is only
* necessary for automatic local variables, or for static local variables with dynamic
@@ -345,6 +379,9 @@ newtype TTranslatedElement =
// A separate element to handle the lvalue-to-rvalue conversion step of an
// expression.
TTranslatedLoad(Expr expr) { hasTranslatedLoad(expr) } or
// A temporary object that we had to synthesize ourselves, so that we could do a field access or
// method call on a prvalue.
TTranslatedSyntheticTemporaryObject(Expr expr) { hasTranslatedSyntheticTemporaryObject(expr) } or
// For expressions that would not otherwise generate an instruction.
TTranslatedResultCopy(Expr expr) {
not ignoreExpr(expr) and

View File

@@ -110,9 +110,10 @@ abstract class TranslatedCoreExpr extends TranslatedExpr {
}
final override predicate producesExprResult() {
// If there's no load, then this is the only TranslatedExpr for this
// If there's no load or temp object, then this is the only TranslatedExpr for this
// expression.
not hasTranslatedLoad(expr) and
not hasTranslatedSyntheticTemporaryObject(expr) and
// If there's a result copy, then this expression's result is the copy.
not exprNeedsCopyIfNotLoaded(expr)
}
@@ -246,19 +247,35 @@ class TranslatedConditionValue extends TranslatedCoreExpr, ConditionContext,
private TranslatedCondition getCondition() { result = getTranslatedCondition(expr) }
}
/**
* The IR translation of a node synthesized to adjust the value category of its operand.
* One of:
* - `TranslatedLoad` - Convert from glvalue to prvalue by loading from the location.
* - `TranslatedSyntheticTemporaryObject` - Convert from prvalue to glvalue by storing to a
* temporary variable.
*/
abstract class TranslatedValueCategoryAdjustment extends TranslatedExpr {
final override Instruction getFirstInstruction() { result = getOperand().getFirstInstruction() }
final override TranslatedElement getChild(int id) { id = 0 and result = getOperand() }
final override predicate producesExprResult() {
// A temp object always produces the result of the expression.
any()
}
final TranslatedCoreExpr getOperand() { result.getExpr() = expr }
}
/**
* IR translation of an implicit lvalue-to-rvalue conversion on the result of
* an expression.
*/
class TranslatedLoad extends TranslatedExpr, TTranslatedLoad {
class TranslatedLoad extends TranslatedValueCategoryAdjustment, TTranslatedLoad {
TranslatedLoad() { this = TTranslatedLoad(expr) }
override string toString() { result = "Load of " + expr.toString() }
override Instruction getFirstInstruction() { result = getOperand().getFirstInstruction() }
override TranslatedElement getChild(int id) { id = 0 and result = getOperand() }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = LoadTag() and
opcode instanceof Opcode::Load and
@@ -286,18 +303,75 @@ class TranslatedLoad extends TranslatedExpr, TTranslatedLoad {
result = getOperand().getResult()
)
}
final override predicate producesExprResult() {
// A load always produces the result of the expression.
any()
}
TranslatedCoreExpr getOperand() { result.getExpr() = expr }
}
/**
* IR translation of an implicit lvalue-to-rvalue conversion on the result of
* an expression.
* The IR translation of a temporary object synthesized by the IR to hold a class prvalue on which
* a member access is going to be performed. This differs from `TranslatedTemporaryObjectExpr` in
* that instances of `TranslatedSyntheticTemporaryObject` are synthesized during IR construction,
* whereas `TranslatedTemporaryObjectExpr` instances are created from `TemporaryObjectExpr` nodes
* from the AST.
*/
class TranslatedSyntheticTemporaryObject extends TranslatedValueCategoryAdjustment,
TTranslatedSyntheticTemporaryObject {
TranslatedSyntheticTemporaryObject() { this = TTranslatedSyntheticTemporaryObject(expr) }
override string toString() { result = "Temporary materialization of " + expr.toString() }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = InitializerVariableAddressTag() and
opcode instanceof Opcode::VariableAddress and
resultType = getTypeForGLValue(expr.getType())
or
tag = InitializerStoreTag() and
opcode instanceof Opcode::Store and
resultType = getTypeForPRValue(expr.getType())
}
override predicate isResultGLValue() { any() }
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = InitializerVariableAddressTag() and
result = getInstruction(InitializerStoreTag()) and
kind instanceof GotoEdge
or
tag = InitializerStoreTag() and
result = getParent().getChildSuccessor(this) and
kind instanceof GotoEdge
}
override Instruction getChildSuccessor(TranslatedElement child) {
child = getOperand() and result = getInstruction(InitializerVariableAddressTag())
}
override Instruction getResult() { result = getInstruction(InitializerVariableAddressTag()) }
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = InitializerStoreTag() and
(
operandTag instanceof AddressOperandTag and
result = getInstruction(InitializerVariableAddressTag())
or
operandTag instanceof StoreValueOperandTag and
result = getOperand().getResult()
)
}
final override predicate hasTempVariable(TempVariableTag tag, CppType type) {
tag = TempObjectTempVar() and
type = getTypeForPRValue(expr.getType())
}
final override IRVariable getInstructionVariable(InstructionTag tag) {
tag = InitializerVariableAddressTag() and
result = getIRTempVariable(expr, TempObjectTempVar())
}
}
/**
* IR translation of an expression that simply returns its result. We generate an otherwise useless
* `CopyValue` instruction for these expressions so that there is at least one instruction
* associated with the expression.
*/
class TranslatedResultCopy extends TranslatedExpr, TTranslatedResultCopy {
TranslatedResultCopy() { this = TTranslatedResultCopy(expr) }

View File

@@ -10656,6 +10656,8 @@ ir.cpp:
# 1363| params:
# 1363| [TemplateFunction,TopLevelFunction] T returnValue<T>()
# 1363| params:
# 1363| [FunctionTemplateInstantiation,TopLevelFunction] UnusualFields returnValue<UnusualFields>()
# 1363| params:
# 1363| [FunctionTemplateInstantiation,TopLevelFunction] copy_constructor returnValue<copy_constructor>()
# 1363| params:
# 1363| [FunctionTemplateInstantiation,TopLevelFunction] destructor_only returnValue<destructor_only>()
@@ -11061,6 +11063,104 @@ ir.cpp:
# 1413| Type = [Struct] Point
# 1413| ValueCategory = prvalue
# 1414| 7: [ReturnStmt] return ...
# 1416| [CopyAssignmentOperator] UnusualFields& UnusualFields::operator=(UnusualFields const&)
# 1416| params:
#-----| 0: [Parameter] (unnamed parameter 0)
#-----| Type = [LValueReferenceType] const UnusualFields &
# 1416| [Constructor] void UnusualFields::UnusualFields()
# 1416| params:
# 1416| [CopyConstructor] void UnusualFields::UnusualFields(UnusualFields const&)
# 1416| params:
#-----| 0: [Parameter] (unnamed parameter 0)
#-----| Type = [LValueReferenceType] const UnusualFields &
# 1416| [MoveConstructor] void UnusualFields::UnusualFields(UnusualFields&&)
# 1416| params:
#-----| 0: [Parameter] (unnamed parameter 0)
#-----| Type = [RValueReferenceType] UnusualFields &&
# 1421| [TopLevelFunction] void temporary_unusual_fields()
# 1421| params:
# 1421| body: [BlockStmt] { ... }
# 1422| 0: [DeclStmt] declaration
# 1422| 0: [VariableDeclarationEntry] definition of rx
# 1422| Type = [LValueReferenceType] const int &
# 1422| init: [Initializer] initializer for rx
# 1422| expr: [ReferenceToExpr] (reference to)
# 1422| Type = [LValueReferenceType] const int &
# 1422| ValueCategory = prvalue
# 1422| expr: [CStyleCast] (const int)...
# 1422| Conversion = [GlvalueConversion] glvalue conversion
# 1422| Type = [SpecifiedType] const int
# 1422| ValueCategory = lvalue
# 1422| expr: [ReferenceDereferenceExpr] (reference dereference)
# 1422| Type = [IntType] int
# 1422| ValueCategory = lvalue
# 1422| expr: [ValueFieldAccess] r
# 1422| Type = [LValueReferenceType] int &
# 1422| ValueCategory = prvalue
# 1422| -1: [FunctionCall] call to returnValue
# 1422| Type = [Struct] UnusualFields
# 1422| ValueCategory = prvalue
# 1423| 1: [DeclStmt] declaration
# 1423| 0: [VariableDeclarationEntry] definition of x
# 1423| Type = [IntType] int
# 1423| init: [Initializer] initializer for x
# 1423| expr: [ReferenceDereferenceExpr] (reference dereference)
# 1423| Type = [IntType] int
# 1423| ValueCategory = prvalue(load)
# 1423| expr: [ValueFieldAccess] r
# 1423| Type = [LValueReferenceType] int &
# 1423| ValueCategory = prvalue
# 1423| -1: [FunctionCall] call to returnValue
# 1423| Type = [Struct] UnusualFields
# 1423| ValueCategory = prvalue
# 1425| 2: [DeclStmt] declaration
# 1425| 0: [VariableDeclarationEntry] definition of rf
# 1425| Type = [LValueReferenceType] const float &
# 1425| init: [Initializer] initializer for rf
# 1425| expr: [ReferenceToExpr] (reference to)
# 1425| Type = [LValueReferenceType] const float &
# 1425| ValueCategory = prvalue
# 1425| expr: [CStyleCast] (const float)...
# 1425| Conversion = [GlvalueConversion] glvalue conversion
# 1425| Type = [SpecifiedType] const float
# 1425| ValueCategory = lvalue
# 1425| expr: [ArrayExpr] access to array
# 1425| Type = [FloatType] float
# 1425| ValueCategory = lvalue
# 1425| 0: [ArrayToPointerConversion] array to pointer conversion
# 1425| Type = [PointerType] float *
# 1425| ValueCategory = prvalue
# 1425| expr: [ValueFieldAccess] a
# 1425| Type = [ArrayType] float[10]
# 1425| ValueCategory = prvalue
# 1425| -1: [FunctionCall] call to returnValue
# 1425| Type = [Struct] UnusualFields
# 1425| ValueCategory = prvalue
# 1425| 1: [Literal] 3
# 1425| Type = [IntType] int
# 1425| Value = [Literal] 3
# 1425| ValueCategory = prvalue
# 1426| 3: [DeclStmt] declaration
# 1426| 0: [VariableDeclarationEntry] definition of f
# 1426| Type = [FloatType] float
# 1426| init: [Initializer] initializer for f
# 1426| expr: [ArrayExpr] access to array
# 1426| Type = [FloatType] float
# 1426| ValueCategory = prvalue(load)
# 1426| 0: [ArrayToPointerConversion] array to pointer conversion
# 1426| Type = [PointerType] float *
# 1426| ValueCategory = prvalue
# 1426| expr: [ValueFieldAccess] a
# 1426| Type = [ArrayType] float[10]
# 1426| ValueCategory = prvalue
# 1426| -1: [FunctionCall] call to returnValue
# 1426| Type = [Struct] UnusualFields
# 1426| ValueCategory = prvalue
# 1426| 1: [Literal] 5
# 1426| Type = [IntType] int
# 1426| Value = [Literal] 5
# 1426| ValueCategory = prvalue
# 1427| 4: [ReturnStmt] return ...
perf-regression.cpp:
# 4| [CopyAssignmentOperator] Big& Big::operator=(Big const&)
# 4| params:

View File

@@ -22,7 +22,6 @@ wronglyMarkedAsConflated
invalidOverlap
nonUniqueEnclosingIRFunction
fieldAddressOnNonPointer
| ir.cpp:1411:34:1411:34 | FieldAddress: y | FieldAddress instruction 'FieldAddress: y' has an object address operand that is not an address, in function '$@'. | ir.cpp:1404:6:1404:20 | void temporary_point() | void temporary_point() |
thisArgumentIsNonPointer
missingCanonicalLanguageType
multipleCanonicalLanguageTypes

View File

@@ -22,7 +22,6 @@ wronglyMarkedAsConflated
invalidOverlap
nonUniqueEnclosingIRFunction
fieldAddressOnNonPointer
| ir.cpp:1411:34:1411:34 | FieldAddress: y | FieldAddress instruction 'FieldAddress: y' has an object address operand that is not an address, in function '$@'. | ir.cpp:1404:6:1404:20 | void temporary_point() | void temporary_point() |
thisArgumentIsNonPointer
missingCanonicalLanguageType
multipleCanonicalLanguageTypes

View File

@@ -1413,4 +1413,17 @@ void temporary_point() {
defaultConstruct<Point>();
}
struct UnusualFields {
int& r;
float a[10];
};
void temporary_unusual_fields() {
const int& rx = returnValue<UnusualFields>().r;
int x = returnValue<UnusualFields>().r;
const float& rf = returnValue<UnusualFields>().a[3];
float f = returnValue<UnusualFields>().a[5];
}
// semmle-extractor-options: -std=c++17 --clang

View File

@@ -22,7 +22,6 @@ wronglyMarkedAsConflated
invalidOverlap
nonUniqueEnclosingIRFunction
fieldAddressOnNonPointer
| ir.cpp:1411:34:1411:34 | FieldAddress: y | FieldAddress instruction 'FieldAddress: y' has an object address operand that is not an address, in function '$@'. | ir.cpp:1404:6:1404:20 | void temporary_point() | void temporary_point() |
thisArgumentIsNonPointer
missingCanonicalLanguageType
multipleCanonicalLanguageTypes

View File

@@ -7753,7 +7753,8 @@ ir.cpp:
# 1401| mu1401_5(unknown) = ^CallSideEffect : ~m?
# 1401| mu1401_6(copy_constructor) = Store[#temp1401:13] : &:r1401_2, r1401_4
# 1401| r1401_7(glval<int>) = FieldAddress[y] : r1401_2
# 1401| mu1401_8(int) = Store[y] : &:r1401_1, r1401_7
# 1401| r1401_8(int) = Load[?] : &:r1401_7, ~m?
# 1401| mu1401_9(int) = Store[y] : &:r1401_1, r1401_8
# 1402| v1402_1(void) = NoOp :
# 1391| v1391_4(void) = ReturnVoid :
# 1391| v1391_5(void) = AliasedUse : ~m?
@@ -7796,8 +7797,11 @@ ir.cpp:
# 1411| r1411_2(glval<unknown>) = FunctionAddress[returnValue] :
# 1411| r1411_3(Point) = Call[returnValue] : func:r1411_2
# 1411| mu1411_4(unknown) = ^CallSideEffect : ~m?
# 1411| r1411_5(glval<int>) = FieldAddress[y] : r1411_3
# 1411| mu1411_6(int) = Store[y] : &:r1411_1, r1411_5
# 1411| r1411_5(glval<Point>) = VariableAddress[#temp1411:13] :
# 1411| mu1411_6(Point) = Store[#temp1411:13] : &:r1411_5, r1411_3
# 1411| r1411_7(glval<int>) = FieldAddress[y] : r1411_5
# 1411| r1411_8(int) = Load[?] : &:r1411_7, ~m?
# 1411| mu1411_9(int) = Store[y] : &:r1411_1, r1411_8
# 1413| r1413_1(glval<unknown>) = FunctionAddress[defaultConstruct] :
# 1413| r1413_2(Point) = Call[defaultConstruct] : func:r1413_1
# 1413| mu1413_3(unknown) = ^CallSideEffect : ~m?
@@ -7806,6 +7810,63 @@ ir.cpp:
# 1404| v1404_5(void) = AliasedUse : ~m?
# 1404| v1404_6(void) = ExitFunction :
# 1421| void temporary_unusual_fields()
# 1421| Block 0
# 1421| v1421_1(void) = EnterFunction :
# 1421| mu1421_2(unknown) = AliasedDefinition :
# 1421| mu1421_3(unknown) = InitializeNonLocal :
# 1422| r1422_1(glval<int &>) = VariableAddress[rx] :
# 1422| r1422_2(glval<unknown>) = FunctionAddress[returnValue] :
# 1422| r1422_3(UnusualFields) = Call[returnValue] : func:r1422_2
# 1422| mu1422_4(unknown) = ^CallSideEffect : ~m?
# 1422| r1422_5(glval<UnusualFields>) = VariableAddress[#temp1422:21] :
# 1422| mu1422_6(UnusualFields) = Store[#temp1422:21] : &:r1422_5, r1422_3
# 1422| r1422_7(glval<int &>) = FieldAddress[r] : r1422_5
# 1422| r1422_8(int &) = Load[?] : &:r1422_7, ~m?
# 1422| r1422_9(glval<int>) = CopyValue : r1422_8
# 1422| r1422_10(glval<int>) = Convert : r1422_9
# 1422| r1422_11(int &) = CopyValue : r1422_10
# 1422| mu1422_12(int &) = Store[rx] : &:r1422_1, r1422_11
# 1423| r1423_1(glval<int>) = VariableAddress[x] :
# 1423| r1423_2(glval<unknown>) = FunctionAddress[returnValue] :
# 1423| r1423_3(UnusualFields) = Call[returnValue] : func:r1423_2
# 1423| mu1423_4(unknown) = ^CallSideEffect : ~m?
# 1423| r1423_5(glval<UnusualFields>) = VariableAddress[#temp1423:13] :
# 1423| mu1423_6(UnusualFields) = Store[#temp1423:13] : &:r1423_5, r1423_3
# 1423| r1423_7(glval<int &>) = FieldAddress[r] : r1423_5
# 1423| r1423_8(int &) = Load[?] : &:r1423_7, ~m?
# 1423| r1423_9(int) = Load[?] : &:r1423_8, ~m?
# 1423| mu1423_10(int) = Store[x] : &:r1423_1, r1423_9
# 1425| r1425_1(glval<float &>) = VariableAddress[rf] :
# 1425| r1425_2(glval<unknown>) = FunctionAddress[returnValue] :
# 1425| r1425_3(UnusualFields) = Call[returnValue] : func:r1425_2
# 1425| mu1425_4(unknown) = ^CallSideEffect : ~m?
# 1425| r1425_5(glval<UnusualFields>) = VariableAddress[#temp1425:23] :
# 1425| mu1425_6(UnusualFields) = Store[#temp1425:23] : &:r1425_5, r1425_3
# 1425| r1425_7(glval<float[10]>) = FieldAddress[a] : r1425_5
# 1425| r1425_8(float *) = Convert : r1425_7
# 1425| r1425_9(int) = Constant[3] :
# 1425| r1425_10(glval<float>) = PointerAdd[4] : r1425_8, r1425_9
# 1425| r1425_11(glval<float>) = Convert : r1425_10
# 1425| r1425_12(float &) = CopyValue : r1425_11
# 1425| mu1425_13(float &) = Store[rf] : &:r1425_1, r1425_12
# 1426| r1426_1(glval<float>) = VariableAddress[f] :
# 1426| r1426_2(glval<unknown>) = FunctionAddress[returnValue] :
# 1426| r1426_3(UnusualFields) = Call[returnValue] : func:r1426_2
# 1426| mu1426_4(unknown) = ^CallSideEffect : ~m?
# 1426| r1426_5(glval<UnusualFields>) = VariableAddress[#temp1426:15] :
# 1426| mu1426_6(UnusualFields) = Store[#temp1426:15] : &:r1426_5, r1426_3
# 1426| r1426_7(glval<float[10]>) = FieldAddress[a] : r1426_5
# 1426| r1426_8(float *) = Convert : r1426_7
# 1426| r1426_9(int) = Constant[5] :
# 1426| r1426_10(glval<float>) = PointerAdd[4] : r1426_8, r1426_9
# 1426| r1426_11(float) = Load[?] : &:r1426_10, ~m?
# 1426| mu1426_12(float) = Store[f] : &:r1426_1, r1426_11
# 1427| v1427_1(void) = NoOp :
# 1421| v1421_4(void) = ReturnVoid :
# 1421| v1421_5(void) = AliasedUse : ~m?
# 1421| v1421_6(void) = ExitFunction :
perf-regression.cpp:
# 6| void Big::Big()
# 6| Block 0

View File

@@ -22,7 +22,6 @@ wronglyMarkedAsConflated
invalidOverlap
nonUniqueEnclosingIRFunction
fieldAddressOnNonPointer
| ir.cpp:1411:34:1411:34 | FieldAddress: y | FieldAddress instruction 'FieldAddress: y' has an object address operand that is not an address, in function '$@'. | ir.cpp:1404:6:1404:20 | void temporary_point() | void temporary_point() |
thisArgumentIsNonPointer
missingCanonicalLanguageType
multipleCanonicalLanguageTypes

View File

@@ -22,7 +22,6 @@ wronglyMarkedAsConflated
invalidOverlap
nonUniqueEnclosingIRFunction
fieldAddressOnNonPointer
| ir.cpp:1411:34:1411:34 | FieldAddress: y | FieldAddress instruction 'FieldAddress: y' has an object address operand that is not an address, in function '$@'. | ir.cpp:1404:6:1404:20 | void temporary_point() | void temporary_point() |
thisArgumentIsNonPointer
missingCanonicalLanguageType
multipleCanonicalLanguageTypes

View File

@@ -13,7 +13,6 @@ instructionWithoutSuccessor
| condition_decls.cpp:41:22:41:23 | Chi: call to BoxedInt | Instruction 'Chi: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:40:6:40:20 | void while_decl_bind(int) | void while_decl_bind(int) |
| condition_decls.cpp:48:52:48:53 | Chi: call to BoxedInt | Instruction 'Chi: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:47:6:47:18 | void for_decl_bind(int) | void for_decl_bind(int) |
| misc.c:171:10:171:13 | Uninitialized: definition of str2 | Instruction 'Uninitialized: definition of str2' has no successors in function '$@'. | misc.c:168:6:168:8 | void vla() | void vla() |
| misc.c:219:47:219:48 | InitializeIndirection: sp | Instruction 'InitializeIndirection: sp' has no successors in function '$@'. | misc.c:219:5:219:26 | int assign_designated_init(someStruct*) | int assign_designated_init(someStruct*) |
| ms_try_except.cpp:3:9:3:9 | Uninitialized: definition of x | Instruction 'Uninitialized: definition of x' has no successors in function '$@'. | ms_try_except.cpp:2:6:2:18 | void ms_try_except(int) | void ms_try_except(int) |
| ms_try_mix.cpp:11:12:11:15 | Chi: call to C | Instruction 'Chi: call to C' has no successors in function '$@'. | ms_try_mix.cpp:10:6:10:18 | void ms_except_mix(int) | void ms_except_mix(int) |
| ms_try_mix.cpp:28:12:28:15 | Chi: call to C | Instruction 'Chi: call to C' has no successors in function '$@'. | ms_try_mix.cpp:27:6:27:19 | void ms_finally_mix(int) | void ms_finally_mix(int) |

View File

@@ -1558,6 +1558,9 @@ postWithInFlow
| misc.c:158:14:158:18 | Chi | PostUpdateNode should not be the target of local flow. |
| misc.c:160:31:160:33 | Chi | PostUpdateNode should not be the target of local flow. |
| misc.c:160:31:160:33 | Chi | PostUpdateNode should not be the target of local flow. |
| misc.c:220:3:223:3 | Chi | PostUpdateNode should not be the target of local flow. |
| misc.c:221:10:221:10 | Chi | PostUpdateNode should not be the target of local flow. |
| misc.c:222:10:222:10 | Chi | PostUpdateNode should not be the target of local flow. |
| range_analysis.c:102:5:102:15 | Chi | PostUpdateNode should not be the target of local flow. |
| static_init_templates.cpp:3:2:3:8 | Chi | PostUpdateNode should not be the target of local flow. |
| static_init_templates.cpp:21:2:21:12 | Chi | PostUpdateNode should not be the target of local flow. |

View File

@@ -4,9 +4,6 @@ missingOperand
| condition_decls.cpp:41:9:41:23 | CopyValue: (condition decl) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | condition_decls.cpp:40:6:40:20 | void while_decl_bind(int) | void while_decl_bind(int) |
| condition_decls.cpp:48:39:48:53 | CopyValue: (condition decl) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | condition_decls.cpp:47:6:47:18 | void for_decl_bind(int) | void for_decl_bind(int) |
| misc.c:125:5:125:11 | CopyValue: (statement expression) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | misc.c:97:6:97:10 | void misc3() | void misc3() |
| misc.c:220:3:223:3 | Store: ... = ... | Instruction 'Store' is missing an expected operand with tag 'StoreValue' in function '$@'. | misc.c:219:5:219:26 | int assign_designated_init(someStruct*) | int assign_designated_init(someStruct*) |
| misc.c:220:9:223:3 | FieldAddress: {...} | Instruction 'FieldAddress' is missing an expected operand with tag 'Unary' in function '$@'. | misc.c:219:5:219:26 | int assign_designated_init(someStruct*) | int assign_designated_init(someStruct*) |
| misc.c:220:9:223:3 | FieldAddress: {...} | Instruction 'FieldAddress' is missing an expected operand with tag 'Unary' in function '$@'. | misc.c:219:5:219:26 | int assign_designated_init(someStruct*) | int assign_designated_init(someStruct*) |
| try_catch.cpp:23:5:23:18 | CopyValue: (statement expression) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | try_catch.cpp:19:6:19:23 | void throw_from_nonstmt(int) | void throw_from_nonstmt(int) |
unexpectedOperand
duplicateOperand
@@ -34,9 +31,6 @@ instructionWithoutSuccessor
| misc.c:174:17:174:22 | CallSideEffect: call to getInt | Instruction 'CallSideEffect: call to getInt' has no successors in function '$@'. | misc.c:168:6:168:8 | void vla() | void vla() |
| misc.c:174:30:174:35 | CallSideEffect: call to getInt | Instruction 'CallSideEffect: call to getInt' has no successors in function '$@'. | misc.c:168:6:168:8 | void vla() | void vla() |
| misc.c:174:55:174:60 | Store: (char ****)... | Instruction 'Store: (char ****)...' has no successors in function '$@'. | misc.c:168:6:168:8 | void vla() | void vla() |
| misc.c:219:47:219:48 | InitializeIndirection: sp | Instruction 'InitializeIndirection: sp' has no successors in function '$@'. | misc.c:219:5:219:26 | int assign_designated_init(someStruct*) | int assign_designated_init(someStruct*) |
| misc.c:221:10:221:10 | Store: 1 | Instruction 'Store: 1' has no successors in function '$@'. | misc.c:219:5:219:26 | int assign_designated_init(someStruct*) | int assign_designated_init(someStruct*) |
| misc.c:222:10:222:10 | Store: 2 | Instruction 'Store: 2' has no successors in function '$@'. | misc.c:219:5:219:26 | int assign_designated_init(someStruct*) | int assign_designated_init(someStruct*) |
| ms_try_except.cpp:3:9:3:9 | Uninitialized: definition of x | Instruction 'Uninitialized: definition of x' has no successors in function '$@'. | ms_try_except.cpp:2:6:2:18 | void ms_try_except(int) | void ms_try_except(int) |
| ms_try_except.cpp:7:13:7:17 | Store: ... = ... | Instruction 'Store: ... = ...' has no successors in function '$@'. | ms_try_except.cpp:2:6:2:18 | void ms_try_except(int) | void ms_try_except(int) |
| ms_try_except.cpp:9:19:9:19 | Load: j | Instruction 'Load: j' has no successors in function '$@'. | ms_try_except.cpp:2:6:2:18 | void ms_try_except(int) | void ms_try_except(int) |
@@ -150,8 +144,6 @@ wronglyMarkedAsConflated
invalidOverlap
nonUniqueEnclosingIRFunction
fieldAddressOnNonPointer
| misc.c:220:9:223:3 | FieldAddress: {...} | FieldAddress instruction 'FieldAddress: {...}' has an object address operand that is not an address, in function '$@'. | misc.c:219:5:219:26 | int assign_designated_init(someStruct*) | int assign_designated_init(someStruct*) |
| misc.c:220:9:223:3 | FieldAddress: {...} | FieldAddress instruction 'FieldAddress: {...}' has an object address operand that is not an address, in function '$@'. | misc.c:219:5:219:26 | int assign_designated_init(someStruct*) | int assign_designated_init(someStruct*) |
thisArgumentIsNonPointer
| pmcallexpr.cpp:8:2:8:15 | Call: call to expression | Call instruction 'Call: call to expression' has a `this` argument operand that is not an address, in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| pointer_to_member.cpp:23:5:23:54 | Call: call to expression | Call instruction 'Call: call to expression' has a `this` argument operand that is not an address, in function '$@'. | pointer_to_member.cpp:14:5:14:9 | int usePM(int PM::*) | int usePM(int PM::*) |

View File

@@ -13,7 +13,6 @@ instructionWithoutSuccessor
| condition_decls.cpp:41:22:41:23 | IndirectMayWriteSideEffect: call to BoxedInt | Instruction 'IndirectMayWriteSideEffect: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:40:6:40:20 | void while_decl_bind(int) | void while_decl_bind(int) |
| condition_decls.cpp:48:52:48:53 | IndirectMayWriteSideEffect: call to BoxedInt | Instruction 'IndirectMayWriteSideEffect: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:47:6:47:18 | void for_decl_bind(int) | void for_decl_bind(int) |
| misc.c:171:10:171:13 | Uninitialized: definition of str2 | Instruction 'Uninitialized: definition of str2' has no successors in function '$@'. | misc.c:168:6:168:8 | void vla() | void vla() |
| misc.c:219:47:219:48 | InitializeIndirection: sp | Instruction 'InitializeIndirection: sp' has no successors in function '$@'. | misc.c:219:5:219:26 | int assign_designated_init(someStruct*) | int assign_designated_init(someStruct*) |
| ms_try_except.cpp:3:9:3:9 | Uninitialized: definition of x | Instruction 'Uninitialized: definition of x' has no successors in function '$@'. | ms_try_except.cpp:2:6:2:18 | void ms_try_except(int) | void ms_try_except(int) |
| ms_try_mix.cpp:11:12:11:15 | IndirectMayWriteSideEffect: call to C | Instruction 'IndirectMayWriteSideEffect: call to C' has no successors in function '$@'. | ms_try_mix.cpp:10:6:10:18 | void ms_except_mix(int) | void ms_except_mix(int) |
| ms_try_mix.cpp:28:12:28:15 | IndirectMayWriteSideEffect: call to C | Instruction 'IndirectMayWriteSideEffect: call to C' has no successors in function '$@'. | ms_try_mix.cpp:27:6:27:19 | void ms_finally_mix(int) | void ms_finally_mix(int) |