This revision was automatically updated to reflect the committed changes.
Closed by commit rC348382: [OpenCL] Diagnose conflicting address spaces in
templates. (authored by stulova, committed by ).
Changed prior to commit:
https://reviews.llvm.org/D55127?vs=176793&id=176841#toc
Repository:
rC Clang
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D55127/new/
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: 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<
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/SemaType.cpp
===================================================================
--- lib/Sema/SemaType.cpp
+++ lib/Sema/SemaType.cpp
@@ -7201,7 +7201,10 @@
!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 for dependent types because they might end
+ // up instantiating to a type with an explicit address space qualifier.
+ T->isDependentType())
return;
LangAS ImpAddr = LangAS::Default;
@@ -7226,9 +7229,8 @@
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.
+ 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 {
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);
}
@@ -4240,13 +4239,14 @@
QualType
TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
QualifiedTypeLoc T) {
- Qualifiers Quals = T.getType().getLocalQualifiers();
-
QualType Result = getDerived().TransformType(TLB, T.getUnqualifiedLoc());
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 +4256,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.
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits