mizvekov created this revision. Herald added subscribers: manas, steakhal, ASDenysPetrov, dkrupp, donat.nagy, Szelethus, a.sidorin, baloghadamsoftware. mizvekov requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Fixes PR50591. When analyzing classes with members which have user-defined conversion operators to builtin types, the defaulted comparison analyzer was picking the member type instead of the type for the builtin operator which was selected as the best match. This could either result in wrong comparison category being selected, or a crash when runtime checks are enabled. Signed-off-by: Matheus Izvekov <mizve...@gmail.com> Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D103760 Files: clang/lib/Sema/SemaDeclCXX.cpp clang/test/CXX/class/class.compare/class.spaceship/p2.cpp Index: clang/test/CXX/class/class.compare/class.spaceship/p2.cpp =================================================================== --- clang/test/CXX/class/class.compare/class.spaceship/p2.cpp +++ clang/test/CXX/class/class.compare/class.spaceship/p2.cpp @@ -172,3 +172,23 @@ int C::*x; // expected-note {{because there is no viable three-way comparison function for member 'x'}} }; } + +namespace PR50591 { + struct a1 { + operator int() const; + }; + struct b1 { + auto operator<=>(b1 const &) const = default; + a1 f; + }; + std::strong_ordering cmp_b1 = b1() <=> b1(); + + struct a2 { + operator float() const; + }; + struct b2 { + auto operator<=>(b2 const &) const = default; + a2 f; + }; + std::partial_ordering cmp_b2 = b2() <=> b2(); +} Index: clang/lib/Sema/SemaDeclCXX.cpp =================================================================== --- clang/lib/Sema/SemaDeclCXX.cpp +++ clang/lib/Sema/SemaDeclCXX.cpp @@ -7861,8 +7861,13 @@ return Result::deleted(); } } else { + QualType T = Best->BuiltinParamTypes[0]; + assert(T == Best->BuiltinParamTypes[1] && + "builtin comparison for different types?"); + assert(Best->BuiltinParamTypes[2].isNull() && + "invalid builtin comparison"); Optional<ComparisonCategoryType> Cat = - getComparisonCategoryForBuiltinCmp(Args[0]->getType()); + getComparisonCategoryForBuiltinCmp(T); assert(Cat && "no category for builtin comparison?"); R.Category = *Cat; }
Index: clang/test/CXX/class/class.compare/class.spaceship/p2.cpp =================================================================== --- clang/test/CXX/class/class.compare/class.spaceship/p2.cpp +++ clang/test/CXX/class/class.compare/class.spaceship/p2.cpp @@ -172,3 +172,23 @@ int C::*x; // expected-note {{because there is no viable three-way comparison function for member 'x'}} }; } + +namespace PR50591 { + struct a1 { + operator int() const; + }; + struct b1 { + auto operator<=>(b1 const &) const = default; + a1 f; + }; + std::strong_ordering cmp_b1 = b1() <=> b1(); + + struct a2 { + operator float() const; + }; + struct b2 { + auto operator<=>(b2 const &) const = default; + a2 f; + }; + std::partial_ordering cmp_b2 = b2() <=> b2(); +} Index: clang/lib/Sema/SemaDeclCXX.cpp =================================================================== --- clang/lib/Sema/SemaDeclCXX.cpp +++ clang/lib/Sema/SemaDeclCXX.cpp @@ -7861,8 +7861,13 @@ return Result::deleted(); } } else { + QualType T = Best->BuiltinParamTypes[0]; + assert(T == Best->BuiltinParamTypes[1] && + "builtin comparison for different types?"); + assert(Best->BuiltinParamTypes[2].isNull() && + "invalid builtin comparison"); Optional<ComparisonCategoryType> Cat = - getComparisonCategoryForBuiltinCmp(Args[0]->getType()); + getComparisonCategoryForBuiltinCmp(T); assert(Cat && "no category for builtin comparison?"); R.Category = *Cat; }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits