tbaeder created this revision.
tbaeder added reviewers: aaron.ballman, erichkeane, tahonermann, shafik.
Herald added a project: All.
tbaeder requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

As discussed the other day. This fixes the diagnostics for the test case in 
`records.cpp`.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D150364

Files:
  clang/lib/AST/Interp/ByteCodeExprGen.cpp
  clang/lib/AST/Interp/ByteCodeExprGen.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,28 @@
+// RUN: %clang_cc1 -fcxx-exceptions -fexperimental-new-constant-interpreter -verify %s
+// RUN: %clang_cc1 -fcxx-exceptions -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;
+  }
+}
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 Unsupported : 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 Unsupported(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/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->emitUnsupported(E);
+}
+
 template <class Emitter> bool ByteCodeExprGen<Emitter>::discard(const Expr *E) {
   if (E->containsErrors())
     return false;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to