Commit Graph

701 Commits

Author SHA1 Message Date
Jordan Rose e521f93225 [analyzer] Look up DynamicTypeInfo by region instead of symbol.
This allows us to store type info for non-symbolic regions.

No functionality change.

llvm-svn: 161811
2012-08-13 23:59:07 +00:00
Jordan Rose ce6c99a559 [analyzer] Reduce code duplication: make CXXDestructorCall a CXXInstanceCall.
While there is now some duplication between SimpleCall and the CXXInstanceCall
sub-hierarchy, this is much better than copy-and-pasting the devirtualization
logic shared by both instance methods and destructors.

An unfortunate side effect is that there is no longer a single CallEvent type
that corresponds to "calls written as CallExprs". For the most part this is a
good thing, but the checker callback eval::Call still takes a CallExpr rather
than a CallEvent (since we're not sure if we want to allow checkers to
evaluate other kinds of calls). A mistake here will be caught by a cast<> in
CheckerManager::runCheckersForEvalCall.

No functionality change.

llvm-svn: 161809
2012-08-13 23:46:05 +00:00
Jordan Rose 710f6b1259 [analyzer] Be more careful when downcasting for devirtualization.
Virtual base regions are never layered, so simply stripping them off won't
necessarily get you to the correct casted class. Instead, what we want is
the same logic for evaluating dynamic_cast: strip off base regions if possible,
but add new base regions if necessary.

llvm-svn: 161808
2012-08-13 23:46:01 +00:00
Jordan Rose 574ef152fc [analyzer] Handle dynamic_casts that turn out to be upcasts.
This can occur with multiple inheritance, which jumps from one parent to
the other, and with virtual inheritance, since virtual base regions always
wrap the actual object and can't be nested within other base regions.

This also exposed some incorrect logic for multiple inheritance: even if B
is known not to derive from C, D might still derive from both of them.

llvm-svn: 161798
2012-08-13 22:11:42 +00:00
Jordan Rose 07a7ed80cb [analyzer] Don't strip CXXBaseObjectRegions when checking dynamic_casts.
...and /do/ strip CXXBaseObjectRegions when casting to a virtual base class.

This allows us to enforce the invariant that a CXXBaseObjectRegion can always
provide an offset for its base region if its base region has a known class
type, by only allowing virtual bases and direct non-virtual bases to form
CXXBaseObjectRegions.

This does mean some slight problems for our modeling of dynamic_cast, which
needs to be resolved by finding a path from the current region to the class
we're trying to cast to.

llvm-svn: 161797
2012-08-13 22:11:34 +00:00
Jordan Rose 02e5309b35 [analyzer] Strip CXXBaseObjectRegions when devirtualizing method calls.
This was causing a crash when we tried to re-apply a base object region to
itself. It probably also caused incorrect offset calculations in RegionStore.

PR13569 / <rdar://problem/12076683>

llvm-svn: 161710
2012-08-10 22:26:46 +00:00
Jordan Rose 51bcb226a2 [analyzer] Try to devirtualize even if the static callee has no definition.
This mostly affects pure virtual methods, but would also affect parent
methods defined inline in the header when analyzing the child's source file.

llvm-svn: 161709
2012-08-10 22:26:43 +00:00
Anna Zaks 75f49a9c07 [analyzer] Track if a region can be a subclass in the dynamic type info.
When object is allocated with alloc or init, we assume it cannot be a
subclass (currently used only for bifurcation purposes).

llvm-svn: 161682
2012-08-10 18:55:58 +00:00
Anna Zaks 920af014c1 [analyzer] Optimize dynamic dispatch bifurcation by detecting the cases
when we don't need to split.

In some cases we know that a method cannot have a different
implementation in a subclass:
 - the class is declared in the main file (private)
 - all the method declarations (including the ones coming from super
classes) are in the main file.

This can be improved further, but might be enough for the heuristic.
(When we are too aggressive splitting the state, efficiency suffers.
When we fail to split the state coverage might suffer.)

llvm-svn: 161681
2012-08-10 18:55:53 +00:00
Benjamin Kramer 3a913ed805 Fix a couple of pedantic gcc warnings.
llvm-svn: 161656
2012-08-10 10:06:13 +00:00
Jordan Rose 637ff0cc0f [analyzer] Merge RegionStore's KillStruct and CopyLazyBindings: BindAggregate.
Both methods need to clear out existing bindings and provide a new default
binding. Originally KillStruct always provided UnknownVal as the default,
but it's allowed symbolic values for quite some time (for handling returned
structs in C).

