<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/59733>59733</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
False positive on clang-analyzer-optin.cplusplus.UninitializedObject
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
brevzin
</td>
</tr>
</table>
<pre>
Trying to reduce this from some fmt code:
```cpp
#include <fmt/format.h>
using EH = fmt::detail::error_handler;
namespace fmt::detail {
template <typename Char, typename ErrorHandler = detail::error_handler>
class CompileParseContext
: public basic_format_parse_context<Char, ErrorHandler> {
private:
int num_args_;
const type* types_;
using base = basic_format_parse_context<Char, ErrorHandler>;
public:
explicit constexpr CompileParseContext(
basic_string_view<Char> format_str, int num_args, const type* types,
ErrorHandler eh = {}, int next_arg_id = 0)
: base(format_str, eh, next_arg_id), num_args_(num_args), types_(types) {}
};
}
struct FormatStringChecker {
#ifdef OK
using parse_context_type = fmt::detail::CompileParseContext<char, EH>;
#else
using parse_context_type = fmt::detail::compile_parse_context<char, EH>;
#endif
parse_context_type context_;
fmt::detail::type types_[1];
constexpr FormatStringChecker(fmt::string_view format_str, EH eh)
: context_(format_str, 0, types_, eh)
, types_{}
{ }
};
void show() {
FormatStringChecker c("", {});
}
```
When I run (with clang-15 and fmt-9.1.0):
```
$ clang-tidy -checks='-*,clang-analyzer-optin.cplusplus.UninitializedObject' foo.cxx -- -std=c++17 -I fmt/include -DOK
$ clang-tidy -checks='-*,clang-analyzer-optin.cplusplus.UninitializedObject' foo.cxx -- -std=c++17 -I fmt/include
1 warning generated.
/home/brevzin/sandbox/foo.cxx:34:17: error: 5 uninitialized fields at the end of the constructor call [clang-analyzer-optin.cplusplus.UninitializedObject,-warnings-as-errors]
, types_{}
^
/home/brevzin/sandbox/fmt/include/fmt/core.h:732:7: note: uninitialized field 'this->context_.num_args_'
int num_args_;
^~~~~~~~~
/home/brevzin/sandbox/fmt/include/fmt/core.h:733:15: note: uninitialized pointer 'this->context_.types_'
const type* types_;
^~~~~~
/home/brevzin/sandbox/fmt/include/fmt/core.h:432:15: note: uninitialized pointer 'this->context_.basic_format_parse_context::format_str_.data_'
const Char* data_;
^~~~~
/home/brevzin/sandbox/fmt/include/fmt/core.h:433:10: note: uninitialized field 'this->context_.basic_format_parse_context::format_str_.size_'
size_t size_;
^~~~~
/home/brevzin/sandbox/fmt/include/fmt/core.h:657:7: note: uninitialized field 'this->context_.basic_format_parse_context::next_arg_id_'
int next_arg_id_;
^~~~~~~~~~~~
/home/brevzin/sandbox/foo.cxx:39:25: note: Calling constructor for 'FormatStringChecker'
FormatStringChecker c("", {});
^~~~~~~~~
/home/brevzin/sandbox/foo.cxx:34:17: note: 5 uninitialized fields at the end of the constructor call
, types_{}
^~
1 warning treated as error
```
All of these fields are actually initialized though. What's especially confusing is that my `CompileParseContext` is exactly the same as `fmt::detail::compile_parse_context`, as you can see [here](https://github.com/fmtlib/fmt/blob/9.1.0/include/fmt/core.h#L728-L740):
```cpp
template <typename Char, typename ErrorHandler = detail::error_handler>
class compile_parse_context
: public basic_format_parse_context<Char, ErrorHandler> {
private:
int num_args_;
const type* types_;
using base = basic_format_parse_context<Char, ErrorHandler>;
public:
explicit FMT_CONSTEXPR compile_parse_context(
basic_string_view<Char> format_str, int num_args, const type* types,
ErrorHandler eh = {}, int next_arg_id = 0)
: base(format_str, eh, next_arg_id), num_args_(num_args), types_(types) {}
```
And yet my version (which I copied to continue attempting to reduce) doesn't give uninitialized errors.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsWEuT4jgS_jXikmHCyBjDgQPPqI6d3Z7Y6Y3ZGyHkBGtXSA5JroI6zG_fkGyDoaGmq7Y7Yg5dQRnbeuSXmV8-BLNW7BXilKRzki57rHKFNtOtwedXoXpbnZ-mX8xJqD04DQbziiO4QljYGX0Aqw8Iu4MDrnMkyYzESxK311Fcf3hZNm9oIhSXVY5AksXu4Ahd77Q5MNcvSLLqLq6sF7l6ApIsvQC_dzLL0TEh63s0RptNwVQu0ZBk3l2t2AFtyTjeLgWSNRMdHkrJXEDiTiX6JbAomCF0AecXKy_kqZYRoLyBoMHPJbMWFvpQCom_MmNxoZXDo6uHAQBIMoOy2krBYcus4JvaCJvSz97wZnqyaOF0UZBkdVECSiOembtYHkAoB6o6bJjZ283ZLABcK-uCYoTOwnd3uDb3llkMWn4E1Y0LGgU7yPBYSsGFq6HgsTR3rUTHzYIahHVGqP3mWeBLKztZQQPNuoCkq7N_vqMroYtm2yuXYhH09QbNluet8Oj8XhuRh9GY0MnFebX7vKkIHV_jwMJfO8v9Qv_m7A86vuCctEwL7xuUkxZLbcpseTHr-WW4Wmcq7mAdAPwWjLQokP_X8_RMDw-WJmKX4w4-_-3ysnb3lWM3HsDjaLvnqWTBWyo8dQnQiEVp8f8RyWuRX_HvgVAvUeVid0VCgHsi24crxHcxhOmNj9L5gKTLW5oDdPh8xxueJO3OHS7fMHj1FMhzRbOaaGest2SLu_RZXC3vjHTIFHbM5nCfXeH6rEUOttAvPgobLp7X3qMaDxNp-CzOYTS5Q9q2GHTF_V6ggk9gKgWEjl-EK4BLpvbRIAWmcu-SaNIf9EMAPigubWUZNkudyE8QcY_PkmRJaBYROiN0UQ8zxeTpFU2kSydUn5eysv6__y8llHCCSfGK-eftf5A7QjPYad3nxyNEEUTW5SRZckLnhM4HGUSfoK5hbVGLlm2Q_YVQ1VAG8MKM8iG4R4WGOcz7Lch1oQ9I6Lop-oSuLVP5Vh9DeQ6SSDJLhiSZDTLPyVD4_E0KVRcg7ATK3AJz4AoEVDnoXbgNIeITljbAmZRA0vlHVF9EjRo2YjYKOKwPyjd5T9LVN6l6ZbX2mWuDvjuZZQn1V6-20qHk3lMeCM18exSRZNWGbr-T_7M_qdMkXf3R_H0XzIl3WvoYdKmFcr5m3IHdJpfs23qIFvp3wD0Mtv4o7re6F5-GL3l008-ZY1-rWLc4M6hHbzX8LgoGx8QfYdN71LPiFbvqhWdXf_0IvUZp9tEg-TO1Om3VV3HUHerWdOjG07dqeMl4vujQKxIumJQ-iXbz2U4HGt6t_S3Mj9TOd-eCe6m6Bf7hTH3TkTzMsH_c1hln0FcZYLapF4_7gJmUjXiLZ2QGgXFXMSlP0EXuCl3tiz78XjBfCy2gLZGLMI9rtasbTWHBFczB4QRkFN_rXkexn4RHxp08BdWtP_Ex6xe8oyEdhUaMWTjpCjhTYBF9eSvQoC9NdFw4V1q_BV0Tut4LV1TbPteHOnyk2J7jaCu1f2h6nkdhRpNfMjqOfsmGbzVG51P3Dz7p3rfKz7NufdZd__3LZvH5H799Wf37138-sNXPE-_87XPCTOVwwhDMz2is0PV5oRC8gE_AdSl8XtDhrCRUhcCcJ727-tXKS8o1WuWLD-zFM96kxLqb7EMvnyb5JJmwHk4Ho4zS4TAexL1iynGYMzbYceQszbIEc5qPdsMtplk-GQ8HPTGlMaUDSseD0SBJ4n48HiRxng5oHu-242xMhjEemJB9KZ8PfW32PWFthdN0kiVJT7ItSht-iaNU4QuEQV8f0mXPTP2aaFvtLRnGUlhnL7s44SRO10xahFJb4bx2WsH7W-xeZeT0jYTlRTZfUWl03ZWvA1BL6Doo8r8AAAD__6x6a1E">