Skip to content

Commit 9b8302f

Browse files
authored
Merge pull request #20068 from jketema/spaceship-test
C++: Add test that shows that IR generation for `<=>` is broken
2 parents a9fb49a + 807ab98 commit 9b8302f

9 files changed

+338
-0
lines changed

cpp/ql/test/library-tests/ir/ir/PrintAST.expected

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24436,6 +24436,107 @@ ir.cpp:
2443624436
# 2742| Type = [IntType] int
2443724437
# 2742| ValueCategory = prvalue
2443824438
# 2743| getStmt(14): [ReturnStmt] return ...
24439+
# 2747| [CopyAssignmentOperator] std::strong_ordering& std::strong_ordering::operator=(std::strong_ordering const&)
24440+
# 2747| <params>:
24441+
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
24442+
#-----| Type = [LValueReferenceType] const strong_ordering &
24443+
# 2747| [MoveAssignmentOperator] std::strong_ordering& std::strong_ordering::operator=(std::strong_ordering&&)
24444+
# 2747| <params>:
24445+
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
24446+
#-----| Type = [RValueReferenceType] strong_ordering &&
24447+
# 2747| [CopyConstructor] void std::strong_ordering::strong_ordering(std::strong_ordering const&)
24448+
# 2747| <params>:
24449+
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
24450+
#-----| Type = [LValueReferenceType] const strong_ordering &
24451+
# 2747| [MoveConstructor] void std::strong_ordering::strong_ordering(std::strong_ordering&&)
24452+
# 2747| <params>:
24453+
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
24454+
#-----| Type = [RValueReferenceType] strong_ordering &&
24455+
# 2747| <initializations>:
24456+
# 2747| getEntryPoint(): [BlockStmt] { ... }
24457+
# 2747| getStmt(0): [ReturnStmt] return ...
24458+
# 2748| [Constructor] void std::strong_ordering::strong_ordering(std::_Order)
24459+
# 2748| <params>:
24460+
# 2748| getParameter(0): [Parameter] v
24461+
# 2748| Type = [ScopedEnum] _Order
24462+
# 2748| <initializations>:
24463+
# 2748| getEntryPoint(): [BlockStmt] { ... }
24464+
# 2748| getStmt(0): [ReturnStmt] return ...
24465+
# 2763| [CopyAssignmentOperator] ThreeWay& ThreeWay::operator=(ThreeWay const&)
24466+
# 2763| <params>:
24467+
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
24468+
#-----| Type = [LValueReferenceType] const ThreeWay &
24469+
# 2763| [MoveAssignmentOperator] ThreeWay& ThreeWay::operator=(ThreeWay&&)
24470+
# 2763| <params>:
24471+
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
24472+
#-----| Type = [RValueReferenceType] ThreeWay &&
24473+
# 2763| [Constructor] void ThreeWay::ThreeWay()
24474+
# 2763| <params>:
24475+
# 2766| [MemberFunction] std::strong_ordering ThreeWay::operator<=>(ThreeWay&)
24476+
# 2766| <params>:
24477+
# 2766| getParameter(0): [Parameter] y
24478+
# 2766| Type = [LValueReferenceType] ThreeWay &
24479+
# 2766| getEntryPoint(): [BlockStmt] { ... }
24480+
# 2766| getStmt(0): [ReturnStmt] return ...
24481+
# 2766| getExpr(): [SpaceshipExpr] ... <=> ...
24482+
# 2766| Type = [Class] strong_ordering
24483+
# 2766| ValueCategory = prvalue
24484+
# 2766| getChild(0): [PointerFieldAccess] x
24485+
# 2766| Type = [IntType] int
24486+
# 2766| ValueCategory = prvalue(load)
24487+
# 2766| getQualifier(): [ThisExpr] this
24488+
# 2766| Type = [PointerType] ThreeWay *
24489+
# 2766| ValueCategory = prvalue(load)
24490+
# 2766| getChild(1): [ReferenceFieldAccess] x
24491+
# 2766| Type = [IntType] int
24492+
# 2766| ValueCategory = prvalue(load)
24493+
# 2766| getQualifier(): [VariableAccess] y
24494+
# 2766| Type = [LValueReferenceType] ThreeWay &
24495+
# 2766| ValueCategory = prvalue(load)
24496+
# 2766| getQualifier().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
24497+
# 2766| Type = [Class] ThreeWay
24498+
# 2766| ValueCategory = lvalue
24499+
# 2769| [TopLevelFunction] void test_three_way(int, int, ThreeWay, ThreeWay)
24500+
# 2769| <params>:
24501+
# 2769| getParameter(0): [Parameter] a
24502+
# 2769| Type = [IntType] int
24503+
# 2769| getParameter(1): [Parameter] b
24504+
# 2769| Type = [IntType] int
24505+
# 2769| getParameter(2): [Parameter] c
24506+
# 2769| Type = [Class] ThreeWay
24507+
# 2769| getParameter(3): [Parameter] d
24508+
# 2769| Type = [Class] ThreeWay
24509+
# 2769| getEntryPoint(): [BlockStmt] { ... }
24510+
# 2770| getStmt(0): [DeclStmt] declaration
24511+
# 2770| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x
24512+
# 2770| Type = [Class] strong_ordering
24513+
# 2770| getVariable().getInitializer(): [Initializer] initializer for x
24514+
# 2770| getExpr(): [SpaceshipExpr] ... <=> ...
24515+
# 2770| Type = [Class] strong_ordering
24516+
# 2770| ValueCategory = prvalue
24517+
# 2770| getChild(0): [VariableAccess] a
24518+
# 2770| Type = [IntType] int
24519+
# 2770| ValueCategory = prvalue(load)
24520+
# 2770| getChild(1): [VariableAccess] b
24521+
# 2770| Type = [IntType] int
24522+
# 2770| ValueCategory = prvalue(load)
24523+
# 2771| getStmt(1): [DeclStmt] declaration
24524+
# 2771| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y
24525+
# 2771| Type = [Class] strong_ordering
24526+
# 2771| getVariable().getInitializer(): [Initializer] initializer for y
24527+
# 2771| getExpr(): [FunctionCall] call to operator<=>
24528+
# 2771| Type = [Class] strong_ordering
24529+
# 2771| ValueCategory = prvalue
24530+
# 2771| getQualifier(): [VariableAccess] c
24531+
# 2771| Type = [Class] ThreeWay
24532+
# 2771| ValueCategory = lvalue
24533+
# 2771| getArgument(0): [VariableAccess] d
24534+
# 2771| Type = [Class] ThreeWay
24535+
# 2771| ValueCategory = lvalue
24536+
# 2771| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to)
24537+
# 2771| Type = [LValueReferenceType] ThreeWay &
24538+
# 2771| ValueCategory = prvalue
24539+
# 2772| getStmt(2): [ReturnStmt] return ...
2443924540
ir23.cpp:
2444024541
# 1| [TopLevelFunction] bool consteval_1()
2444124542
# 1| <params>:

