<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/105711>105711</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[clang] Unexpected Initialization of Private Member Array in Clang
</td>
</tr>
<tr>
<th>Labels</th>
<td>
clang
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
arvidjonasson
</td>
</tr>
</table>
<pre>
## Description
When compiling C++11 code with Clang (versions 3.2 through 18.1), there's an unexpected behavior where a large array within a private member is initialized (using `memset`), while the same array in other contexts remains uninitialized.
## Minimal Reproducer
```cpp
struct UninitializedData {
UninitializedData() noexcept {}
unsigned long long size = 0;
unsigned char arr[1024 * 1024];
};
class AsPublic {
public:
UninitializedData data;
};
class AsPrivate {
private:
UninitializedData data;
};
template<typename T>
void acceptAnything(T);
void testUninitializedData() {
UninitializedData* p = new UninitializedData{};
acceptAnything(p);
}
void testAsPublic() {
AsPublic* p = new AsPublic{};
acceptAnything(p);
}
void testAsPrivate() {
AsPrivate* p = new AsPrivate{};
acceptAnything(p);
}
```
## Assembly
```assembly
testUninitializedData():
push rax
mov edi, 1048584
call operator new(unsigned long)@PLT
mov qword ptr [rax], 0
mov rdi, rax
pop rax
jmp void acceptAnything<UninitializedData*>(UninitializedData*)@PLT
testAsPublic():
push rax
mov edi, 1048584
call operator new(unsigned long)@PLT
mov qword ptr [rax], 0
mov rdi, rax
pop rax
jmp void acceptAnything<AsPublic*>(AsPublic*)@PLT
testAsPrivate():
push rbx
mov edi, 1048584
call operator new(unsigned long)@PLT
mov rbx, rax
mov edx, 1048584
mov rdi, rax
xor esi, esi
call memset@PLT
mov rdi, rbx
pop rbx
jmp void acceptAnything<AsPrivate*>(AsPrivate*)@PLT
```
https://godbolt.org/z/93K1TE8Ph
## Expected Behavior
The `arr` member should remain uninitialized in all three test cases: `testUninitializedData()`, `testAsPublic()`, and `testAsPrivate()`.
## Actual Behavior
In Clang (versions 3.2 through 18.1), the `arr` member is initialized (using `memset`) only in the `testAsPrivate()` case. It remains uninitialized in the other two cases.
## Environment
- Compiler: Clang 3.2 through 18.1 (expected behaviour from Clang 3.1 and 3.0)
- Language: C++11
## Additional Context
GCC 6.1 and later does not initialize `arr` in any of the functions, while GCC 5.5 and earlier initialize `arr` in `testAsPublic`, `testAsPrivate` but not `testUninitializedData`.
The unexpected initialization could lead to performance issues, especially when dealing with large arrays or in performance-critical code where unnecessary initialization is undesirable.
## Questions
1. Is this behavior intentional or a bug?
2. If intentional, what's the rationale behind initializing private member arrays but not public ones?
3. If a bug, are there any known workarounds to prevent this initialization?
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzEV12P4joS_TXmpdQocQgfDzzw0axae680u-qrfTZOQTzj2FnbgWZ-_cp2gJBO98zOarSjEaFdlfKpc8qmilkrjgpxSfI1ybcj1rhSmyUzJ1F81YpZq9Vor4vLktCM0Ay2aLkRtRNakWRLktW_SlTAdVULKdQRNoSuCV2nKXBdIJyFK2EjmToCofMTGiu0spCNKbjS6OZYQjofp4QuCN2AK9EgoTMLTEGj8K1G7rCAPZbsJLSBs3cABpKZIwIzhl3CFkIBg9qIE3MIFVZ7NCAsCCWcYFJ8x8Jv31iPkEyTCiuLjkyTdt9zKST63cGy6hpXKNAeEHCtHL45CwYrJpSFRnUCjyMN7Wck6U-hRMUk_BNro4uGo2nN0yT-53UdV6wzDXfwVzfiljkGZLaOHvDeSOic0AUojW8caxd8Z9ure6OCpAVIrY7xw4rvCCTbQkKy9Ts_XjLjcyb5Ok3oBAhdgf9C8u3N3ce_fQ-fXDJrYWW_NHsp-B1vHf4m2epD-FD4HH4icqvnPXRc-F9iO6xqGWJs3KVG5eV-JdlztJ60KIBxT-pKXXxZHQmdv_oqeQwTHB1a95E2d_kGPFZQBzUUngfMUcybTu_g1A9wrrr3cF11eQcHAO62LpDbam9_gF-H0OrVx9Cx9BC0y78O4XrAHo7jylqs9vLS82EPy5-o2Sm4-K9ubAmGvT2uVvoUnlgIf6mkyWSezyePPpxJ6Z-6RsOcNj5xfzN1z6zfcZJ8-eN1OPy_z9oUUDsDJF97EPnWb5cMe5sI5h3YWtfR3jd8raJh6Cxkm6Fq9seHzgctj5nciX4szzu_gdghVD_N7e8j9jcx2jmNkcjuwif8dc_WAIH7_09x-n2HyLlv__bh9j8i-E2bGMMGu39E-xV3-7P-Gbw2dJ-dm3Y3ww9Fu91gN9XuKz3ZHi-l0rnaesXojtDdURd7Ld1YmyOhu--E7hbZ39PX5_mXcqCxeL52ROu2I4rW1xJ9W-N_w6fJtf-xpW5k0TYtjz2L7208Z640iOGyBs4selQ-zmdXoe-ZNlen3jGONqaKjv2hTKfJULe04q5hspfSi_qv2sb36f9k-wdaydDrtUGGYQd6xvDihnvA6_uxX3RnHekcSvZZnYTRqkLl4voTbELzjMazH3Pu5-nR95vhxsDB6Or2RhqIz8ahp20j_8HUsWFHDJGvjfmQAkUhfEfPJGxisxvNf9tsYNpG9l2TgUKjBaVdh9sO9b6s1AX0IbBxaBT3Ue29xfYB83EeAiIzUnihPojUr7F-5bUSTRPYNy5g-rB0e3Xnj0tnurh5M48WeDg2ElkBTkON5qBNxRRHENY2aOPdUyMXTMqLH0kUFMjC9BPGnc5wYkH7BLtRnrgRTnAm2wEpTDSNUsjRWmYufTjC11qBVhi2lzhUUv9o0Eaew2o6hhcLrhT2PjcJ5VC1CmsDDPbNkWS7-AIdw8uh6xL1Yi5MYl5Jw6IBfUShOpT5pHtzV5v4VZQ4D4BW_nppd8zCjhGFvzEMxtEvVM83pc8Kztp8Y0Y3qrBBBoMnVC6m9cgQyXajYpkVi2zBRrhMZ3SS5ck0z0flMmOMpZztKaXpfLHn-WyWZTmnSZYfkvmCj8SSJnSSzL09nWX5mC1oyug8PxTz-ZTPEzJJ_ImXYylPlb-lR6EKlmmSz9J0JNkepQ3TM6XcH0VCqR-kzdK_8LRvjpZMEimss_cQTjgZRu74Rr6Fv-7l-PKovz7AdRD6MxK8uo6n4eiPGiOXvd8U4cpmP-a6InTnN20fT7XRX5E7QnfXUt61eZyW9D8BAAD__9Du2gM">