aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mmitchell@usa.net>1998-05-20 10:04:25 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>1998-05-20 10:04:25 +0000
commit3568074438b66ec38030db7e1a604158f73fc630 (patch)
treea65451c103401649edab63a17b403de48f8b42ca
parent3e98dfd1cb277152daf7d1b2146fb9f0386f75f3 (diff)
downloadgcc-3568074438b66ec38030db7e1a604158f73fc630.zip
gcc-3568074438b66ec38030db7e1a604158f73fc630.tar.gz
gcc-3568074438b66ec38030db7e1a604158f73fc630.tar.bz2
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
-rw-r--r--gcc/cp/ChangeLog14
-rw-r--r--gcc/cp/cp-tree.h15
-rw-r--r--gcc/cp/decl.c34
-rw-r--r--gcc/cp/friend.c4
-rw-r--r--gcc/cp/typeck.c18
5 files changed, 53 insertions, 32 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 101b598..153aedc 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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,
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 8679f58..12ca027 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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)))
+
/* Define the sets of attributes that member functions and baseclasses
can have. These are sensible combinations of {public,private,protected}
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index b6b2f66..0550db7 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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
diff --git a/gcc/cp/friend.c b/gcc/cp/friend.c
index 52a84a5..6f40f0a 100644
--- a/gcc/cp/friend.c
+++ b/gcc/cp/friend.c
@@ -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] == '_'
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index de5c3b3..98f94fa 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -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'");