aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-common.c
diff options
context:
space:
mode:
authorAlexandre Oliva <aoliva@redhat.com>2005-11-09 20:13:41 +0000
committerAlexandre Oliva <aoliva@gcc.gnu.org>2005-11-09 20:13:41 +0000
commita0203ca711308b96d33acb895d4f7d254594287c (patch)
treecdc3a1f501856957bef831df0b91b2b381edd2b8 /gcc/c-common.c
parent317adebb1faac58d50f0e44906aa18edaf663759 (diff)
downloadgcc-a0203ca711308b96d33acb895d4f7d254594287c.zip
gcc-a0203ca711308b96d33acb895d4f7d254594287c.tar.gz
gcc-a0203ca711308b96d33acb895d4f7d254594287c.tar.bz2
re PR other/4372 (#pragma weak pthread* inclusion causes applications to crash without a linker error when one forgets to link with -lpthread)
PR other/4372 * tree.h (IDENTIFIER_TRANSPARENT_ALIAS): New. (TREE_DEPRECATED): Adjust comment. Check for a DECL. * c-common.c (handle_weakref_attribute): New. (c_common_attribute_table): Add weakref. * configure.ac (HAVE_GAS_WEAKREF): Check for weakref support in the assembler. * configure, config.in: Rebuilt. * defaults.h (ASM_OUTPUT_WEAKREF): Define if HAVE_GAS_WEAKREF. * doc/extend.texi: Document weakref attribute. * varasm.c (ultimate_transparent_alias_target): New (assemble_name): Use it. (weak_finish_1): Split out of... (weak_finish): ... and deal with weakrefs in... (weakref_targets): ... new list. (globalize_decl): Clean up weakref_targets. (do_assemble_alias): Handle weakrefs. (finish_aliases_1): Do not reject weakrefs to external symbols. (assemble_alias): Handle weakrefs. From-SVN: r106703
Diffstat (limited to 'gcc/c-common.c')
-rw-r--r--gcc/c-common.c42
1 files changed, 41 insertions, 1 deletions
diff --git a/gcc/c-common.c b/gcc/c-common.c
index abd33d2..4501841 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -520,6 +520,7 @@ static tree handle_section_attribute (tree *, tree, tree, int, bool *);
static tree handle_aligned_attribute (tree *, tree, tree, int, bool *);
static tree handle_weak_attribute (tree *, tree, tree, int, bool *) ;
static tree handle_alias_attribute (tree *, tree, tree, int, bool *);
+static tree handle_weakref_attribute (tree *, tree, tree, int, bool *) ;
static tree handle_visibility_attribute (tree *, tree, tree, int,
bool *);
static tree handle_tls_model_attribute (tree *, tree, tree, int,
@@ -599,6 +600,8 @@ const struct attribute_spec c_common_attribute_table[] =
handle_weak_attribute },
{ "alias", 1, 1, true, false, false,
handle_alias_attribute },
+ { "weakref", 0, 1, true, false, false,
+ handle_weakref_attribute },
{ "no_instrument_function", 0, 0, true, false, false,
handle_no_instrument_function_attribute },
{ "malloc", 0, 0, true, false, false,
@@ -4742,7 +4745,10 @@ handle_alias_attribute (tree *node, tree name, tree args,
DECL_INITIAL (decl) = error_mark_node;
else
{
- DECL_EXTERNAL (decl) = 0;
+ if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl)))
+ DECL_EXTERNAL (decl) = 1;
+ else
+ DECL_EXTERNAL (decl) = 0;
TREE_STATIC (decl) = 1;
}
}
@@ -4755,6 +4761,40 @@ handle_alias_attribute (tree *node, tree name, tree args,
return NULL_TREE;
}
+/* Handle a "weakref" attribute; arguments as in struct
+ attribute_spec.handler. */
+
+static tree
+handle_weakref_attribute (tree *node, tree ARG_UNUSED (name), tree args,
+ int flags, bool *no_add_attrs)
+{
+ tree attr = NULL_TREE;
+
+ /* The idea here is that `weakref("name")' mutates into `weakref,
+ alias("name")', and weakref without arguments, in turn,
+ implicitly adds weak. */
+
+ if (args)
+ {
+ attr = tree_cons (get_identifier ("alias"), args, attr);
+ attr = tree_cons (get_identifier ("weakref"), NULL_TREE, attr);
+
+ *no_add_attrs = true;
+ }
+ else
+ {
+ if (lookup_attribute ("alias", DECL_ATTRIBUTES (*node)))
+ error ("%Jweakref attribute must appear before alias attribute",
+ *node);
+
+ attr = tree_cons (get_identifier ("weak"), NULL_TREE, attr);
+ }
+
+ decl_attributes (node, attr, flags);
+
+ return NULL_TREE;
+}
+
/* Handle an "visibility" attribute; arguments as in
struct attribute_spec.handler. */