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]
Other format: [Raw text]

[PATCH] PR6321


Hi, 

this patch implements checking for incorrect parameters to "main" in the C++ 
frontend. It already error'ed upon a wrong return type, now it will also 
error out if the types of the parameters don't match (the app would most 
likely crash then upon use anyway). 

The C frontend already had pedwarns implemented for this, so it was easy to 
reuse them. Patch bootstrapped, regtested on i686-suse-linux. 

This patch unfortunately needs approval (I think) of a C frontend maintainer, 
a C++ frontend maintainer and a testsuite maintainer. 

Ok for mainline?


2006-10-29  Dirk Mueller  <dmueller@suse.de>

        PR c++/6321
        * c-decl (start_function): Move code for main decl warning ..
        * c-common.c (main_args_warning): .. here.
        * c-common.h (main_args_warning): Declare.

        * decl.c(grokfndecl): Use main_args_warning.

        * g++.old-deja/g++.pt/eichin01a.C (main): Fix prototype.
        * g++.old-deja/g++.pt/eichin01b.C (main): Same.
        * g++.old-deja/g++.pt/eichin01.C (main): Same.
        * g++.old-deja/g++.mike/net25.C (main): Same.
        * g++.dg/lookup/exception1.C (main): Same.
        * g++.dg/parse/parens2.C (main): Same.


--- cp/decl.c
+++ cp/decl.c
@@ -6026,6 +6026,7 @@ grokfndecl (tree ctype,
 					  oldtypeargs);
 	  TREE_TYPE (decl) = newtype;
 	}
+      main_args_warning (decl);
       inlinep = 0;
       publicp = 1;
     }
--- c-decl.c
+++ c-decl.c
@@ -6133,54 +6133,7 @@ start_function (struct c_declspecs *decl
   /* Warn for unlikely, improbable, or stupid declarations of `main'.  */
   if (warn_main > 0 && MAIN_NAME_P (DECL_NAME (decl1)))
     {
-      tree args;
-      int argct = 0;
-
-      if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl1)))
-	  != integer_type_node)
-	pedwarn ("return type of %q+D is not %<int%>", decl1);
-
-      for (args = TYPE_ARG_TYPES (TREE_TYPE (decl1)); args;
-	   args = TREE_CHAIN (args))
-	{
-	  tree type = args ? TREE_VALUE (args) : 0;
-
-	  if (type == void_type_node)
-	    break;
-
-	  ++argct;
-	  switch (argct)
-	    {
-	    case 1:
-	      if (TYPE_MAIN_VARIANT (type) != integer_type_node)
-		pedwarn ("first argument of %q+D should be %<int%>", decl1);
-	      break;
-
-	    case 2:
-	      if (TREE_CODE (type) != POINTER_TYPE
-		  || TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
-		  || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
-		      != char_type_node))
-		pedwarn ("second argument of %q+D should be %<char **%>",
-			 decl1);
-	      break;
-
-	    case 3:
-	      if (TREE_CODE (type) != POINTER_TYPE
-		  || TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
-		  || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
-		      != char_type_node))
-		pedwarn ("third argument of %q+D should probably be "
-			 "%<char **%>", decl1);
-	      break;
-	    }
-	}
-
-      /* It is intentional that this message does not mention the third
-	 argument because it's only mentioned in an appendix of the
-	 standard.  */
-      if (argct > 0 && (argct < 2 || argct > 3))
-	pedwarn ("%q+D takes only zero or two arguments", decl1);
+      main_args_warning (decl1);
 
       if (!TREE_PUBLIC (decl1))
 	pedwarn ("%q+D is normally a non-static function", decl1);
--- c-common.c
+++ c-common.c
@@ -1010,7 +1010,6 @@ strict_aliasing_warning (tree otype, tre
     }
 }
 
