Also, fix the order of if statements so that an explicit return_typestate annotation takes precedence over the default behavior for rvalue refs.
Note that for by-value arguments, the object being consumed is always a temporary. If you write:
void a(X); a((X &&)x);
...this first constructs a temporary X by moving from x, then calls a with a pointer to the temporary. Before and after this change, the move copies x's typestate to the temporary and marks x itself as consumed. But before this change, if the temporary started out unconsumed (because x was unconsumed before the move), it would still be unconsumed when its destructor was run after the call. Now it will be considered consumed at that point.
Also note that currently, only parameters explicitly marked return_typestate have their state-on-return checked on the callee side. Parameters which are implicitly consuming due to being rvalue references – or, after this patch, by-value – are checked only on the caller side. This discrepancy was very surprising to me as a user. I wrote a fix, but in my codebase it broke some code that was using std::forward. Therefore, I plan to hold off on submitting the fix until a followup patch, which will generalize the current std::move special case into an attribute that can be applied to any 'cast' function like std::move and std::forward.
unless these are testing something noteworthy about them being static functions I'd probably suggest making them non-members like the other test functions below, for consistency (otherwise the inconsistency tends to raise the question of "what is significant about this difference?")