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
61846184 gen_op('+');
61856185 /* change type to field type, and set to lvalue */
61866186 vtop->type = s->type;
6187− vtop->type.t |= qualifiers;
6187+ if (qualifiers)
6188+ parse_btype_qualify(&vtop->type, qualifiers);
61886189 /* an array is never an lvalue */
61896190 if (!(vtop->type.t & VT_ARRAY)) {
61906191 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
551551
552552 }
553553
554+#elif defined test_const_array_member_addr_ok
555+
556+typedef int int_array[1];
557+typedef struct { int_array arr; } my_struct;
558+
559+int_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+
566+typedef int int_array[1];
567+typedef struct { int_array arr; } my_struct;
568+
569+const int *good_decay(const my_struct *s)
570+{
571+ return s->arr;
572+}
573+
574+#elif defined test_const_array_member_addr_bad
575+
576+typedef int int_array[1];
577+typedef struct { int_array arr; } my_struct;
578+
579+int_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+
586+typedef int int_array[1];
587+typedef struct { int_array arr; } my_struct;
588+
589+int *bad_decay(const my_struct *s)
590+{
591+ return s->arr;
592+}
593+
594+#elif defined test_const_array_member_write_bad
595+
596+typedef int int_array[1];
597+typedef struct { int_array arr; } my_struct;
598+
599+void 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+
606+typedef struct { int x; } inner;
607+typedef struct { inner arr[1]; } outer;
608+
609+void 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+
616+typedef int int_array[1];
617+typedef struct { int_array arr; } my_struct;
618+
619+int_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+
626+typedef int int_array[1];
627+typedef struct { int_array arr; } my_struct;
628+
629+volatile 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+
636+typedef int int_array[1];
637+typedef struct { int_array arr; } my_struct;
638+
639+int_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+
646+typedef int int_array[1];
647+typedef struct { int_array arr; } my_struct;
648+
649+int *bad_volatile_decay(volatile my_struct *s)
650+{
651+ return s->arr;
652+}
653+
654+#elif defined test_volatile_array_member_write_ok
655+
656+typedef int int_array[1];
657+typedef struct { int_array arr; } my_struct;
658+
659+void good_volatile_write(volatile my_struct *s)
660+{
661+ s->arr[0] = 1;
662+}
663+
554664 #endif
tests/tests2/60_errors_and_warnings.expect+28−0
@@ -262,3 +262,31 @@ bar 15 12 34 · 261 unmodified lines
262262 [test_scope_3]
263263 60_errors_and_warnings.c:548: warning: assignment from incompatible pointer type
264264 60_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]
271+60_errors_and_warnings.c:581: warning: assignment discards qualifiers from pointer target type
272+
273+[test_const_array_member_decay_bad]
274+60_errors_and_warnings.c:591: warning: assignment discards qualifiers from pointer target type
275+
276+[test_const_array_member_write_bad]
277+60_errors_and_warnings.c:601: warning: assignment of read-only location
278+
279+[test_const_struct_array_member_write_bad]
280+60_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]
287+60_errors_and_warnings.c:641: warning: assignment discards qualifiers from pointer target type
288+
289+[test_volatile_array_member_decay_bad]
290+60_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