C++ support for -Wunused-but-set-variable

gcc/cp/ChangeLog:
	PR 18624
	* cp-tree.h (mark_exp_read, mark_rvalue_use, mark_lvalue_use,
	mark_type_use): Declare ...
	* expr.c (mark_exp_read, mark_rvalue_use, mark_lvalue_use,
	mark_type_use): ... new fns.
	* typeck.c (cxx_sizeof_expr, cxx_alignof_expr): Call mark_type_use.
	(perform_integral_promotions): Call mark_rvalue_use.
	(cp_build_unary_op): Call mark_lvalue_use.
	(decay_conversion): Update comment. Call mark_lvalue.
	* decl.c (unused_but_set_errorcount): New variable.
	(poplevel): Issue -Wunused-but-set-variable diagnostics.
	(duplicate_decls): Merge DECL_READ_P flags.
	(start_cleanup_fn): Set DECL_READ_P flag.
	(finish_function): Issue -Wunused-but-set-parameter diagnostics.
	* tree.c (rvalue): Call mark_rvalue_use.
	* pt.c (convert_nontype_argument): Likewise.
	* semantics.c (finish_typeof, finish_decltype_type): Call
	mark_type_use.
	(finish_asm_stmt): Call mark_lvalue_use.
	(finish_expr_stmt): Call mark_exp_read.
	* call.c (convert_like_real) <ck_identity, ck_user>: Call
	mark_rvalue_use.
	(build_x_va_arg): Call mark_lvalue_use.
	(build_over_call): Call mark_type_use.
	* init.c (build_new, build_delete): Call mark_value_use.
	* rtti.c (build_typeid): Call mark_lvalue_use or mark_type_use.
	(build_dynamic_cast_1): call mark_lvalue_use or mark_rvalue_use.

gcc/testsuite/ChangeLog:
	PR 18624
	* g++.dg/warn/Wunused-7.C: Add dg-warning.
	* g++.dg/template/sfinae16.C: Likewise.
	* gcc.dg/Wunused-var-1.c: Moved to...
	* c-c++-common/Wunused-var-1.c: ...here. New test.
	* gcc.dg/Wunused-var-2.c: Moved to...
	* c-c++-common/Wunused-var-2.c: ...here. New test.
	* gcc.dg/Wunused-var-3.c: Moved to...
	* c-c++-common/Wunused-var-3.c: ...here. New test.
	* gcc.dg/Wunused-var-4.c: Moved to...
	* gcc.dg/Wunused-var-1.c: ... here.
	* gcc.dg/Wunused-var-5.c: Moved to...
	* c-c++-common/Wunused-var-4.c: ...here. New test.
	* gcc.dg/Wunused-var-7.c: Moved to...
	* c-c++-common/Wunused-var-5.c: ...here. New test.
	* gcc.dg/Wunused-var-6.c: Moved to...
	* gcc.dg/Wunused-var-2.c: ... here.
	* c-c++-common/Wunused-var-1.c: New test.
	* c-c++-common/Wunused-var-2.c: New test.
	* c-c++-common/Wunused-var-3.c: New test.
	* c-c++-common/Wunused-var-4.c: New test.
	* c-c++-common/Wunused-var-5.c: New test.
	* g++.dg/warn/Wunused-var-1.C: New test.
	* g++.dg/warn/Wunused-var-2.C: New test.
	* g++.dg/warn/Wunused-var-3.C: New test.
	* g++.dg/warn/Wunused-var-4.C: New test.
	* g++.dg/warn/Wunused-var-5.C: New test.
	* g++.dg/warn/Wunused-var-6.C: New test.
	* g++.dg/warn/Wunused-var-7.C: New test.
	* g++.dg/warn/Wunused-var-8.C: New test.
	* g++.dg/warn/Wunused-parm-1.C: New test.
	* g++.dg/warn/Wunused-parm-2.C: New test.
	* g++.dg/warn/Wunused-parm-3.C: New test.

Co-Authored-By: Dodji Seketeli <dodji@redhat.com>

From-SVN: r159096
This commit is contained in:
Jakub Jelinek 2010-05-06 08:52:30 +02:00 committed by Dodji Seketeli
parent 7d8930a046
commit 03a904b5a6
35 changed files with 1274 additions and 234 deletions

View file

@ -1,3 +1,28 @@
2010-04-22 Jakub Jelinek <jakub@redhat.com>
Dodji Seketeli <dodji@redhat.com>
PR c/18624
* cp-tree.h (mark_exp_read, rvalue_use, lvalue_use, type_use):
Declare ...
* expr.c (mark_exp_read, rvalue_use, lvalue_use, type_use): ... new fns.
* typeck.c (cxx_sizeof_expr, cxx_alignof_expr): Call type_use.
(decay_conversion, perform_integral_promotions): Call rvalue_use.
(cp_build_unary_op): Call lvalue_use.
* decl.c (unused_but_set_errorcount): New variable.
(poplevel): Issue -Wunused-but-set-variable diagnostics.
(duplicate_decls): Merge DECL_READ_P flags.
(start_cleanup_fn): Set DECL_READ_P flag.
(finish_function): Issue -Wunused-but-set-parameter diagnostics.
* tree.c (rvalue): Call rvalue_use.
* pt.c (convert_nontype_argument): Likewise.
* semantics.c (finish_expr_stmt, finish_asm_stmt, finish_typeof,
finish_decltype_type): Likewise.
* call.c (convert_like_real) <ck_identity, ck_user>: Call rvalue use.
(build_x_va_arg, build_new_method_call, build_over_call): Call lvalue_use
or rvalue_use depending on the expr.
* init.c (build_new, build_delete): Likewise.
* rtti.c (build_typeid, build_dynamic_cast_1): Likewise.
2010-05-05 Jason Merrill <jason@redhat.com>
PR c++/43787

View file

@ -4888,6 +4888,8 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
tree convfn = cand->fn;
unsigned i;
expr = mark_rvalue_use (expr);
/* When converting from an init list we consider explicit
constructors, but actually trying to call one is an error. */
if (DECL_NONCONVERTING_P (convfn) && DECL_CONSTRUCTOR_P (convfn))
@ -4920,6 +4922,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
return expr;
}
case ck_identity:
expr = mark_rvalue_use (expr);
if (BRACE_ENCLOSED_INITIALIZER_P (expr))
{
int nelts = CONSTRUCTOR_NELTS (expr);
@ -5230,6 +5233,8 @@ build_x_va_arg (tree expr, tree type)
if (expr == error_mark_node || !type)
return error_mark_node;
expr = mark_lvalue_use (expr);
if (type_has_nontrivial_copy_init (type)
|| TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
|| TREE_CODE (type) == REFERENCE_TYPE)
@ -5698,7 +5703,8 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
{
tree a = VEC_index (tree, args, arg_index);
if (magic_varargs_p (fn))
/* Do no conversions for magic varargs. */;
/* Do no conversions for magic varargs. */
a = mark_type_use (a);
else
a = convert_arg_to_ellipsis (a);
argarray[j++] = a;

View file

@ -4815,6 +4815,10 @@ extern tree build_eh_type_type (tree);
/* in expr.c */
extern tree cplus_expand_constant (tree);
extern tree mark_rvalue_use (tree);
extern tree mark_lvalue_use (tree);
extern tree mark_type_use (tree);
extern void mark_exp_read (tree);
/* friend.c */
extern int is_friend (tree, tree);

View file

@ -498,6 +498,10 @@ poplevel_named_label_1 (void **slot, void *data)
return 1;
}
/* Saved errorcount to avoid -Wunused-but-set-{parameter,variable} warnings
when errors were reported, except for -Werror-unused-but-set-*. */
static int unused_but_set_errorcount;
/* Exit a binding level.
Pop the level off, and restore the state of the identifier-decl mappings
that were in effect when this level was entered.
@ -589,14 +593,28 @@ poplevel (int keep, int reverse, int functionbody)
= current_binding_level->kind == sk_for && flag_new_for_scope == 1;
/* Before we remove the declarations first check for unused variables. */
if (warn_unused_variable
if ((warn_unused_variable || warn_unused_but_set_variable)
&& !processing_template_decl)
for (decl = getdecls (); decl; decl = TREE_CHAIN (decl))
if (TREE_CODE (decl) == VAR_DECL
&& ! TREE_USED (decl)
&& (! TREE_USED (decl) || !DECL_READ_P (decl))
&& ! DECL_IN_SYSTEM_HEADER (decl)
&& DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl))
warning (OPT_Wunused_variable, "unused variable %q+D", decl);
{
if (! TREE_USED (decl))
warning (OPT_Wunused_variable, "unused variable %q+D", decl);
else if (DECL_CONTEXT (decl) == current_function_decl
&& TREE_TYPE (decl) != error_mark_node
&& TREE_CODE (TREE_TYPE (decl)) != REFERENCE_TYPE
&& errorcount == unused_but_set_errorcount
&& (!CLASS_TYPE_P (TREE_TYPE (decl))
|| !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl))))
{
warning (OPT_Wunused_but_set_variable,
"variable %q+D set but not used", decl);
unused_but_set_errorcount = errorcount;
}
}
/* Remove declarations for all the DECLs in this level. */
for (link = decls; link; link = TREE_CHAIN (link))
@ -2096,6 +2114,13 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
TREE_USED (newdecl) = 1;
else if (TREE_USED (newdecl))
TREE_USED (olddecl) = 1;
if (TREE_CODE (newdecl) == VAR_DECL)
{
if (DECL_READ_P (olddecl))
DECL_READ_P (newdecl) = 1;
else if (DECL_READ_P (newdecl))
DECL_READ_P (olddecl) = 1;
}
if (DECL_PRESERVE_P (olddecl))
DECL_PRESERVE_P (newdecl) = 1;
else if (DECL_PRESERVE_P (newdecl))
@ -6181,6 +6206,7 @@ start_cleanup_fn (void)
parmdecl = cp_build_parm_decl (NULL_TREE, ptr_type_node);
DECL_CONTEXT (parmdecl) = fndecl;
TREE_USED (parmdecl) = 1;
DECL_READ_P (parmdecl) = 1;
DECL_ARGUMENTS (fndecl) = parmdecl;
}
@ -12596,6 +12622,33 @@ finish_function (int flags)
info for the epilogue. */
cfun->function_end_locus = input_location;
/* Complain about parameters that are only set, but never otherwise used. */
if (warn_unused_but_set_parameter
&& !processing_template_decl
&& errorcount == unused_but_set_errorcount
&& !DECL_CLONED_FUNCTION_P (fndecl))
{
tree decl;
for (decl = DECL_ARGUMENTS (fndecl);
decl;
decl = TREE_CHAIN (decl))
if (TREE_USED (decl)
&& TREE_CODE (decl) == PARM_DECL
&& !DECL_READ_P (decl)
&& DECL_NAME (decl)
&& !DECL_ARTIFICIAL (decl)
&& !TREE_NO_WARNING (decl)
&& !DECL_IN_SYSTEM_HEADER (decl)
&& TREE_TYPE (decl) != error_mark_node
&& TREE_CODE (TREE_TYPE (decl)) != REFERENCE_TYPE
&& (!CLASS_TYPE_P (TREE_TYPE (decl))
|| !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl))))
warning (OPT_Wunused_but_set_parameter,
"parameter %q+D set but not used", decl);
unused_but_set_errorcount = errorcount;
}
/* Genericize before inlining. */
if (!processing_template_decl)
{

View file

@ -369,6 +369,7 @@ initialize_handler_parm (tree decl, tree exp)
/* Make sure we mark the catch param as used, otherwise we'll get a
warning about an unused ((anonymous)). */
TREE_USED (decl) = 1;
DECL_READ_P (decl) = 1;
/* Figure out the type that the initializer is. Pointers are returned
adjusted by value from __cxa_begin_catch. Others are returned by

View file

@ -82,3 +82,71 @@ cplus_expand_constant (tree cst)
return cst;
}
/* Called whenever an expression is used
in a rvalue context. */
tree
mark_rvalue_use (tree expr)
{
mark_exp_read (expr);
return expr;
}
/* Called whenever an expression is used
in a lvalue context. */
tree
mark_lvalue_use (tree expr)
{
mark_exp_read (expr);
return expr;
}
/* Called whenever an expression is used in a type use context. */
tree
mark_type_use (tree expr)
{
mark_exp_read (expr);
return expr;
}
/* Mark EXP as read, not just set, for set but not used -Wunused
warning purposes. */
void
mark_exp_read (tree exp)
{
if (exp == NULL)
return;
switch (TREE_CODE (exp))
{
case VAR_DECL:
case PARM_DECL:
DECL_READ_P (exp) = 1;
break;
case ARRAY_REF:
case COMPONENT_REF:
case MODIFY_EXPR:
case REALPART_EXPR:
case IMAGPART_EXPR:
CASE_CONVERT:
case ADDR_EXPR:
mark_exp_read (TREE_OPERAND (exp, 0));
break;
case COMPOUND_EXPR:
mark_exp_read (TREE_OPERAND (exp, 1));
break;
case COND_EXPR:
if (TREE_OPERAND (exp, 1))
mark_exp_read (TREE_OPERAND (exp, 1));
if (TREE_OPERAND (exp, 2))
mark_exp_read (TREE_OPERAND (exp, 2));
break;
default:
break;
}
}

View file

@ -2465,6 +2465,7 @@ build_new (VEC(tree,gc) **placement, tree type, tree nelts,
else
return error_mark_node;
}
nelts = mark_rvalue_use (nelts);
nelts = cp_save_expr (cp_convert (sizetype, nelts));
}
@ -3120,6 +3121,8 @@ build_delete (tree type, tree addr, special_function_kind auto_delete,
type = TYPE_MAIN_VARIANT (type);
addr = mark_rvalue_use (addr);
if (TREE_CODE (type) == POINTER_TYPE)
{
bool complete_p = true;

View file

@ -4930,6 +4930,7 @@ convert_nontype_argument (tree type, tree expr)
if (error_operand_p (expr))
return error_mark_node;
expr_type = TREE_TYPE (expr);
expr = mark_rvalue_use (expr);
/* HACK: Due to double coercion, we can get a
NOP_EXPR<REFERENCE_TYPE>(ADDR_EXPR<POINTER_TYPE> (arg)) here,

View file

@ -318,7 +318,7 @@ typeid_ok_p (void)
tree
build_typeid (tree exp)
{
tree cond = NULL_TREE;
tree cond = NULL_TREE, initial_expr = exp;
int nonnull = 0;
if (exp == error_mark_node || !typeid_ok_p ())
@ -333,6 +333,9 @@ build_typeid (tree exp)
&& ! resolves_to_fixed_type_p (exp, &nonnull)
&& ! nonnull)
{
/* So we need to look into the vtable of the type of exp.
This is an lvalue use of expr then. */
exp = mark_lvalue_use (exp);
exp = stabilize_reference (exp);
cond = cp_convert (boolean_type_node, TREE_OPERAND (exp, 0));
}
@ -348,6 +351,8 @@ build_typeid (tree exp)
exp = build3 (COND_EXPR, TREE_TYPE (exp), cond, exp, bad);
}
else
mark_type_use (initial_expr);
return exp;
}
@ -546,6 +551,8 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain)
/* If T is a pointer type, v shall be an rvalue of a pointer to
complete class type, and the result is an rvalue of type T. */
expr = mark_rvalue_use (expr);
if (TREE_CODE (exprtype) != POINTER_TYPE)
{
errstr = _("source is not a pointer");
@ -564,6 +571,8 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain)
}
else
{
expr = mark_lvalue_use (expr);
exprtype = build_reference_type (exprtype);
/* T is a reference type, v shall be an lvalue of a complete class

View file

@ -610,6 +610,13 @@ finish_expr_stmt (tree expr)
{
if (warn_sequence_point)
verify_sequence_points (expr);
if (TREE_CODE (expr) != MODIFY_EXPR)
/* Expr is not being 'used' here, otherwise we whould have
called mark_{rl}value_use use here, which would have in turn
called mark_exp_read. Rather, we call mark_exp_read directly
to avoid some warnings when
-Wunused-but-set-{variable,parameter} is in effect. */
mark_exp_read (expr);
expr = convert_to_void (expr, "statement", tf_warning_or_error);
}
else if (!type_dependent_expression_p (expr))
@ -1238,6 +1245,8 @@ finish_asm_stmt (int volatile_p, tree string, tree output_operands,
otherwise we'll get an error. Gross, but ... */
STRIP_NOPS (operand);
operand = mark_lvalue_use (operand);
if (!lvalue_or_else (operand, lv_asm, tf_warning_or_error))
operand = error_mark_node;
@ -3182,6 +3191,8 @@ finish_typeof (tree expr)
return type;
}
expr = mark_type_use (expr);
type = unlowered_expr_type (expr);
if (!type || type == unknown_type_node)
@ -4859,6 +4870,7 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p)
case PARM_DECL:
case RESULT_DECL:
case TEMPLATE_PARM_INDEX:
expr = mark_type_use (expr);
type = TREE_TYPE (expr);
break;
@ -4867,6 +4879,7 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p)
break;
case COMPONENT_REF:
mark_type_use (expr);
type = is_bitfield_expr_with_lowered_type (expr);
if (!type)
type = TREE_TYPE (TREE_OPERAND (expr, 1));

View file

@ -551,6 +551,8 @@ rvalue (tree expr)
if (error_operand_p (expr))
return expr;
expr = mark_rvalue_use (expr);
/* [basic.lval]
Non-class rvalues always have cv-unqualified types. */

View file

@ -1631,6 +1631,8 @@ cxx_sizeof_expr (tree e, tsubst_flags_t complain)
&& DECL_TEMPLATE_INSTANTIATION (e))
instantiate_decl (e, /*defer_ok*/true, /*expl_inst_mem*/false);
e = mark_type_use (e);
if (TREE_CODE (e) == COMPONENT_REF
&& TREE_CODE (TREE_OPERAND (e, 1)) == FIELD_DECL
&& DECL_C_BIT_FIELD (TREE_OPERAND (e, 1)))
@ -1686,6 +1688,8 @@ cxx_alignof_expr (tree e, tsubst_flags_t complain)
return e;
}
e = mark_type_use (e);
if (TREE_CODE (e) == VAR_DECL)
t = size_int (DECL_ALIGN_UNIT (e));
else if (TREE_CODE (e) == COMPONENT_REF
@ -1835,7 +1839,9 @@ unlowered_expr_type (const_tree exp)
in an rvalue context: the lvalue-to-rvalue, array-to-pointer, and
function-to-pointer conversions. In addition, manifest constants
are replaced by their values, and bitfield references are converted
to their declared types.
to their declared types. Note that this function does not perform the
lvalue-to-rvalue conversion for class types. If you need that conversion
to for class types, then you probably need to use force_rvalue.
Although the returned value is being used as an rvalue, this
function does not wrap the returned expression in a
@ -1852,6 +1858,8 @@ decay_conversion (tree exp)
if (type == error_mark_node)
return error_mark_node;
exp = mark_rvalue_use (exp);
exp = resolve_nondeduced_context (exp);
if (type_unknown_p (exp))
{
@ -1976,6 +1984,8 @@ perform_integral_promotions (tree expr)
tree type;
tree promoted_type;
expr = mark_rvalue_use (expr);
/* [conv.prom]
If the bitfield has an enumerated type, it is treated as any
@ -4807,6 +4817,8 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
if (val != 0)
return val;
arg = mark_lvalue_use (arg);
/* Increment or decrement the real part of the value,
and don't change the imaginary part. */
if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
@ -4940,6 +4952,8 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
argtype = lvalue_type (arg);
arg = mark_lvalue_use (arg);
if (TREE_CODE (arg) == OFFSET_REF)
goto offset_ref;
@ -8042,3 +8056,4 @@ lvalue_or_else (tree ref, enum lvalue_use use, tsubst_flags_t complain)
return win;
}

View file

@ -1,3 +1,40 @@
2010-04-22 Jakub Jelinek <jakub@redhat.com>
Dodji Seketeli <dodji@redhat.com>
PR c/18624
* g++.dg/warn/Wunused-7.C: Add dg-warning.
* g++.dg/template/sfinae16.C: Likewise.
* gcc.dg/Wunused-var-1.c: Moved to...
* c-c++-common/Wunused-var-1.c: ...here. New test.
* gcc.dg/Wunused-var-2.c: Moved to...
* c-c++-common/Wunused-var-2.c: ...here. New test.
* gcc.dg/Wunused-var-3.c: Moved to...
* c-c++-common/Wunused-var-3.c: ...here. New test.
* gcc.dg/Wunused-var-4.c: Moved to...
* gcc.dg/Wunused-var-1.c: ... here.
* gcc.dg/Wunused-var-5.c: Moved to...
* c-c++-common/Wunused-var-4.c: ...here. New test.
* gcc.dg/Wunused-var-7.c: Moved to...
* c-c++-common/Wunused-var-5.c: ...here. New test.
* gcc.dg/Wunused-var-6.c: Moved to...
* gcc.dg/Wunused-var-2.c: ... here.
* c-c++-common/Wunused-var-1.c: New test.
* c-c++-common/Wunused-var-2.c: New test.
* c-c++-common/Wunused-var-3.c: New test.
* c-c++-common/Wunused-var-4.c: New test.
* c-c++-common/Wunused-var-5.c: New test.
* g++.dg/warn/Wunused-var-1.C: New test.
* g++.dg/warn/Wunused-var-2.C: New test.
* g++.dg/warn/Wunused-var-3.C: New test.
* g++.dg/warn/Wunused-var-4.C: New test.
* g++.dg/warn/Wunused-var-5.C: New test.
* g++.dg/warn/Wunused-var-6.C: New test.
* g++.dg/warn/Wunused-var-7.C: New test.
* g++.dg/warn/Wunused-var-8.C: New test.
* g++.dg/warn/Wunused-parm-1.C: New test.
* g++.dg/warn/Wunused-parm-2.C: New test.
* g++.dg/warn/Wunused-parm-3.C: New test.
2010-05-06 Tobias Burnus <burnus@net-b.de>
PR fortran/43985

View file

@ -0,0 +1,179 @@
/* { dg-do compile } */
/* { dg-options "-Wunused" } */
void
f1 (void)
{
int a; /* { dg-warning "set but not used" } */
int b;
int c;
c = 1;
a = b = c;
}
void
f2 (int x)
{
int a; /* { dg-warning "set but not used" } */
int b;
int c; /* { dg-warning "set but not used" } */
c = (a = x, b = x);
}
int
f3 (int x)
{
int a;
return a = x;
}
int
f4 (int x)
{
int a;
a = x;
return a;
}
void
f5 (int x)
{
int a[2]; /* { dg-warning "set but not used" } */
int b;
int *c, d[2];
c = d;
b = x;
a[b] = 1;
c[b] = 1;
}
int
f6 (int x)
{
int a[2];
int b;
b = x;
a[b] = 1;
return a[b];
}
void
f7 (int x, int *p)
{
int *a[2];
a[x] = p;
a[x][x] = x;
}
struct S { int i; };
void
f8 (void)
{
struct S s; /* { dg-warning "set but not used" } */
s.i = 6;
}
int
f9 (void)
{
struct S s;
s.i = 6;
return s.i;
}
struct S
f10 (void)
{
struct S s;
s.i = 6;
return s;
}
extern int foo11 (int *);
void
f11 (void)
{
int a[2];
foo11 (a);
}
void
f12 (void)
{
int a;
a = 1;
a; /* { dg-warning "no effect" } */
}
void
f13 (void (*x) (void))
{
void (*a) (void);
a = x;
a ();
}
void
f14 (void (*x) (void))
{
void (*a) (void); /* { dg-warning "set but not used" } */
a = x;
}
extern void foo15 (int *);
void
f15 (void)
{
int a[10];
int *b = a + 2;
foo15 (b);
}
extern void foo16 (int **);
void
f16 (void)
{
int a[10];
int *b[] = { a, a + 2 };
foo16 (b);
}
void
f17 (int x)
{
long a; /* { dg-warning "set but not used" } */
int b;
a = b = x;
}
void
f18 (int x)
{
int a; /* { dg-warning "set but not used" } */
int b;
a = (char) (b = x);
}
int
f19 (int x, int y, int z)
{
int a;
int b;
a = x;
b = y;
return z ? a : b;
}
int *
f20 (int x)
{
static int a[] = { 3, 4, 5, 6 };
static int b[] = { 4, 5, 6, 7 };
static int c[] = { 5, 6, 7, 8 }; /* { dg-warning "set but not used" } */
c[1] = 1;
return x ? a : b;
}

View file

@ -0,0 +1,20 @@
/* { dg-do compile } */
/* { dg-options "-Wunused" } */
int
f1 (void)
{
int c = ({
int a;
a = 1;
a; });
return c;
}
void
f2 (void)
{
int f;
f = 0;
__asm__ __volatile__ ("" : "+r" (f));
}

View file

@ -14,9 +14,9 @@ f2 (void)
struct S { int i; } a;
int b[1];
a.i = 1;
a.i; /* { dg-warning "with no effect" } */
a.i; /* { dg-warning "no effect" } */
b[0] = 1;
b[0]; /* { dg-warning "with no effect" } */
b[0]; /* { dg-warning "no effect" } */
}
void

