diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 547233690024..53a4a4c7834a 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -4395,8 +4395,13 @@ Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, if (VK != VK_RValue) OK = OK_VectorComponent; - // FIXME: need to deal with const... ResultType = VTy->getElementType(); + QualType BaseType = BaseExpr->getType(); + Qualifiers BaseQuals = BaseType.getQualifiers(); + Qualifiers MemberQuals = ResultType.getQualifiers(); + Qualifiers Combined = BaseQuals + MemberQuals; + if (Combined != MemberQuals) + ResultType = Context.getQualifiedType(ResultType, Combined); } else if (LHSTy->isArrayType()) { // If we see an array that wasn't promoted by // DefaultFunctionArrayLvalueConversion, it must be an array that @@ -10434,8 +10439,16 @@ static void DiagnoseConstAssignment(Sema &S, const Expr *E, // Static fields do not inherit constness from parents. break; } - break; - } // End MemberExpr + break; // End MemberExpr + } else if (const ArraySubscriptExpr *ASE = + dyn_cast(E)) { + E = ASE->getBase()->IgnoreParenImpCasts(); + continue; + } else if (const ExtVectorElementExpr *EVE = + dyn_cast(E)) { + E = EVE->getBase()->IgnoreParenImpCasts(); + continue; + } break; } diff --git a/clang/lib/Sema/SemaExprMember.cpp b/clang/lib/Sema/SemaExprMember.cpp index f57f79e62efe..5bb9653db084 100644 --- a/clang/lib/Sema/SemaExprMember.cpp +++ b/clang/lib/Sema/SemaExprMember.cpp @@ -1623,10 +1623,14 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, else VK = BaseExpr.get()->getValueKind(); } + QualType ret = CheckExtVectorComponent(S, BaseType, VK, OpLoc, Member, MemberLoc); if (ret.isNull()) return ExprError(); + Qualifiers BaseQ = + S.Context.getCanonicalType(BaseExpr.get()->getType()).getQualifiers(); + ret = S.Context.getQualifiedType(ret, BaseQ); return new (S.Context) ExtVectorElementExpr(ret, VK, BaseExpr.get(), *Member, MemberLoc); diff --git a/clang/test/Sema/assign.c b/clang/test/Sema/assign.c index 5bdfa9a3a5df..28d7b9f3bbdf 100644 --- a/clang/test/Sema/assign.c +++ b/clang/test/Sema/assign.c @@ -11,10 +11,10 @@ void test2 (const struct {int a;} *x) { typedef int arr[10]; void test3() { - const arr b; - const int b2[10]; - b[4] = 1; // expected-error {{read-only variable is not assignable}} - b2[4] = 1; // expected-error {{read-only variable is not assignable}} + const arr b; // expected-note {{variable 'b' declared const here}} + const int b2[10]; // expected-note {{variable 'b2' declared const here}} + b[4] = 1; // expected-error {{cannot assign to variable 'b' with const-qualified type 'const arr' (aka 'int const[10]')}} + b2[4] = 1; // expected-error {{cannot assign to variable 'b2' with const-qualified type 'const int [10]'}} } typedef struct I { diff --git a/clang/test/Sema/typedef-retain.c b/clang/test/Sema/typedef-retain.c index d216466360b7..3d784ce60a75 100644 --- a/clang/test/Sema/typedef-retain.c +++ b/clang/test/Sema/typedef-retain.c @@ -16,8 +16,8 @@ void test2(float4 a, int4p result, int i) { typedef int a[5]; void test3() { typedef const a b; - b r; - r[0]=10; // expected-error {{read-only variable is not assignable}} + b r; // expected-note {{variable 'r' declared const here}} + r[0] = 10; // expected-error {{cannot assign to variable 'r' with const-qualified type 'b' (aka 'int const[5]')}} } int test4(const a y) { diff --git a/clang/test/SemaCXX/err_typecheck_assign_const.cpp b/clang/test/SemaCXX/err_typecheck_assign_const.cpp index 7e2812565144..3725e58b422d 100644 --- a/clang/test/SemaCXX/err_typecheck_assign_const.cpp +++ b/clang/test/SemaCXX/err_typecheck_assign_const.cpp @@ -129,3 +129,23 @@ void test() { 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 {{cannot assign to non-static data member within const member function 'AssignMe'}} \ + expected-note {{member function 'OhNo::AssignMe' is declared const here}} +}; + +typedef float float4_2 __attribute__((__vector_size__(16))); +struct OhNo2 { + float4_2 v; + void AssignMe() const { v[0] = 1; } // expected-error {{cannot assign to non-static data member within const member function 'AssignMe'}} \ + expected-note {{member function 'OhNo2::AssignMe' is declared const here}} +}; + +struct OhNo3 { + float v[4]; + void AssignMe() const { v[0] = 1; } // expected-error {{cannot assign to non-static data member within const member function 'AssignMe'}} \ + expected-note {{member function 'OhNo3::AssignMe' is declared const here}} +};