When emitting code for a new array expression we check whether the array size is negative in C++98 and C++11 mode, but not from C++14 onwards. E.g. char *foo(int a) { return new char[a]; } $ clang++ tmp.cpp -std=c++11 -S -o- -emit-llvm -Os define noalias nonnull i8* @_Z3fooi(i32 %a) local_unnamed_addr #0 { entry: %0 = sext i32 %a to i64 %1 = icmp sgt i64 %0, -1 %2 = select i1 %1, i64 %0, i64 -1 %call = tail call i8* @_Znam(i64 %2) #2 ret i8* %call } $ clang++ tmp.cpp -std=c++14 -S -o- -emit-llvm -Os define noalias nonnull i8* @_Z3fooi(i32 %a) local_unnamed_addr #0 { entry: %conv = sext i32 %a to i64 %call = tail call i8* @_Znam(i64 %conv) #2 ret i8* %call }
This is related to https://llvm.org/PR11644: we should actually be throwing std::bad_array_new_length from C++11 onwards, but we certainly shouldn't be dropping the bounds check entirely.
Omitting the bounds check on an non-allocating form of operator new[] means running the initialization code. [[nodiscard]] void *operator new[](decltype(sizeof 0), void *) noexcept; extern "C" void abort(); int *f(void *p, int sz) { return new (p) int[sz] {0, (abort(), 1)}; }