cpp/ql/test/library-tests/ir/ir/aliased_ir.expected

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20273,6 +20273,90 @@ ir.cpp:
2027320273
# 2728| v2728_14(void) = AliasedUse : ~m2728_9
2027420274
# 2728| v2728_15(void) = ExitFunction :
2027520275

20276+
# 2747| void std::strong_ordering::strong_ordering(std::strong_ordering&&)
20277+
# 2747| Block 0
20278+
# 2747| v2747_1(void) = EnterFunction :
20279+
# 2747| m2747_2(unknown) = AliasedDefinition :
20280+
# 2747| m2747_3(unknown) = InitializeNonLocal :
20281+
# 2747| m2747_4(unknown) = Chi : total:m2747_2, partial:m2747_3
20282+
# 2747| r2747_5(glval<unknown>) = VariableAddress[#this] :
20283+
# 2747| m2747_6(glval<strong_ordering>) = InitializeParameter[#this] : &:r2747_5
20284+
# 2747| r2747_7(glval<strong_ordering>) = Load[#this] : &:r2747_5, m2747_6
20285+
# 2747| m2747_8(strong_ordering) = InitializeIndirection[#this] : &:r2747_7
20286+
#-----| r0_1(glval<strong_ordering &&>) = VariableAddress[(unnamed parameter 0)] :
20287+
#-----| m0_2(strong_ordering &&) = InitializeParameter[(unnamed parameter 0)] : &:r0_1
20288+
#-----| r0_3(strong_ordering &&) = Load[(unnamed parameter 0)] : &:r0_1, m0_2
20289+
#-----| m0_4(unknown) = InitializeIndirection[(unnamed parameter 0)] : &:r0_3
20290+
# 2747| v2747_9(void) = NoOp :
20291+
# 2747| v2747_10(void) = ReturnIndirection[#this] : &:r2747_7, m2747_8
20292+
#-----| v0_5(void) = ReturnIndirection[(unnamed parameter 0)] : &:r0_3, m0_4
20293+
# 2747| v2747_11(void) = ReturnVoid :
20294+
# 2747| v2747_12(void) = AliasedUse : m2747_3
20295+
# 2747| v2747_13(void) = ExitFunction :
20296+
20297+
# 2748| void std::strong_ordering::strong_ordering(std::_Order)
20298+
# 2748| Block 0
20299+
# 2748| v2748_1(void) = EnterFunction :
20300+
# 2748| m2748_2(unknown) = AliasedDefinition :
20301+
# 2748| m2748_3(unknown) = InitializeNonLocal :
20302+
# 2748| m2748_4(unknown) = Chi : total:m2748_2, partial:m2748_3
20303+
# 2748| r2748_5(glval<unknown>) = VariableAddress[#this] :
20304+
# 2748| m2748_6(glval<strong_ordering>) = InitializeParameter[#this] : &:r2748_5
20305+
# 2748| r2748_7(glval<strong_ordering>) = Load[#this] : &:r2748_5, m2748_6
20306+
# 2748| m2748_8(strong_ordering) = InitializeIndirection[#this] : &:r2748_7
20307+
# 2748| r2748_9(glval<_Order>) = VariableAddress[v] :
20308+
# 2748| m2748_10(_Order) = InitializeParameter[v] : &:r2748_9
20309+
# 2748| v2748_11(void) = NoOp :
20310+
# 2748| v2748_12(void) = ReturnIndirection[#this] : &:r2748_7, m2748_8
20311+
# 2748| v2748_13(void) = ReturnVoid :
20312+
# 2748| v2748_14(void) = AliasedUse : m2748_3
20313+
# 2748| v2748_15(void) = ExitFunction :
20314+
20315+
# 2766| std::strong_ordering ThreeWay::operator<=>(ThreeWay&)
20316+
# 2766| Block 0
20317+
# 2766| v2766_1(void) = EnterFunction :
20318+
# 2766| m2766_2(unknown) = AliasedDefinition :
20319+
# 2766| m2766_3(unknown) = InitializeNonLocal :
20320+
# 2766| m2766_4(unknown) = Chi : total:m2766_2, partial:m2766_3
20321+
# 2766| r2766_5(glval<unknown>) = VariableAddress[#this] :
20322+
# 2766| m2766_6(glval<ThreeWay>) = InitializeParameter[#this] : &:r2766_5
20323+
# 2766| r2766_7(glval<ThreeWay>) = Load[#this] : &:r2766_5, m2766_6
20324+
# 2766| m2766_8(ThreeWay) = InitializeIndirection[#this] : &:r2766_7
20325+
# 2766| r2766_9(glval<ThreeWay &>) = VariableAddress[y] :
20326+
# 2766| m2766_10(ThreeWay &) = InitializeParameter[y] : &:r2766_9
20327+
# 2766| r2766_11(ThreeWay &) = Load[y] : &:r2766_9, m2766_10
20328+
# 2766| m2766_12(unknown) = InitializeIndirection[y] : &:r2766_11
20329+
# 2766| r2766_13(glval<strong_ordering>) = VariableAddress[#return] :
20330+
# 2766| r2766_14(glval<unknown>) = VariableAddress[#this] :
20331+
# 2766| r2766_15(ThreeWay *) = Load[#this] : &:r2766_14, m2766_6
20332+
# 2766| r2766_16(glval<int>) = FieldAddress[x] : r2766_15
20333+
# 2766| r2766_17(int) = Load[?] : &:r2766_16, ~m2766_8
20334+
# 2766| r2766_18(glval<ThreeWay &>) = VariableAddress[y] :
20335+
# 2766| r2766_19(ThreeWay &) = Load[y] : &:r2766_18, m2766_10
20336+
# 2766| r2766_20(glval<ThreeWay>) = CopyValue : r2766_19
20337+
# 2766| r2766_21(glval<int>) = FieldAddress[x] : r2766_20
20338+
# 2766| r2766_22(int) = Load[?] : &:r2766_21, ~m2766_12
20339+
20340+
# 2769| void test_three_way(int, int, ThreeWay, ThreeWay)
20341+
# 2769| Block 0
20342+
# 2769| v2769_1(void) = EnterFunction :
20343+
# 2769| m2769_2(unknown) = AliasedDefinition :
20344+
# 2769| m2769_3(unknown) = InitializeNonLocal :
20345+
# 2769| m2769_4(unknown) = Chi : total:m2769_2, partial:m2769_3
20346+
# 2769| r2769_5(glval<int>) = VariableAddress[a] :
20347+
# 2769| m2769_6(int) = InitializeParameter[a] : &:r2769_5
20348+
# 2769| r2769_7(glval<int>) = VariableAddress[b] :
20349+
# 2769| m2769_8(int) = InitializeParameter[b] : &:r2769_7
20350+
# 2769| r2769_9(glval<ThreeWay>) = VariableAddress[c] :
20351+
# 2769| m2769_10(ThreeWay) = InitializeParameter[c] : &:r2769_9
20352+
# 2769| r2769_11(glval<ThreeWay>) = VariableAddress[d] :
20353+
# 2769| m2769_12(ThreeWay) = InitializeParameter[d] : &:r2769_11
20354+
# 2770| r2770_1(glval<strong_ordering>) = VariableAddress[x] :
20355+
# 2770| r2770_2(glval<int>) = VariableAddress[a] :
20356+
# 2770| r2770_3(int) = Load[a] : &:r2770_2, m2769_6
20357+
# 2770| r2770_4(glval<int>) = VariableAddress[b] :
20358+
# 2770| r2770_5(int) = Load[b] : &:r2770_4, m2769_8
20359+
2027620360
ir23.cpp:
2027720361
# 1| bool consteval_1()
2027820362
# 1| Block 0

cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ missingOperandType
66
duplicateChiOperand
77
sideEffectWithoutPrimary
88
instructionWithoutSuccessor
9+
| ir.cpp:2766:72:2766:72 | Load: x | Instruction 'Load: x' has no successors in function '$@'. | ir.cpp:2766:24:2766:34 | std::strong_ordering ThreeWay::operator<=>(ThreeWay&) | std::strong_ordering ThreeWay::operator<=>(ThreeWay&) |
10+
| ir.cpp:2770:18:2770:18 | Load: b | Instruction 'Load: b' has no successors in function '$@'. | ir.cpp:2769:6:2769:19 | void test_three_way(int, int, ThreeWay, ThreeWay) | void test_three_way(int, int, ThreeWay, ThreeWay) |
911
ambiguousSuccessors
1012
unexplainedLoop
1113
unnecessaryPhiInstruction

cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency_unsound.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ missingOperandType
66
duplicateChiOperand
77
sideEffectWithoutPrimary
88
instructionWithoutSuccessor
9+
| ir.cpp:2766:72:2766:72 | Load: x | Instruction 'Load: x' has no successors in function '$@'. | ir.cpp:2766:24:2766:34 | std::strong_ordering ThreeWay::operator<=>(ThreeWay&) | std::strong_ordering ThreeWay::operator<=>(ThreeWay&) |
10+
| ir.cpp:2770:18:2770:18 | Load: b | Instruction 'Load: b' has no successors in function '$@'. | ir.cpp:2769:6:2769:19 | void test_three_way(int, int, ThreeWay, ThreeWay) | void test_three_way(int, int, ThreeWay, ThreeWay) |
911
ambiguousSuccessors
1012
unexplainedLoop
1113
unnecessaryPhiInstruction

