njames93 created this revision. njames93 added reviewers: alexfh, aaron.ballman, LegalizeAdulthood. Herald added subscribers: carlosgalvezp, xazax.hun. njames93 requested review of this revision. Herald added a project: clang-tools-extra. Herald added a subscriber: cfe-commits.
These `explicit(cond)` feature in c++20 can be used to specify if a declaration should be implicit or explicit. For these cases we shouldn't produce any warning as the developer is already enforcing a specific behaviour. Fixes https://llvm.org/PR53115. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D117593 Files: clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.cpp clang-tools-extra/docs/ReleaseNotes.rst clang-tools-extra/test/clang-tidy/checkers/google-explicit-constructor-cxx20.cpp Index: clang-tools-extra/test/clang-tidy/checkers/google-explicit-constructor-cxx20.cpp =================================================================== --- /dev/null +++ clang-tools-extra/test/clang-tidy/checkers/google-explicit-constructor-cxx20.cpp @@ -0,0 +1,17 @@ +// RUN: %check_clang_tidy -std=c++20 %s google-explicit-constructor %t + +struct Foo { + Foo(int) {} + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: single-argument constructors must be marked explicit to avoid unintentional implicit conversions + // CHECK-FIXES: {{^}} explicit Foo(int) {} + explicit Foo(long) {} + explicit(false) Foo(float) {} + explicit(true) Foo(double) {} + + operator int() const; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'operator int' must be marked explicit to avoid unintentional implicit conversions + // CHECK-FIXES: {{^}} explicit operator int() const; + explicit operator long() const; + explicit(false) operator float() const; + explicit(true) operator double() const; +}; Index: clang-tools-extra/docs/ReleaseNotes.rst =================================================================== --- clang-tools-extra/docs/ReleaseNotes.rst +++ clang-tools-extra/docs/ReleaseNotes.rst @@ -156,6 +156,10 @@ - Removed default setting ``cppcoreguidelines-explicit-virtual-functions.IgnoreDestructors = "true"``, to match the current state of the C++ Core Guidelines. +- Updated :doc:`google-explicit-constructor + <clang-tidy/checks/google-explicit-constructor>` check to ignore constructors + or conversion operators where they are marked ``explicit(false)``. + - Updated :doc:`google-readability-casting <clang-tidy/checks/google-readability-casting>` to diagnose and fix functional casts, to achieve feature parity with the corresponding ``cpplint.py`` check. Index: clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.cpp =================================================================== --- clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.cpp +++ clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.cpp @@ -88,6 +88,8 @@ Result.Nodes.getNodeAs<CXXConversionDecl>("conversion")) { if (Conversion->isOutOfLine()) return; + if (Conversion->getExplicitSpecifier().isSpecified()) + return; SourceLocation Loc = Conversion->getLocation(); // Ignore all macros until we learn to ignore specific ones (e.g. used in // gmock to define matchers). @@ -133,7 +135,7 @@ } if (Ctor->isExplicit() || Ctor->isCopyOrMoveConstructor() || - TakesInitializerList) + TakesInitializerList || Ctor->getExplicitSpecifier().isSpecified()) return; bool SingleArgument =
Index: clang-tools-extra/test/clang-tidy/checkers/google-explicit-constructor-cxx20.cpp =================================================================== --- /dev/null +++ clang-tools-extra/test/clang-tidy/checkers/google-explicit-constructor-cxx20.cpp @@ -0,0 +1,17 @@ +// RUN: %check_clang_tidy -std=c++20 %s google-explicit-constructor %t + +struct Foo { + Foo(int) {} + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: single-argument constructors must be marked explicit to avoid unintentional implicit conversions + // CHECK-FIXES: {{^}} explicit Foo(int) {} + explicit Foo(long) {} + explicit(false) Foo(float) {} + explicit(true) Foo(double) {} + + operator int() const; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'operator int' must be marked explicit to avoid unintentional implicit conversions + // CHECK-FIXES: {{^}} explicit operator int() const; + explicit operator long() const; + explicit(false) operator float() const; + explicit(true) operator double() const; +}; Index: clang-tools-extra/docs/ReleaseNotes.rst =================================================================== --- clang-tools-extra/docs/ReleaseNotes.rst +++ clang-tools-extra/docs/ReleaseNotes.rst @@ -156,6 +156,10 @@ - Removed default setting ``cppcoreguidelines-explicit-virtual-functions.IgnoreDestructors = "true"``, to match the current state of the C++ Core Guidelines. +- Updated :doc:`google-explicit-constructor + <clang-tidy/checks/google-explicit-constructor>` check to ignore constructors + or conversion operators where they are marked ``explicit(false)``. + - Updated :doc:`google-readability-casting <clang-tidy/checks/google-readability-casting>` to diagnose and fix functional casts, to achieve feature parity with the corresponding ``cpplint.py`` check. Index: clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.cpp =================================================================== --- clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.cpp +++ clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.cpp @@ -88,6 +88,8 @@ Result.Nodes.getNodeAs<CXXConversionDecl>("conversion")) { if (Conversion->isOutOfLine()) return; + if (Conversion->getExplicitSpecifier().isSpecified()) + return; SourceLocation Loc = Conversion->getLocation(); // Ignore all macros until we learn to ignore specific ones (e.g. used in // gmock to define matchers). @@ -133,7 +135,7 @@ } if (Ctor->isExplicit() || Ctor->isCopyOrMoveConstructor() || - TakesInitializerList) + TakesInitializerList || Ctor->getExplicitSpecifier().isSpecified()) return; bool SingleArgument =
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits