OSDN Git Service

PR c++/41109
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 24 Aug 2009 21:31:54 +0000 (21:31 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 24 Aug 2009 21:31:54 +0000 (21:31 +0000)
PR c++/41110
PR c++/41134
* cp-tree.h (DECL_ODR_USED): New macro.
(struct lang_decl_base): Add odr_used flag.
* decl.c (duplicate_decls): Propagate it.  Use it for error.
* pt.c (register_specialization): Use it for error.
* decl2.c (mark_used): Use it as gating flag rather than TREE_USED.
(cp_write_global_declarations): Use it for error.
(tree_used_ok): Remove.
* cp-tree.h: Remove tree_used_ok.
* call.c (build_call_a): Don't call it.
* init.c (build_offset_ref): Likewise.

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

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/init.c
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/warn/Wunused-17.C [new file with mode: 0644]

index 545ac18..8c555e6 100644 (file)
@@ -1,3 +1,19 @@
+2009-08-21  Jason Merrill  <jason@redhat.com>
+
+       PR c++/41109
+       PR c++/41110
+       PR c++/41134
+       * cp-tree.h (DECL_ODR_USED): New macro.
+       (struct lang_decl_base): Add odr_used flag.
+       * decl.c (duplicate_decls): Propagate it.  Use it for error.
+       * pt.c (register_specialization): Use it for error.
+       * decl2.c (mark_used): Use it as gating flag rather than TREE_USED.
+       (cp_write_global_declarations): Use it for error.
+       (tree_used_ok): Remove.
+       * cp-tree.h: Remove tree_used_ok.
+       * call.c (build_call_a): Don't call it.
+       * init.c (build_offset_ref): Likewise.
+
 2009-08-21  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/41131
 2009-08-21  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/41131
index 30a1b45..f6a083b 100644 (file)
@@ -318,7 +318,7 @@ build_call_a (tree function, int n, tree *argarray)
       && TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL)
     {
       decl = TREE_OPERAND (function, 0);
       && TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL)
     {
       decl = TREE_OPERAND (function, 0);
-      if (!tree_used_ok (decl))
+      if (!TREE_USED (decl))
        {
          /* We invoke build_call directly for several library
             functions.  These may have been declared normally if
        {
          /* We invoke build_call directly for several library
             functions.  These may have been declared normally if
index bbd1a42..bafe033 100644 (file)
@@ -1579,8 +1579,9 @@ struct GTY(()) lang_decl_base {
   unsigned anticipated_p : 1;             /* fn or type */
   unsigned friend_attr : 1;               /* fn or type */
   unsigned template_conv_p : 1;                   /* template only? */
   unsigned anticipated_p : 1;             /* fn or type */
   unsigned friend_attr : 1;               /* fn or type */
   unsigned template_conv_p : 1;                   /* template only? */
+  unsigned odr_used : 1;                  /* var or fn */
   unsigned u2sel : 1;
   unsigned u2sel : 1;
-  /* 2 spare bits */
+  /* 1 spare bit */
 };
 
 /* True for DECL codes which have template info and access.  */
 };
 
 /* True for DECL codes which have template info and access.  */
@@ -1982,6 +1983,12 @@ struct GTY(()) lang_decl {
   (DECL_LANG_SPECIFIC (VAR_OR_FUNCTION_DECL_CHECK (DECL)) \
    ->u.base.initialized_in_class)
 
   (DECL_LANG_SPECIFIC (VAR_OR_FUNCTION_DECL_CHECK (DECL)) \
    ->u.base.initialized_in_class)
 
+/* Nonzero if the DECL is used in the sense of 3.2 [basic.def.odr].
+   Only available for decls with DECL_LANG_SPECIFIC.  */
+#define DECL_ODR_USED(DECL) \
+  (DECL_LANG_SPECIFIC (VAR_OR_FUNCTION_DECL_CHECK (DECL)) \
+   ->u.base.odr_used)
+
 /* Nonzero for DECL means that this decl is just a friend declaration,
    and should not be added to the list of members for this class.  */
 #define DECL_FRIEND_P(NODE) (DECL_LANG_SPECIFIC (NODE)->u.base.friend_attr)
 /* Nonzero for DECL means that this decl is just a friend declaration,
    and should not be added to the list of members for this class.  */
 #define DECL_FRIEND_P(NODE) (DECL_LANG_SPECIFIC (NODE)->u.base.friend_attr)
@@ -4477,7 +4484,6 @@ extern tree build_cleanup                 (tree);
 extern tree build_offset_ref_call_from_tree    (tree, VEC(tree,gc) **);
 extern void check_default_args                 (tree);
 extern void mark_used                          (tree);
 extern tree build_offset_ref_call_from_tree    (tree, VEC(tree,gc) **);
 extern void check_default_args                 (tree);
 extern void mark_used                          (tree);
-extern bool tree_used_ok                       (tree);
 extern void finish_static_data_member_decl     (tree, tree, bool, tree, int);
 extern tree cp_build_parm_decl                 (tree, tree);
 extern tree get_guard                          (tree);
 extern void finish_static_data_member_decl     (tree, tree, bool, tree, int);
 extern tree cp_build_parm_decl                 (tree, tree);
 extern tree get_guard                          (tree);
index 0746b82..cad0fc5 100644 (file)
@@ -1890,6 +1890,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
        }
       DECL_TEMPLATE_INSTANTIATED (newdecl)
        |= DECL_TEMPLATE_INSTANTIATED (olddecl);
        }
       DECL_TEMPLATE_INSTANTIATED (newdecl)
        |= DECL_TEMPLATE_INSTANTIATED (olddecl);
+      DECL_ODR_USED (newdecl) |= DECL_ODR_USED (olddecl);
 
       /* If the OLDDECL is an instantiation and/or specialization,
         then the NEWDECL must be too.  But, it may not yet be marked
 
       /* If the OLDDECL is an instantiation and/or specialization,
         then the NEWDECL must be too.  But, it may not yet be marked
@@ -1955,7 +1956,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
             should have exited above, returning 0.  */
          gcc_assert (DECL_TEMPLATE_SPECIALIZATION (newdecl));
 
             should have exited above, returning 0.  */
          gcc_assert (DECL_TEMPLATE_SPECIALIZATION (newdecl));
 
-         if (TREE_USED (olddecl))
+         if (DECL_ODR_USED (olddecl))
            /* From [temp.expl.spec]:
 
               If a template, a member template or the member of a class
            /* From [temp.expl.spec]:
 
               If a template, a member template or the member of a class
index 9aa8ef1..960ccf0 100644 (file)
@@ -3631,7 +3631,7 @@ cp_write_global_declarations (void)
   for (i = 0; VEC_iterate (tree, deferred_fns, i, decl); ++i)
     {
       if (/* Check online inline functions that were actually used.  */
   for (i = 0; VEC_iterate (tree, deferred_fns, i, decl); ++i)
     {
       if (/* Check online inline functions that were actually used.  */
-         TREE_USED (decl) && DECL_DECLARED_INLINE_P (decl)
+         DECL_ODR_USED (decl) && DECL_DECLARED_INLINE_P (decl)
          /* If the definition actually was available here, then the
             fact that the function was not defined merely represents
             that for some reason (use of a template repository,
          /* If the definition actually was available here, then the
             fact that the function was not defined merely represents
             that for some reason (use of a template repository,
@@ -3845,22 +3845,33 @@ mark_used (tree decl)
       decl = OVL_CURRENT (decl);
     }
 
       decl = OVL_CURRENT (decl);
     }
 
+  /* Set TREE_USED for the benefit of -Wunused.  */
+  TREE_USED (decl) = 1;
+  if (DECL_CLONED_FUNCTION_P (decl))
+    TREE_USED (DECL_CLONED_FUNCTION (decl)) = 1;
+
   if (TREE_CODE (decl) == FUNCTION_DECL
       && DECL_DELETED_FN (decl))
     {
       error ("deleted function %q+D", decl);
       error ("used here");
   if (TREE_CODE (decl) == FUNCTION_DECL
       && DECL_DELETED_FN (decl))
     {
       error ("deleted function %q+D", decl);
       error ("used here");
-      TREE_USED (decl) = 1;
       return;
     }
   /* If we don't need a value, then we don't need to synthesize DECL.  */
   if (cp_unevaluated_operand != 0)
     return;
 
       return;
     }
   /* If we don't need a value, then we don't need to synthesize DECL.  */
   if (cp_unevaluated_operand != 0)
     return;
 
+  /* We can only check DECL_ODR_USED on variables or functions with
+     DECL_LANG_SPECIFIC set, and these are also the only decls that we
+     might need special handling for.  */
+  if ((TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL)
+      || DECL_LANG_SPECIFIC (decl) == NULL)
+    return;
+
   /* We only want to do this processing once.  We don't need to keep trying
      to instantiate inline templates, because unit-at-a-time will make sure
      we get them compiled before functions that want to inline them.  */
   /* We only want to do this processing once.  We don't need to keep trying
      to instantiate inline templates, because unit-at-a-time will make sure
      we get them compiled before functions that want to inline them.  */
-  if (TREE_USED (decl))
+  if (DECL_ODR_USED (decl))
     return;
 
   /* If within finish_function, defer the rest until that function
     return;
 
   /* If within finish_function, defer the rest until that function
@@ -3896,9 +3907,9 @@ mark_used (tree decl)
   if (processing_template_decl)
     return;
 
   if (processing_template_decl)
     return;
 
-  TREE_USED (decl) = 1;
+  DECL_ODR_USED (decl) = 1;
   if (DECL_CLONED_FUNCTION_P (decl))
   if (DECL_CLONED_FUNCTION_P (decl))
-    TREE_USED (DECL_CLONED_FUNCTION (decl)) = 1;
+    DECL_ODR_USED (DECL_CLONED_FUNCTION (decl)) = 1;
 
   /* DR 757: A type without linkage shall not be used as the type of a
      variable or function with linkage, unless
 
   /* DR 757: A type without linkage shall not be used as the type of a
      variable or function with linkage, unless
@@ -3981,15 +3992,4 @@ mark_used (tree decl)
   processing_template_decl = saved_processing_template_decl;
 }
 
   processing_template_decl = saved_processing_template_decl;
 }
 
-/* Use this function to verify that mark_used has been called
-   previously.  That is, either TREE_USED is set, or we're in a
-   context that doesn't set it.  */
-
-bool
-tree_used_ok (tree decl)
-{
-  return (TREE_USED (decl) || cp_unevaluated_operand
-         || defer_mark_used_calls || processing_template_decl);
-}
-
 #include "gt-cp-decl2.h"
 #include "gt-cp-decl2.h"
index 9dac7de..ef18a6c 100644 (file)
@@ -1502,7 +1502,7 @@ build_offset_ref (tree type, tree member, bool address_p)
 
   gcc_assert (DECL_P (member) || BASELINK_P (member));
   /* Callers should call mark_used before this point.  */
 
   gcc_assert (DECL_P (member) || BASELINK_P (member));
   /* Callers should call mark_used before this point.  */
-  gcc_assert (!DECL_P (member) || tree_used_ok (member));
+  gcc_assert (!DECL_P (member) || TREE_USED (member));
 
   if (!COMPLETE_TYPE_P (complete_type (type))
       && !TYPE_BEING_DEFINED (type))
 
   if (!COMPLETE_TYPE_P (complete_type (type))
       && !TYPE_BEING_DEFINED (type))
index eb43271..b856140 100644 (file)
@@ -1296,7 +1296,7 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend,
     {
       if (DECL_TEMPLATE_INSTANTIATION (fn))
        {
     {
       if (DECL_TEMPLATE_INSTANTIATION (fn))
        {
-         if (TREE_USED (fn)
+         if (DECL_ODR_USED (fn)
              || DECL_EXPLICIT_INSTANTIATION (fn))
            {
              error ("specialization of %qD after instantiation",
              || DECL_EXPLICIT_INSTANTIATION (fn))
            {
              error ("specialization of %qD after instantiation",
index 3716a90..4aa4154 100644 (file)
@@ -1,3 +1,7 @@
+2009-08-21  Jason Merrill  <jason@redhat.com>
+
+       * g++.dg/warn/Wunused-17.C: New.
+
 2009-08-11  Ramana Radhakrishnan  <ramana.radhakrishnan@arm.com>
 
        * gcc.target/arm/combine-cmp-shift.c: New test.
 2009-08-11  Ramana Radhakrishnan  <ramana.radhakrishnan@arm.com>
 
        * gcc.target/arm/combine-cmp-shift.c: New test.
diff --git a/gcc/testsuite/g++.dg/warn/Wunused-17.C b/gcc/testsuite/g++.dg/warn/Wunused-17.C
new file mode 100644 (file)
index 0000000..217bb4b
--- /dev/null
@@ -0,0 +1,19 @@
+// PR c++/41109, 41110, 41134
+// { dg-options "-Wunused" }
+
+int memory_consumption(const int &t) { return sizeof(t); }
+
+int s;
+int g() { return memory_consumption(s); }
+
+template <int> struct X { static const int s = 2; };
+
+template <typename T> int f() {
+  const unsigned int dim = 2;
+  return X<dim>::s;
+}
+
+template int f<int>();
+
+static int i;
+template <typename> int h() { return i; }