Index: clang-tidy/misc/CMakeLists.txt =================================================================== --- clang-tidy/misc/CMakeLists.txt +++ clang-tidy/misc/CMakeLists.txt @@ -3,6 +3,7 @@ add_clang_library(clangTidyMiscModule ArgumentCommentCheck.cpp BoolPointerImplicitConversion.cpp + ImplicitArgumentConversion.cpp MiscTidyModule.cpp RedundantSmartptrGet.cpp UseOverride.cpp Index: clang-tidy/misc/ImplicitArgumentConversion.h =================================================================== --- /dev/null +++ clang-tidy/misc/ImplicitArgumentConversion.h @@ -0,0 +1,29 @@ +//===--- ImplicitArgumentConversion.h - clang-tidy --------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_IMPLICIT_ARGUMENT_CONVERSION_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_IMPLICIT_ARGUMENT_CONVERSION_H + +#include "../ClangTidy.h" + +namespace clang { +namespace tidy { + +/// \brief +class ImplicitArgumentConversion : public ClangTidyCheck { +public: + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; +}; + +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_IMPLICIT_ARGUMENT_CONVERSION_H + Index: clang-tidy/misc/ImplicitArgumentConversion.cpp =================================================================== --- /dev/null +++ clang-tidy/misc/ImplicitArgumentConversion.cpp @@ -0,0 +1,59 @@ +//===--- ImplicitArgumentConversion.cpp - clang-tidy ----------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "ImplicitArgumentConversion.h" +#include "clang/AST/TypeOrdering.h" +#include + +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { + +void ImplicitArgumentConversion::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(callExpr().bind("call"), this); +} + +void ImplicitArgumentConversion::check(const MatchFinder::MatchResult &Result) { + auto *Call = Result.Nodes.getStmtAs("call"); + + // Get a set of types of literals that are on the call and a set of the + // corresponding types in the declaration. We only record them if it's coming + // from an implicit conversion of a literal. + std::set DeclTypes; + std::set CallTypes; + unsigned NumConversions = 0; + for (auto *Parm : Call->arguments()) { + // We only care about literals. + const Expr *PP = Parm->IgnoreImpCasts(); + if (!isa(PP) && !isa(PP) && + !isa(PP) && !isa(PP)) + continue; + + DeclTypes.insert(Parm->getType()); + + // If we have an implicit conversion remember it. + if (auto *Cast = dyn_cast(Parm)) { + if (CallTypes.insert(Cast->getSubExpr()->getType()).second) + ++NumConversions; + } else { + CallTypes.insert(Parm->getType()); + } + } + + // We emit a warning if there are two or more implicit conversions. This is + // most likely a swap. + if (NumConversions >= 2 && DeclTypes == CallTypes) { + diag(Call->getLocStart(), + "multiple implicit literal conversions, possibly swapped arguments"); + } +} + +} // namespace tidy +} // namespace clang Index: clang-tidy/misc/MiscTidyModule.cpp =================================================================== --- clang-tidy/misc/MiscTidyModule.cpp +++ clang-tidy/misc/MiscTidyModule.cpp @@ -12,6 +12,7 @@ #include "../ClangTidyModuleRegistry.h" #include "ArgumentCommentCheck.h" #include "BoolPointerImplicitConversion.h" +#include "ImplicitArgumentConversion.h" #include "RedundantSmartptrGet.h" #include "UseOverride.h" @@ -28,6 +29,9 @@ "misc-bool-pointer-implicit-conversion", new ClangTidyCheckFactory()); CheckFactories.addCheckFactory( + "misc-implicit-argument-conversion", + new ClangTidyCheckFactory()); + CheckFactories.addCheckFactory( "misc-redundant-smartptr-get", new ClangTidyCheckFactory()); CheckFactories.addCheckFactory( Index: test/clang-tidy/misc-implicit-argument-conversion.cpp =================================================================== --- /dev/null +++ test/clang-tidy/misc-implicit-argument-conversion.cpp @@ -0,0 +1,14 @@ +// RUN: clang-tidy %s --checks="-*,misc-implicit-argument-conversion" -- 2>&1 | FileCheck %s + +void F(int, double); + +void foo() { +// CHECK: multiple implicit literal conversions + F(1.0, 3); + + F(1.0, 1.0); // no-warning + F(3, 1.0); // no-warning + F(true, false); // no-warning + F(0, 'c'); // no-warning +} +