Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -15094,22 +15094,6 @@ } } - // TR 18037 does not allow fields to be declared with address spaces. - if (T.getQualifiers().hasAddressSpace() || - T->isDependentAddressSpaceType() || - T->getBaseElementTypeUnsafe()->isDependentAddressSpaceType()) { - Diag(Loc, diag::err_field_with_address_space); - D.setInvalidType(); - } - - // OpenCL v1.2 s6.9b,r & OpenCL v2.0 s6.12.5 - The following types cannot be - // used as structure or union field: image, sampler, event or block types. - if (LangOpts.OpenCL && (T->isEventT() || T->isImageType() || - T->isSamplerT() || T->isBlockPointerType())) { - Diag(Loc, diag::err_opencl_type_struct_or_union_field) << T; - D.setInvalidType(); - } - DiagnoseFunctionSpecifiers(D.getDeclSpec()); if (D.getDeclSpec().isInlineSpecified()) @@ -15221,12 +15205,30 @@ } } - // OpenCL v1.2 s6.9.c: bitfields are not supported. - if (BitWidth && getLangOpts().OpenCL) { - Diag(Loc, diag::err_opencl_bitfields); + // TR 18037 does not allow fields to be declared with address space + if (T.getQualifiers().hasAddressSpace() || T->isDependentAddressSpaceType() || + T->getBaseElementTypeUnsafe()->isDependentAddressSpaceType()) { + Diag(Loc, diag::err_field_with_address_space); + Record->setInvalidDecl(); InvalidDecl = true; } + if (LangOpts.OpenCL) { + // OpenCL v1.2 s6.9b,r & OpenCL v2.0 s6.12.5 - The following types cannot be + // used as structure or union field: image, sampler, event or block types. + if (T->isEventT() || T->isImageType() || T->isSamplerT() || + T->isBlockPointerType()) { + Diag(Loc, diag::err_opencl_type_struct_or_union_field) << T; + Record->setInvalidDecl(); + InvalidDecl = true; + } + // OpenCL v1.2 s6.9.c: bitfields are not supported. + if (BitWidth) { + Diag(Loc, diag::err_opencl_bitfields); + InvalidDecl = true; + } + } + // Anonymous bit-fields cannot be cv-qualified (CWG 2229). if (!InvalidDecl && getLangOpts().CPlusPlus && !II && BitWidth && T.hasQualifiers()) { Index: lib/Sema/TreeTransform.h =================================================================== --- lib/Sema/TreeTransform.h +++ lib/Sema/TreeTransform.h @@ -4231,6 +4231,15 @@ QualifiedTypeLoc T) { Qualifiers Quals = T.getType().getLocalQualifiers(); + // Template parameter types used as function parameters are deduced to + // private addr space in OpenCL just like regular function parameters. + // The instantiated template might be given different addr space, + // this is incorrect but we can only diagnose it once the type is created. + // Therefore, the addr space is ignored here so that the type creation + // succeeds. + if (SemaRef.getLangOpts().OpenCL && T.getType()->isTemplateTypeParmType()) + Quals.removeAddressSpace(); + QualType Result = getDerived().TransformType(TLB, T.getUnqualifiedLoc()); if (Result.isNull()) return QualType(); @@ -5273,6 +5282,13 @@ if (ResultType.isNull()) return QualType(); + // Return type cann't be qualified with an address space. + if (ResultType.getAddressSpace() != LangAS::Default) { + SemaRef.Diag(TL.getReturnLoc().getBeginLoc(), + diag::err_attribute_address_function_type); + return QualType(); + } + if (getDerived().TransformFunctionTypeParams( TL.getBeginLoc(), TL.getParams(), TL.getTypePtr()->param_type_begin(), Index: test/CodeGenOpenCLCXX/template-address-spaces.cl =================================================================== --- test/CodeGenOpenCLCXX/template-address-spaces.cl +++ test/CodeGenOpenCLCXX/template-address-spaces.cl @@ -21,8 +21,6 @@ S sint; S sintptr; S<__global int*> sintptrgl; - // FIXME: Preserve AS in TreeTransform - //S<__global int> sintgl; sint.foo(); sintptr.foo(); Index: test/SemaOpenCLCXX/address-space-templates.cl =================================================================== --- /dev/null +++ test/SemaOpenCLCXX/address-space-templates.cl @@ -0,0 +1,12 @@ +//RUN: %clang_cc1 %s -cl-std=c++ -pedantic -verify -fsyntax-only + +template +struct S { + T a; // expected-error{{field may not be qualified with an address space}} + T f1(); // expected-error{{function type may not be qualified with an address space}} + void f2(T); // expected-error{{parameter may not be qualified with an address space}} +}; + +void bar() { + S sintgl; // expected-note{{in instantiation of template class 'S' requested here}} +}