Author: ogoffart Date: Fri Feb 12 06:34:44 2016 New Revision: 260675 URL: http://llvm.org/viewvc/llvm-project?rev=260675&view=rev Log: Fix ICE with constexpr and friend functions
Fix a crash while parsing this code: struct X { friend constexpr int foo(X*) { return 12; } static constexpr int j = foo(static_cast<X*>(nullptr)); }; Differential Revision: http://reviews.llvm.org/D16973 Modified: cfe/trunk/lib/AST/ExprConstant.cpp cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp Modified: cfe/trunk/lib/AST/ExprConstant.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=260675&r1=260674&r2=260675&view=diff ============================================================================== --- cfe/trunk/lib/AST/ExprConstant.cpp (original) +++ cfe/trunk/lib/AST/ExprConstant.cpp Fri Feb 12 06:34:44 2016 @@ -3736,7 +3736,8 @@ static bool CheckTrivialDefaultConstruct /// expression. static bool CheckConstexprFunction(EvalInfo &Info, SourceLocation CallLoc, const FunctionDecl *Declaration, - const FunctionDecl *Definition) { + const FunctionDecl *Definition, + const Stmt *Body) { // Potential constant expressions can contain calls to declared, but not yet // defined, constexpr functions. if (Info.checkingPotentialConstantExpression() && !Definition && @@ -3749,7 +3750,8 @@ static bool CheckConstexprFunction(EvalI return false; // Can we evaluate this function call? - if (Definition && Definition->isConstexpr() && !Definition->isInvalidDecl()) + if (Definition && Definition->isConstexpr() && + !Definition->isInvalidDecl() && Body) return true; if (Info.getLangOpts().CPlusPlus11) { @@ -4275,7 +4277,7 @@ public: const FunctionDecl *Definition = nullptr; Stmt *Body = FD->getBody(Definition); - if (!CheckConstexprFunction(Info, E->getExprLoc(), FD, Definition) || + if (!CheckConstexprFunction(Info, E->getExprLoc(), FD, Definition, Body) || !HandleFunctionCall(E->getExprLoc(), Definition, This, Args, Body, Info, Result, ResultSlot)) return false; @@ -5483,9 +5485,9 @@ bool RecordExprEvaluator::VisitCXXConstr } const FunctionDecl *Definition = nullptr; - FD->getBody(Definition); + auto Body = FD->getBody(Definition); - if (!CheckConstexprFunction(Info, E->getExprLoc(), FD, Definition)) + if (!CheckConstexprFunction(Info, E->getExprLoc(), FD, Definition, Body)) return false; // Avoid materializing a temporary for an elidable copy/move constructor. @@ -5971,9 +5973,9 @@ bool ArrayExprEvaluator::VisitCXXConstru } const FunctionDecl *Definition = nullptr; - FD->getBody(Definition); + auto Body = FD->getBody(Definition); - if (!CheckConstexprFunction(Info, E->getExprLoc(), FD, Definition)) + if (!CheckConstexprFunction(Info, E->getExprLoc(), FD, Definition, Body)) return false; if (ZeroInit && !HadZeroInit) { 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=260675&r1=260674&r2=260675&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp (original) +++ cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp Fri Feb 12 06:34:44 2016 @@ -2005,3 +2005,13 @@ namespace PR24597 { constexpr int a = *f().p; constexpr int b = *g().p; } + +namespace IncompleteClass { + struct XX { + static constexpr int f(XX*) { return 1; } // expected-note {{here}} + friend constexpr int g(XX*) { return 2; } // expected-note {{here}} + + static constexpr int i = f(static_cast<XX*>(nullptr)); // expected-error {{constexpr variable 'i' must be initialized by a constant expression}} expected-note {{undefined function 'f' cannot be used in a constant expression}} + static constexpr int j = g(static_cast<XX*>(nullptr)); // expected-error {{constexpr variable 'j' must be initialized by a constant expression}} expected-note {{undefined function 'g' cannot be used in a constant expression}} + }; +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits