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.

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

Part Number: CODECOMPOSER
Other Parts Discussed in Thread: AWR1843AOP, AWR1843

hi.

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

Now that mass production (more than 1 million AWR1843AOP units) has been confirmed for four car models, it is important to prevent developer 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.

code
#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_(? const_cast<pointer>(&(arr[0])) : nullptr)
    , sz_(N) {}

    template<size_t N>
    explicit constexpr Arr(const std::array<value_type, N>& arr)
    : p_(? 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;
}

Functions verified in other compilers cause many errors in the TI compiler.

As mentioned in the code above,

there is also an absurd problem in that constexpr is not supported for the Logical NOT operator.

If I had known about these problems, I wouldn't have used C++.

We need a way to replace the TI compiler in CCS with linaro ARM GCC.

Thank you for your support.