PATCH for crash on redefinition of main
Mark Mitchell
mmitchell@usa.net
Tue May 19 21:49:00 GMT 1998
Jason --
Here's a patch to avoid crashing on two definitions of main in the
same translation unit. OK?
--
Mark Mitchell <mmitchell@usa.net>
http://home.earthlink.net/~mbmitchell
Consulting Services Available
Tue May 19 15:59:02 1998 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.
Index: cp-tree.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.69
diff -c -p -r1.69 cp-tree.h
*** cp-tree.h 1998/05/19 14:51:34 1.69
--- cp-tree.h 1998/05/19 22:38:19
*************** extern int current_function_parms_stored
*** 1918,1923 ****
--- 1921,1941 ----
#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)))
+
/* Define the sets of attributes that member functions and baseclasses
can have. These are sensible combinations of {public,private,protected}
Index: decl.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/decl.c,v
retrieving revision 1.112
diff -c -p -r1.112 decl.c
*** decl.c 1998/05/19 15:15:20 1.112
--- decl.c 1998/05/19 22:39:00
*************** pushdecl (x)
*** 3345,3350 ****
--- 3345,3364 ----
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))
*************** grokfndecl (ctype, type, declarator, ori
*** 7545,7551 ****
if (ctype)
DECL_CLASS_CONTEXT (decl) = ctype;
! if (ctype == NULL_TREE && ! strcmp (IDENTIFIER_POINTER (declarator), "main"))
{
if (inlinep)
error ("cannot declare `main' to be inline");
--- 7559,7565 ----
if (ctype)
DECL_CLASS_CONTEXT (decl) = ctype;
! if (ctype == NULL_TREE && MAIN_NAME_P (declarator))
{
if (inlinep)
error ("cannot declare `main' to be inline");
*************** grokdeclarator (declarator, declspecs, d
*** 10077,10085 ****
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)
&& ! (IDENTIFIER_LENGTH (original_name) > 10
&& IDENTIFIER_POINTER (original_name)[0] == '_'
&& IDENTIFIER_POINTER (original_name)[1] == '_'
--- 10091,10097 ----
if (current_lang_name == lang_name_cplusplus
&& ! processing_template_decl
! && ! MAIN_NAME_P (original_name)
&& ! (IDENTIFIER_LENGTH (original_name) > 10
&& IDENTIFIER_POINTER (original_name)[0] == '_'
&& IDENTIFIER_POINTER (original_name)[1] == '_'
*************** start_function (declspecs, declarator, a
*** 11724,11732 ****
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)
{
/* If this doesn't return integer_type, complain. */
if (TREE_TYPE (TREE_TYPE (decl1)) != integer_type_node)
--- 11736,11742 ----
if (TREE_CODE (fntype) == METHOD_TYPE)
ctype = TYPE_METHOD_BASETYPE (fntype);
! else if (DECL_MAIN_P (decl1))
{
/* If this doesn't return integer_type, complain. */
if (TREE_TYPE (TREE_TYPE (decl1)) != integer_type_node)
*************** store_parm_decls ()
*** 12121,12130 ****
/* 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)
{
expand_main_function ();
}
--- 12131,12138 ----
/* If this function is `main', emit a call to `__main'
to run global initializers, etc. */
! if (DECL_MAIN_P (fndecl))
! expand_main_function ();
{
expand_main_function ();
}
*************** finish_function (lineno, call_poplevel,
*** 12576,12584 ****
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)
{
/* Make it so that `main' always returns 0 by default. */
#ifdef VMS
--- 12584,12590 ----
current_function_assigns_this = 0;
current_function_just_assigned_this = 0;
}
! else if (DECL_MAIN_P (fndecl))
{
/* Make it so that `main' always returns 0 by default. */
#ifdef VMS
Index: friend.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/friend.c,v
retrieving revision 1.15
diff -c -p -r1.15 friend.c
*** friend.c 1998/05/08 02:05:54 1.15
--- friend.c 1998/05/19 22:39:14
*************** do_friend (ctype, declarator, decl, parm
*** 364,372 ****
}
}
else if (TREE_CODE (decl) == FUNCTION_DECL
! && ((IDENTIFIER_LENGTH (declarator) == 4
! && IDENTIFIER_POINTER (declarator)[0] == 'm'
! && ! strcmp (IDENTIFIER_POINTER (declarator), "main"))
|| (IDENTIFIER_LENGTH (declarator) > 10
&& IDENTIFIER_POINTER (declarator)[0] == '_'
&& IDENTIFIER_POINTER (declarator)[1] == '_'
--- 364,370 ----
}
}
else if (TREE_CODE (decl) == FUNCTION_DECL
! && (MAIN_NAME_P (declarator)
|| (IDENTIFIER_LENGTH (declarator) > 10
&& IDENTIFIER_POINTER (declarator)[0] == '_'
&& IDENTIFIER_POINTER (declarator)[1] == '_'
Index: typeck.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/typeck.c,v
retrieving revision 1.70
diff -c -p -r1.70 typeck.c
*** typeck.c 1998/05/19 14:51:37 1.70
--- typeck.c 1998/05/19 22:40:18
*************** build_function_call_real (function, para
*** 2744,2757 ****
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");
! }
/* Differs from default_conversion by not setting TREE_ADDRESSABLE
(because calling an inline function does not mean the function
--- 2744,2751 ----
fndecl = function;
/* Convert anything with function type to a pointer-to-function. */
! 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
*************** build_unary_op (code, xarg, noconvert)
*** 4509,4521 ****
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"))
/* ARM $3.4 */
pedwarn ("taking address of function `main'");
--- 4503,4509 ----
TREE_CONSTANT (arg) = TREE_CONSTANT (TREE_OPERAND (arg, 0));
return arg;
}
! else if (pedantic && DECL_MAIN_P (arg))
/* ARM $3.4 */
pedwarn ("taking address of function `main'");
Index: ../testsuite/g++.old-deja/g++.other/main1.C
===================================================================
RCS file: main1.C
diff -N main1.C
*** /dev/null Mon Dec 31 20:00:00 1979
--- main1.C Tue May 19 15:40:38 1998
***************
*** 0 ****
--- 1,12 ----
+ // Build don't linK:
+
+ int main()
+ {
+ return 0;
+ }
+
+
+ int main(int, const char**)
+ {
+ return 0;
+ }
More information about the Gcc-bugs
mailing list