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>