diff --git a/girepository/giarginfo.c b/girepository/giarginfo.c
index c96976a..99a4e3f 100644
--- a/girepository/giarginfo.c
+++ b/girepository/giarginfo.c
@@ -125,13 +125,29 @@ g_arg_info_is_caller_allocates (GIArgInfo *info)
  * g_arg_info_is_optional:
  * @info: a #GIArgInfo
  *
- * Obtain if the argument is optional.
+ * Obtain if the argument accepts %NULL to ignore the results.
+ * The result is only valid for (out) arguments.
  *
  * Returns: %TRUE if it is an optional argument
  */
 gboolean
 g_arg_info_is_optional (GIArgInfo *info)
 {
+  return g_arg_info_may_be_null(info);
+}
+
+/**
+ * g_arg_info_may_be_null:
+ * @info: a #GIArgInfo
+ *
+ * Obtain if the C function accepts %NULL as passed value without
+ * generating an error.
+ *
+ * Returns: %TRUE if it accepts %NULL
+ */
+gboolean
+g_arg_info_may_be_null (GIArgInfo *info)
+{
   GIRealInfo *rinfo = (GIRealInfo *)info;
   ArgBlob *blob;
 
@@ -140,19 +156,22 @@ g_arg_info_is_optional (GIArgInfo *info)
 
   blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
 
-  return blob->optional;
+  return blob->allow_none;
 }
 
 /**
- * g_arg_info_may_be_null:
+ * g_arg_info_is_nullable:
  * @info: a #GIArgInfo
  *
- * Obtain if the argument accepts %NULL.
+ * Obtain if the passed in or passed out value can be %NULL.
+ * This applies to the values that get passed in for (in) arguments
+ * and values written out by (out) arguments.
  *
- * Returns: %TRUE if it accepts %NULL
+ * Returns: %TRUE if the value can be %NULL
+ * Since: 1.41.0
  */
 gboolean
-g_arg_info_may_be_null (GIArgInfo *info)
+g_arg_info_is_nullable (GIArgInfo *info)
 {
   GIRealInfo *rinfo = (GIRealInfo *)info;
   ArgBlob *blob;
diff --git a/girepository/giarginfo.h b/girepository/giarginfo.h
index 4045ab9..89566bf 100644
--- a/girepository/giarginfo.h
+++ b/girepository/giarginfo.h
@@ -45,6 +45,7 @@ gboolean               g_arg_info_is_return_value        (GIArgInfo *info);
 gboolean               g_arg_info_is_optional            (GIArgInfo *info);
 gboolean               g_arg_info_is_caller_allocates    (GIArgInfo *info);
 gboolean               g_arg_info_may_be_null            (GIArgInfo *info);
+gboolean               g_arg_info_is_nullable            (GIArgInfo *info);
 gboolean               g_arg_info_is_skip                (GIArgInfo *info);
 GITransfer             g_arg_info_get_ownership_transfer (GIArgInfo *info);
 GIScopeType            g_arg_info_get_scope              (GIArgInfo *info);
diff --git a/girepository/girepository.symbols b/girepository/girepository.symbols
index 5f01adf..93850c7 100644
--- a/girepository/girepository.symbols
+++ b/girepository/girepository.symbols
@@ -5,6 +5,7 @@ g_arg_info_get_ownership_transfer
 g_arg_info_get_scope
 g_arg_info_get_type
 g_arg_info_is_caller_allocates
+g_arg_info_is_nullable
 g_arg_info_is_optional
 g_arg_info_is_return_value
 g_arg_info_is_skip
diff --git a/girepository/girnode.c b/girepository/girnode.c
index 53385c2..cc338d5 100644
--- a/girepository/girnode.c
+++ b/girepository/girnode.c
@@ -1850,7 +1850,7 @@ _g_ir_node_build_typelib (GIrNode         *node,
 	blob->caller_allocates = param->caller_allocates;
 	blob->nullable = param->nullable;
 	blob->skip = param->skip;
-	blob->optional = param->optional;
+	blob->allow_none = param->allow_none;
 	blob->transfer_ownership = param->transfer;
 	blob->transfer_container_ownership = param->shallow_transfer;
 	blob->return_value = param->retval;
diff --git a/girepository/girnode.h b/girepository/girnode.h
index 4beef7f..2c73c8e 100644
--- a/girepository/girnode.h
+++ b/girepository/girnode.h
@@ -144,7 +144,7 @@ struct _GIrNodeParam
   gboolean in;
   gboolean out;
   gboolean caller_allocates;
-  gboolean optional;
+  gboolean allow_none;
   gboolean retval;
   gboolean nullable;
   gboolean skip;
diff --git a/girepository/girparser.c b/girepository/girparser.c
index 6c76866..d4de0bd 100644
--- a/girepository/girparser.c
+++ b/girepository/girparser.c
@@ -1124,20 +1124,23 @@ start_parameter (GMarkupParseContext *context,
     param->retval = FALSE;
 
   if (optional && strcmp (optional, "1") == 0)
-    param->optional = TRUE;
+    param->allow_none = TRUE;
   else
-    param->optional = FALSE;
+    param->allow_none = FALSE;
 
   if (nullable && strcmp (nullable, "1") == 0)
-    param->nullable = TRUE;
+    {
+      param->nullable = TRUE;
+      if (param->in)
+        param->allow_none = TRUE;
+    }
   else
     param->nullable = FALSE;
 
   if (allow_none && strcmp (allow_none, "1") == 0)
     {
-      if (param->out)
-        param->optional = TRUE;
-      else
+      param->allow_none = TRUE;
+      if (param->in)
         param->nullable = TRUE;
     }
 
diff --git a/girepository/gitypelib-internal.h b/girepository/gitypelib-internal.h
index 93d621b..51fe97e 100644
--- a/girepository/gitypelib-internal.h
+++ b/girepository/gitypelib-internal.h
@@ -396,13 +396,14 @@ typedef union _SimpleTypeBlob SimpleTypeBlob;
  *   parameter, the function actually takes an uint32*.
  * @caller_allocates: The parameter is a pointer to a struct or object that
  *   will receive an output of the function.
+ * @allow_none: Indicates that NULL may be passed in without
+ * generating an error.
  * @nullable: Only meaningful for types which are passed as pointers. For an
  *   in parameter, indicates if it is ok to pass NULL in. Gor an out
  *   parameter, indicates whether it may return NULL. Note that NULL is a
  *   valid GList and GSList value, thus allow_none will normally be set
  *   for parameters of these types.
- * @optional: For an out parameter, indicates that NULL may be passed in
- *   if the value is not needed.
+ *   (Note: this was named "optional" before but was never used)
  * @transfer_ownership: For an in parameter, indicates that the function takes
  *   over ownership of the parameter value. For an out parameter, it indicates
  *   that the caller is responsible for freeing the return value.
@@ -437,8 +438,8 @@ typedef struct {
   guint          in                           : 1;
   guint          out                          : 1;
   guint          caller_allocates             : 1;
+  guint          allow_none                   : 1;
   guint          nullable                     : 1;
-  guint          optional                     : 1;
   guint          transfer_ownership           : 1;
   guint          transfer_container_ownership : 1;
   guint          return_value                 : 1;
