checker, cgen: fix shared non-decl assignment (#14466)
							parent
							
								
									d5beaa0798
								
							
						
					
					
						commit
						2835a190e8
					
				|  | @ -224,7 +224,7 @@ pub fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) { | |||
| 							left_type = left_type.set_nr_muls(1) | ||||
| 						} | ||||
| 					} else if left_type.has_flag(.shared_f) { | ||||
| 						left_type = left_type.clear_flag(.shared_f) | ||||
| 						left_type = left_type.clear_flag(.shared_f).deref() | ||||
| 					} | ||||
| 					if ident_var_info.share == .atomic_t { | ||||
| 						left_type = left_type.set_flag(.atomic_f) | ||||
|  |  | |||
|  | @ -81,7 +81,11 @@ pub fn (mut c Checker) array_init(mut node ast.ArrayInit) ast.Type { | |||
| 		array_info := type_sym.array_info() | ||||
| 		node.elem_type = array_info.elem_type | ||||
| 		// clear optional flag incase of: `fn opt_arr ?[]int { return [] }`
 | ||||
| 		return c.expected_type.clear_flag(.optional) | ||||
| 		return if c.expected_type.has_flag(.shared_f) { | ||||
| 			c.expected_type.clear_flag(.shared_f).deref() | ||||
| 		} else { | ||||
| 			c.expected_type | ||||
| 		}.clear_flag(.optional) | ||||
| 	} | ||||
| 	// [1,2,3]
 | ||||
| 	if node.exprs.len > 0 && node.elem_type == ast.void_type { | ||||
|  |  | |||
|  | @ -389,6 +389,9 @@ fn (mut g Gen) gen_assign_stmt(node_ ast.AssignStmt) { | |||
| 							g.write('*') | ||||
| 						} | ||||
| 						g.expr(left) | ||||
| 						if !is_decl && var_type.has_flag(.shared_f) { | ||||
| 							g.write('->val') // don't reset the mutex, just change the value
 | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
|  | @ -432,7 +435,6 @@ fn (mut g Gen) gen_assign_stmt(node_ ast.AssignStmt) { | |||
| 				} | ||||
| 				*/ | ||||
| 			} | ||||
| 			g.is_shared = var_type.has_flag(.shared_f) | ||||
| 			if !cloned { | ||||
| 				if is_fixed_array_var { | ||||
| 					// TODO Instead of the translated check, check if it's a pointer already
 | ||||
|  | @ -445,6 +447,7 @@ fn (mut g Gen) gen_assign_stmt(node_ ast.AssignStmt) { | |||
| 					g.expr(val) | ||||
| 					g.write(', sizeof($typ_str))') | ||||
| 				} else if is_decl { | ||||
| 					g.is_shared = var_type.has_flag(.shared_f) | ||||
| 					if is_fixed_array_init && !has_val { | ||||
| 						if val is ast.ArrayInit { | ||||
| 							g.array_init(val, ident.name) | ||||
|  | @ -476,11 +479,11 @@ fn (mut g Gen) gen_assign_stmt(node_ ast.AssignStmt) { | |||
| 						if op_overloaded { | ||||
| 							g.op_arg(val, op_expected_right, val_type) | ||||
| 						} else { | ||||
| 							exp_type := if left.is_auto_deref_var() { | ||||
| 							exp_type := if left.is_auto_deref_var() || var_type.has_flag(.shared_f) { | ||||
| 								var_type.deref() | ||||
| 							} else { | ||||
| 								var_type | ||||
| 							} | ||||
| 							}.clear_flag(.shared_f) // don't reset the mutex, just change the value
 | ||||
| 							g.expr_with_cast(val, val_type, exp_type) | ||||
| 						} | ||||
| 					} | ||||
|  |  | |||
|  | @ -0,0 +1,13 @@ | |||
| struct AA { | ||||
| 	a shared []int | ||||
| } | ||||
| 
 | ||||
| fn test_assign_shared() { | ||||
| 	a := AA{[1]} | ||||
| 	lock a.a { | ||||
| 		a.a = []int{cap: 10} | ||||
| 	} | ||||
| 	lock a.a { | ||||
| 		assert a.a == [] | ||||
| 	} | ||||
| } | ||||
		Loading…
	
		Reference in New Issue