[clang] [clang][Interp] Three-way comparisons (PR #65901)
https://github.com/tbaederr closed https://github.com/llvm/llvm-project/pull/65901 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Three-way comparisons (PR #65901)
https://github.com/erichkeane approved this pull request. https://github.com/llvm/llvm-project/pull/65901 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Three-way comparisons (PR #65901)
https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/65901 >From 5dc457a45bdf8366a5f8e5d7df7bcf3383120ecd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Sun, 10 Sep 2023 17:02:22 +0200 Subject: [PATCH] [clang][Interp] Three-way comparisons --- clang/lib/AST/Interp/Boolean.h | 6 +++ clang/lib/AST/Interp/ByteCodeExprGen.cpp | 23 ++ clang/lib/AST/Interp/Floating.h | 6 +++ clang/lib/AST/Interp/Integral.h | 7 +++ clang/lib/AST/Interp/Interp.h| 29 + clang/lib/AST/Interp/InterpBuiltin.cpp | 17 clang/lib/AST/Interp/Opcodes.td | 5 +++ clang/lib/AST/Interp/Pointer.h | 13 ++ clang/test/AST/Interp/cxx20.cpp | 54 9 files changed, 160 insertions(+) diff --git a/clang/lib/AST/Interp/Boolean.h b/clang/lib/AST/Interp/Boolean.h index 6f0fe26ace68807..c3ed3d61f76ca1c 100644 --- a/clang/lib/AST/Interp/Boolean.h +++ b/clang/lib/AST/Interp/Boolean.h @@ -84,6 +84,12 @@ class Boolean final { Boolean truncate(unsigned TruncBits) const { return *this; } void print(llvm::raw_ostream ) const { OS << (V ? "true" : "false"); } + std::string toDiagnosticString(const ASTContext ) const { +std::string NameStr; +llvm::raw_string_ostream OS(NameStr); +print(OS); +return NameStr; + } static Boolean min(unsigned NumBits) { return Boolean(false); } static Boolean max(unsigned NumBits) { return Boolean(true); } diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index e813d4fa651ceaf..a09e2a007b912c9 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -253,6 +253,29 @@ bool ByteCodeExprGen::VisitBinaryOperator(const BinaryOperator *BO) { return this->delegate(RHS); } + // Special case for C++'s three-way/spaceship operator <=>, which + // returns a std::{strong,weak,partial}_ordering (which is a class, so doesn't + // have a PrimType). + if (!T) { +if (DiscardResult) + return true; +const ComparisonCategoryInfo *CmpInfo = +Ctx.getASTContext().CompCategories.lookupInfoForType(BO->getType()); +assert(CmpInfo); + +// We need a temporary variable holding our return value. +if (!Initializing) { + std::optional ResultIndex = this->allocateLocal(BO, false); + if (!this->emitGetPtrLocal(*ResultIndex, BO)) +return false; +} + +if (!visit(LHS) || !visit(RHS)) + return false; + +return this->emitCMP3(*LT, CmpInfo, BO); + } + if (!LT || !RT || !T) return this->bail(BO); diff --git a/clang/lib/AST/Interp/Floating.h b/clang/lib/AST/Interp/Floating.h index 9a8fd34ec934893..a22b3fa79f3992f 100644 --- a/clang/lib/AST/Interp/Floating.h +++ b/clang/lib/AST/Interp/Floating.h @@ -76,6 +76,12 @@ class Floating final { F.toString(Buffer); OS << Buffer; } + std::string toDiagnosticString(const ASTContext ) const { +std::string NameStr; +llvm::raw_string_ostream OS(NameStr); +print(OS); +return NameStr; + } unsigned bitWidth() const { return F.semanticsSizeInBits(F.getSemantics()); } diff --git a/clang/lib/AST/Interp/Integral.h b/clang/lib/AST/Interp/Integral.h index 72285cabcbbf8ce..0295a9c3b5c898c 100644 --- a/clang/lib/AST/Interp/Integral.h +++ b/clang/lib/AST/Interp/Integral.h @@ -128,6 +128,13 @@ template class Integral final { return Compare(V, RHS.V); } + std::string toDiagnosticString(const ASTContext ) const { +std::string NameStr; +llvm::raw_string_ostream OS(NameStr); +OS << V; +return NameStr; + } + unsigned countLeadingZeros() const { if constexpr (!Signed) return llvm::countl_zero(V); diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index 8453856e526a6b2..dd37150b63f6db0 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -112,6 +112,11 @@ bool CheckCtorCall(InterpState , CodePtr OpPC, const Pointer ); bool CheckPotentialReinterpretCast(InterpState , CodePtr OpPC, const Pointer ); +/// Sets the given integral value to the pointer, which is of +/// a std::{weak,partial,strong}_ordering type. +bool SetThreeWayComparisonField(InterpState , CodePtr OpPC, +const Pointer , const APSInt ); + /// Checks if the shift operation is legal. template bool CheckShift(InterpState , CodePtr OpPC, const LT , const RT , @@ -781,6 +786,30 @@ bool EQ(InterpState , CodePtr OpPC) { }); } +template ::T> +bool CMP3(InterpState , CodePtr OpPC, const ComparisonCategoryInfo *CmpInfo) { + const T = S.Stk.pop(); + const T = S.Stk.pop(); + const Pointer = S.Stk.peek(); + + ComparisonCategoryResult CmpResult = LHS.compare(RHS); + if (CmpResult == ComparisonCategoryResult::Unordered) { +// This should only happen with pointers. +const
[clang] [clang][Interp] Three-way comparisons (PR #65901)
https://github.com/tbaederr resolved https://github.com/llvm/llvm-project/pull/65901 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Three-way comparisons (PR #65901)
@@ -253,6 +253,29 @@ bool ByteCodeExprGen::VisitBinaryOperator(const BinaryOperator *BO) { return this->delegate(RHS); } + // Special case for C++'s three-way/spaceship operator <=>, which + // returns a std::strong_ordering (which is class, so doesn't have a tbaederr wrote: Right, I wrote that comment for the first test case I had. Updated it, thanks. https://github.com/llvm/llvm-project/pull/65901 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Three-way comparisons (PR #65901)
https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/65901 >From 0c61a3cd0d02e70bc1cedf048e73af50caf65bd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Sun, 10 Sep 2023 17:02:22 +0200 Subject: [PATCH] [clang][Interp] Three-way comparisons --- clang/lib/AST/Interp/Boolean.h | 6 +++ clang/lib/AST/Interp/ByteCodeExprGen.cpp | 23 ++ clang/lib/AST/Interp/Floating.h | 6 +++ clang/lib/AST/Interp/Integral.h | 7 +++ clang/lib/AST/Interp/Interp.h| 29 + clang/lib/AST/Interp/InterpBuiltin.cpp | 17 clang/lib/AST/Interp/Opcodes.td | 5 +++ clang/lib/AST/Interp/Pointer.h | 13 ++ clang/test/AST/Interp/cxx20.cpp | 54 9 files changed, 160 insertions(+) diff --git a/clang/lib/AST/Interp/Boolean.h b/clang/lib/AST/Interp/Boolean.h index 6f0fe26ace68807..c3ed3d61f76ca1c 100644 --- a/clang/lib/AST/Interp/Boolean.h +++ b/clang/lib/AST/Interp/Boolean.h @@ -84,6 +84,12 @@ class Boolean final { Boolean truncate(unsigned TruncBits) const { return *this; } void print(llvm::raw_ostream ) const { OS << (V ? "true" : "false"); } + std::string toDiagnosticString(const ASTContext ) const { +std::string NameStr; +llvm::raw_string_ostream OS(NameStr); +print(OS); +return NameStr; + } static Boolean min(unsigned NumBits) { return Boolean(false); } static Boolean max(unsigned NumBits) { return Boolean(true); } diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index e813d4fa651ceaf..f18b969805b373e 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -253,6 +253,29 @@ bool ByteCodeExprGen::VisitBinaryOperator(const BinaryOperator *BO) { return this->delegate(RHS); } + // Special case for C++'s three-way/spaceship operator <=>, which + // returns a std::{strong,weak,partial}_ordering (which is class, so doesn't + // have a PrimType). + if (!T) { +if (DiscardResult) + return true; +const ComparisonCategoryInfo *CmpInfo = +Ctx.getASTContext().CompCategories.lookupInfoForType(BO->getType()); +assert(CmpInfo); + +// We need a temporary variable holding our return value. +if (!Initializing) { + std::optional ResultIndex = this->allocateLocal(BO, false); + if (!this->emitGetPtrLocal(*ResultIndex, BO)) +return false; +} + +if (!visit(LHS) || !visit(RHS)) + return false; + +return this->emitCMP3(*LT, CmpInfo, BO); + } + if (!LT || !RT || !T) return this->bail(BO); diff --git a/clang/lib/AST/Interp/Floating.h b/clang/lib/AST/Interp/Floating.h index 9a8fd34ec934893..a22b3fa79f3992f 100644 --- a/clang/lib/AST/Interp/Floating.h +++ b/clang/lib/AST/Interp/Floating.h @@ -76,6 +76,12 @@ class Floating final { F.toString(Buffer); OS << Buffer; } + std::string toDiagnosticString(const ASTContext ) const { +std::string NameStr; +llvm::raw_string_ostream OS(NameStr); +print(OS); +return NameStr; + } unsigned bitWidth() const { return F.semanticsSizeInBits(F.getSemantics()); } diff --git a/clang/lib/AST/Interp/Integral.h b/clang/lib/AST/Interp/Integral.h index 72285cabcbbf8ce..0295a9c3b5c898c 100644 --- a/clang/lib/AST/Interp/Integral.h +++ b/clang/lib/AST/Interp/Integral.h @@ -128,6 +128,13 @@ template class Integral final { return Compare(V, RHS.V); } + std::string toDiagnosticString(const ASTContext ) const { +std::string NameStr; +llvm::raw_string_ostream OS(NameStr); +OS << V; +return NameStr; + } + unsigned countLeadingZeros() const { if constexpr (!Signed) return llvm::countl_zero(V); diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index 8453856e526a6b2..dd37150b63f6db0 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -112,6 +112,11 @@ bool CheckCtorCall(InterpState , CodePtr OpPC, const Pointer ); bool CheckPotentialReinterpretCast(InterpState , CodePtr OpPC, const Pointer ); +/// Sets the given integral value to the pointer, which is of +/// a std::{weak,partial,strong}_ordering type. +bool SetThreeWayComparisonField(InterpState , CodePtr OpPC, +const Pointer , const APSInt ); + /// Checks if the shift operation is legal. template bool CheckShift(InterpState , CodePtr OpPC, const LT , const RT , @@ -781,6 +786,30 @@ bool EQ(InterpState , CodePtr OpPC) { }); } +template ::T> +bool CMP3(InterpState , CodePtr OpPC, const ComparisonCategoryInfo *CmpInfo) { + const T = S.Stk.pop(); + const T = S.Stk.pop(); + const Pointer = S.Stk.peek(); + + ComparisonCategoryResult CmpResult = LHS.compare(RHS); + if (CmpResult == ComparisonCategoryResult::Unordered) { +// This should only happen with pointers. +const
[clang] [clang][Interp] Three-way comparisons (PR #65901)
https://github.com/erichkeane edited https://github.com/llvm/llvm-project/pull/65901 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Three-way comparisons (PR #65901)
@@ -253,6 +253,29 @@ bool ByteCodeExprGen::VisitBinaryOperator(const BinaryOperator *BO) { return this->delegate(RHS); } + // Special case for C++'s three-way/spaceship operator <=>, which + // returns a std::strong_ordering (which is class, so doesn't have a erichkeane wrote: So this isn't really true, see the rules here: https://en.cppreference.com/w/cpp/language/default_comparisons It can end up returning a `std::weak_ordering` or `std::partial_ordering` as well. The rest here is true, but I wanted to make sure you know, since these have slightly different semantics that I don't see handled here? https://github.com/llvm/llvm-project/pull/65901 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Three-way comparisons (PR #65901)
@@ -253,6 +253,29 @@ bool ByteCodeExprGen::VisitBinaryOperator(const BinaryOperator *BO) { return this->delegate(RHS); } + // Special case for C++'s three-way/spaceship operator <=>, which + // returns a std::strong_ordering (which is class, so doesn't have a erichkeane wrote: I already put that up, but I see lower you refer to all 3, so this is just a request to modify that comment as necessary. https://github.com/llvm/llvm-project/pull/65901 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Three-way comparisons (PR #65901)
https://github.com/erichkeane commented: This has been sitting a while, else I wouldn't feel comfortable reviewing (as I haven't been keeping up on these as much as I should have). However, I saw 1 issue with the comment I think, else I'm OK with this. So if you can fix that, I'll approve. https://github.com/llvm/llvm-project/pull/65901 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Three-way comparisons (PR #65901)
tbaederr wrote: Ping https://github.com/llvm/llvm-project/pull/65901 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Three-way comparisons (PR #65901)
tbaederr wrote: Ping https://github.com/llvm/llvm-project/pull/65901 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Three-way comparisons (PR #65901)
https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/65901 >From 1b76f3b46359c7a688bc5cefc15254253fb57e64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Sun, 10 Sep 2023 17:02:22 +0200 Subject: [PATCH] [clang][Interp] Three-way comparisons --- clang/lib/AST/Interp/Boolean.h | 6 +++ clang/lib/AST/Interp/ByteCodeExprGen.cpp | 23 ++ clang/lib/AST/Interp/Floating.h | 6 +++ clang/lib/AST/Interp/Integral.h | 7 +++ clang/lib/AST/Interp/Interp.h| 29 + clang/lib/AST/Interp/InterpBuiltin.cpp | 17 clang/lib/AST/Interp/Opcodes.td | 5 +++ clang/lib/AST/Interp/Pointer.h | 13 ++ clang/test/AST/Interp/cxx20.cpp | 54 9 files changed, 160 insertions(+) diff --git a/clang/lib/AST/Interp/Boolean.h b/clang/lib/AST/Interp/Boolean.h index 6f0fe26ace68807..c3ed3d61f76ca1c 100644 --- a/clang/lib/AST/Interp/Boolean.h +++ b/clang/lib/AST/Interp/Boolean.h @@ -84,6 +84,12 @@ class Boolean final { Boolean truncate(unsigned TruncBits) const { return *this; } void print(llvm::raw_ostream ) const { OS << (V ? "true" : "false"); } + std::string toDiagnosticString(const ASTContext ) const { +std::string NameStr; +llvm::raw_string_ostream OS(NameStr); +print(OS); +return NameStr; + } static Boolean min(unsigned NumBits) { return Boolean(false); } static Boolean max(unsigned NumBits) { return Boolean(true); } diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 823bef7a8c19e11..a33dfee0b229ac6 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -253,6 +253,29 @@ bool ByteCodeExprGen::VisitBinaryOperator(const BinaryOperator *BO) { return this->delegate(RHS); } + // Special case for C++'s three-way/spaceship operator <=>, which + // returns a std::strong_ordering (which is class, so doesn't have a + // PrimType). + if (!T) { +if (DiscardResult) + return true; +const ComparisonCategoryInfo *CmpInfo = +Ctx.getASTContext().CompCategories.lookupInfoForType(BO->getType()); +assert(CmpInfo); + +// We need a temporary variable holding our return value. +if (!Initializing) { + std::optional ResultIndex = this->allocateLocal(BO, false); + if (!this->emitGetPtrLocal(*ResultIndex, BO)) +return false; +} + +if (!visit(LHS) || !visit(RHS)) + return false; + +return this->emitCMP3(*LT, CmpInfo, BO); + } + if (!LT || !RT || !T) return this->bail(BO); diff --git a/clang/lib/AST/Interp/Floating.h b/clang/lib/AST/Interp/Floating.h index 9a8fd34ec934893..a22b3fa79f3992f 100644 --- a/clang/lib/AST/Interp/Floating.h +++ b/clang/lib/AST/Interp/Floating.h @@ -76,6 +76,12 @@ class Floating final { F.toString(Buffer); OS << Buffer; } + std::string toDiagnosticString(const ASTContext ) const { +std::string NameStr; +llvm::raw_string_ostream OS(NameStr); +print(OS); +return NameStr; + } unsigned bitWidth() const { return F.semanticsSizeInBits(F.getSemantics()); } diff --git a/clang/lib/AST/Interp/Integral.h b/clang/lib/AST/Interp/Integral.h index 72285cabcbbf8ce..0295a9c3b5c898c 100644 --- a/clang/lib/AST/Interp/Integral.h +++ b/clang/lib/AST/Interp/Integral.h @@ -128,6 +128,13 @@ template class Integral final { return Compare(V, RHS.V); } + std::string toDiagnosticString(const ASTContext ) const { +std::string NameStr; +llvm::raw_string_ostream OS(NameStr); +OS << V; +return NameStr; + } + unsigned countLeadingZeros() const { if constexpr (!Signed) return llvm::countl_zero(V); diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index 8453856e526a6b2..dd37150b63f6db0 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -112,6 +112,11 @@ bool CheckCtorCall(InterpState , CodePtr OpPC, const Pointer ); bool CheckPotentialReinterpretCast(InterpState , CodePtr OpPC, const Pointer ); +/// Sets the given integral value to the pointer, which is of +/// a std::{weak,partial,strong}_ordering type. +bool SetThreeWayComparisonField(InterpState , CodePtr OpPC, +const Pointer , const APSInt ); + /// Checks if the shift operation is legal. template bool CheckShift(InterpState , CodePtr OpPC, const LT , const RT , @@ -781,6 +786,30 @@ bool EQ(InterpState , CodePtr OpPC) { }); } +template ::T> +bool CMP3(InterpState , CodePtr OpPC, const ComparisonCategoryInfo *CmpInfo) { + const T = S.Stk.pop(); + const T = S.Stk.pop(); + const Pointer = S.Stk.peek(); + + ComparisonCategoryResult CmpResult = LHS.compare(RHS); + if (CmpResult == ComparisonCategoryResult::Unordered) { +// This should only happen with pointers. +const SourceInfo =
[clang] [clang][Interp] Three-way comparisons (PR #65901)
llvmbot wrote: @llvm/pr-subscribers-clang Changes None -- Full diff: https://github.com/llvm/llvm-project/pull/65901.diff 9 Files Affected: - (modified) clang/lib/AST/Interp/Boolean.h (+6) - (modified) clang/lib/AST/Interp/ByteCodeExprGen.cpp (+23) - (modified) clang/lib/AST/Interp/Floating.h (+6) - (modified) clang/lib/AST/Interp/Integral.h (+7) - (modified) clang/lib/AST/Interp/Interp.h (+29) - (modified) clang/lib/AST/Interp/InterpBuiltin.cpp (+17) - (modified) clang/lib/AST/Interp/Opcodes.td (+5) - (modified) clang/lib/AST/Interp/Pointer.h (+13) - (modified) clang/test/AST/Interp/cxx20.cpp (+54) diff --git a/clang/lib/AST/Interp/Boolean.h b/clang/lib/AST/Interp/Boolean.h index 6f0fe26ace68807..c3ed3d61f76ca1c 100644 --- a/clang/lib/AST/Interp/Boolean.h +++ b/clang/lib/AST/Interp/Boolean.h @@ -84,6 +84,12 @@ class Boolean final { Boolean truncate(unsigned TruncBits) const { return *this; } void print(llvm::raw_ostream ) const { OS << (V ? "true" : "false"); } + std::string toDiagnosticString(const ASTContext ) const { +std::string NameStr; +llvm::raw_string_ostream OS(NameStr); +print(OS); +return NameStr; + } static Boolean min(unsigned NumBits) { return Boolean(false); } static Boolean max(unsigned NumBits) { return Boolean(true); } diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 6a492c4c907cde0..47e070285aebd67 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -261,6 +261,29 @@ bool ByteCodeExprGen::VisitBinaryOperator(const BinaryOperator *BO) { : this->visit(RHS)); } + // Special case for C++'s three-way/spaceship operator <=>, which + // returns a std::strong_ordering (which is class, so doesn't have a + // PrimType). + if (!T) { +if (DiscardResult) + return true; +const ComparisonCategoryInfo *CmpInfo = +Ctx.getASTContext().CompCategories.lookupInfoForType(BO->getType()); +assert(CmpInfo); + +// We need a temporary variable holding our return value. +if (!Initializing) { + std::optional ResultIndex = this->allocateLocal(BO, false); + if (!this->emitGetPtrLocal(*ResultIndex, BO)) +return false; +} + +if (!visit(LHS) || !visit(RHS)) + return false; + +return this->emitCMP3(*LT, CmpInfo, BO); + } + if (!LT || !RT || !T) return this->bail(BO); diff --git a/clang/lib/AST/Interp/Floating.h b/clang/lib/AST/Interp/Floating.h index 9a8fd34ec934893..a22b3fa79f3992f 100644 --- a/clang/lib/AST/Interp/Floating.h +++ b/clang/lib/AST/Interp/Floating.h @@ -76,6 +76,12 @@ class Floating final { F.toString(Buffer); OS << Buffer; } + std::string toDiagnosticString(const ASTContext ) const { +std::string NameStr; +llvm::raw_string_ostream OS(NameStr); +print(OS); +return NameStr; + } unsigned bitWidth() const { return F.semanticsSizeInBits(F.getSemantics()); } diff --git a/clang/lib/AST/Interp/Integral.h b/clang/lib/AST/Interp/Integral.h index 72285cabcbbf8ce..0295a9c3b5c898c 100644 --- a/clang/lib/AST/Interp/Integral.h +++ b/clang/lib/AST/Interp/Integral.h @@ -128,6 +128,13 @@ template class Integral final { return Compare(V, RHS.V); } + std::string toDiagnosticString(const ASTContext ) const { +std::string NameStr; +llvm::raw_string_ostream OS(NameStr); +OS << V; +return NameStr; + } + unsigned countLeadingZeros() const { if constexpr (!Signed) return llvm::countl_zero(V); diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index 5006f72fe7237f5..14f23e84386d0fd 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -112,6 +112,11 @@ bool CheckCtorCall(InterpState , CodePtr OpPC, const Pointer ); bool CheckPotentialReinterpretCast(InterpState , CodePtr OpPC, const Pointer ); +/// Sets the given integral value to the pointer, which is of +/// a std::{weak,partial,strong}_ordering type. +bool SetThreeWayComparisonField(InterpState , CodePtr OpPC, +const Pointer , const APSInt ); + /// Checks if the shift operation is legal. template bool CheckShift(InterpState , CodePtr OpPC, const LT , const RT , @@ -773,6 +778,30 @@ bool EQ(InterpState , CodePtr OpPC) { }); } +template ::T> +bool CMP3(InterpState , CodePtr OpPC, const ComparisonCategoryInfo *CmpInfo) { + const T = S.Stk.pop(); + const T = S.Stk.pop(); + const Pointer = S.Stk.peek(); + + ComparisonCategoryResult CmpResult = LHS.compare(RHS); + if (CmpResult == ComparisonCategoryResult::Unordered) { +// This should only happen with pointers. +const SourceInfo = S.Current->getSource(OpPC); +S.FFDiag(Loc, diag::note_constexpr_pointer_comparison_unspecified) +<< LHS.toDiagnosticString(S.getCtx()) +<< RHS.toDiagnosticString(S.getCtx()); +
[clang] [clang][Interp] Three-way comparisons (PR #65901)
https://github.com/llvmbot labeled https://github.com/llvm/llvm-project/pull/65901 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Three-way comparisons (PR #65901)
https://github.com/llvmbot labeled https://github.com/llvm/llvm-project/pull/65901 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Three-way comparisons (PR #65901)
https://github.com/tbaederr review_requested https://github.com/llvm/llvm-project/pull/65901 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Three-way comparisons (PR #65901)
https://github.com/tbaederr review_requested https://github.com/llvm/llvm-project/pull/65901 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Three-way comparisons (PR #65901)
https://github.com/tbaederr review_requested https://github.com/llvm/llvm-project/pull/65901 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Three-way comparisons (PR #65901)
https://github.com/tbaederr review_requested https://github.com/llvm/llvm-project/pull/65901 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Three-way comparisons (PR #65901)
https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/65901: None >From a8503c150e80df7c505eb0f82941f2fcebe8a97e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Sun, 10 Sep 2023 17:02:22 +0200 Subject: [PATCH] [clang][Interp] Three-way comparisons --- clang/lib/AST/Interp/Boolean.h | 6 +++ clang/lib/AST/Interp/ByteCodeExprGen.cpp | 23 ++ clang/lib/AST/Interp/Floating.h | 6 +++ clang/lib/AST/Interp/Integral.h | 7 +++ clang/lib/AST/Interp/Interp.h| 29 + clang/lib/AST/Interp/InterpBuiltin.cpp | 17 clang/lib/AST/Interp/Opcodes.td | 5 +++ clang/lib/AST/Interp/Pointer.h | 13 ++ clang/test/AST/Interp/cxx20.cpp | 54 9 files changed, 160 insertions(+) diff --git a/clang/lib/AST/Interp/Boolean.h b/clang/lib/AST/Interp/Boolean.h index 6f0fe26ace68807..c3ed3d61f76ca1c 100644 --- a/clang/lib/AST/Interp/Boolean.h +++ b/clang/lib/AST/Interp/Boolean.h @@ -84,6 +84,12 @@ class Boolean final { Boolean truncate(unsigned TruncBits) const { return *this; } void print(llvm::raw_ostream ) const { OS << (V ? "true" : "false"); } + std::string toDiagnosticString(const ASTContext ) const { +std::string NameStr; +llvm::raw_string_ostream OS(NameStr); +print(OS); +return NameStr; + } static Boolean min(unsigned NumBits) { return Boolean(false); } static Boolean max(unsigned NumBits) { return Boolean(true); } diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 6a492c4c907cde0..47e070285aebd67 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -261,6 +261,29 @@ bool ByteCodeExprGen::VisitBinaryOperator(const BinaryOperator *BO) { : this->visit(RHS)); } + // Special case for C++'s three-way/spaceship operator <=>, which + // returns a std::strong_ordering (which is class, so doesn't have a + // PrimType). + if (!T) { +if (DiscardResult) + return true; +const ComparisonCategoryInfo *CmpInfo = +Ctx.getASTContext().CompCategories.lookupInfoForType(BO->getType()); +assert(CmpInfo); + +// We need a temporary variable holding our return value. +if (!Initializing) { + std::optional ResultIndex = this->allocateLocal(BO, false); + if (!this->emitGetPtrLocal(*ResultIndex, BO)) +return false; +} + +if (!visit(LHS) || !visit(RHS)) + return false; + +return this->emitCMP3(*LT, CmpInfo, BO); + } + if (!LT || !RT || !T) return this->bail(BO); diff --git a/clang/lib/AST/Interp/Floating.h b/clang/lib/AST/Interp/Floating.h index 9a8fd34ec934893..a22b3fa79f3992f 100644 --- a/clang/lib/AST/Interp/Floating.h +++ b/clang/lib/AST/Interp/Floating.h @@ -76,6 +76,12 @@ class Floating final { F.toString(Buffer); OS << Buffer; } + std::string toDiagnosticString(const ASTContext ) const { +std::string NameStr; +llvm::raw_string_ostream OS(NameStr); +print(OS); +return NameStr; + } unsigned bitWidth() const { return F.semanticsSizeInBits(F.getSemantics()); } diff --git a/clang/lib/AST/Interp/Integral.h b/clang/lib/AST/Interp/Integral.h index 72285cabcbbf8ce..0295a9c3b5c898c 100644 --- a/clang/lib/AST/Interp/Integral.h +++ b/clang/lib/AST/Interp/Integral.h @@ -128,6 +128,13 @@ template class Integral final { return Compare(V, RHS.V); } + std::string toDiagnosticString(const ASTContext ) const { +std::string NameStr; +llvm::raw_string_ostream OS(NameStr); +OS << V; +return NameStr; + } + unsigned countLeadingZeros() const { if constexpr (!Signed) return llvm::countl_zero(V); diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index 5006f72fe7237f5..14f23e84386d0fd 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -112,6 +112,11 @@ bool CheckCtorCall(InterpState , CodePtr OpPC, const Pointer ); bool CheckPotentialReinterpretCast(InterpState , CodePtr OpPC, const Pointer ); +/// Sets the given integral value to the pointer, which is of +/// a std::{weak,partial,strong}_ordering type. +bool SetThreeWayComparisonField(InterpState , CodePtr OpPC, +const Pointer , const APSInt ); + /// Checks if the shift operation is legal. template bool CheckShift(InterpState , CodePtr OpPC, const LT , const RT , @@ -773,6 +778,30 @@ bool EQ(InterpState , CodePtr OpPC) { }); } +template ::T> +bool CMP3(InterpState , CodePtr OpPC, const ComparisonCategoryInfo *CmpInfo) { + const T = S.Stk.pop(); + const T = S.Stk.pop(); + const Pointer = S.Stk.peek(); + + ComparisonCategoryResult CmpResult = LHS.compare(RHS); + if (CmpResult == ComparisonCategoryResult::Unordered) { +// This should only happen with pointers. +
[clang] [clang][Interp] Three-way comparisons (PR #65901)
https://github.com/tbaederr review_requested https://github.com/llvm/llvm-project/pull/65901 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits