From 1fca547913774c6c547a15414d1a7051c1f446b5 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Fri, 13 Sep 2013 20:51:45 +0000 Subject: [PATCH] Part three of PR15721: if we have an invalid CXXDefaultInitExpr, don't crash if we try to constant-evaluate it. Patch by Karthik Bhat, test by me. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@190722 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AST/ExprConstant.cpp | 8 ++++++-- test/SemaCXX/constant-expression-cxx11.cpp | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 218ce8101b..0a2cc7b3d6 100644 --- a/lib/AST/ExprConstant.cpp +++ b/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/test/SemaCXX/constant-expression-cxx11.cpp b/test/SemaCXX/constant-expression-cxx11.cpp index 363ca8c7d9..c776687858 100644 --- a/test/SemaCXX/constant-expression-cxx11.cpp +++ b/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}} + }; +} -- 2.40.0