gcc/ 2009-05-05 H.J. Lu Andrew Morrow 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 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 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-07 13:07:36.000000000 -0700 +++ gcc/c-common.c 2009-05-07 13:14:39.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-07 13:07:36.000000000 -0700 +++ gcc/c-decl.c 2009-05-07 13:14:39.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-07 13:07:36.000000000 -0700 +++ gcc/c-typeck.c 2009-05-07 17:40:34.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-05-07 13:07:03.000000000 -0700 +++ gcc/cp/call.c 2009-05-07 13:14:39.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-05-07 13:07:03.000000000 -0700 +++ gcc/cp/decl.c 2009-05-07 16:30:07.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-05-07 13:07:03.000000000 -0700 +++ gcc/cp/semantics.c 2009-05-07 13:14:39.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-07 13:07:03.000000000 -0700 +++ gcc/cp/typeck.c 2009-05-07 13:14:39.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-05-07 13:06:57.000000000 -0700 +++ gcc/doc/extend.texi 2009-05-07 13:14:39.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-07 13:14:39.000000000 -0700 +++ gcc/testsuite/g++.dg/warn/deprecated-6.C 2009-05-08 07:56:32.000000000 -0700 @@ -0,0 +1,110 @@ +/* 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 .declared at \[^\n\]*: Please avoid INT1" "" } */ + +INT1 should_be_unavailable; /* { dg-warning "'INT1' is deprecated .declared at \[^\n\]*: Please avoid INT1" "" } */ +INT1a should_not_be_deprecated; + +INT1 f1(void) __attribute__ ((deprecated("Please avoid f1"))); +INT1 f2(void) { return 0; } /* { dg-warning "'INT1' is deprecated .declared at \[^\n\]*: Please avoid INT1" "" } */ + +INT2 f3(void) __attribute__ ((__deprecated__("Please avoid f3"))); +INT2 f4(void) { return 0; } /* { dg-warning "'INT2' is deprecated .declared at \[^\n\]*: Please avoid INT2" "" } */ +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 Color"))); + +int g1; +int g2 __attribute__ ((deprecated("Please avoid g2"))); +int g3 __attribute__ ((__deprecated__("Please avoid g3"))); +Color k; /* { dg-warning "'Color' is deprecated .declared at \[^\n\]*: Please avoid Color" "" } */ + +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 .declared at \[^\n\]*: Please avoid INT1" "" } */ + 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 .declared at \[^\n\]*: Please avoid f1" "" } */ + + z = w + x + y + g1 + g2 + g3; /* { dg-warning "'x' is deprecated .declared at \[^\n\]*: Please avoid x" "" } */ + /* { dg-warning "'y' is deprecated .declared at \[^\n\]*: Please avoid y" "y" { target *-*-* } 53 } */ + /* { dg-warning "'g2' is deprecated .declared at \[^\n\]*: Please avoid g2" "g2" { target *-*-* } 53 } */ + /* { dg-warning "'g3' is deprecated .declared at \[^\n\]*: Please avoid g3" "g3" { target *-*-* } 53 } */ + return f1(); /* { dg-warning "'INT1 f1\\(\\)' is deprecated .declared at \[^\n\]*: Please avoid f1" "f1" } */ +} + +int func2(S1 *p) +{ + S1 lp; + + if (p->field1) + return p->field2; /* { dg-warning "'S1::field2' is deprecated .declared at \[^\n\]*: Please avoid field2" "" } */ + else if (lp.field4) /* { dg-warning "'S1::field4' is deprecated .declared at \[^\n\]*: Please avoid field4" "" } */ + return p->field3; + + p->u1.field5 = g1 + p->field7; + p->u2.field9; /* { dg-warning "'S1::u2' is deprecated .declared at \[^\n\]*: Please avoid u2" "" } */ + return p->u1.field6 + p->field8; /* { dg-warning "'S1::::field6' is deprecated .declared at \[^\n\]*: Please avoid field6" "" } */ + /* { dg-warning "'S1::field8' is deprecated .declared at \[^\n\]*: Please avoid field8" "field8" { target *-*-* } 71 } */ +} + +struct SS1 { + int x; + INT1 y; /* { dg-warning "'INT1' is deprecated .declared at \[^\n\]*: Please avoid INT1" "" } */ +} __attribute__ ((deprecated("Please avoid SS1"))); + +struct SS1 *p1; /* { dg-warning "'SS1' is deprecated .declared at \[^\n\]*: Please avoid SS1" "" } */ + +struct __attribute__ ((__deprecated__("Please avoid SS2"))) SS2 { + int x; + INT1 y; /* { dg-warning "'INT1' is deprecated .declared at \[^\n\]*: Please avoid INT1" "" } */ +}; + +struct SS2 *p2; /* { dg-warning "'SS2' is deprecated .declared at \[^\n\]*: Please avoid SS2" "" } */ + +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 T"))); + +T *p3; // { dg-warning "'T' is deprecated .declared at \[^\n\]*: Please avoid T" } + +inline void T::member1(int) {} + +int T::member3(T *p) // { dg-warning "'T' is deprecated .declared at \[^\n\]*: Please avoid T" } +{ + p->member1(1); /* { dg-warning "'void T::member1\\(int\\)' is deprecated .declared at \[^\n\]*: Please avoid member1" "" } */ + (*p).member1(2); /* { dg-warning "'void T::member1\\(int\\)' is deprecated .declared at \[^\n\]*: Please avoid member1" "" } */ + p->member2(1); /* { dg-warning "'void T::member2\\(INT1\\)' is deprecated .declared at \[^\n\]*: Please avoid member2" "" } */ + (*p).member2(2); /* { dg-warning "'void T::member2\\(INT1\\)' is deprecated .declared at \[^\n\]*: Please avoid member2" "" } */ + p->member3(p); + (*p).member3(p); + return f1(); /* { dg-warning "'INT1 f1\\(\\)' is deprecated .declared at \[^\n\]*: Please avoid f1" "" } */ +} --- gcc/testsuite/gcc.dg/deprecated-4.c.deprecated 2009-05-07 13:14:39.000000000 -0700 +++ gcc/testsuite/gcc.dg/deprecated-4.c 2009-05-08 07:58:44.000000000 -0700 @@ -0,0 +1,88 @@ +/* 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: Please avoid INT1" "" } */ +typedef INT1 INT1b __attribute__ ((deprecated("Please avoid INT1b"))); + +INT1 should_be_unavailable; /* { dg-warning "'INT1' is deprecated: Please avoid INT1" "" } */ +INT1a should_not_be_deprecated; + +INT1 f1(void) __attribute__ ((deprecated("Please avoid f1"))); +INT1 f2(void) { return 0; } /* { dg-warning "'INT1' is deprecated: Please avoid INT1" "" } */ + +INT2 f3(void) __attribute__ ((__deprecated__("Please avoid f3"))); +INT2 f4(void) { return 0; } /* { dg-warning "'INT2' is deprecated: Please avoid INT2" "" } */ +int f5(INT2 x); /* { dg-warning "'INT2' is deprecated: Please avoid INT2" "" } */ +int f6(INT2 x) __attribute__ ((__deprecated__("Please avoid f6"))); /* { dg-warning "'INT2' is deprecated: Please avoid INT2" "" } */ + +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 .declared at \[^\n\]*: Please avoid Color" "" } */ + +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: Please avoid INT1" "" } */ + int x __attribute__ ((deprecated("Avoid x"))); + int y __attribute__ ((__deprecated__("Bad y"))); + int z; + int (*pf)() = f1; /* { dg-warning "'f1' is deprecated .declared at \[^\n\]*: Please avoid f1" "" } */ + + z = w + x + y + g1 + g2 + g3; /* { dg-warning "'x' is deprecated .declared at \[^\n\]*: Avoid x" "" } */ + /* { dg-warning "'y' is deprecated .declared at \[^\n\]*: Bad y" "y" { target *-*-* } 54 } */ + /* { dg-warning "'g2' is deprecated .declared at \[^\n\]*: Please avoid g2" "g2" { target *-*-* } 54 } */ + /* { dg-warning "'g3' is deprecated .declared at \[^\n\]*: Please avoid g3" "g3" { target *-*-* } 54 } */ + return f1(); /* { dg-warning "'f1' is deprecated .declared at \[^\n\]*: Please avoid f1" "" } */ +} + +int func2(S1 *p) +{ + S1 lp; + + if (p->field1) + return p->field2; /* { dg-warning "'field2' is deprecated .declared at \[^\n\]*: Please avoid field2" "" } */ + else if (lp.field4) /* { dg-warning "'field4' is deprecated .declared at \[^\n\]*: Please avoid field4" "" } */ + return p->field3; + + p->u1.field5 = g1 + p->field7; + p->u2.field9; /* { dg-warning "'u2' is deprecated .declared at \[^\n\]*: Please avoid u2" "" } */ + return p->u1.field6 + p->field8; /* { dg-warning "'field6' is deprecated .declared at \[^\n\]*: Please avoid field6" "" } */ + /* { dg-warning "'field8' is deprecated .declared at \[^\n\]*: Please avoid field8" "field8" { target *-*-* } 72 } */ +} + +struct SS1 { + int x; + INT1 y; /* { dg-warning "'INT1' is deprecated: Please avoid INT1" "" } */ +} __attribute__ ((deprecated("Please avoid SS1"))); + +struct SS1 *p1; /* { dg-warning "'SS1' is deprecated .declared at \[^\n\]*: Please avoid SS1" "" } */ + +struct __attribute__ ((__deprecated__("Please avoid SS2"))) SS2 { + int x; + INT1 y; /* { dg-warning "'INT1' is deprecated: Please avoid INT1" "" } */ +}; + +struct SS2 *p2; /* { dg-warning "'SS2' is deprecated .declared at \[^\n\]*: Please avoid SS2" "" } */ --- gcc/testsuite/gcc.dg/deprecated-5.c.deprecated 2009-05-07 13:14:39.000000000 -0700 +++ gcc/testsuite/gcc.dg/deprecated-5.c 2009-05-07 13:45:35.000000000 -0700 @@ -0,0 +1,7 @@ +/* Test __attribute__((deprecated)). Test types without names. */ +/* Origin: Joseph Myers */ +/* { dg-do compile } */ +/* { dg-options "" } */ + +struct { int a; } __attribute__((deprecated ("Do not use"))) x; /* { dg-warning "type is deprecated" } */ +typeof(x) y; /* { dg-warning "type is deprecated .declared at .*.: Do not use" } */ --- gcc/testsuite/gcc.dg/deprecated-6.c.deprecated 2009-05-07 13:14:39.000000000 -0700 +++ gcc/testsuite/gcc.dg/deprecated-6.c 2009-05-07 13:46:07.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 ("Do not use"))); + +void f(void) { + func(); /* { dg-warning "'func' is deprecated .declared at .*.: Do not use" } */ +} --- gcc/toplev.c.deprecated 2009-05-07 13:07:35.000000000 -0700 +++ gcc/toplev.c 2009-05-07 13:14:39.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-05-07 13:07:35.000000000 -0700 +++ gcc/toplev.h 2009-05-07 13:14:39.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