]> granicus.if.org Git - clang/commitdiff
Parse: MS property members cannot have an in-class initializer
authorDavid Majnemer <david.majnemer@gmail.com>
Sat, 13 Dec 2014 11:34:16 +0000 (11:34 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Sat, 13 Dec 2014 11:34:16 +0000 (11:34 +0000)
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

include/clang/Basic/DiagnosticParseKinds.td
lib/Parse/ParseDeclCXX.cpp
lib/Sema/SemaDeclCXX.cpp
test/Parser/MicrosoftExtensions.cpp

index cdafc080b1f69e441af32a7f705b59f0baa08c24..f39c2b888ede47fbac0ac4a0d3261dbea391be42 100644 (file)
@@ -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">;
index 85f6303970af7daee1607d761c08d41533839ac1..01f91eb26d80faea45e8570142b90ad0090c4862 100644 (file)
@@ -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<MSPropertyDecl>(D)) {
+    Diag(Tok, diag::err_ms_property_initializer) << PD;
+    return ExprError();
   }
   return ParseInitializer();
 }
index a6ff02cc07d55dc54881cd27096084e783113bf8..82407250657d8876148641c0942aaf9fb1286f58 100644 (file)
@@ -2656,13 +2656,14 @@ void Sema::ActOnFinishCXXInClassMemberInitializer(Decl *D,
   // Pop the notional constructor scope we created earlier.
   PopFunctionScopeInfo(nullptr, D);
 
-  FieldDecl *FD = cast<FieldDecl>(D);
-  assert(FD->getInClassInitStyle() != ICIS_NoInit &&
+  FieldDecl *FD = dyn_cast<FieldDecl>(D);
+  assert((isa<MSPropertyDecl>(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;
   }
 
index 6463f090c0773a97d0272be966d776ed4b012b61..7637777d296a5f04d88ce8cee82efb3e8a604241 100644 (file)
@@ -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) {}