Skip to content

Commit

Permalink
[clang][Interp] Handle goto and label statements
Browse files Browse the repository at this point in the history
  • Loading branch information
tbaederr committed Mar 15, 2024
1 parent c42bc2e commit 8ab0632
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 13 deletions.
14 changes: 6 additions & 8 deletions clang/lib/AST/Interp/ByteCodeStmtGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -273,15 +273,18 @@ bool ByteCodeStmtGen<Emitter>::visitStmt(const Stmt *S) {
return visitCaseStmt(cast<CaseStmt>(S));
case Stmt::DefaultStmtClass:
return visitDefaultStmt(cast<DefaultStmt>(S));
case Stmt::GCCAsmStmtClass:
case Stmt::MSAsmStmtClass:
return visitAsmStmt(cast<AsmStmt>(S));
case Stmt::AttributedStmtClass:
return visitAttributedStmt(cast<AttributedStmt>(S));
case Stmt::CXXTryStmtClass:
return visitCXXTryStmt(cast<CXXTryStmt>(S));
case Stmt::NullStmtClass:
return true;
// Always invalid statements.
case Stmt::GCCAsmStmtClass:
case Stmt::MSAsmStmtClass:
case Stmt::GotoStmtClass:
case Stmt::LabelStmtClass:
return this->emitInvalid(S);
default: {
if (auto *Exp = dyn_cast<Expr>(S))
return this->discard(Exp);
Expand Down Expand Up @@ -657,11 +660,6 @@ bool ByteCodeStmtGen<Emitter>::visitDefaultStmt(const DefaultStmt *S) {
return this->visitStmt(S->getSubStmt());
}

template <class Emitter>
bool ByteCodeStmtGen<Emitter>::visitAsmStmt(const AsmStmt *S) {
return this->emitInvalid(S);
}

template <class Emitter>
bool ByteCodeStmtGen<Emitter>::visitAttributedStmt(const AttributedStmt *S) {
// Ignore all attributes.
Expand Down
1 change: 0 additions & 1 deletion clang/lib/AST/Interp/ByteCodeStmtGen.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ class ByteCodeStmtGen final : public ByteCodeExprGen<Emitter> {
bool visitSwitchStmt(const SwitchStmt *S);
bool visitCaseStmt(const CaseStmt *S);
bool visitDefaultStmt(const DefaultStmt *S);
bool visitAsmStmt(const AsmStmt *S);
bool visitAttributedStmt(const AttributedStmt *S);
bool visitCXXTryStmt(const CXXTryStmt *S);

Expand Down
24 changes: 20 additions & 4 deletions clang/test/AST/Interp/cxx23.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -std=c++20 -fsyntax-only -fcxx-exceptions -verify=ref20,all,all-20 %s
// RUN: %clang_cc1 -std=c++20 -fsyntax-only -fcxx-exceptions -verify=ref20,all,all20 %s
// RUN: %clang_cc1 -std=c++23 -fsyntax-only -fcxx-exceptions -verify=ref23,all %s
// RUN: %clang_cc1 -std=c++20 -fsyntax-only -fcxx-exceptions -verify=expected20,all,all-20 %s -fexperimental-new-constant-interpreter
// RUN: %clang_cc1 -std=c++20 -fsyntax-only -fcxx-exceptions -verify=expected20,all,all20 %s -fexperimental-new-constant-interpreter
// RUN: %clang_cc1 -std=c++23 -fsyntax-only -fcxx-exceptions -verify=expected23,all %s -fexperimental-new-constant-interpreter

/// FIXME: The new interpreter is missing all the 'control flows through...' diagnostics.
Expand Down Expand Up @@ -108,9 +108,9 @@ namespace StaticOperators {
static_assert(f2() == 3);

struct S1 {
constexpr S1() { // all-20-error {{never produces a constant expression}}
constexpr S1() { // all20-error {{never produces a constant expression}}
throw; // all-note {{not valid in a constant expression}} \
// all-20-note {{not valid in a constant expression}}
// all20-note {{not valid in a constant expression}}
}
static constexpr int operator()() { return 3; } // ref20-warning {{C++23 extension}} \
// expected20-warning {{C++23 extension}}
Expand All @@ -121,3 +121,19 @@ namespace StaticOperators {


}

int test_in_lambdas() {
auto c = [](int n) constexpr {
if (n == 0)
return 0;
else
goto test; // all-note {{subexpression not valid in a constant expression}} \
// all20-warning {{use of this statement in a constexpr function is a C++23 extension}}
test:
return 1;
};
c(0);
constexpr auto A = c(1); // all-error {{must be initialized by a constant expression}} \
// all-note {{in call to}}
return 0;
}

0 comments on commit 8ab0632

Please sign in to comment.