[clang-tools-extra] r318366 - add check to avoid throwing objc exception according to Google Objective-C guide

Yan Zhang via cfe-commits cfe-commits at lists.llvm.org
Wed Nov 15 17:28:29 PST 2017


Author: wizard
Date: Wed Nov 15 17:28:29 2017
New Revision: 318366

URL: http://llvm.org/viewvc/llvm-project?rev=318366&view=rev
Log:
add check to avoid throwing objc exception according to Google Objective-C guide

Summary:
This is a small check to avoid throwing objc exceptions.
In specific it will detect the usage of @throw statement and throw warning.

Reviewers: hokein, benhamilton

Reviewed By: hokein, benhamilton

Subscribers: cfe-commits, mgorny

Differential Revision: https://reviews.llvm.org/D40058

Added:
    clang-tools-extra/trunk/clang-tidy/google/AvoidThrowingObjCExceptionCheck.cpp
    clang-tools-extra/trunk/clang-tidy/google/AvoidThrowingObjCExceptionCheck.h
    clang-tools-extra/trunk/docs/clang-tidy/checks/google-objc-avoid-throwing-exception.rst
    clang-tools-extra/trunk/test/clang-tidy/google-objc-avoid-throwing-exception.m
Modified:
    clang-tools-extra/trunk/clang-tidy/google/CMakeLists.txt
    clang-tools-extra/trunk/clang-tidy/google/GoogleTidyModule.cpp
    clang-tools-extra/trunk/docs/ReleaseNotes.rst
    clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst

Added: clang-tools-extra/trunk/clang-tidy/google/AvoidThrowingObjCExceptionCheck.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/google/AvoidThrowingObjCExceptionCheck.cpp?rev=318366&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/google/AvoidThrowingObjCExceptionCheck.cpp (added)
+++ clang-tools-extra/trunk/clang-tidy/google/AvoidThrowingObjCExceptionCheck.cpp Wed Nov 15 17:28:29 2017
@@ -0,0 +1,47 @@
+//===--- AvoidThrowingObjCExceptionCheck.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 "AvoidThrowingObjCExceptionCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace google {
+namespace objc {
+
+void AvoidThrowingObjCExceptionCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(objcThrowStmt().bind("throwStmt"), this);
+  Finder->addMatcher(
+      objcMessageExpr(anyOf(hasSelector("raise:format:"),
+                            hasSelector("raise:format:arguments:")),
+                      hasReceiverType(asString("NSException")))
+          .bind("raiseException"),
+      this);
+}
+
+void AvoidThrowingObjCExceptionCheck::check(
+    const MatchFinder::MatchResult &Result) {
+  const auto *MatchedStmt =
+      Result.Nodes.getNodeAs<ObjCAtThrowStmt>("throwStmt");
+  const auto *MatchedExpr =
+      Result.Nodes.getNodeAs<ObjCMessageExpr>("raiseException");
+  auto SourceLoc = MatchedStmt == nullptr ? MatchedExpr->getSelectorStartLoc()
+                                          : MatchedStmt->getThrowLoc();
+  diag(SourceLoc,
+       "pass in NSError ** instead of throwing exception to indicate "
+       "Objective-C errors");
+}
+
+}  // namespace objc
+}  // namespace google
+}  // namespace tidy
+}  // namespace clang

Added: clang-tools-extra/trunk/clang-tidy/google/AvoidThrowingObjCExceptionCheck.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/google/AvoidThrowingObjCExceptionCheck.h?rev=318366&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/google/AvoidThrowingObjCExceptionCheck.h (added)
+++ clang-tools-extra/trunk/clang-tidy/google/AvoidThrowingObjCExceptionCheck.h Wed Nov 15 17:28:29 2017
@@ -0,0 +1,39 @@
+//===--- AvoidThrowingObjCExceptionCheck.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_GOOGLE_OBJC_AVOID_THROWING_EXCEPTION_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_OBJC_AVOID_THROWING_EXCEPTION_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace google {
+namespace objc {
+
+/// The check is to find usage of @throw invocation in Objective-C code.
+/// We should avoid using @throw for Objective-C exceptions according to
+/// the Google Objective-C Style Guide.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/google-objc-avoid-throwing-exception.html
+class AvoidThrowingObjCExceptionCheck : public ClangTidyCheck {
+ public:
+  AvoidThrowingObjCExceptionCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+}  // namespace objc
+}  // namespace google
+}  // namespace tidy
+}  // namespace clang
+
+#endif  // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_OBJC_AVOID_THROWING_EXCEPTION_H

Modified: clang-tools-extra/trunk/clang-tidy/google/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/google/CMakeLists.txt?rev=318366&r1=318365&r2=318366&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/google/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clang-tidy/google/CMakeLists.txt Wed Nov 15 17:28:29 2017
@@ -2,6 +2,7 @@ set(LLVM_LINK_COMPONENTS support)
 
 add_clang_library(clangTidyGoogleModule
   AvoidCStyleCastsCheck.cpp
+  AvoidThrowingObjCExceptionCheck.cpp
   DefaultArgumentsCheck.cpp
   ExplicitConstructorCheck.cpp
   ExplicitMakePairCheck.cpp

Modified: clang-tools-extra/trunk/clang-tidy/google/GoogleTidyModule.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/google/GoogleTidyModule.cpp?rev=318366&r1=318365&r2=318366&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/google/GoogleTidyModule.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/google/GoogleTidyModule.cpp Wed Nov 15 17:28:29 2017
@@ -15,6 +15,7 @@
 #include "../readability/NamespaceCommentCheck.h"
 #include "../readability/RedundantSmartptrGetCheck.h"
 #include "AvoidCStyleCastsCheck.h"
+#include "AvoidThrowingObjCExceptionCheck.h"
 #include "DefaultArgumentsCheck.h"
 #include "ExplicitConstructorCheck.h"
 #include "ExplicitMakePairCheck.h"
@@ -49,6 +50,8 @@ class GoogleModule : public ClangTidyMod
         "google-explicit-constructor");
     CheckFactories.registerCheck<readability::GlobalNamesInHeadersCheck>(
         "google-global-names-in-headers");
