Remove a pointer indirection in STACK_OF(T) comparisons

At the public API, the comparison functions are a double pointer to
match qsort. qsort comparators are passed pointers to the list elements,
and our list elements are T*. qsort needs this indirection because it
can sort values of arbitrary size. However, our type-erased versions
have no such constraints. Since we know our all elements are pointers,
we can skip the indirection.

Change-Id: Ibb102b51a5aaf0a68a7318bf14ec8f4f9c7a3daf
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/60506
Reviewed-by: Bob Beck <bbe@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
diff --git a/crypto/stack/stack.c b/crypto/stack/stack.c
index 4f4f1df..a11533e 100644
--- a/crypto/stack/stack.c
+++ b/crypto/stack/stack.c
@@ -297,8 +297,7 @@
 
   if (!OPENSSL_sk_is_sorted(sk)) {
     for (size_t i = 0; i < sk->num; i++) {
-      const void *elem = sk->data[i];
-      if (call_cmp_func(sk->comp, &p, &elem) == 0) {
+      if (call_cmp_func(sk->comp, p, sk->data[i]) == 0) {
         if (out_index) {
           *out_index = i;
         }
@@ -317,8 +316,7 @@
     // Bias |mid| towards |lo|. See the |r == 0| case below.
     size_t mid = lo + (hi - lo - 1) / 2;
     assert(lo <= mid && mid < hi);
-    const void *elem = sk->data[mid];
-    int r = call_cmp_func(sk->comp, &p, &elem);
+    int r = call_cmp_func(sk->comp, p, sk->data[mid]);
     if (r > 0) {
       lo = mid + 1;  // |mid| is too low.
     } else if (r < 0) {
@@ -403,7 +401,10 @@
 
 static int sort_compare(void *ctx_v, const void *a, const void *b) {
   struct sort_compare_ctx *ctx = ctx_v;
-  return ctx->call_cmp_func(ctx->cmp_func, a, b);
+  // |a| and |b| point to |void*| pointers which contain the actual values.
+  const void *const *a_ptr = a;
+  const void *const *b_ptr = b;
+  return ctx->call_cmp_func(ctx->cmp_func, *a_ptr, *b_ptr);
 }
 #endif
 
diff --git a/include/openssl/stack.h b/include/openssl/stack.h
index ce92be6..7d5d4d7 100644
--- a/include/openssl/stack.h
+++ b/include/openssl/stack.h
@@ -279,9 +279,8 @@
 // true types.
 typedef void (*OPENSSL_sk_call_free_func)(OPENSSL_sk_free_func, void *);
 typedef void *(*OPENSSL_sk_call_copy_func)(OPENSSL_sk_copy_func, const void *);
-typedef int (*OPENSSL_sk_call_cmp_func)(OPENSSL_sk_cmp_func,
-                                        const void *const *,
-                                        const void *const *);
+typedef int (*OPENSSL_sk_call_cmp_func)(OPENSSL_sk_cmp_func, const void *,
+                                        const void *);
 typedef int (*OPENSSL_sk_call_delete_if_func)(OPENSSL_sk_delete_if_func, void *,
                                               void *);
 
@@ -421,13 +420,10 @@
   }                                                                            \
                                                                                \
   OPENSSL_INLINE int sk_##name##_call_cmp_func(OPENSSL_sk_cmp_func cmp_func,   \
-                                               const void *const *a,           \
-                                               const void *const *b) {         \
-    /* The data is actually stored as |void*| pointers, so read the pointer    \
-     * as |void*| and then pass the corrected type into the caller-supplied    \
-     * function, which expects |constptrtype*|. */                             \
-    constptrtype a_ptr = (constptrtype)*a;                                     \
-    constptrtype b_ptr = (constptrtype)*b;                                     \
+                                               const void *a, const void *b) { \
+    constptrtype a_ptr = (constptrtype)a;                                      \
+    constptrtype b_ptr = (constptrtype)b;                                      \
+    /* |cmp_func| expects an extra layer of pointers to match qsort. */        \
     return ((sk_##name##_cmp_func)cmp_func)(&a_ptr, &b_ptr);                   \
   }                                                                            \
                                                                                \