[C++ PATCH] C++ FE version of -Wunused-but-set-{parameter,variable} support (PR c/18624)

Jakub Jelinek jakub@redhat.com
Fri Dec 4 19:11:00 GMT 2009


Hi!

On top of
http://gcc.gnu.org/ml/gcc-patches/2009-11/msg01582.html
http://gcc.gnu.org/ml/gcc-patches/2009-11/msg01583.html
this patch is the first attempt to implement the warnings also in C++.

So far tested just with the included testcases and check-g++,
ext/cleanup-1.C still regresses, because a variable used with invalid
__attribute__((cleanup())) is reported as set but not used.  Perhaps
we should emit these warnings only when no errors have been reported so far,
otherwise they can be confusing.

2009-12-04  Jakub Jelinek  <jakub@redhat.com>

	PR c/18624
	* cp-tree.h (mark_exp_read): New prototype.
	* typeck.c (mark_exp_read): New function.
	(cxx_sizeof_expr, cxx_alignof_expr, decay_conversion,
	perform_integral_promotions): Call it.
	* decl.c (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_exp_read.
	* pt.c (convert_nontype_argument): Likewise.
	* semantics.c (finish_expr_stmt, finish_asm_stmt, finish_typeof,
	finish_decltype_type): Likewise.
	* call.c (implicit_conversion): Likewise.

	* g++.dg/warn/Wunused-7.C: Add dg-warning.
	* g++.dg/warn/Wunused-parm-1.C: New test.
	* g++.dg/warn/Wunused-parm-2.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-var-9.C: New test.
	* g++.dg/warn/Wunused-var-10.C: New test.

--- gcc/cp/cp-tree.h.jj	2009-12-02 21:44:01.000000000 +0100
+++ gcc/cp/cp-tree.h	2009-12-04 14:35:17.000000000 +0100
@@ -5363,6 +5363,7 @@ extern tree convert_ptrmem			(tree, tree
 extern int lvalue_or_else			(tree, enum lvalue_use,
                                                  tsubst_flags_t);
 extern void check_template_keyword		(tree);
+extern void mark_exp_read			(tree);
 
 /* in typeck2.c */
 extern void require_complete_eh_spec_types	(tree, tree);
--- gcc/cp/typeck.c.jj	2009-12-02 21:44:01.000000000 +0100
+++ gcc/cp/typeck.c	2009-12-04 19:28:02.000000000 +0100
@@ -1485,6 +1485,8 @@ cxx_sizeof_expr (tree e, tsubst_flags_t 
       return e;
     }
 
+  mark_exp_read (e);
+
   if (TREE_CODE (e) == COMPONENT_REF
       && TREE_CODE (TREE_OPERAND (e, 1)) == FIELD_DECL
       && DECL_C_BIT_FIELD (TREE_OPERAND (e, 1)))
@@ -1540,6 +1542,8 @@ cxx_alignof_expr (tree e, tsubst_flags_t
       return e;
     }
 
+  mark_exp_read (e);
+
   if (TREE_CODE (e) == VAR_DECL)
     t = size_int (DECL_ALIGN_UNIT (e));
   else if (TREE_CODE (e) == COMPONENT_REF
@@ -1706,6 +1710,8 @@ decay_conversion (tree exp)
   if (type == error_mark_node)
     return error_mark_node;
 
+  mark_exp_read (exp);
+
   exp = resolve_nondeduced_context (exp);
   if (type_unknown_p (exp))
     {
@@ -1830,6 +1836,8 @@ perform_integral_promotions (tree expr)
   tree type;
   tree promoted_type;
 
+  mark_exp_read (expr);
+
   /* [conv.prom]
 
      If the bitfield has an enumerated type, it is treated as any
@@ -7738,3 +7746,41 @@ lvalue_or_else (tree ref, enum lvalue_us
 
   return win;
 }
+
+/* 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;
+    }
+}
--- gcc/cp/decl.c.jj	2009-12-02 21:44:01.000000000 +0100
+++ gcc/cp/decl.c	2009-12-04 19:52:10.000000000 +0100
@@ -590,14 +590,27 @@ poplevel (int keep, int reverse, int fun
     = 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
+		   && (!CLASS_TYPE_P (TREE_TYPE (decl))
+		       || !(TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl))
+			    || TYPE_HAS_COMPLEX_ASSIGN_REF (TREE_TYPE (decl))
+			    || TYPE_HAS_COMPLEX_DFLT (TREE_TYPE (decl))
+			    || TYPE_HAS_COMPLEX_INIT_REF (TREE_TYPE (decl)))))
+	    warning (OPT_Wunused_but_set_variable,
+		     "variable %q+D set but not used", decl); 
+	}
 
   /* Remove declarations for all the DECLs in this level.  */
   for (link = decls; link; link = TREE_CHAIN (link))
@@ -2091,6 +2104,13 @@ duplicate_decls (tree newdecl, tree oldd
     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 (TREE_CODE (newdecl) == FUNCTION_DECL)
     {
@@ -6136,6 +6156,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;
     }
 
@@ -12556,6 +12577,34 @@ 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
+      && !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))
+		     || TYPE_HAS_COMPLEX_ASSIGN_REF (TREE_TYPE (decl))
+		     || TYPE_HAS_COMPLEX_DFLT (TREE_TYPE (decl))
+		     || TYPE_HAS_COMPLEX_INIT_REF (TREE_TYPE (decl)))))
+	  warning (OPT_Wunused_but_set_parameter,
+		   "parameter %q+D set but not used", decl);
+    }
+
   /* Genericize before inlining.  */
   if (!processing_template_decl)
     {
--- gcc/cp/tree.c.jj	2009-11-23 17:07:24.000000000 +0100
+++ gcc/cp/tree.c	2009-12-04 15:34:00.000000000 +0100
@@ -549,6 +549,8 @@ rvalue (tree expr)
 {
   tree type;
 
+  mark_exp_read (expr);
+
   if (error_operand_p (expr))
     return expr;
 
--- gcc/cp/pt.c.jj	2009-12-02 21:44:01.000000000 +0100
+++ gcc/cp/pt.c	2009-12-04 18:31:00.000000000 +0100
@@ -4774,6 +4774,7 @@ convert_nontype_argument (tree type, tre
   if (error_operand_p (expr))
     return error_mark_node;
   expr_type = TREE_TYPE (expr);
+  mark_exp_read (expr);
 
   /* HACK: Due to double coercion, we can get a
      NOP_EXPR<REFERENCE_TYPE>(ADDR_EXPR<POINTER_TYPE> (arg)) here,
--- gcc/cp/semantics.c.jj	2009-12-02 21:44:01.000000000 +0100
+++ gcc/cp/semantics.c	2009-12-04 18:08:56.000000000 +0100
@@ -612,6 +612,8 @@ finish_expr_stmt (tree expr)
 	{
 	  if (warn_sequence_point)
 	    verify_sequence_points (expr);
+	  if (TREE_CODE (expr) != MODIFY_EXPR)
+	    mark_exp_read (expr);
 	  expr = convert_to_void (expr, "statement", tf_warning_or_error);
 	}
       else if (!type_dependent_expression_p (expr))
@@ -1240,6 +1242,8 @@ finish_asm_stmt (int volatile_p, tree st
 	     otherwise we'll get an error.  Gross, but ...  */
 	  STRIP_NOPS (operand);
 
+	  mark_exp_read (operand);
+
 	  if (!lvalue_or_else (operand, lv_asm, tf_warning_or_error))
 	    operand = error_mark_node;
 
@@ -3207,6 +3211,8 @@ finish_typeof (tree expr)
       return type;
     }
 
+  mark_exp_read (expr);
+
   type = unlowered_expr_type (expr);
 
   if (!type || type == unknown_type_node)
@@ -4856,6 +4862,12 @@ finish_decltype_type (tree expr, bool id
 
       switch (TREE_CODE (expr))
         {
+        case VAR_DECL:
+        case PARM_DECL:
+	  mark_exp_read (expr);
+          type = TREE_TYPE (expr);
+          break;
+
         case FIELD_DECL:
           if (DECL_BIT_FIELD_TYPE (expr))
             {
@@ -4865,9 +4877,7 @@ finish_decltype_type (tree expr, bool id
           /* Fall through for fields that aren't bitfields.  */
 
         case FUNCTION_DECL:
-        case VAR_DECL:
         case CONST_DECL:
-        case PARM_DECL:
         case RESULT_DECL:
         case TEMPLATE_PARM_INDEX:
           type = TREE_TYPE (expr);
@@ -4878,6 +4888,7 @@ finish_decltype_type (tree expr, bool id
           break;
 
         case COMPONENT_REF:
+	  mark_exp_read (expr);
           type = is_bitfield_expr_with_lowered_type (expr);
           if (!type)
             type = TREE_TYPE (TREE_OPERAND (expr, 1));
--- gcc/cp/call.c.jj	2009-12-02 21:44:01.000000000 +0100
+++ gcc/cp/call.c	2009-12-04 15:03:31.000000000 +0100
@@ -1417,6 +1417,8 @@ implicit_conversion (tree to, tree from,
 {
   conversion *conv;
 
+  mark_exp_read (expr);
+
   if (from == error_mark_node || to == error_mark_node
       || expr == error_mark_node)
     return NULL;
--- gcc/testsuite/g++.dg/warn/Wunused-var-9.C.jj	2009-12-04 18:13:37.000000000 +0100
+++ gcc/testsuite/g++.dg/warn/Wunused-var-9.C	2009-12-04 18:15:58.000000000 +0100
@@ -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> ();
+}
--- gcc/testsuite/g++.dg/warn/Wunused-var-3.C.jj	2009-12-04 16:09:47.000000000 +0100
+++ gcc/testsuite/g++.dg/warn/Wunused-var-3.C	2009-12-04 16:35:01.000000000 +0100
@@ -0,0 +1,37 @@
+// { dg-do compile }
+// { dg-options "-Wunused" }
+
+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;
+}
+
+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;
+}
+
+_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;
+}
--- gcc/testsuite/g++.dg/warn/Wunused-parm-2.C.jj	2009-12-04 17:09:34.000000000 +0100
+++ gcc/testsuite/g++.dg/warn/Wunused-parm-2.C	2009-12-04 17:10:52.000000000 +0100
@@ -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);
+}
--- gcc/testsuite/g++.dg/warn/Wunused-var-10.C.jj	2009-12-04 18:33:41.000000000 +0100
+++ gcc/testsuite/g++.dg/warn/Wunused-var-10.C	2009-12-04 18:43:47.000000000 +0100
@@ -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>();
--- gcc/testsuite/g++.dg/warn/Wunused-7.C.jj	2008-09-05 12:55:03.000000000 +0200
+++ gcc/testsuite/g++.dg/warn/Wunused-7.C	2009-12-04 16:39:16.000000000 +0100
@@ -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;
 };
 
--- gcc/testsuite/g++.dg/warn/Wunused-var-2.C.jj	2009-12-04 16:09:44.000000000 +0100
+++ gcc/testsuite/g++.dg/warn/Wunused-var-2.C	2009-12-04 16:35:01.000000000 +0100
@@ -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));
+}
--- gcc/testsuite/g++.dg/warn/Wunused-var-8.C.jj	2009-12-04 17:06:48.000000000 +0100
+++ gcc/testsuite/g++.dg/warn/Wunused-var-8.C	2009-12-04 17:09:13.000000000 +0100
@@ -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> ();
+}
--- gcc/testsuite/g++.dg/warn/Wunused-var-1.C.jj	2009-12-04 16:09:40.000000000 +0100
+++ gcc/testsuite/g++.dg/warn/Wunused-var-1.C	2009-12-04 16:45:08.000000000 +0100
@@ -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 "statement has 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;
+}
--- gcc/testsuite/g++.dg/warn/Wunused-var-7.C.jj	2009-12-04 17:06:48.000000000 +0100
+++ gcc/testsuite/g++.dg/warn/Wunused-var-7.C	2009-12-04 17:08:18.000000000 +0100
@@ -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> ();
+}
--- gcc/testsuite/g++.dg/warn/Wunused-var-6.C.jj	2009-12-04 17:06:48.000000000 +0100
+++ gcc/testsuite/g++.dg/warn/Wunused-var-6.C	2009-12-04 17:07:28.000000000 +0100
@@ -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> ();
+}
--- gcc/testsuite/g++.dg/warn/Wunused-var-5.C.jj	2009-12-04 16:49:28.000000000 +0100
+++ gcc/testsuite/g++.dg/warn/Wunused-var-5.C	2009-12-04 17:02:44.000000000 +0100
@@ -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);
+}
--- gcc/testsuite/g++.dg/warn/Wunused-var-4.C.jj	2009-12-04 16:09:50.000000000 +0100
+++ gcc/testsuite/g++.dg/warn/Wunused-var-4.C	2009-12-04 16:35:01.000000000 +0100
@@ -0,0 +1,33 @@
+// { dg-do compile }
+// { dg-options "-Wunused" }
+
+void
+f1 (void)
+{
+  extern int extvari;
+  extvari = 1;
+}
+
+int extvarj;
+
+void
+f2 (void)
+{
+  extern int extvarj;
+  extvarj = 1;
+}
+
+static int extvark;
+
+void
+f3 (void)
+{
+  extern int extvark;
+  extvark = 1;
+}
+
+int
+f4 (void)
+{
+  return extvark;
+}
--- gcc/testsuite/g++.dg/warn/Wunused-parm-1.C.jj	2009-12-04 16:33:46.000000000 +0100
+++ gcc/testsuite/g++.dg/warn/Wunused-parm-1.C	2009-12-04 19:56:33.000000000 +0100
@@ -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;
+};


	Jakub



More information about the Gcc-patches mailing list