This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix PR c++/14962


Hi,

This is a regression that has been present since GCC 3.1 on Solaris-based
platforms: #pragma redefine_extname doesn't work under certain circumstances 
with the C++ compiler, while it does with the C compiler.  This is annoying 
because the circumstances at stake occur for the large file support in the 
Solaris system headers.

The situation is as follows:

extern "C" {

struct old_name { int i; };

#pragma redefine_extname old_name new_name

int old_name(void);

}

References to the function 'old_name' are still emitted as 'old_name' in the 
assembly file, while they should be emitted as 'new_name', like with the C 
compiler.

The problem is in c-pragma.c:handle_pragma_redefine_extname

  decl = identifier_global_value (oldname);
  if (decl && TREE_CODE_CLASS (TREE_CODE (decl)) == 'd')
    {
      if (DECL_ASSEMBLER_NAME_SET_P (decl)
	  && DECL_ASSEMBLER_NAME (decl) != newname)
        warning ("#pragma redefine_extname conflicts with declaration");
      change_decl_assembler_name (decl, newname);
    }
  else
    add_to_renaming_pragma_list(oldname, newname);

Because of the 'struct old_name' definition, 'oldname' already exists when 
the pragma is parsed and is a tag for the C compiler and a type for the C++ 
compiler.

In the first case (C compiler), identifier_global_value returns 0 so 
add_to_renaming_pragma_list is invoked and all works fine.  In the second 
case, identifier_global_value returns a TYPE_DECL, which means the condition 
is true and add_to_renaming_pragma_list is not invoked.

The proposed fix is to restrict the condition to the DECLs that have an 
assembler name.  See the patch for the list.  Bootstrapped/regtested 
(mainline) on SPARC/Solaris 2.5.1, 2.6, 7, 8 and 9.

OK for mainline and 3.4 branch?


2004-05-05  Eric Botcazou  <ebotcazou@libertysurf.fr>

	PR c++/14962
	* c-pragma.c (handle_pragma_redefine_extname): Only change
	the assembler name of DECLs that have one.


2004-05-05  Eric Botcazou  <ebotcazou@libertysurf.fr>

	* g++.dg/other/pragma-re-2.C: New test.


-- 
Eric Botcazou
Index: c-pragma.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-pragma.c,v
retrieving revision 1.66.2.1
diff -u -p -r1.66.2.1 c-pragma.c
--- c-pragma.c	23 Jan 2004 23:35:53 -0000	1.66.2.1
+++ c-pragma.c	4 May 2004 12:15:09 -0000
@@ -377,7 +377,10 @@ handle_pragma_redefine_extname (cpp_read
     warning ("junk at end of #pragma redefine_extname");
 
   decl = identifier_global_value (oldname);
-  if (decl && TREE_CODE_CLASS (TREE_CODE (decl)) == 'd')
+  if (decl && (TREE_CODE (decl) == FUNCTION_DECL
+	       || TREE_CODE (decl) == LABEL_DECL
+	       || TREE_CODE (decl) == CONST_DECL
+	       || TREE_CODE (decl) == VAR_DECL))
     {
       if (DECL_ASSEMBLER_NAME_SET_P (decl)
 	  && DECL_ASSEMBLER_NAME (decl) != newname)
/* PR c++/14962 */
/* Originator: <phil@fsel.com> */

/* { dg-do compile { target *-*-solaris* } } */
/* { dg-final { scan-assembler "new_name" } } */
/* { dg-final { scan-assembler-not "old_name" } } */

#ifndef __PRAGMA_REDEFINE_EXTNAME
#error 
#endif

extern "C" {

struct old_name { int i; };

#pragma redefine_extname old_name new_name

int old_name(void);

}

int foo(void)
{
  return old_name();
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]