-
 /* Print a warning about if (); or if () .. else; constructs
    via the special empty statement node that we create.  INNER_THEN
    and INNER_ELSE are the statement lists of the if and the else
@@ -1039,7 +1038,63 @@ empty_body_warning (tree inner_then, tre
    }
 }
 
-  
+/* Warn for unlikely, improbable, or stupid DECL declarations
+   of `main'.  */
+
+void
+main_args_warning (tree decl)
+{
+  tree args;
+  int argct = 0;
+
+  if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl)))
+     != integer_type_node)
+   pedwarn ("return type of %q+D is not %<int%>", decl);
+
+  for (args = TYPE_ARG_TYPES (TREE_TYPE (decl)); args;
+      args = TREE_CHAIN (args))
+   {
+     tree type = args ? TREE_VALUE (args) : 0;
+
+     if (type == void_type_node)
+       break;
+
+     ++argct;
+     switch (argct)
+       {
+       case 1:
+         if (TYPE_MAIN_VARIANT (type) != integer_type_node)
+           pedwarn ("first argument of %q+D should be %<int%>", decl);
+         break;
+
+       case 2:
+         if (TREE_CODE (type) != POINTER_TYPE
+             || TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
+             || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
+                 != char_type_node))
+           pedwarn ("second argument of %q+D should be %<char **%>",
+                    decl);
+         break;
+
+       case 3:
+         if (TREE_CODE (type) != POINTER_TYPE
+             || TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
+             || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
+                 != char_type_node))
+           pedwarn ("third argument of %q+D should probably be "
+                    "%<char **%>", decl);
+         break;
+       }
+   }
+
+  /* It is intentional that this message does not mention the third
+    argument because it's only mentioned in an appendix of the
+    standard.  */
+  if (argct > 0 && (argct < 2 || argct > 3))
+   pedwarn ("%q+D takes only zero or two arguments", decl);
+}
+
+ 
 /* Nonzero if constant C has a value that is permissible
    for type TYPE (an INTEGER_TYPE).  */
 
--- c-common.h
+++ c-common.h
@@ -658,6 +658,7 @@ extern void strict_aliasing_warning(tree
 extern void empty_body_warning (tree, tree);
 extern tree convert_and_check (tree, tree);
 extern void overflow_warning (tree);
+extern void main_args_warning (tree decl);
 extern bool c_determine_visibility (tree);
 extern bool same_scalar_type_ignoring_signedness (tree, tree);
 
--- g++.old-deja/g++.pt/eichin01a.C
+++ g++.old-deja/g++.pt/eichin01a.C
@@ -14,7 +14,7 @@
 
 TC<long> xjj(1,2);
 
-int main(int,char*) {
+int main(int,char**) {
   TC<float> xff(9.9,3.14);
   xjj.sz(123);
   xff.sz(2.71828);
--- g++.old-deja/g++.pt/eichin01b.C
+++ g++.old-deja/g++.pt/eichin01b.C
@@ -14,7 +14,7 @@
 
 TC<long> xjj(1,2);
 
-int main(int,char*) {
+int main(int,char**) {
   TC<float> xff(9.9,3.14);
   xjj.sz(123);
   xff.sz(2.71828);
--- g++.old-deja/g++.pt/eichin01.C
+++ g++.old-deja/g++.pt/eichin01.C
@@ -20,7 +20,7 @@
 
 TC<long> xjj(1,2);
 
-int main(int,char*) {
+int main(int,char**) {
   TC<float> xff(9.9,3.14);
   xjj.sz(123);
   xff.sz(2.71828);
--- g++.old-deja/g++.mike/net25.C
+++ g++.old-deja/g++.mike/net25.C
@@ -10,7 +10,7 @@
 
 void (*foo)();
 
-int main(int a)
+int main(int a, char** /*argv*/)
 {
   foo = a ? shake_zero : shake_one;
   return 0;
--- g++.dg/lookup/exception1.C
+++ g++.dg/lookup/exception1.C
@@ -28,6 +28,6 @@
 {
 }
 
-int main(int argc, char* argv) {
+int main(int argc, char* argv[]) {
   ns::Test test;
 }
--- g++.dg/parse/parens2.C
+++ g++.dg/parse/parens2.C
@@ -1,6 +1,6 @@
 /* PR c++/8842. */
 /* { dg-do compile } */
-int main( int argc, char* argv )
+int main( int argc, char* argv[] )
 {
     int i = 5;
     // This always worked:


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