@@ -130,7 +130,7 @@ var_t *opstack_pop(void)
130130
131131void read_expr (block_t * parent , basic_block_t * * bb );
132132
133- int write_symbol (char * data )
133+ int write_symbol (const char * data )
134134{
135135 int start_len = elf_data -> size ;
136136 elf_write_str (elf_data , data );
@@ -1325,8 +1325,15 @@ void read_parameter_list_decl(func_t *func, bool anon)
13251325 lex_accept (T_comma );
13261326 }
13271327
1328- while (lex_peek (T_identifier , NULL ) == 1 ) {
1329- read_full_var_decl (& func -> param_defs [vn ++ ], anon , true);
1328+ while (lex_peek (T_identifier , NULL ) == 1 || lex_peek (T_const , NULL )) {
1329+ /* Check for const qualifier */
1330+ bool is_const = false;
1331+ if (lex_accept (T_const ))
1332+ is_const = true;
1333+
1334+ read_full_var_decl (& func -> param_defs [vn ], anon , true);
1335+ func -> param_defs [vn ].is_const_qualified = is_const ;
1336+ vn ++ ;
13301337 lex_accept (T_comma );
13311338 }
13321339 func -> num_params = vn ;
@@ -3808,6 +3815,7 @@ basic_block_t *read_body_statement(block_t *parent, basic_block_t *bb)
38083815 type_t * type ;
38093816 var_t * vd , * rs1 , * rs2 , * var ;
38103817 opcode_t prefix_op = OP_generic ;
3818+ bool is_const = false;
38113819
38123820 if (!bb )
38133821 printf ("Warning: unreachable code detected\n" );
@@ -4127,6 +4135,7 @@ basic_block_t *read_body_statement(block_t *parent, basic_block_t *bb)
41274135 type = find_type (token , find_type_flag );
41284136 if (type ) {
41294137 var = require_typed_var (parent , type );
4138+ var -> is_const_qualified = is_const ;
41304139 read_partial_var_decl (var , NULL );
41314140 add_insn (parent , bb , OP_allocat , var , NULL , NULL , 0 , NULL );
41324141 add_symbol (bb , var );
@@ -4332,14 +4341,22 @@ basic_block_t *read_body_statement(block_t *parent, basic_block_t *bb)
43324341 error ("Unknown struct/union type" );
43334342 }
43344343
4344+ /* Handle const qualifier for local variable declarations */
4345+ if (lex_accept (T_const )) {
4346+ is_const = true;
4347+ /* After const, we expect a type */
4348+ if (!lex_peek (T_identifier , token ))
4349+ error ("Expected type after const" );
4350+ }
4351+
43354352 /* statement with prefix */
4336- if (lex_accept (T_increment ))
4353+ if (! is_const && lex_accept (T_increment ))
43374354 prefix_op = OP_add ;
4338- else if (lex_accept (T_decrement ))
4355+ else if (! is_const && lex_accept (T_decrement ))
43394356 prefix_op = OP_sub ;
43404357 /* must be an identifier or asterisk (for pointer dereference) */
43414358 bool has_asterisk = lex_peek (T_asterisk , NULL );
4342- if (!lex_peek (T_identifier , token ) && !has_asterisk )
4359+ if (!is_const && ! lex_peek (T_identifier , token ) && !has_asterisk )
43434360 error ("Unexpected token" );
43444361
43454362 /* handle macro parameter substitution for statements */
@@ -4411,6 +4428,7 @@ basic_block_t *read_body_statement(block_t *parent, basic_block_t *bb)
44114428
44124429 if (type ) {
44134430 var = require_typed_var (parent , type );
4431+ var -> is_const_qualified = is_const ;
44144432 read_full_var_decl (var , false, false);
44154433 add_insn (parent , bb , OP_allocat , var , NULL , NULL , 0 , NULL );
44164434 add_symbol (bb , var );
@@ -4729,10 +4747,11 @@ void read_func_body(func_t *func)
47294747}
47304748
47314749/* if first token is type */
4732- void read_global_decl (block_t * block )
4750+ void read_global_decl (block_t * block , bool is_const )
47334751{
47344752 var_t * var = require_var (block );
47354753 var -> is_global = true;
4754+ var -> is_const_qualified = is_const ;
47364755
47374756 /* new function, or variables under parent */
47384757 read_full_var_decl (var , false, false);
@@ -4818,6 +4837,7 @@ void initialize_struct_field(var_t *nv, var_t *v, int offset)
48184837 nv -> ptr_level = 0 ;
48194838 nv -> is_func = false;
48204839 nv -> is_global = false;
4840+ nv -> is_const_qualified = false;
48214841 nv -> array_size = 0 ;
48224842 nv -> offset = offset ;
48234843 nv -> init_val = 0 ;
@@ -4832,6 +4852,11 @@ void read_global_statement(void)
48324852{
48334853 char token [MAX_ID_LEN ];
48344854 block_t * block = GLOBAL_BLOCK ; /* global block */
4855+ bool is_const = false;
4856+
4857+ /* Handle const qualifier */
4858+ if (lex_accept (T_const ))
4859+ is_const = true;
48354860
48364861 if (lex_accept (T_struct )) {
48374862 int i = 0 , size = 0 ;
@@ -4847,6 +4872,7 @@ void read_global_statement(void)
48474872 /* one or more declarators */
48484873 var_t * var = require_typed_var (block , decl_type );
48494874 var -> is_global = true; /* Global struct variable */
4875+ var -> is_const_qualified = is_const ;
48504876 read_partial_var_decl (var , NULL );
48514877 add_insn (block , GLOBAL_FUNC -> bbs , OP_allocat , var , NULL , NULL , 0 ,
48524878 NULL );
@@ -5144,7 +5170,7 @@ void read_global_statement(void)
51445170 lex_expect (T_semicolon );
51455171 }
51465172 } else if (lex_peek (T_identifier , NULL )) {
5147- read_global_decl (block );
5173+ read_global_decl (block , is_const );
51485174 } else
51495175 error ("Syntax error in global statement" );
51505176}
@@ -5155,6 +5181,7 @@ void parse_internal(void)
51555181 GLOBAL_FUNC = add_func ("" , true);
51565182 GLOBAL_FUNC -> stack_size = 4 ;
51575183 GLOBAL_FUNC -> bbs = arena_calloc (BB_ARENA , 1 , sizeof (basic_block_t ));
5184+ GLOBAL_FUNC -> bbs -> belong_to = GLOBAL_FUNC ; /* Prevent nullptr deref in RA */
51585185
51595186 /* built-in types */
51605187 TY_void = add_named_type ("void" );
0 commit comments