Re: [PATCH] D43120: [clang-tidy] New checker for exceptions that are created but not thrown
On Thu, Feb 15, 2018 at 3:48 PM, Aaron Ballman via cfe-commits wrote: > On Thu, Feb 15, 2018 at 4:11 AM, Phabricator via Phabricator > wrote: >> This revision was automatically updated to reflect the committed changes. >> Closed by commit rL325222: [clang-tidy] New checker for exceptions that are >> created but not thrown (authored by xazax, committed by ). > > There's nothing wrong with this patch, but it is odd that the > automated text describes the author but not the committer. I wonder if > that's a bug? Committed xazax Thu, Feb 15, 12:08 But there is no https://reviews.llvm.org/p/xazax/, only https://reviews.llvm.org/p/xazax.hun/ I get that too. Because committer name (i.e. svn username) does not verbatim match the Phab username verbatim. It is a bug i'd say, the match should be email-based. > ~Aaron Roman. > ___ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D43120: [clang-tidy] New checker for exceptions that are created but not thrown
On Thu, Feb 15, 2018 at 4:11 AM, Phabricator via Phabricator wrote: > This revision was automatically updated to reflect the committed changes. > Closed by commit rL325222: [clang-tidy] New checker for exceptions that are > created but not thrown (authored by xazax, committed by ). There's nothing wrong with this patch, but it is odd that the automated text describes the author but not the committer. I wonder if that's a bug? ~Aaron ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D43120: [clang-tidy] New checker for exceptions that are created but not thrown
This revision was automatically updated to reflect the committed changes. Closed by commit rL325222: [clang-tidy] New checker for exceptions that are created but not thrown (authored by xazax, committed by ). Herald added subscribers: llvm-commits, klimek. Changed prior to commit: https://reviews.llvm.org/D43120?vs=134174&id=134389#toc Repository: rL LLVM https://reviews.llvm.org/D43120 Files: clang-tools-extra/trunk/clang-tidy/bugprone/BugproneTidyModule.cpp clang-tools-extra/trunk/clang-tidy/bugprone/CMakeLists.txt clang-tools-extra/trunk/clang-tidy/bugprone/ThrowKeywordMissingCheck.cpp clang-tools-extra/trunk/clang-tidy/bugprone/ThrowKeywordMissingCheck.h clang-tools-extra/trunk/docs/ReleaseNotes.rst clang-tools-extra/trunk/docs/clang-tidy/checks/bugprone-throw-keyword-missing.rst clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst clang-tools-extra/trunk/test/clang-tidy/bugprone-throw-keyword-missing.cpp Index: clang-tools-extra/trunk/clang-tidy/bugprone/ThrowKeywordMissingCheck.h === --- clang-tools-extra/trunk/clang-tidy/bugprone/ThrowKeywordMissingCheck.h +++ clang-tools-extra/trunk/clang-tidy/bugprone/ThrowKeywordMissingCheck.h @@ -0,0 +1,36 @@ +//===--- ThrowKeywordMissingCheck.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_BUGPRONE_THROWKEYWORDMISSINGCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_THROWKEYWORDMISSINGCHECK_H + +#include "../ClangTidy.h" + +namespace clang { +namespace tidy { +namespace bugprone { + +/// Emits a warning about temporary objects whose type is (or is derived from) a +/// class that has 'EXCEPTION', 'Exception' or 'exception' in its name. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/bugprone-throw-keyword-missing.html +class ThrowKeywordMissingCheck : public ClangTidyCheck { +public: + ThrowKeywordMissingCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; +}; + +} // namespace bugprone +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_THROWKEYWORDMISSINGCHECK_H Index: clang-tools-extra/trunk/clang-tidy/bugprone/BugproneTidyModule.cpp === --- clang-tools-extra/trunk/clang-tidy/bugprone/BugproneTidyModule.cpp +++ clang-tools-extra/trunk/clang-tidy/bugprone/BugproneTidyModule.cpp @@ -25,6 +25,7 @@ #include "MultipleStatementMacroCheck.h" #include "StringConstructorCheck.h" #include "SuspiciousMemsetUsageCheck.h" +#include "ThrowKeywordMissingCheck.h" #include "UndefinedMemoryManipulationCheck.h" #include "UseAfterMoveCheck.h" #include "VirtualNearMissCheck.h" @@ -66,6 +67,8 @@ "bugprone-string-constructor"); CheckFactories.registerCheck( "bugprone-suspicious-memset-usage"); +CheckFactories.registerCheck( +"bugprone-throw-keyword-missing"); CheckFactories.registerCheck( "bugprone-undefined-memory-manipulation"); CheckFactories.registerCheck( Index: clang-tools-extra/trunk/clang-tidy/bugprone/ThrowKeywordMissingCheck.cpp === --- clang-tools-extra/trunk/clang-tidy/bugprone/ThrowKeywordMissingCheck.cpp +++ clang-tools-extra/trunk/clang-tidy/bugprone/ThrowKeywordMissingCheck.cpp @@ -0,0 +1,52 @@ +//===--- ThrowKeywordMissingCheck.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 "ThrowKeywordMissingCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { +namespace bugprone { + +void ThrowKeywordMissingCheck::registerMatchers(MatchFinder *Finder) { + if (!getLangOpts().CPlusPlus) +return; + + auto CtorInitializerList = + cxxConstructorDecl(hasAnyConstructorInitializer(anything())); + + Finder->addMatcher( + expr(anyOf(cxxFunctionalCastExpr(), cxxBindTemporaryExpr(), + cxxTemporaryObjectExpr()), + hasType(cxxRecordDecl( + isSameOrDerivedFrom(matchesName("[Ee]xception|EXCEPTION", + unless(anyOf(hasAncestor(stmt( +anyOf
[PATCH] D43120: [clang-tidy] New checker for exceptions that are created but not thrown
aaron.ballman accepted this revision. aaron.ballman added a comment. This revision is now accepted and ready to land. LGTM, thank you! https://reviews.llvm.org/D43120 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D43120: [clang-tidy] New checker for exceptions that are created but not thrown
Szelethus added a comment. Just noticed that I can't mark your inline comment as done, since the file got renamed. The typo is also fixed (Classname -> Class name). https://reviews.llvm.org/D43120 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D43120: [clang-tidy] New checker for exceptions that are created but not thrown
Szelethus updated this revision to Diff 134174. Szelethus added a comment. Renamed the checker from `misc-throw-keyword-missing` to `bugprone-throw-keyword-missing`. https://reviews.llvm.org/D43120 Files: clang-tidy/bugprone/BugproneTidyModule.cpp clang-tidy/bugprone/CMakeLists.txt clang-tidy/bugprone/ThrowKeywordMissingCheck.cpp clang-tidy/bugprone/ThrowKeywordMissingCheck.h docs/ReleaseNotes.rst docs/clang-tidy/checks/bugprone-throw-keyword-missing.rst docs/clang-tidy/checks/list.rst test/clang-tidy/bugprone-throw-keyword-missing.cpp Index: test/clang-tidy/bugprone-throw-keyword-missing.cpp === --- /dev/null +++ test/clang-tidy/bugprone-throw-keyword-missing.cpp @@ -0,0 +1,167 @@ +// RUN: %check_clang_tidy %s bugprone-throw-keyword-missing %t + +namespace std { + +// std::string declaration (taken from test/clang-tidy/readability-redundant-string-cstr-msvc.cpp). +template +class allocator {}; +template +class char_traits {}; +template , typename A = std::allocator> +struct basic_string { + basic_string(); + basic_string(const basic_string &); + // MSVC headers define two constructors instead of using optional arguments. + basic_string(const C *); + basic_string(const C *, const A &); + ~basic_string(); +}; +typedef basic_string string; +typedef basic_string wstring; + +// std::exception and std::runtime_error declaration. +struct exception { + exception(); + exception(const exception &other); + virtual ~exception(); +}; + +struct runtime_error : public exception { + explicit runtime_error(const std::string &what_arg); +}; + +} // namespace std + +// The usage of this class should never emit a warning. +struct RegularClass {}; + +// Class name contains the substring "exception", in certain cases using this class should emit a warning. +struct RegularException { + RegularException() {} + + // Constructors with a single argument are treated differently (cxxFunctionalCastExpr). + RegularException(int) {} +}; + +// -- + +void stdExceptionNotTrownTest(int i) { + if (i < 0) +// CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception object created but not thrown; did you mean 'throw {{.*}}'? [bugprone-throw-keyword-missing] +std::exception(); + + if (i > 0) +// CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception +std::runtime_error("Unexpected argument"); +} + +void stdExceptionThrownTest(int i) { + if (i < 0) +throw std::exception(); + + if (i > 0) +throw std::runtime_error("Unexpected argument"); +} + +void regularClassNotThrownTest(int i) { + if (i < 0) +RegularClass(); +} + +void regularClassThrownTest(int i) { + if (i < 0) +throw RegularClass(); +} + +void nameContainsExceptionNotThrownTest(int i) { + if (i < 0) +// CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception +RegularException(); + + if (i > 0) +// CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception +RegularException(5); +} + +void nameContainsExceptionThrownTest(int i) { + if (i < 0) +throw RegularException(); + + if (i > 0) +throw RegularException(5); +} + +template +void f(int i, Exception excToBeThrown) {} + +void funcCallWithTempExcTest() { + f(5, RegularException()); +} + +// Global variable initilization test. +RegularException exc = RegularException(); +RegularException *excptr = new RegularException(); + +void localVariableInitTest() { + RegularException exc = RegularException(); + RegularException *excptr = new RegularException(); +} + +class CtorInitializerListTest { + RegularException exc; + + CtorInitializerListTest() : exc(RegularException()) {} + + CtorInitializerListTest(int) try : exc(RegularException()) { +// Constructor body + } catch (...) { +// CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception +RegularException(); + } + + CtorInitializerListTest(float); +}; + +CtorInitializerListTest::CtorInitializerListTest(float) try : exc(RegularException()) { + // Constructor body +} catch (...) { + // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: suspicious exception + RegularException(); +} + +RegularException funcReturningExceptionTest(int i) { + return RegularException(); +} + +void returnedValueTest() { + funcReturningExceptionTest(3); +} + +struct ClassBracedInitListTest { + ClassBracedInitListTest(RegularException exc) {} +}; + +void foo(RegularException, ClassBracedInitListTest) {} + +void bracedInitListTest() { + RegularException exc{}; + ClassBracedInitListTest test = {RegularException()}; + foo({}, {RegularException()}); +} + +typedef std::exception ERROR_BASE; +class RegularError : public ERROR_BASE {}; + +void typedefTest() { + // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: suspicious exception + RegularError(); +} + +struct ExceptionRAII { + ExceptionRAII() {} + ~ExceptionRAII() {} +}; + +void exceptionRAIITest() { + ExceptionRAII E; +} Index: docs/clang-tidy/checks/list.rst =
[PATCH] D43120: [clang-tidy] New checker for exceptions that are created but not thrown
aaron.ballman requested changes to this revision. aaron.ballman added a comment. This revision now requires changes to proceed. I apologize for not noticing this important detail earlier -- I think this check should live under `bugprone` rather than `misc`. Other than where it lives (and the related naming issues), I think this is looking good! Comment at: test/clang-tidy/misc-throw-keyword-missing.cpp:38 + +// Classname contains the substring "exception", in certain cases using this class should emit a warning. +struct RegularException { Classname -> Class name https://reviews.llvm.org/D43120 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D43120: [clang-tidy] New checker for exceptions that are created but not thrown
Szelethus updated this revision to Diff 134005. https://reviews.llvm.org/D43120 Files: clang-tidy/misc/CMakeLists.txt clang-tidy/misc/MiscTidyModule.cpp clang-tidy/misc/ThrowKeywordMissingCheck.cpp clang-tidy/misc/ThrowKeywordMissingCheck.h docs/ReleaseNotes.rst docs/clang-tidy/checks/list.rst docs/clang-tidy/checks/misc-throw-keyword-missing.rst test/clang-tidy/misc-throw-keyword-missing.cpp Index: test/clang-tidy/misc-throw-keyword-missing.cpp === --- /dev/null +++ test/clang-tidy/misc-throw-keyword-missing.cpp @@ -0,0 +1,167 @@ +// RUN: %check_clang_tidy %s misc-throw-keyword-missing %t + +namespace std { + +// std::string declaration (taken from test/clang-tidy/readability-redundant-string-cstr-msvc.cpp). +template +class allocator {}; +template +class char_traits {}; +template , typename A = std::allocator> +struct basic_string { + basic_string(); + basic_string(const basic_string &); + // MSVC headers define two constructors instead of using optional arguments. + basic_string(const C *); + basic_string(const C *, const A &); + ~basic_string(); +}; +typedef basic_string string; +typedef basic_string wstring; + +// std::exception and std::runtime_error declaration. +struct exception { + exception(); + exception(const exception &other); + virtual ~exception(); +}; + +struct runtime_error : public exception { + explicit runtime_error(const std::string &what_arg); +}; + +} // namespace std + +// The usage of this class should never emit a warning. +struct RegularClass {}; + +// Classname contains the substring "exception", in certain cases using this class should emit a warning. +struct RegularException { + RegularException() {} + + // Constructors with a single argument are treated differently (cxxFunctionalCastExpr). + RegularException(int) {} +}; + +// -- + +void stdExceptionNotTrownTest(int i) { + if (i < 0) +// CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception object created but not thrown; did you mean 'throw {{.*}}'? [misc-throw-keyword-missing] +std::exception(); + + if (i > 0) +// CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception +std::runtime_error("Unexpected argument"); +} + +void stdExceptionThrownTest(int i) { + if (i < 0) +throw std::exception(); + + if (i > 0) +throw std::runtime_error("Unexpected argument"); +} + +void regularClassNotThrownTest(int i) { + if (i < 0) +RegularClass(); +} + +void regularClassThrownTest(int i) { + if (i < 0) +throw RegularClass(); +} + +void nameContainsExceptionNotThrownTest(int i) { + if (i < 0) +// CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception +RegularException(); + + if (i > 0) +// CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception +RegularException(5); +} + +void nameContainsExceptionThrownTest(int i) { + if (i < 0) +throw RegularException(); + + if (i > 0) +throw RegularException(5); +} + +template +void f(int i, Exception excToBeThrown) {} + +void funcCallWithTempExcTest() { + f(5, RegularException()); +} + +// Global variable initilization test. +RegularException exc = RegularException(); +RegularException *excptr = new RegularException(); + +void localVariableInitTest() { + RegularException exc = RegularException(); + RegularException *excptr = new RegularException(); +} + +class CtorInitializerListTest { + RegularException exc; + + CtorInitializerListTest() : exc(RegularException()) {} + + CtorInitializerListTest(int) try : exc(RegularException()) { +// Constructor body + } catch (...) { +// CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception +RegularException(); + } + + CtorInitializerListTest(float); +}; + +CtorInitializerListTest::CtorInitializerListTest(float) try : exc(RegularException()) { + // Constructor body +} catch (...) { + // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: suspicious exception + RegularException(); +} + +RegularException funcReturningExceptionTest(int i) { + return RegularException(); +} + +void returnedValueTest() { + funcReturningExceptionTest(3); +} + +struct ClassBracedInitListTest { + ClassBracedInitListTest(RegularException exc) {} +}; + +void foo(RegularException, ClassBracedInitListTest) {} + +void bracedInitListTest() { + RegularException exc{}; + ClassBracedInitListTest test = {RegularException()}; + foo({}, {RegularException()}); +} + +typedef std::exception ERROR_BASE; +class RegularError : public ERROR_BASE {}; + +void typedefTest() { + // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: suspicious exception + RegularError(); +} + +struct ExceptionRAII { + ExceptionRAII() {} + ~ExceptionRAII() {} +}; + +void exceptionRAIITest() { + ExceptionRAII E; +} Index: docs/clang-tidy/checks/misc-throw-keyword-missing.rst === --- /dev/null +++ docs/clang-tidy/checks/misc-throw-keyword-missing.rst @@ -0
[PATCH] D43120: [clang-tidy] New checker for exceptions that are created but not thrown
aaron.ballman added a comment. In https://reviews.llvm.org/D43120#1005100, @Szelethus wrote: > I also came up with this problem: > >RegularException funcReturningExceptioniTest(int i) { > return RegularException(); >} > >void returnedValueTest() { > funcReturningExceptioniTest(3); //Should this emit a warning? > } > > > I'm not sure whether it'd be a good idea to warn about these cases. Unused > return values can be found by many other means, and I'm afraid the standard > library is filled with these cases. I think it's fine to not warn on this. It can be caught by other means, but if those turn out to be insufficient for some reason, we can address them in a follow-up patch. Comment at: clang-tidy/misc/ThrowKeywordMissingCheck.cpp:45 + diag(TemporaryExpr->getLocStart(), + "exception instantiated but not bound (did you intend to 'throw'?)"); +} Szelethus wrote: > aaron.ballman wrote: > > I'm not keen on the wording here ("bound" isn't a common phrase for > > exceptions). How about `"suspicious exception object created but not > > thrown; did you mean 'throw %0'"` and then pass in the text for the object > > construction? > I tried using the `Lexer::getSourceText` function, but it doesn't print the > right parantheses (ex. `RegularException(` instead of `RegularException()`). > > Also, are you sure it'd be a good idea to pass the entire statement there? In > cases where it would be long, it could draw the programmer's attention away > from the actual problem, the missing `throw` keyword. That's a reasonable point, I'm fine with the way things are in this patch now. Comment at: docs/ReleaseNotes.rst:70 + + Warns if a ``throw`` keyword is potentialy missing before a temporary exception object. + This wording is a bit unclear. How about: Diagnoses when a temporary object that appears to be an exception is constructed but not thrown. Comment at: test/clang-tidy/misc-throw-keyword-missing.cpp:33 + +} //namespace std + Missing space after the comment introducer. This happens in other places as well -- you should run the patch through clang-format to be sure to catch all the formatting issues. Comment at: test/clang-tidy/misc-throw-keyword-missing.cpp:54 + if (i > 0) +//CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception object created but not thrown; did you mean 'throw {{.*}}'? [misc-throw-keyword-missing] +std::runtime_error("Unexpected argument"); Starting with this warning message and each subsequent message, you can drop most of the wording. e.g., `:[[@LINE+1]]:5: warning: suspicious exception` is sufficient. Comment at: test/clang-tidy/misc-throw-keyword-missing.cpp:132 + +RegularException funcReturningExceptioniTest(int i) { + return RegularException(); typo: Exceptioni https://reviews.llvm.org/D43120 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D43120: [clang-tidy] New checker for exceptions that are created but not thrown
Szelethus marked 7 inline comments as done. Szelethus added inline comments. Comment at: clang-tidy/misc/ThrowKeywordMissingCheck.cpp:45 + diag(TemporaryExpr->getLocStart(), + "exception instantiated but not bound (did you intend to 'throw'?)"); +} aaron.ballman wrote: > I'm not keen on the wording here ("bound" isn't a common phrase for > exceptions). How about `"suspicious exception object created but not thrown; > did you mean 'throw %0'"` and then pass in the text for the object > construction? I tried using the `Lexer::getSourceText` function, but it doesn't print the right parantheses (ex. `RegularException(` instead of `RegularException()`). Also, are you sure it'd be a good idea to pass the entire statement there? In cases where it would be long, it could draw the programmer's attention away from the actual problem, the missing `throw` keyword. https://reviews.llvm.org/D43120 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D43120: [clang-tidy] New checker for exceptions that are created but not thrown
Szelethus updated this revision to Diff 133860. Szelethus added a comment. Fixed almost everything mentioned in comments. I also came up with this problem: RegularException funcReturningExceptioniTest(int i) { return RegularException(); } void returnedValueTest() { funcReturningExceptioniTest(3); //Should this emit a warning? } I'm not sure whether it'd be a good idea to warn about these cases. Unused return values can be found by many other means, and I'm afraid the standard library is filled with these cases. I've also added this code snippet to the test file. https://reviews.llvm.org/D43120 Files: clang-tidy/misc/CMakeLists.txt clang-tidy/misc/MiscTidyModule.cpp clang-tidy/misc/ThrowKeywordMissingCheck.cpp clang-tidy/misc/ThrowKeywordMissingCheck.h docs/ReleaseNotes.rst docs/clang-tidy/checks/list.rst docs/clang-tidy/checks/misc-throw-keyword-missing.rst test/clang-tidy/misc-throw-keyword-missing.cpp Index: test/clang-tidy/misc-throw-keyword-missing.cpp === --- /dev/null +++ test/clang-tidy/misc-throw-keyword-missing.cpp @@ -0,0 +1,167 @@ +// RUN: %check_clang_tidy %s misc-throw-keyword-missing %t + +namespace std { + +// std::string declaration (taken from test/clang-tidy/readability-redundant-string-cstr-msvc.cpp). +template +class allocator {}; +template +class char_traits {}; +template , typename A = std::allocator> +struct basic_string { + basic_string(); + basic_string(const basic_string &); + // MSVC headers define two constructors instead of using optional arguments. + basic_string(const C *); + basic_string(const C *, const A &); + ~basic_string(); +}; +typedef basic_string string; +typedef basic_string wstring; + +// std::exception and std::runtime_error declaration. +struct exception { + exception(); + exception(const exception &other); + virtual ~exception(); +}; + +struct runtime_error : public exception { + explicit runtime_error(const std::string &what_arg); +}; + +} //namespace std + +// The usage of this class should never emit a warning. +struct RegularClass {}; + +// Classname contains the substring "exception", in certain cases using this class should emit a warning. +struct RegularException { + RegularException() {} + + // Constructors with a single argument are treated differently (cxxFunctionalCastExpr). + RegularException(int) {} +}; + +// -- + +void stdExceptionNotTrownTest(int i) { + if (i < 0) +//CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception object created but not thrown; did you mean 'throw {{.*}}'? [misc-throw-keyword-missing] +std::exception(); + + if (i > 0) +//CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception object created but not thrown; did you mean 'throw {{.*}}'? [misc-throw-keyword-missing] +std::runtime_error("Unexpected argument"); +} + +void stdExceptionThrownTest(int i) { + if (i < 0) +throw std::exception(); + + if (i > 0) +throw std::runtime_error("Unexpected argument"); +} + +void regularClassNotThrownTest(int i) { + if (i < 0) +RegularClass(); +} + +void regularClassThrownTest(int i) { + if (i < 0) +throw RegularClass(); +} + +void nameContainsExceptionNotThrownTest(int i) { + if (i < 0) +//CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception object created but not thrown; did you mean 'throw {{.*}}'? [misc-throw-keyword-missing] +RegularException(); + + if (i > 0) +//CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception object created but not thrown; did you mean 'throw {{.*}}'? [misc-throw-keyword-missing] +RegularException(5); +} + +void nameContainsExceptionThrownTest(int i) { + if (i < 0) +throw RegularException(); + + if (i > 0) +throw RegularException(5); +} + +template +void f(int i, Exception excToBeThrown) {} + +void funcCallWithTempExcTest() { + f(5, RegularException()); +} + +// Global variable initilization test. +RegularException exc = RegularException(); +RegularException *excptr = new RegularException(); + +void localVariableInitTest() { + RegularException exc = RegularException(); + RegularException *excptr = new RegularException(); +} + +class CtorInitializerListTest { + RegularException exc; + + CtorInitializerListTest() : exc(RegularException()) {} + + CtorInitializerListTest(int) try : exc(RegularException()) { +//Constructor body + } catch (...) { +//CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception object created but not thrown; did you mean 'throw {{.*}}'? [misc-throw-keyword-missing] +RegularException(); + } + + CtorInitializerListTest(float); +}; + +CtorInitializerListTest::CtorInitializerListTest(float) try : exc(RegularException()) { + //Constructor body +} catch (...) { + //CHECK-MESSAGES: :[[@LINE+1]]:3: warning: suspicious exception object created but not thrown; did you mean 'throw {{.*}}'? [misc-throw-keyword-missing] + RegularException();
[PATCH] D43120: [clang-tidy] New checker for exceptions that are created but not thrown
aaron.ballman added inline comments. Comment at: clang-tidy/misc/ThrowKeywordMissingCheck.cpp:24 + + auto CtorInitializerList = + cxxConstructorDecl(hasAnyConstructorInitializer(anything())); Eugene.Zelenko wrote: > Please don't use auto where type could not be easily deduced. `auto` is appropriate here because these are horrible to try to spell out manually. Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D43120 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D43120: [clang-tidy] New checker for exceptions that are created but not thrown
Eugene.Zelenko added inline comments. Comment at: clang-tidy/misc/ThrowKeywordMissingCheck.cpp:24 + + auto CtorInitializerList = + cxxConstructorDecl(hasAnyConstructorInitializer(anything())); Please don't use auto where type could not be easily deduced. Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D43120 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D43120: [clang-tidy] New checker for exceptions that are created but not thrown
Eugene.Zelenko added inline comments. Comment at: docs/clang-tidy/checks/misc-throw-keyword-missing.rst:6 + +This check warns about the potentially missing `throw` keyword. If a temporary object is created, +but the object's type derives from (or the same as) a class that has 'EXCEPTION', 'Exception' or aaron.ballman wrote: > about the potentially -> about a potentially Please remove //This check// and enclose throw in `` https://reviews.llvm.org/D43120 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D43120: [clang-tidy] New checker for exceptions that are created but not thrown
aaron.ballman added a comment. One concern I have is with RAII objects with "exception" in the name. You may already properly handle this, but I'd like to see a test case like: struct ExceptionRAII { ExceptionRAII() {} ~ExceptionRAII() {} }; void foo() { ExceptionRAII E; // Don't trigger on this } Comment at: clang-tidy/misc/ThrowKeywordMissingCheck.cpp:45 + diag(TemporaryExpr->getLocStart(), + "exception instantiated but not bound (did you intend to 'throw'?)"); +} I'm not keen on the wording here ("bound" isn't a common phrase for exceptions). How about `"suspicious exception object created but not thrown; did you mean 'throw %0'"` and then pass in the text for the object construction? Comment at: docs/clang-tidy/checks/misc-throw-keyword-missing.rst:6 + +This check warns about the potentially missing `throw` keyword. If a temporary object is created, +but the object's type derives from (or the same as) a class that has 'EXCEPTION', 'Exception' or about the potentially -> about a potentially Comment at: docs/clang-tidy/checks/misc-throw-keyword-missing.rst:7 +This check warns about the potentially missing `throw` keyword. If a temporary object is created, +but the object's type derives from (or the same as) a class that has 'EXCEPTION', 'Exception' or +'exception' in its name, we can assume that the programmer's intention was to throw that object. or the same as -> or is the same as Comment at: docs/clang-tidy/checks/misc-throw-keyword-missing.rst:14 + void f(int i) { +if(i < 0) { + // Exception is created but is not thrown Can you format the code snippet? https://reviews.llvm.org/D43120 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D43120: [clang-tidy] New checker for exceptions that are created but not thrown
whisperity resigned from this revision. whisperity added a comment. Works for me but I haven't any sayings in these. 😇 https://reviews.llvm.org/D43120 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D43120: [clang-tidy] New checker for exceptions that are created but not thrown
Szelethus updated this revision to Diff 133600. Szelethus marked an inline comment as done. https://reviews.llvm.org/D43120 Files: clang-tidy/misc/CMakeLists.txt clang-tidy/misc/MiscTidyModule.cpp clang-tidy/misc/ThrowKeywordMissingCheck.cpp clang-tidy/misc/ThrowKeywordMissingCheck.h docs/ReleaseNotes.rst docs/clang-tidy/checks/list.rst docs/clang-tidy/checks/misc-throw-keyword-missing.rst test/clang-tidy/misc-throw-keyword-missing.cpp Index: test/clang-tidy/misc-throw-keyword-missing.cpp === --- /dev/null +++ test/clang-tidy/misc-throw-keyword-missing.cpp @@ -0,0 +1,154 @@ +// RUN: %check_clang_tidy %s misc-throw-keyword-missing %t + +namespace std { + +// std::string declaration (taken from test/clang-tidy/readability-redundant-string-cstr-msvc.cpp). +template +class allocator {}; +template +class char_traits {}; +template , typename A = std::allocator> +struct basic_string { + basic_string(); + basic_string(const basic_string &); + // MSVC headers define two constructors instead of using optional arguments. + basic_string(const C *); + basic_string(const C *, const A &); + ~basic_string(); +}; +typedef basic_string string; +typedef basic_string wstring; + +// std::exception and std::runtime_error declaration. +struct exception { + exception(); + exception(const exception &other); + virtual ~exception(); +}; + +struct runtime_error : public exception { + explicit runtime_error(const std::string &what_arg); +}; + +} //namespace std + +// The usage of this class should never emit a warning. +struct RegularClass {}; + +// Classname contains the substring "exception", in certain cases using this class should emit a warning. +struct RegularException { + RegularException() {} + + // Constructors with a single argument are treated differently (cxxFunctionalCastExpr). + RegularException(int) {} +}; + +// -- + +void stdExceptionNotTrown(int i) { + if (i < 0) +//CHECK-MESSAGES: :[[@LINE+1]]:5: warning: exception instantiated but not bound (did you intend to 'throw'?) [misc-throw-keyword-missing] +std::exception(); + + if (i > 0) +//CHECK-MESSAGES: :[[@LINE+1]]:5: warning: exception instantiated but not bound (did you intend to 'throw'?) [misc-throw-keyword-missing] +std::runtime_error("Unexpected argument"); +} + +void stdExceptionThrown(int i) { + if (i < 0) +throw std::exception(); + + if (i > 0) +throw std::runtime_error("Unexpected argument"); +} + +void regularClassNotThrown(int i) { + if (i < 0) +RegularClass(); +} + +void regularClassThrown(int i) { + if (i < 0) +throw RegularClass(); +} + +void nameContainsExceptionNotThrown(int i) { + if (i < 0) +//CHECK-MESSAGES: :[[@LINE+1]]:5: warning: exception instantiated but not bound (did you intend to 'throw'?) [misc-throw-keyword-missing] +RegularException(); + + if (i > 0) +//CHECK-MESSAGES: :[[@LINE+1]]:5: warning: exception instantiated but not bound (did you intend to 'throw'?) [misc-throw-keyword-missing] +RegularException(5); +} + +void nameContainsExceptionThrown(int i) { + if (i < 0) +throw RegularException(); + + if (i > 0) +throw RegularException(5); +} + +template +void f(int i, Exception excToBeThrown) {} + +void funcCallWithTempExcTest() { + f(5, RegularException()); +} + +// Global variable initilization test. +RegularException exc = RegularException(); +RegularException *excptr = new RegularException(); + +void localVariableInitTest() { + RegularException exc = RegularException(); + RegularException *excptr = new RegularException(); +} + +class CtorInitializerListTest { + RegularException exc; + + CtorInitializerListTest() : exc(RegularException()) {} + + CtorInitializerListTest(int) try : exc(RegularException()) { +//Constructor body + } catch (...) { +//CHECK-MESSAGES: :[[@LINE+1]]:5: warning: exception instantiated but not bound (did you intend to 'throw'?) [misc-throw-keyword-missing] +RegularException(); + } + + CtorInitializerListTest(float); +}; + +CtorInitializerListTest::CtorInitializerListTest(float) try : exc(RegularException()) { + //Constructor body +} catch (...) { + //CHECK-MESSAGES: :[[@LINE+1]]:3: warning: exception instantiated but not bound (did you intend to 'throw'?) [misc-throw-keyword-missing] + RegularException(); +} + +RegularException funcReturningExceptioniTest(int i) { + return RegularException(); +} + +struct ClassBracedInitListTest { + ClassBracedInitListTest(RegularException exc) {} +}; + +void functionBracedInitListTest(RegularException, ClassBracedInitListTest) {} + +void bracedInitListTest() { + RegularException exc{}; + ClassBracedInitListTest test = {RegularException()}; + functionBracedInitListTest({}, {RegularException()}); +} + +typedef std::exception ERROR_BASE; +class RegularError : public ERROR_BASE {}; + +void typedefTest() { + //CHECK-MESSAGES: :[[@LINE+1]]:3: warning: exception instantiated but not b
[PATCH] D43120: [clang-tidy] New checker for exceptions that are created but not thrown
Szelethus marked 5 inline comments as done. Szelethus added inline comments. Comment at: clang-tidy/misc/ThrowKeywordMissingCheck.cpp:32 + hasType(cxxRecordDecl( + isSameOrDerivedFrom(matchesName("[Ee]xception|EXCEPTION", + unless(anyOf(hasAncestor(stmt( whisperity wrote: > `matchesName` says > > > Does not match typedefs of an underlying type with the given name. > > Does your check find the following case? > > ``` > typedef std::exception ERROR_BASE; > class my_error : public ERROR_BASE { > /* Usual yadda. */ > }; > > int main() { > my_error(); > } > ``` > It does! I've added this case to the test file. https://reviews.llvm.org/D43120 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D43120: [clang-tidy] New checker for exceptions that are created but not thrown
Szelethus updated this revision to Diff 133597. Szelethus added a comment. Changes made according to @whisperity's comments. https://reviews.llvm.org/D43120 Files: clang-tidy/misc/CMakeLists.txt clang-tidy/misc/MiscTidyModule.cpp clang-tidy/misc/ThrowKeywordMissingCheck.cpp clang-tidy/misc/ThrowKeywordMissingCheck.h docs/ReleaseNotes.rst docs/clang-tidy/checks/list.rst docs/clang-tidy/checks/misc-throw-keyword-missing.rst test/clang-tidy/misc-throw-keyword-missing.cpp Index: test/clang-tidy/misc-throw-keyword-missing.cpp === --- /dev/null +++ test/clang-tidy/misc-throw-keyword-missing.cpp @@ -0,0 +1,154 @@ +// RUN: %check_clang_tidy %s misc-throw-keyword-missing %t + +namespace std { + +// std::string declaration (taken from test/clang-tidy/readability-redundant-string-cstr-msvc.cpp). +template +class allocator {}; +template +class char_traits {}; +template , typename A = std::allocator> +struct basic_string { + basic_string(); + basic_string(const basic_string &); + // MSVC headers define two constructors instead of using optional arguments. + basic_string(const C *); + basic_string(const C *, const A &); + ~basic_string(); +}; +typedef basic_string string; +typedef basic_string wstring; + +// std::exception and std::runtime_error declaration. +struct exception { + exception(); + exception(const exception &other); + virtual ~exception(); +}; + +struct runtime_error : public exception { + explicit runtime_error(const std::string &what_arg); +}; + +} //namespace std + +// The usage of this class should never emit a warning. +struct RegularClass {}; + +// Classname contains the substring "exception", in certain cases using this class should emit a warning. +struct RegularException { + RegularException() {} + + // Constructors with a single argument are treated differently (cxxFunctionalCastExpr). + RegularException(int) {} +}; + +// -- + +void stdExceptionNotTrown(int i) { + if (i < 0) +//CHECK-MESSAGES: :[[@LINE+1]]:5: warning: exception instantiated but not bound (did you intend to 'throw'?) [misc-throw-keyword-missing] +std::exception(); + + if (i > 0) +//CHECK-MESSAGES: :[[@LINE+1]]:5: warning: exception instantiated but not bound (did you intend to 'throw'?) [misc-throw-keyword-missing] +std::runtime_error("Unexpected argument"); +} + +void stdExceptionThrown(int i) { + if (i < 0) +throw std::exception(); + + if (i > 0) +throw std::runtime_error("Unexpected argument"); +} + +void regularClassNotThrown(int i) { + if (i < 0) +RegularClass(); +} + +void regularClassThrown(int i) { + if (i < 0) +throw RegularClass(); +} + +void nameContainsExceptionNotThrown(int i) { + if (i < 0) +//CHECK-MESSAGES: :[[@LINE+1]]:5: warning: exception instantiated but not bound (did you intend to 'throw'?) [misc-throw-keyword-missing] +RegularException(); + + if (i > 0) +//CHECK-MESSAGES: :[[@LINE+1]]:5: warning: exception instantiated but not bound (did you intend to 'throw'?) [misc-throw-keyword-missing] +RegularException(5); +} + +void nameContainsExceptionThrown(int i) { + if (i < 0) +throw RegularException(); + + if (i > 0) +throw RegularException(5); +} + +template +void f(int i, Exception excToBeThrown) {} + +void funcCallWithTempExcTest() { + f(5, RegularException()); +} + +// Global variable initilization test. +RegularException exc = RegularException(); +RegularException *excptr = new RegularException(); + +void localVariableInitTest() { + RegularException exc = RegularException(); + RegularException *excptr = new RegularException(); +} + +class CtorInitializerListTest { + RegularException exc; + + CtorInitializerListTest() : exc(RegularException()) {} + + CtorInitializerListTest(int) try : exc(RegularException()) { +//Constructor body + } catch (...) { +//CHECK-MESSAGES: :[[@LINE+1]]:5: warning: exception instantiated but not bound (did you intend to 'throw'?) [misc-throw-keyword-missing] +RegularException(); + } + + CtorInitializerListTest(float); +}; + +CtorInitializerListTest::CtorInitializerListTest(float) try : exc(RegularException()) { + //Constructor body +} catch (...) { + //CHECK-MESSAGES: :[[@LINE+1]]:3: warning: exception instantiated but not bound (did you intend to 'throw'?) [misc-throw-keyword-missing] + RegularException(); +} + +RegularException funcReturningExceptioniTest(int i) { + return RegularException(); +} + +struct ClassBracedInitListTest { + ClassBracedInitListTest(RegularException exc) {} +}; + +void functionBracedInitListTest(RegularException, ClassBracedInitListTest) {} + +void bracedInitListTest() { + RegularException exc{}; + ClassBracedInitListTest test = {RegularException()}; + functionBracedInitListTest({}, {RegularException()}); +} + +typedef std::exception ERROR_BASE; +class RegularError : public ERROR_BASE {}; + +void preprocessorCheck() { + //CHECK-MESSAGES: :[[@LINE+1]]:3:
[PATCH] D43120: [clang-tidy] New checker for exceptions that are created but not thrown
whisperity requested changes to this revision. whisperity added inline comments. This revision now requires changes to proceed. Comment at: clang-tidy/misc/ThrowKeywordMissingCheck.cpp:21 +void ThrowKeywordMissingCheck::registerMatchers(MatchFinder *Finder) { + // This is a C++ only checker. + if (!getLangOpts().CPlusPlus) Superfluous comment, this can be removed. Comment at: clang-tidy/misc/ThrowKeywordMissingCheck.cpp:32 + hasType(cxxRecordDecl( + isSameOrDerivedFrom(matchesName("[Ee]xception|EXCEPTION", + unless(anyOf(hasAncestor(stmt( `matchesName` says > Does not match typedefs of an underlying type with the given name. Does your check find the following case? ``` typedef std::exception ERROR_BASE; class my_error : public ERROR_BASE { /* Usual yadda. */ }; int main() { my_error(); } ``` Comment at: clang-tidy/misc/ThrowKeywordMissingCheck.cpp:46 + Result.Nodes.getNodeAs("temporary-exception-not-thrown"); + diag(TemporaryExpr->getLocStart(), "exception created but is not thrown"); +} Either use passive for both subsentences or don't use passive at all. Maybe one of the following could be a better wording: > exception instantied and not thrown > exception is constructed but is not thrown > exception construction without a throw statement Comment at: test/clang-tidy/misc-throw-keyword-missing.cpp:23 +// std::exception and std::runtime_error declaration +struct exception{ + exception(); Please format the code. Why isn't there a space before `{`? Comment at: test/clang-tidy/misc-throw-keyword-missing.cpp:29 + +struct runtime_error : public exception{ + explicit runtime_error( const std::string& what_arg ); Format here too. Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D43120 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D43120: [clang-tidy] New checker for exceptions that are created but not thrown
Szelethus created this revision. Szelethus added reviewers: cfe-commits, xazax.hun. Szelethus added a project: clang-tools-extra. Herald added subscribers: hintonda, rnkovacs, mgorny. New checker called misc-throw-keyword-missing warns about cases where a temporary object's type is (likely) an exception but is not thrown. This is done by checking whether the type's name (or one of its baseclass' name) contains the substring "EXCEPTION", "Exception" or "exception". void f(int i){ if(i = 0) // Exception is created but not thrown. std::runtime_error("Wrong argument"); } Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D43120 Files: clang-tidy/misc/CMakeLists.txt clang-tidy/misc/MiscTidyModule.cpp clang-tidy/misc/ThrowKeywordMissingCheck.cpp clang-tidy/misc/ThrowKeywordMissingCheck.h docs/ReleaseNotes.rst docs/clang-tidy/checks/list.rst docs/clang-tidy/checks/misc-throw-keyword-missing.rst test/clang-tidy/misc-throw-keyword-missing.cpp Index: test/clang-tidy/misc-throw-keyword-missing.cpp === --- /dev/null +++ test/clang-tidy/misc-throw-keyword-missing.cpp @@ -0,0 +1,152 @@ +// RUN: %check_clang_tidy %s misc-throw-keyword-missing %t + +namespace std { + +// std::string declaration (taken from test/clang-tidy/readability-redundant-string-cstr-msvc.cpp) +template +class allocator {}; +template +class char_traits {}; +template , typename A = std::allocator> +struct basic_string { + basic_string(); + basic_string(const basic_string&); + // MSVC headers define two constructors instead of using optional arguments. + basic_string(const C *); + basic_string(const C *, const A &); + ~basic_string(); +}; +typedef basic_string string; +typedef basic_string wstring; + +// std::exception and std::runtime_error declaration +struct exception{ + exception(); + exception( const exception& other); + virtual ~exception(); +}; + +struct runtime_error : public exception{ + explicit runtime_error( const std::string& what_arg ); +}; + +} //namespace std + +// The usage of this class should never emit a warning +struct RegularClass {}; + +// Classname contains the substring "exception", in certain cases using this class should emit a warning +struct RegularException { + RegularException() {} + + // Constructors with a single argument are treated differently (cxxFunctionalCastExpr) + RegularException(int) {} +}; + +// -- + +void stdExceptionNotTrown(int i) { + if (i < 0) +//CHECK-MESSAGES: :[[@LINE+1]]:5: warning: exception created but is not thrown [misc-throw-keyword-missing] +std::exception(); + + if (i > 0) +//CHECK-MESSAGES: :[[@LINE+1]]:5: warning: exception created but is not thrown [misc-throw-keyword-missing] +std::runtime_error("Unexpected argument"); + +} + +void stdExceptionThrown(int i) { + if (i < 0) +throw std::exception(); + + if (i > 0) +throw std::runtime_error("Unexpected argument"); +} + +void regularClassNotThrown(int i) { + if (i < 0) +RegularClass(); +} + +void regularClassThrown(int i) { + if (i < 0) +throw RegularClass(); +} + +void nameContainsExceptionNotThrown(int i) { + if (i < 0) +//CHECK-MESSAGES: :[[@LINE+1]]:5: warning: exception created but is not thrown [misc-throw-keyword-missing] +RegularException(); + + if (i > 0) +//CHECK-MESSAGES: :[[@LINE+1]]:5: warning: exception created but is not thrown [misc-throw-keyword-missing] +RegularException(5); +} + +void nameContainsExceptionThrown(int i) { + if (i < 0) +throw RegularException(); + + if (i > 0) +throw RegularException(5); +} + + +template +void f(int i, Exception excToBeThrown){} + +void funcCallWithTempExcTest(){ + f(5, RegularException()); +} + +// Global variable initilization test +RegularException exc = RegularException(); +RegularException* excptr = new RegularException(); + +void localVariableInitTest(){ + RegularException exc = RegularException(); + RegularException* excptr = new RegularException(); +} + +class CtorInitializerListTest{ + RegularException exc; + + CtorInitializerListTest() : exc(RegularException()) {} + + CtorInitializerListTest(int) +try : exc(RegularException()) { + //Constructor +} +catch(...){ + //CHECK-MESSAGES: :[[@LINE+1]]:7: warning: exception created but is not thrown [misc-throw-keyword-missing] + RegularException(); +} + + CtorInitializerListTest(float); +}; + +CtorInitializerListTest::CtorInitializerListTest(float) + try : exc(RegularException()) { +//Constructor + } + catch(...){ +//CHECK-MESSAGES: :[[@LINE+1]]:5: warning: exception created but is not thrown [misc-throw-keyword-missing] +RegularException(); + } + +RegularException funcReturningExceptioniTest(int i){ + return RegularException(); +} + +struct ClassBracedInitListTest{ + ClassBracedInitListTest(RegularException exc) {} +}; + +void functionBracedInitListTest(RegularExce