[chuck-dev] Bug+Fix: Various combinations of virtual functions and base-class variable references fail.

Robin Davies rerdavies at rogers.com
Sun Sep 4 13:03:32 EDT 2005


Problem:
Various legal constructs in extended classes fail to compile, particularly references to base class members and methods. References to global variables in constructor code also fails.

See the test file given below.

Fix:
    chuck-emit.cpp line 3303
        delete 3303
        <        assert( v->owner_class == emit->env->class_def );
    chuck-type.cpp line 1758
        <                    if( !env->class_def || env->class_scope > 0 )
        >                    if( !env->class_def)

Discussion:

The assert is incorrect. The reference may be to a base-class member, (or perhaps a global variable. I'm not sure about that). It may be better to replace the assert with something like:
        assert(is_parent_type(emit->env->class_def,v->owner_class) || is_global_type(v->owner_class) )
(neither function currently avaialble).

The second fix is more difficult. Generally, we want the test to fail and go to the else clause which searches class scope for the variable if we're in a class definition. I don't understand the purpose of the test on class_scope, which is certainly incorrect, whatever it's supposed to do. What I do know: class_scope is zero in constructor code, and increments for each nested scope (function, code block &c) in the code at this point. If the intention is to prevent references to base class or global variables in constructure code, then it would be "env->class_scope == 0" (sense inverted); but this seems like an arbitrary restriction on a perfectly useful functionality, and removing the test altogether doesn't seem to cause problems in code generation.

References to global variables and variables in the current scope seem to be caught before this (which, thinking about it, suggests that global variable references will take precedence over base-class references, which is incorrect -- possibly another bug). The main issue seems to be base-class references. Deleting the || test seems to correct the scanning pass, and the generated code passes the test case given below.

With respect to global and base-class variables with the same name, I wrote a test for this case (see ScopeTest-11 tests below). The test succeeds, with the above patches applied. Both type checking and code generation seem to work. So I'm not going to hunt further.



Test case for the fix:

ScopeTest.ck

/////////////////////////////
// ScopeTest.ck
// Test Scoping of variables and virtual functions in extended classes.
//
/////////////////////////////


function void Assert(int condition, string message)
{
 if (!condition) 
 {
  <<< "Assert Failed: ", message >>>;
 }

}

1 => int globalVariable;
Assert(globalVariable == 1,"ScopeTest-1 Global Assignment");

string globalAndBaseclassVariable;

class Base
{
 int globalAndBaseclassVariable;

 2 => globalVariable;
 Assert(globalVariable == 2,"ScopeTest-2 Global Assignment from constructor.");

 3 => int v;
 Assert(v == 3,"ScopeTest-3 Assigment to class variable in ctor");
 
 function int GetV() { 
  return v; 
 }
 function int GetVVirtual() { 
  return v; 
 }
}

class Super extends Base
{
 4 => int v2;
 Assert(v2 == 4,"ScopeTest-4 Assigment to class scope from extended class.");
 5 => v;
 Assert(v == 5, "ScopeTest-5 Assignment to variable in superclass.");
 6 => v;
 Assert(GetV() == 6, "ScopeTest-6 Assignment to variable in superclass.");

 7 => globalVariable;
 Assert(globalVariable == 7, "ScopeTest-7 assignement to global variable in extended class");

 function int Test() 
 {
  return GetV();
 }

 function int GetVVirtual() { 
  return v2;
 }
 function int GetglobalAndBaseclassVariable()
 {
  return globalAndBaseclassVariable;
 }
}


Base b;
Assert(globalVariable == 2, "ScopeTest-2.1 constructor side-effects in global scope.");


Super s;
Assert(globalVariable == 7, "ScopeTest-7.1 superclass constructor side-effects in global scope.");


8 => b.v;
Assert(b.v == b.GetV(),"ScopeTest-8 assigment to class-scope variable.");
9 => s.v;
Assert(s.v == s.GetV(),"ScopeTest-9 assigment to base-class-scope variable.");
10 => s.v2;
Assert(s.v == s.GetV(),"ScopeTest-10 assigment to super-class-scope variable.");
Assert(s.v2 == 10,"ScopeTest-10.1 assigment to super-class-scope variable.");
Assert(s.v2 == s.GetVVirtual(),"ScopeTest-10.1 virtual function resolution.");


"110" => globalAndBaseclassVariable;
111 => s.globalAndBaseclassVariable;
Assert(globalAndBaseclassVariable == "110","ScopeTest-11.1 aliased global and base-class variable.");
Assert(s.GetglobalAndBaseclassVariable() == 111,"ScopeTest-11.2 aliased global and base-class variable.");
Assert(s.globalAndBaseclassVariable() == 111,"ScopeTest-11.3 aliased global and base-class variable.");


-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.cs.princeton.edu/pipermail/chuck-dev/attachments/20050904/873f3bba/attachment.htm


More information about the chuck-dev mailing list