Wizard updated this revision to Diff 123089.
Wizard marked 2 inline comments as done.
Wizard added a comment.
address comments
https://reviews.llvm.org/D40058
Files:
clang-tidy/google/AvoidThrowingObjcExceptionCheck.cpp
clang-tidy/google/AvoidThrowingObjcExceptionCheck.h
clang-tidy/google/CMakeLists.txt
clang-tidy/google/GoogleTidyModule.cpp
docs/ReleaseNotes.rst
docs/clang-tidy/checks/google-objc-avoid-throwing-exception.rst
docs/clang-tidy/checks/list.rst
test/clang-tidy/google-objc-avoid-throwing-exception.m
Index: test/clang-tidy/google-objc-avoid-throwing-exception.m
===================================================================
--- /dev/null
+++ test/clang-tidy/google-objc-avoid-throwing-exception.m
@@ -0,0 +1,25 @@
+// RUN: %check_clang_tidy %s google-objc-avoid-throwing-exception %t
+@class NSString;
+
+@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
+
+@end
+
+@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]
+}
+@end
+
Index: docs/clang-tidy/checks/list.rst
===================================================================
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -60,6 +60,7 @@
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
Index: docs/clang-tidy/checks/google-objc-avoid-throwing-exception.rst
===================================================================
--- /dev/null
+++ docs/clang-tidy/checks/google-objc-avoid-throwing-exception.rst
@@ -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
Index: docs/ReleaseNotes.rst
===================================================================
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -57,6 +57,11 @@
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 usage of @throw 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
Index: clang-tidy/google/GoogleTidyModule.cpp
===================================================================
--- clang-tidy/google/GoogleTidyModule.cpp
+++ clang-tidy/google/GoogleTidyModule.cpp
@@ -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 @@
"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>(
Index: clang-tidy/google/CMakeLists.txt
===================================================================
--- clang-tidy/google/CMakeLists.txt
+++ clang-tidy/google/CMakeLists.txt
@@ -2,6 +2,7 @@
add_clang_library(clangTidyGoogleModule
AvoidCStyleCastsCheck.cpp
+ AvoidThrowingObjcExceptionCheck.cpp
DefaultArgumentsCheck.cpp
ExplicitConstructorCheck.cpp
ExplicitMakePairCheck.cpp
Index: clang-tidy/google/AvoidThrowingObjcExceptionCheck.h
===================================================================
--- /dev/null
+++ clang-tidy/google/AvoidThrowingObjcExceptionCheck.h
@@ -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
Index: clang-tidy/google/AvoidThrowingObjcExceptionCheck.cpp
===================================================================
--- /dev/null
+++ clang-tidy/google/AvoidThrowingObjcExceptionCheck.cpp
@@ -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
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits