This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH: PR c/36892: Support __attribute__((deprecated("text string")))
- From: "H.J. Lu" <hongjiu dot lu at intel dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: acm at google dot com
- Date: Tue, 5 May 2009 17:29:50 -0700
- Subject: PATCH: PR c/36892: Support __attribute__((deprecated("text string")))
- Reply-to: "H.J. Lu" <hjl dot tools at gmail dot com>
Hi,
Here is the updated patch to implement
__attribute__((deprecated("text string")))
Tested on Linux/ia32, Linux/ia64 and Linux/Intel64. OK for trunk?
Thanks.
H.J.
---
gcc/
2009-05-05 H.J. Lu <hongjiu.lu@intel.com>
Andrew Morrow <acm@google.com>
PR c/36892
* c-common.c (c_common_attribute_table): Permit deprecated
attribute to take an optional argument.
(handle_deprecated_attribute): If the optional argument to
__attribute__((deprecated)) is not a string ignore the attribute
and emit a warning.
* c-decl.c (grokdeclarator): Updated warn_deprecated_use call.
* c-typeck.c (build_component_ref): Likewise.
(build_external_ref): Likewise.
* toplev.c (warn_deprecated_use): Add an attribute argument.
Emit the message associated with __attribute__((deprecated)).
* toplev.h (warn_deprecated_use): Updated.
* doc/extend.texi: Document new optional parameter to
__attribute__((deprecated))
gcc/cp/
2009-05-05 H.J. Lu <hongjiu.lu@intel.com>
PR c/36892
* call.c (build_call_a): Updated warn_deprecated_use call.
(build_over_call): Likewise.
* decl.c (grokdeclarator): Likewise.
(grokparms): Likewise.
* semantics.c (finish_id_expression): Likewise.
* typeck.c (build_class_member_access_expr): Likewise.
(finish_class_member_access_expr): Likewise.
gcc/testsuite/
2009-05-05 H.J. Lu <hongjiu.lu@intel.com>
PR c/36892
* g++.dg/warn/deprecated-6.C: New.
* gcc.dg/deprecated-4.c: Likewise.
* gcc.dg/deprecated-5.c: Likewise.
* gcc.dg/deprecated-6.c: Likewise.
--- gcc/c-common.c.deprecated 2009-05-05 15:44:25.000000000 -0700
+++ gcc/c-common.c 2009-05-05 15:51:00.000000000 -0700
@@ -954,7 +954,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 },
@@ -7179,13 +7179,21 @@ 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;
+ if (!args)
+ *no_add_attrs = true;
+ else if (TREE_CODE (TREE_VALUE (args)) != STRING_CST)
+ {
+ error ("deprecated message is not a string");
+ *no_add_attrs = true;
+ }
+
if (DECL_P (*node))
{
tree decl = *node;
--- gcc/c-decl.c.deprecated 2009-05-05 15:44:25.000000000 -0700
+++ gcc/c-decl.c 2009-05-05 15:51:00.000000000 -0700
@@ -4180,7 +4180,7 @@ grokdeclarator (const struct c_declarato
decl_context = PARM;
if (declspecs->deprecated_p && deprecated_state != DEPRECATED_SUPPRESS)
- warn_deprecated_use (declspecs->type);
+ warn_deprecated_use (declspecs->type, declspecs->decl_attr);
if ((decl_context == NORMAL || decl_context == FIELD)
&& current_scope == file_scope
--- gcc/c-typeck.c.deprecated 2009-05-05 15:44:25.000000000 -0700
+++ gcc/c-typeck.c 2009-05-05 15:51:00.000000000 -0700
@@ -1964,7 +1964,7 @@ build_component_ref (tree datum, tree co
TREE_THIS_VOLATILE (ref) = 1;
if (TREE_DEPRECATED (subdatum))
- warn_deprecated_use (subdatum);
+ warn_deprecated_use (subdatum, NULL_TREE);
datum = ref;
@@ -2225,7 +2225,7 @@ build_external_ref (tree id, int fun, lo
return error_mark_node;
if (TREE_DEPRECATED (ref))
- warn_deprecated_use (ref);
+ warn_deprecated_use (ref, NULL_TREE);
/* Recursive call does not count as usage. */
if (ref != current_function_decl)
--- gcc/cp/call.c.deprecated 2009-04-24 09:36:36.000000000 -0700
+++ gcc/cp/call.c 2009-05-05 15:51:00.000000000 -0700
@@ -342,7 +342,7 @@ build_call_a (tree function, int n, tree
current_function_returns_abnormally = 1;
if (decl && TREE_DEPRECATED (decl))
- warn_deprecated_use (decl);
+ warn_deprecated_use (decl, NULL_TREE);
require_complete_eh_spec_types (fntype, decl);
if (decl && DECL_CONSTRUCTOR_P (decl))
@@ -5457,7 +5457,7 @@ build_over_call (struct z_candidate *can
/* Warn about deprecated virtual functions now, since we're about
to throw away the decl. */
if (TREE_DEPRECATED (fn))
- warn_deprecated_use (fn);
+ warn_deprecated_use (fn, NULL_TREE);
argarray[0] = build_base_path (PLUS_EXPR, argarray[0], binfo, 1);
if (TREE_SIDE_EFFECTS (argarray[0]))
--- gcc/cp/decl.c.deprecated 2009-04-23 10:37:59.000000000 -0700
+++ gcc/cp/decl.c 2009-05-05 15:51:00.000000000 -0700
@@ -7835,7 +7835,7 @@ grokdeclarator (const cp_declarator *dec
suppress reports of deprecated items. */
if (type && TREE_DEPRECATED (type)
&& deprecated_state != DEPRECATED_SUPPRESS)
- warn_deprecated_use (type);
+ warn_deprecated_use (type, NULL_TREE);
if (type && TREE_CODE (type) == TYPE_DECL)
{
typedef_decl = type;
@@ -7843,7 +7843,7 @@ grokdeclarator (const cp_declarator *dec
if (TREE_DEPRECATED (type)
&& DECL_ARTIFICIAL (typedef_decl)
&& deprecated_state != DEPRECATED_SUPPRESS)
- warn_deprecated_use (type);
+ warn_deprecated_use (type, NULL_TREE);
}
/* No type at all: default to `int', and set DEFAULTED_INT
because it was not a user-defined typedef. */
@@ -9697,7 +9697,7 @@ grokparms (tree parmlist, tree *parms)
{
tree deptype = type_is_deprecated (type);
if (deptype)
- warn_deprecated_use (deptype);
+ warn_deprecated_use (deptype, NULL_TREE);
}
/* Top-level qualifiers on the parameters are
--- gcc/cp/semantics.c.deprecated 2009-04-27 14:34:56.000000000 -0700
+++ gcc/cp/semantics.c 2009-05-05 15:51:00.000000000 -0700
@@ -3038,7 +3038,7 @@ finish_id_expression (tree id_expression
}
if (TREE_DEPRECATED (decl))
- warn_deprecated_use (decl);
+ warn_deprecated_use (decl, NULL_TREE);
return decl;
}
--- gcc/cp/typeck.c.deprecated 2009-05-05 15:44:13.000000000 -0700
+++ gcc/cp/typeck.c 2009-05-05 15:51:00.000000000 -0700
@@ -1909,7 +1909,7 @@ build_class_member_access_expr (tree obj
member_scope = DECL_CLASS_CONTEXT (member);
mark_used (member);
if (TREE_DEPRECATED (member))
- warn_deprecated_use (member);
+ warn_deprecated_use (member, NULL_TREE);
}
else
member_scope = BINFO_TYPE (BASELINK_ACCESS_BINFO (member));
@@ -2369,7 +2369,7 @@ finish_class_member_access_expr (tree ob
}
if (TREE_DEPRECATED (member))
- warn_deprecated_use (member);
+ warn_deprecated_use (member, NULL_TREE);
if (template_p)
check_template_keyword (member);
--- gcc/doc/extend.texi.deprecated 2009-04-27 14:34:55.000000000 -0700
+++ gcc/doc/extend.texi 2009-05-05 15:51:00.000000000 -0700
@@ -2069,6 +2069,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
@@ -2084,7 +2085,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}.)
@@ -3849,6 +3852,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
@@ -3864,7 +3868,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}.)
@@ -4494,6 +4500,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.
@@ -4516,7 +4523,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}.)
--- gcc/testsuite/g++.dg/warn/deprecated-6.C.deprecated 2009-05-05 15:51:00.000000000 -0700
+++ gcc/testsuite/g++.dg/warn/deprecated-6.C 2009-05-05 15:51:00.000000000 -0700
@@ -0,0 +1,113 @@
+/* Test __attribute__ ((deprecated("message"))) */
+/* { dg-do compile } */
+/* { dg-options "-Wdeprecated-declarations -fmessage-length=0" } */
+
+typedef int INT1 __attribute__((deprecated("Please avoid INT1")));
+typedef INT1 INT2 __attribute__ ((__deprecated__("Please avoid INT2")));
+
+typedef INT1 INT1a; /* { dg-warning "'INT1' is deprecated" "" } */
+typedef INT1 INT1b __attribute__ ((deprecated("Please avoid INT1b")));
+
+INT1 should_be_unavailable; /* { dg-warning "'INT1' is deprecated" "" } */
+INT1a should_not_be_deprecated;
+
+INT1 f1(void) __attribute__ ((deprecated("Please avoid f1")));
+INT1 f2(void) { return 0; } /* { dg-warning "'INT1' is deprecated" "" } */
+
+INT2 f3(void) __attribute__ ((__deprecated__("Please avoid f3")));
+INT2 f4(void) { return 0; } /* { dg-warning "'INT2' is deprecated" "" } */
+int f5(INT2 x); /* { dg-warning "'INT2' is deprecated" "" } */
+int f6(INT2 x) __attribute__ ((__deprecated__("Please avoid f6")));
+
+typedef enum Color {red, green, blue} Color __attribute__((deprecated("Please avoid INT1")));
+
+int g1;
+int g2 __attribute__ ((deprecated("Please avoid g2")));
+int g3 __attribute__ ((__deprecated__("Please avoid g3")));
+Color k; /* { dg-warning "'Color' is deprecated" "" } */
+
+typedef struct {
+ int field1;
+ int field2 __attribute__ ((deprecated("Please avoid field2")));
+ int field3;
+ int field4 __attribute__ ((__deprecated__("Please avoid field4")));
+ union {
+ int field5;
+ int field6 __attribute__ ((deprecated("Please avoid field6")));
+ } u1;
+ int field7:1;
+ int field8:1 __attribute__ ((deprecated("Please avoid field8")));
+ union {
+ int field9;
+ int field10;
+ } u2 __attribute__ ((deprecated("Please avoid u2")));
+} S1;
+
+int func1()
+{
+ INT1 w; /* { dg-warning "'INT1' is deprecated" "" } */
+ int x __attribute__ ((deprecated("Please avoid x")));
+ int y __attribute__ ((__deprecated__("Please avoid y")));
+ int z;
+ int (*pf)() = f1; /* { dg-warning "'INT1 f1\\(\\)' is deprecated" "" } */
+
+ z = w + x + y + g1 + g2 + g3; /* { dg-warning "'x' is deprecated" "" } */
+ /* { dg-warning "'y' is deprecated" "y" { target *-*-* } 54 } */
+ /* { dg-warning "'g2' is deprecated" "g2" { target *-*-* } 54 } */
+ /* { dg-warning "'g3' is deprecated" "g3" { target *-*-* } 54 } */
+ return f1(); /* { dg-warning "'INT1 f1\\(\\)' is deprecated" "f1" } */
+}
+
+int func2(S1 *p)
+{
+ S1 lp;
+
+ if (p->field1)
+ return p->field2; /* { dg-warning "'S1::field2' is deprecated" "" } */
+ else if (lp.field4) /* { dg-warning "'S1::field4' is deprecated" "" } */
+ return p->field3;
+
+ p->u1.field5 = g1 + p->field7;
+ p->u2.field9; /* { dg-warning "'S1::u2' is deprecated" "" } */
+ return p->u1.field6 + p->field8; /* { dg-warning "'S1::<anonymous union>::field6' is deprecated" "" } */
+ /* { dg-warning "'S1::field8' is deprecated" "field8" { target *-*-* } 72 } */
+}
+
+struct SS1 {
+ int x;
+ INT1 y; /* { dg-warning "'INT1' is deprecated" "" } */
+} __attribute__ ((deprecated("Please avoid SS1")));
+
+struct SS1 *p1; /* { dg-warning "'SS1' is deprecated" "" } */
+
+struct __attribute__ ((__deprecated__("Please avoid SS2"))) SS2 {
+ int x;
+ INT1 y; /* { dg-warning "'INT1' is deprecated" "" } */
+};
+
+struct SS2 *p2; /* { dg-warning "'SS2' is deprecated" "" } */
+
+#ifdef __cplusplus
+class T {
+ public:
+ void member1(int) __attribute__ ((deprecated("Please avoid member1")));
+ void member2(INT1) __attribute__ ((__deprecated__("Please avoid member2"))); /* { dg-warning "'INT1' is deprecated" "" } */
+ int member3(T *);
+ int x;
+} __attribute__ ((deprecated("Please avoid INT1")));
+
+T *p3; // { dg-warning "'T' is deprecated" }
+
+inline void T::member1(int) {}
+
+int T::member3(T *p) // { dg-warning "'T' is deprecated" }
+{
+ p->member1(1); /* { dg-warning "'void T::member1\\(int\\)' is deprecated" "" } */
+ (*p).member1(2); /* { dg-warning "'void T::member1\\(int\\)' is deprecated" "" } */
+ p->member2(1); /* { dg-warning "'void T::member2\\(INT1\\)' is deprecated" "" } */
+ (*p).member2(2); /* { dg-warning "'void T::member2\\(INT1\\)' is deprecated" "" } */
+ p->member3(p);
+ (*p).member3(p);
+ return f1(); /* { dg-warning "'INT1 f1\\(\\)' is deprecated" "" } */
+}
+#endif
--- gcc/testsuite/gcc.dg/deprecated-4.c.deprecated 2009-05-05 15:51:00.000000000 -0700
+++ gcc/testsuite/gcc.dg/deprecated-4.c 2009-05-05 15:51:00.000000000 -0700
@@ -0,0 +1,113 @@
+/* Test __attribute__ ((deprecated("message"))) */
+/* { dg-do compile } */
+/* { dg-options "-Wdeprecated-declarations" } */
+
+typedef int INT1 __attribute__((deprecated("Please avoid INT1")));
+typedef INT1 INT2 __attribute__ ((__deprecated__("Please avoid INT2")));
+
+typedef INT1 INT1a; /* { dg-warning "'INT1' is deprecated" "" } */
+typedef INT1 INT1b __attribute__ ((deprecated("Please avoid INT1b")));
+
+INT1 should_be_unavailable; /* { dg-warning "'INT1' is deprecated" "" } */
+INT1a should_not_be_deprecated;
+
+INT1 f1(void) __attribute__ ((deprecated("Please avoid f1")));
+INT1 f2(void) { return 0; } /* { dg-warning "'INT1' is deprecated" "" } */
+
+INT2 f3(void) __attribute__ ((__deprecated__("Please avoid f3")));
+INT2 f4(void) { return 0; } /* { dg-warning "'INT2' is deprecated" "" } */
+int f5(INT2 x); /* { dg-warning "'INT2' is deprecated" "" } */
+int f6(INT2 x) __attribute__ ((__deprecated__("Please avoid f6"))); /* { dg-warning "'INT2' is deprecated" "" } */
+
+typedef enum {red, green, blue} Color __attribute__((deprecated("Please avoid Color")));
+
+int g1;
+int g2 __attribute__ ((deprecated("Please avoid g2")));
+int g3 __attribute__ ((__deprecated__("Please avoid g3")));
+Color k; /* { dg-warning "'Color' is deprecated" "" } */
+
+typedef struct {
+ int field1;
+ int field2 __attribute__ ((deprecated("Please avoid field2")));
+ int field3;
+ int field4 __attribute__ ((__deprecated__("Please avoid field4")));
+ union {
+ int field5;
+ int field6 __attribute__ ((deprecated("Please avoid field6")));
+ } u1;
+ int field7:1;
+ int field8:1 __attribute__ ((deprecated("Please avoid field8")));
+ union {
+ int field9;
+ int field10;
+ } u2 __attribute__ ((deprecated("Please avoid u2")));
+} S1;
+
+int func1()
+{
+ INT1 w; /* { dg-warning "'INT1' is deprecated" "" } */
+ int x __attribute__ ((deprecated("Please avoid x")));
+ int y __attribute__ ((__deprecated__("Please avoid y")));
+ int z;
+ int (*pf)() = f1; /* { dg-warning "'f1' is deprecated" "" } */
+
+ z = w + x + y + g1 + g2 + g3; /* { dg-warning "'x' is deprecated" "" } */
+ /* { dg-warning "'y' is deprecated" "y" { target *-*-* } 54 } */
+ /* { dg-warning "'g2' is deprecated" "g2" { target *-*-* } 54 } */
+ /* { dg-warning "'g3' is deprecated" "g3" { target *-*-* } 54 } */
+ return f1(); /* { dg-warning "'f1' is deprecated" "f1" } */
+}
+
+int func2(S1 *p)
+{
+ S1 lp;
+
+ if (p->field1)
+ return p->field2; /* { dg-warning "'field2' is deprecated" "" } */
+ else if (lp.field4) /* { dg-warning "'field4' is deprecated" "" } */
+ return p->field3;
+
+ p->u1.field5 = g1 + p->field7;
+ p->u2.field9; /* { dg-warning "'u2' is deprecated" "" } */
+ return p->u1.field6 + p->field8; /* { dg-warning "'field6' is deprecated" "" } */
+ /* { dg-warning "'field8' is deprecated" "field8" { target *-*-* } 72 } */
+}
+
+struct SS1 {
+ int x;
+ INT1 y; /* { dg-warning "'INT1' is deprecated" "" } */
+} __attribute__ ((deprecated("Please avoid SS1")));
+
+struct SS1 *p1; /* { dg-warning "'SS1' is deprecated" "" } */
+
+struct __attribute__ ((__deprecated__("Please avoid SS2"))) SS2 {
+ int x;
+ INT1 y; /* { dg-warning "'INT1' is deprecated" "" } */
+};
+
+struct SS2 *p2; /* { dg-warning "'SS2' is deprecated" "" } */
+
+#ifdef __cplusplus
+class T {
+ public:
+ void member1(int) __attribute__ ((deprecated("Please avoid member1")));
+ void member2(INT1) __attribute__ ((__deprecated__("Please avoid member2")));
+ int member3(T *);
+ int x;
+} __attribute__ ((deprecated("Please avoid T")));
+
+T *p2;
+
+inline void T::member1(int) {}
+
+int T::member2(T *p)
+{
+ p->member1(1); /* { xxdg-warning "'member1' is deprecated" "" } */
+ (*p).member1(2); /* { xxdg-warning "'member1' is deprecated" "" } */
+ p->member2(1); /* { xxdg-warning "'member2' is deprecated" "" } */
+ (*p).member2(2); /* { xxdg-warning "'member2' is deprecated" "" } */
+ p->member3(p);
+ (*p).member3(p);
+ return f1(); /* { xxdg-warning "'f1' is deprecated" "" } */
+}
+#endif
--- gcc/testsuite/gcc.dg/deprecated-5.c.deprecated 2009-05-05 15:51:00.000000000 -0700
+++ gcc/testsuite/gcc.dg/deprecated-5.c 2009-05-05 15:51:00.000000000 -0700
@@ -0,0 +1,7 @@
+/* Test __attribute__((deprecated)). Test types without names. */
+/* Origin: Joseph Myers <jsm@polyomino.org.uk> */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+struct { int a; } __attribute__((deprecated)) x; /* { dg-warning "type is deprecated" } */
+typeof(x) y; /* { dg-warning "type is deprecated" } */
--- gcc/testsuite/gcc.dg/deprecated-6.c.deprecated 2009-05-05 15:51:00.000000000 -0700
+++ gcc/testsuite/gcc.dg/deprecated-6.c 2009-05-05 15:51:00.000000000 -0700
@@ -0,0 +1,11 @@
+/* Test __attribute__((deprecated)). Test merging with multiple
+ declarations. Bug 7425. */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+void func(void);
+void func(void) __attribute__((deprecated));
+
+void f(void) {
+ func(); /* { dg-warning "'func' is deprecated" } */
+}
--- gcc/toplev.c.deprecated 2009-05-05 15:44:24.000000000 -0700
+++ gcc/toplev.c 2009-05-05 15:55:47.000000000 -0700
@@ -908,17 +908,45 @@ emit_debug_global_declarations (tree *ve
/* Warn about a use of an identifier which was marked deprecated. */
void
-warn_deprecated_use (tree node)
+warn_deprecated_use (tree node, tree attr)
{
+ const char *msg;
+
if (node == 0 || !warn_deprecated_decl)
return;
+ if (!attr)
+ {
+ if (DECL_P (node))
+ attr = DECL_ATTRIBUTES (node);
+ else if (TYPE_P (node))
+ {
+ tree decl = TYPE_STUB_DECL (node);
+ if (decl)
+ attr = lookup_attribute ("deprecated",
+ TYPE_ATTRIBUTES (TREE_TYPE (decl)));
+ }
+ }
+
+ if (attr)
+ attr = lookup_attribute ("deprecated", attr);
+
+ if (attr)
+ msg = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr)));
+ else
+ msg = NULL;
+
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);
+ if (msg)
+ warning (OPT_Wdeprecated_declarations,
+ "%qD is deprecated (declared at %s:%d): %s",
+ node, xloc.file, xloc.line, msg);
+ else
+ warning (OPT_Wdeprecated_declarations,
+ "%qD is deprecated (declared at %s:%d)",
+ node, xloc.file, xloc.line);
}
else if (TYPE_P (node))
{
@@ -939,20 +967,46 @@ warn_deprecated_use (tree node)
expanded_location xloc
= expand_location (DECL_SOURCE_LOCATION (decl));
if (what)
- warning (OPT_Wdeprecated_declarations,
- "%qE is deprecated (declared at %s:%d)", what,
- xloc.file, xloc.line);
+ {
+ if (msg)
+ warning (OPT_Wdeprecated_declarations,
+ "%qE is deprecated (declared at %s:%d): %s",
+ what, xloc.file, xloc.line, msg);
+ else
+ warning (OPT_Wdeprecated_declarations,
+ "%qE is deprecated (declared at %s:%d)", what,
+ xloc.file, xloc.line);
+ }
else
- warning (OPT_Wdeprecated_declarations,
- "type is deprecated (declared at %s:%d)",
- xloc.file, xloc.line);
+ {
+ if (msg)
+ warning (OPT_Wdeprecated_declarations,
+ "type is deprecated (declared at %s:%d): %s",
+ xloc.file, xloc.line, msg);
+ else
+ warning (OPT_Wdeprecated_declarations,
+ "type is deprecated (declared at %s:%d)",
+ xloc.file, xloc.line);
+ }
}
else
{
if (what)
- warning (OPT_Wdeprecated_declarations, "%qE is deprecated", what);
+ {
+ if (msg)
+ warning (OPT_Wdeprecated_declarations, "%qE is deprecated: %s",
+ what, msg);
+ else
+ warning (OPT_Wdeprecated_declarations, "%qE is deprecated", what);
+ }
else
- warning (OPT_Wdeprecated_declarations, "type is deprecated");
+ {
+ if (msg)
+ warning (OPT_Wdeprecated_declarations, "type is deprecated: %s",
+ msg);
+ else
+ warning (OPT_Wdeprecated_declarations, "type is deprecated");
+ }
}
}
}
--- gcc/toplev.h.deprecated 2009-04-27 14:34:58.000000000 -0700
+++ gcc/toplev.h 2009-05-05 15:51:00.000000000 -0700
@@ -83,7 +83,7 @@ extern void announce_function (tree);
extern void error_for_asm (const_rtx, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
extern void warning_for_asm (const_rtx, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
-extern void warn_deprecated_use (tree);
+extern void warn_deprecated_use (tree, tree);
extern bool parse_optimize_options (tree, bool);
#ifdef BUFSIZ