diff options
-rw-r--r-- | gcc/ChangeLog | 22 | ||||
-rw-r--r-- | gcc/c-common.c | 12 | ||||
-rw-r--r-- | gcc/c-decl.c | 2 | ||||
-rw-r--r-- | gcc/c-typeck.c | 4 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 51 | ||||
-rw-r--r-- | gcc/cp/call.c | 4 | ||||
-rw-r--r-- | gcc/cp/decl.c | 6 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 2 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 4 | ||||
-rw-r--r-- | gcc/doc/extend.texi | 15 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/deprecated-6.C | 110 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/deprecated-4.c | 88 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/deprecated-5.c | 7 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/deprecated-6.c | 11 | ||||
-rw-r--r-- | gcc/toplev.c | 78 | ||||
-rw-r--r-- | gcc/toplev.h | 2 |
17 files changed, 377 insertions, 49 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ec198ef..ae61006 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/c-common.c b/gcc/c-common.c index 9fa3b96..df6673c 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -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; diff --git a/gcc/c-decl.c b/gcc/c-decl.c index 409c458..5b44153 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -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 diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 4d07a88..0a29d95 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -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) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ca9c05a..cc7b5f7 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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> diff --git a/gcc/cp/call.c b/gcc/cp/call.c index ca45bee..ba8dac1 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -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])) diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index e06dce2..fb91647 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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 diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 4c0c91d..8c0a1e5 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -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; } diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index e34d942..4486b90 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -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); diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 43bebf9..6b626e2 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -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}.) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5c8a16d..2e83302 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,13 @@ 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 __aligned__(__BIGGEST_ALIGNMENT__). * gcc.dg/vect/no-vfa-vect-43.c: Likewise. diff --git a/gcc/testsuite/g++.dg/warn/deprecated-6.C b/gcc/testsuite/g++.dg/warn/deprecated-6.C new file mode 100644 index 0000000..8ce6ac0 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/deprecated-6.C @@ -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" "" } */ +} diff --git a/gcc/testsuite/gcc.dg/deprecated-4.c b/gcc/testsuite/gcc.dg/deprecated-4.c new file mode 100644 index 0000000..f36dbdf --- /dev/null +++ b/gcc/testsuite/gcc.dg/deprecated-4.c @@ -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" "" } */ diff --git a/gcc/testsuite/gcc.dg/deprecated-5.c b/gcc/testsuite/gcc.dg/deprecated-5.c new file mode 100644 index 0000000..133e60e --- /dev/null +++ b/gcc/testsuite/gcc.dg/deprecated-5.c @@ -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" } */ diff --git a/gcc/testsuite/gcc.dg/deprecated-6.c b/gcc/testsuite/gcc.dg/deprecated-6.c new file mode 100644 index 0000000..874e1a6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/deprecated-6.c @@ -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" } */ +} diff --git a/gcc/toplev.c b/gcc/toplev.c index 1b850fa..68dc6a3 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -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"); + } } } } diff --git a/gcc/toplev.h b/gcc/toplev.h index 28f5d0c..08a89ea 100644 --- a/gcc/toplev.h +++ b/gcc/toplev.h @@ -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 |