https://github.com/code-pankaj updated https://github.com/llvm/llvm-project/pull/172001
>From e627d929cb8bc01dad82610219fbb362635b6f00 Mon Sep 17 00:00:00 2001 From: code-pankaj <[email protected]> Date: Fri, 12 Dec 2025 18:02:34 +0530 Subject: [PATCH 1/2] [Clang] Fix crash on malformed std::partial_ordering static members This fixes a crash (segmentation fault) when the standard library implementation of comparison categories (like `std::partial_ordering`) is malformed. Specifically, if the static members (like `equivalent`) are defined as a primitive type (e.g., `int`) instead of the comparison category type itself, the compiler previously attempted to process them incorrectly, leading to a crash. This patch adds strict type checking in `ComparisonCategoryInfo::lookupValueInfo`. If the found static member does not match the record type, it is rejected safely, triggering a diagnostic error instead of a crash. Fixes #170015 --- clang/docs/ReleaseNotes.rst | 1 + clang/lib/AST/ComparisonCategories.cpp | 11 ++++++-- .../SemaCXX/cxx2a-three-way-comparison.cpp | 25 +++++++++++++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 22ca79d6adc28..702903bd0225a 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -602,6 +602,7 @@ Bug Fixes to C++ Support - Fixed an issue where templates prevented nested anonymous records from checking the deletion of special members. (#GH167217) - Fixed spurious diagnoses of certain nested lambda expressions. (#GH149121) (#GH156579) - Fix the result of ``__is_pointer_interconvertible_base_of`` when arguments are qualified and passed via template parameters. (#GH135273) +- - Fixed a crash when standard comparison categories (e.g. ``std::partial_ordering``) are defined with incorrect static member types. (#GH170015) Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/AST/ComparisonCategories.cpp b/clang/lib/AST/ComparisonCategories.cpp index 1b9c938e2ace3..afa662dccab00 100644 --- a/clang/lib/AST/ComparisonCategories.cpp +++ b/clang/lib/AST/ComparisonCategories.cpp @@ -49,7 +49,7 @@ bool ComparisonCategoryInfo::ValueInfo::hasValidIntValue() const { // Before we attempt to get the value of the first field, ensure that we // actually have one (and only one) field. const auto *Record = VD->getType()->getAsCXXRecordDecl(); - if (Record->getNumFields() != 1 || + if (!Record || Record->getNumFields() != 1 || !Record->field_begin()->getType()->isIntegralOrEnumerationType()) return false; @@ -83,7 +83,14 @@ ComparisonCategoryInfo::ValueInfo *ComparisonCategoryInfo::lookupValueInfo( &Ctx.Idents.get(ComparisonCategories::getResultString(ValueKind))); if (Lookup.empty() || !isa<VarDecl>(Lookup.front())) return nullptr; - Objects.emplace_back(ValueKind, cast<VarDecl>(Lookup.front())); + // The static member must have the same type as the comparison category class + // itself (e.g., std::partial_ordering::less must be of type partial_ordering). + VarDecl *ValueDecl = cast<VarDecl>(Lookup.front()); + const CXXRecordDecl *ValueDeclRecord = ValueDecl->getType()->getAsCXXRecordDecl(); + if (!ValueDeclRecord || ValueDeclRecord->getCanonicalDecl() != Record->getCanonicalDecl()) + return nullptr; + + Objects.emplace_back(ValueKind, ValueDecl); return &Objects.back(); } diff --git a/clang/test/SemaCXX/cxx2a-three-way-comparison.cpp b/clang/test/SemaCXX/cxx2a-three-way-comparison.cpp index 76007ff3913dd..31b6f367e9cce 100644 --- a/clang/test/SemaCXX/cxx2a-three-way-comparison.cpp +++ b/clang/test/SemaCXX/cxx2a-three-way-comparison.cpp @@ -67,3 +67,28 @@ struct comparable_t { expected-note {{defaulted 'operator<=>' is implicitly deleted because defaulted comparison of vector types is not supported}} }; } // namespace GH137452 + +namespace GH170015 { +// This test ensures that the compiler enforces strict type checking on the +// static members of comparison category types. +// Previously, a mismatch (e.g., equivalent being an int) could crash the compiler. +} + +namespace std { + struct partial_ordering { + // Malformed: 'equivalent' should be of type 'partial_ordering', not 'int'. + static constexpr int equivalent = 0; + static constexpr int less = -1; + static constexpr int greater = 1; + static constexpr int unordered = 2; + }; +} + +namespace GH170015 { + void f() { + float a = 0.0f, b = 0.0f; + // We expect the compiler to complain that the type form is wrong + // (because the static members are ints, not objects). + auto res = a <=> b; // expected-error {{standard library implementation of 'std::partial_ordering' is not supported; the type does not have the expected form}} + } +} \ No newline at end of file >From 611b6088ba65dbeec6b6040b05fc5910691f6fbe Mon Sep 17 00:00:00 2001 From: Pankaj <[email protected]> Date: Fri, 12 Dec 2025 23:10:21 +0530 Subject: [PATCH 2/2] Removed extra hyphen Co-authored-by: Timm Baeder <[email protected]> --- clang/docs/ReleaseNotes.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 702903bd0225a..477e6ca67c818 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -602,7 +602,7 @@ Bug Fixes to C++ Support - Fixed an issue where templates prevented nested anonymous records from checking the deletion of special members. (#GH167217) - Fixed spurious diagnoses of certain nested lambda expressions. (#GH149121) (#GH156579) - Fix the result of ``__is_pointer_interconvertible_base_of`` when arguments are qualified and passed via template parameters. (#GH135273) -- - Fixed a crash when standard comparison categories (e.g. ``std::partial_ordering``) are defined with incorrect static member types. (#GH170015) +- Fixed a crash when standard comparison categories (e.g. ``std::partial_ordering``) are defined with incorrect static member types. (#GH170015) Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
