This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Fix -Wid-clash-LEN; more cleanup.


This patch and tescase fixes this issue.  We still warn for C
identifiers clashing with CPP macro names.  If anyone thinks it's
worth trying to work around this, let me know, and I'll attempt a fix
as a followup.

We don't play ERROR_MARK games any more, so we don't need the function
make_identifier.

OK to commit?

Neil.

	* c-lex.c (c_lex): Just cast cpp's hashnode to gcc's one.
	* flags.h (warn_id_clash, id_clash_len): Delete.
	* hashtable.c (scan_for_clashes): New.
	(ht_lookup): Update.
	* hashtable.h (struct ht): New members clash_len and
	found_clash.
	* stringpool.c: Don't include flags.h.
	(IS_FE_IDENT, do_identifier_warnings, make_identifier,
	scan_for_clashes): Delete.
	(maybe_get_identifier, start_identifier_warnings): Update.
	(found_clash): New.
	* toplev.c (warn_id_clash, id_clash_len): Delete.
	(decode_W_option): Update.
	* tree.h (make_identifier): Delete.

	* testsuite/gcc.dg/Wid-clash.c: New test.Index: c-lex.c

===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-lex.c,v
retrieving revision 1.138
diff -u -p -r1.138 c-lex.c
--- c-lex.c	2001/05/20 06:26:32	1.138
+++ c-lex.c	2001/05/20 10:14:28
@@ -997,12 +997,7 @@ c_lex (value)
       goto retry;
       
     case CPP_NAME:
-      {
-	tree node = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok.val.node));
-	if (TREE_CODE (node) != IDENTIFIER_NODE)
-	  make_identifier (node);
-	*value = node;
-      }
+      *value = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok.val.node));
       break;
 
     case CPP_INT:
Index: flags.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/flags.h,v
retrieving revision 1.63
diff -u -p -r1.63 flags.h
--- flags.h	2001/05/20 06:26:36	1.63
+++ flags.h	2001/05/20 10:14:32
@@ -142,12 +142,6 @@ extern int warn_missing_noreturn;
 
 extern int warn_cast_align;
 
-/* Nonzero means warn about any identifiers that match in the first N
-   characters.  The value N is in `id_clash_len'.  */
-
-extern int warn_id_clash;
-extern unsigned int id_clash_len;
-
 /* Nonzero means warn about any objects definitions whose size is larger
    than N bytes.  Also want about function definitions whose returned
    values are larger than N bytes. The value N is in `larger_than_size'.  */
Index: hashtable.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/hashtable.c,v
retrieving revision 1.2
diff -u -p -r1.2 hashtable.c
--- hashtable.c	2001/05/20 08:13:32	1.2
+++ hashtable.c	2001/05/20 10:14:32
@@ -32,6 +32,7 @@ Foundation, 59 Temple Place - Suite 330,
 
 static unsigned int calc_hash PARAMS ((const unsigned char *, unsigned int));
 static void ht_expand PARAMS ((hash_table *));
+static void scan_for_clashes PARAMS ((hash_table *, const unsigned char *));
 
 /* Let particular systems override the size of a chunk.  */
 #ifndef OBSTACK_CHUNK_SIZE
