[Mono-list] patch for entry point bug

Lawrence Pit loz@cable.a2000.nl
Thu, 18 Apr 2002 23:13:04 +0300


This is a multi-part message in MIME format.

------=_NextPart_000_01F9_01C1E72E.97F7B5F0
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: 7bit

Hi Jonathan,

It seems you're right. Your second Main method doesn't qualify as an entry
point, so it should indeed compile according to the specs. I checked again,
and mcs does in fact compile correctly, it only gives a warning.

See attachment for a fix for mono.

mcs/errors/cs0028.cs:
    added

mcs/mcs/class.cs:
    added method Report28
        warning: program has more than one entry point
    added method IsEntryPoint
        implements paragraph 10.1 of the spec
    modified method Method.Define, the part at the end of the method

mcs/mcs/typemanager.cs:
    modified method CSharpName
        allow arrays of primitive type to be printed nicely
        (e.g. instead of System.String[][] it now prints string[][])
    added method CSharpSignature
        returns the signature of a method in string format to be
        used in reporting errors, warnings, etc.

mcs/mcs/rootcontext.cs:
    added static public Location EntryPointLocation;


Greets,
Lawrence Pit

> > ----- Original Message -----
> > From: "Jonathan Stowe" <gellyfish@gellyfish.com>
> > To: <mono-list@ximian.com>
> > Sent: Tuesday, April 16, 2002 22:15
> > Subject: [Mono-list] entry point bug ?
> >
> >
> > > This reveals a bug against the specification (as far as I understand
it)
> > > but I will check against csc before I put it in bugzilla :
> > >
> > > public class Test
> > > {
> > >     static void Main()
> > >     {
> > >        System.Console.WriteLine("void Main()");
> > >     }
> > >
> > >     static void Main(string[] args,int foo)
> > >     {
> > >        System.Console.WriteLine("void Main(string[] args, int foo )");
> > >     }
> > >
> > > }


------=_NextPart_000_01F9_01C1E72E.97F7B5F0
Content-Type: application/octet-stream;
	name="file.diff"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="file.diff"

? file.diff=0A=
Index: class.cs=0A=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A=
RCS file: /mono/mcs/mcs/class.cs,v=0A=
retrieving revision 1.195=0A=
diff -u -r1.195 class.cs=0A=
--- class.cs	13 Apr 2002 19:57:00 -0000	1.195=0A=
+++ class.cs	18 Apr 2002 20:58:49 -0000=0A=
@@ -2106,15 +2106,45 @@=0A=
 			return type_return_type;=0A=
 		}=0A=
 =0A=
