Bläddra i källkod

Make locals volatile when modified in Try block. Fixes #312.

woollybah 7 år sedan
förälder
incheckning
1e8a6ddcb3
5 ändrade filer med 88 tillägg och 18 borttagningar
  1. 17 8
      ctranslator.bmx
  2. 33 5
      decl.bmx
  3. 19 1
      expr.bmx
  4. 14 4
      parser.bmx
  5. 5 0
      stmt.bmx

+ 17 - 8
ctranslator.bmx

@@ -705,6 +705,11 @@ t:+"NULLNULLNULL"
 				initTrans = "=" + cast + init.Trans()
 			End If
 		End If
+		
+		Local volTrans:String = " "
+		If decl.volatile Then
+			volTrans = " volatile "
+		End If
 	
 		If Not declare And opt_debug Then
 			Local ty:TType = decl.ty
@@ -738,21 +743,21 @@ t:+"NULLNULLNULL"
 						If TObjectType(ty).classdecl.IsInterface() Then
 							Return TransType( ty, decl.munged )+" "+decl.munged + initTrans
 						Else
-							Return TransType( ty, decl.munged )+" "+decl.munged + initTrans
+							Return TransType( ty, decl.munged )+ volTrans +decl.munged + initTrans
 						End If
 					Else
 						If TObjectType(ty).classdecl.IsStruct() Then
 							Return TransType( ty, decl.munged )+" "+decl.munged + initTrans
 						Else
-							If decl.volatile Then
-								Return TransType( ty, decl.munged )+" volatile "+decl.munged + initTrans
-							Else
-								Return TransType( ty, decl.munged )+" "+decl.munged + initTrans
-							End If
+							'If decl.volatile Then
+								Return TransType( ty, decl.munged )+ volTrans +decl.munged + initTrans
+							'Else
+							'	Return TransType( ty, decl.munged )+" "+decl.munged + initTrans
+							'End If
 						End If
 					End If
 				Else
-					Return TransType( ty, decl.munged )+" "+decl.munged + initTrans
+					Return TransType( ty, decl.munged )+ volTrans +decl.munged + initTrans
 				End If
 			End If
 		End If
@@ -783,7 +788,11 @@ t:+"NULLNULLNULL"
 					End If
 				End If
 			Else
-				Return TransType( decl.ty, decl.munged )+" "+decl.munged + "=" + TransValue(decl.ty, "")
+				If TLocalDecl(decl) And TLocalDecl(decl).volatile Then
+					Return TransType( decl.ty, decl.munged )+" volatile "+decl.munged + "=" + TransValue(decl.ty, "")
+				Else
+					Return TransType( decl.ty, decl.munged )+" "+decl.munged + "=" + TransValue(decl.ty, "")
+				End If
 			End If
 		End If
 	End Method

+ 33 - 5
decl.bmx

@@ -588,9 +588,10 @@ End Type
 Type TLocalDecl Extends TVarDecl
 
 	Field done:Int
-	Field volatile:Int = True
+	Field volatile:Int = False
+	Field declaredInTry:Int
 
-	Method Create:TLocalDecl( ident$,ty:TType,init:TExpr,attrs:Int=0, generated:Int = False, volatile:Int = True )
+	Method Create:TLocalDecl( ident$,ty:TType,init:TExpr,attrs:Int=0, generated:Int = False, volatile:Int = False )
 		Self.ident=ident
 		Self.declTy=ty
 		Self.declInit=init
@@ -605,13 +606,23 @@ Type TLocalDecl Extends TVarDecl
 		decl.scope = scope
 		decl.ty = ty
 		decl.init = init
+		decl.declaredInTry = declaredInTry
 		Return decl
 	End Method
 
 	Method GetDeclPrefix:String()
 		Return "Local "
 	End Method
-	
+
+	Method OnSemant()
+		If declTy Then
+			If TObjectType(declTy) Or TArrayType(declTy) Then
+				volatile = True
+			End If
+		End If
+		Super.OnSemant()
+	End Method
+		
 	Method ToString$()
 		Return GetDeclPrefix() + Super.ToString()
 	End Method
@@ -1598,7 +1609,20 @@ End Rem
 		
 		If scope Return scope.FindLoop( ident )
 	End Method
-	
+
+	Method FindTry:TTryStmtDecl()
+
+		If TTryStmtDecl(Self) Then
+			Return TTryStmtDecl(Self)
+		End If
+
+		If TFuncDecl(scope) Or TModuleDecl(scope)
+			Return Null
+		End If
+		
+		If scope Return scope.FindTry()
+	End Method
+
 	Method OnSemant()
 	End Method
 	
