Skip to content

Commit

Permalink
[Sema] Allow creating types with multiple of the same addrspace.
Browse files Browse the repository at this point in the history
Summary:
The comment with the OpenCL clause about this clearly
says: "No type shall be qualified by qualifiers for
two or more different address spaces."

This must mean that two or more qualifiers for the
_same_ address space is allowed. However, it is
likely unintended by the programmer, so emit a
warning.

For dependent address space types, reject them like
before since we cannot know what the address space
will be.

Patch by Bevin Hansson (ebevhan).

Reviewers: Anastasia

Reviewed By: Anastasia

Subscribers: bader, cfe-commits

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

llvm-svn: 335103
  • Loading branch information
bader committed Jun 20, 2018
1 parent 16662f3 commit f29d777
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 17 deletions.
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Expand Up @@ -2576,6 +2576,9 @@ def err_attribute_address_space_too_high : Error<
"address space is larger than the maximum supported (%0)">;
def err_attribute_address_multiple_qualifiers : Error<
"multiple address spaces specified for type">;
def warn_attribute_address_multiple_identical_qualifiers : Warning<
"multiple identical address spaces specified for type">,
InGroup<DuplicateDeclSpecifier>;
def err_attribute_address_function_type : Error<
"function type may not be qualified with an address space">;
def err_as_qualified_auto_decl : Error<
Expand Down
46 changes: 29 additions & 17 deletions clang/lib/Sema/SemaType.cpp
Expand Up @@ -5758,14 +5758,6 @@ QualType Sema::BuildAddressSpaceAttr(QualType &T, Expr *AddrSpace,
SourceLocation AttrLoc) {
if (!AddrSpace->isValueDependent()) {

// If this type is already address space qualified, reject it.
// ISO/IEC TR 18037 S5.3 (amending C99 6.7.3): "No type shall be qualified
// by qualifiers for two or more different address spaces."
if (T.getAddressSpace() != LangAS::Default) {
Diag(AttrLoc, diag::err_attribute_address_multiple_qualifiers);
return QualType();
}

llvm::APSInt addrSpace(32);
if (!AddrSpace->isIntegerConstantExpr(addrSpace, Context)) {
Diag(AttrLoc, diag::err_attribute_argument_type)
Expand Down Expand Up @@ -5796,6 +5788,20 @@ QualType Sema::BuildAddressSpaceAttr(QualType &T, Expr *AddrSpace,
LangAS ASIdx =
getLangASFromTargetAS(static_cast<unsigned>(addrSpace.getZExtValue()));

// If this type is already address space qualified with a different
// address space, reject it.
// ISO/IEC TR 18037 S5.3 (amending C99 6.7.3): "No type shall be qualified
// by qualifiers for two or more different address spaces."
if (T.getAddressSpace() != LangAS::Default) {
if (T.getAddressSpace() != ASIdx) {
Diag(AttrLoc, diag::err_attribute_address_multiple_qualifiers);
return QualType();
} else
// Emit a warning if they are identical; it's likely unintended.
Diag(AttrLoc,
diag::warn_attribute_address_multiple_identical_qualifiers);
}

return Context.getAddrSpaceQualType(T, ASIdx);
}

Expand All @@ -5817,15 +5823,6 @@ QualType Sema::BuildAddressSpaceAttr(QualType &T, Expr *AddrSpace,
/// space for the type.
static void HandleAddressSpaceTypeAttribute(QualType &Type,
const AttributeList &Attr, Sema &S){
// If this type is already address space qualified, reject it.
// ISO/IEC TR 18037 S5.3 (amending C99 6.7.3): "No type shall be qualified by
// qualifiers for two or more different address spaces."
if (Type.getAddressSpace() != LangAS::Default) {
S.Diag(Attr.getLoc(), diag::err_attribute_address_multiple_qualifiers);
Attr.setInvalid();
return;
}

// ISO/IEC TR 18037 S5.3 (amending C99 6.7.3): "A function type shall not be
// qualified by an address-space qualifier."
if (Type->isFunctionType()) {
Expand Down Expand Up @@ -5888,6 +5885,21 @@ static void HandleAddressSpaceTypeAttribute(QualType &Type,
llvm_unreachable("Invalid address space");
}

// If this type is already address space qualified with a different
// address space, reject it.
// ISO/IEC TR 18037 S5.3 (amending C99 6.7.3): "No type shall be qualified by
// qualifiers for two or more different address spaces."
if (Type.getAddressSpace() != LangAS::Default) {
if (Type.getAddressSpace() != ASIdx) {
S.Diag(Attr.getLoc(), diag::err_attribute_address_multiple_qualifiers);
Attr.setInvalid();
return;
} else
// Emit a warning if they are identical; it's likely unintended.
S.Diag(Attr.getLoc(),
diag::warn_attribute_address_multiple_identical_qualifiers);
}

Type = S.Context.getAddrSpaceQualType(Type, ASIdx);
}
}
Expand Down
1 change: 1 addition & 0 deletions clang/test/Sema/address_spaces.c
Expand Up @@ -14,6 +14,7 @@ void foo(_AS3 float *a,

int _AS1 _AS2 *Y; // expected-error {{multiple address spaces specified for type}}
int *_AS1 _AS2 *Z; // expected-error {{multiple address spaces specified for type}}
int *_AS1 _AS1 *M; // expected-warning {{multiple identical address spaces specified for type}}

_AS1 int local; // expected-error {{automatic variable qualified with an address space}}
_AS1 int array[5]; // expected-error {{automatic variable qualified with an address space}}
Expand Down
2 changes: 2 additions & 0 deletions clang/test/SemaOpenCL/address-spaces.cl
Expand Up @@ -62,4 +62,6 @@ void func_multiple_addr(void) {
__private __local int *var2; // expected-error {{multiple address spaces specified for type}}
__local private_int_t var3; // expected-error {{multiple address spaces specified for type}}
__local private_int_t *var4; // expected-error {{multiple address spaces specified for type}}
__private private_int_t var5; // expected-warning {{multiple identical address spaces specified for type}}
__private private_int_t *var6;// expected-warning {{multiple identical address spaces specified for type}}
}

0 comments on commit f29d777

Please sign in to comment.