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)
 | 
												left_type = left_type.set_nr_muls(1)
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
					} else if left_type.has_flag(.shared_f) {
 | 
										} 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 {
 | 
										if ident_var_info.share == .atomic_t {
 | 
				
			||||||
						left_type = left_type.set_flag(.atomic_f)
 | 
											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()
 | 
							array_info := type_sym.array_info()
 | 
				
			||||||
		node.elem_type = array_info.elem_type
 | 
							node.elem_type = array_info.elem_type
 | 
				
			||||||
		// clear optional flag incase of: `fn opt_arr ?[]int { return [] }`
 | 
							// 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]
 | 
						// [1,2,3]
 | 
				
			||||||
	if node.exprs.len > 0 && node.elem_type == ast.void_type {
 | 
						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.write('*')
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
						g.expr(left)
 | 
											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 !cloned {
 | 
				
			||||||
				if is_fixed_array_var {
 | 
									if is_fixed_array_var {
 | 
				
			||||||
					// TODO Instead of the translated check, check if it's a pointer already
 | 
										// 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.expr(val)
 | 
				
			||||||
					g.write(', sizeof($typ_str))')
 | 
										g.write(', sizeof($typ_str))')
 | 
				
			||||||
				} else if is_decl {
 | 
									} else if is_decl {
 | 
				
			||||||
 | 
										g.is_shared = var_type.has_flag(.shared_f)
 | 
				
			||||||
					if is_fixed_array_init && !has_val {
 | 
										if is_fixed_array_init && !has_val {
 | 
				
			||||||
						if val is ast.ArrayInit {
 | 
											if val is ast.ArrayInit {
 | 
				
			||||||
							g.array_init(val, ident.name)
 | 
												g.array_init(val, ident.name)
 | 
				
			||||||
| 
						 | 
					@ -476,11 +479,11 @@ fn (mut g Gen) gen_assign_stmt(node_ ast.AssignStmt) {
 | 
				
			||||||
						if op_overloaded {
 | 
											if op_overloaded {
 | 
				
			||||||
							g.op_arg(val, op_expected_right, val_type)
 | 
												g.op_arg(val, op_expected_right, val_type)
 | 
				
			||||||
						} else {
 | 
											} 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()
 | 
													var_type.deref()
 | 
				
			||||||
							} else {
 | 
												} else {
 | 
				
			||||||
								var_type
 | 
													var_type
 | 
				
			||||||
							}
 | 
												}.clear_flag(.shared_f) // don't reset the mutex, just change the value
 | 
				
			||||||
							g.expr_with_cast(val, val_type, exp_type)
 | 
												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