From 369dee454fe7e77720d0d0012a23b75e17bee101 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Fri, 1 Feb 2008 07:15:58 +0000 Subject: [PATCH] It is allowed to get the address of an array subscript, even if the array has the register qualifier, if the array is really a pointer. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46634 91177308-0d34-0410-b5e6-96231b3b80d8 --- Sema/SemaExpr.cpp | 26 ++++++++++++++++---------- test/Sema/expr-address-of.c | 5 +++++ 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/Sema/SemaExpr.cpp b/Sema/SemaExpr.cpp index 6228b3cf76..67c967f1e6 100644 --- a/Sema/SemaExpr.cpp +++ b/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(e)->getDecl(); @@ -1629,17 +1629,23 @@ static Decl *getPrimaryDeclaration(Expr *e) { // &X->f is always ok, even if X is declared register. if (cast(e)->isArrow()) return 0; - return getPrimaryDeclaration(cast(e)->getBase()); - case Stmt::ArraySubscriptExprClass: - // &X[4] and &4[X] is invalid if X is invalid. - return getPrimaryDeclaration(cast(e)->getBase()); + return getPrimaryDecl(cast(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(e)->getBase()); + if (VD->getType()->isPointerType()) + return 0; + else + return VD; + } case Stmt::UnaryOperatorClass: - return getPrimaryDeclaration(cast(e)->getSubExpr()); + return getPrimaryDecl(cast(e)->getSubExpr()); case Stmt::ParenExprClass: - return getPrimaryDeclaration(cast(e)->getSubExpr()); + return getPrimaryDecl(cast(e)->getSubExpr()); case Stmt::ImplicitCastExprClass: // &X[4] when X is an array, has an implicit cast from array to pointer. - return getPrimaryDeclaration(cast(e)->getSubExpr()); + return getPrimaryDecl(cast(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/test/Sema/expr-address-of.c b/test/Sema/expr-address-of.c index f085b6012a..5f46b63046 100644 --- a/test/Sema/expr-address-of.c +++ b/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]; } -- 2.40.0