ogoffart created this revision. ogoffart added reviewers: rsmith, cfe-commits.
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)); }; I also added a test for the static function case because i don't think this was tested before. http://reviews.llvm.org/D16973 Files: lib/AST/ExprConstant.cpp test/SemaCXX/constant-expression-cxx11.cpp Index: test/SemaCXX/constant-expression-cxx11.cpp =================================================================== --- test/SemaCXX/constant-expression-cxx11.cpp +++ test/SemaCXX/constant-expression-cxx11.cpp @@ -2005,3 +2005,13 @@ 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}} + }; +} \ No newline at end of file Index: lib/AST/ExprConstant.cpp =================================================================== --- lib/AST/ExprConstant.cpp +++ lib/AST/ExprConstant.cpp @@ -3749,7 +3749,8 @@ return false; // Can we evaluate this function call? - if (Definition && Definition->isConstexpr() && !Definition->isInvalidDecl()) + if (Definition && Definition->isConstexpr() && !Definition->isInvalidDecl() + && Definition->getBody()) return true; if (Info.getLangOpts().CPlusPlus11) {
Index: test/SemaCXX/constant-expression-cxx11.cpp =================================================================== --- test/SemaCXX/constant-expression-cxx11.cpp +++ test/SemaCXX/constant-expression-cxx11.cpp @@ -2005,3 +2005,13 @@ 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}} + }; +} \ No newline at end of file Index: lib/AST/ExprConstant.cpp =================================================================== --- lib/AST/ExprConstant.cpp +++ lib/AST/ExprConstant.cpp @@ -3749,7 +3749,8 @@ return false; // Can we evaluate this function call? - if (Definition && Definition->isConstexpr() && !Definition->isInvalidDecl()) + if (Definition && Definition->isConstexpr() && !Definition->isInvalidDecl() + && Definition->getBody()) return true; if (Info.getLangOpts().CPlusPlus11) {
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits