forked from OSchip/llvm-project
[Sema] Fix for crash on conditional operation with address_space pointer
Compiling the following causes clang to crash ``` char *cmp(__attribute__((address_space(1))) char *x, __attribute__((address_space(2))) char *y) { return x < y ? x : y; } ``` with the message: "wrong cast for pointers in different address spaces(must be an address space cast)!" This is because during IR emission, the source and dest type for a bitcast should not have differing address spaces. This fix prints an error since the code shouldn't compile in the first place. Differential Revision: https://reviews.llvm.org/D50278 llvm-svn: 339167
This commit is contained in:
parent
0edcd0278d
commit
7add582032
|
@ -6460,20 +6460,18 @@ static QualType checkConditionalPointerCompatibility(Sema &S, ExprResult &LHS,
|
|||
LangAS ResultAddrSpace = LangAS::Default;
|
||||
LangAS LAddrSpace = lhQual.getAddressSpace();
|
||||
LangAS RAddrSpace = rhQual.getAddressSpace();
|
||||
if (S.getLangOpts().OpenCL) {
|
||||
// OpenCL v1.1 s6.5 - Conversion between pointers to distinct address
|
||||
// spaces is disallowed.
|
||||
if (lhQual.isAddressSpaceSupersetOf(rhQual))
|
||||
ResultAddrSpace = LAddrSpace;
|
||||
else if (rhQual.isAddressSpaceSupersetOf(lhQual))
|
||||
ResultAddrSpace = RAddrSpace;
|
||||
else {
|
||||
S.Diag(Loc,
|
||||
diag::err_typecheck_op_on_nonoverlapping_address_space_pointers)
|
||||
<< LHSTy << RHSTy << 2 << LHS.get()->getSourceRange()
|
||||
<< RHS.get()->getSourceRange();
|
||||
return QualType();
|
||||
}
|
||||
|
||||
// OpenCL v1.1 s6.5 - Conversion between pointers to distinct address
|
||||
// spaces is disallowed.
|
||||
if (lhQual.isAddressSpaceSupersetOf(rhQual))
|
||||
ResultAddrSpace = LAddrSpace;
|
||||
else if (rhQual.isAddressSpaceSupersetOf(lhQual))
|
||||
ResultAddrSpace = RAddrSpace;
|
||||
else {
|
||||
S.Diag(Loc, diag::err_typecheck_op_on_nonoverlapping_address_space_pointers)
|
||||
<< LHSTy << RHSTy << 2 << LHS.get()->getSourceRange()
|
||||
<< RHS.get()->getSourceRange();
|
||||
return QualType();
|
||||
}
|
||||
|
||||
unsigned MergedCVRQual = lhQual.getCVRQualifiers() | rhQual.getCVRQualifiers();
|
||||
|
@ -6491,16 +6489,12 @@ static QualType checkConditionalPointerCompatibility(Sema &S, ExprResult &LHS,
|
|||
// Thus for conditional operator we merge CVR and address space unqualified
|
||||
// pointees and if there is a composite type we return a pointer to it with
|
||||
// merged qualifiers.
|
||||
if (S.getLangOpts().OpenCL) {
|
||||
LHSCastKind = LAddrSpace == ResultAddrSpace
|
||||
? CK_BitCast
|
||||
: CK_AddressSpaceConversion;
|
||||
RHSCastKind = RAddrSpace == ResultAddrSpace
|
||||
? CK_BitCast
|
||||
: CK_AddressSpaceConversion;
|
||||
lhQual.removeAddressSpace();
|
||||
rhQual.removeAddressSpace();
|
||||
}
|
||||
LHSCastKind =
|
||||
LAddrSpace == ResultAddrSpace ? CK_BitCast : CK_AddressSpaceConversion;
|
||||
RHSCastKind =
|
||||
RAddrSpace == ResultAddrSpace ? CK_BitCast : CK_AddressSpaceConversion;
|
||||
lhQual.removeAddressSpace();
|
||||
rhQual.removeAddressSpace();
|
||||
|
||||
lhptee = S.Context.getQualifiedType(lhptee.getUnqualifiedType(), lhQual);
|
||||
rhptee = S.Context.getQualifiedType(rhptee.getUnqualifiedType(), rhQual);
|
||||
|
@ -6516,6 +6510,7 @@ static QualType checkConditionalPointerCompatibility(Sema &S, ExprResult &LHS,
|
|||
S.Context.getAddrSpaceQualType(S.Context.VoidTy, ResultAddrSpace));
|
||||
LHS = S.ImpCastExprToType(LHS.get(), incompatTy, LHSCastKind);
|
||||
RHS = S.ImpCastExprToType(RHS.get(), incompatTy, RHSCastKind);
|
||||
|
||||
// FIXME: For OpenCL the warning emission and cast to void* leaves a room
|
||||
// for casts between types with incompatible address space qualifiers.
|
||||
// For the following code the compiler produces casts between global and
|
||||
|
@ -6526,6 +6521,7 @@ static QualType checkConditionalPointerCompatibility(Sema &S, ExprResult &LHS,
|
|||
S.Diag(Loc, diag::ext_typecheck_cond_incompatible_pointers)
|
||||
<< LHSTy << RHSTy << LHS.get()->getSourceRange()
|
||||
<< RHS.get()->getSourceRange();
|
||||
|
||||
return incompatTy;
|
||||
}
|
||||
|
||||
|
|
|
@ -71,5 +71,5 @@ __attribute__((address_space("12"))) int *i; // expected-error {{'address_space'
|
|||
|
||||
// Clang extension doesn't forbid operations on pointers to different address spaces.
|
||||
char* cmp(_AS1 char *x, _AS2 char *y) {
|
||||
return x < y ? x : y; // expected-warning {{pointer type mismatch ('__attribute__((address_space(1))) char *' and '__attribute__((address_space(2))) char *')}}
|
||||
return x < y ? x : y; // expected-error{{conditional operator with the second and third operands of type ('__attribute__((address_space(1))) char *' and '__attribute__((address_space(2))) char *') which are pointers to non-overlapping address spaces}}
|
||||
}
|
||||
|
|
|
@ -73,10 +73,10 @@ void foo() {
|
|||
|
||||
int __attribute__((address_space(2))) *adr2;
|
||||
int __attribute__((address_space(3))) *adr3;
|
||||
test0 ? adr2 : adr3; // expected-warning {{pointer type mismatch}} expected-warning {{expression result unused}}
|
||||
test0 ? adr2 : adr3; // expected-error{{conditional operator with the second and third operands of type ('__attribute__((address_space(2))) int *' and '__attribute__((address_space(3))) int *') which are pointers to non-overlapping address spaces}}
|
||||
|
||||
// Make sure address-space mask ends up in the result type
|
||||
(test0 ? (test0 ? adr2 : adr2) : nonconst_int); // expected-warning {{pointer type mismatch}} expected-warning {{expression result unused}}
|
||||
(test0 ? (test0 ? adr2 : adr2) : nonconst_int); // expected-error{{conditional operator with the second and third operands of type ('__attribute__((address_space(2))) int *' and 'int *') which are pointers to non-overlapping address spaces}}
|
||||
}
|
||||
|
||||
int Postgresql() {
|
||||
|
|
Loading…
Reference in New Issue