@@ -4,15 +4,15 @@ use super::ast::*;
44use super :: contracts:: is_base;
55use super :: diagnostics:: Diagnostics ;
66use super :: expression:: {
7- function_call:: { available_functions, call_expr, named_call_expr } ,
7+ function_call:: { available_functions, call_expr} ,
88 ExprContext , ResolveTo ,
99} ;
1010use super :: symtable:: Symtable ;
1111use crate :: sema:: expression:: constructor:: {
1212 constructor_named_args, match_constructor_to_args, new,
1313} ;
1414use crate :: sema:: expression:: function_call:: {
15- function_call_expr, function_call_pos_args, named_function_call_expr ,
15+ function_call_expr, function_call_pos_args, named_call_expr ,
1616} ;
1717use crate :: sema:: expression:: resolve_expression:: expression;
1818use crate :: sema:: function_annotation:: function_body_annotations;
@@ -29,6 +29,8 @@ use solang_parser::pt::CodeLocation;
2929use solang_parser:: pt:: OptionalCodeLocation ;
3030use std:: collections:: { BTreeMap , HashMap , HashSet } ;
3131use std:: sync:: Arc ;
32+ use num_bigint:: BigInt ;
33+ use num_traits:: Zero ;
3234
3335pub fn resolve_function_body (
3436 def : & pt:: FunctionDefinition ,
@@ -713,7 +715,8 @@ fn statement(
713715 let expr =
714716 expression ( expr, context, ns, symtable, diagnostics, ResolveTo :: Unknown ) ?;
715717 used_variable ( ns, & expr, symtable) ;
716- return if let Type :: StorageRef ( _, ty) = expr. ty ( ) {
718+
719+ if let Type :: StorageRef ( _, ty) = expr. ty ( ) {
717720 if expr. ty ( ) . is_mapping ( ) {
718721 ns. diagnostics . push ( Diagnostic :: error (
719722 * loc,
@@ -724,15 +727,33 @@ fn statement(
724727
725728 res. push ( Statement :: Delete ( * loc, ty. as_ref ( ) . clone ( ) , expr) ) ;
726729
727- Ok ( true )
730+ return Ok ( true ) ;
728731 } else {
732+ // For memory arrays and other types, we should only delete the element
733+ // by assigning the default value, not delete the entire array
734+ // Issue #1785 - match Solc behavior for delete array[index]
729735 ns. diagnostics . push ( Diagnostic :: warning (
730736 * loc,
731737 "argument to 'delete' should be storage reference" . to_string ( ) ,
732738 ) ) ;
733739
734- Err ( ( ) )
735- } ;
740+ let expr_ty = expr. ty ( ) . clone ( ) ;
741+ let element_ty = expr_ty. deref_any ( ) ;
742+
743+ if let Ok ( default_expr) = get_default_value ( * loc, element_ty, ns, diagnostics) {
744+ let assign = Expression :: Assign {
745+ loc : * loc,
746+ ty : expr. ty ( ) ,
747+ left : Box :: new ( expr) ,
748+ right : Box :: new ( default_expr) ,
749+ } ;
750+
751+ res. push ( Statement :: Expression ( * loc, true , assign) ) ;
752+ return Ok ( true ) ;
753+ }
754+
755+ return Err ( ( ) ) ;
756+ }
736757 }
737758 // is it an underscore modifier statement
738759 pt:: Expression :: Variable ( id)
@@ -1796,10 +1817,11 @@ fn destructure_values(
17961817 res
17971818 }
17981819 pt:: Expression :: NamedFunctionCall ( loc, ty, args) => {
1799- let res = named_function_call_expr (
1820+ let res = named_call_expr (
18001821 loc,
18011822 ty,
18021823 args,
1824+ true ,
18031825 context,
18041826 ns,
18051827 symtable,
@@ -2310,10 +2332,11 @@ fn try_catch(
23102332 res
23112333 }
23122334 pt:: Expression :: NamedFunctionCall ( loc, ty, args) => {
2313- let res = named_function_call_expr (
2335+ let res = named_call_expr (
23142336 loc,
23152337 ty,
23162338 args,
2339+ true ,
23172340 context,
23182341 ns,
23192342 symtable,
@@ -2752,3 +2775,64 @@ fn try_catch(
27522775
27532776 Ok ( ( stmt, finally_reachable) )
27542777}
2778+
2779+ /// Helper function to get the default value expression for a type
2780+ fn get_default_value (
2781+ loc : pt:: Loc ,
2782+ ty : & Type ,
2783+ ns : & Namespace ,
2784+ diagnostics : & mut Diagnostics ,
2785+ ) -> Result < Expression , ( ) > {
2786+ match ty {
2787+ Type :: Bool => Ok ( Expression :: BoolLiteral {
2788+ loc,
2789+ value : false ,
2790+ } ) ,
2791+ Type :: Uint ( size) => Ok ( Expression :: NumberLiteral {
2792+ loc,
2793+ ty : Type :: Uint ( * size) ,
2794+ value : BigInt :: zero ( ) ,
2795+ } ) ,
2796+ Type :: Int ( size) => Ok ( Expression :: NumberLiteral {
2797+ loc,
2798+ ty : Type :: Int ( * size) ,
2799+ value : BigInt :: zero ( ) ,
2800+ } ) ,
2801+ Type :: Value => Ok ( Expression :: NumberLiteral {
2802+ loc,
2803+ ty : Type :: Value ,
2804+ value : BigInt :: zero ( ) ,
2805+ } ) ,
2806+ Type :: Address ( _) => Ok ( Expression :: NumberLiteral {
2807+ loc,
2808+ ty : ty. clone ( ) ,
2809+ value : BigInt :: zero ( ) ,
2810+ } ) ,
2811+ Type :: Bytes ( n) => Ok ( Expression :: BytesLiteral {
2812+ loc,
2813+ ty : Type :: Bytes ( * n) ,
2814+ value : vec ! [ 0 ; * n as usize ] ,
2815+ } ) ,
2816+ Type :: String => Ok ( Expression :: BytesLiteral {
2817+ loc,
2818+ ty : Type :: String ,
2819+ value : Vec :: new ( ) ,
2820+ } ) ,
2821+ Type :: DynamicBytes => Ok ( Expression :: BytesLiteral {
2822+ loc,
2823+ ty : Type :: DynamicBytes ,
2824+ value : Vec :: new ( ) ,
2825+ } ) ,
2826+ Type :: Ref ( r) => get_default_value ( loc, r, ns, diagnostics) ,
2827+ Type :: StorageRef ( _, r) => get_default_value ( loc, r, ns, diagnostics) ,
2828+ // For arrays, structs, and complex types, a more involved default value would be needed
2829+ // but for now we'll return a basic default value for simple types
2830+ _ => {
2831+ diagnostics. push ( Diagnostic :: error (
2832+ loc,
2833+ format ! ( "cannot create default value for type {}" , ty. to_string( ns) ) ,
2834+ ) ) ;
2835+ Err ( ( ) )
2836+ }
2837+ }
2838+ }
0 commit comments