diff options
| -rw-r--r-- | clang/Sema/SemaExpr.cpp | 26 | ||||
| -rw-r--r-- | clang/test/Sema/expr-address-of.c | 5 |
2 files changed, 21 insertions, 10 deletions
diff --git a/clang/Sema/SemaExpr.cpp b/clang/Sema/SemaExpr.cpp index 6228b3cf76b..67c967f1e61 100644 --- a/clang/Sema/SemaExpr.cpp +++ b/clang/Sema/SemaExpr.cpp @@ -1616,11 +1616,11 @@ QualType Sema::CheckIncrementDecrementOperand(Expr *op, SourceLocation OpLoc) { return resType; } -/// getPrimaryDeclaration - Helper function for CheckAddressOfOperand(). +/// getPrimaryDecl - Helper function for CheckAddressOfOperand(). /// This routine allows us to typecheck complex/recursive expressions /// where the declaration is needed for type checking. Here are some /// examples: &s.xx, &s.zz[1].yy, &(1+2), &(XX), &"123"[2]. -static Decl *getPrimaryDeclaration(Expr *e) { +static ValueDecl *getPrimaryDecl(Expr *e) { switch (e->getStmtClass()) { case Stmt::DeclRefExprClass: return cast<DeclRefExpr>(e)->getDecl(); @@ -1629,17 +1629,23 @@ static Decl *getPrimaryDeclaration(Expr *e) { // &X->f is always ok, even if X is declared register. if (cast<MemberExpr>(e)->isArrow()) return 0; - return getPrimaryDeclaration(cast<MemberExpr>(e)->getBase()); - case Stmt::ArraySubscriptExprClass: - // &X[4] and &4[X] is invalid if X is invalid. - return getPrimaryDeclaration(cast<ArraySubscriptExpr>(e)->getBase()); + return getPrimaryDecl(cast<MemberExpr>(e)->getBase()); + case Stmt::ArraySubscriptExprClass: { + // &X[4] and &4[X] is invalid if X is invalid and X is not a pointer. + + ValueDecl *VD = getPrimaryDecl(cast<ArraySubscriptExpr>(e)->getBase()); + if (VD->getType()->isPointerType()) + return 0; + else + return VD; + } case Stmt::UnaryOperatorClass: - return getPrimaryDeclaration(cast<UnaryOperator>(e)->getSubExpr()); + return getPrimaryDecl(cast<UnaryOperator>(e)->getSubExpr()); case Stmt::ParenExprClass: - return getPrimaryDeclaration(cast<ParenExpr>(e)->getSubExpr()); + return getPrimaryDecl(cast<ParenExpr>(e)->getSubExpr()); case Stmt::ImplicitCastExprClass: // &X[4] when X is an array, has an implicit cast from array to pointer. - return getPrimaryDeclaration(cast<ImplicitCastExpr>(e)->getSubExpr()); + return getPrimaryDecl(cast<ImplicitCastExpr>(e)->getSubExpr()); default: return 0; } @@ -1662,7 +1668,7 @@ QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) { // Technically, there should be a check for array subscript // expressions here, but the result of one is always an lvalue anyway. } - Decl *dcl = getPrimaryDeclaration(op); + ValueDecl *dcl = getPrimaryDecl(op); Expr::isLvalueResult lval = op->isLvalue(); if (lval != Expr::LV_Valid) { // C99 6.5.3.2p1 diff --git a/clang/test/Sema/expr-address-of.c b/clang/test/Sema/expr-address-of.c index f085b6012a0..5f46b630467 100644 --- a/clang/test/Sema/expr-address-of.c +++ b/clang/test/Sema/expr-address-of.c @@ -10,6 +10,11 @@ void test() { void foo() { register int x[10]; &x[10]; // expected-error {{address of register variable requested}} + + register int *y; + + int *x2 = &y; // expected-error {{address of register variable requested}} + int *x3 = &y[10]; } |

