Page MenuHomePhabricator

[Sema] -Wzero-as-null-pointer-constant: don't warn for system macros other than NULL.
ClosedPublic

Authored by lebedev.ri on Oct 16 2017, 7:20 AM.

Details

Summary

The warning was initially introduced in D32914 by @thakis,
and the concerns were raised there, and later in rL302247
and PR33771.

I do believe that it makes sense to relax the diagnostic
e.g. in this case, when the expression originates from the
system header, which can not be modified. This prevents
adoption for the diagnostic for codebases which use pthreads
(PTHREAD_MUTEX_INITIALIZER), gtest, etc.

As @malcolm.parsons suggests, it *may* make sense to also
not warn for the template types, but it is not obvious to
me how to do that in here.

Though, it still makes sense to complain about NULL macro.

While there, add more tests.

Diff Detail

Repository
rL LLVM

Event Timeline

lebedev.ri created this revision.Oct 16 2017, 7:20 AM
thakis edited edge metadata.Oct 16 2017, 7:23 AM

As said on the bug, this matches gcc's behavior, and with this you won't see this warning for NULL. I don't think this is better.

As said on the bug, this matches gcc's behavior,

https://bugs.llvm.org/show_bug.cgi?id=33771#c3

and with this you won't see this warning for NULL.

Finally, an argument that can actually be addressed.

I don't think this is better.

Address @thakis review notes: do make sure that we still warn on NULL.
Any other special macros/cases?

lebedev.ri retitled this revision from [Sema] -Wzero-as-null-pointer-constant: don't warn for system macros. to [Sema] -Wzero-as-null-pointer-constant: don't warn for system macros other than NULL..
lebedev.ri edited the summary of this revision. (Show Details)
lebedev.ri added a reviewer: aaron.ballman.

Ping.
Rebased, added release notes note.

Rakete1111 added inline comments.
lib/Sema/Sema.cpp
445 ↗(On Diff #119833)

That comment doesn't really add anything IMO. It just says what the code just below says.

447 ↗(On Diff #119833)

Please use MaybeMacroLoc there too.

lebedev.ri marked an inline comment as done.

Use MaybeMacroLoc variable in the other place too.

lib/Sema/Sema.cpp
445 ↗(On Diff #119833)

I don't disagree. It seems to be the common pattern for the code in this file.
Having both the code and the comment might help convey the idea better.

  • Rebased
  • Handle -Wsystem-headers properly, as per irc disscussion.

It was suggested that findMacroSpelling() might be slow, and isNullPointerConstant() should be used, but i'm not sure any of the NullPointerConstantKind's can replace direct check for NULL specifically...

Can you build some large-ish codebase (say, LLVM) with and without this patch and make sure that this doesn't measurably add to build perf? (With the warning turned on, obviously.)

Other than that, this looks good to me.

test/SemaCXX/warn-zero-nullptr.cpp
68 ↗(On Diff #120285)

Did you mean to fix this before commit?

Can you build some large-ish codebase (say, LLVM) with and without this patch and make sure that this doesn't measurably add to build perf? (With the warning turned on, obviously.)

Other than that, this looks good to me.

Very contrived example:

$ head -n 3 test.cpp 
#include <cstddef>

int main(int argc, char* argv[]) {
$ perl -e 'print "if(argv == NULL) return 1;\n"x1000000; print "\n"' >> test.cpp
$ tail -n 2 test.cpp 
}

So this is a file with 1 million comparisons of pointer with NULL.

$ time clang -fsyntax-only -Wzero-as-null-pointer-constant -std=c++11 test.cpp -w

real    0m8.197s
user    0m8.071s
sys     0m0.124s
$ time clang -fsyntax-only -Wzero-as-null-pointer-constant -std=c++11 test.cpp -w

real    0m7.881s
user    0m7.728s
sys     0m0.152s
$ time clang -fsyntax-only -Wzero-as-null-pointer-constant -std=c++11 test.cpp -w

real    0m7.212s
user    0m7.063s
sys     0m0.148s
$ time /build/llvm-build-Clang-release/bin/clang -fsyntax-only -Wzero-as-null-pointer-constant -std=c++11 test.cpp -w

real    0m11.200s
user    0m11.070s
sys     0m0.128s
$ time /build/llvm-build-Clang-release/bin/clang -fsyntax-only -Wzero-as-null-pointer-constant -std=c++11 test.cpp -w

real    0m11.141s
user    0m11.019s
sys     0m0.121s
$ time /build/llvm-build-Clang-release/bin/clang -fsyntax-only -Wzero-as-null-pointer-constant -std=c++11 test.cpp -w

real    0m11.254s
user    0m11.127s
sys     0m0.126s

So there absolutely is some penalty, but it does not appear to be huge, at least on this contrived example.
I *could* try benchmark-building llvm, but i'm still sporadically experiencing a crash, so the timings will not be comparable.

test/SemaCXX/warn-zero-nullptr.cpp
68 ↗(On Diff #120285)

Eh, i'm conflicted about this one.
This is more of "for future consideration"

Rebased now that D39301 has landed.

Hm, that's a lot of overhead. Granted, it's a synthetic benchmark, but I think it'd be good to try this on some real codebase to make sure it really is negligible overhead in real-world scenarios.

Hm wait, i'm comparing apples and oranges here, my local build at least has the assertions enabled.
Local build, without the patch:

$ time /build/llvm-build-Clang-release/bin/clang -fsyntax-only -Wzero-as-null-pointer-constant -Wsystem-headers -std=c++11 test.cpp -w;

real    0m10.130s
user    0m9.985s
sys     0m0.144s
$ time /build/llvm-build-Clang-release/bin/clang -fsyntax-only -Wzero-as-null-pointer-constant -Wsystem-headers -std=c++11 test.cpp -w;

real    0m10.195s
user    0m10.081s
sys     0m0.112s
$ time /build/llvm-build-Clang-release/bin/clang -fsyntax-only -Wzero-as-null-pointer-constant -Wsystem-headers -std=c++11 test.cpp -w;

real    0m10.099s
user    0m9.977s
sys     0m0.120s
$ time /build/llvm-build-Clang-release/bin/clang -fsyntax-only -Wzero-as-null-pointer-constant -Wsystem-headers -std=c++11 test.cpp -w;

real    0m10.110s
user    0m9.979s
sys     0m0.130s
$ time /build/llvm-build-Clang-release/bin/clang -fsyntax-only -Wzero-as-null-pointer-constant -Wsystem-headers -std=c++11 test.cpp -w;

real    0m10.063s
user    0m9.969s
sys     0m0.092s

Local build, with the patch:

$ time /build/llvm-build-Clang-release/bin/clang -fsyntax-only -Wzero-as-null-pointer-constant -Wsystem-headers -std=c++11 test.cpp -w;

real    0m10.534s
user    0m10.399s
sys     0m0.133s
$ time /build/llvm-build-Clang-release/bin/clang -fsyntax-only -Wzero-as-null-pointer-constant -Wsystem-headers -std=c++11 test.cpp -w;

real    0m10.478s
user    0m10.286s
sys     0m0.159s
$ time /build/llvm-build-Clang-release/bin/clang -fsyntax-only -Wzero-as-null-pointer-constant -Wsystem-headers -std=c++11 test.cpp -w;

real    0m10.359s
user    0m10.226s
sys     0m0.133s
$ time /build/llvm-build-Clang-release/bin/clang -fsyntax-only -Wzero-as-null-pointer-constant -Wsystem-headers -std=c++11 test.cpp -w;

real    0m10.292s
user    0m10.146s
sys     0m0.145s
$ time /build/llvm-build-Clang-release/bin/clang -fsyntax-only -Wzero-as-null-pointer-constant -Wsystem-headers -std=c++11 test.cpp -w;

real    0m10.383s
user    0m10.305s
sys     0m0.077s

So it seems the overhead is around +0.5s, not +3.0s

Add Diags.isIgnored() early return + move C++11 early return earlier too.
At least partially should help avoid the penalty of findMacroSpelling()
I don't think i see any way to avoid findMacroSpelling() :/

thakis accepted this revision.Oct 25 2017, 2:50 PM

In general, "I don't see any way to prevent $slow_thing" just means the patch can't move ahead. But in this case, this looks like fairly small overhead for a worst-case input, so this won't be slow on real-world code. So lgtm.

This revision is now accepted and ready to land.Oct 25 2017, 2:50 PM
This revision was automatically updated to reflect the committed changes.