Wed Jul 21 21:24:45 2021 UTC ()
lint: move assignments to $$ at the end of the action

They are closely related to return statements.

While here, add some more remarks from reviewing the grammar.

No functional change.


(rillig)
diff -r1.333 -r1.334 src/usr.bin/xlint/lint1/cgram.y

cvs diff -r1.333 -r1.334 src/usr.bin/xlint/lint1/cgram.y (expand / switch to unified diff)

--- src/usr.bin/xlint/lint1/cgram.y 2021/07/21 21:17:57 1.333
+++ src/usr.bin/xlint/lint1/cgram.y 2021/07/21 21:24:45 1.334
@@ -1,15 +1,15 @@ @@ -1,15 +1,15 @@
1%{ 1%{
2/* $NetBSD: cgram.y,v 1.333 2021/07/21 21:17:57 rillig Exp $ */ 2/* $NetBSD: cgram.y,v 1.334 2021/07/21 21:24:45 rillig Exp $ */
3 3
4/* 4/*
5 * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. 5 * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
6 * Copyright (c) 1994, 1995 Jochen Pohl 6 * Copyright (c) 1994, 1995 Jochen Pohl
7 * All Rights Reserved. 7 * All Rights Reserved.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the 15 * notice, this list of conditions and the following disclaimer in the
@@ -25,27 +25,27 @@ @@ -25,27 +25,27 @@
25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 27 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */ 34 */
35 35
36#include <sys/cdefs.h> 36#include <sys/cdefs.h>
37#if defined(__RCSID) && !defined(lint) 37#if defined(__RCSID) && !defined(lint)
38__RCSID("$NetBSD: cgram.y,v 1.333 2021/07/21 21:17:57 rillig Exp $"); 38__RCSID("$NetBSD: cgram.y,v 1.334 2021/07/21 21:24:45 rillig Exp $");
39#endif 39#endif
40 40
41#include <limits.h> 41#include <limits.h>
42#include <stdlib.h> 42#include <stdlib.h>
43#include <string.h> 43#include <string.h>
44 44
45#include "lint1.h" 45#include "lint1.h"
46 46
47extern char *yytext; 47extern char *yytext;
48 48
49/* 49/*
50 * Contains the level of current declaration, used for symbol table entries. 50 * Contains the level of current declaration, used for symbol table entries.
51 * 0 is the top-level, > 0 is inside a function body. 51 * 0 is the top-level, > 0 is inside a function body.
@@ -365,32 +365,32 @@ program: @@ -365,32 +365,32 @@ program:
365 } 365 }
366 | translation_unit 366 | translation_unit
367 ; 367 ;
368 368
369identifier_sym: /* helper for struct/union/enum */ 369identifier_sym: /* helper for struct/union/enum */
370 identifier { 370 identifier {
371 $$ = getsym($1); 371 $$ = getsym($1);
372 } 372 }
373 ; 373 ;
374 374
375/* K&R ???, C90 ???, C99 6.4.2.1, C11 ??? */ 375/* K&R ???, C90 ???, C99 6.4.2.1, C11 ??? */
376identifier: 376identifier:
377 T_NAME { 377 T_NAME {
 378 cgram_debug("name '%s'", $1->sb_name);
378 $$ = $1; 379 $$ = $1;
379 cgram_debug("name '%s'", $$->sb_name); 
380 } 380 }
381 | T_TYPENAME { 381 | T_TYPENAME {
 382 cgram_debug("typename '%s'", $1->sb_name);
382 $$ = $1; 383 $$ = $1;
383 cgram_debug("typename '%s'", $$->sb_name); 
384 } 384 }
385 ; 385 ;
386 386
387/* see C99 6.4.5, string literals are joined by 5.1.1.2 */ 387/* see C99 6.4.5, string literals are joined by 5.1.1.2 */
388string: 388string:
389 T_STRING 389 T_STRING
390 | T_STRING string2 { 390 | T_STRING string2 {
391 $$ = cat_strings($1, $2); 391 $$ = cat_strings($1, $2);
392 } 392 }
393 ; 393 ;
394 394
395/* see C99 6.4.5, string literals are joined by 5.1.1.2 */ 395/* see C99 6.4.5, string literals are joined by 5.1.1.2 */
396string2: 396string2:
@@ -533,29 +533,29 @@ gcc_statement_expr_item: @@ -533,29 +533,29 @@ gcc_statement_expr_item:
533 } 533 }
534 | non_expr_statement { 534 | non_expr_statement {
535 $$ = expr_zalloc_tnode(); 535 $$ = expr_zalloc_tnode();
536 $$->tn_type = gettyp(VOID); 536 $$->tn_type = gettyp(VOID);
537 } 537 }
538 | expression T_SEMI { 538 | expression T_SEMI {
539 if ($1 == NULL) { /* in case of syntax errors */ 539 if ($1 == NULL) { /* in case of syntax errors */
540 $$ = expr_zalloc_tnode(); 540 $$ = expr_zalloc_tnode();
541 $$->tn_type = gettyp(VOID); 541 $$->tn_type = gettyp(VOID);
542 } else { 542 } else {
543 /* XXX: do that only on the last name */ 543 /* XXX: do that only on the last name */
544 if ($1->tn_op == NAME) 544 if ($1->tn_op == NAME)
545 $1->tn_sym->s_used = true; 545 $1->tn_sym->s_used = true;
546 $$ = $1; 
547 expr($1, false, false, false, false); 546 expr($1, false, false, false, false);
548 seen_fallthrough = false; 547 seen_fallthrough = false;
 548 $$ = $1;
549 } 549 }
550 } 550 }
551 ; 551 ;
552 552
553point_or_arrow: /* helper for 'postfix_expression' */ 553point_or_arrow: /* helper for 'postfix_expression' */
554 T_POINT { 554 T_POINT {
555 symtyp = FMEMBER; 555 symtyp = FMEMBER;
556 $$ = POINT; 556 $$ = POINT;
557 } 557 }
558 | T_ARROW { 558 | T_ARROW {
559 symtyp = FMEMBER; 559 symtyp = FMEMBER;
560 $$ = ARROW; 560 $$ = ARROW;
561 } 561 }
@@ -605,26 +605,27 @@ unary_expression: @@ -605,26 +605,27 @@ unary_expression:
605 | T_EXTENSION cast_expression { /* GCC c_parser_unary_expression */ 605 | T_EXTENSION cast_expression { /* GCC c_parser_unary_expression */
606 $$ = $2; 606 $$ = $2;
607 } 607 }
608 | T_SIZEOF unary_expression { 608 | T_SIZEOF unary_expression {
609 $$ = $2 == NULL ? NULL : build_sizeof($2->tn_type); 609 $$ = $2 == NULL ? NULL : build_sizeof($2->tn_type);
610 if ($$ != NULL) 610 if ($$ != NULL)
611 check_expr_misc($2, false, false, false, false, false, true); 611 check_expr_misc($2, false, false, false, false, false, true);
612 } 612 }
613 | T_SIZEOF T_LPAREN type_name T_RPAREN { 613 | T_SIZEOF T_LPAREN type_name T_RPAREN {
614 $$ = build_sizeof($3); 614 $$ = build_sizeof($3);
615 } 615 }
616 /* K&R ---, C90 ---, C99 ---, C11 6.5.3 */ 616 /* K&R ---, C90 ---, C99 ---, C11 6.5.3 */
617 | T_ALIGNOF T_LPAREN type_name T_RPAREN { 617 | T_ALIGNOF T_LPAREN type_name T_RPAREN {
 618 /* TODO: c11ism */
618 $$ = build_alignof($3); 619 $$ = build_alignof($3);
619 } 620 }
620 ; 621 ;
621 622
622/* The rule 'unary_operator' is inlined into unary_expression. */ 623/* The rule 'unary_operator' is inlined into unary_expression. */
623 624
624/* K&R 7.2, C90 ???, C99 6.5.4, C11 6.5.4 */ 625/* K&R 7.2, C90 ???, C99 6.5.4, C11 6.5.4 */
625cast_expression: 626cast_expression:
626 unary_expression 627 unary_expression
627 | T_LPAREN type_name T_RPAREN cast_expression { 628 | T_LPAREN type_name T_RPAREN cast_expression {
628 $$ = cast($4, $2); 629 $$ = cast($4, $2);
629 } 630 }
630 ; 631 ;
@@ -726,26 +727,27 @@ declaration_or_error: @@ -726,26 +727,27 @@ declaration_or_error:
726 ; 727 ;
727 728
728declaration: /* C99 6.7 */ 729declaration: /* C99 6.7 */
729 begin_type_declmods end_type T_SEMI { 730 begin_type_declmods end_type T_SEMI {
730 if (dcs->d_scl == TYPEDEF) { 731 if (dcs->d_scl == TYPEDEF) {
731 /* typedef declares no type name */ 732 /* typedef declares no type name */
732 warning(72); 733 warning(72);
733 } else { 734 } else {
734 /* empty declaration */ 735 /* empty declaration */
735 warning(2); 736 warning(2);
736 } 737 }
737 } 738 }
738 | begin_type_declmods end_type notype_init_declarators T_SEMI 739 | begin_type_declmods end_type notype_init_declarators T_SEMI
 740 /* ^^ There is no check for the missing type-specifier. */
