Fix behavior of __builtin_bit_cast when the From and To types are the

same.

We were missing the lvalue-to-rvalue conversion entirely in this case,
and in fact still need the full CK_LValueToRValueBitCast conversion to
perform a load with no TBAA.

llvm-svn: 373874
This commit is contained in:
Richard Smith 2019-10-07 02:45:12 +00:00
parent a30730f690
commit 74ce7112c3
4 changed files with 24 additions and 7 deletions

View File

@ -66,8 +66,9 @@ CAST_OPERATION(BitCast)
/// bool b; reinterpret_cast<char&>(b) = 'a';
CAST_OPERATION(LValueBitCast)
/// CK_LValueToRValueBitCast - A conversion that causes us to reinterpret an
/// lvalue as an rvalue of a different type. Created by __builtin_bit_cast.
/// CK_LValueToRValueBitCast - A conversion that causes us to reinterpret the
/// object representation of an lvalue as an rvalue. Created by
/// __builtin_bit_cast.
CAST_OPERATION(LValueToRValueBitCast)
/// CK_LValueToRValue - A conversion which causes the extraction of

View File

@ -2835,11 +2835,6 @@ void CastOperation::CheckBuiltinBitCast() {
return;
}
if (Self.Context.hasSameUnqualifiedType(DestType, SrcType)) {
Kind = CK_NoOp;
return;
}
Kind = CK_LValueToRValueBitCast;
}

View File

@ -15,5 +15,10 @@ void test_scalar2() {
// CHECK: load i32, i32* {{.*}}, align 4, !tbaa ![[MAY_ALIAS_TBAA]]
}
int test_same_type(int &r) {
// CHECK: load i32, i32* {{.*}}, align 4, !tbaa ![[MAY_ALIAS_TBAA]]
return __builtin_bit_cast(int, r);
}
// CHECK: ![[CHAR_TBAA:.*]] = !{!"omnipotent char", {{.*}}, i64 0}
// CHECK: ![[MAY_ALIAS_TBAA]] = !{![[CHAR_TBAA]], ![[CHAR_TBAA]], i64 0}

View File

@ -381,3 +381,19 @@ constexpr bool test_pad_buffer() {
return x.a == z.a && x.b == z.b;
}
static_assert(test_pad_buffer());
constexpr unsigned char identity1a = 42;
constexpr unsigned char identity1b = __builtin_bit_cast(unsigned char, identity1a);
static_assert(identity1b == 42);
struct IdentityInStruct {
unsigned char n;
};
constexpr IdentityInStruct identity2a = {42};
constexpr unsigned char identity2b = __builtin_bit_cast(unsigned char, identity2a.n);
union IdentityInUnion {
unsigned char n;
};
constexpr IdentityInUnion identity3a = {42};
constexpr unsigned char identity3b = __builtin_bit_cast(unsigned char, identity3a.n);