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.

  When calling functions in the checkingPotentialConstantExpression mode,
  we cannot have arguments (including This + RVO pointers) for the
  toplevel callee, but the functions called from within can work just
  fine, or at least we succeed in pushing their arguments on the stack, so
  we must also succeed in removing them again.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D150358

Files:
  clang/lib/AST/Interp/Interp.h
  clang/lib/AST/Interp/InterpBuiltin.cpp
  clang/test/AST/Interp/functions.cpp


Index: clang/test/AST/Interp/functions.cpp
===================================================================
--- clang/test/AST/Interp/functions.cpp
+++ clang/test/AST/Interp/functions.cpp
@@ -257,3 +257,11 @@
                    // ref-note {{in call to 'SS()'}}
 
 }
+
+namespace CallWithArgs {
+  /// This used to call problems during checkPotentialConstantExpression() 
runs.
+  constexpr void g(int a) {}
+  constexpr void f() {
+    g(0);
+  }
+}
Index: clang/lib/AST/Interp/InterpBuiltin.cpp
===================================================================
--- clang/lib/AST/Interp/InterpBuiltin.cpp
+++ clang/lib/AST/Interp/InterpBuiltin.cpp
@@ -65,12 +65,12 @@
   switch (F->getBuiltinID()) {
   case Builtin::BI__builtin_is_constant_evaluated:
     S.Stk.push<Boolean>(Boolean::from(S.inConstantContext()));
-    return Ret<PT_Bool, true>(S, OpPC, Dummy);
+    return Ret<PT_Bool>(S, OpPC, Dummy);
   case Builtin::BI__builtin_assume:
-    return RetVoid<true>(S, OpPC, Dummy);
+    return RetVoid(S, OpPC, Dummy);
   case Builtin::BI__builtin_strcmp:
     if (interp__builtin_strcmp(S, OpPC, Frame))
-      return Ret<PT_Sint32, true>(S, OpPC, Dummy);
+      return Ret<PT_Sint32>(S, OpPC, Dummy);
     return false;
   default:
     return false;
Index: clang/lib/AST/Interp/Interp.h
===================================================================
--- clang/lib/AST/Interp/Interp.h
+++ clang/lib/AST/Interp/Interp.h
@@ -192,13 +192,12 @@
 // Returning values
 
//===----------------------------------------------------------------------===//
 
-template <PrimType Name, bool Builtin = false,
-          class T = typename PrimConv<Name>::T>
+template <PrimType Name, class T = typename PrimConv<Name>::T>
 bool Ret(InterpState &S, CodePtr &PC, APValue &Result) {
   const T &Ret = S.Stk.pop<T>();
 
   assert(S.Current->getFrameOffset() == S.Stk.size() && "Invalid frame");
-  if (Builtin || !S.checkingPotentialConstantExpression())
+  if (!S.checkingPotentialConstantExpression() || S.Current->Caller)
     S.Current->popArgs();
 
   if (InterpFrame *Caller = S.Current->Caller) {
@@ -215,10 +214,9 @@
   return true;
 }
 
-template <bool Builtin = false>
 inline bool RetVoid(InterpState &S, CodePtr &PC, APValue &Result) {
   assert(S.Current->getFrameOffset() == S.Stk.size() && "Invalid frame");
-  if (Builtin || !S.checkingPotentialConstantExpression())
+  if (!S.checkingPotentialConstantExpression() || S.Current->Caller)
     S.Current->popArgs();
 
   if (InterpFrame *Caller = S.Current->Caller) {


Index: clang/test/AST/Interp/functions.cpp
===================================================================
--- clang/test/AST/Interp/functions.cpp
+++ clang/test/AST/Interp/functions.cpp
@@ -257,3 +257,11 @@
                    // ref-note {{in call to 'SS()'}}
 
 }
+
+namespace CallWithArgs {
+  /// This used to call problems during checkPotentialConstantExpression() runs.
+  constexpr void g(int a) {}
+  constexpr void f() {
+    g(0);
+  }
+}
Index: clang/lib/AST/Interp/InterpBuiltin.cpp
===================================================================
--- clang/lib/AST/Interp/InterpBuiltin.cpp
+++ clang/lib/AST/Interp/InterpBuiltin.cpp
@@ -65,12 +65,12 @@
   switch (F->getBuiltinID()) {
   case Builtin::BI__builtin_is_constant_evaluated:
     S.Stk.push<Boolean>(Boolean::from(S.inConstantContext()));
-    return Ret<PT_Bool, true>(S, OpPC, Dummy);
+    return Ret<PT_Bool>(S, OpPC, Dummy);
   case Builtin::BI__builtin_assume:
-    return RetVoid<true>(S, OpPC, Dummy);
+    return RetVoid(S, OpPC, Dummy);
   case Builtin::BI__builtin_strcmp:
     if (interp__builtin_strcmp(S, OpPC, Frame))
-      return Ret<PT_Sint32, true>(S, OpPC, Dummy);
+      return Ret<PT_Sint32>(S, OpPC, Dummy);
     return false;
   default:
     return false;
Index: clang/lib/AST/Interp/Interp.h
===================================================================
--- clang/lib/AST/Interp/Interp.h
+++ clang/lib/AST/Interp/Interp.h
@@ -192,13 +192,12 @@
 // Returning values
 //===----------------------------------------------------------------------===//
 
-template <PrimType Name, bool Builtin = false,
-          class T = typename PrimConv<Name>::T>
+template <PrimType Name, class T = typename PrimConv<Name>::T>
 bool Ret(InterpState &S, CodePtr &PC, APValue &Result) {
   const T &Ret = S.Stk.pop<T>();
 
   assert(S.Current->getFrameOffset() == S.Stk.size() && "Invalid frame");
-  if (Builtin || !S.checkingPotentialConstantExpression())
+  if (!S.checkingPotentialConstantExpression() || S.Current->Caller)
     S.Current->popArgs();
 
   if (InterpFrame *Caller = S.Current->Caller) {
@@ -215,10 +214,9 @@
   return true;
 }
 
-template <bool Builtin = false>
 inline bool RetVoid(InterpState &S, CodePtr &PC, APValue &Result) {
   assert(S.Current->getFrameOffset() == S.Stk.size() && "Invalid frame");
-  if (Builtin || !S.checkingPotentialConstantExpression())
+  if (!S.checkingPotentialConstantExpression() || S.Current->Caller)
     S.Current->popArgs();
 
   if (InterpFrame *Caller = S.Current->Caller) {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to