https://github.com/balazske updated https://github.com/llvm/llvm-project/pull/176430
From 5f4e66967cc52652983cd387a544388c65bed727 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20K=C3=A9ri?= <[email protected]> Date: Fri, 16 Jan 2026 17:31:35 +0100 Subject: [PATCH 1/2] [clang-tidy] Add check 'bugprone-unsafe-to-allow-exceptions' --- .../bugprone/BugproneTidyModule.cpp | 3 + .../clang-tidy/bugprone/CMakeLists.txt | 1 + .../bugprone/UnsafeToAllowExceptionsCheck.cpp | 76 +++++++++++++++++++ .../bugprone/UnsafeToAllowExceptionsCheck.h | 39 ++++++++++ .../bugprone/unsafe-to-allow-exceptions.rst | 31 ++++++++ .../docs/clang-tidy/checks/list.rst | 1 + .../bugprone/unsafe-to-allow-exceptions.cpp | 45 +++++++++++ 7 files changed, 196 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/bugprone/UnsafeToAllowExceptionsCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/bugprone/UnsafeToAllowExceptionsCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/bugprone/unsafe-to-allow-exceptions.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-to-allow-exceptions.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp index 4150442c25d61..310184037afbd 100644 --- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp @@ -106,6 +106,7 @@ #include "UnintendedCharOstreamOutputCheck.h" #include "UniquePtrArrayMismatchCheck.h" #include "UnsafeFunctionsCheck.h" +#include "UnsafeToAllowExceptionsCheck.h" #include "UnusedLocalNonTrivialVariableCheck.h" #include "UnusedRaiiCheck.h" #include "UnusedReturnValueCheck.h" @@ -308,6 +309,8 @@ class BugproneModule : public ClangTidyModule { "bugprone-crtp-constructor-accessibility"); CheckFactories.registerCheck<UnsafeFunctionsCheck>( "bugprone-unsafe-functions"); + CheckFactories.registerCheck<UnsafeToAllowExceptionsCheck>( + "bugprone-unsafe-to-allow-exceptions"); CheckFactories.registerCheck<UnusedLocalNonTrivialVariableCheck>( "bugprone-unused-local-non-trivial-variable"); CheckFactories.registerCheck<UnusedRaiiCheck>("bugprone-unused-raii"); diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt index db1256d91d311..96ad671d03b39 100644 --- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt @@ -108,6 +108,7 @@ add_clang_library(clangTidyBugproneModule STATIC UnhandledSelfAssignmentCheck.cpp UniquePtrArrayMismatchCheck.cpp UnsafeFunctionsCheck.cpp + UnsafeToAllowExceptionsCheck.cpp UnusedLocalNonTrivialVariableCheck.cpp UnusedRaiiCheck.cpp UnusedReturnValueCheck.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/UnsafeToAllowExceptionsCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UnsafeToAllowExceptionsCheck.cpp new file mode 100644 index 0000000000000..3f159410d6f4d --- /dev/null +++ b/clang-tools-extra/clang-tidy/bugprone/UnsafeToAllowExceptionsCheck.cpp @@ -0,0 +1,76 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "UnsafeToAllowExceptionsCheck.h" + +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "llvm/ADT/StringSet.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::bugprone { +namespace { + +AST_MATCHER_P(FunctionDecl, isEnabled, llvm::StringSet<>, + FunctionsThatShouldNotThrow) { + return FunctionsThatShouldNotThrow.contains(Node.getNameAsString()); +} + +AST_MATCHER(FunctionDecl, isExplicitThrow) { + return isExplicitThrowExceptionSpec(Node.getExceptionSpecType()) && + Node.getExceptionSpecSourceRange().isValid(); +} + +AST_MATCHER(FunctionDecl, hasAtLeastOneParameter) { + return Node.getNumParams() > 0; +} + +} // namespace + +UnsafeToAllowExceptionsCheck::UnsafeToAllowExceptionsCheck( + StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context), + RawCheckedSwapFunctions( + Options.get("CheckedSwapFunctions", "swap,iter_swap,iter_move")) { + llvm::SmallVector<StringRef, 4> CheckedSwapFunctionsVec; + RawCheckedSwapFunctions.split(CheckedSwapFunctionsVec, ",", -1, false); + CheckedSwapFunctions.insert_range(CheckedSwapFunctionsVec); +} + +void UnsafeToAllowExceptionsCheck::storeOptions( + ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "CheckedSwapFunctions", RawCheckedSwapFunctions); +} + +void UnsafeToAllowExceptionsCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher( + functionDecl(allOf(isDefinition(), isExplicitThrow(), + anyOf(cxxDestructorDecl(), + cxxConstructorDecl(isMoveConstructor()), + cxxMethodDecl(isMoveAssignmentOperator()), + allOf(isEnabled(CheckedSwapFunctions), + hasAtLeastOneParameter()), + isMain()))) + .bind("f"), + this); +} + +void UnsafeToAllowExceptionsCheck::check( + const MatchFinder::MatchResult &Result) { + const auto *MatchedDecl = Result.Nodes.getNodeAs<FunctionDecl>("f"); + + if (!MatchedDecl) + return; + + diag(MatchedDecl->getLocation(), + "function %0 should not throw exceptions but " + "it is still marked as throwable") + << MatchedDecl; +} + +} // namespace clang::tidy::bugprone diff --git a/clang-tools-extra/clang-tidy/bugprone/UnsafeToAllowExceptionsCheck.h b/clang-tools-extra/clang-tidy/bugprone/UnsafeToAllowExceptionsCheck.h new file mode 100644 index 0000000000000..90b9d42a7e4c4 --- /dev/null +++ b/clang-tools-extra/clang-tidy/bugprone/UnsafeToAllowExceptionsCheck.h @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_UNSAFETOALLOWEXCEPTIONSCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_UNSAFETOALLOWEXCEPTIONSCHECK_H + +#include "../ClangTidyCheck.h" +#include "llvm/ADT/StringSet.h" + +namespace clang::tidy::bugprone { + +/// Finds functions where throwing exceptions is unsafe but the function is +/// still marked as throwable. +/// +/// For the user-facing documentation see: +/// https://clang.llvm.org/extra/clang-tidy/checks/bugprone/unsafe-to-allow-exceptions.html +class UnsafeToAllowExceptionsCheck : public ClangTidyCheck { +public: + UnsafeToAllowExceptionsCheck(StringRef Name, ClangTidyContext *Context); + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus && LangOpts.CXXExceptions; + } + void storeOptions(ClangTidyOptions::OptionMap &Opts) override; + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + +private: + StringRef RawCheckedSwapFunctions; + llvm::StringSet<> CheckedSwapFunctions; +}; + +} // namespace clang::tidy::bugprone + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_UNSAFETOALLOWEXCEPTIONSCHECK_H diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/unsafe-to-allow-exceptions.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/unsafe-to-allow-exceptions.rst new file mode 100644 index 0000000000000..56d6507f7f207 --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/unsafe-to-allow-exceptions.rst @@ -0,0 +1,31 @@ +.. title:: clang-tidy - bugprone-unsafe-to-allow-exceptions + +bugprone-unsafe-to-allow-exceptions +=================================== + +Finds functions where throwing exceptions is unsafe but the function is still +marked as throwable. Throwing exceptions from the following functions can be +problematic: + +* Destructors +* Move constructors +* Move assignment operators +* The ``main()`` functions +* ``swap()`` functions +* ``iter_swap()`` functions +* ``iter_move()`` functions + +The check finds any of these functions if it is marked with ``noexcept(false)`` +or ``throw(exception)``. This would indicate that the function is expected to +throw exceptions. Only the presence of these keywords is checked, not if the +function actually throws any exception. + +Options +------- + +.. option:: CheckedSwapFunctions + + Comma-separated list of checked swap function names (where throwing + exceptions is unsafe). + Default value is `swap,iter_swap,iter_move`. + diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst index 3dabf887dc2e1..5bef16e365524 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -176,6 +176,7 @@ Clang-Tidy Checks :doc:`bugprone-unintended-char-ostream-output <bugprone/unintended-char-ostream-output>`, "Yes" :doc:`bugprone-unique-ptr-array-mismatch <bugprone/unique-ptr-array-mismatch>`, "Yes" :doc:`bugprone-unsafe-functions <bugprone/unsafe-functions>`, + :doc:`bugprone-unsafe-to-allow-exceptions <bugprone/unsafe-to-allow-exceptions>`, :doc:`bugprone-unused-local-non-trivial-variable <bugprone/unused-local-non-trivial-variable>`, :doc:`bugprone-unused-raii <bugprone/unused-raii>`, "Yes" :doc:`bugprone-unused-return-value <bugprone/unused-return-value>`, diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-to-allow-exceptions.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-to-allow-exceptions.cpp new file mode 100644 index 0000000000000..1e24a23e7afc9 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-to-allow-exceptions.cpp @@ -0,0 +1,45 @@ +// RUN: %check_clang_tidy -std=c++11,c++14 %s bugprone-unsafe-to-allow-exceptions %t -- -- -fexceptions + +struct may_throw { + may_throw(may_throw&&) throw(int) { + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: function 'may_throw' should not throw exceptions but it is still marked as throwable [bugprone-unsafe-to-allow-exceptions] + } + may_throw& operator=(may_throw&&) noexcept(false) { + // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: function 'operator=' should not throw exceptions but it is still marked as throwable + } + ~may_throw() noexcept(false) { + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: function '~may_throw' should not throw exceptions but it is still marked as throwable + } + + void f() noexcept(false) { + } +}; + +struct no_throw { + no_throw(no_throw&&) throw() { + } + no_throw& operator=(no_throw&&) noexcept(true) { + } + ~no_throw() noexcept(true) { + } +}; + +int main() noexcept(false) { + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'main' should not throw exceptions but it is still marked as throwable + return 0; +} + +void swap(int&, int&) noexcept(false) { + // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'swap' should not throw exceptions but it is still marked as throwable +} + +void iter_swap(int&, int&) noexcept(false) { + // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'iter_swap' should not throw exceptions but it is still marked as throwable +} + +void iter_move(int&) noexcept(false) { + // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'iter_move' should not throw exceptions but it is still marked as throwable +} + +void swap(double&, double&) { +} From 722b7275fb625023994974c223f25d363470cddd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20K=C3=A9ri?= <[email protected]> Date: Tue, 20 Jan 2026 16:52:06 +0100 Subject: [PATCH 2/2] fixed review issues --- .../bugprone/UnsafeToAllowExceptionsCheck.cpp | 19 ++++++--------- .../bugprone/UnsafeToAllowExceptionsCheck.h | 2 +- .../checks/bugprone/exception-escape.rst | 4 +++- .../bugprone/unsafe-to-allow-exceptions.rst | 24 +++++++++++++------ .../bugprone/unsafe-to-allow-exceptions.cpp | 23 ++++++++++++------ 5 files changed, 44 insertions(+), 28 deletions(-) diff --git a/clang-tools-extra/clang-tidy/bugprone/UnsafeToAllowExceptionsCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UnsafeToAllowExceptionsCheck.cpp index 3f159410d6f4d..e1124b864b23d 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UnsafeToAllowExceptionsCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UnsafeToAllowExceptionsCheck.cpp @@ -16,9 +16,8 @@ using namespace clang::ast_matchers; namespace clang::tidy::bugprone { namespace { -AST_MATCHER_P(FunctionDecl, isEnabled, llvm::StringSet<>, - FunctionsThatShouldNotThrow) { - return FunctionsThatShouldNotThrow.contains(Node.getNameAsString()); +AST_MATCHER_P(FunctionDecl, hasAnyName, llvm::StringSet<>, Names) { + return Names.contains(Node.getNameAsString()); } AST_MATCHER(FunctionDecl, isExplicitThrow) { @@ -26,19 +25,15 @@ AST_MATCHER(FunctionDecl, isExplicitThrow) { Node.getExceptionSpecSourceRange().isValid(); } -AST_MATCHER(FunctionDecl, hasAtLeastOneParameter) { - return Node.getNumParams() > 0; -} - } // namespace UnsafeToAllowExceptionsCheck::UnsafeToAllowExceptionsCheck( StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), RawCheckedSwapFunctions( - Options.get("CheckedSwapFunctions", "swap,iter_swap,iter_move")) { + Options.get("CheckedSwapFunctions", "swap;iter_swap;iter_move")) { llvm::SmallVector<StringRef, 4> CheckedSwapFunctionsVec; - RawCheckedSwapFunctions.split(CheckedSwapFunctionsVec, ",", -1, false); + RawCheckedSwapFunctions.split(CheckedSwapFunctionsVec, ";", -1, false); CheckedSwapFunctions.insert_range(CheckedSwapFunctionsVec); } @@ -53,8 +48,8 @@ void UnsafeToAllowExceptionsCheck::registerMatchers(MatchFinder *Finder) { anyOf(cxxDestructorDecl(), cxxConstructorDecl(isMoveConstructor()), cxxMethodDecl(isMoveAssignmentOperator()), - allOf(isEnabled(CheckedSwapFunctions), - hasAtLeastOneParameter()), + allOf(hasAnyName(CheckedSwapFunctions), + unless(parameterCountIs(0))), isMain()))) .bind("f"), this); @@ -69,7 +64,7 @@ void UnsafeToAllowExceptionsCheck::check( diag(MatchedDecl->getLocation(), "function %0 should not throw exceptions but " - "it is still marked as throwable") + "it is still marked as potentially throwing") << MatchedDecl; } diff --git a/clang-tools-extra/clang-tidy/bugprone/UnsafeToAllowExceptionsCheck.h b/clang-tools-extra/clang-tidy/bugprone/UnsafeToAllowExceptionsCheck.h index 90b9d42a7e4c4..a0734a120e3b0 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UnsafeToAllowExceptionsCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/UnsafeToAllowExceptionsCheck.h @@ -15,7 +15,7 @@ namespace clang::tidy::bugprone { /// Finds functions where throwing exceptions is unsafe but the function is -/// still marked as throwable. +/// still marked as potentially throwing. /// /// For the user-facing documentation see: /// https://clang.llvm.org/extra/clang-tidy/checks/bugprone/unsafe-to-allow-exceptions.html diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/exception-escape.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/exception-escape.rst index 7d724a4581715..65543796c9ffe 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/exception-escape.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/exception-escape.rst @@ -28,7 +28,9 @@ Functions declared explicitly with ``noexcept(false)`` or ``throw(exception)`` will be excluded from the analysis, as even though it is not recommended for functions like ``swap()``, ``main()``, move constructors, move assignment operators and destructors, it is a clear indication of the developer's -intention and should be respected. +intention and should be respected. To still check for this situation, the check +:doc:`bugprone-unsafe-to-allow-exceptions <unsafe-to-allow-exceptions>` can be +used. WARNING! This check may be expensive on large source files. diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/unsafe-to-allow-exceptions.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/unsafe-to-allow-exceptions.rst index 56d6507f7f207..d5c8d119813ca 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/unsafe-to-allow-exceptions.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/unsafe-to-allow-exceptions.rst @@ -4,8 +4,8 @@ bugprone-unsafe-to-allow-exceptions =================================== Finds functions where throwing exceptions is unsafe but the function is still -marked as throwable. Throwing exceptions from the following functions can be -problematic: +marked as potentially throwing. Throwing exceptions from the following functions +can be problematic: * Destructors * Move constructors @@ -15,17 +15,27 @@ problematic: * ``iter_swap()`` functions * ``iter_move()`` functions +A destructor throwing an exception may result in undefined behavior, resource +leaks or unexpected termination of the program. Throwing move constructor or +move assignment also may result in undefined behavior or resource leak. The +``swap()`` operations expected to be non throwing most of the cases and they +are always possible to implement in a non throwing way. Non throwing ``swap()`` +operations are also used to create move operations. A throwing ``main()`` +function also results in unexpected termination. + The check finds any of these functions if it is marked with ``noexcept(false)`` or ``throw(exception)``. This would indicate that the function is expected to throw exceptions. Only the presence of these keywords is checked, not if the -function actually throws any exception. +function actually throws any exception. To check if the function actually throws +exception, the check :doc:`bugprone-exception-escape <exception-escape>` can be +used (but it does not warn if a function is explicitly marked as throwing). Options ------- .. option:: CheckedSwapFunctions - Comma-separated list of checked swap function names (where throwing - exceptions is unsafe). - Default value is `swap,iter_swap,iter_move`. - + Semicolon-separated list of checked swap function names (where throwing + exceptions is unsafe). These functions are checked if the parameter count is + at least 1. + Default value is `swap;iter_swap;iter_move`. diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-to-allow-exceptions.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-to-allow-exceptions.cpp index 1e24a23e7afc9..50f7c1b6e2cfc 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-to-allow-exceptions.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-to-allow-exceptions.cpp @@ -1,14 +1,19 @@ // RUN: %check_clang_tidy -std=c++11,c++14 %s bugprone-unsafe-to-allow-exceptions %t -- -- -fexceptions +// RUN: %check_clang_tidy -std=c++11,c++14 -check-suffix=,CUSTOMSWAP %s bugprone-unsafe-to-allow-exceptions %t -- \ +// RUN: -config="{CheckOptions: { \ +// RUN: bugprone-unsafe-to-allow-exceptions.CheckedSwapFunctions: 'swap;iter_swap;iter_move;swap1', \ +// RUN: }}" \ +// RUN: -- -fexceptions struct may_throw { may_throw(may_throw&&) throw(int) { - // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: function 'may_throw' should not throw exceptions but it is still marked as throwable [bugprone-unsafe-to-allow-exceptions] + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: function 'may_throw' should not throw exceptions but it is still marked as potentially throwing [bugprone-unsafe-to-allow-exceptions] } may_throw& operator=(may_throw&&) noexcept(false) { - // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: function 'operator=' should not throw exceptions but it is still marked as throwable + // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: function 'operator=' should not throw exceptions but it is still marked as potentially throwing } ~may_throw() noexcept(false) { - // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: function '~may_throw' should not throw exceptions but it is still marked as throwable + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: function '~may_throw' should not throw exceptions but it is still marked as potentially throwing } void f() noexcept(false) { @@ -25,21 +30,25 @@ struct no_throw { }; int main() noexcept(false) { - // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'main' should not throw exceptions but it is still marked as throwable + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'main' should not throw exceptions but it is still marked as potentially throwing return 0; } void swap(int&, int&) noexcept(false) { - // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'swap' should not throw exceptions but it is still marked as throwable + // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'swap' should not throw exceptions but it is still marked as potentially throwing } void iter_swap(int&, int&) noexcept(false) { - // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'iter_swap' should not throw exceptions but it is still marked as throwable + // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'iter_swap' should not throw exceptions but it is still marked as potentially throwing } void iter_move(int&) noexcept(false) { - // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'iter_move' should not throw exceptions but it is still marked as throwable + // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'iter_move' should not throw exceptions but it is still marked as potentially throwing } void swap(double&, double&) { } + +void swap1(long&) noexcept(false) { + // CHECK-MESSAGES-CUSTOMSWAP: :[[@LINE-1]]:6: warning: function 'swap1' should not throw exceptions but it is still marked as potentially throwing +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
