Tighten up address-of checking, implementing test/Sema/expr-address-of.c.

This fixes a bug reported by Seo Sanghyeon.

This was meant to be committed yesterday, but the commit failed.  doh.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@44190 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2007-11-16 17:46:48 +00:00
Родитель 825502a9ee
Коммит f82228f6ed
2 изменённых файлов: 25 добавлений и 5 удалений

Просмотреть файл

@ -1520,15 +1520,21 @@ static Decl *getPrimaryDeclaration(Expr *e) {
case Stmt::DeclRefExprClass:
return cast<DeclRefExpr>(e)->getDecl();
case Stmt::MemberExprClass:
// Fields cannot be declared with a 'register' storage class.
// &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());
case Stmt::CallExprClass:
return getPrimaryDeclaration(cast<CallExpr>(e)->getCallee());
case Stmt::UnaryOperatorClass:
return getPrimaryDeclaration(cast<UnaryOperator>(e)->getSubExpr());
case Stmt::ParenExprClass:
return getPrimaryDeclaration(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());
default:
return 0;
}
@ -1544,9 +1550,8 @@ QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) {
Expr::isLvalueResult lval = op->isLvalue();
if (lval != Expr::LV_Valid) { // C99 6.5.3.2p1
if (dcl && isa<FunctionDecl>(dcl)) // allow function designators
;
else { // FIXME: emit more specific diag...
if (!dcl || !isa<FunctionDecl>(dcl)) {// allow function designators
// FIXME: emit more specific diag...
Diag(OpLoc, diag::err_typecheck_invalid_lvalue_addrof,
op->getSourceRange());
return QualType();

Просмотреть файл

@ -0,0 +1,15 @@
// RUN: clang %s -verify -fsyntax-only
struct entry { int value; };
void add_one(int *p) { (*p)++; }
void test() {
register struct entry *p;
add_one(&p->value);
}
void foo() {
register int x[10];
&x[10]; // expected-error {{address of register variable requested}}
}