Add atexit test for attributed c-tor/d-tor

 1. Add test for __attribute__((constructor/destructor))
    and static constructor

 2. Compile C++ testlibs with -std=gnu++11

Change-Id: I67f9308144a0c638a51f111fcba8e1933fe0ba41
diff --git a/tests/atexit_test.cpp b/tests/atexit_test.cpp
index e01220e..e92889d 100644
--- a/tests/atexit_test.cpp
+++ b/tests/atexit_test.cpp
@@ -24,20 +24,33 @@
 
 #include <string>
 
-TEST(atexit, dlclose) {
+TEST(atexit, sofile) {
   std::string atexit_call_sequence;
   bool valid_this_in_static_dtor = false;
+  bool attr_dtor_called = false;
+
   void* handle = dlopen("libtest_atexit.so", RTLD_NOW);
-  ASSERT_TRUE(handle != NULL);
+  ASSERT_TRUE(handle != nullptr);
+
+  typedef int (*int_fn)(void);
+  int_fn get_cxx_ctor_called, get_attr_ctor_called;
+  get_cxx_ctor_called = reinterpret_cast<int_fn>(dlsym(handle, "get_cxx_ctor_called"));
+  get_attr_ctor_called = reinterpret_cast<int_fn>(dlsym(handle, "get_attr_ctor_called"));
+  ASSERT_TRUE(get_cxx_ctor_called != nullptr);
+  ASSERT_TRUE(get_attr_ctor_called != nullptr);
+
+  ASSERT_EQ(1, get_cxx_ctor_called());
+  ASSERT_EQ(1, get_attr_ctor_called());
 
   void* sym = dlsym(handle, "register_atexit");
-  ASSERT_TRUE(sym != NULL);
-  reinterpret_cast<void (*)(std::string*, bool*)>(sym)(&atexit_call_sequence, &valid_this_in_static_dtor);
+  ASSERT_TRUE(sym != nullptr);
+  reinterpret_cast<void (*)(std::string*, bool*, bool*)>(sym)(&atexit_call_sequence, &valid_this_in_static_dtor, &attr_dtor_called);
 
   ASSERT_EQ(0, dlclose(handle));
   // this test verifies atexit call from atexit handler. as well as the order of calls
   ASSERT_EQ("Humpty Dumpty sat on a wall", atexit_call_sequence);
   ASSERT_TRUE(valid_this_in_static_dtor);
+  ASSERT_TRUE(attr_dtor_called);
 }
 
 class TestMainStaticDtorClass {
@@ -57,7 +70,7 @@
   static const TestMainStaticDtorClass* expected_this;
 };
 
-const TestMainStaticDtorClass* TestMainStaticDtorClass::expected_this = NULL;
+const TestMainStaticDtorClass* TestMainStaticDtorClass::expected_this = nullptr;
 
 static void atexit_func5() {
   fprintf(stderr, "5");
diff --git a/tests/libs/Android.mk b/tests/libs/Android.mk
index bca2047..65c341d 100644
--- a/tests/libs/Android.mk
+++ b/tests/libs/Android.mk
@@ -17,6 +17,7 @@
 LOCAL_PATH := $(call my-dir)
 TEST_PATH := $(LOCAL_PATH)/..
 
+common_cppflags += -std=gnu++11
 # -----------------------------------------------------------------------------
 # Library used by dlfcn tests.
 # -----------------------------------------------------------------------------
diff --git a/tests/libs/atexit_testlib.cpp b/tests/libs/atexit_testlib.cpp
index d35f57b..314e8de 100644
--- a/tests/libs/atexit_testlib.cpp
+++ b/tests/libs/atexit_testlib.cpp
@@ -19,12 +19,19 @@
 #include <string>
 
 // use external control number from main test
-static std::string* atexit_sequence = NULL;
-static bool* atexit_valid_this_in_static_dtor = NULL;
+static std::string* atexit_sequence = nullptr;
+static bool* atexit_valid_this_in_static_dtor = nullptr;
+static bool* atexit_attr_dtor_called = nullptr;
+
+static int cxx_ctor_called = 0;
+static int attr_ctor_called = 0;
 
 static class AtExitStaticClass {
  public:
-  AtExitStaticClass() { expected_this = this; }
+  AtExitStaticClass() {
+    expected_this = this;
+    cxx_ctor_called = 1;
+  }
   ~AtExitStaticClass() {
     if (atexit_valid_this_in_static_dtor) {
       *atexit_valid_this_in_static_dtor = (expected_this == this);
@@ -35,7 +42,7 @@
 
 } static_obj;
 
-const AtExitStaticClass* AtExitStaticClass::expected_this = NULL;
+const AtExitStaticClass* AtExitStaticClass::expected_this = nullptr;
 
 // 4
 static void atexit_handler_from_atexit_from_atexit2() {
@@ -66,10 +73,30 @@
   *atexit_sequence += " a wall";
 }
 
-extern "C" void register_atexit(std::string* sequence, bool* valid_this_in_static_dtor) {
+// attribute c-tor and d-tor
+static void __attribute__((constructor)) atexit_attr_ctor() {
+  attr_ctor_called = 1;
+}
+
+static void __attribute__((destructor)) atexit_attr_dtor() {
+  if (atexit_attr_dtor_called) {
+    *atexit_attr_dtor_called = true;
+  }
+}
+
+extern "C" void register_atexit(std::string* sequence, bool* valid_this_in_static_dtor, bool* attr_dtor_called) {
   atexit_sequence = sequence;
   atexit_valid_this_in_static_dtor = valid_this_in_static_dtor;
+  atexit_attr_dtor_called = attr_dtor_called;
   atexit(atexit_handler_regular);
   atexit(atexit_handler_with_atexit);
 }
 
+extern "C" int get_cxx_ctor_called() {
+  return cxx_ctor_called;
+}
+
+extern "C" int get_attr_ctor_called() {
+  return attr_ctor_called;
+}
+