@@ -1912,7 +1936,7 @@ Type TFuncDecl Extends TBlockDecl
 		If TArrayType( retType ) And Not retType.EqualsType( retType.ActualType() )
 '			Err "Return type cannot be an array of generic objects."
 		EndIf
-		
+
 		'semant args
 		For Local arg:TArgDecl=EachIn argDecls
 			InsertDecl arg
@@ -3209,6 +3233,10 @@ Type TDefDataDecl Extends TDecl
 	
 End Type
 
+Type TTryStmtDecl Extends TBlockDecl
+	Field tryStmt:TTryStmt
+End Type
+
 Const MODULE_STRICT:Int=1
 Const MODULE_SUPERSTRICT:Int=2
 Const MODULE_ACTUALMOD:Int=4

+ 19 - 1
expr.bmx

@@ -163,6 +163,16 @@ Type TExpr
 						stmt.exprType = TNewObjectExpr(args[i]).ty
 						args[i] = stmt
 					End If
+
+					' passing a non volatile local as Var from within a Try block?					
+					If TVarExpr(args[i]) Then
+						Local ldecl:TLocalDecl = TLocalDecl(TVarExpr(args[i]).decl)
+						If ldecl Then
+							If Not ldecl.volatile And Not ldecl.declaredInTry And _env.FindTry() Then
+								ldecl.volatile = True
+							End If
+						End If
+					End If
 				End If
 				
 				If (funcDecl.argDecls[i].ty._flags & TType.T_VAR) And Not (funcDecl.argDecls[i].ty.EqualsType(args[i].exprType)) Then
@@ -2552,8 +2562,16 @@ Type TIdentExpr Extends TExpr
 		End If
 		
 		If vdecl
+		
+			If op And TLocalDecl( vdecl )
+
+				Local ldecl:TLocalDecl = TLocalDecl( vdecl )
+
+				If Not ldecl.volatile And Not ldecl.declaredInTry And scope.FindTry() Then
+					ldecl.volatile = True
+				End If
 
-			If TConstDecl( vdecl )
+			Else If TConstDecl( vdecl )
 '				If rhs Err "Constant '"+ident+"' cannot be modified."
 '				Return New TConstExpr.Create( vdecl.ty,TConstDecl( vdecl ).value ).Semant()
 				If rhs Err "Constant '"+ident+"' cannot be modified."

+ 14 - 4
parser.bmx

@@ -2033,7 +2033,11 @@ End Rem
 	Method ParseTryStmt()
 		Parse "try"
 
-		Local block:TBlockDecl=New TBlockDecl.Create( _block )
+		Local tryStmtDecl:TTryStmtDecl = TTryStmtDecl(New TTryStmtDecl.Create( _block ))
+		
+		PushBlock tryStmtDecl
+
+		Local block:TBlockDecl=New TBlockDecl.Create( tryStmtDecl )
 		Local catches:TList=New TList
 
 		PushBlock block
@@ -2071,7 +2075,7 @@ End Rem
 			End If
 		Wend
 
-		PopBlock
+		PopBlock ' try block
 		
 		If Not CParse("endtry") Then
 			' TODO : handle case of no catch - perhaps throw the exception again.
@@ -2080,7 +2084,14 @@ End Rem
 			CParse "try"
 		End If
 
-		_block.AddStmt New TTryStmt.Create( block,TCatchStmt[](catches.ToArray()) )
+		PopBlock ' tryStmtDecl
+		
+		Local tryStmt:TTryStmt = New TTryStmt.Create( block,TCatchStmt[](catches.ToArray()) )
+
+		tryStmtDecl.tryStmt = tryStmt
+
+		_block.AddStmt tryStmt
+		
 	End Method
 
 	Method ParseThrowStmt()
@@ -2730,7 +2741,6 @@ End Rem
 			attrs :| (fdecl.attrs & DECL_API_FLAGS)
 		End If
 		
-		
 		If CParse( "nodebug" ) Then
 			attrs :| DECL_NODEBUG
 		End If

+ 5 - 0
stmt.bmx

@@ -77,6 +77,10 @@ Type TDeclStmt Extends TStmt
 	End Method
 	
 	Method OnSemant()
+		If TLocalDecl(decl) And _env.FindTry() Then
+			TLocalDecl(decl).declaredInTry = True
+		End If
+		
 		decl.Semant
 		' if scope is already set, don't try to add it to the current scope.
 		If Not decl.scope Then
@@ -116,6 +120,7 @@ Type TAssignStmt Extends TStmt
 			TIdentExpr(rhs).isRhs = True
 		End If
 		rhs=rhs.Semant()
+
 		lhs=lhs.SemantSet( op,rhs )
 		If TInvokeExpr( lhs ) Or TInvokeMemberExpr( lhs )
 			rhs=Null