bool *));
static tree handle_pure_attribute PARAMS ((tree *, tree, tree, int,
bool *));
+static tree handle_deprecated_attribute PARAMS ((tree *, tree, tree, int,
+ bool *));
static tree handle_vector_size_attribute PARAMS ((tree *, tree, tree, int,
bool *));
static tree vector_size_helper PARAMS ((tree, tree));
handle_no_limit_stack_attribute },
{ "pure", 0, 0, true, false, false,
handle_pure_attribute },
+ { "deprecated", 0, 0, false, false, false,
+ handle_deprecated_attribute },
{ "vector_size", 1, 1, false, true, false,
handle_vector_size_attribute },
{ NULL, 0, 0, false, false, false, NULL }
return NULL_TREE;
}
+/* Handle a "deprecated" attribute; arguments as in
+ struct attribute_spec.handler. */
+
+static tree
+handle_deprecated_attribute (node, name, args, flags, no_add_attrs)
+ tree *node;
+ tree name;
+ tree args ATTRIBUTE_UNUSED;
+ int flags;
+ bool *no_add_attrs;
+{
+ tree type = NULL_TREE;
+ int warn = 0;
+ char *what = NULL;
+
+ if (DECL_P (*node))
+ {
+ tree decl = *node;
+ type = TREE_TYPE (decl);
+
+ if (TREE_CODE (decl) == TYPE_DECL
+ || TREE_CODE (decl) == PARM_DECL
+ || TREE_CODE (decl) == VAR_DECL
+ || TREE_CODE (decl) == FUNCTION_DECL
+ || TREE_CODE (decl) == FIELD_DECL)
+ TREE_DEPRECATED (decl) = 1;
+ else
+ warn = 1;
+ }
+ else if (TYPE_P (*node))
+ {
+ if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
+ *node = build_type_copy (*node);
+ TREE_DEPRECATED (*node) = 1;
+ type = *node;
+ }
+ else
+ warn = 1;
+
+ if (warn)
+ {
+ *no_add_attrs = true;
+ if (type && TYPE_NAME (type))
+ {
+ if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
+ what = IDENTIFIER_POINTER (TYPE_NAME (*node));
+ else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
+ && DECL_NAME (TYPE_NAME (type)))
+ what = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
+ }
+ if (what)
+ warning ("`%s' attribute ignored for `%s'",
+ IDENTIFIER_POINTER (name), what);
+ else
+ warning ("`%s' attribute ignored",
+ IDENTIFIER_POINTER (name));
+ }
+
+ return NULL_TREE;
+}
+
/* Handle a "vector_size" attribute; arguments as in
struct attribute_spec.handler. */
#endif
int dollars_in_ident = DOLLARS_IN_IDENTIFIERS;
+/* States indicating how grokdeclarator() should handle declspecs marked
+ with __attribute__((deprecated)). An object declared as
+ __attribute__((deprecated)) suppresses warnings of uses of other
+ deprecated items. */
+
+enum deprecated_states {
+ DEPRECATED_NORMAL,
+ DEPRECATED_SUPPRESS
+};
+
+static enum deprecated_states deprecated_state = DEPRECATED_NORMAL;
+
/* Decode the string P as a language-specific option for C.
Return the number of strings consumed. Should not complain
if it does not recognise the option. */
int initialized;
tree attributes;
{
- tree decl = grokdeclarator (declarator, declspecs,
- NORMAL, initialized);
+ tree decl;
tree tem;
+
+ /* An object declared as __attribute__((deprecated)) suppresses
+ warnings of uses of other deprecated items. */
+ if (lookup_attribute ("deprecated", attributes))
+ deprecated_state = DEPRECATED_SUPPRESS;
+
+ decl = grokdeclarator (declarator, declspecs,
+ NORMAL, initialized);
+
+ deprecated_state = DEPRECATED_NORMAL;
if (warn_main > 0 && TREE_CODE (decl) != FUNCTION_DECL
&& MAIN_NAME_P (DECL_NAME (decl)))
{
tree id = TREE_VALUE (spec);
+ /* If the entire declaration is itself tagged as deprecated then
+ suppress reports of deprecated items. */
+ if (id && TREE_DEPRECATED (id))
+ {
+ if (deprecated_state != DEPRECATED_SUPPRESS)
+ warn_deprecated_use (id);
+ }
+
if (id == ridpointers[(int) RID_INT])
explicit_int = 1;
if (id == ridpointers[(int) RID_CHAR])
TREE_READONLY (ref) = 1;
if (TREE_THIS_VOLATILE (datum) || TREE_THIS_VOLATILE (subdatum))
TREE_THIS_VOLATILE (ref) = 1;
+
+ if (TREE_DEPRECATED (subdatum))
+ warn_deprecated_use (subdatum);
+
datum = ref;
}
tree decl = lookup_name (id);
tree objc_ivar = lookup_objc_ivar (id);
+ if (decl && TREE_DEPRECATED (decl))
+ warn_deprecated_use (decl);
+
if (!decl || decl == error_mark_node || C_DECL_ANTICIPATED (decl))
{
if (objc_ivar)
throw without being declared throw(). */
nothrow = ((decl && TREE_NOTHROW (decl))
|| TYPE_NOTHROW_P (TREE_TYPE (TREE_TYPE (function))));
-
+
+ if (decl && TREE_DEPRECATED (decl))
+ warn_deprecated_use (decl);
+
if (decl && DECL_CONSTRUCTOR_P (decl))
is_constructor = 1;
tree virtual_dtor = NULL_TREE;
tree *f;
+ ++adding_implicit_members;
+
/* Destructor. */
if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) && !TYPE_HAS_DESTRUCTOR (t))
{
*f = TYPE_METHODS (t);
TYPE_METHODS (t) = implicit_fns;
+ --adding_implicit_members;
+
return virtual_dtor;
}
/* Nonzero means warn about use of multicharacter literals. */
extern int warn_multichar;
+/* Set by add_implicitly_declared_members() to keep those members from
+ being flagged as deprecated or reported as using deprecated
+ types. */
+extern int adding_implicit_members;
+
/* Non-zero means warn if a non-templatized friend function is
declared in a templatized class. This behavior is warned about with
flag_guiding_decls in do_friend. */
(Zero if we are at namespace scope, one inside the body of a
function, two inside the body of a function in a local class, etc.) */
int function_depth;
+
+/* States indicating how grokdeclarator() should handle declspecs marked
+ with __attribute__((deprecated)). An object declared as
+ __attribute__((deprecated)) suppresses warnings of uses of other
+ deprecated items. */
+
+enum deprecated_states {
+ DEPRECATED_NORMAL,
+ DEPRECATED_SUPPRESS
+};
+
+static enum deprecated_states deprecated_state = DEPRECATED_NORMAL;
+
+/* Set by add_implicitly_declared_members() to keep those members from
+ being flagged as deprecated or reported as using deprecated
+ types. */
+int adding_implicit_members = 0;
\f
/* For each binding contour we allocate a binding_level structure
which records the names defined in that contour.
used_extern_spec = 1;
}
+ /* An object declared as __attribute__((deprecated)) suppresses
+ warnings of uses of other deprecated items. */
+ if (lookup_attribute ("deprecated", attributes))
+ deprecated_state = DEPRECATED_SUPPRESS;
+
attributes = chainon (attributes, prefix_attributes);
decl = grokdeclarator (declarator, declspecs, NORMAL, initialized,
&attributes);
+ deprecated_state = DEPRECATED_NORMAL;
+
if (decl == NULL_TREE || TREE_CODE (decl) == VOID_TYPE)
return NULL_TREE;
id = TREE_VALUE (spec);
+ /* If the entire declaration is itself tagged as deprecated then
+ suppress reports of deprecated items. */
+ if (!adding_implicit_members && id && TREE_DEPRECATED (id))
+ {
+ if (deprecated_state != DEPRECATED_SUPPRESS)
+ warn_deprecated_use (id);
+ }
+
if (TREE_CODE (id) == IDENTIFIER_NODE)
{
if (id == ridpointers[(int) RID_INT]
else
id = lastiddecl;
+ if (lexing && id && TREE_DEPRECATED (id))
+ warn_deprecated_use (id);
+
/* Do Koenig lookup if appropriate (inside templates we build lookup
expressions instead).
}
}
+ if (TREE_DEPRECATED (field))
+ warn_deprecated_use (field);
+
/* See if we have to do any conversions so that we pick up the field from the
right context. */
if (DECL_FIELD_CONTEXT (field) != basetype)
{
output_destroy_prefix (buffer);
}
+
+void
+warn_deprecated_use (node)
+ tree node;
+{
+ if (node && warn_deprecated_decl)
+ if (DECL_P (node))
+ {
+ warning ("`%s' is deprecated (declared at %s:%d)",
+ IDENTIFIER_POINTER (DECL_NAME (node)),
+ DECL_SOURCE_FILE (node), DECL_SOURCE_LINE (node));
+ }
+ else if (TYPE_P (node))
+ {
+ char *what = NULL;
+ tree decl = TYPE_STUB_DECL (node);
+
+ if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
+ what = IDENTIFIER_POINTER (TYPE_NAME (node));
+ else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
+ && DECL_NAME (TYPE_NAME (node)))
+ what = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (node)));
+
+ if (what)
+ {
+ if (decl)
+ warning ("`%s' is deprecated (declared at %s:%d)", what,
+ DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
+ else
+ warning ("`%s' is deprecated", what);
+ }
+ else
+ {
+ if (decl)
+ warning ("type is deprecated (declared at %s:%d)",
+ DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
+ else
+ warning ("type is deprecated");
+ }
+ }
+}
@code{noreturn}, @code{noinline}, @code{pure}, @code{const},
@code{format}, @code{format_arg}, @code{no_instrument_function},
@code{section}, @code{constructor}, @code{destructor}, @code{used},
-@code{unused}, @code{weak}, @code{malloc}, and @code{alias}. Several
-other attributes are defined for functions on particular target systems.
-Other attributes, including @code{section} are supported for variables
-declarations (@pxref{Variable Attributes}) and for types (@pxref{Type
-Attributes}).
+@code{unused}, @code{deprecated}, @code{weak}, @code{malloc}, and
+@code{alias}. Several other attributes are defined for functions on
+particular target systems. Other attributes, including @code{section}
+are supported for variables declarations (@pxref{Variable Attributes})
+and for types (@pxref{Type Attributes}).
You may also specify attributes with @samp{__} preceding and following
each keyword. This allows you to use them in header files without
This is useful, for example, when the function is referenced only in
inline assembly.
+@cindex @code{deprecated} attribute.
+@item deprecated
+The @code{deprecated} attribute results in a warning if the function
+is used anywhere in the source file. This is useful when identifying
+functions that are expected to be removed in a future version of a
+program. The warning also includes the location of the declaration
+of the deprecated function, to enable users to easily find further
+information about why the function is deprecated, or what they should
+do instead. Note that the warnings only occurs for uses:
+
+@smallexample
+int old_fn () __attribute__ ((deprecated));
+int old_fn ();
+int (*fn_ptr)() = old_fn;
+@end smallexample
+
+results in a warning on line 3 but not line 2.
+
+The @code{deprecated} attribute can also be used for variables and
+types (@pxref{Variable Attributes}, @pxref{Type Attributes}.)
+
@item weak
@cindex @code{weak} attribute
The @code{weak} attribute causes the declaration to be emitted as a weak
The keyword @code{__attribute__} allows you to specify special
attributes of variables or structure fields. This keyword is followed
-by an attribute specification inside double parentheses. Nine
+by an attribute specification inside double parentheses. Ten
attributes are currently defined for variables: @code{aligned},
@code{mode}, @code{nocommon}, @code{packed}, @code{section},
-@code{transparent_union}, @code{unused}, @code{vector_size}, and
-@code{weak}. Some other attributes are defined for variables on
-particular target systems. Other attributes are available for functions
-(@pxref{Function Attributes}) and for types (@pxref{Type Attributes}).
-Other front ends might define more attributes (@pxref{C++
-Extensions,,Extensions to the C++ Language}).
+@code{transparent_union}, @code{unused}, @code{deprecated},
+@code{vector_size}, and @code{weak}. Some other attributes are defined
+for variables on particular target systems. Other attributes are
+available for functions (@pxref{Function Attributes}) and for types
+(@pxref{Type Attributes}). Other front ends might define more
+attributes (@pxref{C++ Extensions,,Extensions to the C++ Language}).
You may also specify attributes with @samp{__} preceding and following
each keyword. This allows you to use them in header files without
to be possibly unused. GCC will not produce a warning for this
variable.
+@item deprecated
+The @code{deprecated} attribute results in a warning if the variable
+is used anywhere in the source file. This is useful when identifying
+variables that are expected to be removed in a future version of a
+program. The warning also includes the location of the declaration
+of the deprecated variable, to enable users to easily find further
+information about why the variable is deprecated, or what they should
+do instead. Note that the warnings only occurs for uses:
+
+@smallexample
+extern int old_var __attribute__ ((deprecated));
+extern int old_var;
+int new_fn () @{ return old_var; @}
+@end smallexample
+
+results in a warning on line 3 but not line 2.
+
+The @code{deprecated} attribute can also be used for functions and
+types (@pxref{Function Attributes}, @pxref{Type Attributes}.)
+
@item vector_size (@var{bytes})
This attribute specifies the vector size for the variable, measured in
bytes. For example, the declaration:
The keyword @code{__attribute__} allows you to specify special
attributes of @code{struct} and @code{union} types when you define such
types. This keyword is followed by an attribute specification inside
-double parentheses. Four attributes are currently defined for types:
-@code{aligned}, @code{packed}, @code{transparent_union}, and @code{unused}.
-Other attributes are defined for functions (@pxref{Function Attributes}) and
-for variables (@pxref{Variable Attributes}).
+double parentheses. Five attributes are currently defined for types:
+@code{aligned}, @code{packed}, @code{transparent_union}, @code{unused},
+and @code{deprecated}. Other attributes are defined for functions
+(@pxref{Function Attributes}) and for variables (@pxref{Variable Attributes}).
You may also specify any one of these attributes with @samp{__}
preceding and following its keyword. This allows you to use these
not referenced, but contain constructors and destructors that have
nontrivial bookkeeping functions.
+@item deprecated
+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.
+If possible, the warning also includes the location of the declaration
+of the deprecated type, to enable users to easily find further
+information about why the type is deprecated, or what they should do
+instead. Note that the warnings only occur for uses and then only
+if the type is being applied to a identifier that itself is not being
+declared as deprecated.
+
+@smallexample
+typedef int T1 __attribute__ ((deprecated));
+T1 x;
+typedef T1 T2;
+T2 y;
+typedef T1 T3 __attribute__ ((deprecated));
+T3 z __attribute__ ((deprecated));
+@end smallexample
+
+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.
+
+The @code{deprecated} attribute can also be used for functions and
+variables (@pxref{Function Attributes}, @pxref{Variable Attributes}.)
+
@end table
To specify multiple attributes, separate them by commas within the
-fsyntax-only -pedantic -pedantic-errors @gol
-w -W -Wall -Waggregate-return @gol
-Wcast-align -Wcast-qual -Wchar-subscripts -Wcomment @gol
--Wconversion -Wdisabled-optimization -Wdiv-by-zero -Werror @gol
+-Wconversion -Wno-deprecated-declarations @gol
+-Wdisabled-optimization -Wdiv-by-zero -Werror @gol
-Wfloat-equal -Wformat -Wformat=2 @gol
-Wformat-nonliteral -Wformat-security @gol
-Wimplicit -Wimplicit-int @gol
appropriate may not be detected. This option has no effect unless
@option{-Wformat} is enabled (possibly by @option{-Wall}).
+@item -Wno-deprecated-declarations
+@opindex Wno-deprecated-declarations
+Do not warn about uses of functions, variables, and types marked as
+deprecated by using the @code{deprecated} attribute.
+(@pxref{Function Attributes}, @pxref{Variable Attributes},
+@pxref{Type Attributes}.)
+
@item -Wpacked
@opindex Wpacked
Warn if a structure is given the packed attribute, but the packed
extern int warn_disabled_optimization;
+/* Nonzero means warn about uses of __attribute__((deprecated))
+ declarations. */
+
+extern int warn_deprecated_decl;
+
/* Nonzero if generating code to do profiling. */
extern int profile_flag;
fputs (" protected", file);
if (TREE_STATIC (node))
fputs (" static", file);
+ if (TREE_DEPRECATED (node))
+ fputs (" deprecated", file);
if (TREE_LANG_FLAG_0 (node))
fputs (" tree_0", file);
if (TREE_LANG_FLAG_1 (node))
int warn_missing_noreturn;
+/* Nonzero means warn about uses of __attribute__((deprecated))
+ declarations. */
+
+int warn_deprecated_decl = 1;
+
/* Likewise for -W. */
static const lang_independent_options W_options[] =
N_("Warn when padding is required to align struct members") },
{"disabled-optimization", &warn_disabled_optimization, 1,
N_("Warn when an optimization pass is disabled") },
+ {"deprecated-declarations", &warn_deprecated_decl, 1,
+ N_("Warn about uses of __attribute__((deprecated)) declarations") },
{"missing-noreturn", &warn_missing_noreturn, 1,
N_("Warn about functions which might be candidates for attribute noreturn") }
};
const char *, ...));
extern void warning_for_asm PARAMS ((struct rtx_def *,
const char *, ...));
+extern void warn_deprecated_use PARAMS ((union tree_node *));
extern int do_float_handler PARAMS ((void (*) (PTR), PTR));
#ifdef BUFSIZ
unsigned private_flag : 1;
unsigned protected_flag : 1;
unsigned bounded_flag : 1;
+ unsigned deprecated_flag : 1;
unsigned lang_flag_0 : 1;
unsigned lang_flag_1 : 1;
expressions, VAR_DECL, PARM_DECL, FIELD_DECL, FUNCTION_DECL,
IDENTIFIER_NODE
TYPE_BOUNDED in
- ..._TYPE */
+ ..._TYPE
+
+ deprecated_flag:
+
+ TREE_DEPRECATED in
+ ..._DECL
+*/
/* Define accessors for the fields that all tree nodes have
(though some fields are not used for all kinds of nodes). */
#define TREE_BOUNDED(NODE) ((NODE)->common.bounded_flag)
+/* Nonzero in a IDENTIFIER_NODE if the use of the name is defined as a
+ deprecated feature by __attribute__((deprecated)). */
+#define TREE_DEPRECATED(NODE) ((NODE)->common.deprecated_flag)
+
/* These flags are available for each language front end to use internally. */
#define TREE_LANG_FLAG_0(NODE) ((NODE)->common.lang_flag_0)
#define TREE_LANG_FLAG_1(NODE) ((NODE)->common.lang_flag_1)