Anastasia created this revision. Anastasia added a reviewer: rjmccall. Herald added a subscriber: yaxunl.
Added new diagnostics when templates are instantiated with different address space from the one provided in definition. This also prevents deducing generic address space in pointer type of templates to allow giving them concrete address space. https://reviews.llvm.org/D55127 Files: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaType.cpp lib/Sema/TreeTransform.h test/SemaOpenCLCXX/address-space-templates.cl
Index: test/SemaOpenCLCXX/address-space-templates.cl =================================================================== --- test/SemaOpenCLCXX/address-space-templates.cl +++ test/SemaOpenCLCXX/address-space-templates.cl @@ -7,6 +7,25 @@ void f2(T); // expected-error{{parameter may not be qualified with an address space}} }; +template <typename T> +T foo1(__global T *i) { // expected-note{{candidate template ignored: substitution failure [with T = __local int]: conflicting address space qualifiers are provided between types '__global T' and '__local int'}} + return *i; +} + +template <typename T> +T *foo2(T *i) { + return i; +} + +template <typename T> +void foo3() { + __private T ii; // expected-error{{conflicting address space qualifiers are provided between types 'T' and '__global int'}} +} + void bar() { S<const __global int> sintgl; // expected-note{{in instantiation of template class 'S<const __global int>' requested here}} + + foo1<__local int>(1); // expected-error{{no matching function for call to 'foo1'}} + foo2<__global int>(0); + foo3<__global int>(); // expected-note{{in instantiation of function template specialization 'foo3<__global int>' requested here}} } Index: lib/Sema/TreeTransform.h =================================================================== --- lib/Sema/TreeTransform.h +++ lib/Sema/TreeTransform.h @@ -684,15 +684,13 @@ OMPClause *Transform ## Class(Class *S); #include "clang/Basic/OpenMPKinds.def" - /// Build a new qualified type given its unqualified type and type - /// qualifiers. + /// Build a new qualified type given its unqualified type and type location. /// /// By default, this routine adds type qualifiers only to types that can /// have qualifiers, and silently suppresses those qualifiers that are not /// permitted. Subclasses may override this routine to provide different /// behavior. - QualType RebuildQualifiedType(QualType T, SourceLocation Loc, - Qualifiers Quals); + QualType RebuildQualifiedType(QualType T, QualifiedTypeLoc TL); /// Build a new pointer type given its pointee type. /// @@ -4228,8 +4226,9 @@ return nullptr; if (QTL) { - Result = getDerived().RebuildQualifiedType( - Result, QTL.getBeginLoc(), QTL.getType().getLocalQualifiers()); + Result = getDerived().RebuildQualifiedType(Result, QTL); + if (Result.isNull()) + return nullptr; TLB.TypeWasModifiedSafely(Result); } @@ -4246,7 +4245,10 @@ if (Result.isNull()) return QualType(); - Result = getDerived().RebuildQualifiedType(Result, T.getBeginLoc(), Quals); + Result = getDerived().RebuildQualifiedType(Result, T); + + if (Result.isNull()) + return QualType(); // RebuildQualifiedType might have updated the type, but not in a way // that invalidates the TypeLoc. (There's no location information for @@ -4256,10 +4258,21 @@ return Result; } -template<typename Derived> +template <typename Derived> QualType TreeTransform<Derived>::RebuildQualifiedType(QualType T, - SourceLocation Loc, - Qualifiers Quals) { + QualifiedTypeLoc TL) { + + SourceLocation Loc = TL.getBeginLoc(); + Qualifiers Quals = TL.getType().getLocalQualifiers(); + + if (((T.getAddressSpace() != LangAS::Default && + Quals.getAddressSpace() != LangAS::Default)) && + T.getAddressSpace() != Quals.getAddressSpace()) { + SemaRef.Diag(Loc, diag::err_address_space_mismatch_templ_inst) + << TL.getType() << T; + return QualType(); + } + // C++ [dcl.fct]p7: // [When] adding cv-qualifications on top of the function type [...] the // cv-qualifiers are ignored. Index: lib/Sema/SemaType.cpp =================================================================== --- lib/Sema/SemaType.cpp +++ lib/Sema/SemaType.cpp @@ -7201,7 +7201,9 @@ !IsPointee) || // Do not deduce addr space of the void type, e.g. in f(void), otherwise // it will fail some sema check. - (T->isVoidType() && !IsPointee)) + (T->isVoidType() && !IsPointee) || + // Do not deduce address spaces in templates. + T->isDependentType()) return; LangAS ImpAddr = LangAS::Default; @@ -7226,10 +7228,10 @@ if (IsPointee) { ImpAddr = LangAS::opencl_generic; } else { - if (D.getContext() == DeclaratorContext::TemplateArgContext || - T->isDependentType()) { - // Do not deduce address space for non-pointee type in templates. - } else if (D.getContext() == DeclaratorContext::FileContext) { + if (D.getContext() == DeclaratorContext::TemplateArgContext) + // Do not deduce address space for non-pointee type in template arg. + ; + else if (D.getContext() == DeclaratorContext::FileContext) { ImpAddr = LangAS::opencl_global; } else { if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static || Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -2634,6 +2634,8 @@ "field may not be qualified with an address space">; def err_compound_literal_with_address_space : Error< "compound literal in function scope may not be qualified with an address space">; +def err_address_space_mismatch_templ_inst : Error< + "conflicting address space qualifiers are provided between types %0 and %1">; def err_attr_objc_ownership_redundant : Error< "the type %0 is already explicitly ownership-qualified">; def err_invalid_nsnumber_type : Error<
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits