cp-tree.h (MAIN_NAME_P): New macro.
authorMark Mitchell <mmitchell@usa.net>
Wed, 20 May 1998 10:04:25 +0000 (10:04 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Wed, 20 May 1998 10:04:25 +0000 (10:04 +0000)
* cp-tree.h (MAIN_NAME_P): New macro.
(DECL_MAIN_P): Likwise.
* decl.c (pushdecl): Avoid crashing on redefinitions of `main'.
(grokfndecl): Use the new macros.
(grokdeclarator): Likewise.
(start_function): Likewise.
(store_parm_decls): Likewise.
(finsh_function): Likewise.
* friend.c (do_friend): Likewise.
* typeck.c (build_function_call_real): Likewise.
(build_unary_op): Likewise.

From-SVN: r19907

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/friend.c
gcc/cp/typeck.c

index 101b598641588dfbf45ad44c29eab747d85e0d0f..153aedc220b6cd485265f222078a160781e7a4d3 100644 (file)
@@ -1,3 +1,17 @@
+1998-05-20  Mark Mitchell  <mmitchell@usa.net>
+
+       * cp-tree.h (MAIN_NAME_P): New macro.
+       (DECL_MAIN_P): Likwise.
+       * decl.c (pushdecl): Avoid crashing on redefinitions of `main'.
+       (grokfndecl): Use the new macros.
+       (grokdeclarator): Likewise.
+       (start_function): Likewise.
+       (store_parm_decls): Likewise.
+       (finsh_function): Likewise.
+       * friend.c (do_friend): Likewise.
+       * typeck.c (build_function_call_real): Likewise.
+       (build_unary_op): Likewise.
+
 Wed May 20 02:16:01 1998  Jason Merrill  <jason@yorick.cygnus.com>
 
        * decl2.c (start_objects, finish_objects, do_dtors,
index 8679f58052a21a7461d7e27684684eb734da44c3..12ca0275e18abffaa9eddc80c92c0fb1befc9bca 100644 (file)
@@ -1918,6 +1918,21 @@ extern int current_function_parms_stored;
 #define ANON_PARMNAME_P(ID_NODE) (IDENTIFIER_POINTER (ID_NODE)[0] == '_' \
                                  && IDENTIFIER_POINTER (ID_NODE)[1] <= '9')
 #endif /* !defined(NO_DOLLAR_IN_LABEL) || !defined(NO_DOT_IN_LABEL) */
+
+/* Returns non-zero iff ID_NODE is an IDENTIFIER_NODE whose name is
+   `main'.  */
+#define MAIN_NAME_P(ID_NODE) \
+   (strcmp (IDENTIFIER_POINTER (ID_NODE), "main") == 0)
+
+/* Returns non-zero iff NODE is a declaration for the global function
+   `main'.  */
+#define DECL_MAIN_P(NODE)                              \
+   (TREE_CODE (NODE) == FUNCTION_DECL                  \
+    && (DECL_CONTEXT (NODE) == global_namespace        \
+       || DECL_CONTEXT (NODE) == NULL_TREE)            \
+    && DECL_NAME (NODE) != NULL_TREE                   \
+    && MAIN_NAME_P (DECL_NAME (NODE)))
+
 \f
 /* Define the sets of attributes that member functions and baseclasses
    can have.  These are sensible combinations of {public,private,protected}
index b6b2f66fef93f32c76838ed8215887a744bc5c39..0550db7e24e59ee632b0b429eeaf59b2b2a8cbb1 100644 (file)
@@ -3345,6 +3345,20 @@ pushdecl (x)
 
              return t;
            }
+         else if (DECL_MAIN_P (x))
+           {
+             /* A redeclaration of main, but not a duplicate of the
+                previous one. 
+
+                [basic.start.main]
+
+                This function shall not be overloaded.  */
+             cp_error_at ("invalid redeclaration of `%D'", t);
+             cp_error ("as `%D'", x);
+             /* We don't try to push this declaration since that
+                causes a crash.  */
+             return x;
+           }
        }
 
       if (TREE_CODE (x) == FUNCTION_DECL && ! DECL_FUNCTION_MEMBER_P (x))
@@ -7545,7 +7559,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
   if (ctype)
     DECL_CLASS_CONTEXT (decl) = ctype;
 
