-
Notifications
You must be signed in to change notification settings - Fork 14.7k
Open
Labels
clang:codegenIR generation bugs: mangling, exceptions, etc.IR generation bugs: mangling, exceptions, etc.clang:frontendLanguage frontend issues, e.g. anything involving "Sema"Language frontend issues, e.g. anything involving "Sema"questionA question, not bug report. Check out https://llvm.org/docs/GettingInvolved.html instead!A question, not bug report. Check out https://llvm.org/docs/GettingInvolved.html instead!
Description
When compiling the following code targeting AArch64 with Clang/LLVM, I observed that the generated IR includes a select instruction that yields -1 when the array size is less than 1:
__attribute__((noinline)) uint32_t Get() {
return 0;
}
uintptr_t Test() {
const uint32_t len = Get();
auto buf = new uint8_t[len]{0};
return (uintptr_t)buf;
}
The IR:
%conv = zext i32 %0 to i64
%1 = icmp ult i64 %conv, 1
%2 = select i1 %1, i64 -1, i64 %conv
%call1 = call noalias noundef nonnull ptr @operator new[](unsigned long)(i64 noundef %2)
The ASM:
Get():
mov w0, wzr
ret
Test():
stp x29, x30, [sp, #-32]!
str x19, [sp, #16]
mov x29, sp
mov x0, #-1
bl operator new[](unsigned long)
mov w1, wzr
mov x2, #-2
mov x19, x0
strb wzr, [x0], #1
bl memset
mov x0, x19
ldr x19, [sp, #16]
ldp x29, x30, [sp], #32
ret
This seems to be generated from EmitCXXNewAllocSize in CGExprCXX.cpp, where -1 is used if the element count is less than 1.
llvm-project/clang/lib/CodeGen/CGExprCXX.cpp
Lines 874 to 878 in 2780b8f
if (minElements) { | |
// Don't allow allocation of fewer elements than we have initializers. | |
if (!hasOverflow) { | |
hasOverflow = CGF.Builder.CreateICmpULT(numElements, | |
llvm::ConstantInt::get(CGF.SizeTy, minElements)); |
llvm-project/clang/lib/CodeGen/CGExprCXX.cpp
Lines 955 to 962 in 2780b8f
// If we had any possibility of dynamic overflow, make a select to | |
// overwrite 'size' with an all-ones value, which should cause | |
// operator new to throw. | |
if (hasOverflow) | |
size = CGF.Builder.CreateSelect(hasOverflow, | |
llvm::Constant::getAllOnesValue(CGF.SizeTy), | |
size); | |
} |
Why is -1 used in this case?
Why -1 was chosen instead of, say, 0?
Does this implementation risk triggering excessive or unintended memory allocations under certain conditions?
Metadata
Metadata
Assignees
Labels
clang:codegenIR generation bugs: mangling, exceptions, etc.IR generation bugs: mangling, exceptions, etc.clang:frontendLanguage frontend issues, e.g. anything involving "Sema"Language frontend issues, e.g. anything involving "Sema"questionA question, not bug report. Check out https://llvm.org/docs/GettingInvolved.html instead!A question, not bug report. Check out https://llvm.org/docs/GettingInvolved.html instead!