Validate an initializer.
(valid-initer initer target-type lifetime table ienv) → (mv erp new-initer return-types new-table)
The target type passed as input is the type of the object being initialized, which must not be a function or void type [C:6.7.9/3]. The lifetime kind passed as input is the one of the object being initialized.
If the target type is a scalar, the initializer must be either a single expression, or a singleton initializer list without designators [C:6.7.9/11]. The latter is an expression enclosed in braces; experiments show that the final comma is allowed. The same constraints as in assignments apply here [C:6.7.9/11] [C:6.5.16.1/1]. We perform array-to-pointer and function-to-pointer conversions on the expression, as pointers may be required.
If the target type is the structure or union type, the initializer is a single expression, and the object has automatic storage duration, that expression must also have the structure or union type [C:6.7.9/13].
If the target type is an array of characters (of various types), the initializer may be a single string literal, subject to some constraints [C:6.7.9/14] [C:6.7.9/15]. In our currently approximated type system, we must allow any kind of string literal with any array target type.
If the target type is an aggregate or union type, and the initializer is a brace-enclosed list, then we process the elements of the list, via a separate validation function [C:6.7.9/16] [C:6.7.9/17] [C:6.7.9/18].
If none of the case above holds, validation fails.