Author: Rose Hudson Date: 2025-12-10T09:32:41-05:00 New Revision: 8c4950951269ec58296afbeba14e99aef467f84d
URL: https://github.com/llvm/llvm-project/commit/8c4950951269ec58296afbeba14e99aef467f84d DIFF: https://github.com/llvm/llvm-project/commit/8c4950951269ec58296afbeba14e99aef467f84d.diff LOG: [Clang] remove qualifiers in getCanonicalTypeUnqualified (#170271) It was assumed that since this is a method on Type, there are no quals present because usually you get a Type by using operator-> on a QualType. However, quals aren't always stored in the outermost QualType. For example, if const A is used as a template parameter, the outer QualType does not have the const flag set. The const actually lives in the canonical type inside a SubstTemplateTypeParmType. We therefore need to explicitly remove quals before returning. Fixes #135273 --- I've been looking at all the call sites as suggested in https://github.com/llvm/llvm-project/pull/167881#discussion_r2535247632 to check that their usage of this method is sane. So far, most of the sites seem to either want unqualified types or not care, so this patch should handle some spooky edge cases of those. Some of them need more thinking, which I'll do soon. Supersedes #167881 Added: Modified: clang/docs/ReleaseNotes.rst clang/include/clang/AST/CanonicalType.h clang/test/SemaCXX/type-traits.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 690d2a389ef24..005e858821804 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -589,6 +589,7 @@ Bug Fixes to C++ Support - Fix a crash when extracting unavailable member type from alias in template deduction. (#GH165560) - Fix incorrect diagnostics for lambdas with init-captures inside braced initializers. (#GH163498) - 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) Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/include/clang/AST/CanonicalType.h b/clang/include/clang/AST/CanonicalType.h index 87bbd7b5d885d..b46fc8f50fa23 100644 --- a/clang/include/clang/AST/CanonicalType.h +++ b/clang/include/clang/AST/CanonicalType.h @@ -213,7 +213,8 @@ inline bool operator!=(CanQual<T> x, CanQual<U> y) { using CanQualType = CanQual<Type>; inline CanQualType Type::getCanonicalTypeUnqualified() const { - return CanQualType::CreateUnsafe(getCanonicalTypeInternal()); + return CanQualType::CreateUnsafe( + getCanonicalTypeInternal().getUnqualifiedType()); } inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB, diff --git a/clang/test/SemaCXX/type-traits.cpp b/clang/test/SemaCXX/type-traits.cpp index 9ef44d0346b48..561c9ca8286b9 100644 --- a/clang/test/SemaCXX/type-traits.cpp +++ b/clang/test/SemaCXX/type-traits.cpp @@ -1812,6 +1812,11 @@ union Union {}; union UnionIncomplete; struct StructIncomplete; // #StructIncomplete +#if __cplusplus >= 201402L +template<class _Base, class _Derived> +inline constexpr bool IsPointerInterconvertibleBaseOfV = __is_pointer_interconvertible_base_of(_Base, _Derived); +#endif + void is_pointer_interconvertible_base_of(int n) { static_assert(__is_pointer_interconvertible_base_of(Base, Derived)); @@ -1880,6 +1885,11 @@ void is_pointer_interconvertible_base_of(int n) static_assert(!__is_pointer_interconvertible_base_of(void(&)(int), void(&)(char))); static_assert(!__is_pointer_interconvertible_base_of(void(*)(int), void(*)(int))); static_assert(!__is_pointer_interconvertible_base_of(void(*)(int), void(*)(char))); + +#if __cplusplus >= 201402L + static_assert(IsPointerInterconvertibleBaseOfV<const Base, Base>); + static_assert(IsPointerInterconvertibleBaseOfV<const Base, Derived>); +#endif } } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
