[Sema] Disallow assigning record lvalues with nested const-qualified fields.

Summary:
According to C99 6.3.2.1p1, structs and unions with nested
const-qualified fields (that is, const-qualified fields
declared at some recursive level of the aggregate) are not
modifiable lvalues. However, Clang permits assignments of
these lvalues.

With this patch, we both prohibit the assignment of records
with const-qualified fields and emit a best-effort diagnostic.
This fixes https://bugs.llvm.org/show_bug.cgi?id=31796 .

Committing on behalf of bevinh (Bevin Hansson).

Reviewers: rtrieu, rsmith, bjope

Reviewed By: bjope

Subscribers: Ka-Ka, rogfer01, bjope, fhahn, cfe-commits

Differential Revision: https://reviews.llvm.org/D37254

llvm-svn: 313628
diff --git a/clang/lib/AST/ExprClassification.cpp b/clang/lib/AST/ExprClassification.cpp
index d149bdd..3bb2b4e 100644
--- a/clang/lib/AST/ExprClassification.cpp
+++ b/clang/lib/AST/ExprClassification.cpp
@@ -641,7 +641,7 @@
   // Records with any const fields (recursively) are not modifiable.
   if (const RecordType *R = CT->getAs<RecordType>())
     if (R->hasConstFields())
-      return Cl::CM_ConstQualified;
+      return Cl::CM_ConstQualifiedField;
 
   return Cl::CM_Modifiable;
 }
@@ -695,6 +695,7 @@
     llvm_unreachable("CM_LValueCast and CL_LValue don't match");
   case Cl::CM_NoSetterProperty: return MLV_NoSetterProperty;
   case Cl::CM_ConstQualified: return MLV_ConstQualified;
+  case Cl::CM_ConstQualifiedField: return MLV_ConstQualifiedField;
   case Cl::CM_ConstAddrSpace: return MLV_ConstAddrSpace;
   case Cl::CM_ArrayType: return MLV_ArrayType;
   case Cl::CM_IncompleteType: return MLV_IncompleteType;