re PR c/36892 (Support __attribute__((deprecated("text string"))))

gcc/

2009-05-08  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-08  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-08  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.

From-SVN: r147293
This commit is contained in:
H.J. Lu 2009-05-08 11:44:50 -07:00
parent 82ad047f00
commit 9b86d6bb25
17 changed files with 377 additions and 49 deletions

View File

@ -1,3 +1,25 @@
2009-05-08 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))
2009-05-08 Michael Eager <eager@eagercon.com>
* config/rs6000/rs6000.md (*movdf_softfloat32): replace

View File

@ -954,7 +954,7 @@ const struct attribute_spec c_common_attribute_table[] =
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, tree ARG_UNUSED (name),
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;

View File

@ -4220,7 +4220,7 @@ grokdeclarator (const struct c_declarator *declarator,
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

View File

@ -1964,7 +1964,7 @@ build_component_ref (tree datum, tree component)
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, location_t loc, tree *type)
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)

View File

@ -1,3 +1,14 @@
2009-05-08 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.
2009-05-06 Dodji Seketeli <dodji@redhat.com>
PR c++/17395
@ -7,23 +18,23 @@
2009-05-05 Shujing Zhao <pearly.zhao@oracle.com>
* cp-tree.h:
(opname_tab, assignop_tab, update_member_visibility, yyerror, yyhook,
mangle_compound_literal): Remove unused declarations.
(build_vfield_ref, cxx_print_statistics, clone_function_decl,
adjust_clone_args, maybe_push_cleanup_level, pushtag, make_anon_name,
pushdecl_top_level_maybe_friend, pushdecl_top_level_and_finish,
check_for_out_of_scope_variable, print_other_binding_stack,
maybe_push_decl, cxx_mark_addressable, force_target_expr,
build_target_expr_with_type, finish_case_label,
cxx_maybe_build_cleanup, begin_eh_spec_block, finish_eh_spec_block,
check_template_keyword, cxx_omp_predetermined_sharing,
cxx_omp_clause_default_ctor, cxx_omp_clause_copy_ctor,
cxx_omp_clause_assign_op, cxx_omp_clause_dtor, cxx_omp_finish_clause,
cxx_omp_privatize_by_reference): Rearrange the declarations line to
match the comment that indicates the .c file which the functions are
defined.
(cxx_print_xnode, cxx_print_decl, cxx_print_type,
cxx_print_identifier, cxx_print_error_function, pushdecl): Add comment.
(opname_tab, assignop_tab, update_member_visibility, yyerror, yyhook,
mangle_compound_literal): Remove unused declarations.
(build_vfield_ref, cxx_print_statistics, clone_function_decl,
adjust_clone_args, maybe_push_cleanup_level, pushtag, make_anon_name,
pushdecl_top_level_maybe_friend, pushdecl_top_level_and_finish,
check_for_out_of_scope_variable, print_other_binding_stack,
maybe_push_decl, cxx_mark_addressable, force_target_expr,
build_target_expr_with_type, finish_case_label,
cxx_maybe_build_cleanup, begin_eh_spec_block, finish_eh_spec_block,
check_template_keyword, cxx_omp_predetermined_sharing,
cxx_omp_clause_default_ctor, cxx_omp_clause_copy_ctor,
cxx_omp_clause_assign_op, cxx_omp_clause_dtor, cxx_omp_finish_clause,
cxx_omp_privatize_by_reference): Rearrange the declarations line to
match the comment that indicates the .c file which the functions are
defined.
(cxx_print_xnode, cxx_print_decl, cxx_print_type,
cxx_print_identifier, cxx_print_error_function, pushdecl): Add comment.
2009-05-05 Nathan Sidwell <nathan@codesourcery.com>
@ -821,9 +832,9 @@
2009-02-01 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/39053
* parser.c (cp_parser_pure_specifier): If there are no tokens left
do not call cp_lexer_consume_token.
PR c++/39053
* parser.c (cp_parser_pure_specifier): If there are no tokens left
do not call cp_lexer_consume_token.
2009-01-30 Jakub Jelinek <jakub@redhat.com>

View File

@ -342,7 +342,7 @@ build_call_a (tree function, int n, tree *argarray)
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 *cand, int flags, tsubst_flags_t complain)
/* 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]))

View File

@ -7835,7 +7835,7 @@ grokdeclarator (const cp_declarator *declarator,
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 *declarator,
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

View File

@ -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;
}

View File

@ -1909,7 +1909,7 @@ build_class_member_access_expr (tree object, tree member,
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 object, tree name, bool template_p,
}
if (TREE_DEPRECATED (member))
warn_deprecated_use (member);
warn_deprecated_use (member, NULL_TREE);
if (template_p)
check_template_keyword (member);

View File

@ -2065,6 +2065,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
@ -2080,7 +2081,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}.)
@ -3845,6 +3848,7 @@ These attributes override the default chosen by the
@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
@ -3860,7 +3864,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}.)
@ -4490,6 +4496,7 @@ not referenced, but contain constructors and destructors that have
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.
@ -4512,7 +4519,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}.)

View File

@ -1,3 +1,11 @@
2009-05-08 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.
2009-05-08 H.J. Lu <hongjiu.lu@intel.com>
* gcc.dg/vect/no-vfa-vect-37.c: Replace __aligned__(16) with

View File

@ -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::<anonymous union>::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" "" } */
}

View File

@ -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" "" } */

View File

@ -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 ("Do not use"))) x; /* { dg-warning "type is deprecated" } */
typeof(x) y; /* { dg-warning "type is deprecated .declared at .*.: Do not use" } */

View File

@ -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" } */
}

View File

@ -908,17 +908,45 @@ emit_debug_global_declarations (tree *vec, int len)
/* 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");
}
}
}
}

View File

@ -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