[PATCH] Fix assertion failure when a member is given an address space.

Richard Smith richard at metafoo.co.uk
Wed Feb 20 20:52:10 PST 2013


On Wed, Feb 20, 2013 at 8:23 PM, Matt Arsenault
<Matthew.Arsenault at amd.com>wrote:

> Hi rsmith,
>
> 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.
>
> struct Foo
> {
>     __attribute__((address_space(2))) // Should not be accepted
>     int m_x;
> };
>
> void foo_user()
> {
>     struct Foo bar;
>     bar.m_x = 4; // Assertion failed
> }
>
> http://llvm-reviews.chandlerc.com/D444
>
> Files:
>   include/clang/Basic/DiagnosticSemaKinds.td
>   lib/Sema/SemaDecl.cpp
>   lib/Sema/SemaExprMember.cpp
>   test/Sema/address_spaces.c
>
> Index: include/clang/Basic/DiagnosticSemaKinds.td
> ===================================================================
> --- include/clang/Basic/DiagnosticSemaKinds.td
> +++ include/clang/Basic/DiagnosticSemaKinds.td
> @@ -1721,6 +1721,8 @@
>    "automatic variable qualified with an address space">;
>  def err_arg_with_address_space : Error<
>    "parameter may not be qualified with an address space">;
> +def err_member_with_address_space : Error<
> +  "member may not be qualified with an address space">;
>

"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).


>  def err_attr_objc_ownership_redundant : Error<
>    "the type %0 is already explicitly ownership-qualified">;
>  def err_attribute_not_string : Error<
> Index: lib/Sema/SemaDecl.cpp
> ===================================================================
> --- lib/Sema/SemaDecl.cpp
> +++ lib/Sema/SemaDecl.cpp
> @@ -9992,19 +9992,24 @@
>      }
>    }
>
> +  // TR 18037 does not allow fields to be declared with address spaces.
> +  if (T.getQualifiers().hasAddressSpace()) {
> +    Diag(Loc, diag::err_member_with_address_space);
> +    D.setInvalidType();
> +  }
> +
>    // OpenCL 1.2 spec, s6.9 r:
>    // The event type cannot be used to declare a structure or union field.
>    if (LangOpts.OpenCL && T->isEventT()) {
>      Diag(Loc, diag::err_event_t_struct_field);
>      D.setInvalidType();
>    }
>
> -
>    DiagnoseFunctionSpecifiers(D);
>
>    if (D.getDeclSpec().isThreadSpecified())
>      Diag(D.getDeclSpec().getThreadSpecLoc(), diag::err_invalid_thread);
> -
> +
>    // Check to see if this name was declared as a member previously
>    NamedDecl *PrevDecl = 0;
>    LookupResult Previous(*this, II, Loc, LookupMemberName,
> ForRedeclaration);
> Index: lib/Sema/SemaExprMember.cpp
> ===================================================================
> --- lib/Sema/SemaExprMember.cpp
> +++ lib/Sema/SemaExprMember.cpp
> @@ -1598,27 +1598,27 @@
>    } else {
>      QualType BaseType = BaseExpr->getType();
>      if (IsArrow) BaseType =
> BaseType->getAs<PointerType>()->getPointeeType();
> -
> +
>      Qualifiers BaseQuals = BaseType.getQualifiers();
> -
> +
>      // GC attributes are never picked up by members.
>      BaseQuals.removeObjCGCAttr();
> -
> +
>      // CVR attributes from the base are picked up by members,
>      // except that 'mutable' members don't pick up 'const'.
>      if (Field->isMutable()) BaseQuals.removeConst();
> -
> +
>      Qualifiers MemberQuals
>      = S.Context.getCanonicalType(MemberType).getQualifiers();
> -
> -    // TR 18037 does not allow fields to be declared with address spaces.
> +
>      assert(!MemberQuals.hasAddressSpace());
> -
> +
> +
>      Qualifiers Combined = BaseQuals + MemberQuals;
>      if (Combined != MemberQuals)
>        MemberType = S.Context.getQualifiedType(MemberType, Combined);
>    }
> -
> +
>    S.UnusedPrivateFields.remove(Field);
>
>    ExprResult Base =
> Index: test/Sema/address_spaces.c
> ===================================================================
> --- test/Sema/address_spaces.c
> +++ test/Sema/address_spaces.c
> @@ -6,7 +6,7 @@
>
>  void bar(_AS2 int a); // expected-error {{parameter may not be qualified
> with an address space}}
>
> -void foo(_AS3 float *a,
> +void foo(_AS3 float *a,
>           _AS1 float b) // expected-error {{parameter may not be qualified
> with an address space}}
>  {
>    _AS2 *x;// expected-warning {{type specifier missing, defaults to
> 'int'}}
> @@ -48,3 +48,19 @@
>  typedef void ft(void);
>  _AS1 ft qf; // expected-error {{function type may not be qualified with
> an address space}}
>  typedef _AS1 ft qft; // expected-error {{function type may not be
> qualified with an address space}}
> +
> +
> +typedef _AS2 int AS2Int;
> +
> +struct HasASMembers
> +{
> +  _AS2 int as_member; // expected-error {{member may not be qualified
> with an address space}}
> +   AS2Int typedef_as_member; // expected-error {{member may not be
> qualified with an address space}}
> +};
> +
> +// Assertion failure was when the member was accessed
> +void access_as_member()
> +{
> +    struct HasASMembers x;
> +    (void) bar.as_member;
> +}
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130220/62676087/attachment.html>


More information about the cfe-commits mailing list