Commit 35680744 by Mark Mitchell Committed by Mark Mitchell

cp-tree.h (MAIN_NAME_P): New macro.

	* 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
parent 3e98dfd1
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> Wed May 20 02:16:01 1998 Jason Merrill <jason@yorick.cygnus.com>
* decl2.c (start_objects, finish_objects, do_dtors, * decl2.c (start_objects, finish_objects, do_dtors,
......
...@@ -1918,6 +1918,21 @@ extern int current_function_parms_stored; ...@@ -1918,6 +1918,21 @@ extern int current_function_parms_stored;
#define ANON_PARMNAME_P(ID_NODE) (IDENTIFIER_POINTER (ID_NODE)[0] == '_' \ #define ANON_PARMNAME_P(ID_NODE) (IDENTIFIER_POINTER (ID_NODE)[0] == '_' \
&& IDENTIFIER_POINTER (ID_NODE)[1] <= '9') && IDENTIFIER_POINTER (ID_NODE)[1] <= '9')
#endif /* !defined(NO_DOLLAR_IN_LABEL) || !defined(NO_DOT_IN_LABEL) */ #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 /* Define the sets of attributes that member functions and baseclasses
can have. These are sensible combinations of {public,private,protected} can have. These are sensible combinations of {public,private,protected}
......
...@@ -3345,6 +3345,20 @@ pushdecl (x) ...@@ -3345,6 +3345,20 @@ pushdecl (x)
return t; 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)) if (TREE_CODE (x) == FUNCTION_DECL && ! DECL_FUNCTION_MEMBER_P (x))
...@@ -7545,7 +7559,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals, ...@@ -7545,7 +7559,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
if (ctype) if (ctype)
DECL_CLASS_CONTEXT (decl) = 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) if (inlinep)
error ("cannot declare `main' to be inline"); error ("cannot declare `main' to be inline");
...@@ -10077,9 +10091,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) ...@@ -10077,9 +10091,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
if (current_lang_name == lang_name_cplusplus if (current_lang_name == lang_name_cplusplus
&& ! processing_template_decl && ! processing_template_decl
&& ! (IDENTIFIER_LENGTH (original_name) == 4 && ! MAIN_NAME_P (original_name)
&& IDENTIFIER_POINTER (original_name)[0] == 'm'
&& strcmp (IDENTIFIER_POINTER (original_name), "main") == 0)
&& ! (IDENTIFIER_LENGTH (original_name) > 10 && ! (IDENTIFIER_LENGTH (original_name) > 10
&& IDENTIFIER_POINTER (original_name)[0] == '_' && IDENTIFIER_POINTER (original_name)[0] == '_'
&& IDENTIFIER_POINTER (original_name)[1] == '_' && IDENTIFIER_POINTER (original_name)[1] == '_'
...@@ -11724,9 +11736,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p) ...@@ -11724,9 +11736,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
if (TREE_CODE (fntype) == METHOD_TYPE) if (TREE_CODE (fntype) == METHOD_TYPE)
ctype = TYPE_METHOD_BASETYPE (fntype); ctype = TYPE_METHOD_BASETYPE (fntype);
else if (IDENTIFIER_LENGTH (DECL_NAME (decl1)) == 4 else if (DECL_MAIN_P (decl1))
&& ! strcmp (IDENTIFIER_POINTER (DECL_NAME (decl1)), "main")
&& DECL_CONTEXT (decl1) == NULL_TREE)
{ {
/* If this doesn't return integer_type, complain. */ /* If this doesn't return integer_type, complain. */
if (TREE_TYPE (TREE_TYPE (decl1)) != integer_type_node) if (TREE_TYPE (TREE_TYPE (decl1)) != integer_type_node)
...@@ -12121,10 +12131,8 @@ store_parm_decls () ...@@ -12121,10 +12131,8 @@ store_parm_decls ()
/* If this function is `main', emit a call to `__main' /* If this function is `main', emit a call to `__main'
to run global initializers, etc. */ to run global initializers, etc. */
if (DECL_NAME (fndecl) if (DECL_MAIN_P (fndecl))
&& IDENTIFIER_LENGTH (DECL_NAME (fndecl)) == 4 expand_main_function ();
&& strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)), "main") == 0
&& DECL_CONTEXT (fndecl) == global_namespace)
{ {
expand_main_function (); expand_main_function ();
} }
...@@ -12576,9 +12584,7 @@ finish_function (lineno, call_poplevel, nested) ...@@ -12576,9 +12584,7 @@ finish_function (lineno, call_poplevel, nested)
current_function_assigns_this = 0; current_function_assigns_this = 0;
current_function_just_assigned_this = 0; current_function_just_assigned_this = 0;
} }
else if (IDENTIFIER_LENGTH (DECL_NAME (fndecl)) == 4 else if (DECL_MAIN_P (fndecl))
&& ! strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)), "main")
&& DECL_CONTEXT (fndecl) == global_namespace)
{ {
/* Make it so that `main' always returns 0 by default. */ /* Make it so that `main' always returns 0 by default. */
#ifdef VMS #ifdef VMS
......
...@@ -364,9 +364,7 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals, funcdef_flag) ...@@ -364,9 +364,7 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals, funcdef_flag)
} }
} }
else if (TREE_CODE (decl) == FUNCTION_DECL else if (TREE_CODE (decl) == FUNCTION_DECL
&& ((IDENTIFIER_LENGTH (declarator) == 4 && (MAIN_NAME_P (declarator)
&& IDENTIFIER_POINTER (declarator)[0] == 'm'
&& ! strcmp (IDENTIFIER_POINTER (declarator), "main"))
|| (IDENTIFIER_LENGTH (declarator) > 10 || (IDENTIFIER_LENGTH (declarator) > 10
&& IDENTIFIER_POINTER (declarator)[0] == '_' && IDENTIFIER_POINTER (declarator)[0] == '_'
&& IDENTIFIER_POINTER (declarator)[1] == '_' && IDENTIFIER_POINTER (declarator)[1] == '_'
......
...@@ -2744,14 +2744,8 @@ build_function_call_real (function, params, require_complete, flags) ...@@ -2744,14 +2744,8 @@ build_function_call_real (function, params, require_complete, flags)
fndecl = function; fndecl = function;
/* Convert anything with function type to a pointer-to-function. */ /* Convert anything with function type to a pointer-to-function. */
if (pedantic if (pedantic && DECL_MAIN_P (function))
&& name pedwarn ("ANSI C++ forbids calling `main' from within program");
&& 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 /* Differs from default_conversion by not setting TREE_ADDRESSABLE
(because calling an inline function does not mean the function (because calling an inline function does not mean the function
...@@ -4509,13 +4503,7 @@ build_unary_op (code, xarg, noconvert) ...@@ -4509,13 +4503,7 @@ build_unary_op (code, xarg, noconvert)
TREE_CONSTANT (arg) = TREE_CONSTANT (TREE_OPERAND (arg, 0)); TREE_CONSTANT (arg) = TREE_CONSTANT (TREE_OPERAND (arg, 0));
return arg; return arg;
} }
else if (pedantic else if (pedantic && DECL_MAIN_P (arg))
&& 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 */ /* ARM $3.4 */
pedwarn ("taking address of function `main'"); pedwarn ("taking address of function `main'");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment