summaryrefslogblamecommitdiff
path: root/lang/gcc28/files/patch-14
blob: 6e0c0c03fb9c688af802566bdc781623338897cd (plain) (tree)











































































































































































































































                                                                                          
--- c-common.c.orig	Wed Feb 18 19:16:13 1998
+++ c-common.c	Tue Mar 30 14:42:30 1999
@@ -623,6 +623,7 @@
 	    int format_num;
 	    int first_arg_num;
 	    int is_scan;
+	    int null_format_ok;
 	    tree argument;
 	    int arg_num;
 	
@@ -637,12 +638,26 @@
 		&& (!strcmp (IDENTIFIER_POINTER (format_type), "printf")
 		    || !strcmp (IDENTIFIER_POINTER (format_type),
 				"__printf__")))
-	      is_scan = 0;
+	      {
+	        is_scan = 0;
+	        null_format_ok = 0;
+	      }
+	    else if (TREE_CODE (format_type) == IDENTIFIER_NODE
+		&& (!strcmp (IDENTIFIER_POINTER (format_type), "printf0")
+		    || !strcmp (IDENTIFIER_POINTER (format_type),
+				"__printf0__")))
+	      {
+	        is_scan = 0;
+	        null_format_ok = 1;
+	      }
 	    else if (TREE_CODE (format_type) == IDENTIFIER_NODE
 		     && (!strcmp (IDENTIFIER_POINTER (format_type), "scanf")
 			 || !strcmp (IDENTIFIER_POINTER (format_type),
 				     "__scanf__")))
-	      is_scan = 1;
+	      {
+	        is_scan = 1;
+	        null_format_ok = 0;
+	      }
 	    else if (TREE_CODE (format_type) == IDENTIFIER_NODE)
 	      {
 		error ("`%s' is an unrecognized format function type",
@@ -651,7 +666,7 @@
 	      }
 	    else
 	      {
-		error ("unrecognized format specifier");
+		error_with_decl (decl, "unrecognized format specifier");
 		continue;
 	      }
 
@@ -718,7 +733,8 @@
 
 	    record_function_format (DECL_NAME (decl),
 				    DECL_ASSEMBLER_NAME (decl),
-				    is_scan, format_num, first_arg_num);
+				    is_scan, null_format_ok, format_num,
+				    first_arg_num);
 	    break;
 	  }
 
@@ -906,6 +922,7 @@
   int pointer_count;
   /* Type of argument if no length modifier is used.  */
   tree *nolen;
+  /* EGCS has tree *hhlen -- length modifier for shortening to byte */
   /* Type of argument if length modifier for shortening is used.
      If NULL, then this modifier is not allowed.  */
   tree *hlen;
@@ -926,6 +943,11 @@
 } format_char_info;
 
 static format_char_info print_char_table[] = {
+/* FreeBSD kernel extensions.  */
+  { "D",	1,	T_C,	NULL,	NULL,	NULL,	NULL,	NULL,	"-wp"		},
+  { "b",	1,	T_C,	NULL,	NULL,	NULL,	NULL,	NULL,	"-wp"		},
+  { "rz",	0,	NULL,	T_I,	T_L,	NULL,	NULL,	NULL,	"-wp0 +#"	},
+#define unextended_print_char_table	(print_char_table + 3)
   { "di",	0,	T_I,	T_I,	T_L,	T_LL,	T_LL,	T_ST,	"-wp0 +"	},
   { "oxX",	0,	T_UI,	T_UI,	T_UL,	T_ULL,	T_ULL,	T_ST,	"-wp0#"		},
   { "u",	0,	T_UI,	T_UI,	T_UL,	T_ULL,	T_ULL,	T_ST,	"-wp0"		},
@@ -960,6 +982,7 @@
   tree name;			/* identifier such as "printf" */
   tree assembler_name;		/* optional mangled identifier (for C++) */
   int is_scan;			/* TRUE if *scanf */
+  int null_format_ok;		/* TRUE if the format string may be NULL */
   int format_num;		/* number of format argument */
   int first_arg_num;		/* number of first arg (zero for varargs) */
 } function_format_info;
@@ -991,15 +1014,15 @@
 void
 init_function_format_info ()
 {
-  record_function_format (get_identifier ("printf"), NULL_TREE, 0, 1, 2);
-  record_function_format (get_identifier ("fprintf"), NULL_TREE, 0, 2, 3);
-  record_function_format (get_identifier ("sprintf"), NULL_TREE, 0, 2, 3);
-  record_function_format (get_identifier ("scanf"), NULL_TREE, 1, 1, 2);
-  record_function_format (get_identifier ("fscanf"), NULL_TREE, 1, 2, 3);
-  record_function_format (get_identifier ("sscanf"), NULL_TREE, 1, 2, 3);
-  record_function_format (get_identifier ("vprintf"), NULL_TREE, 0, 1, 0);
-  record_function_format (get_identifier ("vfprintf"), NULL_TREE, 0, 2, 0);
-  record_function_format (get_identifier ("vsprintf"), NULL_TREE, 0, 2, 0);
+  record_function_format (get_identifier ("printf"), NULL_TREE, 0, 0, 1, 2);
+  record_function_format (get_identifier ("fprintf"), NULL_TREE, 0, 0, 2, 3);
+  record_function_format (get_identifier ("sprintf"), NULL_TREE, 0, 0, 2, 3);
+  record_function_format (get_identifier ("scanf"), NULL_TREE, 1, 0, 1, 2);
+  record_function_format (get_identifier ("fscanf"), NULL_TREE, 1, 0, 2, 3);
+  record_function_format (get_identifier ("sscanf"), NULL_TREE, 1, 0, 2, 3);
+  record_function_format (get_identifier ("vprintf"), NULL_TREE, 0, 0, 1, 0);
+  record_function_format (get_identifier ("vfprintf"), NULL_TREE, 0, 0, 2, 0);
+  record_function_format (get_identifier ("vsprintf"), NULL_TREE, 0, 0, 2, 0);
 
   record_international_format (get_identifier ("gettext"), NULL_TREE, 1);
   record_international_format (get_identifier ("dgettext"), NULL_TREE, 2);
@@ -1016,11 +1039,12 @@
    (e.g. for varargs such as vfprintf).  */
 
 void
-record_function_format (name, assembler_name, is_scan,
+record_function_format (name, assembler_name, is_scan, null_format_ok,
 			format_num, first_arg_num)
       tree name;
       tree assembler_name;
       int is_scan;
+      int null_format_ok;
       int format_num;
       int first_arg_num;
 {
@@ -1044,6 +1068,7 @@
     }
 
   info->is_scan = is_scan;
+  info->null_format_ok = null_format_ok;
   info->format_num = format_num;
   info->first_arg_num = first_arg_num;
 }
@@ -1194,7 +1219,8 @@
 
   if (integer_zerop (format_tree))
     {
-      warning ("null format string");
+      if (!info->null_format_ok)
+	warning ("null format string");
       return;
     }
   if (TREE_CODE (format_tree) != ADDR_EXPR)
@@ -1329,6 +1355,7 @@
 		     It will work on most machines, because size_t and int
 		     have the same mode.  But might as well warn anyway,
 		     since it will fail on other machines.  */
+		  /* XXX should we allow unsigned ints here?  */
 		  if ((TYPE_MAIN_VARIANT (TREE_TYPE (cur_param))
 		       != integer_type_node)
 		      &&
@@ -1336,7 +1363,7 @@
 		       != unsigned_type_node))
 		    {
 		      sprintf (message,
-			       "field width is not type int (arg %d)",
+			       "precision is not type int (arg %d)",
 			       arg_num);
 		      warning (message);
 		    }
@@ -1371,6 +1398,7 @@
 		      cur_param = TREE_VALUE (params);
 		      params = TREE_CHAIN (params);
 		      ++arg_num;
+		      /* XXX should we allow unsigned ints here?  */
 		      if (TYPE_MAIN_VARIANT (TREE_TYPE (cur_param))
 			  != integer_type_node)
 		        {
@@ -1388,6 +1416,56 @@
 		}
 	    }
 	}
+      if (*format_chars == 'b')
+	{
+	  /* There should be an int arg to control the string arg.  */
+	  if (params == 0)
+	    {
+	      warning (tfaff);
+	      return;
+	    }
+	    if (info->first_arg_num != 0)
+	    {
+	      cur_param = TREE_VALUE (params);
+	      params = TREE_CHAIN (params);
+	      ++arg_num;
+	      if ((TYPE_MAIN_VARIANT (TREE_TYPE (cur_param))
+		   != integer_type_node)
+		  &&
+		  (TYPE_MAIN_VARIANT (TREE_TYPE (cur_param))
+		   != unsigned_type_node))
+		{
+		  sprintf (message, "bitmap is not type int (arg %d)",
+			   arg_num);
+		  warning (message);
+		}
+	    }
+	}
+      if (*format_chars == 'D')
+	{
+	  /* There should be an unsigned char * arg before the string arg.  */
+	  if (params == 0)
+	    {
+	      warning (tfaff);
+	      return;
+	    }
+	    if (info->first_arg_num != 0)
+	    {
+	      cur_param = TREE_VALUE (params);
+	      params = TREE_CHAIN (params);
+	      ++arg_num;
+	      cur_type = TREE_TYPE (cur_param);
+	      if (TREE_CODE (cur_type) != POINTER_TYPE
+		  || TYPE_MAIN_VARIANT (TREE_TYPE (cur_type))
+		     != unsigned_char_type_node)
+		{
+		  sprintf (message,
+		      "ethernet address is not type unsigned char * (arg %d)",
+			   arg_num);
+		  warning (message);
+		}
+	    }
+	}
       if (*format_chars == 'h' || *format_chars == 'l')
 	length_char = *format_chars++;
       else if (*format_chars == 'q' || *format_chars == 'L')
@@ -1436,7 +1514,9 @@
 	  continue;
 	}
       format_chars++;
-      fci = info->is_scan ? scan_char_table : print_char_table;
+      fci = info->is_scan ? scan_char_table
+	    : flag_format_extensions ? print_char_table
+	    : unextended_print_char_table;
       while (fci->format_chars != 0
 	     && index (fci->format_chars, format_char) == 0)
 	  ++fci;