Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -132,6 +132,9 @@ - Clang now warns on unused variables declared and initialized in condition expressions. (`#61681: `_) +- Clang constexpr evaluator now diagnoses compound assignment operators against + uninitialized variables as a read of uninitialized object. + (`#51536 _`) Bug Fixes in This Version ------------------------- Index: clang/lib/AST/ExprConstant.cpp =================================================================== --- clang/lib/AST/ExprConstant.cpp +++ clang/lib/AST/ExprConstant.cpp @@ -4442,6 +4442,10 @@ return foundPointer(Subobj, SubobjType); case APValue::Vector: return foundVector(Subobj, SubobjType); + case APValue::Indeterminate: + Info.FFDiag(E, diag::note_constexpr_access_uninit) + << /*read of=*/0 << /*uninitialized object=*/1; + return false; default: // FIXME: can this happen? Info.FFDiag(E); Index: clang/test/SemaCXX/constant-expression-cxx14.cpp =================================================================== --- clang/test/SemaCXX/constant-expression-cxx14.cpp +++ clang/test/SemaCXX/constant-expression-cxx14.cpp @@ -1275,3 +1275,33 @@ (dbt2.wp = nullptr, 0) }; } + +namespace UninitCompoundAssign { +constexpr int scalar(int a) { + int sum; // cxx14-warning {{uninitialized variable in a constexpr function is a C++20 extension}} + sum += a; // expected-note {{read of uninitialized object}}; + return 0; +} +static_assert(scalar(3), ""); // expected-error {{constant expression}} \ + // expected-note {{in call to 'scalar(3)'}} + +constexpr int array(int a) { + int arr[3]; // cxx14-warning {{uninitialized variable in a constexpr function is a C++20 extension}} + arr[1] += a; // expected-note {{read of uninitialized object}}; + return 0; +} +static_assert(array(3), ""); // expected-error {{constant expression}} \ + // expected-note {{in call to 'array(3)'}} + +struct Foo { + int val; // cxx14-note{{member not initialized by constructor}} + constexpr Foo() {} // cxx14-warning {{constexpr constructor that does not initialize all members is a C++20 extension}} +}; +constexpr int field(int a) { + Foo f; + f.val += a; // expected-note {{read of uninitialized object}}; + return 0; +} +static_assert(field(3), ""); // expected-error {{constant expression}} \ + // expected-note {{in call to 'field(3)'}} +}