OSDN Git Service

gcc/
authorhjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 8 May 2009 18:44:50 +0000 (18:44 +0000)
committerhjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 8 May 2009 18:44:50 +0000 (18:44 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@147293 138bc75d-0d04-0410-961f-82ee72b054a4

17 files changed:
gcc/ChangeLog
gcc/c-common.c
gcc/c-decl.c
gcc/c-typeck.c
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/decl.c
gcc/cp/semantics.c
gcc/cp/typeck.c
gcc/doc/extend.texi
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/warn/deprecated-6.C [new file with mode: 0644]
gcc/testsuite/gcc.dg/deprecated-4.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/deprecated-5.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/deprecated-6.c [new file with mode: 0644]
gcc/toplev.c
gcc/toplev.h

index ec198ef..ae61006 100644 (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
 2009-05-08  Michael Eager <eager@eagercon.com>
 
        * config/rs6000/rs6000.md (*movdf_softfloat32): replace
index 9fa3b96..df6673c 100644 (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 },
      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 },
                              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,
 
 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;
 
                             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;
   if (DECL_P (*node))
     {
       tree decl = *node;
index 409c458..5b44153 100644 (file)
@@ -4220,7 +4220,7 @@ grokdeclarator (const struct c_declarator *declarator,
     decl_context = PARM;
 
   if (declspecs->deprecated_p && deprecated_state != DEPRECATED_SUPPRESS)
     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
 
   if ((decl_context == NORMAL || decl_context == FIELD)
       && current_scope == file_scope
index 4d07a88..0a29d95 100644 (file)
@@ -1964,7 +1964,7 @@ build_component_ref (tree datum, tree component)
            TREE_THIS_VOLATILE (ref) = 1;
 
          if (TREE_DEPRECATED (subdatum))
            TREE_THIS_VOLATILE (ref) = 1;
 
          if (TREE_DEPRECATED (subdatum))
-           warn_deprecated_use (subdatum);
+           warn_deprecated_use (subdatum, NULL_TREE);
 
          datum = ref;
 
 
          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))
     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) 
 
   /* Recursive call does not count as usage.  */
   if (ref != current_function_decl) 
index ca9c05a..cc7b5f7 100644 (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
 2009-05-06  Dodji Seketeli  <dodji@redhat.com>
 
        PR c++/17395
 2009-05-05  Shujing Zhao  <pearly.zhao@oracle.com>
 
        * cp-tree.h:
 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>
 
 
 2009-05-05  Nathan Sidwell  <nathan@codesourcery.com>
 
 
 2009-02-01  Paolo Carlini  <paolo.carlini@oracle.com>
 
 
 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>
 
 
 2009-01-30  Jakub Jelinek  <jakub@redhat.com>
 
index ca45bee..ba8dac1 100644 (file)
@@ -342,7 +342,7 @@ build_call_a (tree function, int n, tree *argarray)
     current_function_returns_abnormally = 1;
 
   if (decl && TREE_DEPRECATED (decl))
     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))
   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 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]))
 
       argarray[0] = build_base_path (PLUS_EXPR, argarray[0], binfo, 1);
       if (TREE_SIDE_EFFECTS (argarray[0]))
index e06dce2..fb91647 100644 (file)
@@ -7835,7 +7835,7 @@ grokdeclarator (const cp_declarator *declarator,
      suppress reports of deprecated items.  */
   if (type && TREE_DEPRECATED (type)
       && deprecated_state != DEPRECATED_SUPPRESS)
      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;
   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)
       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.  */
     }
   /* 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)
            {
              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
            }
 
          /* Top-level qualifiers on the parameters are
index 4c0c91d..8c0a1e5 100644 (file)
@@ -3038,7 +3038,7 @@ finish_id_expression (tree id_expression,
     }
 
   if (TREE_DEPRECATED (decl))
     }
 
   if (TREE_DEPRECATED (decl))
-    warn_deprecated_use (decl);
+    warn_deprecated_use (decl, NULL_TREE);
 
   return decl;
 }
 
   return decl;
 }
index e34d942..4486b90 100644 (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))
       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));
     }
   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))
     }
 
   if (TREE_DEPRECATED (member))
-    warn_deprecated_use (member);
+    warn_deprecated_use (member, NULL_TREE);
 
   if (template_p)
     check_template_keyword (member);
 
   if (template_p)
     check_template_keyword (member);
index 43bebf9..6b626e2 100644 (file)
@@ -2065,6 +2065,7 @@ objects (@pxref{C++ Attributes}).
 These attributes are not currently implemented for Objective-C@.
 
 @item deprecated
 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
 @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
 
 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}.)
 
 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
 @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
 @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
 
 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}.)
 
 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
 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.
 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
 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}.)
 
 The @code{deprecated} attribute can also be used for functions and
 variables (@pxref{Function Attributes}, @pxref{Variable Attributes}.)
index 5c8a16d..2e83302 100644 (file)
@@ -1,5 +1,13 @@
 2009-05-08  H.J. Lu  <hongjiu.lu@intel.com>
 
 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.
        * 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 (file)
index 0000000..8ce6ac0
--- /dev/null
@@ -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 (file)
index 0000000..f36dbdf
--- /dev/null
@@ -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 (file)
index 0000000..133e60e
--- /dev/null
@@ -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 (file)
index 0000000..874e1a6
--- /dev/null
@@ -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" } */
+}
index 1b850fa..68dc6a3 100644 (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 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 (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));
   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))
     {
     }
   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)
          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
          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)
        }
       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
          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");
+           }
        }
     }
 }
        }
     }
 }
index 28f5d0c..08a89ea 100644 (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 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
 extern bool parse_optimize_options (tree, bool);
 
 #ifdef BUFSIZ