[comp.bugs.4bsd] Function-returned structures

guy@gorodish.UUCP (02/10/87)

>4.3BSD won't take
>
>	f().x,

Because there's a bug in the compiler.  The System V PCC has changes
that fix this, but break other things.

The trouble here is that there is a routine "notlval" that returns
TRUE for structure assignment and structure call nodes and for nodes
of type "array" or "function", FALSE for other NAME, OREG, and REG
nodes, and TRUE for everything else.  However, there are some nodes
that are not lvalues but *are* legitimate structure references,
namely the aforementioned structure assignment and structure call
nodes.

This routine is used by the code in "cgram.y" to test whether
the LHS of the "." operator is a legitimate structure reference.
This means that "f()" will not be considered a legitimate structure
reference.

The "fix" in the System V PCC was to change "notlval" to consider
structure assignments and structure calls to be lvalues.  This fixes
this problem, but allows you to write things like

	f() = x;

which is not too cool.

The correct fix is to add a new routine "notstref" that returns FALSE
for the structure assignment and structure call nodes, and have
"notlval" return TRUE for those nodes (both routines return the same
values for other types of nodes), and use that routine instead of
"notlval" in the test in "cgram.y".

>but amazingly it will take
>	
>	( &f() ) -> x

This one is harder to fix; I haven't looked at it in painful detail,
but I think the problem is that by the time it gets around to
checking these things it's already decided that "f()" is really a
"dereference" operator on top of a "pointer to structure" node, and
of *course* you can take the address of *that*.

>Perhaps if this is really too hard to check in a compiler
>(is this what you are saying?),

No, I think he's saying it's too messy to *define* what is valid and
what isn't.  If you allow

	f().a

when "a" is *not* an array, what happens if it is?  Sticking in an
"except if it's an array" clause is a bit messy.  This isn't an
implementation issue (although forbidding this would be hard in PCC -
as would forbidding

	&(f().a)

if "a" is not an array), it's a language definition issue.