Skip to content

Commit 56a636f

Browse files
committed
[clang][Interp] Implement StmtExprs
1 parent 2399d87 commit 56a636f

File tree

3 files changed

+39
-0
lines changed

3 files changed

+39
-0
lines changed

clang/lib/AST/Interp/Compiler.cpp

+26
Original file line numberDiff line numberDiff line change
@@ -3025,6 +3025,32 @@ bool Compiler<Emitter>::VisitCXXStdInitializerListExpr(
30253025
return this->emitInitFieldPtr(R->getField(1u)->Offset, E);
30263026
}
30273027

3028+
template <class Emitter>
3029+
bool Compiler<Emitter>::VisitStmtExpr(const StmtExpr *E) {
3030+
BlockScope<Emitter> BS(this);
3031+
3032+
const CompoundStmt *CS = E->getSubStmt();
3033+
const Stmt *Result = CS->getStmtExprResult();
3034+
for (const Stmt *S : CS->body()) {
3035+
if (S != Result) {
3036+
if (!this->visitStmt(S))
3037+
return false;
3038+
continue;
3039+
}
3040+
3041+
assert(S == Result);
3042+
// This better produces a value (i.e. is an expression).
3043+
if (const Expr *ResultExpr = dyn_cast<Expr>(S)) {
3044+
if (DiscardResult)
3045+
return this->discard(ResultExpr);
3046+
return this->delegate(ResultExpr);
3047+
}
3048+
return false;
3049+
}
3050+
3051+
return true;
3052+
}
3053+
30283054
template <class Emitter> bool Compiler<Emitter>::discard(const Expr *E) {
30293055
OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/true,
30303056
/*NewInitializing=*/false);

clang/lib/AST/Interp/Compiler.h

+1
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>,
183183
bool VisitExtVectorElementExpr(const ExtVectorElementExpr *E);
184184
bool VisitObjCBoxedExpr(const ObjCBoxedExpr *E);
185185
bool VisitCXXStdInitializerListExpr(const CXXStdInitializerListExpr *E);
186+
bool VisitStmtExpr(const StmtExpr *E);
186187

187188
// Statements.
188189
bool visitCompoundStmt(const CompoundStmt *S);

clang/test/AST/Interp/literals.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -1213,6 +1213,18 @@ constexpr int externvar1() { // both-error {{never produces a constant expressio
12131213
return arr[0]; // ref-note {{read of non-constexpr variable 'arr'}} \
12141214
// expected-note {{indexing of array without known bound}}
12151215
}
1216+
1217+
namespace StmtExprs {
1218+
constexpr int foo() {
1219+
({
1220+
int i;
1221+
for (i = 0; i < 76; i++) {}
1222+
i; // both-warning {{expression result unused}}
1223+
});
1224+
return 76;
1225+
}
1226+
static_assert(foo() == 76, "");
1227+
}
12161228
#endif
12171229

12181230
namespace Extern {

0 commit comments

Comments
 (0)