Commit Graph

163 Commits

Author SHA1 Message Date
Chris Lattner
61afbe993f Fix <rdar://problem/20193929> Can't "return nil" in a convenience initializer
This falls out of the rework I did of 'self' in initializers.  We now correctly
dealloc_ref the allocated object on the failure path of a convenience init.



Swift SVN r27752
2015-04-26 05:13:48 +00:00
Chris Lattner
0e8f0d6bfc fix <rdar://problem/20679379> DI crashes on initializers on protocol extensions
DI makes the assumption that the type of self in an initializer is always
derived from a nominal type.  Now that you can put an initializer body on a
protocol, this isn't true anymore, so teach it about this.



Swift SVN r27714
2015-04-24 23:51:40 +00:00
Chris Lattner
42b4a966b0 Introduce a new null_class SIL instruction for forming a null pointer
reference to something of class type.  This is required to model
RebindSelfInConstructorExpr correctly to DI, since in the class case, 
self.init and super.init *take* a value out of class box so that it 
can pass the +1 value without performing an extra retain.  Nothing
else in the compiler uninitializes a DI-controlled memory object
like this, so nothing else needs this.  DI really doesn't like something
going from initialized to uninitialized.

Yes, I feel super-gross about this and am really unhappy about it.  I
may end up reverting this if I can find an alternate solution to this
problem.



Swift SVN r27525
2015-04-21 05:56:55 +00:00
Chris Lattner
3a58ca60fe improve the location information for the "all members must be initialized before 'return nil'
in a initializer" diagnostic by chasing dataflow information more aggressively.  We now generally
point at the problematic return instead of the init containing it.


Swift SVN r27474
2015-04-20 02:38:46 +00:00
Chris Lattner
17bfa99d89 fix <rdar://problem/20608881> DI miscompiles this testcase into a memory leak
When emiting logic for conditional destruction of a variable, we weren't considering
a delegated init as a store to the variable that needed to be tracked.  This caused us
to miscompile situations like this testcase where the self.init was conditional:

struct X {
  var c : C
  init() { c = C()}
  init?(a : Bool) {
    if a { self.init() }
    return nil
  }
}

This was exposed by other work, but needs to be fixed in any case.



Swift SVN r27471
2015-04-20 00:26:55 +00:00
Michael Gottesman
75ea31dba9 Turn on +0 self by default.
The only caveat is that:

1. We do not properly recognize when we have a let binding and we
perform a guaranteed dynamic call. In such a case, we add an extra
retain, release pair around the call. In order to get that case I will
need to refactor some code in Callee. I want to make this change, but
not at the expense of getting the rest of this work in.

2. Some of the protocol witness thunks generated have unnecessary
retains or releases in a similar manner.

But this is a good first step.

I am going to send a large follow up email with all of the relevant results, so
I can let the bots chew on this a little bit.

rdar://19933044

Swift SVN r27241
2015-04-12 22:23:37 +00:00
Chris Lattner
d5769ad609 fix <rdar://problem/20097963> incorrect DI diagnostic in unreachable code
Swift SVN r26679
2015-03-28 05:47:52 +00:00
Nadav Rotem
d78b376d07 [passes] Replace the old invalidation lattice with a new invalidation scheme.
The old invalidation lattice was incorrect because changes to control flow could cause changes to the
call graph, so we've decided to change the way passes invalidate analysis.  In the new scheme, the lattice
is replaced with a list of traits that passes preserve or invalidate. The current traits are Calls and Branches.
Now, passes report which traits they preserve, which is the opposite of the previous implementation where
passes needed to report what they invalidate.

Node: I tried to limit the changes in this commit to mechanical changes to ease the review. I will cleanup some
of the code in a following commit.

Swift SVN r26449
2015-03-23 21:18:58 +00:00
Chris Lattner
7ecfc9cffc fix <rdar://problem/20135113> QoI: enum failable init that doesn't assign to self produces poor error
Swift SVN r26236
2015-03-17 21:37:02 +00:00
Chris Lattner
01f3e81aa5 Work on VarDecl:
- Rename getParentPattern() -> getParentPatternBinding(), since
   it returns the pattern binding, not the pattern.
 - Introduce new getParentPattern()/getParentInitializer() methods,
   covering the most common uses of getParentPatternBinding().

NFC.



Swift SVN r26175
2015-03-16 01:54:20 +00:00
Chris Lattner
c2b19659bf significantly improve the QoI of DI's diagnostics when emitting errors due to "return nil"
in a failable initializer.  Previously, it would always just say "properties of a class 
instance must be initialized before returning nil".

