Commit Graph

1155 Commits

Author SHA1 Message Date
Anna Zaks 05253782a4 [analyzer] Dynamic type info - propagate through implicit casts.
I currently have a bit of redundancy with the cast kind switch statement
inside the ImplicitCast callback, but I might be adding more casts going
forward.

llvm-svn: 161358
2012-08-06 23:25:45 +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 1c715609df [analyzer] Ignore OS X 10.8's annotations for NSMakeCollectable.
The frameworks correctly use the 'cf_consumed' and 'ns_returns_retained'
attributes for NSMakeCollectable, but we can model the behavior under
garbage collection more precisely than that.

No functionality change.

llvm-svn: 161349
2012-08-06 21:28:02 +00:00
Anna Zaks 6ce686e6a4 [analyzer] Malloc: remove assert since is not valid as of r161248
We can be in the situation where we did not track the symbol before
realloc was called on it.

llvm-svn: 161294
2012-08-04 02:04:27 +00:00
Jordan Rose a01741fce4 [analyzer] Use a more robust check for null in CallAndMessageChecker.
This should fix the failing test on the buildbot as well.

llvm-svn: 161290
2012-08-04 01:04:52 +00:00
Jordan Rose 4aa80e156d [analyzer] Don't assume values bound to references are automatically non-null.
While there is no such thing as a "null reference" in the C++ standard,
many implementations of references (including Clang's) do not actually
check that the location bound to them is non-null. Thus unlike a regular
null dereference, this will not cause a problem at runtime until the
reference is actually used. In order to catch these cases, we need to not
prune out paths on which the input pointer is null.

llvm-svn: 161288
2012-08-04 00:25:30 +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 52242a6677 [analyzer] Malloc: track non-allocated but freed memory
There is no reason why we should not track the memory which was not
allocated in the current function, but was freed there. This would
allow to catch more use-after-free and double free with no/limited IPA.

Also fix a realloc issue which surfaced as the result of this patch.

llvm-svn: 161248
2012-08-03 18:30:18 +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 9a2eec3826 [analyzer] Add a simple check for initializing reference variables with null.
There's still more work to be done here; this doesn't catch reference
parameters or return values. But it's a step in the right direction.

Part of <rdar://problem/11212286>.

llvm-svn: 161214
2012-08-02 21:33:42 +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
Jordan Rose 41c98d9dc3 [analyzer] Look through SubstNonTypeTemplateParmExprs.
We were treating this like a CXXDefaultArgExpr, but
SubstNonTypeTemplateParmExpr actually appears when a template is
instantiated, i.e. we have all the information necessary to evaluate it.
This allows us to inline functions like llvm::array_lengthof.

<rdar://problem/11949235>

llvm-svn: 160846
2012-07-27 01:15:02 +00:00
Jordan Rose de76c92b15 [analyzer] Use a stack-based local AGAIN to fix the build for real.
It's a good thing CallEvents aren't created all over the place yet.
I checked all the uses this time and the private copy constructor
/really/ shouldn't cause any more problems.

llvm-svn: 160845
2012-07-27 00:47:52 +00:00
Jordan Rose 7aab2295be [analyzer] Use a stack-based local instead of a temporary to fix build.
Passing a temporary via reference parameter still requires a visible
copy constructor.

llvm-svn: 160840
2012-07-26 23:24:15 +00:00
Ted Kremenek 313c2ff375 Look at the preceding CFGBlock for the expression to load from in ExprEngine::VisitGuardedExpr
instead of walking to the preceding PostStmt node.  There are cases where the last evaluated
expression does not appear in the ExplodedGraph.

Fixes PR 13466.

llvm-svn: 160819
2012-07-26 22:23:41 +00:00
Jordan Rose 72ce8e2d42 [analyzer] CallEvent is no longer a value object.
After discussion, the type-based dispatch was decided to be bad for
maintenance and made it very easy for subtle bugs to creep in. Instead,
we'll just be very careful when we do have to allocate these on the heap.

llvm-svn: 160817
2012-07-26 21:41:15 +00:00
Jordan Rose 4f7df9be69 [analyzer] Rename Calls.{h,cpp} to CallEvent.{h,cpp}. No functionality change.
llvm-svn: 160815
2012-07-26 21:39:41 +00:00
Jordan Rose 25bc20f846 [analyzer] Don't crash on implicit statements inside initializers.
Our BugReporter knows how to deal with implicit statements: it looks in
the ParentMap until it finds a parent with a valid location. However, since
initializers are not in the body of a constructor, their sub-expressions are
not in the ParentMap. That was easy enough to fix in AnalysisDeclContext.

...and then even once THAT was fixed, there's still an extra funny case
of Objective-C object pointer fields under ARC, which are initialized with
a top-level ImplicitValueInitExpr. To catch these cases,
PathDiagnosticLocation will now fall back to the start of the current
function if it can't find any other valid SourceLocations. This isn't great,
but it's miles better than a crash.

(All of this is only relevant when constructors and destructors are being
inlined, i.e. under -cfg-add-initializers and -cfg-add-implicit-dtors.)

llvm-svn: 160810
2012-07-26 20:04:30 +00:00
Jordan Rose 20edae8749 [analyzer] Don't crash on array constructors and destructors.
This workaround is fairly lame: we simulate the first element's constructor
and destructor and rely on the region invalidation to "initialize" the rest
of the elements.

llvm-svn: 160809
2012-07-26 20:04:25 +00:00
Jordan Rose 54529a347e [analyzer] Handle C++ member initializers and destructors.
This uses CFG to tell if a constructor call is for a member, and uses
the member's region appropriately.

llvm-svn: 160808
2012-07-26 20:04:21 +00:00
Jordan Rose 05375eb4ec [analyzer] Use the CFG to see if a constructor is for a local variable.
Previously we were using ParentMap and crawling through the parent DeclStmt.
This should be at least slightly cheaper (and is also more flexible).

No (intended) functionality change.

llvm-svn: 160807
2012-07-26 20:04:16 +00:00
Jordan Rose b970505d0d [analyzer] Handle base class initializers and destructors.
Most of the logic here is fairly simple; the interesting thing is that
we now distinguish complete constructors from base or delegate constructors.
We also make sure to cast to the base class before evaluating a constructor
or destructor, since non-virtual base classes may behave differently.

This includes some refactoring of VisitCXXConstructExpr and VisitCXXDestructor
in order to keep ExprEngine.cpp as clean as possible (leaving the details for
ExprEngineCXX.cpp).

llvm-svn: 160806
2012-07-26 20:04:13 +00:00
Jordan Rose a4c0d21f42 [analyzer] Show paths for destructor calls.
This modifies BugReporter and friends to handle CallEnter and CallExitEnd
program points that came from implicit call CFG nodes (read: destructors).

This required some extra handling for nested implicit calls. For example,
the added multiple-inheritance test case has a call graph that looks like this:

testMultipleInheritance3
  ~MultipleInheritance
    ~SmartPointer
    ~Subclass
      ~SmartPointer
        ***bug here***

In this case we correctly notice that we started in an inlined function
when we reach the CallEnter program point for the second ~SmartPointer.
However, when we reach the next CallEnter (for ~Subclass), we were
accidentally re-using the inner ~SmartPointer call in the diagnostics.

Rather than guess if we saw the corresponding CallExitEnd based on the
contents of the active path, we now just ask the PathDiagnostic if there's
any known stack before popping off the top path.

(A similar issue could have occured without multiple inheritance, but there
wasn't a test case for it.)

llvm-svn: 160804
2012-07-26 20:04:05 +00:00
Jordan Rose c5d852447b [analyzer] Inline ctors + dtors when the CFG is built for them.
At the very least this means initializer nodes for constructors and
automatic object destructors are present in the CFG.

llvm-svn: 160803
2012-07-26 20:04:00 +00:00
Jordan Rose 443ec10e2d [analyzer] PostImplicitCall can also occur between CFGElements.
This avoids an assertion crash when we invalidate on a destructor call
instead of inlining it.

llvm-svn: 160802
2012-07-26 20:03:56 +00:00
Anna Zaks 83f1495fcb [analyzer] Inline ObjC class methods.
- Some cleanup(the TODOs) will be done after ObjC method inlining is
complete.
- Simplified CallEvent::getDefinition not to require ISDynamicDispatch
parameter.
- Also addressed Jordan's comments from r160530.

llvm-svn: 160768
2012-07-26 00:27:51 +00:00
Ted Kremenek faef9cb694 Add static analyzer check for calling a C++ instance method with a null/uninitialized pointer.
llvm-svn: 160767
2012-07-26 00:22:32 +00:00