------- Additional Comments From mark at codesourcery dot com 2005-03-07 22:39 ------- Subject: Re: [PR c++/20103] failure to gimplify constructors for addressable types
Alexandre Oliva wrote: > On Mar 7, 2005, Mark Mitchell <[EMAIL PROTECTED]> wrote: > > >>>>The games that you want to play with type-equality are just too fragile. >>> >>>I still don't see why. > > >>First, you're using "==". As I've told you, that's incredibly >>fragile. > > > Not for the purpose I've been trying to describe. We're at risk of descending into "Yes. No. Yes. No." I think it's fragile. Now, reasonable people can disagree about software engineering -- it's an art form, not a science -- but my opinion is that this is fragile. I've explained why: (a) we should never use "==" to compare types, because there's no guarantee that the compiler will continue to use "==" types in places where it does at present; it might instead switch one of them to be same_type_p. Think about it this way: == has no semantic meaning in C++; the only relationship the language knows about is same_type_p. So, using == means that you're doing something with types that doesn't have semantics grounded in the language, which doesn't make sense, except in places that are trying to get debugging information correct, etc. (b) you're applying a non-uniform transformation depending on non-local knowledge. What I mean by "non-uniform" is that the assignment to the type of the TARGET_EXPR is conditional. If it were an unconditional assignment, I'd be less nervous; then, you'd be asserting that the type of the TARGET_EXPR should always be the type of its initializer, which might make sense. What I mean by "non-local" is that your transformation only works because of some far-off logic that determins how TARGET_EXPRs are created. It doesn't depend on any documented property of TARGET_EXPRs that is enforced throughout the compiler. Consider the comments you should write for your code: /* Code in <some function> creates TARGET_EXPRs with "==" types, and that must be preserved here. If you change that code, don't forget to update this code! */ And, then, you should add something to the TARGET_EXPR documentation along the lines of: /* Some TARGET_EXPRs have the same TREE_TYPE as their initializers; some don't. The kinds that do are ...; the kinds that don't are ... When instantiating templates, we preserve equality for types that "==", but not necessarily those that are same_type_p. */ Finally, I've explained that the entire approach is contrary to the way we want to do things in templates, which is that you keep a syntactic form for dependent expressions until instantiation time, and then run through the same exact routines you would have in the parser. That's really the only way we can be sure that the semantics match up. I'm sorry you're frustruated, but I don't think that your approach is the right way to go. >>But, minor changes elsewhere might make them same_type_p, but not >>==, in some cases. > > If that's fine for those cases, it will remain so after template > substitution. Sounds *exactly* like what I want. Why would you want that? If before substitution, the operand had a typedef type for the incomplete array, and the TARGET_EXPR had a different typedef type for the same incomplete array, wouldn't you want to update the type of the TARGET_EXPR? In the context of a 4.0 patch, I'd be willing to consider a patch like yours, using same_type_p instead of "==", and with suitable comments explaining what's going on. For 4.1, we should do better. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103