No functionality change.

llvm-svn: 161637
2012-08-09 22:55:54 +00:00
Jordan Rose a44a55a8f2 [analyzer] Cluster bindings in RegionStore by base region.
This should speed up activities that need to access bindings by cluster,
such as invalidation and dead-bindings cleaning. In some cases all we save
is the cost of building the region cluster map, but other times we can
actually avoid traversing the rest of the store.

In casual testing, this produced a speedup of nearly 10% analyzing SQLite,
with /less/ memory used.

llvm-svn: 161636
2012-08-09 22:55:51 +00:00
Jordan Rose c91e01bc11 [analyzer] Cache the "concrete offset base" for regions with symbolic offsets.
This makes it faster to access and invalidate bindings with symbolic offsets
by only computing this information once.

No intended functionality change.

llvm-svn: 161635
2012-08-09 22:55:37 +00:00
Jordan Rose 996d309fb7 [analyzer] A CXXBaseObjectRegion should correspond to a DIRECT base.
An ASTContext's RecordLayoutInfo can only be used to look up offsets of
direct base classes, and we need the offset to make non-symbolic bindings
in RegionStore. This change makes sure that we have one layer of
CXXBaseObjectRegion for each base we are casting through.

This was causing crashes on an internal buildbot.

llvm-svn: 161621
2012-08-09 21:24:02 +00:00
Anna Zaks a0105b2320 [analyzer] Rename the function to better reflect what it actually does.
llvm-svn: 161617
2012-08-09 21:02:45 +00:00
Anna Zaks 8d1f1f3b06 [analyzer] Clarify the values in Dyn. Dispatch Bifurcation map.
llvm-svn: 161616
2012-08-09 21:02:41 +00:00
Anna Zaks 85383182ec [analyzer] Improve readability of the dyn. dispatch bifurcation patch
r161552.

As per Jordan's feedback.

llvm-svn: 161603
2012-08-09 18:43:00 +00:00
Anna Zaks bc6d0ccf92 Unbreak the build.
Declaring "const Decl *Decl" is not a good idea.

llvm-svn: 161567
2012-08-09 02:57:02 +00:00
Anna Zaks 123af098b8 [analyzer] Bifurcate the path with dynamic dispatch.
This is an initial (unoptimized) version. We split the path when
inlining ObjC instance methods. On one branch we always assume that the
type information for the given memory region is precise. On the other we
assume that we don't have the exact type info. It is important to check
since the class could be subclassed and the method can be overridden. If
we always inline we can loose coverage.

Had to refactor some of the call eval functions.

llvm-svn: 161552
2012-08-09 00:21:33 +00:00
Jordan Rose d86b3bdb7a [analyzer] Clean up the printing of FieldRegions for leaks.
Unfortunately, generalized region printing is very difficult:
- ElementRegions are used both for casting and as actual elements.
- Accessing values through a pointer means going through an intermediate
  SymbolRegionValue; symbolic regions are untyped.
- Referring to implicitly-defined variables like 'this' and 'self' could be
  very confusing if they come from another stack frame.

We fall back to simply not printing the region name if we can't be sure it
will print well. This will allow us to improve in the future.

llvm-svn: 161512
2012-08-08 18:23:36 +00:00
Jordan Rose 356279ca2d [analyzer] Track malloc'd regions stored in structs.
The main blocker on this (besides the previous commit) was that
ScanReachableSymbols was not looking through LazyCompoundVals.
Once that was fixed, it's easy enough to clear out malloc data on return,
just like we do when we bind to a global region.

<rdar://problem/10872635>

llvm-svn: 161511
2012-08-08 18:23:31 +00:00
Jordan Rose 3a80cec5e9 [analyzer] Revamp RegionStore to distinguish regions with symbolic offsets.
RegionStore currently uses a (Region, Offset) pair to describe the locations
of memory bindings. However, this representation breaks down when we have
regions like 'array[index]', where 'index' is unknown. We used to store this
as (SubRegion, 0); now we mark them specially as (SubRegion, SYMBOLIC).

Furthermore, ProgramState::scanReachableSymbols depended on the existence of
a sub-region map, but RegionStore's implementation doesn't provide for such
a thing. Moving the store-traversing logic of scanReachableSymbols into the
StoreManager allows us to eliminate the notion of SubRegionMap altogether.

This fixes some particularly awkward broken test cases, now in
array-struct-region.c.

