2002-03-12 Miguel de Icaza <miguel@ximian.com>
authorMiguel de Icaza <miguel@gnome.org>
Tue, 12 Mar 2002 02:41:25 +0000 (02:41 -0000)
committerMiguel de Icaza <miguel@gnome.org>
Tue, 12 Mar 2002 02:41:25 +0000 (02:41 -0000)
* class.cs: Only report 108 if there is no `new' modifier.

* cs-parser.jay: rework foreach statement to work with the new
changes to the policy on SimpleNames.

* report.cs: support Stacktrace on warnings as well.

* makefile: drop --unsafe and /unsafe from the compile.

2002-03-11  Miguel de Icaza  <miguel@ximian.com>

* ecore.cs (SimpleName.SimpleNameResolve): Perform local variable
lookups here, instead of doing that at parse time.  This means
that our grammar will not introduce `LocalVariableReferences' as
expressions at this point.  That solves the problem of code like
this:

class X {
   static void Main ()
   { int X = 1;
    { X x = null }}}

This is only half the fix.  The full fix requires parameters to
also be handled in this way.

Added test for the above new scenario, updated our foreach tests to try
the new changes.

svn path=/trunk/mcs/; revision=3059

mcs/mcs/ChangeLog
mcs/mcs/TODO
mcs/mcs/class.cs
mcs/mcs/cs-parser.jay
mcs/mcs/ecore.cs
mcs/mcs/makefile
mcs/mcs/report.cs
mcs/mcs/statement.cs
mcs/tests/makefile
mcs/tests/test-36.cs
mcs/tests/test-84.cs [new file with mode: 0755]

index e4394c2670cfc5f51a03911f3512dde922390c94..1dda870a05e4a1ad6970a74caa33c0ffe71efec7 100755 (executable)
@@ -1,5 +1,30 @@
+2002-03-12  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs: Only report 108 if there is no `new' modifier.
+
+       * cs-parser.jay: rework foreach statement to work with the new
+       changes to the policy on SimpleNames.
+       
+       * report.cs: support Stacktrace on warnings as well.
+
+       * makefile: drop --unsafe and /unsafe from the compile.
+
 2002-03-11  Miguel de Icaza  <miguel@ximian.com>
 
+       * ecore.cs (SimpleName.SimpleNameResolve): Perform local variable
+       lookups here, instead of doing that at parse time.  This means
+       that our grammar will not introduce `LocalVariableReferences' as
+       expressions at this point.  That solves the problem of code like
+       this:
+
+       class X {
+          static void Main ()
+          { int X = 1;
+           { X x = null }}}
+
+       This is only half the fix.  The full fix requires parameters to
+       also be handled in this way.
+
        * class.cs (Property.DefineMethod): When implementing an interface
        method, set newslot, when implementing an abstract method, do not
        set the flag (before we tried never setting it, or always setting
index 70de1839a90483deffeb045d34f3a1139e8ae9f4..ea312816a9384057f51248c5cda1d517e0af6e46 100644 (file)
@@ -1,3 +1,16 @@
+NOTES:
+       I am trying to remove the LocalVariableReference from the code
+       but the compiler does not pass its own self-compilation.
+
+       The problem is that constructs with embedded_statements like:
+
+       foreach (int b in X)
+               if (b ...)
+
+       The ec.CurrentBlock is not updated with the fact that `b' lives
+       in an implicit internal block, and the lookup is attempted on the
+       parent's block, hence rendering the lookup invalid.
+
 Major tasks:
 ------------
 
@@ -45,7 +58,9 @@ BUGS
 * Emit warning on hiding members without NEW not only in members.
 
 * Implement visibility.
+
+* Casts need to trigger a name resolution against types only.
+
 * Adding variables.
 
        We do add variables in a number of places, and this is erroneous:
index e74cb98f54feaa2330326dc45b0a86876f50bd75..7707df85aed4e562c4f21c9dc80536174a9a7ca3 100755 (executable)
@@ -1118,7 +1118,8 @@ namespace Mono.CSharp {
                                        // then: `continue;' 
                                }
 #endif
