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 *);

Reply via email to