Now, in designated inits, it adds to that message with notes for each member that is not
initialized but must be.  It also adds a note saying that super.init() must be called if
that is the problem.

In convenience inits, it says:
 "failable convenience initializer must delegate to self.init() before returning nil"

For example, in:

class B : A {
  var x : Int
     override init?() { return nil }

We now produce:

t.swift:13:15: error: all stored properties of a class instance must be initialized before returning nil from an initializer
t.swift:11:7: note: 'self.x' not initialized
t.swift:13:15: note: super.init must be called before returning nil

I don't see any radars about this, but someone was confused on the dev forums:
https://devforums.apple.com/message/1113604#1113604



Swift SVN r26166
2015-03-15 22:12:11 +00:00
Chris Lattner
4f708c049b fix const correctness and standardize on names for the successor list of
TerminatorInsts.  Now you can walk over the successor list of a terminator
and actually modify the SILSuccessor directly, allowing better CFG
transformations.  NFC.




Swift SVN r26140
2015-03-14 17:52:27 +00:00
Chris Lattner
8c258eee67 Fix <rdar://problem/19746552> QoI: variable "used before being initialized" instead of "returned uninitialized" in address-only enum/struct
Teach DI about a pattern in address-only struct/enum initializers, improving diagnostics
on code like:

struct S<T, U> {
    let a : T?
    let b : U?
    
    init(a : T) {
        self.a = a
    }
}

enum E<T> {
  case X(T), Y
  
  init() {
  }
}

from:

t.swift:7:5: error: variable 'self.b' used before being initialized
    }
    ^
t.swift:14:3: error: variable 'self' used before being initialized
  }
  ^

To:

t.swift:7:5: error: return from initializer without initializing all stored properties
    }
    ^
t.swift:3:9: note: 'self.b' not initialized
    let b : U?
        ^
t.swift:14:3: error: return from enum initializer method without storing to 'self'
  }
  ^




Swift SVN r25528
2015-02-25 04:52:55 +00:00
Dmitri Hrybenko
61286f0260 Fix warnings produced by a newer version of Clang
Swift SVN r25257
2015-02-12 23:50:47 +00:00
Erik Eckstein
c2776c455b Rename SILBasicBlock::getID() -> getDebugID()
Swift SVN r24321
2015-01-09 19:37:03 +00:00
Erik Eckstein
12b43dde74 Change the algorithm for computing the availability in DefiniteInitialization.
The old recursive algorithm had exponential complexity in worst case.
The new algorithm is a simple iterative dataflow algorithm.

This fixes <rdar://problem/19259710> Swift project locks up "indexing" or building (LifetimeChecker::doIt())

In the new algorithm I didn't specialize for the NumElements==1 case (as the old algorithm did),
because IMO it does not make a significant difference.



Swift SVN r24309
2015-01-09 17:09:10 +00:00
Chris Lattner
3a7d8df92b fix <rdar://problem/19259730> Using mutating methods in a struct initializer with a let property is rejected
while we're at it, improve the QoI for actually-invalid mutating method calls in struct initalizers.


Swift SVN r24030
2014-12-19 06:52:37 +00:00
Chris Lattner
e5bbc8988b stoop to even more grotty AST crawling to get descent diagnostics from DI.
Swift SVN r23885
2014-12-12 06:34:45 +00:00
Chris Lattner
66ab73bf69 Pour some QoI love on the DI mutation diagnostics when an inout use
happens due to a method call.


Swift SVN r23884
2014-12-12 06:19:24 +00:00
Chris Lattner
d513803d84 Sigificantly replumb how SILGen generates mark_uninitialized instructions, generating
them in a more consistent and principled way.  Two changes here: MUI is generated
when a vardecl is emitted, not as a separate "MarkPatternUninitialized" pass.  Second,
when generating a MUI for self parameters with a temporary alloc_stack (due to the
possibility of superclass remapping of self) emit the MUI on the allocation itself,
not on the incoming argument.  This is a lot more consistent (dissolving a bunch of 
hacks in DI).

In terms of behavior changes, this only changes the raw sil generated by SILGen and
consumed by DI, so there is no user-visible change.  This simply unblocks future work.



Swift SVN r23823
2014-12-10 00:29:40 +00:00
Chris Lattner
674a50df2f refactor how "getPathStringToElement" in DI works, to clean it up and simplify
clients.  NFC except for slightly better diagnostic in .sil testcases.  


