From: George Burgess IV Date: Mon, 16 Oct 2017 22:58:37 +0000 (+0000) Subject: Make __builtin_types_compatible_p more like GCC's X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=73c1500cc3b3a4cd39a7c59753a7d0e63887a839;p=clang Make __builtin_types_compatible_p more like GCC's 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 --- diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 17aa8847e0..7f5b792e8c 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -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: diff --git a/test/Parser/builtin_types_compatible.c b/test/Parser/builtin_types_compatible.c index ac81e7b08d..d967a7023a 100644 --- a/test/Parser/builtin_types_compatible.c +++ b/test/Parser/builtin_types_compatible.c @@ -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(*)[]), ""); +}