On Wed, Feb 20, 2013 at 8:23 PM, Matt Arsenault <span dir="ltr"><<a href="mailto:Matthew.Arsenault@amd.com" target="_blank">Matthew.Arsenault@amd.com</a>></span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hi rsmith,<br>
<br>
Previously adding an address space to a struct member was incorrectly accepted, and would later hit an assertion when accessed. This patch causes it to emit an error rejecting this.<br>
<br>
struct Foo<br>
{<br>
    __attribute__((address_space(2))) // Should not be accepted<br>
    int m_x;<br>
};<br>
<br>
void foo_user()<br>
{<br>
    struct Foo bar;<br>
    bar.m_x = 4; // Assertion failed<br>
}<br>
<br>
<a href="http://llvm-reviews.chandlerc.com/D444" target="_blank">http://llvm-reviews.chandlerc.com/D444</a><br>
<br>
Files:<br>
  include/clang/Basic/DiagnosticSemaKinds.td<br>
  lib/Sema/SemaDecl.cpp<br>
  lib/Sema/SemaExprMember.cpp<br>
  test/Sema/address_spaces.c<br>
<br>
Index: include/clang/Basic/DiagnosticSemaKinds.td<br>
===================================================================<br>
--- include/clang/Basic/DiagnosticSemaKinds.td<br>
+++ include/clang/Basic/DiagnosticSemaKinds.td<br>
@@ -1721,6 +1721,8 @@<br>
   "automatic variable qualified with an address space">;<br>
 def err_arg_with_address_space : Error<<br>
   "parameter may not be qualified with an address space">;<br>
+def err_member_with_address_space : Error<<br>
+  "member may not be qualified with an address space">;<br></blockquote><div><br></div><div>"member" is the wrong word to use here (it includes static data members and member functions too). For diagnostics shared between C and C++, we generally use "field" (some C++-specific diagnostics use "non-static data member" instead).</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
 def err_attr_objc_ownership_redundant : Error<<br>
   "the type %0 is already explicitly ownership-qualified">;<br>
 def err_attribute_not_string : Error<<br>
Index: lib/Sema/SemaDecl.cpp<br>
===================================================================<br>
--- lib/Sema/SemaDecl.cpp<br>
+++ lib/Sema/SemaDecl.cpp<br>
@@ -9992,19 +9992,24 @@<br>
     }<br>
   }<br>
<br>
+  // TR 18037 does not allow fields to be declared with address spaces.<br>
+  if (T.getQualifiers().hasAddressSpace()) {<br>
+    Diag(Loc, diag::err_member_with_address_space);<br>
+    D.setInvalidType();<br>
+  }<br>
+<br>
   // OpenCL 1.2 spec, s6.9 r:<br>
   // The event type cannot be used to declare a structure or union field.<br>
   if (LangOpts.OpenCL && T->isEventT()) {<br>
     Diag(Loc, diag::err_event_t_struct_field);<br>
     D.setInvalidType();<br>
   }<br>
<br>
-<br>
   DiagnoseFunctionSpecifiers(D);<br>
<br>
   if (D.getDeclSpec().isThreadSpecified())<br>
     Diag(D.getDeclSpec().getThreadSpecLoc(), diag::err_invalid_thread);<br>
-<br>
+<br>
   // Check to see if this name was declared as a member previously<br>
   NamedDecl *PrevDecl = 0;<br>
   LookupResult Previous(*this, II, Loc, LookupMemberName, ForRedeclaration);<br>
Index: lib/Sema/SemaExprMember.cpp<br>
===================================================================<br>
--- lib/Sema/SemaExprMember.cpp<br>
+++ lib/Sema/SemaExprMember.cpp<br>
@@ -1598,27 +1598,27 @@<br>
   } else {<br>
     QualType BaseType = BaseExpr->getType();<br>
     if (IsArrow) BaseType = BaseType->getAs<PointerType>()->getPointeeType();<br>
-<br>
+<br>
     Qualifiers BaseQuals = BaseType.getQualifiers();<br>
-<br>
+<br>
     // GC attributes are never picked up by members.<br>
     BaseQuals.removeObjCGCAttr();<br>
-<br>
+<br>
     // CVR attributes from the base are picked up by members,<br>
     // except that 'mutable' members don't pick up 'const'.<br>
     if (Field->isMutable()) BaseQuals.removeConst();<br>
-<br>
+<br>
     Qualifiers MemberQuals<br>
     = S.Context.getCanonicalType(MemberType).getQualifiers();<br>
-<br>
-    // TR 18037 does not allow fields to be declared with address spaces.<br>
+<br>
     assert(!MemberQuals.hasAddressSpace());<br>
-<br>
+<br>
+<br>
     Qualifiers Combined = BaseQuals + MemberQuals;<br>
     if (Combined != MemberQuals)<br>
       MemberType = S.Context.getQualifiedType(MemberType, Combined);<br>
   }<br>
-<br>
+<br>
   S.UnusedPrivateFields.remove(Field);<br>
<br>
   ExprResult Base =<br>
Index: test/Sema/address_spaces.c<br>
===================================================================<br>
--- test/Sema/address_spaces.c<br>
+++ test/Sema/address_spaces.c<br>
@@ -6,7 +6,7 @@<br>
<br>
 void bar(_AS2 int a); // expected-error {{parameter may not be qualified with an address space}}<br>
<br>
-void foo(_AS3 float *a,<br>
+void foo(_AS3 float *a,<br>
          _AS1 float b) // expected-error {{parameter may not be qualified with an address space}}<br>
 {<br>
   _AS2 *x;// expected-warning {{type specifier missing, defaults to 'int'}}<br>
@@ -48,3 +48,19 @@<br>
 typedef void ft(void);<br>
 _AS1 ft qf; // expected-error {{function type may not be qualified with an address space}}<br>
 typedef _AS1 ft qft; // expected-error {{function type may not be qualified with an address space}}<br>
+<br>
+<br>
+typedef _AS2 int AS2Int;<br>
+<br>
+struct HasASMembers<br>
+{<br>
+  _AS2 int as_member; // expected-error {{member may not be qualified with an address space}}<br>
+   AS2Int typedef_as_member; // expected-error {{member may not be qualified with an address space}}<br>
+};<br>
+<br>
+// Assertion failure was when the member was accessed<br>
+void access_as_member()<br>
+{<br>
+    struct HasASMembers x;<br>
+    (void) bar.as_member;<br>
+}<br>
</blockquote></div><br>