Module Name: src Committed By: rillig Date: Wed Aug 2 21:11:36 UTC 2023
Modified Files: src/tests/usr.bin/xlint/lint1: decl_direct_abstract.c msg_347.c parse_type_name.c src/usr.bin/xlint/lint1: cgram.y decl.c externs1.h Log Message: lint: fix handling of unnamed function parameters To generate a diff of this commit: cvs rdiff -u -r1.9 -r1.10 \ src/tests/usr.bin/xlint/lint1/decl_direct_abstract.c cvs rdiff -u -r1.6 -r1.7 src/tests/usr.bin/xlint/lint1/msg_347.c cvs rdiff -u -r1.10 -r1.11 src/tests/usr.bin/xlint/lint1/parse_type_name.c cvs rdiff -u -r1.468 -r1.469 src/usr.bin/xlint/lint1/cgram.y cvs rdiff -u -r1.374 -r1.375 src/usr.bin/xlint/lint1/decl.c cvs rdiff -u -r1.205 -r1.206 src/usr.bin/xlint/lint1/externs1.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/tests/usr.bin/xlint/lint1/decl_direct_abstract.c diff -u src/tests/usr.bin/xlint/lint1/decl_direct_abstract.c:1.9 src/tests/usr.bin/xlint/lint1/decl_direct_abstract.c:1.10 --- src/tests/usr.bin/xlint/lint1/decl_direct_abstract.c:1.9 Sat Jul 1 20:57:37 2023 +++ src/tests/usr.bin/xlint/lint1/decl_direct_abstract.c Wed Aug 2 21:11:35 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: decl_direct_abstract.c,v 1.9 2023/07/01 20:57:37 rillig Exp $ */ +/* $NetBSD: decl_direct_abstract.c,v 1.10 2023/08/02 21:11:35 rillig Exp $ */ # 3 "decl_direct_abstract.c" /* @@ -42,8 +42,7 @@ function_returning_char(void) // GCC adds a pointer, then says 'char (*)(short int (*)(long int))'. // Clang says 'char (short (*)(long))'. /* cdecl says 'function (pointer to function (long) returning short) returning char' */ - /* FIXME: It's a function type, not only 'short'. */ - /* expect+1: ... 'short' ... */ + /* expect+1: ... 'function(pointer to function(long) returning short) returning char' ... */ x = (char(short (*)(long)))x; /* expect+1: warning: nested 'extern' declaration of 'f1' [352] */ @@ -58,7 +57,7 @@ function_returning_pointer(void) { // GCC says 'error: cast specifies function type'. // Clang says 'char (short *(*)(long))'. - /* expect+1: error: invalid cast from 'struct incompatible' to 'short' [147] */ + /* expect+1: error: invalid cast from 'struct incompatible' to 'function(pointer to function(long) returning pointer to short) returning char' [147] */ x = (char(short *(long)))x; /* expect+1: warning: nested 'extern' declaration of 'f2' [352] */ @@ -67,8 +66,7 @@ function_returning_pointer(void) // GCC adds two pointers, saying 'char (*)(short int * (*)(long int))'. // Clang says 'char (short *(*)(long))' */ /* cdecl says 'syntax error' */ - /* FIXME: lint is wrong, it discards the 'short *' */ - /* expect+1: ... 'pointer to function(long) returning char' ... */ + /* expect+1: ... 'pointer to function(pointer to function(long) returning pointer to short) returning char' ... */ x = f2; } @@ -90,12 +88,11 @@ void int_array_ast_array(int[*][7]); /* expect+1: error: cannot take size/alignment of function type 'function() returning int' [144] */ unsigned long size_unspecified_args = sizeof(int()); -/* FIXME: Must be 'of function', not 'of void'. */ -/* expect+1: error: cannot take size/alignment of void [146] */ +/* expect+1: error: cannot take size/alignment of function type 'function(void) returning int' [144] */ unsigned long size_prototype_void = sizeof(int(void)); -/* TODO: error: cannot take size/alignment of function type 'function(double) returning int' [144] */ +/* expect+1: error: cannot take size/alignment of function type 'function(double) returning int' [144] */ unsigned long size_prototype_unnamed = sizeof(int(double)); -/* TODO: error: cannot take size/alignment of function type 'function(double) returning int' [144] */ +/* expect+1: error: cannot take size/alignment of function type 'function(double) returning int' [144] */ unsigned long size_prototype_named = sizeof(int(double dbl)); /* expect+2: error: cannot take size/alignment of function type 'function() returning int' [144] */ @@ -106,26 +103,28 @@ int size_unspecified_args_return_int[-10 /* expect+1: error: negative array dimension (-1000) [20] */ int size_unspecified_args_return_char[-1000 - (int)sizeof(char())]; -/* FIXME: 'of void' must be 'of function'. */ -/* expect+2: error: cannot take size/alignment of void [146] */ +/* expect+2: error: cannot take size/alignment of function type 'function(void) returning int' [144] */ /* expect+1: error: negative array dimension (-1000) [20] */ int size_prototype_void_return_int[-1000 - (int)sizeof(int(void))]; -/* FIXME: 'of void' must be 'of function'. */ -/* expect+2: error: cannot take size/alignment of void [146] */ +/* expect+2: error: cannot take size/alignment of function type 'function(void) returning double' [144] */ /* expect+1: error: negative array dimension (-1000) [20] */ int size_prototype_void_return_double[-1000 - (int)sizeof(double(void))]; -/* expect+1: error: negative array dimension (-1008) [20] */ +/* expect+2: error: cannot take size/alignment of function type 'function(double) returning int' [144] */ +/* expect+1: error: negative array dimension (-1000) [20] */ int size_prototype_unnamed_return_int[-1000 - (int)sizeof(int(double))]; -/* expect+1: error: negative array dimension (-1008) [20] */ +/* expect+2: error: cannot take size/alignment of function type 'function(double) returning pointer to char' [144] */ +/* expect+1: error: negative array dimension (-1000) [20] */ int size_prototype_unnamed_return_pchar[-1000 - (int)sizeof(char *(double))]; -/* expect+1: error: negative array dimension (-1008) [20] */ +/* expect+2: error: cannot take size/alignment of function type 'function(double) returning int' [144] */ +/* expect+1: error: negative array dimension (-1000) [20] */ int size_prototype_named_return_int[-1000 - (int)sizeof(int(double dbl))]; -/* expect+1: error: negative array dimension (-1008) [20] */ +/* expect+2: error: cannot take size/alignment of function type 'function(double) returning pointer to pointer to pointer to char' [144] */ +/* expect+1: error: negative array dimension (-1000) [20] */ int size_prototype_named_return_pppchar[-1000 - (int)sizeof(char ***(double dbl))]; @@ -158,49 +157,61 @@ int unspecified_args_return_08[-1000 - ( /* expect+1: error: negative array dimension (-1000) [20] */ int unspecified_args_return_32[-1000 - (int)sizeof(a32())]; -/* expect+2: error: cannot take size/alignment of void [146] */ +/* expect+2: error: cannot take size/alignment of function type 'function(void) returning struct typedef a01' [144] */ /* expect+1: error: negative array dimension (-1000) [20] */ int prototype_void_return_01[-1000 - (int)sizeof(a01(void))]; -/* expect+2: error: cannot take size/alignment of void [146] */ +/* expect+2: error: cannot take size/alignment of function type 'function(void) returning struct typedef a04' [144] */ /* expect+1: error: negative array dimension (-1000) [20] */ int prototype_void_return_04[-1000 - (int)sizeof(a04(void))]; -/* expect+2: error: cannot take size/alignment of void [146] */ +/* expect+2: error: cannot take size/alignment of function type 'function(void) returning struct typedef a08' [144] */ /* expect+1: error: negative array dimension (-1000) [20] */ int prototype_void_return_08[-1000 - (int)sizeof(a08(void))]; -/* expect+2: error: cannot take size/alignment of void [146] */ +/* expect+2: error: cannot take size/alignment of function type 'function(void) returning struct typedef a32' [144] */ /* expect+1: error: negative array dimension (-1000) [20] */ int prototype_void_return_32[-1000 - (int)sizeof(a32(void))]; -/* expect+1: error: negative array dimension (-1001) [20] */ +/* expect+2: error: cannot take size/alignment of function type 'function(struct typedef a01) returning struct typedef a32' [144] */ +/* expect+1: error: negative array dimension (-1000) [20] */ int prototype_unnamed_01_return_32[-1000 - (int)sizeof(a32(a01))]; -/* expect+1: error: negative array dimension (-1004) [20] */ +/* expect+2: error: cannot take size/alignment of function type 'function(struct typedef a04) returning struct typedef a32' [144] */ +/* expect+1: error: negative array dimension (-1000) [20] */ int prototype_unnamed_04_return_32[-1000 - (int)sizeof(a32(a04))]; -/* expect+1: error: negative array dimension (-1008) [20] */ +/* expect+2: error: cannot take size/alignment of function type 'function(struct typedef a08) returning struct typedef a32' [144] */ +/* expect+1: error: negative array dimension (-1000) [20] */ int prototype_unnamed_08_return_32[-1000 - (int)sizeof(a32(a08))]; /* expect+2: error: cannot take size/alignment of function type 'function(struct typedef a32) returning struct typedef a32' [144] */ /* expect+1: error: negative array dimension (-1000) [20] */ int prototype_unnamed_32_return_32[-1000 - (int)sizeof(a32(a32))]; -/* expect+1: error: negative array dimension (-1032) [20] */ +/* expect+2: error: cannot take size/alignment of function type 'function(struct typedef a32) returning struct typedef a01' [144] */ +/* expect+1: error: negative array dimension (-1000) [20] */ int prototype_unnamed_32_return_01[-1000 - (int)sizeof(a01(a32))]; -/* expect+1: error: negative array dimension (-1032) [20] */ +/* expect+2: error: cannot take size/alignment of function type 'function(struct typedef a32) returning struct typedef a04' [144] */ +/* expect+1: error: negative array dimension (-1000) [20] */ int prototype_unnamed_32_return_04[-1000 - (int)sizeof(a04(a32))]; -/* expect+1: error: negative array dimension (-1032) [20] */ +/* expect+2: error: cannot take size/alignment of function type 'function(struct typedef a32) returning struct typedef a08' [144] */ +/* expect+1: error: negative array dimension (-1000) [20] */ int prototype_unnamed_32_return_08[-1000 - (int)sizeof(a08(a32))]; -/* expect+1: error: negative array dimension (-1001) [20] */ +/* expect+2: error: cannot take size/alignment of function type 'function(struct typedef a01) returning struct typedef a32' [144] */ +/* expect+1: error: negative array dimension (-1000) [20] */ int prototype_named_01_return_32[-1000 - (int)sizeof(a32(a01 arg))]; -/* expect+1: error: negative array dimension (-1004) [20] */ +/* expect+2: error: cannot take size/alignment of function type 'function(struct typedef a04) returning struct typedef a32' [144] */ +/* expect+1: error: negative array dimension (-1000) [20] */ int prototype_named_04_return_32[-1000 - (int)sizeof(a32(a04 arg))]; -/* expect+1: error: negative array dimension (-1008) [20] */ +/* expect+2: error: cannot take size/alignment of function type 'function(struct typedef a08) returning struct typedef a32' [144] */ +/* expect+1: error: negative array dimension (-1000) [20] */ int prototype_named_08_return_32[-1000 - (int)sizeof(a32(a08 arg))]; /* expect+2: error: cannot take size/alignment of function type 'function(struct typedef a32) returning struct typedef a32' [144] */ /* expect+1: error: negative array dimension (-1000) [20] */ int prototype_named_32_return_32[-1000 - (int)sizeof(a32(a32 arg))]; -/* expect+1: error: negative array dimension (-1032) [20] */ +/* expect+2: error: cannot take size/alignment of function type 'function(struct typedef a32) returning struct typedef a01' [144] */ +/* expect+1: error: negative array dimension (-1000) [20] */ int prototype_named_32_return_01[-1000 - (int)sizeof(a01(a32 arg))]; -/* expect+1: error: negative array dimension (-1032) [20] */ +/* expect+2: error: cannot take size/alignment of function type 'function(struct typedef a32) returning struct typedef a04' [144] */ +/* expect+1: error: negative array dimension (-1000) [20] */ int prototype_named_32_return_04[-1000 - (int)sizeof(a04(a32 arg))]; -/* expect+1: error: negative array dimension (-1032) [20] */ +/* expect+2: error: cannot take size/alignment of function type 'function(struct typedef a32) returning struct typedef a08' [144] */ +/* expect+1: error: negative array dimension (-1000) [20] */ int prototype_named_32_return_08[-1000 - (int)sizeof(a08(a32 arg))]; Index: src/tests/usr.bin/xlint/lint1/msg_347.c diff -u src/tests/usr.bin/xlint/lint1/msg_347.c:1.6 src/tests/usr.bin/xlint/lint1/msg_347.c:1.7 --- src/tests/usr.bin/xlint/lint1/msg_347.c:1.6 Wed Aug 2 18:51:25 2023 +++ src/tests/usr.bin/xlint/lint1/msg_347.c Wed Aug 2 21:11:35 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: msg_347.c,v 1.6 2023/08/02 18:51:25 rillig Exp $ */ +/* $NetBSD: msg_347.c,v 1.7 2023/08/02 21:11:35 rillig Exp $ */ # 3 "msg_347.c" // Test for message: redeclaration of '%s' with type '%s', expected '%s' [347] @@ -11,35 +11,17 @@ */ /* - * As of 2021-09-12, lint complains about mismatched types. - * GCC and Clang accept this. - * - * Above: - * function(pointer to void, int) returning void - * - * Below: function( - * pointer to void, - * pointer to function(pointer to void, int) returning pointer to double - * ) returning void + * Before 2023-08-02, lint did not interpret unnamed function parameters with + * complicated types correctly. The named counterparts were no problem, though. */ -/* FIXME: the type of the second parameter is not 'int' */ -/* expect+1: previous declaration of 'function_parameter' [260] */ + void function_parameter(void *, double *(void *, int)); -/* expect+1: error: redeclaration of 'function_parameter' with type 'function(pointer to void, pointer to function(pointer to void, int) returning pointer to double) returning void', expected 'function(pointer to void, int) returning void' [347] */ -void function_parameter(void *fs, double *func(void *, int)); +void function_parameter(void *fs, double *fn(void *, int)); /* expect+1: warning: struct 'last_arg' never defined [233] */ struct last_arg; -/* - * FIXME: The following error is completely wrong. - * There is no parameter that has 'struct last_arg', there are only pointers - * to it. - */ -/* expect+2: error: '<unnamed>' has incomplete type 'incomplete struct last_arg' [31] */ -/* expect+1: previous declaration of 'last_arg_struct' [260] */ void last_arg_struct(double, double *(struct last_arg *)); -/* expect+1: error: redeclaration of 'last_arg_struct' with type 'function(double, pointer to function(pointer to incomplete struct last_arg) returning pointer to double) returning void', expected 'function(double, incomplete struct last_arg) returning void' [347] */ void last_arg_struct(double d, double *fn(struct last_arg *)); @@ -47,18 +29,11 @@ struct last_param { int member; }; -/* expect+1: previous declaration of 'last_param' [260] */ void last_param(double, double *(struct last_param)); - -/* - * FIXME: The type of last_param is completely wrong. The second parameter - * must be a function, not a struct. - */ -/* expect+1: error: cannot initialize 'double' from 'pointer to function(double, struct last_param) returning void' [185] */ -double reveal_type_of_last_param_abstract = last_param; - -/* expect+1: error: redeclaration of 'last_param' with type 'function(double, pointer to function(struct last_param) returning pointer to double) returning void', expected 'function(double, struct last_param) returning void' [347] */ void last_param(double d, double *fn(struct last_param)); -/* expect+1: error: cannot initialize 'double' from 'pointer to function(double, pointer to function(struct last_param) returning pointer to double) returning void' [185] */ -double reveal_type_of_last_param_named = last_param; + +/* expect+1: previous declaration of 'mismatch' [260] */ +void mismatch(double, double *(struct last_param)); +/* expect+1: error: redeclaration of 'mismatch' with type 'function(double, pointer to function(struct last_param) returning pointer to float) returning void', expected 'function(double, pointer to function(struct last_param) returning pointer to double) returning void' [347] */ +void mismatch(double d, float *fn(struct last_param)); Index: src/tests/usr.bin/xlint/lint1/parse_type_name.c diff -u src/tests/usr.bin/xlint/lint1/parse_type_name.c:1.10 src/tests/usr.bin/xlint/lint1/parse_type_name.c:1.11 --- src/tests/usr.bin/xlint/lint1/parse_type_name.c:1.10 Tue Mar 28 14:44:35 2023 +++ src/tests/usr.bin/xlint/lint1/parse_type_name.c Wed Aug 2 21:11:35 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: parse_type_name.c,v 1.10 2023/03/28 14:44:35 rillig Exp $ */ +/* $NetBSD: parse_type_name.c,v 1.11 2023/08/02 21:11:35 rillig Exp $ */ # 3 "parse_type_name.c" /* @@ -81,8 +81,11 @@ cover_direct_abstract_declarator(void) sink(sizeof(int[3][5][8])); /* cover 'abstract_decl_param_list asm_or_symbolrename_opt' */ + /* expect+1: error: cannot take size/alignment of function type 'function(double) returning int' [144] */ sink(sizeof(int(double))); + /* expect+1: error: cannot take size/alignment of function type 'function(double) returning int' [144] */ sink(sizeof(int(double) __asm("anything"))); + /* expect+1: error: cannot take size/alignment of function type 'function(double) returning int' [144] */ sink(sizeof(int(double) __symbolrename(alias))); /* cover 'direct_abstract_declarator abstract_decl_param_list asm_or_symbolrename_opt' */ Index: src/usr.bin/xlint/lint1/cgram.y diff -u src/usr.bin/xlint/lint1/cgram.y:1.468 src/usr.bin/xlint/lint1/cgram.y:1.469 --- src/usr.bin/xlint/lint1/cgram.y:1.468 Wed Aug 2 18:51:25 2023 +++ src/usr.bin/xlint/lint1/cgram.y Wed Aug 2 21:11:35 2023 @@ -1,5 +1,5 @@ %{ -/* $NetBSD: cgram.y,v 1.468 2023/08/02 18:51:25 rillig Exp $ */ +/* $NetBSD: cgram.y,v 1.469 2023/08/02 21:11:35 rillig Exp $ */ /* * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. @@ -35,7 +35,7 @@ #include <sys/cdefs.h> #if defined(__RCSID) -__RCSID("$NetBSD: cgram.y,v 1.468 2023/08/02 18:51:25 rillig Exp $"); +__RCSID("$NetBSD: cgram.y,v 1.469 2023/08/02 21:11:35 rillig Exp $"); #endif #include <limits.h> @@ -1529,7 +1529,8 @@ direct_abstract_declarator: $$ = add_array($1, $3.has_dim, $3.dim); } | abstract_decl_param_list asm_or_symbolrename_opt { - $$ = add_function(symbolrename(abstract_name(), $2), $1); + sym_t *name = abstract_enclosing_name(); + $$ = add_function(symbolrename(name, $2), $1); end_declaration_level(); block_level--; } Index: src/usr.bin/xlint/lint1/decl.c diff -u src/usr.bin/xlint/lint1/decl.c:1.374 src/usr.bin/xlint/lint1/decl.c:1.375 --- src/usr.bin/xlint/lint1/decl.c:1.374 Wed Aug 2 18:51:25 2023 +++ src/usr.bin/xlint/lint1/decl.c Wed Aug 2 21:11:35 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: decl.c,v 1.374 2023/08/02 18:51:25 rillig Exp $ */ +/* $NetBSD: decl.c,v 1.375 2023/08/02 21:11:35 rillig Exp $ */ /* * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. @@ -38,7 +38,7 @@ #include <sys/cdefs.h> #if defined(__RCSID) -__RCSID("$NetBSD: decl.c,v 1.374 2023/08/02 18:51:25 rillig Exp $"); +__RCSID("$NetBSD: decl.c,v 1.375 2023/08/02 21:11:35 rillig Exp $"); #endif #include <sys/param.h> @@ -2767,8 +2767,8 @@ declare_local(sym_t *dsym, bool has_init } /* Create a symbol for an abstract declaration. */ -sym_t * -abstract_name(void) +static sym_t * +abstract_name_level(bool enclosing) { lint_assert(dcs->d_kind == DLK_ABSTRACT @@ -2786,12 +2786,7 @@ abstract_name(void) * type will be updated later, adding pointers, arrays and functions * as necessary. */ - /* - * XXX: This is not the correct type. For example in msg_347, it is - * the type of the last prototype parameter, but it should rather be - * the return type of the function. - */ - sym->s_type = dcs->d_type; + sym->s_type = (enclosing ? dcs->d_enclosing : dcs)->d_type; dcs->d_redeclared_symbol = NULL; debug_printf("%s: ", __func__); @@ -2799,6 +2794,18 @@ abstract_name(void) return sym; } +sym_t * +abstract_name(void) +{ + return abstract_name_level(false); +} + +sym_t * +abstract_enclosing_name(void) +{ + return abstract_name_level(true); +} + /* Removes anything which has nothing to do on global level. */ void global_clean_up(void) Index: src/usr.bin/xlint/lint1/externs1.h diff -u src/usr.bin/xlint/lint1/externs1.h:1.205 src/usr.bin/xlint/lint1/externs1.h:1.206 --- src/usr.bin/xlint/lint1/externs1.h:1.205 Wed Aug 2 18:51:25 2023 +++ src/usr.bin/xlint/lint1/externs1.h Wed Aug 2 21:11:35 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: externs1.h,v 1.205 2023/08/02 18:51:25 rillig Exp $ */ +/* $NetBSD: externs1.h,v 1.206 2023/08/02 21:11:35 rillig Exp $ */ /* * Copyright (c) 1994, 1995 Jochen Pohl @@ -254,6 +254,7 @@ void check_func_old_style_parameters(voi void declare_local(sym_t *, bool); sym_t *abstract_name(void); +sym_t *abstract_enclosing_name(void); void global_clean_up(void); sym_t *declare_abstract_type(sym_t *); void check_size(const sym_t *);