// bsla_noreturn.h -*-C++-*- #ifndef INCLUDED_BSLA_NORETURN #define INCLUDED_BSLA_NORETURN #include <bsls_ident.h> BSLS_IDENT("$Id: $") //@PURPOSE: Provide a macro to issue a compiler warning if a function returns. // //@MACROS: // BSLA_NORETURN: issue a compiler warning if function returns normally // BSLA_NORETURN_IS_ACTIVE: 1 if 'BSLA_NORETURN' is active and 0 otherwise // //@SEE_ALSO: bsla_annotations // //@DESCRIPTION: This component provides a preprocessor macro that annotates a // function as never returning, resulting in a compiler warning if a path of // control exists such that the function does return. // ///Macro Reference ///--------------- //: 'BSLA_NORETURN' //: This annotation is used to tell the compiler that a specified function //: will not return in a normal fashion. The function can still exit via //: other means such as throwing an exception or aborting the process. // //: 'BSLA_NORETURN_IS_ACTIVE' //: The macro 'BSLA_NORETURN_IS_ACTIVE' is defined to 0 if 'BSLA_NORETURN' //: expands to nothing and 1 otherwise. // // Note that on Windows, the only effect of 'BSLA_NORETURN' is to indicate that // the code after a call to a function annotated as such is not executed. On // all other platforms where 'BSLA_NORETURN_IS_ACTIVE' is 1, warning messages // are also emitted any time code returns from a function annotated with // 'BSLA_NORETURN'. // ///Usage ///----- // This section illustrates intended use of this component. // ///Example 1: Assertion Handler /// - - - - - - - - - - - - - - // First, we create an assertion handler, 'myHandlerA', which never returns, // and annotate it with 'BSLA_NORETURN' so that the compiler will warn if it // does return: //.. // BSLA_NORETURN void myHandlerA(const bsls::AssertViolation& assertViolation) // { // printf("%s:%d %s", assertViolation.fileName(), // assertViolation.lineNumber(), // assertViolation.comment()); // // if (::getenv("MY_HANDLER_THROW")) { // throw -1; // } // else if (::getenv("MY_HANDLER_EXIT")) { // ::exit(1); // } // // ::abort(); // } //.. // Now, a new hire copies 'myHandlerA' and creates a new handler, 'myHandlerB', // that doesn't abort unless instructed to via an environment variable, not // realizing that this opens up the possibility of the handler returning: //.. // BSLA_NORETURN void myHandlerB(const bsls::AssertViolation& assertViolation) // { // printf("%s:%d %s", assertViolation.fileName(), // assertViolation.lineNumber(), // assertViolation.comment()); // // if (::getenv("MY_HANDLER_THROW")) { // throw -1; // } // else if (::getenv("MY_HANDLER_EXIT")) { // ::exit(1); // } // else if (::getenv("MY_HANDLER_ABORT")) { // ::abort(); // } // } //.. // Finally, we observe the compiler warning that occurs to point out the // possibility of 'myHandlerB' returning: //.. // .../bsla_noreturn.t.cpp:157:5: warning: function declared 'noreturn' should // not return [-Winvalid-noreturn] // } // ^ //.. #include <bsls_compilerfeatures.h> #include <bsls_platform.h> #if defined(BSLS_COMPILERFEATURES_SUPPORT_ATTRIBUTE_NORETURN) #define BSLA_NORETURN [[ noreturn ]] #define BSLA_NORETURN_IS_ACTIVE 1 #elif defined(BSLS_PLATFORM_CMP_GNU) || defined(BSLS_PLATFORM_CMP_CLANG) #define BSLA_NORETURN __attribute__((noreturn)) #define BSLA_NORETURN_IS_ACTIVE 1 #elif defined(BSLS_PLATFORM_CMP_MSVC) #define BSLA_NORETURN __declspec(noreturn) #define BSLA_NORETURN_IS_ACTIVE 1 #else #define BSLA_NORETURN #define BSLA_NORETURN_IS_ACTIVE 0 #endif #endif // ---------------------------------------------------------------------------- // Copyright 2019 Bloomberg Finance L.P. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ----------------------------- END-OF-FILE ----------------------------------