History

Fix qualifiers on const array struct members

Use the existing array-aware qualifier helper when propagating qualifiers from a const or volatile aggregate to a selected field. This keeps address-of array members from spuriously warning while preserving warnings for discarded qualifiers and read-only writes. Add regression coverage for pointer-to-array returns, array decay, and writes through const array members.

Mounir IDRASSI committed 5 months ago

Commit a3382581 parent fb4077f3 files · +140 −1Browse files

Unified · Split

3 files
  1. tccgen.c +2 −1
  2. tests/tests2/60_errors_and_warnings.c +110 −0
  3. tests/tests2/60_errors_and_warnings.expect +28 −0
tccgen.c+2−1
@@ -6184,7 +6184,8 @@ special_math_val: · 6183 unmodified lines
6184 gen_op('+');6184 gen_op('+');
6185 /* change type to field type, and set to lvalue */6185 /* change type to field type, and set to lvalue */
6186 vtop->type = s->type;6186 vtop->type = s->type;
6187 vtop->type.t |= qualifiers;6187 if (qualifiers)
6188 parse_btype_qualify(&vtop->type, qualifiers);
6188 /* an array is never an lvalue */6189 /* an array is never an lvalue */
6189 if (!(vtop->type.t & VT_ARRAY)) {6190 if (!(vtop->type.t & VT_ARRAY)) {
6190 vtop->r |= VT_LVAL;6191 vtop->r |= VT_LVAL;
tests/tests2/60_errors_and_warnings.c+110−0
@@ -551,4 +551,114 @@ int main(int argc, char **argv) · 550 unmodified lines
551 551
552}552}
553 553
554#elif defined test_const_array_member_addr_ok
555
556typedef int int_array[1];
557typedef struct { int_array arr; } my_struct;
558
559int_array const *get_array(const my_struct *s)
560{
561 return &(s->arr);
562}
563
564#elif defined test_const_array_member_decay_ok
565
566typedef int int_array[1];
567typedef struct { int_array arr; } my_struct;
568
569const int *good_decay(const my_struct *s)
570{
571 return s->arr;
572}
573
574#elif defined test_const_array_member_addr_bad
575
576typedef int int_array[1];
577typedef struct { int_array arr; } my_struct;
578
579int_array *bad_array_addr(const my_struct *s)
580{
581 return &(s->arr);
582}
583
584#elif defined test_const_array_member_decay_bad
585
586typedef int int_array[1];
587typedef struct { int_array arr; } my_struct;
588
589int *bad_decay(const my_struct *s)
590{
591 return s->arr;
592}
593
594#elif defined test_const_array_member_write_bad
595
596typedef int int_array[1];
597typedef struct { int_array arr; } my_struct;
598
599void bad_write(const my_struct *s)
600{
601 s->arr[0] = 1;
602}
603
604#elif defined test_const_struct_array_member_write_bad
605
606typedef struct { int x; } inner;
607typedef struct { inner arr[1]; } outer;
608
609void bad_inner_write(const outer *s)
610{
611 s->arr[0].x = 1;
612}
613
614#elif defined test_volatile_array_member_addr_ok
615
616typedef int int_array[1];
617typedef struct { int_array arr; } my_struct;
618
619int_array volatile *get_volatile_array(volatile my_struct *s)
620{
621 return &(s->arr);
622}
623
624#elif defined test_volatile_array_member_decay_ok
625
626typedef int int_array[1];
627typedef struct { int_array arr; } my_struct;
628
629volatile int *good_volatile_decay(volatile my_struct *s)
630{
631 return s->arr;
632}
633
634#elif defined test_volatile_array_member_addr_bad
635
636typedef int int_array[1];
637typedef struct { int_array arr; } my_struct;
638
639int_array *bad_volatile_array_addr(volatile my_struct *s)
640{
641 return &(s->arr);
642}
643
644#elif defined test_volatile_array_member_decay_bad
645
646typedef int int_array[1];
647typedef struct { int_array arr; } my_struct;
648
649int *bad_volatile_decay(volatile my_struct *s)
650{
651 return s->arr;
652}
653
654#elif defined test_volatile_array_member_write_ok
655
656typedef int int_array[1];
657typedef struct { int_array arr; } my_struct;
658
659void good_volatile_write(volatile my_struct *s)
660{
661 s->arr[0] = 1;
662}
663
554#endif664#endif
tests/tests2/60_errors_and_warnings.expect+28−0
@@ -262,3 +262,31 @@ bar 15 12 34 · 261 unmodified lines
262[test_scope_3]262[test_scope_3]
26360_errors_and_warnings.c:548: warning: assignment from incompatible pointer type26360_errors_and_warnings.c:548: warning: assignment from incompatible pointer type
26460_errors_and_warnings.c:549: error: initialization of incomplete type26460_errors_and_warnings.c:549: error: initialization of incomplete type
265
266[test_const_array_member_addr_ok]
267
268[test_const_array_member_decay_ok]
269
270[test_const_array_member_addr_bad]
27160_errors_and_warnings.c:581: warning: assignment discards qualifiers from pointer target type
272
273[test_const_array_member_decay_bad]
27460_errors_and_warnings.c:591: warning: assignment discards qualifiers from pointer target type
275
276[test_const_array_member_write_bad]
27760_errors_and_warnings.c:601: warning: assignment of read-only location
278
279[test_const_struct_array_member_write_bad]
28060_errors_and_warnings.c:611: warning: assignment of read-only location
281
282[test_volatile_array_member_addr_ok]
283
284[test_volatile_array_member_decay_ok]
285
286[test_volatile_array_member_addr_bad]
28760_errors_and_warnings.c:641: warning: assignment discards qualifiers from pointer target type
288
289[test_volatile_array_member_decay_bad]
29060_errors_and_warnings.c:651: warning: assignment discards qualifiers from pointer target type
291
292[test_volatile_array_member_write_ok]

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t