Description of problem: Libvirt had a bug for 11 months that would have been detected had we been using gcc's -Wlogical-op (warn on suspicious boolean operators that are always true or always false). When we turned this option on, the only remaining failure came from curl's installed headers. https://www.redhat.com/archives/libvir-list/2010-July/msg00520.html Version-Release number of selected component (if applicable): libcurl-devel-7.20.1-3.fc13.x86_64 gcc-4.4.4-10.fc13.x86_64 How reproducible: Always Steps to Reproduce: 1. $ cat > foo.c <<\EOF #include <curl/curl.h> int main(int argc, char **argv) { CURL *h = NULL; char *url = ""; if (argc > 1) curl_easy_setopt(h, CURLOPT_URL, url); return 0; } EOF 2. $ gcc -Wall -Wlogical-op -o foo.o -c foo.c Actual results: Lots of spurious warnings, because curl_easy_setopt expands to a macro that uses lots of && under the hood in a way that bothers gcc: foo.c: In function ‘main’: foo.c:7: warning: logical ‘&&’ with non-zero constant will always evaluate as true foo.c:7: warning: logical ‘&&’ with non-zero constant will always evaluate as true foo.c:7: warning: logical ‘&&’ with non-zero constant will always evaluate as true foo.c:7: warning: logical ‘&&’ with non-zero constant will always evaluate as true foo.c:7: warning: logical ‘&&’ with non-zero constant will always evaluate as true Expected results: Compile without warnings. It's nice that curl's curl/typecheck-gcc.h adds some gcc-specific checks to aid in programming with more type safety, but it would be even nicer if it did it in a manner that would not trigger warnings during the compilation of third-party packages. The macros are pretty hairy, so I'm not sure exactly which part of the macro actually caused the warning, or how easy it would be to refactor the code to avoid it. Additional info: It may also be worth cloning or reassigning this as a gcc bug, for warning about expressions buried so deeply within a macro, since there is no && directly visible in my sample foo.c.
I'm not seeing the error in the headers when I read them, but I must be missing something. Which is the non-zero constant that "will always evaluate as true" ?
I'm not sure - I suppose taking the preprocessed source and adding strategic line breaks will help with that effort, but I have not tried that yet. Do you need me to tackle that approach to aid in further reducing the initial report to a simpler test case?
I would certainly appreciate the help, yes!
Created attachment 436274 [details] a reproducer Let's take this as the first step. I'll try to reduce it further...
Created attachment 436283 [details] a smaller example
It seems like a transient problem in gcc, I am not able to repeat it with gcc 4.5+.
The following change seems relevant: http://gcc.gnu.org/viewcvs/trunk/gcc/c-family/c-common.c?r1=147639&r2=147708
Oops, I meant this one: http://gcc.gnu.org/viewcvs/trunk/gcc/c-family/c-common.c?r2=147639&r1=147596
Nope, it was this one: http://gcc.gnu.org/viewcvs/trunk/gcc/c-family/c-common.c?r1=146153&r2=146344 upstream bug 32061: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32061
Created attachment 436727 [details] patch taken from upstream bug 32061 I rebuilt Fedora gcc with the patch applied and the warnings are gone.
switching component to gcc
This is a user visible change that IMNSHO shouldn't be backported (not only because it changes the meaning of the warning and enables it by default for -W when it hasn't been enabled before). -Wlogical-op isn't on by default, either don't use those && 1's, or just live with the warnings.
so where exactly are those "&& 1"s?
Considering our example, there are five of them: 1. _curl_is_long_option(_curl_opt) && ... 2. ... && !_curl_is_off_t(value) 3. ... && !_curl_is_write_cb(value) 4. ... && !_curl_is_conv_cb(value) 5. ... && !_curl_is_arr((value), struct curl_slist)
If gcc won't fix this, then let's reopen it and reassign it curl. By the way, I think there's an easy way to shut gcc up in this case. Instead of: if ((0 < (_curl_opt) && (_curl_opt) < 10000) && !(__builtin_types_compatible_p(__typeof__(url), long))) foo(); you can use: if ((0 < (_curl_opt) && (_curl_opt) < 10000)) if (!(__builtin_types_compatible_p(__typeof__(url), long))) foo(); That is, break up the code to use two if statements instead of an && within a single if statement.
It would be at 5 places in our example, however at about 28 places in total. Introducing of 28 new 'if' statements sounds like a big cost to work around a transient problem in a newly introduced gcc option, that isn't widely used yet anyway. What about making sure that -Wlogical-op and -Werror aren't used together unless gcc version is 4.5+? Are you sure that <curl/curl.h> is the only code affected by the bug?
Discussed with Daniel off-list, and as he likes the workaround, written a patch and raised at upstream mailing list: http://article.gmane.org/gmane.comp.web.curl.library/28936
pushed upstream: http://github.com/bagder/curl/commit/a6e088e
curl-7.21.0-4.fc14 has been submitted as an update for Fedora 14. http://admin.fedoraproject.org/updates/curl-7.21.0-4.fc14
curl-7.20.1-4.fc13 has been submitted as an update for Fedora 13. http://admin.fedoraproject.org/updates/curl-7.20.1-4.fc13
curl-7.20.1-4.fc13 has been pushed to the Fedora 13 testing repository. If problems still persist, please make note of it in this bug report. If you want to test the update, you can install it with su -c 'yum --enablerepo=updates-testing update curl'. You can provide feedback for this update here: http://admin.fedoraproject.org/updates/curl-7.20.1-4.fc13
curl-7.20.1-4.fc13 has been pushed to the Fedora 13 stable repository. If problems still persist, please make note of it in this bug report.
curl-7.21.0-4.fc14 has been pushed to the Fedora 14 stable repository. If problems still persist, please make note of it in this bug report.