Skip to content

Commit 8f2d2a7

Browse files
committed
For PR45333: Move AnalyzeImplicitConversions to using data recursion
instead of recursing on the stack. This doesn't actually resolve PR45333, because we now hit stack overflow somewhere else, but it does get us further. I've not found any way of testing this that doesn't still crash elsewhere.
1 parent 8115e08 commit 8f2d2a7

File tree

1 file changed

+33
-10
lines changed

1 file changed

+33
-10
lines changed

clang/lib/Sema/SemaChecking.cpp

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11649,19 +11649,30 @@ static void CheckBoolLikeConversion(Sema &S, Expr *E, SourceLocation CC) {
1164911649
CheckImplicitConversion(S, E->IgnoreParenImpCasts(), S.Context.BoolTy, CC);
1165011650
}
1165111651

11652-
/// AnalyzeImplicitConversions - Find and report any interesting
11653-
/// implicit conversions in the given expression. There are a couple
11654-
/// of competing diagnostics here, -Wconversion and -Wsign-compare.
11655-
static void AnalyzeImplicitConversions(Sema &S, Expr *OrigE, SourceLocation CC,
11656-
bool IsListInit/*= false*/) {
11652+
namespace {
11653+
struct AnalyzeImplicitConversionsWorkItem {
11654+
Expr *E;
11655+
SourceLocation CC;
11656+
bool IsListInit;
11657+
};
11658+
}
11659+
11660+
/// Data recursive variant of AnalyzeImplicitConversions. Subexpressions
11661+
/// that should be visited are added to WorkList.
11662+
static void AnalyzeImplicitConversions(
11663+
Sema &S, AnalyzeImplicitConversionsWorkItem Item,
11664+
llvm::SmallVectorImpl<AnalyzeImplicitConversionsWorkItem> &WorkList) {
11665+
Expr *OrigE = Item.E;
11666+
SourceLocation CC = Item.CC;
11667+
1165711668
QualType T = OrigE->getType();
1165811669
Expr *E = OrigE->IgnoreParenImpCasts();
1165911670

1166011671
// Propagate whether we are in a C++ list initialization expression.
1166111672
// If so, we do not issue warnings for implicit int-float conversion
1166211673
// precision loss, because C++11 narrowing already handles it.
11663-
IsListInit =
11664-
IsListInit || (isa<InitListExpr>(OrigE) && S.getLangOpts().CPlusPlus);
11674+
bool IsListInit = Item.IsListInit ||
11675+
(isa<InitListExpr>(OrigE) && S.getLangOpts().CPlusPlus);
1166511676

1166611677
if (E->isTypeDependent() || E->isValueDependent())
1166711678
return;
@@ -11707,15 +11718,16 @@ static void AnalyzeImplicitConversions(Sema &S, Expr *OrigE, SourceLocation CC,
1170711718
// FIXME: Use a more uniform representation for this.
1170811719
for (auto *SE : POE->semantics())
1170911720
if (auto *OVE = dyn_cast<OpaqueValueExpr>(SE))
11710-
AnalyzeImplicitConversions(S, OVE->getSourceExpr(), CC, IsListInit);
11721+
WorkList.push_back({OVE->getSourceExpr(), CC, IsListInit});
1171111722
}
1171211723

1171311724
// Skip past explicit casts.
1171411725
if (auto *CE = dyn_cast<ExplicitCastExpr>(E)) {
1171511726
E = CE->getSubExpr()->IgnoreParenImpCasts();
1171611727
if (!CE->getType()->isVoidType() && E->getType()->isAtomicType())
1171711728
S.Diag(E->getBeginLoc(), diag::warn_atomic_implicit_seq_cst);
11718-
return AnalyzeImplicitConversions(S, E, CC, IsListInit);
11729+
WorkList.push_back({E, CC, IsListInit});
11730+
return;
1171911731
}
1172011732

1172111733
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
@@ -11754,7 +11766,7 @@ static void AnalyzeImplicitConversions(Sema &S, Expr *OrigE, SourceLocation CC,
1175411766
// Ignore checking string literals that are in logical and operators.
1175511767
// This is a common pattern for asserts.
1175611768
continue;
11757-
AnalyzeImplicitConversions(S, ChildExpr, CC, IsListInit);
11769+
WorkList.push_back({ChildExpr, CC, IsListInit});
1175811770
}
1175911771

1176011772
if (BO && BO->isLogicalOp()) {
@@ -11778,6 +11790,17 @@ static void AnalyzeImplicitConversions(Sema &S, Expr *OrigE, SourceLocation CC,
1177811790
}
1177911791
}
1178011792

11793+
/// AnalyzeImplicitConversions - Find and report any interesting
11794+
/// implicit conversions in the given expression. There are a couple
11795+
/// of competing diagnostics here, -Wconversion and -Wsign-compare.
11796+
static void AnalyzeImplicitConversions(Sema &S, Expr *OrigE, SourceLocation CC,
11797+
bool IsListInit/*= false*/) {
11798+
llvm::SmallVector<AnalyzeImplicitConversionsWorkItem, 16> WorkList;
11799+
WorkList.push_back({OrigE, CC, IsListInit});
11800+
while (!WorkList.empty())
11801+
AnalyzeImplicitConversions(S, WorkList.pop_back_val(), WorkList);
11802+
}
11803+
1178111804
/// Diagnose integer type and any valid implicit conversion to it.
1178211805
static bool checkOpenCLEnqueueIntType(Sema &S, Expr *E, const QualType &IntT) {
1178311806
// Taking into account implicit conversions,

0 commit comments

Comments
 (0)