diff --git a/.github/workflows/clang-c++11.yml b/.github/workflows/clang-c++11.yml index 6ca727ef..39c0a0a4 100644 --- a/.github/workflows/clang-c++11.yml +++ b/.github/workflows/clang-c++11.yml @@ -50,7 +50,6 @@ jobs: run: | export CC=clang export CXX=clang++ - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 cmake -D BUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=11 ./ clang --version make -j "$(getconf _NPROCESSORS_ONLN)" @@ -79,7 +78,6 @@ jobs: export CXX=clang++ export CXXFLAGS="-stdlib=libc++" export LDFLAGS="-stdlib=libc++" - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 cmake -D BUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=11 ./ clang --version make -j "$(getconf _NPROCESSORS_ONLN)" @@ -101,7 +99,6 @@ jobs: run: | export CC=clang export CXX=clang++ - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 cmake -D BUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=11 ./ clang --version make -j "$(getconf _NPROCESSORS_ONLN)" diff --git a/.github/workflows/clang-c++14.yml b/.github/workflows/clang-c++14.yml index 3ddb0cfa..e7909302 100644 --- a/.github/workflows/clang-c++14.yml +++ b/.github/workflows/clang-c++14.yml @@ -50,7 +50,6 @@ jobs: run: | export CC=clang export CXX=clang++ - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 cmake -D BUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=14 ./ clang --version make -j "$(getconf _NPROCESSORS_ONLN)" @@ -79,7 +78,6 @@ jobs: export CXX=clang++ export CXXFLAGS="-stdlib=libc++" export LDFLAGS="-stdlib=libc++" - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 cmake -D BUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=14 ./ clang --version make -j "$(getconf _NPROCESSORS_ONLN)" @@ -101,7 +99,6 @@ jobs: run: | export CC=clang export CXX=clang++ - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 cmake -D BUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=14 ./ clang --version make -j "$(getconf _NPROCESSORS_ONLN)" diff --git a/.github/workflows/clang-c++17.yml b/.github/workflows/clang-c++17.yml index ccec532b..54b05957 100644 --- a/.github/workflows/clang-c++17.yml +++ b/.github/workflows/clang-c++17.yml @@ -50,7 +50,6 @@ jobs: run: | export CC=clang export CXX=clang++ - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 cmake -D BUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=17 ./ clang --version make -j "$(getconf _NPROCESSORS_ONLN)" @@ -79,7 +78,6 @@ jobs: export CXX=clang++ export CXXFLAGS="-stdlib=libc++" export LDFLAGS="-stdlib=libc++" - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 cmake -D BUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=17 ./ clang --version make -j "$(getconf _NPROCESSORS_ONLN)" @@ -101,7 +99,6 @@ jobs: run: | export CC=clang export CXX=clang++ - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 cmake -D BUILD_TESTS=ON -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 ./ clang --version make -j "$(getconf _NPROCESSORS_ONLN)" diff --git a/.github/workflows/clang-c++20.yml b/.github/workflows/clang-c++20.yml index 0d3fa3f7..eb6d6bf5 100644 --- a/.github/workflows/clang-c++20.yml +++ b/.github/workflows/clang-c++20.yml @@ -62,7 +62,6 @@ jobs: export CXX=clang++-17 export CXXFLAGS="-stdlib=libc++" export LDFLAGS="-stdlib=libc++" - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 cmake -D BUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=20 ./ clang-17 --version make -j "$(getconf _NPROCESSORS_ONLN)" @@ -91,7 +90,6 @@ jobs: run: | export CC=clang-17 export CXX=clang++-17 - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 cmake -DBUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=20 ./ clang-17 --version make -j "$(getconf _NPROCESSORS_ONLN)" @@ -120,7 +118,6 @@ jobs: run: | export CC=clang-17 export CXX=clang++-17 - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 cmake -D BUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=20 ./ clang-17 --version make -j "$(getconf _NPROCESSORS_ONLN)" @@ -149,7 +146,6 @@ jobs: run: | export CC=clang-17 export CXX=clang++-17 - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 cmake -D BUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=20 ./ clang-17 --version make -j "$(getconf _NPROCESSORS_ONLN)" @@ -171,7 +167,6 @@ jobs: run: | export CC=clang export CXX=clang++ - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 cmake -D BUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=20 ./ clang --version make -j "$(getconf _NPROCESSORS_ONLN)" @@ -193,7 +188,6 @@ jobs: run: | export CC=clang export CXX=clang++ - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 cmake -D BUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=20 ./ clang --version make -j "$(getconf _NPROCESSORS_ONLN)" @@ -215,7 +209,6 @@ jobs: run: | export CC=clang export CXX=clang++ - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 cmake -D BUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=20 ./ clang --version make -j "$(getconf _NPROCESSORS_ONLN)" @@ -237,7 +230,6 @@ jobs: run: | export CC=clang export CXX=clang++ - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 cmake -D BUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=20 ./ clang --version make -j "$(getconf _NPROCESSORS_ONLN)" diff --git a/.github/workflows/clang-c++23.yml b/.github/workflows/clang-c++23.yml index d25a346c..97ba5af3 100644 --- a/.github/workflows/clang-c++23.yml +++ b/.github/workflows/clang-c++23.yml @@ -57,12 +57,19 @@ jobs: export CXX=clang++ export CXXFLAGS="-stdlib=libc++" export LDFLAGS="-stdlib=libc++" - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 - cmake -D BUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=23 -DETL_OPTIMISATION=-O3 ./ + cmake -D BUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=23 -DETL_OPTIMISATION=-O3 -DETL_ENABLE_SANITIZER=ON ./ clang --version make -j "$(getconf _NPROCESSORS_ONLN)" - name: Run tests + # The system libc++/libc++abi are not built with ASan. Exception objects + # (e.g. std::runtime_error's reference counted string) are allocated with + # operator new inside libc++.so, but released with free() inside + # libc++abi.so, which AddressSanitizer reports as an alloc-dealloc-mismatch. + # This is a libc++ packaging issue, not an ETL defect, so the check is + # disabled for this job only. + env: + ASAN_OPTIONS: alloc_dealloc_mismatch=0 run: ./test/etl_tests -v build-clang-cpp23-linux-no-stl: @@ -79,8 +86,7 @@ jobs: run: | export CC=clang export CXX=clang++ - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 - cmake -DBUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=23 -DETL_OPTIMISATION=-O3 ./ + cmake -DBUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=23 -DETL_OPTIMISATION=-O3 -DETL_ENABLE_SANITIZER=ON ./ clang --version make -j "$(getconf _NPROCESSORS_ONLN)" @@ -101,8 +107,7 @@ jobs: run: | export CC=clang export CXX=clang++ - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 - cmake -D BUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=23 -DETL_OPTIMISATION=-O3 ./ + cmake -D BUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=23 -DETL_OPTIMISATION=-O3 -DETL_ENABLE_SANITIZER=ON ./ clang --version make -j "$(getconf _NPROCESSORS_ONLN)" @@ -123,8 +128,7 @@ jobs: run: | export CC=clang export CXX=clang++ - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 - cmake -D BUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=23 -DETL_OPTIMISATION=-O3 ./ + cmake -D BUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=23 -DETL_OPTIMISATION=-O3 -DETL_ENABLE_SANITIZER=ON ./ clang --version make -j "$(getconf _NPROCESSORS_ONLN)" @@ -145,8 +149,7 @@ jobs: run: | export CC=clang export CXX=clang++ - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 - cmake -D BUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=23 -DETL_OPTIMISATION=-O3 ./ + cmake -D BUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=23 -DETL_OPTIMISATION=-O3 -DETL_ENABLE_SANITIZER=ON ./ clang --version make -j "$(getconf _NPROCESSORS_ONLN)" @@ -167,8 +170,7 @@ jobs: run: | export CC=clang export CXX=clang++ - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 - cmake -D BUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=23 -DETL_OPTIMISATION=-O3 ./ + cmake -D BUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=23 -DETL_OPTIMISATION=-O3 -DETL_ENABLE_SANITIZER=ON ./ clang --version make -j "$(getconf _NPROCESSORS_ONLN)" @@ -189,8 +191,7 @@ jobs: run: | export CC=clang export CXX=clang++ - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 - cmake -D BUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=23 -DETL_OPTIMISATION=-O3 ./ + cmake -D BUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=23 -DETL_OPTIMISATION=-O3 -DETL_ENABLE_SANITIZER=ON ./ clang --version make -j "$(getconf _NPROCESSORS_ONLN)" @@ -211,8 +212,7 @@ jobs: run: | export CC=clang export CXX=clang++ - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 - cmake -D BUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=23 -DETL_OPTIMISATION=-O3 ./ + cmake -D BUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=23 -DETL_OPTIMISATION=-O3 -DETL_ENABLE_SANITIZER=ON ./ clang --version make -j "$(getconf _NPROCESSORS_ONLN)" diff --git a/.github/workflows/clang-c++26.yml b/.github/workflows/clang-c++26.yml index e118c66a..5905289a 100644 --- a/.github/workflows/clang-c++26.yml +++ b/.github/workflows/clang-c++26.yml @@ -55,7 +55,6 @@ jobs: export CXX=clang++ && \ export CXXFLAGS=-stdlib=libc++ && \ export LDFLAGS=-stdlib=libc++ && \ - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 && \ cmake -DBUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=26 ./ && \ clang --version && \ make -j \$(getconf _NPROCESSORS_ONLN) && \ @@ -77,7 +76,6 @@ jobs: cd /workspaces/etl && \ export CC=clang && \ export CXX=clang++ && \ - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 && \ cmake -DBUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=26 ./ && \ clang --version && \ make -j \$(getconf _NPROCESSORS_ONLN) && \ @@ -99,7 +97,6 @@ jobs: cd /workspaces/etl && \ export CC=clang && \ export CXX=clang++ && \ - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 && \ cmake -DBUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=26 ./ && \ clang --version && \ make -j \$(getconf _NPROCESSORS_ONLN) && \ @@ -121,7 +118,6 @@ jobs: cd /workspaces/etl && \ export CC=clang && \ export CXX=clang++ && \ - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 && \ cmake -DBUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=26 ./ && \ clang --version && \ make -j \$(getconf _NPROCESSORS_ONLN) && \ @@ -143,7 +139,6 @@ jobs: cd /workspaces/etl && \ export CC=clang && \ export CXX=clang++ && \ - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 && \ cmake -DBUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=26 ./ && \ clang --version && \ make -j \$(getconf _NPROCESSORS_ONLN) && \ @@ -163,7 +158,6 @@ jobs: run: | export CC=clang export CXX=clang++ - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 cmake -D BUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=26 ./ clang --version make -j "$(getconf _NPROCESSORS_ONLN)" @@ -185,7 +179,6 @@ jobs: run: | export CC=clang export CXX=clang++ - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 cmake -D BUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=26 ./ clang --version make -j "$(getconf _NPROCESSORS_ONLN)" @@ -207,7 +200,6 @@ jobs: run: | export CC=clang export CXX=clang++ - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 cmake -D BUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=26 ./ clang --version make -j "$(getconf _NPROCESSORS_ONLN)" @@ -229,7 +221,6 @@ jobs: run: | export CC=clang export CXX=clang++ - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 cmake -D BUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=26 ./ clang --version make -j "$(getconf _NPROCESSORS_ONLN)" diff --git a/.github/workflows/gcc-c++11.yml b/.github/workflows/gcc-c++11.yml index 4d33a909..71a5809e 100644 --- a/.github/workflows/gcc-c++11.yml +++ b/.github/workflows/gcc-c++11.yml @@ -49,7 +49,6 @@ jobs: - name: Build run: | git fetch - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 export CC=gcc export CXX=g++ cmake -DBUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=11 ./ @@ -72,7 +71,6 @@ jobs: - name: Build run: | git fetch - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 export CC=gcc export CXX=g++ cmake -DBUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=11 ./ diff --git a/.github/workflows/gcc-c++14.yml b/.github/workflows/gcc-c++14.yml index bc7cca67..0cb6dc2c 100644 --- a/.github/workflows/gcc-c++14.yml +++ b/.github/workflows/gcc-c++14.yml @@ -48,7 +48,6 @@ jobs: - name: Build run: | - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 export CC=gcc export CXX=g++ cmake -DBUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=14 ./ @@ -70,7 +69,6 @@ jobs: - name: Build run: | - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 export CC=gcc export CXX=g++ cmake -DBUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=14 ./ diff --git a/.github/workflows/gcc-c++17.yml b/.github/workflows/gcc-c++17.yml index 1378fc69..4968a87d 100644 --- a/.github/workflows/gcc-c++17.yml +++ b/.github/workflows/gcc-c++17.yml @@ -48,7 +48,6 @@ jobs: - name: Build run: | - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 export CC=gcc export CXX=g++ cmake -DBUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=17 ./ @@ -70,7 +69,6 @@ jobs: - name: Build run: | - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 export CC=gcc export CXX=g++ cmake -DBUILD_TESTS=ON -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 ./ diff --git a/.github/workflows/gcc-c++20.yml b/.github/workflows/gcc-c++20.yml index 6e004456..68be97d8 100644 --- a/.github/workflows/gcc-c++20.yml +++ b/.github/workflows/gcc-c++20.yml @@ -48,7 +48,6 @@ jobs: - name: Build run: | - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 export CC=gcc export CXX=g++ cmake -DBUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=20 ./ @@ -70,7 +69,6 @@ jobs: - name: Build run: | - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 export CC=gcc export CXX=g++ cmake -DBUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=20 ./ @@ -92,7 +90,6 @@ jobs: - name: Build run: | - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 export CC=gcc export CXX=g++ cmake -DBUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=20 ./ @@ -114,7 +111,6 @@ jobs: - name: Build run: | - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 export CC=gcc export CXX=g++ cmake -DBUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=20 ./ diff --git a/.github/workflows/gcc-c++23.yml b/.github/workflows/gcc-c++23.yml index a7e29e56..65cf7dc4 100644 --- a/.github/workflows/gcc-c++23.yml +++ b/.github/workflows/gcc-c++23.yml @@ -48,7 +48,6 @@ jobs: - name: Build run: | - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 export CC=gcc-14 export CXX=g++-14 cmake -DBUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=23 -DETL_OPTIMISATION=-O3 ./ @@ -70,7 +69,6 @@ jobs: - name: Build run: | - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 export CC=gcc-14 export CXX=g++-14 cmake -DBUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=23 -DETL_OPTIMISATION=-O3 ./ @@ -92,7 +90,6 @@ jobs: - name: Build run: | - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 export CC=gcc-14 export CXX=g++-14 cmake -DBUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=23 -DETL_OPTIMISATION=-O3 ./ @@ -114,7 +111,6 @@ jobs: - name: Build run: | - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 export CC=gcc-14 export CXX=g++-14 cmake -DBUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=23 -DETL_OPTIMISATION=-O3 ./ diff --git a/.github/workflows/gcc-c++26.yml b/.github/workflows/gcc-c++26.yml index 63677261..38506641 100644 --- a/.github/workflows/gcc-c++26.yml +++ b/.github/workflows/gcc-c++26.yml @@ -50,7 +50,6 @@ jobs: run: | docker run --rm --user root -v ${{ github.workspace }}:/workspaces/etl etl-ubuntu-2604 bash -c "\ cd /workspaces/etl && \ - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 && \ export CC=gcc && \ export CXX=g++ && \ cmake -DBUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=26 ./ && \ @@ -72,7 +71,6 @@ jobs: run: | docker run --rm --user root -v ${{ github.workspace }}:/workspaces/etl etl-ubuntu-2604 bash -c "\ cd /workspaces/etl && \ - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 && \ export CC=gcc && \ export CXX=g++ && \ cmake -DBUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=26 ./ && \ @@ -94,7 +92,6 @@ jobs: run: | docker run --rm --user root -v ${{ github.workspace }}:/workspaces/etl etl-ubuntu-2604 bash -c "\ cd /workspaces/etl && \ - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 && \ export CC=gcc && \ export CXX=g++ && \ cmake -DBUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=26 ./ && \ @@ -116,7 +113,6 @@ jobs: run: | docker run --rm --user root -v ${{ github.workspace }}:/workspaces/etl etl-ubuntu-2604 bash -c "\ cd /workspaces/etl && \ - export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 && \ export CC=gcc && \ export CXX=g++ && \ cmake -DBUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=26 ./ && \ diff --git a/include/etl/expected.h b/include/etl/expected.h index 1feb1487..49b99aad 100644 --- a/include/etl/expected.h +++ b/include/etl/expected.h @@ -1435,6 +1435,11 @@ namespace etl return lhs.error() == rhs.error(); } +#include "private/diagnostic_uninitialized_push.h" + //******************************************* + // The error is only read when the expected does not have a value, in which + // case it is always fully constructed. GCC can emit a false positive + // -Wmaybe-uninitialized when these are inlined at high optimisation levels. //******************************************* template ETL_CONSTEXPR14 bool operator==(const etl::expected& lhs, const etl::expected& rhs) @@ -1460,6 +1465,7 @@ namespace etl } return lhs.error() == rhs.error(); } +#include "private/diagnostic_pop.h" //******************************************* template diff --git a/include/etl/inplace_function.h b/include/etl/inplace_function.h index 63760d15..e9211702 100644 --- a/include/etl/inplace_function.h +++ b/include/etl/inplace_function.h @@ -1126,8 +1126,13 @@ namespace etl { } + #include "private/diagnostic_uninitialized_push.h" //************************************************************************* // clone_from + // + // GCC can emit a false positive -Wmaybe-uninitialized for the source + // storage when this is inlined into a copy constructor at high + // optimisation levels. The source object is always fully constructed. //************************************************************************* template void clone_from(const etl::inplace_function& other) @@ -1139,6 +1144,7 @@ namespace etl vtable->copy(&other.storage, &storage); } } + #include "private/diagnostic_pop.h" //************************************************************************* // move_from diff --git a/include/etl/invoke.h b/include/etl/invoke.h index 52ad388c..d2644748 100644 --- a/include/etl/invoke.h +++ b/include/etl/invoke.h @@ -39,6 +39,8 @@ SOFTWARE. #if ETL_USING_CPP11 + #include "private/diagnostic_array_bounds_push.h" + namespace etl { //**************************************************************************** @@ -387,5 +389,7 @@ namespace etl #endif } // namespace etl + #include "private/diagnostic_pop.h" + #endif // ETL_USING_CPP11 #endif // ETL_INVOKE_INCLUDED diff --git a/include/etl/message_packet.h b/include/etl/message_packet.h index fdaed2b3..de56fb9c 100644 --- a/include/etl/message_packet.h +++ b/include/etl/message_packet.h @@ -305,6 +305,7 @@ namespace etl (add_new_message_type(etl::move(msg)) || ...); } + #include "private/diagnostic_array_bounds_push.h" #include "private/diagnostic_uninitialized_push.h" //******************************************** /// Only enabled for types that are in the typelist. @@ -318,6 +319,9 @@ namespace etl } #include "private/diagnostic_pop.h" + #include "private/diagnostic_pop.h" + + #include "private/diagnostic_array_bounds_push.h" #include "private/diagnostic_uninitialized_push.h" //******************************************** template @@ -336,6 +340,9 @@ namespace etl } #include "private/diagnostic_pop.h" + #include "private/diagnostic_pop.h" + + #include "private/diagnostic_array_bounds_push.h" #include "private/diagnostic_uninitialized_push.h" //******************************************** template @@ -352,6 +359,8 @@ namespace etl return false; } } + #include "private/diagnostic_pop.h" + #include "private/diagnostic_pop.h" typename etl::aligned_storage::type data; diff --git a/include/etl/not_null.h b/include/etl/not_null.h index dc1ada2f..de0ebe22 100644 --- a/include/etl/not_null.h +++ b/include/etl/not_null.h @@ -35,6 +35,7 @@ SOFTWARE. #include "error_handler.h" #include "exception.h" #include "memory.h" +#include "nullptr.h" #include "type_traits.h" namespace etl @@ -95,7 +96,16 @@ namespace etl ETL_CONSTEXPR14 explicit not_null(underlying_type ptr_) : ptr(ptr_) { - ETL_ASSERT(ptr_ != ETL_NULLPTR, ETL_ERROR(not_null_contains_null)); + if (etl::is_constant_evaluated()) + { + // ETL_IS_FOLDED_NULL keeps the compile time rejection of null working + // when the undefined behaviour sanitizer instruments the comparison. + ETL_ASSERT(!ETL_IS_FOLDED_NULL(ptr_), ETL_ERROR(not_null_contains_null)); + } + else + { + ETL_ASSERT(ptr_ != ETL_NULLPTR, ETL_ERROR(not_null_contains_null)); + } } //********************************* @@ -112,7 +122,14 @@ namespace etl //********************************* ETL_CONSTEXPR14 not_null& operator=(underlying_type rhs) { - ETL_ASSERT_OR_RETURN_VALUE(rhs != ETL_NULLPTR, ETL_ERROR(not_null_contains_null), *this); + if (etl::is_constant_evaluated()) + { + ETL_ASSERT_OR_RETURN_VALUE(!ETL_IS_FOLDED_NULL(rhs), ETL_ERROR(not_null_contains_null), *this); + } + else + { + ETL_ASSERT_OR_RETURN_VALUE(rhs != ETL_NULLPTR, ETL_ERROR(not_null_contains_null), *this); + } ptr = rhs; diff --git a/include/etl/nullptr.h b/include/etl/nullptr.h index 581305ae..57f1c8bd 100644 --- a/include/etl/nullptr.h +++ b/include/etl/nullptr.h @@ -78,4 +78,26 @@ namespace etl #endif } // namespace etl +//***************************************************************************** +/// True when the compiler can fold the comparison at compile time and it yields +/// null. +/// +/// Normally the comparison folds for any pointer that is a constant expression, +/// so this is equivalent to a plain null check. Under GCC's undefined behaviour +/// sanitizer, however, the comparison is instrumented and only folds for a null +/// pointer constant, not for the address of an object or function. +/// __builtin_constant_p filters out the latter, which would otherwise make the +/// enclosing expression non-constant and reject perfectly valid code. +/// +/// Only meaningful during constant evaluation. At run time +/// __builtin_constant_p is false for any pointer that is not a compile time +/// constant, so this reports false for a genuine null pointer. Callers must +/// use a plain comparison against ETL_NULLPTR on the run time path. +//***************************************************************************** +#if ETL_USING_BUILTIN_CONSTANT_P + #define ETL_IS_FOLDED_NULL(p) (__builtin_constant_p((p) == ETL_NULLPTR) && ((p) == ETL_NULLPTR)) +#else + #define ETL_IS_FOLDED_NULL(p) ((p) == ETL_NULLPTR) +#endif + #endif diff --git a/include/etl/optional.h b/include/etl/optional.h index d0c10b44..f675354e 100644 --- a/include/etl/optional.h +++ b/include/etl/optional.h @@ -703,6 +703,11 @@ namespace etl } #endif +#include "private/diagnostic_uninitialized_push.h" + //******************************* + // GCC may warn that 'valid' is used uninitialised when the storage of a + // nested optional is inspected through an inlined destructor chain. + // The flag is always initialised by the constructors, so this is a false positive. //******************************* ETL_CONSTEXPR20_STL void destroy() @@ -713,6 +718,7 @@ namespace etl valid = false; } } +#include "private/diagnostic_pop.h" //******************************* union union_type diff --git a/include/etl/private/delegate_cpp11.h b/include/etl/private/delegate_cpp11.h index eafbde77..c351da9c 100644 --- a/include/etl/private/delegate_cpp11.h +++ b/include/etl/private/delegate_cpp11.h @@ -492,7 +492,7 @@ namespace etl //************************************************************************* /// Assignment //************************************************************************* - delegate& operator=(const delegate& rhs) = default; + ETL_CONSTEXPR14 delegate& operator=(const delegate& rhs) = default; //************************************************************************* /// Create from Lambda or Functor. diff --git a/include/etl/private/variant_variadic.h b/include/etl/private/variant_variadic.h index 5f6444b2..aaedb064 100644 --- a/include/etl/private/variant_variadic.h +++ b/include/etl/private/variant_variadic.h @@ -94,6 +94,15 @@ namespace etl template struct variant_operations { + #include "diagnostic_uninitialized_push.h" + //************************************************************************* + // destroy + // + // GCC can emit a false positive -Wmaybe-uninitialized when this is inlined + // into a variant destructor at high optimisation levels, as it cannot + // prove that the branch for an inactive alternative is never taken. + // The alternative identified by type_id is always fully constructed. + //************************************************************************* static void destroy(char* data, size_t type_id) { if (type_id == Index) @@ -105,6 +114,7 @@ namespace etl variant_operations::destroy(data, type_id); } } + #include "diagnostic_pop.h" static void copy(char* dst, const char* src, size_t type_id) { @@ -156,6 +166,14 @@ namespace etl private: + #include "diagnostic_uninitialized_push.h" + //************************************************************************* + // The *_impl functions below read the alternative identified by type_id, + // which is always fully constructed. GCC can emit a false positive + // -Wmaybe-uninitialized when these are inlined at high optimisation + // levels, as it cannot prove that the branch for an inactive alternative + // is never taken. + //************************************************************************* static void copy_impl(char* dst, const char* src, etl::true_type) { ::new (dst) THead(*reinterpret_cast(src)); @@ -183,6 +201,7 @@ namespace etl } static void move_assign_impl(char*, const char*, etl::false_type) {} + #include "diagnostic_pop.h" }; //******************************************* diff --git a/include/etl/profiles/determine_builtin_support.h b/include/etl/profiles/determine_builtin_support.h index 3db1a474..6340e6e3 100644 --- a/include/etl/profiles/determine_builtin_support.h +++ b/include/etl/profiles/determine_builtin_support.h @@ -232,6 +232,10 @@ SOFTWARE. #define ETL_USING_BUILTIN_IS_CONSTANT_EVALUATED __has_builtin(__builtin_is_constant_evaluated) #endif + #if !defined(ETL_USING_BUILTIN_CONSTANT_P) + #define ETL_USING_BUILTIN_CONSTANT_P __has_builtin(__builtin_constant_p) + #endif + #if !defined(ETL_USING_BUILTIN_BIT_CAST) #define ETL_USING_BUILTIN_BIT_CAST __has_builtin(__builtin_bit_cast) #endif @@ -444,6 +448,16 @@ SOFTWARE. #define ETL_USING_BUILTIN_BUILTIN_IS_CPP_TRIVIALLY_RELOCATABLE 0 #endif +// __builtin_constant_p predates __has_builtin on GCC and Clang, so enable it for +// those compilers when __has_builtin was not available to detect it. +#if !defined(ETL_USING_BUILTIN_CONSTANT_P) && (defined(__GNUC__) || defined(__clang__)) + #define ETL_USING_BUILTIN_CONSTANT_P 1 +#endif + +#if !defined(ETL_USING_BUILTIN_CONSTANT_P) + #define ETL_USING_BUILTIN_CONSTANT_P 0 +#endif + #if !defined(ETL_USING_BUILTIN_BIT_CAST) #define ETL_USING_BUILTIN_BIT_CAST 0 #endif @@ -470,6 +484,7 @@ namespace etl static ETL_CONSTANT bool using_builtin_is_trivially_copyable = (ETL_USING_BUILTIN_IS_TRIVIALLY_COPYABLE == 1); static ETL_CONSTANT bool using_builtin_underlying_type = (ETL_USING_BUILTIN_UNDERLYING_TYPE == 1); static ETL_CONSTANT bool using_builtin_is_constant_evaluated = (ETL_USING_BUILTIN_IS_CONSTANT_EVALUATED == 1); + static ETL_CONSTANT bool using_builtin_constant_p = (ETL_USING_BUILTIN_CONSTANT_P == 1); static ETL_CONSTANT bool using_builtin_memcpy = (ETL_USING_BUILTIN_MEMCPY == 1); static ETL_CONSTANT bool using_builtin_memmove = (ETL_USING_BUILTIN_MEMMOVE == 1); static ETL_CONSTANT bool using_builtin_memset = (ETL_USING_BUILTIN_MEMSET == 1); diff --git a/include/etl/to_arithmetic.h b/include/etl/to_arithmetic.h index 941fc09b..bba59f88 100644 --- a/include/etl/to_arithmetic.h +++ b/include/etl/to_arithmetic.h @@ -713,7 +713,9 @@ namespace etl const uvalue_t uvalue = static_cast(accumulator_result.value()); // Convert from the accumulator type to the desired type. - result = (is_negative ? static_cast(static_cast(0) - static_cast(uvalue)) : etl::bit_cast(uvalue)); + // The negation is performed on the unsigned type to avoid signed overflow + // when the value is the most negative value for the type. + result = (is_negative ? etl::bit_cast(static_cast(static_cast(0) - uvalue)) : etl::bit_cast(uvalue)); } } } diff --git a/include/etl/type_traits.h b/include/etl/type_traits.h index 0c9da447..87b7607b 100644 --- a/include/etl/type_traits.h +++ b/include/etl/type_traits.h @@ -3603,8 +3603,9 @@ namespace etl template struct is_nothrow_relocatable { - // In builtins mode, conservatively use trivially_relocatable as the definition - static ETL_CONSTANT bool value = etl::is_trivially_relocatable::value; + static ETL_CONSTANT bool value = etl::is_trivially_relocatable::value + || (etl::is_nothrow_move_constructible::type>::value + && etl::is_nothrow_destructible::type>::value); }; #elif defined(ETL_USER_DEFINED_TYPE_TRAITS) && !defined(ETL_USE_TYPE_TRAITS_BUILTINS) diff --git a/test/test_delegate.cpp b/test/test_delegate.cpp index c4e870bd..60a8965e 100644 --- a/test/test_delegate.cpp +++ b/test/test_delegate.cpp @@ -2183,6 +2183,65 @@ namespace } #endif + #if ETL_USING_CPP17 + //************************************************************************* + // Verify that copy assigning a delegate, and comparing against a default + // constructed one, are usable in a constant expression. + //************************************************************************* + TEST(test_constexpr_copy_assignment_and_clear) + { + using delegate_type = etl::delegate; + + // Copy assignment from a bound delegate. + constexpr auto copy_assigned = []() constexpr + { + const delegate_type source(&free_void); + delegate_type d; + d = source; + return d; + }; + + constexpr delegate_type d1 = copy_assigned(); + + static_assert(d1.is_valid(), "a copy assigned delegate should be valid"); + static_assert(d1 == delegate_type(&free_void), "a copy assigned delegate should compare equal to its source"); + + // Copy assignment from a default constructed delegate, and comparing an + // unbound delegate against another one. Neither may inspect the null stub + // pointer, which the undefined behaviour sanitizer makes non-constant. + constexpr auto cleared = []() constexpr + { + delegate_type d(&free_void); + d = delegate_type(); + return d; + }; + + constexpr delegate_type d2 = cleared(); + + static_assert(!d2.is_valid(), "a delegate assigned from a default constructed one should be invalid"); + static_assert(d2 == delegate_type(), "an unbound delegate should compare equal to a default constructed one"); + static_assert(d2 != d1, "an unbound delegate should not compare equal to a bound one"); + + // The same operations must still behave identically at run time. + delegate_type d3; + d3 = d1; + CHECK_TRUE(d3.is_valid()); + CHECK(d3 == d1); + + d3 = delegate_type(); + CHECK_FALSE(d3.is_valid()); + CHECK(d3 == delegate_type()); + + // Assigning a null function pointer clears the delegate at run time. + // This is deliberately not checked in a constant expression: the null + // test cannot be folded there when the sanitizer instruments it. + delegate_type d4(&free_void); + d4 = static_cast(ETL_NULLPTR); + CHECK_FALSE(d4.is_valid()); + CHECK(d4 == delegate_type()); + } + #endif + TEST(test_delegate_clear_equals_default_constructed) { using delegate_type = etl::delegate; diff --git a/test/test_optional.cpp b/test/test_optional.cpp index a6ffc5a7..905de3cb 100644 --- a/test/test_optional.cpp +++ b/test/test_optional.cpp @@ -35,6 +35,12 @@ SOFTWARE. #include #include +// GCC can emit false positive -Wmaybe-uninitialized warnings inside the test data +// types when optional's storage is inspected through inlined, never-taken branches. +// The diagnostic is raised late (after inlining), so the suppression has to cover the +// whole translation unit. It is popped at the end of the file. +#include "etl/private/diagnostic_uninitialized_push.h" + #include "data.h" #include "etl/algorithm.h" #include "etl/optional.h" @@ -1949,3 +1955,5 @@ namespace #endif } } // namespace + +#include "etl/private/diagnostic_pop.h"