Skip to content

Commit 048b253

Browse files
committed
Refix MSVC Debug crash
1 parent 5591740 commit 048b253

File tree

2 files changed

+31
-25
lines changed

2 files changed

+31
-25
lines changed

libsolutil/Visitor.h

+12-1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,17 @@ struct VisitorFallback<R> { template<typename T> R operator()(T&&) const { retur
5656
template<>
5757
struct VisitorFallback<> { template<typename T> void operator()(T&&) const {} };
5858

59-
template <typename... Visitors> struct GenericVisitor: Visitors... { using Visitors::operator()...; };
59+
// MSVC. Empty base class optimization does not happen in some scenarios.
60+
// Enforcing it with __declspec(empty_bases) avoids MSVC Debug test crash
61+
// (Run-Time Check Failure #2 - Stack around the variable '....' was corrupted).
62+
// See https://docs.microsoft.com/en-us/cpp/cpp/empty-bases,
63+
// https://developercommunity.visualstudio.com/t/10005513.
64+
#if defined(_MSC_VER)
65+
#define SOLC_EMPTY_BASES __declspec(empty_bases)
66+
#else
67+
#define SOLC_EMPTY_BASES
68+
#endif
69+
70+
template <typename... Visitors> struct SOLC_EMPTY_BASES GenericVisitor: Visitors... { using Visitors::operator()...; };
6071
template <typename... Visitors> GenericVisitor(Visitors...) -> GenericVisitor<Visitors...>;
6172
}

libyul/optimiser/StructuralSimplifier.cpp

+19-24
Original file line numberDiff line numberDiff line change
@@ -93,32 +93,27 @@ void StructuralSimplifier::operator()(Block& _block)
9393

9494
void StructuralSimplifier::simplify(std::vector<yul::Statement>& _statements)
9595
{
96-
// Explicit local variables ifLambda, switchLambda, forLoopLambda are created to avoid MSVC C++17 Debug test crash
97-
// (Run-Time Check Failure #2 - Stack around the variable '....' was corrupted).
98-
// As soon as the issue is fixed, this workaround can be removed.
99-
auto ifLambda = [&](If& _ifStmt) -> OptionalStatements
100-
{
101-
if (expressionAlwaysTrue(*_ifStmt.condition))
102-
return {std::move(_ifStmt.body.statements)};
103-
else if (expressionAlwaysFalse(*_ifStmt.condition))
104-
return {vector<Statement>{}};
105-
return {};
106-
};
107-
auto switchLambda = [&](Switch& _switchStmt) -> OptionalStatements
108-
{
109-
if (std::optional<u256> const constExprVal = hasLiteralValue(*_switchStmt.expression))
110-
return replaceConstArgSwitch(_switchStmt, constExprVal.value());
111-
return {};
112-
};
113-
auto forLoopLambda = [&](ForLoop& _forLoop) -> OptionalStatements
114-
{
115-
if (expressionAlwaysFalse(*_forLoop.condition))
116-
return {std::move(_forLoop.pre.statements)};
117-
return {};
96+
util::GenericVisitor visitor{
97+
util::VisitorFallback<OptionalStatements>{},
98+
[&](If& _ifStmt) -> OptionalStatements {
99+
if (expressionAlwaysTrue(*_ifStmt.condition))
100+
return {std::move(_ifStmt.body.statements)};
101+
else if (expressionAlwaysFalse(*_ifStmt.condition))
102+
return {vector<Statement>{}};
103+
return {};
104+
},
105+
[&](Switch& _switchStmt) -> OptionalStatements {
106+
if (std::optional<u256> const constExprVal = hasLiteralValue(*_switchStmt.expression))
107+
return replaceConstArgSwitch(_switchStmt, constExprVal.value());
108+
return {};
109+
},
110+
[&](ForLoop& _forLoop) -> OptionalStatements {
111+
if (expressionAlwaysFalse(*_forLoop.condition))
112+
return {std::move(_forLoop.pre.statements)};
113+
return {};
114+
}
118115
};
119116

120-
util::GenericVisitor visitor{util::VisitorFallback<OptionalStatements>{}, ifLambda, switchLambda, forLoopLambda};
121-
122117
util::iterateReplacing(
123118
_statements,
124119
[&](Statement& _stmt) -> OptionalStatements

0 commit comments

Comments
 (0)