Skip to content
This repository has been archived by the owner on Dec 31, 2020. It is now read-only.

Commit

Permalink
Add checker for MISRA C++:2008 rule 15-5-1
Browse files Browse the repository at this point in the history
  • Loading branch information
rettichschnidi committed Apr 17, 2016
1 parent c39b0ab commit 3991c67
Show file tree
Hide file tree
Showing 6 changed files with 171 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ add_clang_library(clangTidyMISRAModule
src/rules/cpp2008/11-0-1.h
src/rules/cpp2008/12-8-2.cpp
src/rules/cpp2008/12-8-2.h
src/rules/cpp2008/15-5-1.cpp
src/rules/cpp2008/15-5-1.h
src/rules/cpp2008/16-3-1.cpp
src/rules/cpp2008/16-3-1.h
src/rules/cpp2008/16-3-2.cpp
Expand Down
2 changes: 1 addition & 1 deletion doc/cpp2008.md
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ Exception handling - Special functions
======================================
| Rule | Supported by | Remarks |
| ----- | -------------------- | --------------------------------------------- |
|15-5-1 | TBD | |
|15-5-1 | misra-cpp2008-15-5-1 | Not tested on real world code! |
|15-5-2 | TBD | |
|15-5-3 | TBD | |

Expand Down
2 changes: 2 additions & 0 deletions src/MISRATidyModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "rules/cpp2008/10-3-3.h"
#include "rules/cpp2008/11-0-1.h"
#include "rules/cpp2008/12-8-2.h"
#include "rules/cpp2008/15-5-1.h"
#include "rules/cpp2008/16-3-1.h"
#include "rules/cpp2008/16-3-2.h"
#include "rules/cpp2008/17-0-1.h"
Expand Down Expand Up @@ -46,6 +47,7 @@ class MISRAModule : public ClangTidyModule {
CheckFactories.registerCheck<cpp2008::Rule_10_3_3>("misra-cpp2008-10-3-3");
CheckFactories.registerCheck<cpp2008::Rule_11_0_1>("misra-cpp2008-11-0-1");
CheckFactories.registerCheck<cpp2008::Rule_12_8_2>("misra-cpp2008-12-8-2");
CheckFactories.registerCheck<cpp2008::Rule_15_5_1>("misra-cpp2008-15-5-1");
CheckFactories.registerCheck<cpp2008::Rule_16_3_1>("misra-cpp2008-16-3-1");
CheckFactories.registerCheck<cpp2008::Rule_16_3_2>("misra-cpp2008-16-3-2");
CheckFactories.registerCheck<cpp2008::Rule_17_0_1>("misra-cpp2008-17-0-1");
Expand Down
70 changes: 70 additions & 0 deletions src/rules/cpp2008/15-5-1.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
//===--- 15-5-1.cpp - clang-tidy-misra ------------------------------------===//
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "15-5-1.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"

namespace {
template <typename T> const clang::Stmt *searchStmt(const clang::Stmt *S) {
if (!S) {
return nullptr;
}

if (llvm::isa<T>(S)) {
return S;
}

for (auto c : S->children()) {
if (auto b = searchStmt<T>(c)) {
return b;
}
}

return nullptr;
}
}

namespace clang {
namespace tidy {
namespace misra {
namespace cpp2008 {

using namespace clang::ast_matchers;

Rule_15_5_1::Rule_15_5_1(llvm::StringRef Name, ClangTidyContext *Context)
: ClangTidyMisraCheck(Name, Context) {}

void Rule_15_5_1::registerMatchers(ast_matchers::MatchFinder *Finder) {
auto matcher = cxxDestructorDecl().bind("CXXDestructorDecl");
Finder->addMatcher(matcher, this);
}

void Rule_15_5_1::checkImpl(
const ast_matchers::MatchFinder::MatchResult &Result) {
if (const auto *D =
Result.Nodes.getNodeAs<CXXDestructorDecl>("CXXDestructorDecl")) {
// No body -> no error possible!
if (!D->hasBody()) {
return;
}

Stmt *body = D->getBody();
auto cxxThrowStmt = searchStmt<CXXThrowExpr>(body);
auto cxxCatchStmt = searchStmt<CXXCatchStmt>(body);

// dctor throws, check if there's a catch block
if (cxxThrowStmt && !cxxCatchStmt) {
diag(cxxThrowStmt->getLocStart());
}
}
}

} // namespace cpp2008
} // namespace misra
} // namespace tidy
} // namespace clang
31 changes: 31 additions & 0 deletions src/rules/cpp2008/15-5-1.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//===--- 15-5-1.h - clang-tidy-misra ----------------------------*- C++ -*-===//
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef CLANG_TIDY_MISRA_CPP_2008_RULE_15_5_1_H
#define CLANG_TIDY_MISRA_CPP_2008_RULE_15_5_1_H

#include "ClangTidyMisraCheck.h"

namespace clang {
namespace tidy {
namespace misra {
namespace cpp2008 {

class Rule_15_5_1 : public ClangTidyMisraCheck {
public:
Rule_15_5_1(StringRef Name, ClangTidyContext *Context);
virtual void registerMatchers(ast_matchers::MatchFinder *Finder) override;
virtual void
checkImpl(const ast_matchers::MatchFinder::MatchResult &Result) override;
};

} // cpp2008
} // namespace misra
} // namespace tidy
} // namespace clang

#endif // CLANG_TIDY_MISRA_CPP_2008_RULE_15_5_1_H
65 changes: 65 additions & 0 deletions test/cpp2008/15-5-1.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// RUN: %python %S/../check_clang_tidy.py %s misra-cpp2008-15-5-1 %t

#include <stdexcept>

class A {
public:
~A() {
throw std::runtime_error(""); // CHECK-MESSAGES: :[[@LINE]]:5: warning: A class destructor shall not exit with an exception. [misra-cpp2008-15-5-1]
}
};

class B {
public:
~B() {
throw std::runtime_error(""); // CHECK-MESSAGES: :[[@LINE]]:5: warning: A class destructor shall not exit with an exception. [misra-cpp2008-15-5-1]
}
};

class C {
public:
~C();
};

C::~C() {
try {
throw std::runtime_error("");
} catch (const std::exception &ex) { // Compliant
}
}

class D {
~D() noexcept;
};

D::~D() noexcept {
throw std::runtime_error(""); // CHECK-MESSAGES: :[[@LINE]]:3: warning: A class destructor shall not exit with an exception. [misra-cpp2008-15-5-1]
}

class MoreComplicated {
public:
~MoreComplicated() {
if (test()) {
fun();
}
if (test()) {
if (test()) {
fun();
throw std::domain_error(""); // CHECK-MESSAGES: :[[@LINE]]:9: warning: A class destructor shall not exit with an exception. [misra-cpp2008-15-5-1]
}
}
}

void fun() {
for (int i = 0; i < 10; ++i) {
}
}

bool test() {
return true;
}
};

void fun() {
A a;
}

0 comments on commit 3991c67

Please sign in to comment.