Swift SVN r23809
2014-12-09 17:51:06 +00:00
Chris Lattner
cb8a65e831 Clean up the semantics of 'let' properties in a number of ways:
- We switch to a model where let properties may be "initialized", but never
  reassigned.  Specifically, immutable properties in structs/classes may have
  an init value specified in their declaration (but can then never be reset
  in any init implementation) or not (in which case they must be initialized 
  exactly once on all paths through every init.  This makes a lot more sense 
  for immutability, defines several problems away, and provides a path to
  supporting things like (rdar://16181314)

- We now *never* default initialize an immutable property.  Formerly
  we would default initialize optional let properties to nil, but this
  isn't actually useful, and allows an error of omission with let 
  properties.  

This resolves: <rdar://problem/19035287> let properties should only be initializable, not reassignable
and possibly other radars.





Swift SVN r23779
2014-12-08 20:59:53 +00:00
Ben Langmuir
e9e1666ab0 Update for upstream LLVM changes
* removal of StringMap's GetOrCreateValue
* SmallSet::insert now returns a pair like std::set

Swift SVN r23435
2014-11-19 16:49:30 +00:00
Adrian Prantl
c41b30299f Audit all SILPasses to ensure that new instructions are never created
without a valid SILDebugScope. An assertion in IRGenSIL prevents future
optimizations from regressing in this regard.
Introducing SILBuilderWithScope and SILBuilderwithPostprocess to ease the
transition.

This patch is large, but mostly mechanical.
<rdar://problem/18494573> Swift: Debugger is not stopping at the set breakpoint

Swift SVN r22978
2014-10-28 01:49:11 +00:00
Joe Groff
e3f9a2035c SIL: Move SILGen and passes over to use "builtin" instead of "apply (builtin_function_ref)".
Swift SVN r22785
2014-10-15 23:37:22 +00:00
Jordan Rose
042569a3be Optional: Replace uses of Nothing with None.
llvm::Optional (like Swift.Optional!) uses None as its placeholder value,
not Nothing.

Swift SVN r22476
2014-10-02 18:51:42 +00:00
Chris Lattner
a2df9c650e reapply r22223 with a testcase update:
Dramatically improve DI diagnostics in initializers fixing rdar://18414728.

As one small example of the improvement, where an initializer like this:

class Foo {
    var path:String? {
        return "boo"
    }
    
    let aaaaa:String
    
    init() {
        if let p1 = path {

used to  produce the error: "error: variable 'self.aaaaa' used before being initialized" on path,
we now produce:

x.swift:9:21: error: use of 'self' in property access 'path' before all stored properties are initialized
        if let p1 = path {
                    ^
x.swift:6:9: note: 'self.aaaaa' not initialized
    let aaaaa:String
        ^

which is more useful.





Swift SVN r22238
2014-09-23 23:17:29 +00:00
Dmitri Hrybenko
5de6540670 Revert "Dramatically improve DI diagnostics in initializers fixing rdar://18414728."
This reverts commit r22223.

Swift SVN r22233
2014-09-23 21:52:04 +00:00
Chris Lattner
88750f6ff3 Dramatically improve DI diagnostics in initializers fixing rdar://18414728.
As one small example of the improvement, where an initializer like this:

class Foo {
    var path:String? {
        return "boo"
    }
    
    let aaaaa:String
    
    init() {
        if let p1 = path {

used to  produce the error: "error: variable 'self.aaaaa' used before being initialized" on path,
we now produce:

x.swift:9:21: error: use of 'self' in property access 'path' before all stored properties are initialized
        if let p1 = path {
                    ^
x.swift:6:9: note: 'self.aaaaa' not initialized
    let aaaaa:String
        ^

which is more useful.



Swift SVN r22223
2014-09-23 19:28:36 +00:00
Chris Lattner
160438e14e Fix <rdar://problem/18199087> DI doesn't catch use of super properties lexically inside super.init call
When analyzing a super.init call, we have several instructions involved including an upcast
to the parent type and an applyinst to call super.init.  DI was using the location of the upcast
as the point at which it modeled the super.init requirement, not at the point of the applyinst.  This
meant that code like:

 %x = upcast self to basetype
 ... stuff ...
 apply super.init(%x)

would not catch invalid uses of super in the "stuff" range, because DI thought that super.init was
called at the upcast.  Fix this by using the apply as the super.init use, not the upcast.




Swift SVN r22101
2014-09-18 21:52:11 +00:00
Chris Lattner
cc06b7d7a2 tweak the prediate that currently failure from inits where the object is partially
initialized to also cover the delegating init case.  The location info is pretty awful
on these, but it is more important that we reject these in Beta 1 than it is to be pretty.


Swift SVN r21673
2014-09-03 16:08:00 +00:00
Joe Groff
5e57dc13fe DI: Complain if an initializer 'self' is released before being fully initialized.
This raises an error for some cases we don't implement correctly yet, though not ones that require super.init or self.init delegation yet.

Swift SVN r21669
2014-09-03 04:47:31 +00:00
Chris Lattner
c16cdf656d implement support for cleaning up early returns from class initializers that
are delegating and/or derived.


Swift SVN r21623
2014-09-01 06:14:10 +00:00
Chris Lattner
ffdba8fd36 Teach the derived init class 'self' analyzer to look at the refcount result of the
self box as well as the address result, so that it picks up retains and releases.
Classify releases as interesting usepoints, and ignore the dealloc_stack.

Similarly, teach the logic in DefiniteInit's conditional destruction stuff to handle
the derived self case (basically, teaching it to special case the self box).



Swift SVN r21622
2014-09-01 05:19:25 +00:00
Chris Lattner
f154cb1961 implement full support for partial liveness tracking of class elements in class initializers,
allowing partially initialized and conditionally uninitialized elements at failure points.

For example, we compile (with optimizations enabled to clean up the branching) this code:

class SomeClass {}
class RootClassWithNontrivialStoredProperties {
  let x, y: SomeClass

  init?(failAfterPartialInitialization: ()) {
    x = SomeClass()
    return nil 
  }
}

into:

sil @...
bb0(%0 : $RootClassWithNontrivialStoredProperties):
  %1 = alloc_ref $SomeClass                       // users: %3, %4
  %2 = ref_element_addr %0 : $RootClassWithNontrivialStoredProperties, #RootClassWithNontrivialStoredProperties.x // user: %3
  store %1 to %2 : $*SomeClass                    // id: %3
  strong_release %1 : $SomeClass                  // id: %4
  dealloc_ref %0 : $RootClassWithNontrivialStoredProperties // id: %5
  %6 = enum $Optional<RootClassWithNontrivialStoredProperties>, #Optional.None!enumelt // user: %7
  return %6 : $Optional<RootClassWithNontrivialStoredProperties> // id: %7
}

where the elements of the class are all individually tracked and destroyed if necessary before the class is dealloc'd.



Swift SVN r21621
2014-09-01 04:30:42 +00:00
Chris Lattner
5425835c79 Rework handling of retain and release instructions in init methods of classes
to track the release as something that needs the class reference to be alive at.

This implements the first piece of that: if all elements of the class are uninitialized
at the time of the release, just turn the release into a dealloc_ref.  This is correct
because we know that the value would have had to be fully initialized at a retain, and
though careful construction, this only triggers in the init case.

This allows us to compile this:

class RootClassWithNontrivialStoredProperties {
  let x, y: SomeClass

  init?(failBeforeInitialization: ()) {
    return nil
  }
}

into:

sil @_TFC1t39RootClassWithNontrivialStoredPropertiesCfMS0_FT24failBeforeInitializationT__GSqS0__ : $@thin (@thick RootClassWithNontrivialStoredProperties.Type) -> @owned Optional<RootClassWithNontrivialStoredProperties> {
bb0(%0 : $@thick RootClassWithNontrivialStoredProperties.Type):
  %1 = alloc_ref $RootClassWithNontrivialStoredProperties // user: %2
  dealloc_ref %1 : $RootClassWithNontrivialStoredProperties // id: %2
  %3 = enum $Optional<RootClassWithNontrivialStoredProperties>, #Optional.None!enumelt // user: %4
  return %3 : $Optional<RootClassWithNontrivialStoredProperties> // id: %4
}



Swift SVN r21620
2014-09-01 04:10:31 +00:00
Chris Lattner
14024ea13c fix <rdar://problem/15631987> QoI: DI emits two errors for the same problem at the same location
This is straight-forward, we just unique based on SourceLoc instead of by SILLocation.  In cases
where there are multiple SIL Instructions that map to the same file/line/column, the SourceLoc is
a better approximation of what the user cares about.

This wouldn't be super important, except that not having it causes a QoI regression 
in a patch I'm working on.



Swift SVN r21619
2014-09-01 03:38:02 +00:00
Chris Lattner
a1d4f47930 fix <rdar://problem/18089574> Protocol member in struct + delegating init miscompilation
When DI processes a delegating initializer of an address-only value type, make sure to
mark the copy_addr as an initialization (as it was already doing for an assign 
instruction) to fix a miscompilation.

The change to DIMemoryUseCollector.cpp is just to facilitate writing testcases.



Swift SVN r21478
2014-08-27 06:22:39 +00:00
Nadav Rotem
f5549dce0f A small cleanup suggested by Chris. NFC.
Swift SVN r20657
2014-07-28 23:38:12 +00:00
Nadav Rotem
a09e0d58ba DI: Handle 'assert' instructions in the SelfInit state.
rdar://17746401



Swift SVN r20646
2014-07-28 21:46:55 +00:00
Chris Lattner
d214e1a75c fix <rdar://problem/17686667> If super.init is implicitly inserted, DI diagnostics have no location info
This has two changes:
 - In the case when we have an invalid source loc, DI will default to emitting diagnostics
   at the enclosing function's location.  This makes it more robust in general against
   implicitly synthesized code.

 - For this diagnostic in particular, emit a tailored message, since super.init is a commonly
   synthesized thing.



Swift SVN r20104
2014-07-17 17:44:16 +00:00
Chris Lattner
86df649f90 Fix <rdar://problem/16797372> Bogus error: self.init called multiple times in initializer
DI has two paths for analyzing initialization state: one optimize for solving a single
fact (e.g. the state of a single non-tuple variable in a function), and one that handles 
the full generality of multiple states in parallel (e.g. a tuple in a function or the
fields of a struct/class during its init method).

Unfortunately, the dataflow analysis between these two implementations drifted, and I
fixed a bug in the "N" case (rdar://16119509 back in feb) that didn't get fixed in the "1"
case.  This reworks all of the dataflow to make the fact propagation more similar between
the two paths and fix the bug along the way.



Swift SVN r17343
2014-05-04 00:22:33 +00:00
Chris Lattner
2aa3e50343 fix <rdar://problem/16660680> QoI: fatal() in init method complains about super.init being called multiple times
The problem here is that the implicitly generated self.init() call is unreachable, 
and DCE runs after DI, so DI doesn't know it is unreachable.  Fix this by adding a trivial
reachability check before emitting a diagnostic. 

This isn't a wholesome solution though, as certain infinite loops and other scenarios that
rely on constant folding won't be handled properly.  If anyone runs into this, we could consider
moving constant prop and DCE earlier, though that comes with its own tradeoffs.


Swift SVN r16898
2014-04-26 23:39:00 +00:00
Joe Groff
8adaab0233 Fold ExtInfo::isThin and ::isBlock into a "Representation" enum.
These bits are orthogonal to each other, so combine them into one, and diagnose attempts to produce a type that's both. Spot-fix a bunch of places this revealed by inspection that we would have crashed in SILGen or IRGen if blocks were be handled.

Swift SVN r16088
2014-04-09 00:37:26 +00:00
Chris Lattner
3b29fb68a8 fit in 80 columns and format more nicely :)
Swift SVN r15803
2014-04-02 16:22:45 +00:00
Chris Lattner
afea47b621 rename "destroy_value" to "release_value", part of rdar://15889208.
Swift SVN r15777
2014-04-02 05:33:52 +00:00
Chris Lattner
6051a5e9a4 improve the QoI of DI's diagnostics when calling a method or accessing a computed
property in a base class before calling super.init.  This is a nice improvement, 
and also avoids regressing on QoI when a patch I'm working on finally lands.


Swift SVN r15379
2014-03-23 05:51:41 +00:00
Chris Lattner
001c1890e5 put all the SIL*Transform classes in anonymous namespaces, there is
no need for their symbols to be exported out of their implementation
file.


Swift SVN r14714
2014-03-06 01:49:53 +00:00
Chris Lattner
7baac64e94 fix rdar://16119509 - <unknown>:0: error: super.init called multiple times in initializer
This is a problem whereby the parallel bitvector dataflow stuff in DI was
incorrectly caching speculated results in cycles.  In principle, this algorithm
should be reworked to use standard oldschool RPO bitwise dataflow algorithms, but
this patch is a minimal fix and the performance of this code is unlikely to be an issue
anyway.


Swift SVN r14322
2014-02-24 23:23:22 +00:00
Joe Groff
b19cfb27ea Drop the context generic params from SILFunctionType.
SILFunctionType is now 100% context free!

Swift SVN r13775
2014-02-11 04:21:20 +00:00