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/SemaType.cpp =================================================================== --- lib/Sema/SemaType.cpp +++ lib/Sema/SemaType.cpp @@ -7223,8 +7223,9 @@ if (IsPointee) { ImpAddr = LangAS::opencl_generic; } else { - if (D.getContext() == DeclaratorContext::TemplateArgContext) { - // Do not deduce address space for non-pointee type in template args + if (D.getContext() == DeclaratorContext::TemplateArgContext || + T->isDependentType()) { + // Do not deduce address space for non-pointee type in templates. } else if (D.getContext() == DeclaratorContext::FileContext) { ImpAddr = LangAS::opencl_global; } else { Index: lib/Sema/TreeTransform.h =================================================================== --- lib/Sema/TreeTransform.h +++ lib/Sema/TreeTransform.h @@ -5273,6 +5273,13 @@ if (ResultType.isNull()) return QualType(); + // Return type can not 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,11 +21,8 @@ S sint; S sintptr; S<__global int*> sintptrgl; - // FIXME: Preserve AS in TreeTransform - //S<__global int> sintgl; sint.foo(); sintptr.foo(); sintptrgl.foo(); - //sintgl.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}} +}