aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2009-08-24 17:31:54 -0400
committerJason Merrill <jason@gcc.gnu.org>2009-08-24 17:31:54 -0400
commit3146f36f935b0594a4719320e891e2d7524c014c (patch)
tree21f3fafc0a9586551eed28be49bc928210769cec
parentc767899ef26cac6092786591518ff9e5a54dbe04 (diff)
downloadgcc-3146f36f935b0594a4719320e891e2d7524c014c.zip
gcc-3146f36f935b0594a4719320e891e2d7524c014c.tar.gz
gcc-3146f36f935b0594a4719320e891e2d7524c014c.tar.bz2
re PR c++/41109 (Argument flagged as unused despite use in sizeof())
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. From-SVN: r151061
-rw-r--r--gcc/cp/ChangeLog16
-rw-r--r--gcc/cp/call.c2
-rw-r--r--gcc/cp/cp-tree.h10
-rw-r--r--gcc/cp/decl.c3
-rw-r--r--gcc/cp/decl2.c32
-rw-r--r--gcc/cp/init.c2
-rw-r--r--gcc/cp/pt.c2
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.dg/warn/Wunused-17.C19
9 files changed, 68 insertions, 22 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 545ac18..8c555e6 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 30a1b45..f6a083b 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -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);
- 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
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index bbd1a42..bafe033 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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 odr_used : 1; /* var or fn */
unsigned u2sel : 1;
- /* 2 spare bits */
+ /* 1 spare bit */
};
/* 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)
+/* 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)
@@ -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 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);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 0746b82..cad0fc5 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -1890,6 +1890,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
}
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
@@ -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));
- 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
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 9aa8ef1..960ccf0 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -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. */
- 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,
@@ -3845,22 +3845,33 @@ mark_used (tree 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");
- 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;
+ /* 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. */
- if (TREE_USED (decl))
+ if (DECL_ODR_USED (decl))
return;
/* If within finish_function, defer the rest until that function
@@ -3896,9 +3907,9 @@ mark_used (tree decl)
if (processing_template_decl)
return;
- TREE_USED (decl) = 1;
+ DECL_ODR_USED (decl) = 1;
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
@@ -3981,15 +3992,4 @@ mark_used (tree 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"
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 9dac7de..ef18a6c 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -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) || tree_used_ok (member));
+ gcc_assert (!DECL_P (member) || TREE_USED (member));
if (!COMPLETE_TYPE_P (complete_type (type))
&& !TYPE_BEING_DEFINED (type))
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index eb43271..b856140 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -1296,7 +1296,7 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend,
{
if (DECL_TEMPLATE_INSTANTIATION (fn))
{
- if (TREE_USED (fn)
+ if (DECL_ODR_USED (fn)
|| DECL_EXPLICIT_INSTANTIATION (fn))
{
error ("specialization of %qD after instantiation",
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 3716a90..4aa4154 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/g++.dg/warn/Wunused-17.C b/gcc/testsuite/g++.dg/warn/Wunused-17.C
new file mode 100644
index 0000000..217bb4b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wunused-17.C
@@ -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; }