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.

llvm-svn: 224193

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

index cdafc08..f39c2b8 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 85f6303..01f91eb 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 a6ff02c..8240725 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 6463f09..7637777 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) {}