@@ -46,6 +47,7 @@ static void ht_expand PARAMS ((hash_tabl
 #endif
 
 /* Initialise an obstack.  */
+
 void
 gcc_obstack_init (obstack)
      struct obstack *obstack;
@@ -102,6 +104,7 @@ ht_create (order)
    string is alloced if INSERT is CPP_ALLOC, otherwise INSERT is
    CPP_ALLOCED and the item is assumed to be at the top of the
    obstack.  */
+
 hashnode
 ht_lookup (table, str, len, insert)
      hash_table *table;
@@ -146,6 +149,9 @@ ht_lookup (table, str, len, insert)
   if (insert == HT_NO_INSERT)
     return NULL;
 
+  if (table->found_clash && len >= table->clash_len)
+    scan_for_clashes (table, str);
+
   node = (*table->alloc_node) (table);
   table->entries[index] = node;
 
@@ -204,8 +210,32 @@ ht_expand (table)
   table->nslots = size;
 }
 
+/* If STR is longer than the clash-warning length, do a brute force
+   search of the entire table for clashes.  */
+
+static void
+scan_for_clashes (table, str)
+     hash_table *table;
+     const unsigned char *str;
+{
+  hashnode *p, *limit;
+
+  p = table->entries;
+  limit = p + table->nslots;
+  do
+    if (*p)
+      {
+	if (HT_LEN (*p) >= table->clash_len
+	    && !memcmp (HT_STR (*p), str, table->clash_len)
+	    && table->found_clash (table, *p, str) == 0)
+	  break;
+      }
+  while (++p < limit);
+}
+
 /* For all nodes in TABLE, callback CB with parameters TABLE->PFILE,
    the node, and V.  */
+
 void
 ht_forall (table, cb, v)
      hash_table *table;
@@ -293,6 +323,7 @@ ht_dump_statistics (table)
 
 /* Return the approximate positive square root of a number N.  This is for
    statistical reports, not code generation.  */
+
 double
 approx_sqrt (x)
      double x;
Index: hashtable.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/hashtable.h,v
retrieving revision 1.1
diff -u -p -r1.1 hashtable.h
--- hashtable.h	2001/05/20 06:26:37	1.1
+++ hashtable.h	2001/05/20 10:14:34
@@ -52,11 +52,22 @@ struct ht
   /* Call back.  */
   hashnode (*alloc_node) PARAMS ((hash_table *));
 
-  unsigned int nslots;		/* Total slots in the entries array.  */
-  unsigned int nelements;	/* Number of live elements.  */
+  /* Total slots in the entries array.  */
+  unsigned int nslots;
 
+  /* Number of live elements.  */
+  unsigned int nelements;
+
   /* Link to reader, if any.  For the benefit of cpplib.  */
   struct cpp_reader *pfile;
+
+  /* If non-NULL, is called when a new identifier STR matches an
+     existing one, NODE, in the first CLASH_LEN characters.  If the
+     handler returns 0, scanning for clashes with STR stops, otherwise
+     it continues.  */
+  int (*found_clash) PARAMS ((hash_table *, hashnode node,
+			       const unsigned char *str));
+  unsigned int clash_len;
 
   /* Table usage statistics.  */
   unsigned int searches;
Index: stringpool.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/stringpool.c,v
retrieving revision 1.7
diff -u -p -r1.7 stringpool.c
--- stringpool.c	2001/05/20 08:13:32	1.7
+++ stringpool.c	2001/05/20 10:14:34
@@ -32,11 +32,8 @@ Software Foundation, 59 Temple Place - S
 #include "ggc.h"
 #include "tree.h"
 #include "hashtable.h"
-#include "flags.h"
 #include "toplev.h"
 
-#define IS_FE_IDENT(NODE) (TREE_CODE (NODE) == IDENTIFIER_NODE)
-
 /* The "" allocated string.  */
 const char empty_string[] = "";
 
@@ -49,13 +46,12 @@ const char digit_vector[] = {
 
 struct ht *ident_hash;
 static struct obstack string_stack;
-static int do_identifier_warnings;
 
 static hashnode alloc_node PARAMS ((hash_table *));
 static int mark_ident PARAMS ((struct cpp_reader *, hashnode, const PTR));
 static void mark_ident_hash PARAMS ((void *));
-static int scan_for_clashes PARAMS ((struct cpp_reader *, hashnode,
-				     const char *));
+static int found_clash PARAMS ((hash_table *, hashnode,
+				const unsigned char *));
 
 /* Initialize the string pool.  */
 void
@@ -76,6 +72,20 @@ alloc_node (table)
   return GCC_IDENT_TO_HT_IDENT (make_node (IDENTIFIER_NODE));
 }
 
+/* Warn for identifier clashes with -Wid-clash-LEN.  */
+static int
+found_clash (table, node, str)
+     hash_table *table;
+     hashnode node;
+     const unsigned char *str;
+{
+  warning ("\"%s\" and \"%s\" identical in first %d characters",
+	   str, HT_STR (node), table->clash_len);
+
+  /* Stop scanning.  */
+  return 0;
+}
+
 /* Allocate and return a string constant of length LENGTH, containing
    CONTENTS.  If LENGTH is -1, CONTENTS is assumed to be a
    nul-terminated string, and the length is calculated using strlen.
@@ -99,23 +109,6 @@ ggc_alloc_string (contents, length)
   return obstack_finish (&string_stack);
 }
 
-/* NODE is an identifier known to the preprocessor.  Make it known to
-   the front ends as well.  */
-
-void
-make_identifier (node)
-     tree node;
-{
-  /* If this identifier is longer than the clash-warning length,
-     do a brute force search of the entire table for clashes.  */
-  if (warn_id_clash && do_identifier_warnings
-      && IDENTIFIER_LENGTH (node) >= id_clash_len)
-    ht_forall (ident_hash, (ht_cb) scan_for_clashes,
-	       IDENTIFIER_POINTER (node));
-
-  TREE_SET_CODE (node, IDENTIFIER_NODE);
-}
-
 /* Return an IDENTIFIER_NODE whose name is TEXT (a null-terminated string).
    If an identifier with that name has previously been referred to,
    the same node is returned this time.  */
@@ -140,45 +133,14 @@ tree
 maybe_get_identifier (text)
      const char *text;
 {
-  hashnode ht_node;
-  tree node;
-  size_t length = strlen (text);
-
-  ht_node = ht_lookup (ident_hash, (const unsigned char *) text,
-		       length, HT_NO_INSERT);
+  hashnode ht_node = ht_lookup (ident_hash, (const unsigned char *) text,
+				strlen (text), HT_NO_INSERT);
   if (ht_node)
-    {
-      node = HT_IDENT_TO_GCC_IDENT (ht_node);
-      if (IS_FE_IDENT (node))
-	return node;
-    }
+    return HT_IDENT_TO_GCC_IDENT (ht_node);
 
   return NULL_TREE;
 }
 
-/* If this identifier is longer than the clash-warning length,
-   do a brute force search of the entire table for clashes.  */
-
-static int
-scan_for_clashes (pfile, h, text)
-     struct cpp_reader *pfile ATTRIBUTE_UNUSED;
-     hashnode h;
-     const char *text;
-{
-  tree node = HT_IDENT_TO_GCC_IDENT (h);
-
-  if (IS_FE_IDENT (node)
-      && IDENTIFIER_LENGTH (node) >= id_clash_len
-      && !memcmp (IDENTIFIER_POINTER (node), text, id_clash_len))
-    {
-      warning ("\"%s\" and \"%s\" identical in first %d characters",
-	       text, IDENTIFIER_POINTER (node), id_clash_len);
-      return 0;
-    }
-
-  return 1;
-}
-
 /* Record the size of an identifier node for the language in use.
    SIZE is the total size in bytes.
    This is called by the language-specific files.  This must be
@@ -198,7 +160,8 @@ set_identifier_size (size)
 void
 start_identifier_warnings ()
 {
-  do_identifier_warnings = 1;
+  if (ident_hash->clash_len)
+    ident_hash->found_clash = found_clash;
 }
 
 /* Report some basic statistics about the string pool.  */
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.460
diff -u -p -r1.460 toplev.c
--- toplev.c	2001/05/20 06:26:37	1.460
+++ toplev.c	2001/05/20 10:14:49
@@ -1417,12 +1417,6 @@ int warn_return_type;
 
 int warn_cast_align;
 
-/* Nonzero means warn about any identifiers that match in the first N
-   characters.  The value N is in `id_clash_len'.  */
-
-int warn_id_clash;
-unsigned int id_clash_len;
-
 /* Nonzero means warn about any objects definitions whose size is larger
    than N bytes.  Also want about function definitions whose returned
    values are larger than N bytes. The value N is in `larger_than_size'.  */
@@ -4194,10 +4188,10 @@ decode_W_option (arg)
 
   if ((option_value = skip_leading_substring (arg, "id-clash-")))
     {
-      id_clash_len = read_integral_parameter (option_value, arg - 2, -1);
+      int id_clash_len = read_integral_parameter (option_value, arg - 2, -1);
 
       if (id_clash_len != -1)
-	warn_id_clash = 1;
+	ident_hash->clash_len = id_clash_len;
     }
   else if ((option_value = skip_leading_substring (arg, "larger-than-")))
     {
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.239
diff -u -p -r1.239 tree.h
--- tree.h	2001/05/20 06:26:42	1.239
+++ tree.h	2001/05/20 10:14:59
@@ -1958,10 +1958,6 @@ extern tree make_tree_vec		PARAMS ((int)
 
 extern tree get_identifier		PARAMS ((const char *));
 
-/* NODE is an identifier known to the preprocessor.  Make it known to
-   the front ends as well.  */
-extern void make_identifier		PARAMS ((tree node));
-
 /* If an identifier with the name TEXT (a null-terminated string) has
    previously been referred to, return that node; otherwise return
    NULL_TREE.  */
Index: testsuite/gcc.dg/Wid-clash.c
===================================================================
RCS file: Wid-clash.c
diff -N Wid-clash.c
--- /dev/null	Tue May  5 13:32:27 1998
+++ Wid-clash.c	Sun May 20 03:15:16 2001
@@ -0,0 +1,7 @@
+/* Test for -Wid-clash-LEN.  */
+/* Origin: Neil Booth. */
+/* { dg-do compile } */
+/* { dg-options "-Wid-clash-12" } */
+
+int a_long_identifier;
+int a_long_identifier_again; /* { dg-warning "identical in first" "-Wid-clash-LEN broken" } */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]