From 2ef06beb77833e951ce436d9b0b954090e4248b6 Mon Sep 17 00:00:00 2001
From: Mark Mitchell <mark@codesourcery.com>
Date: Sat, 28 Jan 2006 22:11:42 +0000
Subject: [PATCH] re PR c++/25999 (compiler loses extern "C" for function after
 #pragma weak)

	PR c++/25999
	* decl.c (start_preparsed_function): Call maybe_apply_pragma_weak
	here, not ...
	(start_function): ... here.
	PR c++/25999
	* g++.dg/ext/pragmaweak1.C: New test.

From-SVN: r110340
---
 gcc/cp/ChangeLog                       |  7 +++++++
 gcc/cp/decl.c                          | 15 +++++++++++----
 gcc/testsuite/ChangeLog                |  5 +++++
 gcc/testsuite/g++.dg/ext/pragmaweak1.C |  9 +++++++++
 4 files changed, 32 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/pragmaweak1.C

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index ad3be507d4ec..107187937331 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2006-01-28  Mark Mitchell  <mark@codesourcery.com>
+
+	PR c++/25999
+	* decl.c (start_preparsed_function): Call maybe_apply_pragma_weak
+	here, not ...
+	(start_function): ... here.
+
 2006-01-28  Mark Mitchell  <mark@codesourcery.com>
 
 	PR c++/25855
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index e4be9e0f88c7..ef7ed3a4fcdc 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -10287,6 +10287,17 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
 	    DECL_CONTEXT (decl1) = DECL_CONTEXT (DECL_TI_TEMPLATE (decl1));
 	}
       fntype = TREE_TYPE (decl1);
+
+      /* If #pragma weak applies, mark the decl appropriately now.
+	 The pragma only applies to global functions.  Because
+	 determining whether or not the #pragma applies involves
+	 computing the mangled name for the declaration, we cannot
+	 apply the pragma until after we have merged this declaration
+	 with any previous declarations; if the original declaration
+	 has a linkage specification, that specification applies to
+	 the definition as well, and may affect the mangled name.  */
+      if (!DECL_CONTEXT (decl1))
+	maybe_apply_pragma_weak (decl1);
     }
 
   /* Determine the ELF visibility attribute for the function.  We must
@@ -10458,10 +10469,6 @@ start_function (cp_decl_specifier_seq *declspecs,
   if (decl1 == NULL_TREE || TREE_CODE (decl1) != FUNCTION_DECL)
     return 0;
 
-  /* If #pragma weak was used, mark the decl weak now.  */
-  if (global_scope_p (current_binding_level))
-    maybe_apply_pragma_weak (decl1);
-
   if (DECL_MAIN_P (decl1))
     /* main must return int.  grokfndecl should have corrected it
        (and issued a diagnostic) if the user got it wrong.  */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 70b6deef740f..5b40db880e2d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2006-01-28  Mark Mitchell  <mark@codesourcery.com>
+
+	PR c++/25999
+	* g++.dg/ext/pragmaweak1.C: New test.
+
 2006-01-28  Mark Mitchell  <mark@codesourcery.com>
 
 	PR c++/25855
diff --git a/gcc/testsuite/g++.dg/ext/pragmaweak1.C b/gcc/testsuite/g++.dg/ext/pragmaweak1.C
new file mode 100644
index 000000000000..68bf3fce2ddb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/pragmaweak1.C
@@ -0,0 +1,9 @@
+// PR c++/25999
+// { dg-final { scan-assembler-not "_Z3Foov" } }
+
+extern "C" {
+  void Foo();
+}
+#pragma weak Random_Symbol
+void Foo() { }
+
-- 
GitLab