diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 218ce8101b50..0a2cc7b3d6d5 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -3742,8 +3742,12 @@ public: { return StmtVisitorTy::Visit(E->getReplacement()); } RetTy VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { return StmtVisitorTy::Visit(E->getExpr()); } - RetTy VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *E) - { return StmtVisitorTy::Visit(E->getExpr()); } + RetTy VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *E) { + // The initializer may not have been parsed yet, or might be erroneous. + if (!E->getExpr()) + return Error(E); + return StmtVisitorTy::Visit(E->getExpr()); + } // We cannot create any objects for which cleanups are required, so there is // nothing to do here; all cleanups must come from unevaluated subexpressions. RetTy VisitExprWithCleanups(const ExprWithCleanups *E) diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp b/clang/test/SemaCXX/constant-expression-cxx11.cpp index 363ca8c7d9d8..c7766878583a 100644 --- a/clang/test/SemaCXX/constant-expression-cxx11.cpp +++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp @@ -1776,3 +1776,21 @@ namespace ZeroSizeTypes { return &arr[3] - &arr[0]; // expected-note {{subtraction of pointers to type 'int [0]' of zero size}} } } + +namespace BadDefaultInit { + template struct X { static const int n = N; }; + + struct A { // expected-note {{subexpression}} + int k = X::n; // expected-error {{defaulted default constructor of 'A' cannot be used}} expected-error {{not a constant expression}} expected-note {{in call to 'A()'}} + }; + + // FIXME: The "constexpr constructor must initialize all members" diagnostic + // here is bogus (we discard the k(k) initializer because the parameter 'k' + // has been marked invalid). + struct B { // expected-note 2{{candidate}} + constexpr B( // expected-error {{must initialize all members}} expected-note {{candidate}} + int k = X::n) : // expected-error {{no matching constructor}} + k(k) {} + int k; // expected-note {{not initialized}} + }; +}