This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Patch: push_cfun -vs- in_system_header
- From: Tom Tromey <tromey at redhat dot com>
- To: Gcc Patch List <gcc-patches at gcc dot gnu dot org>
- Date: Mon, 05 Nov 2007 07:58:58 -0700
- Subject: Patch: push_cfun -vs- in_system_header
- Reply-to: Tom Tromey <tromey at redhat dot com>
This patch fixes PRs c++/32256 and c++/32368. But, despite their
names, I think they are not C++ bugs per se, but rather a general
problem in the middle end.
The bug is that when a function is analyzed, in_system_header is not
properly set. This leads gcc to emit warnings which should not be
emitted. This can happen if, e.g., cgraph defers processing a
function in unit-at-a-time mode.
My fix is to save and restore in_system_header in push_cfun and
pop_cfun. I think this is safe because these are used pairwise to
wrap code that should be run in the context of a particular function;
so using the function's notion of in_system_header here seems correct.
I tried instrumenting set_cfun instead, but that didn't work out. It
is used in strange and unconstrained ways. (Maybe it would be nice to
get rid of this. And, FWIW, I noticed a couple places that still
assign directly to cfun... maybe we should make it a compile-time
error to use cfun as an lvalue?)
Bootstrapped and regtested on x86 FC-6. Two new test cases included.
Ok?
Tom
:ADDPATCH middle-end:
ChangeLog:
2007-11-05 Tom Tromey <tromey@redhat.com>
PR c++/32256, PR c++/32368:
* function.c (saved_in_system_header): New global.
(push_cfun): Save in_system_header.
(pop_cfun): Restore in_system_header.
(push_struct_function): Save in_system_header.
testsuite/ChangeLog:
2007-11-05 Tom Tromey <tromey@redhat.com>
PR c++/32368:
* g++.dg/warn/pragma-system_header3.h: New.
* g++.dg/warn/pragma-system_header3.C: New.
PR c++/32256:
* g++.dg/warn/pragma-system_header4.C: New.
* g++.dg/warn/pragma-system_header4.h: New.
Index: function.c
===================================================================
--- function.c (revision 129850)
+++ function.c (working copy)
@@ -3834,12 +3834,22 @@
static VEC(function_p,heap) *cfun_stack;
+/* We save the value of in_system_header here when pushing the first
+ function on the cfun stack, and we restore it from here when
+ popping the last function. */
+
+static bool saved_in_system_header;
+
/* Push the current cfun onto the stack, and set cfun to new_cfun. */
void
push_cfun (struct function *new_cfun)
{
+ if (cfun == NULL)
+ saved_in_system_header = in_system_header;
VEC_safe_push (function_p, heap, cfun_stack, cfun);
+ if (new_cfun)
+ in_system_header = DECL_IN_SYSTEM_HEADER (new_cfun->decl);
set_cfun (new_cfun);
}
@@ -3848,7 +3858,10 @@
void
pop_cfun (void)
{
- set_cfun (VEC_pop (function_p, cfun_stack));
+ struct function *new_cfun = VEC_pop (function_p, cfun_stack);
+ in_system_header = ((new_cfun == NULL) ? saved_in_system_header
+ : DECL_IN_SYSTEM_HEADER (new_cfun->decl));
+ set_cfun (new_cfun);
}
/* Return value of funcdef and increase it. */
@@ -3922,7 +3935,11 @@
void
push_struct_function (tree fndecl)
{
+ if (cfun == NULL)
+ saved_in_system_header = in_system_header;
VEC_safe_push (function_p, heap, cfun_stack, cfun);
+ if (fndecl)
+ in_system_header = DECL_IN_SYSTEM_HEADER (fndecl);
allocate_struct_function (fndecl);
}
Index: testsuite/g++.dg/warn/pragma-system_header3.C
===================================================================
--- testsuite/g++.dg/warn/pragma-system_header3.C (revision 0)
+++ testsuite/g++.dg/warn/pragma-system_header3.C (revision 0)
@@ -0,0 +1,9 @@
+// PR c++/32368
+// { dg-options "-Wall -O" }
+
+#include "pragma-system_header3.h"
+
+int main()
+{
+ return f();
+}
Index: testsuite/g++.dg/warn/pragma-system_header3.h
===================================================================
--- testsuite/g++.dg/warn/pragma-system_header3.h (revision 0)
+++ testsuite/g++.dg/warn/pragma-system_header3.h (revision 0)
@@ -0,0 +1,7 @@
+#pragma GCC system_header
+
+static inline int f()
+{
+ int i;
+ return i;
+}
Index: testsuite/g++.dg/warn/pragma-system_header4.C
===================================================================
--- testsuite/g++.dg/warn/pragma-system_header4.C (revision 0)
+++ testsuite/g++.dg/warn/pragma-system_header4.C (revision 0)
@@ -0,0 +1,6 @@
+// PR c++/32256
+// { dg-options "-Wall" }
+
+#include "pragma-system_header4.h"
+
+void ok() { }
Index: testsuite/g++.dg/warn/pragma-system_header4.h
===================================================================
--- testsuite/g++.dg/warn/pragma-system_header4.h (revision 0)
+++ testsuite/g++.dg/warn/pragma-system_header4.h (revision 0)
@@ -0,0 +1,2 @@
+#pragma GCC system_header
+int noreturn() { }