tbaeder updated this revision to Diff 521568.
tbaeder marked an inline comment as done.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D150364/new/
https://reviews.llvm.org/D150364
Files:
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/lib/AST/Interp/ByteCodeExprGen.h
clang/lib/AST/Interp/ByteCodeStmtGen.cpp
clang/lib/AST/Interp/ByteCodeStmtGen.h
clang/lib/AST/Interp/Interp.h
clang/lib/AST/Interp/Opcodes.td
clang/test/AST/Interp/records.cpp
clang/test/AST/Interp/unsupported.cpp
Index: clang/test/AST/Interp/unsupported.cpp
===================================================================
--- /dev/null
+++ clang/test/AST/Interp/unsupported.cpp
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -fcxx-exceptions -std=c++20 -fexperimental-new-constant-interpreter -verify %s
+// RUN: %clang_cc1 -fcxx-exceptions -std=c++20 -verify=ref %s
+
+namespace Throw {
+
+ constexpr int ConditionalThrow(bool t) {
+ if (t)
+ throw 4; // expected-note {{subexpression not valid in a constant expression}} \
+ // ref-note {{subexpression not valid in a constant expression}}
+
+ return 0;
+ }
+
+ static_assert(ConditionalThrow(false) == 0, "");
+ static_assert(ConditionalThrow(true) == 0, ""); // expected-error {{not an integral constant expression}} \
+ // expected-note {{in call to 'ConditionalThrow(true)'}} \
+ // ref-error {{not an integral constant expression}} \
+ // ref-note {{in call to 'ConditionalThrow(true)'}}
+
+ constexpr int Throw() { // expected-error {{never produces a constant expression}} \
+ // ref-error {{never produces a constant expression}}
+ throw 5; // expected-note {{subexpression not valid in a constant expression}} \
+ // ref-note {{subexpression not valid in a constant expression}}
+ return 0;
+ }
+}
+
+namespace Asm {
+ constexpr int ConditionalAsm(bool t) {
+ if (t)
+ asm(""); // expected-note {{subexpression not valid in a constant expression}} \
+ // ref-note {{subexpression not valid in a constant expression}}
+
+ return 0;
+ }
+ static_assert(ConditionalAsm(false) == 0, "");
+ static_assert(ConditionalAsm(true) == 0, ""); // expected-error {{not an integral constant expression}} \
+ // expected-note {{in call to 'ConditionalAsm(true)'}} \
+ // ref-error {{not an integral constant expression}} \
+ // ref-note {{in call to 'ConditionalAsm(true)'}}
+
+
+ constexpr int Asm() { // expected-error {{never produces a constant expression}} \
+ // ref-error {{never produces a constant expression}}
+ __asm volatile(""); // expected-note {{subexpression not valid in a constant expression}} \
+ // ref-note {{subexpression not valid in a constant expression}}
+ return 0;
+ }
+}
Index: clang/test/AST/Interp/records.cpp
===================================================================
--- clang/test/AST/Interp/records.cpp
+++ clang/test/AST/Interp/records.cpp
@@ -328,7 +328,8 @@
struct S {
constexpr S() {}
constexpr ~S() noexcept(false) { throw 12; } // expected-error {{cannot use 'throw'}} \
- // expected-note {{declared here}} \
+ // expected-error {{never produces a constant expression}} \
+ // expected-note 2{{subexpression not valid}} \
// ref-error {{cannot use 'throw'}} \
// ref-error {{never produces a constant expression}} \
// ref-note 2{{subexpression not valid}}
@@ -336,7 +337,9 @@
constexpr int f() {
S{}; // ref-note {{in call to '&S{}->~S()'}}
- return 12; // expected-note {{undefined function '~S'}}
+
+ /// FIXME: Wrong source location below.
+ return 12; // expected-note {{in call to '&S{}->~S()'}}
}
static_assert(f() == 12); // expected-error {{not an integral constant expression}} \
// expected-note {{in call to 'f()'}} \
Index: clang/lib/AST/Interp/Opcodes.td
===================================================================
--- clang/lib/AST/Interp/Opcodes.td
+++ clang/lib/AST/Interp/Opcodes.td
@@ -627,3 +627,6 @@
let Types = [AllTypeClass];
let HasGroup = 1;
}
+
+// [] -> []
+def Invalid : Opcode {}
Index: clang/lib/AST/Interp/Interp.h
===================================================================
--- clang/lib/AST/Interp/Interp.h
+++ clang/lib/AST/Interp/Interp.h
@@ -1823,6 +1823,14 @@
return true;
}
+/// Just emit a diagnostic. The expression that caused emission of this
+/// op is not valid in a constant context.
+inline bool Invalid(InterpState &S, CodePtr OpPC) {
+ const SourceLocation &Loc = S.Current->getLocation(OpPC);
+ S.FFDiag(Loc, diag::note_invalid_subexpr_in_const_expr);
+ return false;
+}
+
//===----------------------------------------------------------------------===//
// Read opcode arguments
//===----------------------------------------------------------------------===//
Index: clang/lib/AST/Interp/ByteCodeStmtGen.h
===================================================================
--- clang/lib/AST/Interp/ByteCodeStmtGen.h
+++ clang/lib/AST/Interp/ByteCodeStmtGen.h
@@ -67,6 +67,7 @@
bool visitSwitchStmt(const SwitchStmt *S);
bool visitCaseStmt(const CaseStmt *S);
bool visitDefaultStmt(const DefaultStmt *S);
+ bool visitAsmStmt(const AsmStmt *S);
bool emitLambdaStaticInvokerBody(const CXXMethodDecl *MD);
Index: clang/lib/AST/Interp/ByteCodeStmtGen.cpp
===================================================================
--- clang/lib/AST/Interp/ByteCodeStmtGen.cpp
+++ clang/lib/AST/Interp/ByteCodeStmtGen.cpp
@@ -243,6 +243,9 @@
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::NullStmtClass:
return true;
default: {
@@ -617,6 +620,11 @@
return this->visitStmt(S->getSubStmt());
}
+template <class Emitter>
+bool ByteCodeStmtGen<Emitter>::visitAsmStmt(const AsmStmt *S) {
+ return this->emitInvalid(S);
+}
+
namespace clang {
namespace interp {
Index: clang/lib/AST/Interp/ByteCodeExprGen.h
===================================================================
--- clang/lib/AST/Interp/ByteCodeExprGen.h
+++ clang/lib/AST/Interp/ByteCodeExprGen.h
@@ -97,6 +97,7 @@
bool VisitTypeTraitExpr(const TypeTraitExpr *E);
bool VisitLambdaExpr(const LambdaExpr *E);
bool VisitPredefinedExpr(const PredefinedExpr *E);
+ bool VisitCXXThrowExpr(const CXXThrowExpr *E);
protected:
bool visitExpr(const Expr *E) override;
Index: clang/lib/AST/Interp/ByteCodeExprGen.cpp
===================================================================
--- clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -1102,6 +1102,14 @@
return this->visit(E->getFunctionName());
}
+template <class Emitter>
+bool ByteCodeExprGen<Emitter>::VisitCXXThrowExpr(const CXXThrowExpr *E) {
+ if (!this->discard(E->getSubExpr()))
+ return false;
+
+ return this->emitInvalid(E);
+}
+
template <class Emitter> bool ByteCodeExprGen<Emitter>::discard(const Expr *E) {
if (E->containsErrors())
return false;
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits