[clang-tools-extra] r254415 - Add a new checker, cert-err58-cpp, that checks for static or thread_local objects that use a throwing constructor.

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Tue Dec 1 06:05:39 PST 2015


Author: aaronballman
Date: Tue Dec  1 08:05:39 2015
New Revision: 254415

URL: http://llvm.org/viewvc/llvm-project?rev=254415&view=rev
Log:
Add a new checker, cert-err58-cpp, that checks for static or thread_local objects that use a throwing constructor.

This check corresponds to the CERT secure coding rule: https://www.securecoding.cert.org/confluence/display/cplusplus/ERR58-CPP.+Constructors+of+objects+with+static+or+thread+storage+duration+must+not+throw+exceptions

Added:
    clang-tools-extra/trunk/clang-tidy/cert/StaticObjectExceptionCheck.cpp
    clang-tools-extra/trunk/clang-tidy/cert/StaticObjectExceptionCheck.h
    clang-tools-extra/trunk/docs/clang-tidy/checks/cert-static-object-exception.rst
    clang-tools-extra/trunk/test/clang-tidy/cert-static-object-exception.cpp
Modified:
    clang-tools-extra/trunk/clang-tidy/cert/CERTTidyModule.cpp
    clang-tools-extra/trunk/clang-tidy/cert/CMakeLists.txt
    clang-tools-extra/trunk/clang-tidy/cert/ThrownExceptionTypeCheck.cpp
    clang-tools-extra/trunk/clang-tidy/utils/Matchers.h
    clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst

Modified: clang-tools-extra/trunk/clang-tidy/cert/CERTTidyModule.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cert/CERTTidyModule.cpp?rev=254415&r1=254414&r2=254415&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/cert/CERTTidyModule.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/cert/CERTTidyModule.cpp Tue Dec  1 08:05:39 2015
@@ -17,6 +17,7 @@
 #include "../misc/StaticAssertCheck.h"
 #include "../misc/ThrowByValueCatchByReferenceCheck.h"
 #include "SetLongJmpCheck.h"
+#include "StaticObjectExceptionCheck.h"
 #include "ThrownExceptionTypeCheck.h"
 #include "VariadicFunctionDefCheck.h"
 
@@ -41,6 +42,8 @@ public:
     // ERR
     CheckFactories.registerCheck<SetLongJmpCheck>(
         "cert-err52-cpp");
+    CheckFactories.registerCheck<StaticObjectExceptionCheck>(
+        "cert-err58-cpp");
     CheckFactories.registerCheck<ThrownExceptionTypeCheck>(
         "cert-err60-cpp");
     CheckFactories.registerCheck<ThrowByValueCatchByReferenceCheck>(

Modified: clang-tools-extra/trunk/clang-tidy/cert/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cert/CMakeLists.txt?rev=254415&r1=254414&r2=254415&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/cert/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clang-tidy/cert/CMakeLists.txt Tue Dec  1 08:05:39 2015
@@ -3,6 +3,7 @@ set(LLVM_LINK_COMPONENTS support)
 add_clang_library(clangTidyCERTModule
   CERTTidyModule.cpp
   SetLongJmpCheck.cpp
+  StaticObjectExceptionCheck.cpp
   ThrownExceptionTypeCheck.cpp
   VariadicFunctionDefCheck.cpp
 
@@ -14,4 +15,5 @@ add_clang_library(clangTidyCERTModule
   clangTidy
   clangTidyGoogleModule
   clangTidyMiscModule
+  clangTidyUtils
   )

Added: clang-tools-extra/trunk/clang-tidy/cert/StaticObjectExceptionCheck.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cert/StaticObjectExceptionCheck.cpp?rev=254415&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/cert/StaticObjectExceptionCheck.cpp (added)
+++ clang-tools-extra/trunk/clang-tidy/cert/StaticObjectExceptionCheck.cpp Tue Dec  1 08:05:39 2015
@@ -0,0 +1,49 @@
+//===--- StaticObjectExceptionCheck.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 "StaticObjectExceptionCheck.h"
+#include "../utils/Matchers.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+
+void StaticObjectExceptionCheck::registerMatchers(MatchFinder *Finder) {
+  if (!getLangOpts().CPlusPlus)
+    return;
+
+  // Match any static or thread_local variable declaration that is initialized
+  // with a constructor that can throw.
+  Finder->addMatcher(
+      varDecl(anyOf(hasThreadStorageDuration(), hasStaticStorageDuration()),
+              hasInitializer(cxxConstructExpr(hasDeclaration(
+                  cxxConstructorDecl(unless(matchers::isNoThrow()))
+                      .bind("ctor")))))
+          .bind("var"),
+      this);
+}
+
+void StaticObjectExceptionCheck::check(const MatchFinder::MatchResult &Result) {
+  const auto *VD = Result.Nodes.getNodeAs<VarDecl>("var");
+  const auto *Ctor = Result.Nodes.getNodeAs<CXXConstructorDecl>("ctor");
+
+  diag(VD->getLocation(),
+       "construction of %0 with %select{static|thread_local}1 storage "
+       "duration may throw an exception that cannot be caught")
+      << VD << (VD->getStorageDuration() == SD_Static ? 0 : 1);
+  diag(Ctor->getLocation(), "possibly throwing constructor declared here",
+       DiagnosticIDs::Note);
+}
+
+} // namespace tidy
+} // namespace clang
+

