+2002-05-26 Richard Henderson <rth@redhat.com>
+
+ 2002-05-25 Richard Henderson <rth@redhat.com>
+ * c-pragma.c (apply_pragma_weak): Convert value identifier to
+ string for decl_attributes.
+ (handle_pragma_weak): Call assemble_alias if we're modifying
+ an existing decl.
+
+ 2002-05-15 Richard Henderson <rth@redhat.com>
+ * varasm.c (merge_weak): Remove special case for extern and common.
+
+ 2002-05-15 Richard Henderson <rth@redhat.com>
+ * varasm.c (merge_weak): Error for any weakening after definition.
+ Adjust weakening after use warning to catch more cases.
+ (assemble_alias): Set TREE_USED and TREE_ASM_WRITTEN consistently.
+ * config/alpha/alpha.c (alpha_encode_section_info): Do not abort.
+
+ 2002-03-02 Richard Henderson <rth@redhat.com>
+ * attribs.c (handle_alias_attribute): Don't call assemble_alias.
+ * toplev.c (rest_of_decl_compilation): Invoke assemble_alias when
+ needed.
+
2002-05-26 Jakub Jelinek <jakub@redhat.com>
* cse.c (fold_rtx): Don't optimize if SUBREG changes mode class.
DECL_INITIAL (decl) = error_mark_node;
else
DECL_EXTERNAL (decl) = 0;
- assemble_alias (decl, id);
}
else
{
tree decl, value;
{
if (value)
- decl_attributes (&decl, build_tree_list (get_identifier ("alias"),
- build_tree_list (NULL, value)),
- 0);
+ {
+ value = build_string (IDENTIFIER_LENGTH (value),
+ IDENTIFIER_POINTER (value));
+ decl_attributes (&decl, build_tree_list (get_identifier ("alias"),
+ build_tree_list (NULL, value)),
+ 0);
+ }
+
if (SUPPORTS_WEAK && DECL_EXTERNAL (decl) && TREE_USED (decl)
&& TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
warning_with_decl (decl, "applying #pragma weak `%s' after first use results in unspecified behavior");
decl = identifier_global_value (name);
if (decl && TREE_CODE_CLASS (TREE_CODE (decl)) == 'd')
- apply_pragma_weak (decl, value);
+ {
+ apply_pragma_weak (decl, value);
+ if (value)
+ assemble_alias (decl, value);
+ }
else
pending_weaks = tree_cons (name, value, pending_weaks);
}
XSTR (XEXP (DECL_RTL (decl), 0), 0) = string;
}
else if (symbol_str[0] == '@')
- abort ();
+ {
+ /* We're hosed. This can happen when the user adds a weak
+ attribute after rtl generation. They should have gotten
+ a warning about unspecified behaviour from varasm.c. */
+ }
}
/* legitimate_address_p recognizes an RTL expression that is a valid
/* { dg-final { if [string match h8300-*-hms $target_triplet ] {return} } } */
/* { dg-final { if [string match i?86-pc-cygwin $target_triplet ] {return} } } */
/* { dg-final { if [string match *-*-coff $target_triplet ] {return} } } */
-/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1a" } } */
-/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1b" } } */
-/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1c" } } */
-/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1d" } } */
-/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1e" } } */
-/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1f" } } */
-/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1g" } } */
-/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1h" } } */
-/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1i" } } */
-/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1j" } } */
-/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1k" } } */
-/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1l" } } */
+/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?vfoo1a" } } */
+/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?vfoo1b" } } */
+/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?vfoo1c" } } */
+/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?vfoo1d" } } */
+/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?vfoo1e" } } */
+/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?vfoo1f" } } */
+/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?vfoo1g" } } */
+/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?vfoo1h" } } */
+/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?vfoo1i" } } */
+/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?vfoo1j" } } */
+/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?vfoo1k" } } */
+/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?vfoo1l" } } */
/* test variable addresses with __attribute__ ((weak)) */
{
return (void *)&vfoo1c;
}
-extern int vfoo1c __attribute__((weak)); /* { dg-warning "weak declaration" "weak declaration" } */
+extern int vfoo1c __attribute__((weak)); /* { dg-warning "unspecified behavior" } */
extern int vfoo1d __attribute__((weak));
{
return (void *)&vfoo1f;
}
-extern int vfoo1f __attribute__((weak));
+extern int vfoo1f __attribute__((weak)); /* { dg-warning "unspecified behavior" } */
extern int vfoo1g;
{
return (void *)&vfoo1g;
}
-int vfoo1g __attribute__((weak));
+int vfoo1g __attribute__((weak)); /* { dg-warning "unspecified behavior" } */
extern int vfoo1h __attribute__((weak));
int vfoox1l = 1;
-extern int vfoo1l __attribute__((alias ("vfoox1l")));
extern int vfoo1l __attribute__((weak, alias ("vfoox1l")));
-
#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP, END)
#endif
+ /* We deferred calling assemble_alias so that we could collect
+ other attributes such as visibility. Emit the alias now. */
+ {
+ tree alias;
+ alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl));
+ if (alias)
+ {
+ alias = TREE_VALUE (TREE_VALUE (alias));
+ alias = get_identifier (TREE_STRING_POINTER (alias));
+ assemble_alias (decl, alias);
+ }
+ }
+
/* Forward declarations for nested functions are not "external",
but we need to treat them as if they were. */
if (TREE_STATIC (decl) || DECL_EXTERNAL (decl)
if (DECL_WEAK (newdecl) == DECL_WEAK (olddecl))
return;
- if (SUPPORTS_WEAK
- && DECL_WEAK (newdecl)
- && DECL_EXTERNAL (newdecl) && DECL_EXTERNAL (olddecl)
- && (TREE_CODE (olddecl) != VAR_DECL || ! TREE_STATIC (olddecl))
- && TREE_USED (olddecl)
- && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (olddecl)))
- warning_with_decl (newdecl, "weak declaration of `%s' after first use results in unspecified behavior");
-
if (DECL_WEAK (newdecl))
{
tree wd;
go back and make it weak. This error cannot caught in
declare_weak because the NEWDECL and OLDDECL was not yet
been merged; therefore, TREE_ASM_WRITTEN was not set. */
- if (TREE_CODE (olddecl) == FUNCTION_DECL && TREE_ASM_WRITTEN (olddecl))
+ if (TREE_ASM_WRITTEN (olddecl))
error_with_decl (newdecl,
"weak declaration of `%s' must precede definition");
-
+
+ /* If we've already generated rtl referencing OLDDECL, we may
+ have done so in a way that will not function properly with
+ a weak symbol. */
+ else if (TREE_USED (olddecl)
+ && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (olddecl)))
+ warning_with_decl (newdecl, "weak declaration of `%s' after first use results in unspecified behavior");
+
if (SUPPORTS_WEAK)
{
/* We put the NEWDECL on the weak_decls list at some point.
#else
ASM_OUTPUT_DEF (asm_out_file, name, IDENTIFIER_POINTER (target));
#endif
- TREE_ASM_WRITTEN (decl) = 1;
#else /* !ASM_OUTPUT_DEF */
#if defined (ASM_OUTPUT_WEAK_ALIAS) || defined (ASM_WEAKEN_DECL)
if (! DECL_WEAK (decl))
#else
ASM_OUTPUT_WEAK_ALIAS (asm_out_file, name, IDENTIFIER_POINTER (target));
#endif
- TREE_ASM_WRITTEN (decl) = 1;
#else
warning ("alias definitions not supported in this configuration; ignored");
#endif
#endif
+
+ TREE_USED (decl) = 1;
+ TREE_ASM_WRITTEN (decl) = 1;
+ TREE_ASM_WRITTEN (DECL_ASSEMBLER_NAME (decl)) = 1;
}
/* Returns 1 if the target configuration supports defining public symbols