test: Add linter to make sure single parameter constructors are marked explicit #14505

pull practicalswift wants to merge 1 commits into bitcoin:master from practicalswift:explicit-single-argument-constructors changing 8 files +145 −4
  1. practicalswift commented at 5:24 pm on October 17, 2018: contributor

    Make single parameter constructors explicit (C++11).

    Rationale from the developer notes:

    • By default, declare single-argument constructors explicit.
      • Rationale: This is a precaution to avoid unintended conversions that might arise when single-argument constructors are used as implicit conversion functions.
  2. fanquake added the label Refactoring on Oct 17, 2018
  3. promag commented at 0:29 am on October 18, 2018: member
    Concept ACK. @practicalswift is there a compiler flag to detect these?
  4. practicalswift commented at 6:48 am on October 19, 2018: contributor

    @promag Perhaps surprisingly clang and GCC lack such a warning AFAIK, but the Intel C++ Compiler has it.

    Also most C++ linters support flagging single parameter constructors not declared explicit.

  5. DrahtBot commented at 9:52 am on October 20, 2018: member

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #13728 (lint: Run the CI lint stage on mac by Empact)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

  6. MarcoFalke commented at 2:23 pm on October 20, 2018: member

    See #13769, #11112, #10969, …

    At this point I’d prefer a linter that runs in travis than having a fixup pull request every couple of weeks. I think there are some intentional cases of not using explicit, so those could be added to a whitelist.

  7. practicalswift force-pushed on Oct 21, 2018
  8. practicalswift force-pushed on Oct 21, 2018
  9. DrahtBot added the label Needs rebase on Oct 22, 2018
  10. practicalswift force-pushed on Oct 23, 2018
  11. DrahtBot removed the label Needs rebase on Oct 23, 2018
  12. practicalswift force-pushed on Nov 7, 2018
  13. practicalswift force-pushed on Nov 7, 2018
  14. practicalswift force-pushed on Nov 7, 2018
  15. practicalswift force-pushed on Nov 7, 2018
  16. practicalswift force-pushed on Nov 7, 2018
  17. practicalswift force-pushed on Nov 7, 2018
  18. practicalswift commented at 4:35 pm on November 7, 2018: contributor
    @MarcoFalke Good point! I’ve now added a Travis check that will catch newly introduced single-argument constructors not declare explicit. Please re-review :-)
  19. DrahtBot added the label Needs rebase on Nov 7, 2018
  20. practicalswift force-pushed on Nov 7, 2018
  21. DrahtBot removed the label Needs rebase on Nov 7, 2018
  22. practicalswift renamed this:
    Make all single parameter constructors explicit (C++11)
    Make all single parameter constructors explicit (C++11). Add linter.
    on Nov 11, 2018
  23. practicalswift renamed this:
    Make all single parameter constructors explicit (C++11). Add linter.
    Make all single parameter constructors explicit (C++11). Add explicit constructor linter.
    on Nov 11, 2018
  24. practicalswift force-pushed on Nov 12, 2018
  25. practicalswift commented at 4:31 pm on November 12, 2018: contributor

    @promag Would you mind reviewing the updated version which contains the automatic Travis checking for explicit?

    If merged we’ll never have to think about explicit ever again :-)

  26. Empact commented at 6:11 pm on November 22, 2018: member
    utACK c191011 - could squash the first five commits, and “all” is not strictly accurate given the linter exceptions.
  27. practicalswift force-pushed on Nov 22, 2018
  28. practicalswift renamed this:
    Make all single parameter constructors explicit (C++11). Add explicit constructor linter.
    Make single parameter constructors explicit (C++11). Add explicit constructor linter.
    on Nov 22, 2018
  29. practicalswift force-pushed on Nov 22, 2018
  30. practicalswift commented at 11:16 pm on November 22, 2018: contributor
    @Empact Good points! Now addressed. Please re-review :-)
  31. DrahtBot added the label Needs rebase on Dec 12, 2018
  32. practicalswift force-pushed on Dec 12, 2018
  33. DrahtBot removed the label Needs rebase on Dec 12, 2018
  34. practicalswift commented at 8:47 am on December 12, 2018: contributor
    Rebased!
  35. in test/lint/lint-cppcheck.sh:21 in e3dd0dbf4d outdated
    16+    "src/prevector.h:.* Class 'const_reverse_iterator' has a constructor with 1 argument that is not explicit."
    17+    "src/prevector.h:.* Class 'iterator' has a constructor with 1 argument that is not explicit."
    18+    "src/prevector.h:.* Class 'reverse_iterator' has a constructor with 1 argument that is not explicit."
    19+    "src/primitives/transaction.h:.* Class 'CTransaction' has a constructor with 1 argument that is not explicit."
    20+    "src/protocol.h:.* Class 'CMessageHeader' has a constructor with 1 argument that is not explicit."
    21+    "src/rpc/server.h:.* Struct 'UniValueType' has a constructor with 1 argument that is not explicit."
    


    MarcoFalke commented at 7:04 pm on December 12, 2018:
    Why are some of our own classes suppressed as warnings and others fixed up? Seems arbitrary to me.

    practicalswift commented at 9:21 am on December 13, 2018:

    I excluded the constructors that appeared to be intentionally non-explicit or where switching to explicit seemed non-trivial.

    The remaining cases are:

     0CTransaction(CMutableTransaction &&tx)
     1CTransaction(const CMutableTransaction &tx)
     2UniValueType(UniValue::VType _type)
     3arith_uint256(const base_uint<256>& b)
     4arith_uint256(uint64_t b)
     5base_uint(uint64_t b)
     6const_iterator(const T* ptr_)
     7const_iterator(iterator x)
     8const_reverse_iterator(const T* ptr_)
     9const_reverse_iterator(reverse_iterator x)
    10iterator(T* ptr_)
    11reverse_iterator(T* ptr_)
    12secure_allocator(const secure_allocator<U>& a)
    13zero_after_free_allocator(const zero_after_free_allocator<U>& a)
    

    And also two cases that appear to be incorrectly flagged as single-parameter:

    0CMessageHeader(const MessageStartChars& pchMessageStartIn, const char* pszCommand, unsigned int nMessageSizeIn)
    1CNetMessage(const CMessageHeader::MessageStartChars& pchMessageStartIn, int nTypeIn, int nVersionIn)
    

    Should any of these be be turned explicit as part of this PR? :-)


    MarcoFalke commented at 8:18 pm on December 13, 2018:
    Makes sense. Though, I’d prefer if this was a test only change (adding all the suppressions) and then go out and fixup violations in the code in another pull request(s), since both tasks are slightly different when it comes to review process.
  36. MarcoFalke commented at 7:05 pm on December 12, 2018: member
    Doesn’t compile?
  37. DrahtBot added the label Needs rebase on Dec 12, 2018
  38. practicalswift force-pushed on Dec 13, 2018
  39. practicalswift commented at 9:23 am on December 13, 2018: contributor
    Rebased!
  40. DrahtBot removed the label Needs rebase on Dec 13, 2018
  41. in test/lint/lint-cppcheck.sh:41 in ae02a8d0c3 outdated
    36+}
    37+
    38+ENABLED_CHECKS_REGEXP=$(join_array "|" "${ENABLED_CHECKS[@]}")
    39+IGNORED_WARNINGS_REGEXP=$(join_array "|" "${IGNORED_WARNINGS[@]}")
    40+WARNINGS=$(git ls-files -- "*.cpp" "*.h" ":(exclude)src/leveldb/" ":(exclude)src/secp256k1/" ":(exclude)src/univalue/" | \
    41+    xargs cppcheck --enable=all -j "$(nproc)" --language=c++ --std=c++11 --template=gcc -D__cplusplus -DCLIENT_VERSION_BUILD -DCLIENT_VERSION_IS_RELEASE -DCLIENT_VERSION_MAJOR -DCLIENT_VERSION_MINOR -DCLIENT_VERSION_REVISION -DCOPYRIGHT_YEAR -DDEBUG -DHAVE_WORKING_BOOST_SLEEP_FOR -I src/ -q 2>&1 | \
    


    MarcoFalke commented at 8:19 pm on December 13, 2018:
    Looks like installing and running this takes some time. Could add another more expensive lint check after the two stages as a third stage? (Feel free to ignore my suggestion)
  42. practicalswift force-pushed on Dec 14, 2018
  43. practicalswift force-pushed on Dec 14, 2018
  44. practicalswift force-pushed on Dec 14, 2018
  45. practicalswift force-pushed on Dec 14, 2018
  46. practicalswift force-pushed on Dec 14, 2018
  47. practicalswift force-pushed on Dec 14, 2018
  48. practicalswift force-pushed on Dec 14, 2018
  49. practicalswift renamed this:
    Make single parameter constructors explicit (C++11). Add explicit constructor linter.
    Add linter to make sure single parameter constructors are marked explicit (C++11).
    on Dec 14, 2018
  50. practicalswift renamed this:
    Add linter to make sure single parameter constructors are marked explicit (C++11).
    Add linter to make sure single parameter constructors are marked explicit (C++11) by default
    on Dec 14, 2018
  51. practicalswift commented at 3:42 pm on December 14, 2018: contributor
    @MarcoFalke Thanks for reviewing. Feedback addressed: 1.) this PR is now test only and 2.) added another more expensive lint check after the two stages as a third stage. Please re-review :-)
  52. promag commented at 4:12 pm on December 14, 2018: member

    @promag Perhaps surprisingly clang and GCC lack such a warning AFAIK, but the Intel C++ Compiler has it.

    Could we add a stage to build with it?

  53. practicalswift commented at 5:13 pm on December 14, 2018: contributor
    @promag I’m not sure the Intel C++ Compiler license would allow that. On the other hand the problem is already solved using cppcheck in this PR :-)
  54. MarcoFalke commented at 5:57 pm on December 14, 2018: member
    utACK f9d10fd2315dd73c8f1c8e6e18c041ebdffdd463
  55. MarcoFalke added the label Tests on Dec 14, 2018
  56. MarcoFalke removed the label Refactoring on Dec 14, 2018
  57. luke-jr commented at 4:41 am on December 20, 2018: member
    Am I the only one who finds it annoying when linters fail on non-bugs?
  58. practicalswift commented at 8:13 am on December 20, 2018: contributor

    @luke-jr In this specific case the alternative and the current situation is that a human reviewer with probability ~100 % will point out that the PR author forgot to add the explicit specifier. The PR author will then add it with probability ~100 % before PR merge since explicit is the reasonable post-C++11 default which we explicitly recommend in the developer notes:

    By default, declare single-argument constructors explicit.

    Rationale: This is a precaution to avoid unintended conversions that might arise when single-argument constructors are used as implicit conversion functions.

    This is one of the most common review comments in my experience. IMO it is better to have it automatically and mechanically fixed by the PR author before human review takes place to minimise the time spent by human reviewers on dull “mechanical review work”.

    Rationale directly from the Bible’s Old Testament^W^W^WC++ Core Guidelines with editors Bjarne Stroustrup and Herb Sutter:

    C.46: By default, declare single-argument constructors explicitReason: To avoid unintended conversions. … Enforcement: (Simple) Single-argument constructors should be declared explicit. Good single argument non-explicit constructors are rare in most code based. Warn for all that are not on a “positive list”.

    :-)

  59. DrahtBot commented at 4:42 pm on January 3, 2019: member
  60. DrahtBot added the label Needs rebase on Jan 3, 2019
  61. practicalswift force-pushed on Jan 4, 2019
  62. practicalswift commented at 7:27 pm on January 4, 2019: contributor
    Rebased! :-) @MarcoFalke @promag Would you mind re-reviewing?
  63. in .travis.yml:100 in 7066019f11 outdated
    61+      install:
    62+        - set -o errexit; source .travis/extended_lint_04_install.sh
    63+      before_script:
    64+        - set -o errexit; source .travis/lint_05_before_script.sh
    65+      script:
    66+        - set -o errexit; source .travis/extended_lint_06_script.sh
    


    Empact commented at 2:37 am on January 5, 2019:
    nit: somewhat prefer the visual separation of whitespace
  64. in .travis.yml:59 in 7066019f11 outdated
    55+    - stage: extended-lint
    56+      name: 'extended lint [runtime >= 60 seconds]'
    57+      env:
    58+      cache: false
    59+      language: python
    60+      python: '3.6'
    


    Empact commented at 2:38 am on January 5, 2019:
    Should this be 3.4, as with lint?
  65. practicalswift force-pushed on Jan 5, 2019
  66. practicalswift commented at 9:09 am on January 5, 2019: contributor
    @Empact Thanks for reviewing. Feedback addressed. Please re-review :-)
  67. fanquake removed the label Needs rebase on Jan 5, 2019
  68. in .travis/extended_lint_04_install.sh:9 in bdd1c9ffe7 outdated
    0@@ -0,0 +1,12 @@
    1+#!/usr/bin/env bash
    2+#
    3+# Copyright (c) 2018 The Bitcoin Core developers
    4+# Distributed under the MIT software license, see the accompanying
    5+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
    6+
    7+export LC_ALL=C
    8+
    9+CPPCHECK_VERSION=1.85
    


    fanquake commented at 9:14 am on January 5, 2019:
    I assume we can use Cppcheck 1.86? Might as well update to the newest version before merging.
  69. in .travis/extended_lint_04_install.sh:3 in bdd1c9ffe7 outdated
    0@@ -0,0 +1,12 @@
    1+#!/usr/bin/env bash
    2+#
    3+# Copyright (c) 2018 The Bitcoin Core developers
    


    fanquake commented at 9:15 am on January 5, 2019:
    Can just use 2019 here, and in all the other new files.
  70. in test/lint/extended-lint-cppcheck.sh:1 in bdd1c9ffe7 outdated
    0@@ -0,0 +1,71 @@
    1+#!/usr/bin/env bash
    


    fanquake commented at 9:15 am on January 5, 2019:
    Missing copyright header.
  71. in test/lint/extended-lint-cppcheck.sh:67 in bdd1c9ffe7 outdated
    57+}
    58+
    59+ENABLED_CHECKS_REGEXP=$(join_array "|" "${ENABLED_CHECKS[@]}")
    60+IGNORED_WARNINGS_REGEXP=$(join_array "|" "${IGNORED_WARNINGS[@]}")
    61+WARNINGS=$(git ls-files -- "*.cpp" "*.h" ":(exclude)src/leveldb/" ":(exclude)src/secp256k1/" ":(exclude)src/univalue/" | \
    62+    xargs cppcheck --enable=all -j "$(nproc)" --language=c++ --std=c++11 --template=gcc -D__cplusplus -DCLIENT_VERSION_BUILD -DCLIENT_VERSION_IS_RELEASE -DCLIENT_VERSION_MAJOR -DCLIENT_VERSION_MINOR -DCLIENT_VERSION_REVISION -DCOPYRIGHT_YEAR -DDEBUG -DHAVE_WORKING_BOOST_SLEEP_FOR -I src/ -q 2>&1 | \
    


    fanquake commented at 9:21 am on January 5, 2019:

    nproc isn’t available on macOS, although if this is script is just meant for Travis I guess it doesn’t matter too much.

    sysctl -n hw.physicalcpu is a macOS nproc equivalent.


    practicalswift commented at 3:26 pm on January 5, 2019:
    Good point: nproc is part of coreutils. I’ve now switched to getconf _NPROCESSORS_ONLN which is the most portable way to get the number of processors AFAIK.
  72. practicalswift force-pushed on Jan 5, 2019
  73. practicalswift force-pushed on Jan 5, 2019
  74. practicalswift commented at 3:52 pm on January 5, 2019: contributor
    @fanquake Thanks for the review and feedback. Feedback addressed. Please re-review :-)
  75. Empact commented at 3:22 am on January 6, 2019: member
    re-utACK 6907678
  76. practicalswift commented at 5:16 pm on January 19, 2019: contributor
    @MarcoFalke @promag Would you mind re-reviewing? :-)
  77. in test/lint/extended-lint-cppcheck.sh:29 in 6907678d72 outdated
    24+    "src/prevector.h:.* Class 'const_iterator' has a constructor with 1 argument that is not explicit."
    25+    "src/prevector.h:.* Class 'const_reverse_iterator' has a constructor with 1 argument that is not explicit."
    26+    "src/prevector.h:.* Class 'iterator' has a constructor with 1 argument that is not explicit."
    27+    "src/prevector.h:.* Class 'reverse_iterator' has a constructor with 1 argument that is not explicit."
    28+    "src/primitives/block.h:.* Class 'CBlock' has a constructor with 1 argument that is not explicit."
    29+    "src/primitives/transaction.h:.* Class 'CTransaction' has a constructor with 1 argument that is not explicit."
    


    MarcoFalke commented at 1:52 am on January 25, 2019:
    this is explicit in master?

    practicalswift commented at 9:37 am on January 25, 2019:

    I’m afraid that suppressions is still needed in master:

    0$ test/lint/extended-lint-cppcheck.sh
    1src/primitives/transaction.h:302: style: Class 'CTransaction' has a constructor with 1 argument that is not explicit.
    2
    3Advice not applicable in this specific case? Add an exception by updating
    4IGNORED_WARNINGS in test/lint/extended-lint-cppcheck.sh
    5$ head -302 src/primitives/transaction.h | tail -1
    6    CTransaction(CMutableTransaction &&tx);
    
  78. practicalswift force-pushed on Jan 25, 2019
  79. practicalswift commented at 9:42 am on January 25, 2019: contributor

    @MarcoFalke Updated. Added suppression src/support/allocators/secure.h:.* style: Struct 'secure_allocator < RNGState >' has a constructor with 1 argument that is not explicit..

    Please re-review :-) I think we’re ready for merge :-)

  80. practicalswift force-pushed on Jan 25, 2019
  81. practicalswift force-pushed on Jan 27, 2019
  82. practicalswift force-pushed on Jan 27, 2019
  83. practicalswift force-pushed on Feb 8, 2019
  84. practicalswift commented at 9:30 am on February 8, 2019: contributor
    Rebased and updated. @MarcoFalke @promag @Empact, would you mind reviewing? :-)
  85. practicalswift commented at 9:16 pm on March 6, 2019: contributor
    @MarcoFalke Can this one get a release milestone? :-)
  86. MarcoFalke commented at 9:30 pm on March 6, 2019: member

    This is controversial in its current form. See #14505 (comment)

    I guess I’d be ok with it if it would never fail (and only print the warnings), like the spell-checker.

  87. in .travis.yml:63 in d5ac0153bc outdated
    53@@ -53,6 +54,19 @@ jobs:
    54       script:
    55         - set -o errexit; source .travis/lint_06_script.sh
    56 
    57+    - stage: extended-lint
    58+      name: 'extended lint [runtime >= 60 seconds]'
    59+      env:
    60+      cache: false
    61+      language: python
    62+      python: '3.4' # Oldest supported version according to doc/dependencies.md
    


    MarcoFalke commented at 9:31 pm on March 6, 2019:
    Needs rebase (and update)
  88. MarcoFalke renamed this:
    Add linter to make sure single parameter constructors are marked explicit (C++11) by default
    test: Add linter to make sure single parameter constructors are marked explicit
    on Mar 6, 2019
  89. practicalswift force-pushed on Mar 6, 2019
  90. practicalswift force-pushed on Mar 6, 2019
  91. practicalswift commented at 9:56 pm on March 6, 2019: contributor
    @MarcoFalke Updated. The updated version never fails: it only prints the warnings – like the spell-checker. Looks good? :-)
  92. MarcoFalke commented at 11:18 pm on March 6, 2019: member
    utACK 2eb79c3601bfb4bff140693b3225aa4779d73390
  93. in test/lint/extended-lint-all.sh:7 in 2eb79c3601 outdated
    0@@ -0,0 +1,26 @@
    1+#!/usr/bin/env bash
    2+#
    3+# Copyright (c) 2019 The Bitcoin Core developers
    4+# Distributed under the MIT software license, see the accompanying
    5+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
    6+#
    7+# This script runs all contrib/devtools/lint-*.sh files, and fails if any exit
    


    Empact commented at 0:03 am on March 13, 2019:
    nit: lint- -> extended-lint-
  94. practicalswift force-pushed on Mar 20, 2019
  95. practicalswift commented at 1:46 pm on March 20, 2019: contributor
    Fixed typo identified by @Empact and squashed. @Empact @MarcoFalke @promag Would you mind re-reviewing? :-)
  96. Add Travis check for single parameter constructors not marked "explicit" c4606b8432
  97. practicalswift force-pushed on Jun 26, 2019
  98. laanwj commented at 6:22 pm on July 8, 2019: member
    ACK c4606b84329d760d7cee144bebe05807857edaae
  99. laanwj merged this on Jul 8, 2019
  100. laanwj closed this on Jul 8, 2019

  101. laanwj referenced this in commit 345f42a9e3 on Jul 8, 2019
  102. in test/lint/extended-lint-cppcheck.sh:78 in c4606b8432
    73+    echo "${WARNINGS}"
    74+    echo
    75+    echo "Advice not applicable in this specific case? Add an exception by updating"
    76+    echo "IGNORED_WARNINGS in $0"
    77+    # Uncomment to enforce the developer note policy "By default, declare single-argument constructors `explicit`"
    78+    # exit 1
    


    MarcoFalke commented at 9:16 pm on July 8, 2019:
    It could be enabled, but guarded by a allow_failures travis flag?
  103. sidhujag referenced this in commit 50942d07a2 on Jul 9, 2019
  104. deadalnix referenced this in commit 09768becd9 on Jun 12, 2020
  105. practicalswift deleted the branch on Apr 10, 2021
  106. Munkybooty referenced this in commit 9d114ebf0f on Nov 4, 2021
  107. Munkybooty referenced this in commit 47710db859 on Nov 4, 2021
  108. Munkybooty referenced this in commit eee2248753 on Nov 6, 2021
  109. Munkybooty referenced this in commit b712f51b21 on Nov 12, 2021
  110. Munkybooty referenced this in commit 7996fb3284 on Nov 16, 2021
  111. Munkybooty referenced this in commit 11615f95d2 on Nov 18, 2021
  112. Munkybooty referenced this in commit d58ff4eb01 on Nov 24, 2021
  113. DrahtBot locked this on Aug 18, 2022

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2024-10-04 22:12 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me