-                               Report108 (mc.Location, defined_names [idx]);
+                               if ((mc.ModFlags & Modifiers.NEW) == 0)
+                                       Report108 (mc.Location, defined_names [idx]);
                        }
                        
                        foreach (object o in remove_list)
index f49caf47667d5f67b1b55474582dada455ecfc1d..421de3d84d670964ca95c23eb4525aaea0325789 100755 (executable)
@@ -1,5 +1,10 @@
 %{
 //
+// OPTIMIZATION:
+//   This loop is pointless:
+//    while (current_block != prev_block)
+//       current_block = current_block.Parent;
+//
 // cs-parser.jay: The Parser for the C# compiler
 //
 // Author: Miguel de Icaza (miguel@gnu.org)
@@ -3102,7 +3107,8 @@ for_iterator
 statement_expression_list
        : statement_expression  
          {
-               Block b = new Block (null, true);
+               // CHANGE: was `null'
+               Block b = new Block (current_block, true);   
 
                b.AddStatement ((Statement) $1);
                $$ = b;
@@ -3138,22 +3144,24 @@ foreach_statement
                }
 
                v = new LocalVariableReference (foreach_block, (string) $4, l);
-
-               current_block.AddStatement (foreach_block);
                current_block = foreach_block;
 
                oob_stack.Push (v);
+               oob_stack.Push (current_block);
          } 
          embedded_statement 
          {
+               Block foreach_block = (Block) oob_stack.Pop ();
                LocalVariableReference v = (LocalVariableReference) oob_stack.Pop ();
                Block prev_block = (Block) oob_stack.Pop ();
                Location l = (Location) oob_stack.Pop ();
 
-               while (current_block != prev_block)
-                       current_block = current_block.Parent;
+               current_block = prev_block;
 
-               $$ = new Foreach ((string) $3, v, (Expression) $7, (Statement) $10, l);
+               Foreach f = new Foreach ((string) $3, v, (Expression) $7, (Statement) $10, l);
+               foreach_block.AddStatement (f);
+
+               $$ = foreach_block;
          }
        ;
 
@@ -3642,6 +3650,11 @@ CheckDef (bool result, string name)
        CheckDef (AdditionResult.NameExists, name);
 }
 
+//
+// This routine should be removed soon.  I am in the process of making
+// changes to never keep anything but SimpleNames during parsing, as
+// that breaks some kinds of code (documented in the ChangeLog).
+//
 Expression
 SimpleLookup (string name, Location loc)
 {
@@ -3650,10 +3663,13 @@ SimpleLookup (string name, Location loc)
        // as `expression' is allowed in argument_lists, which 
        // do not exist inside a block.  
        //
+#if BLAH
        if (current_block != null){
-               if (current_block.IsVariableDefined (name))
+               if (current_block.IsVariableDefined (name)){
                        return new LocalVariableReference (current_block, name, loc);
+               }
        }
+#endif
 
        if (current_local_parameters != null){
                int idx;
index dd182641eb91bde9725fb29c74e88f2266d13097..517debd337c6dad8caacfb405464bf0f53e5496f 100755 (executable)
@@ -232,7 +232,7 @@ namespace Mono.CSharp {
                        if (e != null){
                                if (e is SimpleName){
                                        SimpleName s = (SimpleName) e;
-                                       
+
                                        Report.Error (
                                                103, s.Location,
                                                "The name `" + s.Name + "' could not be found in `" +
@@ -2971,7 +2971,15 @@ namespace Mono.CSharp {
                        //
                        // Stage 1: Performed by the parser (binding to locals or parameters).
                        //
+                       Block current_block = ec.CurrentBlock;
+                       if (current_block != null && current_block.IsVariableDefined (Name)){
+                               LocalVariableReference var;
+                               
+                               var = new LocalVariableReference (ec.CurrentBlock, Name, Location);
 
+                               return var.Resolve (ec);
+                       }
+                       
                        //
                        // Stage 2: Lookup members 
                        //
index 04d3fb2169a0c01e46f0fb2551a2fd17c936b26c..310d5626c30343c3193ec14cec2e4b46905c748c 100755 (executable)
@@ -1,5 +1,5 @@
 CSC=csc.exe
-CSCFLAGS=/nologo /debug+ /debug:full  /optimize /unsafe
+CSCFLAGS=/nologo /debug+ /debug:full  /optimize
 
 VERSION=0.13
 
@@ -46,10 +46,10 @@ dum: cs-parser.cs
        ./mcs --fatal --target exe -o mcs2.exe $(COMPILER_SOURCES)
 
 mcs2.exe: mcs.exe
-       ./mcs $(XFLAGS) --target exe --unsafe -o mcs2.exe $(COMPILER_SOURCES)
+       ./mcs $(XFLAGS) --target exe -o mcs2.exe $(COMPILER_SOURCES)
 
 mcs3.exe: mcs2.exe
-       ./mcs2 --target exe --unsafe -o mcs3.exe $(COMPILER_SOURCES)
+       ./mcs2 --target exe -o mcs3.exe $(COMPILER_SOURCES)
 
 mm:
        mint ./mcs.exe --target exe -o mcs4.exe $(COMPILER_SOURCES)
index 524b949172597f52fc34fce2a2a56d2e33094817..61389262e5e3ab65139d96ea3cb6160ac4f8cfd8 100644 (file)
@@ -111,6 +111,9 @@ namespace Mono.CSharp {
                                        l.Name,  row, code, text));
                                Warnings++;
                                Check (code);
+
+                               if (Stacktrace)
+                                       Console.WriteLine (new StackTrace ().ToString ());
                        }
                }
                
index 5bca63561cd7eb3cad1f027bdbd5ae6ed6d160f1..c2a39a0b55f6d77c5173011337334de240abc222 100755 (executable)
@@ -818,6 +818,7 @@ namespace Mono.CSharp {
 
                        variables.Add (name, vi);
 
+                       // Console.WriteLine ("Adding {0} to {1}", name, ID);
                        return vi;
                }
 
@@ -888,6 +889,7 @@ namespace Mono.CSharp {
                /// </summary>
                public bool IsVariableDefined (string name)
                {
+                       // Console.WriteLine ("Looking up {0} in {1}", name, ID);
                        if (variables != null) {
                                if (variables.Contains (name))
                                        return true;
index 1a45997a108abea47a2ef8e25f950b7d81e5fdec..f853b8b95ae18052ccd7eec27fd5cfbe3f38f0fa 100755 (executable)
@@ -12,7 +12,7 @@ TEST_SOURCES = \
        test-51 test-52 test-53 test-54 test-55 test-56 test-57         test-59         \
        test-61 test-62 test-63 test-64 test-65 test-66 test-67 test-68 test-69 test-70 \
        test-71 test-72 test-73 test-74 test-75         test-77 test-78 test-79 test-80 \
-       test-81 test-82 test-83
+       test-81 test-82 test-83 test-84
 
 UNSAFE_SOURCES = \
        unsafe-1 unsafe-2
index 11f52732edc891b3eaa70e2f6b68f83d63c98f4a..9f4897a82f4f3368b34e6cb030c00f2876ba3815 100755 (executable)
@@ -29,6 +29,17 @@ class Y {
 
                if (total != 6)
                        return 1;
+
+               total = 0;
+
+               //
+               // implicit block
+               //
+               foreach (object a in x)
+                       total += (int) a;
+               if (total != 6)
+                       return 2;
+               
                return 0;
        }
 }
diff --git a/mcs/tests/test-84.cs b/mcs/tests/test-84.cs
new file mode 100755 (executable)
index 0000000..e6b3d4e
--- /dev/null
@@ -0,0 +1,22 @@
+//
+// This test shows how a variable can be created with the 
+// same name as the class, and then the class referenced again
+// 
+// This was a bug exposed by Digger, as we incorrectly tried to
+// do some work ahead of time during the resolution process
+// (ie, we created LocalVariableReferences for the int variable `Ghost', 
+// which stopped `Ghost' from being useful as a type afterwards
+//
+
+class Ghost {
+
+       static int Main ()
+       {
+               int Ghost = 0;
+               
+               if (true){
+                       Ghost g = null;
+               }
+               return 0;
+       }
+}