forked from OSchip/llvm-project
Make sure to propagate qualifiers through the member operator.
llvm-svn: 46830
This commit is contained in:
parent
2d489b5081
commit
1242fff6ec
|
@ -686,6 +686,7 @@ void MemberExpr::EmitImpl(Serializer& S) const {
|
||||||
S.EmitPtr(MemberDecl);
|
S.EmitPtr(MemberDecl);
|
||||||
S.EmitBool(IsArrow);
|
S.EmitBool(IsArrow);
|
||||||
S.EmitOwnedPtr(Base);
|
S.EmitOwnedPtr(Base);
|
||||||
|
S.Emit(getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
MemberExpr* MemberExpr::CreateImpl(Deserializer& D) {
|
MemberExpr* MemberExpr::CreateImpl(Deserializer& D) {
|
||||||
|
@ -693,8 +694,9 @@ MemberExpr* MemberExpr::CreateImpl(Deserializer& D) {
|
||||||
FieldDecl* MemberDecl = cast<FieldDecl>(D.ReadPtr<Decl>());
|
FieldDecl* MemberDecl = cast<FieldDecl>(D.ReadPtr<Decl>());
|
||||||
bool IsArrow = D.ReadBool();
|
bool IsArrow = D.ReadBool();
|
||||||
Expr* base = D.ReadOwnedPtr<Expr>();
|
Expr* base = D.ReadOwnedPtr<Expr>();
|
||||||
|
QualType T = QualType::ReadVal(D);
|
||||||
|
|
||||||
return new MemberExpr(base,IsArrow,MemberDecl,L);
|
return new MemberExpr(base,IsArrow,MemberDecl,L,T);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NullStmt::EmitImpl(Serializer& S) const {
|
void NullStmt::EmitImpl(Serializer& S) const {
|
||||||
|
|
|
@ -746,7 +746,7 @@ Stmt *RewriteTest::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) {
|
||||||
ObjCIvarDecl *D = IV->getDecl();
|
ObjCIvarDecl *D = IV->getDecl();
|
||||||
if (IV->isFreeIvar()) {
|
if (IV->isFreeIvar()) {
|
||||||
Expr *Replacement = new MemberExpr(IV->getBase(), true, D,
|
Expr *Replacement = new MemberExpr(IV->getBase(), true, D,
|
||||||
IV->getLocation());
|
IV->getLocation(), D->getType());
|
||||||
ReplaceStmt(IV, Replacement);
|
ReplaceStmt(IV, Replacement);
|
||||||
delete IV;
|
delete IV;
|
||||||
return Replacement;
|
return Replacement;
|
||||||
|
|
|
@ -532,7 +532,15 @@ ActOnMemberReferenceExpr(ExprTy *Base, SourceLocation OpLoc,
|
||||||
if (!MemberDecl)
|
if (!MemberDecl)
|
||||||
return Diag(OpLoc, diag::err_typecheck_no_member, Member.getName(),
|
return Diag(OpLoc, diag::err_typecheck_no_member, Member.getName(),
|
||||||
SourceRange(MemberLoc));
|
SourceRange(MemberLoc));
|
||||||
return new MemberExpr(BaseExpr, OpKind==tok::arrow, MemberDecl, MemberLoc);
|
|
||||||
|
// Figure out the type of the member; see C99 6.5.2.3p3
|
||||||
|
QualType MemberType = MemberDecl->getType();
|
||||||
|
unsigned combinedQualifiers =
|
||||||
|
MemberType.getQualifiers() | BaseType.getQualifiers();
|
||||||
|
MemberType = MemberType.getQualifiedType(combinedQualifiers);
|
||||||
|
|
||||||
|
return new MemberExpr(BaseExpr, OpKind==tok::arrow, MemberDecl,
|
||||||
|
MemberLoc, MemberType);
|
||||||
} else if (BaseType->isOCUVectorType() && OpKind == tok::period) {
|
} else if (BaseType->isOCUVectorType() && OpKind == tok::period) {
|
||||||
// Component access limited to variables (reject vec4.rg.g).
|
// Component access limited to variables (reject vec4.rg.g).
|
||||||
if (!isa<DeclRefExpr>(BaseExpr))
|
if (!isa<DeclRefExpr>(BaseExpr))
|
||||||
|
@ -2050,8 +2058,9 @@ Sema::ExprResult Sema::ActOnBuiltinOffsetOf(SourceLocation BuiltinLoc,
|
||||||
|
|
||||||
// FIXME: C++: Verify that MemberDecl isn't a static field.
|
// FIXME: C++: Verify that MemberDecl isn't a static field.
|
||||||
// FIXME: Verify that MemberDecl isn't a bitfield.
|
// FIXME: Verify that MemberDecl isn't a bitfield.
|
||||||
|
// MemberDecl->getType() doesn't get the right qualifiers, but it doesn't
|
||||||
Res = new MemberExpr(Res, false, MemberDecl, OC.LocEnd);
|
// matter here.
|
||||||
|
Res = new MemberExpr(Res, false, MemberDecl, OC.LocEnd, MemberDecl->getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
return new UnaryOperator(Res, UnaryOperator::OffsetOf, Context.getSizeType(),
|
return new UnaryOperator(Res, UnaryOperator::OffsetOf, Context.getSizeType(),
|
||||||
|
|
|
@ -650,10 +650,11 @@ class MemberExpr : public Expr {
|
||||||
SourceLocation MemberLoc;
|
SourceLocation MemberLoc;
|
||||||
bool IsArrow; // True if this is "X->F", false if this is "X.F".
|
bool IsArrow; // True if this is "X->F", false if this is "X.F".
|
||||||
public:
|
public:
|
||||||
MemberExpr(Expr *base, bool isarrow, FieldDecl *memberdecl, SourceLocation l)
|
MemberExpr(Expr *base, bool isarrow, FieldDecl *memberdecl, SourceLocation l,
|
||||||
: Expr(MemberExprClass, memberdecl->getType()),
|
QualType ty)
|
||||||
|
: Expr(MemberExprClass, ty),
|
||||||
Base(base), MemberDecl(memberdecl), MemberLoc(l), IsArrow(isarrow) {}
|
Base(base), MemberDecl(memberdecl), MemberLoc(l), IsArrow(isarrow) {}
|
||||||
|
|
||||||
Expr *getBase() const { return Base; }
|
Expr *getBase() const { return Base; }
|
||||||
FieldDecl *getMemberDecl() const { return MemberDecl; }
|
FieldDecl *getMemberDecl() const { return MemberDecl; }
|
||||||
bool isArrow() const { return IsArrow; }
|
bool isArrow() const { return IsArrow; }
|
||||||
|
|
|
@ -2,4 +2,6 @@
|
||||||
|
|
||||||
void *test1(void) { return 0; }
|
void *test1(void) { return 0; }
|
||||||
|
|
||||||
|
void test2 (const struct {int a;} *x) {
|
||||||
|
x->a = 10; // expected-error {{read-only variable is not assignable}}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue