]> granicus.if.org Git - clang/commitdiff
Tighten up address-of checking, implementing test/Sema/expr-address-of.c.
authorChris Lattner <sabre@nondot.org>
Fri, 16 Nov 2007 17:46:48 +0000 (17:46 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 16 Nov 2007 17:46:48 +0000 (17:46 +0000)
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

Sema/SemaExpr.cpp
test/Sema/expr-address-of.c [new file with mode: 0644]

index 416661ee6c4ed716ef5a71580113882a13853d88..6c3b06e0155f61669fb4c59bdd07dcfdd3f44bca 100644 (file)
@@ -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();
diff --git a/test/Sema/expr-address-of.c b/test/Sema/expr-address-of.c
new file mode 100644 (file)
index 0000000..f085b60
--- /dev/null
@@ -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}}
+}
+
+