static int test_SS_stack(void)
{
    STACK_OF(SS) *s = sk_SS_new_null();
    STACK_OF(SS) *r = NULL;
    SS *v[10], *p;
    const int n = OSSL_NELEM(v);
    int i;
    int testresult = 0;

    /* allocate and push */
    for (i = 0; i < n; i++) {
        v[i] = OPENSSL_malloc(sizeof(*v[i]));

        if (!TEST_ptr(v[i]))
            goto end;
        v[i]->n = i;
        v[i]->c = 'A' + i;
        if (!TEST_int_eq(sk_SS_num(s), i)) {
            TEST_info("SS stack size %d", i);
            goto end;
        }
        sk_SS_push(s, v[i]);
    }
    if (!TEST_int_eq(sk_SS_num(s), n))
        goto end;

    /* deepcopy */
    r = sk_SS_deep_copy(s, &SS_copy, &SS_free);
    if (!TEST_ptr(r))
        goto end;
    for (i = 0; i < n; i++) {
        p = sk_SS_value(r, i);
        if (!TEST_ptr_ne(p, v[i])) {
            TEST_info("SS deepcopy non-copy %d", i);
            goto end;
        }
        if (!TEST_int_eq(p->n, v[i]->n)) {
            TEST_info("test SS deepcopy int %d", i);
            goto end;
        }
        if (!TEST_char_eq(p->c, v[i]->c)) {
            TEST_info("SS deepcopy char %d", i);
            goto end;
        }
    }

    /* pop_free - we rely on the malloc debug to catch the leak */
    sk_SS_pop_free(r, &SS_free);
    r = NULL;

    /* delete_ptr */
    p = sk_SS_delete_ptr(s, v[3]);
    if (!TEST_ptr(p))
        goto end;
    SS_free(p);
    if (!TEST_int_eq(sk_SS_num(s), n - 1))
        goto end;
    for (i = 0; i < n-1; i++)
        if (!TEST_ptr_eq(sk_SS_value(s, i), v[i<3 ? i : 1+i])) {
            TEST_info("SS delete ptr item %d", i);
            goto end;
        }

    testresult = 1;
end:
    sk_SS_pop_free(r, &SS_free);
    sk_SS_pop_free(s, &SS_free);
    return testresult;
}