On April 7, 2017 3:37:30 PM GMT+02:00, Bernd Edlinger <bernd.edlin...@hotmail.de> wrote: >On 04/07/17 08:54, Richard Biener wrote: >> On Thu, 6 Apr 2017, Bernd Edlinger wrote: >>> I think get_alias_set(t) will return 0 for typeless_storage >>> types, and therefore has_zero_child will be set anyway. >>> I think both mean the same thing in the end, but it depends on >>> what typeless_storage should actually mean, and we have >>> not yet the same idea about it. >> >> But has_zero_child does not do what we like it to because otherwise >> in the PR using the char[] array member would have worked! >> >> has_zero_child doesn't do that on purpose of course, but this means >> returing alias-set zero for the typeless storage _member_ doesn't >> suffice. >> > >I see you have a certain idea how to solve the C++17 issue. >And yes, I apologize, if I tried to pee on your tree :)
We do have the need to support this part of the C++ standard. For other user code may_alias suffices and I see no reason to haste inventing sth new without a single convincing testcase. GCC/Language extensions should not be added without a good reason. I didn't propose to expose the type flag to users at all. Richard. >What you propose is I think the following: >The C++ FE sets TYPE_TYPELESS_STORAGE a std::byte >and on "unsigned char" if the language dialect is cxx17 >and the TBAA makes all the rest. > >What I propose is as follows: >The TYPE_TYPELESS_STORAGE is a generic attribute, it >can be set on any type, and in the TBAA the attribute >does not squirrel around at all. If it is on a type, >then all DECLs with this type get the alias set 0. >If it is on a member of a struct that does not mean >more than if the struct has a char member this it >sets has_zero_child, which I do not want to mean >anything else than before. > >The C++ FE does the business logic here, in deciding >where to distribute the TYPE_TYPELESS_STORAGE flags. > >in this example >class A { > class B { > std::byte x[5]; > } b; >}; > >std::byte, class B, and class A would get the >TYPE_TYPELESS_STORAGE flag set by the C++FE if >the language dialect is cxx17 or above, >so that you can place anything into any object >of class A and class B, and of type std::byte. > >but in this example >class B { > std::byte x; >}; > >only std::byte would get the TYPE_TYPELESS_STORAGE >flag, so you can not put anyting into an object >of class B, just on an object of std::byte. > > > >>> >>> I wanted to be able to declare a int >__attribute__((typeless_storage)) >>> as in the test case, and the sample in the spec. And that >>> information is not in the TYPE_MAIN_VARIANT. Therefore I look for >>> typeless_storage before "t = TYPE_MAIN_VARIANT (t)". >> >> As I said I believe this is a useless feature. If you want something >> typeless then the underlying type doesn't matter so we can as well >> force it to be an array of char. Makes our live simpler. And >> even makes the code portable to compilers that treat arrays of char >> conservatively. >> > >I just learned that the C11 standard does not guarantee that, and also >an array of char does not provide the necessary alignment per se, at >least without alignment attributes. > >>> >>> See cxx_type_contains_byte_buffer: this function looks recursively >into >>> structures and unions, and returns the information if the beast >>> contains an array of unsigned char or std::byte. >> >> But with a properly designed middle-end feature that's not needed. >> >> There's technically no reason to pessimize TBAA for anything but >> the typeless storage member of a structure. >> > >Yes, it is just a matter of taste. And if you want the middle >end to be flexible here or if everything should work without user >intervention. > > >>>> >>>> @@ -1491,6 +1491,7 @@ struct GTY(()) tree_type_common { >>>> unsigned needs_constructing_flag : 1; >>>> unsigned transparent_aggr_flag : 1; >>>> unsigned restrict_flag : 1; >>>> + unsigned typeless_storage_flag : 1; >>>> unsigned contains_placeholder_bits : 2; >>>> >>>> ENUM_BITFIELD(machine_mode) mode : 8; >>>> >>>> bits are grouped in groups of 8 bits, this breaks it. >>>> >>> >>> Oh..., does this explain the problems that I had with this >version??? >> >> No, just "cosmetics". >> >>>> @@ -8041,7 +8041,8 @@ build_pointer_type_for_mode (tree to_type, >machine >>>> >>>> /* If the pointed-to type has the may_alias attribute set, force >>>> a TYPE_REF_CAN_ALIAS_ALL pointer to be generated. */ >>>> - if (lookup_attribute ("may_alias", TYPE_ATTRIBUTES (to_type))) >>>> + if (TYPE_TYPELESS_STORAGE (to_type) >>>> + || lookup_attribute ("may_alias", TYPE_ATTRIBUTES >(to_type))) >>>> can_alias_all = true; >>>> >>>> /* In some cases, languages will have things that aren't a >POINTER_TYPE >>>> @@ -8110,7 +8111,8 @@ build_reference_type_for_mode (tree to_type, >machi >>>> >>>> /* If the pointed-to type has the may_alias attribute set, force >>>> a TYPE_REF_CAN_ALIAS_ALL pointer to be generated. */ >>>> - if (lookup_attribute ("may_alias", TYPE_ATTRIBUTES (to_type))) >>>> + if (TYPE_TYPELESS_STORAGE (to_type) >>>> + || lookup_attribute ("may_alias", TYPE_ATTRIBUTES >(to_type))) >>>> can_alias_all = true; >>>> >>>> /* In some cases, languages will have things that aren't a >>>> >>>> not needed. >>>> >>> >>> You mean, because the get_alias_set (to_type) will be 0 anyways, >>> and can_alias_all wont change the semantic? >> >> Well, typeless_storage and may_alias are something different. If >> you require the above then your implementation of typeless_storage >> is broken. >> > >You are right, the hunk above is actually unnecessary. > >> Richard. >> >>> >>> Bernd. >>> >>>> +/* Nonzero if the type should behave like a character type >>>> + with respect to aliasing sementics. */ >>>> +#define TYPE_TYPELESS_STORAGE(NODE) \ >>>> + (TYPE_CHECK (NODE)->type_common.typeless_storage_flag) >>>> >>>> ARRAY_TYPE_CHECK (NODE)-> >>>> >>>> Richard. >>>> >>> >>> >>