This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: #pragma weak conformance
- To: Geoff Keating <geoffk at geoffk dot org>
- Subject: Re: #pragma weak conformance
- From: David Edelsohn <dje at watson dot ibm dot com>
- Date: Fri, 02 Nov 2001 17:30:55 -0500
- cc: gcc at gcc dot gnu dot org
>>>>> Geoff Keating writes:
Geoff> I believe that GCC is trying to conform to the union of all the
Geoff> implementations out there. '#pragma weak' is only for compatibility
Geoff> with other implementations, so it should try to be compatible with as
Geoff> many other implementations as possible :-).
The problem is:
#pragma weak foo=bar
as opposed to
extern bar __attribute__ ((weak, alias ("foo")))
The former calls ASM_OUTPUT_WEAK_ALIAS from weak_finish() while
the latter calls ASM_OUTPUT_DEF_FROM_DECLS from assemble_weak(). Not
calling ASM_OUTPUT_DEF_FROM_DECLS means that some additional machinery
necessary for a weak function may not be invokved. The pragma case does
not have any associated DECL.
The Solaris semantics require that an alias of an identifier match
a declaration. Is there any way to find the GCC declaration associated
with an identifier?
What I am proposing is something along the lines of the following
patch. The main piece missing is that I am calling declare_weak with an
identifier tree structure instead of a decl tree structure.
Thanks, David
Index: c-pragma.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-pragma.c,v
retrieving revision 1.45
diff -c -p -r1.45 c-pragma.c
*** c-pragma.c 2001/08/31 19:27:12 1.45
--- c-pragma.c 2001/11/02 22:20:00
*************** handle_pragma_weak (dummy)
*** 282,304 ****
cpp_reader *dummy ATTRIBUTE_UNUSED;
{
tree name, value, x;
! enum cpp_ttype t;
value = 0;
! if (c_lex (&name) != CPP_NAME)
BAD ("malformed #pragma weak, ignored");
! t = c_lex (&x);
! if (t == CPP_EQ)
{
! if (c_lex (&value) != CPP_NAME)
BAD ("malformed #pragma weak, ignored");
! t = c_lex (&x);
}
! if (t != CPP_EOF)
warning ("junk at end of #pragma weak");
! add_weak (IDENTIFIER_POINTER (name), value ? IDENTIFIER_POINTER (value) : 0);
}
#endif
--- 282,318 ----
cpp_reader *dummy ATTRIBUTE_UNUSED;
{
tree name, value, x;
! enum cpp_ttype t_name, t_value, t_x;
value = 0;
! t_name = c_lex (&name);
!
! if (t_name != CPP_NAME && t_name != CPP_STRING)
BAD ("malformed #pragma weak, ignored");
! if (t_name == CPP_NAME && !DECL_P (name))
! BAD ("#pragma weak identifier not defined in compilation unit");
!
! t_x = c_lex (&x);
! if (t_x == CPP_EQ)
{
! t_value = c_lex (&value);
! /* Name and value must both be identifier or string. */
! if (t_value != CPP_NAME && t_value != CPP_STRING && t_value != t_name)
BAD ("malformed #pragma weak, ignored");
! if (t_value == CPP_NAME && !DECL_P (value))
! BAD ("#pragma weak identifier not defined in compilation unit");
!
! t_x = c_lex (&x);
}
! if (t_x != CPP_EOF)
warning ("junk at end of #pragma weak");
! if (t_name == CPP_NAME)
! declare_weak (name, value);
! else
! add_weak (IDENTIFIER_POINTER (name),
! value ? IDENTIFIER_POINTER (value) : 0);
}
#endif