Run constructors before resolving ifunc functions

Bug: 17177284

(cherry picked from commit 9598b8c415e2fa9f240508185fe8c964b83f538d)

Change-Id: I2c9631ee1cd77f8cf95ec0216a35b605c8786454
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index 260cbd6..6de38c8 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -90,32 +90,42 @@
 // ifuncs are only supported on intel for now
 #if defined(__i386__) || defined(__x86_64__)
 TEST(dlfcn, ifunc) {
-  const char* (*foo_ptr)();
-  const char* (*foo_library_ptr)();
+  typedef const char* (*fn_ptr)();
 
   // ifunc's choice depends on whether IFUNC_CHOICE has a value
   // first check the set case
   setenv("IFUNC_CHOICE", "set", 1);
   void* handle = dlopen("libtest_ifunc.so", RTLD_NOW);
   ASSERT_TRUE(handle != NULL);
-  *(void **)(&foo_ptr) = dlsym(handle, "foo");
-  *(void **)(&foo_library_ptr) = dlsym(handle, "foo_library");
+  fn_ptr foo_ptr = reinterpret_cast<fn_ptr>(dlsym(handle, "foo"));
+  fn_ptr foo_library_ptr = reinterpret_cast<fn_ptr>(dlsym(handle, "foo_library"));
   ASSERT_TRUE(foo_ptr != NULL);
   ASSERT_TRUE(foo_library_ptr != NULL);
-  ASSERT_EQ(strncmp("set", (*foo_ptr)(), 3), 0);
-  ASSERT_EQ(strncmp("set", (*foo_library_ptr)(), 3), 0);
+  ASSERT_EQ(strncmp("set", foo_ptr(), 3), 0);
+  ASSERT_EQ(strncmp("set", foo_library_ptr(), 3), 0);
   dlclose(handle);
 
   // then check the unset case
   unsetenv("IFUNC_CHOICE");
   handle = dlopen("libtest_ifunc.so", RTLD_NOW);
   ASSERT_TRUE(handle != NULL);
-  *(void **)(&foo_ptr) = dlsym(handle, "foo");
-  *(void **)(&foo_library_ptr) = dlsym(handle, "foo_library");
+  foo_ptr = reinterpret_cast<fn_ptr>(dlsym(handle, "foo"));
+  foo_library_ptr = reinterpret_cast<fn_ptr>(dlsym(handle, "foo_library"));
   ASSERT_TRUE(foo_ptr != NULL);
   ASSERT_TRUE(foo_library_ptr != NULL);
-  ASSERT_EQ(strncmp("unset", (*foo_ptr)(), 5), 0);
-  ASSERT_EQ(strncmp("unset", (*foo_library_ptr)(), 3), 0);
+  ASSERT_EQ(strncmp("unset", foo_ptr(), 5), 0);
+  ASSERT_EQ(strncmp("unset", foo_library_ptr(), 3), 0);
+  dlclose(handle);
+}
+
+TEST(dlfcn, ifunc_ctor_call) {
+  typedef const char* (*fn_ptr)();
+
+  void* handle = dlopen("libtest_ifunc.so", RTLD_NOW);
+  ASSERT_TRUE(handle != NULL) << dlerror();
+  fn_ptr is_ctor_called =  reinterpret_cast<fn_ptr>(dlsym(handle, "is_ctor_called"));
+  ASSERT_TRUE(is_ctor_called != NULL) << dlerror();
+  ASSERT_STREQ("true", is_ctor_called());
   dlclose(handle);
 }
 #endif