diff mbox

Fix up #pragma weak handling (PR middle-end/36282)

Message ID 20140313180042.GZ22862@tucnak.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek March 13, 2014, 6 p.m. UTC
Hi!

We get bogus warning on the -1 and -4 testcases.
The problem is that we accept without warning an __asm rename like:
extern void *baz (void *dest, const void *src, __SIZE_TYPE__ n);
extern __typeof (baz) baz __asm("bazfn");
only if it doesn't have DECL_ASSEMBLER_NAME_SET_P yet, after it is
set we just warn and ignore the rename.

But for #pragma weak, if there are any pending #pragma weak pragmas,
we actually set DECL_ASSEMBLER_NAME right away.

Fixed by computing DECL_ASSEMBLER_NAME for the #pragma weak handling
just temporarily if it hasn't been set yet (yeah, it is duplicate work then,
but hopefully not very common), plus also fixing the early outs
- if a decl matching some #pragma weak is found, that vector entry is
removed from pending_weaks, but we were only testing if pending_weaks is
NULL, which it will never be after it has been allocated once.
Thus, for the most common case (well, most code doesn't use #pragma weak at
all) where you have #pragma weak followed by corresponding prototype or
say a couple of #pragma weak directives followed by corresponding
prototypes, there should be either no or just very small amount of extra
decl_assembler_name invocations.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2014-03-13  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/36282
	* c-pragma.c (apply_pragma_weak): Only look at
	TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)) if
	DECL_ASSEMBLER_NAME_SET_P (decl).
	(maybe_apply_pending_pragma_weaks): Exit early if
	vec_safe_is_empty (pending_weaks) rather than only when
	!pending_weaks.
	(maybe_apply_pragma_weak): Likewise.  If !DECL_ASSEMBLER_NAME_SET_P,
	set assembler name back to NULL afterwards.

	* c-c++-common/pr36282-1.c: New test.
	* c-c++-common/pr36282-2.c: New test.
	* c-c++-common/pr36282-3.c: New test.
	* c-c++-common/pr36282-4.c: New test.


	Jakub

Comments

Joseph Myers March 13, 2014, 8:53 p.m. UTC | #1
On Thu, 13 Mar 2014, Jakub Jelinek wrote:

> 2014-03-13  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR middle-end/36282
> 	* c-pragma.c (apply_pragma_weak): Only look at
> 	TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)) if
> 	DECL_ASSEMBLER_NAME_SET_P (decl).
> 	(maybe_apply_pending_pragma_weaks): Exit early if
> 	vec_safe_is_empty (pending_weaks) rather than only when
> 	!pending_weaks.
> 	(maybe_apply_pragma_weak): Likewise.  If !DECL_ASSEMBLER_NAME_SET_P,
> 	set assembler name back to NULL afterwards.
> 
> 	* c-c++-common/pr36282-1.c: New test.
> 	* c-c++-common/pr36282-2.c: New test.
> 	* c-c++-common/pr36282-3.c: New test.
> 	* c-c++-common/pr36282-4.c: New test.

OK.
diff mbox

Patch

--- gcc/c-family/c-pragma.c.jj	2014-03-06 13:05:17.000000000 +0100
+++ gcc/c-family/c-pragma.c	2014-03-13 14:39:44.200586561 +0100
@@ -263,6 +263,7 @@  apply_pragma_weak (tree decl, tree value
 
   if (SUPPORTS_WEAK && DECL_EXTERNAL (decl) && TREE_USED (decl)
       && !DECL_WEAK (decl) /* Don't complain about a redundant #pragma.  */
+      && DECL_ASSEMBLER_NAME_SET_P (decl)
       && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
     warning (OPT_Wpragmas, "applying #pragma weak %q+D after first use "
 	     "results in unspecified behavior", decl);
@@ -280,7 +281,7 @@  maybe_apply_pragma_weak (tree decl)
   /* Avoid asking for DECL_ASSEMBLER_NAME when it's not needed.  */
 
   /* No weak symbols pending, take the short-cut.  */
-  if (!pending_weaks)
+  if (vec_safe_is_empty (pending_weaks))
     return;
   /* If it's not visible outside this file, it doesn't matter whether
      it's weak.  */
@@ -292,7 +293,13 @@  maybe_apply_pragma_weak (tree decl)
   if (TREE_CODE (decl) != FUNCTION_DECL && TREE_CODE (decl) != VAR_DECL)
     return;
 
-  id = DECL_ASSEMBLER_NAME (decl);
+  if (DECL_ASSEMBLER_NAME_SET_P (decl))
+    id = DECL_ASSEMBLER_NAME (decl);
+  else
+    {
+      id = DECL_ASSEMBLER_NAME (decl);
+      SET_DECL_ASSEMBLER_NAME (decl, NULL_TREE);
+    }
 
   FOR_EACH_VEC_ELT (*pending_weaks, i, pe)
     if (id == pe->name)
@@ -313,7 +320,7 @@  maybe_apply_pending_pragma_weaks (void)
   pending_weak *pe;
   symtab_node *target;
 
-  if (!pending_weaks)
+  if (vec_safe_is_empty (pending_weaks))
     return;
 
   FOR_EACH_VEC_ELT (*pending_weaks, i, pe)
--- gcc/testsuite/c-c++-common/pr36282-1.c.jj	2014-03-13 14:31:03.752580696 +0100
+++ gcc/testsuite/c-c++-common/pr36282-1.c	2014-03-13 14:31:56.110270219 +0100
@@ -0,0 +1,12 @@ 
+/* PR middle-end/36282 */
+/* { dg-do compile } */
+
+#pragma weak bar
+
+extern void *baz (void *dest, const void *src, __SIZE_TYPE__ n);
+extern __typeof (baz) baz __asm("bazfn"); /* { dg-bogus "asm declaration ignored due to conflict with previous rename" } */
+
+void
+foo (void)
+{
+}
--- gcc/testsuite/c-c++-common/pr36282-2.c.jj	2014-03-13 14:31:03.752580696 +0100
+++ gcc/testsuite/c-c++-common/pr36282-2.c	2014-03-13 14:32:01.264247933 +0100
@@ -0,0 +1,10 @@ 
+/* PR middle-end/36282 */
+/* { dg-do compile } */
+
+extern void *baz (void *dest, const void *src, __SIZE_TYPE__ n);
+extern __typeof (baz) baz __asm("bazfn"); /* { dg-bogus "asm declaration ignored due to conflict with previous rename" } */
+
+void
+foo (void)
+{
+}
--- gcc/testsuite/c-c++-common/pr36282-3.c.jj	2014-03-13 14:31:03.752580696 +0100
+++ gcc/testsuite/c-c++-common/pr36282-3.c	2014-03-13 14:32:07.243209260 +0100
@@ -0,0 +1,13 @@ 
+/* PR middle-end/36282 */
+/* { dg-do compile } */
+
+void bar (void);
+#pragma weak bar
+
+extern void *baz (void *dest, const void *src, __SIZE_TYPE__ n);
+extern __typeof (baz) baz __asm("bazfn"); /* { dg-bogus "asm declaration ignored due to conflict with previous rename" } */
+
+void
+foo (void)
+{
+}
--- gcc/testsuite/c-c++-common/pr36282-4.c.jj	2014-03-13 14:31:03.752580696 +0100
+++ gcc/testsuite/c-c++-common/pr36282-4.c	2014-03-13 14:32:12.831177682 +0100
@@ -0,0 +1,13 @@ 
+/* PR middle-end/36282 */
+/* { dg-do compile } */
+
+#pragma weak bar
+void bar (void);
+
+extern void *baz (void *dest, const void *src, __SIZE_TYPE__ n);
+extern __typeof (baz) baz __asm("bazfn"); /* { dg-bogus "asm declaration ignored due to conflict with previous rename" } */
+
+void
+foo (void)
+{
+}