739 | begin_type_declaration_specifiers end_type T_SEMI { 741 | begin_type_declaration_specifiers end_type T_SEMI {
740 if (dcs->d_scl == TYPEDEF) { 742 if (dcs->d_scl == TYPEDEF) {
741 /* typedef declares no type name */ 743 /* typedef declares no type name */
742 warning(72); 744 warning(72);
743 } else if (!dcs->d_nonempty_decl) { 745 } else if (!dcs->d_nonempty_decl) {
744 /* empty declaration */ 746 /* empty declaration */
745 warning(2); 747 warning(2);
746 } 748 }
747 } 749 }
748 | begin_type_declaration_specifiers end_type 750 | begin_type_declaration_specifiers end_type
749 type_init_declarators T_SEMI 751 type_init_declarators T_SEMI
750 ; 752 ;
751 753
@@ -767,26 +769,27 @@ begin_type_declmods: /* see C99 6.7 */ @@ -767,26 +769,27 @@ begin_type_declmods: /* see C99 6.7 */
767 begin_type T_QUAL { 769 begin_type T_QUAL {
768 add_qualifier($2); 770 add_qualifier($2);
769 } 771 }
770 | begin_type T_SCLASS { 772 | begin_type T_SCLASS {
771 add_storage_class($2); 773 add_storage_class($2);
772 } 774 }
773 | begin_type_declmods declmod 775 | begin_type_declmods declmod
774 ; 776 ;
775 777
776begin_type_specifier_qualifier_list: /* see C11 6.7.2.1 */ 778begin_type_specifier_qualifier_list: /* see C11 6.7.2.1 */
777 begin_type_typespec { 779 begin_type_typespec {
778 add_type($1); 780 add_type($1);
779 } 781 }
 782 /* TODO: shift/reduce conflict for type_attribute */
780 | type_attribute begin_type_specifier_qualifier_list 783 | type_attribute begin_type_specifier_qualifier_list
781 | begin_type_qualifier_list type_specifier { 784 | begin_type_qualifier_list type_specifier {
782 add_type($2); 785 add_type($2);
783 } 786 }
784 | begin_type_specifier_qualifier_list T_QUAL { 787 | begin_type_specifier_qualifier_list T_QUAL {
785 add_qualifier($2); 788 add_qualifier($2);
786 } 789 }
787 | begin_type_specifier_qualifier_list notype_type_specifier { 790 | begin_type_specifier_qualifier_list notype_type_specifier {
788 add_type($2); 791 add_type($2);
789 } 792 }
790 | begin_type_specifier_qualifier_list type_attribute 793 | begin_type_specifier_qualifier_list type_attribute
791 ; 794 ;
792 795
@@ -824,26 +827,27 @@ type_attribute_list: @@ -824,26 +827,27 @@ type_attribute_list:
824 ; 827 ;
825 828
826type_attribute_opt: 829type_attribute_opt:
827 /* empty */ 830 /* empty */
828 | type_attribute 831 | type_attribute
829 ; 832 ;
830 833
831type_attribute: /* See C11 6.7 declaration-specifiers */ 834type_attribute: /* See C11 6.7 declaration-specifiers */
832 T_ATTRIBUTE T_LPAREN T_LPAREN { 835 T_ATTRIBUTE T_LPAREN T_LPAREN {
833 attron = true; 836 attron = true;
834 } gcc_attribute_spec_list { 837 } gcc_attribute_spec_list {
835 attron = false; 838 attron = false;
836 } T_RPAREN T_RPAREN 839 } T_RPAREN T_RPAREN
 840 /* TODO: c11ism */
837 | T_ALIGNAS T_LPAREN align_as T_RPAREN 841 | T_ALIGNAS T_LPAREN align_as T_RPAREN
838 | T_PACKED { 842 | T_PACKED {
839 addpacked(); 843 addpacked();
840 } 844 }
841 | T_NORETURN 845 | T_NORETURN
842 ; 846 ;
843 847
844align_as: /* See alignment-specifier in C11 6.7.5 */ 848align_as: /* See alignment-specifier in C11 6.7.5 */
845 type_specifier 849 type_specifier
846 | constant_expr 850 | constant_expr
847 ; 851 ;
848 852
849begin_type: 853begin_type:
@@ -939,26 +943,27 @@ struct_declaration_list_with_rbrace: /*  @@ -939,26 +943,27 @@ struct_declaration_list_with_rbrace: /*
939 $$ = NULL; 943 $$ = NULL;
940 } 944 }
941 ; 945 ;
942 946
943struct_declaration_list: /* C99 6.7.2.1 */ 947struct_declaration_list: /* C99 6.7.2.1 */
944 struct_declaration 948 struct_declaration
945 | struct_declaration_list struct_declaration { 949 | struct_declaration_list struct_declaration {
946 $$ = lnklst($1, $2); 950 $$ = lnklst($1, $2);
947 } 951 }
948 ; 952 ;
949 953
950struct_declaration: /* C99 6.7.2.1 */ 954struct_declaration: /* C99 6.7.2.1 */
951 begin_type_qualifier_list end_type { 955 begin_type_qualifier_list end_type {
 956 /* ^^ There is no check for the missing type-specifier. */
952 /* too late, i know, but getsym() compensates it */ 957 /* too late, i know, but getsym() compensates it */
953 symtyp = FMEMBER; 958 symtyp = FMEMBER;
954 } notype_struct_declarators type_attribute_opt T_SEMI { 959 } notype_struct_declarators type_attribute_opt T_SEMI {
955 symtyp = FVFT; 960 symtyp = FVFT;
956 $$ = $4; 961 $$ = $4;
957 } 962 }
958 | begin_type_specifier_qualifier_list end_type { 963 | begin_type_specifier_qualifier_list end_type {
959 symtyp = FMEMBER; 964 symtyp = FMEMBER;
960 } type_struct_declarators type_attribute_opt T_SEMI { 965 } type_struct_declarators type_attribute_opt T_SEMI {
961 symtyp = FVFT; 966 symtyp = FVFT;
962 $$ = $4; 967 $$ = $4;
963 } 968 }
964 | begin_type_qualifier_list end_type type_attribute_opt T_SEMI { 969 | begin_type_qualifier_list end_type type_attribute_opt T_SEMI {
@@ -1465,60 +1470,64 @@ vararg_parameter_type_list: @@ -1465,60 +1470,64 @@ vararg_parameter_type_list:
1465 ; 1470 ;
1466 1471
1467/* XXX: C99 6.7.5 defines the same name, but it looks different. */ 1472/* XXX: C99 6.7.5 defines the same name, but it looks different. */
1468parameter_type_list: 1473parameter_type_list:
1469 parameter_declaration 1474 parameter_declaration
1470 | parameter_type_list T_COMMA parameter_declaration { 1475 | parameter_type_list T_COMMA parameter_declaration {
1471 $$ = lnklst($1, $3); 1476 $$ = lnklst($1, $3);
1472 } 1477 }
1473 ; 1478 ;
1474 1479
1475/* XXX: C99 6.7.5 defines the same name, but it looks completely different. */ 1480/* XXX: C99 6.7.5 defines the same name, but it looks completely different. */
1476parameter_declaration: 1481parameter_declaration:
1477 begin_type_declmods end_type { 1482 begin_type_declmods end_type {
 1483 /* ^^ There is no check for the missing type-specifier. */
1478 $$ = declare_argument(abstract_name(), false); 1484 $$ = declare_argument(abstract_name(), false);
1479 } 1485 }
1480 | begin_type_declaration_specifiers end_type { 1486 | begin_type_declaration_specifiers end_type {
1481 $$ = declare_argument(abstract_name(), false); 1487 $$ = declare_argument(abstract_name(), false);
1482 } 1488 }
1483 | begin_type_declmods end_type notype_param_declarator { 1489 | begin_type_declmods end_type notype_param_declarator {
 1490 /* ^^ There is no check for the missing type-specifier. */
1484 $$ = declare_argument($3, false); 1491 $$ = declare_argument($3, false);
1485 } 1492 }
1486 /* 1493 /*
1487 * type_param_declarator is needed because of following conflict: 1494 * type_param_declarator is needed because of following conflict:
1488 * "typedef int a; f(int (a));" could be parsed as 1495 * "typedef int a; f(int (a));" could be parsed as
1489 * "function with argument a of type int", or 1496 * "function with argument a of type int", or
1490 * "function with an abstract argument of type function". 1497 * "function with an abstract argument of type function".
1491 * This grammar realizes the second case. 1498 * This grammar realizes the second case.
1492 */ 1499 */
1493 | begin_type_declaration_specifiers end_type type_param_declarator { 1500 | begin_type_declaration_specifiers end_type type_param_declarator {
1494 $$ = declare_argument($3, false); 1501 $$ = declare_argument($3, false);
1495 } 1502 }
1496 | begin_type_declmods end_type abstract_declarator { 1503 | begin_type_declmods end_type abstract_declarator {
 1504 /* ^^ There is no check for the missing type-specifier. */
1497 $$ = declare_argument($3, false); 1505 $$ = declare_argument($3, false);
1498 } 1506 }
1499 | begin_type_declaration_specifiers end_type abstract_declarator { 1507 | begin_type_declaration_specifiers end_type abstract_declarator {
1500 $$ = declare_argument($3, false); 1508 $$ = declare_argument($3, false);
1501 } 1509 }
1502 ; 1510 ;
1503 1511
1504initializer: /* C99 6.7.8 "Initialization" */ 1512initializer: /* C99 6.7.8 "Initialization" */
1505 assignment_expression { 1513 assignment_expression {
1506 init_expr($1); 1514 init_expr($1);
1507 } 1515 }
1508 | init_lbrace init_rbrace { 1516 | init_lbrace init_rbrace {
1509 /* XXX: Empty braces are not covered by C99 6.7.8. */ 1517 /* XXX: Empty braces are not covered by C99 6.7.8. */
1510 } 1518 }
1511 | init_lbrace initializer_list comma_opt init_rbrace 1519 | init_lbrace initializer_list comma_opt init_rbrace
 1520 /* XXX: What is this error handling for? */
1512 | error 1521 | error
1513 ; 1522 ;
1514 1523
1515initializer_list: /* C99 6.7.8 "Initialization" */ 1524initializer_list: /* C99 6.7.8 "Initialization" */
1516 initializer_list_item 1525 initializer_list_item
1517 | initializer_list T_COMMA initializer_list_item 1526 | initializer_list T_COMMA initializer_list_item
1518 ; 1527 ;
1519 1528
1520initializer_list_item: /* helper */ 1529initializer_list_item: /* helper */
1521 designation initializer 1530 designation initializer
1522 | initializer 1531 | initializer
1523 ; 1532 ;
1524 1533
@@ -1930,29 +1939,31 @@ function_definition: /* C99 6.9.1 */ @@ -1930,29 +1939,31 @@ function_definition: /* C99 6.9.1 */
1930 end_declaration_level(); 1939 end_declaration_level();
1931 block_level--; 1940 block_level--;
1932 check_func_lint_directives(); 1941 check_func_lint_directives();
1933 check_func_old_style_arguments(); 1942 check_func_old_style_arguments();
1934 begin_control_statement(CS_FUNCTION_BODY); 1943 begin_control_statement(CS_FUNCTION_BODY);
1935 } compound_statement { 1944 } compound_statement {
1936 funcend(); 1945 funcend();
1937 end_control_statement(CS_FUNCTION_BODY); 1946 end_control_statement(CS_FUNCTION_BODY);
1938 } 1947 }
1939 ; 1948 ;
1940 1949
1941func_declarator: 1950func_declarator:
1942 begin_type end_type notype_declarator { 1951 begin_type end_type notype_declarator {
 1952 /* ^^ There is no check for the missing type-specifier. */
1943 $$ = $3; 1953 $$ = $3;
1944 } 1954 }
1945 | begin_type_declmods end_type notype_declarator { 1955 | begin_type_declmods end_type notype_declarator {
 1956 /* ^^ There is no check for the missing type-specifier. */
1946 $$ = $3; 1957 $$ = $3;
1947 } 1958 }
1948 | begin_type_declaration_specifiers end_type type_declarator { 1959 | begin_type_declaration_specifiers end_type type_declarator {
1949 $$ = $3; 1960 $$ = $3;
1950 } 1961 }
1951 ; 1962 ;
1952 1963
1953arg_declaration_list_opt: /* C99 6.9.1p13 example 1 */ 1964arg_declaration_list_opt: /* C99 6.9.1p13 example 1 */
1954 /* empty */ 1965 /* empty */
1955 | arg_declaration_list 1966 | arg_declaration_list
1956 ; 1967 ;
1957 1968
1958arg_declaration_list: /* C99 6.9.1p13 example 1 */ 1969arg_declaration_list: /* C99 6.9.1p13 example 1 */