View file

@ -29,6 +29,6 @@ template<typename Rep>
int main()
{
duration<int> d0;
duration<int> d1 = d0;
duration<int> d1 = d0; // { dg-warning "set but not used" }
}

View file

@ -6,7 +6,7 @@ void func()
struct mybitfields {
unsigned int s_field:8;
};
struct mybitfields s;
struct mybitfields s; // { dg-warning "set but not used" }
s.s_field = 255;
};

View file

@ -0,0 +1,58 @@
// { dg-do compile }
// { dg-options "-Wunused -W" }
long
f1 (unsigned long long x)
{
unsigned long long a = 1;
const union { unsigned long long l; unsigned int p[2]; } b = { x };
const union { unsigned long long l; unsigned int p[2]; } c = { a };
return b.p[0] + c.p[0];
}
int
f2 (int x, int y)
{
int a = 1;
int b[] = { 1, 2, x, a, 3, 4 };
return b[y];
}
int
f3 (int a) // { dg-warning "unused parameter" }
{
return 0;
}
int
f4 (int a) // { dg-warning "set but not used" }
{
a = 1;
return 0;
}
int
f5 (int a)
{
a = 1;
return a;
}
int
f6 (int &a)
{
return a;
}
void
f7 (int &a)
{
a = 1;
}
struct S
{
S (int i) : j(i) {}
S (long i) : j(i + 1) {}
int j;
};