-  if (ctype == NULL_TREE && ! strcmp (IDENTIFIER_POINTER (declarator), "main"))
+  if (ctype == NULL_TREE && MAIN_NAME_P (declarator))
     {
       if (inlinep)
        error ("cannot declare `main' to be inline");
@@ -10077,9 +10091,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
 
            if (current_lang_name == lang_name_cplusplus
                && ! processing_template_decl
-               && ! (IDENTIFIER_LENGTH (original_name) == 4
-                     && IDENTIFIER_POINTER (original_name)[0] == 'm'
-                     && strcmp (IDENTIFIER_POINTER (original_name), "main") == 0)
+               && ! MAIN_NAME_P (original_name)
                && ! (IDENTIFIER_LENGTH (original_name) > 10
                      && IDENTIFIER_POINTER (original_name)[0] == '_'
                      && IDENTIFIER_POINTER (original_name)[1] == '_'
@@ -11724,9 +11736,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
 
       if (TREE_CODE (fntype) == METHOD_TYPE)
        ctype = TYPE_METHOD_BASETYPE (fntype);
-      else if (IDENTIFIER_LENGTH (DECL_NAME (decl1)) == 4
-              && ! strcmp (IDENTIFIER_POINTER (DECL_NAME (decl1)), "main")
-              && DECL_CONTEXT (decl1) == NULL_TREE)
+      else if (DECL_MAIN_P (decl1))
        {
          /* If this doesn't return integer_type, complain.  */
          if (TREE_TYPE (TREE_TYPE (decl1)) != integer_type_node)
@@ -12121,10 +12131,8 @@ store_parm_decls ()
 
   /* If this function is `main', emit a call to `__main'
      to run global initializers, etc.  */
-  if (DECL_NAME (fndecl)
-      && IDENTIFIER_LENGTH (DECL_NAME (fndecl)) == 4
-      && strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)), "main") == 0
-      && DECL_CONTEXT (fndecl) == global_namespace)
+  if (DECL_MAIN_P (fndecl))
+    expand_main_function ();
     {
       expand_main_function ();
     }
@@ -12576,9 +12584,7 @@ finish_function (lineno, call_poplevel, nested)
          current_function_assigns_this = 0;
          current_function_just_assigned_this = 0;
        }
-      else if (IDENTIFIER_LENGTH (DECL_NAME (fndecl)) == 4
-              && ! strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)), "main")
-              && DECL_CONTEXT (fndecl) == global_namespace)
+      else if (DECL_MAIN_P (fndecl))
        {
          /* Make it so that `main' always returns 0 by default.  */
 #ifdef VMS
index 52a84a54d39634e4b0085e6fd6edd40ee0a6a9b0..6f40f0adad8c5416e5cb2319a051f8887748dbcd 100644 (file)
@@ -364,9 +364,7 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals, funcdef_flag)
        }
     }
   else if (TREE_CODE (decl) == FUNCTION_DECL
-          && ((IDENTIFIER_LENGTH (declarator) == 4
-               && IDENTIFIER_POINTER (declarator)[0] == 'm'
-               && ! strcmp (IDENTIFIER_POINTER (declarator), "main"))
+          && (MAIN_NAME_P (declarator)
               || (IDENTIFIER_LENGTH (declarator) > 10
                   && IDENTIFIER_POINTER (declarator)[0] == '_'
                   && IDENTIFIER_POINTER (declarator)[1] == '_'
index de5c3b34f43931c202ae3658c5b5fbcaac0de207..98f94fa1f65750ddc6ad3491bc3ffe66a933c509 100644 (file)
@@ -2744,14 +2744,8 @@ build_function_call_real (function, params, require_complete, flags)
       fndecl = function;
 
       /* Convert anything with function type to a pointer-to-function.  */
-      if (pedantic
-         && name
-         && IDENTIFIER_LENGTH (name) == 4
-         && ! strcmp (IDENTIFIER_POINTER (name), "main")
-         && DECL_CONTEXT (function) == global_namespace)
-       {
-         pedwarn ("ANSI C++ forbids calling `main' from within program");
-       }
+      if (pedantic && DECL_MAIN_P (function))
+       pedwarn ("ANSI C++ forbids calling `main' from within program");
 
       /* Differs from default_conversion by not setting TREE_ADDRESSABLE
         (because calling an inline function does not mean the function
@@ -4509,13 +4503,7 @@ build_unary_op (code, xarg, noconvert)
          TREE_CONSTANT (arg) = TREE_CONSTANT (TREE_OPERAND (arg, 0));
          return arg;
        }
-      else if (pedantic
-              && TREE_CODE (arg) == FUNCTION_DECL
-              && DECL_NAME (arg)
-              && DECL_CONTEXT (arg) == global_namespace
-              && IDENTIFIER_LENGTH (DECL_NAME (arg)) == 4
-              && IDENTIFIER_POINTER (DECL_NAME (arg))[0] == 'm'
-              && ! strcmp (IDENTIFIER_POINTER (DECL_NAME (arg)), "main"))
+      else if (pedantic && DECL_MAIN_P (arg))
        /* ARM $3.4 */
        pedwarn ("taking address of function `main'");