From owner-svn-src-all@FreeBSD.ORG Tue Apr 16 13:14:19 2013 Return-Path: Delivered-To: svn-src-all@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id 2971FCD9; Tue, 16 Apr 2013 13:14:19 +0000 (UTC) (envelope-from keramida@ceid.upatras.gr) Received: from tux-cave.hellug.gr (tux-cave.hellug.gr [195.134.99.74]) by mx1.freebsd.org (Postfix) with ESMTP id 9A33FA18; Tue, 16 Apr 2013 13:14:18 +0000 (UTC) X-Spam-Status: No X-Hellug-MailScanner-From: keramida@ceid.upatras.gr X-Hellug-MailScanner-SpamCheck: not spam, SpamAssassin (not cached, score=-2.9, required 5, autolearn=not spam, ALL_TRUSTED -1.00, BAYES_00 -1.90) X-Hellug-MailScanner: Found to be clean X-Hellug-MailScanner-ID: r3GDE4Lj013142 Received: from saturn.laptop (217-162-217-29.dynamic.hispeed.ch [217.162.217.29]) (authenticated bits=0) by tux-cave.hellug.gr (8.14.3/8.14.3/Debian-9.4) with ESMTP id r3GDE4Lj013142 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT); Tue, 16 Apr 2013 16:14:13 +0300 Received: from saturn.laptop (localhost [127.0.0.1]) by saturn.laptop (8.14.4/8.14.4/Debian-2.1ubuntu1) with ESMTP id r3GDDvK3027102 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT); Tue, 16 Apr 2013 15:13:57 +0200 Received: (from keramida@localhost) by saturn.laptop (8.14.4/8.14.4/Submit) id r3GDDtne027095; Tue, 16 Apr 2013 15:13:55 +0200 X-Authentication-Warning: saturn.laptop: keramida set sender to keramida@ceid.upatras.gr using -f From: keramida@ceid.upatras.gr (Giorgos Keramidas) To: Bruce Evans Subject: Re: svn commit: r246880 - in head: lib/libsm libexec/mail.local libexec/smrsh share/mk usr.bin/vacation usr.sbin/sendmail References: <201302162017.r1GKHVdY022667@svn.freebsd.org> <87a9ozayzk.fsf@saturn.laptop> <516D13C5.70900@FreeBSD.org> <20130416205349.W1783@besplex.bde.org> Date: Tue, 16 Apr 2013 15:13:55 +0200 In-Reply-To: <20130416205349.W1783@besplex.bde.org> (Bruce Evans's message of "Tue, 16 Apr 2013 21:28:36 +1000 (EST)") Message-ID: <87zjwy62jw.fsf@saturn.laptop> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain Cc: svn-src-head@FreeBSD.org, Gregory Shapiro , src-committers@FreeBSD.org, Dimitry Andric , svn-src-all@FreeBSD.org X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 16 Apr 2013 13:14:19 -0000 On Tue, 16 Apr 2013 21:28:36 +1000 (EST), Bruce Evans wrote: >On Tue, 16 Apr 2013, Dimitry Andric wrote: >> Have you tried the patch I posted here? >> >> http://lists.freebsd.org/pipermail/freebsd-current/2013-March/040634.html >> >> If people feel this is the right approach, I am happy to commit it. If >> people prefer to just shut up warnings, I am happy with that too. Hi Dimitry, I haven't but I will right now. Thanks for pointing me to it :) Also Bruce, thanks for the very detailed explanation. I admit I was a bit confused when a similar small test program I wrote failed to trigger the warning in clang: #include void foo(int code, const char *text); void foo(code, text) int code; const char *text; { printf("error %d: %s", code, text); } int main(void) { foo(0, "unknown error"); return 0; } But now -- having read all the details you wrote -- using stdbool.h and changing the type of 'code' to bool, *does* trigger the promotion and the warning: #include #include void foo(bool code, const char *text); void foo(code, text) bool code; const char *text; { if (code != false) printf("error: %s", text); } int main(void) { foo(false, "unknown error"); return 0; } % cc -O2 -pipe -std=gnu99 -Qunused-arguments -fstack-protector -c proto.c proto.c:8:10: warning: promoted type 'int' of K&R function parameter is not compatible with the parameter type 'bool' declared in a previous prototype [-Wknr-promoted-parameter] bool code; ^ proto.c:4:15: note: previous declaration is here void foo(bool code, const char *text); ^ 1 warning generated. > stdbool is certainly incompatible with simple use of __P(()), but why does > the error message say that the function type is 'void ()', and why doesn't > it say that the prototype doesn't match the function? The function is > declared as: > > @ static void getsasldata __P((char *, bool, MAILER *, MCI *, ENVELOPE *)); > > This says that the function type is the same as the parameter type. > > @ static void > @ getsasldata(line, firstline, m, mci, e) > @ char *line; > @ bool firstline; > @ MAILER *m; > @ register MCI *mci; > @ ENVELOPE *e; > @ { > > This says that the function type is different from what the function's > prototype is, at least if the bool is smaller than int or otherwise > magic, which it is on at least amd64. > > clang prints a good error message in the following simplified example: > > @ #include > @ @ void foo(bool first); > @ @ void > @ foo(first) > @ bool first; > @ { > @ } > > @ z.c:7:7: warning: promoted type 'int' of K&R function parameter is not compatible with the parameter type 'bool' declared in a previous prototype [-Wknr-promoted-parameter] > @ bool first; > @ ^ > @ z.c:3:15: note: previous declaration is here > @ void foo(bool first); > @ ^ > @ 1 warning generated. > > This happens with plain cc -c. > > gcc of course turns the undefined behaviour from this into a portability > problem by accepting the bad code. It takes gcc -pedantic to get a warning. > > The correct prototype on amd64 is 'void foo(int first);'. This is MD. > Unfortunately, the correct way to declare this is unsupported AFAIK. It > is 'void foo(__promoteof(bool) first);'. __P(()) is really hard to use, > since to use it you first have to modify compilers to support > __promoteof(), then use it on the type of all integer args whose type is > not int or larger, or do this using MD ifdefs. > > Extending the example a little gives the answer to my question: > > @ #include > @ @ typedef void vb(bool first); > @ @ vb foo; > @ void bar(vb *p); > @ @ void > @ foo(first) > @ bool first; > @ { > @ bar(foo); > @ } > > @ z.c:10:7: warning: promoted type 'int' of K&R function parameter is not compatible with the parameter type 'bool' declared in a previous prototype [-Wknr-promoted-parameter] > @ bool first; > @ ^ > @ z.c:5:4: note: previous declaration is here > @ vb foo; > @ ^ > @ z.c:12:6: warning: incompatible pointer types passing 'void ()' to parameter of type 'vb *' (aka 'void (*)(bool)') [-Wincompatible-pointer-types] > @ bar(foo); > @ ^~~ > @ z.c:6:14: note: passing argument to parameter 'p' here > @ void bar(vb *p); > @ ^ > @ 2 warnings generated. > > Apparently clang ignores the mismatched prototype after printing a warning > about it, and also throws away the type info that it learns by compiling > the K&R function, so it is left with only 'void ()' for the type. Then > the warnings for some reason emphasize the secondary warnings from this. > > The first warning should be an error. It is only a warning for gcc -pedantic > too. > > Bruce -- Giorgos Keramidas; gkeramidas@gmail.com