Skip to content

Commit

Permalink
[clang][ExprConst] Fix crash on uninitialized array subobject (#67817)
Browse files Browse the repository at this point in the history
https://reviews.llvm.org/D146358 was assuming that all subobjects have
their own name (`SubobjectDecl`), but it was not true for array
elements.

Fixes #67317
  • Loading branch information
hazohelet authored and tru committed Oct 30, 2023
1 parent 8c8abe6 commit f6fb6a9
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 6 deletions.
2 changes: 2 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,8 @@ Bug Fixes in This Version
points (i.e., uses function descriptor objects instead).
- Fixes a ``clang-17`` regression where ``LLVM_UNREACHABLE_OPTIMIZE=OFF``
cannot be used with ``Release`` mode builds. (`#68237 <https://github.com/llvm/llvm-project/issues/68237>`_).
- Fix crash from constexpr evaluator evaluating uninitialized arrays as rvalue.
Fixes (`#67317 <https://github.com/llvm/llvm-project/issues/67317>`_)
- No longer use C++ ``thread_local`` semantics in C23 when using
``thread_local`` instead of ``_Thread_local``.
Fixes (`#70068 <https://github.com/llvm/llvm-project/issues/70068>`_) and
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/DiagnosticASTKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def note_consteval_address_accessible : Note<
"%select{pointer|reference}0 to a consteval declaration "
"is not a constant expression">;
def note_constexpr_uninitialized : Note<
"subobject %0 is not initialized">;
"subobject %select{of type |}0%1 is not initialized">;
def note_constexpr_uninitialized_base : Note<
"constructor of base class %0 is not called">;
def note_constexpr_static_local : Note<
Expand Down
13 changes: 9 additions & 4 deletions clang/lib/AST/ExprConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2379,10 +2379,15 @@ static bool CheckEvaluationResult(CheckEvaluationResultKind CERK,
const FieldDecl *SubobjectDecl,
CheckedTemporaries &CheckedTemps) {
if (!Value.hasValue()) {
assert(SubobjectDecl && "SubobjectDecl shall be non-null");
Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized) << SubobjectDecl;
Info.Note(SubobjectDecl->getLocation(),
diag::note_constexpr_subobject_declared_here);
if (SubobjectDecl) {
Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
<< /*(name)*/ 1 << SubobjectDecl;
Info.Note(SubobjectDecl->getLocation(),
diag::note_constexpr_subobject_declared_here);
} else {
Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
<< /*of type*/ 0 << Type;
}
return false;
}

Expand Down
3 changes: 2 additions & 1 deletion clang/lib/AST/Interp/Interp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,8 @@ bool CheckPure(InterpState &S, CodePtr OpPC, const CXXMethodDecl *MD) {
static void DiagnoseUninitializedSubobject(InterpState &S, const SourceInfo &SI,
const FieldDecl *SubObjDecl) {
assert(SubObjDecl && "Subobject declaration does not exist");
S.FFDiag(SI, diag::note_constexpr_uninitialized) << SubObjDecl;
S.FFDiag(SI, diag::note_constexpr_uninitialized)
<< /*(name)*/ 1 << SubObjDecl;
S.Note(SubObjDecl->getLocation(),
diag::note_constexpr_subobject_declared_here);
}
Expand Down
6 changes: 6 additions & 0 deletions clang/test/SemaCXX/constant-expression-cxx2a.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1492,3 +1492,9 @@ class B{
class D : B{}; // expected-error {{deleted function '~D' cannot override a non-deleted function}}
// expected-note@-1 {{destructor of 'D' is implicitly deleted because base class 'B' has an inaccessible destructor}}
}

namespace GH67317 {
constexpr unsigned char a = // expected-error {{constexpr variable 'a' must be initialized by a constant expression}} \
// expected-note {{subobject of type 'const unsigned char' is not initialized}}
__builtin_bit_cast(unsigned char, *new char[3][1]);
};
7 changes: 7 additions & 0 deletions clang/test/SemaCXX/eval-crashes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,10 @@ namespace pr33140_10 {
int a(const int &n = 0);
bool b() { return a() == a(); }
}

namespace GH67317 {
struct array {
int (&data)[2];
array() : data(*new int[1][2]) {}
};
}

0 comments on commit f6fb6a9

Please sign in to comment.