]> granicus.if.org Git - clang/commitdiff
Make __builtin_types_compatible_p more like GCC's
authorGeorge Burgess IV <george.burgess.iv@gmail.com>
Mon, 16 Oct 2017 22:58:37 +0000 (22:58 +0000)
committerGeorge Burgess IV <george.burgess.iv@gmail.com>
Mon, 16 Oct 2017 22:58:37 +0000 (22:58 +0000)
GCC ignore qualifiers on array types. Since we seem to have this
function primarily for GCC compatibility, we should try to match that
behavior.

This also adds a few more test-cases __builtin_types_compatible_p,
which were inspired by GCC's documentation on the builtin.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@315951 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExprCXX.cpp
test/Parser/builtin_types_compatible.c

index 17aa8847e03d82c0c3036bd3ed5f1acc838360b1..7f5b792e8c4923561d0bf0a5363fc707b17a9c84 100644 (file)
@@ -4824,9 +4824,13 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, QualType LhsT,
   }
   case BTT_IsSame:
     return Self.Context.hasSameType(LhsT, RhsT);
-  case BTT_TypeCompatible:
-    return Self.Context.typesAreCompatible(LhsT.getUnqualifiedType(),
-                                           RhsT.getUnqualifiedType());
+  case BTT_TypeCompatible: {
+    // GCC ignores cv-qualifiers on arrays for this builtin.
+    Qualifiers LhsQuals, RhsQuals;
+    QualType Lhs = Self.getASTContext().getUnqualifiedArrayType(LhsT, LhsQuals);
+    QualType Rhs = Self.getASTContext().getUnqualifiedArrayType(RhsT, RhsQuals);
+    return Self.Context.typesAreCompatible(Lhs, Rhs);
+  }
   case BTT_IsConvertible:
   case BTT_IsConvertibleTo: {
     // C++0x [meta.rel]p4:
index ac81e7b08dc95e97a8cecd291fd7c06f6d98da70..d967a7023a490100b65ef65efbfc2c29e732bee7 100644 (file)
@@ -41,3 +41,20 @@ static void test()
 
 }
 
+enum E1 { E1Foo };
+enum E2 { E2Foo };
+
+static void testGccCompatibility() {
+  _Static_assert(__builtin_types_compatible_p(const volatile int, int), "");
+  _Static_assert(__builtin_types_compatible_p(int[5], int[]), "");
+  _Static_assert(!__builtin_types_compatible_p(int[5], int[4]), "");
+  _Static_assert(!__builtin_types_compatible_p(int *, int **), "");
+  _Static_assert(!__builtin_types_compatible_p(const int *, int *), "");
+  _Static_assert(!__builtin_types_compatible_p(enum E1, enum E2), "");
+
+  // GCC's __builtin_types_compatible_p ignores qualifiers on arrays.
+  _Static_assert(__builtin_types_compatible_p(const int[4], int[4]), "");
+  _Static_assert(__builtin_types_compatible_p(int[4], const int[4]), "");
+  _Static_assert(__builtin_types_compatible_p(const int[5][4], int[][4]), "");
+  _Static_assert(!__builtin_types_compatible_p(const int(*)[], int(*)[]), "");
+}