> On Jun 28, 2023, at 3:26 AM, Alexandre Oliva <ol...@adacore.com> wrote: > >>>>> I'd probably have arranged for the front-end to create the initializer >>>>> value, because expansion time is too late to figure it out: we may not >>>>> even have the front-end at hand any more, in case of lto compilation. >>> >>>> Is the hardbool attribute information available during the rtl expansion >>>> phase? >>> >>> It is in the sense that the attribute lives on, but c_hardbool_type_attr >>> is a frontend function, it cannot be called from e.g. lto1. >> does lookup_attribute work for this attribute during rtl expansion? >> (Still a little confusing here) > > Yes, the hardbool attribute would be there in C. > But not in Ada. > > And that should be fine, because Ada hardbool is handled entirely in the > frontend, as are non-hardened booleans with representation clauses, that > become enumeration types without any distinguishing feature. > >>> The hardbool attribute is also implemented in Ada, but there it only >>> affects validity checking in the front end: Boolean types in Ada are >>> Enumeration types, and there is standard syntax to specify the >>> representations for true and false. AFAICT, once we translate GNAT IR >>> to GNU IR, hardened booleans would not be recognizable as boolean types. >>> Even non-hardened booleans with representation clauses would. > >> So, right now, the GNU IR represents Ada’s boolean type as enumeration type? > > All Ada boolean types are defined by the language as enumeration types: > > There is a predefined enumeration type named Boolean, [declared in the > visible part of package Standard]. It has the two enumeration > literals False and True ordered with the relation False < True. Any > descendant of the predefined type Boolean is called a boolean type. > > However, boolean types without representation clauses are mapped to the > language-independent boolean_type_node. Those that do are mapped to > enumeration types.
>>> So >>> handling these differently from other enumeration types, to make them >>> closer to booleans, would be a bit of a challenge, > >> is there any special handling in GNU IR when representing Ada’s >> boolean type as enumeration type? >> Any issue right now? > > Not that I'm aware of. The front end takes care of converting between > non-boolean_type_node enumeration types and boolean_type_node as needed, > so that the GNU IR needs no extra information. In summary, Ada’s Boolean variables (whether it’s hardened or not) are represented as enumeration types in GNU IR. FE takes care of the converting between non-boolean_type_node enumeration types and boolean_type_node as needed, no special handling in Middle end. So, is this exactly the same situation as the new hardbool attribute for C being implemented in this patch? (Another question, for Ada’s Boolean variables, does the ada FE also insert BUILT_IN_TRAP when The value is neither true_value nor false_value?) >>> and a >>> backwards-compatibility issue (because such booleans have already been >>> handled in the present way since the introduction of -ftrivial-* back in >>> GCC12) > >> With the new hardbool attribute added for C, an original bool type >> becomes an enumeration type logically, > > There's no change to the original bool type. > > Only hardbool types are represented as enumeration types in C. > > In Ada, boolean types with representation clauses are still represented > as enumeration types, whether or not they're hardbool. > >> But such information is not passed to middle end through GNU IR, So, >> in GCC middle-end, We still treat such type as boolean, not an >> enumeration type. > > The middle-end doesn't know (and ATM cannot know) that those represented > as enumeration types are conceptually booleans, so they are treated as > enumeration types, not as booleans. They should know it’s a boolean if using the lookup_attribute to get the attribute info -:) > >>> static hbool zeroinit; /* False, stored as (char)0x5a. */ >>> auto hbool uninit; /* Undefined, may trap. */ > >> For the hardbool variable "uninit", -ftrivial-auto-var-init=zero will >> initialize it to zero, and it will trap during runtime. >> And at the same time, -ftrivial-auto-var-init=pattern will initialize >> it to 0xfe, and it will trap during runtime, too. > >> I think these are good behaviors, just need to be documented. > > You mean more than what's in the patch posted last week? No, the updated doc is good I think. > >>> >>>> And this is a very reasonable initial value for Boolean variables, >>> >>> Agreed. The all-zeros bit pattern is not so great for booleans that use >>> alternate representations, though, such as the following standard Ada: >>> >>> type MyBool is new Boolean; >>> for MyBool use (16#5a#, 16#a5#); >>> for MyBool'Size use 8; >>> >>> or for biased variables such as: >>> >>> X : Integer range 254 .. 507; >>> for X'Size use 8; -- bits, so a biased representation is required. >>> >>> Just to make things more interesting, I chose a range for X that causes >>> the compiler to represent 0xfe as 0x00 in in the byte that holds X, but >>> that places the 0xfe pattern just out of the range :-) So with >>> -ftrivial-auto-var-init=zero, X = 254, whereas with >>> -ftrivial-auto-var-init=pattern, it fails validity checking, and might >>> come out as 508 if that's disabled. > >> for the biased variable X, it was initialized to 254 (the smallest >> valid value in the range) when -ftrivial-auto-var-init=zero, and >> fails validity checking when -ftrivial-auto-var-init=pattern, both are >> GOOD and reasonable behaviors with -ftrivial-auto-var-init. > > *nod*. However, I don't think this specific biased representation is > mandated by the language (AFAICT it doesn't even mandate support for > biased representations, but it explicitly allows them). This means it > could conceivably map the all-zeros pattern to a trapping value, and > 0xfe could stand for 507, or 506, or even other values, depending on the > bias. Yes. > >> How about the following: > >>> +Users of the @option{-ftrivial-auto-var-init} should be aware that the bit >>> +patterns used as initializers are @emph{not} converted to >>> +@code{hardbool} types, so using a @code{hardbool} variable that is >>> implicitly initialized >>> +by the @option{-ftrivial-auto-var-init} may trap if the representations >>> values >>> +chosen for @code{false} and @code{true} do not match the initializer. > > That works for me. > >>> even if it would for a @code{static} >>> +variable of the same type. > >> A little confused about the above sentence: do you mean, if a hardbool >> variable is static (not auto), then the implicit initizlation to it by >> the compiler will be false? (Because static variable initialization is >> done by the FE) > > Yes, exactly, that's what's implemented and documented with the example > "static hbool zeroinit" above. > >> But when a hardbool variable is auto, then the implicit initialization >> to it by the compiler (with -ftrivial-auto-var-init) will not be >> false? > > Yeah, it can't be counted on being false. It can be a malformed value. > > This is also the case of e.g. Integer ranges: > > X : Integer range 17..42; > > type E is (Red, Green, Blue); > for E use (16#00f#, 16#0f0#, 16#f00#); > Y : E; > > -ftrivial-auto-var-init will initialize X and Y with values that are not > acceptable for those variables. And, as you say, that's a good thing. So, from my current understanding, a summary on my major concern and the possible solution to this concern: 1. There is one inconsistent issue for the new hardbool attribute for C: If the hardbool variable is implicitly initialized by FE, i.e, when it is a static variable, the initialized value is the logical false value; At the same time, If the hardbool variable is implicitly initialized by middle end, i.e, when it is an auto variable without initialization + -ftrivial-auto-var-init, the initialized value is a bitwise zero or 0xFE; 2. Such inconsistency has been there for Ada’s Boolean variables and also types with biases already, not a new issue. 3. Possible solution to this existing inconsistency issue: A. Document such inconsistency as we discussed; B. Fixing such inconsistency. Currently, we are taking the solution A. I am okay with it. Is it necessary to fix such inconsistency? I am not the right person to make the suggestion at this moment. Is the above understanding correct? Thanks. Qing > > -- > Alexandre Oliva, happy hacker https://FSFLA.org/blogs/lxo/ > Free Software Activist GNU Toolchain Engineer > Disinformation flourishes because many people care deeply about injustice > but very few check the facts. Ask me about <https://stallmansupport.org>