cpp/ql/test/library-tests/ir/ir/ir.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2742,4 +2742,33 @@ void test_postfix_crement(int *p, int q) {
27422742
int q2 = (int)(q++);
27432743
}
27442744

2745+
namespace std {
2746+
enum class _Order : signed char { __less = -1, __equiv = 0, __greater = 1 };
2747+
class strong_ordering {
2748+
explicit constexpr strong_ordering(_Order v) {}
2749+
2750+
public:
2751+
static const strong_ordering less;
2752+
static const strong_ordering equal;
2753+
static const strong_ordering equivalent;
2754+
static const strong_ordering greater;
2755+
};
2756+
2757+
inline constexpr strong_ordering strong_ordering::less(_Order::__less);
2758+
inline constexpr strong_ordering strong_ordering::equal(_Order::__equiv);
2759+
inline constexpr strong_ordering strong_ordering::equivalent(_Order::__equiv);
2760+
inline constexpr strong_ordering strong_ordering::greater(_Order::__greater);
2761+
}
2762+
2763+
class ThreeWay {
2764+
int x;
2765+
public:
2766+
std::strong_ordering operator<=>(ThreeWay &y) { return this->x <=> y.x; }
2767+
};
2768+
2769+
void test_three_way(int a, int b, ThreeWay c, ThreeWay d) {
2770+
auto x = a <=> b;
2771+
auto y = c <=> d;
2772+
}
2773+
27452774
// semmle-extractor-options: -std=c++20 --clang

