SDL: Functions which return function pointers now return SDL_FunctionPointer instead of void*

From e9b86eebf3018dd3653af53fc47cb772ab85059f Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Mon, 9 Jan 2023 14:55:12 -0800
Subject: [PATCH] Functions which return function pointers now return
 SDL_FunctionPointer instead of void*

This fixes the clang warning "Cast between pointer-to-function and pointer-to-object is an extension"

You can define SDL_FUNCTION_POINTER_IS_VOID_POINTER in your project to restore the previous behavior.

Fixes https://github.com/libsdl-org/SDL/issues/2866
---
 docs/README-migration.md                      |   8 +
 include/SDL3/SDL_loadso.h                     |   4 +-
 include/SDL3/SDL_stdinc.h                     |   7 +
 include/SDL3/SDL_video.h                      |   4 +-
 include/SDL3/SDL_vulkan.h                     |   8 +-
 src/audio/aaudio/SDL_aaudio.c                 |   2 +-
 src/core/linux/SDL_dbus.c                     |  90 ++++-----
 src/dynapi/SDL_dynapi_procs.h                 |   8 +-
 src/loadso/dlopen/SDL_sysloadso.c             |   6 +-
 src/loadso/dummy/SDL_sysloadso.c              |   6 +-
 src/loadso/windows/SDL_sysloadso.c            |   6 +-
 src/render/opengl/SDL_render_gl.c             |   2 +-
 src/render/opengles2/SDL_render_gles2.c       |   2 +-
 src/video/SDL_egl.c                           |  81 ++++----
 src/video/SDL_egl_c.h                         |  98 +++------
 src/video/SDL_sysvideo.h                      |   2 +-
 src/video/SDL_video.c                         | 190 +++++++-----------
 src/video/cocoa/SDL_cocoaopengl.h             |   2 +-
 src/video/cocoa/SDL_cocoaopengl.m             |   6 +-
 src/video/emscripten/SDL_emscriptenopengles.c |   6 +-
 src/video/emscripten/SDL_emscriptenopengles.h |   2 +-
 src/video/haiku/SDL_bopengl.cc                |   2 +-
 src/video/haiku/SDL_bopengl.h                 |   2 +-
 src/video/kmsdrm/SDL_kmsdrmvideo.h            |   2 +-
 src/video/psp/SDL_pspgl.c                     |   6 +-
 src/video/psp/SDL_pspgl_c.h                   |   2 +-
 src/video/psp/SDL_pspvideo.h                  |   2 +-
 src/video/raspberry/SDL_rpivideo.h            |   2 +-
 src/video/uikit/SDL_uikitopengles.h           |   2 +-
 src/video/uikit/SDL_uikitopengles.m           |   6 +-
 src/video/vita/SDL_vitagl_pvr_c.h             |   2 +-
 src/video/vita/SDL_vitagles.c                 |   6 +-
 src/video/vita/SDL_vitagles_c.h               |   2 +-
 src/video/vita/SDL_vitavideo.h                |   4 +-
 src/video/windows/SDL_windowsopengl.c         |  16 +-
 src/video/windows/SDL_windowsopengl.h         |   4 +-
 src/video/x11/SDL_x11opengl.c                 |  14 +-
 src/video/x11/SDL_x11opengl.h                 |   6 +-
 src/video/x11/SDL_x11vulkan.c                 |   2 +-
 test/testgl.c                                 |   2 +-
 test/testgles2.c                              |   2 +-
 test/testgles2_sdf.c                          |   2 +-
 test/testvulkan.c                             |   2 +-
 43 files changed, 273 insertions(+), 357 deletions(-)

diff --git a/docs/README-migration.md b/docs/README-migration.md
index 9205ebed80ad..fa3d8bbef422 100644
--- a/docs/README-migration.md
+++ b/docs/README-migration.md
@@ -406,6 +406,10 @@ The following symbols have been renamed:
 * KMOD_SCROLL => SDL_KMOD_SCROLL
 * KMOD_SHIFT => SDL_KMOD_SHIFT
 
+## SDL_loadso.h
+
+SDL_LoadFunction() now returns `SDL_FunctionPointer` instead of `void *`, and should be cast to the appropriate function type. You can define SDL_FUNCTION_POINTER_IS_VOID_POINTER in your project to restore the previous behavior.
+
 ## SDL_main.h
 
 SDL3 doesn't have a static libSDLmain to link against anymore.  
@@ -867,6 +871,8 @@ Programs which have access to shaders can implement more robust versions of thos
 
 Removed SDL_GL_CONTEXT_EGL from OpenGL configuration attributes. You can instead use `SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);`
 
+SDL_GL_GetProcAddress() and SDL_EGL_GetProcAddress() now return `SDL_FunctionPointer` instead of `void *`, and should be cast to the appropriate function type. You can define SDL_FUNCTION_POINTER_IS_VOID_POINTER in your project to restore the previous behavior.
+
 SDL_GL_SwapWindow() returns 0 if the function succeeds or a negative error code if there was an error.
 
 SDL_GL_GetSwapInterval() takes the interval as an output parameter and returns 0 if the function succeeds or a negative error code if there was an error.
@@ -882,3 +888,5 @@ SDL_Window id type is named SDL_WindowID
 
 SDL_Vulkan_GetInstanceExtensions() no longer takes a window parameter.
 
+SDL_Vulkan_GetVkGetInstanceProcAddr() now returns `SDL_FunctionPointer` instead of `void *`, and should be cast to PFN_vkGetInstanceProcAddr.
+
diff --git a/include/SDL3/SDL_loadso.h b/include/SDL3/SDL_loadso.h
index b56a719f5a25..c5c564997a37 100644
--- a/include/SDL3/SDL_loadso.h
+++ b/include/SDL3/SDL_loadso.h
@@ -89,8 +89,8 @@ extern DECLSPEC void *SDLCALL SDL_LoadObject(const char *sofile);
  * \sa SDL_LoadObject
  * \sa SDL_UnloadObject
  */
-extern DECLSPEC void *SDLCALL SDL_LoadFunction(void *handle,
-                                               const char *name);
+extern DECLSPEC SDL_FunctionPointer SDL_LoadFunction(void *handle,
+                                                     const char *name);
 
 /**
  * Unload a shared object from memory.
diff --git a/include/SDL3/SDL_stdinc.h b/include/SDL3/SDL_stdinc.h
index a5a37e392084..db6c8da47b86 100644
--- a/include/SDL3/SDL_stdinc.h
+++ b/include/SDL3/SDL_stdinc.h
@@ -738,6 +738,13 @@ SDL_FORCE_INLINE int SDL_size_add_overflow_builtin (size_t a,
 #define SDL_size_add_overflow(a, b, ret) (SDL_size_add_overflow_builtin(a, b, ret))
 #endif
 
+/* This is a generic function pointer which should be cast to the type you expect */
+#ifdef SDL_FUNCTION_POINTER_IS_VOID_POINTER
+typedef void *SDL_FunctionPointer;
+#else
+typedef void (*SDL_FunctionPointer)(void);
+#endif
+
 /* Ends C function definitions when using C++ */
 #ifdef __cplusplus
 }
diff --git a/include/SDL3/SDL_video.h b/include/SDL3/SDL_video.h
index 7649ed6ad472..07a978c6946f 100644
--- a/include/SDL3/SDL_video.h
+++ b/include/SDL3/SDL_video.h
@@ -1723,7 +1723,7 @@ extern DECLSPEC int SDLCALL SDL_GL_LoadLibrary(const char *path);
  * \sa SDL_GL_LoadLibrary
  * \sa SDL_GL_UnloadLibrary
  */
-extern DECLSPEC void *SDLCALL SDL_GL_GetProcAddress(const char *proc);
+extern DECLSPEC SDL_FunctionPointer SDLCALL SDL_GL_GetProcAddress(const char *proc);
 
 /**
  * Get an EGL library function by name.
@@ -1740,7 +1740,7 @@ extern DECLSPEC void *SDLCALL SDL_GL_GetProcAddress(const char *proc);
  *
  * \sa SDL_GL_GetCurrentEGLDisplay
  */
-extern DECLSPEC void *SDLCALL SDL_EGL_GetProcAddress(const char *proc);
+extern DECLSPEC SDL_FunctionPointer SDLCALL SDL_EGL_GetProcAddress(const char *proc);
 
 /**
  * Unload the OpenGL library previously loaded by SDL_GL_LoadLibrary().
diff --git a/include/SDL3/SDL_vulkan.h b/include/SDL3/SDL_vulkan.h
index 169ab8767ac0..06a6c3bbda67 100644
--- a/include/SDL3/SDL_vulkan.h
+++ b/include/SDL3/SDL_vulkan.h
@@ -111,11 +111,17 @@ extern DECLSPEC int SDLCALL SDL_Vulkan_LoadLibrary(const char *path);
  * This should be called after either calling SDL_Vulkan_LoadLibrary() or
  * creating an SDL_Window with the `SDL_WINDOW_VULKAN` flag.
  *
+ * The actual type of the returned function pointer is PFN_vkGetInstanceProcAddr,
+ * but that isn't available because the Vulkan headers are not included here. You
+ * should cast the return value of this function to that type, e.g.
+ *
+ *  `vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)SDL_Vulkan_GetVkGetInstanceProcAddr();`
+ *
  * \returns the function pointer for `vkGetInstanceProcAddr` or NULL on error.
  *
  * \since This function is available since SDL 3.0.0.
  */
-extern DECLSPEC void *SDLCALL SDL_Vulkan_GetVkGetInstanceProcAddr(void);
+extern DECLSPEC SDL_FunctionPointer SDLCALL SDL_Vulkan_GetVkGetInstanceProcAddr(void);
 
 /**
  * Unload the Vulkan library previously loaded by SDL_Vulkan_LoadLibrary()
diff --git a/src/audio/aaudio/SDL_aaudio.c b/src/audio/aaudio/SDL_aaudio.c
index 8db63a4f3fe6..312a3cf7eb5f 100644
--- a/src/audio/aaudio/SDL_aaudio.c
+++ b/src/audio/aaudio/SDL_aaudio.c
@@ -50,7 +50,7 @@ static int aaudio_LoadFunctions(AAUDIO_Data *data)
 {
 #define SDL_PROC(ret, func, params)                                                             \
     do {                                                                                        \
-        data->func = SDL_LoadFunction(data->handle, #func);                                     \
+        data->func = (ret (*) params)SDL_LoadFunction(data->handle, #func);                                     \
         if (!data->func) {                                                                      \
             return SDL_SetError("Couldn't load AAUDIO function %s: %s", #func, SDL_GetError()); \
         }                                                                                       \
diff --git a/src/core/linux/SDL_dbus.c b/src/core/linux/SDL_dbus.c
index 7a92fa1f5d02..16a7c13f94e8 100644
--- a/src/core/linux/SDL_dbus.c
+++ b/src/core/linux/SDL_dbus.c
@@ -33,53 +33,53 @@ static SDL_DBusContext dbus;
 
 static int LoadDBUSSyms(void)
 {
-#define SDL_DBUS_SYM2(x, y)                            \
-    if (!(dbus.x = SDL_LoadFunction(dbus_handle, #y))) \
+#define SDL_DBUS_SYM2(TYPE, x, y)                            \
+    if (!(dbus.x = (TYPE)SDL_LoadFunction(dbus_handle, #y))) \
     return -1
 
-#define SDL_DBUS_SYM(x) \
-    SDL_DBUS_SYM2(x, dbus_##x)
-
-    SDL_DBUS_SYM(bus_get_private);
-    SDL_DBUS_SYM(bus_register);
-    SDL_DBUS_SYM(bus_add_match);
-    SDL_DBUS_SYM(connection_open_private);
-    SDL_DBUS_SYM(connection_set_exit_on_disconnect);
-    SDL_DBUS_SYM(connection_get_is_connected);
-    SDL_DBUS_SYM(connection_add_filter);
-    SDL_DBUS_SYM(connection_try_register_object_path);
-    SDL_DBUS_SYM(connection_send);
-    SDL_DBUS_SYM(connection_send_with_reply_and_block);
-    SDL_DBUS_SYM(connection_close);
-    SDL_DBUS_SYM(connection_ref);
-    SDL_DBUS_SYM(connection_unref);
-    SDL_DBUS_SYM(connection_flush);
-    SDL_DBUS_SYM(connection_read_write);
-    SDL_DBUS_SYM(connection_dispatch);
-    SDL_DBUS_SYM(message_is_signal);
-    SDL_DBUS_SYM(message_new_method_call);
-    SDL_DBUS_SYM(message_append_args);
-    SDL_DBUS_SYM(message_append_args_valist);
-    SDL_DBUS_SYM(message_iter_init_append);
-    SDL_DBUS_SYM(message_iter_open_container);
-    SDL_DBUS_SYM(message_iter_append_basic);
-    SDL_DBUS_SYM(message_iter_close_container);
-    SDL_DBUS_SYM(message_get_args);
-    SDL_DBUS_SYM(message_get_args_valist);
-    SDL_DBUS_SYM(message_iter_init);
-    SDL_DBUS_SYM(message_iter_next);
-    SDL_DBUS_SYM(message_iter_get_basic);
-    SDL_DBUS_SYM(message_iter_get_arg_type);
-    SDL_DBUS_SYM(message_iter_recurse);
-    SDL_DBUS_SYM(message_unref);
-    SDL_DBUS_SYM(threads_init_default);
-    SDL_DBUS_SYM(error_init);
-    SDL_DBUS_SYM(error_is_set);
-    SDL_DBUS_SYM(error_free);
-    SDL_DBUS_SYM(get_local_machine_id);
-    SDL_DBUS_SYM(free);
-    SDL_DBUS_SYM(free_string_array);
-    SDL_DBUS_SYM(shutdown);
+#define SDL_DBUS_SYM(TYPE, x) \
+    SDL_DBUS_SYM2(TYPE, x, dbus_##x)
+
+    SDL_DBUS_SYM(DBusConnection *(*)(DBusBusType, DBusError *), bus_get_private);
+    SDL_DBUS_SYM(dbus_bool_t (*)(DBusConnection *, DBusError *), bus_register);
+    SDL_DBUS_SYM(void (*)(DBusConnection *, const char *, DBusError *), bus_add_match);
+    SDL_DBUS_SYM(DBusConnection *(*)(const char *, DBusError *), connection_open_private);
+    SDL_DBUS_SYM(void (*)(DBusConnection *, dbus_bool_t), connection_set_exit_on_disconnect);
+    SDL_DBUS_SYM(dbus_bool_t (*)(DBusConnection *), connection_get_is_connected);
+    SDL_DBUS_SYM(dbus_bool_t (*)(DBusConnection *, DBusHandleMessageFunction, void *, DBusFreeFunction), connection_add_filter);
+    SDL_DBUS_SYM(dbus_bool_t (*)(DBusConnection *, const char *, const DBusObjectPathVTable *, void *, DBusError *), connection_try_register_object_path);
+    SDL_DBUS_SYM(dbus_bool_t (*)(DBusConnection *, DBusMessage *, dbus_uint32_t *), connection_send);
+    SDL_DBUS_SYM(DBusMessage *(*)(DBusConnection *, DBusMessage *, int, DBusError *), connection_send_with_reply_and_block);
+    SDL_DBUS_SYM(void (*)(DBusConnection *), connection_close);
+    SDL_DBUS_SYM(void (*)(DBusConnection *), connection_ref);
+    SDL_DBUS_SYM(void (*)(DBusConnection *), connection_unref);
+    SDL_DBUS_SYM(void (*)(DBusConnection *), connection_flush);
+    SDL_DBUS_SYM(dbus_bool_t (*)(DBusConnection *, int), connection_read_write);
+    SDL_DBUS_SYM(DBusDispatchStatus (*)(DBusConnection *), connection_dispatch);
+    SDL_DBUS_SYM(dbus_bool_t (*)(DBusMessage *, const char *, const char *), message_is_signal);
+    SDL_DBUS_SYM(DBusMessage *(*)(const char *, const char *, const char *, const char *), message_new_method_call);
+    SDL_DBUS_SYM(dbus_bool_t (*)(DBusMessage *, int, ...), message_append_args);
+    SDL_DBUS_SYM(dbus_bool_t (*)(DBusMessage *, int, va_list), message_append_args_valist);
+    SDL_DBUS_SYM(void (*)(DBusMessage *, DBusMessageIter *), message_iter_init_append);
+    SDL_DBUS_SYM(dbus_bool_t (*)(DBusMessageIter *, int, const char *, DBusMessageIter *), message_iter_open_container);
+    SDL_DBUS_SYM(dbus_bool_t (*)(DBusMessageIter *, int, const void *), message_iter_append_basic);
+    SDL_DBUS_SYM(dbus_bool_t (*)(DBusMessageIter *, DBusMessageIter *), message_iter_close_container);
+    SDL_DBUS_SYM(dbus_bool_t (*)(DBusMessage *, DBusError *, int, ...), message_get_args);
+    SDL_DBUS_SYM(dbus_bool_t (*)(DBusMessage *, DBusError *, int, va_list), message_get_args_valist);
+    SDL_DBUS_SYM(dbus_bool_t (*)(DBusMessage *, DBusMessageIter *), message_iter_init);
+    SDL_DBUS_SYM(dbus_bool_t (*)(DBusMessageIter *), message_iter_next);
+    SDL_DBUS_SYM(void (*)(DBusMessageIter *, void *), message_iter_get_basic);
+    SDL_DBUS_SYM(int (*)(DBusMessageIter *), message_iter_get_arg_type);
+    SDL_DBUS_SYM(void (*)(DBusMessageIter *, DBusMessageIter *), message_iter_recurse);
+    SDL_DBUS_SYM(void (*)(DBusMessage *), message_unref);
+    SDL_DBUS_SYM(dbus_bool_t (*)(void), threads_init_default);
+    SDL_DBUS_SYM(void (*)(DBusError *), error_init);
+    SDL_DBUS_SYM(dbus_bool_t (*)(const DBusError *), error_is_set);
+    SDL_DBUS_SYM(void (*)(DBusError *), error_free);
+    SDL_DBUS_SYM(char *(*)(void), get_local_machine_id);
+    SDL_DBUS_SYM(void (*)(void *), free);
+    SDL_DBUS_SYM(void (*)(char **), free_string_array);
+    SDL_DBUS_SYM(void (*)(void), shutdown);
 
 #undef SDL_DBUS_SYM
 #undef SDL_DBUS_SYM2
diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h
index 781c8873927a..efbf90fed682 100644
--- a/src/dynapi/SDL_dynapi_procs.h
+++ b/src/dynapi/SDL_dynapi_procs.h
@@ -199,7 +199,7 @@ SDL_DYNAPI_PROC(void,SDL_DisableScreenSaver,(void),(),)
 SDL_DYNAPI_PROC(SDL_Surface*,SDL_DuplicateSurface,(SDL_Surface *a),(a),return)
 SDL_DYNAPI_PROC(SDL_EGLConfig,SDL_EGL_GetCurrentEGLConfig,(void),(),return)
 SDL_DYNAPI_PROC(SDL_EGLDisplay,SDL_EGL_GetCurrentEGLDisplay,(void),(),return)
-SDL_DYNAPI_PROC(void*,SDL_EGL_GetProcAddress,(const char *a),(a),return)
+SDL_DYNAPI_PROC(SDL_FunctionPointer,SDL_EGL_GetProcAddress,(const char *a),(a),return)
 SDL_DYNAPI_PROC(SDL_EGLSurface,SDL_EGL_GetWindowEGLSurface,(SDL_Window *a),(a),return)
 SDL_DYNAPI_PROC(void,SDL_EGL_SetEGLAttributeCallbacks,(SDL_EGLAttribArrayCallback a, SDL_EGLIntArrayCallback b, SDL_EGLIntArrayCallback c),(a,b,c),)
 SDL_DYNAPI_PROC(void,SDL_EnableScreenSaver,(void),(),)
@@ -222,7 +222,7 @@ SDL_DYNAPI_PROC(int,SDL_GL_GetAttribute,(SDL_GLattr a, int *b),(a,b),return)
 SDL_DYNAPI_PROC(SDL_GLContext,SDL_GL_GetCurrentContext,(void),(),return)
 SDL_DYNAPI_PROC(SDL_Window*,SDL_GL_GetCurrentWindow,(void),(),return)
 SDL_DYNAPI_PROC(void,SDL_GL_GetDrawableSize,(SDL_Window *a, int *b, int *c),(a,b,c),)
-SDL_DYNAPI_PROC(void*,SDL_GL_GetProcAddress,(const char *a),(a),return)
+SDL_DYNAPI_PROC(SDL_FunctionPointer,SDL_GL_GetProcAddress,(const char *a),(a),return)
 SDL_DYNAPI_PROC(int,SDL_GL_GetSwapInterval,(int *a),(a),return)
 SDL_DYNAPI_PROC(int,SDL_GL_LoadLibrary,(const char *a),(a),return)
 SDL_DYNAPI_PROC(int,SDL_GL_MakeCurrent,(SDL_Window *a, SDL_GLContext b),(a,b),return)
@@ -536,7 +536,7 @@ SDL_DYNAPI_PROC(int,SDL_JoystickIsHaptic,(SDL_Joystick *a),(a),return)
 SDL_DYNAPI_PROC(SDL_Surface*,SDL_LoadBMP_RW,(SDL_RWops *a, int b),(a,b),return)
 SDL_DYNAPI_PROC(void*,SDL_LoadFile,(const char *a, size_t *b),(a,b),return)
 SDL_DYNAPI_PROC(void*,SDL_LoadFile_RW,(SDL_RWops *a, size_t *b, int c),(a,b,c),return)
-SDL_DYNAPI_PROC(void*,SDL_LoadFunction,(void *a, const char *b),(a,b),return)
+SDL_DYNAPI_PROC(SDL_FunctionPointer,SDL_LoadFunction,(void *a, const char *b),(a,b),return)
 SDL_DYNAPI_PROC(void*,SDL_LoadObject,(const char *a),(a),return)
 SDL_DYNAPI_PROC(SDL_AudioSpec*,SDL_LoadWAV_RW,(SDL_RWops *a, int b, SDL_AudioSpec *c, Uint8 **d, Uint32 *e),(a,b,c,d,e),return)
 SDL_DYNAPI_PROC(void,SDL_LockAudioDevice,(SDL_AudioDeviceID a),(a),)
@@ -755,7 +755,7 @@ SDL_DYNAPI_PROC(int,SDL_UpdateYUVTexture,(SDL_Texture *a, const SDL_Rect *b, con
 SDL_DYNAPI_PROC(SDL_bool,SDL_Vulkan_CreateSurface,(SDL_Window *a, VkInstance b, VkSurfaceKHR *c),(a,b,c),return)
 SDL_DYNAPI_PROC(void,SDL_Vulkan_GetDrawableSize,(SDL_Window *a, int *b, int *c),(a,b,c),)
 SDL_DYNAPI_PROC(SDL_bool,SDL_Vulkan_GetInstanceExtensions,(unsigned int *a, const char **b),(a,b),return)
-SDL_DYNAPI_PROC(void*,SDL_Vulkan_GetVkGetInstanceProcAddr,(void),(),return)
+SDL_DYNAPI_PROC(SDL_FunctionPointer,SDL_Vulkan_GetVkGetInstanceProcAddr,(void),(),return)
 SDL_DYNAPI_PROC(int,SDL_Vulkan_LoadLibrary,(const char *a),(a),return)
 SDL_DYNAPI_PROC(void,SDL_Vulkan_UnloadLibrary,(void),(),)
 SDL_DYNAPI_PROC(int,SDL_WaitEvent,(SDL_Event *a),(a),return)
diff --git a/src/loadso/dlopen/SDL_sysloadso.c b/src/loadso/dlopen/SDL_sysloadso.c
index 231d90d6cc20..22c7a0667450 100644
--- a/src/loadso/dlopen/SDL_sysloadso.c
+++ b/src/loadso/dlopen/SDL_sysloadso.c
@@ -32,8 +32,7 @@
 #include "../../video/uikit/SDL_uikitvideo.h"
 #endif
 
-void *
-SDL_LoadObject(const char *sofile)
+void *SDL_LoadObject(const char *sofile)
 {
     void *handle;
     const char *loaderror;
@@ -53,8 +52,7 @@ SDL_LoadObject(const char *sofile)
     return handle;
 }
 
-void *
-SDL_LoadFunction(void *handle, const char *name)
+SDL_FunctionPointer SDL_LoadFunction(void *handle, const char *name)
 {
     void *symbol = dlsym(handle, name);
     if (symbol == NULL) {
diff --git a/src/loadso/dummy/SDL_sysloadso.c b/src/loadso/dummy/SDL_sysloadso.c
index d068f82cc45d..ba18a7a2b3eb 100644
--- a/src/loadso/dummy/SDL_sysloadso.c
+++ b/src/loadso/dummy/SDL_sysloadso.c
@@ -25,16 +25,14 @@
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 /* System dependent library loading routines                           */
 
-void *
-SDL_LoadObject(const char *sofile)
+void *SDL_LoadObject(const char *sofile)
 {
     const char *loaderror = "SDL_LoadObject() not implemented";
     SDL_SetError("Failed loading %s: %s", sofile, loaderror);
     return NULL;
 }
 
-void *
-SDL_LoadFunction(void *handle, const char *name)
+SDL_FunctionPointer SDL_LoadFunction(void *handle, const char *name)
 {
     const char *loaderror = "SDL_LoadFunction() not implemented";
     SDL_SetError("Failed loading %s: %s", name, loaderror);
diff --git a/src/loadso/windows/SDL_sysloadso.c b/src/loadso/windows/SDL_sysloadso.c
index 21d0674bcfd7..94198f16cd0a 100644
--- a/src/loadso/windows/SDL_sysloadso.c
+++ b/src/loadso/windows/SDL_sysloadso.c
@@ -27,8 +27,7 @@
 
 #include "../../core/windows/SDL_windows.h"
 
-void *
-SDL_LoadObject(const char *sofile)
+void *SDL_LoadObject(const char *sofile)
 {
     void *handle;
     LPTSTR tstr;
@@ -59,8 +58,7 @@ SDL_LoadObject(const char *sofile)
     return handle;
 }
 
-void *
-SDL_LoadFunction(void *handle, const char *name)
+SDL_FunctionPointer SDL_LoadFunction(void *handle, const char *name)
 {
     void *symbol = (void *)GetProcAddress((HMODULE)handle, name);
     if (symbol == NULL) {
diff --git a/src/render/opengl/SDL_render_gl.c b/src/render/opengl/SDL_render_gl.c
index ec06030e9b19..9dabc95db494 100644
--- a/src/render/opengl/SDL_render_gl.c
+++ b/src/render/opengl/SDL_render_gl.c
@@ -242,7 +242,7 @@ static int GL_LoadFunctions(GL_RenderData *data)
     int retval = 0;
 #define SDL_PROC(ret, func, params)                                                           \
     do {                                                                                      \
-        data->func = SDL_GL_GetProcAddress(#func);                                            \
+        data->func = (ret (APIENTRY *) params)SDL_GL_GetProcAddress(#func);                                            \
         if (!data->func) {                                                                    \
             retval = SDL_SetError("Couldn't load GL function %s: %s", #func, SDL_GetError()); \
         }                                                                                     \
diff --git a/src/render/opengles2/SDL_render_gles2.c b/src/render/opengles2/SDL_render_gles2.c
index ef0b2a5f2f18..f169c81892f7 100644
--- a/src/render/opengles2/SDL_render_gles2.c
+++ b/src/render/opengles2/SDL_render_gles2.c
@@ -252,7 +252,7 @@ static int GLES2_LoadFunctions(GLES2_RenderData *data)
 #else
 #define SDL_PROC(ret, func, params)                                                            \
     do {                                                                                       \
-        data->func = SDL_GL_GetProcAddress(#func);                                             \
+        data->func = (ret (APIENTRY *) params)SDL_GL_GetProcAddress(#func);                                             \
         if (!data->func) {                                                                     \
             return SDL_SetError("Couldn't load GLES2 function %s: %s", #func, SDL_GetError()); \
         }                                                                                      \
diff --git a/src/video/SDL_egl.c b/src/video/SDL_egl.c
index e4b12e9b5fa0..d3b1e4b8c16a 100644
--- a/src/video/SDL_egl.c
+++ b/src/video/SDL_egl.c
@@ -115,20 +115,24 @@
 #define EGL_PLATFORM_DEVICE_EXT 0x0
 #endif
 
+#if SDL_VIDEO_OPENGL
+typedef void (APIENTRY* PFNGLGETINTEGERVPROC) (GLenum pname, GLint * params);
+#endif
+
 #if defined(SDL_VIDEO_STATIC_ANGLE) || defined(SDL_VIDEO_DRIVER_VITA)
-#define LOAD_FUNC(NAME) \
-    _this->egl_data->NAME = (void *)NAME;
+#define LOAD_FUNC(TYPE, NAME) \
+    _this->egl_data->NAME = NAME;
 #else
-#define LOAD_FUNC(NAME)                                                               \
-    _this->egl_data->NAME = SDL_LoadFunction(_this->egl_data->egl_dll_handle, #NAME); \
+#define LOAD_FUNC(TYPE, NAME)                                                               \
+    _this->egl_data->NAME = (TYPE)SDL_LoadFunction(_this->egl_data->egl_dll_handle, #NAME); \
     if (!_this->egl_data->NAME) {                                                     \
         return SDL_SetError("Could not retrieve EGL function " #NAME);                \
     }
 #endif
 
 /* it is allowed to not have some of the EGL extensions on start - attempts to use them will fail later. */
-#define LOAD_FUNC_EGLEXT(NAME) \
-    _this->egl_data->NAME = _this->egl_data->eglGetProcAddress(#NAME);
+#define LOAD_FUNC_EGLEXT(TYPE, NAME) \
+    _this->egl_data->NAME = (TYPE)_this->egl_data->eglGetProcAddress(#NAME);
 
 static const char *SDL_EGL_GetErrorName(EGLint eglErrorCode)
 {
@@ -241,10 +245,9 @@ SDL_bool SDL_EGL_HasExtension(_THIS, SDL_EGL_ExtensionType type, const char *ext
     return SDL_FALSE;
 }
 
-void *
-SDL_EGL_GetProcAddressInternal(_THIS, const char *proc)
+SDL_FunctionPointer SDL_EGL_GetProcAddressInternal(_THIS, const char *proc)
 {
-    void *retval = NULL;
+    SDL_FunctionPointer retval = NULL;
     if (_this->egl_data != NULL) {
         const Uint32 eglver = (((Uint32)_this->egl_data->egl_version_major) << 16) | ((Uint32)_this->egl_data->egl_version_minor);
         const SDL_bool is_egl_15_or_later = eglver >= ((((Uint32)1) << 16) | 5);
@@ -424,34 +427,33 @@ static int SDL_EGL_LoadLibraryInternal(_THIS, const char *egl_path)
 #endif
 
     /* Load new function pointers */
-    LOAD_FUNC(eglGetDisplay);
-    LOAD_FUNC(eglInitialize);
-    LOAD_FUNC(eglTerminate);
-    LOAD_FUNC(eglGetProcAddress);
-    LOAD_FUNC(eglChooseConfig);
-    LOAD_FUNC(eglGetConfigAttrib);
-    LOAD_FUNC(eglCreateContext);
-    LOAD_FUNC(eglDestroyContext);
-    LOAD_FUNC(eglCreatePbufferSurface);
-    LOAD_FUNC(eglCreateWindowSurface);
-    LOAD_FUNC(eglDestroySurface);
-    LOAD_FUNC(eglMakeCurrent);
-    LOAD_FUNC(eglSwapBuffers);
-    LOAD_FUNC(eglSwapInterval);
-    LOAD_FUNC(eglWaitNative);
-    LOAD_FUNC(eglWaitGL);
-    LOAD_FUNC(eglBindAPI);
-    LOAD_FUNC(eglQueryAPI);
-    LOAD_FUNC(eglQueryString);
-    LOAD_FUNC(eglGetError);
-    LOAD_FUNC_EGLEXT(eglQueryDevicesEXT);
-    LOAD_FUNC_EGLEXT(eglGetPlatformDisplayEXT);
+    LOAD_FUNC(PFNEGLGETDISPLAYPROC, eglGetDisplay);
+    LOAD_FUNC(PFNEGLINITIALIZEPROC, eglInitialize);
+    LOAD_FUNC(PFNEGLTERMINATEPROC, eglTerminate);
+    LOAD_FUNC(PFNEGLGETPROCADDRESSPROC, eglGetProcAddress);
+    LOAD_FUNC(PFNEGLCHOOSECONFIGPROC, eglChooseConfig);
+    LOAD_FUNC(PFNEGLCREATECONTEXTPROC, eglCreateContext);
+    LOAD_FUNC(PFNEGLDESTROYCONTEXTPROC, eglDestroyContext);
+    LOAD_FUNC(PFNEGLCREATEPBUFFERSURFACEPROC, eglCreatePbufferSurface);
+    LOAD_FUNC(PFNEGLCREATEWINDOWSURFACEPROC, eglCreateWindowSurface);
+    LOAD_FUNC(PFNEGLDESTROYSURFACEPROC, eglDestroySurface);
+    LOAD_FUNC(PFNEGLMAKECURRENTPROC, eglMakeCurrent);
+    LOAD_FUNC(PFNEGLSWAPBUFFERSPROC, eglSwapBuffers);
+    LOAD_FUNC(PFNEGLSWAPINTERVALPROC, eglSwapInterval);
+    LOAD_FUNC(PFNEGLQUERYSTRINGPROC, eglQueryString);
+    LOAD_FUNC(PFNEGLGETCONFIGATTRIBPROC, eglGetConfigAttrib);
+    LOAD_FUNC(PFNEGLWAITNATIVEPROC, eglWaitNative);
+    LOAD_FUNC(PFNEGLWAITGLPROC, eglWaitGL);
+    LOAD_FUNC(PFNEGLBINDAPIPROC, eglBindAPI);
+    LOAD_FUNC(PFNEGLGETERRORPROC, eglGetError);
+    LOAD_FUNC_EGLEXT(PFNEGLQUERYDEVICESEXTPROC, eglQueryDevicesEXT);
+    LOAD_FUNC_EGLEXT(PFNEGLGETPLATFORMDISPLAYEXTPROC, eglGetPlatformDisplayEXT);
     /* Atomic functions */
-    LOAD_FUNC_EGLEXT(eglCreateSyncKHR);
-    LOAD_FUNC_EGLEXT(eglDestroySyncKHR);
-    LOAD_FUNC_EGLEXT(eglDupNativeFenceFDANDROID);
-    LOAD_FUNC_EGLEXT(eglWaitSyncKHR);
-    LOAD_FUNC_EGLEXT(eglClientWaitSyncKHR);
+    LOAD_FUNC_EGLEXT(PFNEGLCREATESYNCKHRPROC, eglCreateSyncKHR);
+    LOAD_FUNC_EGLEXT(PFNEGLDESTROYSYNCKHRPROC, eglDestroySyncKHR);
+    LOAD_FUNC_EGLEXT(PFNEGLDUPNATIVEFENCEFDANDROIDPROC, eglDupNativeFenceFDANDROID);
+    LOAD_FUNC_EGLEXT(PFNEGLWAITSYNCKHRPROC, eglWaitSyncKHR);
+    LOAD_FUNC_EGLEXT(PFNEGLCLIENTWAITSYNCKHRPROC, eglClientWaitSyncKHR);
     /* Atomic functions end */
 
     if (path) {
@@ -519,7 +521,7 @@ int SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_di
         SDL_EGL_GetVersion(_this);
 
         if (_this->egl_data->egl_version_major == 1 && _this->egl_data->egl_version_minor == 5) {
-            LOAD_FUNC(eglGetPlatformDisplay);
+            LOAD_FUNC(PFNEGLGETPLATFORMDISPLAYPROC, eglGetPlatformDisplay);
         }
 
         if (_this->egl_data->eglGetPlatformDisplay) {
@@ -535,7 +537,7 @@ int SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_di
             _this->egl_data->egl_display = _this->egl_data->eglGetPlatformDisplay(platform, (void *)(uintptr_t)native_display, attribs);
         } else {
             if (SDL_EGL_HasExtension(_this, SDL_EGL_CLIENT_EXTENSION, "EGL_EXT_platform_base")) {
-                _this->egl_data->eglGetPlatformDisplayEXT = SDL_EGL_GetProcAddressInternal(_this, "eglGetPlatformDisplayEXT");
+                _this->egl_data->eglGetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC)SDL_EGL_GetProcAddressInternal(_this, "eglGetPlatformDisplayEXT");
                 if (_this->egl_data->eglGetPlatformDisplayEXT) {
                     _this->egl_data->egl_display = _this->egl_data->eglGetPlatformDisplayEXT(platform, (void *)(uintptr_t)native_display, NULL);
                 }
@@ -1103,8 +1105,7 @@ SDL_EGL_CreateContext(_THIS, EGLSurface egl_surface)
 #if SDL_VIDEO_OPENGL && !defined(SDL_VIDEO_DRIVER_VITA)
         } else {
             /* Desktop OpenGL supports it by default from version 3.0 on. */
-            void(APIENTRY * glGetIntegervFunc)(GLenum pname, GLint * params);
-            glGetIntegervFunc = SDL_GL_GetProcAddress("glGetIntegerv");
+             PFNGLGETINTEGERVPROC glGetIntegervFunc = (PFNGLGETINTEGERVPROC)SDL_GL_GetProcAddress("glGetIntegerv");
             if (glGetIntegervFunc) {
                 GLint v = 0;
                 glGetIntegervFunc(GL_MAJOR_VERSION, &v);
diff --git a/src/video/SDL_egl_c.h b/src/video/SDL_egl_c.h
index 93a44e92c139..b0be4524d2ab 100644
--- a/src/video/SDL_egl_c.h
+++ b/src/video/SDL_egl_c.h
@@ -43,77 +43,35 @@ typedef struct SDL_EGL_VideoData
     SDL_bool is_offscreen; /* whether EGL display was offscreen */
     EGLenum apitype;       /* EGL_OPENGL_ES_API, EGL_OPENGL_API, etc */
 
-    EGLDisplay(EGLAPIENTRY *eglGetDisplay)(NativeDisplayType display);
-    EGLDisplay(EGLAPIENTRY *eglGetPlatformDisplay)(EGLenum platform,
-                                                   void *native_display,
-                                                   const EGLAttrib *attrib_list);
-    EGLDisplay(EGLAPIENTRY *eglGetPlatformDisplayEXT)(EGLenum platform,
-                                                      void *native_display,
-                                                      const EGLint *attrib_list);
-    EGLBoolean(EGLAPIENTRY *eglInitialize)(EGLDisplay dpy, EGLint *major,
-                                           EGLint *minor);
-    EGLBoolean(EGLAPIENTRY *eglTerminate)(EGLDisplay dpy);
-
-    void *(EGLAPIENTRY *eglGetProcAddress)(const char *procName);
-
-    EGLBoolean(EGLAPIENTRY *eglChooseConfig)(EGLDisplay dpy,
-                                             const EGLint *attrib_list,
-                                             EGLConfig *configs,
-                                             EGLint config_size, EGLint *num_config);
-
-    EGLContext(EGLAPIENTRY *eglCreateContext)(EGLDisplay dpy,
-                                              EGLConfig config,
-                                              EGLContext share_list,
-                                              const EGLint *attrib_list);
-
-    EGLBoolean(EGLAPIENTRY *eglDestroyContext)(EGLDisplay dpy, EGLContext ctx);
-
-    EGLSurface(EGLAPIENTRY *eglCreatePbufferSurface)(EGLDisplay dpy, EGLConfig config,
-                                                     EGLint const *attrib_list);
-
-    EGLSurface(EGLAPIENTRY *eglCreateWindowSurface)(EGLDisplay dpy,
-                                                    EGLConfig config,
-                                                    NativeWindowType window,
-                                                    const EGLint *attrib_list);
-    EGLBoolean(EGLAPIENTRY *eglDestroySurface)(EGLDisplay dpy, EGLSurface surface);
-
-    EGLBoolean(EGLAPIENTRY *eglMakeCurrent)(EGLDisplay dpy, EGLSurface draw,
-                                            EGLSurface read, EGLContext ctx);
-
-    EGLBoolean(EGLAPIENTRY *eglSwapBuffers)(EGLDisplay dpy, EGLSurface draw);
-
-    EGLBoolean(EGLAPIENTRY *eglSwapInterval)(EGLDisplay dpy, EGLint interval);
-
-    const char *(EGLAPIENTRY *eglQueryString)(EGLDisplay dpy, EGLint name);
-
-    EGLenum(EGLAP

(Patch may be truncated, please check the link at the top of this post.)