#include <glib.h>
#include <gmodule.h>

#if     __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)
#  define G_GNUC_MAY_ALIAS __attribute__((may_alias))
#else
#  define G_GNUC_MAY_ALIAS
#endif

int
main (int   argc,
      char *argv[])
{
  GModule *main_module = g_module_open (NULL, G_MODULE_BIND_LAZY);
  gboolean success;
  if (1) /* uses wrong type, but doesn't warn */
    {
      void *p;
      success = g_module_symbol (main_module, "main", &p);
      g_assert (success == TRUE);
      g_assert (p == main);
      g_print ("passed 1.\n");
    }
  if (1) /* generates strict aliasing warning */
    {
      int (*p) (int, char**);
      success = g_module_symbol (main_module, "main", (void**) &p);
      g_assert (success == TRUE);
      g_assert (p == main);
      g_print ("passed 2.\n");
    }
  if (1) /* correct type, no warning */
    {
      typedef int (MainFType) (int, char**);
      typedef MainFType G_GNUC_MAY_ALIAS *MainFunc;
      MainFunc p;
      success = g_module_symbol (main_module, "main", (void **) &p);
      g_assert (success == TRUE);
      g_assert (p == main);
      g_print ("passed 3.\n");
    }
  if (1) /* correct type, no warning */
    {
      typedef int (MainFType) (int, char**);
      MainFType G_GNUC_MAY_ALIAS *p;
      success = g_module_symbol (main_module, "main", (void **) &p);
      g_assert (success == TRUE);
      g_assert (p == main);
      g_print ("passed 4.\n");
    }
  return 0;
}

// gcc -Wall -g -O2 `pkg-config --cflags --libs glib-2.0 gmodule-2.0` strict-aliasing.c -o strict-aliasing && ./strict-aliasing
