From c3be846008a1ae6aba05d3c4f83b8787e41dd239 Mon Sep 17 00:00:00 2001 From: rillig Date: Sun, 12 Sep 2021 17:30:53 +0000 Subject: [PATCH] lint: track down wrong function type in abstract type --- tests/usr.bin/xlint/lint1/msg_347.c | 16 +++++++++++++++- tests/usr.bin/xlint/lint1/msg_347.exp | 4 ++++ usr.bin/xlint/lint1/decl.c | 14 +++++++++++--- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/tests/usr.bin/xlint/lint1/msg_347.c b/tests/usr.bin/xlint/lint1/msg_347.c index 1980efe667a3..1619096c88ab 100644 --- a/tests/usr.bin/xlint/lint1/msg_347.c +++ b/tests/usr.bin/xlint/lint1/msg_347.c @@ -1,4 +1,4 @@ -/* $NetBSD: msg_347.c,v 1.1 2021/09/12 16:28:45 rillig Exp $ */ +/* $NetBSD: msg_347.c,v 1.2 2021/09/12 17:30:53 rillig Exp $ */ # 3 "msg_347.c" // Test for message: redeclaration of '%s' with type '%s', expected '%s' [347] @@ -27,3 +27,17 @@ 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)); + + +/* expect+1: warning: struct last_arg never defined [233] */ +struct last_arg; +/* + * FIXME: The following error is completely wrong. + * There is no argument that has 'struct last_arg', there are only pointers + * to it. + */ +/* expect+2: error: '' 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 *)); diff --git a/tests/usr.bin/xlint/lint1/msg_347.exp b/tests/usr.bin/xlint/lint1/msg_347.exp index 03fee641e07a..b6d5fd7f1f30 100644 --- a/tests/usr.bin/xlint/lint1/msg_347.exp +++ b/tests/usr.bin/xlint/lint1/msg_347.exp @@ -1,2 +1,6 @@ msg_347.c(29): 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] msg_347.c(27): previous declaration of function_parameter [260] +msg_347.c(41): error: '' has incomplete type 'incomplete struct last_arg' [31] +msg_347.c(43): 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] +msg_347.c(41): previous declaration of last_arg_struct [260] +msg_347.c(33): warning: struct last_arg never defined [233] diff --git a/usr.bin/xlint/lint1/decl.c b/usr.bin/xlint/lint1/decl.c index 3ac7eb02d37b..9405fdbe3871 100644 --- a/usr.bin/xlint/lint1/decl.c +++ b/usr.bin/xlint/lint1/decl.c @@ -1,4 +1,4 @@ -/* $NetBSD: decl.c,v 1.236 2021/09/12 16:28:45 rillig Exp $ */ +/* $NetBSD: decl.c,v 1.237 2021/09/12 17:30:53 rillig Exp $ */ /* * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. @@ -38,7 +38,7 @@ #include #if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: decl.c,v 1.236 2021/09/12 16:28:45 rillig Exp $"); +__RCSID("$NetBSD: decl.c,v 1.237 2021/09/12 17:30:53 rillig Exp $"); #endif #include @@ -1398,11 +1398,19 @@ add_function(sym_t *decl, sym_t *args) dcs->d_next->d_func_args = args; } + /* + * XXX: What is this code doing on a semantic level, and why? + * Returning decl leads to the wrong function types in msg_347. + */ tpp = &decl->s_type; while (*tpp != NULL && *tpp != dcs->d_next->d_type) + /* + * XXX: accessing INT->t_subt feels strange, even though it + * may even be guaranteed to be NULL. + */ tpp = &(*tpp)->t_subt; if (*tpp == NULL) - return decl; + return decl; /* see msg_347 */ *tpp = tp = getblk(sizeof(*tp)); tp->t_tspec = FUNC;