-		void DuplicatEntryPoint (MethodInfo b)=0A=
-		{=0A=
-			Report.Error (=0A=
-				17, Location,=0A=
-				"Program `" + CodeGen.FileName +=0A=
-				"'  has more than one entry point defined: `" +=0A=
-				b.DeclaringType.Name + "." + b.Name + "'");=0A=
-		}=0A=
-		=0A=
+                void DuplicateEntryPoint (MethodInfo b, Location =
location)=0A=
+                {=0A=
+                        Report.Error (=0A=
+                                17, location,=0A=
+                                "Program `" + CodeGen.FileName +=0A=
+                                "'  has more than one entry point =
defined: `" +=0A=
+                                TypeManager.CSharpSignature(b) + "'");=0A=
+                }=0A=
+=0A=
+                void Report28 (MethodInfo b)=0A=
+                {=0A=
+                        Report.Warning (=0A=
+                                28, Location,=0A=
+                                "`" + TypeManager.CSharpSignature(b) +=0A=
+                                "' has the wrong signature to be an =
entry point");=0A=
+                }=0A=
+=0A=
+                public bool IsEntryPoint (MethodBuilder b, =
InternalParameters pinfo)=0A=
+                {=0A=
+                        if (b.ReturnType !=3D TypeManager.void_type &&=0A=
+                            b.ReturnType !=3D TypeManager.int32_type)=0A=
+                                return false;=0A=
+=0A=
+                        if (pinfo.Count =3D=3D 0)=0A=
+                                return true;=0A=
+=0A=
+                        if (pinfo.Count > 1)=0A=
+                                return false;=0A=
+=0A=
+                        Type t =3D pinfo.ParameterType(0);=0A=
+                        if (t.IsArray &&=0A=
+                            (t.GetArrayRank() =3D=3D 1) &&=0A=
+                            (t.GetElementType() =3D=3D =
TypeManager.string_type) &&=0A=
+                            (pinfo.ParameterModifier(0) =3D=3D =
Parameter.Modifier.NONE))=0A=
+                                return true;=0A=
+                        else=0A=
+                                return false;=0A=
+                }	=0A=
+=0A=
 		//=0A=
 		// Creates the type=0A=
 		//=0A=
@@ -2347,23 +2377,21 @@=0A=
 			//=0A=
 			// This is used to track the Entry Point,=0A=
 			//=0A=
-			// FIXME: Allow pluggable entry point, check arguments, etc.=0A=
-			//=0A=
 			if (Name =3D=3D "Main" &&=0A=
 			    ((ModFlags & Modifiers.STATIC) !=3D 0) && =0A=
 			    (RootContext.MainClass =3D=3D null ||=0A=
 			     RootContext.MainClass =3D=3D parent.TypeBuilder.FullName)){=0A=
-				if (RootContext.EntryPoint !=3D null){=0A=
-					DuplicatEntryPoint (MethodBuilder);=0A=
-					DuplicatEntryPoint (RootContext.EntryPoint);=0A=
-				} else =0A=
-					RootContext.EntryPoint =3D MethodBuilder;=0A=
-				=0A=
-				//=0A=
-				// FIXME: Verify that the method signature=0A=
-				// is valid for an entry point, and report=0A=
-				// error 28 if not.=0A=
-				//=0A=
+                                if (IsEntryPoint (MethodBuilder, =
ParameterInfo)) {=0A=
+                                        if (RootContext.EntryPoint =
=3D=3D null) {=0A=
+                                                RootContext.EntryPoint =
=3D MethodBuilder;=0A=
+                                                =
RootContext.EntryPointLocation =3D Location;=0A=
+                                        } else {=0A=
+                                                DuplicateEntryPoint =
(RootContext.EntryPoint, RootContext.EntryPointLocation);=0A=
+                                                DuplicateEntryPoint =
(MethodBuilder, Location);=0A=
+                                        }=0A=
+                                } else {=0A=
+                                        Report28(MethodBuilder);=0A=
+                                }=0A=
 			}=0A=
 =0A=
 			return true;=0A=
Index: rootcontext.cs=0A=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A=
RCS file: /mono/mcs/mcs/rootcontext.cs,v=0A=
retrieving revision 1.69=0A=
diff -u -r1.69 rootcontext.cs=0A=
--- rootcontext.cs	12 Apr 2002 18:51:31 -0000	1.69=0A=
+++ rootcontext.cs	18 Apr 2002 20:58:49 -0000=0A=
@@ -666,6 +666,11 @@=0A=
 		//=0A=
 		static public MethodInfo EntryPoint;=0A=
 =0A=
+                //=0A=
+                // Track the location of the entry point.=0A=
+                //=0A=
+                static public Location EntryPointLocation;=0A=
+=0A=
 		//=0A=
 		// These are used to generate unique names on the structs and fields.=0A=
 		//=0A=
Index: typemanager.cs=0A=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A=
RCS file: /mono/mcs/mcs/typemanager.cs,v=0A=
retrieving revision 1.101=0A=
diff -u -r1.101 typemanager.cs=0A=
--- typemanager.cs	12 Apr 2002 18:51:32 -0000	1.101=0A=
+++ typemanager.cs	18 Apr 2002 20:58:50 -0000=0A=
@@ -369,43 +369,70 @@=0A=
 	/// </summary>=0A=
 	static public string CSharpName (Type t)=0A=
 	{=0A=
+                string ar =3D null;=0A=
+=0A=
+                if (t.IsArray) {=0A=
+                        for (int i =3D 0; i < t.GetArrayRank(); i++)=0A=
+                                ar +=3D "[]";=0A=
+                        t =3D t.GetElementType();=0A=
+=0A=
+                }=0A=
+=0A=
 		if (t =3D=3D int32_type)=0A=
-			return "int";=0A=
+			return "int" + ar;=0A=
 		else if (t =3D=3D uint32_type)=0A=
-			return "uint";=0A=
+			return "uint" + ar;=0A=
 		else if (t =3D=3D int64_type)=0A=
-			return "long";=0A=
+			return "long" + ar;=0A=
 		else if (t =3D=3D uint64_type)=0A=
-			return "ulong";=0A=
+			return "ulong" + ar;=0A=
 		else if (t =3D=3D float_type)=0A=
-			return "float";=0A=
+			return "float" + ar;=0A=
 		else if (t =3D=3D double_type)=0A=
-			return "double";=0A=
+			return "double" + ar;=0A=
 		else if (t =3D=3D char_type)=0A=
-			return "char";=0A=
+			return "char" + ar;=0A=
 		else if (t =3D=3D short_type)=0A=
-			return "short";=0A=
+			return "short" + ar;=0A=
 		else if (t =3D=3D decimal_type)=0A=
-			return "decimal";=0A=
+			return "decimal" + ar;=0A=
 		else if (t =3D=3D bool_type)=0A=
-			return "bool";=0A=
+			return "bool" + ar;=0A=
 		else if (t =3D=3D sbyte_type)=0A=
-			return "sbyte";=0A=
+			return "sbyte" + ar;=0A=
 		else if (t =3D=3D byte_type)=0A=
-			return "byte";=0A=
+			return "byte" + ar;=0A=
 		else if (t =3D=3D short_type)=0A=
-			return "short";=0A=
+			return "short" + ar;=0A=
 		else if (t =3D=3D ushort_type)=0A=
-			return "ushort";=0A=
+			return "ushort" + ar;=0A=
 		else if (t =3D=3D string_type)=0A=
-			return "string";=0A=
+			return "string" + ar;=0A=
 		else if (t =3D=3D object_type)=0A=
-			return "object";=0A=
+			return "object" + ar;=0A=
 		else if (t =3D=3D void_type)=0A=
 			return "void";=0A=
 		else=0A=
-			return t.FullName;=0A=
+			return t.FullName + ar;=0A=
 	}=0A=
+=0A=
+        /// <summary>=0A=
+        ///   Returns the signature of the method=0A=
+        /// </summary>=0A=
+        static public string CSharpSignature (MethodBase mb)=0A=
+        {=0A=
+                string sig =3D "(";=0A=
+                InternalParameters iparams =3D =
LookupParametersByBuilder(mb);=0A=
+                for (int i =3D 0; i < iparams.Count; i++) {=0A=
+                        if (i > 0) {=0A=
+                                sig +=3D ", ";=0A=
+                        }=0A=
+                        sig +=3D iparams.ParameterDesc(i);=0A=
+                }=0A=
+                sig +=3D ")";=0A=
+=0A=
+                return mb.DeclaringType.Name + "." + mb.Name + sig;=0A=
+        }=0A=
 =0A=
 	/// <summary>=0A=
 	///   Looks up a type, and aborts if it is not found.  This is used=0A=

------=_NextPart_000_01F9_01C1E72E.97F7B5F0
Content-Type: application/octet-stream;
	name="cs0028.cs"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="cs0028.cs"

// cs0028: has the wrong signature to be an entry point=0A=
// Line: 8=0A=
=0A=
class T {=0A=
        public static int Main ()=0A=
        {=0A=
        }=0A=
        public static int Main (int foo)=0A=
        {=0A=
        }=0A=
}=0A=
=0A=

------=_NextPart_000_01F9_01C1E72E.97F7B5F0--