llvm-svn: 161510
2012-08-08 18:23:27 +00:00
Anna Zaks 75930b65b4 [analyzer] Address Jordan's review of DynamicTypePropagation.
llvm-svn: 161391
2012-08-07 05:12:24 +00:00
Anna Zaks 472dbcf156 [analyzer] Add a checker to manage dynamic type propagation.
Instead of sprinkling dynamic type info propagation throughout
ExprEngine, the added checker would add the more precise type
information on known APIs (Ex: ObjC alloc, new) and propagate
the type info in other cases (ex: ObjC init method, casts (the second is
not implemented yet)).

Add handling of ObjC alloc, new and init to the checker.

llvm-svn: 161357
2012-08-06 23:25:39 +00:00
Jordan Rose 17a8757a46 [analyzer] Update initializer assertion for delegating constructors.
Like base constructors, delegating constructors require no further
processing in the CFGInitializer node.

Also, add PrettyStackTraceLoc to the initializer and destructor logic
so we can get better stack traces in the future.

llvm-svn: 161283
2012-08-03 23:31:15 +00:00
Jordan Rose cfb4eb293f [analyzer] When a symbol is null, we should track its constraints.
Because of this, we would previously emit NO path notes when a parameter
is constrained to null (because there are no stores). Now we show where we
made the assumption, which is much more useful.

llvm-svn: 161280
2012-08-03 23:09:01 +00:00
Jordan Rose 3eb3cd45b8 [analyzer] Flatten path diagnostics for text output like we do for HTML.
llvm-svn: 161279
2012-08-03 23:08:54 +00:00
Jordan Rose 92e1449b55 [analyzer] Track null/uninitialized C++ objects used in method calls.
llvm-svn: 161278
2012-08-03 23:08:49 +00:00
Jordan Rose 80880ac7ee [analyzer] Provide useful PathDiagnosticLocations for CallEnter/Exit events.
llvm-svn: 161277
2012-08-03 23:08:44 +00:00
Jordan Rose adec516f4e [analyzer] FindLastStoreBRVisitor was not actually finding stores.
The visitor walks back through the ExplodedGraph as expected, but
it wasn't actually keeping track of when a value was assigned. This
meant that it only worked when the value was assigned when the variable
was defined.

Tests in the next commit (dependent on another change).

llvm-svn: 161276
2012-08-03 23:08:42 +00:00
Anna Zaks afc13b9ec5 [analyzer] Fixup: remove the extra whitespace
llvm-svn: 161265
2012-08-03 21:49:42 +00:00
Anna Zaks 150843b87e [analyzer] ObjC Inlining: Start tracking dynamic type info in the GDM
In the following code, find the type of the symbolic receiver by
following it and updating the dynamic type info in the state when we
cast the symbol from id to MyClass *.

  MyClass *a = [[self alloc] init];
  return 5/[a testSelf];

llvm-svn: 161264
2012-08-03 21:43:37 +00:00
Anna Zaks 4bd96c4469 [analyzer] Fix a typo. Thanks Jordan.
llvm-svn: 161249
2012-08-03 18:30:20 +00:00
Anna Zaks 4c03dfd4b1 [analyzer] Solve another source of non-determinism in the diagnostic
engine.

The code that was supposed to split the tie in a deterministic way is
not deterministic. Most likely one of the profile methods uses a
pointer. After this change we do finally get the consistent diagnostic
output. Testing this requires running the analyzer on large code bases
and diffing the results.

llvm-svn: 161224
2012-08-02 23:41:05 +00:00
Jordan Rose fa49c92b5c [analyzer] Also emit Prev/Next links for macros in HTML output. Oops.
llvm-svn: 161154
2012-08-02 02:43:42 +00:00
Jordan Rose 11790a4810 [analyzer] Add Prev/Next links to the HTML output.
llvm-svn: 161153
2012-08-02 02:26:19 +00:00
Anna Zaks 4c4fe84b25 [analyzer] Flush bug reports in deterministic order.
This makes the diagnostic output order deterministic. 
1) This makes order of text diagnostics consistent from run to run.

2) Also resulted in different bugs being reported (from one run to
another) with plist-html output.

llvm-svn: 161151
2012-08-02 00:41:43 +00:00
Jordan Rose 69bd4e803b [analyzer] Control C++ inlining with a macro in ExprEngineCallAndReturn.cpp.
For now this will stay on, but this way it's easy to switch off if we need
to pull back our support for a while.

