This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AWR1843AOP: bug occurs in the arm compiler when writing at c++14 code

Part Number: AWR1843AOP
Other Parts Discussed in Thread: AWR1843

hi.

To reduce developer mistakes, I am actively using C++'s constexpr and template functions for code management and compile-time constant calculation.

We have confirmed mass production of more than 1 million units for 4 automotive vehicle models, so it is important to prevent coding mistakes.

I also tried MSVC and ARM GCC with the C++14 option turned on, but the compilation was successful.

Please refer to this compiler explorer link : Compiler Explorer (godbolt.org)

The CCS development environment used TI v20.2.7.LTS as the AWR1843 MSS core(ARM coretex R4F) target.

The code that causes a bug when compiling is as follows:

    Please refer to the ENABLE_TI_COMPILER_ERROR and ENABLE_TI_COMPILER_STACK_OVERFLOW_ERROR macros to turn them on/off.

#include <stdio.h>
#include <type_traits>
#include <array>
#include <cmath>
#include <stddef.h>

#define ENABLE_TI_COMPILER_ERROR                    1
#define ENABLE_TI_COMPILER_STACK_OVERFLOW_ERROR     0 // Warning: Please save all files you were working on before trying.

template <typename T>
struct is_std_array : std::false_type {};
template <typename V, size_t N>
struct is_std_array<std::array<V, N>> : std::true_type {};
template <typename V, size_t N>
struct is_std_array<const std::array<V, N>> : std::true_type {};

template<typename T>
constexpr bool is_std_array_v = is_std_array<T>::value;


#if ENABLE_TI_COMPILER_ERROR
    /**
     * @brief TI v20.2.7.LTS Compiler error
     * : error #28: expression must have a constant value
     * template constexpr bool does not appear to work
     */
    #define STD_ARR_CHK(_TYPE_) is_std_array_v<_TYPE_>
#else
    #define STD_ARR_CHK(_TYPE_) is_std_array<_TYPE_>::value
#endif

template<typename Ty>
inline constexpr Ty get_gt(Ty a, Ty b) {
    return a > b ? a : b;
}

template<typename Ty, size_t N>
constexpr std::enable_if_t<!STD_ARR_CHK(Ty) && std::is_arithmetic<Ty>::value,
std::decay_t<Ty>> getArrMax(const std::array<Ty, N>& arr) {
    auto max = arr[0];
    for (size_t i = 1; i < N; i++)
        max = get_gt(arr[i], max);
    return max;
}

template<typename Ty, size_t N, typename std::enable_if_t<STD_ARR_CHK(Ty)>* = nullptr>
constexpr auto getArrMax(const std::array<Ty, N>& arr) {
    auto max = getArrMax(arr[0]);
    for (size_t i = 1; i < N; i++)
        max = get_gt(getArrMax(arr[i]), max);
    return max;
}


static constexpr std::array<const std::array<float, 3>, 2> testStdArr = {
    std::array<float, 3>{0.f, 1.f, 2.f},
    std::array<float, 3>{3.f, 4.f, -5.f}
};

static constexpr float testCstyleArr[2][3] = {
    {0.f, 1.f, 2.f},
    {3.f, 4.f, -5.f}
};


template<typename Ty>
struct Arr {
public:
    typedef Arr __self;
    typedef Ty                  value_type;
    typedef value_type&         reference;
    typedef const value_type&   const_reference;
    typedef value_type*         iterator;
    typedef const value_type*   const_iterator;
    typedef value_type*         pointer;
    typedef const value_type*   const_pointer;
    typedef size_t              size_type;
    typedef ptrdiff_t           difference_type;

    explicit constexpr Arr()
    : p_(nullptr), sz_(0U) {};

    template<size_t N>
    explicit constexpr Arr(const value_type (&addr)[N])
    : p_(const_cast<pointer>(addr)), sz_(N) {}

    template<size_t N>
    explicit constexpr Arr(std::array<value_type, N>&& arr)
    : p_(N ? const_cast<pointer>(&(arr[0])) : nullptr)
    , sz_(N) {}

    template<size_t N>
    explicit constexpr Arr(const std::array<value_type, N>& arr)
    : p_(N ? const_cast<pointer>(&(arr[0])) : nullptr)
    , sz_(N) {}

    inline constexpr const_reference operator[](size_type n) const { return p_[n]; }
    inline constexpr reference operator[](size_type n) { return p_[n]; }

    inline constexpr iterator begin() noexcept { return p_; }
    inline constexpr iterator end() noexcept { return p_ + sz_; }
    inline constexpr const_iterator begin() const noexcept { return p_; }
    inline constexpr const_iterator end() const noexcept { return p_ + sz_; }
    inline constexpr const_iterator cbegin() const noexcept { return p_; }
    inline constexpr const_iterator cend() const noexcept { return p_ + sz_; }

    inline constexpr size_type size() const noexcept { return sz_; }

    inline constexpr pointer data() noexcept { return p_; }
    inline constexpr const_pointer data() const noexcept { return p_; }
    inline constexpr operator pointer() noexcept { return p_; }
    inline constexpr operator const_pointer() const noexcept { return p_; }

private:
    pointer const p_;
    const size_type sz_;
};


int main() {
    static_assert(__cplusplus >= 201402L, "__cplusplus version require c++14");
#ifdef _LIBCPP_STD_VER
    static_assert(_LIBCPP_STD_VER >= 14, "_LIBCPP_STD_VER error");
#endif

    static constexpr auto arrMax = getArrMax(testStdArr);
    static_assert(arrMax == 4.f, "getArrMax error");

    static constexpr const Arr<float> cArrOk(testCstyleArr[0]);
    static_assert(cArrOk.size() == 3, "Arr size error");
   

#if ENABLE_TI_COMPILER_ERROR && ENABLE_TI_COMPILER_STACK_OVERFLOW_ERROR
    /**
     * @brief TI v20.2.7.LTS Compiler error
     *  : fatal error #4: out of memory
     *  array subscript compile error(?)
     *  Warning: Please save all files you were working on before trying.
     */
    static_assert((cArrOk[0] < cArrOk[1]) && (cArrOk[1] < cArrOk[2]), "Arr elem compare fail(1)");
#endif

#if ENABLE_TI_COMPILER_ERROR && ENABLE_TI_COMPILER_STACK_OVERFLOW_ERROR
    /**
     * @brief TI v20.2.7.LTS Compiler error
     *  : fatal error #4: out of memory
     * constructor compile bug(?)
     * Warning: Please save all files you were working on before trying.
     */
    static constexpr const Arr<float> stdArrFail(testStdArr[0]);
    static_assert(cArrOk[1] == stdArrFail[1], "Arr elem compare fail(2)");
#endif

#if ENABLE_TI_COMPILER_ERROR && ENABLE_TI_COMPILER_STACK_OVERFLOW_ERROR
    /**
     * @brief TI v20.2.7.LTS Compiler error
     *  : fatal error #4: out of memory
     *  double array subscript compile error(?)
     *  Warning: Please save all files you were working on before trying.
     */
    static_assert(testStdArr[0][1] == 1.f, "");
#endif
    return 0;
}

In the case of the std::array subscript problem, the array is copied and used, but it seems that memory may be wasted in some cases.

As for other issues, I hope they are fixed as soon as possible because code compatibility is not good.

I wish C++17 or later would be supported quickly, but I am satisfied because most of what I want is possible with C++14.

Thank you for your support.