Commit 2bb5f487922aa908d27175c5a562d34f4c6197d9

Pali Rohár 2019-07-25T20:34:46

Fix gcc warning: ISO C forbids return between function pointer and void * Instead of using compiler specific pragma to disable particular warning, rewrite code which cast from function pointer to data pointer according to POSIX dlopen() documentation. This also fix compile warning under MSVC. According to the ISO C standard, casting between function pointers and 'void *', as done above, produces undefined results. POSIX.1-2003 and POSIX.1-2008 accepted this state of affairs and proposed the following workaround: *(void **) (&cosine) = dlsym(handle, "cos"); This (clumsy) cast conforms with the ISO C standard and will avoid any compiler warnings.

diff --git a/dlfcn.c b/dlfcn.c
index 1815ae0..f8af91f 100644
--- a/dlfcn.c
+++ b/dlfcn.c
@@ -454,11 +454,7 @@ end:
         save_err_str( name );
     }
 
-    //  warning C4054: 'type cast' : from function pointer 'FARPROC' to data pointer 'void *'
-#ifdef _MSC_VER
-#pragma warning( suppress: 4054 )
-#endif
-    return (void*) symbol;
+    return *(void **) (&symbol);
 }
 
 char *dlerror( void )
diff --git a/test.c b/test.c
index b576b9a..798ab08 100644
--- a/test.c
+++ b/test.c
@@ -241,7 +241,7 @@ int main()
     else
         printf( "SUCCESS\tGot global handle: %p\n", global );
 
-    fwrite_local = dlsym(global, "fwrite");
+    *(void **) (&fwrite_local) = dlsym( global, "fwrite" );
     if (!fwrite_local)
     {
         error = dlerror();
@@ -252,12 +252,12 @@ int main()
         RETURN_ERROR;
     }
     else
-        printf("SUCCESS\tGot symbol from global handle: %p\n", fwrite_local);
+        printf( "SUCCESS\tGot symbol from global handle: %p\n", *(void **) (&fwrite_local) );
     char * hello_world = "Hello world from local fwrite!\n";
     fwrite_local(hello_world,sizeof(char),strlen(hello_world),stderr);
     fflush(stderr);
 
-    fputs_default = dlsym(RTLD_DEFAULT, "fputs");
+    *(void **) (&fputs_default) = dlsym( RTLD_DEFAULT, "fputs" );
     if (!fputs_default)
     {
         error = dlerror();
@@ -268,12 +268,12 @@ int main()
         RETURN_ERROR;
     }
     else
-        printf("SUCCESS\tGot symbol from default handle: %p\n", fputs_default);
+        printf( "SUCCESS\tGot symbol from default handle: %p\n", *(void **) (&fputs_default) );
     char * hello_world_fputs = "Hello world from default fputs!\n";
     fputs_default(hello_world_fputs, stderr);
     fflush(stderr);
 
-    function = dlsym( library, "function" );
+    *(void **) (&function) = dlsym( library, "function" );
     if( !function )
     {
         error = dlerror( );
@@ -284,11 +284,11 @@ int main()
         RETURN_ERROR;
     }
     else
-        printf( "SUCCESS\tGot symbol from library handle: %p\n", function );
+        printf( "SUCCESS\tGot symbol from library handle: %p\n", *(void **) (&function) );
 
     RUNFUNC;
 
-    function2_from_library2 = dlsym( library2, "function2" );
+    *(void **) (&function2_from_library2) = dlsym( library2, "function2" );
     if( !function2_from_library2 )
     {
         error = dlerror( );
@@ -299,7 +299,7 @@ int main()
         RETURN_ERROR;
     }
     else
-        printf( "SUCCESS\tGot symbol from library2 handle: %p\n", function2_from_library2 );
+        printf( "SUCCESS\tGot symbol from library2 handle: %p\n", *(void **) (&function2_from_library2) );
 
     ret = function2_from_library2 ();
     if( ret != 2 )
@@ -309,11 +309,11 @@ int main()
         RETURN_ERROR;
     }
 
-    nonexistentfunction = dlsym( library, "nonexistentfunction" );
+    *(void **) (&nonexistentfunction) = dlsym( library, "nonexistentfunction" );
     if( nonexistentfunction )
     {
         error = dlerror( );
-        printf( "ERROR\tGot nonexistent symbol from library handle: %p\n", nonexistentfunction );
+        printf( "ERROR\tGot nonexistent symbol from library handle: %p\n", *(void **) (&nonexistentfunction) );
         CLOSE_LIB;
         CLOSE_GLOBAL;
         RETURN_ERROR;
@@ -327,7 +327,7 @@ int main()
     else
         printf( "SUCCESS\tCould not get nonexistent symbol from library handle: %s\n", error );
 
-    function = dlsym( global, "function" );
+    *(void **) (&function) = dlsym( global, "function" );
     if( !function )
     {
         error = dlerror( );
@@ -338,15 +338,15 @@ int main()
         RETURN_ERROR;
     }
     else
-        printf( "SUCCESS\tGot symbol from global handle: %p\n", function );
+        printf( "SUCCESS\tGot symbol from global handle: %p\n", *(void **) (&function) );
 
     RUNFUNC;
 
-    nonexistentfunction = dlsym( global, "nonexistentfunction" );
+    *(void **) (&nonexistentfunction) = dlsym( global, "nonexistentfunction" );
     if( nonexistentfunction )
     {
         error = dlerror( );
-        printf( "ERROR\tGot nonexistent symbol from global handle: %p\n", nonexistentfunction );
+        printf( "ERROR\tGot nonexistent symbol from global handle: %p\n", *(void **) (&nonexistentfunction) );
         CLOSE_LIB;
         CLOSE_GLOBAL;
         RETURN_ERROR;
@@ -392,7 +392,7 @@ int main()
     else
         printf( "SUCCESS\tOpened library locally: %p\n", library );
 
-    function = dlsym( library, "function" );
+    *(void **) (&function) = dlsym( library, "function" );
     if( !function )
     {
         error = dlerror( );
@@ -403,15 +403,15 @@ int main()
         RETURN_ERROR;
     }
     else
-        printf( "SUCCESS\tGot symbol from library handle: %p\n", function );
+        printf( "SUCCESS\tGot symbol from library handle: %p\n", *(void **) (&function) );
 
     RUNFUNC;
 
-    nonexistentfunction = dlsym( library, "nonexistentfunction" );
+    *(void **) (&nonexistentfunction) = dlsym( library, "nonexistentfunction" );
     if( nonexistentfunction )
     {
         error = dlerror( );
-        printf( "ERROR\tGot nonexistent symbol from library handle: %p\n", nonexistentfunction );
+        printf( "ERROR\tGot nonexistent symbol from library handle: %p\n", *(void **) (&nonexistentfunction) );
         CLOSE_LIB;
         CLOSE_GLOBAL;
         RETURN_ERROR;
@@ -425,12 +425,12 @@ int main()
     else
         printf( "SUCCESS\tCould not get nonexistent symbol from library handle: %s\n", error );
 
-    function = dlsym( global, "function" );
+    *(void **) (&function) = dlsym( global, "function" );
     if( function )
     {
         error = dlerror( );
         printf( "ERROR\tGot local symbol from global handle: %s @ %p\n",
-                error ? error : "", function );
+                error ? error : "", *(void **) (&function) );
         CLOSE_LIB;
         CLOSE_GLOBAL;
         RETURN_ERROR;
@@ -438,11 +438,11 @@ int main()
     else
         printf( "SUCCESS\tDid not get local symbol from global handle.\n" );
 
-    nonexistentfunction = dlsym( global, "nonexistentfunction" );
+    *(void **) (&nonexistentfunction) = dlsym( global, "nonexistentfunction" );
     if( nonexistentfunction )
     {
         error = dlerror( );
-        printf( "ERROR\tGot nonexistent local symbol from global handle: %p\n", nonexistentfunction );
+        printf( "ERROR\tGot nonexistent local symbol from global handle: %p\n", *(void **) (&nonexistentfunction) );
         CLOSE_LIB;
         CLOSE_GLOBAL;
         RETURN_ERROR;
@@ -468,7 +468,7 @@ int main()
     else
         printf( "SUCCESS\tOpened library globally without closing it first: %p\n", library );
 
-    function = dlsym( global, "function" );
+    *(void **) (&function) = dlsym( global, "function" );
     if( !function )
     {
         error = dlerror( );
@@ -479,15 +479,15 @@ int main()
         RETURN_ERROR;
     }
     else
-        printf( "SUCCESS\tGot symbol from global handle: %p\n", function );
+        printf( "SUCCESS\tGot symbol from global handle: %p\n", *(void **) (&function) );
 
     RUNFUNC;
 
-    nonexistentfunction = dlsym( global, "nonexistentfunction" );
+    *(void **) (&nonexistentfunction) = dlsym( global, "nonexistentfunction" );
     if( nonexistentfunction )
     {
         error = dlerror( );
-        printf( "ERROR\tGot nonexistent symbol from global handle: %p\n", nonexistentfunction );
+        printf( "ERROR\tGot nonexistent symbol from global handle: %p\n", *(void **) (&nonexistentfunction) );
         CLOSE_LIB;
         CLOSE_GLOBAL;
         RETURN_ERROR;
@@ -518,7 +518,7 @@ int main()
         }
     }
 
-    function = dlsym(global, "fwrite");
+    *(void **) (&function) = dlsym( global, "fwrite" );
     if (!function)
     {
         error = dlerror();
@@ -529,7 +529,7 @@ int main()
         RETURN_ERROR;
     }
     else
-        printf("SUCCESS\tGot symbol from global handle: %p\n", function);
+        printf( "SUCCESS\tGot symbol from global handle: %p\n", *(void **) (&function) );
     
 
     uMode = SetErrorMode( SEM_FAILCRITICALERRORS );
@@ -541,7 +541,7 @@ int main()
         RETURN_ERROR;
     }
     else
-        printf( "SUCCESS\tOpened library3 via WINAPI: %p\n", library3 );
+        printf( "SUCCESS\tOpened library3 via WINAPI: %p\n", (void *)library3 );
 
     ret = dlclose( library );
     if( ret )
@@ -554,7 +554,7 @@ int main()
     else
         printf( "SUCCESS\tClosed library.\n" );
 
-    function = dlsym(global, "function3");
+    *(void **) (&function) = dlsym( global, "function3" );
     if (!function)
     {
         error = dlerror();
@@ -565,7 +565,7 @@ int main()
         RETURN_ERROR;
     }
     else
-        printf("SUCCESS\tGot symbol from global handle: %p\n", function);
+        printf( "SUCCESS\tGot symbol from global handle: %p\n", *(void **) (&function) );
 
     RUNFUNC;
 
diff --git a/testdll2.c b/testdll2.c
index 910c820..71d385a 100644
--- a/testdll2.c
+++ b/testdll2.c
@@ -38,7 +38,7 @@ EXPORT int function2( void )
     char *error;
     int (*function2_orig)(void);
     printf( "Hello, world! from wrapper library\n" );
-    function2_orig = dlsym(RTLD_NEXT, "function2");
+    *(void **) (&function2_orig) = dlsym( RTLD_NEXT, "function2" );
     if (!function2_orig)
     {
         error = dlerror( );