Added: clang-tools-extra/trunk/clang-tidy/cert/StaticObjectExceptionCheck.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cert/StaticObjectExceptionCheck.h?rev=254415&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/cert/StaticObjectExceptionCheck.h (added)
+++ clang-tools-extra/trunk/clang-tidy/cert/StaticObjectExceptionCheck.h Tue Dec  1 08:05:39 2015
@@ -0,0 +1,35 @@
+//===--- StaticObjectExceptionCheck.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_CERT_ERR58_CPP_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_ERR58_CPP_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+
+/// Checks whether the constructor for a static or thread_local object will
+/// throw.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/cert-static-object-exception.html
+class StaticObjectExceptionCheck : public ClangTidyCheck {
+public:
+  StaticObjectExceptionCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_ERR58_CPP_H
+

Modified: clang-tools-extra/trunk/clang-tidy/cert/ThrownExceptionTypeCheck.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cert/ThrownExceptionTypeCheck.cpp?rev=254415&r1=254414&r2=254415&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/cert/ThrownExceptionTypeCheck.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/cert/ThrownExceptionTypeCheck.cpp Tue Dec  1 08:05:39 2015
@@ -8,26 +8,13 @@
 //===----------------------------------------------------------------------===//
 
 #include "ThrownExceptionTypeCheck.h"
+#include "../utils/Matchers.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 
 using namespace clang::ast_matchers;
 
 namespace clang {
-namespace {
-AST_MATCHER(CXXConstructorDecl, isNoThrowCopyConstructor) {
-  if (!Node.isCopyConstructor())
-    return false;
-
-  const auto *FnTy = Node.getType()->getAs<FunctionProtoType>();
-  // Assume the best for any unresolved exception specification.
-  if (isUnresolvedExceptionSpec(FnTy->getExceptionSpecType()))
-    return true;
-
-  return FnTy->isNothrow(Node.getASTContext());
-}
-} // end namespace
-
 namespace tidy {
 void ThrownExceptionTypeCheck::registerMatchers(MatchFinder *Finder) {
   if (!getLangOpts().CPlusPlus)
@@ -36,7 +23,7 @@ void ThrownExceptionTypeCheck::registerM
   Finder->addMatcher(
       cxxThrowExpr(
           has(cxxConstructExpr(hasDeclaration(cxxConstructorDecl(
-              isCopyConstructor(), unless(isNoThrowCopyConstructor()))))
+              isCopyConstructor(), unless(matchers::isNoThrow()))))
           .bind("expr"))),
       this);
 }

Modified: clang-tools-extra/trunk/clang-tidy/utils/Matchers.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/utils/Matchers.h?rev=254415&r1=254414&r2=254415&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/utils/Matchers.h (original)
+++ clang-tools-extra/trunk/clang-tidy/utils/Matchers.h Tue Dec  1 08:05:39 2015
@@ -23,6 +23,22 @@ AST_MATCHER(QualType, isExpensiveToCopy)
   return IsExpensive && *IsExpensive;
 }
 
