This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Fix for PR c++/26195 (pragma interface)
- From: Zak Kipling <zak at transversal dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 13 Feb 2006 18:44:37 +0000
- Subject: Fix for PR c++/26195 (pragma interface)
This fixes PR26195: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26195
Briefly, in 4.x compilers, #pragma interface doesn't behave correctly if
you specify an explicit parameter that is different to the basename of
the file containing the directive. 3.3 and 3.4 compilers handle this
correctly.
This appears to be due to
(1) in handle_pragma_interface, get_fileinfo being passed the parameter
to the directive rather than input_filename -- causing the
interface_only flag to be set in a place where it will never be seen;
(2) in a number of places, lbasename being called on input_filename
before passing it to get_fileinfo -- causing like-named files in
different directories to share the same c_fileinfo struct.
Tested on i686-pc-linux-gnu as per the instructions at
http://gcc.gnu.org/contribute.html for changes to the C++ front-end
(gcc, libstdc++ and libjava rebuilt, no new failures from check-c++).
ChangeLog:
2006-01-13 Zak Kipling <zak@transversal.com>
PR c++/26195
* gcc/cp/decl.c (make_rtl_for_nonlocal_decl,
start_preparsed_function): don't use lbasename on
input_filename when calling get_fileinfo.
* gcc/cp/semantics.c (begin_class_definition): likewise.
* gcc/cp/lex.c (cxx_make_type): likewise.
(handle_pragma_interface): call get_fileinfo on input_filename,
not on the parameter to the directive.
* gcc/testsuite/g++.dg/ext/interface2.C,
gcc/testsuite/g++.dg/ext/interface2a.h,
gcc/testsuite/g++.dg/ext/interface2b.cc: test case for bug in
handle_pragma_interface.
* gcc/testsuite/g++.dg/ext/interface3/interface3a.C,
gcc/testsuite/g++.dg/ext/interface3/interface3b.C,
gcc/testsuite/g++.dg/ext/interface3/interface3a2.cc,
gcc/testsuite/g++.dg/ext/interface3/interface3b2.cc,
gcc/testsuite/g++.dg/ext/interface3/dir1/interface3.h,
gcc/testsuite/g++.dg/ext/interface3/dir2/interface3.h: test
case for bugs caused by use of lbasename.
Zak.
Index: gcc/testsuite/g++.dg/ext/interface2.C
===================================================================
--- gcc/testsuite/g++.dg/ext/interface2.C (revision 0)
+++ gcc/testsuite/g++.dg/ext/interface2.C (revision 0)
@@ -0,0 +1,7 @@
+// PR c++/26195
+// { dg-do link }
+// { dg-additional-sources "interface2b.cc" }
+// { dg-options "-fno-inline" }
+
+#pragma implementation "interface2-imaginary.h"
+#include "interface2a.h"
Index: gcc/testsuite/g++.dg/ext/interface3/dir1/interface3.h
===================================================================
--- gcc/testsuite/g++.dg/ext/interface3/dir1/interface3.h (revision 0)
+++ gcc/testsuite/g++.dg/ext/interface3/dir1/interface3.h (revision 0)
@@ -0,0 +1,6 @@
+// PR c++/26195
+#pragma interface "dir1/interface3.h"
+#include "../dir2/interface3.h"
+
+inline void f1() { }
+inline void f2() { }
Index: gcc/testsuite/g++.dg/ext/interface3/dir2/interface3.h
===================================================================
--- gcc/testsuite/g++.dg/ext/interface3/dir2/interface3.h (revision 0)
+++ gcc/testsuite/g++.dg/ext/interface3/dir2/interface3.h (revision 0)
@@ -0,0 +1,5 @@
+// PR c++/26195
+#pragma interface "dir2/interface3.h"
+
+inline void g1() { }
+inline void g2() { }
Index: gcc/testsuite/g++.dg/ext/interface3/interface3a.C
===================================================================
--- gcc/testsuite/g++.dg/ext/interface3/interface3a.C (revision 0)
+++ gcc/testsuite/g++.dg/ext/interface3/interface3a.C (revision 0)
@@ -0,0 +1,7 @@
+// PR c++/26195
+// { dg-do link }
+// { dg-additional-sources "interface3a2.cc" }
+// { dg-options "-I. -fno-inline" }
+
+#pragma implementation "dir1/interface3.cc"
+#include "dir1/interface3.h"
Index: gcc/testsuite/g++.dg/ext/interface3/interface3b.C
===================================================================
--- gcc/testsuite/g++.dg/ext/interface3/interface3b.C (revision 0)
+++ gcc/testsuite/g++.dg/ext/interface3/interface3b.C (revision 0)
@@ -0,0 +1,7 @@
+// PR c++/26195
+// { dg-do link }
+// { dg-additional-sources "interface3b2.cc" }
+// { dg-options "-fno-inline" }
+
+#pragma implementation "dir2/interface3.cc"
+#include "dir1/interface3.h"
Index: gcc/testsuite/g++.dg/ext/interface3/interface3a2.cc
===================================================================
--- gcc/testsuite/g++.dg/ext/interface3/interface3a2.cc (revision 0)
+++ gcc/testsuite/g++.dg/ext/interface3/interface3a2.cc (revision 0)
@@ -0,0 +1,9 @@
+// PR c++/26195
+extern void f1();
+extern void f2();
+
+int main()
+{
+ f1();
+ f2();
+}
Index: gcc/testsuite/g++.dg/ext/interface3/interface3b2.cc
===================================================================
--- gcc/testsuite/g++.dg/ext/interface3/interface3b2.cc (revision 0)
+++ gcc/testsuite/g++.dg/ext/interface3/interface3b2.cc (revision 0)
@@ -0,0 +1,9 @@
+// PR c++/26195
+extern void g1();
+extern void g2();
+
+int main()
+{
+ g1();
+ g2();
+}
Index: gcc/testsuite/g++.dg/ext/interface2a.h
===================================================================
--- gcc/testsuite/g++.dg/ext/interface2a.h (revision 0)
+++ gcc/testsuite/g++.dg/ext/interface2a.h (revision 0)
@@ -0,0 +1,5 @@
+// PR c++/26195
+#pragma interface "interface2-imaginary.h"
+
+inline void foo1() { }
+inline void foo2() { }
Index: gcc/testsuite/g++.dg/ext/interface2b.cc
===================================================================
--- gcc/testsuite/g++.dg/ext/interface2b.cc (revision 0)
+++ gcc/testsuite/g++.dg/ext/interface2b.cc (revision 0)
@@ -0,0 +1,9 @@
+// PR c++/26195
+extern void foo1();
+extern void foo2();
+
+int main()
+{
+ foo1();
+ foo2();
+}
Index: gcc/cp/decl.c
===================================================================
--- gcc/cp/decl.c (revision 110544)
+++ gcc/cp/decl.c (working copy)
@@ -4752,7 +4752,7 @@ make_rtl_for_nonlocal_decl (tree decl, t
{
/* Fool with the linkage of static consts according to #pragma
interface. */
- struct c_fileinfo *finfo = get_fileinfo (lbasename (filename));
+ struct c_fileinfo *finfo = get_fileinfo (filename);
if (!finfo->interface_unknown && !TREE_PUBLIC (decl))
{
TREE_PUBLIC (decl) = 1;
@@ -10118,7 +10118,7 @@ start_preparsed_function (tree decl1, tr
struct cp_binding_level *bl;
tree current_function_parms;
struct c_fileinfo *finfo
- = get_fileinfo (lbasename (LOCATION_FILE (DECL_SOURCE_LOCATION (decl1))));
+ = get_fileinfo (LOCATION_FILE (DECL_SOURCE_LOCATION (decl1)));
bool honor_interface;
/* Sanity check. */
Index: gcc/cp/semantics.c
===================================================================
--- gcc/cp/semantics.c (revision 110544)
+++ gcc/cp/semantics.c (working copy)
@@ -2178,7 +2178,7 @@ begin_class_definition (tree t)
before. */
if (! TYPE_ANONYMOUS_P (t))
{
- struct c_fileinfo *finfo = get_fileinfo (lbasename (input_filename));
+ struct c_fileinfo *finfo = get_fileinfo (input_filename);
CLASSTYPE_INTERFACE_ONLY (t) = finfo->interface_only;
SET_CLASSTYPE_INTERFACE_UNKNOWN_X
(t, finfo->interface_unknown);
Index: gcc/cp/lex.c
===================================================================
--- gcc/cp/lex.c (revision 110544)
+++ gcc/cp/lex.c (working copy)
@@ -504,7 +504,7 @@ handle_pragma_interface (cpp_reader* dfi
else
filename = ggc_strdup (TREE_STRING_POINTER (fname));
- finfo = get_fileinfo (filename);
+ finfo = get_fileinfo (input_filename);
if (impl_file_chain == 0)
{
@@ -810,7 +810,7 @@ cxx_make_type (enum tree_code code)
/* Set up some flags that give proper default behavior. */
if (IS_AGGR_TYPE_CODE (code))
{
- struct c_fileinfo *finfo = get_fileinfo (lbasename (input_filename));
+ struct c_fileinfo *finfo = get_fileinfo (input_filename);
SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, finfo->interface_unknown);
CLASSTYPE_INTERFACE_ONLY (t) = finfo->interface_only;
}