[C PATCH] Reject weak nested functions (PR c/89340)

Jakub Jelinek jakub@redhat.com
Thu Feb 14 23:00:00 GMT 2019


Hi!

We ICE on the following testcase, because C nested functions are turned into
!TREE_PUBLIC ones very soon,  and the IPA code asserts that DECL_WEAK functions
are either TREE_PUBLIC or DECL_EXTERNAL.
As we reject static __attribute__((weak)) void foo () {}, I think we should
reject weak nested functions, they don't make much sense either, they are
TU local too.

The following patch fixes that.  The other effect of the patch is that leaf
attribute is warned and ignored on the nested function, but similarly, we
ignore and warn for leaf attribute on other TU local functions, we see the
nested function body and can analyze everything in it.

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

2019-02-14  Jakub Jelinek  <jakub@redhat.com>

	PR c/89340
	* c-decl.c (start_function): Clear TREE_PUBLIC on nested functions
	before c_decl_attributes rather than after it.

	* gcc.dg/pr89340.c: New test.
	* gcc.dg/torture/pr57036-2.c (jpgDecode_convert): Expect a warning
	that leaf attribute on nested function is useless.

--- gcc/c/c-decl.c.jj	2019-02-06 09:53:49.000000000 +0100
+++ gcc/c/c-decl.c	2019-02-14 14:03:23.630109817 +0100
@@ -8904,6 +8904,10 @@ start_function (struct c_declspecs *decl
 
   loc = DECL_SOURCE_LOCATION (decl1);
 
+  /* A nested function is not global.  */
+  if (current_function_decl != NULL_TREE)
+    TREE_PUBLIC (decl1) = 0;
+
   c_decl_attributes (&decl1, attributes, 0);
 
   if (DECL_DECLARED_INLINE_P (decl1)
@@ -8945,10 +8949,6 @@ start_function (struct c_declspecs *decl
      error_mark_node is replaced below (in pop_scope) with the BLOCK.  */
   DECL_INITIAL (decl1) = error_mark_node;
 
-  /* A nested function is not global.  */
-  if (current_function_decl != NULL_TREE)
-    TREE_PUBLIC (decl1) = 0;
-
   /* If this definition isn't a prototype and we had a prototype declaration
      before, copy the arg type info from that prototype.  */
   old_decl = lookup_name_in_scope (DECL_NAME (decl1), current_scope);
--- gcc/testsuite/gcc.dg/pr89340.c.jj	2019-02-14 14:16:35.998034363 +0100
+++ gcc/testsuite/gcc.dg/pr89340.c	2019-02-14 14:10:31.936033775 +0100
@@ -0,0 +1,9 @@
+/* PR c/89340 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+void bar (void)
+{
+  __attribute__((weak)) void foo () {}	/* { dg-error "weak declaration of 'foo' must be public" } */
+  foo ();
+}
--- gcc/testsuite/gcc.dg/torture/pr57036-2.c.jj	2014-11-11 00:06:07.247079690 +0100
+++ gcc/testsuite/gcc.dg/torture/pr57036-2.c	2019-02-14 22:04:04.936850407 +0100
@@ -9,7 +9,7 @@ int jpgDecode_convert (unsigned i)
   int j;
 
   inline void __attribute__((always_inline,leaf)) f(void)
-    {
+    {		/* { dg-warning "'leaf' attribute has no effect" } */
       g();
     }
 

	Jakub



More information about the Gcc-patches mailing list