mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-25 05:35:23 +08:00
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
This commit is contained in:
parent
c767899ef2
commit
3146f36f93
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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))
|
||||
|
@ -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",
|
||||
|
@ -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.
|
||||
|
19
gcc/testsuite/g++.dg/warn/Wunused-17.C
Normal file
19
gcc/testsuite/g++.dg/warn/Wunused-17.C
Normal file
@ -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; }
|
Loading…
Reference in New Issue
Block a user