-
CSR
-
Resolution: Approved
-
P4
-
None
-
behavioral
-
low
-
-
Java API
Summary
Change the native linker implementation to reject variadic argument layouts that correspond to C type that is subject to default argument promotion.
Problem
The C specification mandates that some arguments passed as variadic arguments are subject to default argument promotion. In practice that means that certain types of values can not be passed as variadic arguments, and are instead promoted to another type.
However, the native linker currently allows linking functions with variadic argument layouts representing an unpromoted type. This could lead to surprising behaviors in the long run, as the implementation tries to support something that is not specified by the C spec.
Also, the fallback implementation already rejects these types.
Solution
Align the spec and the implementation: explicitly reject linking variadic argument layouts corresponding to types that are subject to change as a result of default argument promotion.
Specification
The section in the class javadoc of the java.lang.foreign.Linker class pertaining to variadic functions is updated. A paragraph that explains the promotions is added:
diff --git a/src/java.base/share/classes/java/lang/foreign/Linker.java b/src/java.base/share/classes/java/lang/foreign/Linker.java
index 8a57f51d1508..9862ded081de 100644
--- a/src/java.base/share/classes/java/lang/foreign/Linker.java
+++ b/src/java.base/share/classes/java/lang/foreign/Linker.java
@@ -365,11 +365,41 @@
*
* <h3 id="variadic-funcs">Variadic functions</h3>
*
- * Variadic functions (e.g. a C function declared with a trailing ellipses {@code ...} at the end of the formal parameter
- * list or with an empty formal parameter list) are not supported directly by the native linker. However, it is still possible
- * to link a variadic function by using a <em>specialized</em> function descriptor, together with a
- * {@linkplain Linker.Option#firstVariadicArg(int) a linker option} which indicates the position of the first variadic argument
- * in that specialized descriptor.
+ * Variadic functions are C functions which can accept a variable number and type of arguments. They are declared:
+ * <ol>
+ * <li>With a trailing ellipsis ({@code ...}) at the end of the formal parameter list, such as: {@code void foo(int x, ...);}</li>
+ * <li>With an empty formal parameter list, called a prototype-less function, such as: {@code void foo();}</li>
+ * </ol>
+ * The arguments passed in place of the ellipsis, or the arguments passed to a prototype-less function are called
+ * <em>variadic arguments</em>. Variadic functions are, essentially, templates that can be <em>specialized</em> into multiple
+ * non-variadic functions by replacing the {@code ...} or empty formal parameter list with a list of <em>variadic parameters</em>
+ * of a fixed number and type.
+ * <p>
+ * It should be noted that values passed as variadic arguments undergo default argument promotion in C. For instance, the
+ * following argument promotions are applied:
+ * <ul>
+ * <li>{@code _Bool} -> {@code unsigned int}</li>
+ * <li>{@code [signed] char} -> {@code [signed] int}</li>
+ * <li>{@code [signed] short} -> {@code [signed] int}</li>
+ * <li>{@code float} -> {@code double}</li>
+ * </ul>
+ * whereby the signed-ness of the source type corresponds to the signed-ness of the promoted type. The complete process
+ * of default argument promotion is described in the C specification. In effect these promotions place limits on the
+ * specialized form of a variadic function, as the variadic parameters of the specialized form will always have a promoted
+ * type.
+ * <p>
+ * The native linker only supports linking the specialized form of a variadic function. A variadic function in its specialized
+ * form can be linked using a function descriptor describing the specialized form. Additionally, the
+ * {@link Linker.Option#firstVariadicArg(int)} linker option must be provided to indicate the first variadic parameter in
+ * the parameter list. The corresponding argument layout, and all following argument layouts in the specialized function
+ * descriptor, are called <em>variadic argument layouts</em>. For a prototype-less function, the index passed to
+ * {@link Linker.Option#firstVariadicArg(int)} should always be {@code 0}.
+ * <p>
+ * The native linker will reject an attempt to link a specialized function descriptor with any variadic argument layouts
+ * corresponding to a C type that would be subject to default argument promotion (as described above). Exactly which layouts
+ * will be rejected is platform specific, but as an example: on Linux/x64 the layouts {@link ValueLayout#JAVA_BOOLEAN},
+ * {@link ValueLayout#JAVA_BYTE}, {@link ValueLayout#JAVA_CHAR}, {@link ValueLayout#JAVA_SHORT}, and
+ * {@link ValueLayout#JAVA_FLOAT} will be rejected.
* <p>
* A well-known variadic function is the {@code printf} function, defined in the C standard library:
*
- csr of
-
JDK-8308031 Linkers should reject unpromoted variadic parameters
-
- Resolved
-