Index: dtypes.c
===================================================================
--- dtypes.c	(revision 154119)
+++ dtypes.c	(revision 154152)
@@ -6530,6 +6530,252 @@
     return 1;
 } /* end test_named_indirect_reopen() */
 
+
+/*-------------------------------------------------------------------------
+ * Function:	test_named_indirect_reopen_file
+ *
+ * Purpose:	Tests that a named compound datatype that refers to a named
+ *          string datatype can be reopened indirectly through H5Dget_type,
+ *          and shows the correct H5Tcommitted() state, including after the
+ *          file has been closed and reopened.
+ *
+ * Return:	Success:	0
+ *
+ *		Failure:	number of errors
+ *
+ * Programmer:	Mark Hodson
+ *              Tuesday, March 17, 2015
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_named_indirect_reopen_file(hid_t fapl)
+{
+    hid_t file=-1, space=-1, cmptype=-1, reopened_cmptype=-1, strtype=-1, reopened_strtype=-1, dset=-1;
+    static hsize_t dims[1] = {3};
+    size_t strtype_size, cmptype_size;
+    char filename[1024];
+
+    TESTING("indirectly reopening recursively committed datatypes including file reopening");
+
+    /* PREPARATION */
+
+    /* Create file, dataspace */
+    h5_fixname(FILENAME[1], fapl, filename, sizeof filename);
+    if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
+    if((space = H5Screate_simple(1, dims, dims)) < 0) TEST_ERROR
+
+    /* Create string type */
+    if((strtype = H5Tcopy(H5T_C_S1)) < 0) TEST_ERROR
+    if(H5Tset_size(strtype, H5T_VARIABLE) < 0) TEST_ERROR
+
+    /* Get size of string type */
+    if((strtype_size = H5Tget_size(strtype)) == 0) TEST_ERROR
+
+    /* Commit string type and verify the size doesn't change */
+    if(H5Tcommit2(file, "str_type", strtype, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+    if(strtype_size != H5Tget_size(strtype)) TEST_ERROR
+
+    /* Create compound type */
+    if((cmptype = H5Tcreate(H5T_COMPOUND, sizeof(char *))) < 0) TEST_ERROR
+    if(H5Tinsert(cmptype, "vlstr", (size_t)0, strtype) < 0) TEST_ERROR
+
+    /* Get size of compound type */
+    if((cmptype_size = H5Tget_size(cmptype)) == 0) TEST_ERROR
+
+    /* Commit compound type and verify the size doesn't change */
+    if(H5Tcommit2(file, "cmp_type", cmptype, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+    if(cmptype_size != H5Tget_size(cmptype)) TEST_ERROR
+
+    /* Create dataset with compound type */
+    if((dset = H5Dcreate2(file, "cmp_dset", cmptype, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+    /* Close original types */
+    if(H5Tclose(strtype) < 0) TEST_ERROR
+    strtype = -1;
+    if(H5Tclose(cmptype) < 0) TEST_ERROR
+    cmptype = -1;
+
+    /* CHECK DATA TYPES WHILE STILL HOLDING THE FILE OPEN */
+
+    /* Indirectly reopen compound type, verify that they report as committed, and the size doesn't change */
+    if((reopened_cmptype = H5Dget_type(dset)) < 0) TEST_ERROR
+    if(cmptype_size != H5Tget_size(reopened_cmptype)) TEST_ERROR
+    if(H5Tcommitted(reopened_cmptype) != 1) TEST_ERROR
+
+    /* Indirectly reopen string type, verify that they report as committed, and the size doesn't change */
+    if((reopened_strtype = H5Tget_member_type(reopened_cmptype, 0)) < 0) TEST_ERROR
+    if(strtype_size != H5Tget_size(reopened_strtype)) TEST_ERROR
+    if(H5Tcommitted(reopened_strtype) != 0) TEST_ERROR // HDF-group says nested committed types are not supported!
+
+    /* Close types and dataset */
+    if(H5Tclose(reopened_strtype) < 0) TEST_ERROR
+    reopened_strtype = -1;
+    if(H5Tclose(reopened_cmptype) < 0) TEST_ERROR
+    reopened_cmptype = -1;
+    if(H5Dclose(dset) < 0) TEST_ERROR
+    dset = -1;
+
+    /* CHECK DATA TYPES AFTER REOPENING THE SAME FILE */
+
+    /* Close file */
+    if(H5Fclose(file) < 0) TEST_ERROR
+    file = -1;
+
+    /* Reopen file */
+    if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR
+
+    /* Reopen dataset */
+    if((dset = H5Dopen2(file, "cmp_dset", H5P_DEFAULT)) < 0) TEST_ERROR
+
+    /* Indirectly reopen compound type, verify that they report as committed, and the size doesn't change */
+    if((reopened_cmptype = H5Dget_type(dset)) < 0) TEST_ERROR
+    if(cmptype_size != H5Tget_size(reopened_cmptype)) TEST_ERROR
+    if(H5Tcommitted(reopened_cmptype) != 1) TEST_ERROR
+
+    /* Indirectly reopen string type, verify that they report as committed, and the size doesn't change */
+    if((reopened_strtype = H5Tget_member_type(reopened_cmptype, 0)) < 0) TEST_ERROR
+    if(strtype_size != H5Tget_size(reopened_strtype)) TEST_ERROR
+    if(H5Tcommitted(reopened_strtype) != 0) TEST_ERROR // HDF-group says nested committed types are not supported!
+
+    /* Close types and dataset */
+    if(H5Tclose(reopened_strtype) < 0) TEST_ERROR
+    reopened_strtype = -1;
+    if(H5Tclose(reopened_cmptype) < 0) TEST_ERROR
+    reopened_cmptype = -1;
+    if(H5Dclose(dset) < 0) TEST_ERROR
+    dset = -1;
+
+    /* DONE */
+
+    /* Close file and dataspace */
+    if(H5Fclose(file) < 0) TEST_ERROR
+    file = -1;
+    if(H5Sclose(space) < 0) TEST_ERROR
+    space = -1;
+
+    PASSED();
+    return 0;
+
+error:
+    H5E_BEGIN_TRY {
+	H5Tclose(cmptype);
+	H5Tclose(strtype);
+	H5Tclose(reopened_cmptype);
+    H5Tclose(reopened_strtype);
+	H5Dclose(dset);
+	H5Fclose(file);
+    H5Sclose(space);
+    } H5E_END_TRY;
+    return 1;
+} /* end test_named_indirect_reopen() */
+
+
+/*-------------------------------------------------------------------------
+ * Function:	test_named_datatype_conversions_work_with_soft_links
+ *
+ * Purpose:	Tests that datatype conversions registered internally where
+ *          named datatypes make up either source or destination work with
+ *          soft link deletion after the file containing the named type(s)
+ *          has been closed (and another one opened). This is (was) a bug
+ *          in HDF-5 1.8.14.
+ *          
+ *          NOTE: This is based on test_compound_16() which we noticed was
+ *          tripping the dangling file reference, but didn't crash. We made
+ *          it crash by bringing in a second file into the mix, but even
+ *          then it won't crash unless the HDF5 internal memory heap writes
+ *          some sort of garbage pattern into memory in the free list!
+ *
+ * Return:	Success:	0
+ *
+ *		Failure:	number of errors
+ *
+ * Programmer:	Mark Hodson
+ *              Monday, March 23, 2015
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_named_datatype_conversions_work_with_soft_links(hid_t fapl)
+{
+    typedef struct cmpd_struct {
+       int  i1;
+       int  i2;
+    } cmpd_struct;
+
+    cmpd_struct wdata1 = {1254, 5471};
+    hid_t       file;
+    hid_t       file1;
+    hid_t       file2;
+    hid_t       cmpd_m_tid, cmpd_f_tid, int_id;
+    hid_t       space_id;
+    hid_t       dset_id;
+    hid_t       open_dtypes[2] = {0, 0};
+    hsize_t     dim1[1] = {1};
+    char        filename1[1024];
+    char        filename2[1024];
+
+    TESTING("visibility of internally registered type ids");
+
+    /* Create File #2 (unused) */
+    h5_fixname(FILENAME[6], H5P_DEFAULT, filename2, sizeof filename2);
+    if((file2=H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+    /* Create File #1 (used) */
+    h5_fixname(FILENAME[3], H5P_DEFAULT, filename1, sizeof filename1);
+    if((file1=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+    /* Copy and commit integer datatype */
+    if((int_id = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR
+    if(H5Tcommit2(file1, "int", int_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+    /* Create file compound datatype */
+    if((cmpd_f_tid = H5Tcreate(H5T_COMPOUND, 2 * sizeof(int) + 2)) < 0) TEST_ERROR
+    if(H5Tinsert(cmpd_f_tid, "i1", (size_t)0, int_id) < 0) TEST_ERROR
+    if(H5Tinsert(cmpd_f_tid, "i2", sizeof(int) + 1, int_id) < 0) TEST_ERROR
+
+    /* Create memory compound datatype */
+    if((cmpd_m_tid = H5Tcreate(H5T_COMPOUND, sizeof(struct cmpd_struct))) < 0) TEST_ERROR
+    if(H5Tinsert(cmpd_m_tid, "i1", HOFFSET(struct cmpd_struct, i1), int_id) < 0) TEST_ERROR
+    if(H5Tinsert(cmpd_m_tid, "i2", HOFFSET(struct cmpd_struct, i2), int_id) < 0) TEST_ERROR
+
+    /* Create space, dataset, write wdata1 */
+    if((space_id = H5Screate_simple(1, dim1, NULL)) < 0) TEST_ERROR
+    if((dset_id = H5Dcreate2(file1, "Dataset", cmpd_f_tid, space_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+    /* This write creates the converter and sets up the conversion path w/ the dangling file reference */
+    if(H5Dwrite(dset_id, cmpd_m_tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, &wdata1) < 0) TEST_ERROR
+
+    /* Create a soft link to nothing in particular; we'll delete it later */
+    if(H5Lcreate_soft("/Nothing/Matters", file1, "Link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+    /* Close */
+    if(H5Dclose(dset_id) < 0) TEST_ERROR
+    if(H5Sclose(space_id) < 0) TEST_ERROR
+    if(H5Tclose(cmpd_f_tid) < 0) TEST_ERROR
+    if(H5Tclose(cmpd_m_tid) < 0) TEST_ERROR
+    if(H5Tclose(int_id) < 0) TEST_ERROR
+    if(H5Fclose(file1) < 0) TEST_ERROR
+    if(H5Fclose(file2) < 0) TEST_ERROR
+
+    /* Reopen the file and try to delete the soft link; this will traverse all data types looking for matches */
+    /* and will try and dereference the dangling file reference. This re-uses file2's memory in the free list */
+    /* so file1 correctly remains a junk structure */
+    if((file = H5Fopen(filename1, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) TEST_ERROR
+    if(H5Ldelete(file, "Link", H5P_DEFAULT) < 0) TEST_ERROR
+    if(H5Fclose(file) < 0) TEST_ERROR
+
+    PASSED();
+    return 0;
+
+error:
+    return 1;
+} /* end test_named_indirect_reopen() */
+
 static void create_del_obj_named_test_file(const char *filename, hid_t fapl,
     hbool_t new_format)
 {
@@ -7284,6 +7530,8 @@
     nerrors += test_latest();
     nerrors += test_int_float_except();
     nerrors += test_named_indirect_reopen(fapl);
+    nerrors += test_named_indirect_reopen_file(fapl);
+    nerrors += test_named_datatype_conversions_work_with_soft_links(fapl);
 #ifndef H5_CANNOT_OPEN_TWICE
     nerrors += test_delete_obj_named(fapl);
     nerrors += test_delete_obj_named_fileid(fapl);