+AST_MATCHER(FunctionDecl, isNoThrow) {
+  const auto *FnTy = Node.getType()->getAs<FunctionProtoType>();
+  
+  // If the function does not have a prototype, then it is assumed to be a
+  // throwing function (as it would if the function did not have any exception
+  // specification).
+  if (!FnTy)
+    return false;
+
+  // Assume the best for any unresolved exception specification.
+  if (isUnresolvedExceptionSpec(FnTy->getExceptionSpecType()))
+    return true;
+
+  return FnTy->isNothrow(Node.getASTContext());
+}
+
 } // namespace matchers
 } // namespace tidy
 } // namespace clang

Added: clang-tools-extra/trunk/docs/clang-tidy/checks/cert-static-object-exception.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/cert-static-object-exception.rst?rev=254415&view=auto
==============================================================================
--- clang-tools-extra/trunk/docs/clang-tidy/checks/cert-static-object-exception.rst (added)
+++ clang-tools-extra/trunk/docs/clang-tidy/checks/cert-static-object-exception.rst Tue Dec  1 08:05:39 2015
@@ -0,0 +1,9 @@
+cert-err58-cpp
+==============
+
+This check flags all static or thread_local variable declarations where the
+constructor for the object may throw an exception.
+
+This check corresponds to the CERT C++ Coding Standard rule
+`ERR58-CPP. Constructors of objects with static or thread storage duration must not throw exceptions
+<https://www.securecoding.cert.org/confluence/display/cplusplus/ERR58-CPP.+Constructors+of+objects+with+static+or+thread+storage+duration+must+not+throw+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=254415&r1=254414&r2=254415&view=diff
==============================================================================
--- clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst (original)
+++ clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst Tue Dec  1 08:05:39 2015
@@ -1,8 +1,9 @@
 List of clang-tidy Checks
 =========================
 
-.. toctree::
+.. toctree::   
    cert-setlongjmp
+   cert-static-object-exception
    cert-thrown-exception-type
    cert-variadic-function-def
    cppcoreguidelines-pro-bounds-array-to-pointer-decay

Added: clang-tools-extra/trunk/test/clang-tidy/cert-static-object-exception.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/cert-static-object-exception.cpp?rev=254415&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/cert-static-object-exception.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/cert-static-object-exception.cpp Tue Dec  1 08:05:39 2015
@@ -0,0 +1,52 @@
+// RUN: %check_clang_tidy %s cert-err58-cpp %t
+
+struct S {
+  S() noexcept(false);
+};
+
+struct T {
+  T() noexcept;
+};
+
+struct U {
+  U() {}
+};
+
+struct V {
+  explicit V(const char *) {} // Can throw
+};
+
+
+S s;
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: construction of 's' with static storage duration may throw an exception that cannot be caught [cert-err58-cpp]
+// CHECK-MESSAGES: 4:3: note: possibly throwing constructor declared here
+T t; // ok
+U u;
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: construction of 'u' with static storage duration may throw an exception that cannot be caught
+// CHECK-MESSAGES: 12:3: note: possibly throwing constructor declared here
+V v("v");
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: construction of 'v' with static storage duration may throw an exception that cannot be caught
+// CHECK-MESSAGES: 16:12: note: possibly throwing constructor declared here
+
+void f(S s1, T t1, U u1, V v1) { // ok, ok, ok, ok
+  S s2; // ok
+  T t2; // ok
+  U u2; // ok
+  V v2("v"); // ok
+
+  thread_local S s3;
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: construction of 's3' with thread_local storage duration may throw an exception that cannot be caught
+  thread_local T t3; // ok
+  thread_local U u3;
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: construction of 'u3' with thread_local storage duration may throw an exception that cannot be caught
+  thread_local V v3("v");
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: construction of 'v3' with thread_local storage duration may throw an exception that cannot be caught
+
+  static S s4;
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: construction of 's4' with static storage duration may throw an exception that cannot be caught
+  static T t4; // ok
+  static U u4;
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: construction of 'u4' with static storage duration may throw an exception that cannot be caught
+  static V v4("v");
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: construction of 'v4' with static storage duration may throw an exception that cannot be caught
+}




More information about the cfe-commits mailing list