Author: Takuya Shimizu Date: 2023-08-25T16:08:07+09:00 New Revision: 615d812696ee8827d6d78ad106d6022ff2778137
URL: https://github.com/llvm/llvm-project/commit/615d812696ee8827d6d78ad106d6022ff2778137 DIFF: https://github.com/llvm/llvm-project/commit/615d812696ee8827d6d78ad106d6022ff2778137.diff LOG: [clang][ExprConstant] Improve error message of compound assignment against uninitialized object BEFORE this patch, compound assignment operator against uninitialized object such as uninit += 1 was diagnosed as subexpression not valid This patch clarifies the reason for the error by saying that uninit is an uninitialized object. Fixes https://github.com/llvm/llvm-project/issues/51536 Reviewed By: shafik, tbaeder Differential Revision: https://reviews.llvm.org/D157855 Added: Modified: clang/docs/ReleaseNotes.rst clang/lib/AST/ExprConstant.cpp clang/test/SemaCXX/constant-expression-cxx14.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index a7c39bad615406..f0e601fc2df88b 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -140,6 +140,9 @@ Improvements to Clang's diagnostics 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 ------------------------- diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 51fdef708dde5a..d77c5d3f84a8d7 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -4442,6 +4442,10 @@ struct CompoundAssignSubobjectHandler { 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); diff --git a/clang/test/SemaCXX/constant-expression-cxx14.cpp b/clang/test/SemaCXX/constant-expression-cxx14.cpp index a43ee74e3df56c..273d7ff3a208e2 100644 --- a/clang/test/SemaCXX/constant-expression-cxx14.cpp +++ b/clang/test/SemaCXX/constant-expression-cxx14.cpp @@ -1275,3 +1275,33 @@ namespace TemporaryWithBadPointer { (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)'}} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits