I compiled my code with the same version of GCC using both -std=gnu++17 and -std=gnu++20. This warning appears for c++17 but is NOT present when using c++20.
I am going to state right up front that, try as I might, I have been unable to create a minimum reproducible example of this problem, but I will continue to try. In the absence of an example, I am just looking for some guidance or would like to know if anyone has ever encountered a similar problem.
I am encountering a large number of the following warnings in my code:
left shift of negative value [-Wshift-negative-value]
The odd thing is, the place where the error is occurring is on the following lines which occur all over my code (as part of a state machine framework):
CState(static_cast<CState::State>(...))
Where CState and State are:
class CState {
public:
using State = CState (AbstractStateMachineV2::*)(const AbstractEventV2&);
constexpr CState(State fn = nullptr) : _fn(fn) {}
static constexpr CState null() { return CState(); }
inline CState operator()(AbstractStateMachineV2& context, const AbstractEventV2& e) {
return context.call(_fn, e);
}
inline operator bool() const { return _fn != nullptr; }
inline bool operator==(CState const& other) { return _fn == other._fn;}
inline bool operator!=(CState const& other) { return _fn != other._fn;}
private:
State _fn;
};
Where the value being casted is just a pointer to a member method used like so:
class MyStateMachine : public AbstractStateMachineV2
{
protected:
CState myState(const AbstractEventV2& e);
};
auto s = CState(static_cast<CState::State>(&MyStateMachine::myState));
As you can see, there is no shifting being done here. And none of the other code that I didn't show involves shifting either.
Unfortunately, I can provide no further insight than this.
I am using the following GCC version but also get the same results on the latest version:
arm-none-eabi-g++.exe (GNU Tools for STM32 10.3-2021.10.20211105-1100) 10.3.1 20210824 (release)
I would really appreciate even the smallest bit of insight anyone could provide on this.
I don't know if this will help at all, but here is a snippet of the actual compilation output for a single source file of my project:
arm-none-eabi-g++ -g3 --specs=nano.specs -mfpu=fpv5-sp-d16 -mfloat-abi=hard -O1 -Wno-missing-field-initializers --debug -g -DBUILD_VERSION_RELEASE=0 -DBUILD_VERSION_MAJOR=0 -DBUILD_VERSION_MINOR=0 -DBUILD_VERSION_BUILD=0 -DBUILD_VERSION_STEM="'a'" -DBUILD_VERSION=\"\" -DUNIX_TIMESTAMP_COMPILE_DATE=\""NO-COMPILE-TIME-PROVIDED"\" -DCOMPILE_BRANCH=\""no-branch"\" -DCODE_REVISION=\""0000000000000000000000000000000000000000"\" -DCODE_REVISION_HASH="{"0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00"}" -DPROJECT_NAME=\"prj-tw-av-base\" -DBUILD_CONFIGURATION=\"debug\" -DBUILD_TARGET_ARCH=\"stm32l562xx\" -DNULL=0 -DDEBUG=1 -DHAVE_CONFIG_H -DOPUS_ARM_ASM -DTW_DEBUG=1 -DLFS_THREADSAFE=1 -DUSE_HAL_DRIVER -DSTM32L562xx -DUSE_FULL_LL_DRIVER -fdata-sections -ffunction-sections -fstack-usage -mcpu=cortex-m33 -MMD -MP -mthumb -Wall -Wextra -mfpu=fpv5-sp-d16 -mfloat-abi=hard -c -std=gnu++17 -fno-exceptions -fno-rtti -fno-use-cxa-atexit -Wdelete-non-virtual-dtor -Wno-volatile -Ilibraries/lib-ext-ctti/include/ -Ilibraries/lib-ext-etl/include/ -Ilibraries/lib-gsp-core-framework/include/ -Ilibraries/lib-tw-av-base-littlefs/include/ -Isources/prj-tw-av-base/include -Isources/prj-tw-av-base/private-include -Itwframework/include -Itwstm32/include -Itwcommon/include -Itwstm32/freertos/include -Itwstm32/stm32cube/STM32L5xx_HAL_Driver/Inc -Itwstm32/stm32cube/CMSIS/Device/ST/STM32L5xx/Include -Itwstm32/stm32cube/CMSIS/Include -Itwstm32/freertos/portable/GCC/ARM_CM33_NTZ/non_secure -Iavbase/include -Iconfig/include -Itwinnet/include -Ist8500/include -Itwfreertos/include -Itwstm32/stm32cube/STM32L5xx_HAL_Driver/Inc/Legacy -Iseggersystemview/include -Iopus/include -Iopus/silk -Iopus/celt -Iopus -Iopus/silk/fixed -Iopus/silk/arm -Iopus/silk/fixed/arm -Iopus/celt/arm -o "build/stm32l562xx/debug/obj/./avbase/src/tw/avbase/filesystem/FilesystemSubsystem.cpp.obj" "avbase/src/tw/avbase/filesystem/FilesystemSubsystem.cpp"
In file included from twframework/include/tw/statemachinev2/StateMachine.h:10,
from avbase/include/tw/avbase/filesystem/FilesystemSubsystem.h:26,
from avbase/src/tw/avbase/filesystem/FilesystemSubsystem.cpp:10:
avbase/include/tw/avbase/filesystem/FilesystemSubsystem.h: In static member function 'static constexpr tw::AbstractStateMachineV2::CState tw::avbase::FilesystemSubsystem::sFS_INFO::init()':
twframework/include/tw/statemachinev2/macros.h:31:89: warning: left shift of negative value [-Wshift-negative-value]
31 | static constexpr CState init() { return CState(static_cast<CState::State>(&init_)); }\
| ^
twframework/include/tw/statemachinev2/macros.h:19:50: note: in expansion of macro '_TW_DECLARE_STATE3'
19 | #define _TW_DECLARE_STATEN(_1, _2, _3, FN_, ...) FN_
| ^~~
twframework/include/tw/statemachinev2/macros.h:18:31: note: in expansion of macro '_TW_DECLARE_STATEN'
18 | #define TW_DECLARE_STATE(...) _TW_DECLARE_STATEN(__VA_ARGS__, _TW_DECLARE_STATE3, _TW_DECLARE_STATE2, _TW_DECLARE_STATE1)(__VA_ARGS__)
| ^~~~~~~~~~~~~~~~~~
avbase/include/tw/avbase/filesystem/FilesystemSubsystem.h:77:2: note: in expansion of macro 'TW_DECLARE_STATE'
77 | TW_DECLARE_STATE(sFS, FilesystemSubsystem::top, FilesystemSubsystem::sFSIdle);
| ^~~~~~~~~~~~~~~~
avbase/src/tw/avbase/filesystem/FilesystemSubsystem.cpp: In constructor 'tw::avbase::FilesystemSubsystem::FilesystemSubsystem(tw::AbstractActiveThread&, tw::twfs::AbstractFilesystem&, tw::twinnet::app::MessageRouter&, tw::twinnet::app::SubAddress, const char*, tw::logging::AbstractLoggable*)':
twframework/include/tw/statemachinev2/macros.h:161:54: warning: left shift of negative value [-Wshift-negative-value]
161 | transition(CState(static_cast<CState::State>(&state_)))
| ^
avbase/src/tw/avbase/filesystem/FilesystemSubsystem.cpp:39:2: note: in expansion of macro 'TW_INITIAL_TRANSITION'
39 | TW_INITIAL_TRANSITION(FilesystemSubsystem::sFS);
| ^~~~~~~~~~~~~~~~~~~~~
...
Every time I do that function pointer casting (via a helper macro), a warning is generated.
The warning is even generated if I add a line as simple as:
FilesystemSubsystem::FilesystemSubsystem()
{
//Warning generated at the following line
auto s = CState(static_cast<CState::State>(&FilesystemSubsystem::state1));
}
AbstractStateMachineV2::CState FilesystemSubsystem::state1(const AbstractEventV2& _e)
{
//...
}
This makes me start to wonder if there is some sort of really odd compiler bug that is exhibiting itself.