| Summary: | [compiler] Copy inheritance problem | ||||||||
|---|---|---|---|---|---|---|---|---|---|
| Product: | [Tools] Objectteams | Reporter: | Andreas Mertgen <programmfehler> | ||||||
| Component: | OTJ | Assignee: | Stephan Herrmann <stephan.herrmann> | ||||||
| Status: | ASSIGNED --- | QA Contact: | |||||||
| Severity: | normal | ||||||||
| Priority: | P3 | CC: | stephan.herrmann | ||||||
| Version: | 0.7 | ||||||||
| Target Milestone: | --- | ||||||||
| Hardware: | PC | ||||||||
| OS: | Windows 7 | ||||||||
| Whiteboard: | |||||||||
| Attachments: |
|
||||||||
Thanks for the report, I can indeed reproduce
(see test0c15_overrideBoundSuperRole1)
The core of the problem is a default lifting constructor (RSub(BSub)) in T$RSub
which invokes the default super constructor (R()) from T$R.
Role TSub$RSub inherits this lifting constructor, but the super call within
is now illegal, because the bound role TSub$R cannot be initialized with an
argumentless default constructor.
This problem is detected while copying the constructor RSub(BSub) from T$RSub
to TSub$RSub.
I see two options for solving this issue:
(1) instead of marking the role RSub as invalid, the compiler could
transitively ensure that the copied constructor is never called.
(2) if the calling constructor takes care of initializing the base link,
the super constructor which cannot be invoked directly could actually
be accepted.
Let's document this issue a little more generally:
(1) If an unbound role from T0 is overridden with a bound role in T1, any
constructor of the tsuper role will be illegal in the context of T1,
because it fails to establish the role-base link.
One obvious consequence *could* be to disallow such overriding from
unbound to bound, however, this is exactly the situation in the
connector pattern, which we definitely want to support.
(2) If we have to cope with such illegal (copy-)inherited constructors
we must implement analysis to prevent this code from creating invalid
structures (bound role instance without an associated base instance)
at runtime.
(a) We already throw IllegalRoleCreationException from copied constructors
for which we detect the above situation. This is always the last resort
if things cannot be analyzed statically.
Looking at different call-patterns two basic situations should be considered:
(b) If a bad constructor is invoked by a super or tsuper call we are
basically able to detect this within the scope of T1, because due to
copy-inheritance all relevant code is available.
More specifically, we can detect that a call to the bad ctor is actually
NOT bad, because the calling ctor already establishes the role-base link.
(c) If a bad constructor is invoked from a team-level method it is only
dynamic binding that will chose the role and thus the specific ctor
to be used. The best we can do here is to mark the ctor in T0 to be
used and generally require it to be overridden in T1.
If analysis can show the absence of problems according to (b) and (c) the
exception from (a) should actually NOT be thrown.
(3) Given an illegal call chain has been found statically, the error message
should mention two ways of correcting the issue:
(a) overriding the invalid constructor (within T1)
(b) avoiding call it (depending on the call-chain)
Concrete examples will be given as test cases in section ImplicitInheritance,
and should be linked to the above items.
Created attachment 173197 [details] snapshot of experiments This patch is a snapshot of some experiments that I made regarding test0c15_overrideBoundSuperRole1 ff. This requires more work post the 0.7.0 release. Here's another pointer: most of the currently handling of illegal copied ctors was introduced in http://trac.objectteams.org/ot/changeset/15746 Not a priority for 2.3 ... |
Created attachment 173068 [details] Eclipse project Here is a simple program to produce a java.lang.VerifyError (eclipse project attached). Suppose 2 base classes: B and BSub extends B and the following 2 teams: public team class T { protected abstract class R { void foo() {System.out.println("foo");} } protected class RSub extends R playedBy BSub { foo <- after m; } } public team class TSub extends T { protected class R playedBy B { } } At the time of role lifting in TSub I get an java.lang.VerifyError. If I clean the project, I see an error "Illegally copied default constructor, role TSub.RSub is a bound role." in the problems view. After saving (without changes) the error message disappears. First time I executed the program I got an IllegalRoleCreationException.