Re: [PATCH] D20857: [clang-tidy] Add modernize-explicit-operator-bool check.

2016-07-22 Thread Murray Cumming via cfe-commits
murrayc added inline comments.


Comment at: clang-tidy/modernize/ExplicitOperatorBoolCheck.cpp:38
@@ +37,3 @@
+  Finder->addMatcher(
+  cxxConversionDecl(returns(booleanType()), unless(isExplicit()))
+  .bind("operator-bool"),

alexfh wrote:
> Please merge these two matchers to avoid repeated work. Something along the 
> lines of:
> 
>   cxxConversionDecl(unless(isExplicit()),
> anyOf(cxxConversionDecl(returns(booleanType())).bind("operator-bool"),
>   cxxConversionDecl(returns(pointerType(pointee(isConstQualified(), 
> voidType(.bind("operator-void-pointer";
It seems that I can't pass cxxConversionDecls to anyOf(). I can pass anyOf to 
cxxConversionDecl, but then I don't see how to bind() to the two kinds of 
declaration separately:

Finder->addMatcher(
   cxxConversionDecl(
   anyOf(returns(booleanType()),
 returns(pointerType(pointee(isConstQualified(), voidType(),
   unless(isExplicit())),
   this);

I also wonder if I'll be able to combine them while keeping the check for 
WarnOnOperatorVoidPointer, to avoid unnecessary work when that is disabled. 
(And I still wonder if you even want the check for operator void*.)


https://reviews.llvm.org/D20857



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D20857: [clang-tidy] Add modernize-explicit-operator-bool check.

2016-06-30 Thread Murray Cumming via cfe-commits
murrayc added a comment.

I'd still be perfectly happy if just the simple check for implicit operator 
bool was accepted.


http://reviews.llvm.org/D20857



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D20857: [clang-tidy] Add modernize-explicit-operator-bool check.

2016-06-30 Thread Murray Cumming via cfe-commits
murrayc updated this revision to Diff 62355.
murrayc marked an inline comment as done.
murrayc added a comment.

Same as previous patch, but with a tiny suggested whitespace corretion.


http://reviews.llvm.org/D20857

Files:
  clang-tidy/modernize/CMakeLists.txt
  clang-tidy/modernize/ExplicitOperatorBoolCheck.cpp
  clang-tidy/modernize/ExplicitOperatorBoolCheck.h
  clang-tidy/modernize/ModernizeTidyModule.cpp
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/checks/modernize-explicit-operator-bool.rst
  test/clang-tidy/modernize-explicit-operator-bool-void-pointer.cpp
  test/clang-tidy/modernize-explicit-operator-bool.cpp

Index: test/clang-tidy/modernize-explicit-operator-bool.cpp
===
--- /dev/null
+++ test/clang-tidy/modernize-explicit-operator-bool.cpp
@@ -0,0 +1,19 @@
+// RUN: %check_clang_tidy %s modernize-explicit-operator-bool %t -- -- -std=c++11
+
+// This should trigger the check:
+class SomethingBad {
+  operator bool() const {
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator bool declaration is not explicit [modernize-explicit-operator-bool]
+return something != 0;
+  }
+
+  int something = 0;
+};
+
+class SomethingGood {
+  explicit operator bool() const {
+return something != 0;
+  }
+
+  int something = 0;
+};
Index: test/clang-tidy/modernize-explicit-operator-bool-void-pointer.cpp
===
--- /dev/null
+++ test/clang-tidy/modernize-explicit-operator-bool-void-pointer.cpp
@@ -0,0 +1,46 @@
+// RUN: %check_clang_tidy %s modernize-explicit-operator-bool %t -- -- -std=c++11
+
+// This should trigger the check:
+class SomethingBad {
+  operator const void *() const {
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: implicit operator const void* declaration should probably be explicit operator bool [modernize-explicit-operator-bool]
+return reinterpret_cast(something != 0);
+  }
+
+  int something = 0;
+};
+
+class SomethingGood {
+  // Note: Use modernize-explicit-operator-bool to check for implicit operator bool.
+  explicit operator bool() const {
+return something != 0;
+  }
+
+  int something = 0;
+};
+
+class SomethingGoodExplicitConstVoidPtr {
+  explicit operator const void *() const {
+return &something;
+  }
+
+  const int something = 0;
+};
+
+class SomethingGoodExplicitNonConstVoidPtr {
+  explicit operator void *() {
+return &something;
+  }
+
+  int something = 0;
+};
+
+class SomethingGoodNonConstVoidPtr {
+  // A non-const void* is unlikely to to be meant as operator bool before C++11
+  // let us use explicit.
+  operator void *() {
+return &something;
+  }
+
+  int something = 0;
+};
Index: docs/clang-tidy/checks/modernize-explicit-operator-bool.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/modernize-explicit-operator-bool.rst
@@ -0,0 +1,28 @@
+.. title:: clang-tidy - modernize-explicit-operator-bool
+
+modernize-explicit-operator-bool
+
+
+This check finds implicit ``operator bool`` overloads and inserts the
+``explicit`` keyword, which is available since C++11.
+
+Without the ``explicit`` keyword, the implicit ``bool`` overload can allow
+objects to be compared accidentally. For instance, even when objects `a` and
+`b` have no ``operator ==`` overloads, an implicit ``operator bool`` would allow
+`a == b` to compile because both `a` and `b` can be implictly converted to
+``bool``.
+
+This check also finds implicit ``operator const void*`` overloads. These were
+often used before C++11 to avoid implicit conversions to ``bool`` when providing
+an ``operator bool`` overload.
+
+To disable the check for ``operator const void*`` overloads, you may set
+The :option:`WarnOnOperatorVoidPointer` option to 1.
+
+.. code-block:: c++
+
+  operator bool () const;
+
+  // becomes
+
+  explicit operator bool () const;
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -93,6 +93,7 @@
misc-virtual-near-miss
modernize-avoid-bind
modernize-deprecated-headers
+   modernize-explicit-operator-bool
modernize-loop-convert
modernize-make-shared
modernize-make-unique
Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -204,6 +204,13 @@
 
   Replaces C standard library headers with their C++ alternatives.
 
+- New `modernize-explicit-operator-bool
+  `_ check
+
+  Adds the ``explicit`` keyword to ``operator bool`` overloads.
+  Also finds ``operator const void*`` overloads, which should often be
+  ``explicit operator bool`` overloads.
+
 - New `modernize-make-shared
   

Re: [PATCH] D20857: [clang-tidy] Add modernize-explicit-operator-bool check.

2016-06-04 Thread Murray Cumming via cfe-commits
murrayc added a comment.

In http://reviews.llvm.org/D20857#449080, @alexfh wrote:

> Looks like a useful check to have. I'm not sure though, that it has anything 
> to do with "modernize". I'd suggest adding a new "bugprone" module (should be 
> added by http://reviews.llvm.org/D18821, hopefully soon) and moving the check 
> there.


Fair enough. My logic is that this is a problem that can only be fixed properly 
in C++11 and that the best/correct/common way to do this has changed from C++98 
to C++11. It's not just a nice use of new syntax (such as auto), it's also 
fixes bugs, but it's still use of new syntax.



Comment at: test/clang-tidy/modernize-explicit-operator-bool-void-pointer.cpp:6
@@ +5,3 @@
+  operator const void *() const {
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: implicit operator const void* 
declaration should probably be explicit operator bool 
[modernize-explicit-operator-bool]
+return reinterpret_cast(something != 0);

alexfh wrote:
> From the first glance, this doesn't look like an easy mistake to make. Have 
> you actually seen this pattern in real code?
Yes, in glibmm and gtkmm, which I maintain. This commit is from me though the 
idea wasn't:
https://git.gnome.org/browse/gtkmm/commit/gtk/src/treerowreference.hg?id=c182608593e2d4799f523580a0532fbc68d296b2

We later used a typedef to make that clearer:
https://git.gnome.org/browse/gtkmm/commit/gtk/src/treerowreference.hg?id=7dff74cca47827d6e34bc8f239674bf044ddedaa

There's lots of mention of this in StackOverflow, though not always so clearly. 
For instance: 
https://stackoverflow.com/questions/9134888/is-using-void-instead-of-bool-an-advisable-practice


http://reviews.llvm.org/D20857



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D20857: [clang-tidy] Add modernize-explicit-operator-bool check.

2016-06-03 Thread Murray Cumming via cfe-commits
murrayc updated this revision to Diff 59537.
murrayc added a comment.

Combined into one check. Also specifies C++11 for the test.


http://reviews.llvm.org/D20857

Files:
  clang-tidy/modernize/CMakeLists.txt
  clang-tidy/modernize/ExplicitOperatorBoolCheck.cpp
  clang-tidy/modernize/ExplicitOperatorBoolCheck.h
  clang-tidy/modernize/ModernizeTidyModule.cpp
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/checks/modernize-explicit-operator-bool.rst
  test/clang-tidy/modernize-explicit-operator-bool-void-pointer.cpp
  test/clang-tidy/modernize-explicit-operator-bool.cpp

Index: test/clang-tidy/modernize-explicit-operator-bool.cpp
===
--- /dev/null
+++ test/clang-tidy/modernize-explicit-operator-bool.cpp
@@ -0,0 +1,19 @@
+// RUN: %check_clang_tidy %s modernize-explicit-operator-bool %t -- -- -std=c++11
+
+// This should trigger the check:
+class SomethingBad {
+  operator bool() const {
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator bool declaration is not explicit [modernize-explicit-operator-bool]
+return something != 0;
+  }
+
+  int something = 0;
+};
+
+class SomethingGood {
+  explicit operator bool() const {
+return something != 0;
+  }
+
+  int something = 0;
+};
Index: test/clang-tidy/modernize-explicit-operator-bool-void-pointer.cpp
===
--- /dev/null
+++ test/clang-tidy/modernize-explicit-operator-bool-void-pointer.cpp
@@ -0,0 +1,46 @@
+// RUN: %check_clang_tidy %s modernize-explicit-operator-bool %t -- -- -std=c++11
+
+// This should trigger the check:
+class SomethingBad {
+  operator const void *() const {
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: implicit operator const void* declaration should probably be explicit operator bool [modernize-explicit-operator-bool]
+return reinterpret_cast(something != 0);
+  }
+
+  int something = 0;
+};
+
+class SomethingGood {
+  //Note: Use modernize-explicit-operator-bool to check for implicit operator bool.
+  explicit operator bool() const {
+return something != 0;
+  }
+
+  int something = 0;
+};
+
+class SomethingGoodExplicitConstVoidPtr {
+  explicit operator const void *() const {
+return &something;
+  }
+
+  const int something = 0;
+};
+
+class SomethingGoodExplicitNonConstVoidPtr {
+  explicit operator void *() {
+return &something;
+  }
+
+  int something = 0;
+};
+
+class SomethingGoodNonConstVoidPtr {
+  // A non-const void* is unlikely to to be meant as operator bool before C++11
+  // let us use explicit.
+  operator void *() {
+return &something;
+  }
+
+  int something = 0;
+};
Index: docs/clang-tidy/checks/modernize-explicit-operator-bool.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/modernize-explicit-operator-bool.rst
@@ -0,0 +1,28 @@
+.. title:: clang-tidy - modernize-explicit-operator-bool
+
+modernize-explicit-operator-bool
+
+
+This check finds implicit ``operator bool`` overloads and inserts the
+``explicit`` keyword, which is available since C++11.
+
+Without the ``explicit`` keyword, the implicit ``bool`` overload can allow
+objects to be compared accidentally. For instance, even when objects `a` and
+`b` have no ``operator ==`` overloads, an implicit ``operator bool`` would allow
+`a == b` to compile because both `a` and `b` can be implictly converted to
+``bool``.
+
+This check also finds implicit ``operator const void*`` overloads. These were
+often used before C++11 to avoid implicit conversions to ``bool`` when providing
+an ``operator bool`` overload.
+
+To disable the check for ``operator const void*`` overloads, you may set
+The :option:`WarnOnOperatorVoidPointer` option to 1.
+
+.. code-block:: c++
+
+  operator bool () const;
+
+  // becomes
+
+  explicit operator bool () const;
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -93,6 +93,7 @@
misc-virtual-near-miss
modernize-avoid-bind
modernize-deprecated-headers
+   modernize-explicit-operator-bool
modernize-loop-convert
modernize-make-shared
modernize-make-unique
Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -190,6 +190,13 @@
 
   Replaces C standard library headers with their C++ alternatives.
 
+- New `modernize-explicit-operator-bool
+  `_ check
+
+  Adds the ``explicit`` keyword to ``operator bool`` overloads.
+  Also finds ``operator const void*`` overloads, which should often be
+  ``explicit operator bool`` overloads.
+
 - New `modernize-make-shared
   `

Re: [PATCH] D20857: [clang-tidy] Add modernize-explicit-operator-bool check.

2016-06-02 Thread Murray Cumming via cfe-commits
murrayc added inline comments.


Comment at: clang-tidy/modernize/OperatorVoidPointerCheck.cpp:27
@@ +26,3 @@
+  Finder->addMatcher(cxxConversionDecl(returns(pointerType(pointee(
+   isConstQualified(), voidType(,
+   unless(isExplicit()))

etienneb wrote:
> I'm curious, why: isConstQualified() ?
> I'm probably missing something.
This is a workaround for the lack of explicit operator bool before C++:
  operator const void*() const;
but this would be unlikely to be meant the same way, partly because the 
constness would be awkward:
  operator void*() const;




Comment at: clang-tidy/modernize/OperatorVoidPointerCheck.cpp:40
@@ +39,3 @@
+
+  // FIXME: This tries to change the type and add explicit, but
+  // MatchedDecl->getTypeSpecStartLoc() gets the start of void, not the start

etienneb wrote:
> The FIXME only apply to the fixtit statements.
>   << FIxItHint(...)
> 
> you can still output a diag message.
Yes. I do that in the previous lines.


http://reviews.llvm.org/D20857



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D20857: [clang-tidy] Add modernize-explicit-operator-bool check.

2016-06-02 Thread Murray Cumming via cfe-commits
murrayc added a comment.

In http://reviews.llvm.org/D20857#446732, @etienneb wrote:

> Enabling/disabling can be done with options (see SizeofExpressionCheck).


Thanks. Am I being asked to combine the checks?


http://reviews.llvm.org/D20857



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D20857: [clang-tidy] Add modernize-explicit-operator-bool check.

2016-06-02 Thread Murray Cumming via cfe-commits
murrayc updated this revision to Diff 59367.
murrayc added a comment.

With suggested changes. Ran clang-format (LLVM style). Used voidType() matcher.


http://reviews.llvm.org/D20857

Files:
  clang-tidy/modernize/CMakeLists.txt
  clang-tidy/modernize/ExplicitOperatorBoolCheck.cpp
  clang-tidy/modernize/ExplicitOperatorBoolCheck.h
  clang-tidy/modernize/ModernizeTidyModule.cpp
  clang-tidy/modernize/OperatorVoidPointerCheck.cpp
  clang-tidy/modernize/OperatorVoidPointerCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/checks/modernize-explicit-operator-bool.rst
  docs/clang-tidy/checks/modernize-operator-void-pointer.rst
  test/clang-tidy/modernize-explicit-operator-bool.cpp
  test/clang-tidy/modernize-operator-void-pointer.cpp

Index: test/clang-tidy/modernize-operator-void-pointer.cpp
===
--- /dev/null
+++ test/clang-tidy/modernize-operator-void-pointer.cpp
@@ -0,0 +1,46 @@
+// RUN: %check_clang_tidy %s modernize-operator-void-pointer %t
+
+// This should trigger the check:
+class SomethingBad {
+  operator const void *() const {
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: implicit operator void* declaration should probably be explicit operator bool [modernize-operator-void-pointer]
+return reinterpret_cast(something != 0);
+  }
+
+  int something = 0;
+};
+
+class SomethingGood {
+  //Note: Use modernize-explicit-operator-bool to check for implicit operator bool.
+  explicit operator bool() const {
+return something != 0;
+  }
+
+  int something = 0;
+};
+
+class SomethingGoodExplicitConstVoidPtr {
+  explicit operator const void *() const {
+return &something;
+  }
+
+  const int something = 0;
+};
+
+class SomethingGoodExplicitNonConstVoidPtr {
+  explicit operator void *() {
+return &something;
+  }
+
+  int something = 0;
+};
+
+class SomethingGoodNonConstVoidPtr {
+  // A non-const void* is unlikely to to be meant as operator bool before C++11
+  // let us use explicit.
+  operator void *() {
+return &something;
+  }
+
+  int something = 0;
+};
Index: test/clang-tidy/modernize-explicit-operator-bool.cpp
===
--- /dev/null
+++ test/clang-tidy/modernize-explicit-operator-bool.cpp
@@ -0,0 +1,19 @@
+// RUN: %check_clang_tidy %s modernize-explicit-operator-bool %t
+
+// This should trigger the check:
+class SomethingBad {
+  operator bool() const {
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator bool declaration is not explicit [modernize-explicit-operator-bool]
+return something != 0;
+  }
+
+  int something = 0;
+};
+
+class SomethingGood {
+  explicit operator bool() const {
+return something != 0;
+  }
+
+  int something = 0;
+};
Index: docs/clang-tidy/checks/modernize-operator-void-pointer.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/modernize-operator-void-pointer.rst
@@ -0,0 +1,21 @@
+.. title:: clang-tidy - modernize-operator-void-pointer
+
+modernize-operator-void-pointer
+
+
+This check finds implicit ``operator void*`` overloads and replaces them with
+``explicit operator bool`` overloads, available since C++11.
+
+Implicit ``operator void*`` overloads were often used before C++11 to avoid
+implicit conversions to ``bool`` when providing an ``operator bool`` overload,
+but C++11 provides the ``explicit`` keyword.
+
+See also the modernize-implicit-operator-bool check.
+
+.. code-block:: c++
+
+  operator void* () const;
+
+  // becomes
+
+  explicit operator bool () const;
Index: docs/clang-tidy/checks/modernize-explicit-operator-bool.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/modernize-explicit-operator-bool.rst
@@ -0,0 +1,21 @@
+.. title:: clang-tidy - modernize-explicit-operator-bool
+
+modernize-explicit-operator-bool
+
+
+This check finds implicit ``operator bool`` overloads and inserts the
+``explicit`` keyword, which is available since C++11.
+
+Without the ``explicit`` keyword, the implicit ``bool`` overload can allow
+objects to be compared accidentally. For instance, even when objects a and b
+have no ``operator ==`` overloads, an implicit ``operator bool`` would allow
+``a == b`` to compile because both a and b can be implictly converted to
+``bool``.
+
+.. code-block:: c++
+
+  operator bool () const;
+
+  // becomes
+
+  explicit operator bool () const;
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -93,6 +93,7 @@
misc-virtual-near-miss
modernize-avoid-bind
modernize-deprecated-headers
+   modernize-explicit-operator-bool
modernize-loop-convert
modernize-make-shared
modernize-make-unique
@@ -106,6 +107,7 @@
modernize-use

Re: [PATCH] D20857: [clang-tidy] Add modernize-explicit-operator-bool check.

2016-06-02 Thread Murray Cumming via cfe-commits
murrayc added a comment.

In http://reviews.llvm.org/D20857#446101, @etienneb wrote:

> I wonder if these two checks should not be merge in one checker.


Personally I find it cleaner to keep them separate, but I would be happy to 
combine them if that's wanted. I guessed that it would be easier to accept the 
explicit bool check than the operator void pointer check, and didn't want to 
make acceptance harder. I can also imagine someone wanting to disable one but 
not the other.


http://reviews.llvm.org/D20857



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D20857: [clang-tidy] Add modernize-explicit-operator-bool check.

2016-06-02 Thread Murray Cumming via cfe-commits
murrayc updated this revision to Diff 59346.
murrayc added a comment.

These are the commits amended with the suggested changes.
Many thanks for the suggestions.

(I'm not quite sure what arcanist will do, so hopefully this will not create a 
mess.)


http://reviews.llvm.org/D20857

Files:
  clang-tidy/modernize/CMakeLists.txt
  clang-tidy/modernize/ExplicitOperatorBoolCheck.cpp
  clang-tidy/modernize/ExplicitOperatorBoolCheck.h
  clang-tidy/modernize/ModernizeTidyModule.cpp
  clang-tidy/modernize/OperatorVoidPointerCheck.cpp
  clang-tidy/modernize/OperatorVoidPointerCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/checks/modernize-explicit-operator-bool.rst
  docs/clang-tidy/checks/modernize-operator-void-pointer.rst
  test/clang-tidy/modernize-explicit-operator-bool.cpp
  test/clang-tidy/modernize-operator-void-pointer.cpp

Index: test/clang-tidy/modernize-operator-void-pointer.cpp
===
--- /dev/null
+++ test/clang-tidy/modernize-operator-void-pointer.cpp
@@ -0,0 +1,46 @@
+// RUN: %check_clang_tidy %s modernize-operator-void-pointer %t
+
+// This should trigger the check:
+class SomethingBad {
+  operator const void *() const {
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: implicit operator void* declaration should probably be explicit operator bool [modernize-operator-void-pointer]
+return reinterpret_cast(something != 0);
+  }
+
+  int something = 0;
+};
+
+class SomethingGood {
+  //Note: Use modernize-explicit-operator-bool to check for implicit operator bool.
+  explicit operator bool() const {
+return something != 0;
+  }
+
+  int something = 0;
+};
+
+class SomethingGoodExplicitConstVoidPtr {
+  explicit operator const void *() const {
+return &something;
+  }
+
+  const int something = 0;
+};
+
+class SomethingGoodExplicitNonConstVoidPtr {
+  explicit operator void *() {
+return &something;
+  }
+
+  int something = 0;
+};
+
+class SomethingGoodNonConstVoidPtr {
+  // A non-const void* is unlikely to to be meant as operator bool before C++11
+  // let us use explicit.
+  operator void *() {
+return &something;
+  }
+
+  int something = 0;
+};
Index: test/clang-tidy/modernize-explicit-operator-bool.cpp
===
--- /dev/null
+++ test/clang-tidy/modernize-explicit-operator-bool.cpp
@@ -0,0 +1,19 @@
+// RUN: %check_clang_tidy %s modernize-explicit-operator-bool %t
+
+// This should trigger the check:
+class SomethingBad {
+  operator bool() const {
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator bool declaration is not explicit [modernize-explicit-operator-bool]
+return something != 0;
+  }
+
+  int something = 0;
+};
+
+class SomethingGood {
+  explicit operator bool() const {
+return something != 0;
+  }
+
+  int something = 0;
+};
Index: docs/clang-tidy/checks/modernize-operator-void-pointer.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/modernize-operator-void-pointer.rst
@@ -0,0 +1,21 @@
+.. title:: clang-tidy - modernize-operator-void-pointer
+
+modernize-operator-void-pointer
+
+
+This check finds implicit ``operator void*`` overloads and replaces them with
+``explicit operator bool`` overloads, available since C++11.
+
+Implicit ``operator void*`` overloads were often used before C++11 to avoid
+implicit conversions to ``bool`` when providing an ``operator bool`` overload,
+but C++11 provides the ``explicit`` keyword.
+
+See also the modernize-implicit-operator-bool check.
+
+.. code-block:: c++
+
+  operator void* () const;
+
+  // becomes
+
+  explicit operator bool () const;
Index: docs/clang-tidy/checks/modernize-explicit-operator-bool.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/modernize-explicit-operator-bool.rst
@@ -0,0 +1,21 @@
+.. title:: clang-tidy - modernize-explicit-operator-bool
+
+modernize-explicit-operator-bool
+
+
+This check finds implicit ``operator bool`` overloads and inserts the
+``explicit`` keyword, which is available since C++11.
+
+Without the ``explicit`` keyword, the implicit ``bool`` overload can allow
+objects to be compared accidentally. For instance, even when objects a and b
+have no ``operator ==`` overloads, an implicit ``operator bool`` would allow
+``a == b`` to compile because both a and b can be implictly converted to
+``bool``.
+
+.. code-block:: c++
+
+  operator bool () const;
+
+  // becomes
+
+  explicit operator bool () const;
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -93,6 +93,7 @@
misc-virtual-near-miss
modernize-avoid-bind
modernize-deprecated-headers
+   modernize-explicit-operator-bool
modernize-loo