зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
825502a9ee
Коммит
f82228f6ed
|
@ -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}}
|
||||
}
|
||||
|
||||
|
Загрузка…
Ссылка в новой задаче