Skip to content

Commit 8c49509

Browse files
[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 #167881 (comment) 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
1 parent 3ba0ff6 commit 8c49509

File tree

3 files changed

+13
-1
lines changed

3 files changed

+13
-1
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,7 @@ Bug Fixes to C++ Support
589589
- Fix a crash when extracting unavailable member type from alias in template deduction. (#GH165560)
590590
- Fix incorrect diagnostics for lambdas with init-captures inside braced initializers. (#GH163498)
591591
- Fixed spurious diagnoses of certain nested lambda expressions. (#GH149121) (#GH156579)
592+
- Fix the result of ``__is_pointer_interconvertible_base_of`` when arguments are qualified and passed via template parameters. (#GH135273)
592593

593594
Bug Fixes to AST Handling
594595
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/include/clang/AST/CanonicalType.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,8 @@ inline bool operator!=(CanQual<T> x, CanQual<U> y) {
213213
using CanQualType = CanQual<Type>;
214214

215215
inline CanQualType Type::getCanonicalTypeUnqualified() const {
216-
return CanQualType::CreateUnsafe(getCanonicalTypeInternal());
216+
return CanQualType::CreateUnsafe(
217+
getCanonicalTypeInternal().getUnqualifiedType());
217218
}
218219

219220
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,

clang/test/SemaCXX/type-traits.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1812,6 +1812,11 @@ union Union {};
18121812
union UnionIncomplete;
18131813
struct StructIncomplete; // #StructIncomplete
18141814

1815+
#if __cplusplus >= 201402L
1816+
template<class _Base, class _Derived>
1817+
inline constexpr bool IsPointerInterconvertibleBaseOfV = __is_pointer_interconvertible_base_of(_Base, _Derived);
1818+
#endif
1819+
18151820
void is_pointer_interconvertible_base_of(int n)
18161821
{
18171822
static_assert(__is_pointer_interconvertible_base_of(Base, Derived));
@@ -1880,6 +1885,11 @@ void is_pointer_interconvertible_base_of(int n)
18801885
static_assert(!__is_pointer_interconvertible_base_of(void(&)(int), void(&)(char)));
18811886
static_assert(!__is_pointer_interconvertible_base_of(void(*)(int), void(*)(int)));
18821887
static_assert(!__is_pointer_interconvertible_base_of(void(*)(int), void(*)(char)));
1888+
1889+
#if __cplusplus >= 201402L
1890+
static_assert(IsPointerInterconvertibleBaseOfV<const Base, Base>);
1891+
static_assert(IsPointerInterconvertibleBaseOfV<const Base, Derived>);
1892+
#endif
18831893
}
18841894
}
18851895

0 commit comments

Comments
 (0)