This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Extend __attribute__((deprecated)) with an optional message
- From: "Andrew C. Morrow" <acm at google dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 14 Nov 2008 17:40:21 -0500
- Subject: [PATCH] Extend __attribute__((deprecated)) with an optional message
Hi -
The following patch extends __attribute__((deprecated)) with an
optional string to be emitted in the deprecation warning:
int foo __attribute__((deprecated("use new_foo")));
int bar = foo;
Will emit a warning like: warning: 'foo' is deprecated (declared at
...) with message 'use new_foo'
Thanks,
Andrew
2008-11-14 Andrew Morrow <acm@google.com>
* doc/extend.texi: Document new optional parameter to
__attribute__((deprecated))
* toplev.c (get_deprecation_message): New function.
* toplev.c (warn_deprecated_use): If a deprecation attribute has
an associated message, emit the message as part of the warning.
* c-common.c (c_common_attribute_table): Permit deprecated
attribute to take an optional argument.
* c-common.c (handle_deprecated_attribute): If the optional
argument to __attribute__((deprecated)) is not a string ignore the
attribute and emit a warning.
testsuite/ChangeLog
* gcc.dg/deprecated-4.c: New file.
Index: gcc/doc/extend.texi
===================================================================
--- gcc/doc/extend.texi (revision 141865)
+++ gcc/doc/extend.texi (working copy)
@@ -2036,6 +2036,7 @@ objects (@pxref{C++ Attributes}).
These attributes are not currently implemented for Objective-C@.
@item deprecated
+@itemx deprecated (@var{msg})
@cindex @code{deprecated} attribute.
The @code{deprecated} attribute results in a warning if the function
is used anywhere in the source file. This is useful when identifying
@@ -2051,7 +2052,9 @@ int old_fn ();
int (*fn_ptr)() = old_fn;
@end smallexample
-results in a warning on line 3 but not line 2.
+results in a warning on line 3 but not line 2. The optional msg
+argument, which must be a string, will be printed in the warning if
+present.
The @code{deprecated} attribute can also be used for variables and
types (@pxref{Variable Attributes}, @pxref{Type Attributes}.)
@@ -3761,6 +3764,7 @@ These attributes override the default ch
@option{-fno-common} and @option{-fcommon} flags respectively.
@item deprecated
+@itemx deprecated (@var{msg})
@cindex @code{deprecated} attribute
The @code{deprecated} attribute results in a warning if the variable
is used anywhere in the source file. This is useful when identifying
@@ -3776,7 +3780,9 @@ extern int old_var;
int new_fn () @{ return old_var; @}
@end smallexample
-results in a warning on line 3 but not line 2.
+results in a warning on line 3 but not line 2. The optional msg
+argument, which must be a string, will be printed in the warning if
+present.
The @code{deprecated} attribute can also be used for functions and
types (@pxref{Function Attributes}, @pxref{Type Attributes}.)
@@ -4399,6 +4405,7 @@ not referenced, but contain constructors
nontrivial bookkeeping functions.
@item deprecated
+@itemx deprecated (@var{msg})
The @code{deprecated} attribute results in a warning if the type
is used anywhere in the source file. This is useful when identifying
types that are expected to be removed in a future version of a program.
@@ -4421,7 +4428,9 @@ T3 z __attribute__ ((deprecated));
results in a warning on line 2 and 3 but not lines 4, 5, or 6. No
warning is issued for line 4 because T2 is not explicitly
deprecated. Line 5 has no warning because T3 is explicitly
-deprecated. Similarly for line 6.
+deprecated. Similarly for line 6. The optional msg
+argument, which must be a string, will be printed in the warning if
+present.
The @code{deprecated} attribute can also be used for functions and
variables (@pxref{Function Attributes}, @pxref{Variable Attributes}.)
Index: gcc/toplev.c
===================================================================
--- gcc/toplev.c (revision 141865)
+++ gcc/toplev.c (working copy)
@@ -895,19 +895,59 @@ emit_debug_global_declarations (tree *ve
timevar_pop (TV_SYMOUT);
}
+/* If the given tree, which must be a decl or type, has an associated
+ deprecation attribute with a message, then return the message. */
+
+static const char *
+get_deprecation_message (tree node)
+{
+ tree attributes = NULL_TREE;
+ if (DECL_P (node))
+ attributes = DECL_ATTRIBUTES (node);
+ else if (TYPE_P (node))
+ attributes = TYPE_ATTRIBUTES (node);
+
+ if (attributes != NULL_TREE)
+ {
+ tree deprecation = lookup_attribute ("deprecated", attributes);
+ if (deprecation != NULL_TREE)
+ {
+ tree argument_list = TREE_VALUE (deprecation);
+ if (argument_list != NULL_TREE)
+ if (TREE_CODE (TREE_VALUE (argument_list)) == STRING_CST)
+ return TREE_STRING_POINTER (TREE_VALUE (argument_list));
+ }
+ }
+
+ return NULL;
+}
+
/* Warn about a use of an identifier which was marked deprecated. */
void
warn_deprecated_use (tree node)
{
+ char *deprecation_message = NULL;
+ const char *deprecation_arg = NULL;
+
if (node == 0 || !warn_deprecated_decl)
return;
+ /* If the deprecation has a message, construct a string containing
+ the message that we can emit as part of the warning. Otherwise,
+ build an empty string that we can print silently. */
+
+ if ((deprecation_arg = get_deprecation_message (node)) != NULL)
+ asprintf (&deprecation_message, " with message '%s'",
+ deprecation_arg);
+ else
+ deprecation_message = xstrdup ("");
+
if (DECL_P (node))
{
expanded_location xloc = expand_location (DECL_SOURCE_LOCATION (node));
warning (OPT_Wdeprecated_declarations,
- "%qD is deprecated (declared at %s:%d)",
- node, xloc.file, xloc.line);
+ "%qD is deprecated (declared at %s:%d)%s",
+ node, xloc.file, xloc.line, deprecation_message);
}
else if (TYPE_P (node))
{
@@ -929,21 +969,25 @@ warn_deprecated_use (tree node)
= expand_location (DECL_SOURCE_LOCATION (decl));
if (what)
warning (OPT_Wdeprecated_declarations,
- "%qs is deprecated (declared at %s:%d)", what,
- xloc.file, xloc.line);
+ "%qs is deprecated (declared at %s:%d)%s", what,
+ xloc.file, xloc.line, deprecation_message);
else
warning (OPT_Wdeprecated_declarations,
- "type is deprecated (declared at %s:%d)",
- xloc.file, xloc.line);
+ "type is deprecated (declared at %s:%d)%s",
+ xloc.file, xloc.line, deprecation_message);
}
else
{
if (what)
- warning (OPT_Wdeprecated_declarations, "%qs is deprecated", what);
+ warning (OPT_Wdeprecated_declarations, "%qs is deprecated%s", what,
+ deprecation_message);
else
- warning (OPT_Wdeprecated_declarations, "type is deprecated");
+ warning (OPT_Wdeprecated_declarations, "type is deprecated%s",
+ deprecation_message);
}
}
+
+ free (deprecation_message);
}
/* Compile an entire translation unit. Write a file of assembly
Index: gcc/testsuite/gcc.dg/deprecated-4.c
===================================================================
--- gcc/testsuite/gcc.dg/deprecated-4.c (revision 0)
+++ gcc/testsuite/gcc.dg/deprecated-4.c (revision 0)
@@ -0,0 +1,25 @@
+/* Test __attribute__((deprecated)). Test deprecation attribute tags. */
+/* Origin: Andrew Morrow <acm@google.com> */
+/* { dg-do compile } */
+/* { dg-options "" } */
+int value_bad_tag __attribute__((deprecated(1))); /* { dg-warning
"non-string message ignored" } */
+
+int value_is_deprecated __attribute__((deprecated("Use
value_is_not_deprecated instead")));
+
+void use_value_is_deprecated() {
+ int useit = value_is_deprecated; /* { dg-warning "with message
'Use value_is_not_deprecated instead'" } */
+}
+
+struct __attribute__((deprecated("See some_other_type for
replacement"))) type_is_deprecated {
+};
+
+void use_type_is_deprecated() {
+ struct type_is_deprecated x; /* { dg-warning "with message 'See
some_other_type for replacement'" } */
+}
+
+void function_is_deprecated() __attribute__((deprecated("@deprecated
http://deprecationdb/293847")));
+void function_is_deprecated() {}
+
+void use_function_is_deprecated() {
+ function_is_deprecated(); /* { dg-warning "with message
'@deprecated http://deprecationdb/293847'" } */
+}
Index: gcc/c-common.c
===================================================================
--- gcc/c-common.c (revision 141865)
+++ gcc/c-common.c (working copy)
@@ -823,7 +823,7 @@ const struct attribute_spec c_common_att
to prevent its usage in source code. */
{ "no vops", 0, 0, true, false, false,
handle_novops_attribute },
- { "deprecated", 0, 0, false, false, false,
+ { "deprecated", 0, 1, false, false, false,
handle_deprecated_attribute },
{ "vector_size", 1, 1, false, true, false,
handle_vector_size_attribute },
@@ -6444,13 +6444,23 @@ handle_novops_attribute (tree *node, tre
static tree
handle_deprecated_attribute (tree *node, tree name,
- tree ARG_UNUSED (args), int flags,
+ tree args, int flags,
bool *no_add_attrs)
{
tree type = NULL_TREE;
int warn = 0;
tree what = NULL_TREE;
+ /* Validate any argument is a string or ignore the attribute. */
+ if (args != NULL_TREE && TREE_CODE (TREE_VALUE (args)) != STRING_CST)
+ {
+ warning (OPT_Wattributes,
+ "%qE attribute with non-string message ignored",
+ name);
+ *no_add_attrs = true;
+ return NULL_TREE;
+ }
+
if (DECL_P (*node))
{
tree decl = *node;