View file

@ -0,0 +1,54 @@
// { dg-do compile }
// { dg-options "-Wunused -W" }
template <int N>
long
f1 (unsigned long long x)
{
unsigned long long a = 1;
const union { unsigned long long l; unsigned int p[2]; } b = { x };
const union { unsigned long long l; unsigned int p[2]; } c = { a };
return b.p[0] + c.p[0];
}
template <int N>
int
f2 (int x, int y)
{
int a = 1;
int b[] = { 1, 2, x, a, 3, 4 };
return b[y];
}
template <int N>
int
f3 (int a) // { dg-warning "unused parameter" }
{
return 0;
}
template <int N>
int
f4 (int a) // { dg-warning "set but not used" }
{
a = 1;
return 0;
}
template <int N>
int
f5 (int a)
{
a = 1;
return a;
}
void
test ()
{
(void) f1<0> (0);
(void) f2<0> (0, 0);
(void) f3<0> (0);
(void) f4<0> (0);
(void) f5<0> (0);
}

View file

@ -0,0 +1,69 @@
// { dg-do compile }
// { dg-options "-Wunused -W" }
#include <stdarg.h>
struct A
{
long a;
A () : a (0) { }
A (long x) : a (x) { }
operator long () const { return a; }
long operator- (const A& x) const { return a - x.a; }
};
long
fn1 (A a)
{
return a - A (0);
}
struct B
{
bool operator() (const int x, const int y) const throw() { return x < y; }
};
template <typename T>
bool
fn2 (int x, int y, T z)
{
return z (x, y);
}
bool
fn3 (void)
{
return fn2 (1, 2, B ());
}
int
fn4 (va_list ap)
{
return va_arg (ap, int);
}
template <typename T>
T
fn5 (va_list ap)
{
return va_arg (ap, T);
}
int
fn6 (va_list ap)
{
return fn5 <int> (ap);
}
template <typename T>
int
fn7 (T ap)
{
return va_arg (ap, int);
}
int
fn8 (va_list ap)
{
return fn7 (ap);
}

