[pkg-d-commits] [ldc] 151/211: Fix check if nested function can access outer function frame

Matthias Klumpp mak at moszumanska.debian.org
Sun Apr 23 22:36:18 UTC 2017


This is an automated email from the git hooks/post-receive script.

mak pushed a commit to annotated tag v1.1.0
in repository ldc.

commit 0de021fe3297e9920405785998d12c2ea57c63c2
Author: Martin <noone at nowhere.com>
Date:   Fri Nov 18 00:00:37 2016 +0100

    Fix check if nested function can access outer function frame
    
    The previous check wouldn't check intermediate aggregates for static-ness,
    that was one problem. The other was the assertion that the outer function
    can be reached as long as there are no static functions inbetween, which
    isn't always the case, as issue #1864 clearly shows, which is resolved by
    this.
---
 gen/functions.cpp      |  2 +-
 gen/llvmhelpers.cpp    | 41 ++++++++++++++++++-----------------------
 gen/llvmhelpers.h      |  2 +-
 gen/nested.cpp         | 21 ++++++++++-----------
 tests/d2/dmd-testsuite |  2 +-
 5 files changed, 31 insertions(+), 37 deletions(-)

diff --git a/gen/functions.cpp b/gen/functions.cpp
index e7f28f7..e69c1cf 100644
--- a/gen/functions.cpp
+++ b/gen/functions.cpp
@@ -852,7 +852,7 @@ void DtoDefineFunction(FuncDeclaration *fd, bool linkageAvailableExternally) {
   // data from the template function itself, but it would still mess up our
   // nested context creation code.
   FuncDeclaration *parent = fd;
-  while ((parent = getParentFunc(parent, true))) {
+  while ((parent = getParentFunc(parent))) {
     if (parent->semanticRun != PASSsemantic3done || parent->semantic3Errors) {
       IF_LOG Logger::println(
           "Ignoring nested function with unanalyzed parent.");
diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp
index 132a5df..0de8684 100644
--- a/gen/llvmhelpers.cpp
+++ b/gen/llvmhelpers.cpp
@@ -1733,29 +1733,26 @@ llvm::GlobalVariable *getOrCreateGlobal(const Loc &loc, llvm::Module &module,
                                   nullptr, tlsModel);
 }
 
-FuncDeclaration *getParentFunc(Dsymbol *sym, bool stopOnStatic) {
+FuncDeclaration *getParentFunc(Dsymbol *sym) {
   if (!sym) {
     return nullptr;
   }
 
-  // check if symbol is itself a static function/aggregate
-  if (stopOnStatic) {
-    // Static functions and function (not delegate) literals don't allow
-    // access to a parent context, even if they are nested.
-    if (FuncDeclaration *fd = sym->isFuncDeclaration()) {
-      bool certainlyNewRoot =
-          fd->isStatic() ||
-          (fd->isFuncLiteralDeclaration() &&
-           static_cast<FuncLiteralDeclaration *>(fd)->tok == TOKfunction);
-      if (certainlyNewRoot) {
-        return nullptr;
-      }
+  // Static functions and function (not delegate) literals don't allow
+  // access to a parent context, even if they are nested.
+  if (FuncDeclaration *fd = sym->isFuncDeclaration()) {
+    bool certainlyNewRoot =
+        fd->isStatic() ||
+        (fd->isFuncLiteralDeclaration() &&
+         static_cast<FuncLiteralDeclaration *>(fd)->tok == TOKfunction);
+    if (certainlyNewRoot) {
+      return nullptr;
     }
-    // Fun fact: AggregateDeclarations are not Declarations.
-    else if (AggregateDeclaration *ad = sym->isAggregateDeclaration()) {
-      if (!ad->isNested()) {
-        return nullptr;
-      }
+  }
+  // Fun fact: AggregateDeclarations are not Declarations.
+  else if (AggregateDeclaration *ad = sym->isAggregateDeclaration()) {
+    if (!ad->isNested()) {
+      return nullptr;
     }
   }
 
@@ -1764,11 +1761,9 @@ FuncDeclaration *getParentFunc(Dsymbol *sym, bool stopOnStatic) {
       return fd;
     }
 
-    if (stopOnStatic) {
-      if (AggregateDeclaration *ad = parent->isAggregateDeclaration()) {
-        if (!ad->isNested()) {
-          return nullptr;
-        }
+    if (AggregateDeclaration *ad = parent->isAggregateDeclaration()) {
+      if (!ad->isNested()) {
+        return nullptr;
       }
     }
   }
diff --git a/gen/llvmhelpers.h b/gen/llvmhelpers.h
index db9435d..dd7bb82 100644
--- a/gen/llvmhelpers.h
+++ b/gen/llvmhelpers.h
@@ -260,7 +260,7 @@ llvm::GlobalVariable *getOrCreateGlobal(const Loc &loc, llvm::Module &module,
                                         llvm::StringRef name,
                                         bool isThreadLocal = false);
 
-FuncDeclaration *getParentFunc(Dsymbol *sym, bool stopOnStatic);
+FuncDeclaration *getParentFunc(Dsymbol *sym);
 
 void Declaration_codegen(Dsymbol *decl);
 void Declaration_codegen(Dsymbol *decl, IRState *irs);
diff --git a/gen/nested.cpp b/gen/nested.cpp
index 8d66844..a15c979 100644
--- a/gen/nested.cpp
+++ b/gen/nested.cpp
@@ -42,14 +42,13 @@ DValue *DtoNestedVariable(Loc &loc, Type *astype, VarDeclaration *vd,
 
   // Check whether we can access the needed frame
   FuncDeclaration *fd = irfunc->decl;
-  while (fd != vdparent) {
-    if (fd->isStatic()) {
-      error(loc, "function %s cannot access frame of function %s",
-            irfunc->decl->toPrettyChars(), vdparent->toPrettyChars());
-      return new DLValue(astype, llvm::UndefValue::get(DtoPtrToType(astype)));
-    }
-    fd = getParentFunc(fd, false);
-    assert(fd);
+  while (fd && fd != vdparent) {
+    fd = getParentFunc(fd);
+  }
+  if (!fd) {
+    error(loc, "function %s cannot access frame of function %s",
+          irfunc->decl->toPrettyChars(), vdparent->toPrettyChars());
+    return new DLValue(astype, llvm::UndefValue::get(DtoPtrToType(astype)));
   }
 
   // is the nested variable in this scope?
@@ -261,7 +260,7 @@ LLValue *DtoNestedContext(Loc &loc, Dsymbol *sym) {
   } else if (FuncDeclaration *symfd = sym->isFuncDeclaration()) {
     // If sym is a nested function, and its parent context is different
     // than the one we got, adjust it.
-    frameToPass = getParentFunc(symfd, true);
+    frameToPass = getParentFunc(symfd);
   }
 
   if (frameToPass) {
@@ -269,7 +268,7 @@ LLValue *DtoNestedContext(Loc &loc, Dsymbol *sym) {
     FuncDeclaration *ctxfd = irFunc.decl;
     IF_LOG Logger::println("Current function is %s", ctxfd->toChars());
     if (fromParent) {
-      ctxfd = getParentFunc(ctxfd, true);
+      ctxfd = getParentFunc(ctxfd);
       assert(ctxfd && "Context from outer function, but no outer function?");
     }
     IF_LOG Logger::println("Context is from %s", ctxfd->toChars());
@@ -319,7 +318,7 @@ static void DtoCreateNestedContextType(FuncDeclaration *fd) {
   }
   irFunc.nestedContextCreated = true;
 
-  FuncDeclaration *parentFunc = getParentFunc(fd, true);
+  FuncDeclaration *parentFunc = getParentFunc(fd);
   // Make sure the parent has already been analyzed.
   if (parentFunc) {
     DtoCreateNestedContextType(parentFunc);
diff --git a/tests/d2/dmd-testsuite b/tests/d2/dmd-testsuite
index 56c5a64..a6d0fc7 160000
--- a/tests/d2/dmd-testsuite
+++ b/tests/d2/dmd-testsuite
@@ -1 +1 @@
-Subproject commit 56c5a640ec6fa34d69b42ef2bea726c3f5991d71
+Subproject commit a6d0fc716643ceee52a7a63d70d7c860e12e5f6d

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-d/ldc.git



More information about the pkg-d-commits mailing list