Index: lib/Sema/SemaCast.cpp =================================================================== --- lib/Sema/SemaCast.cpp +++ lib/Sema/SemaCast.cpp @@ -2170,6 +2170,21 @@ assert(!SrcType->isPlaceholderType()); + // OpenCL v1 s6.5: Casting a pointer to address space A to a pointer to + // address space B is illegal. + if (Self.getLangOpts().OpenCL && DestType->isPointerType() && + SrcType->isPointerType()) { + if (DestType->getPointeeType().getAddressSpace() != + SrcType->getPointeeType().getAddressSpace()) { + Self.Diag(OpRange.getBegin(), + diag::err_typecheck_incompatible_address_space) + << SrcType << DestType << Sema::AA_Casting + << SrcExpr.get()->getSourceRange(); + SrcExpr = ExprError(); + return; + } + } + if (Self.RequireCompleteType(OpRange.getBegin(), DestType, diag::err_typecheck_cast_to_incomplete)) { SrcExpr = ExprError(); Index: test/SemaOpenCL/address-spaces.cl =================================================================== --- test/SemaOpenCL/address-spaces.cl +++ test/SemaOpenCL/address-spaces.cl @@ -11,3 +11,22 @@ ip = &li; // expected-error {{assigning '__local int *' to 'int *' changes address space of pointer}} ip = &ci; // expected-error {{assigning '__constant int *' to 'int *' changes address space of pointer}} } + +void explicit_cast(global int* g, local int* l, constant int* c, private int* p) +{ + g = (global int*) l; // expected-error {{casting '__local int *' to type '__global int *' changes address space of pointer}} + g = (global int*) c; // expected-error {{casting '__constant int *' to type '__global int *' changes address space of pointer}} + g = (global int*) p; // expected-error {{casting 'int *' to type '__global int *' changes address space of pointer}} + + l = (local int*) g; // expected-error {{casting '__global int *' to type '__local int *' changes address space of pointer}} + l = (local int*) c; // expected-error {{casting '__constant int *' to type '__local int *' changes address space of pointer}} + l = (local int*) p; // expected-error {{casting 'int *' to type '__local int *' changes address space of pointer}} + + c = (constant int*) g; // expected-error {{casting '__global int *' to type '__constant int *' changes address space of pointer}} + c = (constant int*) l; // expected-error {{casting '__local int *' to type '__constant int *' changes address space of pointer}} + c = (constant int*) p; // expected-error {{casting 'int *' to type '__constant int *' changes address space of pointer}} + + p = (private int*) g; // expected-error {{casting '__global int *' to type 'int *' changes address space of pointer}} + p = (private int*) l; // expected-error {{casting '__local int *' to type 'int *' changes address space of pointer}} + p = (private int*) c; // expected-error {{casting '__constant int *' to type 'int *' changes address space of pointer}} +}