| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: decl.c,v 1.364 2023/07/29 07:03:19 rillig Exp $ */ | | 1 | /* $NetBSD: decl.c,v 1.365 2023/07/29 07:26:53 rillig Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. | | 4 | * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. |
5 | * Copyright (c) 1994, 1995 Jochen Pohl | | 5 | * Copyright (c) 1994, 1995 Jochen Pohl |
6 | * All Rights Reserved. | | 6 | * All Rights Reserved. |
7 | * | | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | | 8 | * Redistribution and use in source and binary forms, with or without |
9 | * modification, are permitted provided that the following conditions | | 9 | * modification, are permitted provided that the following conditions |
10 | * are met: | | 10 | * are met: |
11 | * 1. Redistributions of source code must retain the above copyright | | 11 | * 1. Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. | | 12 | * notice, this list of conditions and the following disclaimer. |
13 | * 2. Redistributions in binary form must reproduce the above copyright | | 13 | * 2. Redistributions in binary form must reproduce the above copyright |
14 | * notice, this list of conditions and the following disclaimer in the | | 14 | * notice, this list of conditions and the following disclaimer in the |
| @@ -28,27 +28,27 @@ | | | @@ -28,27 +28,27 @@ |
28 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | | 28 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | | 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | | 30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | | 31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | | 32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
33 | */ | | 33 | */ |
34 | | | 34 | |
35 | #if HAVE_NBTOOL_CONFIG_H | | 35 | #if HAVE_NBTOOL_CONFIG_H |
36 | #include "nbtool_config.h" | | 36 | #include "nbtool_config.h" |
37 | #endif | | 37 | #endif |
38 | | | 38 | |
39 | #include <sys/cdefs.h> | | 39 | #include <sys/cdefs.h> |
40 | #if defined(__RCSID) | | 40 | #if defined(__RCSID) |
41 | __RCSID("$NetBSD: decl.c,v 1.364 2023/07/29 07:03:19 rillig Exp $"); | | 41 | __RCSID("$NetBSD: decl.c,v 1.365 2023/07/29 07:26:53 rillig Exp $"); |
42 | #endif | | 42 | #endif |
43 | | | 43 | |
44 | #include <sys/param.h> | | 44 | #include <sys/param.h> |
45 | #include <limits.h> | | 45 | #include <limits.h> |
46 | #include <stdlib.h> | | 46 | #include <stdlib.h> |
47 | #include <string.h> | | 47 | #include <string.h> |
48 | | | 48 | |
49 | #include "lint1.h" | | 49 | #include "lint1.h" |
50 | | | 50 | |
51 | const char unnamed[] = "<unnamed>"; | | 51 | const char unnamed[] = "<unnamed>"; |
52 | | | 52 | |
53 | /* shared type structures for arithmetic types and void */ | | 53 | /* shared type structures for arithmetic types and void */ |
54 | static type_t typetab[NTSPEC]; | | 54 | static type_t typetab[NTSPEC]; |
| @@ -2782,27 +2782,27 @@ global_clean_up(void) | | | @@ -2782,27 +2782,27 @@ global_clean_up(void) |
2782 | } | | 2782 | } |
2783 | | | 2783 | |
2784 | sym_t * | | 2784 | sym_t * |
2785 | declare_abstract_type(sym_t *sym) | | 2785 | declare_abstract_type(sym_t *sym) |
2786 | { | | 2786 | { |
2787 | | | 2787 | |
2788 | check_function_definition(sym, true); | | 2788 | check_function_definition(sym, true); |
2789 | check_type(sym); | | 2789 | check_type(sym); |
2790 | return sym; | | 2790 | return sym; |
2791 | } | | 2791 | } |
2792 | | | 2792 | |
2793 | /* Checks size after declarations of variables and their initialization. */ | | 2793 | /* Checks size after declarations of variables and their initialization. */ |
2794 | void | | 2794 | void |
2795 | check_size(sym_t *dsym) | | 2795 | check_size(const sym_t *dsym) |
2796 | { | | 2796 | { |
2797 | | | 2797 | |
2798 | if (dsym->s_def == DEF && | | 2798 | if (dsym->s_def == DEF && |
2799 | dsym->s_scl != TYPEDEF && | | 2799 | dsym->s_scl != TYPEDEF && |
2800 | dsym->s_type->t_tspec != FUNC && | | 2800 | dsym->s_type->t_tspec != FUNC && |
2801 | length_in_bits(dsym->s_type, dsym->s_name) == 0 && | | 2801 | length_in_bits(dsym->s_type, dsym->s_name) == 0 && |
2802 | dsym->s_type->t_tspec == ARRAY && | | 2802 | dsym->s_type->t_tspec == ARRAY && |
2803 | dsym->s_type->t_dim == 0) { | | 2803 | dsym->s_type->t_dim == 0) { |
2804 | if (!allow_c90) | | 2804 | if (!allow_c90) |
2805 | /* empty array declaration for '%s' */ | | 2805 | /* empty array declaration for '%s' */ |
2806 | warning(190, dsym->s_name); | | 2806 | warning(190, dsym->s_name); |
2807 | else | | 2807 | else |
2808 | /* empty array declaration for '%s' */ | | 2808 | /* empty array declaration for '%s' */ |
| @@ -2833,57 +2833,57 @@ mark_as_used(sym_t *sym, bool fcall, boo | | | @@ -2833,57 +2833,57 @@ mark_as_used(sym_t *sym, bool fcall, boo |
2833 | /* | | 2833 | /* |
2834 | * For function calls, another record is written. | | 2834 | * For function calls, another record is written. |
2835 | * | | 2835 | * |
2836 | * XXX: Should symbols used in sizeof() be treated as used or not? | | 2836 | * XXX: Should symbols used in sizeof() be treated as used or not? |
2837 | * Probably not, because there is no point in declaring an external | | 2837 | * Probably not, because there is no point in declaring an external |
2838 | * variable only to get its size. | | 2838 | * variable only to get its size. |
2839 | */ | | 2839 | */ |
2840 | if (!fcall && !szof && sym->s_kind == FVFT && sym->s_scl == EXTERN) | | 2840 | if (!fcall && !szof && sym->s_kind == FVFT && sym->s_scl == EXTERN) |
2841 | outusg(sym); | | 2841 | outusg(sym); |
2842 | } | | 2842 | } |
2843 | | | 2843 | |
2844 | /* Warns about variables and labels that are not used or only set. */ | | 2844 | /* Warns about variables and labels that are not used or only set. */ |
2845 | void | | 2845 | void |
2846 | check_usage(decl_level *dl) | | 2846 | check_usage(const decl_level *dl) |
2847 | { | | 2847 | { |
2848 | /* for this warning LINTED has no effect */ | | 2848 | /* for this warning LINTED has no effect */ |
2849 | int saved_lwarn = lwarn; | | 2849 | int saved_lwarn = lwarn; |
2850 | lwarn = LWARN_ALL; | | 2850 | lwarn = LWARN_ALL; |
2851 | | | 2851 | |
2852 | debug_step("begin lwarn %d", lwarn); | | 2852 | debug_step("begin lwarn %d", lwarn); |
2853 | for (sym_t *sym = dl->d_first_dlsym; | | 2853 | for (sym_t *sym = dl->d_first_dlsym; |
2854 | sym != NULL; sym = sym->s_level_next) | | 2854 | sym != NULL; sym = sym->s_level_next) |
2855 | check_usage_sym(dl->d_asm, sym); | | 2855 | check_usage_sym(dl->d_asm, sym); |
2856 | lwarn = saved_lwarn; | | 2856 | lwarn = saved_lwarn; |
2857 | debug_step("end lwarn %d", lwarn); | | 2857 | debug_step("end lwarn %d", lwarn); |
2858 | } | | 2858 | } |
2859 | | | 2859 | |
2860 | static void | | 2860 | static void |
2861 | check_argument_usage(bool novar, sym_t *arg) | | 2861 | check_argument_usage(bool novar, const sym_t *arg) |
2862 | { | | 2862 | { |
2863 | | | 2863 | |
2864 | lint_assert(arg->s_set); | | 2864 | lint_assert(arg->s_set); |
2865 | | | 2865 | |
2866 | if (novar) | | 2866 | if (novar) |
2867 | return; | | 2867 | return; |
2868 | | | 2868 | |
2869 | if (!arg->s_used && !vflag) { | | 2869 | if (!arg->s_used && !vflag) { |
2870 | /* parameter '%s' unused in function '%s' */ | | 2870 | /* parameter '%s' unused in function '%s' */ |
2871 | warning_at(231, &arg->s_def_pos, arg->s_name, funcsym->s_name); | | 2871 | warning_at(231, &arg->s_def_pos, arg->s_name, funcsym->s_name); |
2872 | } | | 2872 | } |
2873 | } | | 2873 | } |
2874 | | | 2874 | |
2875 | static void | | 2875 | static void |
2876 | check_variable_usage(bool novar, sym_t *sym) | | 2876 | check_variable_usage(bool novar, const sym_t *sym) |
2877 | { | | 2877 | { |
2878 | | | 2878 | |
2879 | lint_assert(block_level != 0); | | 2879 | lint_assert(block_level != 0); |
2880 | | | 2880 | |
2881 | /* example at file scope: int c = ({ return 3; }); */ | | 2881 | /* example at file scope: int c = ({ return 3; }); */ |
2882 | if (sym->s_block_level == 0 && ch_isdigit(sym->s_name[0])) | | 2882 | if (sym->s_block_level == 0 && ch_isdigit(sym->s_name[0])) |
2883 | return; | | 2883 | return; |
2884 | | | 2884 | |
2885 | /* errors in expressions easily cause lots of these warnings */ | | 2885 | /* errors in expressions easily cause lots of these warnings */ |
2886 | if (seen_error) | | 2886 | if (seen_error) |
2887 | return; | | 2887 | return; |
2888 | | | 2888 | |
2889 | /* | | 2889 | /* |
| @@ -2931,45 +2931,45 @@ check_variable_usage(bool novar, sym_t * | | | @@ -2931,45 +2931,45 @@ check_variable_usage(bool novar, sym_t * |
2931 | if (sym->s_used && !xsym->s_used) { | | 2931 | if (sym->s_used && !xsym->s_used) { |
2932 | xsym->s_used = true; | | 2932 | xsym->s_used = true; |
2933 | xsym->s_use_pos = sym->s_use_pos; | | 2933 | xsym->s_use_pos = sym->s_use_pos; |
2934 | } | | 2934 | } |
2935 | if (sym->s_set && !xsym->s_set) { | | 2935 | if (sym->s_set && !xsym->s_set) { |
2936 | xsym->s_set = true; | | 2936 | xsym->s_set = true; |
2937 | xsym->s_set_pos = sym->s_set_pos; | | 2937 | xsym->s_set_pos = sym->s_set_pos; |
2938 | } | | 2938 | } |
2939 | } | | 2939 | } |
2940 | } | | 2940 | } |
2941 | } | | 2941 | } |
2942 | | | 2942 | |
2943 | static void | | 2943 | static void |
2944 | check_label_usage(sym_t *lab) | | 2944 | check_label_usage(const sym_t *lab) |
2945 | { | | 2945 | { |
2946 | | | 2946 | |
2947 | lint_assert(block_level == 1); | | 2947 | lint_assert(block_level == 1); |
2948 | lint_assert(lab->s_block_level == 1); | | 2948 | lint_assert(lab->s_block_level == 1); |
2949 | | | 2949 | |
2950 | if (funcsym == NULL) | | 2950 | if (funcsym == NULL) |
2951 | /* syntax error '%s' */ | | 2951 | /* syntax error '%s' */ |
2952 | error(249, "labels are only valid inside a function"); | | 2952 | error(249, "labels are only valid inside a function"); |
2953 | else if (lab->s_set && !lab->s_used) | | 2953 | else if (lab->s_set && !lab->s_used) |
2954 | /* label '%s' unused in function '%s' */ | | 2954 | /* label '%s' unused in function '%s' */ |
2955 | warning_at(232, &lab->s_set_pos, lab->s_name, funcsym->s_name); | | 2955 | warning_at(232, &lab->s_set_pos, lab->s_name, funcsym->s_name); |
2956 | else if (!lab->s_set) | | 2956 | else if (!lab->s_set) |
2957 | /* undefined label '%s' */ | | 2957 | /* undefined label '%s' */ |
2958 | warning_at(23, &lab->s_use_pos, lab->s_name); | | 2958 | warning_at(23, &lab->s_use_pos, lab->s_name); |
2959 | } | | 2959 | } |
2960 | | | 2960 | |
2961 | static void | | 2961 | static void |
2962 | check_tag_usage(sym_t *sym) | | 2962 | check_tag_usage(const sym_t *sym) |
2963 | { | | 2963 | { |
2964 | | | 2964 | |
2965 | if (!is_incomplete(sym->s_type)) | | 2965 | if (!is_incomplete(sym->s_type)) |
2966 | return; | | 2966 | return; |
2967 | | | 2967 | |
2968 | /* always complain about incomplete tags declared inside blocks */ | | 2968 | /* always complain about incomplete tags declared inside blocks */ |
2969 | if (zflag || dcs->d_kind != DLK_EXTERN) | | 2969 | if (zflag || dcs->d_kind != DLK_EXTERN) |
2970 | return; | | 2970 | return; |
2971 | | | 2971 | |
2972 | switch (sym->s_type->t_tspec) { | | 2972 | switch (sym->s_type->t_tspec) { |
2973 | case STRUCT: | | 2973 | case STRUCT: |
2974 | /* struct '%s' never defined */ | | 2974 | /* struct '%s' never defined */ |
2975 | warning_at(233, &sym->s_def_pos, sym->s_name); | | 2975 | warning_at(233, &sym->s_def_pos, sym->s_name); |
| @@ -2978,27 +2978,27 @@ check_tag_usage(sym_t *sym) | | | @@ -2978,27 +2978,27 @@ check_tag_usage(sym_t *sym) |
2978 | /* union '%s' never defined */ | | 2978 | /* union '%s' never defined */ |
2979 | warning_at(234, &sym->s_def_pos, sym->s_name); | | 2979 | warning_at(234, &sym->s_def_pos, sym->s_name); |
2980 | break; | | 2980 | break; |
2981 | default: | | 2981 | default: |
2982 | lint_assert(sym->s_type->t_tspec == ENUM); | | 2982 | lint_assert(sym->s_type->t_tspec == ENUM); |
2983 | /* enum '%s' never defined */ | | 2983 | /* enum '%s' never defined */ |
2984 | warning_at(235, &sym->s_def_pos, sym->s_name); | | 2984 | warning_at(235, &sym->s_def_pos, sym->s_name); |
2985 | break; | | 2985 | break; |
2986 | } | | 2986 | } |
2987 | } | | 2987 | } |
2988 | | | 2988 | |
2989 | /* Warns about a variable or a label that is not used or only set. */ | | 2989 | /* Warns about a variable or a label that is not used or only set. */ |
2990 | void | | 2990 | void |
2991 | check_usage_sym(bool novar, sym_t *sym) | | 2991 | check_usage_sym(bool novar, const sym_t *sym) |
2992 | { | | 2992 | { |
2993 | | | 2993 | |
2994 | if (sym->s_block_level == -1) | | 2994 | if (sym->s_block_level == -1) |
2995 | return; | | 2995 | return; |
2996 | | | 2996 | |
2997 | if (sym->s_kind == FVFT && sym->s_arg) | | 2997 | if (sym->s_kind == FVFT && sym->s_arg) |
2998 | check_argument_usage(novar, sym); | | 2998 | check_argument_usage(novar, sym); |
2999 | else if (sym->s_kind == FVFT) | | 2999 | else if (sym->s_kind == FVFT) |
3000 | check_variable_usage(novar, sym); | | 3000 | check_variable_usage(novar, sym); |
3001 | else if (sym->s_kind == FLABEL) | | 3001 | else if (sym->s_kind == FLABEL) |
3002 | check_label_usage(sym); | | 3002 | check_label_usage(sym); |
3003 | else if (sym->s_kind == FTAG) | | 3003 | else if (sym->s_kind == FTAG) |
3004 | check_tag_usage(sym); | | 3004 | check_tag_usage(sym); |