re PR c++/45603 (crash in "build_addr_func")
authorJason Merrill <jason@redhat.com>
Fri, 8 Jul 2011 17:39:17 +0000 (13:39 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 8 Jul 2011 17:39:17 +0000 (13:39 -0400)
PR c++/45603
* decl.c (expand_static_init): Don't get confused by user
declaration of __cxa_guard_acquire.

From-SVN: r176054

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/abi/guard3.C [new file with mode: 0644]

index 092e5c01043e668b23589ccc750996bc16f88a5e..41157a1de837f6654a33da4038b67d398cdb5c4c 100644 (file)
@@ -1,5 +1,9 @@
 2011-07-08  Jason Merrill  <jason@redhat.com>
 
+       PR c++/45603
+       * decl.c (expand_static_init): Don't get confused by user
+       declaration of __cxa_guard_acquire.
+
        * typeck.c (cp_apply_type_quals_to_decl): Don't check
        COMPLETE_TYPE_P either.
 
index e36739b38d6fe7d0426785bbf8a0c43ded8a8a0f..266d0492ed97065e6f160e8f668016dab9b3cfcf 100644 (file)
@@ -6646,7 +6646,6 @@ expand_static_init (tree decl, tree init)
       tree if_stmt = NULL_TREE, inner_if_stmt = NULL_TREE;
       tree then_clause = NULL_TREE, inner_then_clause = NULL_TREE;
       tree guard, guard_addr;
-      tree acquire_fn, release_fn, abort_fn;
       tree flag, begin;
 
       /* Emit code to perform this initialization but once.  This code
@@ -6696,29 +6695,31 @@ expand_static_init (tree decl, tree init)
 
       if (flag_threadsafe_statics)
        {
+         tree vfntype = NULL_TREE;
+         tree acquire_name, release_name, abort_name;
+         tree acquire_fn, release_fn, abort_fn;
          guard_addr = build_address (guard);
 
-         acquire_fn = get_identifier ("__cxa_guard_acquire");
-         release_fn = get_identifier ("__cxa_guard_release");
-         abort_fn = get_identifier ("__cxa_guard_abort");
-         if (!get_global_value_if_present (acquire_fn, &acquire_fn))
-           {
-             tree vfntype = build_function_type_list (void_type_node,
-                                                      TREE_TYPE (guard_addr),
-                                                      NULL_TREE);
-             acquire_fn = push_library_fn
-               (acquire_fn, build_function_type_list (integer_type_node,
+         acquire_name = get_identifier ("__cxa_guard_acquire");
+         release_name = get_identifier ("__cxa_guard_release");
+         abort_name = get_identifier ("__cxa_guard_abort");
+         acquire_fn = identifier_global_value (acquire_name);
+         release_fn = identifier_global_value (release_name);
+         abort_fn = identifier_global_value (abort_name);
+         if (!acquire_fn)
+           acquire_fn = push_library_fn
+             (acquire_name, build_function_type_list (integer_type_node,
                                                       TREE_TYPE (guard_addr),
                                                       NULL_TREE),
-                NULL_TREE);
-             release_fn = push_library_fn (release_fn, vfntype, NULL_TREE);
-             abort_fn = push_library_fn (abort_fn, vfntype, NULL_TREE);
-           }
-         else
-           {
-             release_fn = identifier_global_value (release_fn);
-             abort_fn = identifier_global_value (abort_fn);
-           }
+              NULL_TREE);
+         if (!release_fn || !abort_fn)
+           vfntype = build_function_type_list (void_type_node,
+                                               TREE_TYPE (guard_addr),
+                                               NULL_TREE);
+         if (!release_fn)
+           release_fn = push_library_fn (release_name, vfntype, NULL_TREE);
+         if (!abort_fn)
+           abort_fn = push_library_fn (abort_name, vfntype, NULL_TREE);
 
          inner_if_stmt = begin_if_stmt ();
          finish_if_stmt_cond (build_call_n (acquire_fn, 1, guard_addr),
index b2ba49aea53fa9198ad81a6e9b198a66f96c4ef2..21e6d8d84b1c7393cda612411773c49bafda9861 100644 (file)
@@ -1,3 +1,8 @@
+2011-07-08  Jason Merrill  <jason@redhat.com>
+
+       PR c++/45603
+       * g++.dg/abi/guard3.C: New.
+
 2011-07-08  Julian Brown  <julian@codesourcery.com>
 
        * lib/target-supports.exp
diff --git a/gcc/testsuite/g++.dg/abi/guard3.C b/gcc/testsuite/g++.dg/abi/guard3.C
new file mode 100644 (file)
index 0000000..fd9d00e
--- /dev/null
@@ -0,0 +1,14 @@
+// PR c++/45603
+
+extern "C" int __cxa_guard_acquire();
+
+struct A
+{
+  ~A();
+};
+
+A* f()
+{
+  static A a;
+  return &a;
+}