[clang] [clang] Fix a crash from nested ArrayInitLoopExpr (PR #67722)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 28 12:27:49 PDT 2023
https://github.com/isuckatcs updated https://github.com/llvm/llvm-project/pull/67722
>From fb0bf2fcc9d873ce9cf4269cfb6de8786ac6f343 Mon Sep 17 00:00:00 2001
From: isuckatcs <65320245+isuckatcs at users.noreply.github.com>
Date: Thu, 28 Sep 2023 20:43:23 +0200
Subject: [PATCH 1/2] [clang] Fix a crash from nested ArrayInitLoopExpr
When visiting an ArrayInitLoopExpr, clang creates a temporary
variable for the source array, however in a nested AILE this
variable is created multiple times, in every iteration as they
have the same AST node and clang is unable to differentiate them.
Fixes #57135
---
clang/lib/AST/ExprConstant.cpp | 11 ++++++-----
.../nested-array-init-loop-in-lambda-capture.cpp | 13 +++++++++++++
2 files changed, 19 insertions(+), 5 deletions(-)
create mode 100644 clang/test/AST/nested-array-init-loop-in-lambda-capture.cpp
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index fea06b97259fe31..a1f5c262ca10be3 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -10967,19 +10967,20 @@ bool ArrayExprEvaluator::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E) {
LValue Subobject = This;
Subobject.addArray(Info, E, CAT);
- bool Success = true;
for (EvalInfo::ArrayInitLoopIndex Index(Info); Index != Elements; ++Index) {
if (!EvaluateInPlace(Result.getArrayInitializedElt(Index),
Info, Subobject, E->getSubExpr()) ||
!HandleLValueArrayAdjustment(Info, E, Subobject,
CAT->getElementType(), 1)) {
- if (!Info.noteFailure())
- return false;
- Success = false;
+
+ // There's no need to try and evaluate the rest, as those are the exact
+ // same expressions.
+ std::ignore = Info.noteFailure();
+ return false;
}
}
- return Success;
+ return true;
}
bool ArrayExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E) {
diff --git a/clang/test/AST/nested-array-init-loop-in-lambda-capture.cpp b/clang/test/AST/nested-array-init-loop-in-lambda-capture.cpp
new file mode 100644
index 000000000000000..82d27380b637d03
--- /dev/null
+++ b/clang/test/AST/nested-array-init-loop-in-lambda-capture.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++17 -verify %s
+// RUN: %clang_cc1 -std=c++17 -verify=ref %s
+
+// ref-no-diagnostics
+// expected-no-diagnostics
+
+void used_to_crash() {
+ int s[2][2];
+
+ int arr[4];
+
+ arr[0] = [s] { return s[0][0]; }();
+}
>From 19c09fb7656ba3b2e170802adfd397dd9aa9fec9 Mon Sep 17 00:00:00 2001
From: isuckatcs <65320245+isuckatcs at users.noreply.github.com>
Date: Thu, 28 Sep 2023 21:26:40 +0200
Subject: [PATCH 2/2] wrapping the temporary into a scope
---
clang/lib/AST/ExprConstant.cpp | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index a1f5c262ca10be3..12b4d6b22c2c2bc 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -10950,6 +10950,9 @@ bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
}
bool ArrayExprEvaluator::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E) {
+
+ FullExpressionRAII Scope(Info);
+
LValue CommonLV;
if (E->getCommonExpr() &&
!Evaluate(Info.CurrentCall->createTemporary(
@@ -10967,20 +10970,19 @@ bool ArrayExprEvaluator::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E) {
LValue Subobject = This;
Subobject.addArray(Info, E, CAT);
+ bool Success = true;
for (EvalInfo::ArrayInitLoopIndex Index(Info); Index != Elements; ++Index) {
if (!EvaluateInPlace(Result.getArrayInitializedElt(Index),
Info, Subobject, E->getSubExpr()) ||
!HandleLValueArrayAdjustment(Info, E, Subobject,
CAT->getElementType(), 1)) {
-
- // There's no need to try and evaluate the rest, as those are the exact
- // same expressions.
- std::ignore = Info.noteFailure();
- return false;
+ if (!Info.noteFailure())
+ return false;
+ Success = false;
}
}
- return true;
+ return Success;
}
bool ArrayExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E) {
More information about the cfe-commits
mailing list