IPA.rst 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. Inlining
  2. ========
  3. There are several options that control which calls the analyzer will consider for
  4. inlining. The major one is ``-analyzer-config ipa``:
  5. * ``analyzer-config ipa=none`` - All inlining is disabled. This is the only mode
  6. available in LLVM 3.1 and earlier and in Xcode 4.3 and earlier.
  7. * ``analyzer-config ipa=basic-inlining`` - Turns on inlining for C functions, C++
  8. static member functions, and blocks -- essentially, the calls that behave
  9. like simple C function calls. This is essentially the mode used in
  10. Xcode 4.4.
  11. * ``analyzer-config ipa=inlining`` - Turns on inlining when we can confidently find
  12. the function/method body corresponding to the call. (C functions, static
  13. functions, devirtualized C++ methods, Objective-C class methods, Objective-C
  14. instance methods when ExprEngine is confident about the dynamic type of the
  15. instance).
  16. * ``analyzer-config ipa=dynamic`` - Inline instance methods for which the type is
  17. determined at runtime and we are not 100% sure that our type info is
  18. correct. For virtual calls, inline the most plausible definition.
  19. * ``analyzer-config ipa=dynamic-bifurcate`` - Same as -analyzer-config ipa=dynamic,
  20. but the path is split. We inline on one branch and do not inline on the
  21. other. This mode does not drop the coverage in cases when the parent class
  22. has code that is only exercised when some of its methods are overridden.
  23. Currently, ``-analyzer-config ipa=dynamic-bifurcate`` is the default mode.
  24. While ``-analyzer-config ipa`` determines in general how aggressively the analyzer
  25. will try to inline functions, several additional options control which types of
  26. functions can inlined, in an all-or-nothing way. These options use the
  27. analyzer's configuration table, so they are all specified as follows:
  28. ``-analyzer-config OPTION=VALUE``
  29. c++-inlining
  30. ------------
  31. This option controls which C++ member functions may be inlined.
  32. ``-analyzer-config c++-inlining=[none | methods | constructors | destructors]``
  33. Each of these modes implies that all the previous member function kinds will be
  34. inlined as well; it doesn't make sense to inline destructors without inlining
  35. constructors, for example.
  36. The default c++-inlining mode is 'destructors', meaning that all member
  37. functions with visible definitions will be considered for inlining. In some
  38. cases the analyzer may still choose not to inline the function.
  39. Note that under 'constructors', constructors for types with non-trivial
  40. destructors will not be inlined. Additionally, no C++ member functions will be
  41. inlined under -analyzer-config ipa=none or -analyzer-config ipa=basic-inlining,
  42. regardless of the setting of the c++-inlining mode.
  43. c++-template-inlining
  44. ^^^^^^^^^^^^^^^^^^^^^
  45. This option controls whether C++ templated functions may be inlined.
  46. ``-analyzer-config c++-template-inlining=[true | false]``
  47. Currently, template functions are considered for inlining by default.
  48. The motivation behind this option is that very generic code can be a source
  49. of false positives, either by considering paths that the caller considers
  50. impossible (by some unstated precondition), or by inlining some but not all
  51. of a deep implementation of a function.
  52. c++-stdlib-inlining
  53. ^^^^^^^^^^^^^^^^^^^
  54. This option controls whether functions from the C++ standard library, including
  55. methods of the container classes in the Standard Template Library, should be
  56. considered for inlining.
  57. ``-analyzer-config c++-stdlib-inlining=[true | false]``
  58. Currently, C++ standard library functions are considered for inlining by
  59. default.
  60. The standard library functions and the STL in particular are used ubiquitously
  61. enough that our tolerance for false positives is even lower here. A false
  62. positive due to poor modeling of the STL leads to a poor user experience, since
  63. most users would not be comfortable adding assertions to system headers in order
  64. to silence analyzer warnings.
  65. c++-container-inlining
  66. ^^^^^^^^^^^^^^^^^^^^^^
  67. This option controls whether constructors and destructors of "container" types
  68. should be considered for inlining.
  69. ``-analyzer-config c++-container-inlining=[true | false]``
  70. Currently, these constructors and destructors are NOT considered for inlining
  71. by default.
  72. The current implementation of this setting checks whether a type has a member
  73. named 'iterator' or a member named 'begin'; these names are idiomatic in C++,
  74. with the latter specified in the C++11 standard. The analyzer currently does a
  75. fairly poor job of modeling certain data structure invariants of container-like
  76. objects. For example, these three expressions should be equivalent:
  77. .. code-block:: cpp
  78. std::distance(c.begin(), c.end()) == 0
  79. c.begin() == c.end()
  80. c.empty()
  81. Many of these issues are avoided if containers always have unknown, symbolic
  82. state, which is what happens when their constructors are treated as opaque.
  83. In the future, we may decide specific containers are "safe" to model through
  84. inlining, or choose to model them directly using checkers instead.
  85. Basics of Implementation
  86. ------------------------
  87. The low-level mechanism of inlining a function is handled in
  88. ExprEngine::inlineCall and ExprEngine::processCallExit.
  89. If the conditions are right for inlining, a CallEnter node is created and added
  90. to the analysis work list. The CallEnter node marks the change to a new
  91. LocationContext representing the called function, and its state includes the
  92. contents of the new stack frame. When the CallEnter node is actually processed,
  93. its single successor will be a edge to the first CFG block in the function.
  94. Exiting an inlined function is a bit more work, fortunately broken up into
  95. reasonable steps:
  96. 1. The CoreEngine realizes we're at the end of an inlined call and generates a
  97. CallExitBegin node.
  98. 2. ExprEngine takes over (in processCallExit) and finds the return value of the
  99. function, if it has one. This is bound to the expression that triggered the
  100. call. (In the case of calls without origin expressions, such as destructors,
  101. this step is skipped.)
  102. 3. Dead symbols and bindings are cleaned out from the state, including any local
  103. bindings.
  104. 4. A CallExitEnd node is generated, which marks the transition back to the
  105. caller's LocationContext.
  106. 5. Custom post-call checks are processed and the final nodes are pushed back
  107. onto the work list, so that evaluation of the caller can continue.
  108. Retry Without Inlining
  109. ^^^^^^^^^^^^^^^^^^^^^^
  110. In some cases, we would like to retry analysis without inlining a particular
  111. call.
  112. Currently, we use this technique to recover coverage in case we stop
  113. analyzing a path due to exceeding the maximum block count inside an inlined
  114. function.
  115. When this situation is detected, we walk up the path to find the first node
  116. before inlining was started and enqueue it on the WorkList with a special
  117. ReplayWithoutInlining bit added to it (ExprEngine::replayWithoutInlining). The
  118. path is then re-analyzed from that point without inlining that particular call.
  119. Deciding When to Inline
  120. ^^^^^^^^^^^^^^^^^^^^^^^
  121. In general, the analyzer attempts to inline as much as possible, since it
  122. provides a better summary of what actually happens in the program. There are
  123. some cases, however, where the analyzer chooses not to inline:
  124. - If there is no definition available for the called function or method. In
  125. this case, there is no opportunity to inline.
  126. - If the CFG cannot be constructed for a called function, or the liveness
  127. cannot be computed. These are prerequisites for analyzing a function body,
  128. with or without inlining.
  129. - If the LocationContext chain for a given ExplodedNode reaches a maximum cutoff
  130. depth. This prevents unbounded analysis due to infinite recursion, but also
  131. serves as a useful cutoff for performance reasons.
  132. - If the function is variadic. This is not a hard limitation, but an engineering
  133. limitation.
  134. Tracked by: <rdar://problem/12147064> Support inlining of variadic functions
  135. - In C++, constructors are not inlined unless the destructor call will be
  136. processed by the ExprEngine. Thus, if the CFG was built without nodes for
  137. implicit destructors, or if the destructors for the given object are not
  138. represented in the CFG, the constructor will not be inlined. (As an exception,
  139. constructors for objects with trivial constructors can still be inlined.)
  140. See "C++ Caveats" below.
  141. - In C++, ExprEngine does not inline custom implementations of operator 'new'
  142. or operator 'delete', nor does it inline the constructors and destructors
  143. associated with these. See "C++ Caveats" below.
  144. - Calls resulting in "dynamic dispatch" are specially handled. See more below.
  145. - The FunctionSummaries map stores additional information about declarations,
  146. some of which is collected at runtime based on previous analyses.
  147. We do not inline functions which were not profitable to inline in a different
  148. context (for example, if the maximum block count was exceeded; see
  149. "Retry Without Inlining").
  150. Dynamic Calls and Devirtualization
  151. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  152. "Dynamic" calls are those that are resolved at runtime, such as C++ virtual
  153. method calls and Objective-C message sends. Due to the path-sensitive nature of
  154. the analysis, the analyzer may be able to reason about the dynamic type of the
  155. object whose method is being called and thus "devirtualize" the call.
  156. This path-sensitive devirtualization occurs when the analyzer can determine what
  157. method would actually be called at runtime. This is possible when the type
  158. information is constrained enough for a simulated C++/Objective-C object that
  159. the analyzer can make such a decision.
  160. DynamicTypeInfo
  161. ^^^^^^^^^^^^^^^
  162. As the analyzer analyzes a path, it may accrue information to refine the
  163. knowledge about the type of an object. This can then be used to make better
  164. decisions about the target method of a call.
  165. Such type information is tracked as DynamicTypeInfo. This is path-sensitive
  166. data that is stored in ProgramState, which defines a mapping from MemRegions to
  167. an (optional) DynamicTypeInfo.
  168. If no DynamicTypeInfo has been explicitly set for a MemRegion, it will be lazily
  169. inferred from the region's type or associated symbol. Information from symbolic
  170. regions is weaker than from true typed regions.
  171. EXAMPLE: A C++ object declared "A obj" is known to have the class 'A', but a
  172. reference "A &ref" may dynamically be a subclass of 'A'.
  173. The DynamicTypePropagation checker gathers and propagates DynamicTypeInfo,
  174. updating it as information is observed along a path that can refine that type
  175. information for a region.
  176. WARNING: Not all of the existing analyzer code has been retrofitted to use
  177. DynamicTypeInfo, nor is it universally appropriate. In particular,
  178. DynamicTypeInfo always applies to a region with all casts stripped
  179. off, but sometimes the information provided by casts can be useful.
  180. RuntimeDefinition
  181. ^^^^^^^^^^^^^^^^^
  182. The basis of devirtualization is CallEvent's getRuntimeDefinition() method,
  183. which returns a RuntimeDefinition object. When asked to provide a definition,
  184. the CallEvents for dynamic calls will use the DynamicTypeInfo in their
  185. ProgramState to attempt to devirtualize the call. In the case of no dynamic
  186. dispatch, or perfectly constrained devirtualization, the resulting
  187. RuntimeDefinition contains a Decl corresponding to the definition of the called
  188. function, and RuntimeDefinition::mayHaveOtherDefinitions will return FALSE.
  189. In the case of dynamic dispatch where our information is not perfect, CallEvent
  190. can make a guess, but RuntimeDefinition::mayHaveOtherDefinitions will return
  191. TRUE. The RuntimeDefinition object will then also include a MemRegion
  192. corresponding to the object being called (i.e., the "receiver" in Objective-C
  193. parlance), which ExprEngine uses to decide whether or not the call should be
  194. inlined.
  195. Inlining Dynamic Calls
  196. ^^^^^^^^^^^^^^^^^^^^^^
  197. The -analyzer-config ipa option has five different modes: none, basic-inlining,
  198. inlining, dynamic, and dynamic-bifurcate. Under -analyzer-config ipa=dynamic,
  199. all dynamic calls are inlined, whether we are certain or not that this will
  200. actually be the definition used at runtime. Under -analyzer-config ipa=inlining,
  201. only "near-perfect" devirtualized calls are inlined*, and other dynamic calls
  202. are evaluated conservatively (as if no definition were available).
  203. * Currently, no Objective-C messages are not inlined under
  204. -analyzer-config ipa=inlining, even if we are reasonably confident of the type
  205. of the receiver. We plan to enable this once we have tested our heuristics
  206. more thoroughly.
  207. The last option, -analyzer-config ipa=dynamic-bifurcate, behaves similarly to
  208. "dynamic", but performs a conservative invalidation in the general virtual case
  209. in *addition* to inlining. The details of this are discussed below.
  210. As stated above, -analyzer-config ipa=basic-inlining does not inline any C++
  211. member functions or Objective-C method calls, even if they are non-virtual or
  212. can be safely devirtualized.
  213. Bifurcation
  214. ^^^^^^^^^^^
  215. ExprEngine::BifurcateCall implements the ``-analyzer-config ipa=dynamic-bifurcate``
  216. mode.
  217. When a call is made on an object with imprecise dynamic type information
  218. (RuntimeDefinition::mayHaveOtherDefinitions() evaluates to TRUE), ExprEngine
  219. bifurcates the path and marks the object's region (retrieved from the
  220. RuntimeDefinition object) with a path-sensitive "mode" in the ProgramState.
  221. Currently, there are 2 modes:
  222. * ``DynamicDispatchModeInlined`` - Models the case where the dynamic type information
  223. of the receiver (MemoryRegion) is assumed to be perfectly constrained so
  224. that a given definition of a method is expected to be the code actually
  225. called. When this mode is set, ExprEngine uses the Decl from
  226. RuntimeDefinition to inline any dynamically dispatched call sent to this
  227. receiver because the function definition is considered to be fully resolved.
  228. * ``DynamicDispatchModeConservative`` - Models the case where the dynamic type
  229. information is assumed to be incorrect, for example, implies that the method
  230. definition is overridden in a subclass. In such cases, ExprEngine does not
  231. inline the methods sent to the receiver (MemoryRegion), even if a candidate
  232. definition is available. This mode is conservative about simulating the
  233. effects of a call.
  234. Going forward along the symbolic execution path, ExprEngine consults the mode
  235. of the receiver's MemRegion to make decisions on whether the calls should be
  236. inlined or not, which ensures that there is at most one split per region.
  237. At a high level, "bifurcation mode" allows for increased semantic coverage in
  238. cases where the parent method contains code which is only executed when the
  239. class is subclassed. The disadvantages of this mode are a (considerable?)
  240. performance hit and the possibility of false positives on the path where the
  241. conservative mode is used.
  242. Objective-C Message Heuristics
  243. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  244. ExprEngine relies on a set of heuristics to partition the set of Objective-C
  245. method calls into those that require bifurcation and those that do not. Below
  246. are the cases when the DynamicTypeInfo of the object is considered precise
  247. (cannot be a subclass):
  248. - If the object was created with +alloc or +new and initialized with an -init
  249. method.
  250. - If the calls are property accesses using dot syntax. This is based on the
  251. assumption that children rarely override properties, or do so in an
  252. essentially compatible way.
  253. - If the class interface is declared inside the main source file. In this case
  254. it is unlikely that it will be subclassed.
  255. - If the method is not declared outside of main source file, either by the
  256. receiver's class or by any superclasses.
  257. C++ Caveats
  258. ^^^^^^^^^^^
  259. C++11 [class.cdtor]p4 describes how the vtable of an object is modified as it is
  260. being constructed or destructed; that is, the type of the object depends on
  261. which base constructors have been completed. This is tracked using
  262. DynamicTypeInfo in the DynamicTypePropagation checker.
  263. There are several limitations in the current implementation:
  264. * Temporaries are poorly modeled right now because we're not confident in the
  265. placement of their destructors in the CFG. We currently won't inline their
  266. constructors unless the destructor is trivial, and don't process their
  267. destructors at all, not even to invalidate the region.
  268. * 'new' is poorly modeled due to some nasty CFG/design issues. This is tracked
  269. in PR12014. 'delete' is not modeled at all.
  270. * Arrays of objects are modeled very poorly right now. ExprEngine currently
  271. only simulates the first constructor and first destructor. Because of this,
  272. ExprEngine does not inline any constructors or destructors for arrays.
  273. CallEvent
  274. ^^^^^^^^^
  275. A CallEvent represents a specific call to a function, method, or other body of
  276. code. It is path-sensitive, containing both the current state (ProgramStateRef)
  277. and stack space (LocationContext), and provides uniform access to the argument
  278. values and return type of a call, no matter how the call is written in the
  279. source or what sort of code body is being invoked.
  280. NOTE: For those familiar with Cocoa, CallEvent is roughly equivalent to
  281. NSInvocation.
  282. CallEvent should be used whenever there is logic dealing with function calls
  283. that does not care how the call occurred.
  284. Examples include checking that arguments satisfy preconditions (such as
  285. __attribute__((nonnull))), and attempting to inline a call.
  286. CallEvents are reference-counted objects managed by a CallEventManager. While
  287. there is no inherent issue with persisting them (say, in a ProgramState's GDM),
  288. they are intended for short-lived use, and can be recreated from CFGElements or
  289. non-top-level StackFrameContexts fairly easily.