Sorry, Ben. I've approached this in my head in four ways:
1. (Non-preferred; must be wrong because of lvalue conversion)
'res', before lvalue conversion, has a compatible type with the return
type of the function, so "the value is converted as if by assignment
to an object having the return type of the function" does not apply,
and "the value of" 'res' "is returned to the caller as the value of
the function call expression"
2. (More preferred than #1)
'res' undergoes lvalue conversion and yields an unqualified type with
the value. This type is incompatible with the return type of the
function, so "the value is converted as if by assignment to an object
having the return type of the function", but the footnote reminds us
that "The return statement is not an assignment." So there might be
one or more differences.
Looking at 6.5.16p1, it cannot apply as it is, since "an object having
the return type of the function" isn't the same as "a modifiable
lvalue designating an object having the return type of the function."
We need to twist it a bit. There's also no direct discussion of
conversion for the RHS operand... That's "2 strikes". So what if we
drop that bit and move on to 6.5.16.1?
Alternatively to moving on, there's a constraint violation (as you've
mentioned) based on "modifiable". But why pick "modifiable" and not
"lvalue"?
Looking at 6.5.16.1p1, the return type of 'foo' and the unqualified
type of rvalue from 'res' satisfy the second bullet. Then p2 does
indeed refer back to 6.5.16p2, but only insofar as the type of the
assignment-expression. The type of the assignment-expression so
happens to be the unqualified type of 'struct toto', which is the same
type as the rvalue from 'res', so there's actually no conversion for
the rvalue from 'res'.
3. (Preferred)
6.7.3p4: "The properties associated with qualified types are
meaningful only for expressions that are lvalues.132)" But "the value
of the function call expression" is never an lvalue, so perhaps the
return type of a function is never qualified.
In that case, the lvalue conversion of 'res' yields an rvalue whose
type is already compatible with the return type, so "the value is
converted as if by assignment to an object having the return type of
the function" does not apply, and "the value of" 'res' "is returned to
the caller as the value of the function call expression".
If #3 is true, the wording could be a bit clearer.
4. (D'oh!)
Unfortunately, I don't think any of #1, #2, #3 is true, due to
6.7.3p9: "...If the specification of a function type includes any type
qualifiers, the behavior is undefined.136)" (Since at least C90.) I
think that means that 'foo' can't be declared that way.