This checker is annotation driven. It checks that the annotated
invalidation method accesses all ivars of the enclosing objects that are
objects of type, which in turn contains an invalidation method.
This is driven by
__attribute((annotation("objc_instance_variable_invalidator")).
llvm-svn: 164716
There are very few tests here because SValBuilder is fairly aggressive
about not building SymExprs that we can't evaluate, which saves memory
and CPU but also makes it very much tied to the current constraint
manager. We should probably scale back here and let things decay to
UnknownVal later on.
bitwise-ops.c tests that for the SymExprs we do create, we persist our
assumptions about them. traversal-path-unification.c tests that we do
clean out constraints on arbitrary SymExprs once they have actually died.
llvm-svn: 164623
Previously, we'd just keep constraints around forever, which means we'd
never be able to merge paths that differed only in constraints on dead
symbols.
Because we now allow constraints on symbolic expressions, not just single
symbols, this requires changing SymExpr::symbol_iterator to include
intermediate symbol nodes in its traversal, not just the SymbolData leaf
nodes.
This depends on the previous commit to be correct. Originally applied in
r163444, reverted in r164275, now being re-applied.
llvm-svn: 164622
This is a heuristic intended to greatly reduce the number of false
positives resulting from inlining, particularly inlining of generic,
defensive C++ methods that live in header files. The suppression is
triggered in the cases where we ask to track where a null pointer came
from, and it turns out that the source of the null pointer was an inlined
function call.
This change brings the number of bug reports in LLVM from ~1500 down to
around ~300, a much more manageable number. Yes, some true positives may
be hidden as well, but from what I looked at the vast majority of silenced
reports are false positives, and many of the true issues found by the
analyzer are still reported.
I'm hoping to improve this heuristic further by adding some exceptions
next week (cases in which a bug should still be reported).
llvm-svn: 164449
Rather than saying "Null pointer value stored to 'foo'", we now say
"Passing null pointer value via Nth parameter 'foo'", which is much better.
The note is also now on the argument expression as well, rather than the
entire call.
This paves the way for continuing to track arguments back to their sources.
<rdar://problem/12211490>
llvm-svn: 164444
Like with struct fields, we want to catch cases like this early,
so that we can produce better diagnostics and path notes:
PointObj *p = nil;
int *px = &p->_x; // should warn here
*px = 1;
llvm-svn: 164442
We want to catch cases like this early, so that we can produce better
diagnostics and path notes:
Point *p = 0;
int *px = &p->x; // should warn here
*px = 1;
llvm-svn: 164441
their implementations are unavailable. Start by simulating dispatch_sync().
This change is largely a bunch of plumbing around something very simple. We
use AnalysisDeclContext to conjure up a fake function body (using the
current ASTContext) when one does not exist. This is controlled
under the analyzer-config option "faux-bodies", which is off by default.
The plumbing in this patch is largely to pass the necessary machinery
around. CallEvent needs the AnalysisDeclContextManager to get
the function definition, as one may get conjured up lazily.
BugReporter and PathDiagnosticLocation needed to be relaxed to handle
invalid locations, as the conjured body has no real source locations.
We do some primitive recovery in diagnostic generation to generate
some reasonable locations (for arrows and events), but it can be
improved.
llvm-svn: 164339
- Inputs/system-header-simulator.h: Declare strlen() with size_t.
- malloc-interprocedural.c: Move the definition of size_t into the header above.
Then XFAIL can be pruned.
llvm-svn: 164300
If someone provides their own function called 'strdup', or 'reallocf', or
even 'malloc', and we inlined it, the inlining should have given us all the
malloc-related information we need. If we then try to attach new information
to the return value, we could end up with spurious warnings.
<rdar://problem/12317671>
llvm-svn: 164276
While we definitely want this optimization in the future, we're not
currently handling constraints on symbolic /expressions/ correctly.
These should stay live even if the SymExpr itself is no longer referenced
because could recreate an identical SymExpr later. Only once the SymExpr
can no longer be recreated -- i.e. a component symbol is dead -- can we
safely remove the constraints on it.
This liveness issue is tracked by <rdar://problem/12333297>.
This reverts r163444 / 24c7f98828e039005cff3bd847e7ab404a6a09f8.
llvm-svn: 164275
in ObjCMethods.
Extend FunctionTextRegion to represent ObjC methods as well as
functions. Note, it is not clear what type ObjCMethod region should
return. Since the type of the FunctionText region is not currently used,
defer solving this issue.
llvm-svn: 164046
crazy case where dispatch_once gets redefined as a macro that calls
_dispatch_once (which calls the real dispatch_once). Users want to
see the warning in their own code.
Fixes <rdar://problem/11617767>
llvm-svn: 163816
Using the static type may be inconsistent with later calls. We should just
report that there is no inlining definition available if the static type is
better than the dynamic type. See next commit.
This reverts r163644 / 19d5886d1704e24282c86217b09d5c6d35ba604d.
llvm-svn: 163744
'Inputs' subdirectory.
The general desire has been to have essentially all of the non-test
input files live in such directories, with some exceptions for obvious
and common patterns like 'foo.c' using 'foo.h'.
This came up because our distributed test runner couldn't find some of
the headers, for example with stl.cpp.
No functionality changed, just shuffling around here.
llvm-svn: 163674
reinterpret_cast does not provide any of the usual type information that
static_cast or dynamic_cast provide -- only the new type. This can get us
in a situation where the dynamic type info for an object is actually a
superclass of the static type, which does not match what CodeGen does at all.
In these cases, just fall back to the static type as the best possible type
for devirtualization.
Should fix the crashes on our internal buildbot.
llvm-svn: 163644
C++11 [expr.call]p1: ...If the selected function is non-virtual, or if the
id-expression in the class member access expression is a qualified-id,
that function is called. Otherwise, its final overrider in the dynamic type
of the object expression is called.
<rdar://problem/12255556>
llvm-svn: 163577
The option allows to always inline very small functions, whose size (in
number of basic blocks) is set using -analyzer-config
ipa-always-inline-size option.
llvm-svn: 163558
This is a (heavy-handed) solution to PR13724 -- until we know we can do
a good job inlining the STL, it's best to be consistent and not generate
more false positives than we did before. We can selectively whitelist
certain parts of the 'std' namespace that are known to be safe.
This is controlled by analyzer config option 'c++-stdlib-inlining', which
can be set to "true" or "false".
This commit also adds control for whether or not to inline any templated
functions (member or non-member), under the config option
'c++-template-inlining'. This option is currently on by default.
llvm-svn: 163548
I need to see how this breaks on other platforms when I fix the issue
that Benjamin Kramer pointed out.
This includes r163489 and r163490, plus a two line change.
llvm-svn: 163512
r163489, "Take another crack at stabilizing the emission order of analyzer"
r163490, "Use isBeforeInTranslationUnitThan() instead of operator<."
llvm-svn: 163497
diagnostics without using FoldingSetNodeIDs. This is done
by doing a complete recursive comparison of the PathDiagnostics.
Note that the previous method of comparing FoldingSetNodeIDs did
not end up relying on unstable things such as pointer addresses, so
I suspect this may still have some issues on various buildbots because
I'm not sure if the true source of non-determinism has been eliminated.
The tests pass for me, so the only way to know is to commit this change
and see what happens.
llvm-svn: 163489
ObjCSelfInitChecker stashes information in the GDM to persist it across
function calls; it is stored in pre-call checks and retrieved post-call.
The post-call check is supposed to clear out the stored state, but was
failing to do so in cases where the call did not have a symbolic return
value.
This was actually causing the inappropriate cache-out from r163361.
Per discussion with Anna, we should never actually cache out when
assuming the receiver of an Objective-C message is non-nil, because
we guarded that node generation by checking that the state has changed.
Therefore, the only states that could reach this exact ExplodedNode are
ones that should have merged /before/ making this assumption.
r163361 has been reverted and the test case removed, since it won't
actually test anything interesting now.
llvm-svn: 163449
Previously, we'd just keep constraints around forever, which means we'd
never be able to merge paths that differed only in constraints on dead
symbols.
Because we now allow constraints on symbolic expressions, not just single
symbols, this requires changing SymExpr::symbol_iterator to include
intermediate symbol nodes in its traversal, not just the SymbolData leaf
nodes.
llvm-svn: 163444
This is necessary because further analysis will assume that the SVal's
type matches the AST type. This caused a crash when trying to perform
a derived-to-base cast on a C++ object that had been new'd to be another
object type.
Yet another crash in PR13763.
llvm-svn: 163442
While the check itself should count 0-based for the parameter index,
the diagnostic should be 1-based (first, second, third, not start at 0).
Fixes <rdar://problem/12249569>.
llvm-svn: 163375
of the analyzer, as the RetainReleaseChecker has many fine-grain
path diagnostic events that were not being checked. This uncovered
an inconsistency between the path diagnostics between Objective-C
and Objective-C++ code in ConditionBRVisitor that was fixed in a recent
patch.
llvm-svn: 163373
implicit pointer-to-boolean conversions in condition expressions. This would
result in inconsistent diagnostic emission between C and C++.
A consequence of this is now ConditionBRVisitor and TrackConstraintBRVisitor may
emit redundant diagnostics, for example:
"Assuming pointer value is null" (TrackConstraintBRVisitor)
"Assuming 'p' is null" (ConditionBRVisitor)
We need to reconcile the two, and perhaps prefer one over the other in some
cases.
llvm-svn: 163372
With some particularly evil casts, we can get an object whose dynamic type
is not actually a subclass of its static type. In this case, we won't even
find the statically-resolved method as a devirtualization candidate.
Rather than assert that this situation cannot occur, we now simply check
that the dynamic type is not an ancestor or descendent of the static type,
and leave it at that.
This error actually occurred analyzing LLVM: CallEventManager uses a
BumpPtrAllocator to allocate a concrete subclass of CallEvent
(FunctionCall), but then casts it to the actual subclass requested
(such as ObjCMethodCall) to perform the constructor.
Yet another crash in PR13763.
llvm-svn: 163367
A bizarre series of coincidences led us to generate a previously-seen
node in the middle of processing an Objective-C message, where we assume
the receiver is non-nil. We were assuming that such an assumption would
never "cache out" like this, and blithely went on using a null ExplodedNode
as the predecessor for the next step in evaluation.
Although the test case committed here is complicated, this could in theory
happen in other ways as well, so the correct fix is just to test if the
non-nil assumption results in an ExplodedNode we've seen before.
<rdar://problem/12243648>
llvm-svn: 163361
are used in EH code. Right now the CFG doesn't support exceptions well,
so we need this hack to avoid bogus dead store warnings.
Fixes <rdar://problem/12147586>
llvm-svn: 163353
CXXDestructorCall now has a flag for when it is a base destructor call.
Other kinds of destructor calls (locals, fields, temporaries, and 'delete')
all behave as "whole-object" destructors and do not behave differently
from one another (specifically, in these cases we /should/ try to
devirtualize a call to a virtual destructor).
This was causing crashes in both our internal buildbot, the crash still
being tracked in PR13765, and some of the crashes being tracked in PR13763,
due to a assertion failure. (The behavior under -Asserts happened to be
correct anyway.)
Adding this knowledge also allows our DynamicTypePropagation checker to do
a bit less work; the special rules about virtual method calls during a
destructor only require extra handling during base destructors.
llvm-svn: 163348
While destructors will continue to not be inlined (unless the analyzer
config option 'c++-inlining' is set to 'destructors'), leaving them out
of the CFG is an incomplete model of the behavior of an object, and
can cause false positive warnings (like PR13751, now working).
Destructors for temporaries are still not on by default, since
(a) we haven't actually checked this code to be sure it's fully correct
(in particular, we probably need to be very careful with regard to
lifetime-extension when a temporary is bound to a reference,
C++11 [class.temporary]p5), and
(b) ExprEngine doesn't actually do anything when it sees a temporary
destructor in the CFG -- not even invalidate the object region.
To enable temporary destructors, set the 'cfg-temporary-dtors' analyzer
config option to '1'. The old -cfg-add-implicit-dtors cc1 option, which
controlled all implicit destructors, has been removed.
llvm-svn: 163264
If a region is binded to a symbolic value, we should track the symbol.
(The code I changed was not previously exercised by the regression
tests.)
llvm-svn: 163261
The problem is that the value of 'this' in a C++ member function call
should always be a region (or NULL). However, if the object is an rvalue,
it has no associated region (only a conjured symbol or LazyCompoundVal).
For now, we handle this in two ways:
1) Actually respect MaterializeTemporaryExpr. Before, it was relying on
CXXConstructExpr to create temporary regions for all struct values.
Now it just does the right thing: if the value is not in a temporary
region, create one.
2) Have CallEvent recognize the case where its 'this' pointer is a
non-region, and just return UnknownVal to keep from confusing clients.
The long-term problem is being tracked internally in <rdar://problem/12137950>,
but this makes many test cases pass.
llvm-svn: 163220
This turned out to have many implications, but what eventually seemed to
make it unworkable was the fact that we can get struct values (as
LazyCompoundVals) from other places besides return-by-value function calls;
that is, we weren't actually able to "treat all struct values as regions"
consistently across the entire analyzer core.
Hopefully we'll be able to come up with an alternate solution soon.
This reverts r163066 / 02df4f0aef142f00d4637cd851e54da2a123ca8e.
llvm-svn: 163218
SimpleSValBuilder processes a couple trivial identities, including 'x - x'
and 'x ^ x' (both 0). However, the former could appear with arguments of
floating-point type, and we weren't checking for that. This started
triggering an assert with r163069, which checks that a constant value is
actually going to be used as an integer or pointer.
llvm-svn: 163159
This allows us to correctly symbolicate the fields of structs returned by
value, as well as get the proper 'this' value for when methods are called
on structs returned by value.
This does require a moderately ugly hack in the StoreManager: if we assign
a "struct value" to a struct region, that now appears as a Loc value being
bound to a region of struct type. We handle this by simply "dereferencing"
the struct value region, which should create a LazyCompoundVal.
This should fix recent crashes analyzing LLVM and on our internal buildbot.
<rdar://problem/12137950>
llvm-svn: 163066
Previously, we preferred to get a result type by looking at the callee's
declared result type. This allowed us to handlereferences, which are
represented in the AST as lvalues of their pointee type. (That is, a call
to a function returning 'int &' has type 'int' and value kind 'lvalue'.)
However, this results in us preferring the original type of a function
over a casted type. This is a problem when a function pointer is casted
to another type, because the conjured result value will have the wrong
type. AdjustedReturnValueChecker is supposed to handle this, but still
doesn't handle the case where there is no "original function" at all,
i.e. where the callee is unknown.
Now, we instead look at the call expression's value kind (lvalue, xvalue,
or prvalue), and adjust the expr's type accordingly. This will have no
effect when the function is inlined, and will conjure the value that will
actually be used when it is not.
This makes AdjustedReturnValueChecker /nearly/ unnecessary; unfortunately,
the cases where it would still be useful are where we need to cast the
result of an inlined function or a checker-evaluated function, and in these
cases we don't know what we're casting /from/ by the time we can do post-
call checks. In light of that, remove AdjustedReturnValueChecker, which
was already not checking quite a few calls.
llvm-svn: 163065
Fixes a hard-to-reach crash when calling a non-member overloaded operator
with arguments that may be callbacks.
Future-proofing: don't make the same assumption in MallocSizeofChecker.
Aside from possibly respecting attributes in the future, it might be
possible to call 'malloc' through a function pointer.
I audited all other uses of FunctionDecl::getIdentifier() in the analyzer;
they all now correctly test to see if the identifier is present before
using it.
llvm-svn: 163012
More generally, this adds a new configuration option 'c++-inlining', which
controls which C++ member functions can be considered for inlining. This
uses the new -analyzer-config table, so the cc1 arguments will look like this:
... -analyzer-config c++-inlining=[none|methods|constructors|destructors]
Note that each mode implies that all the previous member function kinds
will be inlined as well; it doesn't make sense to inline destructors
without inlining constructors, for example.
The default mode is 'methods'.
llvm-svn: 163004
PathDiagnostics are actually profiled and uniqued independently of the
path on which the bug occurred. This is used to merge diagnostics that
refer to the same issue along different paths, as well as by the plist
diagnostics to reference files created by the HTML diagnostics.
However, there are two problems with the current implementation:
1) The bug description is included in the profile, but some
PathDiagnosticConsumers prefer abbreviated descriptions and some
prefer verbose descriptions. Fixed by including both descriptions in
the PathDiagnostic objects and always using the verbose one in the profile.
2) The "minimal" path generation scheme provides extra information about
which events came from macros that the "extensive" scheme does not.
This resulted not only in different locations for the plist and HTML
diagnostics, but also in diagnostics being uniqued in the plist output
but not in the HTML output. Fixed by storing the "end path" location
explicitly in the PathDiagnostic object, rather than trying to find the
last piece of the path when the diagnostic is requested.
This should hopefully finish unsticking our internal buildbot.
llvm-svn: 162965
inlined function.
This resolves retain count checker false positives that are caused by
inlining ObjC and other methods. Essentially, if we are passing an
object to a method with "delegate" in the selector or a function pointer
as another argument, we should stop tracking the other parameters/return
value as far as the retain count checker is concerned.
llvm-svn: 162876
This heuristic addresses the case when a pointer (or ref) is passed
to a function, which initializes the variable (or sets it to something
other than '0'). On the branch where the inlined function does not
set the value, we report use of undefined value (or NULL pointer
dereference). The access happens in the caller and the path
through the callee would get pruned away with regular path pruning. To
solve this issue, we previously disabled diagnostic pruning completely
on undefined and null pointer dereference checks, which entailed very
verbose diagnostics in most cases. Furthermore, not all of the
undef value checks had the diagnostic pruning disabled.
This patch implements the following heuristic: if we pass a pointer (or
ref) to the region (on which the error is reported) into a function and
it's value is either undef or 'NULL' (and is a pointer), do not prune
the function.
llvm-svn: 162863
In C++, objects being returned on the stack are actually copy-constructed into
the return value. That means that when a temporary is returned, it still has
to be destroyed, i.e. the returned expression will be wrapped in an
ExprWithCleanups node. Our "returning stack memory" checker needs to look
through this node to see if we really are returning an object by value.
PR13722
llvm-svn: 162817
Specifically, CallEventManager::getCaller was looking at the call site for
an inlined call and trying to see what kind of call it was, but it only
checked for CXXConstructExprClass. (It's not using an isa<> here to avoid
doing three more checks on the the statement class.)
This caused an unreachable when we actually did inline the constructor of a
temporary object.
PR13717
llvm-svn: 162792
When exiting a function, the analyzer looks for the last statement in the
function to see if it's a return statement (and thus bind the return value).
However, the search for "the last statement" was accepting statements that
were in implicitly-generated inlined functions (i.e. destructors). So we'd
go and get the statement from the destructor, and then say "oh look, this
function had no explicit return...guess there's no return value". And /that/
led to the value being returned being declared dead, and all our leak
checkers complaining.
llvm-svn: 162791
Previously, if we were tracking stores to a variable 'x', and came across this:
x = foo();
...we would simply emit a note here and stop. Now, we'll step into 'foo' and
continue tracking the returned value from there.
<rdar://problem/12114689>
llvm-svn: 162718
Because the CXXNewExpr appears after the CXXConstructExpr in the CFG, we don't
actually have the correct region to construct into at the time we decide
whether or not to inline. The long-term fix (discussed in PR12014) might be to
introduce a new CFG node (CFGAllocator) that appears before the constructor.
Tracking the short-term fix in <rdar://problem/12180598>.
llvm-svn: 162689
This allows us to better reason about status objects, like Clang's own
llvm::Optional (when its contents are trivially destructible), which are
often intended to be passed around by value.
We still don't inline constructors for temporaries in the general case.
<rdar://problem/11986434>
llvm-svn: 162681
This allows checkers (like the MallocChecker) to process the effects of the
bind. Previously, using a memory-allocating function (like strdup()) in an
initializer would result in a leak warning.
This does bend the expectations of checkBind a bit; since there is no
assignment expression, the statement being used is the initializer value.
In most cases this shouldn't matter because we'll use a PostInitializer
program point (rather than PostStmt) for any checker-generated nodes, though
we /will/ generate a PostStore node referencing the internal statement.
(In theory this could have funny effects if someone actually does an
assignment within an initializer; in practice, that seems like it would be
very rare.)
<rdar://problem/12171711>
llvm-svn: 162637
More generally, any time we try to track where a null value came from, we
should show if it came from a function. This usually isn't necessary if
the value is symbolic, but if the value is just a constant we previously
just ignored its origin entirely. Now, we'll step into the function and
recursively add a visitor to the returned expression.
<rdar://problem/12114609>
llvm-svn: 162563
With inlining, retain count checker starts tracking 'self' through the
init methods. The analyser results were too noisy if the developer
did not follow 'self = [super init]' pattern (which is common
especially in older code bases) - we reported self init anti-pattern AND
possible use-after-free. This patch teaches the retain count
checker to assume that [super init] does not fail when it's not consumed
by another expression. This silences the retain count warning that warns
about possibility of use-after-free when init fails, while preserving
all the other checking on 'self'.
llvm-svn: 162508
Until we have full support for pointers-to-members, we can at least
approximate some of their use by tracking null and non-null values.
We thus treat &A::m_ptr as a non-null void * symbol, and MemberPointer(0)
as a pointer-sized null constant.
This enables support for what is sometimes called the "safe bool" idiom,
demonstrated in the test case.
llvm-svn: 162495
This is trivial; the UserDefinedConversion always wraps a CXXMemberCallExpr
for the appropriate conversion function, so it's just a matter of
propagating that value to the CastExpr itself.
llvm-svn: 162494
A CXXDefaultArgExpr wraps an Expr owned by a ParmVarDecl belonging to the
called function. In general, ExprEngine and Environment ought to treat this
like a ParenExpr or other transparent wrapper expression, with the inside
expression evaluated first.
However, if we call the same function twice, we'd produce a CFG that contains
the same wrapped expression twice, and we're not set up to handle that. I've
added a FIXME to the CFG builder to come back to that, but meanwhile we can
at least handle expressions that don't need to be explicitly evaluated:
literals. This probably handles many common uses of default parameters:
true/false, null, etc.
Part of PR13385 / <rdar://problem/12156507>
llvm-svn: 162453
The checker adds assumptions that the return values from the known APIs
are non-nil. Teach the checker about NSArray/NSMutableArray/NSOrderedSet
objectAtIndex, objectAtIndexedSubscript.
llvm-svn: 162398
As part of this change, I discovered that a few of our tests were not testing
the RangeConstraintManager. Luckily all of those passed when I moved them
over to use that constraint manager.
llvm-svn: 162384
The actual change here is a little more complicated than the summary above.
What we want to do is have our generic inlining tests run under whatever
mode is the default. However, there are some tests that depend on the
presence of C++ inlining, which still has some rough edges. These tests have
been explicitly marked as -analyzer-ipa=inlining in preparation for a new
mode that limits inlining to C functions and blocks. This will be the
default until the false positives for C++ have been brought down to
manageable levels.
llvm-svn: 162317
This reduces duplication across the Basic and Range constraint managers, and
keeps their internals free of dealing with the semantics of C++. It's still
a little unfortunate that the constraint manager is dealing with this at all,
but this is pretty much the only place to put it so that it will apply to all
symbolic values, even when embedded in larger expressions.
llvm-svn: 162313
By doing this in the constraint managers, we can ensure that ANY reference
whose value we don't know gets the effect, even if it's not a top-level
parameter.
llvm-svn: 162246
Under GC, a release message is ignored, so "release and stop tracking" just
becomes "stop tracking". But CFRelease is still honored. This is the main
difference between ns_consumed and cf_consumed.
llvm-svn: 162234
This is used to handle functions and methods that consume an argument
(annotated with the ns_consumed or cf_consumed attribute), but then the
argument's retain count may be further modified in a callback. We want
to warn about over-releasing, but we can't really track the object afterwards.
llvm-svn: 162221
Forgetting to at least cast the result was giving us Loc/NonLoc problems
in SValBuilder (hitting an assertion). But the standard (both C and C++)
does actually guarantee that && and || will result in the actual values
1 and 0, typed as 'int' in C and 'bool' in C++, and we can easily model that.
PR13461
llvm-svn: 162209
Our current handling of 'throw' is all CFG-based: it jumps to a 'catch' block
if there is one and the function exit block if not. But this doesn't really
get the right behavior when a function is inlined: execution will continue on
the caller's side, which is always the wrong thing to do.
Even within a single function, 'throw' completely skips any destructors that
are to be run. This is essentially the same problem as @finally -- a CFGBlock
that can have multiple entry points, whose exit points depend on whether it
was entered normally or exceptionally.
Representing 'throw' as a sink matches our current (non-)handling of @throw.
It's not a perfect solution, but it's better than continuing analysis in an
inconsistent or even impossible state.
<rdar://problem/12113713>
llvm-svn: 162157
The CFG approximates @throw as a return statement, but that's not good
enough in inlined functions. Moreover, since Objective-C exceptions are
usually considered fatal, we should be suppressing leak warnings like we
do for calls to noreturn functions (like abort()).
The comments indicate that we were probably intending to do this all along;
it may have been inadvertantly changed during a refactor at one point.
llvm-svn: 162156
This fixes several issues:
- removes egregious hack where PlistDiagnosticConsumer would forward to HTMLDiagnosticConsumer,
but diagnostics wouldn't be generated consistently in the same way if PlistDiagnosticConsumer
was used by itself.
- emitting diagnostics to the terminal (using clang's diagnostic machinery) is no longer a special
case, just another PathDiagnosticConsumer. This also magically resolved some duplicate warnings,
as we now use PathDiagnosticConsumer's diagnostic pruning, which has scope for the entire translation
unit, not just the scope of a BugReporter (which is limited to a particular ExprEngine).
As an interesting side-effect, diagnostics emitted to the terminal also have their trailing "." stripped,
just like with diagnostics emitted to plists and HTML. This required some tests to be updated, but now
the tests have higher fidelity with what users will see.
There are some inefficiencies in this patch. We currently generate the report graph (from the ExplodedGraph)
once per PathDiagnosticConsumer, which is a bit wasteful, but that could be pulled up higher in the
logic stack. There is some intended duplication, however, as we now generate different PathDiagnostics (for the same issue)
for different PathDiagnosticConsumers. This is necessary to produce the diagnostics that a particular
consumer expects.
llvm-svn: 162028
This is analogous to our handling of pointer dereferences: if we
dereference a pointer that may or may not be null, we assume it's non-null
from then on.
While some implementations of C++ (including ours) allow you to call a
non-virtual method through a null pointer of object type, it is technically
disallowed by the C++ standard, and should not prune out any real paths in
practice.
[class.mfct.non-static]p1: A non-static member function may be called
for an object of its class type, or for an object of a class derived
from its class type...
(a null pointer value does not refer to an object)
We can also make the same assumption about function pointers.
llvm-svn: 161992
This is the other half of C++11 [class.cdtor]p4 (the destructor side
was added in r161915). This also fixes an issue with post-call checks
where the 'this' value was already being cleaned out of the state, thus
being omitted from a reconstructed CXXConstructorCall.
llvm-svn: 161981
With reinterpret_cast, we can get completely unrelated types in a region
hierarchy together; this was resulting in CXXBaseObjectRegions being layered
directly on an (untyped) SymbolicRegion, whose symbol was from a completely
different type hierarchy. This was what was causing the internal buildbot to
fail.
Reverts r161911, which merely masked the problem.
llvm-svn: 161960
Previously we were checking -analyzer-ipa=dynamic-bifurcate only, and
unconditionally inlining everything else that had an available definition,
even under -analyzer-ipa=inlining (but not under -analyzer-ipa=none).
llvm-svn: 161916
C++11 [class.cdtor]p4: When a virtual function is called directly or
indirectly from a constructor or from a destructor, including during
the construction or destruction of the class’s non-static data members,
and the object to which the call applies is the object under
construction or destruction, the function called is the final overrider
in the constructor's or destructor's class and not one overriding it in
a more-derived class.
llvm-svn: 161915
Add a TODO test case for r161822 - calling self from a class method.
Remove a TODO comment for r161683 - value2 is not a property - we just
have method names that look like they are getters/setters for a
property.
llvm-svn: 161884
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
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
...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
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
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
This check is also accessible through the debug.ExprInspection checker.
Like clang_analyzer_eval, you can use it to test the analyzer engine's
current state; the argument should be true or false to indicate whether or
not you expect the function to be inlined.
When used in the positive case (clang_analyzer_checkInlined(true)), the
analyzer prints the message "TRUE" if the function is ever inlined. However,
clang_analyzer_checkInlined(false) should never print a message; this asserts
that there should be no paths on which the current function is inlined, but
then there are no paths on which to print a message! (If the assertion is
violated, the message "FALSE" will be printed.)
This asymmetry comes from the fact that the only other chance to print a
message is when the function is analyzed as a top-level function. However,
when we do that, we can't be sure it isn't also inlined elsewhere (such as
in a recursive function, or if we want to analyze in both general or
specialized cases). Rather than have all checkInlined calls have an appended,
meaningless "FALSE" or "TOP-LEVEL" case, there is just no message printed.
void clang_analyzer_checkInlined(int);
For debugging purposes only!
llvm-svn: 161708
TODO:
- Handle @syncronized properties.
- Always inline properties declared publicly (do not split the path).
This is tricky since there is no mapping from a Decl to the property in
the AST as far as I can tell.
llvm-svn: 161683
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
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
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
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
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
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
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
Warns on anti-patterns/typos in the 'size' argument to strncat. The
correct size argument should look like the following:
- strncat(dst, src, sizeof(dst) - strlen(dest) - 1);
We warn on:
- sizeof(dst)
- sizeof(src)
- sizeof(dst) - strlen(dst)
- sizeof(src) - anything
(This has been implemented in void Sema::CheckStrncatArguments().)
llvm-svn: 161440
Dynamic type inference does the right thing in this case. However, as
Jordan suggested, it would be nice to add a warning here as well.
llvm-svn: 161365
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
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
No functionality change, but from now on, any new path notes should be
tested both with plain-text output (for ease of human auditing) and with
plist output (to ensure control flow and events are being correctly
represented in Xcode).
llvm-svn: 161351
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
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
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
This only applies in the case where ->* is not overloaded, since it
specifically looks for BinaryOperator and not CXXOperatorCallExpr.
llvm-svn: 161275
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
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
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
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
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
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
- 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
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
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
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
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
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
- 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
value by scanning the path, rather than assuming we have visited the '?:' operator
as a terminator (which sets a value indicating which expression to grab the
final ternary expression value from).
llvm-svn: 160760
to fix all the issues. Currently the code is essentially unmaintained and buggy, and
needs major revision (with coupled enhancements to the analyzer core).
llvm-svn: 160754
As pointed out by Anna, we only differentiate between explicit message sends
This also adds support for ObjCSubscriptExprs, which are basically the same
as properties in many ways. We were already checking these, but not emitting
nice messages for them.
This depends on the llvm::PointerIntPair change in r160456.
llvm-svn: 160461