Why is flowing off the end of a function without a return value not ill formed?
Because maybe you can guarantee that you won't let the program execute there.
The difference between undefined behavior and ill-formed C++ programs
Undefined behavior (commonly abbreviated UB) is a runtime concept. If a program does something which the language specified as “a program isn’t allowed to do that”, then the behavior at runtime is undefined: The program is permitted by the standard to do anything it wants.
However, if your program avoids the code paths which trigger undefined behavior, then you are safe.
Even if a program contains undefined behavior, the compiler is still obligated to produce a runnable program. And if the code path containing undefined behavior is not executed, then the program’s behavior is still constrained by the standard.
By comparison, an ill-formed program is a program that breaks one of the rules for how programs are written. For example, maybe you try to modify a variable declared as const, or maybe you called a function that returns void and tried to store the result into a variable.