llvm-svn: 161064
2012-07-31 18:22:40 +00:00
Jordan Rose a765bac7a1 [analyzer] Turn -cfg-add-initializers on by default, and remove the flag.
llvm-svn: 161060
2012-07-31 18:04:59 +00:00
Jordan Rose 6a97d92ef5 [analyzer] Don't try to inline if there's no region for a message receiver.
While usually we'd use a symbolic region rather than a straight-up Unknown,
we can still generate unknowns via array subscripts with symbolic indexes.
(And if this ever changes in the future, we still shouldn't crash.)

llvm-svn: 161059
2012-07-31 18:04:53 +00:00
Jordan Rose 1f8c0b4587 [analyzer] Add a FIXME about devirtualization in ctors/dtors.
llvm-svn: 161058
2012-07-31 18:04:49 +00:00
Jordan Rose e8a21b73ac [analyzer] Getting an lvalue for a reference field still requires a load.
This was causing a crash in our array-to-pointer logic, since the region
was clearly not an array.

PR13440 / <rdar://problem/11977113>

llvm-svn: 161051
2012-07-31 16:34:07 +00:00
Jordan Rose 42e8d6497d [analyzer] Let CallEvent decide what goes in an inital stack frame.
This removes explicit checks for 'this' and 'self' from
Store::enterStackFrame. It also removes getCXXThisRegion() as a virtual
method on all CallEvents; it's now only implemented in the parts of the
hierarchy where it is relevant. Finally, it removes the option to ask
for the ParmVarDecls attached to the definition of an inlined function,
saving a recomputation of the result of getRuntimeDefinition().

No visible functionality change!

llvm-svn: 161017
2012-07-31 01:07:55 +00:00
Anna Zaks 5808eb8029 [analyzer] Handle inlining of instance calls to super.
Use self-init.m for testing. (It used to have a bunch of failing tests
with dynamic inlining turned on.)

llvm-svn: 161012
2012-07-30 23:48:36 +00:00
Jordan Rose c2d249ce2c [analyzer] Perform post-call checks for all inlined calls.
Previously, we were only checking the origin expressions of inlined calls.
Checkers using the generic postCall and older postObjCMessage callbacks were
ignored. Now that we have CallEventManager, it is much easier to create
a CallEvent generically when exiting an inlined function, which we can then
use for post-call checks.

No test case because we don't (yet) have any checkers that depend on this
behavior (which is why it hadn't been fixed before now).

llvm-svn: 161005
2012-07-30 23:39:47 +00:00
Anna Zaks 63282aefb9 [analyzer] Very simple ObjC instance method inlining
- Retrieves the type of the object/receiver from the state.
- Binds self during stack setup.
- Only explores the path on which the method is inlined (no
bifurcation to explore the path on which the method is not inlined).

llvm-svn: 160991
2012-07-30 20:31:29 +00:00
Anna Zaks e49190984c [analyzer] Add -analyzer-ipa=dynamic option for inlining dynamically
dispatched methods.

Disabled by default for now.

llvm-svn: 160988
2012-07-30 20:31:18 +00:00
Jordan Rose fcd016e57e [analyzer] Only allow CallEvents to be created by CallEventManager.
This ensures that it is valid to reference-count any CallEvents, and we
won't accidentally try to reclaim a CallEvent that lives on the stack.
It also hides an ugly switch statement for handling CallExprs!

There should be no functionality change here.

llvm-svn: 160986
2012-07-30 20:22:09 +00:00
Jordan Rose d457ca92ce [analyzer] Introduce a CallEventManager to keep a pool of CallEvents.
This allows us to get around the C++ "virtual constructor" problem
when we'd like to create a CallEvent from an ExplodedNode, an inlined
StackFrameContext, or another CallEvent. The solution has three parts:

- CallEventManager uses a BumpPtrAllocator to allocate CallEvent-sized
  memory blocks. It also keeps a cache of freed CallEvents for reuse.
- CallEvents all have protected copy constructors, along with cloneTo()
  methods that use placement new to copy into CallEventManager-managed
  memory, vtables intact.
- CallEvents owned by CallEventManager are now wrapped in an
  IntrusiveRefCntPtr. Going forwards, it's probably a good idea to create
  ALL CallEvents through the CallEventManager, so that we don't accidentally
  try to reclaim a stack-allocated CallEvent.

All of this machinery is currently unused but will be put into use shortly.

llvm-svn: 160983
2012-07-30 20:21:55 +00:00
NAKAMURA Takumi 836926dbdf clang/lib: [CMake] Update tblgen'd dependencies.
llvm-svn: 160851
2012-07-27 06:18:33 +00:00