Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-9871] 'malloc: [...] pointer being freed was not allocated' during runtime when using 'indirect' enum case with '[Self]' associated value #52277

Closed
swift-ci opened this issue Feb 6, 2019 · 15 comments

Comments

@swift-ci
Copy link
Collaborator

@swift-ci swift-ci commented Feb 6, 2019

Previous ID SR-9871
Radar rdar://problem/47852446
Original Reporter luiz (JIRA User)
Type Bug
Status Closed
Resolution Done
Environment
  • Xcode 10.2 beta 2 (10P91b)

  • Apple Swift version 5.0 (swiftlang-1001.0.60.3 clang-1001.0.37.8)
    Target: x86_64-apple-darwin18.2.0
    ABI version: 0.7

  • macOS 10.14.2 (18C54)

Additional Detail from JIRA
Votes 1
Component/s Compiler
Labels Bug, 5.0Regression, Runtime
Assignee @gottesmm
Priority Medium

md5: 2b8141b3d0e3078efc1e46d9461a4f87

Issue Description:

The following test case traps during runtime in the latest Xcode 10.2 beta 2 (10P91b):

public enum MatchRule<U: Equatable> {
    case any
    case equals(U)
    indirect case all([MatchRule])
    
    public func evaluate(_ value: U) -> Bool {
        switch self {
        case .any:
            return true
            
        case .equals(let v):
            return value == v
            
        case .all(let rules):
            for r in rules {
                if !r.evaluate(value) {
                    return false
                }
            }
            
            return true
        }
    }
}

print(MatchRule<String>.all([.equals("a"), .any]).evaluate("a"))

The error reads:

$ ./Test
Test(4717,0x10f7375c0) malloc: *** error for object 0x7fea28d0bc40: pointer being freed was not allocated
Test(4717,0x10f7375c0) malloc: *** set a breakpoint in malloc_error_break to debug

Removing the spurious 'indirect' modifier from 'case all([MatchRule])' fixes the crash and the code behaves normally.

@belkadan
Copy link
Contributor

@belkadan belkadan commented Feb 6, 2019

Gets an assertion failure on master:

Assertion failed: (isPlusOne(SGF) && "Can not forward borrowed RValues"), function forwardInto, file /Volumes/Data/swift-public/swift/lib/SILGen/RValue.cpp, line 531.
Stack dump:
0.  Program arguments: /Volumes/Data/swift-public/build/ninja/swift-macosx-x86_64/bin/swift -frontend -c -primary-file - -target x86_64-apple-darwin18.5.0 -enable-objc-interop -sdk /Volumes/Data/Applications/Xcode10.2.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk -color-diagnostics -module-name main -o /var/folders/_d/dmrgv26d3bs6lkrks9z825_w0000gn/T/--2848c3.o 
1.  While emitting SIL for 'evaluate(_:)' (at <stdin>:6:12)
2.  While silgen emitFunction SIL function "@$s4main9MatchRuleO8evaluateySbxF".
 for 'evaluate(_:)' (at <stdin>:6:12)

cc @gottesmm, @jckarter

@gottesmm
Copy link
Member

@gottesmm gottesmm commented Feb 7, 2019

I have a small fix.

@gottesmm
Copy link
Member

@gottesmm gottesmm commented Feb 7, 2019

(it is just using ensurePlusOne. No leaks/use-after-free occur. Before we use that though, I would like to understand the problem better).

@gottesmm
Copy link
Member

@gottesmm gottesmm commented Feb 7, 2019

Slightly simpler (without stdlib type):

class Box<T> {
  var value: T
  init(inputValue: T) { value = inputValue }
}


enum Value<U> {
  case inline(U)
  indirect case box(Box<U>)
}


func evaluate<U>(v: Value<U>) {
  switch v {
  case .inline:
    return
  case .box(let box):
    return
  }
}

@gottesmm
Copy link
Member

@gottesmm gottesmm commented Feb 7, 2019

In the following SIL, we are trying to store %12 into memory.

// evaluate<A>(v:)
sil hidden [ossa] @$s8testcase8evaluate1vyAA5ValueOyxG_tlF : $@convention(thin) <U> (@in_guaranteed Value<U>) -> () {
// %0                                             // users: %3, %1
bb0(%0 : $*Value<U>):
  debug_value_addr %0 : $*Value<U>, let, name "v", argno 1 // id: %1
  %2 = alloc_stack $Value<U>                      // users: %9, %7, %5, %4, %3
  copy_addr %0 to [initialization] %2 : $*Value<U> // id: %3
  switch_enum_addr %2 : $*Value<U>, case #Value.inline!enumelt.1: bb1, case #Value.box!enumelt.1: bb2 // id: %4

bb1:                                              // Preds: bb0
  %5 = unchecked_take_enum_data_addr %2 : $*Value<U>, #Value.inline!enumelt.1 // user: %6
  destroy_addr %5 : $*U                           // id: %6
  dealloc_stack %2 : $*Value<U>                   // id: %7
  br bb6                                          // id: %8

bb2:                                              // Preds: bb0
  %9 = unchecked_take_enum_data_addr %2 : $*Value<U>, #Value.box!enumelt.1 // user: %10
  %10 = load [take] %9 : $*<τ_0_0> { var Box<τ_0_0> } <U> // user: %11
  %11 = project_box %10 : $<τ_0_0> { var Box<τ_0_0> } <U>, 0 // user: %12
  %12 = load_borrow %11 : $*Box<U>

bb3:

bb4:

bb5:

bb6:                                              // Preds: bb1

bb7:
} // end sil function '$s8testcase8evaluate1vyAA5ValueOyxG_tlF'

@gottesmm
Copy link
Member

@gottesmm gottesmm commented Feb 7, 2019

Ok. This is interesting. The take_borrow has a TakeAlways. We should have copied it before we made that transition.

@gottesmm
Copy link
Member

@gottesmm gottesmm commented Feb 7, 2019

I found the problem:

https://github.com/apple/swift/blob/master/lib/SILGen/SILGenPattern.cpp#L2176

At the same time, I also noticed that we are also /not/ inserting a read access here like we do in the other parts of the code that deals with boxes.

@gottesmm
Copy link
Member

@gottesmm gottesmm commented Feb 7, 2019

@gottesmm
Copy link
Member

@gottesmm gottesmm commented Feb 7, 2019

I talked with Andy. He said that the missing accesses will just cause the verifier to be more strict. I am not sure if they matter.

@gottesmm
Copy link
Member

@gottesmm gottesmm commented Feb 7, 2019

@gottesmm
Copy link
Member

@gottesmm gottesmm commented Feb 8, 2019

Merged into both 5.0 and master.

@tonyarnold
Copy link
Contributor

@tonyarnold tonyarnold commented Feb 22, 2019

Did this fix make it into Xcode 10.2 beta 3?

@swift-ci
Copy link
Collaborator Author

@swift-ci swift-ci commented Feb 22, 2019

Comment by Luiz Fernando Silva (JIRA)

@tonyarnold seems like this fix didn't make to beta 3 yet.

@swift-ci
Copy link
Collaborator Author

@swift-ci swift-ci commented Mar 9, 2019

Comment by Luiz Fernando Silva (JIRA)

Appears to be fixed in Xcode 10.2 beta 4!

@AnnaZaks
Copy link
Mannequin

@AnnaZaks AnnaZaks mannequin commented Jul 23, 2019

Closing the bug.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants