The analyzer trims unnecessary nodes from the exploded graph before reporting
path diagnostics. However, in some cases it can trim all nodes (including the
error node), leading to an assertion failure (see
https://llvm.org/bugs/show_bug.cgi?id=24184).
This commit addresses the issue by adding two new APIs to CheckerContext to
explicitly create error nodes. Unless the client provides a custom tag, these
APIs tag the node with the checker's tag -- preventing it from being trimmed.
The generateErrorNode() method creates a sink error node, while
generateNonFatalErrorNode() creates an error node for a path that should
continue being explored.
The intent is that one of these two methods should be used whenever a checker
creates an error node.
This commit updates the checkers to use these APIs. These APIs
(unlike addTransition() and generateSink()) do not take an explicit Pred node.
This is because there are not any error nodes in the checkers that were created
with an explicit different than the default (the CheckerContext's Pred node).
It also changes generateSink() to require state and pred nodes (previously
these were optional) to reduce confusion.
Additionally, there were several cases where checkers did check whether a
generated node could be null; we now explicitly check for null in these places.
This commit also includes a test case written by Ying Yi as part of
http://reviews.llvm.org/D12163 (that patch originally addressed this issue but
was reverted because it introduced false positive regressions).
Differential Revision: http://reviews.llvm.org/D12780
llvm-svn: 247859
In Objective-C, method calls with nil receivers are essentially no-ops. They
do not fault (although the returned value may be garbage depending on the
declared return type and architecture). Programmers are aware of this
behavior and will complain about a false alarm when the analyzer
diagnoses API violations for method calls when the receiver is known to
be nil.
Rather than require each individual checker to be aware of this behavior
and suppress a warning when the receiver is nil, this commit
changes ExprEngineObjC so that VisitObjCMessage skips calling checker
pre/post handlers when the receiver is definitely nil. Instead, it adds a
new event, ObjCMessageNil, that is only called in that case.
The CallAndMessageChecker explicitly cares about this case, so I've changed it
to add a callback for ObjCMessageNil and moved the logic in PreObjCMessage
that handles nil receivers to the new callback.
rdar://problem/18092611
Differential Revision: http://reviews.llvm.org/D12123
llvm-svn: 247653
Add an option (-analyzer-config min-blocks-for-inline-large=14) to control the function
size the inliner considers as large, in relation to "max-times-inline-large". The option
defaults to the original hard coded behaviour, which I believe should be adjustable with
the other inlining settings.
The analyzer-config test has been modified so that the analyzer will reach the
getMinBlocksForInlineLarge() method and store the result in the ConfigTable, to ensure it
is dumped by the debug checker.
A patch by Sean Eveson!
Differential Revision: http://reviews.llvm.org/D12406
llvm-svn: 247463
This is making our internal build bot fail because it results in extra warnings being
emitted past what should be sink nodes. (There is actually an example of this in the
updated malloc.c test in the reverted commit.)
I'm working on a patch to fix the original issue by adding a new checker API to explicitly
create error nodes. This API will ensure that error nodes are always tagged in order to
prevent them from being reclaimed.
This reverts commit r246188.
llvm-svn: 247103
Change the analyzer's modeling of memcpy to be more precise when copying into fixed-size
array fields. With this change, instead of invalidating the entire containing region the
analyzer now invalidates only offsets for the array itself when it can show that the
memcpy stays within the bounds of the array.
This addresses false positive memory leak warnings of the kind reported by
krzysztof in https://llvm.org/bugs/show_bug.cgi?id=22954
A patch by Pierre Gousseau!
Differential Revision: http://reviews.llvm.org/D11832
llvm-svn: 246345
The assertion is caused by reusing a “filler” ExplodedNode as an error node.
The “filler” nodes are only used for intermediate processing and are not
essential for analyzer history, so they can be reclaimed when the
ExplodedGraph is trimmed by the “collectNode” function. When a checker finds a
bug, they generate a new transition in the ExplodedGraph. The analyzer will
try to reuse the existing predecessor node. If it cannot, it creates a new
ExplodedNode, which always has a tag to uniquely identify the creation site.
The assertion is caused when the analyzer reuses a “filler” node.
In the test case, some “filler” nodes were reused and then reclaimed later
when the ExplodedGraph was trimmed. This caused an assertion because the node
was needed to generate the report. The “filler” nodes should not be reused as
error nodes. The patch adds a constraint to prevent this happening, which
solves the problem and makes the test cases pass.
Differential Revision: http://reviews.llvm.org/D11433
Patch by Ying Yi!
llvm-svn: 246188
Add checkers that detect code-level localizability issues for OS X / iOS:
- A path sensitive checker that warns about uses of non-localized
NSStrings passed to UI methods expecting localized strings.
- A syntax checker that warns against not including a comment in
NSLocalizedString macros.
A patch by Kulpreet Chilana!
(This is the second attempt with the compilation issue on Windows and
the random test failures resolved.)
llvm-svn: 245093
This reverts commit fc885033a30b6e30ccf82398ae7c30e646727b10.
Revert all localization checker commits until the proper fix is implemented.
llvm-svn: 244394
Add checkers that detect code-level localizability issues for OS X / iOS:
- A path sensitive checker that warns about uses of non-localized
NSStrings passed to UI methods expecting localized strings.
- A syntax checker that warns against not including a comment in
NSLocalizedString macros.
A patch by Kulpreet Chilana!
llvm-svn: 244389
The ObjCSuperCallChecker issues alarms for various Objective-C APIs that require
a subclass to call to its superclass's version of a method when overriding it.
So, for example, it raises an alarm when the -viewDidLoad method in a subclass
of UIViewController does not call [super viewDidLoad].
This patch fixes a false alarm where the analyzer erroneously required the
implementation of the superclass itself (e.g., UIViewController) to call
super.
rdar://problem/18416944
Differential Revision: http://reviews.llvm.org/D11842
llvm-svn: 244386
BlockDecl has a poor AST representation because it doesn't carry its type
with it. Instead, the containing BlockExpr has the full type. This almost
never matters for the analyzer, but if the block decl contains static
local variables we need to synthesize a region to put them in, and this
region will necessarily not have the right type.
Even /that/ doesn't matter, unless
(1) the block calls the function or method containing the block, and
(2) the value of the block expr is used in some interesting way.
In this case, we actually end up needing the type of the block region,
and it will be set to our synthesized type. It turns out we've been doing
a terrible job faking that type -- it wasn't a block pointer type at all.
This commit fixes that to at least guarantee a block pointer type, using
the signature written by the user if there is one.
This is not really a correct answer because the block region's type will
/still/ be wrong, but further efforts to make this right in the analyzer
would probably be silly. We should just change the AST.
rdar://problem/21698099
llvm-svn: 241944
A patch by Karthik Bhat!
This patch fixes a regression introduced by r224398. Prior to r224398
we were able to analyze the following code in test-include.c and report
a null deref in this case. But post r224398 this analysis is being skipped.
E.g.
// test-include.c
#include "test-include.h"
void test(int * data) {
data = 0;
*data = 1;
}
// test-include.h
void test(int * data);
This patch uses the function body (instead of its declaration) as the location
of the function when deciding if the Decl should be analyzed with path-sensitive
analysis. (Prior to r224398, the call graph was guaranteed to have a definition
when available.)
llvm-svn: 240800
Addresses a conflict with glibc's __nonnull macro by renaming the type
nullability qualifiers as follows:
__nonnull -> _Nonnull
__nullable -> _Nullable
__null_unspecified -> _Null_unspecified
This is the major part of rdar://problem/21530726, but does not yet
provide the Darwin-specific behavior for the old names.
llvm-svn: 240596
That is,
void cf2(CFTypeRef * __nullable p CF_RETURNS_NOT_RETAINED);
is equivalent to
void cf2(CFTypeRef __nullable * __nullable p CF_RETURNS_NOT_RETAINED);
More rdar://problem/18742441
llvm-svn: 240186
Includes a simple static analyzer check and not much else, but we'll also
be able to take advantage of this in Swift.
This feature can be tested for using __has_feature(cf_returns_on_parameters).
This commit also contains two fixes:
- Look through non-typedef sugar when deciding whether something is a CF type.
- When (cf|ns)_returns(_not)?_retained is applied to invalid properties,
refer to "property" instead of "method" in the error message.
rdar://problem/18742441
llvm-svn: 240185
Update ObjCContainersChecker to be notified when pointers escape so it can
remove size information for escaping CFMutableArrayRefs. When such pointers
escape, un-analyzed code could mutate the array and cause the size information
to be incorrect.
rdar://problem/19406485
llvm-svn: 239709
Based on previous discussion on the mailing list, clang currently lacks support
for C99 partial re-initialization behavior:
Reference: http://lists.cs.uiuc.edu/pipermail/cfe-dev/2013-April/029188.html
Reference: http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_253.htm
This patch attempts to fix this problem.
Given the following code snippet,
struct P1 { char x[6]; };
struct LP1 { struct P1 p1; };
struct LP1 l = { .p1 = { "foo" }, .p1.x[2] = 'x' };
// this example is adapted from the example for "struct fred x[]" in DR-253;
// currently clang produces in l: { "\0\0x" },
// whereas gcc 4.8 produces { "fox" };
// with this fix, clang will also produce: { "fox" };
Differential Review: http://reviews.llvm.org/D5789
llvm-svn: 239446
Emit warning when operand to `delete` is allocated with `new[]` or
operand to `delete[]` is allocated with `new`.
rev 2 update:
`getNewExprFromInitListOrExpr` should return `dyn_cast_or_null`
instead of `dyn_cast`, since `E` might be null.
Reviewers: rtrieu, jordan_rose, rsmith
Subscribers: majnemer, cfe-commits
Differential Revision: http://reviews.llvm.org/D4661
llvm-svn: 237608
This reverts commit 742dc9b6c9686ab52860b7da39c3a126d8a97fbc.
This is generating multiple segfaults in our internal builds.
Test case coming up shortly.
llvm-svn: 237391
Emit warning when operand to `delete` is allocated with `new[]` or
operand to `delete[]` is allocated with `new`.
Reviewers: rtrieu, jordan_rose, rsmith
Subscribers: majnemer, cfe-commits
Differential Revision: http://reviews.llvm.org/D4661
llvm-svn: 237368
TODO: support realloc(). Currently it is not possible due to the present realloc() handling. Currently RegionState is not being attached to realloc() in case of a zero Size argument.
llvm-svn: 234889
Again, this is being applied in a separate commit so that the previous commit
can be reverted while leaving the test in place.
rdar://problem/20335433
llvm-svn: 233593
This is imitating a pre-r228174 state where ivars are not considered tracked by
default, but with the addition that even ivars /with/ retain count information
(e.g. "[_ivar retain]; [ivar _release];") are not being tracked as well. This is
to ensure that we don't regress on values accessed through both properties and
ivars, which is what r228174 was trying to fix.
The issue occurs in code like this:
[_contentView retain];
[_contentView removeFromSuperview];
[self addSubview:_contentView]; // invalidates 'self'
[_contentView release];
In this case, the call to -addSubview: may change the value of self->_contentView,
and so the analyzer can't be sure that we didn't leak the original _contentView.
This is a correct conservative view of the world, but not a useful one. Until we
have a heuristic that allows us to not consider this a leak, not emitting a
diagnostic is our best bet.
This commit disables all of the ivar-related retain count tests, but does not
remove them to ensure that we don't crash trying to evaluate either valid or
erroneous code. The next commit will add a new test for the example above so
that this commit (and the previous one) can be reverted wholesale when a better
solution is implemented.
Rest of rdar://problem/20335433
llvm-svn: 233592
Give up this checking in order to continue tracking that these values came from
direct ivar access, which will be important in the next commit.
Part of rdar://problem/20335433
llvm-svn: 233591
Fixes https://llvm.org/bugs/show_bug.cgi?id=20744
struct A {
A() = default;
};
Previously the source range of the declaration of A ended at the ')'. It should
include the '= default' part as well. The same for '= delete'.
Note: this will break one of the clang-tidy fixers, which is going to be
addessed in a follow-up patch.
Differential Revision: http://reviews.llvm.org/D8465
llvm-svn: 233028
Similarly, don't assume +0 if the property's setter is manually implemented.
In both cases, if the property's ownership is explicitly written, then we /do/
assume the ivar has the same ownership.
rdar://problem/20218183
llvm-svn: 232849
CloudABI also supports the arc4random() function. We can enable compiler
warnings for rand(), random() and *rand48() on this system as well.
llvm-svn: 231914
In theory we could assume a CF property is stored at +0 if there's not a custom
setter, but that's not really worth the complexity. What we do know is that a
CF property can't have ownership attributes, and so we shouldn't assume anything
about the ownership of the ivar.
rdar://problem/20076963
llvm-svn: 231553
Modules and Tooling tests in particular tend to want to change the cwd,
so we were missing test coverage in this area on Windows. It should now
be easier to write such portable tests.
llvm-svn: 231029
We expect in general that any nil value has no retain count information
associated with it; violating this results in unexpected state unification
/later/ when we decide to throw the information away. Unexpectedly caching
out can lead to an assertion failure or crash.
rdar://problem/19862648
llvm-svn: 229934
+ separate bug report for "Free alloca()" error to be able to customize checkers responsible for this error.
+ Muted "Free alloca()" error for NewDelete checker that is not responsible for c-allocated memory, turned on for unix.MismatchedDeallocator checker.
+ RefState for alloca() - to be able to detect usage of zero-allocated memory by upcoming ZeroAllocDereference checker.
+ AF_Alloca family to handle alloca() consistently - keep proper family in RefState, handle 'alloca' by getCheckIfTracked() facility, etc.
+ extra tests.
llvm-svn: 229850
PrettyStackTrace now requires the ENABLE_BACKTRACES option. We need to check for that here or these tests fail llvm-lit.
Reviewed by chandlerc
llvm-svn: 228735
to the plist output. This check_name field does not guaranteed to be the
same as the name of the checker in the future.
Reviewer: Anna Zaks
Differential Revision: http://reviews.llvm.org/D6841
llvm-svn: 228624
The analyzer thinks that ArraySubscriptExpr cannot be an r-value (ever).
However, it can be in some corner cases. Specifically, C forbids expressions
of unqualified void type from being l-values.
Note, the analyzer will keep modeling the subscript expr as an l-value. The
analyzer should be treating void* as a char array
(https://gcc.gnu.org/onlinedocs/gcc-4.3.0/gcc/Pointer-Arith.html).
llvm-svn: 228249
Instead of handling edge cases (mostly involving blocks), where we have difficulty finding
an allocation statement, allow the allocation site to be in a parent node.
Previously we assumed that the allocation site can always be found in the same frame
as allocation, but there are scenarios in which an element is leaked in a child
frame but is allocated in the parent.
llvm-svn: 228247
A refinement of r204730, itself a refinement of r198953, to better handle
cases where an object is accessed both through a property getter and
through direct ivar access. An object accessed through a property should
always be treated as +0, i.e. not owned by the caller. However, an object
accessed through an ivar may be at +0 or at +1, depending on whether the
ivar is a strong reference. Outside of ARC, we don't always have that
information.
The previous attempt would clear out the +0 provided by a getter, but only
if that +0 hadn't already participated in other retain counting operations.
(That is, "self.foo" is okay, but "[[self.foo retain] autorelease]" is
problematic.) This turned out to not be good enough when our synthesized
getters get involved.
This commit drops the notion of "overridable" reference counting and instead
just tracks whether a value ever came from a (strong) ivar. If it has, we
allow one more release than we otherwise would. This has the added benefit
of being able to catch /some/ overreleases of instance variables, though
it's not likely to come up in practice.
We do still get some false negatives because we currently throw away
refcount state upon assigning a value into an ivar. We should probably
improve on that in the future, especially once we synthesize setters as
well as getters.
rdar://problem/18075108
llvm-svn: 228174
A patch by Daniel DeFreez!
We were previously dropping edges on re-declarations. Store the
canonical declarations in the graph to ensure that different
references to the same function end up reflected with the same call graph
node.
(Note, this might lead to performance fluctuation because call graph
is used to determine the function analysis order.)
llvm-svn: 224398
This suppresses a common false positive when analyzing libc++.
Along the way, introduce some tests to show this checker actually
works with C++ static_cast<>.
llvm-svn: 220160
The return value of mempcpy is only correct when the destination type is
one byte in size. This patch casts the argument to a char* so the
calculation is also correct for structs, ints etc.
A patch by Daniel Fahlgren!
llvm-svn: 219024
in the super class, do not issue the warning about property
in current class's protocol will not be auto synthesized.
// rdar://18179833
llvm-svn: 216769
People have been incorrectly using "-analyzer-disable-checker" to
silence analyzer warnings on a file, when analyzing a project. Add
the "-analyzer-disable-all-checks" option, which would allow the
suppression and suggest it as part of the error message for
"-analyzer-disable-checker". The idea here is to compose this with
"--analyze" so that users can selectively opt out specific files from
static analysis.
llvm-svn: 216763
Do not warn when property declared in class's protocol will be auto-synthesized
by its uper class implementation because super class has also declared this
property while this class has not. Continue to warn if current class
has declared the property also (because this declaration will not result
in a 2nd synthesis).
rdar://18152478
llvm-svn: 216753
Currently the analyzer lazily models some functions using 'BodyFarm',
which constructs a fake function implementation that the analyzer
can simulate that approximates the semantics of the function when
it is called. BodyFarm does this by constructing the AST for
such definitions on-the-fly. One strength of BodyFarm
is that all symbols and types referenced by synthesized function
bodies are contextual adapted to the containing translation unit.
The downside is that these ASTs are hardcoded in Clang's own
source code.
A more scalable model is to allow these models to be defined as source
code in separate "model" files and have the analyzer use those
definitions lazily when a function body is needed. Among other things,
it will allow more customization of the analyzer for specific APIs
and platforms.
This patch provides the initial infrastructure for this feature.
It extends BodyFarm to use an abstract API 'CodeInjector' that can be
used to synthesize function bodies. That 'CodeInjector' is
implemented using a new 'ModelInjector' in libFrontend, which lazily
parses a model file and injects the ASTs into the current translation
unit.
Models are currently found by specifying a 'model-path' as an
analyzer option; if no path is specified the CodeInjector is not
used, thus defaulting to the current behavior in the analyzer.
Models currently contain a single function definition, and can
be found by finding the file <function name>.model. This is an
initial starting point for something more rich, but it bootstraps
this feature for future evolution.
This patch was contributed by Gábor Horváth as part of his
Google Summer of Code project.
Some notes:
- This introduces the notion of a "model file" into
FrontendAction and the Preprocessor. This nomenclature
is specific to the static analyzer, but possibly could be
generalized. Essentially these are sources pulled in
exogenously from the principal translation.
Preprocessor gets a 'InitializeForModelFile' and
'FinalizeForModelFile' which could possibly be hoisted out
of Preprocessor if Preprocessor exposed a new API to
change the PragmaHandlers and some other internal pieces. This
can be revisited.
FrontendAction gets a 'isModelParsingAction()' predicate function
used to allow a new FrontendAction to recycle the Preprocessor
and ASTContext. This name could probably be made something
more general (i.e., not tied to 'model files') at the expense
of losing the intent of why it exists. This can be revisited.
- This is a moderate sized patch; it has gone through some amount of
offline code review. Most of the changes to the non-analyzer
parts are fairly small, and would make little sense without
the analyzer changes.
- Most of the analyzer changes are plumbing, with the interesting
behavior being introduced by ModelInjector.cpp and
ModelConsumer.cpp.
- The new functionality introduced by this change is off-by-default.
It requires an analyzer config option to enable.
llvm-svn: 216550
Also, make it slightly clearer what's being tested by only differentiating integer
literals based on their suffix, rather than using a very large constant.
llvm-svn: 216133
Yet more problems due to the missing CXXBindTemporaryExpr in the CFG for
default arguments.
Unfortunately we cannot just switch off inserting temporaries for the
corresponding default arguments, as that breaks existing tests
(test/SemaCXX/return-noreturn.cpp:245).
llvm-svn: 215554
In cases like:
struct C { ~C(); }
void f(C c = C());
void t() {
f();
}
We currently do not add the CXXBindTemporaryExpr for the temporary (the
code mentions that as the default parameter expressions are owned by
the declaration, we'd otherwise add the same expression multiple times),
but we add the temporary destructor pointing to the CXXBindTemporaryExpr.
We need to fix that before we can re-enable the assertion.
llvm-svn: 215357
Changes to the original patch:
- model the CFG for temporary destructors in conditional operators so that
the destructors of the true and false branch are always exclusive. This
is necessary because we must not have impossible paths for the path
based analysis to work.
- add multiple regression tests with ternary operators
Original description:
Fix modelling of non-lifetime-extended temporary destructors in the
analyzer.
Changes to the CFG:
When creating the CFG for temporary destructors, we create a structure
that mirrors the branch structure of the conditionally executed
temporary constructors in a full expression.
The branches we create use a CXXBindTemporaryExpr as terminator which
corresponds to the temporary constructor which must have been executed
to enter the destruction branch.
2. Changes to the Analyzer:
When we visit a CXXBindTemporaryExpr we mark the CXXBindTemporaryExpr as
executed in the state; when we reach a branch that contains the
corresponding CXXBindTemporaryExpr as terminator, we branch out
depending on whether the corresponding CXXBindTemporaryExpr was marked
as executed.
llvm-svn: 215096
This reverts commit r214962 because after the change the
following code doesn't compile with -Wreturn-type -Werror.
#include <cstdlib>
class NoReturn {
public:
~NoReturn() __attribute__((noreturn)) { exit(1); }
};
int check() {
true ? NoReturn() : NoReturn();
}
llvm-svn: 214998
1. Changes to the CFG:
When creating the CFG for temporary destructors, we create a structure
that mirrors the branch structure of the conditionally executed
temporary constructors in a full expression.
The branches we create use a CXXBindTemporaryExpr as terminator which
corresponds to the temporary constructor which must have been executed
to enter the destruction branch.
2. Changes to the Analyzer:
When we visit a CXXBindTemporaryExpr we mark the CXXBindTemporaryExpr as
executed in the state; when we reach a branch that contains the
corresponding CXXBindTemporaryExpr as terminator, we branch out
depending on whether the corresponding CXXBindTemporaryExpr was marked
as executed.
llvm-svn: 214962
MaterializeTemporaryExpr already contains information about the lifetime
of the temporary; if the lifetime is not the full statement, we do not
want to emit a destructor at the end of the full statement for it.
llvm-svn: 214292
This new checker, alpha.core.TestAfterDivZero, catches issues like this:
int sum = ...
int avg = sum / count; // potential division by zero...
if (count == 0) { ... } // ...caught here
Because the analyzer does not necessarily explore /all/ paths through a program,
this check is restricted to only work on zero checks that immediately follow a
division operation (/ % /= %=). This could later be expanded to handle checks
dominated by a division operation but not necessarily in the same CFG block.
Patch by Anders Rönnholm! (with very minor modifications by me)
llvm-svn: 212731
This silences false positives (leaks, use of uninitialized value) in simple
code that uses containers such as std::vector and std::list. The analyzer
cannot reason about the internal invariances of those data structures which
leads to false positives. Until we come up with a better solution to that
problem, let's just not inline the methods of the containers and allow objects
to escape whenever such methods are called.
This just extends an already existing flag "c++-container-inlining" and applies
the heuristic not only to constructors and destructors of the containers, but
to all of their methods.
We have a bunch of distinct user reports all related to this issue
(radar://16058651, radar://16580751, radar://16384286, radar://16795491
[PR19637]).
llvm-svn: 211832
When adding the implicit compound statement (required for Codegen?), the
end location was previously overridden by the start location, probably
based on the assumptions:
* The location of the compound statement should be the member's location
* The compound statement if present is the last element of a FunctionDecl
This patch changes the location of the compound statement to the
member's end location.
Code review: http://reviews.llvm.org/D4175
llvm-svn: 211344
Doing this caused us to mistakenly think we'd seen a particular state before
when we actually hadn't, which resulted in false negatives. Credit to
Rafael Auler for discovering this issue!
llvm-svn: 211209
Fixes a crash in Retain Count checker error reporting logic by handing
the allocation statement retrieval from a BlockEdge program point.
Also added a simple CFG dump routine for debugging.
llvm-svn: 210960
This applies to __attribute__((pure)) as well, but 'const' is more interesting
because many of our builtins are marked 'const'.
PR19661
llvm-svn: 208154
The assignment needs to be before the destruction of the temporary.
This patch calls out to addStmt, which invokes VisitDeclStmt, which has
all the correct logic for handling temporaries.
llvm-svn: 207985
Document and simplify ResolveCondition.
1. Introduce a temporary special case for temporary desctructors when resolving
the branch condition - in an upcoming patch, alexmc will change temporary
destructor conditions to not run through this logic, in which case we can remove
this (marked as FIXME); this currently fixes a crash.
2. Simplify ResolveCondition; while documenting the function, I noticed that it
always returns the last statement - either that statement is the condition
itself (in which case the condition was returned anyway), or the rightmost
leaf is returned; for correctness, the rightmost leaf must be evaluated anyway
(which the CFG does in the last statement), thus we can just return the last
statement in that case, too. Added an assert to verify the invariant.
llvm-svn: 207957
The constructor that comes right before a variable declaration in the CFG might
not be the initialization of that variable. Previously, we just checked that
the variable's initializer expression was different from the construction
expression, but forgot to see whether the variable had an initializer expression
at all.
Thanks for the prompting, David.
llvm-svn: 207562
While we don't model pointer-to-member operators yet (neither .* nor ->*),
CallAndMessageChecker still checks to make sure the 'this' object is not
null or undefined first. However, it also expects that the object should
always have a valid MemRegion, something that's generally important elsewhere
in the analyzer as well. Ensure this is true ahead of time, just like we do
for member access.
PR19531
llvm-svn: 207561
This also includes some infrastructure to make it easier to build multi-argument
selectors, rather than trying to use string matching on each piece. There's a bit
more setup code, but less cost at runtime.
PR18908
llvm-svn: 205827
Fixes a false positive when temporary destructors are enabled where a temporary
is destroyed after a variable is constructed but before the VarDecl itself is
processed, which occurs when the variable is in the condition of an if or while.
Patch by Alex McCarthy, with an extra test from me.
llvm-svn: 205661
For namespaces, this is consistent with mangling and GCC's debug info
behavior. For structs, GCC uses <anonymous struct> but we prefer
consistency between all anonymous entities but don't want to confuse
them with template arguments, etc, so we'll just go with parens in all
cases.
llvm-svn: 205398
If we're trying to get the zero element region of something that's not a region,
we should be returning UnknownVal, which is what ProgramState::getLValue will
do for us.
Patch by Alex McCarthy!
llvm-svn: 205327
Add M_ZERO awareness to malloc() static analysis in Clang for FreeBSD,
NetBSD, and OpenBSD in a similar fashion to O_CREAT for open(2).
These systems have a three-argument malloc() in the kernel where the
third argument contains flags; the M_ZERO flag will zero-initialize the
allocated buffer.
This should reduce the number of false positives when running static
analysis on BSD kernels.
Additionally, add kmalloc() (Linux kernel malloc()) and treat __GFP_ZERO
like M_ZERO on Linux.
Future work involves a better method of checking for named flags without
hardcoding values.
Patch by Conrad Meyer, with minor modifications by me.
llvm-svn: 204832
A refinement of r198953 to handle cases where an object is accessed both through
a property getter and through direct ivar access. An object accessed through a
property should always be treated as +0, i.e. not owned by the caller. However,
an object accessed through an ivar may be at +0 or at +1, depending on whether
the ivar is a strong reference. Outside of ARC, we don't have that information,
so we just don't track objects accessed through ivars.
With this change, accessing an ivar directly will deliberately override the +0
provided by a getter, but only if the +0 hasn't participated in other retain
counting yet. That isn't perfect, but it's already unusual for people to be
mixing property access with direct ivar access. (The primary use case for this
is in setters, init methods, and -dealloc.)
Thanks to Ted for spotting a few mistakes in private review.
<rdar://problem/16333368>
llvm-svn: 204730
Passing a pointer to an uninitialized memory buffer is normally okay,
but if the function is declared to take a pointer-to-const then it's
very unlikely it will be modifying the buffer. In this case the analyzer
should warn that there will likely be a read of uninitialized memory.
This doesn't check all elements of an array, only the first one.
It also doesn't yet check Objective-C methods, only C functions and
C++ methods.
This is controlled by a new check: alpha.core.CallAndMessageUnInitRefArg.
Patch by Per Viberg!
llvm-svn: 203822
Like the binary operator check of r201702, this actually checks the
condition of every if in a chain against every other condition, an
O(N^2) operation. In most cases N should be small enough to make this
practical, and checking all cases like this makes it much more likely
to catch a copy-paste error within the same series of branches.
Part of IdenticalExprChecker; patch by Daniel Fahlgren!
llvm-svn: 203585
null comparison when the pointer is known to be non-null.
This catches the array to pointer decay, function to pointer decay and
address of variables. This does not catch address of function since this
has been previously used to silence a warning.
Pointer to bool conversion is under -Wbool-conversion.
Pointer to null comparison is under -Wtautological-pointer-compare, a sub-group
of -Wtautological-compare.
void foo() {
int arr[5];
int x;
// warn on these conditionals
if (foo);
if (arr);
if (&x);
if (foo == null);
if (arr == null);
if (&x == null);
if (&foo); // no warning
}
llvm-svn: 202216
For now, just ignore them. Later, we could try looking through LazyCompoundVals,
but we at least shouldn't crash.
<rdar://problem/16153464>
llvm-svn: 202212
Somehow both Daniel and I missed the fact that while loops are only identical
if they have identical bodies.
Patch by Daniel Fahlgren!
llvm-svn: 201829
IdenticalExprChecker now warns if any expressions in a logical or bitwise
chain (&&, ||, &, |, or ^) are the same. Unlike the previous patch, this
actually checks all subexpressions against each other (an O(N^2) operation,
but N is likely to be small).
Patch by Daniel Fahlgren!
llvm-svn: 201702
This extends the checks for identical expressions to handle identical
statements, and compares the consequent and alternative ("then" and "else")
branches of an if-statement to see if they are identical, treating a single
statement surrounded by braces as equivalent to one without braces.
This does /not/ check subsequent branches in an if/else chain, let alone
branches that are not consecutive. This may improve in a future patch, but
it would certainly take more work.
Patch by Daniel Fahlgren!
llvm-svn: 201701
This will let us stage in the modeling of operator new. The -analyzer-config
opton 'c++-inline-allocators' is currently off by default.
Patch by Karthik Bhat!
llvm-svn: 201122
This means always walking the whole call stack for the end path node, but
we'll assume that's always fairly tractable.
<rdar://problem/15952973>
llvm-svn: 200980
redeclaration, not just when looking them up for a use -- we need the implicit
declaration to appropriately check various properties of them (notably, whether
they're deleted).
llvm-svn: 200729
Due to statement expressions supported as GCC extension, it is possible
to put 'break' or 'continue' into a loop/switch statement but outside
its body, for example:
for ( ; ({ if (first) { first = 0; continue; } 0; }); )
This code is rejected by GCC if compiled in C mode but is accepted in C++
code. GCC bug 44715 tracks this discrepancy. Clang used code generation
that differs from GCC in both modes: only statement of the third
expression of 'for' behaves as if it was inside loop body.
This change makes code generation more close to GCC, considering 'break'
or 'continue' statement in condition and increment expressions of a
loop as it was inside the loop body. It also adds error for the cases
when 'break'/'continue' appear outside loop due to this syntax. If
code generation differ from GCC, warning is issued.
Differential Revision: http://llvm-reviews.chandlerc.com/D2518
llvm-svn: 199897
If there are non-trivially-copyable types /other/ than C++ records, we
won't have a synthesized copy expression, but we can't just use a simple
load/return.
Also, add comments and shore up tests, making sure to test in both ARC
and non-ARC.
llvm-svn: 199869