diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 12 | ||||
-rw-r--r-- | clang/test/Sema/exprs.c | 7 |
2 files changed, 19 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 628f233d681..6b82eadaea2 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -1571,6 +1571,12 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc, } else MemberDecl = Result; + // If the decl being referenced had an error, return an error for this + // sub-expr without emitting another error, in order to avoid cascading + // error cases. + if (MemberDecl->isInvalidDecl()) + return ExprError(); + if (FieldDecl *FD = dyn_cast<FieldDecl>(MemberDecl)) { // We may have found a field within an anonymous union or struct // (C++ [class.union]). @@ -1623,6 +1629,12 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc, // (*Obj).ivar. if (const ObjCInterfaceType *IFTy = BaseType->getAsObjCInterfaceType()) { if (ObjCIvarDecl *IV = IFTy->getDecl()->lookupInstanceVariable(&Member)) { + // If the decl being referenced had an error, return an error for this + // sub-expr without emitting another error, in order to avoid cascading + // error cases. + if (IV->isInvalidDecl()) + return ExprError(); + ObjCIvarRefExpr *MRef= new (Context) ObjCIvarRefExpr(IV, IV->getType(), MemberLoc, BaseExpr, OpKind == tok::arrow); diff --git a/clang/test/Sema/exprs.c b/clang/test/Sema/exprs.c index db2daf1f7ca..4ddb976eb2e 100644 --- a/clang/test/Sema/exprs.c +++ b/clang/test/Sema/exprs.c @@ -57,3 +57,10 @@ int test9(struct f *P) { return R; } +// PR3562 +void test10(int n,...) { + struct S { + double a[n]; // expected-error {{fields must have a constant size}} + } s; + double x = s.a[0]; // should not get another error here. +} |