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