Tyker updated this revision to Diff 194684.
Tyker added a comment.

@Quuxplusone  edited based of feedback

i simplified the test but didn't put the original because this one test 
arguments for variable and literal and there may be corner case differences


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D60561/new/

https://reviews.llvm.org/D60561

Files:
  clang/lib/AST/ExprConstant.cpp
  clang/test/SemaCXX/constant-expression-cxx1y.cpp

Index: clang/test/SemaCXX/constant-expression-cxx1y.cpp
===================================================================
--- clang/test/SemaCXX/constant-expression-cxx1y.cpp
+++ clang/test/SemaCXX/constant-expression-cxx1y.cpp
@@ -1159,3 +1159,18 @@
 enum class InEnum3 {
   THREE = indirect_builtin_constant_p("abc")
 };
+
+constexpr int f1(int i) {
+  i -= 1;
+  return 1 << i; // expected-note {{negative shift count -2}}
+}
+
+constexpr int f2(int i) {
+  i -= 1;
+  // expected-note@+1 {{'f1(-1)}}
+  return f1(i);
+}
+
+// expected-error@+2 {{constant expression}}
+// expected-note@+1 {{'f2(0)}}
+constexpr int a = f2(0);
Index: clang/lib/AST/ExprConstant.cpp
===================================================================
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -476,9 +476,14 @@
     const LValue *This;
 
     /// Arguments - Parameter bindings for this function call, indexed by
-    /// parameters' function scope indices.
+    /// parameters' function scope indices. may be modified by called function
     APValue *Arguments;
 
+    /// ConstantArgs - Parameter bindings for this function call, indexed by
+    /// parameters' function scope indices. can't be modified. used for
+    /// diagnostics
+    const APValue *ConstantArgs;
+
     // Note that we intentionally use std::map here so that references to
     // values are stable.
     typedef std::pair<const void *, unsigned> MapKeyTy;
@@ -519,7 +524,7 @@
 
     CallStackFrame(EvalInfo &Info, SourceLocation CallLoc,
                    const FunctionDecl *Callee, const LValue *This,
-                   APValue *Arguments);
+                   APValue *Arguments, const APValue *ConstantArgs);
     ~CallStackFrame();
 
     // Return the temporary for Key whose version number is Version.
@@ -789,14 +794,15 @@
     bool checkingForOverflow() { return EvalMode == EM_EvaluateForOverflow; }
 
     EvalInfo(const ASTContext &C, Expr::EvalStatus &S, EvaluationMode Mode)
-      : Ctx(const_cast<ASTContext &>(C)), EvalStatus(S), CurrentCall(nullptr),
-        CallStackDepth(0), NextCallIndex(1),
-        StepsLeft(getLangOpts().ConstexprStepLimit),
-        BottomFrame(*this, SourceLocation(), nullptr, nullptr, nullptr),
-        EvaluatingDecl((const ValueDecl *)nullptr),
-        EvaluatingDeclValue(nullptr), HasActiveDiagnostic(false),
-        HasFoldFailureDiagnostic(false), IsSpeculativelyEvaluating(false),
-        InConstantContext(false), EvalMode(Mode) {}
+        : Ctx(const_cast<ASTContext &>(C)), EvalStatus(S), CurrentCall(nullptr),
+          CallStackDepth(0), NextCallIndex(1),
+          StepsLeft(getLangOpts().ConstexprStepLimit),
+          BottomFrame(*this, SourceLocation(), nullptr, nullptr, nullptr,
+                      nullptr),
+          EvaluatingDecl((const ValueDecl *)nullptr),
+          EvaluatingDeclValue(nullptr), HasActiveDiagnostic(false),
+          HasFoldFailureDiagnostic(false), IsSpeculativelyEvaluating(false),
+          InConstantContext(false), EvalMode(Mode) {}
 
     void setEvaluatingDecl(APValue::LValueBase Base, APValue &Value) {
       EvaluatingDecl = Base;
@@ -1235,9 +1241,10 @@
 
 CallStackFrame::CallStackFrame(EvalInfo &Info, SourceLocation CallLoc,
                                const FunctionDecl *Callee, const LValue *This,
-                               APValue *Arguments)
+                               APValue *Arguments, const APValue *CArgs)
     : Info(Info), Caller(Info.CurrentCall), Callee(Callee), This(This),
-      Arguments(Arguments), CallLoc(CallLoc), Index(Info.NextCallIndex++) {
+      Arguments(Arguments), ConstantArgs(CArgs), CallLoc(CallLoc),
+      Index(Info.NextCallIndex++) {
   Info.CurrentCall = this;
   ++Info.CallStackDepth;
 }
@@ -1679,7 +1686,7 @@
       Out << ", ";
 
     const ParmVarDecl *Param = *I;
-    const APValue &Arg = Frame->Arguments[ArgIndex];
+    const APValue &Arg = Frame->ConstantArgs[ArgIndex];
     Arg.printPretty(Out, Frame->Info.Ctx, Param->getType());
 
     if (ArgIndex == 0 && IsMemberCall)
@@ -4455,7 +4462,11 @@
   if (!Info.CheckCallLimit(CallLoc))
     return false;
 
-  CallStackFrame Frame(Info, CallLoc, Callee, This, ArgValues.data());
+  // ArgValues - may be modified by the called function.
+  // ConstantArgs - can't be modified by the called function
+  const ArgVector ConstantArgs(ArgValues.begin(), ArgValues.end());
+  CallStackFrame Frame(Info, CallLoc, Callee, This, ArgValues.data(),
+                       ConstantArgs.data());
 
   // For a trivial copy or move assignment, perform an APValue copy. This is
   // essential for unions, where the operations performed by the assignment
@@ -4505,6 +4516,7 @@
 /// Evaluate a constructor call.
 static bool HandleConstructorCall(const Expr *E, const LValue &This,
                                   APValue *ArgValues,
+                                  APValue const *const ConstantArgs,
                                   const CXXConstructorDecl *Definition,
                                   EvalInfo &Info, APValue &Result) {
   SourceLocation CallLoc = E->getExprLoc();
@@ -4520,7 +4532,8 @@
   EvalInfo::EvaluatingConstructorRAII EvalObj(
       Info, {This.getLValueBase(),
              {This.getLValueCallIndex(), This.getLValueVersion()}});
-  CallStackFrame Frame(Info, CallLoc, Definition, &This, ArgValues);
+  CallStackFrame Frame(Info, CallLoc, Definition, &This, ArgValues,
+                       ConstantArgs);
 
   // FIXME: Creating an APValue just to hold a nonexistent return value is
   // wasteful.
@@ -4667,8 +4680,9 @@
   if (!EvaluateArgs(Args, ArgValues, Info))
     return false;
 
-  return HandleConstructorCall(E, This, ArgValues.data(), Definition,
-                               Info, Result);
+  ArgVector ConstantArgs(ArgValues.begin(), ArgValues.end());
+  return HandleConstructorCall(E, This, ArgValues.data(), ConstantArgs.data(),
+                               Definition, Info, Result);
 }
 
 //===----------------------------------------------------------------------===//
@@ -6791,9 +6805,9 @@
   if (!CheckConstexprFunction(Info, E->getExprLoc(), FD, Definition, Body))
     return false;
 
-  return HandleConstructorCall(E, This, Info.CurrentCall->Arguments,
-                               cast<CXXConstructorDecl>(Definition), Info,
-                               Result);
+  return HandleConstructorCall(
+      E, This, Info.CurrentCall->Arguments, Info.CurrentCall->ConstantArgs,
+      cast<CXXConstructorDecl>(Definition), Info, Result);
 }
 
 bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
@@ -11799,9 +11813,10 @@
       return false;
   }
 
+  const ArgVector ConstantArgs(ArgValues.begin(), ArgValues.end());
   // Build fake call to Callee.
   CallStackFrame Frame(Info, Callee->getLocation(), Callee, ThisPtr,
-                       ArgValues.data());
+                       ArgValues.data(), ConstantArgs.data());
   return Evaluate(Value, Info, this) && !Info.EvalStatus.HasSideEffects;
 }
 
@@ -11865,7 +11880,9 @@
   (void)Success;
   assert(Success &&
          "Failed to set up arguments for potential constant evaluation");
-  CallStackFrame Frame(Info, SourceLocation(), FD, nullptr, ArgValues.data());
+  const ArgVector ConstantArgs(ArgValues.begin(), ArgValues.end());
+  CallStackFrame Frame(Info, SourceLocation(), FD, nullptr, ArgValues.data(),
+                       ConstantArgs.data());
 
   APValue ResultScratch;
   Evaluate(ResultScratch, Info, E);
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to