This is a syntactic checker aimed at helping iOS programmers correctly
subclass and override the methods of UIViewController. While this should
eventually be covered by the 'objc_requires_super' attribute, this
checker can be used with the existing iOS SDKs without any header changes.
This new checker is currently named 'alpha.osx.cocoa.MissingSuperCall'.
Patch by Julian Mayer!
llvm-svn: 166993
Our one basic suppression heuristic is to assume that functions do not
usually return NULL. However, when one of the arguments is NULL it is
suddenly much more likely that NULL is a valid return value. In this case,
we don't suppress the report here, but we do attach /another/ visitor to
go find out if this NULL argument also comes from an inlined function's
error path.
This new behavior, controlled by the 'avoid-suppressing-null-argument-paths'
analyzer-config option, is turned off by default. Turning it on produced
two false positives and no new true positives when running over LLVM/Clang.
This is one of the possible refinements to our suppression heuristics.
<rdar://problem/12350829>
llvm-svn: 166941
Additionally, don't collect PostStore nodes -- they are often used in
path diagnostics.
Previously, we tried to track null arguments in the same way as any other
null values, but in many cases the necessary nodes had already been
collected (a memory optimization in ExplodedGraph). Now, we fall back to
using the value of the argument at the time of the call, which may not
always match the actual contents of the region, but often will.
This is a precursor to improving our suppression heuristic.
<rdar://problem/12350829>
llvm-svn: 166940
path notes for cases where a value may be assumed to be null, etc.
Instead of having redundant diagnostics, do a pass over the generated
PathDiagnostic pieces and remove notes from TrackConstraintBRVisitor
that are already covered by ConditionBRVisitor, whose notes tend
to be better.
Fixes <rdar://problem/12252783>
llvm-svn: 166728
After every 1000 CFGElements processed, the ExplodedGraph trims out nodes
that satisfy a number of criteria for being "boring" (single predecessor,
single successor, and more). Rather than controlling this with a cc1 option,
which can only disable this behavior, we now have an analyzer-config option,
'graph-trim-interval', which can change this interval from 1000 to something
else. Setting the value to 0 disables reclamation.
The next commit relies on this behavior to actually test anything.
llvm-svn: 166528
This is actually required by the C++ standard in
[basic.stc.dynamic.allocation]p3:
If an allocation function declared with a non-throwing
exception-specification fails to allocate storage, it shall return a
null pointer. Any other allocation function that fails to allocate
storage shall indicate failure only by throwing an exception of a type
that would match a handler of type std::bad_alloc.
We don't bother checking for the specific exception type, but just go off
the operator new prototype. This should help with a certain class of lazy
initalization false positives.
<rdar://problem/12115221>
llvm-svn: 166363
This actually looks through several kinds of expression, such as
OpaqueValueExpr and ExprWithCleanups. The idea is that binding and lookup
should be consistent, and so if the environment needs to be modified later,
the code doing the modification will not have to manually look through these
"transparent" expressions to find the real binding to change.
This is necessary for proper updating of struct rvalues as described in
the previous commit.
llvm-svn: 166121
In C++, rvalues that need to have their address taken (for example, to be
passed to a function by const reference) will be wrapped in a
MaterializeTemporaryExpr, which lets CodeGen know to create a temporary
region to store this value. However, MaterializeTemporaryExprs are /not/
created when a method is called on an rvalue struct, even though the 'this'
pointer needs a valid value. CodeGen works around this by creating a
temporary region anyway; now, so does the analyzer.
The analyzer also does this when accessing a field of a struct rvalue.
This is a little unfortunate, since the rest of the struct will soon be
thrown away, but it does make things consistent with the rest of the
analyzer.
This allows us to bring back the assumption that all known 'this' values
are Locs. This is a revised version of r164828-9, reverted in r164876-7.
<rdar://problem/12137950>
llvm-svn: 166120
This implementation doesn't warn on anything that GCC doesn't warn on with the
exception of templates specializations (GCC doesn't warn, Clang does). The
specific skipped cases (boolean, constant expressions, enums) are open for
debate/adjustment if anyone wants to demonstrate that GCC is being overly
conservative here. The only really obvious false positive I found was in the
Clang regression suite's MPI test - apparently MPI uses specific flag values in
pointer constants. (eg: #define FOO (void*)~0)
llvm-svn: 166039
This time, actually uncomment the code that's supposed to fix the problem.
This reverts r165671 / 8ceb837585ed973dc36fba8dfc57ef60fc8f2735.
llvm-svn: 165676
Author: Jordan Rose <jordan_rose@apple.com>
Date: Wed Oct 10 21:31:21 2012 +0000
[analyzer] Treat fields of unions as having symbolic offsets.
This allows only one field to be active at a time in RegionStore.
This isn't quite the correct behavior for unions, but it at least
would handle the case of "value goes in, value comes out" from the
same field.
RegionStore currently has a number of places where any access to a union
results in UnknownVal being returned. However, it is clearly missing
some cases, or the original issue wouldn't have occurred. It is probably
now safe to remove those changes, but that's a potentially destabilizing
change that should wait for more thorough testing.
Fixes PR14054.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@165660 91177308-0d34-0410-b5e6-96231b3b80d8
This reverts commit cf9030e480f77ab349672f00ad302e216c26c92c.
llvm-svn: 165671
This allows only one field to be active at a time in RegionStore.
This isn't quite the correct behavior for unions, but it at least
would handle the case of "value goes in, value comes out" from the
same field.
RegionStore currently has a number of places where any access to a union
results in UnknownVal being returned. However, it is clearly missing
some cases, or the original issue wouldn't have occurred. It is probably
now safe to remove those changes, but that's a potentially destabilizing
change that should wait for more thorough testing.
Fixes PR14054.
llvm-svn: 165660
...but do run them on user headers.
Previously, we were inconsistent here: non-path-sensitive checks on code
/bodies/ were only run in the main source file, but checks on
/declarations/ were run in /all/ headers. Neither of those is the
behavior we want.
Thanks to Sujit for pointing this out!
<rdar://problem/12454226>
llvm-svn: 165635
The Clang ASTs are a DAG, not a pure tree. However, ParentMap has to
choose a single parent for each object. In the main (only?) cases in
which the AST forms a DAG, it protects from multiple traversal by using
OpaqueValueExprs. Previously, ParentMap would just unconditionally look
through all OpaqueValueExprs when building its map.
In order to make this behavior better for the analyzer's diagnostics,
ParentMap was changed to not set a statement's parent if there already
was one in the map. However, ParentMap is supposed to allow updating
existing mappings by calling addStmt once again. This change makes the
"transparency" of OpaqueValueExprs explicit, and disables it when it
is not desired, rather than checking the current contents of the map.
This new code seems like a big change, but it should actually have
essentially the same performance as before. Only OpaqueValueExprs and
their users (PseudoObjectExpr and BinaryConditionalOperator) will
have any different behavior.
There should be no user-visible functionality change, though a test
has been added for the current behavior of BinaryConditionalOperator
source locations and accompanying Xcode arrows (which are not so great...).
llvm-svn: 165355
Some implicit statements, such as the implicit 'self' inserted for "free"
Objective-C ivar access, have invalid source locations. If one of these
statements is the location where an issue is reported, we'll now look at
the enclosing statements for a valid source location.
<rdar://problem/12446776>
llvm-svn: 165354
...and fix the run line so that the expected warnings are the same on
all platforms.
This reverts r165088 / d09074f0ca06626914108f1c0d4e70adeb851e01.
llvm-svn: 165124
In C++, overriding virtual methods are allowed to specify a covariant
return type -- that is, if the return type of the base method is an
object pointer type (or reference type), the overriding method's return
type can be a pointer to a subclass of the original type. The analyzer
was failing to take this into account when devirtualizing a method call,
and anything that relied on the return value having the proper type later
would crash.
In Objective-C, overriding methods are allowed to specify ANY return type,
meaning we can NEVER be sure that devirtualizing will give us a "safe"
return value. Of course, a program that does this will most likely crash
at runtime, but the analyzer at least shouldn't crash.
The solution is to check and see if the function/method being inlined is
the function that static binding would have picked. If not, check that
the return value has the same type. If the types don't match, see if we
can fix it with a derived-to-base cast (the C++ case). If we can't,
return UnknownVal to avoid crashing later.
<rdar://problem/12409977>
llvm-svn: 165079
table, making it printable with the ConfigDump checker. Along the
way, fix a really serious bug where the value was getting parsed
from the string in code that was in an assert() call. This means
in a Release-Asserts build this code wouldn't work as expected.
llvm-svn: 165041
By analogy with C structs, this seems to be legal, if probably discouraged.
It's only if the ivar is read from or written to that there's a problem.
Running a program that gets the "address" of an instance variable does in
fact return the offset when the base "object" is nil.
This isn't a full revert because r164442 includes some diagnostic tweaks
as well; those have been kept.
This partially reverts r164442 / 08965091770c9b276c238bac2f716eaa4da2dca4.
llvm-svn: 164960
The original intent of this commit was to catch potential null dereferences
early, but it breaks the common "home-grown offsetof" idiom (PR13927):
(((struct Foo *)0)->member - ((struct foo *)0))
As it turns out, this appears to be legal in C, per a footnote in
C11 6.5.3.2: "Thus, &*E is equivalent to E (even if E is a null pointer)".
In C++ this issue is still open:
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#232
We'll just have to make sure we have good path notes in the future.
This reverts r164441 / 9be016dcd1ca3986873a7b66bd4bc027309ceb59.
llvm-svn: 164958
string in the config table so that it can be dumped as part of the
config dumper. Add a test to show that these options are sticking
and can be cross-checked using FileCheck.
llvm-svn: 164954
This is related to but not blocked by <rdar://problem/12137950>
("Return-by-value structs do not have associated regions")
This reverts r164875 / 3278d41e17749dbedb204a81ef373499f10251d7.
llvm-svn: 164952
the validation occurred.
The original implementation was pessimistic - we assumed that ivars
which escape are invalidated. This version is optimistic, it assumes
that the ivars will always be explicitly invalidated: either set to nil
or sent an invalidation message.
llvm-svn: 164868
Previously the analyzer treated all inlined constructors like lvalues,
setting the value of the CXXConstructExpr to the newly-constructed
region. However, some CXXConstructExprs behave like rvalues -- in
particular, the implicit copy constructor into a pass-by-value argument.
In this case, we want only the /contents/ of a temporary object to be
passed, so that we can use the same "copy each argument into the
parameter region" algorithm that we use for scalar arguments.
This may change when we start modeling destructors of temporaries,
but for now this is the last part of <rdar://problem/12137950>.
llvm-svn: 164830
An rvalue has no address, but calling a C++ member function requires a
'this' pointer. This commit makes the analyzer create a temporary region
in which to store the struct rvalue and use as a 'this' pointer whenever
a member function is called on an rvalue, which is essentially what
CodeGen does.
More of <rdar://problem/12137950>. The last part is tracking down the
C++ FIXME in array-struct-region.cpp.
llvm-svn: 164829
Struct rvalues are represented in the analyzer by CompoundVals,
LazyCompoundVals, or plain ConjuredSymbols -- none of which have associated
regions. If the entire structure is going to persist, this is not a
problem -- either the rvalue will be assigned to an existing region, or
a MaterializeTemporaryExpr will be present to create a temporary region.
However, if we just need a field from the struct, we need to create the
temporary region ourselves.
This is inspired by the way CodeGen handles calls to temporaries;
support for that in the analyzer is coming next.
Part of <rdar://problem/12137950>
llvm-svn: 164828
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