+    CheckFactories.registerCheck<objc::AvoidThrowingObjCExceptionCheck>(
+        "google-objc-avoid-throwing-exception");
     CheckFactories.registerCheck<objc::GlobalVariableDeclarationCheck>(
         "google-objc-global-variable-declaration");
     CheckFactories.registerCheck<runtime::IntegerTypesCheck>(

Modified: clang-tools-extra/trunk/docs/ReleaseNotes.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/ReleaseNotes.rst?rev=318366&r1=318365&r2=318366&view=diff
==============================================================================
--- clang-tools-extra/trunk/docs/ReleaseNotes.rst (original)
+++ clang-tools-extra/trunk/docs/ReleaseNotes.rst Wed Nov 15 17:28:29 2017
@@ -57,6 +57,11 @@ The improvements are...
 Improvements to clang-tidy
 --------------------------
 
+- New `google-avoid-throwing-objc-exception
+  <http://clang.llvm.org/extra/clang-tidy/checks/google-objc-avoid-throwing-exception.html>`_ check
+
+  Add new check to detect throwing exceptions in Objective-C code, which should be avoided.
+
 - New `objc-property-declaration
   <http://clang.llvm.org/extra/clang-tidy/checks/objc-property-declaration.html>`_ check
 

Added: clang-tools-extra/trunk/docs/clang-tidy/checks/google-objc-avoid-throwing-exception.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/google-objc-avoid-throwing-exception.rst?rev=318366&view=auto
==============================================================================
--- clang-tools-extra/trunk/docs/clang-tidy/checks/google-objc-avoid-throwing-exception.rst (added)
+++ clang-tools-extra/trunk/docs/clang-tidy/checks/google-objc-avoid-throwing-exception.rst Wed Nov 15 17:28:29 2017
@@ -0,0 +1,38 @@
+.. title:: clang-tidy - google-objc-avoid-throwing-exception
+
+google-objc-avoid-throwing-exception
+====================================
+
+This check finds finds uses of throwing exceptions usages in Objective-C files.
+For the same reason as the Google C++ style guide, we prefer not throwing 
+exceptions from Objective-C code.
+
+The corresponding C++ style guide rule:
+https://google.github.io/styleguide/cppguide.html#Exceptions
+
+Instead, prefer passing in ``NSError **`` and return ``BOOL`` to indicate success or failure.
+
+A counterexample:
+
+.. code-block:: objc
+
+  - (void)readFile {
+    if ([self isError]) {
+      @throw [NSException exceptionWithName:...];
+    }
+  }
+
+Instead, returning an error via ``NSError **`` is preferred:
+
+.. code-block:: objc
+
+  - (BOOL)readFileWithError:(NSError **)error {
+    if ([self isError]) {
+      *error = [NSError errorWithDomain:...];
+      return NO;
+    }
+    return YES;
+  }
+
+The corresponding style guide rule:
+http://google.github.io/styleguide/objcguide.html#avoid-throwing-exceptions

Modified: clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst?rev=318366&r1=318365&r2=318366&view=diff
==============================================================================
--- clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst (original)
+++ clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst Wed Nov 15 17:28:29 2017
@@ -60,6 +60,7 @@ Clang-Tidy Checks
    google-default-arguments
    google-explicit-constructor
    google-global-names-in-headers
+   google-objc-avoid-throwing-exception
    google-objc-global-variable-declaration
    google-readability-braces-around-statements (redirects to readability-braces-around-statements) <google-readability-braces-around-statements>
    google-readability-casting

Added: clang-tools-extra/trunk/test/clang-tidy/google-objc-avoid-throwing-exception.m
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/google-objc-avoid-throwing-exception.m?rev=318366&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/google-objc-avoid-throwing-exception.m (added)
+++ clang-tools-extra/trunk/test/clang-tidy/google-objc-avoid-throwing-exception.m Wed Nov 15 17:28:29 2017
@@ -0,0 +1,32 @@
+// RUN: %check_clang_tidy %s google-objc-avoid-throwing-exception %t
+ at class NSString;
+
+ at interface NSException
+
++ (void)raise:(NSString *)name format:(NSString *)format;
++ (void)raise:(NSString *)name format:(NSString *)format arguments:(NSString *)args; // using NSString type since va_list cannot be recognized here
+
+ at end
+
+ at interface NotException
+
++ (void)raise:(NSString *)name format:(NSString *)format;
+
+ at end
+
+ at implementation Foo
+- (void)f {
+    NSString *foo = @"foo";
+    @throw foo;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: pass in NSError ** instead of throwing exception to indicate Objective-C errors [google-objc-avoid-throwing-exception]
+}
+
+- (void)f2 {
+    [NSException raise:@"TestException" format:@"Test"];
+    // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: pass in NSError ** instead of throwing exception to indicate Objective-C errors [google-objc-avoid-throwing-exception]
+    [NSException raise:@"TestException" format:@"Test %@" arguments:@"bar"];
+    // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: pass in NSError ** instead of throwing exception to indicate Objective-C errors [google-objc-avoid-throwing-exception]
+    [NotException raise:@"NotException" format:@"Test"];
+}
+ at end
+




More information about the cfe-commits mailing list