cpp/ql/test/library-tests/ir/ir/raw_consistency.expected

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
missingOperand
2+
| ir.cpp:2766:58:2766:72 | Store: ... <=> ... | Instruction 'Store' is missing an expected operand with tag 'StoreValue' in function '$@'. | ir.cpp:2766:24:2766:34 | std::strong_ordering ThreeWay::operator<=>(ThreeWay&) | std::strong_ordering ThreeWay::operator<=>(ThreeWay&) |
3+
| ir.cpp:2770:12:2770:18 | Store: ... <=> ... | Instruction 'Store' is missing an expected operand with tag 'StoreValue' in function '$@'. | ir.cpp:2769:6:2769:19 | void test_three_way(int, int, ThreeWay, ThreeWay) | void test_three_way(int, int, ThreeWay, ThreeWay) |
24
unexpectedOperand
35
duplicateOperand
46
missingPhiOperand
57
missingOperandType
68
duplicateChiOperand
79
sideEffectWithoutPrimary
810
instructionWithoutSuccessor
11+
| ir.cpp:2766:72:2766:72 | Load: x | Instruction 'Load: x' has no successors in function '$@'. | ir.cpp:2766:24:2766:34 | std::strong_ordering ThreeWay::operator<=>(ThreeWay&) | std::strong_ordering ThreeWay::operator<=>(ThreeWay&) |
12+
| ir.cpp:2770:18:2770:18 | Load: b | Instruction 'Load: b' has no successors in function '$@'. | ir.cpp:2769:6:2769:19 | void test_three_way(int, int, ThreeWay, ThreeWay) | void test_three_way(int, int, ThreeWay, ThreeWay) |
913
ambiguousSuccessors
1014
unexplainedLoop
1115
unnecessaryPhiInstruction
@@ -21,6 +25,10 @@ lostReachability
2125
backEdgeCountMismatch
2226
useNotDominatedByDefinition
2327
| ir.cpp:1535:8:1535:8 | Unary | Operand 'Unary' is not dominated by its definition in function '$@'. | ir.cpp:1535:8:1535:8 | void StructuredBindingDataMemberStruct::StructuredBindingDataMemberStruct() | void StructuredBindingDataMemberStruct::StructuredBindingDataMemberStruct() |
28+
| ir.cpp:2766:24:2766:34 | Address | Operand 'Address' is not dominated by its definition in function '$@'. | ir.cpp:2766:24:2766:34 | std::strong_ordering ThreeWay::operator<=>(ThreeWay&) | std::strong_ordering ThreeWay::operator<=>(ThreeWay&) |
29+
| ir.cpp:2766:46:2766:46 | Address | Operand 'Address' is not dominated by its definition in function '$@'. | ir.cpp:2766:24:2766:34 | std::strong_ordering ThreeWay::operator<=>(ThreeWay&) | std::strong_ordering ThreeWay::operator<=>(ThreeWay&) |
30+
| ir.cpp:2766:51:2766:73 | Address | Operand 'Address' is not dominated by its definition in function '$@'. | ir.cpp:2766:24:2766:34 | std::strong_ordering ThreeWay::operator<=>(ThreeWay&) | std::strong_ordering ThreeWay::operator<=>(ThreeWay&) |
31+
| ir.cpp:2770:8:2770:8 | Address | Operand 'Address' is not dominated by its definition in function '$@'. | ir.cpp:2769:6:2769:19 | void test_three_way(int, int, ThreeWay, ThreeWay) | void test_three_way(int, int, ThreeWay, ThreeWay) |
2432
switchInstructionWithoutDefaultEdge
2533
notMarkedAsConflated
2634
wronglyMarkedAsConflated

0 commit comments

Comments
 (0)