Author: faisalv Date: Sun Nov 13 00:09:16 2016 New Revision: 286748 URL: http://llvm.org/viewvc/llvm-project?rev=286748&view=rev Log: Fix PR28366: Handle variables from enclosing local scopes more gracefully during constant expression evaluation.
Only look for a variable's value in the constant expression evaluation activation frame, if the variable was indeed declared in that frame, otherwise it might be a constant expression and be usable within a nested local scope or emit an error. void f(char c) { struct X { static constexpr char f() { return c; // error gracefully here as opposed to crashing. } }; int I = X::f(); } Modified: cfe/trunk/lib/AST/ExprConstant.cpp cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp Modified: cfe/trunk/lib/AST/ExprConstant.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=286748&r1=286747&r2=286748&view=diff ============================================================================== --- cfe/trunk/lib/AST/ExprConstant.cpp (original) +++ cfe/trunk/lib/AST/ExprConstant.cpp Sun Nov 13 00:09:16 2016 @@ -4803,10 +4803,21 @@ bool LValueExprEvaluator::VisitDeclRefEx return Error(E); } + bool LValueExprEvaluator::VisitVarDecl(const Expr *E, const VarDecl *VD) { CallStackFrame *Frame = nullptr; - if (VD->hasLocalStorage() && Info.CurrentCall->Index > 1) - Frame = Info.CurrentCall; + if (VD->hasLocalStorage() && Info.CurrentCall->Index > 1) { + // Only if a local variable was declared in the function currently being + // evaluated, do we expect to be able to find its value in the current + // frame. (Otherwise it was likely declared in an enclosing context and + // could either have a valid evaluatable value (for e.g. a constexpr + // variable) or be ill-formed (and trigger an appropriate evaluation + // diagnostic)). + if (Info.CurrentCall->Callee && + Info.CurrentCall->Callee->Equals(VD->getDeclContext())) { + Frame = Info.CurrentCall; + } + } if (!VD->getType()->isReferenceType()) { if (Frame) { Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=286748&r1=286747&r2=286748&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Sun Nov 13 00:09:16 2016 @@ -188,7 +188,7 @@ static void instantiateDependentEnableIf SmallVector<PartialDiagnosticAt, 8> Diags; if (A->getCond()->isValueDependent() && !Cond->isValueDependent() && - !Expr::isPotentialConstantExprUnevaluated(Cond, cast<FunctionDecl>(Tmpl), + !Expr::isPotentialConstantExprUnevaluated(Cond, cast<FunctionDecl>(New), Diags)) { S.Diag(A->getLocation(), diag::err_enable_if_never_constant_expr); for (int I = 0, N = Diags.size(); I != N; ++I) Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp?rev=286748&r1=286747&r2=286748&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp (original) +++ cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp Sun Nov 13 00:09:16 2016 @@ -2066,3 +2066,33 @@ namespace InheritedCtor { constexpr Z z(1); static_assert(z.w == 1 && z.x == 2 && z.y == 3 && z.z == 4, ""); } + + +namespace PR28366 { +namespace ns1 { + +void f(char c) { //expected-note2{{declared here}} + struct X { + static constexpr char f() { //expected-error{{never produces a constant expression}} + return c; //expected-error{{reference to local}} expected-note{{non-const variable}} + } + }; + int I = X::f(); +} + +void g() { + const int c = 'c'; + static const int d = 'd'; + struct X { + static constexpr int f() { + return c + d; + } + }; + static_assert(X::f() == 'c' + 'd',""); +} + + +} // end ns1 + +} //end ns PR28366 + Modified: cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp?rev=286748&r1=286747&r2=286748&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp (original) +++ cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp Sun Nov 13 00:09:16 2016 @@ -46,5 +46,17 @@ namespace ns3 { } // end ns test_constexpr_call -#endif // ndef CPP14_AND_EARLIER +namespace test_captureless_lambda { +void f() { + const char c = 'c'; + auto L = [] { return c; }; + constexpr char C = L(); +} + +void f(char c) { //expected-note{{declared here}} + auto L = [] { return c; }; //expected-error{{cannot be implicitly captured}} expected-note{{lambda expression begins here}} + int I = L(); +} +} +#endif // ndef CPP14_AND_EARLIER _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits