Fif for an issue when Clang permits assignment to vector/extvector elements in a const method.

llvm-svn: 324721
This commit is contained in:
Andrew V. Tischenko 2018-02-09 09:30:42 +00:00
parent 7850601fa3
commit 425f7b4894
5 changed files with 46 additions and 9 deletions

View File

@ -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<ArraySubscriptExpr>(E)) {
E = ASE->getBase()->IgnoreParenImpCasts();
continue;
} else if (const ExtVectorElementExpr *EVE =
dyn_cast<ExtVectorElementExpr>(E)) {
E = EVE->getBase()->IgnoreParenImpCasts();
continue;
}
break;
}

View File

@ -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);

View File

@ -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 {

View File

@ -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) {

View File

@ -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}}
};