Commit 30804441 authored by Miklos Magyari's avatar Miklos Magyari
Browse files

OOP: semantic check - return statement cannot be used in destructor (issue #427)


Signed-off-by: Miklos Magyari's avatarMiklos Magyari <miklos.magyari@sigmatechnology.se>
parent acbc9aad
...@@ -183,6 +183,13 @@ type class @trait FinallyClass2 { ...@@ -183,6 +183,13 @@ type class @trait FinallyClass2 {
log(this.m_const); log(this.m_const);
} }
// finally blocks canot have a return clause
type class FinallyClass3 {
public function f_pub() { }
} finally {
return;
}
// bad combination of class modifiers // bad combination of class modifiers
type class @final @abstract BadClass1 { } type class @final @abstract BadClass1 { }
type class @final @trait BadClass3 { } type class @final @trait BadClass3 { }
......
...@@ -45,6 +45,7 @@ public final class Return_Statement extends Statement { ...@@ -45,6 +45,7 @@ public final class Return_Statement extends Statement {
private static final String UNEXPETEDRETURNSTATEMENT = "Return statement cannot be used in a {0}. It is allowed only in functions and altsteps"; private static final String UNEXPETEDRETURNSTATEMENT = "Return statement cannot be used in a {0}. It is allowed only in functions and altsteps";
private static final String ALTSTEPRETURNINGVALUE = "An altstep cannot return a value"; private static final String ALTSTEPRETURNINGVALUE = "An altstep cannot return a value";
private static final String USAGEINCONTROLPART = "Return statement cannot be used in the control part. It is alowed only in functions and altsteps"; private static final String USAGEINCONTROLPART = "Return statement cannot be used in the control part. It is alowed only in functions and altsteps";
private static final String RETURNINDESTRUCTOR = "Return statement cannot be used in a class destructor";
private static final String FULLNAMEPART = ".returnexpression"; private static final String FULLNAMEPART = ".returnexpression";
private static final String STATEMENT_NAME = "return"; private static final String STATEMENT_NAME = "return";
...@@ -117,6 +118,10 @@ public final class Return_Statement extends Statement { ...@@ -117,6 +118,10 @@ public final class Return_Statement extends Statement {
genRestrictionCheck = false; genRestrictionCheck = false;
final Definition definition = myStatementBlock.getMyDefinition(); final Definition definition = myStatementBlock.getMyDefinition();
if (myStatementBlock.hasDestructor()) {
location.reportSemanticError(RETURNINDESTRUCTOR);
return;
}
if (definition == null) { if (definition == null) {
location.reportSemanticError(USAGEINCONTROLPART); location.reportSemanticError(USAGEINCONTROLPART);
return; return;
......
...@@ -113,6 +113,9 @@ public final class StatementBlock extends TTCN3Scope implements ILocateableNode, ...@@ -113,6 +113,9 @@ public final class StatementBlock extends TTCN3Scope implements ILocateableNode,
/** Indicates if it is a statement block of a loop. */ /** Indicates if it is a statement block of a loop. */
private boolean ownerIsLoop; private boolean ownerIsLoop;
/** Indicates it is a statement block of a class destructor */
private boolean ownerIsDestructor;
/** /**
* Indicates if it is a statement block of an AltGuard (in alt, * Indicates if it is a statement block of an AltGuard (in alt,
...@@ -140,6 +143,7 @@ public final class StatementBlock extends TTCN3Scope implements ILocateableNode, ...@@ -140,6 +143,7 @@ public final class StatementBlock extends TTCN3Scope implements ILocateableNode,
statements = new ArrayList<Statement>(); statements = new ArrayList<Statement>();
ownerIsLoop = false; ownerIsLoop = false;
ownerIsAltguard = false; ownerIsAltguard = false;
ownerIsDestructor = false;
} }
@Override @Override
...@@ -228,6 +232,13 @@ public final class StatementBlock extends TTCN3Scope implements ILocateableNode, ...@@ -228,6 +232,13 @@ public final class StatementBlock extends TTCN3Scope implements ILocateableNode,
public void setOwnerIsAltguard() { public void setOwnerIsAltguard() {
ownerIsAltguard = true; ownerIsAltguard = true;
} }
/**
* Sets indication that it is a statement block of a class destructor.
**/
public void setOwnerIsDestructor() {
ownerIsDestructor = true;
}
/** /**
* Adds a statement to the list of statements stored in this statement * Adds a statement to the list of statements stored in this statement
...@@ -708,6 +719,13 @@ public final class StatementBlock extends TTCN3Scope implements ILocateableNode, ...@@ -708,6 +719,13 @@ public final class StatementBlock extends TTCN3Scope implements ILocateableNode,
public boolean hasEnclosingLoopOrAltguard() { public boolean hasEnclosingLoopOrAltguard() {
return ownerIsLoop || ownerIsAltguard || (myStatementBlock != null && myStatementBlock.hasEnclosingLoopOrAltguard()); return ownerIsLoop || ownerIsAltguard || (myStatementBlock != null && myStatementBlock.hasEnclosingLoopOrAltguard());
} }
/**
* @return indication if the statement block is enclosed in a class destructor
*/
public boolean hasDestructor() {
return ownerIsDestructor || (myStatementBlock != null && myStatementBlock.hasDestructor());
}
@Override @Override
/** {@inheritDoc} */ /** {@inheritDoc} */
......
...@@ -75,6 +75,7 @@ public final class Class_Type extends Type implements ITypeWithComponents { ...@@ -75,6 +75,7 @@ public final class Class_Type extends Type implements ITypeWithComponents {
} }
if (finallyBlock != null) { if (finallyBlock != null) {
finallyBlock.setFullNameParent(this); finallyBlock.setFullNameParent(this);
finallyBlock.setOwnerIsDestructor();
} }
} }
...@@ -187,6 +188,10 @@ public final class Class_Type extends Type implements ITypeWithComponents { ...@@ -187,6 +188,10 @@ public final class Class_Type extends Type implements ITypeWithComponents {
if (classBody != null) { if (classBody != null) {
classBody.check(timestamp); classBody.check(timestamp);
} }
if (finallyBlock != null) {
finallyBlock.check(timestamp);
}
lastTimeChecked = timestamp; lastTimeChecked = timestamp;
} }
......
...@@ -117,7 +117,7 @@ public class OOP_Semantic_tests { ...@@ -117,7 +117,7 @@ public class OOP_Semantic_tests {
private ArrayList<MarkerToCheck> oopNegative_ttcn_initializer() { private ArrayList<MarkerToCheck> oopNegative_ttcn_initializer() {
//oopNegativeSemanticTest.ttcn //oopNegativeSemanticTest.ttcn
ArrayList<MarkerToCheck> markersToCheck = new ArrayList<MarkerToCheck>(71); ArrayList<MarkerToCheck> markersToCheck = new ArrayList<MarkerToCheck>(72);
int lineNum = 28; int lineNum = 28;
markersToCheck.add(new MarkerToCheck("class type expected", lineNum, IMarker.SEVERITY_ERROR)); markersToCheck.add(new MarkerToCheck("class type expected", lineNum, IMarker.SEVERITY_ERROR));
lineNum += 10; lineNum += 10;
...@@ -187,7 +187,9 @@ public class OOP_Semantic_tests { ...@@ -187,7 +187,9 @@ public class OOP_Semantic_tests {
lineNum += 7; lineNum += 7;
markersToCheck.add(new MarkerToCheck("Trait classes can only declare abstract methods", lineNum, IMarker.SEVERITY_ERROR)); markersToCheck.add(new MarkerToCheck("Trait classes can only declare abstract methods", lineNum, IMarker.SEVERITY_ERROR));
markersToCheck.add(new MarkerToCheck("A trait class should not define a finally block", ++lineNum, IMarker.SEVERITY_ERROR)); markersToCheck.add(new MarkerToCheck("A trait class should not define a finally block", ++lineNum, IMarker.SEVERITY_ERROR));
lineNum += 5; lineNum += 8;
markersToCheck.add(new MarkerToCheck("Return statement cannot be used in a class destructor", lineNum, IMarker.SEVERITY_ERROR));
lineNum += 4;
markersToCheck.add(new MarkerToCheck("An absract class cannot be final", lineNum, IMarker.SEVERITY_ERROR)); markersToCheck.add(new MarkerToCheck("An absract class cannot be final", lineNum, IMarker.SEVERITY_ERROR));
markersToCheck.add(new MarkerToCheck("A trait class cannot be final", ++lineNum, IMarker.SEVERITY_ERROR)); markersToCheck.add(new MarkerToCheck("A trait class cannot be final", ++lineNum, IMarker.SEVERITY_ERROR));
markersToCheck.add(new MarkerToCheck("A class cannot be both abstract and trait", ++lineNum, IMarker.SEVERITY_ERROR)); markersToCheck.add(new MarkerToCheck("A class cannot be both abstract and trait", ++lineNum, IMarker.SEVERITY_ERROR));
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment