From: David Majnemer Date: Sat, 13 Dec 2014 11:34:16 +0000 (+0000) Subject: Parse: MS property members cannot have an in-class initializer X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4757126ccbd9aa88faaf680fb3cd04c3eb122779;p=clang Parse: MS property members cannot have an in-class initializer We would crash trying to treat a property member as a field. These shoudl be forbidden anyway, reject programs which contain them. This fixes PR21840. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@224193 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index cdafc080b1..f39c2b888e 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -602,6 +602,8 @@ def err_ms_property_expected_accessor_name : Error< "expected name of accessor method">; def err_ms_property_expected_comma_or_rparen : Error< "expected ',' or ')' at end of property accessor list">; +def err_ms_property_initializer : Error< + "property declaration cannot have an in-class initializer">; /// C++ Templates def err_expected_template : Error<"expected template">; diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index 85f6303970..01f91eb26d 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -2608,7 +2608,10 @@ ExprResult Parser::ParseCXXMemberInitializer(Decl *D, bool IsFunction, Diag(ConsumeToken(), diag::err_default_special_members); return ExprError(); } - + } + if (const auto *PD = dyn_cast_or_null(D)) { + Diag(Tok, diag::err_ms_property_initializer) << PD; + return ExprError(); } return ParseInitializer(); } diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index a6ff02cc07..8240725065 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -2656,13 +2656,14 @@ void Sema::ActOnFinishCXXInClassMemberInitializer(Decl *D, // Pop the notional constructor scope we created earlier. PopFunctionScopeInfo(nullptr, D); - FieldDecl *FD = cast(D); - assert(FD->getInClassInitStyle() != ICIS_NoInit && + FieldDecl *FD = dyn_cast(D); + assert((isa(D) || FD->getInClassInitStyle() != ICIS_NoInit) && "must set init style when field is created"); if (!InitExpr) { - FD->setInvalidDecl(); - FD->removeInClassInitializer(); + D->setInvalidDecl(); + if (FD) + FD->removeInClassInitializer(); return; } diff --git a/test/Parser/MicrosoftExtensions.cpp b/test/Parser/MicrosoftExtensions.cpp index 6463f090c0..7637777d29 100644 --- a/test/Parser/MicrosoftExtensions.cpp +++ b/test/Parser/MicrosoftExtensions.cpp @@ -320,6 +320,7 @@ struct StructWithProperty { __declspec(property(get=GetV,)) int V10; // expected-error {{expected 'get' or 'put' in property declaration}} __declspec(property(get=GetV,put=SetV)) int V11; // no-warning __declspec(property(get=GetV,put=SetV,get=GetV)) int V12; // expected-error {{property declaration specifies 'get' accessor twice}} + __declspec(property(get=GetV)) int V13 = 3; // expected-error {{property declaration cannot have an in-class initializer}} int GetV() { return 123; } void SetV(int v) {}