[clang] [clang] Implement `__is_pointer_interconvertible_base_of()` (PR #88473)

Vlad Serebrennikov via cfe-commits cfe-commits at lists.llvm.org
Thu Apr 11 23:48:07 PDT 2024


================
@@ -1839,6 +1839,90 @@ void is_layout_compatible(int n)
   static_assert(!__is_layout_compatible(EnumClassForward, int));
 }
 
+namespace IPIBO {
+struct Base {};
+struct Base2 {};
+struct Base3 : Base {};
+struct Base3Virtual : virtual Base {};
+struct Derived : Base {};
+struct DerivedIndirect : Base3 {};
+struct DerivedMultiple : Base, Base2 {};
+struct DerivedAmbiguous : Base, Base3 {};
+/* expected-warning at -1 {{direct base 'Base' is inaccessible due to ambiguity:
+    struct IPIBO::DerivedAmbiguous -> Base
+    struct IPIBO::DerivedAmbiguous -> Base3 -> Base}} */
+struct DerivedPrivate : private Base {};
+struct DerivedVirtual : virtual Base {};
+
+union Union {};
+union UnionIncomplete;
+struct StructIncomplete;
+
+void is_pointer_interconvertible_base_of(int n)
+{
+  static_assert(__is_pointer_interconvertible_base_of(Base, Derived));
+  static_assert(!__is_pointer_interconvertible_base_of(Base2, Derived));
+  static_assert(__is_pointer_interconvertible_base_of(Base, DerivedIndirect));
+  static_assert(__is_pointer_interconvertible_base_of(Base, DerivedMultiple));
+  static_assert(!__is_pointer_interconvertible_base_of(Base3, DerivedMultiple));
+  static_assert(!__is_pointer_interconvertible_base_of(Base, DerivedAmbiguous));
+  static_assert(__is_pointer_interconvertible_base_of(Base, DerivedPrivate));
+  static_assert(!__is_pointer_interconvertible_base_of(Base, DerivedVirtual));
+  static_assert(!__is_pointer_interconvertible_base_of(Union, Union));
+  static_assert(!__is_pointer_interconvertible_base_of(UnionIncomplete, UnionIncomplete));
+  static_assert(__is_pointer_interconvertible_base_of(StructIncomplete, StructIncomplete));
+  static_assert(__is_pointer_interconvertible_base_of(StructIncomplete, const StructIncomplete));
+  static_assert(__is_pointer_interconvertible_base_of(StructIncomplete, volatile StructIncomplete));
+  static_assert(__is_pointer_interconvertible_base_of(const StructIncomplete, volatile StructIncomplete));
+  static_assert(!__is_pointer_interconvertible_base_of(CStruct2, CppStructNonStandardByBase2));
+  static_assert(__is_pointer_interconvertible_base_of(void, void));
+  static_assert(!__is_pointer_interconvertible_base_of(void, int));
+  static_assert(__is_pointer_interconvertible_base_of(void, const void));
+  static_assert(__is_pointer_interconvertible_base_of(void, volatile void));
+  static_assert(__is_pointer_interconvertible_base_of(const void, volatile void));
+  static_assert(__is_pointer_interconvertible_base_of(int, int));
+  static_assert(__is_pointer_interconvertible_base_of(int, const int));
+  static_assert(__is_pointer_interconvertible_base_of(int, volatile int));
+  static_assert(__is_pointer_interconvertible_base_of(const int, volatile int));
+  static_assert(__is_pointer_interconvertible_base_of(int *, int * __restrict));
----------------
Endilll wrote:

I initially had `isClassType() && !isUnionType()`, but then I looked into implementation of `isUnionType()`, and thought that it checks for class type as well by cast to `RecordType`. Looks like I was wrong.

https://github.com/llvm/llvm-project/pull/88473


More information about the cfe-commits mailing list