mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-01 09:41:08 +00:00
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 llvm-svn: 318366
This commit is contained in:
parent
35019dbe6b
commit
9994581395
@ -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
|
@ -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
|
@ -2,6 +2,7 @@ set(LLVM_LINK_COMPONENTS support)
|
||||
|
||||
add_clang_library(clangTidyGoogleModule
|
||||
AvoidCStyleCastsCheck.cpp
|
||||
AvoidThrowingObjCExceptionCheck.cpp
|
||||
DefaultArgumentsCheck.cpp
|
||||
ExplicitConstructorCheck.cpp
|
||||
ExplicitMakePairCheck.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 @@ class GoogleModule : public ClangTidyModule {
|
||||
"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>(
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
@ -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
|
||||
|
@ -0,0 +1,32 @@
|
||||
// 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
|
||||
|
||||
@interface NotException
|
||||
|
||||
+ (void)raise:(NSString *)name format:(NSString *)format;
|
||||
|
||||
@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]
|
||||
[NotException raise:@"NotException" format:@"Test"];
|
||||
}
|
||||
@end
|
||||
|
Loading…
Reference in New Issue
Block a user