[OpenCL] Improve diags for addr spaces in templates

Fix ICEs on template instantiations that were leading to
the creation of invalid code patterns with address spaces.

Incorrect cases are now diagnosed properly.

Differential Revision: https://reviews.llvm.org/D54858

llvm-svn: 347865
This commit is contained in:
Anastasia Stulova 2018-11-29 14:11:15 +00:00
parent 6e3be9d12e
commit 6a4c34689e
5 changed files with 43 additions and 24 deletions

View File

@ -15148,22 +15148,6 @@ FieldDecl *Sema::HandleField(Scope *S, RecordDecl *Record,
}
}
// 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())
@ -15275,12 +15259,30 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
}
}
// 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()) {

View File

@ -7226,8 +7226,9 @@ static void deduceOpenCLImplicitAddrSpace(TypeProcessingState &State,
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 {

View File

@ -5284,6 +5284,13 @@ QualType TreeTransform<Derived>::TransformFunctionProtoType(
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(),

View File

@ -21,11 +21,8 @@ void bar(){
S<int> sint;
S<int*> sintptr;
S<__global int*> sintptrgl;
// FIXME: Preserve AS in TreeTransform
//S<__global int> sintgl;
sint.foo();
sintptr.foo();
sintptrgl.foo();
//sintgl.foo();
}

View File

@ -0,0 +1,12 @@
//RUN: %clang_cc1 %s -cl-std=c++ -pedantic -verify -fsyntax-only
template <typename T>
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<const __global int> sintgl; // expected-note{{in instantiation of template class 'S<const __global int>' requested here}}
}