diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 00000000..59753925 --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,182 @@ +--- +# TODO: Enable these checks in smaller steps +# cppcoreguidelines-*, +# portability-* if needed +# readability-*, -readability-magic-numbers, +# misc-*, -misc-no-recursion, +# modernize-*, -modernize-use-trailing-return-type, +# performance-*, + +Checks: >- + cert-*, -cert-dcl37-c, -cert-dcl51-cpp, + clang-analyzer-*, + bugprone-*, + -bugprone-easily-swappable-parameters, + cppcoreguidelines-pro-type-vararg, + cppcoreguidelines-pro-type-reinterpret-cast, + llvm-*,-llvm-header-guard,-llvm-include-order, + google-readability-casting +ExtraArgs: ['-Wno-unknown-warning-option'] +HeaderFileExtensions: ['h', 'hpp'] +HeaderFilterRegex: '.*include/etl/.*' +ImplementationFileExtensions: ['cpp'] +UseColor: true +# TODO: Enable these when readability check is enabled +# CheckOptions : +# - key: readability-identifier-naming.AbstractClassCase +# value: snake_case +# - key: readability-identifier-naming.AbstractClassPrefix +# value: I +# - key: readability-identifier-naming.AbstractClassSuffix +# value: '' +# - key: readability-identifier-naming.ClassCase +# value: snake_case +# - key: readability-identifier-naming.ClassPrefix +# value: '' +# - key: readability-identifier-naming.ClassSuffix +# value: '' +# - key: readability-identifier-naming.GlobalConstantCase +# value: UPPER_CASE +# - key: readability-identifier-naming.GlobalConstantPrefix +# value: '' +# - key: readability-identifier-naming.GlobalConstantSuffix +# value: '' +# - key: readability-identifier-naming.ConstantCase +# value: snake_case +# - key: readability-identifier-naming.ConstantPrefix +# value: '' +# - key: readability-identifier-naming.ConstantSuffix +# value: '' +# - key: readability-identifier-naming.ConstantMemberCase +# value: snake_case +# - key: readability-identifier-naming.ConstantMemberPrefix +# value: k +# - key: readability-identifier-naming.ConstantMemberSuffix +# value: '' +# - key: readability-identifier-naming.StaticConstantCase +# value: snake_case +# - key: readability-identifier-naming.StaticConstantPrefix +# value: k +# - key: readability-identifier-naming.StaticConstantSuffix +# value: '' +# - key: readability-identifier-naming.EnumCase +# value: snake_case +# - key: readability-identifier-naming.EnumPrefix +# value: '' +# - key: readability-identifier-naming.EnumSuffix +# value: '' +# - key: readability-identifier-naming.EnumConstantCase +# value: snake_case +# - key: readability-identifier-naming.EnumConstantPrefix +# value: '' +# - key: readability-identifier-naming.EnumConstantSuffix +# value: '' +# - key: readability-identifier-naming.GlobalVariableCase +# value: snake_case +# - key: readability-identifier-naming.GlobalVariablePrefix +# value: g +# - key: readability-identifier-naming.GlobalVariableSuffix +# value: '' +# - key: readability-identifier-naming.LocalVariableCase +# value: snake_case +# - key: readability-identifier-naming.LocalVariablePrefix +# value: '' +# - key: readability-identifier-naming.LocalVariableSuffix +# value: '' +# - key: readability-identifier-naming.StructCase +# value: aNy_CasE +# - key: readability-identifier-naming.StructPrefix +# value: '' +# - key: readability-identifier-naming.StructSuffix +# value: '' +# - key: readability-identifier-naming.FunctionCase +# value: snake_case +# - key: readability-identifier-naming.FunctionPrefix +# value: '' +# - key: readability-identifier-naming.FunctionSuffix +# value: '' +# - key: readability-identifier-naming.MethodCase +# value: snake_case +# - key: readability-identifier-naming.MethodPrefix +# value: '' +# - key: readability-identifier-naming.MethodSuffix +# value: '' +# - key: readability-identifier-naming.ParameterCase +# value: snake_case +# - key: readability-identifier-naming.PrivateMethodCase +# value: snake_case +# - key: readability-identifier-naming.PrivateMethodPrefix +# value: '' +# - key: readability-identifier-naming.PrivateMethodSuffix +# value: '' +# - key: readability-identifier-naming.PublicMethodCase +# value: snake_case +# - key: readability-identifier-naming.PublicMethodPrefix +# value: '' +# - key: readability-identifier-naming.PublicMethodSuffix +# value: '' +# - key: readability-identifier-naming.MemberCase +# value: snake_case +# - key: readability-identifier-naming.MemberPrefix +# value: _ +# - key: readability-identifier-naming.MemberSuffix +# value: '' +# - key: readability-identifier-naming.PrivateMemberCase +# value: snake_case +# - key: readability-identifier-naming.PrivateMemberPrefix +# value: _ +# - key: readability-identifier-naming.PrivateMemberSuffix +# value: '' +# - key: readability-identifier-naming.PublicMemberCase +# value: snake_case +# - key: readability-identifier-naming.PublicMemberPrefix +# value: '' +# - key: readability-identifier-naming.PublicMemberSuffix +# value: '' +# - key: readability-identifier-naming.NamespaceCase +# value: lower_case +# - key: readability-identifier-naming.NamespacePrefix +# value: '' +# - key: readability-identifier-naming.NamespaceSuffix +# value: '' +# - key: readability-identifier-naming.InlineNamespaceCase +# value: lower_case +# - key: readability-identifier-naming.InlineNamespacePrefix +# value: '' +# - key: readability-identifier-naming.InlineNamespaceSuffix +# value: '' +# - key: readability-identifier-length.IgnoredParameterNames +# value: ^(n|id|a|b|x|y)$ +# - key: readability-identifier-length.IgnoredLoopCounterNames +# value: ^[ijkxy_]$ +# - key: readability-identifier-naming.GlobalFunctionCase +# value: snake_case +# - key: readability-identifier-naming.GlobalFunctionPrefix +# value: '' +# - key: readability-identifier-naming.GlobalFunctionSuffix +# value: '' +# - key: readability-identifier-naming.TemplateParameterCase +# value: CamelCase +# - key: readability-identifier-naming.TemplateParameterPrefix +# value: '' +# - key: readability-identifier-naming.TemplateParameterSuffix +# value: '' +# - key: readability-identifier-naming.TemplateTemplateParameterCase +# value: CamelCase +# - key: readability-identifier-naming.TemplateTemplateParameterPrefix +# value: 'TPL' +# - key: readability-identifier-naming.TemplateTemplateParameterSuffix +# value: '' +# - key: readability-identifier-naming.TypeTemplateParameterCase +# value: CamelCase +# - key: readability-identifier-naming.TypeTemplateParameterPrefix +# value: 'T' +# - key: readability-identifier-naming.TypeTemplateParameterSuffix +# value: '' +# - key: readability-identifier-naming.ValueTemplateParameterCase +# value: UPPER_CASE +# - key: readability-identifier-naming.ValueTemplateParameterPrefix +# value: '' +# - key: readability-identifier-naming.ValueTemplateParameterSuffix +# value: '' +... diff --git a/.github/workflows/clang-tidy.yaml b/.github/workflows/clang-tidy.yaml new file mode 100644 index 00000000..214d30b2 --- /dev/null +++ b/.github/workflows/clang-tidy.yaml @@ -0,0 +1,29 @@ +name: clang-tidy + +on: + push: + branches: [ master, development, pull-request/* ] + pull_request: + branches: [ master, development, pull-request/* ] + types: [opened, synchronize, reopened] + +jobs: + clang-tidy: + name: clang-tidy + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y --no-install-recommends clang clang-tidy + clang --version + clang-tidy --version + run-clang-tidy --version || true + + - name: Run clang-tidy + run: | + test/run-clang-tidy.sh diff --git a/include/etl/callback_timer.h b/include/etl/callback_timer.h index 0b3da8ba..35022b55 100644 --- a/include/etl/callback_timer.h +++ b/include/etl/callback_timer.h @@ -59,8 +59,8 @@ SOFTWARE. #endif #if defined(ETL_CALLBACK_TIMER_USE_ATOMIC_LOCK) - #define ETL_DISABLE_TIMER_UPDATES (++process_semaphore) - #define ETL_ENABLE_TIMER_UPDATES (--process_semaphore) + #define ETL_DISABLE_TIMER_UPDATES (++process_semaphore); + #define ETL_ENABLE_TIMER_UPDATES (--process_semaphore); #define ETL_TIMER_UPDATES_ENABLED (process_semaphore.load() == 0) #endif #endif @@ -70,8 +70,8 @@ SOFTWARE. #error ETL_CALLBACK_TIMER_DISABLE_INTERRUPTS and/or ETL_CALLBACK_TIMER_ENABLE_INTERRUPTS not defined #endif - #define ETL_DISABLE_TIMER_UPDATES ETL_CALLBACK_TIMER_DISABLE_INTERRUPTS - #define ETL_ENABLE_TIMER_UPDATES ETL_CALLBACK_TIMER_ENABLE_INTERRUPTS + #define ETL_DISABLE_TIMER_UPDATES ETL_CALLBACK_TIMER_DISABLE_INTERRUPTS; + #define ETL_ENABLE_TIMER_UPDATES ETL_CALLBACK_TIMER_ENABLE_INTERRUPTS; #define ETL_TIMER_UPDATES_ENABLED true #endif @@ -195,10 +195,10 @@ namespace etl { if (timer.is_active()) { - ETL_DISABLE_TIMER_UPDATES; + ETL_DISABLE_TIMER_UPDATES active_list.remove(timer.id, false); remove_callback.call_if(timer.id); - ETL_ENABLE_TIMER_UPDATES; + ETL_ENABLE_TIMER_UPDATES } // Reset in-place. @@ -233,9 +233,9 @@ namespace etl //******************************************* void clear() { - ETL_DISABLE_TIMER_UPDATES; + ETL_DISABLE_TIMER_UPDATES active_list.clear(); - ETL_ENABLE_TIMER_UPDATES; + ETL_ENABLE_TIMER_UPDATES for (int i = 0; i < MAX_TIMERS; ++i) { @@ -333,7 +333,7 @@ namespace etl // Has a valid period. if (timer.period != etl::timer::state::Inactive) { - ETL_DISABLE_TIMER_UPDATES; + ETL_DISABLE_TIMER_UPDATES if (timer.is_active()) { active_list.remove(timer.id, false); @@ -343,7 +343,7 @@ namespace etl timer.delta = immediate_ ? 0 : timer.period; active_list.insert(timer.id); insert_callback.call_if(timer.id); - ETL_ENABLE_TIMER_UPDATES; + ETL_ENABLE_TIMER_UPDATES result = true; } @@ -370,10 +370,10 @@ namespace etl { if (timer.is_active()) { - ETL_DISABLE_TIMER_UPDATES; + ETL_DISABLE_TIMER_UPDATES active_list.remove(timer.id, false); remove_callback.call_if(timer.id); - ETL_ENABLE_TIMER_UPDATES; + ETL_ENABLE_TIMER_UPDATES } result = true; diff --git a/include/etl/callback_timer_deferred_locked.h b/include/etl/callback_timer_deferred_locked.h index 91927d8d..e9679bc7 100644 --- a/include/etl/callback_timer_deferred_locked.h +++ b/include/etl/callback_timer_deferred_locked.h @@ -79,7 +79,7 @@ namespace etl //******************************************* /// Handle the tick call //******************************************* - bool tick(uint32_t count) final + bool tick(uint32_t count) ETL_FINAL { if (enabled) { diff --git a/include/etl/callback_timer_locked.h b/include/etl/callback_timer_locked.h index 4c53f259..27497b2e 100644 --- a/include/etl/callback_timer_locked.h +++ b/include/etl/callback_timer_locked.h @@ -709,7 +709,7 @@ namespace etl //******************************************* /// Handle the tick call //******************************************* - bool tick(uint32_t count) final + bool tick(uint32_t count) ETL_FINAL { if (enabled) { diff --git a/include/etl/fsm.h b/include/etl/fsm.h index ba25d495..f38efd36 100644 --- a/include/etl/fsm.h +++ b/include/etl/fsm.h @@ -60,7 +60,7 @@ namespace etl #endif // For internal FSM use. - typedef typename etl::larger_type::type fsm_internal_id_t; + typedef etl::larger_type::type fsm_internal_id_t; #if ETL_USING_CPP11 && !defined(ETL_FSM_FORCE_CPP03_IMPLEMENTATION) // For C++11 and above template @@ -189,6 +189,7 @@ namespace etl template ETL_CONSTANT fsm_state_id_t ifsm_state_helper::Self_Transition; +#if ETL_USING_CPP11 // Compile-time: TState::ID must equal its index in the type list (0..N-1) template struct check_ids : etl::true_type @@ -200,6 +201,7 @@ namespace etl : etl::integral_constant< bool, (TState0::STATE_ID == Id) && private_fsm::check_ids::value> { }; +#endif //*************************************************************************** /// RAII detection mechanism to catch reentrant calls to methods that might diff --git a/include/etl/hfsm.h b/include/etl/hfsm.h index e9fccf93..ebab16b8 100644 --- a/include/etl/hfsm.h +++ b/include/etl/hfsm.h @@ -184,6 +184,12 @@ namespace etl etl::fsm_state_id_t next_state_id; // State which was active when the on_enter triggered a state change etl::fsm_state_id_t active_state_id; + + do_enters_result(etl::fsm_state_id_t next_state_id_, etl::fsm_state_id_t active_state_id_) + : next_state_id(next_state_id_) + , active_state_id(active_state_id_) + { + } }; //******************************************* @@ -221,7 +227,7 @@ namespace etl // changed if (next_state != ifsm_state::No_State_Change) { - return {next_state, p_target->get_state_id()}; + return do_enters_result(next_state, p_target->get_state_id()); } // Activate default child if we need to activate any initial states in an @@ -238,7 +244,7 @@ namespace etl // state changed if (next_state != ifsm_state::No_State_Change) { - return {next_state, p_target->get_state_id()}; + return do_enters_result(next_state, p_target->get_state_id()); } } @@ -247,7 +253,7 @@ namespace etl // Wrapping No_State_Change in a static_cast gets rid of the "undefined // reference" error when compiling on C++11 - return {next_state, static_cast(ifsm_state::No_State_Change)}; + return do_enters_result(next_state, static_cast(ifsm_state::No_State_Change)); } //******************************************* diff --git a/include/etl/io_port.h b/include/etl/io_port.h index 7ddca02e..02b99c05 100644 --- a/include/etl/io_port.h +++ b/include/etl/io_port.h @@ -43,6 +43,8 @@ SOFTWARE. #include +#include "private/diagnostic_cxx_11_extensions_push.h" + namespace etl { template @@ -1375,4 +1377,6 @@ namespace etl }; } // namespace etl +#include "private/diagnostic_pop.h" + #endif diff --git a/include/etl/math_constants.h b/include/etl/math_constants.h index d27279ed..60c50700 100644 --- a/include/etl/math_constants.h +++ b/include/etl/math_constants.h @@ -31,6 +31,8 @@ SOFTWARE. #include "platform.h" +#include "private/diagnostic_gnu_static_float_init_push.h" + namespace etl { namespace private_math_constants @@ -86,4 +88,6 @@ namespace etl }; } // namespace etl +#include "private/diagnostic_pop.h" + #endif diff --git a/include/etl/mem_cast.h b/include/etl/mem_cast.h index 987fc7ef..853aa18c 100644 --- a/include/etl/mem_cast.h +++ b/include/etl/mem_cast.h @@ -565,7 +565,7 @@ namespace etl ETL_NODISCARD size_t alignment() const { - typedef typename etl::smallest_uint_for_bits::type type; + typedef etl::smallest_uint_for_bits::type type; const type p = reinterpret_cast(pbuffer); diff --git a/include/etl/message_bus.h b/include/etl/message_bus.h index c2e7bfbc..b2d023cd 100644 --- a/include/etl/message_bus.h +++ b/include/etl/message_bus.h @@ -39,6 +39,8 @@ SOFTWARE. #include "nullptr.h" #include "vector.h" +#include "private/diagnostic_unnamed_type_template_args_push.h" + #include namespace etl @@ -431,4 +433,6 @@ namespace etl }; } // namespace etl +#include "private/diagnostic_pop.h" + #endif diff --git a/include/etl/message_router.h b/include/etl/message_router.h index 216b4710..2bd22456 100644 --- a/include/etl/message_router.h +++ b/include/etl/message_router.h @@ -77,6 +77,7 @@ namespace etl namespace private_message_router { +#if ETL_USING_CPP11 //*************************************************************************** // Traits for a message router. // message packet type @@ -86,8 +87,6 @@ namespace etl template class traits { -#if ETL_USING_CPP11 - private: using message_id_sequence = etl::index_sequence; @@ -102,7 +101,6 @@ namespace etl static_assert(etl::type_list_all_of::value, "All TMessageTypes must satisfy the condition etl::is_message_type"); static_assert(etl::index_sequence_is_unique::value, "All message IDs must be unique"); -#endif }; //*************************************************************************** @@ -116,12 +114,19 @@ namespace etl { public: -#if ETL_USING_CPP11 using message_packet = etl::message_packet<>; using message_types = etl::type_list<>; using sorted_message_types = etl::type_list<>; -#endif }; +#else + //*************************************************************************** + // C++03 empty traits placeholder. + //*************************************************************************** + template + class traits + { + }; +#endif } // namespace private_message_router //*************************************************************************** diff --git a/include/etl/message_timer.h b/include/etl/message_timer.h index 378ff36f..ac0b54a3 100644 --- a/include/etl/message_timer.h +++ b/include/etl/message_timer.h @@ -60,8 +60,8 @@ SOFTWARE. #endif #if defined(ETL_MESSAGE_TIMER_USE_ATOMIC_LOCK) - #define ETL_DISABLE_TIMER_UPDATES (++process_semaphore) - #define ETL_ENABLE_TIMER_UPDATES (--process_semaphore) + #define ETL_DISABLE_TIMER_UPDATES (++process_semaphore); + #define ETL_ENABLE_TIMER_UPDATES (--process_semaphore); #define ETL_TIMER_UPDATES_ENABLED (process_semaphore.load() == 0) #endif @@ -70,8 +70,8 @@ SOFTWARE. #error ETL_MESSAGE_TIMER_DISABLE_INTERRUPTS and/or ETL_MESSAGE_TIMER_ENABLE_INTERRUPTS not defined #endif - #define ETL_DISABLE_TIMER_UPDATES ETL_MESSAGE_TIMER_DISABLE_INTERRUPTS - #define ETL_ENABLE_TIMER_UPDATES ETL_MESSAGE_TIMER_ENABLE_INTERRUPTS + #define ETL_DISABLE_TIMER_UPDATES ETL_MESSAGE_TIMER_DISABLE_INTERRUPTS; + #define ETL_ENABLE_TIMER_UPDATES ETL_MESSAGE_TIMER_ENABLE_INTERRUPTS; #define ETL_TIMER_UPDATES_ENABLED true #endif #endif @@ -390,10 +390,10 @@ namespace etl { if (timer.is_active()) { - ETL_DISABLE_TIMER_UPDATES; + ETL_DISABLE_TIMER_UPDATES active_list.remove(timer.id, true); remove_callback.call_if(timer.id); - ETL_ENABLE_TIMER_UPDATES; + ETL_ENABLE_TIMER_UPDATES } // Reset in-place. @@ -428,9 +428,9 @@ namespace etl //******************************************* void clear() { - ETL_DISABLE_TIMER_UPDATES; + ETL_DISABLE_TIMER_UPDATES active_list.clear(); - ETL_ENABLE_TIMER_UPDATES; + ETL_ENABLE_TIMER_UPDATES for (int i = 0; i < Max_Timers; ++i) { @@ -513,7 +513,7 @@ namespace etl // Has a valid period. if (timer.period != etl::timer::state::Inactive) { - ETL_DISABLE_TIMER_UPDATES; + ETL_DISABLE_TIMER_UPDATES if (timer.is_active()) { active_list.remove(timer.id, false); @@ -523,7 +523,7 @@ namespace etl timer.delta = immediate_ ? 0 : timer.period; active_list.insert(timer.id); insert_callback.call_if(timer.id); - ETL_ENABLE_TIMER_UPDATES; + ETL_ENABLE_TIMER_UPDATES result = true; } @@ -550,10 +550,10 @@ namespace etl { if (timer.is_active()) { - ETL_DISABLE_TIMER_UPDATES; + ETL_DISABLE_TIMER_UPDATES active_list.remove(timer.id, false); remove_callback.call_if(timer.id); - ETL_ENABLE_TIMER_UPDATES; + ETL_ENABLE_TIMER_UPDATES } result = true; @@ -596,9 +596,9 @@ namespace etl //******************************************* bool has_active_timer() const { - ETL_DISABLE_TIMER_UPDATES; + ETL_DISABLE_TIMER_UPDATES bool result = !active_list.empty(); - ETL_ENABLE_TIMER_UPDATES; + ETL_ENABLE_TIMER_UPDATES return result; } @@ -612,12 +612,12 @@ namespace etl { uint32_t delta = static_cast(etl::timer::interval::No_Active_Interval); - ETL_DISABLE_TIMER_UPDATES; + ETL_DISABLE_TIMER_UPDATES if (!active_list.empty()) { delta = active_list.front().delta; } - ETL_ENABLE_TIMER_UPDATES; + ETL_ENABLE_TIMER_UPDATES return delta; } diff --git a/include/etl/private/diagnostic_cxx_11_extensions_push.h b/include/etl/private/diagnostic_cxx_11_extensions_push.h new file mode 100644 index 00000000..6d991898 --- /dev/null +++ b/include/etl/private/diagnostic_cxx_11_extensions_push.h @@ -0,0 +1,39 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2026 BMW AG + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +/* + * The header include guard has been intentionally omitted. + * This file is intended to evaluated multiple times by design. + */ + +#if defined(__clang__) || defined(__llvm__) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wc++11-extensions" +#endif diff --git a/include/etl/private/diagnostic_gnu_static_float_init_push.h b/include/etl/private/diagnostic_gnu_static_float_init_push.h new file mode 100644 index 00000000..2f243d55 --- /dev/null +++ b/include/etl/private/diagnostic_gnu_static_float_init_push.h @@ -0,0 +1,44 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2026 BMW AG + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +/* + * The header include guard has been intentionally omitted. + * This file is intended to evaluated multiple times by design. + */ + +// Matching GCC push for later pop +#if defined(__GNUC__) && !defined(__clang__) && !defined(__llvm__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) + #pragma GCC diagnostic push +#endif + +#if defined(__clang__) || defined(__llvm__) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wgnu-static-float-init" +#endif diff --git a/include/etl/private/diagnostic_unnamed_type_template_args_push.h b/include/etl/private/diagnostic_unnamed_type_template_args_push.h new file mode 100644 index 00000000..17123437 --- /dev/null +++ b/include/etl/private/diagnostic_unnamed_type_template_args_push.h @@ -0,0 +1,39 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2026 BMW AG + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +/* + * The header include guard has been intentionally omitted. + * This file is intended to evaluated multiple times by design. + */ + +#if defined(__clang__) || defined(__llvm__) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wunnamed-type-template-args" +#endif diff --git a/include/etl/scheduler.h b/include/etl/scheduler.h index 8ecf51b2..80d00022 100644 --- a/include/etl/scheduler.h +++ b/include/etl/scheduler.h @@ -287,7 +287,7 @@ namespace etl if (!task_list.full()) { - typename task_list_t::iterator itask = etl::upper_bound(task_list.begin(), task_list.end(), task.get_task_priority(), compare_priority()); + task_list_t::iterator itask = etl::upper_bound(task_list.begin(), task_list.end(), task.get_task_priority(), compare_priority()); task_list.insert(itask, &task); diff --git a/test/run-clang-tidy.sh b/test/run-clang-tidy.sh new file mode 100755 index 00000000..c1490e85 --- /dev/null +++ b/test/run-clang-tidy.sh @@ -0,0 +1,29 @@ +#!/bin/bash +# +# Execute from project root directory +# + +set -euo pipefail + +if [[ ! -f CMakeLists.txt || ! -d .git ]]; then + echo "Error: must be run from the project root directory" >&2 + exit 1 +fi + +export CMAKE_EXPORT_COMPILE_COMMANDS=ON +CMAKE_BUILD_PARALLEL_LEVEL=$(nproc) +export CMAKE_BUILD_PARALLEL_LEVEL + +cd test/syntax_check +rm -rf build-clang-tidy +mkdir -p build-clang-tidy +cd build-clang-tidy + +CC=clang CXX=clang++ cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF \ + -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=17 .. +cmake --build . + +cd ../../.. + +run-clang-tidy -j "$(nproc)" -p test/syntax_check/build-clang-tidy +# TODO: Add -warnings-as-errors='*' once the code is clean of warnings. diff --git a/test/syntax_check/CMakeLists.txt b/test/syntax_check/CMakeLists.txt index 0e2627df..115cd769 100644 --- a/test/syntax_check/CMakeLists.txt +++ b/test/syntax_check/CMakeLists.txt @@ -30,7 +30,7 @@ endif() add_library(tests OBJECT) target_compile_definitions(tests PRIVATE __STDC_LIMIT_MACROS __STDC_CONSTANT_MACROS __STDC_FORMAT_MACROS) target_include_directories(tests PRIVATE "") -target_include_directories(tests SYSTEM PRIVATE ../../include) +target_include_directories(tests PRIVATE ../../include) set_target_properties(tests PROPERTIES CXX_STANDARD_REQUIRED ON CXX_EXTENSIONS ON @@ -59,9 +59,11 @@ endif () if (ETL_CXX_STANDARD MATCHES "98") message(STATUS "Compiling for C++98") set_property(TARGET tests PROPERTY CXX_STANDARD 98) + target_compile_options(tests PRIVATE -Wno-long-long -Wno-pedantic) elseif (ETL_CXX_STANDARD MATCHES "03") message(STATUS "Compiling for C++03 (C++98)") set_property(TARGET tests PROPERTY CXX_STANDARD 98) + target_compile_options(tests PRIVATE -Wno-long-long -Wno-pedantic) elseif (ETL_CXX_STANDARD MATCHES "11") message(STATUS "Compiling for C++11") set_property(TARGET tests PROPERTY CXX_STANDARD 11)