diff -ur gcc/gcc/c-parse.in gcc-tmp/gcc/c-parse.in
--- gcc/gcc/c-parse.in	Sun Sep 17 18:38:10 2000
+++ gcc-tmp/gcc/c-parse.in	Sat Oct  7 00:32:24 2000
@@ -498,10 +498,12 @@
 		  if (TREE_CODE ($2) == COMPONENT_REF
 		      && DECL_C_BIT_FIELD (TREE_OPERAND ($2, 1)))
 		    error ("`sizeof' applied to a bit-field");
-		  $$ = c_sizeof (TREE_TYPE ($2)); }
+		  $$ = c_sizeof (TREE_TYPE ($2));
+		  TREE_WAS_SIZEOF ($$) = 1; }
 	| sizeof '(' typename ')'  %prec HYPERUNARY
 		{ skip_evaluation--;
-		  $$ = c_sizeof (groktypename ($3)); }
+		  $$ = c_sizeof (groktypename ($3));
+		  TREE_WAS_SIZEOF ($$) = 1; }
 	| alignof unary_expr  %prec UNARY
 		{ skip_evaluation--;
 		  $$ = c_alignof_expr ($2); }
diff -ur gcc/gcc/c-typeck.c gcc-tmp/gcc/c-typeck.c
--- gcc/gcc/c-typeck.c	Wed Sep 20 01:26:38 2000
+++ gcc-tmp/gcc/c-typeck.c	Sat Oct  7 00:32:24 2000
@@ -1524,6 +1524,30 @@
   /* fntype now gets the type of function pointed to.  */
   fntype = TREE_TYPE (fntype);
 
+  /* Do this check even if they are using their own memset */
+  if (!flag_no_builtin && name
+      && IDENTIFIER_LENGTH (name) == 6
+      && strcmp (IDENTIFIER_POINTER (name), "memset") == 0)
+    {
+      tree arg1, arg2, arg3;
+
+      if ((arg1 = params)
+	  && (arg2 = TREE_CHAIN(arg1))
+	  && (arg3 = TREE_CHAIN(arg2)))
+	{
+	  /* If arg2 is sizeof-derived and arg3 isn't always warn. */
+	  if (TREE_WAS_SIZEOF (TREE_VALUE (arg2))
+	      && !TREE_WAS_SIZEOF (TREE_VALUE (arg3)))
+	    warning ("memset arguments 2 and 3 probably reversed");
+	  else /* Try harder for common `memset(ptr, len, 0)' mistake. */
+	    if (TREE_CODE (TREE_VALUE (arg3)) == INTEGER_CST
+		&& TREE_INT_CST_LOW (TREE_VALUE (arg3)) == 0
+		&& TREE_INT_CST_HIGH (TREE_VALUE (arg3)) == 0
+		&& (TREE_INT_CST_LOW (TREE_VALUE (arg2)) != 0
+		    || TREE_INT_CST_HIGH (TREE_VALUE (arg2)) != 0))
+	      warning ("memset called with zero length");
+	}
+    }
   /* Convert the parameters to the types declared in the
      function prototype, or apply default promotions.  */
 
diff -ur gcc/gcc/flags.h gcc-tmp/gcc/flags.h
--- gcc/gcc/flags.h	Tue Sep 26 09:54:03 2000
+++ gcc-tmp/gcc/flags.h	Sat Oct  7 00:35:14 2000
@@ -608,4 +608,7 @@
    and to print them when we are done.  */
 extern int flag_detailed_statistics;
 
+/* Nonzero means don't recognize any builtin functions.  */
+extern int flag_no_builtin;
+
 #endif /* GCC_FLAGS_H */
diff -ur gcc/gcc/tree.c gcc-tmp/gcc/tree.c
--- gcc/gcc/tree.c	Wed Sep 20 05:19:43 2000
+++ gcc-tmp/gcc/tree.c	Sat Oct  7 00:45:33 2000
@@ -3325,11 +3325,15 @@
 	{
 	  if (TREE_SIDE_EFFECTS (arg0))
 	    TREE_SIDE_EFFECTS (t) = 1;
+	  if (TREE_WAS_SIZEOF (arg0))
+	    TREE_WAS_SIZEOF (t) = 1;
 	}
       if (arg1 && fro > 1)
 	{
 	  if (TREE_SIDE_EFFECTS (arg1))
 	    TREE_SIDE_EFFECTS (t) = 1;
+	  if (TREE_WAS_SIZEOF (arg1))
+	    TREE_WAS_SIZEOF (t) = 1;
 	}
     }
   else if (length == 1)
@@ -3344,6 +3348,8 @@
 	{
 	  if (arg0 && TREE_SIDE_EFFECTS (arg0))
 	    TREE_SIDE_EFFECTS (t) = 1;
+	  if (arg0 && TREE_WAS_SIZEOF (arg0))
+	    TREE_WAS_SIZEOF (t) = 1;
 	}
     }
   else
@@ -3356,6 +3362,8 @@
 	    {
 	      if (TREE_SIDE_EFFECTS (operand))
 		TREE_SIDE_EFFECTS (t) = 1;
+	      if (TREE_WAS_SIZEOF (operand))
+		TREE_WAS_SIZEOF (t) = 1;
 	    }
 	}
     }
@@ -3407,8 +3415,13 @@
   TREE_TYPE (t) = type;
   TREE_COMPLEXITY (t) = 0;
   TREE_OPERAND (t, 0) = node;
-  if (node && first_rtl_op (code) != 0 && TREE_SIDE_EFFECTS (node))
-    TREE_SIDE_EFFECTS (t) = 1;
+  if (node && first_rtl_op (code) != 0)
+    {
+      if (TREE_SIDE_EFFECTS (node))
+	TREE_SIDE_EFFECTS (t) = 1;
+      if (TREE_WAS_SIZEOF (node))
+	TREE_WAS_SIZEOF (t) = 1;
+    }
 
   switch (code)
     {
@@ -3436,6 +3449,7 @@
    and leave the TREE_SIDE_EFFECTS as 0.
    It is permissible for arguments to be null,
    or even garbage if their values do not matter.  */
+/* ??? Should copy TREE_WAS_SIZEOF, for better coverage. */
 
 tree
 build_nt VPARAMS ((enum tree_code code, ...))
diff -ur gcc/gcc/tree.h gcc-tmp/gcc/tree.h
--- gcc/gcc/tree.h	Wed Sep 20 05:19:43 2000
+++ gcc-tmp/gcc/tree.h	Sat Oct  7 00:46:47 2000
@@ -147,6 +147,7 @@
   unsigned private_flag : 1;
   unsigned protected_flag : 1;
   unsigned bounded_flag : 1;
+  unsigned size_type_flag : 1;
 
   unsigned lang_flag_0 : 1;
   unsigned lang_flag_1 : 1;
@@ -642,6 +643,9 @@
    argument type(s).  */
 
 #define TREE_BOUNDED(NODE) ((NODE)->common.bounded_flag)
+
+/* A sizeof()-derived expression, to check memset args */
+#define TREE_WAS_SIZEOF(NODE) ((NODE)->common.size_type_flag)
 
 /* These flags are available for each language front end to use internally.  */
 #define TREE_LANG_FLAG_0(NODE) ((NODE)->common.lang_flag_0)