View file

@ -0,0 +1,8 @@
// { dg-options "-Wunused" }
template <int> struct X { static const int s = 2; };
template <typename T> int f() { const int v = 2; return X<v+1>::s; }
template <typename T> int g() { const int v = 2; return X<v>::s; }
template <typename T> int h() { const int v = 2; return X<1 ? v : 0>::s; }
template int f<int>();
template int g<int>();
template int h<int>();

View file

@ -0,0 +1,104 @@
// { dg-options "-Wunused -W" }
extern void foo ();
void
f1 ()
{
try
{
foo ();
}
catch (int i)
{
}
catch (double d)
{
}
}
void
f2 (int x)
{
int a = 0;
x++;
++a;
}
struct A
{
bool foo () const { return true; }
};
int
f3 ()
{
A a;
bool b = a.foo ();
return b;
}
struct B
{
int i;
B (int j);
};
void
f4 ()
{
B b (6);
}
struct C
{
int i;
C (int j) : i (j) {}
};
void
f5 ()
{
C c (6);
}
struct D
{
int i;
D (int j) : i (j) {}
~D ();
};
void
f6 ()
{
D d (6);
}
int *f7 (int s)
{
return new int[s];
}
template <typename T>
T *f8 (int s)
{
return new T[s];
}
template int *f8<int> (int);
void
f9 (char *p)
{
delete p;
}
template <typename T>
void
f10 (T *p)
{
delete p;
}
template void f10<char> (char *);

View file

@ -0,0 +1,110 @@
// { dg-options "-Wunused -W" }
#include <typeinfo>
#include <stdarg.h>
void
f1 (int a, ...)
{
va_list ap;
va_start (ap, a);
va_end (ap);
}
int
f2 (int a, ...)
{
va_list ap;
va_start (ap, a);
int i = va_arg (ap, int);
va_end (ap);
return i;
}
struct A { int a; A (); virtual ~A (); };
struct B : virtual A { int b; };
struct B *
f3 (struct A *a)
{
return dynamic_cast <B *> (a);
}
struct A *
f4 (struct B *a)
{
return static_cast <A *> (a);
}
struct A *
f5 (struct B *a)
{
return reinterpret_cast <A *> (a);
}
struct A *
f6 (const struct A *a)
{
return const_cast <A *> (a);
}
int
f7 (long a)
{
return (int) a;
}
int
f8 (long a)
{
return int (a);
}
struct C
{
operator unsigned int() { return 42; }
};
unsigned int
f9 ()
{
C u;
return u;
}
struct D
{
operator int & ();
operator const int & () const;
};
void foo (int &);
void foo (const int &);
void
f10 ()
{
const D x = D ();
foo (x);
}
int
f11 (int a)
{
return typeid (a) == typeid (int);
}
struct E
{
int e () {return 0;}
};
template <typename T>
int
f12 (E a)
{
__decltype (a.e()) i;
return i;
}
template <> int f12<int> (E);

