Fix PR6327:  restore invariants when there's a parse error in an initializer.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99980 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 1909607..72e7f17 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -828,6 +828,7 @@
   virtual void AddInitializerToDecl(DeclPtrTy dcl, ExprArg init);
   void AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit);
   void ActOnUninitializedDecl(DeclPtrTy dcl, bool TypeContainsUndeducedAuto);
+  virtual void ActOnInitializerError(DeclPtrTy Dcl);
   virtual void SetDeclDeleted(DeclPtrTy dcl, SourceLocation DelLoc);
   virtual DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
                                                  DeclPtrTy *Group,
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index b60804a..51514e7 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -3797,6 +3797,41 @@
   return;
 }
 
+/// ActOnInitializerError - Given that there was an error parsing an
+/// initializer for the given declaration, try to return to some form
+/// of sanity.
+void Sema::ActOnInitializerError(DeclPtrTy dcl) {
+  // Our main concern here is re-establishing invariants like "a
+  // variable's type is either dependent or complete".
+  Decl *D = dcl.getAs<Decl>();
+  if (!D || D->isInvalidDecl()) return;
+
+  VarDecl *VD = dyn_cast<VarDecl>(D);
+  if (!VD) return;
+
+  QualType Ty = VD->getType();
+  if (Ty->isDependentType()) return;
+
+  // Require a complete type.
+  if (RequireCompleteType(VD->getLocation(), 
+                          Context.getBaseElementType(Ty),
+                          diag::err_typecheck_decl_incomplete_type)) {
+    VD->setInvalidDecl();
+    return;
+  }
+
+  // Require an abstract type.
+  if (RequireNonAbstractType(VD->getLocation(), Ty,
+                             diag::err_abstract_type_in_decl,
+                             AbstractVariableType)) {
+    VD->setInvalidDecl();
+    return;
+  }
+
+  // Don't bother complaining about constructors or destructors,
+  // though.
+}
+
 void Sema::ActOnUninitializedDecl(DeclPtrTy dcl,
                                   bool TypeContainsUndeducedAuto) {
   Decl *RealDecl = dcl.getAs<Decl>();