hgabii created this revision.
hgabii added a reviewer: clang-tools-extra.
hgabii added a project: clang-tools-extra.
Herald added subscribers: cfe-commits, hintonda, mgorny, srhines.

Add misc-io-functions-misused checker to warns for cases when the return value 
of certain standard iostream C functions (fgetwc, getwc, getwchar, 
istream::get()) return int value which is then incorrectly stored in char typed 
values.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D42682

Files:
  clang-tidy/misc/CMakeLists.txt
  clang-tidy/misc/IoFunctionsMisusedCheck.cpp
  clang-tidy/misc/IoFunctionsMisusedCheck.h
  clang-tidy/misc/MiscTidyModule.cpp
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/checks/misc-io-functions-misused.rst
  test/clang-tidy/misc-io-functions-misused.cpp

Index: test/clang-tidy/misc-io-functions-misused.cpp
===================================================================
--- /dev/null
+++ test/clang-tidy/misc-io-functions-misused.cpp
@@ -0,0 +1,74 @@
+// RUN: %check_clang_tidy %s misc-io-functions-misused %t
+
+typedef int wint_t;
+typedef void *FILE;
+
+namespace std {
+wint_t getwchar();
+wint_t getwc(FILE);
+wint_t fgetwc(FILE);
+class istream {
+public:
+  wint_t get();
+};
+} // namespace std
+
+int char_io_getwchar() {
+  char c;
+  c = std::getwchar();
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: consider to cast the return value of 'getwchar' from type integer to type char, possible loss of precision if an error has occurred or the end of file has been reached [misc-io-functions-misused]
+  return c;
+}
+
+int char_io_getwc(FILE *fp) {
+  char c;
+  c = std::getwc(fp);
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: consider to cast the return value of 'getwc' from type integer to type char, possible loss of precision if an error has occurred or the end of file has been reached [misc-io-functions-misused]
+  return c;
+}
+
+int char_io_fgetwc(FILE *fp) {
+  char c;
+  c = std::fgetwc(fp);
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: consider to cast the return value of 'fgetwc' from type integer to type char, possible loss of precision if an error has occurred or the end of file has been reached [misc-io-functions-misused]
+  return c;
+}
+
+int char_io_get(std::istream &is) {
+  char c;
+  c = is.get();
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: consider to cast the return value of 'get' from type integer to type char, possible loss of precision if an error has occurred or the end of file has been reached [misc-io-functions-misused]
+  return c;
+}
+
+void char_type_in_argument(char c) {}
+
+void call_char_type_in_argument_with_getwchar() {
+  char_type_in_argument(std::getwchar());
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: consider to cast the return value of 'getwchar' from type integer to type char, possible loss of precision if an error has occurred or the end of file has been reached [misc-io-functions-misused]
+}
+
+// Negatives
+int int_io_getwchar() {
+  int x;
+  x = std::getwchar();
+  return x;
+}
+
+int int_io_getwc(FILE *fp) {
+  int x;
+  x = std::getwc(fp);
+  return x;
+}
+
+int int_io_fgetwc(FILE *fp) {
+  int x;
+  x = std::fgetwc(fp);
+  return x;
+}
+
+int int_io_get(std::istream &is) {
+  int x;
+  x = is.get();
+  return x;
+}
Index: docs/clang-tidy/checks/misc-io-functions-misused.rst
===================================================================
--- /dev/null
+++ docs/clang-tidy/checks/misc-io-functions-misused.rst
@@ -0,0 +1,34 @@
+.. title:: clang-tidy - misc-io-functions-misused
+
+misc-io-functions-misused
+=========================
+
+This checker warns for cases when the return value of certain standard iostream C functions
+(fgetwc, getwc, getwchar, istream::get()) return int value which is then incorrectly stored 
+in char typed values which can cause overflow at type conversion.
+This check is valid in C and C++.
+
+Checking for implicit cast from integer to char.
+
+.. code-block:: c++
+	
+	char c;
+c = std::getwchar(); // Implicit cast from integer to char
+
+Check will warns for fgetwc, getwc, getwchar functions from global or 'std' namespace
+and will warn for get function from istream.
+
+.. code-block:: c++
+
+	namespace ownnamespace { ... }
+	std::istream is = ...
+	char c;
+c = is.get();                   // Warning about incorrectly stored int value
+        c = ownnamespace::get() // Won't warn
+	
+Check will also warns for incorrectly used functions in parameter passing.
+
+.. code-block:: c++
+	
+	void f(char c){ ...	}
+	f(std::fgetwc( ... ));  //  Warning about passed int value instead of char
Index: docs/clang-tidy/checks/list.rst
===================================================================
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -7,9 +7,9 @@
    android-cloexec-accept
    android-cloexec-accept4
    android-cloexec-creat
+   android-cloexec-dup
    android-cloexec-epoll-create
    android-cloexec-epoll-create1
-   android-cloexec-dup
    android-cloexec-fopen
    android-cloexec-inotify-init
    android-cloexec-inotify-init1
@@ -38,7 +38,7 @@
    cert-msc30-c (redirects to cert-msc50-cpp) <cert-msc30-c>
    cert-msc50-cpp
    cert-oop11-cpp (redirects to misc-move-constructor-init) <cert-oop11-cpp>
-   cppcoreguidelines-c-copy-assignment-signature
+   cppcoreguidelines-c-copy-assignment-signature (redirects to misc-unconventional-assign-operator) <cppcoreguidelines-c-copy-assignment-signature>
    cppcoreguidelines-interfaces-global-init
    cppcoreguidelines-no-malloc
    cppcoreguidelines-pro-bounds-array-to-pointer-decay
@@ -100,6 +100,7 @@
    misc-inaccurate-erase
    misc-incorrect-roundings
    misc-inefficient-algorithm
+   misc-io-functions-misused
    misc-lambda-function-name
    misc-macro-parentheses
    misc-macro-repeated-side-effects
Index: docs/ReleaseNotes.rst
===================================================================
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -57,6 +57,12 @@
 Improvements to clang-tidy
 --------------------------
 
+- New `misc-io-functions-misused
+  <http://clang.llvm.org/extra/clang-tidy/checks/misc-io-functions-misused.html>`_ check
+
+  Check if the fgetwc, getwc, getwchar, istream::get standard iostream C functions 
+  return values incorrectly stored in char type value.
+
 - Renamed checks to use correct term "implicit conversion" instead of "implicit
   cast" and modified messages and option names accordingly:
 
Index: clang-tidy/misc/MiscTidyModule.cpp
===================================================================
--- clang-tidy/misc/MiscTidyModule.cpp
+++ clang-tidy/misc/MiscTidyModule.cpp
@@ -21,6 +21,7 @@
 #include "InaccurateEraseCheck.h"
 #include "IncorrectRoundings.h"
 #include "InefficientAlgorithmCheck.h"
+#include "IoFunctionsMisusedCheck.h"
 #include "LambdaFunctionNameCheck.h"
 #include "MacroParenthesesCheck.h"
 #include "MacroRepeatedSideEffectsCheck.h"
@@ -69,6 +70,8 @@
         "misc-assert-side-effect");
     CheckFactories.registerCheck<ForwardingReferenceOverloadCheck>(
         "misc-forwarding-reference-overload");
+    CheckFactories.registerCheck<IoFunctionsMisusedCheck>(
+        "misc-io-functions-misused");
     CheckFactories.registerCheck<LambdaFunctionNameCheck>(
         "misc-lambda-function-name");
     CheckFactories.registerCheck<MisplacedConstCheck>("misc-misplaced-const");
Index: clang-tidy/misc/IoFunctionsMisusedCheck.h
===================================================================
--- /dev/null
+++ clang-tidy/misc/IoFunctionsMisusedCheck.h
@@ -0,0 +1,38 @@
+//===--- IoFunctionsMisusedCheck.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_IO_FUNCTIONS_MISUSED_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_IO_FUNCTIONS_MISUSED_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace misc {
+
+/// This checker warns for cases when the return value of certain standard
+/// iostream C functions (fgetwc, getwc, getwchar, istream::get()) return int
+/// value which is then incorrectly stored in char typed values which can cause
+/// overflow at type conversion.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/misc-io-functions-misused.html
+class IoFunctionsMisusedCheck : public ClangTidyCheck {
+public:
+  IoFunctionsMisusedCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace misc
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_IO_FUNCTIONS_MISUSED_H
Index: clang-tidy/misc/IoFunctionsMisusedCheck.cpp
===================================================================
--- /dev/null
+++ clang-tidy/misc/IoFunctionsMisusedCheck.cpp
@@ -0,0 +1,65 @@
+//===--- IoFunctionsMisusedCheck.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 "IoFunctionsMisusedCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace misc {
+
+void IoFunctionsMisusedCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(
+      implicitCastExpr(
+          hasImplicitDestinationType(isAnyCharacter()),
+          anyOf(
+              has(callExpr(callee(
+                  functionDecl(hasAnyName("::getwchar", "::getwc", "::fgetwc"))
+                      .bind("FuncDeclInGlobal")))),
+              has(callExpr(callee(
+                  functionDecl(hasAnyName("::std::getwchar", "::std::getwc",
+                                          "::std::fgetwc"))
+                      .bind("FuncDeclInStd")))),
+              has(cxxMemberCallExpr(
+                  on(hasType(namedDecl(matchesName("istream")))),
+                  callee(cxxMethodDecl(hasName("get")).bind("Decl"))))),
+          hasCastKind(CK_IntegralCast))
+          .bind("ImplicitCast"),
+      this);
+}
+
+void IoFunctionsMisusedCheck::check(const MatchFinder::MatchResult &Result) {
+  const auto *MatchedImplicitCastToChar =
+      Result.Nodes.getNodeAs<ImplicitCastExpr>("ImplicitCast");
+  const auto *FuncDeclInStd =
+      Result.Nodes.getNodeAs<FunctionDecl>("FuncDeclInStd");
+  const auto *FuncDeclInGlobal =
+      Result.Nodes.getNodeAs<FunctionDecl>("FuncDeclInGlobal");
+  const auto *MatchedDecl = Result.Nodes.getNodeAs<CXXMethodDecl>("Decl");
+
+  auto Diag = diag(
+      MatchedImplicitCastToChar->getLocStart(),
+      "consider to cast the return value of %0 from type integer to type char, "
+      "possible loss of precision if an error has occurred or the end "
+      "of file has been reached");
+
+  if (FuncDeclInStd)
+    Diag << FuncDeclInStd;
+  else if (FuncDeclInGlobal)
+    Diag << FuncDeclInGlobal;
+  else
+    Diag << MatchedDecl;
+}
+
+} // namespace misc
+} // namespace tidy
+} // namespace clang
Index: clang-tidy/misc/CMakeLists.txt
===================================================================
--- clang-tidy/misc/CMakeLists.txt
+++ clang-tidy/misc/CMakeLists.txt
@@ -4,6 +4,7 @@
   ArgumentCommentCheck.cpp
   AssertSideEffectCheck.cpp
   ForwardingReferenceOverloadCheck.cpp
+  IoFunctionsMisusedCheck.cpp
   LambdaFunctionNameCheck.cpp
   MisplacedConstCheck.cpp
   UnconventionalAssignOperatorCheck.cpp
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to