Re: Proposed semantics for attributes in C++ (and in C?)

2006-10-17 Thread Mark Mitchell

Geoffrey Keating wrote:


A typedef declaration which adds semantic attributes to a non-class
type is valid, but again creates an entirely new type. 


 It is invalid to

do anything that would require either type_info or a mangled name for
Q, including using it as an argument to typeid, thowing an exception
of a type involving Q, or declaring a template to take a parameter
of a type involving Q.  (We could relax some of these restrictions
in future, if we add mangling support for attributes.)


Declaring a function which takes a 'Q' also requires the mangled name of 'Q'.


Good point!


where T is some invented type name different from all others in the program.

For example given:

   __attribute__((packed)) S v;

the type of v is __attribute__((packed)) S *, and cannot be
passed to a function expecting an S*, but can of course be passed to
a function expecting an __attribute__((packed)) S *, or a typedef
for such a type.


... except that there can't be any such functions.  You could assign
it to another variable of the same type, or a field of a class with
that type.


Right.  And, since there seems to be consensus that you shouldn't be 
able to apply semantic attributes to class types, packed is a bad 
example there too.  (If you applied packed at the point of declaration 
of S, then S has a different layout than it otherwise would, but we 
don't need to do anything regarding mangling, etc.)


Thanks,

--
Mark Mitchell
CodeSourcery
[EMAIL PROTECTED]
(650) 331-3385 x713


Re: Proposed semantics for attributes in C++ (and in C?)

2006-10-16 Thread Joseph S. Myers
On Mon, 16 Oct 2006, Jason Merrill wrote:

 Mark Mitchell wrote:
  Yes, I would be happy to explicitly ignore semantic attributes in typedefs
  as well, with a warning (or even an error).  However, I had not realized
  that we ever did that; I'm surprised that the change that instituted this is
  so recent.  I suppose that explains why we're suddenly seeing a rash of such
  problems.  Jason, as you made this change, do you have any comments on the
  proposal?
 
 I don't think my patch changed the handling of class typedefs; certainly my
 intent was only to change how we handle
 
   class __attribute ((foo)) C
 
 Previously we rejected it, now we apply the attributes to the class.

I was referring to the change in extend.texi

-the closing brace.  It is ignored if the content of the structure, union
-or enumerated type is not defined in the specifier in which the
-attribute specifier list is used---that is, in usages such as
[EMAIL PROTECTED] __attribute__((foo)) bar} with no following opening brace.
+the closing brace.  The former syntax is preferred.

(note that r115086 changed extend.texi but extend.texi doesn't appear to 
be mentioned in the log message).  The old text only covered some of the 
problem cases, but the statement that attributes were ignored in such 
cases was still removed.

-- 
Joseph S. Myers
[EMAIL PROTECTED]


Re: Proposed semantics for attributes in C++ (and in C?)

2006-10-16 Thread Mark Mitchell

Jason Merrill wrote:

I don't think my patch changed the handling of class typedefs; certainly 
my intent was only to change how we handle


  class __attribute ((foo)) C

Previously we rejected it, now we apply the attributes to the class.


OK, that certainly makes sense.  (That's one of the items in the 
proposal I wrote up: that you can apply attributes at the point of 
declaration of a class.)



Which PRs are you referring to?


One example is:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28558

However, this is a problem with non-semantic attributes, and not related 
to your patch.  So, I apologize for any aspersions cast.  But, it does 
motivate for writing something down about what we want semantics we 
want.  Here, what I think we want is (as per the proposal) to create a 
new anonymous typedef for __attribute__((unused)) A, but consider that 
the same type as A.


I was pretty sure there were other PRs, but I'm not able to find them 
now, so perhaps I was dreaming.  I thought there were also PRs about 
typeid and mangling failing (and/or doing the wrong thing) for types 
with attributes (including scalars with attributes).


I'd be inclined to prohibit semantic attributes on typedefs in general. 


That's certainly simpler.  I'm happy to be talked out of that idea. :-)

 Extending the type system to handle attribute types seems excessively 
complicated.  I think we should define a set of attributes which prevent 
us from taking the address of a variable with that attribute 
(packed...anything else?) and check for them at the same places we check 
for taking the address of a bitfield.


That seems like a good idea to me.  However, one consequence is that a 
packed class cannot have member functions (since you'd never be able to 
get a this pointer for them); do you think that's OK?


--
Mark Mitchell
CodeSourcery
[EMAIL PROTECTED]
(650) 331-3385 x713


Re: Proposed semantics for attributes in C++ (and in C?)

2006-10-16 Thread Jason Merrill

Joseph S. Myers wrote:

I was referring to the change in extend.texi

-the closing brace.  It is ignored if the content of the structure, union
-or enumerated type is not defined in the specifier in which the
-attribute specifier list is used---that is, in usages such as
[EMAIL PROTECTED] __attribute__((foo)) bar} with no following opening brace.
+the closing brace.  The former syntax is preferred.


That passage has nothing to do with typedefs.  The change is that 
previously, if we saw


  class __attribute ((visibility (hidden))) C;

we would ignore the attribute, now we record it.

My change to the previous paragraph now seems excessive, however:


-You may specify the @code{aligned} and @code{transparent_union}
-attributes either in a @code{typedef} declaration or just past the
-closing curly brace of a complete enum, struct or union type
[EMAIL PROTECTED] and the @code{packed} attribute only past the closing
-brace of a definition.
+You may specify type attributes either in a @code{typedef} declaration
+or in an enum, struct or union type declaration or definition.


I didn't notice the distinction this passage was trying to make between 
packed and other attributes, just that it was an incomplete list.  In 
removing the incomplete list I also removed the useful separation.


Jason


Re: Proposed semantics for attributes in C++ (and in C?)

2006-10-16 Thread Geoffrey Keating
Mark Mitchell [EMAIL PROTECTED] writes:

 We have a number of C++ PRs open around problems with code like this:
 
struct S {
  void f();
  virtual void g();
};
 
typedef __attribute__((...)) struct S T;
 
 If the attribute makes any substantive change to S (e.g., changes its
 size, alignment, etc.) then bad things happen.  For example, the
 member functions of S have expectations about the layout of S that
 are not satisfied if they are called with a T.  Depending on the
 attribute and circumstances, we do all manner of bad things, including
 ICE, generate wrong code, etc.
 
 For a while now, I've been promising to propose semantics for these
 constructs.  Here is a sketch of the semantics that I think we should
 have.  (I say a sketch because I have not attempted to write
 standardese.)
 
 All attributes must be classified as either semantic or
 non-semantic attributes.  A semantic attribute is one which might
 affect code-generation in any way.  A non-semantic attribute cannot
 affect code-generation.  For example, used and deprecated are
 non-semantic attributes; there is no way to observe, by looking at an
 object file, whether or not a class has been marked with one of these
 attributes.  In contrast, packed is a semantic attribute; the size
 of a class is different depending on whether or not it is packed.
 
 Any attribute may be applied at the point of definition of a
 class. These attributes (whether semantic or non-semantic) apply to
 the class. For example, if the class is packed, then the member
 functions expect the this pointer to point to the packed class.
 
 A typedef declaration which adds only non-semantic attributes is
 always valid.  As with other typedefs, the typedef declaration creates
 a new name for an existing type.  The type referred to by that name is
 the same type as the original type.  However, the *name* has
 additional properties, implied by the (non-semantic) attributes.  For
 example, using a deprecated name for a type results in a deprecation
 warning. But, a function declared to take a parameter with the
 non-deprecated name may be passed a parameter with the deprecated
 name.
 
 A typedef declaration which adds semantic attributes to a class type,
 other than POD classes with no explicitly declared members other than
 data members, to arrays of such classes, to arrays of such arrays,
 etc., is invalid. (POD-ness alone is not satisfactory, as PODs may
 contain function members, and I think dealing with static data members
 and typedef members is not worth the trouble.)
 
 A typedef declaration which adds semantic attributes to a POD class
 type with no function members is valid, but creates an entirely new
 type, different from all other types except others formed by adding
 the same combination of semantic attributes to the same original class
 type.  In the example above, if the typedef adds a semantic attribute,
 you may not pass an S to a function expecting a T or vice versa.
 Neither may you pass an S* to a function expecting a T*, without
 an explicit reinterpret_cast.  The name of T, for linkage purposes,
 is T, and there is no implicit T::S type; instead, however, there
 is a T::T type.  (Various consequences follow; for example,
 typeid(T) gives you a type_info object that indicates that the name of
 the type is T.) References to the original type from within the
 types of the members of the class still refer to the original class.
 For example, in:
 
struct S {
  char c;
  S* next;
};
typedef __attribute__((packed)) S T;
 
 the data member T::next has type S*, not T*.
 
 A typedef declaration which adds semantic attributes to a non-class
 type is valid, but again creates an entirely new type.  (We might want
 a special exception to the entirely new type rule for the mode
 attribute, declaring that typedef __attribute__((mode(DI))) int LL
 is equivalent to typedef long long LL; on platforms where long
 long has DImode.) So,
 
typedef S* P;
typedef __attribute__((...)) P Q;
 
 creates a type Q that is incompatible with S* if the attribute is
 semantic.  However, the type of *Q is still S.  It is invalid to
 do anything that would require either type_info or a mangled name for
 Q, including using it as an argument to typeid, thowing an exception
 of a type involving Q, or declaring a template to take a parameter
 of a type involving Q.  (We could relax some of these restrictions
 in future, if we add mangling support for attributes.)

Declaring a function which takes a 'Q' also requires the mangled name of 'Q'.

 A variable declaration involving attributes, like:
 
__attribute__((...)) S v;
 
 is treated as syntactic sugar for:
 
typedef __attribute__((...)) S T;
T v;
 
 where T is some invented type name different from all others in the program.
 
 For example given:
 
__attribute__((packed)) S v;
 
 the type of v is __attribute__((packed)) S *, and cannot be
 passed to a function expecting an S*, 

Re: Proposed semantics for attributes in C++ (and in C?)

2006-10-15 Thread Joseph S. Myers
On Sun, 15 Oct 2006, Mark Mitchell wrote:

 We have a number of C++ PRs open around problems with code like this:
 
   struct S {
 void f();
 virtual void g();
   };
 
   typedef __attribute__((...)) struct S T;

I was happy with the state before r115086 (i.e. with it being documented 
that such attributes on typedefs are ignored).  But given that we are now 
attempting to honour them, the proposed semantics seem reasonable.

The proposal requires documentation for each (type) attribute of whether 
it is semantic or non-semantic.  In general the documentation of attribute 
semantics needs cleaning up to make clear just when each attribute can be 
used and what exactly it means (and the code needs cleaning up to follow 
sensible documented semantics) - for example, attributes with 
documentation split and duplicated because they apply to more than one of 
functions, variables and types.  (The syntax documentation is cleaner, and 
I think accurate for C, but it does include some speculative future 
possibilities that seemed nice when I first wrote it but I no longer think 
would be a good idea.)

-- 
Joseph S. Myers
[EMAIL PROTECTED]


Re: Proposed semantics for attributes in C++ (and in C?)

2006-10-15 Thread Mark Mitchell

Joseph S. Myers wrote:


On Sun, 15 Oct 2006, Mark Mitchell wrote:


We have a number of C++ PRs open around problems with code like this:

  struct S {
void f();
virtual void g();
  };

  typedef __attribute__((...)) struct S T;


I was happy with the state before r115086 (i.e. with it being documented 
that such attributes on typedefs are ignored).  But given that we are now 
attempting to honour them, the proposed semantics seem reasonable.


Yes, I would be happy to explicitly ignore semantic attributes in 
typedefs as well, with a warning (or even an error).  However, I had not 
realized that we ever did that; I'm surprised that the change that 
instituted this is so recent.  I suppose that explains why we're 
suddenly seeing a rash of such problems.  Jason, as you made this 
change, do you have any comments on the proposal?


--
Mark Mitchell
CodeSourcery
[EMAIL PROTECTED]
(650) 331-3385 x713


Re: Proposed semantics for attributes in C++ (and in C?)

2006-10-15 Thread Chris Lattner

On Oct 15, 2006, at 3:12 PM, Mark Mitchell wrote:

A typedef declaration which adds semantic attributes to a POD class  
type with no function members is valid, but creates an entirely new  
type, different from all other types except others formed by adding  
the same combination of semantic attributes to the same original  
class type.  In the example above, if the typedef adds a semantic  
attribute, you may not pass an S to a function expecting a T or  
vice versa.  Neither may you pass an S* to a function expecting a  
T*, without an explicit reinterpret_cast.  The name of T, for  
linkage purposes, is T, and there is no implicit T::S type;  
instead, however, there is a T::T type.  (Various consequences  
follow; for example, typeid(T) gives you a type_info object that  
indicates that the name of the type is T.)


Note that this is an ABI change for any code that uses these.  I  
agree that it seems cleaner to just disallow this practice entirely,  
particularly if it is a recent invention.  In any case, having the  
compiler reject code that does not or will not work is a much better  
position to be in than silently miscompiling code.


-Chris


Re: Proposed semantics for attributes in C++ (and in C?)

2006-10-15 Thread Richard Kenner
 If the attribute makes any substantive change to S (e.g., changes its 
 size, alignment, etc.) then bad things happen.  For example, the member 
 functions of S have expectations about the layout of S that are not 
 satisfied if they are called with a T.  Depending on the attribute and 
 circumstances, we do all manner of bad things, including ICE, generate 
 wrong code, etc.
 
 For a while now, I've been promising to propose semantics for these 
 constructs.

You might want to take a look at the Ada concept of freeze point.  That's
one approach to a similar problem.