Index: lib/AST/ExprClassification.cpp =================================================================== --- lib/AST/ExprClassification.cpp +++ lib/AST/ExprClassification.cpp @@ -643,6 +643,14 @@ if (R->hasConstFields()) return Cl::CM_ConstQualifiedField; + if (const ExtVectorElementExpr *VE = dyn_cast(E)) + if (Ctx.getCanonicalType(VE->getBase()->getType()).isConstQualified()) + return Cl::CM_ConstQualified; + + if (const ArraySubscriptExpr *ASE = dyn_cast(E)) + if (Ctx.getCanonicalType(ASE->getBase()->getType()).isConstQualified()) + return Cl::CM_ConstQualified; + return Cl::CM_Modifiable; } Index: lib/Sema/SemaExpr.cpp =================================================================== --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -10321,7 +10321,7 @@ /// 'const' due to being captured within a block? enum NonConstCaptureKind { NCCK_None, NCCK_Block, NCCK_Lambda }; static NonConstCaptureKind isReferenceToNonConstCapture(Sema &S, Expr *E) { - assert(E->isLValue() && E->getType().isConstQualified()); + assert(E->isLValue()); E = E->IgnoreParens(); // Must be a reference to a declaration from an enclosing scope. Index: test/SemaCXX/err_typecheck_assign_const.cpp =================================================================== --- test/SemaCXX/err_typecheck_assign_const.cpp +++ test/SemaCXX/err_typecheck_assign_const.cpp @@ -129,3 +129,21 @@ Func &bar(); bar()() = 0; // expected-error {{read-only variable is not assignable}} } + +typedef float float4 __attribute__((ext_vector_type(4))); +struct OhNo { + float4 v; + void AssignMe() const { v.x = 1; } // expected-error {{read-only variable is not assignable}} +}; + +typedef float float4_2 __attribute__((__vector_size__(16))); +struct OhNo2 { + float4_2 v; + void AssignMe() const { v[0] = 1; } // expected-error {{read-only variable is not assignable}} +}; + +struct OhNo3 { + float v[4]; + void AssignMe() const { v[0] = 1; } // expected-error {{read-only variable is not assignable}} +}; +