View file

@ -0,0 +1,50 @@
/* { dg-do compile } */
/* { dg-options "-Wunused" } */
struct S { int e; };
int
f1 (void)
{
int a;
int b;
int c;
int d;
S s;
a = 1;
b = 2;
c = 3;
d = 4;
s.e = 5;
__typeof (c) e; // { dg-warning "set but not used" }
__decltype (d) f; // { dg-warning "set but not used" }
__decltype (s.e) g; // { dg-warning "set but not used" }
e = 1;
f = 1;
g = 1;
return sizeof (a) + __alignof__ (b);
}
template <int N>
int f2 (void)
{
int a;
int b;
int c;
int d;
a = 1;
b = 2;
c = 3;
d = 4;
__typeof (c) e; // { dg-warning "set but not used" }
__decltype (d) f; // { dg-warning "set but not used" }
e = 1;
f = 1;
return sizeof (a) + __alignof__ (b);
}
void
test (void)
{
(void) f2<0> ();
}

View file

@ -0,0 +1,227 @@
// { dg-do compile }
// { dg-options "-Wunused" }
template <int N>
void
f1 (void)
{
int a; // { dg-warning "set but not used" }
int b;
int c;
c = 1;
a = b = c;
}
template <int N>
void
f2 (int x)
{
int a; // { dg-warning "set but not used" }
int b;
int c; // { dg-warning "set but not used" }
c = (a = x, b = x);
}
template <int N>
int
f3 (int x)
{
int a;
return a = x;
}
template <int N>
int
f4 (int x)
{
int a;
a = x;
return a;
}
template <int N>
void
f5 (int x)
{
int a[2]; // { dg-warning "set but not used" }
int b;
int *c, d[2];
c = d;
b = x;
a[b] = 1;
c[b] = 1;
}
template <int N>
int
f6 (int x)
{
int a[2];
int b;
b = x;
a[b] = 1;
return a[b];
}
template <int N>
void
f7 (int x, int *p)
{
int *a[2];
a[x] = p;
a[x][x] = x;
}
struct S { int i; };
template <int N>
void
f8 (void)
{
struct S s; // { dg-warning "set but not used" }
s.i = 6;
}
template <int N>
int
f9 (void)
{
struct S s;
s.i = 6;
return s.i;
}
template <int N>
struct S
f10 (void)
{
struct S s;
s.i = 6;
return s;
}
extern int foo11 (int *);
template <int N>
void
f11 (void)
{
int a[2];
foo11 (a);
}
template <int N>
void
f12 (void)
{
int a;
a = 1;
a; // { dg-warning "statement has no effect" }
}
template <int N>
void
f13 (void (*x) (void))
{
void (*a) (void);
a = x;
a ();
}
template <int N>
void
f14 (void (*x) (void))
{
void (*a) (void); // { dg-warning "set but not used" }
a = x;
}
extern void foo15 (int *);
template <int N>
void
f15 (void)
{
int a[10];
int *b = a + 2;
foo15 (b);
}
extern void foo16 (int **);
template <int N>
void
f16 (void)
{
int a[10];
int *b[] = { a, a + 2 };
foo16 (b);
}
template <int N>
void
f17 (int x)
{
long a; // { dg-warning "set but not used" }
int b;
a = b = x;
}
template <int N>
void
f18 (int x)
{
int a; // { dg-warning "set but not used" }
int b;
a = (char) (b = x);
}
template <int N>
int
f19 (int x, int y, int z)
{
int a;
int b;
a = x;
b = y;
return z ? a : b;
}
template <int N>
int *
f20 (int x)
{
static int a[] = { 3, 4, 5, 6 };
static int b[] = { 4, 5, 6, 7 };
static int c[] = { 5, 6, 7, 8 }; // { dg-warning "set but not used" }
c[1] = 1;
return x ? a : b;
}
S s;
void
test ()
{
int i = 0;
f1<0> ();
f2<0> (0);
(void) f3<0> (0);
(void) f4<0> (0);
f5<0> (0);
(void) f6<0> (0);
f7<0> (0, &i);
f8<0> ();
(void) f9<0> ();
s = f10<0> ();
f11<0> ();
f12<0> ();
f13<0> (f1<0>);
f14<0> (f1<0>);
f15<0> ();
f16<0> ();
f17<0> (0);
f18<0> (0);
(void) f19<0> (0, 0, 0);
(void) f20<0> (0);
}

View file

@ -0,0 +1,29 @@
// { dg-do compile }
// { dg-options "-Wunused" }
template <int N>
int
f1 (void)
{
int c = ({
int a;
a = 1;
a; });
return c;
}
template <int N>
void
f2 (void)
{
int f;
f = 0;
__asm__ __volatile__ ("" : "+r" (f));
}
void
test ()
{
(void) f1<0> ();
f2<0> ();
}

View file

@ -0,0 +1,48 @@
// { dg-do compile }
// { dg-options "-Wunused" }
template <int N>
void
f1 (void)
{
_Complex int a; // { dg-warning "set but not used" }
_Complex double b; // { dg-warning "set but not used" }
__real__ a = 1;
__imag__ a = 2;
__real__ b = 3.0;
__imag__ b = 4.0;
}
template <int N>
int
f2 (void)
{
_Complex int a;
_Complex double b;
__real__ a = 1;
__imag__ a = 2;
__real__ b = 3.0;
__imag__ b = 4.0;
return __real__ a + __imag__ b;
}
template <int N>
_Complex double
f3 (void)
{
_Complex int a;
_Complex double b;
__real__ a = 1;
__imag__ a = 2;
__real__ b = 3.0;
__imag__ b = 4.0;
return a + b;
}
void
test ()
{
f1<0> ();
(void) f2<0> ();
(void) f3<0> ();
}

View file

@ -0,0 +1,46 @@
// { dg-do compile }
// { dg-options "-Wunused" }
template <int N>
void
f1 (void)
{
extern int extvari;
extvari = 1;
}
int extvarj;
template <int N>
void
f2 (void)
{
extern int extvarj;
extvarj = 1;
}
static int extvark;
template <int N>
void
f3 (void)
{
extern int extvark;
extvark = 1;
}
template <int N>
int
f4 (void)
{
return extvark;
}
void
test ()
{
f1<0> ();
f2<0> ();
f3<0> ();
(void) f4<0> ();
}

View file

@ -1,179 +1,26 @@
/* { dg-do compile } */
/* { dg-options "-Wunused" } */
void
int
f1 (void)
{
int a; /* { dg-warning "set but not used" } */
int b;
int c;
c = 1;
a = b = c;
}
void
f2 (int x)
{
int a; /* { dg-warning "set but not used" } */
int b;
int c; /* { dg-warning "set but not used" } */
c = (a = x, b = x);
}
int
f3 (int x)
{
int a;
return a = x;
}
int
f4 (int x)
{
int a;
a = x;
return a;
}
void
f5 (int x)
{
int a[2]; /* { dg-warning "set but not used" } */
int b;
int *c, d[2];
c = d;
b = x;
a[b] = 1;
c[b] = 1;
}
int
f6 (int x)
{
int a[2];
int b;
b = x;
a[b] = 1;
return a[b];
}
void
f7 (int x, int *p)
{
int *a[2];
a[x] = p;
a[x][x] = x;
}
struct S { int i; };
void
f8 (void)
{
struct S s; /* { dg-warning "set but not used" } */
s.i = 6;
}
int
f9 (void)
{
struct S s;
s.i = 6;
return s.i;
}
struct S
f10 (void)
{
struct S s;
s.i = 6;
return s;
}
extern int foo11 (int *);
void
f11 (void)
{
int a[2];
foo11 (a);
}
void
f12 (void)
{
int a;
int foo (void)
{
return a;
}
a = 1;
a; /* { dg-warning "statement with no effect" } */
return foo ();
}
void
f13 (void (*x) (void))
{
void (*a) (void);
a = x;
a ();
}
void
f14 (void (*x) (void))
{
void (*a) (void); /* { dg-warning "set but not used" } */
a = x;
}
extern void foo15 (int *);
void
f15 (void)
{
int a[10];
int *b = a + 2;
foo15 (b);
}
extern void foo16 (int **);
void
f16 (void)
{
int a[10];
int *b[] = { a, a + 2 };
foo16 (b);
}
void
f17 (int x)
{
long a; /* { dg-warning "set but not used" } */
int b;
a = b = x;
}
void
f18 (int x)
f2 (void)
{
int a; /* { dg-warning "set but not used" } */
int b;
a = (char) (b = x);
}
int
f19 (int x, int y, int z)
{
int a;
int b;
a = x;
b = y;
return z ? a : b;
}
int *
f20 (int x)
{
static int a[] = { 3, 4, 5, 6 };
static int b[] = { 4, 5, 6, 7 };
static int c[] = { 5, 6, 7, 8 }; /* { dg-warning "set but not used" } */
c[1] = 1;
return x ? a : b;
void foo (void)
{
a = 2;
}
a = 1;
foo ();
}

View file

@ -4,17 +4,16 @@
int
f1 (void)
{
int c = ({
int a;
a = 1;
a; });
return c;
}
void
f2 (void)
{
int f;
f = 0;
__asm__ __volatile__ ("" : "+r" (f));
int a;
int b;
int c;
int d;
int e;
a = 1;
b = 2;
c = 3;
d = 4;
e = 5;
return sizeof (a) + ((__typeof (b)) 1) + __alignof__ (c)
+ __builtin_choose_expr (1, d, e);
}

View file

@ -1,26 +0,0 @@
/* { dg-do compile } */
/* { dg-options "-Wunused" } */
int
f1 (void)
{
int a;
int foo (void)
{
return a;
}
a = 1;
return foo ();
}
void
f2 (void)
{
int a; /* { dg-warning "set but not used" } */
void foo (void)
{
a = 2;
}
a = 1;
foo ();
}

View file

@ -1,19 +0,0 @@
/* { dg-do compile } */
/* { dg-options "-Wunused" } */
int
f1 (void)
{
int a;
int b;
int c;
int d;
int e;
a = 1;
b = 2;
c = 3;
d = 4;
e = 5;
return sizeof (a) + ((__typeof (b)) 1) + __alignof__ (c)
+ __builtin_choose_expr (1, d, e);
}