Uploaded image for project: 'Swift'
  1. Swift
  2. SR-2189

Nested function with local default value crashes

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: Medium
    • Resolution: Done
    • Component/s: Compiler
    • Labels:
    • Environment:

      Swift 0712ffcb07f64980e6a5f321c55618a9a50c6d9d

      Description

      The following snippet crashes the compiler:

      func doSomething() { 
          var aValue = 42 
          func nestedFunc(_ v: Int = aValue) { 
              print("Got \(v)") 
          } 
          nestedFunc() 
          nestedFunc(36)
      }
      
      Assertion failed: (!var->getDeclContext()->isLocalContext() && "not a global variable!"), function isGlobalLazilyInitialized, file /Spring/Projects/3rdParty/OpenSource/Apple/swift/lib/SILGen/SILGenGlobalVariable.cpp, line 64.
      
      0  swift                    0x0000000108e00c3b llvm::sys::PrintStackTrace(llvm::raw_ostream&) + 43
      1  swift                    0x0000000108dffe66 llvm::sys::RunSignalHandlers() + 70
      2  swift                    0x0000000108e01511 SignalHandler(int) + 641
      3  libsystem_platform.dylib 0x000000010b60dd7a _sigtramp + 26
      4  libsystem_pthread.dylib  0x000000010b6312c8 _pthread_keys + 9720
      5  swift                    0x0000000108e0115e abort + 14
      6  swift                    0x0000000108e01141 __assert_rtn + 81
      7  swift                    0x00000001061a207c swift::Lowering::SILGenFunction::emitGlobalVariableRef(swift::SILLocation, swift::VarDecl*) + 1356
      8  swift                    0x0000000106185a04 swift::Lowering::SILGenFunction::emitLValueForDecl(swift::SILLocation, swift::VarDecl*, swift::CanType, swift::AccessKind, swift::AccessSemantics) + 324
      9  swift                    0x00000001061a8596 emitLValueForNonMemberVarDecl(swift::Lowering::SILGenFunction&, swift::SILLocation, swift::VarDecl*, swift::CanType, swift::AccessKind, swift::AccessSemantics) + 150
      10 swift                    0x00000001061a8464 SILGenLValue::visitDeclRefExpr(swift::DeclRefExpr*, swift::AccessKind) + 228
      11 swift                    0x00000001061a6e73 swift::ASTVisitor<SILGenLValue, swift::Lowering::LValue, void, void, void, void, void, swift::AccessKind>::visit(swift::Expr*, swift::AccessKind) + 99
      12 swift                    0x00000001061a6d0a swift::Lowering::SILGenFunction::emitLValue(swift::Expr*, swift::AccessKind) + 106
      13 swift                    0x000000010618c632 swift::ASTVisitor<(anonymous namespace)::RValueEmitter, swift::Lowering::RValue, void, void, void, void, void, swift::Lowering::SGFContext>::visit(swift::Expr*, swift::Lowering::SGFContext) + 8882
      14 swift                    0x0000000106185733 swift::Lowering::SILGenFunction::emitRValue(swift::Expr*, swift::Lowering::SGFContext) + 35
      15 swift                    0x00000001061e0617 swift::Lowering::SILGenFunction::emitReturnExpr(swift::SILLocation, swift::Expr*) + 903
      16 swift                    0x00000001061a0cb0 swift::Lowering::SILGenFunction::emitGeneratorFunction(swift::SILDeclRef, swift::Expr*) + 320
      17 swift                    0x000000010613ad3a swift::Lowering::SILGenModule::emitDefaultArgGenerator(swift::SILDeclRef, swift::Expr*) + 586
      18 swift                    0x0000000106137f0e swift::Lowering::SILGenModule::emitAbstractFuncDecl(swift::AbstractFunctionDecl*) + 318
      19 swift                    0x00000001061375ae swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*) + 46
      20 swift                    0x00000001061ddb56 swift::ASTVisitor<(anonymous namespace)::StmtEmitter, void, void, void, void, void, void>::visit(swift::Stmt*) + 566
      21 swift                    0x00000001061dee20 swift::ASTVisitor<(anonymous namespace)::StmtEmitter, void, void, void, void, void, void>::visit(swift::Stmt*) + 5376
      22 swift                    0x00000001061ddad0 swift::ASTVisitor<(anonymous namespace)::StmtEmitter, void, void, void, void, void, void>::visit(swift::Stmt*) + 432
      23 swift                    0x00000001061dd915 swift::Lowering::SILGenFunction::emitStmt(swift::Stmt*) + 21
      24 swift                    0x000000010619df1a swift::Lowering::SILGenFunction::emitFunction(swift::FuncDecl*) + 362
      25 swift                    0x0000000106140b38 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*)::$_1::operator()(swift::SILFunction*) const + 216
      26 swift                    0x00000001061377e9 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*) + 617
      27 swift                    0x00000001061e41b0 swift::ASTVisitor<SILGenExtension, void, void, void, void, void, void>::visit(swift::Decl*) + 368
      28 swift                    0x00000001061e349b SILGenExtension::emitExtension(swift::ExtensionDecl*) + 59
      29 swift                    0x00000001061e3455 swift::Lowering::SILGenModule::visitExtensionDecl(swift::ExtensionDecl*) + 21
      30 swift                    0x000000010613d48b swift::Lowering::SILGenModule::emitSourceFile(swift::SourceFile*, unsigned int) + 715
      31 swift                    0x000000010613e370 swift::SILModule::constructSIL(swift::ModuleDecl*, swift::SILOptions&, swift::FileUnit*, llvm::Optional<unsigned int>, bool, bool) + 928
      32 swift                    0x000000010613e895 swift::performSILGeneration(swift::FileUnit&, swift::SILOptions&, llvm::Optional<unsigned int>, bool) + 117
      33 swift                    0x0000000105fac436 performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*) + 13846
      34 swift                    0x0000000105fa7b4f swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 2895
      35 swift                    0x0000000105f6a0a0 main + 2448
      36 libdyld.dylib            0x000000010b2df255 start + 1
      37 libdyld.dylib            0x0000000000000057 start + 4107406851
      

      The use case for doing this was that nestedFunc was being called from a loop (capturing some common logic that gets called in a few branches), and aValue is a cumulative value. We almost always want to use that value, but there is one edge-case where we need to use a different value from a previous iteration.

      The same functionality could be achieved by always capturing aValue, making the parameter optional and branching on whether or not an override was given.

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              slavapestov Slava Pestov
              Reporter:
              kawa Karl
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: