Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -2576,6 +2576,9 @@ "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; def err_attribute_address_function_type : Error< "function type may not be qualified with an address space">; def err_as_qualified_auto_decl : Error< Index: lib/Sema/SemaType.cpp =================================================================== --- lib/Sema/SemaType.cpp +++ lib/Sema/SemaType.cpp @@ -5758,14 +5758,6 @@ 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) @@ -5796,6 +5788,20 @@ LangAS ASIdx = getLangASFromTargetAS(static_cast(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); } @@ -5817,15 +5823,6 @@ /// 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()) { @@ -5888,6 +5885,21 @@ 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); } } Index: test/Sema/address_spaces.c =================================================================== --- test/Sema/address_spaces.c +++ test/Sema/address_spaces.c @@ -14,6 +14,7 @@ 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}} Index: test/SemaOpenCL/address-spaces.cl =================================================================== --- test/SemaOpenCL/address-spaces.cl +++ test/SemaOpenCL/address-spaces.cl @@ -62,4 +62,6 @@ __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}} }