svn commit: r246880 - in head: lib/libsm libexec/mail.local libexec/smrsh share/mk usr.bin/vacation usr.sbin/sendmail

Bruce Evans brde at optusnet.com.au
Tue Apr 16 11:50:53 UTC 2013


On Tue, 16 Apr 2013, Dimitry Andric wrote:

> On 2013-04-16 06:19, Γιώργος Κεραμίδας wrote:
>> ...
>> The warnings that usersmtp.c still triggers when -DSASL is used are:
>> 
>> : cc -O2 -pipe  -I/usr/src/usr.sbin/sendmail/../../contrib/sendmail/src 
>> -I/usr/src/usr.sbin/sendmail/../../contrib/sendmail/include -I. -DNEWDB 
>> -DNIS -DTCPWRAPPERS -DMAP_REGEX -DDNSMAP -DNETINET6 -DSTARTTLS -D_FFR_TLS_1 
>> -I/usr/local/include -DSASL=20126 -std=gnu99 -Qunused-arguments 
>> -fstack-protector -Wsystem-headers -Wno-pointer-sign -Wno-empty-body 
>> -Wno-string-plus-int -Wno-tautological-compare -Wno-unused-value 
>> -Wno-parentheses-equality -Wno-unused-function -Wno-conversion -Wno-switch 
>> -Wno-switch-enum -Wno-knr-promoted-parameter -Wno-parentheses -c 
>> /usr/src/usr.sbin/sendmail/../../contrib/sendmail/src/usersmtp.c
>> : /usr/src/usr.sbin/sendmail/../../contrib/sendmail/src/usersmtp.c:1797:50: 
>> warning: incompatible pointer types passing 'void ()' to parameter of type 
>> 'void (*)(char *, bool, MAILER *, struct
>> :       mailer_con_info *, ENVELOPE *)' [-Wincompatible-pointer-types]
>> :         smtpresult = reply(m, mci, e, TimeOuts.to_auth, getsasldata, 
>> NULL,
>> :                                                         ^~~~~~~~~~~
>
> 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.

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 <stdbool.h>
@ 
@ 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 <stdbool.h>
@ 
@ 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


More information about the svn-src-all mailing list