This revision was landed with ongoing or failed builds. This revision was automatically updated to reflect the committed changes. Closed by commit rG615d812696ee: [clang][ExprConstant] Improve error message of compound assignment against… (authored by hazohelet).
Changed prior to commit: https://reviews.llvm.org/D157855?vs=550216&id=553389#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D157855/new/ https://reviews.llvm.org/D157855 Files: clang/docs/ReleaseNotes.rst clang/lib/AST/ExprConstant.cpp clang/test/SemaCXX/constant-expression-cxx14.cpp 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)'}} +} 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/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -140,6 +140,9 @@ tautologies like ``x && !x`` and ``!x || x`` in expressions. This also makes ``-Winfinite-recursion`` diagnose more cases. (`#56035: <https://github.com/llvm/llvm-project/issues/56035>`_). +- Clang constexpr evaluator now diagnoses compound assignment operators against + uninitialized variables as a read of uninitialized object. + (`#51536 <https://github.com/llvm/llvm-project/issues/51536>_`) Bug Fixes in This Version -------------------------
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)'}} +} 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/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -140,6 +140,9 @@ tautologies like ``x && !x`` and ``!x || x`` in expressions. This also makes ``-Winfinite-recursion`` diagnose more cases. (`#56035: <https://github.com/llvm/llvm-project/issues/56035>`_). +- Clang constexpr evaluator now diagnoses compound assignment operators against + uninitialized variables as a read of uninitialized object. + (`#51536 <https://github.com/llvm/llvm-project/issues/51536>_`) Bug Fixes in This Version -------------------------
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits