Current standard draft, in [dcl.type.auto.deduct], Part 3, reads:
If the placeholder-type-specifier is of the form type-constraint(opt) auto, the deduced type
T′replacingTis determined using the rules for template argument deduction. If the initialization is copy-list-initialization, a declaration ofstd::initializer_listshall precede ([basic.lookup.general]) the placeholder-type-specifier. ObtainPfromTby replacing the occurrences of type-constraint(opt) auto either with a new invented type template parameterUor, if the initialization is copy-list-initialization, withstd::initializer_list<U>. Deduce a value forUusing the rules of template argument deduction from a function call ([temp.deduct.call]), wherePis a function template parameter type and the corresponding argument isE. If the deduction fails, the declaration is ill-formed. Otherwise,T′is obtained by substituting the deducedUintoP.
The only example I can see with "multiple occurrences" of (optionally type-constrained) auto within type T, is with a function where auto is in both decl-specifier and trailing-return-type:
auto foo() -> auto;
or similarly, for a variable or function parameter that have function pointer/reference type, e.g.;
auto (*fp)() -> auto = ...initializer...;
I see two chances here:
1) preliminary Part 2 clarifies that the type T to be considered is, for example, the declared return type of a function, or the declared type of a variable. In former case, it means that a single auto is considered, because [dcl.spec.auto.general] indicates the trailing-return-type replaces the type of the decl-specifier, and this is true even for latter case despite [dcl.spec.auto.general]-p5 does not define an explicit (overall) declared type for the variable.
In this perspective 1), T would anyway contain a single 'auto' and the wording "occurrences" should be fixed, for example from "the occurrences of type-constraint(opt) auto" to "the placeholder-type-specifier" (provided that the begin of p3 states the placeholder is just a single type-constraint(opt) auto").
2) if, for any other reason, T really contains both 'auto', then the wording of replacing U in P with the deduced type is formally wrong, as for example for the function above foo(), if the type parameter U is deduced as int, then the replacement leads to:
int foo() -> int;
which is syntactically not allowed.
Additionally, even with a single auto, in decl-specifier only:
auto (*fp)() -> int = ...initializer...;
Therefore, even with perspective 2), the wording about replacing should change.
Are there other intended examples with 'multiple occurrences' ? I tried to ask on stackoverflow but no one provided any.
As an additional note, [dcl.spec.auto.general]-p4 states that a deduction is done in ase any non-discarded return statement is present, and even [dcl.type.auto.deduct]-p2 focuses on the non-discarded return statements.
Shouldn't we extend [dcl.spec.auto.general]-p4 for deducing void type when no non-discarded return statement is present ?