aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog22
-rw-r--r--gcc/c-common.c12
-rw-r--r--gcc/c-decl.c2
-rw-r--r--gcc/c-typeck.c4
-rw-r--r--gcc/cp/ChangeLog51
-rw-r--r--gcc/cp/call.c4
-rw-r--r--gcc/cp/decl.c6
-rw-r--r--gcc/cp/semantics.c2
-rw-r--r--gcc/cp/typeck.c4
-rw-r--r--gcc/doc/extend.texi15
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/g++.dg/warn/deprecated-6.C110
-rw-r--r--gcc/testsuite/gcc.dg/deprecated-4.c88
-rw-r--r--gcc/testsuite/gcc.dg/deprecated-5.c7
-rw-r--r--gcc/testsuite/gcc.dg/deprecated-6.c11
-rw-r--r--gcc/toplev.c78
-rw-r--r--gcc/toplev.h2
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