[futures.async] (3.1) says:
Any exception propagated from the execution of invoke(decay-copy(std::forward<F>(f)), decay-copy(std::forward<Args>(args))...) is stored as the exceptional result in the shared state.
It's not clear whether this includes the evaluation of the decay-copy calls in the calling thread, or only the invocation of invoke with the results of those decay-copy calls.
A literal reading suggests that any exceptions from any part of that expression should be stored in the shared state. All of libstdc++, libc++ and MSVC only store exceptions from the call to invoke, not the calls to decay-copy. Exceptions from the decay-copy calls are propagated to the caller of std::async. We should clarify that that's what the standard means.